]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge tag 'sunxi-drm-for-4.14' of https://git.kernel.org/pub/scm/linux/kernel/git...
authorDave Airlie <airlied@redhat.com>
Sun, 20 Aug 2017 23:05:01 +0000 (09:05 +1000)
committerDave Airlie <airlied@redhat.com>
Sun, 20 Aug 2017 23:05:01 +0000 (09:05 +1000)
Allwinner DRM changes for 4.14

A few changes, but most notably improving the HDMI support merged in 4.13,
by reporting the DDC adapter as an i2c bus, and by adding CEC support
through the CEC framework.

* tag 'sunxi-drm-for-4.14' of https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux:
  sun4i_hdmi: add CEC support
  dt-bindings: display: sunxi: Improve endpoint ID scheme readability
  drm/sun4i: tcon: remove unused function
  drm/sun4i: Remove useless atomic_check
  drm/sun4i: Add if statement instead of depends on
  drm/sun4i: hdmi: Implement I2C adapter for A10s DDC bus
  drm/sun4i: constify drm_plane_helper_funcs

1874 files changed:
Documentation/admin-guide/pm/cpufreq.rst
Documentation/device-mapper/dm-raid.txt
Documentation/devicetree/bindings/ata/sata_rcar.txt
Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt
Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt [new file with mode: 0644]
Documentation/devicetree/bindings/display/repaper.txt [new file with mode: 0644]
Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
Documentation/devicetree/bindings/display/sitronix,st7586.txt [new file with mode: 0644]
Documentation/devicetree/bindings/display/st,stm32-ltdc.txt
Documentation/devicetree/bindings/gpio/gpio-exar.txt [new file with mode: 0644]
Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt
Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
Documentation/devicetree/bindings/mmc/img-dw-mshc.txt
Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt
Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt
Documentation/devicetree/bindings/net/brcm,amac.txt
Documentation/devicetree/bindings/net/brcm,bgmac-nsp.txt [deleted file]
Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt
Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt
Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/fb/efifb.txt
Documentation/gpio/gpio-legacy.txt
Documentation/gpu/drm-internals.rst
Documentation/gpu/drm-kms-helpers.rst
Documentation/gpu/drm-kms.rst
Documentation/gpu/drm-mm.rst
Documentation/gpu/drm-uapi.rst
Documentation/gpu/todo.rst
Documentation/media/kapi/dtv-core.rst
Documentation/media/typical_media_device.svg
Documentation/media/uapi/dvb/dvbstb.svg
Documentation/media/uapi/v4l/bayer.svg
Documentation/media/uapi/v4l/constraints.svg
Documentation/media/uapi/v4l/crop.svg
Documentation/media/uapi/v4l/fieldseq_bt.svg
Documentation/media/uapi/v4l/fieldseq_tb.svg
Documentation/media/uapi/v4l/nv12mt.svg
Documentation/media/uapi/v4l/nv12mt_example.svg
Documentation/media/uapi/v4l/selection.svg
Documentation/media/uapi/v4l/subdev-image-processing-crop.svg
Documentation/media/uapi/v4l/subdev-image-processing-full.svg
Documentation/media/uapi/v4l/subdev-image-processing-scaling-multi-source.svg
Documentation/media/uapi/v4l/vbi_525.svg
Documentation/media/uapi/v4l/vbi_625.svg
Documentation/media/uapi/v4l/vbi_hsync.svg
Documentation/media/uapi/v4l/vidioc-g-fmt.rst
Documentation/media/v4l-drivers/imx.rst
Documentation/media/v4l-drivers/index.rst
Documentation/power/runtime_pm.txt
MAINTAINERS
Makefile
arch/alpha/include/uapi/asm/ioctls.h
arch/arc/mm/dma.c
arch/arm/Kconfig
arch/arm/boot/dts/armada-388-gp.dts
arch/arm/boot/dts/da850-evm.dts
arch/arm/boot/dts/da850-lcdk.dts
arch/arm/boot/dts/dm8168-evm.dts
arch/arm/boot/dts/dm816x.dtsi
arch/arm/boot/dts/dra71-evm.dts
arch/arm/boot/dts/exynos4.dtsi
arch/arm/boot/dts/rk3288.dtsi
arch/arm/boot/dts/sun8i-a83t.dtsi
arch/arm/boot/dts/sunxi-h3-h5.dtsi
arch/arm/boot/dts/tango4-vantage-1172.dts
arch/arm/include/asm/bug.h
arch/arm/include/asm/cacheflush.h
arch/arm/include/asm/kexec.h
arch/arm/include/asm/tlb.h
arch/arm/include/asm/ucontext.h
arch/arm/kernel/machine_kexec.c
arch/arm/kernel/setup.c
arch/arm/kernel/signal.c
arch/arm/mach-davinci/board-da850-evm.c
arch/arm/mach-davinci/clock.c
arch/arm/mach-ep93xx/clock.c
arch/arm/mach-ixp4xx/include/mach/io.h
arch/arm/mach-mmp/devices.c
arch/arm/mach-mvebu/platsmp.c
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/display.h
arch/arm/mach-omap2/drm.c [deleted file]
arch/arm/mach-omap2/hsmmc.c
arch/arm/mach-omap2/hsmmc.h
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/prm3xxx.c
arch/arm/mach-omap2/prm44xx.c
arch/arm/mach-prima2/common.c
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/include/mach/mtd-xip.h
arch/arm/mach-rpc/include/mach/hardware.h
arch/arm/mach-sa1100/clock.c
arch/arm/mach-sa1100/include/mach/mtd-xip.h
arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
arch/arm/mach-ux500/cpu-db8500.c
arch/arm/mach-w90x900/clock.c
arch/arm/mm/dma-mapping-nommu.c
arch/arm/mm/dma-mapping.c
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
arch/arm64/boot/dts/amlogic/meson-gx.dtsi
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
arch/arm64/boot/dts/marvell/armada-37xx.dtsi
arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
arch/arm64/boot/dts/renesas/salvator-common.dtsi
arch/arm64/boot/dts/renesas/ulcb.dtsi
arch/arm64/configs/defconfig
arch/arm64/include/asm/atomic_lse.h
arch/arm64/include/asm/bug.h
arch/arm64/include/asm/memory.h
arch/arm64/include/asm/sysreg.h
arch/arm64/include/asm/uaccess.h
arch/arm64/kernel/cpu_ops.c
arch/arm64/kernel/smp.c
arch/arm64/kernel/topology.c
arch/arm64/kernel/traps.c
arch/arm64/kvm/sys_regs.c
arch/arm64/lib/copy_page.S
arch/arm64/mm/dma-mapping.c
arch/arm64/mm/fault.c
arch/arm64/mm/mmu.c
arch/arm64/mm/numa.c
arch/blackfin/include/asm/bug.h
arch/blackfin/include/asm/flat.h
arch/blackfin/kernel/flat.c
arch/h8300/include/asm/flat.h
arch/ia64/include/asm/tlb.h
arch/m68k/include/asm/flat.h
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/boot/compressed/.gitignore [new file with mode: 0644]
arch/mips/cavium-octeon/octeon-usb.c
arch/mips/dec/int-handler.S
arch/mips/include/asm/cache.h
arch/mips/include/asm/cpu-features.h
arch/mips/include/asm/mach-ralink/ralink_regs.h
arch/mips/include/asm/octeon/cvmx-l2c-defs.h
arch/mips/include/asm/octeon/cvmx-l2d-defs.h [new file with mode: 0644]
arch/mips/include/asm/octeon/cvmx.h
arch/mips/include/uapi/asm/ioctls.h
arch/mips/kernel/smp.c
arch/mips/mm/dma-default.c
arch/mips/mm/uasm-mips.c
arch/mips/net/ebpf_jit.c [new file with mode: 0644]
arch/mips/pci/pci.c
arch/mips/ralink/mt7620.c
arch/mips/vdso/gettimeofday.c
arch/mn10300/include/asm/bug.h
arch/parisc/Kconfig
arch/parisc/configs/712_defconfig
arch/parisc/configs/a500_defconfig
arch/parisc/configs/b180_defconfig
arch/parisc/configs/c3000_defconfig
arch/parisc/configs/c8000_defconfig
arch/parisc/configs/default_defconfig
arch/parisc/configs/generic-32bit_defconfig
arch/parisc/configs/generic-64bit_defconfig
arch/parisc/include/asm/bug.h
arch/parisc/include/asm/pdcpat.h
arch/parisc/include/asm/thread_info.h
arch/parisc/include/uapi/asm/ioctls.h
arch/parisc/kernel/cache.c
arch/parisc/kernel/firmware.c
arch/parisc/kernel/irq.c
arch/parisc/kernel/pdt.c
arch/parisc/kernel/process.c
arch/parisc/kernel/vmlinux.lds.S
arch/powerpc/Makefile
arch/powerpc/boot/Makefile
arch/powerpc/configs/powernv_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/include/asm/book3s/64/hash.h
arch/powerpc/include/asm/book3s/64/mmu.h
arch/powerpc/include/asm/book3s/64/pgtable.h
arch/powerpc/include/asm/book3s/64/radix.h
arch/powerpc/include/asm/bug.h
arch/powerpc/include/asm/mmu_context.h
arch/powerpc/include/asm/pgtable.h
arch/powerpc/include/uapi/asm/ioctls.h
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/idle_book3s.S
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/watchdog.c
arch/powerpc/kvm/book3s_64_mmu_hv.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/mm/mem.c
arch/powerpc/mm/mmu_context_book3s64.c
arch/powerpc/mm/pgtable-hash64.c
arch/powerpc/mm/pgtable-radix.c
arch/powerpc/mm/pgtable_64.c
arch/powerpc/mm/subpage-prot.c
arch/powerpc/mm/tlb-radix.c
arch/powerpc/platforms/83xx/mpc832x_rdb.c
arch/powerpc/platforms/powernv/idle.c
arch/powerpc/platforms/powernv/opal.c
arch/powerpc/platforms/powernv/pci-ioda.c
arch/powerpc/platforms/pseries/reconfig.c
arch/s390/include/asm/bug.h
arch/s390/include/asm/tlb.h
arch/s390/kernel/perf_cpum_sf.c
arch/s390/kvm/kvm-s390.c
arch/s390/mm/pgtable.c
arch/s390/net/bpf_jit_comp.c
arch/sh/include/asm/bug.h
arch/sh/include/asm/tlb.h
arch/sh/include/uapi/asm/ioctls.h
arch/sparc/configs/sparc32_defconfig
arch/sparc/configs/sparc64_defconfig
arch/sparc/include/asm/mmu_context_64.h
arch/sparc/include/asm/spitfire.h
arch/sparc/include/asm/trap_block.h
arch/sparc/include/uapi/asm/ioctls.h
arch/sparc/kernel/cpu.c
arch/sparc/kernel/cpumap.c
arch/sparc/kernel/head_64.S
arch/sparc/kernel/pci_sun4v.c
arch/sparc/kernel/setup_64.c
arch/sparc/kernel/smp_64.c
arch/sparc/kernel/sun4v_ivec.S
arch/sparc/kernel/traps_64.c
arch/sparc/kernel/tsb.S
arch/sparc/lib/U3memcpy.S
arch/sparc/mm/init_64.c
arch/sparc/power/hibernate.c
arch/um/include/asm/tlb.h
arch/x86/Kconfig.debug
arch/x86/boot/Makefile
arch/x86/boot/compressed/Makefile
arch/x86/boot/string.c
arch/x86/configs/i386_defconfig
arch/x86/configs/x86_64_defconfig
arch/x86/entry/entry_64.S
arch/x86/events/core.c
arch/x86/events/intel/core.c
arch/x86/events/intel/cstate.c
arch/x86/events/intel/ds.c
arch/x86/events/intel/lbr.c
arch/x86/events/intel/uncore_snbep.c
arch/x86/events/perf_event.h
arch/x86/include/asm/bug.h
arch/x86/include/asm/entry_arch.h
arch/x86/include/asm/hardirq.h
arch/x86/include/asm/hw_irq.h
arch/x86/include/asm/hypervisor.h
arch/x86/include/asm/io.h
arch/x86/include/asm/irq_vectors.h
arch/x86/include/asm/kprobes.h
arch/x86/include/asm/mmu_context.h
arch/x86/include/asm/paravirt_types.h
arch/x86/include/asm/processor.h
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/aperfmperf.c
arch/x86/kernel/devicetree.c
arch/x86/kernel/early-quirks.c
arch/x86/kernel/hpet.c
arch/x86/kernel/irq.c
arch/x86/kernel/irqinit.c
arch/x86/kernel/kprobes/core.c
arch/x86/kernel/kvm.c
arch/x86/kernel/reboot.c
arch/x86/kvm/Kconfig
arch/x86/kvm/hyperv.c
arch/x86/kvm/lapic.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/math-emu/Makefile
arch/x86/math-emu/fpu_emu.h
arch/x86/math-emu/reg_compare.c
arch/x86/mm/init.c
arch/x86/platform/intel-mid/device_libs/platform_max7315.c
arch/x86/platform/uv/tlb_uv.c
arch/x86/xen/enlighten_hvm.c
arch/x86/xen/smp_pv.c
arch/x86/xen/time.c
arch/xtensa/include/asm/Kbuild
arch/xtensa/include/asm/device.h [deleted file]
arch/xtensa/include/asm/param.h [deleted file]
arch/xtensa/include/uapi/asm/ioctls.h
arch/xtensa/kernel/xtensa_ksyms.c
arch/xtensa/mm/cache.c
block/bfq-iosched.c
block/bfq-iosched.h
block/bfq-wf2q.c
block/bio-integrity.c
block/blk-core.c
block/blk-mq-cpumap.c
block/blk-mq.c
crypto/authencesn.c
drivers/acpi/acpi_apd.c
drivers/acpi/acpi_lpss.c
drivers/acpi/acpi_watchdog.c
drivers/acpi/ec.c
drivers/acpi/internal.h
drivers/acpi/nfit/core.c
drivers/acpi/numa.c
drivers/acpi/sleep.c
drivers/acpi/spcr.c
drivers/android/binder.c
drivers/ata/Kconfig
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/sata_rcar.c
drivers/atm/zatm.c
drivers/base/dma-coherent.c
drivers/base/dma-mapping.c
drivers/base/firmware_class.c
drivers/base/power/domain.c
drivers/base/regmap/regmap-w1.c
drivers/block/nbd.c
drivers/block/sunvdc.c
drivers/block/virtio_blk.c
drivers/block/xen-blkfront.c
drivers/block/zram/zram_drv.c
drivers/bus/uniphier-system-bus.c
drivers/char/agp/ali-agp.c
drivers/char/agp/amd-k7-agp.c
drivers/char/agp/amd64-agp.c
drivers/char/agp/ati-agp.c
drivers/char/agp/efficeon-agp.c
drivers/char/agp/intel-agp.c
drivers/char/agp/nvidia-agp.c
drivers/char/agp/sis-agp.c
drivers/char/agp/uninorth-agp.c
drivers/char/random.c
drivers/clk/clk-gemini.c
drivers/clk/keystone/sci-clk.c
drivers/clk/meson/clk-mpll.c
drivers/clk/meson/clkc.h
drivers/clk/meson/gxbb.c
drivers/clk/meson/meson8b.c
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/sunxi-ng/ccu-sun5i.c
drivers/clk/x86/clk-pmc-atom.c
drivers/clocksource/timer-of.c
drivers/cpufreq/intel_pstate.c
drivers/cpuidle/cpuidle-powernv.c
drivers/crypto/Kconfig
drivers/crypto/bcm/spu2.c
drivers/crypto/cavium/nitrox/nitrox_main.c
drivers/crypto/inside-secure/safexcel.c
drivers/crypto/inside-secure/safexcel_hash.c
drivers/dax/device-dax.h
drivers/dax/device.c
drivers/dax/pmem.c
drivers/dax/super.c
drivers/dma-buf/dma-fence.c
drivers/dma-buf/reservation.c
drivers/dma-buf/sw_sync.c
drivers/dma-buf/sync_debug.c
drivers/dma-buf/sync_debug.h
drivers/dma-buf/sync_file.c
drivers/fsi/fsi-core.c
drivers/gpio/Kconfig
drivers/gpio/gpio-exar.c
drivers/gpio/gpio-lp87565.c
drivers/gpio/gpio-mxc.c
drivers/gpio/gpio-tegra.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/Makefile
drivers/gpu/drm/amd/amdgpu/Makefile
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h [new file with mode: 0644]
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h
drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c [new file with mode: 0644]
drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h [new file with mode: 0644]
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
drivers/gpu/drm/amd/amdgpu/cik.c
drivers/gpu/drm/amd/amdgpu/cik_sdma.c
drivers/gpu/drm/amd/amdgpu/clearstate_gfx9.h
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
drivers/gpu/drm/amd/amdgpu/dce_virtual.c
drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.h
drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c
drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h
drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h
drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h
drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h
drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c
drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h
drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
drivers/gpu/drm/amd/amdgpu/psp_v10_0.h
drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
drivers/gpu/drm/amd/amdgpu/si.c
drivers/gpu/drm/amd/amdgpu/si_dpm.c
drivers/gpu/drm/amd/amdgpu/soc15.c
drivers/gpu/drm/amd/amdgpu/soc15_common.h
drivers/gpu/drm/amd/amdgpu/soc15d.h
drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
drivers/gpu/drm/amd/include/atomfirmware.h
drivers/gpu/drm/amd/include/cgs_common.h
drivers/gpu/drm/amd/include/kgd_kfd_interface.h
drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c
drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h
drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
drivers/gpu/drm/amd/powerplay/inc/pp_debug.h
drivers/gpu/drm/amd/powerplay/inc/pp_soc15.h
drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h
drivers/gpu/drm/amd/powerplay/inc/smu9.h
drivers/gpu/drm/amd/powerplay/inc/smu9_driver_if.h
drivers/gpu/drm/amd/powerplay/inc/smumgr.h
drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h
drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c
drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h
drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h
drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c
drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h
drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c
drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h
drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
drivers/gpu/drm/arc/arcpgu_crtc.c
drivers/gpu/drm/arc/arcpgu_drv.c
drivers/gpu/drm/arm/hdlcd_crtc.c
drivers/gpu/drm/arm/hdlcd_drv.c
drivers/gpu/drm/arm/malidp_crtc.c
drivers/gpu/drm/arm/malidp_drv.c
drivers/gpu/drm/arm/malidp_planes.c
drivers/gpu/drm/armada/armada_crtc.c
drivers/gpu/drm/armada/armada_crtc.h
drivers/gpu/drm/armada/armada_drv.c
drivers/gpu/drm/armada/armada_fbdev.c
drivers/gpu/drm/armada/armada_overlay.c
drivers/gpu/drm/ast/ast_dp501.c
drivers/gpu/drm/ast/ast_drv.c
drivers/gpu/drm/ast/ast_drv.h
drivers/gpu/drm/ast/ast_fb.c
drivers/gpu/drm/ast/ast_main.c
drivers/gpu/drm/ast/ast_mode.c
drivers/gpu/drm/ast/ast_ttm.c
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
drivers/gpu/drm/bochs/bochs_drv.c
drivers/gpu/drm/bochs/bochs_fbdev.c
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
drivers/gpu/drm/bridge/analogix-anx78xx.c
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
drivers/gpu/drm/bridge/dumb-vga-dac.c
drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
drivers/gpu/drm/bridge/nxp-ptn3460.c
drivers/gpu/drm/bridge/panel.c
drivers/gpu/drm/bridge/parade-ps8622.c
drivers/gpu/drm/bridge/sii902x.c
drivers/gpu/drm/bridge/synopsys/Kconfig
drivers/gpu/drm/bridge/synopsys/Makefile
drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c [new file with mode: 0644]
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h [new file with mode: 0644]
drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c [new file with mode: 0644]
drivers/gpu/drm/bridge/tc358767.c
drivers/gpu/drm/bridge/ti-tfp410.c
drivers/gpu/drm/cirrus/cirrus_drv.c
drivers/gpu/drm/cirrus/cirrus_drv.h
drivers/gpu/drm/cirrus/cirrus_fbdev.c
drivers/gpu/drm/cirrus/cirrus_main.c
drivers/gpu/drm/cirrus/cirrus_mode.c
drivers/gpu/drm/drm_atomic.c
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/drm_color_mgmt.c
drivers/gpu/drm/drm_connector.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/drm_crtc_internal.h
drivers/gpu/drm/drm_debugfs_crc.c
drivers/gpu/drm/drm_dp_helper.c
drivers/gpu/drm/drm_dp_mst_topology.c
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_dumb_buffers.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_fb_cma_helper.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/drm_file.c
drivers/gpu/drm/drm_framebuffer.c
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_gem_cma_helper.c
drivers/gpu/drm/drm_gem_framebuffer_helper.c [new file with mode: 0644]
drivers/gpu/drm/drm_internal.h
drivers/gpu/drm/drm_ioc32.c
drivers/gpu/drm/drm_ioctl.c
drivers/gpu/drm/drm_mipi_dsi.c
drivers/gpu/drm/drm_mode_config.c
drivers/gpu/drm/drm_mode_object.c
drivers/gpu/drm/drm_modes.c
drivers/gpu/drm/drm_modeset_helper.c
drivers/gpu/drm/drm_modeset_lock.c
drivers/gpu/drm/drm_of.c
drivers/gpu/drm/drm_pci.c
drivers/gpu/drm/drm_plane.c
drivers/gpu/drm/drm_probe_helper.c
drivers/gpu/drm/drm_property.c
drivers/gpu/drm/drm_scdc_helper.c
drivers/gpu/drm/drm_simple_kms_helper.c
drivers/gpu/drm/drm_syncobj.c
drivers/gpu/drm/drm_vblank.c
drivers/gpu/drm/drm_vm.c
drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
drivers/gpu/drm/exynos/Kconfig
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_dpi.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/exynos/exynos_drm_dsi.c
drivers/gpu/drm/exynos/exynos_drm_fb.c
drivers/gpu/drm/exynos/exynos_drm_fbdev.c
drivers/gpu/drm/exynos/exynos_drm_gem.c
drivers/gpu/drm/exynos/exynos_drm_gem.h
drivers/gpu/drm/exynos/exynos_drm_mic.c
drivers/gpu/drm/exynos/exynos_drm_plane.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
drivers/gpu/drm/gma500/framebuffer.c
drivers/gpu/drm/gma500/gem.c
drivers/gpu/drm/gma500/gma_display.c
drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
drivers/gpu/drm/gma500/mdfld_intel_display.c
drivers/gpu/drm/gma500/psb_drv.c
drivers/gpu/drm/gma500/psb_drv.h
drivers/gpu/drm/gma500/psb_intel_display.c
drivers/gpu/drm/gma500/psb_intel_drv.h
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h
drivers/gpu/drm/i2c/tda998x_drv.c
drivers/gpu/drm/i810/i810_drv.c
drivers/gpu/drm/i915/Kconfig
drivers/gpu/drm/i915/gvt/display.c
drivers/gpu/drm/i915/gvt/execlist.c
drivers/gpu/drm/i915/gvt/firmware.c
drivers/gpu/drm/i915/gvt/gvt.h
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/gvt/scheduler.c
drivers/gpu/drm/i915/gvt/vgpu.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_clflush.c
drivers/gpu/drm/i915/i915_gem_clflush.h
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_context.h
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_gem_gtt.h
drivers/gpu/drm/i915/i915_gem_request.c
drivers/gpu/drm/i915/i915_gem_request.h
drivers/gpu/drm/i915/i915_gem_shrinker.c
drivers/gpu/drm/i915/i915_gpu_error.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_params.c
drivers/gpu/drm/i915/i915_params.h
drivers/gpu/drm/i915/i915_pci.c
drivers/gpu/drm/i915/i915_perf.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_sysfs.c
drivers/gpu/drm/i915/i915_vma.c
drivers/gpu/drm/i915/i915_vma.h
drivers/gpu/drm/i915/intel_atomic_plane.c
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_color.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_device_info.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_dp_aux_backlight.c
drivers/gpu/drm/i915/intel_dp_mst.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_dsi.c
drivers/gpu/drm/i915/intel_dvo.c
drivers/gpu/drm/i915/intel_engine_cs.c
drivers/gpu/drm/i915/intel_fbdev.c
drivers/gpu/drm/i915/intel_gvt.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h
drivers/gpu/drm/i915/intel_runtime_pm.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_sprite.c
drivers/gpu/drm/i915/intel_tv.c
drivers/gpu/drm/i915/intel_uncore.c
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
drivers/gpu/drm/i915/selftests/i915_vma.c
drivers/gpu/drm/i915/selftests/intel_hangcheck.c
drivers/gpu/drm/i915/selftests/mock_context.c
drivers/gpu/drm/i915/selftests/mock_context.h
drivers/gpu/drm/i915/selftests/mock_gem_device.c
drivers/gpu/drm/i915/selftests/mock_gtt.c
drivers/gpu/drm/imx/imx-drm-core.c
drivers/gpu/drm/imx/imx-ldb.c
drivers/gpu/drm/imx/imx-tve.c
drivers/gpu/drm/imx/ipuv3-crtc.c
drivers/gpu/drm/imx/ipuv3-plane.c
drivers/gpu/drm/imx/parallel-display.c
drivers/gpu/drm/mediatek/mtk_disp_color.c
drivers/gpu/drm/mediatek/mtk_disp_ovl.c
drivers/gpu/drm/mediatek/mtk_disp_rdma.c
drivers/gpu/drm/mediatek/mtk_dpi.c
drivers/gpu/drm/mediatek/mtk_drm_crtc.c
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
drivers/gpu/drm/mediatek/mtk_drm_drv.c
drivers/gpu/drm/mediatek/mtk_drm_fb.c
drivers/gpu/drm/mediatek/mtk_drm_gem.c
drivers/gpu/drm/mediatek/mtk_drm_gem.h
drivers/gpu/drm/mediatek/mtk_drm_plane.c
drivers/gpu/drm/mediatek/mtk_dsi.c
drivers/gpu/drm/mediatek/mtk_hdmi.c
drivers/gpu/drm/meson/meson_crtc.c
drivers/gpu/drm/meson/meson_drv.c
drivers/gpu/drm/meson/meson_plane.c
drivers/gpu/drm/meson/meson_venc_cvbs.c
drivers/gpu/drm/mga/mga_drv.c
drivers/gpu/drm/mgag200/mgag200_cursor.c
drivers/gpu/drm/mgag200/mgag200_drv.c
drivers/gpu/drm/mgag200/mgag200_drv.h
drivers/gpu/drm/mgag200/mgag200_fb.c
drivers/gpu/drm/mgag200/mgag200_main.c
drivers/gpu/drm/mgag200/mgag200_mode.c
drivers/gpu/drm/msm/Kconfig
drivers/gpu/drm/msm/adreno/a5xx_gpu.c
drivers/gpu/drm/msm/adreno/a5xx_gpu.h
drivers/gpu/drm/msm/adreno/adreno_gpu.c
drivers/gpu/drm/msm/dsi/dsi_host.c
drivers/gpu/drm/msm/dsi/dsi_manager.c
drivers/gpu/drm/msm/edp/edp_connector.c
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
drivers/gpu/drm/msm/hdmi/hdmi_connector.c
drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
drivers/gpu/drm/msm/msm_atomic.c
drivers/gpu/drm/msm/msm_drv.c
drivers/gpu/drm/msm/msm_fbdev.c
drivers/gpu/drm/msm/msm_gem.c
drivers/gpu/drm/msm/msm_gem_submit.c
drivers/gpu/drm/msm/msm_gem_vma.c
drivers/gpu/drm/mxsfb/mxsfb_drv.c
drivers/gpu/drm/mxsfb/mxsfb_out.c
drivers/gpu/drm/nouveau/dispnv04/crtc.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_crtc.h
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/nouveau/nouveau_fbcon.c
drivers/gpu/drm/nouveau/nouveau_ttm.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild
drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h
drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c
drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c
drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c
drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
drivers/gpu/drm/omapdrm/displays/panel-dpi.c
drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
drivers/gpu/drm/omapdrm/dss/Makefile
drivers/gpu/drm/omapdrm/dss/core.c
drivers/gpu/drm/omapdrm/dss/dispc.c
drivers/gpu/drm/omapdrm/dss/dpi.c
drivers/gpu/drm/omapdrm/dss/dsi.c
drivers/gpu/drm/omapdrm/dss/dss.c
drivers/gpu/drm/omapdrm/dss/dss.h
drivers/gpu/drm/omapdrm/dss/dss_features.c [deleted file]
drivers/gpu/drm/omapdrm/dss/dss_features.h [deleted file]
drivers/gpu/drm/omapdrm/dss/hdmi.h
drivers/gpu/drm/omapdrm/dss/hdmi4.c
drivers/gpu/drm/omapdrm/dss/hdmi4_core.c
drivers/gpu/drm/omapdrm/dss/hdmi5.c
drivers/gpu/drm/omapdrm/dss/hdmi_phy.c
drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
drivers/gpu/drm/omapdrm/dss/omapdss.h
drivers/gpu/drm/omapdrm/dss/venc.c
drivers/gpu/drm/omapdrm/dss/video-pll.c
drivers/gpu/drm/omapdrm/omap_connector.c
drivers/gpu/drm/omapdrm/omap_crtc.c
drivers/gpu/drm/omapdrm/omap_drv.c
drivers/gpu/drm/omapdrm/omap_encoder.c
drivers/gpu/drm/omapdrm/omap_fb.c
drivers/gpu/drm/omapdrm/omap_fbdev.c
drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
drivers/gpu/drm/omapdrm/omap_plane.c
drivers/gpu/drm/panel/panel-lvds.c
drivers/gpu/drm/pl111/pl111_connector.c
drivers/gpu/drm/pl111/pl111_display.c
drivers/gpu/drm/pl111/pl111_drv.c
drivers/gpu/drm/qxl/qxl_display.c
drivers/gpu/drm/qxl/qxl_drv.c
drivers/gpu/drm/qxl/qxl_drv.h
drivers/gpu/drm/qxl/qxl_fb.c
drivers/gpu/drm/qxl/qxl_ioctl.c
drivers/gpu/drm/qxl/qxl_object.c
drivers/gpu/drm/qxl/qxl_ttm.c
drivers/gpu/drm/r128/r128_drv.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_acpi.c
drivers/gpu/drm/radeon/radeon_acpi.h
drivers/gpu/drm/radeon/radeon_audio.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_cs.c
drivers/gpu/drm/radeon/radeon_cursor.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_dp_mst.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_fb.c
drivers/gpu/drm/radeon/radeon_gem.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/radeon_kfd.c
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/radeon/radeon_vm.c
drivers/gpu/drm/radeon/vce_v2_0.c
drivers/gpu/drm/rcar-du/rcar_du_crtc.c
drivers/gpu/drm/rcar-du/rcar_du_crtc.h
drivers/gpu/drm/rcar-du/rcar_du_drv.c
drivers/gpu/drm/rcar-du/rcar_du_encoder.c
drivers/gpu/drm/rcar-du/rcar_du_group.c
drivers/gpu/drm/rcar-du/rcar_du_kms.c
drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
drivers/gpu/drm/rcar-du/rcar_du_plane.c
drivers/gpu/drm/rcar-du/rcar_du_plane.h
drivers/gpu/drm/rcar-du/rcar_du_vsp.c
drivers/gpu/drm/rcar-du/rcar_du_vsp.h
drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
drivers/gpu/drm/rockchip/Kconfig
drivers/gpu/drm/rockchip/cdn-dp-core.c
drivers/gpu/drm/rockchip/dw-mipi-dsi.c
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
drivers/gpu/drm/rockchip/inno_hdmi.c
drivers/gpu/drm/rockchip/rockchip_drm_drv.c
drivers/gpu/drm/rockchip/rockchip_drm_fb.c
drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
drivers/gpu/drm/rockchip/rockchip_drm_gem.c
drivers/gpu/drm/rockchip/rockchip_drm_gem.h
drivers/gpu/drm/rockchip/rockchip_drm_vop.c
drivers/gpu/drm/rockchip/rockchip_drm_vop.h
drivers/gpu/drm/rockchip/rockchip_vop_reg.c
drivers/gpu/drm/rockchip/rockchip_vop_reg.h
drivers/gpu/drm/savage/savage_drv.c
drivers/gpu/drm/shmobile/shmob_drm_drv.c
drivers/gpu/drm/sis/sis_drv.c
drivers/gpu/drm/sti/sti_crtc.c
drivers/gpu/drm/sti/sti_cursor.c
drivers/gpu/drm/sti/sti_drv.c
drivers/gpu/drm/sti/sti_dvo.c
drivers/gpu/drm/sti/sti_gdp.c
drivers/gpu/drm/sti/sti_hda.c
drivers/gpu/drm/sti/sti_hdmi.c
drivers/gpu/drm/sti/sti_hqvdp.c
drivers/gpu/drm/stm/Kconfig
drivers/gpu/drm/stm/Makefile
drivers/gpu/drm/stm/drv.c
drivers/gpu/drm/stm/dw_mipi_dsi-stm.c [new file with mode: 0644]
drivers/gpu/drm/stm/ltdc.c
drivers/gpu/drm/stm/ltdc.h
drivers/gpu/drm/sun4i/sun4i_crtc.c
drivers/gpu/drm/sun4i/sun4i_drv.c
drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
drivers/gpu/drm/sun4i/sun4i_layer.c
drivers/gpu/drm/sun4i/sun4i_rgb.c
drivers/gpu/drm/sun4i/sun4i_tv.c
drivers/gpu/drm/sun4i/sun8i_layer.c
drivers/gpu/drm/tdfx/tdfx_drv.c
drivers/gpu/drm/tegra/dc.c
drivers/gpu/drm/tegra/drm.c
drivers/gpu/drm/tegra/dsi.c
drivers/gpu/drm/tegra/gem.c
drivers/gpu/drm/tegra/gem.h
drivers/gpu/drm/tegra/hdmi.c
drivers/gpu/drm/tegra/rgb.c
drivers/gpu/drm/tegra/sor.c
drivers/gpu/drm/tilcdc/tilcdc_crtc.c
drivers/gpu/drm/tilcdc/tilcdc_drv.c
drivers/gpu/drm/tilcdc/tilcdc_panel.c
drivers/gpu/drm/tilcdc/tilcdc_plane.c
drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
drivers/gpu/drm/tinydrm/Kconfig
drivers/gpu/drm/tinydrm/Makefile
drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
drivers/gpu/drm/tinydrm/mi0283qt.c
drivers/gpu/drm/tinydrm/mipi-dbi.c
drivers/gpu/drm/tinydrm/repaper.c [new file with mode: 0644]
drivers/gpu/drm/tinydrm/st7586.c [new file with mode: 0644]
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_bo_manager.c
drivers/gpu/drm/ttm/ttm_bo_vm.c
drivers/gpu/drm/ttm/ttm_page_alloc.c
drivers/gpu/drm/udl/udl_connector.c
drivers/gpu/drm/udl/udl_dmabuf.c
drivers/gpu/drm/udl/udl_drv.c
drivers/gpu/drm/udl/udl_fb.c
drivers/gpu/drm/udl/udl_gem.c
drivers/gpu/drm/udl/udl_main.c
drivers/gpu/drm/vc4/Kconfig
drivers/gpu/drm/vc4/vc4_bo.c
drivers/gpu/drm/vc4/vc4_crtc.c
drivers/gpu/drm/vc4/vc4_dpi.c
drivers/gpu/drm/vc4/vc4_drv.c
drivers/gpu/drm/vc4/vc4_drv.h
drivers/gpu/drm/vc4/vc4_dsi.c
drivers/gpu/drm/vc4/vc4_gem.c
drivers/gpu/drm/vc4/vc4_hdmi.c
drivers/gpu/drm/vc4/vc4_kms.c
drivers/gpu/drm/vc4/vc4_plane.c
drivers/gpu/drm/vc4/vc4_regs.h
drivers/gpu/drm/vc4/vc4_render_cl.c
drivers/gpu/drm/vc4/vc4_v3d.c
drivers/gpu/drm/vc4/vc4_validate.c
drivers/gpu/drm/vc4/vc4_validate_shaders.c
drivers/gpu/drm/vc4/vc4_vec.c
drivers/gpu/drm/vgem/vgem_drv.c
drivers/gpu/drm/vgem/vgem_drv.h
drivers/gpu/drm/vgem/vgem_fence.c
drivers/gpu/drm/via/via_drv.c
drivers/gpu/drm/virtio/virtgpu_display.c
drivers/gpu/drm/virtio/virtgpu_drv.c
drivers/gpu/drm/virtio/virtgpu_drv.h
drivers/gpu/drm/virtio/virtgpu_fb.c
drivers/gpu/drm/virtio/virtgpu_gem.c
drivers/gpu/drm/virtio/virtgpu_plane.c
drivers/gpu/drm/virtio/virtgpu_ttm.c
drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
drivers/gpu/drm/vmwgfx/vmwgfx_context.c
drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
drivers/gpu/drm/zte/zx_drm_drv.c
drivers/gpu/drm/zte/zx_hdmi.c
drivers/gpu/drm/zte/zx_plane.c
drivers/gpu/drm/zte/zx_tvenc.c
drivers/gpu/drm/zte/zx_vga.c
drivers/gpu/drm/zte/zx_vou.c
drivers/gpu/host1x/bus.c
drivers/gpu/host1x/dev.c
drivers/gpu/ipu-v3/ipu-common.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-logitech-hidpp.c
drivers/hid/hid-multitouch.c
drivers/hid/hid-ortek.c
drivers/hid/usbhid/hid-core.c
drivers/hv/channel.c
drivers/hwmon/applesmc.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/i2c-core-acpi.c
drivers/i2c/i2c-core-base.c
drivers/i2c/i2c-core.h
drivers/i2c/muxes/Kconfig
drivers/ide/ide-timings.c
drivers/iio/accel/bmc150-accel-core.c
drivers/iio/accel/st_accel_core.c
drivers/iio/adc/aspeed_adc.c
drivers/iio/adc/axp288_adc.c
drivers/iio/adc/sun4i-gpadc-iio.c
drivers/iio/adc/vf610_adc.c
drivers/iio/common/st_sensors/st_sensors_core.c
drivers/iio/light/tsl2563.c
drivers/iio/pressure/st_pressure_core.c
drivers/infiniband/core/addr.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/roce_gid_mgmt.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/bnxt_re/bnxt_re.h
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/ib_verbs.h
drivers/infiniband/hw/bnxt_re/main.c
drivers/infiniband/hw/bnxt_re/qplib_fp.c
drivers/infiniband/hw/bnxt_re/qplib_fp.h
drivers/infiniband/hw/bnxt_re/qplib_sp.c
drivers/infiniband/hw/bnxt_re/qplib_sp.h
drivers/infiniband/hw/cxgb3/iwch_provider.c
drivers/infiniband/hw/cxgb4/cq.c
drivers/infiniband/hw/cxgb4/qp.c
drivers/infiniband/hw/hfi1/chip.c
drivers/infiniband/hw/hfi1/qp.c
drivers/infiniband/hw/hfi1/qp.h
drivers/infiniband/hw/hns/hns_roce_hw_v1.c
drivers/infiniband/hw/hns/hns_roce_main.c
drivers/infiniband/hw/i40iw/i40iw.h
drivers/infiniband/hw/i40iw/i40iw_cm.c
drivers/infiniband/hw/i40iw/i40iw_ctrl.c
drivers/infiniband/hw/i40iw/i40iw_main.c
drivers/infiniband/hw/i40iw/i40iw_puda.c
drivers/infiniband/hw/i40iw/i40iw_utils.c
drivers/infiniband/hw/i40iw/i40iw_verbs.c
drivers/infiniband/hw/i40iw/i40iw_verbs.h
drivers/infiniband/hw/mlx4/cm.c
drivers/infiniband/hw/mlx4/cq.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/mcg.c
drivers/infiniband/hw/mlx4/mlx4_ib.h
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/mlx4/srq.c
drivers/infiniband/hw/mlx5/mr.c
drivers/infiniband/hw/mlx5/odp.c
drivers/infiniband/hw/nes/nes_hw.c
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
drivers/infiniband/hw/qedr/verbs.c
drivers/infiniband/hw/qib/qib_qp.c
drivers/infiniband/hw/qib/qib_verbs.h
drivers/infiniband/sw/rdmavt/qp.c
drivers/infiniband/sw/rxe/rxe_net.c
drivers/infiniband/sw/rxe/rxe_resp.c
drivers/infiniband/sw/rxe/rxe_verbs.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/infiniband/ulp/iser/iser_initiator.c
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/iommu/amd_iommu.c
drivers/iommu/amd_iommu_init.c
drivers/iommu/arm-smmu.c
drivers/iommu/io-pgtable-arm-v7s.c
drivers/iommu/io-pgtable-arm.c
drivers/iommu/io-pgtable.h
drivers/iommu/mtk_iommu.c
drivers/iommu/mtk_iommu.h
drivers/irqchip/irq-digicolor.c
drivers/irqchip/irq-gic-realview.c
drivers/irqchip/irq-mips-cpu.c
drivers/irqchip/irq-mips-gic.c
drivers/isdn/divert/isdn_divert.c
drivers/isdn/hardware/avm/c4.c
drivers/isdn/hardware/eicon/divasmain.c
drivers/isdn/hardware/mISDN/avmfritz.c
drivers/isdn/hardware/mISDN/hfcmulti.c
drivers/isdn/hardware/mISDN/hfcpci.c
drivers/isdn/hardware/mISDN/netjet.c
drivers/isdn/hardware/mISDN/w6692.c
drivers/isdn/hisax/config.c
drivers/isdn/hisax/hfc4s8s_l1.c
drivers/isdn/hisax/hisax_fcpcipnp.c
drivers/isdn/hysdn/hysdn_proclog.c
drivers/isdn/i4l/isdn_common.c
drivers/isdn/i4l/isdn_net.c
drivers/lightnvm/pblk-rb.c
drivers/lightnvm/pblk-read.c
drivers/lightnvm/pblk.h
drivers/mailbox/pcc.c
drivers/md/bitmap.c
drivers/md/dm-bufio.c
drivers/md/dm-integrity.c
drivers/md/dm-raid.c
drivers/md/dm-table.c
drivers/md/dm-verity-fec.c
drivers/md/dm-zoned-metadata.c
drivers/md/dm-zoned-reclaim.c
drivers/md/dm-zoned-target.c
drivers/md/md.c
drivers/md/md.h
drivers/md/raid1-10.c [new file with mode: 0644]
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5-ppl.c
drivers/md/raid5.c
drivers/media/cec/cec-adap.c
drivers/media/cec/cec-notifier.c
drivers/media/dvb-core/dvb_ca_en50221.c
drivers/media/dvb-core/dvb_ca_en50221.h
drivers/media/dvb-frontends/cxd2841er.c
drivers/media/dvb-frontends/drx39xyj/drx_driver.h
drivers/media/dvb-frontends/lnbh25.c
drivers/media/dvb-frontends/stv0367.c
drivers/media/i2c/et8ek8/et8ek8_driver.c
drivers/media/i2c/tvp5150.c
drivers/media/pci/ddbridge/ddbridge-core.c
drivers/media/pci/ngene/ngene-core.c
drivers/media/pci/ngene/ngene-i2c.c
drivers/media/pci/ngene/ngene.h
drivers/media/pci/tw5864/tw5864-video.c
drivers/media/platform/Kconfig
drivers/media/platform/coda/coda-bit.c
drivers/media/platform/coda/coda-common.c
drivers/media/platform/coda/coda.h
drivers/media/platform/davinci/ccdc_hw_device.h
drivers/media/platform/davinci/dm355_ccdc.c
drivers/media/platform/davinci/dm644x_ccdc.c
drivers/media/platform/davinci/vpfe_capture.c
drivers/media/platform/davinci/vpif_capture.c
drivers/media/platform/davinci/vpif_display.c
drivers/media/platform/omap/omap_vout_vrfb.c
drivers/media/platform/omap/omap_voutdef.h
drivers/media/platform/qcom/venus/core.c
drivers/media/platform/qcom/venus/core.h
drivers/media/platform/qcom/venus/firmware.c
drivers/media/platform/qcom/venus/firmware.h
drivers/media/platform/qcom/venus/hfi_msgs.c
drivers/media/platform/sti/bdisp/bdisp-debug.c
drivers/media/platform/vimc/vimc-capture.c
drivers/media/platform/vimc/vimc-debayer.c
drivers/media/platform/vimc/vimc-scaler.c
drivers/media/platform/vimc/vimc-sensor.c
drivers/media/platform/vsp1/vsp1.h
drivers/media/platform/vsp1/vsp1_bru.c
drivers/media/platform/vsp1/vsp1_bru.h
drivers/media/platform/vsp1/vsp1_dl.c
drivers/media/platform/vsp1/vsp1_dl.h
drivers/media/platform/vsp1/vsp1_drm.c
drivers/media/platform/vsp1/vsp1_drm.h
drivers/media/platform/vsp1/vsp1_drv.c
drivers/media/platform/vsp1/vsp1_entity.c
drivers/media/platform/vsp1/vsp1_entity.h
drivers/media/platform/vsp1/vsp1_lif.c
drivers/media/platform/vsp1/vsp1_lif.h
drivers/media/platform/vsp1/vsp1_pipe.c
drivers/media/platform/vsp1/vsp1_pipe.h
drivers/media/platform/vsp1/vsp1_regs.h
drivers/media/platform/vsp1/vsp1_video.c
drivers/media/platform/vsp1/vsp1_wpf.c
drivers/media/radio/radio-wl1273.c
drivers/media/rc/ir-lirc-codec.c
drivers/media/tuners/fc0011.c
drivers/media/tuners/mxl5005s.c
drivers/media/usb/au0828/au0828-input.c
drivers/media/usb/dvb-usb-v2/lmedm04.c
drivers/media/usb/dvb-usb/dib0700_core.c
drivers/media/usb/em28xx/em28xx-cards.c
drivers/media/usb/em28xx/em28xx-dvb.c
drivers/media/usb/em28xx/em28xx-i2c.c
drivers/media/usb/em28xx/em28xx-input.c
drivers/media/usb/em28xx/em28xx.h
drivers/media/usb/pulse8-cec/pulse8-cec.c
drivers/media/usb/rainshadow-cec/rainshadow-cec.c
drivers/media/usb/stkwebcam/stk-sensor.c
drivers/media/usb/stkwebcam/stk-webcam.c
drivers/media/usb/stkwebcam/stk-webcam.h
drivers/media/v4l2-core/tuner-core.c
drivers/misc/mei/pci-me.c
drivers/misc/mei/pci-txe.c
drivers/mmc/core/block.c
drivers/mmc/core/mmc.c
drivers/mmc/host/dw_mmc.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/sdhci-of-at91.c
drivers/mmc/host/sunxi-mmc.c
drivers/mtd/mtd_blkdevs.c
drivers/mtd/nand/atmel/nand-controller.c
drivers/mtd/nand/atmel/pmecc.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_timings.c
drivers/mtd/nand/sunxi_nand.c
drivers/mux/Kconfig
drivers/mux/mux-core.c
drivers/net/bonding/bond_main.c
drivers/net/dsa/b53/b53_common.c
drivers/net/dsa/mt7530.c
drivers/net/dsa/mt7530.h
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/ethernet/apm/xgene/xgene_enet_main.c
drivers/net/ethernet/aurora/nb8800.c
drivers/net/ethernet/broadcom/b44.c
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/broadcom/bgmac-platform.c
drivers/net/ethernet/broadcom/bgmac.c
drivers/net/ethernet/broadcom/bgmac.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/broadcom/genet/bcmgenet.h
drivers/net/ethernet/broadcom/genet/bcmmii.c
drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
drivers/net/ethernet/cavium/thunder/thunder_bgx.c
drivers/net/ethernet/cavium/thunder/thunder_bgx.h
drivers/net/ethernet/chelsio/cxgb4/cxgb4_ptp.c
drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h
drivers/net/ethernet/faraday/ftgmac100.c
drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/marvell/mv643xx_eth.c
drivers/net/ethernet/mediatek/mtk_eth_soc.c
drivers/net/ethernet/mellanox/mlx4/alloc.c
drivers/net/ethernet/mellanox/mlx4/cq.c
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
drivers/net/ethernet/mellanox/mlx4/en_rx.c
drivers/net/ethernet/mellanox/mlx4/en_tx.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/fw.h
drivers/net/ethernet/mellanox/mlx4/icm.c
drivers/net/ethernet/mellanox/mlx4/icm.h
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx4/mlx4.h
drivers/net/ethernet/mellanox/mlx4/mr.c
drivers/net/ethernet/mellanox/mlx4/qp.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/mellanox/mlx4/srq.c
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_clock.c
drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/eq.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
drivers/net/ethernet/mellanox/mlx5/core/lag.c
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
drivers/net/ethernet/mellanox/mlx5/core/sriov.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
drivers/net/ethernet/netronome/nfp/nfp_net_common.c
drivers/net/ethernet/qlogic/qed/qed_mcp.c
drivers/net/ethernet/qualcomm/emac/emac.c
drivers/net/ethernet/sgi/ioc3-eth.c
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/sun/niu.c
drivers/net/ethernet/sun/sunhme.h
drivers/net/ethernet/tehuti/tehuti.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/ethernet/ti/cpts.c
drivers/net/ethernet/ti/cpts.h
drivers/net/ethernet/toshiba/tc35815.c
drivers/net/geneve.c
drivers/net/gtp.c
drivers/net/hyperv/hyperv_net.h
drivers/net/hyperv/netvsc.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/hyperv/rndis_filter.c
drivers/net/ipvlan/ipvlan_main.c
drivers/net/irda/mcs7780.c
drivers/net/phy/Kconfig
drivers/net/phy/mdio-mux.c
drivers/net/phy/phy.c
drivers/net/ppp/ppp_generic.c
drivers/net/ppp/pptp.c
drivers/net/team/team.c
drivers/net/tun.c
drivers/net/usb/asix.h
drivers/net/usb/asix_common.c
drivers/net/usb/asix_devices.c
drivers/net/usb/cdc_ncm.c
drivers/net/usb/huawei_cdc_ncm.c
drivers/net/usb/lan78xx.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/smsc95xx.c
drivers/net/virtio_net.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/net/vxlan.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
drivers/net/wireless/intel/iwlwifi/dvm/tx.c
drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/pcie/trans.c
drivers/net/wireless/intel/iwlwifi/pcie/tx.c
drivers/net/wireless/ralink/rt2x00/rt2800lib.c
drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
drivers/net/wireless/realtek/rtlwifi/wifi.h
drivers/nvdimm/core.c
drivers/nvme/host/core.c
drivers/nvme/host/fc.c
drivers/nvme/host/pci.c
drivers/nvme/target/admin-cmd.c
drivers/nvme/target/configfs.c
drivers/nvme/target/core.c
drivers/nvme/target/fc.c
drivers/nvme/target/nvmet.h
drivers/nvmem/rockchip-efuse.c
drivers/of/irq.c
drivers/of/property.c
drivers/parisc/pdc_stable.c
drivers/pci/pci.c
drivers/perf/arm_pmu.c
drivers/perf/arm_pmu_platform.c
drivers/perf/qcom_l2_pmu.c
drivers/phy/broadcom/Kconfig
drivers/pinctrl/intel/pinctrl-cherryview.c
drivers/pinctrl/intel/pinctrl-merrifield.c
drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
drivers/pinctrl/stm32/Kconfig
drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c
drivers/pinctrl/zte/pinctrl-zx.c
drivers/platform/x86/Kconfig
drivers/platform/x86/dell-wmi.c
drivers/platform/x86/intel-vbtn.c
drivers/platform/x86/wmi.c
drivers/ptp/ptp_clock.c
drivers/ptp/ptp_private.h
drivers/s390/cio/chp.c
drivers/s390/net/qeth_l3_main.c
drivers/sbus/char/display7seg.c
drivers/sbus/char/flash.c
drivers/sbus/char/uctrl.c
drivers/scsi/Kconfig
drivers/scsi/aacraid/aachba.c
drivers/scsi/aic7xxx/Makefile
drivers/scsi/aic7xxx/aicasm/Makefile
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
drivers/scsi/bnx2fc/bnx2fc_hwi.c
drivers/scsi/bnx2i/bnx2i_init.c
drivers/scsi/cxgbi/libcxgbi.c
drivers/scsi/cxlflash/main.c
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
drivers/scsi/hpsa.c
drivers/scsi/isci/request.c
drivers/scsi/libfc/fc_disc.c
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_debugfs.c
drivers/scsi/lpfc/lpfc_nvmet.c
drivers/scsi/lpfc/lpfc_nvmet.h
drivers/scsi/megaraid/megaraid_sas_fusion.c
drivers/scsi/qedf/qedf.h
drivers/scsi/qedf/qedf_main.c
drivers/scsi/qedi/Kconfig
drivers/scsi/qedi/qedi.h
drivers/scsi/qedi/qedi_fw.c
drivers/scsi/qedi/qedi_iscsi.c
drivers/scsi/qedi/qedi_main.c
drivers/scsi/qedi/qedi_nvm_iscsi_cfg.h [new file with mode: 0644]
drivers/scsi/qla2xxx/qla_target.c
drivers/scsi/qla2xxx/tcm_qla2xxx.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/sg.c
drivers/scsi/smartpqi/smartpqi.h
drivers/scsi/virtio_scsi.c
drivers/soc/zte/Kconfig
drivers/spmi/spmi-pmic-arb.c
drivers/spmi/spmi.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/comedi/comedi_fops.c
drivers/staging/comedi/drivers/ni_mio_common.c
drivers/staging/iio/resolver/ad2s1210.c
drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
drivers/staging/media/atomisp/i2c/ap1302.h
drivers/staging/media/atomisp/i2c/gc0310.h
drivers/staging/media/atomisp/i2c/gc2235.h
drivers/staging/media/atomisp/i2c/imx/imx.h
drivers/staging/media/atomisp/i2c/ov2680.h
drivers/staging/media/atomisp/i2c/ov2722.h
drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
drivers/staging/media/atomisp/i2c/ov8858.h
drivers/staging/media/atomisp/i2c/ov8858_btns.h
drivers/staging/media/atomisp/pci/atomisp2/Makefile
drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h
drivers/staging/media/cxd2099/cxd2099.c
drivers/staging/media/cxd2099/cxd2099.h
drivers/staging/rtl8188eu/core/rtw_cmd.c
drivers/staging/rtl8188eu/os_dep/usb_intf.c
drivers/staging/sm750fb/ddk750_chip.c
drivers/staging/sm750fb/sm750.c
drivers/staging/speakup/main.c
drivers/staging/speakup/spk_priv.h
drivers/staging/speakup/spk_ttyio.c
drivers/staging/vboxvideo/Kconfig [new file with mode: 0644]
drivers/staging/vboxvideo/Makefile [new file with mode: 0644]
drivers/staging/vboxvideo/TODO [new file with mode: 0644]
drivers/staging/vboxvideo/hgsmi_base.c [new file with mode: 0644]
drivers/staging/vboxvideo/hgsmi_ch_setup.h [new file with mode: 0644]
drivers/staging/vboxvideo/hgsmi_channels.h [new file with mode: 0644]
drivers/staging/vboxvideo/hgsmi_defs.h [new file with mode: 0644]
drivers/staging/vboxvideo/modesetting.c [new file with mode: 0644]
drivers/staging/vboxvideo/vbox_drv.c [new file with mode: 0644]
drivers/staging/vboxvideo/vbox_drv.h [new file with mode: 0644]
drivers/staging/vboxvideo/vbox_err.h [new file with mode: 0644]
drivers/staging/vboxvideo/vbox_fb.c [new file with mode: 0644]
drivers/staging/vboxvideo/vbox_hgsmi.c [new file with mode: 0644]
drivers/staging/vboxvideo/vbox_irq.c [new file with mode: 0644]
drivers/staging/vboxvideo/vbox_main.c [new file with mode: 0644]
drivers/staging/vboxvideo/vbox_mode.c [new file with mode: 0644]
drivers/staging/vboxvideo/vbox_prime.c [new file with mode: 0644]
drivers/staging/vboxvideo/vbox_ttm.c [new file with mode: 0644]
drivers/staging/vboxvideo/vboxvideo.h [new file with mode: 0644]
drivers/staging/vboxvideo/vboxvideo_guest.h [new file with mode: 0644]
drivers/staging/vboxvideo/vboxvideo_vbe.h [new file with mode: 0644]
drivers/staging/vboxvideo/vbva_base.c [new file with mode: 0644]
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
drivers/target/iscsi/cxgbit/cxgbit_cm.c
drivers/target/iscsi/cxgbit/cxgbit_target.c
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_login.c
drivers/target/target_core_tpg.c
drivers/target/target_core_transport.c
drivers/target/target_core_user.c
drivers/thunderbolt/eeprom.c
drivers/thunderbolt/icm.c
drivers/thunderbolt/switch.c
drivers/thunderbolt/tb.h
drivers/thunderbolt/tb_msgs.h
drivers/tty/pty.c
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/8250/8250_exar.c
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/fsl_lpuart.c
drivers/tty/serial/imx.c
drivers/tty/serial/sh-sci.c
drivers/tty/serial/st-asc.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/quirks.c
drivers/usb/dwc2/gadget.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/dwc3-omap.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/f_mass_storage.c
drivers/usb/gadget/function/f_uac1.c
drivers/usb/gadget/function/f_uac2.c
drivers/usb/gadget/udc/Kconfig
drivers/usb/gadget/udc/renesas_usb3.c
drivers/usb/gadget/udc/snps_udc_plat.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/pci-quirks.h
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/musb/musb_host.c
drivers/usb/phy/phy-msm-usb.c
drivers/usb/renesas_usbhs/common.c
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/renesas_usbhs/rcar3.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/storage/isd200.c
drivers/usb/storage/unusual_uas.h
drivers/usb/storage/usb.c
drivers/usb/typec/ucsi/ucsi.h
drivers/vfio/pci/vfio_pci.c
drivers/vfio/pci/vfio_pci_config.c
drivers/vhost/vhost.c
drivers/vhost/vhost.h
drivers/video/fbdev/efifb.c
drivers/video/fbdev/imxfb.c
drivers/video/fbdev/omap2/omapfb/dss/core.c
drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
drivers/virtio/virtio_balloon.c
drivers/w1/masters/omap_hdq.c
drivers/w1/w1.c
drivers/xen/balloon.c
drivers/xen/events/events_base.c
drivers/xen/grant-table.c
drivers/xen/xen-balloon.c
drivers/xen/xen-selfballoon.c
drivers/xen/xenbus/xenbus_xs.c
drivers/xen/xenfs/super.c
fs/binfmt_flat.c
fs/btrfs/extent-tree.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/ceph/dir.c
fs/ext2/acl.c
fs/ext4/acl.c
fs/ext4/ext4.h
fs/ext4/ext4_jbd2.h
fs/ext4/extents.c
fs/ext4/file.c
fs/ext4/inode.c
fs/ext4/ioctl.c
fs/ext4/mballoc.c
fs/ext4/namei.c
fs/ext4/resize.c
fs/ext4/super.c
fs/ext4/xattr.c
fs/f2fs/acl.c
fs/f2fs/checkpoint.c
fs/f2fs/file.c
fs/f2fs/sysfs.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/hfsplus/posix_acl.c
fs/isofs/inode.c
fs/jfs/acl.c
fs/jfs/resize.c
fs/jfs/super.c
fs/mount.h
fs/namei.c
fs/nfs/Kconfig
fs/nfs/client.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/filelayout/filelayout.c
fs/nfs/flexfilelayout/flexfilelayout.c
fs/nfs/flexfilelayout/flexfilelayoutdev.c
fs/nfs/mount_clnt.c
fs/nfs/nfs3proc.c
fs/nfs/nfs4client.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
fs/nfs/pnfs_nfs.c
fs/nfsd/nfs4callback.c
fs/ocfs2/acl.c
fs/overlayfs/dir.c
fs/overlayfs/inode.c
fs/overlayfs/namei.c
fs/overlayfs/overlayfs.h
fs/overlayfs/readdir.c
fs/overlayfs/super.c
fs/overlayfs/util.c
fs/proc/internal.h
fs/proc/meminfo.c
fs/proc/task_mmu.c
fs/reiserfs/xattr_acl.c
fs/userfaultfd.c
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_btree.c
fs/xfs/libxfs/xfs_dir2_data.c
fs/xfs/libxfs/xfs_refcount.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_log_cil.c
fs/xfs/xfs_qm.c
fs/xfs/xfs_reflink.c
include/acpi/acpi_numa.h
include/asm-generic/tlb.h
include/drm/bridge/dw_mipi_dsi.h [new file with mode: 0644]
include/drm/drmP.h
include/drm/drm_atomic.h
include/drm/drm_atomic_helper.h
include/drm/drm_bridge.h
include/drm/drm_connector.h
include/drm/drm_crtc.h
include/drm/drm_device.h [new file with mode: 0644]
include/drm/drm_dp_mst_helper.h
include/drm/drm_drv.h
include/drm/drm_edid.h
include/drm/drm_fb_cma_helper.h
include/drm/drm_fb_helper.h
include/drm/drm_framebuffer.h
include/drm/drm_gem.h
include/drm/drm_gem_cma_helper.h
include/drm/drm_gem_framebuffer_helper.h [new file with mode: 0644]
include/drm/drm_mode_config.h
include/drm/drm_modes.h
include/drm/drm_modeset_helper_vtables.h
include/drm/drm_pci.h
include/drm/drm_plane.h
include/drm/drm_property.h
include/drm/drm_scdc_helper.h
include/drm/drm_simple_kms_helper.h
include/drm/drm_vblank.h
include/drm/tinydrm/mipi-dbi.h
include/drm/tinydrm/tinydrm-helpers.h
include/drm/tinydrm/tinydrm.h
include/drm/ttm/ttm_bo_driver.h
include/kvm/arm_pmu.h
include/linux/acpi.h
include/linux/binfmts.h
include/linux/bpf-cgroup.h
include/linux/bpf_verifier.h
include/linux/cdev.h
include/linux/ceph/ceph_features.h
include/linux/ceph/osd_client.h
include/linux/ceph/osdmap.h
include/linux/ceph/rados.h
include/linux/compiler-gcc.h
include/linux/compiler.h
include/linux/cpuhotplug.h
include/linux/cpuset.h
include/linux/cred.h
include/linux/crush/crush.h
include/linux/dax.h
include/linux/dcache.h
include/linux/device.h
include/linux/dma-fence.h
include/linux/dma-mapping.h
include/linux/fs.h
include/linux/fs_struct.h
include/linux/ftrace.h
include/linux/i2c.h
include/linux/iio/common/st_sensors.h
include/linux/ipc.h
include/linux/ipc_namespace.h
include/linux/ipv6.h
include/linux/irq.h
include/linux/jhash.h
include/linux/key-type.h
include/linux/kmod.h
include/linux/kobject.h
include/linux/kthread.h
include/linux/kvm_host.h
include/linux/libata.h
include/linux/llist.h
include/linux/lsm_hooks.h
include/linux/mlx4/device.h
include/linux/mlx5/mlx5_ifc.h
include/linux/mlx5/qp.h
include/linux/mm_types.h
include/linux/module.h
include/linux/mount.h
include/linux/msg.h
include/linux/mtd/nand.h
include/linux/netfilter.h
include/linux/nfs_fs.h
include/linux/nfs_xdr.h
include/linux/nvme-fc-driver.h
include/linux/nvme-fc.h
include/linux/nvme.h
include/linux/pagemap.h
include/linux/path.h
include/linux/pci.h
include/linux/perf/arm_pmu.h
include/linux/phy.h
include/linux/pid_namespace.h
include/linux/pinctrl/pinconf-generic.h
include/linux/platform_data/hsmmc-omap.h
include/linux/platform_data/omap_drm.h [deleted file]
include/linux/platform_data/st_sensors_pdata.h
include/linux/proc_ns.h
include/linux/ptp_clock_kernel.h
include/linux/reservation.h
include/linux/sched.h
include/linux/sched/signal.h
include/linux/sem.h
include/linux/shm.h
include/linux/sync_file.h
include/linux/sysctl.h
include/linux/trace_events.h
include/linux/tty.h
include/linux/tty_driver.h
include/linux/usb/audio-v2.h
include/linux/usb/cdc_ncm.h
include/linux/user_namespace.h
include/linux/utsname.h
include/linux/uuid.h
include/linux/vfio.h
include/linux/wait.h
include/linux/workqueue.h
include/media/cec-notifier.h
include/media/davinci/dm644x_ccdc.h
include/media/davinci/vpfe_capture.h
include/media/vsp1.h
include/net/af_unix.h
include/net/neighbour.h
include/net/net_namespace.h
include/net/netlink.h
include/net/sctp/sctp.h
include/net/sock.h
include/net/tcp.h
include/net/udp.h
include/rdma/ib_addr.h
include/rdma/ib_verbs.h
include/rdma/rdma_vt.h
include/rdma/rdmavt_qp.h
include/sound/omap-hdmi-audio.h
include/sound/soc.h
include/target/iscsi/iscsi_target_core.h
include/trace/events/ext4.h
include/uapi/asm-generic/ioctls.h
include/uapi/drm/armada_drm.h
include/uapi/drm/drm_fourcc.h
include/uapi/drm/drm_mode.h
include/uapi/drm/msm_drm.h
include/uapi/drm/qxl_drm.h
include/uapi/drm/vc4_drm.h
include/uapi/linux/usb/audio.h
include/xen/balloon.h
ipc/msg.c
ipc/sem.c
ipc/shm.c
kernel/audit.c
kernel/bpf/syscall.c
kernel/bpf/verifier.c
kernel/cgroup/cgroup-internal.h
kernel/cgroup/cgroup.c
kernel/cgroup/cpuset.c
kernel/cpu.c
kernel/events/core.c
kernel/fork.c
kernel/futex.c
kernel/irq/chip.c
kernel/irq/cpuhotplug.c
kernel/irq/internals.h
kernel/irq/manage.c
kernel/irq/pm.c
kernel/locking/rtmutex.c
kernel/pid.c
kernel/power/snapshot.c
kernel/sched/core.c
kernel/sched/cputime.c
kernel/sched/deadline.c
kernel/signal.c
kernel/time/timer.c
kernel/trace/ftrace.c
kernel/trace/ring_buffer.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/workqueue.c
lib/fault-inject.c
lib/test_kmod.c
lib/test_rhashtable.c
lib/test_uuid.c
mm/balloon_compaction.c
mm/debug.c
mm/huge_memory.c
mm/hugetlb.c
mm/internal.h
mm/kasan/report.c
mm/ksm.c
mm/madvise.c
mm/memory.c
mm/migrate.c
mm/mprotect.c
mm/mremap.c
mm/page_alloc.c
mm/page_io.c
mm/rmap.c
mm/shmem.c
mm/util.c
mm/zsmalloc.c
net/batman-adv/translation-table.c
net/batman-adv/types.h
net/bridge/br_device.c
net/bridge/br_input.c
net/ceph/crush/mapper.c
net/ceph/messenger.c
net/ceph/osd_client.c
net/ceph/osdmap.c
net/core/dev.c
net/core/dev_ioctl.c
net/core/fib_rules.c
net/core/filter.c
net/core/netpoll.c
net/core/rtnetlink.c
net/dccp/feat.c
net/dccp/input.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/dsa/dsa2.c
net/ipv4/af_inet.c
net/ipv4/cipso_ipv4.c
net/ipv4/fib_frontend.c
net/ipv4/fib_semantics.c
net/ipv4/fou.c
net/ipv4/igmp.c
net/ipv4/ip_output.c
net/ipv4/netfilter/nf_tables_arp.c
net/ipv4/syncookies.c
net/ipv4/tcp_bbr.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv4/tcp_timer.c
net/ipv4/udp.c
net/ipv4/udp_offload.c
net/ipv6/exthdrs.c
net/ipv6/ip6_output.c
net/ipv6/output_core.c
net/ipv6/route.c
net/ipv6/syncookies.c
net/ipv6/udp.c
net/ipv6/udp_offload.c
net/netfilter/core.c
net/netfilter/nf_conntrack_expect.c
net/netfilter/nf_nat_core.c
net/netfilter/nfnetlink.c
net/openvswitch/conntrack.c
net/packet/af_packet.c
net/rds/ib_recv.c
net/rds/send.c
net/sched/act_api.c
net/sched/act_ipt.c
net/sctp/sm_make_chunk.c
net/socket.c
net/sunrpc/xprtsock.c
net/tipc/node.c
samples/bpf/tcbpf2_kern.c
samples/bpf/test_tunnel_bpf.sh
scripts/dtc/dtx_diff
scripts/get_maintainer.pl
scripts/parse-maintainers.pl [new file with mode: 0644]
security/keys/internal.h
sound/pci/fm801.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/msm8916-wcd-analog.c
sound/soc/codecs/rt5663.c
sound/soc/codecs/rt5665.c
sound/soc/codecs/rt5665.h
sound/soc/codecs/sgtl5000.c
sound/soc/fsl/imx-ssi.c
sound/soc/generic/audio-graph-card.c
sound/soc/generic/audio-graph-scu-card.c
sound/soc/generic/simple-card-utils.c
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
sound/soc/intel/skylake/skl-messages.c
sound/soc/intel/skylake/skl.c
sound/soc/omap/omap-hdmi-audio.c
sound/soc/pxa/Kconfig
sound/soc/samsung/odroid.c
sound/soc/sh/hac.c
sound/soc/soc-core.c
sound/soc/soc-pcm.c
sound/soc/ux500/mop500.c
tools/build/feature/test-bpf.c
tools/kvm/kvm_stat/kvm_stat
tools/lib/bpf/bpf.c
tools/lib/bpf/bpf.h
tools/perf/ui/browser.c
tools/perf/util/evsel.c
tools/perf/util/machine.c
tools/testing/selftests/bpf/test_align.c
tools/testing/selftests/bpf/test_pkt_md_access.c
tools/testing/selftests/bpf/test_progs.c
tools/testing/selftests/bpf/test_verifier.c
virt/kvm/arm/mmu.c
virt/kvm/arm/pmu.c
virt/kvm/arm/vgic/vgic-init.c
virt/kvm/arm/vgic/vgic-its.c
virt/kvm/arm/vgic/vgic-mmio-v3.c
virt/kvm/kvm_main.c

index 463cf7e73db80b3bf3f8a36afe91bcf3d7f0d429..7af83a92d2d6103ea3fb0a3a0425e994b29f7f53 100644 (file)
@@ -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).
index 7e06e65586d4ae110262a4dc8c0eef62d43d9dd5..4a0a7469fdd7bbcd93e26ea5ae9c11e4285f7c7f 100644 (file)
@@ -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
index 0764f9ab63dcde31f7efff01f74e56c5c6fa1c56..e20eac7a30874f0db82adefa0cdf3a77ac09aec2 100644 (file)
@@ -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>;
index f69773f4252bf01bb9948767b254bd7bd190a41a..941bb6a6fb1304609bb3fa8a94520bfbdcca06f7 100644 (file)
@@ -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 (file)
index 0000000..b13adf3
--- /dev/null
@@ -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 (file)
index 0000000..f5f9f9c
--- /dev/null
@@ -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";
+       };
index 046076c6b2775b8124da53ce4647094fe7e3c96c..fad8b7619647661cac9de0df3a8bf1d0f1711074 100644 (file)
@@ -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:
 
index 9eb3f0a2a078b4e1f62d71daf123cf7d8363b683..5d835d9c1ba807540d1bc065640513ab092dea42 100644 (file)
@@ -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 (file)
index 0000000..1d0dad1
--- /dev/null
@@ -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>;
+       };
index 8e1476941c0ff86b4ae4d032975f60e45616346d..74b5ac7b26d65278e7453301be2b8491e1c6668c 100644 (file)
@@ -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.
   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 (file)
index 0000000..4540d61
--- /dev/null
@@ -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)
index d3b6e1a4713a58d00692ab8bf2ae74f1956a40e3..5aa5926029ee7286c4cd2e41a446574c13102021 100644 (file)
@@ -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>,
index aad98442788bc386366b019a6166e6145b2f0017..a58c173b7ab9882091fe26e378ce655610f17455 100644 (file)
@@ -78,7 +78,6 @@ Example:
        };
 
        dwmmc0@12200000 {
-               num-slots = <1>;
                cap-mmc-highspeed;
                cap-sd-highspeed;
                broken-cd;
index 85de99fcaa2fa14c146f768431978b089c674d54..c54e577eea0703c498d5fb397bd1d509f03faaa4 100644 (file)
@@ -24,6 +24,5 @@ Example:
 
                fifo-depth = <0x20>;
                bus-width = <4>;
-               num-slots = <1>;
                disable-wp;
        };
index 8af1afcb86dcf8c375aec37e99103ad73ddf2551..07242d1417735c56576bc59742284957259a4660 100644 (file)
@@ -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;
index 9cb55ca5746135a104d9e6d4722b87d888be63af..ef3e5f14067a17b91abf9715e98d56ad4bb220dd 100644 (file)
@@ -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>;
index eaade0e5adeb09e8d1c2e25763cf90d7bb3c06c7..906819a90c2bb6232f82f1549ea563c58132aec4 100644 (file)
@@ -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;
index 2fefa1a44afd4472f75a8fd74b73d7ae6c9083b9..ad16c1f481f77fed199e1c24bc3450aa75fbb970 100644 (file)
@@ -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 (file)
index 022946c..0000000
+++ /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";
-};
index 194926f77194c4d3fea8e73942bd1f20ae361815..1ff02afdc55a8afab456daa3b17dce7c2a97263c 100644 (file)
@@ -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
index 07590bcdad15a9bb4f66455b29363245ac3039c4..7c04e22a5d6af016fe8198d2d6d955011abc2173 100644 (file)
@@ -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";
 };
index e6b572409cf50a3aeb6f2899c961c8d0f248fefa..574c3a2c77d5cd28570e1272488703f0852ec2eb 100644 (file)
@@ -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>;
 };
index daf465bef75898c1b1960d456c82b666c4f9dca6..36b27b1efec675ef38a1fece766ee3c0ef0bd07f 100644 (file)
@@ -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
index a59916c29b3312cd4946a1d9a8da2331819e7845..1a85c1bdaf38a9ae7fb8b6555afc30abae661a20 100644 (file)
@@ -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>
index b34fd94f70898a7f65c2a0313349588411eb8e81..5eacc147ea870c80bb06c38d43bd5b662c171194 100644 (file)
@@ -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
index 0d936c67bf7d78a84a38d284681d142ad34031d4..5ee9674fb9e981db2c17c0b6f1a08402b5ab5290 100644 (file)
@@ -201,6 +201,8 @@ drivers.
 Open/Close, File Operations and IOCTLs
 ======================================
 
+.. _drm_driver_fops:
+
 File Operations
 ---------------
 
index 7c5e2549a58a61091b286e88c2171cbc9439668f..13dd237418cc4595159c2037ae2e9bbdfd41f0de 100644 (file)
@@ -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:
index 2d77c958016483ca294ffe9a58f5dbd72f2dbd0f..307284125d7aa964522f85ea6fb34247e67c9de2 100644 (file)
@@ -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
 ------------------------------------------------------------
index 9412798645c1ae84e9d3d1a252d4ff9b0b12a1b3..b08e9dcd91771c39ab56216c506ece87ce755059 100644 (file)
@@ -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:
index 858457567d3df7460ab7074de88d82e24b8fab8e..679373b4a03f2189e14cce4c30686bdc947eb5a1 100644 (file)
@@ -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
 =============================
 
index 1ae42006deea7814ce88b9ad121cbf56d246714f..22af55d06ab8d6be092cf9d8699a9c4e09cd5260 100644 (file)
@@ -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.
index ff86bf0abeae9624c7dd2ae898bc4af464ddc6f9..de9a228aca8a862ff585b374a498bbc9d103ef1c 100644 (file)
@@ -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
 
 
index 0c8abd69f39aff72e9ee732cb7c80410fbbe5778..d6fad90ec19987ad2be86387b72277094a677c3d 100644 (file)
-<?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>
index c4140fb518afc91cd5e84245d14b8313a498231a..4effe45b448d5812e1be9235bcbd810993d4524a 100644 (file)
-<?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>
index fbd4cfb5e6bffb7a7d13c3f4fd6580e28e83b152..c395113d1876b4daefd5eb222c15286f491bcaaf 100644 (file)
-<?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>
index f710ee46b1f8b2d5dbaf5b9fe39ee711375fdc6a..7e5d7185ca49ddbd40d4666d5f1dbaa0858ad0f2 100644 (file)
-<?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>
index dc9a471bae6b6bca8ba17dbe2f3c7417291f1ceb..3878fe4c49e99736e703903411eb9e04c89ec87d 100644 (file)
    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"
        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"
        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"
        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>
index b195301771ce0f10d4f65d55a22e851e305ce209..909d758f8543fea33e710deb77ad8c6c461a2c6e 100644 (file)
      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"
        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"
        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
index 6a7b10ad4ab80b0f04db7594aae1aea95620384b..7c74344e770fa64658d20b86d3e7be42743b91ab 100644 (file)
      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"
        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"
        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
index 21fcccda9723724c425ef16ce3a8f7a2fcffb469..65d05606c04cdb360aab9a29b4684e235c0c4344 100644 (file)
@@ -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"
      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
      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>
index d65d989ee73b09e455dd9d1d6e7e1353283c34f0..fc51fe8fda8b677e3a74969009e31ac197851124 100644 (file)
@@ -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"
      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>
index d309187af967b107515b34e82a7d49a1ab5e038a..a93e3b59786db3b3677dd40e2fb446406d890a0f 100644 (file)
-<?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>
index 1903dd3846c2942a9d6083223ba297a589426e49..ee1df49f83e8078c6ce4eced10d910be86db3bec 100644 (file)
      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>
index 91cf51832c1205b9b7f93ed19c2816cc8087340c..c10d222b9ea963a82ed7451e3575b1a59e4af4f3 100644 (file)
      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>
index cedcbf59892379f393c1f5643b5e98ac60ece79f..3cb68bf9fc047fb12ba331615bc62043336270c0 100644 (file)
      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>
index b05f7777ccf86124fa1e56574f7bb28a040d62a9..643aec8d0ba2cd093ebe54d59b45fcefc969fac2 100644 (file)
      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"
        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"
        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
index c117ddb7bf7ee8798c47e0e7616aab474a047d5d..9b18243c0a066e931e5cd856a196aff406eb83c6 100644 (file)
      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"
        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"
        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"
        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"
        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"
        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
index 4d5c0b4f146e3f533fed3fc9d0066209f2254a38..e17ff8314e7b12ce4c0cf136767384f38a7c3fb6 100644 (file)
      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"
        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"
        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"
        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
index b853e48312e2bcaf41a4b182af3b28a96b69cb07..d082f9a215481eac326297cb50b8d8e5924fd717 100644 (file)
@@ -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.
index e0ee0f1aeb05b499ee3254878698bf2b86ac107f..3c4f58bda178448c03702b9a4ed9b5a9faca0db8 100644 (file)
@@ -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.
index 2e24d680605229d86f81b8089af35f72c0499dfa..10f2ce42ece2bfc232e7c7dea91b23ff16a4d5e5 100644 (file)
@@ -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
index 0fde3dcf077a302eb24ea6d8fd8df65c4b252d8e..625549d4c74a09642d72bce75387c15348406223 100644 (file)
@@ -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
index 205d3977ac46e1a3bf58d95b46df5db29eabc70f..4a5971fa1c21bc6ccd88d4267853f9ab83c86ff3 100644 (file)
@@ -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,27 +1527,26 @@ 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>
+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)
-W:     http://www.digriz.org.uk/ts78xx/kernel
 S:     Maintained
-F:     arch/arm/mach-orion5x/ts78xx-*
+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/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/Mediatek RTC DRIVER
-M:     Eddie Huang <eddie.huang@mediatek.com>
+ARM/Mediatek RTC DRIVER
+M:     Eddie Huang <eddie.huang@mediatek.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-mediatek@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -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,47 +2546,47 @@ W:      http://blackfin.uclinux.org
 S:     Supported
 F:     drivers/net/ethernet/adi/
 
-BLACKFIN RTC DRIVER
+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
+W:     http://blackfin.uclinux.org/
 S:     Supported
-F:     drivers/rtc/rtc-bfin.c
+F:     drivers/i2c/busses/i2c-bfin-twi.c
 
-BLACKFIN SDH DRIVER
-M:     Sonic Zhang <sonic.zhang@analog.com>
+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
+W:     http://blackfin.uclinux.org/
 S:     Supported
-F:     drivers/mmc/host/bfin_sdh.c
-
-BLACKFIN SERIAL DRIVER
-M:     Sonic Zhang <sonic.zhang@analog.com>
+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
 S:     Supported
-F:     drivers/tty/serial/bfin_uart.c
+F:     drivers/rtc/rtc-bfin.c
 
-BLACKFIN WATCHDOG DRIVER
+BLACKFIN SDH 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/watchdog/bfin_wdt.c
+F:     drivers/mmc/host/bfin_sdh.c
 
-BLACKFIN I2C TWI DRIVER
+BLACKFIN SERIAL DRIVER
 M:     Sonic Zhang <sonic.zhang@analog.com>
 L:     adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
-W:     http://blackfin.uclinux.org/
+W:     http://blackfin.uclinux.org
 S:     Supported
-F:     drivers/i2c/busses/i2c-bfin-twi.c
+F:     drivers/tty/serial/bfin_uart.c
 
-BLACKFIN MEDIA DRIVER
-M:     Scott Jiang <scott.jiang.linux@gmail.com>
+BLACKFIN WATCHDOG DRIVER
 L:     adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
-W:     http://blackfin.uclinux.org/
+W:     http://blackfin.uclinux.org
 S:     Supported
-F:     drivers/media/platform/blackfin/
-F:     drivers/media/i2c/adv7183*
-F:     drivers/media/i2c/vs6624*
+F:     drivers/watchdog/bfin_wdt.c
 
 BLINKM RGB LED DRIVER
 M:     Jan-Simon Moeller <jansimon.moeller@gmx.de>
@@ -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,68 +4300,142 @@ T:     git git://anongit.freedesktop.org/drm/drm-misc
 S:     Maintained
 F:     drivers/gpu/drm/bochs/
 
-DRM DRIVER FOR QEMU'S CIRRUS DEVICE
-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:     Obsolete
-W:     https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful/
-F:     drivers/gpu/drm/cirrus/
+DRM DRIVER FOR INTEL I810 VIDEO CARDS
+S:     Orphan / Obsolete
+F:     drivers/gpu/drm/i810/
+F:     include/uapi/drm/i810_drm.h
 
-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 MATROX G200/G400 GRAPHICS CARDS
+S:     Orphan / Obsolete
+F:     drivers/gpu/drm/mga/
+F:     include/uapi/drm/mga_drm.h
 
-DRM PANEL DRIVERS
-M:     Thierry Reding <thierry.reding@gmail.com>
+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
-T:     git git://anongit.freedesktop.org/tegra/linux.git
+L:     freedreno@lists.freedesktop.org
+T:     git git://people.freedesktop.org/~robclark/linux
 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/msm/
+F:     include/uapi/drm/msm_drm.h
+F:     Documentation/devicetree/bindings/display/msm/
 
-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
+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/i915/
-F:     include/drm/i915*
-F:     include/uapi/drm/i915_drm.h
-F:     Documentation/gpu/i915.rst
+F:     drivers/gpu/drm/nouveau/
+F:     include/uapi/drm/nouveau_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 QEMU'S CIRRUS DEVICE
+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:     Obsolete
+W:     https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful/
+F:     drivers/gpu/drm/cirrus/
 
-DRM DRIVERS FOR ATMEL HLCDC
-M:     Boris Brezillon <boris.brezillon@free-electrons.com>
+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 DRIVER FOR PERVASIVE DISPLAYS REPAPER PANELS
+M:     Noralf Trønnes <noralf@tronnes.org>
+S:     Maintained
+F:     drivers/gpu/drm/tinydrm/repaper.c
+F:     Documentation/devicetree/bindings/display/repaper.txt
+
+DRM DRIVER FOR RAGE 128 VIDEO CARDS
+S:     Orphan / Obsolete
+F:     drivers/gpu/drm/r128/
+F:     include/uapi/drm/r128_drm.h
+
+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 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>
@@ -5136,14 +5108,22 @@ F:      net/bridge/
 ETHERNET PHY LIBRARY
 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/
+L:     netdev@vger.kernel.org
+S:     Maintained
+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,49 +5820,24 @@ 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>
-S:     Maintained
-F:     drivers/staging/greybus/audio_apbridgea.c
-F:     drivers/staging/greybus/audio_apbridgea.h
-F:     drivers/staging/greybus/audio_codec.c
-F:     drivers/staging/greybus/audio_codec.h
-F:     drivers/staging/greybus/audio_gb.c
-F:     drivers/staging/greybus/audio_manager.c
-F:     drivers/staging/greybus/audio_manager.h
-F:     drivers/staging/greybus/audio_manager_module.c
-F:     drivers/staging/greybus/audio_manager_private.h
-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
+M:     Mark Greer <mgreer@animalcreek.com>
+S:     Maintained
+F:     drivers/staging/greybus/audio_apbridgea.c
+F:     drivers/staging/greybus/audio_apbridgea.h
+F:     drivers/staging/greybus/audio_codec.c
+F:     drivers/staging/greybus/audio_codec.h
+F:     drivers/staging/greybus/audio_gb.c
+F:     drivers/staging/greybus/audio_manager.c
+F:     drivers/staging/greybus/audio_manager.h
+F:     drivers/staging/greybus/audio_manager_module.c
+F:     drivers/staging/greybus/audio_manager_private.h
+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
+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,26 +6484,27 @@ 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
 F:     drivers/scsi/ips.*
 
 ICH LPC AND GPIO DRIVER
-M:     Peter Tyser <ptyser@xes-inc.com>
-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>
+M:     Peter Tyser <ptyser@xes-inc.com>
 S:     Maintained
-F:     drivers/clk/clk-versaclock5.c
+F:     drivers/mfd/lpc_ich.c
+F:     drivers/gpio/gpio-ich.c
 
 IDE SUBSYSTEM
 M:     "David S. Miller" <davem@davemloft.net>
@@ -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,96 +6763,20 @@ T:      git git://git.code.sf.net/p/intel-sas/isci
 S:     Supported
 F:     drivers/scsi/isci/
 
-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 IDLE DRIVER
-M:     Jacob Pan <jacob.jun.pan@linux.intel.com>
-M:     Len Brown <lenb@kernel.org>
-L:     linux-pm@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git
-B:     https://bugzilla.kernel.org
-S:     Supported
-F:     drivers/idle/intel_idle.c
-
-INTEL INTEGRATED SENSOR HUB DRIVER
-M:     Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
-M:     Jiri Kosina <jikos@kernel.org>
-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
-T:     git git://git.infradead.org/iommu-2.6.git
+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/iommu/intel-iommu.c
-F:     include/linux/intel-iommu.h
-
-INTEL IOP-ADMA DMA DRIVER
-R:     Dan Williams <dan.j.williams@intel.com>
-S:     Odd fixes
-F:     drivers/dma/iop-adma.c
-
-INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
-M:     Krzysztof Halasa <khalasa@piap.pl>
-S:     Maintained
-F:     arch/arm/mach-ixp4xx/include/mach/qmgr.h
-F:     arch/arm/mach-ixp4xx/include/mach/npe.h
-F:     arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
-F:     arch/arm/mach-ixp4xx/ixp4xx_npe.c
-F:     drivers/net/ethernet/xscale/ixp4xx_eth.c
-F:     drivers/net/wan/ixp4xx_hss.c
-
-INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT
-M:     Deepak Saxena <dsaxena@plexity.net>
-S:     Maintained
-F:     drivers/char/hw_random/ixp4xx-rng.c
+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>
@@ -6883,75 +6801,80 @@ F:      drivers/net/ethernet/intel/
 F:     drivers/net/ethernet/intel/*/
 F:     include/linux/avf/virtchnl.h
 
-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 MERRIFIELD GPIO DRIVER
-M:     Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-L:     linux-gpio@vger.kernel.org
+INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
+M:     Maik Broemme <mbroemme@libmpq.org>
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
-F:     drivers/gpio/gpio-merrifield.c
+F:     Documentation/fb/intelfb.txt
+F:     drivers/video/fbdev/intelfb/
 
-INTEL-MID GPIO DRIVER
-M:     David Cohen <david.a.cohen@linux.intel.com>
-L:     linux-gpio@vger.kernel.org
-S:     Maintained
-F:     drivers/gpio/gpio-intel-mid.c
+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 PRO/WIRELESS 2100, 2200BG, 2915ABG NETWORK CONNECTION SUPPORT
-M:     Stanislav Yakovlev <stas.yakovlev@gmail.com>
-L:     linux-wireless@vger.kernel.org
+INTEL HID EVENT DRIVER
+M:     Alex Hung <alex.hung@canonical.com>
+L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
-F:     Documentation/networking/README.ipw2100
-F:     Documentation/networking/README.ipw2200
-F:     drivers/net/wireless/intel/ipw2x00/
+F:     drivers/platform/x86/intel-hid.c
 
-INTEL(R) TRACE HUB
-M:     Alexander Shishkin <alexander.shishkin@linux.intel.com>
+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:     Documentation/trace/intel_th.txt
-F:     drivers/hwtracing/intel_th/
+F:     drivers/dma/ioat*
 
-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 IDLE DRIVER
+M:     Jacob Pan <jacob.jun.pan@linux.intel.com>
+M:     Len Brown <lenb@kernel.org>
+L:     linux-pm@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git
+B:     https://bugzilla.kernel.org
 S:     Supported
-F:     Documentation/intel_txt.txt
-F:     include/linux/tboot.h
-F:     arch/x86/kernel/tboot.c
+F:     drivers/idle/intel_idle.c
 
-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 INTEGRATED SENSOR HUB DRIVER
+M:     Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+M:     Jiri Kosina <jikos@kernel.org>
+L:     linux-input@vger.kernel.org
+S:     Maintained
+F:     drivers/hid/intel-ish-hid/
 
-INTEL WIRELESS 3945ABG/BG, 4965AGN (iwlegacy)
-M:     Stanislaw Gruszka <sgruszka@redhat.com>
-L:     linux-wireless@vger.kernel.org
+INTEL IOMMU (VT-d)
+M:     David Woodhouse <dwmw2@infradead.org>
+L:     iommu@lists.linux-foundation.org
+T:     git git://git.infradead.org/iommu-2.6.git
 S:     Supported
-F:     drivers/net/wireless/intel/iwlegacy/
+F:     drivers/iommu/intel-iommu.c
+F:     include/linux/intel-iommu.h
 
-INTEL WIRELESS WIFI LINK (iwlwifi)
-M:     Johannes Berg <johannes.berg@intel.com>
-M:     Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-M:     Luca Coelho <luciano.coelho@intel.com>
-M:     Intel Linux Wireless <linuxwifi@intel.com>
-L:     linux-wireless@vger.kernel.org
-W:     http://intellinuxwireless.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git
-S:     Supported
-F:     drivers/net/wireless/intel/iwlwifi/
+INTEL IOP-ADMA DMA DRIVER
+R:     Dan Williams <dan.j.williams@intel.com>
+S:     Odd fixes
+F:     drivers/dma/iop-adma.c
+
+INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
+M:     Krzysztof Halasa <khalasa@piap.pl>
+S:     Maintained
+F:     arch/arm/mach-ixp4xx/include/mach/qmgr.h
+F:     arch/arm/mach-ixp4xx/include/mach/npe.h
+F:     arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
+F:     arch/arm/mach-ixp4xx/ixp4xx_npe.c
+F:     drivers/net/ethernet/xscale/ixp4xx_eth.c
+F:     drivers/net/wan/ixp4xx_hss.c
+
+INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT
+M:     Deepak Saxena <dsaxena@plexity.net>
+S:     Maintained
+F:     drivers/char/hw_random/ixp4xx-rng.c
 
 INTEL MANAGEMENT ENGINE (mei)
 M:     Tomas Winkler <tomas.winkler@intel.com>
@@ -6964,6 +6887,19 @@ F:       drivers/watchdog/mei_wdt.c
 F:     Documentation/misc-devices/mei/*
 F:     samples/mei/*
 
+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>
+L:     linux-gpio@vger.kernel.org
+S:     Maintained
+F:     drivers/gpio/gpio-merrifield.c
+
 INTEL MIC DRIVERS (mic)
 M:     Sudeep Dutt <sudeep.dutt@intel.com>
 M:     Ashutosh Dixit <ashutosh.dixit@intel.com>
@@ -6973,13 +6909,21 @@ 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/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:     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
@@ -6989,6 +6933,28 @@ 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>
+L:     linux-wireless@vger.kernel.org
+S:     Maintained
+F:     Documentation/networking/README.ipw2100
+F:     Documentation/networking/README.ipw2200
+F:     drivers/net/wireless/intel/ipw2x00/
+
+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 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 TELEMETRY DRIVER
 M:     Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>
 L:     platform-driver-x86@vger.kernel.org
@@ -6996,13 +6962,60 @@ S:      Maintained
 F:     arch/x86/include/asm/intel_telemetry.h
 F:     drivers/platform/x86/intel_telemetry*
 
-INTEL PMC CORE DRIVER
-M:     Rajneesh Bhardwaj <rajneesh.bhardwaj@intel.com>
-M:     Vishwanath Somayaji <vishwanath.somayaji@intel.com>
+INTEL VIRTUAL BUTTON DRIVER
+M:     AceLan Kao <acelan.kao@canonical.com>
 L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
-F:     arch/x86/include/asm/pmc_core.h
-F:     drivers/platform/x86/intel_pmc_core*
+F:     drivers/platform/x86/intel-vbtn.c
+
+INTEL WIRELESS 3945ABG/BG, 4965AGN (iwlegacy)
+M:     Stanislaw Gruszka <sgruszka@redhat.com>
+L:     linux-wireless@vger.kernel.org
+S:     Supported
+F:     drivers/net/wireless/intel/iwlegacy/
+
+INTEL WIRELESS WIFI LINK (iwlwifi)
+M:     Johannes Berg <johannes.berg@intel.com>
+M:     Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+M:     Luca Coelho <luciano.coelho@intel.com>
+M:     Intel Linux Wireless <linuxwifi@intel.com>
+L:     linux-wireless@vger.kernel.org
+W:     http://intellinuxwireless.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git
+S:     Supported
+F:     drivers/net/wireless/intel/iwlwifi/
+
+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(R) TRACE HUB
+M:     Alexander Shishkin <alexander.shishkin@linux.intel.com>
+S:     Supported
+F:     Documentation/trace/intel_th.txt
+F:     drivers/hwtracing/intel_th/
+
+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-MID GPIO DRIVER
+M:     David Cohen <david.a.cohen@linux.intel.com>
+L:     linux-gpio@vger.kernel.org
+S:     Maintained
+F:     drivers/gpio/gpio-intel-mid.c
 
 INVENSENSE MPU-3050 GYROSCOPE DRIVER
 M:     Linus Walleij <linus.walleij@linaro.org>
@@ -7048,13 +7061,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 +7107,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 +7134,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 +7141,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 +7149,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 +7165,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 +7426,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 +7440,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 +7467,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 +7496,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 +7517,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 +7671,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 +7714,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 +7736,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 +7751,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 +7772,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 +7813,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 +7830,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 +7841,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 +7861,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 +7895,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 +7947,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 +8244,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 +8252,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 +8302,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 +8334,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 +8343,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 +8351,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 +8361,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 +8371,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>
@@ -8440,17 +8453,8 @@ MEDIATEK JPEG DRIVER
 M:     Rick Chang <rick.chang@mediatek.com>
 M:     Bin Liu <bin.liu@mediatek.com>
 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
+F:     drivers/media/platform/mtk-jpeg/
+F:     Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
 
 MEDIATEK MDP DRIVER
 M:     Minghsiu Tsai <minghsiu.tsai@mediatek.com>
@@ -8461,6 +8465,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 +8481,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 +8505,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 +8572,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 +8639,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 +8764,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 +8798,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 +8823,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 +8831,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 +8973,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 +8988,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 +9050,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 +9057,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 +9180,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 +9240,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 +9264,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 +9387,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 +9398,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 +9433,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 +9462,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 +9472,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 +9489,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 +9503,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 +9541,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 +9564,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 +9579,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 +9597,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 +9612,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,20 +9644,56 @@ 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>
+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:     Documentation/devicetree/bindings/gpio/gpio-omap.txt
-F:     drivers/gpio/gpio-omap.c
+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
 
-OMAP/NEWFLOW NANOBONE MACHINE SUPPORT
-M:     Mark Jackson <mpfj@newflow.co.uk>
+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/boot/dts/am335x-nano.dts
+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>
@@ -9708,6 +9714,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 +9743,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 +9760,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 +9804,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 +9858,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 +9868,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 +9890,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 +9908,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 +9948,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 +10048,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 +10064,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 +10088,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 +10098,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 +10116,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 +10133,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 +10149,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 +10172,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 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/endpoint/
+F:     drivers/misc/pci_endpoint_test.c
+F:     tools/pci/
 
-PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
-M:     Keith Busch <keith.busch@intel.com>
-L:     linux-pci@vger.kernel.org
+PCI ENHANCED ERROR HANDLING (EEH) FOR POWERPC
+M:     Russell Currey <ruscur@russell.cc>
+L:     linuxppc-dev@lists.ozlabs.org
 S:     Supported
-F:     drivers/pci/host/vmd.c
+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
 
-PCIE DRIVER FOR ST SPEAR13XX
-M:     Pratyush Anand <pratyush.anand@gmail.com>
+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 +10227,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 +10249,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 +10273,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 +10296,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 +10403,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 +10469,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 +10519,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 +10545,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 +10554,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 +10588,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 +10707,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 +10714,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 +10768,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 +10801,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 +10814,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 +10877,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 +10884,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 +10907,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 +10933,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 +10941,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 +10977,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 +11018,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 +11110,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 +11126,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 +11174,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 +11183,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 +11263,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 +11409,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 +11443,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 +11467,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 +11500,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 +11522,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 +11546,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,20 +11554,6 @@ S:     Maintained
 F:     drivers/media/platform/s3c-camif/
 F:     include/media/drv-intf/s3c_camif.h
 
-SAMSUNG S5C73M3 CAMERA DRIVER
-M:     Kyungmin Park <kyungmin.park@samsung.com>
-M:     Andrzej Hajda <a.hajda@samsung.com>
-L:     linux-media@vger.kernel.org
-S:     Supported
-F:     drivers/media/i2c/s5c73m3/*
-
-SAMSUNG S5K5BAF CAMERA DRIVER
-M:     Kyungmin Park <kyungmin.park@samsung.com>
-M:     Andrzej Hajda <a.hajda@samsung.com>
-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>
@@ -11548,176 +11561,86 @@ L:   linux-nfc@lists.01.org (moderated for non-subscribers)
 S:     Supported
 F:     drivers/nfc/s3fwrn5
 
-SAMSUNG SOC CLOCK DRIVERS
-M:     Sylwester Nawrocki <s.nawrocki@samsung.com>
-M:     Tomasz Figa <tomasz.figa@gmail.com>
-M:     Chanwoo Choi <cw00.choi@samsung.com>
-S:     Supported
-L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
-F:     drivers/clk/samsung/
-F:     include/dt-bindings/clock/exynos*.h
-F:     Documentation/devicetree/bindings/clock/exynos*.txt
-
-SAMSUNG SPI DRIVERS
-M:     Kukjin Kim <kgene@kernel.org>
-M:     Krzysztof Kozlowski <krzk@kernel.org>
-M:     Andi Shyti <andi.shyti@samsung.com>
-L:     linux-spi@vger.kernel.org
-L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
-S:     Maintained
-F:     Documentation/devicetree/bindings/spi/spi-samsung.txt
-F:     drivers/spi/spi-s3c*
-F:     include/linux/platform_data/spi-s3c64xx.h
-
-SAMSUNG SXGBE DRIVERS
-M:     Byungho An <bh74.an@samsung.com>
-M:     Girish K S <ks.giri@samsung.com>
-M:     Vipul Pandya <vipul.pandya@samsung.com>
-S:     Supported
-L:     netdev@vger.kernel.org
-F:     drivers/net/ethernet/samsung/sxgbe/
-
-SAMSUNG THERMAL DRIVER
-M:     Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-L:     linux-pm@vger.kernel.org
-L:     linux-samsung-soc@vger.kernel.org
-S:     Supported
-T:     git https://github.com/lmajewski/linux-samsung-thermal.git
-F:     drivers/thermal/samsung/
-
-SAMSUNG USB2 PHY DRIVER
-M:     Kamil Debski <kamil@wypas.org>
-M:     Sylwester Nawrocki <s.nawrocki@samsung.com>
-L:     linux-kernel@vger.kernel.org
-S:     Supported
-F:     Documentation/devicetree/bindings/phy/samsung-phy.txt
-F:     Documentation/phy/samsung-usb2.txt
-F:     drivers/phy/samsung/phy-exynos4210-usb2.c
-F:     drivers/phy/samsung/phy-exynos4x12-usb2.c
-F:     drivers/phy/samsung/phy-exynos5250-usb2.c
-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>
+SAMSUNG S5C73M3 CAMERA DRIVER
+M:     Kyungmin Park <kyungmin.park@samsung.com>
+M:     Andrzej Hajda <a.hajda@samsung.com>
 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/
+F:     drivers/media/i2c/s5c73m3/*
 
-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
+SAMSUNG S5K5BAF CAMERA DRIVER
+M:     Kyungmin Park <kyungmin.park@samsung.com>
+M:     Andrzej Hajda <a.hajda@samsung.com>
+L:     linux-media@vger.kernel.org
+S:     Supported
+F:     drivers/media/i2c/s5k5baf.c
 
-SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER
-M:     Jaehoon Chung <jh80.chung@samsung.com>
-L:     linux-mmc@vger.kernel.org
+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/mmc/host/dw_mmc*
+F:     drivers/crypto/s5p-sss.c
 
-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
+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/
 
-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
+SAMSUNG SOC CLOCK DRIVERS
+M:     Sylwester Nawrocki <s.nawrocki@samsung.com>
+M:     Tomasz Figa <tomasz.figa@gmail.com>
+M:     Chanwoo Choi <cw00.choi@samsung.com>
+S:     Supported
+L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
+F:     drivers/clk/samsung/
+F:     include/dt-bindings/clock/exynos*.h
+F:     Documentation/devicetree/bindings/clock/exynos*.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>
+SAMSUNG SPI DRIVERS
+M:     Kukjin Kim <kgene@kernel.org>
+M:     Krzysztof Kozlowski <krzk@kernel.org>
+M:     Andi Shyti <andi.shyti@samsung.com>
+L:     linux-spi@vger.kernel.org
+L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 S:     Maintained
-F:     drivers/thunderbolt/
+F:     Documentation/devicetree/bindings/spi/spi-samsung.txt
+F:     drivers/spi/spi-s3c*
+F:     include/linux/platform_data/spi-s3c64xx.h
 
-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
+SAMSUNG SXGBE DRIVERS
+M:     Byungho An <bh74.an@samsung.com>
+M:     Girish K S <ks.giri@samsung.com>
+M:     Vipul Pandya <vipul.pandya@samsung.com>
+S:     Supported
+L:     netdev@vger.kernel.org
+F:     drivers/net/ethernet/samsung/sxgbe/
 
-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
+SAMSUNG THERMAL DRIVER
+M:     Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+L:     linux-pm@vger.kernel.org
+L:     linux-samsung-soc@vger.kernel.org
 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/
+T:     git https://github.com/lmajewski/linux-samsung-thermal.git
+F:     drivers/thermal/samsung/
 
-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)
+SAMSUNG USB2 PHY DRIVER
+M:     Kamil Debski <kamil@wypas.org>
+M:     Sylwester Nawrocki <s.nawrocki@samsung.com>
+L:     linux-kernel@vger.kernel.org
 S:     Supported
-F:     drivers/nfc/trf7970a.c
-F:     Documentation/devicetree/bindings/net/nfc/trf7970a.txt
+F:     Documentation/devicetree/bindings/phy/samsung-phy.txt
+F:     Documentation/phy/samsung-usb2.txt
+F:     drivers/phy/samsung/phy-exynos4210-usb2.c
+F:     drivers/phy/samsung/phy-exynos4x12-usb2.c
+F:     drivers/phy/samsung/phy-exynos5250-usb2.c
+F:     drivers/phy/samsung/phy-s5pv210-usb2.c
+F:     drivers/phy/samsung/phy-samsung-usb2.c
+F:     drivers/phy/samsung/phy-samsung-usb2.h
 
 SC1200 WDT DRIVER
 M:     Zwane Mwaikambo <zwanem@gmail.com>
@@ -11747,16 +11670,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 +11754,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 +11776,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 +11808,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 +11821,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 +11834,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 +11888,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 +11988,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 +12007,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 +12039,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 +12099,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 +12136,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 +12162,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 +12176,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 +12217,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 +12228,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 +12263,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 +12282,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 +12324,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 +12372,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 +12409,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 +12498,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 +12602,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 +12634,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 +12670,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 +12688,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 +12866,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>
@@ -13058,7 +13003,24 @@ W:     http://ibm-acpi.sourceforge.net
 W:     http://thinkwiki.org/wiki/Ibm-acpi
 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
+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>
@@ -13068,13 +13030,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 +13048,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 +13098,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 +13142,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 +13173,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 +13188,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 +13224,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 +13292,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 +13307,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 +13413,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 +13487,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 +13554,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 +13785,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)
@@ -13808,16 +13835,9 @@ L:     linux-usb@vger.kernel.org
 L:     linux-media@vger.kernel.org
 T:     git git://linuxtv.org/media_tree.git
 W:     http://royale.zerezo.com/zr364xx/
-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/
+S:     Maintained
+F:     Documentation/media/v4l-drivers/zr364xx*
+F:     drivers/media/usb/zr364xx/
 
 USER-MODE LINUX (UML)
 M:     Jeff Dike <jdike@addtoit.com>
@@ -13912,6 +13932,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 +13972,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 +14003,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 +14024,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 +14070,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 +14084,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 +14103,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 +14111,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 +14147,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 +14239,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 +14289,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 +14373,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 +14385,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 +14410,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 +14432,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 +14462,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 +14538,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 +14579,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>
index b4fb9a1d1594ea2ba78889b12fcd434ced7f11be..90da7bdc3f4552d10bbd82c4fd0a88ed2f41db37 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 13
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc5
 NAME = Fearless Coyote
 
 # *DOCUMENTATION*
index ff67b8373bf78bb24a72df561390236842707a6a..1cd7dc7d487012fc1fa19cc636d1da562c905203 100644 (file)
 #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
index 2a07e6ecafbd768bcdca7c09fa4cc29bc1a6ff65..71d3efff99d35c56c6f30bea8a6ab1cf1702d753 100644 (file)
@@ -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)) {
index a208bfe367b55574e2ca4a901de8b3a2862aee2e..61a0cb15067ea653eaa9631fe64276385e3de064 100644 (file)
@@ -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
index 895fa6cfa15a9ee1c56c5827f5f5fe2f8e512196..563901e0ec071f0c66a4590b17fe5c3f6cfcbd69 100644 (file)
@@ -75,7 +75,7 @@ expander0: pca9555@20 {
                                        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 @@ expander1: pca9555@21 {
                                        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;
index a423e8ebfb3758057d41a4e9f77505df5dc1d783..67e72bc72e805be995b0d44fa68f74e29161b140 100644 (file)
@@ -301,25 +301,4 @@ &vpif {
        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>;
-               };
-       };
 };
index b837fec70eec8cb7d241d14559c8fad9c0cbb909..a0f0916156e66d83949716c4b571184695fbef3b 100644 (file)
@@ -318,11 +318,4 @@ &vpif {
        pinctrl-names = "default";
        pinctrl-0 = <&vpif_capture_pins>;
        status = "okay";
-
-       /* VPIF capture port */
-       port {
-               vpif_ch0: endpoint {
-                         bus-width = <8>;
-               };
-       };
 };
index 1865976db5f9a3e11aad03cdd951d2f3af83c78d..c72a2132aa823b053c5ab9450a92faf266c85878 100644 (file)
@@ -68,6 +68,34 @@ usb1_pins: pinmux_usb1_pins {
                        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 @@ extgpio1: pcf8575@20 {
 
 &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 @@ nand@0,0 {
                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 @@ &mmc1 {
        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 */
index 59cbf958fcc3178c4b56aad647c340e40a63c098..566b2a8c8b96853da331571c233dc786d8adc187 100644 (file)
@@ -145,7 +145,7 @@ edma: edma@49000000 {
                };
 
                elm: elm@48080000 {
-                       compatible = "ti,816-elm";
+                       compatible = "ti,am3352-elm";
                        ti,hwmods = "elm";
                        reg = <0x48080000 0x2000>;
                        interrupts = <4>;
index 4d57a55473afd1f563667d948b49269e11028697..a6298eb56978710c24291fc05d17770fefccd188 100644 (file)
@@ -190,7 +190,7 @@ dp83867_0: ethernet-phy@2 {
                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 @@ dp83867_1: ethernet-phy@3 {
                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;
        };
 };
 
index 497a9470c8881bca6e49800f90c0f5d20dd3d84a..5739389f5bb877ef7b29455a1bcd47328d7223ed 100644 (file)
@@ -59,6 +59,9 @@ clock_audss: clock-controller@03810000 {
                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 {
index 2484f11761ea24f3bfa44a81e7309442399367d9..858e1fed762a1df80f33bac4576b5d900e021bcf 100644 (file)
@@ -1126,8 +1126,8 @@ hdmi_in_vopl: endpoint@1 {
                };
        };
 
-       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>,
index 8923ba625b76f156f27fde9c66f1f72ad044405a..19a8f4fcfab50ef5300360d980f1738d99345a94 100644 (file)
@@ -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 @@ dma: dma-controller@1c02000 {
                        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 @@ pio: pinctrl@1c20800 {
                                     <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 @@ spdif: spdif@1c21000 {
                                     "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 @@ uart0: serial@01c28000 {
                        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";
                };
 
index 6f2162608006770896df2adcc258a4ed2a3b63a9..d38282b9e5d442cbf1709e38f8a64ee9bfacce1c 100644 (file)
@@ -394,7 +394,7 @@ timer@01c20c00 {
                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>;
index 86d8df98802fdf66a651adb04de5c4be49af3fcc..13bcc460bcb2adf2ab17775bc0aa2c01bc694aed 100644 (file)
@@ -22,7 +22,7 @@ chosen {
 };
 
 &eth0 {
-       phy-connection-type = "rgmii";
+       phy-connection-type = "rgmii-id";
        phy-handle = <&eth0_phy>;
        #address-cells = <1>;
        #size-cells = <0>;
index 4e6e88a6b2f4ba36bcc3a0167b684a24cc58b7e9..2244a94ed9c9d30af84c2ac220c8f3c2abeb7e2b 100644 (file)
@@ -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"                     \
index d69bebf697e76d2003bb671645290c938a156abd..74504b154256e36ff4897ed1c7df43eb4d91bdef 100644 (file)
@@ -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
index 1869af6bac5ceee7178b7e0126ecc88816d4d0c5..25021b798a1e4d857567df78349e5d7c781aa5a3 100644 (file)
 
 #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
index 3f2eb76243e3c5f9d387959acae740ce871e5afa..d5562f9ce60079139d360e5d6afac59469051454 100644 (file)
@@ -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 */
index 14749aec94bf3847148d3e6532f6507d06a2e15a..921d8274855c74cc5f1ba170db869dbe056d03b4 100644 (file)
@@ -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)
index 15495887ca14eedc883daa60b9a9a034913f0c3e..fe1419eeb9321ea553fcd68462596dadaf385185 100644 (file)
@@ -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,
index 4e80bf7420d4e65fb30e0c68e7bef53932f765b3..8e9a3e40d949567598cfdcc8146823f5ada96cb2 100644 (file)
@@ -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) {
index 7b8f2141427bda172899bfe8ae5113367163af47..5814298ef0b701e61e4de018aa216009c9445d30 100644 (file)
@@ -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
index b5625d0092881bbbbb1022de2664c51f2a304844..e568c8c6f69cb67bf423db51f25d6315a15fbc96 100644 (file)
@@ -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,
index f5dce9b4e617df833cd210bac2fe65ac4a93b788..f77a4f7660505fe949af782e50b99c08b12a5570 100644 (file)
@@ -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))
index 39ef3b613912f8888013c30d591e4ad4f0cd8095..beec5f16443a29fb5a62f6deb8969ea33cff5b6d 100644 (file)
@@ -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 };
index 7a0c13bf42694b724e0fcb35439070eefde0a646..844e8ac593e270125980df3ecced92b6d6322f5e 100644 (file)
@@ -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 */
index 3330ac7cfbefc78388b78ad06a47ab102a9d9a79..671c7a09ab3d65a43b1effae5fd3bffbcb9c22cb 100644 (file)
@@ -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[] = {
index e62273aacb43681f2bd8ab0c7e95d82d2c32020f..4ffbbd217e8286e18181fac98487a8860ead6372 100644 (file)
@@ -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);
 
index 6613a6ff5dbc9e35512ac94fd84904ddf2a63ee1..6cbc69c92913dbc4074a65e269bb5243e9193cdb 100644 (file)
@@ -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[] = {
index 4dfb995048103b8bff965b6119f3665e54887a40..95ac1929aede4d3f82cabcf627ccf548d369b6c6 100644 (file)
@@ -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");
 
index 779fb1f680b339dd9e4fb88826fffb5127d00dd2..b3b3b3a19183507f736669ebc4f6a55302dfb571 100644 (file)
@@ -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
index dc9e34e670a26f280bdfe7947fa8709ee750465f..583fc39d84cd1f273f0c09d79318dd2b9a49b87c 100644 (file)
@@ -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
index 8fa01c0ecdb29ab9b3a9057a23bf610ce3070447..798fc718fffebf4b09e9f1aa82aa8a4b85436839 100644 (file)
@@ -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,64 @@ 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;
+
+       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 +394,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 +406,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 +419,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();
 }
index 9a39646d43160c2152a2bea1a5b39ac6b7ede63f..42ec2e99a2f4830193af2e6ceb5415c24698f417 100644 (file)
@@ -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 (file)
index 44fef96..0000000
+++ /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
index be517b048762b4fe1bb5467ebaea61a19cc1386e..5b614388d72f4b7ca8be1c851f1369f719ce2c29 100644 (file)
@@ -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);
index 69b619ddc7650c7eac714898b0219a925005a7b5..af9af5094ec33811e0fa5fba562e87a51e7568ff 100644 (file)
@@ -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);
 };
index 1d739d1a0a657aec9ee73450154ff5b5197f8939..cb5d7314cf996a3c844c476de84715bdb794328e 100644 (file)
@@ -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
index d44e0e2f11063134e9dd031c0a55b523dd76befa..841ba19d64a69b153a38ef594220d1a4054d7e59 100644 (file)
@@ -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");
index 382e236fbfd9a188a91aba9e731436dfca86dd02..64f6451499a795de85fd451903de1d9aef59ba7a 100644 (file)
@@ -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)
index 87e86a4a9eadd7f6a544fb04e228a791268e6d73..3ab5df1ce900b26f91b8b582a36188bd281c6c3c 100644 (file)
@@ -336,6 +336,27 @@ static void omap44xx_prm_reconfigure_io_chain(void)
        return;
 }
 
+/**
+ * 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
  *
@@ -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);
index 8cadb302a7d2f54a3bbcddaf7296606293d69e4e..ffe05c27087e88340c40f3a302f87aae19e1d81e 100644 (file)
@@ -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();
 }
index 76fbc115ec33f7bc620e462a01f80fd915e864c1..ce7d97babb0f9428803df53cae836e437ed08118 100644 (file)
@@ -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
index 990d2bf2fb45e6451226afe25a4699a14ff5f53a..9bf4ea6a6f7446b830a6bfadf5156ff9cf5aed0c 100644 (file)
 
 #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
index aa79fa47373ac8d3e605592cbe40e574cc9b3966..622d4e5df0293b48c697bb355a52a11613e7a629 100644 (file)
@@ -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
index 0db46895c82a4729d40b6c94c62482cd00ae1c9b..7d52cd97d96e4091adbcff105f9a0dc8db86c83e 100644 (file)
@@ -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)
 {
        /*
index b3d684098fbf545c033e56793935cee7da3e2bf0..cb76096a2e36b4ea4ccf02f983244a97919ff243 100644 (file)
@@ -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__ */
index 73e3adbc133096eca9cdf652d37ff110f5e35850..44438f344dc80f9c5073502fbe2019270d8df24a 100644 (file)
@@ -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;
 }
index 28083ef728195816b440b4076d0f1d4a69aa3092..71a34e8c345a5b19b98f42cc368f796118d3214f 100644 (file)
@@ -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 = {
index ac6fd1a2cb59fb43897d00581d18e53aa354ca80..3f93fac98d973dc9a952d40a98f33b9343545e8e 100644 (file)
@@ -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);
index 90ee354d803e6ce6a9f06e6bf3513f439716ac35..6db5fc26d154c6febf6d61c0bdf66aae9c563f9e 100644 (file)
@@ -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,
index e7380bafbfa6d37ef928fecf38ec26c56df31f90..fcf1473d6fed5398be1f9474c2543958120e22a5 100644 (file)
@@ -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)) {
index 9d00622ce8453820441e9c3c26980cab35c3dcd8..bd0f33b77f5728781f558414eebf1eb02055a78d 100644 (file)
@@ -452,7 +452,7 @@ i2c2: i2c@1c2b400 {
                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>;
index 35b8c88c3220c84c76ce1b22c8440ad8fdcbaa10..738ed689ff692b0f16b9add648f9f32dd514d010 100644 (file)
@@ -400,7 +400,7 @@ i2c_AO: i2c@500 {
                        };
 
                        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";
index 72c5a9f64ca8499fe83a11bdbb17c1c95c4206c6..94567eb178759c18162c276baa4ba481f903c064 100644 (file)
@@ -109,8 +109,8 @@ &pwm_AO_ab {
        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 {
index 890821d6e52b2d01a00e06d03ded2b49e091857a..266fbcf3e47f5640b565c09fae289003b7b9e679 100644 (file)
 
 #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 @@ cvbs_connector_in: endpoint {
                };
        };
 
+       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 @@ blue {
                        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 @@ cvbs_vdac_out: endpoint {
        };
 };
 
+&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 @@ hdmi_tx_tmds_out: endpoint {
        };
 };
 
-/*
- * 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";
 };
index dbcc3d4e2ed523e72bc8cd68dbf2c52503b7332f..51763d674050cb27c32b0909c62a62724d5d429d 100644 (file)
@@ -219,7 +219,7 @@ pinctrl_sb: pinctrl@18800 {
                                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>,
index 726528ce54e9650fe2b0ebfc085b0f0753e876d8..4c68605675a83db1639c0efed23788379c4d9e17 100644 (file)
@@ -270,6 +270,7 @@ cpm_crypto: crypto@800000 {
                                interrupt-names = "mem", "ring0", "ring1",
                                "ring2", "ring3", "eip";
                                clocks = <&cpm_clk 1 26>;
+                               dma-coherent;
                        };
                };
 
index 95f8e5f607f608d2ec1bd258e1eec76f0d4b8528..923f354b02f00d199db276f60adffb013d688186 100644 (file)
@@ -64,7 +64,7 @@ cps_rtc: rtc@284000 {
                                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 @@ cps_crypto: crypto@800000 {
                                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
index aef35e0b685a3a8599f33d1b227f31d0e5f551ea..a451996f590a5173a3e9dbe56831a623e3c0639a 100644 (file)
@@ -508,7 +508,7 @@ &rcar_sound {
 
        /* audio_clkout0/1/2/3 */
        #clock-cells = <1>;
-       clock-frequency = <11289600 12288000>;
+       clock-frequency = <12288000 11289600>;
 
        status = "okay";
 
index b5c6ee07d7f91d84d4b5b8e612fcc4f4304bc4c2..d1a3f3b7a0ab0b97aff29a898813a023a7d5bd3d 100644 (file)
@@ -281,7 +281,7 @@ &rcar_sound {
 
        /* audio_clkout0/1/2/3 */
        #clock-cells = <1>;
-       clock-frequency = <11289600 12288000>;
+       clock-frequency = <12288000 11289600>;
 
        status = "okay";
 
index 6c7d147eed54de4cc19678ce8f318987406b0521..b4ca115b3be1c0a25121517e1e9e598d26c7c0b1 100644 (file)
@@ -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
index 99fa69c9c3cf3ebf080c7443fb16ac6c11cf234a..9ef0797380cbbdf182a86e934c2eec5aa97d889d 100644 (file)
@@ -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");
 
index 366448eb0fb7ad093d1e85eec0e84126cb32aa3d..a02a57186f5689b7a3d99869d6770f7705332957 100644 (file)
@@ -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__)               \
index 32f82723338a0e23bd880273aa9ae53e93a9979d..ef39dcb9ca6af1150152883cf338114536167b5f 100644 (file)
  * 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)
index 16e44fa9b3b61b0bec9cc8ed92874310cd094176..248339e4aaf5a7a0b6bc09bc2184654bbda72845 100644 (file)
@@ -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)
 
index 8f0a1de11e4a6cd11fc7af0bd6db587538fab7be..fab46a0ea223d74781464a2a3904a4d2eac0a423 100644 (file)
@@ -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"         \
index e137ceaf5016b2d796e6703058d6f62209955059..d16978213c5b332b439205f7c582e1c9a2f65e4d 100644 (file)
@@ -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);
index 321119881abfedf93b4df127cb4f8bc74764e20d..dc66e6ec3a99dfe9e91d83f1cde2cec8ff225863 100644 (file)
@@ -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;
                        }
 
index 79244c75eaec4fb6f13d3b19a9fd1b8e20346108..8d48b233e6ce5d09cd84db6a21a52f4d0dd68e97 100644 (file)
@@ -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++;
index c7c7088097be0c1b8e80d594c3d02f715c03abfa..8a62648848e5754a747649078206e782ef550172 100644 (file)
@@ -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;
 }
 
index 77862881ae860943b2f2553dbbd93c65b64102ab..2e070d3baf9f12db1363ed95d079b19b02ca0382 100644 (file)
@@ -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);
index c3cd65e3181414bcaf3ec5b50937f95bf895570b..076c43715e64afe7fcc12eabd753d355ca94558f 100644 (file)
  */
 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]
index e90cd1db42a809ebbb978cc9ae4674c0944d265f..f27d4dd043848dc8775a52588cffa7e27bd006a6 100644 (file)
@@ -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) {
index c7861c9864e69e7b6dc7efc16083063bbab99e98..2509e4fe699225675f74876032e22b24b338a3b1 100644 (file)
@@ -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;
index 23c2d89a362e4423f62c732b290015d23211f38e..f1eb15e0e8642d2a74c7d19d18e8e8d3ae5a7062 100644 (file)
@@ -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))) {
                /*
index b388a99fea7b783e5ab8edcad004f8a7457ee40e..dad128ba98bf8d827a1f7cc750f41c543a8f92f8 100644 (file)
@@ -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);
index 8d9b1eba89c48ad57a1437c0e19716082266cc69..76b2e82ee73095e049cb7b305e32ba659cb8b831 100644 (file)
@@ -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"                              \
index 296d7f56fbfd005bb77b264474a179bcfb81bc61..f1d6ba7afbf245a0e593bf9aba7aad6229902ca8 100644 (file)
@@ -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) {
index d29ab6a2e909f301154a65409847f2b0a5256871..8ebc54daaa8e9d7c141ae1fd21d072812b0746ae 100644 (file)
@@ -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;
        }
 }
index 18d024251738dd4e8499f0687842ce776c59816f..7e0bd6fa15324495ea5875fd3180c7f8081c54e3 100644 (file)
@@ -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;
index fced197b96264e01b20743e90706ed20cf30b242..cbe5ac3699bf0f9dbdfd726c112f6fc6bd1271f0 100644 (file)
@@ -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.
index 48b62790fe70f1a620b0f5e47d0546e07ed77664..b2a41f5b3890a524d0335b89aaa3111194cd189d 100644 (file)
@@ -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;
 }
index 8dd20358464f8efabcad2185d2b6f56c4fe805fa..48d91d5be4e9b6cf56c1cd0849830e2708967aa2 100644 (file)
@@ -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
index 04343625b9292807d886951eaed6866426dfc42d..bc2708c9ada40cf4206cd228d84a6ebf634161b3 100644 (file)
@@ -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 (file)
index 0000000..ebae133
--- /dev/null
@@ -0,0 +1,2 @@
+ashldi3.c
+bswapsi.c
index 542be1cd0f32c6cbe14cb0c3936ffe9cd11bd594..bfdfaf32d2c49742066329e800a6b535f363c3e1 100644 (file)
@@ -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 {
index 1910223a9c02ba1474929905b235e43a07501aaa..cea2bb1621e68b211d5dc99fdad78f208b1ad8a3 100644 (file)
                 * 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
                 * 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
index fc67947ed6586c2e416b2f6cc588a4445b3761ab..8b14c2706aa52ca83e07ff4dcb37c71850d133bc 100644 (file)
@@ -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)
 
index 8baa9033b181d2ca2e3f6e469315bdb8bf5345b5..721b698bfe3cf7e0274bb9f0bb4bf58bfecef29e 100644 (file)
 #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
index 9df1a53bcb36c60bc082223ff8daa24a7eb4a506..b4e7dfa214eb0b882022fe1ce2e8e7e7c3f0097d 100644 (file)
@@ -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,
index d045973ddb336abbe9b54b21a65b4fb1a6c4f5fe..3ea84acf1814cb2c874ac17dafc73c64db50b5dc 100644 (file)
 #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))
                ((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 (file)
index 0000000..a951ad5
--- /dev/null
@@ -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
index 9742202f2a326c45c504de6d77b51eb523421c0c..e638735cc3ac56c84fc861f293e6f2217b7ba3cb 100644 (file)
@@ -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>
index 68e19b689a00c4d783cdde376ca40c95a48c3f3c..1609cb0907acecaa03d149e4b043ebe3dff952c9 100644 (file)
@@ -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 */
index 770d4d1516cbb1ff34cca30cdccbe6c1b0aeebdc..6bace7695788fbc3b7663aeb353a08a3c45503af 100644 (file)
@@ -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.
index e08598c70b3e72d3c579462d9b82cbe340256ac9..8e78251eccc25e0a981ede0b89d1df907f9e896a 100644 (file)
@@ -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)) {
index 3f74f6c1f065fb6b5d2b930dc1d164e1624e63f0..9fea6c6bbf49e3768e81ad3ffb8b8af2bbdef61f 100644 (file)
@@ -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 (file)
index 0000000..3f87b96
--- /dev/null
@@ -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;
+}
index bd67ac74fe2d3420509a03647a20856341bb70c8..9632436d74d7a74b3d584ab6e87a1fc7e55827cc 100644 (file)
@@ -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);
 
index 094a0ee4af46e913f2cb92f25a8503313dccc26c..9be8b08ae46b76a59984f47745138ceb16983e3a 100644 (file)
@@ -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>
index 974276e828b2cdd3eecb07493f480a8779da2d41..e2690d7ca4ddd992e69fffe802cac6355ad14de8 100644 (file)
@@ -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;
 }
index aa6a3888639144a758e88e9e157943ebd7282569..811414fb002dec95e2e2fb17251fb67934d31f50 100644 (file)
@@ -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"     \
                :                                               \
index 531da9eb8f4363ad95c65e16b3d7c9653ac973b8..dda1f558ef35c5fa9113c763c846924ee24f93dc 100644 (file)
@@ -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
 
index 143d0265279204ef9e51288640ba091eb2453c27..ccc109761f445655218bd3cdc16a16f772b65d77 100644 (file)
@@ -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
index 1a4f776b49b8915dca8cf9d1dbd09e6116b96204..5acb93dcaabfd84680f7c5cdde0a598fc4bf1b3e 100644 (file)
@@ -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
index f1a0c25bef8dc3a6667c608a092f96a39d5994aa..83ffd161aec55fc1f7063c7ed8bcb9f92bcca909 100644 (file)
@@ -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
index 8e8f0e34f8174c5905ca8b3b3b65c829c3557265..0764d3971cf66e456a03e26f7542a11ddd98f86f 100644 (file)
@@ -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
index f6a4c016304b657149d8c87f23e0c564e875a36b..088ab948a5caf8b8f7455233c1cba5295e00cc0f 100644 (file)
@@ -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
index 310b6657e4ac9b38380eaecab1eccf12aeaad0d6..52c9050a7c5c6d5305923a5e3f357ab9f6515a78 100644 (file)
@@ -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
index 8688ba7f5966af8d7b626054a366d44c0448becd..37ae4b57c00151323e0561551a9aa1a3ff0d8d29 100644 (file)
@@ -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
index c564e6e1fa23424c39efa967cce4a42ac9ae4f2f..d39e7f821aba318377b16bf2ef48b58315f5e252 100644 (file)
@@ -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
index d2742273a685df2d243a14fd19a7b47b5a1b94a7..07ea467f22fcd50f5e6721db491e9165d417666f 100644 (file)
@@ -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"                          \
index 32e105fb8adb362f261d20432f1f8af068086376..e3c0586260d8a34cd188764dae1e5452eefd7c22 100644 (file)
 #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__ */
 
index 88fe0aad4390b10830ce1bc1be62925d4b2d4bbc..bc208136bbb26a837a978cdf77304f1c9dec0b2d 100644 (file)
@@ -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)
index 674c68a5bbd035c86bee42834d010ba20eb06464..d0e3321403bedcd641610ba744e96ba45ef1d6cc 100644 (file)
@@ -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
index c32a0909521665b5f08c22ef37fa8d8f9c654012..19c0c141bc3f9f0edd509708f978a2d7ca16c230 100644 (file)
@@ -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));
        }
 }
index 98190252c12fdc801ca8f7f328733727577f48f2..f622a311d04a1a99676f5b90469d18940a9d8294 100644 (file)
@@ -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;
index ba5e1c7b1f177d45f743392c0950017622b143a8..0ca254085a6626374ed488401618ca3af19872c7 100644 (file)
@@ -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 @@ static inline void stack_overflow_check(struct pt_regs *regs)
 #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
 }
 
index f3a797e670b09461b45e1e7163d036fd457beb18..d02874ecb94df27d3171ae221ba693f4f8ca0a9c 100644 (file)
@@ -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);
index b64d7d21646ed50c4a5c1f046b0f8ca758abfcc6..a45a67d526f8ca8001fd1d06625b3b233d5a3835 100644 (file)
@@ -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 (;;);
 }
 
index 3d6ef1b29c6ad312e5114f86ad737d13bf606403..ffe2cbf52d1a25617955c54f73890fdb02e7e394 100644 (file)
@@ -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 */
index 8d4ed73d549091368be87c5b4483f33d6b00640d..e2b3e7a00c9e3548e0b0086f878d4b707ba40dbb 100644 (file)
@@ -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
index a7814a7b15233261b0d9ba9d848543948dcd34d6..6f952fe1f0842232fab09eba6d89953d09946111 100644 (file)
@@ -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 $@.$$$$ $@
index 0695ce047d565199e4501333fa41ece48cdf9e45..34fc9bbfca9e68d6372e1d34b79ebf95d978e685 100644 (file)
@@ -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
index 5175028c56ce74e3e50a2b30eabccf7b87ed8f0e..c5246d29f3859965316bd4d48e4e816283439bf0 100644 (file)
@@ -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
index 1a61aa20dfbac9d5072ae83ef90640b8be380bd3..fd5d98a0b95c7b1ae5fda56892c2ecd43ea29f3a 100644 (file)
@@ -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
index 0ce513f2926f12680ce1570266550eb8b2b09eeb..36fc7bfe9e1140d1e5eabc781199851a6445d51a 100644 (file)
@@ -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,
index 77529a3e38114cd4e5d413d687184e037827ea3a..5b4023c616f7087d247d17509f170944b26f6a76 100644 (file)
@@ -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.
index c0737c86a36272b1df213a41c4c75426c16d9178..818a58fc3f4f967d3bc4524c32e64ba4529c4cca 100644 (file)
@@ -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_ */
index 487709ff6875bd61d6b6cc7c8652c7e27f8404a2..544440b5aff395c1d00076af87dec8b15628dd77 100644 (file)
 
 #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,
index 0151af6c2a505a77c512110271e73f0c9c3fcd6e..87fcc19488177e6e15b79e1a7e5487edabe4b408 100644 (file)
@@ -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
    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"                          \
index da7e9432fa8fc512b8c00f0ecc57bd626cf56911..0c76675394c5930d5cecf2ac01a2718c8e9b6c1f 100644 (file)
@@ -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
index dd01212935acacd32504e0ab2783b6670674f744..afae9a336136a4916c9912d3fd7f8c8f268406f2 100644 (file)
@@ -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 */
index bfd609a3e928f8b8536567e4e030cf8ff05643ff..e3b10469f787786a2c7ea3ed1013aff35ce619b3 100644 (file)
 #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
index 49d8422767b4de686ec0ee64fbf69ac415f05003..e925c1c99c71cab982967e7f7df6325e3135506f 100644 (file)
@@ -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
index e6d8354d79ef25a34ece7766683813a65ffde57c..f14f3c04ec7e0c7d366f60d161ff0ced6f1497ad 100644 (file)
@@ -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,
index 5adb390e773bdd441ed0456eaed2511c094264a7..e6252c5a57a4a06f10bd13710ceecdcf72c3d26e 100644 (file)
@@ -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
index 0bcec745a6724771c076e34132fb40e158b318f1..f291f7826abc65fe27bd9502ff45d922fa3f9e4e 100644 (file)
@@ -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 */
index 9f3e2c932dccc1c3a1158fc174a8cf57e63dd75d..ec480966f9bf55f17184537f64e7d10c40c723c0 100644 (file)
@@ -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;
index 925a4ef9055932174b4dc5a8f0424b330149132b..660ed39e9c9a59fc3b7087362787502a41ba50fd 100644 (file)
@@ -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) { }
index 997c88d54acf292b3e80beef1791ee2194ca9071..8d3320562c70f3ef7308645fb7b805fc14794e42 100644 (file)
@@ -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();
index b67f8b03a32d0f12ce29eeb4ac3be0a97384fe72..34721a257a770c450baac0288f8006c94ff1975b 100644 (file)
@@ -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 @@ static void watchdog_smp_panic(int cpu, u64 tb)
 
        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;
index 8cb0190e2a737aab903d350bb6d79422a8c37ac5..b42812e014c04b2fc96cdf5d183c23df0ee88b53 100644 (file)
@@ -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)
index 0b436df746fcb094d8bd8b3c928c0862d6a90df5..359c79cdf0cc821d87a4e4322177294648b42ee3 100644 (file)
@@ -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);
index cb44065e29463f99d6c44bf129ca01e82695a8ff..c52184a8efdf025c1efffc6dd7310e9374dca630 100644 (file)
@@ -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
index 8541f18694a4a6d8003b32ad29f7c192f190ef6e..46b4e67d2372328231b47c7e225af6d780fde022 100644 (file)
@@ -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);
 }
 
index abed1fe6992fa1bb365dfd30717bcfac3f402ee4..a75f63833284cbb089f67fa21bee0357426a2a88 100644 (file)
@@ -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;
 
index 188b4107584d2a741645aac48382bffadbfb4116..443a2c66a30467d7bea260d6a7d01df19d55c33a 100644 (file)
@@ -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
index 8c13e4282308add562bf794be32b989ef90eb803..671a45d86c18dd7e174ffb909084cd0a37fcdaff 100644 (file)
@@ -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 @@ int radix__map_kernel_page(unsigned long ea, unsigned long pa,
 }
 
 #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;
index 5c0b795d656c4298fc36aaac72d15d58359f23e7..0736e94c7615a67b2efd8bd39e237bb757a8e74c 100644 (file)
@@ -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
index e94fbd4c88458aa5953a271b1ef1eac0ef5c5c66..781532d7bc4d29683ab2ac72cff6f0ad7d4d01f4 100644 (file)
@@ -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;
index 744e0164ecf58551f036ef30e19a79638adcaa76..16ae1bbe13f09e588919f8aa55a81ed575290360 100644 (file)
 #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 */
index d7c9b186954d931c0957908dbd7a19e3f19d0610..763ffca9628d2e983299a2d44cb007cbbefd85c9 100644 (file)
@@ -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);
index 2abee070373fb3a8b757b8d3cb269e5d0b89dff6..a553aeea7af683812ba2f5a80d65e97cda163919 100644 (file)
@@ -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;
                }
 
index 9b87abb178f02aaa0dd3afc757499df58bf133eb..cad6b57ce494bb72dff04102e7d8d0499b8e038a 100644 (file)
@@ -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;
index 437613588df15ceab2a1ce5e88649b675c495de4..b900eb1d5e174c1cdafc0a7e9620caecac98bb69 100644 (file)
@@ -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);
index e5bf1e84047f4c3fb9746ae85b0c6593f47ab012..011ef2180fe6b8d85f4fa11a1b31e8636e29d617 100644 (file)
@@ -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;
 }
 
index 1bbd9dbfe4e0a2baac12f5a83ac4538bc8a6ca8f..ce9cc123988b975b3bf6766926b2f4f7b158e1a8 100644 (file)
@@ -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"                \
index 7317b3108a88859a91523c45f1e52c08cb22fdc4..2eb8ff0d6fca443543c32ac80ff690b4b67be1ef 100644 (file)
@@ -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);
 }
 
index 0c82f7903fc7a7c0bfc9c7d5b02ab79ab4a2be89..c1bf75ffb8756549b1c6a5c97908ff49dd2e79aa 100644 (file)
@@ -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;
 
        /*
index 3f2884e99ed4ce461cdb6f08148968880e90747b..af09d3437631d348dca2f1a6699c34ed49c624ed 100644 (file)
@@ -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);
index d4d409ba206b2e0f4ed0b88cc4f3a3ba125b3597..4a1f7366b17aeffacb6c766ab891227e2609f1b9 100644 (file)
@@ -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);
index 01c6fbc3e85b62fdec83bacea0f76a88126bfe84..1803797fc885cf799337b5d61f30ae726628b8d6 100644 (file)
@@ -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);
 
index c9828f785ca0bce1f3e49a73def335bfc67eafc7..5b5086367639f0f103edd9d5f3adae0c46ba73f7 100644 (file)
  */
 #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"                       \
index 46e0d635e36f711aff9a88c45955905d7fbf3cc2..51a8bc967e75f1e3c96a70783e9da439310edbcb 100644 (file)
@@ -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 */
index eec7901e9e658b18e0eadeeb2af65966cc15993d..787bac9f67da3fd069f3f5f2d05e535b819c86cf 100644 (file)
@@ -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 */
index c74d3701ad6830fe88338c185be374f7a6730f07..207a43a2d8b337ee61d8d982341946018ded5c97 100644 (file)
@@ -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
index b2e650d1764f63d430d6b96eac793621d26902da..ca8609d7292ffee5ffbf068eb2b11653bf59ff7c 100644 (file)
@@ -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
index 2cddcda4f85f7555dced053b1fc82fd991e19943..87841d687f8d5306663c54d050aa0ca4b2b08cd7 100644 (file)
@@ -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
index 1d8321c827a8821bb4e9f4989eb883cd761370db..1b1286d0506910c0f9a92ab6af14e272dd008d61 100644 (file)
 #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 {
index ec9c04de3664910d81b7a55bbb09084d5e235d39..ff05992dae7a352597bf99fcd2d83500ad0c2995 100644 (file)
@@ -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);
 
index 6d27398632eacd22a72e0437ea57d1c048930d11..f5df72b93bb27fe7601b4994889d4103562fffc0 100644 (file)
@@ -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)
index 493e023a468a919c61d77451e43e0a4a2e414bbe..ef4f18f7a67402ed8baceb2ea05ee7f6368cc404 100644 (file)
@@ -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";
index 45c820e1cba5d949ff936f15392ca3c0c8578a34..90d550bbfeefe484f1560940f111235f26332d7a 100644 (file)
@@ -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;
index 41a4073286671eff51f275bfca4ae6d9d01db74d..78e0211753d28f14f955af865704248b1e5daf24 100644 (file)
@@ -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
        
@@ -600,6 +603,9 @@ niagara_tlb_fixup:
        be,pt   %xcc, niagara4_patch
         nop
        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
index 24f21c726dfad7474da03d6a4a80f329843ff8e4..f10e2f7123949dedc8904ea37895d402ed097d2b 100644 (file)
@@ -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;
index 4d9c3e13c15056b5d60e7ccd266b36cfe29d2c00..150ee7d4b059a69e174dff7c7d16ff906f73e1ed 100644 (file)
@@ -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 |
index fdf31040a7dc5cc460de6d60c9724a60933b38dc..3218bc43302e1cbbfc48420d868f5148a8d61085 100644 (file)
@@ -622,22 +622,48 @@ static void cheetah_xcall_deliver(struct trap_per_cpu *tb, int cnt)
        }
 }
 
-/* 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);
index 559bc5e9c199232d092ec425d705a016b639db9a..34631995859afb2c273f3087796ff550371bc634 100644 (file)
@@ -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
 
index 196ee5eb4d489b156d677f079f545e6ff792289d..ad31af1dd726575986c87bba514b345f291342ec 100644 (file)
@@ -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);
 
index 07c0df92496034efd1262dd2b40e56ffd5486c0c..db872dbfafe943fd92ca10b9995b003ed6a1aee7 100644 (file)
@@ -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]
index 54f98706b03b2f53025adb99e086002a0629e9f0..5a8cb37f0a3b8e31d0a4194d831bb39559bb6a51 100644 (file)
@@ -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
 
index 3c40ebd50f928cbbbfe69c65c35810a78b30c53d..afa0099f374852e0cf093088d942512008a45a68 100644 (file)
@@ -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;
index 17bd2e167e07edd934dfe9957c43712b21401c55..df707a8ad3117074805e138a3992a7e080d43e5a 100644 (file)
@@ -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));
 }
index 600a2e9bfee2feea2a6dbc8b91d2a5a872d9d8d3..344d95619d0334659e6f4a9f3a5bff70ae95f67c 100644 (file)
@@ -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 */
index fcb7604172cecb9879652a2b3f768bb9117fdf1a..cd20ca0b404341d12e3a619fefacf7f3652a8ea2 100644 (file)
@@ -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---
index 0d810fb15eac82fc72e555ca76eb42cbdba90564..d88a2fddba8c7edb3eda2e21ea4a142ea25644a9 100644 (file)
@@ -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
index 2c860ad4fe0686a9cf796cd9a5b4453b8199223f..8a958274b54cc4bb9d17888f80aa7737fad4f618 100644 (file)
@@ -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
index 630e3664906bfc399c885ff7c3525fc27bfb7218..16f49123d747b7a1c224b75c60d8a3af1e8e701c 100644 (file)
 #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;
index 6cf79e1a68301794f35977bf03ea190cc3caa2fd..0eb9f92f37179516637d1722bd12522e9060d231 100644 (file)
@@ -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
index de45f57b410deb314ee0b6a89af702866cc23c02..4a4b16e56d354f3d48bcf8ba8a6ac21127f4cf13 100644 (file)
@@ -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
index a9a8027a6c0eaa748541282448f41b9eec834d6c..d271fb79248f3569c6a0a934f707d91f398562b8 100644 (file)
@@ -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
index ff1ea2fb97055e4d6a3282a18c16a0eea689c29a..8e3db8f642a7a02dd8f99db3a25dedbfd1deb01a 100644 (file)
@@ -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;
 
index aa62437d1aa142a3960804d44ad48e6f08e44eb8..98b0f072952735da9928970093ac1857bb9a932a 100644 (file)
@@ -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:
index 238ae3248ba5594265f14ef37ee6fde5c320675a..4cf100ff2a3746f440049dd5c27c254e4dcc1776 100644 (file)
  * 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
  *                            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);
index c6d23ffe422d110bf91483427a6198e6dd0eaad4..a322fed5f8edcab18401e2745438c362f80e0851 100644 (file)
@@ -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;
        }
 }
 
index eb261656a320d52cd428e7ecdac34b62474ba20a..955457a30197e8be224f0304ec83f14365b3fba9 100644 (file)
@@ -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
index dae2fedc16015e691ad6ae85ce4bc4122011eefc..4f9127644b80abd87d4c49204dde197a9ade7ac2 100644 (file)
 #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,
index 53728eea1bedea1562715228404d2efaa7f030a4..476aec3a4cabd3852be09731a69f6c5f3c28948b 100644 (file)
@@ -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[];
index 39e702d90cdbdda8df0b42349d9f8d262b08bf4d..aa6b2023d8f8bc104e0b30a086a4c981ed47abb1 100644 (file)
@@ -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"                                  \
index df002992d8fd3dffa9d9d0913e823ae52f9e2256..07b06955a05df90575d2d66ffec0e0b44793a587 100644 (file)
@@ -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
 
 /*
index 9b76cd331990159dcdd042e10f90946f7440adba..ad1ed531febcbc3a15992be0e367f1cb4d43978e 100644 (file)
@@ -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;
index b90e1053049bdd17ad36989315db8ac1b3ccc973..d6dbafbd420737a5ea5363c700940acb22a8c358 100644 (file)
@@ -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
index 21126155a739f4a3495499f052abcd3eab5a0bb7..0ead9dbb91301d0f7f8923dcf33f25515bd182b8 100644 (file)
@@ -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 */
index 7afb0e2f07f40d69ccbe44a70baea52bc70ef685..48febf07e828099d0580be40ad82a8baee6ade18 100644 (file)
@@ -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)
index 6ca9fd6234e13b83de1bd495d0c4f7231ba439d4..aaf8d28b5d008969786ee60522d0d2f2a2fae126 100644 (file)
@@ -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
 
 /*
index 34b984c607903751f867b85d962457f7ea04776b..6cf65437b5e502194c9f4a354f755ee7b2a39102 100644 (file)
@@ -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 -       \
index ecfcb6643c9b4502fa8d89b99dd8b351a9665b73..265c907d7d4c9b8c69e24792a20c5a3dfb6c95ee 100644 (file)
@@ -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;
index cb976bab62996332f8b808ebaa18315d35005679..9ffc36bfe4cddfb96a019ceea43c074a9be682de 100644 (file)
@@ -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;
index 6a79547e8ee01e06a84cc948f0d9a61002cdda82..028245e1c42b23d1498643427ebb73be25ded661 100644 (file)
@@ -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;
index 6bb680671088694af194eabd987fc86b2b02441d..7491e73d92530bf868a9b91b2c71c892bcbdb94a 100644 (file)
@@ -346,6 +346,14 @@ static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
        int pin;
        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'.
         */
index b4f5f73febdb8c2ac3b64f3964027869b80cc835..237e9c2341c71eef924296d3d425c9cd4e95f447 100644 (file)
@@ -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);
index bb5abe8f5fd46c17ca7c27361cbdb99e00db645f..3b9e220621f83c8a5161e8b57b297233370f72ea 100644 (file)
@@ -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();
index d869c8671e364d55e343322b410fec9a3e5f66c6..7cf7c70b6ef2a20483361fb8333a85ace25bf1d7 100644 (file)
@@ -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);
 }
index 3fe45f84ced4463b147bcb907feedca94c07cab0..cbf1f6ba39a8328acded677cf10822b45ec4b198 100644 (file)
@@ -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);
index d907c3d8633fdb289ea03397c2e76efc284517aa..a4516ca4c4f3c684a3b150435c0e851d60aa3b48 100644 (file)
@@ -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
index 16f82a3aaec7c9c8d85e7c8b4f805da396981fce..8ce4212e2b8d0f139e543e05e7e284ee25ee856d 100644 (file)
@@ -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,
index 4aa03c5a14c905e9c1a1db283d61ac56372041c9..4ed0aba8dbc83b6ef83aed558ae4c459009d9146 100644 (file)
@@ -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)
index 7468c69875477e876dafd5209f0cd83c6939bce9..c7fd18526c3e3087dee25af3ab0c3f3ff7dc616b 100644 (file)
@@ -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 */
index 6b877807598b9028527a2357fef630431021c383..f0153714ddac6b2305645ef5c0e35fd3a6c9fb2c 100644 (file)
@@ -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)
index 71c17a5be983524ea277718b759ff1511a9a3214..d04e30e3c0ffd3f255f50e595c0ab0f919fddc70 100644 (file)
@@ -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);
index 67393fc883534f47a5d5c4d92478da9f0601ef53..a56bf6051f4e3707594b1b5ddab9711da9c27117 100644 (file)
@@ -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;
index 760433b2574a502a907adcd1ddd71ad6b7f4f9fd..2688c7dc53234bcdd66fff189b83cde9cb0583a8 100644 (file)
@@ -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
index 2695a34fa1c5190f98b9fdd092e9cc2d3e44b2a0..337b6d2730fa15b14a8c411b9a77662e48f4a190 100644 (file)
@@ -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);
                        }
                }
index 2819d4c123eb89c0e00e9785239f19e2b79d6f73..589dcc117086ffdfda31920cfdddfc462bd468c9 100644 (file)
@@ -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);
 
index 4d8141e533c369711df245d0a783683598ad4559..1107626938ccff4f26da130f8b570928ca7c8efb 100644 (file)
@@ -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
index 84e62acf2dd861023b17382e61f9c98c8df82f68..9b21b12230354e334900e6536b7612285f75b7e3 100644 (file)
@@ -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 |
index 5b8f07889f6a591f4e23ac69c6bb9656e7bc0a31..d734aa8c5b4f7290e365badd00ea962fd0af9acd 100644 (file)
@@ -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;
 
index 9b0c63b6030296defe20d5035b4feedf344b251c..1b2dac1743213475c461df056b4009641e7ced49 100644 (file)
@@ -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 \
index afbc4d805d66f51b5392056a0f83cc42382c60ad..c9c320dccca13678df20155b450abe648aef7488 100644 (file)
@@ -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; }
index b77360fdbf4a8cc8aa191147208d6acb50609d78..19b33b50adfacc0e6cd607750378219cd3052bf8 100644 (file)
@@ -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) {
index 673541eb3b3f16c8c029349d597d67f4bb83a77a..bf3f1065d6addb88b898ba3a86089cccff6ed15e 100644 (file)
@@ -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);
 }
 
index 6e075afa7877b349dc3372a122597b663c5ae77e..58337b2bc6823a5730a48be02559dee4affc07ec 100644 (file)
@@ -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");
index d4a61ddf9e6220e3bc1ff4c996e5f9441fb7edd8..3e4bdb442fbcfc783059be96efe4d4e2d6b58b47 100644 (file)
@@ -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);
index 87d791356ea9052f79f23e00f5d0024ff8cf0b7f..de503c225ae1f194b10c71b44528ad2a2a7a4c0d 100644 (file)
@@ -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>
 #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);
index 1ea598e5f03025ef509aaafca17623f7d8cbed5f..51471408fdd1329b0097f2463acff17596b83b1e 100644 (file)
@@ -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 */
index a1895a8e85c15753d4781c3ac72185b4c96a7d9d..1ecb05db363203ec004f0e3c6764ca5f448fbc78 100644 (file)
@@ -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) {
index 2d716ebc5a5e90d62c3759e01a512e0ff6ab9de4..dff7cc39437caba214fac506f57009837f2223c8 100644 (file)
@@ -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 (file)
index 1deeb8e..0000000
+++ /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 (file)
index 0a70e78..0000000
+++ /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 */
index 98b004e24e8523b735d60937c56e22b2b0f7d2bd..47d82c09be7b0b0df85c9fd97ec50334cc6d738c 100644 (file)
 #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)
index d159e9b9c01837ba5aa9e77d50c3c14e475ce367..672391003e40fac4f814fe5b6aa1dc04e791c81b 100644 (file)
@@ -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
index 1a804a2f9a5be6212c57febc01f6d28f47b8c91a..3c75c4e597da8f086f65de51201e0d37d6672733 100644 (file)
@@ -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,
index 60a6835265fc386a229ec96338eb735c7dbea65b..436b6ca6b1759228b69d3087c5e4ea0708940690 100644 (file)
@@ -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)
index 8fd83b885774392fc1368b728621a430ffcec519..859f0a8c97c8a1bf58b6ed4dc016c0ce0fb355ad 100644 (file)
@@ -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 */
index 5ec05cd42b80725cb297129739da2edf1372a70a..911aa7431dbeb08d6db591c1a0f577bd3af56e22 100644 (file)
@@ -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);
index 83e92beb3c9feb25f3be917e2b675f90b1544b5f..9b1ea478577b033195f34b457c85ad16eb759c6a 100644 (file)
@@ -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;
index 970b9c9638c55f4852019f452f64d2a4c66c1a9c..dbecbf4a64e05b764a1ba0a3c4dfe8f01bc7aac1 100644 (file)
@@ -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);
index 4891f042a22ff7c7a27abb0f71a6c65fa32ffd51..9f8cffc8a701ec24c87729b9ef4a1048cc7d205f 100644 (file)
@@ -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;
 }
index 041f7b7fa0d6def444e9349b6cf748afc8e89b2d..535cbdf32aabb28de64e7613e748bfa7a73ade6a 100644 (file)
@@ -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);
 
index 6f8f6b86bfe29e0cf0c8fbf2cbe6ab26b705bc9a..0cf5fefdb859b1158460faa278017a524f54a93a 100644 (file)
@@ -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);
 
index fc6c416f8724670aef2f29d4d81d373ed400dcd5..d5999eb41c00176e840d90b84241ab855c8881c4 100644 (file)
@@ -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
        { }
 };
index e51a1e98e62f4f5ab5f2132184e9686ab1a1f3a9..f88caf5aab76217d73feb277b1918e399cc61beb 100644 (file)
@@ -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)
index 8c4e0a18460a78df600067da69537e6256d6bc1c..bf22c29d25179e937523c026c8028f644f3379f6 100644 (file)
@@ -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;
                        }
index ddb01e9fa5b225eda5a83cf8a06501ddaded2fc5..62068a5e814f026a44e212bd2b93941590a3fe53 100644 (file)
@@ -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)
 };
 
index 9531d3276f652a14e5eb39d9e0cb8a0325353f72..58dd7ab3c6538bd490b45e2e420c3d822ecf8c3e 100644 (file)
@@ -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
index b75b734ee73addc621c26710d8dfed1cbbe05fba..19182d091587382e0b94e9354f9c442ea90624a3 100644 (file)
@@ -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)
index edb0c79f7c64eea8b4d3cdde4467a356c20a32f8..917f1cc0fda4c2f6c8cc64f7b90dc252a264ac7a 100644 (file)
@@ -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];
 
index be17664736b2f12388148580ccb0b2f0450c348e..fa8243c5c062c31b74847a0eb7c87e1f2d30e240 100644 (file)
@@ -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;
 }
 
index 4ac3e06b41d846440d35079dfa54885111eec0df..98aa8c808a3346dc559e2f419ae4378dec075ffc 100644 (file)
 #include <linux/kernel.h>
 #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
@@ -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";
 
index aae4d8d4be361b6a38195f165c630e74cefdfdd6..f7665c31fecaf3f46b64e17a821f9b8528def937 100644 (file)
@@ -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);
index 948fc86980a1b75d1b9f99e9588bf894e024a88c..363fc5330c211456762e049d1569a04940c580ef 100644 (file)
@@ -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.
index 8453f9a4682f855e910f59d1d78860f639d4bf59..fa7dd4394c02b642c00119bd00a4b59b18921a0d 100644 (file)
@@ -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 @@ unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
                                     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;
        }
 
index b70bcf6d2914b6a82967fee346f5865b5c3b66b8..3dbd05532c09cdde995935539efa917e4f96dcd9 100644 (file)
@@ -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);
index d462c5a3a7efd8b3c4933df845c0f3f1d8637bac..44ba292f2cd793f07e279ada3b2c83c44578f0cf 100644 (file)
@@ -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];
        }
 
index ee98447587366f240a580e56a49e0983f58727e2..537d11869069aae7d26e1e253ed3f4d587d25bbf 100644 (file)
@@ -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);
index 292dec18ffb87acf57842f3a0c2490b326488e12..07bdd51b3b9aab2e82e79346f52f6eb1bf4d9cbe 100644 (file)
@@ -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;
index 2ae24c28e70c87901185de6d558545ebe58d8d0b..1c152aed6b8265409a0ab2a677ce4bd0a99d62a9 100644 (file)
@@ -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 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size,
         */
        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
index 5096755d185e0c1a597d25189547ab797b568f36..b555ff9dd8fceb176af2f567157165726e9ab314 100644 (file)
@@ -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)) {
index b9f907eedbf770ee32359468d2b8d07e57bde667..bfbe1e15412889dfb40e699af7c3623a06d83253 100644 (file)
@@ -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;
        }
index 3b8210ebb50ebfd1844622a883193fecdacaa282..60303aa28587b9079317a8fc3500ef1aa70ec247 100644 (file)
@@ -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);
index 5f04e7bf063e1b24413bbbf2f9dd6fe6bd53471e..e6c64b0be5b21a7414e32f62c52983a7b239990c 100644 (file)
@@ -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"
 
index dea7d85134ee6eaa04803f1a0ce4878756e1461a..5bdf923294a5d610429581c83e558529f7d40b62 100644 (file)
@@ -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);
index 6b16ead1da5871abcef5b2233733f281158596a8..ad9749463d4fa9a382afa7f24587bbbe3a2efcc9 100644 (file)
@@ -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);
index 4e02aa5fdac053dfa254fb05aac1b2c252e4c1be..1498b899a593e31951c835f4f537d1bb03d0e596 100644 (file)
@@ -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);
index c852ed3c01d55f23c69e4c9133b2fd88137402f9..98e34e4c62b8b228a6ee6d37256e860ee7d3c2b7 100644 (file)
@@ -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 @@ static blk_status_t blkif_queue_rq(struct blk_mq_hw_ctx *hctx,
        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)) {
index 856d5dc02451d44b59695127994017877cd02b38..3b1b6340ba13a2977ffd0a13424ce95322f67f0e 100644 (file)
@@ -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;
 }
index 1e6e0269edcc18ed9f7c8e4cc65e6ce6595c8683..f76be6bd6eb3dfd52bac8c847f3a93e5c3f7777c 100644 (file)
@@ -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);
index dcbbb4ea3cc1d7040a847799fad2415e44a24e08..89527bae4602a906bde52ee056bb9acb0306c01a 100644 (file)
@@ -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,
index 5fbd333e4c6d74bbd2e34f25ac74648f9b13a62d..b450544dcaf0fc3c188b3eabfea7319438709ed7 100644 (file)
@@ -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,
index c99cd19d91479ce62ca1871925fc046f9efa16fe..e50c29c97ca74d20542a176387d3de8ee4780b79 100644 (file)
@@ -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,
index 0b5ec7af2414bb924fa1a927aafe0d4115492281..88b4cbee4dac1cf748aa8a5799e7c1654ef5929c 100644 (file)
@@ -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,
index 533cb6d229b8ed2e974ae94801ec80f5b456a133..7f88490b5479c3f47341712d01f36095c0477b0e 100644 (file)
@@ -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,
index 0a21daed5b6251edd8136bc014d073ab734a2a0a..9e4f27a6cb5afad0034f1636a12a2b775cb36663 100644 (file)
@@ -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), \
index 6c8d39cb566e32ea4ac14c818f3bd16962823097..828b34445203fc76138236cf8266f904cab28db4 100644 (file)
@@ -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,
index 2c74038da459ac039e0f1490be8e034e8bccda70..14909fc5d767f42d6039a2c58398e38ad58c680e 100644 (file)
@@ -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,
index fdced547ad5961ff722cfb438c0e33de9f5fabb2..c381c8e396fcc0e43b5a1b2a5ebd0c9e80ad732f 100644 (file)
@@ -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,
index afa3ce7d3e729a1ad1485d129aa1d26646292f74..8ad92707e45f23b890203d5c5468d47473acf636 100644 (file)
@@ -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);
 }
 
index c391a49aaaffb22fe1b02693368a447bbdc39dfd..b4cf2f699a21024b727aabcb5a265fb0d613e817 100644 (file)
@@ -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,
 };
 
index 43b0f2f08df2f7536d2f09e4f37984dde090e474..9cdf9d5050aca80858d3dc9dfcea416d91912b97 100644 (file)
@@ -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 @@ static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider,
        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 @@ static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider,
 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;
                        }
 
index 39eab69fe51a8a76791029ae718c575f16843630..44a5a535ca6334ebe17acf74ca38fea45ab86708 100644 (file)
@@ -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);
index d6feafe8bd6cea9ff9d61b0416f7c5d7858a044a..1629da9b414195c5159ee96449f5e5a22dec39c6 100644 (file)
@@ -118,6 +118,7 @@ struct meson_clk_mpll {
        struct parm sdm_en;
        struct parm n2;
        struct parm en;
+       struct parm ssen;
        spinlock_t *lock;
 };
 
index a897ea45327c985b189e9c5e81ac40028a682d7d..a7ea5f3da89d5357c2332f8a7fe4afa609cb9997 100644 (file)
@@ -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",
index bb3f1de876b1a8cd6bd5f191c6f2ff0737751aa7..6ec512ad259805c34b57be3ee96eddef149599ee 100644 (file)
@@ -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",
index 0748a0b333c54c4a4a4b888ddd9e83a25d4323f7..9a6476aa7d818b3ad3ec84c9e68abccf21f04daf 100644 (file)
@@ -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 = {
index 5372bf8be5e6fb8b0a43185279d33cc1cc30bd3b..31d7ffda9aab0c826627c14e3f51808d4639a6b4 100644 (file)
@@ -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),
        }
 };
 
index f99abc1106f0cb725ff7c63e9bc84b75596a4e75..08ef69945ffbf425efa001d48c6c9b5b0f4333eb 100644 (file)
@@ -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);
index f6e7491c873cd8767b92c0ba0e1222052e1bdc4c..d509b500a7b5f8565514352a0313cb4704976042 100644 (file)
@@ -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;
index b7fb8b7c980dc5d2eb2001e4790910cb5b399514..0566455f233ed3cd663506321f08f7ae546862be 100644 (file)
@@ -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();
 }
index 37b0698b7193e60be4107a8be107285e55c65877..42896a67aeae38325cbda2acb7ca655c1b43915c 100644 (file)
@@ -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
index 193204dfbf3a084f7540621fd377b98f2cb7e01a..4b75084fabad23e29b81048d8d93f38888aea0ec 100644 (file)
@@ -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
index ef04c974831732b0c27977be838bbc10e2a9fd41..bf7ac621c591dcad6737c42edb06d9392c27c8f9 100644 (file)
@@ -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;
index ae44a464cd2d20509e435c4b0b7a34e394abbc14..9ccefb9b7232ef68501c04db31aa7ac3ee983525 100644 (file)
@@ -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";
 
index e7f87ac126858519a0477c1254dc9e02424146a9..1fabd4aee81b75cd9e52785e6d09bb82dad58812 100644 (file)
@@ -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;
 
index 8527a5899a2f7b6a3245a4a52ca4c0283b2f4666..3f819399cd95519a9956ed1d3ecba76fa2aa62b4 100644 (file)
@@ -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;
 }
 
index fdcd9769ffded4eb4885bf20735e4fd60ca761e8..688b051750bd7cc615849491605bc0ecf50d9101 100644 (file)
@@ -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__ */
index 12943d19bfc43ea17e6f2f92419c5a52ffa35f44..e9f3b3e4bbf45805d5288ad0d3ee03243c2a1af0 100644 (file)
@@ -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);
 
index 9f2a0b4fd8012c05b79a561ee4c2711e64c17fa5..8d8c852ba8f209c5118987aa2dbb98cf3290d213 100644 (file)
@@ -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);
index ce9e563e6e1d47715a776405c3b86b283900a283..938eb4868f7f78c7264cae58b15a0dcc0565d5c4 100644 (file)
@@ -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);
index 57da14c15987fc019d1786ec0a4b0bd65077cf99..9a302799040e4529bc5d08ce7c17343421ea19b6 100644 (file)
@@ -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);
index 393817e849ed2a662e8696867bb1297dad9c5397..dec3a815455d6712864cc75e18c6f8210cebe06b 100644 (file)
@@ -195,8 +195,7 @@ reservation_object_add_shared_replace(struct reservation_object *obj,
        if (old)
                kfree_rcu(old, rcu);
 
-       if (old_fence)
-               dma_fence_put(old_fence);
+       dma_fence_put(old_fence);
 }
 
 /**
@@ -258,11 +257,70 @@ 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
@@ -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 @@ long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
                }
        }
 
-       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)) {
index 69c5ff36e2f9e4f57ab72b87da2634332c97fe55..38cc7389a6c172c4f22ac89ec3694220a2083dc1 100644 (file)
@@ -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;
index 82a6e7f6d37f4c15cab1f63638d78ce39185021f..c4c8ecb24aa9b4e9eb233847dd9a7bbfa1cb7fe4 100644 (file)
@@ -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;
 }
 
index 26fe8b9907b38aac09d786997bd02a4e8be1706a..d615a89f774c249e2b779a82436561822e863bbc 100644 (file)
@@ -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>
 
  * 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
index 545e2c5c4815d411d485c1f63a3cb88992036d37..66fb40d0ebdbbec521499cd58cf2e1d55c195878 100644 (file)
@@ -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,
index a485864cb5125cd5612656e8064d62cc9408249a..06432d84cbf8c58215fdd7e1fcd07ab85926ad91 100644 (file)
@@ -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");
index f235eae04c16ed1096689329c0462df74e05a36d..461d6fc3688b61128f280a84c8ed3e1073488ab0 100644 (file)
@@ -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.
index fb8d304cfa171fcb3a5372f413a54783a7e52b96..0ecd2369c2cad0daa5e08696ab85b91af5235a26 100644 (file)
@@ -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;
index 6313c50bb91be057a9de80a2d22277270518e648..a121c8f1061005380464d4cf96ac68a4905b293c 100644 (file)
@@ -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)
index 3abea3f0b307e143848686dd935ee0745a414eec..92692251ade1a13b7c2df99f97598584c3c05081 100644 (file)
@@ -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;
index 88529d3c06c9af4d6e4a69ea71557939ba0ff48e..506c6a67c5fcb951154faad9c4b73cb7b8c45ac3 100644 (file)
@@ -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);
                        }
 
index 9568708a550b55b79824784270f98b3260a6f70f..cd003b74512f692e2ec67eca68bd1f4d80db0e39 100644 (file)
@@ -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 {
index 24a066e1841cc76104ff9b7ada90f50c865c1aa8..a8acc197dec37760f6e6b6c44eec0abda5e97e0c 100644 (file)
@@ -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
index faea6349228fe4a566464eaa467e1a77eaf5fd4d..658bac0cdc5e96094499a13c2183de9f56e6f12f 100644 (file)
@@ -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 \
index ff7bf1a9f96780408027d4273101666df7335522..12e71bbfd2228ebeaccd9188142c276653edb938 100644 (file)
 
 #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);
@@ -531,49 +468,6 @@ int amdgpu_mode_dumb_mmap(struct drm_file *filp,
 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
  */
@@ -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);
index 06879d1dcabd320045560a35edb8f606a35df46a..a52795d9b45852a371fed81a8f17a51d63bab120 100644 (file)
@@ -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;
index ef79551b4cb7acde9467cdb7bcefcf64a3561f39..57afad79f55d086b673cd6c61c688d532620a033 100644 (file)
 #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 @@ static int amdgpu_atif_get_sbios_requests(acpi_handle handle,
  * 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;
index 5f8ada1d872bcc022ed88920b33c7f14eea0486b..c7bcf5207d798671d49dcb9efd0ba683952355e6 100644 (file)
@@ -27,7 +27,6 @@
 #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**);
 
@@ -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);
index 73f83a10ae1485dac5adcfe66358757549ff05d4..b8802a561cbd1ed014965d984fc2f7299ec7b91a 100644 (file)
@@ -39,8 +39,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,
index 1e8e1123ddf416f18176cbc6e82fa791b3df9fb5..ce443586a0c71c13bd36472558473c0beae9b081 100644 (file)
@@ -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
index 38d0fe32e5cd4218fad2244597930c90465cc7e9..b0d5d1d7fdba15d6674fdfbc744c90592cee8c8c 100644 (file)
@@ -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,
index 4bdda56fcceea36b8229d74ac3b76fe706919a77..f9ffe8ef0cd60a85ae4180f66727f791e8679622 100644 (file)
@@ -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;
+}
index a2c3ebe22c713aeacff5036d431ffc1e157f5f7e..288b97e543478b48f2298cf3e442b03f99a91d69 100644 (file)
 
 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
index 1beae5b930d0e10d407501708a0585e56001181e..63ec1e1bb6aa17dff2ad786f2aae9600d607a38a 100644 (file)
@@ -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;
        }
index 365e735f664744042cec72b939a06078444a69ae..c21adf60a7f200ba6a4faaa32c163157d00da9ce 100644 (file)
@@ -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;
 }
index f621ee115c98d4e5d5a4faa0d845864dc65a0b8c..59089e027f4d8ac386f1174fe47eea5622ec182d 100644 (file)
@@ -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;
index c0a806280257c80954930c3744d7cd65e6b6de5f..fd435a96481c2f1c019bd4d2303ebbb9b590adad 100644 (file)
@@ -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 = {
index 5599c01b265d40c105b59b5ca0f3f14c2efdf40e..15d4a28d73bb53d36d446e88e2cf0e8473376b53 100644 (file)
@@ -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;
                }
        }
index 4a8fc15467cf8c40ed268f190a01acd4f506fed0..1a459ac63df453b2cab796b8ed28fd4afff59522 100644 (file)
@@ -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;
@@ -598,22 +560,6 @@ void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb)
                __clear_bit(wb, adev->wb.used);
 }
 
-/**
- * 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
@@ -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 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
                }
        } 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 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
        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;
 }
 
index cdf2ab20166a2f1b86beb7a2d84e7d68cb2b5d6c..6ad243293a78b163f0c0269ad2eba78623a60811 100644 (file)
@@ -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);
        }
 
index b59f37c83fa633ac057251ae4a57e8b2e9dded7e..e39ec981b11c85d11ca6250caf2c4ab7de35fd97 100644 (file)
  * - 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,
index c0d8c6ff6380e8a69de8faf58d28963dde29c8de..9afa9c097e1f1012d93fa2fcd89e9fb5c8d3cffd 100644 (file)
@@ -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 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
 
        }
        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,
 };
 
index a57abc1a25fb5fbe6da96410316cc85342363b44..94c1e2e8e34ca659717af06aa944c8e2675ba2a7 100644 (file)
 /*
  * 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;
                }
@@ -262,6 +275,41 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
        return 0;
 }
 
+/**
+ * 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
  *
@@ -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 (file)
index 0000000..d4cce69
--- /dev/null
@@ -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
index 621f739103a6a30c9cf38801343ff5397a928d63..7171968f261e1a13094f3c94b2d649a382b2f6a0 100644 (file)
@@ -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 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
        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 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
        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)
index e26108aad3fe246bfd12d9e1417c91a353cef5e3..4f6c68fc1dd91a43813a2782bbc9cf3dbbf43ded 100644 (file)
@@ -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);
index f7d22c44034d43cce77ecd096c953e18aadc955d..9e05e257729f2e20dd91c4e81f6299e0800cc0e7 100644 (file)
@@ -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;
 }
@@ -80,6 +84,20 @@ static int amdgpu_gtt_mgr_fini(struct ttm_mem_type_manager *man)
        return 0;
 }
 
+/**
+ * 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
  *
@@ -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 = {
index f774b3f497d28735829d9b6407cd1832e9174945..659997bfff303b789f9f5fa6ae8ec17b0a02ae5c 100644 (file)
@@ -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;
index 62da6c5c6095a03ca0bc0f2c93f783212abd1e94..4bdd851f56d081310614f27dce5093255ecf7dfd 100644 (file)
@@ -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;
index 3d641e10e6b65c728ddda00be6027d7fe42cc461..4510627ae83e9b57e19dccfe19f260da00f918f2 100644 (file)
@@ -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;
 }
index b0b23101d1c870ddeefc89b15818cd5b13ea13a7..e16229000a983e8cc068a70af7ec32074be06c30 100644 (file)
@@ -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);
        }
 
index 38f739fb727bd2da4c81ad198ae18e46bee8e040..6558a3ed57a7f6a1127f81aa0e1b5a861aa21b8d 100644 (file)
@@ -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;
index 43a9d3aec6c426e20bbff9bbb30084fe3cc523b2..2af2678ddaf6254948d529f647f87bb1ef74a959 100644 (file)
@@ -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;
index 8ee69652be8ceea145129cefb46ab46920744a74..e7e899190befb9f74edd45a82eeefbed7529fde5 100644 (file)
 #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,19 +226,51 @@ 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
  *
@@ -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 @@ int amdgpu_bo_restore_from_shadow(struct amdgpu_device *adev,
 
 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;
index 382485115b0641b059602d21fa92be33281ac8de..a288fa6d72c8026f60a62625f4bf421cc6d3a74e 100644 (file)
 
 #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);
index c19c4d138751df410be7f6a9c44fc462eced2dd4..f21a7716b90e67b7cdd184046a107153bc49d19a 100644 (file)
@@ -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);
index 6bdc866570ab8d67575ac3734d1f67573978df79..5b3f92891f899d8b6f00da5ade675245beba6571 100644 (file)
@@ -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);
index 4083be61b328fb56f1832fa95496074e8c84cef7..8c2204c7b3847c3ce18042b48d70516155b843e5 100644 (file)
@@ -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;
 }
 
@@ -351,6 +340,13 @@ static int psp_load_fw(struct amdgpu_device *adev)
                                      &psp->fence_buf_bo,
                                      &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;
 
@@ -358,7 +354,7 @@ static int psp_load_fw(struct amdgpu_device *adev)
 
        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;
index 1a1c8b469f9385758c188c825597cf67b6121c2d..538fa9dbfb21200094df54f07ad598f77f323fc6 100644 (file)
@@ -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 {
index 75165e07b1cd8807831d4dd602a9c1a2037d8ad6..6c5646b48d1a5fce145df441ce66098ea62e95d8 100644 (file)
@@ -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,
index bc8dec992f73d5da7a4d8742fd3d7bc110cd0312..322d25299a00cf364fba3b8ad4343ffa22b3efb5 100644 (file)
@@ -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
index 5ca75a456ad2ad94e81773fc209e1977dc18aa9f..3144400435b79ca3c3e58bf18abba5462efe0bed 100644 (file)
@@ -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;
index a6899180b265721831837282e6c66d12a8bccf48..c586f44312f9772fb93f8b1442827c842d610594 100644 (file)
@@ -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;
        }
 
index 15510dadde018d87d455b371af32e8d349c3a6e1..ed8c3739015be481cfd7072b712b3c8ee562d2e4 100644 (file)
@@ -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:
index 8601904e670ae7cf094a341c19abb76404fb3ec6..1c88bd5e29adc161719a93bc07de4485c4fecce3 100644 (file)
 #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)
 );
index c9b131b13ef74de91a85afa562d2b2446c59a1bd..8b2c294f6f7999371a045aa985dd409ef12dd2d5 100644 (file)
 #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 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo,
                }
        }
 
+       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 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **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 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring,
 }
 
 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 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
 
 #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
index 6bdede8ff12b4c37f1e679de83f7afd54014cc0b..f22a4758719da1121bd9368b857cb14fa42bb958 100644 (file)
@@ -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
index 4f50eeb6585534b54a5408360611798ccd2e447f..36c763310df5f6402fc3d28be2f2ab5b85245f9f 100644 (file)
@@ -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) {
index 2ca09f111f08d02838cea38e3d7148752c6ffc0b..e19928dae8e3fa92d48c3047a1bda98107e6b595 100644 (file)
@@ -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;
 
index b692ad4022521a5244f23e846430898a3a3bd9d4..c855366521abc527d6ed9188ae664892aa94d8ad 100644 (file)
@@ -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) {
index 09190fadd2288c011c4cf82e67d744825334450e..041e0121590c96bb34e17444d32ec0186efeb539 100644 (file)
@@ -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 (file)
index 0000000..45ac918
--- /dev/null
@@ -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 (file)
index 0000000..2a3278e
--- /dev/null
@@ -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__ */
index 8a081e162d13cb6f6cc6b674fd82cd52180cb40c..ab05121b9272b9f11bf7ab52aa0ca085149aeeca 100644 (file)
@@ -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;
 }
index 9e1062edb76eb0649a0a97291c320222fd21bfa9..afcfb8bcfb65edda5e37def8ace207e0ded84ae1 100644 (file)
@@ -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);
index 5795f81369f0fc6e68f0659c400a700091713db8..6b1343e5541d3f2a2c0415cd33593c6c1f188a08 100644 (file)
@@ -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;
index 936f158bc5ec651fae06acc5e9a62a0ce0763355..ba6691b58ee72f4e785bcf83a643065a3e8b89e0 100644 (file)
@@ -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);
index a2c59a08b2bd69919b23989feddff71a88855617..26e90062797173d772b4c71c2f3229ebb1bfbbbc 100644 (file)
@@ -28,6 +28,8 @@
 struct amdgpu_vram_mgr {
        struct drm_mm mm;
        spinlock_t lock;
+       atomic64_t usage;
+       atomic64_t vis_usage;
 };
 
 /**
@@ -78,6 +80,27 @@ static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man)
        return 0;
 }
 
+/**
+ * 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
  *
@@ -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 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
 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 = {
index 37a499ab30eb02fc0506727b8004c71dc640db58..567c4a5cf90cc2ce927c151c2665d4d2ab5a8395 100644 (file)
@@ -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)
index c216e16826c99df35e1ab22c9c14a97144fff9ad..f508f4d01e4a9000f633c85e290964098e8c1b86 100644 (file)
@@ -341,6 +341,63 @@ static void cik_sdma_rlc_stop(struct amdgpu_device *adev)
        /* XXX todo */
 }
 
+/**
+ * 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
  *
@@ -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;
index 18fd01f3e4b245d7d9f4cf24a97daa20beeaee66..003a131bad474db5d28584735c0e399b1def20d6 100644 (file)
@@ -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[] =
 {
index 9f78c03a2e3152eb9244d4b733fbd194c6227299..4e519dc4291616912ed0622698cb8720fb89aa40 100644 (file)
@@ -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 @@ static int dce_v10_0_crtc_cursor_set2(struct drm_crtc *crtc,
                        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)
index 4bcf01dc567a183b462a4333727f2fa90c6e924d..11edc75edaa99603c40d6986caf3fa8a5b94ff25 100644 (file)
@@ -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 @@ static int dce_v11_0_crtc_cursor_set2(struct drm_crtc *crtc,
                        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)
index fd134a4629d7a4ee5f3d8559049f1bfaddd8bb48..a51e35f824a1a3211a0a6ccc5029dec78cdccff5 100644 (file)
@@ -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 @@ static int dce_v6_0_crtc_cursor_set2(struct drm_crtc *crtc,
                        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)
index a9e8695546272638e0922ba20853c241b0d7ae3b..9cf14b8b2db9b594ccd36085e29632ca511f4137 100644 (file)
@@ -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 @@ static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc,
                        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)
index 90bb08309a533cd2bad92de91ac9b3cc3bc3db7f..b9ee9073cb0dc2df7a0f28790282aa5c68a969fa 100644 (file)
@@ -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;
 }
 
index 5173ca1fd159d19971ace8cf87bafb8749a75bbf..d228f5a990449f0b2c28314c972db2664c6bc1cd 100644 (file)
@@ -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;
index 37b45e4403d175229855c167218ceeeaa627180b..53a4af7596c1415321475719f3e759da58fc7446 100644 (file)
@@ -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;
@@ -1939,7 +1939,7 @@ static void gfx_v7_0_gpu_init(struct amdgpu_device *adev)
        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;
                }
index aa5a50f5eac817cd2a51a157a3af6a44fa51f587..0710b0b2e4b64523c654e0715882328c7e423433 100644 (file)
@@ -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);
+               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) {
-                       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);
-               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);
-       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);
+       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);
-               gfx_v8_0_mec_fini(adev);
+               dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
                return r;
        }
 
@@ -4564,7 +4469,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;
                }
index 3a0b69b09ed62ed9dd18a8b4dbfad595b7d30030..69182eeca264e723d2ae8a7bce6567258600732d 100644 (file)
@@ -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,
index 56ef652a575dd3d36d60c48c13a049c620e350ee..fa5a3fbaf6aba2f873bc6014c8977299ab99561c 100644 (file)
@@ -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);
index a42f483767e75510d02d834fdc724c3b83baa6ec..4f2788b61a08bd4db43d52d14ec9ab6e771b0e37 100644 (file)
@@ -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);
index d2dbb085f4802249fcaceaed5f8bab266c6ca6ed..206e29cad7533579f460f3964fc5c07326d50bf1 100644 (file)
@@ -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
index d0214d942bfc48f2044d6ef26f8671ee5d3b6f39..12b0c4cd7a5af801b32dd29067cbba3ee88b2e08 100644 (file)
@@ -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);
        }
 
index 7e9ea53edf8bfe65ef5667a4a6a8002c9e0ef0cf..e42c1ad3af5e06c33a59939bc9abab48b2d9c406 100644 (file)
@@ -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);
        }
 
index cc9f88057cd5e745cfdcc36d16e716fcc2c168ac..7ca2dae8237a0952da81414d5e14b53fa06e566e 100644 (file)
@@ -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;
 }
 
index 175ba5f9691c4a5188442d012430e4212bbaee20..2769c2b3b56e8f5ff8e8bbfa0f2cefe86569fe1f 100644 (file)
 #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;
index 9804318f3488cf67eaf357756dd239425fc27457..4395a4f12149c37db23404fa89077d783aa88c06 100644 (file)
@@ -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
index 57bb940c0ecd8300b7f646cc10865205edf427a1..5d38229baf6981d6a3830e04de5e87ba981ff97a 100644 (file)
@@ -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
index bde3ca3c21c190fb526a3f0fe7a1706122a71f59..2812d88a8bdd480371b9ad93ced23322e581e9c2 100644 (file)
@@ -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,
 };
index 9aefc44d2c34474296c17d83dc7a7d9100a6171f..1e91b9a1c59150f6bc86101cb0339bdb3a0abf5a 100644 (file)
@@ -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 {
index 171a658135b50795d3420eb6f50bd195fb79d35c..c25a831f94ecf65b8a8a6bd6653b5d188ebb42c9 100644 (file)
@@ -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. */
 };
index 2db741131bc6fac7efc035dbbe962b7c404f6e2e..c791d73d2d542cc368def9b227ebff3c1a6e8e62 100644 (file)
@@ -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 */
index 1e272f785def74e40b3019b3aeb1ef69a957ed0d..045988b18bc3361fff6b52f6e38f499d23c9090c 100644 (file)
@@ -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);
+}
index f6f8bc0455189bb8766f90cf55cdcdff18526805..686e4b4d296a7bb02d18a540b0a80afdc1b4ad4f 100644 (file)
@@ -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
index aa04632523fa8e4457d0674804d8eef98e6faf10..11b70d601922e170efe6b5de950953df7a5eacdc 100644 (file)
@@ -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)
index 2258323a3c2698a18b6c093bd5143eff98f9c963..f7cf994b1da2871a4437655f8306cf9bcb284468 100644 (file)
@@ -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,
index 2022b7b7151e9c374be77189c7eb4bbae20546db..e76cde2f01f9521f5a13509c17687cb532c08b9f 100644 (file)
 
 #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,
index c98d77d0c8f84a064fa16d82ed1f57fedb9723be..2a535a4b8d5b3263dde9158f09be3c8d5547ce12 100644 (file)
@@ -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;
 }
 
index 1d766ae98dc8d90c85cead54b966bef91c000f87..b1de44f2282490189f0c4024d3d75711512547fe 100644 (file)
@@ -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);
        }
 }
index 4a65697ccc942ec1b2b7393acbcf360274bb8e13..fd7c72aaafa6248a566996140128a1fc22569279 100644 (file)
@@ -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++));
 
index f45fb0f022b3c6480b08afa545f4e3f4f9381610..8284d5dbfc30c5227088de36d269459e3c3511b8 100644 (file)
@@ -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,
index a7ad8390981c7cfb38b9e530fe00d4c8d68f034c..d63873f3f57436cdda4a76ad542f4512a55b0b7b 100644 (file)
@@ -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:
index a7341d88a32024728866e728c689cd946c1c099d..f2c3a49f73a0051b74c602990d6e18ea64928eda 100644 (file)
@@ -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);
 
index e2d330eed952cade98142d943ce2ceafa3c5e461..7a8e4e28abb2a9bf3b68933f80c21596920c4781 100644 (file)
@@ -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 : \
index e79befd80eed98ff4d9ee702ba5d6945ca132f44..7f408f85fdb631ee7bccda52ec444a7ec87942f9 100644 (file)
 #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
index 987b958368acdb411f63f9a73edb71da97aa2a7b..23a85750edd6fba1c591709dbededb92e54dfec6 100644 (file)
@@ -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);
 }
 
 /**
index 1ecd6bb90c1f2b8372b160ce0b1fed8fa0263e28..11134d5f744335fcaaf9987b288d8127feb52ec8 100644 (file)
@@ -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;
 }
 
index 88187bfc5ea3fe1813ca0685cdc30d2c712f4df9..3f95f7cb4019468b1011e0483fa50192d0d45f6a 100644 (file)
@@ -226,10 +226,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;
index 955aa304ff486dadde10273d18faa770cf289306..42de22bbe14c89f472a2038ca28d15fc1130d117 100644 (file)
@@ -77,13 +77,6 @@ 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);
@@ -671,7 +664,7 @@ 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))) {
+               if (WARN_ON(i >= (sizeof(res.queue_mask)*8))) {
                        pr_err("Invalid queue enabled by amdgpu: %d\n", i);
                        break;
                }
index 66b9615bc3c17da85e09fe20ddc98d610b04ab92..faf820a06400061491d42b985edf79fb9e10b57d 100644 (file)
@@ -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);
index 0021a1c63356e8cee086dfc50c0dd5c09329abfa..837296db9628b98a37bdc7d2941aba759adcc405 100644 (file)
@@ -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;
+};
 
 /* 
   ***************************************************************************
index 0a94f749e3c0a24f5d9b98256f19336d73704a09..0214f63f52fc6a6ac14dd1500c4efdaf2e0fcf14 100644 (file)
@@ -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 */
index 91ef1484b3bb6c5f1280f1aa0e49c308b30179f9..36f376677a53322dce8e3e95cc66135457d6ea86 100644 (file)
@@ -63,9 +63,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;
 
index 0b74da3dca8b5d83e2af51347a4afb5b77e43a40..bc839ff0bdd0425218a729f4838dc073ebfe4d30 100644 (file)
@@ -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;
 }
 
index d025653c78235fabc68413a605475aed2fe3aa9f..9547f265a8bb86d11e1edd42637eda55adb6c8d3 100644 (file)
@@ -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;
 }
index 720d5006ff62842efbf46bdc47ea03bba6ad5bb1..c062844b15f3c076f3490e1f4a017340e91bc3b3 100644 (file)
@@ -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;
 }
index 81908b5cfd5f11f226df1b9c4054588802394701..8e6b1f0ddebc00769bee23d1b48162421a47d8b5 100644 (file)
@@ -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 {
index 4c7f430b36eba81ab13d76932bcabec2b5e50ff7..edc5fb6412d95be624dd3ef7903602c01b27c51d 100644 (file)
@@ -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,
index afb852295a1573d148fa6eaca387840f14033641..2472b50e54cfb67730176b47676c0ca1cc9f5163 100644 (file)
@@ -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;
index 1f01020ce3a92a34baa5b3d8257f974008143179..c2743233ba10ed8dd9b55338730fbff9722ae680 100644 (file)
@@ -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))
index d6f097f44b6cfe8587b64c16cfa6af4663c729e7..9d71a259d97d46fc8008e288f71605f3cb5e23ff 100644 (file)
@@ -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;
@@ -222,6 +237,8 @@ static int vega10_set_features_platform_caps(struct pp_hwmgr *hwmgr)
        /* assume disabled */
        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,
@@ -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;
 }
 
index 6e5c5b99593bcb8922546dc4c02983b88019d46b..676cd77358837ad9c604c93352808285049e13a9 100644 (file)
@@ -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);
index 3f72268e99bb812d780ba1b9b4f52b2211ee3445..e7fa67063cdcbf2b5257b7a86ce58f1c087341ef 100644 (file)
 #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)
 {
index 9ecaa27c0bb547e1c72707c4a562f19123b7ff76..b95771ab89cd19130f6ecd6d51025a3ef53b5340 100644 (file)
@@ -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_ */
 
index 1623644ea49acef8f8c4053b396fd26e8bd703f8..e343df1903754fc19e0f2ac082f8b8369c5f1201 100644 (file)
@@ -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)
index e7ab8eb8a0cfae1c9b60c582a4cbee4b5b49e567..d44243441d284a80bc5abe398bf1bb9d0f3f875c 100644 (file)
@@ -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;
index a1ebe1014492058e07658b512ec4ac3bc6db2c1a..a4c8b09b6f1464eb92950dfbe12c838fa5bdf34f 100644 (file)
@@ -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 */
index 47e57bd2c36f9b747c4a7632a1d488efcd13e40e..91b0105e82403c448cee8a6c303828f392e87eb8 100644 (file)
@@ -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 {
index f3f9ebb631a5f3383142956e1793ebd8d0936500..822cd8b5bf90d1982c860e42a44e440b9dc69c5f 100644 (file)
                }                               \
        } while (0)
 
+#define PP_ASSERT(cond, msg)   \
+       do {                                    \
+               if (!(cond)) {                  \
+                       pr_warn("%s\n", msg);   \
+               }                               \
+       } while (0)
 
 #define PP_DBG_LOG(fmt, ...) \
        do { \
index 227d999b6bd11ca5be538a87cfaf471f6d81a871..a511611ec7e0c0190fde321ba9e6cbc9e236bf9c 100644 (file)
@@ -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;
 }
index e0e106f1b23a0de38a8222dc9d220afb04d549e2..901c960cfe21999787ea9d1b46dee00e5872c2da 100644 (file)
 #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;
index 9ef2490c7c2e009f9a613abbc953b463baba1af7..550ed675027ad79bebb5261a434beeeae8b316ae 100644 (file)
@@ -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
 #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           )
index 532186b6f941f4cc1e3256f7ad6ad392ced4e020..f6d6c61f796a463abfd8dfb2be0129c6c2579740 100644 (file)
@@ -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 */
index 976e942ec69433f10c32dd29aee4617974a349c3..5d61cc9d45544ad817702d3c777f10d31557eeaf 100644 (file)
@@ -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
index b4af9e85dfa532e7db728253cbd00a2de9a1c3b3..cb070ebc7de196f185415c6c02afd27c66e24a6d 100644 (file)
@@ -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
 
index 6a320b27aefd17ce96cee015d8e2db82b1dacd91..8712f093d6d90afcc3b64274c71424d55ec2af61 100644 (file)
@@ -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);
index 0e9e1f2d7238da3741324fd478630f6a700344c7..d9c72d992e302777521a7b853f4d75e7725e96e6 100644 (file)
@@ -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
 
index a1cb78552cf69372997cbb1c1cb36e92d825095b..6ae948fc524f72e1f916f4e256fcd992b1d92690 100644 (file)
@@ -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,
 };
index adcbdfb209be477dcffd12333ac52b81fffe6a1e..175bf9f8ef9cd9ba25e9ed86db56dc71e490b2f4 100644 (file)
 #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
 
index f68e759e8be287956609314dfd4134739660ca56..99a00bd39256586b501414fcca02b13d198c8c1e 100644 (file)
@@ -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)
index 9616cedc139cebe35557adb324bb39c8087d5c4d..75f43dadc56ba95838ca0d33ed6a71573d47ca50 100644 (file)
@@ -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,
 };
index 49ebf1d5a53c9a0194eead44ccfd605414a385a8..5e19c24b0561fd0d3ba082bf5f05a4820a4d4926 100644 (file)
 
 #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];
 };
 
 
index 35ac276814150a4fcf91e798a4de7283acf01855..76347ff6d6554b447e8e066c7ac81ef85562d4bc 100644 (file)
@@ -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;
 }
 
index 919be435b49c890368ca0f3dc6906fb3f90ddf2f..ee5e32d2921ed8576a78f6ba6b389461503d9ee2 100644 (file)
@@ -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;
 };
 
 
index bcc61ffd13cb1913a61e8ce82a5855358181525d..3bdf6478de7fac4ef77f88030458f38ffb5fe269 100644 (file)
@@ -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;
+}
index 269678443862d8e446a6256b6bb91c3d8789dc8d..408514c965a015cd1ea025957eb21370d5209960 100644 (file)
@@ -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;
index dbd4fd3a810b71223f1c485dc051515d5da59654..8bd38102b58e25c970a28d2844d0e345c1a06292 100644 (file)
@@ -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)
 );
 
index ad9a95916f1f8c06ced45d4a45634042cd697316..16903dc7fe0dc465d7d6f93f138efeb337ca4c42 100644 (file)
@@ -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);
index 3e43a5d4fb09e0c9233f02b6bd1545e5abc190cc..289eda54e5aa83b23216af852445f44f70893b80 100644 (file)
@@ -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)
index d67b6f15e8b8a03f902d02861e51cb696eb1e9b5..72b22b805412b2cb19d8d90e85904be737ecf335 100644 (file)
@@ -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);
index d3da87fbd85a57ff199881fcb12b8afd93434025..f9bda7b0d2ec275996979e70822fc56b5279c53a 100644 (file)
@@ -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 @@ static int hdlcd_drm_bind(struct device *dev)
        }
 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);
index 4bb38a21efecb6e0741a626f986515570ed3b1f3..3615d18a7ddf3a5cc49f7d09d68eec35fccc6e3c 100644 (file)
@@ -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)
index 01b13d2199179e6ec83c5e91796f42fe905c713d..1a57cc28955e7fe7cbc595c718ba62570f476c0c 100644 (file)
@@ -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,
index 600fa7bd7f5201b451069dee8f21e9871cae70e3..94e7e3fa3408cf163fda7f81b40e76ca73ac4c96 100644 (file)
@@ -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;
 
index 4fe19fde84f9624dbae3bdbc062e282401f617c7..2a4d163ac76f7be9e0291d5d1d51a31798688e40 100644 (file)
@@ -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,
index 7e8906d3ae2677bd8f644f1f0e3be8b1815719f0..bab11f48357591325d5bab2f80de34981f4d5482 100644 (file)
@@ -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,
index e618fab7f519d6b8602f65c1bb09de3f1186d814..0b3227c039d768ada13307e99892ff1b9f78ff55 100644 (file)
@@ -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;
                }
index 602dfead8eefa6b6bc70e3290fa9671efc3eada1..29c7d047b1525d3323d87d28d7615560fc485df1 100644 (file)
@@ -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,
 };
 
index e9a29df4b4438382cd9d6de5c814738649f1c6fb..edc44910d79fc7c65bce893d31b2caf9ce1d34e4 100644 (file)
@@ -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);
index 76f07f38b941f5e8ea3ad9255e8870b293bfab84..749646ae365fc36e7ab64df83228a9f04a472fc7 100644 (file)
@@ -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;
+}
index fd7c9eec92e4d75eba8aeb935d6dbcd2e122c1f7..69dab82a37714853b5dfdb74dbe479f7d6c10fb1 100644 (file)
@@ -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);
index 8880f0b62e9c2832845d7df2f40e0e77817a9f91..e6c4cd3dc50ec7540d65efd61fea71ddb249ecdd 100644 (file)
@@ -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
index 4ad4acd0ccab8528d52be211f321f7f589443dc1..0cd827e11fa20d8af7f038cecb8ea12465014523 100644 (file)
@@ -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 @@ static int astfb_create(struct drm_fb_helper *helper,
        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);
index 262c2c0e43b4b162fae7530f88b143814abe8949..dac355812adcbdcea7d68a40ff44bca90b0e0dcf 100644 (file)
@@ -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;
 
index aaef0a652f10fdf145b272dc4f28782abfb8701a..6f3849ec0c1d0eb3fabc071c132b4ac7717f77bd 100644 (file)
@@ -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;
 }
 
index 58084985e6cfe2b0cf9d13d1d43b4f2407e543a6..696a15dc2f3f9965e775ea3579383502edff4b57 100644 (file)
@@ -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)
index 53489859997b4991e4feafbac9a7360b9050a5ca..d73281095facabbaf7b54d6f309123f8b044821d 100644 (file)
@@ -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;
index 30dbffdb45a357bafb4f612d4887413933cdb317..74d66e11f68876c622e5e516aae3f266a2a037fd 100644 (file)
@@ -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",
index b0596a84c1b881dd1b6d2f46a595c54a5dbc7807..4237b0446721ef925a6f3663823ea937c8cbfe47 100644 (file)
 #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)
 #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)
index 1124200bb280d8f58eb59e5370aa91b7916bb134..703c2d13603fc8f6e8cbae7fb7e1ac7c8dafda8a 100644 (file)
@@ -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;
 
index aa342515ddf43c86f00b9082812305d96eef65e3..7b20318483e4d37e8a91489a721db2a60433f703 100644 (file)
@@ -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);
index c38deffa14de24054711ab96d28fbe30a17c8f35..14eb8d0d5a00a5f679219e7b101633678421af1b 100644 (file)
@@ -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);
index f75ab627811349beb55180a2c651e1c666da08a7..b2431aee788795cfa078dbf4b5515c75dbe1961c 100644 (file)
@@ -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);
 
index 9006578b9789b0dc248184b939289160929c274d..9385eb0b1ee40ca5441eb3b1876e04265d394bad 100644 (file)
@@ -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))
index 4c758ed51939d5a4fdacb9cacb93bab4f0953bb8..5dd3f1cd074a1d36f17022af23c7a23638eaa41e 100644 (file)
@@ -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,
index 831a606c4706815999a938966ae561ec10497103..de5e7dee7ad60f808f7d0380d0e44e827745204f 100644 (file)
@@ -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)
index 11f11086a68fd97d62b8d7febd1ca017de621ce9..7ccadba7c98cd30c3c81e3e0dc183cd050ab6d63 100644 (file)
@@ -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,
index 4f64e717e01be4a4dd46bc2c3310f8615b71d2e6..d64a3283822ae7a877175aad01305d32b6d49bf5 100644 (file)
@@ -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);
 
index 67fe19e5a9c6e65777c528e9a333e2c2247233fd..e0cca19b404406d4a22a4a40d871e8a8bbd5b2e0 100644 (file)
@@ -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);
index 6f22f9fec9bfed145e6fd781c715287c97f1d682..81198f5e9afacf91bf2301652a2ac4671030f7cf 100644 (file)
@@ -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);
 
index 9b87067c022cd8f541d94310dd5266ab84cf7c9d..b1ab4ab09532b49901bdd7126f951c40a10424d5 100644 (file)
@@ -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);
 
index 53e78d092d18e3b9085d0784772639f8fa01f21c..3cc53b44186e2d3e3eae3fb7ad6bf0379254b319 100644 (file)
@@ -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
index 17aa7a65b57e677e06d4b20dfeb23adb23ec0941..5dad97d920be4842da57d90e78f1f79e5f2f8470 100644 (file)
@@ -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
index 8f2d1379c8809b8b8c428fb521c58bf1282d7c52..cf3f0caf9c632fe47dd5f48999031100e12cf68c 100644 (file)
@@ -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 (file)
index 0000000..6c32351
--- /dev/null
@@ -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 (file)
index 0000000..cf4dc12
--- /dev/null
@@ -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
index b2cf59f54c889e528b1a7c7bc6371c899594bd20..3b7e5c59a5e9941df113ff53f4c98664232b5054 100644 (file)
@@ -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
index ead11242c4b91e2fd0f2c2da7a68ff0e72025b3c..bf14214fa4640279fa46b655333198ed5aa1446e 100644 (file)
 
 #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 @@ __dw_hdmi_probe(struct platform_device *pdev,
                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;
 }
index c59f87e1483eadc7a8ecd4dcee4345514fed3668..9d90eb9c46e5910165c6e36b39c62e5ce9150c2e 100644 (file)
 #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 (file)
index 0000000..63c7a01
--- /dev/null
@@ -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");
index 5c26488e7a2d7a0320ddf321375b8ff4c200185f..8571cfd877c520b2e09530f1070a58dae8a4baf9 100644 (file)
@@ -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);
 
index eee4efda829ecb91ace06df720fa670fe584a53a..acb857030951a0eff0682fce7b5d38d80ba6edb1 100644 (file)
@@ -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:
index d893ea21a359226400d56920d663db3d2c4c1083..69c4e352dd784bbc33921746af2276c0f4e6899f 100644 (file)
@@ -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);
index 8690352d96f7b49c169fac7760e1fea1f36acbd1..be2d7e4880621a075b4d0f900d14cc204e86c262 100644 (file)
@@ -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,
index 7fa58eeadc9d05d743de30d6033985224b245ea3..32fbfba2c623a7ddbb43d68534316b5a8485d950 100644 (file)
@@ -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,
 };
 
index e7fc95f63dcaacdbfd9203e3bc883f18e83920e7..b5f52854395627e1e6ac0dc0807fcb0b23d7cb8b 100644 (file)
@@ -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;
 }
index 53f6f0f84206f03143522d345627c7782164c6fb..a4c4a465b38523e69abcc92e70578bc6f2e1db49 100644 (file)
  * 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)
index c0f336d23f9ccab1d375eda63f8381d62ccf0f00..1b755439f5918b7b61c43577b86a5f7fe4aea955 100644 (file)
@@ -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
@@ -990,12 +963,45 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
                plane->funcs->atomic_print_state(p, state);
 }
 
+/**
+ * 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)
@@ -1579,38 +1587,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 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
                                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;
index 86d3093c6c9b6b24b3576c296b717a0ae9afec1f..1bc32cd74d78e61126d0b67a4a1c3e477b2582d9 100644 (file)
@@ -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,
@@ -1240,28 +1244,55 @@ 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;
@@ -1310,6 +1370,114 @@ static void commit_work(struct work_struct *work)
        commit_tail(state);
 }
 
+/**
+ * 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
@@ -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);
 
@@ -2556,13 +2746,13 @@ 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;
@@ -2763,177 +2953,11 @@ int drm_atomic_helper_resume(struct drm_device *dev,
 }
 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 +3051,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;
@@ -3064,85 +3087,6 @@ int drm_atomic_helper_page_flip_target(
 }
 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
@@ -3612,12 +3556,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 +3592,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 +3605,18 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
        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);
index 3eda500fc005ea485b4c5ed52bc19bead9a23814..fe0982708e9528cdaaaca6cd1e1996558c4a0806 100644 (file)
@@ -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,
index 8072e6e4c62c6b67ee2af3c8eda990fe735291ec..ba9f36cef68c69d2d9601c75363537ca1a93800e 100644 (file)
@@ -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;
index 4afdf7902eda7d4a50c2ac0bacb30ca40ec3f31d..eab36a4606382dc18bdedf788b526d07a2b462b4 100644 (file)
@@ -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.
index d077c54900416835823615077ea2c1500ab82706..a43582076b20b9283fa02f44abf1bc97f4e7395d 100644 (file)
@@ -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,
index 1722d8f214499794d5304dc7e9597bfcd0dadd6b..f9e26dda56d6d48a618932f804e365444505b998 100644 (file)
@@ -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;
        }
index 213fb837e1c40fe79bf536d54b083d99dee1c192..08af8d6b844b67e0653f93c5dc012706d9a13b19 100644 (file)
@@ -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]);
 
index bfd237c15e76e8cfe9f3c78ffd555f42390a7d5e..41b492f99955f8d6778197e7102c854e41530b8f 100644 (file)
@@ -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 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr)
 }
 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);
index 37b8ad3e30d80440aea9ea2654a7a99696b50a57..be38ac7050d473b9be9be24ddb44c1ed79a152f9 100644 (file)
@@ -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;
 
index 10307cc16d7589949ac6ce8a5037b2e8724710c6..39ac15ce47023055f5a2badb7e5a99c59e19b3dd 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include <drm/drmP.h>
+#include <drm/drm_gem.h>
 
 #include "drm_crtc_internal.h"
 
  * 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);
 }
 
index 2e55599816aa5dfda1252a4affd0cee81d2c2ef2..6bb6337be920c6b440ef33f579832368feed86e5 100644 (file)
@@ -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++;
                }
@@ -3217,6 +3514,12 @@ cea_db_payload_len(const u8 *db)
        return db[0] & 0x1f;
 }
 
+static int
+cea_db_extended_tag(const u8 *db)
+{
+       return db[1];
+}
+
 static int
 cea_db_tag(const u8 *db)
 {
@@ -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);
        }
 }
 
@@ -4214,6 +4607,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
@@ -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;
 
        /*
index 53f9bdf470d77eed4f0c937ce98421cc8eacc043..f2ee8836301594170b9bc37256bf9c6ad9246994 100644 (file)
  */
 
 #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 @@ struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *dev,
 }
 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,
index 574af01d3ce94a1cc266d32e3128ab0d0e96c3d6..1b8f013ffa6503ec960cee3bdb9cb7c3fa78d2bc 100644 (file)
@@ -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 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
        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 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper)
                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 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper)
 
                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 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper)
 
                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 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
        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 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
  */
 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);
 
index 84f3a242cc39830fac620946379615d03a57ca87..b3c6e997ccdb0920c47fb19077ee9bd75ae91ab8 100644 (file)
@@ -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);
index b3ef4f1c2630fd5973132f43c809b1dfe05a169c..af279844d7ceb69d44ec9bf260ea63d9435b6de4 100644 (file)
@@ -817,7 +817,7 @@ static int atomic_remove_fb(struct drm_framebuffer *fb)
                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)
index 8dc11064253d9e5ed58f8c817a471b36c25c5951..ad4e9cfe48a2d3f2d25e8bee01a80d6c2d14192d 100644 (file)
@@ -310,6 +310,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
@@ -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);
index bc28e75752546c9390917cbe26e9ce7938183daf..373e33f22be42c7fccc36ab7aea48f365a6826aa 100644 (file)
@@ -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 (file)
index 0000000..d54a083
--- /dev/null
@@ -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);
index 5edc24bd10fa34551d826a493670695b5e4e992f..4e906b82a1701b9aa3c15f995951e793bdf09da3 100644 (file)
@@ -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,
index d1f2028520288261e4ad7c6344ea94e80178f3db..f8e96e648acfd17985f740afe4abd43022b762e5 100644 (file)
@@ -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;
 
index f1eb326524cf573852fb1d6fc2a4153669ac76ab..d920b2118a3905f5af2f8e1d0179e468cccabb27 100644 (file)
@@ -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;
index 1160a579e0dc0dd18dae853a55844080a5b950c5..4b47226b90d4bb2731e7bdc19b551693ae4cfe1d 100644 (file)
@@ -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);
        }
 
index d9862259a2a7919859fea4de629b1b34c7f1abfe..74f6ff5df6565baa98947c1ee806010a3050dac6 100644 (file)
@@ -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;
 }
 
index da9a9adbcc9857ec37f9fa75e48bbc7a6ed1d283..1055533792f3a538b65f0c202b6d81f5e0718175 100644 (file)
@@ -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;
 }
index f2493b9b82e6075e481833178b6279d728d8503d..4a3f68a33844589ad25a7f02f59c6470c0d2e891 100644 (file)
@@ -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);
index 2b33825f2f93138066b3593289bd076ad9f43409..9cb1eede0b4d9444a40e9b575b0e0184f4d2c9a5 100644 (file)
@@ -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);
index 64ef09a6cccb2d47e2443ca9a3bd56206031047b..af4e906c630d5bc20f08eb62107946fe70c0a107 100644 (file)
  *     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)
index 2120f33bdf4a4f21d9fc7d89577818193f30020e..8dafbdfcd2ea087865b233acd6b3622fb8b9e081 100644 (file)
@@ -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;
                        }
index 1eb4fc3eee20ad46ff44f917440f2d599ab80412..1235c9877d6f1cebb50cf5c478c2f086d9da42a0 100644 (file)
@@ -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 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
 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);
index 5dc8c4350602a561fe4cfd77fce77e26770696fb..85ab1eec73e572e4a1ce220bb4d73afb929e8e81 100644 (file)
@@ -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));
index 00e6832a8c1a69514a0487c5557977d8f5e1e6a3..904966cde32b51886fc5ee9e876a1d2ec992745b 100644 (file)
@@ -528,6 +528,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
                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:
index 3e88fa24eab3d382b037a873c6849fe32ead1d46..bc5128203056d08e1bf8ec806b401d7a3de90727 100644 (file)
@@ -709,6 +709,29 @@ int drm_property_replace_global_blob(struct drm_device *dev,
 }
 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)
 {
index 3cd96a95736d716fbb50f3343ab3d18e0fb47a15..7d1b0f011d33e1d796890bb71c88458b0ae6d054 100644 (file)
@@ -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.
index e084f9f8ca666c168e1df7e7108abdb1cc39744b..dc9fd109de14f00db553b4b02a6bd882f08a94aa 100644 (file)
@@ -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;
index 789ba0b37f7bab1e90a5821e81911b6acdc39d59..a5b38a80a99a0e2e893d169a7728dc9bc7a89796 100644 (file)
@@ -330,7 +330,6 @@ int drm_syncobj_export_sync_file(struct drm_file *file_private,
 }
 /**
  * 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.
index e9f33cd805dd6bfaa746800d2d67e53ec578ae18..70f2b9593edcb13e8a34f4705c27a38305d8ce12 100644 (file)
 #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;
index 1170b3209a1269aff7c1cfa3692b0fe73b413bb8..13a59ed2afbc4112568a62aba71d9857aadf940a 100644 (file)
@@ -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);
index 5bd93169dac2059a0981cc2f24b8c9032447ba9e..6463fc2c736fd4db5881a259b21848328b7f6cea 100644 (file)
@@ -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;
                }
 
index 1d185347c64c06f7b749061909390ea0953ed3f8..305dc3d4ff772a7fe8a1ad80b9a2897f04a4cca1 100644 (file)
@@ -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.
 
index d72777f6411a73144ffb3142c2bdca2e8585ac61..c37078fbe0ea4181c16391b134e5e650da7fe806 100644 (file)
@@ -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)
index 63abcd280fa027a965735cef0f9c7a768231373d..76d80e5de521501a04b7aff5a08df5e32f423608 100644 (file)
@@ -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,
index 35a8dfc93836d83f0223d3e030dea597d57abb55..b1f7299600f040947240618cf2cfc262d1847b70 100644 (file)
@@ -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))
index a11b79596e2f8d483c113b78d1df7568d59a48d4..c399dc9b325f640f51b6da03d3fb83c9bf2a33bb 100644 (file)
@@ -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);
 }
index d48fd7c918f880df0b3a27da5e8fa4f09c011b04..6592f50d460a6843e39222cf4f39152d6d34f190 100644 (file)
@@ -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 = {
index 641531243e04ce534a58928023c4207b6c597ac2..c3a068409b484fda04bbf837626f011beb875c1f 100644 (file)
@@ -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);
 }
index c23479be48500091fcb7aa0e0bdaf962a1f9fb59..077de014d61017d77853c41a7e5a2d4084e092f1 100644 (file)
@@ -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;
index 85457255fcd1aa093ddfb9a8c4e09b5d63720c7f..e86d1a9518c31bc4de5cbbf196303d8a6b833ce7 100644 (file)
@@ -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);
 
index e45720543a453d22c29150807815666ca0afffd9..16bbee897e0db9e7b3025f039a047e6580a59e3b 100644 (file)
@@ -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 @@ static int exynos_mic_probe(struct platform_device *pdev)
 
 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;
 }
 
index 611b6fd65433d0a29a77c8549dcca47c0e4979a9..8de74009dee4f439bbf2306c254c95723a1ac1fd 100644 (file)
@@ -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;
index cb8a728425371856dc9ef6c0b533574cc2038f96..9186a654c3b5f443fbb0db5f188388e29eca1efc 100644 (file)
@@ -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,
index 06bfbe400cf1d2ea23ec361a0fa1364a139ac43d..d70eeb8c5f75117d7c557a095aef701057416c4a 100644 (file)
@@ -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)
index 6bed4f3ffcd6bd8592c51ee398a3ccdbe10355e1..a998a8dd783cbc347792f88d56141ca34e4716e1 100644 (file)
@@ -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,
index cc4e944a1d3c668a595616ca208cc587bc794b1f..0e3752437e44fd822e91949db7c234e9889c30c1 100644 (file)
@@ -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,
 };
 
index 5cbde196895aa42873c77c15c101e487f3d065e0..58e9e0601a616b86bc910dc606ea7229c79fa52b 100644 (file)
@@ -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",
index 0a20723aa6e17194b08940beef9c211299a30455..9554b245746ebaef31d698c702903e7c40980289 100644 (file)
@@ -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;
index dcbf3c06e1d80f5b731ec018563802f13a2dc02a..edd7d8127d194d87440d721fcce53026fd319592 100644 (file)
@@ -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,
 };
index 7da70b6c83f0163b30b64b4cde74662ff2db132c..2570c7f647a637f3ea5eabf4030e77888116a33b 100644 (file)
@@ -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,
 };
 
index 7da061aab7299c2b2a38e14fb784c8f233f62468..131239759a75a2b9aafd4f3f805003480bed79b3 100644 (file)
@@ -47,36 +47,6 @@ int psb_gem_get_aperture(struct drm_device *dev, void *data,
        return -EINVAL;
 }
 
-/**
- *     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
index e7fd356acf2e2e7613127388c4f3900961a2f866..f3c48a2be71b87088e81becf739786bd7dc94755 100644 (file)
@@ -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;
index 1616af209bfcf89f9890b2d7a52a19c677f2802d..c50534c923df66014e26e7a634a45aa43d06be5e 100644 (file)
@@ -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
index 63c6e08600ae3a2351993dd5b6b824102a1e5420..531e4450c0009b7189490207182e033783113f3b 100644 (file)
@@ -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;
 
index 1f9b35afefeebc9f66ad6e018afe479f4b8b0df0..37a3be71acd909d6eb6ed7e9de2ed0175459dbb8 100644 (file)
@@ -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);
index 83667087d6e5ddc55291bbefe092543604a0e802..821497dbd3fcbee99b2feb4e7a2890b2b40f213f 100644 (file)
@@ -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 */
index 7b6c849250984149f871ea9075b995def2291021..8762efaef2839ca5b1582f0a195025d7e382ef90 100644 (file)
@@ -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;
index 6a10215fc42d4f6ca2877390721253a34cb2338c..e8e4ea14b12ba4f2bb8474e7941b9eec858f7cfe 100644 (file)
@@ -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 */
index 59542bddc9802838316d2a04e9a023ff546de014..a956545774a39225702ac05243769ed7cc3e76af 100644 (file)
@@ -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)
index 2ffdbf9801bd644c3d1320b2499012c8ba6c83f0..d4f6f1f9df5b73e06fd7f19999aa345f1b46798a 100644 (file)
@@ -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);
index f5ac80daeef2de2d1f5eeac2da80c9855056d630..b92595c477ef63038811e1af940822599eb577e3 100644 (file)
@@ -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 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper,
 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 = {
index 12a18557c5fd71d459eb9bd23c80f8363d4c4172..ec4dd9df91500d279ce078dacfff95606761b10e 100644 (file)
@@ -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,
index ac457c779caad6affc1cbfa3b54c8805fc49852a..3518167a7dc4c2512bec7e792ab9c0fcf7a50a56 100644 (file)
@@ -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;
index c96c228a98980810d220eec84b2a8a3326e0c487..39f7d15673ed9f03a7a1666135246dd77d3ff25f 100644 (file)
@@ -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;
index 9c903672f582315700cfd3c8c43ec4497404cbbf..e27352ca26c4041ad61da6d5caf82dd1bff237f9 100644 (file)
@@ -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,
index 7f60c64915d953563155de418764c74951f5bbb6..56cb62df065cfbfc9245bc876c3e0e38b301b7c7 100644 (file)
@@ -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;
index 86f47e190309aea31bfdbacfc532f7df3307221c..54e3255dde13d09b27efa1ab5c5d077380d80a96 100644 (file)
@@ -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,
index 37fd0906f807f0224b78a535746fbd41024e3f56..c69d5c487f513400fdea5bdeff2455c39b85ee76 100644 (file)
@@ -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);
index a5cd5dacf055c1ea2cbdf160045bf6bdec4e18ae..e9e64e8e9765952fb20808a9ee1d72c46fb60e4a 100644 (file)
@@ -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,
index 2deb05f618fb11054064122a4b86f468d148c73b..7cb0818a13debecc1d3f08e4fb10042a3536b1e9 100644 (file)
@@ -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)
index 700050556242480e6fbf8eb4a8d97c6307e9390d..1648887d3f55248cf055524a2f0e341062f0cd8d 100644 (file)
@@ -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,
index 5dad9298b2d5dbbe7b626895806e6008047bbd6a..a26c1705430eb2134d002b68ddcb26d272684bd9 100644 (file)
@@ -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;
index 3a74e79eac2f6c13fef32e1611b539db7b8f46c3..2964a4d01a66da5d2fb06d256ed35fa83fa96a38 100644 (file)
@@ -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;
 
@@ -195,6 +195,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 +223,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;
 };
index 17febe830ff6984e06bb81cb91601a76b67d5f2a..feed9921b3b3eb05e6e8dce5e1b510f4d6fc9479 100644 (file)
@@ -2857,31 +2857,15 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
        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 +2896,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 +2946,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 +3028,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;
 
        /*
index 4f7057d62d88b393ce77670f9100bc2d3b246014..c873136add977dd7348e82a6ec77cf725d995e89 100644 (file)
@@ -432,7 +432,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 +617,7 @@ int intel_gvt_init_workload_scheduler(struct intel_gvt *gvt)
 
 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)
index 90c14e6e3ea06b8de36d90284132659eb80f72c6..3deadcbd5a245c039169f1a10c6c91cc791d3a66 100644 (file)
@@ -480,11 +480,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,7 +499,7 @@ 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) {
@@ -520,7 +522,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");
 }
index 00d8967c8512048f5fb46f629c9c76ace1161bbf..2ef75c1a611957c6188402be8422a6e3c1ca4489 100644 (file)
@@ -1159,7 +1159,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 +1181,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 +1210,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 +1241,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 +1410,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 +1858,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 +1878,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 +1935,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 +1991,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;
@@ -2076,7 +2097,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 +2331,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 +2346,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 &&
@@ -3289,6 +3310,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 +3334,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();
 
@@ -3758,13 +3782,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 +3825,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 +3876,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 +3934,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");
@@ -4824,6 +4868,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},
index fc307e03943c829c8355d7da4c80db41c0838570..4c96a721448291e4b1e263c925709a9d4c3b8b41 100644 (file)
@@ -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");
                                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");
                                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");
                                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);
@@ -585,16 +596,18 @@ static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
 
 static void i915_gem_fini(struct drm_i915_private *dev_priv)
 {
+       flush_workqueue(dev_priv->wq);
+
        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)
@@ -1319,7 +1332,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 +1349,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:
@@ -1373,8 +1384,6 @@ void i915_driver_unload(struct drm_device *dev)
 
        i915_driver_unregister(dev_priv);
 
-       drm_vblank_cleanup(dev);
-
        intel_modeset_cleanup(dev);
 
        /*
@@ -1427,9 +1436,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 +1469,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);
 
@@ -1911,9 +1921,72 @@ void i915_reset(struct drm_i915_private *dev_priv)
 
 error:
        i915_gem_set_wedged(dev_priv);
+       i915_gem_retire_requests(dev_priv);
        goto finish;
 }
 
+/**
+ * i915_reset_engine - reset GPU engine to recover from a hang
+ * @engine: engine to reset
+ *
+ * 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)
+{
+       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));
+
+       DRM_DEBUG_DRIVER("resetting %s\n", engine->name);
+
+       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;
+       }
+
+       /*
+        * 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);
+
+       /* Finally, reset just this engine. */
+       ret = intel_gpu_reset(engine->i915, intel_engine_flag(engine));
+
+       i915_gem_reset_finish_engine(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 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;
+
+       error->reset_engine_count[engine->id]++;
+out:
+       return ret;
+}
+
 static int i915_pm_suspend(struct device *kdev)
 {
        struct pci_dev *pdev = to_pci_dev(kdev);
@@ -2670,7 +2743,6 @@ static struct drm_driver driver = {
        .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 +2755,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,
index e1f7c97a338a8e0744f673274ee83170fa2e0691..7c6fab08a2e6d1d61c878affe449769608df2009 100644 (file)
@@ -80,8 +80,8 @@
 
 #define DRIVER_NAME            "i915"
 #define DRIVER_DESC            "Intel Graphics"
-#define DRIVER_DATE            "20170619"
-#define DRIVER_TIMESTAMP       1497857498
+#define DRIVER_DATE            "20170717"
+#define DRIVER_TIMESTAMP       1500275179
 
 /* 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;
@@ -753,6 +758,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 +923,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;
@@ -1149,8 +1156,8 @@ 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 */
@@ -1166,6 +1173,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 +1309,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;
@@ -1550,6 +1555,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
@@ -1559,6 +1570,10 @@ struct i915_gpu_error {
 #define I915_RESET_BACKOFF     0
 #define I915_RESET_HANDOFF     1
 #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
@@ -2236,13 +2251,6 @@ 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];
@@ -2303,11 +2311,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 +2327,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;
 
@@ -2996,16 +3013,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 +3038,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)
@@ -3089,6 +3109,8 @@ 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);
+extern int i915_reset_engine(struct intel_engine_cs *engine);
+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);
@@ -3461,11 +3483,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 +3532,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 +3564,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 *
index 969bac8404f18cb31d4b22da8b0284d42f174541..d6f9b4cb6e9b4dc3d5505584fd8175c43564e553 100644 (file)
@@ -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 @@ i915_gem_object_wait_fence(struct dma_fence *fence,
        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;
 }
 
@@ -2832,46 +2816,64 @@ 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);
+
+       if (engine_stalled(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);
@@ -2925,7 +2927,7 @@ static void engine_skip_context(struct drm_i915_gem_request *request)
 static bool i915_gem_reset_request(struct drm_i915_gem_request *request)
 {
        /* Read once and return the resolution */
-       const bool guilty = engine_stalled(request->engine);
+       const bool guilty = !i915_gem_request_completed(request);
 
        /* The guilty request will get skipped on a hung engine.
         *
@@ -2959,11 +2961,9 @@ static bool i915_gem_reset_request(struct drm_i915_gem_request *request)
        return guilty;
 }
 
-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;
-
-       request = i915_gem_find_active_request(engine);
        if (request && i915_gem_reset_request(request)) {
                DRM_DEBUG_DRIVER("resetting %s to restart from tail of request 0x%x\n",
                                 engine->name, request->global_seqno);
@@ -2989,7 +2989,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 +3005,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,8 +3019,8 @@ 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);
        }
 }
 
@@ -3041,7 +3047,8 @@ 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
@@ -3071,6 +3078,13 @@ 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);
        }
 }
 
@@ -3080,6 +3094,7 @@ static int __i915_gem_set_wedged_BKL(void *data)
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
 
+       set_bit(I915_WEDGED, &i915->gpu_error.flags);
        for_each_engine(engine, i915, id)
                engine_set_wedged(engine);
 
@@ -3088,20 +3103,7 @@ static int __i915_gem_set_wedged_BKL(void *data)
 
 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 +3158,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);
@@ -4565,7 +4568,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 +4582,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 +4813,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;
 
@@ -4922,7 +4923,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);
@@ -5038,15 +5038,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 +5052,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);
 
index 152f16c11878ef937e48b9139c9b8ab844322df3..348b29a845c961c73b1605b23212692b438f0f19 100644 (file)
@@ -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,
@@ -140,7 +140,7 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
         * tracking.
         */
        if (!(flags & I915_CLFLUSH_FORCE) && obj->cache_coherent)
-               return;
+               return false;
 
        trace_i915_gem_object_clflush(obj);
 
@@ -179,4 +179,5 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
        }
 
        obj->cache_dirty = false;
+       return true;
 }
index 2455a7820937b0f461839de713693a9010950997..f390247561b37691d615fe0182d47cf40bcc4277 100644 (file)
@@ -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)
index 39ed58a21fc1f517f56d179d48b3b9bef00e9410..1a87d04e7937c126c5f1883b948941521fe1194a 100644 (file)
@@ -158,13 +158,11 @@ static void vma_lut_free(struct i915_gem_context *ctx)
        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);
@@ -188,8 +186,54 @@ 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)
@@ -205,7 +249,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 +257,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,7 +309,7 @@ __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;
 
@@ -354,6 +398,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 +465,7 @@ i915_gem_context_create_gvt(struct drm_device *dev)
        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 +474,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 +488,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 +514,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 +535,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 +554,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 +578,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);
@@ -981,20 +1034,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 +1056,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 +1088,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 +1101,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 +1145,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 +1161,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;
+       args->batch_active = READ_ONCE(ctx->guilty_count);
+       args->batch_pending = READ_ONCE(ctx->active_count);
 
-       mutex_unlock(&dev->struct_mutex);
-
-       return 0;
+       ret = 0;
+out:
+       rcu_read_unlock();
+       return ret;
 }
 
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
index 82c99ba92ad386b3e1ad60a1b4e2966a2761d16d..04320f80f9f4d487fde343b0659c1000be13a9a1 100644 (file)
@@ -86,6 +86,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
@@ -98,6 +99,11 @@ struct i915_gem_context {
         */
        struct kref ref;
 
+       /**
+        * @rcu: rcu_head for deferred freeing.
+        */
+       struct rcu_head rcu;
+
        /**
         * @flags: small set of booleans
         */
@@ -273,14 +279,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 +305,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__ */
index 054b2e54cdafd765e82f9a86276c863744f3cd14..5fa44767c29eb4189de6e602223dc4a070f15adc 100644 (file)
@@ -560,9 +560,6 @@ 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)) {
                err = i915_vma_get_fence(vma);
                if (unlikely(err)) {
@@ -574,6 +571,9 @@ static int eb_reserve_vma(const struct i915_execbuffer *eb,
                        entry->flags |= __EXEC_OBJECT_HAS_FENCE;
        }
 
+       entry->flags |= __EXEC_OBJECT_HAS_PIN;
+       GEM_BUG_ON(eb_vma_misplaced(entry, vma));
+
        return 0;
 }
 
@@ -675,16 +675,17 @@ 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(!ctx))
+               return -ENOENT;
 
        if (unlikely(i915_gem_context_is_banned(ctx))) {
                DRM_DEBUG("Context %u tried to submit while banned\n",
                          ctx->user_handle);
+               i915_gem_context_put(ctx);
                return -EIO;
        }
 
-       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;
@@ -1458,7 +1459,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 {
@@ -1775,7 +1776,7 @@ static noinline int eb_relocate_slow(struct i915_execbuffer *eb)
                }
        }
 
-       return err ?: have_copy;
+       return err;
 }
 
 static int eb_relocate(struct i915_execbuffer *eb)
@@ -1825,7 +1826,7 @@ 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 drm_i915_gem_exec_object2 *entry = &eb->exec[i];
                struct i915_vma *vma = exec_to_vma(entry);
                struct drm_i915_gem_object *obj = vma->obj;
 
@@ -1841,12 +1842,14 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
                        eb->request->capture_list = capture;
                }
 
+               if (unlikely(obj->cache_dirty && !obj->cache_coherent)) {
+                       if (i915_gem_clflush_object(obj, 0))
+                               entry->flags &= ~EXEC_OBJECT_ASYNC;
+               }
+
                if (entry->flags & EXEC_OBJECT_ASYNC)
                        goto skip_flushes;
 
-               if (unlikely(obj->cache_dirty && !obj->cache_coherent))
-                       i915_gem_clflush_object(obj, 0);
-
                err = i915_gem_request_await_object
                        (eb->request, obj, entry->flags & EXEC_OBJECT_WRITE);
                if (err)
@@ -2134,7 +2137,6 @@ i915_gem_do_execbuffer(struct drm_device *dev,
        if (DBG_FORCE_RELOC || !(args->flags & I915_EXEC_NO_RELOC))
                args->flags |= __EXEC_HAS_RELOC;
        eb.exec = exec;
-       eb.ctx = NULL;
        eb.invalid_flags = __EXEC_OBJECT_UNKNOWN_FLAGS;
        if (USES_FULL_PPGTT(eb.i915))
                eb.invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
@@ -2192,6 +2194,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 +2206,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,8 +2221,8 @@ 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)) {
                DRM_DEBUG("Attempting to use self-modifying batch buffer\n");
@@ -2343,11 +2346,11 @@ i915_gem_do_execbuffer(struct drm_device *dev,
 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)
index 61fc7e90a7da1447a78d2bbf164e15755b76bfda..10aa7762d9a63c440a845509c08acd05849bb28b 100644 (file)
@@ -207,8 +207,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 +906,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 +1618,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 +1631,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 +2086,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 +2097,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 +2132,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 +2223,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 +2231,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 +2308,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 +2345,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 +2398,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);
        }
 
index 1b2a56c3e5d3ab38251e02ed4d54a0c57ae653af..b4e3aa7c0ce197f5ae7cfb7ed79c08e73609ee08 100644 (file)
@@ -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);
index 8c59c79cbd8b1871a634093c92966cf6b8e7b1a0..483af8921060bfcd963b062bf0845a94ce3f14d9 100644 (file)
@@ -384,7 +384,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);
@@ -639,6 +643,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
index 7579b9702c22602fd280c5acce1295fd109dbc38..49a4c8994ff07afe721134bd26d50a0a88261a31 100644 (file)
@@ -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;
 
index 1032f98add112a66a19fb186a2b28de773caadf8..77fb3980813143d2d9e3432c0ebb994a4bcad032 100644 (file)
@@ -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();
index e18f350bc364253b7228c3d913f1797ce7b1f919..ae70283470a6c7b9ee60c22f7e652d9abfe697fb 100644 (file)
@@ -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;
index 4cd9ee1ba332e63247ed1d2e1505e10ff61ca633..eb4f1dca2077d8a8d600613f1feb6b46149ab545 100644 (file)
@@ -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)
@@ -1603,7 +1591,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);
        }
 }
@@ -2599,60 +2587,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);
+                               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
@@ -2722,6 +2743,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 +2764,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_HANDOFF >= 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)
+                               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_and_wakeup(dev_priv);
+       i915_reset_device(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);
index b6a7e363d07699e79a6b3d957c1444299a3f8fe6..88b9d3e6713a8e90184bb5e7eaf916f4dc628cc7 100644 (file)
@@ -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,
@@ -63,8 +63,9 @@ struct i915_params i915 __read_mostly = {
        .huc_firmware_path = NULL,
        .enable_dp_mst = true,
        .inject_load_failure = 0,
-       .enable_dpcd_backlight = false,
+       .enable_dpcd_backlight = -1,
        .enable_gvt = false,
+       .enable_dbc = true,
 };
 
 module_param_named(modeset, i915.modeset, int, 0400);
@@ -115,8 +116,8 @@ 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])");
 
 #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
 module_param_named(error_capture, i915.error_capture, bool, 0600);
@@ -246,10 +247,15 @@ MODULE_PARM_DESC(enable_dp_mst,
 module_param_named_unsafe(inject_load_failure, i915.inject_load_failure, uint, 0400);
 MODULE_PARM_DESC(inject_load_failure,
        "Force an error after a number of failure check points (0:disabled (default), N:force failure at the Nth failure check point)");
-module_param_named(enable_dpcd_backlight, i915.enable_dpcd_backlight, bool, 0600);
+module_param_named_unsafe(enable_dpcd_backlight, i915.enable_dpcd_backlight, int, 0600);
 MODULE_PARM_DESC(enable_dpcd_backlight,
-       "Enable support for DPCD backlight control (default:false)");
+       "Enable support for DPCD backlight control "
+       "(-1:auto (default), 0:force disable, 1:force enabled if supported");
 
 module_param_named(enable_gvt, i915.enable_gvt, bool, 0400);
 MODULE_PARM_DESC(enable_gvt,
        "Enable support for Intel GVT-g graphics virtualization host support(default:false)");
+
+module_param_named_unsafe(enable_dbc, i915.enable_dbc, bool, 0600);
+MODULE_PARM_DESC(enable_dbc,
+       "Enable support for dynamic backlight control (default:true)");
index 34148cc8637c1ac721bb6f481a9a2f7b1d671d66..057e203e6bda24cae2eab0cc8f890c1df6e8c614 100644 (file)
@@ -51,7 +51,9 @@
        func(int, use_mmio_flip); \
        func(int, mmio_debug); \
        func(int, edp_vswing); \
+       func(int, reset); \
        func(unsigned int, inject_load_failure); \
+       func(int, enable_dpcd_backlight); \
        /* leave bools at the end to not create holes */ \
        func(bool, alpha_support); \
        func(bool, enable_cmd_parser); \
        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); \
        func(bool, nuclear_pageflip); \
        func(bool, enable_dp_mst); \
-       func(bool, enable_dpcd_backlight); \
-       func(bool, enable_gvt)
+       func(bool, enable_gvt); \
+       func(bool, enable_dbc)
 
 #define MEMBER(T, member) T member
 struct i915_params {
index 506ec32b9e53d68ca22cb8c0144d7a096b331c29..a1e6b696bcfa076059854b2c46c0f65e26f1adee 100644 (file)
@@ -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
@@ -446,6 +449,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 }
 };
 
 /*
index 9cd22f83b0cfaee680ed06c5bde67db6fc89d0fa..ed396f7b7dcaf667ca9c3de0e84eb4bd21200207 100644 (file)
@@ -1601,11 +1601,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) |
@@ -1746,7 +1746,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;
 
@@ -2444,7 +2444,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);
 }
@@ -2633,7 +2633,7 @@ i915_perf_open_ioctl_locked(struct drm_i915_private *dev_priv,
        kfree(stream);
 err_ctx:
        if (specific_ctx)
-               i915_gem_context_put_unlocked(specific_ctx);
+               i915_gem_context_put(specific_ctx);
 err:
        return ret;
 }
index 64cc674b652ac038f14b9c8ad860601e43a51ae8..c712d01f92abaac30fdb406b1d17078d9fd7690f 100644 (file)
@@ -3522,7 +3522,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 +3531,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)) : \
@@ -8343,6 +8343,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 +8351,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)
index 1eef3fae4db31312f788372d72470ad2e9b38f5c..7fcf00622c4c19e10cc1361c6698114fb4f7fbf8 100644 (file)
@@ -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;
@@ -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;
index 1cfe137cdc32fc5103727b9110ed8c058954edb7..958be0a959602a4e6c773f4d3b4532029b031ce3 100644 (file)
@@ -579,11 +579,17 @@ int __i915_vma_do_pin(struct i915_vma *vma,
 
 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));
@@ -680,9 +686,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;
index 4a673fc1a4320f957595dffe5ff8c7c53fa20adf..20cf272c97b1f8e16328a0304d25539797f07631 100644 (file)
@@ -284,12 +284,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);
 }
index 4325cb0a04f5db5e3cdf37e70330283309d93d06..ee76fab7bb6f99f85a3d3136f21f20dcbb2855b4 100644 (file)
@@ -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);
index 639d45c1dd2e6ac24013431aa6da84abb9f0b089..82b144cdfa1d2d605d4ca2dba4a83ea9c523616a 100644 (file)
@@ -1187,6 +1187,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);
        }
 
index 306c6b06b330bfc57f75a992c60468cb9d88e81c..1813d84989c9c7d097632302543f25d8d2fce6a5 100644 (file)
@@ -398,6 +398,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 +616,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 {
index 84a1f5e85153fe1af4f7cfde8a5e7bf1a00201d5..70e0ff41070cbb174cd6b78008f230470d05b861 100644 (file)
@@ -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,
 };
index 80e96f1f49d2d09deb59ec08e6ebe78ac07b8cf3..f4fbb396054b377a57adfe6fa9c08628a8200376 100644 (file)
@@ -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;
@@ -1124,6 +1180,59 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
        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 +1376,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)
@@ -1868,9 +1979,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 +2010,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);
index 77d3214e1a7773bf1c1a8571ca826a80cf245f54..5f91ddc78c7a332c92653651fe983345bdea1a58 100644 (file)
@@ -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;
index dec9e58545a111b6f8d5aa9957c924d9e2ebcf16..f47ab0ef14bb4b2b224fe0024d610a8a1431055f 100644 (file)
@@ -3311,7 +3311,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 |
@@ -3367,7 +3367,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 |
@@ -3427,26 +3427,6 @@ static void intel_complete_page_flips(struct drm_i915_private *dev_priv)
                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 +3479,12 @@ 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;
+
        /*
         * Need mode_config.mutex so that we don't
         * trample ongoing ->detect() and whatnot.
@@ -3512,12 +3498,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,6 +3527,14 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
        struct drm_atomic_state *state = dev_priv->modeset_restore_state;
        int ret;
 
+       /* reset doesn't touch the display */
+       if (!i915.force_reset_modeset_test &&
+           !gpu_reset_clobbers_display(dev_priv))
+               return;
+
+       if (!state)
+               goto unlock;
+
        /*
         * Flips in the rings will be nuked by the reset,
         * so complete all pending flips so that user space
@@ -3558,22 +3546,10 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
 
        /* 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,8 +3573,8 @@ 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);
@@ -4612,6 +4588,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 +4600,18 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
         */
        need_scaling = src_w != dst_w || src_h != dst_h;
 
+       /*
+        * 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
@@ -9117,6 +9108,13 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
        u64 power_domain_mask;
        bool active;
 
+       if (INTEL_GEN(dev_priv) >= 9) {
+               intel_crtc_init_scalers(crtc, pipe_config);
+
+               pipe_config->scaler_state.scaler_id = -1;
+               pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX);
+       }
+
        power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
@@ -9145,13 +9143,6 @@ 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);
-
-               pipe_config->scaler_state.scaler_id = -1;
-               pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX);
-       }
-
        power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
        if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {
                power_domain_mask |= BIT_ULL(power_domain);
@@ -9540,7 +9531,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 +9559,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));
@@ -12803,7 +12804,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);
 }
@@ -13271,7 +13272,15 @@ 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);
+
+               mutex_lock(&dev->struct_mutex);
+               drm_atomic_helper_cleanup_planes(dev, state);
+               mutex_unlock(&dev->struct_mutex);
+               return ret;
+       }
        dev_priv->wm.distrust_bios_wm = false;
        intel_shared_dpll_swap_state(state);
        intel_atomic_track_fbs(state);
@@ -13300,7 +13309,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,
@@ -13577,7 +13585,6 @@ const 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,
@@ -13712,7 +13719,6 @@ 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,
@@ -13786,18 +13792,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,
+                                              NULL,
                                               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,
+                                              NULL,
                                               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,
+                                              NULL,
                                               DRM_PLANE_TYPE_PRIMARY,
                                               "plane %c", plane_name(primary->plane));
        if (ret)
@@ -13883,7 +13892,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
                                       0, &intel_cursor_plane_funcs,
                                       intel_cursor_formats,
                                       ARRAY_SIZE(intel_cursor_formats),
-                                      DRM_PLANE_TYPE_CURSOR,
+                                      NULL, DRM_PLANE_TYPE_CURSOR,
                                       "cursor %c", pipe_name(pipe));
        if (ret)
                goto fail;
@@ -14765,6 +14774,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 +14868,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)
index 64fa774c855b91e9f400fe90da6e8b56bd4520a9..76c8a0bd17f9f70bc5d83c5770284dcfe05a2954 100644 (file)
@@ -4418,8 +4418,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 +4441,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 +4450,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 +4523,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)
 {
@@ -4547,16 +4595,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 +5007,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 +5176,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 +5228,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 +5346,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;
index 228ca06d9f0bb3dd88c676bbf444e4cc3756dfbc..b25cd88fc1c596e0aa21d5a673f17e0a8e40501d 100644 (file)
@@ -98,13 +98,105 @@ 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;
+}
+
+/*
+* Set minimum / maximum dynamic brightness percentage. This value is expressed
+* as the percentage of normal brightness in 5% increments.
+*/
+static bool
+intel_dp_aux_set_dynamic_backlight_percent(struct intel_dp *intel_dp,
+                                          u32 min, u32 max)
+{
+       u8 dbc[] = { DIV_ROUND_CLOSEST(min, 5), DIV_ROUND_CLOSEST(max, 5) };
+
+       if (drm_dp_dpcd_write(&intel_dp->aux, DP_EDP_DBC_MINIMUM_BRIGHTNESS_SET,
+                         dbc, sizeof(dbc)) < 0) {
+               DRM_DEBUG_KMS("Failed to write aux DBC brightness level\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 +205,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 +222,25 @@ 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 (i915.enable_dbc &&
+           (intel_dp->edp_dpcd[2] & DP_EDP_DYNAMIC_BACKLIGHT_CAP)) {
+               if(intel_dp_aux_set_dynamic_backlight_percent(intel_dp, 0, 100)) {
+                       new_dpcd_buf |= DP_EDP_DYNAMIC_BACKLIGHT_ENABLE;
+                       DRM_DEBUG_KMS("Enable dynamic brightness.\n");
+               }
+       }
+
+       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);
 }
@@ -169,15 +277,66 @@ intel_dp_aux_display_control_capable(struct intel_connector *connector)
        /* Check the eDP Display control capabilities registers to determine if
         * the panel can support backlight control over the aux channel
         */
-       if (intel_dp->edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP &&
-           (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP) &&
-           !(intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_PWM_PIN_CAP)) {
+       if ((intel_dp->edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP) &&
+           (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP)) {
                DRM_DEBUG_KMS("AUX Backlight Control Supported!\n");
                return true;
        }
        return false;
 }
 
+/*
+ * Heuristic function whether we should use AUX for backlight adjustment or not.
+ *
+ * We should use AUX for backlight brightness adjustment if panel doesn't this
+ * via PWM pin or using AUX is better than using PWM pin.
+ *
+ * The heuristic to determine that using AUX pin is better than using PWM pin is
+ * that the panel support any of the feature list here.
+ * - Regional backlight brightness adjustment
+ * - Backlight PWM frequency set
+ * - More than 8 bits resolution of brightness level
+ * - Backlight enablement via AUX and not by BL_ENABLE pin
+ *
+ * If all above are not true, assume that using PWM pin is better.
+ */
+static bool
+intel_dp_aux_display_control_heuristic(struct intel_connector *connector)
+{
+       struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base);
+       uint8_t reg_val;
+
+       /* Panel doesn't support adjusting backlight brightness via PWN pin */
+       if (!(intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_PWM_PIN_CAP))
+               return true;
+
+       /* Panel supports regional backlight brightness adjustment */
+       if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_GENERAL_CAP_3,
+                             &reg_val) != 1) {
+               DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
+                              DP_EDP_GENERAL_CAP_3);
+               return false;
+       }
+       if (reg_val > 0)
+               return true;
+
+       /* Panel supports backlight PWM frequency set */
+       if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_FREQ_AUX_SET_CAP)
+               return true;
+
+       /* Panel supports more than 8 bits resolution of brightness level */
+       if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT)
+               return true;
+
+       /* Panel supports enabling backlight via AUX but not by BL_ENABLE pin */
+       if ((intel_dp->edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) &&
+           !(intel_dp->edp_dpcd[1] & DP_EDP_BACKLIGHT_PIN_ENABLE_CAP))
+               return true;
+
+       return false;
+
+}
+
 int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector)
 {
        struct intel_panel *panel = &intel_connector->panel;
@@ -188,6 +347,10 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector)
        if (!intel_dp_aux_display_control_capable(intel_connector))
                return -ENODEV;
 
+       if (i915.enable_dpcd_backlight == -1 &&
+           !intel_dp_aux_display_control_heuristic(intel_connector))
+               return -ENODEV;
+
        panel->backlight.setup = intel_dp_aux_setup_backlight;
        panel->backlight.enable = intel_dp_aux_enable_backlight;
        panel->backlight.disable = intel_dp_aux_disable_backlight;
index 2cf046beae0fa62eed80565e06a6f21154e34fd2..58568559711a51ff3f22adfc422ff828328c52eb 100644 (file)
@@ -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,
@@ -443,28 +441,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 +476,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");
 }
 
index d93efb49a2e2b500c879650b20b4607c3fa90326..210a8c63bde84813281fbbfc157dcc45413806f6 100644 (file)
@@ -786,7 +786,6 @@ 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
@@ -1858,9 +1857,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);
index 50ec836da8b1c3a112f9ad83114d4b317c067990..b0b3adf016f830ab394fbbe27344cd3f43a52e56 100644 (file)
@@ -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,
index c1544a53095ddb353430f9468b2e644dff4ea673..baf369d2de304b56883e6aa1a83dec909516d59b 100644 (file)
@@ -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,
 };
index 5b4de719bec3dc2faf9fefeaf7dd46cceb8f2679..24db316e0fd1137ff456b61120c041684a2cb30d 100644 (file)
@@ -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 @@ int intel_engines_init_mmio(struct drm_i915_private *dev_priv)
  */
 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;
 }
@@ -1340,6 +1329,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;
        }
 }
index 0c4cde6b2e6fc7aad314e7c7f329f51f0937a87d..0986ca4f16f1a3b2b9d5f49d42986d76a76f68a9 100644 (file)
@@ -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 @@ static int intelfb_create(struct drm_fb_helper *helper,
        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 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
                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 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
 
                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 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
 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,
 };
 
@@ -813,7 +789,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);
 }
 
index 52d5b82790d9fa5461a3c75977b320bd4348d407..c17ed0e62b6757b678272056326062c74f71ee6b 100644 (file)
@@ -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;
 }
index ec0779a52d5354a0d0f40aec373ec5e37661c622..eb0c559b66c116a3a9041765376278ee2b2efe49 100644 (file)
@@ -459,11 +459,14 @@ 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;
@@ -1321,7 +1324,7 @@ 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)
@@ -1703,11 +1706,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,
index 7404cf2aac28690e2e5367de5a93164062a909b4..699868d81de8a4db733c8c1705f0fac12bd38036 100644 (file)
@@ -2071,7 +2071,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;
index 6fe5d7c3bc23bf149e67ab4af228efbd5bf0642c..61d557948e2150bd9e511baccf930722950026e1 100644 (file)
@@ -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,
index 96c2cbd81869e7e55dedc8ce09f53938466bee70..593349be8b9dfce328d20ea3ca5d1b22e41da320 100644 (file)
@@ -469,7 +469,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;
index 48ea0fca1f7239eb502b8269d57b95520ddb5708..48785ef75d33370b2fcfc150f58b8bed51cf61c4 100644 (file)
@@ -3837,7 +3837,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 +3861,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 +3872,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 +3891,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 +3913,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 +3938,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);
 
@@ -4276,7 +4276,7 @@ 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);
        return ret;
 }
 
@@ -4294,7 +4294,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 +4306,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 +4361,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;
@@ -4390,7 +4390,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 +4397,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,14 +4430,14 @@ 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,
+               plane_blocks_per_line = div_fixed16(interm_pbpl,
                                                        y_min_scanlines);
        } else if (x_tiled) {
                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);
@@ -4450,35 +4446,35 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
                                 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);
 
        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 +4559,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 +5847,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 +5989,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 +6121,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 +6348,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 +6361,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 +6667,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 +6685,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 +7816,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);
@@ -9078,7 +9061,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 +9074,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 +9096,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 +9125,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);
index acd1da9b62a3f2d5ed2f4620c130c33c684d6042..5224b7abb8a3d0a462a2b89ff46edbc1d646def7 100644 (file)
@@ -2140,7 +2140,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 +2184,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) {
index 6aa20ac8cde388613248f06a627213215a794948..d33c93444c0d7f80b22d806672dc12495b334ca3 100644 (file)
@@ -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;
 };
 
index efe80ed5fd4d062f1999bfafc19670293d5a3dea..f630d632a976eb5a39db843855ad44b27bac76ed 100644 (file)
@@ -341,6 +341,59 @@ static void skl_power_well_pre_disable(struct drm_i915_private *dev_priv,
                                                1 << PIPE_C | 1 << PIPE_B);
 }
 
+static void gen9_wait_for_power_well_enable(struct drm_i915_private *dev_priv,
+                                           struct i915_power_well *power_well)
+{
+       int 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_DRIVER,
+                                       SKL_POWER_WELL_STATE(id),
+                                       SKL_POWER_WELL_STATE(id),
+                                       1));
+}
+
+static u32 gen9_power_well_requesters(struct drm_i915_private *dev_priv, int id)
+{
+       u32 req_mask = SKL_POWER_WELL_REQ(id);
+       u32 ret;
+
+       ret = I915_READ(HSW_PWR_WELL_BIOS) & req_mask ? 1 : 0;
+       ret |= I915_READ(HSW_PWR_WELL_DRIVER) & req_mask ? 2 : 0;
+       ret |= I915_READ(HSW_PWR_WELL_KVMR) & req_mask ? 4 : 0;
+       ret |= I915_READ(HSW_PWR_WELL_DEBUG) & req_mask ? 8 : 0;
+
+       return ret;
+}
+
+static void gen9_wait_for_power_well_disable(struct drm_i915_private *dev_priv,
+                                            struct i915_power_well *power_well)
+{
+       int id = power_well->id;
+       bool disabled;
+       u32 reqs;
+
+       /*
+        * 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.
+        */
+       wait_for((disabled = !(I915_READ(HSW_PWR_WELL_DRIVER) &
+                              SKL_POWER_WELL_STATE(id))) ||
+                (reqs = gen9_power_well_requesters(dev_priv, id)), 1);
+       if (disabled)
+               return;
+
+       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 hsw_set_power_well(struct drm_i915_private *dev_priv,
                               struct i915_power_well *power_well, bool enable)
 {
@@ -549,7 +602,9 @@ static void assert_can_enable_dc9(struct drm_i915_private *dev_priv)
                  "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_DRIVER) &
+                 SKL_POWER_WELL_REQ(SKL_DISP_PW_2),
+                 "Power well 2 on.\n");
        WARN_ONCE(intel_irqs_enabled(dev_priv),
                  "Interrupts not disabled yet.\n");
 
@@ -744,45 +799,6 @@ 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)
 {
@@ -846,6 +862,8 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv,
                        DRM_DEBUG_KMS("Enabling %s\n", power_well->name);
                        check_fuse_status = true;
                }
+
+               gen9_wait_for_power_well_enable(dev_priv, power_well);
        } else {
                if (enable_requested) {
                        I915_WRITE(HSW_PWR_WELL_DRIVER, tmp & ~req_mask);
@@ -853,14 +871,9 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv,
                        DRM_DEBUG_KMS("Disabling %s\n", power_well->name);
                }
 
-               gen9_sanitize_power_well_requests(dev_priv, power_well);
+               gen9_wait_for_power_well_disable(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,
@@ -2479,7 +2492,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)) {
@@ -2694,13 +2707,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 +2769,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) \
@@ -2821,7 +2845,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,12 +2880,18 @@ 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;
index 3f8f30b412cd883c6919f9c59ca32610a344cf0e..bea8152ae859a0fef38b22a424ebf2e384740688 100644 (file)
@@ -996,7 +996,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,7 +1344,7 @@ 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);
@@ -2192,10 +2193,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,
index 0c650c2cbca8593636e8f04e64e3a61ed42d4234..4c6b387fa9dc8e7e3b83e74548804ec6bc262b6a 100644 (file)
@@ -262,7 +262,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 |
@@ -1171,13 +1171,13 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
                ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
                                               possible_crtcs, &intel_plane_funcs,
                                               plane_formats, num_plane_formats,
-                                              DRM_PLANE_TYPE_OVERLAY,
+                                              NULL, 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,
                                               plane_formats, num_plane_formats,
-                                              DRM_PLANE_TYPE_OVERLAY,
+                                              NULL, DRM_PLANE_TYPE_OVERLAY,
                                               "sprite %c", sprite_name(pipe, plane));
        if (ret)
                goto fail;
index 784df024e23056ce08c7ec2ca53f23d8e143886f..906893c006d8b48f7c4df38fc55a2dd358b084f3 100644 (file)
@@ -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,
index 9882724bc2b69c9d56c21e013a3806b1cab649d6..deb4430541cf8316f7734a564495c130873735c2 100644 (file)
@@ -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,
@@ -1719,6 +1719,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;
index 50710e3f1caa98c1a800df29068971b957916d48..6b132caffa184d8689a495613857bba1475022ef 100644 (file)
@@ -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;
 
index fb9072d5877fefc2cd3dcde84a7978221425e195..2e86ec136b3558ba019e3b67e66b127f0a056879 100644 (file)
@@ -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);
index aa31d6c0cdfb110a84f4d35fec1b3826e4fa4d89..7096c3911cd358084b5b1e6bb9423312b06a9e76 100644 (file)
@@ -316,6 +316,56 @@ static int igt_global_reset(void *arg)
 
        GEM_BUG_ON(test_bit(I915_RESET_HANDOFF, &i915->gpu_error.flags));
        clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+       wake_up_all(&i915->gpu_error.reset_queue);
+
+       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);
+               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;
 
@@ -404,6 +454,7 @@ static int igt_wait_reset(void *arg)
 unlock:
        mutex_unlock(&i915->drm.struct_mutex);
        clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+       wake_up_all(&i915->gpu_error.reset_queue);
 
        if (i915_terminally_wedged(&i915->gpu_error))
                return -EIO;
@@ -519,11 +570,117 @@ static int igt_reset_queue(void *arg)
 unlock:
        mutex_unlock(&i915->drm.struct_mutex);
        clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+       wake_up_all(&i915->gpu_error.reset_queue);
+
+       if (i915_terminally_wedged(&i915->gpu_error))
+               return -EIO;
+
+       return err;
+}
+
+static int igt_render_engine_reset_fallback(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;
+       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;
+
+       set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+       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);
+
+       /* make reset engine fail */
+       rq->fence.error = -EIO;
+
+       if (!wait_for_hang(&h, rq)) {
+               pr_err("Failed to start request %x\n", rq->fence.seqno);
+               err = -EIO;
+               goto err_request;
+       }
+
+       reset_engine_count = i915_reset_engine_count(&i915->gpu_error, engine);
+       reset_count = fake_hangcheck(rq);
+
+       /* unlock since we'll call handle_error */
+       mutex_unlock(&i915->drm.struct_mutex);
+       clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+       wake_up_all(&i915->gpu_error.reset_queue);
+
+       i915_handle_error(i915, intel_engine_flag(engine), "live test");
+
+       if (i915_reset_engine_count(&i915->gpu_error, engine) !=
+           reset_engine_count) {
+               pr_err("render engine reset recorded! (full reset expected)\n");
+               err = -EINVAL;
+               goto out_rq;
+       }
+
+       if (i915_reset_count(&i915->gpu_error) == reset_count) {
+               pr_err("No full GPU reset recorded!\n");
+               err = -EINVAL;
+               goto out_rq;
+       }
+
+       /*
+        * by using fence.error = -EIO, full reset sets the wedged flag, do one
+        * more full reset to re-enable the hw.
+        */
+       if (i915_terminally_wedged(&i915->gpu_error)) {
+               set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+               rq->fence.error = 0;
+
+               mutex_lock(&i915->drm.struct_mutex);
+               set_bit(I915_RESET_HANDOFF, &i915->gpu_error.flags);
+               i915_reset(i915);
+               GEM_BUG_ON(test_bit(I915_RESET_HANDOFF,
+                                   &i915->gpu_error.flags));
+               mutex_unlock(&i915->drm.struct_mutex);
+
+               if (i915_reset_count(&i915->gpu_error) == reset_count) {
+                       pr_err("No full GPU reset recorded!\n");
+                       err = -EINVAL;
+                       goto out_rq;
+               }
+       }
+
+out_rq:
+       i915_gem_request_put(rq);
+       hang_fini(&h);
+out_backoff:
+       clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+       wake_up_all(&i915->gpu_error.reset_queue);
 
        if (i915_terminally_wedged(&i915->gpu_error))
                return -EIO;
 
        return err;
+
+err_request:
+       i915_gem_request_put(rq);
+err_fini:
+       hang_fini(&h);
+err_unlock:
+       mutex_unlock(&i915->drm.struct_mutex);
+       goto out_backoff;
 }
 
 int intel_hangcheck_live_selftests(struct drm_i915_private *i915)
@@ -531,8 +688,10 @@ 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_wait_reset),
                SUBTEST(igt_reset_queue),
+               SUBTEST(igt_render_engine_reset_fallback),
        };
 
        if (!intel_has_gpu_reset(i915))
index f8b9cc212b02df33cf06ee9c0d87ae433ebc6a6c..9c7c68181f82de186d7edbf7eb0fbf2e4f7568e7 100644 (file)
@@ -48,7 +48,7 @@ mock_context(struct drm_i915_private *i915,
        if (!ctx->vma_lut.ht)
                goto err_free;
 
-       ret = ida_simple_get(&i915->context_hw_ida,
+       ret = ida_simple_get(&i915->contexts.hw_ida,
                             0, MAX_CONTEXT_HW_ID, GFP_KERNEL);
        if (ret < 0)
                goto err_vma_ht;
@@ -86,3 +86,12 @@ 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);
+}
index 2427e5c0916a2a0f2acf19304c17a100ccb790e2..383941a611240f362cea2018e8415b973e0da7d3 100644 (file)
@@ -25,6 +25,8 @@
 #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);
index 627e2aa097665f7667f2cf6a834112dd28ac1a3a..2f1844c50e7de70af05cc4c116a0e36e3e272637 100644 (file)
@@ -57,11 +57,12 @@ static void mock_device_release(struct drm_device *dev)
 
        cancel_delayed_work_sync(&i915->gt.retire_work);
        cancel_delayed_work_sync(&i915->gt.idle_work);
+       flush_workqueue(i915->wq);
 
        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);
@@ -160,7 +161,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);
@@ -206,7 +207,7 @@ struct drm_i915_private *mock_gem_device(void)
        mkwrite_device_info(i915)->ring_mask = BIT(0);
        i915->engine[RCS] = mock_engine(i915, "mock");
        if (!i915->engine[RCS])
-               goto err_dependencies;
+               goto err_priorities;
 
        i915->kernel_context = mock_context(i915, NULL);
        if (!i915->kernel_context)
index a61309c7cb3ed1875931351498e0e55790032315..f2118cf535a053926254a523474be87dc5789142 100644 (file)
@@ -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)
 {
 }
index 95e2181963d9aa097fef3c0063a6fc94cb024bcf..f91cb72d08305f50e437f69bb2c2e7478588cf87 100644 (file)
@@ -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,
index 8b05ecb8fdefccafeed07755d501e8902ccba0c3..56dd7a9a8e254a3e03e4bebb5fda75b8555abbba 100644 (file)
@@ -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,
index 4826bb7817232ac9523e5459176ed18cd0131f3b..bc27c26994641a1289324d0731cd1e1e7c4b13bf 100644 (file)
@@ -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,
index 5456c15d962c525a4879b9b8a2b9cf63814ffc12..53e0b24beda6e0e2ee44c57550d5c752393b5863 100644 (file)
@@ -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)
index 49546222c6d398540a50025076c952f8444b7c66..debde2dae7bf920ed6c24a79e65bee58a727312b 100644 (file)
@@ -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,
@@ -675,7 +675,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 +718,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);
index 636031a30e17d5b3b74aee7d99d475b0d681b097..8def97d75030c8c49a64ef63764769bb7d44bf42 100644 (file)
@@ -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;
index ef79a6d556469dbb0cfec3337c0851129935c465..f609b62b8be6f47ede11549bcacaf95b8ba8582c 100644 (file)
@@ -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;
        }
 
index 35bc5babdbf70d5263e06c9d5f0cb0ebd5715e3c..978782a776292e6d954755cc71786bd98b5d81ac 100644 (file)
@@ -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;
        }
 
index b68a51376f83ac809d19e2ee020d355a61830493..585943c81e1f8818de1a6bb481f6adb90c8ad308 100644 (file)
@@ -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;
        }
 
index 32ca351ecd09122cfba5305bd7d184c4d7c75a37..e80a603e5fb087c5641916b07e9083f11c0ace70 100644 (file)
@@ -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);
index cb32c9369f3a6259914898bcc6817bc9d2fd0e99..658b8dd45b834fb463cab8424e5067dc82258e39 100644 (file)
@@ -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;
                }
 
index 07d7ea2268eff7b4b3e43cca47fbd889c2d2fa99..4672317e3ad12497ee68b86cf1dcb55f5a436d9f 100644 (file)
@@ -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;
        }
index 41d2cffe953e59f220eb53de2821583d6211e7bc..a2ca90fc403cb5779e40bebb0124f0aa3f5147d7 100644 (file)
@@ -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 {
index d4246c9dceae9804a7bef86784e4c665df3e500c..0d8d506695f9f87d9622708f9144549fc1b63ef6 100644 (file)
@@ -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);
 }
index 7abc550ebc0021b301dc6b9cfaa59aa3b8b9ca00..f595ac816b555f688a554ea9e2a74163f9cd775d 100644 (file)
@@ -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 @@ int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
        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)
 
index 2752718fa5b2fd121e3da87af3696667ccf0c0bc..534639b43a1c77c24a5942c6cb627dc32389f425 100644 (file)
@@ -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);
index 1a59b9ab4aa817701938235dd9ac397d75206098..6f121891430fadad9ed1086e82e61cfa4dc92271 100644 (file)
@@ -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;
index 97253c8f813b0ea026f03a686215c0783ec35b7c..7e5e24c2152a3e85e6fa01eeff504017356a9cd4 100644 (file)
@@ -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;
        }
 
index 71eb4fbbfc85fd74e260fccc1ecdb96bacfc6644..690c67507cbce6cd445bdcf245b08a3d52032b65 100644 (file)
@@ -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;
        }
index c986eb03b9d98d57356c016375878a593f13cf09..5155f0179b61744f41f18922a9d0c1b39ec28b10 100644 (file)
@@ -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)
index 4d98fac9279555224a0f1b617b8ff181ef47b6ce..7742c7d81ed8fbaac2e036a3c5d061ff553eed73 100644 (file)
@@ -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;
 }
index a32d3b6e2e12e482f16d4f23eedea11cb8f5da18..17e96fa4786854e2001a9c8553c0500127db403b 100644 (file)
@@ -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);
index 00775b397dbac3ee7f2a3ffa416b8ac55d247ce5..79d95ca8a0c099601e8dada4680320bf829f97dc 100644 (file)
@@ -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,
index 63ba0699d107e0ca0247ca78336ab1151f3284a0..1aad27813c23f6b5e823573ed3440aed141f194f 100644 (file)
@@ -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);
index 2ac3fcbfea7bc988667eb5b2819712187dd8be81..968e20379d54d6f05ec7e5db64e82b4ba36b3395 100644 (file)
@@ -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;
 }
index 9ac007880328b7659130b81b196ae92d7230929c..74cdde2ee474df7afd5a95c5c88d2d287ba7c95c 100644 (file)
@@ -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);
index c88b6ec88dd2b2ee56d68f383079559a4cbec626..04f1dfba12e5993ead71b7ef1639ac208c0be938 100644 (file)
@@ -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);
index 5d3b1fac906f44dc4e216dd10abf08c622f4ff6a..30726c9fe28c810486a127c3dfbd92c07836b2e3 100644 (file)
@@ -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,
 };
 
index dce8a3eb5a1065cba88368f25405784a5432910b..780f983b0294ded7d2f0a222bd185597995f982a 100644 (file)
@@ -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;
 }
index f4b53588e071e4cdc10ecbf152fcb0cee3d55e10..5e9cd4c0e8b631be790148c1df05d9573f7068cf 100644 (file)
 
 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
index b638d192ce5e046cc29e87459cc36e988e498ea8..99d39b2aefa675941d42c86b3c9b5a4d2cda937b 100644 (file)
@@ -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
index b4b54f1c24bc1995a032493838d99e8e31dff9e9..f9eae03aa1dcaef072974d60216fb6b09ef81e66 100644 (file)
@@ -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)
@@ -377,45 +368,6 @@ 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;
@@ -444,11 +396,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;
 
@@ -545,7 +493,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 +639,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);
@@ -920,31 +865,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 +964,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
 
index 6638bc85645dbad4adf3689bd7d9bae9441173c2..1137092241d593c34e4607e3c723acfb74861972 100644 (file)
@@ -36,8 +36,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 +57,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__ */
index f1ab2703674a2f5d4f533828bb6c8b49df24f571..7414c6bbd582e9597e502305885f0dec909859be 100644 (file)
@@ -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);
index 9e9c5696bc03547b813ecf2ae56c535265e64bcd..c7b612c3d7717a02d8d64be21dea68f183163917 100644 (file)
@@ -2137,6 +2137,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;
@@ -2280,7 +2287,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 +2299,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;
 }
 
index a879ffa534b4d845007d3f974f9ce9c7df69dff0..855248132b2bd2d0a24c878b0066074e412f83ca 100644 (file)
@@ -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,
index 5960628ceb93e47ea55bb0fba6173e98f618581b..6f3fc6b0f0a31e5567ad714cdc1654d654b596ab 100644 (file)
@@ -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,
index ae40e7179d4f5f21cbdef9401d68b2e09d954a7f..13ac822dee5d89c7cc47411ea2f7b517223c0b65 100644 (file)
@@ -97,7 +97,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) {
index a2515b466ce51d771f7966e9e574deecd0bcdf19..71536d9c7fe8c89d37b0061ae97e962e446ff536 100644 (file)
@@ -407,7 +407,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,
index 615e1def64d9482f2609f0545652f340d4d9743f..47fa2aba198301ce2d61102164af3dad9c494bc1 100644 (file)
@@ -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)
index bcd1f5cac72c9a239d9c956ac05d3d0fd614dc0e..f7f087419ed8bc936df5d461f9d3e98a09a50ea0 100644 (file)
@@ -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);
index 353429b05733745977fc616944695962a6e76e62..e3b1c86b7aaeaeecf39d0fff91cad1f6c1f325b8 100644 (file)
@@ -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,
index a20e3d644523572193893a2f26d19c19d2308590..7a1ad3af08e330c08519f287b600fa425a9b1780 100644 (file)
@@ -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;
 
index cb5415d6c04b7ab6e1e80503d26b32891a934dee..3a81e26629c7dc001fd9fa6bfd2bd26cf72848d6 100644 (file)
@@ -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,7 +409,8 @@ 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);
@@ -429,7 +430,8 @@ static void mdp5_crtc_disable(struct drm_crtc *crtc)
        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);
@@ -753,6 +755,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
        if (!handle) {
                DBG("Cursor off");
                cursor_enable = false;
+               mdp5_enable(mdp5_kms);
                goto set_cursor;
        }
 
@@ -776,6 +779,8 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
 
        get_roi(crtc, &roi_w, &roi_h);
 
+       mdp5_enable(mdp5_kms);
+
        mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride);
        mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm),
                        MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888));
@@ -804,6 +809,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
        crtc_flush(crtc, flush_mask);
 
 end:
+       mdp5_disable(mdp5_kms);
        if (old_bo) {
                drm_flip_work_queue(&mdp5_crtc->unref_cursor_work, old_bo);
                /* enable vblank to complete cursor work: */
@@ -836,6 +842,8 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 
        get_roi(crtc, &roi_w, &roi_h);
 
+       mdp5_enable(mdp5_kms);
+
        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 +855,8 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 
        crtc_flush(crtc, flush_mask);
 
+       mdp5_disable(mdp5_kms);
+
        return 0;
 }
 
@@ -917,7 +927,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 +939,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 +947,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)
index 97f3294fbfc6f9d26f453dac36d5dbb3cb00e93a..70bef51245af89d5bbb292f4495f2fd79dcc9e33 100644 (file)
@@ -299,7 +299,7 @@ static void mdp5_encoder_enable(struct drm_encoder *encoder)
        struct mdp5_interface *intf = mdp5_encoder->intf;
 
        if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
-               mdp5_cmd_encoder_disable(encoder);
+               mdp5_cmd_encoder_enable(encoder);
        else
                mdp5_vid_encoder_enable(encoder);
 }
index 5d13fa5381ee37705a0c282bf023b4782fc19268..1c603aef3c59cdff286ce38e84c3e6a4745dd0c2 100644 (file)
@@ -502,7 +502,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);
@@ -887,21 +887,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
index fe3a4de1a4331ff86f0b4f0cc85a48b208bca3b5..4b22ac3413a107fa02768e626ebc055a4efd7b11 100644 (file)
@@ -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;
 
index 9633a68b14d7b95e6151e192dc4326d8f1746df6..025d454163b04ec659f8a42edea4c231e9065a3b 100644 (file)
@@ -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;
index f49f6ac5585c4ff7aabf1ecf7fe3c9d61a4de4ee..b0129e7b29e3067e9f00dfa578da8d13e1b4c7fa 100644 (file)
@@ -832,7 +832,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,
index 5ecf4ff9a05982882691f0f76044c38d21790174..9c00fedfc741614632d25fa29235d367f3763408 100644 (file)
@@ -143,7 +143,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");
index 65f35544c1ec8859018c2afb713fa5120fc43272..a0c60e738db8d7be5e841311832e82f0b45bd7fa 100644 (file)
@@ -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;
index 6bfca74701410050b20d1a136ae5cdc4454b1306..8a75c0bd8a78b1481e30fdab63f2d14bfc64536d 100644 (file)
@@ -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;
index c36321bc87148864db09bd0af4fc38a39cb182f9..d34e331554f3903eaded86cf12fdd4a4ef24507a 100644 (file)
@@ -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) {
index d1b9c34c7c00d86c0e62f6c176ae9ec2a5b5b0e5..7fbad9cb656e70009d744cc3c7662ba481db14c2 100644 (file)
@@ -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,
index f7d729aa09bd40528815817e9f94ed5060bcb8d9..e5edf016a4399f44a84f2e657953b59212d00520 100644 (file)
@@ -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,
index 4b4b0b49626218c087705f90c7090384cbbda70f..8f689f1f61222a91f49f375b217a79b8730c76a9 100644 (file)
@@ -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,7 +1093,6 @@ 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,
 };
 
@@ -1103,17 +1100,12 @@ 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;
index 147b22163f9f6839419ebe3051f492f20fd9e0eb..5137155bf3c0ab7954865108834525e126124b51 100644 (file)
@@ -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)
index 050fcf30a0d2015baf7f244c3a7b4f58b964eca0..b7a18fbee6dc486d95c5380ef2ab66ed05b714dc 100644 (file)
@@ -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;
 
index 8d1df5678eaaa7291eaf64ce71d39d79cccd60ca..d666400479137076353d27e093e4106a75cc7fc3 100644 (file)
@@ -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);
@@ -409,7 +407,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 +415,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);
 
index 90757af9bc73ce578831b620d414dba17cf05caf..df7e2037031a35e88418d34b05f7027e3001fea4 100644 (file)
@@ -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();
 
index 2665a078b6dac94bd0ff07bcfea69b772a9c044c..f7707849bb538697009ca3b68c8296100a67b2a4 100644 (file)
@@ -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,
 };
 
index 999c35a25498f891be3d329ad2342484154f2d2a..b0ad7fcefcf5b6134fbd4d40c80b28cbf82976e5 100644 (file)
@@ -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)
 {
 }
 
index e3132a2ce34d60acb9eb75cdf83ec1506e8f874b..f7b4326a464176f4b6834bc4646440103a39381c 100644 (file)
@@ -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,
@@ -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;
        }
index c7c84d34d97e20308b926077e7ed4ce6e8d77281..88582af8bd89745b7c78332cf415dd0bc9f24e23 100644 (file)
@@ -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)
index a24312fb0228ff1f1053bca27f33c5702d2dc2ac..a1e8bf48b778430d45d46fb9e9de453fb897cd2a 100644 (file)
@@ -22,6 +22,7 @@ struct nvkm_ior {
                unsigned proto_evo:4;
                enum nvkm_ior_proto {
                        CRT,
+                       TV,
                        TMDS,
                        LVDS,
                        DP,
index 19c635663399a2442b670479df18621119595043..6ea19466f43622565052d8600424c948c9705343 100644 (file)
@@ -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 *);
index 85aff85394ac29893b25180d62a6994af266c429..be9e7f8c3b2392fa96643f91391e606196ad7a67 100644 (file)
@@ -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;
index c794b2c2d21e710faa3ac64f70ac970ae69826c9..6d8f21290aa20342c1d50f73aa836feab1266d8c 100644 (file)
@@ -129,7 +129,7 @@ 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);
+               nvkm_wr32(device, 0x001714, 0x80000000 | addr);
        }
 
        return 0;
index 48f01e40b8fcc948126cbc1601b0217c034e7b90..b768e66a472beef8da6f871b6da6bdb471dc2a05 100644 (file)
@@ -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
index d172e42dd2280682d58c3907ed882bae03fa0a2f..4c1f547da463afff3dee772446f92f13b2f4043e 100644 (file)
@@ -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);
 }
 
index 27a4a39c87f0044577a6b72bd4e95c6e4fc1437b..9587ab456d9eaa882eb3e9e9749993dc8fe62e17 100644 (file)
@@ -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 {                                               \
index ab8cb196c34e73202c288c7dc24a14a88a18b78f..c8ab1b5741a3e3c0e93a9943c0b3811b8c646ea6 100644 (file)
@@ -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 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
        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 (file)
index 0000000..dab40cd
--- /dev/null
@@ -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);
+}
index ee091fa79628e1da1864d230731d4dd8e94e5cfa..7ef60895f43a7808229a8d72e27b2b54d67f3d48 100644 (file)
@@ -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 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
 
 static const struct nvkm_i2c_aux_func
 gm200_i2c_aux_func = {
+       .address_only = true,
        .xfer = gm200_i2c_aux_xfer,
 };
 
index d53212f1aa52731dc7929d2b89637d6a5d1c51b9..3bc4d03100767da585ad9d6dbd95483be3174403 100644 (file)
@@ -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
index e1fa143a5625b228a833e79e8b0042b421c5f7f1..542a76503fbd0eb15a689008fd798d5df4b9e7f9 100644 (file)
@@ -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;
index 79cb69f1acf5c68ceedc51623cfc20f58ca94cb9..d9d25df6fc1b5311cb1a97c6517fb3587f8bf708 100644 (file)
@@ -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;
index 58276a48112e5d79a5f9a951a88f89897718f861..a9e9d667c55e9716a5ac3d473f73578a1e930b14 100644 (file)
 #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;
index 6468a765f3d17dc5f4eeb83d54d8c52494105874..e065f7e10cca50579f55845d5b1bac99e85e9f77 100644 (file)
@@ -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;
index 76787a75a4dcc691340c07e27761b241b8e34eef..92c556ac22c7c6818ceae5a290a7dc287818a1db 100644 (file)
@@ -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,
 };
 
index c90474afaebd278ef70a2f3a5cf4fab4edee20fa..74d13969b9ca7c0c5b187c27b77a6780ffb7bcd8 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "../dss/omapdss.h"
 
-static struct videomode lb035q02_vm = {
+static const struct videomode lb035q02_vm = {
        .hactive = 320,
        .vactive = 240,
 
index 346aefdb015fc9b009e9336bb983ae3544489795..8e5bff4e5226d533aa92d74eb9da14ec1958c7a0 100644 (file)
@@ -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);
index cbf4c67c493386261f7d540fc61fdd175d5ef713..0a38a0e8c925c3901da5573f8c20d3f049398c34 100644 (file)
@@ -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,
index 20c6d8fe215a1d9bea70729288d2f54d74fe8661..ac4a6d4d134c14dc2cc11e09f46255f0f5596efe 100644 (file)
@@ -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,
 };
 
index 688195e448c5cc455281c59b49c65884e5509212..142ce5a02542f28862956c2694e7033d37abc9d3 100644 (file)
@@ -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
index bdce4bfdf6e094545fb89636907330d872b0f3ea..197ddbc1512bb2a3f0380ffb2fe4c8321b0c5050 100644 (file)
 
 #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 @@ static int __init omap_dss_init(void)
                        ++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);
index fd7504b37e3bf73ba91a0fca770235960d91c557..0f4fdb221498e3144aa44a760a01fba0d9db5be1 100644 (file)
 #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,
index 86dbb65a6c28d6155c7944a6222a15e4634c12c7..daf286fc8a4082a7fc7f8f8bf6bf38ab74362c09 100644 (file)
 #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 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
 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;
 
index 835f49004bc3eda54438d973e48759bb502cad6a..b56a05730314ffe0257d157ea27d44859829fb40 100644 (file)
@@ -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>
 #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 @@ static int dsi_cio_init(struct platform_device *dsidev)
                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 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
  * 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,
index 99e22ca972c7c3e973a021a19e1aa3352084b751..d1755f12236ba1d43f0b2266c58182993730908a 100644 (file)
@@ -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>
 #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,
index 8dbf35f3ab23e18c72c3979d35ed2dd0f794d67e..085486024089f997f0580a2a5ab2dd25d7c4be26 100644 (file)
@@ -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
 #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,
@@ -192,6 +203,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 +235,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 +251,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 +268,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 +281,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 +337,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 (file)
index 0e59971..0000000
+++ /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 (file)
index c36436d..0000000
+++ /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
index fb6cccd02374649950d70f9d720151a74b9a1132..a820b394af0914719a2983b76868bdd6b6b59ea9 100644 (file)
@@ -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 */
index 284b4942b9ac4826c0f55b870fc67b53f3d6c307..f169348da377ed2798cd604c443ad37f79921470 100644 (file)
@@ -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;
 
index ed60016134055375cbaabe67d0061d7e437cd30e..365cf07daa017e7aab854ba01017f1750b4ef698 100644 (file)
 #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))
index 441e1999d86a0b46122dda722ec9533135ba2bf1..b3221ca5bcd8413852ea1f0df3570adcb6d14337 100644 (file)
@@ -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;
 
index fb5e4c724b4b7bfe8c953af4abcff3dba098cd47..a156292b1820b9a8cce0560dbcd4a13643aeb373 100644 (file)
 #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);
index 46239358655a3287eb15610e4fc47127c61b89f9..55bee81f4dd52a25ef4d9df81087411fa024e7f8 100644 (file)
@@ -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;
index ab129df2e310568c744ca34acd5c7cb2886183da..88034fbe0e9f05402804af57382feee52ed373ad 100644 (file)
@@ -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;
 }
index 85953a0bc7c2facc4ba0ac5a2d45ed13a0494010..47a331670963b2fdffd47a0080e56c09257f3595 100644 (file)
@@ -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 *);
index a6bfb3918b8d3645624764b4f94b9a74fea53740..5bd7788357b22d81b8143a906f136cda5f151c2e 100644 (file)
 #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,7 @@ 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 = {
+static const struct videomode omap_dss_pal_vm = {
        .hactive        = 720,
        .vactive        = 574,
        .pixelclock     = 13500000,
@@ -279,9 +279,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 +296,6 @@ const struct videomode omap_dss_ntsc_vm = {
                          DISPLAY_FLAGS_PIXDATA_POSEDGE |
                          DISPLAY_FLAGS_SYNC_NEGEDGE,
 };
-EXPORT_SYMBOL(omap_dss_ntsc_vm);
 
 static struct {
        struct platform_device *pdev;
@@ -311,6 +309,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;
@@ -693,7 +692,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 +827,12 @@ static int venc_probe_of(struct platform_device *pdev)
 }
 
 /* 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 +842,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;
index fbd1263a29a4a474e6ec5096b9410a12238f17ee..f7ea02a88b1a80e0380780f9e75c9d12d098d487 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "omapdss.h"
 #include "dss.h"
-#include "dss_features.h"
 
 struct dss_video_pll {
        struct dss_pll pll;
index c24b6b783e9a5fbee4184d51dffaa0b7d8ac429f..aa5ba9ae2191c15518ee1aa326165793653912e1 100644 (file)
@@ -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
index dd0ef40ca46929ee192b6e2bcf7fbc9a44721d84..cc85c16cbc2abdf58e044c13840d16bd212f11b1 100644 (file)
 
 #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,
 };
 
 /* -----------------------------------------------------------------------------
index 022029ea69722cd823ca47f519bcb28d8e1e5b7f..9b3c36b48356145f20e2f874149179f1a95fdd97 100644 (file)
@@ -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);
@@ -323,6 +323,32 @@ static int omap_modeset_init(struct drm_device *dev)
        return 0;
 }
 
+/*
+ * 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 +464,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 +510,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 +542,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 +601,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 +614,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 +643,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 +735,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,
index 86c977b7189a567afc2314c7bb4c140a40181a77..624f5b50b75518dd3f094efbc2c943e9e7dc3658 100644 (file)
@@ -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);
        }
index ddf7a457951be4fecd2c43f18ebdca14d0a58c74..b1a762b70cbf8d1a9410966d8496276075a0db97 100644 (file)
@@ -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;
index daf81a0a2899ccc9c616ad0eaad5afef1e661de4..9273118040b740e01f08b127c40aa5cfb7edc1d9 100644 (file)
@@ -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);
index 863a881dd7cd7275ddf7115f851b0e5d0b68fb1b..afdbad5c866abdac8791a9174448144e69a14f27 100644 (file)
@@ -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,
index 2160f64548e03bc028c6f7d9dd36d1aee5ae5745..15e5d5d325c617b8cf00dc84dad5bf299897f24c 100644 (file)
@@ -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;
 
index 3216aa9a88d6c280bf42ea579213e7b2c8b51114..e2d57c01200b291b207e976011e70b71e7be9a72 100644 (file)
@@ -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;
        }
 
index 3f213d7e7692d35b2fb51ad38791f9a572c9bf9e..d335f9a29ce4aa59bbc46219195642224dee7e53 100644 (file)
@@ -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,
index c6ca4f1bbd495bdcf34398d7cdae613ac58d4d81..b58c988d9da0118b4a117f4e1bd852d9b40dfe84 100644 (file)
@@ -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;
 
index ac8771be70b0d6b9d68d85046813e76cb6a9e0ed..581c452cede1df08822a8e0f5932062c3c52c6cc 100644 (file)
 #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,
index 03fe182203ce9122abfe37bc3a1afcc16971ca4c..14c5613b4388a839461915fc448d4772422861a3 100644 (file)
@@ -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 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane,
 
 }
 
-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;
 
index c2fc201d9e1ba87a7e61722bc297b36a5e5c112b..2445e75cf7ea6664854325a6383fe0e32e2bdd57 100644 (file)
@@ -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);
index 3591d2330a09d809490427574b7d2fa03628e7ad..3397a190733693d649794649e35a7c725a251262 100644 (file)
@@ -64,6 +64,7 @@
 
 extern int qxl_log_level;
 extern int qxl_num_crtc;
+extern int qxl_max_ioctls;
 
 enum {
        QXL_INFO_LEVEL = 1,
index 573e7e9a5f986e6af4487f4696b8eef92ad5206e..844c4a31ca1305b131e13a158904b0f60e551178 100644 (file)
@@ -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;
 
        /*
index 0b82a87916ae65b3d871d533bd528c6a47516aea..31effed4a3c823d8509af4338258d76c6ab65764 100644 (file)
@@ -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;
 
index 9a7eef7dd604e07d620c2b4435607e319d8f0f68..0a67ddf19c3d4fe5e091d730afbe20403e1160a0 100644 (file)
@@ -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;
index 87fc1dbd0a2fcfe6b0e350b92b3729b180d98f10..7ecf8a4b9fe6ab5bdbcec36035b05d0fa8441a4c 100644 (file)
@@ -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
index a982be57d1efb44b0638f55faa18621dcdc14fce..0d2b7e42b3a7d876c6879c24017d3e5cc2c08cc6 100644 (file)
@@ -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);
index 3c492a0aa6bd4813ee3683c9fdff8aadb0cf5929..02baaaf20e9d07a09b957ebcc957fc8393bfae41 100644 (file)
@@ -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,
 };
 
index 5008f3d4cccc3522d100348cba5c9860de6322d6..ec63bc5e9de74c2b0d61de04ebc55ae66dfbf382 100644 (file)
@@ -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;
index 6efbd65c929efc28135056c4077ed979e18017c3..8d3251a10cd49edd6ddbbd2ea15ba0faca219ad3 100644 (file)
@@ -351,7 +351,7 @@ static int radeon_atif_get_sbios_requests(acpi_handle handle,
  * 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;
index 7af1977c2c686e7a317b82baad6435dcd0b981d3..35202a453e660320404b84a30607dac6ca817407 100644 (file)
@@ -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
index aaacac190d2688789928a24b0efbc8c92cb5aba3..770e31f5fd1b0c720762aeb8b9eee949c5c01aa0 100644 (file)
@@ -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;
index 27affbde058c626eec6ae5b5b77cd9a2d4601ba9..2f642cbefd8eaa2223205f99bdac474d658a076c 100644 (file)
@@ -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);
                }
        }
 
index 00b22af70f5c093b07462fa084e7854bd18b38ca..1ae31dbc61c64a2fbf30ede3a84fa0ea315fe8b5 100644 (file)
@@ -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);
index 4a4f9533c53b888ab10fb0f4839fc4a5df852bd8..91952277557edfd7fae6913796b11cf72b38d3ca 100644 (file)
@@ -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 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
                        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;
index 17d3dafc8319881eae56c83a1ac1a00b169f945e..ddfe91efa61e4bef713454a8738429898df21053 100644 (file)
@@ -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 @@ static int radeon_crtc_page_flip_target(struct drm_crtc *crtc,
        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" },
index 6598306dca9b87b5a508e921c7e008e9ec43167a..ebdf1b859cb6cb966d9ff34fa13ae56b4f59ed09 100644 (file)
@@ -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");
index 74abd161237b92ff18aa7e682c879d549cacc3d2..f4becad0a78c0b0b13bdf14cb8a0d077ef805841 100644 (file)
@@ -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();
 }
 
index 356ad90a52383a755ffa168c2b7209d449232a1e..fd25361ac681bb3507a9c0f168a16c83b7724855 100644 (file)
@@ -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 @@ static int radeonfb_create(struct drm_fb_helper *helper,
 
        }
        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)
index 574bf7e6b1186fed318cf10f05ff9ed313d671e1..3386452bd2f057239c4ae63bea1eeb6e040c3acc 100644 (file)
@@ -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;
        }
index 7aacb44df2012f7608df560d5c418d26626159a3..afaf10db47ccbc6a4325020a01853dadcce7b11f 100644 (file)
@@ -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;
index 699fe7f9b8bfcdfe052df67c8631a5e9ebda3631..a2ab6dcdf4a25adb9062a1b591827a7dbf457fdb 100644 (file)
@@ -184,7 +184,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
                };
index ce6cb66662127aade60da663e38aedb5fddf3824..1f1856e0b1e06bd8dbd2d613fbf05aa9892f0c50 100644 (file)
@@ -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
 };
 
index 00f5ec5c12c7afba423876584648aa0ce7d05131..da44ac234f6410731d0207ee3d25ed15f8b778c0 100644 (file)
@@ -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,
index 8b722297a05c7f5c3d958285664e3c37c398eb7a..0935949761260ca2351a15a304634898921bf747 100644 (file)
@@ -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);
index faa021396da342b964139577c35c2d0fecce28d5..bf69bf9086bf2acb03509fdc0cf6d52e5442f2fe 100644 (file)
@@ -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;
 
index 5f68245579a3b4d1bc0eb908c096bff2da757d8e..5e82b408d5227681cbe24b615d77f61e6a8a2ecc 100644 (file)
@@ -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;
index fce214482e7209e406c66fd129297ac56658e2e5..b0a43b68776d3659334aa9d1ee59285ab29e23be 100644 (file)
@@ -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;
index 345eff72f581943a6d7b25c63644e274cc2cf394..301ea1a8018eb786e7d210c476f041df2327e9e4 100644 (file)
@@ -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 @@ static void rcar_du_dpll_divider(struct rcar_du_crtc *rcrtc,
                 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;
 
index b199ed5adf3638303371838a321215b68940f1c1..fdc2bf99bda1420c3fb10e0557675e79dbe237c3 100644 (file)
@@ -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)
index d6a0255181ccea6c1883bdb2946c82937aa1b61c..d2f29e6b1112131014e6e9b770565a31a96b9101 100644 (file)
@@ -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);
index 3e048dd98b6421946f7e0c4612b0d991d59e4a45..ba8d2804c1d13b0131a5bf29c2e53c822b90af33 100644 (file)
@@ -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);
index 64738fca96d04acfa0515a020f24ffa07dea036c..2f37ea901873b7b559b92ea9f0ceee7e66950955 100644 (file)
@@ -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.
         */
index f4125c8ca902100fea09090f1725a255f316c310..7278b9703c15184635365523fa32145437bd7996 100644 (file)
@@ -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.
         */
index ee91481131ad15a46eb8c07a05270c80a811f94b..b373ad48ef5ff00ef6d3b534cdc183c8398b0500 100644 (file)
@@ -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,
index 1661f620121005398956028dfc8c291aac96238a..12d22f3db1af0fd992693711080f87a3ca8bee5c 100644 (file)
@@ -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.
         */
index dcde6288da6c9dabf4a340c9802c842b2e5f2d28..61833cc1c6991c3e0bfaaaa8752ef7047545fffa 100644 (file)
  * 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;
 
index 8b91dd3a46e44992971a2f5025329bb124136a1e..f62e09f195de595316972e22df221dad1fbfd6e2 100644 (file)
@@ -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.
index f870445ebc8df025b0ff9b37696d95552b9e1353..2c96147bc44434ccb1f850d7a3aa594024da46d5 100644 (file)
@@ -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>
 #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;
 
index 8861661590ff905fd6e3d315ec1434e3323b6e95..f876c512163c3c93d76f76b33ef5710db3248500 100644 (file)
@@ -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) { };
index 7539626b8ebdf138a8ed860760fd71f700c11220..dc85b53d58ef2e8fb640e90afdac701e6397a1af 100644 (file)
@@ -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;
        }
index 50c41c0a50ef3f989553bc091193b57288a28914..dcc539ba85d65da734d9a94a77bfc6b09d62b05e 100644 (file)
@@ -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
index 9b0b0588bbedbc8becb6d94a6e38c177c3615092..a57da051f516a3bbaed34555d20e4f0521f6acc6 100644 (file)
@@ -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,
index 21b9737662ae9a23e2f7496dce59172a303d2f38..9a20b9dc27c834ab3d92a709dba64d0a4aec550e 100644 (file)
@@ -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,
index f8208489724e02d7953660b27a2247a06a817996..ccd5d595ada7ca207164582368b39753be0ed7e4 100644 (file)
@@ -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>
 #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);
index 7d9b75eb6c44ad0a3262e1a85feeb87213ad952d..7a251a54e7925d5e8e0119c29e2354bc9ca339ce 100644 (file)
@@ -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,
index c6b1b7f3a2a397740d5545671113def5bb2e5519..c41f48ae7913e5c33919f233fad5d90876a12a53 100644 (file)
@@ -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.
index 81f9548672b02734044a08f8ecae300df7edbf87..70773041785bf8b1a34077f1e7c2fae49f71b1a0 100644 (file)
@@ -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 = {
index ce946b9c57a9f36e7c3d50c6e4c00c837565690a..724579ebf947f537ca774fb6229dbb0a653683c0 100644 (file)
@@ -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);
 }
index b74ac717e56a502a647bf3a601c1166e7787ffa2..1869c8bb76c8173677be56c1d68a8364cf80a1f2 100644 (file)
@@ -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 @@ rockchip_gem_create_with_handle(struct drm_file *file_priv,
        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
index 3f6ea4d18a5c4746f0cd8e7b0f16f49f82612504..f237375582fb668053e2082d8a7311a2e2346aa1 100644 (file)
@@ -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 */
index 5d450332c2fd79fd8c1052aca84d7d15c5db3ef8..bf9ed0e639731cf15d0847674856a7082986ac76 100644 (file)
 #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; \
                                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 @@ static int vop_enable(struct drm_crtc *crtc)
        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);
index 9979fd0c22821d7efa3d7054468e0914619e0692..56bbd2e2a8efb95b7ae45ef985175add37abf3a0 100644 (file)
 #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);
 }
 
index bafd698a28b1b491c01823d2be293a41e67c3722..94de7b9f6fde598d90bb19f00bbf9dc68bdfaf49 100644 (file)
 #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);
index cd197260ece5defab17c0448d6cee18001bc14b3..4a4799ff65dee794afde5c0fb77b53479b0a11ff 100644 (file)
@@ -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
 #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
 #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 */
index 78c6d8e9b42c1fc149b259baa62ace6ccdf0f3df..2bddeb8bf457d16f55c965c11c90ff70cf6bfa91 100644 (file)
@@ -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);
index 800d1d2c435d0b7e4954728afc4d4bee9bae58cb..592572554eb0ea1c102432af051bd72356e614b8 100644 (file)
@@ -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);
index 7f05da13ea5ed44729d4d3349a39ce004a23df99..e04a92658cd74c239a467114d5f38132afc8e6e1 100644 (file)
@@ -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);
index d45a4335df5df92a213be2119eb84d792aa59c3f..e8a4d48e985a46ad7a2d6efa7c18b97af4f8df99 100644 (file)
@@ -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)
index 5b3a41f74f21b2da5d130ffba0d8d947d9b44de8..b709ebbec09589f138f9ba7de3cf9bfcbc1856bd 100644 (file)
@@ -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;
index a4b5742832690052c058a2898c2fc0492e8b7fcc..1700c542cd93fb449076f3d135c977bc59068e94 100644 (file)
@@ -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;
index 24ebc6b2f34d1db80fdd0645b34e71badcb1df68..852bf2293b05888919aee4a5e48c396ce3d9765e 100644 (file)
@@ -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 */ }
 };
index 5ee0503945c8bfb3a7224aa509e4fba4af2a2751..b65eea4f2c973ea9b416ac275a08f00cf3496cda 100644 (file)
@@ -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;
index d6ed909d9d75ffb45b61b364aea973d6b8751967..cf65e32b5090a00991e06a583a31214b951a8eff 100644 (file)
@@ -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,
index a59c95a8081b7acce1161b6dca34e027b8975825..30f02d2fdd034ccffc89fa95aa8d94ff5edecb5e 100644 (file)
@@ -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,
index a1c161f77804424e0014c93478f92847559ea484..b19b3430b2962d1d9c25b46bc3341f13827fc015 100644 (file)
@@ -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 */ }
 };
index 2c4817fb08902427df09223b7ab4046241fc6c77..35367ada3bc1562b77f2581958022dae8230859a 100644 (file)
@@ -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.
index a09ecf450218455913b3732921bc8c4c122b3407..d883adc365a2c29b00bf98cdbfae7d11b8841192 100644 (file)
@@ -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
index 83ab48f1fd0087f7b26572b3ed11bc7f8736fbcd..b333b37f3f898a9a666e730f1999272b67518498 100644 (file)
 
 #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 (file)
index 0000000..568c5d0
--- /dev/null
@@ -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");
index 1b9483d4f2a4ec3b80dea15acdd38ca730733381..d394a03632c450e011744c1cf10cc931ea396b01 100644 (file)
@@ -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>
  * 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 */
 
 #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 */
 #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);
 }
index d7a9c736ac1ea4d51f2c98dcf9ab4581375a7de4..bc6d6f6419a93751c4710e2cb9c38e8601df41f2 100644 (file)
@@ -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;
 };
index f8c70439d1e2f030b9173deace6bc1700afa0fa1..d097c6f93ad0188ce82494c63e2d722253a05a98 100644 (file)
@@ -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)
index abc7d8fe06b450084bcd20ec560b62405415ff40..d599206a1e86f989b324c1a240c4122efaa5247b 100644 (file)
@@ -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++;
        }
index 863a516188198070fbb3fba0736ded778b3ab32f..9ea6cd5a1370d92e6eb78c864641986bffbc0086 100644 (file)
@@ -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,
index b0c1155891b42c7fb966eaa057ce7500ac688686..7bddf12548d3f01b580e1aeceb15bd57bcabe88b 100644 (file)
@@ -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);
index 76362c09c6089a6fd242874faa4fc9334d953142..7cd7090ad63adde22826652674550beca7efc4d5 100644 (file)
@@ -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,
index 73bfe7b1cd785aaa1a75d933ba41579f58341f34..050cfd43c7a0f1bad292998f0182bb539fa1bdff 100644 (file)
@@ -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,
index e627eeece65890176468dccfe0b390d7469cf878..23810ff7268412a87edb449a6ac6e559ce5f0cb3 100644 (file)
@@ -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);
index c54138c3a3768f07962e2bed294e9d827f85681f..3a1476818c6530bb95e3854cc87beef2e425fe92 100644 (file)
@@ -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);
index c875f11786b933612e85cdeba677ecb706130954..4df39112e38ec6052beb2165e0550594922174f6 100644 (file)
@@ -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)
index 518f4b69ea5335983ac3dc6d570a4b77c10d46eb..224ce1dbb1cb9eecb0b9b183783ef7ce30198fd6 100644 (file)
@@ -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)
@@ -1075,8 +1077,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),
index 3dea1216bafdcc1f07deb5222b98ec08bd5578fa..e4b5aedfdbd452358398621b46eeaf095439cccf 100644 (file)
@@ -815,7 +815,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,
index 7a39a355678a444d1cf1477ee932339169006957..c6079affe642b8c7e08041c4d84eae7137e2650e 100644 (file)
@@ -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;
index 8b32a6fd586da6c38d9de2556ac887065d3e4a5c..8eb9fd24ef0e5dcf50ab0ac5c9ca0f6d4f251506 100644 (file)
@@ -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);
 
index cda0491ed6bf80f2e77fd668adaff5d1233d7e94..a621b0da4092a93fd28f21c0d7d58aa188d60f3e 100644 (file)
@@ -734,7 +734,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 +902,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,
index a131b44e2d6fba01d05cbe1c90d5d24ce4f7b20c..78ec5193741dd51a6d8de1d7aeefd5ec8c14cb91 100644 (file)
@@ -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,
index a8f528925009e67938dc7e7b84b7d33b418733a3..e0642d05a8d3720824289729e7b89e52360befc9 100644 (file)
@@ -1340,7 +1340,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 +1903,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;
index d524ed0d5146ca8ee0caf9e1a290163af0470f46..406fe4544b83d3351669a91103a0b56207feda82 100644 (file)
@@ -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;
                }
index d67e18983a7d40538b5be1779fd51db9c8613d25..b0d70f943cec56116085f7c3b4740ea30e11e750 100644 (file)
@@ -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,
index 28c3e2f44f647555ef4be9ab45092fa256b27db6..1813a3623ce6012829eb8238a7c9158bebd03b9f 100644 (file)
@@ -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,
index ba0d66c0d8ac8965056026354b5a591e3f6dd210..7667b038ae7fec5162aa392a8c1f2c6882d67c09 100644 (file)
@@ -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,
index aabfad882e2395daa8cbb9d52f6f951367bbffbd..1e2dfb1b1d6b2521895a7f55ff99a02d8082346d 100644 (file)
@@ -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,
index 3504c53846dac49e7d2e12256d1d6f8495b67d8b..2e790e7dced5dc08dea014d58095deba555c715c 100644 (file)
@@ -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.
index 7a3604cf4fc2391fe55796140d82f1ab2802ece1..0c184bd1bb59598d61a2f0529e4998c7e38bd68a 100644 (file)
@@ -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
index d4cda3308ac72b4a1d1858a16b98a8b3d214da3d..bd6cce093a850589f434f349a889715ba169dc09 100644 (file)
@@ -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");
@@ -180,6 +182,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
index ec43fb7ad9e46889b129eb14fd3b1c0c9489317d..177e9d861001ad1d386d7d7c76398174c347fe0b 100644 (file)
@@ -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;
 
index 482ff1c3db61b58e50848eec4eeee3519ac1f26c..7e5bb7d6f655835e39a2fb91db54b960e199213d 100644 (file)
@@ -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;
 
index c83eeb7a34b00e9e74c9d3ef97cd411b7603a315..2caeabcd34588ee202de9f439673a9d591868f96 100644 (file)
@@ -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 (file)
index 0000000..30dc97b
--- /dev/null
@@ -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 (file)
index 0000000..b439956
--- /dev/null
@@ -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");
index 22b57020790da749c4494becbabc981164191ded..cba11f13d994fbb9b51ee99d8beac08cac26d8fe 100644 (file)
@@ -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))) {
index 90a6c0b03afc522a64fd9c79e173981017b64f1d..a7c232dc39cba9bcbbd3ddd9c6d16957fa12cd8b 100644 (file)
@@ -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);
 }
 
index b442d12f2f7d64819faff9eace7bdc51fa199f89..a01e5c90fd87cb548990757bf4bd17b3978f6ab9 100644 (file)
@@ -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,
index eeddc1e48409c87b8f45c1c44d8bdef52802a53c..8715998267730cd3db5511ce9280259854790555 100644 (file)
@@ -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);
index d2f57c52f7db2c74dcba7bcc35a6a3c622009cbe..9f9a49748d176c7e8b53833968daded5ea646631 100644 (file)
@@ -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;
 }
index 2e031a894813678d1e7d84facc90520c1e8d40b8..2867ed155ff6d09974791a69f198d0290209ec40 100644 (file)
@@ -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,
index cd8b01727734fef7f121bd1bd0c9ce97b471b2fc..31421b6b586e76f07b2721b5dfd23c0862cdb4fa 100644 (file)
 #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,
index 4a650036256444ed84d1d2ef4e349236d5eb5f26..b7ca90db4e8044c17f47f2f678ce9ada3e3f5570 100644 (file)
@@ -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)
index db9ceceba30e239c8668e360334d06cf061c38df..dee6bd9a3dd1bb34602c888c0b3c6fd49cc43ffb 100644 (file)
@@ -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;
index a9d93b871a15e3e5172c16661178f16723805c11..0328b2c7b210a0331f8721e93c3b25124ad27daf 100644 (file)
@@ -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);
 
index 4361bdcfd28a2177b762922ebe62ee15d1435fcb..fdae18aeab4fe582d99e576d5600bed3b5afc443 100644 (file)
@@ -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.
index 487f96412d35999a03713dc9e59a4106b740bb6c..3afdbf4bc10b37fcc1a21fc62b21aaa974405490 100644 (file)
 #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;
 }
index 403bbd5f99a9fa97c025f60be11e31a6e043027e..ce1e3b9e14c9ac2e676ad760f653fd6d7091f964 100644 (file)
@@ -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 = {
index 2e0fe46aeb2e19c441509ffbfcd77a2a70590002..519cefef800d91f7fa6eb00dfbe2d5cb58393988 100644 (file)
@@ -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[] = {
index c6b487c3d2b7645b0ae249f0ce40f4795c80bf1f..1c96edcb302be825cb3aeb438ab9a59c63fb6052 100644 (file)
@@ -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 @@ static int vc4_drm_bind(struct device *dev)
        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;
 }
 
index df22698d62ee5ca89f00bcd42b10a6862506a4cf..87f2d8e5c1346c1ccab7292c4c80dc553c48438d 100644 (file)
 #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,
index 5e8b81eaa168b8307f601117f32fd769d9dc446e..d1e0dc908048242749b92fcac689a3333ab5230d 100644 (file)
@@ -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;
 }
index d5b821ad06af63a28d442edc4cc97658a26f67b2..d0c6bfb68c4ee9d88c2a026e5908915d331733db 100644 (file)
@@ -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);
 }
index ed63d4e857624831e9c25d6686554e5e51389002..937da8dd65b8b02168aeee602225c8a3e3fa171e 100644 (file)
 #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);
index bc6ecdc6f10402da5131292593137aa51c9de1a2..50c4959b5bd33efe329119a0aa9fd39b255e098f 100644 (file)
@@ -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");
index fa6809d8b0fe69ed6f7372e48e704449d04b1878..2968b3ebb895714cb8c8faeaf40dff1c996f2259 100644 (file)
@@ -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);
 
index d382c34c1b9e0c6d5b949ca09bf1e8401d44f91a..55677bd50f6610795e3d04bfdeaa245cf9aad0cb 100644 (file)
 # 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)
index 5dc19429d4ae65b316eed20472145ed3232bd0ff..273984f71ae284760a92252bef233329ce17ef55 100644 (file)
@@ -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;
        }
 
index 8c723da71f66c2e60bd0a68249fc8d9fdf15aca5..622cd43840b8c53588396b6d1d82b5d234a69113 100644 (file)
@@ -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);
index 814b512c6b9ad7caa23bb71600d5e4e5128dc8bd..2db485abb186a292cd0c33773a07762e3808fb8b 100644 (file)
@@ -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;
index 0b2df5c6efb4a931cdb6bb9973d8d9ed2198298a..d3f15bf609008f869f11bb132a1a9f0b2f457739 100644 (file)
@@ -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;
        }
index 09c1e05765fa7ea8b64dac9ca21a612d93db82e6..3a9a302247a2f162fc77688bb25ae9ebf86523b5 100644 (file)
@@ -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,
index 18f401b442c2d0c334e1f879a8b9d9b0892d5306..2524ff116f00d922267213d1a4f8554172057400 100644 (file)
@@ -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,
index 1aae0141911239e9d1ff86aa24c55a13eab21af1..5c8f6d619ff382a096d585e82b5ddf4f282366a9 100644 (file)
@@ -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;
 };
 
index 3109c8308eb588e38267e483f947ccbb9aad53f0..8fd52f211e9d9623d0225eb0b549aeac7dd31bca 100644 (file)
@@ -213,7 +213,7 @@ int vgem_fence_attach_ioctl(struct drm_device *dev,
                dma_fence_put(fence);
        }
 err:
-       drm_gem_object_unreference_unlocked(obj);
+       drm_gem_object_put_unlocked(obj);
        return ret;
 }
 
index 9e0e5392b6ecb93cb1d6569c0eaaf7bacb48728f..aaf766f7cca25a96a05f211cceea71c24e1699b8 100644 (file)
@@ -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);
index d51bd4521f170df0ab60472892fb013ff9989c42..b6d52055a11fc5ec180a96481a193c21e9860a5f 100644 (file)
@@ -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,
index 63d35c7e416c4fdd6b45c44e9c2fbbb177b339b3..49a3d8d5a2496d07a5e1cb3d8192ce93d264dace 100644 (file)
@@ -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,
index 3a66abb8fd50b8c983c6b90f1d739883f8c7b363..da2fb585fea4f49c140e3d0ed500bd1088d9ec39 100644 (file)
@@ -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);
index 33df067b11c1bb19564fc6dad0fe7caca928bc90..15d18fd0c64b4fd524d6722c5c30b05189416237 100644 (file)
@@ -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,
 };
 
index cc025d8fbe195096a62a2d426709ba2bcaf28cc5..72ad7b103448b826a85db0645c66fa89c04533a0 100644 (file)
@@ -118,13 +118,6 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
        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)
index adcdbd0abef692d46bf574dcf1c5c130b3510e4d..71ba455af915b78298662ee5daf588bd554984b0 100644 (file)
@@ -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;
 
index c1f2af4ca4ca9ab7b8ea8a775dbe3f6d9c40a389..cd389c5eaef5b74aefd052bdaddc11a27b6d8f31 100644 (file)
@@ -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,
index 35bf781e418e339eae86760c04697b9a1b128d25..c7056322211cc80fa5b42742ffcd496973d19ed6 100644 (file)
 #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,
index 99a7f4ab7d97edf1652aae7a04ec0f8cf51c9e6f..86178796de6c354a32cf1ef35637aa459d8cb7b5 100644 (file)
@@ -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 +
index 1f013d45c9e9a3959dfa19300ba76fc37820592a..36c7b6c839c0dd230752cba96c348b40e2c65c65 100644 (file)
@@ -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;
index bcc6d4136c878ef159e0aeefcf00f294fc565ef2..4212b3e673bce2df55c5c6b71894a97fbe9b7c5f 100644 (file)
@@ -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;
index 6c026d75c18043a9e8f6926e21f3bef917038f8a..d87861bbe971b1d474e1ab2b43cd2097bd2c32de 100644 (file)
@@ -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;
        }
index 4a641555b960b8fc654c6ab89c428e783a61aad4..8be26509a9aa3aac3179ecbb2224dcef90821090 100644 (file)
@@ -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);
index c7b53d987f06c923c53eaafb0fccdd9631ba72a7..2cfb3c93f42ab430be0b36ae78c40897ef75cc4c 100644 (file)
@@ -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.
index 6f4cb4678cbcc4d917f7ec1739f93ba3e4ae21cd..d23a18aae476be3ab181a7a7bd3b8b52e3487efb 100644 (file)
@@ -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 */
index 6b2708b4eafe84c832d41a10f75c2be9e65fc0b9..b8bc5bc7de7e0d4616cbbfe6fbee1d309aa55360 100644 (file)
@@ -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;
index c1900f4390a41efbf5a613fb6f451d391e336fed..f2f9d88131f25ad37d0c018940627630030a4c26 100644 (file)
@@ -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 = {
index 3d94ea67a825e1cf37d9075035283236ebff69fa..36dd7930bf5f9b6587846f19f69eef3759a12ae8 100644 (file)
@@ -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 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
  * 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;
index 5f8d678ae675156178dc306efc2fc83338c390ba..ff9c8389ff21c3b2923c8387455976d5425e33f3 100644 (file)
@@ -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,
index d3987bcf53f843de239f736f9fe8380705685f4d..b8a09807c5de8ebd447af97a56465323672d33d2 100644 (file)
@@ -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 @@ int vmw_kms_ldu_init_display(struct vmw_private *dev_priv)
 
 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);
index 941bcfd131ff7a169472b0b92c62cf7a40e01bd9..b17f08fc50d3fa2306505bedf33d6eea1ec7e323 100644 (file)
@@ -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);
index 6063c9636d4a08f0b908eb54531b8f2efb818bd8..97000996b8dc5122ba5d8109af5b14930b6f4e60 100644 (file)
@@ -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;
        }
index 7d591f653dfa323e5f51f0bfeca58dac44bf5fa4..a96f90f017d16072423a95302779e54444339cd4 100644 (file)
@@ -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,
index 8d7dc9def7c20ba5fe101dd55e5612e4f9e5d631..d1552d3e0652b61a3859ef65a59a12ec501ea1e9 100644 (file)
@@ -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)
 {
index 68f135c5b0d8e0b81dff7dd039ea1a032683f89b..9b832f13681370e38cf3345f1eb6f5415f715c71 100644 (file)
@@ -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,
index 50be1f034f9efa701f2c6feda57fe28d8cf6d596..ca3afae2db1f13068fdbd63ab8a3a1d1675ee6b6 100644 (file)
@@ -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;
 }
index f46c855d274bd391d0c232458b9dd29c39534e62..45244828fc1f29fce54009045fd34f377ba71a3d 100644 (file)
@@ -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 @@ static int zx_drm_bind(struct device *dev)
 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;
index 0df7366e594b32d8d732987727f0bc2f60f60325..b8abb1b496ff5b56c8f3e51e4dc54cbcd0b369d4 100644 (file)
@@ -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,
index 4a6252720c10a16cbf686ff52fd5ca112d55063a..18e7634932649783695a0aba16d7fd494648b053 100644 (file)
@@ -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;
index b56dc69843fc5b6956fa2d1fc1b117e1d678d3d4..0de1a71ca4e082b7deddd010319f648237f05d30 100644 (file)
@@ -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,
index 1e0811f775cb33bff8c2de1734c3fd5f6be38e25..3e7e33cd3dfa46ec226b2fbf50bc925550d1c124 100644 (file)
@@ -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,
index 5fbd10b60ee516de96c48bf5f4eb09558a2b64c8..7491813131f3515690ac79775e2cc027dd061b39 100644 (file)
@@ -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)
index a048e3ac523dc98085aec3ec4351ecc65880145b..7ece0e9058c6a12494afd95daf51b829a30bb6de 100644 (file)
@@ -41,7 +41,6 @@ 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,
index 2c58a390123a1a7c3f8a4e6fd6f11a34f3340fbe..7782725141648360cedd89f3363155da5f7c8d9c 100644 (file)
@@ -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) {
index 960d816ad7f7bac9a66e428a3c3dd6319be78dd7..6a573d21d3cc2ec91ea3d0d0e0ebecda20e4c534 100644 (file)
@@ -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;
                }
index 6fd01a692197af4e70c9e1bb4bfd0bd8ffb4f348..9017dcc14502d7236ff48a03457cb67a7f9d0a5e 100644 (file)
@@ -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)
index 3d911bfd91cf1a8ea67c504f344ecba32acc603e..c9ba4c6db74ca076d0e26426656d238ac878088e 100644 (file)
 #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
 
index 41b39464ded87f6ee3a4b0b302e0df52feddc520..501e16a9227dc001df41d993aafb6fb092116752 100644 (file)
@@ -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)
index f3e35e7a189d30aba1b6619ddba328cbec75a836..aff20f4b6d97ead09453b303eaf4ac3ac94e1628 100644 (file)
@@ -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;
index 6620f15fec228a21ccf6f1b12a5e7dfd7b73046d..8783a064cdcf43b0752973a4693d72ddca4fe4fa 100644 (file)
@@ -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) },
        { }
 };
index 76013eb5cb7faedbf5ec6ca62dca6181afc5919b..c008847e0b20a2accb00451b10fb1c648f67925b 100644 (file)
@@ -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;
index e9bf0bb87ac40c7e610aa28ac23d35dcc3991ba2..e57cc40cb768b7d3b85c761700e3729c2a2deebc 100644 (file)
@@ -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;
 }
 
index 0af7fd311979d25d0684e585ec92f9a65169bdaa..76c34f4fde132cef26d2a76900401dce82a2e23f 100644 (file)
@@ -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;
index 1006b230b236f1c977d1c1a7d9bf32a268b7e263..65fa29591d21641fd1bd4e4484d8daeef56f9bdb 100644 (file)
@@ -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
index 2ea6d0d25a01a33069bce293ab6858947a0cb01f..143a8fd582b4aeb905ea25b416261a5c1f44a6e9 100644 (file)
@@ -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;
        }
index 4842ec3a5451ed479446fc13352405aca45697d2..a9126b3cda61bc95f6a9d1282821ab7552484534 100644 (file)
@@ -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;
 }
 
index c89dac7fd2e7b793217119f2ccee849cf75ebcfe..12822a4b8f8f09b5c080f7338a89e0ea00cbb4f2 100644 (file)
@@ -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;
 
index 3b63f5e5b89cbda662a580c387bfa2d23e2ebcef..3d3d9bf02101bddf06fc6597f107cc3ac8e3beb8 100644 (file)
@@ -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;
 
index 2c64d0e0740f0db0c4427af9d6602bc8aaa0ea24..17121329bb793a615e8969a15327e3f07035cdbb 100644 (file)
@@ -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"
index 0e05f75934c98c7fccb73286d6270a1011c215c6..1858e3ce3993ac35424f005193a6542c3a1ac346 100644 (file)
@@ -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,
index 6b5d3be283c4e7e00f72bb32e550b52ab06e1526..807299dd45ebf0663fbc97b3831bd8f92148ec20 100644 (file)
@@ -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);
 
index 07d1489cd457a6b5445b8b3ba35dad95b1792acc..e44f62bf9caa9f1a45c6699875b885d497bb0a7a 100644 (file)
@@ -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,
        },
index e0ea411a0b2df9563085c70552086946843ba2ca..c02b23d675cbc1540ec47769515da714c784cf67 100644 (file)
@@ -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
 
 #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[] = {
index 64799ad7ebad02a797607470678aa500842ed99f..462a99c13e7a210a74f1d9b2a9c87de7ebc3fad6 100644 (file)
@@ -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;
index 81d4c39e414a4da6b0f8df0ebd8922d371a909d7..137f577d94326a299e0f944edfd108bdc2db31fe 100644 (file)
@@ -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;
 }
 
index 01fc76f7d6602c7b14c5f0cd4ea0c01090278087..c168e0db329ab49b6b59d720cc62cb2b37352088 100644 (file)
@@ -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
index 79c8c7cd70d5c6d74fc2e32cad372f8644233c6b..6e6a1ecc99ddf4b69252b6b4232c9cda6f00d4be 100644 (file)
@@ -550,6 +550,31 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev,
 }
 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);
index e7d4ea75e007c0bd82ef087812524258ec69f490..7599693f7fe9597cb750319ccb2635362c1dc9f0 100644 (file)
@@ -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),
index aa61ec15c1396ca3925ecf1a099fbf91a302dae7..f1bce05ffa135703792f24317db81375d3e4ebb3 100644 (file)
@@ -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,
        },
 };
index a6cb379a4ebcb3060c93eb959aa3071d45f78b37..437522ca97b4b62fd79b8e84fa643ff9c4751ccd 100644 (file)
@@ -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;
 
index 31bb82d8ecd7f19bbee90bd95a83cec7fe5abca7..0eb393237ba2fc74e486d2880f3c6d71d50ccced 100644 (file)
@@ -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,
index db958d3207efc9e13aa1ae2d05fbadce2732c0cd..94a9eefb3cfcad894d13b400a9d3a2281773b5b0 100644 (file)
@@ -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);
 }
index 8ba9bfb073d17c3025206fe66995547433c6a9a8..c551d2b275fdf339310a087bef9c6e821d7c7e09 100644 (file)
@@ -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.
index 3d2609608f589625d0077167fa2e66a00430b89f..c023e2c81b8f2b06443452f91edcc506b46b6d17 100644 (file)
@@ -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 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
 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;
 }
index c973a83c898b487710600f4e4f6441c99595ca6c..7f8fe443df46f5b562ac3b2561e19226e3ab6b68 100644 (file)
@@ -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 @@ int ib_resolve_eth_dmac(struct ib_device *device,
 }
 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);
 
index 08772836fded416e41be8eccfe53cf3e8427691b..85527532c49dbecc05f965c9811b055621f9178b 100644 (file)
@@ -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)
 
 #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;
index c7bd68311d0c5317973ecf9c3fb8fce8fe8ffad4..f0e01b3ac7116f582575bfc5f95f1ed15d68d47c 100644 (file)
@@ -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;
 }
index 6c160f6a5398702d4b73a3c319db3660f472c190..a0bb7e33d7ca4c2460713915fdda1b5a9ca57f5e 100644 (file)
@@ -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 */
 };
index 1fce5e73216be1bc74c23d2773690dc824d0e251..ceae2d92fb08b9c4591d387db8228fafe16b48f8 100644 (file)
@@ -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);
index f05500bcdcf1e35d21a88aba70b013d0d0d8a2cf..9af1514e59448fbf83315a03421048c9f64a14fc 100644 (file)
@@ -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 @@ static int bnxt_qplib_cq_process_res_ud(struct bnxt_qplib_cq *cq,
        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,
index 36b7b7db0e3f9782104ee8b049e674edb830226b..19176e06c98a76cad2112c9d335dc3ec2306b367 100644 (file)
@@ -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);
index fde18cf0e406b9f78e2af96d70077622f3d02732..ef91ab786dd4c77930c49c8673ef9206f0df40ac 100644 (file)
@@ -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;
index a543f959098bd11972383a9d907725c08497a8f4..2ce7e2a32cf0d28094533d38fd6df1480fc799bc 100644 (file)
@@ -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 {
index 29d30744d6c9e37653e872132b7ce5ca3385dedb..0cd0c1fa27d452b9a0edc8eb2f034ec452f93c2c 100644 (file)
@@ -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);
index e16fcaf6b5a3f48792d478b5c6c21944395630f7..be07da1997e68ea0a2bcc157a67a34cbd27bc4e7 100644 (file)
@@ -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;
index bfc77596acbe1ec5c6d8f1346d567b4db0117297..cb7fc0d35d1d14efff512c2ef9101304532121ad 100644 (file)
@@ -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));
index 2ba00b89df6a046bba536cfe889c373d9063ced0..94b54850ec75b7273eb63b961ffe7ebfbc0ee5c5 100644 (file)
@@ -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;
index 650305cc037306923e5e742c02f7977e672a70f9..1a7af9f60c137f916a125588318a182cf535ac01 100644 (file)
@@ -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);
index 1eb9cd7b8c1973da834ed36ea42e7ae61a524c17..6fe542b6a92751863cd6385be0fe0654a346f08f 100644 (file)
@@ -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);
index 37d5d29597a449d23bf34587024b83e4c55bb657..2540b65e242cebcf5b7c9fd60f936bc35bbf019b 100644 (file)
@@ -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)
index c3b41f95e70a5f1c39e89d91e48653fc05e2b20a..d9777b662eba94ed6d917b262f073f911b073059 100644 (file)
@@ -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;
 }
 
index da2eb5a281fa18514064184eaec5a85a476b4512..9b1566468744ed81a922188f220e7ef64629273b 100644 (file)
@@ -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);
index 6ae98aa7f74ebb14f4ce2e9e3cee7c629270253f..5a2fa743676caa3aded77b9a5be3670928454caf 100644 (file)
@@ -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);
        }
 }
index a027e2072477aef12a230fdc79a1a1d6668bf15c..9ec1ae9a82c9843878ea10266b0d5338d8862308 100644 (file)
@@ -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;
 }
 
index e0f47cc2effc36ae40de18961348e6063ef0658b..ae8463ff59a76a3628ee5b7f27b0779a943b63eb 100644 (file)
@@ -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 @@ static void i40iw_destroy_aeq(struct i40iw_device *iwdev, bool reset)
  * 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 @@ static void i40iw_destroy_ceq(struct i40iw_device *iwdev,
 /**
  * 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);
 }
 
 /**
index db41ab40da9cea375b087d02fccbfe07adf0356a..71050c5d29a05f3f6cb9433aafd7e09fbb5695aa 100644 (file)
@@ -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 */
index 56d986924a4c1708216684f776f4705451a65f79..e311ec559f4eb79de0e94aaa0f58861aba2882b0 100644 (file)
@@ -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);
 }
 
 /**
@@ -364,6 +366,56 @@ void i40iw_put_cqp_request(struct i40iw_cqp *cqp,
                i40iw_free_cqp_request(cqp, cqp_request);
 }
 
+/**
+ * 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
@@ -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);
 }
 
 /**
index 4dbe61ec7a77caa87ad7eacc66b859c3412fd708..02d871db7ca56eded6143a741e5879b4fec96d80 100644 (file)
@@ -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;
index 07c3fec77de6a1fcbb3a52a95e4937b6e23ea8aa..9067443cd31151bb501a505e74b06bb56265f1b5 100644 (file)
@@ -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;
index 1e6c526450d9ce8f93f165af1027b937e3db1847..fedaf82601054a38c10c67cc81cf92b0c0612953 100644 (file)
@@ -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)
index 4f5a143fc0a7229a703d0ba99a6fdd1cddb00313..ff931c580557b18cdecab6d86d00297e6c7993ff 100644 (file)
@@ -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;
 
index 75b2f7d4cd95577814a3b9031aff4c0cebf56fa4..d1b43cbbfea7795418d4e2dffb5acaf454552c85 100644 (file)
@@ -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 ||
index 3405e947dc1ebb420b2e2aa3104e1a2ea92485f8..b73f89700ef9eaee928487b374491e863eb4444e 100644 (file)
@@ -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);
index c2b9cbf4da050e22afee4251079f7eece418416a..9db82e67e9591a5f56a540da8b8c96984714cbae 100644 (file)
@@ -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,
index 996e9058e515adf924eb23fd9ef10606ab74342a..75c0e6c5dd5691a2d57f21a80be80e29fb07b706 100644 (file)
@@ -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);
 
index e32dd58937a821a914c3e7d79d2d4482b158db47..0facaf5f6d2376d395a739726b740b1d6f352435 100644 (file)
@@ -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;
 
index 763bb5b36144be84c9ba2eafa7b3ade06fa57f44..2c40a2e989d26bfbe9449d0beb3763a49fa81cf7 100644 (file)
@@ -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);
index ae0746754008798fc0c4ab7e940f736c376a72f1..3d701c7a4c9140e488b7427d9d901a4ea77d2786 100644 (file)
@@ -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);
index 8f9d8b4ad583918dc4a2785b1df33d6eee3b6921..b0adf65e4bdbf4c1e19f4b75c1b805b9d42ef622 100644 (file)
@@ -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);
                        }
                }
        }
index 2f30bda8457a9acea831e0991ff648ba8ec44c44..27d5e8d9f08d38a6a5358885b4315d35cab949ae 100644 (file)
@@ -744,7 +744,8 @@ struct ib_pd *ocrdma_alloc_pd(struct ib_device *ibdev,
        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)
index 548e4d1e998f15bfa5356a96c0419c2b2d8deb03..2ae71b8f1ba8a49f1c2aae0e6c59908ed4063093 100644 (file)
 
 #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",
index 5984981e7dd41b9c681e44bd275e230d19f29bd5..a343e3b5d4cbf1188db5801b0856b13ad08ff72e 100644 (file)
@@ -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);
index da0db5485ddc7129151c10e8ec66cf7aa6332594..a52fc67b40d73ab3e7e3c6659bf050cd16a0035d 100644 (file)
@@ -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
 
index 727e81cc2c8f6ad71b66b486c9b3d581e66e47d0..8876ee7bc326c9d5a05f438830ec1ba0740eebef 100644 (file)
@@ -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)
index c3a140ed4df27a0abf33ce0a032774d250883faa..08f3f90d29123e9f6840b34f72b8aa56b7054b7d 100644 (file)
@@ -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);
 
index be944d5aa9afc1c3d357653275d7c39883d801ec..a958ee918a49f0a8b1e23b63fa20a9d8a4db5e7d 100644 (file)
@@ -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);
 }
index 073e66783f1dd8a4b62f9fc59a84319b507b51b8..af90a7d42b96abb115d647a919e1080530e01ca4 100644 (file)
@@ -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)
index ff50a7bd66d864506ec65aef1b63f45ce5d36e36..7ac25059c40f94aad951b28351cf425ebe573197 100644 (file)
@@ -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;
index 7cbcfdac6529cc5a93f43212a3d05744985f814c..d69410c2ed97bdeceb17aedb2a7fe6049c59c310 100644 (file)
@@ -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);
                }
        }
 
index 7871379342f48fa77b2e6e8279ca774b4c49ad2f..184a22f4802773efc67131093f4ab4fcc89cd276 100644 (file)
@@ -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)
index efe7402f48852195efae4fc70cf843d0398dda30..2e075377242e2baccc54cda5859d5b3ba7e768d0 100644 (file)
@@ -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");
index 6e86eeee370e86602977bbf3f3949bf2d5ac26ef..6c77df34869dfb719d66787f6ccbb7637b042d36 100644 (file)
@@ -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
 
        /*
index 057f58e6afca249744f2d9013021e3c1c5d6417f..93e149efc1f5fc0382b61dcfc9f84d786d8b52ca 100644 (file)
@@ -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);
 
        /*
index 5a887efb4bdf1b6405d3fc4342918084ae420b57..37b33d708c2dd5aecfa9bcc0328fb60876e9c310 100644 (file)
@@ -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;
 }
 
index 12ed62ce9ff7ea36bcb622c5f29577c0b16b9685..2a07692007bddac1b56196839c7e403678d61bca 100644 (file)
@@ -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",
index c538a38c91ce95acf8e00fcdf43fa28588ad2f49..26a004e97ae0fc3d4f7d257e725313f4b75ed82e 100644 (file)
@@ -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);
 }
index 688e77576e5a50b3f2f137eec72cd721d6bf96fa..354cbd6392cdf261ba657548ed2c208a09ddf50f 100644 (file)
@@ -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;
 
index 5cc597b383c7208d69e83d8ec0646e936817d1b4..372303700566f4f984e6656bd937e2d99bf07cc6 100644 (file)
@@ -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();
index bc89b4d6c043dacee88463ba22edc8883f60385e..2d80fa8a0634aba34b366609d8bcc50f432bb31c 100644 (file)
@@ -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;
index af330f513653d2849682b2d4536dd86dcb6a43d7..d665d0dc16e8f787813a6106d15bd83afacc4f34 100644 (file)
@@ -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);
index b182039862c50debf8c55df4aad825cee468eed6..e8018a308868e33a4ea722c0b9686118078dc0db 100644 (file)
@@ -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);
index 524263a7ae6f54c290d9fc017633e0ac074054df..a3e667077b14e12ccca5df742922fe47d4e64005 100644 (file)
@@ -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);
 }
 
 /**
index 5d14cd15198db5cb6361d060abf208260c086ebe..91c6d367ab3593b99a6c9cfb9be01855e8372af2 100644 (file)
@@ -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 = {
index 2a28eadeea0ec3cf2ad363f7076f8555245520a2..c06cc91b5d9a1e63ec0984927b6c7722b5242f82 100644 (file)
@@ -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;
 };
index dad85e74c37c051c02ea1b859db6aa5e66047731..3aae015469a5189a2592087fc40f27767c754316 100644 (file)
@@ -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;
index 54c296401525c1a97df216c2cd045f64c7ce0d60..18d58d2b4ffeb8b50e2df2179e95e15f3185d033 100644 (file)
@@ -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;
index 0a8ed1c05518a9f7c2b08761338c9bcc56258985..14461cbfab2fa234d365a947cc4e3d68e90378ed 100644 (file)
@@ -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 */
index 832ebf4062f7016ae5a808325b7199021f3e6e47..6ab1d3afec02b39f4d8b26e9e30c280b316de156 100644 (file)
@@ -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 &&
index 060d357f107f8c7720b08e6791dc352893c08fff..6f423bc49d0dcfa0a0bd4ef9321213dbd14de07e 100644 (file)
@@ -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);
index 40c7e2cf423bfeae548c484335cf9916d602fb38..034cabac699dc273d34653e73651ea3189483b62 100644 (file)
@@ -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 */
index 8b7ad4f1ab0160aec609cdfb587b73c03d7c2b12..b2023e08dcd28b3c85783b7df51a3e3b35c0e2eb 100644 (file)
@@ -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 },
index e3fa1cd64470ce48ba32ab797f4f063c62293f4b..dce6632daae1c4b5a0f43be11d80b99d995c5011 100644 (file)
@@ -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,
index aea0c9616ea51cfac248e50958ac838fcf72f5a9..3cf07b8ced1c067c43c3aeae463e306ae1b22c99 100644 (file)
@@ -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,
index 5dc246d71c167d5a69f449603cbd4a329a85fa9c..d2e401a8090e3dfde6969262a50a55fa0b1b7a9c 100644 (file)
@@ -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] },
index afde4edef9ae895fa009fb5ad7305cc13af2c22e..6a6d848bd18eefc1d7400a49f64c02960a6b4592 100644 (file)
@@ -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},
        { }
index 3052c836b89f70bc441520e439635a6e91dd2248..d80072fef43415f2812169b2111391b3a6b5281e 100644 (file)
@@ -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,
index c7d68675b02874e3661af07d1b8ad22ae8bcb887..7108bdb8742e7a41b5aac61ada26ad212211fe67 100644 (file)
@@ -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
index 90f051ce02590f3e70ee2e1227d7aa507441a24c..9090cc1e1f299a8b3a3296fa088b2f2cf33ef342 100644 (file)
@@ -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,
index 5a9f39ed1d5d97da6427e327786053f6f9ab5ecd..e4f7573ba9bf6777c5fcd8548e1fbdb298f3a499 100644 (file)
@@ -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,
index 7b5fd8fb1761d1912be615ee14571e420dc4c92b..aaca0b3d662eb18bda0848652c309985d5f6ad0e 100644 (file)
@@ -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 */
 
index 89b09c51ab7cff64d20e24ff43fff8bd720d1ef3..38a5bb764c7b55cb8b742639e49756e413b4ab26 100644 (file)
@@ -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);
index c151c6daa67ee8aa2ae600b4462f146d85776335..f63a110b7bcb2d2257869484bd9b894d94b9b5d2 100644 (file)
@@ -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)))
index 5ecc154f6831e8f17341495ccfde286757960b29..9bc32578a766e1581d315dc23337214d75fd38d3 100644 (file)
@@ -657,7 +657,7 @@ unsigned int pblk_rb_read_to_bio(struct pblk_rb *rb, struct nvm_rq *rqd,
  * 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);
index 4e5c48f3de628d64c806bb21f14c4bd7a473d9b3..d682e89e649351f5811232427a7aeab1009706f0 100644 (file)
@@ -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 @@ static void pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd,
                        rqd->ppa_list[j++] = p;
                }
 
+next:
                if (advanced_bio)
                        bio_advance(bio, PBLK_EXPOSED_PAGE_SIZE);
        }
@@ -282,7 +291,7 @@ static void pblk_read_rq(struct pblk *pblk, struct nvm_rq *rqd,
         * 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;
                }
index 0c5692cc2f605861da62a93de7a61aafb3f09f75..67e623bd5c2df1f69fecd084def0d793da7eab7c 100644 (file)
@@ -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);
index ac91fd0d62c6e4e22c57ab354ceb56adfdaee48e..cbca5e51b9759c57813b8579a2d38318bab39e02 100644 (file)
@@ -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];
index f4eace5ea184095eb0c170c4f3f1647f72b8c537..40f3cd7eab0fc69ef0ea3e79efa079a33fc78aaf 100644 (file)
@@ -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);
index 850ff6c6799449541cf8c0357cf7efa17d9e8c60..44f4a8ac95bd5a3a0f7742291c4827a27e27b3b5 100644 (file)
@@ -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;
 
index 1b224aa9cf15213ac22bafe6f27d2206d37ff1b5..3acce09bba35c54b1afe4e8af962766bfd90eb73 100644 (file)
@@ -1587,16 +1587,18 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map
        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 @@ static void do_journal_write(struct dm_integrity_c *ic, unsigned write_start,
 
        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) {
index 2e10c2f13a34986c9d8d445e1b00ea94261b2628..5bfe285ea9d1c815ae8014064a29e4a08566d374 100644 (file)
@@ -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,
index a39bcd9b982a443cdfdac2013fcbf5ce3561ac4e..28a4071cdf85e8ae15e8741d8770199a689de6b2 100644 (file)
@@ -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);
index 504ba3fa328b2ebb0d3abf40097d297eb08d9de4..e13f90832b6b54256f88d45ba30cee16660f58ef 100644 (file)
@@ -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;
 }
 
index 884ff7c170a0450a308d5405ada1c72de9b76a58..a4fa2ada688365da1f8f3f896bc3475eccc2c9d6 100644 (file)
@@ -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);
index 05c0a126f5c82c6dff4b0d924980654456cacf35..44a119e12f1abd8eb5b4e4ae15689c83a9502536 100644 (file)
@@ -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",
index 2b538fa817f43e6fbc851be50aeb17133f35f3e4..b08bbbd4d9027d8c4a7d07fd5e4786b25462f740 100644 (file)
@@ -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) {
index 8cdca029674975f2d365ef6d17aabbc684c33b8e..c99634612fc408fbc97df9c7c8ef8e028efe2fad 100644 (file)
@@ -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);
index 991f0fe2dcc684a7f0cb2c5c51902b3dc9a19af8..09db034558017e3d327960e8333d5defa35acdcb 100644 (file)
@@ -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 (file)
index 0000000..9f2670b
--- /dev/null
@@ -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);
+}
index 3febfc8391fbd381876930bf7a38447b9346bb48..f50958ded9f0c4dd9982c440b20d4e8854697b0d 100644 (file)
@@ -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 @@ static struct bio *alloc_behind_master_bio(struct r1bio *r1_bio,
        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;
 
index 5026e7ad51d3a8c50bc3803c32fed8c4e026a0ea..f55d4cc085f60daa6b25c9f398e462420dbc6c18 100644 (file)
@@ -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) {
index 77cce3573aa85b40b6e2492ac458405426cdaf6e..44ad5baf320684e61b1aee1549d15b6e68c0a732 100644 (file)
@@ -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;
index 2ceb338b094b2bd41c2a788ed5c9efe448bf1568..0fc2748aaf95a48a4b1fb227d3b80bffe9cea8d5 100644 (file)
@@ -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;
index bf45977b2823b067076eb1e01f741af8dd424bdb..d596b601ff42a6efe27d9e3aa82c0e7521ba2856 100644 (file)
@@ -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;
index 74dc1c32080eaf8d57d837fb93ab6587992e0483..08b619d0ea1ef7f24f93771471366a340517b764 100644 (file)
@@ -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);
index af694f2066a2f4b34f710952e02878783dab4e72..17970cdd55fa75c99e21481b1213c21461670ff3 100644 (file)
@@ -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;
                                }
index 1e4bbbd34d911fc5f22b2421f3b45a385c094c07..82617bac08756ead4992822f563c6fa10333042d 100644 (file)
@@ -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);
index 08f67d60a7d9f644b7d59fd847036ae4a8224f13..12bff778c97f67c23f1c451ff050707686266824 100644 (file)
@@ -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);
index 4442e478db72a2420207efc2deca49d56c92c30c..cd69e187ba7a9c0eea95855531a82db3e09a528b 100644 (file)
@@ -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)
@@ -449,19 +449,6 @@ MACROS
 #define DRX_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
                        ((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
 */
index ef3021e964be89e61eeda59daa38d1e71fa7320c..cb486e879fdd3f50925dd8431a4d0a4de0e09d4d 100644 (file)
@@ -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;
 }
index e726c2e004601988a4af69559d4dbbead03d286b..8ac0f598978dacb8ed441bf6cc816a8b6bd5a463 100644 (file)
@@ -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,
index 6e313d5243a0352791b7cd2117da5e0aaa8990a7..f39f5179dd95792b5414a3132b8ccdf730abaded 100644 (file)
@@ -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         = {
index 9da4bf4f2c7a73222043088ba68be4e2c0051108..7b79a7498751981e424bbe4d515f3463c2953975 100644 (file)
@@ -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;
 }
index 9420479bee9a5ad324b0344541e0905495cfe91c..cd1723e79a078a650e6777206ffc417d9c83f4bb 100644 (file)
@@ -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)
index ce69e648b663a934f5ace1c834e8c0b1642d044a..8c92cb7f7e72f7af8ca6411ec60db81c8b95bbaa 100644 (file)
@@ -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)
index cf39fcf54adfb812ca691caa68e09ddcbb434947..fbf36353c7014b9f3424a850585b82d147177e3a 100644 (file)
@@ -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;
 }
 
index 10d8f74c4f0a50a4f282b0211b8bb0b616919d5a..7c7cd217333d8af262e802081fb775ea4db2f7b4 100644 (file)
@@ -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;
index 2a044be729da278ad8e2b40dc90039a05968900a..e7bd2b8484e3dea151da347a9c369eedbabacfe5 100644 (file)
@@ -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;
index 1313cd5334360342d776cee365c53985c82599d4..fb1fa0b82077fa61b808ac515968bd14286097b5 100644 (file)
@@ -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---
index 25cbf9e5ac5a749bf4a8a7c2f47a6b36cd6843cd..bba1eb43b5d83ca7dd908ac9834a6f2975869476 100644 (file)
@@ -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,
 };
index f92cc7df58fb8e64d039217dcb5fcba5fe60d479..829c7895a98a2b60efcca128075017ea0f988403 100644 (file)
@@ -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);
        }
index 40fe22f0d757327f03b8e9dce43546a745da9b6a..c5f504d8cf67f8f89350d29db3aeb9bfaa3ad15d 100644 (file)
@@ -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);
 };
index 8f6688a7a111cd0a5dbf9cf7370f9b97a1fcde52..f1b521045d6418d9cde3946490e3e91c7243619c 100644 (file)
@@ -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);
 
index 73db166dc338e5b352e9718950fe1739e42115e7..6d492dc4c3a9cb0029d16b23eecc86dc3b4db230 100644 (file)
  * 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,
index 740fbc7a8c149172202c082576fdf159b6ba5bc7..3b2d8a9317b8d872c894cfa46defd4006096ac59 100644 (file)
  * 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,
index e3fe3e0635aa87806abf4b15e4ba83264ec8b557..b1bf4a7e8eb7a846cb11b1d65a9d40f7d6a29267 100644 (file)
@@ -280,45 +280,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 @@ static int vpfe_s_selection(struct file *file, void *priv,
        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)
index d78580f9e431f669797ce816a928f579cb956793..4be6554c56c5245fc75eb99c22ba2be9d386a33f 100644 (file)
@@ -1719,7 +1719,6 @@ static __init int vpif_probe(struct platform_device *pdev)
  */
 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]);
index b5ac6ce626b3c664ab7ac9b1852ac327c6663721..bf982bf86542accce57aa97efad2edaeb634e832 100644 (file)
@@ -1339,7 +1339,6 @@ static __init int vpif_probe(struct platform_device *pdev)
  */
 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]);
index 92c4e18263566888abd32837f656e4fe7105fbf7..45a553d4f5b2fb6d27c6e0e0efc2eb8c1edade39 100644 (file)
@@ -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;
index 80c79fabdf95b463b49743515488d18c7fafed9b..56b630b1c8b436f760183890cb864730754c7339 100644 (file)
@@ -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;
index 776d2bae697934f02d3ce70fa1adfe4c1d35966a..41eef376eb2da69dfa710a1d5113b123998e1b4f 100644 (file)
@@ -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 @@ static int venus_probe(struct platform_device *pdev)
 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 @@ static int venus_runtime_resume(struct device *dev)
        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,
index e542700eee32147ee7e58cceb7cd8e17c4d3d995..cba092bcb76ddaf5e43f6e499e8365824fbe8e07 100644 (file)
@@ -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;
index 1b1a4f3559188ce208603c6c0ff88af938258f23..521d4b36c0904d1e6f25e8db688216108ad61c40 100644 (file)
  *
  */
 
-#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);
 }
index f81a98979798c9b3136f4db5f7ed11c14eb3a04f..428efb56d3391d14f66aa8938e691cc226e42868 100644 (file)
@@ -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
index f8841713e417268a1955f902d04519a47daf49fb..a681ae5381d6cd43ef736280b7199edfbca5e40c 100644 (file)
@@ -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:
index 7af66860d6240cca3cf44e9b8a2ea8724920481e..2cc289e4dea1db9c02d3f4ce161a23f99034ef02 100644 (file)
@@ -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;
        }
 
index 14cb32e211304f834ff24aef76ad40253fbbee43..88a1e5670c725101999be6e99febaff7aebe8770 100644 (file)
@@ -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);
index 35b15bd4d61db32d5263aa21e23c6c863ef01c7a..033a131f67aff124a15fc395a25fcf20d182b3a6 100644 (file)
@@ -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);
index fe77505d2679c1ef0a5af2aba3ef1ecc9884091a..0a3e086e12f32e0474a30c7add7ecc53de76c818 100644 (file)
@@ -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);
index ebdbbe8c05ed53aa4372b1300b044e6d5b25b3d1..615c2b18dcfc87ebd14717001c3af31b7a4c5485 100644 (file)
@@ -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);
index 847963b6e9ebd016deda060d81450c95ed817dfa..78ef838416b303a971cccb526031b78a829ccddd 100644 (file)
@@ -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;
index 85362c5ef57a4ce9efea182698b26bc1dd4367e7..e8fd2ae3b3ebd28278e831299acde0269d7a02a9 100644 (file)
@@ -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);
index 828a3fcadea8b7d073f6a6724ff32f4ed5ea80c5..c98ed96d8de63a4b3ac0b9f91d07d43e57c58776 100644 (file)
@@ -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__ */
index aaf17b13fd7875f29c6c966e4caae234cb4d29e6..8b5cbb6b7a704651117960d2ff7bd95a24ca4e7d 100644 (file)
@@ -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);
index 6ec1380a10afbf6e2cdbd037a589d284a036fbd4..ee3508172f0a7fd4b4fb17082c48caebb64aaa6b 100644 (file)
@@ -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);
index 9377aafa8996a8d839db535c455e5e619e2d79ab..4dfbeac8f42c90c97cb63308efbe84e352c035ee 100644 (file)
  * 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;
 }
 
index e9f80727ff92140a41d08b83dfd0a33c12dcc54e..1cd9db785bf7fea319962c1bb033e305e1853e9c 100644 (file)
 #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__ */
index 95c26edead85291f097a4850a08c95e5490ce50d..962e4c304076875f6731d52336e064879f239685 100644 (file)
@@ -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,
@@ -705,11 +717,38 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
                .wpf_count = 1,
                .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,
index 4bdb3b141611a6dd8450e8e8a9e46147a570dfac..54de15095709d24def304b5d7839cd36a7c89caf 100644 (file)
 #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 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
  * 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),
index c169a060b6d2d28fc6b6c42fb02a76adfeea6a97..11f8363fa6b0f6fdb086d0584678878740291f58 100644 (file)
@@ -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;
index 702487f895b39e293254ed806de279f7933f5445..e6fa16d7fda897d342ef99274d31cef4948a050e 100644 (file)
@@ -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
index 7b35879028de0436b3b9a58e0e444ecdfcbd51ad..3417339379b110fbdb7cdfa1e726ef3c64f4eca0 100644 (file)
@@ -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__ */
index e817623b84e04632440d5d5155b56f96c7345c5e..4f4b732df84b0fa185046789161e7c6efb117fe1 100644 (file)
@@ -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);
index 91a784a134221d4e0a54e18bd256ae156b76043f..c5d01a36537076c84c07583fe47c6ead60230c36 100644 (file)
@@ -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;
index cd3e32af6e3b5cf572614b129578cb9e1db3c085..58d0bea963a665008726ab5f18a55292b22ceace 100644 (file)
@@ -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
 #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))
 #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)
 #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
 
 #define VI6_HSI_CTRL_EN                        (1 << 0)
 
 /* -----------------------------------------------------------------------------
- * BRU Control Registers
+ * BRS and BRU Control Registers
  */
 
 #define VI6_ROP_NOP                    0
 #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))
 #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)
 #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)
 #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)
 #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)
  * 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
 #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
index 5af3486afe07f87d51d1cade1af10fd22eb4c5ba..e9f5dcb8fae5fa8c639c713472650efde14408a7 100644 (file)
@@ -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 =
index 32df109b119fc353767b5c0b8a16702a5c4b1d64..b6c902be225b779e4a04beab8a1151862ad7c8b7 100644 (file)
@@ -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);
 
index 7240223dc15abae5a9dd00cf6662beaec8e2f196..17e82a9a01099bf6cc5f01b2ce4ab08a0f6b23a8 100644 (file)
@@ -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__);
        }
index a30af91710fe675183b8fa5dc915bc2e3181b308..d2223c04e9ad08ddc93065e5fa3802bdfa0805d8 100644 (file)
@@ -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:
index 192b1c7740df23f99b77230643a5e4b1ccab34fa..145407dee3dbb8b2f0f73804d7a251d300e3abb7 100644 (file)
@@ -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);
index 353744fee053651bfb3b60c610dd89565cf0cbcf..dd59c2c0e4a529a60b8e68965d3c0a51be7141b0 100644 (file)
@@ -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 */
index 9ec919c68482df5c5c97e4a41d421f71411422ee..9d82ec0a4b6409a0e445b653758bba6762242533 100644 (file)
@@ -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;
 
index 594360a63c1871bffdf092a61a3613c476ce4a08..a91fdad8f8d4b6407fe8cf39c4a7d7f500c65fef 100644 (file)
@@ -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)
index 08acdd32e412945765a0760eaca32396bed47350..bea1b4764a66773850387cf4b7acf8981848b324 100644 (file)
@@ -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,
index 146341aeb7823458a8e019342a2d67f5796030b3..4c57fd7929cb4c71786956650ebd7ea869401219 100644 (file)
@@ -1188,6 +1188,22 @@ struct em28xx_board em28xx_boards[] = {
                .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_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 |
@@ -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),
index 82edd37f0d733ddc263b5be4883ac314c133eaa3..4a7db623fe291031cec327a3189b866ffa14e843 100644 (file)
@@ -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 */
index 8c472d5adb5091985971eadb73e23f077fa45a77..60b195c157b807486bf87aa5a1b6ebd60e9754cc 100644 (file)
@@ -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;
                }
        }
 
index eba75736e65406a39c547df442ebbb5835836cf6..ca9673917ad5a74b6a2321b330ff6e17099a73a9 100644 (file)
@@ -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;
 
index e8d97d5ec161b5ca1b7a700a6c2073b9cc3414b8..88084f24f0337036d5313e6ab145a18fea553eb7 100644 (file)
 #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
index c843070f24c13247f6de3c8a0c866895b815e178..f9ed9c950247d84e38287ea1263b3e366826b47c 100644 (file)
@@ -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)");
index f203699e9c1bb086dbb5924bb37625244346e3b6..65692576690f0cb732d4386e884a8a58f60ee83c 100644 (file)
@@ -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;
index 985af9933c7e093a1d4017d04cb52861b6212992..c1d4505f84ea2774995da203f69dbf30320b199c 100644 (file)
@@ -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;
        }
index 6e7fc36b658f9b09786240f98046792c4ebca2a5..90d4a08cda31637fc47e5f9a3d8286cebbb613e5 100644 (file)
@@ -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 @@ static void stk_isoc_handler(struct urb *urb)
        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);
index 0284120ce246b011cd1d4272091dd9039cc2dbe6..5cecbdc975736e752f04227d02645dd739f7316d 100644 (file)
 #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;
index e48b7c032c951eb9fc9f382ec615677b4ed8897a..8db45dfc271b2823d97da42ecbf44c02d6322152 100644 (file)
@@ -43,8 +43,6 @@
 
 #define UNSET (-1U)
 
-#define PREFIX (t->i2c->dev.driver->name)
-
 /*
  * Driver modprobe parameters
  */
index 8621a198a2ce3eae317e4007cd6c533b56cfecc4..bac33311f55a6d7a6699b362c39730fae9c4f107 100644 (file)
@@ -215,6 +215,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.
index f811cd52446852beecfedf02b7100f4bb6789169..e38a5f144373451fc87007ffc1cf4292059c5408 100644 (file)
@@ -137,6 +137,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.
index 8ac59dc80f23e51b8449c884611396376000e5a4..f1bbfd389367ff4530137be199c4063c65f97f5c 100644 (file)
@@ -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) {
index 4ffea14b7eb645d92a91d62907d64c97cf8a9998..2bae69e39544452dc323a9a3bd15ae9b3e7de1b9 100644 (file)
@@ -1289,7 +1289,7 @@ int mmc_hs400_to_hs200(struct mmc_card *card)
 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)) {
index a9dfb26972f212587e9d6af2b223c39403a65af8..250dc6ec4c82df50f4dabb72a7e2486f093c83f9 100644 (file)
@@ -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))
index 7c12f3715676fc0e23855a01c4d8dfdc1365c742..2ab4788d021f0512082c6bd67d1edaa57ba61379 100644 (file)
@@ -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)
index 7611fd679f1ad83d7dee4052aebb6e9f6d3168cf..1485530c35921744a5fac79f53e2f35c05e1b51d 100644 (file)
@@ -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;
index d6fa2214aaae8f967bf34230f7d784b4c598718b..0fb4e4c119e10682b2a2860f5389cd6350bcbb82 100644 (file)
@@ -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)
index f336a9b855765e5ea236fddf9564f5f084793597..9ec8f033ac5f077b05fdfc32a7f97f1747339ca8 100644 (file)
@@ -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;
        }
index d922a88e407f119bbf52aae494c632e08d113e7f..2c8baa0c2c4e11f2b5d1c39d4c3ad795d634135a 100644 (file)
@@ -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);
index 55a8ee5306ea992f39bbcd0c2cbaa5e40ad90214..8c210a5776bcbea1677e422dc3f06397c831d9cc 100644 (file)
@@ -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);
        }
index 5fa5ddc94834d0a27a8add0125ed27310601af09..c6c18b82f8f4eade18561edb24439a9d4737efa5 100644 (file)
@@ -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,
index f06312df3669c18cb788fc033acf6b5811db8d0a..7e36d7d13c268fc2317c330f7688e188e81d6bdc 100644 (file)
@@ -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);
index d0b6f8f9f297ab89f355a727c333de1c5a2f7fc8..6abd142b13246f1189e189c03d3ff499665c1b0b 100644 (file)
@@ -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
index 7c754a0f14bb5327b6e590ae6f31755a3762034a..19e4e904c9bfcf5bb1ccdfba3faf2b60ced9e7e5 100644 (file)
@@ -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
index 90b8995f07cba08ad9c0dfb241916da10eac7fcf..2fe96c4701126300dc36adfe43801ec2fe81465f 100644 (file)
@@ -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);
 }
 
index 14ff622190a5b90c827c1be8a0bd9ca54821ec4f..9bee6c1c70cca33941ae8db8002d69e760693bac 100644 (file)
@@ -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);
index e68d368e20ac84b636c9d62958c084ad80371787..7f36d3e3c98bc6727e765fef9fbc56bc8e695240 100644 (file)
@@ -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,
index 1e46418a3b74c3f351068fd6d1a3b3b5168e8ab2..264b281eb86bf1b52abb88ef67c2ce7143ba6024 100644 (file)
@@ -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);
        }
 }
 
index b83d76b998023c38c9e67b90ca73e393f7d29fc4..74db9822eb40437a92bc21ace75971df48c1bfa4 100644 (file)
@@ -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 | \
index 53b088166c28388d700e80a81df10d828f1edc90..5bcdd33101b00d0b492f87b2a3dc3e67bcf14f09 100644 (file)
@@ -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,
index d3906f6b01bd1f7e34f3182ebc14c9bdbbe672b7..1d307f2def2d910eff7c983d9866fa88b331d869 100644 (file)
@@ -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)
index 041cfb7952f81d71278279454a394c9754e0fb97..e94159507847b33962f99d63561301b924fd2dd1 100644 (file)
@@ -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:
index f411936b744cb1fa4d331f7b439a181916fa118e..a1125d10c8255f6eb8fbb6046b09473c35ba52b8 100644 (file)
@@ -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;
index 5333601f855f88529c04e003eae5e3d19aa59f6d..dc3052751bc13ed2248c218de01849d865dbe952 100644 (file)
@@ -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++;
index 73aca97a96bc70fb1e79f04ec2585589d0616cc5..d937083db9a4af74455156f389b50aee0b0fdf04 100644 (file)
@@ -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,
index ba4d2e145bb9bb81c32ade2e3855743e493c1c59..48d672b204a4847bc113635ed9534d8a3fd53066 100644 (file)
@@ -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);
 
index c1818766c501f8a33b309495b02566c2c1a1cb5e..443d57b1026417b4feccbc79f562cc5462e90652 100644 (file)
 #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 {
index 43423744fdfa8151b2312bc84b41267965d6c92c..1e33abde4a3e8c833386df176896ad9684c9dc10 100644 (file)
@@ -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,
index daca1c9d254be4b4f2b513f1754c7534c104c757..a981c4ee9d72deab705231088043e8690853d563 100644 (file)
@@ -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 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
        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);
index efd07020b89fc3a7bd3c68fce1bbd7fe406acfcf..3a34fdba5301185e9939dc2feff52bef4f3ea68f 100644 (file)
@@ -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);
index 071fcbd14e6a4e17534950107d5081662eba5c3c..30cb97b4a1d7a27f4be917e4d718f86d596734a5 100644 (file)
@@ -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;
index 28ecda3d34049342b6e58c108dd22679cb4ad8cc..ebd353bc78ffa1ea6ed3673d95b0cf365d8eb054 100644 (file)
@@ -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;
index a0ca68ce3fbb164ea6e6a2c75a36a8c1ae54172d..5e5c4d7796b8882168eba6fe858ac4bfff2aaf53 100644 (file)
@@ -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;
index 6b7fe6fdd13b9b27b4a1573e8c7b3869b17bcc19..23acdc5ab896306f3f1e6d2fbc7d8afb58273888 100644 (file)
 #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
index 50517cfd9671574c630b676ecec2892eb304b4d9..9f9d6cae39d555057ba63ac6ee874d0884c0c51d 100644 (file)
@@ -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;
index 99987d8e437e2a09c3ddccffae916dd2804a0020..aa28299aef5f64d222f087f33965cf7ce8ffa008 100644 (file)
@@ -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:
         */
index 95bf5e89cfd17b30d3543b33cb069f8aaee69d31..34dae51effd45a19c9a2b8b607dafeaec3aa0456 100644 (file)
@@ -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;
index ff864a187d5a71fa277f2907659621b9f87ffdcf..a37166ee577b71f4fc2ea07e82d1097c19b4bf66 100644 (file)
@@ -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);
 }
 
index 7a8addda726e3937d3d8813c08e7555a2b9bb278..408b63faf9a81ac9d4bb3e78af3fbfdeb4dbc407 100644 (file)
@@ -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;
index a3e6946796350d0a3bb79410d1f354a844ab7f60..c45e8e3b82d38da950a7cf1ca72022d120b7947e 100644 (file)
@@ -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;
index b936febc315a17b3d8db0af05f60938d478edefd..2194960d5855c6576ec03c870479344b099ce12b 100644 (file)
@@ -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
index 084c5358279319ed6d826aa00f135adb98b7631b..032f8ac06357aefa7a695c6685b8bbbbf7a8949e 100644 (file)
@@ -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);
index 5794d98d946f35c132f010b58368a15b5534070d..9c94ea9b2b802306c0286472c2255571e8e3ed36 100644 (file)
@@ -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;
        }
index b3d0c2e6347a636aa23a6f637233d27d7b55f646..e588a0cdb074040fe83ba8caaec9cd30c4189689 100644 (file)
@@ -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)))
index 249a4584401ad487629c03b92a52f728d3318307..b651c1210555bfe02ec7393486dff9291651afb8 100644 (file)
@@ -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 @@ u32 mlx4_zone_free_entries_unique(struct mlx4_zone_allocator *zones, u32 obj, u3
 }
 
 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 @@ static int mlx4_alloc_db_from_pgdir(struct mlx4_db_pgdir *pgdir,
        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;
 
index fa6d2354a0e910ee160863e3cbe21a512d77bf03..c56a511b918e034e10fdb055c77785ea4a90b27a 100644 (file)
@@ -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;
index c751a1d434ad7167e6b65a62f46b7295044860f8..3d4e4a5d00d1c5f81267c4a4a9675bc667709211 100644 (file)
@@ -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;
index e5fb89505a134dbbfc54ee8af136432e9dfcf573..bf1638044a7a89b6e911b3f5786c75597f89f2ba 100644 (file)
@@ -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;
index 4f3a9b27ce4ad647a8a932001f5b2e16e3525b92..73faa3d779214d86d3c653f9065518375039c7ce 100644 (file)
@@ -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;
index 37e84a59e751d8ad44c34f5a0c7b16337a207c9e..041c0ed6592909a2d7b99cbaa51fc6cc59b7096b 100644 (file)
@@ -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);
index 5343a0599253b98d6f2b9b77b65210a4e1e0abf9..b52ba01aa486a0b492cdb623cbe253c7a2e583d0 100644 (file)
@@ -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 {
index e1f9e7cebf8f7adcf0a095513086b949c246aab6..5a7816e7c7b4e1ad129f176ae148d217cb5e86e6 100644 (file)
@@ -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;
        }
index 0c73645501509d752f8316da7c72fefe8deb03f9..dee67fa39107f890508e158e56b680af6496d74a 100644 (file)
@@ -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);
index a27c9c13a36ed11d577e7cd9cff1e2a9daec137d..09b9bc17bce998a99f360577a92a0211b552bf38 100644 (file)
@@ -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)) {
index 30616cd0140d573573f5f334b937522a9a7c0974..706d7f21ac5c10b439ca3f9398c855488604a50d 100644 (file)
@@ -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);
index ce852ca22a968673b46d3f92d3a1ab3e526864fa..24282cd017d37e32d1653b1c3cb0bde1cc1af80a 100644 (file)
@@ -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;
 
index 5a310d313e94d08d035c265e6b538c27dcf957c3..26747212526b074ea0fd4f8c6a0a274b34bb5033 100644 (file)
@@ -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 @@ int __mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn, gfp_t gfp)
        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;
 
index 812783865205715e8e88ad66d4ccbfe7172ec6e5..215e21c3dc8a8ac80bbf4e7fa0735bcb24c7df33 100644 (file)
@@ -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;
index f44d089e2ca607e8b18cf46fdf0f713424171fe5..bedf5212682464651fe51d2a12a6ed41a8777f6d 100644 (file)
@@ -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;
index f5a2c605749ff2dad1db091bb93d3b6957fa4058..31cbe5e86a01300bacd92db829d9ddc186e5db7a 100644 (file)
@@ -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);
index e1b7ddfecd011436c1520edc93eb30e8e15221d4..0039b4725405fcf0a961fa53eab250adc2d51f3c 100644 (file)
@@ -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 {
index 66f432385dbbd5ea6ce3ceb256abb7ce6dada7b0..84dd63e740414e75d5aa5ac1ebf871c801718bda 100644 (file)
@@ -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);
 }
index bdd82c9b399262428247471798e7fd4dbf03ca92..eafc59280adae527374e321b3cfcd8549ac140d8 100644 (file)
@@ -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",
index 1eac5003084fb9d131392ab7e87ec82d7c4d20b7..57f31fa478ceee5b83a3b4041cfef12457acbd03 100644 (file)
@@ -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,
index af51a5d2b912721222fa2434e7919231ccaacdcb..52b9a64cd3a20be3eb8a8e5beb1990d583d2db93 100644 (file)
@@ -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))
index 89bfda419efe96efc1778ec832ff0eac56588cc5..8b18cc9ec026f99d68d23626bde3d695fa1aa895 100644 (file)
@@ -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",
index 1ee5bce8590118a2075bfd4ce2cc52d0da8c1f27..85298051a3e4fcf74767196dcc6660114222b4cf 100644 (file)
@@ -178,8 +178,6 @@ static int mlx5i_create_underlay_qp(struct mlx5_core_dev *mdev, struct mlx5_core
 
 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 @@ static int mlx5i_init_rx(struct mlx5e_priv *priv)
 
 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);
index a3a836bdcfd29c18e2ba46822a559c8e6982d7fb..f26f97fe46666ff7a3f2ce6c496cb8936ee5cbb3 100644 (file)
@@ -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,
index 6a3d6bef7dd4a4a99d6e8427a0a35a78c0b56d20..6a263e8d883a6bae2791a011026e03bc0cd1dead 100644 (file)
@@ -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);
index bcdf7779c48d79ffb85f3505e122210d16e9b46d..bf99d40e30b4e07a234ea68366d226267d365d7b 100644 (file)
@@ -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
 
index 383fef5a8e24203e20137671c0924f7cc7cbfbf3..4b2e0fd7d51e0a6635cdea75055eec9365d21588 100644 (file)
@@ -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;
index 656b2d3f1bee0e8aa5b1f328d5066d60f5e96099..5eb1606765c58064a5e2fd6677a791165c18c071 100644 (file)
@@ -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);
 }
index 18750ff0ede6262d1a5fd50b8acc808c12a50756..4631ca8b8eb2780865bc2eefae51ce5c5a61f5cf 100644 (file)
@@ -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);
index 9da91045d167b095ad2bb45f5bd3fa1a89255012..3eb241657368e33cb6bc7b25afcecee931a24366 100644 (file)
@@ -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;
index 746d94e28470f74a1b0e546fbce0eac6b344a281..60850bfa3d32e5d574bddacda871cb75da2076fd 100644 (file)
@@ -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 = {
index b607936e1b3ec4ae93225106ac0eb53e15c892a6..9c0488e0f08ec2af6e075acd696c54900a648325 100644 (file)
@@ -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;
 
index 22cf6353ba0418ab5c64ad1fbb343c797d82f18d..7ecf549c7f1cd594f86f165c02743f415f7ada85 100644 (file)
@@ -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);
index eef2f222ce9a87f91a1d02fa6a6c7354486d4231..6502b9aa3bf587d0095816052066ce301a765634 100644 (file)
@@ -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);
 
index f233bf8b4ebb844d9b27ca8cf01947f066e5ba03..c4407e8e39a35a523bda481a9cc1787ab24bc608 100644 (file)
@@ -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 },
index 9091df86723a3988075cbda535d5d6ba21826b7b..adc54006f8843a5bb2081de064291068e66fcf28 100644 (file)
 #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);
index babb39c646ff2f64c96880b437cbca5fc5668453..af30b4857c3b9352d4b9745ebdb07779b7621afc 100644 (file)
@@ -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
index 1853f7ff6657562cc95e78bdf7954aa8203a7ccd..1763e48c84e2090678f4ffc1b55cf1d7a62382e4 100644 (file)
@@ -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);
index 46cb7f8955a22ebf9143f18f993e2bdfd2aaf752..4bb04aaf9650e3c1973dcd85eea57239477b419d 100644 (file)
@@ -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);
 
index 3af540adb3c58e83b4265c77fa436d7d44da06c7..fca1bca7f69d1c4c1307c1cc7e2a11f80d6ec866 100644 (file)
@@ -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
index 711fbbbc4b1f724fcebdaec80eda2eec1eef8551..163d8d16bc245b48a10390d7706b21fd603489a4 100644 (file)
@@ -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))
index 1850e348f5555b67f253c7a8fc9cb927d9694f16..badd0a8caeb9e85d26a16d48b0eb892123276aaf 100644 (file)
@@ -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);
 
index 32279d21c8363d4976c6d313599fbc0e015e6a36..c2121d214f089eb1fe59af4ceb4b2b358abb8f0c 100644 (file)
 
 #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)
index 01ea82ba9cdca7e83a03f36d9ef1f43ec4267bc0..73d73faf0f38748327cf5ca241f7a5c685f10275 100644 (file)
@@ -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);
index d9db8a06afd26ef901aa0e5cf559559657ea3179..cce9c9ed46aa9a8462080c5949bdb6621e247f0d 100644 (file)
@@ -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");
index de8156c6b2925741534a45a6c3a28a3afe9d1ad6..2bbda71818adb022853964dd6d51a14c26f7cd19 100644 (file)
@@ -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;
        }
 
index 1542e837fdfa777e96155f041bc6d2072946d0cc..f38e32a7ec9c979ac4524c31e09da375a6e0606c 100644 (file)
@@ -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;
 
index d6c25580f8dd636dc43fe464adb339f597fdbcee..12cc64bfcff83c3c28c1bf97033dfd0162848b0e 100644 (file)
@@ -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;
 
index 0a9167dd72fb94e50692fa70ec9bc50fd99f733e..d18c3326a1f782b403de4a10ef057196beb3aaa5 100644 (file)
@@ -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 */
index 63c98bbbc596dbe11cc74ba71c384da02c5d763b..0d78727f1a14dd9c4ae301f053769437cbe4eb3b 100644 (file)
@@ -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;
index 85c00e1c52b6aa9309e782df639e03f444ffc1be..d6308ffda53ec797acf5f9e6038bf0a230008b55 100644 (file)
@@ -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);
index f37e3c1fd4e73f27e46564a6ef2739ff658523df..8dab74a81303277aed5cf24844941bdcadfcef1a 100644 (file)
@@ -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;
 
index 6f6ed75b63c97e7eaa2e49e7fcb385ca965f1ca5..765de3bedb8817d018b4f6143b3195c581cc3834 100644 (file)
@@ -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;
 }
index 2dda72004a7d5ba0ede8fb34c853bce2266ace4a..928fd892f167546e329f913ec10ea56e454cea0d 100644 (file)
@@ -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
index 00755b6a42cf1960e0a60bc95b72685afaee987e..c608e1dfaf09745a5ba25aabfbcf7d8c20819e23 100644 (file)
@@ -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));
index d0626bf5c540911b0d15bdbab1b960145b6d124c..5068c582d502c6944a01a2ee87062d7ffb409034 100644 (file)
@@ -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);
 }
 
 /**
index 13028833bee39e26641976dacb879b8ddf34c7a8..a404552555d488c832e7758293d7d4c1e229e679 100644 (file)
@@ -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);
 }
index eac499c58aa706a40ebf76024767ad80b1749678..6dde9a0cfe76ca3b09fcb355b26b75c3dad7c622 100644 (file)
@@ -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;
index 4645704097963ca2b57bd90642171f6dfb8c892a..ae53e899259f8d6f919d6f6bef07524c92c6fea5 100644 (file)
@@ -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)
index 3d4c24572ecdcda8ffdd47070ce75dcb625441da..32ad87345f5798498584d8dcfbda2f9ac993e619 100644 (file)
@@ -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:
index d1092421aaa7e7b69ba926d508155574f072ba61..9a4171b9094760871cf4396c99b2236bccd15193 100644 (file)
@@ -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);
index 7847436c441e3c16b91fb0d72c3f07061d4e772d..522d2900cd1dd942ae58c407920289e95f0ae5e3 100644 (file)
@@ -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)
 {
index a3aa0a27dfe56b22121a0571cc4eaca1b2bbee03..b2ff88e69a819cc3098a720ece238d8847d6be57 100644 (file)
@@ -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);
 }
 
index d103a1d4fb36713dac529bbc8703dd3023c6ab66..8f572b9f362555b55dc2e3cccfc5761140664616 100644 (file)
@@ -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) {
index 2680a65cd5e4fde5e333ef1ca1ff5d5ad4091222..63f28908afda78e05dcbcdd27e0a1a037f8b6fcb 100644 (file)
@@ -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;
index 5833f7e2a127811aa2298ded2bc62b1d06ae1e9d..b99a7fb09f8e31827a725151b415967699cdfa27 100644 (file)
@@ -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);
index 5894e3c9468f590e6b50144901b3f3b606e4ee69..8c373360827108855717f6d139034ff9f264bf0b 100644 (file)
@@ -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();
index 2dfca96a63b60283b89efab676932a711024a499..340c13484e5cc7dd5001577b7522d5a4318bd5b6 100644 (file)
@@ -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)
index 99a26a9efec1ab695bae833a1f9dca437e9dde5c..98f17b05c68b745276ecbe67d2934918eaf340bd 100644 (file)
@@ -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);
 
index ba1c9f93592b809cddc64b5e2dc68d1ecadf4190..9c51b8be00388adc840c68e38f60952dd1e46896 100644 (file)
@@ -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
index 96aa7e6cf214cc332eba6d54fcd626bee917c633..e17baac70f439f86c723732cc0298eaa5eee15de 100644 (file)
@@ -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;
index 2153e8062b4cefcca2ee92c6459fae295fbf4500..5cc3a07dda9e6acf202ba29a1f0a420814c4a96d 100644 (file)
@@ -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);
index fbcbb43259366ccd87c37119a5024dbb825099ed..f3556122c6ace17c419e13023057861957a507fa 100644 (file)
@@ -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);
index adaa2f0097cc085b964ad4fd571b1ca17e85b8b0..fb40ddfced999ca3b4516bec1f6f4133b6b61f1a 100644 (file)
@@ -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 */
index 545d14b0bc92fbca03b786f537b523e6ab453600..f5c1127253cb13fcccde047ba2d210b9f41fb556 100644 (file)
@@ -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,
index bcde1ba0f1c8b620c6046286e67c46343c14a07e..c7b1e58e33847a8250ab708695373a0817f85874 100644 (file)
@@ -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 {
index eaacfaf3720680e8e1bb8cbcd63d268d537d512a..ddd8719f27b8f7a9c22c7a25b9c78618bbaba95e 100644 (file)
@@ -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,
index 4d1188b8736ab40b36095f4027689d516aaf0100..9c175d5e9d67971266c6828a4191b3bda8f89756 100644 (file)
@@ -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);
        }
 }
index 4df5f13fcdae7949804d2c8aa4d5fd6a556cb452..ab66b4394dfc8ca2afc0cf1321f93f28f186d1cb 100644 (file)
@@ -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;
index 92b3a55d0fbc2633bd6e06c5ef2e772fe98b679b..f95eec52508e9bc4784f5cda71548bbd7d761b0b 100644 (file)
@@ -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);
index de50418adae5013173facd2bcfaf05c9bb5bf90b..034bdb4a0b06f41b86915e568bb6a5e2c14eb0bf 100644 (file)
@@ -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);
index 6e2e760d98b1b94ce03c7bb74fd034e6e0c9b693..0b75def39c6c4179ae157316f5d2b371775ae48b 100644 (file)
@@ -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 */
index 2a7ad5ffe997d1b2e65e9d62d9303830df74477a..cd5dc6dcb19f8a5050b7ce922b0fce612992c996 100644 (file)
@@ -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));
 
index fb1ebb01133f8ffba8dd785cfe27b1052a0e56f3..70723e67b7d75a4fc01ae6bac319855d0bdeb511 100644 (file)
@@ -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);
index 7cd99b1f8596b9856bf6c02bdddafcdd7910c21d..75bc08c6838ccebe1c01e3cec8e9fe0db0fba33d 100644 (file)
@@ -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;
index cb96f4a7ae3a93b4f6736d6b375098a88e935fa3..37046ac2c4413a51b9a77864cdf9e434a6ac7bd6 100644 (file)
@@ -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) {
                /*
index d666ada39a9be6d6f27fff36904af75063c035d6..5c2a08ef08bafd8351b0000ac5029620a9f19522 100644 (file)
@@ -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 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
        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);
 
index d10d2f279d19ad5b5924ffb16a70762f4548da42..74a124a062640ae77abb8554881e1a93222abd2d 100644 (file)
@@ -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 @@ static int nvme_alloc_host_mem(struct nvme_dev *dev, u64 min, u64 preferred)
        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 */
index 35f930db3c02c20c728d37e05a6fed40c79a15f2..2d7a98ab53fbf2de131990b753b929fe31cd154b 100644 (file)
@@ -168,11 +168,21 @@ static void nvmet_execute_get_log_page(struct nvmet_req *req)
        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));
index a358ecd93e110bcbc0331fc77ad22303c0099876..0a0067e771f59d89114a07b5e12b307b820b2670 100644 (file)
@@ -650,7 +650,7 @@ static ssize_t nvmet_subsys_attr_allow_any_host_store(struct config_item *item,
 
 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,
 };
 
index b5b4ac103748477174973d0ed23a92e3cf816ccd..f4b02bb4a1a891c578bb8cae3ad7a8db7ef5cc1d 100644 (file)
@@ -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:
index 1e6dcc241b3cfbc4cfd5e62d0668509ab636bb34..1b7f2520a20db7e151afe4a85a0e488fe0c85005 100644 (file)
@@ -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;
 
index 747bbdb4f9c613d11f52aadff8b2ddbfc4ba3fed..e3b244c7e443e1b0cc38116500130ed448d99d60 100644 (file)
@@ -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;
index a0d4ede9b8fc4aae1fdedbd901376a8c06972c0b..63e3eb55f3ac62e0784b21005d3f41c3a1b544b7 100644 (file)
@@ -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,
        },
        {
index 6ce72aa6542596e50c24d06d2177f7ac8b474774..ab21c846eb273b515da3723b443bd6bbdfcb2c10 100644 (file)
@@ -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;
index eda50b4be9349d26c5600a19426cdc1d7f7fe92b..067f9fab7b77c7945d40b7646b443bb8412bf01f 100644 (file)
@@ -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);
 
index 055f83fddc188d42e37869b4d403dfab635c9461..b1ff46fe45478e35904f13b4c4a4e2445706533b 100644 (file)
@@ -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);
        }
        
index af0cc3456dc1b48b1325c06c5edd2ca8cc22a640..b4b7eab2940024024c46ead23d6b1c415fa146f7 100644 (file)
@@ -4259,6 +4259,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
index dc459eb1246b16e9368dd0091d8b6bf50630eaba..1c5e0f33377936e16d42d9a5ea9c984157f1e8d4 100644 (file)
@@ -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;
index 69255f53057a38131e4588313e34b92bffdc2b3d..4eafa7a42e52102f2d02be5c8dac277861995dee 100644 (file)
@@ -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;
 }
index c259848228b4c337cab8e50ef1d0f6673fcb9b93..b242cce104686944efb68bfb4e8347358ffa135a 100644 (file)
@@ -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,
index 37371b89b14f3259e708debd883c57f9ae770a20..64fc59c3ae6d982ec2a7e9a0e56c54e7705d16aa 100644 (file)
@@ -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.
index 20f1b44939944614ff270c757fc7152f901e9f09..04e929fd0ffee494cc744cf495e5acd9e437ea6b 100644 (file)
@@ -1547,6 +1547,13 @@ static const struct dmi_system_id chv_no_valid_mask[] = {
                        DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_Strago"),
                },
        },
+       {
+               .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 = {
index 4d4ef42a39b5faaa1969d20a5aeeedffef90074c..86c4b3fab7b0ea8f0abfdf36e5a2b035e024ec66 100644 (file)
@@ -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 };
index f024e25787fc603c3469ea75de53452743d6af16..0c6d7812d6fd981b95f9d526cb9d6645e4b7855d 100644 (file)
@@ -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++;
index 3b8026fca057bef7173eda4834eeb4fec7832109..7e1fe39a56a5592040b02c961c08ebe5087ed28c 100644 (file)
@@ -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
index 159580c04b14b138c5ec78b6768db2224d63fb58..47a392bc73c821203abe1c7cb1e966db9a40a3ba 100644 (file)
@@ -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),
index a433a306a2d06ae11dd2a8c61830e0c76c4e7862..c75e094b2d90779f92570a534fd1c8d53e6a9e97 100644 (file)
@@ -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 */
index 787e3967bd5c5741aeb7a2cb96c18e38901092ed..f828ee340a98238052448d15a5f7604c286926dd 100644 (file)
@@ -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;
index b0486070374028fec219f3bdee1f46fc9e50fb93..80b87954f6ddf686fe3a1b593fbebaeaf1f2c229 100644 (file)
@@ -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.
 
index f8978464df31c9a8273b93776fc1224776d71471..dad8f4afa17cd4882a9f5e4f6e816f060e459588 100644 (file)
@@ -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) {
index 61f10637766108d253058a8b2aba48eb5bb77742..480926786cb8a39f62208cb55681e698822c1826 100644 (file)
@@ -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 */
index 1a764e311e11a2a9c4eeea310fbd8ac1960db704..e32ba575e8d9e2bfe3f1ff398c90ddbfe87196bf 100644 (file)
@@ -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;
 }
 
index b77435783ef332c30963f84e280cefbedbdb8e3b..7eacc1c4b3b10e1103e6e9c895112eb176245faa 100644 (file)
@@ -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 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
 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)
index d95888974d0c67f1e4cf4d3c2229ba4e901a2d87..b86f1bfecd6f2329cdd19c16da49c562e9e86fc6 100644 (file)
@@ -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;
 };
 
 /*
index 7e0d4f724ddae73c71f698a9e4f7775328ef4d93..432fc40990bd26ad2e0dd9e39897ba5c348b197f 100644 (file)
@@ -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);
index 8975cd32139047cf03afe9a93544cc919eaed661..d42e758518ed92e33dfd6c6aaf2a4ee2ec198ff0 100644 (file)
@@ -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 */
index 04efed171c88981e23e23bf6ac8438c42ebae69a..f32765d3cbd89dd3cd50186f803b74a44ea0973f 100644 (file)
@@ -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" : "");
index 216f923161d1007866130c22872ef22f604197d9..a610b8d3d11f0dfff4def05edf3c2342780dc0b8 100644 (file)
@@ -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);
 
index 57696fc0b482687421c3787a0abed6102845d603..0a5013350acdb66f3acf51b2cb24672994d4ccb5 100644 (file)
@@ -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);
 
index d384f4f86c263c57bcef36ceb0ca930fbfed9094..f4538d7a3016e2b1514df38c9e6e9b48939d6ce7 100644 (file)
@@ -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
index 707ee2f5954d0ac0890c6f05967f7acd24157704..4591113c49de3af951908ed2257f6f5e88663b96 100644 (file)
@@ -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;
index 741d81861d17f777e8fd814edd469004e0491040..07b60a780c06b8b2be234e1a5f4ea97403f1c54f 100644 (file)
@@ -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/
index b98c5c1056c380a10dddaa0c6b4a3e6c5d50796c..45e2d49c1fff5e5f2c6f0c11b8e5e6874a45f514 100644 (file)
@@ -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 $@ $<
index 7dfe709a713837b075cd2021c00ee6a5fb44d978..6844ba36161638d995f3d5d5135c160fc54bc9ed 100644 (file)
@@ -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);
        /*
index 913c750205ce2a3f1a90f5d255d98d3b39f90145..26de61d65a4d259fa41e7e070648f775031a9662 100644 (file)
@@ -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++;
index 86afc002814cd07bbc3b55b64ca31201208a514b..4ebcda8d9500439941bd630f8b1187875a7beac5 100644 (file)
@@ -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 @@ static int __init bnx2i_mod_init(void)
 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);
index e4c83b7c96a8180c856627562549c4aae362dcdf..1a4cfa562a6087206ee2f68eaf3fc63988d1934a 100644 (file)
@@ -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);
index 077f62e208aaef5125756ecd30273176698a7bc7..6a4367cc9caabea8f0bbc1519d309ab50b55578f 100644 (file)
@@ -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);
index 551d103c27f1303b5299e6d2ff80e8cd93b777ff..2bfea7082e3a070f0e6e44f27837df86b8f75c89 100644 (file)
@@ -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,
index 8914eab843372fe3dde09e97b0d2c45aa65bbf64..4f7cdb28bd38fbadc6105906f56fe813346c299c 100644 (file)
@@ -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,
 };
 
index 47f66e9497451e290112852fa5a3f6503b4f33eb..ed197bc8e801a604029ac12e93bf24d9bdce7e34 100644 (file)
@@ -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
index fd501f8dbb1107fe7f567ec3e66cf7c9e6471083..8660f923ace02120eb63c2ac11724448d4cbd060 100644 (file)
@@ -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);
index 4ed48ed38e79316f02ca1e299e56f66eea84ba8e..7ee1a94c0b33eefd57a6889df66649477ad4713b 100644 (file)
@@ -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));
 
index 5cc8b0f7d885fb0dfd5a00342f6ca72c72a40129..744f3f395b64852a294a9300adb64a496087aed7 100644 (file)
@@ -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) !=
index fbeec344c6cc3be0bdd878db6bafda7353dcf901..bbbd0f84160d36563008a212afd8252f86ef15c8 100644 (file)
@@ -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",
index e675ef17be08a0f67dd76f9d33a2ab831f961ce8..48a76788b003cb746afa45376272af362c4446ce 100644 (file)
@@ -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 */
index f990ab4d45e1bf72b3adf8991b11c01309c7530b..985510628f564286f5df386085476e9020e2ad47 100644 (file)
@@ -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
index 4d038926a4558c45b8685ca08c4976233a7ed5e7..351f06dfc5a0dac7bf4f7606166611848876d477 100644 (file)
@@ -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
index b58bba4604e8cfce57fd320d53043bb293845765..1d13c9ca517de7e2cec033bdf050498fafbfeccc 100644 (file)
@@ -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;
index 21331453db7bd29a0c2bc8cac430b8c8bb60b9c2..2ff753ce6e27a49a9e395c52057998b508c3e66f 100644 (file)
@@ -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.
index 32632c9b22766d59e223a256c430810a4fa33bec..91d2f51c351b4d6940d04a1e4a261f2d816e7b04 100644 (file)
 #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 {
index 19254bd739d9c9e32b300d24fd418fc6f4ebd2b1..93d54acd4a22f70f7be57470056166f58ed69b0d 100644 (file)
@@ -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;
        }
 
index 80edd28b635f5dc6fa11d9d867e295a19122e586..37da9a8b43b1f1dfa25133cab878ce39d6efcde3 100644 (file)
@@ -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:
index 5f5a4ef2e52965647e1e3db5b4cdd7bdb8021af8..2c37836848152f91b394bfeea4e120ce2d35f46a 100644 (file)
@@ -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 @@ static int qedi_setup_int(struct qedi_ctx *qedi)
        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 (file)
index 0000000..df39b69
--- /dev/null
@@ -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
index c2dc836dc4843e79ad6239186b650a14f1f91693..e101cd3043b94539a2893e77aa9949c8fd9c7acb 100644 (file)
@@ -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);
index b20da0d27ad78494bc9a0172d428dc176cbcb852..3f82ea1b72dc8739283992b4f425d77692b51e7b 100644 (file)
@@ -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 *,
index 7e24aa30c3b05b487130b028d4aa5688d3f7b6cf..892fbd9800d986a8dba22efac7ac4803be2c5f17 100644 (file)
@@ -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,
index 21225d62b0c1f4424bc72f57f8daf109cabffb7e..d7ff71e0c85c6ecd525d0d59d3f3f0da63952b47 100644 (file)
@@ -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);
index 07ec8a8877dec04b6ac3ea35aef2ac1a6c6c3e01..e164ffade38a7166690a9ecb206be1165e62278c 100644 (file)
@@ -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
index 8b93197daefe33c2330377dcac7dcf6d8c46c048..9be211d68b1596b4a9b482fa4e17888b6f559e39 100644 (file)
@@ -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,
index 20bde38ce2f912f547f07874b2b91789c9ee7215..e9d750c510cd9c90a5ac1bb22ddbc89e29c6024f 100644 (file)
@@ -2,6 +2,7 @@
 # ZTE SoC drivers
 #
 menuconfig SOC_ZTE
+       depends on ARCH_ZX || COMPILE_TEST
        bool "ZTE SoC driver support"
 
 if SOC_ZTE
index 2afe3597982e73f5b592be8f7d991c4ebef9f8ad..f4b7a98a7913e236e295d4dd3422fa0f218b6e53 100644 (file)
@@ -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",
index 2b9b0941d9eb5f82e917978426290a9d39b5c5cd..6d23226e5f696ee2268073efbe899bdfea88ba8a 100644 (file)
@@ -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,
 };
 
 /**
index 268d4e6ef48a641cd04e9647c2a07b1fc24a216e..ef28a1cb64aecf5a0af0afd0d33b3313eaf26013 100644 (file)
@@ -110,4 +110,6 @@ source "drivers/staging/ccree/Kconfig"
 
 source "drivers/staging/typec/Kconfig"
 
+source "drivers/staging/vboxvideo/Kconfig"
+
 endif # STAGING
index b93e6f5f0f6eadc21efeda879175969fc68d7f72..2918580bdb9e215bfa407d4c38b94a661069c6fa 100644 (file)
@@ -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/
index ca11be21f64b606091d5e8e0e62044ae263dc3ab..34ca7823255d692d05aa753e7c5bc28a385c5583 100644 (file)
@@ -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;
index b2e38288898132004152c1e00d38c8df286e5d43..2f7bfc1c59e5171583613d4ba58f06d34b4742e6 100644 (file)
@@ -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;
index a6a8393d66645e75c13ecf8f67ca9c71ef48a6e5..3e00df74b18c883d4e19f0bac7ec087988b58821 100644 (file)
@@ -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;
index 85b242ec5f9b284442e3fffe136ced430d2dd862..8fc191d9992703932a6692b531d82b6767763d51 100644 (file)
@@ -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;
 
index 9341232c580dbaeb78d33286192f0595def5acdb..4d0b181a96714b8471b77692fd61d4c064ab45c2 100644 (file)
@@ -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;
 };
 
index f31eb277f5428f98711ea235bc9dca1ba7ba1a1f..7d8a0aeecb6c1f20998d2c0f334a97aa004d4ac9 100644 (file)
@@ -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
 
index ccbc757045a5560d53fee7ff6349b1ddfe9f16c9..7c3d994180cc110515a2815a62d5cb0b9ba41aa0 100644 (file)
@@ -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
index 36b3f3a5a41fd33b485f6581b5ebe57622254fcd..41b4133ca995bd48b303752be948516f1be0da6a 100644 (file)
@@ -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;
index 944fe8e3bcbf2e275c13c117a4323f0fbd00abba..ab8907e6c9efa1e20b9def2f8f5dff3a4318984c 100644 (file)
@@ -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
index b0d40965d89e6ec9a0a3b8dfbbdf1a72514dd388..73ecb167971896f6f7b5e64a3cf069ac4cf5938d 100644 (file)
@@ -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
index d88ac1777d86bcbf1d800f5c2e5d7f25f8850a40..8c2e6794463bc5bd47b476c1093ba9e9cb8a2d8f 100644 (file)
@@ -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
index 9be6a0e6386193fc7b5315e2b3e6e8777c4156a3..d3fde200c013ea77ccecc014ebd54d6c3984a610 100644 (file)
@@ -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;
index 09e3cdc1a394a91adfb0a53fb08283f8ece998c3..f9a3cf8fbf1a7fa663918e1e92acf9e61a06c159 100644 (file)
@@ -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;
index 726eaa293c55056fc5848d2c324267f4a7b4ab08..2bd98f0667ec6fb08534681c20e14c7d4c6a9882 100644 (file)
@@ -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)
index d3667132851bca6ce854c7c2014ce5ded1f23d6c..c8e0c4fe3717807b6a76df69ae1cfd3be566b1e6 100644 (file)
@@ -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;
index 370ecb9595431c4283fab8028ad67b85859ed4a0..f28916ea69f1ccadd21506c8cf8f3dec8394534d 100644 (file)
@@ -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
 
 #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;
 }
index 0eb607c5b4237db755684c5dbec7b6beb20d5bcb..f4b29b1d6eb88b9a6b1d11e6400614c1ea588908 100644 (file)
 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) || \
index 002d09159896e63e1d2c54b1fb47efa2766197d9..a69007ef77bf0a32bb37468c3ee83a74493c2d42 100644 (file)
@@ -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);
index 963235fd72921f268e8304170f01fb5bbcc48681..d283341cfe4356914e3e9071f8d6851a7a180d46 100644 (file)
@@ -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 */
 };
index 944dd25924beba1decd0894564df6efc3323b5bf..4754f7a2068460e1f3259afc3b5c0741150cad5d 100644 (file)
@@ -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;
 
index 3aa4128703d537ed665b0ddd5ee12302712c4e5c..67207b0554cd4c868a095d8b8ab7cfeb51cb9233 100644 (file)
@@ -1053,6 +1053,26 @@ static int sm750fb_frambuffer_alloc(struct sm750_dev *sm750_dev, int fbidx)
        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)
index 82e5de248947f4cd5bd24d8bf4a2cba7f903b88b..67956e24779ce6fea015da416422cdf5c834bf18 100644 (file)
@@ -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();
        /*
index 87b6a0a4c54dc80c8cbbbbf3b3c7d4208827cbcc..046040ac074c63851e8b289d5a6bf0f05b31684d 100644 (file)
@@ -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);
index ed8e96b06ead24fde5c0c54f48d1c2dc83e825ef..fe340b07c482fac63410d57ed1b7c0d262e069c1 100644 (file)
@@ -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 (file)
index 0000000..a52746f
--- /dev/null
@@ -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 (file)
index 0000000..2d0b3bc
--- /dev/null
@@ -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 (file)
index 0000000..ce76430
--- /dev/null
@@ -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 (file)
index 0000000..15ff5f4
--- /dev/null
@@ -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 (file)
index 0000000..8e6d9e1
--- /dev/null
@@ -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 (file)
index 0000000..a2a34b2
--- /dev/null
@@ -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 (file)
index 0000000..5b21fb9
--- /dev/null
@@ -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 (file)
index 0000000..7616b8a
--- /dev/null
@@ -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 (file)
index 0000000..6d0600c
--- /dev/null
@@ -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 (file)
index 0000000..4b93027
--- /dev/null
@@ -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 (file)
index 0000000..562db86
--- /dev/null
@@ -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 (file)
index 0000000..c157284
--- /dev/null
@@ -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 (file)
index 0000000..822fd31
--- /dev/null
@@ -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 (file)
index 0000000..3ca8bec
--- /dev/null
@@ -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 (file)
index 0000000..80bd039
--- /dev/null
@@ -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 (file)
index 0000000..e5b6383
--- /dev/null
@@ -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 (file)
index 0000000..b7453e4
--- /dev/null
@@ -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 (file)
index 0000000..34a905d
--- /dev/null
@@ -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 (file)
index 0000000..d835d75
--- /dev/null
@@ -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 (file)
index 0000000..d09da84
--- /dev/null
@@ -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 (file)
index 0000000..f842f4d
--- /dev/null
@@ -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 (file)
index 0000000..c10c782
--- /dev/null
@@ -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;
+}
index 030bec855d86aabff800548016eca5e7f403248b..314ffac50bb8303971ca71a5f702f07fb8ed6639 100644 (file)
@@ -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 @@ static int vchiq_probe(struct platform_device *pdev)
        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:
index e583dd8a418b537eda69a9606fa8a3fc2c6a6207..d4fa41be80f9a1719574af28c8981ef8e8d287ca 100644 (file)
@@ -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)
index dda13f1af38e581f746e4528590510c07efb916f..514986b57c2d60ce19c1074f4d19d65dd550be2e 100644 (file)
@@ -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:
index 74e4975dd1b1e74d6c39517be102ccdc92614e80..5001261f5d69d759dd25161401510551d35c3da7 100644 (file)
@@ -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);
index e9bdc8b86e7d1d71d77cf4388370af6fcf3fded7..dc13afbd4c88dec2390ca8e65b3332d2f78acd73 100644 (file)
@@ -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);
index 36913734c6bc58ed326ac793dc19d3d265ec878d..02e8a5d8665837f415ac7b2d78e51067d1ef5b62 100644 (file)
@@ -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);
index 97fed9a298bdc29a19d184ba49df458e04e4f9f1..836d552b0385e978bc1a0b98c59a3379c262fd61 100644 (file)
@@ -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);
 
index 80ee130f8253ec44324ac2ba616cfd93beb1ba76..942d094269fba5db66ff7e791dcfaab1c6acec15 100644 (file)
@@ -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;
index 308b6e17c88aace0775b4ed0a5460097559d66ca..fe2f00ceafc5d7e1a3bbafea4224c838dc2158a4 100644 (file)
@@ -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)
index 8ee34029021986c94319e20adf4d36ce1d4ef374..bdaac1ff00a5af7518da6e3e03a2c8e6ef99a11b 100644 (file)
@@ -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;
 }
 
 /*
index ab3e8f410444498c49d0c43c86c93d12fc016cbf..e9391bbd4036023c63d8b7ec90185f56f9523ade 100644 (file)
@@ -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;
index 3d9f64676e5839d35b5b3a7edb56a9bbcc00c211..e0deee4f1eb095233789ca7ff8fa3de377d770c1 100644 (file)
@@ -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)
 {
index 85b6d33c09193a4fdf255d3c809ecfb84e7f8177..de6441e4a060283f6e5abdd43672f34103577e93 100644 (file)
@@ -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;
index d1399aac05a17e96ead10d5bd616a5a780ce9237..284749fb0f6b96d3d6d667332e569ba0d745e048 100644 (file)
@@ -448,48 +448,6 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty,
        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)
 {
index b5def356af63b70e3ebc2e23a48da0753e41b47e..1aab3010fbfae76e2c25cb60085f21051a1f24cf 100644 (file)
@@ -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);
 
index b5c98e5bf52402c2febb0b4d64d54dd19c739446..c6360fbdf808655524415e228d5779347b4d6276 100644 (file)
@@ -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),
        { }
 };
index 8a857bb34fbb26c6d60784d3fe7576730a9aa5b3..1888d168a41c87c605962da2605df8ab1c02bd20 100644 (file)
@@ -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;
 
index 343de8c384b027366e92818d39cc9c525a95a77f..898dcb091a279fde22b40431acf6dfd8e5badfe8 100644 (file)
@@ -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 |
index 9e3162bf3bd12ea32a0bc35d5851a1f17297907d..80934e7bd67f422629b8ea7c37fdf1f8afc188e6 100644 (file)
 
 #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
index da5ddfc14778869cdc8974fa618a923ba75c90ea..e08b16b070c0fb914916dd6c2f78fcf3546edfea 100644 (file)
@@ -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)
index f5335be344f67ced2a601c81e3713a7d90e275c7..6b0ca65027d00162e6a8099527878cdea3599f82 100644 (file)
@@ -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] =
index 5357d83bbda2b87d8823b24995dbfcd626c2262f..5e056064259c85432ebe9f3d9eb12616e2aa1271 100644 (file)
@@ -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,
index ab1bb3b538ac6175dd1fbe5babb686a6a8f4bc49..7f277b092b5bf070c21d9c321d15b2e0d630792e 100644 (file)
@@ -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);
 
index 6e6797d145dd80136c413129641bdbbae2f1e63b..822f8c50e4233c70d159a4e374ad66b49502c0c1 100644 (file)
@@ -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 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
 
 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.
index 3116edfcdc18558aa768d248f1ff1881448ced09..574da2b4529cc26cc0a97ee7146e42889ca55bbe 100644 (file)
@@ -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 },
index bc3b3fda5000d94813d51bade73eac5f2a2b0b70..c4066cd77e47345bc1f31791ba9955c80a12d452 100644 (file)
@@ -3573,6 +3573,9 @@ static irqreturn_t dwc2_hsotg_irq(int irq, void *pw)
                /* 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);
        }
index 326b302fc440d89d7aa4b4ea3d5ba9e839005318..03474d3575abe1381771a88eeb563a39649aa162 100644 (file)
@@ -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;
 
index 98926504b55b5b425eb3c9dce66e889a524d2152..f5aaa0cf38734ccdfea16cfd29dbf2e8e1599cf1 100644 (file)
@@ -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:
index 9e41605a276ba8bc8718340272f2cf21d27cfed7..f064f1549333dcd7dab10fd491e43cf31bac887e 100644 (file)
@@ -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;
index e80b9c123a9dd27eb9e547210e1d1ee34b3fcc63..f95bddd6513f7e88e4d511508afef2b9c84c063b 100644 (file)
@@ -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;
index 8656f84e17d95ffcaac97f7c60b0d0251828b8c7..29efbedc91f9b1bfe9a3d84d5c906c5fc38fc775 100644 (file)
@@ -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;
index 9082ce261e70a7fa00979abacf11d84c94940261..f05c3f3e6103c61ca322da00fce6d5fc02aa1881 100644 (file)
@@ -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;
index 9ffb11ec9ed961eb157a7c35e43a5d3a01b651b8..7cd5c969fcbe9724ec0892403f1a5bd1c7d01320 100644 (file)
@@ -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
index d8278322d5ac1b4fafca40af9b757016be40b0ce..e1de8fe599a35695eceda22d3138492af8995b20 100644 (file)
@@ -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;
 
index 2e11f19e07ae8ae42bfdea6e5c1c2755b42c8a0f..f7b4d0f159e4e4492bbfb6d5877370bb9275cda5 100644 (file)
@@ -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;
 
index a9a1e4c40480cf2c5c7c7995aa5d337d3ef3ee87..c8f38649f749311a81ff63aa194c1b97cb71718f 100644 (file)
 #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);
index 0222195bd5b0e2a954ec8d2e841720b577c7282a..5582cbafecd4c1a3ddc5443d6cc9182a9b9bc89f 100644 (file)
@@ -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) {}
index 1adae9eab8313f341bf01f43145a94c6b5f8121e..00721e8807ab472f1e886fff791e7bbbaeec3a13 100644 (file)
@@ -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);
 
index 53882e2babbb2ec3903aebdb14b9fd3a28482d47..8071c8fdd15e741b008af64075cda3c87072bfb4 100644 (file)
@@ -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);
 
index c50c902d009ed8ea634ce073ecff75024ff8cda8..cc368ad2b51e44c731a2926902f78de830e2f17a 100644 (file)
@@ -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;
index 56f85df013dbd7201d48c7a0afc2e93041d6e851..b2ff1ff1a02faff066374cafdf9fa5b531db5b81 100644 (file)
@@ -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);
index 3c6da1f93c845a6373deffcbf81be9530b03b122..e3e935291ed6fcb57be0402000a4beac6161a9ce 100644 (file)
@@ -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;
index 76decb8011ebc2d37d3e7e64a394bd2bb6e5c8ba..3344ffd5bb13743812bab737f52b8e81eb77b9db 100644 (file)
@@ -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);
        }
 }
 
index 8fb86a5f458e01275186dc83ff86e38b38fff35b..3d0dd2f9741571423522ee80c972d8db2ffec853 100644 (file)
@@ -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);
 
index 623c5130039303b389717f94ea6a89972627bc55..f0ce304c5aaf54f1255bd94d786a3e1cb4148b79 100644 (file)
@@ -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);
 
index 5bc7a6138855ec7ecf69046ceb71a3c992ccb9fa..2c8161bcf5b5e22ee8ed2eb413d29fdfde504e95 100644 (file)
@@ -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 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
 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",
index d544b331c9f2ce80d83095f30184e2102eda6ea6..02b67abfc2a16139a3230d1120a17a4a9ab1cc09 100644 (file)
 /* 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);
index f64e914a8985495bf6ef51bb3de4772c40ffbf49..2d945c9f975c04d5cd7909e00a37017a97e8062e 100644 (file)
@@ -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 */
index ebe51f11105d8889d6144a72bbf719f14e4b1103..fe123153b1a5439f016f2637d4f9d19f0fde3f14 100644 (file)
@@ -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 */
index c9ebefd8f35fdbe5491627f4df89b80c87aeabad..a585b477415dde58b38c9e2defe0d26c24552757 100644 (file)
@@ -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) },
index 09d9be88209e1ce6b1f53dc052a53c5e4c491336..3b5a15d1dc0dd50a0ebf9d925e33ef4cf8db0090 100644 (file)
@@ -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
index fba4005dd737b9a43689ae1db1ecc20f3ac46ac7..6a7720e66595609160c7cc9c5be7f64a157cc3b0 100644 (file)
@@ -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 */
index cbea9f329e715aad97b23928d79579cdcf5e8c92..cde115359793001dcf18b8884c3c9e22eec0fa73 100644 (file)
@@ -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,
index 06615934fed1cc537694b03d023b613c95aea9f1..0dceb9fa3a0629af3bd1a1990508d2c32bb42db2 100644 (file)
@@ -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 @@ static int usb_stor_control_thread(void * __us)
 
                /* 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 */
index 6b0d2f0918c6dd7fbf19207a47b2f6a43fcd9d57..8a88f45822e39eb1a8c1826c2c5129371d555aef 100644 (file)
@@ -3,6 +3,7 @@
 #define __DRIVER_USB_TYPEC_UCSI_H
 
 #include <linux/bitops.h>
+#include <linux/device.h>
 #include <linux/types.h>
 
 /* -------------------------------------------------------------------------- */
index 063c1ce6fa422e24d1bceb0ef10aeeccce864b96..f041b1a6cf665e6410917d3608de5fe0ac557476 100644 (file)
@@ -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)
index 330a57024cbc5414b381b26e6ef80cf129cd7f9b..5628fe114347a9d710860022182a26893a87d5ab 100644 (file)
@@ -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)
index e4613a3c362dae8ffbb1e701b4dca51bb858625a..9cb3f722dce13aea78b5e81152e27ca1346f10f9 100644 (file)
@@ -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. */
index f72095868b933735a08c3e6c343504ba112cfefd..bb7c29b8b9fc83e63cdd6be02acd58690e36cb57 100644 (file)
@@ -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;
 
index ff01bed7112f1566ca13b3e17330851bf02fec05..1e784adb89b17534ce31751b546ef20801b2427f 100644 (file)
@@ -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);
index c166e0725be5dab13e9a685a93ea7ea9c23a3351..ba82f97fb42b2d10fdbebd227fcb7e5eb19dcbdc 100644 (file)
@@ -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;
 }
index eecf695c16f41b6996520e47b8fa7e1b71efbabc..09e5bb013d28071c69b63b1968ef6eca44252f1e 100644 (file)
@@ -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;
index 156a254705ea5e090bbd1e3c1915adb96264e238..ec78d61bc55122e3fca807a55f612ba740f077ce 100644 (file)
@@ -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,
        };
index 4da36bcab97798c370971731c0541772b357378c..2e2fcc3d6d4f7b7ade7edcea0bb24463f062f799 100644 (file)
@@ -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,
        };
index 22caf808bfaba97e45662de0f4150632bcb85d2f..f0b3a0b9d42f8b8b3ea9c6943a4010c3d7e15f18 100644 (file)
@@ -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;
 }
index 3612542b604444bbfdf30a2212e45e830eb5e9d3..83fc9aab34e872377274c3521055365fc618bef4 100644 (file)
@@ -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;
        }
 
index 95ea7e6b1d991b681579477653e173fd2412a4b0..74471e7aa5cc42d82305967bc5a1795363fb5895 100644 (file)
@@ -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;
index 50dcb68d8070756ef8e4a67af8200c9d5e4c8c20..ab609255a0f35f02aaa401ecb0be925a2b4b5ba9 100644 (file)
@@ -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);
index b241bfa529ce3cd9879da106b04531fc03b005e9..2d43118077e4eecc12f68bee605fb068def11c95 100644 (file)
@@ -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;
 
index d6786b87e13b2392c366cfa807c35cf2401c8387..2c6a9114d332c74a85e2d679b9c2672a7447e188 100644 (file)
@@ -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)
index e7715cb62eefc307a354a77902baaaa5916a157c..e89136ab851e30c1aff97893615f72f2d5bf3cd7 100644 (file)
@@ -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,                  \
index 66620713242a1e7416d656cca5f0353c660e1133..a67e955cacd199298a3bfa22049b5549507c52bf 100644 (file)
@@ -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();
index e460802149555b6f0d5def7659d8e8207828eb53..3e59590c7254ddc8f1a08f4232262a74a29e3711 100644 (file)
@@ -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();
index 967f069385d0cf1fa9933cdeb0f8804dc0324e06..71ddfb4cf61ccfef375a07d6271715e9478c68c6 100644 (file)
@@ -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;
 }
 
index 69ec23daa25e003ff94ef306c93a0a77c51b00a3..a1e6860b6f46a091e28855eb5b6ed48c937aebac 100644 (file)
@@ -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);
index 375f8c728d91888469a4820f1d669ea74c752b8c..e3b0b4196d3df173fd52d62076396f21029f073d 100644 (file)
@@ -4825,10 +4825,6 @@ static void shrink_delalloc(struct btrfs_fs_info *fs_info, u64 to_reclaim,
                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 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
                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 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
 
                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 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
                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);
 
index f20ef211a73d081f38f8ebac80b315d7ee30112e..3a11ae63676ea8a299828c18fc772e74e57a07e5 100644 (file)
@@ -2153,8 +2153,7 @@ static int replay_xattr_deletes(struct btrfs_trans_handle *trans,
                        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;
index 5eb7217738edbba5a49237736c3263b9b044d46f..e8b9a269fddec78fdf42adec32eabaffdf9c3636 100644 (file)
@@ -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;
index e071d23f61481bf23fc4407d72ea75c9d1ec2430..ef7240ace5767a0439f9eab941725b900281e844 100644 (file)
@@ -271,6 +271,11 @@ static int __dcache_readdir(struct file *file,  struct dir_context *ctx,
                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;
 }
index 79dafa71effdd149d2441e1a443261c1f8e2ce3a..51f0aea70cb434bd9f5ddcd854fe5cf156766f42 100644 (file)
@@ -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:
@@ -221,6 +211,31 @@ ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
        return error;
 }
 
+/*
+ * 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.
  *
@@ -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;
index 09441ae07a5be9de1f18cdc01d896808ba1e02be..46ff2229ff5efed30a498d05a416ea7e5c1e6d22 100644 (file)
@@ -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 @@ ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type)
        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;
index 9ebde0cd632e77b69fecd7800ed196e67b059507..a2bb7d2870e487de3f8601107cdf67c05b022034 100644 (file)
@@ -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,
index dabad1bc861723932fd7f25da1d86cdd0a641ce9..48143e32411c4cabfdd56bebe41c8fdc522c9665 100644 (file)
@@ -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.
  */
index e0a8425ff74da9e60427f09f5525e1bc85952d51..97f0fd06728d7bb18bb05637db169cfeb91f9bcf 100644 (file)
@@ -4652,7 +4652,7 @@ int ext4_ext_truncate(handle_t *handle, struct inode *inode)
 
 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;
index 58294c9a7e1df0028f267e4eaad67d7b0d2a910b..0d7cf0cc9b87562bbc52b17224794d9147208910 100644 (file)
@@ -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);
index 3c600f02673f07ca829195605acaebd0eb9ad7cd..c774bdc22759b1602341da70a0b3fec7b8830f2c 100644 (file)
@@ -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);
 }
 
index 42b3a73143cf1a3b2cadef40459a50714b6b80d5..afb66d4ab5cfb895ce99574f18740621c37815db 100644 (file)
@@ -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);
 
index 581e357e8406c7cdea04999bdd89a12762c55e89..5a1052627a81413685241f0c4669bbf755e2c5f9 100644 (file)
@@ -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)
index 13f0cadb1238e61983629e02cda233a60b84f6d1..c1cf020d18895ccedca1690431e009c1f05ad846 100644 (file)
@@ -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 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
                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 @@ static int ext4_delete_entry(handle_t *handle,
 }
 
 /*
- * 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);
 }
 
 /*
index c3ed9021b781c57cce5d6cff163c216be6c20020..035cd3f4785e2d824be923cbed2c5012b18abb9c 100644 (file)
@@ -1927,7 +1927,8 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
                        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 */
                }
 
index 0886fe82e9c49202311922680a33723c513c9983..d61a70e2193a012d48f5c56140a416abb2280b68 100644 (file)
@@ -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));
index cff4f41ced612d9b0f344be66a17e434981f8861..82a5af9f66685a6165a59a1f0c6ba603dd332e8b 100644 (file)
@@ -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 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
                } 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 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
                        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 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
                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 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
                    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 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
                        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;
 }
 
index a140c5e3dc54ebf89853e57fb80bbce0c5590478..b4b8438c42ef9cbbe9805fbc233a5a9cde216ada 100644 (file)
@@ -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;
index 56bbf592e487577b4d21614d7f56c1dbfc45e2c3..5b876f6d3f6b1d81a661f00a3d7c40cb99a83597 100644 (file)
@@ -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 @@ int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
        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
index a0e6d2c65a9ec013ed05a6a67ced7ca6995e9842..2706130c261b060f46cb526b8e7ac501789808a7 100644 (file)
@@ -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;
 }
index 9adc202fcd6f76ca4e0f0b16d5b4aedd6e2e4e9c..71191d89917d8c1aa78dcedc36a71307a878d96b 100644 (file)
@@ -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"
index 3ee4fdc3da9ec359ad847afa36354240329a2da6..ab60051be6e533eb167a72e590494f0a46e3a488 100644 (file)
@@ -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 @@ static int fuse_writepage_locked(struct page *page)
 err_free:
        fuse_request_free(req);
 err:
+       mapping_set_error(page->mapping, error);
        end_page_writeback(page);
        return error;
 }
index 1bd7ffdad593977013c1ddd233b2a91093471471..bd4d2a3e1ec1b8cc0af29bcb8c26f13d82708804 100644 (file)
@@ -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;
index 9b92058a12409d6aa4040ed228ab1d2e5a6d8537..6bb5d7c42888fe049dba0cc98fc2d92f10e5d6d8 100644 (file)
@@ -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 @@ int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *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;
index 8cf898a59730dff80eec216b069cd415fbd5ca70..217a5e7815da6a896daeddb53d8200dcba56a303 100644 (file)
@@ -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;
index 7bc186f4ed4de6837b94ab8670cca7043122b28c..2e71b6e7e646a489e35bad17c23cc2140c5bc64b 100644 (file)
@@ -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;
index bd9b641ada2c5e9ba507c4efaf346a244559f4fb..7ddcb445a3d9f65c61a4c423e2e969bf14649394 100644 (file)
@@ -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) {
                /*
index e8aad7d87b8c938aad4a51db500684950df73944..78b41e1d5c67151744fb1c98bf1af54560593457 100644 (file)
@@ -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);
index de45d9e7674878db78d77d9aa4ac09e8da429dd9..6790767d18834fcb71b360f6683fe2cf54edb42f 100644 (file)
@@ -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 */
 
index 88fd38d1e3e7ae8b9a6e0df2ea4baedb0c423cfa..ddb6a7c2b3d4aee1c3512e064350822533968dc5 100644 (file)
@@ -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)
 {
index 69d02cf8cf370678609175d6e5626d0dedf02c3a..5f93cfacb3d14b9befc6ba33a91d79ccde044d89 100644 (file)
@@ -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
index ee5ddbd36088e66d21b2900fddb9c7ded0d17f9a..efebe6cf4378e32a13d109eebd0b694dd629c2a5 100644 (file)
@@ -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);
 
index 5ac484fe0dee04f9c09630468f64aa779190534d..3522b1249019ce261db090af01baf9525302f10d 100644 (file)
@@ -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);
index 5713eb32a45ea20c1de50f2ee28f4ddcae468f67..af330c31f62752f22c6fe1dc6de5c57f0e02a3d3 100644 (file)
@@ -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;
 }
index 080fc6b278bd5bbc813bcaa4dcf828a1789451ea..44c638b7876cfd5824d2d6287731e4411ea02052 100644 (file)
@@ -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:
index 1f2ac3dd0fe5c2755dec68b79d64c61030e3f3f2..b0fa83a607541a4ed2f8190e46827778d328912f 100644 (file)
@@ -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)
index 6df7a0cf566015378aa3f76c480115675454297d..f32c58bbe55671cb75abdcb9934152d110e3537d 100644 (file)
@@ -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);
 }
 
index 3efe946672beb0b23cb7b7fbf0da79842b801cd5..60bad882c12351fe39314bd1d265f7980c5719ab 100644 (file)
@@ -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),
index df4a7d3ab91571a6368acc6be0a77474458755e5..d1e87ec0df8482d272b2a2c481b0eb3d76401ebd 100644 (file)
@@ -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);
index 50566acb54694ac4f14330f4bbb7ab360ba15f88..e9bea90dc0179770b9fbfa39fe6651c5949f0d62 100644 (file)
@@ -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]);
index a0b4e1091340df476bd48990e3631d1588d25052..d901326423401c3e7d442f62bfa80d03d281ed02 100644 (file)
@@ -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:
index fa3eb361d4f863be18072272293dcbdcedfd887f..37c8af00327588d772610cac487fcf0651cf8fbf 100644 (file)
@@ -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);
index d40755a0984bbb0942e96aee388ed50fe7629a6e..25f28fa64c575129130d916d566674da792376ae 100644 (file)
@@ -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 @@ void pnfs_generic_recover_commit_reqs(struct list_head *dst,
                        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);
index b45083c0f9ae8a78838d84145f71efaf1eab4d89..49b0a9e7ff18bb70d8be183718c598eb90009a49 100644 (file)
@@ -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;
index dc22ba8c710ff10de13526d52712ec4ef16cbb96..e50a387959bf80e7ff2bbd5fa2bd4d17128c631b 100644 (file)
@@ -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;
index 641d9ee97f91fcc3a92b456e7007578dbe269d2e..48b70e6490f32e9c7f9c34f8dcb20735279b3946 100644 (file)
@@ -481,17 +481,30 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
 }
 
 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);
 
index 69f4fc26ee398002879b7383b48f14a27e26c015..5bc71642b22605367ee319abdf8e45a0ec9adcde 100644 (file)
@@ -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 @@ int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value,
        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);
index 9bc0e580a5b3fa44dbacd26ec0196e1ec4bd282b..8aef2b304b2d2bd2ad0c26942765e4bca0362835 100644 (file)
@@ -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 @@ int ovl_verify_index(struct dentry *index, struct path *lowerstack,
        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;
        }
 
index 60d26605e039ede4fb95c68a54090b97baf80801..e927a62c97ae3c92070dbb440712c819cc8e827f 100644 (file)
@@ -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);
index 0298463cf9c3f89f2e3d5ae0b57c2940c774049a..3d424a51cabbf7f1739f154c4d8a7b5616262029 100644 (file)
@@ -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;
index 44dc2d6ffe0f077c09767320ba149eeac42ab5a5..d86e89f972016b4046b20a7a45c2f3f436c50f02 100644 (file)
@@ -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;
index c492ba75c659513c45f9ac750fbe6833a506b230..f46ad75dc96af187ea22990a09e63d051aa4bbca 100644 (file)
@@ -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;
 }
index 18694598bebfb4781c79cb9c75107f37e54349c4..aa2b8907163086daf83034a3dcf54b011d794fe9 100644 (file)
@@ -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);
 
index 8a428498d6b21f08c8c26ef184ff9f4332b5cdd0..509a61668d902b84f6756e2ed1bcb22a6d7020a5 100644 (file)
@@ -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:     ",
index b836fd61ed878a38d25d5ffe44bb86e30066955c..fe8f3265e8779ac18a5694ef600c024f9e88f281 100644 (file)
 #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);
index 3d2256a425ee7a71e97603778e0eab428db84be4..54415f0e3d1868601ab08a6ff49d2fb29cdfb2da 100644 (file)
@@ -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;
index cadcd12a3d35f6ba5deb54df94c995b19d3d34a8..b0d5897bc4e6d0e019c79f65b6d41df1d3b0d050 100644 (file)
@@ -854,6 +854,9 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
        __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;
index 0a9880777c9c2ff51846e09efde4933e5a6ace3d..c09c16b1ad3b8b1f883e2ee93b9fcc275c7ed63c 100644 (file)
@@ -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),
index 4da85fff69ad0aa390a73fe4d5f47ae766b56abb..e0bcc4a59efdac646947f917f8c5d2a7713997fb 100644 (file)
@@ -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.
         */
index d478065b954478c2f61bfe39c2ee9d59e2255d9f..8727a43115efd54757e89862d6e38dce3b35da2e 100644 (file)
@@ -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);
index 900ea231f9a3d3d0e8bbbf9bb0f43e24f342f3e2..45b1c3b4e047b1682ded2e0aca55f7160163986e 100644 (file)
@@ -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. */
index ceef77c0416ad5833c2b513006496c8d57a4c62f..ff48f00968100df0de830892f0c9aed7bca6d74d 100644 (file)
@@ -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:
index fbe72b134bef219e80420063bfe2db2abc594e49..43aa42a3a5d319fffff98417bff98055083f1a75 100644 (file)
@@ -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
index 6ce948c436d5f37029d49c2a1e974a5c75baed37..15751dc2a27df04a4608754ff8250de6ae8bd77f 100644 (file)
@@ -111,6 +111,9 @@ xfs_qm_dquot_walk(
                        skipped = 0;
                        break;
                }
+               /* we're done if id overflows back to zero */
+               if (!next_index)
+                       break;
        }
 
        if (skipped) {
index ab2270a87196949357ea2e29f921db0762d9d6d7..f45fbf0db9bbea2cfb9578afd76de61b44bc7285 100644 (file)
@@ -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)
index d4b72944ccdabc89748f054dd92c7b355f05de5a..1e3a74f94131eb15448f9c48c8410d75602949cd 100644 (file)
@@ -3,6 +3,7 @@
 
 #ifdef CONFIG_ACPI_NUMA
 #include <linux/kernel.h>
+#include <linux/numa.h>
 
 /* Proximity bitmap length */
 #if MAX_NUMNODES > 256
index 8afa4335e5b2bfd0c42c00e1b1506d4e1f7377ac..faddde44de8c902e6884e64eeb8b22bd0d11b75a 100644 (file)
@@ -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 (file)
index 0000000..9b30fec
--- /dev/null
@@ -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__ */
index 39df16af7a4a41e1082c6403e3bd3bc47d168fec..7277783a4ff00c1db7c3816c73547f4e0defd96b 100644 (file)
 #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;
@@ -305,143 +296,6 @@ struct pci_controller;
 #define DRM_IF_VERSION(maj, min) (maj << 16 | min)
 
 
-/**
- * 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()
@@ -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 */
 /*@{*/
index 0196f264a418a1d0885cd5cb4ebbf3ab56f3c91e..8a5808eb562876cd35f2d3f098db5c9156757f3b 100644 (file)
@@ -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
index f0a8678ae98e542c8632262437c3f5568ecf2398..d2b56cc657e933593c8c8298c931876061f46e34 100644 (file)
@@ -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
index 1dc94d5392e27d6abd6f0f7b4ad2fd8b5ecad975..6522d4cbc9d9d7426728198024ce44aa622f2b32 100644 (file)
@@ -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
index ae5b7dc316c8ac586f6f72e9d3cb26f5fbec2557..ea8da401c93c14248374ffaabb1675c2e1bf45d4 100644 (file)
@@ -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.
index 629a5fe075b3f7fc3d915e8204a279af1211dc5e..1a642020e306778e55ee65e8a535c0746eb07372 100644 (file)
@@ -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 (file)
index 0000000..e21af87
--- /dev/null
@@ -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
index 177ab6f868554c23169c654b7c97545ecf77de14..d55abb75f29ae1f998a8cc3f0124bacfceb10170 100644 (file)
@@ -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
  *
@@ -418,6 +423,11 @@ struct drm_dp_mst_topology_state {
  * on the GPU.
  */
 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.
         */
index d855f9ae41a80e4c77b396e7210609cbee91798e..71bbaaec836d29f491fc78c74c5fa4801873fa9b 100644 (file)
@@ -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);
 
index 7b9f48b62e07cda87f74b5d6df617c2dc54734ef..1e1908a6b1d66eddede740c60ccc5084e2f49deb 100644 (file)
@@ -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);
index 199a63f48659a8956bfe6350b1778e35c589a95b..a323781afc3f3a73a6c0bdbdd7ac1dfc5b10e9a0 100644 (file)
@@ -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,
index 119e5e4609c7cef6fe6b099bc640495d7c314050..33fe959277428baa28922c8d35c44a854474117c 100644 (file)
@@ -84,38 +84,6 @@ struct drm_fb_helper_surface_size {
  * Driver callbacks used by the fbdev emulation helper library.
  */
 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:
         *
@@ -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;
@@ -200,6 +173,18 @@ struct drm_fb_helper {
        struct work_struct dirty_work;
        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:
         *
@@ -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;
 };
 
 /**
index 5244f059d23a06f6ad58fb6388451acf76cb8081..b6996ddb19d6e8831d74aac16d6be98d6c72bdff 100644 (file)
@@ -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)
index 663d803580578b9ee198ff9f4402dfa8c86cd05c..9c55c2acaa2b366dc5b93f068f66575aa3177a64 100644 (file)
@@ -130,21 +130,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:
         *
@@ -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);
index b42529e0fae0c68d96fb8d947f53bc383236b351..58a739bf15f1fd5d5cfb112dfa9b425fc07f5856 100644 (file)
@@ -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 (file)
index 0000000..db9cfa0
--- /dev/null
@@ -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
index 42981711189bda6d93d282ede8d5607f88b1d434..1b37368416c8561f63aea14205f537056be98525 100644 (file)
@@ -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;
 
index 94ac771fe460b1aea79918d55ecdfac3f318a23a..9f3421c8efcd870a410eb3a2ba1d97d66e8035ad 100644 (file)
@@ -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);
index 85984b2082182b510479c806f3efae6301c1cd7a..c55cf3ff68477b8b6e0009a8c54e5b33238df9d5 100644 (file)
@@ -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.
         */
@@ -266,22 +266,6 @@ struct drm_crtc_helper_funcs {
                                    struct drm_framebuffer *fb, int x, int y,
                                    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:
         *
@@ -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.
         *
@@ -315,24 +299,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:
         *
@@ -432,6 +398,30 @@ struct drm_crtc_helper_funcs {
        void (*atomic_flush)(struct drm_crtc *crtc,
                             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:
         *
@@ -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
index 4579fac1080c665b49b9fb3572768072f17228cd..674599025d7d3b15fb08e5a7337475f8f9d588a8 100644 (file)
@@ -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
index 9ab3e70448127902aad5414f7fe1e109ed298e21..73f90f9d057f984a34ff541c3f110e7d61403726 100644 (file)
@@ -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,
index 619868dc08d8c13cb235b4063eb7013948aefe9c..37355c623e6c32888b2f7b2defabc8f023e7bcc4 100644 (file)
@@ -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);
 
index c25122bb490a345528f0228b0ef11ff542c5bc50..f92eb2094d6b1915630e299fbde67858ff34cd5a 100644 (file)
@@ -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
index 2d36538e4a17ebdabe7fa9e20de25fb8cf952dbe..6d9adbb46293310cb09780ec509f048b94642a41 100644 (file)
@@ -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 */
index 4cde47332dfad6163c6a113b89823655061b09f3..7fba9efe495165097a08930b5d1e769f1626902b 100644 (file)
@@ -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,
index d137b16ee8734ee2a0ec648509e1e83890dbcf43..83346ddb9dba5bcd0101b0e7a86fadab6a699f62 100644 (file)
@@ -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,
index 9b9b6cfe3ba526b1c9e0d49adb28813a201a9764..d554ded60ee989a087fe16b6cef5b636d18e9174 100644 (file)
@@ -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);
index 00b800df4d1b2b6c6cbe69a3646c8fc577b524db..4774fe3d427393ef7e1809b1512d7b8c3ada6870 100644 (file)
@@ -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
index 990d529f823c6e751c0fdb60130fe1b924b83416..5f821a9b3a1fa8110186c964a706805714a33966 100644 (file)
@@ -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);
 };
 
 /**
index f6e030617467f4d98d0727d480ea3d5d1ac7a0bc..f87fe20fcb052eeb63e4879a03478ad9b5bf8e7b 100644 (file)
@@ -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)
index c749eef1daa1557910ec81c5f296dc907f5ccab2..27b4b66152637fe38b82711f0fa66d6ce946f7d7 100644 (file)
@@ -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; }
index 05488da3aee9db28e3a233564421efe6971a2a32..3ae9013eeaaa4367bb160aef88b36ab549b0446d 100644 (file)
@@ -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);
 
index 360c082e885c7777ef6d9509dec75bbb6ee3fff3..d41d40ac3efdb940bf96391d17ee737456cd24c2 100644 (file)
@@ -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); \
index 621076f56251d860f647981b95e2e64cd8e9a5da..8e5d31f6faefd361cee145be654a968123ae5e6a 100644 (file)
@@ -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 {
index 408bc09ce497bb14fdd058b11debbdda7c22fa78..cb28eb21e3ca52054fbb65d72e22c93127aaf472 100644 (file)
@@ -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 *);
 
index f0f6c537b64cbc37bfba285b3373ee085ef806e2..040dd105c3e72aa4d9e20621515381192ab2b07f 100644 (file)
 #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);
 
 /*
index c6d96a5f46fd6127c712d1cea79e4e47075a24e7..adf670ecaf94688449f92f240dd3f0bde3b87500 100644 (file)
@@ -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;
index a0996cb9faeddfff86a9837676aa3a79da1f01bf..af3444a5bfdd1a0e45493d9603596fd38c042a24 100644 (file)
@@ -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,
index 385db08bb8b2d0a16b6fdc0188e7c5701fa9ef50..b8281feda9c77ac7a821a06f28da03fcac5565fe 100644 (file)
@@ -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
index cd4bbe8242bd89802c0440329615c6c64fedbd69..bdb80c4aef6e13631075b2ad06b39d2788c8eba5 100644 (file)
 #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
  * 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__)
index 219f82f3ec1a731c251b68e40623c01e3152f7eb..eca8ad75e28b054db4657d5e562b3904120b042e 100644 (file)
@@ -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.
index b56573bf440db4b85f8f11f678edb9e28d4e6cd8..82b30e638430fa6e9b3b410feb84bc79a4bf2b13 100644 (file)
@@ -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,
index 119a3f9604b0d90b499bdbd6627d30fbc936469b..898cfe2eeb420ab8bf7201bf4b01dd315bdb265b 100644 (file)
 
 #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);
index c728d515e5e2fb66ea7a3cc4a3ff93ae9e978b2e..099058e1178b4d8529438450e28ad03b06497d32 100644 (file)
@@ -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 *);
index 92e165d417a6119d200ce1dbf2972c7297d6da1a..07eed95e10c7d67b8a2c0543c152672bc6019203 100644 (file)
@@ -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 */
index 79481187573288505a8136e8dffbf810cf9088a2..df97b7af7e2c7263c4ae9fb1608b19aad1ae02ba 100644 (file)
@@ -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
index 3f3ff4ccdc3fdc37c87ac345e2c49037ab3294e3..aae1cdb76851308dd825e1558cf007a3722dad73 100644 (file)
@@ -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:
index 723cd54b94da84f95cd18934d14198b6d21040dd..beabdbc0842059b36a2c6b22b882e04ddc968f75 100644 (file)
@@ -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.
index a5195a7d6f77e40d23d29ba2793c7b393f4eb0bb..171895072435bd7efa0303e401a3f907d12cdc7d 100644 (file)
@@ -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 */
 };
@@ -335,6 +337,19 @@ dma_fence_is_signaled(struct dma_fence *fence)
        return false;
 }
 
+/**
+ * __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
@@ -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;
 }
index 843ab866e0f487c2000e0974592ee98544293758..03c0196a6f2474ea4e34e9840638ff80a45370ec 100644 (file)
@@ -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)
index 7b5d6816542b7f5af171d5680961aeb03184707b..6e1fd5d2124877c16bbbfab4487a772c8f7e37ee 100644 (file)
@@ -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);
index 0efc3e62843ae74592128dc7e34bd11fbaca4a3c..7a026240cbb1bc0b45f65ac9b14a1f1823501c06 100644 (file)
@@ -12,7 +12,7 @@ struct fs_struct {
        int umask;
        int in_exec;
        struct path root, pwd;
-};
+} __randomize_layout;
 
 extern struct kmem_cache *fs_cachep;
 
index 5857390ac35aa37d4d2431504adc98c3a3075026..6383115e9d2c5c6459973a1d2d74609aeb438b9f 100644 (file)
@@ -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;
index 00ca5b86a753f8023cad87ce02cbe90748255383..d501d3956f13f041864dc25f0d7e8724ea2b5210 100644 (file)
@@ -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
index 497f2b3a5a62c8da6f87107de16519b176cc9f1f..97f1b465d04ff0b1ab33b0c1074a722ca41c1b0a 100644 (file)
@@ -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;
 };
index 5591f055e13fd0777da082846331b6d106e3a33d..fadd579d577dc8aafd7c100ea51fe2bf630c76a0 100644 (file)
@@ -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 */
index 848e5796400e797a57fb0ab253c6accc215ed9d4..65327ee0936b314fe38fffee3ffb5f882d8883ac 100644 (file)
@@ -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;
index e1b442996f810529a755533270b6d21c350fbd5a..474d6bbc158ccb3797a93a02740852b6046ccac8 100644 (file)
@@ -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)
 {
index 00db35b61e9ec1e3dc850080681ed93dffa959ad..d2d543794093f1272aa62551cfb9867195b490cc 100644 (file)
@@ -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
index 348c6f47e4cc36681e55ff4800a4d2a4e052f954..8037850f31041696a30a046696c99f902d222b03 100644 (file)
@@ -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 */
index 8496cf64575c679b49a0eeedf0c0d3c4d1e2dd1c..9520fc3c3b9ab376ae571cb9895d0dc838212ffc 100644 (file)
@@ -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;
 
index c4e441e00db57c85103e93ffedd16674762df5af..655082c88fd93b5057fc641d196aae66d805850b 100644 (file)
@@ -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);
index eeab34b0f58912bbcf92607f90cf022414378410..4d800c79475a29fca0cf87c6936174c4ffd509d2 100644 (file)
@@ -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);
index 4fec8b7758951cf9395613b072659efdce33e1d1..82e197eeac91f2bff8b62df9a58c75b5645b1ca2 100644 (file)
@@ -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();
index 648b34cabb38214e6bb957aeecbcf61e03a26d4c..21a6fd6c44aff62baaea860fb05fb02cb69c0444 100644 (file)
@@ -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)
index 55de3da58b1c4f5582f95e09a868f6ffb1de852a..931c32f1f18d38835425eb21a4c952e1195e4f10 100644 (file)
@@ -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 */
 
index d11738110a7aeff53b1349f994e3e435d2f0e76b..1957635e6d5f7b677896c50921627aff79445cfb 100644 (file)
@@ -92,6 +92,23 @@ static inline void init_llist_head(struct llist_head *list)
 #define llist_entry(ptr, type, member)         \
        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
@@ -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)
 
index 7a86925ba8f30033ef2402d7a34b76c1498fe2bf..3a90febadbe20e6756819dcd04e235a05fb7d99e 100644 (file)
@@ -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
index d5bed0875d309ce95025dbcab502f51815ca431b..b54517c05e9ab20fff33e3526fe0ea8de1e702bb 100644 (file)
@@ -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,
index 87869c04849ad6681cb3604320c8c39a5745e995..3030121b474601b3dc7003bb5b0a48a1a5d5f5ba 100644 (file)
@@ -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 {
index 6f41270d80c03128bdeb60e5c6fc1b6ca2b5fe54..f378dc0e7eaf4db75eab8606f03df4e9269602e4 100644 (file)
@@ -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,
index 45cdb27791a33ff8d494549ce92f080a93434889..3cadee0a350889f748e7b1a999b449ae003e9c3f 100644 (file)
@@ -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;
 
index 8eb9a1e693e5b3ae245e93771b4489d5307b08b6..e7bdd549e527bde19eeb565f8e5735d80f589d92 100644 (file)
@@ -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
index 8e0352af06b786fb0cccde2022af945772f5091e..1ce85e6fd95f798a2e0f2afbb470515d8b0e40dd 100644 (file)
@@ -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;
index f3f302f9c1975a67ea1c01a828403950fac8a061..a001305f5a79959a5e4f816320f3c4276e308e12 100644 (file)
@@ -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,
index 892148c448cce2c9c9e9e59b2d44941283635cbd..5216d2eb22891010187b86a5911a10b17aedf273 100644 (file)
@@ -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;
index a4b97be30b28109c4f2987737e1dc532f2b8cf6e..22f081065d4966dbbd3c09bc2b3eea5ecd8c8cf9 100644 (file)
@@ -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);
index e52cc55ac300f56b7ea876fe05d3377163d4f358..5cc91d6381a35ce73d64fbf40743a21ef2876d68 100644 (file)
@@ -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;
 };
 
index ca3bcc4ed4e55563ecd505fada0cc0dc1f5dbb8d..62cbcb842f99c2cbda7121bcb5a4ebc5e818a3bc 100644 (file)
@@ -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;
 };
index 6c8c5d8041b72ec01097d1c0563b793ea7449f1f..2591878c1d4804d374d39491c2a3f64d1b43a214 100644 (file)
@@ -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;
index 21c37e39e41a2829c77ebac20afcd8a38102ac57..36cca93a5ff273e22be5511b44a33c4d9b3f8796 100644 (file)
@@ -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 */
index 6b8ee9e628e1890e616b4708c0ceed22a903df86..25d8225dbd046d4dcac62e8261d1e49981b72df9 100644 (file)
@@ -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;
 }
 
index baa9344dcd10deb9aaf418a76afa901d2a7f1558..79b36f57c3ba42271b4f09f1d771fb80a835c0ad 100644 (file)
@@ -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());
index d1372186f4315c3de45b3949017026dca2d7f109..cde895cc4af4cd5053f1a0f477f15c6a1240eedc 100644 (file)
@@ -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 *);
index 4869e66dd659a6bc8fe4ad90df2ed9d3ff98ccac..a75c136738529db410baf870f3baafc6e178a5a0 100644 (file)
@@ -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);
index 1360dd6d5e617a0fee746a0d530129e66530a0fb..af0f44effd44abc067d7f31e498c433fd061725e 100644 (file)
  *     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
index 2a9567bb818636ddf979d8a2d6708991ee06d1a5..0bb5b212ab42e4a430ac721362d317f51c0f637d 100644 (file)
@@ -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)
 {
index c2a989dee876360d85f305965e34c1dddc0a9c12..b09136f88cf45c3bd84064a88f441c41da6730b3 100644 (file)
@@ -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;
 
index 231d3075815adfa63d462a236e66f214c3216117..e91d1b6a260d5996583a4365d4020524ad57700a 100644 (file)
@@ -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.
index 8e981be2e2c2ee8c0472e7824300a6178b474640..0ff1e0dba7201b146a561369ddb3deedfe4d7d67 100644 (file)
@@ -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 (file)
index f4e4a23..0000000
+++ /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__ */
index 79b0e4cdb8141a10e73affb9a837d5bcc5f00a2a..f8274b0c68880ccbd02de1a85ece46a3cab2053f 100644 (file)
  *     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 */
index 58ab28d81fc2ecd4f78f37a81ac07a56d984f2e5..06844b54dfc17a222dc42ce17d4cde5e0d848a8e 100644 (file)
@@ -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;
index a026bfd089db81191b5a322979d4bf58c2777dc5..51349d124ee5d47ded05a433028d765858c61f00 100644 (file)
@@ -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
index 156cfd330b6675c79780418e53cd0057410556ec..21fc84d82d41572db2216c4baf07b32c45044ff8 100644 (file)
@@ -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);
index 2ba9ec93423f97e97d0dd5ed99d0ee7fb23038f8..8337e2db0bb2e71473f94c283c5e51639ddd8dc8 100644 (file)
@@ -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;
 
index c06d63b3a58389b92483bb6a0f24f427324ac000..2a0dd40b15dbae8c49c6196ee9d13b6146f2df8d 100644 (file)
@@ -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.
index be5cf2ea14ade9d40e88114ea27a5c876423c8a0..de2deb8676bd6c39c55a439b5df98715915eb9c9 100644 (file)
@@ -41,7 +41,7 @@ struct sem_array {
        unsigned int            use_global_lock;/* >0: global lock required */
 
        struct sem              sems[];
-};
+} __randomize_layout;
 
 #ifdef CONFIG_SYSVIPC
 
index 04e88182962511da30753010075c42f8ab30f086..0fb7061ec54c13d29e36ba5b6f09628f4f2ba676 100644 (file)
@@ -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 */
index 5726107963b2d9930d61c3cf5c486abfe244c18a..0ad87c434ae6a344984837e8dd053fe7705d21f1 100644 (file)
@@ -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);
index 3a89b9ff4cdc586a7f657f57ef816a431599aeda..1d4dba490fb6830835bf9a35f5edaf4b14bbe9ce 100644 (file)
@@ -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;
index f73cedfa2e0b97cde1c3bcd1c07d650cf616afdb..536c80ff7ad96680ddcca0a7880cd7df81c57f17 100644 (file)
@@ -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;
index 69464c0d8068a5fd3bf44b8f7b36d899213172c0..79c30daf46a92160d7560bcc44acdb785b672631 100644 (file)
@@ -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 {
index b742b5e47cc209ac60e441cc42fcf8f431239fab..00b2213f6a35564974d5be7ac7ba909c464d3e01 100644 (file)
@@ -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;
 
index c5f2158ab00e48742b0b47d6a18d5e167f50f86b..fd73bc0e902744de88104e2df7a2aaf375beaa9e 100644 (file)
@@ -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));
 
index 021f7a88f52c929ec804d856a8f6541e1c4c6490..1a59699cf82a90bae208d478092a425d926f4d77 100644 (file)
@@ -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)
index 32354b4b4b2ba5ae72034d00c3b1d43fa8c2a15c..b3575ce291483284847ccc7eef5fea679fade38b 100644 (file)
@@ -66,7 +66,7 @@ struct user_namespace {
 #endif
        struct ucounts          *ucounts;
        int ucount_max[UCOUNT_COUNTS];
-};
+} __randomize_layout;
 
 struct ucounts {
        struct hlist_node node;
index 60f0bb83b313af0e5429264bb83296735c8cdf01..da826ed059cfd7de52135a40caafe5589b52d2d6 100644 (file)
@@ -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
index 2251e1925ea4f34b491b615288c19ca6aba921fb..33b0bdbb613c6b63c9d8c16ca8ee155e981f52b7 100644 (file)
@@ -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
index 586809abb273498705be4d75a0e2571caa81ec7a..a47b985341d12cb685a525c9a5d7179d376cb6a9 100644 (file)
@@ -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
index b289c96151eec4395197236f567b957687565130..5b74e36c0ca896481acd04bbea92be002ad4ba64 100644 (file)
@@ -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.
index c102ef65cb64a94269b950ff09c47d90bbc2d315..db6dc9dc0482bf1299c010f54873f2ae36a4684e 100644 (file)
@@ -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))
index 298f996969df632ba41b6c68f3d815678c89e079..a4f7429c4ae533a07d9c3efdeebb62892fcab2f6 100644 (file)
@@ -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
index 7c909da29d435759970b0523cc5ce98ae6493955..6ea2ce2418511255c3c7ec63ced3c2eeb34a18ff 100644 (file)
@@ -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;
 };
 
 
index 8e1a4d88daa024cc2b5df4e687d1d96f3925ae61..f003533602d0ff14e5393bc8f2d42941a658c2b2 100644 (file)
@@ -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 */
index c837383b201393b20de47aa2d7561725323aaedf..68a8abe4fac5a35620dc2fa0a2f5bd6ce02e01ed 100644 (file)
@@ -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);
 
index 678e4d6fa31766d64e93a17bc33a81e5d9b634bf..53b1a2cca42129f69a5e4925421a3f0cb3fb2ca9 100644 (file)
@@ -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))
 
index afc39e3a3f7c030d7f1d5d3d6ae39b0acd635c9b..9816df225af3b4c29017e6a762315e85b3e2733c 100644 (file)
@@ -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;
index 31a2b51bef2c8f05a68f3d6ff3923d94a77592f8..1c401bd4c2e0b78d77a6e94507a9525be716c6d4 100644 (file)
@@ -148,7 +148,7 @@ struct net {
 #endif
        struct sock             *diag_nlsk;
        atomic_t                fnhe_genid;
-};
+} __randomize_layout;
 
 #include <linux/seq_file_net.h>
 
index 01709172b3d38455e7e5510228d6b4a0ad6e94a6..ef8e6c3a80a63f6c41f92e82405a5a77c1264ed6 100644 (file)
@@ -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
index a9519a06a23b2083b4eec970eb2d99d98216aa83..45fd4c6056b53cd5fd88d84d45509277921aaf29 100644 (file)
@@ -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))))
index f69c8c2782dfba68c6f080902cbf5feb0a40a2f0..7c0632c7e87043ca18fe5d32d7d55792f75ca6e8 100644 (file)
@@ -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);
index 70483296157f87acdf5acd5e96eaa910119ba220..ada65e767b28dfcabb662a7b08f65c6fc04f5b73 100644 (file)
@@ -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
  */
index 972ce4baab6b2a4b0539624d1a671c632d77514c..cc8036987dcb885012c6c5eda0fb2bed2e588841 100644 (file)
@@ -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
index 4b34c51f859e89406802d9b5b8c3644c81861629..b73a14edc85e3570e2394fbad23234f689f3a956 100644 (file)
@@ -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);
        }
 }
index 356953d3dbd18c351313b3f5e36e92ae24b58cda..b5732432bb297dbf6067ae34b16c00073cb2949d 100644 (file)
@@ -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 */
@@ -2947,6 +2947,22 @@ static inline int ib_post_srq_recv(struct ib_srq *srq,
 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.
index 4878aaf7bdffd871515bc826470ec77886a1c02c..55af692710539d6555c072a0c2a290aca7bfba42 100644 (file)
@@ -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,
index be6472e5b06bd1ed1117e928e9b3d44748dfbfeb..d664d2e762808321d7b2aece6d3146b713b51631 100644 (file)
@@ -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;
index 1df2ff61a4dd95dda25c5962a6335cc6fb9ca44f..0e495ed8872ee14750c6647edf169ccc2946144b 100644 (file)
@@ -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;
index 9c94b97c17f8ebc830f9ccac9e00c9a0b0e1d463..c4a8b1947566bb659f47051f5987e01a1e2918f0 100644 (file)
@@ -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);
index 0ca1fb08805b254fa8ffda73f4decd4c48ac2211..fb87d32f5e513de3c2a1b7c6f402b5f48e401c45 100644 (file)
@@ -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;
index dfae175ddebc2340c68e9145d588f57f2f45ebce..9c3bc3883d2fac1fbd4683d9eb4efbd74282f5c6 100644 (file)
@@ -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,
index 06d5f7ddf84e73bc08e1719c1c97795ada561fff..14baf9f23a14b952e76e9d4aaa7030e53e5092ed 100644 (file)
@@ -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
index 72e326f9c7defd73eab70d139dde8d867e3bd776..0cb932416cfea4ac5f24e319bd883cace23ea08b 100644 (file)
@@ -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)
index 7586c46f68bf22f48a1536c0f27eed0d8d06eb92..76c9101a7fc60993ee7187c1a62a6f7c9248cf0d 100644 (file)
@@ -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))
 
@@ -196,6 +198,15 @@ extern "C" {
  * authoritative source for all of these.
  */
 
+/*
+ * 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
  *
index 403339f98a925edb15d25974a5ac227216211800..a2bb7161f0208d107a184e7c5b61dfc9355a7df4 100644 (file)
@@ -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.
index 26c54f6d595d4070c7708ef22daf7533468404a2..ad4eb2863e70ee195f9abc68e6b8c3c3020f27bc 100644 (file)
@@ -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) */
 };
 
index 7eef42213051b4e80197c7983e12ed1cd79b4f20..880999d2d8630dd1408807342d0f127a4185e2be 100644 (file)
@@ -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 {
index 6ac4c5c014cb9b98343f25721f74b727a88f2bb5..afae870049636e9c5db9a10a03d40dc3beb4c6ee 100644 (file)
@@ -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
index d2314be4f0c03381c1390f0d0d3eefe4f958f4ed..a4680a5bf5dd4724aad4d16743543f3f35b52be3 100644 (file)
@@ -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));
index d1767dfb0d95d76dff1b91bb5c2b40f18fee8f6f..8906361bb50ca318fae27126799629210446b3f1 100644 (file)
@@ -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
index 5b25e0755656a6a2b85a7f647bf77cd87db77a5a..2c38f10d148305857a6388764b0ad1501f227bce 100644 (file)
--- 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",
index 9e70cd7a17da7e74e915ce7f4061aa99aea66b89..38371e93bfa5c4f101e264b46eab6a19f2f02404 100644 (file)
--- 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;
 
        /*
index 28a444861a8f489fa46edca81878eedf0f55da7a..8828b4c3a19041833f390d62f38084de2f64470b 100644 (file)
--- 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
index 833267bbd80bc62b367699eb9cdc646c20fb264c..6dd5569317393889d2f90814dc7b15a840f7e0eb 100644 (file)
@@ -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;
        }
index 045646da97cc5dc55a5063301a2e76e4178a8ea3..6c772adabad2909628ea9199cfb10d0b07f2ac82 100644 (file)
@@ -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);
index 6a86723c5b64bad1534d6519f33e03e9ad4fad99..664d939723739e0333fb5921533e3327912a3b84 100644 (file)
@@ -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,
index 793565c057426656312ab7b31471f6c523b7ae59..8b4c3c2f2509d2b49666410b011bf604926194f3 100644 (file)
@@ -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;
 
index 620794a20a339c7e10948da829fae5a6818e598b..df2e0f14a95d8e75ecbf424a0e308cc52d5b5eb2 100644 (file)
@@ -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 */
index ca8376e5008c7c16ca91175e3ad1021ec69e2777..8d51516885047c7807cb050979c1ebbdaec6dc07 100644 (file)
@@ -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. */
index ab860453841dfd244c141f329fa9cdecc1f9e063..eee0331342628f09a02720ffe34aba2f8fb12f31 100644 (file)
@@ -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);
index 1538df9b2b65d57ebc30b9d156acc2dcb71e7fea..426c2ffba16d4ce1474a798a4c43d78d5abedb1e 100644 (file)
@@ -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.
  */
@@ -7356,12 +7353,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
index 17921b0390b4f91113bcf8c9ccac5c1225751460..e075b7780421dee1d8243b9dc178248398c5f189 100644 (file)
@@ -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
index c934689043b2bee840513ff2856e0dae74ed5ca2..f50b434756c18eb0c200ec6e3b4db16231062f24 100644 (file)
@@ -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 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
                 * 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);
 
index d171bc57e1e01830d6540cdcef145d25797f1393..a3cc37c0c85e2267497f650611b656af90aaf5aa 100644 (file)
@@ -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);
index aee8f7ec40af259d605b370fe22045c589180f25..638eb9c83d9f75b0e73c0d80e2c87f6e4c2e02f3 100644 (file)
@@ -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);
index dbfba9933ed251c23deb6eb9e34155b1ca1c19f2..a2c48058354c871803eb9650db60acc0e7cb4b13 100644 (file)
@@ -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)
index 5624b2dd6b5807a0658dd8ce1a9bb3dd62a75209..1d1a5b945ab428008ebaa8b31cd1f2a638f6aa97 100644 (file)
@@ -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 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 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);
        }
 
index cea1de0161f18a164aebb84e275ad67d5899eda8..6bd9b58429ccb6524b78f07315ebca5cf10b16a3 100644 (file)
@@ -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);
index 78069895032a9abb38fe19415a7faf3e7d01b884..649dc9d3951a5fed57930769957552841528f784 100644 (file)
@@ -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;
index 731c4e528f4e3cb2150370b37dc22afe9dc8e5cb..c69c30d827e5a2fc2605c6449617eb3754d8479b 100644 (file)
@@ -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)
index 222317721c5a09291c6b78fc839e722b2196b177..0972a8e09d082d99c7f197cbe6bd4fdb6475ba33 100644 (file)
@@ -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)
index 17c667b427b4a570611272f2906a8bf50778a7ce..0869b20fba81f6f1a7f5f73bde65fadc483f0fa2 100644 (file)
@@ -2069,7 +2069,7 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
 /**
  * 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
index 6e3ea4ac1bdaf2d18fbb0fd07f2c5bddbd0ce5ed..14d2dbf97c531db0dd0c1bba3113a35cbe8d3bd9 100644 (file)
@@ -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);
 }
index a84299f44b5d8c2990e10f9a74d1818fad3a7040..755bd3f1a1a93a8f1daf713dd36578637ce515c5 100644 (file)
@@ -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.
index caed9133ae52733aa96baf74cb4ef3c344832125..7e33f8c583e64c91d7cb6ac1fb330b01299b7be2 100644 (file)
@@ -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
 
index 71ce3f4eead34afc12fa2743c69e8e9e77c544ad..8f5d1bf18854593e6fa27730d07a99c6700ab45c 100644 (file)
@@ -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:
                 */
index 53f6b6401cf05fe9d63be0b67d646d25eed929e7..02004ae918608f915b28341b6ed1b3b7f551c5a5 100644 (file)
@@ -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();
index 4ae268e687fe1683d9253235d539d840d8bf4f14..529cc50d7243d6c1007e517bcdc83a5312f7ae6b 100644 (file)
@@ -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);
index 2d0ffcc49dba0354e17f2a083d86ad407fc2b425..42b9355033d45d5a7c27bf0606799772e70d7421 100644 (file)
@@ -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);
 
index 6ade1c55cc3acaccaad5f50896708c1774072854..490ba229931d7d00243a1be009dec6ab2b3a5864 100644 (file)
@@ -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 {
index a86688fabc55c4a4ec2bad843f6dc1e0e411f2d1..ca937b0c3a968f247a227d68812c9062fb4916c5 100644 (file)
@@ -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);
index 7d315fdb9f13d9b17d8a2aa129c75790c7599bdb..cf7b129b0b2b08adcc1aae98f990c384761532dc 100644 (file)
@@ -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 */
index 6c1d678bcf8b00ff7b2d2fc70747045e6c14327a..ff9148969b9233ba7502b992b026d31e100be497 100644 (file)
@@ -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) {
index 64e899b633371d252deaf057156408a8ea8f4625..0ffca990a83370d13553266be315f9373d6995da 100644 (file)
@@ -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();
                }
index 478c049630b5cb8e09a57c5ccd012d51b5c4be97..cd819c397dc7ebed8be5bc6167254c543d0f26c8 100644 (file)
@@ -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);
        }
index 9075aa54e95517cdbb1094f04e72c36357401e52..b06d9fe23a28c14f71c3263daaa84965dadeee45 100644 (file)
@@ -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;
 
index db1cd26d8752022b7f8b576cdff78f5412209d39..5715448ab0b53db5d8bd4b64d47706f7deaaf7a6 100644 (file)
@@ -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
        );
 }
index 86975dec0ba160feadfb8aa0d13b8f2be943638d..216114f6ef0b7f8c09378edd3615d6a39527ead0 100644 (file)
@@ -1495,6 +1495,13 @@ int do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd)
                goto clear_pmdnuma;
        }
 
+       /*
+        * 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.
index bc48ee783dd9e1e31f03a4b0393ef2902ea00a6e..31e207cb399bebd11371e46eb26f625a5b74487c 100644 (file)
@@ -4062,9 +4062,9 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
        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 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
         */
        *position = vaddr;
 
-       return i ? i : -EFAULT;
+       return i ? i : err;
 }
 
 #ifndef __HAVE_ARCH_FLUSH_HUGETLB_TLB_RANGE
index 24d88f0847059ebc028ce9fc9eabce90caae40b9..4ef49fc55e58bdffd54a592d5f27813a2580e643 100644 (file)
@@ -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[];
index 04bb1d3eb9ece0480182f2c738ed9d827fea3c62..6bcfb01ba0386e5bf2ec49512321e59a1fac0661 100644 (file)
@@ -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;
index 4dc92f138786988c4ef0f9d371ff8a48b2e6e905..db20f8436bc3c15bf05f86ccec5e7b1f80d807cc 100644 (file)
--- 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);
index 9976852f1e1cb25c986cf69c1846ba8f17e981fd..47d8d8a25eae49604f81bcffe40e45ef9b8e4c6c 100644 (file)
@@ -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;
index 0e517be91a89e162bb868af9835c8641aadfd01b..e158f7ac67300b10b8827fe6825667506095f550 100644 (file)
@@ -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 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
        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;
index 62767155187356d54d1fa7333ad402e76183ca0b..d68a41da6abb0743d6b09cc49c5c9524463715c3 100644 (file)
@@ -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);
index 1a8c9ca83e48ec9a998ea0882e24c58dee0d3dd1..bd0f409922cb2fc133f9fecba64a839380d4f937 100644 (file)
@@ -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;
 }
index cd8a1b199ef9496ef63a50d97f92e648b8eecd58..3f23715d3c692770193ff99e707131d95369065c 100644 (file)
@@ -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 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
        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;
index 6d30e914afb6c1b9ecc77b33ee5e01fc7a0ed6b3..6d00f746c2fd96452661fde3f704289eed7f1f70 100644 (file)
@@ -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;
index b6c4ac388209c945d744f2541326411314a1cceb..5f61b54ee1f38e0bb7ae7bee3efe3257f8967a44 100644 (file)
@@ -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 @@ static void end_swap_bio_read(struct bio *bio)
        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);
index ced14f1af6dc29ac2337eac9806eb6415238536b..c1286d47aa1fad7fee7ea5bb865a2dc7efd672f2 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -604,6 +604,13 @@ static void set_tlb_ubc_flush_pending(struct mm_struct *mm, bool writable)
        arch_tlbbatch_add_mm(&tlb_ubc->arch, mm);
        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()
@@ -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;
 }
 
index b0aa6075d164df9ae4766876cc823394abaebc6d..6540e598244412023db650412062604b704b58b3 100644 (file)
@@ -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++;
index 7b07ec852e01fa931b2b302e8df5cff9f17f62d6..9ecddf568fe30e5cf1fba6db8eda3b7abe96d379 100644 (file)
--- 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.
index 013eea76685e1c5fea8a3ee3dcaae37acbbf2395..308acb9d814b68d006775cb396479c2f328d9865 100644 (file)
@@ -2453,7 +2453,6 @@ void zs_destroy_pool(struct zs_pool *pool)
        }
 
        destroy_cache(pool);
-       kfree(pool->size_class);
        kfree(pool->name);
        kfree(pool);
 }
index e1133bc634b5e8ed9a4639677e577a0d52e7c1d5..8a3ce79b1307b7f260ce2f64e96bdacfb9a322f0 100644 (file)
@@ -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();
        }
index ea43a64492479809fe6bdf95b436792078f50e9f..a62795868794103d7e712ba91def5997dc3a5779 100644 (file)
@@ -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;
index f0f3447e8aa48ff02c3f11f6da0e65e79cb28e90..861ae2a165f4dc3271b648794486e6a768590733 100644 (file)
@@ -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)) {
index 013f2290bfa56df90708879437a762c812dec101..7637f58c12263bae0bc907d01d0838c1fd68cf5c 100644 (file)
@@ -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)) {
index 746b145bfd113975e1f17399d845e2fcbdc7541a..417df675c71b0a2e53a25b0f7e9195c6f3c7804e 100644 (file)
@@ -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)
index 0c31035bbfee8cd682ccf63b3e00728b6252f545..a67298c7e0cd4f8f7a441fa938af57e37c4bd4da 100644 (file)
@@ -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;
index 86a9737d8e3ff7f86c0ea12e9d417e084b725816..dcfbdd74dfd1f13ce51cde01f541974517b35f9b 100644 (file)
@@ -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)
index 864789c5974e072698841bf6207e9f044e2b8a78..f358d0bfa76b35cb978e9e92b57aea38a4e3b391 100644 (file)
@@ -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 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
 
 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;
                        }
                }
        }
index 8515f8fe0460ae08e08e269a47524e0738714626..ce15a06d5558af0292cc739b42a7dc3c1d89428d 100644 (file)
@@ -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;
 }
index 82fd4c9c4a1bf491f094a17c774c3e611c483690..709a4e6fb447fda886046308de5b613a88ff9dfa 100644 (file)
@@ -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);
        }
 
index a0093e1b0235355db66b980580243dd6619c9aa6..fdcb1bcd2afad5737a2c11fab55a3c214b86388d 100644 (file)
@@ -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
index c7f737058d8964f1bb81c245fd9e5de2648d10e4..f44fc22fd45aca4941c618abf97eb48494a67c16 100644 (file)
@@ -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,
index d3408a69316622a59de0ce19d5197be56d5a87a4..912731bed7b71b9208f3947b49c4b93922f7ab0d 100644 (file)
@@ -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);
        }
index d1ba90980be1325e86836795a354214cb96a4079..9201e3621351144f1fde497dfa1025d93d0a76f9 100644 (file)
@@ -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:
index 1704948e6a12bc87827c71ccb4e81de8b8c2c9f7..f227f002c73d382fecd98c8857ce4c9139cb7a8a 100644 (file)
@@ -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))
index 4a05d78768502df69275b4f91cb03bb2ada9f4c3..fa6be9750bb46d9aeee2462fa86ed1a7cfc40cd1 100644 (file)
@@ -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,
index f85d901f4e3fc02741ad20f3ff3066108af1e7e8..1b202f16531fce72860a78d89ca1af716f883d99 100644 (file)
@@ -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:
index c376af5bfdfb34774d82de6858ec0e4b6e3380bb..1b58eac8aad326b6db09a4cee82fdcc178c2afad 100644 (file)
@@ -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:
index 56e46090526bb3baf26b5e06478cdd66ccc94280..c442051d5a55732d37ddc18187389d66d8d08bd9 100644 (file)
@@ -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;
 }
 
index 76c2077c3f5b697bf8e0d4b030b70dde8fc70345..2e548eca34898f51316275c918bb1f0f4a63526e 100644 (file)
@@ -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;
 }
 
index c4c6e1969ed0606ff9fb4ea46609f75b249e589b..2ae8f54cb32148f2499f78ecbf29259db36bd207 100644 (file)
@@ -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;
        }
index 4e678fa892ddcf1985fb37c3627a660a8f69da9d..044d2a159a3c51bef90acd029067ef047ccaa046 100644 (file)
@@ -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);
 }
index 2221001038084af89b6f9fa0e306c2320ece4a3f..b8d18171cca33ab5dab67408c3cd11ad57f25b83 100644 (file)
@@ -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),
index 8e0257d0120097770e37017439684a2345619f5e..1540db65241a6fd4d96b00546f13a3e3d3cd1815 100644 (file)
@@ -450,6 +450,7 @@ static struct sk_buff **gue_gro_receive(struct sock *sk,
 out:
        NAPI_GRO_CB(skb)->flush |= flush;
        skb_gro_remcsum_cleanup(skb, &grc);
+       skb->remcsum_offload = 0;
 
        return pp;
 }
index 28f14afd0dd3a392da3b84c5e791fffaf46ad254..498706b072fb70e1ffe6b5dba817816db5a4cfa7 100644 (file)
@@ -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:
index 7eb252dceceea31acb84fc0bbc902ca426283154..e153c40c2436109d4bca4a9caf34b90cbf000cd9 100644 (file)
@@ -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 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
        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)
index 805c8ddfe86022e6b47df2026d5c5830c613b0ff..4bbc273b45e871b2c3033bfd31af73f2b8bc9aa4 100644 (file)
@@ -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)
index 0905cf04c2a4e41e06a047ab52de6ab95a5afb61..03ad8778c395334ed53a250bccc0b991cd85c2f2 100644 (file)
@@ -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;
index dbcc9352a48f07a12484e45f3baf0a733e244f75..69ee877574d08b36bc990f890899037108eafe05 100644 (file)
@@ -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;
index 2920e0cb09f8d3e743eb4f49c16060ba1af48ed4..53de1424c13cda5d1fec826b97cacf4f95adc99a 100644 (file)
@@ -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);
index 4e985dea1dd24fdecfbf9b47d51cff698e97cd2f..b7661a68d4984c485a4853441d21abe8da9e325a 100644 (file)
@@ -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)) {
index c0feeeef962aa31401ee90f8bd015c2aae2ef932..e906014890b64ef6a2bfe022e17358bd9659d204 100644 (file)
@@ -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);
index 25294d43e1470757e4631a8ac2af7fda7e810008..a7c804f73990a0610bc85c02fc2dd76858973c22 100644 (file)
@@ -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 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset,
        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 @@ static int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 /* 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.
index 781250151d40ee4559f7b90d15dccad8ffaeafd0..0932c85b42af0bc868badd1771b5cb9353c969a9 100644 (file)
@@ -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
index 4996d734f1d2a8c535aa34f3bd7a7186279a07c2..3cec529c61130f5f43b7d65c4f4cb4ca63d1bf98 100644 (file)
@@ -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:
index 1422d6c083773549d667dc88ffe07d447d5c8e97..2dfe50d8d609a7a623edacbe40e93022dfac685e 100644 (file)
@@ -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 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
                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 @@ static int __ip6_append_data(struct sock *sk,
         */
 
        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);
index e9065b8d3af852c6e9a7359667f68a5ad00bfe75..abb2c307fbe8337ce1714e7392072c945ed5af51 100644 (file)
@@ -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;
        }
 
index 4d30c96a819dee548ec34704a34b22774fac5da1..a640fbcba15dbf246e419d3e03da8eca0fa6901a 100644 (file)
@@ -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;
index 7b75b062073087b7b715629de839dcc107144402..4e7817abc0b934fbff21ba481c3f6773475c7a63 100644 (file)
@@ -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.
index 4a3e65626e8baddf5d7d1c246e6e5fded2b08b8a..578142b7ca3e6e91e528b8c81addec812bb6a5ca 100644 (file)
@@ -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 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
        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;
index a2267f80febbb6f31459097f27bd89d51d0f2b11..e7d378c032cb6ebe80323db987ca201e5ae2d845 100644 (file)
@@ -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
index 552d606e57ca4aac6bfe5ad26c42c385a431ab68..974cf2a3795aaa8ea68a17d60349d4b1cfad9496 100644 (file)
@@ -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);
 }
 
index e03d16ed550d6bf07a537f4b150148a3cd967f59..899c2c36da136fe3e7268e44437a8d49d73789e2 100644 (file)
@@ -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;
index 832c5a08d9a58f216f61008ebdb6636e2384f5e3..eb541786ccb7c79b3498477dfefc2927368f1a6f 100644 (file)
@@ -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
index 92b05e188fd1f8adac7e363f59998ce8310ed9ed..733d3e4a30d85d0bfe5656c1e99a24c01b0fabec 100644 (file)
@@ -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;
 
index 08679ebb3068298a58a081926c6a7dd5a2a73d17..03859e386b47c95838c50dba5e09b75163b759dc 100644 (file)
@@ -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)",
index e3beb28203ebe06a4192ff80d4d0eb3b3741cf41..008a45ca31124ed5fa54d666fce61c7982b12a2f 100644 (file)
@@ -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 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
                        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);
index e10624aa6959b596a2629a9f18bb25504428545f..9722bf839d9dec7fc7c7bed5cca0818389b245ba 100644 (file)
@@ -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;
index e81aa176f4e2c3f42a6ba75769b5d42142c7e3c4..41b9f0f5bb9c7fac6f23efb8fe535dfa8b2f4530 100644 (file)
@@ -170,8 +170,8 @@ int rds_send_xmit(struct rds_conn_path *cp)
         * 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 @@ int rds_send_xmit(struct rds_conn_path *cp)
                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;
index aed6cf2e9fd87792e5124838466a98045fd60ce4..f2e9ed34a963e1a06dbefb792836919d92bf6733 100644 (file)
@@ -835,7 +835,7 @@ static int tca_get_fill(struct sk_buff *skb, struct list_head *actions,
 }
 
 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)
index 36f0ced9e60c03297e195135ca5a8a53d1a3a27b..d516ba8178b8099f5e8e180f2e60e7a61de37811 100644 (file)
@@ -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,
index 4e16b02ed8321fcbd022cee0ed2c9d9c90d422a6..6110447fe51dcbd206cf0e3bf78d4746f0854d3e 100644 (file)
@@ -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;
index bf2122691fba25ae778d6fd68a179b1e9163defe..ad22df1ffbd13bbea78df55b8347aa32ae2105ad 100644 (file)
@@ -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;
index d5b54c020decdc2665d671f34d74dd809aa6682a..4f154d3887483e9cf1a6ab151c487e1d6113c1a8 100644 (file)
@@ -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:
index aeef8011ac7d82d828289f4085efe3acaa8a3945..9b4dcb6a16b50eefc04167dfdd1e509546b71bf6 100644 (file)
@@ -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);
index 9c823a609e75f8d66bbe1fa31a1ecebac7f65311..270edcc149a113c4026602f9d3a35e01475086df 100644 (file)
@@ -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;
 
index 1ff634f187b7fd927bef6a091b96e32dbca27870..a70d2ea90313fe9535abb92ea604681a73a1ce0c 100755 (executable)
@@ -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
index fb86f3899e1622008dee15ea70086af4788a53ca..f9a3d8d23c644a536ce0c9aaeed2c04b580af2f4 100755 (executable)
@@ -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__"
 
index 3bd5f4f302354cf8cecd78ae0ab13b9b3bf130ef..bc443201d3ef00ac2b197da0896a186891cff188 100755 (executable)
@@ -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 (file)
index 0000000..e40b53d
--- /dev/null
@@ -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);
index 91bc6214ae578fe6c1f0e29f2a37f34eb7575e45..1c02c65470384aa076e2de6885ecba356eb44342 100644 (file)
@@ -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,
index 2e402ece4c86d274b40f2e22d659bf63c53f8272..8e6b04b39dcc199a9895f5f7680066ee203fe2ea 100644 (file)
@@ -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;
index 63bc894ddf5e8102c3f1ed93c80fef50c3f95700..8c1289963c802b34783a8a8b4af42ed55bbcd71c 100644 (file)
@@ -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),
index d549f35f39d3e2ba1eab84b368354a3618153542..53f9311370dec18fabdc0cb03820f7f24c1dab1d 100644 (file)
@@ -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),
index 45d58fc1df393a3bb0bda87aec6f7d8983760d9e..a91a9ef00c40611db8f19ffcd14d414cd7d42d71 100644 (file)
@@ -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;
index a78802920c3cc098af2526a4ba335dba0df5a59f..5710fd440bcd2f8239e60262211d696590d5d7d6 100644 (file)
@@ -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)
index a33202affeb123aca338303d9d9c61bd7d5f5f39..fa550e3c1332bdc7071b77b712eb47dc388ee00e 100644 (file)
@@ -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 },
index 370ed54d1e1590f1036a4ff4425c0462245d3360..e597c893536dd04a0b115f1c49861fc675529f56 100644 (file)
@@ -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;
index 1db5c6a62a8e0c872e24fc6474031cbdfb72ab80..d95249c4c47bf04a0901ff3192ce84ebbf9f39d9 100644 (file)
 #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)
index 8f6814c1eb6b34aa7b83c04c87594cca18b90152..80f6d1da709536f901500d19a6bcf8334efbcc9e 100644 (file)
@@ -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;
 
index b95132e2f9dc299d82c783810982c2d5b768fb35..06790615e04eb70dac42167706857b4d7f63498c 100644 (file)
@@ -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)) {
index 105ec3a6e30df8340d62d1be45e1bb8577956672..de2550c7a96b095d33e449232087ef2d3b6e4655 100644 (file)
@@ -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;
 }
index dcd2df37bc3bfbd78e1f0d7bbb50b5192a89cc2d..758ac06f3a99413c5dffffbfe747d6c14c4f3a9c 100644 (file)
@@ -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);
index 26d64fa40c9cf1438f43a08d8f45b15ac0184fa9..7d7ab4aee42e3ab133926f2dc5b11489b93a28ae 100644 (file)
@@ -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 */
index 3fe4a080709598dba91fa8965b1a37fd98c36b68..cfd89ca6a18dacaaa42f5df95d7e573132383a39 100644 (file)
@@ -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;
                        }
                }
index eca85827dbd2af68f1bece9718650023dd91fbd4..fb2f1f603f3c9ef955f35c61e2b21d964f666be8 100644 (file)
@@ -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;
 
index 334917ee41cf8ede4aa443cc9eb8d7653e6471ac..9e3f8c04dd322bd0d3e21fe5b57dfc89ef4eccce 100644 (file)
@@ -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 */
index 888133f9e65d0188def0b7cb374621d940a0b1b8..3e9cc4842a1db14c2e8b0dc0a60dd462305f07aa 100644 (file)
@@ -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:
index 960744e46edc0549854f2ec5e28e68bf8a60a232..484ab3c2ad672fc819aa6101f0e442e507b8e785 100644 (file)
@@ -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
index 0c0b00e40646657b4592d2b646f183d76d456442..0834319ead42448673d023cabcb4e649400cd0cd 100644 (file)
@@ -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;
index 84c51037a7d07a5771c0510a412a4f7e5a3ae84b..624aaf569feff86a042056a15da5a7557636fae9 100644 (file)
@@ -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;
index 921622a019448394687655034f52befb4abfd6ec..13c875e2392a40ec5651d7c12a28b9ac9f3aab85 100644 (file)
@@ -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);
index dcc5ece0866832bbb11e353b1ac0b797e48b1065..7d3859e1a7b9b9537744b53d90e74012a5454d07 100644 (file)
@@ -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,
index b50f68a439cebaf5d28ac38331e165b31e72ead2..ba9fc099cf67b22997aad328f256c2b1150c86a1 100644 (file)
@@ -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;
        }
index 7598361ef1f10898ea73d944ae0b0c02c4725d99..da2172ff9662d0e86ffd132b6041b30ea232eb87 100644 (file)
@@ -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
index dd8f00cfb8b482b71b60529fac0618363dc8e540..32283d88701afa33a0e53d730c8e4e3bd7ec2861 100755 (executable)
@@ -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:
index 7e0405e1651d23ea80b2f000495e199a561eca72..e5bbb090bf88549111f939dcd7c1f500e6f84a4f 100644 (file)
@@ -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);
index 16de44a14b48706886ef77e37abed2bafa8e8fc1..418c86e69bcbfae71d93d07c7054afa08b149c18 100644 (file)
@@ -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);
index a4d3762cd8250c0e799978d0454d52a04073b8f1..83874b0e266c5ca57c73e85b4ba4b229f77b446d 100644 (file)
@@ -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;
index 87b43188667046c8a676b9bcbb3f2c7c315eb9bc..413f74df08de7cae06b1313ef0ed4c1339ee2093 100644 (file)
@@ -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;
index 5de2b86b9880c88a7570674688cfaba50744b5ed..2e9eb6aa3ce2e15ccc3a60506de1b1072e2da7d9 100644 (file)
@@ -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;
index bccebd935907a894afbe835f6ea480131559b9ea..29793694cbc79c3efeb100fed07df8930ec5e62c 100644 (file)
@@ -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);
index 71729d47eb8552bca1350fc923b91ec189e2ef2f..7956302ecdf2ace692ba49927fe72c97ebf0cca3 100644 (file)
 
 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)
index 5855cd3d3d45cbd1ee967263c622d4e9d2e7b417..1f7dd35551b9136d24987d79deb2c1024cd2fc82 100644 (file)
@@ -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);
index 404aec5208128101812f6c9189ed046d1ec6eb24..d3ed7324105e4eeeb281c4c90922c27541b2b58f 100644 (file)
@@ -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;
index 0e1fc75f3585774b7b885cf3f52eda59a4fd299f..2ea21dac0b441f4d91bff83508e6fa38bedfc488 100644 (file)
@@ -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);
 }
index fc8a723ff387f5c02a5525b33a078ae83819ac61..8a9c42366db7df0874fe3fb4347de4bb4174575c 100644 (file)
@@ -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);
                }
        }
 }
index 3a0b8999f011c6e3e1ff6ea7699577879a651fd3..5801261f3adddeaab819f4ffd23ecd5839d03c8a 100644 (file)
@@ -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);
 
index 2dff288b3a668e401d924e52cee10b9e85ecd8df..aa6b68db80b47c6089ef27c64dbf1e2654acc458 100644 (file)
@@ -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;
index 714fa393354613de21aef3184360689699bbbfd0..408ef06638fc6c7d8a459576e30feacaa3c3cea2 100644 (file)
@@ -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);
index 82987d457b8bb4e7ec4c1159e37857fd85a11c18..15252d723b54e196d864d29a7aac2040686dc59a 100644 (file)
@@ -717,10 +717,9 @@ static struct kvm *kvm_create_vm(unsigned long type)
        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)