aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64')
-rw-r--r--arch/arm64/Kconfig37
-rw-r--r--arch/arm64/Kconfig.debug10
-rw-r--r--arch/arm64/Kconfig.platforms32
-rw-r--r--arch/arm64/Makefile10
-rw-r--r--arch/arm64/boot/dts/Makefile1
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts11
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts6
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi35
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi42
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi329
-rw-r--r--arch/arm64/boot/dts/apm/apm-mustang.dts1
-rw-r--r--arch/arm64/boot/dts/apm/apm-shadowcat.dtsi135
-rw-r--r--arch/arm64/boot/dts/apm/apm-storm.dtsi105
-rw-r--r--arch/arm64/boot/dts/broadcom/ns2.dtsi8
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7.dtsi13
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts14
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts8
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi7
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts3
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts4
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi18
-rw-r--r--arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts86
-rw-r--r--arch/arm64/boot/dts/hisilicon/hi6220.dtsi61
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip05.dtsi5
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi180
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip06-d03.dts28
-rw-r--r--arch/arm64/boot/dts/hisilicon/hip06.dtsi365
-rw-r--r--arch/arm64/boot/dts/marvell/Makefile1
-rw-r--r--arch/arm64/boot/dts/marvell/armada-8020.dtsi1
-rw-r--r--arch/arm64/boot/dts/marvell/armada-8040-db.dts150
-rw-r--r--arch/arm64/boot/dts/marvell/armada-8040.dtsi1
-rw-r--r--arch/arm64/boot/dts/marvell/armada-ap806.dtsi14
-rw-r--r--arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi3
-rw-r--r--arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi249
-rw-r--r--arch/arm64/boot/dts/marvell/berlin4ct.dtsi12
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173-evb.dts38
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173.dtsi77
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra132.dtsi119
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210-smaug.dts120
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra210.dtsi206
-rw-r--r--arch/arm64/boot/dts/qcom/Makefile1
-rw-r--r--arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi48
-rw-r--r--arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi82
-rw-r--r--arch/arm64/boot/dts/qcom/apq8096-db820c-pins.dtsi39
-rw-r--r--arch/arm64/boot/dts/qcom/apq8096-db820c.dts21
-rw-r--r--arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi88
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916.dtsi286
-rw-r--r--arch/arm64/boot/dts/qcom/msm8996.dtsi94
-rw-r--r--arch/arm64/boot/dts/renesas/Makefile2
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts328
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts87
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7795.dtsi276
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts16
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7796.dtsi117
-rw-r--r--arch/arm64/boot/dts/rockchip/Makefile1
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts382
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368-r88.dts1
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3368.dtsi10
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-evb.dts87
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399.dtsi607
-rw-r--r--arch/arm64/boot/dts/socionext/Makefile4
-rw-r--r--arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts100
-rw-r--r--arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi338
-rw-r--r--arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts (renamed from arch/arm64/boot/dts/socionext/uniphier-ph1-ld20-ref.dts)11
-rw-r--r--arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi (renamed from arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi)94
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts2
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp.dtsi100
-rw-r--r--arch/arm64/boot/dts/zte/Makefile5
-rw-r--r--arch/arm64/boot/dts/zte/zx296718-evb.dts64
-rw-r--r--arch/arm64/boot/dts/zte/zx296718.dtsi292
-rw-r--r--arch/arm64/configs/defconfig35
-rw-r--r--arch/arm64/include/asm/Kbuild5
-rw-r--r--arch/arm64/include/asm/acpi.h8
-rw-r--r--arch/arm64/include/asm/alternative.h71
-rw-r--r--arch/arm64/include/asm/arch_gicv3.h19
-rw-r--r--arch/arm64/include/asm/arch_timer.h82
-rw-r--r--arch/arm64/include/asm/assembler.h53
-rw-r--r--arch/arm64/include/asm/atomic_lse.h64
-rw-r--r--arch/arm64/include/asm/barrier.h3
-rw-r--r--arch/arm64/include/asm/cacheflush.h3
-rw-r--r--arch/arm64/include/asm/clocksource.h8
-rw-r--r--arch/arm64/include/asm/cmpxchg.h4
-rw-r--r--arch/arm64/include/asm/cpufeature.h42
-rw-r--r--arch/arm64/include/asm/cputype.h6
-rw-r--r--arch/arm64/include/asm/dcc.h14
-rw-r--r--arch/arm64/include/asm/esr.h84
-rw-r--r--arch/arm64/include/asm/hw_breakpoint.h15
-rw-r--r--arch/arm64/include/asm/insn.h11
-rw-r--r--arch/arm64/include/asm/io.h19
-rw-r--r--arch/arm64/include/asm/kvm_arm.h4
-rw-r--r--arch/arm64/include/asm/kvm_asm.h9
-rw-r--r--arch/arm64/include/asm/kvm_emulate.h11
-rw-r--r--arch/arm64/include/asm/kvm_host.h12
-rw-r--r--arch/arm64/include/asm/kvm_hyp.h1
-rw-r--r--arch/arm64/include/asm/kvm_mmu.h16
-rw-r--r--arch/arm64/include/asm/memory.h8
-rw-r--r--arch/arm64/include/asm/mmu_context.h36
-rw-r--r--arch/arm64/include/asm/pgtable-hwdef.h1
-rw-r--r--arch/arm64/include/asm/pgtable-prot.h5
-rw-r--r--arch/arm64/include/asm/pgtable.h20
-rw-r--r--arch/arm64/include/asm/processor.h2
-rw-r--r--arch/arm64/include/asm/sections.h30
-rw-r--r--arch/arm64/include/asm/spinlock.h27
-rw-r--r--arch/arm64/include/asm/suspend.h3
-rw-r--r--arch/arm64/include/asm/sysreg.h44
-rw-r--r--arch/arm64/include/asm/system_misc.h6
-rw-r--r--arch/arm64/include/asm/thread_info.h3
-rw-r--r--arch/arm64/include/asm/tlbflush.h34
-rw-r--r--arch/arm64/include/asm/traps.h6
-rw-r--r--arch/arm64/include/asm/virt.h15
-rw-r--r--arch/arm64/kernel/Makefile2
-rw-r--r--arch/arm64/kernel/acpi.c11
-rw-r--r--arch/arm64/kernel/acpi_numa.c4
-rw-r--r--arch/arm64/kernel/alternative.c28
-rw-r--r--arch/arm64/kernel/asm-offsets.c2
-rw-r--r--arch/arm64/kernel/cacheinfo.c8
-rw-r--r--arch/arm64/kernel/cpu_errata.c26
-rw-r--r--arch/arm64/kernel/cpu_ops.c3
-rw-r--r--arch/arm64/kernel/cpufeature.c137
-rw-r--r--arch/arm64/kernel/cpuinfo.c2
-rw-r--r--arch/arm64/kernel/debug-monitors.c48
-rw-r--r--arch/arm64/kernel/entry-ftrace.S2
-rw-r--r--arch/arm64/kernel/entry.S24
-rw-r--r--arch/arm64/kernel/fpsimd.c22
-rw-r--r--arch/arm64/kernel/ftrace.c2
-rw-r--r--arch/arm64/kernel/head.S200
-rw-r--r--arch/arm64/kernel/hibernate-asm.S6
-rw-r--r--arch/arm64/kernel/hibernate.c118
-rw-r--r--arch/arm64/kernel/hw_breakpoint.c48
-rw-r--r--arch/arm64/kernel/insn.c15
-rw-r--r--arch/arm64/kernel/kaslr.c3
-rw-r--r--arch/arm64/kernel/perf_event.c100
-rw-r--r--arch/arm64/kernel/probes/decode-insn.c48
-rw-r--r--arch/arm64/kernel/probes/kprobes.c36
-rw-r--r--arch/arm64/kernel/process.c22
-rw-r--r--arch/arm64/kernel/relocate_kernel.S2
-rw-r--r--arch/arm64/kernel/setup.c11
-rw-r--r--arch/arm64/kernel/signal.c36
-rw-r--r--arch/arm64/kernel/sleep.S29
-rw-r--r--arch/arm64/kernel/smp.c14
-rw-r--r--arch/arm64/kernel/smp_spin_table.c3
-rw-r--r--arch/arm64/kernel/stacktrace.c26
-rw-r--r--arch/arm64/kernel/suspend.c10
-rw-r--r--arch/arm64/kernel/sys_compat.c2
-rw-r--r--arch/arm64/kernel/traps.c97
-rw-r--r--arch/arm64/kernel/vdso.c36
-rw-r--r--arch/arm64/kernel/vmlinux.lds.S20
-rw-r--r--arch/arm64/kvm/Kconfig4
-rw-r--r--arch/arm64/kvm/Makefile3
-rw-r--r--arch/arm64/kvm/emulate.c159
-rw-r--r--arch/arm64/kvm/handle_exit.c23
-rw-r--r--arch/arm64/kvm/hyp.S6
-rw-r--r--arch/arm64/kvm/hyp/Makefile2
-rw-r--r--arch/arm64/kvm/hyp/debug-sr.c4
-rw-r--r--arch/arm64/kvm/hyp/entry.S128
-rw-r--r--arch/arm64/kvm/hyp/hyp-entry.S73
-rw-r--r--arch/arm64/kvm/hyp/switch.c84
-rw-r--r--arch/arm64/kvm/hyp/tlb.c13
-rw-r--r--arch/arm64/kvm/hyp/vgic-v3-sr.c343
-rw-r--r--arch/arm64/kvm/inject_fault.c12
-rw-r--r--arch/arm64/kvm/sys_regs.c31
-rw-r--r--arch/arm64/kvm/sys_regs_generic_v8.c6
-rw-r--r--arch/arm64/lib/copy_page.S13
-rw-r--r--arch/arm64/mm/cache.S82
-rw-r--r--arch/arm64/mm/dma-mapping.c11
-rw-r--r--arch/arm64/mm/extable.c2
-rw-r--r--arch/arm64/mm/fault.c7
-rw-r--r--arch/arm64/mm/flush.c2
-rw-r--r--arch/arm64/mm/init.c15
-rw-r--r--arch/arm64/mm/mm.h2
-rw-r--r--arch/arm64/mm/mmu.c15
-rw-r--r--arch/arm64/mm/numa.c115
-rw-r--r--arch/arm64/mm/pageattr.c41
-rw-r--r--arch/arm64/mm/pgd.c2
-rw-r--r--arch/arm64/mm/proc.S13
175 files changed, 7455 insertions, 1926 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index bc3f00f586f1..30398dbc940a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -4,18 +4,19 @@ config ARM64
select ACPI_GENERIC_GSI if ACPI
select ACPI_REDUCED_HARDWARE_ONLY if ACPI
select ACPI_MCFG if ACPI
+ select ACPI_SPCR_TABLE if ACPI
+ select ARCH_CLOCKSOURCE_DATA
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
- select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_GCOV_PROFILE_ALL
+ select ARCH_HAS_GIGANTIC_PAGE
select ARCH_HAS_KCOV
select ARCH_HAS_SG_CHAIN
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_USE_CMPXCHG_LOCKREF
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_SUPPORTS_NUMA_BALANCING
- select ARCH_WANT_OPTIONAL_GPIOLIB
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
select ARCH_WANT_FRAME_POINTERS
select ARCH_HAS_UBSAN_SANITIZE_ALL
@@ -102,10 +103,8 @@ config ARM64
select NO_BOOTMEM
select OF
select OF_EARLY_FLATTREE
- select OF_NUMA if NUMA && OF
select OF_RESERVED_MEM
select PCI_ECAM if ACPI
- select PERF_USE_VMALLOC
select POWER_RESET
select POWER_SUPPLY
select SPARSE_IRQ
@@ -122,6 +121,9 @@ config ARCH_PHYS_ADDR_T_64BIT
config MMU
def_bool y
+config DEBUG_RODATA
+ def_bool y
+
config ARM64_PAGE_SHIFT
int
default 16 if ARM64_64K_PAGES
@@ -415,18 +417,13 @@ config ARM64_ERRATUM_845719
config ARM64_ERRATUM_843419
bool "Cortex-A53: 843419: A load or store might access an incorrect address"
- depends on MODULES
default y
- select ARM64_MODULE_CMODEL_LARGE
+ select ARM64_MODULE_CMODEL_LARGE if MODULES
help
- This option builds kernel modules using the large memory model in
- order to avoid the use of the ADRP instruction, which can cause
- a subsequent memory access to use an incorrect address on Cortex-A53
- parts up to r0p4.
-
- Note that the kernel itself must be linked with a version of ld
- which fixes potentially affected ADRP instructions through the
- use of veneers.
+ This option links the kernel with '--fix-cortex-a53-843419' and
+ builds modules using the large memory model in order to avoid the use
+ of the ADRP instruction, which can cause a subsequent memory access
+ to use an incorrect address on Cortex-A53 parts up to r0p4.
If unsure, say Y.
@@ -582,7 +579,8 @@ config HOTPLUG_CPU
# Common NUMA Features
config NUMA
bool "Numa Memory Allocation and Scheduler Support"
- depends on SMP
+ select ACPI_NUMA if ACPI
+ select OF_NUMA
help
Enable NUMA (Non Uniform Memory Access) support.
@@ -603,11 +601,18 @@ config USE_PERCPU_NUMA_NODE_ID
def_bool y
depends on NUMA
+config HAVE_SETUP_PER_CPU_AREA
+ def_bool y
+ depends on NUMA
+
+config NEED_PER_CPU_EMBED_FIRST_CHUNK
+ def_bool y
+ depends on NUMA
+
source kernel/Kconfig.preempt
source kernel/Kconfig.hz
config ARCH_SUPPORTS_DEBUG_PAGEALLOC
- depends on !HIBERNATION
def_bool y
config ARCH_HAS_HOLES_MEMORYMODEL
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
index 0cc758cdd0dc..b661fe742615 100644
--- a/arch/arm64/Kconfig.debug
+++ b/arch/arm64/Kconfig.debug
@@ -49,16 +49,6 @@ config DEBUG_SET_MODULE_RONX
If in doubt, say Y.
-config DEBUG_RODATA
- bool "Make kernel text and rodata read-only"
- default y
- help
- If this is set, kernel text and rodata will be made read-only. This
- is to help catch accidental or malicious attempts to change the
- kernel's executable code.
-
- If in doubt, say Y.
-
config DEBUG_ALIGN_RODATA
depends on DEBUG_RODATA
bool "Align linker sections up to SECTION_SIZE"
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index be5d824ebdba..cfbdf02ef566 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -3,6 +3,8 @@ menu "Platform selection"
config ARCH_SUNXI
bool "Allwinner sunxi 64-bit SoC Family"
select GENERIC_IRQ_CHIP
+ select PINCTRL
+ select PINCTRL_SUN50I_A64
help
This enables support for Allwinner sunxi based SoCs like the A64.
@@ -15,8 +17,8 @@ config ARCH_ALPINE
config ARCH_BCM2835
bool "Broadcom BCM2835 family"
- select ARCH_REQUIRE_GPIOLIB
select CLKSRC_OF
+ select GPIOLIB
select PINCTRL
select PINCTRL_BCM2835
select ARM_AMBA
@@ -29,19 +31,26 @@ config ARCH_BCM2835
config ARCH_BCM_IPROC
bool "Broadcom iProc SoC Family"
select COMMON_CLK_IPROC
+ select GPIOLIB
select PINCTRL
- select ARCH_REQUIRE_GPIOLIB
help
This enables support for Broadcom iProc based SoCs
config ARCH_BERLIN
bool "Marvell Berlin SoC Family"
- select ARCH_REQUIRE_GPIOLIB
select DW_APB_ICTL
+ select GPIOLIB
select PINCTRL
help
This enables support for Marvell Berlin SoC Family
+config ARCH_BRCMSTB
+ bool "Broadcom Set-Top-Box SoCs"
+ select BRCMSTB_L2_IRQ
+ select GENERIC_IRQ_CHIP
+ help
+ This enables support for Broadcom's ARMv8 Set Top Box SoCs
+
config ARCH_EXYNOS
bool "ARMv8 based Samsung Exynos SoC family"
select COMMON_CLK_SAMSUNG
@@ -55,6 +64,7 @@ config ARCH_EXYNOS
config ARCH_LAYERSCAPE
bool "ARMv8 based Freescale Layerscape SoC family"
+ select EDAC_SUPPORT
help
This enables support for the Freescale Layerscape SoC family.
@@ -67,6 +77,7 @@ config ARCH_HISI
bool "Hisilicon SoC Family"
select ARM_TIMER_SP804
select HISILICON_IRQ_MBIGEN if PCI
+ select PINCTRL
help
This enables support for Hisilicon ARMv8 SoC family
@@ -93,6 +104,7 @@ config ARCH_MVEBU
select ARMADA_CP110_SYSCON
select ARMADA_37XX_CLK
select MVEBU_ODMI
+ select MVEBU_PIC
help
This enables support for Marvell EBU familly, including:
- Armada 3700 SoC Family
@@ -108,7 +120,7 @@ config ARCH_QCOM
config ARCH_ROCKCHIP
bool "Rockchip Platforms"
select ARCH_HAS_RESET_CONTROLLER
- select ARCH_REQUIRE_GPIOLIB
+ select GPIOLIB
select PINCTRL
select PINCTRL_ROCKCHIP
select ROCKCHIP_TIMER
@@ -154,13 +166,14 @@ config ARCH_STRATIX10
config ARCH_TEGRA
bool "NVIDIA Tegra SoC Family"
select ARCH_HAS_RESET_CONTROLLER
- select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP
select CLKSRC_MMIO
select CLKSRC_OF
select GENERIC_CLOCKEVENTS
- select HAVE_CLK
+ select GPIOLIB
select PINCTRL
+ select PM
+ select PM_GENERIC_DOMAINS
select RESET_CONTROLLER
help
This enables support for the NVIDIA Tegra SoC family.
@@ -183,8 +196,8 @@ config ARCH_UNIPHIER
config ARCH_VEXPRESS
bool "ARMv8 software model (Versatile Express)"
- select ARCH_REQUIRE_GPIOLIB
select COMMON_CLK_VERSATILE
+ select GPIOLIB
select PM
select PM_GENERIC_DOMAINS
select POWER_RESET_VEXPRESS
@@ -204,6 +217,11 @@ config ARCH_XGENE
help
This enables support for AppliedMicro X-Gene SOC Family
+config ARCH_ZX
+ bool "ZTE ZX SoC Family"
+ help
+ This enables support for ZTE ZX SoC Family
+
config ARCH_ZYNQMP
bool "Xilinx ZynqMP Family"
help
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 5b54f8c021d8..ab51aed6b6c1 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -18,6 +18,14 @@ ifneq ($(CONFIG_RELOCATABLE),)
LDFLAGS_vmlinux += -pie -Bsymbolic
endif
+ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
+ ifeq ($(call ld-option, --fix-cortex-a53-843419),)
+$(warning ld does not support --fix-cortex-a53-843419; kernel may be susceptible to erratum)
+ else
+LDFLAGS_vmlinux += --fix-cortex-a53-843419
+ endif
+endif
+
KBUILD_DEFCONFIG := defconfig
# Check for binutils support for specific extensions
@@ -38,10 +46,12 @@ ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
KBUILD_CPPFLAGS += -mbig-endian
AS += -EB
LD += -EB
+UTS_MACHINE := aarch64_be
else
KBUILD_CPPFLAGS += -mlittle-endian
AS += -EL
LD += -EL
+UTS_MACHINE := aarch64
endif
CHECKFLAGS += -D__aarch64__
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 6e199c903676..6684f97c2722 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -19,6 +19,7 @@ dts-dirs += socionext
dts-dirs += sprd
dts-dirs += xilinx
dts-dirs += lg
+dts-dirs += zte
subdir-y := $(dts-dirs)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index 90a84c514d3d..e6e3491d48a5 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -87,3 +87,14 @@
pinctrl-names = "default";
};
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+};
+
+&i2c_A {
+ status = "okay";
+ pinctrl-0 = <&i2c_a_pins>;
+ pinctrl-names = "default";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
index 62979076e250..03e3d76626dd 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
@@ -50,3 +50,9 @@
compatible = "amlogic,p200", "amlogic,meson-gxbb";
model = "Amlogic Meson GXBB P200 Development Board";
};
+
+&i2c_B {
+ status = "okay";
+ pinctrl-0 = <&i2c_b_pins>;
+ pinctrl-names = "default";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
index f4f30f674b4c..06a34dc6002f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
@@ -57,6 +57,19 @@
device_type = "memory";
reg = <0x0 0x0 0x0 0x40000000>;
};
+
+ usb_pwr: regulator-usb-pwrs {
+ compatible = "regulator-fixed";
+
+ regulator-name = "USB_PWR";
+
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+
+ /* signal name in schematic: USB_PWR_EN */
+ gpio = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
};
/* This UART is brought out to the DB9 connector */
@@ -72,3 +85,25 @@
pinctrl-names = "default";
};
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+};
+
+&usb0_phy {
+ status = "okay";
+ phy-supply = <&usb_pwr>;
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
index 54bb7c739089..73f159370188 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
@@ -52,6 +52,19 @@
chosen {
stdout-path = "serial0:115200n8";
};
+
+ usb_vbus: regulator-usb0-vbus {
+ compatible = "regulator-fixed";
+
+ regulator-name = "USB0_VBUS";
+
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+
+ gpio = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
};
&uart_AO {
@@ -60,3 +73,32 @@
pinctrl-names = "default";
};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+};
+
+&ethmac {
+ status = "okay";
+ pinctrl-0 = <&eth_pins>;
+ pinctrl-names = "default";
+};
+
+&usb0_phy {
+ status = "okay";
+ phy-supply = <&usb_vbus>;
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index bf6c8d051002..610e0e1c3cee 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -45,6 +45,9 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/gpio/meson-gxbb-gpio.h>
#include <dt-bindings/reset/amlogic,meson-gxbb-reset.h>
+#include <dt-bindings/clock/gxbb-clkc.h>
+#include <dt-bindings/clock/gxbb-aoclkc.h>
+#include <dt-bindings/reset/gxbb-aoclkc.h>
/ {
compatible = "amlogic,meson-gxbb";
@@ -99,6 +102,30 @@
method = "smc";
};
+ firmware {
+ sm: secure-monitor {
+ compatible = "amlogic,meson-gxbb-sm";
+ };
+ };
+
+ efuse: efuse {
+ compatible = "amlogic,meson-gxbb-efuse";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ sn: sn@14 {
+ reg = <0x14 0x10>;
+ };
+
+ eth_mac: eth_mac@34 {
+ reg = <0x34 0x10>;
+ };
+
+ bid: bid@46 {
+ reg = <0x46 0x30>;
+ };
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13
@@ -124,6 +151,25 @@
#size-cells = <2>;
ranges;
+ usb0_phy: phy@c0000000 {
+ compatible = "amlogic,meson-gxbb-usb2-phy";
+ #phy-cells = <0>;
+ reg = <0x0 0xc0000000 0x0 0x20>;
+ resets = <&reset RESET_USB_OTG>;
+ clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB0>;
+ clock-names = "usb_general", "usb";
+ status = "disabled";
+ };
+
+ usb1_phy: phy@c0000020 {
+ compatible = "amlogic,meson-gxbb-usb2-phy";
+ #phy-cells = <0>;
+ reg = <0x0 0xc0000020 0x0 0x20>;
+ clocks = <&clkc CLKID_USB>, <&clkc CLKID_USB1>;
+ clock-names = "usb_general", "usb";
+ status = "disabled";
+ };
+
cbus: cbus@c1100000 {
compatible = "simple-bus";
reg = <0x0 0xc1100000 0x0 0x100000>;
@@ -153,6 +199,27 @@
status = "disabled";
};
+ pwm_ab: pwm@8550 {
+ compatible = "amlogic,meson-gxbb-pwm";
+ reg = <0x0 0x08550 0x0 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm_cd: pwm@8650 {
+ compatible = "amlogic,meson-gxbb-pwm";
+ reg = <0x0 0x08650 0x0 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm_ef: pwm@86c0 {
+ compatible = "amlogic,meson-gxbb-pwm";
+ reg = <0x0 0x086c0 0x0 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
uart_C: serial@8700 {
compatible = "amlogic,meson-uart";
reg = <0x0 0x8700 0x0 0x14>;
@@ -160,6 +227,51 @@
clocks = <&xtal>;
status = "disabled";
};
+
+ watchdog@98d0 {
+ compatible = "amlogic,meson-gxbb-wdt";
+ reg = <0x0 0x098d0 0x0 0x10>;
+ clocks = <&xtal>;
+ };
+
+ spifc: spi@8c80 {
+ compatible = "amlogic,meson-gxbb-spifc";
+ reg = <0x0 0x08c80 0x0 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clkc CLKID_SPI>;
+ status = "disabled";
+ };
+
+ i2c_A: i2c@8500 {
+ compatible = "amlogic,meson-gxbb-i2c";
+ reg = <0x0 0x08500 0x0 0x20>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_I2C>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c_B: i2c@87c0 {
+ compatible = "amlogic,meson-gxbb-i2c";
+ reg = <0x0 0x087c0 0x0 0x20>;
+ interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_I2C>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c_C: i2c@87e0 {
+ compatible = "amlogic,meson-gxbb-i2c";
+ reg = <0x0 0x087e0 0x0 0x20>;
+ interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_I2C>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
gic: interrupt-controller@c4301000 {
@@ -203,6 +315,56 @@
function = "uart_ao";
};
};
+
+ remote_input_ao_pins: remote_input_ao {
+ mux {
+ groups = "remote_input_ao";
+ function = "remote_input_ao";
+ };
+ };
+
+ i2c_ao_pins: i2c_ao {
+ mux {
+ groups = "i2c_sck_ao",
+ "i2c_sda_ao";
+ function = "i2c_ao";
+ };
+ };
+
+ pwm_ao_a_3_pins: pwm_ao_a_3 {
+ mux {
+ groups = "pwm_ao_a_3";
+ function = "pwm_ao_a_3";
+ };
+ };
+
+ pwm_ao_a_6_pins: pwm_ao_a_6 {
+ mux {
+ groups = "pwm_ao_a_6";
+ function = "pwm_ao_a_6";
+ };
+ };
+
+ pwm_ao_a_12_pins: pwm_ao_a_12 {
+ mux {
+ groups = "pwm_ao_a_12";
+ function = "pwm_ao_a_12";
+ };
+ };
+
+ pwm_ao_b_pins: pwm_ao_b {
+ mux {
+ groups = "pwm_ao_b";
+ function = "pwm_ao_b";
+ };
+ };
+ };
+
+ clkc_AO: clock-controller@040 {
+ compatible = "amlogic,gxbb-aoclkc";
+ reg = <0x0 0x00040 0x0 0x4>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
};
uart_AO: serial@4c0 {
@@ -212,6 +374,30 @@
clocks = <&xtal>;
status = "disabled";
};
+
+ ir: ir@580 {
+ compatible = "amlogic,meson-gxbb-ir";
+ reg = <0x0 0x00580 0x0 0x40>;
+ interrupts = <GIC_SPI 196 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+
+ pwm_ab_AO: pwm@550 {
+ compatible = "amlogic,meson-gxbb-pwm";
+ reg = <0x0 0x0550 0x0 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ i2c_AO: i2c@500 {
+ compatible = "amlogic,meson-gxbb-i2c";
+ reg = <0x0 0x500 0x0 0x20>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_AO_I2C>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
periphs: periphs@c8834000 {
@@ -251,6 +437,16 @@
};
};
+ nor_pins: nor {
+ mux {
+ groups = "nor_d",
+ "nor_q",
+ "nor_c",
+ "nor_cs";
+ function = "nor";
+ };
+ };
+
sdcard_pins: sdcard {
mux {
groups = "sdcard_d0",
@@ -263,6 +459,25 @@
};
};
+ sdio_pins: sdio {
+ mux {
+ groups = "sdio_d0",
+ "sdio_d1",
+ "sdio_d2",
+ "sdio_d3",
+ "sdio_cmd",
+ "sdio_clk";
+ function = "sdio";
+ };
+ };
+
+ sdio_irq_pins: sdio_irq {
+ mux {
+ groups = "sdio_irq";
+ function = "sdio";
+ };
+ };
+
uart_a_pins: uart_a {
mux {
groups = "uart_tx_a",
@@ -287,6 +502,30 @@
};
};
+ i2c_a_pins: i2c_a {
+ mux {
+ groups = "i2c_sck_a",
+ "i2c_sda_a";
+ function = "i2c_a";
+ };
+ };
+
+ i2c_b_pins: i2c_b {
+ mux {
+ groups = "i2c_sck_b",
+ "i2c_sda_b";
+ function = "i2c_b";
+ };
+ };
+
+ i2c_c_pins: i2c_c {
+ mux {
+ groups = "i2c_sck_c",
+ "i2c_sda_c";
+ function = "i2c_c";
+ };
+ };
+
eth_pins: eth_c {
mux {
groups = "eth_mdio",
@@ -306,6 +545,55 @@
function = "eth";
};
};
+
+ pwm_a_x_pins: pwm_a_x {
+ mux {
+ groups = "pwm_a_x";
+ function = "pwm_a_x";
+ };
+ };
+
+ pwm_a_y_pins: pwm_a_y {
+ mux {
+ groups = "pwm_a_y";
+ function = "pwm_a_y";
+ };
+ };
+
+ pwm_b_pins: pwm_b {
+ mux {
+ groups = "pwm_b";
+ function = "pwm_b";
+ };
+ };
+
+ pwm_d_pins: pwm_d {
+ mux {
+ groups = "pwm_d";
+ function = "pwm_d";
+ };
+ };
+
+ pwm_e_pins: pwm_e {
+ mux {
+ groups = "pwm_e";
+ function = "pwm_e";
+ };
+ };
+
+ pwm_f_x_pins: pwm_f_x {
+ mux {
+ groups = "pwm_f_x";
+ function = "pwm_f_x";
+ };
+ };
+
+ pwm_f_y_pins: pwm_f_y {
+ mux {
+ groups = "pwm_f_y";
+ function = "pwm_f_y";
+ };
+ };
};
};
@@ -321,6 +609,15 @@
#clock-cells = <1>;
reg = <0x0 0x0 0x0 0x3db>;
};
+
+ mailbox: mailbox@404 {
+ compatible = "amlogic,meson-gxbb-mhu";
+ reg = <0 0x404 0 0x4c>;
+ interrupts = <0 208 IRQ_TYPE_EDGE_RISING>,
+ <0 209 IRQ_TYPE_EDGE_RISING>,
+ <0 210 IRQ_TYPE_EDGE_RISING>;
+ #mbox-cells = <1>;
+ };
};
apb: apb@d0000000 {
@@ -331,14 +628,40 @@
ranges = <0x0 0x0 0x0 0xd0000000 0x0 0x200000>;
};
+ usb0: usb@c9000000 {
+ compatible = "amlogic,meson-gxbb-usb", "snps,dwc2";
+ reg = <0x0 0xc9000000 0x0 0x40000>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLKID_USB0_DDR_BRIDGE>;
+ clock-names = "otg";
+ phys = <&usb0_phy>;
+ phy-names = "usb2-phy";
+ dr_mode = "host";
+ status = "disabled";
+ };
+
+ usb1: usb@c9100000 {
+ compatible = "amlogic,meson-gxbb-usb", "snps,dwc2";
+ reg = <0x0 0xc9100000 0x0 0x40000>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLKID_USB1_DDR_BRIDGE>;
+ clock-names = "otg";
+ phys = <&usb1_phy>;
+ phy-names = "usb2-phy";
+ dr_mode = "host";
+ status = "disabled";
+ };
+
ethmac: ethernet@c9410000 {
- compatible = "amlogic,meson6-dwmac", "snps,dwmac";
+ compatible = "amlogic,meson-gxbb-dwmac", "snps,dwmac";
reg = <0x0 0xc9410000 0x0 0x10000
0x0 0xc8834540 0x0 0x4>;
interrupts = <0 8 1>;
interrupt-names = "macirq";
- clocks = <&xtal>;
- clock-names = "stmmaceth";
+ clocks = <&clkc CLKID_ETH>,
+ <&clkc CLKID_FCLK_DIV2>,
+ <&clkc CLKID_MPLL2>;
+ clock-names = "stmmaceth", "clkin0", "clkin1";
phy-mode = "rgmii";
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/apm/apm-mustang.dts b/arch/arm64/boot/dts/apm/apm-mustang.dts
index b7fb5d9295c2..32a961c5e98a 100644
--- a/arch/arm64/boot/dts/apm/apm-mustang.dts
+++ b/arch/arm64/boot/dts/apm/apm-mustang.dts
@@ -74,6 +74,7 @@
&xgenet {
status = "ok";
+ rxlos-gpios = <&sbgpio 12 1>;
};
&mmc0 {
diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
index 1425ed41620c..72720e9132a1 100644
--- a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
@@ -26,6 +26,8 @@
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
next-level-cache = <&xgene_L2_0>;
+ #clock-cells = <1>;
+ clocks = <&pmd0clk 0>;
};
cpu@001 {
device_type = "cpu";
@@ -34,6 +36,8 @@
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
next-level-cache = <&xgene_L2_0>;
+ #clock-cells = <1>;
+ clocks = <&pmd0clk 0>;
};
cpu@100 {
device_type = "cpu";
@@ -42,6 +46,8 @@
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
next-level-cache = <&xgene_L2_1>;
+ #clock-cells = <1>;
+ clocks = <&pmd1clk 0>;
};
cpu@101 {
device_type = "cpu";
@@ -50,6 +56,8 @@
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
next-level-cache = <&xgene_L2_1>;
+ #clock-cells = <1>;
+ clocks = <&pmd1clk 0>;
};
cpu@200 {
device_type = "cpu";
@@ -58,6 +66,8 @@
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
next-level-cache = <&xgene_L2_2>;
+ #clock-cells = <1>;
+ clocks = <&pmd2clk 0>;
};
cpu@201 {
device_type = "cpu";
@@ -66,6 +76,8 @@
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
next-level-cache = <&xgene_L2_2>;
+ #clock-cells = <1>;
+ clocks = <&pmd2clk 0>;
};
cpu@300 {
device_type = "cpu";
@@ -74,6 +86,8 @@
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
next-level-cache = <&xgene_L2_3>;
+ #clock-cells = <1>;
+ clocks = <&pmd3clk 0>;
};
cpu@301 {
device_type = "cpu";
@@ -82,6 +96,8 @@
enable-method = "spin-table";
cpu-release-addr = <0x1 0x0000fff8>;
next-level-cache = <&xgene_L2_3>;
+ #clock-cells = <1>;
+ clocks = <&pmd3clk 0>;
};
xgene_L2_0: l2-cache-0 {
compatible = "cache";
@@ -223,6 +239,46 @@
clock-output-names = "refclk";
};
+ pmdpll: pmdpll@170000f0 {
+ compatible = "apm,xgene-pcppll-v2-clock";
+ #clock-cells = <1>;
+ clocks = <&refclk 0>;
+ reg = <0x0 0x170000f0 0x0 0x10>;
+ clock-output-names = "pmdpll";
+ };
+
+ pmd0clk: pmd0clk@7e200200 {
+ compatible = "apm,xgene-pmd-clock";
+ #clock-cells = <1>;
+ clocks = <&pmdpll 0>;
+ reg = <0x0 0x7e200200 0x0 0x10>;
+ clock-output-names = "pmd0clk";
+ };
+
+ pmd1clk: pmd1clk@7e200210 {
+ compatible = "apm,xgene-pmd-clock";
+ #clock-cells = <1>;
+ clocks = <&pmdpll 0>;
+ reg = <0x0 0x7e200210 0x0 0x10>;
+ clock-output-names = "pmd1clk";
+ };
+
+ pmd2clk: pmd2clk@7e200220 {
+ compatible = "apm,xgene-pmd-clock";
+ #clock-cells = <1>;
+ clocks = <&pmdpll 0>;
+ reg = <0x0 0x7e200220 0x0 0x10>;
+ clock-output-names = "pmd2clk";
+ };
+
+ pmd3clk: pmd3clk@7e200230 {
+ compatible = "apm,xgene-pmd-clock";
+ #clock-cells = <1>;
+ clocks = <&pmdpll 0>;
+ reg = <0x0 0x7e200230 0x0 0x10>;
+ clock-output-names = "pmd3clk";
+ };
+
socpll: socpll@17000120 {
compatible = "apm,xgene-socpll-v2-clock";
#clock-cells = <1>;
@@ -453,6 +509,64 @@
};
};
+ pmu: pmu@78810000 {
+ compatible = "apm,xgene-pmu-v2";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ regmap-csw = <&csw>;
+ regmap-mcba = <&mcba>;
+ regmap-mcbb = <&mcbb>;
+ reg = <0x0 0x78810000 0x0 0x1000>;
+ interrupts = <0x0 0x22 0x4>;
+
+ pmul3c@7e610000 {
+ compatible = "apm,xgene-pmu-l3c";
+ reg = <0x0 0x7e610000 0x0 0x1000>;
+ };
+
+ pmuiob@7e940000 {
+ compatible = "apm,xgene-pmu-iob";
+ reg = <0x0 0x7e940000 0x0 0x1000>;
+ };
+
+ pmucmcb@7e710000 {
+ compatible = "apm,xgene-pmu-mcb";
+ reg = <0x0 0x7e710000 0x0 0x1000>;
+ enable-bit-index = <0>;
+ };
+
+ pmucmcb@7e730000 {
+ compatible = "apm,xgene-pmu-mcb";
+ reg = <0x0 0x7e730000 0x0 0x1000>;
+ enable-bit-index = <1>;
+ };
+
+ pmucmc@7e810000 {
+ compatible = "apm,xgene-pmu-mc";
+ reg = <0x0 0x7e810000 0x0 0x1000>;
+ enable-bit-index = <0>;
+ };
+
+ pmucmc@7e850000 {
+ compatible = "apm,xgene-pmu-mc";
+ reg = <0x0 0x7e850000 0x0 0x1000>;
+ enable-bit-index = <1>;
+ };
+
+ pmucmc@7e890000 {
+ compatible = "apm,xgene-pmu-mc";
+ reg = <0x0 0x7e890000 0x0 0x1000>;
+ enable-bit-index = <2>;
+ };
+
+ pmucmc@7e8d0000 {
+ compatible = "apm,xgene-pmu-mc";
+ reg = <0x0 0x7e8d0000 0x0 0x1000>;
+ enable-bit-index = <3>;
+ };
+ };
+
mailbox: mailbox@10540000 {
compatible = "apm,xgene-slimpro-mbox";
reg = <0x0 0x10540000 0x0 0x8000>;
@@ -472,6 +586,11 @@
mboxes = <&mailbox 0>;
};
+ hwmonslimpro {
+ compatible = "apm,xgene-slimpro-hwmon";
+ mboxes = <&mailbox 7>;
+ };
+
serial0: serial@10600000 {
device_type = "serial";
compatible = "ns16550";
@@ -508,10 +627,10 @@
dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
- interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0x0 0x0 0x10 0x1
- 0x0 0x0 0x0 0x2 &gic 0x0 0x0 0x0 0x11 0x1
- 0x0 0x0 0x0 0x3 &gic 0x0 0x0 0x0 0x12 0x1
- 0x0 0x0 0x0 0x4 &gic 0x0 0x0 0x0 0x13 0x1>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0x0 0x0 0x10 0x4
+ 0x0 0x0 0x0 0x2 &gic 0x0 0x0 0x0 0x11 0x4
+ 0x0 0x0 0x0 0x3 &gic 0x0 0x0 0x0 0x12 0x4
+ 0x0 0x0 0x0 0x4 &gic 0x0 0x0 0x0 0x13 0x4>;
dma-coherent;
clocks = <&pcie0clk 0>;
msi-parent = <&v2m0>;
@@ -533,10 +652,10 @@
dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
- interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0x0 0x0 0x16 0x1
- 0x0 0x0 0x0 0x2 &gic 0x0 0x0 0x0 0x17 0x1
- 0x0 0x0 0x0 0x3 &gic 0x0 0x0 0x0 0x18 0x1
- 0x0 0x0 0x0 0x4 &gic 0x0 0x0 0x0 0x19 0x1>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0x0 0x0 0x16 0x4
+ 0x0 0x0 0x0 0x2 &gic 0x0 0x0 0x0 0x17 0x4
+ 0x0 0x0 0x0 0x3 &gic 0x0 0x0 0x0 0x18 0x4
+ 0x0 0x0 0x0 0x4 &gic 0x0 0x0 0x0 0x19 0x4>;
dma-coherent;
clocks = <&pcie1clk 0>;
msi-parent = <&v2m0>;
diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi
index c29dab9d1834..63be8e51eaa8 100644
--- a/arch/arm64/boot/dts/apm/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi
@@ -553,6 +553,64 @@
};
};
+ pmu: pmu@78810000 {
+ compatible = "apm,xgene-pmu-v2";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ regmap-csw = <&csw>;
+ regmap-mcba = <&mcba>;
+ regmap-mcbb = <&mcbb>;
+ reg = <0x0 0x78810000 0x0 0x1000>;
+ interrupts = <0x0 0x22 0x4>;
+
+ pmul3c@7e610000 {
+ compatible = "apm,xgene-pmu-l3c";
+ reg = <0x0 0x7e610000 0x0 0x1000>;
+ };
+
+ pmuiob@7e940000 {
+ compatible = "apm,xgene-pmu-iob";
+ reg = <0x0 0x7e940000 0x0 0x1000>;
+ };
+
+ pmucmcb@7e710000 {
+ compatible = "apm,xgene-pmu-mcb";
+ reg = <0x0 0x7e710000 0x0 0x1000>;
+ enable-bit-index = <0>;
+ };
+
+ pmucmcb@7e730000 {
+ compatible = "apm,xgene-pmu-mcb";
+ reg = <0x0 0x7e730000 0x0 0x1000>;
+ enable-bit-index = <1>;
+ };
+
+ pmucmc@7e810000 {
+ compatible = "apm,xgene-pmu-mc";
+ reg = <0x0 0x7e810000 0x0 0x1000>;
+ enable-bit-index = <0>;
+ };
+
+ pmucmc@7e850000 {
+ compatible = "apm,xgene-pmu-mc";
+ reg = <0x0 0x7e850000 0x0 0x1000>;
+ enable-bit-index = <1>;
+ };
+
+ pmucmc@7e890000 {
+ compatible = "apm,xgene-pmu-mc";
+ reg = <0x0 0x7e890000 0x0 0x1000>;
+ enable-bit-index = <2>;
+ };
+
+ pmucmc@7e8d0000 {
+ compatible = "apm,xgene-pmu-mc";
+ reg = <0x0 0x7e8d0000 0x0 0x1000>;
+ enable-bit-index = <3>;
+ };
+ };
+
pcie0: pcie@1f2b0000 {
status = "disabled";
device_type = "pci";
@@ -569,10 +627,10 @@
dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
- interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc2 0x1
- 0x0 0x0 0x0 0x2 &gic 0x0 0xc3 0x1
- 0x0 0x0 0x0 0x3 &gic 0x0 0xc4 0x1
- 0x0 0x0 0x0 0x4 &gic 0x0 0xc5 0x1>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc2 0x4
+ 0x0 0x0 0x0 0x2 &gic 0x0 0xc3 0x4
+ 0x0 0x0 0x0 0x3 &gic 0x0 0xc4 0x4
+ 0x0 0x0 0x0 0x4 &gic 0x0 0xc5 0x4>;
dma-coherent;
clocks = <&pcie0clk 0>;
msi-parent = <&msi>;
@@ -594,10 +652,10 @@
dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
- interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc8 0x1
- 0x0 0x0 0x0 0x2 &gic 0x0 0xc9 0x1
- 0x0 0x0 0x0 0x3 &gic 0x0 0xca 0x1
- 0x0 0x0 0x0 0x4 &gic 0x0 0xcb 0x1>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc8 0x4
+ 0x0 0x0 0x0 0x2 &gic 0x0 0xc9 0x4
+ 0x0 0x0 0x0 0x3 &gic 0x0 0xca 0x4
+ 0x0 0x0 0x0 0x4 &gic 0x0 0xcb 0x4>;
dma-coherent;
clocks = <&pcie1clk 0>;
msi-parent = <&msi>;
@@ -619,10 +677,10 @@
dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
- interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xce 0x1
- 0x0 0x0 0x0 0x2 &gic 0x0 0xcf 0x1
- 0x0 0x0 0x0 0x3 &gic 0x0 0xd0 0x1
- 0x0 0x0 0x0 0x4 &gic 0x0 0xd1 0x1>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xce 0x4
+ 0x0 0x0 0x0 0x2 &gic 0x0 0xcf 0x4
+ 0x0 0x0 0x0 0x3 &gic 0x0 0xd0 0x4
+ 0x0 0x0 0x0 0x4 &gic 0x0 0xd1 0x4>;
dma-coherent;
clocks = <&pcie2clk 0>;
msi-parent = <&msi>;
@@ -644,10 +702,10 @@
dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
- interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xd4 0x1
- 0x0 0x0 0x0 0x2 &gic 0x0 0xd5 0x1
- 0x0 0x0 0x0 0x3 &gic 0x0 0xd6 0x1
- 0x0 0x0 0x0 0x4 &gic 0x0 0xd7 0x1>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xd4 0x4
+ 0x0 0x0 0x0 0x2 &gic 0x0 0xd5 0x4
+ 0x0 0x0 0x0 0x3 &gic 0x0 0xd6 0x4
+ 0x0 0x0 0x0 0x4 &gic 0x0 0xd7 0x4>;
dma-coherent;
clocks = <&pcie3clk 0>;
msi-parent = <&msi>;
@@ -669,10 +727,10 @@
dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
- interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xda 0x1
- 0x0 0x0 0x0 0x2 &gic 0x0 0xdb 0x1
- 0x0 0x0 0x0 0x3 &gic 0x0 0xdc 0x1
- 0x0 0x0 0x0 0x4 &gic 0x0 0xdd 0x1>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xda 0x4
+ 0x0 0x0 0x0 0x2 &gic 0x0 0xdb 0x4
+ 0x0 0x0 0x0 0x3 &gic 0x0 0xdc 0x4
+ 0x0 0x0 0x0 0x4 &gic 0x0 0xdd 0x4>;
dma-coherent;
clocks = <&pcie4clk 0>;
msi-parent = <&msi>;
@@ -697,6 +755,11 @@
mboxes = <&mailbox 0>;
};
+ hwmonslimpro {
+ compatible = "apm,xgene-slimpro-hwmon";
+ mboxes = <&mailbox 7>;
+ };
+
serial0: serial@1c020000 {
status = "disabled";
device_type = "serial";
@@ -923,7 +986,7 @@
/* mac address will be overwritten by the bootloader */
local-mac-address = [00 00 00 00 00 00];
phy-connection-type = "rgmii";
- phy-handle = <&menet0phy>,<&menetphy>;
+ phy-handle = <&menetphy>,<&menet0phy>;
mdio {
compatible = "apm,xgene-mdio";
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi
index d4a12fad8afd..d95dc408629a 100644
--- a/arch/arm64/boot/dts/broadcom/ns2.dtsi
+++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi
@@ -299,6 +299,14 @@
};
};
+ pwm: pwm@66010000 {
+ compatible = "brcm,iproc-pwm";
+ reg = <0x66010000 0x28>;
+ clocks = <&osc>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
mdio_mux_iproc: mdio-mux@6602023c {
compatible = "brcm,mdio-mux-iproc";
reg = <0x6602023c 0x14>;
diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index 162831546e18..6328a66ed97e 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -10,6 +10,7 @@
*/
#include <dt-bindings/clock/exynos7-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
compatible = "samsung,exynos7";
@@ -473,10 +474,14 @@
timer {
compatible = "arm,armv8-timer";
- interrupts = <1 13 0xff08>,
- <1 14 0xff08>,
- <1 11 0xff08>,
- <1 10 0xff08>;
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14
+ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11
+ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10
+ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
};
pmu_system_controller: system-controller@105c0000 {
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts
index 9d3e9fe1c87c..dd9e91941df4 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts
@@ -56,12 +56,14 @@
gpio1 = &gpio2;
gpio2 = &gpio3;
gpio3 = &gpio4;
- serial0 = &lpuart0;
- serial1 = &lpuart1;
- serial2 = &lpuart2;
- serial3 = &lpuart3;
- serial4 = &lpuart4;
- serial5 = &lpuart5;
+ serial0 = &duart0;
+ serial1 = &duart1;
+ serial2 = &duart2;
+ serial3 = &duart3;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
};
};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
index 40846319be69..d2313e05fd22 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
@@ -52,6 +52,14 @@
aliases {
crypto = &crypto;
+ serial0 = &duart0;
+ serial1 = &duart1;
+ serial2 = &duart2;
+ serial3 = &duart3;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
};
};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
index a67e210e2019..58635f7f4668 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
@@ -247,6 +247,13 @@
bus-width = <4>;
};
+ ddr: memory-controller@1080000 {
+ compatible = "fsl,qoriq-memory-controller";
+ reg = <0x0 0x1080000 0x0 0x1000>;
+ interrupts = <0 144 0x4>;
+ big-endian;
+ };
+
dspi0: dspi@2100000 {
compatible = "fsl,ls1043a-dspi", "fsl,ls1021a-v1.0-dspi";
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts
index e8801faca996..b0dd010979e7 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts
@@ -57,6 +57,9 @@
serial1 = &serial1;
};
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
};
&esdhc {
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts
index e127f0baab19..ad0ebb8a1949 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts
@@ -56,6 +56,10 @@
serial0 = &serial0;
serial1 = &serial1;
};
+
+ chosen {
+ stdout-path = "serial1:115200n8";
+ };
};
&esdhc {
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
index e3b6034ea5d9..d1059765dfee 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
@@ -588,6 +588,7 @@
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
+ dma-coherent;
num-lanes = <4>;
bus-range = <0x0 0xff>;
ranges = <0x81000000 0x0 0x00000000 0x10 0x00010000 0x0 0x00010000 /* downstream I/O */
@@ -612,6 +613,7 @@
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
+ dma-coherent;
num-lanes = <4>;
bus-range = <0x0 0xff>;
ranges = <0x81000000 0x0 0x00000000 0x12 0x00010000 0x0 0x00010000 /* downstream I/O */
@@ -636,6 +638,7 @@
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
+ dma-coherent;
num-lanes = <8>;
bus-range = <0x0 0xff>;
ranges = <0x81000000 0x0 0x00000000 0x14 0x00010000 0x0 0x00010000 /* downstream I/O */
@@ -660,6 +663,7 @@
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
+ dma-coherent;
num-lanes = <4>;
bus-range = <0x0 0xff>;
ranges = <0x81000000 0x0 0x00000000 0x16 0x00010000 0x0 0x00010000 /* downstream I/O */
@@ -715,4 +719,18 @@
interrupts = <0 12 4>;
};
};
+
+ ddr1: memory-controller@1080000 {
+ compatible = "fsl,qoriq-memory-controller";
+ reg = <0x0 0x1080000 0x0 0x1000>;
+ interrupts = <0 17 0x4>;
+ little-endian;
+ };
+
+ ddr2: memory-controller@1090000 {
+ compatible = "fsl,qoriq-memory-controller";
+ reg = <0x0 0x1090000 0x0 0x1000>;
+ interrupts = <0 18 0x4>;
+ little-endian;
+ };
};
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
index 593c7e43de79..dba3c131c62c 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
@@ -29,16 +29,56 @@
* Reserve below regions from memory node:
*
* 0x05e0,0000 - 0x05ef,ffff: MCU firmware runtime using
+ * 0x05f0,1000 - 0x05f0,1fff: Reboot reason
* 0x06df,f000 - 0x06df,ffff: Mailbox message data
* 0x0740,f000 - 0x0740,ffff: MCU firmware section
+ * 0x21f0,0000 - 0x21ff,ffff: pstore/ramoops buffer
* 0x3e00,0000 - 0x3fff,ffff: OP-TEE
*/
memory@0 {
device_type = "memory";
reg = <0x00000000 0x00000000 0x00000000 0x05e00000>,
- <0x00000000 0x05f00000 0x00000000 0x00eff000>,
+ <0x00000000 0x05f00000 0x00000000 0x00001000>,
+ <0x00000000 0x05f02000 0x00000000 0x00efd000>,
<0x00000000 0x06e00000 0x00000000 0x0060f000>,
- <0x00000000 0x07410000 0x00000000 0x36bf0000>;
+ <0x00000000 0x07410000 0x00000000 0x1aaf0000>,
+ <0x00000000 0x22000000 0x00000000 0x1c000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ramoops@0x21f00000 {
+ compatible = "ramoops";
+ reg = <0x0 0x21f00000 0x0 0x00100000>;
+ record-size = <0x00020000>;
+ console-size = <0x00020000>;
+ ftrace-size = <0x00020000>;
+ };
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x00000000 0x08000000>;
+ linux,cma-default;
+ };
+ };
+
+ reboot-mode-syscon@5f01000 {
+ compatible = "syscon", "simple-mfd";
+ reg = <0x0 0x05f01000 0x0 0x00001000>;
+
+ reboot-mode {
+ compatible = "syscon-reboot-mode";
+ offset = <0x0>;
+
+ mode-normal = <0x77665501>;
+ mode-bootloader = <0x77665500>;
+ mode-recovery = <0x77665502>;
+ };
};
soc {
@@ -55,6 +95,8 @@
};
uart1: uart@f7111000 {
+ assigned-clocks = <&sys_ctrl HI6220_UART1_SRC>;
+ assigned-clock-rates = <150000000>;
status = "ok";
};
@@ -372,3 +414,43 @@
&uart3 {
label = "LS-UART1";
};
+
+&ade {
+ status = "ok";
+};
+
+&dsi {
+ status = "ok";
+
+ ports {
+ /* 1 for output port */
+ port@1 {
+ reg = <1>;
+
+ dsi_out0: endpoint@0 {
+ remote-endpoint = <&adv7533_in>;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "ok";
+
+ adv7533: adv7533@39 {
+ compatible = "adi,adv7533";
+ reg = <0x39>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <1 2>;
+ pd-gpio = <&gpio0 4 0>;
+ adi,dsi-lanes = <4>;
+
+ port {
+ adv7533_in: endpoint {
+ remote-endpoint = <&dsi_out0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index 4f270410a5cb..17839db585d5 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -262,6 +262,11 @@
#clock-cells = <1>;
};
+ medianoc_ade: medianoc_ade@f4520000 {
+ compatible = "syscon";
+ reg = <0x0 0xf4520000 0x0 0x4000>;
+ };
+
stub_clock: stub_clock {
compatible = "hisilicon,hi6220-stub-clk";
hisilicon,hi6220-clk-sram = <&sram>;
@@ -766,6 +771,7 @@
interrupts = <0x0 0x48 0x4>;
clocks = <&sys_ctrl 2>, <&sys_ctrl 1>;
clock-names = "ciu", "biu";
+ resets = <&sys_ctrl PERIPH_RSTDIS0_MMC0>;
bus-width = <0x8>;
vmmc-supply = <&ldo19>;
pinctrl-names = "default";
@@ -779,12 +785,16 @@
card-detect-delay = <200>;
hisilicon,peripheral-syscon = <&ao_ctrl>;
cap-sd-highspeed;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
reg = <0x0 0xf723e000 0x0 0x1000>;
interrupts = <0x0 0x49 0x4>;
#address-cells = <0x1>;
#size-cells = <0x0>;
clocks = <&sys_ctrl 4>, <&sys_ctrl 3>;
clock-names = "ciu", "biu";
+ resets = <&sys_ctrl PERIPH_RSTDIS0_MMC1>;
vqmmc-supply = <&ldo7>;
vmmc-supply = <&ldo10>;
bus-width = <0x4>;
@@ -802,6 +812,7 @@
interrupts = <0x0 0x4a 0x4>;
clocks = <&sys_ctrl HI6220_MMC2_CIUCLK>, <&sys_ctrl HI6220_MMC2_CLK>;
clock-names = "ciu", "biu";
+ resets = <&sys_ctrl PERIPH_RSTDIS0_MMC2>;
bus-width = <0x4>;
broken-cd;
pinctrl-names = "default", "idle";
@@ -850,5 +861,55 @@
};
};
};
+
+ ade: ade@f4100000 {
+ compatible = "hisilicon,hi6220-ade";
+ reg = <0x0 0xf4100000 0x0 0x7800>;
+ reg-names = "ade_base";
+ hisilicon,noc-syscon = <&medianoc_ade>;
+ resets = <&media_ctrl MEDIA_ADE>;
+ interrupts = <0 115 4>; /* ldi interrupt */
+
+ clocks = <&media_ctrl HI6220_ADE_CORE>,
+ <&media_ctrl HI6220_CODEC_JPEG>,
+ <&media_ctrl HI6220_ADE_PIX_SRC>;
+ /*clock name*/
+ clock-names = "clk_ade_core",
+ "clk_codec_jpeg",
+ "clk_ade_pix";
+
+ assigned-clocks = <&media_ctrl HI6220_ADE_CORE>,
+ <&media_ctrl HI6220_CODEC_JPEG>;
+ assigned-clock-rates = <360000000>, <288000000>;
+ dma-coherent;
+ status = "disabled";
+
+ port {
+ ade_out: endpoint {
+ remote-endpoint = <&dsi_in>;
+ };
+ };
+ };
+
+ dsi: dsi@f4107800 {
+ compatible = "hisilicon,hi6220-dsi";
+ reg = <0x0 0xf4107800 0x0 0x100>;
+ clocks = <&media_ctrl HI6220_DSI_PCLK>;
+ clock-names = "pclk";
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* 0 for input port */
+ port@0 {
+ reg = <0>;
+ dsi_in: endpoint {
+ remote-endpoint = <&ade_out>;
+ };
+ };
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
index bf322ed038b8..4b472a302cd8 100644
--- a/arch/arm64/boot/dts/hisilicon/hip05.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
@@ -300,11 +300,6 @@
clock-frequency = <200000000>;
};
- peri_c_subctrl: syscon@80000000 {
- compatible = "hisilicon,hip05-perisubc", "syscon";
- reg = < 0x0 0x80000000 0x0 0x10000>;
- };
-
uart0: uart@80300000 {
compatible = "snps,dw-apb-uart";
reg = <0x0 0x80300000 0x0 0x10000>;
diff --git a/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi b/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi
deleted file mode 100644
index b6a130c2e5a4..000000000000
--- a/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi
+++ /dev/null
@@ -1,180 +0,0 @@
-soc0: soc@000000000 {
- #address-cells = <2>;
- #size-cells = <2>;
- device_type = "soc";
- compatible = "simple-bus";
- ranges = <0x0 0x0 0x0 0x0 0x1 0x0>;
- chip-id = <0>;
-
- soc0_mdio0: mdio@803c0000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "hisilicon,hns-mdio";
- reg = <0x0 0x803c0000 0x0 0x10000>;
- subctrl-vbase = <&peri_c_subctrl>;
-
- soc0_phy0: ethernet-phy@0 {
- reg = <0x0>;
- compatible = "ethernet-phy-ieee802.3-c22";
- };
- soc0_phy1: ethernet-phy@1 {
- reg = <0x1>;
- compatible = "ethernet-phy-ieee802.3-c22";
- };
- };
-
- dsaf0: dsa@c7000000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "hisilicon,hns-dsaf-v1";
- mode = "6port-16rss";
- interrupt-parent = <&mbigen_dsa>;
-
- reg = <0x0 0xc5000000 0x0 0x890000
- 0x0 0xc7000000 0x0 0x60000
- >;
-
- reg-names = "ppe-base","dsaf-base";
- subctrl-syscon = <&dsaf_subctrl>;
- reset-field-offset = <0>;
- interrupts = <
- /* [14] ge fifo err 8 / xge 6**/
- 149 0x4 150 0x4 151 0x4 152 0x4
- 153 0x4 154 0x4 26 0x4 27 0x4
- 155 0x4 156 0x4 157 0x4 158 0x4 159 0x4 160 0x4
- /* [12] rcb com 4*3**/
- 0x6 0x4 0x7 0x4 0x8 0x4 0x9 0x4
- 16 0x4 17 0x4 18 0x4 19 0x4
- 22 0x4 23 0x4 24 0x4 25 0x4
- /* [8] ppe tnl 0-7***/
- 0x0 0x4 0x1 0x4 0x2 0x4 0x3 0x4
- 0x4 0x4 0x5 0x4 12 0x4 13 0x4
- /* [21] dsaf event int 3+18**/
- 128 0x4 129 0x4 130 0x4
- 0x83 0x4 0x84 0x4 0x85 0x4 0x86 0x4 0x87 0x4 0x88 0x4
- 0x89 0x4 0x8a 0x4 0x8b 0x4 0x8c 0x4 0x8d 0x4 0x8e 0x4
- 0x8f 0x4 0x90 0x4 0x91 0x4 0x92 0x4 0x93 0x4 0x94 0x4
- /* [4] debug rcb 2*2*/
- 0xe 0x1 0xf 0x1 0x14 0x1 0x15 0x1
- /* [256] sevice rcb 2*128*/
- 0x180 0x1 0x181 0x1 0x182 0x1 0x183 0x1
- 0x184 0x1 0x185 0x1 0x186 0x1 0x187 0x1
- 0x188 0x1 0x189 0x1 0x18a 0x1 0x18b 0x1
- 0x18c 0x1 0x18d 0x1 0x18e 0x1 0x18f 0x1
- 0x190 0x1 0x191 0x1 0x192 0x1 0x193 0x1
- 0x194 0x1 0x195 0x1 0x196 0x1 0x197 0x1
- 0x198 0x1 0x199 0x1 0x19a 0x1 0x19b 0x1
- 0x19c 0x1 0x19d 0x1 0x19e 0x1 0x19f 0x1
- 0x1a0 0x1 0x1a1 0x1 0x1a2 0x1 0x1a3 0x1
- 0x1a4 0x1 0x1a5 0x1 0x1a6 0x1 0x1a7 0x1
- 0x1a8 0x1 0x1a9 0x1 0x1aa 0x1 0x1ab 0x1
- 0x1ac 0x1 0x1ad 0x1 0x1ae 0x1 0x1af 0x1
- 0x1b0 0x1 0x1b1 0x1 0x1b2 0x1 0x1b3 0x1
- 0x1b4 0x1 0x1b5 0x1 0x1b6 0x1 0x1b7 0x1
- 0x1b8 0x1 0x1b9 0x1 0x1ba 0x1 0x1bb 0x1
- 0x1bc 0x1 0x1bd 0x1 0x1be 0x1 0x1bf 0x1
- 0x1c0 0x1 0x1c1 0x1 0x1c2 0x1 0x1c3 0x1
- 0x1c4 0x1 0x1c5 0x1 0x1c6 0x1 0x1c7 0x1
- 0x1c8 0x1 0x1c9 0x1 0x1ca 0x1 0x1cb 0x1
- 0x1cc 0x1 0x1cd 0x1 0x1ce 0x1 0x1cf 0x1
- 0x1d0 0x1 0x1d1 0x1 0x1d2 0x1 0x1d3 0x1
- 0x1d4 0x1 0x1d5 0x1 0x1d6 0x1 0x1d7 0x1
- 0x1d8 0x1 0x1d9 0x1 0x1da 0x1 0x1db 0x1
- 0x1dc 0x1 0x1dd 0x1 0x1de 0x1 0x1df 0x1
- 0x1e0 0x1 0x1e1 0x1 0x1e2 0x1 0x1e3 0x1
- 0x1e4 0x1 0x1e5 0x1 0x1e6 0x1 0x1e7 0x1
- 0x1e8 0x1 0x1e9 0x1 0x1ea 0x1 0x1eb 0x1
- 0x1ec 0x1 0x1ed 0x1 0x1ee 0x1 0x1ef 0x1
- 0x1f0 0x1 0x1f1 0x1 0x1f2 0x1 0x1f3 0x1
- 0x1f4 0x1 0x1f5 0x1 0x1f6 0x1 0x1f7 0x1
- 0x1f8 0x1 0x1f9 0x1 0x1fa 0x1 0x1fb 0x1
- 0x1fc 0x1 0x1fd 0x1 0x1fe 0x1 0x1ff 0x1
- 0x200 0x1 0x201 0x1 0x202 0x1 0x203 0x1
- 0x204 0x1 0x205 0x1 0x206 0x1 0x207 0x1
- 0x208 0x1 0x209 0x1 0x20a 0x1 0x20b 0x1
- 0x20c 0x1 0x20d 0x1 0x20e 0x1 0x20f 0x1
- 0x210 0x1 0x211 0x1 0x212 0x1 0x213 0x1
- 0x214 0x1 0x215 0x1 0x216 0x1 0x217 0x1
- 0x218 0x1 0x219 0x1 0x21a 0x1 0x21b 0x1
- 0x21c 0x1 0x21d 0x1 0x21e 0x1 0x21f 0x1
- 0x220 0x1 0x221 0x1 0x222 0x1 0x223 0x1
- 0x224 0x1 0x225 0x1 0x226 0x1 0x227 0x1
- 0x228 0x1 0x229 0x1 0x22a 0x1 0x22b 0x1
- 0x22c 0x1 0x22d 0x1 0x22e 0x1 0x22f 0x1
- 0x230 0x1 0x231 0x1 0x232 0x1 0x233 0x1
- 0x234 0x1 0x235 0x1 0x236 0x1 0x237 0x1
- 0x238 0x1 0x239 0x1 0x23a 0x1 0x23b 0x1
- 0x23c 0x1 0x23d 0x1 0x23e 0x1 0x23f 0x1
- 0x240 0x1 0x241 0x1 0x242 0x1 0x243 0x1
- 0x244 0x1 0x245 0x1 0x246 0x1 0x247 0x1
- 0x248 0x1 0x249 0x1 0x24a 0x1 0x24b 0x1
- 0x24c 0x1 0x24d 0x1 0x24e 0x1 0x24f 0x1
- 0x250 0x1 0x251 0x1 0x252 0x1 0x253 0x1
- 0x254 0x1 0x255 0x1 0x256 0x1 0x257 0x1
- 0x258 0x1 0x259 0x1 0x25a 0x1 0x25b 0x1
- 0x25c 0x1 0x25d 0x1 0x25e 0x1 0x25f 0x1
- 0x260 0x1 0x261 0x1 0x262 0x1 0x263 0x1
- 0x264 0x1 0x265 0x1 0x266 0x1 0x267 0x1
- 0x268 0x1 0x269 0x1 0x26a 0x1 0x26b 0x1
- 0x26c 0x1 0x26d 0x1 0x26e 0x1 0x26f 0x1
- 0x270 0x1 0x271 0x1 0x272 0x1 0x273 0x1
- 0x274 0x1 0x275 0x1 0x276 0x1 0x277 0x1
- 0x278 0x1 0x279 0x1 0x27a 0x1 0x27b 0x1
- 0x27c 0x1 0x27d 0x1 0x27e 0x1 0x27f 0x1>;
- buf-size = <4096>;
- desc-num = <1024>;
- dma-coherent;
-
- port@0 {
- reg = <0>;
- serdes-syscon = <&serdes_ctrl0>;
- };
- port@1 {
- reg = <1>;
- serdes-syscon = <&serdes_ctrl0>;
- };
- port@4 {
- reg = <4>;
- phy-handle = <&soc0_phy0>;
- serdes-syscon = <&serdes_ctrl1>;
- };
- port@5 {
- reg = <5>;
- phy-handle = <&soc0_phy1>;
- serdes-syscon = <&serdes_ctrl1>;
- };
- };
-
- eth0: ethernet@0{
- compatible = "hisilicon,hns-nic-v1";
- ae-handle = <&dsaf0>;
- port-idx-in-ae = <0>;
- local-mac-address = [00 00 00 01 00 58];
- status = "disabled";
- dma-coherent;
- };
- eth1: ethernet@1{
- compatible = "hisilicon,hns-nic-v1";
- ae-handle = <&dsaf0>;
- port-idx-in-ae = <1>;
- local-mac-address = [00 00 00 01 00 59];
- status = "disabled";
- dma-coherent;
- };
- eth2: ethernet@4{
- compatible = "hisilicon,hns-nic-v1";
- ae-handle = <&dsaf0>;
- port-idx-in-ae = <4>;
- local-mac-address = [00 00 00 01 00 5a];
- status = "disabled";
- dma-coherent;
- };
- eth3: ethernet@5{
- compatible = "hisilicon,hns-nic-v1";
- ae-handle = <&dsaf0>;
- port-idx-in-ae = <5>;
- local-mac-address = [00 00 00 01 00 5b];
- status = "disabled";
- dma-coherent;
- };
-};
diff --git a/arch/arm64/boot/dts/hisilicon/hip06-d03.dts b/arch/arm64/boot/dts/hisilicon/hip06-d03.dts
index f3e5323e430b..f54b28359607 100644
--- a/arch/arm64/boot/dts/hisilicon/hip06-d03.dts
+++ b/arch/arm64/boot/dts/hisilicon/hip06-d03.dts
@@ -25,6 +25,34 @@
chosen { };
};
+&eth0 {
+ status = "ok";
+};
+
+&eth1 {
+ status = "ok";
+};
+
+&eth2 {
+ status = "ok";
+};
+
+&eth3 {
+ status = "ok";
+};
+
+&sas0 {
+ status = "ok";
+};
+
+&sas1 {
+ status = "ok";
+};
+
+&sas2 {
+ status = "ok";
+};
+
&usb_ohci {
status = "ok";
};
diff --git a/arch/arm64/boot/dts/hisilicon/hip06.dtsi b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
index 5927bc472f1b..b548763366dd 100644
--- a/arch/arm64/boot/dts/hisilicon/hip06.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
@@ -277,6 +277,39 @@
#interrupt-cells = <2>;
num-pins = <2>;
};
+
+ mbigen_sas1: intc_sas1 {
+ msi-parent = <&its_dsa 0x40000>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ num-pins = <128>;
+ };
+
+ mbigen_sas2: intc_sas2 {
+ msi-parent = <&its_dsa 0x40040>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ num-pins = <128>;
+ };
+ };
+
+ mbigen_dsa@c0080000 {
+ compatible = "hisilicon,mbigen-v2";
+ reg = <0x0 0xc0080000 0x0 0x10000>;
+
+ mbigen_dsaf0: intc_dsaf0 {
+ msi-parent = <&its_dsa 0x40800>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ num-pins = <409>;
+ };
+
+ mbigen_sas0: intc-sas0 {
+ msi-parent = <&its_dsa 0x40900>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ num-pins = <128>;
+ };
};
soc {
@@ -302,6 +335,338 @@
dma-coherent;
status = "disabled";
};
+
+ peri_c_subctrl: sub_ctrl_c@60000000 {
+ compatible = "hisilicon,peri-subctrl","syscon";
+ reg = <0 0x60000000 0x0 0x10000>;
+ };
+
+ dsa_subctrl: dsa_subctrl@c0000000 {
+ compatible = "hisilicon,dsa-subctrl", "syscon";
+ reg = <0x0 0xc0000000 0x0 0x10000>;
+ };
+
+ pcie_subctl: pcie_subctl@a0000000 {
+ compatible = "hisilicon,pcie-sas-subctrl", "syscon";
+ reg = <0x0 0xa0000000 0x0 0x10000>;
+ };
+
+ serdes_ctrl: sds_ctrl@c2200000 {
+ compatible = "syscon";
+ reg = <0 0xc2200000 0x0 0x80000>;
+ };
+
+ mdio@603c0000 {
+ compatible = "hisilicon,hns-mdio";
+ reg = <0x0 0x603c0000 0x0 0x1000>;
+ subctrl-vbase = <&peri_c_subctrl 0x338 0xa38 0x531c 0x5a1c>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+ };
+
+ dsaf0: dsa@c7000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "hisilicon,hns-dsaf-v2";
+ mode = "6port-16rss";
+ reg = <0x0 0xc5000000 0x0 0x890000
+ 0x0 0xc7000000 0x0 0x600000>;
+ reg-names = "ppe-base", "dsaf-base";
+ interrupt-parent = <&mbigen_dsaf0>;
+ subctrl-syscon = <&dsa_subctrl>;
+ reset-field-offset = <0>;
+ interrupts =
+ <576 1>, <577 1>, <578 1>, <579 1>, <580 1>,
+ <581 1>, <582 1>, <583 1>, <584 1>, <585 1>,
+ <586 1>, <587 1>, <588 1>, <589 1>, <590 1>,
+ <591 1>, <592 1>, <593 1>, <594 1>, <595 1>,
+ <596 1>, <597 1>, <598 1>, <599 1>, <600 1>,
+ <960 1>, <961 1>, <962 1>, <963 1>, <964 1>,
+ <965 1>, <966 1>, <967 1>, <968 1>, <969 1>,
+ <970 1>, <971 1>, <972 1>, <973 1>, <974 1>,
+ <975 1>, <976 1>, <977 1>, <978 1>, <979 1>,
+ <980 1>, <981 1>, <982 1>, <983 1>, <984 1>,
+ <985 1>, <986 1>, <987 1>, <988 1>, <989 1>,
+ <990 1>, <991 1>, <992 1>, <993 1>, <994 1>,
+ <995 1>, <996 1>, <997 1>, <998 1>, <999 1>,
+ <1000 1>, <1001 1>, <1002 1>, <1003 1>, <1004 1>,
+ <1005 1>, <1006 1>, <1007 1>, <1008 1>, <1009 1>,
+ <1010 1>, <1011 1>, <1012 1>, <1013 1>, <1014 1>,
+ <1015 1>, <1016 1>, <1017 1>, <1018 1>, <1019 1>,
+ <1020 1>, <1021 1>, <1022 1>, <1023 1>, <1024 1>,
+ <1025 1>, <1026 1>, <1027 1>, <1028 1>, <1029 1>,
+ <1030 1>, <1031 1>, <1032 1>, <1033 1>, <1034 1>,
+ <1035 1>, <1036 1>, <1037 1>, <1038 1>, <1039 1>,
+ <1040 1>, <1041 1>, <1042 1>, <1043 1>, <1044 1>,
+ <1045 1>, <1046 1>, <1047 1>, <1048 1>, <1049 1>,
+ <1050 1>, <1051 1>, <1052 1>, <1053 1>, <1054 1>,
+ <1055 1>, <1056 1>, <1057 1>, <1058 1>, <1059 1>,
+ <1060 1>, <1061 1>, <1062 1>, <1063 1>, <1064 1>,
+ <1065 1>, <1066 1>, <1067 1>, <1068 1>, <1069 1>,
+ <1070 1>, <1071 1>, <1072 1>, <1073 1>, <1074 1>,
+ <1075 1>, <1076 1>, <1077 1>, <1078 1>, <1079 1>,
+ <1080 1>, <1081 1>, <1082 1>, <1083 1>, <1084 1>,
+ <1085 1>, <1086 1>, <1087 1>, <1088 1>, <1089 1>,
+ <1090 1>, <1091 1>, <1092 1>, <1093 1>, <1094 1>,
+ <1095 1>, <1096 1>, <1097 1>, <1098 1>, <1099 1>,
+ <1100 1>, <1101 1>, <1102 1>, <1103 1>, <1104 1>,
+ <1105 1>, <1106 1>, <1107 1>, <1108 1>, <1109 1>,
+ <1110 1>, <1111 1>, <1112 1>, <1113 1>, <1114 1>,
+ <1115 1>, <1116 1>, <1117 1>, <1118 1>, <1119 1>,
+ <1120 1>, <1121 1>, <1122 1>, <1123 1>, <1124 1>,
+ <1125 1>, <1126 1>, <1127 1>, <1128 1>, <1129 1>,
+ <1130 1>, <1131 1>, <1132 1>, <1133 1>, <1134 1>,
+ <1135 1>, <1136 1>, <1137 1>, <1138 1>, <1139 1>,
+ <1140 1>, <1141 1>, <1142 1>, <1143 1>, <1144 1>,
+ <1145 1>, <1146 1>, <1147 1>, <1148 1>, <1149 1>,
+ <1150 1>, <1151 1>, <1152 1>, <1153 1>, <1154 1>,
+ <1155 1>, <1156 1>, <1157 1>, <1158 1>, <1159 1>,
+ <1160 1>, <1161 1>, <1162 1>, <1163 1>, <1164 1>,
+ <1165 1>, <1166 1>, <1167 1>, <1168 1>, <1169 1>,
+ <1170 1>, <1171 1>, <1172 1>, <1173 1>, <1174 1>,
+ <1175 1>, <1176 1>, <1177 1>, <1178 1>, <1179 1>,
+ <1180 1>, <1181 1>, <1182 1>, <1183 1>, <1184 1>,
+ <1185 1>, <1186 1>, <1187 1>, <1188 1>, <1189 1>,
+ <1190 1>, <1191 1>, <1192 1>, <1193 1>, <1194 1>,
+ <1195 1>, <1196 1>, <1197 1>, <1198 1>, <1199 1>,
+ <1200 1>, <1201 1>, <1202 1>, <1203 1>, <1204 1>,
+ <1205 1>, <1206 1>, <1207 1>, <1208 1>, <1209 1>,
+ <1210 1>, <1211 1>, <1212 1>, <1213 1>, <1214 1>,
+ <1215 1>, <1216 1>, <1217 1>, <1218 1>, <1219 1>,
+ <1220 1>, <1221 1>, <1222 1>, <1223 1>, <1224 1>,
+ <1225 1>, <1226 1>, <1227 1>, <1228 1>, <1229 1>,
+ <1230 1>, <1231 1>, <1232 1>, <1233 1>, <1234 1>,
+ <1235 1>, <1236 1>, <1237 1>, <1238 1>, <1239 1>,
+ <1240 1>, <1241 1>, <1242 1>, <1243 1>, <1244 1>,
+ <1245 1>, <1246 1>, <1247 1>, <1248 1>, <1249 1>,
+ <1250 1>, <1251 1>, <1252 1>, <1253 1>, <1254 1>,
+ <1255 1>, <1256 1>, <1257 1>, <1258 1>, <1259 1>,
+ <1260 1>, <1261 1>, <1262 1>, <1263 1>, <1264 1>,
+ <1265 1>, <1266 1>, <1267 1>, <1268 1>, <1269 1>,
+ <1270 1>, <1271 1>, <1272 1>, <1273 1>, <1274 1>,
+ <1275 1>, <1276 1>, <1277 1>, <1278 1>, <1279 1>,
+ <1280 1>, <1281 1>, <1282 1>, <1283 1>, <1284 1>,
+ <1285 1>, <1286 1>, <1287 1>, <1288 1>, <1289 1>,
+ <1290 1>, <1291 1>, <1292 1>, <1293 1>, <1294 1>,
+ <1295 1>, <1296 1>, <1297 1>, <1298 1>, <1299 1>,
+ <1300 1>, <1301 1>, <1302 1>, <1303 1>, <1304 1>,
+ <1305 1>, <1306 1>, <1307 1>, <1308 1>, <1309 1>,
+ <1310 1>, <1311 1>, <1312 1>, <1313 1>, <1314 1>,
+ <1315 1>, <1316 1>, <1317 1>, <1318 1>, <1319 1>,
+ <1320 1>, <1321 1>, <1322 1>, <1323 1>, <1324 1>,
+ <1325 1>, <1326 1>, <1327 1>, <1328 1>, <1329 1>,
+ <1330 1>, <1331 1>, <1332 1>, <1333 1>, <1334 1>,
+ <1335 1>, <1336 1>, <1337 1>, <1338 1>, <1339 1>,
+ <1340 1>, <1341 1>, <1342 1>, <1343 1>;
+
+ desc-num = <0x400>;
+ buf-size = <0x1000>;
+ dma-coherent;
+
+ port@0 {
+ reg = <0>;
+ serdes-syscon = <&serdes_ctrl>;
+ port-rst-offset = <0>;
+ port-mode-offset = <0>;
+ media-type = "fiber";
+ };
+
+ port@1 {
+ reg = <1>;
+ serdes-syscon= <&serdes_ctrl>;
+ port-rst-offset = <1>;
+ port-mode-offset = <1>;
+ media-type = "fiber";
+ };
+
+ port@4 {
+ reg = <4>;
+ phy-handle = <&phy0>;
+ serdes-syscon= <&serdes_ctrl>;
+ port-rst-offset = <4>;
+ port-mode-offset = <2>;
+ media-type = "copper";
+ };
+
+ port@5 {
+ reg = <5>;
+ phy-handle = <&phy1>;
+ serdes-syscon= <&serdes_ctrl>;
+ port-rst-offset = <5>;
+ port-mode-offset = <3>;
+ media-type = "copper";
+ };
+ };
+
+ eth0: ethernet@4{
+ compatible = "hisilicon,hns-nic-v2";
+ ae-handle = <&dsaf0>;
+ port-idx-in-ae = <4>;
+ local-mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ dma-coherent;
+ };
+
+ eth1: ethernet@5{
+ compatible = "hisilicon,hns-nic-v2";
+ ae-handle = <&dsaf0>;
+ port-idx-in-ae = <5>;
+ local-mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ dma-coherent;
+ };
+
+ eth2: ethernet@0{
+ compatible = "hisilicon,hns-nic-v2";
+ ae-handle = <&dsaf0>;
+ port-idx-in-ae = <0>;
+ local-mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ dma-coherent;
+ };
+
+ eth3: ethernet@1{
+ compatible = "hisilicon,hns-nic-v2";
+ ae-handle = <&dsaf0>;
+ port-idx-in-ae = <1>;
+ local-mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ dma-coherent;
+ };
+
+ sas0: sas@c3000000 {
+ compatible = "hisilicon,hip06-sas-v2";
+ reg = <0 0xc3000000 0 0x10000>;
+ sas-addr = [50 01 88 20 16 00 00 00];
+ hisilicon,sas-syscon = <&dsa_subctrl>;
+ ctrl-reset-reg = <0xa60>;
+ ctrl-reset-sts-reg = <0x5a30>;
+ ctrl-clock-ena-reg = <0x338>;
+ queue-count = <16>;
+ phy-count = <8>;
+ dma-coherent;
+ interrupt-parent = <&mbigen_sas0>;
+ interrupts = <64 4>,<65 4>,<66 4>,<67 4>,<68 4>,
+ <69 4>,<70 4>,<71 4>,<72 4>,<73 4>,
+ <75 4>,<76 4>,<77 4>,<78 4>,<79 4>,
+ <80 4>,<81 4>,<82 4>,<83 4>,<84 4>,
+ <85 4>,<86 4>,<87 4>,<88 4>,<89 4>,
+ <90 4>,<91 4>,<92 4>,<93 4>,<94 4>,
+ <95 4>,<96 4>,<97 4>,<98 4>,<99 4>,
+ <100 4>,<101 4>,<102 4>,<103 4>,<104 4>,
+ <105 4>,<106 4>,<107 4>,<108 4>,<109 4>,
+ <110 4>,<111 4>,<112 4>,<113 4>,<114 4>,
+ <115 4>,<116 4>,<117 4>,<118 4>,<119 4>,
+ <120 4>,<121 4>,<122 4>,<123 4>,<124 4>,
+ <125 4>,<126 4>,<127 4>,<128 4>,<129 4>,
+ <130 4>,<131 4>,<132 4>,<133 4>,<134 4>,
+ <135 4>,<136 4>,<137 4>,<138 4>,<139 4>,
+ <140 4>,<141 4>,<142 4>,<143 4>,<144 4>,
+ <145 4>,<146 4>,<147 4>,<148 4>,<149 4>,
+ <150 4>,<151 4>,<152 4>,<153 4>,<154 4>,
+ <155 4>,<156 4>,<157 4>,<158 4>,<159 4>,
+ <160 4>,<601 1>,<602 1>,<603 1>,<604 1>,
+ <605 1>,<606 1>,<607 1>,<608 1>,<609 1>,
+ <610 1>,<611 1>,<612 1>,<613 1>,<614 1>,
+ <615 1>,<616 1>,<617 1>,<618 1>,<619 1>,
+ <620 1>,<621 1>,<622 1>,<623 1>,<624 1>,
+ <625 1>,<626 1>,<627 1>,<628 1>,<629 1>,
+ <630 1>,<631 1>,<632 1>;
+ status = "disabled";
+ };
+
+ sas1: sas@a2000000 {
+ compatible = "hisilicon,hip06-sas-v2";
+ reg = <0 0xa2000000 0 0x10000>;
+ sas-addr = [50 01 88 20 16 00 00 00];
+ hisilicon,sas-syscon = <&pcie_subctl>;
+ am-max-trans;
+ ctrl-reset-reg = <0xa18>;
+ ctrl-reset-sts-reg = <0x5a0c>;
+ ctrl-clock-ena-reg = <0x318>;
+ queue-count = <16>;
+ phy-count = <8>;
+ dma-coherent;
+ interrupt-parent = <&mbigen_sas1>;
+ interrupts = <64 4>,<65 4>,<66 4>,<67 4>,<68 4>,
+ <69 4>,<70 4>,<71 4>,<72 4>,<73 4>,
+ <74 4>,<75 4>,<76 4>,<77 4>,<78 4>,
+ <79 4>,<80 4>,<81 4>,<82 4>,<83 4>,
+ <84 4>,<85 4>,<86 4>,<87 4>,<88 4>,
+ <89 4>,<90 4>,<91 4>,<92 4>,<93 4>,
+ <94 4>,<95 4>,<96 4>,<97 4>,<98 4>,
+ <99 4>,<100 4>,<101 4>,<102 4>,<103 4>,
+ <104 4>,<105 4>,<106 4>,<107 4>,<108 4>,
+ <109 4>,<110 4>,<111 4>,<112 4>,<113 4>,
+ <114 4>,<115 4>,<116 4>,<117 4>,<118 4>,
+ <119 4>,<120 4>,<121 4>,<122 4>,<123 4>,
+ <124 4>,<125 4>,<126 4>,<127 4>,<128 4>,
+ <129 4>,<130 4>,<131 4>,<132 4>,<133 4>,
+ <134 4>,<135 4>,<136 4>,<137 4>,<138 4>,
+ <139 4>,<140 4>,<141 4>,<142 4>,<143 4>,
+ <144 4>,<145 4>,<146 4>,<147 4>,<148 4>,
+ <149 4>,<150 4>,<151 4>,<152 4>,<153 4>,
+ <154 4>,<155 4>,<156 4>,<157 4>,<158 4>,
+ <159 4>,<576 1>,<577 1>,<578 1>,<579 1>,
+ <580 1>,<581 1>,<582 1>,<583 1>,<584 1>,
+ <585 1>,<586 1>,<587 1>,<588 1>,<589 1>,
+ <590 1>,<591 1>,<592 1>,<593 1>,<594 1>,
+ <595 1>,<596 1>,<597 1>,<598 1>,<599 1>,
+ <600 1>,<601 1>,<602 1>,<603 1>,<604 1>,
+ <605 1>,<606 1>,<607 1>;
+ status = "disabled";
+ };
+
+ sas2: sas@a3000000 {
+ compatible = "hisilicon,hip06-sas-v2";
+ reg = <0 0xa3000000 0 0x10000>;
+ sas-addr = [50 01 88 20 16 00 00 00];
+ hisilicon,sas-syscon = <&pcie_subctl>;
+ ctrl-reset-reg = <0xae0>;
+ ctrl-reset-sts-reg = <0x5a70>;
+ ctrl-clock-ena-reg = <0x3a8>;
+ queue-count = <16>;
+ phy-count = <9>;
+ dma-coherent;
+ interrupt-parent = <&mbigen_sas2>;
+ interrupts = <192 4>,<193 4>,<194 4>,<195 4>,<196 4>,
+ <197 4>,<198 4>,<199 4>,<200 4>,<201 4>,
+ <202 4>,<203 4>,<204 4>,<205 4>,<206 4>,
+ <207 4>,<208 4>,<209 4>,<210 4>,<211 4>,
+ <212 4>,<213 4>,<214 4>,<215 4>,<216 4>,
+ <217 4>,<218 4>,<219 4>,<220 4>,<221 4>,
+ <222 4>,<223 4>,<224 4>,<225 4>,<226 4>,
+ <227 4>,<228 4>,<229 4>,<230 4>,<231 4>,
+ <232 4>,<233 4>,<234 4>,<235 4>,<236 4>,
+ <237 4>,<238 4>,<239 4>,<240 4>,<241 4>,
+ <242 4>,<243 4>,<244 4>,<245 4>,<246 4>,
+ <247 4>,<248 4>,<249 4>,<250 4>,<251 4>,
+ <252 4>,<253 4>,<254 4>,<255 4>,<256 4>,
+ <257 4>,<258 4>,<259 4>,<260 4>,<261 4>,
+ <262 4>,<263 4>,<264 4>,<265 4>,<266 4>,
+ <267 4>,<268 4>,<269 4>,<270 4>,<271 4>,
+ <272 4>,<273 4>,<274 4>,<275 4>,<276 4>,
+ <277 4>,<278 4>,<279 4>,<280 4>,<281 4>,
+ <282 4>,<283 4>,<284 4>,<285 4>,<286 4>,
+ <287 4>,<608 1>,<609 1>,<610 1>,<611 1>,
+ <612 1>,<613 1>,<614 1>,<615 1>,<616 1>,
+ <617 1>,<618 1>,<619 1>,<620 1>,<621 1>,
+ <622 1>,<623 1>,<624 1>,<625 1>,<626 1>,
+ <627 1>,<628 1>,<629 1>,<630 1>,<631 1>,
+ <632 1>,<633 1>,<634 1>,<635 1>,<636 1>,
+ <637 1>,<638 1>,<639 1>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm64/boot/dts/marvell/Makefile b/arch/arm64/boot/dts/marvell/Makefile
index 308468d377d0..cf3953124cef 100644
--- a/arch/arm64/boot/dts/marvell/Makefile
+++ b/arch/arm64/boot/dts/marvell/Makefile
@@ -5,6 +5,7 @@ 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
+dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-db.dtb
always := $(dtb-y)
subdir-y := $(dts-dirs)
diff --git a/arch/arm64/boot/dts/marvell/armada-8020.dtsi b/arch/arm64/boot/dts/marvell/armada-8020.dtsi
index 3753c1c6d54d..048e5cf5160e 100644
--- a/arch/arm64/boot/dts/marvell/armada-8020.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-8020.dtsi
@@ -47,6 +47,7 @@
#include "armada-ap806-dual.dtsi"
#include "armada-cp110-master.dtsi"
+#include "armada-cp110-slave.dtsi"
/ {
model = "Marvell Armada 8020";
diff --git a/arch/arm64/boot/dts/marvell/armada-8040-db.dts b/arch/arm64/boot/dts/marvell/armada-8040-db.dts
new file mode 100644
index 000000000000..6e6f182fb297
--- /dev/null
+++ b/arch/arm64/boot/dts/marvell/armada-8040-db.dts
@@ -0,0 +1,150 @@
+/*
+ * 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 8040 Development board platform
+ */
+
+#include "armada-8040.dtsi"
+
+/ {
+ model = "Marvell Armada 8040 DB board";
+ compatible = "marvell,armada8040-db", "marvell,armada8040",
+ "marvell,armada-ap806-quad", "marvell,armada-ap806";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@00000000 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x80000000>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <100000>;
+};
+
+&spi0 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0 0x200000>;
+ };
+ partition@400000 {
+ label = "Filesystem";
+ reg = <0x200000 0xce0000>;
+ };
+ };
+ };
+};
+
+/* Accessible over the mini-USB CON9 connector on the main board */
+&uart0 {
+ status = "okay";
+};
+
+
+/* CON5 on CP0 expansion */
+&cpm_pcie2 {
+ status = "okay";
+};
+
+&cpm_i2c0 {
+ status = "okay";
+ clock-frequency = <100000>;
+};
+
+/* CON4 on CP0 expansion */
+&cpm_sata0 {
+ status = "okay";
+};
+
+/* CON9 on CP0 expansion */
+&cpm_usb3_0 {
+ status = "okay";
+};
+
+/* CON10 on CP0 expansion */
+&cpm_usb3_1 {
+ status = "okay";
+};
+
+/* CON5 on CP1 expansion */
+&cps_pcie2 {
+ status = "okay";
+};
+
+&cps_i2c0 {
+ status = "okay";
+ clock-frequency = <100000>;
+};
+
+/* CON4 on CP1 expansion */
+&cps_sata0 {
+ status = "okay";
+};
+
+/* CON9 on CP1 expansion */
+&cps_usb3_0 {
+ status = "okay";
+};
+
+/* CON10 on CP1 expansion */
+&cps_usb3_1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/marvell/armada-8040.dtsi b/arch/arm64/boot/dts/marvell/armada-8040.dtsi
index 8bd0d8f8ad4c..9c1b28c47683 100644
--- a/arch/arm64/boot/dts/marvell/armada-8040.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-8040.dtsi
@@ -47,6 +47,7 @@
#include "armada-ap806-quad.dtsi"
#include "armada-cp110-master.dtsi"
+#include "armada-cp110-slave.dtsi"
/ {
model = "Marvell Armada 8040";
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index c2a6745f168c..7b6136182ad0 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -128,6 +128,12 @@
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
+ pmu {
+ compatible = "arm,cortex-a72-pmu";
+ interrupt-parent = <&pic>;
+ interrupts = <17>;
+ };
+
odmi: odmi@300000 {
compatible = "marvell,odmi-controller";
interrupt-controller;
@@ -140,6 +146,14 @@
marvell,spi-base = <128>, <136>, <144>, <152>;
};
+ pic: interrupt-controller@3f0100 {
+ compatible = "marvell,armada-8k-pic";
+ reg = <0x3f0100 0x10>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
xor@400000 {
compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
reg = <0x400000 0x1000>,
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
index da31bbbbb59e..e5e3ed678b6f 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
@@ -176,6 +176,7 @@
#interrupt-cells = <1>;
device_type = "pci";
dma-coherent;
+ msi-parent = <&gic_v2m0>;
bus-range = <0 0xff>;
ranges =
@@ -201,6 +202,7 @@
#interrupt-cells = <1>;
device_type = "pci";
dma-coherent;
+ msi-parent = <&gic_v2m0>;
bus-range = <0 0xff>;
ranges =
@@ -227,6 +229,7 @@
#interrupt-cells = <1>;
device_type = "pci";
dma-coherent;
+ msi-parent = <&gic_v2m0>;
bus-range = <0 0xff>;
ranges =
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
new file mode 100644
index 000000000000..842fb333285c
--- /dev/null
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
@@ -0,0 +1,249 @@
+/*
+ * 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 CP110 Slave.
+ */
+
+/ {
+ cp110-slave {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ ranges;
+
+ config-space {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ ranges = <0x0 0x0 0xf4000000 0x2000000>;
+
+ cps_syscon0: system-controller@440000 {
+ compatible = "marvell,cp110-system-controller0",
+ "syscon";
+ reg = <0x440000 0x1000>;
+ #clock-cells = <2>;
+ core-clock-output-names =
+ "cps-apll", "cps-ppv2-core", "cps-eip",
+ "cps-core", "cps-nand-core";
+ gate-clock-output-names =
+ "cps-audio", "cps-communit", "cps-nand",
+ "cps-ppv2", "cps-sdio", "cps-mg-domain",
+ "cps-mg-core", "cps-xor1", "cps-xor0",
+ "cps-gop-dp", "none", "cps-pcie_x10",
+ "cps-pcie_x11", "cps-pcie_x4", "cps-pcie-xor",
+ "cps-sata", "cps-sata-usb", "cps-main",
+ "cps-sd-mmc", "none", "none",
+ "cps-slow-io", "cps-usb3h0", "cps-usb3h1",
+ "cps-usb3dev", "cps-eip150", "cps-eip197";
+ };
+
+ cps_sata0: sata@540000 {
+ compatible = "marvell,armada-8k-ahci";
+ reg = <0x540000 0x30000>;
+ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cps_syscon0 1 15>;
+ status = "disabled";
+ };
+
+ cps_usb3_0: usb3@500000 {
+ compatible = "marvell,armada-8k-xhci",
+ "generic-xhci";
+ reg = <0x500000 0x4000>;
+ dma-coherent;
+ interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cps_syscon0 1 22>;
+ status = "disabled";
+ };
+
+ cps_usb3_1: usb3@510000 {
+ compatible = "marvell,armada-8k-xhci",
+ "generic-xhci";
+ reg = <0x510000 0x4000>;
+ dma-coherent;
+ interrupts = <GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cps_syscon0 1 23>;
+ status = "disabled";
+ };
+
+ cps_xor0: xor@6a0000 {
+ compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
+ reg = <0x6a0000 0x1000>,
+ <0x6b0000 0x1000>;
+ dma-coherent;
+ msi-parent = <&gic_v2m0>;
+ clocks = <&cps_syscon0 1 8>;
+ };
+
+ cps_xor1: xor@6c0000 {
+ compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
+ reg = <0x6c0000 0x1000>,
+ <0x6d0000 0x1000>;
+ dma-coherent;
+ msi-parent = <&gic_v2m0>;
+ clocks = <&cps_syscon0 1 7>;
+ };
+
+ cps_spi0: spi@700600 {
+ compatible = "marvell,armada-380-spi";
+ reg = <0x700600 0x50>;
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+ cell-index = <1>;
+ clocks = <&cps_syscon0 0 3>;
+ status = "disabled";
+ };
+
+ cps_spi1: spi@700680 {
+ compatible = "marvell,armada-380-spi";
+ reg = <0x700680 0x50>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <2>;
+ clocks = <&cps_syscon0 1 21>;
+ status = "disabled";
+ };
+
+ cps_i2c0: i2c@701000 {
+ compatible = "marvell,mv78230-i2c";
+ reg = <0x701000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cps_syscon0 1 21>;
+ status = "disabled";
+ };
+
+ cps_i2c1: i2c@701100 {
+ compatible = "marvell,mv78230-i2c";
+ reg = <0x701100 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cps_syscon0 1 21>;
+ status = "disabled";
+ };
+ };
+
+ cps_pcie0: pcie@f4600000 {
+ compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
+ reg = <0 0xf4600000 0 0x10000>,
+ <0 0xfaf00000 0 0x80000>;
+ reg-names = "ctrl", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ dma-coherent;
+ msi-parent = <&gic_v2m0>;
+
+ bus-range = <0 0xff>;
+ ranges =
+ /* downstream I/O */
+ <0x81000000 0 0xfd000000 0 0xfd000000 0 0x10000
+ /* non-prefetchable memory */
+ 0x82000000 0 0xfa000000 0 0xfa000000 0 0xf00000>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>;
+ num-lanes = <1>;
+ clocks = <&cps_syscon0 1 13>;
+ status = "disabled";
+ };
+
+ cps_pcie1: pcie@f4620000 {
+ compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
+ reg = <0 0xf4620000 0 0x10000>,
+ <0 0xfbf00000 0 0x80000>;
+ reg-names = "ctrl", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ dma-coherent;
+ msi-parent = <&gic_v2m0>;
+
+ bus-range = <0 0xff>;
+ ranges =
+ /* downstream I/O */
+ <0x81000000 0 0xfd010000 0 0xfd010000 0 0x10000
+ /* non-prefetchable memory */
+ 0x82000000 0 0xfb000000 0 0xfb000000 0 0xf00000>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>;
+
+ num-lanes = <1>;
+ clocks = <&cps_syscon0 1 11>;
+ status = "disabled";
+ };
+
+ cps_pcie2: pcie@f4640000 {
+ compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
+ reg = <0 0xf4640000 0 0x10000>,
+ <0 0xfcf00000 0 0x80000>;
+ reg-names = "ctrl", "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ dma-coherent;
+ msi-parent = <&gic_v2m0>;
+
+ bus-range = <0 0xff>;
+ ranges =
+ /* downstream I/O */
+ <0x81000000 0 0xfd020000 0 0xfd020000 0 0x10000
+ /* non-prefetchable memory */
+ 0x82000000 0 0xfc000000 0 0xfc000000 0 0xf00000>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>;
+
+ num-lanes = <1>;
+ clocks = <&cps_syscon0 1 12>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/marvell/berlin4ct.dtsi b/arch/arm64/boot/dts/marvell/berlin4ct.dtsi
index 099ad93bb49b..85c23facb9fe 100644
--- a/arch/arm64/boot/dts/marvell/berlin4ct.dtsi
+++ b/arch/arm64/boot/dts/marvell/berlin4ct.dtsi
@@ -68,6 +68,7 @@
device_type = "cpu";
reg = <0x0>;
enable-method = "psci";
+ next-level-cache = <&l2>;
cpu-idle-states = <&CPU_SLEEP_0>;
};
@@ -76,6 +77,7 @@
device_type = "cpu";
reg = <0x1>;
enable-method = "psci";
+ next-level-cache = <&l2>;
cpu-idle-states = <&CPU_SLEEP_0>;
};
@@ -84,6 +86,7 @@
device_type = "cpu";
reg = <0x2>;
enable-method = "psci";
+ next-level-cache = <&l2>;
cpu-idle-states = <&CPU_SLEEP_0>;
};
@@ -92,9 +95,14 @@
device_type = "cpu";
reg = <0x3>;
enable-method = "psci";
+ next-level-cache = <&l2>;
cpu-idle-states = <&CPU_SLEEP_0>;
};
+ l2: cache {
+ compatible = "cache";
+ };
+
idle-states {
entry-method = "psci";
CPU_SLEEP_0: cpu-sleep-0 {
@@ -115,7 +123,7 @@
};
pmu {
- compatible = "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a53-pmu", "arm,armv8-pmuv3";
interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
@@ -279,7 +287,6 @@
reg = <0x4000 0x100>;
clocks = <&osc>;
interrupts = <1>;
- status = "disabled";
};
wdt2: watchdog@5000 {
@@ -287,7 +294,6 @@
reg = <0x5000 0x100>;
clocks = <&osc>;
interrupts = <2>;
- status = "disabled";
};
sm_gpio0: gpio@8000 {
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 7453a47b3047..2a7f731c7759 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -42,6 +42,44 @@
gpio = <&pio 130 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
+
+ connector {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+ type = "d";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi0_out>;
+ };
+ };
+ };
+};
+
+&cec {
+ status = "okay";
+};
+
+&dpi0 {
+ status = "okay";
+};
+
+&hdmi_phy {
+ status = "okay";
+};
+
+&hdmi0 {
+ status = "okay";
+
+ ports {
+ port@1 {
+ reg = <1>;
+
+ hdmi0_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
};
&i2c1 {
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 10f638f4e7d8..1c71e256601d 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -254,6 +254,16 @@
<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ hdmi_pin: xxx {
+
+ /*hdmi htplg pin*/
+ pins1 {
+ pinmux = <MT8173_PIN_21_HTPLG__FUNC_HTPLG>;
+ input-enable;
+ bias-pull-down;
+ };
+ };
+
i2c0_pins_a: i2c0 {
pins1 {
pinmux = <MT8173_PIN_45_SDA0__FUNC_SDA0>,
@@ -341,6 +351,14 @@
clock-names = "spi", "wrap";
};
+ cec: cec@10013000 {
+ compatible = "mediatek,mt8173-cec";
+ reg = <0 0x10013000 0 0xbc>;
+ interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&infracfg CLK_INFRA_CEC>;
+ status = "disabled";
+ };
+
vpu: vpu@10020000 {
compatible = "mediatek,mt8173-vpu";
reg = <0 0x10020000 0 0x30000>,
@@ -383,6 +401,19 @@
#clock-cells = <1>;
};
+ hdmi_phy: hdmi-phy@10209100 {
+ compatible = "mediatek,mt8173-hdmi-phy";
+ reg = <0 0x10209100 0 0x24>;
+ clocks = <&apmixedsys CLK_APMIXED_HDMI_REF>;
+ clock-names = "pll_ref";
+ clock-output-names = "hdmitx_dig_cts";
+ mediatek,ibias = <0xa>;
+ mediatek,ibias_up = <0x1c>;
+ #clock-cells = <0>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
mipi_tx0: mipi-dphy@10215000 {
compatible = "mediatek,mt8173-mipi-tx";
reg = <0 0x10215000 0 0x1000>;
@@ -577,6 +608,14 @@
status = "disabled";
};
+ hdmiddc0: i2c@11012000 {
+ compatible = "mediatek,mt8173-hdmi-ddc";
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_LOW>;
+ reg = <0 0x11012000 0 0x1C>;
+ clocks = <&pericfg CLK_PERI_I2C5>;
+ clock-names = "ddc-i2c";
+ };
+
i2c6: i2c@11013000 {
compatible = "mediatek,mt8173-i2c";
reg = <0 0x11013000 0 0x70>,
@@ -885,6 +924,12 @@
<&apmixedsys CLK_APMIXED_TVDPLL>;
clock-names = "pixel", "engine", "pll";
status = "disabled";
+
+ port {
+ dpi0_out: endpoint {
+ remote-endpoint = <&hdmi0_in>;
+ };
+ };
};
pwm0: pwm@1401e000 {
@@ -942,6 +987,38 @@
clocks = <&mmsys CLK_MM_DISP_OD>;
};
+ hdmi0: hdmi@14025000 {
+ compatible = "mediatek,mt8173-hdmi";
+ reg = <0 0x14025000 0 0x400>;
+ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&mmsys CLK_MM_HDMI_PIXEL>,
+ <&mmsys CLK_MM_HDMI_PLLCK>,
+ <&mmsys CLK_MM_HDMI_AUDIO>,
+ <&mmsys CLK_MM_HDMI_SPDIF>;
+ clock-names = "pixel", "pll", "bclk", "spdif";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_pin>;
+ phys = <&hdmi_phy>;
+ phy-names = "hdmi";
+ mediatek,syscon-hdmi = <&mmsys 0x900>;
+ assigned-clocks = <&topckgen CLK_TOP_HDMI_SEL>;
+ assigned-clock-parents = <&hdmi_phy>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ hdmi0_in: endpoint {
+ remote-endpoint = <&dpi0_out>;
+ };
+ };
+ };
+ };
+
larb4: larb@14027000 {
compatible = "mediatek,mt8173-smi-larb";
reg = <0 0x14027000 0 0x1000>;
diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
index 2013f8916084..3f3a46a4bd01 100644
--- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
@@ -4,6 +4,7 @@
#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/tegra124-soctherm.h>
/ {
compatible = "nvidia,tegra132", "nvidia,tegra124";
@@ -727,8 +728,10 @@
};
soctherm: thermal-sensor@700e2000 {
- compatible = "nvidia,tegra124-soctherm";
- reg = <0x0 0x700e2000 0x0 0x1000>;
+ compatible = "nvidia,tegra132-soctherm";
+ reg = <0x0 0x700e2000 0x0 0x600 /* 0: SOC_THERM reg_base */
+ 0x0 0x70040000 0x0 0x200>; /* 2: CCROC reg_base */
+ reg-names = "soctherm-reg", "ccroc-reg";
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA124_CLK_TSENSOR>,
<&tegra_car TEGRA124_CLK_SOC_THERM>;
@@ -736,6 +739,118 @@
resets = <&tegra_car 78>;
reset-names = "soctherm";
#thermal-sensor-cells = <1>;
+
+ throttle-cfgs {
+ throttle_heavy: heavy {
+ nvidia,priority = <100>;
+ nvidia,cpu-throt-level = <TEGRA_SOCTHERM_THROT_LEVEL_HIGH>;
+
+ #cooling-cells = <2>;
+ };
+ };
+ };
+
+ thermal-zones {
+ cpu {
+ polling-delay-passive = <1000>;
+ polling-delay = <0>;
+
+ thermal-sensors =
+ <&soctherm TEGRA124_SOCTHERM_SENSOR_CPU>;
+
+ trips {
+ cpu_shutdown_trip {
+ temperature = <105000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+
+ cpu_throttle_trip: throttle-trip {
+ temperature = <102000>;
+ hysteresis = <1000>;
+ type = "hot";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_throttle_trip>;
+ cooling-device = <&throttle_heavy 1 1>;
+ };
+ };
+ };
+ mem {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors =
+ <&soctherm TEGRA124_SOCTHERM_SENSOR_MEM>;
+
+ trips {
+ mem_shutdown_trip {
+ temperature = <101000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ /*
+ * There are currently no cooling maps,
+ * because there are no cooling devices.
+ */
+ };
+ };
+ gpu {
+ polling-delay-passive = <1000>;
+ polling-delay = <0>;
+
+ thermal-sensors =
+ <&soctherm TEGRA124_SOCTHERM_SENSOR_GPU>;
+
+ trips {
+ gpu_shutdown_trip {
+ temperature = <101000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+
+ gpu_throttle_trip: throttle-trip {
+ temperature = <99000>;
+ hysteresis = <1000>;
+ type = "hot";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&gpu_throttle_trip>;
+ cooling-device = <&throttle_heavy 1 1>;
+ };
+ };
+ };
+ pllx {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors =
+ <&soctherm TEGRA124_SOCTHERM_SENSOR_PLLX>;
+
+ trips {
+ pllx_shutdown_trip {
+ temperature = <105000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ /*
+ * There are currently no cooling maps,
+ * because there are no cooling devices.
+ */
+ };
+ };
};
ahub@70300000 {
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
index 431266a48e9c..c2becb603e11 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
@@ -27,6 +27,12 @@
reg = <0x0 0x80000000 0x0 0xc0000000>;
};
+ host1x@50000000 {
+ dpaux: dpaux@545c0000 {
+ status = "okay";
+ };
+ };
+
pinmux: pinmux@700008d4 {
pinctrl-names = "boot";
pinctrl-0 = <&state_boot>;
@@ -1556,6 +1562,46 @@
};
};
+ i2c@7000d100 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ nau8825@1a {
+ compatible = "nuvoton,nau8825";
+ reg = <0x1a>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(E, 6) IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&tegra_car TEGRA210_CLK_CLK_OUT_2>;
+ clock-names = "mclk";
+
+ nuvoton,jkdet-enable;
+ nuvoton,jkdet-polarity = <GPIO_ACTIVE_LOW>;
+ nuvoton,vref-impedance = <2>;
+ nuvoton,micbias-voltage = <6>;
+ nuvoton,sar-threshold-num = <4>;
+ nuvoton,sar-threshold = <0xc 0x1e 0x38 0x60>;
+ nuvoton,sar-hysteresis = <1>;
+ nuvoton,sar-voltage = <0>;
+ nuvoton,sar-compare-time = <0>;
+ nuvoton,sar-sampling-time = <0>;
+ nuvoton,short-key-debounce = <2>;
+ nuvoton,jack-insert-debounce = <7>;
+ nuvoton,jack-eject-debounce = <7>;
+ status = "okay";
+ };
+
+ audio-codec@2d {
+ compatible = "realtek,rt5677";
+ reg = <0x2d>;
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(X, 0) IRQ_TYPE_LEVEL_HIGH>;
+ realtek,reset-gpio = <&gpio TEGRA_GPIO(BB, 3) GPIO_ACTIVE_LOW>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ status = "okay";
+ };
+ };
+
pmc@7000e400 {
nvidia,invert-interrupt;
nvidia,suspend-mode = <0>;
@@ -1568,12 +1614,81 @@
status = "okay";
};
+ usb@70090000 {
+ phys = <&{/padctl@7009f000/pads/usb2/lanes/usb2-0}>,
+ <&{/padctl@7009f000/pads/pcie/lanes/pcie-6}>;
+ phy-names = "usb2-0", "usb3-0";
+
+ dvddio-pex-supply = <&avddio_1v05>;
+ hvddio-pex-supply = <&pp1800>;
+ avdd-usb-supply = <&pp3300>;
+ avdd-pll-utmip-supply = <&pp1800>;
+ avdd-pll-uerefe-supply = <&pp1050_avdd>;
+ dvdd-pex-pll-supply = <&avddio_1v05>;
+ hvdd-pex-pll-e-supply = <&pp1800>;
+
+ status = "okay";
+ };
+
+ padctl@7009f000 {
+ status = "okay";
+
+ pads {
+ usb2 {
+ status = "okay";
+
+ lanes {
+ usb2-0 {
+ nvidia,function = "xusb";
+ status = "okay";
+ };
+ };
+ };
+
+ pcie {
+ status = "okay";
+
+ lanes {
+ pcie-6 {
+ nvidia,function = "usb3-ss";
+ status = "okay";
+ };
+ };
+ };
+ };
+
+ ports {
+ usb2-0 {
+ status = "okay";
+ vbus-supply = <&usbc_vbus>;
+ mode = "otg";
+ };
+
+ usb3-0 {
+ nvidia,usb2-companion = <0>;
+ status = "okay";
+ };
+ };
+ };
+
sdhci@700b0600 {
bus-width = <8>;
non-removable;
status = "okay";
};
+ aconnect@702c0000 {
+ status = "okay";
+
+ dma@702e2000 {
+ status = "okay";
+ };
+
+ agic@702f9000 {
+ status = "okay";
+ };
+ };
+
clocks {
compatible = "simple-bus";
#address-cells = <1>;
@@ -1646,6 +1761,11 @@
};
};
+ max98357a {
+ compatible = "maxim,max98357a";
+ status = "okay";
+ };
+
psci {
compatible = "arm,psci-1.0";
method = "smc";
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index c4cfdcf60d26..46045fe719da 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -3,6 +3,7 @@
#include <dt-bindings/memory/tegra210-mc.h>
#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/tegra124-soctherm.h>
/ {
compatible = "nvidia,tegra210";
@@ -34,6 +35,7 @@
clock-names = "dpaux", "parent";
resets = <&tegra_car 207>;
reset-names = "dpaux";
+ power-domains = <&pd_sor>;
status = "disabled";
state_dpaux1_aux: pinmux-aux {
@@ -108,6 +110,7 @@
clock-names = "dsi", "lp", "parent";
resets = <&tegra_car 48>;
reset-names = "dsi";
+ power-domains = <&pd_sor>;
nvidia,mipi-calibrate = <&mipi 0x0c0>; /* DSIA & DSIB pads */
status = "disabled";
@@ -137,6 +140,7 @@
clock-names = "dsi", "lp", "parent";
resets = <&tegra_car 82>;
reset-names = "dsi";
+ power-domains = <&pd_sor>;
nvidia,mipi-calibrate = <&mipi 0x300>; /* DSIC & DSID pads */
status = "disabled";
@@ -178,6 +182,7 @@
pinctrl-1 = <&state_dpaux_i2c>;
pinctrl-2 = <&state_dpaux_off>;
pinctrl-names = "aux", "i2c", "off";
+ power-domains = <&pd_sor>;
status = "disabled";
};
@@ -197,6 +202,7 @@
pinctrl-1 = <&state_dpaux1_i2c>;
pinctrl-2 = <&state_dpaux1_off>;
pinctrl-names = "aux", "i2c", "off";
+ power-domains = <&pd_sor>;
status = "disabled";
};
@@ -209,6 +215,7 @@
clock-names = "dpaux", "parent";
resets = <&tegra_car 181>;
reset-names = "dpaux";
+ power-domains = <&pd_sor>;
status = "disabled";
state_dpaux_aux: pinmux-aux {
@@ -325,7 +332,7 @@
};
gpio: gpio@6000d000 {
- compatible = "nvidia,tegra210-gpio", "nvidia,tegra124-gpio", "nvidia,tegra30-gpio";
+ compatible = "nvidia,tegra210-gpio", "nvidia,tegra30-gpio";
reg = <0x0 0x6000d000 0x0 0x1000>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
@@ -648,27 +655,41 @@
#power-domain-cells = <0>;
};
+ pd_sor: sor {
+ clocks = <&tegra_car TEGRA210_CLK_SOR0>,
+ <&tegra_car TEGRA210_CLK_SOR1>,
+ <&tegra_car TEGRA210_CLK_CSI>,
+ <&tegra_car TEGRA210_CLK_DSIA>,
+ <&tegra_car TEGRA210_CLK_DSIB>,
+ <&tegra_car TEGRA210_CLK_DPAUX>,
+ <&tegra_car TEGRA210_CLK_DPAUX1>,
+ <&tegra_car TEGRA210_CLK_MIPI_CAL>;
+ resets = <&tegra_car TEGRA210_CLK_SOR0>,
+ <&tegra_car TEGRA210_CLK_SOR1>,
+ <&tegra_car TEGRA210_CLK_CSI>,
+ <&tegra_car TEGRA210_CLK_DSIA>,
+ <&tegra_car TEGRA210_CLK_DSIB>,
+ <&tegra_car TEGRA210_CLK_DPAUX>,
+ <&tegra_car TEGRA210_CLK_DPAUX1>,
+ <&tegra_car TEGRA210_CLK_MIPI_CAL>;
+ #power-domain-cells = <0>;
+ };
+
pd_xusbss: xusba {
clocks = <&tegra_car TEGRA210_CLK_XUSB_SS>;
- clock-names = "xusb-ss";
resets = <&tegra_car TEGRA210_CLK_XUSB_SS>;
- reset-names = "xusb-ss";
#power-domain-cells = <0>;
};
pd_xusbdev: xusbb {
clocks = <&tegra_car TEGRA210_CLK_XUSB_DEV>;
- clock-names = "xusb-dev";
resets = <&tegra_car 95>;
- reset-names = "xusb-dev";
#power-domain-cells = <0>;
};
pd_xusbhost: xusbc {
clocks = <&tegra_car TEGRA210_CLK_XUSB_HOST>;
- clock-names = "xusb-host";
resets = <&tegra_car TEGRA210_CLK_XUSB_HOST>;
- reset-names = "xusb-host";
#power-domain-cells = <0>;
};
};
@@ -948,6 +969,7 @@
reg = <0x0 0x700e3000 0x0 0x100>;
clocks = <&tegra_car TEGRA210_CLK_MIPI_CAL>;
clock-names = "mipi-cal";
+ power-domains = <&pd_sor>;
#nvidia,mipi-calibrate-cells = <1>;
};
@@ -961,6 +983,50 @@
#size-cells = <1>;
ranges = <0x702c0000 0x0 0x702c0000 0x00040000>;
status = "disabled";
+
+ adma: dma@702e2000 {
+ compatible = "nvidia,tegra210-adma";
+ reg = <0x702e2000 0x2000>;
+ interrupt-parent = <&agic>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>;
+ clock-names = "d_audio";
+ status = "disabled";
+ };
+
+ agic: agic@702f9000 {
+ compatible = "nvidia,tegra210-agic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x702f9000 0x2000>,
+ <0x702fa000 0x2000>;
+ interrupts = <GIC_SPI 102 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&tegra_car TEGRA210_CLK_APE>;
+ clock-names = "clk";
+ status = "disabled";
+ };
};
spi@70410000 {
@@ -1094,4 +1160,130 @@
(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
interrupt-parent = <&gic>;
};
+
+ soctherm: thermal-sensor@700e2000 {
+ compatible = "nvidia,tegra210-soctherm";
+ reg = <0x0 0x700e2000 0x0 0x600 /* SOC_THERM reg_base */
+ 0x0 0x60006000 0x0 0x400>; /* CAR reg_base */
+ reg-names = "soctherm-reg", "car-reg";
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_TSENSOR>,
+ <&tegra_car TEGRA210_CLK_SOC_THERM>;
+ clock-names = "tsensor", "soctherm";
+ resets = <&tegra_car 78>;
+ reset-names = "soctherm";
+ #thermal-sensor-cells = <1>;
+
+ throttle-cfgs {
+ throttle_heavy: heavy {
+ nvidia,priority = <100>;
+ nvidia,cpu-throt-percent = <85>;
+
+ #cooling-cells = <2>;
+ };
+ };
+ };
+
+ thermal-zones {
+ cpu {
+ polling-delay-passive = <1000>;
+ polling-delay = <0>;
+
+ thermal-sensors =
+ <&soctherm TEGRA124_SOCTHERM_SENSOR_CPU>;
+
+ trips {
+ cpu-shutdown-trip {
+ temperature = <102500>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+
+ cpu_throttle_trip: throttle-trip {
+ temperature = <98500>;
+ hysteresis = <1000>;
+ type = "hot";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_throttle_trip>;
+ cooling-device = <&throttle_heavy 1 1>;
+ };
+ };
+ };
+ mem {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors =
+ <&soctherm TEGRA124_SOCTHERM_SENSOR_MEM>;
+
+ trips {
+ mem-shutdown-trip {
+ temperature = <103000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ /*
+ * There are currently no cooling maps,
+ * because there are no cooling devices.
+ */
+ };
+ };
+ gpu {
+ polling-delay-passive = <1000>;
+ polling-delay = <0>;
+
+ thermal-sensors =
+ <&soctherm TEGRA124_SOCTHERM_SENSOR_GPU>;
+
+ trips {
+ gpu-shutdown-trip {
+ temperature = <103000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+
+ gpu_throttle_trip: throttle-trip {
+ temperature = <100000>;
+ hysteresis = <1000>;
+ type = "hot";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&gpu_throttle_trip>;
+ cooling-device = <&throttle_heavy 1 1>;
+ };
+ };
+ };
+ pllx {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors =
+ <&soctherm TEGRA124_SOCTHERM_SENSOR_PLLX>;
+
+ trips {
+ pllx-shutdown-trip {
+ temperature = <103000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ /*
+ * There are currently no cooling maps,
+ * because there are no cooling devices.
+ */
+ };
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index fa1f661ccccf..5dd05de5619b 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -1,5 +1,6 @@
dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc.dtb msm8916-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8996-mtp.dtb
+dtb-$(CONFIG_ARCH_QCOM) += apq8096-db820c.dtb
always := $(dtb-y)
subdir-y := $(dts-dirs)
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 ee828a8a8236..e1e6c6b5c489 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi
@@ -24,4 +24,52 @@
bias-pull-up;
};
};
+
+ adv7533_int_active: adv533_int_active {
+ pinmux {
+ function = "gpio";
+ pins = "gpio31";
+ };
+ pinconf {
+ pins = "gpio31";
+ drive-strength = <16>;
+ bias-disable;
+ };
+ };
+
+ adv7533_int_suspend: adv7533_int_suspend {
+ pinmux {
+ function = "gpio";
+ pins = "gpio31";
+ };
+ pinconf {
+ pins = "gpio31";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ adv7533_switch_active: adv7533_switch_active {
+ pinmux {
+ function = "gpio";
+ pins = "gpio32";
+ };
+ pinconf {
+ pins = "gpio32";
+ drive-strength = <16>;
+ bias-disable;
+ };
+ };
+
+ adv7533_switch_suspend: adv7533_switch_suspend {
+ pinmux {
+ function = "gpio";
+ pins = "gpio32";
+ };
+ pinconf {
+ pins = "gpio32";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
index 18639bc0a506..bb062b547110 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
@@ -63,6 +63,47 @@
/* On High speed expansion */
label = "HS-I2C2";
status = "okay";
+
+ adv_bridge: bridge@39 {
+ status = "okay";
+
+ compatible = "adi,adv7533";
+ reg = <0x39>;
+
+ interrupt-parent = <&msmgpio>;
+ interrupts = <31 2>;
+
+ adi,dsi-lanes = <4>;
+
+ pd-gpios = <&msmgpio 32 0>;
+
+ avdd-supply = <&pm8916_l6>;
+ v1p2-supply = <&pm8916_l6>;
+ v3p3-supply = <&pm8916_l17>;
+
+ pinctrl-names = "default","sleep";
+ pinctrl-0 = <&adv7533_int_active &adv7533_switch_active>;
+ pinctrl-1 = <&adv7533_int_suspend &adv7533_switch_suspend>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ adv7533_in: endpoint {
+ remote-endpoint = <&dsi0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ adv7533_out: endpoint {
+ remote-endpoint = <&hdmi_con>;
+ };
+ };
+ };
+ };
};
i2c@78ba000 {
@@ -180,6 +221,36 @@
lpass@07708000 {
status = "okay";
};
+
+ mdss@1a00000 {
+ status = "okay";
+
+ mdp@1a01000 {
+ status = "okay";
+ };
+
+ dsi@1a98000 {
+ status = "okay";
+
+ vdda-supply = <&pm8916_l2>;
+ vddio-supply = <&pm8916_l6>;
+
+ ports {
+ port@1 {
+ endpoint {
+ remote-endpoint = <&adv7533_in>;
+ data-lanes = <0 1 2 3>;
+ };
+ };
+ };
+ };
+
+ dsi-phy@1a98300 {
+ status = "okay";
+
+ vddio-supply = <&pm8916_l6>;
+ };
+ };
};
usb2513 {
@@ -194,6 +265,17 @@
pinctrl-names = "default";
pinctrl-0 = <&usb_id_default>;
};
+
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con: endpoint {
+ remote-endpoint = <&adv7533_out>;
+ };
+ };
+ };
};
&smd_rpm_regulators {
diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c-pins.dtsi
new file mode 100644
index 000000000000..24552f19b3fa
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8096-db820c-pins.dtsi
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013-2016, 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.
+ */
+&msmgpio {
+ sdc2_cd_on: sdc2_cd_on {
+ mux {
+ pins = "gpio38";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio38";
+ bias-pull-up; /* pull up */
+ drive-strength = <16>; /* 16 MA */
+ };
+ };
+
+ sdc2_cd_off: sdc2_cd_off {
+ mux {
+ pins = "gpio38";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio38";
+ bias-pull-up; /* pull up */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dts b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
new file mode 100644
index 000000000000..230e9c8484ac
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2014-2016, 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 "apq8096-db820c.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. DB820c";
+ compatible = "arrow,apq8096-db820c", "qcom,apq8096-sbc";
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
new file mode 100644
index 000000000000..afb218cffc60
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014-2016, 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"
+#include "apq8096-db820c-pins.dtsi"
+
+/ {
+ aliases {
+ serial0 = &blsp2_uart1;
+ serial1 = &blsp2_uart2;
+ i2c0 = &blsp1_i2c2;
+ i2c1 = &blsp2_i2c1;
+ i2c2 = &blsp2_i2c0;
+ spi0 = &blsp1_spi0;
+ spi1 = &blsp2_spi5;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ soc {
+ serial@75b0000 {
+ label = "LS-UART1";
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&blsp2_uart1_2pins_default>;
+ pinctrl-1 = <&blsp2_uart1_2pins_sleep>;
+ };
+
+ serial@75b1000 {
+ label = "LS-UART0";
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&blsp2_uart2_4pins_default>;
+ pinctrl-1 = <&blsp2_uart2_4pins_sleep>;
+ };
+
+ i2c@07577000 {
+ /* On Low speed expansion */
+ label = "LS-I2C0";
+ status = "okay";
+ };
+
+ i2c@075b6000 {
+ /* On Low speed expansion */
+ label = "LS-I2C1";
+ status = "okay";
+ };
+
+ spi@07575000 {
+ /* On Low speed expansion */
+ label = "LS-SPI0";
+ status = "okay";
+ };
+
+ i2c@075b5000 {
+ /* On High speed expansion */
+ label = "HS-I2C2";
+ status = "okay";
+ };
+
+ spi@075ba000{
+ /* On High speed expansion */
+ label = "HS-SPI1";
+ status = "okay";
+ };
+
+ sdhci@74a4900 {
+ /* External SD card */
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+ cd-gpios = <&msmgpio 38 0x1>;
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 11bdc24cfc74..466ca5705c99 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -86,6 +86,11 @@
reg = <0x0 0x89300000 0x0 0x600000>;
no-map;
};
+
+ mba_mem: mba@8ea00000 {
+ no-map;
+ reg = <0 0x8ea00000 0 0x100000>;
+ };
};
cpus {
@@ -155,6 +160,49 @@
interrupts = <GIC_PPI 7 GIC_CPU_MASK_SIMPLE(4)>;
};
+ thermal-zones {
+ cpu-thermal0 {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 4>;
+
+ trips {
+ cpu_alert0: trip0 {
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu_crit0: trip1 {
+ temperature = <110000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu-thermal1 {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 3>;
+
+ trips {
+ cpu_alert1: trip0 {
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ cpu_crit1: trip1 {
+ temperature = <110000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
@@ -187,10 +235,11 @@
};
firmware {
- scm {
+ scm: scm {
compatible = "qcom,scm";
clocks = <&gcc GCC_CRYPTO_CLK>, <&gcc GCC_CRYPTO_AXI_CLK>, <&gcc GCC_CRYPTO_AHB_CLK>;
clock-names = "core", "bus", "iface";
+ #reset-cells = <1>;
};
};
@@ -228,6 +277,11 @@
reg = <0x1905000 0x20000>;
};
+ tcsr: syscon@1937000 {
+ compatible = "qcom,tcsr-msm8916", "syscon";
+ reg = <0x1937000 0x30000>;
+ };
+
tcsr_mutex: hwlock {
compatible = "qcom,tcsr-mutex";
syscon = <&tcsr_mutex_regs 0 0x1000>;
@@ -483,7 +537,7 @@
compatible = "qcom,ci-hdrc";
reg = <0x78d9000 0x400>;
dr_mode = "peripheral";
- interrupts = <GIC_SPI 134 IRQ_TYPE_NONE>;
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
usb-phy = <&usb_otg>;
status = "disabled";
};
@@ -491,7 +545,7 @@
usb_host: ehci@78d9000 {
compatible = "qcom,ehci-host";
reg = <0x78d9000 0x400>;
- interrupts = <GIC_SPI 134 IRQ_TYPE_NONE>;
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
usb-phy = <&usb_otg>;
status = "disabled";
};
@@ -499,8 +553,8 @@
usb_otg: phy@78d9000 {
compatible = "qcom,usb-otg-snps";
reg = <0x78d9000 0x400>;
- interrupts = <GIC_SPI 134 IRQ_TYPE_EDGE_BOTH>,
- <GIC_SPI 140 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
qcom,vdd-levels = <500000 1000000 1320000>;
qcom,phy-init-sequence = <0x44 0x6B 0x24 0x13>;
@@ -594,7 +648,7 @@
<0x200a000 0x002100>;
reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
interrupt-names = "periph_irq";
- interrupts = <GIC_SPI 190 IRQ_TYPE_NONE>;
+ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
qcom,ee = <0>;
qcom,channel = <0>;
#address-cells = <2>;
@@ -609,6 +663,144 @@
clocks = <&gcc GCC_PRNG_AHB_CLK>;
clock-names = "core";
};
+
+ qfprom: qfprom@5c000 {
+ compatible = "qcom,qfprom";
+ reg = <0x5c000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ tsens_caldata: caldata@d0 {
+ reg = <0xd0 0x8>;
+ };
+ tsens_calsel: calsel@ec {
+ reg = <0xec 0x4>;
+ };
+ };
+
+ tsens: thermal-sensor@4a8000 {
+ compatible = "qcom,msm8916-tsens";
+ reg = <0x4a8000 0x2000>;
+ nvmem-cells = <&tsens_caldata>, <&tsens_calsel>;
+ nvmem-cell-names = "calib", "calib_sel";
+ #thermal-sensor-cells = <1>;
+ };
+
+ mdss: mdss@1a00000 {
+ compatible = "qcom,mdss";
+ reg = <0x1a00000 0x1000>,
+ <0x1ac8000 0x3000>;
+ reg-names = "mdss_phys", "vbif_phys";
+
+ power-domains = <&gcc MDSS_GDSC>;
+
+ clocks = <&gcc GCC_MDSS_AHB_CLK>,
+ <&gcc GCC_MDSS_AXI_CLK>,
+ <&gcc GCC_MDSS_VSYNC_CLK>;
+ clock-names = "iface_clk",
+ "bus_clk",
+ "vsync_clk";
+
+ interrupts = <0 72 0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ mdp: mdp@1a01000 {
+ compatible = "qcom,mdp5";
+ reg = <0x1a01000 0x90000>;
+ reg-names = "mdp_phys";
+
+ interrupt-parent = <&mdss>;
+ interrupts = <0 0>;
+
+ clocks = <&gcc GCC_MDSS_AHB_CLK>,
+ <&gcc GCC_MDSS_AXI_CLK>,
+ <&gcc GCC_MDSS_MDP_CLK>,
+ <&gcc GCC_MDSS_VSYNC_CLK>;
+ clock-names = "iface_clk",
+ "bus_clk",
+ "core_clk",
+ "vsync_clk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ mdp5_intf1_out: endpoint {
+ remote-endpoint = <&dsi0_in>;
+ };
+ };
+ };
+ };
+
+ dsi0: dsi@1a98000 {
+ compatible = "qcom,mdss-dsi-ctrl";
+ reg = <0x1a98000 0x25c>;
+ reg-names = "dsi_ctrl";
+
+ interrupt-parent = <&mdss>;
+ interrupts = <4 0>;
+
+ assigned-clocks = <&gcc BYTE0_CLK_SRC>,
+ <&gcc PCLK0_CLK_SRC>;
+ assigned-clock-parents = <&dsi_phy0 0>,
+ <&dsi_phy0 1>;
+
+ clocks = <&gcc GCC_MDSS_MDP_CLK>,
+ <&gcc GCC_MDSS_AHB_CLK>,
+ <&gcc GCC_MDSS_AXI_CLK>,
+ <&gcc GCC_MDSS_BYTE0_CLK>,
+ <&gcc GCC_MDSS_PCLK0_CLK>,
+ <&gcc GCC_MDSS_ESC0_CLK>;
+ clock-names = "mdp_core_clk",
+ "iface_clk",
+ "bus_clk",
+ "byte_clk",
+ "pixel_clk",
+ "core_clk";
+ phys = <&dsi_phy0>;
+ phy-names = "dsi-phy";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dsi0_in: endpoint {
+ remote-endpoint = <&mdp5_intf1_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ dsi0_out: endpoint {
+ };
+ };
+ };
+ };
+
+ dsi_phy0: dsi-phy@1a98300 {
+ compatible = "qcom,dsi-phy-28nm-lp";
+ reg = <0x1a98300 0xd4>,
+ <0x1a98500 0x280>,
+ <0x1a98780 0x30>;
+ reg-names = "dsi_pll",
+ "dsi_phy",
+ "dsi_phy_regulator";
+
+ #clock-cells = <1>;
+
+ clocks = <&gcc GCC_MDSS_AHB_CLK>;
+ clock-names = "iface_clk";
+ };
+ };
};
smd {
@@ -657,6 +849,88 @@
};
};
};
+
+ hexagon-smp2p {
+ compatible = "qcom,smp2p";
+ qcom,smem = <435>, <428>;
+
+ interrupts = <0 27 IRQ_TYPE_EDGE_RISING>;
+
+ qcom,ipc = <&apcs 8 14>;
+
+ qcom,local-pid = <0>;
+ qcom,remote-pid = <1>;
+
+ hexagon_smp2p_out: master-kernel {
+ qcom,entry-name = "master-kernel";
+
+ #qcom,smem-state-cells = <1>;
+ };
+
+ hexagon_smp2p_in: slave-kernel {
+ qcom,entry-name = "slave-kernel";
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ wcnss-smp2p {
+ compatible = "qcom,smp2p";
+ qcom,smem = <451>, <431>;
+
+ interrupts = <0 143 IRQ_TYPE_EDGE_RISING>;
+
+ qcom,ipc = <&apcs 8 18>;
+
+ qcom,local-pid = <0>;
+ qcom,remote-pid = <4>;
+
+ wcnss_smp2p_out: master-kernel {
+ qcom,entry-name = "master-kernel";
+
+ #qcom,smem-state-cells = <1>;
+ };
+
+ wcnss_smp2p_in: slave-kernel {
+ qcom,entry-name = "slave-kernel";
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ smsm {
+ compatible = "qcom,smsm";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,ipc-1 = <&apcs 0 13>;
+ qcom,ipc-6 = <&apcs 0 19>;
+
+ apps_smsm: apps@0 {
+ reg = <0>;
+
+ #qcom,smem-state-cells = <1>;
+ };
+
+ hexagon_smsm: hexagon@1 {
+ reg = <1>;
+ interrupts = <0 26 IRQ_TYPE_EDGE_RISING>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ wcnss_smsm: wcnss@6 {
+ reg = <6>;
+ interrupts = <0 144 IRQ_TYPE_EDGE_RISING>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
};
#include "msm8916-pins.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 55ec3e8326b7..338f82a7fdc7 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -97,6 +97,92 @@
};
};
+ thermal-zones {
+ cpu-thermal0 {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens0 3>;
+
+ trips {
+ cpu_alert0: trip0 {
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_crit0: trip1 {
+ temperature = <110000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu-thermal1 {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens0 5>;
+
+ trips {
+ cpu_alert1: trip0 {
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_crit1: trip1 {
+ temperature = <110000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu-thermal2 {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens0 8>;
+
+ trips {
+ cpu_alert2: trip0 {
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_crit2: trip1 {
+ temperature = <110000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu-thermal3 {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens0 10>;
+
+ trips {
+ cpu_alert3: trip0 {
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_crit3: trip1 {
+ temperature = <110000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
@@ -181,6 +267,12 @@
status = "disabled";
};
+ tsens0: thermal-sensor@4a8000 {
+ compatible = "qcom,msm8996-tsens";
+ reg = <0x4a8000 0x2000>;
+ #thermal-sensor-cells = <1>;
+ };
+
blsp2_uart1: serial@75b0000 {
compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
reg = <0x75b0000 0x1000>;
@@ -339,7 +431,7 @@
<0x400a000 0x002100>;
reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
interrupt-names = "periph_irq";
- interrupts = <GIC_SPI 326 IRQ_TYPE_NONE>;
+ interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>;
qcom,ee = <0>;
qcom,channel = <0>;
#address-cells = <2>;
diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 17139f7003a6..eb72830ec9eb 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -1,4 +1,4 @@
-dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-x.dtb
+dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-x.dtb r8a7795-h3ulcb.dtb
dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x.dtb
always := $(dtb-y)
diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
new file mode 100644
index 000000000000..bcb11a868343
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
@@ -0,0 +1,328 @@
+/*
+ * Device Tree Source for the H3ULCB board
+ *
+ * Copyright (C) 2016 Renesas Electronics Corp.
+ * Copyright (C) 2016 Cogent Embedded, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "r8a7795.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "Renesas H3ULCB board based on r8a7795";
+ compatible = "renesas,h3ulcb", "renesas,r8a7795";
+
+ aliases {
+ serial0 = &scif2;
+ ethernet0 = &avb;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@48000000 {
+ device_type = "memory";
+ /* first 128MB is reserved for secure area. */
+ reg = <0x0 0x48000000 0x0 0x38000000>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led5 {
+ gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
+ };
+ led6 {
+ gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ keyboard {
+ compatible = "gpio-keys";
+
+ key-1 {
+ linux,code = <KEY_1>;
+ label = "SW3";
+ wakeup-source;
+ debounce-interval = <20>;
+ gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ x12_clk: x12 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24576000>;
+ };
+
+ vcc_sdhi0: regulator-vcc-sdhi0 {
+ 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-vccq-sdhi0 {
+ 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>;
+ };
+
+ audio_clkout: audio-clkout {
+ /*
+ * This is same as <&rcar_sound 0>
+ * but needed to avoid cs2000/rcar_sound probe dead-lock
+ */
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <11289600>;
+ };
+
+ rsnd_ak4613: sound {
+ compatible = "simple-audio-card";
+
+ simple-audio-card,format = "left_j";
+ simple-audio-card,bitclock-master = <&sndcpu>;
+ simple-audio-card,frame-master = <&sndcpu>;
+
+ sndcpu: simple-audio-card,cpu {
+ sound-dai = <&rcar_sound>;
+ };
+
+ sndcodec: simple-audio-card,codec {
+ sound-dai = <&ak4613>;
+ };
+ };
+};
+
+&extal_clk {
+ clock-frequency = <16666666>;
+};
+
+&extalr_clk {
+ clock-frequency = <32768>;
+};
+
+&pfc {
+ pinctrl-0 = <&scif_clk_pins>;
+ pinctrl-names = "default";
+
+ scif2_pins: scif2 {
+ groups = "scif2_data_a";
+ function = "scif2";
+ };
+
+ scif_clk_pins: scif_clk {
+ groups = "scif_clk_a";
+ function = "scif_clk";
+ };
+
+ i2c2_pins: i2c2 {
+ groups = "i2c2_a";
+ function = "i2c2";
+ };
+
+ avb_pins: avb {
+ groups = "avb_mdc";
+ function = "avb";
+ };
+
+ sdhi0_pins_3v3: sd0_3v3 {
+ groups = "sdhi0_data4", "sdhi0_ctrl";
+ function = "sdhi0";
+ power-source = <3300>;
+ };
+
+ sdhi0_pins_1v8: sd0_1v8 {
+ groups = "sdhi0_data4", "sdhi0_ctrl";
+ function = "sdhi0";
+ power-source = <1800>;
+ };
+
+ sound_pins: sound {
+ groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
+ function = "ssi";
+ };
+
+ sound_clk_pins: sound-clk {
+ groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a",
+ "audio_clkout_a", "audio_clkout3_a";
+ function = "audio_clk";
+ };
+
+ usb1_pins: usb1 {
+ groups = "usb1";
+ function = "usb1";
+ };
+};
+
+&scif2 {
+ pinctrl-0 = <&scif2_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&scif_clk {
+ clock-frequency = <14745600>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-0 = <&i2c2_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ clock-frequency = <100000>;
+
+ ak4613: codec@10 {
+ compatible = "asahi-kasei,ak4613";
+ #sound-dai-cells = <0>;
+ reg = <0x10>;
+ clocks = <&rcar_sound 3>;
+
+ asahi-kasei,in1-single-end;
+ asahi-kasei,in2-single-end;
+ asahi-kasei,out1-single-end;
+ asahi-kasei,out2-single-end;
+ asahi-kasei,out3-single-end;
+ asahi-kasei,out4-single-end;
+ asahi-kasei,out5-single-end;
+ asahi-kasei,out6-single-end;
+ };
+
+ cs2000: clk-multiplier@4f {
+ #clock-cells = <0>;
+ compatible = "cirrus,cs2000-cp";
+ reg = <0x4f>;
+ clocks = <&audio_clkout>, <&x12_clk>;
+ clock-names = "clk_in", "ref_clk";
+
+ assigned-clocks = <&cs2000>;
+ assigned-clock-rates = <24576000>; /* 1/1 divide */
+ };
+};
+
+&rcar_sound {
+ pinctrl-0 = <&sound_pins &sound_clk_pins>;
+ pinctrl-names = "default";
+
+ /* Single DAI */
+ #sound-dai-cells = <0>;
+
+ /* audio_clkout0/1/2/3 */
+ #clock-cells = <1>;
+ clock-frequency = <11289600>;
+
+ status = "okay";
+
+ /* update <audio_clk_b> to <cs2000> */
+ clocks = <&cpg CPG_MOD 1005>,
+ <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+ <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+ <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+ <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+ <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+ <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+ <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+ <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+ <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+ <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+ <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+ <&audio_clk_a>, <&cs2000>,
+ <&audio_clk_c>,
+ <&cpg CPG_CORE R8A7795_CLK_S0D4>;
+
+ rcar_sound,dai {
+ dai0 {
+ playback = <&ssi0 &src0 &dvc0>;
+ capture = <&ssi1 &src1 &dvc1>;
+ };
+ };
+};
+
+&sdhi0 {
+ pinctrl-0 = <&sdhi0_pins_3v3>;
+ pinctrl-1 = <&sdhi0_pins_1v8>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&vcc_sdhi0>;
+ vqmmc-supply = <&vccq_sdhi0>;
+ cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ sd-uhs-sdr50;
+ status = "okay";
+};
+
+&ssi1 {
+ shared-pin;
+};
+
+&wdt0 {
+ timeout-sec = <60>;
+ status = "okay";
+};
+
+&audio_clk_a {
+ clock-frequency = <22579200>;
+};
+
+&avb {
+ pinctrl-0 = <&avb_pins>;
+ pinctrl-names = "default";
+ renesas,no-ether-link;
+ phy-handle = <&phy0>;
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ rxc-skew-ps = <900>;
+ rxdv-skew-ps = <0>;
+ rxd0-skew-ps = <0>;
+ rxd1-skew-ps = <0>;
+ rxd2-skew-ps = <0>;
+ rxd3-skew-ps = <0>;
+ txc-skew-ps = <900>;
+ txen-skew-ps = <0>;
+ txd0-skew-ps = <0>;
+ txd1-skew-ps = <0>;
+ txd2-skew-ps = <0>;
+ txd3-skew-ps = <0>;
+ reg = <0>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&usb2_phy1 {
+ pinctrl-0 = <&usb1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
index 98f02631a0f0..b1eab6876f8c 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
+++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
@@ -110,6 +110,17 @@
1800000 0>;
};
+ vbus0_usb2: regulator-vbus0-usb2 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "USB20_VBUS0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+
+ gpio = <&gpio6 16 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
audio_clkout: audio_clkout {
/*
* This is same as <&rcar_sound 0>
@@ -135,6 +146,52 @@
sound-dai = <&ak4613>;
};
};
+
+ vga-encoder {
+ compatible = "adi,adv7123";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ adv7123_in: endpoint {
+ remote-endpoint = <&du_out_rgb>;
+ };
+ };
+ port@1 {
+ reg = <1>;
+ adv7123_out: endpoint {
+ remote-endpoint = <&vga_in>;
+ };
+ };
+ };
+ };
+
+ vga {
+ compatible = "vga-connector";
+
+ port {
+ vga_in: endpoint {
+ remote-endpoint = <&adv7123_out>;
+ };
+ };
+ };
+};
+
+&du {
+ pinctrl-0 = <&du_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ ports {
+ port@0 {
+ endpoint {
+ remote-endpoint = <&adv7123_in>;
+ };
+ };
+ };
};
&extal_clk {
@@ -172,6 +229,11 @@
function = "avb";
};
+ du_pins: du {
+ groups = "du_rgb888", "du_sync", "du_oddf", "du_clk_out_0";
+ function = "du";
+ };
+
sdhi0_pins: sd0 {
groups = "sdhi0_data4", "sdhi0_ctrl";
function = "sdhi0";
@@ -193,6 +255,11 @@
function = "audio_clk";
};
+ usb0_pins: usb0 {
+ groups = "usb0";
+ function = "usb0";
+ };
+
usb1_pins: usb1 {
groups = "usb1";
function = "usb1";
@@ -369,6 +436,14 @@
status = "okay";
};
+&usb2_phy0 {
+ pinctrl-0 = <&usb0_pins>;
+ pinctrl-names = "default";
+
+ vbus-supply = <&vbus0_usb2>;
+ status = "okay";
+};
+
&usb2_phy1 {
pinctrl-0 = <&usb1_pins>;
pinctrl-names = "default";
@@ -383,6 +458,10 @@
status = "okay";
};
+&ehci0 {
+ status = "okay";
+};
+
&ehci1 {
status = "okay";
};
@@ -391,6 +470,10 @@
status = "okay";
};
+&ohci0 {
+ status = "okay";
+};
+
&ohci1 {
status = "okay";
};
@@ -399,6 +482,10 @@
status = "okay";
};
+&hsusb {
+ status = "okay";
+};
+
&pcie_bus_clk {
clock-frequency = <100000000>;
status = "okay";
diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index b902356873c2..8c15040f2540 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -328,7 +328,8 @@
};
audma0: dma-controller@ec700000 {
- compatible = "renesas,rcar-dmac";
+ compatible = "renesas,dmac-r8a7795",
+ "renesas,rcar-dmac";
reg = <0 0xec700000 0 0x10000>;
interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
@@ -360,7 +361,8 @@
};
audma1: dma-controller@ec720000 {
- compatible = "renesas,rcar-dmac";
+ compatible = "renesas,dmac-r8a7795",
+ "renesas,rcar-dmac";
reg = <0 0xec720000 0 0x10000>;
interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH
@@ -1098,6 +1100,7 @@
reg = <0 0xee100000 0 0x2000>;
interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 314>;
+ max-frequency = <200000000>;
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
status = "disabled";
};
@@ -1107,6 +1110,7 @@
reg = <0 0xee120000 0 0x2000>;
interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 313>;
+ max-frequency = <200000000>;
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
status = "disabled";
};
@@ -1116,8 +1120,8 @@
reg = <0 0xee140000 0 0x2000>;
interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 312>;
+ max-frequency = <200000000>;
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
- cap-mmc-highspeed;
status = "disabled";
};
@@ -1126,8 +1130,8 @@
reg = <0 0xee160000 0 0x2000>;
interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 311>;
+ max-frequency = <200000000>;
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
- cap-mmc-highspeed;
status = "disabled";
};
@@ -1224,6 +1228,23 @@
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
status = "disabled";
};
+
+ hsusb: usb@e6590000 {
+ compatible = "renesas,usbhs-r8a7795",
+ "renesas,rcar-gen3-usbhs";
+ reg = <0 0xe6590000 0 0x100>;
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 704>;
+ dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
+ <&usb_dmac1 0>, <&usb_dmac1 1>;
+ dma-names = "ch0", "ch1", "ch2", "ch3";
+ renesas,buswait = <11>;
+ phys = <&usb2_phy0>;
+ phy-names = "usb";
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+ };
+
pciec0: pcie@fe000000 {
compatible = "renesas,pcie-r8a7795";
reg = <0 0xfe000000 0 0x80000>;
@@ -1273,5 +1294,252 @@
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
status = "disabled";
};
+
+ vspbc: vsp@fe920000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfe920000 0 0x8000>;
+ interrupts = <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 624>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+
+ renesas,fcp = <&fcpvb1>;
+ };
+
+ fcpvb1: fcp@fe92f000 {
+ compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ reg = <0 0xfe92f000 0 0x200>;
+ clocks = <&cpg CPG_MOD 606>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+ };
+
+ fcpf0: fcp@fe950000 {
+ compatible = "renesas,r8a7795-fcpf", "renesas,fcpf";
+ reg = <0 0xfe950000 0 0x200>;
+ clocks = <&cpg CPG_MOD 615>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+ };
+
+ fcpf1: fcp@fe951000 {
+ compatible = "renesas,r8a7795-fcpf", "renesas,fcpf";
+ reg = <0 0xfe951000 0 0x200>;
+ clocks = <&cpg CPG_MOD 614>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+ };
+
+ fcpf2: fcp@fe952000 {
+ compatible = "renesas,r8a7795-fcpf", "renesas,fcpf";
+ reg = <0 0xfe952000 0 0x200>;
+ clocks = <&cpg CPG_MOD 613>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+ };
+
+ vspbd: vsp@fe960000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfe960000 0 0x8000>;
+ interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 626>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+
+ renesas,fcp = <&fcpvb0>;
+ };
+
+ fcpvb0: fcp@fe96f000 {
+ compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ reg = <0 0xfe96f000 0 0x200>;
+ clocks = <&cpg CPG_MOD 607>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+ };
+
+ vspi0: vsp@fe9a0000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfe9a0000 0 0x8000>;
+ interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 631>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+
+ renesas,fcp = <&fcpvi0>;
+ };
+
+ fcpvi0: fcp@fe9af000 {
+ compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ reg = <0 0xfe9af000 0 0x200>;
+ clocks = <&cpg CPG_MOD 611>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+ };
+
+ vspi1: vsp@fe9b0000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfe9b0000 0 0x8000>;
+ interrupts = <GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 630>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+
+ renesas,fcp = <&fcpvi1>;
+ };
+
+ fcpvi1: fcp@fe9bf000 {
+ compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ reg = <0 0xfe9bf000 0 0x200>;
+ clocks = <&cpg CPG_MOD 610>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+ };
+
+ vspi2: vsp@fe9c0000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfe9c0000 0 0x8000>;
+ interrupts = <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 629>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+
+ renesas,fcp = <&fcpvi2>;
+ };
+
+ fcpvi2: fcp@fe9cf000 {
+ compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ reg = <0 0xfe9cf000 0 0x200>;
+ clocks = <&cpg CPG_MOD 609>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+ };
+
+ vspd0: vsp@fea20000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfea20000 0 0x4000>;
+ interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 623>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+
+ renesas,fcp = <&fcpvd0>;
+ };
+
+ fcpvd0: fcp@fea27000 {
+ compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ reg = <0 0xfea27000 0 0x200>;
+ clocks = <&cpg CPG_MOD 603>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ };
+
+ vspd1: vsp@fea28000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfea28000 0 0x4000>;
+ interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 622>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+
+ renesas,fcp = <&fcpvd1>;
+ };
+
+ fcpvd1: fcp@fea2f000 {
+ compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ reg = <0 0xfea2f000 0 0x200>;
+ clocks = <&cpg CPG_MOD 602>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ };
+
+ vspd2: vsp@fea30000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfea30000 0 0x4000>;
+ interrupts = <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 621>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+
+ renesas,fcp = <&fcpvd2>;
+ };
+
+ fcpvd2: fcp@fea37000 {
+ compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ reg = <0 0xfea37000 0 0x200>;
+ clocks = <&cpg CPG_MOD 601>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ };
+
+ vspd3: vsp@fea38000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfea38000 0 0x4000>;
+ interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 620>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+
+ renesas,fcp = <&fcpvd3>;
+ };
+
+ fcpvd3: fcp@fea3f000 {
+ compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
+ reg = <0 0xfea3f000 0 0x200>;
+ clocks = <&cpg CPG_MOD 600>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ };
+
+ fdp1@fe940000 {
+ compatible = "renesas,fdp1";
+ reg = <0 0xfe940000 0 0x2400>;
+ interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 119>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+ renesas,fcp = <&fcpf0>;
+ };
+
+ fdp1@fe944000 {
+ compatible = "renesas,fdp1";
+ reg = <0 0xfe944000 0 0x2400>;
+ interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 118>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+ renesas,fcp = <&fcpf1>;
+ };
+
+ fdp1@fe948000 {
+ compatible = "renesas,fdp1";
+ reg = <0 0xfe948000 0 0x2400>;
+ interrupts = <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 117>;
+ power-domains = <&sysc R8A7795_PD_A3VP>;
+ renesas,fcp = <&fcpf2>;
+ };
+
+ du: display@feb00000 {
+ compatible = "renesas,du-r8a7795";
+ reg = <0 0xfeb00000 0 0x80000>,
+ <0 0xfeb90000 0 0x14>;
+ reg-names = "du", "lvds.0";
+ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 724>,
+ <&cpg CPG_MOD 723>,
+ <&cpg CPG_MOD 722>,
+ <&cpg CPG_MOD 721>,
+ <&cpg CPG_MOD 727>;
+ clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0";
+ status = "disabled";
+
+ vsps = <&vspd0 &vspd1 &vspd2 &vspd3>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ du_out_rgb: endpoint {
+ };
+ };
+ port@1 {
+ reg = <1>;
+ du_out_hdmi0: endpoint {
+ };
+ };
+ port@2 {
+ reg = <2>;
+ du_out_hdmi1: endpoint {
+ };
+ };
+ port@3 {
+ reg = <3>;
+ du_out_lvds0: endpoint {
+ };
+ };
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts
index e72be3856d79..13db7d61c26c 100644
--- a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts
+++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts
@@ -31,11 +31,27 @@
};
};
+&pfc {
+ pinctrl-0 = <&scif_clk_pins>;
+ pinctrl-names = "default";
+
+ scif2_pins: scif2 {
+ groups = "scif2_data_a";
+ function = "scif2";
+ };
+ scif_clk_pins: scif_clk {
+ groups = "scif_clk_a";
+ function = "scif_clk";
+ };
+};
+
&extal_clk {
clock-frequency = <16666666>;
};
&scif2 {
+ pinctrl-0 = <&scif2_pins>;
+ pinctrl-names = "default";
status = "okay";
};
diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
index 1edf82440d78..9217da983525 100644
--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
@@ -107,6 +107,123 @@
status = "disabled";
};
+ gpio0: gpio@e6050000 {
+ compatible = "renesas,gpio-r8a7796",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6050000 0 0x50>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 0 16>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 912>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ };
+
+ gpio1: gpio@e6051000 {
+ compatible = "renesas,gpio-r8a7796",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6051000 0 0x50>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 32 29>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 911>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ };
+
+ gpio2: gpio@e6052000 {
+ compatible = "renesas,gpio-r8a7796",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6052000 0 0x50>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 64 15>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 910>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ };
+
+ gpio3: gpio@e6053000 {
+ compatible = "renesas,gpio-r8a7796",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6053000 0 0x50>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 96 16>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 909>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ };
+
+ gpio4: gpio@e6054000 {
+ compatible = "renesas,gpio-r8a7796",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6054000 0 0x50>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 128 18>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 908>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ };
+
+ gpio5: gpio@e6055000 {
+ compatible = "renesas,gpio-r8a7796",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6055000 0 0x50>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 160 26>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 907>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ };
+
+ gpio6: gpio@e6055400 {
+ compatible = "renesas,gpio-r8a7796",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6055400 0 0x50>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 192 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 906>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ };
+
+ gpio7: gpio@e6055800 {
+ compatible = "renesas,gpio-r8a7796",
+ "renesas,gpio-rcar";
+ reg = <0 0xe6055800 0 0x50>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 224 4>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 905>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ };
+
+ pfc: pin-controller@e6060000 {
+ compatible = "renesas,pfc-r8a7796";
+ reg = <0 0xe6060000 0 0x50c>;
+ };
+
cpg: clock-controller@e6150000 {
compatible = "renesas,r8a7796-cpg-mssr";
reg = <0 0xe6150000 0 0x1000>;
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 7037a161b6ef..87669f656454 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -1,5 +1,6 @@
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-geekbox.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-orion-r68-meta.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-r88.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-evb.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
new file mode 100644
index 000000000000..5797933ef80e
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2016 Matthias Brugger <mbrugger@suse.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 "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/input/input.h>
+#include "rk3368.dtsi"
+
+/ {
+ model = "Rockchip Orion R68";
+ compatible = "tronsmart,orion-r68-meta", "rockchip,rk3368";
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x80000000>;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ pinctrl-0 = <&emmc_reset>;
+ pinctrl-names = "default";
+ reset-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+ };
+
+ ext_gmac: external-gmac-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <125000000>;
+ clock-output-names = "ext_gmac";
+ };
+
+ keys: gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwr_key>;
+
+ power {
+ wakeup-source;
+ gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;
+ label = "GPIO Power";
+ linux,code = <KEY_POWER>;
+ };
+ };
+
+ leds: gpio-leds {
+ compatible = "gpio-leds";
+
+ red {
+ gpios = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+ label = "orion:red:led";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_ctl>;
+ default-state = "on";
+ };
+
+ blue {
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ label = "orion:blue:led";
+ pinctrl-names = "default";
+ pinctrl-0 = <&stby_pwren>;
+ default-state = "off";
+ };
+ };
+
+ vcc_18: vcc18-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ /* supplies both host and otg */
+ vcc_host: vcc-host-regulator {
+ compatible = "regulator-fixed";
+ gpio = <&gpio0 4 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_vbus_drv>;
+ regulator-name = "vcc_host";
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vcc_io: vcc-io-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vcc_lan: vcc-lan-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_lan";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_sd: vcc-sd-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sd";
+ gpio = <&gpio3 11 GPIO_ACTIVE_LOW>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_sys: vcc-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vccio_sd: vcc-io-sd-regulator {
+ compatible = "regulator-fixed";
+ regulator-name= "vccio_sd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_io>;
+ };
+
+ vccio_wl: vccio-wl-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vccio_wl";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_io>;
+ };
+
+ vdd_10: vdd-10-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_10";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ };
+};
+
+&emmc {
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ disable-wp;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&emmc_pwrseq>;
+ mmc-hs200-1_2v;
+ mmc-hs200-1_8v;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+ status = "okay";
+};
+
+&gmac {
+ assigned-clocks = <&cru SCLK_MAC>;
+ assigned-clock-parents = <&ext_gmac>;
+ clock_in_out = "input";
+ phy-supply = <&vcc_lan>;
+ phy-mode = "rgmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
+ snps,reset-gpio = <&gpio3 12 0>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 1000000>;
+ tx_delay = <0x30>;
+ rx_delay = <0x10>;
+ status = "ok";
+};
+
+&i2c0 {
+ status = "okay";
+
+ vdd_cpu: syr827@40 {
+ compatible = "silergy,syr827";
+ reg = <0x40>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu";
+ regulator-enable-ramp-delay = <300>;
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1500000>;
+ regulator-ramp-delay = <8000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ hym8563: hym8563@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ /* rtc_int is not connected */
+ };
+};
+
+&pinctrl {
+ pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
+ bias-disable;
+ drive-strength = <8>;
+ };
+
+ pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma {
+ bias-pull-up;
+ drive-strength = <8>;
+ };
+
+ emmc {
+ emmc_bus8: emmc-bus8 {
+ rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 19 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 20 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 21 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 22 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 23 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 24 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
+ <1 25 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
+ };
+
+ emmc-clk {
+ rockchip,pins = <2 4 RK_FUNC_2 &pcfg_pull_none_drv_8ma>;
+ };
+
+ emmc-cmd {
+ rockchip,pins = <1 26 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
+ };
+
+ emmc_reset: emmc-reset {
+ rockchip,pins = <2 3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ keys {
+ pwr_key: pwr-key {
+ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+
+ leds {
+ stby_pwren: stby-pwren {
+ rockchip,pins = <0 12 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ led_ctl: led-ctl {
+ rockchip,pins = <3 29 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_clk: sdmmc-clk {
+ rockchip,pins = <2 9 RK_FUNC_1 &pcfg_pull_none_drv_8ma>;
+ };
+
+ sdmmc_cmd: sdmmc-cmd {
+ rockchip,pins = <2 10 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
+ };
+
+ sdmmc_cd: sdmmc-cd {
+ rockchip,pins = <2 11 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
+ };
+
+ sdmmc_bus1: sdmmc-bus1 {
+ rockchip,pins = <2 5 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
+ };
+
+ sdmmc_bus4: sdmmc-bus4 {
+ rockchip,pins = <2 5 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
+ <2 6 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
+ <2 7 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
+ <2 8 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
+ };
+ };
+
+ usb {
+ host_vbus_drv: host-vbus-drv {
+ rockchip,pins = <0 4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&saradc {
+ vref-supply = <&vcc_18>;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ clock-frequency = <50000000>;
+ clock-freq-min-max = <400000 50000000>;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ keep-power-in-suspend;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+ vmmc-supply = <&vcc_sd>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_xfer>;
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
index 82a32e5591e2..eed1ef6669ff 100644
--- a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
@@ -248,7 +248,6 @@
&sdio0 {
assigned-clocks = <&cru SCLK_SDIO0>;
assigned-clock-parents = <&cru PLL_CPLL>;
- broken-cd;
bus-width = <4>;
cap-sd-highspeed;
cap-sdio-irq;
diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
index 4f44d1191bfd..0fcb2147c9f9 100644
--- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi
@@ -45,6 +45,7 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,boot-mode.h>
#include <dt-bindings/thermal/thermal.h>
/ {
@@ -641,6 +642,15 @@
compatible = "rockchip,rk3368-pmu-io-voltage-domain";
status = "disabled";
};
+
+ reboot-mode {
+ compatible = "syscon-reboot-mode";
+ offset = <0x200>;
+ mode-normal = <BOOT_NORMAL>;
+ mode-recovery = <BOOT_RECOVERY>;
+ mode-bootloader = <BOOT_FASTBOOT>;
+ mode-loader = <BOOT_BL_DOWNLOAD>;
+ };
};
cru: clock-controller@ff760000 {
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb.dts
index d33aa06d46f5..8e82497925fe 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-evb.dts
@@ -49,6 +49,13 @@
compatible = "rockchip,rk3399-evb", "rockchip,rk3399",
"google,rk3399evb-rev2";
+ clkin_gmac: external-gmac-clock {
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ clock-output-names = "clkin_gmac";
+ #clock-cells = <0>;
+ };
+
vdd_center: vdd-center {
compatible = "pwm-regulator";
pwms = <&pwm3 0 25000 0>;
@@ -69,18 +76,61 @@
regulator-max-microvolt = <3300000>;
};
+ vcc5v0_sys: vcc5v0-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc5v0_host: vcc5v0-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_host_en>;
+ regulator-name = "vcc5v0_host";
+ vin-supply = <&vcc5v0_sys>;
+ };
+
vcc_phy: vcc-phy-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc_phy";
regulator-always-on;
regulator-boot-on;
};
+
+ vcc_phy: vcc-phy-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_phy";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
};
&emmc_phy {
status = "okay";
};
+&gmac {
+ assigned-clocks = <&cru SCLK_RMII_SRC>;
+ assigned-clock-parents = <&clkin_gmac>;
+ clock_in_out = "input";
+ phy-supply = <&vcc_phy>;
+ phy-mode = "rgmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
+ snps,reset-gpio = <&gpio3 15 GPIO_ACTIVE_LOW>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 50000>;
+ tx_delay = <0x28>;
+ rx_delay = <0x11>;
+ status = "okay";
+};
+
&pwm0 {
status = "okay";
};
@@ -101,6 +151,36 @@
status = "okay";
};
+&pcie_phy {
+ status = "disabled";
+};
+
+&pcie0 {
+ ep-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
+ num-lanes = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_clkreqn>;
+ status = "disabled";
+};
+
+&u2phy0 {
+ status = "okay";
+};
+
+&u2phy0_host {
+ phy-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
+&u2phy1 {
+ status = "okay";
+};
+
+&u2phy1_host {
+ phy-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
&uart2 {
status = "okay";
};
@@ -133,4 +213,11 @@
<1 18 RK_FUNC_GPIO &pcfg_pull_down>;
};
};
+
+ usb2 {
+ vcc5v0_host_en: vcc5v0-host-en {
+ rockchip,pins =
+ <4 25 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index a6dd623a8845..b65c193dc64e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -45,6 +45,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/power/rk3399-power.h>
#include <dt-bindings/thermal/thermal.h>
/ {
@@ -152,6 +153,16 @@
};
};
+ pmu_a53 {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW &ppi_cluster0>;
+ };
+
+ pmu_a72 {
+ compatible = "arm,cortex-a72-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW &ppi_cluster1>;
+ };
+
psci {
compatible = "arm,psci-1.0";
method = "smc";
@@ -159,10 +170,10 @@
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>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW 0>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW 0>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW 0>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW 0>;
};
xin24m: xin24m {
@@ -181,8 +192,8 @@
dmac_bus: dma-controller@ff6d0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x0 0xff6d0000 0x0 0x4000>;
- interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH 0>;
#dma-cells = <1>;
clocks = <&cru ACLK_DMAC0_PERILP>;
clock-names = "apb_pclk";
@@ -191,19 +202,39 @@
dmac_peri: dma-controller@ff6e0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x0 0xff6e0000 0x0 0x4000>;
- interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH 0>;
#dma-cells = <1>;
clocks = <&cru ACLK_DMAC1_PERILP>;
clock-names = "apb_pclk";
};
};
+ gmac: ethernet@fe300000 {
+ compatible = "rockchip,rk3399-gmac";
+ reg = <0x0 0xfe300000 0x0 0x10000>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "macirq";
+ clocks = <&cru SCLK_MAC>, <&cru SCLK_MAC_RX>,
+ <&cru SCLK_MAC_TX>, <&cru SCLK_MACREF>,
+ <&cru SCLK_MACREF_OUT>, <&cru ACLK_GMAC>,
+ <&cru PCLK_GMAC>;
+ clock-names = "stmmaceth", "mac_clk_rx",
+ "mac_clk_tx", "clk_mac_ref",
+ "clk_mac_refout", "aclk_mac",
+ "pclk_mac";
+ power-domains = <&power RK3399_PD_GMAC>;
+ resets = <&cru SRST_A_GMAC>;
+ reset-names = "stmmaceth";
+ rockchip,grf = <&grf>;
+ status = "disabled";
+ };
+
sdio0: dwmmc@fe310000 {
compatible = "rockchip,rk3399-dw-mshc",
"rockchip,rk3288-dw-mshc";
reg = <0x0 0xfe310000 0x0 0x4000>;
- interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH 0>;
clock-freq-min-max = <400000 150000000>;
clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
<&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
@@ -216,7 +247,7 @@
compatible = "rockchip,rk3399-dw-mshc",
"rockchip,rk3288-dw-mshc";
reg = <0x0 0xfe320000 0x0 0x4000>;
- interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH 0>;
clock-freq-min-max = <400000 150000000>;
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
<&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
@@ -228,7 +259,7 @@
sdhci: sdhci@fe330000 {
compatible = "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1";
reg = <0x0 0xfe330000 0x0 0x10000>;
- interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH 0>;
arasan,soc-ctl-syscon = <&grf>;
assigned-clocks = <&cru SCLK_EMMC>;
assigned-clock-rates = <200000000>;
@@ -241,19 +272,60 @@
status = "disabled";
};
+ pcie0: pcie@f8000000 {
+ compatible = "rockchip,rk3399-pcie";
+ reg = <0x0 0xf8000000 0x0 0x2000000>,
+ <0x0 0xfd000000 0x0 0x1000000>;
+ reg-names = "axi-base", "apb-base";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ bus-range = <0x0 0x1>;
+ clocks = <&cru ACLK_PCIE>, <&cru ACLK_PERF_PCIE>,
+ <&cru PCLK_PCIE>, <&cru SCLK_PCIE_PM>;
+ clock-names = "aclk", "aclk-perf",
+ "hclk", "pm";
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "sys", "legacy", "client";
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie0_intc 0>,
+ <0 0 0 2 &pcie0_intc 1>,
+ <0 0 0 3 &pcie0_intc 2>,
+ <0 0 0 4 &pcie0_intc 3>;
+ msi-map = <0x0 &its 0x0 0x1000>;
+ phys = <&pcie_phy>;
+ phy-names = "pcie-phy";
+ ranges = <0x83000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x600000
+ 0x81000000 0x0 0xfa600000 0x0 0xfa600000 0x0 0x100000>;
+ resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>,
+ <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>;
+ reset-names = "core", "mgmt", "mgmt-sticky", "pipe";
+ status = "disabled";
+
+ pcie0_intc: interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+ };
+
usb_host0_ehci: usb@fe380000 {
compatible = "generic-ehci";
reg = <0x0 0xfe380000 0x0 0x20000>;
- interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>;
clock-names = "hclk_host0", "hclk_host0_arb";
+ phys = <&u2phy0_host>;
+ phy-names = "usb";
status = "disabled";
};
usb_host0_ohci: usb@fe3a0000 {
compatible = "generic-ohci";
reg = <0x0 0xfe3a0000 0x0 0x20000>;
- interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>;
clock-names = "hclk_host0", "hclk_host0_arb";
status = "disabled";
@@ -262,16 +334,18 @@
usb_host1_ehci: usb@fe3c0000 {
compatible = "generic-ehci";
reg = <0x0 0xfe3c0000 0x0 0x20000>;
- interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST1_ARB>;
clock-names = "hclk_host1", "hclk_host1_arb";
+ phys = <&u2phy1_host>;
+ phy-names = "usb";
status = "disabled";
};
usb_host1_ohci: usb@fe3e0000 {
compatible = "generic-ohci";
reg = <0x0 0xfe3e0000 0x0 0x20000>;
- interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST1_ARB>;
clock-names = "hclk_host1", "hclk_host1_arb";
status = "disabled";
@@ -279,7 +353,7 @@
gic: interrupt-controller@fee00000 {
compatible = "arm,gic-v3";
- #interrupt-cells = <3>;
+ #interrupt-cells = <4>;
#address-cells = <2>;
#size-cells = <2>;
ranges;
@@ -290,12 +364,34 @@
<0x0 0xfff00000 0 0x10000>, /* GICC */
<0x0 0xfff10000 0 0x10000>, /* GICH */
<0x0 0xfff20000 0 0x10000>; /* GICV */
- interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
its: interrupt-controller@fee20000 {
compatible = "arm,gic-v3-its";
msi-controller;
reg = <0x0 0xfee20000 0x0 0x20000>;
};
+
+ ppi-partitions {
+ ppi_cluster0: interrupt-partition-0 {
+ affinity = <&cpu_l0 &cpu_l1 &cpu_l2 &cpu_l3>;
+ };
+
+ ppi_cluster1: interrupt-partition-1 {
+ affinity = <&cpu_b0 &cpu_b1>;
+ };
+ };
+ };
+
+ saradc: saradc@ff100000 {
+ compatible = "rockchip,rk3399-saradc";
+ reg = <0x0 0xff100000 0x0 0x100>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH 0>;
+ #io-channel-cells = <1>;
+ clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+ clock-names = "saradc", "apb_pclk";
+ resets = <&cru SRST_P_SARADC>;
+ reset-names = "saradc-apb";
+ status = "disabled";
};
i2c1: i2c@ff110000 {
@@ -305,7 +401,7 @@
assigned-clock-rates = <200000000>;
clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>;
clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c1_xfer>;
#address-cells = <1>;
@@ -320,7 +416,7 @@
assigned-clock-rates = <200000000>;
clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>;
clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c2_xfer>;
#address-cells = <1>;
@@ -335,7 +431,7 @@
assigned-clock-rates = <200000000>;
clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>;
clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c3_xfer>;
#address-cells = <1>;
@@ -350,7 +446,7 @@
assigned-clock-rates = <200000000>;
clocks = <&cru SCLK_I2C5>, <&cru PCLK_I2C5>;
clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c5_xfer>;
#address-cells = <1>;
@@ -365,7 +461,7 @@
assigned-clock-rates = <200000000>;
clocks = <&cru SCLK_I2C6>, <&cru PCLK_I2C6>;
clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c6_xfer>;
#address-cells = <1>;
@@ -380,7 +476,7 @@
assigned-clock-rates = <200000000>;
clocks = <&cru SCLK_I2C7>, <&cru PCLK_I2C7>;
clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c7_xfer>;
#address-cells = <1>;
@@ -393,7 +489,7 @@
reg = <0x0 0xff180000 0x0 0x100>;
clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
clock-names = "baudclk", "apb_pclk";
- interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH 0>;
reg-shift = <2>;
reg-io-width = <4>;
pinctrl-names = "default";
@@ -406,7 +502,7 @@
reg = <0x0 0xff190000 0x0 0x100>;
clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
clock-names = "baudclk", "apb_pclk";
- interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH 0>;
reg-shift = <2>;
reg-io-width = <4>;
pinctrl-names = "default";
@@ -419,7 +515,7 @@
reg = <0x0 0xff1a0000 0x0 0x100>;
clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
clock-names = "baudclk", "apb_pclk";
- interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH 0>;
reg-shift = <2>;
reg-io-width = <4>;
pinctrl-names = "default";
@@ -432,7 +528,7 @@
reg = <0x0 0xff1b0000 0x0 0x100>;
clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
clock-names = "baudclk", "apb_pclk";
- interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH 0>;
reg-shift = <2>;
reg-io-width = <4>;
pinctrl-names = "default";
@@ -445,7 +541,7 @@
reg = <0x0 0xff1c0000 0x0 0x1000>;
clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
clock-names = "spiclk", "apb_pclk";
- interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
#address-cells = <1>;
@@ -458,7 +554,7 @@
reg = <0x0 0xff1d0000 0x0 0x1000>;
clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
clock-names = "spiclk", "apb_pclk";
- interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
#address-cells = <1>;
@@ -471,7 +567,7 @@
reg = <0x0 0xff1e0000 0x0 0x1000>;
clocks = <&cru SCLK_SPI2>, <&cru PCLK_SPI2>;
clock-names = "spiclk", "apb_pclk";
- interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&spi2_clk &spi2_tx &spi2_rx &spi2_cs0>;
#address-cells = <1>;
@@ -484,7 +580,7 @@
reg = <0x0 0xff1f0000 0x0 0x1000>;
clocks = <&cru SCLK_SPI4>, <&cru PCLK_SPI4>;
clock-names = "spiclk", "apb_pclk";
- interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&spi4_clk &spi4_tx &spi4_rx &spi4_cs0>;
#address-cells = <1>;
@@ -497,7 +593,7 @@
reg = <0x0 0xff200000 0x0 0x1000>;
clocks = <&cru SCLK_SPI5>, <&cru PCLK_SPI5>;
clock-names = "spiclk", "apb_pclk";
- interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&spi5_clk &spi5_tx &spi5_rx &spi5_cs0>;
#address-cells = <1>;
@@ -577,7 +673,7 @@
tsadc: tsadc@ff260000 {
compatible = "rockchip,rk3399-tsadc";
reg = <0x0 0xff260000 0x0 0x100>;
- interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH 0>;
assigned-clocks = <&cru SCLK_TSADC>;
assigned-clock-rates = <750000>;
clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;
@@ -594,6 +690,203 @@
status = "disabled";
};
+ qos_gmac: qos@ffa5c000 {
+ compatible = "syscon";
+ reg = <0x0 0xffa5c000 0x0 0x20>;
+ };
+
+ qos_hdcp: qos@ffa90000 {
+ compatible = "syscon";
+ reg = <0x0 0xffa90000 0x0 0x20>;
+ };
+
+ qos_iep: qos@ffa98000 {
+ compatible = "syscon";
+ reg = <0x0 0xffa98000 0x0 0x20>;
+ };
+
+ qos_isp0_m0: qos@ffaa0000 {
+ compatible = "syscon";
+ reg = <0x0 0xffaa0000 0x0 0x20>;
+ };
+
+ qos_isp0_m1: qos@ffaa0080 {
+ compatible = "syscon";
+ reg = <0x0 0xffaa0080 0x0 0x20>;
+ };
+
+ qos_isp1_m0: qos@ffaa8000 {
+ compatible = "syscon";
+ reg = <0x0 0xffaa8000 0x0 0x20>;
+ };
+
+ qos_isp1_m1: qos@ffaa8080 {
+ compatible = "syscon";
+ reg = <0x0 0xffaa8080 0x0 0x20>;
+ };
+
+ qos_rga_r: qos@ffab0000 {
+ compatible = "syscon";
+ reg = <0x0 0xffab0000 0x0 0x20>;
+ };
+
+ qos_rga_w: qos@ffab0080 {
+ compatible = "syscon";
+ reg = <0x0 0xffab0080 0x0 0x20>;
+ };
+
+ qos_video_m0: qos@ffab8000 {
+ compatible = "syscon";
+ reg = <0x0 0xffab8000 0x0 0x20>;
+ };
+
+ qos_video_m1_r: qos@ffac0000 {
+ compatible = "syscon";
+ reg = <0x0 0xffac0000 0x0 0x20>;
+ };
+
+ qos_video_m1_w: qos@ffac0080 {
+ compatible = "syscon";
+ reg = <0x0 0xffac0080 0x0 0x20>;
+ };
+
+ qos_vop_big_r: qos@ffac8000 {
+ compatible = "syscon";
+ reg = <0x0 0xffac8000 0x0 0x20>;
+ };
+
+ qos_vop_big_w: qos@ffac8080 {
+ compatible = "syscon";
+ reg = <0x0 0xffac8080 0x0 0x20>;
+ };
+
+ qos_vop_little: qos@ffad0000 {
+ compatible = "syscon";
+ reg = <0x0 0xffad0000 0x0 0x20>;
+ };
+
+ qos_gpu: qos@ffae0000 {
+ compatible = "syscon";
+ reg = <0x0 0xffae0000 0x0 0x20>;
+ };
+
+ pmu: power-management@ff310000 {
+ compatible = "rockchip,rk3399-pmu", "syscon", "simple-mfd";
+ reg = <0x0 0xff310000 0x0 0x1000>;
+
+ /*
+ * Note: RK3399 supports 6 voltage domains including VD_CORE_L,
+ * VD_CORE_B, VD_CENTER, VD_GPU, VD_LOGIC and VD_PMU.
+ * Some of the power domains are grouped together for every
+ * voltage domain.
+ * The detail contents as below.
+ */
+ power: power-controller {
+ compatible = "rockchip,rk3399-power-controller";
+ #power-domain-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* These power domains are grouped by VD_CENTER */
+ pd_iep@RK3399_PD_IEP {
+ reg = <RK3399_PD_IEP>;
+ clocks = <&cru ACLK_IEP>,
+ <&cru HCLK_IEP>;
+ pm_qos = <&qos_iep>;
+ };
+ pd_rga@RK3399_PD_RGA {
+ reg = <RK3399_PD_RGA>;
+ clocks = <&cru ACLK_RGA>,
+ <&cru HCLK_RGA>;
+ pm_qos = <&qos_rga_r>,
+ <&qos_rga_w>;
+ };
+ pd_vcodec@RK3399_PD_VCODEC {
+ reg = <RK3399_PD_VCODEC>;
+ clocks = <&cru ACLK_VCODEC>,
+ <&cru HCLK_VCODEC>;
+ pm_qos = <&qos_video_m0>;
+ };
+ pd_vdu@RK3399_PD_VDU {
+ reg = <RK3399_PD_VDU>;
+ clocks = <&cru ACLK_VDU>,
+ <&cru HCLK_VDU>;
+ pm_qos = <&qos_video_m1_r>,
+ <&qos_video_m1_w>;
+ };
+
+ /* These power domains are grouped by VD_GPU */
+ pd_gpu@RK3399_PD_GPU {
+ reg = <RK3399_PD_GPU>;
+ clocks = <&cru ACLK_GPU>;
+ pm_qos = <&qos_gpu>;
+ };
+
+ /* These power domains are grouped by VD_LOGIC */
+ pd_gmac@RK3399_PD_GMAC {
+ reg = <RK3399_PD_GMAC>;
+ clocks = <&cru ACLK_GMAC>;
+ pm_qos = <&qos_gmac>;
+ };
+ pd_vio@RK3399_PD_VIO {
+ reg = <RK3399_PD_VIO>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_hdcp@RK3399_PD_HDCP {
+ reg = <RK3399_PD_HDCP>;
+ clocks = <&cru ACLK_HDCP>,
+ <&cru HCLK_HDCP>,
+ <&cru PCLK_HDCP>;
+ pm_qos = <&qos_hdcp>;
+ };
+ pd_isp0@RK3399_PD_ISP0 {
+ reg = <RK3399_PD_ISP0>;
+ clocks = <&cru ACLK_ISP0>,
+ <&cru HCLK_ISP0>;
+ pm_qos = <&qos_isp0_m0>,
+ <&qos_isp0_m1>;
+ };
+ pd_isp1@RK3399_PD_ISP1 {
+ reg = <RK3399_PD_ISP1>;
+ clocks = <&cru ACLK_ISP1>,
+ <&cru HCLK_ISP1>;
+ pm_qos = <&qos_isp1_m0>,
+ <&qos_isp1_m1>;
+ };
+ pd_tcpc0@RK3399_PD_TCPC0 {
+ reg = <RK3399_PD_TCPD0>;
+ clocks = <&cru SCLK_UPHY0_TCPDCORE>,
+ <&cru SCLK_UPHY0_TCPDPHY_REF>;
+ };
+ pd_tcpc1@RK3399_PD_TCPC1 {
+ reg = <RK3399_PD_TCPD1>;
+ clocks = <&cru SCLK_UPHY1_TCPDCORE>,
+ <&cru SCLK_UPHY1_TCPDPHY_REF>;
+ };
+ pd_vo@RK3399_PD_VO {
+ reg = <RK3399_PD_VO>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pd_vopb@RK3399_PD_VOPB {
+ reg = <RK3399_PD_VOPB>;
+ clocks = <&cru ACLK_VOP0>,
+ <&cru HCLK_VOP0>;
+ pm_qos = <&qos_vop_big_r>,
+ <&qos_vop_big_w>;
+ };
+ pd_vopl@RK3399_PD_VOPL {
+ reg = <RK3399_PD_VOPL>;
+ clocks = <&cru ACLK_VOP1>,
+ <&cru HCLK_VOP1>;
+ pm_qos = <&qos_vop_little>;
+ };
+ };
+ };
+ };
+ };
+
pmugrf: syscon@ff320000 {
compatible = "rockchip,rk3399-pmugrf", "syscon", "simple-mfd";
reg = <0x0 0xff320000 0x0 0x1000>;
@@ -611,7 +904,7 @@
reg = <0x0 0xff350000 0x0 0x1000>;
clocks = <&pmucru SCLK_SPI3_PMU>, <&pmucru PCLK_SPI3_PMU>;
clock-names = "spiclk", "apb_pclk";
- interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&spi3_clk &spi3_tx &spi3_rx &spi3_cs0>;
#address-cells = <1>;
@@ -624,7 +917,7 @@
reg = <0x0 0xff370000 0x0 0x100>;
clocks = <&pmucru SCLK_UART4_PMU>, <&pmucru PCLK_UART4_PMU>;
clock-names = "baudclk", "apb_pclk";
- interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH 0>;
reg-shift = <2>;
reg-io-width = <4>;
pinctrl-names = "default";
@@ -639,7 +932,7 @@
assigned-clock-rates = <200000000>;
clocks = <&pmucru SCLK_I2C0_PMU>, <&pmucru PCLK_I2C0_PMU>;
clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c0_xfer>;
#address-cells = <1>;
@@ -654,7 +947,7 @@
assigned-clock-rates = <200000000>;
clocks = <&pmucru SCLK_I2C4_PMU>, <&pmucru PCLK_I2C4_PMU>;
clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c4_xfer>;
#address-cells = <1>;
@@ -669,7 +962,7 @@
assigned-clock-rates = <200000000>;
clocks = <&pmucru SCLK_I2C8_PMU>, <&pmucru PCLK_I2C8_PMU>;
clock-names = "i2c", "pclk";
- interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c8_xfer>;
#address-cells = <1>;
@@ -721,6 +1014,35 @@
status = "disabled";
};
+ efuse0: efuse@ff690000 {
+ compatible = "rockchip,rk3399-efuse";
+ reg = <0x0 0xff690000 0x0 0x80>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cru PCLK_EFUSE1024NS>;
+ clock-names = "pclk_efuse";
+
+ /* Data cells */
+ cpub_leakage: cpu-leakage@17 {
+ reg = <0x17 0x1>;
+ };
+ gpu_leakage: gpu-leakage@18 {
+ reg = <0x18 0x1>;
+ };
+ center_leakage: center-leakage@19 {
+ reg = <0x19 0x1>;
+ };
+ cpul_leakage: cpu-leakage@1a {
+ reg = <0x1a 0x1>;
+ };
+ logic_leakage: logic-leakage@1b {
+ reg = <0x1b 0x1>;
+ };
+ wafer_info: wafer-info@1c {
+ reg = <0x1c 0x1>;
+ };
+ };
+
pmucru: pmu-clock-controller@ff750000 {
compatible = "rockchip,rk3399-pmucru";
reg = <0x0 0xff750000 0x0 0x1000>;
@@ -741,7 +1063,7 @@
<&cru ACLK_PERIHP>, <&cru HCLK_PERIHP>,
<&cru PCLK_PERIHP>,
<&cru ACLK_PERILP0>, <&cru HCLK_PERILP0>,
- <&cru PCLK_PERILP0>,
+ <&cru PCLK_PERILP0>, <&cru ACLK_CCI>,
<&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>;
assigned-clock-rates =
<594000000>, <800000000>,
@@ -749,7 +1071,7 @@
<150000000>, <75000000>,
<37500000>,
<100000000>, <100000000>,
- <50000000>,
+ <50000000>, <600000000>,
<100000000>, <50000000>;
};
@@ -764,6 +1086,40 @@
status = "disabled";
};
+ u2phy0: usb2-phy@e450 {
+ compatible = "rockchip,rk3399-usb2phy";
+ reg = <0xe450 0x10>;
+ clocks = <&cru SCLK_USB2PHY0_REF>;
+ clock-names = "phyclk";
+ #clock-cells = <0>;
+ clock-output-names = "clk_usbphy0_480m";
+ status = "disabled";
+
+ u2phy0_host: host-port {
+ #phy-cells = <0>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "linestate";
+ status = "disabled";
+ };
+ };
+
+ u2phy1: usb2-phy@e460 {
+ compatible = "rockchip,rk3399-usb2phy";
+ reg = <0xe460 0x10>;
+ clocks = <&cru SCLK_USB2PHY1_REF>;
+ clock-names = "phyclk";
+ #clock-cells = <0>;
+ clock-output-names = "clk_usbphy1_480m";
+ status = "disabled";
+
+ u2phy1_host: host-port {
+ #phy-cells = <0>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "linestate";
+ status = "disabled";
+ };
+ };
+
emmc_phy: phy@f780 {
compatible = "rockchip,rk3399-emmc-phy";
reg = <0xf780 0x24>;
@@ -772,19 +1128,85 @@
#phy-cells = <0>;
status = "disabled";
};
+
+ pcie_phy: pcie-phy {
+ compatible = "rockchip,rk3399-pcie-phy";
+ clocks = <&cru SCLK_PCIEPHY_REF>;
+ clock-names = "refclk";
+ #phy-cells = <0>;
+ resets = <&cru SRST_PCIEPHY>;
+ reset-names = "phy";
+ status = "disabled";
+ };
};
- watchdog@ff840000 {
+ tcphy0: phy@ff7c0000 {
+ compatible = "rockchip,rk3399-typec-phy";
+ reg = <0x0 0xff7c0000 0x0 0x40000>;
+ clocks = <&cru SCLK_UPHY0_TCPDCORE>,
+ <&cru SCLK_UPHY0_TCPDPHY_REF>;
+ clock-names = "tcpdcore", "tcpdphy-ref";
+ assigned-clocks = <&cru SCLK_UPHY0_TCPDCORE>;
+ assigned-clock-rates = <50000000>;
+ resets = <&cru SRST_UPHY0>,
+ <&cru SRST_UPHY0_PIPE_L00>,
+ <&cru SRST_P_UPHY0_TCPHY>;
+ reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
+ rockchip,grf = <&grf>;
+ rockchip,typec-conn-dir = <0xe580 0 16>;
+ rockchip,usb3tousb2-en = <0xe580 3 19>;
+ rockchip,external-psm = <0xe588 14 30>;
+ rockchip,pipe-status = <0xe5c0 0 0>;
+ status = "disabled";
+
+ tcphy0_dp: dp-port {
+ #phy-cells = <0>;
+ };
+
+ tcphy0_usb3: usb3-port {
+ #phy-cells = <0>;
+ };
+ };
+
+ tcphy1: phy@ff800000 {
+ compatible = "rockchip,rk3399-typec-phy";
+ reg = <0x0 0xff800000 0x0 0x40000>;
+ clocks = <&cru SCLK_UPHY1_TCPDCORE>,
+ <&cru SCLK_UPHY1_TCPDPHY_REF>;
+ clock-names = "tcpdcore", "tcpdphy-ref";
+ assigned-clocks = <&cru SCLK_UPHY1_TCPDCORE>;
+ assigned-clock-rates = <50000000>;
+ resets = <&cru SRST_UPHY1>,
+ <&cru SRST_UPHY1_PIPE_L00>,
+ <&cru SRST_P_UPHY1_TCPHY>;
+ reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
+ rockchip,grf = <&grf>;
+ rockchip,typec-conn-dir = <0xe58c 0 16>;
+ rockchip,usb3tousb2-en = <0xe58c 3 19>;
+ rockchip,external-psm = <0xe594 14 30>;
+ rockchip,pipe-status = <0xe5c0 16 16>;
+ status = "disabled";
+
+ tcphy1_dp: dp-port {
+ #phy-cells = <0>;
+ };
+
+ tcphy1_usb3: usb3-port {
+ #phy-cells = <0>;
+ };
+ };
+
+ watchdog@ff848000 {
compatible = "snps,dw-wdt";
- reg = <0x0 0xff840000 0x0 0x100>;
+ reg = <0x0 0xff848000 0x0 0x100>;
clocks = <&cru PCLK_WDT>;
- interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH 0>;
};
rktimer: rktimer@ff850000 {
compatible = "rockchip,rk3399-timer";
reg = <0x0 0xff850000 0x0 0x1000>;
- interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cru PCLK_TIMER0>, <&cru SCLK_TIMER00>;
clock-names = "pclk", "timer";
};
@@ -792,7 +1214,7 @@
spdif: spdif@ff870000 {
compatible = "rockchip,rk3399-spdif";
reg = <0x0 0xff870000 0x0 0x1000>;
- interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH 0>;
dmas = <&dmac_bus 7>;
dma-names = "tx";
clock-names = "mclk", "hclk";
@@ -806,7 +1228,7 @@
compatible = "rockchip,rk3399-i2s", "rockchip,rk3066-i2s";
reg = <0x0 0xff880000 0x0 0x1000>;
rockchip,grf = <&grf>;
- interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH 0>;
dmas = <&dmac_bus 0>, <&dmac_bus 1>;
dma-names = "tx", "rx";
clock-names = "i2s_clk", "i2s_hclk";
@@ -819,7 +1241,7 @@
i2s1: i2s@ff890000 {
compatible = "rockchip,rk3399-i2s", "rockchip,rk3066-i2s";
reg = <0x0 0xff890000 0x0 0x1000>;
- interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH 0>;
dmas = <&dmac_bus 2>, <&dmac_bus 3>;
dma-names = "tx", "rx";
clock-names = "i2s_clk", "i2s_hclk";
@@ -832,7 +1254,7 @@
i2s2: i2s@ff8a0000 {
compatible = "rockchip,rk3399-i2s", "rockchip,rk3066-i2s";
reg = <0x0 0xff8a0000 0x0 0x1000>;
- interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH 0>;
dmas = <&dmac_bus 4>, <&dmac_bus 5>;
dma-names = "tx", "rx";
clock-names = "i2s_clk", "i2s_hclk";
@@ -852,7 +1274,7 @@
compatible = "rockchip,gpio-bank";
reg = <0x0 0xff720000 0x0 0x100>;
clocks = <&pmucru PCLK_GPIO0_PMU>;
- interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH 0>;
gpio-controller;
#gpio-cells = <0x2>;
@@ -865,7 +1287,7 @@
compatible = "rockchip,gpio-bank";
reg = <0x0 0xff730000 0x0 0x100>;
clocks = <&pmucru PCLK_GPIO1_PMU>;
- interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH 0>;
gpio-controller;
#gpio-cells = <0x2>;
@@ -878,7 +1300,7 @@
compatible = "rockchip,gpio-bank";
reg = <0x0 0xff780000 0x0 0x100>;
clocks = <&cru PCLK_GPIO2>;
- interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH 0>;
gpio-controller;
#gpio-cells = <0x2>;
@@ -891,7 +1313,7 @@
compatible = "rockchip,gpio-bank";
reg = <0x0 0xff788000 0x0 0x100>;
clocks = <&cru PCLK_GPIO3>;
- interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH 0>;
gpio-controller;
#gpio-cells = <0x2>;
@@ -904,7 +1326,7 @@
compatible = "rockchip,gpio-bank";
reg = <0x0 0xff790000 0x0 0x100>;
clocks = <&cru PCLK_GPIO4>;
- interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH 0>;
gpio-controller;
#gpio-cells = <0x2>;
@@ -955,6 +1377,72 @@
drive-strength = <13>;
};
+ clock {
+ clk_32k: clk-32k {
+ rockchip,pins = <0 0 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ gmac {
+ rgmii_pins: rgmii-pins {
+ rockchip,pins =
+ /* mac_txclk */
+ <3 17 RK_FUNC_1 &pcfg_pull_none_13ma>,
+ /* mac_rxclk */
+ <3 14 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_mdio */
+ <3 13 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txen */
+ <3 12 RK_FUNC_1 &pcfg_pull_none_13ma>,
+ /* mac_clk */
+ <3 11 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxdv */
+ <3 9 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_mdc */
+ <3 8 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxd1 */
+ <3 7 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxd0 */
+ <3 6 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txd1 */
+ <3 5 RK_FUNC_1 &pcfg_pull_none_13ma>,
+ /* mac_txd0 */
+ <3 4 RK_FUNC_1 &pcfg_pull_none_13ma>,
+ /* mac_rxd3 */
+ <3 3 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxd2 */
+ <3 2 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txd3 */
+ <3 1 RK_FUNC_1 &pcfg_pull_none_13ma>,
+ /* mac_txd2 */
+ <3 0 RK_FUNC_1 &pcfg_pull_none_13ma>;
+ };
+
+ rmii_pins: rmii-pins {
+ rockchip,pins =
+ /* mac_mdio */
+ <3 13 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txen */
+ <3 12 RK_FUNC_1 &pcfg_pull_none_13ma>,
+ /* mac_clk */
+ <3 11 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxer */
+ <3 10 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxdv */
+ <3 9 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_mdc */
+ <3 8 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxd1 */
+ <3 7 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_rxd0 */
+ <3 6 RK_FUNC_1 &pcfg_pull_none>,
+ /* mac_txd1 */
+ <3 5 RK_FUNC_1 &pcfg_pull_none_13ma>,
+ /* mac_txd0 */
+ <3 4 RK_FUNC_1 &pcfg_pull_none_13ma>;
+ };
+ };
+
i2c0 {
i2c0_xfer: i2c0-xfer {
rockchip,pins =
@@ -1326,5 +1814,18 @@
<1 14 RK_FUNC_1 &pcfg_pull_none>;
};
};
+
+ pcie {
+ pcie_clkreqn: pci-clkreqn {
+ rockchip,pins =
+ <2 26 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ pcie_clkreqnb: pci-clkreqnb {
+ rockchip,pins =
+ <4 24 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
};
};
diff --git a/arch/arm64/boot/dts/socionext/Makefile b/arch/arm64/boot/dts/socionext/Makefile
index 299b67ec4d44..5538598b302c 100644
--- a/arch/arm64/boot/dts/socionext/Makefile
+++ b/arch/arm64/boot/dts/socionext/Makefile
@@ -1,4 +1,6 @@
-dtb-$(CONFIG_ARCH_UNIPHIER) += uniphier-ph1-ld20-ref.dtb
+dtb-$(CONFIG_ARCH_UNIPHIER) += \
+ uniphier-ld11-ref.dtb \
+ uniphier-ld20-ref.dtb
always := $(dtb-y)
clean-files := *.dtb
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts
new file mode 100644
index 000000000000..7168cf818ad8
--- /dev/null
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts
@@ -0,0 +1,100 @@
+/*
+ * Device Tree Source for UniPhier LD11 Reference Board
+ *
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.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 "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/ "uniphier-ld11.dtsi"
+/include/ "uniphier-ref-daughter.dtsi"
+/include/ "uniphier-support-card.dtsi"
+
+/ {
+ model = "UniPhier LD11 Reference Board";
+ compatible = "socionext,uniphier-ld11-ref", "socionext,uniphier-ld11";
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x80000000 0 0x40000000>;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ serial3 = &serial3;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ };
+};
+
+&ethsc {
+ interrupts = <0 48 4>;
+};
+
+&serial0 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+};
+
+&usb2 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
new file mode 100644
index 000000000000..3eb4c42ce7b9
--- /dev/null
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
@@ -0,0 +1,338 @@
+/*
+ * Device Tree Source for UniPhier LD11 SoC
+ *
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.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 "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.
+ */
+
+/memreserve/ 0x80000000 0x00000008; /* cpu-release-addr */
+
+/ {
+ compatible = "socionext,uniphier-ld11";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+ core1 {
+ cpu = <&cpu1>;
+ };
+ };
+ };
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0 0x000>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0x80000000>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0 0x001>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0 0x80000000>;
+ };
+ };
+
+ clocks {
+ refclk: ref {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <1 13 4>,
+ <1 14 4>,
+ <1 11 4>,
+ <1 10 4>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0 0xffffffff>;
+
+ serial0: serial@54006800 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006800 0x40>;
+ interrupts = <0 33 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ clocks = <&peri_clk 0>;
+ };
+
+ serial1: serial@54006900 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006900 0x40>;
+ interrupts = <0 35 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ clocks = <&peri_clk 1>;
+ };
+
+ serial2: serial@54006a00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006a00 0x40>;
+ interrupts = <0 37 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ clocks = <&peri_clk 2>;
+ };
+
+ serial3: serial@54006b00 {
+ compatible = "socionext,uniphier-uart";
+ status = "disabled";
+ reg = <0x54006b00 0x40>;
+ interrupts = <0 177 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ clocks = <&peri_clk 3>;
+ };
+
+ i2c0: i2c@58780000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58780000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 41 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ clocks = <&peri_clk 4>;
+ clock-frequency = <100000>;
+ };
+
+ i2c1: i2c@58781000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58781000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 42 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ clocks = <&peri_clk 5>;
+ clock-frequency = <100000>;
+ };
+
+ i2c2: i2c@58782000 {
+ compatible = "socionext,uniphier-fi2c";
+ reg = <0x58782000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 43 4>;
+ clocks = <&peri_clk 6>;
+ clock-frequency = <400000>;
+ };
+
+ i2c3: i2c@58783000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58783000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 44 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ clocks = <&peri_clk 7>;
+ clock-frequency = <100000>;
+ };
+
+ i2c4: i2c@58784000 {
+ compatible = "socionext,uniphier-fi2c";
+ status = "disabled";
+ reg = <0x58784000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 45 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ clocks = <&peri_clk 8>;
+ clock-frequency = <100000>;
+ };
+
+ i2c5: i2c@58785000 {
+ compatible = "socionext,uniphier-fi2c";
+ reg = <0x58785000 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 25 4>;
+ clocks = <&peri_clk 9>;
+ clock-frequency = <400000>;
+ };
+
+ system_bus: system-bus@58c00000 {
+ compatible = "socionext,uniphier-system-bus";
+ status = "disabled";
+ reg = <0x58c00000 0x400>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_system_bus>;
+ };
+
+ smpctrl@59800000 {
+ compatible = "socionext,uniphier-smpctrl";
+ reg = <0x59801000 0x400>;
+ };
+
+ perictrl@59820000 {
+ compatible = "socionext,uniphier-perictrl",
+ "simple-mfd", "syscon";
+ reg = <0x59820000 0x200>;
+
+ peri_clk: clock {
+ compatible = "socionext,uniphier-ld11-peri-clock";
+ #clock-cells = <1>;
+ };
+
+ peri_rst: reset {
+ compatible = "socionext,uniphier-ld11-peri-reset";
+ #reset-cells = <1>;
+ };
+ };
+
+ usb0: usb@5a800100 {
+ compatible = "socionext,uniphier-ehci", "generic-ehci";
+ status = "disabled";
+ reg = <0x5a800100 0x100>;
+ interrupts = <0 243 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0>;
+ clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>;
+ resets = <&mio_rst 7>, <&mio_rst 8>, <&mio_rst 12>, <&sys_rst 8>;
+ };
+
+ usb1: usb@5a810100 {
+ compatible = "socionext,uniphier-ehci", "generic-ehci";
+ status = "disabled";
+ reg = <0x5a810100 0x100>;
+ interrupts = <0 244 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1>;
+ clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>;
+ resets = <&mio_rst 7>, <&mio_rst 9>, <&mio_rst 13>, <&sys_rst 8>;
+ };
+
+ usb2: usb@5a820100 {
+ compatible = "socionext,uniphier-ehci", "generic-ehci";
+ status = "disabled";
+ reg = <0x5a820100 0x100>;
+ interrupts = <0 245 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb2>;
+ clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>;
+ resets = <&mio_rst 7>, <&mio_rst 10>, <&mio_rst 14>, <&sys_rst 8>;
+ };
+
+ mioctrl@5b3e0000 {
+ compatible = "socionext,uniphier-mioctrl",
+ "simple-mfd", "syscon";
+ reg = <0x5b3e0000 0x800>;
+
+ mio_clk: clock {
+ compatible = "socionext,uniphier-ld11-mio-clock";
+ #clock-cells = <1>;
+ };
+
+ mio_rst: reset {
+ compatible = "socionext,uniphier-ld11-mio-reset";
+ #reset-cells = <1>;
+ resets = <&sys_rst 7>;
+ };
+ };
+
+ soc-glue@5f800000 {
+ compatible = "socionext,uniphier-soc-glue",
+ "simple-mfd", "syscon";
+ reg = <0x5f800000 0x2000>;
+
+ pinctrl: pinctrl {
+ compatible = "socionext,uniphier-ld11-pinctrl";
+ };
+ };
+
+ gic: interrupt-controller@5fe00000 {
+ compatible = "arm,gic-v3";
+ reg = <0x5fe00000 0x10000>, /* GICD */
+ <0x5fe40000 0x80000>; /* GICR */
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupts = <1 9 4>;
+ };
+
+ sysctrl@61840000 {
+ compatible = "socionext,uniphier-ld11-sysctrl",
+ "simple-mfd", "syscon";
+ reg = <0x61840000 0x4000>;
+
+ sys_clk: clock {
+ compatible = "socionext,uniphier-ld11-clock";
+ #clock-cells = <1>;
+ };
+
+ sys_rst: reset {
+ compatible = "socionext,uniphier-ld11-reset";
+ #reset-cells = <1>;
+ };
+ };
+ };
+};
+
+/include/ "uniphier-pinctrl.dtsi"
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts
index 2adad8c8cd27..609162a1a322 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20-ref.dts
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts
@@ -1,7 +1,8 @@
/*
- * Device Tree Source for UniPhier PH1-LD20 Reference Board
+ * Device Tree Source for UniPhier LD20 Reference Board
*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.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
@@ -43,13 +44,13 @@
*/
/dts-v1/;
-/include/ "uniphier-ph1-ld20.dtsi"
+/include/ "uniphier-ld20.dtsi"
/include/ "uniphier-ref-daughter.dtsi"
/include/ "uniphier-support-card.dtsi"
/ {
- model = "UniPhier PH1-LD20 Reference Board";
- compatible = "socionext,ph1-ld20-ref", "socionext,ph1-ld20";
+ model = "UniPhier LD20 Reference Board";
+ compatible = "socionext,uniphier-ld20-ref", "socionext,uniphier-ld20";
memory {
device_type = "memory";
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
index d73bdc8c9115..08fd7cf7769c 100644
--- a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi
+++ b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
@@ -1,7 +1,8 @@
/*
- * Device Tree Source for UniPhier PH1-LD20 SoC
+ * Device Tree Source for UniPhier LD20 SoC
*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.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
@@ -45,7 +46,7 @@
/memreserve/ 0x80000000 0x00000008; /* cpu-release-addr */
/ {
- compatible = "socionext,ph1-ld20";
+ compatible = "socionext,uniphier-ld20";
#address-cells = <2>;
#size-cells = <2>;
interrupt-parent = <&gic>;
@@ -113,18 +114,6 @@
#clock-cells = <0>;
clock-frequency = <25000000>;
};
-
- uart_clk: uart_clk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <58820000>;
- };
-
- i2c_clk: i2c_clk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <50000000>;
- };
};
timer {
@@ -148,7 +137,7 @@
interrupts = <0 33 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart0>;
- clocks = <&uart_clk>;
+ clocks = <&peri_clk 0>;
};
serial1: serial@54006900 {
@@ -158,7 +147,7 @@
interrupts = <0 35 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
- clocks = <&uart_clk>;
+ clocks = <&peri_clk 1>;
};
serial2: serial@54006a00 {
@@ -168,7 +157,7 @@
interrupts = <0 37 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
- clocks = <&uart_clk>;
+ clocks = <&peri_clk 2>;
};
serial3: serial@54006b00 {
@@ -178,7 +167,7 @@
interrupts = <0 177 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart3>;
- clocks = <&uart_clk>;
+ clocks = <&peri_clk 3>;
};
i2c0: i2c@58780000 {
@@ -190,7 +179,7 @@
interrupts = <0 41 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
- clocks = <&i2c_clk>;
+ clocks = <&peri_clk 4>;
clock-frequency = <100000>;
};
@@ -203,7 +192,7 @@
interrupts = <0 42 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
- clocks = <&i2c_clk>;
+ clocks = <&peri_clk 5>;
clock-frequency = <100000>;
};
@@ -213,7 +202,7 @@
#address-cells = <1>;
#size-cells = <0>;
interrupts = <0 43 4>;
- clocks = <&i2c_clk>;
+ clocks = <&peri_clk 6>;
clock-frequency = <400000>;
};
@@ -226,7 +215,7 @@
interrupts = <0 44 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
- clocks = <&i2c_clk>;
+ clocks = <&peri_clk 7>;
clock-frequency = <100000>;
};
@@ -239,7 +228,7 @@
interrupts = <0 45 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4>;
- clocks = <&i2c_clk>;
+ clocks = <&peri_clk 8>;
clock-frequency = <100000>;
};
@@ -249,7 +238,7 @@
#address-cells = <1>;
#size-cells = <0>;
interrupts = <0 25 4>;
- clocks = <&i2c_clk>;
+ clocks = <&peri_clk 9>;
clock-frequency = <400000>;
};
@@ -259,6 +248,8 @@
reg = <0x58c00000 0x400>;
#address-cells = <2>;
#size-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_system_bus>;
};
smpctrl@59800000 {
@@ -266,12 +257,45 @@
reg = <0x59801000 0x400>;
};
+ mioctrl@59810000 {
+ compatible = "socionext,uniphier-mioctrl",
+ "simple-mfd", "syscon";
+ reg = <0x59810000 0x800>;
+
+ mio_clk: clock {
+ compatible = "socionext,uniphier-ld20-mio-clock";
+ #clock-cells = <1>;
+ };
+
+ mio_rst: reset {
+ compatible = "socionext,uniphier-ld20-mio-reset";
+ #reset-cells = <1>;
+ };
+ };
+
+ perictrl@59820000 {
+ compatible = "socionext,uniphier-perictrl",
+ "simple-mfd", "syscon";
+ reg = <0x59820000 0x200>;
+
+ peri_clk: clock {
+ compatible = "socionext,uniphier-ld20-peri-clock";
+ #clock-cells = <1>;
+ };
+
+ peri_rst: reset {
+ compatible = "socionext,uniphier-ld20-peri-reset";
+ #reset-cells = <1>;
+ };
+ };
+
soc-glue@5f800000 {
- compatible = "simple-mfd", "syscon";
+ compatible = "socionext,uniphier-soc-glue",
+ "simple-mfd", "syscon";
reg = <0x5f800000 0x2000>;
pinctrl: pinctrl {
- compatible = "socionext,uniphier-ld20-pinctrl";
+ compatible = "socionext,uniphier-ld20-pinctrl";
};
};
@@ -283,6 +307,22 @@
#interrupt-cells = <3>;
interrupts = <1 9 4>;
};
+
+ sysctrl@61840000 {
+ compatible = "socionext,uniphier-sysctrl",
+ "simple-mfd", "syscon";
+ reg = <0x61840000 0x4000>;
+
+ sys_clk: clock {
+ compatible = "socionext,uniphier-ld20-clock";
+ #clock-cells = <1>;
+ };
+
+ sys_rst: reset {
+ compatible = "socionext,uniphier-ld20-reset";
+ #reset-cells = <1>;
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts
index acb0527fdc4a..358089687a69 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts
@@ -29,7 +29,7 @@
memory {
device_type = "memory";
- reg = <0x0 0x0 0x40000000>;
+ reg = <0x0 0x0 0x0 0x40000000>;
};
};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index 3e2e51fbd2bc..68a908334c7b 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -14,7 +14,7 @@
/ {
compatible = "xlnx,zynqmp";
#address-cells = <2>;
- #size-cells = <1>;
+ #size-cells = <2>;
cpus {
#address-cells = <1>;
@@ -51,6 +51,7 @@
pmu {
compatible = "arm,armv8-pmuv3";
+ interrupt-parent = <&gic>;
interrupts = <0 143 4>,
<0 144 4>,
<0 145 4>,
@@ -75,15 +76,15 @@
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <1>;
- ranges;
+ ranges = <0 0 0 0 0xffffffff>;
gic: interrupt-controller@f9010000 {
compatible = "arm,gic-400", "arm,cortex-a15-gic";
#interrupt-cells = <3>;
reg = <0x0 0xf9010000 0x10000>,
- <0x0 0xf902f000 0x2000>,
+ <0x0 0xf9020000 0x20000>,
<0x0 0xf9040000 0x20000>,
- <0x0 0xf906f000 0x2000>;
+ <0x0 0xf9060000 0x20000>;
interrupt-controller;
interrupt-parent = <&gic>;
interrupts = <1 9 0xf04>;
@@ -93,14 +94,14 @@
amba: amba {
compatible = "simple-bus";
#address-cells = <2>;
- #size-cells = <1>;
+ #size-cells = <2>;
ranges;
can0: can@ff060000 {
compatible = "xlnx,zynq-can-1.0";
status = "disabled";
clock-names = "can_clk", "pclk";
- reg = <0x0 0xff060000 0x1000>;
+ reg = <0x0 0xff060000 0x0 0x1000>;
interrupts = <0 23 4>;
interrupt-parent = <&gic>;
tx-fifo-depth = <0x40>;
@@ -111,7 +112,7 @@
compatible = "xlnx,zynq-can-1.0";
status = "disabled";
clock-names = "can_clk", "pclk";
- reg = <0x0 0xff070000 0x1000>;
+ reg = <0x0 0xff070000 0x0 0x1000>;
interrupts = <0 24 4>;
interrupt-parent = <&gic>;
tx-fifo-depth = <0x40>;
@@ -123,7 +124,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 57 4>, <0 57 4>;
- reg = <0x0 0xff0b0000 0x1000>;
+ reg = <0x0 0xff0b0000 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk";
#address-cells = <1>;
#size-cells = <0>;
@@ -134,7 +135,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 59 4>, <0 59 4>;
- reg = <0x0 0xff0c0000 0x1000>;
+ reg = <0x0 0xff0c0000 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk";
#address-cells = <1>;
#size-cells = <0>;
@@ -145,7 +146,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 61 4>, <0 61 4>;
- reg = <0x0 0xff0d0000 0x1000>;
+ reg = <0x0 0xff0d0000 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk";
#address-cells = <1>;
#size-cells = <0>;
@@ -156,7 +157,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 63 4>, <0 63 4>;
- reg = <0x0 0xff0e0000 0x1000>;
+ reg = <0x0 0xff0e0000 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk";
#address-cells = <1>;
#size-cells = <0>;
@@ -170,7 +171,7 @@
interrupts = <0 16 4>;
interrupt-controller;
#interrupt-cells = <2>;
- reg = <0x0 0xff0a0000 0x1000>;
+ reg = <0x0 0xff0a0000 0x0 0x1000>;
};
i2c0: i2c@ff020000 {
@@ -178,7 +179,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 17 4>;
- reg = <0x0 0xff020000 0x1000>;
+ reg = <0x0 0xff020000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
};
@@ -188,15 +189,54 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 18 4>;
- reg = <0x0 0xff030000 0x1000>;
+ reg = <0x0 0xff030000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
};
+ pcie: pcie@fd0e0000 {
+ compatible = "xlnx,nwl-pcie-2.11";
+ status = "disabled";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ msi-controller;
+ device_type = "pci";
+ interrupt-parent = <&gic>;
+ interrupts = <0 118 4>,
+ <0 117 4>,
+ <0 116 4>,
+ <0 115 4>, /* MSI_1 [63...32] */
+ <0 114 4>; /* MSI_0 [31...0] */
+ interrupt-names = "misc", "dummy", "intx",
+ "msi1", "msi0";
+ msi-parent = <&pcie>;
+ reg = <0x0 0xfd0e0000 0x0 0x1000>,
+ <0x0 0xfd480000 0x0 0x1000>,
+ <0x80 0x00000000 0x0 0x1000000>;
+ reg-names = "breg", "pcireg", "cfg";
+ ranges = <0x02000000 0x00000000 0xe0000000 0x00000000
+ 0xe0000000 0x00000000 0x10000000
+ /* non-prefetchable memory */
+ 0x43000000 0x00000006 0x00000000 0x00000006
+ 0x00000000 0x00000002 0x00000000>;
+ /* prefetchable memory */
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc 0x1>,
+ <0x0 0x0 0x0 0x2 &pcie_intc 0x2>,
+ <0x0 0x0 0x0 0x3 &pcie_intc 0x3>,
+ <0x0 0x0 0x0 0x4 &pcie_intc 0x4>;
+ pcie_intc: legacy-interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+ };
+
sata: ahci@fd0c0000 {
compatible = "ceva,ahci-1v84";
status = "disabled";
- reg = <0x0 0xfd0c0000 0x2000>;
+ reg = <0x0 0xfd0c0000 0x0 0x2000>;
interrupt-parent = <&gic>;
interrupts = <0 133 4>;
};
@@ -206,7 +246,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 48 4>;
- reg = <0x0 0xff160000 0x1000>;
+ reg = <0x0 0xff160000 0x0 0x1000>;
clock-names = "clk_xin", "clk_ahb";
};
@@ -215,13 +255,13 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 49 4>;
- reg = <0x0 0xff170000 0x1000>;
+ reg = <0x0 0xff170000 0x0 0x1000>;
clock-names = "clk_xin", "clk_ahb";
};
smmu: smmu@fd800000 {
compatible = "arm,mmu-500";
- reg = <0x0 0xfd800000 0x20000>;
+ reg = <0x0 0xfd800000 0x0 0x20000>;
#global-interrupts = <1>;
interrupt-parent = <&gic>;
interrupts = <0 157 4>,
@@ -236,7 +276,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 19 4>;
- reg = <0x0 0xff040000 0x1000>;
+ reg = <0x0 0xff040000 0x0 0x1000>;
clock-names = "ref_clk", "pclk";
#address-cells = <1>;
#size-cells = <0>;
@@ -247,7 +287,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 20 4>;
- reg = <0x0 0xff050000 0x1000>;
+ reg = <0x0 0xff050000 0x0 0x1000>;
clock-names = "ref_clk", "pclk";
#address-cells = <1>;
#size-cells = <0>;
@@ -258,7 +298,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 36 4>, <0 37 4>, <0 38 4>;
- reg = <0x0 0xff110000 0x1000>;
+ reg = <0x0 0xff110000 0x0 0x1000>;
timer-width = <32>;
};
@@ -267,7 +307,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 39 4>, <0 40 4>, <0 41 4>;
- reg = <0x0 0xff120000 0x1000>;
+ reg = <0x0 0xff120000 0x0 0x1000>;
timer-width = <32>;
};
@@ -276,7 +316,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 42 4>, <0 43 4>, <0 44 4>;
- reg = <0x0 0xff130000 0x1000>;
+ reg = <0x0 0xff130000 0x0 0x1000>;
timer-width = <32>;
};
@@ -285,7 +325,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 45 4>, <0 46 4>, <0 47 4>;
- reg = <0x0 0xff140000 0x1000>;
+ reg = <0x0 0xff140000 0x0 0x1000>;
timer-width = <32>;
};
@@ -294,7 +334,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 21 4>;
- reg = <0x0 0xff000000 0x1000>;
+ reg = <0x0 0xff000000 0x0 0x1000>;
clock-names = "uart_clk", "pclk";
};
@@ -303,7 +343,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 22 4>;
- reg = <0x0 0xff010000 0x1000>;
+ reg = <0x0 0xff010000 0x0 0x1000>;
clock-names = "uart_clk", "pclk";
};
@@ -312,7 +352,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 65 4>;
- reg = <0x0 0xfe200000 0x40000>;
+ reg = <0x0 0xfe200000 0x0 0x40000>;
clock-names = "clk_xin", "clk_ahb";
};
@@ -321,7 +361,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 70 4>;
- reg = <0x0 0xfe300000 0x40000>;
+ reg = <0x0 0xfe300000 0x0 0x40000>;
clock-names = "clk_xin", "clk_ahb";
};
@@ -329,8 +369,8 @@
compatible = "cdns,wdt-r1p2";
status = "disabled";
interrupt-parent = <&gic>;
- interrupts = <0 52 1>;
- reg = <0x0 0xfd4d0000 0x1000>;
+ interrupts = <0 113 1>;
+ reg = <0x0 0xfd4d0000 0x0 0x1000>;
timeout-sec = <10>;
};
};
diff --git a/arch/arm64/boot/dts/zte/Makefile b/arch/arm64/boot/dts/zte/Makefile
new file mode 100644
index 000000000000..667806620f59
--- /dev/null
+++ b/arch/arm64/boot/dts/zte/Makefile
@@ -0,0 +1,5 @@
+dtb-$(CONFIG_ARCH_ZX) += zx296718-evb.dtb
+
+always := $(dtb-y)
+subdir-y := $(dts-dirs)
+clean-files := *.dtb
diff --git a/arch/arm64/boot/dts/zte/zx296718-evb.dts b/arch/arm64/boot/dts/zte/zx296718-evb.dts
new file mode 100644
index 000000000000..e164ff6de5fc
--- /dev/null
+++ b/arch/arm64/boot/dts/zte/zx296718-evb.dts
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2016 ZTE Corporation.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * 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 "zx296718.dtsi"
+
+/ {
+ model = "ZTE zx296718 evaluation board";
+ compatible = "zte,zx296718-evb", "zte,zx296718";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x40000000 0x40000000>;
+ };
+
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/zte/zx296718.dtsi b/arch/arm64/boot/dts/zte/zx296718.dtsi
new file mode 100644
index 000000000000..a223066f24ce
--- /dev/null
+++ b/arch/arm64/boot/dts/zte/zx296718.dtsi
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2016 ZTE Corporation.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * 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/input/input.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ compatible = "zte,zx296718";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&gic>;
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+ core1 {
+ cpu = <&cpu1>;
+ };
+ core2 {
+ cpu = <&cpu2>;
+ };
+ core3 {
+ cpu = <&cpu3>;
+ };
+ };
+ };
+
+ 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";
+ };
+ };
+
+ clk24k: clk-24k {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000>;
+ clock-output-names = "rtcclk";
+ };
+
+ osc32k: clk-osc32k {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32000>;
+ clock-output-names = "osc32k";
+ };
+
+ osc12m: clk-osc12m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <12000000>;
+ clock-output-names = "osc12m";
+ };
+
+ osc24m: clk-osc24m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "osc24m";
+ };
+
+ osc25m: clk-osc25m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ clock-output-names = "osc25m";
+ };
+
+ osc60m: clk-osc60m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <60000000>;
+ clock-output-names = "osc60m";
+ };
+
+ osc99m: clk-osc99m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <99000000>;
+ clock-output-names = "osc99m";
+ };
+
+ osc125m: clk-osc125m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <125000000>;
+ clock-output-names = "osc125m";
+ };
+
+ osc198m: clk-osc198m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <198000000>;
+ clock-output-names = "osc198m";
+ };
+
+ pll_audio: clk-pll-884m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <884000000>;
+ clock-output-names = "pll_audio";
+ };
+
+ pll_ddr: clk-pll-932m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <932000000>;
+ clock-output-names = "pll_ddr";
+ };
+
+ pll_hsic: clk-pll-960m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <960000000>;
+ clock-output-names = "pll_hsic";
+ };
+
+ pll_mac: clk-pll-1000m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1000000000>;
+ clock-output-names = "pll_mac";
+ };
+
+ pll_vga: clk-pll-1073m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1073000000>;
+ clock-output-names = "pll_vga";
+ };
+
+ pll_mm0: clk-pll-1188m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1188000000>;
+ clock-output-names = "pll_mm0";
+ };
+
+ pll_mm1: clk-pll-1296m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1296000000>;
+ clock-output-names = "pll_mm1";
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ 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,cortex-a53-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gic: interrupt-controller@2a00000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ #redistributor-regions = <6>;
+ redistributor-stride = <0x0 0x40000>;
+ interrupt-controller;
+ reg = <0x02a00000 0x10000>,
+ <0x02b00000 0x20000>,
+ <0x02b20000 0x20000>,
+ <0x02b40000 0x20000>,
+ <0x02b60000 0x20000>,
+ <0x02b80000 0x20000>,
+ <0x02ba0000 0x20000>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+
+ aon_sysctrl: aon-sysctrl@116000 {
+ compatible = "zte,zx296718-aon-sysctrl", "syscon";
+ reg = <0x116000 0x1000>;
+ };
+
+ uart0: uart@11f000 {
+ compatible = "arm,pl011", "arm,primecell";
+ arm,primecell-periphid = <0x001feffe>;
+ reg = <0x11f000 0x1000>;
+ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc24m>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ dma: dma-controller@1460000 {
+ compatible = "zte,zx296702-dma";
+ reg = <0x01460000 0x1000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc24m>;
+ clock-names = "dmaclk";
+ #dma-cells = <1>;
+ dma-channels = <32>;
+ dma-requests = <32>;
+ };
+
+ sysctrl: sysctrl@1463000 {
+ compatible = "zte,zx296718-sysctrl", "syscon";
+ reg = <0x1463000 0x1000>;
+ };
+ };
+};
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index eadf4855ad2d..dab2cb0c1f1c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -57,10 +57,12 @@ CONFIG_ARCH_UNIPHIER=y
CONFIG_ARCH_VEXPRESS=y
CONFIG_ARCH_VULCAN=y
CONFIG_ARCH_XGENE=y
+CONFIG_ARCH_ZX=y
CONFIG_ARCH_ZYNQMP=y
CONFIG_PCI=y
CONFIG_PCI_MSI=y
CONFIG_PCI_IOV=y
+CONFIG_PCI_AARDVARK=y
CONFIG_PCIE_RCAR=y
CONFIG_PCI_HOST_GENERIC=y
CONFIG_PCI_XGENE=y
@@ -82,6 +84,7 @@ CONFIG_COMPAT=y
CONFIG_CPU_IDLE=y
CONFIG_ARM_CPUIDLE=y
CONFIG_CPU_FREQ=y
+CONFIG_CPUFREQ_DT=y
CONFIG_ARM_BIG_LITTLE_CPUFREQ=y
CONFIG_ARM_SCPI_CPUFREQ=y
CONFIG_NET=y
@@ -120,6 +123,14 @@ CONFIG_VLAN_8021Q=m
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_VLAN_8021Q_MVRP=y
CONFIG_BPF_JIT=y
+CONFIG_BT=m
+CONFIG_BT_HIDP=m
+# CONFIG_BT_HS is not set
+# CONFIG_BT_LE is not set
+CONFIG_BT_LEDS=y
+# CONFIG_BT_DEBUGFS is not set
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_LL=y
CONFIG_CFG80211=m
CONFIG_MAC80211=m
CONFIG_MAC80211_LEDS=y
@@ -139,7 +150,8 @@ CONFIG_VIRTIO_BLK=y
CONFIG_SRAM=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
-# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_SCSI_SAS_ATA=y
+CONFIG_SCSI_HISI_SAS=y
CONFIG_ATA=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y
@@ -160,6 +172,8 @@ CONFIG_VIRTIO_NET=y
CONFIG_AMD_XGBE=y
CONFIG_NET_XGENE=y
CONFIG_MACB=y
+CONFIG_HNS_DSAF=y
+CONFIG_HNS_ENET=y
CONFIG_E1000E=y
CONFIG_IGB=y
CONFIG_IGBVF=y
@@ -186,6 +200,7 @@ CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_GPIO=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PM8941_PWRKEY=y
+CONFIG_INPUT_HISI_POWERKEY=y
# CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_AMBAKMI=y
CONFIG_LEGACY_PTY_COUNT=16
@@ -211,12 +226,12 @@ 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_CHARDEV=y
CONFIG_I2C_MUX=y
CONFIG_I2C_MUX_PCA954x=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_I2C_IMX=y
+CONFIG_I2C_MESON=y
CONFIG_I2C_MV64XXX=y
CONFIG_I2C_QUP=y
CONFIG_I2C_TEGRA=y
@@ -224,6 +239,7 @@ CONFIG_I2C_UNIPHIER_F=y
CONFIG_I2C_RCAR=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_SPI=y
+CONFIG_SPI_MESON_SPIFC=m
CONFIG_SPI_ORION=y
CONFIG_SPI_PL022=y
CONFIG_SPI_QUP=y
@@ -234,6 +250,7 @@ CONFIG_PINCTRL_SINGLE=y
CONFIG_PINCTRL_MAX77620=y
CONFIG_PINCTRL_MSM8916=y
CONFIG_PINCTRL_MSM8996=y
+CONFIG_PINCTRL_QDF2XXX=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_DWAPB=y
@@ -252,10 +269,14 @@ CONFIG_SENSORS_INA2XX=m
CONFIG_SENSORS_ARM_SCPI=y
CONFIG_THERMAL=y
CONFIG_THERMAL_EMULATION=y
+CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
+CONFIG_CPU_THERMAL=y
CONFIG_EXYNOS_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_RENESAS_WDT=y
CONFIG_S3C2410_WATCHDOG=y
+CONFIG_MESON_GXBB_WATCHDOG=m
+CONFIG_MESON_WATCHDOG=m
CONFIG_MFD_MAX77620=y
CONFIG_MFD_SPMI_PMIC=y
CONFIG_MFD_SEC_CORE=y
@@ -264,6 +285,7 @@ CONFIG_REGULATOR=y
CONFIG_MFD_CROS_EC=y
CONFIG_MFD_CROS_EC_I2C=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_HI655X=y
CONFIG_REGULATOR_MAX77620=y
CONFIG_REGULATOR_PWM=y
@@ -274,6 +296,8 @@ CONFIG_DRM=m
CONFIG_DRM_NOUVEAU=m
CONFIG_DRM_TEGRA=m
CONFIG_DRM_PANEL_SIMPLE=m
+CONFIG_DRM_I2C_ADV7511=m
+CONFIG_DRM_HISI_KIRIN=m
CONFIG_FB=y
CONFIG_FB_ARMCLCD=y
CONFIG_BACKLIGHT_GENERIC=m
@@ -291,6 +315,7 @@ CONFIG_SND_SOC_AK4613=y
CONFIG_USB=y
CONFIG_USB_OTG=y
CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PLATFORM=y
CONFIG_USB_XHCI_RCAR=y
CONFIG_USB_EHCI_EXYNOS=y
CONFIG_USB_XHCI_TEGRA=y
@@ -300,6 +325,7 @@ CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_OHCI_EXYNOS=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_RENESAS_USBHS=m
CONFIG_USB_STORAGE=y
CONFIG_USB_DWC2=y
CONFIG_USB_DWC3=y
@@ -311,15 +337,18 @@ CONFIG_USB_HSIC_USB3503=y
CONFIG_USB_MSM_OTG=y
CONFIG_USB_ULPI=y
CONFIG_USB_GADGET=y
+CONFIG_USB_RENESAS_USBHS_UDC=m
CONFIG_MMC=y
CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_ARMMMCI=y
CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ACPI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_OF_ESDHC=y
CONFIG_MMC_SDHCI_TEGRA=y
CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_SPI=y
+CONFIG_MMC_SDHI=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_EXYNOS=y
CONFIG_MMC_DW_K3=y
@@ -345,6 +374,8 @@ CONFIG_DMADEVICES=y
CONFIG_PL330_DMA=y
CONFIG_TEGRA20_APB_DMA=y
CONFIG_QCOM_BAM_DMA=y
+CONFIG_QCOM_HIDMA_MGMT=y
+CONFIG_QCOM_HIDMA=y
CONFIG_RCAR_DMAC=y
CONFIG_VFIO=y
CONFIG_VFIO_PCI=y
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index f43d2c44c765..44e1d7f10add 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -1,4 +1,3 @@
-generic-y += bug.h
generic-y += bugs.h
generic-y += clkdev.h
generic-y += cputime.h
@@ -10,7 +9,6 @@ generic-y += dma-contiguous.h
generic-y += early_ioremap.h
generic-y += emergency-restart.h
generic-y += errno.h
-generic-y += ftrace.h
generic-y += hw_irq.h
generic-y += ioctl.h
generic-y += ioctls.h
@@ -27,12 +25,10 @@ generic-y += mman.h
generic-y += msgbuf.h
generic-y += msi.h
generic-y += mutex.h
-generic-y += pci.h
generic-y += poll.h
generic-y += preempt.h
generic-y += resource.h
generic-y += rwsem.h
-generic-y += sections.h
generic-y += segment.h
generic-y += sembuf.h
generic-y += serial.h
@@ -45,7 +41,6 @@ generic-y += swab.h
generic-y += switch_to.h
generic-y += termbits.h
generic-y += termios.h
-generic-y += topology.h
generic-y += trace_clock.h
generic-y += types.h
generic-y += unaligned.h
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 5420cb0fcb3e..e517088d635f 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -12,7 +12,7 @@
#ifndef _ASM_ACPI_H
#define _ASM_ACPI_H
-#include <linux/mm.h>
+#include <linux/memblock.h>
#include <linux/psci.h>
#include <asm/cputype.h>
@@ -32,7 +32,11 @@
static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
acpi_size size)
{
- if (!page_is_ram(phys >> PAGE_SHIFT))
+ /*
+ * EFI's reserve_regions() call adds memory with the WB attribute
+ * to memblock via early_init_dt_add_memory_arch().
+ */
+ if (!memblock_is_memory(phys))
return ioremap(phys, size);
return ioremap_cache(phys, size);
diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h
index 8746ff6abd77..39feb85a6931 100644
--- a/arch/arm64/include/asm/alternative.h
+++ b/arch/arm64/include/asm/alternative.h
@@ -2,11 +2,11 @@
#define __ASM_ALTERNATIVE_H
#include <asm/cpufeature.h>
+#include <asm/insn.h>
#ifndef __ASSEMBLY__
#include <linux/init.h>
-#include <linux/kconfig.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/stringify.h>
@@ -90,34 +90,55 @@ void apply_alternatives(void *start, size_t length);
.endm
/*
- * Begin an alternative code sequence.
+ * Alternative sequences
+ *
+ * The code for the case where the capability is not present will be
+ * assembled and linked as normal. There are no restrictions on this
+ * code.
+ *
+ * The code for the case where the capability is present will be
+ * assembled into a special section to be used for dynamic patching.
+ * Code for that case must:
+ *
+ * 1. Be exactly the same length (in bytes) as the default code
+ * sequence.
*
- * The code that follows this macro will be assembled and linked as
- * normal. There are no restrictions on this code.
+ * 2. Not contain a branch target that is used outside of the
+ * alternative sequence it is defined in (branches into an
+ * alternative sequence are not fixed up).
+ */
+
+/*
+ * Begin an alternative code sequence.
*/
.macro alternative_if_not cap
+ .set .Lasm_alt_mode, 0
.pushsection .altinstructions, "a"
altinstruction_entry 661f, 663f, \cap, 662f-661f, 664f-663f
.popsection
661:
.endm
+.macro alternative_if cap
+ .set .Lasm_alt_mode, 1
+ .pushsection .altinstructions, "a"
+ altinstruction_entry 663f, 661f, \cap, 664f-663f, 662f-661f
+ .popsection
+ .pushsection .altinstr_replacement, "ax"
+ .align 2 /* So GAS knows label 661 is suitably aligned */
+661:
+.endm
+
/*
- * Provide the alternative code sequence.
- *
- * The code that follows this macro is assembled into a special
- * section to be used for dynamic patching. Code that follows this
- * macro must:
- *
- * 1. Be exactly the same length (in bytes) as the default code
- * sequence.
- *
- * 2. Not contain a branch target that is used outside of the
- * alternative sequence it is defined in (branches into an
- * alternative sequence are not fixed up).
+ * Provide the other half of the alternative code sequence.
*/
.macro alternative_else
-662: .pushsection .altinstr_replacement, "ax"
+662:
+ .if .Lasm_alt_mode==0
+ .pushsection .altinstr_replacement, "ax"
+ .else
+ .popsection
+ .endif
663:
.endm
@@ -125,11 +146,25 @@ void apply_alternatives(void *start, size_t length);
* Complete an alternative code sequence.
*/
.macro alternative_endif
-664: .popsection
+664:
+ .if .Lasm_alt_mode==0
+ .popsection
+ .endif
.org . - (664b-663b) + (662b-661b)
.org . - (662b-661b) + (664b-663b)
.endm
+/*
+ * Provides a trivial alternative or default sequence consisting solely
+ * of NOPs. The number of NOPs is chosen automatically to match the
+ * previous case.
+ */
+.macro alternative_else_nop_endif
+alternative_else
+ nops (662b-661b) / AARCH64_INSN_SIZE
+alternative_endif
+.endm
+
#define _ALTERNATIVE_CFG(insn1, insn2, cap, cfg, ...) \
alternative_insn insn1, insn2, cap, IS_ENABLED(cfg)
diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index 8ec88e5b290f..f8ae6d6e4767 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -28,6 +28,7 @@
#define ICC_CTLR_EL1 sys_reg(3, 0, 12, 12, 4)
#define ICC_SRE_EL1 sys_reg(3, 0, 12, 12, 5)
#define ICC_GRPEN1_EL1 sys_reg(3, 0, 12, 12, 7)
+#define ICC_BPR1_EL1 sys_reg(3, 0, 12, 12, 3)
#define ICC_SRE_EL2 sys_reg(3, 4, 12, 9, 5)
@@ -79,6 +80,19 @@
#include <linux/stringify.h>
#include <asm/barrier.h>
+#define read_gicreg(r) \
+ ({ \
+ u64 reg; \
+ asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg)); \
+ reg; \
+ })
+
+#define write_gicreg(v,r) \
+ do { \
+ u64 __val = (v); \
+ asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
+ } while (0)
+
/*
* Low-level accessors
*
@@ -165,6 +179,11 @@ static inline void gic_write_sre(u32 val)
isb();
}
+static inline void gic_write_bpr1(u32 val)
+{
+ asm volatile("msr_s " __stringify(ICC_BPR1_EL1) ", %0" : : "r" (val));
+}
+
#define gic_read_typer(c) readq_relaxed(c)
#define gic_write_irouter(v, c) writeq_relaxed(v, c)
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index fbe0ca31a99c..eaa5bbe3fa87 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -20,13 +20,55 @@
#define __ASM_ARCH_TIMER_H
#include <asm/barrier.h>
+#include <asm/sysreg.h>
#include <linux/bug.h>
#include <linux/init.h>
+#include <linux/jump_label.h>
#include <linux/types.h>
#include <clocksource/arm_arch_timer.h>
+#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585)
+extern struct static_key_false arch_timer_read_ool_enabled;
+#define needs_fsl_a008585_workaround() \
+ static_branch_unlikely(&arch_timer_read_ool_enabled)
+#else
+#define needs_fsl_a008585_workaround() false
+#endif
+
+u32 __fsl_a008585_read_cntp_tval_el0(void);
+u32 __fsl_a008585_read_cntv_tval_el0(void);
+u64 __fsl_a008585_read_cntvct_el0(void);
+
+/*
+ * The number of retries is an arbitrary value well beyond the highest number
+ * of iterations the loop has been observed to take.
+ */
+#define __fsl_a008585_read_reg(reg) ({ \
+ u64 _old, _new; \
+ int _retries = 200; \
+ \
+ do { \
+ _old = read_sysreg(reg); \
+ _new = read_sysreg(reg); \
+ _retries--; \
+ } while (unlikely(_old != _new) && _retries); \
+ \
+ WARN_ON_ONCE(!_retries); \
+ _new; \
+})
+
+#define arch_timer_reg_read_stable(reg) \
+({ \
+ u64 _val; \
+ if (needs_fsl_a008585_workaround()) \
+ _val = __fsl_a008585_read_##reg(); \
+ else \
+ _val = read_sysreg(reg); \
+ _val; \
+})
+
/*
* These register accessors are marked inline so the compiler can
* nicely work out which register we want, and chuck away the rest of
@@ -38,19 +80,19 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val)
if (access == ARCH_TIMER_PHYS_ACCESS) {
switch (reg) {
case ARCH_TIMER_REG_CTRL:
- asm volatile("msr cntp_ctl_el0, %0" : : "r" (val));
+ write_sysreg(val, cntp_ctl_el0);
break;
case ARCH_TIMER_REG_TVAL:
- asm volatile("msr cntp_tval_el0, %0" : : "r" (val));
+ write_sysreg(val, cntp_tval_el0);
break;
}
} else if (access == ARCH_TIMER_VIRT_ACCESS) {
switch (reg) {
case ARCH_TIMER_REG_CTRL:
- asm volatile("msr cntv_ctl_el0, %0" : : "r" (val));
+ write_sysreg(val, cntv_ctl_el0);
break;
case ARCH_TIMER_REG_TVAL:
- asm volatile("msr cntv_tval_el0, %0" : : "r" (val));
+ write_sysreg(val, cntv_tval_el0);
break;
}
}
@@ -61,48 +103,38 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val)
static __always_inline
u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
{
- u32 val;
-
if (access == ARCH_TIMER_PHYS_ACCESS) {
switch (reg) {
case ARCH_TIMER_REG_CTRL:
- asm volatile("mrs %0, cntp_ctl_el0" : "=r" (val));
- break;
+ return read_sysreg(cntp_ctl_el0);
case ARCH_TIMER_REG_TVAL:
- asm volatile("mrs %0, cntp_tval_el0" : "=r" (val));
- break;
+ return arch_timer_reg_read_stable(cntp_tval_el0);
}
} else if (access == ARCH_TIMER_VIRT_ACCESS) {
switch (reg) {
case ARCH_TIMER_REG_CTRL:
- asm volatile("mrs %0, cntv_ctl_el0" : "=r" (val));
- break;
+ return read_sysreg(cntv_ctl_el0);
case ARCH_TIMER_REG_TVAL:
- asm volatile("mrs %0, cntv_tval_el0" : "=r" (val));
- break;
+ return arch_timer_reg_read_stable(cntv_tval_el0);
}
}
- return val;
+ BUG();
}
static inline u32 arch_timer_get_cntfrq(void)
{
- u32 val;
- asm volatile("mrs %0, cntfrq_el0" : "=r" (val));
- return val;
+ return read_sysreg(cntfrq_el0);
}
static inline u32 arch_timer_get_cntkctl(void)
{
- u32 cntkctl;
- asm volatile("mrs %0, cntkctl_el1" : "=r" (cntkctl));
- return cntkctl;
+ return read_sysreg(cntkctl_el1);
}
static inline void arch_timer_set_cntkctl(u32 cntkctl)
{
- asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl));
+ write_sysreg(cntkctl, cntkctl_el1);
}
static inline u64 arch_counter_get_cntpct(void)
@@ -116,12 +148,8 @@ static inline u64 arch_counter_get_cntpct(void)
static inline u64 arch_counter_get_cntvct(void)
{
- u64 cval;
-
isb();
- asm volatile("mrs %0, cntvct_el0" : "=r" (cval));
-
- return cval;
+ return arch_timer_reg_read_stable(cntvct_el0);
}
static inline int arch_timer_arch_init(void)
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index d5025c69ca81..28bfe6132eb6 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -87,6 +87,15 @@
.endm
/*
+ * NOP sequence
+ */
+ .macro nops, num
+ .rept \num
+ nop
+ .endr
+ .endm
+
+/*
* Emit an entry into the exception table
*/
.macro _asm_extable, from, to
@@ -216,11 +225,26 @@ lr .req x30 // link register
.macro mmid, rd, rn
ldr \rd, [\rn, #MM_CONTEXT_ID]
.endm
+/*
+ * read_ctr - read CTR_EL0. If the system has mismatched
+ * cache line sizes, provide the system wide safe value
+ * from arm64_ftr_reg_ctrel0.sys_val
+ */
+ .macro read_ctr, reg
+alternative_if_not ARM64_MISMATCHED_CACHE_LINE_SIZE
+ mrs \reg, ctr_el0 // read CTR
+ nop
+alternative_else
+ ldr_l \reg, arm64_ftr_reg_ctrel0 + ARM64_FTR_SYSVAL
+alternative_endif
+ .endm
+
/*
- * dcache_line_size - get the minimum D-cache line size from the CTR register.
+ * raw_dcache_line_size - get the minimum D-cache line size on this CPU
+ * from the CTR register.
*/
- .macro dcache_line_size, reg, tmp
+ .macro raw_dcache_line_size, reg, tmp
mrs \tmp, ctr_el0 // read CTR
ubfm \tmp, \tmp, #16, #19 // cache line size encoding
mov \reg, #4 // bytes per word
@@ -228,9 +252,20 @@ lr .req x30 // link register
.endm
/*
- * icache_line_size - get the minimum I-cache line size from the CTR register.
+ * dcache_line_size - get the safe D-cache line size across all CPUs
*/
- .macro icache_line_size, reg, tmp
+ .macro dcache_line_size, reg, tmp
+ read_ctr \tmp
+ ubfm \tmp, \tmp, #16, #19 // cache line size encoding
+ mov \reg, #4 // bytes per word
+ lsl \reg, \reg, \tmp // actual cache line size
+ .endm
+
+/*
+ * raw_icache_line_size - get the minimum I-cache line size on this CPU
+ * from the CTR register.
+ */
+ .macro raw_icache_line_size, reg, tmp
mrs \tmp, ctr_el0 // read CTR
and \tmp, \tmp, #0xf // cache line size encoding
mov \reg, #4 // bytes per word
@@ -238,6 +273,16 @@ lr .req x30 // link register
.endm
/*
+ * icache_line_size - get the safe I-cache line size across all CPUs
+ */
+ .macro icache_line_size, reg, tmp
+ read_ctr \tmp
+ and \tmp, \tmp, #0xf // cache line size encoding
+ mov \reg, #4 // bytes per word
+ lsl \reg, \reg, \tmp // actual cache line size
+ .endm
+
+/*
* tcr_set_idmap_t0sz - update TCR.T0SZ so that we can load the ID map
*/
.macro tcr_set_idmap_t0sz, valreg, tmpreg
diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
index b5890be8f257..7457ce082b5f 100644
--- a/arch/arm64/include/asm/atomic_lse.h
+++ b/arch/arm64/include/asm/atomic_lse.h
@@ -86,8 +86,8 @@ static inline int atomic_add_return##name(int i, atomic_t *v) \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
- " nop\n" \
- __LL_SC_ATOMIC(add_return##name), \
+ __LL_SC_ATOMIC(add_return##name) \
+ __nops(1), \
/* LSE atomics */ \
" ldadd" #mb " %w[i], w30, %[v]\n" \
" add %w[i], %w[i], w30") \
@@ -112,8 +112,8 @@ static inline void atomic_and(int i, atomic_t *v)
asm volatile(ARM64_LSE_ATOMIC_INSN(
/* LL/SC */
- " nop\n"
- __LL_SC_ATOMIC(and),
+ __LL_SC_ATOMIC(and)
+ __nops(1),
/* LSE atomics */
" mvn %w[i], %w[i]\n"
" stclr %w[i], %[v]")
@@ -130,8 +130,8 @@ static inline int atomic_fetch_and##name(int i, atomic_t *v) \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
- " nop\n" \
- __LL_SC_ATOMIC(fetch_and##name), \
+ __LL_SC_ATOMIC(fetch_and##name) \
+ __nops(1), \
/* LSE atomics */ \
" mvn %w[i], %w[i]\n" \
" ldclr" #mb " %w[i], %w[i], %[v]") \
@@ -156,8 +156,8 @@ static inline void atomic_sub(int i, atomic_t *v)
asm volatile(ARM64_LSE_ATOMIC_INSN(
/* LL/SC */
- " nop\n"
- __LL_SC_ATOMIC(sub),
+ __LL_SC_ATOMIC(sub)
+ __nops(1),
/* LSE atomics */
" neg %w[i], %w[i]\n"
" stadd %w[i], %[v]")
@@ -174,9 +174,8 @@ static inline int atomic_sub_return##name(int i, atomic_t *v) \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
- " nop\n" \
__LL_SC_ATOMIC(sub_return##name) \
- " nop", \
+ __nops(2), \
/* LSE atomics */ \
" neg %w[i], %w[i]\n" \
" ldadd" #mb " %w[i], w30, %[v]\n" \
@@ -203,8 +202,8 @@ static inline int atomic_fetch_sub##name(int i, atomic_t *v) \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
- " nop\n" \
- __LL_SC_ATOMIC(fetch_sub##name), \
+ __LL_SC_ATOMIC(fetch_sub##name) \
+ __nops(1), \
/* LSE atomics */ \
" neg %w[i], %w[i]\n" \
" ldadd" #mb " %w[i], %w[i], %[v]") \
@@ -284,8 +283,8 @@ static inline long atomic64_add_return##name(long i, atomic64_t *v) \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
- " nop\n" \
- __LL_SC_ATOMIC64(add_return##name), \
+ __LL_SC_ATOMIC64(add_return##name) \
+ __nops(1), \
/* LSE atomics */ \
" ldadd" #mb " %[i], x30, %[v]\n" \
" add %[i], %[i], x30") \
@@ -310,8 +309,8 @@ static inline void atomic64_and(long i, atomic64_t *v)
asm volatile(ARM64_LSE_ATOMIC_INSN(
/* LL/SC */
- " nop\n"
- __LL_SC_ATOMIC64(and),
+ __LL_SC_ATOMIC64(and)
+ __nops(1),
/* LSE atomics */
" mvn %[i], %[i]\n"
" stclr %[i], %[v]")
@@ -328,8 +327,8 @@ static inline long atomic64_fetch_and##name(long i, atomic64_t *v) \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
- " nop\n" \
- __LL_SC_ATOMIC64(fetch_and##name), \
+ __LL_SC_ATOMIC64(fetch_and##name) \
+ __nops(1), \
/* LSE atomics */ \
" mvn %[i], %[i]\n" \
" ldclr" #mb " %[i], %[i], %[v]") \
@@ -354,8 +353,8 @@ static inline void atomic64_sub(long i, atomic64_t *v)
asm volatile(ARM64_LSE_ATOMIC_INSN(
/* LL/SC */
- " nop\n"
- __LL_SC_ATOMIC64(sub),
+ __LL_SC_ATOMIC64(sub)
+ __nops(1),
/* LSE atomics */
" neg %[i], %[i]\n"
" stadd %[i], %[v]")
@@ -372,9 +371,8 @@ static inline long atomic64_sub_return##name(long i, atomic64_t *v) \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
- " nop\n" \
__LL_SC_ATOMIC64(sub_return##name) \
- " nop", \
+ __nops(2), \
/* LSE atomics */ \
" neg %[i], %[i]\n" \
" ldadd" #mb " %[i], x30, %[v]\n" \
@@ -401,8 +399,8 @@ static inline long atomic64_fetch_sub##name(long i, atomic64_t *v) \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
- " nop\n" \
- __LL_SC_ATOMIC64(fetch_sub##name), \
+ __LL_SC_ATOMIC64(fetch_sub##name) \
+ __nops(1), \
/* LSE atomics */ \
" neg %[i], %[i]\n" \
" ldadd" #mb " %[i], %[i], %[v]") \
@@ -426,13 +424,8 @@ static inline long atomic64_dec_if_positive(atomic64_t *v)
asm volatile(ARM64_LSE_ATOMIC_INSN(
/* LL/SC */
- " nop\n"
__LL_SC_ATOMIC64(dec_if_positive)
- " nop\n"
- " nop\n"
- " nop\n"
- " nop\n"
- " nop",
+ __nops(6),
/* LSE atomics */
"1: ldr x30, %[v]\n"
" subs %[ret], x30, #1\n"
@@ -464,9 +457,8 @@ static inline unsigned long __cmpxchg_case_##name(volatile void *ptr, \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
- " nop\n" \
- __LL_SC_CMPXCHG(name) \
- " nop", \
+ __LL_SC_CMPXCHG(name) \
+ __nops(2), \
/* LSE atomics */ \
" mov " #w "30, %" #w "[old]\n" \
" cas" #mb #sz "\t" #w "30, %" #w "[new], %[v]\n" \
@@ -517,10 +509,8 @@ static inline long __cmpxchg_double##name(unsigned long old1, \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
- " nop\n" \
- " nop\n" \
- " nop\n" \
- __LL_SC_CMPXCHG_DBL(name), \
+ __LL_SC_CMPXCHG_DBL(name) \
+ __nops(3), \
/* LSE atomics */ \
" casp" #mb "\t%[old1], %[old2], %[new1], %[new2], %[v]\n"\
" eor %[old1], %[old1], %[oldval1]\n" \
diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
index 4eea7f618dce..4e0497f581a0 100644
--- a/arch/arm64/include/asm/barrier.h
+++ b/arch/arm64/include/asm/barrier.h
@@ -20,6 +20,9 @@
#ifndef __ASSEMBLY__
+#define __nops(n) ".rept " #n "\nnop\n.endr\n"
+#define nops(n) asm volatile(__nops(n))
+
#define sev() asm volatile("sev" : : : "memory")
#define wfe() asm volatile("wfe" : : : "memory")
#define wfi() asm volatile("wfi" : : : "memory")
diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
index c64268dbff64..2e5fb976a572 100644
--- a/arch/arm64/include/asm/cacheflush.h
+++ b/arch/arm64/include/asm/cacheflush.h
@@ -68,6 +68,7 @@
extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
extern void flush_icache_range(unsigned long start, unsigned long end);
extern void __flush_dcache_area(void *addr, size_t len);
+extern void __clean_dcache_area_poc(void *addr, size_t len);
extern void __clean_dcache_area_pou(void *addr, size_t len);
extern long __flush_cache_user_range(unsigned long start, unsigned long end);
@@ -85,7 +86,7 @@ static inline void flush_cache_page(struct vm_area_struct *vma,
*/
extern void __dma_map_area(const void *, size_t, int);
extern void __dma_unmap_area(const void *, size_t, int);
-extern void __dma_flush_range(const void *, const void *);
+extern void __dma_flush_area(const void *, size_t);
/*
* Copy user data from/to a page which is mapped into a different
diff --git a/arch/arm64/include/asm/clocksource.h b/arch/arm64/include/asm/clocksource.h
new file mode 100644
index 000000000000..0b350a7e26f3
--- /dev/null
+++ b/arch/arm64/include/asm/clocksource.h
@@ -0,0 +1,8 @@
+#ifndef _ASM_CLOCKSOURCE_H
+#define _ASM_CLOCKSOURCE_H
+
+struct arch_clocksource_data {
+ bool vdso_direct; /* Usable for direct VDSO access? */
+};
+
+#endif
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
index bd86a79491bc..91b26d26af8a 100644
--- a/arch/arm64/include/asm/cmpxchg.h
+++ b/arch/arm64/include/asm/cmpxchg.h
@@ -43,10 +43,8 @@ static inline unsigned long __xchg_case_##name(unsigned long x, \
" cbnz %w1, 1b\n" \
" " #mb, \
/* LSE atomics */ \
- " nop\n" \
- " nop\n" \
" swp" #acq_lse #rel #sz "\t%" #w "3, %" #w "0, %2\n" \
- " nop\n" \
+ __nops(3) \
" " #nop_lse) \
: "=&r" (ret), "=&r" (tmp), "+Q" (*(u8 *)ptr) \
: "r" (x) \
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 7099f26e3702..758d74fedfad 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -9,6 +9,8 @@
#ifndef __ASM_CPUFEATURE_H
#define __ASM_CPUFEATURE_H
+#include <linux/jump_label.h>
+
#include <asm/hwcap.h>
#include <asm/sysreg.h>
@@ -37,8 +39,9 @@
#define ARM64_WORKAROUND_CAVIUM_27456 12
#define ARM64_HAS_32BIT_EL0 13
#define ARM64_HYP_OFFSET_LOW 14
+#define ARM64_MISMATCHED_CACHE_LINE_SIZE 15
-#define ARM64_NCAPS 15
+#define ARM64_NCAPS 16
#ifndef __ASSEMBLY__
@@ -63,7 +66,7 @@ struct arm64_ftr_bits {
enum ftr_type type;
u8 shift;
u8 width;
- s64 safe_val; /* safe value for discrete features */
+ s64 safe_val; /* safe value for FTR_EXACT features */
};
/*
@@ -72,13 +75,14 @@ struct arm64_ftr_bits {
* @sys_val Safe value across the CPUs (system view)
*/
struct arm64_ftr_reg {
- u32 sys_id;
- const char *name;
- u64 strict_mask;
- u64 sys_val;
- struct arm64_ftr_bits *ftr_bits;
+ const char *name;
+ u64 strict_mask;
+ u64 sys_val;
+ const struct arm64_ftr_bits *ftr_bits;
};
+extern struct arm64_ftr_reg arm64_ftr_reg_ctrel0;
+
/* scope of capability check */
enum {
SCOPE_SYSTEM,
@@ -109,6 +113,7 @@ struct arm64_cpu_capabilities {
};
extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
+extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
bool this_cpu_has_cap(unsigned int cap);
@@ -121,16 +126,21 @@ static inline bool cpus_have_cap(unsigned int num)
{
if (num >= ARM64_NCAPS)
return false;
- return test_bit(num, cpu_hwcaps);
+ if (__builtin_constant_p(num))
+ return static_branch_unlikely(&cpu_hwcap_keys[num]);
+ else
+ return test_bit(num, cpu_hwcaps);
}
static inline void cpus_set_cap(unsigned int num)
{
- if (num >= ARM64_NCAPS)
+ if (num >= ARM64_NCAPS) {
pr_warn("Attempt to set an illegal CPU capability (%d >= %d)\n",
num, ARM64_NCAPS);
- else
+ } else {
__set_bit(num, cpu_hwcaps);
+ static_branch_enable(&cpu_hwcap_keys[num]);
+ }
}
static inline int __attribute_const__
@@ -157,7 +167,7 @@ cpuid_feature_extract_unsigned_field(u64 features, int field)
return cpuid_feature_extract_unsigned_field_width(features, field, 4);
}
-static inline u64 arm64_ftr_mask(struct arm64_ftr_bits *ftrp)
+static inline u64 arm64_ftr_mask(const struct arm64_ftr_bits *ftrp)
{
return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift);
}
@@ -170,7 +180,7 @@ cpuid_feature_extract_field(u64 features, int field, bool sign)
cpuid_feature_extract_unsigned_field(features, field);
}
-static inline s64 arm64_ftr_value(struct arm64_ftr_bits *ftrp, u64 val)
+static inline s64 arm64_ftr_value(const struct arm64_ftr_bits *ftrp, u64 val)
{
return (s64)cpuid_feature_extract_field(val, ftrp->shift, ftrp->sign);
}
@@ -193,11 +203,11 @@ void __init setup_cpu_features(void);
void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
const char *info);
void enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps);
-void check_local_cpu_errata(void);
-void __init enable_errata_workarounds(void);
+void check_local_cpu_capabilities(void);
-void verify_local_cpu_errata(void);
-void verify_local_cpu_capabilities(void);
+void update_cpu_errata_workarounds(void);
+void __init enable_errata_workarounds(void);
+void verify_local_cpu_errata_workarounds(void);
u64 read_system_reg(u32 id);
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 9d9fd4b9a72e..26a68ddb11c1 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -93,11 +93,7 @@
#include <asm/sysreg.h>
-#define read_cpuid(reg) ({ \
- u64 __val; \
- asm("mrs_s %0, " __stringify(SYS_ ## reg) : "=r" (__val)); \
- __val; \
-})
+#define read_cpuid(reg) read_sysreg_s(SYS_ ## reg)
/*
* The CPU ID never changes at run time, so we might as well tell the
diff --git a/arch/arm64/include/asm/dcc.h b/arch/arm64/include/asm/dcc.h
index 65e0190e97c8..836b05630003 100644
--- a/arch/arm64/include/asm/dcc.h
+++ b/arch/arm64/include/asm/dcc.h
@@ -21,21 +21,16 @@
#define __ASM_DCC_H
#include <asm/barrier.h>
+#include <asm/sysreg.h>
static inline u32 __dcc_getstatus(void)
{
- u32 ret;
-
- asm volatile("mrs %0, mdccsr_el0" : "=r" (ret));
-
- return ret;
+ return read_sysreg(mdccsr_el0);
}
static inline char __dcc_getchar(void)
{
- char c;
-
- asm volatile("mrs %0, dbgdtrrx_el0" : "=r" (c));
+ char c = read_sysreg(dbgdtrrx_el0);
isb();
return c;
@@ -47,8 +42,7 @@ static inline void __dcc_putchar(char c)
* The typecast is to make absolutely certain that 'c' is
* zero-extended.
*/
- asm volatile("msr dbgdtrtx_el0, %0"
- : : "r" ((unsigned long)(unsigned char)c));
+ write_sysreg((unsigned char)c, dbgdtrtx_el0);
isb();
}
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index f772e15c4766..d14c478976d0 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -78,6 +78,23 @@
#define ESR_ELx_IL (UL(1) << 25)
#define ESR_ELx_ISS_MASK (ESR_ELx_IL - 1)
+
+/* ISS field definitions shared by different classes */
+#define ESR_ELx_WNR (UL(1) << 6)
+
+/* Shared ISS field definitions for Data/Instruction aborts */
+#define ESR_ELx_EA (UL(1) << 9)
+#define ESR_ELx_S1PTW (UL(1) << 7)
+
+/* Shared ISS fault status code(IFSC/DFSC) for Data/Instruction aborts */
+#define ESR_ELx_FSC (0x3F)
+#define ESR_ELx_FSC_TYPE (0x3C)
+#define ESR_ELx_FSC_EXTABT (0x10)
+#define ESR_ELx_FSC_ACCESS (0x08)
+#define ESR_ELx_FSC_FAULT (0x04)
+#define ESR_ELx_FSC_PERM (0x0C)
+
+/* ISS field definitions for Data Aborts */
#define ESR_ELx_ISV (UL(1) << 24)
#define ESR_ELx_SAS_SHIFT (22)
#define ESR_ELx_SAS (UL(3) << ESR_ELx_SAS_SHIFT)
@@ -86,16 +103,9 @@
#define ESR_ELx_SRT_MASK (UL(0x1F) << ESR_ELx_SRT_SHIFT)
#define ESR_ELx_SF (UL(1) << 15)
#define ESR_ELx_AR (UL(1) << 14)
-#define ESR_ELx_EA (UL(1) << 9)
#define ESR_ELx_CM (UL(1) << 8)
-#define ESR_ELx_S1PTW (UL(1) << 7)
-#define ESR_ELx_WNR (UL(1) << 6)
-#define ESR_ELx_FSC (0x3F)
-#define ESR_ELx_FSC_TYPE (0x3C)
-#define ESR_ELx_FSC_EXTABT (0x10)
-#define ESR_ELx_FSC_ACCESS (0x08)
-#define ESR_ELx_FSC_FAULT (0x04)
-#define ESR_ELx_FSC_PERM (0x0C)
+
+/* ISS field definitions for exceptions taken in to Hyp */
#define ESR_ELx_CV (UL(1) << 24)
#define ESR_ELx_COND_SHIFT (20)
#define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT)
@@ -109,6 +119,62 @@
((ESR_ELx_EC_BRK64 << ESR_ELx_EC_SHIFT) | ESR_ELx_IL | \
((imm) & 0xffff))
+/* ISS field definitions for System instruction traps */
+#define ESR_ELx_SYS64_ISS_RES0_SHIFT 22
+#define ESR_ELx_SYS64_ISS_RES0_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_RES0_SHIFT)
+#define ESR_ELx_SYS64_ISS_DIR_MASK 0x1
+#define ESR_ELx_SYS64_ISS_DIR_READ 0x1
+#define ESR_ELx_SYS64_ISS_DIR_WRITE 0x0
+
+#define ESR_ELx_SYS64_ISS_RT_SHIFT 5
+#define ESR_ELx_SYS64_ISS_RT_MASK (UL(0x1f) << ESR_ELx_SYS64_ISS_RT_SHIFT)
+#define ESR_ELx_SYS64_ISS_CRM_SHIFT 1
+#define ESR_ELx_SYS64_ISS_CRM_MASK (UL(0xf) << ESR_ELx_SYS64_ISS_CRM_SHIFT)
+#define ESR_ELx_SYS64_ISS_CRN_SHIFT 10
+#define ESR_ELx_SYS64_ISS_CRN_MASK (UL(0xf) << ESR_ELx_SYS64_ISS_CRN_SHIFT)
+#define ESR_ELx_SYS64_ISS_OP1_SHIFT 14
+#define ESR_ELx_SYS64_ISS_OP1_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_OP1_SHIFT)
+#define ESR_ELx_SYS64_ISS_OP2_SHIFT 17
+#define ESR_ELx_SYS64_ISS_OP2_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_OP2_SHIFT)
+#define ESR_ELx_SYS64_ISS_OP0_SHIFT 20
+#define ESR_ELx_SYS64_ISS_OP0_MASK (UL(0x3) << ESR_ELx_SYS64_ISS_OP0_SHIFT)
+#define ESR_ELx_SYS64_ISS_SYS_MASK (ESR_ELx_SYS64_ISS_OP0_MASK | \
+ ESR_ELx_SYS64_ISS_OP1_MASK | \
+ ESR_ELx_SYS64_ISS_OP2_MASK | \
+ ESR_ELx_SYS64_ISS_CRN_MASK | \
+ ESR_ELx_SYS64_ISS_CRM_MASK)
+#define ESR_ELx_SYS64_ISS_SYS_VAL(op0, op1, op2, crn, crm) \
+ (((op0) << ESR_ELx_SYS64_ISS_OP0_SHIFT) | \
+ ((op1) << ESR_ELx_SYS64_ISS_OP1_SHIFT) | \
+ ((op2) << ESR_ELx_SYS64_ISS_OP2_SHIFT) | \
+ ((crn) << ESR_ELx_SYS64_ISS_CRN_SHIFT) | \
+ ((crm) << ESR_ELx_SYS64_ISS_CRM_SHIFT))
+
+#define ESR_ELx_SYS64_ISS_SYS_OP_MASK (ESR_ELx_SYS64_ISS_SYS_MASK | \
+ ESR_ELx_SYS64_ISS_DIR_MASK)
+/*
+ * User space cache operations have the following sysreg encoding
+ * in System instructions.
+ * op0=1, op1=3, op2=1, crn=7, crm={ 5, 10, 11, 14 }, WRITE (L=0)
+ */
+#define ESR_ELx_SYS64_ISS_CRM_DC_CIVAC 14
+#define ESR_ELx_SYS64_ISS_CRM_DC_CVAU 11
+#define ESR_ELx_SYS64_ISS_CRM_DC_CVAC 10
+#define ESR_ELx_SYS64_ISS_CRM_IC_IVAU 5
+
+#define ESR_ELx_SYS64_ISS_EL0_CACHE_OP_MASK (ESR_ELx_SYS64_ISS_OP0_MASK | \
+ ESR_ELx_SYS64_ISS_OP1_MASK | \
+ ESR_ELx_SYS64_ISS_OP2_MASK | \
+ ESR_ELx_SYS64_ISS_CRN_MASK | \
+ ESR_ELx_SYS64_ISS_DIR_MASK)
+#define ESR_ELx_SYS64_ISS_EL0_CACHE_OP_VAL \
+ (ESR_ELx_SYS64_ISS_SYS_VAL(1, 3, 1, 7, 0) | \
+ ESR_ELx_SYS64_ISS_DIR_WRITE)
+
+#define ESR_ELx_SYS64_ISS_SYS_CTR ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 1, 0, 0)
+#define ESR_ELx_SYS64_ISS_SYS_CTR_READ (ESR_ELx_SYS64_ISS_SYS_CTR | \
+ ESR_ELx_SYS64_ISS_DIR_READ)
+
#ifndef __ASSEMBLY__
#include <asm/types.h>
diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h
index 115ea2a64520..9510ace570e2 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/sysreg.h>
#include <asm/virt.h>
#ifdef __KERNEL__
@@ -98,18 +99,18 @@ static inline void decode_ctrl_reg(u32 reg,
#define AARCH64_DBG_REG_WCR (AARCH64_DBG_REG_WVR + ARM_MAX_WRP)
/* Debug register names. */
-#define AARCH64_DBG_REG_NAME_BVR "bvr"
-#define AARCH64_DBG_REG_NAME_BCR "bcr"
-#define AARCH64_DBG_REG_NAME_WVR "wvr"
-#define AARCH64_DBG_REG_NAME_WCR "wcr"
+#define AARCH64_DBG_REG_NAME_BVR bvr
+#define AARCH64_DBG_REG_NAME_BCR bcr
+#define AARCH64_DBG_REG_NAME_WVR wvr
+#define AARCH64_DBG_REG_NAME_WCR wcr
/* Accessor macros for the debug registers. */
#define AARCH64_DBG_READ(N, REG, VAL) do {\
- asm volatile("mrs %0, dbg" REG #N "_el1" : "=r" (VAL));\
+ VAL = read_sysreg(dbg##REG##N##_el1);\
} while (0)
#define AARCH64_DBG_WRITE(N, REG, VAL) do {\
- asm volatile("msr dbg" REG #N "_el1, %0" :: "r" (VAL));\
+ write_sysreg(VAL, dbg##REG##N##_el1);\
} while (0)
struct task_struct;
@@ -141,8 +142,6 @@ static inline void ptrace_hw_copy_thread(struct task_struct *task)
}
#endif
-extern struct pmu perf_ops_bp;
-
/* Determine number of BRP registers available. */
static inline int get_num_brps(void)
{
diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index 1dbaa901d7e5..bc853663dd51 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -246,7 +246,8 @@ static __always_inline bool aarch64_insn_is_##abbr(u32 code) \
static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \
{ return (val); }
-__AARCH64_INSN_FUNCS(adr_adrp, 0x1F000000, 0x10000000)
+__AARCH64_INSN_FUNCS(adr, 0x9F000000, 0x10000000)
+__AARCH64_INSN_FUNCS(adrp, 0x9F000000, 0x90000000)
__AARCH64_INSN_FUNCS(prfm_lit, 0xFF000000, 0xD8000000)
__AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800)
__AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800)
@@ -318,6 +319,11 @@ __AARCH64_INSN_FUNCS(msr_reg, 0xFFF00000, 0xD5100000)
bool aarch64_insn_is_nop(u32 insn);
bool aarch64_insn_is_branch_imm(u32 insn);
+static inline bool aarch64_insn_is_adr_adrp(u32 insn)
+{
+ return aarch64_insn_is_adr(insn) || aarch64_insn_is_adrp(insn);
+}
+
int aarch64_insn_read(void *addr, u32 *insnp);
int aarch64_insn_write(void *addr, u32 insn);
enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn);
@@ -398,6 +404,9 @@ int aarch64_insn_patch_text_nosync(void *addr, u32 insn);
int aarch64_insn_patch_text_sync(void *addrs[], u32 insns[], int cnt);
int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt);
+s32 aarch64_insn_adrp_get_offset(u32 insn);
+u32 aarch64_insn_adrp_set_offset(u32 insn, s32 offset);
+
bool aarch32_insn_is_wide(u32 insn);
#define A32_RN_OFFSET 16
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 9b6e408cfa51..0bba427bb4c2 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -40,25 +40,25 @@
#define __raw_writeb __raw_writeb
static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
{
- asm volatile("strb %w0, [%1]" : : "r" (val), "r" (addr));
+ asm volatile("strb %w0, [%1]" : : "rZ" (val), "r" (addr));
}
#define __raw_writew __raw_writew
static inline void __raw_writew(u16 val, volatile void __iomem *addr)
{
- asm volatile("strh %w0, [%1]" : : "r" (val), "r" (addr));
+ asm volatile("strh %w0, [%1]" : : "rZ" (val), "r" (addr));
}
#define __raw_writel __raw_writel
static inline void __raw_writel(u32 val, volatile void __iomem *addr)
{
- asm volatile("str %w0, [%1]" : : "r" (val), "r" (addr));
+ asm volatile("str %w0, [%1]" : : "rZ" (val), "r" (addr));
}
#define __raw_writeq __raw_writeq
static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
{
- asm volatile("str %0, [%1]" : : "r" (val), "r" (addr));
+ asm volatile("str %x0, [%1]" : : "rZ" (val), "r" (addr));
}
#define __raw_readb __raw_readb
@@ -184,17 +184,6 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
#define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
#define iowrite64be(v,p) ({ __iowmb(); __raw_writeq((__force __u64)cpu_to_be64(v), p); })
-/*
- * Convert a physical pointer to a virtual kernel pointer for /dev/mem
- * access
- */
-#define xlate_dev_mem_ptr(p) __va(p)
-
-/*
- * Convert a virtual cached pointer to an uncached pointer
- */
-#define xlate_dev_kmem_ptr(p) p
-
#include <asm-generic/io.h>
/*
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 4b5c977af465..2a2752b5b6aa 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -50,7 +50,7 @@
#define HCR_BSU (3 << 10)
#define HCR_BSU_IS (UL(1) << 10)
#define HCR_FB (UL(1) << 9)
-#define HCR_VA (UL(1) << 8)
+#define HCR_VSE (UL(1) << 8)
#define HCR_VI (UL(1) << 7)
#define HCR_VF (UL(1) << 6)
#define HCR_AMO (UL(1) << 5)
@@ -80,7 +80,7 @@
#define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \
HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \
HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW)
-#define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF)
+#define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF)
#define HCR_INT_OVERRIDE (HCR_FMO | HCR_IMO)
#define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 7561f63f1c28..18f746551bf6 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -20,10 +20,15 @@
#include <asm/virt.h>
+#define ARM_EXIT_WITH_SERROR_BIT 31
+#define ARM_EXCEPTION_CODE(x) ((x) & ~(1U << ARM_EXIT_WITH_SERROR_BIT))
+#define ARM_SERROR_PENDING(x) !!((x) & (1U << ARM_EXIT_WITH_SERROR_BIT))
+
#define ARM_EXCEPTION_IRQ 0
-#define ARM_EXCEPTION_TRAP 1
+#define ARM_EXCEPTION_EL1_SERROR 1
+#define ARM_EXCEPTION_TRAP 2
/* The hyp-stub will return this for any kvm_call_hyp() call */
-#define ARM_EXCEPTION_HYP_GONE 2
+#define ARM_EXCEPTION_HYP_GONE 3
#define KVM_ARM64_DEBUG_DIRTY_SHIFT 0
#define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT)
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 4cdeae3b17c6..fd9d5fd788f5 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -38,6 +38,7 @@ bool kvm_condition_valid32(const struct kvm_vcpu *vcpu);
void kvm_skip_instr32(struct kvm_vcpu *vcpu, bool is_wide_instr);
void kvm_inject_undefined(struct kvm_vcpu *vcpu);
+void kvm_inject_vabt(struct kvm_vcpu *vcpu);
void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr);
void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
@@ -147,6 +148,16 @@ static inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu)
return vcpu->arch.fault.esr_el2;
}
+static inline int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu)
+{
+ u32 esr = kvm_vcpu_get_hsr(vcpu);
+
+ if (esr & ESR_ELx_CV)
+ return (esr & ESR_ELx_COND_MASK) >> ESR_ELx_COND_SHIFT;
+
+ return -1;
+}
+
static inline unsigned long kvm_vcpu_get_hfar(const struct kvm_vcpu *vcpu)
{
return vcpu->arch.fault.far_el2;
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 3eda975837d0..bd94e6766759 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -290,15 +290,15 @@ struct kvm_vcpu_arch {
#endif
struct kvm_vm_stat {
- u32 remote_tlb_flush;
+ ulong remote_tlb_flush;
};
struct kvm_vcpu_stat {
- u32 halt_successful_poll;
- u32 halt_attempted_poll;
- u32 halt_poll_invalid;
- u32 halt_wakeup;
- u32 hvc_exit_stat;
+ u64 halt_successful_poll;
+ u64 halt_attempted_poll;
+ u64 halt_poll_invalid;
+ u64 halt_wakeup;
+ u64 hvc_exit_stat;
u64 wfe_exit_stat;
u64 wfi_exit_stat;
u64 mmio_exit_user;
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index cff510574fae..b18e852d27e8 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -123,6 +123,7 @@ typeof(orig) * __hyp_text fname(void) \
void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
+int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu);
void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
void __vgic_v3_restore_state(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index b6bb83400cd8..a79b969c26fc 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -99,14 +99,10 @@
.macro kern_hyp_va reg
alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
and \reg, \reg, #HYP_PAGE_OFFSET_HIGH_MASK
-alternative_else
- nop
-alternative_endif
-alternative_if_not ARM64_HYP_OFFSET_LOW
- nop
-alternative_else
+alternative_else_nop_endif
+alternative_if ARM64_HYP_OFFSET_LOW
and \reg, \reg, #HYP_PAGE_OFFSET_LOW_MASK
-alternative_endif
+alternative_else_nop_endif
.endm
#else
@@ -166,12 +162,6 @@ void kvm_clear_hyp_idmap(void);
#define kvm_set_pte(ptep, pte) set_pte(ptep, pte)
#define kvm_set_pmd(pmdp, pmd) set_pmd(pmdp, pmd)
-static inline void kvm_clean_pgd(pgd_t *pgd) {}
-static inline void kvm_clean_pmd(pmd_t *pmd) {}
-static inline void kvm_clean_pmd_entry(pmd_t *pmd) {}
-static inline void kvm_clean_pte(pte_t *pte) {}
-static inline void kvm_clean_pte_entry(pte_t *pte) {}
-
static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
{
pte_val(pte) |= PTE_S2_RDWR;
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 31b73227b41f..ba62df8c6e35 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -214,7 +214,7 @@ static inline void *phys_to_virt(phys_addr_t x)
#ifndef CONFIG_SPARSEMEM_VMEMMAP
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#define _virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
#else
#define __virt_to_pgoff(kaddr) (((u64)(kaddr) & ~PAGE_OFFSET) / PAGE_SIZE * sizeof(struct page))
#define __page_to_voff(kaddr) (((u64)(page) & ~VMEMMAP_START) * PAGE_SIZE / sizeof(struct page))
@@ -222,11 +222,15 @@ static inline void *phys_to_virt(phys_addr_t x)
#define page_to_virt(page) ((void *)((__page_to_voff(page)) | PAGE_OFFSET))
#define virt_to_page(vaddr) ((struct page *)((__virt_to_pgoff(vaddr)) | VMEMMAP_START))
-#define virt_addr_valid(kaddr) pfn_valid((((u64)(kaddr) & ~PAGE_OFFSET) \
+#define _virt_addr_valid(kaddr) pfn_valid((((u64)(kaddr) & ~PAGE_OFFSET) \
+ PHYS_OFFSET) >> PAGE_SHIFT)
#endif
#endif
+#define _virt_addr_is_linear(kaddr) (((u64)(kaddr)) >= PAGE_OFFSET)
+#define virt_addr_valid(kaddr) (_virt_addr_is_linear(kaddr) && \
+ _virt_addr_valid(kaddr))
+
#include <asm-generic/memory_model.h>
#endif
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index b1892a0dbcb0..a50185375f09 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -27,22 +27,17 @@
#include <asm-generic/mm_hooks.h>
#include <asm/cputype.h>
#include <asm/pgtable.h>
+#include <asm/sysreg.h>
#include <asm/tlbflush.h>
-#ifdef CONFIG_PID_IN_CONTEXTIDR
-static inline void contextidr_thread_switch(struct task_struct *next)
-{
- asm(
- " msr contextidr_el1, %0\n"
- " isb"
- :
- : "r" (task_pid_nr(next)));
-}
-#else
static inline void contextidr_thread_switch(struct task_struct *next)
{
+ if (!IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR))
+ return;
+
+ write_sysreg(task_pid_nr(next), contextidr_el1);
+ isb();
}
-#endif
/*
* Set TTBR0 to empty_zero_page. No translations will be possible via TTBR0.
@@ -51,11 +46,8 @@ static inline void cpu_set_reserved_ttbr0(void)
{
unsigned long ttbr = virt_to_phys(empty_zero_page);
- asm(
- " msr ttbr0_el1, %0 // set TTBR0\n"
- " isb"
- :
- : "r" (ttbr));
+ write_sysreg(ttbr, ttbr0_el1);
+ isb();
}
/*
@@ -81,13 +73,11 @@ static inline void __cpu_set_tcr_t0sz(unsigned long t0sz)
if (!__cpu_uses_extended_idmap())
return;
- asm volatile (
- " mrs %0, tcr_el1 ;"
- " bfi %0, %1, %2, %3 ;"
- " msr tcr_el1, %0 ;"
- " isb"
- : "=&r" (tcr)
- : "r"(t0sz), "I"(TCR_T0SZ_OFFSET), "I"(TCR_TxSZ_WIDTH));
+ tcr = read_sysreg(tcr_el1);
+ tcr &= ~TCR_T0SZ_MASK;
+ tcr |= t0sz << TCR_T0SZ_OFFSET;
+ write_sysreg(tcr, tcr_el1);
+ isb();
}
#define cpu_set_default_tcr_t0sz() __cpu_set_tcr_t0sz(TCR_T0SZ(VA_BITS))
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index c3ae239db3ee..eb0c2bd90de9 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -208,6 +208,7 @@
#define TCR_T1SZ(x) ((UL(64) - (x)) << TCR_T1SZ_OFFSET)
#define TCR_TxSZ(x) (TCR_T0SZ(x) | TCR_T1SZ(x))
#define TCR_TxSZ_WIDTH 6
+#define TCR_T0SZ_MASK (((UL(1) << TCR_TxSZ_WIDTH) - 1) << TCR_T0SZ_OFFSET)
#define TCR_IRGN0_SHIFT 8
#define TCR_IRGN0_MASK (UL(3) << TCR_IRGN0_SHIFT)
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 39f5252673f7..2142c7726e76 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -70,12 +70,13 @@
#define PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
#define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
#define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
+#define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN)
#define __P000 PAGE_NONE
#define __P001 PAGE_READONLY
#define __P010 PAGE_COPY
#define __P011 PAGE_COPY
-#define __P100 PAGE_READONLY_EXEC
+#define __P100 PAGE_EXECONLY
#define __P101 PAGE_READONLY_EXEC
#define __P110 PAGE_COPY_EXEC
#define __P111 PAGE_COPY_EXEC
@@ -84,7 +85,7 @@
#define __S001 PAGE_READONLY
#define __S010 PAGE_SHARED
#define __S011 PAGE_SHARED
-#define __S100 PAGE_READONLY_EXEC
+#define __S100 PAGE_EXECONLY
#define __S101 PAGE_READONLY_EXEC
#define __S110 PAGE_SHARED_EXEC
#define __S111 PAGE_SHARED_EXEC
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index e20bd431184a..ffbb9a520563 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -73,7 +73,7 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
#define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE))
#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN))
#define pte_cont(pte) (!!(pte_val(pte) & PTE_CONT))
-#define pte_user(pte) (!!(pte_val(pte) & PTE_USER))
+#define pte_ng(pte) (!!(pte_val(pte) & PTE_NG))
#ifdef CONFIG_ARM64_HW_AFDBM
#define pte_hw_dirty(pte) (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
@@ -84,8 +84,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
#define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte))
#define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID))
-#define pte_valid_not_user(pte) \
- ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID)
+#define pte_valid_global(pte) \
+ ((pte_val(pte) & (PTE_VALID | PTE_NG)) == PTE_VALID)
#define pte_valid_young(pte) \
((pte_val(pte) & (PTE_VALID | PTE_AF)) == (PTE_VALID | PTE_AF))
@@ -155,6 +155,16 @@ static inline pte_t pte_mknoncont(pte_t pte)
return clear_pte_bit(pte, __pgprot(PTE_CONT));
}
+static inline pte_t pte_clear_rdonly(pte_t pte)
+{
+ return clear_pte_bit(pte, __pgprot(PTE_RDONLY));
+}
+
+static inline pte_t pte_mkpresent(pte_t pte)
+{
+ return set_pte_bit(pte, __pgprot(PTE_VALID));
+}
+
static inline pmd_t pmd_mkcont(pmd_t pmd)
{
return __pmd(pmd_val(pmd) | PMD_SECT_CONT);
@@ -168,7 +178,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
* Only if the new pte is valid and kernel, otherwise TLB maintenance
* or update_mmu_cache() have the necessary barriers.
*/
- if (pte_valid_not_user(pte)) {
+ if (pte_valid_global(pte)) {
dsb(ishst);
isb();
}
@@ -202,7 +212,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_val(pte) &= ~PTE_RDONLY;
else
pte_val(pte) |= PTE_RDONLY;
- if (pte_user(pte) && pte_exec(pte) && !pte_special(pte))
+ if (pte_ng(pte) && pte_exec(pte) && !pte_special(pte))
__sync_icache_dcache(pte, addr);
}
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index ace0a96e7d6e..df2e53d3a969 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -37,7 +37,6 @@
#include <asm/ptrace.h>
#include <asm/types.h>
-#ifdef __KERNEL__
#define STACK_TOP_MAX TASK_SIZE_64
#ifdef CONFIG_COMPAT
#define AARCH32_VECTORS_BASE 0xffff0000
@@ -49,7 +48,6 @@
extern phys_addr_t arm64_dma_phys_limit;
#define ARCH_LOW_ADDRESS_LIMIT (arm64_dma_phys_limit - 1)
-#endif /* __KERNEL__ */
struct debug_info {
/* Have we suspended stepping by a debugger? */
diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h
new file mode 100644
index 000000000000..4e7e7067afdb
--- /dev/null
+++ b/arch/arm64/include/asm/sections.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 ARM Limited
+ *
+ * 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_SECTIONS_H
+#define __ASM_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+extern char __alt_instructions[], __alt_instructions_end[];
+extern char __exception_text_start[], __exception_text_end[];
+extern char __hibernate_exit_text_start[], __hibernate_exit_text_end[];
+extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[];
+extern char __hyp_text_start[], __hyp_text_end[];
+extern char __idmap_text_start[], __idmap_text_end[];
+extern char __irqentry_text_start[], __irqentry_text_end[];
+extern char __mmuoff_data_start[], __mmuoff_data_end[];
+
+#endif /* __ASM_SECTIONS_H */
diff --git a/arch/arm64/include/asm/spinlock.h b/arch/arm64/include/asm/spinlock.h
index 89206b568cd4..cae331d553f8 100644
--- a/arch/arm64/include/asm/spinlock.h
+++ b/arch/arm64/include/asm/spinlock.h
@@ -66,8 +66,7 @@ static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
ARM64_LSE_ATOMIC_INSN(
/* LL/SC */
" stxr %w1, %w0, %2\n"
-" nop\n"
-" nop\n",
+ __nops(2),
/* LSE atomics */
" mov %w1, %w0\n"
" cas %w0, %w0, %2\n"
@@ -99,9 +98,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
/* LSE atomics */
" mov %w2, %w5\n"
" ldadda %w2, %w0, %3\n"
-" nop\n"
-" nop\n"
-" nop\n"
+ __nops(3)
)
/* Did we get the lock? */
@@ -165,8 +162,8 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
" stlrh %w1, %0",
/* LSE atomics */
" mov %w1, #1\n"
- " nop\n"
- " staddlh %w1, %0")
+ " staddlh %w1, %0\n"
+ __nops(1))
: "=Q" (lock->owner), "=&r" (tmp)
:
: "memory");
@@ -212,7 +209,7 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
" cbnz %w0, 1b\n"
" stxr %w0, %w2, %1\n"
" cbnz %w0, 2b\n"
- " nop",
+ __nops(1),
/* LSE atomics */
"1: mov %w0, wzr\n"
"2: casa %w0, %w2, %1\n"
@@ -241,8 +238,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
/* LSE atomics */
" mov %w0, wzr\n"
" casa %w0, %w2, %1\n"
- " nop\n"
- " nop")
+ __nops(2))
: "=&r" (tmp), "+Q" (rw->lock)
: "r" (0x80000000)
: "memory");
@@ -290,8 +286,8 @@ static inline void arch_read_lock(arch_rwlock_t *rw)
" add %w0, %w0, #1\n"
" tbnz %w0, #31, 1b\n"
" stxr %w1, %w0, %2\n"
- " nop\n"
- " cbnz %w1, 2b",
+ " cbnz %w1, 2b\n"
+ __nops(1),
/* LSE atomics */
"1: wfe\n"
"2: ldxr %w0, %2\n"
@@ -317,9 +313,8 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
" cbnz %w1, 1b",
/* LSE atomics */
" movn %w0, #0\n"
- " nop\n"
- " nop\n"
- " staddl %w0, %2")
+ " staddl %w0, %2\n"
+ __nops(2))
: "=&r" (tmp), "=&r" (tmp2), "+Q" (rw->lock)
:
: "memory");
@@ -344,7 +339,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
" tbnz %w1, #31, 1f\n"
" casa %w0, %w1, %2\n"
" sbc %w1, %w1, %w0\n"
- " nop\n"
+ __nops(1)
"1:")
: "=&r" (tmp), "=&r" (tmp2), "+Q" (rw->lock)
:
diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
index 024d623f662e..b8a313fd7a09 100644
--- a/arch/arm64/include/asm/suspend.h
+++ b/arch/arm64/include/asm/suspend.h
@@ -47,4 +47,7 @@ int swsusp_arch_resume(void);
int arch_hibernation_header_save(void *addr, unsigned int max_size);
int arch_hibernation_header_restore(void *addr);
+/* Used to resume on the CPU we hibernated on */
+int hibernate_resume_nonboot_cpu_disable(void);
+
#endif
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index cc06794b7346..e8d46e8e6079 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -100,6 +100,7 @@
/* SCTLR_EL1 specific flags. */
#define SCTLR_EL1_UCI (1 << 26)
#define SCTLR_EL1_SPAN (1 << 23)
+#define SCTLR_EL1_UCT (1 << 15)
#define SCTLR_EL1_SED (1 << 8)
#define SCTLR_EL1_CP15BEN (1 << 5)
@@ -253,16 +254,6 @@ asm(
" .endm\n"
);
-static inline void config_sctlr_el1(u32 clear, u32 set)
-{
- u32 val;
-
- asm volatile("mrs %0, sctlr_el1" : "=r" (val));
- val &= ~clear;
- val |= set;
- asm volatile("msr sctlr_el1, %0" : : "r" (val));
-}
-
/*
* Unlike read_cpuid, calls to read_sysreg are never expected to be
* optimized away or replaced with synthetic values.
@@ -273,12 +264,41 @@ static inline void config_sctlr_el1(u32 clear, u32 set)
__val; \
})
+/*
+ * The "Z" constraint normally means a zero immediate, but when combined with
+ * the "%x0" template means XZR.
+ */
#define write_sysreg(v, r) do { \
u64 __val = (u64)v; \
- asm volatile("msr " __stringify(r) ", %0" \
- : : "r" (__val)); \
+ asm volatile("msr " __stringify(r) ", %x0" \
+ : : "rZ" (__val)); \
+} while (0)
+
+/*
+ * For registers without architectural names, or simply unsupported by
+ * GAS.
+ */
+#define read_sysreg_s(r) ({ \
+ u64 __val; \
+ asm volatile("mrs_s %0, " __stringify(r) : "=r" (__val)); \
+ __val; \
+})
+
+#define write_sysreg_s(v, r) do { \
+ u64 __val = (u64)v; \
+ asm volatile("msr_s " __stringify(r) ", %0" : : "rZ" (__val)); \
} while (0)
+static inline void config_sctlr_el1(u32 clear, u32 set)
+{
+ u32 val;
+
+ val = read_sysreg(sctlr_el1);
+ val &= ~clear;
+ val |= set;
+ write_sysreg(val, sctlr_el1);
+}
+
#endif
#endif /* __ASM_SYSREG_H */
diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
index 57f110bea6a8..bc812435bc76 100644
--- a/arch/arm64/include/asm/system_misc.h
+++ b/arch/arm64/include/asm/system_misc.h
@@ -56,12 +56,6 @@ extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
__show_ratelimited; \
})
-#define UDBG_UNDEFINED (1 << 0)
-#define UDBG_SYSCALL (1 << 1)
-#define UDBG_BADABORT (1 << 2)
-#define UDBG_SEGV (1 << 3)
-#define UDBG_BUS (1 << 4)
-
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SYSTEM_MISC_H */
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index abd64bd1f6d9..e9ea5a6bd449 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -75,6 +75,9 @@ static inline struct thread_info *current_thread_info(void) __attribute_const__;
/*
* struct thread_info can be accessed directly via sp_el0.
+ *
+ * We don't use read_sysreg() as we want the compiler to cache the value where
+ * possible.
*/
static inline struct thread_info *current_thread_info(void)
{
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index b460ae28e346..deab52374119 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -25,6 +25,24 @@
#include <asm/cputype.h>
/*
+ * Raw TLBI operations.
+ *
+ * Where necessary, use the __tlbi() macro to avoid asm()
+ * boilerplate. Drivers and most kernel code should use the TLB
+ * management routines in preference to the macro below.
+ *
+ * The macro can be used as __tlbi(op) or __tlbi(op, arg), depending
+ * on whether a particular TLBI operation takes an argument or
+ * not. The macros handles invoking the asm with or without the
+ * register argument as appropriate.
+ */
+#define __TLBI_0(op, arg) asm ("tlbi " #op)
+#define __TLBI_1(op, arg) asm ("tlbi " #op ", %0" : : "r" (arg))
+#define __TLBI_N(op, arg, n, ...) __TLBI_##n(op, arg)
+
+#define __tlbi(op, ...) __TLBI_N(op, ##__VA_ARGS__, 1, 0)
+
+/*
* TLB Management
* ==============
*
@@ -66,7 +84,7 @@
static inline void local_flush_tlb_all(void)
{
dsb(nshst);
- asm("tlbi vmalle1");
+ __tlbi(vmalle1);
dsb(nsh);
isb();
}
@@ -74,7 +92,7 @@ static inline void local_flush_tlb_all(void)
static inline void flush_tlb_all(void)
{
dsb(ishst);
- asm("tlbi vmalle1is");
+ __tlbi(vmalle1is);
dsb(ish);
isb();
}
@@ -84,7 +102,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
unsigned long asid = ASID(mm) << 48;
dsb(ishst);
- asm("tlbi aside1is, %0" : : "r" (asid));
+ __tlbi(aside1is, asid);
dsb(ish);
}
@@ -94,7 +112,7 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long addr = uaddr >> 12 | (ASID(vma->vm_mm) << 48);
dsb(ishst);
- asm("tlbi vale1is, %0" : : "r" (addr));
+ __tlbi(vale1is, addr);
dsb(ish);
}
@@ -122,9 +140,9 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
dsb(ishst);
for (addr = start; addr < end; addr += 1 << (PAGE_SHIFT - 12)) {
if (last_level)
- asm("tlbi vale1is, %0" : : "r"(addr));
+ __tlbi(vale1is, addr);
else
- asm("tlbi vae1is, %0" : : "r"(addr));
+ __tlbi(vae1is, addr);
}
dsb(ish);
}
@@ -149,7 +167,7 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
dsb(ishst);
for (addr = start; addr < end; addr += 1 << (PAGE_SHIFT - 12))
- asm("tlbi vaae1is, %0" : : "r"(addr));
+ __tlbi(vaae1is, addr);
dsb(ish);
isb();
}
@@ -163,7 +181,7 @@ static inline void __flush_tlb_pgtable(struct mm_struct *mm,
{
unsigned long addr = uaddr >> 12 | (ASID(mm) << 48);
- asm("tlbi vae1is, %0" : : "r" (addr));
+ __tlbi(vae1is, addr);
dsb(ish);
}
diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h
index 9cd03f3e812f..02e9035b0685 100644
--- a/arch/arm64/include/asm/traps.h
+++ b/arch/arm64/include/asm/traps.h
@@ -19,6 +19,7 @@
#define __ASM_TRAP_H
#include <linux/list.h>
+#include <asm/sections.h>
struct pt_regs;
@@ -39,9 +40,6 @@ void arm64_notify_segfault(struct pt_regs *regs, unsigned long addr);
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
static inline int __in_irqentry_text(unsigned long ptr)
{
- extern char __irqentry_text_start[];
- extern char __irqentry_text_end[];
-
return ptr >= (unsigned long)&__irqentry_text_start &&
ptr < (unsigned long)&__irqentry_text_end;
}
@@ -54,8 +52,6 @@ static inline int __in_irqentry_text(unsigned long ptr)
static inline int in_exception_text(unsigned long ptr)
{
- extern char __exception_text_start[];
- extern char __exception_text_end[];
int in;
in = ptr >= (unsigned long)&__exception_text_start &&
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index 1788545f25bc..fea10736b11f 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -45,6 +45,8 @@
#ifndef __ASSEMBLY__
#include <asm/ptrace.h>
+#include <asm/sections.h>
+#include <asm/sysreg.h>
/*
* __boot_cpu_mode records what mode CPUs were booted in.
@@ -75,10 +77,7 @@ static inline bool is_hyp_mode_mismatched(void)
static inline bool is_kernel_in_hyp_mode(void)
{
- u64 el;
-
- asm("mrs %0, CurrentEL" : "=r" (el));
- return el == CurrentEL_EL2;
+ return read_sysreg(CurrentEL) == CurrentEL_EL2;
}
#ifdef CONFIG_ARM64_VHE
@@ -87,14 +86,6 @@ extern void verify_cpu_run_el(void);
static inline void verify_cpu_run_el(void) {}
#endif
-/* The section containing the hypervisor idmap text */
-extern char __hyp_idmap_text_start[];
-extern char __hyp_idmap_text_end[];
-
-/* The section containing the hypervisor text */
-extern char __hyp_text_start[];
-extern char __hyp_text_end[];
-
#endif /* __ASSEMBLY__ */
#endif /* ! __ASM__VIRT_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 14f7b651c787..7d66bbaafc0c 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -10,6 +10,8 @@ CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_insn.o = -pg
CFLAGS_REMOVE_return_address.o = -pg
+CFLAGS_setup.o = -DUTS_MACHINE='"$(UTS_MACHINE)"'
+
# Object file lists.
arm64-obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
entry-fpsimd.o process.o ptrace.o setup.o signal.o \
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 3e4f1a45b125..252a6d9c1da5 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -24,6 +24,7 @@
#include <linux/memblock.h>
#include <linux/of_fdt.h>
#include <linux/smp.h>
+#include <linux/serial_core.h>
#include <asm/cputype.h>
#include <asm/cpu_ops.h>
@@ -206,7 +207,7 @@ void __init acpi_boot_table_init(void)
if (param_acpi_off ||
(!param_acpi_on && !param_acpi_force &&
of_scan_flat_dt(dt_scan_depth1_nodes, NULL)))
- return;
+ goto done;
/*
* ACPI is disabled at this point. Enable it in order to parse
@@ -226,6 +227,14 @@ void __init acpi_boot_table_init(void)
if (!param_acpi_force)
disable_acpi();
}
+
+done:
+ if (acpi_disabled) {
+ if (earlycon_init_is_deferred)
+ early_init_dt_scan_chosen_stdout();
+ } else {
+ parse_spcr(earlycon_init_is_deferred);
+ }
}
#ifdef CONFIG_ACPI_APEI
diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c
index f85149cc7c71..f01fab637dab 100644
--- a/arch/arm64/kernel/acpi_numa.c
+++ b/arch/arm64/kernel/acpi_numa.c
@@ -105,8 +105,10 @@ int __init arm64_acpi_numa_init(void)
int ret;
ret = acpi_numa_init();
- if (ret)
+ if (ret) {
+ pr_info("Failed to initialise from firmware\n");
return ret;
+ }
return srat_disabled() ? -EINVAL : 0;
}
diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c
index d2ee1b21a10d..06d650f61da7 100644
--- a/arch/arm64/kernel/alternative.c
+++ b/arch/arm64/kernel/alternative.c
@@ -25,14 +25,13 @@
#include <asm/alternative.h>
#include <asm/cpufeature.h>
#include <asm/insn.h>
+#include <asm/sections.h>
#include <linux/stop_machine.h>
#define __ALT_PTR(a,f) (u32 *)((void *)&(a)->f + (a)->f)
#define ALT_ORIG_PTR(a) __ALT_PTR(a, orig_offset)
#define ALT_REPL_PTR(a) __ALT_PTR(a, alt_offset)
-extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
-
struct alt_region {
struct alt_instr *begin;
struct alt_instr *end;
@@ -59,6 +58,8 @@ static bool branch_insn_requires_update(struct alt_instr *alt, unsigned long pc)
BUG();
}
+#define align_down(x, a) ((unsigned long)(x) & ~(((unsigned long)(a)) - 1))
+
static u32 get_alt_insn(struct alt_instr *alt, u32 *insnptr, u32 *altinsnptr)
{
u32 insn;
@@ -80,6 +81,25 @@ static u32 get_alt_insn(struct alt_instr *alt, u32 *insnptr, u32 *altinsnptr)
offset = target - (unsigned long)insnptr;
insn = aarch64_set_branch_offset(insn, offset);
}
+ } else if (aarch64_insn_is_adrp(insn)) {
+ s32 orig_offset, new_offset;
+ unsigned long target;
+
+ /*
+ * If we're replacing an adrp instruction, which uses PC-relative
+ * immediate addressing, adjust the offset to reflect the new
+ * PC. adrp operates on 4K aligned addresses.
+ */
+ orig_offset = aarch64_insn_adrp_get_offset(insn);
+ target = align_down(altinsnptr, SZ_4K) + orig_offset;
+ new_offset = target - align_down(insnptr, SZ_4K);
+ insn = aarch64_insn_adrp_set_offset(insn, new_offset);
+ } else if (aarch64_insn_uses_literal(insn)) {
+ /*
+ * Disallow patching unhandled instructions using PC relative
+ * literal addresses
+ */
+ BUG();
}
return insn;
@@ -124,8 +144,8 @@ static int __apply_alternatives_multi_stop(void *unused)
{
static int patched = 0;
struct alt_region region = {
- .begin = __alt_instructions,
- .end = __alt_instructions_end,
+ .begin = (struct alt_instr *)__alt_instructions,
+ .end = (struct alt_instr *)__alt_instructions_end,
};
/* We always have a CPU 0 at this point (__init) */
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 05070b72fc28..4a2f0f0fef32 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -23,6 +23,7 @@
#include <linux/dma-mapping.h>
#include <linux/kvm_host.h>
#include <linux/suspend.h>
+#include <asm/cpufeature.h>
#include <asm/thread_info.h>
#include <asm/memory.h>
#include <asm/smp_plat.h>
@@ -145,5 +146,6 @@ int main(void)
DEFINE(HIBERN_PBE_ORIG, offsetof(struct pbe, orig_address));
DEFINE(HIBERN_PBE_ADDR, offsetof(struct pbe, address));
DEFINE(HIBERN_PBE_NEXT, offsetof(struct pbe, next));
+ DEFINE(ARM64_FTR_SYSVAL, offsetof(struct arm64_ftr_reg, sys_val));
return 0;
}
diff --git a/arch/arm64/kernel/cacheinfo.c b/arch/arm64/kernel/cacheinfo.c
index b8629d52fba9..9617301f76b5 100644
--- a/arch/arm64/kernel/cacheinfo.c
+++ b/arch/arm64/kernel/cacheinfo.c
@@ -39,7 +39,7 @@ static inline enum cache_type get_cache_type(int level)
if (level > MAX_CACHE_LEVEL)
return CACHE_TYPE_NOCACHE;
- asm volatile ("mrs %x0, clidr_el1" : "=r" (clidr));
+ clidr = read_sysreg(clidr_el1);
return CLIDR_CTYPE(clidr, level);
}
@@ -55,11 +55,9 @@ u64 __attribute_const__ cache_get_ccsidr(u64 csselr)
WARN_ON(preemptible());
- /* Put value into CSSELR */
- asm volatile("msr csselr_el1, %x0" : : "r" (csselr));
+ write_sysreg(csselr, csselr_el1);
isb();
- /* Read result out of CCSIDR */
- asm volatile("mrs %x0, ccsidr_el1" : "=r" (ccsidr));
+ ccsidr = read_sysreg(ccsidr_el1);
return ccsidr;
}
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 82b0fc2e637b..0150394f4cab 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -30,6 +30,21 @@ is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
entry->midr_range_max);
}
+static bool
+has_mismatched_cache_line_size(const struct arm64_cpu_capabilities *entry,
+ int scope)
+{
+ WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
+ return (read_cpuid_cachetype() & arm64_ftr_reg_ctrel0.strict_mask) !=
+ (arm64_ftr_reg_ctrel0.sys_val & arm64_ftr_reg_ctrel0.strict_mask);
+}
+
+static void cpu_enable_trap_ctr_access(void *__unused)
+{
+ /* Clear SCTLR_EL1.UCT */
+ config_sctlr_el1(SCTLR_EL1_UCT, 0);
+}
+
#define MIDR_RANGE(model, min, max) \
.def_scope = SCOPE_LOCAL_CPU, \
.matches = is_affected_midr_range, \
@@ -108,6 +123,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
},
#endif
{
+ .desc = "Mismatched cache line size",
+ .capability = ARM64_MISMATCHED_CACHE_LINE_SIZE,
+ .matches = has_mismatched_cache_line_size,
+ .def_scope = SCOPE_LOCAL_CPU,
+ .enable = cpu_enable_trap_ctr_access,
+ },
+ {
}
};
@@ -116,7 +138,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
* and the related information is freed soon after. If the new CPU requires
* an errata not detected at boot, fail this CPU.
*/
-void verify_local_cpu_errata(void)
+void verify_local_cpu_errata_workarounds(void)
{
const struct arm64_cpu_capabilities *caps = arm64_errata;
@@ -131,7 +153,7 @@ void verify_local_cpu_errata(void)
}
}
-void check_local_cpu_errata(void)
+void update_cpu_errata_workarounds(void)
{
update_cpu_capabilities(arm64_errata, "enabling workaround for");
}
diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
index c7cfb8fe06f9..e137ceaf5016 100644
--- a/arch/arm64/kernel/cpu_ops.c
+++ b/arch/arm64/kernel/cpu_ops.c
@@ -17,6 +17,7 @@
*/
#include <linux/acpi.h>
+#include <linux/cache.h>
#include <linux/errno.h>
#include <linux/of.h>
#include <linux/string.h>
@@ -28,7 +29,7 @@ extern const struct cpu_operations smp_spin_table_ops;
extern const struct cpu_operations acpi_parking_protocol_ops;
extern const struct cpu_operations cpu_psci_ops;
-const struct cpu_operations *cpu_ops[NR_CPUS];
+const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init;
static const struct cpu_operations *dt_supported_cpu_ops[] __initconst = {
&smp_spin_table_ops,
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 62272eac1352..d577f263cc4a 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -46,6 +46,9 @@ unsigned int compat_elf_hwcap2 __read_mostly;
DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
+DEFINE_STATIC_KEY_ARRAY_FALSE(cpu_hwcap_keys, ARM64_NCAPS);
+EXPORT_SYMBOL(cpu_hwcap_keys);
+
#define __ARM64_FTR_BITS(SIGNED, STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
{ \
.sign = SIGNED, \
@@ -74,7 +77,7 @@ static bool __maybe_unused
cpufeature_pan_not_uao(const struct arm64_cpu_capabilities *entry, int __unused);
-static struct arm64_ftr_bits ftr_id_aa64isar0[] = {
+static const struct arm64_ftr_bits ftr_id_aa64isar0[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 32, 32, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64ISAR0_RDM_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 24, 4, 0),
@@ -87,7 +90,7 @@ static struct arm64_ftr_bits ftr_id_aa64isar0[] = {
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
+static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 32, 32, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 4, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64PFR0_GIC_SHIFT, 4, 0),
@@ -101,7 +104,7 @@ static struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
+static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 32, 32, 0),
S_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR0_TGRAN4_SHIFT, 4, ID_AA64MMFR0_TGRAN4_NI),
S_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR0_TGRAN64_SHIFT, 4, ID_AA64MMFR0_TGRAN64_NI),
@@ -119,7 +122,7 @@ static struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
+static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 32, 32, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_PAN_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR1_LOR_SHIFT, 4, 0),
@@ -130,7 +133,7 @@ static struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
+static const struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_LVA_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_IESB_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_AA64MMFR2_LSM_SHIFT, 4, 0),
@@ -139,7 +142,7 @@ static struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_ctr[] = {
+static const struct arm64_ftr_bits ftr_ctr[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RAO */
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 3, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_SAFE, 24, 4, 0), /* CWG */
@@ -147,15 +150,21 @@ static struct arm64_ftr_bits ftr_ctr[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 1), /* DminLine */
/*
* Linux can handle differing I-cache policies. Userspace JITs will
- * make use of *minLine
+ * make use of *minLine.
+ * If we have differing I-cache policies, report it as the weakest - AIVIVT.
*/
- ARM64_FTR_BITS(FTR_NONSTRICT, FTR_EXACT, 14, 2, 0), /* L1Ip */
+ ARM64_FTR_BITS(FTR_NONSTRICT, FTR_EXACT, 14, 2, ICACHE_POLICY_AIVIVT), /* L1Ip */
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 10, 0), /* RAZ */
ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0), /* IminLine */
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_id_mmfr0[] = {
+struct arm64_ftr_reg arm64_ftr_reg_ctrel0 = {
+ .name = "SYS_CTR_EL0",
+ .ftr_bits = ftr_ctr
+};
+
+static const struct arm64_ftr_bits ftr_id_mmfr0[] = {
S_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 4, 0xf), /* InnerShr */
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 24, 4, 0), /* FCSE */
ARM64_FTR_BITS(FTR_NONSTRICT, FTR_LOWER_SAFE, 20, 4, 0), /* AuxReg */
@@ -167,7 +176,7 @@ static struct arm64_ftr_bits ftr_id_mmfr0[] = {
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
+static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 32, 32, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_CTX_CMPS_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_WRPS_SHIFT, 4, 0),
@@ -178,14 +187,14 @@ static struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_mvfr2[] = {
+static const struct arm64_ftr_bits ftr_mvfr2[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 8, 24, 0), /* RAZ */
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 4, 0), /* FPMisc */
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 0, 4, 0), /* SIMDMisc */
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_dczid[] = {
+static const struct arm64_ftr_bits ftr_dczid[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 5, 27, 0), /* RAZ */
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 1, 1), /* DZP */
ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0), /* BS */
@@ -193,7 +202,7 @@ static struct arm64_ftr_bits ftr_dczid[] = {
};
-static struct arm64_ftr_bits ftr_id_isar5[] = {
+static const struct arm64_ftr_bits ftr_id_isar5[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_ISAR5_RDM_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 20, 4, 0), /* RAZ */
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, ID_ISAR5_CRC32_SHIFT, 4, 0),
@@ -204,14 +213,14 @@ static struct arm64_ftr_bits ftr_id_isar5[] = {
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_id_mmfr4[] = {
+static const struct arm64_ftr_bits ftr_id_mmfr4[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 8, 24, 0), /* RAZ */
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 4, 4, 0), /* ac2 */
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 0, 4, 0), /* RAZ */
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_id_pfr0[] = {
+static const struct arm64_ftr_bits ftr_id_pfr0[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 16, 16, 0), /* RAZ */
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 12, 4, 0), /* State3 */
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 8, 4, 0), /* State2 */
@@ -220,7 +229,7 @@ static struct arm64_ftr_bits ftr_id_pfr0[] = {
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_id_dfr0[] = {
+static const struct arm64_ftr_bits ftr_id_dfr0[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 28, 4, 0),
S_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 24, 4, 0xf), /* PerfMon */
ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0),
@@ -238,7 +247,7 @@ static struct arm64_ftr_bits ftr_id_dfr0[] = {
* 0. Covers the following 32bit registers:
* id_isar[0-4], id_mmfr[1-3], id_pfr1, mvfr[0-1]
*/
-static struct arm64_ftr_bits ftr_generic_32bits[] = {
+static const struct arm64_ftr_bits ftr_generic_32bits[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 28, 4, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 24, 4, 0),
ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0),
@@ -250,29 +259,32 @@ static struct arm64_ftr_bits ftr_generic_32bits[] = {
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_generic[] = {
+static const struct arm64_ftr_bits ftr_generic[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 0, 64, 0),
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_generic32[] = {
+static const struct arm64_ftr_bits ftr_generic32[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 0, 32, 0),
ARM64_FTR_END,
};
-static struct arm64_ftr_bits ftr_aa64raz[] = {
+static const struct arm64_ftr_bits ftr_aa64raz[] = {
ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 0, 64, 0),
ARM64_FTR_END,
};
-#define ARM64_FTR_REG(id, table) \
- { \
- .sys_id = id, \
+#define ARM64_FTR_REG(id, table) { \
+ .sys_id = id, \
+ .reg = &(struct arm64_ftr_reg){ \
.name = #id, \
.ftr_bits = &((table)[0]), \
- }
+ }}
-static struct arm64_ftr_reg arm64_ftr_regs[] = {
+static const struct __ftr_reg_entry {
+ u32 sys_id;
+ struct arm64_ftr_reg *reg;
+} arm64_ftr_regs[] = {
/* Op1 = 0, CRn = 0, CRm = 1 */
ARM64_FTR_REG(SYS_ID_PFR0_EL1, ftr_id_pfr0),
@@ -315,7 +327,7 @@ static struct arm64_ftr_reg arm64_ftr_regs[] = {
ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2),
/* Op1 = 3, CRn = 0, CRm = 0 */
- ARM64_FTR_REG(SYS_CTR_EL0, ftr_ctr),
+ { SYS_CTR_EL0, &arm64_ftr_reg_ctrel0 },
ARM64_FTR_REG(SYS_DCZID_EL0, ftr_dczid),
/* Op1 = 3, CRn = 14, CRm = 0 */
@@ -324,7 +336,7 @@ static struct arm64_ftr_reg arm64_ftr_regs[] = {
static int search_cmp_ftr_reg(const void *id, const void *regp)
{
- return (int)(unsigned long)id - (int)((const struct arm64_ftr_reg *)regp)->sys_id;
+ return (int)(unsigned long)id - (int)((const struct __ftr_reg_entry *)regp)->sys_id;
}
/*
@@ -339,14 +351,20 @@ static int search_cmp_ftr_reg(const void *id, const void *regp)
*/
static struct arm64_ftr_reg *get_arm64_ftr_reg(u32 sys_id)
{
- return bsearch((const void *)(unsigned long)sys_id,
+ const struct __ftr_reg_entry *ret;
+
+ ret = bsearch((const void *)(unsigned long)sys_id,
arm64_ftr_regs,
ARRAY_SIZE(arm64_ftr_regs),
sizeof(arm64_ftr_regs[0]),
search_cmp_ftr_reg);
+ if (ret)
+ return ret->reg;
+ return NULL;
}
-static u64 arm64_ftr_set_value(struct arm64_ftr_bits *ftrp, s64 reg, s64 ftr_val)
+static u64 arm64_ftr_set_value(const struct arm64_ftr_bits *ftrp, s64 reg,
+ s64 ftr_val)
{
u64 mask = arm64_ftr_mask(ftrp);
@@ -355,7 +373,8 @@ static u64 arm64_ftr_set_value(struct arm64_ftr_bits *ftrp, s64 reg, s64 ftr_val
return reg;
}
-static s64 arm64_ftr_safe_value(struct arm64_ftr_bits *ftrp, s64 new, s64 cur)
+static s64 arm64_ftr_safe_value(const struct arm64_ftr_bits *ftrp, s64 new,
+ s64 cur)
{
s64 ret = 0;
@@ -376,27 +395,13 @@ static s64 arm64_ftr_safe_value(struct arm64_ftr_bits *ftrp, s64 new, s64 cur)
return ret;
}
-static int __init sort_cmp_ftr_regs(const void *a, const void *b)
-{
- return ((const struct arm64_ftr_reg *)a)->sys_id -
- ((const struct arm64_ftr_reg *)b)->sys_id;
-}
-
-static void __init swap_ftr_regs(void *a, void *b, int size)
-{
- struct arm64_ftr_reg tmp = *(struct arm64_ftr_reg *)a;
- *(struct arm64_ftr_reg *)a = *(struct arm64_ftr_reg *)b;
- *(struct arm64_ftr_reg *)b = tmp;
-}
-
static void __init sort_ftr_regs(void)
{
- /* Keep the array sorted so that we can do the binary search */
- sort(arm64_ftr_regs,
- ARRAY_SIZE(arm64_ftr_regs),
- sizeof(arm64_ftr_regs[0]),
- sort_cmp_ftr_regs,
- swap_ftr_regs);
+ int i;
+
+ /* Check that the array is sorted so that we can do the binary search */
+ for (i = 1; i < ARRAY_SIZE(arm64_ftr_regs); i++)
+ BUG_ON(arm64_ftr_regs[i].sys_id < arm64_ftr_regs[i - 1].sys_id);
}
/*
@@ -407,7 +412,7 @@ static void __init init_cpu_ftr_reg(u32 sys_reg, u64 new)
{
u64 val = 0;
u64 strict_mask = ~0x0ULL;
- struct arm64_ftr_bits *ftrp;
+ const struct arm64_ftr_bits *ftrp;
struct arm64_ftr_reg *reg = get_arm64_ftr_reg(sys_reg);
BUG_ON(!reg);
@@ -464,7 +469,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
static void update_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 new)
{
- struct arm64_ftr_bits *ftrp;
+ const struct arm64_ftr_bits *ftrp;
for (ftrp = reg->ftr_bits; ftrp->width; ftrp++) {
s64 ftr_cur = arm64_ftr_value(ftrp, reg->sys_val);
@@ -1004,23 +1009,33 @@ verify_local_cpu_features(const struct arm64_cpu_capabilities *caps)
* cannot do anything to fix it up and could cause unexpected failures. So
* we park the CPU.
*/
-void verify_local_cpu_capabilities(void)
+static void verify_local_cpu_capabilities(void)
{
+ verify_local_cpu_errata_workarounds();
+ verify_local_cpu_features(arm64_features);
+ verify_local_elf_hwcaps(arm64_elf_hwcaps);
+ if (system_supports_32bit_el0())
+ verify_local_elf_hwcaps(compat_elf_hwcaps);
+}
+void check_local_cpu_capabilities(void)
+{
+ /*
+ * All secondary CPUs should conform to the early CPU features
+ * in use by the kernel based on boot CPU.
+ */
check_early_cpu_features();
/*
- * If we haven't computed the system capabilities, there is nothing
- * to verify.
+ * If we haven't finalised the system capabilities, this CPU gets
+ * a chance to update the errata work arounds.
+ * Otherwise, this CPU should verify that it has all the system
+ * advertised capabilities.
*/
if (!sys_caps_initialised)
- return;
-
- verify_local_cpu_errata();
- verify_local_cpu_features(arm64_features);
- verify_local_elf_hwcaps(arm64_elf_hwcaps);
- if (system_supports_32bit_el0())
- verify_local_elf_hwcaps(compat_elf_hwcaps);
+ update_cpu_errata_workarounds();
+ else
+ verify_local_cpu_capabilities();
}
static void __init setup_feature_capabilities(void)
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index ed1b84fe6925..b3d5b3e8fbcb 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -363,8 +363,6 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
}
cpuinfo_detect_icache_policy(info);
-
- check_local_cpu_errata();
}
void cpuinfo_store_cpu(void)
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
index 91fff48d0f57..73ae90ef434c 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -46,16 +46,14 @@ static void mdscr_write(u32 mdscr)
{
unsigned long flags;
local_dbg_save(flags);
- asm volatile("msr mdscr_el1, %0" :: "r" (mdscr));
+ write_sysreg(mdscr, mdscr_el1);
local_dbg_restore(flags);
}
NOKPROBE_SYMBOL(mdscr_write);
static u32 mdscr_read(void)
{
- u32 mdscr;
- asm volatile("mrs %0, mdscr_el1" : "=r" (mdscr));
- return mdscr;
+ return read_sysreg(mdscr_el1);
}
NOKPROBE_SYMBOL(mdscr_read);
@@ -132,36 +130,18 @@ NOKPROBE_SYMBOL(disable_debug_monitors);
/*
* OS lock clearing.
*/
-static void clear_os_lock(void *unused)
+static int clear_os_lock(unsigned int cpu)
{
- asm volatile("msr oslar_el1, %0" : : "r" (0));
-}
-
-static int os_lock_notify(struct notifier_block *self,
- unsigned long action, void *data)
-{
- if ((action & ~CPU_TASKS_FROZEN) == CPU_ONLINE)
- clear_os_lock(NULL);
- return NOTIFY_OK;
+ write_sysreg(0, oslar_el1);
+ isb();
+ return 0;
}
-static struct notifier_block os_lock_nb = {
- .notifier_call = os_lock_notify,
-};
-
static int debug_monitors_init(void)
{
- cpu_notifier_register_begin();
-
- /* Clear the OS lock. */
- on_each_cpu(clear_os_lock, NULL, 1);
- isb();
-
- /* Register hotplug handler. */
- __register_cpu_notifier(&os_lock_nb);
-
- cpu_notifier_register_done();
- return 0;
+ return cpuhp_setup_state(CPUHP_AP_ARM64_DEBUG_MONITORS_STARTING,
+ "CPUHP_AP_ARM64_DEBUG_MONITORS_STARTING",
+ clear_os_lock, NULL);
}
postcore_initcall(debug_monitors_init);
@@ -254,7 +234,7 @@ static int single_step_handler(unsigned long addr, unsigned int esr,
return 0;
if (user_mode(regs)) {
- send_user_sigtrap(TRAP_HWBKPT);
+ send_user_sigtrap(TRAP_TRACE);
/*
* ptrace will disable single step unless explicitly
@@ -382,7 +362,7 @@ NOKPROBE_SYMBOL(aarch32_break_handler);
static int __init debug_traps_init(void)
{
hook_debug_fault_code(DBG_ESR_EVT_HWSS, single_step_handler, SIGTRAP,
- TRAP_HWBKPT, "single-step handler");
+ TRAP_TRACE, "single-step handler");
hook_debug_fault_code(DBG_ESR_EVT_BRK, brk_handler, SIGTRAP,
TRAP_BRKPT, "ptrace BRK handler");
return 0;
@@ -435,8 +415,10 @@ NOKPROBE_SYMBOL(kernel_active_single_step);
/* ptrace API */
void user_enable_single_step(struct task_struct *task)
{
- set_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP);
- set_regs_spsr_ss(task_pt_regs(task));
+ struct thread_info *ti = task_thread_info(task);
+
+ if (!test_and_set_ti_thread_flag(ti, TIF_SINGLESTEP))
+ set_regs_spsr_ss(task_pt_regs(task));
}
NOKPROBE_SYMBOL(user_enable_single_step);
diff --git a/arch/arm64/kernel/entry-ftrace.S b/arch/arm64/kernel/entry-ftrace.S
index 0f03a8fe2314..aef02d2af3b5 100644
--- a/arch/arm64/kernel/entry-ftrace.S
+++ b/arch/arm64/kernel/entry-ftrace.S
@@ -219,7 +219,7 @@ ENDPROC(ftrace_graph_caller)
*
* Run ftrace_return_to_handler() before going back to parent.
* @fp is checked against the value passed by ftrace_graph_caller()
- * only when CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST is enabled.
+ * only when HAVE_FUNCTION_GRAPH_FP_TEST is enabled.
*/
ENTRY(return_to_handler)
save_return_regs
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 441420ca7d08..223d54a4d66b 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -104,7 +104,7 @@
str x20, [sp, #S_ORIG_ADDR_LIMIT]
mov x20, #TASK_SIZE_64
str x20, [tsk, #TI_ADDR_LIMIT]
- ALTERNATIVE(nop, SET_PSTATE_UAO(0), ARM64_HAS_UAO, CONFIG_ARM64_UAO)
+ /* No need to reset PSTATE.UAO, hardware's already set it to 0 for us */
.endif /* \el == 0 */
mrs x22, elr_el1
mrs x23, spsr_el1
@@ -150,13 +150,7 @@
ldr x23, [sp, #S_SP] // load return stack pointer
msr sp_el0, x23
#ifdef CONFIG_ARM64_ERRATUM_845719
-alternative_if_not ARM64_WORKAROUND_845719
- nop
- nop
-#ifdef CONFIG_PID_IN_CONTEXTIDR
- nop
-#endif
-alternative_else
+alternative_if ARM64_WORKAROUND_845719
tbz x22, #4, 1f
#ifdef CONFIG_PID_IN_CONTEXTIDR
mrs x29, contextidr_el1
@@ -165,7 +159,7 @@ alternative_else
msr contextidr_el1, xzr
#endif
1:
-alternative_endif
+alternative_else_nop_endif
#endif
.endif
msr elr_el1, x21 // set up the return data
@@ -707,18 +701,13 @@ ret_fast_syscall_trace:
* Ok, we need to do extra processing, enter the slow path.
*/
work_pending:
- tbnz x1, #TIF_NEED_RESCHED, work_resched
- /* TIF_SIGPENDING, TIF_NOTIFY_RESUME or TIF_FOREIGN_FPSTATE case */
mov x0, sp // 'regs'
- enable_irq // enable interrupts for do_notify_resume()
bl do_notify_resume
- b ret_to_user
-work_resched:
#ifdef CONFIG_TRACE_IRQFLAGS
- bl trace_hardirqs_off // the IRQs are off here, inform the tracing code
+ bl trace_hardirqs_on // enabled while in userspace
#endif
- bl schedule
-
+ ldr x1, [tsk, #TI_FLAGS] // re-check for single-step
+ b finish_ret_to_user
/*
* "slow" syscall return path.
*/
@@ -727,6 +716,7 @@ ret_to_user:
ldr x1, [tsk, #TI_FLAGS]
and x2, x1, #_TIF_WORK_MASK
cbnz x2, work_pending
+finish_ret_to_user:
enable_step_tsk x1, x2
kernel_exit 0
ENDPROC(ret_to_user)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 975b274ee7b5..394c61db5566 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -299,28 +299,16 @@ static inline void fpsimd_pm_init(void) { }
#endif /* CONFIG_CPU_PM */
#ifdef CONFIG_HOTPLUG_CPU
-static int fpsimd_cpu_hotplug_notifier(struct notifier_block *nfb,
- unsigned long action,
- void *hcpu)
+static int fpsimd_cpu_dead(unsigned int cpu)
{
- unsigned int cpu = (long)hcpu;
-
- switch (action) {
- case CPU_DEAD:
- case CPU_DEAD_FROZEN:
- per_cpu(fpsimd_last_state, cpu) = NULL;
- break;
- }
- return NOTIFY_OK;
+ per_cpu(fpsimd_last_state, cpu) = NULL;
+ return 0;
}
-static struct notifier_block fpsimd_cpu_hotplug_notifier_block = {
- .notifier_call = fpsimd_cpu_hotplug_notifier,
-};
-
static inline void fpsimd_hotplug_init(void)
{
- register_cpu_notifier(&fpsimd_cpu_hotplug_notifier_block);
+ cpuhp_setup_state_nocalls(CPUHP_ARM64_FPSIMD_DEAD, "arm64/fpsimd:dead",
+ NULL, fpsimd_cpu_dead);
}
#else
diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c
index ebecf9aa33d1..40ad08ac569a 100644
--- a/arch/arm64/kernel/ftrace.c
+++ b/arch/arm64/kernel/ftrace.c
@@ -138,7 +138,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
return;
err = ftrace_push_return_trace(old, self_addr, &trace.depth,
- frame_pointer);
+ frame_pointer, NULL);
if (err == -EBUSY)
return;
else
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 3e7b050e99dc..427f6d3f084c 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -208,13 +208,23 @@ efi_header_end:
__INIT
+ /*
+ * The following callee saved general purpose registers are used on the
+ * primary lowlevel boot path:
+ *
+ * Register Scope Purpose
+ * x21 stext() .. start_kernel() FDT pointer passed at boot in x0
+ * x23 stext() .. start_kernel() physical misalignment/KASLR offset
+ * x28 __create_page_tables() callee preserved temp register
+ * x19/x20 __primary_switch() callee preserved temp registers
+ */
ENTRY(stext)
bl preserve_boot_args
- bl el2_setup // Drop to EL1, w20=cpu_boot_mode
- adrp x24, __PHYS_OFFSET
- and x23, x24, MIN_KIMG_ALIGN - 1 // KASLR offset, defaults to 0
+ bl el2_setup // Drop to EL1, w0=cpu_boot_mode
+ adrp x23, __PHYS_OFFSET
+ and x23, x23, MIN_KIMG_ALIGN - 1 // KASLR offset, defaults to 0
bl set_cpu_boot_mode_flag
- bl __create_page_tables // x25=TTBR0, x26=TTBR1
+ bl __create_page_tables
/*
* The following calls CPU setup code, see arch/arm64/mm/proc.S for
* details.
@@ -222,9 +232,7 @@ ENTRY(stext)
* the TCR will have been set.
*/
bl __cpu_setup // initialise processor
- adr_l x27, __primary_switch // address to jump to after
- // MMU has been enabled
- b __enable_mmu
+ b __primary_switch
ENDPROC(stext)
/*
@@ -311,23 +319,21 @@ ENDPROC(preserve_boot_args)
* been enabled
*/
__create_page_tables:
- adrp x25, idmap_pg_dir
- adrp x26, swapper_pg_dir
mov x28, lr
/*
* Invalidate the idmap and swapper page tables to avoid potential
* dirty cache lines being evicted.
*/
- mov x0, x25
- add x1, x26, #SWAPPER_DIR_SIZE
+ adrp x0, idmap_pg_dir
+ adrp x1, swapper_pg_dir + SWAPPER_DIR_SIZE
bl __inval_cache_range
/*
* Clear the idmap and swapper page tables.
*/
- mov x0, x25
- add x6, x26, #SWAPPER_DIR_SIZE
+ adrp x0, idmap_pg_dir
+ adrp x6, swapper_pg_dir + SWAPPER_DIR_SIZE
1: stp xzr, xzr, [x0], #16
stp xzr, xzr, [x0], #16
stp xzr, xzr, [x0], #16
@@ -340,7 +346,7 @@ __create_page_tables:
/*
* Create the identity mapping.
*/
- mov x0, x25 // idmap_pg_dir
+ adrp x0, idmap_pg_dir
adrp x3, __idmap_text_start // __pa(__idmap_text_start)
#ifndef CONFIG_ARM64_VA_BITS_48
@@ -390,7 +396,7 @@ __create_page_tables:
/*
* Map the kernel image (starting with PHYS_OFFSET).
*/
- mov x0, x26 // swapper_pg_dir
+ adrp x0, swapper_pg_dir
mov_q x5, KIMAGE_VADDR + TEXT_OFFSET // compile time __va(_text)
add x5, x5, x23 // add KASLR displacement
create_pgd_entry x0, x5, x3, x6
@@ -405,8 +411,8 @@ __create_page_tables:
* accesses (MMU disabled), invalidate the idmap and swapper page
* tables again to remove any speculatively loaded cache lines.
*/
- mov x0, x25
- add x1, x26, #SWAPPER_DIR_SIZE
+ adrp x0, idmap_pg_dir
+ adrp x1, swapper_pg_dir + SWAPPER_DIR_SIZE
dmb sy
bl __inval_cache_range
@@ -416,14 +422,27 @@ ENDPROC(__create_page_tables)
/*
* The following fragment of code is executed with the MMU enabled.
+ *
+ * x0 = __PHYS_OFFSET
*/
- .set initial_sp, init_thread_union + THREAD_START_SP
__primary_switched:
- mov x28, lr // preserve LR
+ adrp x4, init_thread_union
+ add sp, x4, #THREAD_SIZE
+ msr sp_el0, x4 // Save thread_info
+
adr_l x8, vectors // load VBAR_EL1 with virtual
msr vbar_el1, x8 // vector table address
isb
+ stp xzr, x30, [sp, #-16]!
+ mov x29, sp
+
+ str_l x21, __fdt_pointer, x5 // Save FDT pointer
+
+ ldr_l x4, kimage_vaddr // Save the offset between
+ sub x4, x4, x0 // the kernel virtual and
+ str_l x4, kimage_voffset, x5 // physical mappings
+
// Clear BSS
adr_l x0, __bss_start
mov x1, xzr
@@ -432,17 +451,6 @@ __primary_switched:
bl __pi_memset
dsb ishst // Make zero page visible to PTW
- adr_l sp, initial_sp, x4
- mov x4, sp
- and x4, x4, #~(THREAD_SIZE - 1)
- msr sp_el0, x4 // Save thread_info
- str_l x21, __fdt_pointer, x5 // Save FDT pointer
-
- ldr_l x4, kimage_vaddr // Save the offset between
- sub x4, x4, x24 // the kernel virtual and
- str_l x4, kimage_voffset, x5 // physical mappings
-
- mov x29, #0
#ifdef CONFIG_KASAN
bl kasan_early_init
#endif
@@ -454,8 +462,8 @@ __primary_switched:
bl kaslr_early_init // parse FDT for KASLR options
cbz x0, 0f // KASLR disabled? just proceed
orr x23, x23, x0 // record KASLR offset
- ret x28 // we must enable KASLR, return
- // to __enable_mmu()
+ ldp x29, x30, [sp], #16 // we must enable KASLR, return
+ ret // to __primary_switch()
0:
#endif
b start_kernel
@@ -465,7 +473,7 @@ ENDPROC(__primary_switched)
* end early head section, begin head code that is also used for
* hotplug and needs to have the same protections as the text region
*/
- .section ".text","ax"
+ .section ".idmap.text","ax"
ENTRY(kimage_vaddr)
.quad _text - TEXT_OFFSET
@@ -490,7 +498,7 @@ CPU_LE( bic x0, x0, #(1 << 25) ) // Clear the EE bit for EL2
CPU_BE( orr x0, x0, #(3 << 24) ) // Set the EE and E0E bits for EL1
CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1
msr sctlr_el1, x0
- mov w20, #BOOT_CPU_MODE_EL1 // This cpu booted in EL1
+ mov w0, #BOOT_CPU_MODE_EL1 // This cpu booted in EL1
isb
ret
@@ -586,7 +594,7 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems
cbz x2, install_el2_stub
- mov w20, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2
+ mov w0, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2
isb
ret
@@ -601,7 +609,7 @@ install_el2_stub:
PSR_MODE_EL1h)
msr spsr_el2, x0
msr elr_el2, lr
- mov w20, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2
+ mov w0, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2
eret
ENDPROC(el2_setup)
@@ -611,27 +619,39 @@ ENDPROC(el2_setup)
*/
set_cpu_boot_mode_flag:
adr_l x1, __boot_cpu_mode
- cmp w20, #BOOT_CPU_MODE_EL2
+ cmp w0, #BOOT_CPU_MODE_EL2
b.ne 1f
add x1, x1, #4
-1: str w20, [x1] // This CPU has booted in EL1
+1: str w0, [x1] // This CPU has booted in EL1
dmb sy
dc ivac, x1 // Invalidate potentially stale cache line
ret
ENDPROC(set_cpu_boot_mode_flag)
/*
+ * These values are written with the MMU off, but read with the MMU on.
+ * Writers will invalidate the corresponding address, discarding up to a
+ * 'Cache Writeback Granule' (CWG) worth of data. The linker script ensures
+ * sufficient alignment that the CWG doesn't overlap another section.
+ */
+ .pushsection ".mmuoff.data.write", "aw"
+/*
* We need to find out the CPU boot mode long after boot, so we need to
* store it in a writable variable.
*
* This is not in .bss, because we set it sufficiently early that the boot-time
* zeroing of .bss would clobber it.
*/
- .pushsection .data..cacheline_aligned
- .align L1_CACHE_SHIFT
ENTRY(__boot_cpu_mode)
.long BOOT_CPU_MODE_EL2
.long BOOT_CPU_MODE_EL1
+/*
+ * The booting CPU updates the failed status @__early_cpu_boot_status,
+ * with MMU turned off.
+ */
+ENTRY(__early_cpu_boot_status)
+ .long 0
+
.popsection
/*
@@ -639,7 +659,7 @@ ENTRY(__boot_cpu_mode)
* cores are held until we're ready for them to initialise.
*/
ENTRY(secondary_holding_pen)
- bl el2_setup // Drop to EL1, w20=cpu_boot_mode
+ bl el2_setup // Drop to EL1, w0=cpu_boot_mode
bl set_cpu_boot_mode_flag
mrs x0, mpidr_el1
mov_q x1, MPIDR_HWID_BITMASK
@@ -666,12 +686,10 @@ secondary_startup:
/*
* Common entry point for secondary CPUs.
*/
- adrp x25, idmap_pg_dir
- adrp x26, swapper_pg_dir
bl __cpu_setup // initialise processor
-
- adr_l x27, __secondary_switch // address to jump to after enabling the MMU
- b __enable_mmu
+ bl __enable_mmu
+ ldr x8, =__secondary_switched
+ br x8
ENDPROC(secondary_startup)
__secondary_switched:
@@ -706,33 +724,27 @@ ENDPROC(__secondary_switched)
dc ivac, \tmp1 // Invalidate potentially stale cache line
.endm
- .pushsection .data..cacheline_aligned
- .align L1_CACHE_SHIFT
-ENTRY(__early_cpu_boot_status)
- .long 0
- .popsection
-
/*
* Enable the MMU.
*
* x0 = SCTLR_EL1 value for turning on the MMU.
- * x27 = *virtual* address to jump to upon completion
*
- * Other registers depend on the function called upon completion.
+ * Returns to the caller via x30/lr. This requires the caller to be covered
+ * by the .idmap.text section.
*
* Checks if the selected granule size is supported by the CPU.
* If it isn't, park the CPU
*/
- .section ".idmap.text", "ax"
ENTRY(__enable_mmu)
- mrs x22, sctlr_el1 // preserve old SCTLR_EL1 value
mrs x1, ID_AA64MMFR0_EL1
ubfx x2, x1, #ID_AA64MMFR0_TGRAN_SHIFT, 4
cmp x2, #ID_AA64MMFR0_TGRAN_SUPPORTED
b.ne __no_granule_support
update_early_cpu_boot_status 0, x1, x2
- msr ttbr0_el1, x25 // load TTBR0
- msr ttbr1_el1, x26 // load TTBR1
+ adrp x1, idmap_pg_dir
+ adrp x2, swapper_pg_dir
+ msr ttbr0_el1, x1 // load TTBR0
+ msr ttbr1_el1, x2 // load TTBR1
isb
msr sctlr_el1, x0
isb
@@ -744,29 +756,7 @@ ENTRY(__enable_mmu)
ic iallu
dsb nsh
isb
-#ifdef CONFIG_RANDOMIZE_BASE
- mov x19, x0 // preserve new SCTLR_EL1 value
- blr x27
-
- /*
- * If we return here, we have a KASLR displacement in x23 which we need
- * to take into account by discarding the current kernel mapping and
- * creating a new one.
- */
- msr sctlr_el1, x22 // disable the MMU
- isb
- bl __create_page_tables // recreate kernel mapping
-
- tlbi vmalle1 // Remove any stale TLB entries
- dsb nsh
-
- msr sctlr_el1, x19 // re-enable the MMU
- isb
- ic iallu // flush instructions fetched
- dsb nsh // via old mapping
- isb
-#endif
- br x27
+ ret
ENDPROC(__enable_mmu)
__no_granule_support:
@@ -775,11 +765,11 @@ __no_granule_support:
1:
wfe
wfi
- b 1b
+ b 1b
ENDPROC(__no_granule_support)
-__primary_switch:
#ifdef CONFIG_RELOCATABLE
+__relocate_kernel:
/*
* Iterate over each entry in the relocation table, and apply the
* relocations in place.
@@ -801,14 +791,46 @@ __primary_switch:
add x13, x13, x23 // relocate
str x13, [x11, x23]
b 0b
+1: ret
+ENDPROC(__relocate_kernel)
+#endif
-1:
+__primary_switch:
+#ifdef CONFIG_RANDOMIZE_BASE
+ mov x19, x0 // preserve new SCTLR_EL1 value
+ mrs x20, sctlr_el1 // preserve old SCTLR_EL1 value
#endif
+
+ bl __enable_mmu
+#ifdef CONFIG_RELOCATABLE
+ bl __relocate_kernel
+#ifdef CONFIG_RANDOMIZE_BASE
ldr x8, =__primary_switched
- br x8
-ENDPROC(__primary_switch)
+ adrp x0, __PHYS_OFFSET
+ blr x8
-__secondary_switch:
- ldr x8, =__secondary_switched
+ /*
+ * If we return here, we have a KASLR displacement in x23 which we need
+ * to take into account by discarding the current kernel mapping and
+ * creating a new one.
+ */
+ msr sctlr_el1, x20 // disable the MMU
+ isb
+ bl __create_page_tables // recreate kernel mapping
+
+ tlbi vmalle1 // Remove any stale TLB entries
+ dsb nsh
+
+ msr sctlr_el1, x19 // re-enable the MMU
+ isb
+ ic iallu // flush instructions fetched
+ dsb nsh // via old mapping
+ isb
+
+ bl __relocate_kernel
+#endif
+#endif
+ ldr x8, =__primary_switched
+ adrp x0, __PHYS_OFFSET
br x8
-ENDPROC(__secondary_switch)
+ENDPROC(__primary_switch)
diff --git a/arch/arm64/kernel/hibernate-asm.S b/arch/arm64/kernel/hibernate-asm.S
index 46f29b6560ec..e56d848b6466 100644
--- a/arch/arm64/kernel/hibernate-asm.S
+++ b/arch/arm64/kernel/hibernate-asm.S
@@ -36,8 +36,8 @@
.macro break_before_make_ttbr_switch zero_page, page_table
msr ttbr1_el1, \zero_page
isb
- tlbi vmalle1is
- dsb ish
+ tlbi vmalle1
+ dsb nsh
msr ttbr1_el1, \page_table
isb
.endm
@@ -96,7 +96,7 @@ ENTRY(swsusp_arch_suspend_exit)
add x1, x10, #PAGE_SIZE
/* Clean the copied page to PoU - based on flush_icache_range() */
- dcache_line_size x2, x3
+ raw_dcache_line_size x2, x3
sub x3, x2, #1
bic x4, x10, x3
2: dc cvau, x4 /* clean D line / unified line */
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index 65d81f965e74..d55a7b09959b 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -15,9 +15,9 @@
* License terms: GNU General Public License (GPL) version 2
*/
#define pr_fmt(x) "hibernate: " x
+#include <linux/cpu.h>
#include <linux/kvm_host.h>
#include <linux/mm.h>
-#include <linux/notifier.h>
#include <linux/pm.h>
#include <linux/sched.h>
#include <linux/suspend.h>
@@ -26,6 +26,7 @@
#include <asm/barrier.h>
#include <asm/cacheflush.h>
+#include <asm/cputype.h>
#include <asm/irqflags.h>
#include <asm/memory.h>
#include <asm/mmu_context.h>
@@ -34,6 +35,7 @@
#include <asm/pgtable-hwdef.h>
#include <asm/sections.h>
#include <asm/smp.h>
+#include <asm/smp_plat.h>
#include <asm/suspend.h>
#include <asm/sysreg.h>
#include <asm/virt.h>
@@ -54,12 +56,6 @@ extern int in_suspend;
/* Do we need to reset el2? */
#define el2_reset_needed() (is_hyp_mode_available() && !is_kernel_in_hyp_mode())
-/*
- * Start/end of the hibernate exit code, this must be copied to a 'safe'
- * location in memory, and executed from there.
- */
-extern char __hibernate_exit_text_start[], __hibernate_exit_text_end[];
-
/* temporary el2 vectors in the __hibernate_exit_text section. */
extern char hibernate_el2_vectors[];
@@ -67,6 +63,12 @@ extern char hibernate_el2_vectors[];
extern char __hyp_stub_vectors[];
/*
+ * The logical cpu number we should resume on, initialised to a non-cpu
+ * number.
+ */
+static int sleep_cpu = -EINVAL;
+
+/*
* Values that may not change over hibernate/resume. We put the build number
* and date in here so that we guarantee not to resume with a different
* kernel.
@@ -88,6 +90,8 @@ static struct arch_hibernate_hdr {
* re-configure el2.
*/
phys_addr_t __hyp_stub_vectors;
+
+ u64 sleep_cpu_mpidr;
} resume_hdr;
static inline void arch_hdr_invariants(struct arch_hibernate_hdr_invariants *i)
@@ -130,12 +134,22 @@ int arch_hibernation_header_save(void *addr, unsigned int max_size)
else
hdr->__hyp_stub_vectors = 0;
+ /* Save the mpidr of the cpu we called cpu_suspend() on... */
+ if (sleep_cpu < 0) {
+ pr_err("Failing to hibernate on an unkown CPU.\n");
+ return -ENODEV;
+ }
+ hdr->sleep_cpu_mpidr = cpu_logical_map(sleep_cpu);
+ pr_info("Hibernating on CPU %d [mpidr:0x%llx]\n", sleep_cpu,
+ hdr->sleep_cpu_mpidr);
+
return 0;
}
EXPORT_SYMBOL(arch_hibernation_header_save);
int arch_hibernation_header_restore(void *addr)
{
+ int ret;
struct arch_hibernate_hdr_invariants invariants;
struct arch_hibernate_hdr *hdr = addr;
@@ -145,6 +159,24 @@ int arch_hibernation_header_restore(void *addr)
return -EINVAL;
}
+ sleep_cpu = get_logical_index(hdr->sleep_cpu_mpidr);
+ pr_info("Hibernated on CPU %d [mpidr:0x%llx]\n", sleep_cpu,
+ hdr->sleep_cpu_mpidr);
+ if (sleep_cpu < 0) {
+ pr_crit("Hibernated on a CPU not known to this kernel!\n");
+ sleep_cpu = -EINVAL;
+ return -EINVAL;
+ }
+ if (!cpu_online(sleep_cpu)) {
+ pr_info("Hibernated on a CPU that is offline! Bringing CPU up.\n");
+ ret = cpu_up(sleep_cpu);
+ if (ret) {
+ pr_err("Failed to bring hibernate-CPU up!\n");
+ sleep_cpu = -EINVAL;
+ return ret;
+ }
+ }
+
resume_hdr = *hdr;
return 0;
@@ -241,6 +273,7 @@ out:
return rc;
}
+#define dcache_clean_range(start, end) __flush_dcache_area(start, (end - start))
int swsusp_arch_suspend(void)
{
@@ -256,10 +289,16 @@ int swsusp_arch_suspend(void)
local_dbg_save(flags);
if (__cpu_suspend_enter(&state)) {
+ sleep_cpu = smp_processor_id();
ret = swsusp_save();
} else {
- /* Clean kernel to PoC for secondary core startup */
- __flush_dcache_area(LMADDR(KERNEL_START), KERNEL_END - KERNEL_START);
+ /* Clean kernel core startup/idle code to PoC*/
+ dcache_clean_range(__mmuoff_data_start, __mmuoff_data_end);
+ dcache_clean_range(__idmap_text_start, __idmap_text_end);
+
+ /* Clean kvm setup code to PoC? */
+ if (el2_reset_needed())
+ dcache_clean_range(__hyp_idmap_text_start, __hyp_idmap_text_end);
/*
* Tell the hibernation core that we've just restored
@@ -267,6 +306,7 @@ int swsusp_arch_suspend(void)
*/
in_suspend = 0;
+ sleep_cpu = -EINVAL;
__cpu_suspend_exit();
}
@@ -275,6 +315,33 @@ int swsusp_arch_suspend(void)
return ret;
}
+static void _copy_pte(pte_t *dst_pte, pte_t *src_pte, unsigned long addr)
+{
+ pte_t pte = *src_pte;
+
+ if (pte_valid(pte)) {
+ /*
+ * Resume will overwrite areas that may be marked
+ * read only (code, rodata). Clear the RDONLY bit from
+ * the temporary mappings we use during restore.
+ */
+ set_pte(dst_pte, pte_clear_rdonly(pte));
+ } else if (debug_pagealloc_enabled() && !pte_none(pte)) {
+ /*
+ * debug_pagealloc will removed the PTE_VALID bit if
+ * the page isn't in use by the resume kernel. It may have
+ * been in use by the original kernel, in which case we need
+ * to put it back in our copy to do the restore.
+ *
+ * Before marking this entry valid, check the pfn should
+ * be mapped.
+ */
+ BUG_ON(!pfn_valid(pte_pfn(pte)));
+
+ set_pte(dst_pte, pte_mkpresent(pte_clear_rdonly(pte)));
+ }
+}
+
static int copy_pte(pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long start,
unsigned long end)
{
@@ -290,13 +357,7 @@ static int copy_pte(pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long start,
src_pte = pte_offset_kernel(src_pmd, start);
do {
- if (!pte_none(*src_pte))
- /*
- * Resume will overwrite areas that may be marked
- * read only (code, rodata). Clear the RDONLY bit from
- * the temporary mappings we use during restore.
- */
- set_pte(dst_pte, __pte(pte_val(*src_pte) & ~PTE_RDONLY));
+ _copy_pte(dst_pte, src_pte, addr);
} while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end);
return 0;
@@ -483,27 +544,12 @@ out:
return rc;
}
-static int check_boot_cpu_online_pm_callback(struct notifier_block *nb,
- unsigned long action, void *ptr)
+int hibernate_resume_nonboot_cpu_disable(void)
{
- if (action == PM_HIBERNATION_PREPARE &&
- cpumask_first(cpu_online_mask) != 0) {
- pr_warn("CPU0 is offline.\n");
- return notifier_from_errno(-ENODEV);
+ if (sleep_cpu < 0) {
+ pr_err("Failing to resume from hibernate on an unkown CPU.\n");
+ return -ENODEV;
}
- return NOTIFY_OK;
-}
-
-static int __init check_boot_cpu_online_init(void)
-{
- /*
- * Set this pm_notifier callback with a lower priority than
- * cpu_hotplug_pm_callback, so that cpu_hotplug_pm_callback will be
- * called earlier to disable cpu hotplug before the cpu online check.
- */
- pm_notifier(check_boot_cpu_online_pm_callback, -INT_MAX);
-
- return 0;
+ return freeze_secondary_cpus(sleep_cpu);
}
-core_initcall(check_boot_cpu_online_init);
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 26a6bf77d272..948b73148d56 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -857,7 +857,7 @@ void hw_breakpoint_thread_switch(struct task_struct *next)
/*
* CPU initialisation.
*/
-static void hw_breakpoint_reset(void *unused)
+static int hw_breakpoint_reset(unsigned int cpu)
{
int i;
struct perf_event **slots;
@@ -888,28 +888,14 @@ static void hw_breakpoint_reset(void *unused)
write_wb_reg(AARCH64_DBG_REG_WVR, i, 0UL);
}
}
-}
-static int hw_breakpoint_reset_notify(struct notifier_block *self,
- unsigned long action,
- void *hcpu)
-{
- if ((action & ~CPU_TASKS_FROZEN) == CPU_ONLINE) {
- local_irq_disable();
- hw_breakpoint_reset(NULL);
- local_irq_enable();
- }
- return NOTIFY_OK;
+ return 0;
}
-static struct notifier_block hw_breakpoint_reset_nb = {
- .notifier_call = hw_breakpoint_reset_notify,
-};
-
#ifdef CONFIG_CPU_PM
-extern void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *));
+extern void cpu_suspend_set_dbg_restorer(int (*hw_bp_restore)(unsigned int));
#else
-static inline void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
+static inline void cpu_suspend_set_dbg_restorer(int (*hw_bp_restore)(unsigned int))
{
}
#endif
@@ -919,36 +905,34 @@ static inline void cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
*/
static int __init arch_hw_breakpoint_init(void)
{
+ int ret;
+
core_num_brps = get_num_brps();
core_num_wrps = get_num_wrps();
pr_info("found %d breakpoint and %d watchpoint registers.\n",
core_num_brps, core_num_wrps);
- cpu_notifier_register_begin();
-
- /*
- * Reset the breakpoint resources. We assume that a halting
- * debugger will leave the world in a nice state for us.
- */
- smp_call_function(hw_breakpoint_reset, NULL, 1);
- hw_breakpoint_reset(NULL);
-
/* Register debug fault handlers. */
hook_debug_fault_code(DBG_ESR_EVT_HWBP, breakpoint_handler, SIGTRAP,
TRAP_HWBKPT, "hw-breakpoint handler");
hook_debug_fault_code(DBG_ESR_EVT_HWWP, watchpoint_handler, SIGTRAP,
TRAP_HWBKPT, "hw-watchpoint handler");
- /* Register hotplug notifier. */
- __register_cpu_notifier(&hw_breakpoint_reset_nb);
-
- cpu_notifier_register_done();
+ /*
+ * Reset the breakpoint resources. We assume that a halting
+ * debugger will leave the world in a nice state for us.
+ */
+ ret = cpuhp_setup_state(CPUHP_AP_PERF_ARM_HW_BREAKPOINT_STARTING,
+ "CPUHP_AP_PERF_ARM_HW_BREAKPOINT_STARTING",
+ hw_breakpoint_reset, NULL);
+ if (ret)
+ pr_err("failed to register CPU hotplug notifier: %d\n", ret);
/* Register cpu_suspend hw breakpoint restore hook */
cpu_suspend_set_dbg_restorer(hw_breakpoint_reset);
- return 0;
+ return ret;
}
arch_initcall(arch_hw_breakpoint_init);
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
index 63f9432d05e8..6f2ac4fc66ca 100644
--- a/arch/arm64/kernel/insn.c
+++ b/arch/arm64/kernel/insn.c
@@ -96,7 +96,7 @@ static void __kprobes *patch_map(void *addr, int fixmap)
if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX))
page = vmalloc_to_page(addr);
- else if (!module && IS_ENABLED(CONFIG_DEBUG_RODATA))
+ else if (!module)
page = pfn_to_page(PHYS_PFN(__pa(addr)));
else
return addr;
@@ -1202,6 +1202,19 @@ u32 aarch64_set_branch_offset(u32 insn, s32 offset)
BUG();
}
+s32 aarch64_insn_adrp_get_offset(u32 insn)
+{
+ BUG_ON(!aarch64_insn_is_adrp(insn));
+ return aarch64_insn_decode_immediate(AARCH64_INSN_IMM_ADR, insn) << 12;
+}
+
+u32 aarch64_insn_adrp_set_offset(u32 insn, s32 offset)
+{
+ BUG_ON(!aarch64_insn_is_adrp(insn));
+ return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn,
+ offset >> 12);
+}
+
/*
* Extract the Op/CR data from a msr/mrs instruction.
*/
diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
index b05469173ba5..769f24ef628c 100644
--- a/arch/arm64/kernel/kaslr.c
+++ b/arch/arm64/kernel/kaslr.c
@@ -6,6 +6,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/cache.h>
#include <linux/crc32.h>
#include <linux/init.h>
#include <linux/libfdt.h>
@@ -20,7 +21,7 @@
#include <asm/pgtable.h>
#include <asm/sections.h>
-u64 __read_mostly module_alloc_base;
+u64 __ro_after_init module_alloc_base;
u16 __initdata memstart_offset_seed;
static __init u64 get_kaslr_seed(void *fdt)
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 838ccf123307..a9310a69fffd 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -24,6 +24,7 @@
#include <asm/sysreg.h>
#include <asm/virt.h>
+#include <linux/acpi.h>
#include <linux/of.h>
#include <linux/perf/arm_pmu.h>
#include <linux/platform_device.h>
@@ -190,13 +191,23 @@
#define ARMV8_THUNDER_PERFCTR_L1I_CACHE_PREF_MISS 0xED
/* PMUv3 HW events mapping. */
+
+/*
+ * ARMv8 Architectural defined events, not all of these may
+ * be supported on any given implementation. Undefined events will
+ * be disabled at run-time.
+ */
static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
PERF_MAP_ALL_UNSUPPORTED,
[PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES,
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INST_RETIRED,
[PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE,
[PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED,
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = ARMV8_PMUV3_PERFCTR_BUS_CYCLES,
+ [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV8_PMUV3_PERFCTR_STALL_FRONTEND,
+ [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV8_PMUV3_PERFCTR_STALL_BACKEND,
};
/* ARM Cortex-A53 HW events mapping. */
@@ -258,6 +269,15 @@ static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
[C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE,
[C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL,
+ [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE,
+ [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL,
+
+ [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1D_TLB_REFILL,
+ [C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1D_TLB,
+
+ [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL,
+ [C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB,
+
[C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED,
[C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED,
[C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED,
@@ -523,12 +543,6 @@ static struct attribute_group armv8_pmuv3_format_attr_group = {
.attrs = armv8_pmuv3_format_attrs,
};
-static const struct attribute_group *armv8_pmuv3_attr_groups[] = {
- &armv8_pmuv3_events_attr_group,
- &armv8_pmuv3_format_attr_group,
- NULL,
-};
-
/*
* Perf Events' indices
*/
@@ -905,9 +919,22 @@ static void armv8pmu_reset(void *info)
static int armv8_pmuv3_map_event(struct perf_event *event)
{
- return armpmu_map_event(event, &armv8_pmuv3_perf_map,
- &armv8_pmuv3_perf_cache_map,
- ARMV8_PMU_EVTYPE_EVENT);
+ int hw_event_id;
+ struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+
+ hw_event_id = armpmu_map_event(event, &armv8_pmuv3_perf_map,
+ &armv8_pmuv3_perf_cache_map,
+ ARMV8_PMU_EVTYPE_EVENT);
+ if (hw_event_id < 0)
+ return hw_event_id;
+
+ /* disable micro/arch events not supported by this PMU */
+ if ((hw_event_id < ARMV8_PMUV3_MAX_COMMON_EVENTS) &&
+ !test_bit(hw_event_id, armpmu->pmceid_bitmap)) {
+ return -EOPNOTSUPP;
+ }
+
+ return hw_event_id;
}
static int armv8_a53_map_event(struct perf_event *event)
@@ -985,7 +1012,10 @@ static int armv8_pmuv3_init(struct arm_pmu *cpu_pmu)
armv8_pmu_init(cpu_pmu);
cpu_pmu->name = "armv8_pmuv3";
cpu_pmu->map_event = armv8_pmuv3_map_event;
- cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] =
+ &armv8_pmuv3_events_attr_group;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] =
+ &armv8_pmuv3_format_attr_group;
return armv8pmu_probe_pmu(cpu_pmu);
}
@@ -994,7 +1024,10 @@ static int armv8_a53_pmu_init(struct arm_pmu *cpu_pmu)
armv8_pmu_init(cpu_pmu);
cpu_pmu->name = "armv8_cortex_a53";
cpu_pmu->map_event = armv8_a53_map_event;
- cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] =
+ &armv8_pmuv3_events_attr_group;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] =
+ &armv8_pmuv3_format_attr_group;
return armv8pmu_probe_pmu(cpu_pmu);
}
@@ -1003,7 +1036,10 @@ static int armv8_a57_pmu_init(struct arm_pmu *cpu_pmu)
armv8_pmu_init(cpu_pmu);
cpu_pmu->name = "armv8_cortex_a57";
cpu_pmu->map_event = armv8_a57_map_event;
- cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] =
+ &armv8_pmuv3_events_attr_group;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] =
+ &armv8_pmuv3_format_attr_group;
return armv8pmu_probe_pmu(cpu_pmu);
}
@@ -1012,7 +1048,10 @@ static int armv8_a72_pmu_init(struct arm_pmu *cpu_pmu)
armv8_pmu_init(cpu_pmu);
cpu_pmu->name = "armv8_cortex_a72";
cpu_pmu->map_event = armv8_a57_map_event;
- cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] =
+ &armv8_pmuv3_events_attr_group;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] =
+ &armv8_pmuv3_format_attr_group;
return armv8pmu_probe_pmu(cpu_pmu);
}
@@ -1021,7 +1060,10 @@ 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;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] =
+ &armv8_pmuv3_events_attr_group;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] =
+ &armv8_pmuv3_format_attr_group;
return armv8pmu_probe_pmu(cpu_pmu);
}
@@ -1030,7 +1072,10 @@ static int armv8_vulcan_pmu_init(struct arm_pmu *cpu_pmu)
armv8_pmu_init(cpu_pmu);
cpu_pmu->name = "armv8_brcm_vulcan";
cpu_pmu->map_event = armv8_vulcan_map_event;
- cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] =
+ &armv8_pmuv3_events_attr_group;
+ cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] =
+ &armv8_pmuv3_format_attr_group;
return armv8pmu_probe_pmu(cpu_pmu);
}
@@ -1044,21 +1089,32 @@ static const struct of_device_id armv8_pmu_of_device_ids[] = {
{},
};
+/*
+ * Non DT systems have their micro/arch events probed at run-time.
+ * A fairly complete list of generic events are provided and ones that
+ * aren't supported by the current PMU are disabled.
+ */
+static const struct pmu_probe_info armv8_pmu_probe_table[] = {
+ PMU_PROBE(0, 0, armv8_pmuv3_init), /* enable all defined counters */
+ { /* sentinel value */ }
+};
+
static int armv8_pmu_device_probe(struct platform_device *pdev)
{
- return arm_pmu_device_probe(pdev, armv8_pmu_of_device_ids, NULL);
+ if (acpi_disabled)
+ return arm_pmu_device_probe(pdev, armv8_pmu_of_device_ids,
+ NULL);
+
+ return arm_pmu_device_probe(pdev, armv8_pmu_of_device_ids,
+ armv8_pmu_probe_table);
}
static struct platform_driver armv8_pmu_driver = {
.driver = {
- .name = "armv8-pmu",
+ .name = ARMV8_PMU_PDEV_NAME,
.of_match_table = armv8_pmu_of_device_ids,
},
.probe = armv8_pmu_device_probe,
};
-static int __init register_armv8_pmu_driver(void)
-{
- return platform_driver_register(&armv8_pmu_driver);
-}
-device_initcall(register_armv8_pmu_driver);
+builtin_platform_driver(armv8_pmu_driver);
diff --git a/arch/arm64/kernel/probes/decode-insn.c b/arch/arm64/kernel/probes/decode-insn.c
index 37e47a9d617e..d1731bf977ef 100644
--- a/arch/arm64/kernel/probes/decode-insn.c
+++ b/arch/arm64/kernel/probes/decode-insn.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/module.h>
+#include <linux/kallsyms.h>
#include <asm/kprobes.h>
#include <asm/insn.h>
#include <asm/sections.h>
@@ -122,7 +123,7 @@ arm_probe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
static bool __kprobes
is_probed_address_atomic(kprobe_opcode_t *scan_start, kprobe_opcode_t *scan_end)
{
- while (scan_start > scan_end) {
+ while (scan_start >= scan_end) {
/*
* atomic region starts from exclusive load and ends with
* exclusive store.
@@ -142,33 +143,30 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi)
{
enum kprobe_insn decoded;
kprobe_opcode_t insn = le32_to_cpu(*addr);
- kprobe_opcode_t *scan_start = addr - 1;
- kprobe_opcode_t *scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
- struct module *mod;
-#endif
-
- if (addr >= (kprobe_opcode_t *)_text &&
- scan_end < (kprobe_opcode_t *)_text)
- scan_end = (kprobe_opcode_t *)_text;
-#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
- else {
- preempt_disable();
- mod = __module_address((unsigned long)addr);
- if (mod && within_module_init((unsigned long)addr, mod) &&
- !within_module_init((unsigned long)scan_end, mod))
- scan_end = (kprobe_opcode_t *)mod->init_layout.base;
- else if (mod && within_module_core((unsigned long)addr, mod) &&
- !within_module_core((unsigned long)scan_end, mod))
- scan_end = (kprobe_opcode_t *)mod->core_layout.base;
- preempt_enable();
+ kprobe_opcode_t *scan_end = NULL;
+ unsigned long size = 0, offset = 0;
+
+ /*
+ * If there's a symbol defined in front of and near enough to
+ * the probe address assume it is the entry point to this
+ * code and use it to further limit how far back we search
+ * when determining if we're in an atomic sequence. If we could
+ * not find any symbol skip the atomic test altogether as we
+ * could otherwise end up searching irrelevant text/literals.
+ * KPROBES depends on KALLSYMS so this last case should never
+ * happen.
+ */
+ if (kallsyms_lookup_size_offset((unsigned long) addr, &size, &offset)) {
+ if (offset < (MAX_ATOMIC_CONTEXT_SIZE*sizeof(kprobe_opcode_t)))
+ scan_end = addr - (offset / sizeof(kprobe_opcode_t));
+ else
+ scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
}
-#endif
decoded = arm_probe_decode_insn(insn, asi);
- if (decoded == INSN_REJECTED ||
- is_probed_address_atomic(scan_start, scan_end))
- return INSN_REJECTED;
+ if (decoded != INSN_REJECTED && scan_end)
+ if (is_probed_address_atomic(addr - 1, scan_end))
+ return INSN_REJECTED;
return decoded;
}
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
index c6b0f40620d8..f5077ea7af6d 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -19,7 +19,7 @@
#include <linux/kasan.h>
#include <linux/kernel.h>
#include <linux/kprobes.h>
-#include <linux/module.h>
+#include <linux/extable.h>
#include <linux/slab.h>
#include <linux/stop_machine.h>
#include <linux/stringify.h>
@@ -31,7 +31,7 @@
#include <asm/insn.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
-#include <asm-generic/sections.h>
+#include <asm/sections.h>
#include "decode-insn.h"
@@ -166,13 +166,18 @@ static void __kprobes set_current_kprobe(struct kprobe *p)
}
/*
- * The D-flag (Debug mask) is set (masked) upon debug exception entry.
- * Kprobes needs to clear (unmask) D-flag -ONLY- in case of recursive
- * probe i.e. when probe hit from kprobe handler context upon
- * executing the pre/post handlers. In this case we return with
- * D-flag clear so that single-stepping can be carried-out.
- *
- * Leave D-flag set in all other cases.
+ * When PSTATE.D is set (masked), then software step exceptions can not be
+ * generated.
+ * SPSR's D bit shows the value of PSTATE.D immediately before the
+ * exception was taken. PSTATE.D is set while entering into any exception
+ * mode, however software clears it for any normal (none-debug-exception)
+ * mode in the exception entry. Therefore, when we are entering into kprobe
+ * breakpoint handler from any normal mode then SPSR.D bit is already
+ * cleared, however it is set when we are entering from any debug exception
+ * mode.
+ * Since we always need to generate single step exception after a kprobe
+ * breakpoint exception therefore we need to clear it unconditionally, when
+ * we become sure that the current breakpoint exception is for kprobe.
*/
static void __kprobes
spsr_set_debug_flag(struct pt_regs *regs, int mask)
@@ -245,10 +250,7 @@ static void __kprobes setup_singlestep(struct kprobe *p,
set_ss_context(kcb, slot); /* mark pending ss */
- if (kcb->kprobe_status == KPROBE_REENTER)
- spsr_set_debug_flag(regs, 0);
- else
- WARN_ON(regs->pstate & PSR_D_BIT);
+ spsr_set_debug_flag(regs, 0);
/* IRQs and single stepping do not mix well. */
kprobes_save_local_irqflag(kcb, regs);
@@ -333,8 +335,6 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
BUG();
kernel_disable_single_step();
- if (kcb->kprobe_status == KPROBE_REENTER)
- spsr_set_debug_flag(regs, 1);
if (kcb->kprobe_status == KPROBE_REENTER)
restore_previous_kprobe(kcb);
@@ -457,9 +457,6 @@ kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr)
kprobes_restore_local_irqflag(kcb, regs);
kernel_disable_single_step();
- if (kcb->kprobe_status == KPROBE_REENTER)
- spsr_set_debug_flag(regs, 1);
-
post_kprobe_handler(kcb, regs);
}
@@ -543,9 +540,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
bool arch_within_kprobe_blacklist(unsigned long addr)
{
- extern char __idmap_text_start[], __idmap_text_end[];
- extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[];
-
if ((addr >= (unsigned long)__kprobes_text_start &&
addr < (unsigned long)__kprobes_text_end) ||
(addr >= (unsigned long)__entry_text_start &&
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 6cd2612236dc..27b2f1387df4 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -202,7 +202,7 @@ void show_regs(struct pt_regs * regs)
static void tls_thread_flush(void)
{
- asm ("msr tpidr_el0, xzr");
+ write_sysreg(0, tpidr_el0);
if (is_compat_task()) {
current->thread.tp_value = 0;
@@ -213,7 +213,7 @@ static void tls_thread_flush(void)
* with a stale shadow state during context switch.
*/
barrier();
- asm ("msr tpidrro_el0, xzr");
+ write_sysreg(0, tpidrro_el0);
}
}
@@ -253,7 +253,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
* Read the current TLS pointer from tpidr_el0 as it may be
* out-of-sync with the saved value.
*/
- asm("mrs %0, tpidr_el0" : "=r" (*task_user_tls(p)));
+ *task_user_tls(p) = read_sysreg(tpidr_el0);
if (stack_start) {
if (is_compat_thread(task_thread_info(p)))
@@ -289,17 +289,15 @@ static void tls_thread_switch(struct task_struct *next)
{
unsigned long tpidr, tpidrro;
- asm("mrs %0, tpidr_el0" : "=r" (tpidr));
+ tpidr = read_sysreg(tpidr_el0);
*task_user_tls(current) = tpidr;
tpidr = *task_user_tls(next);
tpidrro = is_compat_thread(task_thread_info(next)) ?
next->thread.tp_value : 0;
- asm(
- " msr tpidr_el0, %0\n"
- " msr tpidrro_el0, %1"
- : : "r" (tpidr), "r" (tpidrro));
+ write_sysreg(tpidr, tpidr_el0);
+ write_sysreg(tpidrro, tpidrro_el0);
}
/* Restore the UAO state depending on next's addr_limit */
@@ -374,12 +372,8 @@ unsigned long arch_align_stack(unsigned long sp)
unsigned long arch_randomize_brk(struct mm_struct *mm)
{
- unsigned long range_end = mm->brk;
-
if (is_compat_task())
- range_end += 0x02000000;
+ return randomize_page(mm->brk, 0x02000000);
else
- range_end += 0x40000000;
-
- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
+ return randomize_page(mm->brk, 0x40000000);
}
diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
index 51b73cdde287..ce704a4aeadd 100644
--- a/arch/arm64/kernel/relocate_kernel.S
+++ b/arch/arm64/kernel/relocate_kernel.S
@@ -34,7 +34,7 @@ ENTRY(arm64_relocate_new_kernel)
/* Setup the list loop variables. */
mov x17, x1 /* x17 = kimage_start */
mov x16, x0 /* x16 = kimage_head */
- dcache_line_size x15, x0 /* x15 = dcache line size */
+ raw_dcache_line_size x15, x0 /* x15 = dcache line size */
mov x14, xzr /* x14 = entry ptr */
mov x13, xzr /* x13 = copy dest */
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 536dce22fe76..f534f492a268 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -206,10 +206,15 @@ static void __init request_standard_resources(void)
for_each_memblock(memory, region) {
res = alloc_bootmem_low(sizeof(*res));
- res->name = "System RAM";
+ if (memblock_is_nomap(region)) {
+ res->name = "reserved";
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ } else {
+ res->name = "System RAM";
+ res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
+ }
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_SYSTEM_RAM | IORESOURCE_BUSY;
request_resource(&iomem_resource, res);
@@ -228,7 +233,7 @@ void __init setup_arch(char **cmdline_p)
{
pr_info("Boot CPU: AArch64 Processor [%08x]\n", read_cpuid_id());
- sprintf(init_utsname()->machine, ELF_PLATFORM);
+ sprintf(init_utsname()->machine, UTS_MACHINE);
init_mm.start_code = (unsigned long) _text;
init_mm.end_code = (unsigned long) _etext;
init_mm.end_data = (unsigned long) _edata;
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index a8eafdbc7cb8..404dd67080b9 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -402,15 +402,31 @@ static void do_signal(struct pt_regs *regs)
asmlinkage void do_notify_resume(struct pt_regs *regs,
unsigned int thread_flags)
{
- if (thread_flags & _TIF_SIGPENDING)
- do_signal(regs);
-
- if (thread_flags & _TIF_NOTIFY_RESUME) {
- clear_thread_flag(TIF_NOTIFY_RESUME);
- tracehook_notify_resume(regs);
- }
-
- if (thread_flags & _TIF_FOREIGN_FPSTATE)
- fpsimd_restore_current_state();
+ /*
+ * The assembly code enters us with IRQs off, but it hasn't
+ * informed the tracing code of that for efficiency reasons.
+ * Update the trace code with the current status.
+ */
+ trace_hardirqs_off();
+ do {
+ if (thread_flags & _TIF_NEED_RESCHED) {
+ schedule();
+ } else {
+ local_irq_enable();
+
+ if (thread_flags & _TIF_SIGPENDING)
+ do_signal(regs);
+
+ if (thread_flags & _TIF_NOTIFY_RESUME) {
+ clear_thread_flag(TIF_NOTIFY_RESUME);
+ tracehook_notify_resume(regs);
+ }
+
+ if (thread_flags & _TIF_FOREIGN_FPSTATE)
+ fpsimd_restore_current_state();
+ }
+ local_irq_disable();
+ thread_flags = READ_ONCE(current_thread_info()->flags);
+ } while (thread_flags & _TIF_WORK_MASK);
}
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index ccf79d849e0a..b8799e7c79de 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -73,10 +73,9 @@ ENTRY(__cpu_suspend_enter)
str x2, [x0, #SLEEP_STACK_DATA_SYSTEM_REGS + CPU_CTX_SP]
/* find the mpidr_hash */
- ldr x1, =sleep_save_stash
- ldr x1, [x1]
+ ldr_l x1, sleep_save_stash
mrs x7, mpidr_el1
- ldr x9, =mpidr_hash
+ adr_l x9, mpidr_hash
ldr x10, [x9, #MPIDR_HASH_MASK]
/*
* Following code relies on the struct mpidr_hash
@@ -95,36 +94,30 @@ ENTRY(__cpu_suspend_enter)
mov x0, #1
ret
ENDPROC(__cpu_suspend_enter)
- .ltorg
+ .pushsection ".idmap.text", "ax"
ENTRY(cpu_resume)
bl el2_setup // if in EL2 drop to EL1 cleanly
+ bl __cpu_setup
/* enable the MMU early - so we can access sleep_save_stash by va */
- adr_l lr, __enable_mmu /* __cpu_setup will return here */
- adr_l x27, _resume_switched /* __enable_mmu will branch here */
- adrp x25, idmap_pg_dir
- adrp x26, swapper_pg_dir
- b __cpu_setup
-ENDPROC(cpu_resume)
-
- .pushsection ".idmap.text", "ax"
-_resume_switched:
+ bl __enable_mmu
ldr x8, =_cpu_resume
br x8
-ENDPROC(_resume_switched)
+ENDPROC(cpu_resume)
.ltorg
.popsection
ENTRY(_cpu_resume)
mrs x1, mpidr_el1
- adrp x8, mpidr_hash
- add x8, x8, #:lo12:mpidr_hash // x8 = struct mpidr_hash phys address
- /* retrieve mpidr_hash members to compute the hash */
+ adr_l x8, mpidr_hash // x8 = struct mpidr_hash virt address
+
+ /* retrieve mpidr_hash members to compute the hash */
ldr x2, [x8, #MPIDR_HASH_MASK]
ldp w3, w4, [x8, #MPIDR_HASH_SHIFTS]
ldp w5, w6, [x8, #(MPIDR_HASH_SHIFTS + 8)]
compute_mpidr_hash x7, x3, x4, x5, x6, x1, x2
- /* x7 contains hash index, let's use it to grab context pointer */
+
+ /* x7 contains hash index, let's use it to grab context pointer */
ldr_l x0, sleep_save_stash
ldr x0, [x0, x7, lsl #3]
add x29, x0, #SLEEP_STACK_DATA_CALLEE_REGS
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 3ff173e92582..d3f151cfd4a1 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -233,7 +233,7 @@ asmlinkage void secondary_start_kernel(void)
* this CPU ticks all of those. If it doesn't, the CPU will
* fail to come online.
*/
- verify_local_cpu_capabilities();
+ check_local_cpu_capabilities();
if (cpu_ops[cpu]->cpu_postboot)
cpu_ops[cpu]->cpu_postboot();
@@ -431,8 +431,19 @@ void __init smp_cpus_done(unsigned int max_cpus)
void __init smp_prepare_boot_cpu(void)
{
set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
+ /*
+ * Initialise the static keys early as they may be enabled by the
+ * cpufeature code.
+ */
+ jump_label_init();
cpuinfo_store_boot_cpu();
save_boot_cpu_run_el();
+ /*
+ * Run the errata work around checks on the boot CPU, once we have
+ * initialised the cpu feature infrastructure from
+ * cpuinfo_store_boot_cpu() above.
+ */
+ update_cpu_errata_workarounds();
}
static u64 __init of_get_cpu_mpidr(struct device_node *dn)
@@ -613,6 +624,7 @@ static void __init of_parse_and_init_cpus(void)
}
bootcpu_valid = true;
+ early_map_cpu_to_node(0, of_node_to_nid(dn));
/*
* cpu_logical_map has already been
diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c
index 18a71bcd26ee..9a00eee9acc8 100644
--- a/arch/arm64/kernel/smp_spin_table.c
+++ b/arch/arm64/kernel/smp_spin_table.c
@@ -29,7 +29,8 @@
#include <asm/smp_plat.h>
extern void secondary_holding_pen(void);
-volatile unsigned long secondary_holding_pen_release = INVALID_HWID;
+volatile unsigned long __section(".mmuoff.data.read")
+secondary_holding_pen_release = INVALID_HWID;
static phys_addr_t cpu_release_addr[NR_CPUS];
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index d9751a4769e7..c2efddfca18c 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -43,6 +43,9 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
unsigned long fp = frame->fp;
unsigned long irq_stack_ptr;
+ if (!tsk)
+ tsk = current;
+
/*
* Switching between stacks is valid when tracing current and in
* non-preemptible context.
@@ -67,7 +70,7 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
- if (tsk && tsk->ret_stack &&
+ if (tsk->ret_stack &&
(frame->pc == (unsigned long)return_to_handler)) {
/*
* This is a case where function graph tracer has
@@ -152,6 +155,27 @@ static int save_trace(struct stackframe *frame, void *d)
return trace->nr_entries >= trace->max_entries;
}
+void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
+{
+ struct stack_trace_data data;
+ struct stackframe frame;
+
+ data.trace = trace;
+ data.skip = trace->skip;
+ data.no_sched_functions = 0;
+
+ frame.fp = regs->regs[29];
+ frame.sp = regs->sp;
+ frame.pc = regs->pc;
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ frame.graph = current->curr_ret_stack;
+#endif
+
+ walk_stackframe(current, &frame, save_trace, &data);
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
{
struct stack_trace_data data;
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index b616e365cee3..ad734142070d 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -23,8 +23,8 @@ unsigned long *sleep_save_stash;
* time the notifier runs debug exceptions might have been enabled already,
* with HW breakpoints registers content still in an unknown state.
*/
-static void (*hw_breakpoint_restore)(void *);
-void __init cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
+static int (*hw_breakpoint_restore)(unsigned int);
+void __init cpu_suspend_set_dbg_restorer(int (*hw_bp_restore)(unsigned int))
{
/* Prevent multiple restore hook initializations */
if (WARN_ON(hw_breakpoint_restore))
@@ -34,6 +34,8 @@ void __init cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
void notrace __cpu_suspend_exit(void)
{
+ unsigned int cpu = smp_processor_id();
+
/*
* We are resuming from reset with the idmap active in TTBR0_EL1.
* We must uninstall the idmap and restore the expected MMU
@@ -45,7 +47,7 @@ void notrace __cpu_suspend_exit(void)
* Restore per-cpu offset before any kernel
* subsystem relying on it has a chance to run.
*/
- set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
+ set_my_cpu_offset(per_cpu_offset(cpu));
/*
* Restore HW breakpoint registers to sane values
@@ -53,7 +55,7 @@ void notrace __cpu_suspend_exit(void)
* through local_dbg_restore.
*/
if (hw_breakpoint_restore)
- hw_breakpoint_restore(NULL);
+ hw_breakpoint_restore(cpu);
}
/*
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
index 28c511b06edf..abaf582fc7a8 100644
--- a/arch/arm64/kernel/sys_compat.c
+++ b/arch/arm64/kernel/sys_compat.c
@@ -94,7 +94,7 @@ long compat_arm_syscall(struct pt_regs *regs)
* See comment in tls_thread_flush.
*/
barrier();
- asm ("msr tpidrro_el0, %0" : : "r" (regs->regs[0]));
+ write_sysreg(regs->regs[0], tpidrro_el0);
return 0;
default:
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index e04f83873af7..5ff020f8fb7f 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -142,6 +142,11 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
unsigned long irq_stack_ptr;
int skip;
+ pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
+
+ if (!tsk)
+ tsk = current;
+
/*
* Switching between stacks is valid when tracing current and in
* non-preemptible context.
@@ -151,11 +156,6 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
else
irq_stack_ptr = 0;
- pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
-
- if (!tsk)
- tsk = current;
-
if (tsk == current) {
frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_stack_pointer;
@@ -447,36 +447,29 @@ void cpu_enable_cache_maint_trap(void *__unused)
: "=r" (res) \
: "r" (address), "i" (-EFAULT) )
-asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
+static void user_cache_maint_handler(unsigned int esr, struct pt_regs *regs)
{
unsigned long address;
- int ret;
-
- /* if this is a write with: Op0=1, Op2=1, Op1=3, CRn=7 */
- if ((esr & 0x01fffc01) == 0x0012dc00) {
- int rt = (esr >> 5) & 0x1f;
- int crm = (esr >> 1) & 0x0f;
+ int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
+ int crm = (esr & ESR_ELx_SYS64_ISS_CRM_MASK) >> ESR_ELx_SYS64_ISS_CRM_SHIFT;
+ int ret = 0;
- address = (rt == 31) ? 0 : regs->regs[rt];
+ address = (rt == 31) ? 0 : regs->regs[rt];
- switch (crm) {
- case 11: /* DC CVAU, gets promoted */
- __user_cache_maint("dc civac", address, ret);
- break;
- case 10: /* DC CVAC, gets promoted */
- __user_cache_maint("dc civac", address, ret);
- break;
- case 14: /* DC CIVAC */
- __user_cache_maint("dc civac", address, ret);
- break;
- case 5: /* IC IVAU */
- __user_cache_maint("ic ivau", address, ret);
- break;
- default:
- force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0);
- return;
- }
- } else {
+ switch (crm) {
+ case ESR_ELx_SYS64_ISS_CRM_DC_CVAU: /* DC CVAU, gets promoted */
+ __user_cache_maint("dc civac", address, ret);
+ break;
+ case ESR_ELx_SYS64_ISS_CRM_DC_CVAC: /* DC CVAC, gets promoted */
+ __user_cache_maint("dc civac", address, ret);
+ break;
+ case ESR_ELx_SYS64_ISS_CRM_DC_CIVAC: /* DC CIVAC */
+ __user_cache_maint("dc civac", address, ret);
+ break;
+ case ESR_ELx_SYS64_ISS_CRM_IC_IVAU: /* IC IVAU */
+ __user_cache_maint("ic ivau", address, ret);
+ break;
+ default:
force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0);
return;
}
@@ -487,6 +480,48 @@ asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
regs->pc += 4;
}
+static void ctr_read_handler(unsigned int esr, struct pt_regs *regs)
+{
+ int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
+
+ regs->regs[rt] = arm64_ftr_reg_ctrel0.sys_val;
+ regs->pc += 4;
+}
+
+struct sys64_hook {
+ unsigned int esr_mask;
+ unsigned int esr_val;
+ void (*handler)(unsigned int esr, struct pt_regs *regs);
+};
+
+static struct sys64_hook sys64_hooks[] = {
+ {
+ .esr_mask = ESR_ELx_SYS64_ISS_EL0_CACHE_OP_MASK,
+ .esr_val = ESR_ELx_SYS64_ISS_EL0_CACHE_OP_VAL,
+ .handler = user_cache_maint_handler,
+ },
+ {
+ /* Trap read access to CTR_EL0 */
+ .esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK,
+ .esr_val = ESR_ELx_SYS64_ISS_SYS_CTR_READ,
+ .handler = ctr_read_handler,
+ },
+ {},
+};
+
+asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
+{
+ struct sys64_hook *hook;
+
+ for (hook = sys64_hooks; hook->handler; hook++)
+ if ((hook->esr_mask & esr) == hook->esr_val) {
+ hook->handler(esr, regs);
+ return;
+ }
+
+ force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0);
+}
+
long compat_arm_syscall(struct pt_regs *regs);
asmlinkage long do_ni_syscall(struct pt_regs *regs)
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 076312b17d4f..a2c2478e7d78 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -18,12 +18,13 @@
* Author: Will Deacon <will.deacon@arm.com>
*/
-#include <linux/kernel.h>
+#include <linux/cache.h>
#include <linux/clocksource.h>
#include <linux/elf.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/gfp.h>
+#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/signal.h>
@@ -37,8 +38,7 @@
#include <asm/vdso_datapage.h>
extern char vdso_start, vdso_end;
-static unsigned long vdso_pages;
-static struct page **vdso_pagelist;
+static unsigned long vdso_pages __ro_after_init;
/*
* The vDSO data page.
@@ -53,9 +53,9 @@ struct vdso_data *vdso_data = &vdso_data_store.data;
/*
* Create and map the vectors page for AArch32 tasks.
*/
-static struct page *vectors_page[1];
+static struct page *vectors_page[1] __ro_after_init;
-static int alloc_vectors_page(void)
+static int __init alloc_vectors_page(void)
{
extern char __kuser_helper_start[], __kuser_helper_end[];
extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[];
@@ -88,7 +88,7 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
{
struct mm_struct *mm = current->mm;
unsigned long addr = AARCH32_VECTORS_BASE;
- static struct vm_special_mapping spec = {
+ static const struct vm_special_mapping spec = {
.name = "[vectors]",
.pages = vectors_page,
@@ -110,11 +110,19 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
}
#endif /* CONFIG_COMPAT */
-static struct vm_special_mapping vdso_spec[2];
+static struct vm_special_mapping vdso_spec[2] __ro_after_init = {
+ {
+ .name = "[vvar]",
+ },
+ {
+ .name = "[vdso]",
+ },
+};
static int __init vdso_init(void)
{
int i;
+ struct page **vdso_pagelist;
if (memcmp(&vdso_start, "\177ELF", 4)) {
pr_err("vDSO is not a valid ELF object!\n");
@@ -138,16 +146,8 @@ static int __init vdso_init(void)
for (i = 0; i < vdso_pages; i++)
vdso_pagelist[i + 1] = pfn_to_page(PHYS_PFN(__pa(&vdso_start)) + i);
- /* Populate the special mapping structures */
- vdso_spec[0] = (struct vm_special_mapping) {
- .name = "[vvar]",
- .pages = vdso_pagelist,
- };
-
- vdso_spec[1] = (struct vm_special_mapping) {
- .name = "[vdso]",
- .pages = &vdso_pagelist[1],
- };
+ vdso_spec[0].pages = &vdso_pagelist[0];
+ vdso_spec[1].pages = &vdso_pagelist[1];
return 0;
}
@@ -201,7 +201,7 @@ up_fail:
*/
void update_vsyscall(struct timekeeper *tk)
{
- u32 use_syscall = strcmp(tk->tkr_mono.clock->name, "arch_sys_counter");
+ u32 use_syscall = !tk->tkr_mono.clock->archdata.vdso_direct;
++vdso_data->tb_seq_count;
smp_wmb();
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 659963d40bb4..1105aab1e6d6 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -122,6 +122,7 @@ SECTIONS
ENTRY_TEXT
TEXT_TEXT
SCHED_TEXT
+ CPUIDLE_TEXT
LOCK_TEXT
KPROBES_TEXT
HYPERVISOR_TEXT
@@ -185,6 +186,25 @@ SECTIONS
_data = .;
_sdata = .;
RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+
+ /*
+ * Data written with the MMU off but read with the MMU on requires
+ * cache lines to be invalidated, discarding up to a Cache Writeback
+ * Granule (CWG) of data from the cache. Keep the section that
+ * requires this type of maintenance to be in its own Cache Writeback
+ * Granule (CWG) area so the cache maintenance operations don't
+ * interfere with adjacent data.
+ */
+ .mmuoff.data.write : ALIGN(SZ_2K) {
+ __mmuoff_data_start = .;
+ *(.mmuoff.data.write)
+ }
+ . = ALIGN(SZ_2K);
+ .mmuoff.data.read : {
+ *(.mmuoff.data.read)
+ __mmuoff_data_end = .;
+ }
+
PECOFF_EDATA_PADDING
_edata = .;
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 9c9edc98d271..6eaf12c1d627 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -16,7 +16,7 @@ menuconfig VIRTUALIZATION
if VIRTUALIZATION
-config KVM_ARM_VGIC_V3
+config KVM_ARM_VGIC_V3_ITS
bool
config KVM
@@ -34,7 +34,7 @@ config KVM
select KVM_VFIO
select HAVE_KVM_EVENTFD
select HAVE_KVM_IRQFD
- select KVM_ARM_VGIC_V3
+ select KVM_ARM_VGIC_V3_ITS
select KVM_ARM_PMU if HW_PERF_EVENTS
select HAVE_KVM_MSI
select HAVE_KVM_IRQCHIP
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 695eb3c7ef41..d50a82a16ff6 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -16,9 +16,10 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/e
kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/arm.o $(ARM)/mmu.o $(ARM)/mmio.o
kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/psci.o $(ARM)/perf.o
-kvm-$(CONFIG_KVM_ARM_HOST) += emulate.o inject_fault.o regmap.o
+kvm-$(CONFIG_KVM_ARM_HOST) += inject_fault.o regmap.o
kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o
kvm-$(CONFIG_KVM_ARM_HOST) += guest.o debug.o reset.o sys_regs.o sys_regs_generic_v8.o
+kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/aarch32.o
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic.o
kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-init.o
diff --git a/arch/arm64/kvm/emulate.c b/arch/arm64/kvm/emulate.c
deleted file mode 100644
index f87d8fbaa48d..000000000000
--- a/arch/arm64/kvm/emulate.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * (not much of an) Emulation layer for 32bit guests.
- *
- * Copyright (C) 2012,2013 - ARM Ltd
- * Author: Marc Zyngier <marc.zyngier@arm.com>
- *
- * based on arch/arm/kvm/emulate.c
- * Copyright (C) 2012 - Virtual Open Systems and Columbia University
- * Author: Christoffer Dall <c.dall@virtualopensystems.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/kvm_host.h>
-#include <asm/esr.h>
-#include <asm/kvm_emulate.h>
-
-/*
- * stolen from arch/arm/kernel/opcodes.c
- *
- * condition code lookup table
- * index into the table is test code: EQ, NE, ... LT, GT, AL, NV
- *
- * bit position in short is condition code: NZCV
- */
-static const unsigned short cc_map[16] = {
- 0xF0F0, /* EQ == Z set */
- 0x0F0F, /* NE */
- 0xCCCC, /* CS == C set */
- 0x3333, /* CC */
- 0xFF00, /* MI == N set */
- 0x00FF, /* PL */
- 0xAAAA, /* VS == V set */
- 0x5555, /* VC */
- 0x0C0C, /* HI == C set && Z clear */
- 0xF3F3, /* LS == C clear || Z set */
- 0xAA55, /* GE == (N==V) */
- 0x55AA, /* LT == (N!=V) */
- 0x0A05, /* GT == (!Z && (N==V)) */
- 0xF5FA, /* LE == (Z || (N!=V)) */
- 0xFFFF, /* AL always */
- 0 /* NV */
-};
-
-static int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu)
-{
- u32 esr = kvm_vcpu_get_hsr(vcpu);
-
- if (esr & ESR_ELx_CV)
- return (esr & ESR_ELx_COND_MASK) >> ESR_ELx_COND_SHIFT;
-
- return -1;
-}
-
-/*
- * Check if a trapped instruction should have been executed or not.
- */
-bool kvm_condition_valid32(const struct kvm_vcpu *vcpu)
-{
- unsigned long cpsr;
- u32 cpsr_cond;
- int cond;
-
- /* Top two bits non-zero? Unconditional. */
- if (kvm_vcpu_get_hsr(vcpu) >> 30)
- return true;
-
- /* Is condition field valid? */
- cond = kvm_vcpu_get_condition(vcpu);
- if (cond == 0xE)
- return true;
-
- cpsr = *vcpu_cpsr(vcpu);
-
- if (cond < 0) {
- /* This can happen in Thumb mode: examine IT state. */
- unsigned long it;
-
- it = ((cpsr >> 8) & 0xFC) | ((cpsr >> 25) & 0x3);
-
- /* it == 0 => unconditional. */
- if (it == 0)
- return true;
-
- /* The cond for this insn works out as the top 4 bits. */
- cond = (it >> 4);
- }
-
- cpsr_cond = cpsr >> 28;
-
- if (!((cc_map[cond] >> cpsr_cond) & 1))
- return false;
-
- return true;
-}
-
-/**
- * adjust_itstate - adjust ITSTATE when emulating instructions in IT-block
- * @vcpu: The VCPU pointer
- *
- * When exceptions occur while instructions are executed in Thumb IF-THEN
- * blocks, the ITSTATE field of the CPSR is not advanced (updated), so we have
- * to do this little bit of work manually. The fields map like this:
- *
- * IT[7:0] -> CPSR[26:25],CPSR[15:10]
- */
-static void kvm_adjust_itstate(struct kvm_vcpu *vcpu)
-{
- unsigned long itbits, cond;
- unsigned long cpsr = *vcpu_cpsr(vcpu);
- bool is_arm = !(cpsr & COMPAT_PSR_T_BIT);
-
- BUG_ON(is_arm && (cpsr & COMPAT_PSR_IT_MASK));
-
- if (!(cpsr & COMPAT_PSR_IT_MASK))
- return;
-
- cond = (cpsr & 0xe000) >> 13;
- itbits = (cpsr & 0x1c00) >> (10 - 2);
- itbits |= (cpsr & (0x3 << 25)) >> 25;
-
- /* Perform ITAdvance (see page A2-52 in ARM DDI 0406C) */
- if ((itbits & 0x7) == 0)
- itbits = cond = 0;
- else
- itbits = (itbits << 1) & 0x1f;
-
- cpsr &= ~COMPAT_PSR_IT_MASK;
- cpsr |= cond << 13;
- cpsr |= (itbits & 0x1c) << (10 - 2);
- cpsr |= (itbits & 0x3) << 25;
- *vcpu_cpsr(vcpu) = cpsr;
-}
-
-/**
- * kvm_skip_instr - skip a trapped instruction and proceed to the next
- * @vcpu: The vcpu pointer
- */
-void kvm_skip_instr32(struct kvm_vcpu *vcpu, bool is_wide_instr)
-{
- bool is_thumb;
-
- is_thumb = !!(*vcpu_cpsr(vcpu) & COMPAT_PSR_T_BIT);
- if (is_thumb && !is_wide_instr)
- *vcpu_pc(vcpu) += 2;
- else
- *vcpu_pc(vcpu) += 4;
- kvm_adjust_itstate(vcpu);
-}
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index fa96fe2bd469..a204adf29f0a 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -170,9 +170,32 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
{
exit_handle_fn exit_handler;
+ if (ARM_SERROR_PENDING(exception_index)) {
+ u8 hsr_ec = ESR_ELx_EC(kvm_vcpu_get_hsr(vcpu));
+
+ /*
+ * HVC/SMC already have an adjusted PC, which we need
+ * to correct in order to return to after having
+ * injected the SError.
+ */
+ if (hsr_ec == ESR_ELx_EC_HVC32 || hsr_ec == ESR_ELx_EC_HVC64 ||
+ hsr_ec == ESR_ELx_EC_SMC32 || hsr_ec == ESR_ELx_EC_SMC64) {
+ u32 adj = kvm_vcpu_trap_il_is32bit(vcpu) ? 4 : 2;
+ *vcpu_pc(vcpu) -= adj;
+ }
+
+ kvm_inject_vabt(vcpu);
+ return 1;
+ }
+
+ exception_index = ARM_EXCEPTION_CODE(exception_index);
+
switch (exception_index) {
case ARM_EXCEPTION_IRQ:
return 1;
+ case ARM_EXCEPTION_EL1_SERROR:
+ kvm_inject_vabt(vcpu);
+ return 1;
case ARM_EXCEPTION_TRAP:
/*
* See ARM ARM B1.14.1: "Hyp traps on instructions
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 7ce931565151..2726635dceba 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -46,10 +46,6 @@ alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
hvc #0
ldr lr, [sp], #16
ret
-alternative_else
+alternative_else_nop_endif
b __vhe_hyp_call
- nop
- nop
- nop
-alternative_endif
ENDPROC(__kvm_call_hyp)
diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
index 0c85febcc1eb..aaf42ae8d8c3 100644
--- a/arch/arm64/kvm/hyp/Makefile
+++ b/arch/arm64/kvm/hyp/Makefile
@@ -5,9 +5,9 @@
KVM=../../../../virt/kvm
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v3-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) += sysreg-sr.o
obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o
obj-$(CONFIG_KVM_ARM_HOST) += entry.o
diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
index 33342a776ec7..4ba5c9095d03 100644
--- a/arch/arm64/kvm/hyp/debug-sr.c
+++ b/arch/arm64/kvm/hyp/debug-sr.c
@@ -131,9 +131,7 @@ void __hyp_text __debug_cond_restore_host_state(struct kvm_vcpu *vcpu)
vcpu->arch.debug_flags &= ~KVM_ARM64_DEBUG_DIRTY;
}
-static u32 __hyp_text __debug_read_mdcr_el2(void)
+u32 __hyp_text __kvm_get_mdcr_el2(void)
{
return read_sysreg(mdcr_el2);
}
-
-__alias(__debug_read_mdcr_el2) u32 __kvm_get_mdcr_el2(void);
diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
index ce9e5e5f28cf..12ee62d6d410 100644
--- a/arch/arm64/kvm/hyp/entry.S
+++ b/arch/arm64/kvm/hyp/entry.S
@@ -55,79 +55,111 @@
*/
ENTRY(__guest_enter)
// x0: vcpu
- // x1: host/guest context
- // x2-x18: clobbered by macros
+ // x1: host context
+ // x2-x17: clobbered by macros
+ // x18: guest context
// Store the host regs
save_callee_saved_regs x1
- // Preserve vcpu & host_ctxt for use at exit time
- stp x0, x1, [sp, #-16]!
+ // Store the host_ctxt for use at exit time
+ str x1, [sp, #-16]!
- add x1, x0, #VCPU_CONTEXT
+ add x18, x0, #VCPU_CONTEXT
- // Prepare x0-x1 for later restore by pushing them onto the stack
- ldp x2, x3, [x1, #CPU_XREG_OFFSET(0)]
- stp x2, x3, [sp, #-16]!
+ // Restore guest regs x0-x17
+ ldp x0, x1, [x18, #CPU_XREG_OFFSET(0)]
+ ldp x2, x3, [x18, #CPU_XREG_OFFSET(2)]
+ ldp x4, x5, [x18, #CPU_XREG_OFFSET(4)]
+ ldp x6, x7, [x18, #CPU_XREG_OFFSET(6)]
+ ldp x8, x9, [x18, #CPU_XREG_OFFSET(8)]
+ ldp x10, x11, [x18, #CPU_XREG_OFFSET(10)]
+ ldp x12, x13, [x18, #CPU_XREG_OFFSET(12)]
+ ldp x14, x15, [x18, #CPU_XREG_OFFSET(14)]
+ ldp x16, x17, [x18, #CPU_XREG_OFFSET(16)]
- // x2-x18
- ldp x2, x3, [x1, #CPU_XREG_OFFSET(2)]
- ldp x4, x5, [x1, #CPU_XREG_OFFSET(4)]
- ldp x6, x7, [x1, #CPU_XREG_OFFSET(6)]
- ldp x8, x9, [x1, #CPU_XREG_OFFSET(8)]
- ldp x10, x11, [x1, #CPU_XREG_OFFSET(10)]
- ldp x12, x13, [x1, #CPU_XREG_OFFSET(12)]
- ldp x14, x15, [x1, #CPU_XREG_OFFSET(14)]
- ldp x16, x17, [x1, #CPU_XREG_OFFSET(16)]
- ldr x18, [x1, #CPU_XREG_OFFSET(18)]
-
- // x19-x29, lr
- restore_callee_saved_regs x1
-
- // Last bits of the 64bit state
- ldp x0, x1, [sp], #16
+ // Restore guest regs x19-x29, lr
+ restore_callee_saved_regs x18
+
+ // Restore guest reg x18
+ ldr x18, [x18, #CPU_XREG_OFFSET(18)]
// Do not touch any register after this!
eret
ENDPROC(__guest_enter)
ENTRY(__guest_exit)
- // x0: vcpu
- // x1: return code
- // x2-x3: free
- // x4-x29,lr: vcpu regs
- // vcpu x0-x3 on the stack
+ // x0: return code
+ // x1: vcpu
+ // x2-x29,lr: vcpu regs
+ // vcpu x0-x1 on the stack
- add x2, x0, #VCPU_CONTEXT
+ add x1, x1, #VCPU_CONTEXT
- stp x4, x5, [x2, #CPU_XREG_OFFSET(4)]
- stp x6, x7, [x2, #CPU_XREG_OFFSET(6)]
- stp x8, x9, [x2, #CPU_XREG_OFFSET(8)]
- stp x10, x11, [x2, #CPU_XREG_OFFSET(10)]
- stp x12, x13, [x2, #CPU_XREG_OFFSET(12)]
- stp x14, x15, [x2, #CPU_XREG_OFFSET(14)]
- stp x16, x17, [x2, #CPU_XREG_OFFSET(16)]
- str x18, [x2, #CPU_XREG_OFFSET(18)]
+ ALTERNATIVE(nop, SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
- ldp x6, x7, [sp], #16 // x2, x3
- ldp x4, x5, [sp], #16 // x0, x1
+ // Store the guest regs x2 and x3
+ stp x2, x3, [x1, #CPU_XREG_OFFSET(2)]
- stp x4, x5, [x2, #CPU_XREG_OFFSET(0)]
- stp x6, x7, [x2, #CPU_XREG_OFFSET(2)]
+ // Retrieve the guest regs x0-x1 from the stack
+ ldp x2, x3, [sp], #16 // x0, x1
+
+ // Store the guest regs x0-x1 and x4-x18
+ stp x2, x3, [x1, #CPU_XREG_OFFSET(0)]
+ stp x4, x5, [x1, #CPU_XREG_OFFSET(4)]
+ stp x6, x7, [x1, #CPU_XREG_OFFSET(6)]
+ stp x8, x9, [x1, #CPU_XREG_OFFSET(8)]
+ stp x10, x11, [x1, #CPU_XREG_OFFSET(10)]
+ stp x12, x13, [x1, #CPU_XREG_OFFSET(12)]
+ stp x14, x15, [x1, #CPU_XREG_OFFSET(14)]
+ stp x16, x17, [x1, #CPU_XREG_OFFSET(16)]
+ str x18, [x1, #CPU_XREG_OFFSET(18)]
+
+ // Store the guest regs x19-x29, lr
+ save_callee_saved_regs x1
- save_callee_saved_regs x2
+ // Restore the host_ctxt from the stack
+ ldr x2, [sp], #16
- // Restore vcpu & host_ctxt from the stack
- // (preserving return code in x1)
- ldp x0, x2, [sp], #16
// Now restore the host regs
restore_callee_saved_regs x2
- mov x0, x1
- ret
+ // If we have a pending asynchronous abort, now is the
+ // time to find out. From your VAXorcist book, page 666:
+ // "Threaten me not, oh Evil one! For I speak with
+ // the power of DEC, and I command thee to show thyself!"
+ mrs x2, elr_el2
+ mrs x3, esr_el2
+ mrs x4, spsr_el2
+ mov x5, x0
+
+ dsb sy // Synchronize against in-flight ld/st
+ msr daifclr, #4 // Unmask aborts
+
+ // This is our single instruction exception window. A pending
+ // SError is guaranteed to occur at the earliest when we unmask
+ // it, and at the latest just after the ISB.
+ .global abort_guest_exit_start
+abort_guest_exit_start:
+
+ isb
+
+ .global abort_guest_exit_end
+abort_guest_exit_end:
+
+ // If the exception took place, restore the EL1 exception
+ // context so that we can report some information.
+ // Merge the exception code with the SError pending bit.
+ tbz x0, #ARM_EXIT_WITH_SERROR_BIT, 1f
+ msr elr_el2, x2
+ msr esr_el2, x3
+ msr spsr_el2, x4
+ orr x0, x0, x5
+1: ret
ENDPROC(__guest_exit)
ENTRY(__fpsimd_guest_restore)
+ stp x2, x3, [sp, #-16]!
stp x4, lr, [sp, #-16]!
alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index f6d9694ae3b1..4e92399f7105 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -27,16 +27,6 @@
.text
.pushsection .hyp.text, "ax"
-.macro save_x0_to_x3
- stp x0, x1, [sp, #-16]!
- stp x2, x3, [sp, #-16]!
-.endm
-
-.macro restore_x0_to_x3
- ldp x2, x3, [sp], #16
- ldp x0, x1, [sp], #16
-.endm
-
.macro do_el2_call
/*
* Shuffle the parameters before calling the function
@@ -79,23 +69,23 @@ ENTRY(__kvm_hyp_teardown)
ENDPROC(__kvm_hyp_teardown)
el1_sync: // Guest trapped into EL2
- save_x0_to_x3
+ stp x0, x1, [sp, #-16]!
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
+ lsr x0, x1, #ESR_ELx_EC_SHIFT
- cmp x2, #ESR_ELx_EC_HVC64
+ cmp x0, #ESR_ELx_EC_HVC64
b.ne el1_trap
- mrs x3, vttbr_el2 // If vttbr is valid, the 64bit guest
- cbnz x3, el1_trap // called HVC
+ mrs x1, vttbr_el2 // If vttbr is valid, the 64bit guest
+ cbnz x1, el1_trap // called HVC
/* Here, we're pretty sure the host called HVC. */
- restore_x0_to_x3
+ ldp x0, x1, [sp], #16
cmp x0, #HVC_GET_VECTORS
b.ne 1f
@@ -113,24 +103,51 @@ alternative_endif
el1_trap:
/*
- * x1: ESR
- * x2: ESR_EC
+ * x0: ESR_EC
*/
/* Guest accessed VFP/SIMD registers, save host, restore Guest */
- cmp x2, #ESR_ELx_EC_FP_ASIMD
+ cmp x0, #ESR_ELx_EC_FP_ASIMD
b.eq __fpsimd_guest_restore
- mrs x0, tpidr_el2
- mov x1, #ARM_EXCEPTION_TRAP
+ mrs x1, tpidr_el2
+ mov x0, #ARM_EXCEPTION_TRAP
b __guest_exit
el1_irq:
- save_x0_to_x3
- mrs x0, tpidr_el2
- mov x1, #ARM_EXCEPTION_IRQ
+ stp x0, x1, [sp, #-16]!
+ mrs x1, tpidr_el2
+ mov x0, #ARM_EXCEPTION_IRQ
+ b __guest_exit
+
+el1_error:
+ stp x0, x1, [sp, #-16]!
+ mrs x1, tpidr_el2
+ mov x0, #ARM_EXCEPTION_EL1_SERROR
b __guest_exit
+el2_error:
+ /*
+ * Only two possibilities:
+ * 1) Either we come from the exit path, having just unmasked
+ * PSTATE.A: change the return code to an EL2 fault, and
+ * carry on, as we're already in a sane state to handle it.
+ * 2) Or we come from anywhere else, and that's a bug: we panic.
+ *
+ * For (1), x0 contains the original return code and x1 doesn't
+ * contain anything meaningful at that stage. We can reuse them
+ * as temp registers.
+ * For (2), who cares?
+ */
+ mrs x0, elr_el2
+ adr x1, abort_guest_exit_start
+ cmp x0, x1
+ adr x1, abort_guest_exit_end
+ ccmp x0, x1, #4, ne
+ b.ne __hyp_panic
+ mov x0, #(1 << ARM_EXIT_WITH_SERROR_BIT)
+ eret
+
ENTRY(__hyp_do_panic)
mov lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
PSR_MODE_EL1h)
@@ -155,11 +172,9 @@ ENDPROC(\label)
invalid_vector el2h_sync_invalid
invalid_vector el2h_irq_invalid
invalid_vector el2h_fiq_invalid
- invalid_vector el2h_error_invalid
invalid_vector el1_sync_invalid
invalid_vector el1_irq_invalid
invalid_vector el1_fiq_invalid
- invalid_vector el1_error_invalid
.ltorg
@@ -174,15 +189,15 @@ ENTRY(__kvm_hyp_vector)
ventry el2h_sync_invalid // Synchronous EL2h
ventry el2h_irq_invalid // IRQ EL2h
ventry el2h_fiq_invalid // FIQ EL2h
- ventry el2h_error_invalid // Error EL2h
+ ventry el2_error // Error EL2h
ventry el1_sync // Synchronous 64-bit EL1
ventry el1_irq // IRQ 64-bit EL1
ventry el1_fiq_invalid // FIQ 64-bit EL1
- ventry el1_error_invalid // Error 64-bit EL1
+ ventry el1_error // Error 64-bit EL1
ventry el1_sync // Synchronous 32-bit EL1
ventry el1_irq // IRQ 32-bit EL1
ventry el1_fiq_invalid // FIQ 32-bit EL1
- ventry el1_error_invalid // Error 32-bit EL1
+ ventry el1_error // Error 32-bit EL1
ENDPROC(__kvm_hyp_vector)
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 5a84b4562603..83037cd62d01 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -16,7 +16,10 @@
*/
#include <linux/types.h>
+#include <linux/jump_label.h>
+
#include <asm/kvm_asm.h>
+#include <asm/kvm_emulate.h>
#include <asm/kvm_hyp.h>
static bool __hyp_text __fpsimd_enabled_nvhe(void)
@@ -109,6 +112,15 @@ static hyp_alternate_select(__deactivate_traps_arch,
static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
{
+ /*
+ * If we pended a virtual abort, preserve it until it gets
+ * cleared. See D1.14.3 (Virtual Interrupts) for details, but
+ * the crucial bit is "On taking a vSError interrupt,
+ * HCR_EL2.VSE is cleared to 0."
+ */
+ if (vcpu->arch.hcr_el2 & HCR_VSE)
+ vcpu->arch.hcr_el2 = read_sysreg(hcr_el2);
+
__deactivate_traps_arch()();
write_sysreg(0, hstr_el2);
write_sysreg(read_sysreg(mdcr_el2) & MDCR_EL2_HPMN_MASK, mdcr_el2);
@@ -126,17 +138,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
write_sysreg(0, vttbr_el2);
}
-static hyp_alternate_select(__vgic_call_save_state,
- __vgic_v2_save_state, __vgic_v3_save_state,
- ARM64_HAS_SYSREG_GIC_CPUIF);
-
-static hyp_alternate_select(__vgic_call_restore_state,
- __vgic_v2_restore_state, __vgic_v3_restore_state,
- ARM64_HAS_SYSREG_GIC_CPUIF);
-
static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
{
- __vgic_call_save_state()(vcpu);
+ if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
+ __vgic_v3_save_state(vcpu);
+ else
+ __vgic_v2_save_state(vcpu);
+
write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
}
@@ -149,7 +157,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
val |= vcpu->arch.irq_lines;
write_sysreg(val, hcr_el2);
- __vgic_call_restore_state()(vcpu);
+ if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
+ __vgic_v3_restore_state(vcpu);
+ else
+ __vgic_v2_restore_state(vcpu);
}
static bool __hyp_text __true_value(void)
@@ -232,7 +243,22 @@ static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
return true;
}
-static int __hyp_text __guest_run(struct kvm_vcpu *vcpu)
+static void __hyp_text __skip_instr(struct kvm_vcpu *vcpu)
+{
+ *vcpu_pc(vcpu) = read_sysreg_el2(elr);
+
+ if (vcpu_mode_is_32bit(vcpu)) {
+ vcpu->arch.ctxt.gp_regs.regs.pstate = read_sysreg_el2(spsr);
+ kvm_skip_instr32(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+ write_sysreg_el2(vcpu->arch.ctxt.gp_regs.regs.pstate, spsr);
+ } else {
+ *vcpu_pc(vcpu) += 4;
+ }
+
+ write_sysreg_el2(*vcpu_pc(vcpu), elr);
+}
+
+int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
{
struct kvm_cpu_context *host_ctxt;
struct kvm_cpu_context *guest_ctxt;
@@ -267,9 +293,43 @@ again:
exit_code = __guest_enter(vcpu, host_ctxt);
/* And we're baaack! */
+ /*
+ * We're using the raw exception code in order to only process
+ * the trap if no SError is pending. We will come back to the
+ * same PC once the SError has been injected, and replay the
+ * trapping instruction.
+ */
if (exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu))
goto again;
+ if (static_branch_unlikely(&vgic_v2_cpuif_trap) &&
+ exit_code == ARM_EXCEPTION_TRAP) {
+ bool valid;
+
+ valid = kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_DABT_LOW &&
+ kvm_vcpu_trap_get_fault_type(vcpu) == FSC_FAULT &&
+ kvm_vcpu_dabt_isvalid(vcpu) &&
+ !kvm_vcpu_dabt_isextabt(vcpu) &&
+ !kvm_vcpu_dabt_iss1tw(vcpu);
+
+ if (valid) {
+ int ret = __vgic_v2_perform_cpuif_access(vcpu);
+
+ if (ret == 1) {
+ __skip_instr(vcpu);
+ goto again;
+ }
+
+ if (ret == -1) {
+ /* Promote an illegal access to an SError */
+ __skip_instr(vcpu);
+ exit_code = ARM_EXCEPTION_EL1_SERROR;
+ }
+
+ /* 0 falls through to be handler out of EL2 */
+ }
+ }
+
fp_enabled = __fpsimd_enabled();
__sysreg_save_guest_state(guest_ctxt);
@@ -293,8 +353,6 @@ again:
return exit_code;
}
-__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";
static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par)
diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c
index be8177cdd3bf..9cc0ea784ae6 100644
--- a/arch/arm64/kvm/hyp/tlb.c
+++ b/arch/arm64/kvm/hyp/tlb.c
@@ -17,7 +17,7 @@
#include <asm/kvm_hyp.h>
-static void __hyp_text __tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
+void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
{
dsb(ishst);
@@ -48,10 +48,7 @@ static void __hyp_text __tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
write_sysreg(0, vttbr_el2);
}
-__alias(__tlb_flush_vmid_ipa) void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm,
- phys_addr_t ipa);
-
-static void __hyp_text __tlb_flush_vmid(struct kvm *kvm)
+void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
{
dsb(ishst);
@@ -67,14 +64,10 @@ static void __hyp_text __tlb_flush_vmid(struct kvm *kvm)
write_sysreg(0, vttbr_el2);
}
-__alias(__tlb_flush_vmid) void __kvm_tlb_flush_vmid(struct kvm *kvm);
-
-static void __hyp_text __tlb_flush_vm_context(void)
+void __hyp_text __kvm_flush_vm_context(void)
{
dsb(ishst);
asm volatile("tlbi alle1is \n"
"ic ialluis ": : );
dsb(ish);
}
-
-__alias(__tlb_flush_vm_context) void __kvm_flush_vm_context(void);
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
deleted file mode 100644
index 5f8f80b4a224..000000000000
--- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
+++ /dev/null
@@ -1,343 +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-v3.h>
-#include <linux/kvm_host.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)
-
-#define read_gicreg(r) \
- ({ \
- u64 reg; \
- asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg)); \
- reg; \
- })
-
-#define write_gicreg(v,r) \
- do { \
- u64 __val = (v); \
- asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
- } while (0)
-
-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;
-
- /*
- * Make sure stores to the GIC via the memory mapped interface
- * are now visible to the system register interface.
- */
- if (!cpu_if->vgic_sre)
- dsb(st);
-
- cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2);
-
- if (vcpu->arch.vgic_cpu.live_lrs) {
- int i;
- u32 max_lr_idx, nr_pri_bits;
-
- 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);
-
- 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;
- else
- 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);
- write_gicreg(val | ICC_SRE_EL2_ENABLE, ICC_SRE_EL2);
-
- if (!cpu_if->vgic_sre) {
- /* Make sure ENABLE is set at EL2 before setting SRE at EL1 */
- isb();
- write_gicreg(1, ICC_SRE_EL1);
- }
-}
-
-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
- * Group0 interrupt (as generated in GICv2 mode) to be
- * delivered as a FIQ to the guest, with potentially fatal
- * consequences. So we must make sure that ICC_SRE_EL1 has
- * been actually programmed with the value we want before
- * starting to mess with the rest of the GIC.
- */
- if (!cpu_if->vgic_sre) {
- write_gicreg(0, ICC_SRE_EL1);
- isb();
- }
-
- val = read_gicreg(ICH_VTR_EL2);
- max_lr_idx = vtr_to_max_lr_idx(val);
- nr_pri_bits = vtr_to_nr_pri_bits(val);
-
- for (i = 0; i <= max_lr_idx; i++) {
- if (cpu_if->vgic_lr[i] & ICH_LR_STATE)
- live_lrs |= (1 << i);
- }
-
- 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);
- }
- }
-
- /*
- * Ensures that the above will have reached the
- * (re)distributors. This ensure the guest will read the
- * correct values from the memory-mapped interface.
- */
- if (!cpu_if->vgic_sre) {
- isb();
- dsb(sy);
- }
- vcpu->arch.vgic_cpu.live_lrs = live_lrs;
-
- /*
- * Prevent the guest from touching the GIC system registers if
- * SRE isn't enabled for GICv3 emulation.
- */
- write_gicreg(read_gicreg(ICC_SRE_EL2) & ~ICC_SRE_EL2_ENABLE,
- ICC_SRE_EL2);
-}
-
-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);
-}
-
-__alias(__vgic_v3_read_ich_vtr_el2) u64 __vgic_v3_get_ich_vtr_el2(void);
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index 898c0e6aedd4..da6a8cfa54a0 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -231,3 +231,15 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
else
inject_undef64(vcpu);
}
+
+/**
+ * kvm_inject_vabt - inject an async abort / SError into the guest
+ * @vcpu: The VCPU to receive the exception
+ *
+ * It is assumed that this code is called from the VCPU thread and that the
+ * VCPU therefore is not currently executing guest code.
+ */
+void kvm_inject_vabt(struct kvm_vcpu *vcpu)
+{
+ vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
+}
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index e51367d159d0..f302fdb3a030 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -36,6 +36,7 @@
#include <asm/kvm_host.h>
#include <asm/kvm_mmu.h>
#include <asm/perf_event.h>
+#include <asm/sysreg.h>
#include <trace/events/kvm.h>
@@ -67,11 +68,9 @@ static u32 get_ccsidr(u32 csselr)
/* Make sure noone else changes CSSELR during this! */
local_irq_disable();
- /* Put value into CSSELR */
- asm volatile("msr csselr_el1, %x0" : : "r" (csselr));
+ write_sysreg(csselr, csselr_el1);
isb();
- /* Read result out of CCSIDR */
- asm volatile("mrs %0, ccsidr_el1" : "=r" (ccsidr));
+ ccsidr = read_sysreg(ccsidr_el1);
local_irq_enable();
return ccsidr;
@@ -174,9 +173,7 @@ static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
if (p->is_write) {
return ignore_write(vcpu, p);
} else {
- u32 val;
- asm volatile("mrs %0, dbgauthstatus_el1" : "=r" (val));
- p->regval = val;
+ p->regval = read_sysreg(dbgauthstatus_el1);
return true;
}
}
@@ -429,10 +426,7 @@ static void reset_wcr(struct kvm_vcpu *vcpu,
static void reset_amair_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
{
- u64 amair;
-
- asm volatile("mrs %0, amair_el1\n" : "=r" (amair));
- vcpu_sys_reg(vcpu, AMAIR_EL1) = amair;
+ vcpu_sys_reg(vcpu, AMAIR_EL1) = read_sysreg(amair_el1);
}
static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
@@ -456,8 +450,9 @@ 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
+ pmcr = read_sysreg(pmcr_el0);
+ /*
+ * Writable bits of PMCR_EL0 (ARMV8_PMU_PMCR_MASK) are reset to UNKNOWN
* except PMCR.E resetting to zero.
*/
val = ((pmcr & ~ARMV8_PMU_PMCR_MASK)
@@ -557,9 +552,9 @@ static bool access_pmceid(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
return false;
if (!(p->Op2 & 1))
- asm volatile("mrs %0, pmceid0_el0\n" : "=r" (pmceid));
+ pmceid = read_sysreg(pmceid0_el0);
else
- asm volatile("mrs %0, pmceid1_el0\n" : "=r" (pmceid));
+ pmceid = read_sysreg(pmceid1_el0);
p->regval = pmceid;
@@ -1833,11 +1828,7 @@ static const struct sys_reg_desc *index_to_sys_reg_desc(struct kvm_vcpu *vcpu,
static void get_##reg(struct kvm_vcpu *v, \
const struct sys_reg_desc *r) \
{ \
- u64 val; \
- \
- asm volatile("mrs %0, " __stringify(reg) "\n" \
- : "=r" (val)); \
- ((struct sys_reg_desc *)r)->val = val; \
+ ((struct sys_reg_desc *)r)->val = read_sysreg(reg); \
}
FUNCTION_INVARIANT(midr_el1)
diff --git a/arch/arm64/kvm/sys_regs_generic_v8.c b/arch/arm64/kvm/sys_regs_generic_v8.c
index ed90578fa120..46af7186bca6 100644
--- a/arch/arm64/kvm/sys_regs_generic_v8.c
+++ b/arch/arm64/kvm/sys_regs_generic_v8.c
@@ -26,6 +26,7 @@
#include <asm/kvm_host.h>
#include <asm/kvm_emulate.h>
#include <asm/kvm_coproc.h>
+#include <asm/sysreg.h>
#include <linux/init.h>
#include "sys_regs.h"
@@ -43,10 +44,7 @@ static bool access_actlr(struct kvm_vcpu *vcpu,
static void reset_actlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
{
- u64 actlr;
-
- asm volatile("mrs %0, actlr_el1\n" : "=r" (actlr));
- vcpu_sys_reg(vcpu, ACTLR_EL1) = actlr;
+ vcpu_sys_reg(vcpu, ACTLR_EL1) = read_sysreg(actlr_el1);
}
/*
diff --git a/arch/arm64/lib/copy_page.S b/arch/arm64/lib/copy_page.S
index 4c1e700840b6..c3cd65e31814 100644
--- a/arch/arm64/lib/copy_page.S
+++ b/arch/arm64/lib/copy_page.S
@@ -29,14 +29,11 @@
* x1 - src
*/
ENTRY(copy_page)
-alternative_if_not ARM64_HAS_NO_HW_PREFETCH
- nop
- nop
-alternative_else
+alternative_if ARM64_HAS_NO_HW_PREFETCH
# Prefetch two cache lines ahead.
prfm pldl1strm, [x1, #128]
prfm pldl1strm, [x1, #256]
-alternative_endif
+alternative_else_nop_endif
ldp x2, x3, [x1]
ldp x4, x5, [x1, #16]
@@ -52,11 +49,9 @@ alternative_endif
1:
subs x18, x18, #128
-alternative_if_not ARM64_HAS_NO_HW_PREFETCH
- nop
-alternative_else
+alternative_if ARM64_HAS_NO_HW_PREFETCH
prfm pldl1strm, [x1, #384]
-alternative_endif
+alternative_else_nop_endif
stnp x2, x3, [x0]
ldp x2, x3, [x1]
diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
index 07d7352d7c38..58b5a906ff78 100644
--- a/arch/arm64/mm/cache.S
+++ b/arch/arm64/mm/cache.S
@@ -105,19 +105,20 @@ ENTRY(__clean_dcache_area_pou)
ENDPROC(__clean_dcache_area_pou)
/*
- * __inval_cache_range(start, end)
- * - start - start address of region
- * - end - end address of region
+ * __dma_inv_area(start, size)
+ * - start - virtual start address of region
+ * - size - size in question
*/
-ENTRY(__inval_cache_range)
+__dma_inv_area:
+ add x1, x1, x0
/* FALLTHROUGH */
/*
- * __dma_inv_range(start, end)
- * - start - virtual start address of region
- * - end - virtual end address of region
+ * __inval_cache_range(start, end)
+ * - start - start address of region
+ * - end - end address of region
*/
-__dma_inv_range:
+ENTRY(__inval_cache_range)
dcache_line_size x2, x3
sub x3, x2, #1
tst x1, x3 // end cache line aligned?
@@ -136,46 +137,43 @@ __dma_inv_range:
dsb sy
ret
ENDPIPROC(__inval_cache_range)
-ENDPROC(__dma_inv_range)
+ENDPROC(__dma_inv_area)
+
+/*
+ * __clean_dcache_area_poc(kaddr, size)
+ *
+ * Ensure that any D-cache lines for the interval [kaddr, kaddr+size)
+ * are cleaned to the PoC.
+ *
+ * - kaddr - kernel address
+ * - size - size in question
+ */
+ENTRY(__clean_dcache_area_poc)
+ /* FALLTHROUGH */
/*
- * __dma_clean_range(start, end)
+ * __dma_clean_area(start, size)
* - start - virtual start address of region
- * - end - virtual end address of region
+ * - size - size in question
*/
-__dma_clean_range:
- dcache_line_size x2, x3
- sub x3, x2, #1
- bic x0, x0, x3
-1:
-alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE
- dc cvac, x0
-alternative_else
- dc civac, x0
-alternative_endif
- add x0, x0, x2
- cmp x0, x1
- b.lo 1b
- dsb sy
+__dma_clean_area:
+ dcache_by_line_op cvac, sy, x0, x1, x2, x3
ret
-ENDPROC(__dma_clean_range)
+ENDPIPROC(__clean_dcache_area_poc)
+ENDPROC(__dma_clean_area)
/*
- * __dma_flush_range(start, end)
+ * __dma_flush_area(start, size)
+ *
+ * clean & invalidate D / U line
+ *
* - start - virtual start address of region
- * - end - virtual end address of region
+ * - size - size in question
*/
-ENTRY(__dma_flush_range)
- dcache_line_size x2, x3
- sub x3, x2, #1
- bic x0, x0, x3
-1: dc civac, x0 // clean & invalidate D / U line
- add x0, x0, x2
- cmp x0, x1
- b.lo 1b
- dsb sy
+ENTRY(__dma_flush_area)
+ dcache_by_line_op civac, sy, x0, x1, x2, x3
ret
-ENDPIPROC(__dma_flush_range)
+ENDPIPROC(__dma_flush_area)
/*
* __dma_map_area(start, size, dir)
@@ -184,10 +182,9 @@ ENDPIPROC(__dma_flush_range)
* - dir - DMA direction
*/
ENTRY(__dma_map_area)
- add x1, x1, x0
cmp w2, #DMA_FROM_DEVICE
- b.eq __dma_inv_range
- b __dma_clean_range
+ b.eq __dma_inv_area
+ b __dma_clean_area
ENDPIPROC(__dma_map_area)
/*
@@ -197,8 +194,7 @@ ENDPIPROC(__dma_map_area)
* - dir - DMA direction
*/
ENTRY(__dma_unmap_area)
- add x1, x1, x0
cmp w2, #DMA_TO_DEVICE
- b.ne __dma_inv_range
+ b.ne __dma_inv_area
ret
ENDPIPROC(__dma_unmap_area)
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index c4284c432ae8..3f74d0d98de6 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -20,6 +20,7 @@
#include <linux/gfp.h>
#include <linux/acpi.h>
#include <linux/bootmem.h>
+#include <linux/cache.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/genalloc.h>
@@ -30,7 +31,7 @@
#include <asm/cacheflush.h>
-static int swiotlb __read_mostly;
+static int swiotlb __ro_after_init;
static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
bool coherent)
@@ -168,7 +169,7 @@ static void *__dma_alloc(struct device *dev, size_t size,
return ptr;
/* remove any dirty cache lines on the kernel alias */
- __dma_flush_range(ptr, ptr + size);
+ __dma_flush_area(ptr, size);
/* create a coherent mapping */
page = virt_to_page(ptr);
@@ -387,7 +388,7 @@ static int __init atomic_pool_init(void)
void *page_addr = page_address(page);
memset(page_addr, 0, atomic_pool_size);
- __dma_flush_range(page_addr, page_addr + atomic_pool_size);
+ __dma_flush_area(page_addr, atomic_pool_size);
atomic_pool = gen_pool_create(PAGE_SHIFT, -1);
if (!atomic_pool)
@@ -548,7 +549,7 @@ fs_initcall(dma_debug_do_init);
/* Thankfully, all cache ops are by VA so we can ignore phys here */
static void flush_page(struct device *dev, const void *virt, phys_addr_t phys)
{
- __dma_flush_range(virt, virt + PAGE_SIZE);
+ __dma_flush_area(virt, PAGE_SIZE);
}
static void *__iommu_alloc_attrs(struct device *dev, size_t size,
@@ -827,7 +828,7 @@ static bool do_iommu_attach(struct device *dev, const struct iommu_ops *ops,
* then the IOMMU core will have already configured a group for this
* device, and allocated the default domain for that group.
*/
- if (!domain || iommu_dma_init_domain(domain, dma_base, size)) {
+ if (!domain || iommu_dma_init_domain(domain, dma_base, size, dev)) {
pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
dev_name(dev));
return false;
diff --git a/arch/arm64/mm/extable.c b/arch/arm64/mm/extable.c
index 81acd4706878..c9f118cd812b 100644
--- a/arch/arm64/mm/extable.c
+++ b/arch/arm64/mm/extable.c
@@ -2,7 +2,7 @@
* Based on arch/arm/mm/extable.c
*/
-#include <linux/module.h>
+#include <linux/extable.h>
#include <linux/uaccess.h>
int fixup_exception(struct pt_regs *regs)
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 05d2bd776c69..53d9159662fe 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -18,7 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/module.h>
+#include <linux/extable.h>
#include <linux/signal.h>
#include <linux/mm.h>
#include <linux/hardirq.h>
@@ -251,8 +251,7 @@ static int __do_page_fault(struct mm_struct *mm, unsigned long addr,
good_area:
/*
* Check that the permissions on the VMA allow for the fault which
- * occurred. If we encountered a write or exec fault, we must have
- * appropriate permissions, otherwise we allow any permission.
+ * occurred.
*/
if (!(vma->vm_flags & vm_flags)) {
fault = VM_FAULT_BADACCESS;
@@ -288,7 +287,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
struct task_struct *tsk;
struct mm_struct *mm;
int fault, sig, code;
- unsigned long vm_flags = VM_READ | VM_WRITE | VM_EXEC;
+ unsigned long vm_flags = VM_READ | VM_WRITE;
unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
if (notify_page_fault(regs, esr))
diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
index 43a76b07eb32..8377329d8c97 100644
--- a/arch/arm64/mm/flush.c
+++ b/arch/arm64/mm/flush.c
@@ -25,8 +25,6 @@
#include <asm/cachetype.h>
#include <asm/tlbflush.h>
-#include "mm.h"
-
void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end)
{
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index bbb7ee76e319..21c489bdeb4e 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -23,6 +23,7 @@
#include <linux/swap.h>
#include <linux/init.h>
#include <linux/bootmem.h>
+#include <linux/cache.h>
#include <linux/mman.h>
#include <linux/nodemask.h>
#include <linux/initrd.h>
@@ -34,6 +35,7 @@
#include <linux/dma-contiguous.h>
#include <linux/efi.h>
#include <linux/swiotlb.h>
+#include <linux/vmalloc.h>
#include <asm/boot.h>
#include <asm/fixmap.h>
@@ -47,16 +49,14 @@
#include <asm/tlb.h>
#include <asm/alternative.h>
-#include "mm.h"
-
/*
* We need to be able to catch inadvertent references to memstart_addr
* that occur (potentially in generic code) before arm64_memblock_init()
* executes, which assigns it its actual value. So use a default value
* that cannot be mistaken for a real physical address.
*/
-s64 memstart_addr __read_mostly = -1;
-phys_addr_t arm64_dma_phys_limit __read_mostly;
+s64 memstart_addr __ro_after_init = -1;
+phys_addr_t arm64_dma_phys_limit __ro_after_init;
#ifdef CONFIG_BLK_DEV_INITRD
static int __init early_initrd(char *p)
@@ -485,7 +485,12 @@ void free_initmem(void)
{
free_reserved_area(__va(__pa(__init_begin)), __va(__pa(__init_end)),
0, "unused kernel");
- fixup_init();
+ /*
+ * Unmap the __init region but leave the VM area in place. This
+ * prevents the region from being reused for kernel modules, which
+ * is not supported by kallsyms.
+ */
+ unmap_kernel_range((u64)__init_begin, (u64)(__init_end - __init_begin));
}
#ifdef CONFIG_BLK_DEV_INITRD
diff --git a/arch/arm64/mm/mm.h b/arch/arm64/mm/mm.h
deleted file mode 100644
index 71fe98985455..000000000000
--- a/arch/arm64/mm/mm.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-void fixup_init(void);
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 4989948d1feb..05615a3fdc6f 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/cache.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -42,11 +43,9 @@
#include <asm/memblock.h>
#include <asm/mmu_context.h>
-#include "mm.h"
-
u64 idmap_t0sz = TCR_T0SZ(VA_BITS);
-u64 kimage_voffset __read_mostly;
+u64 kimage_voffset __ro_after_init;
EXPORT_SYMBOL(kimage_voffset);
/*
@@ -399,16 +398,6 @@ void mark_rodata_ro(void)
section_size, PAGE_KERNEL_RO);
}
-void fixup_init(void)
-{
- /*
- * Unmap the __init region but leave the VM area in place. This
- * prevents the region from being reused for kernel modules, which
- * is not supported by kallsyms.
- */
- unmap_kernel_range((u64)__init_begin, (u64)(__init_end - __init_begin));
-}
-
static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
pgprot_t prot, struct vm_struct *vma)
{
diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
index 5bb15eab6f00..778a985c8a70 100644
--- a/arch/arm64/mm/numa.c
+++ b/arch/arm64/mm/numa.c
@@ -17,6 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#define pr_fmt(fmt) "NUMA: " fmt
+
#include <linux/acpi.h>
#include <linux/bootmem.h>
#include <linux/memblock.h>
@@ -24,6 +26,7 @@
#include <linux/of.h>
#include <asm/acpi.h>
+#include <asm/sections.h>
struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
EXPORT_SYMBOL(node_data);
@@ -38,10 +41,9 @@ static __init int numa_parse_early_param(char *opt)
{
if (!opt)
return -EINVAL;
- if (!strncmp(opt, "off", 3)) {
- pr_info("%s\n", "NUMA turned off");
+ if (!strncmp(opt, "off", 3))
numa_off = true;
- }
+
return 0;
}
early_param("numa", numa_parse_early_param);
@@ -93,7 +95,6 @@ void numa_clear_node(unsigned int cpu)
*/
static void __init setup_node_to_cpumask_map(void)
{
- unsigned int cpu;
int node;
/* setup nr_node_ids if not done yet */
@@ -106,11 +107,8 @@ static void __init setup_node_to_cpumask_map(void)
cpumask_clear(node_to_cpumask_map[node]);
}
- for_each_possible_cpu(cpu)
- set_cpu_numa_node(cpu, NUMA_NO_NODE);
-
/* cpumask_of_node() will now work */
- pr_debug("NUMA: Node to cpumask map for %d nodes\n", nr_node_ids);
+ pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
}
/*
@@ -118,18 +116,77 @@ static void __init setup_node_to_cpumask_map(void)
*/
void numa_store_cpu_info(unsigned int cpu)
{
- map_cpu_to_node(cpu, numa_off ? 0 : cpu_to_node_map[cpu]);
+ map_cpu_to_node(cpu, cpu_to_node_map[cpu]);
}
void __init early_map_cpu_to_node(unsigned int cpu, int nid)
{
/* fallback to node 0 */
- if (nid < 0 || nid >= MAX_NUMNODES)
+ if (nid < 0 || nid >= MAX_NUMNODES || numa_off)
nid = 0;
cpu_to_node_map[cpu] = nid;
+
+ /*
+ * We should set the numa node of cpu0 as soon as possible, because it
+ * has already been set up online before. cpu_to_node(0) will soon be
+ * called.
+ */
+ if (!cpu)
+ set_cpu_numa_node(cpu, nid);
+}
+
+#ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA
+unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
+EXPORT_SYMBOL(__per_cpu_offset);
+
+static int __init early_cpu_to_node(int cpu)
+{
+ return cpu_to_node_map[cpu];
+}
+
+static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
+{
+ return node_distance(from, to);
}
+static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size,
+ size_t align)
+{
+ int nid = early_cpu_to_node(cpu);
+
+ return memblock_virt_alloc_try_nid(size, align,
+ __pa(MAX_DMA_ADDRESS), MEMBLOCK_ALLOC_ACCESSIBLE, nid);
+}
+
+static void __init pcpu_fc_free(void *ptr, size_t size)
+{
+ memblock_free_early(__pa(ptr), size);
+}
+
+void __init setup_per_cpu_areas(void)
+{
+ unsigned long delta;
+ unsigned int cpu;
+ int rc;
+
+ /*
+ * Always reserve area for module percpu variables. That's
+ * what the legacy allocator did.
+ */
+ rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
+ PERCPU_DYNAMIC_RESERVE, PAGE_SIZE,
+ pcpu_cpu_distance,
+ pcpu_fc_alloc, pcpu_fc_free);
+ if (rc < 0)
+ panic("Failed to initialize percpu areas.");
+
+ delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
+ for_each_possible_cpu(cpu)
+ __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu];
+}
+#endif
+
/**
* numa_add_memblk - Set node id to memblk
* @nid: NUMA node ID of the new memblk
@@ -145,13 +202,13 @@ int __init numa_add_memblk(int nid, u64 start, u64 end)
ret = memblock_set_node(start, (end - start), &memblock.memory, nid);
if (ret < 0) {
- pr_err("NUMA: memblock [0x%llx - 0x%llx] failed to add on node %d\n",
+ pr_err("memblock [0x%llx - 0x%llx] failed to add on node %d\n",
start, (end - 1), nid);
return ret;
}
node_set(nid, numa_nodes_parsed);
- pr_info("NUMA: Adding memblock [0x%llx - 0x%llx] on node %d\n",
+ pr_info("Adding memblock [0x%llx - 0x%llx] on node %d\n",
start, (end - 1), nid);
return ret;
}
@@ -166,19 +223,18 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
void *nd;
int tnid;
- pr_info("NUMA: Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
- nid, start_pfn << PAGE_SHIFT,
- (end_pfn << PAGE_SHIFT) - 1);
+ pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
+ nid, start_pfn << PAGE_SHIFT, (end_pfn << PAGE_SHIFT) - 1);
nd_pa = memblock_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid);
nd = __va(nd_pa);
/* report and initialize */
- pr_info("NUMA: NODE_DATA [mem %#010Lx-%#010Lx]\n",
+ pr_info("NODE_DATA [mem %#010Lx-%#010Lx]\n",
nd_pa, nd_pa + nd_size - 1);
tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
if (tnid != nid)
- pr_info("NUMA: NODE_DATA(%d) on node %d\n", nid, tnid);
+ pr_info("NODE_DATA(%d) on node %d\n", nid, tnid);
node_data[nid] = nd;
memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
@@ -235,8 +291,7 @@ static int __init numa_alloc_distance(void)
numa_distance[i * numa_distance_cnt + j] = i == j ?
LOCAL_DISTANCE : REMOTE_DISTANCE;
- pr_debug("NUMA: Initialized distance table, cnt=%d\n",
- numa_distance_cnt);
+ pr_debug("Initialized distance table, cnt=%d\n", numa_distance_cnt);
return 0;
}
@@ -257,20 +312,20 @@ static int __init numa_alloc_distance(void)
void __init numa_set_distance(int from, int to, int distance)
{
if (!numa_distance) {
- pr_warn_once("NUMA: Warning: distance table not allocated yet\n");
+ pr_warn_once("Warning: distance table not allocated yet\n");
return;
}
if (from >= numa_distance_cnt || to >= numa_distance_cnt ||
from < 0 || to < 0) {
- pr_warn_once("NUMA: Warning: node ids are out of bound, from=%d to=%d distance=%d\n",
+ pr_warn_once("Warning: node ids are out of bound, from=%d to=%d distance=%d\n",
from, to, distance);
return;
}
if ((u8)distance != distance ||
(from == to && distance != LOCAL_DISTANCE)) {
- pr_warn_once("NUMA: Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
+ pr_warn_once("Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
from, to, distance);
return;
}
@@ -297,7 +352,7 @@ static int __init numa_register_nodes(void)
/* Check that valid nid is set to memblks */
for_each_memblock(memory, mblk)
if (mblk->nid == NUMA_NO_NODE || mblk->nid >= MAX_NUMNODES) {
- pr_warn("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
+ pr_warn("Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
mblk->nid, mblk->base,
mblk->base + mblk->size - 1);
return -EINVAL;
@@ -335,8 +390,10 @@ static int __init numa_init(int (*init_func)(void))
if (ret < 0)
return ret;
- if (nodes_empty(numa_nodes_parsed))
+ if (nodes_empty(numa_nodes_parsed)) {
+ pr_info("No NUMA configuration found\n");
return -EINVAL;
+ }
ret = numa_register_nodes();
if (ret < 0)
@@ -344,10 +401,6 @@ static int __init numa_init(int (*init_func)(void))
setup_node_to_cpumask_map();
- /* init boot processor */
- cpu_to_node_map[0] = 0;
- map_cpu_to_node(0, 0);
-
return 0;
}
@@ -367,10 +420,8 @@ static int __init dummy_numa_init(void)
if (numa_off)
pr_info("NUMA disabled\n"); /* Forced off on command line. */
- else
- pr_info("No NUMA configuration found\n");
- pr_info("NUMA: Faking a node at [mem %#018Lx-%#018Lx]\n",
- 0LLU, PFN_PHYS(max_pfn) - 1);
+ pr_info("Faking a node at [mem %#018Lx-%#018Lx]\n",
+ 0LLU, PFN_PHYS(max_pfn) - 1);
for_each_memblock(memory, mblk) {
ret = numa_add_memblk(0, mblk->base, mblk->base + mblk->size);
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index ca6d268e3313..8def55e7249b 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -139,4 +139,43 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
__pgprot(0),
__pgprot(PTE_VALID));
}
-#endif
+#ifdef CONFIG_HIBERNATION
+/*
+ * When built with CONFIG_DEBUG_PAGEALLOC and CONFIG_HIBERNATION, this function
+ * is used to determine if a linear map page has been marked as not-valid by
+ * CONFIG_DEBUG_PAGEALLOC. Walk the page table and check the PTE_VALID bit.
+ * This is based on kern_addr_valid(), which almost does what we need.
+ *
+ * Because this is only called on the kernel linear map, p?d_sect() implies
+ * p?d_present(). When debug_pagealloc is enabled, sections mappings are
+ * disabled.
+ */
+bool kernel_page_present(struct page *page)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ unsigned long addr = (unsigned long)page_address(page);
+
+ pgd = pgd_offset_k(addr);
+ if (pgd_none(*pgd))
+ return false;
+
+ pud = pud_offset(pgd, addr);
+ if (pud_none(*pud))
+ return false;
+ if (pud_sect(*pud))
+ return true;
+
+ pmd = pmd_offset(pud, addr);
+ if (pmd_none(*pmd))
+ return false;
+ if (pmd_sect(*pmd))
+ return true;
+
+ pte = pte_offset_kernel(pmd, addr);
+ return pte_valid(*pte);
+}
+#endif /* CONFIG_HIBERNATION */
+#endif /* CONFIG_DEBUG_PAGEALLOC */
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
index ae11d4e03d0e..371c5f03a170 100644
--- a/arch/arm64/mm/pgd.c
+++ b/arch/arm64/mm/pgd.c
@@ -26,8 +26,6 @@
#include <asm/page.h>
#include <asm/tlbflush.h>
-#include "mm.h"
-
static struct kmem_cache *pgd_cache;
pgd_t *pgd_alloc(struct mm_struct *mm)
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 9d37e967fa19..352c73b6a59e 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -83,6 +83,7 @@ ENDPROC(cpu_do_suspend)
*
* x0: Address of context pointer
*/
+ .pushsection ".idmap.text", "ax"
ENTRY(cpu_do_resume)
ldp x2, x3, [x0]
ldp x4, x5, [x0, #16]
@@ -120,6 +121,7 @@ ENTRY(cpu_do_resume)
isb
ret
ENDPROC(cpu_do_resume)
+ .popsection
#endif
/*
@@ -134,17 +136,12 @@ ENTRY(cpu_do_switch_mm)
bfi x0, x1, #48, #16 // set the ASID
msr ttbr0_el1, x0 // set TTBR0
isb
-alternative_if_not ARM64_WORKAROUND_CAVIUM_27456
- ret
- nop
- nop
- nop
-alternative_else
+alternative_if ARM64_WORKAROUND_CAVIUM_27456
ic iallu
dsb nsh
isb
+alternative_else_nop_endif
ret
-alternative_endif
ENDPROC(cpu_do_switch_mm)
.pushsection ".idmap.text", "ax"
@@ -181,6 +178,7 @@ ENDPROC(idmap_cpu_replace_ttbr1)
* Initialise the processor for turning the MMU on. Return in x0 the
* value of the SCTLR_EL1 register.
*/
+ .pushsection ".idmap.text", "ax"
ENTRY(__cpu_setup)
tlbi vmalle1 // Invalidate local TLB
dsb nsh
@@ -266,3 +264,4 @@ ENDPROC(__cpu_setup)
crval:
.word 0xfcffffff // clear
.word 0x34d5d91d // set
+ .popsection