diff options
Diffstat (limited to 'arch/arm64')
143 files changed, 6918 insertions, 1310 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index dbd47bb9caf2..4f436220384f 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -237,8 +237,6 @@ config PCI_SYSCALL def_bool PCI source "drivers/pci/Kconfig" -source "drivers/pci/pcie/Kconfig" -source "drivers/pci/hotplug/Kconfig" endmenu @@ -767,6 +765,19 @@ config ARM64_LSE_ATOMICS not support these instructions and requires the kernel to be built with binutils >= 2.25. +config ARM64_VHE + bool "Enable support for Virtualization Host Extensions (VHE)" + default y + help + Virtualization Host Extensions (VHE) allow the kernel to run + directly at EL2 (instead of EL1) on processors that support + it. This leads to better performance for KVM, as they reduce + the cost of the world switch. + + Selecting this option allows the VHE feature to be detected + at runtime, and does not affect processors that do not + implement this feature. + endmenu menu "ARMv8.2 architectural features" diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 21074f674bde..efa77c146415 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -1,7 +1,22 @@ menu "Platform selection" +config ARCH_SUNXI + bool "Allwinner sunxi 64-bit SoC Family" + help + This enables support for Allwinner sunxi based SoCs like the A64. + +config ARCH_ALPINE + bool "Annapurna Labs Alpine platform" + select ALPINE_MSI + help + This enables support for the Annapurna Labs Alpine + Soc family. + config ARCH_BCM_IPROC bool "Broadcom iProc SoC Family" + select COMMON_CLK_IPROC + select PINCTRL + select ARCH_REQUIRE_GPIOLIB help This enables support for Broadcom iProc based SoCs @@ -14,21 +29,14 @@ config ARCH_BERLIN This enables support for Marvell Berlin SoC Family config ARCH_EXYNOS - bool - help - This enables support for Samsung Exynos SoC family - -config ARCH_EXYNOS7 - bool "ARMv8 based Samsung Exynos7" - select ARCH_EXYNOS + bool "ARMv8 based Samsung Exynos SoC family" select COMMON_CLK_SAMSUNG select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS select PINCTRL select PINCTRL_EXYNOS - help - This enables support for Samsung Exynos7 SoC family + This enables support for ARMv8 based Samsung Exynos SoC family. config ARCH_LAYERSCAPE bool "ARMv8 based Freescale Layerscape SoC family" @@ -37,6 +45,7 @@ config ARCH_LAYERSCAPE config ARCH_HISI bool "Hisilicon SoC Family" + select HISILICON_IRQ_MBIGEN help This enables support for Hisilicon ARMv8 SoC family @@ -48,6 +57,22 @@ config ARCH_MEDIATEK help Support for Mediatek MT65xx & MT81xx ARMv8 SoCs +config ARCH_MESON + bool "Amlogic Platforms" + help + This enables support for the Amlogic S905 SoCs. + +config ARCH_MVEBU + bool "Marvell EBU SoC Family" + select ARMADA_AP806_CORE_CLK + select ARMADA_AP806_RING_CLK + select MVEBU_ODMI + help + This enables support for Marvell EBU familly, including: + - Armada 3700 SoC Family + - Armada 7K SoC Family + - Armada 8K SoC Family + config ARCH_QCOM bool "Qualcomm Platforms" select PINCTRL @@ -60,6 +85,7 @@ config ARCH_ROCKCHIP select ARCH_REQUIRE_GPIOLIB select PINCTRL select PINCTRL_ROCKCHIP + select ROCKCHIP_TIMER help This enables support for the ARMv8 based Rockchip chipsets, like the RK3368. @@ -76,7 +102,9 @@ config ARCH_RENESAS bool "Renesas SoC Platforms" select ARCH_SHMOBILE select PINCTRL - select PM_GENERIC_DOMAINS if PM + select PM + select PM_GENERIC_DOMAINS + select RENESAS_IRQC help This enables support for the ARMv8 based Renesas SoCs. @@ -131,6 +159,11 @@ config ARCH_VEXPRESS This enables support for the ARMv8 software model (Versatile Express). +config ARCH_VULCAN + bool "Broadcom Vulcan SOC Family" + help + This enables support for Broadcom Vulcan SoC Family + config ARCH_XGENE bool "AppliedMicro X-Gene SOC Family" help diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 6b5508a17495..354d75402ace 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -96,7 +96,7 @@ Image: vmlinux Image.%: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ -zinstall install: vmlinux +zinstall install: $(Q)$(MAKE) $(build)=$(boot) $@ %.dtb: scripts diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile index abcbba2f01ba..305c552b5ec1 100644 --- a/arch/arm64/boot/Makefile +++ b/arch/arm64/boot/Makefile @@ -34,10 +34,10 @@ $(obj)/Image.lzma: $(obj)/Image FORCE $(obj)/Image.lzo: $(obj)/Image FORCE $(call if_changed,lzo) -install: $(obj)/Image +install: $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ $(obj)/Image System.map "$(INSTALL_PATH)" -zinstall: $(obj)/Image.gz +zinstall: $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ $(obj)/Image.gz System.map "$(INSTALL_PATH)" diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index f832b8a7453a..330fae966cf3 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile @@ -1,5 +1,7 @@ +dts-dirs += al dts-dirs += altera dts-dirs += amd +dts-dirs += amlogic dts-dirs += apm dts-dirs += arm dts-dirs += broadcom diff --git a/arch/arm64/boot/dts/al/Makefile b/arch/arm64/boot/dts/al/Makefile new file mode 100644 index 000000000000..8a6cde4f9b23 --- /dev/null +++ b/arch/arm64/boot/dts/al/Makefile @@ -0,0 +1,5 @@ +dtb-$(CONFIG_ARCH_ALPINE) += alpine-v2-evp.dtb + +always := $(dtb-y) +subdir-y := $(dts-dirs) +clean-files := *.dtb diff --git a/arch/arm64/boot/dts/al/alpine-v2-evp.dts b/arch/arm64/boot/dts/al/alpine-v2-evp.dts new file mode 100644 index 000000000000..a079d7b3063e --- /dev/null +++ b/arch/arm64/boot/dts/al/alpine-v2-evp.dts @@ -0,0 +1,53 @@ +/* + * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Antoine Tenart <antoine.tenart@free-electrons.com> + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed 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, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "alpine-v2.dtsi" + +/ { + model = "Annapurna Labs Alpine v2 EVP"; + compatible = "al,alpine-v2-evp", "al,alpine-v2"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/al/alpine-v2.dtsi b/arch/arm64/boot/dts/al/alpine-v2.dtsi new file mode 100644 index 000000000000..5b7bef684256 --- /dev/null +++ b/arch/arm64/boot/dts/al/alpine-v2.dtsi @@ -0,0 +1,236 @@ +/* + * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Antoine Tenart <antoine.tenart@free-electrons.com> + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed 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, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/dts-v1/; + +#include <dt-bindings/interrupt-controller/arm-gic.h> + +/ { + model = "Annapurna Labs Alpine v2"; + compatible = "al,alpine-v2"; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-a57", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + + cpu@1 { + compatible = "arm,cortex-a57", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x1>; + enable-method = "psci"; + }; + + cpu@2 { + compatible = "arm,cortex-a57", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x2>; + enable-method = "psci"; + }; + + cpu@3 { + compatible = "arm,cortex-a57", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x3>; + enable-method = "psci"; + }; + }; + + psci { + compatible = "arm,psci-0.2", "arm,psci"; + method = "smc"; + cpu_suspend = <0x84000001>; + cpu_off = <0x84000002>; + cpu_on = <0x84000003>; + }; + + sbclk: sbclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + + interrupt-parent = <&gic>; + ranges; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>; + }; + + gic: gic@f0100000 { + compatible = "arm,gic-v3"; + reg = <0x0 0xf0200000 0x0 0x10000>, /* GIC Dist */ + <0x0 0xf0280000 0x0 0x200000>, /* GICR */ + <0x0 0xf0100000 0x0 0x2000>, /* GICC */ + <0x0 0xf0110000 0x0 0x2000>, /* GICV */ + <0x0 0xf0120000 0x0 0x2000>; /* GICH */ + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <3>; + }; + + pci@fbc00000 { + compatible = "pci-host-ecam-generic"; + device_type = "pci"; + #size-cells = <2>; + #address-cells = <3>; + #interrupt-cells = <1>; + reg = <0x0 0xfbc00000 0x0 0x100000>; + interrupt-map-mask = <0xf800 0 0 7>; + /* add legacy interrupts for SATA only */ + interrupt-map = <0x4000 0 0 1 &gic 0 53 4>, + <0x4800 0 0 1 &gic 0 54 4>; + /* 32 bit non prefetchable memory space */ + ranges = <0x2000000 0x0 0xfe000000 0x0 0xfe000000 0x0 0x1000000>; + bus-range = <0x00 0x00>; + msi-parent = <&msix>; + }; + + msix: msix@fbe00000 { + compatible = "al,alpine-msix"; + reg = <0x0 0xfbe00000 0x0 0x100000>; + interrupt-controller; + msi-controller; + al,msi-base-spi = <160>; + al,msi-num-spis = <160>; + }; + + io-fabric { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0xfc000000 0x2000000>; + + uart0: serial@1883000 { + compatible = "ns16550a"; + device_type = "serial"; + reg = <0x1883000 0x1000>; + interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <500000000>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart1: serial@1884000 { + compatible = "ns16550a"; + device_type = "serial"; + reg = <0x1884000 0x1000>; + interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <500000000>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart2: serial@1885000 { + compatible = "ns16550a"; + device_type = "serial"; + reg = <0x1885000 0x1000>; + interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <500000000>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart3: serial@1886000 { + compatible = "ns16550a"; + device_type = "serial"; + reg = <0x1886000 0x1000>; + interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <500000000>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + timer0: timer@1890000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x1890000 0x1000>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&sbclk>; + }; + + timer1: timer@1891000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x1891000 0x1000>; + interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&sbclk>; + status = "disabled"; + }; + + timer2: timer@1892000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x1892000 0x1000>; + interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&sbclk>; + status = "disabled"; + }; + + timer3: timer@1893000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x1893000 0x1000>; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&sbclk>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/amd/Makefile b/arch/arm64/boot/dts/amd/Makefile index cfdf701e05df..ba84770f789f 100644 --- a/arch/arm64/boot/dts/amd/Makefile +++ b/arch/arm64/boot/dts/amd/Makefile @@ -1,4 +1,6 @@ -dtb-$(CONFIG_ARCH_SEATTLE) += amd-overdrive.dtb +dtb-$(CONFIG_ARCH_SEATTLE) += amd-overdrive.dtb \ + amd-overdrive-rev-b0.dtb amd-overdrive-rev-b1.dtb \ + husky.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts new file mode 100644 index 000000000000..8e3074a4947d --- /dev/null +++ b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts @@ -0,0 +1,87 @@ +/* + * DTS file for AMD Seattle Overdrive Development Board + * Note: For Seattle Rev.B0 + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/include/ "amd-seattle-soc.dtsi" + +/ { + model = "AMD Seattle (Rev.B0) Development Board (Overdrive)"; + compatible = "amd,seattle-overdrive", "amd,seattle"; + + chosen { + stdout-path = &serial0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; +}; + +&ccp0 { + status = "ok"; + amd,zlib-support = <1>; +}; + +/** + * NOTE: In Rev.B, gpio0 is reserved. + */ +&gpio1 { + status = "ok"; +}; + +&gpio2 { + status = "ok"; +}; + +&gpio3 { + status = "ok"; +}; + +&gpio4 { + status = "ok"; +}; + +&i2c0 { + status = "ok"; +}; + +&i2c1 { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; + +&spi0 { + status = "ok"; +}; + +&spi1 { + status = "ok"; + sdcard0: sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3200 3400>; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,com-mode = <0x0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + }; +}; + +&ipmi_kcs { + status = "ok"; +}; + +&smb0 { + /include/ "amd-seattle-xgbe-b.dtsi" +}; diff --git a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts new file mode 100644 index 000000000000..ed5e043f37aa --- /dev/null +++ b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts @@ -0,0 +1,91 @@ +/* + * DTS file for AMD Seattle Overdrive Development Board + * Note: For Seattle Rev.B1 + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/include/ "amd-seattle-soc.dtsi" + +/ { + model = "AMD Seattle (Rev.B1) Development Board (Overdrive)"; + compatible = "amd,seattle-overdrive", "amd,seattle"; + + chosen { + stdout-path = &serial0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; +}; + +&ccp0 { + status = "ok"; + amd,zlib-support = <1>; +}; + +/** + * NOTE: In Rev.B, gpio0 is reserved. + */ +&gpio1 { + status = "ok"; +}; + +&gpio2 { + status = "ok"; +}; + +&gpio3 { + status = "ok"; +}; + +&gpio4 { + status = "ok"; +}; + +&i2c0 { + status = "ok"; +}; + +&i2c1 { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; + +&sata1 { + status = "ok"; +}; + +&spi0 { + status = "ok"; +}; + +&spi1 { + status = "ok"; + sdcard0: sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3200 3400>; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,com-mode = <0x0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + }; +}; + +&ipmi_kcs { + status = "ok"; +}; + +&smb0 { + /include/ "amd-seattle-xgbe-b.dtsi" +}; diff --git a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi index 2874d92881fd..bd3adeac374f 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi @@ -18,8 +18,8 @@ #size-cells = <2>; reg = <0x0 0xe1110000 0 0x1000>, <0x0 0xe112f000 0 0x2000>, - <0x0 0xe1140000 0 0x10000>, - <0x0 0xe1160000 0 0x10000>; + <0x0 0xe1140000 0 0x2000>, + <0x0 0xe1160000 0 0x2000>; interrupts = <1 9 0xf04>; ranges = <0 0 0 0xe1100000 0 0x100000>; v2m0: v2m@e0080000 { @@ -55,25 +55,47 @@ #size-cells = <2>; ranges; - /* DDR range is 40-bit addressing */ - dma-ranges = <0x80 0x0 0x80 0x0 0x7f 0xffffffff>; + /* + * dma-ranges is 40-bit address space containing: + * - GICv2m MSI register is at 0xe0080000 + * - DRAM range [0x8000000000 to 0xffffffffff] + */ + dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>; /include/ "amd-seattle-clks.dtsi" sata0: sata@e0300000 { compatible = "snps,dwc-ahci"; - reg = <0 0xe0300000 0 0x800>; + reg = <0 0xe0300000 0 0xf0000>; interrupts = <0 355 4>; clocks = <&sataclk_333mhz>; dma-coherent; }; + /* This is for Rev B only */ + sata1: sata@e0d00000 { + status = "disabled"; + compatible = "snps,dwc-ahci"; + reg = <0 0xe0d00000 0 0xf0000>; + interrupts = <0 354 4>; + clocks = <&sataclk_333mhz>; + dma-coherent; + }; + i2c0: i2c@e1000000 { status = "disabled"; compatible = "snps,designware-i2c"; reg = <0 0xe1000000 0 0x1000>; interrupts = <0 357 4>; - clocks = <&uartspiclk_100mhz>; + clocks = <&miscclk_250mhz>; + }; + + i2c1: i2c@e0050000 { + status = "disabled"; + compatible = "snps,designware-i2c"; + reg = <0 0xe0050000 0 0x1000>; + interrupts = <0 340 4>; + clocks = <&miscclk_250mhz>; }; serial0: serial@e1010000 { @@ -87,7 +109,6 @@ spi0: ssp@e1020000 { status = "disabled"; compatible = "arm,pl022", "arm,primecell"; - #gpio-cells = <2>; reg = <0 0xe1020000 0 0x1000>; spi-controller; interrupts = <0 330 4>; @@ -98,7 +119,6 @@ spi1: ssp@e1030000 { status = "disabled"; compatible = "arm,pl022", "arm,primecell"; - #gpio-cells = <2>; reg = <0 0xe1030000 0 0x1000>; spi-controller; interrupts = <0 329 4>; @@ -109,7 +129,7 @@ #size-cells = <0>; }; - gpio0: gpio@e1040000 { + gpio0: gpio@e1040000 { /* Not available to OS for B0 */ status = "disabled"; compatible = "arm,pl061", "arm,primecell"; #gpio-cells = <2>; @@ -118,18 +138,59 @@ interrupts = <0 359 4>; interrupt-controller; #interrupt-cells = <2>; - clocks = <&uartspiclk_100mhz>; + clocks = <&miscclk_250mhz>; clock-names = "apb_pclk"; }; - gpio1: gpio@e1050000 { + gpio1: gpio@e1050000 { /* [0:7] */ status = "disabled"; compatible = "arm,pl061", "arm,primecell"; #gpio-cells = <2>; reg = <0 0xe1050000 0 0x1000>; gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; interrupts = <0 358 4>; - clocks = <&uartspiclk_100mhz>; + clocks = <&miscclk_250mhz>; + clock-names = "apb_pclk"; + }; + + gpio2: gpio@e0020000 { /* [8:15] */ + status = "disabled"; + compatible = "arm,pl061", "arm,primecell"; + #gpio-cells = <2>; + reg = <0 0xe0020000 0 0x1000>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 366 4>; + clocks = <&miscclk_250mhz>; + clock-names = "apb_pclk"; + }; + + gpio3: gpio@e0030000 { /* [16:23] */ + status = "disabled"; + compatible = "arm,pl061", "arm,primecell"; + #gpio-cells = <2>; + reg = <0 0xe0030000 0 0x1000>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 365 4>; + clocks = <&miscclk_250mhz>; + clock-names = "apb_pclk"; + }; + + gpio4: gpio@e0080000 { /* [24] */ + status = "disabled"; + compatible = "arm,pl061", "arm,primecell"; + #gpio-cells = <2>; + reg = <0 0xe0080000 0 0x1000>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 361 4>; + clocks = <&miscclk_250mhz>; clock-names = "apb_pclk"; }; @@ -159,7 +220,7 @@ <0x1000 0x0 0x0 0x4 &gic0 0x0 0x0 0x0 0x123 0x1>; dma-coherent; - dma-ranges = <0x43000000 0x80 0x0 0x80 0x0 0x7f 0xffffffff>; + dma-ranges = <0x43000000 0x0 0x0 0x0 0x0 0x100 0x0>; ranges = /* I/O Memory (size=64K) */ <0x01000000 0x00 0x00000000 0x00 0xefff0000 0x00 0x00010000>, @@ -168,5 +229,22 @@ /* 64-bit MMIO (size= 124G) */ <0x03000000 0x01 0x00000000 0x01 0x00000000 0x7f 0x00000000>; }; + + /* Perf CCN504 PMU */ + ccn: ccn@e8000000 { + compatible = "arm,ccn-504"; + reg = <0x0 0xe8000000 0 0x1000000>; + interrupts = <0 380 4>; + }; + + ipmi_kcs: kcs@e0010000 { + status = "disabled"; + compatible = "ipmi-kcs"; + device_type = "ipmi"; + reg = <0x0 0xe0010000 0 0x8>; + interrupts = <0 389 4>; + reg-size = <1>; + reg-spacing = <4>; + }; }; }; diff --git a/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi new file mode 100644 index 000000000000..8e8631952497 --- /dev/null +++ b/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi @@ -0,0 +1,117 @@ +/* + * DTS file for AMD Seattle XGBE (RevB) + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + + xgmacclk0_dma_250mhz: clk250mhz_0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk0_dma_250mhz"; + }; + + xgmacclk0_ptp_250mhz: clk250mhz_1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk0_ptp_250mhz"; + }; + + xgmacclk1_dma_250mhz: clk250mhz_2 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk1_dma_250mhz"; + }; + + xgmacclk1_ptp_250mhz: clk250mhz_3 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk1_ptp_250mhz"; + }; + + xgmac0: xgmac@e0700000 { + compatible = "amd,xgbe-seattle-v1a"; + reg = <0 0xe0700000 0 0x80000>, + <0 0xe0780000 0 0x80000>, + <0 0xe1240800 0 0x00400>, /* SERDES RX/TX0 */ + <0 0xe1250000 0 0x00060>, /* SERDES IR 1/2 */ + <0 0xe12500f8 0 0x00004>; /* SERDES IR 2/2 */ + interrupts = <0 325 4>, + <0 346 1>, <0 347 1>, <0 348 1>, <0 349 1>, + <0 323 4>; + amd,per-channel-interrupt; + amd,speed-set = <0>; + amd,serdes-blwc = <1>, <1>, <0>; + amd,serdes-cdr-rate = <2>, <2>, <7>; + amd,serdes-pq-skew = <10>, <10>, <18>; + amd,serdes-tx-amp = <0>, <0>, <0>; + amd,serdes-dfe-tap-config = <3>, <3>, <3>; + amd,serdes-dfe-tap-enable = <0>, <0>, <7>; + mac-address = [ 02 A1 A2 A3 A4 A5 ]; + clocks = <&xgmacclk0_dma_250mhz>, <&xgmacclk0_ptp_250mhz>; + clock-names = "dma_clk", "ptp_clk"; + phy-mode = "xgmii"; + #stream-id-cells = <16>; + dma-coherent; + }; + + xgmac1: xgmac@e0900000 { + compatible = "amd,xgbe-seattle-v1a"; + reg = <0 0xe0900000 0 0x80000>, + <0 0xe0980000 0 0x80000>, + <0 0xe1240c00 0 0x00400>, /* SERDES RX/TX1 */ + <0 0xe1250080 0 0x00060>, /* SERDES IR 1/2 */ + <0 0xe12500fc 0 0x00004>; /* SERDES IR 2/2 */ + interrupts = <0 324 4>, + <0 341 1>, <0 342 1>, <0 343 1>, <0 344 1>, + <0 322 4>; + amd,per-channel-interrupt; + amd,speed-set = <0>; + amd,serdes-blwc = <1>, <1>, <0>; + amd,serdes-cdr-rate = <2>, <2>, <7>; + amd,serdes-pq-skew = <10>, <10>, <18>; + amd,serdes-tx-amp = <0>, <0>, <0>; + amd,serdes-dfe-tap-config = <3>, <3>, <3>; + amd,serdes-dfe-tap-enable = <0>, <0>, <7>; + mac-address = [ 02 B1 B2 B3 B4 B5 ]; + clocks = <&xgmacclk1_dma_250mhz>, <&xgmacclk1_ptp_250mhz>; + clock-names = "dma_clk", "ptp_clk"; + phy-mode = "xgmii"; + #stream-id-cells = <16>; + dma-coherent; + }; + + xgmac0_smmu: smmu@e0600000 { + compatible = "arm,mmu-401"; + reg = <0 0xe0600000 0 0x10000>; + #global-interrupts = <1>; + interrupts = /* Uses combined intr for both + * global and context + */ + <0 336 4>, + <0 336 4>; + + mmu-masters = <&xgmac0 + 0 1 2 3 4 5 6 7 + 16 17 18 19 20 21 22 23 + >; + }; + + xgmac1_smmu: smmu@e0800000 { + compatible = "arm,mmu-401"; + reg = <0 0xe0800000 0 0x10000>; + #global-interrupts = <1>; + interrupts = /* Uses combined intr for both + * global and context + */ + <0 335 4>, + <0 335 4>; + + mmu-masters = <&xgmac1 + 0 1 2 3 4 5 6 7 + 16 17 18 19 20 21 22 23 + >; + }; diff --git a/arch/arm64/boot/dts/amd/husky.dts b/arch/arm64/boot/dts/amd/husky.dts new file mode 100644 index 000000000000..1381d4b2bf1b --- /dev/null +++ b/arch/arm64/boot/dts/amd/husky.dts @@ -0,0 +1,83 @@ +/* + * DTS file for AMD/Linaro 96Boards Enterprise Edition Server (Husky) Board + * Note: Based-on AMD Seattle Rev.B0 + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/include/ "amd-seattle-soc.dtsi" + +/ { + model = "Linaro 96Boards Enterprise Edition Server (Husky) Board"; + compatible = "amd,seattle-overdrive", "amd,seattle"; + + chosen { + stdout-path = &serial0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; +}; + +&ccp0 { + status = "ok"; + amd,zlib-support = <1>; +}; + +/** + * NOTE: In Rev.B, gpio0 is reserved. + */ +&gpio1 { + status = "ok"; +}; + +&gpio2 { + status = "ok"; +}; + +&gpio3 { + status = "ok"; +}; + +&gpio4 { + status = "ok"; +}; + +&i2c0 { + status = "ok"; +}; + +&i2c1 { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; + +&spi0 { + status = "ok"; +}; + +&spi1 { + status = "ok"; + sdcard0: sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3200 3400>; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,com-mode = <0x0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + }; +}; + +&smb0 { + /include/ "amd-seattle-xgbe-b.dtsi" +}; diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile new file mode 100644 index 000000000000..eb672f38f89e --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/Makefile @@ -0,0 +1,7 @@ +dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-pro.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-meta.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-telos.dtb + +always := $(dtb-y) +subdir-y := $(dts-dirs) +clean-files := *.dtb diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-meta.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-meta.dts new file mode 100644 index 000000000000..399aff9e7975 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-meta.dts @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 Andreas Färber + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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. + * + * This library 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. + * + * Or, alternatively, + * + * b) 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 AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "meson-gxbb-vega-s95.dtsi" + +/ { + compatible = "tronsmart,vega-s95-meta", "tronsmart,vega-s95", "amlogic,meson-gxbb"; + model = "Tronsmart Vega S95 Meta"; + + memory { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-pro.dts new file mode 100644 index 000000000000..ac5a241b5ec2 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-pro.dts @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 Andreas Färber + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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. + * + * This library 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. + * + * Or, alternatively, + * + * b) 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 AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "meson-gxbb-vega-s95.dtsi" + +/ { + compatible = "tronsmart,vega-s95-pro", "tronsmart,vega-s95", "amlogic,meson-gxbb"; + model = "Tronsmart Vega S95 Pro"; + + memory { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x40000000>; + }; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-telos.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-telos.dts new file mode 100644 index 000000000000..fff7bfa2aa39 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-telos.dts @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 Andreas Färber + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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. + * + * This library 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. + * + * Or, alternatively, + * + * b) 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 AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "meson-gxbb-vega-s95.dtsi" + +/ { + compatible = "tronsmart,vega-s95-telos", "tronsmart,vega-s95", "amlogic,meson-gxbb"; + model = "Tronsmart Vega S95 Telos"; + + memory { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi new file mode 100644 index 000000000000..c1fa2667ec5c --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 Andreas Färber + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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. + * + * This library 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. + * + * Or, alternatively, + * + * b) 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 AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "meson-gxbb.dtsi" + +/ { + compatible = "tronsmart,vega-s95", "amlogic,meson-gxbb"; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart_AO { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi new file mode 100644 index 000000000000..eaa0a4553734 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2016 Andreas Färber + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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. + * + * This library 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. + * + * Or, alternatively, + * + * b) 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 AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> + +/ { + compatible = "amlogic,meson-gxbb"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &uart_AO; + serial1 = &uart_A; + }; + + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "psci"; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "psci"; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "psci"; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 + (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_EDGE_RISING)>, + <GIC_PPI 14 + (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_EDGE_RISING)>, + <GIC_PPI 11 + (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_EDGE_RISING)>, + <GIC_PPI 10 + (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_EDGE_RISING)>; + }; + + xtal: xtal-clk { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "xtal"; + #clock-cells = <0>; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + cbus: cbus@c1100000 { + compatible = "simple-bus"; + reg = <0x0 0xc1100000 0x0 0x100000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xc1100000 0x0 0x100000>; + + uart_A: serial@84c0 { + compatible = "amlogic,meson-uart"; + reg = <0x0 0x084c0 0x0 0x14>; + interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>; + clocks = <&xtal>; + status = "disabled"; + }; + }; + + gic: interrupt-controller@c4301000 { + compatible = "arm,gic-400"; + reg = <0x0 0xc4301000 0 0x1000>, + <0x0 0xc4302000 0 0x2000>, + <0x0 0xc4304000 0 0x2000>, + <0x0 0xc4306000 0 0x2000>; + interrupt-controller; + interrupts = <GIC_PPI 9 + (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>; + #interrupt-cells = <3>; + #address-cells = <0>; + }; + + aobus: aobus@c8100000 { + compatible = "simple-bus"; + reg = <0x0 0xc8100000 0x0 0x100000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>; + + uart_AO: serial@4c0 { + compatible = "amlogic,meson-uart"; + reg = <0x0 0x004c0 0x0 0x14>; + interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>; + clocks = <&xtal>; + status = "disabled"; + }; + }; + + apb: apb@d0000000 { + compatible = "simple-bus"; + reg = <0x0 0xd0000000 0x0 0x200000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xd0000000 0x0 0x200000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apm/apm-merlin.dts b/arch/arm64/boot/dts/apm/apm-merlin.dts index e5ba8d5d0cae..387c6a8d0da9 100644 --- a/arch/arm64/boot/dts/apm/apm-merlin.dts +++ b/arch/arm64/boot/dts/apm/apm-merlin.dts @@ -30,7 +30,8 @@ label = "POWER"; linux,code = <116>; linux,input-type = <0x1>; - interrupts = <0x0 0x28 0x1>; + interrupt-parent = <&sbgpio>; + interrupts = <0x0 0x1>; }; }; diff --git a/arch/arm64/boot/dts/apm/apm-mustang.dts b/arch/arm64/boot/dts/apm/apm-mustang.dts index 178aef2cdd09..44db32ec5e9c 100644 --- a/arch/arm64/boot/dts/apm/apm-mustang.dts +++ b/arch/arm64/boot/dts/apm/apm-mustang.dts @@ -30,7 +30,8 @@ label = "POWER"; linux,code = <116>; linux,input-type = <0x1>; - interrupts = <0x0 0x2d 0x1>; + interrupt-parent = <&sbgpio>; + interrupts = <0x5 0x1>; }; }; diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi index 5d87a3dc44b8..a055a5d443b7 100644 --- a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi +++ b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi @@ -224,7 +224,7 @@ }; socpll: socpll@17000120 { - compatible = "apm,xgene-socpll-clock"; + compatible = "apm,xgene-socpll-v2-clock"; #clock-cells = <1>; clocks = <&refclk 0>; reg = <0x0 0x17000120 0x0 0x1000>; @@ -453,6 +453,25 @@ }; }; + mailbox: mailbox@10540000 { + compatible = "apm,xgene-slimpro-mbox"; + reg = <0x0 0x10540000 0x0 0x8000>; + #mbox-cells = <1>; + interrupts = <0x0 0x0 0x4 + 0x0 0x1 0x4 + 0x0 0x2 0x4 + 0x0 0x3 0x4 + 0x0 0x4 0x4 + 0x0 0x5 0x4 + 0x0 0x6 0x4 + 0x0 0x7 0x4>; + }; + + i2cslimpro { + compatible = "apm,xgene-slimpro-i2c"; + mboxes = <&mailbox 0>; + }; + serial0: serial@10600000 { device_type = "serial"; compatible = "ns16550"; @@ -598,6 +617,12 @@ <0x0 0x2d 0x1>, <0x0 0x2e 0x1>, <0x0 0x2f 0x1>; + interrupt-parent = <&gic>; + #interrupt-cells = <2>; + interrupt-controller; + apm,nr-gpios = <22>; + apm,nr-irqs = <8>; + apm,irq-start = <8>; }; sgenet0: ethernet@1f610000 { @@ -621,7 +646,13 @@ <0x0 0x1f600000 0x0 0Xd100>, <0x0 0x20000000 0x0 0X220000>; interrupts = <0 108 4>, - <0 109 4>; + <0 109 4>, + <0 110 4>, + <0 111 4>, + <0 112 4>, + <0 113 4>, + <0 114 4>, + <0 115 4>; port-id = <1>; dma-coherent; clocks = <&xge1clk 0>; diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi index fe30f7671ea3..ae4a173df493 100644 --- a/arch/arm64/boot/dts/apm/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi @@ -493,6 +493,11 @@ reg = <0x0 0x1054a000 0x0 0x20>; }; + rb: rb@7e000000 { + compatible = "apm,xgene-rb", "syscon"; + reg = <0x0 0x7e000000 0x0 0x10>; + }; + edac@78800000 { compatible = "apm,xgene-edac"; #address-cells = <2>; @@ -502,6 +507,7 @@ regmap-mcba = <&mcba>; regmap-mcbb = <&mcbb>; regmap-efuse = <&efuse>; + regmap-rb = <&rb>; reg = <0x0 0x78800000 0x0 0x100>; interrupts = <0x0 0x20 0x4>, <0x0 0x21 0x4>, @@ -691,6 +697,25 @@ msi-parent = <&msi>; }; + mailbox: mailbox@10540000 { + compatible = "apm,xgene-slimpro-mbox"; + reg = <0x0 0x10540000 0x0 0xa000>; + #mbox-cells = <1>; + interrupts = <0x0 0x0 0x4>, + <0x0 0x1 0x4>, + <0x0 0x2 0x4>, + <0x0 0x3 0x4>, + <0x0 0x4 0x4>, + <0x0 0x5 0x4>, + <0x0 0x6 0x4>, + <0x0 0x7 0x4>; + }; + + i2cslimpro { + compatible = "apm,xgene-slimpro-i2c"; + mboxes = <&mailbox 0>; + }; + serial0: serial@1c020000 { status = "disabled"; device_type = "serial"; @@ -883,6 +908,9 @@ <0x0 0x2b 0x1>, <0x0 0x2c 0x1>, <0x0 0x2d 0x1>; + interrupt-parent = <&gic>; + #interrupt-cells = <2>; + interrupt-controller; }; rtc: rtc@10510000 { @@ -958,7 +986,13 @@ <0x0 0x18000000 0x0 0X200>; reg-names = "enet_csr", "ring_csr", "ring_cmd"; interrupts = <0x0 0x60 0x4>, - <0x0 0x61 0x4>; + <0x0 0x61 0x4>, + <0x0 0x62 0x4>, + <0x0 0x63 0x4>, + <0x0 0x64 0x4>, + <0x0 0x65 0x4>, + <0x0 0x66 0x4>, + <0x0 0x67 0x4>; dma-coherent; clocks = <&xge0clk 0>; /* mac address will be overwritten by the bootloader */ diff --git a/arch/arm64/boot/dts/arm/Makefile b/arch/arm64/boot/dts/arm/Makefile index bb3c07209676..75cc2aa10101 100644 --- a/arch/arm64/boot/dts/arm/Makefile +++ b/arch/arm64/boot/dts/arm/Makefile @@ -1,5 +1,5 @@ -dtb-$(CONFIG_ARCH_VEXPRESS) += foundation-v8.dtb -dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb juno-r1.dtb +dtb-$(CONFIG_ARCH_VEXPRESS) += foundation-v8.dtb foundation-v8-gicv3.dtb +dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb juno-r1.dtb juno-r2.dtb dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2f-1xv7-ca53x2.dtb diff --git a/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts b/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts new file mode 100644 index 000000000000..35588dfa095c --- /dev/null +++ b/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts @@ -0,0 +1,30 @@ +/* + * ARM Ltd. + * + * ARMv8 Foundation model DTS (GICv3 configuration) + */ + +#include "foundation-v8.dtsi" + +/ { + gic: interrupt-controller@2f000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + interrupt-controller; + reg = <0x0 0x2f000000 0x0 0x10000>, + <0x0 0x2f100000 0x0 0x200000>, + <0x0 0x2c000000 0x0 0x2000>, + <0x0 0x2c010000 0x0 0x2000>, + <0x0 0x2c02f000 0x0 0x2000>; + interrupts = <1 9 4>; + + its: its@2f020000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0x2f020000 0x0 0x20000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dts b/arch/arm64/boot/dts/arm/foundation-v8.dts index 4eac8dcea423..71168077312d 100644 --- a/arch/arm64/boot/dts/arm/foundation-v8.dts +++ b/arch/arm64/boot/dts/arm/foundation-v8.dts @@ -1,240 +1,21 @@ /* * ARM Ltd. * - * ARMv8 Foundation model DTS + * ARMv8 Foundation model DTS (GICv2 configuration) */ -/dts-v1/; - -/memreserve/ 0x80000000 0x00010000; +#include "foundation-v8.dtsi" / { - model = "Foundation-v8A"; - compatible = "arm,foundation-aarch64", "arm,vexpress"; - interrupt-parent = <&gic>; - #address-cells = <2>; - #size-cells = <2>; - - chosen { }; - - aliases { - serial0 = &v2m_serial0; - serial1 = &v2m_serial1; - serial2 = &v2m_serial2; - serial3 = &v2m_serial3; - }; - - cpus { - #address-cells = <2>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x0>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; - next-level-cache = <&L2_0>; - }; - cpu@1 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x1>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; - next-level-cache = <&L2_0>; - }; - cpu@2 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x2>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; - next-level-cache = <&L2_0>; - }; - cpu@3 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x3>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; - next-level-cache = <&L2_0>; - }; - - L2_0: l2-cache0 { - compatible = "cache"; - }; - }; - - memory@80000000 { - device_type = "memory"; - reg = <0x00000000 0x80000000 0 0x80000000>, - <0x00000008 0x80000000 0 0x80000000>; - }; - gic: interrupt-controller@2c001000 { compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <0>; + #address-cells = <2>; interrupt-controller; reg = <0x0 0x2c001000 0 0x1000>, - <0x0 0x2c002000 0 0x1000>, + <0x0 0x2c002000 0 0x2000>, <0x0 0x2c004000 0 0x2000>, <0x0 0x2c006000 0 0x2000>; interrupts = <1 9 0xf04>; }; - - timer { - compatible = "arm,armv8-timer"; - interrupts = <1 13 0xf08>, - <1 14 0xf08>, - <1 11 0xf08>, - <1 10 0xf08>; - clock-frequency = <100000000>; - }; - - pmu { - compatible = "arm,armv8-pmuv3"; - interrupts = <0 60 4>, - <0 61 4>, - <0 62 4>, - <0 63 4>; - }; - - smb { - compatible = "arm,vexpress,v2m-p1", "simple-bus"; - arm,v2m-memory-map = "rs1"; - #address-cells = <2>; /* SMB chipselect number and offset */ - #size-cells = <1>; - - ranges = <0 0 0 0x08000000 0x04000000>, - <1 0 0 0x14000000 0x04000000>, - <2 0 0 0x18000000 0x04000000>, - <3 0 0 0x1c000000 0x04000000>, - <4 0 0 0x0c000000 0x04000000>, - <5 0 0 0x10000000 0x04000000>; - - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 63>; - interrupt-map = <0 0 0 &gic 0 0 4>, - <0 0 1 &gic 0 1 4>, - <0 0 2 &gic 0 2 4>, - <0 0 3 &gic 0 3 4>, - <0 0 4 &gic 0 4 4>, - <0 0 5 &gic 0 5 4>, - <0 0 6 &gic 0 6 4>, - <0 0 7 &gic 0 7 4>, - <0 0 8 &gic 0 8 4>, - <0 0 9 &gic 0 9 4>, - <0 0 10 &gic 0 10 4>, - <0 0 11 &gic 0 11 4>, - <0 0 12 &gic 0 12 4>, - <0 0 13 &gic 0 13 4>, - <0 0 14 &gic 0 14 4>, - <0 0 15 &gic 0 15 4>, - <0 0 16 &gic 0 16 4>, - <0 0 17 &gic 0 17 4>, - <0 0 18 &gic 0 18 4>, - <0 0 19 &gic 0 19 4>, - <0 0 20 &gic 0 20 4>, - <0 0 21 &gic 0 21 4>, - <0 0 22 &gic 0 22 4>, - <0 0 23 &gic 0 23 4>, - <0 0 24 &gic 0 24 4>, - <0 0 25 &gic 0 25 4>, - <0 0 26 &gic 0 26 4>, - <0 0 27 &gic 0 27 4>, - <0 0 28 &gic 0 28 4>, - <0 0 29 &gic 0 29 4>, - <0 0 30 &gic 0 30 4>, - <0 0 31 &gic 0 31 4>, - <0 0 32 &gic 0 32 4>, - <0 0 33 &gic 0 33 4>, - <0 0 34 &gic 0 34 4>, - <0 0 35 &gic 0 35 4>, - <0 0 36 &gic 0 36 4>, - <0 0 37 &gic 0 37 4>, - <0 0 38 &gic 0 38 4>, - <0 0 39 &gic 0 39 4>, - <0 0 40 &gic 0 40 4>, - <0 0 41 &gic 0 41 4>, - <0 0 42 &gic 0 42 4>; - - ethernet@2,02000000 { - compatible = "smsc,lan91c111"; - reg = <2 0x02000000 0x10000>; - interrupts = <15>; - }; - - v2m_clk24mhz: clk24mhz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <24000000>; - clock-output-names = "v2m:clk24mhz"; - }; - - v2m_refclk1mhz: refclk1mhz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <1000000>; - clock-output-names = "v2m:refclk1mhz"; - }; - - v2m_refclk32khz: refclk32khz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <32768>; - clock-output-names = "v2m:refclk32khz"; - }; - - iofpga@3,00000000 { - compatible = "arm,amba-bus", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 3 0 0x200000>; - - v2m_sysreg: sysreg@010000 { - compatible = "arm,vexpress-sysreg"; - reg = <0x010000 0x1000>; - }; - - v2m_serial0: uart@090000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x090000 0x1000>; - interrupts = <5>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - v2m_serial1: uart@0a0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0a0000 0x1000>; - interrupts = <6>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - v2m_serial2: uart@0b0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0b0000 0x1000>; - interrupts = <7>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - v2m_serial3: uart@0c0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0c0000 0x1000>; - interrupts = <8>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - virtio_block@0130000 { - compatible = "virtio,mmio"; - reg = <0x130000 0x200>; - interrupts = <42>; - }; - }; - }; }; diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dtsi b/arch/arm64/boot/dts/arm/foundation-v8.dtsi new file mode 100644 index 000000000000..7cfa8e414e7f --- /dev/null +++ b/arch/arm64/boot/dts/arm/foundation-v8.dtsi @@ -0,0 +1,236 @@ +/* + * ARM Ltd. + * + * ARMv8 Foundation model DTS + */ + +/dts-v1/; + +/memreserve/ 0x80000000 0x00010000; + +/ { + model = "Foundation-v8A"; + compatible = "arm,foundation-aarch64", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + next-level-cache = <&L2_0>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + next-level-cache = <&L2_0>; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + next-level-cache = <&L2_0>; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + next-level-cache = <&L2_0>; + }; + + L2_0: l2-cache0 { + compatible = "cache"; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0 0x80000000>, + <0x00000008 0x80000000 0 0x80000000>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + clock-frequency = <100000000>; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + }; + + watchdog@2a440000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0x2a440000 0 0x1000>, + <0x0 0x2a450000 0 0x1000>; + interrupts = <0 27 4>; + timeout-sec = <30>; + }; + + smb@08000000 { + compatible = "arm,vexpress,v2m-p1", "simple-bus"; + arm,v2m-memory-map = "rs1"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 0 0 4>, + <0 0 1 &gic 0 0 0 1 4>, + <0 0 2 &gic 0 0 0 2 4>, + <0 0 3 &gic 0 0 0 3 4>, + <0 0 4 &gic 0 0 0 4 4>, + <0 0 5 &gic 0 0 0 5 4>, + <0 0 6 &gic 0 0 0 6 4>, + <0 0 7 &gic 0 0 0 7 4>, + <0 0 8 &gic 0 0 0 8 4>, + <0 0 9 &gic 0 0 0 9 4>, + <0 0 10 &gic 0 0 0 10 4>, + <0 0 11 &gic 0 0 0 11 4>, + <0 0 12 &gic 0 0 0 12 4>, + <0 0 13 &gic 0 0 0 13 4>, + <0 0 14 &gic 0 0 0 14 4>, + <0 0 15 &gic 0 0 0 15 4>, + <0 0 16 &gic 0 0 0 16 4>, + <0 0 17 &gic 0 0 0 17 4>, + <0 0 18 &gic 0 0 0 18 4>, + <0 0 19 &gic 0 0 0 19 4>, + <0 0 20 &gic 0 0 0 20 4>, + <0 0 21 &gic 0 0 0 21 4>, + <0 0 22 &gic 0 0 0 22 4>, + <0 0 23 &gic 0 0 0 23 4>, + <0 0 24 &gic 0 0 0 24 4>, + <0 0 25 &gic 0 0 0 25 4>, + <0 0 26 &gic 0 0 0 26 4>, + <0 0 27 &gic 0 0 0 27 4>, + <0 0 28 &gic 0 0 0 28 4>, + <0 0 29 &gic 0 0 0 29 4>, + <0 0 30 &gic 0 0 0 30 4>, + <0 0 31 &gic 0 0 0 31 4>, + <0 0 32 &gic 0 0 0 32 4>, + <0 0 33 &gic 0 0 0 33 4>, + <0 0 34 &gic 0 0 0 34 4>, + <0 0 35 &gic 0 0 0 35 4>, + <0 0 36 &gic 0 0 0 36 4>, + <0 0 37 &gic 0 0 0 37 4>, + <0 0 38 &gic 0 0 0 38 4>, + <0 0 39 &gic 0 0 0 39 4>, + <0 0 40 &gic 0 0 0 40 4>, + <0 0 41 &gic 0 0 0 41 4>, + <0 0 42 &gic 0 0 0 42 4>; + + ethernet@2,02000000 { + compatible = "smsc,lan91c111"; + reg = <2 0x02000000 0x10000>; + interrupts = <15>; + }; + + v2m_clk24mhz: clk24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "v2m:clk24mhz"; + }; + + v2m_refclk1mhz: refclk1mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + clock-output-names = "v2m:refclk1mhz"; + }; + + v2m_refclk32khz: refclk32khz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "v2m:refclk32khz"; + }; + + iofpga@3,00000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + + v2m_sysreg: sysreg@010000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x010000 0x1000>; + }; + + v2m_serial0: uart@090000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x090000 0x1000>; + interrupts = <5>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial1: uart@0a0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a0000 0x1000>; + interrupts = <6>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial2: uart@0b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b0000 0x1000>; + interrupts = <7>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial3: uart@0c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c0000 0x1000>; + interrupts = <8>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + virtio_block@0130000 { + compatible = "virtio,mmio"; + reg = <0x130000 0x200>; + interrupts = <42>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index e5b59ca9debb..68ccc39a7a66 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -75,6 +75,28 @@ }; }; + pcie_ctlr: pcie-controller@40000000 { + compatible = "arm,juno-r1-pcie", "plda,xpressrich3-axi", "pci-host-ecam-generic"; + device_type = "pci"; + reg = <0 0x40000000 0 0x10000000>; /* ECAM config space */ + bus-range = <0 255>; + linux,pci-domain = <0>; + #address-cells = <3>; + #size-cells = <2>; + dma-coherent; + ranges = <0x01000000 0x00 0x5f800000 0x00 0x5f800000 0x0 0x00800000>, + <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>, + <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &gic 0 0 0 136 4>, + <0 0 0 2 &gic 0 0 0 137 4>, + <0 0 0 3 &gic 0 0 0 138 4>, + <0 0 0 4 &gic 0 0 0 139 4>; + msi-parent = <&v2m_0>; + status = "disabled"; + }; + scpi { compatible = "arm,scpi"; mboxes = <&mailbox 1>; @@ -83,17 +105,17 @@ clocks { compatible = "arm,scpi-clocks"; - scpi_dvfs: scpi_clocks@0 { + scpi_dvfs: scpi-dvfs { compatible = "arm,scpi-dvfs-clocks"; #clock-cells = <1>; clock-indices = <0>, <1>, <2>; clock-output-names = "atlclk", "aplclk","gpuclk"; }; - scpi_clk: scpi_clocks@3 { + scpi_clk: scpi-clk { compatible = "arm,scpi-variable-clocks"; #clock-cells = <1>; - clock-indices = <3>, <4>; - clock-output-names = "pxlclk0", "pxlclk1"; + clock-indices = <3>; + clock-output-names = "pxlclk"; }; }; @@ -124,6 +146,34 @@ clock-names = "apb_pclk"; }; + hdlcd@7ff50000 { + compatible = "arm,hdlcd"; + reg = <0 0x7ff50000 0 0x1000>; + interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scpi_clk 3>; + clock-names = "pxlclk"; + + port { + hdlcd1_output: hdlcd1-endpoint { + remote-endpoint = <&tda998x_1_input>; + }; + }; + }; + + hdlcd@7ff60000 { + compatible = "arm,hdlcd"; + reg = <0 0x7ff60000 0 0x1000>; + interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&scpi_clk 3>; + clock-names = "pxlclk"; + + port { + hdlcd0_output: hdlcd0-endpoint { + remote-endpoint = <&tda998x_0_input>; + }; + }; + }; + soc_uart0: uart@7ff80000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x0 0x7ff80000 0x0 0x1000>; @@ -142,14 +192,24 @@ i2c-sda-hold-time-ns = <500>; clocks = <&soc_smc50mhz>; - dvi0: dvi-transmitter@70 { + hdmi-transmitter@70 { compatible = "nxp,tda998x"; reg = <0x70>; + port { + tda998x_0_input: tda998x-0-endpoint { + remote-endpoint = <&hdlcd0_output>; + }; + }; }; - dvi1: dvi-transmitter@71 { + hdmi-transmitter@71 { compatible = "nxp,tda998x"; reg = <0x71>; + port { + tda998x_1_input: tda998x-1-endpoint { + remote-endpoint = <&hdlcd1_output>; + }; + }; }; }; @@ -183,7 +243,7 @@ <0x00000008 0x80000000 0x1 0x80000000>; }; - smb { + smb@08000000 { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <1>; diff --git a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi index 413f1b9ebcd4..3ad4c3000611 100644 --- a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi +++ b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi @@ -46,7 +46,7 @@ arm,vexpress,site = <0>; arm,v2m-memory-map = "rs1"; - mb_fixed_3v3: fixedregulator@0 { + mb_fixed_3v3: mcc-sb-3v3 { compatible = "regulator-fixed"; regulator-name = "MCC_SB_3V3"; regulator-min-microvolt = <3300000>; @@ -59,42 +59,42 @@ #address-cells = <1>; #size-cells = <0>; - button@1 { + power-button { debounce_interval = <50>; wakeup-source; linux,code = <116>; label = "POWER"; gpios = <&iofpga_gpio0 0 0x4>; }; - button@2 { + home-button { debounce_interval = <50>; wakeup-source; linux,code = <102>; label = "HOME"; gpios = <&iofpga_gpio0 1 0x4>; }; - button@3 { + rlock-button { debounce_interval = <50>; wakeup-source; linux,code = <152>; label = "RLOCK"; gpios = <&iofpga_gpio0 2 0x4>; }; - button@4 { + vol-up-button { debounce_interval = <50>; wakeup-source; linux,code = <115>; label = "VOL+"; gpios = <&iofpga_gpio0 3 0x4>; }; - button@5 { + vol-down-button { debounce_interval = <50>; wakeup-source; linux,code = <114>; label = "VOL-"; gpios = <&iofpga_gpio0 4 0x4>; }; - button@6 { + nmi-button { debounce_interval = <50>; wakeup-source; linux,code = <99>; @@ -139,7 +139,7 @@ }; iofpga@3,00000000 { - compatible = "arm,amba-bus", "simple-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0 3 0 0x200000>; @@ -159,7 +159,7 @@ compatible = "syscon", "simple-mfd"; reg = <0x010000 0x1000>; - led@08.0 { + led0 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x01>; @@ -167,7 +167,7 @@ linux,default-trigger = "heartbeat"; default-state = "on"; }; - led@08.1 { + led1 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x02>; @@ -175,7 +175,7 @@ linux,default-trigger = "mmc0"; default-state = "off"; }; - led@08.2 { + led2 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x04>; @@ -183,7 +183,7 @@ linux,default-trigger = "cpu0"; default-state = "off"; }; - led@08.3 { + led3 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x08>; @@ -191,7 +191,7 @@ linux,default-trigger = "cpu1"; default-state = "off"; }; - led@08.4 { + led4 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x10>; @@ -199,7 +199,7 @@ linux,default-trigger = "cpu2"; default-state = "off"; }; - led@08.5 { + led5 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x20>; @@ -207,14 +207,14 @@ linux,default-trigger = "cpu3"; default-state = "off"; }; - led@08.6 { + led6 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x40>; label = "vexpress:6"; default-state = "off"; }; - led@08.7 { + led7 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x80>; diff --git a/arch/arm64/boot/dts/arm/juno-r1.dts b/arch/arm64/boot/dts/arm/juno-r1.dts index 8826f834f54f..d95d9e7e2dc0 100644 --- a/arch/arm64/boot/dts/arm/juno-r1.dts +++ b/arch/arm64/boot/dts/arm/juno-r1.dts @@ -172,29 +172,12 @@ }; #include "juno-base.dtsi" - - pcie-controller@40000000 { - compatible = "arm,juno-r1-pcie", "plda,xpressrich3-axi", "pci-host-ecam-generic"; - device_type = "pci"; - reg = <0 0x40000000 0 0x10000000>; /* ECAM config space */ - bus-range = <0 255>; - linux,pci-domain = <0>; - #address-cells = <3>; - #size-cells = <2>; - dma-coherent; - ranges = <0x01000000 0x00 0x5f800000 0x00 0x5f800000 0x0 0x00800000>, - <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>, - <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &gic 0 0 0 136 4>, - <0 0 0 2 &gic 0 0 0 137 4>, - <0 0 0 3 &gic 0 0 0 138 4>, - <0 0 0 4 &gic 0 0 0 139 4>; - msi-parent = <&v2m_0>; - }; }; &memtimer { status = "okay"; }; + +&pcie_ctlr { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/arm/juno-r2.dts b/arch/arm64/boot/dts/arm/juno-r2.dts new file mode 100644 index 000000000000..88ecd6182b67 --- /dev/null +++ b/arch/arm64/boot/dts/arm/juno-r2.dts @@ -0,0 +1,183 @@ +/* + * ARM Ltd. Juno Platform + * + * Copyright (c) 2015 ARM Ltd. + * + * This file is licensed under a dual GPLv2 or BSD license. + */ + +/dts-v1/; + +#include <dt-bindings/interrupt-controller/arm-gic.h> + +/ { + model = "ARM Juno development board (r2)"; + compatible = "arm,juno-r2", "arm,juno", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &soc_uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&A72_0>; + }; + core1 { + cpu = <&A72_1>; + }; + }; + + cluster1 { + core0 { + cpu = <&A53_0>; + }; + core1 { + cpu = <&A53_1>; + }; + core2 { + cpu = <&A53_2>; + }; + core3 { + cpu = <&A53_3>; + }; + }; + }; + + idle-states { + entry-method = "arm,psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <1200>; + min-residency-us = <2000>; + }; + + CLUSTER_SLEEP_0: cluster-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x1010000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <1200>; + min-residency-us = <2500>; + }; + }; + + A72_0: cpu@0 { + compatible = "arm,cortex-a72","arm,armv8"; + reg = <0x0 0x0>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A72_L2>; + clocks = <&scpi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A72_1: cpu@1 { + compatible = "arm,cortex-a72","arm,armv8"; + reg = <0x0 0x1>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A72_L2>; + clocks = <&scpi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A53_0: cpu@100 { + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x0 0x100>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A53_1: cpu@101 { + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x0 0x101>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A53_2: cpu@102 { + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x0 0x102>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A53_3: cpu@103 { + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x0 0x103>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A72_L2: l2-cache0 { + compatible = "cache"; + }; + + A53_L2: l2-cache1 { + compatible = "cache"; + }; + }; + + pmu_a72 { + compatible = "arm,cortex-a72-pmu"; + interrupts = <GIC_SPI 02 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 06 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&A72_0>, + <&A72_1>; + }; + + pmu_a53 { + compatible = "arm,cortex-a53-pmu"; + interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&A53_0>, + <&A53_1>, + <&A53_2>, + <&A53_3>; + }; + + #include "juno-base.dtsi" +}; + +&memtimer { + status = "okay"; +}; + +&pcie_ctlr { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts index 20addabbd127..a852e28a40e1 100644 --- a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts +++ b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts @@ -104,7 +104,7 @@ <0 63 4>; }; - smb { + smb@08000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi index 88a7583ed7a7..161ac98418a3 100644 --- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi +++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi @@ -55,7 +55,7 @@ }; iofpga@3,00000000 { - compatible = "arm,amba-bus", "simple-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0 3 0 0x200000>; @@ -226,7 +226,7 @@ }; }; - v2m_fixed_3v3: fixedregulator@0 { + v2m_fixed_3v3: v2m-3v3 { compatible = "regulator-fixed"; regulator-name = "3V3"; regulator-min-microvolt = <3300000>; @@ -238,7 +238,7 @@ compatible = "arm,vexpress,config-bus"; arm,vexpress,config-bridge = <&v2m_sysreg>; - v2m_oscclk1: osc@1 { + v2m_oscclk1: oscclk1 { /* CLCD clock */ compatible = "arm,vexpress-osc"; arm,vexpress-sysreg,func = <1 1>; @@ -247,27 +247,27 @@ clock-output-names = "v2m:oscclk1"; }; - reset@0 { + reset { compatible = "arm,vexpress-reset"; arm,vexpress-sysreg,func = <5 0>; }; - muxfpga@0 { + muxfpga { compatible = "arm,vexpress-muxfpga"; arm,vexpress-sysreg,func = <7 0>; }; - shutdown@0 { + shutdown { compatible = "arm,vexpress-shutdown"; arm,vexpress-sysreg,func = <8 0>; }; - reboot@0 { + reboot { compatible = "arm,vexpress-reboot"; arm,vexpress-sysreg,func = <9 0>; }; - dvimode@0 { + dvimode { compatible = "arm,vexpress-dvimode"; arm,vexpress-sysreg,func = <11 0>; }; diff --git a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts index bb3c26d1154d..e3a171162bb4 100644 --- a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts +++ b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts @@ -93,7 +93,7 @@ compatible = "arm,vexpress,config-bus"; arm,vexpress,config-bridge = <&v2m_sysreg>; - smbclk: osc@4 { + smbclk: smclk { /* SMC clock */ compatible = "arm,vexpress-osc"; arm,vexpress-sysreg,func = <1 4>; @@ -102,7 +102,7 @@ clock-output-names = "smclk"; }; - volt@0 { + volt-vio { /* VIO to expansion board above */ compatible = "arm,vexpress-volt"; arm,vexpress-sysreg,func = <2 0>; @@ -112,7 +112,7 @@ regulator-always-on; }; - volt@1 { + volt-12v { /* 12V from power connector J6 */ compatible = "arm,vexpress-volt"; arm,vexpress-sysreg,func = <2 1>; @@ -120,7 +120,7 @@ regulator-always-on; }; - temp@0 { + temp-fpga { /* FPGA temperature */ compatible = "arm,vexpress-temp"; arm,vexpress-sysreg,func = <4 0>; @@ -128,7 +128,7 @@ }; }; - smb { + smb@08000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm64/boot/dts/broadcom/Makefile b/arch/arm64/boot/dts/broadcom/Makefile index e21fe66f1837..bec1f8b36f60 100644 --- a/arch/arm64/boot/dts/broadcom/Makefile +++ b/arch/arm64/boot/dts/broadcom/Makefile @@ -1,4 +1,5 @@ dtb-$(CONFIG_ARCH_BCM_IPROC) += ns2-svk.dtb +dtb-$(CONFIG_ARCH_VULCAN) += vulcan-eval.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts index 6bb3d4d9efa9..ce0ab84e0f2d 100644 --- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts +++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts @@ -52,6 +52,14 @@ }; }; +&pcie0 { + status = "ok"; +}; + +&pcie4 { + status = "ok"; +}; + &i2c0 { status = "ok"; }; @@ -64,6 +72,10 @@ status = "ok"; }; +&sdio0 { + status = "ok"; +}; + &nand { nandcs@0 { compatible = "brcm,nandcs"; diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi index a510d3a8e647..6f81c9d7fb06 100644 --- a/arch/arm64/boot/dts/broadcom/ns2.dtsi +++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi @@ -137,6 +137,80 @@ }; }; + pcie0: pcie@20020000 { + compatible = "brcm,iproc-pcie"; + reg = <0 0x20020000 0 0x1000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 281 IRQ_TYPE_NONE>; + + linux,pci-domain = <0>; + + bus-range = <0x00 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x83000000 0 0x00000000 0 0x00000000 0 0x20000000>; + + brcm,pcie-ob; + brcm,pcie-ob-oarr-size; + brcm,pcie-ob-axi-offset = <0x00000000>; + brcm,pcie-ob-window-size = <256>; + + status = "disabled"; + + msi-parent = <&msi0>; + msi0: msi@20020000 { + compatible = "brcm,iproc-msi"; + msi-controller; + interrupt-parent = <&gic>; + interrupts = <GIC_SPI 277 IRQ_TYPE_NONE>, + <GIC_SPI 278 IRQ_TYPE_NONE>, + <GIC_SPI 279 IRQ_TYPE_NONE>, + <GIC_SPI 280 IRQ_TYPE_NONE>; + brcm,num-eq-region = <1>; + brcm,num-msi-msg-region = <1>; + }; + }; + + pcie4: pcie@50020000 { + compatible = "brcm,iproc-pcie"; + reg = <0 0x50020000 0 0x1000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 305 IRQ_TYPE_NONE>; + + linux,pci-domain = <4>; + + bus-range = <0x00 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x83000000 0 0x00000000 0 0x30000000 0 0x20000000>; + + brcm,pcie-ob; + brcm,pcie-ob-oarr-size; + brcm,pcie-ob-axi-offset = <0x30000000>; + brcm,pcie-ob-window-size = <256>; + + status = "disabled"; + + msi-parent = <&msi4>; + msi4: msi@50020000 { + compatible = "brcm,iproc-msi"; + msi-controller; + interrupt-parent = <&gic>; + interrupts = <GIC_SPI 301 IRQ_TYPE_NONE>, + <GIC_SPI 302 IRQ_TYPE_NONE>, + <GIC_SPI 303 IRQ_TYPE_NONE>, + <GIC_SPI 304 IRQ_TYPE_NONE>; + }; + }; + soc: soc { compatible = "simple-bus"; #address-cells = <1>; @@ -256,6 +330,46 @@ <0x65260000 0x1000>; }; + timer0: timer@66030000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x66030000 0x1000>; + interrupts = <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&iprocslow>, + <&iprocslow>, + <&iprocslow>; + clock-names = "timer1", "timer2", "apb_pclk"; + }; + + timer1: timer@66040000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x66040000 0x1000>; + interrupts = <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&iprocslow>, + <&iprocslow>, + <&iprocslow>; + clock-names = "timer1", "timer2", "apb_pclk"; + }; + + timer2: timer@66050000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x66050000 0x1000>; + interrupts = <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&iprocslow>, + <&iprocslow>, + <&iprocslow>; + clock-names = "timer1", "timer2", "apb_pclk"; + }; + + timer3: timer@66060000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x66060000 0x1000>; + interrupts = <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&iprocslow>, + <&iprocslow>, + <&iprocslow>; + clock-names = "timer1", "timer2", "apb_pclk"; + }; + i2c0: i2c@66080000 { compatible = "brcm,iproc-i2c"; reg = <0x66080000 0x100>; @@ -266,6 +380,14 @@ status = "disabled"; }; + wdt0: watchdog@66090000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x66090000 0x1000>; + interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&iprocslow>, <&iprocslow>; + clock-names = "wdogclk", "apb_pclk"; + }; + i2c1: i2c@660b0000 { compatible = "brcm,iproc-i2c"; reg = <0x660b0000 0x100>; @@ -291,6 +413,24 @@ reg = <0x66220000 0x28>; }; + sdio0: sdhci@66420000 { + compatible = "brcm,sdhci-iproc-cygnus"; + reg = <0x66420000 0x100>; + interrupts = <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>; + bus-width = <8>; + clocks = <&genpll_sw BCM_NS2_GENPLL_SW_SDIO_CLK>; + status = "disabled"; + }; + + sdio1: sdhci@66430000 { + compatible = "brcm,sdhci-iproc-cygnus"; + reg = <0x66430000 0x100>; + interrupts = <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>; + bus-width = <8>; + clocks = <&genpll_sw BCM_NS2_GENPLL_SW_SDIO_CLK>; + status = "disabled"; + }; + nand: nand@66460000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x66460000 0x600>, diff --git a/arch/arm64/boot/dts/broadcom/vulcan-eval.dts b/arch/arm64/boot/dts/broadcom/vulcan-eval.dts new file mode 100644 index 000000000000..9ee8d3da0e3f --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/vulcan-eval.dts @@ -0,0 +1,33 @@ +/* + * dts file for Broadcom (BRCM) Vulcan Evaluation Platform + * + * Copyright (c) 2013-2016 Broadcom + * + * 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. + */ + +/dts-v1/; + +#include "vulcan.dtsi" + +/ { + model = "Broadcom Vulcan Eval Platform"; + compatible = "brcm,vulcan-eval", "brcm,vulcan-soc"; + + memory { + device_type = "memory"; + reg = <0x00000000 0x80000000 0x0 0x80000000>, /* 2G @ 2G */ + <0x00000008 0x80000000 0x0 0x80000000>; /* 2G @ 34G */ + }; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; diff --git a/arch/arm64/boot/dts/broadcom/vulcan.dtsi b/arch/arm64/boot/dts/broadcom/vulcan.dtsi new file mode 100644 index 000000000000..c49b5a85809c --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/vulcan.dtsi @@ -0,0 +1,144 @@ +/* + * dtsi file for Broadcom (BRCM) Vulcan processor + * + * Copyright (c) 2013-2016 Broadcom + * Author: Zi Shen Lim <zlim@broadcom.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 <dt-bindings/interrupt-controller/arm-gic.h> + +/ { + model = "Broadcom Vulcan"; + compatible = "brcm,vulcan-soc"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + /* just 4 cpus now, 128 needed in full config */ + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + cpu@0 { + device_type = "cpu"; + compatible = "brcm,vulcan", "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "brcm,vulcan", "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "psci"; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "brcm,vulcan", "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "psci"; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "brcm,vulcan", "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "psci"; + }; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + gic: interrupt-controller@400080000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + interrupt-controller; + #redistributor-regions = <1>; + reg = <0x04 0x00080000 0x0 0x20000>, /* GICD */ + <0x04 0x01000000 0x0 0x1000000>; /* GICR */ + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + + gicits: gic-its@40010000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x04 0x00100000 0x0 0x20000>; /* GIC ITS */ + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>, + <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH>, + <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>, + <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH>; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>; /* PMU overflow */ + }; + + clk125mhz: uart_clk125mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + clock-output-names = "clk125mhz"; + }; + + pci { + compatible = "pci-host-ecam-generic"; + device_type = "pci"; + #interrupt-cells = <1>; + #address-cells = <3>; + #size-cells = <2>; + + /* ECAM at 0x3000_0000 - 0x4000_0000 */ + reg = <0x0 0x30000000 0x0 0x10000000>; + reg-names = "PCI ECAM"; + + /* IO 0x4000_0000 - 0x4001_0000 */ + ranges = <0x01000000 0 0x40000000 0 0x40000000 0 0x00010000 + /* MEM 0x4800_0000 - 0x5000_0000 */ + 0x02000000 0 0x48000000 0 0x48000000 0 0x08000000 + /* MEM64 pref 0x6_0000_0000 - 0x7_0000_0000 */ + 0x43000000 6 0x00000000 6 0x00000000 1 0x00000000>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = + /* addr pin ic icaddr icintr */ + <0 0 0 1 &gic 0 0 GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH + 0 0 0 2 &gic 0 0 GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH + 0 0 0 3 &gic 0 0 GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH + 0 0 0 4 &gic 0 0 GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; + msi-parent = <&gicits>; + dma-coherent; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + uart0: serial@402020000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x04 0x02020000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk125mhz>; + clock-names = "apb_pclk"; + }; + }; + +}; diff --git a/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi b/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi index 9cb7cf94284a..2eb9b225f0bc 100644 --- a/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi +++ b/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi @@ -360,6 +360,11 @@ <1 10 0xff01>; }; + pmu { + compatible = "cavium,thunder-pmu", "arm,armv8-pmuv3"; + interrupts = <1 7 4>; + }; + soc { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile index 20310e5b6d6f..50c9b9383cfa 100644 --- a/arch/arm64/boot/dts/exynos/Makefile +++ b/arch/arm64/boot/dts/exynos/Makefile @@ -1,4 +1,4 @@ -dtb-$(CONFIG_ARCH_EXYNOS7) += exynos7-espresso.dtb +dtb-$(CONFIG_ARCH_EXYNOS) += exynos7-espresso.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi index 42a61549afd4..be72bf5b58b5 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi @@ -407,6 +407,7 @@ reg = <0x0 0x2f00000 0x0 0x10000>; interrupts = <0 60 0x4>; dr_mode = "host"; + snps,quirk-frame-length-adjustment = <0x20>; }; usb1: usb3@3000000 { @@ -414,6 +415,7 @@ reg = <0x0 0x3000000 0x0 0x10000>; interrupts = <0 61 0x4>; dr_mode = "host"; + snps,quirk-frame-length-adjustment = <0x20>; }; usb2: usb3@3100000 { @@ -421,6 +423,7 @@ reg = <0x0 0x3100000 0x0 0x10000>; interrupts = <0 63 0x4>; dr_mode = "host"; + snps,quirk-frame-length-adjustment = <0x20>; }; sata: sata@3200000 { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi index 2b23d0360683..9d746c69a789 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi @@ -456,7 +456,8 @@ }; pcie@3400000 { - compatible = "fsl,ls2080a-pcie", "snps,dw-pcie"; + compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", + "snps,dw-pcie"; reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ 0x10 0x00000000 0x0 0x00002000>; /* configuration space */ reg-names = "regs", "config"; @@ -479,7 +480,8 @@ }; pcie@3500000 { - compatible = "fsl,ls2080a-pcie", "snps,dw-pcie"; + compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", + "snps,dw-pcie"; reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ 0x12 0x00000000 0x0 0x00002000>; /* configuration space */ reg-names = "regs", "config"; @@ -502,7 +504,8 @@ }; pcie@3600000 { - compatible = "fsl,ls2080a-pcie", "snps,dw-pcie"; + compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", + "snps,dw-pcie"; reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */ 0x14 0x00000000 0x0 0x00002000>; /* configuration space */ reg-names = "regs", "config"; @@ -525,7 +528,8 @@ }; pcie@3700000 { - compatible = "fsl,ls2080a-pcie", "snps,dw-pcie"; + compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", + "snps,dw-pcie"; reg = <0x00 0x03700000 0x0 0x00100000 /* controller registers */ 0x16 0x00000000 0x0 0x00002000>; /* configuration space */ reg-names = "regs", "config"; @@ -569,6 +573,7 @@ reg = <0x0 0x3100000 0x0 0x10000>; interrupts = <0 80 0x4>; /* Level high type */ dr_mode = "host"; + snps,quirk-frame-length-adjustment = <0x20>; }; usb1: usb3@3110000 { @@ -577,6 +582,7 @@ reg = <0x0 0x3110000 0x0 0x10000>; interrupts = <0 81 0x4>; /* Level high type */ dr_mode = "host"; + snps,quirk-frame-length-adjustment = <0x20>; }; ccn@4000000 { diff --git a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts index ae34e250456f..e9436c0d81f7 100644 --- a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts +++ b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts @@ -11,6 +11,7 @@ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> #include "hip05.dtsi" / { @@ -29,8 +30,25 @@ chosen { stdout-path = "serial0:115200n8"; }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + pwrbutton { + label = "Power Button"; + gpios = <&porta 8 GPIO_ACTIVE_LOW>; + linux,code = <116>; + debounce-interval = <0>; + }; + }; }; &uart0 { status = "ok"; }; + +&peri_gpio0 { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi index c1ea999c7be1..6319ff3b03ea 100644 --- a/arch/arm64/boot/dts/hisilicon/hip05.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi @@ -90,6 +90,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20000>; enable-method = "psci"; + next-level-cache = <&cluster0_l2>; }; cpu1: cpu@20001 { @@ -97,6 +98,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20001>; enable-method = "psci"; + next-level-cache = <&cluster0_l2>; }; cpu2: cpu@20002 { @@ -104,6 +106,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20002>; enable-method = "psci"; + next-level-cache = <&cluster0_l2>; }; cpu3: cpu@20003 { @@ -111,6 +114,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20003>; enable-method = "psci"; + next-level-cache = <&cluster0_l2>; }; cpu4: cpu@20100 { @@ -118,6 +122,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20100>; enable-method = "psci"; + next-level-cache = <&cluster1_l2>; }; cpu5: cpu@20101 { @@ -125,6 +130,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20101>; enable-method = "psci"; + next-level-cache = <&cluster1_l2>; }; cpu6: cpu@20102 { @@ -132,6 +138,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20102>; enable-method = "psci"; + next-level-cache = <&cluster1_l2>; }; cpu7: cpu@20103 { @@ -139,6 +146,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20103>; enable-method = "psci"; + next-level-cache = <&cluster1_l2>; }; cpu8: cpu@20200 { @@ -146,6 +154,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20200>; enable-method = "psci"; + next-level-cache = <&cluster2_l2>; }; cpu9: cpu@20201 { @@ -153,6 +162,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20201>; enable-method = "psci"; + next-level-cache = <&cluster2_l2>; }; cpu10: cpu@20202 { @@ -160,6 +170,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20202>; enable-method = "psci"; + next-level-cache = <&cluster2_l2>; }; cpu11: cpu@20203 { @@ -167,6 +178,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20203>; enable-method = "psci"; + next-level-cache = <&cluster2_l2>; }; cpu12: cpu@20300 { @@ -174,6 +186,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20300>; enable-method = "psci"; + next-level-cache = <&cluster3_l2>; }; cpu13: cpu@20301 { @@ -181,6 +194,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20301>; enable-method = "psci"; + next-level-cache = <&cluster3_l2>; }; cpu14: cpu@20302 { @@ -188,6 +202,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20302>; enable-method = "psci"; + next-level-cache = <&cluster3_l2>; }; cpu15: cpu@20303 { @@ -195,6 +210,23 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20303>; enable-method = "psci"; + next-level-cache = <&cluster3_l2>; + }; + + cluster0_l2: l2-cache0 { + compatible = "cache"; + }; + + cluster1_l2: l2-cache1 { + compatible = "cache"; + }; + + cluster2_l2: l2-cache2 { + compatible = "cache"; + }; + + cluster3_l2: l2-cache3 { + compatible = "cache"; }; }; @@ -214,11 +246,29 @@ <0x0 0xfe020000 0 0x10000>; /* GICV */ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; - its_totems: interrupt-controller@8c000000 { + its_peri: interrupt-controller@8c000000 { compatible = "arm,gic-v3-its"; msi-controller; reg = <0x0 0x8c000000 0x0 0x40000>; }; + + its_m3: interrupt-controller@a3000000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0xa3000000 0x0 0x40000>; + }; + + its_pcie: interrupt-controller@b7000000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0xb7000000 0x0 0x40000>; + }; + + its_dsa: interrupt-controller@c6000000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0xc6000000 0x0 0x40000>; + }; }; timer { @@ -230,7 +280,7 @@ }; pmu { - compatible = "arm,armv8-pmuv3"; + compatible = "arm,cortex-a57-pmu"; interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>; }; @@ -272,5 +322,43 @@ reg-io-width = <4>; status = "disabled"; }; + + peri_gpio0: gpio@802e0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dw-apb-gpio"; + reg = <0x0 0x802e0000 0x0 0x10000>; + status = "disabled"; + + porta: gpio-controller@0 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + reg = <0>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + + peri_gpio1: gpio@802f0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dw-apb-gpio"; + reg = <0x0 0x802f0000 0x0 0x10000>; + status = "disabled"; + + portb: gpio-controller@0 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + reg = <0>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/marvell/Makefile b/arch/arm64/boot/dts/marvell/Makefile index 348f4db4f313..308468d377d0 100644 --- a/arch/arm64/boot/dts/marvell/Makefile +++ b/arch/arm64/boot/dts/marvell/Makefile @@ -1,6 +1,11 @@ +# Berlin SoC Family dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-dmp.dtb dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-stb.dtb +# Mvebu SoC Family +dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-db.dtb +dtb-$(CONFIG_ARCH_MVEBU) += armada-7040-db.dtb + always := $(dtb-y) subdir-y := $(dts-dirs) clean-files := *.dtb diff --git a/arch/arm64/boot/dts/marvell/armada-371x.dtsi b/arch/arm64/boot/dts/marvell/armada-371x.dtsi new file mode 100644 index 000000000000..c9e5325b8ac3 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-371x.dtsi @@ -0,0 +1,53 @@ +/* + * Device Tree Include file for Marvell Armada 371x family of SoCs + * (also named 88F3710) + * + * Copyright (C) 2016 Marvell + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file 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. + * + * Or, alternatively + * + * b) 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 , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "armada-37xx.dtsi" + +/ { + model = "Marvell Armada 3710 SoC"; + compatible = "marvell,armada3710", "marvell,armada3700"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts new file mode 100644 index 000000000000..359050154511 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts @@ -0,0 +1,86 @@ +/* + * Device Tree file for Marvell Armada 3720 development board + * (DB-88F3720-DDR3) + * Copyright (C) 2016 Marvell + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file 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. + * + * Or, alternatively + * + * b) 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 , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "armada-372x.dtsi" + +/ { + model = "Marvell Armada 3720 Development Board DB-88F3720-DDR3"; + compatible = "marvell,armada-3720-db", "marvell,armada3720", "marvell,armada3710"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x00000000 0x00000000 0x20000000>; + }; + + soc { + internal-regs { + /* + * Exported on the micro USB connector CON32 + * through an FTDI + */ + uart0: serial@12000 { + status = "okay"; + }; + + /* CON31 */ + usb3@58000 { + status = "okay"; + }; + + /* CON3 */ + sata@e0000 { + status = "okay"; + }; + }; + }; +}; + diff --git a/arch/arm64/boot/dts/marvell/armada-372x.dtsi b/arch/arm64/boot/dts/marvell/armada-372x.dtsi new file mode 100644 index 000000000000..f292a00ce97c --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-372x.dtsi @@ -0,0 +1,63 @@ +/* + * Device Tree Include file for Marvell Armada 372x family of SoCs + * (also named 88F3720) + * + * Copyright (C) 2016 Marvell + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file 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. + * + * Or, alternatively + * + * b) 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 , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "armada-37xx.dtsi" + +/ { + model = "Marvell Armada 3720 SoC"; + compatible = "marvell,armada3720", "marvell,armada3710"; + + cpus { + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x1>; + enable-method = "psci"; + }; + }; + +}; diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi new file mode 100644 index 000000000000..ba9df7ff2a72 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi @@ -0,0 +1,131 @@ +/* + * Device Tree Include file for Marvell Armada 37xx family of SoCs. + * + * Copyright (C) 2016 Marvell + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file 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. + * + * Or, alternatively + * + * b) 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 , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <dt-bindings/interrupt-controller/arm-gic.h> + +/ { + model = "Marvell Armada 37xx SoC"; + compatible = "marvell,armada3700"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &uart0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0>; + enable-method = "psci"; + }; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 + (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>, + <GIC_PPI 14 + (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>, + <GIC_PPI 11 + (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>, + <GIC_PPI 10 + (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + internal-regs { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + /* 32M internal register @ 0xd000_0000 */ + ranges = <0x0 0x0 0xd0000000 0x2000000>; + + uart0: serial@12000 { + compatible = "marvell,armada-3700-uart"; + reg = <0x12000 0x400>; + interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + usb3@58000 { + compatible = "generic-xhci"; + reg = <0x58000 0x4000>; + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + sata@e0000 { + compatible = "marvell,armada-3700-ahci"; + reg = <0xe0000 0x2000>; + interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + gic: interrupt-controller@1d00000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x1d00000 0x10000>, /* GICD */ + <0x1d40000 0x40000>; /* GICR */ + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-7020.dtsi b/arch/arm64/boot/dts/marvell/armada-7020.dtsi new file mode 100644 index 000000000000..52575756d0be --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-7020.dtsi @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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. + * + * This library 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. + * + * Or, alternatively, + * + * b) 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 AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for the Armada 7020 SoC, made of an AP806 Dual and + * one CP110. + */ + +#include "armada-ap806-dual.dtsi" + +/ { + model = "Marvell Armada 7020"; + compatible = "marvell,armada7020", "marvell,armada-ap806-dual", + "marvell,armada-ap806"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-7040-db.dts b/arch/arm64/boot/dts/marvell/armada-7040-db.dts new file mode 100644 index 000000000000..064a251346dd --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-7040-db.dts @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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. + * + * This library 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. + * + * Or, alternatively, + * + * b) 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 AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada 7040 Development board platform + */ + +#include "armada-7040.dtsi" + +/ { + model = "Marvell Armada 7040 DB board"; + compatible = "marvell,armada7040-db", "marvell,armada7040", + "marvell,armada-ap806-quad", "marvell,armada-ap806"; + + memory@00000000 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + ap806 { + config-space { + spi@510600 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "n25q128a13"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <10000000>; + + partition@0 { + label = "U-Boot"; + reg = <0 0x200000>; + }; + partition@400000 { + label = "Filesystem"; + reg = <0x200000 0xce0000>; + }; + }; + }; + + i2c@511000 { + status = "okay"; + clock-frequency = <100000>; + }; + + serial@512000 { + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-7040.dtsi b/arch/arm64/boot/dts/marvell/armada-7040.dtsi new file mode 100644 index 000000000000..7a2de8bf7907 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-7040.dtsi @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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. + * + * This library 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. + * + * Or, alternatively, + * + * b) 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 AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for the Armada 7040 SoC, made of an AP806 Quad and + * one CP110. + */ + +#include "armada-ap806-quad.dtsi" + +/ { + model = "Marvell Armada 7040"; + compatible = "marvell,armada7040", "marvell,armada-ap806-quad", + "marvell,armada-ap806"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-8020.dtsi b/arch/arm64/boot/dts/marvell/armada-8020.dtsi new file mode 100644 index 000000000000..73d69d99513f --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-8020.dtsi @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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. + * + * This library 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. + * + * Or, alternatively, + * + * b) 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 AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for the Armada 8020 SoC, made of an AP806 Dual and + * two CP110. + */ + +#include "armada-ap806-dual.dtsi" + +/ { + model = "Marvell Armada 8020"; + compatible = "marvell,armada8020", "marvell,armada-ap806-dual", + "marvell,armada-ap806"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-8040.dtsi b/arch/arm64/boot/dts/marvell/armada-8040.dtsi new file mode 100644 index 000000000000..a1406a40959e --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-8040.dtsi @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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. + * + * This library 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. + * + * Or, alternatively, + * + * b) 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 AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for the Armada 8040 SoC, made of an AP806 Quad and + * two CP110. + */ + +#include "armada-ap806-quad.dtsi" + +/ { + model = "Marvell Armada 8040"; + compatible = "marvell,armada8040", "marvell,armada-ap806-quad", + "marvell,armada-ap806"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi new file mode 100644 index 000000000000..f25c5c17fad7 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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. + * + * This library 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. + * + * Or, alternatively, + * + * b) 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 AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada AP806. + */ + +#include "armada-ap806.dtsi" + +/ { + model = "Marvell Armada AP806 Dual"; + compatible = "marvell,armada-ap806-dual", "marvell,armada-ap806"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@000 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x000>; + enable-method = "psci"; + }; + cpu@001 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x001>; + enable-method = "psci"; + }; + }; +}; + diff --git a/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi new file mode 100644 index 000000000000..baa7d9a516b3 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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. + * + * This library 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. + * + * Or, alternatively, + * + * b) 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 AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada AP806. + */ + +#include "armada-ap806.dtsi" + +/ { + model = "Marvell Armada AP806 Quad"; + compatible = "marvell,armada-ap806-quad", "marvell,armada-ap806"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@000 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x000>; + enable-method = "psci"; + }; + cpu@001 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x001>; + enable-method = "psci"; + }; + cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x100>; + enable-method = "psci"; + }; + cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x101>; + enable-method = "psci"; + }; + }; + +}; + diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi new file mode 100644 index 000000000000..556a92bcc2f6 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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. + * + * This library 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. + * + * Or, alternatively, + * + * b) 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 AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada AP806. + */ + +#include <dt-bindings/interrupt-controller/arm-gic.h> + +/dts-v1/; + +/ { + model = "Marvell Armada AP806"; + compatible = "marvell,armada-ap806"; + #address-cells = <2>; + #size-cells = <2>; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + + ap806 { + #address-cells = <2>; + #size-cells = <2>; + compatible = "simple-bus"; + interrupt-parent = <&gic>; + ranges; + + config-space { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges = <0x0 0x0 0xf0000000 0x1000000>; + + gic: interrupt-controller@210000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + interrupt-controller; + interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + reg = <0x210000 0x10000>, + <0x220000 0x20000>, + <0x240000 0x20000>, + <0x260000 0x20000>; + + gic_v2m0: v2m@280000 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0x280000 0x1000>; + arm,msi-base-spi = <160>; + arm,msi-num-spis = <32>; + }; + gic_v2m1: v2m@290000 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0x290000 0x1000>; + arm,msi-base-spi = <192>; + arm,msi-num-spis = <32>; + }; + gic_v2m2: v2m@2a0000 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0x2a0000 0x1000>; + arm,msi-base-spi = <224>; + arm,msi-num-spis = <32>; + }; + gic_v2m3: v2m@2b0000 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0x2b0000 0x1000>; + arm,msi-base-spi = <256>; + arm,msi-num-spis = <32>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>; + }; + + odmi: odmi@300000 { + compatible = "marvell,odmi-controller"; + interrupt-controller; + msi-controller; + marvell,odmi-frames = <4>; + reg = <0x300000 0x4000>, + <0x304000 0x4000>, + <0x308000 0x4000>, + <0x30C000 0x4000>; + marvell,spi-base = <128>, <136>, <144>, <152>; + }; + + xor0@400000 { + compatible = "marvell,mv-xor-v2"; + reg = <0x400000 0x1000>, + <0x410000 0x1000>; + msi-parent = <&gic_v2m0>; + dma-coherent; + }; + + xor1@420000 { + compatible = "marvell,mv-xor-v2"; + reg = <0x420000 0x1000>, + <0x430000 0x1000>; + msi-parent = <&gic_v2m0>; + dma-coherent; + }; + + xor2@440000 { + compatible = "marvell,mv-xor-v2"; + reg = <0x440000 0x1000>, + <0x450000 0x1000>; + msi-parent = <&gic_v2m0>; + dma-coherent; + }; + + xor3@460000 { + compatible = "marvell,mv-xor-v2"; + reg = <0x460000 0x1000>, + <0x470000 0x1000>; + msi-parent = <&gic_v2m0>; + dma-coherent; + }; + + spi0: spi@510600 { + compatible = "marvell,armada-380-spi"; + reg = <0x510600 0x50>; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ringclk 2>; + status = "disabled"; + }; + + i2c0: i2c@511000 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0x511000 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; + timeout-ms = <1000>; + clocks = <&ringclk 2>; + status = "disabled"; + }; + + serial@512000 { + compatible = "snps,dw-apb-uart"; + reg = <0x512000 0x100>; + reg-shift = <2>; + interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; + reg-io-width = <1>; + clocks = <&ringclk 2>; + status = "disabled"; + }; + + serial@512100 { + compatible = "snps,dw-apb-uart"; + reg = <0x512100 0x100>; + reg-shift = <2>; + interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; + reg-io-width = <1>; + clocks = <&ringclk 2>; + status = "disabled"; + + }; + + dfx-server@6f8000 { + compatible = "simple-mfd", "syscon"; + reg = <0x6f8000 0x70000>; + + coreclk: clk@204 { + compatible = "marvell,armada-ap806-core-clock"; + #clock-cells = <1>; + clock-output-names = "ddr", "ring", "cpu"; + }; + + ringclk: clk@250 { + compatible = "marvell,armada-ap806-ring-clock"; + #clock-cells = <1>; + clock-output-names = "ring-0", "ring-2", + "ring-3", "ring-4", + "ring-5"; + clocks = <&coreclk 1>; + }; + }; + }; + }; + +}; + diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts index e427f04a9f45..7453a47b3047 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts @@ -214,6 +214,9 @@ }; &pwrap { + /* Only MT8173 E1 needs USB power domain */ + power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; + pmic: mt6397 { compatible = "mediatek,mt6397"; interrupt-parent = <&pio>; diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index ec135eae31f5..eab7efc2302d 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -14,6 +14,7 @@ #include <dt-bindings/clock/mt8173-clk.h> #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/memory/mt8173-larb-port.h> #include <dt-bindings/phy/phy.h> #include <dt-bindings/power/mt8173-power.h> #include <dt-bindings/reset/mt8173-resets.h> @@ -277,6 +278,22 @@ reg = <0 0x10200620 0 0x20>; }; + iommu: iommu@10205000 { + compatible = "mediatek,mt8173-m4u"; + reg = <0 0x10205000 0 0x1000>; + interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_LOW>; + clocks = <&infracfg CLK_INFRA_M4U>; + clock-names = "bclk"; + mediatek,larbs = <&larb0 &larb1 &larb2 + &larb3 &larb4 &larb5>; + #iommu-cells = <1>; + }; + + efuse: efuse@10206000 { + compatible = "mediatek,mt8173-efuse"; + reg = <0 0x10206000 0 0x1000>; + }; + apmixedsys: clock-controller@10209000 { compatible = "mediatek,mt8173-apmixedsys"; reg = <0 0x10209000 0 0x1000>; @@ -397,6 +414,17 @@ status = "disabled"; }; + nor_flash: spi@1100d000 { + compatible = "mediatek,mt8173-nor"; + reg = <0 0x1100d000 0 0xe0>; + clocks = <&pericfg CLK_PERI_SPI>, + <&topckgen CLK_TOP_SPINFI_IFR_SEL>; + clock-names = "spi", "sf"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + i2c3: i2c@11010000 { compatible = "mediatek,mt8173-i2c"; reg = <0 0x11010000 0 0x70>, @@ -589,29 +617,98 @@ status = "disabled"; }; + larb0: larb@14021000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x14021000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + clocks = <&mmsys CLK_MM_SMI_LARB0>, + <&mmsys CLK_MM_SMI_LARB0>; + clock-names = "apb", "smi"; + }; + + smi_common: smi@14022000 { + compatible = "mediatek,mt8173-smi-common"; + reg = <0 0x14022000 0 0x1000>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + clocks = <&mmsys CLK_MM_SMI_COMMON>, + <&mmsys CLK_MM_SMI_COMMON>; + clock-names = "apb", "smi"; + }; + + larb4: larb@14027000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x14027000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + clocks = <&mmsys CLK_MM_SMI_LARB4>, + <&mmsys CLK_MM_SMI_LARB4>; + clock-names = "apb", "smi"; + }; + imgsys: clock-controller@15000000 { compatible = "mediatek,mt8173-imgsys", "syscon"; reg = <0 0x15000000 0 0x1000>; #clock-cells = <1>; }; + larb2: larb@15001000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x15001000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_ISP>; + clocks = <&imgsys CLK_IMG_LARB2_SMI>, + <&imgsys CLK_IMG_LARB2_SMI>; + clock-names = "apb", "smi"; + }; + vdecsys: clock-controller@16000000 { compatible = "mediatek,mt8173-vdecsys", "syscon"; reg = <0 0x16000000 0 0x1000>; #clock-cells = <1>; }; + larb1: larb@16010000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x16010000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>; + clocks = <&vdecsys CLK_VDEC_CKEN>, + <&vdecsys CLK_VDEC_LARB_CKEN>; + clock-names = "apb", "smi"; + }; + vencsys: clock-controller@18000000 { compatible = "mediatek,mt8173-vencsys", "syscon"; reg = <0 0x18000000 0 0x1000>; #clock-cells = <1>; }; + larb3: larb@18001000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x18001000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_VENC>; + clocks = <&vencsys CLK_VENC_CKE1>, + <&vencsys CLK_VENC_CKE0>; + clock-names = "apb", "smi"; + }; + vencltsys: clock-controller@19000000 { compatible = "mediatek,mt8173-vencltsys", "syscon"; reg = <0 0x19000000 0 0x1000>; #clock-cells = <1>; }; + + larb5: larb@19001000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x19001000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_VENC_LT>; + clocks = <&vencltsys CLK_VENCLT_CKE1>, + <&vencltsys CLK_VENCLT_CKE0>; + clock-names = "apb", "smi"; + }; }; }; diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 8e94af64ee94..fa1f661ccccf 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -1,4 +1,5 @@ dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc.dtb msm8916-mtp.dtb +dtb-$(CONFIG_ARCH_QCOM) += msm8996-mtp.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi index e03c11d9d834..f881437d53c5 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi @@ -33,7 +33,7 @@ pm8916_mpps_leds: pm8916_mpps_leds { pinconf { pins = "mpp2", "mpp3"; - function = PMIC_GPIO_FUNC_NORMAL; + function = "digital"; output-low; }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi index cbeee0bcdf52..ee828a8a8236 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi @@ -10,4 +10,18 @@ output-low; }; }; + + usb_id_default: usb-id-default { + pinmux { + function = "gpio"; + pins = "gpio121"; + }; + + pinconf { + pins = "gpio121"; + drive-strength = <8>; + input-enable; + bias-pull-up; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index db17c5d5689c..205ef89b8ca0 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -24,6 +24,8 @@ i2c0 = &blsp_i2c2; i2c1 = &blsp_i2c6; i2c3 = &blsp_i2c4; + spi0 = &blsp_spi5; + spi1 = &blsp_spi3; }; chosen { @@ -127,9 +129,173 @@ default-state = "off"; }; }; + + sdhci@07824000 { + vmmc-supply = <&pm8916_l8>; + vqmmc-supply = <&pm8916_l5>; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; + status = "okay"; + }; + + usb@78d9000 { + extcon = <&usb_id>, <&usb_id>; + status = "okay"; + }; + + ehci@78d9000 { + status = "okay"; + }; + + phy@78d9000 { + v1p8-supply = <&pm8916_l7>; + v3p3-supply = <&pm8916_l13>; + vddcx-supply = <&pm8916_s1>; + extcon = <&usb_id>, <&usb_id>; + dr_mode = "otg"; + status = "okay"; + switch-gpio = <&pm8916_gpios 4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_sw_sel_pm>; + }; + + lpass@07708000 { + status = "okay"; + }; + }; + + usb2513 { + compatible = "smsc,usb3503"; + reset-gpios = <&pm8916_gpios 3 GPIO_ACTIVE_LOW>; + initial-mode = <1>; + }; + + usb_id: usb-id { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_id_default>; }; }; -&sdhc_1 { - status = "okay"; +&smd_rpm_regulators { + vdd_l1_l2_l3-supply = <&pm8916_s3>; + vdd_l5-supply = <&pm8916_s3>; + vdd_l4_l5_l6-supply = <&pm8916_s4>; + vdd_l7-supply = <&pm8916_s4>; + + s1 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1562000>; + }; + + s3 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1562000>; + }; + + s4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-always-on; + regulator-boot-on; + }; + + l1 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1525000>; + }; + + l2 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1525000>; + }; + + l3 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1525000>; + }; + + l4 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l5 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l6 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l7 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l8 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l9 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l10 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l11 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l12 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l13 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l14 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + /** + * 1.8v required on LS expansion + * for mezzanine boards + */ + l15 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + regulator-always-on; + }; + + l16 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l17 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l18 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi index 955c6f174d4c..10c83e11c272 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi @@ -82,7 +82,7 @@ }; pinconf_cs { pins = "gpio2"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -110,13 +110,13 @@ pins = "gpio6"; }; pinconf { - pins = "gpio4", "gpio5", "gpio6", "gpio7"; + pins = "gpio4", "gpio5", "gpio7"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio6"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -144,13 +144,13 @@ pins = "gpio10"; }; pinconf { - pins = "gpio8", "gpio9", "gpio10", "gpio11"; + pins = "gpio8", "gpio9", "gpio11"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio10"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -178,13 +178,13 @@ pins = "gpio14"; }; pinconf { - pins = "gpio12", "gpio13", "gpio14", "gpio15"; + pins = "gpio12", "gpio13", "gpio15"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio14"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -212,13 +212,13 @@ pins = "gpio18"; }; pinconf { - pins = "gpio16", "gpio17", "gpio18", "gpio19"; + pins = "gpio16", "gpio17", "gpio19"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio18"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -246,13 +246,13 @@ pins = "gpio22"; }; pinconf { - pins = "gpio20", "gpio21", "gpio22", "gpio23"; + pins = "gpio20", "gpio21", "gpio23"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio22"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -504,4 +504,220 @@ }; }; }; + + ext-codec-lines { + ext_codec_lines_act: lines_on { + pinmux { + function = "gpio"; + pins = "gpio67"; + }; + pinconf { + pins = "gpio67"; + drive-strength = <8>; + bias-disable; + output-high; + }; + }; + ext_codec_lines_sus: lines_off { + pinmux { + function = "gpio"; + pins = "gpio67"; + }; + pinconf { + pins = "gpio67"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + cdc-pdm-lines { + cdc_pdm_lines_act: pdm_lines_on { + pinmux { + function = "cdc_pdm0"; + pins = "gpio63", "gpio64", "gpio65", "gpio66", + "gpio67", "gpio68"; + }; + pinconf { + pins = "gpio63", "gpio64", "gpio65", "gpio66", + "gpio67", "gpio68"; + drive-strength = <8>; + bias-pull-none; + }; + }; + cdc_pdm_lines_sus: pdm_lines_off { + pinmux { + function = "cdc_pdm0"; + pins = "gpio63", "gpio64", "gpio65", "gpio66", + "gpio67", "gpio68"; + }; + pinconf { + pins = "gpio63", "gpio64", "gpio65", "gpio66", + "gpio67", "gpio68"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + ext-pri-tlmm-lines { + ext_pri_tlmm_lines_act: ext_pa_on { + pinmux { + function = "pri_mi2s"; + pins = "gpio113", "gpio114", "gpio115", + "gpio116"; + }; + pinconf { + pins = "gpio113", "gpio114", "gpio115", + "gpio116"; + drive-strength = <8>; + bias-pull-none; + }; + }; + + ext_pri_tlmm_lines_sus: ext_pa_off { + pinmux { + function = "pri_mi2s"; + pins = "gpio113", "gpio114", "gpio115", + "gpio116"; + }; + pinconf { + pins = "gpio113", "gpio114", "gpio115", + "gpio116"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + ext-pri-ws-line { + ext_pri_ws_act: ext_pa_on { + pinmux { + function = "pri_mi2s_ws"; + pins = "gpio110"; + }; + pinconf { + pins = "gpio110"; + drive-strength = <8>; + bias-pull-none; + }; + }; + + ext_pri_ws_sus: ext_pa_off { + pinmux { + function = "pri_mi2s_ws"; + pins = "gpio110"; + }; + pinconf { + pins = "gpio110"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + ext-mclk-tlmm-lines { + ext_mclk_tlmm_lines_act: mclk_lines_on { + pinmux { + function = "pri_mi2s"; + pins = "gpio116"; + }; + pinconf { + pins = "gpio116"; + drive-strength = <8>; + bias-pull-none; + }; + }; + ext_mclk_tlmm_lines_sus: mclk_lines_off { + pinmux { + function = "pri_mi2s"; + pins = "gpio116"; + }; + pinconf { + pins = "gpio116"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + /* secondary Mi2S */ + ext-sec-tlmm-lines { + ext_sec_tlmm_lines_act: tlmm_lines_on { + pinmux { + function = "sec_mi2s"; + pins = "gpio112", "gpio117", "gpio118", + "gpio119"; + }; + pinconf { + pins = "gpio112", "gpio117", "gpio118", + "gpio119"; + drive-strength = <8>; + bias-pull-none; + }; + }; + ext_sec_tlmm_lines_sus: tlmm_lines_off { + pinmux { + function = "sec_mi2s"; + pins = "gpio112", "gpio117", "gpio118", + "gpio119"; + }; + pinconf { + pins = "gpio112", "gpio117", "gpio118", + "gpio119"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + cdc-dmic-lines { + cdc_dmic_lines_act: dmic_lines_on { + pinmux_dmic0_clk { + function = "dmic0_clk"; + pins = "gpio0"; + }; + pinmux_dmic0_data { + function = "dmic0_data"; + pins = "gpio1"; + }; + pinconf { + pins = "gpio0", "gpio1"; + drive-strength = <8>; + }; + }; + cdc_dmic_lines_sus: dmic_lines_off { + pinconf { + pins = "gpio0", "gpio1"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + cross-conn-det { + cross_conn_det_act: lines_on { + pinmux { + function = "gpio"; + pins = "gpio120"; + }; + pinconf { + pins = "gpio120"; + drive-strength = <8>; + output-low; + bias-pull-down; + }; + }; + cross_conn_det_sus: lines_off { + pinmux { + function = "gpio"; + pins = "gpio120"; + }; + pinconf { + pins = "gpio120"; + drive-strength = <2>; + bias-disable; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 915321479998..96812007850e 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -61,24 +61,33 @@ device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x0>; + next-level-cache = <&L2_0>; }; CPU1: cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x1>; + next-level-cache = <&L2_0>; }; CPU2: cpu@2 { device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x2>; + next-level-cache = <&L2_0>; }; CPU3: cpu@3 { device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x3>; + next-level-cache = <&L2_0>; + }; + + L2_0: l2-cache { + compatible = "cache"; + cache-level = <2>; }; }; @@ -134,7 +143,7 @@ #interrupt-cells = <2>; }; - gcc: qcom,gcc@1800000 { + gcc: clock-controller@1800000 { compatible = "qcom,gcc-msm8916"; #clock-cells = <1>; #reset-cells = <1>; @@ -343,6 +352,32 @@ status = "disabled"; }; + lpass: lpass@07708000 { + status = "disabled"; + compatible = "qcom,lpass-cpu-apq8016"; + clocks = <&gcc GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK>, + <&gcc GCC_ULTAUDIO_PCNOC_MPORT_CLK>, + <&gcc GCC_ULTAUDIO_PCNOC_SWAY_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK>; + + clock-names = "ahbix-clk", + "pcnoc-mport-clk", + "pcnoc-sway-clk", + "mi2s-bit-clk0", + "mi2s-bit-clk1", + "mi2s-bit-clk2", + "mi2s-bit-clk3"; + #sound-dai-cells = <1>; + + interrupts = <0 160 0>; + interrupt-names = "lpass-irq-lpaif"; + reg = <0x07708000 0x10000>; + reg-names = "lpass-lpaif"; + }; + sdhc_1: sdhci@07824000 { compatible = "qcom,sdhci-msm-v4"; reg = <0x07824900 0x11c>, <0x07824000 0x800>; @@ -395,10 +430,11 @@ interrupts = <GIC_SPI 134 IRQ_TYPE_EDGE_BOTH>, <GIC_SPI 140 IRQ_TYPE_EDGE_RISING>; - qcom,vdd-levels = <1 5 7>; + qcom,vdd-levels = <500000 1000000 1320000>; qcom,phy-init-sequence = <0x44 0x6B 0x24 0x13>; dr_mode = "peripheral"; qcom,otg-control = <2>; // PMIC + qcom,manual-pullup; clocks = <&gcc GCC_USB_HS_AHB_CLK>, <&gcc GCC_USB_HS_SYSTEM_CLK>, @@ -515,11 +551,15 @@ compatible = "qcom,rpm-msm8916"; qcom,smd-channels = "rpm_requests"; - pm8916-regulators { + rpmcc: qcom,rpmcc { + compatible = "qcom,rpmcc-msm8916", "qcom,rpmcc"; + #clock-cells = <1>; + }; + + smd_rpm_regulators: pm8916-regulators { compatible = "qcom,rpm-pm8916-regulators"; pm8916_s1: s1 {}; - pm8916_s2: s2 {}; pm8916_s3: s3 {}; pm8916_s4: s4 {}; diff --git a/arch/arm64/boot/dts/qcom/msm8996-mtp.dts b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts new file mode 100644 index 000000000000..619af44a595d --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "msm8996-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8996 MTP"; + compatible = "qcom,msm8996-mtp"; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi new file mode 100644 index 000000000000..9bab5c011c07 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msm8996.dtsi" + +/ { + aliases { + serial0 = &blsp2_uart1; + }; + + chosen { + stdout-path = "serial0"; + }; + + soc { + serial@75b0000 { + status = "okay"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi new file mode 100644 index 000000000000..0506fb808c56 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -0,0 +1,269 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/qcom,gcc-msm8996.h> +#include <dt-bindings/clock/qcom,mmcc-msm8996.h> + +/ { + model = "Qualcomm Technologies, Inc. MSM8996"; + + interrupt-parent = <&intc>; + + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + memory { + device_type = "memory"; + /* We expect the bootloader to fill in the reg */ + reg = <0 0 0 0>; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + CPU0: cpu@0 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x0>; + enable-method = "psci"; + next-level-cache = <&L2_0>; + L2_0: l2-cache { + compatible = "cache"; + cache-level = <2>; + }; + }; + + CPU1: cpu@1 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x1>; + enable-method = "psci"; + next-level-cache = <&L2_0>; + }; + + CPU2: cpu@100 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x100>; + enable-method = "psci"; + next-level-cache = <&L2_1>; + L2_1: l2-cache { + compatible = "cache"; + cache-level = <2>; + }; + }; + + CPU3: cpu@101 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x101>; + enable-method = "psci"; + next-level-cache = <&L2_1>; + }; + + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + + core1 { + cpu = <&CPU1>; + }; + }; + + cluster1 { + core0 { + cpu = <&CPU2>; + }; + + core1 { + cpu = <&CPU3>; + }; + }; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + }; + + clocks { + xo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + clock-output-names = "xo_board"; + }; + + sleep_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32764>; + clock-output-names = "sleep_clk"; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + soc: soc { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0xffffffff>; + compatible = "simple-bus"; + + intc: interrupt-controller@9bc0000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + interrupt-controller; + #redistributor-regions = <1>; + redistributor-stride = <0x0 0x40000>; + reg = <0x09bc0000 0x10000>, + <0x09c00000 0x100000>; + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + }; + + gcc: clock-controller@300000 { + compatible = "qcom,gcc-msm8996"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + reg = <0x300000 0x90000>; + }; + + blsp2_uart1: serial@75b0000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0x75b0000 0x1000>; + interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>, + <&gcc GCC_BLSP2_AHB_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + }; + + pinctrl@1010000 { + compatible = "qcom,msm8996-pinctrl"; + reg = <0x01010000 0x300000>; + interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + timer@09840000 { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "arm,armv7-timer-mem"; + reg = <0x09840000 0x1000>; + clock-frequency = <19200000>; + + frame@9850000 { + frame-number = <0>; + interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x09850000 0x1000>, + <0x09860000 0x1000>; + }; + + frame@9870000 { + frame-number = <1>; + interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x09870000 0x1000>; + status = "disabled"; + }; + + frame@9880000 { + frame-number = <2>; + interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x09880000 0x1000>; + status = "disabled"; + }; + + frame@9890000 { + frame-number = <3>; + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x09890000 0x1000>; + status = "disabled"; + }; + + frame@98a0000 { + frame-number = <4>; + interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x098a0000 0x1000>; + status = "disabled"; + }; + + frame@98b0000 { + frame-number = <5>; + interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x098b0000 0x1000>; + status = "disabled"; + }; + + frame@98c0000 { + frame-number = <6>; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x098c0000 0x1000>; + status = "disabled"; + }; + }; + + spmi_bus: qcom,spmi@400f000 { + compatible = "qcom,spmi-pmic-arb"; + reg = <0x400f000 0x1000>, + <0x4400000 0x800000>, + <0x4c00000 0x800000>, + <0x5800000 0x200000>, + <0x400a000 0x002100>; + reg-names = "core", "chnls", "obsrvr", "intr", "cnfg"; + interrupt-names = "periph_irq"; + interrupts = <GIC_SPI 326 IRQ_TYPE_NONE>; + qcom,ee = <0>; + qcom,channel = <0>; + #address-cells = <2>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <4>; + }; + + mmcc: clock-controller@8c0000 { + compatible = "qcom,mmcc-msm8996"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + reg = <0x8c0000 0x40000>; + assigned-clocks = <&mmcc MMPLL9_PLL>, + <&mmcc MMPLL1_PLL>, + <&mmcc MMPLL3_PLL>, + <&mmcc MMPLL4_PLL>, + <&mmcc MMPLL5_PLL>; + assigned-clock-rates = <624000000>, + <810000000>, + <980000000>, + <960000000>, + <825000000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pm8004.dtsi b/arch/arm64/boot/dts/qcom/pm8004.dtsi new file mode 100644 index 000000000000..ef2207afa86b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pm8004.dtsi @@ -0,0 +1,19 @@ +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/spmi/spmi.h> + +&spmi_bus { + + pmic@4 { + compatible = "qcom,pm8004", "qcom,spmi-pmic"; + reg = <0x4 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; + + pmic@5 { + compatible = "qcom,pm8004", "qcom,spmi-pmic"; + reg = <0x5 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi index 37432451ee4c..f71679b15d54 100644 --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi @@ -12,7 +12,7 @@ rtc@6000 { compatible = "qcom,pm8941-rtc"; - reg = <0x6000 0x6100>; + reg = <0x6000>; reg-names = "rtc", "alarm"; interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; }; @@ -27,7 +27,7 @@ pm8916_gpios: gpios@c000 { compatible = "qcom,pm8916-gpio"; - reg = <0xc000 0x400>; + reg = <0xc000>; gpio-controller; #gpio-cells = <2>; interrupts = <0 0xc0 0 IRQ_TYPE_NONE>, @@ -38,7 +38,7 @@ pm8916_mpps: mpps@a000 { compatible = "qcom,pm8916-mpp"; - reg = <0xa000 0x400>; + reg = <0xa000>; gpio-controller; #gpio-cells = <2>; interrupts = <0 0xa0 0 IRQ_TYPE_NONE>, @@ -49,7 +49,7 @@ pm8916_temp: temp-alarm@2400 { compatible = "qcom,spmi-temp-alarm"; - reg = <0x2400 0x100>; + reg = <0x2400>; interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; io-channels = <&pm8916_vadc VADC_DIE_TEMP>; io-channel-names = "thermal"; @@ -58,7 +58,7 @@ pm8916_vadc: vadc@3100 { compatible = "qcom,spmi-vadc"; - reg = <0x3100 0x100>; + reg = <0x3100>; interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/qcom/pm8994.dtsi b/arch/arm64/boot/dts/qcom/pm8994.dtsi new file mode 100644 index 000000000000..1222d2e904f6 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pm8994.dtsi @@ -0,0 +1,62 @@ +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/spmi/spmi.h> + +&spmi_bus { + + pmic@0 { + compatible = "qcom,pm8994", "qcom,spmi-pmic"; + reg = <0x0 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pm8994_gpios: gpios@c000 { + compatible = "qcom,pm8994-gpio"; + reg = <0xc000>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <0 0xc0 0 IRQ_TYPE_NONE>, + <0 0xc1 0 IRQ_TYPE_NONE>, + <0 0xc2 0 IRQ_TYPE_NONE>, + <0 0xc3 0 IRQ_TYPE_NONE>, + <0 0xc4 0 IRQ_TYPE_NONE>, + <0 0xc5 0 IRQ_TYPE_NONE>, + <0 0xc6 0 IRQ_TYPE_NONE>, + <0 0xc7 0 IRQ_TYPE_NONE>, + <0 0xc8 0 IRQ_TYPE_NONE>, + <0 0xc9 0 IRQ_TYPE_NONE>, + <0 0xca 0 IRQ_TYPE_NONE>, + <0 0xcb 0 IRQ_TYPE_NONE>, + <0 0xcc 0 IRQ_TYPE_NONE>, + <0 0xcd 0 IRQ_TYPE_NONE>, + <0 0xce 0 IRQ_TYPE_NONE>, + <0 0xd0 0 IRQ_TYPE_NONE>, + <0 0xd1 0 IRQ_TYPE_NONE>, + <0 0xd2 0 IRQ_TYPE_NONE>, + <0 0xd3 0 IRQ_TYPE_NONE>, + <0 0xd4 0 IRQ_TYPE_NONE>, + <0 0xd5 0 IRQ_TYPE_NONE>; + }; + + pm8994_mpps: mpps@a000 { + compatible = "qcom,pm8994-mpp"; + reg = <0xa000>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <0 0xa0 0 IRQ_TYPE_NONE>, + <0 0xa1 0 IRQ_TYPE_NONE>, + <0 0xa2 0 IRQ_TYPE_NONE>, + <0 0xa3 0 IRQ_TYPE_NONE>, + <0 0xa4 0 IRQ_TYPE_NONE>, + <0 0xa5 0 IRQ_TYPE_NONE>, + <0 0xa6 0 IRQ_TYPE_NONE>, + <0 0xa7 0 IRQ_TYPE_NONE>; + }; + }; + + pmic@1 { + compatible = "qcom,pm8994", "qcom,spmi-pmic"; + reg = <0x1 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pmi8994.dtsi b/arch/arm64/boot/dts/qcom/pmi8994.dtsi new file mode 100644 index 000000000000..d3879a4e8076 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pmi8994.dtsi @@ -0,0 +1,19 @@ +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/spmi/spmi.h> + +&spmi_bus { + + pmic@2 { + compatible = "qcom,pmi8994", "qcom,spmi-pmic"; + reg = <0x2 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; + + pmic@3 { + compatible = "qcom,pmi8994", "qcom,spmi-pmic"; + reg = <0x3 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts index 265d12ff6022..b992b1a3d956 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts @@ -33,6 +33,7 @@ /dts-v1/; #include "r8a7795.dtsi" +#include <dt-bindings/gpio/gpio.h> / { model = "Renesas Salvator-X board based on r8a7795"; @@ -61,6 +62,54 @@ clock-frequency = <24576000>; }; + vcc_sdhi0: regulator@1 { + compatible = "regulator-fixed"; + + regulator-name = "SDHI0 Vcc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vccq_sdhi0: regulator@2 { + compatible = "regulator-gpio"; + + regulator-name = "SDHI0 VccQ"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; + gpios-states = <1>; + states = <3300000 1 + 1800000 0>; + }; + + vcc_sdhi3: regulator@3 { + compatible = "regulator-fixed"; + + regulator-name = "SDHI3 Vcc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&gpio3 15 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vccq_sdhi3: regulator@4 { + compatible = "regulator-gpio"; + + regulator-name = "SDHI3 VccQ"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>; + gpios-states = <1>; + states = <3300000 1 + 1800000 0>; + }; + audio_clkout: audio_clkout { /* * This is same as <&rcar_sound 0> @@ -93,6 +142,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + scif1_pins: scif1 { renesas,groups = "scif1_data_a", "scif1_ctrl"; renesas,function = "scif1"; @@ -101,6 +153,10 @@ renesas,groups = "scif2_data_a"; renesas,function = "scif2"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk_a"; + renesas,function = "scif_clk"; + }; i2c2_pins: i2c2 { renesas,groups = "i2c2_a"; @@ -112,6 +168,16 @@ renesas,function = "avb"; }; + sdhi0_pins: sd0 { + renesas,groups = "sdhi0_data4", "sdhi0_ctrl"; + renesas,function = "sdhi0"; + }; + + sdhi3_pins: sd3 { + renesas,groups = "sdhi3_data4", "sdhi3_ctrl"; + renesas,function = "sdhi3"; + }; + sound_pins: sound { renesas,groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a"; renesas,function = "ssi"; @@ -122,6 +188,16 @@ "audio_clkout_a", "audio_clkout3_a"; renesas,function = "audio_clk"; }; + + usb1_pins: usb1 { + renesas,groups = "usb1"; + renesas,function = "usb1"; + }; + + usb2_pins: usb2 { + renesas,groups = "usb2"; + renesas,function = "usb2"; + }; }; &scif1 { @@ -138,6 +214,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &i2c2 { pinctrl-0 = <&i2c2_pins>; pinctrl-names = "default"; @@ -216,6 +297,30 @@ status = "okay"; }; +&sdhi0 { + pinctrl-0 = <&sdhi0_pins>; + pinctrl-names = "default"; + + vmmc-supply = <&vcc_sdhi0>; + vqmmc-supply = <&vccq_sdhi0>; + cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>; + bus-width = <4>; + status = "okay"; +}; + +&sdhi3 { + pinctrl-0 = <&sdhi3_pins>; + pinctrl-names = "default"; + + vmmc-supply = <&vcc_sdhi3>; + vqmmc-supply = <&vccq_sdhi3>; + cd-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>; + bus-width = <4>; + status = "okay"; +}; + &ssi1 { shared-pin; }; @@ -249,3 +354,37 @@ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; }; }; + +&xhci0 { + status = "okay"; +}; + +&usb2_phy1 { + pinctrl-0 = <&usb1_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&usb2_phy2 { + pinctrl-0 = <&usb2_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&ehci2 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&ohci2 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index bb353cde1253..a7315ebe3883 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -39,6 +39,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x0>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; @@ -46,22 +47,37 @@ compatible = "arm,cortex-a57","arm,armv8"; reg = <0x1>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; a57_2: cpu@2 { compatible = "arm,cortex-a57","arm,armv8"; reg = <0x2>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; a57_3: cpu@3 { compatible = "arm,cortex-a57","arm,armv8"; reg = <0x3>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; }; + L2_CA57: cache-controller@0 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + }; + + L2_CA53: cache-controller@1 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + }; + extal_clk: extal { compatible = "fixed-clock"; #clock-cells = <0>; @@ -99,6 +115,14 @@ clock-frequency = <0>; }; + /* External SCIF clock - to be overridden by boards that provide it */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + status = "disabled"; + }; + soc { compatible = "simple-bus"; interrupt-parent = <&gic>; @@ -113,7 +137,9 @@ #address-cells = <0>; interrupt-controller; reg = <0x0 0xf1010000 0 0x1000>, - <0x0 0xf1020000 0 0x2000>; + <0x0 0xf1020000 0 0x2000>, + <0x0 0xf1040000 0 0x20000>, + <0x0 0xf1060000 0 0x2000>; interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; }; @@ -230,8 +256,8 @@ power-domains = <&cpg>; }; - pmu { - compatible = "arm,armv8-pmuv3"; + pmu_a57 { + compatible = "arm,cortex-a57-pmu"; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>, @@ -266,23 +292,23 @@ audma0: dma-controller@ec700000 { compatible = "renesas,rcar-dmac"; reg = <0 0xec700000 0 0x10000>; - interrupts = <0 350 IRQ_TYPE_LEVEL_HIGH - 0 320 IRQ_TYPE_LEVEL_HIGH - 0 321 IRQ_TYPE_LEVEL_HIGH - 0 322 IRQ_TYPE_LEVEL_HIGH - 0 323 IRQ_TYPE_LEVEL_HIGH - 0 324 IRQ_TYPE_LEVEL_HIGH - 0 325 IRQ_TYPE_LEVEL_HIGH - 0 326 IRQ_TYPE_LEVEL_HIGH - 0 327 IRQ_TYPE_LEVEL_HIGH - 0 328 IRQ_TYPE_LEVEL_HIGH - 0 329 IRQ_TYPE_LEVEL_HIGH - 0 330 IRQ_TYPE_LEVEL_HIGH - 0 331 IRQ_TYPE_LEVEL_HIGH - 0 332 IRQ_TYPE_LEVEL_HIGH - 0 333 IRQ_TYPE_LEVEL_HIGH - 0 334 IRQ_TYPE_LEVEL_HIGH - 0 335 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -298,23 +324,23 @@ audma1: dma-controller@ec720000 { compatible = "renesas,rcar-dmac"; reg = <0 0xec720000 0 0x10000>; - interrupts = <0 351 IRQ_TYPE_LEVEL_HIGH - 0 336 IRQ_TYPE_LEVEL_HIGH - 0 337 IRQ_TYPE_LEVEL_HIGH - 0 338 IRQ_TYPE_LEVEL_HIGH - 0 339 IRQ_TYPE_LEVEL_HIGH - 0 340 IRQ_TYPE_LEVEL_HIGH - 0 341 IRQ_TYPE_LEVEL_HIGH - 0 342 IRQ_TYPE_LEVEL_HIGH - 0 343 IRQ_TYPE_LEVEL_HIGH - 0 344 IRQ_TYPE_LEVEL_HIGH - 0 345 IRQ_TYPE_LEVEL_HIGH - 0 346 IRQ_TYPE_LEVEL_HIGH - 0 347 IRQ_TYPE_LEVEL_HIGH - 0 348 IRQ_TYPE_LEVEL_HIGH - 0 349 IRQ_TYPE_LEVEL_HIGH - 0 382 IRQ_TYPE_LEVEL_HIGH - 0 383 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -332,20 +358,123 @@ reg = <0 0xe6060000 0 0x50c>; }; + intc_ex: interrupt-controller@e61c0000 { + compatible = "renesas,intc-ex-r8a7795", "renesas,irqc"; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0 0xe61c0000 0 0x200>; + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 407>; + power-domains = <&cpg>; + }; + dmac0: dma-controller@e6700000 { - /* Empty node for now */ + compatible = "renesas,dmac-r8a7795", + "renesas,rcar-dmac"; + reg = <0 0xe6700000 0 0x10000>; + interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 219>; + clock-names = "fck"; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <16>; }; dmac1: dma-controller@e7300000 { - /* Empty node for now */ + compatible = "renesas,dmac-r8a7795", + "renesas,rcar-dmac"; + reg = <0 0xe7300000 0 0x10000>; + interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 218>; + clock-names = "fck"; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <16>; }; dmac2: dma-controller@e7310000 { - /* Empty node for now */ + compatible = "renesas,dmac-r8a7795", + "renesas,rcar-dmac"; + reg = <0 0xe7310000 0 0x10000>; + interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 217>; + clock-names = "fck"; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <16>; }; avb: ethernet@e6800000 { - compatible = "renesas,etheravb-r8a7795"; + compatible = "renesas,etheravb-r8a7795", + "renesas,etheravb-rcar-gen3"; reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>; interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>, @@ -387,11 +516,15 @@ }; hscif0: serial@e6540000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe6540000 0 96>; interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 520>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 520>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x31>, <&dmac1 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -399,11 +532,15 @@ }; hscif1: serial@e6550000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe6550000 0 96>; interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 519>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 519>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x33>, <&dmac1 0x32>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -411,11 +548,15 @@ }; hscif2: serial@e6560000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe6560000 0 96>; interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 518>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 518>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x35>, <&dmac1 0x34>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -423,11 +564,15 @@ }; hscif3: serial@e66a0000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe66a0000 0 96>; interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 517>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 517>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x37>, <&dmac0 0x36>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -435,11 +580,15 @@ }; hscif4: serial@e66b0000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe66b0000 0 96>; interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 516>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 516>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x38>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -447,11 +596,14 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e60000 0 64>; interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 207>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 207>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x51>, <&dmac1 0x50>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -459,11 +611,14 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e68000 0 64>; interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 206>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 206>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x53>, <&dmac1 0x52>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -471,11 +626,14 @@ }; scif2: serial@e6e88000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e88000 0 64>; interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 310>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 310>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x13>, <&dmac1 0x12>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -483,11 +641,14 @@ }; scif3: serial@e6c50000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6c50000 0 64>; interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 204>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 204>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x57>, <&dmac0 0x56>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -495,11 +656,14 @@ }; scif4: serial@e6c40000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6c40000 0 64>; interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 203>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 203>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x59>, <&dmac0 0x58>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -507,11 +671,14 @@ }; scif5: serial@e6f30000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6f30000 0 64>; interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&cpg CPG_MOD 202>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 202>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x5b>, <&dmac1 0x5a>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -663,52 +830,52 @@ rcar_sound,src { src0: src@0 { - interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x85>, <&audma1 0x9a>; dma-names = "rx", "tx"; }; src1: src@1 { - interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x87>, <&audma1 0x9c>; dma-names = "rx", "tx"; }; src2: src@2 { - interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x89>, <&audma1 0x9e>; dma-names = "rx", "tx"; }; src3: src@3 { - interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x8b>, <&audma1 0xa0>; dma-names = "rx", "tx"; }; src4: src@4 { - interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x8d>, <&audma1 0xb0>; dma-names = "rx", "tx"; }; src5: src@5 { - interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x8f>, <&audma1 0xb2>; dma-names = "rx", "tx"; }; src6: src@6 { - interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x91>, <&audma1 0xb4>; dma-names = "rx", "tx"; }; src7: src@7 { - interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x93>, <&audma1 0xb6>; dma-names = "rx", "tx"; }; src8: src@8 { - interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x95>, <&audma1 0xb8>; dma-names = "rx", "tx"; }; src9: src@9 { - interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x97>, <&audma1 0xba>; dma-names = "rx", "tx"; }; @@ -716,52 +883,52 @@ rcar_sound,ssi { ssi0: ssi@0 { - interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi1: ssi@1 { - interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi2: ssi@2 { - interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi3: ssi@3 { - interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi4: ssi@4 { - interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi5: ssi@5 { - interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi6: ssi@6 { - interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi7: ssi@7 { - interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi8: ssi@8 { - interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi9: ssi@9 { - interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; dma-names = "rx", "tx", "rxu", "txu"; }; @@ -775,5 +942,181 @@ clocks = <&cpg CPG_MOD 815>; status = "disabled"; }; + + xhci0: usb@ee000000 { + compatible = "renesas,xhci-r8a7795"; + reg = <0 0xee000000 0 0xc00>; + interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 328>; + power-domains = <&cpg>; + status = "disabled"; + }; + + xhci1: usb@ee0400000 { + compatible = "renesas,xhci-r8a7795"; + reg = <0 0xee040000 0 0xc00>; + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 327>; + power-domains = <&cpg>; + status = "disabled"; + }; + + usb_dmac0: dma-controller@e65a0000 { + compatible = "renesas,r8a7795-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65a0000 0 0x100>; + interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 330>; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <2>; + }; + + usb_dmac1: dma-controller@e65b0000 { + compatible = "renesas,r8a7795-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65b0000 0 0x100>; + interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH + GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 331>; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <2>; + }; + + sdhi0: sd@ee100000 { + compatible = "renesas,sdhi-r8a7795"; + reg = <0 0xee100000 0 0x2000>; + interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 314>; + power-domains = <&cpg>; + status = "disabled"; + }; + + sdhi1: sd@ee120000 { + compatible = "renesas,sdhi-r8a7795"; + reg = <0 0xee120000 0 0x2000>; + interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 313>; + power-domains = <&cpg>; + status = "disabled"; + }; + + sdhi2: sd@ee140000 { + compatible = "renesas,sdhi-r8a7795"; + reg = <0 0xee140000 0 0x2000>; + interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 312>; + power-domains = <&cpg>; + cap-mmc-highspeed; + status = "disabled"; + }; + + sdhi3: sd@ee160000 { + compatible = "renesas,sdhi-r8a7795"; + reg = <0 0xee160000 0 0x2000>; + interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 311>; + power-domains = <&cpg>; + cap-mmc-highspeed; + status = "disabled"; + }; + + usb2_phy0: usb-phy@ee080200 { + compatible = "renesas,usb2-phy-r8a7795"; + reg = <0 0xee080200 0 0x700>; + interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 703>; + power-domains = <&cpg>; + #phy-cells = <0>; + status = "disabled"; + }; + + usb2_phy1: usb-phy@ee0a0200 { + compatible = "renesas,usb2-phy-r8a7795"; + reg = <0 0xee0a0200 0 0x700>; + clocks = <&cpg CPG_MOD 702>; + power-domains = <&cpg>; + #phy-cells = <0>; + status = "disabled"; + }; + + usb2_phy2: usb-phy@ee0c0200 { + compatible = "renesas,usb2-phy-r8a7795"; + reg = <0 0xee0c0200 0 0x700>; + clocks = <&cpg CPG_MOD 701>; + power-domains = <&cpg>; + #phy-cells = <0>; + status = "disabled"; + }; + + ehci0: usb@ee080100 { + compatible = "generic-ehci"; + reg = <0 0xee080100 0 0x100>; + interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 703>; + phys = <&usb2_phy0>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ehci1: usb@ee0a0100 { + compatible = "generic-ehci"; + reg = <0 0xee0a0100 0 0x100>; + interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 702>; + phys = <&usb2_phy1>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ehci2: usb@ee0c0100 { + compatible = "generic-ehci"; + reg = <0 0xee0c0100 0 0x100>; + interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 701>; + phys = <&usb2_phy2>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ohci0: usb@ee080000 { + compatible = "generic-ohci"; + reg = <0 0xee080000 0 0x100>; + interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 703>; + phys = <&usb2_phy0>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ohci1: usb@ee0a0000 { + compatible = "generic-ohci"; + reg = <0 0xee0a0000 0 0x100>; + interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 702>; + phys = <&usb2_phy1>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ohci2: usb@ee0c0000 { + compatible = "generic-ohci"; + reg = <0 0xee0c0000 0 0x100>; + interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 701>; + phys = <&usb2_phy2>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi index 8c219ccf67a3..6e27b22704df 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi @@ -111,7 +111,7 @@ pinctrl-0 = <&pwr_key>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts index 104cbee762bb..1f2b642e794a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts @@ -71,7 +71,7 @@ pinctrl-0 = <&pwr_key>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi index 122777b1441e..49d119103e31 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi @@ -231,8 +231,9 @@ compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff0c0000 0x0 0x4000>; clock-freq-min-max = <400000 150000000>; - clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; - clock-names = "biu", "ciu"; + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, + <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; @@ -254,8 +255,9 @@ compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff0f0000 0x0 0x4000>; clock-freq-min-max = <400000 150000000>; - clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>; - clock-names = "biu", "ciu"; + clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, + <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; diff --git a/arch/arm64/boot/dts/socionext/Makefile b/arch/arm64/boot/dts/socionext/Makefile index 8d727717c24e..299b67ec4d44 100644 --- a/arch/arm64/boot/dts/socionext/Makefile +++ b/arch/arm64/boot/dts/socionext/Makefile @@ -1,4 +1,4 @@ -dtb-$(CONFIG_ARCH_UNIPHIER) += uniphier-ph1-ld10-ref.dtb +dtb-$(CONFIG_ARCH_UNIPHIER) += uniphier-ph1-ld20-ref.dtb always := $(dtb-y) clean-files := *.dtb diff --git a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20-ref.dts index 3e533178ba2f..727ae5f8c4e7 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10-ref.dts +++ b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20-ref.dts @@ -1,5 +1,5 @@ /* - * Device Tree Source for UniPhier PH1-LD10 Reference Board + * Device Tree Source for UniPhier PH1-LD20 Reference Board * * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> * @@ -43,12 +43,12 @@ */ /dts-v1/; -/include/ "uniphier-ph1-ld10.dtsi" +/include/ "uniphier-ph1-ld20.dtsi" /include/ "uniphier-support-card.dtsi" / { - model = "UniPhier PH1-LD10 Reference Board"; - compatible = "socionext,ph1-ld10-ref", "socionext,ph1-ld10"; + model = "UniPhier PH1-LD20 Reference Board"; + compatible = "socionext,ph1-ld20-ref", "socionext,ph1-ld20"; memory { device_type = "memory"; @@ -74,14 +74,6 @@ }; }; -&extbus { - ranges = <1 0x00000000 0x42000000 0x02000000>; -}; - -&support_card { - ranges = <0x00000000 1 0x01f00000 0x00100000>; -}; - ðsc { interrupts = <0 48 4>; }; diff --git a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi index 0296af9cbbdb..e682a3f52791 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi @@ -1,5 +1,5 @@ /* - * Device Tree Source for UniPhier PH1-LD10 SoC + * Device Tree Source for UniPhier PH1-LD20 SoC * * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> * @@ -43,7 +43,7 @@ */ / { - compatible = "socionext,ph1-ld10"; + compatible = "socionext,ph1-ld20"; #address-cells = <2>; #size-cells = <2>; interrupt-parent = <&gic>; @@ -133,12 +133,6 @@ #size-cells = <1>; ranges = <0 0 0 0xffffffff>; - extbus: extbus { - compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - }; - serial0: serial@54006800 { compatible = "socionext,uniphier-uart"; status = "disabled"; @@ -261,8 +255,21 @@ clock-frequency = <400000>; }; + system_bus: system-bus@58c00000 { + compatible = "socionext,uniphier-system-bus"; + status = "disabled"; + reg = <0x58c00000 0x400>; + #address-cells = <2>; + #size-cells = <1>; + }; + + smpctrl@59800000 { + compatible = "socionext,uniphier-smpctrl"; + reg = <0x59801000 0x400>; + }; + pinctrl: pinctrl@5f801000 { - compatible = "socionext,ph1-ld10-pinctrl", "syscon"; + compatible = "socionext,ph1-ld20-pinctrl", "syscon"; reg = <0x5f801000 0xe00>; }; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi new file mode 100644 index 000000000000..cdc6a437dcc7 --- /dev/null +++ b/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi @@ -0,0 +1,88 @@ +/* + * clock specification for Xilinx ZynqMP ep108 development board + * + * (C) Copyright 2015, Xilinx, Inc. + * + * Michal Simek <michal.simek@xilinx.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. + */ + +&amba { + misc_clk: misc_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + i2c_clk: i2c_clk { + compatible = "fixed-clock"; + #clock-cells = <0x0>; + clock-frequency = <111111111>; + }; + + sata_clk: sata_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <75000000>; + }; +}; + +&can0 { + clocks = <&misc_clk &misc_clk>; +}; + +&gem0 { + clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>; +}; + +&gpio { + clocks = <&misc_clk>; +}; + +&i2c0 { + clocks = <&i2c_clk>; +}; + +&i2c1 { + clocks = <&i2c_clk>; +}; + +&sata { + clocks = <&sata_clk>; +}; + +&sdhci0 { + clocks = <&misc_clk>, <&misc_clk>; +}; + +&sdhci1 { + clocks = <&misc_clk>, <&misc_clk>; +}; + +&spi0 { + clocks = <&misc_clk &misc_clk>; +}; + +&spi1 { + clocks = <&misc_clk &misc_clk>; +}; + +&uart0 { + clocks = <&misc_clk &misc_clk>; +}; + +&usb0 { + clocks = <&misc_clk>, <&misc_clk>; +}; + +&usb1 { + clocks = <&misc_clk>, <&misc_clk>; +}; + +&watchdog0 { + clocks= <&misc_clk>; +}; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts index ce5d848251fa..acb0527fdc4a 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts @@ -14,6 +14,7 @@ /dts-v1/; /include/ "zynqmp.dtsi" +/include/ "zynqmp-ep108-clk.dtsi" / { model = "ZynqMP EP108"; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index 200fb588d0f5..e595f22e7e4b 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -90,7 +90,7 @@ }; }; - amba { + amba: amba { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <1>; @@ -99,7 +99,6 @@ can0: can@ff060000 { compatible = "xlnx,zynq-can-1.0"; status = "disabled"; - clocks = <&misc_clk &misc_clk>; clock-names = "can_clk", "pclk"; reg = <0x0 0xff060000 0x1000>; interrupts = <0 23 4>; @@ -111,7 +110,6 @@ can1: can@ff070000 { compatible = "xlnx,zynq-can-1.0"; status = "disabled"; - clocks = <&misc_clk &misc_clk>; clock-names = "can_clk", "pclk"; reg = <0x0 0xff070000 0x1000>; interrupts = <0 24 4>; @@ -120,24 +118,6 @@ rx-fifo-depth = <0x40>; }; - misc_clk: misc_clk { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <25000000>; - }; - - gpio: gpio@ff0a0000 { - compatible = "xlnx,zynqmp-gpio-1.0"; - status = "disabled"; - #gpio-cells = <0x2>; - clocks = <&misc_clk>; - interrupt-parent = <&gic>; - interrupts = <0 16 4>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x0 0xff0a0000 0x1000>; - }; - gem0: ethernet@ff0b0000 { compatible = "cdns,gem"; status = "disabled"; @@ -145,7 +125,6 @@ interrupts = <0 57 4>, <0 57 4>; reg = <0x0 0xff0b0000 0x1000>; clock-names = "pclk", "hclk", "tx_clk"; - clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>; #address-cells = <1>; #size-cells = <0>; }; @@ -157,7 +136,6 @@ interrupts = <0 59 4>, <0 59 4>; reg = <0x0 0xff0c0000 0x1000>; clock-names = "pclk", "hclk", "tx_clk"; - clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>; #address-cells = <1>; #size-cells = <0>; }; @@ -169,7 +147,6 @@ interrupts = <0 61 4>, <0 61 4>; reg = <0x0 0xff0d0000 0x1000>; clock-names = "pclk", "hclk", "tx_clk"; - clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>; #address-cells = <1>; #size-cells = <0>; }; @@ -181,15 +158,19 @@ interrupts = <0 63 4>, <0 63 4>; reg = <0x0 0xff0e0000 0x1000>; clock-names = "pclk", "hclk", "tx_clk"; - clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>; #address-cells = <1>; #size-cells = <0>; }; - i2c_clk: i2c_clk { - compatible = "fixed-clock"; - #clock-cells = <0x0>; - clock-frequency = <111111111>; + gpio: gpio@ff0a0000 { + compatible = "xlnx,zynqmp-gpio-1.0"; + status = "disabled"; + #gpio-cells = <0x2>; + interrupt-parent = <&gic>; + interrupts = <0 16 4>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x0 0xff0a0000 0x1000>; }; i2c0: i2c@ff020000 { @@ -198,7 +179,6 @@ interrupt-parent = <&gic>; interrupts = <0 17 4>; reg = <0x0 0xff020000 0x1000>; - clocks = <&i2c_clk>; #address-cells = <1>; #size-cells = <0>; }; @@ -209,24 +189,16 @@ interrupt-parent = <&gic>; interrupts = <0 18 4>; reg = <0x0 0xff030000 0x1000>; - clocks = <&i2c_clk>; #address-cells = <1>; #size-cells = <0>; }; - sata_clk: sata_clk { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <75000000>; - }; - sata: ahci@fd0c0000 { compatible = "ceva,ahci-1v84"; status = "disabled"; reg = <0x0 0xfd0c0000 0x2000>; interrupt-parent = <&gic>; interrupts = <0 133 4>; - clocks = <&sata_clk>; }; sdhci0: sdhci@ff160000 { @@ -236,7 +208,6 @@ interrupts = <0 48 4>; reg = <0x0 0xff160000 0x1000>; clock-names = "clk_xin", "clk_ahb"; - clocks = <&misc_clk>, <&misc_clk>; }; sdhci1: sdhci@ff170000 { @@ -246,7 +217,6 @@ interrupts = <0 49 4>; reg = <0x0 0xff170000 0x1000>; clock-names = "clk_xin", "clk_ahb"; - clocks = <&misc_clk>, <&misc_clk>; }; smmu: smmu@fd800000 { @@ -268,7 +238,6 @@ interrupts = <0 19 4>; reg = <0x0 0xff040000 0x1000>; clock-names = "ref_clk", "pclk"; - clocks = <&misc_clk &misc_clk>; #address-cells = <1>; #size-cells = <0>; }; @@ -280,7 +249,6 @@ interrupts = <0 20 4>; reg = <0x0 0xff050000 0x1000>; clock-names = "ref_clk", "pclk"; - clocks = <&misc_clk &misc_clk>; #address-cells = <1>; #size-cells = <0>; }; @@ -291,7 +259,6 @@ interrupt-parent = <&gic>; interrupts = <0 36 4>, <0 37 4>, <0 38 4>; reg = <0x0 0xff110000 0x1000>; - clocks = <&misc_clk>; timer-width = <32>; }; @@ -301,7 +268,6 @@ interrupt-parent = <&gic>; interrupts = <0 39 4>, <0 40 4>, <0 41 4>; reg = <0x0 0xff120000 0x1000>; - clocks = <&misc_clk>; timer-width = <32>; }; @@ -311,7 +277,6 @@ interrupt-parent = <&gic>; interrupts = <0 42 4>, <0 43 4>, <0 44 4>; reg = <0x0 0xff130000 0x1000>; - clocks = <&misc_clk>; timer-width = <32>; }; @@ -321,7 +286,6 @@ interrupt-parent = <&gic>; interrupts = <0 45 4>, <0 46 4>, <0 47 4>; reg = <0x0 0xff140000 0x1000>; - clocks = <&misc_clk>; timer-width = <32>; }; @@ -332,7 +296,6 @@ interrupts = <0 21 4>; reg = <0x0 0xff000000 0x1000>; clock-names = "uart_clk", "pclk"; - clocks = <&misc_clk &misc_clk>; }; uart1: serial@ff010000 { @@ -342,7 +305,6 @@ interrupts = <0 22 4>; reg = <0x0 0xff010000 0x1000>; clock-names = "uart_clk", "pclk"; - clocks = <&misc_clk &misc_clk>; }; usb0: usb@fe200000 { @@ -352,7 +314,6 @@ interrupts = <0 65 4>; reg = <0x0 0xfe200000 0x40000>; clock-names = "clk_xin", "clk_ahb"; - clocks = <&misc_clk>, <&misc_clk>; }; usb1: usb@fe300000 { @@ -362,13 +323,11 @@ interrupts = <0 70 4>; reg = <0x0 0xfe300000 0x40000>; clock-names = "clk_xin", "clk_ahb"; - clocks = <&misc_clk>, <&misc_clk>; }; watchdog0: watchdog@fd4d0000 { compatible = "cdns,wdt-r1p2"; status = "disabled"; - clocks= <&misc_clk>; interrupt-parent = <&gic>; interrupts = <0 52 1>; reg = <0x0 0xfd4d0000 0x1000>; diff --git a/arch/arm64/boot/install.sh b/arch/arm64/boot/install.sh index 12ed78aa6f0c..d91e1f022573 100644 --- a/arch/arm64/boot/install.sh +++ b/arch/arm64/boot/install.sh @@ -20,6 +20,20 @@ # $4 - default install path (blank if root directory) # +verify () { + if [ ! -f "$1" ]; then + echo "" 1>&2 + echo " *** Missing file: $1" 1>&2 + echo ' *** You need to run "make" before "make install".' 1>&2 + echo "" 1>&2 + exit 1 + fi +} + +# Make sure the files actually exist +verify "$2" +verify "$3" + # User may have a custom install script if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 86581f793e39..f70505186820 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -30,12 +30,15 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set +CONFIG_ARCH_SUNXI=y +CONFIG_ARCH_ALPINE=y CONFIG_ARCH_BCM_IPROC=y CONFIG_ARCH_BERLIN=y -CONFIG_ARCH_EXYNOS7=y +CONFIG_ARCH_EXYNOS=y CONFIG_ARCH_LAYERSCAPE=y CONFIG_ARCH_HISI=y CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_MVEBU=y CONFIG_ARCH_QCOM=y CONFIG_ARCH_ROCKCHIP=y CONFIG_ARCH_SEATTLE=y @@ -47,6 +50,7 @@ CONFIG_ARCH_SPRD=y CONFIG_ARCH_THUNDER=y CONFIG_ARCH_UNIPHIER=y CONFIG_ARCH_VEXPRESS=y +CONFIG_ARCH_VULCAN=y CONFIG_ARCH_XGENE=y CONFIG_ARCH_ZYNQMP=y CONFIG_PCI=y @@ -95,6 +99,7 @@ CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y CONFIG_AHCI_CEVA=y +CONFIG_AHCI_MVEBU=y CONFIG_AHCI_XGENE=y CONFIG_SATA_RCAR=y CONFIG_PATA_PLATFORM=y @@ -136,24 +141,40 @@ CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +CONFIG_SERIAL_MVEBU_UART=y CONFIG_VIRTIO_CONSOLE=y # CONFIG_HW_RANDOM is not set +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MV64XXX=y CONFIG_I2C_QUP=y CONFIG_I2C_UNIPHIER_F=y CONFIG_I2C_RCAR=y CONFIG_SPI=y CONFIG_SPI_PL022=y CONFIG_SPI_QUP=y +CONFIG_SPMI=y CONFIG_PINCTRL_MSM8916=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_DWAPB=y CONFIG_GPIO_PL061=y CONFIG_GPIO_RCAR=y CONFIG_GPIO_XGENE=y +CONFIG_POWER_RESET_MSM=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_EMULATION=y +CONFIG_EXYNOS_THERMAL=y +CONFIG_MFD_SPMI_PMIC=y +CONFIG_MFD_SEC_CORE=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_QCOM_SMD_RPM=y +CONFIG_REGULATOR_QCOM_SPMI=y +CONFIG_REGULATOR_S2MPS11=y CONFIG_FB=y CONFIG_FB_ARMCLCD=y CONFIG_FRAMEBUFFER_CONSOLE=y @@ -166,21 +187,35 @@ CONFIG_SND_SOC=y CONFIG_SND_SOC_RCAR=y CONFIG_SND_SOC_AK4613=y CONFIG_USB=y +CONFIG_USB_OTG=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PLATFORM=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_MSM=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y CONFIG_USB_ISP1760=y +CONFIG_USB_HSIC_USB3503=y +CONFIG_USB_MSM_OTG=y CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y CONFIG_MMC=y +CONFIG_MMC_BLOCK_MINORS=16 CONFIG_MMC_ARMMMCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_TEGRA=y +CONFIG_MMC_SDHCI_MSM=y CONFIG_MMC_SPI=y +CONFIG_MMC_SUNXI=y CONFIG_MMC_DW=y CONFIG_MMC_DW_EXYNOS=y +CONFIG_MMC_BLOCK_MINORS=16 CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_SYSCON=y @@ -188,8 +223,10 @@ CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_CPU=y CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_S5M=y CONFIG_RTC_DRV_EFI=y CONFIG_RTC_DRV_PL031=y +CONFIG_RTC_DRV_SUN6I=y CONFIG_RTC_DRV_XGENE=y CONFIG_DMADEVICES=y CONFIG_QCOM_BAM_DMA=y @@ -213,6 +250,8 @@ CONFIG_QCOM_SMD_RPM=y CONFIG_ARCH_TEGRA_132_SOC=y CONFIG_ARCH_TEGRA_210_SOC=y CONFIG_HISILICON_IRQ_MBIGEN=y +CONFIG_EXTCON_USB_GPIO=y +CONFIG_PHY_RCAR_GEN3_USB2=y CONFIG_PHY_XGENE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c index 05d9e16c0dfd..5c888049d061 100644 --- a/arch/arm64/crypto/aes-glue.c +++ b/arch/arm64/crypto/aes-glue.c @@ -15,6 +15,7 @@ #include <crypto/algapi.h> #include <linux/module.h> #include <linux/cpufeature.h> +#include <crypto/xts.h> #include "aes-ce-setkey.h" @@ -85,6 +86,10 @@ static int xts_set_key(struct crypto_tfm *tfm, const u8 *in_key, struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm); int ret; + ret = xts_check_key(tfm, in_key, key_len); + if (ret) + return ret; + ret = aes_expandkey(&ctx->key1, in_key, key_len / 2); if (!ret) ret = aes_expandkey(&ctx->key2, &in_key[key_len / 2], @@ -294,7 +299,7 @@ static struct crypto_alg aes_algs[] = { { .cra_blkcipher = { .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = AES_BLOCK_SIZE, + .ivsize = 0, .setkey = aes_setkey, .encrypt = ecb_encrypt, .decrypt = ecb_decrypt, @@ -371,7 +376,7 @@ static struct crypto_alg aes_algs[] = { { .cra_ablkcipher = { .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = AES_BLOCK_SIZE, + .ivsize = 0, .setkey = ablk_set_key, .encrypt = ablk_encrypt, .decrypt = ablk_decrypt, diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index 70fd9ffb58cf..cff532a6744e 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild @@ -1,5 +1,3 @@ - - generic-y += bug.h generic-y += bugs.h generic-y += checksum.h @@ -31,7 +29,6 @@ generic-y += msgbuf.h generic-y += msi.h generic-y += mutex.h generic-y += pci.h -generic-y += pci-bridge.h generic-y += poll.h generic-y += preempt.h generic-y += resource.h diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h index 6a5ecbddcace..c64268dbff64 100644 --- a/arch/arm64/include/asm/cacheflush.h +++ b/arch/arm64/include/asm/cacheflush.h @@ -149,8 +149,4 @@ int set_memory_rw(unsigned long addr, int numpages); int set_memory_x(unsigned long addr, int numpages); int set_memory_nx(unsigned long addr, int numpages); -#ifdef CONFIG_DEBUG_RODATA -void mark_rodata_ro(void); -#endif - #endif diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index f6f7423e51d0..b9b649422fca 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -33,6 +33,7 @@ #define ARM64_HAS_NO_HW_PREFETCH 8 #define ARM64_HAS_UAO 9 #define ARM64_ALT_PAN_NOT_UAO 10 +#define ARM64_HAS_VIRT_HOST_EXTN 11 #define ARM64_WORKAROUND_CAVIUM_27456 12 #define ARM64_NCAPS 13 diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index f2309a25d14c..87e1985f3be8 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -70,6 +70,7 @@ #define ARM_CPU_IMP_ARM 0x41 #define ARM_CPU_IMP_APM 0x50 #define ARM_CPU_IMP_CAVIUM 0x43 +#define ARM_CPU_IMP_BRCM 0x42 #define ARM_CPU_PART_AEM_V8 0xD0F #define ARM_CPU_PART_FOUNDATION 0xD00 @@ -80,6 +81,8 @@ #define CAVIUM_CPU_PART_THUNDERX 0x0A1 +#define BRCM_CPU_PART_VULCAN 0x516 + #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h index 9732908bfc8a..115ea2a64520 100644 --- a/arch/arm64/include/asm/hw_breakpoint.h +++ b/arch/arm64/include/asm/hw_breakpoint.h @@ -18,6 +18,7 @@ #include <asm/cputype.h> #include <asm/cpufeature.h> +#include <asm/virt.h> #ifdef __KERNEL__ @@ -35,10 +36,21 @@ struct arch_hw_breakpoint { struct arch_hw_breakpoint_ctrl ctrl; }; +/* Privilege Levels */ +#define AARCH64_BREAKPOINT_EL1 1 +#define AARCH64_BREAKPOINT_EL0 2 + +#define DBG_HMC_HYP (1 << 13) + static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl) { - return (ctrl.len << 5) | (ctrl.type << 3) | (ctrl.privilege << 1) | + u32 val = (ctrl.len << 5) | (ctrl.type << 3) | (ctrl.privilege << 1) | ctrl.enabled; + + if (is_kernel_in_hyp_mode() && ctrl.privilege == AARCH64_BREAKPOINT_EL1) + val |= DBG_HMC_HYP; + + return val; } static inline void decode_ctrl_reg(u32 reg, @@ -61,10 +73,6 @@ static inline void decode_ctrl_reg(u32 reg, #define ARM_BREAKPOINT_STORE 2 #define AARCH64_ESR_ACCESS_MASK (1 << 6) -/* Privilege Levels */ -#define AARCH64_BREAKPOINT_EL1 1 -#define AARCH64_BREAKPOINT_EL0 2 - /* Lengths */ #define ARM_BREAKPOINT_LEN_1 0x1 #define ARM_BREAKPOINT_LEN_2 0x3 diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 3d30c1532578..0e391dbfc420 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -23,6 +23,7 @@ #include <asm/types.h> /* Hyp Configuration Register (HCR) bits */ +#define HCR_E2H (UL(1) << 34) #define HCR_ID (UL(1) << 33) #define HCR_CD (UL(1) << 32) #define HCR_RW_SHIFT 31 @@ -81,7 +82,7 @@ HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW) #define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF) #define HCR_INT_OVERRIDE (HCR_FMO | HCR_IMO) - +#define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H) /* Hyp System Control Register (SCTLR_EL2) bits */ #define SCTLR_EL2_EE (1 << 25) @@ -107,8 +108,6 @@ #define TCR_EL2_MASK (TCR_EL2_TG0 | TCR_EL2_SH0 | \ TCR_EL2_ORGN0 | TCR_EL2_IRGN0 | TCR_EL2_T0SZ) -#define TCR_EL2_FLAGS (TCR_EL2_RES1 | TCR_EL2_PS_40B) - /* VTCR_EL2 Registers bits */ #define VTCR_EL2_RES1 (1 << 31) #define VTCR_EL2_PS_MASK (7 << 16) @@ -218,4 +217,7 @@ ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \ ECN(BKPT32), ECN(VECTOR32), ECN(BRK64) +#define CPACR_EL1_FPEN (3 << 20) +#define CPACR_EL1_TTA (1 << 28) + #endif /* __ARM64_KVM_ARM_H__ */ diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 054ac25e7c2e..eb7490d232a0 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -26,7 +26,13 @@ #define KVM_ARM64_DEBUG_DIRTY_SHIFT 0 #define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT) -#define kvm_ksym_ref(sym) phys_to_virt((u64)&sym - kimage_voffset) +#define kvm_ksym_ref(sym) \ + ({ \ + void *val = &sym; \ + if (!is_kernel_in_hyp_mode()) \ + val = phys_to_virt((u64)&sym - kimage_voffset); \ + val; \ + }) #ifndef __ASSEMBLY__ struct kvm; @@ -37,9 +43,6 @@ extern char __kvm_hyp_init_end[]; extern char __kvm_hyp_vector[]; -#define __kvm_hyp_code_start __hyp_text_start -#define __kvm_hyp_code_end __hyp_text_end - extern void __kvm_flush_vm_context(void); extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); extern void __kvm_tlb_flush_vmid(struct kvm *kvm); @@ -47,9 +50,12 @@ extern void __kvm_tlb_flush_vmid(struct kvm *kvm); extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); extern u64 __vgic_v3_get_ich_vtr_el2(void); +extern void __vgic_v3_init_lrs(void); extern u32 __kvm_get_mdcr_el2(void); +extern void __init_stage2_translation(void); + #endif #endif /* __ARM_KVM_ASM_H__ */ diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 779a5872a2c5..40bc1681b6d5 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -29,6 +29,7 @@ #include <asm/kvm_mmio.h> #include <asm/ptrace.h> #include <asm/cputype.h> +#include <asm/virt.h> unsigned long *vcpu_reg32(const struct kvm_vcpu *vcpu, u8 reg_num); unsigned long *vcpu_spsr32(const struct kvm_vcpu *vcpu); @@ -43,6 +44,8 @@ void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) { vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS; + if (is_kernel_in_hyp_mode()) + vcpu->arch.hcr_el2 |= HCR_E2H; if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) vcpu->arch.hcr_el2 &= ~HCR_RW; } @@ -189,6 +192,11 @@ static inline bool kvm_vcpu_dabt_iss1tw(const struct kvm_vcpu *vcpu) return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_S1PTW); } +static inline bool kvm_vcpu_dabt_is_cm(const struct kvm_vcpu *vcpu) +{ + return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_CM); +} + static inline int kvm_vcpu_dabt_get_as(const struct kvm_vcpu *vcpu) { return 1 << ((kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SAS) >> ESR_ELx_SAS_SHIFT); diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index f057404cf711..227ed475dbd3 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -25,7 +25,9 @@ #include <linux/types.h> #include <linux/kvm_types.h> #include <asm/kvm.h> +#include <asm/kvm_asm.h> #include <asm/kvm_mmio.h> +#include <asm/kvm_perf_event.h> #define __KVM_HAVE_ARCH_INTC_INITIALIZED @@ -36,10 +38,11 @@ #include <kvm/arm_vgic.h> #include <kvm/arm_arch_timer.h> +#include <kvm/arm_pmu.h> #define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS -#define KVM_VCPU_MAX_FEATURES 3 +#define KVM_VCPU_MAX_FEATURES 4 int __attribute_const__ kvm_target_cpu(void); int kvm_reset_vcpu(struct kvm_vcpu *vcpu); @@ -114,6 +117,21 @@ enum vcpu_sysreg { MDSCR_EL1, /* Monitor Debug System Control Register */ MDCCINT_EL1, /* Monitor Debug Comms Channel Interrupt Enable Reg */ + /* Performance Monitors Registers */ + PMCR_EL0, /* Control Register */ + PMSELR_EL0, /* Event Counter Selection Register */ + PMEVCNTR0_EL0, /* Event Counter Register (0-30) */ + PMEVCNTR30_EL0 = PMEVCNTR0_EL0 + 30, + PMCCNTR_EL0, /* Cycle Counter Register */ + PMEVTYPER0_EL0, /* Event Type Register (0-30) */ + PMEVTYPER30_EL0 = PMEVTYPER0_EL0 + 30, + PMCCFILTR_EL0, /* Cycle Count Filter Register */ + PMCNTENSET_EL0, /* Count Enable Set Register */ + PMINTENSET_EL1, /* Interrupt Enable Set Register */ + PMOVSSET_EL0, /* Overflow Flag Status Set Register */ + PMSWINC_EL0, /* Software Increment Register */ + PMUSERENR_EL0, /* User Enable Register */ + /* 32bit specific registers. Keep them at the end of the range */ DACR32_EL2, /* Domain Access Control Register */ IFSR32_EL2, /* Instruction Fault Status Register */ @@ -211,6 +229,7 @@ struct kvm_vcpu_arch { /* VGIC state */ struct vgic_cpu vgic_cpu; struct arch_timer_cpu timer_cpu; + struct kvm_pmu pmu; /* * Anything that is not used directly from assembly code goes @@ -344,5 +363,18 @@ void kvm_arm_init_debug(void); void kvm_arm_setup_debug(struct kvm_vcpu *vcpu); void kvm_arm_clear_debug(struct kvm_vcpu *vcpu); void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu); +int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr); +int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr); +int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr); + +/* #define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__) */ + +static inline void __cpu_init_stage2(void) +{ + kvm_call_hyp(__init_stage2_translation); +} #endif /* __ARM64_KVM_HOST_H__ */ diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h new file mode 100644 index 000000000000..a46b019ebcf5 --- /dev/null +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2015 - ARM Ltd + * Author: Marc Zyngier <marc.zyngier@arm.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 __ARM64_KVM_HYP_H__ +#define __ARM64_KVM_HYP_H__ + +#include <linux/compiler.h> +#include <linux/kvm_host.h> +#include <asm/kvm_mmu.h> +#include <asm/kvm_perf_event.h> +#include <asm/sysreg.h> + +#define __hyp_text __section(.hyp.text) notrace + +static inline unsigned long __kern_hyp_va(unsigned long v) +{ + asm volatile(ALTERNATIVE("and %0, %0, %1", + "nop", + ARM64_HAS_VIRT_HOST_EXTN) + : "+r" (v) : "i" (HYP_PAGE_OFFSET_MASK)); + return v; +} + +#define kern_hyp_va(v) (typeof(v))(__kern_hyp_va((unsigned long)(v))) + +static inline unsigned long __hyp_kern_va(unsigned long v) +{ + u64 offset = PAGE_OFFSET - HYP_PAGE_OFFSET; + asm volatile(ALTERNATIVE("add %0, %0, %1", + "nop", + ARM64_HAS_VIRT_HOST_EXTN) + : "+r" (v) : "r" (offset)); + return v; +} + +#define hyp_kern_va(v) (typeof(v))(__hyp_kern_va((unsigned long)(v))) + +#define read_sysreg_elx(r,nvh,vh) \ + ({ \ + u64 reg; \ + asm volatile(ALTERNATIVE("mrs %0, " __stringify(r##nvh),\ + "mrs_s %0, " __stringify(r##vh),\ + ARM64_HAS_VIRT_HOST_EXTN) \ + : "=r" (reg)); \ + reg; \ + }) + +#define write_sysreg_elx(v,r,nvh,vh) \ + do { \ + u64 __val = (u64)(v); \ + asm volatile(ALTERNATIVE("msr " __stringify(r##nvh) ", %x0",\ + "msr_s " __stringify(r##vh) ", %x0",\ + ARM64_HAS_VIRT_HOST_EXTN) \ + : : "rZ" (__val)); \ + } while (0) + +/* + * Unified accessors for registers that have a different encoding + * between VHE and non-VHE. They must be specified without their "ELx" + * encoding. + */ +#define read_sysreg_el2(r) \ + ({ \ + u64 reg; \ + asm volatile(ALTERNATIVE("mrs %0, " __stringify(r##_EL2),\ + "mrs %0, " __stringify(r##_EL1),\ + ARM64_HAS_VIRT_HOST_EXTN) \ + : "=r" (reg)); \ + reg; \ + }) + +#define write_sysreg_el2(v,r) \ + do { \ + u64 __val = (u64)(v); \ + asm volatile(ALTERNATIVE("msr " __stringify(r##_EL2) ", %x0",\ + "msr " __stringify(r##_EL1) ", %x0",\ + ARM64_HAS_VIRT_HOST_EXTN) \ + : : "rZ" (__val)); \ + } while (0) + +#define read_sysreg_el0(r) read_sysreg_elx(r, _EL0, _EL02) +#define write_sysreg_el0(v,r) write_sysreg_elx(v, r, _EL0, _EL02) +#define read_sysreg_el1(r) read_sysreg_elx(r, _EL1, _EL12) +#define write_sysreg_el1(v,r) write_sysreg_elx(v, r, _EL1, _EL12) + +/* The VHE specific system registers and their encoding */ +#define sctlr_EL12 sys_reg(3, 5, 1, 0, 0) +#define cpacr_EL12 sys_reg(3, 5, 1, 0, 2) +#define ttbr0_EL12 sys_reg(3, 5, 2, 0, 0) +#define ttbr1_EL12 sys_reg(3, 5, 2, 0, 1) +#define tcr_EL12 sys_reg(3, 5, 2, 0, 2) +#define afsr0_EL12 sys_reg(3, 5, 5, 1, 0) +#define afsr1_EL12 sys_reg(3, 5, 5, 1, 1) +#define esr_EL12 sys_reg(3, 5, 5, 2, 0) +#define far_EL12 sys_reg(3, 5, 6, 0, 0) +#define mair_EL12 sys_reg(3, 5, 10, 2, 0) +#define amair_EL12 sys_reg(3, 5, 10, 3, 0) +#define vbar_EL12 sys_reg(3, 5, 12, 0, 0) +#define contextidr_EL12 sys_reg(3, 5, 13, 0, 1) +#define cntkctl_EL12 sys_reg(3, 5, 14, 1, 0) +#define cntp_tval_EL02 sys_reg(3, 5, 14, 2, 0) +#define cntp_ctl_EL02 sys_reg(3, 5, 14, 2, 1) +#define cntp_cval_EL02 sys_reg(3, 5, 14, 2, 2) +#define cntv_tval_EL02 sys_reg(3, 5, 14, 3, 0) +#define cntv_ctl_EL02 sys_reg(3, 5, 14, 3, 1) +#define cntv_cval_EL02 sys_reg(3, 5, 14, 3, 2) +#define spsr_EL12 sys_reg(3, 5, 4, 0, 0) +#define elr_EL12 sys_reg(3, 5, 4, 0, 1) + +/** + * hyp_alternate_select - Generates patchable code sequences that are + * used to switch between two implementations of a function, depending + * on the availability of a feature. + * + * @fname: a symbol name that will be defined as a function returning a + * function pointer whose type will match @orig and @alt + * @orig: A pointer to the default function, as returned by @fname when + * @cond doesn't hold + * @alt: A pointer to the alternate function, as returned by @fname + * when @cond holds + * @cond: a CPU feature (as described in asm/cpufeature.h) + */ +#define hyp_alternate_select(fname, orig, alt, cond) \ +typeof(orig) * __hyp_text fname(void) \ +{ \ + typeof(alt) *val = orig; \ + asm volatile(ALTERNATIVE("nop \n", \ + "mov %0, %1 \n", \ + cond) \ + : "+r" (val) : "r" (alt)); \ + return val; \ +} + +void __vgic_v2_save_state(struct kvm_vcpu *vcpu); +void __vgic_v2_restore_state(struct kvm_vcpu *vcpu); + +void __vgic_v3_save_state(struct kvm_vcpu *vcpu); +void __vgic_v3_restore_state(struct kvm_vcpu *vcpu); + +void __timer_save_state(struct kvm_vcpu *vcpu); +void __timer_restore_state(struct kvm_vcpu *vcpu); + +void __sysreg_save_host_state(struct kvm_cpu_context *ctxt); +void __sysreg_restore_host_state(struct kvm_cpu_context *ctxt); +void __sysreg_save_guest_state(struct kvm_cpu_context *ctxt); +void __sysreg_restore_guest_state(struct kvm_cpu_context *ctxt); +void __sysreg32_save_state(struct kvm_vcpu *vcpu); +void __sysreg32_restore_state(struct kvm_vcpu *vcpu); + +void __debug_save_state(struct kvm_vcpu *vcpu, + struct kvm_guest_debug_arch *dbg, + struct kvm_cpu_context *ctxt); +void __debug_restore_state(struct kvm_vcpu *vcpu, + struct kvm_guest_debug_arch *dbg, + struct kvm_cpu_context *ctxt); +void __debug_cond_save_host_state(struct kvm_vcpu *vcpu); +void __debug_cond_restore_host_state(struct kvm_vcpu *vcpu); + +void __fpsimd_save_state(struct user_fpsimd_state *fp_regs); +void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs); +bool __fpsimd_enabled(void); + +u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt); +void __noreturn __hyp_do_panic(unsigned long, ...); + +#endif /* __ARM64_KVM_HYP_H__ */ + diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 2ac4a22d3119..22732a5e3119 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h @@ -23,13 +23,16 @@ #include <asm/cpufeature.h> /* - * As we only have the TTBR0_EL2 register, we cannot express + * As ARMv8.0 only has the TTBR0_EL2 register, we cannot express * "negative" addresses. This makes it impossible to directly share * mappings with the kernel. * * Instead, give the HYP mode its own VA region at a fixed offset from * the kernel by just masking the top bits (which are all ones for a * kernel address). + * + * ARMv8.1 (using VHE) does have a TTBR1_EL2, and doesn't use these + * macros (the entire kernel runs at EL2). */ #define HYP_PAGE_OFFSET_SHIFT VA_BITS #define HYP_PAGE_OFFSET_MASK ((UL(1) << HYP_PAGE_OFFSET_SHIFT) - 1) @@ -56,12 +59,19 @@ #ifdef __ASSEMBLY__ +#include <asm/alternative.h> +#include <asm/cpufeature.h> + /* * Convert a kernel VA into a HYP VA. * reg: VA to be converted. */ .macro kern_hyp_va reg +alternative_if_not ARM64_HAS_VIRT_HOST_EXTN and \reg, \reg, #HYP_PAGE_OFFSET_MASK +alternative_else + nop +alternative_endif .endm #else diff --git a/arch/arm64/include/asm/kvm_perf_event.h b/arch/arm64/include/asm/kvm_perf_event.h new file mode 100644 index 000000000000..c18fdebb8f66 --- /dev/null +++ b/arch/arm64/include/asm/kvm_perf_event.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2012 ARM Ltd. + * + * 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 __ASM_KVM_PERF_EVENT_H +#define __ASM_KVM_PERF_EVENT_H + +#define ARMV8_PMU_MAX_COUNTERS 32 +#define ARMV8_PMU_COUNTER_MASK (ARMV8_PMU_MAX_COUNTERS - 1) + +/* + * Per-CPU PMCR: config reg + */ +#define ARMV8_PMU_PMCR_E (1 << 0) /* Enable all counters */ +#define ARMV8_PMU_PMCR_P (1 << 1) /* Reset all counters */ +#define ARMV8_PMU_PMCR_C (1 << 2) /* Cycle counter reset */ +#define ARMV8_PMU_PMCR_D (1 << 3) /* CCNT counts every 64th cpu cycle */ +#define ARMV8_PMU_PMCR_X (1 << 4) /* Export to ETM */ +#define ARMV8_PMU_PMCR_DP (1 << 5) /* Disable CCNT if non-invasive debug*/ +/* Determines which bit of PMCCNTR_EL0 generates an overflow */ +#define ARMV8_PMU_PMCR_LC (1 << 6) +#define ARMV8_PMU_PMCR_N_SHIFT 11 /* Number of counters supported */ +#define ARMV8_PMU_PMCR_N_MASK 0x1f +#define ARMV8_PMU_PMCR_MASK 0x7f /* Mask for writable bits */ + +/* + * PMOVSR: counters overflow flag status reg + */ +#define ARMV8_PMU_OVSR_MASK 0xffffffff /* Mask for writable bits */ +#define ARMV8_PMU_OVERFLOWED_MASK ARMV8_PMU_OVSR_MASK + +/* + * PMXEVTYPER: Event selection reg + */ +#define ARMV8_PMU_EVTYPE_MASK 0xc80003ff /* Mask for writable bits */ +#define ARMV8_PMU_EVTYPE_EVENT 0x3ff /* Mask for EVENT bits */ + +#define ARMV8_PMU_EVTYPE_EVENT_SW_INCR 0 /* Software increment event */ + +/* + * Event filters for PMUv3 + */ +#define ARMV8_PMU_EXCLUDE_EL1 (1 << 31) +#define ARMV8_PMU_EXCLUDE_EL0 (1 << 30) +#define ARMV8_PMU_INCLUDE_EL2 (1 << 27) + +/* + * PMUSERENR: user enable reg + */ +#define ARMV8_PMU_USERENR_MASK 0xf /* Mask for writable bits */ +#define ARMV8_PMU_USERENR_EN (1 << 0) /* PMU regs can be accessed at EL0 */ +#define ARMV8_PMU_USERENR_SW (1 << 1) /* PMSWINC can be written at EL0 */ +#define ARMV8_PMU_USERENR_CR (1 << 2) /* Cycle counter can be read at EL0 */ +#define ARMV8_PMU_USERENR_ER (1 << 3) /* Event counter can be read at EL0 */ + +#endif diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h index b008a72f8bc0..b9a7ba9ca44c 100644 --- a/arch/arm64/include/asm/pci.h +++ b/arch/arm64/include/asm/pci.h @@ -7,8 +7,6 @@ #include <linux/dma-mapping.h> #include <asm/io.h> -#include <asm-generic/pci-bridge.h> -#include <asm-generic/pci-dma-compat.h> #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0 diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index e308807105e2..989fef16d461 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -26,7 +26,7 @@ /* * VMALLOC and SPARSEMEM_VMEMMAP ranges. * - * VMEMAP_SIZE: allows the whole VA space to be covered by a struct page array + * VMEMAP_SIZE: allows the whole linear region to be covered by a struct page array * (rounded up to PUD_SIZE). * VMALLOC_START: beginning of the kernel vmalloc space * VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space, @@ -37,7 +37,9 @@ #define VMALLOC_START (MODULES_END) #define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K) -#define vmemmap ((struct page *)(VMALLOC_END + SZ_64K)) +#define VMEMMAP_START (VMALLOC_END + SZ_64K) +#define vmemmap ((struct page *)VMEMMAP_START - \ + SECTION_ALIGN_DOWN(memstart_addr >> PAGE_SHIFT)) #define FIRST_USER_ADDRESS 0UL diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h index 7a5df5252dd7..9f22dd607958 100644 --- a/arch/arm64/include/asm/virt.h +++ b/arch/arm64/include/asm/virt.h @@ -23,6 +23,8 @@ #ifndef __ASSEMBLY__ +#include <asm/ptrace.h> + /* * __boot_cpu_mode records what mode CPUs were booted in. * A correctly-implemented bootloader must start all CPUs in the same mode: @@ -50,6 +52,14 @@ static inline bool is_hyp_mode_mismatched(void) return __boot_cpu_mode[0] != __boot_cpu_mode[1]; } +static inline bool is_kernel_in_hyp_mode(void) +{ + u64 el; + + asm("mrs %0, CurrentEL" : "=r" (el)); + return el == CurrentEL_EL2; +} + /* The section containing the hypervisor text */ extern char __hyp_text_start[]; extern char __hyp_text_end[]; diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index 2d4ca4bb0dd3..f209ea151dca 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -94,6 +94,7 @@ struct kvm_regs { #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */ #define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */ #define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */ +#define KVM_ARM_VCPU_PMU_V3 3 /* Support guest PMUv3 */ struct kvm_vcpu_init { __u32 target; @@ -204,6 +205,11 @@ struct kvm_arch_memory_slot { #define KVM_DEV_ARM_VGIC_GRP_CTRL 4 #define KVM_DEV_ARM_VGIC_CTRL_INIT 0 +/* Device Control API on vcpu fd */ +#define KVM_ARM_VCPU_PMU_V3_CTRL 0 +#define KVM_ARM_VCPU_PMU_V3_IRQ 0 +#define KVM_ARM_VCPU_PMU_V3_INIT 1 + /* KVM_IRQ_LINE irq field index values */ #define KVM_ARM_IRQ_TYPE_SHIFT 24 #define KVM_ARM_IRQ_TYPE_MASK 0xff diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index 463fcf1aca8a..3ae6b310ac9b 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -112,9 +112,6 @@ int main(void) DEFINE(CPU_USER_PT_REGS, offsetof(struct kvm_regs, regs)); DEFINE(CPU_FP_REGS, offsetof(struct kvm_regs, fp_regs)); DEFINE(VCPU_FPEXC32_EL2, offsetof(struct kvm_vcpu, arch.ctxt.sys_regs[FPEXC32_EL2])); - DEFINE(VCPU_ESR_EL2, offsetof(struct kvm_vcpu, arch.fault.esr_el2)); - DEFINE(VCPU_FAR_EL2, offsetof(struct kvm_vcpu, arch.fault.far_el2)); - DEFINE(VCPU_HPFAR_EL2, offsetof(struct kvm_vcpu, arch.fault.hpfar_el2)); DEFINE(VCPU_HOST_CONTEXT, offsetof(struct kvm_vcpu, arch.host_cpu_context)); #endif #ifdef CONFIG_CPU_PM diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 392c67eb9fa6..943f5140e0f3 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -27,6 +27,7 @@ #include <asm/mmu_context.h> #include <asm/processor.h> #include <asm/sysreg.h> +#include <asm/virt.h> unsigned long elf_hwcap __read_mostly; EXPORT_SYMBOL_GPL(elf_hwcap); @@ -659,6 +660,11 @@ static bool has_no_hw_prefetch(const struct arm64_cpu_capabilities *entry) return MIDR_IS_CPU_MODEL_RANGE(midr, MIDR_THUNDERX, rv_min, rv_max); } +static bool runs_at_el2(const struct arm64_cpu_capabilities *entry) +{ + return is_kernel_in_hyp_mode(); +} + static const struct arm64_cpu_capabilities arm64_features[] = { { .desc = "GIC system register CPU interface", @@ -714,6 +720,11 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .matches = cpufeature_pan_not_uao, }, #endif /* CONFIG_ARM64_PAN */ + { + .desc = "Virtualization Host Extensions", + .capability = ARM64_HAS_VIRT_HOST_EXTN, + .matches = runs_at_el2, + }, {}, }; diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index 4076a5a7a975..c45f2968bc8c 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -227,11 +227,28 @@ static int call_step_hook(struct pt_regs *regs, unsigned int esr) return retval; } +static void send_user_sigtrap(int si_code) +{ + struct pt_regs *regs = current_pt_regs(); + siginfo_t info = { + .si_signo = SIGTRAP, + .si_errno = 0, + .si_code = si_code, + .si_addr = (void __user *)instruction_pointer(regs), + }; + + if (WARN_ON(!user_mode(regs))) + return; + + if (interrupts_enabled(regs)) + local_irq_enable(); + + force_sig_info(SIGTRAP, &info, current); +} + static int single_step_handler(unsigned long addr, unsigned int esr, struct pt_regs *regs) { - siginfo_t info; - /* * If we are stepping a pending breakpoint, call the hw_breakpoint * handler first. @@ -240,11 +257,7 @@ static int single_step_handler(unsigned long addr, unsigned int esr, return 0; if (user_mode(regs)) { - info.si_signo = SIGTRAP; - info.si_errno = 0; - info.si_code = TRAP_HWBKPT; - info.si_addr = (void __user *)instruction_pointer(regs); - force_sig_info(SIGTRAP, &info, current); + send_user_sigtrap(TRAP_HWBKPT); /* * ptrace will disable single step unless explicitly @@ -308,17 +321,8 @@ static int call_break_hook(struct pt_regs *regs, unsigned int esr) static int brk_handler(unsigned long addr, unsigned int esr, struct pt_regs *regs) { - siginfo_t info; - if (user_mode(regs)) { - info = (siginfo_t) { - .si_signo = SIGTRAP, - .si_errno = 0, - .si_code = TRAP_BRKPT, - .si_addr = (void __user *)instruction_pointer(regs), - }; - - force_sig_info(SIGTRAP, &info, current); + send_user_sigtrap(TRAP_BRKPT); } else if (call_break_hook(regs, esr) != DBG_HOOK_HANDLED) { pr_warning("Unexpected kernel BRK exception at EL1\n"); return -EFAULT; @@ -329,7 +333,6 @@ static int brk_handler(unsigned long addr, unsigned int esr, int aarch32_break_handler(struct pt_regs *regs) { - siginfo_t info; u32 arm_instr; u16 thumb_instr; bool bp = false; @@ -360,14 +363,7 @@ int aarch32_break_handler(struct pt_regs *regs) if (!bp) return -EFAULT; - info = (siginfo_t) { - .si_signo = SIGTRAP, - .si_errno = 0, - .si_code = TRAP_BRKPT, - .si_addr = pc, - }; - - force_sig_info(SIGTRAP, &info, current); + send_user_sigtrap(TRAP_BRKPT); return 0; } diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index a2cf0e3aa1ce..4203d5f257bc 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -31,6 +31,7 @@ #include <asm/cputype.h> #include <asm/elf.h> #include <asm/kernel-pgtable.h> +#include <asm/kvm_arm.h> #include <asm/memory.h> #include <asm/pgtable-hwdef.h> #include <asm/pgtable.h> @@ -534,9 +535,27 @@ CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1 isb ret +2: +#ifdef CONFIG_ARM64_VHE + /* + * Check for VHE being present. For the rest of the EL2 setup, + * x2 being non-zero indicates that we do have VHE, and that the + * kernel is intended to run at EL2. + */ + mrs x2, id_aa64mmfr1_el1 + ubfx x2, x2, #8, #4 +#else + mov x2, xzr +#endif + /* Hyp configuration. */ -2: mov x0, #(1 << 31) // 64-bit EL1 + mov x0, #HCR_RW // 64-bit EL1 + cbz x2, set_hcr + orr x0, x0, #HCR_TGE // Enable Host Extensions + orr x0, x0, #HCR_E2H +set_hcr: msr hcr_el2, x0 + isb /* Generic timers. */ mrs x0, cnthctl_el2 @@ -596,6 +615,13 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems /* Stage-2 translation */ msr vttbr_el2, xzr + cbz x2, install_el2_stub + + mov w20, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2 + isb + ret + +install_el2_stub: /* Hypervisor stub */ adrp x0, __hyp_stub_vectors add x0, x0, #:lo12:__hyp_stub_vectors diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h index db1bf57948f1..5e360ce88f10 100644 --- a/arch/arm64/kernel/image.h +++ b/arch/arm64/kernel/image.h @@ -98,6 +98,7 @@ __efistub_memcpy = KALLSYMS_HIDE(__pi_memcpy); __efistub_memmove = KALLSYMS_HIDE(__pi_memmove); __efistub_memset = KALLSYMS_HIDE(__pi_memset); __efistub_strlen = KALLSYMS_HIDE(__pi_strlen); +__efistub_strnlen = KALLSYMS_HIDE(__pi_strnlen); __efistub_strcmp = KALLSYMS_HIDE(__pi_strcmp); __efistub_strncmp = KALLSYMS_HIDE(__pi_strncmp); __efistub___flush_dcache_area = KALLSYMS_HIDE(__pi___flush_dcache_area); diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index b3d098bd34aa..c72de668e1d4 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c @@ -19,8 +19,6 @@ #include <linux/of_platform.h> #include <linux/slab.h> -#include <asm/pci-bridge.h> - /* * Called after each bus is probed, but before its children are examined */ diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index f7ab14c4d5df..767c4f6e1f5b 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -20,6 +20,7 @@ */ #include <asm/irq_regs.h> +#include <asm/virt.h> #include <linux/of.h> #include <linux/perf/arm_pmu.h> @@ -87,16 +88,25 @@ #define ARMV8_PMUV3_PERFCTR_L2D_TLB 0x2F #define ARMV8_PMUV3_PERFCTR_L21_TLB 0x30 +/* ARMv8 implementation defined event types. */ +#define ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_LD 0x40 +#define ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_ST 0x41 +#define ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_LD 0x42 +#define ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_ST 0x43 +#define ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_LD 0x4C +#define ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_ST 0x4D +#define ARMV8_IMPDEF_PERFCTR_DTLB_ACCESS_LD 0x4E +#define ARMV8_IMPDEF_PERFCTR_DTLB_ACCESS_ST 0x4F + /* ARMv8 Cortex-A53 specific event types. */ #define ARMV8_A53_PERFCTR_PREFETCH_LINEFILL 0xC2 -/* ARMv8 Cortex-A57 and Cortex-A72 specific event types. */ -#define ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_LD 0x40 -#define ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_ST 0x41 -#define ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_LD 0x42 -#define ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_ST 0x43 -#define ARMV8_A57_PERFCTR_DTLB_REFILL_LD 0x4c -#define ARMV8_A57_PERFCTR_DTLB_REFILL_ST 0x4d +/* ARMv8 Cavium ThunderX specific event types. */ +#define ARMV8_THUNDER_PERFCTR_L1_DCACHE_MISS_ST 0xE9 +#define ARMV8_THUNDER_PERFCTR_L1_DCACHE_PREF_ACCESS 0xEA +#define ARMV8_THUNDER_PERFCTR_L1_DCACHE_PREF_MISS 0xEB +#define ARMV8_THUNDER_PERFCTR_L1_ICACHE_PREF_ACCESS 0xEC +#define ARMV8_THUNDER_PERFCTR_L1_ICACHE_PREF_MISS 0xED /* PMUv3 HW events mapping. */ static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { @@ -131,6 +141,18 @@ static const unsigned armv8_a57_perf_map[PERF_COUNT_HW_MAX] = { [PERF_COUNT_HW_BUS_CYCLES] = ARMV8_PMUV3_PERFCTR_BUS_CYCLES, }; +static const unsigned armv8_thunder_perf_map[PERF_COUNT_HW_MAX] = { + PERF_MAP_ALL_UNSUPPORTED, + [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES, + [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED, + [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS, + [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_PC_WRITE, + [PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED, + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV8_PMUV3_PERFCTR_STALL_FRONTEND, + [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV8_PMUV3_PERFCTR_STALL_BACKEND, +}; + static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = { @@ -174,16 +196,46 @@ static const unsigned armv8_a57_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = { PERF_CACHE_MAP_ALL_UNSUPPORTED, - [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_LD, - [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_LD, - [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_ST, - [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_ST, + [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_LD, + [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_LD, + [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_ST, + [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_ST, [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS, [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL, - [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_A57_PERFCTR_DTLB_REFILL_LD, - [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_A57_PERFCTR_DTLB_REFILL_ST, + [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_LD, + [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_ST, + + [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_ITLB_REFILL, + + [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED, + [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED, + [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED, + [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED, +}; + +static const unsigned armv8_thunder_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { + PERF_CACHE_MAP_ALL_UNSUPPORTED, + + [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_LD, + [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_LD, + [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_ST, + [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_THUNDER_PERFCTR_L1_DCACHE_MISS_ST, + [C(L1D)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV8_THUNDER_PERFCTR_L1_DCACHE_PREF_ACCESS, + [C(L1D)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV8_THUNDER_PERFCTR_L1_DCACHE_PREF_MISS, + + [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS, + [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL, + [C(L1I)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV8_THUNDER_PERFCTR_L1_ICACHE_PREF_ACCESS, + [C(L1I)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV8_THUNDER_PERFCTR_L1_ICACHE_PREF_MISS, + + [C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_DTLB_ACCESS_LD, + [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_LD, + [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_DTLB_ACCESS_ST, + [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_ST, [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_ITLB_REFILL, @@ -324,7 +376,6 @@ static const struct attribute_group *armv8_pmuv3_attr_groups[] = { NULL, }; - /* * Perf Events' indices */ @@ -355,9 +406,10 @@ static const struct attribute_group *armv8_pmuv3_attr_groups[] = { #define ARMV8_PMCR_D (1 << 3) /* CCNT counts every 64th cpu cycle */ #define ARMV8_PMCR_X (1 << 4) /* Export to ETM */ #define ARMV8_PMCR_DP (1 << 5) /* Disable CCNT if non-invasive debug*/ +#define ARMV8_PMCR_LC (1 << 6) /* Overflow on 64 bit cycle counter */ #define ARMV8_PMCR_N_SHIFT 11 /* Number of counters supported */ #define ARMV8_PMCR_N_MASK 0x1f -#define ARMV8_PMCR_MASK 0x3f /* Mask for writable bits */ +#define ARMV8_PMCR_MASK 0x7f /* Mask for writable bits */ /* * PMOVSR: counters overflow flag status reg @@ -368,8 +420,8 @@ static const struct attribute_group *armv8_pmuv3_attr_groups[] = { /* * PMXEVTYPER: Event selection reg */ -#define ARMV8_EVTYPE_MASK 0xc80003ff /* Mask for writable bits */ -#define ARMV8_EVTYPE_EVENT 0x3ff /* Mask for EVENT bits */ +#define ARMV8_EVTYPE_MASK 0xc800ffff /* Mask for writable bits */ +#define ARMV8_EVTYPE_EVENT 0xffff /* Mask for EVENT bits */ /* * Event filters for PMUv3 @@ -444,9 +496,16 @@ static inline void armv8pmu_write_counter(struct perf_event *event, u32 value) if (!armv8pmu_counter_valid(cpu_pmu, idx)) pr_err("CPU%u writing wrong counter %d\n", smp_processor_id(), idx); - else if (idx == ARMV8_IDX_CYCLE_COUNTER) - asm volatile("msr pmccntr_el0, %0" :: "r" (value)); - else if (armv8pmu_select_counter(idx) == idx) + else if (idx == ARMV8_IDX_CYCLE_COUNTER) { + /* + * Set the upper 32bits as this is a 64bit counter but we only + * count using the lower 32bits and we want an interrupt when + * it overflows. + */ + u64 value64 = 0xffffffff00000000ULL | value; + + asm volatile("msr pmccntr_el0, %0" :: "r" (value64)); + } else if (armv8pmu_select_counter(idx) == idx) asm volatile("msr pmxevcntr_el0, %0" :: "r" (value)); } @@ -691,9 +750,12 @@ static int armv8pmu_set_event_filter(struct hw_perf_event *event, if (attr->exclude_idle) return -EPERM; + if (is_kernel_in_hyp_mode() && + attr->exclude_kernel != attr->exclude_hv) + return -EINVAL; if (attr->exclude_user) config_base |= ARMV8_EXCLUDE_EL0; - if (attr->exclude_kernel) + if (!is_kernel_in_hyp_mode() && attr->exclude_kernel) config_base |= ARMV8_EXCLUDE_EL1; if (!attr->exclude_hv) config_base |= ARMV8_INCLUDE_EL2; @@ -718,8 +780,11 @@ static void armv8pmu_reset(void *info) armv8pmu_disable_intens(idx); } - /* Initialize & Reset PMNC: C and P bits. */ - armv8pmu_pmcr_write(ARMV8_PMCR_P | ARMV8_PMCR_C); + /* + * Initialize & Reset PMNC. Request overflow interrupt for + * 64 bit cycle counter but cheat in armv8pmu_write_counter(). + */ + armv8pmu_pmcr_write(ARMV8_PMCR_P | ARMV8_PMCR_C | ARMV8_PMCR_LC); } static int armv8_pmuv3_map_event(struct perf_event *event) @@ -743,6 +808,13 @@ static int armv8_a57_map_event(struct perf_event *event) ARMV8_EVTYPE_EVENT); } +static int armv8_thunder_map_event(struct perf_event *event) +{ + return armpmu_map_event(event, &armv8_thunder_perf_map, + &armv8_thunder_perf_cache_map, + ARMV8_EVTYPE_EVENT); +} + static void armv8pmu_read_num_pmnc_events(void *info) { int *nb_cnt = info; @@ -811,11 +883,21 @@ static int armv8_a72_pmu_init(struct arm_pmu *cpu_pmu) return armv8pmu_probe_num_events(cpu_pmu); } +static int armv8_thunder_pmu_init(struct arm_pmu *cpu_pmu) +{ + armv8_pmu_init(cpu_pmu); + cpu_pmu->name = "armv8_cavium_thunder"; + cpu_pmu->map_event = armv8_thunder_map_event; + cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups; + return armv8pmu_probe_num_events(cpu_pmu); +} + static const struct of_device_id armv8_pmu_of_device_ids[] = { {.compatible = "arm,armv8-pmuv3", .data = armv8_pmuv3_init}, {.compatible = "arm,cortex-a53-pmu", .data = armv8_a53_pmu_init}, {.compatible = "arm,cortex-a57-pmu", .data = armv8_a57_pmu_init}, {.compatible = "arm,cortex-a72-pmu", .data = armv8_a72_pmu_init}, + {.compatible = "cavium,thunder-pmu", .data = armv8_thunder_pmu_init}, {}, }; diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c index f67f35b6edb1..42816bebb1e0 100644 --- a/arch/arm64/kernel/psci.c +++ b/arch/arm64/kernel/psci.c @@ -20,7 +20,6 @@ #include <linux/smp.h> #include <linux/delay.h> #include <linux/psci.h> -#include <linux/slab.h> #include <uapi/linux/psci.h> @@ -28,73 +27,6 @@ #include <asm/cpu_ops.h> #include <asm/errno.h> #include <asm/smp_plat.h> -#include <asm/suspend.h> - -static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state); - -static int __maybe_unused cpu_psci_cpu_init_idle(unsigned int cpu) -{ - int i, ret, count = 0; - u32 *psci_states; - struct device_node *state_node, *cpu_node; - - cpu_node = of_get_cpu_node(cpu, NULL); - if (!cpu_node) - return -ENODEV; - - /* - * If the PSCI cpu_suspend function hook has not been initialized - * idle states must not be enabled, so bail out - */ - if (!psci_ops.cpu_suspend) - return -EOPNOTSUPP; - - /* Count idle states */ - while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states", - count))) { - count++; - of_node_put(state_node); - } - - if (!count) - return -ENODEV; - - psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL); - if (!psci_states) - return -ENOMEM; - - for (i = 0; i < count; i++) { - u32 state; - - state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i); - - ret = of_property_read_u32(state_node, - "arm,psci-suspend-param", - &state); - if (ret) { - pr_warn(" * %s missing arm,psci-suspend-param property\n", - state_node->full_name); - of_node_put(state_node); - goto free_mem; - } - - of_node_put(state_node); - pr_debug("psci-power-state %#x index %d\n", state, i); - if (!psci_power_state_is_valid(state)) { - pr_warn("Invalid PSCI power state %#x\n", state); - ret = -EINVAL; - goto free_mem; - } - psci_states[i] = state; - } - /* Idle states parsed correctly, initialize per-cpu pointer */ - per_cpu(psci_power_state, cpu) = psci_states; - return 0; - -free_mem: - kfree(psci_states); - return ret; -} static int __init cpu_psci_cpu_init(unsigned int cpu) { @@ -178,38 +110,11 @@ static int cpu_psci_cpu_kill(unsigned int cpu) } #endif -static int psci_suspend_finisher(unsigned long index) -{ - u32 *state = __this_cpu_read(psci_power_state); - - return psci_ops.cpu_suspend(state[index - 1], - virt_to_phys(cpu_resume)); -} - -static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index) -{ - int ret; - u32 *state = __this_cpu_read(psci_power_state); - /* - * idle state index 0 corresponds to wfi, should never be called - * from the cpu_suspend operations - */ - if (WARN_ON_ONCE(!index)) - return -EINVAL; - - if (!psci_power_state_loses_context(state[index - 1])) - ret = psci_ops.cpu_suspend(state[index - 1], 0); - else - ret = cpu_suspend(index, psci_suspend_finisher); - - return ret; -} - const struct cpu_operations cpu_psci_ops = { .name = "psci", #ifdef CONFIG_CPU_IDLE - .cpu_init_idle = cpu_psci_cpu_init_idle, - .cpu_suspend = cpu_psci_cpu_suspend, + .cpu_init_idle = psci_cpu_init_idle, + .cpu_suspend = psci_cpu_suspend_enter, #endif .cpu_init = cpu_psci_cpu_init, .cpu_prepare = cpu_psci_cpu_prepare, diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 42371f69def3..9dc67769b6a4 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -74,13 +74,13 @@ static struct resource mem_res[] = { .name = "Kernel code", .start = 0, .end = 0, - .flags = IORESOURCE_MEM + .flags = IORESOURCE_SYSTEM_RAM }, { .name = "Kernel data", .start = 0, .end = 0, - .flags = IORESOURCE_MEM + .flags = IORESOURCE_SYSTEM_RAM } }; @@ -211,7 +211,7 @@ static void __init request_standard_resources(void) res->name = "System RAM"; res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region)); res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S index e33fe33876ab..fd10eb663868 100644 --- a/arch/arm64/kernel/sleep.S +++ b/arch/arm64/kernel/sleep.S @@ -145,6 +145,10 @@ ENTRY(cpu_resume_mmu) ENDPROC(cpu_resume_mmu) .popsection cpu_resume_after_mmu: +#ifdef CONFIG_KASAN + mov x0, sp + bl kasan_unpoison_remaining_stack +#endif mov x0, #0 // return zero on success ldp x19, x20, [sp, #16] ldp x21, x22, [sp, #32] diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index d07b19654307..b2d5f4ee9a1c 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -237,7 +237,7 @@ asmlinkage void secondary_start_kernel(void) /* * OK, it's off to the idle thread for us */ - cpu_startup_entry(CPUHP_ONLINE); + cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); } #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 4fad9787ab46..d9751a4769e7 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -44,14 +44,13 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) unsigned long irq_stack_ptr; /* - * Use raw_smp_processor_id() to avoid false-positives from - * CONFIG_DEBUG_PREEMPT. get_wchan() calls unwind_frame() on sleeping - * task stacks, we can be pre-empted in this case, so - * {raw_,}smp_processor_id() may give us the wrong value. Sleeping - * tasks can't ever be on an interrupt stack, so regardless of cpu, - * the checks will always fail. + * Switching between stacks is valid when tracing current and in + * non-preemptible context. */ - irq_stack_ptr = IRQ_STACK_PTR(raw_smp_processor_id()); + if (tsk == current && !preemptible()) + irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id()); + else + irq_stack_ptr = 0; low = frame->sp; /* irq stacks are not THREAD_SIZE aligned */ @@ -64,8 +63,8 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) return -EINVAL; frame->sp = fp + 0x10; - frame->fp = *(unsigned long *)(fp); - frame->pc = *(unsigned long *)(fp + 8); + frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp)); + frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8)); #ifdef CONFIG_FUNCTION_GRAPH_TRACER if (tsk && tsk->ret_stack && diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index cbedd724f48e..c5392081b49b 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -146,9 +146,18 @@ static void dump_instr(const char *lvl, struct pt_regs *regs) static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) { struct stackframe frame; - unsigned long irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id()); + unsigned long irq_stack_ptr; int skip; + /* + * Switching between stacks is valid when tracing current and in + * non-preemptible context. + */ + if (tsk == current && !preemptible()) + irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id()); + else + irq_stack_ptr = 0; + pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); if (!tsk) diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 4c56e7a0621b..37f624df68fa 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -135,6 +135,7 @@ SECTIONS CON_INITCALL SECURITY_INITCALL INIT_RAM_FS + *(.init.rodata.* .init.bss) /* from the EFI stub */ } .exit.data : { ARM_EXIT_KEEP(EXIT_DATA) diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index a5272c07d1cb..de7450df7629 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -36,6 +36,7 @@ config KVM select HAVE_KVM_EVENTFD select HAVE_KVM_IRQFD select KVM_ARM_VGIC_V3 + select KVM_ARM_PMU if HW_PERF_EVENTS ---help--- Support hosting virtualized guest machines. We don't support KVM with 16K page tables yet, due to the multiple @@ -48,6 +49,12 @@ config KVM_ARM_HOST ---help--- Provides host support for ARM processors. +config KVM_ARM_PMU + bool + ---help--- + Adds support for a virtual Performance Monitoring Unit (PMU) in + virtual machines. + source drivers/vhost/Kconfig endif # VIRTUALIZATION diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index caee9ee8e12a..122cff482ac4 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -26,3 +26,4 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v2-emul.o kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3.o kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3-emul.o kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o +kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index fcb778899a38..32fad75bb9ff 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -194,7 +194,7 @@ static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) u64 val; val = kvm_arm_timer_get_reg(vcpu, reg->id); - return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)); + return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0; } /** @@ -380,3 +380,54 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, } return 0; } + +int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) +{ + int ret; + + switch (attr->group) { + case KVM_ARM_VCPU_PMU_V3_CTRL: + ret = kvm_arm_pmu_v3_set_attr(vcpu, attr); + break; + default: + ret = -ENXIO; + break; + } + + return ret; +} + +int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) +{ + int ret; + + switch (attr->group) { + case KVM_ARM_VCPU_PMU_V3_CTRL: + ret = kvm_arm_pmu_v3_get_attr(vcpu, attr); + break; + default: + ret = -ENXIO; + break; + } + + return ret; +} + +int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu, + struct kvm_device_attr *attr) +{ + int ret; + + switch (attr->group) { + case KVM_ARM_VCPU_PMU_V3_CTRL: + ret = kvm_arm_pmu_v3_has_attr(vcpu, attr); + break; + default: + ret = -ENXIO; + break; + } + + return ret; +} diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S index 3e568dcd907b..7d8747c6427c 100644 --- a/arch/arm64/kvm/hyp-init.S +++ b/arch/arm64/kvm/hyp-init.S @@ -64,7 +64,7 @@ __do_hyp_init: mrs x4, tcr_el1 ldr x5, =TCR_EL2_MASK and x4, x4, x5 - ldr x5, =TCR_EL2_FLAGS + mov x5, #TCR_EL2_RES1 orr x4, x4, x5 #ifndef CONFIG_ARM64_VA_BITS_48 @@ -85,25 +85,14 @@ __do_hyp_init: ldr_l x5, idmap_t0sz bfi x4, x5, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH #endif - msr tcr_el2, x4 - - ldr x4, =VTCR_EL2_FLAGS /* * Read the PARange bits from ID_AA64MMFR0_EL1 and set the PS bits in - * VTCR_EL2. + * TCR_EL2. */ mrs x5, ID_AA64MMFR0_EL1 bfi x4, x5, #16, #3 - /* - * Read the VMIDBits bits from ID_AA64MMFR1_EL1 and set the VS bit in - * VTCR_EL2. - */ - mrs x5, ID_AA64MMFR1_EL1 - ubfx x5, x5, #5, #1 - lsl x5, x5, #VTCR_EL2_VS - orr x4, x4, x5 - msr vtcr_el2, x4 + msr tcr_el2, x4 mrs x4, mair_el1 msr mair_el2, x4 diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S index 870578f84b1c..48f19a37b3df 100644 --- a/arch/arm64/kvm/hyp.S +++ b/arch/arm64/kvm/hyp.S @@ -17,7 +17,9 @@ #include <linux/linkage.h> +#include <asm/alternative.h> #include <asm/assembler.h> +#include <asm/cpufeature.h> /* * u64 __kvm_call_hyp(void *hypfn, ...); @@ -38,6 +40,11 @@ * arch/arm64/kernel/hyp_stub.S. */ ENTRY(__kvm_call_hyp) +alternative_if_not ARM64_HAS_VIRT_HOST_EXTN hvc #0 ret +alternative_else + b __vhe_hyp_call + nop +alternative_endif ENDPROC(__kvm_call_hyp) diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile index 826032bc3945..778d0effa2af 100644 --- a/arch/arm64/kvm/hyp/Makefile +++ b/arch/arm64/kvm/hyp/Makefile @@ -2,9 +2,12 @@ # Makefile for Kernel-based Virtual Machine module, HYP part # -obj-$(CONFIG_KVM_ARM_HOST) += vgic-v2-sr.o +KVM=../../../../virt/kvm + +obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o +obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/timer-sr.o + obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o -obj-$(CONFIG_KVM_ARM_HOST) += timer-sr.o obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o obj-$(CONFIG_KVM_ARM_HOST) += entry.o @@ -12,3 +15,8 @@ obj-$(CONFIG_KVM_ARM_HOST) += switch.o obj-$(CONFIG_KVM_ARM_HOST) += fpsimd.o obj-$(CONFIG_KVM_ARM_HOST) += tlb.o obj-$(CONFIG_KVM_ARM_HOST) += hyp-entry.o +obj-$(CONFIG_KVM_ARM_HOST) += s2-setup.o + +GCOV_PROFILE := n +KASAN_SANITIZE := n +UBSAN_SANITIZE := n diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c index 2f8bca8af295..33342a776ec7 100644 --- a/arch/arm64/kvm/hyp/debug-sr.c +++ b/arch/arm64/kvm/hyp/debug-sr.c @@ -20,9 +20,7 @@ #include <asm/debug-monitors.h> #include <asm/kvm_asm.h> -#include <asm/kvm_mmu.h> - -#include "hyp.h" +#include <asm/kvm_hyp.h> #define read_debug(r,n) read_sysreg(r##n##_el1) #define write_debug(v,r,n) write_sysreg(v, r##n##_el1) diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S index fd0fbe9b7e6a..ce9e5e5f28cf 100644 --- a/arch/arm64/kvm/hyp/entry.S +++ b/arch/arm64/kvm/hyp/entry.S @@ -130,9 +130,15 @@ ENDPROC(__guest_exit) ENTRY(__fpsimd_guest_restore) stp x4, lr, [sp, #-16]! +alternative_if_not ARM64_HAS_VIRT_HOST_EXTN mrs x2, cptr_el2 bic x2, x2, #CPTR_EL2_TFP msr cptr_el2, x2 +alternative_else + mrs x2, cpacr_el1 + orr x2, x2, #CPACR_EL1_FPEN + msr cpacr_el1, x2 +alternative_endif isb mrs x3, tpidr_el2 diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S index 93e8d983c0bd..3488894397ff 100644 --- a/arch/arm64/kvm/hyp/hyp-entry.S +++ b/arch/arm64/kvm/hyp/hyp-entry.S @@ -19,7 +19,6 @@ #include <asm/alternative.h> #include <asm/assembler.h> -#include <asm/asm-offsets.h> #include <asm/cpufeature.h> #include <asm/kvm_arm.h> #include <asm/kvm_asm.h> @@ -38,10 +37,42 @@ ldp x0, x1, [sp], #16 .endm +.macro do_el2_call + /* + * Shuffle the parameters before calling the function + * pointed to in x0. Assumes parameters in x[1,2,3]. + */ + sub sp, sp, #16 + str lr, [sp] + mov lr, x0 + mov x0, x1 + mov x1, x2 + mov x2, x3 + blr lr + ldr lr, [sp] + add sp, sp, #16 +.endm + +ENTRY(__vhe_hyp_call) + do_el2_call + /* + * We used to rely on having an exception return to get + * an implicit isb. In the E2H case, we don't have it anymore. + * rather than changing all the leaf functions, just do it here + * before returning to the rest of the kernel. + */ + isb + ret +ENDPROC(__vhe_hyp_call) + el1_sync: // Guest trapped into EL2 save_x0_to_x3 +alternative_if_not ARM64_HAS_VIRT_HOST_EXTN mrs x1, esr_el2 +alternative_else + mrs x1, esr_el1 +alternative_endif lsr x2, x1, #ESR_ELx_EC_SHIFT cmp x2, #ESR_ELx_EC_HVC64 @@ -58,19 +89,13 @@ el1_sync: // Guest trapped into EL2 mrs x0, vbar_el2 b 2f -1: stp lr, xzr, [sp, #-16]! - +1: /* - * Compute the function address in EL2, and shuffle the parameters. + * Perform the EL2 call */ kern_hyp_va x0 - mov lr, x0 - mov x0, x1 - mov x1, x2 - mov x2, x3 - blr lr + do_el2_call - ldp lr, xzr, [sp], #16 2: eret el1_trap: @@ -83,72 +108,10 @@ el1_trap: cmp x2, #ESR_ELx_EC_FP_ASIMD b.eq __fpsimd_guest_restore - cmp x2, #ESR_ELx_EC_DABT_LOW - mov x0, #ESR_ELx_EC_IABT_LOW - ccmp x2, x0, #4, ne - b.ne 1f // Not an abort we care about - - /* This is an abort. Check for permission fault */ -alternative_if_not ARM64_WORKAROUND_834220 - and x2, x1, #ESR_ELx_FSC_TYPE - cmp x2, #FSC_PERM - b.ne 1f // Not a permission fault -alternative_else - nop // Use the permission fault path to - nop // check for a valid S1 translation, - nop // regardless of the ESR value. -alternative_endif - - /* - * Check for Stage-1 page table walk, which is guaranteed - * to give a valid HPFAR_EL2. - */ - tbnz x1, #7, 1f // S1PTW is set - - /* Preserve PAR_EL1 */ - mrs x3, par_el1 - stp x3, xzr, [sp, #-16]! - - /* - * Permission fault, HPFAR_EL2 is invalid. - * Resolve the IPA the hard way using the guest VA. - * Stage-1 translation already validated the memory access rights. - * As such, we can use the EL1 translation regime, and don't have - * to distinguish between EL0 and EL1 access. - */ - mrs x2, far_el2 - at s1e1r, x2 - isb - - /* Read result */ - mrs x3, par_el1 - ldp x0, xzr, [sp], #16 // Restore PAR_EL1 from the stack - msr par_el1, x0 - tbnz x3, #0, 3f // Bail out if we failed the translation - ubfx x3, x3, #12, #36 // Extract IPA - lsl x3, x3, #4 // and present it like HPFAR - b 2f - -1: mrs x3, hpfar_el2 - mrs x2, far_el2 - -2: mrs x0, tpidr_el2 - str w1, [x0, #VCPU_ESR_EL2] - str x2, [x0, #VCPU_FAR_EL2] - str x3, [x0, #VCPU_HPFAR_EL2] - + mrs x0, tpidr_el2 mov x1, #ARM_EXCEPTION_TRAP b __guest_exit - /* - * Translation failed. Just return to the guest and - * let it fault again. Another CPU is probably playing - * behind our back. - */ -3: restore_x0_to_x3 - - eret - el1_irq: save_x0_to_x3 mrs x0, tpidr_el2 diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h deleted file mode 100644 index fb275178b6af..000000000000 --- a/arch/arm64/kvm/hyp/hyp.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2015 - ARM Ltd - * Author: Marc Zyngier <marc.zyngier@arm.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 __ARM64_KVM_HYP_H__ -#define __ARM64_KVM_HYP_H__ - -#include <linux/compiler.h> -#include <linux/kvm_host.h> -#include <asm/kvm_mmu.h> -#include <asm/sysreg.h> - -#define __hyp_text __section(.hyp.text) notrace - -#define kern_hyp_va(v) (typeof(v))((unsigned long)(v) & HYP_PAGE_OFFSET_MASK) -#define hyp_kern_va(v) (typeof(v))((unsigned long)(v) - HYP_PAGE_OFFSET \ - + PAGE_OFFSET) - -/** - * hyp_alternate_select - Generates patchable code sequences that are - * used to switch between two implementations of a function, depending - * on the availability of a feature. - * - * @fname: a symbol name that will be defined as a function returning a - * function pointer whose type will match @orig and @alt - * @orig: A pointer to the default function, as returned by @fname when - * @cond doesn't hold - * @alt: A pointer to the alternate function, as returned by @fname - * when @cond holds - * @cond: a CPU feature (as described in asm/cpufeature.h) - */ -#define hyp_alternate_select(fname, orig, alt, cond) \ -typeof(orig) * __hyp_text fname(void) \ -{ \ - typeof(alt) *val = orig; \ - asm volatile(ALTERNATIVE("nop \n", \ - "mov %0, %1 \n", \ - cond) \ - : "+r" (val) : "r" (alt)); \ - return val; \ -} - -void __vgic_v2_save_state(struct kvm_vcpu *vcpu); -void __vgic_v2_restore_state(struct kvm_vcpu *vcpu); - -void __vgic_v3_save_state(struct kvm_vcpu *vcpu); -void __vgic_v3_restore_state(struct kvm_vcpu *vcpu); - -void __timer_save_state(struct kvm_vcpu *vcpu); -void __timer_restore_state(struct kvm_vcpu *vcpu); - -void __sysreg_save_state(struct kvm_cpu_context *ctxt); -void __sysreg_restore_state(struct kvm_cpu_context *ctxt); -void __sysreg32_save_state(struct kvm_vcpu *vcpu); -void __sysreg32_restore_state(struct kvm_vcpu *vcpu); - -void __debug_save_state(struct kvm_vcpu *vcpu, - struct kvm_guest_debug_arch *dbg, - struct kvm_cpu_context *ctxt); -void __debug_restore_state(struct kvm_vcpu *vcpu, - struct kvm_guest_debug_arch *dbg, - struct kvm_cpu_context *ctxt); -void __debug_cond_save_host_state(struct kvm_vcpu *vcpu); -void __debug_cond_restore_host_state(struct kvm_vcpu *vcpu); - -void __fpsimd_save_state(struct user_fpsimd_state *fp_regs); -void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs); -static inline bool __fpsimd_enabled(void) -{ - return !(read_sysreg(cptr_el2) & CPTR_EL2_TFP); -} - -u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt); -void __noreturn __hyp_do_panic(unsigned long, ...); - -#endif /* __ARM64_KVM_HYP_H__ */ - diff --git a/arch/arm64/kvm/hyp/s2-setup.c b/arch/arm64/kvm/hyp/s2-setup.c new file mode 100644 index 000000000000..bfc54fd82797 --- /dev/null +++ b/arch/arm64/kvm/hyp/s2-setup.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 - ARM Ltd + * Author: Marc Zyngier <marc.zyngier@arm.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/types.h> +#include <asm/kvm_arm.h> +#include <asm/kvm_asm.h> +#include <asm/kvm_hyp.h> + +void __hyp_text __init_stage2_translation(void) +{ + u64 val = VTCR_EL2_FLAGS; + u64 tmp; + + /* + * Read the PARange bits from ID_AA64MMFR0_EL1 and set the PS + * bits in VTCR_EL2. Amusingly, the PARange is 4 bits, while + * PS is only 3. Fortunately, bit 19 is RES0 in VTCR_EL2... + */ + val |= (read_sysreg(id_aa64mmfr0_el1) & 7) << 16; + + /* + * Read the VMIDBits bits from ID_AA64MMFR1_EL1 and set the VS + * bit in VTCR_EL2. + */ + tmp = (read_sysreg(id_aa64mmfr1_el1) >> 4) & 0xf; + val |= (tmp == 2) ? VTCR_EL2_VS : 0; + + write_sysreg(val, vtcr_el2); +} diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c index f0e7bdfae134..437cfad5e3d8 100644 --- a/arch/arm64/kvm/hyp/switch.c +++ b/arch/arm64/kvm/hyp/switch.c @@ -15,7 +15,53 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "hyp.h" +#include <linux/types.h> +#include <asm/kvm_asm.h> +#include <asm/kvm_hyp.h> + +static bool __hyp_text __fpsimd_enabled_nvhe(void) +{ + return !(read_sysreg(cptr_el2) & CPTR_EL2_TFP); +} + +static bool __hyp_text __fpsimd_enabled_vhe(void) +{ + return !!(read_sysreg(cpacr_el1) & CPACR_EL1_FPEN); +} + +static hyp_alternate_select(__fpsimd_is_enabled, + __fpsimd_enabled_nvhe, __fpsimd_enabled_vhe, + ARM64_HAS_VIRT_HOST_EXTN); + +bool __hyp_text __fpsimd_enabled(void) +{ + return __fpsimd_is_enabled()(); +} + +static void __hyp_text __activate_traps_vhe(void) +{ + u64 val; + + val = read_sysreg(cpacr_el1); + val |= CPACR_EL1_TTA; + val &= ~CPACR_EL1_FPEN; + write_sysreg(val, cpacr_el1); + + write_sysreg(__kvm_hyp_vector, vbar_el1); +} + +static void __hyp_text __activate_traps_nvhe(void) +{ + u64 val; + + val = CPTR_EL2_DEFAULT; + val |= CPTR_EL2_TTA | CPTR_EL2_TFP; + write_sysreg(val, cptr_el2); +} + +static hyp_alternate_select(__activate_traps_arch, + __activate_traps_nvhe, __activate_traps_vhe, + ARM64_HAS_VIRT_HOST_EXTN); static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu) { @@ -36,20 +82,37 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu) write_sysreg(val, hcr_el2); /* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */ write_sysreg(1 << 15, hstr_el2); + /* Make sure we trap PMU access from EL0 to EL2 */ + write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0); + write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); + __activate_traps_arch()(); +} - val = CPTR_EL2_DEFAULT; - val |= CPTR_EL2_TTA | CPTR_EL2_TFP; - write_sysreg(val, cptr_el2); +static void __hyp_text __deactivate_traps_vhe(void) +{ + extern char vectors[]; /* kernel exception vectors */ - write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); + write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2); + write_sysreg(CPACR_EL1_FPEN, cpacr_el1); + write_sysreg(vectors, vbar_el1); } -static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu) +static void __hyp_text __deactivate_traps_nvhe(void) { write_sysreg(HCR_RW, hcr_el2); + write_sysreg(CPTR_EL2_DEFAULT, cptr_el2); +} + +static hyp_alternate_select(__deactivate_traps_arch, + __deactivate_traps_nvhe, __deactivate_traps_vhe, + ARM64_HAS_VIRT_HOST_EXTN); + +static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu) +{ + __deactivate_traps_arch()(); write_sysreg(0, hstr_el2); write_sysreg(read_sysreg(mdcr_el2) & MDCR_EL2_HPMN_MASK, mdcr_el2); - write_sysreg(CPTR_EL2_DEFAULT, cptr_el2); + write_sysreg(0, pmuserenr_el0); } static void __hyp_text __activate_vm(struct kvm_vcpu *vcpu) @@ -89,6 +152,86 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu) __vgic_call_restore_state()(vcpu); } +static bool __hyp_text __true_value(void) +{ + return true; +} + +static bool __hyp_text __false_value(void) +{ + return false; +} + +static hyp_alternate_select(__check_arm_834220, + __false_value, __true_value, + ARM64_WORKAROUND_834220); + +static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar) +{ + u64 par, tmp; + + /* + * Resolve the IPA the hard way using the guest VA. + * + * Stage-1 translation already validated the memory access + * rights. As such, we can use the EL1 translation regime, and + * don't have to distinguish between EL0 and EL1 access. + * + * We do need to save/restore PAR_EL1 though, as we haven't + * saved the guest context yet, and we may return early... + */ + par = read_sysreg(par_el1); + asm volatile("at s1e1r, %0" : : "r" (far)); + isb(); + + tmp = read_sysreg(par_el1); + write_sysreg(par, par_el1); + + if (unlikely(tmp & 1)) + return false; /* Translation failed, back to guest */ + + /* Convert PAR to HPFAR format */ + *hpfar = ((tmp >> 12) & ((1UL << 36) - 1)) << 4; + return true; +} + +static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu) +{ + u64 esr = read_sysreg_el2(esr); + u8 ec = esr >> ESR_ELx_EC_SHIFT; + u64 hpfar, far; + + vcpu->arch.fault.esr_el2 = esr; + + if (ec != ESR_ELx_EC_DABT_LOW && ec != ESR_ELx_EC_IABT_LOW) + return true; + + far = read_sysreg_el2(far); + + /* + * The HPFAR can be invalid if the stage 2 fault did not + * happen during a stage 1 page table walk (the ESR_EL2.S1PTW + * bit is clear) and one of the two following cases are true: + * 1. The fault was due to a permission fault + * 2. The processor carries errata 834220 + * + * Therefore, for all non S1PTW faults where we either have a + * permission fault or the errata workaround is enabled, we + * resolve the IPA using the AT instruction. + */ + if (!(esr & ESR_ELx_S1PTW) && + (__check_arm_834220()() || (esr & ESR_ELx_FSC_TYPE) == FSC_PERM)) { + if (!__translate_far_to_hpfar(far, &hpfar)) + return false; + } else { + hpfar = read_sysreg(hpfar_el2); + } + + vcpu->arch.fault.far_el2 = far; + vcpu->arch.fault.hpfar_el2 = hpfar; + return true; +} + static int __hyp_text __guest_run(struct kvm_vcpu *vcpu) { struct kvm_cpu_context *host_ctxt; @@ -102,7 +245,7 @@ static int __hyp_text __guest_run(struct kvm_vcpu *vcpu) host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context); guest_ctxt = &vcpu->arch.ctxt; - __sysreg_save_state(host_ctxt); + __sysreg_save_host_state(host_ctxt); __debug_cond_save_host_state(vcpu); __activate_traps(vcpu); @@ -116,16 +259,20 @@ static int __hyp_text __guest_run(struct kvm_vcpu *vcpu) * to Cortex-A57 erratum #852523. */ __sysreg32_restore_state(vcpu); - __sysreg_restore_state(guest_ctxt); + __sysreg_restore_guest_state(guest_ctxt); __debug_restore_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), guest_ctxt); /* Jump in the fire! */ +again: exit_code = __guest_enter(vcpu, host_ctxt); /* And we're baaack! */ + if (exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu)) + goto again; + fp_enabled = __fpsimd_enabled(); - __sysreg_save_state(guest_ctxt); + __sysreg_save_guest_state(guest_ctxt); __sysreg32_save_state(vcpu); __timer_save_state(vcpu); __vgic_save_state(vcpu); @@ -133,7 +280,7 @@ static int __hyp_text __guest_run(struct kvm_vcpu *vcpu) __deactivate_traps(vcpu); __deactivate_vm(vcpu); - __sysreg_restore_state(host_ctxt); + __sysreg_restore_host_state(host_ctxt); if (fp_enabled) { __fpsimd_save_state(&guest_ctxt->gp_regs.fp_regs); @@ -150,11 +297,34 @@ __alias(__guest_run) int __kvm_vcpu_run(struct kvm_vcpu *vcpu); static const char __hyp_panic_string[] = "HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%p\n"; -void __hyp_text __noreturn __hyp_panic(void) +static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par) { unsigned long str_va = (unsigned long)__hyp_panic_string; - u64 spsr = read_sysreg(spsr_el2); - u64 elr = read_sysreg(elr_el2); + + __hyp_do_panic(hyp_kern_va(str_va), + spsr, elr, + read_sysreg(esr_el2), read_sysreg_el2(far), + read_sysreg(hpfar_el2), par, + (void *)read_sysreg(tpidr_el2)); +} + +static void __hyp_text __hyp_call_panic_vhe(u64 spsr, u64 elr, u64 par) +{ + panic(__hyp_panic_string, + spsr, elr, + read_sysreg_el2(esr), read_sysreg_el2(far), + read_sysreg(hpfar_el2), par, + (void *)read_sysreg(tpidr_el2)); +} + +static hyp_alternate_select(__hyp_call_panic, + __hyp_call_panic_nvhe, __hyp_call_panic_vhe, + ARM64_HAS_VIRT_HOST_EXTN); + +void __hyp_text __noreturn __hyp_panic(void) +{ + u64 spsr = read_sysreg_el2(spsr); + u64 elr = read_sysreg_el2(elr); u64 par = read_sysreg(par_el1); if (read_sysreg(vttbr_el2)) { @@ -165,15 +335,11 @@ void __hyp_text __noreturn __hyp_panic(void) host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context); __deactivate_traps(vcpu); __deactivate_vm(vcpu); - __sysreg_restore_state(host_ctxt); + __sysreg_restore_host_state(host_ctxt); } /* Call panic for real */ - __hyp_do_panic(hyp_kern_va(str_va), - spsr, elr, - read_sysreg(esr_el2), read_sysreg(far_el2), - read_sysreg(hpfar_el2), par, - (void *)read_sysreg(tpidr_el2)); + __hyp_call_panic()(spsr, elr, par); unreachable(); } diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c index 425630980229..0f7c40eb3f53 100644 --- a/arch/arm64/kvm/hyp/sysreg-sr.c +++ b/arch/arm64/kvm/hyp/sysreg-sr.c @@ -19,75 +19,122 @@ #include <linux/kvm_host.h> #include <asm/kvm_asm.h> -#include <asm/kvm_mmu.h> +#include <asm/kvm_hyp.h> -#include "hyp.h" +/* Yes, this does nothing, on purpose */ +static void __hyp_text __sysreg_do_nothing(struct kvm_cpu_context *ctxt) { } -/* ctxt is already in the HYP VA space */ -void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt) +/* + * Non-VHE: Both host and guest must save everything. + * + * VHE: Host must save tpidr*_el[01], actlr_el1, sp0, pc, pstate, and + * guest must save everything. + */ + +static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt) { - ctxt->sys_regs[MPIDR_EL1] = read_sysreg(vmpidr_el2); - ctxt->sys_regs[CSSELR_EL1] = read_sysreg(csselr_el1); - ctxt->sys_regs[SCTLR_EL1] = read_sysreg(sctlr_el1); ctxt->sys_regs[ACTLR_EL1] = read_sysreg(actlr_el1); - ctxt->sys_regs[CPACR_EL1] = read_sysreg(cpacr_el1); - ctxt->sys_regs[TTBR0_EL1] = read_sysreg(ttbr0_el1); - ctxt->sys_regs[TTBR1_EL1] = read_sysreg(ttbr1_el1); - ctxt->sys_regs[TCR_EL1] = read_sysreg(tcr_el1); - ctxt->sys_regs[ESR_EL1] = read_sysreg(esr_el1); - ctxt->sys_regs[AFSR0_EL1] = read_sysreg(afsr0_el1); - ctxt->sys_regs[AFSR1_EL1] = read_sysreg(afsr1_el1); - ctxt->sys_regs[FAR_EL1] = read_sysreg(far_el1); - ctxt->sys_regs[MAIR_EL1] = read_sysreg(mair_el1); - ctxt->sys_regs[VBAR_EL1] = read_sysreg(vbar_el1); - ctxt->sys_regs[CONTEXTIDR_EL1] = read_sysreg(contextidr_el1); ctxt->sys_regs[TPIDR_EL0] = read_sysreg(tpidr_el0); ctxt->sys_regs[TPIDRRO_EL0] = read_sysreg(tpidrro_el0); ctxt->sys_regs[TPIDR_EL1] = read_sysreg(tpidr_el1); - ctxt->sys_regs[AMAIR_EL1] = read_sysreg(amair_el1); - ctxt->sys_regs[CNTKCTL_EL1] = read_sysreg(cntkctl_el1); + ctxt->gp_regs.regs.sp = read_sysreg(sp_el0); + ctxt->gp_regs.regs.pc = read_sysreg_el2(elr); + ctxt->gp_regs.regs.pstate = read_sysreg_el2(spsr); +} + +static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt) +{ + ctxt->sys_regs[MPIDR_EL1] = read_sysreg(vmpidr_el2); + ctxt->sys_regs[CSSELR_EL1] = read_sysreg(csselr_el1); + ctxt->sys_regs[SCTLR_EL1] = read_sysreg_el1(sctlr); + ctxt->sys_regs[CPACR_EL1] = read_sysreg_el1(cpacr); + ctxt->sys_regs[TTBR0_EL1] = read_sysreg_el1(ttbr0); + ctxt->sys_regs[TTBR1_EL1] = read_sysreg_el1(ttbr1); + ctxt->sys_regs[TCR_EL1] = read_sysreg_el1(tcr); + ctxt->sys_regs[ESR_EL1] = read_sysreg_el1(esr); + ctxt->sys_regs[AFSR0_EL1] = read_sysreg_el1(afsr0); + ctxt->sys_regs[AFSR1_EL1] = read_sysreg_el1(afsr1); + ctxt->sys_regs[FAR_EL1] = read_sysreg_el1(far); + ctxt->sys_regs[MAIR_EL1] = read_sysreg_el1(mair); + ctxt->sys_regs[VBAR_EL1] = read_sysreg_el1(vbar); + ctxt->sys_regs[CONTEXTIDR_EL1] = read_sysreg_el1(contextidr); + ctxt->sys_regs[AMAIR_EL1] = read_sysreg_el1(amair); + ctxt->sys_regs[CNTKCTL_EL1] = read_sysreg_el1(cntkctl); ctxt->sys_regs[PAR_EL1] = read_sysreg(par_el1); ctxt->sys_regs[MDSCR_EL1] = read_sysreg(mdscr_el1); - ctxt->gp_regs.regs.sp = read_sysreg(sp_el0); - ctxt->gp_regs.regs.pc = read_sysreg(elr_el2); - ctxt->gp_regs.regs.pstate = read_sysreg(spsr_el2); ctxt->gp_regs.sp_el1 = read_sysreg(sp_el1); - ctxt->gp_regs.elr_el1 = read_sysreg(elr_el1); - ctxt->gp_regs.spsr[KVM_SPSR_EL1]= read_sysreg(spsr_el1); + ctxt->gp_regs.elr_el1 = read_sysreg_el1(elr); + ctxt->gp_regs.spsr[KVM_SPSR_EL1]= read_sysreg_el1(spsr); +} + +static hyp_alternate_select(__sysreg_call_save_host_state, + __sysreg_save_state, __sysreg_do_nothing, + ARM64_HAS_VIRT_HOST_EXTN); + +void __hyp_text __sysreg_save_host_state(struct kvm_cpu_context *ctxt) +{ + __sysreg_call_save_host_state()(ctxt); + __sysreg_save_common_state(ctxt); +} + +void __hyp_text __sysreg_save_guest_state(struct kvm_cpu_context *ctxt) +{ + __sysreg_save_state(ctxt); + __sysreg_save_common_state(ctxt); } -void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt) +static void __hyp_text __sysreg_restore_common_state(struct kvm_cpu_context *ctxt) { - write_sysreg(ctxt->sys_regs[MPIDR_EL1], vmpidr_el2); - write_sysreg(ctxt->sys_regs[CSSELR_EL1], csselr_el1); - write_sysreg(ctxt->sys_regs[SCTLR_EL1], sctlr_el1); write_sysreg(ctxt->sys_regs[ACTLR_EL1], actlr_el1); - write_sysreg(ctxt->sys_regs[CPACR_EL1], cpacr_el1); - write_sysreg(ctxt->sys_regs[TTBR0_EL1], ttbr0_el1); - write_sysreg(ctxt->sys_regs[TTBR1_EL1], ttbr1_el1); - write_sysreg(ctxt->sys_regs[TCR_EL1], tcr_el1); - write_sysreg(ctxt->sys_regs[ESR_EL1], esr_el1); - write_sysreg(ctxt->sys_regs[AFSR0_EL1], afsr0_el1); - write_sysreg(ctxt->sys_regs[AFSR1_EL1], afsr1_el1); - write_sysreg(ctxt->sys_regs[FAR_EL1], far_el1); - write_sysreg(ctxt->sys_regs[MAIR_EL1], mair_el1); - write_sysreg(ctxt->sys_regs[VBAR_EL1], vbar_el1); - write_sysreg(ctxt->sys_regs[CONTEXTIDR_EL1], contextidr_el1); write_sysreg(ctxt->sys_regs[TPIDR_EL0], tpidr_el0); write_sysreg(ctxt->sys_regs[TPIDRRO_EL0], tpidrro_el0); write_sysreg(ctxt->sys_regs[TPIDR_EL1], tpidr_el1); - write_sysreg(ctxt->sys_regs[AMAIR_EL1], amair_el1); - write_sysreg(ctxt->sys_regs[CNTKCTL_EL1], cntkctl_el1); - write_sysreg(ctxt->sys_regs[PAR_EL1], par_el1); - write_sysreg(ctxt->sys_regs[MDSCR_EL1], mdscr_el1); - - write_sysreg(ctxt->gp_regs.regs.sp, sp_el0); - write_sysreg(ctxt->gp_regs.regs.pc, elr_el2); - write_sysreg(ctxt->gp_regs.regs.pstate, spsr_el2); - write_sysreg(ctxt->gp_regs.sp_el1, sp_el1); - write_sysreg(ctxt->gp_regs.elr_el1, elr_el1); - write_sysreg(ctxt->gp_regs.spsr[KVM_SPSR_EL1], spsr_el1); + write_sysreg(ctxt->gp_regs.regs.sp, sp_el0); + write_sysreg_el2(ctxt->gp_regs.regs.pc, elr); + write_sysreg_el2(ctxt->gp_regs.regs.pstate, spsr); +} + +static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt) +{ + write_sysreg(ctxt->sys_regs[MPIDR_EL1], vmpidr_el2); + write_sysreg(ctxt->sys_regs[CSSELR_EL1], csselr_el1); + write_sysreg_el1(ctxt->sys_regs[SCTLR_EL1], sctlr); + write_sysreg_el1(ctxt->sys_regs[CPACR_EL1], cpacr); + write_sysreg_el1(ctxt->sys_regs[TTBR0_EL1], ttbr0); + write_sysreg_el1(ctxt->sys_regs[TTBR1_EL1], ttbr1); + write_sysreg_el1(ctxt->sys_regs[TCR_EL1], tcr); + write_sysreg_el1(ctxt->sys_regs[ESR_EL1], esr); + write_sysreg_el1(ctxt->sys_regs[AFSR0_EL1], afsr0); + write_sysreg_el1(ctxt->sys_regs[AFSR1_EL1], afsr1); + write_sysreg_el1(ctxt->sys_regs[FAR_EL1], far); + write_sysreg_el1(ctxt->sys_regs[MAIR_EL1], mair); + write_sysreg_el1(ctxt->sys_regs[VBAR_EL1], vbar); + write_sysreg_el1(ctxt->sys_regs[CONTEXTIDR_EL1],contextidr); + write_sysreg_el1(ctxt->sys_regs[AMAIR_EL1], amair); + write_sysreg_el1(ctxt->sys_regs[CNTKCTL_EL1], cntkctl); + write_sysreg(ctxt->sys_regs[PAR_EL1], par_el1); + write_sysreg(ctxt->sys_regs[MDSCR_EL1], mdscr_el1); + + write_sysreg(ctxt->gp_regs.sp_el1, sp_el1); + write_sysreg_el1(ctxt->gp_regs.elr_el1, elr); + write_sysreg_el1(ctxt->gp_regs.spsr[KVM_SPSR_EL1],spsr); +} + +static hyp_alternate_select(__sysreg_call_restore_host_state, + __sysreg_restore_state, __sysreg_do_nothing, + ARM64_HAS_VIRT_HOST_EXTN); + +void __hyp_text __sysreg_restore_host_state(struct kvm_cpu_context *ctxt) +{ + __sysreg_call_restore_host_state()(ctxt); + __sysreg_restore_common_state(ctxt); +} + +void __hyp_text __sysreg_restore_guest_state(struct kvm_cpu_context *ctxt) +{ + __sysreg_restore_state(ctxt); + __sysreg_restore_common_state(ctxt); } void __hyp_text __sysreg32_save_state(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/kvm/hyp/timer-sr.c b/arch/arm64/kvm/hyp/timer-sr.c deleted file mode 100644 index 1051e5d7320f..000000000000 --- a/arch/arm64/kvm/hyp/timer-sr.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2012-2015 - ARM Ltd - * Author: Marc Zyngier <marc.zyngier@arm.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 <clocksource/arm_arch_timer.h> -#include <linux/compiler.h> -#include <linux/kvm_host.h> - -#include <asm/kvm_mmu.h> - -#include "hyp.h" - -/* vcpu is already in the HYP VA space */ -void __hyp_text __timer_save_state(struct kvm_vcpu *vcpu) -{ - struct kvm *kvm = kern_hyp_va(vcpu->kvm); - struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; - u64 val; - - if (kvm->arch.timer.enabled) { - timer->cntv_ctl = read_sysreg(cntv_ctl_el0); - timer->cntv_cval = read_sysreg(cntv_cval_el0); - } - - /* Disable the virtual timer */ - write_sysreg(0, cntv_ctl_el0); - - /* Allow physical timer/counter access for the host */ - val = read_sysreg(cnthctl_el2); - val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN; - write_sysreg(val, cnthctl_el2); - - /* Clear cntvoff for the host */ - write_sysreg(0, cntvoff_el2); -} - -void __hyp_text __timer_restore_state(struct kvm_vcpu *vcpu) -{ - struct kvm *kvm = kern_hyp_va(vcpu->kvm); - struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; - u64 val; - - /* - * Disallow physical timer access for the guest - * Physical counter access is allowed - */ - val = read_sysreg(cnthctl_el2); - val &= ~CNTHCTL_EL1PCEN; - val |= CNTHCTL_EL1PCTEN; - write_sysreg(val, cnthctl_el2); - - if (kvm->arch.timer.enabled) { - write_sysreg(kvm->arch.timer.cntvoff, cntvoff_el2); - write_sysreg(timer->cntv_cval, cntv_cval_el0); - isb(); - write_sysreg(timer->cntv_ctl, cntv_ctl_el0); - } -} diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c index 2a7e0d838698..be8177cdd3bf 100644 --- a/arch/arm64/kvm/hyp/tlb.c +++ b/arch/arm64/kvm/hyp/tlb.c @@ -15,7 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "hyp.h" +#include <asm/kvm_hyp.h> static void __hyp_text __tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) { diff --git a/arch/arm64/kvm/hyp/vgic-v2-sr.c b/arch/arm64/kvm/hyp/vgic-v2-sr.c deleted file mode 100644 index e71761238cfc..000000000000 --- a/arch/arm64/kvm/hyp/vgic-v2-sr.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2012-2015 - ARM Ltd - * Author: Marc Zyngier <marc.zyngier@arm.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/compiler.h> -#include <linux/irqchip/arm-gic.h> -#include <linux/kvm_host.h> - -#include <asm/kvm_mmu.h> - -#include "hyp.h" - -/* vcpu is already in the HYP VA space */ -void __hyp_text __vgic_v2_save_state(struct kvm_vcpu *vcpu) -{ - struct kvm *kvm = kern_hyp_va(vcpu->kvm); - struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; - struct vgic_dist *vgic = &kvm->arch.vgic; - void __iomem *base = kern_hyp_va(vgic->vctrl_base); - u32 eisr0, eisr1, elrsr0, elrsr1; - int i, nr_lr; - - if (!base) - return; - - nr_lr = vcpu->arch.vgic_cpu.nr_lr; - cpu_if->vgic_vmcr = readl_relaxed(base + GICH_VMCR); - cpu_if->vgic_misr = readl_relaxed(base + GICH_MISR); - eisr0 = readl_relaxed(base + GICH_EISR0); - elrsr0 = readl_relaxed(base + GICH_ELRSR0); - if (unlikely(nr_lr > 32)) { - eisr1 = readl_relaxed(base + GICH_EISR1); - elrsr1 = readl_relaxed(base + GICH_ELRSR1); - } else { - eisr1 = elrsr1 = 0; - } -#ifdef CONFIG_CPU_BIG_ENDIAN - cpu_if->vgic_eisr = ((u64)eisr0 << 32) | eisr1; - cpu_if->vgic_elrsr = ((u64)elrsr0 << 32) | elrsr1; -#else - cpu_if->vgic_eisr = ((u64)eisr1 << 32) | eisr0; - cpu_if->vgic_elrsr = ((u64)elrsr1 << 32) | elrsr0; -#endif - cpu_if->vgic_apr = readl_relaxed(base + GICH_APR); - - writel_relaxed(0, base + GICH_HCR); - - for (i = 0; i < nr_lr; i++) - cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4)); -} - -/* vcpu is already in the HYP VA space */ -void __hyp_text __vgic_v2_restore_state(struct kvm_vcpu *vcpu) -{ - struct kvm *kvm = kern_hyp_va(vcpu->kvm); - struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; - struct vgic_dist *vgic = &kvm->arch.vgic; - void __iomem *base = kern_hyp_va(vgic->vctrl_base); - int i, nr_lr; - - if (!base) - return; - - writel_relaxed(cpu_if->vgic_hcr, base + GICH_HCR); - writel_relaxed(cpu_if->vgic_vmcr, base + GICH_VMCR); - writel_relaxed(cpu_if->vgic_apr, base + GICH_APR); - - nr_lr = vcpu->arch.vgic_cpu.nr_lr; - for (i = 0; i < nr_lr; i++) - writel_relaxed(cpu_if->vgic_lr[i], base + GICH_LR0 + (i * 4)); -} diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c index 9142e082f5f3..fff7cd42b3a3 100644 --- a/arch/arm64/kvm/hyp/vgic-v3-sr.c +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c @@ -19,9 +19,7 @@ #include <linux/irqchip/arm-gic-v3.h> #include <linux/kvm_host.h> -#include <asm/kvm_mmu.h> - -#include "hyp.h" +#include <asm/kvm_hyp.h> #define vtr_to_max_lr_idx(v) ((v) & 0xf) #define vtr_to_nr_pri_bits(v) (((u32)(v) >> 29) + 1) @@ -39,12 +37,133 @@ asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\ } while (0) -/* vcpu is already in the HYP VA space */ +static u64 __hyp_text __gic_v3_get_lr(unsigned int lr) +{ + switch (lr & 0xf) { + case 0: + return read_gicreg(ICH_LR0_EL2); + case 1: + return read_gicreg(ICH_LR1_EL2); + case 2: + return read_gicreg(ICH_LR2_EL2); + case 3: + return read_gicreg(ICH_LR3_EL2); + case 4: + return read_gicreg(ICH_LR4_EL2); + case 5: + return read_gicreg(ICH_LR5_EL2); + case 6: + return read_gicreg(ICH_LR6_EL2); + case 7: + return read_gicreg(ICH_LR7_EL2); + case 8: + return read_gicreg(ICH_LR8_EL2); + case 9: + return read_gicreg(ICH_LR9_EL2); + case 10: + return read_gicreg(ICH_LR10_EL2); + case 11: + return read_gicreg(ICH_LR11_EL2); + case 12: + return read_gicreg(ICH_LR12_EL2); + case 13: + return read_gicreg(ICH_LR13_EL2); + case 14: + return read_gicreg(ICH_LR14_EL2); + case 15: + return read_gicreg(ICH_LR15_EL2); + } + + unreachable(); +} + +static void __hyp_text __gic_v3_set_lr(u64 val, int lr) +{ + switch (lr & 0xf) { + case 0: + write_gicreg(val, ICH_LR0_EL2); + break; + case 1: + write_gicreg(val, ICH_LR1_EL2); + break; + case 2: + write_gicreg(val, ICH_LR2_EL2); + break; + case 3: + write_gicreg(val, ICH_LR3_EL2); + break; + case 4: + write_gicreg(val, ICH_LR4_EL2); + break; + case 5: + write_gicreg(val, ICH_LR5_EL2); + break; + case 6: + write_gicreg(val, ICH_LR6_EL2); + break; + case 7: + write_gicreg(val, ICH_LR7_EL2); + break; + case 8: + write_gicreg(val, ICH_LR8_EL2); + break; + case 9: + write_gicreg(val, ICH_LR9_EL2); + break; + case 10: + write_gicreg(val, ICH_LR10_EL2); + break; + case 11: + write_gicreg(val, ICH_LR11_EL2); + break; + case 12: + write_gicreg(val, ICH_LR12_EL2); + break; + case 13: + write_gicreg(val, ICH_LR13_EL2); + break; + case 14: + write_gicreg(val, ICH_LR14_EL2); + break; + case 15: + write_gicreg(val, ICH_LR15_EL2); + break; + } +} + +static void __hyp_text save_maint_int_state(struct kvm_vcpu *vcpu, int nr_lr) +{ + struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; + int i; + bool expect_mi; + + expect_mi = !!(cpu_if->vgic_hcr & ICH_HCR_UIE); + + for (i = 0; i < nr_lr; i++) { + if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i))) + continue; + + expect_mi |= (!(cpu_if->vgic_lr[i] & ICH_LR_HW) && + (cpu_if->vgic_lr[i] & ICH_LR_EOI)); + } + + if (expect_mi) { + cpu_if->vgic_misr = read_gicreg(ICH_MISR_EL2); + + if (cpu_if->vgic_misr & ICH_MISR_EOI) + cpu_if->vgic_eisr = read_gicreg(ICH_EISR_EL2); + else + cpu_if->vgic_eisr = 0; + } else { + cpu_if->vgic_misr = 0; + cpu_if->vgic_eisr = 0; + } +} + void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu) { struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; u64 val; - u32 max_lr_idx, nr_pri_bits; /* * Make sure stores to the GIC via the memory mapped interface @@ -53,68 +172,66 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu) dsb(st); cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2); - cpu_if->vgic_misr = read_gicreg(ICH_MISR_EL2); - cpu_if->vgic_eisr = read_gicreg(ICH_EISR_EL2); - cpu_if->vgic_elrsr = read_gicreg(ICH_ELSR_EL2); - write_gicreg(0, ICH_HCR_EL2); - val = read_gicreg(ICH_VTR_EL2); - max_lr_idx = vtr_to_max_lr_idx(val); - nr_pri_bits = vtr_to_nr_pri_bits(val); + if (vcpu->arch.vgic_cpu.live_lrs) { + int i; + u32 max_lr_idx, nr_pri_bits; - switch (max_lr_idx) { - case 15: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(15)] = read_gicreg(ICH_LR15_EL2); - case 14: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(14)] = read_gicreg(ICH_LR14_EL2); - case 13: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(13)] = read_gicreg(ICH_LR13_EL2); - case 12: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(12)] = read_gicreg(ICH_LR12_EL2); - case 11: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(11)] = read_gicreg(ICH_LR11_EL2); - case 10: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(10)] = read_gicreg(ICH_LR10_EL2); - case 9: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(9)] = read_gicreg(ICH_LR9_EL2); - case 8: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(8)] = read_gicreg(ICH_LR8_EL2); - case 7: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(7)] = read_gicreg(ICH_LR7_EL2); - case 6: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(6)] = read_gicreg(ICH_LR6_EL2); - case 5: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(5)] = read_gicreg(ICH_LR5_EL2); - case 4: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(4)] = read_gicreg(ICH_LR4_EL2); - case 3: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(3)] = read_gicreg(ICH_LR3_EL2); - case 2: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(2)] = read_gicreg(ICH_LR2_EL2); - case 1: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(1)] = read_gicreg(ICH_LR1_EL2); - case 0: - cpu_if->vgic_lr[VGIC_V3_LR_INDEX(0)] = read_gicreg(ICH_LR0_EL2); - } + cpu_if->vgic_elrsr = read_gicreg(ICH_ELSR_EL2); - switch (nr_pri_bits) { - case 7: - cpu_if->vgic_ap0r[3] = read_gicreg(ICH_AP0R3_EL2); - cpu_if->vgic_ap0r[2] = read_gicreg(ICH_AP0R2_EL2); - case 6: - cpu_if->vgic_ap0r[1] = read_gicreg(ICH_AP0R1_EL2); - default: - cpu_if->vgic_ap0r[0] = read_gicreg(ICH_AP0R0_EL2); - } + write_gicreg(0, ICH_HCR_EL2); + val = read_gicreg(ICH_VTR_EL2); + max_lr_idx = vtr_to_max_lr_idx(val); + nr_pri_bits = vtr_to_nr_pri_bits(val); - switch (nr_pri_bits) { - case 7: - cpu_if->vgic_ap1r[3] = read_gicreg(ICH_AP1R3_EL2); - cpu_if->vgic_ap1r[2] = read_gicreg(ICH_AP1R2_EL2); - case 6: - cpu_if->vgic_ap1r[1] = read_gicreg(ICH_AP1R1_EL2); - default: - cpu_if->vgic_ap1r[0] = read_gicreg(ICH_AP1R0_EL2); + save_maint_int_state(vcpu, max_lr_idx + 1); + + for (i = 0; i <= max_lr_idx; i++) { + if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i))) + continue; + + if (cpu_if->vgic_elrsr & (1 << i)) { + cpu_if->vgic_lr[i] &= ~ICH_LR_STATE; + continue; + } + + cpu_if->vgic_lr[i] = __gic_v3_get_lr(i); + __gic_v3_set_lr(0, i); + } + + switch (nr_pri_bits) { + case 7: + cpu_if->vgic_ap0r[3] = read_gicreg(ICH_AP0R3_EL2); + cpu_if->vgic_ap0r[2] = read_gicreg(ICH_AP0R2_EL2); + case 6: + cpu_if->vgic_ap0r[1] = read_gicreg(ICH_AP0R1_EL2); + default: + cpu_if->vgic_ap0r[0] = read_gicreg(ICH_AP0R0_EL2); + } + + switch (nr_pri_bits) { + case 7: + cpu_if->vgic_ap1r[3] = read_gicreg(ICH_AP1R3_EL2); + cpu_if->vgic_ap1r[2] = read_gicreg(ICH_AP1R2_EL2); + case 6: + cpu_if->vgic_ap1r[1] = read_gicreg(ICH_AP1R1_EL2); + default: + cpu_if->vgic_ap1r[0] = read_gicreg(ICH_AP1R0_EL2); + } + + vcpu->arch.vgic_cpu.live_lrs = 0; + } else { + cpu_if->vgic_misr = 0; + cpu_if->vgic_eisr = 0; + cpu_if->vgic_elrsr = 0xffff; + cpu_if->vgic_ap0r[0] = 0; + cpu_if->vgic_ap0r[1] = 0; + cpu_if->vgic_ap0r[2] = 0; + cpu_if->vgic_ap0r[3] = 0; + cpu_if->vgic_ap1r[0] = 0; + cpu_if->vgic_ap1r[1] = 0; + cpu_if->vgic_ap1r[2] = 0; + cpu_if->vgic_ap1r[3] = 0; } val = read_gicreg(ICC_SRE_EL2); @@ -128,6 +245,8 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu) struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; u64 val; u32 max_lr_idx, nr_pri_bits; + u16 live_lrs = 0; + int i; /* * VFIQEn is RES1 if ICC_SRE_EL1.SRE is 1. This causes a @@ -140,66 +259,46 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu) write_gicreg(cpu_if->vgic_sre, ICC_SRE_EL1); isb(); - write_gicreg(cpu_if->vgic_hcr, ICH_HCR_EL2); - write_gicreg(cpu_if->vgic_vmcr, ICH_VMCR_EL2); - val = read_gicreg(ICH_VTR_EL2); max_lr_idx = vtr_to_max_lr_idx(val); nr_pri_bits = vtr_to_nr_pri_bits(val); - switch (nr_pri_bits) { - case 7: - write_gicreg(cpu_if->vgic_ap1r[3], ICH_AP1R3_EL2); - write_gicreg(cpu_if->vgic_ap1r[2], ICH_AP1R2_EL2); - case 6: - write_gicreg(cpu_if->vgic_ap1r[1], ICH_AP1R1_EL2); - default: - write_gicreg(cpu_if->vgic_ap1r[0], ICH_AP1R0_EL2); - } - - switch (nr_pri_bits) { - case 7: - write_gicreg(cpu_if->vgic_ap0r[3], ICH_AP0R3_EL2); - write_gicreg(cpu_if->vgic_ap0r[2], ICH_AP0R2_EL2); - case 6: - write_gicreg(cpu_if->vgic_ap0r[1], ICH_AP0R1_EL2); - default: - write_gicreg(cpu_if->vgic_ap0r[0], ICH_AP0R0_EL2); + for (i = 0; i <= max_lr_idx; i++) { + if (cpu_if->vgic_lr[i] & ICH_LR_STATE) + live_lrs |= (1 << i); } - switch (max_lr_idx) { - case 15: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(15)], ICH_LR15_EL2); - case 14: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(14)], ICH_LR14_EL2); - case 13: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(13)], ICH_LR13_EL2); - case 12: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(12)], ICH_LR12_EL2); - case 11: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(11)], ICH_LR11_EL2); - case 10: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(10)], ICH_LR10_EL2); - case 9: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(9)], ICH_LR9_EL2); - case 8: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(8)], ICH_LR8_EL2); - case 7: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(7)], ICH_LR7_EL2); - case 6: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(6)], ICH_LR6_EL2); - case 5: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(5)], ICH_LR5_EL2); - case 4: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(4)], ICH_LR4_EL2); - case 3: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(3)], ICH_LR3_EL2); - case 2: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(2)], ICH_LR2_EL2); - case 1: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(1)], ICH_LR1_EL2); - case 0: - write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(0)], ICH_LR0_EL2); + write_gicreg(cpu_if->vgic_vmcr, ICH_VMCR_EL2); + + if (live_lrs) { + write_gicreg(cpu_if->vgic_hcr, ICH_HCR_EL2); + + switch (nr_pri_bits) { + case 7: + write_gicreg(cpu_if->vgic_ap0r[3], ICH_AP0R3_EL2); + write_gicreg(cpu_if->vgic_ap0r[2], ICH_AP0R2_EL2); + case 6: + write_gicreg(cpu_if->vgic_ap0r[1], ICH_AP0R1_EL2); + default: + write_gicreg(cpu_if->vgic_ap0r[0], ICH_AP0R0_EL2); + } + + switch (nr_pri_bits) { + case 7: + write_gicreg(cpu_if->vgic_ap1r[3], ICH_AP1R3_EL2); + write_gicreg(cpu_if->vgic_ap1r[2], ICH_AP1R2_EL2); + case 6: + write_gicreg(cpu_if->vgic_ap1r[1], ICH_AP1R1_EL2); + default: + write_gicreg(cpu_if->vgic_ap1r[0], ICH_AP1R0_EL2); + } + + for (i = 0; i <= max_lr_idx; i++) { + if (!(live_lrs & (1 << i))) + continue; + + __gic_v3_set_lr(cpu_if->vgic_lr[i], i); + } } /* @@ -209,6 +308,7 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu) */ isb(); dsb(sy); + vcpu->arch.vgic_cpu.live_lrs = live_lrs; /* * Prevent the guest from touching the GIC system registers if @@ -220,6 +320,15 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu) } } +void __hyp_text __vgic_v3_init_lrs(void) +{ + int max_lr_idx = vtr_to_max_lr_idx(read_gicreg(ICH_VTR_EL2)); + int i; + + for (i = 0; i <= max_lr_idx; i++) + __gic_v3_set_lr(0, i); +} + static u64 __hyp_text __vgic_v3_read_ich_vtr_el2(void) { return read_gicreg(ICH_VTR_EL2); diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c index f34745cb3d23..9677bf069bcc 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -77,7 +77,11 @@ int kvm_arch_dev_ioctl_check_extension(long ext) case KVM_CAP_GUEST_DEBUG_HW_WPS: r = get_num_wrps(); break; + case KVM_CAP_ARM_PMU_V3: + r = kvm_arm_support_pmu_v3(); + break; case KVM_CAP_SET_GUEST_DEBUG: + case KVM_CAP_VCPU_ATTRIBUTES: r = 1; break; default: @@ -120,6 +124,9 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) /* Reset system registers */ kvm_reset_sys_regs(vcpu); + /* Reset PMU */ + kvm_pmu_vcpu_reset(vcpu); + /* Reset timer */ return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq); } diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 6f4156f55e7c..7bbe3ff02602 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -20,6 +20,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/bsearch.h> #include <linux/kvm_host.h> #include <linux/mm.h> #include <linux/uaccess.h> @@ -34,6 +35,7 @@ #include <asm/kvm_emulate.h> #include <asm/kvm_host.h> #include <asm/kvm_mmu.h> +#include <asm/perf_event.h> #include <trace/events/kvm.h> @@ -439,6 +441,344 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) vcpu_sys_reg(vcpu, MPIDR_EL1) = (1ULL << 31) | mpidr; } +static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) +{ + u64 pmcr, val; + + asm volatile("mrs %0, pmcr_el0\n" : "=r" (pmcr)); + /* Writable bits of PMCR_EL0 (ARMV8_PMU_PMCR_MASK) is reset to UNKNOWN + * except PMCR.E resetting to zero. + */ + val = ((pmcr & ~ARMV8_PMU_PMCR_MASK) + | (ARMV8_PMU_PMCR_MASK & 0xdecafbad)) & (~ARMV8_PMU_PMCR_E); + vcpu_sys_reg(vcpu, PMCR_EL0) = val; +} + +static bool pmu_access_el0_disabled(struct kvm_vcpu *vcpu) +{ + u64 reg = vcpu_sys_reg(vcpu, PMUSERENR_EL0); + + return !((reg & ARMV8_PMU_USERENR_EN) || vcpu_mode_priv(vcpu)); +} + +static bool pmu_write_swinc_el0_disabled(struct kvm_vcpu *vcpu) +{ + u64 reg = vcpu_sys_reg(vcpu, PMUSERENR_EL0); + + return !((reg & (ARMV8_PMU_USERENR_SW | ARMV8_PMU_USERENR_EN)) + || vcpu_mode_priv(vcpu)); +} + +static bool pmu_access_cycle_counter_el0_disabled(struct kvm_vcpu *vcpu) +{ + u64 reg = vcpu_sys_reg(vcpu, PMUSERENR_EL0); + + return !((reg & (ARMV8_PMU_USERENR_CR | ARMV8_PMU_USERENR_EN)) + || vcpu_mode_priv(vcpu)); +} + +static bool pmu_access_event_counter_el0_disabled(struct kvm_vcpu *vcpu) +{ + u64 reg = vcpu_sys_reg(vcpu, PMUSERENR_EL0); + + return !((reg & (ARMV8_PMU_USERENR_ER | ARMV8_PMU_USERENR_EN)) + || vcpu_mode_priv(vcpu)); +} + +static bool access_pmcr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + u64 val; + + if (!kvm_arm_pmu_v3_ready(vcpu)) + return trap_raz_wi(vcpu, p, r); + + if (pmu_access_el0_disabled(vcpu)) + return false; + + if (p->is_write) { + /* Only update writeable bits of PMCR */ + val = vcpu_sys_reg(vcpu, PMCR_EL0); + val &= ~ARMV8_PMU_PMCR_MASK; + val |= p->regval & ARMV8_PMU_PMCR_MASK; + vcpu_sys_reg(vcpu, PMCR_EL0) = val; + kvm_pmu_handle_pmcr(vcpu, val); + } else { + /* PMCR.P & PMCR.C are RAZ */ + val = vcpu_sys_reg(vcpu, PMCR_EL0) + & ~(ARMV8_PMU_PMCR_P | ARMV8_PMU_PMCR_C); + p->regval = val; + } + + return true; +} + +static bool access_pmselr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + if (!kvm_arm_pmu_v3_ready(vcpu)) + return trap_raz_wi(vcpu, p, r); + + if (pmu_access_event_counter_el0_disabled(vcpu)) + return false; + + if (p->is_write) + vcpu_sys_reg(vcpu, PMSELR_EL0) = p->regval; + else + /* return PMSELR.SEL field */ + p->regval = vcpu_sys_reg(vcpu, PMSELR_EL0) + & ARMV8_PMU_COUNTER_MASK; + + return true; +} + +static bool access_pmceid(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + u64 pmceid; + + if (!kvm_arm_pmu_v3_ready(vcpu)) + return trap_raz_wi(vcpu, p, r); + + BUG_ON(p->is_write); + + if (pmu_access_el0_disabled(vcpu)) + return false; + + if (!(p->Op2 & 1)) + asm volatile("mrs %0, pmceid0_el0\n" : "=r" (pmceid)); + else + asm volatile("mrs %0, pmceid1_el0\n" : "=r" (pmceid)); + + p->regval = pmceid; + + return true; +} + +static bool pmu_counter_idx_valid(struct kvm_vcpu *vcpu, u64 idx) +{ + u64 pmcr, val; + + pmcr = vcpu_sys_reg(vcpu, PMCR_EL0); + val = (pmcr >> ARMV8_PMU_PMCR_N_SHIFT) & ARMV8_PMU_PMCR_N_MASK; + if (idx >= val && idx != ARMV8_PMU_CYCLE_IDX) + return false; + + return true; +} + +static bool access_pmu_evcntr(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + u64 idx; + + if (!kvm_arm_pmu_v3_ready(vcpu)) + return trap_raz_wi(vcpu, p, r); + + if (r->CRn == 9 && r->CRm == 13) { + if (r->Op2 == 2) { + /* PMXEVCNTR_EL0 */ + if (pmu_access_event_counter_el0_disabled(vcpu)) + return false; + + idx = vcpu_sys_reg(vcpu, PMSELR_EL0) + & ARMV8_PMU_COUNTER_MASK; + } else if (r->Op2 == 0) { + /* PMCCNTR_EL0 */ + if (pmu_access_cycle_counter_el0_disabled(vcpu)) + return false; + + idx = ARMV8_PMU_CYCLE_IDX; + } else { + BUG(); + } + } else if (r->CRn == 14 && (r->CRm & 12) == 8) { + /* PMEVCNTRn_EL0 */ + if (pmu_access_event_counter_el0_disabled(vcpu)) + return false; + + idx = ((r->CRm & 3) << 3) | (r->Op2 & 7); + } else { + BUG(); + } + + if (!pmu_counter_idx_valid(vcpu, idx)) + return false; + + if (p->is_write) { + if (pmu_access_el0_disabled(vcpu)) + return false; + + kvm_pmu_set_counter_value(vcpu, idx, p->regval); + } else { + p->regval = kvm_pmu_get_counter_value(vcpu, idx); + } + + return true; +} + +static bool access_pmu_evtyper(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + u64 idx, reg; + + if (!kvm_arm_pmu_v3_ready(vcpu)) + return trap_raz_wi(vcpu, p, r); + + if (pmu_access_el0_disabled(vcpu)) + return false; + + if (r->CRn == 9 && r->CRm == 13 && r->Op2 == 1) { + /* PMXEVTYPER_EL0 */ + idx = vcpu_sys_reg(vcpu, PMSELR_EL0) & ARMV8_PMU_COUNTER_MASK; + reg = PMEVTYPER0_EL0 + idx; + } else if (r->CRn == 14 && (r->CRm & 12) == 12) { + idx = ((r->CRm & 3) << 3) | (r->Op2 & 7); + if (idx == ARMV8_PMU_CYCLE_IDX) + reg = PMCCFILTR_EL0; + else + /* PMEVTYPERn_EL0 */ + reg = PMEVTYPER0_EL0 + idx; + } else { + BUG(); + } + + if (!pmu_counter_idx_valid(vcpu, idx)) + return false; + + if (p->is_write) { + kvm_pmu_set_counter_event_type(vcpu, p->regval, idx); + vcpu_sys_reg(vcpu, reg) = p->regval & ARMV8_PMU_EVTYPE_MASK; + } else { + p->regval = vcpu_sys_reg(vcpu, reg) & ARMV8_PMU_EVTYPE_MASK; + } + + return true; +} + +static bool access_pmcnten(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + u64 val, mask; + + if (!kvm_arm_pmu_v3_ready(vcpu)) + return trap_raz_wi(vcpu, p, r); + + if (pmu_access_el0_disabled(vcpu)) + return false; + + mask = kvm_pmu_valid_counter_mask(vcpu); + if (p->is_write) { + val = p->regval & mask; + if (r->Op2 & 0x1) { + /* accessing PMCNTENSET_EL0 */ + vcpu_sys_reg(vcpu, PMCNTENSET_EL0) |= val; + kvm_pmu_enable_counter(vcpu, val); + } else { + /* accessing PMCNTENCLR_EL0 */ + vcpu_sys_reg(vcpu, PMCNTENSET_EL0) &= ~val; + kvm_pmu_disable_counter(vcpu, val); + } + } else { + p->regval = vcpu_sys_reg(vcpu, PMCNTENSET_EL0) & mask; + } + + return true; +} + +static bool access_pminten(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + u64 mask = kvm_pmu_valid_counter_mask(vcpu); + + if (!kvm_arm_pmu_v3_ready(vcpu)) + return trap_raz_wi(vcpu, p, r); + + if (!vcpu_mode_priv(vcpu)) + return false; + + if (p->is_write) { + u64 val = p->regval & mask; + + if (r->Op2 & 0x1) + /* accessing PMINTENSET_EL1 */ + vcpu_sys_reg(vcpu, PMINTENSET_EL1) |= val; + else + /* accessing PMINTENCLR_EL1 */ + vcpu_sys_reg(vcpu, PMINTENSET_EL1) &= ~val; + } else { + p->regval = vcpu_sys_reg(vcpu, PMINTENSET_EL1) & mask; + } + + return true; +} + +static bool access_pmovs(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + u64 mask = kvm_pmu_valid_counter_mask(vcpu); + + if (!kvm_arm_pmu_v3_ready(vcpu)) + return trap_raz_wi(vcpu, p, r); + + if (pmu_access_el0_disabled(vcpu)) + return false; + + if (p->is_write) { + if (r->CRm & 0x2) + /* accessing PMOVSSET_EL0 */ + kvm_pmu_overflow_set(vcpu, p->regval & mask); + else + /* accessing PMOVSCLR_EL0 */ + vcpu_sys_reg(vcpu, PMOVSSET_EL0) &= ~(p->regval & mask); + } else { + p->regval = vcpu_sys_reg(vcpu, PMOVSSET_EL0) & mask; + } + + return true; +} + +static bool access_pmswinc(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + u64 mask; + + if (!kvm_arm_pmu_v3_ready(vcpu)) + return trap_raz_wi(vcpu, p, r); + + if (pmu_write_swinc_el0_disabled(vcpu)) + return false; + + if (p->is_write) { + mask = kvm_pmu_valid_counter_mask(vcpu); + kvm_pmu_software_increment(vcpu, p->regval & mask); + return true; + } + + return false; +} + +static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + if (!kvm_arm_pmu_v3_ready(vcpu)) + return trap_raz_wi(vcpu, p, r); + + if (p->is_write) { + if (!vcpu_mode_priv(vcpu)) + return false; + + vcpu_sys_reg(vcpu, PMUSERENR_EL0) = p->regval + & ARMV8_PMU_USERENR_MASK; + } else { + p->regval = vcpu_sys_reg(vcpu, PMUSERENR_EL0) + & ARMV8_PMU_USERENR_MASK; + } + + return true; +} + /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */ #define DBG_BCR_BVR_WCR_WVR_EL1(n) \ /* DBGBVRn_EL1 */ \ @@ -454,6 +794,20 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b111), \ trap_wcr, reset_wcr, n, 0, get_wcr, set_wcr } +/* Macro to expand the PMEVCNTRn_EL0 register */ +#define PMU_PMEVCNTR_EL0(n) \ + /* PMEVCNTRn_EL0 */ \ + { Op0(0b11), Op1(0b011), CRn(0b1110), \ + CRm((0b1000 | (((n) >> 3) & 0x3))), Op2(((n) & 0x7)), \ + access_pmu_evcntr, reset_unknown, (PMEVCNTR0_EL0 + n), } + +/* Macro to expand the PMEVTYPERn_EL0 register */ +#define PMU_PMEVTYPER_EL0(n) \ + /* PMEVTYPERn_EL0 */ \ + { Op0(0b11), Op1(0b011), CRn(0b1110), \ + CRm((0b1100 | (((n) >> 3) & 0x3))), Op2(((n) & 0x7)), \ + access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), } + /* * Architected system registers. * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2 @@ -583,10 +937,10 @@ static const struct sys_reg_desc sys_reg_descs[] = { /* PMINTENSET_EL1 */ { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b001), - trap_raz_wi }, + access_pminten, reset_unknown, PMINTENSET_EL1 }, /* PMINTENCLR_EL1 */ { Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b010), - trap_raz_wi }, + access_pminten, NULL, PMINTENSET_EL1 }, /* MAIR_EL1 */ { Op0(0b11), Op1(0b000), CRn(0b1010), CRm(0b0010), Op2(0b000), @@ -623,43 +977,46 @@ static const struct sys_reg_desc sys_reg_descs[] = { /* PMCR_EL0 */ { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b000), - trap_raz_wi }, + access_pmcr, reset_pmcr, }, /* PMCNTENSET_EL0 */ { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b001), - trap_raz_wi }, + access_pmcnten, reset_unknown, PMCNTENSET_EL0 }, /* PMCNTENCLR_EL0 */ { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b010), - trap_raz_wi }, + access_pmcnten, NULL, PMCNTENSET_EL0 }, /* PMOVSCLR_EL0 */ { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b011), - trap_raz_wi }, + access_pmovs, NULL, PMOVSSET_EL0 }, /* PMSWINC_EL0 */ { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b100), - trap_raz_wi }, + access_pmswinc, reset_unknown, PMSWINC_EL0 }, /* PMSELR_EL0 */ { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b101), - trap_raz_wi }, + access_pmselr, reset_unknown, PMSELR_EL0 }, /* PMCEID0_EL0 */ { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b110), - trap_raz_wi }, + access_pmceid }, /* PMCEID1_EL0 */ { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b111), - trap_raz_wi }, + access_pmceid }, /* PMCCNTR_EL0 */ { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b000), - trap_raz_wi }, + access_pmu_evcntr, reset_unknown, PMCCNTR_EL0 }, /* PMXEVTYPER_EL0 */ { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b001), - trap_raz_wi }, + access_pmu_evtyper }, /* PMXEVCNTR_EL0 */ { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b010), - trap_raz_wi }, - /* PMUSERENR_EL0 */ + access_pmu_evcntr }, + /* PMUSERENR_EL0 + * This register resets as unknown in 64bit mode while it resets as zero + * in 32bit mode. Here we choose to reset it as zero for consistency. + */ { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b000), - trap_raz_wi }, + access_pmuserenr, reset_val, PMUSERENR_EL0, 0 }, /* PMOVSSET_EL0 */ { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b011), - trap_raz_wi }, + access_pmovs, reset_unknown, PMOVSSET_EL0 }, /* TPIDR_EL0 */ { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b010), @@ -668,6 +1025,77 @@ static const struct sys_reg_desc sys_reg_descs[] = { { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b011), NULL, reset_unknown, TPIDRRO_EL0 }, + /* PMEVCNTRn_EL0 */ + PMU_PMEVCNTR_EL0(0), + PMU_PMEVCNTR_EL0(1), + PMU_PMEVCNTR_EL0(2), + PMU_PMEVCNTR_EL0(3), + PMU_PMEVCNTR_EL0(4), + PMU_PMEVCNTR_EL0(5), + PMU_PMEVCNTR_EL0(6), + PMU_PMEVCNTR_EL0(7), + PMU_PMEVCNTR_EL0(8), + PMU_PMEVCNTR_EL0(9), + PMU_PMEVCNTR_EL0(10), + PMU_PMEVCNTR_EL0(11), + PMU_PMEVCNTR_EL0(12), + PMU_PMEVCNTR_EL0(13), + PMU_PMEVCNTR_EL0(14), + PMU_PMEVCNTR_EL0(15), + PMU_PMEVCNTR_EL0(16), + PMU_PMEVCNTR_EL0(17), + PMU_PMEVCNTR_EL0(18), + PMU_PMEVCNTR_EL0(19), + PMU_PMEVCNTR_EL0(20), + PMU_PMEVCNTR_EL0(21), + PMU_PMEVCNTR_EL0(22), + PMU_PMEVCNTR_EL0(23), + PMU_PMEVCNTR_EL0(24), + PMU_PMEVCNTR_EL0(25), + PMU_PMEVCNTR_EL0(26), + PMU_PMEVCNTR_EL0(27), + PMU_PMEVCNTR_EL0(28), + PMU_PMEVCNTR_EL0(29), + PMU_PMEVCNTR_EL0(30), + /* PMEVTYPERn_EL0 */ + PMU_PMEVTYPER_EL0(0), + PMU_PMEVTYPER_EL0(1), + PMU_PMEVTYPER_EL0(2), + PMU_PMEVTYPER_EL0(3), + PMU_PMEVTYPER_EL0(4), + PMU_PMEVTYPER_EL0(5), + PMU_PMEVTYPER_EL0(6), + PMU_PMEVTYPER_EL0(7), + PMU_PMEVTYPER_EL0(8), + PMU_PMEVTYPER_EL0(9), + PMU_PMEVTYPER_EL0(10), + PMU_PMEVTYPER_EL0(11), + PMU_PMEVTYPER_EL0(12), + PMU_PMEVTYPER_EL0(13), + PMU_PMEVTYPER_EL0(14), + PMU_PMEVTYPER_EL0(15), + PMU_PMEVTYPER_EL0(16), + PMU_PMEVTYPER_EL0(17), + PMU_PMEVTYPER_EL0(18), + PMU_PMEVTYPER_EL0(19), + PMU_PMEVTYPER_EL0(20), + PMU_PMEVTYPER_EL0(21), + PMU_PMEVTYPER_EL0(22), + PMU_PMEVTYPER_EL0(23), + PMU_PMEVTYPER_EL0(24), + PMU_PMEVTYPER_EL0(25), + PMU_PMEVTYPER_EL0(26), + PMU_PMEVTYPER_EL0(27), + PMU_PMEVTYPER_EL0(28), + PMU_PMEVTYPER_EL0(29), + PMU_PMEVTYPER_EL0(30), + /* PMCCFILTR_EL0 + * This register resets as unknown in 64bit mode while it resets as zero + * in 32bit mode. Here we choose to reset it as zero for consistency. + */ + { Op0(0b11), Op1(0b011), CRn(0b1110), CRm(0b1111), Op2(0b111), + access_pmu_evtyper, reset_val, PMCCFILTR_EL0, 0 }, + /* DACR32_EL2 */ { Op0(0b11), Op1(0b100), CRn(0b0011), CRm(0b0000), Op2(0b000), NULL, reset_unknown, DACR32_EL2 }, @@ -857,6 +1285,20 @@ static const struct sys_reg_desc cp14_64_regs[] = { { Op1( 0), CRm( 2), .access = trap_raz_wi }, }; +/* Macro to expand the PMEVCNTRn register */ +#define PMU_PMEVCNTR(n) \ + /* PMEVCNTRn */ \ + { Op1(0), CRn(0b1110), \ + CRm((0b1000 | (((n) >> 3) & 0x3))), Op2(((n) & 0x7)), \ + access_pmu_evcntr } + +/* Macro to expand the PMEVTYPERn register */ +#define PMU_PMEVTYPER(n) \ + /* PMEVTYPERn */ \ + { Op1(0), CRn(0b1110), \ + CRm((0b1100 | (((n) >> 3) & 0x3))), Op2(((n) & 0x7)), \ + access_pmu_evtyper } + /* * Trapped cp15 registers. TTBR0/TTBR1 get a double encoding, * depending on the way they are accessed (as a 32bit or a 64bit @@ -885,19 +1327,21 @@ static const struct sys_reg_desc cp15_regs[] = { { Op1( 0), CRn( 7), CRm(14), Op2( 2), access_dcsw }, /* PMU */ - { Op1( 0), CRn( 9), CRm(12), Op2( 0), trap_raz_wi }, - { Op1( 0), CRn( 9), CRm(12), Op2( 1), trap_raz_wi }, - { Op1( 0), CRn( 9), CRm(12), Op2( 2), trap_raz_wi }, - { Op1( 0), CRn( 9), CRm(12), Op2( 3), trap_raz_wi }, - { Op1( 0), CRn( 9), CRm(12), Op2( 5), trap_raz_wi }, - { Op1( 0), CRn( 9), CRm(12), Op2( 6), trap_raz_wi }, - { Op1( 0), CRn( 9), CRm(12), Op2( 7), trap_raz_wi }, - { Op1( 0), CRn( 9), CRm(13), Op2( 0), trap_raz_wi }, - { Op1( 0), CRn( 9), CRm(13), Op2( 1), trap_raz_wi }, - { Op1( 0), CRn( 9), CRm(13), Op2( 2), trap_raz_wi }, - { Op1( 0), CRn( 9), CRm(14), Op2( 0), trap_raz_wi }, - { Op1( 0), CRn( 9), CRm(14), Op2( 1), trap_raz_wi }, - { Op1( 0), CRn( 9), CRm(14), Op2( 2), trap_raz_wi }, + { Op1( 0), CRn( 9), CRm(12), Op2( 0), access_pmcr }, + { Op1( 0), CRn( 9), CRm(12), Op2( 1), access_pmcnten }, + { Op1( 0), CRn( 9), CRm(12), Op2( 2), access_pmcnten }, + { Op1( 0), CRn( 9), CRm(12), Op2( 3), access_pmovs }, + { Op1( 0), CRn( 9), CRm(12), Op2( 4), access_pmswinc }, + { Op1( 0), CRn( 9), CRm(12), Op2( 5), access_pmselr }, + { Op1( 0), CRn( 9), CRm(12), Op2( 6), access_pmceid }, + { Op1( 0), CRn( 9), CRm(12), Op2( 7), access_pmceid }, + { Op1( 0), CRn( 9), CRm(13), Op2( 0), access_pmu_evcntr }, + { Op1( 0), CRn( 9), CRm(13), Op2( 1), access_pmu_evtyper }, + { Op1( 0), CRn( 9), CRm(13), Op2( 2), access_pmu_evcntr }, + { Op1( 0), CRn( 9), CRm(14), Op2( 0), access_pmuserenr }, + { Op1( 0), CRn( 9), CRm(14), Op2( 1), access_pminten }, + { Op1( 0), CRn( 9), CRm(14), Op2( 2), access_pminten }, + { Op1( 0), CRn( 9), CRm(14), Op2( 3), access_pmovs }, { Op1( 0), CRn(10), CRm( 2), Op2( 0), access_vm_reg, NULL, c10_PRRR }, { Op1( 0), CRn(10), CRm( 2), Op2( 1), access_vm_reg, NULL, c10_NMRR }, @@ -908,10 +1352,78 @@ static const struct sys_reg_desc cp15_regs[] = { { Op1( 0), CRn(12), CRm(12), Op2( 5), trap_raz_wi }, { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID }, + + /* PMEVCNTRn */ + PMU_PMEVCNTR(0), + PMU_PMEVCNTR(1), + PMU_PMEVCNTR(2), + PMU_PMEVCNTR(3), + PMU_PMEVCNTR(4), + PMU_PMEVCNTR(5), + PMU_PMEVCNTR(6), + PMU_PMEVCNTR(7), + PMU_PMEVCNTR(8), + PMU_PMEVCNTR(9), + PMU_PMEVCNTR(10), + PMU_PMEVCNTR(11), + PMU_PMEVCNTR(12), + PMU_PMEVCNTR(13), + PMU_PMEVCNTR(14), + PMU_PMEVCNTR(15), + PMU_PMEVCNTR(16), + PMU_PMEVCNTR(17), + PMU_PMEVCNTR(18), + PMU_PMEVCNTR(19), + PMU_PMEVCNTR(20), + PMU_PMEVCNTR(21), + PMU_PMEVCNTR(22), + PMU_PMEVCNTR(23), + PMU_PMEVCNTR(24), + PMU_PMEVCNTR(25), + PMU_PMEVCNTR(26), + PMU_PMEVCNTR(27), + PMU_PMEVCNTR(28), + PMU_PMEVCNTR(29), + PMU_PMEVCNTR(30), + /* PMEVTYPERn */ + PMU_PMEVTYPER(0), + PMU_PMEVTYPER(1), + PMU_PMEVTYPER(2), + PMU_PMEVTYPER(3), + PMU_PMEVTYPER(4), + PMU_PMEVTYPER(5), + PMU_PMEVTYPER(6), + PMU_PMEVTYPER(7), + PMU_PMEVTYPER(8), + PMU_PMEVTYPER(9), + PMU_PMEVTYPER(10), + PMU_PMEVTYPER(11), + PMU_PMEVTYPER(12), + PMU_PMEVTYPER(13), + PMU_PMEVTYPER(14), + PMU_PMEVTYPER(15), + PMU_PMEVTYPER(16), + PMU_PMEVTYPER(17), + PMU_PMEVTYPER(18), + PMU_PMEVTYPER(19), + PMU_PMEVTYPER(20), + PMU_PMEVTYPER(21), + PMU_PMEVTYPER(22), + PMU_PMEVTYPER(23), + PMU_PMEVTYPER(24), + PMU_PMEVTYPER(25), + PMU_PMEVTYPER(26), + PMU_PMEVTYPER(27), + PMU_PMEVTYPER(28), + PMU_PMEVTYPER(29), + PMU_PMEVTYPER(30), + /* PMCCFILTR */ + { Op1(0), CRn(14), CRm(15), Op2(7), access_pmu_evtyper }, }; static const struct sys_reg_desc cp15_64_regs[] = { { Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, + { Op1( 0), CRn( 0), CRm( 9), Op2( 0), access_pmu_evcntr }, { Op1( 0), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, { Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR1 }, }; @@ -942,29 +1454,32 @@ static const struct sys_reg_desc *get_target_table(unsigned target, } } +#define reg_to_match_value(x) \ + ({ \ + unsigned long val; \ + val = (x)->Op0 << 14; \ + val |= (x)->Op1 << 11; \ + val |= (x)->CRn << 7; \ + val |= (x)->CRm << 3; \ + val |= (x)->Op2; \ + val; \ + }) + +static int match_sys_reg(const void *key, const void *elt) +{ + const unsigned long pval = (unsigned long)key; + const struct sys_reg_desc *r = elt; + + return pval - reg_to_match_value(r); +} + static const struct sys_reg_desc *find_reg(const struct sys_reg_params *params, const struct sys_reg_desc table[], unsigned int num) { - unsigned int i; - - for (i = 0; i < num; i++) { - const struct sys_reg_desc *r = &table[i]; - - if (params->Op0 != r->Op0) - continue; - if (params->Op1 != r->Op1) - continue; - if (params->CRn != r->CRn) - continue; - if (params->CRm != r->CRm) - continue; - if (params->Op2 != r->Op2) - continue; + unsigned long pval = reg_to_match_value(params); - return r; - } - return NULL; + return bsearch((void *)pval, table, num, sizeof(table[0]), match_sys_reg); } int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run) diff --git a/arch/arm64/lib/strnlen.S b/arch/arm64/lib/strnlen.S index 2ca665711bf2..eae38da6e0bb 100644 --- a/arch/arm64/lib/strnlen.S +++ b/arch/arm64/lib/strnlen.S @@ -168,4 +168,4 @@ CPU_LE( lsr tmp2, tmp2, tmp4 ) /* Shift (tmp1 & 63). */ .Lhit_limit: mov len, limit ret -ENDPROC(strnlen) +ENDPIPROC(strnlen) diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 331c4ca6205c..a6e757cbab77 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -933,6 +933,10 @@ static int __init __iommu_dma_init(void) ret = register_iommu_dma_ops_notifier(&platform_bus_type); if (!ret) ret = register_iommu_dma_ops_notifier(&amba_bustype); + + /* handle devices queued before this arch_initcall */ + if (!ret) + __iommu_attach_notifier(NULL, BUS_NOTIFY_ADD_DEVICE, NULL); return ret; } arch_initcall(__iommu_dma_init); diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 44e56de23f79..95df28bc875f 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -304,7 +304,7 @@ retry: up_read(&mm->mmap_sem); /* - * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR + * Handle the "normal" case first - VM_FAULT_MAJOR */ if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) @@ -380,6 +380,13 @@ static int __kprobes do_translation_fault(unsigned long addr, return 0; } +static int do_alignment_fault(unsigned long addr, unsigned int esr, + struct pt_regs *regs) +{ + do_bad_area(addr, esr, regs); + return 0; +} + /* * This abort handler always returns "fault". */ @@ -427,7 +434,7 @@ static struct fault_info { { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" }, { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" }, { do_bad, SIGBUS, 0, "unknown 32" }, - { do_bad, SIGBUS, BUS_ADRALN, "alignment fault" }, + { do_alignment_fault, SIGBUS, BUS_ADRALN, "alignment fault" }, { do_bad, SIGBUS, 0, "unknown 34" }, { do_bad, SIGBUS, 0, "unknown 35" }, { do_bad, SIGBUS, 0, "unknown 36" }, diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 82d607c3614e..589fd28e1fb5 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -124,7 +124,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, * will be no pte_unmap() to correspond with this * pte_alloc_map(). */ - pte = pte_alloc_map(mm, NULL, pmd, addr); + pte = pte_alloc_map(mm, pmd, addr); } else if (sz == PMD_SIZE) { if (IS_ENABLED(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) && pud_none(*pud)) @@ -306,10 +306,6 @@ static __init int setup_hugepagesz(char *opt) hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT); } else if (ps == PUD_SIZE) { hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); - } else if (ps == (PAGE_SIZE * CONT_PTES)) { - hugetlb_add_hstate(CONT_PTE_SHIFT); - } else if (ps == (PMD_SIZE * CONT_PMDS)) { - hugetlb_add_hstate((PMD_SHIFT + CONT_PMD_SHIFT) - PAGE_SHIFT); } else { pr_err("hugepagesz: Unsupported page size %lu K\n", ps >> 10); return 0; @@ -317,13 +313,3 @@ static __init int setup_hugepagesz(char *opt) return 1; } __setup("hugepagesz=", setup_hugepagesz); - -#ifdef CONFIG_ARM64_64K_PAGES -static __init int add_default_hugepagesz(void) -{ - if (size_to_hstate(CONT_PTES * PAGE_SIZE) == NULL) - hugetlb_add_hstate(CONT_PMD_SHIFT); - return 0; -} -arch_initcall(add_default_hugepagesz); -#endif diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index d09603d0e5e9..ea989d83ea9b 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -382,8 +382,8 @@ void __init mem_init(void) #ifdef CONFIG_SPARSEMEM_VMEMMAP pr_cont(" vmemmap : 0x%16lx - 0x%16lx (%6ld GB maximum)\n" " 0x%16lx - 0x%16lx (%6ld MB actual)\n", - MLG((unsigned long)vmemmap, - (unsigned long)vmemmap + VMEMMAP_SIZE), + MLG(VMEMMAP_START, + VMEMMAP_START + VMEMMAP_SIZE), MLM((unsigned long)phys_to_page(memblock_start_of_DRAM()), (unsigned long)virt_to_page(high_memory))); #endif diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c index 4c893b5189dd..232f787a088a 100644 --- a/arch/arm64/mm/mmap.c +++ b/arch/arm64/mm/mmap.c @@ -53,10 +53,10 @@ unsigned long arch_mmap_rnd(void) #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) - rnd = (unsigned long)get_random_int() & ((1 << mmap_rnd_compat_bits) - 1); + rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1); else #endif - rnd = (unsigned long)get_random_int() & ((1 << mmap_rnd_bits) - 1); + rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1); return rnd << PAGE_SHIFT; } |