diff options
author | Jiri Kosina <jkosina@suse.cz> | 2021-02-23 11:33:13 +0100 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2021-02-23 11:33:13 +0100 |
commit | d6310078d9f8c416e85f641a631aecf58f9c97ff (patch) | |
tree | 58ed5d9818ada3e970d93438083731abd6293ba9 /arch | |
parent | f8dd50e097b221e35c34b844826db92158ec18c2 (diff) | |
parent | df7b622906f24be954beca94e60c195fde65c6d5 (diff) |
Merge branch 'for-5.12/google' into for-linus
- User experience improvements for hid-google from Nicolas Boichat
Diffstat (limited to 'arch')
1279 files changed, 50179 insertions, 13770 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index d4bdc19ed3ad..24862d15f3a3 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -143,6 +143,22 @@ config UPROBES managed by the kernel and kept transparent to the probed application. ) +config HAVE_64BIT_ALIGNED_ACCESS + def_bool 64BIT && !HAVE_EFFICIENT_UNALIGNED_ACCESS + help + Some architectures require 64 bit accesses to be 64 bit + aligned, which also requires structs containing 64 bit values + to be 64 bit aligned too. This includes some 32 bit + architectures which can do 64 bit accesses, as well as 64 bit + architectures without unaligned access. + + This symbol should be selected by an architecture if 64 bit + accesses are required to be 64 bit aligned in this way even + though it is not a 64 bit architecture. + + See Documentation/unaligned-memory-access.txt for more + information on the topic of unaligned memory accesses. + config HAVE_EFFICIENT_UNALIGNED_ACCESS bool help @@ -960,16 +976,16 @@ config VMAP_STACK default y bool "Use a virtually-mapped stack" depends on HAVE_ARCH_VMAP_STACK - depends on !KASAN || KASAN_VMALLOC + depends on !KASAN || KASAN_HW_TAGS || KASAN_VMALLOC help Enable this if you want the use virtually-mapped kernel stacks with guard pages. This causes kernel stack overflows to be caught immediately rather than causing difficult-to-diagnose corruption. - To use this with KASAN, the architecture must support backing - virtual mappings with real shadow memory, and KASAN_VMALLOC must - be enabled. + To use this with software KASAN modes, the architecture must support + backing virtual mappings with real shadow memory, and KASAN_VMALLOC + must be enabled. config ARCH_OPTIONAL_KERNEL_RWX def_bool n @@ -1089,6 +1105,12 @@ config HAVE_ARCH_PFN_VALID config ARCH_SUPPORTS_DEBUG_PAGEALLOC bool +config ARCH_SPLIT_ARG64 + bool + help + If a 32-bit architecture requires 64-bit arguments to be split into + pairs of 32-bit arguments, select this option. + source "kernel/gcov/Kconfig" source "scripts/gcc-plugins/Kconfig" diff --git a/arch/alpha/include/asm/local64.h b/arch/alpha/include/asm/local64.h deleted file mode 100644 index 36c93b5cc239..000000000000 --- a/arch/alpha/include/asm/local64.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/local64.h> diff --git a/arch/alpha/kernel/rtc.c b/arch/alpha/kernel/rtc.c index 1b1d5963ac55..ce3077946e1d 100644 --- a/arch/alpha/kernel/rtc.c +++ b/arch/alpha/kernel/rtc.c @@ -216,6 +216,6 @@ alpha_rtc_init(void) rtc->ops = &remote_rtc_ops; #endif - return rtc_register_device(rtc); + return devm_rtc_register_device(rtc); } device_initcall(alpha_rtc_init); diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c index 0a2ab6cb18db..e5d870ff225f 100644 --- a/arch/alpha/kernel/sys_jensen.c +++ b/arch/alpha/kernel/sys_jensen.c @@ -7,7 +7,7 @@ * * Code supporting the Jensen. */ - +#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/mm.h> diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl index ee7b01bb7346..a6617067dbe6 100644 --- a/arch/alpha/kernel/syscalls/syscall.tbl +++ b/arch/alpha/kernel/syscalls/syscall.tbl @@ -480,3 +480,4 @@ 548 common pidfd_getfd sys_pidfd_getfd 549 common faccessat2 sys_faccessat2 550 common process_madvise sys_process_madvise +551 common epoll_pwait2 sys_epoll_pwait2 diff --git a/arch/arc/Makefile b/arch/arc/Makefile index 0c6bf0d1df7a..578bdbbb0fa7 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -102,16 +102,22 @@ libs-y += arch/arc/lib/ $(LIBGCC) boot := arch/arc/boot -#default target for make without any arguments. -KBUILD_IMAGE := $(boot)/bootpImage - -all: bootpImage -bootpImage: vmlinux - -boot_targets += uImage uImage.bin uImage.gz +boot_targets := uImage.bin uImage.gz uImage.lzma +PHONY += $(boot_targets) $(boot_targets): vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ +uimage-default-y := uImage.bin +uimage-default-$(CONFIG_KERNEL_GZIP) := uImage.gz +uimage-default-$(CONFIG_KERNEL_LZMA) := uImage.lzma + +PHONY += uImage +uImage: $(uimage-default-y) + @ln -sf $< $(boot)/uImage + @$(kecho) ' Image $(boot)/uImage is ready' + +CLEAN_FILES += $(boot)/uImage + archclean: $(Q)$(MAKE) $(clean)=$(boot) diff --git a/arch/arc/boot/Makefile b/arch/arc/boot/Makefile index 538b92f4dd25..5648748c285f 100644 --- a/arch/arc/boot/Makefile +++ b/arch/arc/boot/Makefile @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -targets := vmlinux.bin vmlinux.bin.gz uImage # uImage build relies on mkimage being availble on your host for ARC target # You will need to build u-boot for ARC, rename mkimage to arc-elf32-mkimage @@ -7,23 +6,18 @@ targets := vmlinux.bin vmlinux.bin.gz uImage OBJCOPYFLAGS= -O binary -R .note -R .note.gnu.build-id -R .comment -S -LINUX_START_TEXT = $$(readelf -h vmlinux | \ +LINUX_START_TEXT = $$($(READELF) -h vmlinux | \ grep "Entry point address" | grep -o 0x.*) UIMAGE_LOADADDR = $(CONFIG_LINUX_LINK_BASE) UIMAGE_ENTRYADDR = $(LINUX_START_TEXT) -suffix-y := bin -suffix-$(CONFIG_KERNEL_GZIP) := gz -suffix-$(CONFIG_KERNEL_LZMA) := lzma - -targets += uImage +targets += vmlinux.bin +targets += vmlinux.bin.gz +targets += vmlinux.bin.lzma targets += uImage.bin targets += uImage.gz targets += uImage.lzma -extra-y += vmlinux.bin -extra-y += vmlinux.bin.gz -extra-y += vmlinux.bin.lzma $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) @@ -42,7 +36,3 @@ $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma FORCE $(call if_changed,uimage,lzma) - -$(obj)/uImage: $(obj)/uImage.$(suffix-y) - @ln -sf $(notdir $<) $@ - @echo ' Image $@ is ready' diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild index 81f4edec0c2a..3c1afa524b9c 100644 --- a/arch/arc/include/asm/Kbuild +++ b/arch/arc/include/asm/Kbuild @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 generic-y += extable.h generic-y += kvm_para.h -generic-y += local64.h generic-y += mcs_spinlock.h generic-y += parport.h generic-y += user.h diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h index 23e41e890eda..ad9b7fe4dba3 100644 --- a/arch/arc/include/asm/page.h +++ b/arch/arc/include/asm/page.h @@ -10,6 +10,7 @@ #ifndef __ASSEMBLY__ #define clear_page(paddr) memset((paddr), 0, PAGE_SIZE) +#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) #define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) struct vm_area_struct; diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index 1f5308abf36d..1743506081da 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S @@ -307,7 +307,7 @@ resume_user_mode_begin: mov r0, sp ; pt_regs for arg to do_signal()/do_notify_resume() GET_CURR_THR_INFO_FLAGS r9 - and.f 0, r9, TIF_SIGPENDING|TIF_NOTIFY_SIGNAL + and.f 0, r9, _TIF_SIGPENDING|_TIF_NOTIFY_SIGNAL bz .Lchk_notify_resume ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs diff --git a/arch/arc/plat-hsdk/Kconfig b/arch/arc/plat-hsdk/Kconfig index 6b5c54576f54..a2d10c29fbcc 100644 --- a/arch/arc/plat-hsdk/Kconfig +++ b/arch/arc/plat-hsdk/Kconfig @@ -7,6 +7,7 @@ menuconfig ARC_SOC_HSDK depends on ISA_ARCV2 select ARC_HAS_ACCL_REGS select ARC_IRQ_NO_AUTOSAVE + select ARC_FPU_SAVE_RESTORE select CLK_HSDK select RESET_CONTROLLER select RESET_HSDK diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ba937d85cb6c..138248999df7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -5,7 +5,6 @@ config ARM select ARCH_32BIT_OFF_T select ARCH_HAS_BINFMT_FLAT select ARCH_HAS_DEBUG_VIRTUAL if MMU - select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_FORTIFY_SOURCE @@ -57,6 +56,7 @@ config ARM select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW select GENERIC_IRQ_SHOW_LEVEL + select GENERIC_LIB_DEVMEM_IS_ALLOWED select GENERIC_PCI_IOMAP select GENERIC_SCHED_CLOCK select GENERIC_SMP_IDLE_THREAD @@ -68,6 +68,7 @@ config ARM select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU + select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_PFN_VALID select HAVE_ARCH_SECCOMP @@ -245,7 +246,7 @@ config ARM_PATCH_PHYS_VIRT kernel in system memory. This can only be used with non-XIP MMU kernels where the base - of physical memory is at a 16MB boundary. + of physical memory is at a 2 MiB boundary. Only disable this option if you know that you do not require this feature (eg, building a kernel for a single machine) and @@ -1298,6 +1299,15 @@ config PAGE_OFFSET default 0xB0000000 if VMSPLIT_3G_OPT default 0xC0000000 +config KASAN_SHADOW_OFFSET + hex + depends on KASAN + default 0x1f000000 if PAGE_OFFSET=0x40000000 + default 0x5f000000 if PAGE_OFFSET=0x80000000 + default 0x9f000000 if PAGE_OFFSET=0xC0000000 + default 0x8f000000 if PAGE_OFFSET=0xB0000000 + default 0xffffffff + config NR_CPUS int "Maximum number of CPUs (2-32)" range 2 32 diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 4a066c687cec..4aaec9599e8a 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -10,7 +10,7 @@ # # Copyright (C) 1995-2001 by Russell King -LDFLAGS_vmlinux := --no-undefined -X --pic-veneer +LDFLAGS_vmlinux := --no-undefined -X --pic-veneer -z norelro ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) LDFLAGS_vmlinux += --be8 KBUILD_LDFLAGS_MODULE += --be8 diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index e1567418a2b1..fb521efcc6c2 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -24,6 +24,7 @@ OBJS += hyp-stub.o endif GCOV_PROFILE := n +KASAN_SANITIZE := n # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. KCOV_INSTRUMENT := n diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index caa27322a0ab..d9cce7238a36 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -11,6 +11,12 @@ #include "efi-header.S" +#ifdef __ARMEB__ +#define OF_DT_MAGIC 0xd00dfeed +#else +#define OF_DT_MAGIC 0xedfe0dd0 +#endif + AR_CLASS( .arch armv7-a ) M_CLASS( .arch armv7-m ) @@ -116,7 +122,7 @@ /* * Debug print of the final appended DTB location */ - .macro dbgadtb, begin, end + .macro dbgadtb, begin, size #ifdef DEBUG kputc #'D' kputc #'T' @@ -129,7 +135,7 @@ kputc #'(' kputc #'0' kputc #'x' - kphex \end, 8 /* End of appended DTB */ + kphex \size, 8 /* Size of appended DTB */ kputc #')' kputc #'\n' #endif @@ -165,6 +171,16 @@ orr \res, \res, \tmp1, lsl #24 .endm + .macro be32tocpu, val, tmp +#ifndef __ARMEB__ + /* convert to little endian */ + eor \tmp, \val, \val, ror #16 + bic \tmp, \tmp, #0x00ff0000 + mov \val, \val, ror #8 + eor \val, \val, \tmp, lsr #8 +#endif + .endm + .section ".start", "ax" /* * sort out different calling conventions @@ -325,11 +341,7 @@ restart: adr r0, LC1 */ ldr lr, [r6, #0] -#ifndef __ARMEB__ - ldr r1, =0xedfe0dd0 @ sig is 0xd00dfeed big endian -#else - ldr r1, =0xd00dfeed -#endif + ldr r1, =OF_DT_MAGIC cmp lr, r1 bne dtb_check_done @ not found @@ -345,13 +357,7 @@ restart: adr r0, LC1 /* Get the initial DTB size */ ldr r5, [r6, #4] -#ifndef __ARMEB__ - /* convert to little endian */ - eor r1, r5, r5, ror #16 - bic r1, r1, #0x00ff0000 - mov r5, r5, ror #8 - eor r5, r5, r1, lsr #8 -#endif + be32tocpu r5, r1 dbgadtb r6, r5 /* 50% DTB growth should be good enough */ add r5, r5, r5, lsr #1 @@ -403,13 +409,7 @@ restart: adr r0, LC1 /* Get the current DTB size */ ldr r5, [r6, #4] -#ifndef __ARMEB__ - /* convert r5 (dtb size) to little endian */ - eor r1, r5, r5, ror #16 - bic r1, r1, #0x00ff0000 - mov r5, r5, ror #8 - eor r5, r5, r1, lsr #8 -#endif + be32tocpu r5, r1 /* preserve 64-bit alignment */ add r5, r5, #7 @@ -468,15 +468,10 @@ dtb_check_done: /* * Compute the address of the hyp vectors after relocation. - * This requires some arithmetic since we cannot directly - * reference __hyp_stub_vectors in a PC-relative way. * Call __hyp_set_vectors with the new address so that we * can HVC again after the copy. */ -0: adr r0, 0b - movw r1, #:lower16:__hyp_stub_vectors - 0b - movt r1, #:upper16:__hyp_stub_vectors - 0b - add r0, r0, r1 + adr_l r0, __hyp_stub_vectors sub r0, r0, r5 add r0, r0, r10 bl __hyp_set_vectors @@ -627,17 +622,11 @@ not_relocated: mov r0, #0 cmp r0, #HYP_MODE @ if not booted in HYP mode... bne __enter_kernel @ boot kernel directly - adr r12, .L__hyp_reentry_vectors_offset - ldr r0, [r12] - add r0, r0, r12 - + adr_l r0, __hyp_reentry_vectors bl __hyp_set_vectors __HVC(0) @ otherwise bounce to hyp mode b . @ should never be reached - - .align 2 -.L__hyp_reentry_vectors_offset: .long __hyp_reentry_vectors - . #else b __enter_kernel #endif @@ -1440,8 +1429,7 @@ ENTRY(efi_enter_kernel) mov r4, r0 @ preserve image base mov r8, r1 @ preserve DT pointer - ARM( adrl r0, call_cache_fn ) - THUMB( adr r0, call_cache_fn ) + adr_l r0, call_cache_fn adr r1, 0f @ clean the region of code we bl cache_clean_flush @ may run with the MMU off diff --git a/arch/arm/boot/compressed/string.c b/arch/arm/boot/compressed/string.c index ade5079bebbf..8c0fa276d994 100644 --- a/arch/arm/boot/compressed/string.c +++ b/arch/arm/boot/compressed/string.c @@ -7,6 +7,25 @@ #include <linux/string.h> +/* + * The decompressor is built without KASan but uses the same redirects as the + * rest of the kernel when CONFIG_KASAN is enabled, defining e.g. memcpy() + * to __memcpy() but since we are not linking with the main kernel string + * library in the decompressor, that will lead to link failures. + * + * Undefine KASan's versions, define the wrapped functions and alias them to + * the right names so that when e.g. __memcpy() appear in the code, it will + * still be linked to this local version of memcpy(). + */ +#ifdef CONFIG_KASAN +#undef memcpy +#undef memmove +#undef memset +void *__memcpy(void *__dest, __const void *__src, size_t __n) __alias(memcpy); +void *__memmove(void *__dest, __const void *__src, size_t count) __alias(memmove); +void *__memset(void *s, int c, size_t count) __alias(memset); +#endif + void *memcpy(void *__dest, __const void *__src, size_t __n) { int i = 0; diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index ce66ffd5a1bb..3d1ea0b25168 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -197,6 +197,7 @@ dtb-$(CONFIG_ARCH_EXYNOS4) += \ exynos4412-odroidx.dtb \ exynos4412-odroidx2.dtb \ exynos4412-origen.dtb \ + exynos4412-p4note-n8010.dtb \ exynos4412-smdk4412.dtb \ exynos4412-tiny4412.dtb \ exynos4412-trats2.dtb @@ -339,7 +340,10 @@ dtb-$(CONFIG_ARCH_LPC32XX) += \ lpc3250-ea3250.dtb \ lpc3250-phy3250.dtb dtb-$(CONFIG_ARCH_NPCM7XX) += \ - nuvoton-npcm750-evb.dtb + nuvoton-npcm730-gsj.dtb \ + nuvoton-npcm730-kudo.dtb \ + nuvoton-npcm750-evb.dtb \ + nuvoton-npcm750-runbmc-olympus.dtb dtb-$(CONFIG_MACH_MESON6) += \ meson6-atv1200.dtb dtb-$(CONFIG_MACH_MESON8) += \ @@ -414,6 +418,7 @@ dtb-$(CONFIG_SOC_IMX53) += \ imx53-usbarmory.dtb \ imx53-voipac-bsb.dtb dtb-$(CONFIG_SOC_IMX6Q) += \ + imx6dl-alti6p.dtb \ imx6dl-apf6dev.dtb \ imx6dl-aristainetos_4.dtb \ imx6dl-aristainetos_7.dtb \ @@ -450,6 +455,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6dl-icore.dtb \ imx6dl-icore-mipi.dtb \ imx6dl-icore-rqs.dtb \ + imx6dl-lanmcu.dtb \ imx6dl-mamoj.dtb \ imx6dl-nit6xlite.dtb \ imx6dl-nitrogen6x.dtb \ @@ -581,6 +587,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6qp-nitrogen6_max.dtb \ imx6qp-nitrogen6_som2.dtb \ imx6qp-phytec-mira-rdk-nand.dtb \ + imx6qp-prtwd3.dtb \ imx6qp-sabreauto.dtb \ imx6qp-sabresd.dtb \ imx6qp-tx6qp-8037.dtb \ @@ -622,6 +629,7 @@ dtb-$(CONFIG_SOC_IMX6UL) += \ imx6ul-pico-dwarf.dtb \ imx6ul-pico-hobbit.dtb \ imx6ul-pico-pi.dtb \ + imx6ul-phytec-segin-ff-rdk-emmc.dtb \ imx6ul-phytec-segin-ff-rdk-nand.dtb \ imx6ul-tx6ul-0010.dtb \ imx6ul-tx6ul-0011.dtb \ @@ -641,6 +649,8 @@ dtb-$(CONFIG_SOC_IMX7D) += \ imx7d-colibri-emmc-aster.dtb \ imx7d-colibri-emmc-eval-v3.dtb \ imx7d-colibri-eval-v3.dtb \ + imx7d-flex-concentrator.dtb \ + imx7d-flex-concentrator-mfg.dtb \ imx7d-mba7.dtb \ imx7d-meerkat96.dtb \ imx7d-nitrogen7.dtb \ @@ -1066,6 +1076,7 @@ dtb-$(CONFIG_ARCH_STM32) += \ stm32mp157a-iot-box.dtb \ stm32mp157a-stinger96.dtb \ stm32mp157c-dhcom-pdk2.dtb \ + stm32mp157c-dhcom-picoitx.dtb \ stm32mp157c-dk2.dtb \ stm32mp157c-ed1.dtb \ stm32mp157c-ev1.dtb \ @@ -1192,6 +1203,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \ sun8i-h3-nanopi-m1-plus.dtb \ sun8i-h3-nanopi-neo.dtb \ sun8i-h3-nanopi-neo-air.dtb \ + sun8i-h3-nanopi-r1.dtb \ sun8i-h3-orangepi-2.dtb \ sun8i-h3-orangepi-lite.dtb \ sun8i-h3-orangepi-one.dtb \ @@ -1201,12 +1213,14 @@ dtb-$(CONFIG_MACH_SUN8I) += \ sun8i-h3-orangepi-plus2e.dtb \ sun8i-h3-orangepi-zero-plus2.dtb \ sun8i-h3-rervision-dvk.dtb \ + sun8i-h3-zeropi.dtb \ sun8i-h3-emlid-neutis-n5h3-devboard.dtb \ sun8i-r16-bananapi-m2m.dtb \ sun8i-r16-nintendo-nes-classic.dtb \ sun8i-r16-nintendo-super-nes-classic.dtb \ sun8i-r16-parrot.dtb \ sun8i-r40-bananapi-m2-ultra.dtb \ + sun8i-s3-elimo-initium.dtb \ sun8i-s3-lichee-zero-plus.dtb \ sun8i-s3-pinecube.dtb \ sun8i-t3-cqa3t-bv3.dtb \ @@ -1241,7 +1255,8 @@ dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += \ tegra30-beaver.dtb \ tegra30-cardhu-a02.dtb \ tegra30-cardhu-a04.dtb \ - tegra30-colibri-eval-v3.dtb + tegra30-colibri-eval-v3.dtb \ + tegra30-ouya.dtb dtb-$(CONFIG_ARCH_TEGRA_114_SOC) += \ tegra114-dalmore.dtb \ tegra114-roth.dtb \ @@ -1302,6 +1317,7 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \ zynq-zc770-xm013.dtb \ zynq-zed.dtb \ zynq-zturn.dtb \ + zynq-zturn-v5.dtb \ zynq-zybo.dtb \ zynq-zybo-z7.dtb dtb-$(CONFIG_MACH_ARMADA_370) += \ @@ -1319,6 +1335,7 @@ dtb-$(CONFIG_MACH_ARMADA_370) += \ dtb-$(CONFIG_MACH_ARMADA_375) += \ armada-375-db.dtb dtb-$(CONFIG_MACH_ARMADA_38X) += \ + armada-382-rd-ac3x-48g4x2xl.dtb \ armada-385-clearfog-gtr-s4.dtb \ armada-385-clearfog-gtr-l8.dtb \ armada-385-db-88f6820-amc.dtb \ @@ -1340,6 +1357,12 @@ dtb-$(CONFIG_MACH_ARMADA_39X) += \ armada-398-db.dtb dtb-$(CONFIG_MACH_ARMADA_XP) += \ armada-xp-axpwifiap.dtb \ + armada-xp-crs305-1g-4s.dtb \ + armada-xp-crs305-1g-4s-bit.dtb \ + armada-xp-crs326-24g-2s.dtb \ + armada-xp-crs326-24g-2s-bit.dtb \ + armada-xp-crs328-4c-20s-4s.dtb \ + armada-xp-crs328-4c-20s-4s-bit.dtb \ armada-xp-db.dtb \ armada-xp-db-dxbc2.dtb \ armada-xp-db-xc3-24g4xg.dtb \ @@ -1372,6 +1395,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ dtb-$(CONFIG_ARCH_MILBEAUT) += milbeaut-m10v-evb.dtb dtb-$(CONFIG_ARCH_MSTARV7) += \ mstar-infinity-msc313-breadbee_crust.dtb \ + mstar-infinity2m-ssd202d-ssd201htv2.dtb \ mstar-infinity3-msc313e-breadbee.dtb \ mstar-mercury5-ssc8336n-midrived08.dtb dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb @@ -1381,7 +1405,9 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ aspeed-bmc-amd-ethanolx.dtb \ aspeed-bmc-arm-centriq2400-rep.dtb \ aspeed-bmc-arm-stardragon4800-rep2.dtb \ + aspeed-bmc-bytedance-g220a.dtb \ aspeed-bmc-facebook-cmm.dtb \ + aspeed-bmc-facebook-galaxy100.dtb \ aspeed-bmc-facebook-minipack.dtb \ aspeed-bmc-facebook-tiogapass.dtb \ aspeed-bmc-facebook-wedge40.dtb \ @@ -1390,6 +1416,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ aspeed-bmc-facebook-yamp.dtb \ aspeed-bmc-facebook-yosemitev2.dtb \ aspeed-bmc-ibm-rainier.dtb \ + aspeed-bmc-ibm-rainier-4u.dtb \ aspeed-bmc-intel-s2600wf.dtb \ aspeed-bmc-inspur-fp5280g2.dtb \ aspeed-bmc-lenovo-hr630.dtb \ diff --git a/arch/arm/boot/dts/am335x-baltos.dtsi b/arch/arm/boot/dts/am335x-baltos.dtsi index b7f64c7ba83d..3ea286180382 100644 --- a/arch/arm/boot/dts/am335x-baltos.dtsi +++ b/arch/arm/boot/dts/am335x-baltos.dtsi @@ -168,7 +168,7 @@ AM33XX_PADCONF(AM335X_PIN_GPMC_AD6, PIN_INPUT_PULLUP, MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */ AM33XX_PADCONF(AM335X_PIN_GPMC_AD7, PIN_INPUT_PULLUP, MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */ AM33XX_PADCONF(AM335X_PIN_GPMC_WAIT0, PIN_INPUT_PULLUP, MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */ - AM33XX_PADCONF(AM335X_PIN_GPMC_WPN, PIN_INPUT_PULLUP, MUX_MODE7) /* gpmc_wpn.gpio0_30 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_WPN, PIN_INPUT_PULLUP, MUX_MODE7) /* gpmc_wpn.gpio0_31 */ AM33XX_PADCONF(AM335X_PIN_GPMC_CSN0, PIN_OUTPUT, MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */ AM33XX_PADCONF(AM335X_PIN_GPMC_ADVN_ALE, PIN_OUTPUT, MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */ AM33XX_PADCONF(AM335X_PIN_GPMC_OEN_REN, PIN_OUTPUT, MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */ diff --git a/arch/arm/boot/dts/am335x-boneblue.dts b/arch/arm/boot/dts/am335x-boneblue.dts index c696d57cf364..69acaf4ea0f3 100644 --- a/arch/arm/boot/dts/am335x-boneblue.dts +++ b/arch/arm/boot/dts/am335x-boneblue.dts @@ -241,6 +241,30 @@ AM33XX_PADCONF(AM335X_PIN_MII1_RXD0, PIN_OUTPUT, MUX_MODE7) /* (M16) gmii1_rxd0.gpio2[21] */ >; }; + + /* E1 */ + eqep0_pins: pinmux_eqep0_pins { + pinctrl-single,pins = < + AM33XX_PADCONF(AM335X_PIN_MCASP0_AXR0, PIN_INPUT, MUX_MODE1) /* (B12) mcasp0_aclkr.eQEP0A_in */ + AM33XX_PADCONF(AM335X_PIN_MCASP0_FSR, PIN_INPUT, MUX_MODE1) /* (C13) mcasp0_fsr.eQEP0B_in */ + >; + }; + + /* E2 */ + eqep1_pins: pinmux_eqep1_pins { + pinctrl-single,pins = < + AM33XX_PADCONF(AM335X_PIN_LCD_DATA12, PIN_INPUT, MUX_MODE2) /* (V2) lcd_data12.eQEP1A_in */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA13, PIN_INPUT, MUX_MODE2) /* (V3) lcd_data13.eQEP1B_in */ + >; + }; + + /* E3 */ + eqep2_pins: pinmux_eqep2_pins { + pinctrl-single,pins = < + AM33XX_PADCONF(AM335X_PIN_GPMC_AD12, PIN_INPUT, MUX_MODE4) /* (T12) gpmc_ad12.eQEP2A_in */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD13, PIN_INPUT, MUX_MODE4) /* (R12) gpmc_ad13.eQEP2B_in */ + >; + }; }; &uart0 { @@ -419,3 +443,33 @@ line-name = "LS_BUF_EN"; }; }; + +&epwmss0 { + status = "okay"; +}; + +&eqep0 { + pinctrl-names = "default"; + pinctrl-0 = <&eqep0_pins>; + status = "okay"; +}; + +&epwmss1 { + status = "okay"; +}; + +&eqep1 { + pinctrl-names = "default"; + pinctrl-0 = <&eqep1_pins>; + status = "okay"; +}; + +&epwmss2 { + status = "okay"; +}; + +&eqep2 { + pinctrl-names = "default"; + pinctrl-0 = <&eqep2_pins>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts b/arch/arm/boot/dts/am335x-cm-t335.dts index c6fe9db660e2..36d963db4026 100644 --- a/arch/arm/boot/dts/am335x-cm-t335.dts +++ b/arch/arm/boot/dts/am335x-cm-t335.dts @@ -122,7 +122,7 @@ AM33XX_PADCONF(AM335X_PIN_GPMC_AD6, PIN_INPUT_PULLUP, MUX_MODE0) AM33XX_PADCONF(AM335X_PIN_GPMC_AD7, PIN_INPUT_PULLUP, MUX_MODE0) AM33XX_PADCONF(AM335X_PIN_GPMC_WAIT0, PIN_INPUT_PULLUP, MUX_MODE0) - /* gpmc_wpn.gpio0_30 */ + /* gpmc_wpn.gpio0_31 */ AM33XX_PADCONF(AM335X_PIN_GPMC_WPN, PIN_INPUT_PULLUP, MUX_MODE7) AM33XX_PADCONF(AM335X_PIN_GPMC_CSN0, PIN_OUTPUT, MUX_MODE0) AM33XX_PADCONF(AM335X_PIN_GPMC_ADVN_ALE, PIN_OUTPUT, MUX_MODE0) diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index 12dffccd1ffd..7c6f2c11f0e1 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts @@ -229,7 +229,7 @@ AM33XX_PADCONF(AM335X_PIN_GPMC_AD6, PIN_INPUT_PULLUP, MUX_MODE0) AM33XX_PADCONF(AM335X_PIN_GPMC_AD7, PIN_INPUT_PULLUP, MUX_MODE0) AM33XX_PADCONF(AM335X_PIN_GPMC_WAIT0, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_GPMC_WPN, PIN_INPUT_PULLUP, MUX_MODE7) /* gpmc_wpn.gpio0_30 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_WPN, PIN_INPUT_PULLUP, MUX_MODE7) /* gpmc_wpn.gpio0_31 */ AM33XX_PADCONF(AM335X_PIN_GPMC_CSN0, PIN_OUTPUT, MUX_MODE0) AM33XX_PADCONF(AM335X_PIN_GPMC_ADVN_ALE, PIN_OUTPUT, MUX_MODE0) AM33XX_PADCONF(AM335X_PIN_GPMC_OEN_REN, PIN_OUTPUT, MUX_MODE0) diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi b/arch/arm/boot/dts/am335x-igep0033.dtsi index c9f354fc984a..7ec23d47a429 100644 --- a/arch/arm/boot/dts/am335x-igep0033.dtsi +++ b/arch/arm/boot/dts/am335x-igep0033.dtsi @@ -70,7 +70,7 @@ AM33XX_PADCONF(AM335X_PIN_GPMC_AD6, PIN_INPUT_PULLUP, MUX_MODE0) AM33XX_PADCONF(AM335X_PIN_GPMC_AD7, PIN_INPUT_PULLUP, MUX_MODE0) AM33XX_PADCONF(AM335X_PIN_GPMC_WAIT0, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_GPMC_WPN, PIN_INPUT_PULLUP, MUX_MODE7) /* gpmc_wpn.gpio0_30 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_WPN, PIN_INPUT_PULLUP, MUX_MODE7) /* gpmc_wpn.gpio0_31 */ AM33XX_PADCONF(AM335X_PIN_GPMC_CSN0, PIN_OUTPUT, MUX_MODE0) AM33XX_PADCONF(AM335X_PIN_GPMC_ADVN_ALE, PIN_OUTPUT, MUX_MODE0) AM33XX_PADCONF(AM335X_PIN_GPMC_OEN_REN, PIN_OUTPUT, MUX_MODE0) diff --git a/arch/arm/boot/dts/am335x-nano.dts b/arch/arm/boot/dts/am335x-nano.dts index 0946fbf1b1fb..0dbc72d726c9 100644 --- a/arch/arm/boot/dts/am335x-nano.dts +++ b/arch/arm/boot/dts/am335x-nano.dts @@ -238,7 +238,6 @@ &gpmc { compatible = "ti,am3352-gpmc"; - ti,hwmods = "gpmc"; status = "okay"; gpmc,num-waitpins = <2>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/am33xx-l4.dtsi b/arch/arm/boot/dts/am33xx-l4.dtsi index ea20e4bdf040..78088506d25b 100644 --- a/arch/arm/boot/dts/am33xx-l4.dtsi +++ b/arch/arm/boot/dts/am33xx-l4.dtsi @@ -1,5 +1,8 @@ &l4_wkup { /* 0x44c00000 */ - compatible = "ti,am33xx-l4-wkup", "simple-bus"; + compatible = "ti,am33xx-l4-wkup", "simple-pm-bus"; + power-domains = <&prm_wkup>; + clocks = <&l4_wkup_clkctrl AM3_L4_WKUP_L4_WKUP_CLKCTRL 0>; + clock-names = "fck"; reg = <0x44c00000 0x800>, <0x44c00800 0x800>, <0x44c01000 0x400>, @@ -12,7 +15,7 @@ <0x00200000 0x44e00000 0x100000>; /* segment 2 */ segment@0 { /* 0x44c00000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x00000000 0x000800>, /* ap 0 */ @@ -22,7 +25,7 @@ }; segment@100000 { /* 0x44d00000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x00100000 0x004000>, /* ap 4 */ @@ -34,23 +37,27 @@ compatible = "ti,sysc-omap4", "ti,sysc"; reg = <0x0 0x4>; reg-names = "rev"; + clocks = <&l4_wkup_aon_clkctrl AM3_L4_WKUP_AON_WKUP_M3_CLKCTRL 0>; + clock-names = "fck"; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x0 0x4000>; - status = "disabled"; - }; + ranges = <0x00000000 0x00000000 0x4000>, + <0x00080000 0x00080000 0x2000>; - target-module@80000 { /* 0x44d80000, ap 6 10.0 */ - compatible = "ti,sysc"; - status = "disabled"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x80000 0x2000>; + wkup_m3: cpu@0 { + compatible = "ti,am3352-wkup-m3"; + reg = <0x00000000 0x4000>, + <0x00080000 0x2000>; + reg-names = "umem", "dmem"; + resets = <&prm_wkup 3>; + reset-names = "rstctrl"; + ti,pm-firmware = "am335x-pm-firmware.elf"; + }; }; }; segment@200000 { /* 0x44e00000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x00200000 0x002000>, /* ap 8 */ @@ -274,6 +281,9 @@ compatible = "ti,sysc-omap4", "ti,sysc"; reg = <0x10000 0x4>; reg-names = "rev"; + clocks = <&l4_wkup_clkctrl AM3_L4_WKUP_CONTROL_CLKCTRL 0>; + clock-names = "fck"; + ti,no-idle; #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x00010000 0x00010000>, @@ -433,6 +443,7 @@ <SYSC_IDLE_SMART>, <SYSC_IDLE_SMART_WKUP>; /* Domains (P, C): rtc_pwrdm, l4_rtc_clkdm */ + power-domains = <&prm_rtc>; clocks = <&l4_rtc_clkctrl AM3_L4_RTC_RTC_CLKCTRL 0>; clock-names = "fck"; #address-cells = <1>; @@ -658,7 +669,10 @@ }; &l4_fast { /* 0x4a000000 */ - compatible = "ti,am33xx-l4-fast", "simple-bus"; + compatible = "ti,am33xx-l4-fast", "simple-pm-bus"; + power-domains = <&prm_per>; + clocks = <&l4hs_clkctrl AM3_L4HS_L4_HS_CLKCTRL 0>; + clock-names = "fck"; reg = <0x4a000000 0x800>, <0x4a000800 0x800>, <0x4a001000 0x400>; @@ -668,7 +682,7 @@ ranges = <0x00000000 0x4a000000 0x1000000>; /* segment 0 */ segment@0 { /* 0x4a000000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x00000000 0x000800>, /* ap 0 */ @@ -837,7 +851,10 @@ }; &l4_per { /* 0x48000000 */ - compatible = "ti,am33xx-l4-per", "simple-bus"; + compatible = "ti,am33xx-l4-per", "simple-pm-bus"; + power-domains = <&prm_per>; + clocks = <&l4ls_clkctrl AM3_L4LS_L4_LS_CLKCTRL 0>; + clock-names = "fck"; reg = <0x48000000 0x800>, <0x48000800 0x800>, <0x48001000 0x400>, @@ -855,7 +872,7 @@ <0x46400000 0x46400000 0x400000>; /* l3 data port */ segment@0 { /* 0x48000000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x00000000 0x000800>, /* ap 0 */ @@ -1466,7 +1483,7 @@ }; segment@100000 { /* 0x48100000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x0008c000 0x0018c000 0x001000>, /* ap 42 */ @@ -1850,13 +1867,31 @@ }; segment@200000 { /* 0x48200000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; + ranges = <0x00000000 0x00200000 0x010000>; + + target-module@0 { + compatible = "ti,sysc-omap4-simple", "ti,sysc"; + power-domains = <&prm_mpu>; + clocks = <&mpu_clkctrl AM3_MPU_MPU_CLKCTRL 0>; + clock-names = "fck"; + ti,no-idle; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0x10000>; + + mpu@0 { + compatible = "ti,omap3-mpu"; + pm-sram = <&pm_sram_code + &pm_sram_data>; + }; + }; }; segment@300000 { /* 0x48300000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x00300000 0x001000>, /* ap 66 */ @@ -1923,6 +1958,15 @@ status = "disabled"; }; + eqep0: counter@180 { + compatible = "ti,am3352-eqep"; + reg = <0x180 0x80>; + clocks = <&l4ls_gclk>; + clock-names = "sysclkout"; + interrupts = <79>; + status = "disabled"; + }; + ehrpwm0: pwm@200 { compatible = "ti,am3352-ehrpwm", "ti,am33xx-ehrpwm"; @@ -1975,6 +2019,15 @@ status = "disabled"; }; + eqep1: counter@180 { + compatible = "ti,am3352-eqep"; + reg = <0x180 0x80>; + clocks = <&l4ls_gclk>; + clock-names = "sysclkout"; + interrupts = <88>; + status = "disabled"; + }; + ehrpwm1: pwm@200 { compatible = "ti,am3352-ehrpwm", "ti,am33xx-ehrpwm"; @@ -2027,6 +2080,15 @@ status = "disabled"; }; + eqep2: counter@180 { + compatible = "ti,am3352-eqep"; + reg = <0x180 0x80>; + clocks = <&l4ls_gclk>; + clock-names = "sysclkout"; + interrupts = <89>; + status = "disabled"; + }; + ehrpwm2: pwm@200 { compatible = "ti,am3352-ehrpwm", "ti,am33xx-ehrpwm"; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 4c2298024137..5b213a1e68bb 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -144,11 +144,28 @@ }; }; - pmu@4b000000 { - compatible = "arm,cortex-a8-pmu"; - interrupts = <3>; - reg = <0x4b000000 0x1000000>; - ti,hwmods = "debugss"; + target-module@4b000000 { + compatible = "ti,sysc-omap4-simple", "ti,sysc"; + clocks = <&l3_clkctrl AM3_L3_L3_INSTR_CLKCTRL 0>; + clock-names = "fck"; + ti,no-idle; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x4b000000 0x1000000>; + + target-module@140000 { + compatible = "ti,sysc-omap4-simple", "ti,sysc"; + clocks = <&l3_aon_clkctrl AM3_L3_AON_DEBUGSS_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x140000 0xec0000>; + + pmu@0 { + compatible = "arm,cortex-a8-pmu"; + interrupts = <3>; + }; + }; }; /* @@ -157,12 +174,6 @@ */ soc { compatible = "ti,omap-infra"; - mpu { - compatible = "ti,omap3-mpu"; - ti,hwmods = "mpu"; - pm-sram = <&pm_sram_code - &pm_sram_data>; - }; }; /* @@ -173,21 +184,15 @@ * the whole bus hierarchy. */ ocp: ocp { - compatible = "simple-bus"; + compatible = "simple-pm-bus"; + power-domains = <&prm_per>; + clocks = <&l3_clkctrl AM3_L3_L3_MAIN_CLKCTRL 0>; + clock-names = "fck"; #address-cells = <1>; #size-cells = <1>; ranges; - ti,hwmods = "l3_main"; l4_wkup: interconnect@44c00000 { - wkup_m3: wkup_m3@100000 { - compatible = "ti,am3352-wkup-m3"; - reg = <0x100000 0x4000>, - <0x180000 0x2000>; - reg-names = "umem", "dmem"; - ti,hwmods = "wkup_m3"; - ti,pm-firmware = "am335x-pm-firmware.elf"; - }; }; l4_per: interconnect@48000000 { }; @@ -458,53 +463,89 @@ }; }; - ocmcram: sram@40300000 { - compatible = "mmio-sram"; - reg = <0x40300000 0x10000>; /* 64k */ - ranges = <0x0 0x40300000 0x10000>; + target-module@40300000 { + compatible = "ti,sysc-omap4-simple", "ti,sysc"; + clocks = <&l3_clkctrl AM3_L3_OCMCRAM_CLKCTRL 0>; + clock-names = "fck"; + ti,no-idle; #address-cells = <1>; #size-cells = <1>; - - pm_sram_code: pm-code-sram@0 { - compatible = "ti,sram"; - reg = <0x0 0x1000>; - protect-exec; - }; - - pm_sram_data: pm-data-sram@1000 { - compatible = "ti,sram"; - reg = <0x1000 0x1000>; - pool; + ranges = <0 0x40300000 0x10000>; + + ocmcram: sram@0 { + compatible = "mmio-sram"; + reg = <0 0x10000>; /* 64k */ + ranges = <0 0 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + pm_sram_code: pm-code-sram@0 { + compatible = "ti,sram"; + reg = <0x0 0x1000>; + protect-exec; + }; + + pm_sram_data: pm-data-sram@1000 { + compatible = "ti,sram"; + reg = <0x1000 0x1000>; + pool; + }; }; }; - emif: emif@4c000000 { - compatible = "ti,emif-am3352"; - reg = <0x4c000000 0x1000000>; - ti,hwmods = "emif"; - interrupts = <101>; - sram = <&pm_sram_code - &pm_sram_data>; + target-module@4c000000 { + compatible = "ti,sysc-omap4-simple", "ti,sysc"; + reg = <0x4c000000 0x4>; + reg-names = "rev"; + clocks = <&l3_clkctrl AM3_L3_EMIF_CLKCTRL 0>; + clock-names = "fck"; ti,no-idle; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x4c000000 0x1000000>; + + emif: emif@0 { + compatible = "ti,emif-am3352"; + reg = <0 0x1000000>; + interrupts = <101>; + sram = <&pm_sram_code + &pm_sram_data>; + }; }; - gpmc: gpmc@50000000 { - compatible = "ti,am3352-gpmc"; - ti,hwmods = "gpmc"; - ti,no-idle-on-init; - reg = <0x50000000 0x2000>; - interrupts = <100>; - dmas = <&edma 52 0>; - dma-names = "rxtx"; - gpmc,num-cs = <7>; - gpmc,num-waitpins = <2>; - #address-cells = <2>; + target-module@50000000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x50000000 4>, + <0x50000010 4>, + <0x50000014 4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,syss-mask = <1>; + clocks = <&l3s_clkctrl AM3_L3S_GPMC_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; #size-cells = <1>; - interrupt-controller; - #interrupt-cells = <2>; - gpio-controller; - #gpio-cells = <2>; - status = "disabled"; + ranges = <0x50000000 0x50000000 0x00001000>, /* regs */ + <0x00000000 0x00000000 0x40000000>; /* data */ + + gpmc: gpmc@50000000 { + compatible = "ti,am3352-gpmc"; + reg = <0x50000000 0x2000>; + interrupts = <100>; + dmas = <&edma 52 0>; + dma-names = "rxtx"; + gpmc,num-cs = <7>; + gpmc,num-waitpins = <2>; + #address-cells = <2>; + #size-cells = <1>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; }; sham_target: target-module@53100000 { @@ -601,12 +642,20 @@ compatible = "ti,am3-prm-inst", "ti,omap-prm-inst"; reg = <0xc00 0x100>; #reset-cells = <1>; + #power-domain-cells = <0>; }; prm_wkup: prm@d00 { compatible = "ti,am3-prm-inst", "ti,omap-prm-inst"; reg = <0xd00 0x100>; #reset-cells = <1>; + #power-domain-cells = <0>; + }; + + prm_mpu: prm@e00 { + compatible = "ti,am3-prm-inst", "ti,omap-prm-inst"; + reg = <0xe00 0x100>; + #power-domain-cells = <0>; }; prm_device: prm@f00 { @@ -615,16 +664,31 @@ #reset-cells = <1>; }; + prm_rtc: prm@1000 { + compatible = "ti,am3-prm-inst", "ti,omap-prm-inst"; + reg = <0x1000 0x100>; + #power-domain-cells = <0>; + }; + prm_gfx: prm@1100 { compatible = "ti,am3-prm-inst", "ti,omap-prm-inst"; reg = <0x1100 0x100>; #power-domain-cells = <0>; #reset-cells = <1>; }; + + prm_cefuse: prm@1200 { + compatible = "ti,am3-prm-inst", "ti,omap-prm-inst"; + reg = <0x1200 0x100>; + #power-domain-cells = <0>; + }; }; /* Preferred always-on timer for clocksource */ &timer1_target { + clocks = <&l4_wkup_clkctrl AM3_L4_WKUP_TIMER1_CLKCTRL 0>, + <&l4_wkup_clkctrl AM3_L4_WKUP_L4_WKUP_CLKCTRL 0>; + clock-names = "fck", "ick"; ti,no-reset-on-init; ti,no-idle; timer@0 { @@ -635,6 +699,9 @@ /* Preferred timer for clockevent */ &timer2_target { + clocks = <&l4ls_clkctrl AM3_L4LS_TIMER2_CLKCTRL 0>, + <&l4ls_clkctrl AM3_L4LS_L4_LS_CLKCTRL 0>; + clock-names = "fck", "ick"; ti,no-reset-on-init; ti,no-idle; timer@0 { diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 878406b120be..57a85a6c34a2 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -107,12 +107,6 @@ soc { compatible = "ti,omap-infra"; - mpu { - compatible = "ti,omap4-mpu"; - ti,hwmods = "mpu"; - pm-sram = <&pm_sram_code - &pm_sram_data>; - }; }; gic: interrupt-controller@48241000 { @@ -161,40 +155,48 @@ }; ocp@44000000 { - compatible = "ti,am4372-l3-noc", "simple-bus"; + compatible = "simple-pm-bus"; + power-domains = <&prm_per>; + clocks = <&l3_clkctrl AM4_L3_L3_MAIN_CLKCTRL 0>; + clock-names = "fck"; #address-cells = <1>; #size-cells = <1>; ranges; - ti,hwmods = "l3_main"; ti,no-idle; - reg = <0x44000000 0x400000 - 0x44800000 0x400000>; - interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + + l3-noc@44000000 { + compatible = "ti,am4372-l3-noc"; + reg = <0x44000000 0x400000>, + <0x44800000 0x400000>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + }; l4_wkup: interconnect@44c00000 { - wkup_m3: wkup_m3@100000 { - compatible = "ti,am4372-wkup-m3"; - reg = <0x100000 0x4000>, - <0x180000 0x2000>; - reg-names = "umem", "dmem"; - ti,hwmods = "wkup_m3"; - ti,pm-firmware = "am335x-pm-firmware.elf"; - }; }; l4_per: interconnect@48000000 { }; l4_fast: interconnect@4a000000 { }; - emif: emif@4c000000 { - compatible = "ti,emif-am4372"; - reg = <0x4c000000 0x1000000>; - ti,hwmods = "emif"; - interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + target-module@4c000000 { + compatible = "ti,sysc-omap4-simple", "ti,sysc"; + reg = <0x4c000000 0x4>; + reg-names = "rev"; + clocks = <&emif_clkctrl AM4_EMIF_EMIF_CLKCTRL 0>; + clock-names = "fck"; ti,no-idle; - sram = <&pm_sram_code - &pm_sram_data>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x4c000000 0x1000000>; + + emif: emif@0 { + compatible = "ti,emif-am4372"; + reg = <0 0x1000000>; + interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + sram = <&pm_sram_code + &pm_sram_data>; + }; }; target-module@49000000 { @@ -434,24 +436,41 @@ ranges = <0x0 0x54400000 0x80000>; }; - gpmc: gpmc@50000000 { - compatible = "ti,am3352-gpmc"; - ti,hwmods = "gpmc"; - dmas = <&edma 52 0>; - dma-names = "rxtx"; - clocks = <&l3s_gclk>; + target-module@50000000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x50000000 4>, + <0x50000010 4>, + <0x50000014 4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,syss-mask = <1>; + clocks = <&l3s_clkctrl AM4_L3S_GPMC_CLKCTRL 0>; clock-names = "fck"; - reg = <0x50000000 0x2000>; - interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; - gpmc,num-cs = <7>; - gpmc,num-waitpins = <2>; - #address-cells = <2>; + #address-cells = <1>; #size-cells = <1>; - interrupt-controller; - #interrupt-cells = <2>; - gpio-controller; - #gpio-cells = <2>; - status = "disabled"; + ranges = <0x50000000 0x50000000 0x00001000>, /* regs */ + <0x00000000 0x00000000 0x40000000>; /* data */ + + gpmc: gpmc@50000000 { + compatible = "ti,am3352-gpmc"; + dmas = <&edma 52 0>; + dma-names = "rxtx"; + clocks = <&l3s_gclk>; + clock-names = "fck"; + reg = <0x50000000 0x2000>; + interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; + gpmc,num-cs = <7>; + gpmc,num-waitpins = <2>; + #address-cells = <2>; + #size-cells = <1>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; }; target-module@47900000 { @@ -484,23 +503,33 @@ }; }; - ocmcram: sram@40300000 { - compatible = "mmio-sram"; - reg = <0x40300000 0x40000>; /* 256k */ - ranges = <0x0 0x40300000 0x40000>; + target-module@40300000 { + compatible = "ti,sysc-omap4-simple", "ti,sysc"; + clocks = <&l3_clkctrl AM4_L3_OCMCRAM_CLKCTRL 0>; + clock-names = "fck"; + ti,no-idle; #address-cells = <1>; #size-cells = <1>; + ranges = <0 0x40300000 0x40000>; - pm_sram_code: pm-code-sram@0 { - compatible = "ti,sram"; - reg = <0x0 0x1000>; - protect-exec; - }; - - pm_sram_data: pm-data-sram@1000 { - compatible = "ti,sram"; - reg = <0x1000 0x1000>; - pool; + ocmcram: sram@0 { + compatible = "mmio-sram"; + reg = <0 0x40000>; /* 256k */ + ranges = <0 0 0x40000>; + #address-cells = <1>; + #size-cells = <1>; + + pm_sram_code: pm-code-sram@0 { + compatible = "ti,sram"; + reg = <0x0 0x1000>; + protect-exec; + }; + + pm_sram_data: pm-data-sram@1000 { + compatible = "ti,sram"; + reg = <0x1000 0x1000>; + pool; + }; }; }; @@ -531,6 +560,12 @@ #include "am43xx-clocks.dtsi" &prcm { + prm_mpu: prm@300 { + compatible = "ti,am4-prm-inst", "ti,omap-prm-inst"; + reg = <0x300 0x100>; + #power-domain-cells = <0>; + }; + prm_gfx: prm@400 { compatible = "ti,am4-prm-inst", "ti,omap-prm-inst"; reg = <0x400 0x100>; @@ -538,16 +573,36 @@ #reset-cells = <1>; }; + prm_rtc: prm@500 { + compatible = "ti,am4-prm-inst", "ti,omap-prm-inst"; + reg = <0x500 0x100>; + #power-domain-cells = <0>; + }; + + prm_tamper: prm@600 { + compatible = "ti,am4-prm-inst", "ti,omap-prm-inst"; + reg = <0x600 0x100>; + #power-domain-cells = <0>; + }; + + prm_cefuse: prm@700 { + compatible = "ti,am4-prm-inst", "ti,omap-prm-inst"; + reg = <0x700 0x100>; + #power-domain-cells = <0>; + }; + prm_per: prm@800 { compatible = "ti,am4-prm-inst", "ti,omap-prm-inst"; reg = <0x800 0x100>; #reset-cells = <1>; + #power-domain-cells = <0>; }; prm_wkup: prm@2000 { compatible = "ti,am4-prm-inst", "ti,omap-prm-inst"; reg = <0x2000 0x100>; #reset-cells = <1>; + #power-domain-cells = <0>; }; prm_device: prm@4000 { @@ -561,6 +616,9 @@ &timer1_target { ti,no-reset-on-init; ti,no-idle; + clocks = <&l4_wkup_clkctrl AM4_L4_WKUP_TIMER1_CLKCTRL 0>, + <&l4_wkup_clkctrl AM4_L4_WKUP_L4_WKUP_CLKCTRL 0>; + clock-names = "fck", "ick"; timer@0 { assigned-clocks = <&timer1_fck>; assigned-clock-parents = <&sys_clkin_ck>; @@ -571,6 +629,9 @@ &timer2_target { ti,no-reset-on-init; ti,no-idle; + clocks = <&l4ls_clkctrl AM4_L4LS_TIMER2_CLKCTRL 0>, + <&l4ls_clkctrl AM4_L4LS_L4_LS_CLKCTRL 0>; + clock-names = "fck", "ick"; timer@0 { assigned-clocks = <&timer2_fck>; assigned-clock-parents = <&sys_clkin_ck>; diff --git a/arch/arm/boot/dts/am437x-l4.dtsi b/arch/arm/boot/dts/am437x-l4.dtsi index 243e35f7a56c..e217ffc09770 100644 --- a/arch/arm/boot/dts/am437x-l4.dtsi +++ b/arch/arm/boot/dts/am437x-l4.dtsi @@ -1,5 +1,8 @@ &l4_wkup { /* 0x44c00000 */ - compatible = "ti,am4-l4-wkup", "simple-bus"; + compatible = "ti,am4-l4-wkup", "simple-pm-bus"; + power-domains = <&prm_wkup>; + clocks = <&l4_wkup_clkctrl AM4_L4_WKUP_L4_WKUP_CLKCTRL 0>; + clock-names = "fck"; reg = <0x44c00000 0x800>, <0x44c00800 0x800>, <0x44c01000 0x400>, @@ -12,7 +15,7 @@ <0x00200000 0x44e00000 0x100000>; /* segment 2 */ segment@0 { /* 0x44c00000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x00000000 0x000800>, /* ap 0 */ @@ -22,7 +25,7 @@ }; segment@100000 { /* 0x44d00000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x00100000 0x004000>, /* ap 4 */ @@ -32,19 +35,25 @@ <0x000f0000 0x001f0000 0x010000>; /* ap 8 */ target-module@0 { /* 0x44d00000, ap 4 28.0 */ - compatible = "ti,sysc"; - status = "disabled"; + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x0 0x4>; + reg-names = "rev"; + clocks = <&l4_wkup_aon_clkctrl AM4_L4_WKUP_AON_WKUP_M3_CLKCTRL 0>; + clock-names = "fck"; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x0 0x4000>; - }; + ranges = <0x00000000 0x00000000 0x4000>, + <0x00080000 0x00080000 0x2000>; - target-module@80000 { /* 0x44d80000, ap 6 10.0 */ - compatible = "ti,sysc"; - status = "disabled"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x80000 0x2000>; + wkup_m3: cpu@0 { + compatible = "ti,am4372-wkup-m3"; + reg = <0x00000000 0x4000>, + <0x00080000 0x2000>; + reg-names = "umem", "dmem"; + resets = <&prm_wkup 3>; + reset-names = "rstctrl"; + ti,pm-firmware = "am335x-pm-firmware.elf"; + }; }; target-module@f0000 { /* 0x44df0000, ap 8 58.0 */ @@ -75,7 +84,7 @@ }; segment@200000 { /* 0x44e00000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x00200000 0x001000>, /* ap 9 */ @@ -265,6 +274,9 @@ compatible = "ti,sysc-omap4", "ti,sysc"; reg = <0x10000 0x4>; reg-names = "rev"; + clocks = <&l4_wkup_clkctrl AM4_L4_WKUP_CONTROL_CLKCTRL 0>; + clock-names = "fck"; + ti,no-idle; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x10000 0x10000>; @@ -419,6 +431,7 @@ <SYSC_IDLE_SMART>, <SYSC_IDLE_SMART_WKUP>; /* Domains (P, C): rtc_pwrdm, l4_rtc_clkdm */ + power-domains = <&prm_rtc>; clocks = <&l4_rtc_clkctrl AM4_L4_RTC_RTC_CLKCTRL 0>; clock-names = "fck"; #address-cells = <1>; @@ -479,7 +492,10 @@ }; &l4_fast { /* 0x4a000000 */ - compatible = "ti,am4-l4-fast", "simple-bus"; + compatible = "ti,am4-l4-fast", "simple-pm-bus"; + power-domains = <&prm_per>; + clocks = <&l3_clkctrl AM4_L3_L4_HS_CLKCTRL 0>; + clock-names = "fck"; reg = <0x4a000000 0x800>, <0x4a000800 0x800>, <0x4a001000 0x400>; @@ -489,7 +505,7 @@ ranges = <0x00000000 0x4a000000 0x1000000>; /* segment 0 */ segment@0 { /* 0x4a000000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x00000000 0x000800>, /* ap 0 */ @@ -594,7 +610,10 @@ }; &l4_per { /* 0x48000000 */ - compatible = "ti,am4-l4-per", "simple-bus"; + compatible = "ti,am4-l4-per", "simple-pm-bus"; + power-domains = <&prm_per>; + clocks = <&l4ls_clkctrl AM4_L4LS_L4_LS_CLKCTRL 0>; + clock-names = "fck"; reg = <0x48000000 0x800>, <0x48000800 0x800>, <0x48001000 0x400>, @@ -612,7 +631,7 @@ <0x46400000 0x46400000 0x400000>; /* l3 data port */ segment@0 { /* 0x48000000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x00000000 0x000800>, /* ap 0 */ @@ -1187,7 +1206,7 @@ }; segment@100000 { /* 0x48100000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x0008c000 0x0018c000 0x001000>, /* ap 34 */ @@ -1618,13 +1637,31 @@ }; segment@200000 { /* 0x48200000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; + ranges = <0x00000000 0x00200000 0x010000>; + + target-module@0 { + compatible = "ti,sysc-omap4-simple", "ti,sysc"; + power-domains = <&prm_mpu>; + clocks = <&mpu_clkctrl AM4_MPU_MPU_CLKCTRL 0>; + clock-names = "fck"; + ti,no-idle; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0x10000>; + + mpu@0 { + compatible = "ti,omap4-mpu"; + pm-sram = <&pm_sram_code + &pm_sram_data>; + }; + }; }; segment@300000 { /* 0x48300000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x00300000 0x001000>, /* ap 56 */ @@ -2388,7 +2425,7 @@ ranges = <0 0 0x20000>; usb1: usb@10000 { - compatible = "synopsys,dwc3"; + compatible = "snps,dwc3"; reg = <0x10000 0x10000>; interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, @@ -2468,7 +2505,7 @@ ranges = <0 0 0x20000>; usb2: usb@10000 { - compatible = "synopsys,dwc3"; + compatible = "snps,dwc3"; reg = <0x10000 0x10000>; interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>, diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi index 9805e507c695..7f2f24a29e6c 100644 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@ -426,7 +426,7 @@ status = "disabled"; }; - usb2: usb3@58000 { + usb2: usb@58000 { compatible = "marvell,armada-375-xhci"; reg = <0x58000 0x20000>,<0x5b880 0x80>; interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm/boot/dts/armada-382-rd-ac3x-48g4x2xl.dts b/arch/arm/boot/dts/armada-382-rd-ac3x-48g4x2xl.dts new file mode 100644 index 000000000000..584f0d0398a5 --- /dev/null +++ b/arch/arm/boot/dts/armada-382-rd-ac3x-48g4x2xl.dts @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Device Tree file for Marvell Armada 382 reference board + * (RD-AC3X-48G4X2XL) + * + * Copyright (C) 2020 Allied Telesis Labs + */ + +/dts-v1/; +#include "armada-385.dtsi" + +#include <dt-bindings/gpio/gpio.h> + +/ { + model = "Marvell Armada 382 RD-AC3X"; + compatible = "marvell,rd-ac3x-48g4x2xl", "marvell,rd-ac3x", + "marvell,armada385", "marvell,armada380"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + ethernet0 = ð1; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x20000000>; /* 512MB */ + }; + + soc { + ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000 + MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + status = "okay"; + + eeprom@53{ + compatible = "atmel,24c64"; + reg = <0x53>; + }; + + /* CPLD device present at 0x3c. Function unknown */ +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +ð1 { + status = "okay"; + phy = <&phy0>; + phy-mode = "rgmii-id"; +}; + +&mdio { + pinctrl-names = "default"; + pinctrl-0 = <&mdio_pins>; + + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + +&pciec { + status = "okay"; +}; + +&pcie1 { + /* Port 0, Lane 0 */ + status = "okay"; +}; + +&nand_controller { + status = "okay"; + + nand@0 { + reg = <0>; + label = "pxa3xx_nand-0"; + nand-rb = <0>; + nand-on-flash-bbt; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + reg = <0x00000000 0x00500000>; + label = "u-boot"; + }; + partition@500000{ + reg = <0x00500000 0x00400000>; + label = "u-boot env"; + }; + partition@900000{ + reg = <0x00900000 0x3F700000>; + label = "user"; + }; + }; + }; +}; + +&refclk { + clock-frequency = <200000000>; +}; diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts index 768b6c5d2129..646a06420c77 100644 --- a/arch/arm/boot/dts/armada-385-turris-omnia.dts +++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts @@ -12,6 +12,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> #include "armada-385.dtsi" / { @@ -82,6 +83,32 @@ }; }; }; + + sfp: sfp { + compatible = "sff,sfp"; + i2c-bus = <&sfp_i2c>; + tx-fault-gpios = <&pcawan 0 GPIO_ACTIVE_HIGH>; + tx-disable-gpios = <&pcawan 1 GPIO_ACTIVE_HIGH>; + rate-select0-gpios = <&pcawan 2 GPIO_ACTIVE_HIGH>; + los-gpios = <&pcawan 3 GPIO_ACTIVE_HIGH>; + mod-def0-gpios = <&pcawan 4 GPIO_ACTIVE_LOW>; + maximum-power-milliwatt = <3000>; + + /* + * For now this has to be enabled at boot time by U-Boot when + * a SFP module is present. Read more in the comment in the + * eth2 node below. + */ + status = "disabled"; + }; +}; + +&bm { + status = "okay"; +}; + +&bm_bppi { + status = "okay"; }; /* Connected to 88E6176 switch, port 6 */ @@ -90,6 +117,9 @@ pinctrl-0 = <&ge0_rgmii_pins>; status = "okay"; phy-mode = "rgmii"; + buffer-manager = <&bm>; + bm,pool-long = <0>; + bm,pool-short = <3>; fixed-link { speed = <1000>; @@ -103,6 +133,9 @@ pinctrl-0 = <&ge1_rgmii_pins>; status = "okay"; phy-mode = "rgmii"; + buffer-manager = <&bm>; + bm,pool-long = <1>; + bm,pool-short = <3>; fixed-link { speed = <1000>; @@ -112,9 +145,23 @@ /* WAN port */ ð2 { + /* + * eth2 is connected via a multiplexor to both the SFP cage and to + * ethernet-phy@1. The multiplexor switches the signal to SFP cage when + * a SFP module is present, as determined by the mode-def0 GPIO. + * + * Until kernel supports this configuration properly, in case SFP module + * is present, U-Boot has to enable the sfp node above, remove phy + * handle and add managed = "in-band-status" property. + */ status = "okay"; phy-mode = "sgmii"; - phy = <&phy1>; + phy-handle = <&phy1>; + phys = <&comphy5 2>; + sfp = <&sfp>; + buffer-manager = <&bm>; + bm,pool-long = <2>; + bm,pool-short = <3>; }; &i2c0 { @@ -127,7 +174,6 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x70>; - status = "okay"; i2c@0 { #address-cells = <1>; @@ -135,7 +181,115 @@ reg = <0>; /* STM32F0 command interface at address 0x2a */ - /* leds device (in STM32F0) at address 0x2b */ + + led-controller@2b { + compatible = "cznic,turris-omnia-leds"; + reg = <0x2b>; + #address-cells = <1>; + #size-cells = <0>; + + /* + * LEDs are controlled by MCU (STM32F0) at + * address 0x2b. + * + * The driver does not support HW control mode + * for the LEDs yet. Disable the LEDs for now. + * + * Also LED functions are not stable yet: + * - there are 3 LEDs connected via MCU to PCIe + * ports. One of these ports supports mSATA. + * There is no mSATA nor PCIe function. + * For now we use LED_FUNCTION_WLAN, since + * in most cases users have wifi cards in + * these slots + * - there are 2 LEDs dedicated for user: A and + * B. Again there is no such function defined. + * For now we use LED_FUNCTION_INDICATOR + */ + status = "disabled"; + + multi-led@0 { + reg = <0x0>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <2>; + }; + + multi-led@1 { + reg = <0x1>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <1>; + }; + + multi-led@2 { + reg = <0x2>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_WLAN; + function-enumerator = <3>; + }; + + multi-led@3 { + reg = <0x3>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_WLAN; + function-enumerator = <2>; + }; + + multi-led@4 { + reg = <0x4>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_WLAN; + function-enumerator = <1>; + }; + + multi-led@5 { + reg = <0x5>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_WAN; + }; + + multi-led@6 { + reg = <0x6>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_LAN; + function-enumerator = <4>; + }; + + multi-led@7 { + reg = <0x7>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_LAN; + function-enumerator = <3>; + }; + + multi-led@8 { + reg = <0x8>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_LAN; + function-enumerator = <2>; + }; + + multi-led@9 { + reg = <0x9>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_LAN; + function-enumerator = <1>; + }; + + multi-led@a { + reg = <0xa>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_LAN; + function-enumerator = <0>; + }; + + multi-led@b { + reg = <0xb>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_POWER; + }; + }; eeprom@54 { compatible = "atmel,24c64"; @@ -177,7 +331,7 @@ /* routed to PCIe2 connector (CN62A) */ }; - i2c@4 { + sfp_i2c: i2c@4 { #address-cells = <1>; #size-cells = <0>; reg = <4>; @@ -232,9 +386,8 @@ pinctrl-0 = <&mdio_pins>; status = "okay"; - phy1: phy@1 { - status = "okay"; - compatible = "ethernet-phy-id0141.0DD1", "ethernet-phy-ieee802.3-c22"; + phy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; reg = <1>; /* irq is connected to &pcawan pin 7 */ @@ -242,13 +395,18 @@ /* Switch MV88E6176 at address 0x10 */ switch@10 { + pinctrl-names = "default"; + pinctrl-0 = <&swint_pins>; compatible = "marvell,mv88e6085"; #address-cells = <1>; #size-cells = <0>; - dsa,member = <0 0>; + dsa,member = <0 0>; reg = <0x10>; + interrupt-parent = <&gpio1>; + interrupts = <13 IRQ_TYPE_LEVEL_LOW>; + ports { #address-cells = <1>; #size-cells = <0>; @@ -301,6 +459,11 @@ marvell,function = "gpio"; }; + swint_pins: swint-pins { + marvell,pins = "mpp45"; + marvell,function = "gpio"; + }; + spi0cs0_pins: spi0cs0-pins { marvell,pins = "mpp25"; marvell,function = "spi0"; diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts index 20f8d4667753..4140a5303b48 100644 --- a/arch/arm/boot/dts/armada-388-clearfog.dts +++ b/arch/arm/boot/dts/armada-388-clearfog.dts @@ -73,13 +73,13 @@ * 14-SFP_TX_DISABLE * 15-SFP_MOD_DEF0 */ - pcie2_0_clkreq { + pcie2-0-clkreq-hog { gpio-hog; gpios = <4 GPIO_ACTIVE_LOW>; input; line-name = "pcie2.0-clkreq"; }; - pcie2_0_w_disable { + pcie2-0-w-disable-hog { gpio-hog; gpios = <7 GPIO_ACTIVE_LOW>; output-low; diff --git a/arch/arm/boot/dts/armada-388-clearfog.dtsi b/arch/arm/boot/dts/armada-388-clearfog.dtsi index a0aa1d188f0c..f8a06ae4a3c9 100644 --- a/arch/arm/boot/dts/armada-388-clearfog.dtsi +++ b/arch/arm/boot/dts/armada-388-clearfog.dtsi @@ -141,31 +141,31 @@ #gpio-cells = <2>; reg = <0x20>; - pcie1_0_clkreq { + pcie1-0-clkreq-hog { gpio-hog; gpios = <0 GPIO_ACTIVE_LOW>; input; line-name = "pcie1.0-clkreq"; }; - pcie1_0_w_disable { + pcie1-0-w-disable-hog { gpio-hog; gpios = <3 GPIO_ACTIVE_LOW>; output-low; line-name = "pcie1.0-w-disable"; }; - usb3_ilimit { + usb3-ilimit-hog { gpio-hog; gpios = <5 GPIO_ACTIVE_LOW>; input; line-name = "usb3-current-limit"; }; - usb3_power { + usb3-power-hog { gpio-hog; gpios = <6 GPIO_ACTIVE_HIGH>; output-high; line-name = "usb3-power"; }; - m2_devslp { + m2-devslp-hog { gpio-hog; gpios = <11 GPIO_ACTIVE_HIGH>; output-low; diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts index fb49df2a3bce..b3728de3bd3f 100644 --- a/arch/arm/boot/dts/armada-388-helios4.dts +++ b/arch/arm/boot/dts/armada-388-helios4.dts @@ -166,19 +166,19 @@ interrupt-controller; #interrupt-cells = <2>; - board_rev_bit_0 { + board-rev-bit-0-hog { gpio-hog; gpios = <0 GPIO_ACTIVE_LOW>; input; line-name = "board-rev-0"; }; - board_rev_bit_1 { + board-rev-bit-1-hog { gpio-hog; gpios = <1 GPIO_ACTIVE_LOW>; input; line-name = "board-rev-1"; }; - usb3_ilimit { + usb3-ilimit-hog { gpio-hog; gpios = <5 GPIO_ACTIVE_HIGH>; input; diff --git a/arch/arm/boot/dts/armada-xp-98dx3236.dtsi b/arch/arm/boot/dts/armada-xp-98dx3236.dtsi index 654648b05c7c..38a052a0312d 100644 --- a/arch/arm/boot/dts/armada-xp-98dx3236.dtsi +++ b/arch/arm/boot/dts/armada-xp-98dx3236.dtsi @@ -264,11 +264,8 @@ &i2c0 { compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; reg = <0x11000 0x100>; -}; - -&i2c1 { - compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; - reg = <0x11100 0x100>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; }; &mpic { @@ -324,6 +321,11 @@ "mpp2", "mpp3"; marvell,function = "spi0"; }; + + i2c0_pins: i2c-pins-0 { + marvell,pins = "mpp14", "mpp15"; + marvell,function = "i2c0"; + }; }; &spi0 { diff --git a/arch/arm/boot/dts/armada-xp-crs305-1g-4s-bit.dts b/arch/arm/boot/dts/armada-xp-crs305-1g-4s-bit.dts new file mode 100644 index 000000000000..a022c68dc943 --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-crs305-1g-4s-bit.dts @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree file for MikroTik CRS305-1G-4S+ Bit board + * + * Copyright (C) 2020 Sartura Ltd. + * Author: Luka Kovacic <luka.kovacic@sartura.hr> + */ + +#include "armada-xp-crs305-1g-4s.dtsi" + +/ { + model = "MikroTik CRS305-1G-4S+ Bit"; +}; + +&spi0 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <108000000>; + m25p,fast-read; + + partition@u-boot { + reg = <0x00000000 0x001f0000>; + label = "u-boot"; + }; + partition@u-boot-env { + reg = <0x001f0000 0x00010000>; + label = "u-boot-env"; + }; + partition@ubi1 { + reg = <0x00200000 0x03f00000>; + label = "ubi1"; + }; + partition@ubi2 { + reg = <0x04100000 0x03f00000>; + label = "ubi2"; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-xp-crs305-1g-4s.dts b/arch/arm/boot/dts/armada-xp-crs305-1g-4s.dts new file mode 100644 index 000000000000..010b83b54212 --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-crs305-1g-4s.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree file for MikroTik CRS305-1G-4S+ board + * + * Copyright (C) 2020 Sartura Ltd. + * Author: Luka Kovacic <luka.kovacic@sartura.hr> + */ + +#include "armada-xp-crs305-1g-4s.dtsi" + +/ { + model = "MikroTik CRS305-1G-4S+"; +}; + +&spi0 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/armada-xp-crs305-1g-4s.dtsi b/arch/arm/boot/dts/armada-xp-crs305-1g-4s.dtsi new file mode 100644 index 000000000000..32fb21b2bf6a --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-crs305-1g-4s.dtsi @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree file for CRS305-1G-4S board + * + * Copyright (C) 2016 Allied Telesis Labs + * Copyright (C) 2020 Sartura Ltd. + * + * Based on armada-xp-db.dts + * + * Note: this Device Tree assumes that the bootloader has remapped the + * internal registers to 0xf1000000 (instead of the default + * 0xd0000000). The 0xf1000000 is the default used by the recent, + * DT-capable, U-Boot bootloaders provided by Marvell. Some earlier + * boards were delivered with an older version of the bootloader that + * left internal registers mapped at 0xd0000000. If you are in this + * situation, you should either update your bootloader (preferred + * solution) or the below Device Tree should be adjusted. + */ + +/dts-v1/; +#include "armada-xp-98dx3236.dtsi" + +/ { + model = "CRS305-1G-4S+"; + compatible = "mikrotik,crs305-1g-4s", "marvell,armadaxp-98dx3236", "marvell,armada-370-xp"; + + chosen { + bootargs = "console=ttyS0,115200 earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0 0x00000000 0 0x20000000>; /* 512 MB */ + }; +}; + +&L2 { + arm,parity-enable; + marvell,ecc-enable; +}; + +&devbus_bootcs { + status = "okay"; + + /* Device Bus parameters are required */ + + /* Read parameters */ + devbus,bus-width = <16>; + devbus,turn-off-ps = <60000>; + devbus,badr-skew-ps = <0>; + devbus,acc-first-ps = <124000>; + devbus,acc-next-ps = <248000>; + devbus,rd-setup-ps = <0>; + devbus,rd-hold-ps = <0>; + + /* Write parameters */ + devbus,sync-enable = <0>; + devbus,wr-high-ps = <60000>; + devbus,wr-low-ps = <60000>; + devbus,ale-wr-ps = <60000>; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&i2c0 { + clock-frequency = <100000>; + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <108000000>; + m25p,fast-read; + + partition@u-boot { + reg = <0x00000000 0x001f0000>; + label = "u-boot"; + }; + partition@u-boot-env { + reg = <0x001f0000 0x00010000>; + label = "u-boot-env"; + }; + partition@ubi1 { + reg = <0x00200000 0x00e00000>; + label = "ubi1"; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-xp-crs326-24g-2s-bit.dts b/arch/arm/boot/dts/armada-xp-crs326-24g-2s-bit.dts new file mode 100644 index 000000000000..21f442afab1f --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-crs326-24g-2s-bit.dts @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree file for MikroTik CRS326-24G-2S+ Bit board + * + * Copyright (C) 2020 Sartura Ltd. + * Author: Luka Kovacic <luka.kovacic@sartura.hr> + */ + +#include "armada-xp-crs326-24g-2s.dtsi" + +/ { + model = "MikroTik CRS326-24G-2S+ Bit"; +}; + +&spi0 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <108000000>; + m25p,fast-read; + + partition@u-boot { + reg = <0x00000000 0x001f0000>; + label = "u-boot"; + }; + partition@u-boot-env { + reg = <0x001f0000 0x00010000>; + label = "u-boot-env"; + }; + partition@ubi1 { + reg = <0x00200000 0x03f00000>; + label = "ubi1"; + }; + partition@ubi2 { + reg = <0x04100000 0x03f00000>; + label = "ubi2"; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-xp-crs326-24g-2s.dts b/arch/arm/boot/dts/armada-xp-crs326-24g-2s.dts new file mode 100644 index 000000000000..83aef43f66d5 --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-crs326-24g-2s.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree file for MikroTik CRS326-24G-2S+ board + * + * Copyright (C) 2020 Sartura Ltd. + * Author: Luka Kovacic <luka.kovacic@sartura.hr> + */ + +#include "armada-xp-crs326-24g-2s.dtsi" + +/ { + model = "MikroTik CRS326-24G-2S+"; +}; + +&spi0 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/armada-xp-crs326-24g-2s.dtsi b/arch/arm/boot/dts/armada-xp-crs326-24g-2s.dtsi new file mode 100644 index 000000000000..f3e1a25ca5f2 --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-crs326-24g-2s.dtsi @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree file for CRS326-24G-2S board + * + * Copyright (C) 2016 Allied Telesis Labs + * Copyright (C) 2020 Sartura Ltd. + * + * Based on armada-xp-db.dts + * + * Note: this Device Tree assumes that the bootloader has remapped the + * internal registers to 0xf1000000 (instead of the default + * 0xd0000000). The 0xf1000000 is the default used by the recent, + * DT-capable, U-Boot bootloaders provided by Marvell. Some earlier + * boards were delivered with an older version of the bootloader that + * left internal registers mapped at 0xd0000000. If you are in this + * situation, you should either update your bootloader (preferred + * solution) or the below Device Tree should be adjusted. + */ + +/dts-v1/; +#include "armada-xp-98dx3236.dtsi" + +/ { + model = "CRS326-24G-2S+"; + compatible = "mikrotik,crs326-24g-2s", "marvell,armadaxp-98dx3236", "marvell,armada-370-xp"; + + chosen { + bootargs = "console=ttyS0,115200 earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0 0x00000000 0 0x20000000>; /* 512 MB */ + }; +}; + +&L2 { + arm,parity-enable; + marvell,ecc-enable; +}; + +&devbus_bootcs { + status = "okay"; + + /* Device Bus parameters are required */ + + /* Read parameters */ + devbus,bus-width = <16>; + devbus,turn-off-ps = <60000>; + devbus,badr-skew-ps = <0>; + devbus,acc-first-ps = <124000>; + devbus,acc-next-ps = <248000>; + devbus,rd-setup-ps = <0>; + devbus,rd-hold-ps = <0>; + + /* Write parameters */ + devbus,sync-enable = <0>; + devbus,wr-high-ps = <60000>; + devbus,wr-low-ps = <60000>; + devbus,ale-wr-ps = <60000>; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&i2c0 { + clock-frequency = <100000>; + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <108000000>; + m25p,fast-read; + + partition@u-boot { + reg = <0x00000000 0x001f0000>; + label = "u-boot"; + }; + partition@u-boot-env { + reg = <0x001f0000 0x00010000>; + label = "u-boot-env"; + }; + partition@ubi1 { + reg = <0x00200000 0x00e00000>; + label = "ubi1"; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-xp-crs328-4c-20s-4s-bit.dts b/arch/arm/boot/dts/armada-xp-crs328-4c-20s-4s-bit.dts new file mode 100644 index 000000000000..e05aee6cdc04 --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-crs328-4c-20s-4s-bit.dts @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree file for MikroTik CRS328-4C-20S-4S+ Bit board + * + * Copyright (C) 2020 Sartura Ltd. + * Author: Luka Kovacic <luka.kovacic@sartura.hr> + */ + +#include "armada-xp-crs328-4c-20s-4s.dtsi" + +/ { + model = "MikroTik CRS328-4C-20S-4S+ Bit"; +}; + +&spi0 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <108000000>; + m25p,fast-read; + + partition@u-boot { + reg = <0x00000000 0x001f0000>; + label = "u-boot"; + }; + partition@u-boot-env { + reg = <0x001f0000 0x00010000>; + label = "u-boot-env"; + }; + partition@ubi1 { + reg = <0x00200000 0x03f00000>; + label = "ubi1"; + }; + partition@ubi2 { + reg = <0x04100000 0x03f00000>; + label = "ubi2"; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-xp-crs328-4c-20s-4s.dts b/arch/arm/boot/dts/armada-xp-crs328-4c-20s-4s.dts new file mode 100644 index 000000000000..665757f6e18e --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-crs328-4c-20s-4s.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree file for MikroTik CRS328-4C-20S-4S+ board + * + * Copyright (C) 2020 Sartura Ltd. + * Author: Luka Kovacic <luka.kovacic@sartura.hr> + */ + +#include "armada-xp-crs328-4c-20s-4s.dtsi" + +/ { + model = "MikroTik CRS328-4C-20S-4S+"; +}; + +&spi0 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/armada-xp-crs328-4c-20s-4s.dtsi b/arch/arm/boot/dts/armada-xp-crs328-4c-20s-4s.dtsi new file mode 100644 index 000000000000..c8b1355ce15e --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-crs328-4c-20s-4s.dtsi @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree file for CRS328-4C-20S-4S+ board + * + * Copyright (C) 2016 Allied Telesis Labs + * Copyright (C) 2020 Sartura Ltd. + * + * Based on armada-xp-db.dts + * + * Note: this Device Tree assumes that the bootloader has remapped the + * internal registers to 0xf1000000 (instead of the default + * 0xd0000000). The 0xf1000000 is the default used by the recent, + * DT-capable, U-Boot bootloaders provided by Marvell. Some earlier + * boards were delivered with an older version of the bootloader that + * left internal registers mapped at 0xd0000000. If you are in this + * situation, you should either update your bootloader (preferred + * solution) or the below Device Tree should be adjusted. + */ + +/dts-v1/; +#include "armada-xp-98dx3236.dtsi" + +/ { + model = "CRS328-4C-20S-4S+"; + compatible = "mikrotik,crs328-4c-20s-4s", "marvell,armadaxp-98dx3236", "marvell,armada-370-xp"; + + chosen { + bootargs = "console=ttyS0,115200 earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0 0x00000000 0 0x20000000>; /* 512 MB */ + }; +}; + +&L2 { + arm,parity-enable; + marvell,ecc-enable; +}; + +&devbus_bootcs { + status = "okay"; + + /* Device Bus parameters are required */ + + /* Read parameters */ + devbus,bus-width = <16>; + devbus,turn-off-ps = <60000>; + devbus,badr-skew-ps = <0>; + devbus,acc-first-ps = <124000>; + devbus,acc-next-ps = <248000>; + devbus,rd-setup-ps = <0>; + devbus,rd-hold-ps = <0>; + + /* Write parameters */ + devbus,sync-enable = <0>; + devbus,wr-high-ps = <60000>; + devbus,wr-low-ps = <60000>; + devbus,ale-wr-ps = <60000>; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&i2c0 { + clock-frequency = <100000>; + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <108000000>; + m25p,fast-read; + + partition@u-boot { + reg = <0x00000000 0x001f0000>; + label = "u-boot"; + }; + partition@u-boot-env { + reg = <0x001f0000 0x00010000>; + label = "u-boot-env"; + }; + partition@ubi1 { + reg = <0x00200000 0x00e00000>; + label = "ubi1"; + }; + }; +}; diff --git a/arch/arm/boot/dts/aspeed-ast2600-evb.dts b/arch/arm/boot/dts/aspeed-ast2600-evb.dts index 8d0f4656aa05..89be13197780 100644 --- a/arch/arm/boot/dts/aspeed-ast2600-evb.dts +++ b/arch/arm/boot/dts/aspeed-ast2600-evb.dts @@ -23,6 +23,15 @@ }; }; +&mdio0 { + status = "okay"; + + ethphy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; +}; + &mdio1 { status = "okay"; @@ -50,6 +59,17 @@ }; }; +&mac0 { + status = "okay"; + + phy-mode = "rgmii"; + phy-handle = <ðphy0>; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rgmii1_default>; +}; + + &mac1 { status = "okay"; diff --git a/arch/arm/boot/dts/aspeed-bmc-amd-ethanolx.dts b/arch/arm/boot/dts/aspeed-bmc-amd-ethanolx.dts index 60ba86f3e5bc..96ff0aea64e5 100644 --- a/arch/arm/boot/dts/aspeed-bmc-amd-ethanolx.dts +++ b/arch/arm/boot/dts/aspeed-bmc-amd-ethanolx.dts @@ -13,6 +13,21 @@ memory@80000000 { reg = <0x80000000 0x20000000>; }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + video_engine_memory: jpegbuffer { + size = <0x02000000>; /* 32M */ + alignment = <0x01000000>; + compatible = "shared-dma-pool"; + reusable; + }; + }; + + aliases { serial0 = &uart1; serial4 = &uart5; @@ -82,6 +97,50 @@ &pinctrl_adc4_default>; }; +&gpio { + status = "okay"; + gpio-line-names = + /*A0-A7*/ "","","FAULT_LED","CHASSIS_ID_LED","","","","", + /*B0-B7*/ "","","","","","","","", + /*C0-C7*/ "CHASSIS_ID_BTN","INTRUDER","AC_LOSS","","","","","", + /*D0-D7*/ "HDT_DBREQ","LOCAL_SPI_ROM_SEL","FPGA_SPI_ROM_SEL","JTAG_MUX_S", + "JTAG_MUX_OE","HDT_SEL","ASERT_WARM_RST_BTN","FPGA_RSVD", + /*E0-E7*/ "","","MON_P0_PWR_BTN","MON_P0_RST_BTN","MON_P0_NMI_BTN", + "MON_P0_PWR_GOOD","MON_PWROK","MON_RESET", + /*F0-F7*/ "MON_P0_PROCHOT","MON_P1_PROCHOT","MON_P0_THERMTRIP", + "MON_P1_THERMTRIP","P0_PRESENT","P1_PRESENT","MON_ATX_PWR_OK","", + /*G0-G7*/ "BRD_REV_ID_3","BRD_REV_ID_2","BRD_REV_ID_1","BRD_REV_ID_0", + "P0_APML_ALERT","P1_APML_ALERT","FPGA ALERT","", + /*H0-H7*/ "BRD_ID_0","BRD_ID_1","BRD_ID_2","BRD_ID_3", + "PCIE_DISCONNECTED","USB_DISCONNECTED","SPARE_0","SPARE_1", + /*I0-I7*/ "","","","","","","","", + /*J0-J7*/ "","","","","","","","", + /*K0-K7*/ "","","","","","","","", + /*L0-L7*/ "","","","","","","","", + /*M0-M7*/ "ASSERT_PWR_BTN","ASSERT_RST_BTN","ASSERT_NMI_BTN", + "ASSERT_LOCAL_LOCK","ASSERT_P0_PROCHOT","ASSERT_P1_PROCHOT", + "ASSERT_CLR_CMOS","ASSERT_BMC_READY", + /*N0-N7*/ "","","","","","","","", + /*O0-O7*/ "","","","","","","","", + /*P0-P7*/ "P0_VDD_CORE_RUN_VRHOT","P0_VDD_SOC_RUN_VRHOT", + "P0_VDD_MEM_ABCD_SUS_VRHOT","P0_VDD_MEM_EFGH_SUS_VRHOT", + "P1_VDD_CORE_RUN_VRHOT","P1_VDD_SOC_RUN_VRHOT", + "P1_VDD_MEM_ABCD_SUS_VRHOT","P1_VDD_MEM_EFGH_SUS_VRHOT", + /*Q0-Q7*/ "","","","","","","","", + /*R0-R7*/ "","","","","","","","", + /*S0-S7*/ "","","","","","","","", + /*T0-T7*/ "","","","","","","","", + /*U0-U7*/ "","","","","","","","", + /*V0-V7*/ "","","","","","","","", + /*W0-W7*/ "","","","","","","","", + /*X0-X7*/ "","","","","","","","", + /*Y0-Y7*/ "","","","","","","","", + /*Z0-Z7*/ "","","","","","","","", + /*AA0-AA7*/ "","SENSOR THERM","","","","","","", + /*AB0-AB7*/ "","","","","","","","", + /*AC0-AC7*/ "","","","","","","",""; +}; + //APML for P0 &i2c0 { status = "okay"; @@ -139,17 +198,22 @@ &kcs1 { status = "okay"; - kcs_addr = <0x60>; + aspeed,lpc-io-reg = <0x60>; }; &kcs2 { status = "okay"; - kcs_addr = <0x62>; + aspeed,lpc-io-reg = <0x62>; +}; + +&kcs3 { + status = "okay"; + aspeed,lpc-io-reg = <0xCA2>; }; &kcs4 { status = "okay"; - kcs_addr = <0x97DE>; + aspeed,lpc-io-reg = <0x97DE>; }; &lpc_snoop { @@ -215,5 +279,12 @@ }; }; +&video { + status = "okay"; + memory-region = <&video_engine_memory>; +}; +&vhub { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/aspeed-bmc-bytedance-g220a.dts b/arch/arm/boot/dts/aspeed-bmc-bytedance-g220a.dts new file mode 100644 index 000000000000..2feb25b0e43b --- /dev/null +++ b/arch/arm/boot/dts/aspeed-bmc-bytedance-g220a.dts @@ -0,0 +1,924 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (C) 2020 Bytedance. +/dts-v1/; + +#include "aspeed-g5.dtsi" +#include <dt-bindings/gpio/aspeed-gpio.h> +#include <dt-bindings/i2c/i2c.h> +#include <dt-bindings/leds/leds-pca955x.h> + +/ { + model = "Bytedance G220A BMC"; + compatible = "bytedance,g220a-bmc", "aspeed,ast2500"; + + aliases { + serial4 = &uart5; + i2c14 = &channel_3_0; + i2c15 = &channel_3_1; + i2c16 = &channel_3_2; + i2c17 = &channel_3_3; + i2c18 = &channel_6_0; + i2c19 = &channel_6_1; + i2c20 = &channel_6_2; + i2c21 = &channel_6_3; + i2c22 = &channel_6_4; + i2c23 = &channel_6_5; + i2c24 = &channel_6_6; + i2c25 = &channel_6_7; + i2c26 = &channel_6_8; + i2c27 = &channel_6_9; + i2c28 = &channel_6_10; + i2c29 = &channel_6_11; + i2c30 = &channel_6_12; + i2c31 = &channel_6_13; + i2c32 = &channel_6_14; + i2c33 = &channel_6_15; + i2c34 = &channel_6_16; + i2c35 = &channel_6_17; + i2c36 = &channel_6_18; + i2c37 = &channel_6_19; + i2c38 = &channel_6_20; + i2c39 = &channel_6_21; + i2c40 = &channel_6_22; + i2c41 = &channel_6_23; + i2c42 = &channel_6_24; + i2c43 = &channel_6_25; + i2c44 = &channel_10_0; + i2c45 = &channel_10_1; + i2c46 = &channel_10_2; + i2c47 = &channel_10_3; + i2c48 = &channel_10_4; + i2c49 = &channel_10_5; + i2c50 = &channel_10_6; + i2c51 = &channel_10_7; + }; + + chosen { + stdout-path = &uart5; + bootargs = "console=ttyS4,115200 earlyprintk"; + }; + + memory@80000000 { + reg = <0x80000000 0x40000000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + vga_memory: framebuffer@bc000000 { + no-map; + reg = <0xbc000000 0x04000000>; /* 64M */ + }; + + video_engine_memory: jpegbuffer { + size = <0x02000000>; /* 32M */ + alignment = <0x01000000>; + compatible = "shared-dma-pool"; + reusable; + }; + }; + + iio-hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>, + <&adc 4>, <&adc 5>, <&adc 6>, <&adc 7>, + <&adc 8>, <&adc 9>, <&adc 10>, <&adc 11>, + <&adc 12>, <&adc 13>, <&adc 14>, <&adc 15>; + }; + + leds { + compatible = "gpio-leds"; + bmc_alive { + label = "bmc_alive"; + gpios = <&gpio ASPEED_GPIO(B, 0) GPIO_ACTIVE_LOW>; + linux,default-trigger = "timer"; + led-pattern = <1000 1000>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + burn-in-signal { + label = "burn-in"; + gpios = <&gpio ASPEED_GPIO(R, 5) GPIO_ACTIVE_LOW>; + linux,code = <ASPEED_GPIO(R, 5)>; + }; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + poll-interval = <1000>; + + rear-riser1-presence { + label = "rear-riser1-presence"; + gpios = <&pca0 1 GPIO_ACTIVE_LOW>; + linux,code = <1>; + }; + + alrt-pvddq-cpu0 { + label = "alrt-pvddq-cpu0"; + gpios = <&pca0 8 GPIO_ACTIVE_LOW>; + linux,code = <2>; + }; + + rear-riser0-presence { + label = "rear-riser0-presence"; + gpios = <&pca0 9 GPIO_ACTIVE_LOW>; + linux,code = <3>; + }; + + fault-pvddq-cpu0 { + label = "fault-pvddq-cpu0"; + gpios = <&pca0 10 GPIO_ACTIVE_LOW>; + linux,code = <4>; + }; + + alrt-pvddq-cpu1 { + label = "alrt-pvddq-cpu1"; + gpios = <&pca0 11 GPIO_ACTIVE_LOW>; + linux,code = <5>; + }; + + fault-pvddq-cpu1 { + label = "alrt-pvddq-cpu1"; + gpios = <&pca0 12 GPIO_ACTIVE_LOW>; + linux,code = <6>; + }; + + fault-pvccin-cpu1 { + label = "fault-pvccin-cpuq"; + gpios = <&pca0 13 GPIO_ACTIVE_LOW>; + linux,code = <7>; + }; + + bmc-rom0-wp { + label = "bmc-rom0-wp"; + gpios = <&pca1 0 GPIO_ACTIVE_LOW>; + linux,code = <8>; + }; + + bmc-rom1-wp { + label = "bmc-rom1-wp"; + gpios = <&pca1 1 GPIO_ACTIVE_LOW>; + linux,code = <9>; + }; + + fan0-presence { + label = "fan0-presence"; + gpios = <&pca1 2 GPIO_ACTIVE_LOW>; + linux,code = <10>; + }; + + fan1-presence { + label = "fan1-presence"; + gpios = <&pca1 3 GPIO_ACTIVE_LOW>; + linux,code = <11>; + }; + + fan2-presence { + label = "fan2-presence"; + gpios = <&pca1 4 GPIO_ACTIVE_LOW>; + linux,code = <12>; + }; + + fan3-presence { + label = "fan3-presence"; + gpios = <&pca1 5 GPIO_ACTIVE_LOW>; + linux,code = <13>; + }; + + fan4-presence { + label = "fan4-presence"; + gpios = <&pca1 6 GPIO_ACTIVE_LOW>; + linux,code = <14>; + }; + + fan5-presence { + label = "fan5-presence"; + gpios = <&pca1 7 GPIO_ACTIVE_LOW>; + linux,code = <15>; + }; + + front-bp1-presence { + label = "front-bp1-presence"; + gpios = <&pca1 8 GPIO_ACTIVE_LOW>; + linux,code = <16>; + }; + + rear-bp-presence { + label = "rear-bp-presence"; + gpios = <&pca1 9 GPIO_ACTIVE_LOW>; + linux,code = <17>; + }; + + fault-pvccin-cpu0 { + label = "fault-pvccin-cpu0"; + gpios = <&pca1 10 GPIO_ACTIVE_LOW>; + linux,code = <18>; + }; + + alrt-p1v05-pvcc { + label = "alrt-p1v05-pvcc1"; + gpios = <&pca1 11 GPIO_ACTIVE_LOW>; + linux,code = <19>; + }; + + fault-p1v05-pvccio { + label = "alrt-p1v05-pvcc1"; + gpios = <&pca1 12 GPIO_ACTIVE_LOW>; + linux,code = <20>; + }; + + alrt-p1v8-pvccio { + label = "alrt-p1v8-pvccio"; + gpios = <&pca1 13 GPIO_ACTIVE_LOW>; + linux,code = <21>; + }; + + fault-p1v8-pvccio { + label = "fault-p1v8-pvccio"; + gpios = <&pca1 14 GPIO_ACTIVE_LOW>; + linux,code = <22>; + }; + + front-bp0-presence { + label = "front-bp0-presence"; + gpios = <&pca1 15 GPIO_ACTIVE_LOW>; + linux,code = <23>; + }; + }; +}; + +&fmc { + status = "okay"; + flash@0 { + status = "okay"; + label = "bmc"; + m25p,fast-read; + spi-max-frequency = <50000000>; +#include "openbmc-flash-layout-64.dtsi" + }; +}; + +&spi1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1_default>; + flash@0 { + status = "okay"; + m25p,fast-read; + label = "bios"; + spi-max-frequency = <100000000>; + }; +}; + +&adc { + status = "okay"; +}; + +&gpio { + status = "okay"; + gpio-line-names = + /*A0-A7*/ "SMRST_OCP_N","MAC2_LINK","BMC_CPLD_SMB_RST_R_N","BMC_CPLD_GPIO0", + "","","","", + /*B0-B7*/ "BMC_INIT_R_OK","FM_BOARD_REV_ID2","FM_PROJECT_ID7","FAULT_P12V_STBY_N", + "","CPU0_PROCHOT_LVT3_N","","BIOS_LOAD_DEFAULT_R_N", + /*C0-C7*/ "","","","","","","","", + /*D0-D7*/ "","","","","","","","", + /*E0-E7*/ "FM_PROJECT_ID0","FM_PROJECT_ID1","FM_PROJECT_ID2","FM_PROJECT_ID3", + "FM_PROJECT_ID4","FM_PROJECT_ID5","","", + /*F0-F7*/ "PSU0_PRSNT_N","PSU1_PRSNT_N","","FAULT_P12V_NVME_N", + "BIOS_DEBUG_MODE_R_N","DISABLE_CPU_DDR_R_SPD","COOLING_STRATEGY", + "PCH_GLB_RST_N", + /*G0-G7*/ "P12V_PMBUS_ALERT_N","CPLD_ALERT_N","BMC_RELOAD_N", + "P12V_PVDDQ_PMBUS_ALERT_N","BMC_JTAG_TCK_MUX_R_SEL","","NMI_OUT", + "NMI_BUTTON", + /*H0-H7*/ "BMC_CPLD_JTAG_TDI","BMC_CPLD_JTAG_TDO","BMC_CPLD_JTAG_TCK", + "BMC_CPLD_JTAG_TMS","FM_PROJECT_ID6","FM_BOARD_REV_ID0", + "PCA9546_U70_RST_N","IRQ_SML0_ALERT_N", + /*I0-I7*/ "FAULT_FRONT_RISER_P12V_N","FAULT_OCP_P12V_N","FM_BMC_PCH_SCI_R_N", + "","","","","", + /*J0-J7*/ "FM_CPU0_SKTOCC_N","FM_CPU1_SKTOCC_N","FM_CPU1_DISABLE_COD_N", + "","","","","", + /*K0-K7*/ "","","","","","","","", + /*L0-L7*/ "P12V_FAULT_N","PWRGD_P12V_PCIE_RISER","","LEAKAGE_DETECT_INPUT_N", + "","IRQ_SML1_PMBUS_ALERT_N","","", + /*M0-M7*/ "","","","","","","","", + /*N0-N7*/ "","","","","","","","", + /*O0-O7*/ "","","","","","","","", + /*P0-P7*/ "","","","","","","","", + /*Q0-Q7*/ "","","","","","","FM_PCH_THERMTRIP_N","CHASSIS_INTRUSION", + /*R0-R7*/ "","PVCCIN_CPU1_SMBALERT_N","BMC_PREQ_R_N","FAULT_P12V_PCIE_RISER_N", + "ALT_P12V_PCIE_RISER_N","BURN_BOARD_N","PVCCIN_CPU0_SMBALERT_N","", + /*S0-S7*/ "BMC_PRDY_N","SIO_POWER_GOOD","FM_BMC_PWR_DEBUG_R_N", + "FM_BMC_XDP_DEBUG_EN","","STRAP_BMC_BATTERY_GPIOS5","","", + /*T0-T7*/ "","","","","","","","", + /*U0-U7*/ "","","","","","","","", + /*V0-V7*/ "","","","","","","","", + /*W0-W7*/ "","","","","","","","", + /*X0-X7*/ "","","","","","","","", + /*Y0-Y7*/ "","PWRGD_PSU0_PWROK","CPU1_PROCHOT_LVT3_N","IRQ_BMC_PCH_SMI_LPC_N", + "","","","", + /*Z0-Z7*/ "XDP_PRSNT_N","BMC_XDP_SYS_PWROK","BMC_XDP_JTAG_SEL", + "PCH_BMC_SMI_ACTIVE_R_N","","","","", + /*AA0-AA7*/ "PWRGD_P12V_STBY_OCP","PS_PWROK","RST_PLTRST_BMC_R_N","HDA_SDO_R", + "FM_SLPS4_R_N","PWRGD_PSU1_PWROK","POWER_BUTTON","POWER_OUT", + /*AB0-AB7*/ "","RESET_OUT","SPI_BIOS_MODE_SELECT","POST_COMPLETE","","","","", + /*AC0-AC7*/ "","","","","","","","CPLD_PLTRST_B_N"; +}; + +&kcs3 { + aspeed,lpc-io-reg = <0xCA2>; + status = "okay"; +}; + +&kcs4 { + aspeed,lpc-io-reg = <0xCA4>; + status = "okay"; +}; + +&lpc_snoop { + snoop-ports = <0x80>; + status = "okay"; +}; + +&uart1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_txd1_default + &pinctrl_rxd1_default + &pinctrl_nrts1_default + &pinctrl_ndtr1_default + &pinctrl_ndsr1_default + &pinctrl_ncts1_default + &pinctrl_ndcd1_default + &pinctrl_nri1_default>; +}; + +&uart2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_txd2_default + &pinctrl_rxd2_default + &pinctrl_nrts2_default + &pinctrl_ndtr2_default + &pinctrl_ndsr2_default + &pinctrl_ncts2_default + &pinctrl_ndcd2_default + &pinctrl_nri2_default>; +}; + +&uart3 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&uart5 { + status = "okay"; +}; + +&mac0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rmii1_default>; + clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>, + <&syscon ASPEED_CLK_MAC1RCLK>; + clock-names = "MACCLK", "RCLK"; + use-ncsi; +}; + +&mac1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; + i2c-switch@70 { + compatible = "nxp,pca9546"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + channel_3_0: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + channel_3_1: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + channel_3_2: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + channel_3_3: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + }; +}; + +&i2c4 { + status = "okay"; + +}; + +&i2c5 { + status = "okay"; +}; + +&i2c6 { + status = "okay"; + i2c-switch@72 { + compatible = "nxp,pca9548"; + reg = <0x72>; + #address-cells = <1>; + #size-cells = <0>; + channel_6_0: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + channel_6_1: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + channel_6_2: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + channel_6_3: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + channel_6_4: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + channel_6_5: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + channel_6_6: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + channel_6_7: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; + + i2c-switch@70 { + compatible = "nxp,pca9546"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + channel_6_8: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + i2c-switch@71 { + compatible = "nxp,pca9546"; + reg = <0x71>; + #address-cells = <1>; + #size-cells = <0>; + channel_6_12: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + }; + + channel_6_13: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + channel_6_14: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + channel_6_15: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + }; + }; + + channel_6_9: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + i2c-switch@71 { + compatible = "nxp,pca9546"; + reg = <0x71>; + #address-cells = <1>; + #size-cells = <0>; + channel_6_16: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + }; + + channel_6_17: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + channel_6_18: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + channel_6_19: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + }; + }; + + channel_6_10: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + i2c-switch@71 { + compatible = "nxp,pca9546"; + reg = <0x71>; + #address-cells = <1>; + #size-cells = <0>; + channel_6_20: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + channel_6_21: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + channel_6_22: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + channel_6_23: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + }; + }; + + channel_6_11: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + i2c-switch@71 { + compatible = "nxp,pca9546"; + reg = <0x71>; + #address-cells = <1>; + #size-cells = <0>; + channel_6_24: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + channel_6_25: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + }; + }; + }; +}; + +&i2c7 { + status = "okay"; +}; + +&i2c8 { + status = "okay"; + pca0:pca9555@24 { + compatible = "nxp,pca9555"; + reg = <0x24>; + #address-cells = <1>; + #size-cells = <0>; + + gpio-controller; + #gpio-cells = <2>; + gpio@1 { + reg = <1>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@8 { + reg = <8>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@9 { + reg = <9>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@10 { + reg = <10>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@11 { + reg = <11>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@12 { + reg = <12>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@13 { + reg = <13>; + type = <PCA955X_TYPE_GPIO>; + }; + }; + + pca1:pca9555@25 { + compatible = "nxp,pca9555"; + reg = <0x25>; + + #address-cells = <1>; + #size-cells = <0>; + + gpio-controller; + #gpio-cells = <2>; + + gpio@0 { + reg = <0>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@1 { + reg = <1>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@2 { + reg = <2>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@3 { + reg = <3>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@4 { + reg = <4>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@5 { + reg = <5>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@6 { + reg = <6>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@7 { + reg = <7>; + type = <PCA955X_TYPE_GPIO>; + }; + gpio@8 { + reg = <8>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@9 { + reg = <9>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@10 { + reg = <10>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@11 { + reg = <11>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@12 { + reg = <12>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@13 { + reg = <13>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@14 { + reg = <14>; + type = <PCA955X_TYPE_GPIO>; + }; + + gpio@15 { + reg = <15>; + type = <PCA955X_TYPE_GPIO>; + }; + }; +}; + +&i2c9 { + status = "okay"; +}; + +&i2c10 { + status = "okay"; + i2c-switch@70 { + compatible = "nxp,pca9546"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + channel_10_0: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + channel_10_1: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + channel_10_2: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + channel_10_3: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + }; + + i2c-switch@71 { + compatible = "nxp,pca9546"; + reg = <0x71>; + #address-cells = <1>; + #size-cells = <0>; + channel_10_4: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + channel_10_5: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + channel_10_6: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + channel_10_7: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + }; +}; + +&i2c11 { + status = "okay"; +}; + +&i2c12 { + status = "okay"; +}; + +&i2c13 { + status = "okay"; +}; + +&pwm_tacho { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default + &pinctrl_pwm2_default &pinctrl_pwm3_default + &pinctrl_pwm4_default &pinctrl_pwm5_default>; + + fan@0 { + reg = <0x00>; + aspeed,fan-tach-ch = /bits/ 8 <0x00 0x01>; + }; + fan@1 { + reg = <0x01>; + aspeed,fan-tach-ch = /bits/ 8 <0x02 0x03>; + }; + fan@2 { + reg = <0x02>; + aspeed,fan-tach-ch = /bits/ 8 <0x04 0x05>; + }; + fan@3 { + reg = <0x03>; + aspeed,fan-tach-ch = /bits/ 8 <0x06 0x07>; + }; + fan@4 { + reg = <0x04>; + aspeed,fan-tach-ch = /bits/ 8 <0x08 0x09>; + }; + fan@5 { + reg = <0x05>; + aspeed,fan-tach-ch = /bits/ 8 <0x0a 0x0b>; + }; +}; + +&gpio { + pin_gpio_i3 { + gpio-hog; + gpios = <ASPEED_GPIO(I, 3) GPIO_ACTIVE_LOW>; + output-low; + line-name = "NCSI_BMC_R_SEL"; + }; + + pin_gpio_b6 { + gpio-hog; + gpios = <ASPEED_GPIO(B, 6) GPIO_ACTIVE_LOW>; + output-low; + line-name = "EN_NCSI_SWITCH_N"; + }; +}; + +&video { + status = "okay"; + memory-region = <&video_engine_memory>; +}; + +&vhub { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-galaxy100.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-galaxy100.dts new file mode 100644 index 000000000000..dcf213472749 --- /dev/null +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-galaxy100.dts @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2020 Facebook Inc. +/dts-v1/; + +#include "ast2400-facebook-netbmc-common.dtsi" + +/ { + model = "Facebook Galaxy 100 BMC"; + compatible = "facebook,galaxy100-bmc", "aspeed,ast2400"; + + chosen { + stdout-path = &uart5; + bootargs = "console=ttyS0,9600n8 root=/dev/ram rw"; + }; + + ast-adc-hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc 3>, <&adc 4>, <&adc 8>, <&adc 9>; + }; +}; + +&wdt2 { + status = "okay"; + aspeed,reset-type = "system"; +}; + +&fmc { + flash@1 { + status = "okay"; + m25p,fast-read; + label = "spi0.1"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + flash1@0 { + reg = <0x0 0x2000000>; + label = "flash1"; + }; + }; + }; +}; + + +&i2c9 { + status = "okay"; +}; + +&vhub { + status = "okay"; +}; + +&adc { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts index c34741dbd268..9eb23e874f19 100644 --- a/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts @@ -70,6 +70,162 @@ i2c45 = &imux45; i2c46 = &imux46; i2c47 = &imux47; + + /* + * I2C Switch 24-0071 (channel #0 of 8-0070): 8 channels for + * connecting to left PDB (Power Distribution Board). + */ + i2c48 = &imux48; + i2c49 = &imux49; + i2c50 = &imux50; + i2c51 = &imux51; + i2c52 = &imux52; + i2c53 = &imux53; + i2c54 = &imux54; + i2c55 = &imux55; + + /* + * I2C Switch 25-0072 (channel #1 of 8-0070): 8 channels for + * connecting to right PDB (Power Distribution Board). + */ + i2c56 = &imux56; + i2c57 = &imux57; + i2c58 = &imux58; + i2c59 = &imux59; + i2c60 = &imux60; + i2c61 = &imux61; + i2c62 = &imux62; + i2c63 = &imux63; + + /* + * I2C Switch 26-0076 (channel #2 of 8-0070): 8 channels for + * connecting to top FCM (Fan Control Module). + */ + i2c64 = &imux64; + i2c65 = &imux65; + i2c66 = &imux66; + i2c67 = &imux67; + i2c68 = &imux68; + i2c69 = &imux69; + i2c70 = &imux70; + i2c71 = &imux71; + + /* + * I2C Switch 27-0076 (channel #3 of 8-0070): 8 channels for + * connecting to bottom FCM (Fan Control Module). + */ + i2c72 = &imux72; + i2c73 = &imux73; + i2c74 = &imux74; + i2c75 = &imux75; + i2c76 = &imux76; + i2c77 = &imux77; + i2c78 = &imux78; + i2c79 = &imux79; + + /* + * I2C Switch 40-0073 (channel #0 of 11-0070): connecting + * to PIM (Port Interface Module) #1 (1-based). + */ + i2c80 = &imux80; + i2c81 = &imux81; + i2c82 = &imux82; + i2c83 = &imux83; + i2c84 = &imux84; + i2c85 = &imux85; + i2c86 = &imux86; + i2c87 = &imux87; + + /* + * I2C Switch 41-0073 (channel #1 of 11-0070): connecting + * to PIM (Port Interface Module) #2 (1-based). + */ + i2c88 = &imux88; + i2c89 = &imux89; + i2c90 = &imux90; + i2c91 = &imux91; + i2c92 = &imux92; + i2c93 = &imux93; + i2c94 = &imux94; + i2c95 = &imux95; + + /* + * I2C Switch 42-0073 (channel #2 of 11-0070): connecting + * to PIM (Port Interface Module) #3 (1-based). + */ + i2c96 = &imux96; + i2c97 = &imux97; + i2c98 = &imux98; + i2c99 = &imux99; + i2c100 = &imux100; + i2c101 = &imux101; + i2c102 = &imux102; + i2c103 = &imux103; + + /* + * I2C Switch 43-0073 (channel #3 of 11-0070): connecting + * to PIM (Port Interface Module) #4 (1-based). + */ + i2c104 = &imux104; + i2c105 = &imux105; + i2c106 = &imux106; + i2c107 = &imux107; + i2c108 = &imux108; + i2c109 = &imux109; + i2c110 = &imux110; + i2c111 = &imux111; + + /* + * I2C Switch 44-0073 (channel #4 of 11-0070): connecting + * to PIM (Port Interface Module) #5 (1-based). + */ + i2c112 = &imux112; + i2c113 = &imux113; + i2c114 = &imux114; + i2c115 = &imux115; + i2c116 = &imux116; + i2c117 = &imux117; + i2c118 = &imux118; + i2c119 = &imux119; + + /* + * I2C Switch 45-0073 (channel #5 of 11-0070): connecting + * to PIM (Port Interface Module) #6 (1-based). + */ + i2c120 = &imux120; + i2c121 = &imux121; + i2c122 = &imux122; + i2c123 = &imux123; + i2c124 = &imux124; + i2c125 = &imux125; + i2c126 = &imux126; + i2c127 = &imux127; + + /* + * I2C Switch 46-0073 (channel #6 of 11-0070): connecting + * to PIM (Port Interface Module) #7 (1-based). + */ + i2c128 = &imux128; + i2c129 = &imux129; + i2c130 = &imux130; + i2c131 = &imux131; + i2c132 = &imux132; + i2c133 = &imux133; + i2c134 = &imux134; + i2c135 = &imux135; + + /* + * I2C Switch 47-0073 (channel #7 of 11-0070): connecting + * to PIM (Port Interface Module) #8 (1-based). + */ + i2c136 = &imux136; + i2c137 = &imux137; + i2c138 = &imux138; + i2c139 = &imux139; + i2c140 = &imux140; + i2c141 = &imux141; + i2c142 = &imux142; + i2c143 = &imux143; }; chosen { @@ -184,11 +340,16 @@ &i2c2 { status = "okay"; + /* + * I2C Switch 2-0070 is connecting to SCM (System Controller + * Module). + */ i2c-switch@70 { compatible = "nxp,pca9548"; #address-cells = <1>; #size-cells = <0>; reg = <0x70>; + i2c-mux-idle-disconnect; imux16: i2c@0 { #address-cells = <1>; @@ -269,29 +430,270 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x70>; + i2c-mux-idle-disconnect; + /* + * I2C Switch 8-0070 channel #0: connecting to left PDB + * (Power Distribution Board). + */ imux24: i2c@0 { #address-cells = <1>; #size-cells = <0>; reg = <0>; + + i2c-switch@71 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x71>; + i2c-mux-idle-disconnect; + + imux48: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux49: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux50: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux51: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux52: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux53: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux54: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux55: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; }; + /* + * I2C Switch 8-0070 channel #1: connecting to right PDB + * (Power Distribution Board). + */ imux25: i2c@1 { #address-cells = <1>; #size-cells = <0>; reg = <1>; + + i2c-switch@72 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x72>; + i2c-mux-idle-disconnect; + + imux56: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux57: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux58: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux59: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux60: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux61: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux62: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux63: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; }; + /* + * I2C Switch 8-0070 channel #2: connecting to top FCM + * (Fan Control Module). + */ imux26: i2c@2 { #address-cells = <1>; #size-cells = <0>; reg = <2>; + + i2c-switch@76 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x76>; + i2c-mux-idle-disconnect; + + imux64: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux65: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux66: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux67: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux68: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux69: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux70: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux71: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; }; + /* + * I2C Switch 8-0070 channel #3: connecting to bottom + * FCM (Fan Control Module). + */ imux27: i2c@3 { #address-cells = <1>; #size-cells = <0>; reg = <3>; + + i2c-switch@76 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x76>; + i2c-mux-idle-disconnect; + + imux72: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux73: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux74: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux75: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux76: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux77: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux78: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux79: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; }; imux28: i2c@4 { @@ -323,11 +725,16 @@ &i2c9 { status = "okay"; + /* + * I2C Switch 9-0070 is connecting to MAC/PHY EEPROMs on SMB + * (Switch Main Board). + */ i2c-switch@70 { compatible = "nxp,pca9548"; #address-cells = <1>; #size-cells = <0>; reg = <0x70>; + i2c-mux-idle-disconnect; imux32: i2c@0 { #address-cells = <1>; @@ -391,53 +798,534 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x70>; + i2c-mux-idle-disconnect; + /* + * I2C Switch 11-0070 channel #0: connecting to PIM + * (Port Interface Module) #1 (1-based). + */ imux40: i2c@0 { #address-cells = <1>; #size-cells = <0>; reg = <0>; + + i2c-switch@73 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x73>; + i2c-mux-idle-disconnect; + + imux80: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux81: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux82: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux83: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux84: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux85: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux86: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux87: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; }; + /* + * I2C Switch 11-0070 channel #1: connecting to PIM + * (Port Interface Module) #2 (1-based). + */ imux41: i2c@1 { #address-cells = <1>; #size-cells = <0>; reg = <1>; + + i2c-switch@73 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x73>; + i2c-mux-idle-disconnect; + + imux88: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux89: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux90: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux91: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux92: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux93: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux94: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux95: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; }; + /* + * I2C Switch 11-0070 channel #2: connecting to PIM + * (Port Interface Module) #3 (1-based). + */ imux42: i2c@2 { #address-cells = <1>; #size-cells = <0>; reg = <2>; + + i2c-switch@73 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x73>; + i2c-mux-idle-disconnect; + + imux96: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux97: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux98: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux99: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux100: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux101: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux102: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux103: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; }; + /* + * I2C Switch 11-0070 channel #3: connecting to PIM + * (Port Interface Module) #4 (1-based). + */ imux43: i2c@3 { #address-cells = <1>; #size-cells = <0>; reg = <3>; + + i2c-switch@73 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x73>; + i2c-mux-idle-disconnect; + + imux104: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux105: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux106: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux107: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux108: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux109: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux110: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux111: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; }; + /* + * I2C Switch 11-0070 channel #4: connecting to PIM + * (Port Interface Module) #5 (1-based). + */ imux44: i2c@4 { #address-cells = <1>; #size-cells = <0>; reg = <4>; + + i2c-switch@73 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x73>; + i2c-mux-idle-disconnect; + + imux112: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux113: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux114: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux115: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux116: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux117: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux118: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux119: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; }; + /* + * I2C Switch 11-0070 channel #5: connecting to PIM + * (Port Interface Module) #6 (1-based). + */ imux45: i2c@5 { #address-cells = <1>; #size-cells = <0>; reg = <5>; + + i2c-switch@73 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x73>; + i2c-mux-idle-disconnect; + + imux120: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux121: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux122: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux123: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux124: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux125: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux126: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux127: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; }; + /* + * I2C Switch 11-0070 channel #6: connecting to PIM + * (Port Interface Module) #7 (1-based). + */ imux46: i2c@6 { #address-cells = <1>; #size-cells = <0>; reg = <6>; + + i2c-switch@73 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x73>; + i2c-mux-idle-disconnect; + + imux128: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux129: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux130: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux131: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux132: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux133: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux134: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux135: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; }; + /* + * I2C Switch 11-0070 channel #7: connecting to PIM + * (Port Interface Module) #8 (1-based). + */ imux47: i2c@7 { #address-cells = <1>; #size-cells = <0>; reg = <7>; + + i2c-switch@73 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x73>; + i2c-mux-idle-disconnect; + + imux136: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux137: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux138: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux139: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux140: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux141: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux142: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux143: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; }; }; }; diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts index 2d44d9ad4e40..cd18641d5c23 100644 --- a/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts @@ -82,11 +82,6 @@ status = "okay"; }; -&vuart { - // VUART Host Console - status = "okay"; -}; - &uart1 { // Host Console status = "okay"; @@ -196,6 +191,14 @@ use-ncsi; }; +&mac1 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rmii2_default>; + use-ncsi; +}; + &adc { status = "okay"; }; diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-wedge100.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge100.dts index 322587b7b67d..39c6be91d53f 100644 --- a/arch/arm/boot/dts/aspeed-bmc-facebook-wedge100.dts +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge100.dts @@ -2,36 +2,16 @@ // Copyright (c) 2018 Facebook Inc. /dts-v1/; -#include "aspeed-g4.dtsi" +#include "ast2400-facebook-netbmc-common.dtsi" / { model = "Facebook Wedge 100 BMC"; compatible = "facebook,wedge100-bmc", "aspeed,ast2400"; - aliases { - /* - * Override the default uart aliases to avoid breaking - * the legacy applications. - */ - serial0 = &uart5; - serial1 = &uart1; - serial2 = &uart3; - serial3 = &uart4; - }; - chosen { stdout-path = &uart3; bootargs = "console=ttyS2,9600n8 root=/dev/ram rw"; }; - - memory@40000000 { - reg = <0x40000000 0x20000000>; - }; -}; - -&wdt1 { - status = "okay"; - aspeed,reset-type = "system"; }; &wdt2 { @@ -40,108 +20,38 @@ }; &fmc { - status = "okay"; - flash@0 { + flash@1 { status = "okay"; m25p,fast-read; - label = "fmc0"; -#include "facebook-bmc-flash-layout.dtsi" + label = "spi0.1"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + flash1@0 { + reg = <0x0 0x2000000>; + label = "flash1"; + }; + }; }; }; -&uart1 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_txd1_default - &pinctrl_rxd1_default>; -}; - -&uart3 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_txd3_default - &pinctrl_rxd3_default>; -}; - -&uart4 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_txd4_default - &pinctrl_rxd4_default>; -}; - -&uart5 { - status = "okay"; -}; - -&mac1 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>; -}; - -&i2c0 { - status = "okay"; -}; - -&i2c1 { - status = "okay"; -}; - -&i2c2 { - status = "okay"; -}; - -&i2c3 { - status = "okay"; -}; - -&i2c4 { - status = "okay"; -}; - -&i2c5 { - status = "okay"; -}; - -&i2c6 { - status = "okay"; -}; - &i2c7 { - status = "okay"; - i2c-switch@70 { compatible = "nxp,pca9548"; #address-cells = <1>; #size-cells = <0>; reg = <0x70>; + i2c-mux-idle-disconnect; }; }; -&i2c8 { - status = "okay"; -}; - &i2c9 { status = "okay"; }; -&i2c10 { - status = "okay"; -}; - -&i2c11 { - status = "okay"; -}; - -&i2c12 { - status = "okay"; -}; - -&i2c13 { - status = "okay"; -}; &vhub { status = "okay"; diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-wedge40.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge40.dts index 8c426ba2f8ab..2dcfeae3c92a 100644 --- a/arch/arm/boot/dts/aspeed-bmc-facebook-wedge40.dts +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge40.dts @@ -2,137 +2,27 @@ // Copyright (c) 2018 Facebook Inc. /dts-v1/; -#include "aspeed-g4.dtsi" +#include "ast2400-facebook-netbmc-common.dtsi" / { model = "Facebook Wedge 40 BMC"; compatible = "facebook,wedge40-bmc", "aspeed,ast2400"; - aliases { - /* - * Override the default uart aliases to avoid breaking - * the legacy applications. - */ - serial0 = &uart5; - serial1 = &uart1; - serial2 = &uart3; - serial3 = &uart4; - }; - chosen { stdout-path = &uart3; bootargs = "console=ttyS2,9600n8 root=/dev/ram rw"; }; - memory@40000000 { - reg = <0x40000000 0x20000000>; - }; - ast-adc-hwmon { compatible = "iio-hwmon"; io-channels = <&adc 5>, <&adc 6>, <&adc 7>, <&adc 8>, <&adc 9>; }; }; -&wdt1 { - status = "okay"; - aspeed,reset-type = "system"; -}; - &wdt2 { status = "disabled"; }; -&fmc { - status = "okay"; - flash@0 { - status = "okay"; - m25p,fast-read; - label = "spi0.0"; -#include "facebook-bmc-flash-layout.dtsi" - }; -}; - -&uart1 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_txd1_default - &pinctrl_rxd1_default>; -}; - -&uart3 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_txd3_default - &pinctrl_rxd3_default>; -}; - -&uart4 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_txd4_default - &pinctrl_rxd4_default - &pinctrl_ndts4_default>; -}; - -&uart5 { - status = "okay"; -}; - -&mac1 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>; -}; - -&i2c0 { - status = "okay"; -}; - -&i2c1 { - status = "okay"; -}; - -&i2c2 { - status = "okay"; -}; - -&i2c3 { - status = "okay"; -}; - -&i2c4 { - status = "okay"; -}; - -&i2c5 { - status = "okay"; -}; - -&i2c6 { - status = "okay"; -}; - -&i2c7 { - status = "okay"; -}; - -&i2c8 { - status = "okay"; -}; - -&i2c11 { - status = "okay"; -}; - -&i2c12 { - status = "okay"; -}; - -&vhub { - status = "okay"; -}; - &adc { status = "okay"; }; diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts index ad1fcad3676c..63a3dd548f30 100644 --- a/arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts @@ -124,8 +124,8 @@ * "data0" partition (4MB) is reserved for persistent * data store. */ - data0@3800000 { - reg = <0x7c00000 0x800000>; + data0@7c00000 { + reg = <0x7c00000 0x400000>; label = "data0"; }; diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier-4u.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier-4u.dts new file mode 100644 index 000000000000..291f7d6c9979 --- /dev/null +++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier-4u.dts @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright 2020 IBM Corp. +/dts-v1/; + +#include "aspeed-bmc-ibm-rainier.dts" + +/ { + model = "Rainier 4U"; +}; + +&i2c3 { + power-supply@6a { + compatible = "ibm,cffps"; + reg = <0x6a>; + }; + + power-supply@6b { + compatible = "ibm,cffps"; + reg = <0x6b>; + }; +}; + +&fan0 { + tach-pulses = <4>; +}; + +&fan1 { + tach-pulses = <4>; +}; + +&fan2 { + tach-pulses = <4>; +}; + +&fan3 { + tach-pulses = <4>; +}; diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts index 21ae880c7530..a4b77aec5424 100644 --- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts +++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts @@ -8,7 +8,7 @@ #include <dt-bindings/leds/leds-pca955x.h> / { - model = "Rainier"; + model = "Rainier 2U"; compatible = "ibm,rainier-bmc", "aspeed,ast2600"; aliases { @@ -47,9 +47,18 @@ #size-cells = <1>; ranges; - flash_memory: region@B8000000 { + flash_memory: region@b8000000 { no-map; - reg = <0xB8000000 0x04000000>; /* 64M */ + reg = <0xb8000000 0x04000000>; /* 64M */ + }; + + ramoops@bc000000 { + compatible = "ramoops"; + reg = <0xbc000000 0x180000>; /* 16 * (3 * 0x8000) */ + record-size = <0x8000>; + console-size = <0x8000>; + pmsg-size = <0x8000>; + max-reason = <3>; /* KMSG_DUMP_EMERG */ }; vga_memory: region@bf000000 { @@ -258,6 +267,7 @@ cfam0_spi2: spi@40 { reg = <0x40>; + compatible = "ibm,fsi2spi-restricted"; #address-cells = <1>; #size-cells = <0>; @@ -274,6 +284,7 @@ cfam0_spi3: spi@60 { reg = <0x60>; + compatible = "ibm,fsi2spi-restricted"; #address-cells = <1>; #size-cells = <0>; @@ -370,6 +381,7 @@ cfam1_spi2: spi@40 { reg = <0x40>; + compatible = "ibm,fsi2spi-restricted"; #address-cells = <1>; #size-cells = <0>; @@ -386,6 +398,7 @@ cfam1_spi3: spi@60 { reg = <0x60>; + compatible = "ibm,fsi2spi-restricted"; #address-cells = <1>; #size-cells = <0>; @@ -480,6 +493,7 @@ cfam2_spi2: spi@40 { reg = <0x40>; + compatible = "ibm,fsi2spi-restricted"; #address-cells = <1>; #size-cells = <0>; @@ -496,6 +510,7 @@ cfam2_spi3: spi@60 { reg = <0x60>; + compatible = "ibm,fsi2spi-restricted"; #address-cells = <1>; #size-cells = <0>; @@ -594,16 +609,6 @@ compatible = "ibm,cffps"; reg = <0x69>; }; - - power-supply@6a { - compatible = "ibm,cffps"; - reg = <0x6a>; - }; - - power-supply@6b { - compatible = "ibm,cffps"; - reg = <0x6b>; - }; }; &i2c4 { @@ -723,25 +728,25 @@ #address-cells = <1>; #size-cells = <0>; - fan@0 { + fan0: fan@0 { compatible = "pmbus-fan"; reg = <0>; tach-pulses = <2>; }; - fan@1 { + fan1: fan@1 { compatible = "pmbus-fan"; reg = <1>; tach-pulses = <2>; }; - fan@2 { + fan2: fan@2 { compatible = "pmbus-fan"; reg = <2>; tach-pulses = <2>; }; - fan@3 { + fan3: fan@3 { compatible = "pmbus-fan"; reg = <3>; tach-pulses = <2>; diff --git a/arch/arm/boot/dts/aspeed-bmc-intel-s2600wf.dts b/arch/arm/boot/dts/aspeed-bmc-intel-s2600wf.dts index 1deb30ec912c..6e9baf3bba53 100644 --- a/arch/arm/boot/dts/aspeed-bmc-intel-s2600wf.dts +++ b/arch/arm/boot/dts/aspeed-bmc-intel-s2600wf.dts @@ -22,9 +22,9 @@ #size-cells = <1>; ranges; - vga_memory: framebuffer@7f000000 { + vga_memory: framebuffer@9f000000 { no-map; - reg = <0x7f000000 0x01000000>; + reg = <0x9f000000 0x01000000>; /* 16M */ }; }; diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts b/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts index 4d070d6ba09f..c1478d2db602 100644 --- a/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts +++ b/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts @@ -26,11 +26,20 @@ #size-cells = <1>; ranges; - flash_memory: region@ba000000 { + flash_memory: region@b8000000 { no-map; reg = <0xb8000000 0x4000000>; /* 64M */ }; + ramoops@bc000000 { + compatible = "ramoops"; + reg = <0xbc000000 0x180000>; /* 16 * (3 * 0x8000) */ + record-size = <0x8000>; + console-size = <0x8000>; + pmsg-size = <0x8000>; + max-reason = <3>; /* KMSG_DUMP_EMERG */ + }; + vga_memory: region@bf000000 { no-map; compatible = "shared-dma-pool"; diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index 82f0213e3a3c..b3dafbc8caca 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -192,6 +192,11 @@ status = "disabled"; }; + silicon-id@7c { + compatible = "aspeed,ast2400-silicon-id", "aspeed,silicon-id"; + reg = <0x7c 0x4>; + }; + pinctrl: pinctrl@80 { reg = <0x80 0x18>, <0xa0 0x10>; compatible = "aspeed,ast2400-pinctrl"; diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index a93009aa2f04..5bc0de0f3365 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -239,6 +239,11 @@ status = "disabled"; }; + silicon-id@7c { + compatible = "aspeed,ast2500-silicon-id", "aspeed,silicon-id"; + reg = <0x7c 0x4 0x150 0x8>; + }; + pinctrl: pinctrl@80 { compatible = "aspeed,ast2500-pinctrl"; reg = <0x80 0x18>, <0xa0 0x10>; diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi index 74367ee96f20..810b0676ab03 100644 --- a/arch/arm/boot/dts/aspeed-g6.dtsi +++ b/arch/arm/boot/dts/aspeed-g6.dtsi @@ -317,6 +317,11 @@ compatible = "aspeed,ast2600-pinctrl"; }; + silicon-id@14 { + compatible = "aspeed,ast2600-silicon-id", "aspeed,silicon-id"; + reg = <0x14 0x4 0x5b0 0x8>; + }; + smp-memram@180 { compatible = "aspeed,ast2600-smpmem"; reg = <0x180 0x40>; @@ -363,7 +368,7 @@ #gpio-cells = <2>; gpio-controller; compatible = "aspeed,ast2600-gpio"; - reg = <0x1e780000 0x800>; + reg = <0x1e780000 0x400>; interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; gpio-ranges = <&pinctrl 0 0 208>; ngpios = <208>; diff --git a/arch/arm/boot/dts/ast2400-facebook-netbmc-common.dtsi b/arch/arm/boot/dts/ast2400-facebook-netbmc-common.dtsi new file mode 100644 index 000000000000..73a5503be78c --- /dev/null +++ b/arch/arm/boot/dts/ast2400-facebook-netbmc-common.dtsi @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2020 Facebook Inc. +/dts-v1/; + +#include "aspeed-g4.dtsi" + +/ { + aliases { + /* + * Override the default uart aliases to avoid breaking + * the legacy applications. + */ + serial0 = &uart5; + serial1 = &uart1; + serial2 = &uart3; + serial3 = &uart4; + }; + + memory@40000000 { + reg = <0x40000000 0x20000000>; + }; +}; + +&wdt1 { + status = "okay"; + aspeed,reset-type = "system"; +}; + +&fmc { + status = "okay"; + flash@0 { + status = "okay"; + m25p,fast-read; + label = "spi0.0"; +#include "facebook-bmc-flash-layout.dtsi" + }; +}; + +&uart1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_txd1_default + &pinctrl_rxd1_default>; +}; + +&uart3 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_txd3_default + &pinctrl_rxd3_default>; +}; + +&uart4 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_txd4_default + &pinctrl_rxd4_default + &pinctrl_ndts4_default>; +}; + +&uart5 { + status = "okay"; +}; + +&mac1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; +}; + +&i2c5 { + status = "okay"; +}; + +&i2c6 { + status = "okay"; +}; + +&i2c7 { + status = "okay"; +}; + +&i2c8 { + status = "okay"; +}; + +&i2c11 { + status = "okay"; +}; + +&i2c12 { + status = "okay"; +}; + +&vhub { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/at91-kizbox.dts b/arch/arm/boot/dts/at91-kizbox.dts index 7add151f6250..3b8812fcd854 100644 --- a/arch/arm/boot/dts/at91-kizbox.dts +++ b/arch/arm/boot/dts/at91-kizbox.dts @@ -48,48 +48,37 @@ }; }; - pwm_leds { + led-controller { compatible = "pwm-leds"; - network_green { + led-1 { label = "pwm:green:network"; - pwms = <&tcb_pwm 2 10000000 PWM_POLARITY_INVERTED>; + pwms = <&tcb1_pwm1 0 10000000 PWM_POLARITY_INVERTED>; max-brightness = <255>; linux,default-trigger = "default-on"; }; - network_red { + led-2 { label = "pwm:red:network"; - pwms = <&tcb_pwm 4 10000000 PWM_POLARITY_INVERTED>; + pwms = <&tcb1_pwm2 0 10000000 PWM_POLARITY_INVERTED>; max-brightness = <255>; linux,default-trigger = "default-on"; }; - user_green { + led-3 { label = "pwm:green:user"; - pwms = <&tcb_pwm 0 10000000 PWM_POLARITY_INVERTED>; + pwms = <&tcb1_pwm0 0 10000000 PWM_POLARITY_INVERTED>; max-brightness = <255>; linux,default-trigger = "default-on"; }; - user_red { + led-4 { label = "pwm:red:user"; - pwms = <&tcb_pwm 1 10000000 PWM_POLARITY_INVERTED>; + pwms = <&tcb1_pwm0 1 10000000 PWM_POLARITY_INVERTED>; max-brightness = <255>; linux,default-trigger = "default-on"; }; }; - - tcb_pwm: pwm { - compatible = "atmel,tcb-pwm"; - #pwm-cells = <3>; - tc-block = <1>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_tcb1_tioa0 - &pinctrl_tcb1_tioa1 - &pinctrl_tcb1_tioa2 - &pinctrl_tcb1_tiob0>; - }; }; &tcb0 { @@ -104,6 +93,32 @@ }; }; +&tcb1 { + tcb1_pwm0: pwm@0 { + compatible = "atmel,tcb-pwm"; + reg = <0>; + #pwm-cells = <3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tcb1_tioa0 &pinctrl_tcb1_tiob0>; + }; + + tcb1_pwm1: pwm@1 { + compatible = "atmel,tcb-pwm"; + reg = <1>; + #pwm-cells = <3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tcb1_tioa1>; + }; + + tcb1_pwm2: pwm@2 { + compatible = "atmel,tcb-pwm"; + reg = <2>; + #pwm-cells = <3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tcb1_tioa2>; + }; +}; + &ebi { status = "okay"; }; diff --git a/arch/arm/boot/dts/at91-kizbox2-common.dtsi b/arch/arm/boot/dts/at91-kizbox2-common.dtsi index 25f761065106..c08834ddf07b 100644 --- a/arch/arm/boot/dts/at91-kizbox2-common.dtsi +++ b/arch/arm/boot/dts/at91-kizbox2-common.dtsi @@ -58,24 +58,24 @@ }; }; - pwm_leds { + led-controller { compatible = "pwm-leds"; - blue { + led-1 { label = "pwm:blue:user"; pwms = <&pwm0 2 10000000 0>; max-brightness = <255>; linux,default-trigger = "none"; }; - green { + led-2 { label = "pwm:green:user"; pwms = <&pwm0 1 10000000 0>; max-brightness = <255>; linux,default-trigger = "default-on"; }; - red { + led-3 { label = "pwm:red:user"; pwms = <&pwm0 0 10000000 0>; max-brightness = <255>; diff --git a/arch/arm/boot/dts/at91-kizbox3-hs.dts b/arch/arm/boot/dts/at91-kizbox3-hs.dts index 0da1f0557eaf..2799b2a1f4d2 100644 --- a/arch/arm/boot/dts/at91-kizbox3-hs.dts +++ b/arch/arm/boot/dts/at91-kizbox3-hs.dts @@ -15,40 +15,40 @@ model = "Overkiz KIZBOX3-HS"; compatible = "overkiz,kizbox3-hs", "atmel,sama5d2", "atmel,sama5"; - pwm_leds { + led-controller-1 { status = "okay"; - red { + led-1 { status = "okay"; }; - green { + led-2 { status = "okay"; }; - blue { + led-3 { status = "okay"; }; - white { + led-4 { status = "okay"; }; }; - leds { + led-controller-2 { compatible = "gpio-leds"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_led_red &pinctrl_led_white>; status = "okay"; - red { + led-5 { label = "pio:red:user"; gpios = <&pioA PIN_PB1 GPIO_ACTIVE_HIGH>; default-state = "off"; }; - white { + led-6 { label = "pio:white:user"; gpios = <&pioA PIN_PB8 GPIO_ACTIVE_HIGH>; default-state = "off"; diff --git a/arch/arm/boot/dts/at91-kizbox3_common.dtsi b/arch/arm/boot/dts/at91-kizbox3_common.dtsi index 7c3076e245ef..9ce513dd514b 100644 --- a/arch/arm/boot/dts/at91-kizbox3_common.dtsi +++ b/arch/arm/boot/dts/at91-kizbox3_common.dtsi @@ -62,7 +62,7 @@ regulator-always-on; }; - pwm_leds { + led-controller-1 { compatible = "pwm-leds"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pwm0_pwm_h0 @@ -71,7 +71,7 @@ &pinctrl_pwm0_pwm_h3>; status = "disabled"; - red { + led-1 { label = "pwm:red:user"; pwms = <&pwm0 0 10000000 0>; max-brightness = <255>; @@ -79,7 +79,7 @@ status = "disabled"; }; - green { + led-2 { label = "pwm:green:user"; pwms = <&pwm0 1 10000000 0>; max-brightness = <255>; @@ -87,14 +87,14 @@ status = "disabled"; }; - blue { + led-3 { label = "pwm:blue:user"; pwms = <&pwm0 2 10000000 0>; max-brightness = <255>; status = "disabled"; }; - white { + led-4 { label = "pwm:white:user"; pwms = <&pwm0 3 10000000 0>; max-brightness = <255>; diff --git a/arch/arm/boot/dts/at91-kizboxmini-common.dtsi b/arch/arm/boot/dts/at91-kizboxmini-common.dtsi index d37724c10695..9c622892c692 100644 --- a/arch/arm/boot/dts/at91-kizboxmini-common.dtsi +++ b/arch/arm/boot/dts/at91-kizboxmini-common.dtsi @@ -54,10 +54,10 @@ }; }; - leds: pwm_leds { + leds: led-controller-1 { compatible = "pwm-leds"; - led_blue: pwm_blue { + led_blue: led-1 { label = "pwm:blue:user"; pwms = <&pwm0 2 10000000 0>; max-brightness = <255>; @@ -65,14 +65,14 @@ status = "disabled"; }; - led_green: pwm_green { + led_green: led-2 { label = "pwm:green:user"; pwms = <&pwm0 0 10000000 0>; max-brightness = <255>; linux,default-trigger = "default-on"; }; - led_red: pwm_red { + led_red: led-3 { label = "pwm:red:user"; pwms = <&pwm0 1 10000000 0>; max-brightness = <255>; diff --git a/arch/arm/boot/dts/at91-sam9x60ek.dts b/arch/arm/boot/dts/at91-sam9x60ek.dts index eae28b82c7fd..73b6b1f89de9 100644 --- a/arch/arm/boot/dts/at91-sam9x60ek.dts +++ b/arch/arm/boot/dts/at91-sam9x60ek.dts @@ -569,11 +569,14 @@ atmel,pins = <AT91_PIOB 16 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; }; }; -}; /* pinctrl */ -&pmc { - atmel,osc-bypass; -}; + usb1 { + pinctrl_usb_default: usb_default { + atmel,pins = <AT91_PIOD 15 AT91_PERIPH_GPIO AT91_PINCTRL_NONE + AT91_PIOD 16 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; + }; + }; +}; /* pinctrl */ &pwm0 { pinctrl-names = "default"; @@ -684,6 +687,8 @@ atmel,vbus-gpio = <0 &pioD 15 GPIO_ACTIVE_HIGH &pioD 16 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb_default>; status = "okay"; }; diff --git a/arch/arm/boot/dts/at91-sama5d27_som1.dtsi b/arch/arm/boot/dts/at91-sama5d27_som1.dtsi index b1f994c0ae79..1b1163858b1d 100644 --- a/arch/arm/boot/dts/at91-sama5d27_som1.dtsi +++ b/arch/arm/boot/dts/at91-sama5d27_som1.dtsi @@ -100,7 +100,7 @@ status = "okay"; at24@50 { - compatible = "24c02"; + compatible = "atmel,24c02"; reg = <0x50>; pagesize = <8>; }; diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts index cf13632edd44..5179258f9247 100644 --- a/arch/arm/boot/dts/at91-sama5d3_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts @@ -242,6 +242,11 @@ atmel,pins = <AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PE9, conflicts with A9 */ }; + pinctrl_usb_default: usb_default { + atmel,pins = + <AT91_PIOE 3 AT91_PERIPH_GPIO AT91_PINCTRL_NONE + AT91_PIOE 4 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; + }; }; }; }; @@ -259,6 +264,8 @@ &pioE 3 GPIO_ACTIVE_LOW &pioE 4 GPIO_ACTIVE_LOW >; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb_default>; status = "okay"; }; diff --git a/arch/arm/boot/dts/at91-sama5d4_xplained.dts b/arch/arm/boot/dts/at91-sama5d4_xplained.dts index e5974a17374c..0b3ad1b580b8 100644 --- a/arch/arm/boot/dts/at91-sama5d4_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d4_xplained.dts @@ -134,6 +134,11 @@ atmel,pins = <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; }; + pinctrl_usb_default: usb_default { + atmel,pins = + <AT91_PIOE 11 AT91_PERIPH_GPIO AT91_PINCTRL_NONE + AT91_PIOE 14 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; + }; pinctrl_key_gpio: key_gpio_0 { atmel,pins = <AT91_PIOE 8 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; @@ -159,6 +164,8 @@ &pioE 11 GPIO_ACTIVE_HIGH &pioE 14 GPIO_ACTIVE_HIGH >; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb_default>; status = "okay"; }; diff --git a/arch/arm/boot/dts/at91-smartkiz.dts b/arch/arm/boot/dts/at91-smartkiz.dts index 106f23ba4a3b..b76a6b5ac464 100644 --- a/arch/arm/boot/dts/at91-smartkiz.dts +++ b/arch/arm/boot/dts/at91-smartkiz.dts @@ -84,10 +84,8 @@ status = "okay"; }; -&leds { - blue { - status = "okay"; - }; +&led_blue { + status = "okay"; }; &adc0 { diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 82c5d7fd9811..019f1c3d4d30 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -697,8 +697,6 @@ }; adc0: adc@fffe0000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "atmel,at91sam9260-adc"; reg = <0xfffe0000 0x100>; interrupts = <5 IRQ_TYPE_LEVEL_HIGH 0>; @@ -708,29 +706,6 @@ atmel,adc-channels-used = <0xf>; atmel,adc-vref = <3300>; atmel,adc-startup-time = <15>; - atmel,adc-res = <8 10>; - atmel,adc-res-names = "lowres", "highres"; - atmel,adc-use-res = "highres"; - - trigger0 { - trigger-name = "timer-counter-0"; - trigger-value = <0x1>; - }; - trigger1 { - trigger-name = "timer-counter-1"; - trigger-value = <0x3>; - }; - - trigger2 { - trigger-name = "timer-counter-2"; - trigger-value = <0x5>; - }; - - trigger3 { - trigger-name = "external"; - trigger-value = <0xd>; - trigger-external; - }; }; rtc@fffffd20 { diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 19fc748a87c5..2ab730fd6472 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -812,8 +812,6 @@ }; adc0: adc@fffb0000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "atmel,at91sam9g45-adc"; reg = <0xfffb0000 0x100>; interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>; @@ -822,31 +820,6 @@ atmel,adc-channels-used = <0xff>; atmel,adc-vref = <3300>; atmel,adc-startup-time = <40>; - atmel,adc-res = <8 10>; - atmel,adc-res-names = "lowres", "highres"; - atmel,adc-use-res = "highres"; - - trigger0 { - trigger-name = "external-rising"; - trigger-value = <0x1>; - trigger-external; - }; - trigger1 { - trigger-name = "external-falling"; - trigger-value = <0x2>; - trigger-external; - }; - - trigger2 { - trigger-name = "external-any"; - trigger-value = <0x3>; - trigger-external; - }; - - trigger3 { - trigger-name = "continuous"; - trigger-value = <0x6>; - }; }; isi@fffb4000 { diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index 9734667abbfc..b6256a20fbc7 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -315,27 +315,27 @@ }; }; - leds { + led-controller-1 { compatible = "gpio-leds"; - d8 { + led-1 { label = "d8"; gpios = <&pioD 30 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; }; }; - pwmleds { + led-controller-2 { compatible = "pwm-leds"; - d6 { + led-2 { label = "d6"; pwms = <&pwm0 3 5000 PWM_POLARITY_INVERTED>; max-brightness = <255>; linux,default-trigger = "nand-disk"; }; - d7 { + led-3 { label = "d7"; pwms = <&pwm0 1 5000 PWM_POLARITY_INVERTED>; max-brightness = <255>; diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi index 5653e70c84b4..730d1182c73e 100644 --- a/arch/arm/boot/dts/at91sam9rl.dtsi +++ b/arch/arm/boot/dts/at91sam9rl.dtsi @@ -266,8 +266,6 @@ }; adc0: adc@fffd0000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "atmel,at91sam9rl-adc"; reg = <0xfffd0000 0x100>; interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>; @@ -277,29 +275,6 @@ atmel,adc-channels-used = <0x3f>; atmel,adc-vref = <3300>; atmel,adc-startup-time = <40>; - atmel,adc-res = <8 10>; - atmel,adc-res-names = "lowres", "highres"; - atmel,adc-use-res = "highres"; - - trigger0 { - trigger-name = "timer-counter-0"; - trigger-value = <0x1>; - }; - trigger1 { - trigger-name = "timer-counter-1"; - trigger-value = <0x3>; - }; - - trigger2 { - trigger-name = "timer-counter-2"; - trigger-value = <0x5>; - }; - - trigger3 { - trigger-name = "external"; - trigger-value = <0x13>; - trigger-external; - }; }; usb0: gadget@fffd4000 { diff --git a/arch/arm/boot/dts/at91sam9rlek.dts b/arch/arm/boot/dts/at91sam9rlek.dts index 1590862f16f2..62981b39c815 100644 --- a/arch/arm/boot/dts/at91sam9rlek.dts +++ b/arch/arm/boot/dts/at91sam9rlek.dts @@ -218,26 +218,26 @@ }; }; - pwmleds { + led-controller-1 { compatible = "pwm-leds"; - ds1 { + led-1 { label = "ds1"; pwms = <&pwm0 1 5000 PWM_POLARITY_INVERTED>; max-brightness = <255>; }; - ds2 { + led-2 { label = "ds2"; pwms = <&pwm0 2 5000 PWM_POLARITY_INVERTED>; max-brightness = <255>; }; }; - leds { + led-controller-2 { compatible = "gpio-leds"; - ds3 { + led-3 { label = "ds3"; gpios = <&pioD 14 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 4cdb05079cc7..395e883644cd 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -795,8 +795,6 @@ }; adc0: adc@f804c000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "atmel,at91sam9x5-adc"; reg = <0xf804c000 0x100>; interrupts = <19 IRQ_TYPE_LEVEL_HIGH 0>; @@ -808,32 +806,6 @@ atmel,adc-vref = <3300>; atmel,adc-startup-time = <40>; atmel,adc-sample-hold-time = <11>; - atmel,adc-res = <8 10>; - atmel,adc-res-names = "lowres", "highres"; - atmel,adc-use-res = "highres"; - - trigger0 { - trigger-name = "external-rising"; - trigger-value = <0x1>; - trigger-external; - }; - - trigger1 { - trigger-name = "external-falling"; - trigger-value = <0x2>; - trigger-external; - }; - - trigger2 { - trigger-name = "external-any"; - trigger-value = <0x3>; - trigger-external; - }; - - trigger3 { - trigger-name = "continuous"; - trigger-value = <0x6>; - }; }; spi0: spi@f0000000 { diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi index dacaef2c14ca..0025c88f660c 100644 --- a/arch/arm/boot/dts/bcm-cygnus.dtsi +++ b/arch/arm/boot/dts/bcm-cygnus.dtsi @@ -591,7 +591,6 @@ adc: adc@180a6000 { compatible = "brcm,iproc-static-adc"; #io-channel-cells = <1>; - io-channel-ranges; adc-syscon = <&ts_adc_syscon>; clocks = <&asiu_clks BCM_CYGNUS_ASIU_ADC_CLK>; clock-names = "tsc_clk"; diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi index e895f7cb8c9f..b4d2cc70afb1 100644 --- a/arch/arm/boot/dts/bcm-nsp.dtsi +++ b/arch/arm/boot/dts/bcm-nsp.dtsi @@ -385,12 +385,12 @@ clock-names = "apb_pclk"; }; - srab: srab@36000 { + srab: ethernet-switch@36000 { compatible = "brcm,nsp-srab"; reg = <0x36000 0x1000>, <0x3f308 0x8>, <0x3f410 0xc>; - reg-names = "srab", "mux_config", "sgmii"; + reg-names = "srab", "mux_config", "sgmii_config"; interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, @@ -420,6 +420,10 @@ status = "disabled"; /* ports are defined in board DTS */ + ports { + #address-cells = <1>; + #size-cells = <0>; + }; }; i2c0: i2c@38000 { diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts index 09a1182c2936..403bacf986eb 100644 --- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts @@ -181,12 +181,14 @@ &hdmi0 { clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>; clock-names = "hdmi", "bvb", "audio", "cec"; + wifi-2.4ghz-coexistence; status = "okay"; }; &hdmi1 { clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>; clock-names = "hdmi", "bvb", "audio", "cec"; + wifi-2.4ghz-coexistence; status = "okay"; }; diff --git a/arch/arm/boot/dts/bcm283x-rpi-usb-otg.dtsi b/arch/arm/boot/dts/bcm283x-rpi-usb-otg.dtsi index e2fd9610e125..20322de2f8bf 100644 --- a/arch/arm/boot/dts/bcm283x-rpi-usb-otg.dtsi +++ b/arch/arm/boot/dts/bcm283x-rpi-usb-otg.dtsi @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 &usb { dr_mode = "otg"; - g-rx-fifo-size = <256>; + g-rx-fifo-size = <558>; g-np-tx-fifo-size = <32>; /* * According to dwc2 the sum of all device EP diff --git a/arch/arm/boot/dts/bcm283x-rpi-usb-peripheral.dtsi b/arch/arm/boot/dts/bcm283x-rpi-usb-peripheral.dtsi index 0ff0e9e25327..1409d1b559c1 100644 --- a/arch/arm/boot/dts/bcm283x-rpi-usb-peripheral.dtsi +++ b/arch/arm/boot/dts/bcm283x-rpi-usb-peripheral.dtsi @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 &usb { dr_mode = "peripheral"; - g-rx-fifo-size = <256>; + g-rx-fifo-size = <558>; g-np-tx-fifo-size = <32>; g-tx-fifo-size = <256 256 512 512 512 768 768>; }; diff --git a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts index 810fc32f1895..5b4a481be4f4 100644 --- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts +++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts @@ -57,17 +57,10 @@ status = "okay"; }; -&usb3_phy { - status = "okay"; -}; - &srab { status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; label = "poe"; diff --git a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts index 7604b4480bb1..8636600385fd 100644 --- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts +++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts @@ -64,17 +64,10 @@ status = "okay"; }; -&usb3_phy { - status = "okay"; -}; - &srab { status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@4 { reg = <4>; label = "lan"; diff --git a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts index abd35a518046..51c64f0b2560 100644 --- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts +++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts @@ -122,9 +122,6 @@ status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; label = "lan4"; diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts index 4dcec6865469..2f2d2b0a6893 100644 --- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts +++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts @@ -117,7 +117,3 @@ }; }; }; - -&usb3_phy { - status = "okay"; -}; diff --git a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts index 1ec655809e57..68aaf0af3945 100644 --- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts +++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts @@ -57,17 +57,10 @@ status = "okay"; }; -&usb3_phy { - status = "okay"; -}; - &srab { status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@4 { reg = <4>; label = "poe"; diff --git a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts index 04bfd58127fc..432254383769 100644 --- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts +++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts @@ -105,17 +105,10 @@ status = "okay"; }; -&usb3_phy { - status = "okay"; -}; - &srab { status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; label = "lan4"; diff --git a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts index 01c390ed48ea..12e34a0439b4 100644 --- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts +++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts @@ -126,7 +126,3 @@ &usb2 { vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>; }; - -&usb3_phy { - status = "okay"; -}; diff --git a/arch/arm/boot/dts/bcm4709.dtsi b/arch/arm/boot/dts/bcm4709.dtsi index e1bb8661955f..cba3d910bed8 100644 --- a/arch/arm/boot/dts/bcm4709.dtsi +++ b/arch/arm/boot/dts/bcm4709.dtsi @@ -9,3 +9,7 @@ clock-frequency = <125000000>; status = "okay"; }; + +&srab { + compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab"; +}; diff --git a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts index 0faae8950375..3725f2b0d60b 100644 --- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts +++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts @@ -123,33 +123,13 @@ }; }; - mdio-bus-mux { - #address-cells = <1>; - #size-cells = <0>; + mdio-bus-mux@18003000 { /* BIT(9) = 1 => external mdio */ - mdio_ext: mdio@200 { + mdio@200 { reg = <0x200>; #address-cells = <1>; #size-cells = <0>; - }; - }; - - mdio-mii-mux { - compatible = "mdio-mux-mmioreg"; - mdio-parent-bus = <&mdio_ext>; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x1800c1c0 0x4>; - - /* BIT(6) = mdc, BIT(7) = mdio */ - mux-mask = <0xc0>; - - mdio-mii@0 { - /* Enable MII function */ - reg = <0x0>; - #address-cells = <1>; - #size-cells = <0>; switch@0 { compatible = "brcm,bcm53125"; @@ -159,6 +139,8 @@ reset-names = "robo_reset"; reg = <0>; dsa,member = <1 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_mdio>; ports { #address-cells = <1>; @@ -219,9 +201,6 @@ dsa,member = <0 0>; ports { - #address-cells = <1>; - #size-cells = <0>; - port@1 { reg = <1>; label = "lan7"; @@ -242,6 +221,30 @@ label = "wan"; }; + port@5 { + reg = <5>; + ethernet = <&gmac0>; + label = "cpu"; + status = "disabled"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + port@7 { + reg = <7>; + ethernet = <&gmac1>; + label = "cpu"; + status = "disabled"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + port@8 { reg = <8>; ethernet = <&gmac2>; @@ -268,3 +271,44 @@ &usb3_phy { status = "okay"; }; + +&nandcs { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "boot"; + reg = <0x0000000 0x0080000>; + read-only; + }; + + partition@80000 { + label = "nvram"; + reg = <0x080000 0x0100000>; + }; + + partition@180000{ + label = "devinfo"; + reg = <0x0180000 0x080000>; + }; + + partition@200000 { + label = "firmware"; + reg = <0x0200000 0x01D00000>; + compatible = "brcm,trx"; + }; + + partition@1F00000 { + label = "failsafe"; + reg = <0x01F00000 0x01D00000>; + read-only; + }; + + partition@5200000 { + label = "system"; + reg = <0x05200000 0x02E00000>; + }; + }; +}; diff --git a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts index 068e384b8ab7..6fa101f0a90d 100644 --- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts +++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts @@ -59,9 +59,6 @@ status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; label = "poe"; diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts index 9ae815ddbb4b..4f8d777ae18d 100644 --- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts +++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts @@ -57,9 +57,6 @@ status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; label = "lan"; diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts index a21b2d185596..e17e9a17fb00 100644 --- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts +++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts @@ -108,9 +108,6 @@ status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; label = "lan4"; diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts index 4d5c5aa7dc42..60cc87ecc7ec 100644 --- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts +++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts @@ -71,6 +71,10 @@ vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>; }; +&usb3_phy { + status = "okay"; +}; + &spi_nor { status = "okay"; }; @@ -79,9 +83,6 @@ status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; label = "lan4"; diff --git a/arch/arm/boot/dts/bcm47094.dtsi b/arch/arm/boot/dts/bcm47094.dtsi index cdc5ff593adb..2a8f7312d1be 100644 --- a/arch/arm/boot/dts/bcm47094.dtsi +++ b/arch/arm/boot/dts/bcm47094.dtsi @@ -8,6 +8,15 @@ / { }; +&pinctrl { + compatible = "brcm,bcm4709-pinmux"; + + pinmux_mdio: mdio { + groups = "mdio_grp"; + function = "mdio"; + }; +}; + &usb3_phy { compatible = "brcm,ns-bx-usb3-phy"; }; @@ -16,3 +25,7 @@ clock-frequency = <125000000>; status = "okay"; }; + +&srab { + compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab"; +}; diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi index ac3a99cf2079..7db72a2f1020 100644 --- a/arch/arm/boot/dts/bcm5301x.dtsi +++ b/arch/arm/boot/dts/bcm5301x.dtsi @@ -265,7 +265,7 @@ interrupt-parent = <&gic>; - ehci: ehci@21000 { + ehci: usb@21000 { #usb-cells = <0>; compatible = "generic-ehci"; @@ -287,7 +287,7 @@ }; }; - ohci: ohci@22000 { + ohci: usb@22000 { #usb-cells = <0>; compatible = "generic-ohci"; @@ -318,7 +318,7 @@ interrupt-parent = <&gic>; - xhci: xhci@23000 { + xhci: usb@23000 { #usb-cells = <0>; compatible = "generic-xhci"; @@ -428,7 +428,27 @@ #address-cells = <1>; #size-cells = <1>; - pin-controller@1c0 { + lcpll0: lcpll0@100 { + #clock-cells = <1>; + compatible = "brcm,nsp-lcpll0"; + reg = <0x100 0x14>; + clocks = <&osc>; + clock-output-names = "lcpll0", "pcie_phy", + "sdio", "ddr_phy"; + }; + + genpll: genpll@140 { + #clock-cells = <1>; + compatible = "brcm,nsp-genpll"; + reg = <0x140 0x24>; + clocks = <&osc>; + clock-output-names = "genpll", "phy", + "ethernetclk", + "usbclk", "iprocfast", + "sata1", "sata2"; + }; + + pinctrl: pin-controller@1c0 { compatible = "brcm,bcm4708-pinmux"; reg = <0x1c0 0x24>; reg-names = "cru_gpio_control"; @@ -454,41 +474,26 @@ function = "uart1"; }; }; - }; - }; - - lcpll0: lcpll0@1800c100 { - #clock-cells = <1>; - compatible = "brcm,nsp-lcpll0"; - reg = <0x1800c100 0x14>; - clocks = <&osc>; - clock-output-names = "lcpll0", "pcie_phy", "sdio", - "ddr_phy"; - }; - genpll: genpll@1800c140 { - #clock-cells = <1>; - compatible = "brcm,nsp-genpll"; - reg = <0x1800c140 0x24>; - clocks = <&osc>; - clock-output-names = "genpll", "phy", "ethernetclk", - "usbclk", "iprocfast", "sata1", - "sata2"; - }; - - thermal: thermal@1800c2c0 { - compatible = "brcm,ns-thermal"; - reg = <0x1800c2c0 0x10>; - #thermal-sensor-cells = <0>; + thermal: thermal@2c0 { + compatible = "brcm,ns-thermal"; + reg = <0x2c0 0x10>; + #thermal-sensor-cells = <0>; + }; + }; }; - srab: srab@18007000 { - compatible = "brcm,bcm5301x-srab"; + srab: ethernet-switch@18007000 { + compatible = "brcm,bcm53011-srab", "brcm,bcm5301x-srab"; reg = <0x18007000 0x1000>; status = "disabled"; /* ports are defined in board DTS */ + ports { + #address-cells = <1>; + #size-cells = <0>; + }; }; rng: rng@18004000 { diff --git a/arch/arm/boot/dts/bcm53573.dtsi b/arch/arm/boot/dts/bcm53573.dtsi index 4af8e3293cff..51546fccc616 100644 --- a/arch/arm/boot/dts/bcm53573.dtsi +++ b/arch/arm/boot/dts/bcm53573.dtsi @@ -135,7 +135,7 @@ #address-cells = <1>; #size-cells = <1>; - ehci: ehci@4000 { + ehci: usb@4000 { compatible = "generic-ehci"; reg = <0x4000 0x1000>; interrupt-parent = <&gic>; @@ -155,7 +155,7 @@ }; }; - ohci: ohci@d000 { + ohci: usb@d000 { #usb-cells = <0>; compatible = "generic-ohci"; diff --git a/arch/arm/boot/dts/bcm953012er.dts b/arch/arm/boot/dts/bcm953012er.dts index 957468224622..52feca0fb906 100644 --- a/arch/arm/boot/dts/bcm953012er.dts +++ b/arch/arm/boot/dts/bcm953012er.dts @@ -69,9 +69,6 @@ status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; label = "port0"; diff --git a/arch/arm/boot/dts/bcm958522er.dts b/arch/arm/boot/dts/bcm958522er.dts index 7be4c4e628e0..5443fc079e6e 100644 --- a/arch/arm/boot/dts/bcm958522er.dts +++ b/arch/arm/boot/dts/bcm958522er.dts @@ -178,3 +178,7 @@ &xhci { status = "okay"; }; + +&srab { + compatible = "brcm,bcm58522-srab", "brcm,nsp-srab"; +}; diff --git a/arch/arm/boot/dts/bcm958525er.dts b/arch/arm/boot/dts/bcm958525er.dts index e58ed7e95346..e1e3c26cef19 100644 --- a/arch/arm/boot/dts/bcm958525er.dts +++ b/arch/arm/boot/dts/bcm958525er.dts @@ -190,3 +190,7 @@ &xhci { status = "okay"; }; + +&srab { + compatible = "brcm,bcm58525-srab", "brcm,nsp-srab"; +}; diff --git a/arch/arm/boot/dts/bcm958525xmc.dts b/arch/arm/boot/dts/bcm958525xmc.dts index 21f922dc6019..f161ba2e7e5e 100644 --- a/arch/arm/boot/dts/bcm958525xmc.dts +++ b/arch/arm/boot/dts/bcm958525xmc.dts @@ -210,3 +210,7 @@ &xhci { status = "okay"; }; + +&srab { + compatible = "brcm,bcm58525-srab", "brcm,nsp-srab"; +}; diff --git a/arch/arm/boot/dts/bcm958622hr.dts b/arch/arm/boot/dts/bcm958622hr.dts index a49c2fd21f4a..83cb877d63db 100644 --- a/arch/arm/boot/dts/bcm958622hr.dts +++ b/arch/arm/boot/dts/bcm958622hr.dts @@ -176,9 +176,6 @@ status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { label = "port0"; reg = <0>; diff --git a/arch/arm/boot/dts/bcm958623hr.dts b/arch/arm/boot/dts/bcm958623hr.dts index dd6dff6452b8..4e106ce1384a 100644 --- a/arch/arm/boot/dts/bcm958623hr.dts +++ b/arch/arm/boot/dts/bcm958623hr.dts @@ -180,9 +180,6 @@ status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { label = "port0"; reg = <0>; diff --git a/arch/arm/boot/dts/bcm958625hr.dts b/arch/arm/boot/dts/bcm958625hr.dts index a71371b4065e..cda6cc281e18 100644 --- a/arch/arm/boot/dts/bcm958625hr.dts +++ b/arch/arm/boot/dts/bcm958625hr.dts @@ -195,9 +195,6 @@ status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { label = "port0"; reg = <0>; diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts index 7782b61c51a1..ffbff0014c65 100644 --- a/arch/arm/boot/dts/bcm958625k.dts +++ b/arch/arm/boot/dts/bcm958625k.dts @@ -216,9 +216,6 @@ status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { label = "port0"; reg = <0>; diff --git a/arch/arm/boot/dts/bcm988312hr.dts b/arch/arm/boot/dts/bcm988312hr.dts index edd0f630e025..3fd39c479a3c 100644 --- a/arch/arm/boot/dts/bcm988312hr.dts +++ b/arch/arm/boot/dts/bcm988312hr.dts @@ -184,9 +184,6 @@ status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { label = "port0"; reg = <0>; diff --git a/arch/arm/boot/dts/dove-sbc-a510.dts b/arch/arm/boot/dts/dove-sbc-a510.dts index 2bb85a9b7614..df021f9b0117 100644 --- a/arch/arm/boot/dts/dove-sbc-a510.dts +++ b/arch/arm/boot/dts/dove-sbc-a510.dts @@ -143,6 +143,7 @@ gpio_ext: gpio@20 { compatible = "nxp,pca9555"; reg = <0x20>; + gpio-controller; #gpio-cells = <2>; }; }; diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 4e1bbc0198eb..ce1194744f84 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -724,22 +724,40 @@ /* OCP2SCP1 */ /* IRQ for DWC3_3 and DWC3_4 need IRQ crossbar */ - gpmc: gpmc@50000000 { - compatible = "ti,am3352-gpmc"; - ti,hwmods = "gpmc"; - reg = <0x50000000 0x37c>; /* device IO registers */ - interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; - dmas = <&edma_xbar 4 0>; - dma-names = "rxtx"; - gpmc,num-cs = <8>; - gpmc,num-waitpins = <2>; - #address-cells = <2>; + + target-module@50000000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x50000000 4>, + <0x50000010 4>, + <0x50000014 4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,syss-mask = <1>; + clocks = <&l3main1_clkctrl DRA7_L3MAIN1_GPMC_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; #size-cells = <1>; - interrupt-controller; - #interrupt-cells = <2>; - gpio-controller; - #gpio-cells = <2>; - status = "disabled"; + ranges = <0x50000000 0x50000000 0x00001000>, /* regs */ + <0x00000000 0x00000000 0x40000000>; /* data */ + + gpmc: gpmc@50000000 { + compatible = "ti,am3352-gpmc"; + reg = <0x50000000 0x37c>; /* device IO registers */ + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&edma_xbar 4 0>; + dma-names = "rxtx"; + gpmc,num-cs = <8>; + gpmc,num-waitpins = <2>; + #address-cells = <2>; + #size-cells = <1>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; }; target-module@56000000 { @@ -932,7 +950,7 @@ }; }; - sham_target: target-module@4b101000 { + sham1_target: target-module@4b101000 { compatible = "ti,sysc-omap3-sham", "ti,sysc"; reg = <0x4b101100 0x4>, <0x4b101110 0x4>, @@ -951,7 +969,7 @@ #size-cells = <1>; ranges = <0x0 0x4b101000 0x1000>; - sham: sham@0 { + sham1: sham@0 { compatible = "ti,omap5-sham"; reg = <0 0x300>; interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; @@ -962,6 +980,62 @@ }; }; + sham2_target: target-module@42701000 { + compatible = "ti,sysc-omap3-sham", "ti,sysc"; + reg = <0x42701100 0x4>, + <0x42701110 0x4>, + <0x42701114 0x4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET | + SYSC_OMAP2_AUTOIDLE)>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,syss-mask = <1>; + /* Domains (P, C): l4per_pwrdm, l4sec_clkdm */ + clocks = <&l4sec_clkctrl DRA7_L4SEC_SHAM2_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x42701000 0x1000>; + + sham2: sham@0 { + compatible = "ti,omap5-sham"; + reg = <0 0x300>; + interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&edma_xbar 165 0>; + dma-names = "rx"; + clocks = <&l3_iclk_div>; + clock-names = "fck"; + }; + }; + + iva_hd_target: target-module@5a000000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x5a05a400 0x4>, + <0x5a05a410 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-midle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + power-domains = <&prm_iva>; + resets = <&prm_iva 2>; + reset-names = "rstctrl"; + clocks = <&iva_clkctrl DRA7_IVA_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x5a000000 0x5a000000 0x1000000>, + <0x5b000000 0x5b000000 0x1000000>; + + iva { + compatible = "ti,ivahd"; + }; + }; + opp_supply_mpu: opp-supply@4a003b20 { compatible = "ti,omap5-opp-supply"; reg = <0x4a003b20 0xc>; @@ -1031,53 +1105,130 @@ #include "dra7xx-clocks.dtsi" &prm { + prm_mpu: prm@300 { + compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; + reg = <0x300 0x100>; + #power-domain-cells = <0>; + }; + prm_dsp1: prm@400 { compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; reg = <0x400 0x100>; #reset-cells = <1>; + #power-domain-cells = <0>; }; prm_ipu: prm@500 { compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; reg = <0x500 0x100>; #reset-cells = <1>; + #power-domain-cells = <0>; + }; + + prm_coreaon: prm@628 { + compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; + reg = <0x628 0xd8>; + #power-domain-cells = <0>; }; prm_core: prm@700 { compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; reg = <0x700 0x100>; #reset-cells = <1>; + #power-domain-cells = <0>; }; prm_iva: prm@f00 { compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; reg = <0xf00 0x100>; + #reset-cells = <1>; + #power-domain-cells = <0>; + }; + + prm_cam: prm@1000 { + compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; + reg = <0x1000 0x100>; + #power-domain-cells = <0>; + }; + + prm_dss: prm@1100 { + compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; + reg = <0x1100 0x100>; + #power-domain-cells = <0>; + }; + + prm_gpu: prm@1200 { + compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; + reg = <0x1200 0x100>; + #power-domain-cells = <0>; + }; + + prm_l3init: prm@1300 { + compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; + reg = <0x1300 0x100>; + #reset-cells = <1>; + #power-domain-cells = <0>; + }; + + prm_l4per: prm@1400 { + compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; + reg = <0x1400 0x100>; + #power-domain-cells = <0>; + }; + + prm_custefuse: prm@1600 { + compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; + reg = <0x1600 0x100>; + #power-domain-cells = <0>; + }; + + prm_wkupaon: prm@1724 { + compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; + reg = <0x1724 0x100>; + #power-domain-cells = <0>; }; prm_dsp2: prm@1b00 { compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; reg = <0x1b00 0x40>; #reset-cells = <1>; + #power-domain-cells = <0>; }; prm_eve1: prm@1b40 { compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; reg = <0x1b40 0x40>; + #power-domain-cells = <0>; }; prm_eve2: prm@1b80 { compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; reg = <0x1b80 0x40>; + #power-domain-cells = <0>; }; prm_eve3: prm@1bc0 { compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; reg = <0x1bc0 0x40>; + #power-domain-cells = <0>; }; prm_eve4: prm@1c00 { compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; reg = <0x1c00 0x60>; + #power-domain-cells = <0>; + }; + + prm_rtc: prm@1c60 { + compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; + reg = <0x1c60 0x20>; + #power-domain-cells = <0>; + }; + + prm_vpe: prm@1c80 { + compatible = "ti,dra7-prm-inst", "ti,omap-prm-inst"; + reg = <0x1c80 0x80>; + #power-domain-cells = <0>; }; }; diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi b/arch/arm/boot/dts/dra7xx-clocks.dtsi index dc0a93bccbf1..2365554eef3c 100644 --- a/arch/arm/boot/dts/dra7xx-clocks.dtsi +++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi @@ -1726,6 +1726,20 @@ }; }; + iva_cm: iva-cm@f00 { + compatible = "ti,omap4-cm"; + reg = <0xf00 0x100>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0xf00 0x100>; + + iva_clkctrl: iva-clkctrl@20 { + compatible = "ti,clkctrl"; + reg = <0x20 0xc>; + #clock-cells = <2>; + }; + }; + cam_cm: cam-cm@1000 { compatible = "ti,omap4-cm"; reg = <0x1000 0x100>; diff --git a/arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi b/arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi index 1dbf3bbff8d3..597ade3e252f 100644 --- a/arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi +++ b/arch/arm/boot/dts/exynos-mfc-reserved-memory.dtsi @@ -11,14 +11,14 @@ #size-cells = <1>; ranges; - mfc_left: region_mfc_left { + mfc_left: region-mfc-left { compatible = "shared-dma-pool"; no-map; size = <0x2400000>; alignment = <0x100000>; }; - mfc_right: region_mfc_right { + mfc_right: region-mfc-right { compatible = "shared-dma-pool"; no-map; size = <0x800000>; diff --git a/arch/arm/boot/dts/exynos3250-artik5-eval.dts b/arch/arm/boot/dts/exynos3250-artik5-eval.dts index 20446a846a98..a1e22f630638 100644 --- a/arch/arm/boot/dts/exynos3250-artik5-eval.dts +++ b/arch/arm/boot/dts/exynos3250-artik5-eval.dts @@ -37,3 +37,29 @@ &serial_2 { status = "okay"; }; + +&spi_0 { + status = "okay"; + cs-gpios = <&gpx3 4 GPIO_ACTIVE_LOW>, <0>; + + assigned-clocks = <&cmu CLK_MOUT_SPI0>, <&cmu CLK_DIV_SPI0>, + <&cmu CLK_DIV_SPI0_PRE>, <&cmu CLK_SCLK_SPI0>; + assigned-clock-parents = <&cmu CLK_DIV_MPLL_PRE>, /* for: CLK_MOUT_SPI0 */ + <&cmu CLK_MOUT_SPI0>, /* for: CLK_DIV_SPI0 */ + <&cmu CLK_DIV_SPI0>, /* for: CLK_DIV_SPI0_PRE */ + <&cmu CLK_DIV_SPI0_PRE>; /* for: CLK_SCLK_SPI0 */ + + ethernet@0 { + compatible = "asix,ax88796c"; + reg = <0x0>; + local-mac-address = [00 00 00 00 00 00]; /* Filled in by a boot-loader */ + interrupt-parent = <&gpx2>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + spi-max-frequency = <40000000>; + reset-gpios = <&gpe0 2 GPIO_ACTIVE_LOW>; + + controller-data { + samsung,spi-feedback-delay = <2>; + }; + }; +}; diff --git a/arch/arm/boot/dts/exynos3250-artik5.dtsi b/arch/arm/boot/dts/exynos3250-artik5.dtsi index 12887b3924af..04290ec4583a 100644 --- a/arch/arm/boot/dts/exynos3250-artik5.dtsi +++ b/arch/arm/boot/dts/exynos3250-artik5.dtsi @@ -76,7 +76,7 @@ samsung,i2c-max-bus-freq = <100000>; status = "okay"; - s2mps14_pmic@66 { + pmic@66 { compatible = "samsung,s2mps14-pmic"; interrupt-parent = <&gpx3>; interrupts = <5 IRQ_TYPE_NONE>; diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts index c1a68e612037..69451566945d 100644 --- a/arch/arm/boot/dts/exynos3250-monk.dts +++ b/arch/arm/boot/dts/exynos3250-monk.dts @@ -34,10 +34,10 @@ reg = <0x0205F000 0x1000>; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - power_key { + power-key { gpios = <&gpx2 7 GPIO_ACTIVE_LOW>; linux,code = <KEY_POWER>; label = "power key"; @@ -62,7 +62,7 @@ #address-cells = <1>; #size-cells = <0>; - max77836: subpmic@25 { + max77836: pmic@25 { compatible = "maxim,max77836"; interrupt-parent = <&gpx1>; interrupts = <5 IRQ_TYPE_NONE>; @@ -197,7 +197,7 @@ samsung,i2c-max-bus-freq = <100000>; status = "okay"; - s2mps14_pmic@66 { + pmic@66 { compatible = "samsung,s2mps14-pmic"; interrupt-parent = <&gpx0>; interrupts = <7 IRQ_TYPE_NONE>; diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index b55afaaa691e..a26e3e582a7e 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -38,10 +38,10 @@ reg = <0x0205F000 0x1000>; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - power_key { + power-key { gpios = <&gpx2 7 GPIO_ACTIVE_LOW>; linux,code = <KEY_POWER>; label = "power key"; @@ -62,7 +62,7 @@ #address-cells = <1>; #size-cells = <0>; - max77836: subpmic@25 { + max77836: pmic@25 { compatible = "maxim,max77836"; interrupt-parent = <&gpx1>; interrupts = <5 IRQ_TYPE_NONE>; @@ -267,7 +267,7 @@ samsung,i2c-max-bus-freq = <100000>; status = "okay"; - s2mps14_pmic@66 { + pmic@66 { compatible = "samsung,s2mps14-pmic"; interrupt-parent = <&gpx0>; interrupts = <7 IRQ_TYPE_NONE>; diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi index a1e93fb7f694..77ab7193b903 100644 --- a/arch/arm/boot/dts/exynos3250.dtsi +++ b/arch/arm/boot/dts/exynos3250.dtsi @@ -439,7 +439,6 @@ clock-names = "adc", "sclk"; clocks = <&cmu CLK_TSADC>, <&cmu CLK_SCLK_TSADC>; #io-channel-cells = <1>; - io-channel-ranges; samsung,syscon-phandle = <&pmu_system_controller>; status = "disabled"; }; @@ -691,25 +690,25 @@ status = "disabled"; }; - ppmu_dmc0: ppmu_dmc0@106a0000 { + ppmu_dmc0: ppmu@106a0000 { compatible = "samsung,exynos-ppmu"; reg = <0x106a0000 0x2000>; status = "disabled"; }; - ppmu_dmc1: ppmu_dmc1@106b0000 { + ppmu_dmc1: ppmu@106b0000 { compatible = "samsung,exynos-ppmu"; reg = <0x106b0000 0x2000>; status = "disabled"; }; - ppmu_cpu: ppmu_cpu@106c0000 { + ppmu_cpu: ppmu@106c0000 { compatible = "samsung,exynos-ppmu"; reg = <0x106c0000 0x2000>; status = "disabled"; }; - ppmu_rightbus: ppmu_rightbus@112a0000 { + ppmu_rightbus: ppmu@112a0000 { compatible = "samsung,exynos-ppmu"; reg = <0x112a0000 0x2000>; clocks = <&cmu CLK_PPMURIGHT>; @@ -717,7 +716,7 @@ status = "disabled"; }; - ppmu_leftbus: ppmu_leftbus0@116a0000 { + ppmu_leftbus: ppmu@116a0000 { compatible = "samsung,exynos-ppmu"; reg = <0x116a0000 0x2000>; clocks = <&cmu CLK_PPMULEFT>; @@ -725,7 +724,7 @@ status = "disabled"; }; - ppmu_camif: ppmu_camif@11ac0000 { + ppmu_camif: ppmu@11ac0000 { compatible = "samsung,exynos-ppmu"; reg = <0x11ac0000 0x2000>; clocks = <&cmu CLK_PPMUCAMIF>; @@ -733,7 +732,7 @@ status = "disabled"; }; - ppmu_lcd0: ppmu_lcd0@11e40000 { + ppmu_lcd0: ppmu@11e40000 { compatible = "samsung,exynos-ppmu"; reg = <0x11e40000 0x2000>; clocks = <&cmu CLK_PPMULCD0>; @@ -741,7 +740,7 @@ status = "disabled"; }; - ppmu_fsys: ppmu_fsys@12630000 { + ppmu_fsys: ppmu@12630000 { compatible = "samsung,exynos-ppmu"; reg = <0x12630000 0x2000>; clocks = <&cmu CLK_PPMUFILE>; @@ -749,7 +748,7 @@ status = "disabled"; }; - ppmu_g3d: ppmu_g3d@13220000 { + ppmu_g3d: ppmu@13220000 { compatible = "samsung,exynos-ppmu"; reg = <0x13220000 0x2000>; clocks = <&cmu CLK_PPMUG3D>; @@ -757,7 +756,7 @@ status = "disabled"; }; - ppmu_mfc: ppmu_mfc@13660000 { + ppmu_mfc: ppmu@13660000 { compatible = "samsung,exynos-ppmu"; reg = <0x13660000 0x2000>; clocks = <&cmu CLK_PPMUMFC_L>; @@ -765,7 +764,7 @@ status = "disabled"; }; - bus_dmc: bus_dmc { + bus_dmc: bus-dmc { compatible = "samsung,exynos-bus"; clocks = <&cmu_dmc CLK_DIV_DMC>; clock-names = "bus"; @@ -773,9 +772,8 @@ status = "disabled"; }; - bus_dmc_opp_table: opp_table1 { + bus_dmc_opp_table: opp-table1 { compatible = "operating-points-v2"; - opp-shared; opp-50000000 { opp-hz = /bits/ 64 <50000000>; @@ -799,7 +797,7 @@ }; }; - bus_leftbus: bus_leftbus { + bus_leftbus: bus-leftbus { compatible = "samsung,exynos-bus"; clocks = <&cmu CLK_DIV_GDL>; clock-names = "bus"; @@ -807,7 +805,7 @@ status = "disabled"; }; - bus_rightbus: bus_rightbus { + bus_rightbus: bus-rightbus { compatible = "samsung,exynos-bus"; clocks = <&cmu CLK_DIV_GDR>; clock-names = "bus"; @@ -815,7 +813,7 @@ status = "disabled"; }; - bus_lcd0: bus_lcd0 { + bus_lcd0: bus-lcd0 { compatible = "samsung,exynos-bus"; clocks = <&cmu CLK_DIV_ACLK_160>; clock-names = "bus"; @@ -823,7 +821,7 @@ status = "disabled"; }; - bus_fsys: bus_fsys { + bus_fsys: bus-fsys { compatible = "samsung,exynos-bus"; clocks = <&cmu CLK_DIV_ACLK_200>; clock-names = "bus"; @@ -831,7 +829,7 @@ status = "disabled"; }; - bus_mcuisp: bus_mcuisp { + bus_mcuisp: bus-mcuisp { compatible = "samsung,exynos-bus"; clocks = <&cmu CLK_DIV_ACLK_400_MCUISP>; clock-names = "bus"; @@ -839,7 +837,7 @@ status = "disabled"; }; - bus_isp: bus_isp { + bus_isp: bus-isp { compatible = "samsung,exynos-bus"; clocks = <&cmu CLK_DIV_ACLK_266>; clock-names = "bus"; @@ -847,7 +845,7 @@ status = "disabled"; }; - bus_peril: bus_peril { + bus_peril: bus-peril { compatible = "samsung,exynos-bus"; clocks = <&cmu CLK_DIV_ACLK_100>; clock-names = "bus"; @@ -855,7 +853,7 @@ status = "disabled"; }; - bus_mfc: bus_mfc { + bus_mfc: bus-mfc { compatible = "samsung,exynos-bus"; clocks = <&cmu CLK_SCLK_MFC>; clock-names = "bus"; @@ -863,9 +861,8 @@ status = "disabled"; }; - bus_leftbus_opp_table: opp_table2 { + bus_leftbus_opp_table: opp-table2 { compatible = "operating-points-v2"; - opp-shared; opp-50000000 { opp-hz = /bits/ 64 <50000000>; @@ -889,9 +886,8 @@ }; }; - bus_mcuisp_opp_table: opp_table3 { + bus_mcuisp_opp_table: opp-table3 { compatible = "operating-points-v2"; - opp-shared; opp-50000000 { opp-hz = /bits/ 64 <50000000>; @@ -910,9 +906,8 @@ }; }; - bus_isp_opp_table: opp_table4 { + bus_isp_opp_table: opp-table4 { compatible = "operating-points-v2"; - opp-shared; opp-50000000 { opp-hz = /bits/ 64 <50000000>; @@ -931,9 +926,8 @@ }; }; - bus_peril_opp_table: opp_table5 { + bus_peril_opp_table: opp-table5 { compatible = "operating-points-v2"; - opp-shared; opp-50000000 { opp-hz = /bits/ 64 <50000000>; diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi index a1e54449f33f..eab77a66ae8f 100644 --- a/arch/arm/boot/dts/exynos4.dtsi +++ b/arch/arm/boot/dts/exynos4.dtsi @@ -782,7 +782,7 @@ status = "disabled"; }; - ppmu_dmc0: ppmu_dmc0@106a0000 { + ppmu_dmc0: ppmu@106a0000 { compatible = "samsung,exynos-ppmu"; reg = <0x106a0000 0x2000>; clocks = <&clock CLK_PPMUDMC0>; @@ -790,7 +790,7 @@ status = "disabled"; }; - ppmu_dmc1: ppmu_dmc1@106b0000 { + ppmu_dmc1: ppmu@106b0000 { compatible = "samsung,exynos-ppmu"; reg = <0x106b0000 0x2000>; clocks = <&clock CLK_PPMUDMC1>; @@ -798,7 +798,7 @@ status = "disabled"; }; - ppmu_cpu: ppmu_cpu@106c0000 { + ppmu_cpu: ppmu@106c0000 { compatible = "samsung,exynos-ppmu"; reg = <0x106c0000 0x2000>; clocks = <&clock CLK_PPMUCPU>; @@ -806,7 +806,7 @@ status = "disabled"; }; - ppmu_rightbus: ppmu_rightbus@112a0000 { + ppmu_rightbus: ppmu@112a0000 { compatible = "samsung,exynos-ppmu"; reg = <0x112a0000 0x2000>; clocks = <&clock CLK_PPMURIGHT>; @@ -814,7 +814,7 @@ status = "disabled"; }; - ppmu_leftbus: ppmu_leftbus0@116a0000 { + ppmu_leftbus: ppmu@116a0000 { compatible = "samsung,exynos-ppmu"; reg = <0x116a0000 0x2000>; clocks = <&clock CLK_PPMULEFT>; @@ -822,7 +822,7 @@ status = "disabled"; }; - ppmu_camif: ppmu_camif@11ac0000 { + ppmu_camif: ppmu@11ac0000 { compatible = "samsung,exynos-ppmu"; reg = <0x11ac0000 0x2000>; clocks = <&clock CLK_PPMUCAMIF>; @@ -830,7 +830,7 @@ status = "disabled"; }; - ppmu_lcd0: ppmu_lcd0@11e40000 { + ppmu_lcd0: ppmu@11e40000 { compatible = "samsung,exynos-ppmu"; reg = <0x11e40000 0x2000>; clocks = <&clock CLK_PPMULCD0>; @@ -838,13 +838,13 @@ status = "disabled"; }; - ppmu_fsys: ppmu_g3d@12630000 { + ppmu_fsys: ppmu@12630000 { compatible = "samsung,exynos-ppmu"; reg = <0x12630000 0x2000>; status = "disabled"; }; - ppmu_image: ppmu_image@12aa0000 { + ppmu_image: ppmu@12aa0000 { compatible = "samsung,exynos-ppmu"; reg = <0x12aa0000 0x2000>; clocks = <&clock CLK_PPMUIMAGE>; @@ -852,7 +852,7 @@ status = "disabled"; }; - ppmu_tv: ppmu_tv@12e40000 { + ppmu_tv: ppmu@12e40000 { compatible = "samsung,exynos-ppmu"; reg = <0x12e40000 0x2000>; clocks = <&clock CLK_PPMUTV>; @@ -860,7 +860,7 @@ status = "disabled"; }; - ppmu_g3d: ppmu_g3d@13220000 { + ppmu_g3d: ppmu@13220000 { compatible = "samsung,exynos-ppmu"; reg = <0x13220000 0x2000>; clocks = <&clock CLK_PPMUG3D>; @@ -868,7 +868,7 @@ status = "disabled"; }; - ppmu_mfc_left: ppmu_mfc_left@13660000 { + ppmu_mfc_left: ppmu@13660000 { compatible = "samsung,exynos-ppmu"; reg = <0x13660000 0x2000>; clocks = <&clock CLK_PPMUMFC_L>; @@ -876,7 +876,7 @@ status = "disabled"; }; - ppmu_mfc_right: ppmu_mfc_right@13670000 { + ppmu_mfc_right: ppmu@13670000 { compatible = "samsung,exynos-ppmu"; reg = <0x13670000 0x2000>; clocks = <&clock CLK_PPMUMFC_R>; diff --git a/arch/arm/boot/dts/exynos4210-i9100.dts b/arch/arm/boot/dts/exynos4210-i9100.dts index 5370ee477186..a0c3bab382ae 100644 --- a/arch/arm/boot/dts/exynos4210-i9100.dts +++ b/arch/arm/boot/dts/exynos4210-i9100.dts @@ -329,7 +329,7 @@ pinctrl-0 = <&i2c3_bus>; pinctrl-names = "default"; - mxt224-touchscreen@4a { + touchscreen@4a { compatible = "atmel,maxtouch"; reg = <0x4a>; @@ -348,7 +348,7 @@ pinctrl-0 = <&i2c5_bus>; pinctrl-names = "default"; - max8997_pmic@66 { + pmic@66 { compatible = "maxim,max8997-pmic"; reg = <0x66>; @@ -597,7 +597,7 @@ pinctrl-0 = <&i2c7_bus>; pinctrl-names = "default"; - ak8975@c { + magnetometer@c { compatible = "asahi-kasei,ak8975"; reg = <0x0c>; diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts index 7d2cfbafefb2..1c5394152561 100644 --- a/arch/arm/boot/dts/exynos4210-origen.dts +++ b/arch/arm/boot/dts/exynos4210-origen.dts @@ -43,7 +43,7 @@ enable-active-high; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; up { @@ -171,7 +171,7 @@ pinctrl-0 = <&i2c0_bus>; pinctrl-names = "default"; - max8997_pmic@66 { + pmic@66 { compatible = "maxim,max8997-pmic"; reg = <0x66>; interrupt-parent = <&gpx0>; diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts index c5609afa6101..d5797a67bf48 100644 --- a/arch/arm/boot/dts/exynos4210-smdkv310.dts +++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts @@ -90,61 +90,61 @@ pinctrl-0 = <&keypad_rows &keypad_cols>; status = "okay"; - key_1 { + key-1 { keypad,row = <0>; keypad,column = <3>; linux,code = <2>; }; - key_2 { + key-2 { keypad,row = <0>; keypad,column = <4>; linux,code = <3>; }; - key_3 { + key-3 { keypad,row = <0>; keypad,column = <5>; linux,code = <4>; }; - key_4 { + key-4 { keypad,row = <0>; keypad,column = <6>; linux,code = <5>; }; - key_5 { + key-5 { keypad,row = <0>; keypad,column = <7>; linux,code = <6>; }; - key_a { + key-a { keypad,row = <1>; keypad,column = <3>; linux,code = <30>; }; - key_b { + key-b { keypad,row = <1>; keypad,column = <4>; linux,code = <48>; }; - key_c { + key-c { keypad,row = <1>; keypad,column = <5>; linux,code = <46>; }; - key_d { + key-d { keypad,row = <1>; keypad,column = <6>; linux,code = <32>; }; - key_e { + key-e { keypad,row = <1>; keypad,column = <7>; linux,code = <18>; @@ -200,7 +200,7 @@ cs-gpios = <&gpc1 2 GPIO_ACTIVE_HIGH>; status = "okay"; - w25x80@0 { + flash@0 { #address-cells = <1>; #size-cells = <1>; compatible = "w25x80"; diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts index a226bec56a45..d2406c9146b8 100644 --- a/arch/arm/boot/dts/exynos4210-trats.dts +++ b/arch/arm/boot/dts/exynos4210-trats.dts @@ -263,7 +263,7 @@ pinctrl-names = "default"; status = "okay"; - mms114-touchscreen@48 { + touchscreen@48 { compatible = "melfas,mms114"; reg = <0x48>; interrupt-parent = <&gpx0>; @@ -283,7 +283,7 @@ pinctrl-names = "default"; status = "okay"; - max8997_pmic@66 { + pmic@66 { compatible = "maxim,max8997-pmic"; reg = <0x66>; @@ -462,6 +462,26 @@ }; }; +&pinctrl_1 { + bt_shutdown: bt-shutdown { + samsung,pins = "gpl1-0"; + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + bt_host_wakeup: bt-host-wakeup { + samsung,pins = "gpx2-6"; + samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + bt_device_wakeup: bt-device-wakeup { + samsung,pins = "gpx3-1"; + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; +}; + &rtc { status = "okay"; clocks = <&clock CLK_RTC>, <&pmic_ap_clk>; @@ -512,6 +532,17 @@ &serial_0 { status = "okay"; + pinctrl-0 = <&uart0_data &uart0_fctl>; + pinctrl-names = "default"; + + bluetooth { + compatible = "brcm,bcm4330-bt"; + pinctrl-0 = <&bt_shutdown &bt_device_wakeup &bt_host_wakeup>; + pinctrl-names = "default"; + shutdown-gpios = <&gpl1 0 GPIO_ACTIVE_HIGH>; + device-wakeup-gpios = <&gpx3 1 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpx2 6 GPIO_ACTIVE_HIGH>; + }; }; &serial_1 { diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts index 08284e8f3624..dd44ad2c6ad6 100644 --- a/arch/arm/boot/dts/exynos4210-universal_c210.dts +++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts @@ -532,6 +532,24 @@ }; &pinctrl_1 { + bt_shutdown: bt-shutdown { + samsung,pins = "gpe1-4"; + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + bt_host_wakeup: bt-host-wakeup { + samsung,pins = "gpx2-6"; + samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + bt_device_wakeup: bt-device-wakeup { + samsung,pins = "gpx3-1"; + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + lp3974_irq: lp3974-irq { samsung,pins = "gpx0-7", "gpx2-7"; samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; @@ -608,6 +626,17 @@ status = "okay"; /delete-property/dmas; /delete-property/dma-names; + pinctrl-0 = <&uart0_data &uart0_fctl>; + pinctrl-names = "default"; + + bluetooth { + compatible = "brcm,bcm4330-bt"; + pinctrl-0 = <&bt_shutdown &bt_device_wakeup &bt_host_wakeup>; + pinctrl-names = "default"; + shutdown-gpios = <&gpe1 4 GPIO_ACTIVE_HIGH>; + device-wakeup-gpios = <&gpx3 1 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpx2 6 GPIO_ACTIVE_HIGH>; + }; }; &serial_1 { diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi index fddc661ded28..70baad9b11f0 100644 --- a/arch/arm/boot/dts/exynos4210.dtsi +++ b/arch/arm/boot/dts/exynos4210.dtsi @@ -168,13 +168,13 @@ iommus = <&sysmmu_g2d>; }; - ppmu_acp: ppmu_acp@10ae0000 { + ppmu_acp: ppmu@10ae0000 { compatible = "samsung,exynos-ppmu"; reg = <0x10ae0000 0x2000>; status = "disabled"; }; - ppmu_lcd1: ppmu_lcd1@12240000 { + ppmu_lcd1: ppmu@12240000 { compatible = "samsung,exynos-ppmu"; reg = <0x12240000 0x2000>; clocks = <&clock CLK_PPMULCD1>; @@ -204,7 +204,7 @@ #iommu-cells = <0>; }; - bus_dmc: bus_dmc { + bus_dmc: bus-dmc { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DIV_DMC>; clock-names = "bus"; @@ -212,7 +212,7 @@ status = "disabled"; }; - bus_acp: bus_acp { + bus_acp: bus-acp { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DIV_ACP>; clock-names = "bus"; @@ -220,7 +220,7 @@ status = "disabled"; }; - bus_peri: bus_peri { + bus_peri: bus-peri { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_ACLK100>; clock-names = "bus"; @@ -228,7 +228,7 @@ status = "disabled"; }; - bus_fsys: bus_fsys { + bus_fsys: bus-fsys { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_ACLK133>; clock-names = "bus"; @@ -236,7 +236,7 @@ status = "disabled"; }; - bus_display: bus_display { + bus_display: bus-display { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_ACLK160>; clock-names = "bus"; @@ -244,7 +244,7 @@ status = "disabled"; }; - bus_lcd0: bus_lcd0 { + bus_lcd0: bus-lcd0 { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_ACLK200>; clock-names = "bus"; @@ -252,7 +252,7 @@ status = "disabled"; }; - bus_leftbus: bus_leftbus { + bus_leftbus: bus-leftbus { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DIV_GDL>; clock-names = "bus"; @@ -260,7 +260,7 @@ status = "disabled"; }; - bus_rightbus: bus_rightbus { + bus_rightbus: bus-rightbus { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DIV_GDR>; clock-names = "bus"; @@ -268,7 +268,7 @@ status = "disabled"; }; - bus_mfc: bus_mfc { + bus_mfc: bus-mfc { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_SCLK_MFC>; clock-names = "bus"; @@ -276,7 +276,7 @@ status = "disabled"; }; - bus_dmc_opp_table: opp_table1 { + bus_dmc_opp_table: opp-table1 { compatible = "operating-points-v2"; opp-shared; @@ -295,7 +295,7 @@ }; }; - bus_acp_opp_table: opp_table2 { + bus_acp_opp_table: opp-table2 { compatible = "operating-points-v2"; opp-shared; @@ -310,7 +310,7 @@ }; }; - bus_peri_opp_table: opp_table3 { + bus_peri_opp_table: opp-table3 { compatible = "operating-points-v2"; opp-shared; @@ -322,7 +322,7 @@ }; }; - bus_fsys_opp_table: opp_table4 { + bus_fsys_opp_table: opp-table4 { compatible = "operating-points-v2"; opp-shared; @@ -334,7 +334,7 @@ }; }; - bus_display_opp_table: opp_table5 { + bus_display_opp_table: opp-table5 { compatible = "operating-points-v2"; opp-shared; @@ -349,7 +349,7 @@ }; }; - bus_leftbus_opp_table: opp_table6 { + bus_leftbus_opp_table: opp-table6 { compatible = "operating-points-v2"; opp-shared; @@ -463,7 +463,7 @@ "ppmmu3"; operating-points-v2 = <&gpu_opp_table>; - gpu_opp_table: opp_table { + gpu_opp_table: opp-table { compatible = "operating-points-v2"; opp-160000000 { diff --git a/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi b/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi index 89ed81fb348d..c14e37dc3a9b 100644 --- a/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi +++ b/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi @@ -15,7 +15,7 @@ i2c10 = &i2c_cm36651; }; - aat1290 { + led-controller { compatible = "skyworks,aat1290"; flen-gpios = <&gpj1 1 GPIO_ACTIVE_HIGH>; enset-gpios = <&gpj1 2 GPIO_ACTIVE_HIGH>; @@ -58,9 +58,8 @@ i2c-gpio,delay-us = <2>; #address-cells = <1>; #size-cells = <0>; - status = "okay"; - ak8975@c { + magnetometer@c { compatible = "asahi-kasei,ak8975"; reg = <0x0c>; gpios = <&gpj0 7 GPIO_ACTIVE_HIGH>; @@ -75,7 +74,7 @@ #address-cells = <1>; #size-cells = <0>; - cm36651@18 { + light-sensor@18 { compatible = "capella,cm36651"; reg = <0x18>; interrupt-parent = <&gpx0>; @@ -133,7 +132,7 @@ }; &i2c_3 { - mms114-touchscreen@48 { + touchscreen@48 { compatible = "melfas,mms114"; reg = <0x48>; interrupt-parent = <&gpm2>; diff --git a/arch/arm/boot/dts/exynos4412-itop-elite.dts b/arch/arm/boot/dts/exynos4412-itop-elite.dts index f6d0a5f5d339..47431307cb3c 100644 --- a/arch/arm/boot/dts/exynos4412-itop-elite.dts +++ b/arch/arm/boot/dts/exynos4412-itop-elite.dts @@ -175,7 +175,7 @@ pinctrl-names = "default"; status = "okay"; - codec: wm8960@1a { + codec: audio-codec@1a { compatible = "wlf,wm8960"; reg = <0x1a>; clocks = <&pmu_system_controller 0>; diff --git a/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi b/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi index dfceb155b3a7..4583d342af39 100644 --- a/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi +++ b/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi @@ -134,7 +134,7 @@ pinctrl-names = "default"; status = "okay"; - s5m8767: s5m8767-pmic@66 { + s5m8767: pmic@66 { compatible = "samsung,s5m8767-pmic"; reg = <0x66>; diff --git a/arch/arm/boot/dts/exynos4412-midas.dtsi b/arch/arm/boot/dts/exynos4412-midas.dtsi index 7e7c243ff196..111c32bae02c 100644 --- a/arch/arm/boot/dts/exynos4412-midas.dtsi +++ b/arch/arm/boot/dts/exynos4412-midas.dtsi @@ -169,9 +169,8 @@ i2c-gpio,delay-us = <2>; #address-cells = <1>; #size-cells = <0>; - status = "okay"; - max77693@66 { + pmic@66 { compatible = "maxim,max77693"; interrupt-parent = <&gpx1>; interrupts = <5 IRQ_TYPE_EDGE_FALLING>; @@ -193,7 +192,7 @@ }; }; - max77693_haptic { + motor-driver { compatible = "maxim,max77693-haptic"; haptic-supply = <&ldo26_reg>; pwms = <&pwm 0 38022 0>; @@ -218,9 +217,8 @@ i2c-gpio,delay-us = <2>; #address-cells = <1>; #size-cells = <0>; - status = "okay"; - max77693-fuel-gauge@36 { + fuel-gauge@36 { compatible = "maxim,max17047"; interrupt-parent = <&gpx2>; interrupts = <3 IRQ_TYPE_EDGE_FALLING>; @@ -262,7 +260,6 @@ pinctrl-0 = <&i2c_mhl_bus>; pinctrl-names = "default"; - status = "okay"; sii9234: hdmi-bridge@39 { compatible = "sil,sii9234"; @@ -550,7 +547,7 @@ pinctrl-names = "default"; status = "okay"; - s5c73m3: s5c73m3@3c { + s5c73m3: image-sensor@3c { compatible = "samsung,s5c73m3"; reg = <0x3c>; xshutdown-gpios = <&gpf1 3 GPIO_ACTIVE_LOW>; /* ISP_RESET */ @@ -577,7 +574,7 @@ pinctrl-0 = <&fimc_is_i2c1>; pinctrl-names = "default"; - s5k6a3@10 { + image-sensor@10 { compatible = "samsung,s5k6a3"; reg = <0x10>; svdda-supply = <&cam_io_reg>; @@ -616,7 +613,7 @@ pinctrl-names = "default"; status = "okay"; - wm1811: wm1811@1a { + wm1811: audio-codec@1a { compatible = "wlf,wm1811"; reg = <0x1a>; clocks = <&pmu_system_controller 0>, @@ -665,7 +662,7 @@ pinctrl-names = "default"; status = "okay"; - max77686: max77686_pmic@9 { + max77686: pmic@9 { compatible = "maxim,max77686"; interrupt-parent = <&gpx0>; interrupts = <7 IRQ_TYPE_NONE>; @@ -1109,6 +1106,21 @@ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; }; + bt_shutdown: bt-shutdown { + samsung,pins = "gpl0-6"; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + bt_host_wakeup: bt-host-wakeup { + samsung,pins = "gpx2-6"; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + bt_device_wakeup: bt-device-wakeup { + samsung,pins = "gpx3-1"; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + max77686_irq: max77686-irq { samsung,pins = "gpx0-7"; samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; @@ -1386,7 +1398,20 @@ }; &serial_0 { + pinctrl-0 = <&uart0_data &uart0_fctl>; + pinctrl-names = "default"; status = "okay"; + + bluetooth { + compatible = "brcm,bcm4330-bt"; + pinctrl-0 = <&bt_shutdown &bt_device_wakeup &bt_host_wakeup>; + pinctrl-names = "default"; + max-speed = <3000000>; + shutdown-gpios = <&gpl0 6 GPIO_ACTIVE_HIGH>; + device-wakeup-gpios = <&gpx3 1 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpx2 6 GPIO_ACTIVE_HIGH>; + clocks = <&max77686 MAX77686_CLK_PMIC>; + }; }; &serial_1 { @@ -1407,7 +1432,7 @@ cs-gpios = <&gpb 5 GPIO_ACTIVE_HIGH>; status = "okay"; - s5c73m3_spi: s5c73m3@0 { + s5c73m3_spi: image-sensor@0 { compatible = "samsung,s5c73m3"; spi-max-frequency = <50000000>; reg = <0>; diff --git a/arch/arm/boot/dts/exynos4412-n710x.dts b/arch/arm/boot/dts/exynos4412-n710x.dts index a47b7f35fc80..c49dbb7847b8 100644 --- a/arch/arm/boot/dts/exynos4412-n710x.dts +++ b/arch/arm/boot/dts/exynos4412-n710x.dts @@ -45,7 +45,7 @@ pinctrl-names = "default"; status = "okay"; - mms152-touchscreen@48 { + touchscreen@48 { compatible = "melfas,mms152"; reg = <0x48>; interrupt-parent = <&gpm2>; diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index 2983e91bc7dd..2b20d9095d9f 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -22,12 +22,12 @@ reg = <0x0204F000 0x1000>; }; - gpio_keys { + gpio_keys: gpio-keys { compatible = "gpio-keys"; pinctrl-names = "default"; pinctrl-0 = <&gpio_power_key>; - power_key { + power-key { gpios = <&gpx1 3 GPIO_ACTIVE_LOW>; linux,code = <KEY_POWER>; label = "power key"; @@ -171,7 +171,7 @@ }; &pinctrl_1 { - gpio_power_key: power_key { + gpio_power_key: power-key { samsung,pins = "gpx1-3"; samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; }; @@ -255,7 +255,6 @@ }; &hsotg { - dr_mode = "peripheral"; status = "okay"; vusb_d-supply = <&ldo15_reg>; vusb_a-supply = <&ldo12_reg>; @@ -266,7 +265,7 @@ samsung,i2c-max-bus-freq = <400000>; status = "okay"; - usb3503: usb3503@8 { + usb3503: usb-hub@8 { compatible = "smsc,usb3503"; reg = <0x08>; @@ -492,7 +491,7 @@ &i2c_1 { status = "okay"; - max98090: max98090@10 { + max98090: audio-codec@10 { compatible = "maxim,max98090"; reg = <0x10>; interrupt-parent = <&gpx0>; diff --git a/arch/arm/boot/dts/exynos4412-odroidu3.dts b/arch/arm/boot/dts/exynos4412-odroidu3.dts index b8549d846f86..efaf7533e84f 100644 --- a/arch/arm/boot/dts/exynos4412-odroidu3.dts +++ b/arch/arm/boot/dts/exynos4412-odroidu3.dts @@ -16,11 +16,24 @@ model = "Hardkernel ODROID-U3 board based on Exynos4412"; compatible = "hardkernel,odroid-u3", "samsung,exynos4412", "samsung,exynos4"; + aliases { + ethernet = ðernet; + }; + memory@40000000 { device_type = "memory"; reg = <0x40000000 0x7FF00000>; }; + vbus_otg_reg: regulator-1 { + compatible = "regulator-fixed"; + regulator-name = "VBUS_VDD_5.0V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpl2 0 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + leds { compatible = "gpio-leds"; led1 { @@ -101,8 +114,21 @@ }; &ehci { + #address-cells = <1>; + #size-cells = <0>; phys = <&exynos_usbphy 2>, <&exynos_usbphy 3>; phy-names = "hsic0", "hsic1"; + + ethernet: usbether@2 { + compatible = "usb0424,9730"; + reg = <2>; + local-mac-address = [00 00 00 00 00 00]; /* Filled in by a bootloader */ + }; +}; + +&hsotg { + dr_mode = "otg"; + vbus-supply = <&vbus_otg_reg>; }; &sound { diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts b/arch/arm/boot/dts/exynos4412-odroidx.dts index 3ea2a0101e80..0e9d626e740a 100644 --- a/arch/arm/boot/dts/exynos4412-odroidx.dts +++ b/arch/arm/boot/dts/exynos4412-odroidx.dts @@ -15,6 +15,10 @@ model = "Hardkernel ODROID-X board based on Exynos4412"; compatible = "hardkernel,odroid-x", "samsung,exynos4412", "samsung,exynos4"; + aliases { + ethernet = ðernet; + }; + memory@40000000 { device_type = "memory"; reg = <0x40000000 0x3FF00000>; @@ -36,19 +40,7 @@ }; }; - gpio_keys { - pinctrl-0 = <&gpio_power_key &gpio_home_key>; - - home_key { - gpios = <&gpx2 2 GPIO_ACTIVE_HIGH>; - linux,code = <KEY_HOME>; - label = "home key"; - debounce-interval = <10>; - wakeup-source; - }; - }; - - regulator_p3v3 { + regulator-1 { compatible = "regulator-fixed"; regulator-name = "p3v3_en"; regulator-min-microvolt = <3300000>; @@ -72,8 +64,46 @@ }; &ehci { + #address-cells = <1>; + #size-cells = <0>; phys = <&exynos_usbphy 2>; phy-names = "hsic0"; + + hub@2 { + compatible = "usb0424,3503"; + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + + hub@1 { + compatible = "usb0424,9514"; + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + ethernet: usbether@1 { + compatible = "usb0424,ec00"; + reg = <1>; + local-mac-address = [00 00 00 00 00 00]; /* Filled in by a bootloader */ + }; + }; + }; +}; + +&gpio_keys { + pinctrl-0 = <&gpio_power_key &gpio_home_key>; + + home-key { + gpios = <&gpx2 2 GPIO_ACTIVE_HIGH>; + linux,code = <KEY_HOME>; + label = "home key"; + debounce-interval = <10>; + wakeup-source; + }; +}; + +&hsotg { + dr_mode = "peripheral"; }; &mshc_0 { @@ -81,7 +111,7 @@ }; &pinctrl_1 { - gpio_home_key: home_key { + gpio_home_key: home-key { samsung,pins = "gpx2-2"; samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; }; diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts index c2e793b69e7d..e1f6de53e20e 100644 --- a/arch/arm/boot/dts/exynos4412-origen.dts +++ b/arch/arm/boot/dts/exynos4412-origen.dts @@ -116,7 +116,7 @@ pinctrl-names = "default"; status = "okay"; - s5m8767_pmic@66 { + pmic@66 { compatible = "samsung,s5m8767-pmic"; reg = <0x66>; @@ -453,37 +453,37 @@ pinctrl-names = "default"; status = "okay"; - key_home { + key-home { keypad,row = <0>; keypad,column = <0>; linux,code = <KEY_HOME>; }; - key_down { + key-down { keypad,row = <0>; keypad,column = <1>; linux,code = <KEY_DOWN>; }; - key_up { + key-up { keypad,row = <1>; keypad,column = <0>; linux,code = <KEY_UP>; }; - key_menu { + key-menu { keypad,row = <1>; keypad,column = <1>; linux,code = <KEY_MENU>; }; - key_back { + key-back { keypad,row = <2>; keypad,column = <0>; linux,code = <KEY_BACK>; }; - key_enter { + key-enter { keypad,row = <2>; keypad,column = <1>; linux,code = <KEY_ENTER>; diff --git a/arch/arm/boot/dts/exynos4412-p4note-n8010.dts b/arch/arm/boot/dts/exynos4412-p4note-n8010.dts new file mode 100644 index 000000000000..9f559425bd2c --- /dev/null +++ b/arch/arm/boot/dts/exynos4412-p4note-n8010.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Samsung's Galaxy Note 10.1 - N801x (wifi only version) + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * http://www.samsung.com + */ + +/dts-v1/; +#include "exynos4412-p4note.dtsi" + +/ { + model = "Samsung Galaxy Note 10.1 (GT-N8010/N8013) based on Exynos4412"; + compatible = "samsung,n8010", "samsung,p4note", "samsung,exynos4412", "samsung,exynos4"; + + /* this is the base variant without any kind of modem */ +}; diff --git a/arch/arm/boot/dts/exynos4412-p4note.dtsi b/arch/arm/boot/dts/exynos4412-p4note.dtsi new file mode 100644 index 000000000000..b2f9d5448a18 --- /dev/null +++ b/arch/arm/boot/dts/exynos4412-p4note.dtsi @@ -0,0 +1,1132 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Samsung's Exynos4412 based p4note device family base DT. + * Based on exynos4412-midas.dtsi. + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * http://www.samsung.com + */ + +/dts-v1/; +#include "exynos4412.dtsi" +#include "exynos4412-ppmu-common.dtsi" + +#include <dt-bindings/clock/maxim,max77686.h> +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/pinctrl/samsung.h> + +/ { + compatible = "samsung,p4note", "samsung,exynos4412", "samsung,exynos4"; + + memory@40000000 { + device_type = "memory"; + reg = <0x40000000 0x80000000>; + }; + + chosen { + stdout-path = &serial_2; + }; + + firmware@204f000 { + compatible = "samsung,secure-firmware"; + reg = <0x0204F000 0x1000>; + }; + + fixed-rate-clocks { + xxti { + compatible = "samsung,clock-xxti"; + clock-frequency = <0>; + }; + + xusbxti { + compatible = "samsung,clock-xusbxti"; + clock-frequency = <24000000>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_keys>; + + key-down { + gpios = <&gpx2 2 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEDOWN>; + label = "volume down"; + debounce-interval = <10>; + }; + + key-up { + gpios = <&gpx3 3 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEUP>; + label = "volume up"; + debounce-interval = <10>; + }; + + key-power { + gpios = <&gpx2 7 GPIO_ACTIVE_LOW>; + linux,code = <KEY_POWER>; + label = "power"; + debounce-interval = <10>; + wakeup-source; + }; + }; + + voltage-regulator-1 { + compatible = "regulator-fixed"; + regulator-name = "TSP_LDO1"; + pinctrl-names = "default"; + pinctrl-0 = <&tsp_reg_gpio_1>; + gpios = <&gpm4 5 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + voltage-regulator-2 { + compatible = "regulator-fixed"; + regulator-name = "TSP_LDO2"; + pinctrl-names = "default"; + pinctrl-0 = <&tsp_reg_gpio_2>; + gpios = <&gpb 5 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + voltage-regulator-3 { + compatible = "regulator-fixed"; + regulator-name = "TSP_LDO3"; + pinctrl-names = "default"; + pinctrl-0 = <&tsp_reg_gpio_3>; + gpios = <&gpb 7 GPIO_ACTIVE_HIGH>; + startup-delay-us = <20000>; + enable-active-high; + regulator-always-on; + }; + + wlan_pwrseq: sdhci3-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&gpm3 5 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&wifi_reset>; + pinctrl-names = "default"; + clocks = <&max77686 MAX77686_CLK_PMIC>; + clock-names = "ext_clock"; + }; + + i2c-gpio-1 { + compatible = "i2c-gpio"; + sda-gpios = <&gpy2 4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpy2 5 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + i2c-gpio,delay-us = <2>; + #address-cells = <1>; + #size-cells = <0>; + + magnetometer@c { + compatible = "asahi-kasei,ak8975"; + reg = <0x0c>; + pinctrl-0 = <&ak8975_irq>; + pinctrl-names = "default"; + interrupt-parent = <&gpm4>; + interrupts = <7 IRQ_TYPE_EDGE_RISING>; + }; + }; + + i2c-gpio-2 { + compatible = "i2c-gpio"; + sda-gpios = <&gpy0 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpy0 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + i2c-gpio,delay-us = <2>; + #address-cells = <1>; + #size-cells = <0>; + + fuel-gauge@36 { + compatible = "maxim,max17042"; + reg = <0x36>; + pinctrl-0 = <&fuel_alert_irq>; + pinctrl-names = "default"; + interrupt-parent = <&gpx2>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + maxim,rsns-microohm = <10000>; + maxim,over-heat-temp = <600>; + maxim,over-volt = <4300>; + }; + }; + + i2c-gpio-3 { + compatible = "i2c-gpio"; + sda-gpios = <&gpm4 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpm4 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + i2c-gpio,delay-us = <5>; + #address-cells = <1>; + #size-cells = <0>; + + adc@41 { + compatible = "st,stmpe811"; + reg = <0x41>; + pinctrl-0 = <&stmpe_adc_irq>; + pinctrl-names = "default"; + interrupt-parent = <&gpx0>; + interrupts = <1 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + irq-trigger = <0x1>; + st,adc-freq = <3>; + st,mod-12b = <1>; + st,ref-sel = <0>; + st,sample-time = <3>; + + stmpe_adc { + compatible = "st,stmpe-adc"; + #io-channel-cells = <1>; + st,norequest-mask = <0x2F>; + }; + }; + }; +}; + +&adc { + vdd-supply = <&ldo3_reg>; + /* not verified */ + status = "okay"; +}; + +&bus_dmc { + devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>; + vdd-supply = <&buck1_reg>; + status = "okay"; +}; + +&bus_acp { + devfreq = <&bus_dmc>; + status = "okay"; +}; + +&bus_c2c { + devfreq = <&bus_dmc>; + status = "okay"; +}; + +&bus_leftbus { + devfreq-events = <&ppmu_leftbus_3>, <&ppmu_rightbus_3>; + vdd-supply = <&buck3_reg>; + status = "okay"; +}; + +&bus_rightbus { + devfreq = <&bus_leftbus>; + status = "okay"; +}; + +&bus_display { + devfreq = <&bus_leftbus>; + status = "okay"; +}; + +&bus_fsys { + devfreq = <&bus_leftbus>; + status = "okay"; +}; + +&bus_peri { + devfreq = <&bus_leftbus>; + status = "okay"; +}; + +&bus_mfc { + devfreq = <&bus_leftbus>; + status = "okay"; +}; + +&cpu0 { + cpu0-supply = <&buck2_reg>; +}; + +&cpu_thermal { + cooling-maps { + map0 { + /* Corresponds to 800MHz at freq_table */ + cooling-device = <&cpu0 7 7>, <&cpu1 7 7>, + <&cpu2 7 7>, <&cpu3 7 7>; + }; + map1 { + /* Corresponds to 200MHz at freq_table */ + cooling-device = <&cpu0 13 13>, <&cpu1 13 13>, + <&cpu2 13 13>, <&cpu3 13 13>; + }; + }; +}; + +&exynos_usbphy { + status = "okay"; +}; + +&fimd { + pinctrl-0 = <&lcd_clk &lcd_data24 &pwm1_out>; + pinctrl-names = "default"; + status = "okay"; + + display-timings { + timing0 { + clock-frequency = <66666666>; + hactive = <1280>; + vactive = <800>; + hfront-porch = <18>; + hback-porch = <36>; + hsync-len = <16>; + vback-porch = <16>; + vfront-porch = <4>; + vsync-len = <3>; + hsync-active = <1>; + }; + }; +}; + +&gpu { + mali-supply = <&buck4_reg>; + status = "okay"; +}; + +&hsotg { + vusb_a-supply = <&ldo12_reg>; + dr_mode = "peripheral"; + status = "okay"; +}; + +&i2c_3 { + samsung,i2c-sda-delay = <100>; + samsung,i2c-slave-addr = <0x10>; + samsung,i2c-max-bus-freq = <400000>; + pinctrl-0 = <&i2c3_bus>; + pinctrl-names = "default"; + status = "okay"; + + touchscreen@4a { + compatible = "atmel,maxtouch"; + reg = <0x4a>; + pinctrl-0 = <&tsp_rst &tsp_irq>; + pinctrl-names = "default"; + interrupt-parent = <&gpm2>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&gpm0 4 GPIO_ACTIVE_LOW>; + }; +}; + +&i2c_7 { + samsung,i2c-sda-delay = <100>; + samsung,i2c-slave-addr = <0x10>; + samsung,i2c-max-bus-freq = <400000>; + pinctrl-0 = <&i2c7_bus>; + pinctrl-names = "default"; + status = "okay"; + + max77686: pmic@9 { + compatible = "maxim,max77686"; + interrupt-parent = <&gpx0>; + interrupts = <7 IRQ_TYPE_NONE>; + pinctrl-0 = <&max77686_irq>; + pinctrl-names = "default"; + reg = <0x09>; + #clock-cells = <1>; + + voltage-regulators { + ldo1_reg: LDO1 { + regulator-name = "ldo1"; + regulator-always-on; + }; + + ldo2_reg: LDO2 { + regulator-name = "ldo2"; + regulator-always-on; + }; + + /* WM8994 audio */ + ldo3_reg: LDO3 { + regulator-name = "VCC_1.8V_AP"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + ldo4_reg: LDO4 { + regulator-name = "ldo4"; + regulator-always-on; + }; + + ldo5_reg: LDO5 { + regulator-name = "VCC_1.8V_IO"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + ldo6_reg: LDO6 { + regulator-name = "ldo6"; + regulator-always-on; + }; + + ldo7_reg: LDO7 { + regulator-name = "ldo7"; + regulator-always-on; + }; + + /* CSI IP block */ + ldo8_reg: LDO8 { + regulator-name = "VMIPI_1.0V"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + /* IR LED on/off */ + ldo9_reg: LDO9 { + regulator-name = "VLED_IC_1.9V"; + regulator-min-microvolt = <1950000>; + regulator-max-microvolt = <1950000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + /* CSI IP block */ + ldo10_reg: LDO10 { + regulator-name = "VMIPI_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + ldo11_reg: LDO11 { + regulator-name = "VABB1_1.9V"; + regulator-min-microvolt = <1950000>; + regulator-max-microvolt = <1950000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + /* USB OTG */ + ldo12_reg: LDO12 { + regulator-name = "VUOTG_3.0V"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + /* not connected */ + ldo13_reg: LDO13 { + regulator-name = "ldo13"; + }; + + ldo14_reg: LDO14 { + regulator-name = "VABB2_1.9V"; + regulator-min-microvolt = <1950000>; + regulator-max-microvolt = <1950000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + ldo15_reg: LDO15 { + regulator-name = "ldo15"; + regulator-always-on; + }; + + ldo16_reg: LDO16 { + regulator-name = "ldo16"; + regulator-always-on; + }; + + /* not connected */ + ldo17_reg: LDO17 { + regulator-name = "ldo17"; + }; + + /* Camera ISX012 */ + ldo18_reg: LDO18 { + regulator-name = "CAM_IO_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + /* Camera S5K6A3 */ + ldo19_reg: LDO19 { + regulator-name = "VT_CORE_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + /* not connected */ + ldo20_reg: LDO20 { + regulator-name = "ldo20"; + }; + + /* MMC2 */ + ldo21_reg: LDO21 { + regulator-name = "VTF_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + maxim,ena-gpios = <&gpy2 0 GPIO_ACTIVE_HIGH>; + }; + + /* not connected */ + ldo22_reg: LDO22 { + regulator-name = "ldo22"; + }; + + /* ADC */ + ldo23_reg: LDO23 { + regulator-name = "VDD_ADC_3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + /* Camera S5K6A3 */ + ldo24_reg: LDO24 { + regulator-name = "CAM_A2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + ldo25_reg: LDO25 { + regulator-name = "VLED_3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + /* Camera ISX012 */ + ldo26_reg: LDO26 { + regulator-name = "3MP_AF_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + buck1_reg: BUCK1 { + regulator-name = "VDD_MIF"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1050000>; + regulator-always-on; + regulator-boot-on; + }; + + buck2_reg: BUCK2 { + regulator-name = "VDD_ARM"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + regulator-boot-on; + }; + + buck3_reg: BUCK3 { + regulator-name = "VDD_INT"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + regulator-boot-on; + }; + + buck4_reg: BUCK4 { + regulator-name = "VDD_G3D"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1075000>; + regulator-boot-on; + }; + + buck5_reg: BUCK5 { + regulator-name = "buck5"; + regulator-always-on; + }; + + buck6_reg: BUCK6 { + regulator-name = "buck6"; + regulator-always-on; + }; + + buck7_reg: BUCK7 { + regulator-name = "buck7"; + regulator-always-on; + }; + + /* not connected */ + buck8_reg: BUCK8 { + regulator-name = "buck8"; + }; + + buck9_reg: BUCK9 { + regulator-name = "3MP_CORE_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; +}; + +&mshc_0 { + broken-cd; + non-removable; + card-detect-delay = <200>; + clock-frequency = <400000000>; + samsung,dw-mshc-ciu-div = <0>; + samsung,dw-mshc-sdr-timing = <2 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>; + pinctrl-names = "default"; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + status = "okay"; +}; + +&pinctrl_0 { + pinctrl-names = "default"; + pinctrl-0 = <&sleep0>; + + tsp_reg_gpio_2: tsp-reg-gpio-2 { + samsung,pins = "gpb-5"; + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + tsp_reg_gpio_3: tsp-reg-gpio-3 { + samsung,pins = "gpb-7"; + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + sleep0: sleep-states { + PIN_SLP(gpa0-0, INPUT, NONE); + PIN_SLP(gpa0-1, OUT0, NONE); + PIN_SLP(gpa0-2, INPUT, NONE); + PIN_SLP(gpa0-3, INPUT, UP); + PIN_SLP(gpa0-4, INPUT, NONE); + PIN_SLP(gpa0-5, INPUT, DOWN); + PIN_SLP(gpa0-6, INPUT, DOWN); + PIN_SLP(gpa0-7, INPUT, UP); + + PIN_SLP(gpa1-0, INPUT, DOWN); + PIN_SLP(gpa1-1, INPUT, DOWN); + PIN_SLP(gpa1-2, INPUT, DOWN); + PIN_SLP(gpa1-3, INPUT, DOWN); + PIN_SLP(gpa1-4, INPUT, DOWN); + PIN_SLP(gpa1-5, INPUT, DOWN); + + PIN_SLP(gpb-0, INPUT, NONE); + PIN_SLP(gpb-1, INPUT, NONE); + PIN_SLP(gpb-2, INPUT, NONE); + PIN_SLP(gpb-3, INPUT, NONE); + PIN_SLP(gpb-4, INPUT, DOWN); + PIN_SLP(gpb-5, INPUT, DOWN); + PIN_SLP(gpb-6, INPUT, DOWN); + PIN_SLP(gpb-7, INPUT, DOWN); + + PIN_SLP(gpc0-0, INPUT, DOWN); + PIN_SLP(gpc0-1, INPUT, DOWN); + PIN_SLP(gpc0-2, INPUT, DOWN); + PIN_SLP(gpc0-3, INPUT, DOWN); + PIN_SLP(gpc0-4, INPUT, DOWN); + + PIN_SLP(gpc1-0, INPUT, UP); + PIN_SLP(gpc1-1, PREV, NONE); + PIN_SLP(gpc1-2, INPUT, UP); + PIN_SLP(gpc1-3, INPUT, UP); + PIN_SLP(gpc1-4, INPUT, UP); + + PIN_SLP(gpd0-0, INPUT, DOWN); + PIN_SLP(gpd0-1, OUT0, NONE); + PIN_SLP(gpd0-2, INPUT, NONE); + PIN_SLP(gpd0-3, INPUT, NONE); + + PIN_SLP(gpd1-0, INPUT, DOWN); + PIN_SLP(gpd1-1, INPUT, DOWN); + PIN_SLP(gpd1-2, INPUT, NONE); + PIN_SLP(gpd1-3, INPUT, NONE); + + PIN_SLP(gpf0-0, OUT0, NONE); + PIN_SLP(gpf0-1, OUT0, NONE); + PIN_SLP(gpf0-2, OUT0, NONE); + PIN_SLP(gpf0-3, OUT0, NONE); + PIN_SLP(gpf0-4, OUT0, NONE); + PIN_SLP(gpf0-5, OUT0, NONE); + PIN_SLP(gpf0-6, OUT0, NONE); + PIN_SLP(gpf0-7, OUT0, NONE); + + PIN_SLP(gpf1-0, OUT0, NONE); + PIN_SLP(gpf1-1, OUT0, NONE); + PIN_SLP(gpf1-2, OUT0, NONE); + PIN_SLP(gpf1-3, OUT0, NONE); + PIN_SLP(gpf1-4, OUT0, NONE); + PIN_SLP(gpf1-5, OUT0, NONE); + PIN_SLP(gpf1-6, OUT0, NONE); + PIN_SLP(gpf1-7, OUT0, NONE); + + PIN_SLP(gpf2-0, OUT0, NONE); + PIN_SLP(gpf2-1, OUT0, NONE); + PIN_SLP(gpf2-2, OUT0, NONE); + PIN_SLP(gpf2-3, OUT0, NONE); + PIN_SLP(gpf2-4, OUT0, NONE); + PIN_SLP(gpf2-5, OUT0, NONE); + PIN_SLP(gpf2-6, OUT0, NONE); + PIN_SLP(gpf2-7, OUT0, NONE); + + PIN_SLP(gpf3-0, OUT0, NONE); + PIN_SLP(gpf3-1, OUT0, NONE); + PIN_SLP(gpf3-2, OUT0, NONE); + PIN_SLP(gpf3-3, OUT0, NONE); + PIN_SLP(gpf3-4, OUT0, NONE); + PIN_SLP(gpf3-5, OUT0, NONE); + + PIN_SLP(gpj0-0, INPUT, DOWN); + PIN_SLP(gpj0-1, INPUT, DOWN); + PIN_SLP(gpj0-2, INPUT, DOWN); + PIN_SLP(gpj0-3, PREV, NONE); + PIN_SLP(gpj0-4, PREV, NONE); + PIN_SLP(gpj0-5, OUT0, NONE); + PIN_SLP(gpj0-6, OUT0, NONE); + PIN_SLP(gpj0-7, OUT0, NONE); + + PIN_SLP(gpj1-0, OUT0, NONE); + PIN_SLP(gpj1-1, INPUT, DOWN); + PIN_SLP(gpj1-2, PREV, NONE); + PIN_SLP(gpj1-3, OUT0, NONE); + }; +}; + +&pinctrl_1 { + pinctrl-names = "default"; + pinctrl-0 = <&sleep1>; + + sd3_wifi: sd3-wifi { + samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6"; + samsung,pin-function = <EXYNOS_PIN_FUNC_2>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + bt_shutdown: bt-shutdown { + samsung,pins = "gpl0-6"; + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + uart_sel: uart-sel { + samsung,pins = "gpl2-7"; + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + samsung,pin-val = <1>; + /* 0 = CP, 1 = AP (serial output) */ + }; + + tsp_rst: tsp-rst { + samsung,pins = "gpm0-4"; + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + tsp_irq: tsp-irq { + samsung,pins = "gpm2-3"; + samsung,pin-function = <EXYNOS_PIN_FUNC_F>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + wifi_reset: wifi-reset { + samsung,pins = "gpm3-5"; + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + tsp_reg_gpio_1: tsp-reg-gpio-1 { + samsung,pins = "gpm4-5"; + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + ak8975_irq: ak8975-irq { + samsung,pins = "gpm4-7"; + samsung,pin-function = <EXYNOS_PIN_FUNC_F>; + samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>; + }; + + stmpe_adc_irq: stmpe-adc-irq { + samsung,pins = "gpx0-1"; + samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + max77686_irq: max77686-irq { + samsung,pins = "gpx0-7"; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + gpio_keys: gpio-keys { + samsung,pins = "gpx2-2", "gpx2-7", "gpx3-3"; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + fuel_alert_irq: fuel-alert-irq { + samsung,pins = "gpx2-3"; + samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + wifi_host_wake: wifi-host-wake { + samsung,pins = "gpx2-5"; + samsung,pin-function = <EXYNOS_PIN_FUNC_F>; + samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>; + }; + + bt_host_wakeup: bt-host-wakeup { + samsung,pins = "gpx2-6"; + samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + bt_device_wakeup: bt-device-wakeup { + samsung,pins = "gpx3-1"; + samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + sdhci2_cd: sdhci2-cd { + samsung,pins = "gpx3-4"; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + }; + + sleep1: sleep-states { + PIN_SLP(gpk0-0, PREV, NONE); + PIN_SLP(gpk0-1, PREV, NONE); + PIN_SLP(gpk0-2, PREV, NONE); + PIN_SLP(gpk0-3, PREV, NONE); + PIN_SLP(gpk0-4, PREV, NONE); + PIN_SLP(gpk0-5, PREV, NONE); + PIN_SLP(gpk0-6, PREV, NONE); + + PIN_SLP(gpk1-0, INPUT, DOWN); + PIN_SLP(gpk1-1, INPUT, DOWN); + PIN_SLP(gpk1-2, INPUT, DOWN); + PIN_SLP(gpk1-3, PREV, NONE); + PIN_SLP(gpk1-4, PREV, NONE); + PIN_SLP(gpk1-5, PREV, NONE); + PIN_SLP(gpk1-6, PREV, NONE); + + PIN_SLP(gpk2-0, INPUT, DOWN); + PIN_SLP(gpk2-1, INPUT, DOWN); + PIN_SLP(gpk2-2, INPUT, DOWN); + PIN_SLP(gpk2-3, INPUT, DOWN); + PIN_SLP(gpk2-4, INPUT, DOWN); + PIN_SLP(gpk2-5, INPUT, DOWN); + PIN_SLP(gpk2-6, INPUT, DOWN); + + PIN_SLP(gpk3-0, OUT0, NONE); + PIN_SLP(gpk3-1, INPUT, NONE); + PIN_SLP(gpk3-2, INPUT, DOWN); + PIN_SLP(gpk3-3, INPUT, NONE); + PIN_SLP(gpk3-4, INPUT, NONE); + PIN_SLP(gpk3-5, INPUT, NONE); + PIN_SLP(gpk3-6, INPUT, NONE); + + PIN_SLP(gpl0-0, OUT0, NONE); + PIN_SLP(gpl0-1, INPUT, NONE); + PIN_SLP(gpl0-2, INPUT, NONE); + PIN_SLP(gpl0-3, INPUT, DOWN); + PIN_SLP(gpl0-4, PREV, NONE); + PIN_SLP(gpl0-6, PREV, NONE); + + PIN_SLP(gpl1-0, OUT0, NONE); + PIN_SLP(gpl1-1, OUT0, NONE); + + PIN_SLP(gpl2-0, INPUT, DOWN); + PIN_SLP(gpl2-1, INPUT, DOWN); + PIN_SLP(gpl2-2, INPUT, DOWN); + PIN_SLP(gpl2-3, INPUT, DOWN); + PIN_SLP(gpl2-4, OUT0, NONE); + PIN_SLP(gpl2-5, INPUT, DOWN); + PIN_SLP(gpl2-6, PREV, NONE); + PIN_SLP(gpl2-7, PREV, NONE); + + PIN_SLP(gpm0-0, PREV, NONE); + PIN_SLP(gpm0-1, OUT0, NONE); + PIN_SLP(gpm0-2, INPUT, DOWN); + PIN_SLP(gpm0-3, INPUT, NONE); + PIN_SLP(gpm0-4, OUT0, NONE); + PIN_SLP(gpm0-5, OUT0, NONE); + PIN_SLP(gpm0-6, INPUT, DOWN); + PIN_SLP(gpm0-7, OUT0, NONE); + + PIN_SLP(gpm1-0, INPUT, NONE); + PIN_SLP(gpm1-1, INPUT, NONE); + PIN_SLP(gpm1-2, INPUT, NONE); + PIN_SLP(gpm1-3, INPUT, NONE); + PIN_SLP(gpm1-4, INPUT, NONE); + PIN_SLP(gpm1-5, INPUT, NONE); + PIN_SLP(gpm1-6, INPUT, DOWN); + + PIN_SLP(gpm2-0, INPUT, NONE); + PIN_SLP(gpm2-1, INPUT, NONE); + PIN_SLP(gpm2-2, OUT0, NONE); + PIN_SLP(gpm2-3, OUT0, DOWN); + PIN_SLP(gpm2-4, INPUT, DOWN); + + PIN_SLP(gpm3-0, PREV, NONE); + PIN_SLP(gpm3-1, PREV, NONE); + PIN_SLP(gpm3-2, PREV, NONE); + PIN_SLP(gpm3-3, OUT1, NONE); + PIN_SLP(gpm3-4, OUT0, DOWN); + PIN_SLP(gpm3-5, PREV, NONE); + PIN_SLP(gpm3-6, PREV, NONE); + PIN_SLP(gpm3-7, OUT0, NONE); + + PIN_SLP(gpm4-0, INPUT, NONE); + PIN_SLP(gpm4-1, INPUT, NONE); + PIN_SLP(gpm4-2, INPUT, DOWN); + PIN_SLP(gpm4-3, INPUT, DOWN); + PIN_SLP(gpm4-4, PREV, NONE); + PIN_SLP(gpm4-5, OUT0, NONE); + PIN_SLP(gpm4-6, OUT0, NONE); + PIN_SLP(gpm4-7, INPUT, DOWN); + + PIN_SLP(gpy0-0, INPUT, DOWN); + PIN_SLP(gpy0-1, INPUT, DOWN); + PIN_SLP(gpy0-2, INPUT, NONE); + PIN_SLP(gpy0-3, INPUT, NONE); + PIN_SLP(gpy0-4, INPUT, NONE); + PIN_SLP(gpy0-5, INPUT, NONE); + + PIN_SLP(gpy1-0, INPUT, DOWN); + PIN_SLP(gpy1-1, INPUT, DOWN); + PIN_SLP(gpy1-2, INPUT, DOWN); + PIN_SLP(gpy1-3, INPUT, DOWN); + + PIN_SLP(gpy2-0, PREV, NONE); + PIN_SLP(gpy2-1, INPUT, DOWN); + PIN_SLP(gpy2-2, INPUT, NONE); + PIN_SLP(gpy2-3, INPUT, NONE); + PIN_SLP(gpy2-4, INPUT, NONE); + PIN_SLP(gpy2-5, INPUT, NONE); + + PIN_SLP(gpy3-0, INPUT, DOWN); + PIN_SLP(gpy3-1, INPUT, DOWN); + PIN_SLP(gpy3-2, INPUT, DOWN); + PIN_SLP(gpy3-3, INPUT, DOWN); + PIN_SLP(gpy3-4, INPUT, DOWN); + PIN_SLP(gpy3-5, INPUT, DOWN); + PIN_SLP(gpy3-6, INPUT, DOWN); + PIN_SLP(gpy3-7, INPUT, DOWN); + + PIN_SLP(gpy4-0, INPUT, DOWN); + PIN_SLP(gpy4-1, INPUT, DOWN); + PIN_SLP(gpy4-2, INPUT, DOWN); + PIN_SLP(gpy4-3, INPUT, DOWN); + PIN_SLP(gpy4-4, INPUT, DOWN); + PIN_SLP(gpy4-5, INPUT, DOWN); + PIN_SLP(gpy4-6, INPUT, DOWN); + PIN_SLP(gpy4-7, INPUT, DOWN); + + PIN_SLP(gpy5-0, INPUT, DOWN); + PIN_SLP(gpy5-1, INPUT, DOWN); + PIN_SLP(gpy5-2, INPUT, DOWN); + PIN_SLP(gpy5-3, INPUT, DOWN); + PIN_SLP(gpy5-4, INPUT, DOWN); + PIN_SLP(gpy5-5, INPUT, DOWN); + PIN_SLP(gpy5-6, INPUT, DOWN); + PIN_SLP(gpy5-7, INPUT, DOWN); + + PIN_SLP(gpy6-0, INPUT, DOWN); + PIN_SLP(gpy6-1, INPUT, DOWN); + PIN_SLP(gpy6-2, INPUT, DOWN); + PIN_SLP(gpy6-3, INPUT, DOWN); + PIN_SLP(gpy6-4, INPUT, DOWN); + PIN_SLP(gpy6-5, INPUT, DOWN); + PIN_SLP(gpy6-6, INPUT, DOWN); + PIN_SLP(gpy6-7, INPUT, DOWN); + }; +}; + +&pinctrl_2 { + pinctrl-names = "default"; + pinctrl-0 = <&sleep2>; + + sleep2: sleep-states { + PIN_SLP(gpz-0, INPUT, DOWN); + PIN_SLP(gpz-1, INPUT, DOWN); + PIN_SLP(gpz-2, INPUT, DOWN); + PIN_SLP(gpz-3, INPUT, DOWN); + PIN_SLP(gpz-4, INPUT, DOWN); + PIN_SLP(gpz-5, INPUT, DOWN); + PIN_SLP(gpz-6, INPUT, DOWN); + }; +}; + +&pinctrl_3 { + pinctrl-names = "default"; + pinctrl-0 = <&sleep3>; + + sleep3: sleep-states { + PIN_SLP(gpv0-0, INPUT, DOWN); + PIN_SLP(gpv0-1, INPUT, DOWN); + PIN_SLP(gpv0-2, INPUT, DOWN); + PIN_SLP(gpv0-3, INPUT, DOWN); + PIN_SLP(gpv0-4, INPUT, DOWN); + PIN_SLP(gpv0-5, INPUT, DOWN); + PIN_SLP(gpv0-6, INPUT, DOWN); + PIN_SLP(gpv0-7, INPUT, DOWN); + + PIN_SLP(gpv1-0, INPUT, DOWN); + PIN_SLP(gpv1-1, INPUT, DOWN); + PIN_SLP(gpv1-2, INPUT, DOWN); + PIN_SLP(gpv1-3, INPUT, DOWN); + PIN_SLP(gpv1-4, INPUT, DOWN); + PIN_SLP(gpv1-5, INPUT, DOWN); + PIN_SLP(gpv1-6, INPUT, DOWN); + PIN_SLP(gpv1-7, INPUT, DOWN); + + PIN_SLP(gpv2-0, INPUT, DOWN); + PIN_SLP(gpv2-1, INPUT, DOWN); + PIN_SLP(gpv2-2, INPUT, DOWN); + PIN_SLP(gpv2-3, INPUT, DOWN); + PIN_SLP(gpv2-4, INPUT, DOWN); + PIN_SLP(gpv2-5, INPUT, DOWN); + PIN_SLP(gpv2-6, INPUT, DOWN); + PIN_SLP(gpv2-7, INPUT, DOWN); + + PIN_SLP(gpv3-0, INPUT, DOWN); + PIN_SLP(gpv3-1, INPUT, DOWN); + PIN_SLP(gpv3-2, INPUT, DOWN); + PIN_SLP(gpv3-3, INPUT, DOWN); + PIN_SLP(gpv3-4, INPUT, DOWN); + PIN_SLP(gpv3-5, INPUT, DOWN); + PIN_SLP(gpv3-6, INPUT, DOWN); + PIN_SLP(gpv3-7, INPUT, DOWN); + + PIN_SLP(gpv4-0, INPUT, DOWN); + PIN_SLP(gpv4-1, INPUT, DOWN); + }; +}; + +&pmu_system_controller { + assigned-clocks = <&pmu_system_controller 0>; + assigned-clock-parents = <&clock CLK_XUSBXTI>; +}; + +&rtc { + clocks = <&clock CLK_RTC>, <&max77686 MAX77686_CLK_AP>; + clock-names = "rtc", "rtc_src"; + status = "okay"; +}; + +&sdhci_2 { + bus-width = <4>; + cd-gpios = <&gpx3 4 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sdhci2_cd>; + pinctrl-names = "default"; + vmmc-supply = <&ldo21_reg>; + status = "okay"; +}; + +&sdhci_3 { + #address-cells = <1>; + #size-cells = <0>; + non-removable; + bus-width = <4>; + mmc-pwrseq = <&wlan_pwrseq>; + + pinctrl-names = "default"; + pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_wifi>; + status = "okay"; + + wifi@1 { + compatible = "brcm,bcm4329-fmac"; + reg = <0x1>; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_host_wake>; + interrupt-parent = <&gpx2>; + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "host-wake"; + }; +}; + +&serial_0 { + pinctrl-0 = <&uart0_data &uart0_fctl>; + pinctrl-names = "default"; + status = "okay"; + + bluetooth { + compatible = "brcm,bcm4330-bt"; + pinctrl-0 = <&bt_shutdown &bt_device_wakeup &bt_host_wakeup>; + pinctrl-names = "default"; + + max-speed = <2000000>; + shutdown-gpios = <&gpl0 6 GPIO_ACTIVE_HIGH>; + device-wakeup-gpios = <&gpx3 1 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpx2 6 GPIO_ACTIVE_HIGH>; + clocks = <&max77686 MAX77686_CLK_PMIC>; + clock-names = "lpo"; + }; +}; + +&serial_2 { + pinctrl-0 = <&uart_sel>; + pinctrl-names = "default"; + status = "okay"; +}; + +&tmu { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts index 49971203a8aa..cc99b955af0c 100644 --- a/arch/arm/boot/dts/exynos4412-smdk4412.dts +++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts @@ -71,61 +71,61 @@ pinctrl-names = "default"; status = "okay"; - key_1 { + key-1 { keypad,row = <1>; keypad,column = <3>; linux,code = <2>; }; - key_2 { + key-2 { keypad,row = <1>; keypad,column = <4>; linux,code = <3>; }; - key_3 { + key-3 { keypad,row = <1>; keypad,column = <5>; linux,code = <4>; }; - key_4 { + key-4 { keypad,row = <1>; keypad,column = <6>; linux,code = <5>; }; - key_5 { + key-5 { keypad,row = <1>; keypad,column = <7>; linux,code = <6>; }; - key_A { + key-A { keypad,row = <2>; keypad,column = <6>; linux,code = <30>; }; - key_B { + key-B { keypad,row = <2>; keypad,column = <7>; linux,code = <48>; }; - key_C { + key-C { keypad,row = <0>; keypad,column = <5>; linux,code = <46>; }; - key_D { + key-D { keypad,row = <2>; keypad,column = <5>; linux,code = <32>; }; - key_E { + key-E { keypad,row = <0>; keypad,column = <7>; linux,code = <18>; diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi index e76881dc0014..a142fe84010b 100644 --- a/arch/arm/boot/dts/exynos4412.dtsi +++ b/arch/arm/boot/dts/exynos4412.dtsi @@ -274,7 +274,6 @@ clocks = <&clock CLK_TSADC>; clock-names = "adc"; #io-channel-cells = <1>; - io-channel-ranges; samsung,syscon-phandle = <&pmu_system_controller>; status = "disabled"; }; @@ -378,15 +377,17 @@ #iommu-cells = <0>; }; - bus_dmc: bus_dmc { + bus_dmc: bus-dmc { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DIV_DMC>; clock-names = "bus"; operating-points-v2 = <&bus_dmc_opp_table>; + samsung,data-clock-ratio = <4>; + #interconnect-cells = <0>; status = "disabled"; }; - bus_acp: bus_acp { + bus_acp: bus-acp { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DIV_ACP>; clock-names = "bus"; @@ -394,7 +395,7 @@ status = "disabled"; }; - bus_c2c: bus_c2c { + bus_c2c: bus-c2c { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DIV_C2C>; clock-names = "bus"; @@ -404,7 +405,6 @@ bus_dmc_opp_table: opp-table1 { compatible = "operating-points-v2"; - opp-shared; opp-100000000 { opp-hz = /bits/ 64 <100000000>; @@ -431,7 +431,6 @@ bus_acp_opp_table: opp-table2 { compatible = "operating-points-v2"; - opp-shared; opp-100000000 { opp-hz = /bits/ 64 <100000000>; @@ -447,15 +446,17 @@ }; }; - bus_leftbus: bus_leftbus { + bus_leftbus: bus-leftbus { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DIV_GDL>; clock-names = "bus"; operating-points-v2 = <&bus_leftbus_opp_table>; + interconnects = <&bus_dmc>; + #interconnect-cells = <0>; status = "disabled"; }; - bus_rightbus: bus_rightbus { + bus_rightbus: bus-rightbus { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DIV_GDR>; clock-names = "bus"; @@ -463,15 +464,17 @@ status = "disabled"; }; - bus_display: bus_display { + bus_display: bus-display { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_ACLK160>; clock-names = "bus"; operating-points-v2 = <&bus_display_opp_table>; + interconnects = <&bus_leftbus &bus_dmc>; + #interconnect-cells = <0>; status = "disabled"; }; - bus_fsys: bus_fsys { + bus_fsys: bus-fsys { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_ACLK133>; clock-names = "bus"; @@ -479,7 +482,7 @@ status = "disabled"; }; - bus_peri: bus_peri { + bus_peri: bus-peri { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_ACLK100>; clock-names = "bus"; @@ -487,7 +490,7 @@ status = "disabled"; }; - bus_mfc: bus_mfc { + bus_mfc: bus-mfc { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_SCLK_MFC>; clock-names = "bus"; @@ -497,7 +500,6 @@ bus_leftbus_opp_table: opp-table3 { compatible = "operating-points-v2"; - opp-shared; opp-100000000 { opp-hz = /bits/ 64 <100000000>; @@ -520,7 +522,6 @@ bus_display_opp_table: opp-table4 { compatible = "operating-points-v2"; - opp-shared; opp-160000000 { opp-hz = /bits/ 64 <160000000>; @@ -532,7 +533,6 @@ bus_fsys_opp_table: opp-table5 { compatible = "operating-points-v2"; - opp-shared; opp-100000000 { opp-hz = /bits/ 64 <100000000>; @@ -544,7 +544,6 @@ bus_peri_opp_table: opp-table6 { compatible = "operating-points-v2"; - opp-shared; opp-50000000 { opp-hz = /bits/ 64 <50000000>; @@ -773,6 +772,7 @@ clock-names = "mixer", "hdmi", "sclk_hdmi", "vp"; clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>, <&clock CLK_VP>; + interconnects = <&bus_display &bus_dmc>; }; &pmu { diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index 79546f11af26..a161f6237c7f 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -27,7 +27,7 @@ stdout-path = "serial2:115200n8"; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; menu { @@ -211,7 +211,7 @@ samsung,i2c-max-bus-freq = <20000>; samsung,i2c-slave-addr = <0x66>; - s5m8767_pmic@66 { + pmic@66 { compatible = "samsung,s5m8767-pmic"; reg = <0x66>; interrupt-parent = <&gpx3>; @@ -511,7 +511,7 @@ &i2c_3 { status = "okay"; - wm1811: codec@1a { + wm1811: audio-codec@1a { compatible = "wlf,wm1811"; reg = <0x1a>; clocks = <&i2s0 CLK_I2S_CDCLK>; diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts index 186790f39e4d..8b5a79a8720c 100644 --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -290,7 +290,7 @@ reg = <0x51>; }; - wm8994: wm8994@1a { + wm8994: audio-codec@1a { compatible = "wlf,wm8994"; reg = <0x1a>; @@ -385,7 +385,7 @@ status = "okay"; cs-gpios = <&gpa2 5 GPIO_ACTIVE_HIGH>; - w25q80bw@0 { + flash@0 { #address-cells = <1>; #size-cells = <1>; compatible = "w25x80"; diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi index c952a615148e..6635f6184051 100644 --- a/arch/arm/boot/dts/exynos5250-snow-common.dtsi +++ b/arch/arm/boot/dts/exynos5250-snow-common.dtsi @@ -217,7 +217,7 @@ }; }; - mmc3_pwrseq: mmc3_pwrseq { + mmc3_pwrseq: mmc3-pwrseq { compatible = "mmc-pwrseq-simple"; reset-gpios = <&gpx0 2 GPIO_ACTIVE_LOW>, /* WIFI_RSTn */ <&gpx0 1 GPIO_ACTIVE_LOW>; /* WIFI_EN */ @@ -289,7 +289,7 @@ samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <378000>; - max77686: max77686@9 { + max77686: pmic@9 { compatible = "maxim,max77686"; interrupt-parent = <&gpx3>; interrupts = <2 IRQ_TYPE_NONE>; diff --git a/arch/arm/boot/dts/exynos5250-snow-rev5.dts b/arch/arm/boot/dts/exynos5250-snow-rev5.dts index 7cbfc6f1f4b8..0822b778c035 100644 --- a/arch/arm/boot/dts/exynos5250-snow-rev5.dts +++ b/arch/arm/boot/dts/exynos5250-snow-rev5.dts @@ -32,7 +32,7 @@ }; &i2c_7 { - max98090: codec@10 { + max98090: audio-codec@10 { compatible = "maxim,max98090"; reg = <0x10>; interrupts = <4 IRQ_TYPE_NONE>; diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts index 75fdc5e6d423..9946dce54d74 100644 --- a/arch/arm/boot/dts/exynos5250-snow.dts +++ b/arch/arm/boot/dts/exynos5250-snow.dts @@ -30,7 +30,7 @@ }; &i2c_7 { - max98095: codec@11 { + max98095: audio-codec@11 { compatible = "maxim,max98095"; reg = <0x11>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts index a92ade33779c..9d2baea62d0d 100644 --- a/arch/arm/boot/dts/exynos5250-spring.dts +++ b/arch/arm/boot/dts/exynos5250-spring.dts @@ -105,7 +105,7 @@ samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <378000>; - s5m8767-pmic@66 { + pmic@66 { compatible = "samsung,s5m8767-pmic"; reg = <0x66>; interrupt-parent = <&gpx3>; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index bd2d8835dd36..2ea2caaca4e2 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -70,7 +70,7 @@ }; }; - cpu0_opp_table: opp_table0 { + cpu0_opp_table: opp-table0 { compatible = "operating-points-v2"; opp-shared; @@ -635,8 +635,8 @@ #size-cells = <1>; ranges; - usbdrd_dwc3: dwc3@12000000 { - compatible = "synopsys,dwc3"; + usbdrd_dwc3: usb@12000000 { + compatible = "snps,dwc3"; reg = <0x12000000 0x10000>; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; phys = <&usbdrd_phy 0>, <&usbdrd_phy 1>; @@ -844,7 +844,6 @@ clocks = <&clock CLK_ADC>; clock-names = "adc"; #io-channel-cells = <1>; - io-channel-ranges; samsung,syscon-phandle = <&pmu_system_controller>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/exynos5410-odroidxu.dts b/arch/arm/boot/dts/exynos5410-odroidxu.dts index 75b4150c26d7..949c0721cdb4 100644 --- a/arch/arm/boot/dts/exynos5410-odroidxu.dts +++ b/arch/arm/boot/dts/exynos5410-odroidxu.dts @@ -19,6 +19,10 @@ model = "Hardkernel Odroid XU"; compatible = "hardkernel,odroid-xu", "samsung,exynos5410", "samsung,exynos5"; + aliases { + ethernet = ðernet; + }; + memory@40000000 { device_type = "memory"; reg = <0x40000000 0x7ea00000>; @@ -327,6 +331,8 @@ regulator-name = "vddq_lcd"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; + /* Supplies also GPK and GPJ */ + regulator-always-on; }; ldo8_reg: LDO8 { @@ -498,7 +504,7 @@ &i2c_1 { status = "okay"; - max98090: max98090@10 { + max98090: audio-codec@10 { compatible = "maxim,max98090"; reg = <0x10>; interrupt-parent = <&gpj3>; @@ -636,12 +642,22 @@ vtmu-supply = <&ldo10_reg>; }; +&usb3_0_oc { + /* External pull up */ + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; +}; + +&usb3_1_oc { + /* External pull up */ + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; +}; + &usbdrd_dwc3_0 { - dr_mode = "host"; + dr_mode = "peripheral"; }; &usbdrd_dwc3_1 { - dr_mode = "peripheral"; + dr_mode = "host"; }; &usbdrd3_0 { @@ -653,3 +669,14 @@ vdd33-supply = <&ldo12_reg>; vdd10-supply = <&ldo15_reg>; }; + +&usbhost2 { + #address-cells = <1>; + #size-cells = <0>; + + ethernet: usbether@2 { + compatible = "usb0424,9730"; + reg = <2>; + local-mac-address = [00 00 00 00 00 00]; /* Filled in by a bootloader */ + }; +}; diff --git a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi index e5d0a2a4f648..d0aa18443a69 100644 --- a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi +++ b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi @@ -560,6 +560,34 @@ interrupt-controller; #interrupt-cells = <2>; }; + + usb3_1_oc: usb3-1-oc { + samsung,pins = "gpk2-4", "gpk2-5"; + samsung,pin-function = <EXYNOS_PIN_FUNC_2>; + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>; + samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>; + }; + + usb3_1_vbusctrl: usb3-1-vbusctrl { + samsung,pins = "gpk2-6", "gpk2-7"; + samsung,pin-function = <EXYNOS_PIN_FUNC_2>; + samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>; + samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>; + }; + + usb3_0_oc: usb3-0-oc { + samsung,pins = "gpk3-0", "gpk3-1"; + samsung,pin-function = <EXYNOS_PIN_FUNC_2>; + samsung,pin-pud = <EXYNOS_PIN_PULL_UP>; + samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>; + }; + + usb3_0_vbusctrl: usb3-0-vbusctrl { + samsung,pins = "gpk3-2", "gpk3-3"; + samsung,pin-function = <EXYNOS_PIN_FUNC_2>; + samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>; + samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>; + }; }; &pinctrl_2 { diff --git a/arch/arm/boot/dts/exynos5410.dtsi b/arch/arm/boot/dts/exynos5410.dtsi index 60a87684b1af..584ce62361b1 100644 --- a/arch/arm/boot/dts/exynos5410.dtsi +++ b/arch/arm/boot/dts/exynos5410.dtsi @@ -390,6 +390,8 @@ &usbdrd3_0 { clocks = <&clock CLK_USBD300>; clock-names = "usbdrd30"; + pinctrl-names = "default"; + pinctrl-0 = <&usb3_0_oc>, <&usb3_0_vbusctrl>; }; &usbdrd_phy0 { @@ -401,6 +403,8 @@ &usbdrd3_1 { clocks = <&clock CLK_USBD301>; clock-names = "usbdrd30"; + pinctrl-names = "default"; + pinctrl-0 = <&usb3_1_oc>, <&usb3_1_vbusctrl>; }; &usbdrd_dwc3_1 { diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts index dd7f8385d81e..bf457d0c02eb 100644 --- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts +++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts @@ -39,7 +39,7 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; wakeup { @@ -344,7 +344,7 @@ &hsi2c_4 { status = "okay"; - s2mps11_pmic@66 { + pmic@66 { compatible = "samsung,s2mps11-pmic"; reg = <0x66>; diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index 2bcbdf8a39bf..315b3dc9c017 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -138,7 +138,7 @@ }; }; - mmc1_pwrseq: mmc1_pwrseq { + mmc1_pwrseq: mmc1-pwrseq { compatible = "mmc-pwrseq-simple"; reset-gpios = <&gpx0 0 GPIO_ACTIVE_LOW>; /* WIFI_EN */ clocks = <&max77802 MAX77802_CLK_32K_CP>; @@ -205,7 +205,7 @@ status = "okay"; clock-frequency = <400000>; - max77802: max77802-pmic@9 { + max77802: pmic@9 { compatible = "maxim,max77802"; interrupt-parent = <&gpx3>; interrupts = <1 IRQ_TYPE_NONE>; @@ -615,7 +615,7 @@ status = "okay"; clock-frequency = <400000>; - max98090: codec@10 { + max98090: audio-codec@10 { compatible = "maxim,max98090"; reg = <0x10>; interrupts = <2 IRQ_TYPE_NONE>; diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts index 4e49d8095b29..d506da9fa661 100644 --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts @@ -129,7 +129,7 @@ &hsi2c_4 { status = "okay"; - s2mps11_pmic@66 { + pmic@66 { compatible = "samsung,s2mps11-pmic"; reg = <0x66>; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 83580f076a58..e23e8ffb093f 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -42,7 +42,7 @@ * by exynos5420-cpus.dtsi or exynos5422-cpus.dtsi. */ - cluster_a15_opp_table: opp_table0 { + cluster_a15_opp_table: opp-table0 { compatible = "operating-points-v2"; opp-shared; @@ -108,7 +108,7 @@ }; }; - cluster_a7_opp_table: opp_table1 { + cluster_a7_opp_table: opp-table1 { compatible = "operating-points-v2"; opp-shared; @@ -240,9 +240,6 @@ dmc: memory-controller@10c20000 { compatible = "samsung,exynos5422-dmc"; reg = <0x10c20000 0x10000>, <0x10c30000 0x10000>; - interrupt-parent = <&combiner>; - interrupts = <16 0>, <16 1>; - interrupt-names = "drex_0", "drex_1"; clocks = <&clock CLK_FOUT_SPLL>, <&clock CLK_MOUT_SCLK_SPLL>, <&clock CLK_FF_DOUT_SPLL2>, @@ -1080,112 +1077,112 @@ #iommu-cells = <0>; }; - bus_wcore: bus_wcore { + bus_wcore: bus-wcore { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK400_WCORE>; clock-names = "bus"; status = "disabled"; }; - bus_noc: bus_noc { + bus_noc: bus-noc { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK100_NOC>; clock-names = "bus"; status = "disabled"; }; - bus_fsys_apb: bus_fsys_apb { + bus_fsys_apb: bus-fsys-apb { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_PCLK200_FSYS>; clock-names = "bus"; status = "disabled"; }; - bus_fsys: bus_fsys { + bus_fsys: bus-fsys { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK200_FSYS>; clock-names = "bus"; status = "disabled"; }; - bus_fsys2: bus_fsys2 { + bus_fsys2: bus-fsys2 { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK200_FSYS2>; clock-names = "bus"; status = "disabled"; }; - bus_mfc: bus_mfc { + bus_mfc: bus-mfc { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK333>; clock-names = "bus"; status = "disabled"; }; - bus_gen: bus_gen { + bus_gen: bus-gen { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK266>; clock-names = "bus"; status = "disabled"; }; - bus_peri: bus_peri { + bus_peri: bus-peri { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK66>; clock-names = "bus"; status = "disabled"; }; - bus_g2d: bus_g2d { + bus_g2d: bus-g2d { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK333_G2D>; clock-names = "bus"; status = "disabled"; }; - bus_g2d_acp: bus_g2d_acp { + bus_g2d_acp: bus-g2d-acp { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK266_G2D>; clock-names = "bus"; status = "disabled"; }; - bus_jpeg: bus_jpeg { + bus_jpeg: bus-jpeg { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK300_JPEG>; clock-names = "bus"; status = "disabled"; }; - bus_jpeg_apb: bus_jpeg_apb { + bus_jpeg_apb: bus-jpeg-apb { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK166>; clock-names = "bus"; status = "disabled"; }; - bus_disp1_fimd: bus_disp1_fimd { + bus_disp1_fimd: bus-disp1-fimd { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK300_DISP1>; clock-names = "bus"; status = "disabled"; }; - bus_disp1: bus_disp1 { + bus_disp1: bus-disp1 { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK400_DISP1>; clock-names = "bus"; status = "disabled"; }; - bus_gscl_scaler: bus_gscl_scaler { + bus_gscl_scaler: bus-gscl-scaler { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK300_GSCL>; clock-names = "bus"; status = "disabled"; }; - bus_mscl: bus_mscl { + bus_mscl: bus-mscl { compatible = "samsung,exynos-bus"; clocks = <&clock CLK_DOUT_ACLK400_MSCL>; clock-names = "bus"; diff --git a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi index b1cf9414ce17..d0df560eb0db 100644 --- a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi @@ -35,7 +35,7 @@ }; }; - bus_wcore_opp_table: opp_table2 { + bus_wcore_opp_table: opp-table2 { compatible = "operating-points-v2"; /* derived from 532MHz MPLL */ @@ -61,7 +61,7 @@ }; }; - bus_noc_opp_table: opp_table3 { + bus_noc_opp_table: opp-table3 { compatible = "operating-points-v2"; /* derived from 666MHz CPLL */ @@ -79,7 +79,7 @@ }; }; - bus_fsys_apb_opp_table: opp_table4 { + bus_fsys_apb_opp_table: opp-table4 { compatible = "operating-points-v2"; /* derived from 666MHz CPLL */ @@ -91,7 +91,7 @@ }; }; - bus_fsys2_opp_table: opp_table5 { + bus_fsys2_opp_table: opp-table5 { compatible = "operating-points-v2"; /* derived from 600MHz DPLL */ @@ -106,7 +106,7 @@ }; }; - bus_mfc_opp_table: opp_table6 { + bus_mfc_opp_table: opp-table6 { compatible = "operating-points-v2"; /* derived from 666MHz CPLL */ @@ -127,7 +127,7 @@ }; }; - bus_gen_opp_table: opp_table7 { + bus_gen_opp_table: opp-table7 { compatible = "operating-points-v2"; /* derived from 532MHz MPLL */ @@ -145,7 +145,7 @@ }; }; - bus_peri_opp_table: opp_table8 { + bus_peri_opp_table: opp-table8 { compatible = "operating-points-v2"; /* derived from 666MHz CPLL */ @@ -154,7 +154,7 @@ }; }; - bus_g2d_opp_table: opp_table9 { + bus_g2d_opp_table: opp-table9 { compatible = "operating-points-v2"; /* derived from 666MHz CPLL */ @@ -175,7 +175,7 @@ }; }; - bus_g2d_acp_opp_table: opp_table10 { + bus_g2d_acp_opp_table: opp-table10 { compatible = "operating-points-v2"; /* derived from 532MHz MPLL */ @@ -193,7 +193,7 @@ }; }; - bus_jpeg_opp_table: opp_table11 { + bus_jpeg_opp_table: opp-table11 { compatible = "operating-points-v2"; /* derived from 600MHz DPLL */ @@ -211,7 +211,7 @@ }; }; - bus_jpeg_apb_opp_table: opp_table12 { + bus_jpeg_apb_opp_table: opp-table12 { compatible = "operating-points-v2"; /* derived from 666MHz CPLL */ @@ -229,7 +229,7 @@ }; }; - bus_disp1_fimd_opp_table: opp_table13 { + bus_disp1_fimd_opp_table: opp-table13 { compatible = "operating-points-v2"; /* derived from 600MHz DPLL */ @@ -241,7 +241,7 @@ }; }; - bus_disp1_opp_table: opp_table14 { + bus_disp1_opp_table: opp-table14 { compatible = "operating-points-v2"; /* derived from 600MHz DPLL */ @@ -256,7 +256,7 @@ }; }; - bus_gscl_opp_table: opp_table15 { + bus_gscl_opp_table: opp-table15 { compatible = "operating-points-v2"; /* derived from 600MHz DPLL */ @@ -271,7 +271,7 @@ }; }; - bus_mscl_opp_table: opp_table16 { + bus_mscl_opp_table: opp-table16 { compatible = "operating-points-v2"; /* derived from 666MHz CPLL */ @@ -292,7 +292,7 @@ }; }; - dmc_opp_table: opp_table17 { + dmc_opp_table: opp-table17 { compatible = "operating-points-v2"; opp00 { @@ -503,7 +503,7 @@ &hsi2c_4 { status = "okay"; - s2mps11_pmic@66 { + pmic@66 { compatible = "samsung,s2mps11-pmic"; reg = <0x66>; samsung,s2mps11-acokb-ground; diff --git a/arch/arm/boot/dts/exynos5422-odroidhc1.dts b/arch/arm/boot/dts/exynos5422-odroidhc1.dts index 812659260278..20c222b33f98 100644 --- a/arch/arm/boot/dts/exynos5422-odroidhc1.dts +++ b/arch/arm/boot/dts/exynos5422-odroidhc1.dts @@ -15,10 +15,10 @@ compatible = "hardkernel,odroid-hc1", "samsung,exynos5800", \ "samsung,exynos5"; - pwmleds { + led-controller { compatible = "pwm-leds"; - blueled { + led-1 { label = "blue:heartbeat"; pwms = <&pwm 2 2000000 0>; pwm-names = "pwm2"; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi index b5ec4f47eb3a..86b96f9706db 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi @@ -40,7 +40,7 @@ &hsi2c_5 { status = "okay"; - max98090: max98090@10 { + max98090: audio-codec@10 { compatible = "maxim,max98090"; reg = <0x10>; interrupt-parent = <&gpx3>; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi index 5da2d81e3be2..e35af40a55cb 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi @@ -13,12 +13,12 @@ #include "exynos5422-odroid-core.dtsi" / { - gpio_keys { + gpio-keys { compatible = "gpio-keys"; pinctrl-names = "default"; pinctrl-0 = <&power_key>; - power_key { + power-key { /* * The power button (SW2) is connected to the PWRON * pin (active high) of the S2MPS11 PMIC, which acts diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts b/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts index 98feecad5489..62c5928aa994 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts @@ -16,6 +16,10 @@ / { model = "Hardkernel Odroid XU3 Lite"; compatible = "hardkernel,odroid-xu3-lite", "samsung,exynos5800", "samsung,exynos5"; + + aliases { + ethernet = ðernet; + }; }; &arm_a7_pmu { @@ -103,3 +107,21 @@ &usbdrd_dwc3_1 { dr_mode = "peripheral"; }; + +&usbhost2 { + #address-cells = <1>; + #size-cells = <0>; + + hub@1 { + compatible = "usb0424,9514"; + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + ethernet: usbether@1 { + compatible = "usb0424,ec00"; + reg = <1>; + local-mac-address = [00 00 00 00 00 00]; /* Filled in by a bootloader */ + }; + }; +}; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts b/arch/arm/boot/dts/exynos5422-odroidxu3.dts index db0bc17a667b..cecaeb69e623 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts +++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts @@ -15,34 +15,38 @@ / { model = "Hardkernel Odroid XU3"; compatible = "hardkernel,odroid-xu3", "samsung,exynos5800", "samsung,exynos5"; + + aliases { + ethernet = ðernet; + }; }; &i2c_0 { status = "okay"; /* A15 cluster: VDD_ARM */ - ina231@40 { + power-sensor@40 { compatible = "ti,ina231"; reg = <0x40>; shunt-resistor = <10000>; }; /* memory: VDD_MEM */ - ina231@41 { + power-sensor@41 { compatible = "ti,ina231"; reg = <0x41>; shunt-resistor = <10000>; }; /* GPU: VDD_G3D */ - ina231@44 { + power-sensor@44 { compatible = "ti,ina231"; reg = <0x44>; shunt-resistor = <10000>; }; /* A7 cluster: VDD_KFC */ - ina231@45 { + power-sensor@45 { compatible = "ti,ina231"; reg = <0x45>; shunt-resistor = <10000>; @@ -70,3 +74,21 @@ &usbdrd_dwc3_1 { dr_mode = "peripheral"; }; + +&usbhost2 { + #address-cells = <1>; + #size-cells = <0>; + + hub@1 { + compatible = "usb0424,9514"; + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + ethernet: usbether@1 { + compatible = "usb0424,ec00"; + reg = <1>; + local-mac-address = [00 00 00 00 00 00]; /* Filled in by a bootloader */ + }; + }; +}; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu4.dts b/arch/arm/boot/dts/exynos5422-odroidxu4.dts index ddd55d3bcadd..ede782257643 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu4.dts +++ b/arch/arm/boot/dts/exynos5422-odroidxu4.dts @@ -17,10 +17,10 @@ compatible = "hardkernel,odroid-xu4", "samsung,exynos5800", \ "samsung,exynos5"; - pwmleds { + led-controller { compatible = "pwm-leds"; - blueled { + led-1 { label = "blue:heartbeat"; pwms = <&pwm 2 2000000 0>; pwm-names = "pwm2"; diff --git a/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi b/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi index 56acd832f0b3..2fc3e86dc5f7 100644 --- a/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi +++ b/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi @@ -11,10 +11,10 @@ #include <dt-bindings/gpio/gpio.h> / { - pwmleds { + led-controller-1 { compatible = "pwm-leds"; - greenled { + led-1 { label = "green:mmc0"; pwms = <&pwm 1 2000000 0>; pwm-names = "pwm1"; @@ -26,7 +26,7 @@ linux,default-trigger = "mmc0"; }; - blueled { + led-2 { label = "blue:heartbeat"; pwms = <&pwm 2 2000000 0>; pwm-names = "pwm2"; @@ -35,9 +35,10 @@ }; }; - gpioleds { + led-controller-2 { compatible = "gpio-leds"; - redled { + + led-3 { label = "red:microSD"; gpios = <&gpx2 3 GPIO_ACTIVE_HIGH>; default-state = "off"; diff --git a/arch/arm/boot/dts/exynos54xx.dtsi b/arch/arm/boot/dts/exynos54xx.dtsi index 8aa5117e58ce..fe9d34c23374 100644 --- a/arch/arm/boot/dts/exynos54xx.dtsi +++ b/arch/arm/boot/dts/exynos54xx.dtsi @@ -101,7 +101,6 @@ reg = <0x12d10000 0x100>; interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; #io-channel-cells = <1>; - io-channel-ranges; status = "disabled"; }; @@ -148,7 +147,7 @@ #size-cells = <1>; ranges; - usbdrd_dwc3_0: dwc3@12000000 { + usbdrd_dwc3_0: usb@12000000 { compatible = "snps,dwc3"; reg = <0x12000000 0x10000>; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; @@ -170,7 +169,7 @@ #size-cells = <1>; ranges; - usbdrd_dwc3_1: dwc3@12400000 { + usbdrd_dwc3_1: usb@12400000 { compatible = "snps,dwc3"; reg = <0x12400000 0x10000>; phys = <&usbdrd_phy1 0>, <&usbdrd_phy1 1>; diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index 60ab0effe474..0ce3443d39a8 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -138,7 +138,7 @@ }; }; - mmc1_pwrseq: mmc1_pwrseq { + mmc1_pwrseq: mmc1-pwrseq { compatible = "mmc-pwrseq-simple"; reset-gpios = <&gpx0 0 GPIO_ACTIVE_LOW>; /* WIFI_EN */ clocks = <&max77802 MAX77802_CLK_32K_CP>; @@ -214,7 +214,7 @@ status = "okay"; clock-frequency = <400000>; - max77802: max77802-pmic@9 { + max77802: pmic@9 { compatible = "maxim,max77802"; interrupt-parent = <&gpx3>; interrupts = <1 IRQ_TYPE_NONE>; diff --git a/arch/arm/boot/dts/hi3519-demb.dts b/arch/arm/boot/dts/hi3519-demb.dts index 64f8ed126931..f473fa22e9ce 100644 --- a/arch/arm/boot/dts/hi3519-demb.dts +++ b/arch/arm/boot/dts/hi3519-demb.dts @@ -14,7 +14,7 @@ serial0 = &uart0; }; - memory { + memory@80000000 { device_type = "memory"; reg = <0x80000000 0x40000000>; }; diff --git a/arch/arm/boot/dts/hi3519.dtsi b/arch/arm/boot/dts/hi3519.dtsi index 410409a0ed66..c524c854d319 100644 --- a/arch/arm/boot/dts/hi3519.dtsi +++ b/arch/arm/boot/dts/hi3519.dtsi @@ -52,8 +52,8 @@ compatible = "arm,pl011", "arm,primecell"; reg = <0x12100000 0x1000>; interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_UART0_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_UART0_CLK>, <&crg HI3519_UART0_CLK>; + clock-names = "uartclk", "apb_pclk"; status = "disable"; }; @@ -61,8 +61,8 @@ compatible = "arm,pl011", "arm,primecell"; reg = <0x12101000 0x1000>; interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_UART1_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_UART1_CLK>, <&crg HI3519_UART1_CLK>; + clock-names = "uartclk", "apb_pclk"; status = "disable"; }; @@ -70,8 +70,8 @@ compatible = "arm,pl011", "arm,primecell"; reg = <0x12102000 0x1000>; interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_UART2_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_UART2_CLK>, <&crg HI3519_UART2_CLK>; + clock-names = "uartclk", "apb_pclk"; status = "disable"; }; @@ -79,8 +79,8 @@ compatible = "arm,pl011", "arm,primecell"; reg = <0x12103000 0x1000>; interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_UART3_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_UART3_CLK>, <&crg HI3519_UART3_CLK>; + clock-names = "uartclk", "apb_pclk"; status = "disable"; }; @@ -88,8 +88,8 @@ compatible = "arm,pl011", "arm,primecell"; reg = <0x12104000 0x1000>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_UART4_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_UART4_CLK>, <&crg HI3519_UART4_CLK>; + clock-names = "uartclk", "apb_pclk"; status = "disable"; }; @@ -127,8 +127,8 @@ compatible = "arm,pl022", "arm,primecell"; reg = <0x12120000 0x1000>; interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_SPI0_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_SPI0_CLK>, <&crg HI3519_SPI0_CLK>; + clock-names = "sspclk", "apb_pclk"; num-cs = <1>; #address-cells = <1>; #size-cells = <0>; @@ -139,8 +139,8 @@ compatible = "arm,pl022", "arm,primecell"; reg = <0x12121000 0x1000>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_SPI1_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_SPI1_CLK>, <&crg HI3519_SPI1_CLK>; + clock-names = "sspclk", "apb_pclk"; num-cs = <1>; #address-cells = <1>; #size-cells = <0>; @@ -151,8 +151,8 @@ compatible = "arm,pl022", "arm,primecell"; reg = <0x12122000 0x1000>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_SPI2_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_SPI2_CLK>, <&crg HI3519_SPI2_CLK>; + clock-names = "sspclk", "apb_pclk"; num-cs = <1>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/hi3620-hi4511.dts b/arch/arm/boot/dts/hi3620-hi4511.dts index 8c703c3f2fe0..ce356c469e1e 100644 --- a/arch/arm/boot/dts/hi3620-hi4511.dts +++ b/arch/arm/boot/dts/hi3620-hi4511.dts @@ -17,46 +17,46 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@40000000 { device_type = "memory"; reg = <0x40000000 0x20000000>; }; - amba { + amba-bus { dual_timer0: dual_timer@800000 { status = "ok"; }; - uart0: uart@b00000 { /* console */ - pinctrl-names = "default", "idle"; + uart0: serial@b00000 { /* console */ + pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart0_pmx_func &uart0_cfg_func>; pinctrl-1 = <&uart0_pmx_idle &uart0_cfg_idle>; status = "ok"; }; - uart1: uart@b01000 { /* modem */ - pinctrl-names = "default", "idle"; + uart1: serial@b01000 { /* modem */ + pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart1_pmx_func &uart1_cfg_func>; pinctrl-1 = <&uart1_pmx_idle &uart1_cfg_idle>; status = "ok"; }; - uart2: uart@b02000 { /* audience */ - pinctrl-names = "default", "idle"; + uart2: serial@b02000 { /* audience */ + pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart2_pmx_func &uart2_cfg_func>; pinctrl-1 = <&uart2_pmx_idle &uart2_cfg_idle>; status = "ok"; }; - uart3: uart@b03000 { - pinctrl-names = "default", "idle"; + uart3: serial@b03000 { + pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart3_pmx_func &uart3_cfg_func>; pinctrl-1 = <&uart3_pmx_idle &uart3_cfg_idle>; status = "ok"; }; - uart4: uart@b04000 { - pinctrl-names = "default", "idle"; + uart4: serial@b04000 { + pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart4_pmx_func &uart4_cfg_func>; pinctrl-1 = <&uart4_pmx_idle &uart4_cfg_func>; status = "ok"; diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi index f683440ee569..905900bf3e82 100644 --- a/arch/arm/boot/dts/hi3620.dtsi +++ b/arch/arm/boot/dts/hi3620.dtsi @@ -63,7 +63,7 @@ }; }; - amba { + amba-bus { #address-cells = <1>; #size-cells = <1>; @@ -172,48 +172,48 @@ interrupts = <1 13 0xf01>; }; - uart0: uart@b00000 { + uart0: serial@b00000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb00000 0x1000>; interrupts = <0 20 4>; - clocks = <&clock HI3620_UARTCLK0>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_UARTCLK0>, <&clock HI3620_UARTCLK0>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; }; - uart1: uart@b01000 { + uart1: serial@b01000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb01000 0x1000>; interrupts = <0 21 4>; - clocks = <&clock HI3620_UARTCLK1>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_UARTCLK1>, <&clock HI3620_UARTCLK1>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; }; - uart2: uart@b02000 { + uart2: serial@b02000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb02000 0x1000>; interrupts = <0 22 4>; - clocks = <&clock HI3620_UARTCLK2>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_UARTCLK2>, <&clock HI3620_UARTCLK2>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; }; - uart3: uart@b03000 { + uart3: serial@b03000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb03000 0x1000>; interrupts = <0 23 4>; - clocks = <&clock HI3620_UARTCLK3>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_UARTCLK3>, <&clock HI3620_UARTCLK3>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; }; - uart4: uart@b04000 { + uart4: serial@b04000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb04000 0x1000>; interrupts = <0 24 4>; - clocks = <&clock HI3620_UARTCLK4>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_UARTCLK4>, <&clock HI3620_UARTCLK4>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/hip01-ca9x2.dts b/arch/arm/boot/dts/hip01-ca9x2.dts index f05e74eacfe0..031476304d94 100644 --- a/arch/arm/boot/dts/hip01-ca9x2.dts +++ b/arch/arm/boot/dts/hip01-ca9x2.dts @@ -37,7 +37,7 @@ }; }; - memory { + memory@80000000 { device_type = "memory"; reg = <0x80000000 0x80000000>; }; diff --git a/arch/arm/boot/dts/hip01.dtsi b/arch/arm/boot/dts/hip01.dtsi index 975d39828405..2a7963605390 100644 --- a/arch/arm/boot/dts/hip01.dtsi +++ b/arch/arm/boot/dts/hip01.dtsi @@ -35,47 +35,47 @@ interrupt-parent = <&gic>; ranges = <0 0x10000000 0x20000000>; - amba { + amba-bus { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; ranges; - uart0: uart@10001000 { + uart0: serial@10001000 { compatible = "snps,dw-apb-uart"; reg = <0x10001000 0x1000>; - clocks = <&hisi_refclk144mhz>; - clock-names = "apb_pclk"; + clocks = <&hisi_refclk144mhz>, <&hisi_refclk144mhz>; + clock-names = "baudclk", "apb_pclk"; reg-shift = <2>; interrupts = <0 32 4>; status = "disabled"; }; - uart1: uart@10002000 { + uart1: serial@10002000 { compatible = "snps,dw-apb-uart"; reg = <0x10002000 0x1000>; - clocks = <&hisi_refclk144mhz>; - clock-names = "apb_pclk"; + clocks = <&hisi_refclk144mhz>, <&hisi_refclk144mhz>; + clock-names = "baudclk", "apb_pclk"; reg-shift = <2>; interrupts = <0 33 4>; status = "disabled"; }; - uart2: uart@10003000 { + uart2: serial@10003000 { compatible = "snps,dw-apb-uart"; reg = <0x10003000 0x1000>; - clocks = <&hisi_refclk144mhz>; - clock-names = "apb_pclk"; + clocks = <&hisi_refclk144mhz>, <&hisi_refclk144mhz>; + clock-names = "baudclk", "apb_pclk"; reg-shift = <2>; interrupts = <0 34 4>; status = "disabled"; }; - uart3: uart@10006000 { + uart3: serial@10006000 { compatible = "snps,dw-apb-uart"; reg = <0x10006000 0x1000>; - clocks = <&hisi_refclk144mhz>; - clock-names = "apb_pclk"; + clocks = <&hisi_refclk144mhz>, <&hisi_refclk144mhz>; + clock-names = "baudclk", "apb_pclk"; reg-shift = <2>; interrupts = <0 4 4>; status = "disabled"; diff --git a/arch/arm/boot/dts/hip04-d01.dts b/arch/arm/boot/dts/hip04-d01.dts index 9019e0d2ef60..f5691dbc26d2 100644 --- a/arch/arm/boot/dts/hip04-d01.dts +++ b/arch/arm/boot/dts/hip04-d01.dts @@ -22,7 +22,7 @@ }; soc { - uart0: uart@4007000 { + uart0: serial@4007000 { status = "ok"; }; }; diff --git a/arch/arm/boot/dts/hip04.dtsi b/arch/arm/boot/dts/hip04.dtsi index 555bc6b6720f..bccf5ba3d855 100644 --- a/arch/arm/boot/dts/hip04.dtsi +++ b/arch/arm/boot/dts/hip04.dtsi @@ -250,12 +250,12 @@ <0 79 4>; }; - uart0: uart@4007000 { + uart0: serial@4007000 { compatible = "snps,dw-apb-uart"; reg = <0x4007000 0x1000>; interrupts = <0 381 4>; - clocks = <&clk_168m>; - clock-names = "uartclk"; + clocks = <&clk_168m>, <&clk_168m>; + clock-names = "baudclk", "apb_pclk"; reg-shift = <2>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/hisi-x5hd2-dkb.dts b/arch/arm/boot/dts/hisi-x5hd2-dkb.dts index d55e9cd3b12b..22b122d3f514 100644 --- a/arch/arm/boot/dts/hisi-x5hd2-dkb.dts +++ b/arch/arm/boot/dts/hisi-x5hd2-dkb.dts @@ -35,7 +35,7 @@ }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x80000000>; }; diff --git a/arch/arm/boot/dts/hisi-x5hd2.dtsi b/arch/arm/boot/dts/hisi-x5hd2.dtsi index e2dbf1d8a67b..97211385dc89 100644 --- a/arch/arm/boot/dts/hisi-x5hd2.dtsi +++ b/arch/arm/boot/dts/hisi-x5hd2.dtsi @@ -30,7 +30,7 @@ interrupt-parent = <&gic>; ranges = <0 0xf8000000 0x8000000>; - amba { + amba-bus { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; @@ -86,48 +86,48 @@ status = "disabled"; }; - uart0: uart@b00000 { + uart0: serial@b00000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x00b00000 0x1000>; interrupts = <0 49 4>; - clocks = <&clock HIX5HD2_FIXED_83M>; - clock-names = "apb_pclk"; + clocks = <&clock HIX5HD2_FIXED_83M>, <&clock HIX5HD2_FIXED_83M>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; }; - uart1: uart@6000 { + uart1: serial@6000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x00006000 0x1000>; interrupts = <0 50 4>; - clocks = <&clock HIX5HD2_FIXED_83M>; - clock-names = "apb_pclk"; + clocks = <&clock HIX5HD2_FIXED_83M>, <&clock HIX5HD2_FIXED_83M>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; }; - uart2: uart@b02000 { + uart2: serial@b02000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x00b02000 0x1000>; interrupts = <0 51 4>; - clocks = <&clock HIX5HD2_FIXED_83M>; - clock-names = "apb_pclk"; + clocks = <&clock HIX5HD2_FIXED_83M>, <&clock HIX5HD2_FIXED_83M>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; }; - uart3: uart@b03000 { + uart3: serial@b03000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x00b03000 0x1000>; interrupts = <0 52 4>; - clocks = <&clock HIX5HD2_FIXED_83M>; - clock-names = "apb_pclk"; + clocks = <&clock HIX5HD2_FIXED_83M>, <&clock HIX5HD2_FIXED_83M>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; }; - uart4: uart@b04000 { + uart4: serial@b04000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb04000 0x1000>; interrupts = <0 53 4>; - clocks = <&clock HIX5HD2_FIXED_83M>; - clock-names = "apb_pclk"; + clocks = <&clock HIX5HD2_FIXED_83M>, <&clock HIX5HD2_FIXED_83M>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; }; @@ -423,7 +423,7 @@ interrupts = <0 35 4>; clocks = <&clock HIX5HD2_MMC_CIU_RST>, <&clock HIX5HD2_MMC_BIU_CLK>; - clock-names = "ciu", "biu"; + clock-names = "biu", "ciu"; }; sd: mmc@1820000 { @@ -432,7 +432,7 @@ interrupts = <0 34 4>; clocks = <&clock HIX5HD2_SD_CIU_RST>, <&clock HIX5HD2_SD_BIU_CLK>; - clock-names = "ciu","biu"; + clock-names = "biu", "ciu"; }; gmac0: ethernet@1840000 { @@ -453,14 +453,14 @@ status = "disabled"; }; - usb0: ehci@1890000 { + usb0: usb@1890000 { compatible = "generic-ehci"; reg = <0x1890000 0x1000>; interrupts = <0 66 4>; clocks = <&clock HIX5HD2_USB_CLK>; }; - usb1: ohci@1880000 { + usb1: usb@1880000 { compatible = "generic-ohci"; reg = <0x1880000 0x1000>; interrupts = <0 67 4>; @@ -468,7 +468,7 @@ }; peripheral_ctrl: syscon@a20000 { - compatible = "syscon"; + compatible = "hisilicon,peri-subctrl", "syscon"; reg = <0xa20000 0x1000>; }; diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi index 1ab19f1268f8..fdcca82c9986 100644 --- a/arch/arm/boot/dts/imx25.dtsi +++ b/arch/arm/boot/dts/imx25.dtsi @@ -525,7 +525,7 @@ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx25.bin"; }; - wdog@53fdc000 { + watchdog@53fdc000 { compatible = "fsl,imx25-wdt", "fsl,imx21-wdt"; reg = <0x53fdc000 0x4000>; clocks = <&clks 126>; diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi index 7bc132737a37..fd525c3b16fa 100644 --- a/arch/arm/boot/dts/imx27.dtsi +++ b/arch/arm/boot/dts/imx27.dtsi @@ -99,7 +99,7 @@ #dma-channels = <16>; }; - wdog: wdog@10002000 { + wdog: watchdog@10002000 { compatible = "fsl,imx27-wdt", "fsl,imx21-wdt"; reg = <0x10002000 0x1000>; interrupts = <27>; diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi index 94dfbf5b3f34..bbe52150b165 100644 --- a/arch/arm/boot/dts/imx28.dtsi +++ b/arch/arm/boot/dts/imx28.dtsi @@ -1317,7 +1317,7 @@ status = "disabled"; }; - etn_switch: switch@800f8000 { + eth_switch: switch@800f8000 { reg = <0x800f8000 0x8000>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx31.dtsi b/arch/arm/boot/dts/imx31.dtsi index 45333f7e10ea..948d2a543f8d 100644 --- a/arch/arm/boot/dts/imx31.dtsi +++ b/arch/arm/boot/dts/imx31.dtsi @@ -315,10 +315,11 @@ clock-names = "ref", "ipg"; }; - wdog: wdog@53fdc000 { + wdog: watchdog@53fdc000 { compatible = "fsl,imx31-wdt", "fsl,imx21-wdt"; reg = <0x53fdc000 0x4000>; clocks = <&clks 41>; + interrupts = <55>; }; pwm: pwm@53fe0000 { diff --git a/arch/arm/boot/dts/imx35.dtsi b/arch/arm/boot/dts/imx35.dtsi index aba16252faab..98ccc81ca6d9 100644 --- a/arch/arm/boot/dts/imx35.dtsi +++ b/arch/arm/boot/dts/imx35.dtsi @@ -294,7 +294,7 @@ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx35.bin"; }; - wdog: wdog@53fdc000 { + wdog: watchdog@53fdc000 { compatible = "fsl,imx35-wdt", "fsl,imx21-wdt"; reg = <0x53fdc000 0x4000>; clocks = <&clks 74>; diff --git a/arch/arm/boot/dts/imx50-kobo-aura.dts b/arch/arm/boot/dts/imx50-kobo-aura.dts index a0eaf869b913..97cfd970fe74 100644 --- a/arch/arm/boot/dts/imx50-kobo-aura.dts +++ b/arch/arm/boot/dts/imx50-kobo-aura.dts @@ -6,6 +6,7 @@ /dts-v1/; #include "imx50.dtsi" #include <dt-bindings/input/input.h> +#include <dt-bindings/interrupt-controller/irq.h> / { model = "Kobo Aura (N514)"; @@ -119,7 +120,14 @@ pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; - /* TODO: ektf2132 touch controller at 0x15 */ + touchscreen@15 { + reg = <0x15>; + compatible = "elan,ektf2132"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ts>; + power-gpios = <&gpio4 9 GPIO_ACTIVE_HIGH>; + interrupts-extended = <&gpio5 13 IRQ_TYPE_EDGE_FALLING>; + }; }; &i2c2 { @@ -139,7 +147,7 @@ }; &iomuxc { - pinctrl_gpiokeys: gpiokeys { + pinctrl_gpiokeys: gpiokeysgrp { fsl,pins = < MX50_PAD_CSPI_MISO__GPIO4_10 0x0 MX50_PAD_SD2_D7__GPIO5_15 0x0 @@ -147,34 +155,34 @@ >; }; - pinctrl_i2c1: i2c1 { + pinctrl_i2c1: i2c1grp { fsl,pins = < MX50_PAD_I2C1_SCL__I2C1_SCL 0x400001fd MX50_PAD_I2C1_SDA__I2C1_SDA 0x400001fd >; }; - pinctrl_i2c2: i2c2 { + pinctrl_i2c2: i2c2grp { fsl,pins = < MX50_PAD_I2C2_SCL__I2C2_SCL 0x400001fd MX50_PAD_I2C2_SDA__I2C2_SDA 0x400001fd >; }; - pinctrl_i2c3: i2c3 { + pinctrl_i2c3: i2c3grp { fsl,pins = < MX50_PAD_I2C3_SCL__I2C3_SCL 0x400001fd MX50_PAD_I2C3_SDA__I2C3_SDA 0x400001fd >; }; - pinctrl_leds: leds { + pinctrl_leds: ledsgrp { fsl,pins = < MX50_PAD_PWM1__GPIO6_24 0x0 >; }; - pinctrl_sd1: sd1 { + pinctrl_sd1: sd1grp { fsl,pins = < MX50_PAD_SD1_CMD__ESDHC1_CMD 0x1e4 MX50_PAD_SD1_CLK__ESDHC1_CLK 0xd4 @@ -187,7 +195,7 @@ >; }; - pinctrl_sd2: sd2 { + pinctrl_sd2: sd2grp { fsl,pins = < MX50_PAD_SD2_CMD__ESDHC2_CMD 0x1e4 MX50_PAD_SD2_CLK__ESDHC2_CLK 0xd4 @@ -198,19 +206,19 @@ >; }; - pinctrl_sd2_reset: sd2-reset { + pinctrl_sd2_reset: sd2-resetgrp { fsl,pins = < MX50_PAD_ECSPI2_MOSI__GPIO4_17 0x0 >; }; - pinctrl_sd2_vmmc: sd2-vmmc { + pinctrl_sd2_vmmc: sd2-vmmcgrp { fsl,pins = < MX50_PAD_ECSPI1_SCLK__GPIO4_12 0x0 >; }; - pinctrl_sd3: sd3 { + pinctrl_sd3: sd3grp { fsl,pins = < MX50_PAD_SD3_CMD__ESDHC3_CMD 0x1e4 MX50_PAD_SD3_CLK__ESDHC3_CLK 0xd4 @@ -225,14 +233,21 @@ >; }; - pinctrl_uart2: uart2 { + pinctrl_ts: tsgrp { + fsl,pins = < + MX50_PAD_CSPI_MOSI__GPIO4_9 0x0 + MX50_PAD_SD2_D5__GPIO5_13 0x0 + >; + }; + + pinctrl_uart2: uart2grp { fsl,pins = < MX50_PAD_UART2_TXD__UART2_TXD_MUX 0x1e4 MX50_PAD_UART2_RXD__UART2_RXD_MUX 0x1e4 >; }; - pinctrl_usbphy: usbphy { + pinctrl_usbphy: usbphygrp { fsl,pins = < MX50_PAD_ECSPI2_SS0__GPIO4_19 0x0 >; diff --git a/arch/arm/boot/dts/imx50.dtsi b/arch/arm/boot/dts/imx50.dtsi index b6b2e6af9b96..a969f335b240 100644 --- a/arch/arm/boot/dts/imx50.dtsi +++ b/arch/arm/boot/dts/imx50.dtsi @@ -267,7 +267,7 @@ <&iomuxc 20 140 11>; }; - wdog1: wdog@53f98000 { + wdog1: watchdog@53f98000 { compatible = "fsl,imx50-wdt", "fsl,imx21-wdt"; reg = <0x53f98000 0x4000>; interrupts = <58>; diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts b/arch/arm/boot/dts/imx51-zii-rdu1.dts index e559ab0c3645..ec8ca3ac2c1c 100644 --- a/arch/arm/boot/dts/imx51-zii-rdu1.dts +++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts @@ -451,7 +451,7 @@ "", "", "", "", "", "", "", ""; - unused-sd3-wp-gpio { + unused-sd3-wp-hog { /* * See pinctrl_esdhc1 below for more details on this */ diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index 985e1be03ad6..7ebb46ce9e36 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi @@ -370,14 +370,14 @@ status = "disabled"; }; - wdog1: wdog@73f98000 { + wdog1: watchdog@73f98000 { compatible = "fsl,imx51-wdt", "fsl,imx21-wdt"; reg = <0x73f98000 0x4000>; interrupts = <58>; clocks = <&clks IMX5_CLK_DUMMY>; }; - wdog2: wdog@73f9c000 { + wdog2: watchdog@73f9c000 { compatible = "fsl,imx51-wdt", "fsl,imx21-wdt"; reg = <0x73f9c000 0x4000>; interrupts = <59>; diff --git a/arch/arm/boot/dts/imx53-ppd.dts b/arch/arm/boot/dts/imx53-ppd.dts index 8f4a63ea912e..be040b6a02fa 100644 --- a/arch/arm/boot/dts/imx53-ppd.dts +++ b/arch/arm/boot/dts/imx53-ppd.dts @@ -176,36 +176,37 @@ power-supply = <®_3v3_lcd>; }; - leds-brightness { + led-controller-1 { compatible = "pwm-leds"; - alarm-brightness { + led-1 { + label = "alarm-brightness"; pwms = <&pwm1 0 100000>; max-brightness = <255>; }; }; - leds { + led-controller-2 { compatible = "gpio-leds"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_alarmled_pins>; - alarm1 { + led-2 { label = "alarm:red"; gpios = <&gpio7 3 GPIO_ACTIVE_HIGH>; }; - alarm2 { + led-3 { label = "alarm:yellow"; gpios = <&gpio7 7 GPIO_ACTIVE_HIGH>; }; - alarm3 { + led-4 { label = "alarm:blue"; gpios = <&gpio7 8 GPIO_ACTIVE_HIGH>; }; - alarm4 { + led-5 { label = "alarm:silenced"; gpios = <&gpio7 13 GPIO_ACTIVE_HIGH>; }; diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 500eeaa3a27c..000050aeeabe 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -427,14 +427,14 @@ status = "disabled"; }; - wdog1: wdog@53f98000 { + wdog1: watchdog@53f98000 { compatible = "fsl,imx53-wdt", "fsl,imx21-wdt"; reg = <0x53f98000 0x4000>; interrupts = <58>; clocks = <&clks IMX5_CLK_DUMMY>; }; - wdog2: wdog@53f9c000 { + wdog2: watchdog@53f9c000 { compatible = "fsl,imx53-wdt", "fsl,imx21-wdt"; reg = <0x53f9c000 0x4000>; interrupts = <59>; diff --git a/arch/arm/boot/dts/imx6dl-alti6p.dts b/arch/arm/boot/dts/imx6dl-alti6p.dts new file mode 100644 index 000000000000..4329b372d8cb --- /dev/null +++ b/arch/arm/boot/dts/imx6dl-alti6p.dts @@ -0,0 +1,564 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (c) 2016 Protonic Holland + * Copyright (c) 2020 Oleksij Rempel <kernel@pengutronix.de>, Pengutronix + */ + +/dts-v1/; +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/sound/fsl-imx-audmux.h> +#include "imx6dl.dtsi" + +/ { + model = "Altesco I6P Board"; + compatible = "alt,alti6p", "fsl,imx6dl"; + + chosen { + stdout-path = &uart4; + }; + + clock_ksz8081: clock-ksz8081 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + + i2c2-mux { + compatible = "i2c-mux"; + i2c-parent = <&i2c2>; + mux-controls = <&i2c_mux>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + i2c4-mux { + compatible = "i2c-mux"; + i2c-parent = <&i2c4>; + mux-controls = <&i2c_mux>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_leds>; + + led-debug0 { + function = LED_FUNCTION_STATUS; + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + + led-debug1 { + function = LED_FUNCTION_SD; + gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "disk-activity"; + }; + }; + + i2c_mux: mux-controller { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2cmux>; + + mux-gpios = <&gpio5 10 GPIO_ACTIVE_HIGH>, + <&gpio5 11 GPIO_ACTIVE_HIGH>; + }; + + reg_1v8: regulator-1v8 { + compatible = "regulator-fixed"; + regulator-name = "1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_5v0: regulator-5v0 { + compatible = "regulator-fixed"; + regulator-name = "5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_h1_vbus: regulator-h1-vbus { + compatible = "regulator-fixed"; + regulator-name = "h1-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio1 0 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_otg_vbus: regulator-otg-vbus { + compatible = "regulator-fixed"; + regulator-name = "otg-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "prti6q-sgtl5000"; + simple-audio-card,format = "i2s"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Line", "Line In Jack", + "Headphone", "Headphone Jack", + "Speaker", "External Speaker"; + simple-audio-card,routing = + "MIC_IN", "Microphone Jack", + "LINE_IN", "Line In Jack", + "Headphone Jack", "HP_OUT", + "External Speaker", "LINE_OUT"; + + simple-audio-card,cpu { + sound-dai = <&ssi1>; + system-clock-frequency = <0>; + }; + + simple-audio-card,codec { + sound-dai = <&sgtl5000>; + bitclock-master; + frame-master; + }; + }; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; + + mux-ssi1 { + fsl,audmux-port = <0>; + fsl,port-config = < + IMX_AUDMUX_V2_PTCR_SYN 0 + IMX_AUDMUX_V2_PTCR_TFSEL(2) 0 + IMX_AUDMUX_V2_PTCR_TCSEL(2) 0 + IMX_AUDMUX_V2_PTCR_TFSDIR 0 + IMX_AUDMUX_V2_PTCR_TCLKDIR IMX_AUDMUX_V2_PDCR_RXDSEL(2) + >; + }; + + mux-pins3 { + fsl,audmux-port = <2>; + fsl,port-config = < + IMX_AUDMUX_V2_PTCR_SYN IMX_AUDMUX_V2_PDCR_RXDSEL(0) + 0 IMX_AUDMUX_V2_PDCR_TXRXEN + >; + }; +}; + +&can1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can1>; + xceiver-supply = <®_5v0>; + status = "okay"; +}; + +&ecspi1 { + cs-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <20000000>; + }; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rmii"; + clocks = <&clks IMX6QDL_CLK_ENET>, + <&clks IMX6QDL_CLK_ENET>, + <&clock_ksz8081>; + clock-names = "ipg", "ahb", "ptp"; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + /* Microchip KSZ8081RNA PHY */ + rgmii_phy: ethernet-phy@0 { + reg = <0>; + interrupts-extended = <&gpio4 30 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&gpio4 26 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <300>; + }; + }; +}; + +&gpio1 { + gpio-line-names = + "", "SD1_CD", "", "USB_H1_OC", "", "", "", "", + "DEBUG_0", "DEBUG_1", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio3 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "ECSPI1_SS1", "", "USB_EXT1_OC", "USB_EXT1_PWR", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio4 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "ETH_RESET", "", "", "BUZZER", "ETH_INTRP", ""; +}; + +&gpio5 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "", "", "I2C_EN13", "I2C_EN24", "", "", "", "", + "", "", "", "", "", "AUDIO_RESET", "", "", + "", "", "", "", "", "", "", ""; +}; + +&hdmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hdmi>; + ddc-i2c-bus = <&i2c1>; + status = "okay"; +}; + +/* DDC */ +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + sgtl5000: audio-codec@a { + compatible = "fsl,sgtl5000"; + reg = <0xa>; + #sound-dai-cells = <0>; + clocks = <&clks 201>; + VDDA-supply = <®_3v3>; + VDDIO-supply = <®_3v3>; + VDDD-supply = <®_1v8>; + }; + + /* additional i2c devices are added automatically by the boot loader */ +}; + +&i2c2 { + clock-frequency = <50000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + /* external interface, device are configured from user space */ +}; + +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; + + temperature-sensor@70 { + compatible = "ti,tmp103"; + reg = <0x70>; + }; +}; + +&i2c4 { + clock-frequency = <50000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4>; + status = "okay"; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm1>; + status = "okay"; +}; + +&ssi1 { + #sound-dai-cells = <0>; + fsl,mode = "ac97-slave"; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +&uart5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart5>; + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_h1_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1>; + phy_type = "utmi"; + dr_mode = "host"; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + phy_type = "utmi"; + dr_mode = "host"; + status = "okay"; +}; + +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + cd-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; + no-1-8-v; + disable-wp; + cap-sd-highspeed; + no-mmc; + no-sdio; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3>; + bus-width = <8>; + no-1-8-v; + non-removable; + no-sd; + no-sdio; + status = "okay"; +}; + +&iomuxc { + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6QDL_PAD_CSI0_MCLK__CCM_CLKO1 0x030b0 + MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0 + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0 + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0 + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0 + >; + }; + + pinctrl_can1: can1grp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b000 + MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x3008 + >; + }; + + pinctrl_ecspi1: ecspi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x1b000 + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x3008 + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x3008 + /* CS */ + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x3008 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + /* MX6QDL_ENET_PINGRP4 */ + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1b0b0 + MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1b0b0 + MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1b0b0 + MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0 + MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1b0b0 + MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1b0b0 + MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1b0b0 + + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x1b0b0 + /* Phy reset */ + MX6QDL_PAD_DISP0_DAT5__GPIO4_IO26 0x1b0b0 + /* nINTRP */ + MX6QDL_PAD_DISP0_DAT9__GPIO4_IO30 0x1b0b0 + >; + }; + + pinctrl_hdmi: hdmigrp { + fsl,pins = < + /* NOTE: DDC is done via I2C2, so DON'T configure DDC + * pins for HDMI! + */ + MX6QDL_PAD_EIM_A25__HDMI_TX_CEC_LINE 0x1f8b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001f8b1 + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001f8b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c4: i2c4grp { + fsl,pins = < + MX6QDL_PAD_NANDF_CS3__I2C4_SDA 0x4001f8b1 + MX6QDL_PAD_NANDF_WP_B__I2C4_SCL 0x4001f8b1 + >; + }; + + pinctrl_i2cmux: i2cmuxgrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT16__GPIO5_IO10 0x1b0b0 + MX6QDL_PAD_DISP0_DAT17__GPIO5_IO11 0x1b0b0 + >; + }; + + pinctrl_leds: ledsgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x1b0b0 + MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x1b0b0 + >; + }; + + pinctrl_pwm1: pwm1grp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x8 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_uart5: uart5grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_usbh1: usbh1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_3__USB_H1_OC 0x1B058 + MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1B058 + + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_EIM_D21__USB_OTG_OC 0x1b0b0 + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x170f9 + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x100f9 + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x170f9 + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x170f9 + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x170f9 + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x170f9 + MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x1b0b0 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17099 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10099 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17099 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17099 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17099 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17099 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17099 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17099 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17099 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17099 + MX6QDL_PAD_SD3_RST__SD3_RESET 0x1b0b1 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6dl-aristainetos2_4.dts b/arch/arm/boot/dts/imx6dl-aristainetos2_4.dts index b16603f27dce..dfa6f64d43cc 100644 --- a/arch/arm/boot/dts/imx6dl-aristainetos2_4.dts +++ b/arch/arm/boot/dts/imx6dl-aristainetos2_4.dts @@ -46,7 +46,7 @@ / { model = "aristainetos2 i.MX6 Dual Lite Board 4"; - compatible = "fsl,imx6dl"; + compatible = "abb,aristainetos2-imx6dl-4", "fsl,imx6dl"; memory@10000000 { device_type = "memory"; diff --git a/arch/arm/boot/dts/imx6dl-aristainetos2_7.dts b/arch/arm/boot/dts/imx6dl-aristainetos2_7.dts index abb2a1b9ce08..5e15212eaf3a 100644 --- a/arch/arm/boot/dts/imx6dl-aristainetos2_7.dts +++ b/arch/arm/boot/dts/imx6dl-aristainetos2_7.dts @@ -46,7 +46,7 @@ / { model = "aristainetos2 i.MX6 Dual Lite Board 7"; - compatible = "fsl,imx6dl"; + compatible = "abb,aristainetos2-imx6dl-7", "fsl,imx6dl"; memory@10000000 { device_type = "memory"; diff --git a/arch/arm/boot/dts/imx6dl-aristainetos_4.dts b/arch/arm/boot/dts/imx6dl-aristainetos_4.dts index 5c7e85300695..cc861a43eb58 100644 --- a/arch/arm/boot/dts/imx6dl-aristainetos_4.dts +++ b/arch/arm/boot/dts/imx6dl-aristainetos_4.dts @@ -10,7 +10,7 @@ / { model = "aristainetos i.MX6 Dual Lite Board 4"; - compatible = "fsl,imx6dl"; + compatible = "abb,aristainetos-imx6dl-4", "fsl,imx6dl"; backlight { compatible = "pwm-backlight"; diff --git a/arch/arm/boot/dts/imx6dl-aristainetos_7.dts b/arch/arm/boot/dts/imx6dl-aristainetos_7.dts index 4d58cb4436d9..b6cb78870cd5 100644 --- a/arch/arm/boot/dts/imx6dl-aristainetos_7.dts +++ b/arch/arm/boot/dts/imx6dl-aristainetos_7.dts @@ -10,7 +10,7 @@ / { model = "aristainetos i.MX6 Dual Lite Board 7"; - compatible = "fsl,imx6dl"; + compatible = "abb,aristainetos-imx6dl-7", "fsl,imx6dl"; memory@10000000 { device_type = "memory"; diff --git a/arch/arm/boot/dts/imx6dl-lanmcu.dts b/arch/arm/boot/dts/imx6dl-lanmcu.dts new file mode 100644 index 000000000000..6b6e6fcdea9c --- /dev/null +++ b/arch/arm/boot/dts/imx6dl-lanmcu.dts @@ -0,0 +1,470 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2019 Protonic Holland + * Copyright (c) 2020 Oleksij Rempel <kernel@pengutronix.de>, Pengutronix + */ + +/dts-v1/; +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/leds/common.h> +#include "imx6dl.dtsi" + +/ { + model = "Van der Laan LANMCU"; + compatible = "vdl,lanmcu", "fsl,imx6dl"; + + chosen { + stdout-path = &uart4; + }; + + clock_ksz8081: clock-ksz8081 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 5000000 0>; + brightness-levels = <0 1000>; + num-interpolated-steps = <20>; + default-brightness-level = <19>; + }; + + display { + compatible = "fsl,imx-parallel-display"; + pinctrl-0 = <&pinctrl_ipu1_disp>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + display_in: endpoint { + remote-endpoint = <&ipu1_di0_disp0>; + }; + }; + + port@1 { + reg = <1>; + + display_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_leds>; + + led-0 { + label = "debug0"; + function = LED_FUNCTION_STATUS; + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + panel { + compatible = "edt,etm0700g0bdh6"; + backlight = <&backlight>; + + port { + panel_in: endpoint { + remote-endpoint = <&display_out>; + }; + }; + }; + + reg_otg_vbus: regulator-otg-vbus { + compatible = "regulator-fixed"; + regulator-name = "otg-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + usdhc2_wifi_pwrseq: usdhc2-wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wifi_npd>; + reset-gpios = <&gpio6 10 GPIO_ACTIVE_LOW>; + }; + +}; + +&can1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can1>; + status = "okay"; +}; + +&can2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can2>; + status = "okay"; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rmii"; + clocks = <&clks IMX6QDL_CLK_ENET>, + <&clks IMX6QDL_CLK_ENET>, + <&clock_ksz8081>; + clock-names = "ipg", "ahb", "ptp"; + phy-handle = <&rgmii_phy>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + /* Microchip KSZ8081RNA PHY */ + rgmii_phy: ethernet-phy@0 { + reg = <0>; + interrupts-extended = <&gpio5 23 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&gpio5 22 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <300>; + }; + }; +}; + +&gpio1 { + gpio-line-names = + "", "SD1_CD", "", "", "", "", "", "", + "DEBUG_0", "BL_PWM", "", "", "", "", "", "", + "", "", "", "", "", "", "", "ENET_LED_GREEN", + "", "", "", "", "", "", "", ""; +}; + +&gpio3 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "TS_INT", "USB_OTG1_OC", "USB_OTG1_PWR", "", + "", "", "", "", "UART2_CTS", "", "UART3_CTS", ""; +}; + +&gpio5 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "ENET_RST", "ENET_INT", + "", "", "I2C1_SDA", "I2C1_SCL", "", "", "", ""; +}; + +&gpio6 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "", "", "WLAN_REG_ON", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio7 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "EMMC_RST", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + /* additional i2c devices are added automatically by the boot loader */ +}; + +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + touchscreen@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ts_edt>; + interrupts-extended = <&gpio3 20 IRQ_TYPE_EDGE_FALLING>; + + touchscreen-size-x = <1792>; + touchscreen-size-y = <1024>; + + touchscreen-fuzz-x = <0>; + touchscreen-fuzz-y = <0>; + + /* Touch screen calibration */ + threshold = <50>; + gain = <5>; + offset = <10>; + }; + + rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; +}; + +&ipu1_di0_disp0 { + remote-endpoint = <&display_in>; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm1>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + linux,rs485-enabled-at-boot-time; + uart-has-rtscts; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + linux,rs485-enabled-at-boot-time; + uart-has-rtscts; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + phy_type = "utmi"; + dr_mode = "host"; + status = "okay"; +}; + +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + cd-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; + no-1-8-v; + disable-wp; + cap-sd-highspeed; + no-mmc; + no-sdio; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + no-1-8-v; + non-removable; + mmc-pwrseq = <&usdhc2_wifi_pwrseq>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wifi@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + }; +}; + +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3>; + bus-width = <8>; + no-1-8-v; + non-removable; + no-sd; + no-sdio; + status = "okay"; +}; + +&iomuxc { + pinctrl_can1: can1grp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b000 + MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x3008 + >; + }; + + pinctrl_can2: can2grp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x1b000 + MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x3008 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + /* MX6QDL_ENET_PINGRP4 */ + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1b0b0 + MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1b0b0 + MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1b0b0 + MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0 + MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1b0b0 + MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1b0b0 + MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1b0b0 + + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x1b0b0 + /* Phy reset */ + MX6QDL_PAD_CSI0_DAT4__GPIO5_IO22 0x1b0b0 + /* nINTRP */ + MX6QDL_PAD_CSI0_DAT5__GPIO5_IO23 0x1b0b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001f8b1 + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001f8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 + >; + }; + + pinctrl_ipu1_disp: ipudisp1grp { + fsl,pins = < + /* DSE 0x30 => 25 Ohm, 0x20 => 37 Ohm, 0x10 => 75 Ohm */ + MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x30 + MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x30 + MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x30 + MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x30 + MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x30 + MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x30 + MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x30 + MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x30 + MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x30 + MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x30 + MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x30 + MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x30 + MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x30 + MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x30 + MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x30 + MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x30 + MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x30 + MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x30 + MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x30 + MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x30 + MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x30 + MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x30 + >; + }; + + pinctrl_leds: ledsgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x1b0b0 + >; + }; + + pinctrl_pwm1: pwm1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_9__PWM1_OUT 0x8 + >; + }; + + pinctrl_ts_edt: ts1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x1b0b0 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX6QDL_PAD_EIM_D26__UART2_RX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D27__UART2_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D28__UART2_CTS_B 0x130b1 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x130b1 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_EIM_D21__USB_OTG_OC 0x1b0b0 + /* power enable, high active */ + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x170f9 + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x100f9 + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x170f9 + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x170f9 + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x170f9 + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x170f9 + MX6QDL_PAD_GPIO_1__SD1_CD_B 0x1b0b0 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170b9 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100b9 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170b9 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170b9 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170b9 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x170b9 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17099 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10099 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17099 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17099 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17099 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17099 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17099 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17099 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17099 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17099 + MX6QDL_PAD_SD3_RST__SD3_RESET 0x1b0b1 + >; + }; + + pinctrl_wifi_npd: wifigrp { + fsl,pins = < + /* WL_REG_ON */ + MX6QDL_PAD_NANDF_RB0__GPIO6_IO10 0x13069 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6dl-pico-dwarf.dts b/arch/arm/boot/dts/imx6dl-pico-dwarf.dts index 659a8e8714ea..d85b15a8c127 100644 --- a/arch/arm/boot/dts/imx6dl-pico-dwarf.dts +++ b/arch/arm/boot/dts/imx6dl-pico-dwarf.dts @@ -13,5 +13,5 @@ / { model = "TechNexion PICO-IMX6 DualLite/Solo Board and Dwarf baseboard"; - compatible = "technexion,imx6dl-pico", "fsl,imx6dl"; + compatible = "technexion,imx6dl-pico-dwarf", "fsl,imx6dl"; }; diff --git a/arch/arm/boot/dts/imx6dl-pico-hobbit.dts b/arch/arm/boot/dts/imx6dl-pico-hobbit.dts index d7403c5c4337..08fedcbcc91b 100644 --- a/arch/arm/boot/dts/imx6dl-pico-hobbit.dts +++ b/arch/arm/boot/dts/imx6dl-pico-hobbit.dts @@ -13,5 +13,5 @@ / { model = "TechNexion PICO-IMX6 DualLite/Solo Board and Hobbit baseboard"; - compatible = "technexion,imx6dl-pico", "fsl,imx6dl"; + compatible = "technexion,imx6dl-pico-hobbit", "fsl,imx6dl"; }; diff --git a/arch/arm/boot/dts/imx6dl-pico-nymph.dts b/arch/arm/boot/dts/imx6dl-pico-nymph.dts index b282dbf953aa..32ccfc5d41ce 100644 --- a/arch/arm/boot/dts/imx6dl-pico-nymph.dts +++ b/arch/arm/boot/dts/imx6dl-pico-nymph.dts @@ -13,5 +13,5 @@ / { model = "TechNexion PICO-IMX6 DualLite/Solo Board and Nymph baseboard"; - compatible = "technexion,imx6dl-pico", "fsl,imx6dl"; + compatible = "technexion,imx6dl-pico-nymph", "fsl,imx6dl"; }; diff --git a/arch/arm/boot/dts/imx6dl-pico-pi.dts b/arch/arm/boot/dts/imx6dl-pico-pi.dts index b7b1c07f96f3..4590e8ad9a91 100644 --- a/arch/arm/boot/dts/imx6dl-pico-pi.dts +++ b/arch/arm/boot/dts/imx6dl-pico-pi.dts @@ -13,5 +13,5 @@ / { model = "TechNexion PICO-IMX6 DualLite/Solo Board and PI baseboard"; - compatible = "technexion,imx6dl-pico", "fsl,imx6dl"; + compatible = "technexion,imx6dl-pico-pi", "fsl,imx6dl"; }; diff --git a/arch/arm/boot/dts/imx6q-icore-ofcap10.dts b/arch/arm/boot/dts/imx6q-icore-ofcap10.dts index 81cc346dd149..02aca1e28ce3 100644 --- a/arch/arm/boot/dts/imx6q-icore-ofcap10.dts +++ b/arch/arm/boot/dts/imx6q-icore-ofcap10.dts @@ -12,6 +12,17 @@ / { model = "Engicam i.CoreM6 Quad/Dual OpenFrame Capacitive touch 10.1 Kit"; compatible = "engicam,imx6-icore", "fsl,imx6q"; + + panel { + compatible = "ampire,am-1280800n3tzqw-t00h"; + backlight = <&backlight_lvds>; + + port { + panel_in: endpoint { + remote-endpoint = <&lvds0_out>; + }; + }; + }; }; &ldb { @@ -22,18 +33,11 @@ fsl,data-width = <24>; status = "okay"; - display-timings { - native-mode = <&timing0>; - timing0: timing0 { - clock-frequency = <60000000>; - hactive = <1280>; - vactive = <800>; - hback-porch = <40>; - hfront-porch = <40>; - vback-porch = <10>; - vfront-porch = <3>; - hsync-len = <80>; - vsync-len = <10>; + port@4 { + reg = <4>; + + lvds0_out: endpoint { + remote-endpoint = <&panel_in>; }; }; }; diff --git a/arch/arm/boot/dts/imx6q-pico-dwarf.dts b/arch/arm/boot/dts/imx6q-pico-dwarf.dts index 618d2743e1e9..479a63ed42af 100644 --- a/arch/arm/boot/dts/imx6q-pico-dwarf.dts +++ b/arch/arm/boot/dts/imx6q-pico-dwarf.dts @@ -13,5 +13,5 @@ / { model = "TechNexion PICO-IMX6 Quad Board and Dwarf baseboard"; - compatible = "technexion,imx6q-pico", "fsl,imx6q"; + compatible = "technexion,imx6q-pico-dwarf", "fsl,imx6q"; }; diff --git a/arch/arm/boot/dts/imx6q-pico-hobbit.dts b/arch/arm/boot/dts/imx6q-pico-hobbit.dts index 7a666507b456..b767131068f5 100644 --- a/arch/arm/boot/dts/imx6q-pico-hobbit.dts +++ b/arch/arm/boot/dts/imx6q-pico-hobbit.dts @@ -13,5 +13,5 @@ / { model = "TechNexion PICO-IMX6 Quad Board and Hobbit baseboard"; - compatible = "technexion,imx6q-pico", "fsl,imx6q"; + compatible = "technexion,imx6q-pico-hobbit", "fsl,imx6q"; }; diff --git a/arch/arm/boot/dts/imx6q-pico-nymph.dts b/arch/arm/boot/dts/imx6q-pico-nymph.dts index fe5a7becc9e5..e8ad4c12b263 100644 --- a/arch/arm/boot/dts/imx6q-pico-nymph.dts +++ b/arch/arm/boot/dts/imx6q-pico-nymph.dts @@ -13,5 +13,5 @@ / { model = "TechNexion PICO-IMX6 Quad Board and Nymph baseboard"; - compatible = "technexion,imx6q-pico", "fsl,imx6q"; + compatible = "technexion,imx6q-pico-nymph", "fsl,imx6q"; }; diff --git a/arch/arm/boot/dts/imx6q-pico-pi.dts b/arch/arm/boot/dts/imx6q-pico-pi.dts index 9413f0a68f54..cc2394ddad6c 100644 --- a/arch/arm/boot/dts/imx6q-pico-pi.dts +++ b/arch/arm/boot/dts/imx6q-pico-pi.dts @@ -13,5 +13,5 @@ / { model = "TechNexion PICO-IMX6 Quad Board and PI baseboard"; - compatible = "technexion,imx6q-pico", "fsl,imx6q"; + compatible = "technexion,imx6q-pico-pi", "fsl,imx6q"; }; diff --git a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi index 67042793b0ca..1e530d892b76 100644 --- a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi +++ b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi @@ -55,12 +55,12 @@ pinctrl-0 = <&pinctrl_cubox_i_ir>; }; - pwmleds { + led-controller { compatible = "pwm-leds"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_cubox_i_pwm1>; - front { + led-1 { active-low; label = "imx6:red:front"; max-brightness = <248>; diff --git a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi index 24f793ca2886..d6df598bd1c2 100644 --- a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi +++ b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi @@ -390,21 +390,21 @@ /* I2C_GP */ &i2c1 { - clock-frequency = <100000>; + clock-frequency = <375000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1>; }; /* HDMI_CTRL */ &i2c2 { - clock-frequency = <100000>; + clock-frequency = <375000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; }; /* I2C_PM */ &i2c3 { - clock-frequency = <100000>; + clock-frequency = <375000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c3>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index e361df26a168..7a1e53195785 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -116,7 +116,8 @@ status = "okay"; som_eeprom: eeprom@50 { - compatible = "atmel,24c32"; + compatible = "catalyst,24c32", "atmel,24c32"; + pagesize = <32>; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi index 41ebe4599e43..a80aa08a37cb 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi @@ -84,7 +84,8 @@ status = "okay"; eeprom@50 { - compatible = "atmel,24c32"; + compatible = "st,24c32", "atmel,24c32"; + pagesize = <32>; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi b/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi index 66b15748e287..c0a76202e16b 100644 --- a/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi +++ b/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi @@ -330,28 +330,28 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpio3_hog>; - usb-emulation { + usb-emulation-hog { gpio-hog; gpios = <19 GPIO_ACTIVE_HIGH>; output-low; line-name = "usb-emulation"; }; - usb-mode1 { + usb-mode1-hog { gpio-hog; gpios = <20 GPIO_ACTIVE_HIGH>; output-high; line-name = "usb-mode1"; }; - usb-pwr { + usb-pwr-hog { gpio-hog; gpios = <22 GPIO_ACTIVE_LOW>; output-high; line-name = "usb-pwr-ctrl-en-n"; }; - usb-mode2 { + usb-mode2-hog { gpio-hog; gpios = <23 GPIO_ACTIVE_HIGH>; output-high; diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 7a8837cbe21b..6f59a99cbe82 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -45,6 +45,10 @@ spi1 = &ecspi2; spi2 = &ecspi3; spi3 = &ecspi4; + usb0 = &usbotg; + usb1 = &usbh1; + usb2 = &usbh2; + usb3 = &usbh3; usbphy0 = &usbphy1; usbphy1 = &usbphy2; }; @@ -542,25 +546,25 @@ status = "disabled"; }; - can1: flexcan@2090000 { + can1: can@2090000 { compatible = "fsl,imx6q-flexcan"; reg = <0x02090000 0x4000>; interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6QDL_CLK_CAN1_IPG>, <&clks IMX6QDL_CLK_CAN1_SERIAL>; clock-names = "ipg", "per"; - fsl,stop-mode = <&gpr 0x34 28 0x10 17>; + fsl,stop-mode = <&gpr 0x34 28>; status = "disabled"; }; - can2: flexcan@2094000 { + can2: can@2094000 { compatible = "fsl,imx6q-flexcan"; reg = <0x02094000 0x4000>; interrupts = <0 111 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6QDL_CLK_CAN2_IPG>, <&clks IMX6QDL_CLK_CAN2_SERIAL>; clock-names = "ipg", "per"; - fsl,stop-mode = <&gpr 0x34 29 0x10 18>; + fsl,stop-mode = <&gpr 0x34 29>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6qp-prtwd3.dts b/arch/arm/boot/dts/imx6qp-prtwd3.dts new file mode 100644 index 000000000000..c42723989bc0 --- /dev/null +++ b/arch/arm/boot/dts/imx6qp-prtwd3.dts @@ -0,0 +1,553 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (c) 2018 Protonic Holland + * Copyright (c) 2020 Oleksij Rempel <kernel@pengutronix.de>, Pengutronix + */ + +/dts-v1/; +#include <dt-bindings/gpio/gpio.h> +#include "imx6qp.dtsi" + +/ { + model = "Protonic WD3 board"; + compatible = "prt,prtwd3", "fsl,imx6qp"; + + chosen { + stdout-path = &uart4; + }; + + memory@10000000 { + device_type = "memory"; + reg = <0x10000000 0x20000000>; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x20000000>; + }; + + clock_ksz8081: clock-ksz8081 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + + clock_ksz9031: clock-ksz9031 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + clock_mcp251xfd: clock-mcp251xfd { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <20000000>; + }; + + clock_sja1105: clock-sja1105 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + mdio { + compatible = "virtual,mdio-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mdio>; + + #address-cells = <1>; + #size-cells = <0>; + gpios = <&gpio5 6 GPIO_ACTIVE_HIGH + &gpio5 7 GPIO_ACTIVE_HIGH>; + + /* Microchip KSZ8081 */ + usbeth_phy: ethernet-phy@3 { + reg = <0x3>; + + interrupts-extended = <&gpio5 12 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>; + reset-assert-us = <500>; + reset-deassert-us = <1000>; + clocks = <&clock_ksz8081>; + clock-names = "rmii-ref"; + micrel,led-mode = <0>; + }; + + tja1102_phy0: ethernet-phy@4 { + reg = <0x4>; + + interrupts-extended = <&gpio5 8 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; + reset-assert-us = <20>; + reset-deassert-us = <2000>; + #address-cells = <1>; + #size-cells = <0>; + + tja1102_phy1: ethernet-phy@5 { + reg = <0x5>; + + interrupts-extended = <&gpio5 8 IRQ_TYPE_LEVEL_LOW>; + }; + }; + }; + + reg_5v0: regulator-5v0 { + compatible = "regulator-fixed"; + regulator-name = "5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_otg_vbus: regulator-otg-vbus { + compatible = "regulator-fixed"; + regulator-name = "otg-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + usdhc2_wifi_pwrseq: usdhc2-wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wifi_npd>; + reset-gpios = <&gpio6 10 GPIO_ACTIVE_LOW>; + }; +}; + +&can1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can1>; + xceiver-supply = <®_5v0>; + status = "okay"; +}; + +&ecspi2 { + cs-gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi2>; + status = "okay"; + + switch@0 { + compatible = "nxp,sja1105q"; + reg = <0>; + spi-max-frequency = <4000000>; + spi-rx-delay-us = <1>; + spi-tx-delay-us = <1>; + spi-cpha; + + reset-gpios = <&gpio5 5 GPIO_ACTIVE_LOW>; + + clocks = <&clock_sja1105>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "usb"; + phy-handle = <&usbeth_phy>; + phy-mode = "rmii"; + }; + + port@1 { + reg = <1>; + label = "t1slave"; + phy-handle = <&tja1102_phy1>; + phy-mode = "rmii"; + }; + + port@2 { + reg = <2>; + label = "t1master"; + phy-handle = <&tja1102_phy0>; + phy-mode = "rmii"; + + }; + + port@3 { + reg = <3>; + label = "rj45"; + phy-handle = <&rgmii_phy>; + phy-mode = "rgmii-id"; + }; + + port@4 { + reg = <4>; + label = "cpu"; + ethernet = <&fec>; + phy-mode = "rgmii-id"; + + fixed-link { + speed = <100>; + full-duplex; + }; + }; + }; + }; +}; + +&ecspi3 { + cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi3>; + status = "okay"; + + can@0 { + compatible = "microchip,mcp251xfd"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can2>; + reg = <0>; + clocks = <&clock_mcp251xfd>; + spi-max-frequency = <10000000>; + interrupts-extended = <&gpio4 25 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + status = "okay"; + + phy-mode = "rgmii"; + + fixed-link { + speed = <100>; + full-duplex; + }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + /* Microchip KSZ9031 */ + rgmii_phy: ethernet-phy@2 { + reg = <2>; + + interrupts-extended = <&gpio1 28 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <1000>; + + clocks = <&clock_ksz9031>; + }; + }; +}; + +&gpio1 { + gpio-line-names = + "", "SD1_CD", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "PHY3_RESET", "", "", "PHY3_INT", "", "", ""; +}; + +&gpio2 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "REV_ID0", "REV_ID1", "REV_ID2", "REV_ID3", "BOARD_ID3", + "BOARD_ID0", "BOARD_ID1", "BOARD_ID2", + "", "", "", "", "", "", "", "", + "", "", "ECSPI2_SS0", "", "", "", "", ""; +}; + +&gpio3 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "USB_OTG_OC", "USB_OTG_PWR", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio4 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "", "", "", "", "CAN1_SR", "CAN2_SR", "", "", + "", "", "", "", "", "", "", "", + "ECSPI3_SS0", "CANFD_INT", "USB_ETH_RESET", "", "", "", "", ""; +}; + +&gpio5 { + gpio-line-names = + "", "", "", "", "", "SW_RESET", "", "", + "PHY12_INT", "PHY12_RESET", "PHY12_EN", "PHY0_RESET", + "PHY0_INT", "", "", "", + "", "", "DISP1_EN", "DISP1_LR", "DISP1_TS_IRQ", "LVDS1_PD", + "", "", + "", "LVDS1_INT", "", "", "DISP0_LR", "DISP0_TS_IRQ", + "DISP0_EN", "CAM_GPIO0"; +}; + +&gpio6 { + gpio-line-names = + "LVDS0_INT", "LVDS0_PD", "CAM_INT", "CAM_GPIO1", "CAM_PD", + "CAM_LOCK", "", "POWER_TG", + "POWER_VSEL", "", "WLAN_REG_ON", "USB_ETH_CHG", "", "", + "USB_ETH_CHG_ID0", "USB_ETH_CHG_ID1", + "USB_ETH_CHG_ID2", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + /* additional i2c devices are added automatically by the boot loader */ +}; + +&i2c3 { + adc@49 { + compatible = "ti,ads1015"; + reg = <0x49>; + #address-cells = <1>; + #size-cells = <0>; + + /* VIN */ + channel@4 { + reg = <4>; + ti,gain = <1>; + ti,datarate = <3>; + }; + + /* VBUS */ + channel@5 { + reg = <5>; + ti,gain = <1>; + ti,datarate = <3>; + }; + + /* ICHG */ + channel@6 { + reg = <6>; + ti,gain = <1>; + ti,datarate = <3>; + }; + + channel@7 { + reg = <7>; + ti,gain = <1>; + ti,datarate = <3>; + }; + }; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + phy_type = "utmi"; + dr_mode = "host"; + disable-over-current; + status = "okay"; +}; + +&usbphynop1 { + status = "disabled"; +}; + +&usbphynop2 { + status = "disabled"; +}; + +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + cd-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; + no-1-8-v; + disable-wp; + cap-sd-highspeed; + no-mmc; + no-sdio; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + no-1-8-v; + non-removable; + mmc-pwrseq = <&usdhc2_wifi_pwrseq>; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + brcmf: bcrmf@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + }; +}; + +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3>; + bus-width = <8>; + no-1-8-v; + non-removable; + no-sd; + no-sdio; + status = "okay"; +}; + +&iomuxc { + pinctrl_can1: can1grp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b000 + MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x3008 + /* CAN1_SR */ + MX6QDL_PAD_KEY_COL3__GPIO4_IO12 0x13008 + >; + }; + + pinctrl_can2: can2grp { + fsl,pins = < + /* CAN2_nINT */ + MX6QDL_PAD_DISP0_DAT4__GPIO4_IO25 0x1b0b1 + /* CAN2_SR */ + MX6QDL_PAD_KEY_ROW3__GPIO4_IO13 0x13070 + >; + }; + + pinctrl_ecspi2: ecspi2grp { + fsl,pins = < + MX6QDL_PAD_EIM_OE__ECSPI2_MISO 0x100b1 + MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK 0x100b1 + MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI 0x100b1 + MX6QDL_PAD_EIM_RW__GPIO2_IO26 0x000b1 + >; + }; + + pinctrl_ecspi3: ecspi3grp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1 + MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1 + MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1 + /* CS */ + MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x000b1 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b030 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b030 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b030 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x10030 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x10030 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x10030 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x10030 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x10030 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x10030 + + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x10030 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x10030 + + /* Configure clock provider for RGMII ref clock */ + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0b0 + /* Configure clock consumer for RGMII ref clock */ + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x10030 + + /* SJA1105Q switch reset */ + MX6QDL_PAD_DISP0_DAT11__GPIO5_IO05 0x10030 + + /* phy3/rgmii_phy reset */ + MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x10030 + /* phy3/rgmii_phy int */ + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x40010000 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001f8b1 + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001f8b1 + >; + }; + + pinctrl_mdio: mdiogrp { + fsl,pins = < + /* phy0/usbeth_phy reset */ + MX6QDL_PAD_DISP0_DAT17__GPIO5_IO11 0x10030 + /* phy0/usbeth_phy int */ + MX6QDL_PAD_DISP0_DAT18__GPIO5_IO12 0x100b1 + + /* phy12/tja1102_phy0 reset */ + MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09 0x10030 + /* phy12/tja1102_phy0 int */ + MX6QDL_PAD_DISP0_DAT14__GPIO5_IO08 0x100b1 + /* phy12/tja1102_phy0 enable. Set 100K pull-up */ + MX6QDL_PAD_DISP0_DAT16__GPIO5_IO10 0x1f030 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_EIM_D21__USB_OTG_OC 0x1b0b0 + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x170f9 + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x100f9 + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x170f9 + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x170f9 + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x170f9 + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x170f9 + MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x1b0b0 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170b9 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100b9 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170b9 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170b9 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170b9 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x170b9 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17099 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10099 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17099 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17099 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17099 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17099 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17099 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17099 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17099 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17099 + MX6QDL_PAD_SD3_RST__SD3_RESET 0x1b0b1 + >; + }; + + pinctrl_wifi_npd: wifinpd { + fsl,pins = < + /* WL_REG_ON */ + MX6QDL_PAD_NANDF_RB0__GPIO6_IO10 0x13069 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6sl-warp.dts b/arch/arm/boot/dts/imx6sl-warp.dts index 408da704c459..9d7c8884892a 100644 --- a/arch/arm/boot/dts/imx6sl-warp.dts +++ b/arch/arm/boot/dts/imx6sl-warp.dts @@ -51,8 +51,8 @@ #include "imx6sl.dtsi" / { - model = "WaRP Board"; - compatible = "warp,imx6sl-warp", "fsl,imx6sl"; + model = "Revotics WaRP Board"; + compatible = "revotics,imx6sl-warp", "fsl,imx6sl"; memory@80000000 { device_type = "memory"; diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 91a8c54d5e11..997b96c1c47b 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -39,6 +39,9 @@ spi1 = &ecspi2; spi2 = &ecspi3; spi3 = &ecspi4; + usb0 = &usbotg1; + usb1 = &usbotg2; + usb2 = &usbh; usbphy0 = &usbphy1; usbphy1 = &usbphy2; }; diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi index 0b622201a1f3..04f8d637a501 100644 --- a/arch/arm/boot/dts/imx6sll.dtsi +++ b/arch/arm/boot/dts/imx6sll.dtsi @@ -36,6 +36,8 @@ spi1 = &ecspi2; spi3 = &ecspi3; spi4 = &ecspi4; + usb0 = &usbotg1; + usb1 = &usbotg2; usbphy0 = &usbphy1; usbphy1 = &usbphy2; }; diff --git a/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts b/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts index 5547916870c7..b9a1401e6c6d 100644 --- a/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts +++ b/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts @@ -40,22 +40,22 @@ regulator-max-microvolt = <3300000>; }; - pwmleds { + led-controller { compatible = "pwm-leds"; - red { + led-1 { label = "red"; max-brightness = <255>; pwms = <&pwm6 0 50000>; }; - green { + led-2 { label = "green"; max-brightness = <255>; pwms = <&pwm2 0 50000>; }; - blue { + led-3 { label = "blue"; max-brightness = <255>; pwms = <&pwm1 0 50000>; diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi index dfdca1804f9f..8516730778df 100644 --- a/arch/arm/boot/dts/imx6sx.dtsi +++ b/arch/arm/boot/dts/imx6sx.dtsi @@ -49,6 +49,9 @@ spi2 = &ecspi3; spi3 = &ecspi4; spi4 = &ecspi5; + usb0 = &usbotg1; + usb1 = &usbotg2; + usb2 = &usbh; usbphy0 = &usbphy1; usbphy1 = &usbphy2; }; @@ -463,7 +466,7 @@ clocks = <&clks IMX6SX_CLK_CAN1_IPG>, <&clks IMX6SX_CLK_CAN1_SERIAL>; clock-names = "ipg", "per"; - fsl,stop-mode = <&gpr 0x10 1 0x10 17>; + fsl,stop-mode = <&gpr 0x10 1>; status = "disabled"; }; @@ -474,7 +477,7 @@ clocks = <&clks IMX6SX_CLK_CAN2_IPG>, <&clks IMX6SX_CLK_CAN2_SERIAL>; clock-names = "ipg", "per"; - fsl,stop-mode = <&gpr 0x10 2 0x10 18>; + fsl,stop-mode = <&gpr 0x10 2>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6ul-ccimx6ulsbcpro.dts b/arch/arm/boot/dts/imx6ul-ccimx6ulsbcpro.dts index a0bbec57ddc7..3ec042bfccba 100644 --- a/arch/arm/boot/dts/imx6ul-ccimx6ulsbcpro.dts +++ b/arch/arm/boot/dts/imx6ul-ccimx6ulsbcpro.dts @@ -110,7 +110,7 @@ }; &gpio5 { - emmc-usd-mux { + emmc-usd-mux-hog { gpio-hog; gpios = <1 GPIO_ACTIVE_LOW>; output-high; diff --git a/arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi b/arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi index 88f631c8fabb..19a062635ff6 100644 --- a/arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi +++ b/arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi @@ -75,6 +75,7 @@ eeprom@52 { compatible = "catalyst,24c32", "atmel,24c32"; + pagesize = <32>; reg = <0x52>; }; }; diff --git a/arch/arm/boot/dts/imx6ul-phytec-segin-ff-rdk-emmc.dts b/arch/arm/boot/dts/imx6ul-phytec-segin-ff-rdk-emmc.dts new file mode 100644 index 000000000000..cfc744f8fcad --- /dev/null +++ b/arch/arm/boot/dts/imx6ul-phytec-segin-ff-rdk-emmc.dts @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (C) 2020 PHYTEC Messtechnik GmbH + * Author: Yunus Bas <y.bas@phytec.de> + */ + +/dts-v1/; +#include "imx6ul.dtsi" +#include "imx6ul-phytec-phycore-som.dtsi" +#include "imx6ul-phytec-segin.dtsi" +#include "imx6ul-phytec-segin-peb-eval-01.dtsi" +#include "imx6ul-phytec-segin-peb-av-02.dtsi" + +/ { + model = "PHYTEC phyBOARD-Segin i.MX6 UltraLite Full Featured with eMMC"; + compatible = "phytec,imx6ul-pbacd10-emmc", "phytec,imx6ul-pbacd10", + "phytec,imx6ul-pcl063","fsl,imx6ul"; +}; + +&adc1 { + status = "okay"; +}; + +&can1 { + status = "okay"; +}; + +&ecspi3 { + status = "okay"; +}; + +ðphy1 { + status = "okay"; +}; + +ðphy2 { + status = "okay"; +}; + +&fec1 { + status = "okay"; +}; + +&fec2 { + status = "okay"; +}; + +&i2c_rtc { + status = "okay"; +}; + +®_can1_en { + status = "okay"; +}; + +®_sound_1v8 { + status = "okay"; +}; + +®_sound_3v3 { + status = "okay"; +}; + +&sai2 { + status = "okay"; +}; + +&sound { + status = "okay"; +}; + +&tlv320 { + status = "okay"; +}; + +&uart5 { + status = "okay"; +}; + +&usbotg1 { + status = "okay"; +}; + +&usbotg2 { + status = "okay"; +}; + +&usdhc1 { + status = "okay"; +}; + +&usdhc2 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx6ul-phytec-segin-ff-rdk-nand.dts b/arch/arm/boot/dts/imx6ul-phytec-segin-ff-rdk-nand.dts index 699dfcbf9a60..bff98e676980 100644 --- a/arch/arm/boot/dts/imx6ul-phytec-segin-ff-rdk-nand.dts +++ b/arch/arm/boot/dts/imx6ul-phytec-segin-ff-rdk-nand.dts @@ -9,6 +9,7 @@ #include "imx6ul-phytec-phycore-som.dtsi" #include "imx6ul-phytec-segin.dtsi" #include "imx6ul-phytec-segin-peb-eval-01.dtsi" +#include "imx6ul-phytec-segin-peb-av-02.dtsi" / { model = "PHYTEC phyBOARD-Segin i.MX6 UltraLite Full Featured with NAND"; diff --git a/arch/arm/boot/dts/imx6ul-phytec-segin-peb-av-02.dtsi b/arch/arm/boot/dts/imx6ul-phytec-segin-peb-av-02.dtsi new file mode 100644 index 000000000000..7cda6944501d --- /dev/null +++ b/arch/arm/boot/dts/imx6ul-phytec-segin-peb-av-02.dtsi @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (C) 2016, 2020 PHYTEC Messtechnik + * Author: Christian Hemp <c.hemp@phytec.de> + * Author: Stefan Riedmueller <s.riedmueller@phytec.de> + */ + +/ { + backlight_lcd: backlight-lcd { + compatible = "pwm-backlight"; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <5>; + power-supply = <®_backlight_en>; + pwms = <&pwm3 0 5000000>; + status = "disabled"; + }; + + lcd_panel: lcd-panel { + compatible = "edt,etm0700g0edh6"; + backlight = <&backlight_lcd>; + status = "disabled"; + + port { + lcd_panel_in: endpoint { + remote-endpoint = <&lcdif_parallel_out>; + }; + }; + }; + + reg_backlight_en: regulator-backlight-en { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_backlight_en>; + regulator-name = "backlight-lcd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 18 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&i2c1 { + edt_ft5406: touchscreen@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_edt_ft5406>; + interrupt-parent = <&gpio5>; + interrupts = <5 IRQ_TYPE_EDGE_FALLING>; + wakeup-source; + status = "disabled"; + }; + + stmpe: touchscreen@44 { + compatible = "st,stmpe811"; + reg = <0x44>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_stmpe>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; + interrupt-parent = <&gpio5>; + wakeup-source; + status = "disabled"; + + stmpe_touchscreen { + compatible = "st,stmpe-ts"; + st,sample-time = <4>; + st,mod-12b = <1>; + st,ref-sel = <0>; + st,adc-freq = <1>; + st,ave-ctrl = <1>; + st,touch-det-delay = <2>; + st,settling = <2>; + st,fraction-z = <7>; + st,i-drive = <1>; + touchscreen-inverted-x = <1>; + touchscreen-inverted-y = <1>; + }; + }; +}; + +&lcdif { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcdif_dat>; + status = "disabled"; + + port { + lcdif_parallel_out: endpoint { + remote-endpoint = <&lcd_panel_in>; + }; + }; +}; + +&pwm3 { + #pwm-cells = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm3>; + status = "disabled"; +}; + +&iomuxc { + pinctrl_edt_ft5406: edtft5406grp { + fsl,pins = < + MX6UL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x1b0b0 + >; + }; + + pinctrl_backlight_en: bachlightengrp { + fsl,pins = < + MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x1b0b0 + >; + }; + + pinctrl_lcdif_dat: lcdifdatgrp { + fsl,pins = < + MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x59 + MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x59 + MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x59 + MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x59 + MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x59 + MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x59 + MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x59 + MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x59 + MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x59 + MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x59 + MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x59 + MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x59 + MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x59 + MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x59 + MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x59 + MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x59 + MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x59 + MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x59 + MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x59 + MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x59 + MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x59 + MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x59 + >; + }; + + pinctrl_pwm3: pwm3grp { + fsl,pins = < + MX6UL_PAD_GPIO1_IO04__PWM3_OUT 0x0b0b0 + >; + }; + + pinctrl_stmpe: stmpegrp { + fsl,pins = < + MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x17059 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6ul-phytec-segin.dtsi b/arch/arm/boot/dts/imx6ul-phytec-segin.dtsi index f1513e676c2f..95e4080dd0a6 100644 --- a/arch/arm/boot/dts/imx6ul-phytec-segin.dtsi +++ b/arch/arm/boot/dts/imx6ul-phytec-segin.dtsi @@ -130,31 +130,6 @@ status = "disabled"; }; - stmpe: touchscreen@44 { - compatible = "st,stmpe811"; - reg = <0x44>; - interrupts = <3 IRQ_TYPE_LEVEL_LOW>; - interrupt-parent = <&gpio5>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_stmpe>; - status = "disabled"; - - touchscreen { - compatible = "st,stmpe-ts"; - st,sample-time = <4>; - st,mod-12b = <1>; - st,ref-sel = <0>; - st,adc-freq = <1>; - st,ave-ctrl = <1>; - st,touch-det-delay = <2>; - st,settling = <2>; - st,fraction-z = <7>; - st,i-drive = <1>; - touchscreen-inverted-x = <1>; - touchscreen-inverted-y = <1>; - }; - }; - i2c_rtc: rtc@68 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_rtc_int>; @@ -176,12 +151,6 @@ }; }; -&pwm3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm3>; - status = "disabled"; -}; - &sai2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sai2>; @@ -267,12 +236,6 @@ >; }; - pinctrl_pwm3: pwm3grp { - fsl,pins = < - MX6UL_PAD_GPIO1_IO04__PWM3_OUT 0x0b0b0 - >; - }; - pinctrl_rtc_int: rtcintgrp { fsl,pins = < MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x17059 @@ -289,12 +252,6 @@ >; }; - pinctrl_stmpe: stmpegrp { - fsl,pins = < - MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x17059 - >; - }; - pinctrl_uart5: uart5grp { fsl,pins = < MX6UL_PAD_UART5_TX_DATA__UART5_DCE_TX 0x1b0b1 diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi index d7d9f3e46b92..9d3411cc597b 100644 --- a/arch/arm/boot/dts/imx6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul.dtsi @@ -47,6 +47,8 @@ spi1 = &ecspi2; spi2 = &ecspi3; spi3 = &ecspi4; + usb0 = &usbotg1; + usb1 = &usbotg2; usbphy0 = &usbphy1; usbphy1 = &usbphy2; }; @@ -423,25 +425,25 @@ status = "disabled"; }; - can1: flexcan@2090000 { + can1: can@2090000 { compatible = "fsl,imx6ul-flexcan", "fsl,imx6q-flexcan"; reg = <0x02090000 0x4000>; interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6UL_CLK_CAN1_IPG>, <&clks IMX6UL_CLK_CAN1_SERIAL>; clock-names = "ipg", "per"; - fsl,stop-mode = <&gpr 0x10 1 0x10 17>; + fsl,stop-mode = <&gpr 0x10 1>; status = "disabled"; }; - can2: flexcan@2094000 { + can2: can@2094000 { compatible = "fsl,imx6ul-flexcan", "fsl,imx6q-flexcan"; reg = <0x02094000 0x4000>; interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6UL_CLK_CAN2_IPG>, <&clks IMX6UL_CLK_CAN2_SERIAL>; clock-names = "ipg", "per"; - fsl,stop-mode = <&gpr 0x10 2 0x10 18>; + fsl,stop-mode = <&gpr 0x10 2>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-emmc.dts b/arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-emmc.dts index 9648d4ecaf58..8e2a4c5d7765 100644 --- a/arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-emmc.dts +++ b/arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-emmc.dts @@ -9,6 +9,7 @@ #include "imx6ull-phytec-phycore-som.dtsi" #include "imx6ull-phytec-segin.dtsi" #include "imx6ull-phytec-segin-peb-eval-01.dtsi" +#include "imx6ull-phytec-segin-peb-av-02.dtsi" / { model = "PHYTEC phyBOARD-Segin i.MX6 ULL Full Featured with eMMC"; diff --git a/arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-nand.dts b/arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-nand.dts index 656baf846453..c8d3eff9ed4b 100644 --- a/arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-nand.dts +++ b/arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-nand.dts @@ -9,6 +9,7 @@ #include "imx6ull-phytec-phycore-som.dtsi" #include "imx6ull-phytec-segin.dtsi" #include "imx6ull-phytec-segin-peb-eval-01.dtsi" +#include "imx6ull-phytec-segin-peb-av-02.dtsi" / { model = "PHYTEC phyBOARD-Segin i.MX6 ULL Full Featured with NAND"; diff --git a/arch/arm/boot/dts/imx6ull-phytec-segin-peb-av-02.dtsi b/arch/arm/boot/dts/imx6ull-phytec-segin-peb-av-02.dtsi new file mode 100644 index 000000000000..06bb7f327780 --- /dev/null +++ b/arch/arm/boot/dts/imx6ull-phytec-segin-peb-av-02.dtsi @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) +/* + * Copyright (C) 2018 PHYTEC Messtechnik GmbH + * Author: Stefan Riedmueller <s.riedmueller@phytec.de> + */ + +#include "imx6ul-phytec-segin-peb-av-02.dtsi" + +&iomuxc { + /delete-node/ edtft5406grp; + /delete-node/ stmpegrp; +}; + +&iomuxc_snvs { + pinctrl_edt_ft5406: edtft5406grp { + fsl,pins = < + MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x1b0b0 + >; + }; + + pinctrl_stmpe: stmpegrp { + fsl,pins = < + MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x17059 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6ull-phytec-segin.dtsi b/arch/arm/boot/dts/imx6ull-phytec-segin.dtsi index c1595fc785f7..e287a0453b5f 100644 --- a/arch/arm/boot/dts/imx6ull-phytec-segin.dtsi +++ b/arch/arm/boot/dts/imx6ull-phytec-segin.dtsi @@ -14,7 +14,6 @@ &iomuxc { /delete-node/ flexcan1engrp; /delete-node/ rtcintgrp; - /delete-node/ stmpegrp; }; &iomuxc_snvs { @@ -29,10 +28,4 @@ MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x17059 >; }; - - pinctrl_stmpe: stmpegrp { - fsl,pins = < - MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x17059 - >; - }; }; diff --git a/arch/arm/boot/dts/imx7-mba7.dtsi b/arch/arm/boot/dts/imx7-mba7.dtsi index 50abf18ad30b..c6d1c63f7905 100644 --- a/arch/arm/boot/dts/imx7-mba7.dtsi +++ b/arch/arm/boot/dts/imx7-mba7.dtsi @@ -14,6 +14,12 @@ #include <dt-bindings/net/ti-dp83867.h> / { + aliases { + mmc0 = &usdhc3; + mmc1 = &usdhc1; + /delete-property/ mmc2; + }; + beeper { compatible = "gpio-beeper"; gpios = <&pca9555 0 GPIO_ACTIVE_HIGH>; @@ -164,6 +170,20 @@ regulator-max-microvolt = <3300000>; regulator-always-on; }; + + sound { + compatible = "fsl,imx-audio-tlv320aic32x4"; + model = "imx-audio-tlv320aic32x4"; + ssi-controller = <&sai1>; + audio-codec = <&tlv320aic32x4>; + audio-routing = + "IN3_L", "Mic Jack", + "Mic Jack", "Mic Bias", + "IN1_L", "Line In Jack", + "IN1_R", "Line In Jack", + "Line Out Jack", "LOL", + "Line Out Jack", "LOR"; + }; }; &adc1 { @@ -179,7 +199,6 @@ &ecspi1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; - num-chipselects = <3>; cs-gpios = <&gpio4 0 GPIO_ACTIVE_LOW>, <&gpio4 1 GPIO_ACTIVE_LOW>, <&gpio4 2 GPIO_ACTIVE_LOW>; status = "okay"; @@ -188,7 +207,6 @@ &ecspi2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; - num-chipselects = <1>; status = "okay"; }; @@ -214,10 +232,7 @@ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>; ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>; ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; - /* LED1: Link/Activity, LED2: Error */ - ti,led-function = <0x0db0>; - /* Active low, LED1 and LED2 driven by phy */ - ti,led-ctrl = <0x1001>; + ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>; }; }; }; @@ -362,13 +377,25 @@ >; }; - pinctrl_pca9555: pca95550grp { fsl,pins = < MX7D_PAD_ENET1_TX_CLK__GPIO7_IO12 0x78 >; }; + pinctrl_sai1: sai1grp { + fsl,pins = < + MX7D_PAD_SAI1_MCLK__SAI1_MCLK 0x11 + MX7D_PAD_SAI1_RX_BCLK__SAI1_RX_BCLK 0x1c + MX7D_PAD_SAI1_RX_DATA__SAI1_RX_DATA0 0x1c + MX7D_PAD_SAI1_RX_SYNC__SAI2_RX_SYNC 0x1c + + MX7D_PAD_SAI1_TX_BCLK__SAI1_TX_BCLK 0x1c + MX7D_PAD_SAI1_TX_DATA__SAI1_TX_DATA0 0x14 + MX7D_PAD_SAI1_TX_SYNC__SAI1_TX_SYNC 0x14 + >; + }; + pinctrl_uart3: uart3grp { fsl,pins = < MX7D_PAD_UART3_RX_DATA__UART3_DCE_RX 0x7e @@ -472,6 +499,12 @@ MX7D_PAD_LPSR_GPIO1_IO05__GPIO1_IO5 0x59 >; }; + + pinctrl_wdog1: wdog1grp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B 0x30 + >; + }; }; &pwm1 { @@ -480,6 +513,16 @@ status = "okay"; }; +&sai1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai1>; + assigned-clocks = <&clks IMX7D_SAI1_ROOT_SRC>, + <&clks IMX7D_SAI1_ROOT_CLK>; + assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>; + assigned-clock-rates = <0>, <36864000>; + status = "okay"; +}; + &uart3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart3>; @@ -518,6 +561,9 @@ assigned-clocks = <&clks IMX7D_UART7_ROOT_SRC>; assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>; uart-has-rtscts; + linux,rs485-enabled-at-boot-time; + rs485-rts-active-low; + rs485-rx-during-tx; status = "okay"; }; @@ -532,7 +578,8 @@ srp-disable; hnp-disable; adp-disable; - dr_mode = "host"; + over-current-active-low; + dr_mode = "otg"; status = "okay"; }; @@ -548,3 +595,9 @@ no-1-8-v; status = "okay"; }; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog1>; + fsl,ext-reset-output; +}; diff --git a/arch/arm/boot/dts/imx7d-flex-concentrator-mfg.dts b/arch/arm/boot/dts/imx7d-flex-concentrator-mfg.dts new file mode 100644 index 000000000000..a6d68165fb1e --- /dev/null +++ b/arch/arm/boot/dts/imx7d-flex-concentrator-mfg.dts @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for Kamstrup OMNIA Flex Concentrator in + * manufacturing/debugging mode. + * + * Copyright (C) 2020 Kamstrup A/S + * Author: Bruno Thomsen <bruno.thomsen@gmail.com> + */ + +/dts-v1/; + +#include "imx7d-flex-concentrator.dts" + +/ { + model = "Kamstrup OMNIA Flex Concentrator - Manufacturing"; + compatible = "kam,imx7d-flex-concentrator-mfg", "fsl,imx7d"; + + chosen { + stdout-path = &uart4; + }; +}; + +&uart4 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx7d-flex-concentrator.dts b/arch/arm/boot/dts/imx7d-flex-concentrator.dts new file mode 100644 index 000000000000..84b095279e65 --- /dev/null +++ b/arch/arm/boot/dts/imx7d-flex-concentrator.dts @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for Kamstrup OMNIA Flex Concentrator. + * + * Copyright (C) 2020 Kamstrup A/S + * Author: Bruno Thomsen <bruno.thomsen@gmail.com> + */ + +/dts-v1/; + +#include "imx7d-tqma7.dtsi" + +/* One I2C device on TQMa7 SoM is not mounted */ +/delete-node/ &ds1339; + +/ { + model = "Kamstrup OMNIA Flex Concentrator"; + compatible = "kam,imx7d-flex-concentrator", "fsl,imx7d"; + + memory@80000000 { + device_type = "memory"; + /* 1024 MB - TQMa7D board configuration */ + reg = <0x80000000 0x40000000>; + }; + + reg_usb_otg2_vbus: regulator-usb-otg2-vbus { + compatible = "regulator-fixed"; + regulator-name = "VBUS_USBOTG2"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_vref_1v8: regulator-vref-1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC1V8_REF"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + vin-supply = <&sw2_reg>; + }; + + /* + * Human Machine Interface consists of 4 dual red/green LEDs. + * hmi-a:green is controlled directly by the switch-mode power supply. + * hmi-a:red is not used. + */ + gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_leds>; + + led-0 { + label = "hmi-b:red:heartbeat-degraded"; + gpios = <&gpio3 6 GPIO_ACTIVE_HIGH>; + }; + + led-1 { + label = "hmi-b:green:heartbeat-running"; + gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + + led-2 { + label = "hmi-c:red:mesh-error"; + gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>; + }; + + led-3 { + label = "hmi-c:green:mesh-activity"; + gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>; + }; + + led-4 { + label = "hmi-d:red:omnia-error"; + gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>; + }; + + led-5 { + label = "hmi-d:green:omnia-activity"; + gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>; + }; + }; + + /* + * Errata e10574 board restart workaround. + */ + gpio-restart { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_restart>; + compatible = "gpio-restart"; + gpios = <&gpio7 12 GPIO_ACTIVE_LOW>; + priority = <200>; + }; +}; + +/* + * Analog signals + * ADC1_IN0: SMPS - 5V output monitor (voltage divider: 1/0.2806) + */ +&adc1 { + vref-supply = <®_vref_1v8>; + status = "okay"; +}; + +&ecspi2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi2>; + num-chipselects = <1>; + cs-gpios = <&gpio4 23 GPIO_ACTIVE_LOW>; + status = "okay"; + + pcf2127: rtc@0 { + compatible = "nxp,pcf2127"; + reg = <0>; + spi-max-frequency = <2000000>; + }; +}; + +&ecspi4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi4>; + num-chipselects = <1>; + cs-gpios = <&gpio3 3 GPIO_ACTIVE_LOW>; + status = "okay"; + + /* + * ST chip maximum SPI clock frequency is 33 MHz. + * + * TCG specification - Section 6.4.1 Clocking: + * TPM shall support a SPI clock frequency range of 10-24 MHz. + */ + st33htph: tpm-tis@0 { + compatible = "st,st33htpm-spi", "tcg,tpm_tis-spi"; + reg = <0>; + spi-max-frequency = <24000000>; + }; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet1>; + phy-mode = "rmii"; + phy-handle = <ðphy>; + status = "okay"; + + /* + * MDIO bus reset is used to generate PHY device reset before + * Ethernet PHY type ID auto-detection. Otherwise this communication + * fails as device does not answer when recommended reset circuit + * is used. + */ + mdio { + #address-cells = <1>; + #size-cells = <0>; + + reset-delay-us = <100000>; + reset-post-delay-us = <500000>; + reset-gpios = <&gpio7 15 GPIO_ACTIVE_LOW>; + + /* Microchip/Micrel KSZ8081RNB */ + ethphy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + interrupt-parent = <&gpio1>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; + reg = <1>; + }; + }; +}; + +/* + * Detection signals for internal USB modules. + * Used for robust USB plug and play handling such as USB downstream port + * power-cycle and USB hub reset in case of misbehaving or crashed modules. + * + * SMPS - AC input monitor based on zero crossing. + * Used for last gasp notification. + */ +&gpio3 { + gpio-line-names = "", "", "", "", "", "", "", "", + "", "", "", "", "smps-ac-monitor", "", "usb-hub-reset", "", + "", "", "", "", "", "", "", "", + "", "module-b-detection", "", "module-a-detection", "", "", "", ""; +}; + +/* + * Tamper IRQ trigger timestamp reading. + * Used for sealed cover opened/closed notification. + */ +&gpio5 { + gpio-line-names = "", "", "", "", "", "", "", "", + "", "", "", "", "rtc-tamper-irq", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_misc>; + + pinctrl_ecspi2: ecspi2grp { + fsl,pins = < + MX7D_PAD_ECSPI2_MISO__ECSPI2_MISO 0x7c /* X2-15 */ + MX7D_PAD_ECSPI2_MOSI__ECSPI2_MOSI 0x74 /* X2-18 */ + MX7D_PAD_ECSPI2_SCLK__ECSPI2_SCLK 0x74 /* X2-13 */ + MX7D_PAD_ECSPI2_SS0__GPIO4_IO23 0x74 /* X2-20 */ + /* RTC - Tamper IRQ */ + MX7D_PAD_SD2_CLK__GPIO5_IO12 0x3c /* X1-92 */ + >; + }; + + pinctrl_ecspi4: ecspi4grp { + fsl,pins = < + MX7D_PAD_LCD_CLK__ECSPI4_MISO 0x7c /* X2-72 */ + MX7D_PAD_LCD_ENABLE__ECSPI4_MOSI 0x74 /* X2-68 */ + MX7D_PAD_LCD_HSYNC__ECSPI4_SCLK 0x74 /* X2-76 */ + MX7D_PAD_LCD_VSYNC__GPIO3_IO3 0x74 /* X2-78 */ + >; + }; + + pinctrl_enet1: enet1grp { + fsl,pins = < + MX7D_PAD_GPIO1_IO10__ENET1_MDIO 0x03 /* X2-48 */ + MX7D_PAD_GPIO1_IO11__ENET1_MDC 0x03 /* X2-46 */ + MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 0x71 /* X2-53 */ + MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 0x71 /* X2-55 */ + MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL 0x71 /* X2-61 */ + MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x79 /* X2-56 */ + MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x79 /* X2-58 */ + MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x79 /* X2-64 */ + MX7D_PAD_ENET1_RGMII_RXC__ENET1_RX_ER 0x73 /* X2-52 */ + /* PHY reset: SRE_FAST, DSE_X1 */ + MX7D_PAD_ENET1_COL__GPIO7_IO15 0x00 /* X1-96 */ + /* Clock from PHY to MAC: 100kPU */ + MX7D_PAD_GPIO1_IO12__CCM_ENET_REF_CLK1 0x70 /* X3-4 */ + /* PHY interrupt: 100kPU, HYS */ + MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x78 /* X1-80 */ + >; + }; + + pinctrl_leds: ledsgrp { + fsl,pins = < + MX7D_PAD_LCD_DATA01__GPIO3_IO6 0x14 /* X2-82 */ + MX7D_PAD_EPDC_BDR0__GPIO2_IO28 0x14 /* X1-82 */ + MX7D_PAD_EPDC_BDR1__GPIO2_IO29 0x14 /* X1-84 */ + MX7D_PAD_EPDC_PWR_COM__GPIO2_IO30 0x14 /* X1-86 */ + MX7D_PAD_EPDC_PWR_STAT__GPIO2_IO31 0x14 /* X1-88 */ + MX7D_PAD_UART2_TX_DATA__GPIO4_IO3 0x14 /* X1-90 */ + >; + }; + + pinctrl_misc: miscgrp { + fsl,pins = < + /* Module A detection (low = present) */ + MX7D_PAD_LCD_DATA22__GPIO3_IO27 0x7c /* X2-105 */ + /* Module B detection (low = present) */ + MX7D_PAD_LCD_DATA20__GPIO3_IO25 0x7c /* X2-103 */ + /* SMPS - AC input monitor (high = failure) */ + MX7D_PAD_LCD_DATA07__GPIO3_IO12 0x7c /* X2-88 */ + /* USB - Hub reset */ + MX7D_PAD_LCD_DATA09__GPIO3_IO14 0x74 /* X2-92 */ + >; + }; + + pinctrl_restart: restartgrp { + fsl,pins = < + MX7D_PAD_ENET1_TX_CLK__GPIO7_IO12 0x74 /* X1-94 */ + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX7D_PAD_SAI2_TX_SYNC__UART4_DCE_RX 0x7e /* X3-14 */ + MX7D_PAD_SAI2_TX_BCLK__UART4_DCE_TX 0x76 /* X3-16 */ + >; + }; +}; + +&iomuxc_lpsr { + pinctrl_usbotg2: usbotg2grp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO06__USB_OTG2_OC 0x5c /* X3-11 */ + MX7D_PAD_LPSR_GPIO1_IO07__GPIO1_IO7 0x59 /* X3-9 */ + >; + }; + +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + assigned-clocks = <&clks IMX7D_UART4_ROOT_SRC>; + assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>; +}; + +&usbotg2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg2>; + vbus-supply = <®_usb_otg2_vbus>; + srp-disable; + hnp-disable; + adp-disable; + over-current-active-low; + dr_mode = "host"; + status = "okay"; +}; + +/* + * External watchdog feature provided by pcf2127. + */ +&wdog1 { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/imx7d-mba7.dts b/arch/arm/boot/dts/imx7d-mba7.dts index 221274c73dbd..5ef86de53013 100644 --- a/arch/arm/boot/dts/imx7d-mba7.dts +++ b/arch/arm/boot/dts/imx7d-mba7.dts @@ -14,7 +14,7 @@ / { model = "TQ Systems TQMa7D board on MBa7 carrier board"; - compatible = "tq,imx7d-mba7", "fsl,imx7d"; + compatible = "tq,imx7d-mba7", "tq,imx7d-tqma7", "fsl,imx7d"; }; &fec2 { @@ -39,10 +39,7 @@ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>; ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>; ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; - /* LED1: Link/Activity, LED2: error */ - ti,led-function = <0x0db0>; - /* active low, LED1/2 driven by phy */ - ti,led-ctrl = <0x1001>; + ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>; }; }; }; diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi index cff875b80b60..b0bcfa9094a3 100644 --- a/arch/arm/boot/dts/imx7d.dtsi +++ b/arch/arm/boot/dts/imx7d.dtsi @@ -7,6 +7,12 @@ #include <dt-bindings/reset/imx7-reset.h> / { + aliases { + usb0 = &usbotg1; + usb1 = &usbotg2; + usb2 = &usbh; + }; + cpus { cpu0: cpu@0 { clock-frequency = <996000000>; diff --git a/arch/arm/boot/dts/imx7s-mba7.dts b/arch/arm/boot/dts/imx7s-mba7.dts index a143d566a38b..d7d3f530f843 100644 --- a/arch/arm/boot/dts/imx7s-mba7.dts +++ b/arch/arm/boot/dts/imx7s-mba7.dts @@ -14,5 +14,5 @@ / { model = "TQ Systems TQMa7S board on MBa7 carrier board"; - compatible = "tq,imx7s-mba7", "fsl,imx7s"; + compatible = "tq,imx7s-mba7", "tq,imx7s-tqma7", "fsl,imx7s"; }; diff --git a/arch/arm/boot/dts/imx7s-warp.dts b/arch/arm/boot/dts/imx7s-warp.dts index d6b4888fa686..569bbd84e371 100644 --- a/arch/arm/boot/dts/imx7s-warp.dts +++ b/arch/arm/boot/dts/imx7s-warp.dts @@ -10,8 +10,8 @@ #include "imx7s.dtsi" / { - model = "Warp i.MX7 Board"; - compatible = "warp,imx7s-warp", "fsl,imx7s"; + model = "Element14 Warp i.MX7 Board"; + compatible = "element14,imx7s-warp", "fsl,imx7s"; memory@80000000 { device_type = "memory"; diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index 84d9cc13afb9..251007a7b836 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi @@ -47,6 +47,8 @@ spi1 = &ecspi2; spi2 = &ecspi3; spi3 = &ecspi4; + usb0 = &usbotg1; + usb1 = &usbh; }; cpus { @@ -971,7 +973,7 @@ clocks = <&clks IMX7D_CLK_DUMMY>, <&clks IMX7D_CAN1_ROOT_CLK>; clock-names = "ipg", "per"; - fsl,stop-mode = <&gpr 0x10 1 0x10 17>; + fsl,stop-mode = <&gpr 0x10 1>; status = "disabled"; }; @@ -982,7 +984,7 @@ clocks = <&clks IMX7D_CLK_DUMMY>, <&clks IMX7D_CAN2_ROOT_CLK>; clock-names = "ipg", "per"; - fsl,stop-mode = <&gpr 0x10 2 0x10 18>; + fsl,stop-mode = <&gpr 0x10 2>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/keystone-k2g-evm.dts b/arch/arm/boot/dts/keystone-k2g-evm.dts index 8b3d64c913d8..14e26a4fd62a 100644 --- a/arch/arm/boot/dts/keystone-k2g-evm.dts +++ b/arch/arm/boot/dts/keystone-k2g-evm.dts @@ -46,6 +46,14 @@ regulator-always-on; }; + vcc1v8_ldo2_reg: fixedregulator-vcc1v8-ldo2 { + compatible = "regulator-fixed"; + regulator-name = "ldo2"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + hdmi: connector { compatible = "hdmi-connector"; label = "hdmi"; @@ -58,6 +66,57 @@ }; }; }; + + aud_mclk: aud_mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <12288000>; + }; + + sound0: sound@0 { + compatible = "simple-audio-card"; + simple-audio-card,name = "K2G-EVM"; + simple-audio-card,widgets = + "Headphone", "Headphone Jack", + "Line", "Line In"; + simple-audio-card,routing = + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "LINE1L", "Line In", + "LINE1R", "Line In"; + + simple-audio-card,dai-link@0 { + format = "i2s"; + bitclock-master = <&sound0_0_master>; + frame-master = <&sound0_0_master>; + sound0_0_master: cpu { + sound-dai = <&mcasp2>; + clocks = <&k2g_clks 0x6 1>; + system-clock-direction-out; + }; + + codec { + sound-dai = <&tlv320aic3106>; + clocks = <&aud_mclk>; + }; + }; + + simple-audio-card,dai-link@1 { + format = "i2s"; + bitclock-master = <&sound0_1_master>; + frame-master = <&sound0_1_master>; + sound0_1_master: cpu { + sound-dai = <&mcasp2>; + clocks = <&k2g_clks 0x6 1>; + system-clock-direction-out; + }; + + codec { + sound-dai = <&sii9022>; + clocks = <&aud_mclk>; + }; + }; + }; }; &k2g_pinctrl { @@ -214,6 +273,15 @@ K2G_CORE_IOPAD(0x10e8) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0) /* dssfid.dssfid */ >; }; + + mcasp2_pins: pinmux_mcasp2_pins { + pinctrl-single,pins = < + K2G_CORE_IOPAD(0x1234) (BUFFER_CLASS_B | PIN_PULLDOWN | MUX_MODE4) /* pr0_pru_gpo2.mcasp2_axr2 */ + K2G_CORE_IOPAD(0x1238) (BUFFER_CLASS_B | PIN_PULLDOWN | MUX_MODE4) /* pr0_pru_gpo3.mcasp2_axr3 */ + K2G_CORE_IOPAD(0x1254) (BUFFER_CLASS_B | PIN_PULLDOWN | MUX_MODE4) /* pr0_pru_gpo10.mcasp2_afsx */ + K2G_CORE_IOPAD(0x125c) (BUFFER_CLASS_B | PIN_PULLDOWN | MUX_MODE4) /* pr0_pru_gpo12.mcasp2_aclkx */ + >; + }; }; &uart0 { @@ -423,6 +491,10 @@ compatible = "sil,sii9022"; reg = <0x3b>; + sil,i2s-data-lanes = < 0 >; + clocks = <&aud_mclk>; + clock-names = "mclk"; + ports { #address-cells = <1>; #size-cells = <0>; @@ -444,6 +516,19 @@ }; }; }; + + tlv320aic3106: tlv320aic3106@1b { + #sound-dai-cells = <0>; + compatible = "ti,tlv320aic3106"; + reg = <0x1b>; + status = "okay"; + + /* Regulators */ + AVDD-supply = <&vcc3v3_dcin_reg>; + IOVDD-supply = <&vcc3v3_dcin_reg>; + DRVDD-supply = <&vcc3v3_dcin_reg>; + DVDD-supply = <&vcc1v8_ldo2_reg>; + }; }; &dss { @@ -458,3 +543,30 @@ }; }; }; + +&k2g_clks { + /* on the board 22.5792MHz is connected to AUDOSC_IN */ + assigned-clocks = <&k2g_clks 0x4c 2>; + assigned-clock-rates = <22579200>; +}; + +&mcasp2 { + #sound-dai-cells = <0>; + + pinctrl-names = "default"; + pinctrl-0 = <&mcasp2_pins>; + + assigned-clocks = <&k2g_clks 0x6 1>; + assigned-clock-parents = <&k2g_clks 0x6 2>; + + status = "okay"; + + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; + /* 6 serializer */ + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 1 2 0 0 // AXR2: TX, AXR3: rx + >; + tx-num-evt = <32>; + rx-num-evt = <32>; +}; diff --git a/arch/arm/boot/dts/kirkwood-dockstar.dts b/arch/arm/boot/dts/kirkwood-dockstar.dts index 6a3f1bf6d9f1..264938dfa4d9 100644 --- a/arch/arm/boot/dts/kirkwood-dockstar.dts +++ b/arch/arm/boot/dts/kirkwood-dockstar.dts @@ -34,7 +34,7 @@ }; }; serial@12000 { - status = "ok"; + status = "okay"; }; }; gpio-leds { diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts index 7f326e267494..328516351e84 100644 --- a/arch/arm/boot/dts/kirkwood-dreamplug.dts +++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts @@ -34,7 +34,7 @@ }; }; serial@12000 { - status = "ok"; + status = "okay"; }; spi@10600 { diff --git a/arch/arm/boot/dts/kirkwood-goflexnet.dts b/arch/arm/boot/dts/kirkwood-goflexnet.dts index 02d87e0a1061..d4cb3cd3e2a2 100644 --- a/arch/arm/boot/dts/kirkwood-goflexnet.dts +++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts @@ -66,7 +66,7 @@ }; }; serial@12000 { - status = "ok"; + status = "okay"; }; sata@80000 { diff --git a/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts b/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts index ff1260ee3fe8..dfb41393941d 100644 --- a/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts +++ b/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts @@ -38,7 +38,7 @@ }; }; serial@12000 { - status = "ok"; + status = "okay"; }; sata@80000 { diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts index 4a512d80912c..95af7aa1fdcb 100644 --- a/arch/arm/boot/dts/kirkwood-iconnect.dts +++ b/arch/arm/boot/dts/kirkwood-iconnect.dts @@ -72,7 +72,7 @@ }; }; serial@12000 { - status = "ok"; + status = "okay"; }; }; diff --git a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts index 62272d58664f..2338f495d517 100644 --- a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts +++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts @@ -112,7 +112,7 @@ }; serial@12000 { - status = "ok"; + status = "okay"; }; sata@80000 { diff --git a/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi b/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi index 2c4037b07282..8f73197f251a 100644 --- a/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi +++ b/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi @@ -45,7 +45,7 @@ }; serial@12000 { - status = "ok"; + status = "okay"; }; sata@80000 { diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index 6c8d94beae78..fca31a5d5ac7 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -369,7 +369,7 @@ clocks = <&gate_clk 14>; clock-names = "sata"; #phy-cells = <0>; - status = "ok"; + status = "okay"; }; sata_phy1: sata-phy@84000 { @@ -378,7 +378,7 @@ clocks = <&gate_clk 15>; clock-names = "sata"; #phy-cells = <0>; - status = "ok"; + status = "okay"; }; audio0: audio-controller@a0000 { diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 827373ef1a54..007dd2bd0595 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -173,7 +173,7 @@ dcfg: dcfg@1ee0000 { compatible = "fsl,ls1021a-dcfg", "syscon"; - reg = <0x0 0x1ee0000 0x0 0x10000>; + reg = <0x0 0x1ee0000 0x0 0x1000>; big-endian; }; @@ -288,46 +288,43 @@ compatible = "fsl,qoriq-tmu"; reg = <0x0 0x1f00000 0x0 0x10000>; interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; - fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x30061>; - fsl,tmu-calibration = <0x00000000 0x0000000f - 0x00000001 0x00000017 - 0x00000002 0x0000001e - 0x00000003 0x00000026 - 0x00000004 0x0000002e - 0x00000005 0x00000035 - 0x00000006 0x0000003d - 0x00000007 0x00000044 - 0x00000008 0x0000004c - 0x00000009 0x00000053 - 0x0000000a 0x0000005b - 0x0000000b 0x00000064 - - 0x00010000 0x00000011 - 0x00010001 0x0000001c - 0x00010002 0x00000024 - 0x00010003 0x0000002b - 0x00010004 0x00000034 - 0x00010005 0x00000039 - 0x00010006 0x00000042 - 0x00010007 0x0000004c - 0x00010008 0x00000051 - 0x00010009 0x0000005a - 0x0001000a 0x00000063 - - 0x00020000 0x00000013 - 0x00020001 0x00000019 - 0x00020002 0x00000024 - 0x00020003 0x0000002c - 0x00020004 0x00000035 - 0x00020005 0x0000003d - 0x00020006 0x00000046 - 0x00020007 0x00000050 - 0x00020008 0x00000059 - - 0x00030000 0x00000002 - 0x00030001 0x0000000d - 0x00030002 0x00000019 - 0x00030003 0x00000024>; + fsl,tmu-range = <0xb0000 0x9002c 0x6004e 0x30066>; + fsl,tmu-calibration = <0x00000000 0x00000020 + 0x00000001 0x00000024 + 0x00000002 0x0000002a + 0x00000003 0x00000032 + 0x00000004 0x00000038 + 0x00000005 0x0000003e + 0x00000006 0x00000043 + 0x00000007 0x0000004a + 0x00000008 0x00000050 + 0x00000009 0x00000059 + 0x0000000a 0x0000005f + 0x0000000b 0x00000066 + + 0x00010000 0x00000023 + 0x00010001 0x0000002b + 0x00010002 0x00000033 + 0x00010003 0x0000003a + 0x00010004 0x00000042 + 0x00010005 0x0000004a + 0x00010006 0x00000054 + 0x00010007 0x0000005c + 0x00010008 0x00000065 + 0x00010009 0x0000006f + + 0x00020000 0x00000029 + 0x00020001 0x00000033 + 0x00020002 0x0000003d + 0x00020003 0x00000048 + 0x00020004 0x00000054 + 0x00020005 0x00000060 + 0x00020006 0x0000006c + + 0x00030000 0x00000025 + 0x00030001 0x00000033 + 0x00030002 0x00000043 + 0x00030003 0x00000055>; #thermal-sensor-cells = <1>; }; @@ -1013,7 +1010,7 @@ compatible = "fsl,ls1021a-ftm-alarm"; reg = <0x0 0x29d0000 0x0 0x10000>; reg-names = "ftm"; - fsl,rcpm-wakeup = <&rcpm 0x20000 0x0>; + fsl,rcpm-wakeup = <&rcpm 0x0 0x20000000>; interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; big-endian; }; diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts index 0c26467de4d0..5963566dbcc9 100644 --- a/arch/arm/boot/dts/meson8b-odroidc1.dts +++ b/arch/arm/boot/dts/meson8b-odroidc1.dts @@ -224,7 +224,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOH_4 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; diff --git a/arch/arm/boot/dts/meson8m2-mxiii-plus.dts b/arch/arm/boot/dts/meson8m2-mxiii-plus.dts index cc498191ddd1..8f4eb1ed4581 100644 --- a/arch/arm/boot/dts/meson8m2-mxiii-plus.dts +++ b/arch/arm/boot/dts/meson8m2-mxiii-plus.dts @@ -81,7 +81,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOH_4 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/motorola-mapphone-common.dtsi index 5f8f77cfbe59..f75806d0cd47 100644 --- a/arch/arm/boot/dts/motorola-mapphone-common.dtsi +++ b/arch/arm/boot/dts/motorola-mapphone-common.dtsi @@ -113,32 +113,9 @@ enable-active-high; }; - gpio_keys { - compatible = "gpio-keys"; - - volume_down { - label = "Volume Down"; - gpios = <&gpio5 26 GPIO_ACTIVE_LOW>; /* gpio154 */ - linux,code = <KEY_VOLUMEDOWN>; - linux,can-disable; - /* Value above 7.95ms for no GPIO hardware debounce */ - debounce-interval = <10>; - }; - - slider { - label = "Keypad Slide"; - gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>; /* gpio122 */ - linux,input-type = <EV_SW>; - linux,code = <SW_KEYPAD_SLIDE>; - linux,can-disable; - /* Value above 7.95ms for no GPIO hardware debounce */ - debounce-interval = <10>; - }; - }; - soundcard { compatible = "audio-graph-card"; - label = "Droid 4 Audio"; + label = "Mapphone Audio"; widgets = "Speaker", "Earpiece", @@ -282,80 +259,6 @@ }; }; -&keypad { - keypad,num-rows = <8>; - keypad,num-columns = <8>; - linux,keymap = < - - /* Row 1 */ - MATRIX_KEY(0, 2, KEY_1) - MATRIX_KEY(0, 6, KEY_2) - MATRIX_KEY(2, 3, KEY_3) - MATRIX_KEY(0, 7, KEY_4) - MATRIX_KEY(0, 4, KEY_5) - MATRIX_KEY(5, 5, KEY_6) - MATRIX_KEY(0, 1, KEY_7) - MATRIX_KEY(0, 5, KEY_8) - MATRIX_KEY(0, 0, KEY_9) - MATRIX_KEY(1, 6, KEY_0) - - /* Row 2 */ - MATRIX_KEY(3, 4, KEY_APOSTROPHE) - MATRIX_KEY(7, 6, KEY_Q) - MATRIX_KEY(7, 7, KEY_W) - MATRIX_KEY(7, 2, KEY_E) - MATRIX_KEY(1, 0, KEY_R) - MATRIX_KEY(4, 4, KEY_T) - MATRIX_KEY(1, 2, KEY_Y) - MATRIX_KEY(6, 7, KEY_U) - MATRIX_KEY(2, 2, KEY_I) - MATRIX_KEY(5, 6, KEY_O) - MATRIX_KEY(3, 7, KEY_P) - MATRIX_KEY(6, 5, KEY_BACKSPACE) - - /* Row 3 */ - MATRIX_KEY(5, 4, KEY_TAB) - MATRIX_KEY(5, 7, KEY_A) - MATRIX_KEY(2, 7, KEY_S) - MATRIX_KEY(7, 0, KEY_D) - MATRIX_KEY(2, 6, KEY_F) - MATRIX_KEY(6, 2, KEY_G) - MATRIX_KEY(6, 6, KEY_H) - MATRIX_KEY(1, 4, KEY_J) - MATRIX_KEY(3, 1, KEY_K) - MATRIX_KEY(2, 1, KEY_L) - MATRIX_KEY(4, 6, KEY_ENTER) - - /* Row 4 */ - MATRIX_KEY(3, 6, KEY_LEFTSHIFT) /* KEY_CAPSLOCK */ - MATRIX_KEY(6, 1, KEY_Z) - MATRIX_KEY(7, 4, KEY_X) - MATRIX_KEY(5, 1, KEY_C) - MATRIX_KEY(1, 7, KEY_V) - MATRIX_KEY(2, 4, KEY_B) - MATRIX_KEY(4, 1, KEY_N) - MATRIX_KEY(1, 1, KEY_M) - MATRIX_KEY(3, 5, KEY_COMMA) - MATRIX_KEY(5, 2, KEY_DOT) - MATRIX_KEY(6, 3, KEY_UP) - MATRIX_KEY(7, 3, KEY_OK) - - /* Row 5 */ - MATRIX_KEY(2, 5, KEY_LEFTCTRL) /* KEY_LEFTSHIFT */ - MATRIX_KEY(4, 5, KEY_LEFTALT) /* SYM */ - MATRIX_KEY(6, 0, KEY_MINUS) - MATRIX_KEY(4, 7, KEY_EQUAL) - MATRIX_KEY(1, 5, KEY_SPACE) - MATRIX_KEY(3, 2, KEY_SLASH) - MATRIX_KEY(4, 3, KEY_LEFT) - MATRIX_KEY(5, 3, KEY_DOWN) - MATRIX_KEY(3, 3, KEY_RIGHT) - - /* Side buttons, KEY_VOLUMEDOWN and KEY_PWER are on CPCAP? */ - MATRIX_KEY(5, 0, KEY_VOLUMEUP) - >; -}; - &mmc1 { vmmc-supply = <&vwlan2>; bus-width = <4>; @@ -395,34 +298,6 @@ }; }; -&i2c1 { - led-controller@38 { - compatible = "ti,lm3532"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x38>; - - enable-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>; - - ramp-up-us = <1024>; - ramp-down-us = <8193>; - - backlight_led: led@0 { - reg = <0>; - led-sources = <2>; - ti,led-mode = <0>; - label = ":backlight"; - }; - - led@1 { - reg = <1>; - led-sources = <1>; - ti,led-mode = <0>; - label = ":kbd_backlight"; - }; - }; -}; - &i2c2 { touchscreen@4a { compatible = "atmel,maxtouch"; @@ -796,20 +671,6 @@ "0", "0", "-1"; }; - - lis3dh: accelerometer@18 { - compatible = "st,lis3dh-accel"; - reg = <0x18>; - - vdd-supply = <&vhvio>; - - interrupt-parent = <&gpio2>; - interrupts = <2 IRQ_TYPE_EDGE_BOTH>; /* gpio34 */ - - rotation-matrix = "0", "-1", "0", - "1", "0", "0", - "0", "0", "1"; - }; }; &mcbsp2 { diff --git a/arch/arm/boot/dts/mstar-infinity.dtsi b/arch/arm/boot/dts/mstar-infinity.dtsi index cd911adef014..0bee517797f4 100644 --- a/arch/arm/boot/dts/mstar-infinity.dtsi +++ b/arch/arm/boot/dts/mstar-infinity.dtsi @@ -6,6 +6,13 @@ #include "mstar-v7.dtsi" +#include <dt-bindings/gpio/msc313-gpio.h> + &imi { reg = <0xa0000000 0x16000>; }; + +&gpio { + compatible = "mstar,msc313-gpio"; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/mstar-infinity2m-ssd202d-ssd201htv2.dts b/arch/arm/boot/dts/mstar-infinity2m-ssd202d-ssd201htv2.dts new file mode 100644 index 000000000000..5d81641414a2 --- /dev/null +++ b/arch/arm/boot/dts/mstar-infinity2m-ssd202d-ssd201htv2.dts @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 thingy.jp. + * Author: Daniel Palmer <daniel@thingy.jp> + */ + +/dts-v1/; +#include "mstar-infinity2m-ssd202d.dtsi" + +/ { + model = "SSD201_HT_V2"; + compatible = "honestar,ssd201htv2", "mstar,infinity2m"; + + aliases { + serial0 = &pm_uart; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&pm_uart { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/mstar-infinity2m-ssd202d.dtsi b/arch/arm/boot/dts/mstar-infinity2m-ssd202d.dtsi new file mode 100644 index 000000000000..176e10a29896 --- /dev/null +++ b/arch/arm/boot/dts/mstar-infinity2m-ssd202d.dtsi @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 thingy.jp. + * Author: Daniel Palmer <daniel@thingy.jp> + */ + +#include "mstar-infinity2m-ssd20xd.dtsi" + +/ { + memory { + device_type = "memory"; + reg = <0x20000000 0x8000000>; + }; +}; diff --git a/arch/arm/boot/dts/mstar-infinity2m-ssd20xd.dtsi b/arch/arm/boot/dts/mstar-infinity2m-ssd20xd.dtsi new file mode 100644 index 000000000000..7a5e28b33f96 --- /dev/null +++ b/arch/arm/boot/dts/mstar-infinity2m-ssd20xd.dtsi @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 thingy.jp. + * Author: Daniel Palmer <daniel@thingy.jp> + */ + +#include "mstar-infinity2m.dtsi" + +&smpctrl { + compatible = "sstar,ssd201-smpctrl", "mstar,smpctrl"; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/mstar-infinity2m.dtsi b/arch/arm/boot/dts/mstar-infinity2m.dtsi new file mode 100644 index 000000000000..6d4d1d224e96 --- /dev/null +++ b/arch/arm/boot/dts/mstar-infinity2m.dtsi @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 thingy.jp. + * Author: Daniel Palmer <daniel@thingy.jp> + */ + +#include "mstar-infinity.dtsi" + +&cpus { + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x1>; + }; +}; + +&riu { + smpctrl: smpctrl@204000 { + reg = <0x204000 0x200>; + status = "disabled"; + }; +}; diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi index f07880561e11..b0a21b0b731f 100644 --- a/arch/arm/boot/dts/mstar-v7.dtsi +++ b/arch/arm/boot/dts/mstar-v7.dtsi @@ -12,7 +12,7 @@ #size-cells = <1>; interrupt-parent = <&gic>; - cpus { + cpus: cpus { #address-cells = <1>; #size-cells = <0>; @@ -109,6 +109,16 @@ reg = <0x204400 0x200>; }; + gpio: gpio@207800 { + #gpio-cells = <2>; + reg = <0x207800 0x200>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&intc_fiq>; + status = "disabled"; + }; + pm_uart: uart@221000 { compatible = "ns16550a"; reg = <0x221000 0x100>; diff --git a/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi b/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi index d2d0761295a4..3696980a3da1 100644 --- a/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi +++ b/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi @@ -3,6 +3,8 @@ // Copyright 2018 Google, Inc. #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/nuvoton,npcm7xx-clock.h> +#include <dt-bindings/reset/nuvoton,npcm7xx-reset.h> / { #address-cells = <1>; @@ -63,12 +65,6 @@ interrupt-parent = <&gic>; ranges = <0x0 0xf0000000 0x00900000>; - gcr: gcr@800000 { - compatible = "nuvoton,npcm750-gcr", "syscon", - "simple-mfd"; - reg = <0x800000 0x1000>; - }; - scu: scu@3fe000 { compatible = "arm,cortex-a9-scu"; reg = <0x3fe000 0x1000>; @@ -80,7 +76,7 @@ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; cache-unified; cache-level = <2>; - clocks = <&clk 10>; + clocks = <&clk NPCM7XX_CLK_AXI>; arm,shared-override; }; @@ -91,6 +87,16 @@ reg = <0x3ff000 0x1000>, <0x3fe100 0x100>; }; + + gcr: gcr@800000 { + compatible = "nuvoton,npcm750-gcr", "syscon", "simple-mfd"; + reg = <0x800000 0x1000>; + }; + + rst: rst@801000 { + compatible = "nuvoton,npcm750-rst", "syscon", "simple-mfd"; + reg = <0x801000 0x6C>; + }; }; ahb { @@ -100,6 +106,12 @@ interrupt-parent = <&gic>; ranges; + rstc: rstc@f0801000 { + compatible = "nuvoton,npcm750-reset"; + reg = <0xf0801000 0x70>; + #reset-cells = <2>; + }; + clk: clock-controller@f0801000 { compatible = "nuvoton,npcm750-clk", "syscon"; #clock-cells = <1>; @@ -109,6 +121,63 @@ clocks = <&clk_refclk>, <&clk_sysbypck>, <&clk_mcbypck>; }; + gmac0: eth@f0802000 { + device_type = "network"; + compatible = "snps,dwmac"; + reg = <0xf0802000 0x2000>; + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; + ethernet = <0>; + clocks = <&clk_rg1refck>, <&clk NPCM7XX_CLK_AHB>; + clock-names = "stmmaceth", "clk_gmac"; + pinctrl-names = "default"; + pinctrl-0 = <&rg1_pins + &rg1mdio_pins>; + status = "disabled"; + }; + + ehci1: usb@f0806000 { + compatible = "nuvoton,npcm750-ehci"; + reg = <0xf0806000 0x1000>; + interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + fiu0: spi@fb000000 { + compatible = "nuvoton,npcm750-fiu"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfb000000 0x1000>; + reg-names = "control", "memory"; + clocks = <&clk NPCM7XX_CLK_SPI0>; + clock-names = "clk_spi0"; + status = "disabled"; + }; + + fiu3: spi@c0000000 { + compatible = "nuvoton,npcm750-fiu"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc0000000 0x1000>; + reg-names = "control", "memory"; + clocks = <&clk NPCM7XX_CLK_SPI3>; + clock-names = "clk_spi3"; + pinctrl-names = "default"; + pinctrl-0 = <&spi3_pins>; + status = "disabled"; + }; + + fiux: spi@fb001000 { + compatible = "nuvoton,npcm750-fiu"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfb001000 0x1000>; + reg-names = "control", "memory"; + clocks = <&clk NPCM7XX_CLK_SPIX>; + clock-names = "clk_spix"; + status = "disabled"; + }; + apb { #address-cells = <1>; #size-cells = <1>; @@ -116,11 +185,73 @@ interrupt-parent = <&gic>; ranges = <0x0 0xf0000000 0x00300000>; + lpc_kcs: lpc_kcs@7000 { + compatible = "nuvoton,npcm750-lpc-kcs", "simple-mfd", "syscon"; + reg = <0x7000 0x40>; + reg-io-width = <1>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x7000 0x40>; + + kcs1: kcs1@0 { + compatible = "nuvoton,npcm750-kcs-bmc"; + reg = <0x0 0x40>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; + kcs_chan = <1>; + status = "disabled"; + }; + + kcs2: kcs2@0 { + compatible = "nuvoton,npcm750-kcs-bmc"; + reg = <0x0 0x40>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; + kcs_chan = <2>; + status = "disabled"; + }; + + kcs3: kcs3@0 { + compatible = "nuvoton,npcm750-kcs-bmc"; + reg = <0x0 0x40>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; + kcs_chan = <3>; + status = "disabled"; + }; + }; + + spi0: spi@200000 { + compatible = "nuvoton,npcm750-pspi"; + reg = <0x200000 0x1000>; + pinctrl-names = "default"; + pinctrl-0 = <&pspi1_pins>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM7XX_CLK_APB5>; + clock-names = "clk_apb5"; + resets = <&rstc NPCM7XX_RESET_IPSRST2 NPCM7XX_RESET_PSPI1>; + status = "disabled"; + }; + + spi1: spi@201000 { + compatible = "nuvoton,npcm750-pspi"; + reg = <0x201000 0x1000>; + pinctrl-names = "default"; + pinctrl-0 = <&pspi2_pins>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM7XX_CLK_APB5>; + clock-names = "clk_apb5"; + resets = <&rstc NPCM7XX_RESET_IPSRST2 NPCM7XX_RESET_PSPI2>; + status = "disabled"; + }; + timer0: timer@8000 { compatible = "nuvoton,npcm750-timer"; interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x8000 0x50>; - clocks = <&clk 5>; + reg = <0x8000 0x1C>; + clocks = <&clk NPCM7XX_CLK_TIMER>; }; watchdog0: watchdog@801C { @@ -128,7 +259,7 @@ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; reg = <0x801C 0x4>; status = "disabled"; - clocks = <&clk 5>; + clocks = <&clk NPCM7XX_CLK_TIMER>; }; watchdog1: watchdog@901C { @@ -136,7 +267,7 @@ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; reg = <0x901C 0x4>; status = "disabled"; - clocks = <&clk 5>; + clocks = <&clk NPCM7XX_CLK_TIMER>; }; watchdog2: watchdog@a01C { @@ -144,13 +275,13 @@ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; reg = <0xa01C 0x4>; status = "disabled"; - clocks = <&clk 5>; + clocks = <&clk NPCM7XX_CLK_TIMER>; }; serial0: serial@1000 { compatible = "nuvoton,npcm750-uart"; reg = <0x1000 0x1000>; - clocks = <&clk 6>; + clocks = <&clk NPCM7XX_CLK_UART>; interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; status = "disabled"; @@ -159,7 +290,7 @@ serial1: serial@2000 { compatible = "nuvoton,npcm750-uart"; reg = <0x2000 0x1000>; - clocks = <&clk 6>; + clocks = <&clk NPCM7XX_CLK_UART>; interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; status = "disabled"; @@ -168,7 +299,7 @@ serial2: serial@3000 { compatible = "nuvoton,npcm750-uart"; reg = <0x3000 0x1000>; - clocks = <&clk 6>; + clocks = <&clk NPCM7XX_CLK_UART>; interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; status = "disabled"; @@ -177,11 +308,815 @@ serial3: serial@4000 { compatible = "nuvoton,npcm750-uart"; reg = <0x4000 0x1000>; - clocks = <&clk 6>; + clocks = <&clk NPCM7XX_CLK_UART>; interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; status = "disabled"; }; + + rng: rng@b000 { + compatible = "nuvoton,npcm750-rng"; + reg = <0xb000 0x8>; + status = "disabled"; + }; + + adc: adc@c000 { + compatible = "nuvoton,npcm750-adc"; + reg = <0xc000 0x8>; + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM7XX_CLK_ADC>; + resets = <&rstc NPCM7XX_RESET_IPSRST1 NPCM7XX_RESET_ADC>; + status = "disabled"; + }; + + pwm_fan: pwm-fan-controller@103000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nuvoton,npcm750-pwm-fan"; + reg = <0x103000 0x2000>, <0x180000 0x8000>; + reg-names = "pwm", "fan"; + clocks = <&clk NPCM7XX_CLK_APB3>, + <&clk NPCM7XX_CLK_APB4>; + clock-names = "pwm","fan"; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pins &pwm1_pins + &pwm2_pins &pwm3_pins + &pwm4_pins &pwm5_pins + &pwm6_pins &pwm7_pins + &fanin0_pins &fanin1_pins + &fanin2_pins &fanin3_pins + &fanin4_pins &fanin5_pins + &fanin6_pins &fanin7_pins + &fanin8_pins &fanin9_pins + &fanin10_pins &fanin11_pins + &fanin12_pins &fanin13_pins + &fanin14_pins &fanin15_pins>; + status = "disabled"; + }; + + i2c0: i2c@80000 { + reg = <0x80000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb0_pins>; + status = "disabled"; + }; + + i2c1: i2c@81000 { + reg = <0x81000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb1_pins>; + status = "disabled"; + }; + + i2c2: i2c@82000 { + reg = <0x82000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb2_pins>; + status = "disabled"; + }; + + i2c3: i2c@83000 { + reg = <0x83000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb3_pins>; + status = "disabled"; + }; + + i2c4: i2c@84000 { + reg = <0x84000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb4_pins>; + status = "disabled"; + }; + + i2c5: i2c@85000 { + reg = <0x85000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb5_pins>; + status = "disabled"; + }; + + i2c6: i2c@86000 { + reg = <0x86000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb6_pins>; + status = "disabled"; + }; + + i2c7: i2c@87000 { + reg = <0x87000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb7_pins>; + status = "disabled"; + }; + + i2c8: i2c@88000 { + reg = <0x88000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb8_pins>; + status = "disabled"; + }; + + i2c9: i2c@89000 { + reg = <0x89000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb9_pins>; + status = "disabled"; + }; + + i2c10: i2c@8a000 { + reg = <0x8a000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb10_pins>; + status = "disabled"; + }; + + i2c11: i2c@8b000 { + reg = <0x8b000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb11_pins>; + status = "disabled"; + }; + + i2c12: i2c@8c000 { + reg = <0x8c000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb12_pins>; + status = "disabled"; + }; + + i2c13: i2c@8d000 { + reg = <0x8d000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb13_pins>; + status = "disabled"; + }; + + i2c14: i2c@8e000 { + reg = <0x8e000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb14_pins>; + status = "disabled"; + }; + + i2c15: i2c@8f000 { + reg = <0x8f000 0x1000>; + compatible = "nuvoton,npcm750-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM7XX_CLK_APB2>; + interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb15_pins>; + status = "disabled"; + }; + }; + }; + + pinctrl: pinctrl@f0800000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "nuvoton,npcm750-pinctrl", "syscon", "simple-mfd"; + ranges = <0 0xf0010000 0x8000>; + gpio0: gpio@f0010000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x0 0x80>; + interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 0 32>; + }; + gpio1: gpio@f0011000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x1000 0x80>; + interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 32 32>; + }; + gpio2: gpio@f0012000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x2000 0x80>; + interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 64 32>; + }; + gpio3: gpio@f0013000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x3000 0x80>; + interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 96 32>; + }; + gpio4: gpio@f0014000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x4000 0x80>; + interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 128 32>; + }; + gpio5: gpio@f0015000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x5000 0x80>; + interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 160 32>; + }; + gpio6: gpio@f0016000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x6000 0x80>; + interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 192 32>; + }; + gpio7: gpio@f0017000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x7000 0x80>; + interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; + gpio-ranges = <&pinctrl 0 224 32>; + }; + + iox1_pins: iox1-pins { + groups = "iox1"; + function = "iox1"; + }; + iox2_pins: iox2-pins { + groups = "iox2"; + function = "iox2"; + }; + smb1d_pins: smb1d-pins { + groups = "smb1d"; + function = "smb1d"; + }; + smb2d_pins: smb2d-pins { + groups = "smb2d"; + function = "smb2d"; + }; + lkgpo1_pins: lkgpo1-pins { + groups = "lkgpo1"; + function = "lkgpo1"; + }; + lkgpo2_pins: lkgpo2-pins { + groups = "lkgpo2"; + function = "lkgpo2"; + }; + ioxh_pins: ioxh-pins { + groups = "ioxh"; + function = "ioxh"; + }; + gspi_pins: gspi-pins { + groups = "gspi"; + function = "gspi"; + }; + smb5b_pins: smb5b-pins { + groups = "smb5b"; + function = "smb5b"; + }; + smb5c_pins: smb5c-pins { + groups = "smb5c"; + function = "smb5c"; + }; + lkgpo0_pins: lkgpo0-pins { + groups = "lkgpo0"; + function = "lkgpo0"; + }; + pspi2_pins: pspi2-pins { + groups = "pspi2"; + function = "pspi2"; + }; + smb4den_pins: smb4den-pins { + groups = "smb4den"; + function = "smb4den"; + }; + smb4b_pins: smb4b-pins { + groups = "smb4b"; + function = "smb4b"; + }; + smb4c_pins: smb4c-pins { + groups = "smb4c"; + function = "smb4c"; + }; + smb15_pins: smb15-pins { + groups = "smb15"; + function = "smb15"; + }; + smb4d_pins: smb4d-pins { + groups = "smb4d"; + function = "smb4d"; + }; + smb14_pins: smb14-pins { + groups = "smb14"; + function = "smb14"; + }; + smb5_pins: smb5-pins { + groups = "smb5"; + function = "smb5"; + }; + smb4_pins: smb4-pins { + groups = "smb4"; + function = "smb4"; + }; + smb3_pins: smb3-pins { + groups = "smb3"; + function = "smb3"; + }; + spi0cs1_pins: spi0cs1-pins { + groups = "spi0cs1"; + function = "spi0cs1"; + }; + spi0cs2_pins: spi0cs2-pins { + groups = "spi0cs2"; + function = "spi0cs2"; + }; + spi0cs3_pins: spi0cs3-pins { + groups = "spi0cs3"; + function = "spi0cs3"; + }; + smb3c_pins: smb3c-pins { + groups = "smb3c"; + function = "smb3c"; + }; + smb3b_pins: smb3b-pins { + groups = "smb3b"; + function = "smb3b"; + }; + bmcuart0a_pins: bmcuart0a-pins { + groups = "bmcuart0a"; + function = "bmcuart0a"; + }; + uart1_pins: uart1-pins { + groups = "uart1"; + function = "uart1"; + }; + jtag2_pins: jtag2-pins { + groups = "jtag2"; + function = "jtag2"; + }; + bmcuart1_pins: bmcuart1-pins { + groups = "bmcuart1"; + function = "bmcuart1"; + }; + uart2_pins: uart2-pins { + groups = "uart2"; + function = "uart2"; + }; + bmcuart0b_pins: bmcuart0b-pins { + groups = "bmcuart0b"; + function = "bmcuart0b"; + }; + r1err_pins: r1err-pins { + groups = "r1err"; + function = "r1err"; + }; + r1md_pins: r1md-pins { + groups = "r1md"; + function = "r1md"; + }; + smb3d_pins: smb3d-pins { + groups = "smb3d"; + function = "smb3d"; + }; + fanin0_pins: fanin0-pins { + groups = "fanin0"; + function = "fanin0"; + }; + fanin1_pins: fanin1-pins { + groups = "fanin1"; + function = "fanin1"; + }; + fanin2_pins: fanin2-pins { + groups = "fanin2"; + function = "fanin2"; + }; + fanin3_pins: fanin3-pins { + groups = "fanin3"; + function = "fanin3"; + }; + fanin4_pins: fanin4-pins { + groups = "fanin4"; + function = "fanin4"; + }; + fanin5_pins: fanin5-pins { + groups = "fanin5"; + function = "fanin5"; + }; + fanin6_pins: fanin6-pins { + groups = "fanin6"; + function = "fanin6"; + }; + fanin7_pins: fanin7-pins { + groups = "fanin7"; + function = "fanin7"; + }; + fanin8_pins: fanin8-pins { + groups = "fanin8"; + function = "fanin8"; + }; + fanin9_pins: fanin9-pins { + groups = "fanin9"; + function = "fanin9"; + }; + fanin10_pins: fanin10-pins { + groups = "fanin10"; + function = "fanin10"; + }; + fanin11_pins: fanin11-pins { + groups = "fanin11"; + function = "fanin11"; + }; + fanin12_pins: fanin12-pins { + groups = "fanin12"; + function = "fanin12"; + }; + fanin13_pins: fanin13-pins { + groups = "fanin13"; + function = "fanin13"; + }; + fanin14_pins: fanin14-pins { + groups = "fanin14"; + function = "fanin14"; + }; + fanin15_pins: fanin15-pins { + groups = "fanin15"; + function = "fanin15"; + }; + pwm0_pins: pwm0-pins { + groups = "pwm0"; + function = "pwm0"; + }; + pwm1_pins: pwm1-pins { + groups = "pwm1"; + function = "pwm1"; + }; + pwm2_pins: pwm2-pins { + groups = "pwm2"; + function = "pwm2"; + }; + pwm3_pins: pwm3-pins { + groups = "pwm3"; + function = "pwm3"; + }; + r2_pins: r2-pins { + groups = "r2"; + function = "r2"; + }; + r2err_pins: r2err-pins { + groups = "r2err"; + function = "r2err"; + }; + r2md_pins: r2md-pins { + groups = "r2md"; + function = "r2md"; + }; + ga20kbc_pins: ga20kbc-pins { + groups = "ga20kbc"; + function = "ga20kbc"; + }; + smb5d_pins: smb5d-pins { + groups = "smb5d"; + function = "smb5d"; + }; + lpc_pins: lpc-pins { + groups = "lpc"; + function = "lpc"; + }; + espi_pins: espi-pins { + groups = "espi"; + function = "espi"; + }; + rg1_pins: rg1-pins { + groups = "rg1"; + function = "rg1"; + }; + rg1mdio_pins: rg1mdio-pins { + groups = "rg1mdio"; + function = "rg1mdio"; + }; + rg2_pins: rg2-pins { + groups = "rg2"; + function = "rg2"; + }; + ddr_pins: ddr-pins { + groups = "ddr"; + function = "ddr"; + }; + smb0_pins: smb0-pins { + groups = "smb0"; + function = "smb0"; + }; + smb1_pins: smb1-pins { + groups = "smb1"; + function = "smb1"; + }; + smb2_pins: smb2-pins { + groups = "smb2"; + function = "smb2"; + }; + smb2c_pins: smb2c-pins { + groups = "smb2c"; + function = "smb2c"; + }; + smb2b_pins: smb2b-pins { + groups = "smb2b"; + function = "smb2b"; + }; + smb1c_pins: smb1c-pins { + groups = "smb1c"; + function = "smb1c"; + }; + smb1b_pins: smb1b-pins { + groups = "smb1b"; + function = "smb1b"; + }; + smb8_pins: smb8-pins { + groups = "smb8"; + function = "smb8"; + }; + smb9_pins: smb9-pins { + groups = "smb9"; + function = "smb9"; + }; + smb10_pins: smb10-pins { + groups = "smb10"; + function = "smb10"; + }; + smb11_pins: smb11-pins { + groups = "smb11"; + function = "smb11"; + }; + sd1_pins: sd1-pins { + groups = "sd1"; + function = "sd1"; + }; + sd1pwr_pins: sd1pwr-pins { + groups = "sd1pwr"; + function = "sd1pwr"; + }; + pwm4_pins: pwm4-pins { + groups = "pwm4"; + function = "pwm4"; + }; + pwm5_pins: pwm5-pins { + groups = "pwm5"; + function = "pwm5"; + }; + pwm6_pins: pwm6-pins { + groups = "pwm6"; + function = "pwm6"; + }; + pwm7_pins: pwm7-pins { + groups = "pwm7"; + function = "pwm7"; + }; + mmc8_pins: mmc8-pins { + groups = "mmc8"; + function = "mmc8"; + }; + mmc_pins: mmc-pins { + groups = "mmc"; + function = "mmc"; + }; + mmcwp_pins: mmcwp-pins { + groups = "mmcwp"; + function = "mmcwp"; + }; + mmccd_pins: mmccd-pins { + groups = "mmccd"; + function = "mmccd"; + }; + mmcrst_pins: mmcrst-pins { + groups = "mmcrst"; + function = "mmcrst"; + }; + clkout_pins: clkout-pins { + groups = "clkout"; + function = "clkout"; + }; + serirq_pins: serirq-pins { + groups = "serirq"; + function = "serirq"; + }; + lpcclk_pins: lpcclk-pins { + groups = "lpcclk"; + function = "lpcclk"; + }; + scipme_pins: scipme-pins { + groups = "scipme"; + function = "scipme"; + }; + sci_pins: sci-pins { + groups = "sci"; + function = "sci"; + }; + smb6_pins: smb6-pins { + groups = "smb6"; + function = "smb6"; + }; + smb7_pins: smb7-pins { + groups = "smb7"; + function = "smb7"; + }; + pspi1_pins: pspi1-pins { + groups = "pspi1"; + function = "pspi1"; + }; + faninx_pins: faninx-pins { + groups = "faninx"; + function = "faninx"; + }; + r1_pins: r1-pins { + groups = "r1"; + function = "r1"; + }; + spi3_pins: spi3-pins { + groups = "spi3"; + function = "spi3"; + }; + spi3cs1_pins: spi3cs1-pins { + groups = "spi3cs1"; + function = "spi3cs1"; + }; + spi3quad_pins: spi3quad-pins { + groups = "spi3quad"; + function = "spi3quad"; + }; + spi3cs2_pins: spi3cs2-pins { + groups = "spi3cs2"; + function = "spi3cs2"; + }; + spi3cs3_pins: spi3cs3-pins { + groups = "spi3cs3"; + function = "spi3cs3"; + }; + nprd_smi_pins: nprd-smi-pins { + groups = "nprd_smi"; + function = "nprd_smi"; + }; + smb0b_pins: smb0b-pins { + groups = "smb0b"; + function = "smb0b"; + }; + smb0c_pins: smb0c-pins { + groups = "smb0c"; + function = "smb0c"; + }; + smb0den_pins: smb0den-pins { + groups = "smb0den"; + function = "smb0den"; + }; + smb0d_pins: smb0d-pins { + groups = "smb0d"; + function = "smb0d"; + }; + ddc_pins: ddc-pins { + groups = "ddc"; + function = "ddc"; + }; + rg2mdio_pins: rg2mdio-pins { + groups = "rg2mdio"; + function = "rg2mdio"; + }; + wdog1_pins: wdog1-pins { + groups = "wdog1"; + function = "wdog1"; + }; + wdog2_pins: wdog2-pins { + groups = "wdog2"; + function = "wdog2"; + }; + smb12_pins: smb12-pins { + groups = "smb12"; + function = "smb12"; + }; + smb13_pins: smb13-pins { + groups = "smb13"; + function = "smb13"; + }; + spix_pins: spix-pins { + groups = "spix"; + function = "spix"; + }; + spixcs1_pins: spixcs1-pins { + groups = "spixcs1"; + function = "spixcs1"; + }; + clkreq_pins: clkreq-pins { + groups = "clkreq"; + function = "clkreq"; + }; + hgpio0_pins: hgpio0-pins { + groups = "hgpio0"; + function = "hgpio0"; + }; + hgpio1_pins: hgpio1-pins { + groups = "hgpio1"; + function = "hgpio1"; + }; + hgpio2_pins: hgpio2-pins { + groups = "hgpio2"; + function = "hgpio2"; + }; + hgpio3_pins: hgpio3-pins { + groups = "hgpio3"; + function = "hgpio3"; + }; + hgpio4_pins: hgpio4-pins { + groups = "hgpio4"; + function = "hgpio4"; + }; + hgpio5_pins: hgpio5-pins { + groups = "hgpio5"; + function = "hgpio5"; + }; + hgpio6_pins: hgpio6-pins { + groups = "hgpio6"; + function = "hgpio6"; + }; + hgpio7_pins: hgpio7-pins { + groups = "hgpio7"; + function = "hgpio7"; }; }; }; diff --git a/arch/arm/boot/dts/nuvoton-npcm730-gsj-gpio.dtsi b/arch/arm/boot/dts/nuvoton-npcm730-gsj-gpio.dtsi new file mode 100644 index 000000000000..53cfd15fa03f --- /dev/null +++ b/arch/arm/boot/dts/nuvoton-npcm730-gsj-gpio.dtsi @@ -0,0 +1,477 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018 Nuvoton Technology tomer.maimon@nuvoton.com + +/ { + pinctrl: pinctrl@f0800000 { + gpio0pp_pins: gpio0pp-pins { + pins = "GPIO0/IOX1DI"; + bias-disable; + drive-push-pull; + }; + gpio1pp_pins: gpio1pp-pins { + pins = "GPIO1/IOX1LD"; + bias-disable; + drive-push-pull; + }; + gpio2pp_pins: gpio2pp-pins { + pins = "GPIO2/IOX1CK"; + bias-disable; + drive-push-pull; + }; + gpio3pp_pins: gpio3pp-pins { + pins = "GPIO3/IOX1D0"; + bias-disable; + drive-push-pull; + }; + gpio4pp_pins: gpio4pp-pins { + pins = "GPIO4/IOX2DI/SMB1DSDA"; + bias-disable; + drive-push-pull; + }; + gpio5pp_pins: gpio5pp-pins { + pins = "GPIO5/IOX2LD/SMB1DSCL"; + bias-disable; + drive-push-pull; + }; + gpio6pp_pins: gpio6pp-pins { + pins = "GPIO6/IOX2CK/SMB2DSDA"; + bias-disable; + drive-push-pull; + }; + gpio7pp_pins: gpio7pp-pins { + pins = "GPIO7/IOX2D0/SMB2DSCL"; + bias-disable; + drive-push-pull; + }; + gpio8_pins: gpio8-pins { + pins = "GPIO8/LKGPO1"; + bias-disable; + input-enable; + }; + gpio9_pins: gpio9-pins { + pins = "GPIO9/LKGPO2"; + bias-disable; + input-enable; + }; + gpio10pp_pins: gpio10pp-pins { + pins = "GPIO10/IOXHLD"; + bias-disable; + drive-push-pull; + }; + gpio11pp_pins: gpio11pp-pins { + pins = "GPIO11/IOXHCK"; + bias-disable; + drive-push-pull; + }; + gpio12_pins: gpio12-pins { + pins = "GPIO12/GSPICK/SMB5BSCL"; + bias-disable; + input-enable; + }; + gpio13_pins: gpio13-pins { + pins = "GPIO13/GSPIDO/SMB5BSDA"; + bias-disable; + input-enable; + }; + gpio14_pins: gpio14-pins { + pins = "GPIO14/GSPIDI/SMB5CSCL"; + bias-disable; + input-enable; + }; + gpio15od_pins: gpio15od-pins { + pins = "GPIO15/GSPICS/SMB5CSDA"; + bias-disable; + drive-open-drain; + }; + gpio17pp_pins: gpio17pp-pins { + pins = "GPIO17/PSPI2DI/SMB4DEN"; + bias-disable; + drive-push-pull; + }; + gpio18pp_pins: gpio18pp-pins { + pins = "GPIO18/PSPI2D0/SMB4BSDA"; + bias-disable; + drive-push-pull; + }; + gpio19pp_pins: gpio19pp-pins { + pins = "GPIO19/PSPI2CK/SMB4BSCL"; + bias-disable; + drive-push-pull; + }; + gpio24pp_pins: gpio24pp-pins { + pins = "GPIO24/IOXHDO"; + bias-disable; + drive-push-pull; + }; + gpio25pp_pins: gpio25pp-pins { + pins = "GPIO25/IOXHDI"; + bias-disable; + drive-push-pull; + }; + gpio37od_pins: gpio37od-pins { + pins = "GPIO37/SMB3CSDA"; + bias-disable; + drive-open-drain; + }; + gpio59pp_pins: gpio59pp-pins { + pins = "GPIO59/SMB3DSDA"; + bias-disable; + drive-push-pull; + }; + gpio60_pins: gpio60-pins { + pins = "GPIO60/SMB3DSCL"; + bias-disable; + input-enable; + }; + gpio72od_pins: gpio72od-pins { + pins = "GPIO72/FANIN8"; + bias-disable; + drive-open-drain; + }; + gpio73od_pins: gpio73od-pins { + pins = "GPIO73/FANIN9"; + bias-disable; + drive-open-drain; + }; + gpio74od_pins: gpio74od-pins { + pins = "GPIO74/FANIN10"; + bias-disable; + drive-open-drain; + }; + gpio75od_pins: gpio75od-pins { + pins = "GPIO75/FANIN11"; + bias-disable; + drive-open-drain; + }; + gpio76od_pins: gpio76od-pins { + pins = "GPIO76/FANIN12"; + bias-disable; + drive-open-drain; + }; + gpio77od_pins: gpio77od-pins { + pins = "GPIO77/FANIN13"; + bias-disable; + drive-open-drain; + }; + gpio78od_pins: gpio78od-pins { + pins = "GPIO78/FANIN14"; + bias-disable; + drive-open-drain; + }; + gpio79od_pins: gpio79od-pins { + pins = "GPIO79/FANIN15"; + bias-disable; + drive-open-drain; + }; + gpio83_pins: gpio83-pins { + pins = "GPIO83/PWM3"; + bias-disable; + input-enable; + }; + gpio84pp_pins: gpio84pp-pins { + pins = "GPIO84/R2TXD0"; + bias-disable; + drive-push-pull; + }; + gpio85pp_pins: gpio85pp-pins { + pins = "GPIO85/R2TXD1"; + bias-disable; + drive-push-pull; + }; + gpio86pp_pins: gpio86pp-pins { + pins = "GPIO86/R2TXEN"; + bias-disable; + drive-push-pull; + }; + gpio87pp_pins: gpio87pp-pins { + pins = "GPIO87/R2RXD0"; + bias-disable; + drive-push-pull; + }; + gpio88pp_pins: gpio88pp-pins { + pins = "GPIO88/R2RXD1"; + bias-disable; + drive-push-pull; + }; + gpio89pp_pins: gpio89pp-pins { + pins = "GPIO89/R2CRSDV"; + bias-disable; + drive-push-pull; + }; + gpio90pp_pins: gpio90pp-pins { + pins = "GPIO90/R2RXERR"; + bias-disable; + drive-push-pull; + }; + gpio91_pins: gpio91-pins { + pins = "GPIO91/R2MDC"; + bias-disable; + input-enable; + }; + gpio92_pins: gpio92-pins { + pins = "GPIO92/R2MDIO"; + bias-disable; + input-enable; + }; + gpio93pp_pins: gpio93pp-pins { + pins = "GPIO93/GA20/SMB5DSCL"; + bias-disable; + drive-push-pull; + }; + gpio94pp_pins: gpio94pp-pins { + pins = "GPIO94/nKBRST/SMB5DSDA"; + bias-disable; + drive-push-pull; + }; + gpio95_pins: gpio95-pins { + pins = "GPIO95/nLRESET/nESPIRST"; + bias-disable; + input-enable; + }; + gpio125pp_pins: gpio125pp-pins { + pins = "GPIO125/SMB1CSCL"; + bias-disable; + drive-push-pull; + }; + gpio126od_pins: gpio126od-pins { + pins = "GPIO126/SMB1BSDA"; + bias-disable; + drive-open-drain; + }; + gpio127od_pins: gpio127od-pins { + pins = "GPIO127/SMB1BSCL"; + bias-disable; + drive-open-drain; + }; + gpio136_pins: gpio136-pins { + pins = "GPIO136/SD1DT0"; + bias-disable; + input-enable; + }; + gpio137_pins: gpio137-pins { + pins = "GPIO137/SD1DT1"; + bias-disable; + input-enable; + }; + gpio141_pins: gpio141-pins { + pins = "GPIO141/SD1WP"; + bias-disable; + input-enable; + }; + gpio142od_pins: gpio142od-pins { + pins = "GPIO142/SD1CMD"; + bias-disable; + drive-open-drain; + }; + gpio143ol_pins: gpio143ol-pins { + pins = "GPIO143/SD1CD/SD1PWR"; + bias-disable; + output-low; + }; + gpio144_pins: gpio144-pins { + pins = "GPIO144/PWM4"; + bias-disable; + input-enable; + }; + gpio145_pins: gpio145-pins { + pins = "GPIO145/PWM5"; + bias-disable; + input-enable; + }; + gpio146_pins: gpio146-pins { + pins = "GPIO146/PWM6"; + bias-disable; + input-enable; + }; + gpio147_pins: gpio147-pins { + pins = "GPIO147/PWM7"; + bias-disable; + input-enable; + }; + gpio148_pins: gpio148-pins { + pins = "GPIO148/MMCDT4"; + bias-disable; + input-enable; + }; + gpio149_pins: gpio149-pins { + pins = "GPIO149/MMCDT5"; + bias-disable; + input-enable; + }; + gpio150_pins: gpio150-pins { + pins = "GPIO150/MMCDT6"; + bias-disable; + input-enable; + }; + gpio151_pins: gpio151-pins { + pins = "GPIO151/MMCDT7"; + bias-disable; + input-enable; + }; + gpio152_pins: gpio152-pins { + pins = "GPIO152/MMCCLK"; + bias-disable; + input-enable; + }; + gpio153_pins: gpio153-pins { + pins = "GPIO153/MMCWP"; + bias-disable; + input-enable; + }; + gpio154_pins: gpio154-pins { + pins = "GPIO154/MMCCMD"; + bias-disable; + input-enable; + }; + gpio155_pins: gpio155-pins { + pins = "GPIO155/nMMCCD/nMMCRST"; + bias-disable; + input-enable; + }; + gpio156_pins: gpio156-pins { + pins = "GPIO156/MMCDT0"; + bias-disable; + input-enable; + }; + gpio157_pins: gpio157-pins { + pins = "GPIO157/MMCDT1"; + bias-disable; + input-enable; + }; + gpio158_pins: gpio158-pins { + pins = "GPIO158/MMCDT2"; + bias-disable; + input-enable; + }; + gpio159_pins: gpio159-pins { + pins = "GPIO159/MMCDT3"; + bias-disable; + input-enable; + }; + gpio161_pins: gpio161-pins { + pins = "GPIO161/nLFRAME/nESPICS"; + bias-disable; + input-enable; + }; + gpio162_pins: gpio162-pins { + pins = "GPIO162/SERIRQ"; + bias-disable; + input-enable; + }; + gpio163_pins: gpio163-pins { + pins = "GPIO163/LCLK/ESPICLK"; + bias-disable; + input-enable; + }; + gpio164_pins: gpio164-pins { + pins = "GPIO164/LAD0/ESPI_IO0"; + bias-disable; + input-enable; + }; + gpio165_pins: gpio165-pins { + pins = "GPIO165/LAD1/ESPI_IO1"; + bias-disable; + input-enable; + }; + gpio166_pins: gpio166-pins { + pins = "GPIO166/LAD2/ESPI_IO2"; + bias-disable; + input-enable; + }; + gpio167_pins: gpio167-pins { + pins = "GPIO167/LAD3/ESPI_IO3"; + bias-disable; + input-enable; + }; + gpio168_pins: gpio168-pins { + pins = "GPIO168/nCLKRUN/nESPIALERT"; + bias-disable; + input-enable; + }; + gpio169_pins: gpio169-pins { + pins = "GPIO169/nSCIPME"; + bias-disable; + input-enable; + }; + gpio170_pins: gpio170-pins { + pins = "GPIO170/nSMI"; + bias-disable; + input-enable; + }; + gpio175od_pins: gpio175od-pins { + pins = "GPIO175/PSPI1CK/FANIN19"; + bias-disable; + drive-open-drain; + }; + gpio176od_pins: gpio176od-pins { + pins = "GPIO176/PSPI1DO/FANIN18"; + bias-disable; + drive-open-drain; + }; + gpio177_pins: gpio177-pins { + pins = "GPIO177/PSPI1DI/FANIN17"; + bias-disable; + input-enable; + }; + gpio190od_pins: gpio190od-pins { + pins = "GPIO190/nPRD_SMI"; + bias-disable; + drive-open-drain; + }; + gpio191_pins: gpio191-pins { + pins = "GPIO191"; + bias-disable; + input-enable; + }; + gpio192_pins: gpio192-pins { + pins = "GPIO192"; + bias-disable; + input-enable; + }; + gpio194pp_pins: gpio194pp-pins { + pins = "GPIO194/SMB0BSCL"; + bias-disable; + drive-push-pull; + }; + gpio195od_pins: gpio195od-pins { + pins = "GPIO195/SMB0BSDA"; + bias-disable; + drive-open-drain; + }; + gpio196od_pins: gpio196od-pins { + pins = "GPIO196/SMB0CSCL"; + bias-disable; + drive-open-drain; + }; + gpio197od_pins: gpio197od-pins { + pins = "GPIO197/SMB0DEN"; + bias-disable; + drive-open-drain; + }; + gpio198od_pins: gpio198od-pins { + pins = "GPIO198/SMB0DSDA"; + bias-disable; + drive-open-drain; + }; + gpio199od_pins: gpio199od-pins { + pins = "GPIO199/SMB0DSCL"; + bias-disable; + drive-open-drain; + }; + gpio200pp_pins: gpio200pp-pins { + pins = "GPIO200/R2CK"; + bias-disable; + drive-push-pull; + }; + gpio202od_pins: gpio202od-pins { + pins = "GPIO202/SMB0CSDA"; + bias-disable; + drive-open-drain; + }; + gpio203_pins: gpio203-pins { + pins = "GPIO203/FANIN16"; + bias-disable; + input-enable; + }; + }; +}; diff --git a/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts b/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts new file mode 100644 index 000000000000..d4ff49939a3d --- /dev/null +++ b/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts @@ -0,0 +1,490 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Quanta Computer lnc. Fran.Hsu@quantatw.com + +/dts-v1/; +#include "nuvoton-npcm730.dtsi" +#include "nuvoton-npcm730-gsj-gpio.dtsi" + +#include <dt-bindings/gpio/gpio.h> + +/ { + model = "Quanta GSJ Board (Device Tree v12)"; + compatible = "nuvoton,npcm750"; + + aliases { + ethernet1 = &gmac0; + serial3 = &serial3; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c8 = &i2c8; + i2c9 = &i2c9; + i2c10 = &i2c10; + i2c11 = &i2c11; + i2c12 = &i2c12; + i2c15 = &i2c15; + fiu0 = &fiu0; + }; + + chosen { + stdout-path = &serial3; + }; + + memory { + reg = <0 0x40000000>; + }; + + leds { + compatible = "gpio-leds"; + + led-bmc-live { + gpios = <&gpio4 15 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + + LED_U2_0_LOCATE { + gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_1_LOCATE { + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_2_LOCATE { + gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_3_LOCATE { + gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_4_LOCATE { + gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_5_LOCATE { + gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_BMC_TRAY_PWRGD { + gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_7_FAULT { + gpios = <&gpio6 8 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_6_LOCATE { + gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_7_LOCATE { + gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_0_FAULT { + gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_1_FAULT { + gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_2_FAULT { + gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_3_FAULT { + gpios = <&gpio2 23 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_4_FAULT { + gpios = <&gpio2 24 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_5_FAULT { + gpios = <&gpio2 25 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + LED_U2_6_FAULT { + gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; +}; + +&fiu0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0cs1_pins>; + status = "okay"; + + spi-nor@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + spi-rx-bus-width = <2>; + + partitions@80000000 { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + bmc@0{ + label = "bmc"; + reg = <0x000000 0x2000000>; + }; + u-boot@0 { + label = "u-boot"; + reg = <0x0000000 0x80000>; + read-only; + }; + u-boot-env@100000{ + label = "u-boot-env"; + reg = <0x00100000 0x40000>; + }; + kernel@200000 { + label = "kernel"; + reg = <0x0200000 0x600000>; + }; + rofs@800000 { + label = "rofs"; + reg = <0x800000 0x1400000>; + }; + rwfs@1c00000 { + label = "rwfs"; + reg = <0x1c00000 0x300000>; + }; + reserved@1f00000 { + label = "reserved"; + reg = <0x1f00000 0x100000>; + }; + }; + }; +}; + +&gmac0 { + phy-mode = "rgmii-id"; + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&watchdog1 { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&serial0 { + status = "okay"; +}; + +&serial1 { + status = "okay"; +}; + +&serial2 { + status = "okay"; +}; + +&serial3 { + status = "okay"; +}; + +&adc { + status = "okay"; +}; + +&i2c1 { + status = "okay"; + + lm75@5c { + compatible = "maxim,max31725"; + reg = <0x5c>; + status = "okay"; + }; +}; + +&i2c2 { + status = "okay"; + + lm75@5c { + compatible = "maxim,max31725"; + reg = <0x5c>; + status = "okay"; + }; +}; + +&i2c3 { + status = "okay"; + + lm75@5c { + compatible = "maxim,max31725"; + reg = <0x5c>; + }; +}; + +&i2c4 { + status = "okay"; + + lm75@5c { + compatible = "maxim,max31725"; + reg = <0x5c>; + }; +}; + +&i2c8 { + status = "okay"; +}; + +&i2c9 { + status = "okay"; + + eeprom@55 { + compatible = "atmel,24c64"; + reg = <0x55>; + }; +}; + +&i2c10 { + status = "okay"; + + eeprom@55 { + compatible = "atmel,24c64"; + reg = <0x55>; + }; +}; + +&i2c11 { + status = "okay"; + + /* P12V Quarter Brick DC/DC Power Module Q54SH12050 @60 */ + power-brick@36 { + compatible = "delta,dps800"; + reg = <0x36>; + }; + + hotswap@15 { + compatible = "ti,lm5066i"; + reg = <0x15>; + }; +}; + +&i2c12 { + status = "okay"; + + ucd90160@6b { + compatible = "ti,ucd90160"; + reg = <0x6b>; + }; +}; + +&i2c15 { + status = "okay"; + + i2c-switch@75 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + i2c-mux-idle-disconnect; + + i2c_u20: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + i2c_u21: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + i2c_u22: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + i2c_u23: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + i2c_u24: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + i2c_u25: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + i2c_u26: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + i2c_u27: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; +}; + +&pwm_fan { + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pins &pwm1_pins &pwm2_pins + &fanin0_pins &fanin1_pins + &fanin2_pins &fanin3_pins + &fanin4_pins &fanin5_pins>; + status = "okay"; + + fan@0 { + reg = <0x00>; + fan-tach-ch = /bits/ 8 <0x00 0x01>; + cooling-levels = <127 255>; + }; + + fan@1 { + reg = <0x01>; + fan-tach-ch = /bits/ 8 <0x02 0x03>; + cooling-levels = /bits/ 8 <127 255>; + }; + + fan@2 { + reg = <0x02>; + fan-tach-ch = /bits/ 8 <0x04 0x05>; + cooling-levels = /bits/ 8 <127 255>; + }; +}; + +&pinctrl { + pinctrl-names = "default"; + pinctrl-0 = < + /* GPI pins*/ + &gpio8_pins + &gpio9_pins + &gpio12_pins + &gpio13_pins + &gpio14_pins + &gpio60_pins + &gpio83_pins + &gpio91_pins + &gpio92_pins + &gpio95_pins + &gpio136_pins + &gpio137_pins + &gpio141_pins + &gpio144_pins + &gpio145_pins + &gpio146_pins + &gpio147_pins + &gpio148_pins + &gpio149_pins + &gpio150_pins + &gpio151_pins + &gpio152_pins + &gpio153_pins + &gpio154_pins + &gpio155_pins + &gpio156_pins + &gpio157_pins + &gpio158_pins + &gpio159_pins + &gpio161_pins + &gpio162_pins + &gpio163_pins + &gpio164_pins + &gpio165_pins + &gpio166_pins + &gpio167_pins + &gpio168_pins + &gpio169_pins + &gpio170_pins + &gpio177_pins + &gpio191_pins + &gpio192_pins + &gpio203_pins + /* GPO pins*/ + &gpio0pp_pins + &gpio1pp_pins + &gpio2pp_pins + &gpio3pp_pins + &gpio4pp_pins + &gpio5pp_pins + &gpio6pp_pins + &gpio7pp_pins + &gpio10pp_pins + &gpio11pp_pins + &gpio15od_pins + &gpio17pp_pins + &gpio18pp_pins + &gpio19pp_pins + &gpio24pp_pins + &gpio25pp_pins + &gpio37od_pins + &gpio59pp_pins + &gpio72od_pins + &gpio73od_pins + &gpio74od_pins + &gpio75od_pins + &gpio76od_pins + &gpio77od_pins + &gpio78od_pins + &gpio79od_pins + &gpio84pp_pins + &gpio85pp_pins + &gpio86pp_pins + &gpio87pp_pins + &gpio88pp_pins + &gpio89pp_pins + &gpio90pp_pins + &gpio93pp_pins + &gpio94pp_pins + &gpio125pp_pins + &gpio126od_pins + &gpio127od_pins + &gpio142od_pins + &gpio143ol_pins + &gpio175od_pins + &gpio176od_pins + &gpio190od_pins + &gpio194pp_pins + &gpio195od_pins + &gpio196od_pins + &gpio197od_pins + &gpio198od_pins + &gpio199od_pins + &gpio200pp_pins + &gpio202od_pins + >; +}; diff --git a/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts b/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts new file mode 100644 index 000000000000..82a104b2a65f --- /dev/null +++ b/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts @@ -0,0 +1,826 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2020 Fii USA Inc. + +/dts-v1/; +#include "nuvoton-npcm730.dtsi" + +#include <dt-bindings/gpio/gpio.h> + +/ { + model = "Fii Kudo Board"; + compatible = "fii,kudo", "nuvoton,npcm730"; + + aliases { + ethernet1 = &gmac0; + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + serial3 = &serial3; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; + i2c9 = &i2c9; + i2c10 = &i2c10; + i2c11 = &i2c11; + i2c12 = &i2c12; + i2c13 = &i2c13; + i2c14 = &i2c14; + i2c15 = &i2c15; + spi0 = &spi0; + spi1 = &spi1; + fiu0 = &fiu0; + fiu1 = &fiu3; + }; + + chosen { + stdout-path = &serial3; + }; + + memory { + reg = <0 0x40000000>; + }; + + iio-hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>, + <&adc 4>, <&adc 5>, <&adc 6>, <&adc 7>; + }; + + jtag_master { + compatible = "nuvoton,npcm750-jtag-master"; + #address-cells = <1>; + #size-cells = <1>; + + // dev/jtag0 + dev-num = <0>; + // pspi or gpio + mode = "pspi"; + + // pspi2 + pspi-controller = <2>; + reg = <0xf0201000 0x1000>; + interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM7XX_CLK_APB5>; + + // TCK, TDI, TDO, TMS + jtag-gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>, + <&gpio0 18 GPIO_ACTIVE_HIGH>, + <&gpio0 17 GPIO_ACTIVE_HIGH>, + <&gpio0 16 GPIO_ACTIVE_HIGH>; + }; + + leds { + compatible = "gpio-leds"; + heartbeat { + label = "heartbeat"; + gpios = <&gpio0 14 1>; + }; + }; + + pinctrl: pinctrl@f0800000 { + gpio61oh_pins: gpio61oh-pins { + pins = "GPO61/nDTR1_BOUT1/STRAP6"; + bias-disable; + output-high; + }; + gpio62oh_pins: gpio62oh-pins { + pins = "GPO62/nRTST1/STRAP5"; + bias-disable; + output-high; + }; + gpio161ol_pins: gpio161ol-pins { + pins = "GPIO161/nLFRAME/nESPICS"; + bias-disable; + output-low; + }; + gpio163i_pins: gpio163i-pins { + pins = "GPIO163/LCLK/ESPICLK"; + bias-disable; + input-enable; + }; + gpio167ol_pins: gpio167ol-pins { + pins = "GPIO167/LAD3/ESPI_IO3"; + bias-disable; + output-low; + }; + gpio95i_pins: gpio95i-pins { + pins = "GPIO95/nLRESET/nESPIRST"; + bias-disable; + input-enable; + }; + gpio65ol_pins: gpio65ol-pins { + pins = "GPIO65/FANIN1"; + bias-disable; + output-low; + }; + gpio66oh_pins: gpio66oh-pins { + pins = "GPIO66/FANIN2"; + bias-disable; + output-high; + }; + gpio67oh_pins: gpio67oh-pins { + pins = "GPIO67/FANIN3"; + bias-disable; + output-high; + }; + gpio68ol_pins: gpio68ol-pins { + pins = "GPIO68/FANIN4"; + bias-disable; + output-low; + }; + gpio69i_pins: gpio69i-pins { + pins = "GPIO69/FANIN5"; + bias-disable; + input-enable; + }; + gpio70ol_pins: gpio70ol-pins { + pins = "GPIO70/FANIN6"; + bias-disable; + output-low; + }; + gpio71i_pins: gpio71i-pins { + pins = "GPIO71/FANIN7"; + bias-disable; + input-enable; + }; + gpio72i_pins: gpio72i-pins { + pins = "GPIO72/FANIN8"; + bias-disable; + input-enable; + }; + gpio73i_pins: gpio73i-pins { + pins = "GPIO73/FANIN9"; + bias-disable; + input-enable; + }; + gpio74i_pins: gpio74i-pins { + pins = "GPIO74/FANIN10"; + bias-disable; + input-enable; + }; + gpio75i_pins: gpio75i-pins { + pins = "GPIO75/FANIN11"; + bias-disable; + input-enable; + }; + gpio76i_pins: gpio76i-pins { + pins = "GPIO76/FANIN12"; + bias-disable; + input-enable; + }; + gpio77i_pins: gpio77i-pins { + pins = "GPIO77/FANIN13"; + bias-disable; + input-enable; + }; + gpio78i_pins: gpio78i-pins { + pins = "GPIO78/FANIN14"; + bias-disable; + input-enable; + }; + gpio79ol_pins: gpio79ol-pins { + pins = "GPIO79/FANIN15"; + bias-disable; + output-low; + }; + gpio80oh_pins: gpio80oh-pins { + pins = "GPIO80/PWM0"; + bias-disable; + output-high; + }; + gpio81i_pins: gpio81i-pins { + pins = "GPIO81/PWM1"; + bias-disable; + input-enable; + }; + gpio82i_pins: gpio82i-pins { + pins = "GPIO82/PWM2"; + bias-disable; + input-enable; + }; + gpio83i_pins: gpio83i-pins { + pins = "GPIO83/PWM3"; + bias-disable; + input-enable; + }; + gpio144i_pins: gpio144i-pins { + pins = "GPIO144/PWM4"; + bias-disable; + input-enable; + }; + gpio145i_pins: gpio145i-pins { + pins = "GPIO145/PWM5"; + bias-disable; + input-enable; + }; + gpio146i_pins: gpio146i-pins { + pins = "GPIO146/PWM6"; + bias-disable; + input-enable; + }; + gpio147oh_pins: gpio147oh-pins { + pins = "GPIO147/PWM7"; + bias-disable; + output-high; + }; + gpio168ol_pins: gpio168ol-pins { + pins = "GPIO168/nCLKRUN/nESPIALERT"; + bias-disable; + output-low; + }; + gpio169oh_pins: gpio169oh-pins { + pins = "GPIO169/nSCIPME"; + bias-disable; + output-high; + }; + gpio170ol_pins: gpio170ol-pins { + pins = "GPIO170/nSMI"; + bias-disable; + output-low; + }; + gpio218oh_pins: gpio218oh-pins { + pins = "GPIO218/nWDO1"; + bias-disable; + output-high; + }; + gpio37i_pins: gpio37i-pins { + pins = "GPIO37/SMB3CSDA"; + bias-disable; + input-enable; + }; + gpio38i_pins: gpio38i-pins { + pins = "GPIO38/SMB3CSCL"; + bias-disable; + input-enable; + }; + gpio39i_pins: gpio39i-pins { + pins = "GPIO39/SMB3BSDA"; + bias-disable; + input-enable; + }; + gpio40i_pins: gpio40i-pins { + pins = "GPIO40/SMB3BSCL"; + bias-disable; + input-enable; + }; + gpio121i_pins: gpio121i-pins { + pins = "GPIO121/SMB2CSCL"; + bias-disable; + input-enable; + }; + gpio122i_pins: gpio122i-pins { + pins = "GPIO122/SMB2BSDA"; + bias-disable; + input-enable; + }; + gpio123i_pins: gpio123i-pins { + pins = "GPIO123/SMB2BSCL"; + bias-disable; + input-enable; + }; + gpio124i_pins: gpio124i-pins { + pins = "GPIO124/SMB1CSDA"; + bias-disable; + input-enable; + }; + gpio125i_pins: gpio125i-pins { + pins = "GPIO125/SMB1CSCL"; + bias-disable; + input-enable; + }; + gpio126i_pins: gpio126i-pins { + pins = "GPIO126/SMB1BSDA"; + bias-disable; + input-enable; + }; + gpio127i_pins: gpio127i-pins { + pins = "GPIO127/SMB1BSCL"; + bias-disable; + input-enable; + }; + gpio136i_pins: gpio136i-pins { + pins = "GPIO136/SD1DT0"; + bias-disable; + input-enable; + }; + gpio137oh_pins: gpio137oh-pins { + pins = "GPIO137/SD1DT1"; + bias-disable; + output-high; + }; + gpio138i_pins: gpio138i-pins { + pins = "GPIO138/SD1DT2"; + bias-disable; + input-enable; + }; + gpio139i_pins: gpio139i-pins { + pins = "GPIO139/SD1DT3"; + bias-disable; + input-enable; + }; + gpio140i_pins: gpio140i-pins { + pins = "GPIO140/SD1CLK"; + bias-disable; + input-enable; + }; + gpio141i_pins: gpio141i-pins { + pins = "GPIO141/SD1WP"; + bias-disable; + input-enable; + }; + gpio190oh_pins: gpio190oh-pins { + pins = "GPIO190/nPRD_SMI"; + bias-disable; + output-high; + }; + gpio191oh_pins: gpio191oh-pins { + pins = "GPIO191"; + bias-disable; + output-high; + }; + gpio195ol_pins: gpio195ol-pins { + pins = "GPIO195/SMB0BSDA"; + bias-disable; + output-low; + }; + gpio196ol_pins: gpio196ol-pins { + pins = "GPIO196/SMB0CSCL"; + bias-disable; + output-low; + }; + gpio199i_pins: gpio199i-pins { + pins = "GPIO199/SMB0DSCL"; + bias-disable; + input-enable; + }; + gpio202ol_pins: gpio202ol-pins { + pins = "GPIO202/SMB0CSDA"; + bias-disable; + output-low; + }; + }; +}; + +&gmac0 { + phy-mode = "rgmii-id"; + snps,eee-force-disable; + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&fiu0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0cs1_pins>; + status = "okay"; + spi-nor@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + spi-max-frequency = <5000000>; + spi-rx-bus-width = <2>; + label = "bmc"; + partitions@80000000 { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + u-boot@0 { + label = "u-boot"; + reg = <0x0000000 0xC0000>; + read-only; + }; + u-boot-env@100000{ + label = "u-boot-env"; + reg = <0x00100000 0x40000>; + }; + kernel@200000 { + label = "kernel"; + reg = <0x0200000 0x600000>; + }; + rofs@800000 { + label = "rofs"; + reg = <0x800000 0x3500000>; + }; + rwfs@3d00000 { + label = "rwfs"; + reg = <0x3d00000 0x300000>; + }; + }; + }; + spi-nor@1 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <1>; + spi-max-frequency = <5000000>; + spi-rx-bus-width = <2>; + partitions@88000000 { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + spare1@0 { + label = "spi0-cs1-spare1"; + reg = <0x0 0x800000>; + }; + spare2@800000 { + label = "spi0-cs1-spare2"; + reg = <0x800000 0x0>; + }; + }; + }; +}; + +&fiu3 { + pinctrl-0 = <&spi3_pins>; + spi-nor@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + spi-max-frequency = <5000000>; + spi-rx-bus-width = <2>; + partitions@A0000000 { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + system1@0 { + label = "bios"; + reg = <0x0 0x0>; + }; + system2@800000 { + label = "spi3-system2"; + reg = <0x800000 0x0>; + }; + }; + }; +}; + +&watchdog1 { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&serial0 { + status = "okay"; +}; + +&serial1 { + status = "okay"; +}; + +&serial2 { + status = "okay"; +}; + +&serial3 { + status = "okay"; +}; + +&adc { + #io-channel-cells = <1>; + status = "okay"; +}; + +&i2c1 { + status = "okay"; + i2c-switch@75 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + i2c-mux-idle-disconnect; + + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + + // Rear-Fan + max31790@58 { + compatible = "maxim,max31790"; + reg = <0x58>; + }; + }; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + // Mid-Fan + max31790@58 { + compatible = "maxim,max31790"; + reg = <0x58>; + }; + }; + + i2c-bus@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + + // INLET1_T + lm75@5c { + compatible = "ti,lm75"; + reg = <0x5c>; + }; + }; + + i2c-bus@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + + // OUTLET1_T + lm75@5c { + compatible = "ti,lm75"; + reg = <0x5c>; + }; + }; + + i2c-bus@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + + // OUTLET2_T + lm75@5c { + compatible = "ti,lm75"; + reg = <0x5c>; + }; + }; + + i2c-bus@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + + // OUTLET3_T + lm75@5c { + compatible = "ti,lm75"; + reg = <0x5c>; + }; + }; + }; + i2c-switch@77 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x77>; + i2c-mux-idle-disconnect; + + i2c-bus@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + + // STB-T + pmbus@74 { + compatible = "pmbus"; + reg = <0x74>; + }; + }; + }; +}; + +&i2c2 { + status = "okay"; + smpro@4f { + compatible = "ampere,smpro"; + reg = <0x4f>; + }; + + smpro@4e { + compatible = "ampere,smpro"; + reg = <0x4e>; + }; +}; + +&i2c3 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; + i2c-switch@77 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x77>; + i2c-mux-idle-disconnect; + + i2c-bus@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + // ADC sensors + adm1266@40 { + compatible = "adi,adm1266"; + reg = <0x40>; + }; + }; + + i2c-bus@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + // ADC sensors + adm1266@41 { + compatible = "adi,adm1266"; + reg = <0x41>; + }; + }; + }; +}; + +&i2c5 { + status = "okay"; +}; + +&i2c6 { + status = "okay"; +}; + +&i2c7 { + status = "okay"; +}; + +&i2c8 { + status = "okay"; +}; + +&i2c9 { + status = "okay"; +}; + +&i2c10 { + status = "okay"; +}; + +&i2c11 { + status = "okay"; +}; + +&i2c12 { + status = "okay"; + ssif-bmc@10 { + compatible = "ssif-bmc"; + reg = <0x10>; + }; +}; + +&i2c13 { + status = "okay"; + i2c-switch@77 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x77>; + i2c-mux-idle-disconnect; + + i2c-bus@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + // M2_ZONE_T + lm75@28 { + compatible = "ti,lm75"; + reg = <0x28>; + }; + }; + + i2c-bus@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + + // BATT_ZONE_T + lm75@29 { + compatible = "ti,lm75"; + reg = <0x29>; + }; + }; + + i2c-bus@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + + // NBM1_ZONE_T + lm75@28 { + compatible = "ti,lm75"; + reg = <0x28>; + }; + }; + i2c-bus@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + + // NBM2_ZONE_T + lm75@29 { + compatible = "ti,lm75"; + reg = <0x29>; + }; + }; + }; +}; + +&i2c14 { + status = "okay"; +}; + +&i2c15 { + status = "okay"; +}; + +&spi0 { + cs-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&pinctrl { + pinctrl-names = "default"; + pinctrl-0 = < + &gpio61oh_pins + &gpio62oh_pins + &gpio161ol_pins + &gpio163i_pins + &gpio167ol_pins + &gpio95i_pins + &gpio65ol_pins + &gpio66oh_pins + &gpio67oh_pins + &gpio68ol_pins + &gpio69i_pins + &gpio70ol_pins + &gpio71i_pins + &gpio72i_pins + &gpio73i_pins + &gpio74i_pins + &gpio75i_pins + &gpio76i_pins + &gpio77i_pins + &gpio78i_pins + &gpio79ol_pins + &gpio80oh_pins + &gpio81i_pins + &gpio82i_pins + &gpio83i_pins + &gpio144i_pins + &gpio145i_pins + &gpio146i_pins + &gpio147oh_pins + &gpio168ol_pins + &gpio169oh_pins + &gpio170ol_pins + &gpio218oh_pins + &gpio37i_pins + &gpio38i_pins + &gpio39i_pins + &gpio40i_pins + &gpio121i_pins + &gpio122i_pins + &gpio123i_pins + &gpio124i_pins + &gpio125i_pins + &gpio126i_pins + &gpio127i_pins + &gpio136i_pins + &gpio137oh_pins + &gpio138i_pins + &gpio139i_pins + &gpio140i_pins + &gpio141i_pins + &gpio190oh_pins + &gpio191oh_pins + &gpio195ol_pins + &gpio196ol_pins + &gpio199i_pins + &gpio202ol_pins + >; +}; + +&gcr { + serial_port_mux: mux-controller { + compatible = "mmio-mux"; + #mux-control-cells = <1>; + + mux-reg-masks = <0x38 0x07>; + idle-states = <2>; + }; +}; diff --git a/arch/arm/boot/dts/nuvoton-npcm730.dtsi b/arch/arm/boot/dts/nuvoton-npcm730.dtsi new file mode 100644 index 000000000000..86ec12ec2b50 --- /dev/null +++ b/arch/arm/boot/dts/nuvoton-npcm730.dtsi @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2020 Nuvoton Technology + +#include "nuvoton-common-npcm7xx.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&gic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + enable-method = "nuvoton,npcm750-smp"; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + clocks = <&clk NPCM7XX_CLK_CPU>; + clock-names = "clk_cpu"; + reg = <0>; + next-level-cache = <&l2>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + clocks = <&clk NPCM7XX_CLK_CPU>; + clock-names = "clk_cpu"; + reg = <1>; + next-level-cache = <&l2>; + }; + }; + + soc { + timer@3fe600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x3fe600 0x20>; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | + IRQ_TYPE_LEVEL_HIGH)>; + clocks = <&clk NPCM7XX_CLK_AHB>; + }; + }; +}; diff --git a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts index 15f744f1beea..9f13d08f5804 100644 --- a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts +++ b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts @@ -4,24 +4,161 @@ /dts-v1/; #include "nuvoton-npcm750.dtsi" +#include "dt-bindings/gpio/gpio.h" +#include "nuvoton-npcm750-pincfg-evb.dtsi" / { model = "Nuvoton npcm750 Development Board (Device Tree)"; compatible = "nuvoton,npcm750"; + aliases { + ethernet2 = &gmac0; + ethernet3 = &gmac1; + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + serial3 = &serial3; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; + i2c9 = &i2c9; + i2c10 = &i2c10; + i2c11 = &i2c11; + i2c12 = &i2c12; + i2c13 = &i2c13; + i2c14 = &i2c14; + i2c15 = &i2c15; + spi0 = &spi0; + spi1 = &spi1; + fiu0 = &fiu0; + fiu1 = &fiu3; + fiu2 = &fiux; + }; + chosen { stdout-path = &serial3; }; memory { - reg = <0 0x40000000>; + device_type = "memory"; + reg = <0x0 0x20000000>; + }; +}; + +&gmac0 { + phy-mode = "rgmii-id"; + status = "okay"; +}; + +&gmac1 { + phy-mode = "rgmii-id"; + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&fiu0 { + status = "okay"; + spi-nor@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + spi-rx-bus-width = <2>; + reg = <0>; + spi-max-frequency = <5000000>; + partitions@80000000 { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + bbuboot1@0 { + label = "bb-uboot-1"; + reg = <0x0000000 0x80000>; + read-only; + }; + bbuboot2@80000 { + label = "bb-uboot-2"; + reg = <0x0080000 0x80000>; + read-only; + }; + envparam@100000 { + label = "env-param"; + reg = <0x0100000 0x40000>; + read-only; + }; + spare@140000 { + label = "spare"; + reg = <0x0140000 0xC0000>; + }; + kernel@200000 { + label = "kernel"; + reg = <0x0200000 0x400000>; + }; + rootfs@600000 { + label = "rootfs"; + reg = <0x0600000 0x700000>; + }; + spare1@D00000 { + label = "spare1"; + reg = <0x0D00000 0x200000>; + }; + spare2@0F00000 { + label = "spare2"; + reg = <0x0F00000 0x200000>; + }; + spare3@1100000 { + label = "spare3"; + reg = <0x1100000 0x200000>; + }; + spare4@1300000 { + label = "spare4"; + reg = <0x1300000 0x0>; + }; + }; + }; +}; + +&fiu3 { + pinctrl-0 = <&spi3_pins>, <&spi3quad_pins>; + status = "okay"; + spi-nor@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + spi-rx-bus-width = <2>; + reg = <0>; + spi-max-frequency = <5000000>; + partitions@A0000000 { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + system1@0 { + label = "spi3-system1"; + reg = <0x0 0x0>; + }; + }; }; }; +&fiux { + spix-mode; +}; + &watchdog1 { status = "okay"; }; +&rng { + status = "okay"; +}; + &serial0 { status = "okay"; }; @@ -37,3 +174,231 @@ &serial3 { status = "okay"; }; + +&adc { + status = "okay"; +}; + +&lpc_kcs { + kcs1: kcs1@0 { + status = "okay"; + }; + + kcs2: kcs2@0 { + status = "okay"; + }; + + kcs3: kcs3@0 { + status = "okay"; + }; +}; + +/* lm75 on SVB */ +&i2c0 { + clock-frequency = <100000>; + status = "okay"; + lm75@48 { + compatible = "lm75"; + reg = <0x48>; + status = "okay"; + }; +}; + +/* lm75 on EB */ +&i2c1 { + clock-frequency = <100000>; + status = "okay"; + lm75@48 { + compatible = "lm75"; + reg = <0x48>; + status = "okay"; + }; +}; + +/* tmp100 on EB */ +&i2c2 { + clock-frequency = <100000>; + status = "okay"; + tmp100@48 { + compatible = "tmp100"; + reg = <0x48>; + status = "okay"; + }; +}; + +&i2c3 { + clock-frequency = <100000>; + status = "okay"; +}; + +&i2c5 { + clock-frequency = <100000>; + status = "okay"; +}; + +/* tmp100 on SVB */ +&i2c6 { + clock-frequency = <100000>; + status = "okay"; + tmp100@48 { + compatible = "tmp100"; + reg = <0x48>; + status = "okay"; + }; +}; + +&i2c7 { + clock-frequency = <100000>; + status = "okay"; +}; + +&i2c8 { + clock-frequency = <100000>; + status = "okay"; +}; + +&i2c9 { + clock-frequency = <100000>; + status = "okay"; +}; + +&i2c10 { + clock-frequency = <100000>; + status = "okay"; +}; + +&i2c11 { + clock-frequency = <100000>; + status = "okay"; +}; + +&i2c14 { + clock-frequency = <100000>; + status = "okay"; +}; + +&pwm_fan { + status = "okay"; + fan@0 { + reg = <0x00>; + fan-tach-ch = /bits/ 8 <0x00 0x01>; + cooling-levels = <127 255>; + }; + fan@1 { + reg = <0x01>; + fan-tach-ch = /bits/ 8 <0x02 0x03>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@2 { + reg = <0x02>; + fan-tach-ch = /bits/ 8 <0x04 0x05>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@3 { + reg = <0x03>; + fan-tach-ch = /bits/ 8 <0x06 0x07>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@4 { + reg = <0x04>; + fan-tach-ch = /bits/ 8 <0x08 0x09>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@5 { + reg = <0x05>; + fan-tach-ch = /bits/ 8 <0x0A 0x0B>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@6 { + reg = <0x06>; + fan-tach-ch = /bits/ 8 <0x0C 0x0D>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@7 { + reg = <0x07>; + fan-tach-ch = /bits/ 8 <0x0E 0x0F>; + cooling-levels = /bits/ 8 <127 255>; + }; +}; + +&spi0 { + cs-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>; + status = "okay"; + Flash@0 { + compatible = "winbond,w25q128", + "jedec,spi-nor"; + reg = <0x0>; + #address-cells = <1>; + #size-cells = <1>; + spi-max-frequency = <5000000>; + partition@0 { + label = "spi0_spare1"; + reg = <0x0000000 0x800000>; + }; + partition@1 { + label = "spi0_spare2"; + reg = <0x800000 0x0>; + }; + }; +}; + +&spi1 { + cs-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; + status = "okay"; + Flash@0 { + compatible = "winbond,w25q128fw", + "jedec,spi-nor"; + reg = <0x0>; + #address-cells = <1>; + #size-cells = <1>; + spi-max-frequency = <5000000>; + partition@0 { + label = "spi1_spare1"; + reg = <0x0000000 0x800000>; + }; + partition@1 { + label = "spi1_spare2"; + reg = <0x800000 0x0>; + }; + }; +}; + +&pinctrl { + pinctrl-names = "default"; + pinctrl-0 = < &iox1_pins + &pin8_input + &pin9_output_high + &pin10_input + &pin11_output_high + &pin16_input + &pin24_output_high + &pin25_output_low + &pin32_output_high + &jtag2_pins + &pin61_output_high + &pin62_output_high + &pin63_output_high + &lpc_pins + &pin160_input + &pin162_input + &pin168_input + &pin169_input + &pin170_input + &pin187_output_high + &pin190_input + &pin191_output_high + &pin192_output_high + &pin197_output_low + &ddc_pins + &pin218_input + &pin219_output_low + &pin220_output_low + &pin221_output_high + &pin222_input + &pin223_output_low + &spix_pins + &pin228_output_low + &pin231_output_high + &pin255_input>; +}; + diff --git a/arch/arm/boot/dts/nuvoton-npcm750-pincfg-evb.dtsi b/arch/arm/boot/dts/nuvoton-npcm750-pincfg-evb.dtsi new file mode 100644 index 000000000000..3b3806274adf --- /dev/null +++ b/arch/arm/boot/dts/nuvoton-npcm750-pincfg-evb.dtsi @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018 Nuvoton Technology + +/ { + pinctrl: pinctrl@f0800000 { + pin8_input: pin8-input { + pins = "GPIO8/LKGPO1"; + bias-disable; + input-enable; + }; + pin9_output_high: pin9-output-high { + pins = "GPIO9/LKGPO2"; + bias-disable; + output-high; + }; + pin10_input: pin10-input { + pins = "GPIO10/IOXHLD"; + bias-disable; + input-enable; + }; + pin11_output_high: pin11-output-high { + pins = "GPIO11/IOXHCK"; + bias-disable; + output-high; + }; + pin16_input: pin16-input { + pins = "GPIO16/LKGPO0"; + bias-disable; + input-enable; + }; + pin24_output_high: pin24-output-high { + pins = "GPIO24/IOXHDO"; + bias-disable; + output-high; + }; + pin25_output_low: pin25-output-low { + pins = "GPIO25/IOXHDI"; + bias-disable; + output-low; + }; + pin32_output_high: pin32-output-high { + pins = "GPIO32/nSPI0CS1"; + bias-disable; + output-high; + }; + pin61_output_high: pin61-output-high { + pins = "GPO61/nDTR1_BOUT1/STRAP6"; + bias-disable; + output-high; + }; + pin62_output_high: pin62-output-high { + pins = "GPO62/nRTST1/STRAP5"; + bias-disable; + output-high; + }; + pin63_output_high: pin63-output-high { + pins = "GPO63/TXD1/STRAP4"; + bias-disable; + output-high; + }; + pin160_input: pin160-input { + pins = "GPIO160/CLKOUT/RNGOSCOUT"; + bias-disable; + input-enable; + }; + pin162_input: pin162-input { + pins = "GPIO162/SERIRQ"; + bias-disable; + input-enable; + }; + pin168_input: pin168-input { + pins = "GPIO168/nCLKRUN/nESPIALERT"; + bias-disable; + input-enable; + }; + pin169_input: pin169-input { + pins = "GPIO169/nSCIPME"; + bias-disable; + input-enable; + }; + pin170_input: pin170-input { + pins = "GPIO170/nSMI"; + bias-disable; + input-enable; + }; + pin187_output_high: pin187-output-high { + pins = "GPIO187/nSPI3CS1"; + bias-disable; + output-high; + }; + pin190_input: pin190-input { + pins = "GPIO190/nPRD_SMI"; + bias-disable; + input-enable; + }; + pin191_output_high: pin191-output-high { + pins = "GPIO191"; + bias-disable; + output-high; + }; + pin192_output_high: pin192-output-high { + pins = "GPIO192"; + bias-disable; + output-high; + }; + pin197_output_low: pin197-output-low { + pins = "GPIO197/SMB0DEN"; + bias-disable; + output-low; + }; + pin218_input: pin218-input { + pins = "GPIO218/nWDO1"; + bias-disable; + input-enable; + }; + pin219_output_low: pin219-output-low { + pins = "GPIO219/nWDO2"; + bias-disable; + output-low; + }; + pin220_output_low: pin220-output-low { + pins = "GPIO220/SMB12SCL"; + bias-disable; + output-low; + }; + pin221_output_high: pin221-output-high { + pins = "GPIO221/SMB12SDA"; + bias-disable; + output-high; + }; + pin222_input: pin222-input { + pins = "GPIO222/SMB13SCL"; + bias-disable; + input-enable; + }; + pin223_output_low: pin223-output-low { + pins = "GPIO223/SMB13SDA"; + bias-disable; + output-low; + }; + pin228_output_low: pin228-output-low { + pins = "GPIO228/nSPIXCS1"; + bias-disable; + output-low; + }; + pin231_output_high: pin231-output-high { + pins = "GPIO230/SPIXD3"; + bias-disable; + output-high; + }; + pin255_input: pin255-input { + pins = "GPI255/DACOSEL"; + bias-disable; + input-enable; + }; + }; +}; diff --git a/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus-pincfg.dtsi b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus-pincfg.dtsi new file mode 100644 index 000000000000..230cb344b2e1 --- /dev/null +++ b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus-pincfg.dtsi @@ -0,0 +1,517 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Quanta Computer Inc. Samuel.Jiang@quantatw.com + +/ { + pinctrl: pinctrl@f0800000 { + gpio0ol_pins: gpio0ol-pins { + pins = "GPIO0/IOX1DI"; + bias-disable; + output-low; + }; + gpio1ol_pins: gpio1ol-pins { + pins = "GPIO1/IOX1LD"; + bias-disable; + output-low; + }; + gpio2ol_pins: gpio2ol-pins { + pins = "GPIO2/IOX1CK"; + bias-disable; + output-low; + }; + gpio3ol_pins: gpio3ol-pins { + pins = "GPIO3/IOX1D0"; + bias-disable; + output-low; + }; + gpio5_pins: gpio5-pins { + pins = "GPIO5/IOX2LD/SMB1DSCL"; + bias-disable; + input-enable; + }; + gpio6_pins: gpio6-pins { + pins = "GPIO6/IOX2CK/SMB2DSDA"; + bias-disable; + input-enable; + }; + gpio7_pins: gpio7-pins { + pins = "GPIO7/IOX2D0/SMB2DSCL"; + bias-disable; + input-enable; + }; + gpio8o_pins: gpio8o-pins { + pins = "GPIO8/LKGPO1"; + bias-disable; + output-high; + }; + gpio9ol_pins: gpio9ol-pins { + pins = "GPIO9/LKGPO2"; + bias-disable; + output-low; + }; + gpio10_pins: gpio10-pins { + pins = "GPIO10/IOXHLD"; + bias-disable; + input-enable; + }; + gpio11_pins: gpio11-pins { + pins = "GPIO11/IOXHCK"; + bias-disable; + input-enable; + }; + gpio12ol_pins: gpio12ol-pins { + pins = "GPIO12/GSPICK/SMB5BSCL"; + bias-disable; + output-low; + }; + gpio13ol_pins: gpio13ol-pins { + pins = "GPIO13/GSPIDO/SMB5BSDA"; + bias-disable; + output-low; + }; + gpio14ol_pins: gpio14ol-pins { + pins = "GPIO14/GSPIDI/SMB5CSCL"; + bias-disable; + output-low; + }; + gpio15ol_pins: gpio15ol-pins { + pins = "GPIO15/GSPICS/SMB5CSDA"; + bias-disable; + output-low; + }; + gpio20_pins: gpio20-pins { + pins = "GPIO20/SMB4CSDA/SMB15SDA"; + bias-disable; + input-enable; + }; + gpio21_pins: gpio21-pins { + pins = "GPIO21/SMB4CSCL/SMB15SCL"; + bias-disable; + input-enable; + }; + gpio22o_pins: gpio22o-pins { + pins = "GPIO22/SMB4DSDA/SMB14SDA"; + bias-disable; + output-high; + }; + gpio23_pins: gpio23-pins { + pins = "GPIO23/SMB4DSCL/SMB14SCL"; + bias-disable; + input-enable; + }; + gpio24_pins: gpio24-pins { + pins = "GPIO24/IOXHDO"; + bias-disable; + input-enable; + }; + gpio25_pins: gpio25-pins { + pins = "GPIO25/IOXHDI"; + bias-disable; + input-enable; + }; + gpio30_pins: gpio30-pins { + pins = "GPIO30/SMB3SDA"; + bias-disable; + input-enable; + }; + gpio31_pins: gpio31-pins { + pins = "GPIO31/SMB3SCL"; + bias-disable; + input-enable; + }; + gpio37o_pins: gpio37o-pins { + pins = "GPIO37/SMB3CSDA"; + bias-disable; + output-high; + }; + gpio38_pins: gpio38-pins { + pins = "GPIO38/SMB3CSCL"; + bias-disable; + input-enable; + }; + gpio39_pins: gpio39-pins { + pins = "GPIO39/SMB3BSDA"; + bias-disable; + input-enable; + }; + gpio40o_pins: gpio40o-pins { + pins = "GPIO40/SMB3BSCL"; + bias-disable; + output-high; + }; + gpio59_pins: gpio59-pins { + pins = "GPIO59/SMB3DSDA"; + bias-disable; + input-enable; + }; + gpio76_pins: gpio76-pins { + pins = "GPIO76/FANIN12"; + bias-disable; + input-enable; + }; + gpio77_pins: gpio77-pins { + pins = "GPIO77/FANIN13"; + bias-disable; + input-enable; + }; + gpio78o_pins: gpio78o-pins { + pins = "GPIO78/FANIN14"; + bias-disable; + output-high; + }; + gpio79_pins: gpio79-pins { + pins = "GPIO79/FANIN15"; + bias-disable; + input-enable; + }; + gpio82_pins: gpio82-pins { + pins = "GPIO82/PWM2"; + bias-disable; + input-enable; + }; + gpio83_pins: gpio83-pins { + pins = "GPIO83/PWM3"; + bias-disable; + input-enable; + }; + gpio84_pins: gpio84-pins { + pins = "GPIO84/R2TXD0"; + bias-disable; + input-enable; + }; + gpio85o_pins: gpio85o-pins { + pins = "GPIO85/R2TXD1"; + bias-disable; + output-high; + }; + gpio86ol_pins: gpio86ol-pins { + pins = "GPIO86/R2TXEN"; + bias-disable; + output-low; + }; + gpio87_pins: gpio87-pins { + pins = "GPIO87/R2RXD0"; + bias-disable; + input-enable; + }; + gpio88_pins: gpio88-pins { + pins = "GPIO88/R2RXD1"; + bias-disable; + input-enable; + }; + gpio89_pins: gpio89-pins { + pins = "GPIO89/R2CRSDV"; + bias-disable; + input-enable; + }; + gpio90_pins: gpio90-pins { + pins = "GPIO90/R2RXERR"; + bias-disable; + input-enable; + }; + gpio93_pins: gpio93-pins { + pins = "GPIO93/GA20/SMB5DSCL"; + bias-disable; + input-enable; + }; + gpio94ol_pins: gpio94ol-pins { + pins = "GPIO94/nKBRST/SMB5DSDA"; + bias-disable; + output-low; + }; + gpio108ol_pins: gpio108ol-pins { + pins = "GPIO108/RG1MDC"; + bias-disable; + output-low; + }; + gpio109ol_pins: gpio109ol-pins { + pins = "GPIO109/RG1MDIO"; + bias-disable; + output-low; + }; + gpio110ol_pins: gpio110ol-pins { + pins = "GPIO110/RG2TXD0/DDRV0"; + bias-disable; + output-low; + }; + gpio111ol_pins: gpio111ol-pins { + pins = "GPIO111/RG2TXD1/DDRV1"; + bias-disable; + output-low; + }; + gpio112ol_pins: gpio112ol-pins { + pins = "GPIO112/RG2TXD2/DDRV2"; + bias-disable; + output-low; + }; + gpio113ol_pins: gpio113ol-pins { + pins = "GPIO113/RG2TXD3/DDRV3"; + bias-disable; + output-low; + }; + gpio114o_pins: gpio114o-pins { + pins = "GPIO114/SMB0SCL"; + bias-disable; + output-high; + }; + gpio115_pins: gpio115-pins { + pins = "GPIO115/SMB0SDA"; + bias-disable; + input-enable; + }; + gpio120_pins: gpio120-pins { + pins = "GPIO120/SMB2CSDA"; + bias-disable; + input-enable; + }; + gpio121_pins: gpio121-pins { + pins = "GPIO121/SMB2CSCL"; + bias-disable; + input-enable; + }; + gpio122_pins: gpio122-pins { + pins = "GPIO122/SMB2BSDA"; + bias-disable; + input-enable; + }; + gpio123_pins: gpio123-pins { + pins = "GPIO123/SMB2BSCL"; + bias-disable; + input-enable; + }; + gpio124_pins: gpio124-pins { + pins = "GPIO124/SMB1CSDA"; + bias-disable; + input-enable; + }; + gpio125_pins: gpio125-pins { + pins = "GPIO125/SMB1CSCL"; + bias-disable; + input-enable; + }; + gpio126_pins: gpio126-pins { + pins = "GPIO126/SMB1BSDA"; + bias-disable; + input-enable; + }; + gpio127o_pins: gpio127o-pins { + pins = "GPIO127/SMB1BSCL"; + bias-disable; + output-high; + }; + gpio136_pins: gpio136-pins { + pins = "GPIO136/SD1DT0"; + bias-disable; + input-enable; + }; + gpio137_pins: gpio137-pins { + pins = "GPIO137/SD1DT1"; + bias-disable; + input-enable; + }; + gpio138_pins: gpio138-pins { + pins = "GPIO138/SD1DT2"; + bias-disable; + input-enable; + }; + gpio139_pins: gpio139-pins { + pins = "GPIO139/SD1DT3"; + bias-disable; + input-enable; + }; + gpio140_pins: gpio140-pins { + pins = "GPIO140/SD1CLK"; + bias-disable; + input-enable; + }; + gpio141_pins: gpio141-pins { + pins = "GPIO141/SD1WP"; + bias-disable; + input-enable; + }; + gpio142_pins: gpio142-pins { + pins = "GPIO142/SD1CMD"; + bias-disable; + input-enable; + }; + gpio143_pins: gpio143-pins { + pins = "GPIO143/SD1CD/SD1PWR"; + bias-disable; + input-enable; + }; + gpio144_pins: gpio144-pins { + pins = "GPIO144/PWM4"; + bias-disable; + input-enable; + }; + gpio145_pins: gpio145-pins { + pins = "GPIO145/PWM5"; + bias-disable; + input-enable; + }; + gpio146_pins: gpio146-pins { + pins = "GPIO146/PWM6"; + bias-disable; + input-enable; + }; + gpio147_pins: gpio147-pins { + pins = "GPIO147/PWM7"; + bias-disable; + input-enable; + }; + gpio153o_pins: gpio153o-pins { + pins = "GPIO153/MMCWP"; + bias-disable; + output-high; + }; + gpio155_pins: gpio155-pins { + pins = "GPIO155/nMMCCD/nMMCRST"; + bias-disable; + input-enable; + }; + gpio160o_pins: gpio160o-pins { + pins = "GPIO160/CLKOUT/RNGOSCOUT"; + bias-disable; + output-high; + }; + gpio169o_pins: gpio169o-pins { + pins = "GPIO169/nSCIPME"; + bias-disable; + output-high; + }; + gpio188o_pins: gpio188o-pins { + pins = "GPIO188/SPI3D2/nSPI3CS2"; + bias-disable; + output-high; + }; + gpio189_pins: gpio189-pins { + pins = "GPIO189/SPI3D3/nSPI3CS3"; + bias-disable; + input-enable; + }; + gpio196_pins: gpio196-pins { + pins = "GPIO196/SMB0CSCL"; + bias-disable; + input-enable; + }; + gpio197_pins: gpio197-pins { + pins = "GPIO197/SMB0DEN"; + bias-disable; + input-enable; + }; + gpio198o_pins: gpio198o-pins { + pins = "GPIO198/SMB0DSDA"; + bias-disable; + output-high; + }; + gpio199o_pins: gpio199o-pins { + pins = "GPIO199/SMB0DSCL"; + bias-disable; + output-high; + }; + gpio200_pins: gpio200-pins { + pins = "GPIO200/R2CK"; + input-enable; + bias-disable; + }; + gpio202_pins: gpio202-pins { + pins = "GPIO202/SMB0CSDA"; + bias-disable; + input-enable; + }; + gpio203o_pins: gpio203o-pins { + pins = "GPIO203/FANIN16"; + bias-disable; + output-high; + }; + gpio208_pins: gpio208-pins { + pins = "GPIO208/RG2TXC/DVCK"; + bias-disable; + input-enable; + }; + gpio209ol_pins: gpio209ol-pins { + pins = "GPIO209/RG2TXCTL/DDRV4"; + bias-disable; + output-low; + }; + gpio210ol_pins: gpio210ol-pins { + pins = "GPIO210/RG2RXD0/DDRV5"; + bias-disable; + output-low; + }; + gpio211ol_pins: gpio211ol-pins { + pins = "GPIO211/RG2RXD1/DDRV6"; + bias-disable; + output-low; + }; + gpio212ol_pins: gpio212ol-pins { + pins = "GPIO212/RG2RXD2/DDRV7"; + bias-disable; + output-low; + }; + gpio213ol_pins: gpio213ol-pins { + pins = "GPIO213/RG2RXD3/DDRV8"; + bias-disable; + output-low; + }; + gpio214ol_pins: gpio214ol-pins { + pins = "GPIO214/RG2RXC/DDRV9"; + bias-disable; + output-low; + }; + gpio215ol_pins: gpio215ol-pins { + pins = "GPIO215/RG2RXCTL/DDRV10"; + bias-disable; + output-low; + }; + gpio216ol_pins: gpio216ol-pins { + pins = "GPIO216/RG2MDC/DDRV11"; + bias-disable; + output-low; + }; + gpio217ol_pins: gpio217ol-pins { + pins = "GPIO217/RG2MDIO/DVHSYNC"; + bias-disable; + output-low; + }; + gpio224_pins: gpio224-pins { + pins = "GPIO224/SPIXCK"; + bias-disable; + input-enable; + }; + gpio225ol_pins: gpio225ol-pins { + pins = "GPO225/SPIXD0/STRAP12"; + bias-disable; + output-low; + }; + gpio226ol_pins: gpio226ol-pins { + pins = "GPO226/SPIXD1/STRAP13"; + bias-disable; + output-low; + }; + gpio227ol_pins: gpio227ol-pins { + pins = "GPIO227/nSPIXCS0"; + bias-disable; + output-low; + }; + gpio228o_pins: gpio228ol-pins { + pins = "GPIO228/nSPIXCS1"; + bias-disable; + output-high; + }; + gpio229o_pins: gpio229o-pins { + pins = "GPO229/SPIXD2/STRAP3"; + bias-disable; + output-high; + }; + gpio230_pins: gpio230-pins { + pins = "GPIO230/SPIXD3"; + bias-disable; + input-enable; + }; + gpio231o_pins: gpio231o-pins { + pins = "GPIO231/nCLKREQ"; + bias-disable; + output-high; + }; + }; +}; diff --git a/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts new file mode 100644 index 000000000000..767e0ac0df7c --- /dev/null +++ b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts @@ -0,0 +1,1052 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Nuvoton Technology <kwliu@nuvoton.com> +// Copyright (c) 2019 Quanta Computer Inc. <Samuel.Jiang@quantatw.com> + +/dts-v1/; +#include "nuvoton-npcm750.dtsi" +#include "nuvoton-npcm750-runbmc-olympus-pincfg.dtsi" + +#include <dt-bindings/i2c/i2c.h> +#include <dt-bindings/gpio/gpio.h> + +/ { + model = "Nuvoton npcm750 RunBMC Olympus"; + compatible = "nuvoton,npcm750"; + + aliases { + ethernet1 = &gmac0; + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + serial3 = &serial3; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; + i2c9 = &i2c9; + i2c10 = &i2c10; + i2c11 = &i2c11; + i2c12 = &i2c12; + i2c13 = &i2c13; + spi0 = &spi0; + spi1 = &spi1; + fiu0 = &fiu0; + fiu1 = &fiu3; + }; + + chosen { + stdout-path = &serial3; + }; + + memory { + reg = <0 0x40000000>; + }; + + iio-hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>, + <&adc 4>, <&adc 5>, <&adc 6>, <&adc 7>; + }; + + leds { + compatible = "gpio-leds"; + heartbeat { + label = "heartbeat"; + gpios = <&gpio3 14 1>; + }; + + identify { + label = "identify"; + gpios = <&gpio3 15 1>; + }; + }; + + jtag { + compatible = "nuvoton,npcm750-jtag"; + enable_pspi_jtag = <1>; + pspi-index = <2>; + tck { + label = "tck"; + gpios = <&gpio0 19 0>; /* gpio19 */ + regbase = <0xf0010000 0x1000>; + }; + + tdi { + label = "tdi"; + gpios = <&gpio0 18 0>; /* gpio18 */ + regbase = <0xf0010000 0x1000>; + }; + + tdo { + label = "tdo"; + gpios = <&gpio0 17 0>; /* gpio17 */ + regbase = <0xf0010000 0x1000>; + }; + tms { + label = "tms"; + gpios = <&gpio0 16 0>; /* gpio16 */ + regbase = <0xf0010000 0x1000>; + }; + }; +}; + +&fiu0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0cs1_pins>; + status = "okay"; + + spi-nor@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + spi-rx-bus-width = <2>; + + partitions@80000000 { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + bmc@0{ + label = "bmc"; + reg = <0x000000 0x2000000>; + }; + u-boot@0 { + label = "u-boot"; + reg = <0x0000000 0x80000>; + read-only; + }; + u-boot-env@100000{ + label = "u-boot-env"; + reg = <0x00100000 0x40000>; + }; + kernel@200000 { + label = "kernel"; + reg = <0x0200000 0x600000>; + }; + rofs@800000 { + label = "rofs"; + reg = <0x800000 0x1500000>; + }; + rwfs@1d00000 { + label = "rwfs"; + reg = <0x1d00000 0x300000>; + }; + }; + }; + + spi-nor@1 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <1>; + npcm,fiu-rx-bus-width = <2>; + + partitions@88000000 { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + spare1@0 { + label = "spi0-cs1-spare1"; + reg = <0x0 0x800000>; + }; + spare2@800000 { + label = "spi0-cs1-spare2"; + reg = <0x800000 0x0>; + }; + }; + }; +}; + +&fiu3 { + pinctrl-0 = <&spi3_pins>; + status = "okay"; + + spi-nor@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + spi-rx-bus-width = <2>; + + partitions@A0000000 { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + system1@0 { + label = "spi3-system1"; + reg = <0x0 0x800000>; + }; + system2@800000 { + label = "spi3-system2"; + reg = <0x800000 0x0>; + }; + }; + }; +}; + +&gcr { + mux-controller { + compatible = "mmio-mux"; + #mux-control-cells = <1>; + + mux-reg-masks = <0x38 0x07>; + idle-states = <6>; + }; +}; + +&gmac0 { + phy-mode = "rgmii-id"; + snps,eee-force-disable; + status = "okay"; +}; + +&i2c1 { + status = "okay"; + + i2c-switch@70 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x70>; + i2c-mux-idle-disconnect; + + i2c_slot1a: i2c-bus@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + i2c_slot1b: i2c-bus@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + i2c_slot2a: i2c-bus@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + i2c_slot2b: i2c-bus@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + i2c_slot3: i2c-bus@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + i2c_slot4: i2c-bus@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + i2c_slot5: i2c-bus@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + }; + + i2c-switch@71 { + compatible = "nxp,pca9546"; + reg = <0x71>; + #address-cells = <1>; + #size-cells = <0>; + i2c-mux-idle-disconnect; + + i2c_m2_s1: i2c-bus@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + i2c_m2_s2: i2c-bus@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + i2c_m2_s3: i2c-bus@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + i2c_m2_s4: i2c-bus@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + }; +}; + +&i2c2 { + status = "okay"; + + tmp421@4c { + compatible = "ti,tmp421"; + reg = <0x4c>; + }; + + power-supply@58 { + compatible = "delta,dps800"; + reg = <0x58>; + }; +}; + +&i2c3 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; + + eeprom@54 { + compatible = "atmel,24c64"; + reg = <0x54>; + }; +}; + +&i2c5 { + status = "okay"; + + i2c-slave-mqueue@10 { + compatible = "i2c-slave-mqueue"; + reg = <(I2C_OWN_SLAVE_ADDRESS | 0x10)>; + }; +}; + +&i2c6 { + status = "okay"; + + ina219@40 { + compatible = "ti,ina219"; + reg = <0x40>; + }; + ina219@41 { + compatible = "ti,ina219"; + reg = <0x41>; + }; + ina219@44 { + compatible = "ti,ina219"; + reg = <0x44>; + }; + ina219@45 { + compatible = "ti,ina219"; + reg = <0x45>; + }; + tps53679@60 { + compatible = "ti,tps53679"; + reg = <0x60>; + }; + tps53659@62 { + compatible = "ti,tps53659"; + reg = <0x62>; + }; + tps53659@64 { + compatible = "ti,tps53659"; + reg = <0x64>; + }; + tps53622@67 { + compatible = "ti,tps53622"; + reg = <0x67>; + }; + tps53622@69 { + compatible = "ti,tps53622"; + reg = <0x69>; + }; + tps53679@70 { + compatible = "ti,tps53679"; + reg = <0x70>; + }; + tps53659@72 { + compatible = "ti,tps53659"; + reg = <0x72>; + }; + tps53659@74 { + compatible = "ti,tps53659"; + reg = <0x74>; + }; + tps53622@77 { + compatible = "ti,tps53622"; + reg = <0x77>; + }; +}; + +&i2c7 { + status = "okay"; + + tmp421@4c { + compatible = "ti,tmp421"; + reg = <0x4c>; + }; +}; + +&i2c8 { + status = "okay"; + + adm1278@11 { + compatible = "adm1278"; + reg = <0x11>; + Rsense = <500>; + }; +}; + +&i2c9 { + status = "okay"; +}; + +&i2c10 { + status = "okay"; + + gpio: pca9555@27 { + compatible = "nxp,pca9555"; + reg = <0x27>; + + gpio-controller; + #gpio-cells = <2>; + }; +}; + +&i2c11 { + status = "okay"; + + pca9539_g1a: pca9539-g1a@74 { + compatible = "nxp,pca9539"; + reg = <0x74>; + gpio-controller; + #gpio-cells = <2>; + reset-gpios = <&gpio7 4 GPIO_ACTIVE_LOW>; + G1A_P0_0 { + gpio-hog; + gpios = <0 0>; + output-high; + line-name = "TPM_BMC_ALERT_N"; + }; + G1A_P0_1 { + gpio-hog; + gpios = <1 0>; + input; + line-name = "FM_BIOS_TOP_SWAP"; + }; + G1A_P0_2 { + gpio-hog; + gpios = <2 0>; + input; + line-name = "FM_BIOS_PREFRB2_GOOD"; + }; + G1A_P0_3 { + gpio-hog; + gpios = <3 0>; + input; + line-name = "BMC_SATAXPCIE_0TO3_SEL"; + }; + G1A_P0_4 { + gpio-hog; + gpios = <4 0>; + input; + line-name = "BMC_SATAXPCIE_4TO7_SEL"; + }; + G1A_P0_5 { + gpio-hog; + gpios = <5 0>; + output-low; + line-name = "FM_UV_ADR_TRIGGER_EN_N"; + }; + G1A_P0_6 { + gpio-hog; + gpios = <6 0>; + input; + line-name = "RM_THROTTLE_EN_N"; + }; + G1A_P1_0 { + gpio-hog; + gpios = <8 0>; + input; + line-name = "FM_BMC_TPM_PRES_N"; + }; + G1A_P1_1 { + gpio-hog; + gpios = <9 0>; + input; + line-name = "FM_CPU0_SKTOCC_LVT3_N"; + }; + G1A_P1_2 { + gpio-hog; + gpios = <10 0>; + input; + line-name = "FM_CPU1_SKTOCC_LVT3_N"; + }; + G1A_P1_3 { + gpio-hog; + gpios = <11 0>; + input; + line-name = "PSU1_ALERT_N"; + }; + G1A_P1_4 { + gpio-hog; + gpios = <12 0>; + input; + line-name = "PSU2_ALERT_N"; + }; + G1A_P1_5 { + gpio-hog; + gpios = <13 0>; + input; + line-name = "H_CPU0_FAST_WAKE_LVT3_N"; + }; + G1A_P1_6 { + gpio-hog; + gpios = <14 0>; + output-high; + line-name = "I2C_MUX1_RESET_N"; + }; + G1A_P1_7 { + gpio-hog; + gpios = <15 0>; + input; + line-name = "FM_CPU_CATERR_LVT3_N"; + }; + }; + + pca9539_g1b: pca9539-g1b@75 { + compatible = "nxp,pca9539"; + reg = <0x75>; + gpio-controller; + #gpio-cells = <2>; + G1B_P0_0 { + gpio-hog; + gpios = <0 0>; + input; + line-name = "PVDDQ_ABC_PINALERT_N"; + }; + G1B_P0_1 { + gpio-hog; + gpios = <1 0>; + input; + line-name = "PVDDQ_DEF_PINALERT_N"; + }; + G1B_P0_2 { + gpio-hog; + gpios = <2 0>; + input; + line-name = "PVDDQ_GHJ_PINALERT_N"; + }; + G1B_P0_3 { + gpio-hog; + gpios = <3 0>; + input; + line-name = "PVDDQ_KLM_PINALERT_N"; + }; + G1B_P0_5 { + gpio-hog; + gpios = <5 0>; + input; + line-name = "FM_BOARD_REV_ID0"; + }; + G1B_P0_6 { + gpio-hog; + gpios = <6 0>; + input; + line-name = "FM_BOARD_REV_ID1"; + }; + G1B_P0_7 { + gpio-hog; + gpios = <7 0>; + input; + line-name = "FM_BOARD_REV_ID2"; + }; + G1B_P1_0 { + gpio-hog; + gpios = <8 0>; + input; + line-name = "FM_OC_DETECT_EN_N"; + }; + G1B_P1_1 { + gpio-hog; + gpios = <9 0>; + input; + line-name = "FM_FLASH_DESC_OVERRIDE"; + }; + G1B_P1_2 { + gpio-hog; + gpios = <10 0>; + output-low; + line-name = "FP_PWR_ID_LED_N"; + }; + G1B_P1_3 { + gpio-hog; + gpios = <11 0>; + output-low; + line-name = "BMC_LED_PWR_GRN"; + }; + G1B_P1_4 { + gpio-hog; + gpios = <12 0>; + output-low; + line-name = "BMC_LED_PWR_AMBER"; + }; + G1B_P1_5 { + gpio-hog; + gpios = <13 0>; + output-high; + line-name = "FM_BMC_FAULT_LED_N"; + }; + G1B_P1_6 { + gpio-hog; + gpios = <14 0>; + output-high; + line-name = "FM_CPLD_BMC_PWRDN_N"; + }; + G1B_P1_7 { + gpio-hog; + gpios = <15 0>; + output-high; + line-name = "BMC_LED_CATERR_N"; + }; + }; +}; + +&i2c12 { + status = "okay"; + + pca9539_g2a: pca9539-g2a@74 { + compatible = "nxp,pca9539"; + reg = <0x74>; + gpio-controller; + #gpio-cells = <2>; + reset-gpios = <&gpio5 28 GPIO_ACTIVE_LOW>; + G2A_P0_0 { + gpio-hog; + gpios = <0 0>; + output-high; + line-name = "BMC_PON_RST_REQ_N"; + }; + G2A_P0_1 { + gpio-hog; + gpios = <1 0>; + output-high; + line-name = "BMC_RST_IND_REQ_N"; + }; + G2A_P0_2 { + gpio-hog; + gpios = <2 0>; + input; + line-name = "RST_BMC_RTCRST"; + }; + G2A_P0_3 { + gpio-hog; + gpios = <3 0>; + output-high; + line-name = "FM_BMC_PWRBTN_OUT_N"; + }; + G2A_P0_4 { + gpio-hog; + gpios = <4 0>; + output-high; + line-name = "RST_BMC_SYSRST_BTN_OUT_N"; + }; + G2A_P0_5 { + gpio-hog; + gpios = <5 0>; + output-high; + line-name = "FM_BATTERY_SENSE_EN_N"; + }; + G2A_P0_6 { + gpio-hog; + gpios = <6 0>; + output-high; + line-name = "FM_BMC_READY_N"; + }; + G2A_P0_7 { + gpio-hog; + gpios = <7 0>; + input; + line-name = "IRQ_BMC_PCH_SMI_LPC_N"; + }; + G2A_P1_0 { + gpio-hog; + gpios = <8 0>; + input; + line-name = "FM_SLOT4_CFG0"; + }; + G2A_P1_1 { + gpio-hog; + gpios = <9 0>; + input; + line-name = "FM_SLOT4_CFG1"; + }; + G2A_P1_2 { + gpio-hog; + gpios = <10 0>; + input; + line-name = "FM_NVDIMM_EVENT_N"; + }; + G2A_P1_3 { + gpio-hog; + gpios = <11 0>; + input; + line-name = "PSU1_BLADE_EN_N"; + }; + G2A_P1_4 { + gpio-hog; + gpios = <12 0>; + input; + line-name = "BMC_PCH_FNM"; + }; + G2A_P1_5 { + gpio-hog; + gpios = <13 0>; + input; + line-name = "FM_SOL_UART_CH_SEL"; + }; + G2A_P1_6 { + gpio-hog; + gpios = <14 0>; + input; + line-name = "FM_BIOS_POST_CMPLT_N"; + }; + }; + + pca9539_g2b: pca9539-g2b@75 { + compatible = "nxp,pca9539"; + reg = <0x75>; + gpio-controller; + #gpio-cells = <2>; + G2B_P0_0 { + gpio-hog; + gpios = <0 0>; + input; + line-name = "FM_CPU_MSMI_LVT3_N"; + }; + G2B_P0_1 { + gpio-hog; + gpios = <1 0>; + input; + line-name = "FM_BIOS_MRC_DEBUG_MSG_DIS"; + }; + G2B_P0_2 { + gpio-hog; + gpios = <2 0>; + input; + line-name = "FM_CPU1_DISABLE_BMC_N"; + }; + G2B_P0_3 { + gpio-hog; + gpios = <3 0>; + output-low; + line-name = "BMC_JTAG_SELECT"; + }; + G2B_P0_4 { + gpio-hog; + gpios = <4 0>; + output-high; + line-name = "PECI_MUX_SELECT"; + }; + G2B_P0_5 { + gpio-hog; + gpios = <5 0>; + output-high; + line-name = "I2C_MUX2_RESET_N"; + }; + G2B_P0_6 { + gpio-hog; + gpios = <6 0>; + input; + line-name = "FM_BMC_CPLD_PSU2_ON"; + }; + G2B_P0_7 { + gpio-hog; + gpios = <7 0>; + output-high; + line-name = "PSU2_ALERT_EN_N"; + }; + G2B_P1_0 { + gpio-hog; + gpios = <8 0>; + output-high; + line-name = "FM_CPU_BMC_INIT"; + }; + G2B_P1_1 { + gpio-hog; + gpios = <9 0>; + output-high; + line-name = "IRQ_BMC_PCH_SCI_LPC_N"; + }; + G2B_P1_2 { + gpio-hog; + gpios = <10 0>; + output-low; + line-name = "PMB_ALERT_EN_N"; + }; + G2B_P1_3 { + gpio-hog; + gpios = <11 0>; + output-high; + line-name = "FM_FAST_PROCHOT_EN_N"; + }; + G2B_P1_4 { + gpio-hog; + gpios = <12 0>; + output-high; + line-name = "BMC_NVDIMM_PRSNT_N"; + }; + G2B_P1_5 { + gpio-hog; + gpios = <13 0>; + output-low; + line-name = "FM_BACKUP_BIOS_SEL_H_BMC"; + }; + G2B_P1_6 { + gpio-hog; + gpios = <14 0>; + output-high; + line-name = "FM_PWRBRK_N"; + }; + }; +}; + +&i2c13 { + status = "okay"; + + tmp75@4a { + compatible = "ti,tmp75"; + reg = <0x4a>; + status = "okay"; + }; + m24128_fru@51 { + compatible = "atmel,24c128"; + reg = <0x51>; + pagesize = <64>; + status = "okay"; + }; +}; + +&pwm_fan { + pinctrl-names = "default"; + pinctrl-0 = < &pwm0_pins &pwm1_pins + &fanin0_pins &fanin1_pins + &fanin2_pins &fanin3_pins + &fanin4_pins &fanin5_pins + &fanin6_pins &fanin7_pins + &fanin8_pins &fanin9_pins + &fanin10_pins &fanin11_pins>; + status = "okay"; + + fan@0 { + reg = <0x00>; + fan-tach-ch = /bits/ 8 <0x00 0x01>; + cooling-levels = <127 255>; + }; + fan@1 { + reg = <0x01>; + fan-tach-ch = /bits/ 8 <0x02 0x03>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@2 { + reg = <0x02>; + fan-tach-ch = /bits/ 8 <0x04 0x05>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@3 { + reg = <0x03>; + fan-tach-ch = /bits/ 8 <0x06 0x07>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@4 { + reg = <0x04>; + fan-tach-ch = /bits/ 8 <0x08 0x09>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@5 { + reg = <0x05>; + fan-tach-ch = /bits/ 8 <0x0A 0x0B>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@6 { + reg = <0x06>; + fan-tach-ch = /bits/ 8 <0x0C 0x0D>; + cooling-levels = /bits/ 8 <127 255>; + }; + fan@7 { + reg = <0x07>; + fan-tach-ch = /bits/ 8 <0x0E 0x0F>; + cooling-levels = /bits/ 8 <127 255>; + }; +}; + +&ehci1 { + status = "okay"; +}; + +&watchdog1 { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&serial0 { + status = "okay"; +}; + +&serial1 { + status = "okay"; +}; + +&serial2 { + status = "okay"; +}; + +&serial3 { + status = "okay"; +}; + +&adc { + #io-channel-cells = <1>; + status = "okay"; +}; + +&kcs1 { + status = "okay"; +}; + +&kcs2 { + status = "okay"; +}; + +&kcs3 { + status = "okay"; +}; + +&spi0 { + cs-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&spi1 { + status = "okay"; +}; + +&pinctrl { + pinctrl-names = "default"; + pinctrl-0 = < + /******* RunBMC inside Module pins *******/ + &gpio0ol_pins + &gpio1ol_pins + &gpio2ol_pins + &gpio3ol_pins + &gpio8o_pins + &gpio9ol_pins + &gpio12ol_pins + &gpio13ol_pins + &gpio14ol_pins + &gpio15ol_pins + &gpio37o_pins + &gpio38_pins + &gpio39_pins + &gpio94ol_pins + &gpio108ol_pins + &gpio109ol_pins + &gpio111ol_pins + &gpio112ol_pins + &gpio113ol_pins + &gpio208_pins + &gpio209ol_pins + &gpio210ol_pins + &gpio211ol_pins + &gpio212ol_pins + &gpio213ol_pins + &gpio214ol_pins + &gpio215ol_pins + &gpio216ol_pins + &gpio217ol_pins + /******* RunBMC outside Connector pins *******/ + &gpio5_pins + &gpio6_pins + &gpio7_pins + &gpio10_pins + &gpio11_pins + &gpio20_pins + &gpio21_pins + &gpio22o_pins + &gpio23_pins + &gpio24_pins + &gpio25_pins + &gpio30_pins + &gpio31_pins + &gpio40o_pins + &gpio59_pins + &gpio76_pins + &gpio77_pins + &gpio78o_pins + &gpio79_pins + &gpio82_pins + &gpio83_pins + &gpio84_pins + &gpio85o_pins + &gpio86ol_pins + &gpio87_pins + &gpio88_pins + &gpio89_pins + &gpio90_pins + &gpio93_pins + &gpio114o_pins + &gpio115_pins + &gpio120_pins + &gpio121_pins + &gpio122_pins + &gpio123_pins + &gpio124_pins + &gpio125_pins + &gpio126_pins + &gpio127o_pins + &gpio136_pins + &gpio137_pins + &gpio138_pins + &gpio139_pins + &gpio140_pins + &gpio141_pins + &gpio142_pins + &gpio143_pins + &gpio144_pins + &gpio146_pins + &gpio145_pins + &gpio147_pins + &gpio153o_pins + &gpio155_pins + &gpio160o_pins + &gpio169o_pins + &gpio188o_pins + &gpio189_pins + &gpio196_pins + &gpio197_pins + &gpio198o_pins + &gpio199o_pins + &gpio200_pins + &gpio202_pins + &gpio203o_pins + &gpio224_pins + &gpio225ol_pins + &gpio226ol_pins + &gpio227ol_pins + &gpio228o_pins + &gpio229o_pins + &gpio230_pins + &gpio231o_pins + &ddc_pins + &wdog1_pins + &wdog2_pins + >; +}; diff --git a/arch/arm/boot/dts/nuvoton-npcm750.dtsi b/arch/arm/boot/dts/nuvoton-npcm750.dtsi index 6ac340533587..13eee0fe5642 100644 --- a/arch/arm/boot/dts/nuvoton-npcm750.dtsi +++ b/arch/arm/boot/dts/nuvoton-npcm750.dtsi @@ -17,7 +17,7 @@ cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a9"; - clocks = <&clk 0>; + clocks = <&clk NPCM7XX_CLK_CPU>; clock-names = "clk_cpu"; reg = <0>; next-level-cache = <&l2>; @@ -26,19 +26,37 @@ cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a9"; - clocks = <&clk 0>; + clocks = <&clk NPCM7XX_CLK_CPU>; clock-names = "clk_cpu"; reg = <1>; next-level-cache = <&l2>; }; }; + soc { timer@3fe600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x3fe600 0x20>; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; - clocks = <&clk 5>; + clocks = <&clk NPCM7XX_CLK_AHB>; + }; + }; + + ahb { + gmac1: eth@f0804000 { + device_type = "network"; + compatible = "snps,dwmac"; + reg = <0xf0804000 0x2000>; + interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; + ethernet = <1>; + clocks = <&clk_rg2refck>, <&clk NPCM7XX_CLK_AHB>; + clock-names = "stmmaceth", "clk_gmac"; + pinctrl-names = "default"; + pinctrl-0 = <&rg2_pins + &rg2mdio_pins>; + status = "disabled"; }; }; }; diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts index 252507cf300b..a858ebfa1500 100644 --- a/arch/arm/boot/dts/omap3-beagle-xm.dts +++ b/arch/arm/boot/dts/omap3-beagle-xm.dts @@ -34,26 +34,26 @@ clock-frequency = <26000000>; }; - leds { + led-controller-1 { compatible = "gpio-leds"; - heartbeat { + led-1 { label = "beagleboard::usr0"; gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>; /* 150 -> D6 LED */ linux,default-trigger = "heartbeat"; }; - mmc { + led-2 { label = "beagleboard::usr1"; gpios = <&gpio5 21 GPIO_ACTIVE_HIGH>; /* 149 -> D7 LED */ linux,default-trigger = "mmc0"; }; }; - pwmleds { + led-controller-2 { compatible = "pwm-leds"; - pmu_stat { + led-3 { label = "beagleboard::pmu_stat"; pwms = <&twl_pwmled 1 7812500>; max-brightness = <127>; diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi index 11d41e86f814..7dde9fbb06d3 100644 --- a/arch/arm/boot/dts/omap3-n950-n9.dtsi +++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi @@ -494,3 +494,11 @@ clock-names = "sysclk"; }; }; + +&aes1_target { + status = "disabled"; +}; + +&aes2_target { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/omap3-overo-base.dtsi b/arch/arm/boot/dts/omap3-overo-base.dtsi index 971d3e250515..006a6d97231c 100644 --- a/arch/arm/boot/dts/omap3-overo-base.dtsi +++ b/arch/arm/boot/dts/omap3-overo-base.dtsi @@ -14,10 +14,10 @@ reg = <0 0>; }; - pwmleds { + led-controller { compatible = "pwm-leds"; - overo { + led-1 { label = "overo:blue:COM"; pwms = <&twl_pwmled 1 7812500>; max-brightness = <127>; diff --git a/arch/arm/boot/dts/omap4-droid-bionic-xt875.dts b/arch/arm/boot/dts/omap4-droid-bionic-xt875.dts index ba5c35b7027d..ccf03a743678 100644 --- a/arch/arm/boot/dts/omap4-droid-bionic-xt875.dts +++ b/arch/arm/boot/dts/omap4-droid-bionic-xt875.dts @@ -7,3 +7,49 @@ model = "Motorola Droid Bionic XT875"; compatible = "motorola,droid-bionic", "ti,omap4430", "ti,omap4"; }; + +&keypad { + keypad,num-rows = <8>; + keypad,num-columns = <8>; + linux,keymap = < + MATRIX_KEY(5, 0, KEY_VOLUMEUP) + MATRIX_KEY(3, 0, KEY_VOLUMEDOWN) + >; +}; + +&i2c1 { + led-controller@38 { + compatible = "ti,lm3532"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x38>; + + enable-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>; + + ramp-up-us = <1024>; + ramp-down-us = <8193>; + + backlight_led: led@0 { + reg = <0>; + led-sources = <2>; + ti,led-mode = <0>; + label = ":backlight"; + }; + }; +}; + +&i2c4 { + kxtf9: accelerometer@f { + compatible = "kionix,kxtf9"; + reg = <0x0f>; + + vdd-supply = <&vhvio>; + + interrupt-parent = <&gpio2>; + interrupts = <2 IRQ_TYPE_EDGE_RISING>; + + rotation-matrix = "0", "-1", "0", + "1", "0", "0", + "0", "0", "1"; + }; +}; diff --git a/arch/arm/boot/dts/omap4-droid4-xt894.dts b/arch/arm/boot/dts/omap4-droid4-xt894.dts index c0d2fd92aea3..3ea4c5b9fd31 100644 --- a/arch/arm/boot/dts/omap4-droid4-xt894.dts +++ b/arch/arm/boot/dts/omap4-droid4-xt894.dts @@ -4,6 +4,149 @@ #include "motorola-mapphone-common.dtsi" / { + gpio_keys { + compatible = "gpio-keys"; + + volume_down { + label = "Volume Down"; + gpios = <&gpio5 26 GPIO_ACTIVE_LOW>; /* gpio154 */ + linux,code = <KEY_VOLUMEDOWN>; + linux,can-disable; + /* Value above 7.95ms for no GPIO hardware debounce */ + debounce-interval = <10>; + }; + + slider { + label = "Keypad Slide"; + gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>; /* gpio122 */ + linux,input-type = <EV_SW>; + linux,code = <SW_KEYPAD_SLIDE>; + linux,can-disable; + /* Value above 7.95ms for no GPIO hardware debounce */ + debounce-interval = <10>; + }; + }; +}; + +/ { model = "Motorola Droid 4 XT894"; compatible = "motorola,droid4", "ti,omap4430", "ti,omap4"; }; + +&keypad { + keypad,num-rows = <8>; + keypad,num-columns = <8>; + linux,keymap = < + + /* Row 1 */ + MATRIX_KEY(0, 2, KEY_1) + MATRIX_KEY(0, 6, KEY_2) + MATRIX_KEY(2, 3, KEY_3) + MATRIX_KEY(0, 7, KEY_4) + MATRIX_KEY(0, 4, KEY_5) + MATRIX_KEY(5, 5, KEY_6) + MATRIX_KEY(0, 1, KEY_7) + MATRIX_KEY(0, 5, KEY_8) + MATRIX_KEY(0, 0, KEY_9) + MATRIX_KEY(1, 6, KEY_0) + + /* Row 2 */ + MATRIX_KEY(3, 4, KEY_APOSTROPHE) + MATRIX_KEY(7, 6, KEY_Q) + MATRIX_KEY(7, 7, KEY_W) + MATRIX_KEY(7, 2, KEY_E) + MATRIX_KEY(1, 0, KEY_R) + MATRIX_KEY(4, 4, KEY_T) + MATRIX_KEY(1, 2, KEY_Y) + MATRIX_KEY(6, 7, KEY_U) + MATRIX_KEY(2, 2, KEY_I) + MATRIX_KEY(5, 6, KEY_O) + MATRIX_KEY(3, 7, KEY_P) + MATRIX_KEY(6, 5, KEY_BACKSPACE) + + /* Row 3 */ + MATRIX_KEY(5, 4, KEY_TAB) + MATRIX_KEY(5, 7, KEY_A) + MATRIX_KEY(2, 7, KEY_S) + MATRIX_KEY(7, 0, KEY_D) + MATRIX_KEY(2, 6, KEY_F) + MATRIX_KEY(6, 2, KEY_G) + MATRIX_KEY(6, 6, KEY_H) + MATRIX_KEY(1, 4, KEY_J) + MATRIX_KEY(3, 1, KEY_K) + MATRIX_KEY(2, 1, KEY_L) + MATRIX_KEY(4, 6, KEY_ENTER) + + /* Row 4 */ + MATRIX_KEY(3, 6, KEY_LEFTSHIFT) /* KEY_CAPSLOCK */ + MATRIX_KEY(6, 1, KEY_Z) + MATRIX_KEY(7, 4, KEY_X) + MATRIX_KEY(5, 1, KEY_C) + MATRIX_KEY(1, 7, KEY_V) + MATRIX_KEY(2, 4, KEY_B) + MATRIX_KEY(4, 1, KEY_N) + MATRIX_KEY(1, 1, KEY_M) + MATRIX_KEY(3, 5, KEY_COMMA) + MATRIX_KEY(5, 2, KEY_DOT) + MATRIX_KEY(6, 3, KEY_UP) + MATRIX_KEY(7, 3, KEY_OK) + + /* Row 5 */ + MATRIX_KEY(2, 5, KEY_LEFTCTRL) /* KEY_LEFTSHIFT */ + MATRIX_KEY(4, 5, KEY_LEFTALT) /* SYM */ + MATRIX_KEY(6, 0, KEY_MINUS) + MATRIX_KEY(4, 7, KEY_EQUAL) + MATRIX_KEY(1, 5, KEY_SPACE) + MATRIX_KEY(3, 2, KEY_SLASH) + MATRIX_KEY(4, 3, KEY_LEFT) + MATRIX_KEY(5, 3, KEY_DOWN) + MATRIX_KEY(3, 3, KEY_RIGHT) + + /* Side buttons, KEY_VOLUMEDOWN and KEY_PWER are on CPCAP? */ + MATRIX_KEY(5, 0, KEY_VOLUMEUP) + >; +}; + +&i2c1 { + led-controller@38 { + compatible = "ti,lm3532"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x38>; + + enable-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>; + + ramp-up-us = <1024>; + ramp-down-us = <8193>; + + backlight_led: led@0 { + reg = <0>; + led-sources = <2>; + ti,led-mode = <0>; + label = ":backlight"; + }; + + led@1 { + reg = <1>; + led-sources = <1>; + ti,led-mode = <0>; + label = ":kbd_backlight"; + }; + }; +}; + +&i2c4 { + lis3dh: accelerometer@18 { + compatible = "st,lis3dh-accel"; + reg = <0x18>; + + vdd-supply = <&vhvio>; + + interrupt-parent = <&gpio2>; + interrupts = <2 IRQ_TYPE_EDGE_BOTH>; /* gpio34 */ + + rotation-matrix = "0", "-1", "0", + "1", "0", "0", + "0", "0", "1"; + }; +}; diff --git a/arch/arm/boot/dts/omap4-kc1.dts b/arch/arm/boot/dts/omap4-kc1.dts index 31d856b58f8a..e59d17b25a1d 100644 --- a/arch/arm/boot/dts/omap4-kc1.dts +++ b/arch/arm/boot/dts/omap4-kc1.dts @@ -15,16 +15,16 @@ reg = <0x80000000 0x20000000>; /* 512 MB */ }; - pwmleds { + led-controller { compatible = "pwm-leds"; - green { + led-1 { label = "green"; pwms = <&twl_pwm 0 7812500>; max-brightness = <127>; }; - orange { + led-2 { label = "orange"; pwms = <&twl_pwm 1 7812500>; max-brightness = <127>; diff --git a/arch/arm/boot/dts/omap4-l4.dtsi b/arch/arm/boot/dts/omap4-l4.dtsi index de742bf84efb..e0bb60a30779 100644 --- a/arch/arm/boot/dts/omap4-l4.dtsi +++ b/arch/arm/boot/dts/omap4-l4.dtsi @@ -330,6 +330,7 @@ /* Domains (V, P, C): iva, tesla_pwrdm, tesla_clkdm */ clocks = <&tesla_clkctrl OMAP4_DSP_CLKCTRL 0>; clock-names = "fck"; + power-domains = <&prm_tesla>; resets = <&prm_tesla 1>; reset-names = "rstctrl"; #address-cells = <1>; diff --git a/arch/arm/boot/dts/omap4-panda-es.dts b/arch/arm/boot/dts/omap4-panda-es.dts index cfa85aa3da08..7c6886cd738f 100644 --- a/arch/arm/boot/dts/omap4-panda-es.dts +++ b/arch/arm/boot/dts/omap4-panda-es.dts @@ -46,7 +46,23 @@ button_pins: pinmux_button_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x11b, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */ + OMAP4_IOPAD(0x0fc, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */ + >; + }; + + bt_pins: pinmux_bt_pins { + pinctrl-single,pins = < + OMAP4_IOPAD(0x06c, PIN_OUTPUT | MUX_MODE3) /* gpmc_a22.gpio_46 - BTEN */ + OMAP4_IOPAD(0x072, PIN_OUTPUT_PULLUP | MUX_MODE3) /* gpmc_a25.gpio_49 - BTWAKEUP */ + >; + }; + + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + OMAP4_IOPAD(0x118, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts - HCI */ + OMAP4_IOPAD(0x11a, PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */ + OMAP4_IOPAD(0x11c, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_rx.uart2_rx */ + OMAP4_IOPAD(0x11e, PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */ >; }; }; @@ -80,3 +96,19 @@ &gpio1_target { ti,no-reset-on-init; }; + +&wl12xx_gpio { + pinctrl-single,pins = < + OMAP4_IOPAD(0x066, PIN_OUTPUT | MUX_MODE3) /* gpmc_a19.gpio_43 */ + OMAP4_IOPAD(0x070, PIN_OUTPUT_PULLUP | MUX_MODE3) /* gpmc_a24.gpio_48 */ + >; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins &bt_pins>; + bluetooth: tiwi { + compatible = "ti,wl1271-st"; + enable-gpios = <&gpio2 14 GPIO_ACTIVE_HIGH>; /* GPIO_46 */ + }; +}; diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts index afb49a2d6963..9e976140f34a 100644 --- a/arch/arm/boot/dts/omap4-sdp.dts +++ b/arch/arm/boot/dts/omap4-sdp.dts @@ -45,58 +45,60 @@ regulator-boot-on; }; - leds { + led-controller-1 { compatible = "gpio-leds"; - debug0 { + + led-1 { label = "omap4:green:debug0"; gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>; /* 61 */ }; - debug1 { + led-2 { label = "omap4:green:debug1"; gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>; /* 30 */ }; - debug2 { + led-3 { label = "omap4:green:debug2"; gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; /* 7 */ }; - debug3 { + led-4 { label = "omap4:green:debug3"; gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; /* 8 */ }; - debug4 { + led-5 { label = "omap4:green:debug4"; gpios = <&gpio2 18 GPIO_ACTIVE_HIGH>; /* 50 */ }; - user1 { + led-6 { label = "omap4:blue:user"; gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>; /* 169 */ }; - user2 { + led-7 { label = "omap4:red:user"; gpios = <&gpio6 10 GPIO_ACTIVE_HIGH>; /* 170 */ }; - user3 { + led-8 { label = "omap4:green:user"; gpios = <&gpio5 11 GPIO_ACTIVE_HIGH>; /* 139 */ }; }; - pwmleds { + led-controller-2 { compatible = "pwm-leds"; - kpad { + + led-9 { label = "omap4::keypad"; pwms = <&twl_pwm 0 7812500>; max-brightness = <127>; }; - charging { + led-10 { label = "omap4:green:chrg"; pwms = <&twl_pwmled 0 7812500>; max-brightness = <255>; diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index d6475cc6a91a..72e4f6481776 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -107,11 +107,6 @@ ti,hwmods = "mpu"; sram = <&ocmcram>; }; - - iva { - compatible = "ti,ivahd"; - ti,hwmods = "iva"; - }; }; /* @@ -150,24 +145,41 @@ reg = <0x40304000 0xa000>; /* 40k */ }; - gpmc: gpmc@50000000 { - compatible = "ti,omap4430-gpmc"; - reg = <0x50000000 0x1000>; - #address-cells = <2>; - #size-cells = <1>; - interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; - dmas = <&sdma 4>; - dma-names = "rxtx"; - gpmc,num-cs = <8>; - gpmc,num-waitpins = <4>; - ti,hwmods = "gpmc"; + target-module@50000000 { + compatible = "ti,sysc-omap2", "ti,sysc"; + reg = <0x50000000 4>, + <0x50000010 4>, + <0x50000014 4>; + reg-names = "rev", "sysc", "syss"; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,syss-mask = <1>; ti,no-idle-on-init; - clocks = <&l3_div_ck>; + clocks = <&l3_2_clkctrl OMAP4_GPMC_CLKCTRL 0>; clock-names = "fck"; - interrupt-controller; - #interrupt-cells = <2>; - gpio-controller; - #gpio-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x50000000 0x50000000 0x00001000>, /* regs */ + <0x00000000 0x00000000 0x40000000>; /* data */ + + gpmc: gpmc@50000000 { + compatible = "ti,omap4430-gpmc"; + reg = <0x50000000 0x1000>; + #address-cells = <2>; + #size-cells = <1>; + interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&sdma 4>; + dma-names = "rxtx"; + gpmc,num-cs = <8>; + gpmc,num-waitpins = <4>; + clocks = <&l3_div_ck>; + clock-names = "fck"; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + }; }; target-module@52000000 { @@ -445,6 +457,7 @@ <0x58000014 4>; reg-names = "rev", "syss"; ti,syss-mask = <1>; + power-domains = <&prm_dss>; clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 0>, <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 9>, <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>, @@ -650,6 +663,32 @@ }; }; }; + + iva_hd_target: target-module@5a000000 { + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x5a05a400 0x4>, + <0x5a05a410 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-midle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + ti,sysc-sidle = <SYSC_IDLE_FORCE>, + <SYSC_IDLE_NO>, + <SYSC_IDLE_SMART>; + power-domains = <&prm_ivahd>; + resets = <&prm_ivahd 2>; + reset-names = "rstctrl"; + clocks = <&ivahd_clkctrl OMAP4_IVA_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x5a000000 0x5a000000 0x1000000>, + <0x5b000000 0x5b000000 0x1000000>; + + iva { + compatible = "ti,ivahd"; + }; + }; }; }; @@ -658,10 +697,17 @@ #include "omap44xx-clocks.dtsi" &prm { + prm_mpu: prm@300 { + compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; + reg = <0x300 0x100>; + #power-domain-cells = <0>; + }; + prm_tesla: prm@400 { compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; reg = <0x400 0x100>; #reset-cells = <1>; + #power-domain-cells = <0>; }; prm_abe: prm@500 { @@ -670,16 +716,78 @@ #power-domain-cells = <0>; }; + prm_always_on_core: prm@600 { + compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; + reg = <0x600 0x100>; + #power-domain-cells = <0>; + }; + prm_core: prm@700 { compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; reg = <0x700 0x100>; #reset-cells = <1>; + #power-domain-cells = <0>; }; prm_ivahd: prm@f00 { compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; reg = <0xf00 0x100>; #reset-cells = <1>; + #power-domain-cells = <0>; + }; + + prm_cam: prm@1000 { + compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; + reg = <0x1000 0x100>; + #power-domain-cells = <0>; + }; + + prm_dss: prm@1100 { + compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; + reg = <0x1100 0x100>; + #power-domain-cells = <0>; + }; + + prm_gfx: prm@1200 { + compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; + reg = <0x1200 0x100>; + #power-domain-cells = <0>; + }; + + prm_l3init: prm@1300 { + compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; + reg = <0x1300 0x100>; + #power-domain-cells = <0>; + }; + + prm_l4per: prm@1400 { + compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; + reg = <0x1400 0x100>; + #power-domain-cells = <0>; + }; + + prm_cefuse: prm@1600 { + compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; + reg = <0x1600 0x100>; + #power-domain-cells = <0>; + }; + + prm_wkup: prm@1700 { + compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; + reg = <0x1700 0x100>; + #power-domain-cells = <0>; + }; + + prm_emu: prm@1900 { + compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; + reg = <0x1900 0x100>; + #power-domain-cells = <0>; + }; + + prm_dss: prm@1100 { + compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; + reg = <0x1100 0x40>; + #power-domain-cells = <0>; }; prm_device: prm@1b00 { diff --git a/arch/arm/boot/dts/omap5-l4.dtsi b/arch/arm/boot/dts/omap5-l4.dtsi index f3d3a16b7c64..887b3359dd5a 100644 --- a/arch/arm/boot/dts/omap5-l4.dtsi +++ b/arch/arm/boot/dts/omap5-l4.dtsi @@ -194,7 +194,7 @@ #size-cells = <1>; utmi-mode = <2>; ranges = <0 0 0x20000>; - dwc3: dwc3@10000 { + dwc3: usb@10000 { compatible = "snps,dwc3"; reg = <0x10000 0x10000>; interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index 2bf2e5839a7f..5f1a8bd13880 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -410,6 +410,7 @@ <0x58000014 4>; reg-names = "rev", "syss"; ti,syss-mask = <1>; + power-domains = <&prm_dss>; clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 0>, <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 9>, <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>, @@ -670,10 +671,17 @@ #include "omap54xx-clocks.dtsi" &prm { + prm_mpu: prm@300 { + compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; + reg = <0x300 0x100>; + #power-domain-cells = <0>; + }; + prm_dsp: prm@400 { compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; reg = <0x400 0x100>; #reset-cells = <1>; + #power-domain-cells = <0>; }; prm_abe: prm@500 { @@ -682,16 +690,66 @@ #power-domain-cells = <0>; }; + prm_coreaon: prm@600 { + compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; + reg = <0x600 0x100>; + #power-domain-cells = <0>; + }; + prm_core: prm@700 { compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; reg = <0x700 0x100>; #reset-cells = <1>; + #power-domain-cells = <0>; }; prm_iva: prm@1200 { compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; reg = <0x1200 0x100>; #reset-cells = <1>; + #power-domain-cells = <0>; + }; + + prm_cam: prm@1300 { + compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; + reg = <0x1300 0x100>; + #power-domain-cells = <0>; + }; + + prm_dss: prm@1400 { + compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; + reg = <0x1400 0x100>; + #power-domain-cells = <0>; + }; + + prm_gpu: prm@1500 { + compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; + reg = <0x1500 0x100>; + #power-domain-cells = <0>; + }; + + prm_l3init: prm@1600 { + compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; + reg = <0x1600 0x100>; + #power-domain-cells = <0>; + }; + + prm_custefuse: prm@1700 { + compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; + reg = <0x1700 0x100>; + #power-domain-cells = <0>; + }; + + prm_wkupaon: prm@1800 { + compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; + reg = <0x1800 0x100>; + #power-domain-cells = <0>; + }; + + prm_emu: prm@1a00 { + compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; + reg = <0x1a00 0x100>; + #power-domain-cells = <0>; }; prm_device: prm@1c00 { diff --git a/arch/arm/boot/dts/openbmc-flash-layout-64.dtsi b/arch/arm/boot/dts/openbmc-flash-layout-64.dtsi new file mode 100644 index 000000000000..91163867be34 --- /dev/null +++ b/arch/arm/boot/dts/openbmc-flash-layout-64.dtsi @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Bytedance. + */ + +partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + u-boot@0 { + reg = <0x0 0x60000>; // 384KB + label = "u-boot"; + }; + + u-boot-env@60000 { + reg = <0x60000 0x20000>; // 128KB + label = "u-boot-env"; + }; + + kernel@80000 { + reg = <0x80000 0x500000>; // 5MB + label = "kernel"; + }; + + rofs@580000 { + reg = <0x580000 0x2a80000>; // 42.5MB + label = "rofs"; + }; + + rwfs@3000000 { + reg = <0x3000000 0x1000000>; // 16MB + label = "rwfs"; + }; +}; diff --git a/arch/arm/boot/dts/picoxcell-pc3x2.dtsi b/arch/arm/boot/dts/picoxcell-pc3x2.dtsi index c4c6c7e9e37b..5898879a3038 100644 --- a/arch/arm/boot/dts/picoxcell-pc3x2.dtsi +++ b/arch/arm/boot/dts/picoxcell-pc3x2.dtsi @@ -45,18 +45,21 @@ emac: gem@30000 { compatible = "cadence,gem"; reg = <0x30000 0x10000>; + interrupt-parent = <&vic0>; interrupts = <31>; }; dmac1: dmac@40000 { compatible = "snps,dw-dmac"; reg = <0x40000 0x10000>; + interrupt-parent = <&vic0>; interrupts = <25>; }; dmac2: dmac@50000 { compatible = "snps,dw-dmac"; reg = <0x50000 0x10000>; + interrupt-parent = <&vic0>; interrupts = <26>; }; @@ -233,6 +236,7 @@ axi2pico@c0000000 { compatible = "picochip,axi2pico-pc3x2"; reg = <0xc0000000 0x10000>; + interrupt-parent = <&vic0>; interrupts = <13 14 15 16 17 18 19 20 21>; }; }; diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts index 32b474bfeec3..e769f638f205 100644 --- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts +++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts @@ -566,6 +566,22 @@ usb_otg_vbus: usb-otg-vbus { }; }; + + fuelgauge: max17048@36 { + compatible = "maxim,max17048"; + reg = <0x36>; + + maxim,double-soc; + maxim,rcomp = /bits/ 8 <0x4d>; + + interrupt-parent = <&msmgpio>; + interrupts = <9 IRQ_TYPE_EDGE_FALLING>; + + pinctrl-names = "default"; + pinctrl-0 = <&fuelgauge_pin>; + + maxim,alert-low-soc-level = <2>; + }; }; i2c@f9924000 { @@ -706,6 +722,15 @@ power-source = <PM8941_GPIO_S3>; }; + fuelgauge_pin: fuelgauge-int { + pins = "gpio9"; + function = "normal"; + + bias-disable; + input-enable; + power-source = <PM8941_GPIO_S3>; + }; + wlan_sleep_clk_pin: wl-sleep-clk { pins = "gpio16"; function = "func2"; diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts index d4dc98214225..97352de91314 100644 --- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts +++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts @@ -4,6 +4,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> +#include <dt-bindings/leds/common.h> / { model = "Samsung Galaxy S5"; @@ -11,6 +12,8 @@ aliases { serial0 = &blsp1_uart1; + sdhc1 = &sdhc_1; /* SDC1 eMMC slot */ + sdhc2 = &sdhc_2; /* SDC2 SD card slot */ }; chosen { @@ -145,7 +148,7 @@ }; pma8084_l19: l19 { - regulator-min-microvolt = <2900000>; + regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; }; @@ -160,6 +163,9 @@ pma8084_l21: l21 { regulator-min-microvolt = <2950000>; regulator-max-microvolt = <2950000>; + + regulator-allow-set-load; + regulator-system-load = <200000>; }; pma8084_l22: l22 { @@ -203,6 +209,95 @@ }; }; + i2c-gpio-touchkey { + compatible = "i2c-gpio"; + #address-cells = <1>; + #size-cells = <0>; + sda-gpios = <&msmgpio 95 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + scl-gpios = <&msmgpio 96 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c_touchkey_pins>; + + touchkey@20 { + compatible = "cypress,tm2-touchkey"; + reg = <0x20>; + + interrupt-parent = <&pma8084_gpios>; + interrupts = <6 IRQ_TYPE_EDGE_FALLING>; + pinctrl-names = "default"; + pinctrl-0 = <&touchkey_pin>; + + vcc-supply = <&max77826_ldo15>; + vdd-supply = <&pma8084_l19>; + + linux,keycodes = <KEY_APPSELECT KEY_BACK>; + }; + }; + + i2c-gpio-led { + compatible = "i2c-gpio"; + #address-cells = <1>; + #size-cells = <0>; + scl-gpios = <&msmgpio 121 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&msmgpio 120 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c_led_gpioex_pins>; + + i2c-gpio,delay-us = <2>; + + gpio_expander: gpio@20 { + compatible = "nxp,pcal6416"; + reg = <0x20>; + + gpio-controller; + #gpio-cells = <2>; + + vcc-supply = <&pma8084_s4>; + + pinctrl-names = "default"; + pinctrl-0 = <&gpioex_pin>; + + reset-gpios = <&msmgpio 145 GPIO_ACTIVE_LOW>; + }; + + led-controller@30 { + compatible = "panasonic,an30259a"; + reg = <0x30>; + + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + function = LED_FUNCTION_STATUS; + color = <LED_COLOR_ID_RED>; + }; + + led@2 { + reg = <2>; + function = LED_FUNCTION_STATUS; + color = <LED_COLOR_ID_GREEN>; + }; + + led@3 { + reg = <3>; + function = LED_FUNCTION_STATUS; + color = <LED_COLOR_ID_BLUE>; + }; + }; + }; + + vreg_wlan: wlan-regulator { + compatible = "regulator-fixed"; + + regulator-name = "wl-reg"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&gpio_expander 8 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + /delete-node/ vreg-boost; }; @@ -258,9 +353,109 @@ bias-pull-up; }; }; + + sdhc2_pin_a: sdhc2-pin-active { + clk-cmd-data { + pins = "gpio35", "gpio36", "gpio37", "gpio38", + "gpio39", "gpio40"; + function = "sdc3"; + drive-strength = <8>; + bias-disable; + }; + }; + + sdhc2_cd_pin: sdhc2-cd { + pins = "gpio62"; + function = "gpio"; + + drive-strength = <2>; + bias-disable; + }; + + sdhc3_pin_a: sdhc3-pin-active { + clk { + pins = "sdc2_clk"; + drive-strength = <6>; + bias-disable; + }; + + cmd-data { + pins = "sdc2_cmd", "sdc2_data"; + drive-strength = <6>; + bias-pull-up; + }; + }; + + i2c2_pins: i2c2 { + mux { + pins = "gpio6", "gpio7"; + function = "blsp_i2c2"; + + drive-strength = <2>; + bias-disable; + }; + }; + + i2c6_pins: i2c6 { + mux { + pins = "gpio29", "gpio30"; + function = "blsp_i2c6"; + + drive-strength = <2>; + bias-disable; + }; + }; + + i2c12_pins: i2c12 { + mux { + pins = "gpio87", "gpio88"; + function = "blsp_i2c12"; + + drive-strength = <2>; + bias-disable; + }; + }; + + i2c_touchkey_pins: i2c-touchkey { + mux { + pins = "gpio95", "gpio96"; + function = "gpio"; + input-enable; + bias-pull-up; + }; + }; + + i2c_led_gpioex_pins: i2c-led-gpioex { + mux { + pins = "gpio120", "gpio121"; + function = "gpio"; + input-enable; + bias-pull-down; + }; + }; + + gpioex_pin: gpioex { + res { + pins = "gpio145"; + function = "gpio"; + + bias-pull-up; + drive-strength = <2>; + }; + }; + + wifi_pin: wifi { + int { + pins = "gpio92"; + function = "gpio"; + + input-enable; + bias-pull-down; + }; + }; }; - sdhci@f9824900 { + sdhc_1: sdhci@f9824900 { status = "ok"; vmmc-supply = <&pma8084_l20>; @@ -273,6 +468,55 @@ pinctrl-0 = <&sdhc1_pin_a>; }; + sdhc_2: sdhci@f9864900 { + status = "ok"; + + max-frequency = <100000000>; + + vmmc-supply = <&pma8084_l21>; + vqmmc-supply = <&pma8084_l13>; + + bus-width = <4>; + + /* cd-gpio is intentionally disabled. If enabled, an SD card + * present during boot is not initialized correctly. Without + * cd-gpios the driver resorts to polling, so hotplug works. + */ + pinctrl-names = "default"; + pinctrl-0 = <&sdhc2_pin_a /* &sdhc2_cd_pin */>; + // cd-gpios = <&msmgpio 62 GPIO_ACTIVE_LOW>; + }; + + sdhci@f98a4900 { + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + max-frequency = <100000000>; + + pinctrl-names = "default"; + pinctrl-0 = <&sdhc3_pin_a>; + + vmmc-supply = <&vreg_wlan>; + vqmmc-supply = <&pma8084_s4>; + + bus-width = <4>; + non-removable; + + wifi@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + + interrupt-parent = <&msmgpio>; + interrupts = <92 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "host-wake"; + + pinctrl-names = "default"; + pinctrl-0 = <&wlan_sleep_clk_pin &wifi_pin>; + }; + }; + usb@f9a55000 { status = "ok"; @@ -298,14 +542,38 @@ }; }; - pinctrl@fd510000 { - i2c6_pins: i2c6 { - mux { - pins = "gpio29", "gpio30"; - function = "blsp_i2c6"; + i2c@f9924000 { + status = "okay"; - drive-strength = <2>; - bias-disable; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + + touchscreen@20 { + compatible = "syna,rmi4-i2c"; + reg = <0x20>; + + interrupt-parent = <&pma8084_gpios>; + interrupts = <8 IRQ_TYPE_EDGE_FALLING>; + + vdd-supply = <&max77826_ldo13>; + vio-supply = <&pma8084_lvs2>; + + pinctrl-names = "default"; + pinctrl-0 = <&touch_pin>; + + syna,startup-delay-ms = <100>; + + #address-cells = <1>; + #size-cells = <0>; + + rmi4-f01@1 { + reg = <0x1>; + syna,nosleep-mode = <1>; + }; + + rmi4-f12@12 { + reg = <0x12>; + syna,sensor-type = <1>; }; }; }; @@ -408,6 +676,27 @@ }; }; }; + + i2c@f9968000 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&i2c12_pins>; + + fuelgauge@36 { + compatible = "maxim,max17048"; + reg = <0x36>; + + maxim,double-soc; + maxim,rcomp = /bits/ 8 <0x56>; + + interrupt-parent = <&pma8084_gpios>; + interrupts = <21 IRQ_TYPE_EDGE_FALLING>; + + pinctrl-names = "default"; + pinctrl-0 = <&fuelgauge_pin>; + }; + }; }; &spmi_bus { @@ -420,6 +709,39 @@ bias-pull-up; power-source = <PMA8084_GPIO_S4>; }; + + touchkey_pin: touchkey-int-pin { + pins = "gpio6"; + function = "normal"; + bias-disable; + input-enable; + power-source = <PMA8084_GPIO_S4>; + }; + + touch_pin: touchscreen-int-pin { + pins = "gpio8"; + function = "normal"; + bias-disable; + input-enable; + power-source = <PMA8084_GPIO_S4>; + }; + + wlan_sleep_clk_pin: wlan-sleep-clk-pin { + pins = "gpio16"; + function = "func2"; + + output-high; + power-source = <PMA8084_GPIO_S4>; + qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>; + }; + + fuelgauge_pin: fuelgauge-int-pin { + pins = "gpio21"; + function = "normal"; + bias-disable; + input-enable; + power-source = <PMA8084_GPIO_S4>; + }; }; }; }; diff --git a/arch/arm/boot/dts/qcom-pma8084.dtsi b/arch/arm/boot/dts/qcom-pma8084.dtsi index ea1ca166165c..e921c5e93a5d 100644 --- a/arch/arm/boot/dts/qcom-pma8084.dtsi +++ b/arch/arm/boot/dts/qcom-pma8084.dtsi @@ -68,7 +68,6 @@ #address-cells = <1>; #size-cells = <0>; #io-channel-cells = <1>; - io-channel-ranges; die_temp { reg = <VADC_DIE_TEMP>; diff --git a/arch/arm/boot/dts/r8a7742-iwg21d-q7-dbcm-ca.dts b/arch/arm/boot/dts/r8a7742-iwg21d-q7-dbcm-ca.dts index 961c0f2eeefb..98c3fbd89fa6 100644 --- a/arch/arm/boot/dts/r8a7742-iwg21d-q7-dbcm-ca.dts +++ b/arch/arm/boot/dts/r8a7742-iwg21d-q7-dbcm-ca.dts @@ -20,6 +20,30 @@ serial5 = &hscif0; ethernet1 = ðer; }; + + mclk_cam1: mclk-cam1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + mclk_cam2: mclk-cam2 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + mclk_cam3: mclk-cam3 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + mclk_cam4: mclk-cam4 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; }; &avb { @@ -47,6 +71,19 @@ }; }; +&gpio0 { + /* Disable hogging GP0_18 to output LOW */ + /delete-node/ qspi_en; + + /* Hog GP0_18 to output HIGH to enable VIN2 */ + vin2_en { + gpio-hog; + gpios = <18 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "VIN2_EN"; + }; +}; + &hscif0 { pinctrl-0 = <&hscif0_pins>; pinctrl-names = "default"; @@ -54,6 +91,94 @@ status = "okay"; }; +&i2c0 { + ov5640@3c { + compatible = "ovti,ov5640"; + reg = <0x3c>; + clocks = <&mclk_cam1>; + clock-names = "xclk"; + + port { + ov5640_0: endpoint { + bus-width = <8>; + data-shift = <2>; + bus-type = <6>; + pclk-sample = <1>; + remote-endpoint = <&vin0ep>; + }; + }; + }; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; + + status = "okay"; + clock-frequency = <400000>; + + ov5640@3c { + compatible = "ovti,ov5640"; + reg = <0x3c>; + clocks = <&mclk_cam2>; + clock-names = "xclk"; + + port { + ov5640_1: endpoint { + bus-width = <8>; + data-shift = <2>; + bus-type = <6>; + pclk-sample = <1>; + remote-endpoint = <&vin1ep>; + }; + }; + }; +}; + +&i2c2 { + ov5640@3c { + compatible = "ovti,ov5640"; + reg = <0x3c>; + clocks = <&mclk_cam3>; + clock-names = "xclk"; + + port { + ov5640_2: endpoint { + bus-width = <8>; + data-shift = <2>; + bus-type = <6>; + pclk-sample = <1>; + remote-endpoint = <&vin2ep>; + }; + }; + }; +}; + +&i2c3 { + pinctrl-0 = <&i2c3_pins>; + pinctrl-names = "default"; + + status = "okay"; + clock-frequency = <400000>; + + ov5640@3c { + compatible = "ovti,ov5640"; + reg = <0x3c>; + clocks = <&mclk_cam4>; + clock-names = "xclk"; + + port { + ov5640_3: endpoint { + bus-width = <8>; + data-shift = <2>; + bus-type = <6>; + pclk-sample = <1>; + remote-endpoint = <&vin3ep>; + }; + }; + }; +}; + &pfc { can0_pins: can0 { groups = "can0_data_d"; @@ -70,6 +195,16 @@ function = "hscif0"; }; + i2c1_pins: i2c1 { + groups = "i2c1_c"; + function = "i2c1"; + }; + + i2c3_pins: i2c3 { + groups = "i2c3"; + function = "i2c3"; + }; + scif0_pins: scif0 { groups = "scif0_data"; function = "scif0"; @@ -84,6 +219,31 @@ groups = "scifb1_data"; function = "scifb1"; }; + + vin0_8bit_pins: vin0 { + groups = "vin0_data8", "vin0_clk", "vin0_sync"; + function = "vin0"; + }; + + vin1_8bit_pins: vin1 { + groups = "vin1_data8_b", "vin1_clk_b", "vin1_sync_b"; + function = "vin1"; + }; + + vin2_pins: vin2 { + groups = "vin2_g8", "vin2_clk"; + function = "vin2"; + }; + + vin3_pins: vin3 { + groups = "vin3_data8", "vin3_clk", "vin3_sync"; + function = "vin3"; + }; +}; + +&qspi { + /* Pins shared with VIN2, keep status disabled */ + status = "disabled"; }; &scif0 { @@ -106,3 +266,65 @@ rts-gpios = <&gpio4 21 GPIO_ACTIVE_LOW>; cts-gpios = <&gpio4 17 GPIO_ACTIVE_LOW>; }; + +&vin0 { + /* + * Set SW2 switch on the SOM to 'ON' + * Set SW1 switch on camera board to 'OFF' as we are using 8bit mode + */ + status = "okay"; + pinctrl-0 = <&vin0_8bit_pins>; + pinctrl-names = "default"; + + port { + vin0ep: endpoint { + remote-endpoint = <&ov5640_0>; + bus-width = <8>; + bus-type = <6>; + }; + }; +}; + +&vin1 { + /* Set SW1 switch on the SOM to 'ON' */ + status = "okay"; + pinctrl-0 = <&vin1_8bit_pins>; + pinctrl-names = "default"; + + port { + vin1ep: endpoint { + remote-endpoint = <&ov5640_1>; + bus-width = <8>; + bus-type = <6>; + }; + }; +}; + +&vin2 { + status = "okay"; + pinctrl-0 = <&vin2_pins>; + pinctrl-names = "default"; + + port { + vin2ep: endpoint { + remote-endpoint = <&ov5640_2>; + bus-width = <8>; + data-shift = <8>; + bus-type = <6>; + }; + }; +}; + +&vin3 { + status = "okay"; + pinctrl-0 = <&vin3_pins>; + pinctrl-names = "default"; + + port { + vin3ep: endpoint { + remote-endpoint = <&ov5640_3>; + bus-width = <8>; + bus-type = <6>; + }; + }; +}; diff --git a/arch/arm/boot/dts/r8a7742-iwg21d-q7.dts b/arch/arm/boot/dts/r8a7742-iwg21d-q7.dts index c2c05c9685d1..0063ef92f50e 100644 --- a/arch/arm/boot/dts/r8a7742-iwg21d-q7.dts +++ b/arch/arm/boot/dts/r8a7742-iwg21d-q7.dts @@ -30,6 +30,7 @@ /dts-v1/; #include "r8a7742-iwg21m.dtsi" +#include <dt-bindings/pwm/pwm.h> / { model = "iWave Systems RainboW-G21D-Qseven board based on RZ/G1H"; @@ -52,6 +53,16 @@ clock-frequency = <26000000>; }; + lcd_backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&tpu 2 5000000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + pinctrl-0 = <&backlight_pins>; + pinctrl-names = "default"; + default-brightness-level = <7>; + enable-gpios = <&gpio3 11 GPIO_ACTIVE_HIGH>; + }; + leds { compatible = "gpio-leds"; @@ -62,6 +73,41 @@ }; }; + lvds-receiver { + compatible = "ti,ds90cf384a", "lvds-decoder"; + power-supply = <&vcc_3v3_tft1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + lvds_receiver_in: endpoint { + remote-endpoint = <&lvds0_out>; + }; + }; + port@1 { + reg = <1>; + lvds_receiver_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; + }; + + panel { + compatible = "edt,etm0700g0dh6"; + backlight = <&lcd_backlight>; + power-supply = <&vcc_3v3_tft1>; + + port { + panel_in: endpoint { + remote-endpoint = <&lvds_receiver_out>; + }; + }; + }; + reg_1p5v: 1p5v { compatible = "regulator-fixed"; regulator-name = "1P5V"; @@ -85,6 +131,17 @@ }; }; + vcc_3v3_tft1: regulator-panel { + compatible = "regulator-fixed"; + + regulator-name = "vcc-3v3-tft1"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + startup-delay-us = <500>; + gpio = <&gpio5 28 GPIO_ACTIVE_HIGH>; + }; + vcc_sdhi2: regulator-vcc-sdhi2 { compatible = "regulator-fixed"; @@ -139,6 +196,16 @@ VDDIO-supply = <®_3p3v>; VDDD-supply = <®_1p5v>; }; + + touch: touchpanel@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + interrupt-parent = <&gpio0>; + interrupts = <24 IRQ_TYPE_EDGE_FALLING>; + /* GP1_29 is also shared with audio codec reset pin */ + reset-gpios = <&gpio1 29 GPIO_ACTIVE_LOW>; + vcc-supply = <&vcc_3v3_tft1>; + }; }; &can1 { @@ -152,6 +219,18 @@ status = "okay"; }; +&du { + status = "okay"; +}; + +&gpio0 { + touch-interrupt { + gpio-hog; + gpios = <24 GPIO_ACTIVE_LOW>; + input; + }; +}; + &gpio1 { can-trx-en-gpio{ gpio-hog; @@ -167,6 +246,17 @@ status = "okay"; }; +&lvds0 { + status = "okay"; + ports { + port@1 { + lvds0_out: endpoint { + remote-endpoint = <&lvds_receiver_in>; + }; + }; + }; +}; + &msiof0 { pinctrl-0 = <&msiof0_pins>; pinctrl-names = "default"; @@ -229,6 +319,11 @@ function = "avb"; }; + backlight_pins: backlight { + groups = "tpu0_to2"; + function = "tpu0"; + }; + can1_pins: can1 { groups = "can1_data_b"; function = "can1"; @@ -335,6 +430,10 @@ shared-pin; }; +&tpu { + status = "okay"; +}; + &usbphy { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3288-veyron-jaq.dts b/arch/arm/boot/dts/rk3288-veyron-jaq.dts index af77ab20586d..4a148cf1defc 100644 --- a/arch/arm/boot/dts/rk3288-veyron-jaq.dts +++ b/arch/arm/boot/dts/rk3288-veyron-jaq.dts @@ -20,7 +20,7 @@ &backlight { /* Jaq panel PWM must be >= 3%, so start non-zero brightness at 8 */ - brightness-levels = <0 8 255>; + brightness-levels = <8 255>; num-interpolated-steps = <247>; }; diff --git a/arch/arm/boot/dts/rk3288-veyron-minnie.dts b/arch/arm/boot/dts/rk3288-veyron-minnie.dts index f8b69e0a16a0..82fc6fba9999 100644 --- a/arch/arm/boot/dts/rk3288-veyron-minnie.dts +++ b/arch/arm/boot/dts/rk3288-veyron-minnie.dts @@ -39,7 +39,7 @@ &backlight { /* Minnie panel PWM must be >= 1%, so start non-zero brightness at 3 */ - brightness-levels = <0 3 255>; + brightness-levels = <3 255>; num-interpolated-steps = <252>; }; diff --git a/arch/arm/boot/dts/rk3288-veyron-tiger.dts b/arch/arm/boot/dts/rk3288-veyron-tiger.dts index 069f0c2c1fdf..52a84cbe7a90 100644 --- a/arch/arm/boot/dts/rk3288-veyron-tiger.dts +++ b/arch/arm/boot/dts/rk3288-veyron-tiger.dts @@ -23,7 +23,7 @@ &backlight { /* Tiger panel PWM must be >= 1%, so start non-zero brightness at 3 */ - brightness-levels = <0 3 255>; + brightness-levels = <3 255>; num-interpolated-steps = <252>; }; diff --git a/arch/arm/boot/dts/rk3288-vmarc-som.dtsi b/arch/arm/boot/dts/rk3288-vmarc-som.dtsi index 4a373f5aa600..0ae2bd150e37 100644 --- a/arch/arm/boot/dts/rk3288-vmarc-som.dtsi +++ b/arch/arm/boot/dts/rk3288-vmarc-som.dtsi @@ -231,6 +231,23 @@ }; }; +&i2c1 { + clock-frequency = <400000>; + status = "okay"; + + hym8563: rtc@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + interrupt-parent = <&gpio5>; + interrupts = <RK_PC3 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "hym8563"; + pinctrl-names = "default"; + pinctrl-0 = <&hym8563_int>; + }; +}; + &i2c5 { status = "okay"; }; @@ -241,10 +258,17 @@ gpio1830-supply = <&vcc_18>; gpio30-supply = <&vcc_io>; sdcard-supply = <&vccio_sd>; + wifi-supply = <&vcc_wl>; status = "okay"; }; &pinctrl { + hym8563 { + hym8563_int: hym8563-int { + rockchip,pins = <5 RK_PC3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma { drive-strength = <8>; }; @@ -260,6 +284,12 @@ }; }; + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + sdmmc { sdmmc_bus4: sdmmc-bus4 { rockchip,pins = @@ -291,6 +321,16 @@ }; }; +&sdio_pwrseq { + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_LOW>; /* WIFI_REG_ON */ +}; + &usbphy { status = "okay"; }; diff --git a/arch/arm/boot/dts/rockchip-radxa-dalang-carrier.dtsi b/arch/arm/boot/dts/rockchip-radxa-dalang-carrier.dtsi index 26b53eac4706..da1d548b7330 100644 --- a/arch/arm/boot/dts/rockchip-radxa-dalang-carrier.dtsi +++ b/arch/arm/boot/dts/rockchip-radxa-dalang-carrier.dtsi @@ -15,6 +15,14 @@ #clock-cells = <0>; }; + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&hym8563>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + }; + vcc12v_dcin: vcc12v-dcin-regulator { compatible = "regulator-fixed"; regulator-name = "vcc12v_dcin"; @@ -78,6 +86,19 @@ status = "okay"; }; +&sdio0 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; + sd-uhs-sdr104; + status = "okay"; +}; + &sdmmc { bus-width = <4>; cap-mmc-highspeed; diff --git a/arch/arm/boot/dts/rv1108.dtsi b/arch/arm/boot/dts/rv1108.dtsi index a1a08cb9364e..e491964b1c3d 100644 --- a/arch/arm/boot/dts/rv1108.dtsi +++ b/arch/arm/boot/dts/rv1108.dtsi @@ -299,7 +299,7 @@ clock-names = "timer", "pclk"; }; - watchdog: wdt@10360000 { + watchdog: watchdog@10360000 { compatible = "snps,dw-wdt"; reg = <0x10360000 0x100>; interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm/boot/dts/s3c2416-smdk2416.dts b/arch/arm/boot/dts/s3c2416-smdk2416.dts index 47626ede6fdd..e7c379a9842e 100644 --- a/arch/arm/boot/dts/s3c2416-smdk2416.dts +++ b/arch/arm/boot/dts/s3c2416-smdk2416.dts @@ -10,7 +10,7 @@ / { model = "SMDK2416"; - compatible = "samsung,s3c2416"; + compatible = "samsung,smdk2416", "samsung,s3c2416"; memory@30000000 { device_type = "memory"; diff --git a/arch/arm/boot/dts/s3c6410-smdk6410.dts b/arch/arm/boot/dts/s3c6410-smdk6410.dts index 69c9ec4cf381..581309e7f15e 100644 --- a/arch/arm/boot/dts/s3c6410-smdk6410.dts +++ b/arch/arm/boot/dts/s3c6410-smdk6410.dts @@ -17,7 +17,7 @@ / { model = "Samsung SMDK6410 board based on S3C6410"; - compatible = "samsung,mini6410", "samsung,s3c6410"; + compatible = "samsung,smdk6410", "samsung,s3c6410"; memory@50000000 { device_type = "memory"; diff --git a/arch/arm/boot/dts/s5pv210-aquila.dts b/arch/arm/boot/dts/s5pv210-aquila.dts index 8e57e5a1f0c5..6423348034b6 100644 --- a/arch/arm/boot/dts/s5pv210-aquila.dts +++ b/arch/arm/boot/dts/s5pv210-aquila.dts @@ -277,37 +277,37 @@ <&keypad_col0>, <&keypad_col1>, <&keypad_col2>; status = "okay"; - key_1 { + key-1 { keypad,row = <0>; keypad,column = <1>; linux,code = <KEY_CONNECT>; }; - key_2 { + key-2 { keypad,row = <0>; keypad,column = <2>; linux,code = <KEY_BACK>; }; - key_3 { + key-3 { keypad,row = <1>; keypad,column = <1>; linux,code = <KEY_CAMERA_FOCUS>; }; - key_4 { + key-4 { keypad,row = <1>; keypad,column = <2>; linux,code = <KEY_VOLUMEUP>; }; - key_5 { + key-5 { keypad,row = <2>; keypad,column = <1>; linux,code = <KEY_CAMERA>; }; - key_6 { + key-6 { keypad,row = <2>; keypad,column = <2>; linux,code = <KEY_VOLUMEDOWN>; diff --git a/arch/arm/boot/dts/s5pv210-aries.dtsi b/arch/arm/boot/dts/s5pv210-aries.dtsi index 4da33d0f2748..160f8cd9a68d 100644 --- a/arch/arm/boot/dts/s5pv210-aries.dtsi +++ b/arch/arm/boot/dts/s5pv210-aries.dtsi @@ -54,7 +54,7 @@ clock-frequency = <32768>; }; - bt_codec: bt_sco { + bt_codec: bt-sco { compatible = "linux,bt-sco"; #sound-dai-cells = <0>; }; @@ -113,7 +113,7 @@ pinctrl-names = "default"; pinctrl-0 = <&sound_i2c_pins>; - wm8994: wm8994@1a { + wm8994: audio-codec@1a { compatible = "wlf,wm8994"; reg = <0x1a>; @@ -589,7 +589,6 @@ io-channels = <&adc 9>; shunt-resistor-micro-ohms = <47000000>; /* 47 ohms */ #io-channel-cells = <0>; - io-channel-ranges; }; }; diff --git a/arch/arm/boot/dts/s5pv210-goni.dts b/arch/arm/boot/dts/s5pv210-goni.dts index ad8d5d2fa32d..5c1e12d39747 100644 --- a/arch/arm/boot/dts/s5pv210-goni.dts +++ b/arch/arm/boot/dts/s5pv210-goni.dts @@ -259,37 +259,37 @@ <&keypad_col0>, <&keypad_col1>, <&keypad_col2>; status = "okay"; - key_1 { + key-1 { keypad,row = <0>; keypad,column = <1>; linux,code = <KEY_CONNECT>; }; - key_2 { + key-2 { keypad,row = <0>; keypad,column = <2>; linux,code = <KEY_BACK>; }; - key_3 { + key-3 { keypad,row = <1>; keypad,column = <1>; linux,code = <KEY_CAMERA_FOCUS>; }; - key_4 { + key-4 { keypad,row = <1>; keypad,column = <2>; linux,code = <KEY_VOLUMEUP>; }; - key_5 { + key-5 { keypad,row = <2>; keypad,column = <1>; linux,code = <KEY_CAMERA>; }; - key_6 { + key-6 { keypad,row = <2>; keypad,column = <2>; linux,code = <KEY_VOLUMEDOWN>; @@ -353,7 +353,7 @@ samsung,i2c-slave-addr = <0x10>; status = "okay"; - tsp@4a { + touchscreen@4a { compatible = "atmel,maxtouch"; reg = <0x4a>; interrupt-parent = <&gpj0>; diff --git a/arch/arm/boot/dts/s5pv210-smdkv210.dts b/arch/arm/boot/dts/s5pv210-smdkv210.dts index 7459e41e8ef1..fbae768d65e2 100644 --- a/arch/arm/boot/dts/s5pv210-smdkv210.dts +++ b/arch/arm/boot/dts/s5pv210-smdkv210.dts @@ -76,61 +76,61 @@ <&keypad_col6>, <&keypad_col7>; status = "okay"; - key_1 { + key-1 { keypad,row = <0>; keypad,column = <3>; linux,code = <KEY_1>; }; - key_2 { + key-2 { keypad,row = <0>; keypad,column = <4>; linux,code = <KEY_2>; }; - key_3 { + key-3 { keypad,row = <0>; keypad,column = <5>; linux,code = <KEY_3>; }; - key_4 { + key-4 { keypad,row = <0>; keypad,column = <6>; linux,code = <KEY_4>; }; - key_5 { + key-5 { keypad,row = <0 >; keypad,column = <7>; linux,code = <KEY_5>; }; - key_6 { + key-6 { keypad,row = <1>; keypad,column = <3>; linux,code = <KEY_A>; }; - key_7 { + key-7 { keypad,row = <1>; keypad,column = <4>; linux,code = <KEY_B>; }; - key_8 { + key-8 { keypad,row = <1>; keypad,column = <5>; linux,code = <KEY_C>; }; - key_9 { + key-9 { keypad,row = <1>; keypad,column = <6>; linux,code = <KEY_D>; }; - key_10 { + key-10 { keypad,row = <1>; keypad,column = <7>; linux,code = <KEY_E>; diff --git a/arch/arm/boot/dts/s5pv210.dtsi b/arch/arm/boot/dts/s5pv210.dtsi index 2871351ab907..353ba7b09a0c 100644 --- a/arch/arm/boot/dts/s5pv210.dtsi +++ b/arch/arm/boot/dts/s5pv210.dtsi @@ -149,7 +149,6 @@ clocks = <&clocks CLK_TSADC>; clock-names = "adc"; #io-channel-cells = <1>; - io-channel-ranges; status = "disabled"; }; diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi index 2ddc85dff8ce..2c4952427296 100644 --- a/arch/arm/boot/dts/sama5d2.dtsi +++ b/arch/arm/boot/dts/sama5d2.dtsi @@ -656,6 +656,7 @@ clocks = <&pmc PMC_TYPE_PERIPHERAL 51>; #address-cells = <1>; #size-cells = <1>; + no-memory-wc; ranges = <0 0xf8044000 0x1420>; }; @@ -724,7 +725,7 @@ can0: can@f8054000 { compatible = "bosch,m_can"; - reg = <0xf8054000 0x4000>, <0x210000 0x4000>; + reg = <0xf8054000 0x4000>, <0x210000 0x1c00>; reg-names = "m_can", "message_ram"; interrupts = <56 IRQ_TYPE_LEVEL_HIGH 7>, <64 IRQ_TYPE_LEVEL_HIGH 7>; @@ -1130,7 +1131,7 @@ can1: can@fc050000 { compatible = "bosch,m_can"; - reg = <0xfc050000 0x4000>, <0x210000 0x4000>; + reg = <0xfc050000 0x4000>, <0x210000 0x3800>; reg-names = "m_can", "message_ram"; interrupts = <57 IRQ_TYPE_LEVEL_HIGH 7>, <65 IRQ_TYPE_LEVEL_HIGH 7>; @@ -1140,7 +1141,7 @@ assigned-clocks = <&pmc PMC_TYPE_GCK 57>; assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_UTMI>; assigned-clock-rates = <40000000>; - bosch,mram-cfg = <0x1100 0 0 64 0 0 32 32>; + bosch,mram-cfg = <0x1c00 0 0 64 0 0 32 32>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index 86137f8d2b45..7c979652f330 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi @@ -305,9 +305,7 @@ }; adc0: adc@f8018000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "atmel,at91sam9x5-adc"; + compatible = "atmel,sama5d3-adc"; reg = <0xf8018000 0x100>; interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default"; @@ -333,30 +331,8 @@ atmel,adc-startup-time = <40>; atmel,adc-use-external-triggers; atmel,adc-vref = <3000>; - atmel,adc-res = <10 12>; atmel,adc-sample-hold-time = <11>; - atmel,adc-res-names = "lowres", "highres"; status = "disabled"; - - trigger0 { - trigger-name = "external-rising"; - trigger-value = <0x1>; - trigger-external; - }; - trigger1 { - trigger-name = "external-falling"; - trigger-value = <0x2>; - trigger-external; - }; - trigger2 { - trigger-name = "external-any"; - trigger-value = <0x3>; - trigger-external; - }; - trigger3 { - trigger-name = "continuous"; - trigger-value = <0x6>; - }; }; i2c2: i2c@f801c000 { diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 04f24cf752d3..05c55875835d 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -661,31 +661,9 @@ atmel,adc-startup-time = <40>; atmel,adc-use-external-triggers; atmel,adc-vref = <3000>; - atmel,adc-res = <8 10>; atmel,adc-sample-hold-time = <11>; - atmel,adc-res-names = "lowres", "highres"; atmel,adc-ts-pressure-threshold = <10000>; status = "disabled"; - - trigger0 { - trigger-name = "external-rising"; - trigger-value = <0x1>; - trigger-external; - }; - trigger1 { - trigger-name = "external-falling"; - trigger-value = <0x2>; - trigger-external; - }; - trigger2 { - trigger-name = "external-any"; - trigger-value = <0x3>; - trigger-external; - }; - trigger3 { - trigger-name = "continuous"; - trigger-value = <0x6>; - }; }; aes@fc044000 { diff --git a/arch/arm/boot/dts/ste-ab8500.dtsi b/arch/arm/boot/dts/ste-ab8500.dtsi index aab5719cc1a9..4c16736ea789 100644 --- a/arch/arm/boot/dts/ste-ab8500.dtsi +++ b/arch/arm/boot/dts/ste-ab8500.dtsi @@ -326,13 +326,13 @@ mcde@a0350000 { vana-supply = <&ab8500_ldo_ana_reg>; - dsi-controller@a0351000 { + dsi@a0351000 { vana-supply = <&ab8500_ldo_ana_reg>; }; - dsi-controller@a0352000 { + dsi@a0352000 { vana-supply = <&ab8500_ldo_ana_reg>; }; - dsi-controller@a0353000 { + dsi@a0353000 { vana-supply = <&ab8500_ldo_ana_reg>; }; }; diff --git a/arch/arm/boot/dts/ste-ab8505.dtsi b/arch/arm/boot/dts/ste-ab8505.dtsi index 67bc69e67b33..c72aa250bf6f 100644 --- a/arch/arm/boot/dts/ste-ab8505.dtsi +++ b/arch/arm/boot/dts/ste-ab8505.dtsi @@ -261,13 +261,13 @@ mcde@a0350000 { vana-supply = <&ab8500_ldo_ana_reg>; - dsi-controller@a0351000 { + dsi@a0351000 { vana-supply = <&ab8500_ldo_ana_reg>; }; - dsi-controller@a0352000 { + dsi@a0352000 { vana-supply = <&ab8500_ldo_ana_reg>; }; - dsi-controller@a0353000 { + dsi@a0353000 { vana-supply = <&ab8500_ldo_ana_reg>; }; }; diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi index 05fd544b06c1..404b9c4a5fee 100644 --- a/arch/arm/boot/dts/ste-dbx5x0.dtsi +++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi @@ -1097,7 +1097,7 @@ ranges; status = "disabled"; - dsi0: dsi-controller@a0351000 { + dsi0: dsi@a0351000 { compatible = "ste,mcde-dsi"; reg = <0xa0351000 0x1000>; clocks = <&prcmu_clk PRCMU_DSI0CLK>, <&prcmu_clk PRCMU_DSI0ESCCLK>; @@ -1105,7 +1105,7 @@ #address-cells = <1>; #size-cells = <0>; }; - dsi1: dsi-controller@a0352000 { + dsi1: dsi@a0352000 { compatible = "ste,mcde-dsi"; reg = <0xa0352000 0x1000>; clocks = <&prcmu_clk PRCMU_DSI1CLK>, <&prcmu_clk PRCMU_DSI1ESCCLK>; @@ -1113,7 +1113,7 @@ #address-cells = <1>; #size-cells = <0>; }; - dsi2: dsi-controller@a0353000 { + dsi2: dsi@a0353000 { compatible = "ste,mcde-dsi"; reg = <0xa0353000 0x1000>; /* This DSI port only has the Low Power / Energy Save clock */ diff --git a/arch/arm/boot/dts/ste-href-stuib.dtsi b/arch/arm/boot/dts/ste-href-stuib.dtsi index b8fd8f18ba16..e32d0c36feb8 100644 --- a/arch/arm/boot/dts/ste-href-stuib.dtsi +++ b/arch/arm/boot/dts/ste-href-stuib.dtsi @@ -199,7 +199,7 @@ mcde@a0350000 { status = "okay"; - dsi-controller@a0351000 { + dsi@a0351000 { panel { compatible = "samsung,s6d16d0"; reg = <0>; diff --git a/arch/arm/boot/dts/ste-href-tvk1281618-r2.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618-r2.dtsi index de82b9db956f..e024520f4d47 100644 --- a/arch/arm/boot/dts/ste-href-tvk1281618-r2.dtsi +++ b/arch/arm/boot/dts/ste-href-tvk1281618-r2.dtsi @@ -66,7 +66,7 @@ mcde@a0350000 { status = "okay"; - dsi-controller@a0351000 { + dsi@a0351000 { panel { compatible = "samsung,s6d16d0"; reg = <0>; diff --git a/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi index 9f285c7cf914..cb3677f0a1cb 100644 --- a/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi +++ b/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi @@ -45,7 +45,7 @@ mcde@a0350000 { status = "okay"; - dsi-controller@a0351000 { + dsi@a0351000 { panel { compatible = "sony,acx424akp"; reg = <0>; diff --git a/arch/arm/boot/dts/ste-ux500-samsung-golden.dts b/arch/arm/boot/dts/ste-ux500-samsung-golden.dts index a1093cb37dc7..60fe6189e728 100644 --- a/arch/arm/boot/dts/ste-ux500-samsung-golden.dts +++ b/arch/arm/boot/dts/ste-ux500-samsung-golden.dts @@ -260,6 +260,11 @@ interrupt-parent = <&gpio6>; interrupts = <26 IRQ_TYPE_EDGE_FALLING>; + /* VDDA is "analog supply", 2.57-3.47 V */ + vdda-supply = <&ab8500_ldo_aux2_reg>; + /* VDD is "digital supply" 1.71-3.47V */ + vdd-supply = <&ab8500_ldo_aux5_reg>; + pinctrl-names = "default"; pinctrl-0 = <&tsp_default>; }; @@ -284,7 +289,6 @@ regulator-name = "vreg_tsp_a3v3"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - regulator-always-on; /* FIXME */ }; ab8500_ldo_aux3 { @@ -301,7 +305,6 @@ regulator-name = "vreg_tsp_1v8"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; - regulator-always-on; /* FIXME */ }; ab8500_ldo_aux6 { @@ -322,10 +325,11 @@ pinctrl-names = "default"; pinctrl-0 = <&dsi_default_mode>; - dsi-controller@a0351000 { + dsi@a0351000 { panel@0 { compatible = "samsung,s6e63m0"; reg = <0>; + max-brightness = <15>; vdd3-supply = <&panel_reg_3v0>; vci-supply = <&panel_reg_1v8>; reset-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; diff --git a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts index 27722c42b61c..b50634c81b44 100644 --- a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts +++ b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts @@ -393,7 +393,7 @@ pinctrl-names = "default"; pinctrl-0 = <&dsi_default_mode>; - dsi-controller@a0351000 { + dsi@a0351000 { panel { /* NT35510-based Hydis HVA40WV1 */ compatible = "hydis,hva40wv1", "novatek,nt35510"; @@ -433,6 +433,16 @@ }; }; + /* The unused FBCLK needs to be pulled down on this machine */ + sdi2 { + mc2_a_1_default { + default_cfg2 { + pins = "GPIO130_C8"; /* FBCLK */ + ste,config = <&in_pd>; + }; + }; + }; + mcde { dsi_default_mode: dsi_default { default_mux1 { diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts index 67e7648de41e..7e10ae744c9d 100644 --- a/arch/arm/boot/dts/stm32429i-eval.dts +++ b/arch/arm/boot/dts/stm32429i-eval.dts @@ -188,6 +188,7 @@ port { dcmi_0: endpoint { remote-endpoint = <&ov2640_0>; + bus-type = <5>; bus-width = <8>; hsync-active = <0>; vsync-active = <0>; diff --git a/arch/arm/boot/dts/stm32h743.dtsi b/arch/arm/boot/dts/stm32h743.dtsi index 7febe19e780d..b083afd0ebd6 100644 --- a/arch/arm/boot/dts/stm32h743.dtsi +++ b/arch/arm/boot/dts/stm32h743.dtsi @@ -274,7 +274,7 @@ dmamux1: dma-router@40020800 { compatible = "st,stm32h7-dmamux"; - reg = <0x40020800 0x1c>; + reg = <0x40020800 0x40>; #dma-cells = <3>; dma-channels = <16>; dma-requests = <128>; diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi index d84686e00370..20a59e8f7a33 100644 --- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi +++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi @@ -349,6 +349,61 @@ }; }; + fmc_pins_b: fmc-1 { + pins { + pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */ + <STM32_PINMUX('D', 5, AF12)>, /* FMC_NWE */ + <STM32_PINMUX('B', 7, AF12)>, /* FMC_NL */ + <STM32_PINMUX('D', 14, AF12)>, /* FMC_D0 */ + <STM32_PINMUX('D', 15, AF12)>, /* FMC_D1 */ + <STM32_PINMUX('D', 0, AF12)>, /* FMC_D2 */ + <STM32_PINMUX('D', 1, AF12)>, /* FMC_D3 */ + <STM32_PINMUX('E', 7, AF12)>, /* FMC_D4 */ + <STM32_PINMUX('E', 8, AF12)>, /* FMC_D5 */ + <STM32_PINMUX('E', 9, AF12)>, /* FMC_D6 */ + <STM32_PINMUX('E', 10, AF12)>, /* FMC_D7 */ + <STM32_PINMUX('E', 11, AF12)>, /* FMC_D8 */ + <STM32_PINMUX('E', 12, AF12)>, /* FMC_D9 */ + <STM32_PINMUX('E', 13, AF12)>, /* FMC_D10 */ + <STM32_PINMUX('E', 14, AF12)>, /* FMC_D11 */ + <STM32_PINMUX('E', 15, AF12)>, /* FMC_D12 */ + <STM32_PINMUX('D', 8, AF12)>, /* FMC_D13 */ + <STM32_PINMUX('D', 9, AF12)>, /* FMC_D14 */ + <STM32_PINMUX('D', 10, AF12)>, /* FMC_D15 */ + <STM32_PINMUX('G', 9, AF12)>, /* FMC_NE2_FMC_NCE */ + <STM32_PINMUX('G', 12, AF12)>; /* FMC_NE4 */ + bias-disable; + drive-push-pull; + slew-rate = <3>; + }; + }; + + fmc_sleep_pins_b: fmc-sleep-1 { + pins { + pinmux = <STM32_PINMUX('D', 4, ANALOG)>, /* FMC_NOE */ + <STM32_PINMUX('D', 5, ANALOG)>, /* FMC_NWE */ + <STM32_PINMUX('B', 7, ANALOG)>, /* FMC_NL */ + <STM32_PINMUX('D', 14, ANALOG)>, /* FMC_D0 */ + <STM32_PINMUX('D', 15, ANALOG)>, /* FMC_D1 */ + <STM32_PINMUX('D', 0, ANALOG)>, /* FMC_D2 */ + <STM32_PINMUX('D', 1, ANALOG)>, /* FMC_D3 */ + <STM32_PINMUX('E', 7, ANALOG)>, /* FMC_D4 */ + <STM32_PINMUX('E', 8, ANALOG)>, /* FMC_D5 */ + <STM32_PINMUX('E', 9, ANALOG)>, /* FMC_D6 */ + <STM32_PINMUX('E', 10, ANALOG)>, /* FMC_D7 */ + <STM32_PINMUX('E', 11, ANALOG)>, /* FMC_D8 */ + <STM32_PINMUX('E', 12, ANALOG)>, /* FMC_D9 */ + <STM32_PINMUX('E', 13, ANALOG)>, /* FMC_D10 */ + <STM32_PINMUX('E', 14, ANALOG)>, /* FMC_D11 */ + <STM32_PINMUX('E', 15, ANALOG)>, /* FMC_D12 */ + <STM32_PINMUX('D', 8, ANALOG)>, /* FMC_D13 */ + <STM32_PINMUX('D', 9, ANALOG)>, /* FMC_D14 */ + <STM32_PINMUX('D', 10, ANALOG)>, /* FMC_D15 */ + <STM32_PINMUX('G', 9, ANALOG)>, /* FMC_NE2_FMC_NCE */ + <STM32_PINMUX('G', 12, ANALOG)>; /* FMC_NE4 */ + }; + }; + i2c1_pins_a: i2c1-0 { pins { pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */ @@ -1591,6 +1646,27 @@ }; }; + spi4_pins_a: spi4-0 { + pins { + pinmux = <STM32_PINMUX('E', 12, AF5)>, /* SPI4_SCK */ + <STM32_PINMUX('E', 6, AF5)>; /* SPI4_MOSI */ + bias-disable; + drive-push-pull; + slew-rate = <1>; + }; + pins2 { + pinmux = <STM32_PINMUX('E', 13, AF5)>; /* SPI4_MISO */ + bias-disable; + }; + }; + + stusb1600_pins_a: stusb1600-0 { + pins { + pinmux = <STM32_PINMUX('I', 11, ANALOG)>; + bias-pull-up; + }; + }; + uart4_pins_a: uart4-0 { pins1 { pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */ @@ -1726,20 +1802,6 @@ }; }; - spi4_pins_a: spi4-0 { - pins { - pinmux = <STM32_PINMUX('E', 12, AF5)>, /* SPI4_SCK */ - <STM32_PINMUX('E', 6, AF5)>; /* SPI4_MOSI */ - bias-disable; - drive-push-pull; - slew-rate = <1>; - }; - pins2 { - pinmux = <STM32_PINMUX('E', 13, AF5)>; /* SPI4_MISO */ - bias-disable; - }; - }; - usart2_pins_a: usart2-0 { pins1 { pinmux = <STM32_PINMUX('F', 5, AF7)>, /* USART2_TX */ diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi index 84757901cd8d..3c75abacb374 100644 --- a/arch/arm/boot/dts/stm32mp151.dtsi +++ b/arch/arm/boot/dts/stm32mp151.dtsi @@ -362,8 +362,10 @@ #size-cells = <0>; compatible = "st,stm32-lptimer"; reg = <0x40009000 0x400>; + interrupts-extended = <&exti 47 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc LPTIM1_K>; clock-names = "mux"; + wakeup-source; status = "disabled"; pwm { @@ -999,7 +1001,7 @@ dmamux1: dma-router@48002000 { compatible = "st,stm32h7-dmamux"; - reg = <0x48002000 0x1c>; + reg = <0x48002000 0x40>; #dma-cells = <3>; dma-requests = <128>; dma-masters = <&dma1 &dma2>; @@ -1047,7 +1049,7 @@ sdmmc3: sdmmc@48004000 { compatible = "arm,pl18x", "arm,primecell"; - arm,primecell-periphid = <0x10153180>; + arm,primecell-periphid = <0x00253180>; reg = <0x48004000 0x400>; interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "cmd_irq"; @@ -1068,9 +1070,9 @@ resets = <&rcc USBO_R>; reset-names = "dwc2"; interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; - g-rx-fifo-size = <256>; + g-rx-fifo-size = <512>; g-np-tx-fifo-size = <32>; - g-tx-fifo-size = <128 128 64 64 64 64 32 32>; + g-tx-fifo-size = <256 16 16 16 16 16 16 16>; dr_mode = "otg"; usb33d-supply = <&usb33>; status = "disabled"; @@ -1098,7 +1100,7 @@ resets = <&rcc CAMITF_R>; clocks = <&rcc DCMI>; clock-names = "mclk"; - dmas = <&dmamux1 75 0x400 0x0d>; + dmas = <&dmamux1 75 0x400 0x01>; dma-names = "tx"; status = "disabled"; }; @@ -1156,8 +1158,10 @@ #size-cells = <0>; compatible = "st,stm32-lptimer"; reg = <0x50021000 0x400>; + interrupts-extended = <&exti 48 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc LPTIM2_K>; clock-names = "mux"; + wakeup-source; status = "disabled"; pwm { @@ -1183,8 +1187,10 @@ #size-cells = <0>; compatible = "st,stm32-lptimer"; reg = <0x50022000 0x400>; + interrupts-extended = <&exti 50 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc LPTIM3_K>; clock-names = "mux"; + wakeup-source; status = "disabled"; pwm { @@ -1203,8 +1209,10 @@ lptimer4: timer@50023000 { compatible = "st,stm32-lptimer"; reg = <0x50023000 0x400>; + interrupts-extended = <&exti 52 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc LPTIM4_K>; clock-names = "mux"; + wakeup-source; status = "disabled"; pwm { @@ -1217,8 +1225,10 @@ lptimer5: timer@50024000 { compatible = "st,stm32-lptimer"; reg = <0x50024000 0x400>; + interrupts-extended = <&exti 53 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc LPTIM5_K>; clock-names = "mux"; + wakeup-source; status = "disabled"; pwm { @@ -1284,7 +1294,7 @@ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc HASH1>; resets = <&rcc HASH1_R>; - dmas = <&mdma1 31 0x10 0x1000A02 0x0 0x0>; + dmas = <&mdma1 31 0x2 0x1000A02 0x0 0x0>; dma-names = "in"; dma-maxburst = <2>; status = "disabled"; @@ -1348,8 +1358,8 @@ reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; reg-names = "qspi", "qspi_mm"; interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>; - dmas = <&mdma1 22 0x10 0x100002 0x0 0x0>, - <&mdma1 22 0x10 0x100008 0x0 0x0>; + dmas = <&mdma1 22 0x2 0x100002 0x0 0x0>, + <&mdma1 22 0x2 0x100008 0x0 0x0>; dma-names = "tx", "rx"; clocks = <&rcc QSPI_K>; resets = <&rcc QSPI_R>; @@ -1360,7 +1370,7 @@ sdmmc1: sdmmc@58005000 { compatible = "arm,pl18x", "arm,primecell"; - arm,primecell-periphid = <0x10153180>; + arm,primecell-periphid = <0x00253180>; reg = <0x58005000 0x1000>; interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "cmd_irq"; @@ -1375,7 +1385,7 @@ sdmmc2: sdmmc@58007000 { compatible = "arm,pl18x", "arm,primecell"; - arm,primecell-periphid = <0x10153180>; + arm,primecell-periphid = <0x00253180>; reg = <0x58007000 0x1000>; interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "cmd_irq"; @@ -1426,7 +1436,7 @@ status = "disabled"; }; - usbh_ohci: usbh-ohci@5800c000 { + usbh_ohci: usb@5800c000 { compatible = "generic-ohci"; reg = <0x5800c000 0x1000>; clocks = <&rcc USBH>; @@ -1435,7 +1445,7 @@ status = "disabled"; }; - usbh_ehci: usbh-ehci@5800d000 { + usbh_ehci: usb@5800d000 { compatible = "generic-ehci"; reg = <0x5800d000 0x1000>; clocks = <&rcc USBH>; @@ -1563,6 +1573,11 @@ status = "disabled"; }; + tamp: tamp@5c00a000 { + compatible = "st,stm32-tamp", "syscon", "simple-mfd"; + reg = <0x5c00a000 0x400>; + }; + /* * Break node order to solve dependency probe issue between * pinctrl and exti. @@ -1739,6 +1754,8 @@ st,syscfg-holdboot = <&rcc 0x10C 0x1>; st,syscfg-tz = <&rcc 0x000 0x1>; st,syscfg-pdds = <&pwr_mcu 0x0 0x1>; + st,syscfg-rsc-tbl = <&tamp 0x144 0xFFFFFFFF>; + st,syscfg-m4-state = <&tamp 0x148 0xFFFFFFFF>; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/stm32mp157c-dhcom-picoitx.dts b/arch/arm/boot/dts/stm32mp157c-dhcom-picoitx.dts new file mode 100644 index 000000000000..cfb8f8a0c82d --- /dev/null +++ b/arch/arm/boot/dts/stm32mp157c-dhcom-picoitx.dts @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2020 Marek Vasut <marex@denx.de> + * + * DHCOM STM32MP1 variant: + * DHCM-STM32MP157C-C065-R102-F0819-SPI-E-CAN2-SD-RTC-T-DSI-I-01D2 + * DHCOM PCB number: 587-200 or newer + * PicoITX PCB number: 487-600 or newer + */ +/dts-v1/; + +#include "stm32mp157.dtsi" +#include "stm32mp15xc.dtsi" +#include "stm32mp15xx-dhcom-som.dtsi" +#include "stm32mp15xx-dhcom-picoitx.dtsi" + +/ { + model = "DH electronics STM32MP157C DHCOM PicoITX"; + compatible = "dh,stm32mp157c-dhcom-picoitx", "dh,stm32mp157c-dhcom-som", + "st,stm32mp157"; +}; + +&m_can1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&m_can1_pins_a>; + pinctrl-1 = <&m_can1_sleep_pins_a>; + status = "okay"; +}; + +&m_can2 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&m_can2_pins_a>; + pinctrl-1 = <&m_can2_sleep_pins_a>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/stm32mp157c-dk2.dts b/arch/arm/boot/dts/stm32mp157c-dk2.dts index 045636555ddd..2bc92ef3aeb9 100644 --- a/arch/arm/boot/dts/stm32mp157c-dk2.dts +++ b/arch/arm/boot/dts/stm32mp157c-dk2.dts @@ -29,6 +29,10 @@ }; }; +&cryp1 { + status = "okay"; +}; + &dsi { status = "okay"; phy-dsi-supply = <®18>; diff --git a/arch/arm/boot/dts/stm32mp157c-ed1.dts b/arch/arm/boot/dts/stm32mp157c-ed1.dts index 2e77ccec3fc1..81a7d5849db4 100644 --- a/arch/arm/boot/dts/stm32mp157c-ed1.dts +++ b/arch/arm/boot/dts/stm32mp157c-ed1.dts @@ -115,6 +115,14 @@ }; }; +&crc1 { + status = "okay"; +}; + +&cryp1 { + status = "okay"; +}; + &dac { pinctrl-names = "default"; pinctrl-0 = <&dac_ch1_pins_a &dac_ch2_pins_a>; @@ -136,6 +144,10 @@ contiguous-area = <&gpu_reserved>; }; +&hash1 { + status = "okay"; +}; + &i2c4 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&i2c4_pins_a>; diff --git a/arch/arm/boot/dts/stm32mp157c-ev1.dts b/arch/arm/boot/dts/stm32mp157c-ev1.dts index a55e80ce2602..5c5b1ddf7bfd 100644 --- a/arch/arm/boot/dts/stm32mp157c-ev1.dts +++ b/arch/arm/boot/dts/stm32mp157c-ev1.dts @@ -90,6 +90,7 @@ port { dcmi_0: endpoint { remote-endpoint = <&ov5640_0>; + bus-type = <5>; bus-width = <8>; hsync-active = <0>; vsync-active = <0>; diff --git a/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts b/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts index 1e5333fd437f..cda8e871f999 100644 --- a/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts +++ b/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts @@ -15,7 +15,7 @@ / { model = "Linux Automation MC-1 board"; - compatible = "lxa,stm32mp157c-mc1", "st,stm32mp157"; + compatible = "lxa,stm32mp157c-mc1", "oct,stm32mp15xx-osd32", "st,stm32mp157"; aliases { ethernet0 = ðernet0; diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi new file mode 100644 index 000000000000..356150d28c42 --- /dev/null +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-picoitx.dtsi @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2020 Marek Vasut <marex@denx.de> + */ + +#include <dt-bindings/input/input.h> +#include <dt-bindings/pwm/pwm.h> + +/ { + aliases { + serial0 = &uart4; + serial1 = &usart3; + serial2 = &uart8; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + led { + compatible = "gpio-leds"; + + led-0 { + label = "yellow:led"; + gpios = <&gpioi 3 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; +}; + +&adc { + status = "disabled"; +}; + +&dac { + status = "disabled"; +}; + +&gpioa { + /* + * NOTE: The USB Port on the PicoITX needs a PWR_EN signal to enable + * port power. This signal should be handled by USB power sequencing + * in order to turn on port power when USB bus is powered up, but so + * far there is no such functionality. + */ + usb-port-power { + gpio-hog; + gpios = <13 GPIO_ACTIVE_LOW>; + output-low; + line-name = "usb-port-power"; + }; +}; + +&gpioc { + gpio-line-names = "", "", "", "", + "", "", "In1", "", + "", "", "", "", + "", "", "", ""; +}; + +&gpiod { + gpio-line-names = "", "", "", "", + "", "", "", "", + "", "", "", "Out1", + "Out2", "", "", ""; +}; + +&gpiog { + gpio-line-names = "In2", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", ""; +}; + +&i2c2 { /* On board-to-board connector (optional) */ + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + i2c-scl-rising-time-ns = <185>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; + /* spare dmas for other usage */ + /delete-property/dmas; + /delete-property/dma-names; +}; + +&i2c5 { /* On board-to-board connector */ + pinctrl-names = "default"; + pinctrl-0 = <&i2c5_pins_a>; + i2c-scl-rising-time-ns = <185>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; + /* spare dmas for other usage */ + /delete-property/dmas; + /delete-property/dma-names; +}; + +&usart3 { + pinctrl-names = "default"; + pinctrl-0 = <&usart3_pins_a>; + status = "okay"; +}; + +&uart8 { + pinctrl-names = "default"; + pinctrl-0 = <&uart8_pins_a &uart8_rtscts_pins_a>; + status = "okay"; +}; + +&usbh_ehci { + phys = <&usbphyc_port0>; + status = "okay"; +}; + +&usbh_ohci { + phys = <&usbphyc_port0>; + status = "okay"; +}; + +&usbotg_hs { + dr_mode = "otg"; + pinctrl-0 = <&usbotg_hs_pins_a>; + pinctrl-names = "default"; + phy-names = "usb2-phy"; + phys = <&usbphyc_port1 0>; + vbus-supply = <&vbus_otg>; + status = "okay"; +}; + +&usbphyc { + status = "okay"; +}; + +&usbphyc_port0 { + phy-supply = <&vdd_usb>; + vdda1v1-supply = <®11>; + vdda1v8-supply = <®18>; +}; + +&usbphyc_port1 { + phy-supply = <&vdd_usb>; + vdda1v1-supply = <®11>; + vdda1v8-supply = <®18>; +}; diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi index f796a6150313..ac46ab363e1b 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi @@ -11,6 +11,7 @@ / { aliases { ethernet0 = ðernet0; + ethernet1 = &ksz8851; }; memory@c0000000 { @@ -127,10 +128,46 @@ phy0: ethernet-phy@1 { reg = <1>; + interrupt-parent = <&gpioi>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; }; }; }; +&fmc { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&fmc_pins_b>; + pinctrl-1 = <&fmc_sleep_pins_b>; + status = "okay"; + + ksz8851: ks8851mll@1,0 { + compatible = "micrel,ks8851-mll"; + reg = <1 0x0 0x2>, <1 0x2 0x20000>; + interrupt-parent = <&gpioc>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; + bank-width = <2>; + + /* Timing values are in nS */ + st,fmc2-ebi-cs-mux-enable; + st,fmc2-ebi-cs-transaction-type = <4>; + st,fmc2-ebi-cs-buswidth = <16>; + st,fmc2-ebi-cs-address-setup-ns = <5>; + st,fmc2-ebi-cs-address-hold-ns = <5>; + st,fmc2-ebi-cs-bus-turnaround-ns = <5>; + st,fmc2-ebi-cs-data-setup-ns = <45>; + st,fmc2-ebi-cs-data-hold-ns = <1>; + st,fmc2-ebi-cs-write-address-setup-ns = <5>; + st,fmc2-ebi-cs-write-address-hold-ns = <5>; + st,fmc2-ebi-cs-write-bus-turnaround-ns = <5>; + st,fmc2-ebi-cs-write-data-setup-ns = <45>; + st,fmc2-ebi-cs-write-data-hold-ns = <1>; + }; +}; + +&gpioc { + status = "okay"; +}; + &i2c4 { pinctrl-names = "default"; pinctrl-0 = <&i2c4_pins_a>; diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi index 93398cfae97e..89c0e1ddc387 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi @@ -124,6 +124,10 @@ status = "okay"; }; +&crc1 { + status = "okay"; +}; + &dts { status = "okay"; }; @@ -151,6 +155,10 @@ contiguous-area = <&gpu_reserved>; }; +&hash1 { + status = "okay"; +}; + &i2c1 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&i2c1_pins_a>; @@ -238,6 +246,30 @@ /delete-property/dmas; /delete-property/dma-names; + stusb1600@28 { + compatible = "st,stusb1600"; + reg = <0x28>; + interrupts = <11 IRQ_TYPE_EDGE_FALLING>; + interrupt-parent = <&gpioi>; + pinctrl-names = "default"; + pinctrl-0 = <&stusb1600_pins_a>; + status = "okay"; + vdd-supply = <&vin>; + + connector { + compatible = "usb-c-connector"; + label = "USB-C"; + power-role = "dual"; + typec-power-opmode = "default"; + + port { + con_usbotg_hs_ep: endpoint { + remote-endpoint = <&usbotg_hs_ep>; + }; + }; + }; + }; + pmic: stpmic@33 { compatible = "st,stpmic1"; reg = <0x33>; @@ -648,6 +680,12 @@ phy-names = "usb2-phy"; usb-role-switch; status = "okay"; + + port { + usbotg_hs_ep: endpoint { + remote-endpoint = <&con_usbotg_hs_ep>; + }; + }; }; &usbphyc { diff --git a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts index 4c6704e4c57e..e76d56a3df9c 100644 --- a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts +++ b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts @@ -136,6 +136,70 @@ }; +&pio { + gpio-line-names = + /* PA */ + "CON2-P13", "CON2-P11", "CON2-P22", "CON2-P15", + "CON3-P03", "CON3-P02", "CON2-P07", "CON2-P29", + "CON2-P31", "CON2-P33", "CON2-P35", "CON2-P05", + "CON2-P03", "CON2-P08", "CON2-P10", "CON2-P16", + "CON2-P12", "CON2-P37", "CON2-P28", "CON2-P27", + "CON2-P40", "CON2-P38", "", "", + "", "", "", "", "", "", "", "", + + /* PB */ + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + + /* PC */ + "CON2-P19", "CON2-P21", "CON2-P23", "CON2-P24", + "CON2-P18", "", "", "CON2-P26", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + + /* PD */ + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "CSI-PWR-EN", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + + /* PE */ + "CN3-P17", "CN3-P13", "CN3-P09", "CN3-P07", + "CN3-P19", "CN3-P21", "CN3-P22", "CN3-P20", + "CN3-P18", "CN3-P16", "CN3-P14", "CN3-P12", + "CN3-P05", "CN3-P03", "CN3-P06", "CN3-P08", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + + /* PF */ + "SDC0-D1", "SDC0-D0", "SDC0-CLK", "SDC0-CMD", "SDC0-D3", + "SDC0-D2", "SDC0-DET", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + + /* PG */ + "WL-SDIO-CLK", "WL-SDIO-CMD", "WL-SDIO-D0", "WL-SDIO-D1", + "WL-SDIO-D2", "WL-SDIO-D3", "BT-UART-TX", "BT-UART-RX", + "BT-UART-RTS", "BT-UART-CTS", "WL-WAKE-AP", "BT-WAKE-AP", + "BT-RST-N", "AP-WAKE-BT", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&r_pio { + gpio-line-names = + /* PL */ + "", "CPUX-SET", "CON2-P32", "POWER-KEY", "CON2-P36", + "VCC-IO-EN", "USB0-ID", "WL-PWR-EN", + "PWR-STB", "PWR-DRAM", "PWR-LED", "IR-RX", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + &usb_otg { dr_mode = "otg"; status = "okay"; diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-r1.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-r1.dts new file mode 100644 index 000000000000..204a39f93f4e --- /dev/null +++ b/arch/arm/boot/dts/sun8i-h3-nanopi-r1.dts @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2019 Igor Pecovnik <igor@armbian.com> + * Copyright (C) 2020 Jayantajit Gogoi <jayanta.gogoi525@gmail.com> + * Copyright (C) 2020 Yu-Tung Chang <mtwget@gmail.com> +*/ + +#include "sun8i-h3-nanopi.dtsi" +#include <dt-bindings/leds/common.h> + +/ { + model = "FriendlyARM NanoPi R1"; + compatible = "friendlyarm,nanopi-r1", "allwinner,sun8i-h3"; + + aliases { + serial1 = &uart1; + ethernet0 = &emac; + ethernet1 = &wifi; + }; + + reg_gmac_3v3: gmac-3v3 { + compatible = "regulator-fixed"; + regulator-name = "gmac-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <100000>; + enable-active-high; + gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */ + }; + + reg_vdd_cpux: gpio-regulator { + compatible = "regulator-gpio"; + regulator-name = "vdd-cpux"; + regulator-type = "voltage"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1300000>; + regulator-ramp-delay = <50>; + gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */ + gpios-states = <0x1>; + states = <1100000 0x0 + 1300000 0x1>; + }; + + wifi_pwrseq: wifi_pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */ + clocks = <&rtc 1>; + clock-names = "ext_clock"; + }; + + leds { + led-2 { + function = LED_FUNCTION_WAN; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pio 6 11 GPIO_ACTIVE_HIGH>; /* PG11 */ + }; + + led-3 { + function = LED_FUNCTION_LAN; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pio 0 9 GPIO_ACTIVE_HIGH>; /* PA9 */ + }; + }; +}; + +&cpu0 { + cpu-supply = <®_vdd_cpux>; +}; + +&ehci1 { + status = "okay"; +}; + +&ehci2 { + status = "okay"; +}; + +&emac { + pinctrl-names = "default"; + pinctrl-0 = <&emac_rgmii_pins>; + phy-supply = <®_gmac_3v3>; + phy-handle = <&ext_rgmii_phy>; + phy-mode = "rgmii-id"; + status = "okay"; +}; + +&external_mdio { + ext_rgmii_phy: ethernet-phy@7 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <7>; + }; +}; + +&mmc1 { + vmmc-supply = <®_vcc3v3>; + vqmmc-supply = <®_vcc3v3>; + mmc-pwrseq = <&wifi_pwrseq>; + bus-width = <4>; + non-removable; + status = "okay"; + + wifi: wifi@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + interrupt-parent = <&pio>; + interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 / EINT10 */ + interrupt-names = "host-wake"; + }; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_pins>; + vmmc-supply = <®_vcc3v3>; + vqmmc-supply = <®_vcc3v3>; + bus-width = <8>; + non-removable; + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&ohci2 { + status = "okay"; +}; + +®_usb0_vbus { + gpio = <&r_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */ + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>, <&uart3_rts_cts_pins>; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + clocks = <&rtc 1>; + clock-names = "lpo"; + vbat-supply = <®_vcc3v3>; + vddio-supply = <®_vcc3v3>; + device-wakeup-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */ + host-wakeup-gpios = <&pio 0 7 GPIO_ACTIVE_HIGH>; /* PA7 */ + shutdown-gpios = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */ + }; +}; + +&usb_otg { + status = "okay"; + dr_mode = "otg"; +}; + +&usbphy { + usb0_id_det-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */ + usb0_vbus-supply = <®_usb0_vbus>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-h3-zeropi.dts b/arch/arm/boot/dts/sun8i-h3-zeropi.dts new file mode 100644 index 000000000000..7d3e7323b661 --- /dev/null +++ b/arch/arm/boot/dts/sun8i-h3-zeropi.dts @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2020 Yu-Tung Chang <mtwget@gmail.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. + */ + +#include "sun8i-h3-nanopi.dtsi" + +/ { + model = "FriendlyARM ZeroPi"; + compatible = "friendlyarm,zeropi", "allwinner,sun8i-h3"; + + aliases { + ethernet0 = &emac; + }; + + reg_gmac_3v3: gmac-3v3 { + compatible = "regulator-fixed"; + regulator-name = "gmac-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <100000>; + enable-active-high; + gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */ + }; +}; + +&external_mdio { + ext_rgmii_phy: ethernet-phy@7 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <7>; + }; +}; + +&emac { + pinctrl-names = "default"; + pinctrl-0 = <&emac_rgmii_pins>; + phy-supply = <®_gmac_3v3>; + phy-handle = <&ext_rgmii_phy>; + phy-mode = "rgmii-id"; + + allwinner,leds-active-low; + status = "okay"; +}; + +&usb_otg { + status = "okay"; + dr_mode = "host"; +}; diff --git a/arch/arm/boot/dts/sun8i-s3-elimo-impetus.dtsi b/arch/arm/boot/dts/sun8i-s3-elimo-impetus.dtsi new file mode 100644 index 000000000000..24d507cdbcf9 --- /dev/null +++ b/arch/arm/boot/dts/sun8i-s3-elimo-impetus.dtsi @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2020 Matteo Scordino <matteo@elimo.io> + */ + +/dts-v1/; +#include "sun8i-v3.dtsi" +#include "sunxi-common-regulators.dtsi" + +/ { + model = "Elimo Impetus SoM"; + compatible = "elimo,impetus", "sochip,s3", "allwinner,sun8i-v3"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&mmc0 { + broken-cd; + bus-width = <4>; + vmmc-supply = <®_vcc3v3>; + status = "okay"; +}; + +&uart0 { + pinctrl-0 = <&uart0_pb_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usbphy { + usb0_id_det-gpio = <&pio 5 6 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-s3-elimo-initium.dts b/arch/arm/boot/dts/sun8i-s3-elimo-initium.dts new file mode 100644 index 000000000000..039677c2cc65 --- /dev/null +++ b/arch/arm/boot/dts/sun8i-s3-elimo-initium.dts @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2020 Matteo Scordino <matteo@elimo.io> + */ + +/dts-v1/; +#include "sun8i-s3-elimo-impetus.dtsi" + +/ { + model = "Elimo Initium"; + compatible = "elimo,initium", "elimo,impetus", "sochip,s3", + "allwinner,sun8i-v3"; + + aliases { + serial1 = &uart1; + }; +}; + +&uart1 { + pinctrl-0 = <&uart1_pg_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&emac { + phy-handle = <&int_mii_phy>; + phy-mode = "mii"; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-v3.dtsi b/arch/arm/boot/dts/sun8i-v3.dtsi index ca4672ed2e02..c279e13583ba 100644 --- a/arch/arm/boot/dts/sun8i-v3.dtsi +++ b/arch/arm/boot/dts/sun8i-v3.dtsi @@ -24,4 +24,9 @@ &pio { compatible = "allwinner,sun8i-v3-pinctrl"; + + uart1_pg_pins: uart1-pg-pins { + pins = "PG6", "PG7"; + function = "uart1"; + }; }; diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi index 89abd4cc7e23..f8f19d8fa795 100644 --- a/arch/arm/boot/dts/sun8i-v3s.dtsi +++ b/arch/arm/boot/dts/sun8i-v3s.dtsi @@ -348,6 +348,12 @@ }; /omit-if-no-ref/ + i2c1_pb_pins: i2c1-pb-pins { + pins = "PB8", "PB9"; + function = "i2c1"; + }; + + /omit-if-no-ref/ i2c1_pe_pins: i2c1-pe-pins { pins = "PE21", "PE22"; function = "i2c1"; diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi index 22d533d18992..9be13378d4df 100644 --- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi +++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi @@ -662,6 +662,19 @@ status = "disabled"; }; + i2s2: i2s@1c22800 { + #sound-dai-cells = <0>; + compatible = "allwinner,sun8i-h3-i2s"; + reg = <0x01c22800 0x400>; + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2S2>, <&ccu CLK_I2S2>; + clock-names = "apb", "mod"; + dmas = <&dma 27>; + resets = <&ccu RST_BUS_I2S2>; + dma-names = "tx"; + status = "disabled"; + }; + codec: codec@1c22c00 { #sound-dai-cells = <0>; compatible = "allwinner,sun8i-h3-codec"; diff --git a/arch/arm/boot/dts/tegra124-apalis-emc.dtsi b/arch/arm/boot/dts/tegra124-apalis-emc.dtsi index 32401457ae71..a7ac805eeed5 100644 --- a/arch/arm/boot/dts/tegra124-apalis-emc.dtsi +++ b/arch/arm/boot/dts/tegra124-apalis-emc.dtsi @@ -1465,3 +1465,11 @@ }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@1200000000,1100; +}; + +&emc_bw_dfs_opp_table { + /delete-node/ opp@1200000000; +}; diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi index 861d3f22116b..df4e463afbd1 100644 --- a/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi +++ b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi @@ -2420,3 +2420,11 @@ }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@1200000000,1100; +}; + +&emc_bw_dfs_opp_table { + /delete-node/ opp@1200000000; +}; diff --git a/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi b/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi index c91647d13a50..a0f56cc9da5c 100644 --- a/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi +++ b/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi @@ -6649,3 +6649,13 @@ }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@924000000,1100; + /delete-node/ opp@1200000000,1100; +}; + +&emc_bw_dfs_opp_table { + /delete-node/ opp@924000000; + /delete-node/ opp@1200000000; +}; diff --git a/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi b/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi index d2beea0bd15f..35c98734d35f 100644 --- a/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi +++ b/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi @@ -2048,3 +2048,13 @@ }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@924000000,1100; + /delete-node/ opp@1200000000,1100; +}; + +&emc_bw_dfs_opp_table { + /delete-node/ opp@924000000; + /delete-node/ opp@1200000000; +}; diff --git a/arch/arm/boot/dts/tegra124-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra124-peripherals-opp.dtsi new file mode 100644 index 000000000000..49d9420a3289 --- /dev/null +++ b/arch/arm/boot/dts/tegra124-peripherals-opp.dtsi @@ -0,0 +1,419 @@ +// SPDX-License-Identifier: GPL-2.0 + +/ { + emc_icc_dvfs_opp_table: emc-dvfs-opp-table { + compatible = "operating-points-v2"; + + opp@12750000,800 { + opp-microvolt = <800000 800000 1150000>; + opp-hz = /bits/ 64 <12750000>; + opp-supported-hw = <0x0003>; + }; + + opp@12750000,950 { + opp-microvolt = <950000 950000 1150000>; + opp-hz = /bits/ 64 <12750000>; + opp-supported-hw = <0x0008>; + }; + + opp@12750000,1050 { + opp-microvolt = <1050000 1050000 1150000>; + opp-hz = /bits/ 64 <12750000>; + opp-supported-hw = <0x0010>; + }; + + opp@12750000,1110 { + opp-microvolt = <1110000 1110000 1150000>; + opp-hz = /bits/ 64 <12750000>; + opp-supported-hw = <0x0004>; + }; + + opp@20400000,800 { + opp-microvolt = <800000 800000 1150000>; + opp-hz = /bits/ 64 <20400000>; + opp-supported-hw = <0x0003>; + }; + + opp@20400000,950 { + opp-microvolt = <950000 950000 1150000>; + opp-hz = /bits/ 64 <20400000>; + opp-supported-hw = <0x0008>; + }; + + opp@20400000,1050 { + opp-microvolt = <1050000 1050000 1150000>; + opp-hz = /bits/ 64 <20400000>; + opp-supported-hw = <0x0010>; + }; + + opp@20400000,1110 { + opp-microvolt = <1110000 1110000 1150000>; + opp-hz = /bits/ 64 <20400000>; + opp-supported-hw = <0x0004>; + }; + + opp@40800000,800 { + opp-microvolt = <800000 800000 1150000>; + opp-hz = /bits/ 64 <40800000>; + opp-supported-hw = <0x0003>; + }; + + opp@40800000,950 { + opp-microvolt = <950000 950000 1150000>; + opp-hz = /bits/ 64 <40800000>; + opp-supported-hw = <0x0008>; + }; + + opp@40800000,1050 { + opp-microvolt = <1050000 1050000 1150000>; + opp-hz = /bits/ 64 <40800000>; + opp-supported-hw = <0x0010>; + }; + + opp@40800000,1110 { + opp-microvolt = <1110000 1110000 1150000>; + opp-hz = /bits/ 64 <40800000>; + opp-supported-hw = <0x0004>; + }; + + opp@68000000,800 { + opp-microvolt = <800000 800000 1150000>; + opp-hz = /bits/ 64 <68000000>; + opp-supported-hw = <0x0003>; + }; + + opp@68000000,950 { + opp-microvolt = <950000 950000 1150000>; + opp-hz = /bits/ 64 <68000000>; + opp-supported-hw = <0x0008>; + }; + + opp@68000000,1050 { + opp-microvolt = <1050000 1050000 1150000>; + opp-hz = /bits/ 64 <68000000>; + opp-supported-hw = <0x0010>; + }; + + opp@68000000,1110 { + opp-microvolt = <1110000 1110000 1150000>; + opp-hz = /bits/ 64 <68000000>; + opp-supported-hw = <0x0004>; + }; + + opp@102000000,800 { + opp-microvolt = <800000 800000 1150000>; + opp-hz = /bits/ 64 <102000000>; + opp-supported-hw = <0x0003>; + }; + + opp@102000000,950 { + opp-microvolt = <950000 950000 1150000>; + opp-hz = /bits/ 64 <102000000>; + opp-supported-hw = <0x0008>; + }; + + opp@102000000,1050 { + opp-microvolt = <1050000 1050000 1150000>; + opp-hz = /bits/ 64 <102000000>; + opp-supported-hw = <0x0010>; + }; + + opp@102000000,1110 { + opp-microvolt = <1110000 1110000 1150000>; + opp-hz = /bits/ 64 <102000000>; + opp-supported-hw = <0x0004>; + }; + + opp@204000000,800 { + opp-microvolt = <800000 800000 1150000>; + opp-hz = /bits/ 64 <204000000>; + opp-supported-hw = <0x0003>; + }; + + opp@204000000,950 { + opp-microvolt = <950000 950000 1150000>; + opp-hz = /bits/ 64 <204000000>; + opp-supported-hw = <0x0008>; + }; + + opp@204000000,1050 { + opp-microvolt = <1050000 1050000 1150000>; + opp-hz = /bits/ 64 <204000000>; + opp-supported-hw = <0x0010>; + }; + + opp@204000000,1110 { + opp-microvolt = <1110000 1110000 1150000>; + opp-hz = /bits/ 64 <204000000>; + opp-supported-hw = <0x0004>; + }; + + opp@264000000,800 { + opp-microvolt = <800000 800000 1150000>; + opp-hz = /bits/ 64 <264000000>; + opp-supported-hw = <0x0003>; + }; + + opp@264000000,950 { + opp-microvolt = <950000 950000 1150000>; + opp-hz = /bits/ 64 <264000000>; + opp-supported-hw = <0x0008>; + }; + + opp@264000000,1050 { + opp-microvolt = <1050000 1050000 1150000>; + opp-hz = /bits/ 64 <264000000>; + opp-supported-hw = <0x0010>; + }; + + opp@264000000,1110 { + opp-microvolt = <1110000 1110000 1150000>; + opp-hz = /bits/ 64 <264000000>; + opp-supported-hw = <0x0004>; + }; + + opp@300000000,850 { + opp-microvolt = <850000 850000 1150000>; + opp-hz = /bits/ 64 <300000000>; + opp-supported-hw = <0x0003>; + }; + + opp@300000000,950 { + opp-microvolt = <950000 950000 1150000>; + opp-hz = /bits/ 64 <300000000>; + opp-supported-hw = <0x0008>; + }; + + opp@300000000,1050 { + opp-microvolt = <1050000 1050000 1150000>; + opp-hz = /bits/ 64 <300000000>; + opp-supported-hw = <0x0010>; + }; + + opp@300000000,1110 { + opp-microvolt = <1110000 1110000 1150000>; + opp-hz = /bits/ 64 <300000000>; + opp-supported-hw = <0x0004>; + }; + + opp@348000000,850 { + opp-microvolt = <850000 850000 1150000>; + opp-hz = /bits/ 64 <348000000>; + opp-supported-hw = <0x0003>; + }; + + opp@348000000,950 { + opp-microvolt = <950000 950000 1150000>; + opp-hz = /bits/ 64 <348000000>; + opp-supported-hw = <0x0008>; + }; + + opp@348000000,1050 { + opp-microvolt = <1050000 1050000 1150000>; + opp-hz = /bits/ 64 <348000000>; + opp-supported-hw = <0x0010>; + }; + + opp@348000000,1110 { + opp-microvolt = <1110000 1110000 1150000>; + opp-hz = /bits/ 64 <348000000>; + opp-supported-hw = <0x0004>; + }; + + opp@396000000,950 { + opp-microvolt = <950000 950000 1150000>; + opp-hz = /bits/ 64 <396000000>; + opp-supported-hw = <0x0008>; + }; + + opp@396000000,1000 { + opp-microvolt = <1000000 1000000 1150000>; + opp-hz = /bits/ 64 <396000000>; + opp-supported-hw = <0x0003>; + }; + + opp@396000000,1050 { + opp-microvolt = <1050000 1050000 1150000>; + opp-hz = /bits/ 64 <396000000>; + opp-supported-hw = <0x0010>; + }; + + opp@396000000,1110 { + opp-microvolt = <1110000 1110000 1150000>; + opp-hz = /bits/ 64 <396000000>; + opp-supported-hw = <0x0004>; + }; + + opp@528000000,950 { + opp-microvolt = <950000 950000 1150000>; + opp-hz = /bits/ 64 <528000000>; + opp-supported-hw = <0x0008>; + }; + + opp@528000000,1000 { + opp-microvolt = <1000000 1000000 1150000>; + opp-hz = /bits/ 64 <528000000>; + opp-supported-hw = <0x0003>; + }; + + opp@528000000,1050 { + opp-microvolt = <1050000 1050000 1150000>; + opp-hz = /bits/ 64 <528000000>; + opp-supported-hw = <0x0010>; + }; + + opp@528000000,1110 { + opp-microvolt = <1110000 1110000 1150000>; + opp-hz = /bits/ 64 <528000000>; + opp-supported-hw = <0x0004>; + }; + + opp@600000000,950 { + opp-microvolt = <950000 950000 1150000>; + opp-hz = /bits/ 64 <600000000>; + opp-supported-hw = <0x0008>; + }; + + opp@600000000,1000 { + opp-microvolt = <1000000 1000000 1150000>; + opp-hz = /bits/ 64 <600000000>; + opp-supported-hw = <0x0003>; + }; + + opp@600000000,1050 { + opp-microvolt = <1050000 1050000 1150000>; + opp-hz = /bits/ 64 <600000000>; + opp-supported-hw = <0x0010>; + }; + + opp@600000000,1110 { + opp-microvolt = <1110000 1110000 1150000>; + opp-hz = /bits/ 64 <600000000>; + opp-supported-hw = <0x0004>; + }; + + opp@792000000,1000 { + opp-microvolt = <1000000 1000000 1150000>; + opp-hz = /bits/ 64 <792000000>; + opp-supported-hw = <0x000B>; + }; + + opp@792000000,1050 { + opp-microvolt = <1050000 1050000 1150000>; + opp-hz = /bits/ 64 <792000000>; + opp-supported-hw = <0x0010>; + }; + + opp@792000000,1110 { + opp-microvolt = <1110000 1110000 1150000>; + opp-hz = /bits/ 64 <792000000>; + opp-supported-hw = <0x0004>; + }; + + opp@924000000,1100 { + opp-microvolt = <1100000 1100000 1150000>; + opp-hz = /bits/ 64 <924000000>; + opp-supported-hw = <0x0013>; + }; + + opp@1200000000,1100 { + opp-microvolt = <1100000 1100000 1150000>; + opp-hz = /bits/ 64 <1200000000>; + opp-supported-hw = <0x0003>; + }; + }; + + emc_bw_dfs_opp_table: emc-bandwidth-opp-table { + compatible = "operating-points-v2"; + + opp@12750000 { + opp-hz = /bits/ 64 <12750000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <204000>; + }; + + opp@20400000 { + opp-hz = /bits/ 64 <20400000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <326400>; + }; + + opp@40800000 { + opp-hz = /bits/ 64 <40800000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <652800>; + }; + + opp@68000000 { + opp-hz = /bits/ 64 <68000000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <1088000>; + }; + + opp@102000000 { + opp-hz = /bits/ 64 <102000000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <1632000>; + }; + + opp@204000000 { + opp-hz = /bits/ 64 <204000000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <3264000>; + }; + + opp@264000000 { + opp-hz = /bits/ 64 <264000000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <4224000>; + }; + + opp@300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <4800000>; + }; + + opp@348000000 { + opp-hz = /bits/ 64 <348000000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <5568000>; + }; + + opp@396000000 { + opp-hz = /bits/ 64 <396000000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <6336000>; + }; + + opp@528000000 { + opp-hz = /bits/ 64 <528000000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <8448000>; + }; + + opp@600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <9600000>; + }; + + opp@792000000 { + opp-hz = /bits/ 64 <792000000>; + opp-supported-hw = <0x001F>; + opp-peak-kBps = <12672000>; + }; + + opp@924000000 { + opp-hz = /bits/ 64 <924000000>; + opp-supported-hw = <0x0013>; + opp-peak-kBps = <14784000>; + }; + + opp@1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-supported-hw = <0x0003>; + opp-peak-kBps = <19200000>; + }; + }; +}; diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index 64f488ba1e72..0b678afb2a5c 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -8,6 +8,8 @@ #include <dt-bindings/thermal/tegra124-soctherm.h> #include <dt-bindings/soc/tegra-pmc.h> +#include "tegra124-peripherals-opp.dtsi" + / { compatible = "nvidia,tegra124"; interrupt-parent = <&lic>; @@ -113,6 +115,19 @@ iommus = <&mc TEGRA_SWGROUP_DC>; nvidia,head = <0>; + + interconnects = <&mc TEGRA124_MC_DISPLAY0A &emc>, + <&mc TEGRA124_MC_DISPLAY0B &emc>, + <&mc TEGRA124_MC_DISPLAY0C &emc>, + <&mc TEGRA124_MC_DISPLAYHC &emc>, + <&mc TEGRA124_MC_DISPLAYD &emc>, + <&mc TEGRA124_MC_DISPLAYT &emc>; + interconnect-names = "wina", + "winb", + "winc", + "cursor", + "wind", + "wint"; }; dc@54240000 { @@ -127,6 +142,15 @@ iommus = <&mc TEGRA_SWGROUP_DCB>; nvidia,head = <1>; + + interconnects = <&mc TEGRA124_MC_DISPLAY0AB &emc>, + <&mc TEGRA124_MC_DISPLAY0BB &emc>, + <&mc TEGRA124_MC_DISPLAY0CB &emc>, + <&mc TEGRA124_MC_DISPLAYHCB &emc>; + interconnect-names = "wina", + "winb", + "winc", + "cursor"; }; hdmi: hdmi@54280000 { @@ -268,6 +292,9 @@ clock-names = "actmon", "emc"; resets = <&tegra_car 119>; reset-names = "actmon"; + operating-points-v2 = <&emc_bw_dfs_opp_table>; + interconnects = <&mc TEGRA124_MC_MPCORER &emc>; + interconnect-names = "cpu-read"; }; gpio: gpio@6000d000 { @@ -628,6 +655,7 @@ #iommu-cells = <1>; #reset-cells = <1>; + #interconnect-cells = <1>; }; emc: external-memory-controller@7001b000 { @@ -637,6 +665,9 @@ clock-names = "emc"; nvidia,memory-controller = <&mc>; + operating-points-v2 = <&emc_icc_dvfs_opp_table>; + + #interconnect-cells = <0>; }; sata@70020000 { @@ -650,9 +681,9 @@ <&tegra_car TEGRA124_CLK_PLL_E>; clock-names = "sata", "sata-oob", "cml1", "pll_e"; resets = <&tegra_car 124>, - <&tegra_car 123>, - <&tegra_car 129>; - reset-names = "sata", "sata-oob", "sata-cold"; + <&tegra_car 129>, + <&tegra_car 123>; + reset-names = "sata", "sata-cold", "sata-oob"; status = "disabled"; }; @@ -898,9 +929,11 @@ 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>; + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "thermal", "edp"; clocks = <&tegra_car TEGRA124_CLK_TSENSOR>, - <&tegra_car TEGRA124_CLK_SOC_THERM>; + <&tegra_car TEGRA124_CLK_SOC_THERM>; clock-names = "tsensor", "soctherm"; resets = <&tegra_car 78>; reset-names = "soctherm"; @@ -910,6 +943,7 @@ throttle_heavy: heavy { nvidia,priority = <100>; nvidia,cpu-throt-percent = <85>; + nvidia,gpu-throt-level = <TEGRA_SOCTHERM_THROT_LEVEL_HIGH>; #cooling-cells = <2>; }; @@ -1247,6 +1281,11 @@ hysteresis = <0>; type = "critical"; }; + mem-throttle-trip { + temperature = <99000>; + hysteresis = <1000>; + type = "hot"; + }; }; cooling-maps { @@ -1298,6 +1337,11 @@ hysteresis = <0>; type = "critical"; }; + pllx-throttle-trip { + temperature = <99000>; + hysteresis = <1000>; + type = "hot"; + }; }; cooling-maps { diff --git a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts index 10794a870776..d3b99535d755 100644 --- a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts +++ b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts @@ -512,6 +512,16 @@ reg = <1>; #address-cells = <1>; #size-cells = <0>; + + embedded-controller@58 { + compatible = "acer,a500-iconia-ec", "ene,kb930"; + reg = <0x58>; + + system-power-controller; + + monitored-battery = <&bat1010>; + power-supplies = <&mains>; + }; }; }; @@ -794,6 +804,13 @@ default-brightness-level = <20>; }; + bat1010: battery-2s1p { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3260000>; + energy-full-design-microwatt-hours = <24000000>; + operating-range-celsius = <0 40>; + }; + /* PMIC has a built-in 32KHz oscillator which is used by PMC */ clk32k_in: clock@0 { compatible = "fixed-clock"; @@ -907,6 +924,7 @@ compatible = "ti,sn75lvds83", "lvds-encoder"; powerdown-gpios = <&gpio TEGRA_GPIO(B, 2) GPIO_ACTIVE_LOW>; + power-supply = <&vdd_3v3_sys>; ports { #address-cells = <1>; @@ -1020,14 +1038,14 @@ }; thermal-zones { - nct1008-local { + skin-thermal { polling-delay-passive = <1000>; /* milliseconds */ polling-delay = <0>; /* milliseconds */ thermal-sensors = <&nct1008 0>; }; - nct1008-remote { + cpu-thermal { polling-delay-passive = <1000>; /* milliseconds */ polling-delay = <5000>; /* milliseconds */ @@ -1450,3 +1468,8 @@ }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@666000000; + /delete-node/ opp@760000000; +}; diff --git a/arch/arm/boot/dts/tegra20-colibri.dtsi b/arch/arm/boot/dts/tegra20-colibri.dtsi index 6162d193e12c..585a5b441cf6 100644 --- a/arch/arm/boot/dts/tegra20-colibri.dtsi +++ b/arch/arm/boot/dts/tegra20-colibri.dtsi @@ -742,6 +742,10 @@ }; }; +&emc_icc_dvfs_opp_table { + /delete-node/ opp@760000000; +}; + &gpio { lan-reset-n { gpio-hog; diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts index ada2bed8b1b5..7e49112cd9a1 100644 --- a/arch/arm/boot/dts/tegra20-paz00.dts +++ b/arch/arm/boot/dts/tegra20-paz00.dts @@ -662,3 +662,7 @@ }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@760000000; +}; diff --git a/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi new file mode 100644 index 000000000000..b84afecea154 --- /dev/null +++ b/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0 + +/ { + emc_icc_dvfs_opp_table: emc-dvfs-opp-table { + compatible = "operating-points-v2"; + + opp@36000000 { + opp-microvolt = <950000 950000 1300000>; + opp-hz = /bits/ 64 <36000000>; + opp-supported-hw = <0x000F>; + }; + + opp@47500000 { + opp-microvolt = <950000 950000 1300000>; + opp-hz = /bits/ 64 <47500000>; + opp-supported-hw = <0x000F>; + }; + + opp@50000000 { + opp-microvolt = <950000 950000 1300000>; + opp-hz = /bits/ 64 <50000000>; + opp-supported-hw = <0x000F>; + }; + + opp@54000000 { + opp-microvolt = <950000 950000 1300000>; + opp-hz = /bits/ 64 <54000000>; + opp-supported-hw = <0x000F>; + }; + + opp@57000000 { + opp-microvolt = <950000 950000 1300000>; + opp-hz = /bits/ 64 <57000000>; + opp-supported-hw = <0x000F>; + }; + + opp@100000000 { + opp-microvolt = <1000000 1000000 1300000>; + opp-hz = /bits/ 64 <100000000>; + opp-supported-hw = <0x000F>; + }; + + opp@108000000 { + opp-microvolt = <1000000 1000000 1300000>; + opp-hz = /bits/ 64 <108000000>; + opp-supported-hw = <0x000F>; + }; + + opp@126666000 { + opp-microvolt = <1000000 1000000 1300000>; + opp-hz = /bits/ 64 <126666000>; + opp-supported-hw = <0x000F>; + }; + + opp@150000000 { + opp-microvolt = <1000000 1000000 1300000>; + opp-hz = /bits/ 64 <150000000>; + opp-supported-hw = <0x000F>; + }; + + opp@190000000 { + opp-microvolt = <1000000 1000000 1300000>; + opp-hz = /bits/ 64 <190000000>; + opp-supported-hw = <0x000F>; + }; + + opp@216000000 { + opp-microvolt = <1000000 1000000 1300000>; + opp-hz = /bits/ 64 <216000000>; + opp-supported-hw = <0x000F>; + }; + + opp@300000000 { + opp-microvolt = <1000000 1000000 1300000>; + opp-hz = /bits/ 64 <300000000>; + opp-supported-hw = <0x000F>; + }; + + opp@333000000 { + opp-microvolt = <1000000 1000000 1300000>; + opp-hz = /bits/ 64 <333000000>; + opp-supported-hw = <0x000F>; + }; + + opp@380000000 { + opp-microvolt = <1100000 1100000 1300000>; + opp-hz = /bits/ 64 <380000000>; + opp-supported-hw = <0x000F>; + }; + + opp@600000000 { + opp-microvolt = <1200000 1200000 1300000>; + opp-hz = /bits/ 64 <600000000>; + opp-supported-hw = <0x000F>; + }; + + opp@666000000 { + opp-microvolt = <1200000 1200000 1300000>; + opp-hz = /bits/ 64 <666000000>; + opp-supported-hw = <0x000F>; + }; + + opp@760000000 { + opp-microvolt = <1300000 1300000 1300000>; + opp-hz = /bits/ 64 <760000000>; + opp-supported-hw = <0x000F>; + }; + }; +}; diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts index b158771ac0b7..055334ae3d28 100644 --- a/arch/arm/boot/dts/tegra20-ventana.dts +++ b/arch/arm/boot/dts/tegra20-ventana.dts @@ -3,6 +3,7 @@ #include <dt-bindings/input/input.h> #include "tegra20.dtsi" +#include "tegra20-cpu-opp.dtsi" / { model = "NVIDIA Tegra20 Ventana evaluation board"; @@ -592,6 +593,16 @@ #clock-cells = <0>; }; + cpus { + cpu0: cpu@0 { + operating-points-v2 = <&cpu0_opp_table>; + }; + + cpu@1 { + operating-points-v2 = <&cpu0_opp_table>; + }; + }; + gpio-keys { compatible = "gpio-keys"; diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 72a4211a618f..6ce498178105 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -6,6 +6,8 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/soc/tegra-pmc.h> +#include "tegra20-peripherals-opp.dtsi" + / { compatible = "nvidia,tegra20"; interrupt-parent = <&lic>; @@ -111,6 +113,17 @@ nvidia,head = <0>; + interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>, + <&mc TEGRA20_MC_DISPLAY0B &emc>, + <&mc TEGRA20_MC_DISPLAY1B &emc>, + <&mc TEGRA20_MC_DISPLAY0C &emc>, + <&mc TEGRA20_MC_DISPLAYHC &emc>; + interconnect-names = "wina", + "winb", + "winb-vfilter", + "winc", + "cursor"; + rgb { status = "disabled"; }; @@ -128,6 +141,17 @@ nvidia,head = <1>; + interconnects = <&mc TEGRA20_MC_DISPLAY0AB &emc>, + <&mc TEGRA20_MC_DISPLAY0BB &emc>, + <&mc TEGRA20_MC_DISPLAY1BB &emc>, + <&mc TEGRA20_MC_DISPLAY0CB &emc>, + <&mc TEGRA20_MC_DISPLAYHCB &emc>; + interconnect-names = "wina", + "winb", + "winb-vfilter", + "winc", + "cursor"; + rgb { status = "disabled"; }; @@ -630,15 +654,20 @@ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; #reset-cells = <1>; #iommu-cells = <0>; + #interconnect-cells = <1>; }; - memory-controller@7000f400 { + emc: memory-controller@7000f400 { compatible = "nvidia,tegra20-emc"; - reg = <0x7000f400 0x200>; + reg = <0x7000f400 0x400>; interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA20_CLK_EMC>; #address-cells = <1>; #size-cells = <0>; + #interconnect-cells = <0>; + + operating-points-v2 = <&emc_icc_dvfs_opp_table>; + nvidia,memory-controller = <&mc>; }; fuse@7000f800 { diff --git a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi index 88ca03f57b3b..ac1c1a63eb0e 100644 --- a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi +++ b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi @@ -75,7 +75,7 @@ }; gpio@6000d000 { - init-mode { + init-mode-hog { gpio-hog; gpios = <TEGRA_GPIO(DD, 7) GPIO_ACTIVE_HIGH>, <TEGRA_GPIO(CC, 6) GPIO_ACTIVE_HIGH>, @@ -83,7 +83,7 @@ output-low; }; - init-low-power-mode { + init-low-power-mode-hog { gpio-hog; gpios = <TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>; input; @@ -1073,8 +1073,16 @@ }; display-panel { - compatible = "hydis,hv070wx2-1e0", "chunghwa,claa070wp03xg", - "panel-lvds"; + /* + * Nexus 7 supports two compatible panel models: + * + * 1. hydis,hv070wx2-1e0 + * 2. chunghwa,claa070wp03xg + * + * We want to use timing which is optimized for Nexus 7, + * hence we need to customize the timing. + */ + compatible = "panel-lvds"; power-supply = <&vdd_pnl>; backlight = <&backlight>; @@ -1145,6 +1153,7 @@ compatible = "ti,sn75lvds83", "lvds-encoder"; powerdown-gpios = <&gpio TEGRA_GPIO(N, 6) GPIO_ACTIVE_LOW>; + power-supply = <&vdd_3v3_sys>; ports { #address-cells = <1>; @@ -1240,14 +1249,14 @@ }; thermal-zones { - nct72-local { + skin-thermal { polling-delay-passive = <1000>; /* milliseconds */ polling-delay = <0>; /* milliseconds */ thermal-sensors = <&nct72 0>; }; - nct72-remote { + cpu-thermal { polling-delay-passive = <1000>; /* milliseconds */ polling-delay = <5000>; /* milliseconds */ @@ -1255,9 +1264,9 @@ trips { trip0: cpu-alert0 { - /* start throttling at 50C */ - temperature = <50000>; - hysteresis = <3000>; + /* throttle at 57C until temperature drops to 56.8C */ + temperature = <57000>; + hysteresis = <200>; type = "passive"; }; diff --git a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-maxim-pmic.dtsi b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-maxim-pmic.dtsi index b25b3fa90ac6..17b6682ffce8 100644 --- a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-maxim-pmic.dtsi +++ b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-maxim-pmic.dtsi @@ -29,7 +29,7 @@ }; }; - cpu-pwr-req { + cpu-pwr-req-hog { gpio-hog; gpios = <6 GPIO_ACTIVE_HIGH>; input; diff --git a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-memory-timings.dtsi b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-memory-timings.dtsi index bc0f6f29b956..bcff0997ee51 100644 --- a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-memory-timings.dtsi +++ b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-memory-timings.dtsi @@ -1563,3 +1563,15 @@ }; }; }; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@750000000,1300; + /delete-node/ opp@800000000,1300; + /delete-node/ opp@900000000,1350; +}; + +&emc_bw_dfs_opp_table { + /delete-node/ opp@750000000; + /delete-node/ opp@800000000; + /delete-node/ opp@900000000; +}; diff --git a/arch/arm/boot/dts/tegra30-asus-nexus7-tilapia.dtsi b/arch/arm/boot/dts/tegra30-asus-nexus7-tilapia.dtsi index e3da89f1941a..a681ad51fddd 100644 --- a/arch/arm/boot/dts/tegra30-asus-nexus7-tilapia.dtsi +++ b/arch/arm/boot/dts/tegra30-asus-nexus7-tilapia.dtsi @@ -23,7 +23,7 @@ }; gpio@6000d000 { - init-mode-3g { + init-mode-3g-hog { gpio-hog; gpios = <TEGRA_GPIO(D, 2) GPIO_ACTIVE_HIGH>, <TEGRA_GPIO(C, 6) GPIO_ACTIVE_HIGH>, diff --git a/arch/arm/boot/dts/tegra30-ouya.dts b/arch/arm/boot/dts/tegra30-ouya.dts new file mode 100644 index 000000000000..74da1360d297 --- /dev/null +++ b/arch/arm/boot/dts/tegra30-ouya.dts @@ -0,0 +1,4519 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include <dt-bindings/input/gpio-keys.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/thermal/thermal.h> + +#include "tegra30.dtsi" +#include "tegra30-cpu-opp.dtsi" +#include "tegra30-cpu-opp-microvolt.dtsi" + +/ { + model = "Ouya Game Console"; + compatible = "ouya,ouya", "nvidia,tegra30"; + + aliases { + mmc0 = &sdmmc4; /* eMMC */ + mmc1 = &sdmmc3; /* WiFi */ + rtc0 = &pmic; + rtc1 = "/rtc@7000e000"; + serial0 = &uartd; /* Debug Port */ + serial1 = &uartc; /* Bluetooth */ + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@80000000 { + reg = <0x80000000 0x40000000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + linux,cma@80000000 { + compatible = "shared-dma-pool"; + alloc-ranges = <0x80000000 0x30000000>; + size = <0x10000000>; /* 256MiB */ + linux,cma-default; + reusable; + }; + + ramoops@bfdf0000 { + compatible = "ramoops"; + reg = <0xbfdf0000 0x10000>; /* 64kB */ + console-size = <0x8000>; /* 32kB */ + record-size = <0x400>; /* 1kB */ + ecc-size = <16>; + }; + + trustzone@bfe00000 { + reg = <0xbfe00000 0x200000>; + no-map; + }; + }; + + host1x@50000000 { + hdmi@54280000 { + status = "okay"; + vdd-supply = <&vdd_vid_reg>; + pll-supply = <&ldo7_reg>; + hdmi-supply = <&sys_3v3_reg>; + nvidia,ddc-i2c-bus = <&hdmi_ddc>; + nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>; + }; + }; + + gpio: gpio@6000d000 { + gpio-ranges = <&pinmux 0 0 248>; + #reset-cells = <1>; + }; + + pinmux@70000868 { + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + state_default: pinmux { + /* located at $state_default below */ + }; + }; + + uartc: serial@70006200 { + status = "okay"; + compatible = "nvidia,tegra30-hsuart"; + + nvidia,adjust-baud-rates = <0 9600 100>, + <9600 115200 200>, + <1000000 4000000 136>; + + /* Azurewave AW-NH660 BCM4330B1 */ + bluetooth { + compatible = "brcm,bcm4330-bt"; + + max-speed = <4000000>; + + clocks = <&tegra_pmc TEGRA_PMC_CLK_BLINK>; + clock-names = "txco"; + + vbat-supply = <&sys_3v3_reg>; + vddio-supply = <&vdd_1v8>; + + shutdown-gpios = <&gpio TEGRA_GPIO(U, 0) GPIO_ACTIVE_HIGH>; + device-wakeup-gpios = <&gpio TEGRA_GPIO(U, 1) GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpio TEGRA_GPIO(U, 6) GPIO_ACTIVE_HIGH>; + }; + }; + + uartd: serial@70006300 { + status = "okay"; + }; + + hdmi_ddc: i2c@7000c700 { + status = "okay"; + clock-frequency = <100000>; + }; + + i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + cpu_temp: nct1008@4c { + compatible = "onnn,nct1008"; + reg = <0x4c>; + vcc-supply = <&sys_3v3_reg>; + #thermal-sensor-cells = <1>; +/* + * The interrupt is bugged, once triggered it never clears. + * interrupt-parent = <&gpio>; + * interrupts = <TEGRA_GPIO(CC, 2) IRQ_TYPE_LEVEL_LOW>; + */ + }; + + pmic: pmic@2d { + compatible = "ti,tps65911"; + reg = <0x2d>; + + interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; + #interrupt-cells = <2>; + interrupt-controller; + + ti,en-gpio-sleep = <0 1 1 1 1 1 0 0 1>; + ti,system-power-controller; + ti,sleep-keep-ck32k; + ti,sleep-enable; + + #gpio-cells = <2>; + gpio-controller; + + vcc1-supply = <&vdd_5v0_reg>; + vcc2-supply = <&vdd_5v0_reg>; + vcc3-supply = <&vdd_1v8>; + vcc4-supply = <&vdd_5v0_reg>; + vcc5-supply = <&vdd_5v0_reg>; + vcc6-supply = <&vdd2_reg>; + vcc7-supply = <&vdd_5v0_reg>; + vccio-supply = <&vdd_5v0_reg>; + + regulators { + vdd1_reg: vdd1 { + regulator-name = "vddio_ddr_1v2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + vdd2_reg: vdd2 { + regulator-name = "vdd_1v5_gen"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + }; + + vdd_cpu: vddctrl { + regulator-name = "vdd_cpu,vdd_sys"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1270000>; + regulator-coupled-with = <&vdd_core>; + regulator-coupled-max-spread = <300000>; + regulator-max-step-microvolt = <100000>; + regulator-always-on; + + nvidia,tegra-cpu-regulator; + }; + + vdd_1v8: vio { + regulator-name = "vdd_1v8_gen"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ldo1_reg: ldo1 { + regulator-name = "vdd_pexa,vdd_pexb"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + regulator-always-on; + }; + + ldo2_reg: ldo2 { + regulator-name = "vdd_sata,avdd_plle"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + regulator-always-on; + }; + + /* LDO3 is not connected to anything */ + + ldo4_reg: ldo4 { + regulator-name = "vdd_rtc"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + ldo5_reg: ldo5 { + regulator-name = "vddio_sdmmc,avdd_vdac"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + ldo6_reg: ldo6 { + regulator-name = "avdd_dsi_csi,pwrdet_mipi"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + ldo7_reg: ldo7 { + regulator-name = "vdd_pllm,x,u,a_p_c_s"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + ldo8_reg: ldo8 { + regulator-name = "vdd_ddr_hs"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + }; + }; + }; + + vdd_core: tps62361@60 { + compatible = "ti,tps62361"; + reg = <0x60>; + + regulator-name = "vdd_core"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-coupled-with = <&vdd_cpu>; + regulator-coupled-max-spread = <300000>; + regulator-max-step-microvolt = <100000>; + regulator-boot-on; + regulator-always-on; + ti,vsel0-state-high; + ti,vsel1-state-high; + ti,enable-vout-discharge; + + nvidia,tegra-core-regulator; + }; + }; + + pmc@7000e400 { + status = "okay"; + nvidia,invert-interrupt; + nvidia,suspend-mode = <1>; + nvidia,cpu-pwr-good-time = <2000>; + nvidia,cpu-pwr-off-time = <200>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <458>; + nvidia,core-power-req-active-high; + nvidia,sys-clock-req-active-high; + }; + + mc_timings: memory-controller@7000f000 { + /* timings located at &mc_timings below */ + }; + + emc_timings: memory-controller@7000f400 { + /* timings located at &emc_timings below */ + }; + + hda@70030000 { + status = "okay"; + }; + + wifi_pwrseq: wifi_pwrseq { + compatible = "mmc-pwrseq-simple"; + + clocks = <&tegra_pmc TEGRA_PMC_CLK_BLINK>; + clock-names = "ext_clock"; + + reset-gpios = <&gpio TEGRA_GPIO(D, 3) GPIO_ACTIVE_LOW>; + post-power-on-delay-ms = <300>; + power-off-delay-us = <300>; + }; + + sdmmc3: mmc@78000400 { + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + assigned-clocks = <&tegra_car TEGRA30_CLK_SDMMC3>; + assigned-clock-parents = <&tegra_car TEGRA30_CLK_PLL_C>; + assigned-clock-rates = <50000000>; + + max-frequency = <50000000>; + keep-power-in-suspend; + + bus-width = <4>; + non-removable; + + mmc-pwrseq = <&wifi_pwrseq>; + vmmc-supply = <&sdmmc_3v3_reg>; + vqmmc-supply = <&vdd_1v8>; + + /* Azurewave AW-NH660 BCM4330 */ + brcmf: wifi@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + interrupt-parent = <&gpio>; + interrupts = <TEGRA_GPIO(O, 4) IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "host-wake"; + }; + }; + + sdmmc4: mmc@78000600 { + status = "okay"; + + keep-power-in-suspend; + bus-width = <8>; + non-removable; + vmmc-supply = <&sys_3v3_reg>; + vqmmc-supply = <&vdd_1v8>; + nvidia,default-tap = <0x0F>; + max-frequency = <25500000>; + }; + + usb@7d000000 { + compatible = "nvidia,tegra30-udc"; + status = "okay"; + }; + + usb-phy@7d000000 { + status = "okay"; + dr_mode = "peripheral"; + }; + + usb@7d004000 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + smsc@2 { /* SMSC 10/100T Ethernet Controller */ + compatible = "usb424,9e00"; + reg = <2>; + local-mac-address = [00 11 22 33 44 55]; + }; + }; + + usb-phy@7d004000 { + vbus-supply = <&vdd_smsc>; + status = "okay"; + }; + + usb@7d008000 { + status = "okay"; + }; + + usb-phy@7d008000 { + vbus-supply = <&usb3_vbus_reg>; + status = "okay"; + }; + + /* PMIC has a built-in 32KHz oscillator which is used by PMC */ + clk32k_in: clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "pmic-oscillator"; + }; + + cpus { + cpu0: cpu@0 { + operating-points-v2 = <&cpu0_opp_table>; + cpu-supply = <&vdd_cpu>; + #cooling-cells = <2>; + }; + cpu@1 { + operating-points-v2 = <&cpu0_opp_table>; + cpu-supply = <&vdd_cpu>; + }; + + cpu@2 { + operating-points-v2 = <&cpu0_opp_table>; + cpu-supply = <&vdd_cpu>; + }; + + cpu@3 { + operating-points-v2 = <&cpu0_opp_table>; + cpu-supply = <&vdd_cpu>; + }; + }; + + firmware { + trusted-foundations { + compatible = "tlm,trusted-foundations"; + tlm,version-major = <0x0>; + tlm,version-minor = <0x0>; + }; + }; + + fan: gpio_fan { + compatible = "gpio-fan"; + gpios = <&gpio TEGRA_GPIO(J, 2) GPIO_ACTIVE_HIGH>; + gpio-fan,speed-map = <0 0 + 4500 1>; + #cooling-cells = <2>; + }; + + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay = <5000>; + polling-delay-passive = <5000>; + + thermal-sensors = <&cpu_temp 1>; + + trips { + cpu_alert0: cpu-alert0 { + temperature = <50000>; + hysteresis = <10000>; + type = "active"; + }; + cpu_alert1: cpu-alert1 { + temperature = <70000>; + hysteresis = <5000>; + type = "passive"; + }; + cpu_crit: cpu-crit { + temperature = <90000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu_alert1>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; + + vdd_12v_in: vdd_12v_in { + compatible = "regulator-fixed"; + regulator-name = "vdd_12v_in"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-always-on; + }; + + sdmmc_3v3_reg: sdmmc_3v3_reg { + compatible = "regulator-fixed"; + regulator-name = "sdmmc_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + regulator-always-on; + gpio = <&gpio TEGRA_GPIO(D, 4) GPIO_ACTIVE_HIGH>; + vin-supply = <&sys_3v3_reg>; + }; + + vdd_fuse_3v3_reg: vdd_fuse_3v3_reg { + compatible = "regulator-fixed"; + regulator-name = "vdd_fuse_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + gpio = <&gpio TEGRA_GPIO(L, 6) GPIO_ACTIVE_HIGH>; + vin-supply = <&sys_3v3_reg>; + regulator-always-on; + }; + + vdd_vid_reg: vdd_vid_reg { + compatible = "regulator-fixed"; + regulator-name = "vddio_vid"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio TEGRA_GPIO(T, 0) GPIO_ACTIVE_HIGH>; + vin-supply = <&vdd_5v0_reg>; + regulator-boot-on; + }; + + ddr_reg: ddr_reg { + compatible = "regulator-fixed"; + regulator-name = "vdd_ddr"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + enable-active-high; + gpio = <&pmic 7 GPIO_ACTIVE_HIGH>; + regulator-boot-on; + vin-supply = <&vdd_12v_in>; + }; + + sys_3v3_reg: sys_3v3_reg { + compatible = "regulator-fixed"; + regulator-name = "sys_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + gpio = <&pmic 6 GPIO_ACTIVE_HIGH>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vdd_12v_in>; + }; + + vdd_5v0_reg: vdd_5v0_reg { + compatible = "regulator-fixed"; + regulator-name = "vdd_5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&pmic 0 GPIO_ACTIVE_HIGH>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vdd_12v_in>; + }; + + vdd_smsc: vdd_smsc { + compatible = "regulator-fixed"; + regulator-name = "vdd_smsc"; + enable-active-high; + gpio = <&gpio TEGRA_GPIO(DD, 5) GPIO_ACTIVE_HIGH>; + }; + + usb3_vbus_reg: usb3_vbus_reg { + compatible = "regulator-fixed"; + regulator-name = "usb3_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio TEGRA_GPIO(DD, 4) GPIO_ACTIVE_HIGH>; + vin-supply = <&vdd_5v0_reg>; + }; + + gpio-keys { + compatible = "gpio-keys"; + + power { + gpios = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>; + debounce-interval = <10>; + linux,code = <KEY_POWER>; + wakeup-event-action = <EV_ACT_ASSERTED>; + wakeup-source; + }; + }; + + + leds { + compatible = "gpio-leds"; + + led-power { + label = "power-led"; + gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + retain-state-suspended; + }; + }; +}; +&mc_timings { + emc-timings-0 { + nvidia,ram-code = <0>; /* Samsung RAM */ + timing-25500000 { + clock-frequency = <25500000>; + nvidia,emem-configuration = < + 0x00030003 /* MC_EMEM_ARB_CFG */ + 0xc0000010 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000000 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000001 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000001 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06020102 /* MC_EMEM_ARB_DA_TURNS */ + 0x000a0502 /* MC_EMEM_ARB_DA_COVERS */ + 0x75830303 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-51000000 { + clock-frequency = <51000000>; + nvidia,emem-configuration = < + 0x00010003 /* MC_EMEM_ARB_CFG */ + 0xc0000010 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000000 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000001 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000001 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06020102 /* MC_EMEM_ARB_DA_TURNS */ + 0x000a0502 /* MC_EMEM_ARB_DA_COVERS */ + 0x74630303 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-102000000 { + clock-frequency = <102000000>; + nvidia,emem-configuration = < + 0x00000003 /* MC_EMEM_ARB_CFG */ + 0xc0000018 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000000 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000002 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000001 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06020102 /* MC_EMEM_ARB_DA_TURNS */ + 0x000a0503 /* MC_EMEM_ARB_DA_COVERS */ + 0x73c30504 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-204000000 { + clock-frequency = <204000000>; + nvidia,emem-configuration = < + 0x00000006 /* MC_EMEM_ARB_CFG */ + 0xc0000025 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000005 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000004 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000001 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06020102 /* MC_EMEM_ARB_DA_TURNS */ + 0x000a0505 /* MC_EMEM_ARB_DA_COVERS */ + 0x73840a06 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-400000000 { + clock-frequency = <400000000>; + nvidia,emem-configuration = < + 0x0000000c /* MC_EMEM_ARB_CFG */ + 0xc0000048 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000009 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000005 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000007 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000002 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000003 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06030202 /* MC_EMEM_ARB_DA_TURNS */ + 0x000d0709 /* MC_EMEM_ARB_DA_COVERS */ + 0x7086120a /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-800000000 { + clock-frequency = <800000000>; + nvidia,emem-configuration = < + 0x00000018 /* MC_EMEM_ARB_CFG */ + 0xc0000090 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000004 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000005 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000013 /* MC_EMEM_ARB_TIMING_RC */ + 0x0000000c /* MC_EMEM_ARB_TIMING_RAS */ + 0x0000000f /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x0000000c /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000002 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000004 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000008 /* MC_EMEM_ARB_TIMING_W2R */ + 0x08040202 /* MC_EMEM_ARB_DA_TURNS */ + 0x00160d13 /* MC_EMEM_ARB_DA_COVERS */ + 0x712c2414 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + }; + emc-timings-1 { + nvidia,ram-code = <1>; /* Hynix M RAM */ + timing-25500000 { + clock-frequency = <25500000>; + nvidia,emem-configuration = < + 0x00030003 /* MC_EMEM_ARB_CFG */ + 0xc0000010 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000000 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000001 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000001 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06020102 /* MC_EMEM_ARB_DA_TURNS */ + 0x000a0502 /* MC_EMEM_ARB_DA_COVERS */ + 0x75830303 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-51000000 { + clock-frequency = <51000000>; + nvidia,emem-configuration = < + 0x00010003 /* MC_EMEM_ARB_CFG */ + 0xc0000010 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000000 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000001 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000001 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06020102 /* MC_EMEM_ARB_DA_TURNS */ + 0x000a0502 /* MC_EMEM_ARB_DA_COVERS */ + 0x74630303 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-102000000 { + clock-frequency = <102000000>; + nvidia,emem-configuration = < + 0x00000003 /* MC_EMEM_ARB_CFG */ + 0xc0000018 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000000 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000002 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000001 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06020102 /* MC_EMEM_ARB_DA_TURNS */ + 0x000a0503 /* MC_EMEM_ARB_DA_COVERS */ + 0x73c30504 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-204000000 { + clock-frequency = <204000000>; + nvidia,emem-configuration = < + 0x00000006 /* MC_EMEM_ARB_CFG */ + 0xc0000025 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000005 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000004 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000001 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06020102 /* MC_EMEM_ARB_DA_TURNS */ + 0x000a0505 /* MC_EMEM_ARB_DA_COVERS */ + 0x73840a06 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-400000000 { + clock-frequency = <400000000>; + nvidia,emem-configuration = < + 0x0000000c /* MC_EMEM_ARB_CFG */ + 0xc0000048 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000009 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000005 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000007 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000002 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000003 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06030202 /* MC_EMEM_ARB_DA_TURNS */ + 0x000d0709 /* MC_EMEM_ARB_DA_COVERS */ + 0x7086120a /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-800000000 { + clock-frequency = <800000000>; + nvidia,emem-configuration = < + 0x00000018 /* MC_EMEM_ARB_CFG */ + 0xc0000090 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000004 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000005 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000013 /* MC_EMEM_ARB_TIMING_RC */ + 0x0000000c /* MC_EMEM_ARB_TIMING_RAS */ + 0x0000000f /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x0000000c /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000002 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000004 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000008 /* MC_EMEM_ARB_TIMING_W2R */ + 0x08040202 /* MC_EMEM_ARB_DA_TURNS */ + 0x00160d13 /* MC_EMEM_ARB_DA_COVERS */ + 0x712c2414 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + }; + emc-timings-2 { + nvidia,ram-code = <2>; /* Hynix A RAM */ + timing-25500000 { + clock-frequency = <25500000>; + nvidia,emem-configuration = < + 0x00030003 /* MC_EMEM_ARB_CFG */ + 0xc0000010 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000000 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000001 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000001 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06020102 /* MC_EMEM_ARB_DA_TURNS */ + 0x000a0502 /* MC_EMEM_ARB_DA_COVERS */ + 0x75e30303 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-51000000 { + clock-frequency = <51000000>; + nvidia,emem-configuration = < + 0x00010003 /* MC_EMEM_ARB_CFG */ + 0xc0000010 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000000 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000001 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000001 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06020102 /* MC_EMEM_ARB_DA_TURNS */ + 0x000a0502 /* MC_EMEM_ARB_DA_COVERS */ + 0x74e30303 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-102000000 { + clock-frequency = <102000000>; + nvidia,emem-configuration = < + 0x00000003 /* MC_EMEM_ARB_CFG */ + 0xc0000018 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000000 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000002 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000001 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06020102 /* MC_EMEM_ARB_DA_TURNS */ + 0x000a0503 /* MC_EMEM_ARB_DA_COVERS */ + 0x74430504 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-204000000 { + clock-frequency = <204000000>; + nvidia,emem-configuration = < + 0x00000006 /* MC_EMEM_ARB_CFG */ + 0xc0000025 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000005 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000004 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000001 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06020102 /* MC_EMEM_ARB_DA_TURNS */ + 0x000a0505 /* MC_EMEM_ARB_DA_COVERS */ + 0x74040a06 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-400000000 { + clock-frequency = <400000000>; + nvidia,emem-configuration = < + 0x0000000c /* MC_EMEM_ARB_CFG */ + 0xc0000048 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000009 /* MC_EMEM_ARB_TIMING_RC */ + 0x00000005 /* MC_EMEM_ARB_TIMING_RAS */ + 0x00000007 /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000001 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x00000008 /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000002 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000003 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000006 /* MC_EMEM_ARB_TIMING_W2R */ + 0x06030202 /* MC_EMEM_ARB_DA_TURNS */ + 0x000d0709 /* MC_EMEM_ARB_DA_COVERS */ + 0x7086120a /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + timing-800000000 { + clock-frequency = <800000000>; + nvidia,emem-configuration = < + 0x00000018 /* MC_EMEM_ARB_CFG */ + 0xc0000090 /* MC_EMEM_ARB_OUTSTANDING_REQ */ + 0x00000004 /* MC_EMEM_ARB_TIMING_RCD */ + 0x00000005 /* MC_EMEM_ARB_TIMING_RP */ + 0x00000013 /* MC_EMEM_ARB_TIMING_RC */ + 0x0000000c /* MC_EMEM_ARB_TIMING_RAS */ + 0x0000000f /* MC_EMEM_ARB_TIMING_FAW */ + 0x00000002 /* MC_EMEM_ARB_TIMING_RRD */ + 0x00000003 /* MC_EMEM_ARB_TIMING_RAP2PRE */ + 0x0000000c /* MC_EMEM_ARB_TIMING_WAP2PRE */ + 0x00000002 /* MC_EMEM_ARB_TIMING_R2R */ + 0x00000002 /* MC_EMEM_ARB_TIMING_W2W */ + 0x00000004 /* MC_EMEM_ARB_TIMING_R2W */ + 0x00000008 /* MC_EMEM_ARB_TIMING_W2R */ + 0x08040202 /* MC_EMEM_ARB_DA_TURNS */ + 0x00160d13 /* MC_EMEM_ARB_DA_COVERS */ + 0x712c2414 /* MC_EMEM_ARB_MISC0 */ + 0x001f0000 /* MC_EMEM_ARB_RING1_THROTTLE */ + >; + }; + }; +}; +&emc_timings { + emc-timings-0 { + nvidia,ram-code = <0>; /* Samsung RAM */ + timing-25500000 { + clock-frequency = <25500000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-cfg-dyn-self-ref; + nvidia,emc-configuration = < + 0x00000001 /* EMC_RC */ + 0x00000006 /* EMC_RFC */ + 0x00000000 /* EMC_RAS */ + 0x00000000 /* EMC_RP */ + 0x00000002 /* EMC_R2W */ + 0x0000000a /* EMC_W2R */ + 0x00000005 /* EMC_R2P */ + 0x0000000b /* EMC_W2P */ + 0x00000000 /* EMC_RD_RCD */ + 0x00000000 /* EMC_WR_RCD */ + 0x00000003 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000005 /* EMC_WDV */ + 0x00000005 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000b /* EMC_RDV */ + 0x000000c0 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x00000030 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000002 /* EMC_PDEX2WR */ + 0x00000002 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000007 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x00000007 /* EMC_TXSR */ + 0x00000007 /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000002 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x000000c7 /* EMC_TREFBW */ + 0x00000006 /* EMC_QUSE_EXTRA */ + 0x00000004 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00004288 /* EMC_FBIO_CFG5 */ + 0x007800a4 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x000fc000 /* EMC_DLL_XFORM_DQS0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS3 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS4 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS5 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS6 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800211c /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f108 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x08000168 /* EMC_XM2QUSEPADCTRL */ + 0x08000000 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00000000 /* EMC_ZCAL_INTERVAL */ + 0x00000040 /* EMC_ZCAL_WAIT_CNT */ + 0x000c000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x80000287 /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff00 /* EMC_CFG_RSV */ + >; + }; + timing-51000000 { + clock-frequency = <51000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-cfg-dyn-self-ref; + nvidia,emc-configuration = < + 0x00000002 /* EMC_RC */ + 0x0000000d /* EMC_RFC */ + 0x00000001 /* EMC_RAS */ + 0x00000000 /* EMC_RP */ + 0x00000002 /* EMC_R2W */ + 0x0000000a /* EMC_W2R */ + 0x00000005 /* EMC_R2P */ + 0x0000000b /* EMC_W2P */ + 0x00000000 /* EMC_RD_RCD */ + 0x00000000 /* EMC_WR_RCD */ + 0x00000003 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000005 /* EMC_WDV */ + 0x00000005 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000b /* EMC_RDV */ + 0x00000181 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x00000060 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000002 /* EMC_PDEX2WR */ + 0x00000002 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000007 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x0000000e /* EMC_TXSR */ + 0x0000000e /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000003 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x0000018e /* EMC_TREFBW */ + 0x00000006 /* EMC_QUSE_EXTRA */ + 0x00000004 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00004288 /* EMC_FBIO_CFG5 */ + 0x007800a4 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x000fc000 /* EMC_DLL_XFORM_DQS0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS3 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS4 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS5 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS6 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800211c /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f108 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x08000168 /* EMC_XM2QUSEPADCTRL */ + 0x08000000 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00000000 /* EMC_ZCAL_INTERVAL */ + 0x00000040 /* EMC_ZCAL_WAIT_CNT */ + 0x000c000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x8000040b /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff00 /* EMC_CFG_RSV */ + >; + }; + timing-102000000 { + clock-frequency = <102000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-cfg-dyn-self-ref; + nvidia,emc-configuration = < + 0x00000004 /* EMC_RC */ + 0x0000001a /* EMC_RFC */ + 0x00000003 /* EMC_RAS */ + 0x00000001 /* EMC_RP */ + 0x00000002 /* EMC_R2W */ + 0x0000000a /* EMC_W2R */ + 0x00000005 /* EMC_R2P */ + 0x0000000b /* EMC_W2P */ + 0x00000001 /* EMC_RD_RCD */ + 0x00000001 /* EMC_WR_RCD */ + 0x00000003 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000005 /* EMC_WDV */ + 0x00000005 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000b /* EMC_RDV */ + 0x00000303 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x000000c0 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000002 /* EMC_PDEX2WR */ + 0x00000002 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000007 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x0000001c /* EMC_TXSR */ + 0x0000001c /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000005 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x0000031c /* EMC_TREFBW */ + 0x00000006 /* EMC_QUSE_EXTRA */ + 0x00000004 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00004288 /* EMC_FBIO_CFG5 */ + 0x007800a4 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x000fc000 /* EMC_DLL_XFORM_DQS0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS3 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS4 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS5 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS6 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800211c /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f108 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x08000168 /* EMC_XM2QUSEPADCTRL */ + 0x08000000 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00000000 /* EMC_ZCAL_INTERVAL */ + 0x00000040 /* EMC_ZCAL_WAIT_CNT */ + 0x000c000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x80000713 /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff00 /* EMC_CFG_RSV */ + >; + }; + timing-204000000 { + clock-frequency = <204000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-cfg-dyn-self-ref; + nvidia,emc-configuration = < + 0x00000009 /* EMC_RC */ + 0x00000035 /* EMC_RFC */ + 0x00000007 /* EMC_RAS */ + 0x00000002 /* EMC_RP */ + 0x00000002 /* EMC_R2W */ + 0x0000000a /* EMC_W2R */ + 0x00000005 /* EMC_R2P */ + 0x0000000b /* EMC_W2P */ + 0x00000002 /* EMC_RD_RCD */ + 0x00000002 /* EMC_WR_RCD */ + 0x00000003 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000005 /* EMC_WDV */ + 0x00000005 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000b /* EMC_RDV */ + 0x00000607 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x00000181 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000002 /* EMC_PDEX2WR */ + 0x00000002 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000007 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x00000038 /* EMC_TXSR */ + 0x00000038 /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000009 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x00000638 /* EMC_TREFBW */ + 0x00000006 /* EMC_QUSE_EXTRA */ + 0x00000006 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00004288 /* EMC_FBIO_CFG5 */ + 0x004400a4 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x00080000 /* EMC_DLL_XFORM_DQS0 */ + 0x00080000 /* EMC_DLL_XFORM_DQS1 */ + 0x00080000 /* EMC_DLL_XFORM_DQS2 */ + 0x00080000 /* EMC_DLL_XFORM_DQS3 */ + 0x00080000 /* EMC_DLL_XFORM_DQS4 */ + 0x00080000 /* EMC_DLL_XFORM_DQS5 */ + 0x00080000 /* EMC_DLL_XFORM_DQS6 */ + 0x00080000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x00080000 /* EMC_DLL_XFORM_DQ0 */ + 0x00080000 /* EMC_DLL_XFORM_DQ1 */ + 0x00080000 /* EMC_DLL_XFORM_DQ2 */ + 0x00080000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800211c /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f108 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x08000168 /* EMC_XM2QUSEPADCTRL */ + 0x08000000 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00020000 /* EMC_ZCAL_INTERVAL */ + 0x00000100 /* EMC_ZCAL_WAIT_CNT */ + 0x000c000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x80000d22 /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff00 /* EMC_CFG_RSV */ + >; + }; + timing-400000000 { + clock-frequency = <400000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100002>; + nvidia,emc-mode-2 = <0x80200000>; + nvidia,emc-mode-reset = <0x80000521>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-configuration = < + 0x00000012 /* EMC_RC */ + 0x00000066 /* EMC_RFC */ + 0x0000000c /* EMC_RAS */ + 0x00000004 /* EMC_RP */ + 0x00000003 /* EMC_R2W */ + 0x00000008 /* EMC_W2R */ + 0x00000002 /* EMC_R2P */ + 0x0000000a /* EMC_W2P */ + 0x00000004 /* EMC_RD_RCD */ + 0x00000004 /* EMC_WR_RCD */ + 0x00000002 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000004 /* EMC_WDV */ + 0x00000006 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000c /* EMC_RDV */ + 0x00000bf0 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x000002fc /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000001 /* EMC_PDEX2WR */ + 0x00000008 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000008 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x0000006c /* EMC_TXSR */ + 0x00000200 /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000010 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x00000c30 /* EMC_TREFBW */ + 0x00000000 /* EMC_QUSE_EXTRA */ + 0x00000004 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00007088 /* EMC_FBIO_CFG5 */ + 0x001d0084 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x0003c000 /* EMC_DLL_XFORM_DQS0 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS1 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS2 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS3 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS4 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS5 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS6 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x00048000 /* EMC_DLL_XFORM_DQ0 */ + 0x00048000 /* EMC_DLL_XFORM_DQ1 */ + 0x00048000 /* EMC_DLL_XFORM_DQ2 */ + 0x00048000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800013d /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f508 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x080001e8 /* EMC_XM2QUSEPADCTRL */ + 0x08000021 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00020000 /* EMC_ZCAL_INTERVAL */ + 0x00000100 /* EMC_ZCAL_WAIT_CNT */ + 0x0158000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x800018c8 /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff89 /* EMC_CFG_RSV */ + >; + }; + timing-800000000 { + clock-frequency = <800000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100002>; + nvidia,emc-mode-2 = <0x80200018>; + nvidia,emc-mode-reset = <0x80000d71>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-configuration = < + 0x00000025 /* EMC_RC */ + 0x000000ce /* EMC_RFC */ + 0x0000001a /* EMC_RAS */ + 0x00000009 /* EMC_RP */ + 0x00000005 /* EMC_R2W */ + 0x0000000d /* EMC_W2R */ + 0x00000004 /* EMC_R2P */ + 0x00000013 /* EMC_W2P */ + 0x00000009 /* EMC_RD_RCD */ + 0x00000009 /* EMC_WR_RCD */ + 0x00000004 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000007 /* EMC_WDV */ + 0x0000000a /* EMC_QUSE */ + 0x00000009 /* EMC_QRST */ + 0x0000000b /* EMC_QSAFE */ + 0x00000011 /* EMC_RDV */ + 0x00001820 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x00000608 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000003 /* EMC_PDEX2WR */ + 0x00000012 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x0000000f /* EMC_AR2PDEN */ + 0x00000018 /* EMC_RW2PDEN */ + 0x000000d8 /* EMC_TXSR */ + 0x00000200 /* EMC_TXSRDLL */ + 0x00000005 /* EMC_TCKE */ + 0x00000020 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000007 /* EMC_TCLKSTABLE */ + 0x00000008 /* EMC_TCLKSTOP */ + 0x00001860 /* EMC_TREFBW */ + 0x0000000b /* EMC_QUSE_EXTRA */ + 0x00000006 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00005088 /* EMC_FBIO_CFG5 */ + 0xf0070191 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x0000800a /* EMC_DLL_XFORM_DQS0 */ + 0x0000000a /* EMC_DLL_XFORM_DQS1 */ + 0x0000000a /* EMC_DLL_XFORM_DQS2 */ + 0x0000000a /* EMC_DLL_XFORM_DQS3 */ + 0x0000000a /* EMC_DLL_XFORM_DQS4 */ + 0x0000000a /* EMC_DLL_XFORM_DQS5 */ + 0x0000000a /* EMC_DLL_XFORM_DQS6 */ + 0x0000000a /* EMC_DLL_XFORM_DQS7 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x0000000a /* EMC_DLL_XFORM_DQ0 */ + 0x0000000a /* EMC_DLL_XFORM_DQ1 */ + 0x0000000a /* EMC_DLL_XFORM_DQ2 */ + 0x0000000a /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0600013d /* EMC_XM2DQSPADCTRL2 */ + 0x22220000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f501 /* EMC_XM2COMPPADCTRL */ + 0x07077404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000000 /* EMC_XM2VTTGENPADCTRL2 */ + 0x080001e8 /* EMC_XM2QUSEPADCTRL */ + 0x08000021 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00020000 /* EMC_ZCAL_INTERVAL */ + 0x00000100 /* EMC_ZCAL_WAIT_CNT */ + 0x00f0000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x8000308c /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff49 /* EMC_CFG_RSV */ + >; + }; + }; + emc-timings-1 { + nvidia,ram-code = <1>; /* Hynix M RAM */ + timing-25500000 { + clock-frequency = <25500000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-cfg-dyn-self-ref; + nvidia,emc-configuration = < + 0x00000001 /* EMC_RC */ + 0x00000006 /* EMC_RFC */ + 0x00000000 /* EMC_RAS */ + 0x00000000 /* EMC_RP */ + 0x00000002 /* EMC_R2W */ + 0x0000000a /* EMC_W2R */ + 0x00000005 /* EMC_R2P */ + 0x0000000b /* EMC_W2P */ + 0x00000000 /* EMC_RD_RCD */ + 0x00000000 /* EMC_WR_RCD */ + 0x00000003 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000005 /* EMC_WDV */ + 0x00000005 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000b /* EMC_RDV */ + 0x000000c0 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x00000030 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000002 /* EMC_PDEX2WR */ + 0x00000002 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000007 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x00000007 /* EMC_TXSR */ + 0x00000007 /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000002 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x000000c7 /* EMC_TREFBW */ + 0x00000006 /* EMC_QUSE_EXTRA */ + 0x00000004 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00004288 /* EMC_FBIO_CFG5 */ + 0x007800a4 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x000fc000 /* EMC_DLL_XFORM_DQS0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS3 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS4 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS5 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS6 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800211c /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f108 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x08000168 /* EMC_XM2QUSEPADCTRL */ + 0x08000000 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00000000 /* EMC_ZCAL_INTERVAL */ + 0x00000040 /* EMC_ZCAL_WAIT_CNT */ + 0x000c000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x80000287 /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff00 /* EMC_CFG_RSV */ + >; + }; + timing-51000000 { + clock-frequency = <51000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-cfg-dyn-self-ref; + nvidia,emc-configuration = < + 0x00000002 /* EMC_RC */ + 0x0000000d /* EMC_RFC */ + 0x00000001 /* EMC_RAS */ + 0x00000000 /* EMC_RP */ + 0x00000002 /* EMC_R2W */ + 0x0000000a /* EMC_W2R */ + 0x00000005 /* EMC_R2P */ + 0x0000000b /* EMC_W2P */ + 0x00000000 /* EMC_RD_RCD */ + 0x00000000 /* EMC_WR_RCD */ + 0x00000003 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000005 /* EMC_WDV */ + 0x00000005 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000b /* EMC_RDV */ + 0x00000181 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x00000060 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000002 /* EMC_PDEX2WR */ + 0x00000002 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000007 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x0000000e /* EMC_TXSR */ + 0x0000000e /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000003 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x0000018e /* EMC_TREFBW */ + 0x00000006 /* EMC_QUSE_EXTRA */ + 0x00000004 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00004288 /* EMC_FBIO_CFG5 */ + 0x007800a4 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x000fc000 /* EMC_DLL_XFORM_DQS0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS3 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS4 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS5 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS6 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800211c /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f108 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x08000168 /* EMC_XM2QUSEPADCTRL */ + 0x08000000 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00000000 /* EMC_ZCAL_INTERVAL */ + 0x00000040 /* EMC_ZCAL_WAIT_CNT */ + 0x000c000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x8000040b /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff00 /* EMC_CFG_RSV */ + >; + }; + timing-102000000 { + clock-frequency = <102000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-cfg-dyn-self-ref; + nvidia,emc-configuration = < + 0x00000004 /* EMC_RC */ + 0x0000001a /* EMC_RFC */ + 0x00000003 /* EMC_RAS */ + 0x00000001 /* EMC_RP */ + 0x00000002 /* EMC_R2W */ + 0x0000000a /* EMC_W2R */ + 0x00000005 /* EMC_R2P */ + 0x0000000b /* EMC_W2P */ + 0x00000001 /* EMC_RD_RCD */ + 0x00000001 /* EMC_WR_RCD */ + 0x00000003 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000005 /* EMC_WDV */ + 0x00000005 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000b /* EMC_RDV */ + 0x00000303 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x000000c0 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000002 /* EMC_PDEX2WR */ + 0x00000002 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000007 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x0000001c /* EMC_TXSR */ + 0x0000001c /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000005 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x0000031c /* EMC_TREFBW */ + 0x00000006 /* EMC_QUSE_EXTRA */ + 0x00000004 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00004288 /* EMC_FBIO_CFG5 */ + 0x007800a4 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x000fc000 /* EMC_DLL_XFORM_DQS0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS3 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS4 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS5 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS6 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800211c /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f108 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x08000168 /* EMC_XM2QUSEPADCTRL */ + 0x08000000 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00000000 /* EMC_ZCAL_INTERVAL */ + 0x00000040 /* EMC_ZCAL_WAIT_CNT */ + 0x000c000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x80000713 /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff00 /* EMC_CFG_RSV */ + >; + }; + timing-204000000 { + clock-frequency = <204000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-cfg-dyn-self-ref; + nvidia,emc-configuration = < + 0x00000009 /* EMC_RC */ + 0x00000035 /* EMC_RFC */ + 0x00000007 /* EMC_RAS */ + 0x00000002 /* EMC_RP */ + 0x00000002 /* EMC_R2W */ + 0x0000000a /* EMC_W2R */ + 0x00000005 /* EMC_R2P */ + 0x0000000b /* EMC_W2P */ + 0x00000002 /* EMC_RD_RCD */ + 0x00000002 /* EMC_WR_RCD */ + 0x00000003 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000005 /* EMC_WDV */ + 0x00000005 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000b /* EMC_RDV */ + 0x00000607 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x00000181 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000002 /* EMC_PDEX2WR */ + 0x00000002 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000007 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x00000038 /* EMC_TXSR */ + 0x00000038 /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000009 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x00000638 /* EMC_TREFBW */ + 0x00000006 /* EMC_QUSE_EXTRA */ + 0x00000006 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00004288 /* EMC_FBIO_CFG5 */ + 0x004400a4 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x00080000 /* EMC_DLL_XFORM_DQS0 */ + 0x00080000 /* EMC_DLL_XFORM_DQS1 */ + 0x00080000 /* EMC_DLL_XFORM_DQS2 */ + 0x00080000 /* EMC_DLL_XFORM_DQS3 */ + 0x00080000 /* EMC_DLL_XFORM_DQS4 */ + 0x00080000 /* EMC_DLL_XFORM_DQS5 */ + 0x00080000 /* EMC_DLL_XFORM_DQS6 */ + 0x00080000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x00080000 /* EMC_DLL_XFORM_DQ0 */ + 0x00080000 /* EMC_DLL_XFORM_DQ1 */ + 0x00080000 /* EMC_DLL_XFORM_DQ2 */ + 0x00080000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800211c /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f108 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x08000168 /* EMC_XM2QUSEPADCTRL */ + 0x08000000 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00020000 /* EMC_ZCAL_INTERVAL */ + 0x00000100 /* EMC_ZCAL_WAIT_CNT */ + 0x000c000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x80000d22 /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff00 /* EMC_CFG_RSV */ + >; + }; + timing-400000000 { + clock-frequency = <400000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100002>; + nvidia,emc-mode-2 = <0x80200000>; + nvidia,emc-mode-reset = <0x80000521>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-configuration = < + 0x00000012 /* EMC_RC */ + 0x00000066 /* EMC_RFC */ + 0x0000000c /* EMC_RAS */ + 0x00000004 /* EMC_RP */ + 0x00000003 /* EMC_R2W */ + 0x00000008 /* EMC_W2R */ + 0x00000002 /* EMC_R2P */ + 0x0000000a /* EMC_W2P */ + 0x00000004 /* EMC_RD_RCD */ + 0x00000004 /* EMC_WR_RCD */ + 0x00000002 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000004 /* EMC_WDV */ + 0x00000006 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000c /* EMC_RDV */ + 0x00000bf0 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x000002fc /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000001 /* EMC_PDEX2WR */ + 0x00000008 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000008 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x0000006c /* EMC_TXSR */ + 0x00000200 /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000010 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x00000c30 /* EMC_TREFBW */ + 0x00000000 /* EMC_QUSE_EXTRA */ + 0x00000004 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00007088 /* EMC_FBIO_CFG5 */ + 0x001d0084 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x0003c000 /* EMC_DLL_XFORM_DQS0 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS1 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS2 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS3 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS4 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS5 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS6 */ + 0x0003c000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x00048000 /* EMC_DLL_XFORM_DQ0 */ + 0x00048000 /* EMC_DLL_XFORM_DQ1 */ + 0x00048000 /* EMC_DLL_XFORM_DQ2 */ + 0x00048000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800013d /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f508 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x080001e8 /* EMC_XM2QUSEPADCTRL */ + 0x08000021 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00020000 /* EMC_ZCAL_INTERVAL */ + 0x00000100 /* EMC_ZCAL_WAIT_CNT */ + 0x0158000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x800018c8 /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff89 /* EMC_CFG_RSV */ + >; + }; + timing-800000000 { + clock-frequency = <800000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100002>; + nvidia,emc-mode-2 = <0x80200018>; + nvidia,emc-mode-reset = <0x80000d71>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-configuration = < + 0x00000025 /* EMC_RC */ + 0x000000ce /* EMC_RFC */ + 0x0000001a /* EMC_RAS */ + 0x00000009 /* EMC_RP */ + 0x00000005 /* EMC_R2W */ + 0x0000000d /* EMC_W2R */ + 0x00000004 /* EMC_R2P */ + 0x00000013 /* EMC_W2P */ + 0x00000009 /* EMC_RD_RCD */ + 0x00000009 /* EMC_WR_RCD */ + 0x00000004 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000007 /* EMC_WDV */ + 0x0000000a /* EMC_QUSE */ + 0x00000009 /* EMC_QRST */ + 0x0000000b /* EMC_QSAFE */ + 0x00000011 /* EMC_RDV */ + 0x00001820 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x00000608 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000003 /* EMC_PDEX2WR */ + 0x00000012 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x0000000f /* EMC_AR2PDEN */ + 0x00000018 /* EMC_RW2PDEN */ + 0x000000d8 /* EMC_TXSR */ + 0x00000200 /* EMC_TXSRDLL */ + 0x00000005 /* EMC_TCKE */ + 0x00000020 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000007 /* EMC_TCLKSTABLE */ + 0x00000008 /* EMC_TCLKSTOP */ + 0x00001860 /* EMC_TREFBW */ + 0x0000000b /* EMC_QUSE_EXTRA */ + 0x00000006 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00005088 /* EMC_FBIO_CFG5 */ + 0xf0070191 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x0000800a /* EMC_DLL_XFORM_DQS0 */ + 0x0000000a /* EMC_DLL_XFORM_DQS1 */ + 0x0000000a /* EMC_DLL_XFORM_DQS2 */ + 0x0000000a /* EMC_DLL_XFORM_DQS3 */ + 0x0000000a /* EMC_DLL_XFORM_DQS4 */ + 0x0000000a /* EMC_DLL_XFORM_DQS5 */ + 0x0000000a /* EMC_DLL_XFORM_DQS6 */ + 0x0000000a /* EMC_DLL_XFORM_DQS7 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x0000000a /* EMC_DLL_XFORM_DQ0 */ + 0x0000000a /* EMC_DLL_XFORM_DQ1 */ + 0x0000000a /* EMC_DLL_XFORM_DQ2 */ + 0x0000000a /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0600013d /* EMC_XM2DQSPADCTRL2 */ + 0x22220000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f501 /* EMC_XM2COMPPADCTRL */ + 0x07077404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000000 /* EMC_XM2VTTGENPADCTRL2 */ + 0x080001e8 /* EMC_XM2QUSEPADCTRL */ + 0x08000021 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00020000 /* EMC_ZCAL_INTERVAL */ + 0x00000100 /* EMC_ZCAL_WAIT_CNT */ + 0x00f0000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x8000308c /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff49 /* EMC_CFG_RSV */ + >; + }; + }; + emc-timings-2 { + nvidia,ram-code = <2>; /* Hynix A RAM */ + timing-25500000 { + clock-frequency = <25500000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-cfg-dyn-self-ref; + nvidia,emc-configuration = < + 0x00000001 /* EMC_RC */ + 0x00000007 /* EMC_RFC */ + 0x00000000 /* EMC_RAS */ + 0x00000000 /* EMC_RP */ + 0x00000002 /* EMC_R2W */ + 0x0000000a /* EMC_W2R */ + 0x00000005 /* EMC_R2P */ + 0x0000000b /* EMC_W2P */ + 0x00000000 /* EMC_RD_RCD */ + 0x00000000 /* EMC_WR_RCD */ + 0x00000003 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000005 /* EMC_WDV */ + 0x00000005 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000b /* EMC_RDV */ + 0x000000c0 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x00000030 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000002 /* EMC_PDEX2WR */ + 0x00000002 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000007 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x00000008 /* EMC_TXSR */ + 0x00000008 /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000002 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x000000c7 /* EMC_TREFBW */ + 0x00000006 /* EMC_QUSE_EXTRA */ + 0x00000004 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00004288 /* EMC_FBIO_CFG5 */ + 0x007800a4 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x000fc000 /* EMC_DLL_XFORM_DQS0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS3 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS4 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS5 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS6 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800211c /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f108 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x08000168 /* EMC_XM2QUSEPADCTRL */ + 0x08000000 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00000000 /* EMC_ZCAL_INTERVAL */ + 0x00000040 /* EMC_ZCAL_WAIT_CNT */ + 0x000c000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x80000287 /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff00 /* EMC_CFG_RSV */ + >; + }; + timing-51000000 { + clock-frequency = <51000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-cfg-dyn-self-ref; + nvidia,emc-configuration = < + 0x00000002 /* EMC_RC */ + 0x0000000f /* EMC_RFC */ + 0x00000001 /* EMC_RAS */ + 0x00000000 /* EMC_RP */ + 0x00000002 /* EMC_R2W */ + 0x0000000a /* EMC_W2R */ + 0x00000005 /* EMC_R2P */ + 0x0000000b /* EMC_W2P */ + 0x00000000 /* EMC_RD_RCD */ + 0x00000000 /* EMC_WR_RCD */ + 0x00000003 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000005 /* EMC_WDV */ + 0x00000005 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000b /* EMC_RDV */ + 0x00000181 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x00000060 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000002 /* EMC_PDEX2WR */ + 0x00000002 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000007 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x00000010 /* EMC_TXSR */ + 0x00000010 /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000003 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x0000018e /* EMC_TREFBW */ + 0x00000006 /* EMC_QUSE_EXTRA */ + 0x00000004 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00004288 /* EMC_FBIO_CFG5 */ + 0x007800a4 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x000fc000 /* EMC_DLL_XFORM_DQS0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS3 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS4 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS5 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS6 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800211c /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f108 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x08000168 /* EMC_XM2QUSEPADCTRL */ + 0x08000000 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00000000 /* EMC_ZCAL_INTERVAL */ + 0x00000040 /* EMC_ZCAL_WAIT_CNT */ + 0x000c000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x8000040b /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff00 /* EMC_CFG_RSV */ + >; + }; + timing-102000000 { + clock-frequency = <102000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-cfg-dyn-self-ref; + nvidia,emc-configuration = < + 0x00000004 /* EMC_RC */ + 0x0000001e /* EMC_RFC */ + 0x00000003 /* EMC_RAS */ + 0x00000001 /* EMC_RP */ + 0x00000002 /* EMC_R2W */ + 0x0000000a /* EMC_W2R */ + 0x00000005 /* EMC_R2P */ + 0x0000000b /* EMC_W2P */ + 0x00000001 /* EMC_RD_RCD */ + 0x00000001 /* EMC_WR_RCD */ + 0x00000003 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000005 /* EMC_WDV */ + 0x00000005 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000b /* EMC_RDV */ + 0x00000303 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x000000c0 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000002 /* EMC_PDEX2WR */ + 0x00000002 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000007 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x00000020 /* EMC_TXSR */ + 0x00000020 /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000005 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x0000031c /* EMC_TREFBW */ + 0x00000006 /* EMC_QUSE_EXTRA */ + 0x00000004 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00004288 /* EMC_FBIO_CFG5 */ + 0x007800a4 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x000fc000 /* EMC_DLL_XFORM_DQS0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS3 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS4 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS5 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS6 */ + 0x000fc000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ0 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ1 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ2 */ + 0x000fc000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800211c /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f108 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x08000168 /* EMC_XM2QUSEPADCTRL */ + 0x08000000 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00000000 /* EMC_ZCAL_INTERVAL */ + 0x00000040 /* EMC_ZCAL_WAIT_CNT */ + 0x000c000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x80000713 /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff00 /* EMC_CFG_RSV */ + >; + }; + timing-204000000 { + clock-frequency = <204000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-cfg-dyn-self-ref; + nvidia,emc-configuration = < + 0x00000009 /* EMC_RC */ + 0x0000003d /* EMC_RFC */ + 0x00000007 /* EMC_RAS */ + 0x00000002 /* EMC_RP */ + 0x00000002 /* EMC_R2W */ + 0x0000000a /* EMC_W2R */ + 0x00000005 /* EMC_R2P */ + 0x0000000b /* EMC_W2P */ + 0x00000002 /* EMC_RD_RCD */ + 0x00000002 /* EMC_WR_RCD */ + 0x00000003 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000005 /* EMC_WDV */ + 0x00000005 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000b /* EMC_RDV */ + 0x00000607 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x00000181 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000002 /* EMC_PDEX2WR */ + 0x00000002 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000007 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x00000040 /* EMC_TXSR */ + 0x00000040 /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000009 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x00000638 /* EMC_TREFBW */ + 0x00000006 /* EMC_QUSE_EXTRA */ + 0x00000006 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00004288 /* EMC_FBIO_CFG5 */ + 0x004400a4 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x00080000 /* EMC_DLL_XFORM_DQS0 */ + 0x00080000 /* EMC_DLL_XFORM_DQS1 */ + 0x00080000 /* EMC_DLL_XFORM_DQS2 */ + 0x00080000 /* EMC_DLL_XFORM_DQS3 */ + 0x00080000 /* EMC_DLL_XFORM_DQS4 */ + 0x00080000 /* EMC_DLL_XFORM_DQS5 */ + 0x00080000 /* EMC_DLL_XFORM_DQS6 */ + 0x00080000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x00080000 /* EMC_DLL_XFORM_DQ0 */ + 0x00080000 /* EMC_DLL_XFORM_DQ1 */ + 0x00080000 /* EMC_DLL_XFORM_DQ2 */ + 0x00080000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800211c /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f108 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x08000168 /* EMC_XM2QUSEPADCTRL */ + 0x08000000 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00020000 /* EMC_ZCAL_INTERVAL */ + 0x00000100 /* EMC_ZCAL_WAIT_CNT */ + 0x000c000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x80000d22 /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff00 /* EMC_CFG_RSV */ + >; + }; + timing-400000000 { + clock-frequency = <400000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100002>; + nvidia,emc-mode-2 = <0x80200000>; + nvidia,emc-mode-reset = <0x80000521>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-configuration = < + 0x00000012 /* EMC_RC */ + 0x00000076 /* EMC_RFC */ + 0x0000000c /* EMC_RAS */ + 0x00000004 /* EMC_RP */ + 0x00000003 /* EMC_R2W */ + 0x00000008 /* EMC_W2R */ + 0x00000002 /* EMC_R2P */ + 0x0000000a /* EMC_W2P */ + 0x00000004 /* EMC_RD_RCD */ + 0x00000004 /* EMC_WR_RCD */ + 0x00000002 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000004 /* EMC_WDV */ + 0x00000006 /* EMC_QUSE */ + 0x00000004 /* EMC_QRST */ + 0x0000000a /* EMC_QSAFE */ + 0x0000000c /* EMC_RDV */ + 0x00000bf0 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x000002fc /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000001 /* EMC_PDEX2WR */ + 0x00000008 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x00000008 /* EMC_AR2PDEN */ + 0x0000000f /* EMC_RW2PDEN */ + 0x0000007c /* EMC_TXSR */ + 0x00000200 /* EMC_TXSRDLL */ + 0x00000004 /* EMC_TCKE */ + 0x00000010 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000004 /* EMC_TCLKSTABLE */ + 0x00000005 /* EMC_TCLKSTOP */ + 0x00000c30 /* EMC_TREFBW */ + 0x00000000 /* EMC_QUSE_EXTRA */ + 0x00000004 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00007088 /* EMC_FBIO_CFG5 */ + 0x001d0084 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x00044000 /* EMC_DLL_XFORM_DQS0 */ + 0x00044000 /* EMC_DLL_XFORM_DQS1 */ + 0x00044000 /* EMC_DLL_XFORM_DQS2 */ + 0x00044000 /* EMC_DLL_XFORM_DQS3 */ + 0x00044000 /* EMC_DLL_XFORM_DQS4 */ + 0x00044000 /* EMC_DLL_XFORM_DQS5 */ + 0x00044000 /* EMC_DLL_XFORM_DQS6 */ + 0x00044000 /* EMC_DLL_XFORM_DQS7 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00000000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x00058000 /* EMC_DLL_XFORM_DQ0 */ + 0x00058000 /* EMC_DLL_XFORM_DQ1 */ + 0x00058000 /* EMC_DLL_XFORM_DQ2 */ + 0x00058000 /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0800013d /* EMC_XM2DQSPADCTRL2 */ + 0x00000000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f508 /* EMC_XM2COMPPADCTRL */ + 0x05057404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000007 /* EMC_XM2VTTGENPADCTRL2 */ + 0x080001e8 /* EMC_XM2QUSEPADCTRL */ + 0x08000021 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00020000 /* EMC_ZCAL_INTERVAL */ + 0x00000100 /* EMC_ZCAL_WAIT_CNT */ + 0x0148000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x800018c8 /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff89 /* EMC_CFG_RSV */ + >; + }; + timing-800000000 { + clock-frequency = <800000000>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-mode-1 = <0x80100002>; + nvidia,emc-mode-2 = <0x80200018>; + nvidia,emc-mode-reset = <0x80000d71>; + nvidia,emc-zcal-cnt-long = <0x00000040>; + nvidia,emc-cfg-periodic-qrst; + nvidia,emc-configuration = < + 0x00000025 /* EMC_RC */ + 0x000000ee /* EMC_RFC */ + 0x0000001a /* EMC_RAS */ + 0x00000009 /* EMC_RP */ + 0x00000005 /* EMC_R2W */ + 0x0000000d /* EMC_W2R */ + 0x00000004 /* EMC_R2P */ + 0x00000013 /* EMC_W2P */ + 0x00000009 /* EMC_RD_RCD */ + 0x00000009 /* EMC_WR_RCD */ + 0x00000003 /* EMC_RRD */ + 0x00000001 /* EMC_REXT */ + 0x00000000 /* EMC_WEXT */ + 0x00000007 /* EMC_WDV */ + 0x0000000a /* EMC_QUSE */ + 0x00000009 /* EMC_QRST */ + 0x0000000b /* EMC_QSAFE */ + 0x00000011 /* EMC_RDV */ + 0x00001820 /* EMC_REFRESH */ + 0x00000000 /* EMC_BURST_REFRESH_NUM */ + 0x00000608 /* EMC_PRE_REFRESH_REQ_CNT */ + 0x00000003 /* EMC_PDEX2WR */ + 0x00000012 /* EMC_PDEX2RD */ + 0x00000001 /* EMC_PCHG2PDEN */ + 0x00000000 /* EMC_ACT2PDEN */ + 0x0000000f /* EMC_AR2PDEN */ + 0x00000018 /* EMC_RW2PDEN */ + 0x000000f8 /* EMC_TXSR */ + 0x00000200 /* EMC_TXSRDLL */ + 0x00000005 /* EMC_TCKE */ + 0x00000020 /* EMC_TFAW */ + 0x00000000 /* EMC_TRPAB */ + 0x00000007 /* EMC_TCLKSTABLE */ + 0x00000008 /* EMC_TCLKSTOP */ + 0x00001860 /* EMC_TREFBW */ + 0x0000000b /* EMC_QUSE_EXTRA */ + 0x00000006 /* EMC_FBIO_CFG6 */ + 0x00000000 /* EMC_ODT_WRITE */ + 0x00000000 /* EMC_ODT_READ */ + 0x00005088 /* EMC_FBIO_CFG5 */ + 0xf0070191 /* EMC_CFG_DIG_DLL */ + 0x00008000 /* EMC_CFG_DIG_DLL_PERIOD */ + 0x0000000c /* EMC_DLL_XFORM_DQS0 */ + 0x007fc00a /* EMC_DLL_XFORM_DQS1 */ + 0x00000008 /* EMC_DLL_XFORM_DQS2 */ + 0x0000000a /* EMC_DLL_XFORM_DQS3 */ + 0x0000000a /* EMC_DLL_XFORM_DQS4 */ + 0x0000000a /* EMC_DLL_XFORM_DQS5 */ + 0x0000000a /* EMC_DLL_XFORM_DQS6 */ + 0x0000000a /* EMC_DLL_XFORM_DQS7 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE0 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE1 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE2 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE3 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE4 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE5 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE6 */ + 0x00018000 /* EMC_DLL_XFORM_QUSE7 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS0 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS1 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS2 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS3 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS4 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS5 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS6 */ + 0x00000000 /* EMC_DLI_TRIM_TXDQS7 */ + 0x0000000a /* EMC_DLL_XFORM_DQ0 */ + 0x0000000c /* EMC_DLL_XFORM_DQ1 */ + 0x0000000a /* EMC_DLL_XFORM_DQ2 */ + 0x0000000a /* EMC_DLL_XFORM_DQ3 */ + 0x000002a0 /* EMC_XM2CMDPADCTRL */ + 0x0600013d /* EMC_XM2DQSPADCTRL2 */ + 0x22220000 /* EMC_XM2DQPADCTRL2 */ + 0x77fff884 /* EMC_XM2CLKPADCTRL */ + 0x01f1f501 /* EMC_XM2COMPPADCTRL */ + 0x07077404 /* EMC_XM2VTTGENPADCTRL */ + 0x54000000 /* EMC_XM2VTTGENPADCTRL2 */ + 0x080001e8 /* EMC_XM2QUSEPADCTRL */ + 0x0a000021 /* EMC_XM2DQSPADCTRL3 */ + 0x00000802 /* EMC_CTT_TERM_CTRL */ + 0x00020000 /* EMC_ZCAL_INTERVAL */ + 0x00000100 /* EMC_ZCAL_WAIT_CNT */ + 0x00d0000c /* EMC_MRS_WAIT_CNT */ + 0xa0f10000 /* EMC_AUTO_CAL_CONFIG */ + 0x00000000 /* EMC_CTT */ + 0x00000000 /* EMC_CTT_DURATION */ + 0x8000308c /* EMC_DYN_SELF_REF_CONTROL */ + 0xe8000000 /* EMC_FBIO_SPARE */ + 0xff00ff49 /* EMC_CFG_RSV */ + >; + }; + }; +}; +&state_default { + clk_32k_out_pa0 { + nvidia,pins = "clk_32k_out_pa0"; + nvidia,function = "blink"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + uart3_cts_n_pa1 { + nvidia,pins = "uart3_cts_n_pa1"; + nvidia,function = "uartc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap2_fs_pa2 { + nvidia,pins = "dap2_fs_pa2"; + nvidia,function = "i2s1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap2_sclk_pa3 { + nvidia,pins = "dap2_sclk_pa3"; + nvidia,function = "i2s1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap2_din_pa4 { + nvidia,pins = "dap2_din_pa4"; + nvidia,function = "i2s1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap2_dout_pa5 { + nvidia,pins = "dap2_dout_pa5"; + nvidia,function = "i2s1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + sdmmc3_clk_pa6 { + nvidia,pins = "sdmmc3_clk_pa6"; + nvidia,function = "sdmmc3"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + sdmmc3_cmd_pa7 { + nvidia,pins = "sdmmc3_cmd_pa7"; + nvidia,function = "sdmmc3"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + gmi_a17_pb0 { + nvidia,pins = "gmi_a17_pb0"; + nvidia,function = "spi4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_a18_pb1 { + nvidia,pins = "gmi_a18_pb1"; + nvidia,function = "spi4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_pwr0_pb2 { + nvidia,pins = "lcd_pwr0_pb2"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_pclk_pb3 { + nvidia,pins = "lcd_pclk_pb3"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + sdmmc3_dat3_pb4 { + nvidia,pins = "sdmmc3_dat3_pb4"; + nvidia,function = "sdmmc3"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + sdmmc3_dat2_pb5 { + nvidia,pins = "sdmmc3_dat2_pb5"; + nvidia,function = "sdmmc3"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + sdmmc3_dat1_pb6 { + nvidia,pins = "sdmmc3_dat1_pb6"; + nvidia,function = "sdmmc3"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + sdmmc3_dat0_pb7 { + nvidia,pins = "sdmmc3_dat0_pb7"; + nvidia,function = "sdmmc3"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + uart3_rts_n_pc0 { + nvidia,pins = "uart3_rts_n_pc0"; + nvidia,function = "uartc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_pwr1_pc1 { + nvidia,pins = "lcd_pwr1_pc1"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + uart2_txd_pc2 { + nvidia,pins = "uart2_txd_pc2"; + nvidia,function = "uartb"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + uart2_rxd_pc3 { + nvidia,pins = "uart2_rxd_pc3"; + nvidia,function = "uartb"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gen1_i2c_scl_pc4 { + nvidia,pins = "gen1_i2c_scl_pc4"; + nvidia,function = "i2c1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + nvidia,open-drain = <TEGRA_PIN_DISABLE>; + }; + gen1_i2c_sda_pc5 { + nvidia,pins = "gen1_i2c_sda_pc5"; + nvidia,function = "i2c1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + nvidia,open-drain = <TEGRA_PIN_DISABLE>; + }; + lcd_pwr2_pc6 { + nvidia,pins = "lcd_pwr2_pc6"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_wp_n_pc7 { + nvidia,pins = "gmi_wp_n_pc7"; + nvidia,function = "gmi"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + sdmmc3_dat5_pd0 { + nvidia,pins = "sdmmc3_dat5_pd0"; + nvidia,function = "sdmmc3"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + sdmmc3_dat4_pd1 { + nvidia,pins = "sdmmc3_dat4_pd1"; + nvidia,function = "sdmmc3"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + lcd_dc1_pd2 { + nvidia,pins = "lcd_dc1_pd2"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + sdmmc3_dat6_pd3 { + nvidia,pins = "sdmmc3_dat6_pd3"; + nvidia,function = "spi4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + sdmmc3_dat7_pd4 { + nvidia,pins = "sdmmc3_dat7_pd4"; + nvidia,function = "spi4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + vi_d1_pd5 { + nvidia,pins = "vi_d1_pd5"; + nvidia,function = "sdmmc2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + vi_vsync_pd6 { + nvidia,pins = "vi_vsync_pd6"; + nvidia,function = "ddr"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + vi_hsync_pd7 { + nvidia,pins = "vi_hsync_pd7"; + nvidia,function = "ddr"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + lcd_d0_pe0 { + nvidia,pins = "lcd_d0_pe0"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d1_pe1 { + nvidia,pins = "lcd_d1_pe1"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d2_pe2 { + nvidia,pins = "lcd_d2_pe2"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d3_pe3 { + nvidia,pins = "lcd_d3_pe3"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d4_pe4 { + nvidia,pins = "lcd_d4_pe4"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d5_pe5 { + nvidia,pins = "lcd_d5_pe5"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d6_pe6 { + nvidia,pins = "lcd_d6_pe6"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d7_pe7 { + nvidia,pins = "lcd_d7_pe7"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d8_pf0 { + nvidia,pins = "lcd_d8_pf0"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d9_pf1 { + nvidia,pins = "lcd_d9_pf1"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d10_pf2 { + nvidia,pins = "lcd_d10_pf2"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d11_pf3 { + nvidia,pins = "lcd_d11_pf3"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d12_pf4 { + nvidia,pins = "lcd_d12_pf4"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d13_pf5 { + nvidia,pins = "lcd_d13_pf5"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d14_pf6 { + nvidia,pins = "lcd_d14_pf6"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d15_pf7 { + nvidia,pins = "lcd_d15_pf7"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_ad0_pg0 { + nvidia,pins = "gmi_ad0_pg0"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + gmi_ad1_pg1 { + nvidia,pins = "gmi_ad1_pg1"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_ad2_pg2 { + nvidia,pins = "gmi_ad2_pg2"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + gmi_ad3_pg3 { + nvidia,pins = "gmi_ad3_pg3"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + gmi_ad4_pg4 { + nvidia,pins = "gmi_ad4_pg4"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + gmi_ad5_pg5 { + nvidia,pins = "gmi_ad5_pg5"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + gmi_ad6_pg6 { + nvidia,pins = "gmi_ad6_pg6"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + gmi_ad7_pg7 { + nvidia,pins = "gmi_ad7_pg7"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + gmi_ad8_ph0 { + nvidia,pins = "gmi_ad8_ph0"; + nvidia,function = "pwm0"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_ad9_ph1 { + nvidia,pins = "gmi_ad9_ph1"; + nvidia,function = "pwm1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_ad10_ph2 { + nvidia,pins = "gmi_ad10_ph2"; + nvidia,function = "pwm2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_ad11_ph3 { + nvidia,pins = "gmi_ad11_ph3"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_ad12_ph4 { + nvidia,pins = "gmi_ad12_ph4"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_ad13_ph5 { + nvidia,pins = "gmi_ad13_ph5"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_ad14_ph6 { + nvidia,pins = "gmi_ad14_ph6"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_wr_n_pi0 { + nvidia,pins = "gmi_wr_n_pi0"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_oe_n_pi1 { + nvidia,pins = "gmi_oe_n_pi1"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_dqs_pi2 { + nvidia,pins = "gmi_dqs_pi2"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_iordy_pi5 { + nvidia,pins = "gmi_iordy_pi5"; + nvidia,function = "rsvd1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_cs7_n_pi6 { + nvidia,pins = "gmi_cs7_n_pi6"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_wait_pi7 { + nvidia,pins = "gmi_wait_pi7"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_de_pj1 { + nvidia,pins = "lcd_de_pj1"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_cs1_n_pj2 { + nvidia,pins = "gmi_cs1_n_pj2"; + nvidia,function = "rsvd1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_hsync_pj3 { + nvidia,pins = "lcd_hsync_pj3"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_vsync_pj4 { + nvidia,pins = "lcd_vsync_pj4"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + uart2_cts_n_pj5 { + nvidia,pins = "uart2_cts_n_pj5"; + nvidia,function = "uartb"; + nvidia,pull = <TEGRA_PIN_PULL_DOWN>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + uart2_rts_n_pj6 { + nvidia,pins = "uart2_rts_n_pj6"; + nvidia,function = "uartb"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_a16_pj7 { + nvidia,pins = "gmi_a16_pj7"; + nvidia,function = "spi4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_adv_n_pk0 { + nvidia,pins = "gmi_adv_n_pk0"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_clk_pk1 { + nvidia,pins = "gmi_clk_pk1"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_cs2_n_pk3 { + nvidia,pins = "gmi_cs2_n_pk3"; + nvidia,function = "rsvd1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + gmi_cs3_n_pk4 { + nvidia,pins = "gmi_cs3_n_pk4"; + nvidia,function = "nand"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + spdif_out_pk5 { + nvidia,pins = "spdif_out_pk5"; + nvidia,function = "spdif"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + spdif_in_pk6 { + nvidia,pins = "spdif_in_pk6"; + nvidia,function = "spdif"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + gmi_a19_pk7 { + nvidia,pins = "gmi_a19_pk7"; + nvidia,function = "spi4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + vi_d2_pl0 { + nvidia,pins = "vi_d2_pl0"; + nvidia,function = "sdmmc2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + vi_d3_pl1 { + nvidia,pins = "vi_d3_pl1"; + nvidia,function = "sdmmc2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + vi_d4_pl2 { + nvidia,pins = "vi_d4_pl2"; + nvidia,function = "vi"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + vi_d5_pl3 { + nvidia,pins = "vi_d5_pl3"; + nvidia,function = "sdmmc2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + vi_d6_pl4 { + nvidia,pins = "vi_d6_pl4"; + nvidia,function = "vi"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + vi_d7_pl5 { + nvidia,pins = "vi_d7_pl5"; + nvidia,function = "sdmmc2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + vi_d8_pl6 { + nvidia,pins = "vi_d8_pl6"; + nvidia,function = "sdmmc2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + vi_d9_pl7 { + nvidia,pins = "vi_d9_pl7"; + nvidia,function = "sdmmc2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d16_pm0 { + nvidia,pins = "lcd_d16_pm0"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d17_pm1 { + nvidia,pins = "lcd_d17_pm1"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d18_pm2 { + nvidia,pins = "lcd_d18_pm2"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d19_pm3 { + nvidia,pins = "lcd_d19_pm3"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d20_pm4 { + nvidia,pins = "lcd_d20_pm4"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d21_pm5 { + nvidia,pins = "lcd_d21_pm5"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d22_pm6 { + nvidia,pins = "lcd_d22_pm6"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_d23_pm7 { + nvidia,pins = "lcd_d23_pm7"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + dap1_fs_pn0 { + nvidia,pins = "dap1_fs_pn0"; + nvidia,function = "i2s0"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap1_din_pn1 { + nvidia,pins = "dap1_din_pn1"; + nvidia,function = "i2s0"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap1_dout_pn2 { + nvidia,pins = "dap1_dout_pn2"; + nvidia,function = "i2s0"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap1_sclk_pn3 { + nvidia,pins = "dap1_sclk_pn3"; + nvidia,function = "i2s0"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + lcd_cs0_n_pn4 { + nvidia,pins = "lcd_cs0_n_pn4"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_sdout_pn5 { + nvidia,pins = "lcd_sdout_pn5"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_dc0_pn6 { + nvidia,pins = "lcd_dc0_pn6"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + hdmi_int_pn7 { + nvidia,pins = "hdmi_int_pn7"; + nvidia,function = "hdmi"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + ulpi_data7_po0 { + nvidia,pins = "ulpi_data7_po0"; + nvidia,function = "uarta"; + nvidia,pull = <TEGRA_PIN_PULL_DOWN>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + ulpi_data0_po1 { + nvidia,pins = "ulpi_data0_po1"; + nvidia,function = "uarta"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + ulpi_data1_po2 { + nvidia,pins = "ulpi_data1_po2"; + nvidia,function = "uarta"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + ulpi_data2_po3 { + nvidia,pins = "ulpi_data2_po3"; + nvidia,function = "uarta"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + ulpi_data3_po4 { + nvidia,pins = "ulpi_data3_po4"; + nvidia,function = "uarta"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + ulpi_data4_po5 { + nvidia,pins = "ulpi_data4_po5"; + nvidia,function = "uarta"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + ulpi_data5_po6 { + nvidia,pins = "ulpi_data5_po6"; + nvidia,function = "uarta"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + ulpi_data6_po7 { + nvidia,pins = "ulpi_data6_po7"; + nvidia,function = "uarta"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + dap3_fs_pp0 { + nvidia,pins = "dap3_fs_pp0"; + nvidia,function = "i2s2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap3_din_pp1 { + nvidia,pins = "dap3_din_pp1"; + nvidia,function = "i2s2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap3_dout_pp2 { + nvidia,pins = "dap3_dout_pp2"; + nvidia,function = "i2s2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap3_sclk_pp3 { + nvidia,pins = "dap3_sclk_pp3"; + nvidia,function = "i2s2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap4_fs_pp4 { + nvidia,pins = "dap4_fs_pp4"; + nvidia,function = "i2s3"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap4_din_pp5 { + nvidia,pins = "dap4_din_pp5"; + nvidia,function = "i2s3"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap4_dout_pp6 { + nvidia,pins = "dap4_dout_pp6"; + nvidia,function = "i2s3"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + dap4_sclk_pp7 { + nvidia,pins = "dap4_sclk_pp7"; + nvidia,function = "i2s3"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + kb_col0_pq0 { + nvidia,pins = "kb_col0_pq0"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_col1_pq1 { + nvidia,pins = "kb_col1_pq1"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_col2_pq2 { + nvidia,pins = "kb_col2_pq2"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_col3_pq3 { + nvidia,pins = "kb_col3_pq3"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_col4_pq4 { + nvidia,pins = "kb_col4_pq4"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_col5_pq5 { + nvidia,pins = "kb_col5_pq5"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_col6_pq6 { + nvidia,pins = "kb_col6_pq6"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_col7_pq7 { + nvidia,pins = "kb_col7_pq7"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row0_pr0 { + nvidia,pins = "kb_row0_pr0"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row1_pr1 { + nvidia,pins = "kb_row1_pr1"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row2_pr2 { + nvidia,pins = "kb_row2_pr2"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row3_pr3 { + nvidia,pins = "kb_row3_pr3"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row4_pr4 { + nvidia,pins = "kb_row4_pr4"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row5_pr5 { + nvidia,pins = "kb_row5_pr5"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row6_pr6 { + nvidia,pins = "kb_row6_pr6"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row7_pr7 { + nvidia,pins = "kb_row7_pr7"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + kb_row8_ps0 { + nvidia,pins = "kb_row8_ps0"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row9_ps1 { + nvidia,pins = "kb_row9_ps1"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row10_ps2 { + nvidia,pins = "kb_row10_ps2"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row11_ps3 { + nvidia,pins = "kb_row11_ps3"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row12_ps4 { + nvidia,pins = "kb_row12_ps4"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row13_ps5 { + nvidia,pins = "kb_row13_ps5"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row14_ps6 { + nvidia,pins = "kb_row14_ps6"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + kb_row15_ps7 { + nvidia,pins = "kb_row15_ps7"; + nvidia,function = "kbc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + vi_pclk_pt0 { + nvidia,pins = "vi_pclk_pt0"; + nvidia,function = "rsvd1"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + vi_mclk_pt1 { + nvidia,pins = "vi_mclk_pt1"; + nvidia,function = "vi"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + vi_d10_pt2 { + nvidia,pins = "vi_d10_pt2"; + nvidia,function = "ddr"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + vi_d11_pt3 { + nvidia,pins = "vi_d11_pt3"; + nvidia,function = "ddr"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + vi_d0_pt4 { + nvidia,pins = "vi_d0_pt4"; + nvidia,function = "ddr"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + gen2_i2c_scl_pt5 { + nvidia,pins = "gen2_i2c_scl_pt5"; + nvidia,function = "i2c2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + nvidia,open-drain = <TEGRA_PIN_DISABLE>; + }; + gen2_i2c_sda_pt6 { + nvidia,pins = "gen2_i2c_sda_pt6"; + nvidia,function = "i2c2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + nvidia,open-drain = <TEGRA_PIN_DISABLE>; + }; + sdmmc4_cmd_pt7 { + nvidia,pins = "sdmmc4_cmd_pt7"; + nvidia,function = "sdmmc4"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,io-reset = <TEGRA_PIN_DISABLE>; + }; + pu0 { + nvidia,pins = "pu0"; + nvidia,function = "owr"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pu1 { + nvidia,pins = "pu1"; + nvidia,function = "rsvd1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pu2 { + nvidia,pins = "pu2"; + nvidia,function = "rsvd1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pu3 { + nvidia,pins = "pu3"; + nvidia,function = "pwm0"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pu4 { + nvidia,pins = "pu4"; + nvidia,function = "pwm1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pu5 { + nvidia,pins = "pu5"; + nvidia,function = "rsvd4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pu6 { + nvidia,pins = "pu6"; + nvidia,function = "pwm3"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + jtag_rtck_pu7 { + nvidia,pins = "jtag_rtck_pu7"; + nvidia,function = "rtck"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pv0 { + nvidia,pins = "pv0"; + nvidia,function = "rsvd1"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + pv1 { + nvidia,pins = "pv1"; + nvidia,function = "rsvd1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pv2 { + nvidia,pins = "pv2"; + nvidia,function = "owr"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pv3 { + nvidia,pins = "pv3"; + nvidia,function = "clk_12m_out"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + ddc_scl_pv4 { + nvidia,pins = "ddc_scl_pv4"; + nvidia,function = "i2c4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + ddc_sda_pv5 { + nvidia,pins = "ddc_sda_pv5"; + nvidia,function = "i2c4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + crt_hsync_pv6 { + nvidia,pins = "crt_hsync_pv6"; + nvidia,function = "crt"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + crt_vsync_pv7 { + nvidia,pins = "crt_vsync_pv7"; + nvidia,function = "crt"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_cs1_n_pw0 { + nvidia,pins = "lcd_cs1_n_pw0"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_m1_pw1 { + nvidia,pins = "lcd_m1_pw1"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_DOWN>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + spi2_cs1_n_pw2 { + nvidia,pins = "spi2_cs1_n_pw2"; + nvidia,function = "spi2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + clk1_out_pw4 { + nvidia,pins = "clk1_out_pw4"; + nvidia,function = "extperiph1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + clk2_out_pw5 { + nvidia,pins = "clk2_out_pw5"; + nvidia,function = "extperiph2"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + uart3_txd_pw6 { + nvidia,pins = "uart3_txd_pw6"; + nvidia,function = "uartc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + uart3_rxd_pw7 { + nvidia,pins = "uart3_rxd_pw7"; + nvidia,function = "uartc"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + spi2_sck_px2 { + nvidia,pins = "spi2_sck_px2"; + nvidia,function = "gmi"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + spi1_mosi_px4 { + nvidia,pins = "spi1_mosi_px4"; + nvidia,function = "spi1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + spi1_sck_px5 { + nvidia,pins = "spi1_sck_px5"; + nvidia,function = "spi1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + spi1_cs0_n_px6 { + nvidia,pins = "spi1_cs0_n_px6"; + nvidia,function = "spi1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + spi1_miso_px7 { + nvidia,pins = "spi1_miso_px7"; + nvidia,function = "spi1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + ulpi_clk_py0 { + nvidia,pins = "ulpi_clk_py0"; + nvidia,function = "uartd"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + ulpi_dir_py1 { + nvidia,pins = "ulpi_dir_py1"; + nvidia,function = "uartd"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + ulpi_nxt_py2 { + nvidia,pins = "ulpi_nxt_py2"; + nvidia,function = "uartd"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + ulpi_stp_py3 { + nvidia,pins = "ulpi_stp_py3"; + nvidia,function = "uartd"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + sdmmc1_dat3_py4 { + nvidia,pins = "sdmmc1_dat3_py4"; + nvidia,function = "sdmmc1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + sdmmc1_dat2_py5 { + nvidia,pins = "sdmmc1_dat2_py5"; + nvidia,function = "sdmmc1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + sdmmc1_dat1_py6 { + nvidia,pins = "sdmmc1_dat1_py6"; + nvidia,function = "sdmmc1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + sdmmc1_dat0_py7 { + nvidia,pins = "sdmmc1_dat0_py7"; + nvidia,function = "sdmmc1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + sdmmc1_clk_pz0 { + nvidia,pins = "sdmmc1_clk_pz0"; + nvidia,function = "sdmmc1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + sdmmc1_cmd_pz1 { + nvidia,pins = "sdmmc1_cmd_pz1"; + nvidia,function = "sdmmc1"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_sdin_pz2 { + nvidia,pins = "lcd_sdin_pz2"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_wr_n_pz3 { + nvidia,pins = "lcd_wr_n_pz3"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + lcd_sck_pz4 { + nvidia,pins = "lcd_sck_pz4"; + nvidia,function = "displaya"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + sys_clk_req_pz5 { + nvidia,pins = "sys_clk_req_pz5"; + nvidia,function = "sysclk"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pwr_i2c_scl_pz6 { + nvidia,pins = "pwr_i2c_scl_pz6"; + nvidia,function = "i2cpwr"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,open-drain = <TEGRA_PIN_ENABLE>; + }; + pwr_i2c_sda_pz7 { + nvidia,pins = "pwr_i2c_sda_pz7"; + nvidia,function = "i2cpwr"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,open-drain = <TEGRA_PIN_ENABLE>; + }; + sdmmc4_dat0_paa0 { + nvidia,pins = "sdmmc4_dat0_paa0"; + nvidia,function = "sdmmc4"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,io-reset = <TEGRA_PIN_DISABLE>; + }; + sdmmc4_dat1_paa1 { + nvidia,pins = "sdmmc4_dat1_paa1"; + nvidia,function = "sdmmc4"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,io-reset = <TEGRA_PIN_DISABLE>; + }; + sdmmc4_dat2_paa2 { + nvidia,pins = "sdmmc4_dat2_paa2"; + nvidia,function = "sdmmc4"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,io-reset = <TEGRA_PIN_DISABLE>; + }; + sdmmc4_dat3_paa3 { + nvidia,pins = "sdmmc4_dat3_paa3"; + nvidia,function = "sdmmc4"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,io-reset = <TEGRA_PIN_DISABLE>; + }; + sdmmc4_dat4_paa4 { + nvidia,pins = "sdmmc4_dat4_paa4"; + nvidia,function = "sdmmc4"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,io-reset = <TEGRA_PIN_DISABLE>; + }; + sdmmc4_dat5_paa5 { + nvidia,pins = "sdmmc4_dat5_paa5"; + nvidia,function = "sdmmc4"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,io-reset = <TEGRA_PIN_DISABLE>; + }; + sdmmc4_dat6_paa6 { + nvidia,pins = "sdmmc4_dat6_paa6"; + nvidia,function = "sdmmc4"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,io-reset = <TEGRA_PIN_DISABLE>; + }; + sdmmc4_dat7_paa7 { + nvidia,pins = "sdmmc4_dat7_paa7"; + nvidia,function = "sdmmc4"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,io-reset = <TEGRA_PIN_DISABLE>; + }; + pbb0 { + nvidia,pins = "pbb0"; + nvidia,function = "i2s4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + cam_i2c_scl_pbb1 { + nvidia,pins = "cam_i2c_scl_pbb1"; + nvidia,function = "i2c3"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + nvidia,open-drain = <TEGRA_PIN_DISABLE>; + }; + cam_i2c_sda_pbb2 { + nvidia,pins = "cam_i2c_sda_pbb2"; + nvidia,function = "i2c3"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + nvidia,open-drain = <TEGRA_PIN_DISABLE>; + }; + pbb3 { + nvidia,pins = "pbb3"; + nvidia,function = "vgp3"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pbb4 { + nvidia,pins = "pbb4"; + nvidia,function = "vgp4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pbb5 { + nvidia,pins = "pbb5"; + nvidia,function = "vgp5"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pbb6 { + nvidia,pins = "pbb6"; + nvidia,function = "vgp6"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pbb7 { + nvidia,pins = "pbb7"; + nvidia,function = "i2s4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + cam_mclk_pcc0 { + nvidia,pins = "cam_mclk_pcc0"; + nvidia,function = "vi_alt3"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pcc1 { + nvidia,pins = "pcc1"; + nvidia,function = "i2s4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + pcc2 { + nvidia,pins = "pcc2"; + nvidia,function = "i2s4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + sdmmc4_rst_n_pcc3 { + nvidia,pins = "sdmmc4_rst_n_pcc3"; + nvidia,function = "sdmmc4"; + nvidia,pull = <TEGRA_PIN_PULL_DOWN>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,io-reset = <TEGRA_PIN_DISABLE>; + }; + sdmmc4_clk_pcc4 { + nvidia,pins = "sdmmc4_clk_pcc4"; + nvidia,function = "sdmmc4"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,io-reset = <TEGRA_PIN_DISABLE>; + }; + clk2_req_pcc5 { + nvidia,pins = "clk2_req_pcc5"; + nvidia,function = "dap"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pex_l2_rst_n_pcc6 { + nvidia,pins = "pex_l2_rst_n_pcc6"; + nvidia,function = "pcie"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pex_l2_clkreq_n_pcc7 { + nvidia,pins = "pex_l2_clkreq_n_pcc7"; + nvidia,function = "pcie"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pex_l0_prsnt_n_pdd0 { + nvidia,pins = "pex_l0_prsnt_n_pdd0"; + nvidia,function = "pcie"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pex_l0_rst_n_pdd1 { + nvidia,pins = "pex_l0_rst_n_pdd1"; + nvidia,function = "pcie"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pex_l0_clkreq_n_pdd2 { + nvidia,pins = "pex_l0_clkreq_n_pdd2"; + nvidia,function = "pcie"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pex_wake_n_pdd3 { + nvidia,pins = "pex_wake_n_pdd3"; + nvidia,function = "pcie"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pex_l1_prsnt_n_pdd4 { + nvidia,pins = "pex_l1_prsnt_n_pdd4"; + nvidia,function = "pcie"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pex_l1_rst_n_pdd5 { + nvidia,pins = "pex_l1_rst_n_pdd5"; + nvidia,function = "pcie"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pex_l1_clkreq_n_pdd6 { + nvidia,pins = "pex_l1_clkreq_n_pdd6"; + nvidia,function = "pcie"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + pex_l2_prsnt_n_pdd7 { + nvidia,pins = "pex_l2_prsnt_n_pdd7"; + nvidia,function = "pcie"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + clk3_out_pee0 { + nvidia,pins = "clk3_out_pee0"; + nvidia,function = "extperiph3"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + clk3_req_pee1 { + nvidia,pins = "clk3_req_pee1"; + nvidia,function = "dev3"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + clk1_req_pee2 { + nvidia,pins = "clk1_req_pee2"; + nvidia,function = "dap"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + }; + hdmi_cec_pee3 { + nvidia,pins = "hdmi_cec_pee3"; + nvidia,function = "cec"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,open-drain = <TEGRA_PIN_DISABLE>; + }; + owr { + nvidia,pins = "owr"; + nvidia,function = "owr"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,enable-input = <TEGRA_PIN_DISABLE>; + }; + drive_groups { + nvidia,pins = "drive_gma", + "drive_gmb", + "drive_gmc", + "drive_gmd"; + nvidia,pull-down-strength = <9>; + nvidia,pull-up-strength = <9>; + nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOWEST>; + nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOWEST>; + }; +}; + +&emc_icc_dvfs_opp_table { + /delete-node/ opp@900000000,1350; +}; + +&emc_bw_dfs_opp_table { + /delete-node/ opp@900000000; +}; diff --git a/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi new file mode 100644 index 000000000000..cbe84d25e726 --- /dev/null +++ b/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi @@ -0,0 +1,383 @@ +// SPDX-License-Identifier: GPL-2.0 + +/ { + emc_icc_dvfs_opp_table: emc-dvfs-opp-table { + compatible = "operating-points-v2"; + + opp@12750000,950 { + opp-microvolt = <950000 950000 1350000>; + opp-hz = /bits/ 64 <12750000>; + opp-supported-hw = <0x0006>; + }; + + opp@12750000,1000 { + opp-microvolt = <1000000 1000000 1350000>; + opp-hz = /bits/ 64 <12750000>; + opp-supported-hw = <0x0001>; + }; + + opp@12750000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <12750000>; + opp-supported-hw = <0x0008>; + }; + + opp@25500000,950 { + opp-microvolt = <950000 950000 1350000>; + opp-hz = /bits/ 64 <25500000>; + opp-supported-hw = <0x0006>; + }; + + opp@25500000,1000 { + opp-microvolt = <1000000 1000000 1350000>; + opp-hz = /bits/ 64 <25500000>; + opp-supported-hw = <0x0001>; + }; + + opp@25500000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <25500000>; + opp-supported-hw = <0x0008>; + }; + + opp@27000000,950 { + opp-microvolt = <950000 950000 1350000>; + opp-hz = /bits/ 64 <27000000>; + opp-supported-hw = <0x0006>; + }; + + opp@27000000,1000 { + opp-microvolt = <1000000 1000000 1350000>; + opp-hz = /bits/ 64 <27000000>; + opp-supported-hw = <0x0001>; + }; + + opp@27000000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <27000000>; + opp-supported-hw = <0x0008>; + }; + + opp@51000000,950 { + opp-microvolt = <950000 950000 1350000>; + opp-hz = /bits/ 64 <51000000>; + opp-supported-hw = <0x0006>; + }; + + opp@51000000,1000 { + opp-microvolt = <1000000 1000000 1350000>; + opp-hz = /bits/ 64 <51000000>; + opp-supported-hw = <0x0001>; + }; + + opp@51000000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <51000000>; + opp-supported-hw = <0x0008>; + }; + + opp@54000000,950 { + opp-microvolt = <950000 950000 1350000>; + opp-hz = /bits/ 64 <54000000>; + opp-supported-hw = <0x0006>; + }; + + opp@54000000,1000 { + opp-microvolt = <1000000 1000000 1350000>; + opp-hz = /bits/ 64 <54000000>; + opp-supported-hw = <0x0001>; + }; + + opp@54000000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <54000000>; + opp-supported-hw = <0x0008>; + }; + + opp@102000000,950 { + opp-microvolt = <950000 950000 1350000>; + opp-hz = /bits/ 64 <102000000>; + opp-supported-hw = <0x0006>; + }; + + opp@102000000,1000 { + opp-microvolt = <1000000 1000000 1350000>; + opp-hz = /bits/ 64 <102000000>; + opp-supported-hw = <0x0001>; + }; + + opp@102000000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <102000000>; + opp-supported-hw = <0x0008>; + }; + + opp@108000000,1000 { + opp-microvolt = <1000000 1000000 1350000>; + opp-hz = /bits/ 64 <108000000>; + opp-supported-hw = <0x0007>; + }; + + opp@108000000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <108000000>; + opp-supported-hw = <0x0008>; + }; + + opp@204000000,1000 { + opp-microvolt = <1000000 1000000 1350000>; + opp-hz = /bits/ 64 <204000000>; + opp-supported-hw = <0x0007>; + }; + + opp@204000000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <204000000>; + opp-supported-hw = <0x0008>; + }; + + opp@333500000,1000 { + opp-microvolt = <1000000 1000000 1350000>; + opp-hz = /bits/ 64 <333500000>; + opp-supported-hw = <0x0006>; + }; + + opp@333500000,1200 { + opp-microvolt = <1200000 1200000 1350000>; + opp-hz = /bits/ 64 <333500000>; + opp-supported-hw = <0x0001>; + }; + + opp@333500000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <333500000>; + opp-supported-hw = <0x0008>; + }; + + opp@375000000,1000 { + opp-microvolt = <1000000 1000000 1350000>; + opp-hz = /bits/ 64 <375000000>; + opp-supported-hw = <0x0006>; + }; + + opp@375000000,1200 { + opp-microvolt = <1200000 1200000 1350000>; + opp-hz = /bits/ 64 <375000000>; + opp-supported-hw = <0x0001>; + }; + + opp@375000000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <375000000>; + opp-supported-hw = <0x0008>; + }; + + opp@400000000,1000 { + opp-microvolt = <1000000 1000000 1350000>; + opp-hz = /bits/ 64 <400000000>; + opp-supported-hw = <0x0006>; + }; + + opp@400000000,1200 { + opp-microvolt = <1200000 1200000 1350000>; + opp-hz = /bits/ 64 <400000000>; + opp-supported-hw = <0x0001>; + }; + + opp@400000000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <400000000>; + opp-supported-hw = <0x0008>; + }; + + opp@416000000,1200 { + opp-microvolt = <1200000 1200000 1350000>; + opp-hz = /bits/ 64 <416000000>; + opp-supported-hw = <0x0007>; + }; + + opp@416000000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <416000000>; + opp-supported-hw = <0x0008>; + }; + + opp@450000000,1200 { + opp-microvolt = <1200000 1200000 1350000>; + opp-hz = /bits/ 64 <450000000>; + opp-supported-hw = <0x0007>; + }; + + opp@450000000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <450000000>; + opp-supported-hw = <0x0008>; + }; + + opp@533000000,1200 { + opp-microvolt = <1200000 1200000 1350000>; + opp-hz = /bits/ 64 <533000000>; + opp-supported-hw = <0x0007>; + }; + + opp@533000000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <533000000>; + opp-supported-hw = <0x0008>; + }; + + opp@625000000,1200 { + opp-microvolt = <1200000 1200000 1350000>; + opp-hz = /bits/ 64 <625000000>; + opp-supported-hw = <0x0006>; + }; + + opp@625000000,1250 { + opp-microvolt = <1250000 1250000 1350000>; + opp-hz = /bits/ 64 <625000000>; + opp-supported-hw = <0x0008>; + }; + + opp@667000000,1200 { + opp-microvolt = <1200000 1200000 1350000>; + opp-hz = /bits/ 64 <667000000>; + opp-supported-hw = <0x0006>; + }; + + opp@750000000,1300 { + opp-microvolt = <1300000 1300000 1350000>; + opp-hz = /bits/ 64 <750000000>; + opp-supported-hw = <0x0004>; + }; + + opp@800000000,1300 { + opp-microvolt = <1300000 1300000 1350000>; + opp-hz = /bits/ 64 <800000000>; + opp-supported-hw = <0x0004>; + }; + + opp@900000000,1350 { + opp-microvolt = <1350000 1350000 1350000>; + opp-hz = /bits/ 64 <900000000>; + opp-supported-hw = <0x0004>; + }; + }; + + emc_bw_dfs_opp_table: emc-bandwidth-opp-table { + compatible = "operating-points-v2"; + + opp@12750000 { + opp-hz = /bits/ 64 <12750000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <102000>; + }; + + opp@25500000 { + opp-hz = /bits/ 64 <25500000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <204000>; + }; + + opp@27000000 { + opp-hz = /bits/ 64 <27000000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <216000>; + }; + + opp@51000000 { + opp-hz = /bits/ 64 <51000000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <408000>; + }; + + opp@54000000 { + opp-hz = /bits/ 64 <54000000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <432000>; + }; + + opp@102000000 { + opp-hz = /bits/ 64 <102000000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <816000>; + }; + + opp@108000000 { + opp-hz = /bits/ 64 <108000000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <864000>; + }; + + opp@204000000 { + opp-hz = /bits/ 64 <204000000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <1632000>; + }; + + opp@333500000 { + opp-hz = /bits/ 64 <333500000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <2668000>; + }; + + opp@375000000 { + opp-hz = /bits/ 64 <375000000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <3000000>; + }; + + opp@400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <3200000>; + }; + + opp@416000000 { + opp-hz = /bits/ 64 <416000000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <3328000>; + }; + + opp@450000000 { + opp-hz = /bits/ 64 <450000000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <3600000>; + }; + + opp@533000000 { + opp-hz = /bits/ 64 <533000000>; + opp-supported-hw = <0x000F>; + opp-peak-kBps = <4264000>; + }; + + opp@625000000 { + opp-hz = /bits/ 64 <625000000>; + opp-supported-hw = <0x000E>; + opp-peak-kBps = <5000000>; + }; + + opp@667000000 { + opp-hz = /bits/ 64 <667000000>; + opp-supported-hw = <0x0006>; + opp-peak-kBps = <5336000>; + }; + + opp@750000000 { + opp-hz = /bits/ 64 <750000000>; + opp-supported-hw = <0x0004>; + opp-peak-kBps = <6000000>; + }; + + opp@800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-supported-hw = <0x0004>; + opp-peak-kBps = <6400000>; + }; + + opp@900000000 { + opp-hz = /bits/ 64 <900000000>; + opp-supported-hw = <0x0004>; + opp-peak-kBps = <7200000>; + }; + }; +}; diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index aeae8c092d41..44a6dbba7081 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -6,6 +6,8 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/soc/tegra-pmc.h> +#include "tegra30-peripherals-opp.dtsi" + / { compatible = "nvidia,tegra30"; interrupt-parent = <&lic>; @@ -210,6 +212,17 @@ nvidia,head = <0>; + interconnects = <&mc TEGRA30_MC_DISPLAY0A &emc>, + <&mc TEGRA30_MC_DISPLAY0B &emc>, + <&mc TEGRA30_MC_DISPLAY1B &emc>, + <&mc TEGRA30_MC_DISPLAY0C &emc>, + <&mc TEGRA30_MC_DISPLAYHC &emc>; + interconnect-names = "wina", + "winb", + "winb-vfilter", + "winc", + "cursor"; + rgb { status = "disabled"; }; @@ -229,6 +242,17 @@ nvidia,head = <1>; + interconnects = <&mc TEGRA30_MC_DISPLAY0AB &emc>, + <&mc TEGRA30_MC_DISPLAY0BB &emc>, + <&mc TEGRA30_MC_DISPLAY1BB &emc>, + <&mc TEGRA30_MC_DISPLAY0CB &emc>, + <&mc TEGRA30_MC_DISPLAYHCB &emc>; + interconnect-names = "wina", + "winb", + "winb-vfilter", + "winc", + "cursor"; + rgb { status = "disabled"; }; @@ -395,6 +419,9 @@ clock-names = "actmon", "emc"; resets = <&tegra_car TEGRA30_CLK_ACTMON>; reset-names = "actmon"; + operating-points-v2 = <&emc_bw_dfs_opp_table>; + interconnects = <&mc TEGRA30_MC_MPCORER &emc>; + interconnect-names = "cpu-read"; }; gpio: gpio@6000d000 { @@ -748,15 +775,19 @@ #iommu-cells = <1>; #reset-cells = <1>; + #interconnect-cells = <1>; }; - memory-controller@7000f400 { + emc: memory-controller@7000f400 { compatible = "nvidia,tegra30-emc"; reg = <0x7000f400 0x400>; interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA30_CLK_EMC>; nvidia,memory-controller = <&mc>; + operating-points-v2 = <&emc_icc_dvfs_opp_table>; + + #interconnect-cells = <0>; }; fuse@7000f800 { diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi index 2259d11af721..d53f9c9db8bf 100644 --- a/arch/arm/boot/dts/vfxxx.dtsi +++ b/arch/arm/boot/dts/vfxxx.dtsi @@ -95,7 +95,7 @@ status = "disabled"; }; - can0: flexcan@40020000 { + can0: can@40020000 { compatible = "fsl,vf610-flexcan"; reg = <0x40020000 0x4000>; interrupts = <58 IRQ_TYPE_LEVEL_HIGH>; @@ -293,7 +293,7 @@ status = "disabled"; }; - wdoga5: wdog@4003e000 { + wdoga5: watchdog@4003e000 { compatible = "fsl,vf610-wdt", "fsl,imx21-wdt"; reg = <0x4003e000 0x1000>; interrupts = <20 IRQ_TYPE_LEVEL_HIGH>; @@ -681,7 +681,7 @@ status = "disabled"; }; - can1: flexcan@400d4000 { + can1: can@400d4000 { compatible = "fsl,vf610-flexcan"; reg = <0x400d4000 0x4000>; interrupts = <59 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi index db3899b07992..df9ad831cf05 100644 --- a/arch/arm/boot/dts/zynq-7000.dtsi +++ b/arch/arm/boot/dts/zynq-7000.dtsi @@ -92,7 +92,7 @@ }; }; - amba: amba { + amba: axi { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts index 27cd6cb52f1b..cf70aff26c66 100644 --- a/arch/arm/boot/dts/zynq-zc702.dts +++ b/arch/arm/boot/dts/zynq-zc702.dts @@ -49,7 +49,7 @@ leds { compatible = "gpio-leds"; - ds23 { + led-ds23 { label = "ds23"; gpios = <&gpio0 10 0>; linux,default-trigger = "heartbeat"; @@ -66,6 +66,12 @@ ocm: sram@fffc0000 { compatible = "mmio-sram"; reg = <0xfffc0000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0xfffc0000 0x10000>; + ocm-sram@0 { + reg = <0x0 0x10000>; + }; }; }; diff --git a/arch/arm/boot/dts/zynq-zc770-xm011.dts b/arch/arm/boot/dts/zynq-zc770-xm011.dts index b7f65862c022..56732e8f6ca1 100644 --- a/arch/arm/boot/dts/zynq-zc770-xm011.dts +++ b/arch/arm/boot/dts/zynq-zc770-xm011.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Xilinx ZC770 XM013 board DTS + * Xilinx ZC770 XM011 board DTS * * Copyright (C) 2013-2018 Xilinx, Inc. */ diff --git a/arch/arm/boot/dts/zynq-zc770-xm013.dts b/arch/arm/boot/dts/zynq-zc770-xm013.dts index 4ae2c85df3a0..38d96adc870c 100644 --- a/arch/arm/boot/dts/zynq-zc770-xm013.dts +++ b/arch/arm/boot/dts/zynq-zc770-xm013.dts @@ -63,13 +63,12 @@ num-cs = <4>; is-decoded-cs = <0>; eeprom: eeprom@2 { - at25,byte-len = <8192>; - at25,addr-mode = <2>; - at25,page-size = <32>; - compatible = "atmel,at25"; reg = <2>; spi-max-frequency = <1000000>; + size = <8192>; + address-width = <16>; + pagesize = <32>; }; }; diff --git a/arch/arm/boot/dts/zynq-zturn-common.dtsi b/arch/arm/boot/dts/zynq-zturn-common.dtsi new file mode 100644 index 000000000000..bf5d1c4568b0 --- /dev/null +++ b/arch/arm/boot/dts/zynq-zturn-common.dtsi @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2015 Andrea Merello <adnrea.merello@gmail.com> + * Copyright (C) 2017 Alexander Graf <agraf@suse.de> + * + * Based on zynq-zed.dts which is: + * Copyright (C) 2011 - 2014 Xilinx + * Copyright (C) 2012 National Instruments Corp. + * + */ + +/dts-v1/; +/include/ "zynq-7000.dtsi" + +/ { + compatible = "xlnx,zynq-7000"; + + aliases { + ethernet0 = &gem0; + serial0 = &uart1; + serial1 = &uart0; + mmc0 = &sdhci0; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x40000000>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-leds { + compatible = "gpio-leds"; + usr-led1 { + label = "usr-led1"; + gpios = <&gpio0 0x0 0x1>; + default-state = "off"; + }; + + usr-led2 { + label = "usr-led2"; + gpios = <&gpio0 0x9 0x1>; + default-state = "off"; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + autorepeat; + K1 { + label = "K1"; + gpios = <&gpio0 0x32 0x1>; + linux,code = <0x66>; + wakeup-source; + autorepeat; + }; + }; +}; + +&clkc { + ps-clk-frequency = <33333333>; +}; + +&gem0 { + status = "okay"; + phy-mode = "rgmii-id"; + phy-handle = <ðernet_phy>; + + ethernet_phy: ethernet-phy@0 { + }; +}; + +&sdhci0 { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&can0 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + + stlm75@49 { + status = "okay"; + compatible = "lm75"; + reg = <0x49>; + }; + + accelerometer@53 { + compatible = "adi,adxl345"; + reg = <0x53>; + interrupt-parent = <&intc>; + interrupts = <0x0 0x1e 0x4>; + }; +}; diff --git a/arch/arm/boot/dts/zynq-zturn-v5.dts b/arch/arm/boot/dts/zynq-zturn-v5.dts new file mode 100644 index 000000000000..536632a09a25 --- /dev/null +++ b/arch/arm/boot/dts/zynq-zturn-v5.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 + +/dts-v1/; +/include/ "zynq-zturn-common.dtsi" + +/ { + model = "Zynq Z-Turn MYIR Board V5"; + compatible = "myir,zynq-zturn-v5", "xlnx,zynq-7000"; +}; + +&gem0 { + ethernet_phy: ethernet-phy@0 { + reg = <0x3>; + }; +}; diff --git a/arch/arm/boot/dts/zynq-zturn.dts b/arch/arm/boot/dts/zynq-zturn.dts index 5ec616ebca08..620b24a25e06 100644 --- a/arch/arm/boot/dts/zynq-zturn.dts +++ b/arch/arm/boot/dts/zynq-zturn.dts @@ -1,114 +1,15 @@ // SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2015 Andrea Merello <adnrea.merello@gmail.com> - * Copyright (C) 2017 Alexander Graf <agraf@suse.de> - * - * Based on zynq-zed.dts which is: - * Copyright (C) 2011 - 2014 Xilinx - * Copyright (C) 2012 National Instruments Corp. - * - */ /dts-v1/; -/include/ "zynq-7000.dtsi" +/include/ "zynq-zturn-common.dtsi" / { model = "Zynq Z-Turn MYIR Board"; compatible = "myir,zynq-zturn", "xlnx,zynq-7000"; - - aliases { - ethernet0 = &gem0; - serial0 = &uart1; - serial1 = &uart0; - mmc0 = &sdhci0; - }; - - memory@0 { - device_type = "memory"; - reg = <0x0 0x40000000>; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - gpio-leds { - compatible = "gpio-leds"; - usr-led1 { - label = "usr-led1"; - gpios = <&gpio0 0x0 0x1>; - default-state = "off"; - }; - - usr-led2 { - label = "usr-led2"; - gpios = <&gpio0 0x9 0x1>; - default-state = "off"; - }; - }; - - gpio-keys { - compatible = "gpio-keys"; - autorepeat; - K1 { - label = "K1"; - gpios = <&gpio0 0x32 0x1>; - linux,code = <0x66>; - wakeup-source; - autorepeat; - }; - }; -}; - -&clkc { - ps-clk-frequency = <33333333>; }; &gem0 { - status = "okay"; - phy-mode = "rgmii-id"; - phy-handle = <ðernet_phy>; - ethernet_phy: ethernet-phy@0 { reg = <0x0>; }; }; - -&sdhci0 { - status = "okay"; -}; - -&uart0 { - status = "okay"; -}; - -&uart1 { - status = "okay"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; - -&can0 { - status = "okay"; -}; - -&i2c0 { - status = "okay"; - clock-frequency = <400000>; - - stlm75@49 { - status = "okay"; - compatible = "lm75"; - reg = <0x49>; - }; - - accelerometer@53 { - compatible = "adi,adxl345", "adxl345", "adi,adxl34x", "adxl34x"; - reg = <0x53>; - interrupt-parent = <&intc>; - interrupts = <0x0 0x1e 0x4>; - }; -}; diff --git a/arch/arm/boot/dts/zynq-zybo-z7.dts b/arch/arm/boot/dts/zynq-zybo-z7.dts index 357b78a5c11b..7b87e10d3953 100644 --- a/arch/arm/boot/dts/zynq-zybo-z7.dts +++ b/arch/arm/boot/dts/zynq-zybo-z7.dts @@ -25,7 +25,7 @@ gpio-leds { compatible = "gpio-leds"; - ld4 { + led-ld4 { label = "zynq-zybo-z7:green:ld4"; gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; }; diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig index 4a0ba2ae1a25..c0c219d53b24 100644 --- a/arch/arm/configs/at91_dt_defconfig +++ b/arch/arm/configs/at91_dt_defconfig @@ -124,15 +124,19 @@ CONFIG_MFD_ATMEL_HLCDC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_SUPPORT_FILTER=y +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_VIDEO_ATMEL_ISI=y +CONFIG_VIDEO_OV2640=m +CONFIG_VIDEO_MT9V032=m CONFIG_DRM=y CONFIG_DRM_ATMEL_HLCDC=y CONFIG_DRM_PANEL_SIMPLE=y CONFIG_FB_ATMEL=y CONFIG_BACKLIGHT_ATMEL_LCDC=y -# CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_PWM=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig index 2f7acde2d921..502a9d870ca4 100644 --- a/arch/arm/configs/cm_x300_defconfig +++ b/arch/arm/configs/cm_x300_defconfig @@ -87,7 +87,6 @@ CONFIG_FB=y CONFIG_FB_PXA=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_TDO24M=y -# CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_DA903X=m CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y diff --git a/arch/arm/configs/colibri_pxa300_defconfig b/arch/arm/configs/colibri_pxa300_defconfig index 0dae3b185284..26e5a67f8e2d 100644 --- a/arch/arm/configs/colibri_pxa300_defconfig +++ b/arch/arm/configs/colibri_pxa300_defconfig @@ -34,7 +34,6 @@ CONFIG_FB=y CONFIG_FB_PXA=y # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_GENERIC is not set # CONFIG_VGA_CONSOLE is not set CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index cf82c9d23a08..513f56b3c059 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -107,6 +107,8 @@ CONFIG_MD=y CONFIG_BLK_DEV_DM=y CONFIG_DM_CRYPT=m CONFIG_NETDEVICES=y +CONFIG_NET_VENDOR_ASIX=y +CONFIG_SPI_AX88796C=y CONFIG_SMSC911X=y CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=y @@ -125,7 +127,7 @@ CONFIG_KEYBOARD_CROS_EC=y # CONFIG_MOUSE_PS2 is not set CONFIG_MOUSE_CYAPA=y CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_ATMEL_MXT=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=m CONFIG_TOUCHSCREEN_MMS114=y CONFIG_INPUT_MISC=y CONFIG_INPUT_MAX77693_HAPTIC=y @@ -175,6 +177,8 @@ CONFIG_MFD_MAX77693=y CONFIG_MFD_MAX8997=y CONFIG_MFD_MAX8998=y CONFIG_MFD_SEC_CORE=y +CONFIG_MFD_STMPE=y +CONFIG_STMPE_I2C=y CONFIG_MFD_TPS65090=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y @@ -245,6 +249,7 @@ CONFIG_SND_SOC_SMDK_WM8994_PCM=y CONFIG_SND_SOC_SNOW=y CONFIG_SND_SOC_ODROID=y CONFIG_SND_SOC_ARNDALE=y +CONFIG_SND_SOC_SAMSUNG_MIDAS_WM1811=y CONFIG_SND_SIMPLE_CARD=y CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y @@ -319,6 +324,7 @@ CONFIG_EXTCON_MAX77693=y CONFIG_EXTCON_MAX8997=y CONFIG_IIO=y CONFIG_EXYNOS_ADC=y +CONFIG_STMPE_ADC=y CONFIG_CM36651=y CONFIG_AK8975=y CONFIG_PWM=y diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig index 9f079be2b84b..069f60ffdcd8 100644 --- a/arch/arm/configs/jornada720_defconfig +++ b/arch/arm/configs/jornada720_defconfig @@ -48,7 +48,6 @@ CONFIG_FB=y CONFIG_FB_S1D13XXX=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_GENERIC is not set # CONFIG_VGA_CONSOLE is not set CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y diff --git a/arch/arm/configs/magician_defconfig b/arch/arm/configs/magician_defconfig index d2e684f6565a..b4670d42f378 100644 --- a/arch/arm/configs/magician_defconfig +++ b/arch/arm/configs/magician_defconfig @@ -95,7 +95,6 @@ CONFIG_FB_PXA_OVERLAY=y CONFIG_FB_W100=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_PWM=y # CONFIG_VGA_CONSOLE is not set CONFIG_FRAMEBUFFER_CONSOLE=y diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig index 301f29a1fcc3..898490aaa39e 100644 --- a/arch/arm/configs/mini2440_defconfig +++ b/arch/arm/configs/mini2440_defconfig @@ -158,7 +158,6 @@ CONFIG_FB_S3C2410=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_PLATFORM=y CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_PWM=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index a611b0c1e540..c5f25710fedc 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -109,6 +109,7 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y CONFIG_CPUFREQ_DT=y CONFIG_ARM_IMX6Q_CPUFREQ=y +CONFIG_ARM_SCMI_CPUFREQ=y CONFIG_ARM_RASPBERRYPI_CPUFREQ=y CONFIG_QORIQ_CPUFREQ=y CONFIG_CPU_IDLE=y @@ -117,6 +118,7 @@ CONFIG_ARM_ZYNQ_CPUIDLE=y CONFIG_ARM_EXYNOS_CPUIDLE=y CONFIG_ARM_TEGRA_CPUIDLE=y CONFIG_KERNEL_MODE_NEON=y +CONFIG_ARM_SCMI_PROTOCOL=y CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_TRUSTED_FOUNDATIONS=y CONFIG_BCM47XX_NVRAM=y @@ -154,6 +156,7 @@ CONFIG_INET6_IPCOMP=m CONFIG_IPV6_MIP6=m CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_NET_SWITCHDEV=y CONFIG_NET_DSA=m CONFIG_CAN=y CONFIG_CAN_AT91=m @@ -243,6 +246,8 @@ CONFIG_SATA_HIGHBANK=y CONFIG_SATA_MV=y CONFIG_SATA_RCAR=y CONFIG_NETDEVICES=y +CONFIG_NET_VENDOR_ASIX=y +CONFIG_SPI_AX88796C=m CONFIG_VIRTIO_NET=y CONFIG_B53_SPI_DRIVER=m CONFIG_B53_MDIO_DRIVER=m @@ -270,9 +275,12 @@ CONFIG_SNI_AVE=y CONFIG_STMMAC_ETH=y CONFIG_DWMAC_DWC_QOS_ETH=y CONFIG_TI_CPSW=y +CONFIG_TI_CPSW_SWITCHDEV=y +CONFIG_TI_CPTS=y CONFIG_XILINX_EMACLITE=y CONFIG_BROADCOM_PHY=y CONFIG_ICPLUS_PHY=y +CONFIG_DP83867_PHY=y CONFIG_MARVELL_PHY=y CONFIG_MICREL_PHY=y CONFIG_AT803X_PHY=y @@ -436,6 +444,7 @@ CONFIG_SPI_TEGRA20_SLINK=y CONFIG_SPI_XILINX=y CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y +CONFIG_PTP_1588_CLOCK=y CONFIG_PINCTRL_AS3722=y CONFIG_PINCTRL_RZA2=y CONFIG_PINCTRL_STMFX=y @@ -488,6 +497,7 @@ CONFIG_CHARGER_MAX77693=m CONFIG_CHARGER_MAX8997=m CONFIG_CHARGER_MAX8998=m CONFIG_CHARGER_TPS65090=y +CONFIG_SENSORS_ARM_SCMI=y CONFIG_SENSORS_ASPEED=m CONFIG_SENSORS_IIO_HWMON=y CONFIG_SENSORS_LM90=y @@ -557,6 +567,7 @@ CONFIG_MFD_RK808=y CONFIG_MFD_RN5T618=y CONFIG_MFD_SEC_CORE=y CONFIG_MFD_STMPE=y +CONFIG_STMPE_I2C=y CONFIG_MFD_PALMAS=y CONFIG_MFD_TPS65090=y CONFIG_MFD_TPS65217=y @@ -738,11 +749,14 @@ CONFIG_SND_SOC_SMDK_WM8994_PCM=m CONFIG_SND_SOC_SNOW=m CONFIG_SND_SOC_ODROID=m CONFIG_SND_SOC_ARNDALE=m +CONFIG_SND_SOC_SAMSUNG_MIDAS_WM1811=m CONFIG_SND_SOC_SH4_FSI=m CONFIG_SND_SOC_RCAR=m CONFIG_SND_SOC_STI=m CONFIG_SND_SOC_STM32_SAI=m CONFIG_SND_SOC_STM32_I2S=m +CONFIG_SND_SOC_STM32_SPDIFRX=m +CONFIG_SND_SOC_STM32_DFSDM=m CONFIG_SND_SUN4I_CODEC=m CONFIG_SND_SOC_TEGRA=m CONFIG_SND_SOC_TEGRA20_I2S=m @@ -770,7 +784,7 @@ CONFIG_USB_XHCI_TEGRA=m CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_STI=y CONFIG_USB_EHCI_TEGRA=y -CONFIG_USB_EHCI_EXYNOS=y +CONFIG_USB_EHCI_EXYNOS=m CONFIG_USB_EHCI_MV=m CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_STI=y @@ -829,6 +843,8 @@ CONFIG_USB_CONFIGFS_F_HID=y CONFIG_USB_CONFIGFS_F_UVC=y CONFIG_USB_CONFIGFS_F_PRINTER=y CONFIG_USB_ETH=m +CONFIG_TYPEC=m +CONFIG_TYPEC_STUSB160X=m CONFIG_MMC=y CONFIG_MMC_BLOCK_MINORS=16 CONFIG_MMC_ARMMMCI=y @@ -959,6 +975,7 @@ CONFIG_CROS_EC_I2C=m CONFIG_CROS_EC_SPI=m CONFIG_COMMON_CLK_MAX77686=y CONFIG_COMMON_CLK_RK808=m +CONFIG_COMMON_CLK_SCMI=y CONFIG_COMMON_CLK_S2MPS11=m CONFIG_CLK_RASPBERRYPI=y CONFIG_COMMON_CLK_QCOM=y @@ -1024,6 +1041,7 @@ CONFIG_AT91_SAMA5D2_ADC=m CONFIG_BERLIN2_ADC=m CONFIG_CPCAP_ADC=m CONFIG_EXYNOS_ADC=m +CONFIG_STMPE_ADC=m CONFIG_MESON_SARADC=m CONFIG_ROCKCHIP_SARADC=m CONFIG_STM32_ADC_CORE=m @@ -1096,6 +1114,9 @@ CONFIG_FSI_MASTER_ASPEED=m CONFIG_FSI_SCOM=m CONFIG_FSI_SBEFIFO=m CONFIG_FSI_OCC=m +CONFIG_COUNTER=m +CONFIG_STM32_TIMER_CNT=m +CONFIG_STM32_LPTIMER_CNT=m CONFIG_EXT4_FS=y CONFIG_AUTOFS4_FS=y CONFIG_MSDOS_FS=y @@ -1133,6 +1154,9 @@ CONFIG_CRYPTO_DEV_ATMEL_AES=m CONFIG_CRYPTO_DEV_ATMEL_TDES=m CONFIG_CRYPTO_DEV_ATMEL_SHA=m CONFIG_CRYPTO_DEV_ROCKCHIP=m +CONFIG_CRYPTO_DEV_STM32_CRC=m +CONFIG_CRYPTO_DEV_STM32_HASH=m +CONFIG_CRYPTO_DEV_STM32_CRYP=m CONFIG_CMA_SIZE_MBYTES=64 CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 58df9fd79a76..b515c31f0ab7 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -279,6 +279,7 @@ CONFIG_SERIAL_OMAP_CONSOLE=y CONFIG_SERIAL_DEV_BUS=y CONFIG_I2C_CHARDEV=y CONFIG_SPI=y +CONFIG_SPI_GPIO=m CONFIG_SPI_OMAP24XX=y CONFIG_SPI_TI_QSPI=m CONFIG_HSI=m @@ -296,7 +297,6 @@ CONFIG_GPIO_TWL4030=y CONFIG_W1=m CONFIG_HDQ_MASTER_OMAP=m CONFIG_W1_SLAVE_DS250X=m -CONFIG_POWER_AVS=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_GPIO=y CONFIG_BATTERY_BQ27XXX=m @@ -313,6 +313,7 @@ CONFIG_THERMAL_GOV_FAIR_SHARE=y CONFIG_THERMAL_GOV_USER_SPACE=y CONFIG_CPU_THERMAL=y CONFIG_TI_THERMAL=y +CONFIG_OMAP3_THERMAL=y CONFIG_OMAP4_THERMAL=y CONFIG_OMAP5_THERMAL=y CONFIG_DRA752_THERMAL=y @@ -388,7 +389,6 @@ CONFIG_FB_TILEBLITTING=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_PLATFORM=y CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BACKLIGHT_GENERIC=m CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_PANDORA=m CONFIG_BACKLIGHT_GPIO=m @@ -523,6 +523,8 @@ CONFIG_TI_AM335X_ADC=m CONFIG_TWL4030_MADC=m CONFIG_SENSORS_ISL29028=m CONFIG_BMP280=m +CONFIG_KXCJK1013=m +CONFIG_AK8975=m CONFIG_PWM=y CONFIG_PWM_OMAP_DMTIMER=m CONFIG_PWM_TIECAP=m @@ -535,6 +537,8 @@ CONFIG_PHY_DM816X_USB=m CONFIG_OMAP_USB2=m CONFIG_TI_PIPE3=y CONFIG_TWL4030_USB=m +CONFIG_COUNTER=m +CONFIG_TI_EQEP=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_EXT4_FS_SECURITY=y diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig index 06bbc7a59b60..f0c34017f2aa 100644 --- a/arch/arm/configs/pxa3xx_defconfig +++ b/arch/arm/configs/pxa3xx_defconfig @@ -74,7 +74,6 @@ CONFIG_FB_PXA=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_TDO24M=y CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_DA903X=y # CONFIG_VGA_CONSOLE is not set CONFIG_FRAMEBUFFER_CONSOLE=y diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig index c882167e1496..d6733e745b80 100644 --- a/arch/arm/configs/qcom_defconfig +++ b/arch/arm/configs/qcom_defconfig @@ -159,7 +159,6 @@ CONFIG_FB=y CONFIG_FRAMEBUFFER_CONSOLE=y # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_LM3630A=y CONFIG_BACKLIGHT_LP855X=y CONFIG_SOUND=y diff --git a/arch/arm/configs/sama5_defconfig b/arch/arm/configs/sama5_defconfig index 037d3a718a60..5f6297e6c549 100644 --- a/arch/arm/configs/sama5_defconfig +++ b/arch/arm/configs/sama5_defconfig @@ -153,15 +153,23 @@ CONFIG_REGULATOR_ACT8945A=y CONFIG_REGULATOR_MCP16502=m CONFIG_REGULATOR_PWM=m CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_SUPPORT_FILTER=y +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_ATMEL_ISC=y CONFIG_VIDEO_ATMEL_ISI=y +CONFIG_VIDEO_OV2640=m +CONFIG_VIDEO_OV5640=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OV7740=m +CONFIG_VIDEO_MT9V032=m CONFIG_DRM=y CONFIG_DRM_ATMEL_HLCDC=y CONFIG_DRM_PANEL_SIMPLE=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_PWM=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_SOUND=y diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index 4a161b3c35b9..01a6ebdf033a 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -179,22 +179,22 @@ CONFIG_STAGING=y CONFIG_STAGING_BOARD=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_ARCH_EMEV2=y +CONFIG_ARCH_R8A7794=y +CONFIG_ARCH_R8A7779=y +CONFIG_ARCH_R8A7790=y +CONFIG_ARCH_R8A7778=y +CONFIG_ARCH_R8A7793=y +CONFIG_ARCH_R8A7791=y +CONFIG_ARCH_R8A7792=y +CONFIG_ARCH_R8A7740=y +CONFIG_ARCH_R8A73A4=y CONFIG_ARCH_R7S72100=y CONFIG_ARCH_R7S9210=y -CONFIG_ARCH_R8A73A4=y -CONFIG_ARCH_R8A7740=y +CONFIG_ARCH_R8A77470=y +CONFIG_ARCH_R8A7745=y CONFIG_ARCH_R8A7742=y CONFIG_ARCH_R8A7743=y CONFIG_ARCH_R8A7744=y -CONFIG_ARCH_R8A7745=y -CONFIG_ARCH_R8A77470=y -CONFIG_ARCH_R8A7778=y -CONFIG_ARCH_R8A7779=y -CONFIG_ARCH_R8A7790=y -CONFIG_ARCH_R8A7791=y -CONFIG_ARCH_R8A7792=y -CONFIG_ARCH_R8A7793=y -CONFIG_ARCH_R8A7794=y CONFIG_ARCH_R9A06G032=y CONFIG_ARCH_SH73A0=y CONFIG_IIO=y diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index 244126172fd6..a60c134c5e04 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig @@ -51,6 +51,7 @@ CONFIG_STMMAC_ETH=y # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set CONFIG_MICREL_PHY=y +CONFIG_REALTEK_PHY=y # CONFIG_WLAN is not set CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_SUN4I_LRADC=y @@ -111,7 +112,6 @@ CONFIG_DRM_SIMPLE_BRIDGE=y CONFIG_DRM_LIMA=y CONFIG_FB_SIMPLE=y CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_PWM=y CONFIG_SOUND=y CONFIG_SND=y diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index fff5fae0db30..74739a52a8ad 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig @@ -205,7 +205,6 @@ CONFIG_DRM_PANEL_SIMPLE=y CONFIG_DRM_LVDS_CODEC=y # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_PWM=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 28dd7cf56048..bcedfe1422aa 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -12,7 +12,6 @@ CONFIG_ARM_APPENDED_DTB=y CONFIG_ARM_ATAG_DTB_COMPAT=y CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8" CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPUFREQ_DT=y CONFIG_CPU_IDLE=y @@ -60,6 +59,7 @@ CONFIG_KEYBOARD_TC3589X=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ATMEL_MXT=y CONFIG_TOUCHSCREEN_BU21013=y +CONFIG_TOUCHSCREEN_CY8CTMA140=y CONFIG_INPUT_MISC=y CONFIG_INPUT_AB8500_PONKEY=y CONFIG_INPUT_GPIO_VIBRA=y @@ -88,11 +88,13 @@ CONFIG_REGULATOR_GPIO=y CONFIG_DRM=y CONFIG_DRM_PANEL_NOVATEK_NT35510=y CONFIG_DRM_PANEL_SAMSUNG_S6D16D0=y +CONFIG_DRM_PANEL_SAMSUNG_S6E63M0=y +CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_DSI=y CONFIG_DRM_PANEL_SONY_ACX424AKP=y CONFIG_DRM_LIMA=y CONFIG_DRM_MCDE=y CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BACKLIGHT_GENERIC=m +CONFIG_BACKLIGHT_KTD253=y CONFIG_BACKLIGHT_GPIO=y CONFIG_LOGO=y CONFIG_SOUND=y @@ -100,7 +102,6 @@ CONFIG_SND=y CONFIG_SND_SOC=y CONFIG_SND_SOC_UX500=y CONFIG_SND_SOC_UX500_MACH_MOP500=y -CONFIG_USB=y CONFIG_USB_MUSB_HDRC=y CONFIG_USB_MUSB_UX500=y CONFIG_MUSB_PIO_ONLY=y @@ -113,6 +114,7 @@ CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_LM3530=y CONFIG_LEDS_GPIO=y +CONFIG_LEDS_LP55XX_COMMON=y CONFIG_LEDS_LP5521=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y @@ -153,8 +155,8 @@ CONFIG_CRYPTO_DEV_UX500_HASH=y CONFIG_CRYPTO_DEV_UX500_DEBUG=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y CONFIG_DEBUG_KERNEL=y # CONFIG_SCHED_DEBUG is not set # CONFIG_FTRACE is not set diff --git a/arch/arm/crypto/chacha-glue.c b/arch/arm/crypto/chacha-glue.c index 7b5cf8430c6d..cdde8fd01f8f 100644 --- a/arch/arm/crypto/chacha-glue.c +++ b/arch/arm/crypto/chacha-glue.c @@ -60,6 +60,7 @@ static void chacha_doneon(u32 *state, u8 *dst, const u8 *src, chacha_block_xor_neon(state, d, s, nrounds); if (d != dst) memcpy(dst, buf, bytes); + state[12]++; } } diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 4a0848aef207..03657ff8fbe3 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -2,7 +2,6 @@ generic-y += early_ioremap.h generic-y += extable.h generic-y += flat.h -generic-y += local64.h generic-y += parport.h generated-y += mach-types.h diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index feac2c8b86f2..6ed30421f697 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -259,7 +259,7 @@ */ #define ALT_UP(instr...) \ .pushsection ".alt.smp.init", "a" ;\ - .long 9998b ;\ + .long 9998b - . ;\ 9997: instr ;\ .if . - 9997b == 2 ;\ nop ;\ @@ -270,7 +270,7 @@ .popsection #define ALT_UP_B(label) \ .pushsection ".alt.smp.init", "a" ;\ - .long 9998b ;\ + .long 9998b - . ;\ W(b) . + (label - 9998b) ;\ .popsection #else @@ -494,4 +494,88 @@ THUMB( orr \reg , \reg , #PSR_T_BIT ) #define _ASM_NOKPROBE(entry) #endif + .macro __adldst_l, op, reg, sym, tmp, c + .if __LINUX_ARM_ARCH__ < 7 + ldr\c \tmp, .La\@ + .subsection 1 + .align 2 +.La\@: .long \sym - .Lpc\@ + .previous + .else + .ifnb \c + THUMB( ittt \c ) + .endif + movw\c \tmp, #:lower16:\sym - .Lpc\@ + movt\c \tmp, #:upper16:\sym - .Lpc\@ + .endif + +#ifndef CONFIG_THUMB2_KERNEL + .set .Lpc\@, . + 8 // PC bias + .ifc \op, add + add\c \reg, \tmp, pc + .else + \op\c \reg, [pc, \tmp] + .endif +#else +.Lb\@: add\c \tmp, \tmp, pc + /* + * In Thumb-2 builds, the PC bias depends on whether we are currently + * emitting into a .arm or a .thumb section. The size of the add opcode + * above will be 2 bytes when emitting in Thumb mode and 4 bytes when + * emitting in ARM mode, so let's use this to account for the bias. + */ + .set .Lpc\@, . + (. - .Lb\@) + + .ifnc \op, add + \op\c \reg, [\tmp] + .endif +#endif + .endm + + /* + * mov_l - move a constant value or [relocated] address into a register + */ + .macro mov_l, dst:req, imm:req + .if __LINUX_ARM_ARCH__ < 7 + ldr \dst, =\imm + .else + movw \dst, #:lower16:\imm + movt \dst, #:upper16:\imm + .endif + .endm + + /* + * adr_l - adr pseudo-op with unlimited range + * + * @dst: destination register + * @sym: name of the symbol + * @cond: conditional opcode suffix + */ + .macro adr_l, dst:req, sym:req, cond + __adldst_l add, \dst, \sym, \dst, \cond + .endm + + /* + * ldr_l - ldr <literal> pseudo-op with unlimited range + * + * @dst: destination register + * @sym: name of the symbol + * @cond: conditional opcode suffix + */ + .macro ldr_l, dst:req, sym:req, cond + __adldst_l ldr, \dst, \sym, \dst, \cond + .endm + + /* + * str_l - str <literal> pseudo-op with unlimited range + * + * @src: source register + * @sym: name of the symbol + * @tmp: mandatory scratch register + * @cond: conditional opcode suffix + */ + .macro str_l, src:req, sym:req, tmp:req, cond + __adldst_l str, \src, \sym, \tmp, \cond + .endm + #endif /* __ASM_ASSEMBLER_H__ */ diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h index 898e9c78a7e7..595e538f5bfb 100644 --- a/arch/arm/include/asm/div64.h +++ b/arch/arm/include/asm/div64.h @@ -21,29 +21,20 @@ * assembly implementation with completely non standard calling convention * for arguments and results (beware). */ - -#ifdef __ARMEB__ -#define __xh "r0" -#define __xl "r1" -#else -#define __xl "r0" -#define __xh "r1" -#endif - static inline uint32_t __div64_32(uint64_t *n, uint32_t base) { register unsigned int __base asm("r4") = base; register unsigned long long __n asm("r0") = *n; register unsigned long long __res asm("r2"); - register unsigned int __rem asm(__xh); - asm( __asmeq("%0", __xh) + unsigned int __rem; + asm( __asmeq("%0", "r0") __asmeq("%1", "r2") - __asmeq("%2", "r0") - __asmeq("%3", "r4") + __asmeq("%2", "r4") "bl __do_div64" - : "=r" (__rem), "=r" (__res) - : "r" (__n), "r" (__base) + : "+r" (__n), "=r" (__res) + : "r" (__base) : "ip", "lr", "cc"); + __rem = __n >> 32; *n = __res; return __rem; } diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h index 3ee4f4381985..9de7ab2ce05d 100644 --- a/arch/arm/include/asm/efi.h +++ b/arch/arm/include/asm/efi.h @@ -66,24 +66,17 @@ static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) #define MAX_UNCOMP_KERNEL_SIZE SZ_32M /* - * phys-to-virt patching requires that the physical to virtual offset fits - * into the immediate field of an add/sub instruction, which comes down to the - * 24 least significant bits being zero, and so the offset should be a multiple - * of 16 MB. Since PAGE_OFFSET itself is a multiple of 16 MB, the physical - * base should be aligned to 16 MB as well. + * phys-to-virt patching requires that the physical to virtual offset is a + * multiple of 2 MiB. However, using an alignment smaller than TEXT_OFFSET + * here throws off the memory allocation logic, so let's use the lowest power + * of two greater than 2 MiB and greater than TEXT_OFFSET. */ -#define EFI_PHYS_ALIGN SZ_16M - -/* on ARM, the FDT should be located in a lowmem region */ -static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr) -{ - return round_down(image_addr, EFI_PHYS_ALIGN) + SZ_512M; -} +#define EFI_PHYS_ALIGN max(UL(SZ_2M), roundup_pow_of_two(TEXT_OFFSET)) /* on ARM, the initrd should be loaded in a lowmem region */ static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr) { - return round_down(image_addr, EFI_PHYS_ALIGN) + SZ_512M; + return round_down(image_addr, SZ_4M) + SZ_512M; } struct efi_arm_entry_state { @@ -93,4 +86,9 @@ struct efi_arm_entry_state { u32 sctlr_after_ebs; }; +static inline void efi_capsule_flush_cache_range(void *addr, int size) +{ + __cpuc_flush_dcache_area(addr, size); +} + #endif /* _ASM_ARM_EFI_H */ diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index 61941f369861..b8102a6ddf16 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -51,6 +51,7 @@ typedef struct user_fp elf_fpregset_t; #define R_ARM_NONE 0 #define R_ARM_PC24 1 #define R_ARM_ABS32 2 +#define R_ARM_REL32 3 #define R_ARM_CALL 28 #define R_ARM_JUMP24 29 #define R_ARM_TARGET1 38 @@ -58,11 +59,15 @@ typedef struct user_fp elf_fpregset_t; #define R_ARM_PREL31 42 #define R_ARM_MOVW_ABS_NC 43 #define R_ARM_MOVT_ABS 44 +#define R_ARM_MOVW_PREL_NC 45 +#define R_ARM_MOVT_PREL 46 #define R_ARM_THM_CALL 10 #define R_ARM_THM_JUMP24 30 #define R_ARM_THM_MOVW_ABS_NC 47 #define R_ARM_THM_MOVT_ABS 48 +#define R_ARM_THM_MOVW_PREL_NC 49 +#define R_ARM_THM_MOVT_PREL 50 /* * These are used to set parameters in the core dumps. diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h index c279a8a463a2..707068f852c2 100644 --- a/arch/arm/include/asm/fixmap.h +++ b/arch/arm/include/asm/fixmap.h @@ -2,7 +2,7 @@ #ifndef _ASM_FIXMAP_H #define _ASM_FIXMAP_H -#define FIXADDR_START 0xffc00000UL +#define FIXADDR_START 0xffc80000UL #define FIXADDR_END 0xfff00000UL #define FIXADDR_TOP (FIXADDR_END - PAGE_SIZE) diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index ab2b654084fa..fc748122f1e0 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -441,7 +441,6 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr); #define ARCH_HAS_VALID_PHYS_ADDR_RANGE extern int valid_phys_addr_range(phys_addr_t addr, size_t size); extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); -extern int devmem_is_allowed(unsigned long pfn); #endif /* diff --git a/arch/arm/include/asm/kasan.h b/arch/arm/include/asm/kasan.h new file mode 100644 index 000000000000..303c35df3135 --- /dev/null +++ b/arch/arm/include/asm/kasan.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * arch/arm/include/asm/kasan.h + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com> + * + */ + +#ifndef __ASM_KASAN_H +#define __ASM_KASAN_H + +#ifdef CONFIG_KASAN + +#include <asm/kasan_def.h> + +#define KASAN_SHADOW_SCALE_SHIFT 3 + +/* + * The compiler uses a shadow offset assuming that addresses start + * from 0. Kernel addresses don't start from 0, so shadow + * for kernel really starts from 'compiler's shadow offset' + + * ('kernel address space start' >> KASAN_SHADOW_SCALE_SHIFT) + */ + +asmlinkage void kasan_early_init(void); +extern void kasan_init(void); + +#else +static inline void kasan_init(void) { } +#endif + +#endif diff --git a/arch/arm/include/asm/kasan_def.h b/arch/arm/include/asm/kasan_def.h new file mode 100644 index 000000000000..5739605aa7cf --- /dev/null +++ b/arch/arm/include/asm/kasan_def.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * arch/arm/include/asm/kasan_def.h + * + * Copyright (c) 2018 Huawei Technologies Co., Ltd. + * + * Author: Abbott Liu <liuwenliang@huawei.com> + */ + +#ifndef __ASM_KASAN_DEF_H +#define __ASM_KASAN_DEF_H + +#ifdef CONFIG_KASAN + +/* + * Define KASAN_SHADOW_OFFSET,KASAN_SHADOW_START and KASAN_SHADOW_END for + * the Arm kernel address sanitizer. We are "stealing" lowmem (the 4GB + * addressable by a 32bit architecture) out of the virtual address + * space to use as shadow memory for KASan as follows: + * + * +----+ 0xffffffff + * | | \ + * | | |-> Static kernel image (vmlinux) BSS and page table + * | |/ + * +----+ PAGE_OFFSET + * | | \ + * | | |-> Loadable kernel modules virtual address space area + * | |/ + * +----+ MODULES_VADDR = KASAN_SHADOW_END + * | | \ + * | | |-> The shadow area of kernel virtual address. + * | |/ + * +----+-> TASK_SIZE (start of kernel space) = KASAN_SHADOW_START the + * | |\ shadow address of MODULES_VADDR + * | | | + * | | | + * | | |-> The user space area in lowmem. The kernel address + * | | | sanitizer do not use this space, nor does it map it. + * | | | + * | | | + * | | | + * | | | + * | |/ + * ------ 0 + * + * 1) KASAN_SHADOW_START + * This value begins with the MODULE_VADDR's shadow address. It is the + * start of kernel virtual space. Since we have modules to load, we need + * to cover also that area with shadow memory so we can find memory + * bugs in modules. + * + * 2) KASAN_SHADOW_END + * This value is the 0x100000000's shadow address: the mapping that would + * be after the end of the kernel memory at 0xffffffff. It is the end of + * kernel address sanitizer shadow area. It is also the start of the + * module area. + * + * 3) KASAN_SHADOW_OFFSET: + * This value is used to map an address to the corresponding shadow + * address by the following formula: + * + * shadow_addr = (address >> 3) + KASAN_SHADOW_OFFSET; + * + * As you would expect, >> 3 is equal to dividing by 8, meaning each + * byte in the shadow memory covers 8 bytes of kernel memory, so one + * bit shadow memory per byte of kernel memory is used. + * + * The KASAN_SHADOW_OFFSET is provided in a Kconfig option depending + * on the VMSPLIT layout of the system: the kernel and userspace can + * split up lowmem in different ways according to needs, so we calculate + * the shadow offset depending on this. + */ + +#define KASAN_SHADOW_SCALE_SHIFT 3 +#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL) +#define KASAN_SHADOW_END ((UL(1) << (32 - KASAN_SHADOW_SCALE_SHIFT)) \ + + KASAN_SHADOW_OFFSET) +#define KASAN_SHADOW_START ((KASAN_SHADOW_END >> 3) + KASAN_SHADOW_OFFSET) + +#endif +#endif diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 99035b5891ef..2f841cb65c30 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -18,6 +18,7 @@ #ifdef CONFIG_NEED_MACH_MEMORY_H #include <mach/memory.h> #endif +#include <asm/kasan_def.h> /* PAGE_OFFSET - the virtual address of the start of the kernel image */ #define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET) @@ -28,7 +29,11 @@ * TASK_SIZE - the maximum size of a user space task. * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area */ +#ifndef CONFIG_KASAN #define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(SZ_16M)) +#else +#define TASK_SIZE (KASAN_SHADOW_START) +#endif #define TASK_UNMAPPED_BASE ALIGN(TASK_SIZE / 3, SZ_16M) /* @@ -67,6 +72,10 @@ */ #define XIP_VIRT_ADDR(physaddr) (MODULES_VADDR + ((physaddr) & 0x000fffff)) +#define FDT_FIXED_BASE UL(0xff800000) +#define FDT_FIXED_SIZE (2 * SECTION_SIZE) +#define FDT_VIRT_BASE(physbase) ((void *)(FDT_FIXED_BASE | (physbase) % SECTION_SIZE)) + #if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE) /* * Allow 16MB-aligned ioremap pages @@ -107,6 +116,7 @@ extern unsigned long vectors_base; #define MODULES_VADDR PAGE_OFFSET #define XIP_VIRT_ADDR(physaddr) (physaddr) +#define FDT_VIRT_BASE(physbase) ((void *)(physbase)) #endif /* !CONFIG_MMU */ @@ -173,6 +183,7 @@ extern unsigned long vectors_base; * so that all we need to do is modify the 8-bit constant field. */ #define __PV_BITS_31_24 0x81000000 +#define __PV_BITS_23_16 0x810000 #define __PV_BITS_7_0 0x81 extern unsigned long __pv_phys_pfn_offset; @@ -183,43 +194,65 @@ extern const void *__pv_table_begin, *__pv_table_end; #define PHYS_OFFSET ((phys_addr_t)__pv_phys_pfn_offset << PAGE_SHIFT) #define PHYS_PFN_OFFSET (__pv_phys_pfn_offset) -#define __pv_stub(from,to,instr,type) \ +#ifndef CONFIG_THUMB2_KERNEL +#define __pv_stub(from,to,instr) \ __asm__("@ __pv_stub\n" \ "1: " instr " %0, %1, %2\n" \ + "2: " instr " %0, %0, %3\n" \ " .pushsection .pv_table,\"a\"\n" \ - " .long 1b\n" \ + " .long 1b - ., 2b - .\n" \ " .popsection\n" \ : "=r" (to) \ - : "r" (from), "I" (type)) + : "r" (from), "I" (__PV_BITS_31_24), \ + "I"(__PV_BITS_23_16)) -#define __pv_stub_mov_hi(t) \ - __asm__ volatile("@ __pv_stub_mov\n" \ - "1: mov %R0, %1\n" \ +#define __pv_add_carry_stub(x, y) \ + __asm__("@ __pv_add_carry_stub\n" \ + "0: movw %R0, #0\n" \ + " adds %Q0, %1, %R0, lsl #20\n" \ + "1: mov %R0, %2\n" \ + " adc %R0, %R0, #0\n" \ " .pushsection .pv_table,\"a\"\n" \ - " .long 1b\n" \ + " .long 0b - ., 1b - .\n" \ " .popsection\n" \ - : "=r" (t) \ - : "I" (__PV_BITS_7_0)) + : "=&r" (y) \ + : "r" (x), "I" (__PV_BITS_7_0) \ + : "cc") + +#else +#define __pv_stub(from,to,instr) \ + __asm__("@ __pv_stub\n" \ + "0: movw %0, #0\n" \ + " lsl %0, #21\n" \ + " " instr " %0, %1, %0\n" \ + " .pushsection .pv_table,\"a\"\n" \ + " .long 0b - .\n" \ + " .popsection\n" \ + : "=&r" (to) \ + : "r" (from)) #define __pv_add_carry_stub(x, y) \ - __asm__ volatile("@ __pv_add_carry_stub\n" \ - "1: adds %Q0, %1, %2\n" \ + __asm__("@ __pv_add_carry_stub\n" \ + "0: movw %R0, #0\n" \ + " lsls %R0, #21\n" \ + " adds %Q0, %1, %R0\n" \ + "1: mvn %R0, #0\n" \ " adc %R0, %R0, #0\n" \ " .pushsection .pv_table,\"a\"\n" \ - " .long 1b\n" \ + " .long 0b - ., 1b - .\n" \ " .popsection\n" \ - : "+r" (y) \ - : "r" (x), "I" (__PV_BITS_31_24) \ + : "=&r" (y) \ + : "r" (x) \ : "cc") +#endif static inline phys_addr_t __virt_to_phys_nodebug(unsigned long x) { phys_addr_t t; if (sizeof(phys_addr_t) == 4) { - __pv_stub(x, t, "add", __PV_BITS_31_24); + __pv_stub(x, t, "add"); } else { - __pv_stub_mov_hi(t); __pv_add_carry_stub(x, t); } return t; @@ -235,7 +268,7 @@ static inline unsigned long __phys_to_virt(phys_addr_t x) * assembler expression receives 32 bit argument * in place where 'r' 32 bit operand is expected. */ - __pv_stub((unsigned long) x, t, "sub", __PV_BITS_31_24); + __pv_stub((unsigned long) x, t, "sub"); return t; } diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h index 15f4674715f8..fdee1f04f4f3 100644 --- a/arch/arm/include/asm/pgalloc.h +++ b/arch/arm/include/asm/pgalloc.h @@ -21,6 +21,7 @@ #define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL)) #ifdef CONFIG_ARM_LPAE +#define PGD_SIZE (PTRS_PER_PGD * sizeof(pgd_t)) static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) { @@ -28,14 +29,19 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) } #else /* !CONFIG_ARM_LPAE */ +#define PGD_SIZE (PAGE_SIZE << 2) /* * Since we have only two-level page tables, these are trivial */ #define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(mm, pmd) do { } while (0) +#ifdef CONFIG_KASAN +/* The KASan core unconditionally calls pud_populate() on all architectures */ +#define pud_populate(mm,pmd,pte) do { } while (0) +#else #define pud_populate(mm,pmd,pte) BUG() - +#endif #endif /* CONFIG_ARM_LPAE */ extern pgd_t *pgd_alloc(struct mm_struct *mm); diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h index baf7d0204eb5..70fe69bdcce2 100644 --- a/arch/arm/include/asm/pgtable-2level.h +++ b/arch/arm/include/asm/pgtable-2level.h @@ -179,11 +179,28 @@ * the pud: the pud entry is never bad, always exists, and can't be set or * cleared. */ -#define pud_none(pud) (0) -#define pud_bad(pud) (0) -#define pud_present(pud) (1) -#define pud_clear(pudp) do { } while (0) -#define set_pud(pud,pudp) do { } while (0) +static inline int pud_none(pud_t pud) +{ + return 0; +} + +static inline int pud_bad(pud_t pud) +{ + return 0; +} + +static inline int pud_present(pud_t pud) +{ + return 1; +} + +static inline void pud_clear(pud_t *pudp) +{ +} + +static inline void set_pud(pud_t *pudp, pud_t pud) +{ +} static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) { diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index b9241051e5cb..9e6b97286307 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h @@ -96,7 +96,7 @@ unsigned long get_wchan(struct task_struct *p); #define __ALT_SMP_ASM(smp, up) \ "9998: " smp "\n" \ " .pushsection \".alt.smp.init\", \"a\"\n" \ - " .long 9998b\n" \ + " .long 9998b - .\n" \ " " up "\n" \ " .popsection\n" #else diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h index 1e36c40533c1..402e3f34c7ed 100644 --- a/arch/arm/include/asm/prom.h +++ b/arch/arm/include/asm/prom.h @@ -9,12 +9,12 @@ #ifdef CONFIG_OF -extern const struct machine_desc *setup_machine_fdt(unsigned int dt_phys); +extern const struct machine_desc *setup_machine_fdt(void *dt_virt); extern void __init arm_dt_init_cpu_maps(void); #else /* CONFIG_OF */ -static inline const struct machine_desc *setup_machine_fdt(unsigned int dt_phys) +static inline const struct machine_desc *setup_machine_fdt(void *dt_virt) { return NULL; } diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h index 111a1d8a41dd..6c607c68f3ad 100644 --- a/arch/arm/include/asm/string.h +++ b/arch/arm/include/asm/string.h @@ -5,6 +5,9 @@ /* * We don't do inline string functions, since the * optimised inline asm versions are not small. + * + * The __underscore versions of some functions are for KASan to be able + * to replace them with instrumented versions. */ #define __HAVE_ARCH_STRRCHR @@ -15,15 +18,18 @@ extern char * strchr(const char * s, int c); #define __HAVE_ARCH_MEMCPY extern void * memcpy(void *, const void *, __kernel_size_t); +extern void *__memcpy(void *dest, const void *src, __kernel_size_t n); #define __HAVE_ARCH_MEMMOVE extern void * memmove(void *, const void *, __kernel_size_t); +extern void *__memmove(void *dest, const void *src, __kernel_size_t n); #define __HAVE_ARCH_MEMCHR extern void * memchr(const void *, int, __kernel_size_t); #define __HAVE_ARCH_MEMSET extern void * memset(void *, int, __kernel_size_t); +extern void *__memset(void *s, int c, __kernel_size_t n); #define __HAVE_ARCH_MEMSET32 extern void *__memset32(uint32_t *, uint32_t v, __kernel_size_t); @@ -39,4 +45,24 @@ static inline void *memset64(uint64_t *p, uint64_t v, __kernel_size_t n) return __memset64(p, v, n * 8, v >> 32); } +/* + * For files that are not instrumented (e.g. mm/slub.c) we + * must use non-instrumented versions of the mem* + * functions named __memcpy() etc. All such kernel code has + * been tagged with KASAN_SANITIZE_file.o = n, which means + * that the address sanitization argument isn't passed to the + * compiler, and __SANITIZE_ADDRESS__ is not set. As a result + * these defines kick in. + */ +#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) +#define memcpy(dst, src, len) __memcpy(dst, src, len) +#define memmove(dst, src, len) __memmove(dst, src, len) +#define memset(s, c, n) __memset(s, c, n) + +#ifndef __NO_FORTIFY +#define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */ +#endif + +#endif + #endif diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index eb7ce2747eb0..70d4cbc49ae1 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -13,7 +13,15 @@ #include <asm/fpstate.h> #include <asm/page.h> +#ifdef CONFIG_KASAN +/* + * KASan uses a lot of extra stack space so the thread size order needs to + * be increased. + */ +#define THREAD_SIZE_ORDER 2 +#else #define THREAD_SIZE_ORDER 1 +#endif #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) #define THREAD_START_SP (THREAD_SIZE - 8) diff --git a/arch/arm/include/asm/uaccess-asm.h b/arch/arm/include/asm/uaccess-asm.h index 907571fd05c6..e6eb7a2aaf1e 100644 --- a/arch/arm/include/asm/uaccess-asm.h +++ b/arch/arm/include/asm/uaccess-asm.h @@ -85,7 +85,7 @@ */ .macro uaccess_entry, tsk, tmp0, tmp1, tmp2, disable ldr \tmp1, [\tsk, #TI_ADDR_LIMIT] - mov \tmp2, #TASK_SIZE + ldr \tmp2, =TASK_SIZE str \tmp2, [\tsk, #TI_ADDR_LIMIT] DACR( mrc p15, 0, \tmp0, c3, c0, 0) DACR( str \tmp0, [sp, #SVC_DACR]) diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 09e67cb02b20..ae295a3bcfef 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -21,6 +21,9 @@ obj-y := elf.o entry-common.o irq.o opcodes.o \ setup.o signal.o sigreturn_codes.o \ stacktrace.o sys_arm.o time.o traps.o +KASAN_SANITIZE_stacktrace.o := n +KASAN_SANITIZE_traps.o := n + ifneq ($(CONFIG_ARM_UNWIND),y) obj-$(CONFIG_FRAME_POINTER) += return_address.o endif @@ -88,6 +91,7 @@ obj-$(CONFIG_PARAVIRT) += paravirt.o head-y := head$(MMUEXT).o obj-$(CONFIG_DEBUG_LL) += debug.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +obj-$(CONFIG_ARM_PATCH_PHYS_VIRT) += phys2virt.o # This is executed very early using a temporary stack when no memory allocator # nor global data is available. Everything has to be allocated on the stack. diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h index 067e12edc341..f2819c25b602 100644 --- a/arch/arm/kernel/atags.h +++ b/arch/arm/kernel/atags.h @@ -2,11 +2,11 @@ void convert_to_tag_list(struct tag *tags); #ifdef CONFIG_ATAGS -const struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, +const struct machine_desc *setup_machine_tags(void *__atags_vaddr, unsigned int machine_nr); #else static inline const struct machine_desc * __init __noreturn -setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) +setup_machine_tags(void *__atags_vaddr, unsigned int machine_nr) { early_print("no ATAGS support: can't continue\n"); while (true); diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c index 6c12d9fe694e..373b61f9a4f0 100644 --- a/arch/arm/kernel/atags_parse.c +++ b/arch/arm/kernel/atags_parse.c @@ -174,7 +174,7 @@ static void __init squash_mem_tags(struct tag *tag) } const struct machine_desc * __init -setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) +setup_machine_tags(void *atags_vaddr, unsigned int machine_nr) { struct tag *tags = (struct tag *)&default_tags; const struct machine_desc *mdesc = NULL, *p; @@ -195,8 +195,8 @@ setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) if (!mdesc) return NULL; - if (__atags_pointer) - tags = phys_to_virt(__atags_pointer); + if (atags_vaddr) + tags = atags_vaddr; else if (mdesc->atag_offset) tags = (void *)(PAGE_OFFSET + mdesc->atag_offset); diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 7f0745a97e20..28311dd0fee6 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -203,12 +203,12 @@ static const void * __init arch_get_next_mach(const char *const **match) /** * setup_machine_fdt - Machine setup when an dtb was passed to the kernel - * @dt_phys: physical address of dt blob + * @dt_virt: virtual address of dt blob * * If a dtb was passed to the kernel in r2, then use it to choose the * correct machine_desc and to setup the system. */ -const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) +const struct machine_desc * __init setup_machine_fdt(void *dt_virt) { const struct machine_desc *mdesc, *mdesc_best = NULL; @@ -221,7 +221,7 @@ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) mdesc_best = &__mach_desc_GENERIC_DT; #endif - if (!dt_phys || !early_init_dt_verify(phys_to_virt(dt_phys))) + if (!dt_virt || !early_init_dt_verify(dt_virt)) return NULL; mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach); diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 55a47df04773..0ea8529a4872 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -252,31 +252,10 @@ __und_svc: #else svc_entry #endif - @ - @ call emulation code, which returns using r9 if it has emulated - @ the instruction, or the more conventional lr if we are to treat - @ this as a real undefined instruction - @ - @ r0 - instruction - @ -#ifndef CONFIG_THUMB2_KERNEL - ldr r0, [r4, #-4] -#else - mov r1, #2 - ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2 - cmp r0, #0xe800 @ 32-bit instruction if xx >= 0 - blo __und_svc_fault - ldrh r9, [r4] @ bottom 16 bits - add r4, r4, #2 - str r4, [sp, #S_PC] - orr r0, r9, r0, lsl #16 -#endif - badr r9, __und_svc_finish - mov r2, r4 - bl call_fpe mov r1, #4 @ PC correction to apply -__und_svc_fault: + THUMB( tst r5, #PSR_T_BIT ) @ exception taken in Thumb mode? + THUMB( movne r1, #2 ) @ if so, fix up PC correction mov r0, sp @ struct pt_regs *regs bl __und_fault @@ -427,7 +406,8 @@ ENDPROC(__fiq_abt) @ if it was interrupted in a critical region. Here we @ perform a quick test inline since it should be false @ 99.9999% of the time. The rest is done out of line. - cmp r4, #TASK_SIZE + ldr r0, =TASK_SIZE + cmp r4, r0 blhs kuser_cmpxchg64_fixup #endif #endif diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 77d16390a524..e0d7833a1827 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -50,7 +50,8 @@ __ret_fast_syscall: UNWIND(.cantunwind ) disable_irq_notrace @ disable interrupts ldr r2, [tsk, #TI_ADDR_LIMIT] - cmp r2, #TASK_SIZE + ldr r1, =TASK_SIZE + cmp r2, r1 blne addr_limit_check_failed ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing movs r1, r1, lsl #16 @@ -87,7 +88,8 @@ __ret_fast_syscall: #endif disable_irq_notrace @ disable interrupts ldr r2, [tsk, #TI_ADDR_LIMIT] - cmp r2, #TASK_SIZE + ldr r1, =TASK_SIZE + cmp r2, r1 blne addr_limit_check_failed ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing movs r1, r1, lsl #16 @@ -128,7 +130,8 @@ ret_slow_syscall: disable_irq_notrace @ disable interrupts ENTRY(ret_to_user_from_irq) ldr r2, [tsk, #TI_ADDR_LIMIT] - cmp r2, #TASK_SIZE + ldr r1, =TASK_SIZE + cmp r2, r1 blne addr_limit_check_failed ldr r1, [tsk, #TI_FLAGS] movs r1, r1, lsl #16 diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 4a3982812a40..29b2eda136bb 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -95,7 +95,7 @@ __mmap_switched: THUMB( ldmia r4!, {r0, r1, r2, r3} ) THUMB( mov sp, r3 ) sub r2, r2, r1 - bl memcpy @ copy .data to RAM + bl __memcpy @ copy .data to RAM #endif ARM( ldmia r4!, {r0, r1, sp} ) @@ -103,7 +103,7 @@ __mmap_switched: THUMB( mov sp, r3 ) sub r2, r1, r0 mov r1, #0 - bl memset @ clear .bss + bl __memset @ clear .bss ldmia r4, {r0, r1, r2, r3} str r9, [r0] @ Save processor ID @@ -111,6 +111,9 @@ __mmap_switched: str r8, [r2] @ Save atags pointer cmp r3, #0 strne r10, [r3] @ Save control register values +#ifdef CONFIG_KASAN + bl kasan_early_init +#endif mov lr, #0 b start_kernel ENDPROC(__mmap_switched) @@ -170,11 +173,12 @@ ENDPROC(lookup_processor_type) * r9 = cpuid (preserved) */ __lookup_processor_type: - adr r3, __lookup_processor_type_data - ldmia r3, {r4 - r6} - sub r3, r3, r4 @ get offset between virt&phys - add r5, r5, r3 @ convert virt addresses to - add r6, r6, r3 @ physical address space + /* + * Look in <asm/procinfo.h> for information about the __proc_info + * structure. + */ + adr_l r5, __proc_info_begin + adr_l r6, __proc_info_end 1: ldmia r5, {r3, r4} @ value, mask and r4, r4, r9 @ mask wanted bits teq r3, r4 @@ -186,17 +190,6 @@ __lookup_processor_type: 2: ret lr ENDPROC(__lookup_processor_type) -/* - * Look in <asm/procinfo.h> for information about the __proc_info structure. - */ - .align 2 - .type __lookup_processor_type_data, %object -__lookup_processor_type_data: - .long . - .long __proc_info_begin - .long __proc_info_end - .size __lookup_processor_type_data, . - __lookup_processor_type_data - __error_lpae: #ifdef CONFIG_DEBUG_LL adr r0, str_lpae diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index f8904227e7fd..7f62c5eccdf3 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -103,10 +103,8 @@ ENTRY(stext) #endif #ifndef CONFIG_XIP_KERNEL - adr r3, 2f - ldmia r3, {r4, r8} - sub r4, r3, r4 @ (PHYS_OFFSET - PAGE_OFFSET) - add r8, r8, r4 @ PHYS_OFFSET + adr_l r8, _text @ __pa(_text) + sub r8, r8, #TEXT_OFFSET @ PHYS_OFFSET #else ldr r8, =PLAT_PHYS_OFFSET @ always constant in this case #endif @@ -158,10 +156,6 @@ ENTRY(stext) 1: b __enable_mmu ENDPROC(stext) .ltorg -#ifndef CONFIG_XIP_KERNEL -2: .long . - .long PAGE_OFFSET -#endif /* * Setup the initial page tables. We only setup the barest @@ -224,11 +218,8 @@ __create_page_tables: * Create identity mapping to cater for __enable_mmu. * This identity mapping will be removed by paging_init(). */ - adr r0, __turn_mmu_on_loc - ldmia r0, {r3, r5, r6} - sub r0, r0, r3 @ virt->phys offset - add r5, r5, r0 @ phys __turn_mmu_on - add r6, r6, r0 @ phys __turn_mmu_on_end + adr_l r5, __turn_mmu_on @ _pa(__turn_mmu_on) + adr_l r6, __turn_mmu_on_end @ _pa(__turn_mmu_on_end) mov r5, r5, lsr #SECTION_SHIFT mov r6, r6, lsr #SECTION_SHIFT @@ -274,11 +265,10 @@ __create_page_tables: * We map 2 sections in case the ATAGs/DTB crosses a section boundary. */ mov r0, r2, lsr #SECTION_SHIFT - movs r0, r0, lsl #SECTION_SHIFT - subne r3, r0, r8 - addne r3, r3, #PAGE_OFFSET - addne r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER) - orrne r6, r7, r0 + cmp r2, #0 + ldrne r3, =FDT_FIXED_BASE >> (SECTION_SHIFT - PMD_ORDER) + addne r3, r3, r4 + orrne r6, r7, r0, lsl #SECTION_SHIFT strne r6, [r3], #1 << PMD_ORDER addne r6, r6, #1 << SECTION_SHIFT strne r6, [r3] @@ -351,11 +341,6 @@ __create_page_tables: ret lr ENDPROC(__create_page_tables) .ltorg - .align -__turn_mmu_on_loc: - .long . - .long __turn_mmu_on - .long __turn_mmu_on_end #if defined(CONFIG_SMP) .text @@ -391,10 +376,8 @@ ENTRY(secondary_startup) /* * Use the page tables supplied from __cpu_up. */ - adr r4, __secondary_data - ldmia r4, {r5, r7, r12} @ address to jump to after - sub lr, r4, r5 @ mmu has been enabled - add r3, r7, lr + adr_l r3, secondary_data + mov_l r12, __secondary_switched ldrd r4, r5, [r3, #0] @ get secondary_data.pgdir ARM_BE8(eor r4, r4, r5) @ Swap r5 and r4 in BE: ARM_BE8(eor r5, r4, r5) @ it can be done in 3 steps @@ -409,22 +392,13 @@ ARM_BE8(eor r4, r4, r5) @ without using a temp reg. ENDPROC(secondary_startup) ENDPROC(secondary_startup_arm) - /* - * r6 = &secondary_data - */ ENTRY(__secondary_switched) - ldr sp, [r7, #12] @ get secondary_data.stack + ldr_l r7, secondary_data + 12 @ get secondary_data.stack + mov sp, r7 mov fp, #0 b secondary_start_kernel ENDPROC(__secondary_switched) - .align - - .type __secondary_data, %object -__secondary_data: - .long . - .long secondary_data - .long __secondary_switched #endif /* defined(CONFIG_SMP) */ @@ -539,19 +513,11 @@ ARM_BE8(rev r0, r0) @ byteswap if big endian retne lr __fixup_smp_on_up: - adr r0, 1f - ldmia r0, {r3 - r5} - sub r3, r0, r3 - add r4, r4, r3 - add r5, r5, r3 + adr_l r4, __smpalt_begin + adr_l r5, __smpalt_end b __do_fixup_smp_on_up ENDPROC(__fixup_smp) - .align -1: .word . - .word __smpalt_begin - .word __smpalt_end - .pushsection .data .align 2 .globl smp_on_up @@ -565,14 +531,15 @@ smp_on_up: __do_fixup_smp_on_up: cmp r4, r5 reths lr - ldmia r4!, {r0, r6} - ARM( str r6, [r0, r3] ) - THUMB( add r0, r0, r3 ) + ldmia r4, {r0, r6} + ARM( str r6, [r0, r4] ) + THUMB( add r0, r0, r4 ) + add r4, r4, #8 #ifdef __ARMEB__ THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian. #endif THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords - THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3. + THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r0. THUMB( strh r6, [r0] ) b __do_fixup_smp_on_up ENDPROC(__do_fixup_smp_on_up) @@ -581,151 +548,8 @@ ENTRY(fixup_smp) stmfd sp!, {r4 - r6, lr} mov r4, r0 add r5, r0, r1 - mov r3, #0 bl __do_fixup_smp_on_up ldmfd sp!, {r4 - r6, pc} ENDPROC(fixup_smp) -#ifdef __ARMEB__ -#define LOW_OFFSET 0x4 -#define HIGH_OFFSET 0x0 -#else -#define LOW_OFFSET 0x0 -#define HIGH_OFFSET 0x4 -#endif - -#ifdef CONFIG_ARM_PATCH_PHYS_VIRT - -/* __fixup_pv_table - patch the stub instructions with the delta between - * PHYS_OFFSET and PAGE_OFFSET, which is assumed to be 16MiB aligned and - * can be expressed by an immediate shifter operand. The stub instruction - * has a form of '(add|sub) rd, rn, #imm'. - */ - __HEAD -__fixup_pv_table: - adr r0, 1f - ldmia r0, {r3-r7} - mvn ip, #0 - subs r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET - add r4, r4, r3 @ adjust table start address - add r5, r5, r3 @ adjust table end address - add r6, r6, r3 @ adjust __pv_phys_pfn_offset address - add r7, r7, r3 @ adjust __pv_offset address - mov r0, r8, lsr #PAGE_SHIFT @ convert to PFN - str r0, [r6] @ save computed PHYS_OFFSET to __pv_phys_pfn_offset - strcc ip, [r7, #HIGH_OFFSET] @ save to __pv_offset high bits - mov r6, r3, lsr #24 @ constant for add/sub instructions - teq r3, r6, lsl #24 @ must be 16MiB aligned -THUMB( it ne @ cross section branch ) - bne __error - str r3, [r7, #LOW_OFFSET] @ save to __pv_offset low bits - b __fixup_a_pv_table -ENDPROC(__fixup_pv_table) - - .align -1: .long . - .long __pv_table_begin - .long __pv_table_end -2: .long __pv_phys_pfn_offset - .long __pv_offset - - .text -__fixup_a_pv_table: - adr r0, 3f - ldr r6, [r0] - add r6, r6, r3 - ldr r0, [r6, #HIGH_OFFSET] @ pv_offset high word - ldr r6, [r6, #LOW_OFFSET] @ pv_offset low word - mov r6, r6, lsr #24 - cmn r0, #1 -#ifdef CONFIG_THUMB2_KERNEL - moveq r0, #0x200000 @ set bit 21, mov to mvn instruction - lsls r6, #24 - beq 2f - clz r7, r6 - lsr r6, #24 - lsl r6, r7 - bic r6, #0x0080 - lsrs r7, #1 - orrcs r6, #0x0080 - orr r6, r6, r7, lsl #12 - orr r6, #0x4000 - b 2f -1: add r7, r3 - ldrh ip, [r7, #2] -ARM_BE8(rev16 ip, ip) - tst ip, #0x4000 - and ip, #0x8f00 - orrne ip, r6 @ mask in offset bits 31-24 - orreq ip, r0 @ mask in offset bits 7-0 -ARM_BE8(rev16 ip, ip) - strh ip, [r7, #2] - bne 2f - ldrh ip, [r7] -ARM_BE8(rev16 ip, ip) - bic ip, #0x20 - orr ip, ip, r0, lsr #16 -ARM_BE8(rev16 ip, ip) - strh ip, [r7] -2: cmp r4, r5 - ldrcc r7, [r4], #4 @ use branch for delay slot - bcc 1b - bx lr -#else -#ifdef CONFIG_CPU_ENDIAN_BE8 - moveq r0, #0x00004000 @ set bit 22, mov to mvn instruction -#else - moveq r0, #0x400000 @ set bit 22, mov to mvn instruction -#endif - b 2f -1: ldr ip, [r7, r3] -#ifdef CONFIG_CPU_ENDIAN_BE8 - @ in BE8, we load data in BE, but instructions still in LE - bic ip, ip, #0xff000000 - tst ip, #0x000f0000 @ check the rotation field - orrne ip, ip, r6, lsl #24 @ mask in offset bits 31-24 - biceq ip, ip, #0x00004000 @ clear bit 22 - orreq ip, ip, r0 @ mask in offset bits 7-0 -#else - bic ip, ip, #0x000000ff - tst ip, #0xf00 @ check the rotation field - orrne ip, ip, r6 @ mask in offset bits 31-24 - biceq ip, ip, #0x400000 @ clear bit 22 - orreq ip, ip, r0 @ mask in offset bits 7-0 -#endif - str ip, [r7, r3] -2: cmp r4, r5 - ldrcc r7, [r4], #4 @ use branch for delay slot - bcc 1b - ret lr -#endif -ENDPROC(__fixup_a_pv_table) - - .align -3: .long __pv_offset - -ENTRY(fixup_pv_table) - stmfd sp!, {r4 - r7, lr} - mov r3, #0 @ no offset - mov r4, r0 @ r0 = table start - add r5, r0, r1 @ r1 = table size - bl __fixup_a_pv_table - ldmfd sp!, {r4 - r7, pc} -ENDPROC(fixup_pv_table) - - .data - .align 2 - .globl __pv_phys_pfn_offset - .type __pv_phys_pfn_offset, %object -__pv_phys_pfn_offset: - .word 0 - .size __pv_phys_pfn_offset, . -__pv_phys_pfn_offset - - .globl __pv_offset - .type __pv_offset, %object -__pv_offset: - .quad 0 - .size __pv_offset, . -__pv_offset -#endif - #include "head-common.S" diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S index 26d8e03b1dd3..b699b22a4db1 100644 --- a/arch/arm/kernel/hyp-stub.S +++ b/arch/arm/kernel/hyp-stub.S @@ -24,41 +24,38 @@ ENTRY(__boot_cpu_mode) .text /* - * Save the primary CPU boot mode. Requires 3 scratch registers. + * Save the primary CPU boot mode. Requires 2 scratch registers. */ - .macro store_primary_cpu_mode reg1, reg2, reg3 + .macro store_primary_cpu_mode reg1, reg2 mrs \reg1, cpsr and \reg1, \reg1, #MODE_MASK - adr \reg2, .L__boot_cpu_mode_offset - ldr \reg3, [\reg2] - str \reg1, [\reg2, \reg3] + str_l \reg1, __boot_cpu_mode, \reg2 .endm /* * Compare the current mode with the one saved on the primary CPU. * If they don't match, record that fact. The Z bit indicates * if there's a match or not. - * Requires 3 additionnal scratch registers. + * Requires 2 additional scratch registers. */ - .macro compare_cpu_mode_with_primary mode, reg1, reg2, reg3 - adr \reg2, .L__boot_cpu_mode_offset - ldr \reg3, [\reg2] - ldr \reg1, [\reg2, \reg3] + .macro compare_cpu_mode_with_primary mode, reg1, reg2 + adr_l \reg2, __boot_cpu_mode + ldr \reg1, [\reg2] cmp \mode, \reg1 @ matches primary CPU boot mode? orrne \reg1, \reg1, #BOOT_CPU_MODE_MISMATCH - strne \reg1, [\reg2, \reg3] @ record what happened and give up + strne \reg1, [\reg2] @ record what happened and give up .endm #else /* ZIMAGE */ - .macro store_primary_cpu_mode reg1:req, reg2:req, reg3:req + .macro store_primary_cpu_mode reg1:req, reg2:req .endm /* * The zImage loader only runs on one CPU, so we don't bother with mult-CPU * consistency checking: */ - .macro compare_cpu_mode_with_primary mode, reg1, reg2, reg3 + .macro compare_cpu_mode_with_primary mode, reg1, reg2 cmp \mode, \mode .endm @@ -73,7 +70,7 @@ ENTRY(__boot_cpu_mode) */ @ Call this from the primary CPU ENTRY(__hyp_stub_install) - store_primary_cpu_mode r4, r5, r6 + store_primary_cpu_mode r4, r5 ENDPROC(__hyp_stub_install) @ fall through... @@ -87,7 +84,7 @@ ENTRY(__hyp_stub_install_secondary) * If the secondary has booted with a different mode, give up * immediately. */ - compare_cpu_mode_with_primary r4, r5, r6, r7 + compare_cpu_mode_with_primary r4, r5, r6 retne lr /* @@ -228,12 +225,6 @@ ENTRY(__hyp_soft_restart) ret lr ENDPROC(__hyp_soft_restart) -#ifndef ZIMAGE -.align 2 -.L__boot_cpu_mode_offset: - .long __boot_cpu_mode - . -#endif - .align 5 ENTRY(__hyp_stub_vectors) __hyp_stub_reset: W(b) . diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S index 0dcae787b004..d2b4ac06e4ed 100644 --- a/arch/arm/kernel/iwmmxt.S +++ b/arch/arm/kernel/iwmmxt.S @@ -16,6 +16,7 @@ #include <asm/thread_info.h> #include <asm/asm-offsets.h> #include <asm/assembler.h> +#include "iwmmxt.h" #if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B) #define PJ4(code...) code @@ -113,33 +114,33 @@ concan_save: concan_dump: - wstrw wCSSF, [r1, #MMX_WCSSF] - wstrw wCASF, [r1, #MMX_WCASF] - wstrw wCGR0, [r1, #MMX_WCGR0] - wstrw wCGR1, [r1, #MMX_WCGR1] - wstrw wCGR2, [r1, #MMX_WCGR2] - wstrw wCGR3, [r1, #MMX_WCGR3] + wstrw wCSSF, r1, MMX_WCSSF + wstrw wCASF, r1, MMX_WCASF + wstrw wCGR0, r1, MMX_WCGR0 + wstrw wCGR1, r1, MMX_WCGR1 + wstrw wCGR2, r1, MMX_WCGR2 + wstrw wCGR3, r1, MMX_WCGR3 1: @ MUP? wRn tst r2, #0x2 beq 2f - wstrd wR0, [r1, #MMX_WR0] - wstrd wR1, [r1, #MMX_WR1] - wstrd wR2, [r1, #MMX_WR2] - wstrd wR3, [r1, #MMX_WR3] - wstrd wR4, [r1, #MMX_WR4] - wstrd wR5, [r1, #MMX_WR5] - wstrd wR6, [r1, #MMX_WR6] - wstrd wR7, [r1, #MMX_WR7] - wstrd wR8, [r1, #MMX_WR8] - wstrd wR9, [r1, #MMX_WR9] - wstrd wR10, [r1, #MMX_WR10] - wstrd wR11, [r1, #MMX_WR11] - wstrd wR12, [r1, #MMX_WR12] - wstrd wR13, [r1, #MMX_WR13] - wstrd wR14, [r1, #MMX_WR14] - wstrd wR15, [r1, #MMX_WR15] + wstrd wR0, r1, MMX_WR0 + wstrd wR1, r1, MMX_WR1 + wstrd wR2, r1, MMX_WR2 + wstrd wR3, r1, MMX_WR3 + wstrd wR4, r1, MMX_WR4 + wstrd wR5, r1, MMX_WR5 + wstrd wR6, r1, MMX_WR6 + wstrd wR7, r1, MMX_WR7 + wstrd wR8, r1, MMX_WR8 + wstrd wR9, r1, MMX_WR9 + wstrd wR10, r1, MMX_WR10 + wstrd wR11, r1, MMX_WR11 + wstrd wR12, r1, MMX_WR12 + wstrd wR13, r1, MMX_WR13 + wstrd wR14, r1, MMX_WR14 + wstrd wR15, r1, MMX_WR15 2: teq r0, #0 @ anything to load? reteq lr @ if not, return @@ -147,30 +148,30 @@ concan_dump: concan_load: @ Load wRn - wldrd wR0, [r0, #MMX_WR0] - wldrd wR1, [r0, #MMX_WR1] - wldrd wR2, [r0, #MMX_WR2] - wldrd wR3, [r0, #MMX_WR3] - wldrd wR4, [r0, #MMX_WR4] - wldrd wR5, [r0, #MMX_WR5] - wldrd wR6, [r0, #MMX_WR6] - wldrd wR7, [r0, #MMX_WR7] - wldrd wR8, [r0, #MMX_WR8] - wldrd wR9, [r0, #MMX_WR9] - wldrd wR10, [r0, #MMX_WR10] - wldrd wR11, [r0, #MMX_WR11] - wldrd wR12, [r0, #MMX_WR12] - wldrd wR13, [r0, #MMX_WR13] - wldrd wR14, [r0, #MMX_WR14] - wldrd wR15, [r0, #MMX_WR15] + wldrd wR0, r0, MMX_WR0 + wldrd wR1, r0, MMX_WR1 + wldrd wR2, r0, MMX_WR2 + wldrd wR3, r0, MMX_WR3 + wldrd wR4, r0, MMX_WR4 + wldrd wR5, r0, MMX_WR5 + wldrd wR6, r0, MMX_WR6 + wldrd wR7, r0, MMX_WR7 + wldrd wR8, r0, MMX_WR8 + wldrd wR9, r0, MMX_WR9 + wldrd wR10, r0, MMX_WR10 + wldrd wR11, r0, MMX_WR11 + wldrd wR12, r0, MMX_WR12 + wldrd wR13, r0, MMX_WR13 + wldrd wR14, r0, MMX_WR14 + wldrd wR15, r0, MMX_WR15 @ Load wCx - wldrw wCSSF, [r0, #MMX_WCSSF] - wldrw wCASF, [r0, #MMX_WCASF] - wldrw wCGR0, [r0, #MMX_WCGR0] - wldrw wCGR1, [r0, #MMX_WCGR1] - wldrw wCGR2, [r0, #MMX_WCGR2] - wldrw wCGR3, [r0, #MMX_WCGR3] + wldrw wCSSF, r0, MMX_WCSSF + wldrw wCASF, r0, MMX_WCASF + wldrw wCGR0, r0, MMX_WCGR0 + wldrw wCGR1, r0, MMX_WCGR1 + wldrw wCGR2, r0, MMX_WCGR2 + wldrw wCGR3, r0, MMX_WCGR3 @ clear CUP/MUP (only if r1 != 0) teq r1, #0 diff --git a/arch/arm/kernel/iwmmxt.h b/arch/arm/kernel/iwmmxt.h new file mode 100644 index 000000000000..fb627286f5bb --- /dev/null +++ b/arch/arm/kernel/iwmmxt.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __IWMMXT_H__ +#define __IWMMXT_H__ + +.irp b, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +.set .LwR\b, \b +.set .Lr\b, \b +.endr + +.set .LwCSSF, 0x2 +.set .LwCASF, 0x3 +.set .LwCGR0, 0x8 +.set .LwCGR1, 0x9 +.set .LwCGR2, 0xa +.set .LwCGR3, 0xb + +.macro wldrd, reg:req, base:req, offset:req +.inst 0xedd00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) +.endm + +.macro wldrw, reg:req, base:req, offset:req +.inst 0xfd900100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) +.endm + +.macro wstrd, reg:req, base:req, offset:req +.inst 0xedc00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) +.endm + +.macro wstrw, reg:req, base:req, offset:req +.inst 0xfd800100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) +.endm + +#ifdef __clang__ + +#define wCon c1 + +.macro tmrc, dest:req, control:req +mrc p1, 0, \dest, \control, c0, 0 +.endm + +.macro tmcr, control:req, src:req +mcr p1, 0, \src, \control, c0, 0 +.endm +#endif + +#endif diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index e15444b25ca0..beac45e89ba6 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -185,14 +185,24 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, *(u32 *)loc |= offset & 0x7fffffff; break; + case R_ARM_REL32: + *(u32 *)loc += sym->st_value - loc; + break; + case R_ARM_MOVW_ABS_NC: case R_ARM_MOVT_ABS: + case R_ARM_MOVW_PREL_NC: + case R_ARM_MOVT_PREL: offset = tmp = __mem_to_opcode_arm(*(u32 *)loc); offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); offset = (offset ^ 0x8000) - 0x8000; offset += sym->st_value; - if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS) + if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_PREL || + ELF32_R_TYPE(rel->r_info) == R_ARM_MOVW_PREL_NC) + offset -= loc; + if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS || + ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_PREL) offset >>= 16; tmp &= 0xfff0f000; @@ -283,6 +293,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, case R_ARM_THM_MOVW_ABS_NC: case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_PREL_NC: + case R_ARM_THM_MOVT_PREL: upper = __mem_to_opcode_thumb16(*(u16 *)loc); lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2)); @@ -302,7 +314,11 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, offset = (offset ^ 0x8000) - 0x8000; offset += sym->st_value; - if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS) + if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_PREL || + ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVW_PREL_NC) + offset -= loc; + if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS || + ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_PREL) offset >>= 16; upper = (u16)((upper & 0xfbf0) | diff --git a/arch/arm/kernel/phys2virt.S b/arch/arm/kernel/phys2virt.S new file mode 100644 index 000000000000..fb53db78fe78 --- /dev/null +++ b/arch/arm/kernel/phys2virt.S @@ -0,0 +1,238 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 1994-2002 Russell King + * Copyright (c) 2003, 2020 ARM Limited + * All Rights Reserved + */ + +#include <linux/init.h> +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/page.h> + +#ifdef __ARMEB__ +#define LOW_OFFSET 0x4 +#define HIGH_OFFSET 0x0 +#else +#define LOW_OFFSET 0x0 +#define HIGH_OFFSET 0x4 +#endif + +/* + * __fixup_pv_table - patch the stub instructions with the delta between + * PHYS_OFFSET and PAGE_OFFSET, which is assumed to be + * 2 MiB aligned. + * + * Called from head.S, which expects the following registers to be preserved: + * r1 = machine no, r2 = atags or dtb, + * r8 = phys_offset, r9 = cpuid, r10 = procinfo + */ + __HEAD +ENTRY(__fixup_pv_table) + mov r0, r8, lsr #PAGE_SHIFT @ convert to PFN + str_l r0, __pv_phys_pfn_offset, r3 + + adr_l r0, __pv_offset + subs r3, r8, #PAGE_OFFSET @ PHYS_OFFSET - PAGE_OFFSET + mvn ip, #0 + strcc ip, [r0, #HIGH_OFFSET] @ save to __pv_offset high bits + str r3, [r0, #LOW_OFFSET] @ save to __pv_offset low bits + + mov r0, r3, lsr #21 @ constant for add/sub instructions + teq r3, r0, lsl #21 @ must be 2 MiB aligned + bne 0f + + adr_l r4, __pv_table_begin + adr_l r5, __pv_table_end + b __fixup_a_pv_table + +0: mov r0, r0 @ deadloop on error + b 0b +ENDPROC(__fixup_pv_table) + + .text +__fixup_a_pv_table: + adr_l r6, __pv_offset + ldr r0, [r6, #HIGH_OFFSET] @ pv_offset high word + ldr r6, [r6, #LOW_OFFSET] @ pv_offset low word + cmn r0, #1 +#ifdef CONFIG_THUMB2_KERNEL + @ + @ The Thumb-2 versions of the patchable sequences are + @ + @ phys-to-virt: movw <reg>, #offset<31:21> + @ lsl <reg>, #21 + @ sub <VA>, <PA>, <reg> + @ + @ virt-to-phys (non-LPAE): movw <reg>, #offset<31:21> + @ lsl <reg>, #21 + @ add <PA>, <VA>, <reg> + @ + @ virt-to-phys (LPAE): movw <reg>, #offset<31:21> + @ lsl <reg>, #21 + @ adds <PAlo>, <VA>, <reg> + @ mov <PAhi>, #offset<39:32> + @ adc <PAhi>, <PAhi>, #0 + @ + @ In the non-LPAE case, all patchable instructions are MOVW + @ instructions, where we need to patch in the offset into the + @ second halfword of the opcode (the 16-bit immediate is encoded + @ as imm4:i:imm3:imm8) + @ + @ 15 11 10 9 4 3 0 15 14 12 11 8 7 0 + @ +-----------+---+-------------+------++---+------+----+------+ + @ MOVW | 1 1 1 1 0 | i | 1 0 0 1 0 0 | imm4 || 0 | imm3 | Rd | imm8 | + @ +-----------+---+-------------+------++---+------+----+------+ + @ + @ In the LPAE case, we also need to patch in the high word of the + @ offset into the immediate field of the MOV instruction, or patch it + @ to a MVN instruction if the offset is negative. In this case, we + @ need to inspect the first halfword of the opcode, to check whether + @ it is MOVW or MOV/MVN, and to perform the MOV to MVN patching if + @ needed. The encoding of the immediate is rather complex for values + @ of i:imm3 != 0b0000, but fortunately, we never need more than 8 lower + @ order bits, which can be patched into imm8 directly (and i:imm3 + @ cleared) + @ + @ 15 11 10 9 5 0 15 14 12 11 8 7 0 + @ +-----------+---+---------------------++---+------+----+------+ + @ MOV | 1 1 1 1 0 | i | 0 0 0 1 0 0 1 1 1 1 || 0 | imm3 | Rd | imm8 | + @ MVN | 1 1 1 1 0 | i | 0 0 0 1 1 0 1 1 1 1 || 0 | imm3 | Rd | imm8 | + @ +-----------+---+---------------------++---+------+----+------+ + @ + moveq r0, #0x200000 @ set bit 21, mov to mvn instruction + lsrs r3, r6, #29 @ isolate top 3 bits of displacement + ubfx r6, r6, #21, #8 @ put bits 28:21 into the MOVW imm8 field + bfi r6, r3, #12, #3 @ put bits 31:29 into the MOVW imm3 field + b .Lnext +.Lloop: add r7, r4 + adds r4, #4 @ clears Z flag +#ifdef CONFIG_ARM_LPAE + ldrh ip, [r7] +ARM_BE8(rev16 ip, ip) + tst ip, #0x200 @ MOVW has bit 9 set, MVN has it clear + bne 0f @ skip to MOVW handling (Z flag is clear) + bic ip, #0x20 @ clear bit 5 (MVN -> MOV) + orr ip, ip, r0, lsr #16 @ MOV -> MVN if offset < 0 +ARM_BE8(rev16 ip, ip) + strh ip, [r7] + @ Z flag is set +0: +#endif + ldrh ip, [r7, #2] +ARM_BE8(rev16 ip, ip) + and ip, #0xf00 @ clear everything except Rd field + orreq ip, r0 @ Z flag set -> MOV/MVN -> patch in high bits + orrne ip, r6 @ Z flag clear -> MOVW -> patch in low bits +ARM_BE8(rev16 ip, ip) + strh ip, [r7, #2] +#else +#ifdef CONFIG_CPU_ENDIAN_BE8 +@ in BE8, we load data in BE, but instructions still in LE +#define PV_BIT24 0x00000001 +#define PV_IMM8_MASK 0xff000000 +#define PV_IMMR_MSB 0x00080000 +#else +#define PV_BIT24 0x01000000 +#define PV_IMM8_MASK 0x000000ff +#define PV_IMMR_MSB 0x00000800 +#endif + + @ + @ The ARM versions of the patchable sequences are + @ + @ phys-to-virt: sub <VA>, <PA>, #offset<31:24>, lsl #24 + @ sub <VA>, <PA>, #offset<23:16>, lsl #16 + @ + @ virt-to-phys (non-LPAE): add <PA>, <VA>, #offset<31:24>, lsl #24 + @ add <PA>, <VA>, #offset<23:16>, lsl #16 + @ + @ virt-to-phys (LPAE): movw <reg>, #offset<31:20> + @ adds <PAlo>, <VA>, <reg>, lsl #20 + @ mov <PAhi>, #offset<39:32> + @ adc <PAhi>, <PAhi>, #0 + @ + @ In the non-LPAE case, all patchable instructions are ADD or SUB + @ instructions, where we need to patch in the offset into the + @ immediate field of the opcode, which is emitted with the correct + @ rotation value. (The effective value of the immediate is imm12<7:0> + @ rotated right by [2 * imm12<11:8>] bits) + @ + @ 31 28 27 23 22 20 19 16 15 12 11 0 + @ +------+-----------------+------+------+-------+ + @ ADD | cond | 0 0 1 0 1 0 0 0 | Rn | Rd | imm12 | + @ SUB | cond | 0 0 1 0 0 1 0 0 | Rn | Rd | imm12 | + @ MOV | cond | 0 0 1 1 1 0 1 0 | Rn | Rd | imm12 | + @ MVN | cond | 0 0 1 1 1 1 1 0 | Rn | Rd | imm12 | + @ +------+-----------------+------+------+-------+ + @ + @ In the LPAE case, we use a MOVW instruction to carry the low offset + @ word, and patch in the high word of the offset into the immediate + @ field of the subsequent MOV instruction, or patch it to a MVN + @ instruction if the offset is negative. We can distinguish MOVW + @ instructions based on bits 23:22 of the opcode, and ADD/SUB can be + @ distinguished from MOV/MVN (all using the encodings above) using + @ bit 24. + @ + @ 31 28 27 23 22 20 19 16 15 12 11 0 + @ +------+-----------------+------+------+-------+ + @ MOVW | cond | 0 0 1 1 0 0 0 0 | imm4 | Rd | imm12 | + @ +------+-----------------+------+------+-------+ + @ + moveq r0, #0x400000 @ set bit 22, mov to mvn instruction + mov r3, r6, lsr #16 @ put offset bits 31-16 into r3 + mov r6, r6, lsr #24 @ put offset bits 31-24 into r6 + and r3, r3, #0xf0 @ only keep offset bits 23-20 in r3 + b .Lnext +.Lloop: ldr ip, [r7, r4] +#ifdef CONFIG_ARM_LPAE + tst ip, #PV_BIT24 @ ADD/SUB have bit 24 clear + beq 1f +ARM_BE8(rev ip, ip) + tst ip, #0xc00000 @ MOVW has bits 23:22 clear + bic ip, ip, #0x400000 @ clear bit 22 + bfc ip, #0, #12 @ clear imm12 field of MOV[W] instruction + orreq ip, ip, r6, lsl #4 @ MOVW -> mask in offset bits 31-24 + orreq ip, ip, r3, lsr #4 @ MOVW -> mask in offset bits 23-20 + orrne ip, ip, r0 @ MOV -> mask in offset bits 7-0 (or bit 22) +ARM_BE8(rev ip, ip) + b 2f +1: +#endif + tst ip, #PV_IMMR_MSB @ rotation value >= 16 ? + bic ip, ip, #PV_IMM8_MASK + orreq ip, ip, r6 ARM_BE8(, lsl #24) @ mask in offset bits 31-24 + orrne ip, ip, r3 ARM_BE8(, lsl #24) @ mask in offset bits 23-20 +2: + str ip, [r7, r4] + add r4, r4, #4 +#endif + +.Lnext: + cmp r4, r5 + ldrcc r7, [r4] @ use branch for delay slot + bcc .Lloop + ret lr +ENDPROC(__fixup_a_pv_table) + +ENTRY(fixup_pv_table) + stmfd sp!, {r4 - r7, lr} + mov r4, r0 @ r0 = table start + add r5, r0, r1 @ r1 = table size + bl __fixup_a_pv_table + ldmfd sp!, {r4 - r7, pc} +ENDPROC(fixup_pv_table) + + .data + .align 2 + .globl __pv_phys_pfn_offset + .type __pv_phys_pfn_offset, %object +__pv_phys_pfn_offset: + .word 0 + .size __pv_phys_pfn_offset, . -__pv_phys_pfn_offset + + .globl __pv_offset + .type __pv_offset, %object +__pv_offset: + .quad 0 + .size __pv_offset, . -__pv_offset diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 3f65d0ac9f63..1a5edf562e85 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -18,6 +18,7 @@ #include <linux/of_platform.h> #include <linux/init.h> #include <linux/kexec.h> +#include <linux/libfdt.h> #include <linux/of_fdt.h> #include <linux/cpu.h> #include <linux/interrupt.h> @@ -58,6 +59,7 @@ #include <asm/unwind.h> #include <asm/memblock.h> #include <asm/virt.h> +#include <asm/kasan.h> #include "atags.h" @@ -763,7 +765,7 @@ int __init arm_add_memory(u64 start, u64 size) #ifndef CONFIG_PHYS_ADDR_T_64BIT if (aligned_start > ULONG_MAX) { pr_crit("Ignoring memory at 0x%08llx outside 32-bit physical address space\n", - (long long)start); + start); return -EINVAL; } @@ -1081,19 +1083,27 @@ void __init hyp_mode_check(void) void __init setup_arch(char **cmdline_p) { - const struct machine_desc *mdesc; + const struct machine_desc *mdesc = NULL; + void *atags_vaddr = NULL; + + if (__atags_pointer) + atags_vaddr = FDT_VIRT_BASE(__atags_pointer); setup_processor(); - mdesc = setup_machine_fdt(__atags_pointer); + if (atags_vaddr) { + mdesc = setup_machine_fdt(atags_vaddr); + if (mdesc) + memblock_reserve(__atags_pointer, + fdt_totalsize(atags_vaddr)); + } if (!mdesc) - mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type); + mdesc = setup_machine_tags(atags_vaddr, __machine_arch_type); if (!mdesc) { early_print("\nError: invalid dtb and unrecognized/unsupported machine ID\n"); early_print(" r1=0x%08x, r2=0x%08x\n", __machine_arch_type, __atags_pointer); if (__atags_pointer) - early_print(" r2[]=%*ph\n", 16, - phys_to_virt(__atags_pointer)); + early_print(" r2[]=%*ph\n", 16, atags_vaddr); dump_machine_table(); } @@ -1126,7 +1136,7 @@ void __init setup_arch(char **cmdline_p) efi_init(); /* * Make sure the calculation for lowmem/highmem is set appropriately - * before reserving/allocating any mmeory + * before reserving/allocating any memory */ adjust_lowmem_bounds(); arm_memblock_init(mdesc); @@ -1136,6 +1146,7 @@ void __init setup_arch(char **cmdline_p) early_ioremap_reset(); paging_init(mdesc); + kasan_init(); request_standard_resources(mdesc); if (mdesc->restart) diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index 5dc8b80bb693..43077e11dafd 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -72,8 +72,9 @@ ENTRY(__cpu_suspend) ldr r3, =sleep_save_sp stmfd sp!, {r0, r1} @ save suspend func arg and pointer ldr r3, [r3, #SLEEP_SAVE_SP_VIRT] - ALT_SMP(ldr r0, =mpidr_hash) + ALT_SMP(W(nop)) @ don't use adr_l inside ALT_SMP() ALT_UP_B(1f) + adr_l r0, mpidr_hash /* This ldmia relies on the memory layout of the mpidr_hash struct */ ldmia r0, {r1, r6-r8} @ r1 = mpidr mask (r6,r7,r8) = l[0,1,2] shifts compute_mpidr_hash r0, r6, r7, r8, r2, r1 @@ -147,9 +148,8 @@ no_hyp: mov r1, #0 ALT_SMP(mrc p15, 0, r0, c0, c0, 5) ALT_UP_B(1f) - adr r2, mpidr_hash_ptr - ldr r3, [r2] - add r2, r2, r3 @ r2 = struct mpidr_hash phys address + adr_l r2, mpidr_hash @ r2 = struct mpidr_hash phys address + /* * This ldmia relies on the memory layout of the mpidr_hash * struct mpidr_hash. @@ -157,10 +157,7 @@ no_hyp: ldmia r2, { r3-r6 } @ r3 = mpidr mask (r4,r5,r6) = l[0,1,2] shifts compute_mpidr_hash r1, r4, r5, r6, r0, r3 1: - adr r0, _sleep_save_sp - ldr r2, [r0] - add r0, r0, r2 - ldr r0, [r0, #SLEEP_SAVE_SP_PHYS] + ldr_l r0, sleep_save_sp + SLEEP_SAVE_SP_PHYS ldr r0, [r0, r1, lsl #2] @ load phys pgd, stack, resume fn @@ -177,12 +174,6 @@ ENDPROC(cpu_resume_arm) ENDPROC(cpu_resume_no_hyp) #endif - .align 2 -_sleep_save_sp: - .long sleep_save_sp - . -mpidr_hash_ptr: - .long mpidr_hash - . @ mpidr_hash struct offset - .data .align 2 .type sleep_save_sp, #object diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 48099c6e1e4a..5c48eb4fd0e5 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -524,14 +524,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } static const char *ipi_types[NR_IPI] __tracepoint_string = { -#define S(x,s) [x] = s - S(IPI_WAKEUP, "CPU wakeup interrupts"), - S(IPI_TIMER, "Timer broadcast interrupts"), - S(IPI_RESCHEDULE, "Rescheduling interrupts"), - S(IPI_CALL_FUNC, "Function call interrupts"), - S(IPI_CPU_STOP, "CPU stop interrupts"), - S(IPI_IRQ_WORK, "IRQ work interrupts"), - S(IPI_COMPLETION, "completion interrupts"), + [IPI_WAKEUP] = "CPU wakeup interrupts", + [IPI_TIMER] = "Timer broadcast interrupts", + [IPI_RESCHEDULE] = "Rescheduling interrupts", + [IPI_CALL_FUNC] = "Function call interrupts", + [IPI_CPU_STOP] = "CPU stop interrupts", + [IPI_IRQ_WORK] = "IRQ work interrupts", + [IPI_COMPLETION] = "completion interrupts", }; static void smp_cross_call(const struct cpumask *target, unsigned int ipinr); @@ -550,7 +549,7 @@ void show_ipi_list(struct seq_file *p, int prec) seq_printf(p, "%*s%u: ", prec - 1, "IPI", i); for_each_online_cpu(cpu) - seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu)); + seq_printf(p, "%10u ", irq_desc_kstat_cpu(ipi_desc[i], cpu)); seq_printf(p, " %s\n", ipi_types[i]); } diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index d2bd0df2318d..59fdf257bf8b 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c @@ -18,9 +18,6 @@ #warning Your compiler does not have EABI support. #warning ARM unwind is known to compile only with EABI compilers. #warning Change compiler or disable ARM_UNWIND option. -#elif (__GNUC__ == 4 && __GNUC_MINOR__ <= 2) && !defined(__clang__) -#warning Your compiler is too buggy; it is known to not compile ARM unwind support. -#warning Change compiler or disable ARM_UNWIND option. #endif #endif /* __CHECKER__ */ @@ -236,7 +233,11 @@ static int unwind_pop_register(struct unwind_ctrl_block *ctrl, if (*vsp >= (unsigned long *)ctrl->sp_high) return -URC_FAILURE; - ctrl->vrs[reg] = *(*vsp)++; + /* Use READ_ONCE_NOCHECK here to avoid this memory access + * from being tracked by KASAN. + */ + ctrl->vrs[reg] = READ_ONCE_NOCHECK(*(*vsp)); + (*vsp)++; return URC_OK; } diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S index 09a333153dc6..e4caf48c089f 100644 --- a/arch/arm/lib/memcpy.S +++ b/arch/arm/lib/memcpy.S @@ -58,10 +58,12 @@ /* Prototype: void *memcpy(void *dest, const void *src, size_t n); */ +ENTRY(__memcpy) ENTRY(mmiocpy) -ENTRY(memcpy) +WEAK(memcpy) #include "copy_template.S" ENDPROC(memcpy) ENDPROC(mmiocpy) +ENDPROC(__memcpy) diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S index b50e5770fb44..6fecc12a1f51 100644 --- a/arch/arm/lib/memmove.S +++ b/arch/arm/lib/memmove.S @@ -24,12 +24,13 @@ * occurring in the opposite direction. */ -ENTRY(memmove) +ENTRY(__memmove) +WEAK(memmove) UNWIND( .fnstart ) subs ip, r0, r1 cmphi r2, ip - bls memcpy + bls __memcpy stmfd sp!, {r0, r4, lr} UNWIND( .fnend ) @@ -222,3 +223,4 @@ ENTRY(memmove) 18: backward_copy_shift push=24 pull=8 ENDPROC(memmove) +ENDPROC(__memmove) diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S index 6ca4535c47fb..9817cb258c1a 100644 --- a/arch/arm/lib/memset.S +++ b/arch/arm/lib/memset.S @@ -13,8 +13,9 @@ .text .align 5 +ENTRY(__memset) ENTRY(mmioset) -ENTRY(memset) +WEAK(memset) UNWIND( .fnstart ) ands r3, r0, #3 @ 1 unaligned? mov ip, r0 @ preserve r0 as return value @@ -132,6 +133,7 @@ UNWIND( .fnstart ) UNWIND( .fnend ) ENDPROC(memset) ENDPROC(mmioset) +ENDPROC(__memset) ENTRY(__memset32) UNWIND( .fnstart ) diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index 700763e07083..25b01da4771b 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -177,7 +177,8 @@ static void __init exynos_dt_machine_init(void) if (of_machine_is_compatible("samsung,exynos4210") || (of_machine_is_compatible("samsung,exynos4412") && (of_machine_is_compatible("samsung,trats2") || - of_machine_is_compatible("samsung,midas"))) || + of_machine_is_compatible("samsung,midas") || + of_machine_is_compatible("samsung,p4note"))) || of_machine_is_compatible("samsung,exynos3250") || of_machine_is_compatible("samsung,exynos5250")) platform_device_register(&exynos_cpuidle); @@ -206,8 +207,8 @@ static void __init exynos_dt_fixup(void) } DT_MACHINE_START(EXYNOS_DT, "Samsung Exynos (Flattened Device Tree)") - .l2c_aux_val = 0x38400000, - .l2c_aux_mask = 0xc60fffff, + .l2c_aux_val = 0x08400000, + .l2c_aux_mask = 0xf60fffff, .smp = smp_ops(exynos_smp_ops), .map_io = exynos_init_io, .init_early = exynos_firmware_init, diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index d7fedbb2eefe..ea0be59f469a 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -215,7 +215,7 @@ void exynos_core_restart(u32 core_id) unsigned int timeout = 16; u32 val; - if (!of_machine_is_compatible("samsung,exynos3250")) + if (!soc_is_exynos3250()) return; while (timeout && !pmu_raw_readl(S5P_PMU_SPARE2)) { diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 85c084a716ab..703998ebb52e 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -245,8 +245,13 @@ static void __init imx6q_axi_init(void) static void __init imx6q_init_machine(void) { - if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_2_0) - imx_print_silicon_rev("i.MX6QP", IMX_CHIP_REVISION_1_0); + if (cpu_is_imx6q() && imx_get_soc_revision() >= IMX_CHIP_REVISION_2_0) + /* + * SoCs that identify as i.MX6Q >= rev 2.0 are really i.MX6QP. + * Quirk: i.MX6QP revision = i.MX6Q revision - (1, 0), + * e.g. i.MX6QP rev 1.1 identifies as i.MX6Q rev 2.1. + */ + imx_print_silicon_rev("i.MX6QP", imx_get_soc_revision() - 0x10); else imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", imx_get_soc_revision()); diff --git a/arch/arm/mach-imx/mach-imx7ulp.c b/arch/arm/mach-imx/mach-imx7ulp.c index 445256e6a4a0..a3c8dadec1c5 100644 --- a/arch/arm/mach-imx/mach-imx7ulp.c +++ b/arch/arm/mach-imx/mach-imx7ulp.c @@ -37,6 +37,7 @@ static void __init imx7ulp_set_revision(void) * bit[31:28] of JTAG_ID register defines revision as below from B0: * 0001 B0 * 0010 B1 + * 0011 B2 */ switch (revision >> 28) { case 1: @@ -45,6 +46,9 @@ static void __init imx7ulp_set_revision(void) case 2: imx_set_soc_revision(IMX_CHIP_REVISION_2_1); break; + case 3: + imx_set_soc_revision(IMX_CHIP_REVISION_2_2); + break; default: imx_set_soc_revision(IMX_CHIP_REVISION_1_0); break; diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c index 09a65c2dfd73..cd711bfc591f 100644 --- a/arch/arm/mach-keystone/keystone.c +++ b/arch/arm/mach-keystone/keystone.c @@ -8,7 +8,7 @@ */ #include <linux/io.h> #include <linux/of.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/init.h> #include <linux/of_platform.h> #include <linux/of_address.h> diff --git a/arch/arm/mach-mstar/mstarv7.c b/arch/arm/mach-mstar/mstarv7.c index 81a4cbcab206..274c4f0df270 100644 --- a/arch/arm/mach-mstar/mstarv7.c +++ b/arch/arm/mach-mstar/mstarv7.c @@ -31,10 +31,18 @@ #define MSTARV7_L3BRIDGE_FLUSH_TRIGGER BIT(0) #define MSTARV7_L3BRIDGE_STATUS_DONE BIT(12) +#ifdef CONFIG_SMP +#define MSTARV7_CPU1_BOOT_ADDR_HIGH 0x4c +#define MSTARV7_CPU1_BOOT_ADDR_LOW 0x50 +#define MSTARV7_CPU1_UNLOCK 0x58 +#define MSTARV7_CPU1_UNLOCK_MAGIC 0xbabe +#endif + static void __iomem *l3bridge; static const char * const mstarv7_board_dt_compat[] __initconst = { "mstar,infinity", + "mstar,infinity2m", "mstar,infinity3", "mstar,mercury5", NULL, @@ -62,6 +70,46 @@ static void mstarv7_mb(void) } } +#ifdef CONFIG_SMP +static int mstarv7_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + struct device_node *np; + u32 bootaddr = (u32) __pa_symbol(secondary_startup_arm); + void __iomem *smpctrl; + + /* + * right now we don't know how to boot anything except + * cpu 1. + */ + if (cpu != 1) + return -EINVAL; + + np = of_find_compatible_node(NULL, NULL, "mstar,smpctrl"); + smpctrl = of_iomap(np, 0); + + if (!smpctrl) + return -ENODEV; + + /* set the boot address for the second cpu */ + writew(bootaddr & 0xffff, smpctrl + MSTARV7_CPU1_BOOT_ADDR_LOW); + writew((bootaddr >> 16) & 0xffff, smpctrl + MSTARV7_CPU1_BOOT_ADDR_HIGH); + + /* unlock the second cpu */ + writew(MSTARV7_CPU1_UNLOCK_MAGIC, smpctrl + MSTARV7_CPU1_UNLOCK); + + /* and away we go...*/ + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); + + iounmap(smpctrl); + + return 0; +} + +static const struct smp_operations __initdata mstarv7_smp_ops = { + .smp_boot_secondary = mstarv7_boot_secondary, +}; +#endif + static void __init mstarv7_init(void) { struct device_node *np; @@ -77,4 +125,5 @@ static void __init mstarv7_init(void) DT_MACHINE_START(MSTARV7_DT, "MStar/Sigmastar Armv7 (Device Tree)") .dt_compat = mstarv7_board_dt_compat, .init_machine = mstarv7_init, + .smp = smp_ops(mstarv7_smp_ops), MACHINE_END diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c index c109f47e9cbc..25c9d184fa4c 100644 --- a/arch/arm/mach-mxs/mach-mxs.c +++ b/arch/arm/mach-mxs/mach-mxs.c @@ -22,6 +22,7 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/time.h> +#include <asm/system_info.h> #include <asm/system_misc.h> #include "pm.h" @@ -51,6 +52,9 @@ #define MXS_CLR_ADDR 0x8 #define MXS_TOG_ADDR 0xc +#define HW_OCOTP_OPS2 19 /* offset 0x150 */ +#define HW_OCOTP_OPS3 20 /* offset 0x160 */ + static u32 chipid; static u32 socid; @@ -379,6 +383,8 @@ static void __init mxs_machine_init(void) struct device *parent; struct soc_device *soc_dev; struct soc_device_attribute *soc_dev_attr; + u64 soc_uid = 0; + const u32 *ocotp = mxs_get_ocotp(); int ret; soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); @@ -394,8 +400,21 @@ static void __init mxs_machine_init(void) soc_dev_attr->soc_id = mxs_get_soc_id(); soc_dev_attr->revision = mxs_get_revision(); + if (socid == HW_DIGCTL_CHIPID_MX23) { + soc_uid = system_serial_low = ocotp[HW_OCOTP_OPS3]; + } else if (socid == HW_DIGCTL_CHIPID_MX28) { + soc_uid = system_serial_high = ocotp[HW_OCOTP_OPS2]; + soc_uid <<= 32; + system_serial_low = ocotp[HW_OCOTP_OPS3]; + soc_uid |= system_serial_low; + } + + if (soc_uid) + soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX", soc_uid); + soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) { + kfree(soc_dev_attr->serial_number); kfree(soc_dev_attr->revision); kfree(soc_dev_attr); return; diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index bd5be82101f3..9d4a0ab50a46 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -612,7 +612,7 @@ int clk_enable(struct clk *clk) unsigned long flags; int ret; - if (clk == NULL || IS_ERR(clk)) + if (IS_ERR_OR_NULL(clk)) return -EINVAL; spin_lock_irqsave(&clockfw_lock, flags); @@ -627,7 +627,7 @@ void clk_disable(struct clk *clk) { unsigned long flags; - if (clk == NULL || IS_ERR(clk)) + if (IS_ERR_OR_NULL(clk)) return; spin_lock_irqsave(&clockfw_lock, flags); @@ -650,7 +650,7 @@ unsigned long clk_get_rate(struct clk *clk) unsigned long flags; unsigned long ret; - if (clk == NULL || IS_ERR(clk)) + if (IS_ERR_OR_NULL(clk)) return 0; spin_lock_irqsave(&clockfw_lock, flags); @@ -670,7 +670,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate) unsigned long flags; long ret; - if (clk == NULL || IS_ERR(clk)) + if (IS_ERR_OR_NULL(clk)) return 0; spin_lock_irqsave(&clockfw_lock, flags); @@ -686,7 +686,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) unsigned long flags; int ret = -EINVAL; - if (clk == NULL || IS_ERR(clk)) + if (IS_ERR_OR_NULL(clk)) return ret; spin_lock_irqsave(&clockfw_lock, flags); @@ -791,7 +791,7 @@ void clk_preinit(struct clk *clk) int clk_register(struct clk *clk) { - if (clk == NULL || IS_ERR(clk)) + if (IS_ERR_OR_NULL(clk)) return -EINVAL; /* @@ -817,7 +817,7 @@ EXPORT_SYMBOL(clk_register); void clk_unregister(struct clk *clk) { - if (clk == NULL || IS_ERR(clk)) + if (IS_ERR_OR_NULL(clk)) return; mutex_lock(&clocks_mutex); diff --git a/arch/arm/mach-omap1/usb.c b/arch/arm/mach-omap1/usb.c index ba8566204ea9..86d3b3c157af 100644 --- a/arch/arm/mach-omap1/usb.c +++ b/arch/arm/mach-omap1/usb.c @@ -9,7 +9,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/io.h> #include <asm/irq.h> diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 164985505f9e..4a59c169a113 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -2,11 +2,15 @@ menu "TI OMAP/AM/DM/DRA Family" depends on ARCH_MULTI_V6 || ARCH_MULTI_V7 +config OMAP_HWMOD + bool + config ARCH_OMAP2 bool "TI OMAP2" depends on ARCH_MULTI_V6 select ARCH_OMAP2PLUS select CPU_V6 + select OMAP_HWMOD select SOC_HAS_OMAP2_SDRC config ARCH_OMAP3 @@ -14,6 +18,7 @@ config ARCH_OMAP3 depends on ARCH_MULTI_V7 select ARCH_OMAP2PLUS select ARM_CPU_SUSPEND if PM + select OMAP_HWMOD select OMAP_INTERCONNECT select PM_OPP if PM select PM if CPU_IDLE @@ -30,6 +35,7 @@ config ARCH_OMAP4 select ARM_GIC select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP + select OMAP_HWMOD select OMAP_INTERCONNECT select OMAP_INTERCONNECT_BARRIER select PL310_ERRATA_588369 if CACHE_L2X0 @@ -49,6 +55,7 @@ config SOC_OMAP5 select HAVE_ARM_SCU if SMP select HAVE_ARM_ARCH_TIMER select ARM_ERRATA_798181 if SMP + select OMAP_HWMOD select OMAP_INTERCONNECT select OMAP_INTERCONNECT_BARRIER select PM_OPP if PM @@ -84,6 +91,7 @@ config SOC_DRA7XX select HAVE_ARM_ARCH_TIMER select IRQ_CROSSBAR select ARM_ERRATA_798181 if SMP + select OMAP_HWMOD select OMAP_INTERCONNECT select OMAP_INTERCONNECT_BARRIER select PM_OPP if PM diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 732e614c56b2..9bcfb34a2206 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -8,20 +8,22 @@ ccflags-y := -I$(srctree)/$(src)/include \ # Common support obj-y := id.o io.o control.o devices.o fb.o pm.o \ - common.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \ - omap_device.o omap-headsmp.o sram.o + common.o dma.o omap-headsmp.o sram.o hwmod-common = omap_hwmod.o omap_hwmod_reset.o \ - omap_hwmod_common_data.o + omap_hwmod_common_data.o \ + omap_hwmod_common_ipblock_data.o \ + omap_device.o display.o hdq1w.o \ + i2c.o wd_timer.o clock-common = clock.o secure-common = omap-smc.o omap-secure.o obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common) obj-$(CONFIG_ARCH_OMAP4) += $(hwmod-common) $(secure-common) -obj-$(CONFIG_SOC_AM33XX) += $(hwmod-common) $(secure-common) +obj-$(CONFIG_SOC_AM33XX) += $(secure-common) obj-$(CONFIG_SOC_OMAP5) += $(hwmod-common) $(secure-common) -obj-$(CONFIG_SOC_AM43XX) += $(hwmod-common) $(secure-common) +obj-$(CONFIG_SOC_AM43XX) += $(secure-common) obj-$(CONFIG_SOC_DRA7XX) += $(hwmod-common) $(secure-common) ifneq ($(CONFIG_SND_SOC_OMAP_MCBSP),) @@ -194,7 +196,6 @@ obj-$(CONFIG_SOC_OMAP2420) += opp2420_data.o obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o # hwmod data -obj-y += omap_hwmod_common_ipblock_data.o obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_ipblock_data.o obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_interconnect_data.o @@ -205,12 +206,6 @@ obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_interconnect_data.o obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2430_data.o obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_ipblock_data.o obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o -obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_data.o -obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_43xx_interconnect_data.o -obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_43xx_ipblock_data.o -obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_43xx_data.o -obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_33xx_43xx_interconnect_data.o -obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_33xx_43xx_ipblock_data.o obj-$(CONFIG_SOC_TI81XX) += omap_hwmod_81xx_data.o obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o obj-$(CONFIG_SOC_OMAP5) += omap_hwmod_54xx_data.o diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c index 2a3e72286d3a..edf046b470ba 100644 --- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c +++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c @@ -235,7 +235,7 @@ void omap2xxx_clkt_vps_init(void) hw = kzalloc(sizeof(*hw), GFP_KERNEL); if (!hw) - goto cleanup; + return; init.name = "virt_prcm_set"; init.ops = &virt_prcm_set_ops; init.parent_names = &parent_name; @@ -244,9 +244,12 @@ void omap2xxx_clkt_vps_init(void) hw->hw.init = &init; clk = clk_register(NULL, &hw->hw); + if (IS_ERR(clk)) { + printk(KERN_ERR "Failed to register clock\n"); + kfree(hw); + return; + } + clkdev_create(clk, "cpufreq_ck", NULL); - return; -cleanup: - kfree(hw); } #endif diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 2000fca6bd4e..6daaa645ae5d 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -385,8 +385,7 @@ int omap_dss_reset(struct omap_hwmod *oh) } for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) - if (oc->_clk) - clk_prepare_enable(oc->_clk); + clk_prepare_enable(oc->_clk); dispc_disable_outputs(); @@ -412,8 +411,7 @@ int omap_dss_reset(struct omap_hwmod *oh) pr_debug("dss_core: softreset done\n"); for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) - if (oc->_clk) - clk_disable_unprepare(oc->_clk); + clk_disable_unprepare(oc->_clk); r = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0; diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 27608d1026cb..060ba6957b7c 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -567,8 +567,6 @@ void __init am33xx_init_early(void) omap2_prcm_base_init(); am33xx_powerdomains_init(); am33xx_clockdomains_init(); - am33xx_hwmod_init(); - omap_hwmod_init_postsetup(); omap_clk_soc_init = am33xx_dt_clk_init; omap_secure_init(); } @@ -590,8 +588,6 @@ void __init am43xx_init_early(void) omap2_prcm_base_init(); am43xx_powerdomains_init(); am43xx_clockdomains_init(); - am43xx_hwmod_init(); - omap_hwmod_init_postsetup(); omap_l2_cache_init(); omap_clk_soc_init = am43xx_dt_clk_init; omap_secure_init(); diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index fc7bb2ca1672..56d6814bec26 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -230,10 +230,12 @@ static int _omap_device_notifier_call(struct notifier_block *nb, break; case BUS_NOTIFY_BIND_DRIVER: od = to_omap_device(pdev); - if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED) && - pm_runtime_status_suspended(dev)) { + if (od) { od->_driver_status = BUS_NOTIFY_BIND_DRIVER; - pm_runtime_set_active(dev); + if (od->_state == OMAP_DEVICE_STATE_ENABLED && + pm_runtime_status_suspended(dev)) { + pm_runtime_set_active(dev); + } } break; case BUS_NOTIFY_ADD_DEVICE: @@ -334,10 +336,9 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev, struct omap_hwmod **hwmods; od = kzalloc(sizeof(struct omap_device), GFP_KERNEL); - if (!od) { - ret = -ENOMEM; + if (!od) goto oda_exit1; - } + od->hwmods_cnt = oh_cnt; hwmods = kmemdup(ohs, sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL); diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 15b29a179c8a..2310cd56e99b 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -627,6 +627,9 @@ static struct clockdomain *_get_clkdm(struct omap_hwmod *oh) { struct clk_hw_omap *clk; + if (!oh) + return NULL; + if (oh->clkdm) { return oh->clkdm; } else if (oh->_clk) { @@ -3677,6 +3680,9 @@ static void __init omap_hwmod_setup_earlycon_flags(void) */ static int __init omap_hwmod_setup_all(void) { + if (!inited) + return 0; + _ensure_mpu_hwmod_is_setup(NULL); omap_hwmod_for_each(_init, NULL); diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h deleted file mode 100644 index e29841072287..000000000000 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright (C) 2013 Texas Instruments Incorporated - * - * Data common for AM335x and AM43x - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_33XX_43XX_COMMON_DATA_H -#define __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_33XX_43XX_COMMON_DATA_H - -extern struct omap_hwmod_ocp_if am33xx_mpu__l3_main; -extern struct omap_hwmod_ocp_if am33xx_l3_main__l3_s; -extern struct omap_hwmod_ocp_if am33xx_l3_s__l4_ls; -extern struct omap_hwmod_ocp_if am33xx_l3_s__l4_wkup; -extern struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr; -extern struct omap_hwmod_ocp_if am33xx_mpu__prcm; -extern struct omap_hwmod_ocp_if am33xx_l3_s__l3_main; -extern struct omap_hwmod_ocp_if am33xx_gfx__l3_main; -extern struct omap_hwmod_ocp_if am33xx_l3_main__gfx; -extern struct omap_hwmod_ocp_if am33xx_l3_s__gpmc; -extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer2; -extern struct omap_hwmod_ocp_if am33xx_l3_main__ocmc; - -extern struct omap_hwmod am33xx_l3_main_hwmod; -extern struct omap_hwmod am33xx_l3_s_hwmod; -extern struct omap_hwmod am33xx_l3_instr_hwmod; -extern struct omap_hwmod am33xx_l4_ls_hwmod; -extern struct omap_hwmod am33xx_l4_wkup_hwmod; -extern struct omap_hwmod am33xx_mpu_hwmod; -extern struct omap_hwmod am33xx_gfx_hwmod; -extern struct omap_hwmod am33xx_prcm_hwmod; -extern struct omap_hwmod am33xx_ocmcram_hwmod; -extern struct omap_hwmod am33xx_smartreflex0_hwmod; -extern struct omap_hwmod am33xx_smartreflex1_hwmod; -extern struct omap_hwmod am33xx_gpmc_hwmod; - -extern struct omap_hwmod_class am33xx_emif_hwmod_class; -extern struct omap_hwmod_class am33xx_l4_hwmod_class; -extern struct omap_hwmod_class am33xx_wkup_m3_hwmod_class; -extern struct omap_hwmod_class am33xx_control_hwmod_class; -extern struct omap_hwmod_class am33xx_timer_hwmod_class; -extern struct omap_hwmod_class am33xx_ehrpwm_hwmod_class; -extern struct omap_hwmod_class am33xx_spi_hwmod_class; - -void omap_hwmod_am33xx_reg(void); -void omap_hwmod_am43xx_reg(void); - -#endif diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c deleted file mode 100644 index ab5146bfe941..000000000000 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * - * Copyright (C) 2013 Texas Instruments Incorporated - * - * Interconnects common for AM335x and AM43x - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <linux/sizes.h> -#include "omap_hwmod.h" -#include "omap_hwmod_33xx_43xx_common_data.h" - -/* mpu -> l3 main */ -struct omap_hwmod_ocp_if am33xx_mpu__l3_main = { - .master = &am33xx_mpu_hwmod, - .slave = &am33xx_l3_main_hwmod, - .clk = "dpll_mpu_m2_ck", - .user = OCP_USER_MPU, -}; - -/* l3 main -> l3 s */ -struct omap_hwmod_ocp_if am33xx_l3_main__l3_s = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_l3_s_hwmod, - .clk = "l3s_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3 s -> l4 per/ls */ -struct omap_hwmod_ocp_if am33xx_l3_s__l4_ls = { - .master = &am33xx_l3_s_hwmod, - .slave = &am33xx_l4_ls_hwmod, - .clk = "l3s_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3 s -> l4 wkup */ -struct omap_hwmod_ocp_if am33xx_l3_s__l4_wkup = { - .master = &am33xx_l3_s_hwmod, - .slave = &am33xx_l4_wkup_hwmod, - .clk = "l3s_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3 main -> l3 instr */ -struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_l3_instr_hwmod, - .clk = "l3s_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* mpu -> prcm */ -struct omap_hwmod_ocp_if am33xx_mpu__prcm = { - .master = &am33xx_mpu_hwmod, - .slave = &am33xx_prcm_hwmod, - .clk = "dpll_mpu_m2_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3 s -> l3 main*/ -struct omap_hwmod_ocp_if am33xx_l3_s__l3_main = { - .master = &am33xx_l3_s_hwmod, - .slave = &am33xx_l3_main_hwmod, - .clk = "l3s_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3s cfg -> gpmc */ -struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = { - .master = &am33xx_l3_s_hwmod, - .slave = &am33xx_gpmc_hwmod, - .clk = "l3s_gclk", - .user = OCP_USER_MPU, -}; - -/* l3 main -> ocmc */ -struct omap_hwmod_ocp_if am33xx_l3_main__ocmc = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_ocmcram_hwmod, - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c deleted file mode 100644 index bcc120ed610a..000000000000 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * - * Copyright (C) 2013 Texas Instruments Incorporated - * - * Hwmod common for AM335x and AM43x - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <linux/types.h> - -#include "omap_hwmod.h" -#include "cm33xx.h" -#include "prm33xx.h" -#include "omap_hwmod_33xx_43xx_common_data.h" -#include "prcm43xx.h" -#include "common.h" - -#define CLKCTRL(oh, clkctrl) ((oh).prcm.omap4.clkctrl_offs = (clkctrl)) -#define RSTCTRL(oh, rstctrl) ((oh).prcm.omap4.rstctrl_offs = (rstctrl)) -#define RSTST(oh, rstst) ((oh).prcm.omap4.rstst_offs = (rstst)) - -/* - * 'l3' class - * instance(s): l3_main, l3_s, l3_instr - */ -static struct omap_hwmod_class am33xx_l3_hwmod_class = { - .name = "l3", -}; - -struct omap_hwmod am33xx_l3_main_hwmod = { - .name = "l3_main", - .class = &am33xx_l3_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* l3_s */ -struct omap_hwmod am33xx_l3_s_hwmod = { - .name = "l3_s", - .class = &am33xx_l3_hwmod_class, - .clkdm_name = "l3s_clkdm", -}; - -/* l3_instr */ -struct omap_hwmod am33xx_l3_instr_hwmod = { - .name = "l3_instr", - .class = &am33xx_l3_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* - * 'l4' class - * instance(s): l4_ls, l4_hs, l4_wkup, l4_fw - */ -struct omap_hwmod_class am33xx_l4_hwmod_class = { - .name = "l4", -}; - -/* l4_ls */ -struct omap_hwmod am33xx_l4_ls_hwmod = { - .name = "l4_ls", - .class = &am33xx_l4_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* l4_wkup */ -struct omap_hwmod am33xx_l4_wkup_hwmod = { - .name = "l4_wkup", - .class = &am33xx_l4_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .flags = HWMOD_INIT_NO_IDLE, - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* - * 'mpu' class - */ -static struct omap_hwmod_class am33xx_mpu_hwmod_class = { - .name = "mpu", -}; - -struct omap_hwmod am33xx_mpu_hwmod = { - .name = "mpu", - .class = &am33xx_mpu_hwmod_class, - .clkdm_name = "mpu_clkdm", - .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "dpll_mpu_m2_ck", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* - * 'wakeup m3' class - * Wakeup controller sub-system under wakeup domain - */ -struct omap_hwmod_class am33xx_wkup_m3_hwmod_class = { - .name = "wkup_m3", -}; - -/* - * 'prcm' class - * power and reset manager (whole prcm infrastructure) - */ -static struct omap_hwmod_class am33xx_prcm_hwmod_class = { - .name = "prcm", -}; - -/* prcm */ -struct omap_hwmod am33xx_prcm_hwmod = { - .name = "prcm", - .class = &am33xx_prcm_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", -}; - -/* - * 'emif' class - * instance(s): emif - */ -static struct omap_hwmod_class_sysconfig am33xx_emif_sysc = { - .rev_offs = 0x0000, -}; - -struct omap_hwmod_class am33xx_emif_hwmod_class = { - .name = "emif", - .sysc = &am33xx_emif_sysc, -}; - - - -/* ocmcram */ -static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = { - .name = "ocmcram", -}; - -struct omap_hwmod am33xx_ocmcram_hwmod = { - .name = "ocmcram", - .class = &am33xx_ocmcram_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* 'smartreflex' class */ -static struct omap_hwmod_class am33xx_smartreflex_hwmod_class = { - .name = "smartreflex", -}; - -/* smartreflex0 */ -struct omap_hwmod am33xx_smartreflex0_hwmod = { - .name = "smartreflex0", - .class = &am33xx_smartreflex_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .main_clk = "smartreflex0_fck", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* smartreflex1 */ -struct omap_hwmod am33xx_smartreflex1_hwmod = { - .name = "smartreflex1", - .class = &am33xx_smartreflex_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .main_clk = "smartreflex1_fck", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* - * 'control' module class - */ -struct omap_hwmod_class am33xx_control_hwmod_class = { - .name = "control", -}; - - -/* gpmc */ -static struct omap_hwmod_class_sysconfig gpmc_sysc = { - .rev_offs = 0x0, - .sysc_offs = 0x10, - .syss_offs = 0x14, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class am33xx_gpmc_hwmod_class = { - .name = "gpmc", - .sysc = &gpmc_sysc, -}; - -struct omap_hwmod am33xx_gpmc_hwmod = { - .name = "gpmc", - .class = &am33xx_gpmc_hwmod_class, - .clkdm_name = "l3s_clkdm", - /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ - .flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS, - .main_clk = "l3s_gclk", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static void omap_hwmod_am33xx_clkctrl(void) -{ - CLKCTRL(am33xx_smartreflex0_hwmod, - AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET); - CLKCTRL(am33xx_smartreflex1_hwmod, - AM33XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET); - CLKCTRL(am33xx_gpmc_hwmod, AM33XX_CM_PER_GPMC_CLKCTRL_OFFSET); - CLKCTRL(am33xx_l4_ls_hwmod, AM33XX_CM_PER_L4LS_CLKCTRL_OFFSET); - CLKCTRL(am33xx_l4_wkup_hwmod, AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET); - CLKCTRL(am33xx_l3_main_hwmod, AM33XX_CM_PER_L3_CLKCTRL_OFFSET); - CLKCTRL(am33xx_mpu_hwmod , AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET); - CLKCTRL(am33xx_l3_instr_hwmod , AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET); - CLKCTRL(am33xx_ocmcram_hwmod , AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET); -} - -void omap_hwmod_am33xx_reg(void) -{ - omap_hwmod_am33xx_clkctrl(); -} - -static void omap_hwmod_am43xx_clkctrl(void) -{ - CLKCTRL(am33xx_smartreflex0_hwmod, - AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET); - CLKCTRL(am33xx_smartreflex1_hwmod, - AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET); - CLKCTRL(am33xx_gpmc_hwmod, AM43XX_CM_PER_GPMC_CLKCTRL_OFFSET); - CLKCTRL(am33xx_l4_ls_hwmod, AM43XX_CM_PER_L4LS_CLKCTRL_OFFSET); - CLKCTRL(am33xx_l4_wkup_hwmod, AM43XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET); - CLKCTRL(am33xx_l3_main_hwmod, AM43XX_CM_PER_L3_CLKCTRL_OFFSET); - CLKCTRL(am33xx_mpu_hwmod , AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET); - CLKCTRL(am33xx_l3_instr_hwmod , AM43XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET); - CLKCTRL(am33xx_ocmcram_hwmod , AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET); -} - -void omap_hwmod_am43xx_reg(void) -{ - omap_hwmod_am43xx_clkctrl(); -} diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c deleted file mode 100644 index b232f6ca6fe3..000000000000 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * omap_hwmod_33xx_data.c: Hardware modules present on the AM33XX chips - * - * Copyright (C) {2012} Texas Instruments Incorporated - https://www.ti.com/ - * - * This file is automatically generated from the AM33XX hardware databases. - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "omap_hwmod.h" -#include "omap_hwmod_common_data.h" - -#include "control.h" -#include "cm33xx.h" -#include "prm33xx.h" -#include "prm-regbits-33xx.h" -#include "omap_hwmod_33xx_43xx_common_data.h" - -/* - * IP blocks - */ - -/* emif */ -static struct omap_hwmod am33xx_emif_hwmod = { - .name = "emif", - .class = &am33xx_emif_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "dpll_ddr_m2_div2_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_EMIF_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* l4_hs */ -static struct omap_hwmod am33xx_l4_hs_hwmod = { - .name = "l4_hs", - .class = &am33xx_l4_hwmod_class, - .clkdm_name = "l4hs_clkdm", - .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "l4hs_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_L4HS_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod_rst_info am33xx_wkup_m3_resets[] = { - { .name = "wkup_m3", .rst_shift = 3, .st_shift = 5 }, -}; - -/* wkup_m3 */ -static struct omap_hwmod am33xx_wkup_m3_hwmod = { - .name = "wkup_m3", - .class = &am33xx_wkup_m3_hwmod_class, - .clkdm_name = "l4_wkup_aon_clkdm", - /* Keep hardreset asserted */ - .flags = HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST, - .main_clk = "dpll_core_m4_div2_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET, - .rstctrl_offs = AM33XX_RM_WKUP_RSTCTRL_OFFSET, - .rstst_offs = AM33XX_RM_WKUP_RSTST_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .rst_lines = am33xx_wkup_m3_resets, - .rst_lines_cnt = ARRAY_SIZE(am33xx_wkup_m3_resets), -}; - - -/* - * Modules omap_hwmod structures - * - * The following IPs are excluded for the moment because: - * - They do not need an explicit SW control using omap_hwmod API. - * - They still need to be validated with the driver - * properly adapted to omap_hwmod / omap_device - * - * - cEFUSE (doesn't fall under any ocp_if) - * - clkdiv32k - * - ocp watch point - */ -#if 0 -/* - * 'cefuse' class - */ -static struct omap_hwmod_class am33xx_cefuse_hwmod_class = { - .name = "cefuse", -}; - -static struct omap_hwmod am33xx_cefuse_hwmod = { - .name = "cefuse", - .class = &am33xx_cefuse_hwmod_class, - .clkdm_name = "l4_cefuse_clkdm", - .main_clk = "cefuse_fck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* - * 'clkdiv32k' class - */ -static struct omap_hwmod_class am33xx_clkdiv32k_hwmod_class = { - .name = "clkdiv32k", -}; - -static struct omap_hwmod am33xx_clkdiv32k_hwmod = { - .name = "clkdiv32k", - .class = &am33xx_clkdiv32k_hwmod_class, - .clkdm_name = "clk_24mhz_clkdm", - .main_clk = "clkdiv32k_ick", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_CLKDIV32K_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* ocpwp */ -static struct omap_hwmod_class am33xx_ocpwp_hwmod_class = { - .name = "ocpwp", -}; - -static struct omap_hwmod am33xx_ocpwp_hwmod = { - .name = "ocpwp", - .class = &am33xx_ocpwp_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_OCPWP_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; -#endif - -/* - * 'debugss' class - * debug sub system - */ -static struct omap_hwmod_opt_clk debugss_opt_clks[] = { - { .role = "dbg_sysclk", .clk = "dbg_sysclk_ck" }, - { .role = "dbg_clka", .clk = "dbg_clka_ck" }, -}; - -static struct omap_hwmod_class am33xx_debugss_hwmod_class = { - .name = "debugss", -}; - -static struct omap_hwmod am33xx_debugss_hwmod = { - .name = "debugss", - .class = &am33xx_debugss_hwmod_class, - .clkdm_name = "l3_aon_clkdm", - .main_clk = "trace_clk_div_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_WKUP_DEBUGSS_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .opt_clks = debugss_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(debugss_opt_clks), -}; - -static struct omap_hwmod am33xx_control_hwmod = { - .name = "control", - .class = &am33xx_control_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "dpll_core_m4_div2_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - - -/* - * Interfaces - */ - -/* l3 main -> emif */ -static struct omap_hwmod_ocp_if am33xx_l3_main__emif = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_emif_hwmod, - .clk = "dpll_core_m4_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3 main -> l4 hs */ -static struct omap_hwmod_ocp_if am33xx_l3_main__l4_hs = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_l4_hs_hwmod, - .clk = "l3s_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* wkup m3 -> l4 wkup */ -static struct omap_hwmod_ocp_if am33xx_wkup_m3__l4_wkup = { - .master = &am33xx_wkup_m3_hwmod, - .slave = &am33xx_l4_wkup_hwmod, - .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4 wkup -> wkup m3 */ -static struct omap_hwmod_ocp_if am33xx_l4_wkup__wkup_m3 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_wkup_m3_hwmod, - .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3_main -> debugss */ -static struct omap_hwmod_ocp_if am33xx_l3_main__debugss = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_debugss_hwmod, - .clk = "dpll_core_m4_ck", - .user = OCP_USER_MPU, -}; - -/* l4 wkup -> smartreflex0 */ -static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex0 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_smartreflex0_hwmod, - .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU, -}; - -/* l4 wkup -> smartreflex1 */ -static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex1 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_smartreflex1_hwmod, - .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU, -}; - -/* l4 wkup -> control */ -static struct omap_hwmod_ocp_if am33xx_l4_wkup__control = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_control_hwmod, - .clk = "dpll_core_m4_div2_ck", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { - &am33xx_l3_main__emif, - &am33xx_mpu__l3_main, - &am33xx_mpu__prcm, - &am33xx_l3_s__l4_ls, - &am33xx_l3_s__l4_wkup, - &am33xx_l3_main__l4_hs, - &am33xx_l3_main__l3_s, - &am33xx_l3_main__l3_instr, - &am33xx_l3_s__l3_main, - &am33xx_wkup_m3__l4_wkup, - &am33xx_l3_main__debugss, - &am33xx_l4_wkup__wkup_m3, - &am33xx_l4_wkup__control, - &am33xx_l4_wkup__smartreflex0, - &am33xx_l4_wkup__smartreflex1, - &am33xx_l3_s__gpmc, - &am33xx_l3_main__ocmc, - NULL, -}; - -int __init am33xx_hwmod_init(void) -{ - omap_hwmod_am33xx_reg(); - omap_hwmod_init(); - return omap_hwmod_register_links(am33xx_hwmod_ocp_ifs); -} diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c deleted file mode 100644 index b97cb745bbbc..000000000000 --- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2013 Texas Instruments Incorporated - * - * Hwmod present only in AM43x and those that differ other than register - * offsets as compared to AM335x. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "omap_hwmod.h" -#include "omap_hwmod_33xx_43xx_common_data.h" -#include "prcm43xx.h" -#include "omap_hwmod_common_data.h" - -/* IP blocks */ -static struct omap_hwmod am43xx_emif_hwmod = { - .name = "emif", - .class = &am33xx_emif_hwmod_class, - .clkdm_name = "emif_clkdm", - .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "dpll_ddr_m2_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod am43xx_l4_hs_hwmod = { - .name = "l4_hs", - .class = &am33xx_l4_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "l4hs_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM43XX_CM_PER_L4HS_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -static struct omap_hwmod_rst_info am33xx_wkup_m3_resets[] = { - { .name = "wkup_m3", .rst_shift = 3, .st_shift = 5 }, -}; - -static struct omap_hwmod am43xx_wkup_m3_hwmod = { - .name = "wkup_m3", - .class = &am33xx_wkup_m3_hwmod_class, - .clkdm_name = "l4_wkup_aon_clkdm", - /* Keep hardreset asserted */ - .flags = HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST, - .main_clk = "sys_clkin_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM43XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET, - .rstctrl_offs = AM43XX_RM_WKUP_RSTCTRL_OFFSET, - .rstst_offs = AM43XX_RM_WKUP_RSTST_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .rst_lines = am33xx_wkup_m3_resets, - .rst_lines_cnt = ARRAY_SIZE(am33xx_wkup_m3_resets), -}; - -static struct omap_hwmod am43xx_control_hwmod = { - .name = "control", - .class = &am33xx_control_hwmod_class, - .clkdm_name = "l4_wkup_clkdm", - .flags = HWMOD_INIT_NO_IDLE, - .main_clk = "sys_clkin_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = AM43XX_CM_WKUP_CONTROL_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* Interfaces */ -static struct omap_hwmod_ocp_if am43xx_l3_main__emif = { - .master = &am33xx_l3_main_hwmod, - .slave = &am43xx_emif_hwmod, - .clk = "dpll_core_m4_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = { - .master = &am33xx_l3_main_hwmod, - .slave = &am43xx_l4_hs_hwmod, - .clk = "l3s_gclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -static struct omap_hwmod_ocp_if am43xx_wkup_m3__l4_wkup = { - .master = &am43xx_wkup_m3_hwmod, - .slave = &am33xx_l4_wkup_hwmod, - .clk = "sys_clkin_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -static struct omap_hwmod_ocp_if am43xx_l4_wkup__wkup_m3 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am43xx_wkup_m3_hwmod, - .clk = "sys_clkin_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -static struct omap_hwmod_ocp_if am43xx_l4_wkup__smartreflex0 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_smartreflex0_hwmod, - .clk = "sys_clkin_ck", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if am43xx_l4_wkup__smartreflex1 = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_smartreflex1_hwmod, - .clk = "sys_clkin_ck", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if am43xx_l4_wkup__control = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am43xx_control_hwmod, - .clk = "sys_clkin_ck", - .user = OCP_USER_MPU, -}; - -static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { - &am33xx_mpu__l3_main, - &am33xx_mpu__prcm, - &am33xx_l3_s__l4_ls, - &am33xx_l3_s__l4_wkup, - &am43xx_l3_main__l4_hs, - &am33xx_l3_main__l3_s, - &am33xx_l3_main__l3_instr, - &am33xx_l3_s__l3_main, - &am43xx_l3_main__emif, - &am43xx_wkup_m3__l4_wkup, - &am43xx_l4_wkup__wkup_m3, - &am43xx_l4_wkup__control, - &am43xx_l4_wkup__smartreflex0, - &am43xx_l4_wkup__smartreflex1, - &am33xx_l3_s__gpmc, - &am33xx_l3_main__ocmc, - NULL, -}; - -int __init am43xx_hwmod_init(void) -{ - int ret; - - omap_hwmod_am43xx_reg(); - omap_hwmod_init(); - ret = omap_hwmod_register_links(am43xx_hwmod_ocp_ifs); - - return ret; -} diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 37c59115b353..6aa3b8e81a0c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -354,42 +354,6 @@ static struct omap_hwmod omap44xx_emif2_hwmod = { }; /* - * 'gpmc' class - * general purpose memory controller - */ - -static struct omap_hwmod_class_sysconfig omap44xx_gpmc_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class omap44xx_gpmc_hwmod_class = { - .name = "gpmc", - .sysc = &omap44xx_gpmc_sysc, -}; - -/* gpmc */ -static struct omap_hwmod omap44xx_gpmc_hwmod = { - .name = "gpmc", - .class = &omap44xx_gpmc_hwmod_class, - .clkdm_name = "l3_2_clkdm", - /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ - .flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS, - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET, - .context_offs = OMAP4_RM_L3_2_GPMC_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, - }, - }, -}; - -/* * 'iss' class * external images sensor pixel data processor */ @@ -441,39 +405,6 @@ static struct omap_hwmod omap44xx_iss_hwmod = { }; /* - * 'iva' class - * multi-standard video encoder/decoder hardware accelerator - */ - -static struct omap_hwmod_class omap44xx_iva_hwmod_class = { - .name = "iva", -}; - -/* iva */ -static struct omap_hwmod_rst_info omap44xx_iva_resets[] = { - { .name = "seq0", .rst_shift = 0 }, - { .name = "seq1", .rst_shift = 1 }, - { .name = "logic", .rst_shift = 2 }, -}; - -static struct omap_hwmod omap44xx_iva_hwmod = { - .name = "iva", - .class = &omap44xx_iva_hwmod_class, - .clkdm_name = "ivahd_clkdm", - .rst_lines = omap44xx_iva_resets, - .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets), - .main_clk = "dpll_iva_m5x2_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET, - .rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET, - .context_offs = OMAP4_RM_IVAHD_IVAHD_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, - }, - }, -}; - -/* * 'mpu' class * mpu sub-system */ @@ -644,14 +575,6 @@ static struct omap_hwmod_ocp_if omap44xx_mpu__dmm = { .user = OCP_USER_MPU, }; -/* iva -> l3_instr */ -static struct omap_hwmod_ocp_if omap44xx_iva__l3_instr = { - .master = &omap44xx_iva_hwmod, - .slave = &omap44xx_l3_instr_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l3_main_3 -> l3_instr */ static struct omap_hwmod_ocp_if omap44xx_l3_main_3__l3_instr = { .master = &omap44xx_l3_main_3_hwmod, @@ -708,14 +631,6 @@ static struct omap_hwmod_ocp_if omap44xx_iss__l3_main_2 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* iva -> l3_main_2 */ -static struct omap_hwmod_ocp_if omap44xx_iva__l3_main_2 = { - .master = &omap44xx_iva_hwmod, - .slave = &omap44xx_l3_main_2_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l3_main_1 -> l3_main_2 */ static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_2 = { .master = &omap44xx_l3_main_1_hwmod, @@ -836,14 +751,6 @@ static struct omap_hwmod_ocp_if omap44xx_l3_instr__debugss = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* l3_main_2 -> gpmc */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpmc = { - .master = &omap44xx_l3_main_2_hwmod, - .slave = &omap44xx_gpmc_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l3_main_2 -> iss */ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iss = { .master = &omap44xx_l3_main_2_hwmod, @@ -852,22 +759,6 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iss = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* iva -> sl2if */ -static struct omap_hwmod_ocp_if __maybe_unused omap44xx_iva__sl2if = { - .master = &omap44xx_iva_hwmod, - .slave = &omap44xx_sl2if_hwmod, - .clk = "dpll_iva_m5x2_ck", - .user = OCP_USER_IVA, -}; - -/* l3_main_2 -> iva */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iva = { - .master = &omap44xx_l3_main_2_hwmod, - .slave = &omap44xx_iva_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU, -}; - /* l3_main_2 -> ocmc_ram */ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__ocmc_ram = { .master = &omap44xx_l3_main_2_hwmod, @@ -943,7 +834,6 @@ static struct omap_hwmod_ocp_if omap44xx_mpu__emif2 = { static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l3_main_1__dmm, &omap44xx_mpu__dmm, - &omap44xx_iva__l3_instr, &omap44xx_l3_main_3__l3_instr, &omap44xx_ocp_wp_noc__l3_instr, &omap44xx_l3_main_2__l3_main_1, @@ -951,7 +841,6 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_mpu__l3_main_1, &omap44xx_debugss__l3_main_2, &omap44xx_iss__l3_main_2, - &omap44xx_iva__l3_main_2, &omap44xx_l3_main_1__l3_main_2, &omap44xx_l4_cfg__l3_main_2, &omap44xx_l3_main_1__l3_main_3, @@ -967,10 +856,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_wkup__ctrl_module_wkup, &omap44xx_l4_wkup__ctrl_module_pad_wkup, &omap44xx_l3_instr__debugss, - &omap44xx_l3_main_2__gpmc, &omap44xx_l3_main_2__iss, - /* &omap44xx_iva__sl2if, */ - &omap44xx_l3_main_2__iva, &omap44xx_l3_main_2__ocmc_ram, &omap44xx_mpu_private__prcm_mpu, &omap44xx_l4_wkup__cm_core_aon, diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index 05e163c8337a..48c2a808bd46 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -243,46 +243,6 @@ static struct omap_hwmod dra7xx_ctrl_module_wkup_hwmod = { }; /* - * 'gpmc' class - * - */ - -static struct omap_hwmod_class_sysconfig dra7xx_gpmc_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, -}; - -static struct omap_hwmod_class dra7xx_gpmc_hwmod_class = { - .name = "gpmc", - .sysc = &dra7xx_gpmc_sysc, -}; - -/* gpmc */ - -static struct omap_hwmod dra7xx_gpmc_hwmod = { - .name = "gpmc", - .class = &dra7xx_gpmc_hwmod_class, - .clkdm_name = "l3main1_clkdm", - /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ - .flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS, - .main_clk = "l3_iclk_div", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_L3MAIN1_GPMC_CLKCTRL_OFFSET, - .context_offs = DRA7XX_RM_L3MAIN1_GPMC_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, - }, - }, -}; - - - -/* * 'mpu' class * */ @@ -611,14 +571,6 @@ static struct omap_hwmod_ocp_if dra7xx_l4_wkup__ctrl_module_wkup = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* l3_main_1 -> gpmc */ -static struct omap_hwmod_ocp_if dra7xx_l3_main_1__gpmc = { - .master = &dra7xx_l3_main_1_hwmod, - .slave = &dra7xx_gpmc_hwmod, - .clk = "l3_iclk_div", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l4_cfg -> mpu */ static struct omap_hwmod_ocp_if dra7xx_l4_cfg__mpu = { .master = &dra7xx_l4_cfg_hwmod, @@ -722,7 +674,6 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { &dra7xx_l4_per2__atl, &dra7xx_l3_main_1__bb2d, &dra7xx_l4_wkup__ctrl_module_wkup, - &dra7xx_l3_main_1__gpmc, &dra7xx_l4_cfg__mpu, &dra7xx_l3_main_1__pciess1, &dra7xx_l4_cfg__pciess1, diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 2a4fe3e68b82..cd38bf07c094 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -94,6 +94,7 @@ static void __init hsmmc2_internal_input_clk(void) omap_ctrl_writel(reg, OMAP343X_CONTROL_DEVCONF1); } +#ifdef CONFIG_OMAP_HWMOD static struct iommu_platform_data omap3_iommu_pdata = { .reset_name = "mmu", .assert_reset = omap_device_assert_hardreset, @@ -106,6 +107,7 @@ static struct iommu_platform_data omap3_iommu_isp_pdata = { .device_enable = omap_device_enable, .device_idle = omap_device_idle, }; +#endif static int omap3_sbc_t3730_twl_callback(struct device *dev, unsigned gpio, @@ -272,14 +274,6 @@ static void __init omap3_pandora_legacy_init(void) } #endif /* CONFIG_ARCH_OMAP3 */ -#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) -static struct wkup_m3_platform_data wkup_m3_data = { - .reset_name = "wkup_m3", - .assert_reset = omap_device_assert_hardreset, - .deassert_reset = omap_device_deassert_hardreset, -}; -#endif - #ifdef CONFIG_SOC_OMAP5 static void __init omap5_uevm_legacy_init(void) { @@ -370,6 +364,7 @@ static void ti_sysc_clkdm_allow_idle(struct device *dev, clkdm_allow_idle(cookie->clkdm); } +#ifdef CONFIG_OMAP_HWMOD static int ti_sysc_enable_module(struct device *dev, const struct ti_sysc_cookie *cookie) { @@ -396,6 +391,7 @@ static int ti_sysc_shutdown_module(struct device *dev, return omap_hwmod_shutdown(cookie->data); } +#endif /* CONFIG_OMAP_HWMOD */ static bool ti_sysc_soc_type_gp(void) { @@ -410,10 +406,12 @@ static struct ti_sysc_platform_data ti_sysc_pdata = { .init_clockdomain = ti_sysc_clkdm_init, .clkdm_deny_idle = ti_sysc_clkdm_deny_idle, .clkdm_allow_idle = ti_sysc_clkdm_allow_idle, +#ifdef CONFIG_OMAP_HWMOD .init_module = omap_hwmod_init_module, .enable_module = ti_sysc_enable_module, .idle_module = ti_sysc_idle_module, .shutdown_module = ti_sysc_shutdown_module, +#endif }; static struct pcs_pdata pcs_pdata; @@ -501,14 +499,6 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = { OF_DEV_AUXDATA("ti,omap3-mcbsp", 0x49024000, "49024000.mcbsp", &mcbsp_pdata), #endif #endif -#ifdef CONFIG_SOC_AM33XX - OF_DEV_AUXDATA("ti,am3352-wkup-m3", 0x44d00000, "44d00000.wkup_m3", - &wkup_m3_data), -#endif -#ifdef CONFIG_SOC_AM43XX - OF_DEV_AUXDATA("ti,am4372-wkup-m3", 0x44d00000, "44d00000.wkup_m3", - &wkup_m3_data), -#endif #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) OF_DEV_AUXDATA("ti,omap4-smartreflex-iva", 0x4a0db000, "4a0db000.smartreflex", &omap_sr_pdata[OMAP_SR_IVA]), @@ -580,6 +570,8 @@ static void pdata_quirks_check(struct pdata_init *quirks) void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table) { + struct device_node *np; + /* * We still need this for omap2420 and omap3 PM to work, others are * using drivers/misc/sram.c already. @@ -591,6 +583,15 @@ void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table) if (of_machine_is_compatible("ti,omap3")) omap3_mcbsp_init(); pdata_quirks_check(auxdata_quirks); + + /* Populate always-on PRCM in l4_wkup to probe l4_wkup */ + np = of_find_node_by_name(NULL, "prcm"); + if (!np) + np = of_find_node_by_name(NULL, "prm"); + if (np) + of_platform_populate(np, omap_dt_match_table, + omap_auxdata_lookup, NULL); + of_platform_populate(NULL, omap_dt_match_table, omap_auxdata_lookup, NULL); pdata_quirks_check(pdata_quirks); diff --git a/arch/arm/mach-omap2/pmic-cpcap.c b/arch/arm/mach-omap2/pmic-cpcap.c index eab281a5fc9f..09076ad0576d 100644 --- a/arch/arm/mach-omap2/pmic-cpcap.c +++ b/arch/arm/mach-omap2/pmic-cpcap.c @@ -71,7 +71,7 @@ static struct omap_voltdm_pmic omap_cpcap_iva = { .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN, .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX, .vddmin = 900000, - .vddmax = 1350000, + .vddmax = 1375000, .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US, .i2c_slave_addr = 0x44, .volt_reg_addr = 0x0, diff --git a/arch/arm/mach-s3c/mach-h1940.c b/arch/arm/mach-s3c/mach-h1940.c index 53d51aa83200..8a43ed1c4c4d 100644 --- a/arch/arm/mach-s3c/mach-h1940.c +++ b/arch/arm/mach-s3c/mach-h1940.c @@ -297,6 +297,15 @@ static const struct s3c_adc_bat_thresh bat_lut_acin[] = { { .volt = 3841, .cur = 0, .level = 0}, }; +static struct gpiod_lookup_table h1940_bat_gpio_table = { + .dev_id = "s3c-adc-battery", + .table = { + /* Charge status S3C2410_GPF(3) */ + GPIO_LOOKUP("GPIOF", 3, "charge-status", GPIO_ACTIVE_LOW), + { }, + }, +}; + static int h1940_bat_init(void) { int ret; @@ -330,8 +339,6 @@ static struct s3c_adc_bat_pdata h1940_bat_cfg = { .exit = h1940_bat_exit, .enable_charger = h1940_enable_charger, .disable_charger = h1940_disable_charger, - .gpio_charge_finished = S3C2410_GPF(3), - .gpio_inverted = 1, .lut_noac = bat_lut_noac, .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac), .lut_acin = bat_lut_acin, @@ -720,6 +727,7 @@ static void __init h1940_init(void) s3c24xx_fb_set_platdata(&h1940_fb_info); gpiod_add_lookup_table(&h1940_mmc_gpio_table); gpiod_add_lookup_table(&h1940_audio_gpio_table); + gpiod_add_lookup_table(&h1940_bat_gpio_table); /* Configure the I2S pins (GPE0...GPE4) in correct mode */ s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), S3C_GPIO_PULL_NONE); diff --git a/arch/arm/mach-s3c/mach-rx1950.c b/arch/arm/mach-s3c/mach-rx1950.c index b9758f0a9a14..6e19add158a9 100644 --- a/arch/arm/mach-s3c/mach-rx1950.c +++ b/arch/arm/mach-s3c/mach-rx1950.c @@ -206,6 +206,15 @@ static const struct s3c_adc_bat_thresh bat_lut_acin[] = { { .volt = 3820, .cur = 0, .level = 0}, }; +static struct gpiod_lookup_table rx1950_bat_gpio_table = { + .dev_id = "s3c-adc-battery", + .table = { + /* Charge status S3C2410_GPF(3) */ + GPIO_LOOKUP("GPIOF", 3, "charge-status", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static int rx1950_bat_init(void) { int ret; @@ -331,7 +340,6 @@ static struct s3c_adc_bat_pdata rx1950_bat_cfg = { .exit = rx1950_bat_exit, .enable_charger = rx1950_enable_charger, .disable_charger = rx1950_disable_charger, - .gpio_charge_finished = S3C2410_GPF(3), .lut_noac = bat_lut_noac, .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac), .lut_acin = bat_lut_acin, @@ -840,6 +848,7 @@ static void __init rx1950_init_machine(void) pwm_add_table(rx1950_pwm_lookup, ARRAY_SIZE(rx1950_pwm_lookup)); gpiod_add_lookup_table(&rx1950_audio_gpio_table); + gpiod_add_lookup_table(&rx1950_bat_gpio_table); /* Configure the I2S pins (GPE0...GPE4) in correct mode */ s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), S3C_GPIO_PULL_NONE); diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index bd3a52fd09ce..d4e89a02c8c8 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c @@ -98,6 +98,26 @@ static struct mcp_plat_data collie_mcp_data = { .codec_pdata = &collie_ucb1x00_data, }; +/* Battery management GPIOs */ +static struct gpiod_lookup_table collie_battery_gpiod_table = { + /* the MCP codec mcp0 has the ucb1x00 as attached device */ + .dev_id = "ucb1x00", + .table = { + /* This is found on the main GPIO on the SA1100 */ + GPIO_LOOKUP("gpio", COLLIE_GPIO_CO, + "main battery full", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio", COLLIE_GPIO_MAIN_BAT_LOW, + "main battery low", GPIO_ACTIVE_HIGH), + /* + * This is GPIO 0 on the Scoop expander, which is registered + * from common/scoop.c with this gpio chip label. + */ + GPIO_LOOKUP("sharp-scoop", 0, + "main charge on", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static int collie_ir_startup(struct device *dev) { int rc = gpio_request(COLLIE_GPIO_IR_ON, "IrDA"); @@ -395,6 +415,7 @@ static void __init collie_init(void) platform_scoop_config = &collie_pcmcia_config; gpiod_add_lookup_table(&collie_power_gpiod_table); + gpiod_add_lookup_table(&collie_battery_gpiod_table); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if (ret) { diff --git a/arch/arm/mach-shmobile/platsmp-scu.c b/arch/arm/mach-shmobile/platsmp-scu.c index fcfcef1d1ae4..3849f71e6e12 100644 --- a/arch/arm/mach-shmobile/platsmp-scu.c +++ b/arch/arm/mach-shmobile/platsmp-scu.c @@ -64,7 +64,7 @@ static int shmobile_smp_scu_psr_core_disabled(int cpu) { unsigned long mask = SCU_PM_POWEROFF << (cpu * 8); - if ((__raw_readl(shmobile_scu_base + 8) & mask) == mask) + if ((readl(shmobile_scu_base + 8) & mask) == mask) return 1; return 0; diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 2bc93f391bcf..02cda9cada4c 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -14,6 +14,8 @@ #include "common.h" +#define HPBREG_BASE 0xfe700000 + #define INT2SMSKCR0 0x82288 /* 0xfe782288 */ #define INT2SMSKCR1 0x8228c /* 0xfe78228c */ @@ -22,19 +24,19 @@ static void __init r8a7778_init_irq_dt(void) { - void __iomem *base = ioremap(0xfe700000, 0x00100000); + void __iomem *base = ioremap(HPBREG_BASE, 0x00100000); BUG_ON(!base); irqchip_init(); /* route all interrupts to ARM */ - __raw_writel(0x73ffffff, base + INT2NTSR0); - __raw_writel(0xffffffff, base + INT2NTSR1); + writel(0x73ffffff, base + INT2NTSR0); + writel(0xffffffff, base + INT2NTSR1); /* unmask all known interrupts in INTCS2 */ - __raw_writel(0x08330773, base + INT2SMSKCR0); - __raw_writel(0x00311110, base + INT2SMSKCR1); + writel(0x08330773, base + INT2SMSKCR0); + writel(0x00311110, base + INT2SMSKCR1); iounmap(base); } diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 86406e3f9b22..b6e282116d66 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -15,53 +15,36 @@ #include "common.h" #include "r8a7779.h" -static struct map_desc r8a7779_io_desc[] __initdata = { - /* 2M identity mapping for 0xf0000000 (MPCORE) */ - { - .virtual = 0xf0000000, - .pfn = __phys_to_pfn(0xf0000000), - .length = SZ_2M, - .type = MT_DEVICE_NONSHARED - }, - /* 16M identity mapping for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */ - { - .virtual = 0xfe000000, - .pfn = __phys_to_pfn(0xfe000000), - .length = SZ_16M, - .type = MT_DEVICE_NONSHARED - }, -}; - -static void __init r8a7779_map_io(void) -{ - debug_ll_io_init(); - iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc)); -} +#define HPBREG_BASE 0xfe700000 /* IRQ */ -#define INT2SMSKCR0 IOMEM(0xfe7822a0) -#define INT2SMSKCR1 IOMEM(0xfe7822a4) -#define INT2SMSKCR2 IOMEM(0xfe7822a8) -#define INT2SMSKCR3 IOMEM(0xfe7822ac) -#define INT2SMSKCR4 IOMEM(0xfe7822b0) +#define INT2SMSKCR0 0x822a0 /* Interrupt Submask Clear Register 0 */ +#define INT2SMSKCR1 0x822a4 /* Interrupt Submask Clear Register 1 */ +#define INT2SMSKCR2 0x822a8 /* Interrupt Submask Clear Register 2 */ +#define INT2SMSKCR3 0x822ac /* Interrupt Submask Clear Register 3 */ +#define INT2SMSKCR4 0x822b0 /* Interrupt Submask Clear Register 4 */ -#define INT2NTSR0 IOMEM(0xfe700060) -#define INT2NTSR1 IOMEM(0xfe700064) +#define INT2NTSR0 0x00060 /* Interrupt Notification Select Register 0 */ +#define INT2NTSR1 0x00064 /* Interrupt Notification Select Register 1 */ static void __init r8a7779_init_irq_dt(void) { + void __iomem *base = ioremap(HPBREG_BASE, 0x00100000); + irqchip_init(); /* route all interrupts to ARM */ - __raw_writel(0xffffffff, INT2NTSR0); - __raw_writel(0x3fffffff, INT2NTSR1); + writel(0xffffffff, base + INT2NTSR0); + writel(0x3fffffff, base + INT2NTSR1); /* unmask all known interrupts in INTCS2 */ - __raw_writel(0xfffffff0, INT2SMSKCR0); - __raw_writel(0xfff7ffff, INT2SMSKCR1); - __raw_writel(0xfffbffdf, INT2SMSKCR2); - __raw_writel(0xbffffffc, INT2SMSKCR3); - __raw_writel(0x003fee3f, INT2SMSKCR4); + writel(0xfffffff0, base + INT2SMSKCR0); + writel(0xfff7ffff, base + INT2SMSKCR1); + writel(0xfffbffdf, base + INT2SMSKCR2); + writel(0xbffffffc, base + INT2SMSKCR3); + writel(0x003fee3f, base + INT2SMSKCR4); + + iounmap(base); } static const char *const r8a7779_compat_dt[] __initconst = { @@ -71,7 +54,6 @@ static const char *const r8a7779_compat_dt[] __initconst = { DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)") .smp = smp_ops(r8a7779_smp_ops), - .map_io = r8a7779_map_io, .init_irq = r8a7779_init_irq_dt, .init_late = shmobile_init_late, .dt_compat = r8a7779_compat_dt, diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index eb4a62fa4289..890bf537b7de 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -22,29 +22,11 @@ #include "common.h" #include "sh73a0.h" -static struct map_desc sh73a0_io_desc[] __initdata = { - /* create a 1:1 identity mapping for 0xe6xxxxxx - * used by CPGA, INTC and PFC. - */ - { - .virtual = 0xe6000000, - .pfn = __phys_to_pfn(0xe6000000), - .length = 256 << 20, - .type = MT_DEVICE_NONSHARED - }, -}; - -static void __init sh73a0_map_io(void) -{ - debug_ll_io_init(); - iotable_init(sh73a0_io_desc, ARRAY_SIZE(sh73a0_io_desc)); -} - static void __init sh73a0_generic_init(void) { #ifdef CONFIG_CACHE_L2X0 /* Shared attribute override enable, 64K*8way */ - l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff); + l2x0_init(ioremap(0xf0100000, PAGE_SIZE), 0x00400000, 0xc20f0fff); #endif } @@ -55,7 +37,6 @@ static const char *const sh73a0_boards_compat_dt[] __initconst = { DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)") .smp = smp_ops(sh73a0_smp_ops), - .map_io = sh73a0_map_io, .init_machine = sh73a0_generic_init, .init_late = shmobile_init_late, .dt_compat = sh73a0_boards_compat_dt, diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index 0ed73b650c14..1bc609986c16 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c @@ -20,8 +20,10 @@ #include "common.h" #include "r8a7779.h" -#define AVECR IOMEM(0xfe700040) -#define R8A7779_SCU_BASE 0xf0000000 +#define HPBREG_BASE 0xfe700000 +#define AVECR 0x0040 /* ARM Reset Vector Address Register */ + +#define R8A7779_SCU_BASE 0xf0000000 static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle) { @@ -36,11 +38,15 @@ static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle) static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) { + void __iomem *base = ioremap(HPBREG_BASE, 0x1000); + /* Map the reset vector (in headsmp-scu.S, headsmp.S) */ - __raw_writel(__pa(shmobile_boot_vector), AVECR); + writel(__pa(shmobile_boot_vector), base + AVECR); /* setup r8a7779 specific SCU bits */ shmobile_smp_scu_prepare_cpus(R8A7779_SCU_BASE, max_cpus); + + iounmap(base); } #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index 0403aa8629dd..453d48865029 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c @@ -16,31 +16,42 @@ #include "common.h" #include "sh73a0.h" -#define WUPCR IOMEM(0xe6151010) -#define SRESCR IOMEM(0xe6151018) -#define PSTR IOMEM(0xe6151040) -#define SBAR IOMEM(0xe6180020) -#define APARMBAREA IOMEM(0xe6f10020) +#define CPG_BASE2 0xe6151000 +#define WUPCR 0x10 /* System-CPU Wake Up Control Register */ +#define SRESCR 0x18 /* System-CPU Software Reset Control Register */ +#define PSTR 0x40 /* System-CPU Power Status Register */ + +#define SYSC_BASE 0xe6180000 +#define SBAR 0x20 /* SYS Boot Address Register */ + +#define AP_BASE 0xe6f10000 +#define APARMBAREA 0x20 /* Address Translation Area Register */ #define SH73A0_SCU_BASE 0xf0000000 static int sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned int lcpu = cpu_logical_map(cpu); + void __iomem *cpg2 = ioremap(CPG_BASE2, PAGE_SIZE); - if (((__raw_readl(PSTR) >> (4 * lcpu)) & 3) == 3) - __raw_writel(1 << lcpu, WUPCR); /* wake up */ + if (((readl(cpg2 + PSTR) >> (4 * lcpu)) & 3) == 3) + writel(1 << lcpu, cpg2 + WUPCR); /* wake up */ else - __raw_writel(1 << lcpu, SRESCR); /* reset */ - + writel(1 << lcpu, cpg2 + SRESCR); /* reset */ + iounmap(cpg2); return 0; } static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) { + void __iomem *ap = ioremap(AP_BASE, PAGE_SIZE); + void __iomem *sysc = ioremap(SYSC_BASE, PAGE_SIZE); + /* Map the reset vector (in headsmp.S) */ - __raw_writel(0, APARMBAREA); /* 4k */ - __raw_writel(__pa(shmobile_boot_vector), SBAR); + writel(0, ap + APARMBAREA); /* 4k */ + writel(__pa(shmobile_boot_vector), sysc + SBAR); + iounmap(sysc); + iounmap(ap); /* setup sh73a0 specific SCU bits */ shmobile_smp_scu_prepare_cpus(SH73A0_SCU_BASE, max_cpus); diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 65e4482e3849..02692fbe2db5 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -743,6 +743,7 @@ config SWP_EMULATE config CPU_BIG_ENDIAN bool "Build big-endian kernel" depends on ARCH_SUPPORTS_BIG_ENDIAN + depends on !LD_IS_LLD help Say Y if you plan on running a kernel in big-endian mode. Note that your board must be properly built and your board diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index c4ce477c5261..3510503bc5e6 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -7,6 +7,7 @@ obj-y := extable.o fault.o init.o iomap.o obj-y += dma-mapping$(MMUEXT).o obj-$(CONFIG_MMU) += fault-armv.o flush.o idmap.o ioremap.o \ mmap.o pgd.o mmu.o pageattr.o +KASAN_SANITIZE_mmu.o := n ifneq ($(CONFIG_MMU),y) obj-y += nommu.o @@ -16,6 +17,7 @@ endif obj-$(CONFIG_ARM_PTDUMP_CORE) += dump.o obj-$(CONFIG_ARM_PTDUMP_DEBUGFS) += ptdump_debugfs.o obj-$(CONFIG_MODULES) += proc-syms.o +KASAN_SANITIZE_physaddr.o := n obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o @@ -110,3 +112,6 @@ obj-$(CONFIG_CACHE_L2X0_PMU) += cache-l2x0-pmu.o obj-$(CONFIG_CACHE_XSC3L2) += cache-xsc3l2.o obj-$(CONFIG_CACHE_TAUROS2) += cache-tauros2.o obj-$(CONFIG_CACHE_UNIPHIER) += cache-uniphier.o + +KASAN_SANITIZE_kasan_init.o := n +obj-$(CONFIG_KASAN) += kasan_init.o diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index db623d7c30de..828a2561b229 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -223,7 +223,6 @@ void __init arm_memblock_init(const struct machine_desc *mdesc) if (mdesc->reserve) mdesc->reserve(); - early_init_fdt_reserve_self(); early_init_fdt_scan_reserved_mem(); /* reserve memory for DMA contiguous allocations */ diff --git a/arch/arm/mm/kasan_init.c b/arch/arm/mm/kasan_init.c new file mode 100644 index 000000000000..9c348042a724 --- /dev/null +++ b/arch/arm/mm/kasan_init.c @@ -0,0 +1,291 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * This file contains kasan initialization code for ARM. + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com> + * Author: Linus Walleij <linus.walleij@linaro.org> + */ + +#define pr_fmt(fmt) "kasan: " fmt +#include <linux/kasan.h> +#include <linux/kernel.h> +#include <linux/memblock.h> +#include <linux/sched/task.h> +#include <linux/start_kernel.h> +#include <linux/pgtable.h> +#include <asm/cputype.h> +#include <asm/highmem.h> +#include <asm/mach/map.h> +#include <asm/memory.h> +#include <asm/page.h> +#include <asm/pgalloc.h> +#include <asm/procinfo.h> +#include <asm/proc-fns.h> + +#include "mm.h" + +static pgd_t tmp_pgd_table[PTRS_PER_PGD] __initdata __aligned(PGD_SIZE); + +pmd_t tmp_pmd_table[PTRS_PER_PMD] __page_aligned_bss; + +static __init void *kasan_alloc_block(size_t size) +{ + return memblock_alloc_try_nid(size, size, __pa(MAX_DMA_ADDRESS), + MEMBLOCK_ALLOC_KASAN, NUMA_NO_NODE); +} + +static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr, + unsigned long end, bool early) +{ + unsigned long next; + pte_t *ptep = pte_offset_kernel(pmdp, addr); + + do { + pte_t entry; + void *p; + + next = addr + PAGE_SIZE; + + if (!early) { + if (!pte_none(READ_ONCE(*ptep))) + continue; + + p = kasan_alloc_block(PAGE_SIZE); + if (!p) { + panic("%s failed to allocate shadow page for address 0x%lx\n", + __func__, addr); + return; + } + memset(p, KASAN_SHADOW_INIT, PAGE_SIZE); + entry = pfn_pte(virt_to_pfn(p), + __pgprot(pgprot_val(PAGE_KERNEL))); + } else if (pte_none(READ_ONCE(*ptep))) { + /* + * The early shadow memory is mapping all KASan + * operations to one and the same page in memory, + * "kasan_early_shadow_page" so that the instrumentation + * will work on a scratch area until we can set up the + * proper KASan shadow memory. + */ + entry = pfn_pte(virt_to_pfn(kasan_early_shadow_page), + __pgprot(_L_PTE_DEFAULT | L_PTE_DIRTY | L_PTE_XN)); + } else { + /* + * Early shadow mappings are PMD_SIZE aligned, so if the + * first entry is already set, they must all be set. + */ + return; + } + + set_pte_at(&init_mm, addr, ptep, entry); + } while (ptep++, addr = next, addr != end); +} + +/* + * The pmd (page middle directory) is only used on LPAE + */ +static void __init kasan_pmd_populate(pud_t *pudp, unsigned long addr, + unsigned long end, bool early) +{ + unsigned long next; + pmd_t *pmdp = pmd_offset(pudp, addr); + + do { + if (pmd_none(*pmdp)) { + /* + * We attempt to allocate a shadow block for the PMDs + * used by the PTEs for this address if it isn't already + * allocated. + */ + void *p = early ? kasan_early_shadow_pte : + kasan_alloc_block(PAGE_SIZE); + + if (!p) { + panic("%s failed to allocate shadow block for address 0x%lx\n", + __func__, addr); + return; + } + pmd_populate_kernel(&init_mm, pmdp, p); + flush_pmd_entry(pmdp); + } + + next = pmd_addr_end(addr, end); + kasan_pte_populate(pmdp, addr, next, early); + } while (pmdp++, addr = next, addr != end); +} + +static void __init kasan_pgd_populate(unsigned long addr, unsigned long end, + bool early) +{ + unsigned long next; + pgd_t *pgdp; + p4d_t *p4dp; + pud_t *pudp; + + pgdp = pgd_offset_k(addr); + + do { + /* + * Allocate and populate the shadow block of p4d folded into + * pud folded into pmd if it doesn't already exist + */ + if (!early && pgd_none(*pgdp)) { + void *p = kasan_alloc_block(PAGE_SIZE); + + if (!p) { + panic("%s failed to allocate shadow block for address 0x%lx\n", + __func__, addr); + return; + } + pgd_populate(&init_mm, pgdp, p); + } + + next = pgd_addr_end(addr, end); + /* + * We just immediately jump over the p4d and pud page + * directories since we believe ARM32 will never gain four + * nor five level page tables. + */ + p4dp = p4d_offset(pgdp, addr); + pudp = pud_offset(p4dp, addr); + + kasan_pmd_populate(pudp, addr, next, early); + } while (pgdp++, addr = next, addr != end); +} + +extern struct proc_info_list *lookup_processor_type(unsigned int); + +void __init kasan_early_init(void) +{ + struct proc_info_list *list; + + /* + * locate processor in the list of supported processor + * types. The linker builds this table for us from the + * entries in arch/arm/mm/proc-*.S + */ + list = lookup_processor_type(read_cpuid_id()); + if (list) { +#ifdef MULTI_CPU + processor = *list->proc; +#endif + } + + BUILD_BUG_ON((KASAN_SHADOW_END - (1UL << 29)) != KASAN_SHADOW_OFFSET); + /* + * We walk the page table and set all of the shadow memory to point + * to the scratch page. + */ + kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, true); +} + +static void __init clear_pgds(unsigned long start, + unsigned long end) +{ + for (; start && start < end; start += PMD_SIZE) + pmd_clear(pmd_off_k(start)); +} + +static int __init create_mapping(void *start, void *end) +{ + void *shadow_start, *shadow_end; + + shadow_start = kasan_mem_to_shadow(start); + shadow_end = kasan_mem_to_shadow(end); + + pr_info("Mapping kernel virtual memory block: %px-%px at shadow: %px-%px\n", + start, end, shadow_start, shadow_end); + + kasan_pgd_populate((unsigned long)shadow_start & PAGE_MASK, + PAGE_ALIGN((unsigned long)shadow_end), false); + return 0; +} + +void __init kasan_init(void) +{ + phys_addr_t pa_start, pa_end; + u64 i; + + /* + * We are going to perform proper setup of shadow memory. + * + * At first we should unmap early shadow (clear_pgds() call bellow). + * However, instrumented code can't execute without shadow memory. + * + * To keep the early shadow memory MMU tables around while setting up + * the proper shadow memory, we copy swapper_pg_dir (the initial page + * table) to tmp_pgd_table and use that to keep the early shadow memory + * mapped until the full shadow setup is finished. Then we swap back + * to the proper swapper_pg_dir. + */ + + memcpy(tmp_pgd_table, swapper_pg_dir, sizeof(tmp_pgd_table)); +#ifdef CONFIG_ARM_LPAE + /* We need to be in the same PGD or this won't work */ + BUILD_BUG_ON(pgd_index(KASAN_SHADOW_START) != + pgd_index(KASAN_SHADOW_END)); + memcpy(tmp_pmd_table, + pgd_page_vaddr(*pgd_offset_k(KASAN_SHADOW_START)), + sizeof(tmp_pmd_table)); + set_pgd(&tmp_pgd_table[pgd_index(KASAN_SHADOW_START)], + __pgd(__pa(tmp_pmd_table) | PMD_TYPE_TABLE | L_PGD_SWAPPER)); +#endif + cpu_switch_mm(tmp_pgd_table, &init_mm); + local_flush_tlb_all(); + + clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END); + + kasan_populate_early_shadow(kasan_mem_to_shadow((void *)VMALLOC_START), + kasan_mem_to_shadow((void *)-1UL) + 1); + + for_each_mem_range(i, &pa_start, &pa_end) { + void *start = __va(pa_start); + void *end = __va(pa_end); + + /* Do not attempt to shadow highmem */ + if (pa_start >= arm_lowmem_limit) { + pr_info("Skip highmem block at %pa-%pa\n", &pa_start, &pa_end); + continue; + } + if (pa_end > arm_lowmem_limit) { + pr_info("Truncating shadow for memory block at %pa-%pa to lowmem region at %pa\n", + &pa_start, &pa_end, &arm_lowmem_limit); + end = __va(arm_lowmem_limit); + } + if (start >= end) { + pr_info("Skipping invalid memory block %pa-%pa (virtual %p-%p)\n", + &pa_start, &pa_end, start, end); + continue; + } + + create_mapping(start, end); + } + + /* + * 1. The module global variables are in MODULES_VADDR ~ MODULES_END, + * so we need to map this area. + * 2. PKMAP_BASE ~ PKMAP_BASE+PMD_SIZE's shadow and MODULES_VADDR + * ~ MODULES_END's shadow is in the same PMD_SIZE, so we can't + * use kasan_populate_zero_shadow. + */ + create_mapping((void *)MODULES_VADDR, (void *)(PKMAP_BASE + PMD_SIZE)); + + /* + * KAsan may reuse the contents of kasan_early_shadow_pte directly, so + * we should make sure that it maps the zero page read-only. + */ + for (i = 0; i < PTRS_PER_PTE; i++) + set_pte_at(&init_mm, KASAN_SHADOW_START + i*PAGE_SIZE, + &kasan_early_shadow_pte[i], + pfn_pte(virt_to_pfn(kasan_early_shadow_page), + __pgprot(pgprot_val(PAGE_KERNEL) + | L_PTE_RDONLY))); + + cpu_switch_mm(swapper_pg_dir, &init_mm); + local_flush_tlb_all(); + + memset(kasan_early_shadow_page, 0, PAGE_SIZE); + pr_info("Kernel address sanitizer initialized\n"); + init_task.kasan_depth = 0; +} diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index b8d912ac9e61..a0f8a0ca0788 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -165,25 +165,3 @@ int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) { return (pfn + (size >> PAGE_SHIFT)) <= (1 + (PHYS_MASK >> PAGE_SHIFT)); } - -#ifdef CONFIG_STRICT_DEVMEM - -#include <linux/ioport.h> - -/* - * devmem_is_allowed() checks to see if /dev/mem access to a certain - * address is valid. The argument is a physical page number. - * We mimic x86 here by disallowing access to system RAM as well as - * device-exclusive MMIO regions. This effectively disable read()/write() - * on /dev/mem. - */ -int devmem_is_allowed(unsigned long pfn) -{ - if (iomem_is_exclusive(pfn << PAGE_SHIFT)) - return 0; - if (!page_is_ram(pfn)) - return 1; - return 0; -} - -#endif diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index ab69250a86bc..c06ebfbc48c4 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -29,6 +29,7 @@ #include <asm/procinfo.h> #include <asm/memory.h> #include <asm/pgalloc.h> +#include <asm/kasan_def.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -39,6 +40,8 @@ #include "mm.h" #include "tcm.h" +extern unsigned long __atags_pointer; + /* * empty_zero_page is a special page that is used for * zero-initialized data and COW. @@ -946,7 +949,7 @@ static void __init create_mapping(struct map_desc *md) return; } - if ((md->type == MT_DEVICE || md->type == MT_ROM) && + if (md->type == MT_DEVICE && md->virtual >= PAGE_OFFSET && md->virtual < FIXADDR_START && (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) { pr_warn("BUG: mapping for 0x%08llx at 0x%08lx out of vmalloc space\n", @@ -1253,8 +1256,25 @@ static inline void prepare_page_table(void) /* * Clear out all the mappings below the kernel image. */ +#ifdef CONFIG_KASAN + /* + * KASan's shadow memory inserts itself between the TASK_SIZE + * and MODULES_VADDR. Do not clear the KASan shadow memory mappings. + */ + for (addr = 0; addr < KASAN_SHADOW_START; addr += PMD_SIZE) + pmd_clear(pmd_off_k(addr)); + /* + * Skip over the KASan shadow area. KASAN_SHADOW_END is sometimes + * equal to MODULES_VADDR and then we exit the pmd clearing. If we + * are using a thumb-compiled kernel, there there will be 8MB more + * to clear as KASan always offset to 16 MB below MODULES_VADDR. + */ + for (addr = KASAN_SHADOW_END; addr < MODULES_VADDR; addr += PMD_SIZE) + pmd_clear(pmd_off_k(addr)); +#else for (addr = 0; addr < MODULES_VADDR; addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); +#endif #ifdef CONFIG_XIP_KERNEL /* The XIP kernel is mapped in the module area -- skip over it */ @@ -1333,6 +1353,15 @@ static void __init devicemaps_init(const struct machine_desc *mdesc) for (addr = VMALLOC_START; addr < (FIXADDR_TOP & PMD_MASK); addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); + if (__atags_pointer) { + /* create a read-only mapping of the device tree */ + map.pfn = __phys_to_pfn(__atags_pointer & SECTION_MASK); + map.virtual = FDT_FIXED_BASE; + map.length = FDT_FIXED_SIZE; + map.type = MT_ROM; + create_mapping(&map); + } + /* * Map the kernel if it is XIP. * It is always first in the modulearea. @@ -1489,8 +1518,7 @@ static void __init map_lowmem(void) } #ifdef CONFIG_ARM_PV_FIXUP -extern unsigned long __atags_pointer; -typedef void pgtables_remap(long long offset, unsigned long pgd, void *bdata); +typedef void pgtables_remap(long long offset, unsigned long pgd); pgtables_remap lpae_pgtables_remap_asm; /* @@ -1503,7 +1531,6 @@ static void __init early_paging_init(const struct machine_desc *mdesc) unsigned long pa_pgd; unsigned int cr, ttbcr; long long offset; - void *boot_data; if (!mdesc->pv_fixup) return; @@ -1520,7 +1547,6 @@ static void __init early_paging_init(const struct machine_desc *mdesc) */ lpae_pgtables_remap = (pgtables_remap *)(unsigned long)__pa(lpae_pgtables_remap_asm); pa_pgd = __pa(swapper_pg_dir); - boot_data = __va(__atags_pointer); barrier(); pr_info("Switching physical address space to 0x%08llx\n", @@ -1556,7 +1582,7 @@ static void __init early_paging_init(const struct machine_desc *mdesc) * needs to be assembly. It's fairly simple, as we're using the * temporary tables setup by the initial assembly code. */ - lpae_pgtables_remap(offset, pa_pgd, boot_data); + lpae_pgtables_remap(offset, pa_pgd); /* Re-enable the caches and cacheable TLB walks */ asm volatile("mcr p15, 0, %0, c2, c0, 2" : : "r" (ttbcr)); diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index c5e1b27046a8..f8e9bc58a84f 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c @@ -66,7 +66,21 @@ pgd_t *pgd_alloc(struct mm_struct *mm) new_pmd = pmd_alloc(mm, new_pud, 0); if (!new_pmd) goto no_pmd; -#endif +#ifdef CONFIG_KASAN + /* + * Copy PMD table for KASAN shadow mappings. + */ + init_pgd = pgd_offset_k(TASK_SIZE); + init_p4d = p4d_offset(init_pgd, TASK_SIZE); + init_pud = pud_offset(init_p4d, TASK_SIZE); + init_pmd = pmd_offset(init_pud, TASK_SIZE); + new_pmd = pmd_offset(new_pud, TASK_SIZE); + memcpy(new_pmd, init_pmd, + (pmd_index(MODULES_VADDR) - pmd_index(TASK_SIZE)) + * sizeof(pmd_t)); + clean_dcache_area(new_pmd, PTRS_PER_PMD * sizeof(pmd_t)); +#endif /* CONFIG_KASAN */ +#endif /* CONFIG_LPAE */ if (!vectors_high()) { /* diff --git a/arch/arm/mm/pv-fixup-asm.S b/arch/arm/mm/pv-fixup-asm.S index 8eade0416739..5c5e1952000a 100644 --- a/arch/arm/mm/pv-fixup-asm.S +++ b/arch/arm/mm/pv-fixup-asm.S @@ -39,8 +39,8 @@ ENTRY(lpae_pgtables_remap_asm) /* Update level 2 entries for the boot data */ add r7, r2, #0x1000 - add r7, r7, r3, lsr #SECTION_SHIFT - L2_ORDER - bic r7, r7, #(1 << L2_ORDER) - 1 + movw r3, #FDT_FIXED_BASE >> (SECTION_SHIFT - L2_ORDER) + add r7, r7, r3 ldrd r4, r5, [r7] adds r4, r4, r0 adc r5, r5, r1 diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl index d056a548358e..20e1170e2e0a 100644 --- a/arch/arm/tools/syscall.tbl +++ b/arch/arm/tools/syscall.tbl @@ -454,3 +454,4 @@ 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 440 common process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile index 150ce6e6a5d3..b558bee0e1f6 100644 --- a/arch/arm/vdso/Makefile +++ b/arch/arm/vdso/Makefile @@ -42,6 +42,8 @@ GCOV_PROFILE := n # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. KCOV_INSTRUMENT := n +KASAN_SANITIZE := n + # Force dependency $(obj)/vdso.o : $(obj)/vdso.so diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index 0186cf9da890..27b0a1f27fbd 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S @@ -37,20 +37,3 @@ ENDPROC(vfp_null_entry) .align 2 .LCvfp: .word vfp_vector - -@ This code is called if the VFP does not exist. It needs to flag the -@ failure to the VFP initialisation code. - - __INIT -ENTRY(vfp_testing_entry) - dec_preempt_count_ti r10, r4 - ldr r0, VFP_arch_address - str r0, [r0] @ set to non-zero value - ret r9 @ we have handled the fault -ENDPROC(vfp_testing_entry) - - .align 2 -VFP_arch_address: - .word VFP_arch - - __FINIT diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 4fcff9f59947..d5837bf05a9a 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -79,11 +79,6 @@ ENTRY(vfp_support_entry) DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10 .fpu vfpv2 - ldr r3, [sp, #S_PSR] @ Neither lazy restore nor FP exceptions - and r3, r3, #MODE_MASK @ are supported in kernel mode - teq r3, #USR_MODE - bne vfp_kmode_exception @ Returns through lr - VFPFMRX r1, FPEXC @ Is the VFP enabled? DBGSTR1 "fpexc %08x", r1 tst r1, #FPEXC_EN diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 8c9e7f9f0277..2cb355c1b5b7 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -23,6 +23,7 @@ #include <asm/cputype.h> #include <asm/system_info.h> #include <asm/thread_notify.h> +#include <asm/traps.h> #include <asm/vfp.h> #include "vfpinstr.h" @@ -31,7 +32,6 @@ /* * Our undef handlers (in entry.S) */ -asmlinkage void vfp_testing_entry(void); asmlinkage void vfp_support_entry(void); asmlinkage void vfp_null_entry(void); @@ -42,7 +42,7 @@ asmlinkage void (*vfp_vector)(void) = vfp_null_entry; * Used in startup: set to non-zero if VFP checks fail * After startup, holds VFP architecture */ -unsigned int VFP_arch; +static unsigned int __initdata VFP_arch; /* * The pointer to the vfpstate structure of the thread which currently @@ -436,7 +436,7 @@ static void vfp_enable(void *unused) * present on all CPUs within a SMP complex. Needs to be called prior to * vfp_init(). */ -void vfp_disable(void) +void __init vfp_disable(void) { if (VFP_arch) { pr_debug("%s: should be called prior to vfp_init\n", __func__); @@ -642,7 +642,9 @@ static int vfp_starting_cpu(unsigned int unused) return 0; } -void vfp_kmode_exception(void) +#ifdef CONFIG_KERNEL_MODE_NEON + +static int vfp_kmode_exception(struct pt_regs *regs, unsigned int instr) { /* * If we reach this point, a floating point exception has been raised @@ -660,9 +662,51 @@ void vfp_kmode_exception(void) pr_crit("BUG: unsupported FP instruction in kernel mode\n"); else pr_crit("BUG: FP instruction issued in kernel mode with FP unit disabled\n"); + pr_crit("FPEXC == 0x%08x\n", fmrx(FPEXC)); + return 1; } -#ifdef CONFIG_KERNEL_MODE_NEON +static struct undef_hook vfp_kmode_exception_hook[] = {{ + .instr_mask = 0xfe000000, + .instr_val = 0xf2000000, + .cpsr_mask = MODE_MASK | PSR_T_BIT, + .cpsr_val = SVC_MODE, + .fn = vfp_kmode_exception, +}, { + .instr_mask = 0xff100000, + .instr_val = 0xf4000000, + .cpsr_mask = MODE_MASK | PSR_T_BIT, + .cpsr_val = SVC_MODE, + .fn = vfp_kmode_exception, +}, { + .instr_mask = 0xef000000, + .instr_val = 0xef000000, + .cpsr_mask = MODE_MASK | PSR_T_BIT, + .cpsr_val = SVC_MODE | PSR_T_BIT, + .fn = vfp_kmode_exception, +}, { + .instr_mask = 0xff100000, + .instr_val = 0xf9000000, + .cpsr_mask = MODE_MASK | PSR_T_BIT, + .cpsr_val = SVC_MODE | PSR_T_BIT, + .fn = vfp_kmode_exception, +}, { + .instr_mask = 0x0c000e00, + .instr_val = 0x0c000a00, + .cpsr_mask = MODE_MASK, + .cpsr_val = SVC_MODE, + .fn = vfp_kmode_exception, +}}; + +static int __init vfp_kmode_exception_hook_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(vfp_kmode_exception_hook); i++) + register_undef_hook(&vfp_kmode_exception_hook[i]); + return 0; +} +subsys_initcall(vfp_kmode_exception_hook_init); /* * Kernel-side NEON support functions @@ -708,6 +752,21 @@ EXPORT_SYMBOL(kernel_neon_end); #endif /* CONFIG_KERNEL_MODE_NEON */ +static int __init vfp_detect(struct pt_regs *regs, unsigned int instr) +{ + VFP_arch = UINT_MAX; /* mark as not present */ + regs->ARM_pc += 4; + return 0; +} + +static struct undef_hook vfp_detect_hook __initdata = { + .instr_mask = 0x0c000e00, + .instr_val = 0x0c000a00, + .cpsr_mask = MODE_MASK, + .cpsr_val = SVC_MODE, + .fn = vfp_detect, +}; + /* * VFP support code initialisation. */ @@ -728,10 +787,11 @@ static int __init vfp_init(void) * The handler is already setup to just log calls, so * we just need to read the VFPSID register. */ - vfp_vector = vfp_testing_entry; + register_undef_hook(&vfp_detect_hook); barrier(); vfpsid = fmrx(FPSID); barrier(); + unregister_undef_hook(&vfp_detect_hook); vfp_vector = vfp_null_entry; pr_info("VFP support v0.3: "); diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 60e901cd0de6..5a957a9a0984 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -371,7 +371,7 @@ static int __init xen_guest_init(void) } gnttab_init(); if (!xen_initial_domain()) - xenbus_probe(NULL); + xenbus_probe(); /* * Making sure board specific code will not set up ops for diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 9f0139ba8a1d..f39568b28ec1 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -13,7 +13,6 @@ config ARM64 select ARCH_BINFMT_ELF_STATE select ARCH_HAS_DEBUG_VIRTUAL select ARCH_HAS_DEBUG_VM_PGTABLE - select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_DMA_PREP_COHERENT select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI select ARCH_HAS_FAST_MULTIPLIER @@ -113,6 +112,7 @@ config ARM64 select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW select GENERIC_IRQ_SHOW_LEVEL + select GENERIC_LIB_DEVMEM_IS_ALLOWED select GENERIC_PCI_IOMAP select GENERIC_PTDUMP select GENERIC_SCHED_CLOCK @@ -137,6 +137,7 @@ config ARM64 select HAVE_ARCH_JUMP_LABEL_RELATIVE select HAVE_ARCH_KASAN if !(ARM64_16K_PAGES && ARM64_VA_BITS_48) select HAVE_ARCH_KASAN_SW_TAGS if HAVE_ARCH_KASAN + select HAVE_ARCH_KASAN_HW_TAGS if (HAVE_ARCH_KASAN && ARM64_MTE) select HAVE_ARCH_KGDB select HAVE_ARCH_MMAP_RND_BITS select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT @@ -173,8 +174,6 @@ config ARM64 select HAVE_NMI select HAVE_PATA_PLATFORM select HAVE_PERF_EVENTS - select HAVE_PERF_EVENTS_NMI if ARM64_PSEUDO_NMI && HW_PERF_EVENTS - select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP select HAVE_REGS_AND_STACK_ACCESS_API @@ -334,7 +333,7 @@ config BROKEN_GAS_INST config KASAN_SHADOW_OFFSET hex - depends on KASAN + depends on KASAN_GENERIC || KASAN_SW_TAGS default 0xdfff800000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && !KASAN_SW_TAGS default 0xdfffc00000000000 if ARM64_VA_BITS_47 && !KASAN_SW_TAGS default 0xdffffe0000000000 if ARM64_VA_BITS_42 && !KASAN_SW_TAGS @@ -1571,6 +1570,9 @@ endmenu menu "ARMv8.5 architectural features" +config AS_HAS_ARMV8_5 + def_bool $(cc-option,-Wa$(comma)-march=armv8.5-a) + config ARM64_BTI bool "Branch Target Identification support" default y @@ -1645,6 +1647,9 @@ config ARM64_MTE bool "Memory Tagging Extension support" default y depends on ARM64_AS_HAS_MTE && ARM64_TAGGED_ADDR_ABI + depends on AS_HAS_ARMV8_5 + # Required for tag checking in the uaccess routines + depends on ARM64_PAN select ARCH_USES_HIGH_VMA_FLAGS help Memory Tagging (part of the ARMv8.5 Extensions) provides @@ -1870,6 +1875,7 @@ config EFI select EFI_RUNTIME_WRAPPERS select EFI_STUB select EFI_GENERIC_STUB + imply IMA_SECURE_AND_OR_TRUSTED_BOOT default y help This option provides support for runtime services provided diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 4991aef92be0..6eecdef538bd 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -43,6 +43,14 @@ config ARCH_BCM2835 This enables support for the Broadcom BCM2837 and BCM2711 SoC. These SoCs are used in the Raspberry Pi 3 and 4 devices. +config ARCH_BCM4908 + bool "Broadcom BCM4908 family" + select GPIOLIB + help + This enables support for the Broadcom BCM4906, BCM4908 and + BCM49408 SoCs. These SoCs use Brahma-B53 cores and can be + found in home routers. + config ARCH_BCM_IPROC bool "Broadcom iProc SoC Family" select COMMON_CLK_IPROC @@ -152,11 +160,6 @@ config ARCH_MEDIATEK config ARCH_MESON bool "Amlogic Platforms" - select PINCTRL - select PINCTRL_MESON - select COMMON_CLK_GXBB - select COMMON_CLK_AXG - select COMMON_CLK_G12A select MESON_IRQ_GPIO help This enables support for the arm64 based Amlogic SoCs diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 6a87d592bd00..90309208bb28 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -10,7 +10,7 @@ # # Copyright (C) 1995-2001 by Russell King -LDFLAGS_vmlinux :=--no-undefined -X -z norelro +LDFLAGS_vmlinux :=--no-undefined -X ifeq ($(CONFIG_RELOCATABLE), y) # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour @@ -96,6 +96,11 @@ ifeq ($(CONFIG_AS_HAS_ARMV8_4), y) asm-arch := armv8.4-a endif +ifeq ($(CONFIG_AS_HAS_ARMV8_5), y) +# make sure to pass the newest target architecture to -march. +asm-arch := armv8.5-a +endif + ifdef asm-arch KBUILD_CFLAGS += -Wa,-march=$(asm-arch) \ -DARM64_ASM_ARCH='"$(asm-arch)"' @@ -110,16 +115,20 @@ KBUILD_CPPFLAGS += -mbig-endian CHECKFLAGS += -D__AARCH64EB__ # Prefer the baremetal ELF build target, but not all toolchains include # it so fall back to the standard linux version if needed. -KBUILD_LDFLAGS += -EB $(call ld-option, -maarch64elfb, -maarch64linuxb) +KBUILD_LDFLAGS += -EB $(call ld-option, -maarch64elfb, -maarch64linuxb -z norelro) UTS_MACHINE := aarch64_be else KBUILD_CPPFLAGS += -mlittle-endian CHECKFLAGS += -D__AARCH64EL__ # Same as above, prefer ELF but fall back to linux target if needed. -KBUILD_LDFLAGS += -EL $(call ld-option, -maarch64elf, -maarch64linux) +KBUILD_LDFLAGS += -EL $(call ld-option, -maarch64elf, -maarch64linux -z norelro) UTS_MACHINE := aarch64 endif +ifeq ($(CONFIG_LD_IS_LLD), y) +KBUILD_LDFLAGS += -z norelro +endif + CHECKFLAGS += -D__aarch64__ ifeq ($(CONFIG_DYNAMIC_FTRACE_WITH_REGS),y) @@ -132,7 +141,7 @@ head-y := arch/arm64/kernel/head.o ifeq ($(CONFIG_KASAN_SW_TAGS), y) KASAN_SHADOW_SCALE_SHIFT := 4 -else +else ifeq ($(CONFIG_KASAN_GENERIC), y) KASAN_SHADOW_SCALE_SHIFT := 3 endif diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts index 0c42272106af..3d5a2ae9aa39 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts @@ -9,3 +9,8 @@ model = "Pine64 PinePhone Developer Batch (1.0)"; compatible = "pine64,pinephone-1.0", "allwinner,sun50i-a64"; }; + +&sgm3140 { + enable-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */ + flash-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */ +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts index 3e99a87e9ce5..c9b9f6e9ee8c 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts @@ -28,3 +28,8 @@ num-interpolated-steps = <50>; default-brightness-level = <400>; }; + +&sgm3140 { + enable-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */ + flash-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */ +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts index a9f5b670c9b8..acc0ab53b9c1 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts @@ -8,6 +8,11 @@ / { model = "Pine64 PinePhone (1.2)"; compatible = "pine64,pinephone-1.2", "allwinner,sun50i-a64"; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */ + }; }; &backlight { @@ -38,3 +43,12 @@ interrupt-parent = <&pio>; interrupts = <1 1 IRQ_TYPE_EDGE_RISING>; /* PB1 */ }; + +&mmc1 { + mmc-pwrseq = <&wifi_pwrseq>; +}; + +&sgm3140 { + enable-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */ + flash-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */ +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi index 5780713b0dba..2dfe9bae8c67 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi @@ -13,6 +13,7 @@ / { aliases { + ethernet0 = &rtl8723cs; serial0 = &uart0; }; @@ -49,6 +50,24 @@ }; }; + reg_vbat_wifi: vbat-wifi { + compatible = "regulator-fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vbat-wifi"; + }; + + sgm3140: led-controller { + compatible = "sgmicro,sgm3140"; + vin-supply = <®_dcdc1>; + + sgm3140_flash: led { + function = LED_FUNCTION_FLASH; + color = <LED_COLOR_ID_WHITE>; + flash-max-timeout-us = <250000>; + }; + }; + speaker_amp: audio-amplifier { compatible = "simple-audio-amplifier"; enable-gpios = <&pio 2 7 GPIO_ACTIVE_HIGH>; /* PC7 */ @@ -142,15 +161,25 @@ status = "okay"; /* Magnetometer */ - lis3mdl: lis3mdl@1e { + lis3mdl: magnetometer@1e { compatible = "st,lis3mdl-magn"; reg = <0x1e>; vdd-supply = <®_dldo1>; vddio-supply = <®_dldo1>; }; + /* Light/proximity sensor */ + light-sensor@48 { + compatible = "sensortek,stk3311"; + reg = <0x48>; + interrupt-parent = <&pio>; + interrupts = <1 0 IRQ_TYPE_EDGE_FALLING>; /* PB0 */ + vdd-supply = <®_ldo_io0>; + leda-supply = <®_dldo1>; + }; + /* Accelerometer/gyroscope */ - mpu6050@68 { + accelerometer@68 { compatible = "invensense,mpu6050"; reg = <0x68>; interrupt-parent = <&pio>; @@ -195,6 +224,20 @@ status = "okay"; }; +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + vmmc-supply = <®_vbat_wifi>; + vqmmc-supply = <®_dldo4>; + bus-width = <4>; + non-removable; + status = "okay"; + + rtl8723cs: wifi@1 { + reg = <1>; + }; +}; + &mmc2 { pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; @@ -251,10 +294,6 @@ #include "axp803.dtsi" -&ac_power_supply { - status = "okay"; -}; - &battery_power_supply { status = "okay"; }; @@ -274,8 +313,8 @@ ®_aldo3 { regulator-always-on; - regulator-min-microvolt = <2700000>; - regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; regulator-name = "vcc-pll-avcc"; }; @@ -408,6 +447,19 @@ status = "okay"; }; +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; + status = "okay"; + + bluetooth { + compatible = "realtek,rtl8723cs-bt"; + device-wake-gpios = <&pio 7 6 GPIO_ACTIVE_LOW>; /* PH6 */ + enable-gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */ + host-wake-gpios = <&r_pio 0 5 GPIO_ACTIVE_HIGH>; /* PL5 */ + }; +}; + /* Connected to the modem (hardware flow control can't be used) */ &uart3 { pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index dc238814013c..51cc30e84e26 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -846,6 +846,20 @@ status = "disabled"; }; + i2s2: i2s@1c22800 { + #sound-dai-cells = <0>; + compatible = "allwinner,sun50i-a64-i2s", + "allwinner,sun8i-h3-i2s"; + reg = <0x01c22800 0x400>; + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2S2>, <&ccu CLK_I2S2>; + clock-names = "apb", "mod"; + resets = <&ccu RST_BUS_I2S2>; + dma-names = "rx", "tx"; + dmas = <&dma 27>, <&dma 27>; + status = "disabled"; + }; + dai: dai@1c22c00 { #sound-dai-cells = <0>; compatible = "allwinner,sun50i-a64-codec-i2s"; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts index f4c8966a6497..7fea1e4e2d49 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts @@ -10,6 +10,12 @@ compatible = "pine64,pine-h64-model-b", "allwinner,sun50i-h6"; /delete-node/ reg_gmac_3v3; + + wifi_pwrseq: wifi_pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&r_pio 1 3 GPIO_ACTIVE_LOW>; /* PM3 */ + post-power-on-delay-ms = <200>; + }; }; &hdmi_connector { @@ -19,3 +25,12 @@ &emac { phy-supply = <®_aldo2>; }; + +&mmc1 { + vmmc-supply = <®_cldo3>; + vqmmc-supply = <®_aldo1>; + mmc-pwrseq = <&wifi_pwrseq>; + bus-width = <4>; + non-removable; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi index 28c77d6872f6..8a62a9fbe347 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi @@ -609,6 +609,19 @@ }; }; + i2s1: i2s@5091000 { + #sound-dai-cells = <0>; + compatible = "allwinner,sun50i-h6-i2s"; + reg = <0x05091000 0x1000>; + interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2S1>, <&ccu CLK_I2S1>; + clock-names = "apb", "mod"; + dmas = <&dma 4>, <&dma 4>; + resets = <&ccu RST_BUS_I2S1>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + spdif: spdif@5093000 { #sound-dai-cells = <0>; compatible = "allwinner,sun50i-h6-spdif"; @@ -680,7 +693,7 @@ status = "disabled"; }; - dwc3: dwc3@5200000 { + dwc3: usb@5200000 { compatible = "snps,dwc3"; reg = <0x05200000 0x10000>; interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts index 7740f97c240f..359589d1dfa9 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts +++ b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts @@ -441,6 +441,16 @@ status = "okay"; }; +&pcieA { + reset-gpios = <&gpio GPIOX_19 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&pcieB { + reset-gpios = <&gpio GPIOZ_10 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; + status = "okay"; +}; + &pwm_ab { status = "okay"; pinctrl-0 = <&pwm_a_x20_pins>; diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi index 724ee179b316..ba1c6dfdc4b6 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi @@ -12,6 +12,7 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h> #include <dt-bindings/reset/amlogic,meson-axg-reset.h> +#include <dt-bindings/power/meson-axg-power.h> / { compatible = "amlogic,meson-axg"; @@ -171,6 +172,58 @@ #size-cells = <2>; ranges; + pcieA: pcie@f9800000 { + compatible = "amlogic,axg-pcie", "snps,dw-pcie"; + reg = <0x0 0xf9800000 0x0 0x400000>, + <0x0 0xff646000 0x0 0x2000>, + <0x0 0xf9f00000 0x0 0x100000>; + reg-names = "elbi", "cfg", "config"; + interrupts = <GIC_SPI 177 IRQ_TYPE_EDGE_RISING>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 179 IRQ_TYPE_EDGE_RISING>; + bus-range = <0x0 0xff>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x82000000 0 0xf9c00000 0x0 0xf9c00000 0 0x00300000>; + + clocks = <&clkc CLKID_USB>, <&clkc CLKID_PCIE_A>, <&clkc CLKID_PCIE_CML_EN0>; + clock-names = "general", "pclk", "port"; + resets = <&reset RESET_PCIE_A>, <&reset RESET_PCIE_APB>; + reset-names = "port", "apb"; + num-lanes = <1>; + phys = <&pcie_phy>; + phy-names = "pcie"; + status = "disabled"; + }; + + pcieB: pcie@fa000000 { + compatible = "amlogic,axg-pcie", "snps,dw-pcie"; + reg = <0x0 0xfa000000 0x0 0x400000>, + <0x0 0xff648000 0x0 0x2000>, + <0x0 0xfa400000 0x0 0x100000>; + reg-names = "elbi", "cfg", "config"; + interrupts = <GIC_SPI 167 IRQ_TYPE_EDGE_RISING>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 169 IRQ_TYPE_EDGE_RISING>; + bus-range = <0x0 0xff>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x82000000 0 0xfa500000 0x0 0xfa500000 0 0x00300000>; + + clocks = <&clkc CLKID_USB>, <&clkc CLKID_PCIE_B>, <&clkc CLKID_PCIE_CML_EN1>; + clock-names = "general", "pclk", "port"; + resets = <&reset RESET_PCIE_B>, <&reset RESET_PCIE_APB>; + reset-names = "port", "apb"; + num-lanes = <1>; + phys = <&pcie_phy>; + phy-names = "pcie"; + status = "disabled"; + }; + usb: usb@ffe09080 { compatible = "amlogic,meson-axg-usb-ctrl"; reg = <0x0 0xffe09080 0x0 0x20>; @@ -229,9 +282,19 @@ tx-fifo-depth = <2048>; resets = <&reset RESET_ETHERNET>; reset-names = "stmmaceth"; + power-domains = <&pwrc PWRC_AXG_ETHERNET_MEM_ID>; status = "disabled"; }; + pcie_phy: phy@ff644000 { + compatible = "amlogic,axg-pcie-phy"; + reg = <0x0 0xff644000 0x0 0x1c>; + resets = <&reset RESET_PCIE_PHY>; + phys = <&mipi_pcie_analog_dphy>; + phy-names = "analog"; + #phy-cells = <0>; + }; + pdm: audio-controller@ff632000 { compatible = "amlogic,axg-pdm"; reg = <0x0 0xff632000 0x0 0x34>; @@ -1159,6 +1222,52 @@ clocks = <&xtal>; clock-names = "xtal"; }; + + pwrc: power-controller { + compatible = "amlogic,meson-axg-pwrc"; + #power-domain-cells = <1>; + amlogic,ao-sysctrl = <&sysctrl_AO>; + resets = <&reset RESET_VIU>, + <&reset RESET_VENC>, + <&reset RESET_VCBUS>, + <&reset RESET_VENCL>, + <&reset RESET_VID_LOCK>; + reset-names = "viu", "venc", "vcbus", + "vencl", "vid_lock"; + clocks = <&clkc CLKID_VPU>, + <&clkc CLKID_VAPB>; + clock-names = "vpu", "vapb"; + /* + * VPU clocking is provided by two identical clock paths + * VPU_0 and VPU_1 muxed to a single clock by a glitch + * free mux to safely change frequency while running. + * Same for VAPB but with a final gate after the glitch free mux. + */ + assigned-clocks = <&clkc CLKID_VPU_0_SEL>, + <&clkc CLKID_VPU_0>, + <&clkc CLKID_VPU>, /* Glitch free mux */ + <&clkc CLKID_VAPB_0_SEL>, + <&clkc CLKID_VAPB_0>, + <&clkc CLKID_VAPB_SEL>; /* Glitch free mux */ + assigned-clock-parents = <&clkc CLKID_FCLK_DIV4>, + <0>, /* Do Nothing */ + <&clkc CLKID_VPU_0>, + <&clkc CLKID_FCLK_DIV4>, + <0>, /* Do Nothing */ + <&clkc CLKID_VAPB_0>; + assigned-clock-rates = <0>, /* Do Nothing */ + <250000000>, + <0>, /* Do Nothing */ + <0>, /* Do Nothing */ + <250000000>, + <0>; /* Do Nothing */ + }; + + mipi_pcie_analog_dphy: phy { + compatible = "amlogic,axg-mipi-pcie-analog-phy"; + #phy-cells = <0>; + status = "disabled"; + }; }; }; @@ -1171,6 +1280,19 @@ #mbox-cells = <1>; }; + mipi_dphy: phy@ff640000 { + compatible = "amlogic,axg-mipi-dphy"; + reg = <0x0 0xff640000 0x0 0x100>; + clocks = <&clkc CLKID_MIPI_DSI_PHY>; + clock-names = "pclk"; + resets = <&reset RESET_MIPI_PHY>; + reset-names = "phy"; + phys = <&mipi_pcie_analog_dphy>; + phy-names = "analog"; + #phy-cells = <0>; + status = "disabled"; + }; + audio: bus@ff642000 { compatible = "simple-bus"; reg = <0x0 0xff642000 0x0 0x2000>; @@ -1605,6 +1727,15 @@ }; }; + ge2d: ge2d@ff940000 { + compatible = "amlogic,axg-ge2d"; + reg = <0x0 0xff940000 0x0 0x10000>; + interrupts = <GIC_SPI 150 IRQ_TYPE_EDGE_RISING>; + clocks = <&clkc CLKID_VAPB>; + resets = <&reset RESET_GE2D>; + reset-names = "core"; + }; + gic: interrupt-controller@ffc01000 { compatible = "arm,gic-400"; reg = <0x0 0xffc01000 0 0x1000>, diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi index 8514fe6a275a..9c90d562ada1 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi @@ -2183,6 +2183,12 @@ amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>; }; + watchdog: wdt@f0d0 { + compatible = "amlogic,meson-gxbb-wdt"; + reg = <0x0 0xf0d0 0x0 0x10>; + clocks = <&xtal>; + }; + spicc0: spi@13000 { compatible = "amlogic,meson-g12a-spicc"; reg = <0x0 0x13000 0x0 0x44>; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts index 1b07c8c06eac..463a72d6bb7c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts @@ -340,7 +340,7 @@ eee-broken-1000t; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; interrupt-parent = <&gpio_intc>; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts index f0c56a16af3d..0e5c500fb78f 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts @@ -14,6 +14,11 @@ compatible = "azw,gtking", "amlogic,g12b"; model = "Beelink GT-King Pro"; + aliases { + rtc0 = &rtc; + rtc1 = &vrtc; + }; + gpio-keys-polled { compatible = "gpio-keys-polled"; #address-cells = <1>; @@ -112,6 +117,18 @@ status = "okay"; }; +&i2c3 { + status = "okay"; + pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>; + pinctrl-names = "default"; + + rtc: rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + wakeup-source; + }; +}; + &tdmif_b { status = "okay"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts index eeb7bc5539ef..10b87eb97b14 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts @@ -14,6 +14,11 @@ compatible = "azw,gtking", "amlogic,g12b"; model = "Beelink GT-King"; + aliases { + rtc0 = &rtc; + rtc1 = &vrtc; + }; + spdif_dit: audio-codec-1 { #sound-dai-cells = <0>; compatible = "linux,spdif-dit"; @@ -122,6 +127,19 @@ status = "okay"; }; + +&i2c3 { + status = "okay"; + pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>; + pinctrl-names = "default"; + + rtc: rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + wakeup-source; + }; +}; + &spdifout { pinctrl-0 = <&spdif_out_h_pins>; pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi index 6982632ae646..39a09661c5f6 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi @@ -413,7 +413,7 @@ max-speed = <1000>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; interrupt-parent = <&gpio_intc>; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi index 2802ddbb83ac..feb088504740 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi @@ -264,7 +264,7 @@ max-speed = <1000>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; interrupt-parent = <&gpio_intc>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts index 7be3e354093b..089e0636ba8a 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts @@ -7,6 +7,7 @@ #include "meson-gxbb.dtsi" #include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/sound/meson-aiu.h> / { compatible = "friendlyarm,nanopi-k2", "amlogic,meson-gxbb"; @@ -130,6 +131,45 @@ }; }; }; + + sound { + compatible = "amlogic,gx-sound-card"; + model = "GXBB-NANOPI-K2"; + assigned-clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; + }; + + dai-link-1 { + sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; + dai-format = "i2s"; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&aiu AIU_HDMI CTRL_I2S>; + }; + }; + + dai-link-2 { + sound-dai = <&aiu AIU_HDMI CTRL_OUT>; + + codec-0 { + sound-dai = <&hdmi_tx>; + }; + }; + }; +}; + +&aiu { + status = "okay"; }; &cec_AO { @@ -165,7 +205,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts index 67d901ed2fa3..b5b11cb9f393 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts @@ -10,6 +10,7 @@ #include "meson-gxbb.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> +#include <dt-bindings/sound/meson-aiu.h> / { compatible = "nexbox,a95x", "amlogic,meson-gxbb"; @@ -139,6 +140,45 @@ }; }; }; + + sound { + compatible = "amlogic,gx-sound-card"; + model = "GXBB-NEXBOX-A95X"; + assigned-clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; + }; + + dai-link-1 { + sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; + dai-format = "i2s"; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&aiu AIU_HDMI CTRL_I2S>; + }; + }; + + dai-link-2 { + sound-dai = <&aiu AIU_HDMI CTRL_OUT>; + + codec-0 { + sound-dai = <&hdmi_tx>; + }; + }; + }; +}; + +&aiu { + status = "okay"; }; &cvbs_vdac_port { diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts index 70fcfb7b0683..c04ef57f7b3b 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts @@ -9,6 +9,7 @@ #include "meson-gxbb.dtsi" #include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/sound/meson-aiu.h> / { compatible = "hardkernel,odroid-c2", "amlogic,meson-gxbb"; @@ -172,6 +173,45 @@ }; }; }; + + sound { + compatible = "amlogic,gx-sound-card"; + model = "GXBB-ODROID-C2"; + assigned-clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; + }; + + dai-link-1 { + sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; + dai-format = "i2s"; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&aiu AIU_HDMI CTRL_I2S>; + }; + }; + + dai-link-2 { + sound-dai = <&aiu AIU_HDMI CTRL_OUT>; + + codec-0 { + sound-dai = <&hdmi_tx>; + }; + }; + }; +}; + +&aiu { + status = "okay"; }; &cec_AO { @@ -200,7 +240,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; 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 222ee8069cfa..9b0b81f191f1 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi @@ -126,7 +126,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts index 83b985bb015e..0c1570153842 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts @@ -7,10 +7,50 @@ /dts-v1/; #include "meson-gxbb-wetek.dtsi" +#include <dt-bindings/sound/meson-aiu.h> / { compatible = "wetek,hub", "amlogic,meson-gxbb"; model = "WeTek Hub"; + + sound { + compatible = "amlogic,gx-sound-card"; + model = "GXBB-WETEK-HUB"; + assigned-clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; + }; + + dai-link-1 { + sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; + dai-format = "i2s"; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&aiu AIU_HDMI CTRL_I2S>; + }; + }; + + dai-link-2 { + sound-dai = <&aiu AIU_HDMI CTRL_OUT>; + + codec-0 { + sound-dai = <&hdmi_tx>; + }; + }; + }; +}; + +&aiu { + status = "okay"; }; &ir { diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts index 2ab8a3d10079..f2562c7de67c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts @@ -8,11 +8,19 @@ #include "meson-gxbb-wetek.dtsi" #include <dt-bindings/input/input.h> +#include <dt-bindings/sound/meson-aiu.h> / { compatible = "wetek,play2", "amlogic,meson-gxbb"; model = "WeTek Play 2"; + spdif_dit: audio-codec-0 { + #sound-dai-cells = <0>; + compatible = "linux,spdif-dit"; + status = "okay"; + sound-name-prefix = "DIT"; + }; + leds { led-wifi { label = "wetek-play:wifi-status"; @@ -39,6 +47,59 @@ gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_LOW>; }; }; + + sound { + compatible = "amlogic,gx-sound-card"; + model = "GXBB-WETEK-PLAY2"; + assigned-clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; + }; + + dai-link-1 { + sound-dai = <&aiu AIU_CPU CPU_SPDIF_FIFO>; + }; + + dai-link-2 { + sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; + dai-format = "i2s"; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&aiu AIU_HDMI CTRL_I2S>; + }; + }; + + dai-link-3 { + sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>; + + codec-0 { + sound-dai = <&spdif_dit>; + }; + }; + + dai-link-4 { + sound-dai = <&aiu AIU_HDMI CTRL_OUT>; + + codec-0 { + sound-dai = <&hdmi_tx>; + }; + }; + }; +}; + +&aiu { + status = "okay"; + pinctrl-0 = <&spdif_out_y_pins>; + pinctrl-names = "default"; }; &i2c_A { diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi index ad812854a107..a350fee1264d 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi @@ -147,7 +147,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts index b08c4537f260..b2ab05c22090 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts @@ -82,7 +82,7 @@ /* External PHY reset is shared with internal PHY Led signal */ reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts index 0b95e9ecbef0..ad6d72254150 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts @@ -63,6 +63,10 @@ pinctrl-names = "default"; }; +&ir { + linux,rc-map-name = "rc-khamsin"; +}; + /* This is connected to the Bluetooth module: */ &uart_A { status = "okay"; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts index 8bcdffdf55d0..6fe589cd2ba2 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts @@ -5,9 +5,9 @@ /dts-v1/; -#include <dt-bindings/input/input.h> - #include "meson-gxl-s905x-p212.dtsi" +#include <dt-bindings/input/input.h> +#include <dt-bindings/sound/meson-aiu.h> / { compatible = "khadas,vim", "amlogic,s905x", "amlogic,meson-gxl"; @@ -63,6 +63,45 @@ }; }; }; + + sound { + compatible = "amlogic,gx-sound-card"; + model = "GXL-KHADAS-VIM1"; + assigned-clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; + }; + + dai-link-1 { + sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; + dai-format = "i2s"; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&aiu AIU_HDMI CTRL_I2S>; + }; + }; + + dai-link-2 { + sound-dai = <&aiu AIU_HDMI CTRL_OUT>; + + codec-0 { + sound-dai = <&hdmi_tx>; + }; + }; + }; +}; + +&aiu { + status = "okay"; }; &cec_AO { @@ -97,8 +136,7 @@ pinctrl-names = "default"; rtc: rtc@51 { - /* has to be enabled manually when a battery is connected: */ - status = "disabled"; + status = "okay"; compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts index 675eaa87963e..9a3c08e6e6cc 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts @@ -84,7 +84,6 @@ regulator-always-on; }; - vcck: regulator-vcck { compatible = "regulator-fixed"; regulator-name = "VCCK"; @@ -124,7 +123,6 @@ regulator-always-on; }; - vddio_card: regulator-vddio-card { compatible = "regulator-gpio"; regulator-name = "VDDIO_CARD"; @@ -195,7 +193,6 @@ }; }; - &aiu { status = "okay"; }; @@ -207,7 +204,6 @@ hdmi-phandle = <&hdmi_tx>; }; - ðmac { status = "okay"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts index bff8ec2c1c70..bf9877d33427 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts @@ -7,9 +7,9 @@ /dts-v1/; -#include <dt-bindings/input/input.h> - #include "meson-gxm.dtsi" +#include <dt-bindings/input/input.h> +#include <dt-bindings/sound/meson-aiu.h> / { compatible = "khadas,vim2", "amlogic,s912", "amlogic,meson-gxm"; @@ -145,6 +145,45 @@ clock-frequency = <32768>; pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */ }; + + sound { + compatible = "amlogic,gx-sound-card"; + model = "GXM-KHADAS-VIM2"; + assigned-clocks = <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>, + <&clkc CLKID_MPLL2>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>; + }; + + dai-link-1 { + sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>; + dai-format = "i2s"; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&aiu AIU_HDMI CTRL_I2S>; + }; + }; + + dai-link-2 { + sound-dai = <&aiu AIU_HDMI CTRL_OUT>; + + codec-0 { + sound-dai = <&hdmi_tx>; + }; + }; + }; +}; + +&aiu { + status = "okay"; }; &cec_AO { @@ -154,7 +193,6 @@ hdmi-phandle = <&hdmi_tx>; }; - &cpu_cooling_maps { map0 { cooling-device = <&gpio_fan THERMAL_NO_LIMIT 1>; @@ -194,7 +232,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; @@ -228,8 +266,7 @@ pinctrl-names = "default"; rtc: rtc@51 { - /* has to be enabled manually when a battery is connected: */ - status = "disabled"; + status = "okay"; compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; @@ -341,7 +378,7 @@ #size-cells = <1>; compatible = "winbond,w25q16", "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <3000000>; + spi-max-frequency = <104000000>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts index 83eca3af44ce..dfa7a37a1281 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts @@ -112,7 +112,7 @@ max-speed = <1000>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts index ea45ae0c71b7..8edbfe040805 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts @@ -64,7 +64,7 @@ /* External PHY reset is shared with internal PHY Led signal */ reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts index c89c9f846fb1..dde7cfe12cff 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts @@ -114,7 +114,7 @@ max-speed = <1000>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi index fe4145112295..411cc312fc62 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi @@ -42,11 +42,28 @@ }; }; + cpu0: cpu@0 { + capacity-dmips-mhz = <1024>; + }; + + cpu1: cpu@1 { + capacity-dmips-mhz = <1024>; + }; + + cpu2: cpu@2 { + capacity-dmips-mhz = <1024>; + }; + + cpu3: cpu@3 { + capacity-dmips-mhz = <1024>; + }; + cpu4: cpu@100 { device_type = "cpu"; compatible = "arm,cortex-a53"; reg = <0x0 0x100>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; next-level-cache = <&l2>; clocks = <&scpi_dvfs 1>; #cooling-cells = <2>; @@ -57,6 +74,7 @@ compatible = "arm,cortex-a53"; reg = <0x0 0x101>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; next-level-cache = <&l2>; clocks = <&scpi_dvfs 1>; #cooling-cells = <2>; @@ -67,6 +85,7 @@ compatible = "arm,cortex-a53"; reg = <0x0 0x102>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; next-level-cache = <&l2>; clocks = <&scpi_dvfs 1>; #cooling-cells = <2>; @@ -77,6 +96,7 @@ compatible = "arm,cortex-a53"; reg = <0x0 0x103>; enable-method = "psci"; + capacity-dmips-mhz = <1024>; next-level-cache = <&l2>; clocks = <&scpi_dvfs 1>; #cooling-cells = <2>; diff --git a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi index 7b46555ac55a..8f8656262ae7 100644 --- a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi @@ -6,6 +6,7 @@ */ #include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> #include <dt-bindings/gpio/meson-g12a-gpio.h> #include <dt-bindings/sound/meson-g12a-tohdmitx.h> @@ -13,6 +14,8 @@ aliases { serial0 = &uart_AO; ethernet0 = ðmac; + rtc0 = &rtc; + rtc1 = &vrtc; }; chosen { @@ -40,14 +43,16 @@ leds { compatible = "gpio-leds"; - led-white { - label = "vim3:white:sys"; + white { + color = <LED_COLOR_ID_WHITE>; + function = LED_FUNCTION_STATUS; gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; }; - led-red { - label = "vim3:red"; + red { + color = <LED_COLOR_ID_RED>; + function = LED_FUNCTION_STATUS; gpios = <&gpio_expander 5 GPIO_ACTIVE_HIGH>; }; }; @@ -330,7 +335,7 @@ #gpio-cells = <2>; }; - rtc@51 { + rtc: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi index 71317f5aada1..c309517abae3 100644 --- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi @@ -130,7 +130,7 @@ opp-microvolt = <790000>; }; - opp-1512000000 { + opp-1500000000 { opp-hz = /bits/ 64 <1500000000>; opp-microvolt = <800000>; }; diff --git a/arch/arm64/boot/dts/bitmain/bm1880.dtsi b/arch/arm64/boot/dts/bitmain/bm1880.dtsi index fa6e6905f588..53a9b76057aa 100644 --- a/arch/arm64/boot/dts/bitmain/bm1880.dtsi +++ b/arch/arm64/boot/dts/bitmain/bm1880.dtsi @@ -127,7 +127,7 @@ compatible = "snps,dw-apb-gpio-port"; gpio-controller; #gpio-cells = <2>; - snps,nr-gpios = <32>; + ngpios = <32>; reg = <0>; interrupt-controller; #interrupt-cells = <2>; @@ -145,7 +145,7 @@ compatible = "snps,dw-apb-gpio-port"; gpio-controller; #gpio-cells = <2>; - snps,nr-gpios = <32>; + ngpios = <32>; reg = <0>; interrupt-controller; #interrupt-cells = <2>; @@ -163,7 +163,7 @@ compatible = "snps,dw-apb-gpio-port"; gpio-controller; #gpio-cells = <2>; - snps,nr-gpios = <8>; + ngpios = <8>; reg = <0>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm64/boot/dts/broadcom/Makefile b/arch/arm64/boot/dts/broadcom/Makefile index cb7de8d99223..998e240aa698 100644 --- a/arch/arm64/boot/dts/broadcom/Makefile +++ b/arch/arm64/boot/dts/broadcom/Makefile @@ -5,5 +5,6 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb \ bcm2837-rpi-3-b-plus.dtb \ bcm2837-rpi-cm3-io3.dtb +subdir-y += bcm4908 subdir-y += northstar2 subdir-y += stingray diff --git a/arch/arm64/boot/dts/broadcom/bcm4908/Makefile b/arch/arm64/boot/dts/broadcom/bcm4908/Makefile new file mode 100644 index 000000000000..ef26c23603ce --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/bcm4908/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +dtb-$(CONFIG_ARCH_BCM4908) += bcm4908-asus-gt-ac5300.dtb diff --git a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908-asus-gt-ac5300.dts b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908-asus-gt-ac5300.dts new file mode 100644 index 000000000000..13c6b86eef21 --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908-asus-gt-ac5300.dts @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> + +#include "bcm4908.dtsi" + +/ { + compatible = "asus,gt-ac5300", "brcm,bcm4908"; + model = "Asus GT-AC5300"; + + memory@0 { + device_type = "memory"; + reg = <0x00 0x00 0x00 0x40000000>; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + poll-interval = <100>; + + wifi { + label = "WiFi"; + linux,code = <KEY_RFKILL>; + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + }; + + wps { + label = "WPS"; + linux,code = <KEY_WPS_BUTTON>; + gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; + }; + + restart { + label = "Reset"; + linux,code = <KEY_RESTART>; + gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; + }; + + brightness { + label = "LEDs"; + linux,code = <KEY_BRIGHTNESS_ZERO>; + gpios = <&gpio0 31 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&nandcs { + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + nand-on-flash-bbt; + brcm,nand-has-wp; + + #address-cells = <1>; + #size-cells = <0>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "cferom"; + reg = <0x0 0x100000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi new file mode 100644 index 000000000000..f873dc44ce9c --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> + +/dts-v1/; + +/ { + interrupt-parent = <&gic>; + + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "brcm,brahma-b53"; + reg = <0x0>; + next-level-cache = <&l2>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "brcm,brahma-b53"; + reg = <0x1>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0xfff8>; + next-level-cache = <&l2>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "brcm,brahma-b53"; + reg = <0x2>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0xfff8>; + next-level-cache = <&l2>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "brcm,brahma-b53"; + reg = <0x3>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0xfff8>; + next-level-cache = <&l2>; + }; + + l2: l2-cache0 { + compatible = "cache"; + }; + }; + + axi@81000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x00 0x00 0x81000000 0x4000>; + + gic: interrupt-controller@1000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x1000 0x1000>, + <0x2000 0x2000>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + }; + + pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + + clocks { + periph_clk: periph_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + clock-output-names = "periph"; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x00 0x00 0x80000000 0x10000>; + + usb@c300 { + compatible = "generic-ehci"; + reg = <0xc300 0x100>; + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + usb@c400 { + compatible = "generic-ohci"; + reg = <0xc400 0x100>; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + usb@d000 { + compatible = "generic-xhci"; + reg = <0xd000 0x8c8>; + interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + }; + + bus@ff800000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x00 0x00 0xff800000 0x3000>; + + timer: timer@400 { + compatible = "brcm,bcm6328-timer", "syscon"; + reg = <0x400 0x3c>; + }; + + gpio0: gpio-controller@500 { + compatible = "brcm,bcm6345-gpio"; + reg-names = "dirout", "dat"; + reg = <0x500 0x28>, <0x528 0x28>; + + #gpio-cells = <2>; + gpio-controller; + }; + + uart0: serial@640 { + compatible = "brcm,bcm6345-uart"; + reg = <0x640 0x18>; + interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&periph_clk>; + clock-names = "periph"; + status = "okay"; + }; + + nand@1800 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "brcm,brcmnand-v7.1", "brcm,brcmnand"; + reg = <0x1800 0x600>, <0x2000 0x10>; + reg-names = "nand", "nand-int-base"; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "nand"; + status = "okay"; + + nandcs: nandcs@0 { + compatible = "brcm,nandcs"; + reg = <0>; + }; + }; + + reboot { + compatible = "syscon-reboot"; + regmap = <&timer>; + offset = <0x34>; + mask = <1>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi index d77b88af9582..8997f8f2b96c 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi @@ -87,7 +87,7 @@ status = "disabled"; }; - bus_g2d_400_opp_table: opp_table2 { + bus_g2d_400_opp_table: opp-table2 { compatible = "operating-points-v2"; opp-shared; @@ -117,7 +117,7 @@ }; }; - bus_g2d_266_opp_table: opp_table3 { + bus_g2d_266_opp_table: opp-table3 { compatible = "operating-points-v2"; opp-267000000 { @@ -137,7 +137,7 @@ }; }; - bus_gscl_opp_table: opp_table4 { + bus_gscl_opp_table: opp-table4 { compatible = "operating-points-v2"; opp-333000000 { @@ -151,7 +151,7 @@ }; }; - bus_hevc_opp_table: opp_table5 { + bus_hevc_opp_table: opp-table5 { compatible = "operating-points-v2"; opp-shared; @@ -175,7 +175,7 @@ }; }; - bus_noc2_opp_table: opp_table6 { + bus_noc2_opp_table: opp-table6 { compatible = "operating-points-v2"; opp-400000000 { diff --git a/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi index 9df7c65593a1..32a6518517e5 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi @@ -329,7 +329,7 @@ }; pcie_bus: pcie_bus { - samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6", "gpr3-7"; + samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6"; samsung,pin-function = <EXYNOS_PIN_FUNC_3>; samsung,pin-pud = <EXYNOS_PIN_PULL_UP>; }; diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi index 829fea23d4ab..03486a8ffc67 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi @@ -92,9 +92,8 @@ i2c-gpio,delay-us = <2>; #address-cells = <1>; #size-cells = <0>; - status = "okay"; - max98504: max98504@31 { + max98504: amplifier@31 { compatible = "maxim,max98504"; reg = <0x31>; maxim,rx-path = <1>; @@ -386,7 +385,7 @@ status = "okay"; clock-frequency = <2500000>; - s2mps13-pmic@66 { + pmic@66 { compatible = "samsung,s2mps13-pmic"; interrupt-parent = <&gpa0>; interrupts = <7 IRQ_TYPE_NONE>; @@ -817,7 +816,7 @@ status = "okay"; clock-frequency = <1000000>; - sii8620@39 { + bridge@39 { reg = <0x39>; compatible = "sil,sii8620"; cvcc10-supply = <&ldo36_reg>; @@ -852,7 +851,7 @@ &hsi2c_8 { status = "okay"; - max77843@66 { + pmic@66 { compatible = "maxim,max77843"; interrupt-parent = <&gpa1>; interrupts = <5 IRQ_TYPE_EDGE_FALLING>; @@ -861,7 +860,7 @@ muic: max77843-muic { compatible = "maxim,max77843-muic"; - musb_con: musb_connector { + musb_con: musb-connector { compatible = "samsung,usb-connector-11pin", "usb-b-connector"; label = "micro-USB"; @@ -969,6 +968,25 @@ bus-width = <4>; }; +&pcie { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_bus &pcie_wlanen>; + vdd10-supply = <&ldo6_reg>; + vdd18-supply = <&ldo7_reg>; + assigned-clocks = <&cmu_fsys CLK_MOUT_SCLK_PCIE_100_USER>, + <&cmu_top CLK_MOUT_SCLK_PCIE_100>; + assigned-clock-parents = <&cmu_top CLK_SCLK_PCIE_100_FSYS>, + <&cmu_top CLK_MOUT_BUS_PLL_USER>; + assigned-clock-rates = <0>, <100000000>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>; +}; + +&pcie_phy { + status = "okay"; +}; + &ppmu_d0_general { status = "okay"; events { @@ -1065,7 +1083,7 @@ PIN(INPUT, gpf5-7, DOWN, FAST_SR1); }; - te_irq: te_irq { + te_irq: te-irq { samsung,pins = "gpf1-3"; samsung,pin-function = <0xf>; }; @@ -1085,8 +1103,11 @@ pinctrl-names = "default"; pinctrl-0 = <&initial_ese>; + pcie_wlanen: pcie-wlanen { + PIN(INPUT, gpj2-0, UP, FAST_SR4); + }; + initial_ese: initial-state { - PIN(INPUT, gpj2-0, DOWN, FAST_SR1); PIN(INPUT, gpj2-1, DOWN, FAST_SR1); PIN(INPUT, gpj2-2, DOWN, FAST_SR1); }; @@ -1231,7 +1252,7 @@ cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>; status = "okay"; - wm5110: wm5110-codec@0 { + wm5110: audio-codec@0 { compatible = "wlf,wm5110"; reg = <0x0>; spi-max-frequency = <20000000>; diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index 8eb4576da8f3..6433f9ee35e1 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi @@ -23,7 +23,7 @@ interrupt-parent = <&gic>; - arm_a53_pmu { + arm-a53-pmu { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>, @@ -32,7 +32,7 @@ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; }; - arm_a57_pmu { + arm-a57-pmu { compatible = "arm,cortex-a57-pmu"; interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>, @@ -137,7 +137,7 @@ }; }; - cluster_a53_opp_table: opp_table0 { + cluster_a53_opp_table: opp-table0 { compatible = "operating-points-v2"; opp-shared; @@ -183,7 +183,7 @@ }; }; - cluster_a57_opp_table: opp_table1 { + cluster_a57_opp_table: opp-table1 { compatible = "operating-points-v2"; opp-shared; @@ -1029,6 +1029,11 @@ reg = <0x145f0000 0x1038>; }; + syscon_fsys: syscon@156f0000 { + compatible = "syscon"; + reg = <0x156f0000 0x1044>; + }; + gsc_0: video-scaler@13c00000 { compatible = "samsung,exynos5433-gsc"; reg = <0x13c00000 0x1000>; @@ -1445,7 +1450,6 @@ clock-names = "adc"; clocks = <&cmu_peric CLK_PCLK_ADCIF>; #io-channel-cells = <1>; - io-channel-ranges; status = "disabled"; }; @@ -1647,7 +1651,7 @@ ranges; status = "disabled"; - usbdrd_dwc3: dwc3@15400000 { + usbdrd_dwc3: usb@15400000 { compatible = "snps,dwc3"; clocks = <&cmu_fsys CLK_SCLK_USBDRD30>, <&cmu_fsys CLK_ACLK_USBDRD30>, @@ -1700,7 +1704,7 @@ ranges; status = "disabled"; - usbhost_dwc3: dwc3@15a00000 { + usbhost_dwc3: usb@15a00000 { compatible = "snps,dwc3"; clocks = <&cmu_fsys CLK_SCLK_USBHOST30>, <&cmu_fsys CLK_ACLK_USBHOST30>, @@ -1830,6 +1834,37 @@ status = "disabled"; }; }; + + pcie_phy: pcie-phy@15680000 { + compatible = "samsung,exynos5433-pcie-phy"; + reg = <0x15680000 0x1000>; + samsung,pmu-syscon = <&pmu_system_controller>; + samsung,fsys-sysreg = <&syscon_fsys>; + #phy-cells = <0>; + status = "disabled"; + }; + + pcie: pcie@15700000 { + compatible = "samsung,exynos5433-pcie"; + reg = <0x15700000 0x1000>, <0x156b0000 0x1000>, + <0x0c000000 0x1000>; + reg-names = "dbi", "elbi", "config"; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cmu_fsys CLK_PCIE>, + <&cmu_fsys CLK_PCLK_PCIE_PHY>; + clock-names = "pcie", "pcie_bus"; + num-lanes = <1>; + num-viewport = <3>; + bus-range = <0x00 0xff>; + phys = <&pcie_phy>; + ranges = <0x81000000 0 0 0x0c001000 0 0x00010000>, + <0x82000000 0 0x0c011000 0x0c011000 0 0x03feefff>; + status = "disabled"; + }; }; timer: timer { diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts index 92fecc539c6c..695d4c140646 100644 --- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts +++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts @@ -87,7 +87,7 @@ samsung,i2c-max-bus-freq = <200000>; status = "okay"; - s2mps15_pmic@66 { + pmic@66 { compatible = "samsung,s2mps15-pmic"; reg = <0x66>; interrupts = <2 IRQ_TYPE_NONE>; diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi index b9ed6a33e290..10244e59d56d 100644 --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi @@ -79,8 +79,10 @@ }; psci { - compatible = "arm,psci-0.2"; + compatible = "arm,psci"; method = "smc"; + cpu_off = <0x84000002>; + cpu_on = <0xC4000003>; }; soc: soc@0 { @@ -481,13 +483,6 @@ pmu_system_controller: system-controller@105c0000 { compatible = "samsung,exynos7-pmu", "syscon"; reg = <0x105c0000 0x5000>; - - reboot: syscon-reboot { - compatible = "syscon-reboot"; - regmap = <&pmu_system_controller>; - offset = <0x0400>; - mask = <0x1>; - }; }; rtc: rtc@10590000 { @@ -567,7 +562,6 @@ clocks = <&clock_peric0 PCLK_ADCIF>; clock-names = "adc"; #io-channel-cells = <1>; - io-channel-ranges; status = "disabled"; }; @@ -654,7 +648,7 @@ #size-cells = <1>; ranges; - dwc3@15400000 { + usb@15400000 { compatible = "snps,dwc3"; reg = <0x15400000 0x10000>; interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>; @@ -687,3 +681,4 @@ }; #include "exynos7-pinctrl.dtsi" +#include "arm/exynos-syscon-restart.dtsi" diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile index f8d59433af01..6f0777ee6cd6 100644 --- a/arch/arm64/boot/dts/freescale/Makefile +++ b/arch/arm64/boot/dts/freescale/Makefile @@ -27,10 +27,12 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-clearfog-cx.dtb dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-honeycomb.dtb dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-rdb.dtb +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2162a-qds.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-beacon-kit.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-ddr4-evk.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mm-kontron-n801x-s.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mn-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mn-ddr4-evk.dtb diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi index 6a2c09199047..626b709d1fb9 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi @@ -291,43 +291,46 @@ compatible = "fsl,qoriq-tmu"; reg = <0x0 0x1f00000 0x0 0x10000>; interrupts = <0 33 0x4>; - fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x30062>; - fsl,tmu-calibration = <0x00000000 0x00000026 - 0x00000001 0x0000002d + fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x60062>; + fsl,tmu-calibration = <0x00000000 0x00000025 + 0x00000001 0x0000002c 0x00000002 0x00000032 0x00000003 0x00000039 0x00000004 0x0000003f 0x00000005 0x00000046 - 0x00000006 0x0000004d - 0x00000007 0x00000054 - 0x00000008 0x0000005a - 0x00000009 0x00000061 - 0x0000000a 0x0000006a - 0x0000000b 0x00000071 - - 0x00010000 0x00000025 - 0x00010001 0x0000002c + 0x00000006 0x0000004c + 0x00000007 0x00000053 + 0x00000008 0x00000059 + 0x00000009 0x0000005f + 0x0000000a 0x00000066 + 0x0000000b 0x0000006c + + 0x00010000 0x00000026 + 0x00010001 0x0000002d 0x00010002 0x00000035 0x00010003 0x0000003d 0x00010004 0x00000045 - 0x00010005 0x0000004e - 0x00010006 0x00000057 - 0x00010007 0x00000061 - 0x00010008 0x0000006b - 0x00010009 0x00000076 - - 0x00020000 0x00000029 - 0x00020001 0x00000033 - 0x00020002 0x0000003d - 0x00020003 0x00000049 - 0x00020004 0x00000056 - 0x00020005 0x00000061 - 0x00020006 0x0000006d - - 0x00030000 0x00000021 - 0x00030001 0x0000002a - 0x00030002 0x0000003c - 0x00030003 0x0000004e>; + 0x00010005 0x0000004d + 0x00010006 0x00000055 + 0x00010007 0x0000005d + 0x00010008 0x00000065 + 0x00010009 0x0000006d + + 0x00020000 0x00000026 + 0x00020001 0x00000030 + 0x00020002 0x0000003a + 0x00020003 0x00000044 + 0x00020004 0x0000004e + 0x00020005 0x00000059 + 0x00020006 0x00000063 + + 0x00030000 0x00000014 + 0x00030001 0x00000021 + 0x00030002 0x0000002e + 0x00030003 0x0000003a + 0x00030004 0x00000047 + 0x00030005 0x00000053 + 0x00030006 0x00000060>; big-endian; #thermal-sensor-cells = <1>; }; @@ -401,7 +404,7 @@ #interrupt-cells = <2>; }; - wdog0: wdog@2ad0000 { + wdog0: watchdog@2ad0000 { compatible = "fsl,ls1012a-wdt", "fsl,imx21-wdt"; reg = <0x0 0x2ad0000 0x0 0x10000>; @@ -454,7 +457,7 @@ <&clockgen 4 3>; }; - usb0: usb3@2f00000 { + usb0: usb@2f00000 { compatible = "snps,dwc3"; reg = <0x0 0x2f00000 0x0 0x10000>; interrupts = <0 60 0x4>; @@ -475,7 +478,7 @@ status = "disabled"; }; - usb1: usb2@8600000 { + usb1: usb@8600000 { compatible = "fsl-usb2-dr-v2.5", "fsl-usb2-dr"; reg = <0x0 0x8600000 0x0 0x1000>; interrupts = <0 139 0x4>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts index 8161dd237971..0516076087ae 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts @@ -23,6 +23,8 @@ serial2 = &lpuart1; spi0 = &fspi; spi1 = &dspi2; + mmc0 = &esdhc1; + mmc1 = &esdhc; }; buttons0 { @@ -60,6 +62,10 @@ }; }; +&can0 { + status = "okay"; +}; + &dspi2 { status = "okay"; }; @@ -155,20 +161,10 @@ }; partition@210000 { - reg = <0x210000 0x0f0000>; + reg = <0x210000 0x1d0000>; label = "bootloader"; }; - partition@300000 { - reg = <0x300000 0x040000>; - label = "DP firmware"; - }; - - partition@340000 { - reg = <0x340000 0x0a0000>; - label = "trusted firmware"; - }; - partition@3e0000 { reg = <0x3e0000 0x020000>; label = "bootloader environment"; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts index 13cdc958ba3e..c0786b713791 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts @@ -23,6 +23,8 @@ gpio2 = &gpio3; serial0 = &duart0; serial1 = &duart1; + mmc0 = &esdhc; + mmc1 = &esdhc1; }; chosen { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts index 1efb61cff454..c1d1ba459307 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts @@ -19,6 +19,8 @@ crypto = &crypto; serial0 = &duart0; serial1 = &duart1; + mmc0 = &esdhc; + mmc1 = &esdhc1; }; chosen { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi index 7a6fb7e1fb82..60ff19fa53b4 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi @@ -90,6 +90,14 @@ clocks = <&osc_27m>; }; + firmware { + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + status = "disabled"; + }; + }; + reboot { compatible ="syscon-reboot"; regmap = <&rst>; @@ -309,7 +317,7 @@ <0x0 0x20000000 0x0 0x10000000>; reg-names = "fspi_base", "fspi_mmap"; interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clockgen 4 3>, <&clockgen 4 3>; + clocks = <&clockgen 2 0>, <&clockgen 2 0>; clock-names = "fspi_en", "fspi"; status = "disabled"; }; @@ -386,6 +394,24 @@ status = "disabled"; }; + can0: can@2180000 { + compatible = "fsl,ls1028ar1-flexcan", "fsl,lx2160ar1-flexcan"; + reg = <0x0 0x2180000 0x0 0x10000>; + interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&sysclk>, <&clockgen 4 1>; + clock-names = "ipg", "per"; + status = "disabled"; + }; + + can1: can@2190000 { + compatible = "fsl,ls1028ar1-flexcan", "fsl,lx2160ar1-flexcan"; + reg = <0x0 0x2190000 0x0 0x10000>; + interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&sysclk>, <&clockgen 4 1>; + clock-names = "ipg", "per"; + status = "disabled"; + }; + duart0: serial@21c0500 { compatible = "fsl,ns16550", "ns16550a"; reg = <0x00 0x21c0500 0x0 0x100>; @@ -934,7 +960,7 @@ ethernet@0,4 { compatible = "fsl,enetc-ptp"; reg = <0x000400 0 0 0 0>; - clocks = <&clockgen 4 0>; + clocks = <&clockgen 2 3>; little-endian; fsl,extts-fifo; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi index 0464b8aa4bc4..bbae4b353d3f 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi @@ -403,43 +403,47 @@ compatible = "fsl,qoriq-tmu"; reg = <0x0 0x1f00000 0x0 0x10000>; interrupts = <0 33 0x4>; - fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x30062>; - fsl,tmu-calibration = <0x00000000 0x00000026 - 0x00000001 0x0000002d - 0x00000002 0x00000032 - 0x00000003 0x00000039 - 0x00000004 0x0000003f - 0x00000005 0x00000046 - 0x00000006 0x0000004d - 0x00000007 0x00000054 - 0x00000008 0x0000005a - 0x00000009 0x00000061 - 0x0000000a 0x0000006a - 0x0000000b 0x00000071 - - 0x00010000 0x00000025 - 0x00010001 0x0000002c - 0x00010002 0x00000035 - 0x00010003 0x0000003d - 0x00010004 0x00000045 - 0x00010005 0x0000004e - 0x00010006 0x00000057 - 0x00010007 0x00000061 - 0x00010008 0x0000006b - 0x00010009 0x00000076 - - 0x00020000 0x00000029 - 0x00020001 0x00000033 - 0x00020002 0x0000003d - 0x00020003 0x00000049 - 0x00020004 0x00000056 - 0x00020005 0x00000061 - 0x00020006 0x0000006d - - 0x00030000 0x00000021 - 0x00030001 0x0000002a - 0x00030002 0x0000003c - 0x00030003 0x0000004e>; + fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x70062>; + fsl,tmu-calibration = <0x00000000 0x00000023 + 0x00000001 0x0000002a + 0x00000002 0x00000031 + 0x00000003 0x00000037 + 0x00000004 0x0000003e + 0x00000005 0x00000044 + 0x00000006 0x0000004b + 0x00000007 0x00000051 + 0x00000008 0x00000058 + 0x00000009 0x0000005e + 0x0000000a 0x00000065 + 0x0000000b 0x0000006b + + 0x00010000 0x00000023 + 0x00010001 0x0000002b + 0x00010002 0x00000033 + 0x00010003 0x0000003b + 0x00010004 0x00000043 + 0x00010005 0x0000004b + 0x00010006 0x00000054 + 0x00010007 0x0000005c + 0x00010008 0x00000064 + 0x00010009 0x0000006c + + 0x00020000 0x00000021 + 0x00020001 0x0000002c + 0x00020002 0x00000036 + 0x00020003 0x00000040 + 0x00020004 0x0000004b + 0x00020005 0x00000055 + 0x00020006 0x0000005f + + 0x00030000 0x00000013 + 0x00030001 0x0000001d + 0x00030002 0x00000028 + 0x00030003 0x00000032 + 0x00030004 0x0000003d + 0x00030005 0x00000047 + 0x00030006 0x00000052 + 0x00030007 0x0000005c>; #thermal-sensor-cells = <1>; }; @@ -725,7 +729,7 @@ status = "disabled"; }; - wdog0: wdog@2ad0000 { + wdog0: watchdog@2ad0000 { compatible = "fsl,ls1043a-wdt", "fsl,imx21-wdt"; reg = <0x0 0x2ad0000 0x0 0x10000>; interrupts = <0 83 0x4>; @@ -750,7 +754,7 @@ <&clockgen 4 0>; }; - usb0: usb3@2f00000 { + usb0: usb@2f00000 { compatible = "snps,dwc3"; reg = <0x0 0x2f00000 0x0 0x10000>; interrupts = <0 60 0x4>; @@ -761,7 +765,7 @@ status = "disabled"; }; - usb1: usb3@3000000 { + usb1: usb@3000000 { compatible = "snps,dwc3"; reg = <0x0 0x3000000 0x0 0x10000>; interrupts = <0 61 0x4>; @@ -772,7 +776,7 @@ status = "disabled"; }; - usb2: usb3@3100000 { + usb2: usb@3100000 { compatible = "snps,dwc3"; reg = <0x0 0x3100000 0x0 0x10000>; interrupts = <0 63 0x4>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi index 1fa39bacff4b..025e1f587662 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi @@ -400,45 +400,49 @@ compatible = "fsl,qoriq-tmu"; reg = <0x0 0x1f00000 0x0 0x10000>; interrupts = <0 33 0x4>; - fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x30062>; + fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x70062>; fsl,tmu-calibration = /* Calibration data group 1 */ - <0x00000000 0x00000026 - 0x00000001 0x0000002d - 0x00000002 0x00000032 - 0x00000003 0x00000039 - 0x00000004 0x0000003f - 0x00000005 0x00000046 - 0x00000006 0x0000004d - 0x00000007 0x00000054 - 0x00000008 0x0000005a - 0x00000009 0x00000061 - 0x0000000a 0x0000006a - 0x0000000b 0x00000071 + <0x00000000 0x00000023 + 0x00000001 0x00000029 + 0x00000002 0x0000002f + 0x00000003 0x00000036 + 0x00000004 0x0000003c + 0x00000005 0x00000042 + 0x00000006 0x00000049 + 0x00000007 0x0000004f + 0x00000008 0x00000055 + 0x00000009 0x0000005c + 0x0000000a 0x00000062 + 0x0000000b 0x00000068 /* Calibration data group 2 */ - 0x00010000 0x00000025 - 0x00010001 0x0000002c - 0x00010002 0x00000035 - 0x00010003 0x0000003d - 0x00010004 0x00000045 - 0x00010005 0x0000004e - 0x00010006 0x00000057 - 0x00010007 0x00000061 - 0x00010008 0x0000006b - 0x00010009 0x00000076 + 0x00010000 0x00000022 + 0x00010001 0x0000002a + 0x00010002 0x00000032 + 0x00010003 0x0000003a + 0x00010004 0x00000042 + 0x00010005 0x0000004a + 0x00010006 0x00000052 + 0x00010007 0x0000005a + 0x00010008 0x00000062 + 0x00010009 0x0000006a /* Calibration data group 3 */ - 0x00020000 0x00000029 - 0x00020001 0x00000033 - 0x00020002 0x0000003d - 0x00020003 0x00000049 - 0x00020004 0x00000056 - 0x00020005 0x00000061 - 0x00020006 0x0000006d + 0x00020000 0x00000021 + 0x00020001 0x0000002b + 0x00020002 0x00000035 + 0x00020003 0x0000003e + 0x00020004 0x00000048 + 0x00020005 0x00000052 + 0x00020006 0x0000005c /* Calibration data group 4 */ - 0x00030000 0x00000021 - 0x00030001 0x0000002a - 0x00030002 0x0000003c - 0x00030003 0x0000004e>; + 0x00030000 0x00000011 + 0x00030001 0x0000001a + 0x00030002 0x00000024 + 0x00030003 0x0000002e + 0x00030004 0x00000038 + 0x00030005 0x00000042 + 0x00030006 0x0000004c + 0x00030007 0x00000056>; big-endian; #thermal-sensor-cells = <1>; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts index 5633e59febc3..528ec72d0b83 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts @@ -17,6 +17,113 @@ compatible = "fsl,ls1088a-rdb", "fsl,ls1088a"; }; +&dpmac2 { + phy-handle = <&mdio2_aquantia_phy>; + phy-connection-type = "10gbase-r"; + pcs-handle = <&pcs2>; +}; + +&dpmac3 { + phy-handle = <&mdio1_phy5>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + pcs-handle = <&pcs3_0>; +}; + +&dpmac4 { + phy-handle = <&mdio1_phy6>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + pcs-handle = <&pcs3_1>; +}; + +&dpmac5 { + phy-handle = <&mdio1_phy7>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + pcs-handle = <&pcs3_2>; +}; + +&dpmac6 { + phy-handle = <&mdio1_phy8>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + pcs-handle = <&pcs3_3>; +}; + +&dpmac7 { + phy-handle = <&mdio1_phy1>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + pcs-handle = <&pcs7_0>; +}; + +&dpmac8 { + phy-handle = <&mdio1_phy2>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + pcs-handle = <&pcs7_1>; +}; + +&dpmac9 { + phy-handle = <&mdio1_phy3>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + pcs-handle = <&pcs7_2>; +}; + +&dpmac10 { + phy-handle = <&mdio1_phy4>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + pcs-handle = <&pcs7_3>; +}; + +&emdio1 { + status = "okay"; + + mdio1_phy5: ethernet-phy@c { + reg = <0xc>; + }; + + mdio1_phy6: ethernet-phy@d { + reg = <0xd>; + }; + + mdio1_phy7: ethernet-phy@e { + reg = <0xe>; + }; + + mdio1_phy8: ethernet-phy@f { + reg = <0xf>; + }; + + mdio1_phy1: ethernet-phy@1c { + reg = <0x1c>; + }; + + mdio1_phy2: ethernet-phy@1d { + reg = <0x1d>; + }; + + mdio1_phy3: ethernet-phy@1e { + reg = <0x1e>; + }; + + mdio1_phy4: ethernet-phy@1f { + reg = <0x1f>; + }; +}; + +&emdio2 { + status = "okay"; + + mdio2_aquantia_phy: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x0>; + }; +}; + &i2c0 { status = "okay"; @@ -87,6 +194,18 @@ status = "okay"; }; +&pcs_mdio2 { + status = "okay"; +}; + +&pcs_mdio3 { + status = "okay"; +}; + +&pcs_mdio7 { + status = "okay"; +}; + &qspi { status = "okay"; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi index 692d8f4a206d..6403455ed039 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi @@ -420,7 +420,7 @@ status = "disabled"; }; - usb0: usb3@3100000 { + usb0: usb@3100000 { compatible = "snps,dwc3"; reg = <0x0 0x3100000 0x0 0x10000>; interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>; @@ -431,7 +431,7 @@ status = "disabled"; }; - usb1: usb3@3110000 { + usb1: usb@3110000 { compatible = "snps,dwc3"; reg = <0x0 0x3110000 0x0 0x10000>; interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>; @@ -517,6 +517,17 @@ status = "disabled"; }; + pcie_ep1: pcie-ep@3400000 { + compatible = "fsl,ls1088a-pcie-ep", "fsl,ls-pcie-ep"; + reg = <0x00 0x03400000 0x0 0x00100000 + 0x20 0x00000000 0x8 0x00000000>; + reg-names = "regs", "addr_space"; + num-ib-windows = <24>; + num-ob-windows = <256>; + max-functions = /bits/ 8 <2>; + status = "disabled"; + }; + pcie2: pcie@3500000 { compatible = "fsl,ls1088a-pcie"; reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ @@ -543,6 +554,16 @@ status = "disabled"; }; + pcie_ep2: pcie-ep@3500000 { + compatible = "fsl,ls1088a-pcie-ep", "fsl,ls-pcie-ep"; + reg = <0x00 0x03500000 0x0 0x00100000 + 0x28 0x00000000 0x8 0x00000000>; + reg-names = "regs", "addr_space"; + num-ib-windows = <6>; + num-ob-windows = <6>; + status = "disabled"; + }; + pcie3: pcie@3600000 { compatible = "fsl,ls1088a-pcie"; reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */ @@ -569,6 +590,16 @@ status = "disabled"; }; + pcie_ep3: pcie-ep@3600000 { + compatible = "fsl,ls1088a-pcie-ep", "fsl,ls-pcie-ep"; + reg = <0x00 0x03600000 0x0 0x00100000 + 0x30 0x00000000 0x8 0x00000000>; + reg-names = "regs", "addr_space"; + num-ib-windows = <6>; + num-ob-windows = <6>; + status = "disabled"; + }; + smmu: iommu@5000000 { compatible = "arm,mmu-500"; reg = <0 0x5000000 0 0x800000>; @@ -672,6 +703,87 @@ fsl,extts-fifo; }; + emdio1: mdio@8b96000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8b96000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + emdio2: mdio@8b97000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8b97000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + pcs_mdio2: mdio@8c0b000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c0b000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs2: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio3: mdio@8c0f000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c0f000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs3_0: ethernet-phy@0 { + reg = <0>; + }; + + pcs3_1: ethernet-phy@1 { + reg = <1>; + }; + + pcs3_2: ethernet-phy@2 { + reg = <2>; + }; + + pcs3_3: ethernet-phy@3 { + reg = <3>; + }; + }; + + pcs_mdio7: mdio@8c1f000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c1f000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs7_0: ethernet-phy@0 { + reg = <0>; + }; + + pcs7_1: ethernet-phy@1 { + reg = <1>; + }; + + pcs7_2: ethernet-phy@2 { + reg = <2>; + }; + + pcs7_3: ethernet-phy@3 { + reg = <3>; + }; + }; + cluster1_core0_watchdog: wdt@c000000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc000000 0x0 0x1000>; @@ -749,52 +861,52 @@ #address-cells = <1>; #size-cells = <0>; - dpmac1: dpmac@1 { + dpmac1: ethernet@1 { compatible = "fsl,qoriq-mc-dpmac"; reg = <1>; }; - dpmac2: dpmac@2 { + dpmac2: ethernet@2 { compatible = "fsl,qoriq-mc-dpmac"; reg = <2>; }; - dpmac3: dpmac@3 { + dpmac3: ethernet@3 { compatible = "fsl,qoriq-mc-dpmac"; reg = <3>; }; - dpmac4: dpmac@4 { + dpmac4: ethernet@4 { compatible = "fsl,qoriq-mc-dpmac"; reg = <4>; }; - dpmac5: dpmac@5 { + dpmac5: ethernet@5 { compatible = "fsl,qoriq-mc-dpmac"; reg = <5>; }; - dpmac6: dpmac@6 { + dpmac6: ethernet@6 { compatible = "fsl,qoriq-mc-dpmac"; reg = <6>; }; - dpmac7: dpmac@7 { + dpmac7: ethernet@7 { compatible = "fsl,qoriq-mc-dpmac"; reg = <7>; }; - dpmac8: dpmac@8 { + dpmac8: ethernet@8 { compatible = "fsl,qoriq-mc-dpmac"; reg = <8>; }; - dpmac9: dpmac@9 { + dpmac9: ethernet@9 { compatible = "fsl,qoriq-mc-dpmac"; reg = <9>; }; - dpmac10: dpmac@a { + dpmac10: ethernet@a { compatible = "fsl,qoriq-mc-dpmac"; reg = <0xa>; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts index f6b4d75a258b..60563917be44 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts @@ -22,3 +22,123 @@ stdout-path = "serial1:115200n8"; }; }; + +&dpmac1 { + phy-handle = <&mdio1_phy1>; + phy-connection-type = "10gbase-r"; +}; + +&dpmac2 { + phy-handle = <&mdio1_phy2>; + phy-connection-type = "10gbase-r"; +}; + +&dpmac3 { + phy-handle = <&mdio1_phy3>; + phy-connection-type = "10gbase-r"; +}; + +&dpmac4 { + phy-handle = <&mdio1_phy4>; + phy-connection-type = "10gbase-r"; +}; + +&dpmac5 { + phy-handle = <&mdio2_phy1>; + phy-connection-type = "10gbase-r"; +}; + +&dpmac6 { + phy-handle = <&mdio2_phy2>; + phy-connection-type = "10gbase-r"; +}; + +&dpmac7 { + phy-handle = <&mdio2_phy3>; + phy-connection-type = "10gbase-r"; +}; + +&dpmac8 { + phy-handle = <&mdio2_phy4>; + phy-connection-type = "10gbase-r"; +}; + +&emdio1 { + status = "okay"; + + mdio1_phy1: ethernet-phy@10 { + compatible = "ethernet-phy-id13e5.1002"; + reg = <0x10>; + }; + + mdio1_phy2: ethernet-phy@11 { + compatible = "ethernet-phy-id13e5.1002"; + reg = <0x11>; + }; + + mdio1_phy3: ethernet-phy@12 { + compatible = "ethernet-phy-id13e5.1002"; + reg = <0x12>; + }; + + mdio1_phy4: ethernet-phy@13 { + compatible = "ethernet-phy-id13e5.1002"; + reg = <0x13>; + }; +}; + +&emdio2 { + status = "okay"; + + mdio2_phy1: ethernet-phy@0 { + compatible = "ethernet-phy-id03a1.b4b0", "ethernet-phy-ieee802.3-c45"; + reg = <0x0>; + }; + + mdio2_phy2: ethernet-phy@1 { + compatible = "ethernet-phy-id03a1.b4b0", "ethernet-phy-ieee802.3-c45"; + reg = <0x1>; + }; + + mdio2_phy3: ethernet-phy@2 { + compatible = "ethernet-phy-id03a1.b4b0", "ethernet-phy-ieee802.3-c45"; + reg = <0x2>; + }; + + mdio2_phy4: ethernet-phy@3 { + compatible = "ethernet-phy-id03a1.b4b0", "ethernet-phy-ieee802.3-c45"; + reg = <0x3>; + }; +}; + +&pcs_mdio1 { + status = "okay"; +}; + +&pcs_mdio2 { + status = "okay"; +}; + +&pcs_mdio3 { + status = "okay"; +}; + +&pcs_mdio4 { + status = "okay"; +}; + +&pcs_mdio5 { + status = "okay"; +}; + +&pcs_mdio6 { + status = "okay"; +}; + +&pcs_mdio7 { + status = "okay"; +}; + +&pcs_mdio8 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index e7abb74bd816..c68901f8c6f0 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -458,6 +458,232 @@ fsl,extts-fifo; }; + emdio1: mdio@8b96000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8b96000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + emdio2: mdio@8b97000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8b97000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + pcs_mdio1: mdio@8c07000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c07000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs1: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio2: mdio@8c0b000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c0b000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs2: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio3: mdio@8c0f000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c0f000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs3: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio4: mdio@8c13000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c13000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs4: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio5: mdio@8c17000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c17000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs5: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio6: mdio@8c1b000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c1b000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs6: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio7: mdio@8c1f000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c1f000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs7: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio8: mdio@8c23000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c23000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs8: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio9: mdio@8c27000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c27000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs9: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio10: mdio@8c2b000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c2b000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs10: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio11: mdio@8c2f000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c2f000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs11: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio12: mdio@8c33000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c33000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs12: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio13: mdio@8c37000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c37000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs13: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio14: mdio@8c3b000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c3b000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs14: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio15: mdio@8c3f000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c3f000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs15: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio16: mdio@8c43000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c43000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs16: ethernet-phy@0 { + reg = <0>; + }; + }; + fsl_mc: fsl-mc@80c000000 { compatible = "fsl,qoriq-mc"; reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */ @@ -482,84 +708,100 @@ #address-cells = <1>; #size-cells = <0>; - dpmac1: dpmac@1 { + dpmac1: ethernet@1 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x1>; + pcs-handle = <&pcs1>; }; - dpmac2: dpmac@2 { + dpmac2: ethernet@2 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x2>; + pcs-handle = <&pcs2>; }; - dpmac3: dpmac@3 { + dpmac3: ethernet@3 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x3>; + pcs-handle = <&pcs3>; }; - dpmac4: dpmac@4 { + dpmac4: ethernet@4 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x4>; + pcs-handle = <&pcs4>; }; - dpmac5: dpmac@5 { + dpmac5: ethernet@5 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x5>; + pcs-handle = <&pcs5>; }; - dpmac6: dpmac@6 { + dpmac6: ethernet@6 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x6>; + pcs-handle = <&pcs6>; }; - dpmac7: dpmac@7 { + dpmac7: ethernet@7 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x7>; + pcs-handle = <&pcs7>; }; - dpmac8: dpmac@8 { + dpmac8: ethernet@8 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x8>; + pcs-handle = <&pcs8>; }; - dpmac9: dpmac@9 { + dpmac9: ethernet@9 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x9>; + pcs-handle = <&pcs9>; }; - dpmac10: dpmac@a { + dpmac10: ethernet@a { compatible = "fsl,qoriq-mc-dpmac"; reg = <0xa>; + pcs-handle = <&pcs10>; }; - dpmac11: dpmac@b { + dpmac11: ethernet@b { compatible = "fsl,qoriq-mc-dpmac"; reg = <0xb>; + pcs-handle = <&pcs11>; }; - dpmac12: dpmac@c { + dpmac12: ethernet@c { compatible = "fsl,qoriq-mc-dpmac"; reg = <0xc>; + pcs-handle = <&pcs12>; }; - dpmac13: dpmac@d { + dpmac13: ethernet@d { compatible = "fsl,qoriq-mc-dpmac"; reg = <0xd>; + pcs-handle = <&pcs13>; }; - dpmac14: dpmac@e { + dpmac14: ethernet@e { compatible = "fsl,qoriq-mc-dpmac"; reg = <0xe>; + pcs-handle = <&pcs14>; }; - dpmac15: dpmac@f { + dpmac15: ethernet@f { compatible = "fsl,qoriq-mc-dpmac"; reg = <0xf>; + pcs-handle = <&pcs15>; }; - dpmac16: dpmac@10 { + dpmac16: ethernet@10 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x10>; + pcs-handle = <&pcs16>; }; }; }; @@ -860,7 +1102,7 @@ dma-coherent; }; - usb0: usb3@3100000 { + usb0: usb@3100000 { status = "disabled"; compatible = "snps,dwc3"; reg = <0x0 0x3100000 0x0 0x10000>; @@ -871,7 +1113,7 @@ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; }; - usb1: usb3@3110000 { + usb1: usb@3110000 { status = "disabled"; compatible = "snps,dwc3"; reg = <0x0 0x3110000 0x0 0x10000>; diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts index 54fe8cd3a711..7723ad5efd37 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts @@ -35,6 +35,18 @@ status = "okay"; }; +&dpmac3 { + phy-handle = <&aquantia_phy1>; + phy-connection-type = "usxgmii"; + managed = "in-band-status"; +}; + +&dpmac4 { + phy-handle = <&aquantia_phy2>; + phy-connection-type = "usxgmii"; + managed = "in-band-status"; +}; + &dpmac17 { phy-handle = <&rgmii_phy1>; phy-connection-type = "rgmii-id"; @@ -61,6 +73,18 @@ reg = <0x2>; eee-broken-1000t; }; + + aquantia_phy1: ethernet-phy@4 { + /* AQR107 PHY */ + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x4>; + }; + + aquantia_phy2: ethernet-phy@5 { + /* AQR107 PHY */ + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x5>; + }; }; &esdhc0 { @@ -156,6 +180,14 @@ }; }; +&pcs_mdio3 { + status = "okay"; +}; + +&pcs_mdio4 { + status = "okay"; +}; + &sata0 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi index 83072da6f6c6..197397777c83 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi @@ -1305,6 +1305,240 @@ status = "disabled"; }; + pcs_mdio1: mdio@8c07000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c07000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs1: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio2: mdio@8c0b000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c0b000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs2: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio3: mdio@8c0f000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c0f000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs3: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio4: mdio@8c13000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c13000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs4: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio5: mdio@8c17000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c17000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs5: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio6: mdio@8c1b000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c1b000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs6: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio7: mdio@8c1f000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c1f000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs7: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio8: mdio@8c23000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c23000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs8: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio9: mdio@8c27000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c27000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs9: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio10: mdio@8c2b000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c2b000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs10: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio11: mdio@8c2f000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c2f000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs11: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio12: mdio@8c33000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c33000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs12: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio13: mdio@8c37000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c37000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs13: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio14: mdio@8c3b000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c3b000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs14: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio15: mdio@8c3f000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c3f000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs15: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio16: mdio@8c43000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c43000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs16: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio17: mdio@8c47000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c47000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs17: ethernet-phy@0 { + reg = <0>; + }; + }; + + pcs_mdio18: mdio@8c4b000 { + compatible = "fsl,fman-memac-mdio"; + reg = <0x0 0x8c4b000 0x0 0x1000>; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + pcs18: ethernet-phy@0 { + reg = <0>; + }; + }; + fsl_mc: fsl-mc@80c000000 { compatible = "fsl,qoriq-mc"; reg = <0x00000008 0x0c000000 0 0x40>, @@ -1330,94 +1564,112 @@ #address-cells = <1>; #size-cells = <0>; - dpmac1: dpmac@1 { + dpmac1: ethernet@1 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x1>; + pcs-handle = <&pcs1>; }; - dpmac2: dpmac@2 { + dpmac2: ethernet@2 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x2>; + pcs-handle = <&pcs2>; }; - dpmac3: dpmac@3 { + dpmac3: ethernet@3 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x3>; + pcs-handle = <&pcs3>; }; - dpmac4: dpmac@4 { + dpmac4: ethernet@4 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x4>; + pcs-handle = <&pcs4>; }; - dpmac5: dpmac@5 { + dpmac5: ethernet@5 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x5>; + pcs-handle = <&pcs5>; }; - dpmac6: dpmac@6 { + dpmac6: ethernet@6 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x6>; + pcs-handle = <&pcs6>; }; - dpmac7: dpmac@7 { + dpmac7: ethernet@7 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x7>; + pcs-handle = <&pcs7>; }; - dpmac8: dpmac@8 { + dpmac8: ethernet@8 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x8>; + pcs-handle = <&pcs8>; }; - dpmac9: dpmac@9 { + dpmac9: ethernet@9 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x9>; + pcs-handle = <&pcs9>; }; - dpmac10: dpmac@a { + dpmac10: ethernet@a { compatible = "fsl,qoriq-mc-dpmac"; reg = <0xa>; + pcs-handle = <&pcs10>; }; - dpmac11: dpmac@b { + dpmac11: ethernet@b { compatible = "fsl,qoriq-mc-dpmac"; reg = <0xb>; + pcs-handle = <&pcs11>; }; - dpmac12: dpmac@c { + dpmac12: ethernet@c { compatible = "fsl,qoriq-mc-dpmac"; reg = <0xc>; + pcs-handle = <&pcs12>; }; - dpmac13: dpmac@d { + dpmac13: ethernet@d { compatible = "fsl,qoriq-mc-dpmac"; reg = <0xd>; + pcs-handle = <&pcs13>; }; - dpmac14: dpmac@e { + dpmac14: ethernet@e { compatible = "fsl,qoriq-mc-dpmac"; reg = <0xe>; + pcs-handle = <&pcs14>; }; - dpmac15: dpmac@f { + dpmac15: ethernet@f { compatible = "fsl,qoriq-mc-dpmac"; reg = <0xf>; + pcs-handle = <&pcs15>; }; - dpmac16: dpmac@10 { + dpmac16: ethernet@10 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x10>; + pcs-handle = <&pcs16>; }; - dpmac17: dpmac@11 { + dpmac17: ethernet@11 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x11>; + pcs-handle = <&pcs17>; }; - dpmac18: dpmac@12 { + dpmac18: ethernet@12 { compatible = "fsl,qoriq-mc-dpmac"; reg = <0x12>; + pcs-handle = <&pcs18>; }; }; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2162a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-lx2162a-qds.dts new file mode 100644 index 000000000000..91786848bd30 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-lx2162a-qds.dts @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +// +// Device Tree file for LX2162AQDS +// +// Copyright 2020 NXP + +/dts-v1/; + +#include "fsl-lx2160a.dtsi" + +/ { + model = "NXP Layerscape LX2162AQDS"; + compatible = "fsl,lx2162a-qds", "fsl,lx2160a"; + + aliases { + crypto = &crypto; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + sb_3v3: regulator-sb3v3 { + compatible = "regulator-fixed"; + regulator-name = "LTM4619-3.3VSB"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + mdio-mux-1 { + compatible = "mdio-mux-multiplexer"; + mux-controls = <&mux 0>; + mdio-parent-bus = <&emdio1>; + #address-cells=<1>; + #size-cells = <0>; + + mdio@0 { /* On-board RTL8211F PHY #1 RGMII1 */ + reg = <0x00>; + #address-cells = <1>; + #size-cells = <0>; + + rgmii_phy1: ethernet-phy@1 { + compatible = "ethernet-phy-id001c.c916"; + reg = <0x1>; + eee-broken-1000t; + }; + }; + + mdio@8 { /* On-board RTL8211F PHY #2 RGMII2 */ + reg = <0x8>; + #address-cells = <1>; + #size-cells = <0>; + + rgmii_phy2: ethernet-phy@2 { + compatible = "ethernet-phy-id001c.c916"; + reg = <0x2>; + eee-broken-1000t; + }; + }; + + mdio@18 { /* Slot #1 */ + reg = <0x18>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@19 { /* Slot #2 */ + reg = <0x19>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@1a { /* Slot #3 */ + reg = <0x1a>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@1b { /* Slot #4 */ + reg = <0x1b>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@1c { /* Slot #5 */ + reg = <0x1c>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@1d { /* Slot #6 */ + reg = <0x1d>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@1e { /* Slot #7 */ + reg = <0x1e>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@1f { /* Slot #8 */ + reg = <0x1f>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + mdio-mux-2 { + compatible = "mdio-mux-multiplexer"; + mux-controls = <&mux 1>; + mdio-parent-bus = <&emdio2>; + #address-cells=<1>; + #size-cells = <0>; + + mdio@0 { /* Slot #1 (secondary EMI) */ + reg = <0x00>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@1 { /* Slot #2 (secondary EMI) */ + reg = <0x01>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@2 { /* Slot #3 (secondary EMI) */ + reg = <0x02>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@3 { /* Slot #4 (secondary EMI) */ + reg = <0x03>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@4 { /* Slot #5 (secondary EMI) */ + reg = <0x04>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@5 { /* Slot #6 (secondary EMI) */ + reg = <0x05>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@6 { /* Slot #7 (secondary EMI) */ + reg = <0x06>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@7 { /* Slot #8 (secondary EMI) */ + reg = <0x07>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; + +&crypto { + status = "okay"; +}; + +&dpmac17 { + phy-handle = <&rgmii_phy1>; + phy-connection-type = "rgmii-id"; +}; + +&dpmac18 { + phy-handle = <&rgmii_phy2>; + phy-connection-type = "rgmii-id"; +}; + +&dspi0 { + status = "okay"; + + dflash0: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + }; +}; + +&dspi1 { + status = "okay"; + + dflash1: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + }; +}; + +&dspi2 { + status = "okay"; + + dflash2: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + }; +}; + +&emdio1 { + status = "okay"; +}; + +&emdio2 { + status = "okay"; +}; + +&esdhc0 { + status = "okay"; +}; + +&esdhc1 { + status = "okay"; +}; + +&fspi { + status = "okay"; + + mt35xu512aba0: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + m25p,fast-read; + spi-max-frequency = <50000000>; + reg = <0>; + spi-rx-bus-width = <8>; + spi-tx-bus-width = <8>; + }; +}; + +&i2c0 { + status = "okay"; + + fpga@66 { + compatible = "fsl,lx2160aqds-fpga", "fsl,fpga-qixis-i2c", + "simple-mfd"; + reg = <0x66>; + + mux: mux-controller { + compatible = "reg-mux"; + #mux-control-cells = <1>; + mux-reg-masks = <0x54 0xf8>, /* 0: reg 0x54, bits 7:3 */ + <0x54 0x07>; /* 1: reg 0x54, bit 2:0 */ + }; + }; + + i2c-mux@77 { + compatible = "nxp,pca9547"; + reg = <0x77>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2>; + + power-monitor@40 { + compatible = "ti,ina220"; + reg = <0x40>; + shunt-resistor = <500>; + }; + + power-monitor@41 { + compatible = "ti,ina220"; + reg = <0x41>; + shunt-resistor = <1000>; + }; + }; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x3>; + + temperature-sensor@4c { + compatible = "nxp,sa56004"; + reg = <0x4c>; + vcc-supply = <&sb_3v3>; + }; + + rtc@51 { + compatible = "nxp,pcf2129"; + reg = <0x51>; + }; + }; + }; +}; + +&sata0 { + status = "okay"; +}; + +&sata1 { + status = "okay"; +}; + +&sata2 { + status = "okay"; +}; + +&sata3 { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi index b88c3c99b007..d897913537ca 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi @@ -4,6 +4,11 @@ */ / { + aliases { + rtc0 = &rtc; + rtc1 = &snvs_rtc; + }; + usdhc1_pwrseq: usdhc1_pwrseq { compatible = "mmc-pwrseq-simple"; pinctrl-names = "default"; @@ -24,6 +29,18 @@ cpu-supply = <&buck2_reg>; }; +&A53_1 { + cpu-supply = <&buck2_reg>; +}; + +&A53_2 { + cpu-supply = <&buck2_reg>; +}; + +&A53_3 { + cpu-supply = <&buck2_reg>; +}; + &ddrc { operating-points-v2 = <&ddrc_opp_table>; @@ -63,6 +80,22 @@ }; }; +&flexspi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexspi>; + status = "okay"; + + flash@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + spi-max-frequency = <80000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + }; +}; + &i2c1 { clock-frequency = <400000>; pinctrl-names = "default"; @@ -78,6 +111,10 @@ interrupts = <3 IRQ_TYPE_LEVEL_LOW>; rohm,reset-snvs-powered; + #clock-cells = <0>; + clocks = <&osc_32k 0>; + clock-output-names = "clk-32k-out"; + regulators { buck1_reg: BUCK1 { regulator-name = "buck1"; @@ -191,7 +228,7 @@ reg = <0x50>; }; - rtc@51 { + rtc: rtc@51 { compatible = "nxp,pcf85263"; reg = <0x51>; }; @@ -258,155 +295,166 @@ }; &iomuxc { - pinctrl_fec1: fec1grp { - fsl,pins = < - MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3 - MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3 - MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f - MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f - MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f - MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f - MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91 - MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 - MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 - MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 - MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f - MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 - MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 - MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f - MX8MM_IOMUXC_SAI2_RXC_GPIO4_IO22 0x19 - >; - }; + pinctrl_fec1: fec1grp { + fsl,pins = < + MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3 + MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3 + MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f + MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f + MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f + MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f + MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91 + MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 + MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 + MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 + MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f + MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 + MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 + MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f + MX8MM_IOMUXC_SAI2_RXC_GPIO4_IO22 0x19 + >; + }; - pinctrl_i2c1: i2c1grp { - fsl,pins = < - MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 - MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3 - >; - }; + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 + MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3 + >; + }; - pinctrl_i2c3: i2c3grp { - fsl,pins = < - MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3 - MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3 - >; - }; + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3 + MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3 + >; + }; - pinctrl_pmic: pmicirqgrp { - fsl,pins = < - MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x141 - >; - }; + pinctrl_flexspi: flexspigrp { + fsl,pins = < + MX8MM_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x1c2 + MX8MM_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x82 + MX8MM_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x82 + MX8MM_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x82 + MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x82 + MX8MM_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x82 + >; + }; - pinctrl_uart1: uart1grp { - fsl,pins = < - MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140 - MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140 - MX8MM_IOMUXC_UART3_RXD_UART1_DCE_CTS_B 0x140 - MX8MM_IOMUXC_UART3_TXD_UART1_DCE_RTS_B 0x140 - MX8MM_IOMUXC_SD1_DATA4_GPIO2_IO6 0x19 - MX8MM_IOMUXC_SD1_DATA5_GPIO2_IO7 0x19 - MX8MM_IOMUXC_SD1_DATA6_GPIO2_IO8 0x19 - MX8MM_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K 0x141 - >; - }; + pinctrl_pmic: pmicirqgrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x141 + >; + }; - pinctrl_usdhc1_gpio: usdhc1gpiogrp { - fsl,pins = < - MX8MM_IOMUXC_SD1_RESET_B_GPIO2_IO10 0x41 - >; - }; + pinctrl_uart1: uart1grp { + fsl,pins = < + MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140 + MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140 + MX8MM_IOMUXC_UART3_RXD_UART1_DCE_CTS_B 0x140 + MX8MM_IOMUXC_UART3_TXD_UART1_DCE_RTS_B 0x140 + MX8MM_IOMUXC_SD1_DATA4_GPIO2_IO6 0x19 + MX8MM_IOMUXC_SD1_DATA5_GPIO2_IO7 0x19 + MX8MM_IOMUXC_SD1_DATA6_GPIO2_IO8 0x19 + MX8MM_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K 0x141 + >; + }; - pinctrl_usdhc1: usdhc1grp { - fsl,pins = < - MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 - MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 - MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 - MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 - MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 - MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 - >; - }; + pinctrl_usdhc1_gpio: usdhc1gpiogrp { + fsl,pins = < + MX8MM_IOMUXC_SD1_RESET_B_GPIO2_IO10 0x41 + >; + }; - pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { - fsl,pins = < - MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x194 - MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4 - MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d4 - MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d4 - MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d4 - MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d4 - >; - }; + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 + MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 + MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 + MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 + MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 + MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 + >; + }; - pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { - fsl,pins = < - MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x196 - MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6 - MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d6 - MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d6 - MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d6 - MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d6 - >; - }; + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x194 + MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4 + MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d4 + MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d4 + MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d4 + MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d4 + >; + }; - pinctrl_usdhc3: usdhc3grp { - fsl,pins = < - MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190 - MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0 - MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0 - MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0 - MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0 - MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0 - MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d0 - MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d0 - MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d0 - MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d0 - MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x190 - >; - }; + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x196 + MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6 + MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d6 + MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d6 + MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d6 + MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d6 + >; + }; - pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp { - fsl,pins = < - MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194 - MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4 - MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d4 - MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d4 - MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d4 - MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d4 - MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d4 - MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d4 - MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d4 - MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d4 - MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x194 - >; - }; + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190 + MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0 + MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0 + MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0 + MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0 + MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0 + MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d0 + MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d0 + MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d0 + MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d0 + MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x190 + >; + }; - pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { - fsl,pins = < - MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196 - MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6 - MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d6 - MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d6 - MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d6 - MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d6 - MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d6 - MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d6 - MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d6 - MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d6 - MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x196 - >; - }; + pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194 + MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4 + MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d4 + MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d4 + MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d4 + MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d4 + MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d4 + MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d4 + MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d4 + MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d4 + MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x194 + >; + }; - pinctrl_wdog: wdoggrp { - fsl,pins = < - MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 - >; - }; + pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196 + MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6 + MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d6 + MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d6 + MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d6 + MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d6 + MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d6 + MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d6 + MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d6 + MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d6 + MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x196 + >; + }; - pinctrl_wlan: wlangrp { - fsl,pins = < - MX8MM_IOMUXC_SD1_DATA7_GPIO2_IO9 0x111 - >; - }; + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0x166 + >; + }; + + pinctrl_wlan: wlangrp { + fsl,pins = < + MX8MM_IOMUXC_SD1_DATA7_GPIO2_IO9 0x111 + >; + }; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi index 521eb3a5a12e..6518f088b2c2 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi @@ -41,6 +41,14 @@ enable-active-high; }; + ir-receiver { + compatible = "gpio-ir-receiver"; + gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ir>; + linux,autosuspend-period = <125>; + }; + wm8524: audio-codec { #sound-dai-cells = <0>; compatible = "wlf,wm8524"; @@ -364,6 +372,12 @@ >; }; + pinctrl_ir: irgrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x4f + >; + }; + pinctrl_gpio_wlf: gpiowlfgrp { fsl,pins = < MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21 0xd6 @@ -469,7 +483,7 @@ pinctrl_wdog: wdoggrp { fsl,pins = < - MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 + MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0x166 >; }; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts new file mode 100644 index 000000000000..d17abb515835 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts @@ -0,0 +1,322 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2019 Kontron Electronics GmbH + */ + +/dts-v1/; + +#include "imx8mm-kontron-n801x-som.dtsi" + +/ { + model = "Kontron i.MX8MM N801X S"; + compatible = "kontron,imx8mm-n801x-s", "kontron,imx8mm-n801x-som", "fsl,imx8mm"; + + aliases { + ethernet1 = &usbnet; + }; + + /* fixed crystal dedicated to mcp2515 */ + osc_can: clock-osc-can { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <16000000>; + clock-output-names = "osc-can"; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_led>; + + led1 { + label = "led1"; + gpios = <&gpio4 17 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + + led2 { + label = "led2"; + gpios = <&gpio4 19 GPIO_ACTIVE_LOW>; + }; + + led3 { + label = "led3"; + gpios = <&gpio4 18 GPIO_ACTIVE_LOW>; + }; + + led4 { + label = "led4"; + gpios = <&gpio4 8 GPIO_ACTIVE_LOW>; + }; + + led5 { + label = "led5"; + gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; + }; + + led6 { + label = "led6"; + gpios = <&gpio4 7 GPIO_ACTIVE_LOW>; + }; + }; + + pwm-beeper { + compatible = "pwm-beeper"; + pwms = <&pwm2 0 5000 0>; + }; + + reg_rst_eth2: regulator-rst-eth2 { + compatible = "regulator-fixed"; + regulator-name = "rst-usb-eth2"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb_eth2>; + gpio = <&gpio3 2 GPIO_ACTIVE_LOW>; + }; + + reg_vdd_5v: regulator-5v { + compatible = "regulator-fixed"; + regulator-name = "vdd-5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +}; + +&ecspi2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi2>; + cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>; + status = "okay"; + + can0: can@0 { + compatible = "microchip,mcp2515"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can>; + clocks = <&osc_can>; + interrupt-parent = <&gpio4>; + interrupts = <28 IRQ_TYPE_EDGE_FALLING>; + spi-max-frequency = <100000>; + vdd-supply = <®_vdd_3v3>; + xceiver-supply = <®_vdd_5v>; + }; +}; + +&ecspi3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi3>; + cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-connection-type = "rgmii"; + phy-handle = <ðphy>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy: ethernet-phy@0 { + reg = <0>; + reset-assert-us = <100>; + reset-deassert-us = <100>; + reset-gpios = <&gpio4 27 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&i2c4 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4>; + status = "okay"; + + rtc@32 { + compatible = "epson,rx8900"; + reg = <0x32>; + }; +}; + +&pwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm2>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + uart-has-rtscts; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + linux,rs485-enabled-at-boot-time; + uart-has-rtscts; + status = "okay"; +}; + +&usbotg1 { + dr_mode = "otg"; + over-current-active-low; + status = "okay"; +}; + +&usbotg2 { + dr_mode = "host"; + disable-over-current; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + usb1@1 { + compatible = "usb424,9514"; + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + usbnet: usbether@1 { + compatible = "usb424,ec00"; + reg = <1>; + local-mac-address = [ 00 00 00 00 00 00 ]; + }; + }; +}; + +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + vmmc-supply = <®_vdd_3v3>; + vqmmc-supply = <®_nvcc_sd>; + cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio>; + + pinctrl_can: cangrp { + fsl,pins = < + MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x19 + >; + }; + + pinctrl_ecspi2: ecspi2grp { + fsl,pins = < + MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x82 + MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x82 + MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x82 + MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x19 + >; + }; + + pinctrl_ecspi3: ecspi3grp { + fsl,pins = < + MX8MM_IOMUXC_UART2_RXD_ECSPI3_MISO 0x82 + MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI 0x82 + MX8MM_IOMUXC_UART1_RXD_ECSPI3_SCLK 0x82 + MX8MM_IOMUXC_UART2_TXD_GPIO5_IO25 0x19 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3 + MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3 + MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f + MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f + MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f + MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f + MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91 + MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 + MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 + MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 + MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f + MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 + MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 + MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f + MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x19 /* PHY RST */ + MX8MM_IOMUXC_SAI2_TXC_GPIO4_IO25 0x19 /* ETH IRQ */ + >; + }; + + pinctrl_gpio_led: gpioledgrp { + fsl,pins = < + MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16 0x19 + MX8MM_IOMUXC_SAI1_RXD5_GPIO4_IO7 0x19 + MX8MM_IOMUXC_SAI1_RXD6_GPIO4_IO8 0x19 + MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9 0x19 + MX8MM_IOMUXC_SAI1_TXD5_GPIO4_IO17 0x19 + MX8MM_IOMUXC_SAI1_TXD6_GPIO4_IO18 0x19 + MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19 0x19 + >; + }; + + pinctrl_gpio: gpiogrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x19 + MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x19 + MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 + MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x19 + MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x19 + MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x19 + MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x19 + MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x19 + >; + }; + + pinctrl_i2c4: i2c4grp { + fsl,pins = < + MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c3 + MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c3 + >; + }; + + pinctrl_pwm2: pwm2grp { + fsl,pins = < + MX8MM_IOMUXC_SPDIF_RX_PWM2_OUT 0x19 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x140 + MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x140 + MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x140 + MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x140 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x140 + MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x140 + MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x140 + MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x140 + >; + }; + + pinctrl_usb_eth2: usbeth2grp { + fsl,pins = < + MX8MM_IOMUXC_NAND_CE1_B_GPIO3_IO2 0x19 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 + MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0 + MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0 + MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0 + MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0 + MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0 + MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019 + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi new file mode 100644 index 000000000000..d0456daefda8 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright (C) 2019 Kontron Electronics GmbH + */ + +#include "imx8mm.dtsi" + +/ { + model = "Kontron i.MX8MM N801X SoM"; + compatible = "kontron,imx8mm-n801x-som", "fsl,imx8mm"; + + memory@40000000 { + device_type = "memory"; + /* + * There are multiple SoM flavors with different DDR sizes. + * The smallest is 1GB. For larger sizes the bootloader will + * update the reg property. + */ + reg = <0x0 0x40000000 0 0x80000000>; + }; + + chosen { + stdout-path = &uart3; + }; +}; + +&A53_0 { + cpu-supply = <®_vdd_arm>; +}; + +&A53_1 { + cpu-supply = <®_vdd_arm>; +}; + +&A53_2 { + cpu-supply = <®_vdd_arm>; +}; + +&A53_3 { + cpu-supply = <®_vdd_arm>; +}; + +&ddrc { + operating-points-v2 = <&ddrc_opp_table>; + + ddrc_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-25M { + opp-hz = /bits/ 64 <25000000>; + }; + + opp-100M { + opp-hz = /bits/ 64 <100000000>; + }; + + opp-750M { + opp-hz = /bits/ 64 <750000000>; + }; + }; +}; + +&ecspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1>; + cs-gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>; + status = "okay"; + + spi-flash@0 { + compatible = "mxicy,mx25r1635f", "jedec,spi-nor"; + spi-max-frequency = <80000000>; + reg = <0>; + }; +}; + +&i2c1 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + pca9450: pmic@25 { + compatible = "nxp,pca9450a"; + reg = <0x25>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic>; + interrupt-parent = <&gpio1>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + + regulators { + reg_vdd_soc: BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <3125>; + }; + + reg_vdd_arm: BUCK2 { + regulator-name = "buck2"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <950000>; + regulator-boot-on; + regulator-ramp-delay = <3125>; + nxp,dvs-run-voltage = <950000>; + nxp,dvs-standby-voltage = <850000>; + }; + + reg_vdd_dram: BUCK3 { + regulator-name = "buck3"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_vdd_3v3: BUCK4 { + regulator-name = "buck4"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_vdd_1v8: BUCK5 { + regulator-name = "buck5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_nvcc_dram: BUCK6 { + regulator-name = "buck6"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_nvcc_snvs: LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_vdd_snvs: LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_vdda: LDO3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_vdd_phy: LDO4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_nvcc_sd: LDO5 { + regulator-name = "ldo5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + }; + }; + }; +}; + +&uart3 { /* console */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + status = "okay"; +}; + +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + vmmc-supply = <®_vdd_3v3>; + vqmmc-supply = <®_vdd_1v8>; + bus-width = <8>; + non-removable; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; + +&iomuxc { + pinctrl_ecspi1: ecspi1grp { + fsl,pins = < + MX8MM_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x82 + MX8MM_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x82 + MX8MM_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK 0x82 + MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x19 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 + MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3 + >; + }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x141 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX8MM_IOMUXC_UART3_RXD_UART3_DCE_RX 0x140 + MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX 0x140 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 + MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 + MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 + MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 + MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 + MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 + MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d0 + MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d0 + MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d0 + MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d0 + MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0x019 + MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x190 + >; + }; + + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x194 + MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4 + MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d4 + MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d4 + MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d4 + MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d4 + MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d4 + MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d4 + MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d4 + MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d4 + MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0x019 + MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x194 + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x196 + MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6 + MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d6 + MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d6 + MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d6 + MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d6 + MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4 0x1d6 + MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5 0x1d6 + MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6 0x1d6 + MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7 0x1d6 + MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0x019 + MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x196 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-var-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-var-som.dtsi index 49082529764f..1dc9d187601c 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-var-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-var-som.dtsi @@ -552,7 +552,7 @@ pinctrl_wdog: wdoggrp { fsl,pins = < - MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 + MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0x166 >; }; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi index 05ee062548e4..c824f2615fe8 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi @@ -194,16 +194,16 @@ pmu { compatible = "arm,armv8-pmuv3"; interrupts = <GIC_PPI 7 - (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>; + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; interrupt-affinity = <&A53_0>, <&A53_1>, <&A53_2>, <&A53_3>; }; timer { compatible = "arm,armv8-timer"; - interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Secure */ - <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Non-Secure */ - <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, /* Virtual */ - <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; /* Hypervisor */ + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Secure */ + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, /* Physical Non-Secure */ + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, /* Virtual */ + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; /* Hypervisor */ clock-frequency = <8000000>; arm,no-tick-in-suspend; }; @@ -339,6 +339,49 @@ status = "disabled"; }; + micfil: audio-controller@30080000 { + compatible = "fsl,imx8mm-micfil"; + reg = <0x30080000 0x10000>; + interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_PDM_IPG>, + <&clk IMX8MM_CLK_PDM_ROOT>, + <&clk IMX8MM_AUDIO_PLL1_OUT>, + <&clk IMX8MM_AUDIO_PLL2_OUT>, + <&clk IMX8MM_CLK_EXT3>; + clock-names = "ipg_clk", "ipg_clk_app", + "pll8k", "pll11k", "clkext3"; + dmas = <&sdma2 24 25 0x80000000>; + dma-names = "rx"; + status = "disabled"; + }; + + spdif1: spdif@30090000 { + compatible = "fsl,imx35-spdif"; + reg = <0x30090000 0x10000>; + interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_AUDIO_AHB>, /* core */ + <&clk IMX8MM_CLK_24M>, /* rxtx0 */ + <&clk IMX8MM_CLK_SPDIF1>, /* rxtx1 */ + <&clk IMX8MM_CLK_DUMMY>, /* rxtx2 */ + <&clk IMX8MM_CLK_DUMMY>, /* rxtx3 */ + <&clk IMX8MM_CLK_DUMMY>, /* rxtx4 */ + <&clk IMX8MM_CLK_AUDIO_AHB>, /* rxtx5 */ + <&clk IMX8MM_CLK_DUMMY>, /* rxtx6 */ + <&clk IMX8MM_CLK_DUMMY>, /* rxtx7 */ + <&clk IMX8MM_CLK_DUMMY>; /* spba */ + clock-names = "core", "rxtx0", + "rxtx1", "rxtx2", + "rxtx3", "rxtx4", + "rxtx5", "rxtx6", + "rxtx7", "spba"; + dmas = <&sdma2 28 18 0>, <&sdma2 29 18 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + gpio1: gpio@30200000 { compatible = "fsl,imx8mm-gpio", "fsl,imx35-gpio"; reg = <0x30200000 0x10000>; diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dts b/arch/arm64/boot/dts/freescale/imx8mn-evk.dts index 8311b95dee49..b4225cfcb6d9 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dts @@ -14,6 +14,22 @@ compatible = "fsl,imx8mn-evk", "fsl,imx8mn"; }; +&A53_0 { + cpu-supply = <&buck2>; +}; + +&A53_1 { + cpu-supply = <&buck2>; +}; + +&A53_2 { + cpu-supply = <&buck2>; +}; + +&A53_3 { + cpu-supply = <&buck2>; +}; + &i2c1 { pmic: pmic@25 { compatible = "nxp,pca9450b"; @@ -110,19 +126,3 @@ }; }; }; - -&A53_0 { - /delete-property/operating-points-v2; -}; - -&A53_1 { - /delete-property/operating-points-v2; -}; - -&A53_2 { - /delete-property/operating-points-v2; -}; - -&A53_3 { - /delete-property/operating-points-v2; -}; diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi index 4aa0dbd578df..76d042a4cf09 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi @@ -38,6 +38,14 @@ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; enable-active-high; }; + + ir-receiver { + compatible = "gpio-ir-receiver"; + gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ir>; + linux,autosuspend-period = <125>; + }; }; &fec1 { @@ -202,6 +210,12 @@ >; }; + pinctrl_ir: irgrp { + fsl,pins = < + MX8MN_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x4f + >; + }; + pinctrl_i2c1: i2c1grp { fsl,pins = < MX8MN_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 @@ -340,7 +354,7 @@ pinctrl_wdog: wdoggrp { fsl,pins = < - MX8MN_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 + MX8MN_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0x166 >; }; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi index 7f356edf9f91..b16c7caf34c1 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi @@ -542,7 +542,7 @@ pinctrl_wdog: wdoggrp { fsl,pins = < - MX8MN_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 + MX8MN_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0x166 >; }; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi index 16c7202885d7..ee1790230490 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi @@ -186,6 +186,13 @@ clock-output-names = "clk_ext4"; }; + pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <GIC_PPI 7 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + interrupt-affinity = <&A53_0>, <&A53_1>, <&A53_2>, <&A53_3>; + }; + psci { compatible = "arm,psci-1.0"; method = "smc"; @@ -225,10 +232,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; clock-frequency = <8000000>; arm,no-tick-in-suspend; }; @@ -246,6 +253,149 @@ #size-cells = <1>; ranges; + spba: bus@30000000 { + compatible = "fsl,spba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x30000000 0x100000>; + ranges; + + sai2: sai@30020000 { + compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; + reg = <0x30020000 0x10000>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MN_CLK_SAI2_IPG>, + <&clk IMX8MN_CLK_DUMMY>, + <&clk IMX8MN_CLK_SAI2_ROOT>, + <&clk IMX8MN_CLK_DUMMY>, <&clk IMX8MN_CLK_DUMMY>; + clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma2 2 2 0>, <&sdma2 3 2 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + sai3: sai@30030000 { + compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; + reg = <0x30030000 0x10000>; + interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MN_CLK_SAI3_IPG>, + <&clk IMX8MN_CLK_DUMMY>, + <&clk IMX8MN_CLK_SAI3_ROOT>, + <&clk IMX8MN_CLK_DUMMY>, <&clk IMX8MN_CLK_DUMMY>; + clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma2 4 2 0>, <&sdma2 5 2 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + sai5: sai@30050000 { + compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; + reg = <0x30050000 0x10000>; + interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MN_CLK_SAI5_IPG>, + <&clk IMX8MN_CLK_DUMMY>, + <&clk IMX8MN_CLK_SAI5_ROOT>, + <&clk IMX8MN_CLK_DUMMY>, <&clk IMX8MN_CLK_DUMMY>; + clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma2 8 2 0>, <&sdma2 9 2 0>; + dma-names = "rx", "tx"; + fsl,shared-interrupt; + fsl,dataline = <0 0xf 0xf>; + status = "disabled"; + }; + + sai6: sai@30060000 { + compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; + reg = <0x30060000 0x10000>; + interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MN_CLK_SAI6_IPG>, + <&clk IMX8MN_CLK_DUMMY>, + <&clk IMX8MN_CLK_SAI6_ROOT>, + <&clk IMX8MN_CLK_DUMMY>, <&clk IMX8MN_CLK_DUMMY>; + clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma2 10 2 0>, <&sdma2 11 2 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + micfil: audio-controller@30080000 { + compatible = "fsl,imx8mm-micfil"; + reg = <0x30080000 0x10000>; + interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MN_CLK_PDM_IPG>, + <&clk IMX8MN_CLK_PDM_ROOT>, + <&clk IMX8MN_AUDIO_PLL1_OUT>, + <&clk IMX8MN_AUDIO_PLL2_OUT>, + <&clk IMX8MN_CLK_EXT3>; + clock-names = "ipg_clk", "ipg_clk_app", + "pll8k", "pll11k", "clkext3"; + dmas = <&sdma2 24 25 0x80000000>; + dma-names = "rx"; + status = "disabled"; + }; + + spdif1: spdif@30090000 { + compatible = "fsl,imx35-spdif"; + reg = <0x30090000 0x10000>; + interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MN_CLK_AUDIO_AHB>, /* core */ + <&clk IMX8MN_CLK_24M>, /* rxtx0 */ + <&clk IMX8MN_CLK_SPDIF1>, /* rxtx1 */ + <&clk IMX8MN_CLK_DUMMY>, /* rxtx2 */ + <&clk IMX8MN_CLK_DUMMY>, /* rxtx3 */ + <&clk IMX8MN_CLK_DUMMY>, /* rxtx4 */ + <&clk IMX8MN_CLK_AUDIO_AHB>, /* rxtx5 */ + <&clk IMX8MN_CLK_DUMMY>, /* rxtx6 */ + <&clk IMX8MN_CLK_DUMMY>, /* rxtx7 */ + <&clk IMX8MN_CLK_DUMMY>; /* spba */ + clock-names = "core", "rxtx0", + "rxtx1", "rxtx2", + "rxtx3", "rxtx4", + "rxtx5", "rxtx6", + "rxtx7", "spba"; + dmas = <&sdma2 28 18 0>, <&sdma2 29 18 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + sai7: sai@300b0000 { + compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; + reg = <0x300b0000 0x10000>; + interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MN_CLK_SAI7_IPG>, + <&clk IMX8MN_CLK_DUMMY>, + <&clk IMX8MN_CLK_SAI7_ROOT>, + <&clk IMX8MN_CLK_DUMMY>, <&clk IMX8MN_CLK_DUMMY>; + clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma2 12 2 0>, <&sdma2 13 2 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + easrc: easrc@300c0000 { + compatible = "fsl,imx8mn-easrc"; + reg = <0x300c0000 0x10000>; + interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MN_CLK_ASRC_ROOT>; + clock-names = "mem"; + dmas = <&sdma2 16 23 0> , <&sdma2 17 23 0>, + <&sdma2 18 23 0> , <&sdma2 19 23 0>, + <&sdma2 20 23 0> , <&sdma2 21 23 0>, + <&sdma2 22 23 0> , <&sdma2 23 23 0>; + dma-names = "ctx0_rx", "ctx0_tx", + "ctx1_rx", "ctx1_tx", + "ctx2_rx", "ctx2_tx", + "ctx3_rx", "ctx3_tx"; + firmware-name = "imx/easrc/easrc-imx8mn.bin"; + fsl,asrc-rate = <8000>; + fsl,asrc-format = <2>; + status = "disabled"; + }; + }; + gpio1: gpio@30200000 { compatible = "fsl,imx8mn-gpio", "fsl,imx35-gpio"; reg = <0x30200000 0x10000>; diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts index ad66f1286d95..b10dce8767a4 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -33,6 +33,28 @@ <0x1 0x00000000 0 0xc0000000>; }; + reg_can1_stby: regulator-can1-stby { + compatible = "regulator-fixed"; + regulator-name = "can1-stby"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1_reg>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio5 5 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_can2_stby: regulator-can2-stby { + compatible = "regulator-fixed"; + regulator-name = "can2-stby"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2_reg>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + reg_usdhc2_vmmc: regulator-usdhc2 { compatible = "regulator-fixed"; pinctrl-names = "default"; @@ -45,6 +67,20 @@ }; }; +&flexcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1>; + xceiver-supply = <®_can1_stby>; + status = "okay"; +}; + +&flexcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2>; + xceiver-supply = <®_can2_stby>; + status = "disabled";/* can2 pin conflict with pdm */ +}; + &fec { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec>; @@ -144,6 +180,32 @@ >; }; + pinctrl_flexcan1: flexcan1grp { + fsl,pins = < + MX8MP_IOMUXC_SPDIF_RX__CAN1_RX 0x154 + MX8MP_IOMUXC_SPDIF_TX__CAN1_TX 0x154 + >; + }; + + pinctrl_flexcan2: flexcan2grp { + fsl,pins = < + MX8MP_IOMUXC_SAI5_MCLK__CAN2_RX 0x154 + MX8MP_IOMUXC_SAI5_RXD3__CAN2_TX 0x154 + >; + }; + + pinctrl_flexcan1_reg: flexcan1reggrp { + fsl,pins = < + MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 0x154 /* CAN1_STBY */ + >; + }; + + pinctrl_flexcan2_reg: flexcan2reggrp { + fsl,pins = < + MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27 0x154 /* CAN2_STBY */ + >; + }; + pinctrl_gpio_led: gpioledgrp { fsl,pins = < MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x19 @@ -262,7 +324,7 @@ pinctrl_wdog: wdoggrp { fsl,pins = < - MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0xc6 + MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0x166 >; }; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index 6038f66aefc1..ecccfbb4f5ad 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi @@ -133,6 +133,13 @@ clock-output-names = "clk_ext4"; }; + pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <GIC_PPI 7 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + interrupt-affinity = <&A53_0>, <&A53_1>, <&A53_2>, <&A53_3>; + }; + psci { compatible = "arm,psci-1.0"; method = "smc"; @@ -202,10 +209,10 @@ timer { compatible = "arm,armv8-timer"; - interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, - <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; clock-frequency = <8000000>; arm,no-tick-in-suspend; }; @@ -545,6 +552,36 @@ status = "disabled"; }; + flexcan1: can@308c0000 { + compatible = "fsl,imx8mp-flexcan", "fsl,imx6q-flexcan"; + reg = <0x308c0000 0x10000>; + interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_IPG_ROOT>, + <&clk IMX8MP_CLK_CAN1_ROOT>; + clock-names = "ipg", "per"; + assigned-clocks = <&clk IMX8MP_CLK_CAN1>; + assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_40M>; + assigned-clock-rates = <40000000>; + fsl,clk-source = /bits/ 8 <0>; + fsl,stop-mode = <&gpr 0x10 4>; + status = "disabled"; + }; + + flexcan2: can@308d0000 { + compatible = "fsl,imx8mp-flexcan", "fsl,imx6q-flexcan"; + reg = <0x308d0000 0x10000>; + interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MP_CLK_IPG_ROOT>, + <&clk IMX8MP_CLK_CAN2_ROOT>; + clock-names = "ipg", "per"; + assigned-clocks = <&clk IMX8MP_CLK_CAN2>; + assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_40M>; + assigned-clock-rates = <40000000>; + fsl,clk-source = /bits/ 8 <0>; + fsl,stop-mode = <&gpr 0x10 5>; + status = "disabled"; + }; + crypto: crypto@30900000 { compatible = "fsl,sec-v4.0"; #address-cells = <1>; diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts index 2418cca00bc5..85b045253a0e 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts @@ -57,6 +57,7 @@ gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ir>; + linux,autosuspend-period = <125>; }; wm8524: audio-codec { @@ -87,6 +88,21 @@ clocks = <&clk IMX8MQ_CLK_SAI2_ROOT>; }; }; + + sound-spdif { + compatible = "fsl,imx-audio-spdif"; + model = "imx-spdif"; + spdif-controller = <&spdif1>; + spdif-out; + spdif-in; + }; + + sound-hdmi-arc { + compatible = "fsl,imx-audio-spdif"; + model = "imx-hdmi-arc"; + spdif-controller = <&spdif2>; + spdif-in; + }; }; &A53_0 { @@ -336,6 +352,22 @@ status = "okay"; }; +&spdif1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spdif1>; + assigned-clocks = <&clk IMX8MQ_CLK_SPDIF1>; + assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>; + assigned-clock-rates = <24576000>; + status = "okay"; +}; + +&spdif2 { + assigned-clocks = <&clk IMX8MQ_CLK_SPDIF2>; + assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>; + assigned-clock-rates = <24576000>; + status = "okay"; +}; + &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; @@ -467,6 +499,13 @@ >; }; + pinctrl_spdif1: spdif1grp { + fsl,pins = < + MX8MQ_IOMUXC_SPDIF_TX_SPDIF1_OUT 0xd6 + MX8MQ_IOMUXC_SPDIF_RX_SPDIF1_IN 0xd6 + >; + }; + pinctrl_uart1: uart1grp { fsl,pins = < MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x49 diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi index e3c6d1272198..64fc546b110f 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi @@ -250,7 +250,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pmic_5v>; - pmic-5v { + pmic-5v-hog { gpio-hog; gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; input; diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi index 5e0e7d0f1bc4..a841a023e8e0 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi @@ -606,11 +606,25 @@ "clk_ext3", "clk_ext4"; assigned-clocks = <&clk IMX8MQ_CLK_A53_SRC>, <&clk IMX8MQ_CLK_A53_CORE>, - <&clk IMX8MQ_CLK_NOC>; + <&clk IMX8MQ_CLK_NOC>, + <&clk IMX8MQ_CLK_AUDIO_AHB>, + <&clk IMX8MQ_AUDIO_PLL1_BYPASS>, + <&clk IMX8MQ_AUDIO_PLL2_BYPASS>, + <&clk IMX8MQ_AUDIO_PLL1>, + <&clk IMX8MQ_AUDIO_PLL2>; assigned-clock-rates = <0>, <0>, - <800000000>; + <800000000>, + <0>, + <0>, + <0>, + <786432000>, + <722534400>; assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_800M>, - <&clk IMX8MQ_ARM_PLL_OUT>; + <&clk IMX8MQ_ARM_PLL_OUT>, + <0>, + <&clk IMX8MQ_SYS2_PLL_500M>, + <&clk IMX8MQ_AUDIO_PLL1>, + <&clk IMX8MQ_AUDIO_PLL2>; }; src: reset-controller@30390000 { @@ -779,6 +793,30 @@ ranges = <0x30800000 0x30800000 0x400000>, <0x08000000 0x08000000 0x10000000>; + spdif1: spdif@30810000 { + compatible = "fsl,imx35-spdif"; + reg = <0x30810000 0x10000>; + interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_IPG_ROOT>, /* core */ + <&clk IMX8MQ_CLK_25M>, /* rxtx0 */ + <&clk IMX8MQ_CLK_SPDIF1>, /* rxtx1 */ + <&clk IMX8MQ_CLK_DUMMY>, /* rxtx2 */ + <&clk IMX8MQ_CLK_DUMMY>, /* rxtx3 */ + <&clk IMX8MQ_CLK_DUMMY>, /* rxtx4 */ + <&clk IMX8MQ_CLK_IPG_ROOT>, /* rxtx5 */ + <&clk IMX8MQ_CLK_DUMMY>, /* rxtx6 */ + <&clk IMX8MQ_CLK_DUMMY>, /* rxtx7 */ + <&clk IMX8MQ_CLK_DUMMY>; /* spba */ + clock-names = "core", "rxtx0", + "rxtx1", "rxtx2", + "rxtx3", "rxtx4", + "rxtx5", "rxtx6", + "rxtx7", "spba"; + dmas = <&sdma1 8 18 0>, <&sdma1 9 18 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + ecspi1: spi@30820000 { #address-cells = <1>; #size-cells = <0>; @@ -848,6 +886,30 @@ status = "disabled"; }; + spdif2: spdif@308a0000 { + compatible = "fsl,imx35-spdif"; + reg = <0x308a0000 0x10000>; + interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_IPG_ROOT>, /* core */ + <&clk IMX8MQ_CLK_25M>, /* rxtx0 */ + <&clk IMX8MQ_CLK_SPDIF2>, /* rxtx1 */ + <&clk IMX8MQ_CLK_DUMMY>, /* rxtx2 */ + <&clk IMX8MQ_CLK_DUMMY>, /* rxtx3 */ + <&clk IMX8MQ_CLK_DUMMY>, /* rxtx4 */ + <&clk IMX8MQ_CLK_IPG_ROOT>, /* rxtx5 */ + <&clk IMX8MQ_CLK_DUMMY>, /* rxtx6 */ + <&clk IMX8MQ_CLK_DUMMY>, /* rxtx7 */ + <&clk IMX8MQ_CLK_DUMMY>; /* spba */ + clock-names = "core", "rxtx0", + "rxtx1", "rxtx2", + "rxtx3", "rxtx4", + "rxtx5", "rxtx6", + "rxtx7", "spba"; + dmas = <&sdma1 16 18 0>, <&sdma1 17 18 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + sai2: sai@308b0000 { #sound-dai-cells = <0>; compatible = "fsl,imx8mq-sai"; diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index 994140fbc916..49c19c6879f9 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -971,8 +971,8 @@ #address-cells = <1>; #size-cells = <0>; interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg_ctrl HI3660_CLK_GATE_SPI2>; - clock-names = "apb_pclk"; + clocks = <&crg_ctrl HI3660_CLK_GATE_SPI2>, <&crg_ctrl HI3660_CLK_GATE_SPI2>; + clock-names = "sspclk", "apb_pclk"; pinctrl-names = "default"; pinctrl-0 = <&spi2_pmx_func &spi2_cfg_func>; num-cs = <1>; @@ -986,8 +986,8 @@ #address-cells = <1>; #size-cells = <0>; interrupts = <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg_ctrl HI3660_CLK_GATE_SPI3>; - clock-names = "apb_pclk"; + clocks = <&crg_ctrl HI3660_CLK_GATE_SPI3>, <&crg_ctrl HI3660_CLK_GATE_SPI3>; + clock-names = "sspclk", "apb_pclk"; pinctrl-names = "default"; pinctrl-0 = <&spi3_pmx_func &spi3_cfg_func>; num-cs = <1>; @@ -1045,7 +1045,8 @@ clocks = <&crg_ctrl HI3660_CLK_GATE_UFSIO_REF>, <&crg_ctrl HI3660_CLK_GATE_UFSPHY_CFG>; clock-names = "ref_clk", "phy_clk"; - freq-table-hz = <0 0>, <0 0>; + freq-table-hz = <0 0 + 0 0>; /* offset: 0x84; bit: 12 */ resets = <&crg_rst 0x84 12>; reset-names = "rst"; @@ -1168,7 +1169,7 @@ }; }; - dwc3: dwc3@ff100000 { + dwc3: usb@ff100000 { compatible = "snps,dwc3"; reg = <0x0 0xff100000 0x0 0x100000>; diff --git a/arch/arm64/boot/dts/hisilicon/hi3670.dtsi b/arch/arm64/boot/dts/hisilicon/hi3670.dtsi index 2dcffa3ed218..85b0dfb35d6d 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3670.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3670.dtsi @@ -213,7 +213,6 @@ clocks = <&crg_ctrl HI3670_CLK_GATE_UART1>, <&crg_ctrl HI3670_PCLK>; clock-names = "uartclk", "apb_pclk"; - pinctrl-names = "default"; status = "disabled"; }; @@ -260,7 +259,6 @@ clocks = <&crg_ctrl HI3670_CLK_GATE_UART5>, <&crg_ctrl HI3670_PCLK>; clock-names = "uartclk", "apb_pclk"; - pinctrl-names = "default"; status = "disabled"; }; @@ -667,7 +665,8 @@ clocks = <&crg_ctrl HI3670_CLK_GATE_UFSIO_REF>, <&crg_ctrl HI3670_CLK_GATE_UFS_SUBSYS>; clock-names = "ref_clk", "phy_clk"; - freq-table-hz = <0 0>, <0 0>; + freq-table-hz = <0 0 + 0 0>; /* offset: 0x84; bit: 12 */ resets = <&crg_rst 0x84 12>; reset-names = "rst"; diff --git a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi index 12bc1d3ed424..81d09434c5c6 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi @@ -91,11 +91,10 @@ gmacphyrst: reset-controller { compatible = "ti,syscon-reset"; #reset-cells = <1>; - ti,reset-bits = - <0xcc 12 0xcc 12 0 0 (ASSERT_CLEAR | - DEASSERT_SET|STATUS_NONE)>, - <0xcc 13 0xcc 13 0 0 (ASSERT_CLEAR | - DEASSERT_SET|STATUS_NONE)>; + ti,reset-bits = < + 0xcc 12 0xcc 12 0 0 (ASSERT_CLEAR | DEASSERT_SET | STATUS_NONE) + 0xcc 13 0xcc 13 0 0 (ASSERT_CLEAR | DEASSERT_SET | STATUS_NONE) + >; }; }; @@ -217,8 +216,8 @@ compatible = "arm,pl011", "arm,primecell"; reg = <0x8b00000 0x1000>; interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&sysctrl HISTB_UART0_CLK>; - clock-names = "apb_pclk"; + clocks = <&sysctrl HISTB_UART0_CLK>, <&sysctrl HISTB_UART0_CLK>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; }; @@ -226,8 +225,8 @@ compatible = "arm,pl011", "arm,primecell"; reg = <0x8b02000 0x1000>; interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HISTB_UART2_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HISTB_UART2_CLK>, <&crg HISTB_UART2_CLK>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; }; @@ -292,8 +291,8 @@ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; num-cs = <1>; cs-gpios = <&gpio7 1 0>; - clocks = <&crg HISTB_SPI0_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HISTB_SPI0_CLK>, <&crg HISTB_SPI0_CLK>; + clock-names = "sspclk", "apb_pclk"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -305,7 +304,7 @@ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; clocks = <&crg HISTB_SDIO0_CIU_CLK>, <&crg HISTB_SDIO0_BIU_CLK>; - clock-names = "ciu", "biu"; + clock-names = "biu", "ciu"; resets = <&crg 0x9c 4>; reset-names = "reset"; status = "disabled"; @@ -585,7 +584,7 @@ status = "disabled"; }; - ohci: ohci@9880000 { + ohci: usb@9880000 { compatible = "generic-ohci"; reg = <0x9880000 0x10000>; interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; @@ -600,7 +599,7 @@ status = "disabled"; }; - ehci: ehci@9890000 { + ehci: usb@9890000 { compatible = "generic-ehci"; reg = <0x9890000 0x10000>; interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi index 014735a9bc73..c6580c9f068e 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi @@ -725,8 +725,8 @@ interrupts = <0 50 4>; bus-id = <0>; enable-dma = <0>; - clocks = <&sys_ctrl HI6220_SPI_CLK>; - clock-names = "apb_pclk"; + clocks = <&sys_ctrl HI6220_SPI_CLK>, <&sys_ctrl HI6220_SPI_CLK>; + clock-names = "sspclk", "apb_pclk"; pinctrl-names = "default"; pinctrl-0 = <&spi0_pmx_func &spi0_cfg_func>; num-cs = <1>; diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi index bc49955360db..405acaa3e9dd 100644 --- a/arch/arm64/boot/dts/hisilicon/hip05.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi @@ -242,28 +242,28 @@ <0x0 0xfe020000 0 0x10000>; /* GICV */ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; - its_peri: interrupt-controller@8c000000 { + its_peri: msi-controller@8c000000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; reg = <0x0 0x8c000000 0x0 0x40000>; }; - its_m3: interrupt-controller@a3000000 { + its_m3: msi-controller@a3000000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; reg = <0x0 0xa3000000 0x0 0x40000>; }; - its_pcie: interrupt-controller@b7000000 { + its_pcie: msi-controller@b7000000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; reg = <0x0 0xb7000000 0x0 0x40000>; }; - its_dsa: interrupt-controller@c6000000 { + its_dsa: msi-controller@c6000000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; @@ -296,23 +296,23 @@ clock-frequency = <200000000>; }; - uart0: uart@80300000 { + uart0: serial@80300000 { compatible = "snps,dw-apb-uart"; reg = <0x0 0x80300000 0x0 0x10000>; interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&refclk200mhz>; - clock-names = "apb_pclk"; + clocks = <&refclk200mhz>, <&refclk200mhz>; + clock-names = "baudclk", "apb_pclk"; reg-shift = <2>; reg-io-width = <4>; status = "disabled"; }; - uart1: uart@80310000 { + uart1: serial@80310000 { compatible = "snps,dw-apb-uart"; reg = <0x0 0x80310000 0x0 0x10000>; interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&refclk200mhz>; - clock-names = "apb_pclk"; + clocks = <&refclk200mhz>, <&refclk200mhz>; + clock-names = "baudclk", "apb_pclk"; reg-shift = <2>; reg-io-width = <4>; status = "disabled"; @@ -335,7 +335,7 @@ compatible = "snps,dw-apb-gpio-port"; gpio-controller; #gpio-cells = <2>; - snps,nr-gpios = <32>; + ngpios = <32>; reg = <0>; interrupt-controller; #interrupt-cells = <2>; @@ -354,7 +354,7 @@ compatible = "snps,dw-apb-gpio-port"; gpio-controller; #gpio-cells = <2>; - snps,nr-gpios = <32>; + ngpios = <32>; reg = <0>; interrupt-controller; #interrupt-cells = <2>; diff --git a/arch/arm64/boot/dts/hisilicon/hip06.dtsi b/arch/arm64/boot/dts/hisilicon/hip06.dtsi index 50ceaa959bdc..7980709e21ff 100644 --- a/arch/arm64/boot/dts/hisilicon/hip06.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hip06.dtsi @@ -242,7 +242,7 @@ <0x0 0xfe020000 0 0x10000>; /* GICV */ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; - its_dsa: interrupt-controller@c6000000 { + its_dsa: msi-controller@c6000000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; @@ -330,7 +330,7 @@ * when iommu-map entry is used along with the PCIe node. * Refer:https://www.spinics.net/lists/arm-kernel/msg602812.html */ - smmu0: smmu_pcie { + smmu0: iommu@a0040000 { compatible = "arm,smmu-v3"; reg = <0x0 0xa0040000 0x0 0x20000>; #iommu-cells = <1>; @@ -359,7 +359,7 @@ status = "disabled"; }; - uart0: lpc-uart@2f8 { + uart0: serial@2f8 { compatible = "ns16550a"; clock-frequency = <1843200>; reg = <0x01 0x2f8 0x08>; @@ -373,7 +373,7 @@ #clock-cells = <0>; }; - usb_ohci: ohci@a7030000 { + usb_ohci: usb@a7030000 { compatible = "generic-ohci"; reg = <0x0 0xa7030000 0x0 0x10000>; interrupt-parent = <&mbigen_usb>; @@ -382,7 +382,7 @@ status = "disabled"; }; - usb_ehci: ehci@a7020000 { + usb_ehci: usb@a7020000 { compatible = "generic-ehci"; reg = <0x0 0xa7020000 0x0 0x10000>; interrupt-parent = <&mbigen_usb>; @@ -434,8 +434,8 @@ #size-cells = <0>; compatible = "hisilicon,hns-dsaf-v2"; mode = "6port-16rss"; - reg = <0x0 0xc5000000 0x0 0x890000 - 0x0 0xc7000000 0x0 0x600000>; + reg = <0x0 0xc5000000 0x0 0x890000>, + <0x0 0xc7000000 0x0 0x600000>; reg-names = "ppe-base", "dsaf-base"; interrupt-parent = <&mbigen_dsaf0>; subctrl-syscon = <&dsa_subctrl>; diff --git a/arch/arm64/boot/dts/hisilicon/hip07.dtsi b/arch/arm64/boot/dts/hisilicon/hip07.dtsi index 4773a533fce5..7832d9cdec21 100644 --- a/arch/arm64/boot/dts/hisilicon/hip07.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hip07.dtsi @@ -924,56 +924,56 @@ <0x0 0xfe020000 0x0 0x10000>; /* GICV */ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; - p0_its_peri_a: interrupt-controller@4c000000 { + p0_its_peri_a: msi-controller@4c000000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; reg = <0x0 0x4c000000 0x0 0x40000>; }; - p0_its_peri_b: interrupt-controller@6c000000 { + p0_its_peri_b: msi-controller@6c000000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; reg = <0x0 0x6c000000 0x0 0x40000>; }; - p0_its_dsa_a: interrupt-controller@c6000000 { + p0_its_dsa_a: msi-controller@c6000000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; reg = <0x0 0xc6000000 0x0 0x40000>; }; - p0_its_dsa_b: interrupt-controller@8,c6000000 { + p0_its_dsa_b: msi-controller@8c6000000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; reg = <0x8 0xc6000000 0x0 0x40000>; }; - p1_its_peri_a: interrupt-controller@400,4c000000 { + p1_its_peri_a: msi-controller@4004c000000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; reg = <0x400 0x4c000000 0x0 0x40000>; }; - p1_its_peri_b: interrupt-controller@400,6c000000 { + p1_its_peri_b: msi-controller@4006c000000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; reg = <0x400 0x6c000000 0x0 0x40000>; }; - p1_its_dsa_a: interrupt-controller@400,c6000000 { + p1_its_dsa_a: msi-controller@400c6000000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; reg = <0x400 0xc6000000 0x0 0x40000>; }; - p1_its_dsa_b: interrupt-controller@408,c6000000 { + p1_its_dsa_b: msi-controller@408c6000000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; @@ -1161,7 +1161,7 @@ * when iommu-map entry is used along with the PCIe node. * Refer:https://www.spinics.net/lists/arm-kernel/msg602812.html */ - smmu0: smmu_pcie { + smmu0: iommu@a0040000 { compatible = "arm,smmu-v3"; reg = <0x0 0xa0040000 0x0 0x20000>; #iommu-cells = <1>; @@ -1170,7 +1170,7 @@ hisilicon,broken-prefetch-cmd; status = "disabled"; }; - p0_smmu_alg_a: smmu_alg@d0040000 { + p0_smmu_alg_a: iommu@d0040000 { compatible = "arm,smmu-v3"; reg = <0x0 0xd0040000 0x0 0x20000>; interrupt-parent = <&p0_mbigen_smmu_alg_a>; @@ -1183,7 +1183,7 @@ hisilicon,broken-prefetch-cmd; /* smmu-cb-memtype = <0x0 0x1>;*/ }; - p0_smmu_alg_b: smmu_alg@8,d0040000 { + p0_smmu_alg_b: iommu@8d0040000 { compatible = "arm,smmu-v3"; reg = <0x8 0xd0040000 0x0 0x20000>; interrupt-parent = <&p0_mbigen_smmu_alg_b>; @@ -1196,7 +1196,7 @@ hisilicon,broken-prefetch-cmd; /* smmu-cb-memtype = <0x0 0x1>;*/ }; - p1_smmu_alg_a: smmu_alg@400,d0040000 { + p1_smmu_alg_a: iommu@400d0040000 { compatible = "arm,smmu-v3"; reg = <0x400 0xd0040000 0x0 0x20000>; interrupt-parent = <&p1_mbigen_smmu_alg_a>; @@ -1209,7 +1209,7 @@ hisilicon,broken-prefetch-cmd; /* smmu-cb-memtype = <0x0 0x1>;*/ }; - p1_smmu_alg_b: smmu_alg@408,d0040000 { + p1_smmu_alg_b: iommu@408d0040000 { compatible = "arm,smmu-v3"; reg = <0x408 0xd0040000 0x0 0x20000>; interrupt-parent = <&p1_mbigen_smmu_alg_b>; @@ -1253,7 +1253,7 @@ status = "disabled"; }; - usb_ohci: ohci@a7030000 { + usb_ohci: usb@a7030000 { compatible = "generic-ohci"; reg = <0x0 0xa7030000 0x0 0x10000>; interrupt-parent = <&mbigen_usb>; @@ -1262,7 +1262,7 @@ status = "disabled"; }; - usb_ehci: ehci@a7020000 { + usb_ehci: usb@a7020000 { compatible = "generic-ehci"; reg = <0x0 0xa7020000 0x0 0x10000>; interrupt-parent = <&mbigen_usb>; @@ -1321,8 +1321,8 @@ #size-cells = <0>; compatible = "hisilicon,hns-dsaf-v2"; mode = "6port-16rss"; - reg = <0x0 0xc5000000 0x0 0x890000 - 0x0 0xc7000000 0x0 0x600000>; + reg = <0x0 0xc5000000 0x0 0x890000>, + <0x0 0xc7000000 0x0 0x600000>; reg-names = "ppe-base", "dsaf-base"; interrupt-parent = <&mbigen_dsaf0>; subctrl-syscon = <&dsa_subctrl>; @@ -1720,24 +1720,24 @@ }; p0_sec_a: crypto@d2000000 { compatible = "hisilicon,hip07-sec"; - reg = <0x0 0xd0000000 0x0 0x10000 - 0x0 0xd2000000 0x0 0x10000 - 0x0 0xd2010000 0x0 0x10000 - 0x0 0xd2020000 0x0 0x10000 - 0x0 0xd2030000 0x0 0x10000 - 0x0 0xd2040000 0x0 0x10000 - 0x0 0xd2050000 0x0 0x10000 - 0x0 0xd2060000 0x0 0x10000 - 0x0 0xd2070000 0x0 0x10000 - 0x0 0xd2080000 0x0 0x10000 - 0x0 0xd2090000 0x0 0x10000 - 0x0 0xd20a0000 0x0 0x10000 - 0x0 0xd20b0000 0x0 0x10000 - 0x0 0xd20c0000 0x0 0x10000 - 0x0 0xd20d0000 0x0 0x10000 - 0x0 0xd20e0000 0x0 0x10000 - 0x0 0xd20f0000 0x0 0x10000 - 0x0 0xd2100000 0x0 0x10000>; + reg = <0x0 0xd0000000 0x0 0x10000>, + <0x0 0xd2000000 0x0 0x10000>, + <0x0 0xd2010000 0x0 0x10000>, + <0x0 0xd2020000 0x0 0x10000>, + <0x0 0xd2030000 0x0 0x10000>, + <0x0 0xd2040000 0x0 0x10000>, + <0x0 0xd2050000 0x0 0x10000>, + <0x0 0xd2060000 0x0 0x10000>, + <0x0 0xd2070000 0x0 0x10000>, + <0x0 0xd2080000 0x0 0x10000>, + <0x0 0xd2090000 0x0 0x10000>, + <0x0 0xd20a0000 0x0 0x10000>, + <0x0 0xd20b0000 0x0 0x10000>, + <0x0 0xd20c0000 0x0 0x10000>, + <0x0 0xd20d0000 0x0 0x10000>, + <0x0 0xd20e0000 0x0 0x10000>, + <0x0 0xd20f0000 0x0 0x10000>, + <0x0 0xd2100000 0x0 0x10000>; interrupt-parent = <&p0_mbigen_sec_a>; iommus = <&p0_smmu_alg_a 0x600>; dma-coherent; @@ -1761,24 +1761,24 @@ }; p0_sec_b: crypto@8,d2000000 { compatible = "hisilicon,hip07-sec"; - reg = <0x8 0xd0000000 0x0 0x10000 - 0x8 0xd2000000 0x0 0x10000 - 0x8 0xd2010000 0x0 0x10000 - 0x8 0xd2020000 0x0 0x10000 - 0x8 0xd2030000 0x0 0x10000 - 0x8 0xd2040000 0x0 0x10000 - 0x8 0xd2050000 0x0 0x10000 - 0x8 0xd2060000 0x0 0x10000 - 0x8 0xd2070000 0x0 0x10000 - 0x8 0xd2080000 0x0 0x10000 - 0x8 0xd2090000 0x0 0x10000 - 0x8 0xd20a0000 0x0 0x10000 - 0x8 0xd20b0000 0x0 0x10000 - 0x8 0xd20c0000 0x0 0x10000 - 0x8 0xd20d0000 0x0 0x10000 - 0x8 0xd20e0000 0x0 0x10000 - 0x8 0xd20f0000 0x0 0x10000 - 0x8 0xd2100000 0x0 0x10000>; + reg = <0x8 0xd0000000 0x0 0x10000>, + <0x8 0xd2000000 0x0 0x10000>, + <0x8 0xd2010000 0x0 0x10000>, + <0x8 0xd2020000 0x0 0x10000>, + <0x8 0xd2030000 0x0 0x10000>, + <0x8 0xd2040000 0x0 0x10000>, + <0x8 0xd2050000 0x0 0x10000>, + <0x8 0xd2060000 0x0 0x10000>, + <0x8 0xd2070000 0x0 0x10000>, + <0x8 0xd2080000 0x0 0x10000>, + <0x8 0xd2090000 0x0 0x10000>, + <0x8 0xd20a0000 0x0 0x10000>, + <0x8 0xd20b0000 0x0 0x10000>, + <0x8 0xd20c0000 0x0 0x10000>, + <0x8 0xd20d0000 0x0 0x10000>, + <0x8 0xd20e0000 0x0 0x10000>, + <0x8 0xd20f0000 0x0 0x10000>, + <0x8 0xd2100000 0x0 0x10000>; interrupt-parent = <&p0_mbigen_sec_b>; iommus = <&p0_smmu_alg_b 0x600>; dma-coherent; @@ -1802,24 +1802,24 @@ }; p1_sec_a: crypto@400,d2000000 { compatible = "hisilicon,hip07-sec"; - reg = <0x400 0xd0000000 0x0 0x10000 - 0x400 0xd2000000 0x0 0x10000 - 0x400 0xd2010000 0x0 0x10000 - 0x400 0xd2020000 0x0 0x10000 - 0x400 0xd2030000 0x0 0x10000 - 0x400 0xd2040000 0x0 0x10000 - 0x400 0xd2050000 0x0 0x10000 - 0x400 0xd2060000 0x0 0x10000 - 0x400 0xd2070000 0x0 0x10000 - 0x400 0xd2080000 0x0 0x10000 - 0x400 0xd2090000 0x0 0x10000 - 0x400 0xd20a0000 0x0 0x10000 - 0x400 0xd20b0000 0x0 0x10000 - 0x400 0xd20c0000 0x0 0x10000 - 0x400 0xd20d0000 0x0 0x10000 - 0x400 0xd20e0000 0x0 0x10000 - 0x400 0xd20f0000 0x0 0x10000 - 0x400 0xd2100000 0x0 0x10000>; + reg = <0x400 0xd0000000 0x0 0x10000>, + <0x400 0xd2000000 0x0 0x10000>, + <0x400 0xd2010000 0x0 0x10000>, + <0x400 0xd2020000 0x0 0x10000>, + <0x400 0xd2030000 0x0 0x10000>, + <0x400 0xd2040000 0x0 0x10000>, + <0x400 0xd2050000 0x0 0x10000>, + <0x400 0xd2060000 0x0 0x10000>, + <0x400 0xd2070000 0x0 0x10000>, + <0x400 0xd2080000 0x0 0x10000>, + <0x400 0xd2090000 0x0 0x10000>, + <0x400 0xd20a0000 0x0 0x10000>, + <0x400 0xd20b0000 0x0 0x10000>, + <0x400 0xd20c0000 0x0 0x10000>, + <0x400 0xd20d0000 0x0 0x10000>, + <0x400 0xd20e0000 0x0 0x10000>, + <0x400 0xd20f0000 0x0 0x10000>, + <0x400 0xd2100000 0x0 0x10000>; interrupt-parent = <&p1_mbigen_sec_a>; iommus = <&p1_smmu_alg_a 0x600>; dma-coherent; @@ -1843,24 +1843,24 @@ }; p1_sec_b: crypto@408,d2000000 { compatible = "hisilicon,hip07-sec"; - reg = <0x408 0xd0000000 0x0 0x10000 - 0x408 0xd2000000 0x0 0x10000 - 0x408 0xd2010000 0x0 0x10000 - 0x408 0xd2020000 0x0 0x10000 - 0x408 0xd2030000 0x0 0x10000 - 0x408 0xd2040000 0x0 0x10000 - 0x408 0xd2050000 0x0 0x10000 - 0x408 0xd2060000 0x0 0x10000 - 0x408 0xd2070000 0x0 0x10000 - 0x408 0xd2080000 0x0 0x10000 - 0x408 0xd2090000 0x0 0x10000 - 0x408 0xd20a0000 0x0 0x10000 - 0x408 0xd20b0000 0x0 0x10000 - 0x408 0xd20c0000 0x0 0x10000 - 0x408 0xd20d0000 0x0 0x10000 - 0x408 0xd20e0000 0x0 0x10000 - 0x408 0xd20f0000 0x0 0x10000 - 0x408 0xd2100000 0x0 0x10000>; + reg = <0x408 0xd0000000 0x0 0x10000>, + <0x408 0xd2000000 0x0 0x10000>, + <0x408 0xd2010000 0x0 0x10000>, + <0x408 0xd2020000 0x0 0x10000>, + <0x408 0xd2030000 0x0 0x10000>, + <0x408 0xd2040000 0x0 0x10000>, + <0x408 0xd2050000 0x0 0x10000>, + <0x408 0xd2060000 0x0 0x10000>, + <0x408 0xd2070000 0x0 0x10000>, + <0x408 0xd2080000 0x0 0x10000>, + <0x408 0xd2090000 0x0 0x10000>, + <0x408 0xd20a0000 0x0 0x10000>, + <0x408 0xd20b0000 0x0 0x10000>, + <0x408 0xd20c0000 0x0 0x10000>, + <0x408 0xd20d0000 0x0 0x10000>, + <0x408 0xd20e0000 0x0 0x10000>, + <0x408 0xd20f0000 0x0 0x10000>, + <0x408 0xd2100000 0x0 0x10000>; interrupt-parent = <&p1_mbigen_sec_b>; iommus = <&p1_smmu_alg_b 0x600>; dma-coherent; diff --git a/arch/arm64/boot/dts/marvell/Makefile b/arch/arm64/boot/dts/marvell/Makefile index 3e5f2e7a040c..34efe0fb6f37 100644 --- a/arch/arm64/boot/dts/marvell/Makefile +++ b/arch/arm64/boot/dts/marvell/Makefile @@ -3,6 +3,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-db.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin-emmc.dtb +dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin-ultra.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin-v7.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin-v7-emmc.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-turris-mox.dtb @@ -12,6 +13,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-clearfog-gt-8k.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-db.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-mcbin.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-mcbin-singleshot.dtb +dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-puzzle-m801.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-8080-db.dtb dtb-$(CONFIG_ARCH_MVEBU) += cn9130-db.dtb dtb-$(CONFIG_ARCH_MVEBU) += cn9131-db.dtb diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts index ec72a11ed80f..5c4d8f379704 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-emmc.dts @@ -21,24 +21,6 @@ "marvell,armada3720", "marvell,armada3710"; }; -/* U11 */ &sdhci0 { - non-removable; - bus-width = <8>; - mmc-ddr-1_8v; - mmc-hs400-1_8v; - marvell,xenon-emmc; - marvell,xenon-tun-count = <9>; - marvell,pad-type = "fixed-1-8v"; - - pinctrl-names = "default"; - pinctrl-0 = <&mmc_pins>; status = "okay"; - - #address-cells = <1>; - #size-cells = <0>; - mmccard: mmccard@0 { - compatible = "mmc-card"; - reg = <0>; - }; }; diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts new file mode 100644 index 000000000000..c5eb3604dd5b --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree file for ESPRESSObin-Ultra board. + * Copyright (C) 2019 Globalscale technologies, Inc. + * + * Jason Hung <jhung@globalscaletechnologies.com> + */ + +/dts-v1/; + +#include "armada-3720-espressobin.dtsi" + +/ { + model = "Globalscale Marvell ESPRESSOBin Ultra Board"; + compatible = "globalscale,espressobin-ultra", "marvell,armada3720", + "marvell,armada3710"; + + aliases { + /* ethernet1 is WAN port */ + ethernet1 = &switch0port5; + ethernet2 = &switch0port1; + ethernet3 = &switch0port2; + ethernet4 = &switch0port3; + ethernet5 = &switch0port4; + }; + + reg_usb3_vbus: usb3-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb3-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpionb 19 GPIO_ACTIVE_HIGH>; + }; + + usb3_phy: usb3-phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <®_usb3_vbus>; + }; + + gpio-leds { + pinctrl-names = "default"; + compatible = "gpio-leds"; + /* No assigned functions to the LEDs by default */ + led1 { + label = "ebin-ultra:blue:led1"; + gpios = <&gpionb 11 GPIO_ACTIVE_LOW>; + }; + led2 { + label = "ebin-ultra:green:led2"; + gpios = <&gpionb 12 GPIO_ACTIVE_LOW>; + }; + led3 { + label = "ebin-ultra:red:led3"; + gpios = <&gpionb 13 GPIO_ACTIVE_LOW>; + }; + led4 { + label = "ebin-ultra:yellow:led4"; + gpios = <&gpionb 14 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&sdhci0 { + status = "okay"; +}; + +&sdhci1 { + status = "disabled"; +}; + +&spi0 { + flash@0 { + spi-max-frequency = <108000000>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "firmware"; + reg = <0x0 0x3e0000>; + }; + partition@3e0000 { + label = "hw-info"; + reg = <0x3e0000 0x10000>; + read-only; + }; + partition@3f0000 { + label = "u-boot-env"; + reg = <0x3f0000 0x10000>; + }; + }; + }; +}; + +&i2c0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + + clock-frequency = <100000>; + + rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; +}; + +&usb3 { + usb-phy = <&usb3_phy>; + status = "disabled"; +}; + +&mdio { + extphy: ethernet-phy@1 { + reg = <1>; + }; +}; + +&switch0 { + reg = <3>; + + ports { + switch0port1: port@1 { + reg = <1>; + label = "lan0"; + phy-handle = <&switch0phy0>; + }; + + switch0port2: port@2 { + reg = <2>; + label = "lan1"; + phy-handle = <&switch0phy1>; + }; + + switch0port3: port@3 { + reg = <3>; + label = "lan2"; + phy-handle = <&switch0phy2>; + }; + + switch0port4: port@4 { + reg = <4>; + label = "lan3"; + phy-handle = <&switch0phy3>; + }; + + switch0port5: port@5 { + reg = <5>; + label = "wan"; + phy-handle = <&extphy>; + phy-mode = "sgmii"; + }; + }; + + mdio { + switch0phy3: switch0phy3@14 { + reg = <0x14>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts index 215d2f702623..75401eab4d42 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7-emmc.dts @@ -8,7 +8,7 @@ * */ /* - * Schematic available at http://wiki.espressobin.net/tiki-download_file.php?fileId=200 + * Schematic available at http://espressobin.net/wp-content/uploads/2020/05/ESPRESSObin_V7-0_Schematic.pdf */ /dts-v1/; @@ -28,40 +28,18 @@ }; }; -&switch0 { - ports { - switch0port1: port@1 { - reg = <1>; - label = "lan1"; - phy-handle = <&switch0phy0>; - }; +&switch0port1 { + label = "lan1"; +}; - switch0port3: port@3 { - reg = <3>; - label = "wan"; - phy-handle = <&switch0phy2>; - }; - }; +&switch0port3 { + label = "wan"; }; -/* U11 */ &sdhci0 { - non-removable; - bus-width = <8>; - mmc-ddr-1_8v; - mmc-hs400-1_8v; - marvell,xenon-emmc; - marvell,xenon-tun-count = <9>; - marvell,pad-type = "fixed-1-8v"; - - pinctrl-names = "default"; - pinctrl-0 = <&mmc_pins>; status = "okay"; +}; - #address-cells = <1>; - #size-cells = <0>; - mmccard: mmccard@0 { - compatible = "mmc-card"; - reg = <0>; - }; +&led2 { + status = "okay"; }; diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts index b6f4af8ebafb..48a7f50fb427 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-v7.dts @@ -8,7 +8,7 @@ * */ /* - * Schematic available at http://wiki.espressobin.net/tiki-download_file.php?fileId=200 + * Schematic available at http://espressobin.net/wp-content/uploads/2020/05/ESPRESSObin_V7-0_Schematic.pdf */ /dts-v1/; @@ -27,18 +27,14 @@ }; }; -&switch0 { - ports { - switch0port1: port@1 { - reg = <1>; - label = "lan1"; - phy-handle = <&switch0phy0>; - }; +&switch0port1 { + label = "lan1"; +}; - switch0port3: port@3 { - reg = <3>; - label = "wan"; - phy-handle = <&switch0phy2>; - }; - }; +&switch0port3 { + label = "wan"; +}; + +&led2 { + status = "okay"; }; diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi index 0775c16e0ec8..daffe136c523 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi @@ -17,8 +17,6 @@ ethernet1 = &switch0port1; ethernet2 = &switch0port2; ethernet3 = &switch0port3; - serial0 = &uart0; - serial1 = &uart1; }; chosen { @@ -43,6 +41,19 @@ 3300000 0x0>; enable-active-high; }; + + led2: gpio-led2 { + /* led2 is working only on v7 board */ + status = "disabled"; + + compatible = "gpio-leds"; + + led2 { + label = "led2"; + gpios = <&gpionb 2 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + }; }; /* J9 */ @@ -60,6 +71,30 @@ phy-names = "sata-phy"; }; +/* U11 */ +&sdhci0 { + /* Main DTS file for Espressobin is without eMMC */ + status = "disabled"; + + non-removable; + bus-width = <8>; + mmc-ddr-1_8v; + mmc-hs400-1_8v; + marvell,xenon-emmc; + marvell,xenon-tun-count = <9>; + marvell,pad-type = "fixed-1-8v"; + + pinctrl-names = "default"; + pinctrl-0 = <&mmc_pins>; + + #address-cells = <1>; + #size-cells = <0>; + mmccard: mmccard@0 { + compatible = "mmc-card"; + reg = <0>; + }; +}; + /* J1 */ &sdhci1 { wp-inverted; diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts index f3a678e0fd99..f5ec3b644769 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts @@ -102,6 +102,7 @@ mod-def0-gpio = <&moxtet_sfp 2 GPIO_ACTIVE_LOW>; tx-disable-gpio = <&moxtet_sfp 4 GPIO_ACTIVE_HIGH>; rate-select0-gpio = <&moxtet_sfp 5 GPIO_ACTIVE_HIGH>; + maximum-power-milliwatt = <3000>; /* enabled by U-Boot if SFP module is present */ status = "disabled"; @@ -146,7 +147,7 @@ pinctrl-names = "default"; pinctrl-0 = <&rgmii_pins>; phy-mode = "rgmii-id"; - phy = <&phy1>; + phy-handle = <&phy1>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/marvell/armada-7040.dtsi b/arch/arm64/boot/dts/marvell/armada-7040.dtsi index 7a3198cd7a07..2f440711d21d 100644 --- a/arch/arm64/boot/dts/marvell/armada-7040.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-7040.dtsi @@ -15,10 +15,6 @@ "marvell,armada-ap806"; }; -&smmu { - status = "okay"; -}; - &cp0_pcie0 { iommu-map = <0x0 &smmu 0x480 0x20>, diff --git a/arch/arm64/boot/dts/marvell/armada-8040-mcbin-singleshot.dts b/arch/arm64/boot/dts/marvell/armada-8040-mcbin-singleshot.dts index 2e6832d02a59..411d20064271 100644 --- a/arch/arm64/boot/dts/marvell/armada-8040-mcbin-singleshot.dts +++ b/arch/arm64/boot/dts/marvell/armada-8040-mcbin-singleshot.dts @@ -5,6 +5,8 @@ * Device Tree file for MACCHIATOBin Armada 8040 community board platform */ +#include <dt-bindings/leds/common.h> + #include "armada-8040-mcbin.dtsi" / { @@ -12,6 +14,19 @@ compatible = "marvell,armada8040-mcbin-singleshot", "marvell,armada8040-mcbin", "marvell,armada8040", "marvell,armada-ap806-quad", "marvell,armada-ap806"; + + leds { + compatible = "gpio-leds"; + pinctrl-0 = <&cp0_led18_pins>; + pinctrl-names = "default"; + + led18 { + gpios = <&cp0_gpio2 1 GPIO_ACTIVE_LOW>; + function = LED_FUNCTION_HEARTBEAT; + color = <LED_COLOR_ID_GREEN>; + linux,default-trigger = "heartbeat"; + }; + }; }; &cp0_eth0 { @@ -27,3 +42,10 @@ managed = "in-band-status"; sfp = <&sfp_eth1>; }; + +&cp0_pinctrl { + cp0_led18_pins: led18-pins { + marvell,pins = "mpp33"; + marvell,function = "gpio"; + }; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-8040-puzzle-m801.dts b/arch/arm64/boot/dts/marvell/armada-8040-puzzle-m801.dts new file mode 100644 index 000000000000..dac85fa748de --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-8040-puzzle-m801.dts @@ -0,0 +1,523 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * Copyright (C) 2020 Sartura Ltd. + * + * Device Tree file for IEI Puzzle-M801 + */ + +#include "armada-8040.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/leds/common.h> + +/ { + model = "IEI-Puzzle-M801"; + compatible = "marvell,armada8040", "marvell,armada-ap806-quad", "marvell,armada-ap806"; + + aliases { + ethernet0 = &cp0_eth0; + ethernet1 = &cp1_eth0; + ethernet2 = &cp0_eth1; + ethernet3 = &cp0_eth2; + ethernet4 = &cp1_eth1; + ethernet5 = &cp1_eth2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + /* Regulator labels correspond with schematics */ + v_3_3: regulator-3-3v { + compatible = "regulator-fixed"; + regulator-name = "v_3_3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + status = "okay"; + }; + + v_5v0_usb3_hst_vbus: regulator-usb3-vbus0 { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&cp0_gpio2 15 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&cp0_xhci_vbus_pins>; + regulator-name = "v_5v0_usb3_hst_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + status = "okay"; + }; + + v_vddo_h: regulator-1-8v { + compatible = "regulator-fixed"; + regulator-name = "v_vddo_h"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + status = "okay"; + }; + + sfp_cp0_eth0: sfp-cp0-eth0 { + compatible = "sff,sfp"; + i2c-bus = <&sfpplus0_i2c>; + los-gpio = <&sfpplus_gpio 11 GPIO_ACTIVE_HIGH>; + mod-def0-gpio = <&sfpplus_gpio 10 GPIO_ACTIVE_LOW>; + tx-disable-gpio = <&sfpplus_gpio 9 GPIO_ACTIVE_HIGH>; + tx-fault-gpio = <&sfpplus_gpio 8 GPIO_ACTIVE_HIGH>; + maximum-power-milliwatt = <3000>; + }; + + sfp_cp1_eth0: sfp-cp1-eth0 { + compatible = "sff,sfp"; + i2c-bus = <&sfpplus1_i2c>; + los-gpio = <&sfpplus_gpio 3 GPIO_ACTIVE_HIGH>; + mod-def0-gpio = <&sfpplus_gpio 2 GPIO_ACTIVE_LOW>; + tx-disable-gpio = <&sfpplus_gpio 1 GPIO_ACTIVE_HIGH>; + tx-fault-gpio = <&sfpplus_gpio 0 GPIO_ACTIVE_HIGH>; + maximum-power-milliwatt = <3000>; + }; + + leds { + compatible = "gpio-leds"; + status = "okay"; + pinctrl-0 = <&cp0_sfpplus_led_pins &cp1_sfpplus_led_pins>; + pinctrl-names = "default"; + + led-0 { + /* SFP+ port 2: Activity */ + function = LED_FUNCTION_LAN; + function-enumerator = <0>; + gpios = <&cp1_gpio1 6 GPIO_ACTIVE_LOW>; + }; + + led-1 { + /* SFP+ port 1: Activity */ + function = LED_FUNCTION_LAN; + function-enumerator = <1>; + gpios = <&cp1_gpio1 14 GPIO_ACTIVE_LOW>; + }; + + led-2 { + /* SFP+ port 2: 10 Gbps indicator */ + function = LED_FUNCTION_LAN; + function-enumerator = <2>; + gpios = <&cp1_gpio1 7 GPIO_ACTIVE_LOW>; + }; + + led-3 { + /* SFP+ port 2: 1 Gbps indicator */ + function = LED_FUNCTION_LAN; + function-enumerator = <3>; + gpios = <&cp1_gpio1 8 GPIO_ACTIVE_LOW>; + }; + + led-4 { + /* SFP+ port 1: 10 Gbps indicator */ + function = LED_FUNCTION_LAN; + function-enumerator = <4>; + gpios = <&cp1_gpio1 10 GPIO_ACTIVE_LOW>; + }; + + led-5 { + /* SFP+ port 1: 1 Gbps indicator */ + function = LED_FUNCTION_LAN; + function-enumerator = <5>; + gpios = <&cp1_gpio1 31 GPIO_ACTIVE_LOW>; + }; + + led-6 { + function = LED_FUNCTION_DISK; + linux,default-trigger = "disk-activity"; + gpios = <&cp0_gpio2 22 GPIO_ACTIVE_HIGH>; + }; + + }; +}; + +&ap_sdhci0 { + bus-width = <8>; + /* + * Not stable in HS modes - phy needs "more calibration", so add + * the "slow-mode" and disable SDR104, SDR50 and DDR50 modes. + */ + marvell,xenon-phy-slow-mode; + no-1-8-v; + no-sd; + no-sdio; + non-removable; + status = "okay"; + vqmmc-supply = <&v_vddo_h>; +}; + +&ap_thermal_cpu1 { + trips { + cpu_active: cpu-active { + temperature = <44000>; + hysteresis = <2000>; + type = "active"; + }; + }; + cooling-maps { + fan-map { + trip = <&cpu_active>; + cooling-device = <&chassis_fan_group0 64 THERMAL_NO_LIMIT>, + <&chassis_fan_group1 64 THERMAL_NO_LIMIT>; + }; + }; +}; + +&i2c0 { + clock-frequency = <100000>; + status = "okay"; + + rtc@32 { + compatible = "epson,rx8010"; + reg = <0x32>; + }; +}; + +&spi0 { + status = "okay"; + spi-flash@0 { + #address-cells = <0x1>; + #size-cells = <0x1>; + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-max-frequency = <20000000>; + partition@u-boot { + label = "u-boot"; + reg = <0x00000000 0x001f0000>; + }; + partition@u-boot-env { + label = "u-boot-env"; + reg = <0x001f0000 0x00010000>; + }; + partition@ubi1 { + label = "ubi1"; + reg = <0x00200000 0x03f00000>; + }; + partition@ubi2 { + label = "ubi2"; + reg = <0x04100000 0x03f00000>; + }; + }; +}; + +&uart0 { + status = "okay"; + pinctrl-0 = <&uart0_pins>; + pinctrl-names = "default"; +}; + +&uart1 { + status = "okay"; + /* IEI WT61P803 PUZZLE MCU Controller */ + mcu { + compatible = "iei,wt61p803-puzzle"; + current-speed = <115200>; + enable-beep; + + leds { + compatible = "iei,wt61p803-puzzle-leds"; + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + function = LED_FUNCTION_POWER; + color = <LED_COLOR_ID_BLUE>; + }; + }; + + hwmon { + compatible = "iei,wt61p803-puzzle-hwmon"; + #address-cells = <1>; + #size-cells = <0>; + + chassis_fan_group0:fan-group@0 { + #cooling-cells = <2>; + reg = <0x00>; + cooling-levels = <64 102 170 230 250>; + }; + + chassis_fan_group1:fan-group@1 { + #cooling-cells = <2>; + reg = <0x01>; + cooling-levels = <64 102 170 230 250>; + }; + }; + }; +}; + +&cp0_rtc { + status = "disabled"; +}; + +&cp0_i2c0 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&cp0_i2c0_pins>; + status = "okay"; + + sfpplus_gpio: gpio@21 { + compatible = "nxp,pca9555"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + }; + + eeprom@54 { + compatible = "atmel,24c04"; + reg = <0x54>; + }; +}; + +&cp0_i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&cp0_i2c1_pins>; + status = "okay"; + + i2c-switch@70 { + compatible = "nxp,pca9544"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x70>; + + sfpplus0_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + sfpplus1_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + }; +}; + +&cp0_uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&cp0_uart1_pins>; + status = "okay"; +}; + +&cp0_mdio { + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + ge_phy2: ethernet-phy@0 { + reg = <0>; + }; + + ge_phy3: ethernet-phy@1 { + reg = <1>; + }; +}; + +&cp0_pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&cp0_pcie_pins>; + num-lanes = <1>; + num-viewport = <8>; + reset-gpios = <&cp0_gpio2 20 GPIO_ACTIVE_LOW>; + ranges = <0x82000000 0x0 0xc0000000 0x0 0xc0000000 0x0 0x20000000>; + phys = <&cp0_comphy0 0>; + phy-names = "cp0-pcie0-x1-phy"; + status = "okay"; +}; + +&cp0_pinctrl { + cp0_ge_mdio_pins: ge-mdio-pins { + marvell,pins = "mpp32", "mpp34"; + marvell,function = "ge"; + }; + cp0_i2c1_pins: i2c1-pins { + marvell,pins = "mpp35", "mpp36"; + marvell,function = "i2c1"; + }; + cp0_i2c0_pins: i2c0-pins { + marvell,pins = "mpp37", "mpp38"; + marvell,function = "i2c0"; + }; + cp0_uart1_pins: uart1-pins { + marvell,pins = "mpp40", "mpp41"; + marvell,function = "uart1"; + }; + cp0_xhci_vbus_pins: xhci0-vbus-pins { + marvell,pins = "mpp47"; + marvell,function = "gpio"; + }; + cp0_pcie_pins: pcie-pins { + marvell,pins = "mpp52"; + marvell,function = "gpio"; + }; + cp0_sdhci_pins: sdhci-pins { + marvell,pins = "mpp55", "mpp56", "mpp57", "mpp58", "mpp59", + "mpp60", "mpp61"; + marvell,function = "sdio"; + }; + cp0_sfpplus_led_pins: sfpplus-led-pins { + marvell,pins = "mpp54"; + marvell,function = "gpio"; + }; +}; + +&cp0_ethernet { + status = "okay"; +}; + +&cp0_eth0 { + status = "okay"; + phy-mode = "10gbase-r"; + phys = <&cp0_comphy4 0>; + local-mac-address = [ae 00 00 00 ff 00]; + sfp = <&sfp_cp0_eth0>; + managed = "in-band-status"; +}; + +&cp0_eth1 { + status = "okay"; + phy = <&ge_phy2>; + phy-mode = "sgmii"; + local-mac-address = [ae 00 00 00 ff 01]; + phys = <&cp0_comphy3 1>; +}; + +&cp0_eth2 { + status = "okay"; + phy-mode = "sgmii"; + phys = <&cp0_comphy1 2>; + local-mac-address = [ae 00 00 00 ff 02]; + phy = <&ge_phy3>; +}; + +&cp0_sata0 { + status = "okay"; + + sata-port@0 { + phys = <&cp0_comphy2 0>; + phy-names = "cp0-sata0-0-phy"; + }; + + sata-port@1 { + phys = <&cp0_comphy5 1>; + phy-names = "cp0-sata0-1-phy"; + }; +}; + +&cp0_sdhci0 { + broken-cd; + bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&cp0_sdhci_pins>; + status = "okay"; + vqmmc-supply = <&v_3_3>; +}; + +&cp0_usb3_0 { + status = "okay"; +}; + +&cp0_usb3_1 { + status = "okay"; +}; + +&cp1_i2c0 { + clock-frequency = <100000>; + status = "disabled"; +}; + +&cp1_i2c1 { + clock-frequency = <100000>; + status = "disabled"; +}; + +&cp1_rtc { + status = "disabled"; +}; + +&cp1_ethernet { + status = "okay"; +}; + +&cp1_eth0 { + status = "okay"; + phy-mode = "10gbase-r"; + phys = <&cp1_comphy4 0>; + local-mac-address = [ae 00 00 00 ff 03]; + sfp = <&sfp_cp1_eth0>; + managed = "in-band-status"; +}; + +&cp1_eth1 { + status = "okay"; + phy = <&ge_phy4>; + phy-mode = "sgmii"; + local-mac-address = [ae 00 00 00 ff 04]; + phys = <&cp1_comphy3 1>; +}; + +&cp1_eth2 { + status = "okay"; + phy-mode = "sgmii"; + local-mac-address = [ae 00 00 00 ff 05]; + phys = <&cp1_comphy5 2>; + phy = <&ge_phy5>; +}; + +&cp1_pinctrl { + cp1_sfpplus_led_pins: sfpplus-led-pins { + marvell,pins = "mpp6", "mpp7", "mpp8", "mpp10", "mpp14", "mpp31"; + marvell,function = "gpio"; + }; +}; + +&cp1_uart0 { + status = "disabled"; +}; + +&cp1_comphy2 { + cp1_usbh0_con: connector { + compatible = "usb-a-connector"; + phy-supply = <&v_5v0_usb3_hst_vbus>; + }; +}; + +&cp1_usb3_0 { + phys = <&cp1_comphy2 0>; + phy-names = "cp1-usb3h0-comphy"; + status = "okay"; +}; + +&cp1_mdio { + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + ge_phy4: ethernet-phy@1 { + reg = <1>; + }; + ge_phy5: ethernet-phy@0 { + reg = <0>; + }; +}; + +&cp1_pcie0 { + num-lanes = <2>; + phys = <&cp1_comphy0 0>, <&cp1_comphy1 0>; + phy-names = "cp1-pcie0-x2-lane0-phy", "cp1-pcie0-x2-lane1-phy"; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-8040.dtsi b/arch/arm64/boot/dts/marvell/armada-8040.dtsi index 79e8ce59baa8..22c2d6ebf381 100644 --- a/arch/arm64/boot/dts/marvell/armada-8040.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-8040.dtsi @@ -15,10 +15,6 @@ "marvell,armada-ap806"; }; -&smmu { - status = "okay"; -}; - &cp0_pcie0 { iommu-map = <0x0 &smmu 0x480 0x20>, diff --git a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi index 9dcf16beabf5..994a2fce449a 100644 --- a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi @@ -275,7 +275,7 @@ }; }; - CP11X_LABEL(usb3_0): usb3@500000 { + CP11X_LABEL(usb3_0): usb@500000 { compatible = "marvell,armada-8k-xhci", "generic-xhci"; reg = <0x500000 0x4000>; @@ -287,7 +287,7 @@ status = "disabled"; }; - CP11X_LABEL(usb3_1): usb3@510000 { + CP11X_LABEL(usb3_1): usb@510000 { compatible = "marvell,armada-8k-xhci", "generic-xhci"; reg = <0x510000 0x4000>; @@ -300,11 +300,9 @@ }; CP11X_LABEL(sata0): sata@540000 { - compatible = "marvell,armada-8k-ahci", - "generic-ahci"; + compatible = "marvell,armada-8k-ahci"; reg = <0x540000 0x30000>; dma-coherent; - interrupts = <107 IRQ_TYPE_LEVEL_HIGH>; clocks = <&CP11X_LABEL(clk) 1 15>, <&CP11X_LABEL(clk) 1 16>; #address-cells = <1>; @@ -312,10 +310,12 @@ status = "disabled"; sata-port@0 { + interrupts = <109 IRQ_TYPE_LEVEL_HIGH>; reg = <0>; }; sata-port@1 { + interrupts = <107 IRQ_TYPE_LEVEL_HIGH>; reg = <1>; }; }; diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile index 3ee682c266cc..18f7b46c4095 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile @@ -1,15 +1,18 @@ # SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_MEDIATEK) += mt2712-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt6779-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana-rev7.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb diff --git a/arch/arm64/boot/dts/mediatek/mt6779-evb.dts b/arch/arm64/boot/dts/mediatek/mt6779-evb.dts new file mode 100644 index 000000000000..164f5cbb3821 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt6779-evb.dts @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Mars.C <mars.cheng@mediatek.com> + * + */ + +/dts-v1/; +#include "mt6779.dtsi" + +/ { + model = "MediaTek MT6779 EVB"; + compatible = "mediatek,mt6779-evb", "mediatek,mt6779"; + + aliases { + serial0 = &uart0; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 0 0x1e800000>; + }; + + chosen { + stdout-path = "serial0:921600n8"; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt6779.dtsi b/arch/arm64/boot/dts/mediatek/mt6779.dtsi new file mode 100644 index 000000000000..370f309d32de --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt6779.dtsi @@ -0,0 +1,271 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Mars.C <mars.cheng@mediatek.com> + * + */ + +#include <dt-bindings/clock/mt6779-clk.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/pinctrl/mt6779-pinfunc.h> + +/ { + compatible = "mediatek,mt6779"; + interrupt-parent = <&sysirq>; + #address-cells = <2>; + #size-cells = <2>; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + enable-method = "psci"; + reg = <0x000>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + enable-method = "psci"; + reg = <0x100>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + enable-method = "psci"; + reg = <0x200>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + enable-method = "psci"; + reg = <0x300>; + }; + + cpu4: cpu@4 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + enable-method = "psci"; + reg = <0x400>; + }; + + cpu5: cpu@5 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + enable-method = "psci"; + reg = <0x500>; + }; + + cpu6: cpu@6 { + device_type = "cpu"; + compatible = "arm,cortex-a75"; + enable-method = "psci"; + reg = <0x600>; + }; + + cpu7: cpu@7 { + device_type = "cpu"; + compatible = "arm,cortex-a75"; + enable-method = "psci"; + reg = <0x700>; + }; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupt-parent = <&gic>; + interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW 0>; + }; + + clk26m: oscillator@0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + clock-output-names = "clk26m"; + }; + + clk32k: oscillator@1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "clk32k"; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + 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>; + }; + + soc { + #address-cells = <2>; + #size-cells = <2>; + compatible = "simple-bus"; + ranges; + + gic: interrupt-controller@0c000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <4>; + interrupt-parent = <&gic>; + interrupt-controller; + reg = <0 0x0c000000 0 0x40000>, /* GICD */ + <0 0x0c040000 0 0x200000>; /* GICR */ + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>; + + ppi-partitions { + ppi_cluster0: interrupt-partition-0 { + affinity = <&cpu0 &cpu1 \ + &cpu2 &cpu3 &cpu4 &cpu5>; + }; + ppi_cluster1: interrupt-partition-1 { + affinity = <&cpu6 &cpu7>; + }; + }; + + }; + + sysirq: intpol-controller@0c53a650 { + compatible = "mediatek,mt6779-sysirq", + "mediatek,mt6577-sysirq"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + reg = <0 0x0c53a650 0 0x50>; + }; + + topckgen: clock-controller@10000000 { + compatible = "mediatek,mt6779-topckgen", "syscon"; + reg = <0 0x10000000 0 0x1000>; + #clock-cells = <1>; + }; + + infracfg_ao: clock-controller@10001000 { + compatible = "mediatek,mt6779-infracfg_ao", "syscon"; + reg = <0 0x10001000 0 0x1000>; + #clock-cells = <1>; + }; + + pio: pinctrl@10005000 { + compatible = "mediatek,mt6779-pinctrl", "syscon"; + reg = <0 0x10005000 0 0x1000>, + <0 0x11c20000 0 0x1000>, + <0 0x11d10000 0 0x1000>, + <0 0x11e20000 0 0x1000>, + <0 0x11e70000 0 0x1000>, + <0 0x11ea0000 0 0x1000>, + <0 0x11f20000 0 0x1000>, + <0 0x11f30000 0 0x1000>, + <0 0x1000b000 0 0x1000>; + reg-names = "gpio", "iocfg_rm", + "iocfg_br", "iocfg_lm", + "iocfg_lb", "iocfg_rt", + "iocfg_lt", "iocfg_tl", + "eint"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pio 0 0 210>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>; + }; + + apmixed: clock-controller@1000c000 { + compatible = "mediatek,mt6779-apmixed", "syscon"; + reg = <0 0x1000c000 0 0xe00>; + #clock-cells = <1>; + }; + + uart0: serial@11002000 { + compatible = "mediatek,mt6779-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11002000 0 0x400>; + interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>; + clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_UART0>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart1: serial@11003000 { + compatible = "mediatek,mt6779-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11003000 0 0x400>; + interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_LOW>; + clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_UART1>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart2: serial@11004000 { + compatible = "mediatek,mt6779-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11004000 0 0x400>; + interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_LOW>; + clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_UART2>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + audio: clock-controller@11210000 { + compatible = "mediatek,mt6779-audio", "syscon"; + reg = <0 0x11210000 0 0x1000>; + #clock-cells = <1>; + }; + + mfgcfg: clock-controller@13fbf000 { + compatible = "mediatek,mt6779-mfgcfg", "syscon"; + reg = <0 0x13fbf000 0 0x1000>; + #clock-cells = <1>; + }; + + mmsys: syscon@14000000 { + compatible = "mediatek,mt6779-mmsys", "syscon"; + reg = <0 0x14000000 0 0x1000>; + #clock-cells = <1>; + }; + + imgsys: clock-controller@15020000 { + compatible = "mediatek,mt6779-imgsys", "syscon"; + reg = <0 0x15020000 0 0x1000>; + #clock-cells = <1>; + }; + + vdecsys: clock-controller@16000000 { + compatible = "mediatek,mt6779-vdecsys", "syscon"; + reg = <0 0x16000000 0 0x1000>; + #clock-cells = <1>; + }; + + vencsys: clock-controller@17000000 { + compatible = "mediatek,mt6779-vencsys", "syscon"; + reg = <0 0x17000000 0 0x1000>; + #clock-cells = <1>; + }; + + camsys: clock-controller@1a000000 { + compatible = "mediatek,mt6779-camsys", "syscon"; + reg = <0 0x1a000000 0 0x10000>; + #clock-cells = <1>; + }; + + ipesys: clock-controller@1b000000 { + compatible = "mediatek,mt6779-ipesys", "syscon"; + reg = <0 0x1b000000 0 0x1000>; + #clock-cells = <1>; + }; + + }; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts index 9a11e5c60c26..2f77dc40b9b8 100644 --- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts @@ -412,10 +412,15 @@ }; }; - pwm7_pins: pwm1-2-pins { + pwm_pins: pwm-pins { mux { function = "pwm"; - groups = "pwm_ch7_2"; + groups = "pwm_ch1_0", /* mt7622_pwm_ch1_0_pins[] = { 51, }; */ + "pwm_ch2_0", /* mt7622_pwm_ch2_0_pins[] = { 52, }; */ + "pwm_ch3_2", /* mt7622_pwm_ch3_2_pins[] = { 97, }; */ + "pwm_ch4_1", /* mt7622_pwm_ch4_1_pins[] = { 67, }; */ + "pwm_ch5_0", /* mt7622_pwm_ch5_0_pins[] = { 68, }; */ + "pwm_ch6_0"; /* mt7622_pwm_ch6_0_pins[] = { 69, }; */ }; }; @@ -535,7 +540,7 @@ &pwm { pinctrl-names = "default"; - pinctrl-0 = <&pwm7_pins>; + pinctrl-0 = <&pwm_pins>; status = "okay"; }; @@ -563,7 +568,6 @@ &spi1 { pinctrl-names = "default"; pinctrl-0 = <&spic1_pins>; - status = "okay"; }; &ssusb { @@ -585,7 +589,6 @@ &uart2 { pinctrl-names = "default"; pinctrl-0 = <&uart2_pins>; - status = "okay"; }; &watchdog { diff --git a/arch/arm64/boot/dts/mediatek/mt8167-pinfunc.h b/arch/arm64/boot/dts/mediatek/mt8167-pinfunc.h new file mode 100644 index 000000000000..061c3255a973 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8167-pinfunc.h @@ -0,0 +1,744 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 MediaTek Inc. + */ +#ifndef __DTS_MT8167_PINFUNC_H +#define __DTS_MT8167_PINFUNC_H + +#include <dt-bindings/pinctrl/mt65xx.h> + +#define MT8167_PIN_0_EINT0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) +#define MT8167_PIN_0_EINT0__FUNC_PWM_B (MTK_PIN_NO(0) | 1) +#define MT8167_PIN_0_EINT0__FUNC_DPI_CK (MTK_PIN_NO(0) | 2) +#define MT8167_PIN_0_EINT0__FUNC_I2S2_BCK (MTK_PIN_NO(0) | 3) +#define MT8167_PIN_0_EINT0__FUNC_EXT_TXD0 (MTK_PIN_NO(0) | 4) +#define MT8167_PIN_0_EINT0__FUNC_SQICS (MTK_PIN_NO(0) | 6) +#define MT8167_PIN_0_EINT0__FUNC_DBG_MON_A_6 (MTK_PIN_NO(0) | 7) + +#define MT8167_PIN_1_EINT1__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) +#define MT8167_PIN_1_EINT1__FUNC_PWM_C (MTK_PIN_NO(1) | 1) +#define MT8167_PIN_1_EINT1__FUNC_DPI_D12 (MTK_PIN_NO(1) | 2) +#define MT8167_PIN_1_EINT1__FUNC_I2S2_DI (MTK_PIN_NO(1) | 3) +#define MT8167_PIN_1_EINT1__FUNC_EXT_TXD1 (MTK_PIN_NO(1) | 4) +#define MT8167_PIN_1_EINT1__FUNC_CONN_MCU_TDO (MTK_PIN_NO(1) | 5) +#define MT8167_PIN_1_EINT1__FUNC_SQISO (MTK_PIN_NO(1) | 6) +#define MT8167_PIN_1_EINT1__FUNC_DBG_MON_A_7 (MTK_PIN_NO(1) | 7) + +#define MT8167_PIN_2_EINT2__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) +#define MT8167_PIN_2_EINT2__FUNC_CLKM0 (MTK_PIN_NO(2) | 1) +#define MT8167_PIN_2_EINT2__FUNC_DPI_D13 (MTK_PIN_NO(2) | 2) +#define MT8167_PIN_2_EINT2__FUNC_I2S2_LRCK (MTK_PIN_NO(2) | 3) +#define MT8167_PIN_2_EINT2__FUNC_EXT_TXD2 (MTK_PIN_NO(2) | 4) +#define MT8167_PIN_2_EINT2__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(2) | 5) +#define MT8167_PIN_2_EINT2__FUNC_SQISI (MTK_PIN_NO(2) | 6) +#define MT8167_PIN_2_EINT2__FUNC_DBG_MON_A_8 (MTK_PIN_NO(2) | 7) + +#define MT8167_PIN_3_EINT3__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) +#define MT8167_PIN_3_EINT3__FUNC_CLKM1 (MTK_PIN_NO(3) | 1) +#define MT8167_PIN_3_EINT3__FUNC_DPI_D14 (MTK_PIN_NO(3) | 2) +#define MT8167_PIN_3_EINT3__FUNC_SPI_MI (MTK_PIN_NO(3) | 3) +#define MT8167_PIN_3_EINT3__FUNC_EXT_TXD3 (MTK_PIN_NO(3) | 4) +#define MT8167_PIN_3_EINT3__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(3) | 5) +#define MT8167_PIN_3_EINT3__FUNC_SQIWP (MTK_PIN_NO(3) | 6) +#define MT8167_PIN_3_EINT3__FUNC_DBG_MON_A_9 (MTK_PIN_NO(3) | 7) + +#define MT8167_PIN_4_EINT4__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) +#define MT8167_PIN_4_EINT4__FUNC_CLKM2 (MTK_PIN_NO(4) | 1) +#define MT8167_PIN_4_EINT4__FUNC_DPI_D15 (MTK_PIN_NO(4) | 2) +#define MT8167_PIN_4_EINT4__FUNC_SPI_MO (MTK_PIN_NO(4) | 3) +#define MT8167_PIN_4_EINT4__FUNC_EXT_TXC (MTK_PIN_NO(4) | 4) +#define MT8167_PIN_4_EINT4__FUNC_CONN_MCU_TCK (MTK_PIN_NO(4) | 5) +#define MT8167_PIN_4_EINT4__FUNC_CONN_MCU_AICE_JCKC (MTK_PIN_NO(4) | 6) +#define MT8167_PIN_4_EINT4__FUNC_DBG_MON_A_10 (MTK_PIN_NO(4) | 7) + +#define MT8167_PIN_5_EINT5__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) +#define MT8167_PIN_5_EINT5__FUNC_UCTS2 (MTK_PIN_NO(5) | 1) +#define MT8167_PIN_5_EINT5__FUNC_DPI_D16 (MTK_PIN_NO(5) | 2) +#define MT8167_PIN_5_EINT5__FUNC_SPI_CSB (MTK_PIN_NO(5) | 3) +#define MT8167_PIN_5_EINT5__FUNC_EXT_RXER (MTK_PIN_NO(5) | 4) +#define MT8167_PIN_5_EINT5__FUNC_CONN_MCU_TDI (MTK_PIN_NO(5) | 5) +#define MT8167_PIN_5_EINT5__FUNC_CONN_TEST_CK (MTK_PIN_NO(5) | 6) +#define MT8167_PIN_5_EINT5__FUNC_DBG_MON_A_11 (MTK_PIN_NO(5) | 7) + +#define MT8167_PIN_6_EINT6__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) +#define MT8167_PIN_6_EINT6__FUNC_URTS2 (MTK_PIN_NO(6) | 1) +#define MT8167_PIN_6_EINT6__FUNC_DPI_D17 (MTK_PIN_NO(6) | 2) +#define MT8167_PIN_6_EINT6__FUNC_SPI_CLK (MTK_PIN_NO(6) | 3) +#define MT8167_PIN_6_EINT6__FUNC_EXT_RXC (MTK_PIN_NO(6) | 4) +#define MT8167_PIN_6_EINT6__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(6) | 5) +#define MT8167_PIN_6_EINT6__FUNC_MM_TEST_CK (MTK_PIN_NO(6) | 6) +#define MT8167_PIN_6_EINT6__FUNC_DBG_MON_A_12 (MTK_PIN_NO(6) | 7) + +#define MT8167_PIN_7_EINT7__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) +#define MT8167_PIN_7_EINT7__FUNC_SQIRST (MTK_PIN_NO(7) | 1) +#define MT8167_PIN_7_EINT7__FUNC_DPI_D6 (MTK_PIN_NO(7) | 2) +#define MT8167_PIN_7_EINT7__FUNC_SDA1_0 (MTK_PIN_NO(7) | 3) +#define MT8167_PIN_7_EINT7__FUNC_EXT_RXDV (MTK_PIN_NO(7) | 4) +#define MT8167_PIN_7_EINT7__FUNC_CONN_MCU_TMS (MTK_PIN_NO(7) | 5) +#define MT8167_PIN_7_EINT7__FUNC_CONN_MCU_AICE_JMSC (MTK_PIN_NO(7) | 6) +#define MT8167_PIN_7_EINT7__FUNC_DBG_MON_A_13 (MTK_PIN_NO(7) | 7) + +#define MT8167_PIN_8_EINT8__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) +#define MT8167_PIN_8_EINT8__FUNC_SQICK (MTK_PIN_NO(8) | 1) +#define MT8167_PIN_8_EINT8__FUNC_CLKM3 (MTK_PIN_NO(8) | 2) +#define MT8167_PIN_8_EINT8__FUNC_SCL1_0 (MTK_PIN_NO(8) | 3) +#define MT8167_PIN_8_EINT8__FUNC_EXT_RXD0 (MTK_PIN_NO(8) | 4) +#define MT8167_PIN_8_EINT8__FUNC_ANT_SEL0 (MTK_PIN_NO(8) | 5) +#define MT8167_PIN_8_EINT8__FUNC_DPI_D7 (MTK_PIN_NO(8) | 6) +#define MT8167_PIN_8_EINT8__FUNC_DBG_MON_A_14 (MTK_PIN_NO(8) | 7) + +#define MT8167_PIN_9_EINT9__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) +#define MT8167_PIN_9_EINT9__FUNC_CLKM4 (MTK_PIN_NO(9) | 1) +#define MT8167_PIN_9_EINT9__FUNC_SDA2_0 (MTK_PIN_NO(9) | 2) +#define MT8167_PIN_9_EINT9__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(9) | 3) +#define MT8167_PIN_9_EINT9__FUNC_EXT_RXD1 (MTK_PIN_NO(9) | 4) +#define MT8167_PIN_9_EINT9__FUNC_ANT_SEL1 (MTK_PIN_NO(9) | 5) +#define MT8167_PIN_9_EINT9__FUNC_DPI_D8 (MTK_PIN_NO(9) | 6) +#define MT8167_PIN_9_EINT9__FUNC_DBG_MON_A_15 (MTK_PIN_NO(9) | 7) + +#define MT8167_PIN_10_EINT10__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) +#define MT8167_PIN_10_EINT10__FUNC_CLKM5 (MTK_PIN_NO(10) | 1) +#define MT8167_PIN_10_EINT10__FUNC_SCL2_0 (MTK_PIN_NO(10) | 2) +#define MT8167_PIN_10_EINT10__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(10) | 3) +#define MT8167_PIN_10_EINT10__FUNC_EXT_RXD2 (MTK_PIN_NO(10) | 4) +#define MT8167_PIN_10_EINT10__FUNC_ANT_SEL2 (MTK_PIN_NO(10) | 5) +#define MT8167_PIN_10_EINT10__FUNC_DPI_D9 (MTK_PIN_NO(10) | 6) +#define MT8167_PIN_10_EINT10__FUNC_DBG_MON_A_16 (MTK_PIN_NO(10) | 7) + +#define MT8167_PIN_11_EINT11__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) +#define MT8167_PIN_11_EINT11__FUNC_CLKM4 (MTK_PIN_NO(11) | 1) +#define MT8167_PIN_11_EINT11__FUNC_PWM_C (MTK_PIN_NO(11) | 2) +#define MT8167_PIN_11_EINT11__FUNC_CONN_TEST_CK (MTK_PIN_NO(11) | 3) +#define MT8167_PIN_11_EINT11__FUNC_ANT_SEL3 (MTK_PIN_NO(11) | 4) +#define MT8167_PIN_11_EINT11__FUNC_DPI_D10 (MTK_PIN_NO(11) | 5) +#define MT8167_PIN_11_EINT11__FUNC_EXT_RXD3 (MTK_PIN_NO(11) | 6) +#define MT8167_PIN_11_EINT11__FUNC_DBG_MON_A_17 (MTK_PIN_NO(11) | 7) + +#define MT8167_PIN_12_EINT12__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) +#define MT8167_PIN_12_EINT12__FUNC_CLKM5 (MTK_PIN_NO(12) | 1) +#define MT8167_PIN_12_EINT12__FUNC_PWM_A (MTK_PIN_NO(12) | 2) +#define MT8167_PIN_12_EINT12__FUNC_SPDIF_OUT (MTK_PIN_NO(12) | 3) +#define MT8167_PIN_12_EINT12__FUNC_ANT_SEL4 (MTK_PIN_NO(12) | 4) +#define MT8167_PIN_12_EINT12__FUNC_DPI_D11 (MTK_PIN_NO(12) | 5) +#define MT8167_PIN_12_EINT12__FUNC_EXT_TXEN (MTK_PIN_NO(12) | 6) +#define MT8167_PIN_12_EINT12__FUNC_DBG_MON_A_18 (MTK_PIN_NO(12) | 7) + +#define MT8167_PIN_13_EINT13__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) +#define MT8167_PIN_13_EINT13__FUNC_TSF_IN (MTK_PIN_NO(13) | 3) +#define MT8167_PIN_13_EINT13__FUNC_ANT_SEL5 (MTK_PIN_NO(13) | 4) +#define MT8167_PIN_13_EINT13__FUNC_DPI_D0 (MTK_PIN_NO(13) | 5) +#define MT8167_PIN_13_EINT13__FUNC_SPDIF_IN (MTK_PIN_NO(13) | 6) +#define MT8167_PIN_13_EINT13__FUNC_DBG_MON_A_19 (MTK_PIN_NO(13) | 7) + +#define MT8167_PIN_14_EINT14__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) +#define MT8167_PIN_14_EINT14__FUNC_I2S_8CH_DO1 (MTK_PIN_NO(14) | 2) +#define MT8167_PIN_14_EINT14__FUNC_TDM_RX_MCK (MTK_PIN_NO(14) | 3) +#define MT8167_PIN_14_EINT14__FUNC_ANT_SEL1 (MTK_PIN_NO(14) | 4) +#define MT8167_PIN_14_EINT14__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(14) | 5) +#define MT8167_PIN_14_EINT14__FUNC_NCLE (MTK_PIN_NO(14) | 6) +#define MT8167_PIN_14_EINT14__FUNC_DBG_MON_B_8 (MTK_PIN_NO(14) | 7) + +#define MT8167_PIN_15_EINT15__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) +#define MT8167_PIN_15_EINT15__FUNC_I2S_8CH_LRCK (MTK_PIN_NO(15) | 2) +#define MT8167_PIN_15_EINT15__FUNC_TDM_RX_BCK (MTK_PIN_NO(15) | 3) +#define MT8167_PIN_15_EINT15__FUNC_ANT_SEL2 (MTK_PIN_NO(15) | 4) +#define MT8167_PIN_15_EINT15__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(15) | 5) +#define MT8167_PIN_15_EINT15__FUNC_NCEB1 (MTK_PIN_NO(15) | 6) +#define MT8167_PIN_15_EINT15__FUNC_DBG_MON_B_9 (MTK_PIN_NO(15) | 7) + +#define MT8167_PIN_16_EINT16__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) +#define MT8167_PIN_16_EINT16__FUNC_I2S_8CH_BCK (MTK_PIN_NO(16) | 2) +#define MT8167_PIN_16_EINT16__FUNC_TDM_RX_LRCK (MTK_PIN_NO(16) | 3) +#define MT8167_PIN_16_EINT16__FUNC_ANT_SEL3 (MTK_PIN_NO(16) | 4) +#define MT8167_PIN_16_EINT16__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(16) | 5) +#define MT8167_PIN_16_EINT16__FUNC_NCEB0 (MTK_PIN_NO(16) | 6) +#define MT8167_PIN_16_EINT16__FUNC_DBG_MON_B_10 (MTK_PIN_NO(16) | 7) + +#define MT8167_PIN_17_EINT17__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) +#define MT8167_PIN_17_EINT17__FUNC_I2S_8CH_MCK (MTK_PIN_NO(17) | 2) +#define MT8167_PIN_17_EINT17__FUNC_TDM_RX_DI (MTK_PIN_NO(17) | 3) +#define MT8167_PIN_17_EINT17__FUNC_IDDIG (MTK_PIN_NO(17) | 4) +#define MT8167_PIN_17_EINT17__FUNC_ANT_SEL4 (MTK_PIN_NO(17) | 5) +#define MT8167_PIN_17_EINT17__FUNC_NREB (MTK_PIN_NO(17) | 6) +#define MT8167_PIN_17_EINT17__FUNC_DBG_MON_B_11 (MTK_PIN_NO(17) | 7) + +#define MT8167_PIN_18_EINT18__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) +#define MT8167_PIN_18_EINT18__FUNC_USB_DRVVBUS (MTK_PIN_NO(18) | 2) +#define MT8167_PIN_18_EINT18__FUNC_I2S3_LRCK (MTK_PIN_NO(18) | 3) +#define MT8167_PIN_18_EINT18__FUNC_CLKM1 (MTK_PIN_NO(18) | 4) +#define MT8167_PIN_18_EINT18__FUNC_ANT_SEL3 (MTK_PIN_NO(18) | 5) +#define MT8167_PIN_18_EINT18__FUNC_I2S2_BCK (MTK_PIN_NO(18) | 6) +#define MT8167_PIN_18_EINT18__FUNC_DBG_MON_A_20 (MTK_PIN_NO(18) | 7) + +#define MT8167_PIN_19_EINT19__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) +#define MT8167_PIN_19_EINT19__FUNC_UCTS1 (MTK_PIN_NO(19) | 1) +#define MT8167_PIN_19_EINT19__FUNC_IDDIG (MTK_PIN_NO(19) | 2) +#define MT8167_PIN_19_EINT19__FUNC_I2S3_BCK (MTK_PIN_NO(19) | 3) +#define MT8167_PIN_19_EINT19__FUNC_CLKM2 (MTK_PIN_NO(19) | 4) +#define MT8167_PIN_19_EINT19__FUNC_ANT_SEL4 (MTK_PIN_NO(19) | 5) +#define MT8167_PIN_19_EINT19__FUNC_I2S2_DI (MTK_PIN_NO(19) | 6) +#define MT8167_PIN_19_EINT19__FUNC_DBG_MON_A_21 (MTK_PIN_NO(19) | 7) + +#define MT8167_PIN_20_EINT20__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) +#define MT8167_PIN_20_EINT20__FUNC_URTS1 (MTK_PIN_NO(20) | 1) +#define MT8167_PIN_20_EINT20__FUNC_I2S3_DO (MTK_PIN_NO(20) | 3) +#define MT8167_PIN_20_EINT20__FUNC_CLKM3 (MTK_PIN_NO(20) | 4) +#define MT8167_PIN_20_EINT20__FUNC_ANT_SEL5 (MTK_PIN_NO(20) | 5) +#define MT8167_PIN_20_EINT20__FUNC_I2S2_LRCK (MTK_PIN_NO(20) | 6) +#define MT8167_PIN_20_EINT20__FUNC_DBG_MON_A_22 (MTK_PIN_NO(20) | 7) + +#define MT8167_PIN_21_EINT21__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) +#define MT8167_PIN_21_EINT21__FUNC_NRNB (MTK_PIN_NO(21) | 1) +#define MT8167_PIN_21_EINT21__FUNC_ANT_SEL0 (MTK_PIN_NO(21) | 2) +#define MT8167_PIN_21_EINT21__FUNC_I2S_8CH_DO4 (MTK_PIN_NO(21) | 3) +#define MT8167_PIN_21_EINT21__FUNC_DBG_MON_B_31 (MTK_PIN_NO(21) | 7) + +#define MT8167_PIN_22_EINT22__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) +#define MT8167_PIN_22_EINT22__FUNC_I2S_8CH_DO2 (MTK_PIN_NO(22) | 2) +#define MT8167_PIN_22_EINT22__FUNC_TSF_IN (MTK_PIN_NO(22) | 3) +#define MT8167_PIN_22_EINT22__FUNC_USB_DRVVBUS (MTK_PIN_NO(22) | 4) +#define MT8167_PIN_22_EINT22__FUNC_SPDIF_OUT (MTK_PIN_NO(22) | 5) +#define MT8167_PIN_22_EINT22__FUNC_NRE_C (MTK_PIN_NO(22) | 6) +#define MT8167_PIN_22_EINT22__FUNC_DBG_MON_B_12 (MTK_PIN_NO(22) | 7) + +#define MT8167_PIN_23_EINT23__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) +#define MT8167_PIN_23_EINT23__FUNC_I2S_8CH_DO3 (MTK_PIN_NO(23) | 2) +#define MT8167_PIN_23_EINT23__FUNC_CLKM0 (MTK_PIN_NO(23) | 3) +#define MT8167_PIN_23_EINT23__FUNC_IR (MTK_PIN_NO(23) | 4) +#define MT8167_PIN_23_EINT23__FUNC_SPDIF_IN (MTK_PIN_NO(23) | 5) +#define MT8167_PIN_23_EINT23__FUNC_NDQS_C (MTK_PIN_NO(23) | 6) +#define MT8167_PIN_23_EINT23__FUNC_DBG_MON_B_13 (MTK_PIN_NO(23) | 7) + +#define MT8167_PIN_24_EINT24__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) +#define MT8167_PIN_24_EINT24__FUNC_DPI_D20 (MTK_PIN_NO(24) | 1) +#define MT8167_PIN_24_EINT24__FUNC_DPI_DE (MTK_PIN_NO(24) | 2) +#define MT8167_PIN_24_EINT24__FUNC_ANT_SEL1 (MTK_PIN_NO(24) | 3) +#define MT8167_PIN_24_EINT24__FUNC_UCTS2 (MTK_PIN_NO(24) | 4) +#define MT8167_PIN_24_EINT24__FUNC_PWM_A (MTK_PIN_NO(24) | 5) +#define MT8167_PIN_24_EINT24__FUNC_I2S0_MCK (MTK_PIN_NO(24) | 6) +#define MT8167_PIN_24_EINT24__FUNC_DBG_MON_A_0 (MTK_PIN_NO(24) | 7) + +#define MT8167_PIN_25_EINT25__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) +#define MT8167_PIN_25_EINT25__FUNC_DPI_D19 (MTK_PIN_NO(25) | 1) +#define MT8167_PIN_25_EINT25__FUNC_DPI_VSYNC (MTK_PIN_NO(25) | 2) +#define MT8167_PIN_25_EINT25__FUNC_ANT_SEL0 (MTK_PIN_NO(25) | 3) +#define MT8167_PIN_25_EINT25__FUNC_URTS2 (MTK_PIN_NO(25) | 4) +#define MT8167_PIN_25_EINT25__FUNC_PWM_B (MTK_PIN_NO(25) | 5) +#define MT8167_PIN_25_EINT25__FUNC_I2S_8CH_MCK (MTK_PIN_NO(25) | 6) +#define MT8167_PIN_25_EINT25__FUNC_DBG_MON_A_1 (MTK_PIN_NO(25) | 7) + +#define MT8167_PIN_26_PWRAP_SPI0_MI__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) +#define MT8167_PIN_26_PWRAP_SPI0_MI__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(26) | 1) +#define MT8167_PIN_26_PWRAP_SPI0_MI__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(26) | 2) + +#define MT8167_PIN_27_PWRAP_SPI0_MO__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) +#define MT8167_PIN_27_PWRAP_SPI0_MO__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(27) | 1) +#define MT8167_PIN_27_PWRAP_SPI0_MO__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(27) | 2) + +#define MT8167_PIN_28_PWRAP_INT__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) +#define MT8167_PIN_28_PWRAP_INT__FUNC_I2S0_MCK (MTK_PIN_NO(28) | 1) +#define MT8167_PIN_28_PWRAP_INT__FUNC_I2S_8CH_MCK (MTK_PIN_NO(28) | 4) +#define MT8167_PIN_28_PWRAP_INT__FUNC_I2S2_MCK (MTK_PIN_NO(28) | 5) +#define MT8167_PIN_28_PWRAP_INT__FUNC_I2S3_MCK (MTK_PIN_NO(28) | 6) + +#define MT8167_PIN_29_PWRAP_SPI0_CK__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) +#define MT8167_PIN_29_PWRAP_SPI0_CK__FUNC_PWRAP_SPI0_CK (MTK_PIN_NO(29) | 1) + +#define MT8167_PIN_30_PWRAP_SPI0_CSN__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) +#define MT8167_PIN_30_PWRAP_SPI0_CSN__FUNC_PWRAP_SPI0_CSN (MTK_PIN_NO(30) | 1) + +#define MT8167_PIN_31_RTC32K_CK__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) +#define MT8167_PIN_31_RTC32K_CK__FUNC_RTC32K_CK (MTK_PIN_NO(31) | 1) + +#define MT8167_PIN_32_WATCHDOG__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) +#define MT8167_PIN_32_WATCHDOG__FUNC_WATCHDOG (MTK_PIN_NO(32) | 1) + +#define MT8167_PIN_33_SRCLKENA__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) +#define MT8167_PIN_33_SRCLKENA__FUNC_SRCLKENA0 (MTK_PIN_NO(33) | 1) + +#define MT8167_PIN_34_URXD2__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) +#define MT8167_PIN_34_URXD2__FUNC_URXD2 (MTK_PIN_NO(34) | 1) +#define MT8167_PIN_34_URXD2__FUNC_DPI_D5 (MTK_PIN_NO(34) | 2) +#define MT8167_PIN_34_URXD2__FUNC_UTXD2 (MTK_PIN_NO(34) | 3) +#define MT8167_PIN_34_URXD2__FUNC_DBG_SCL (MTK_PIN_NO(34) | 4) +#define MT8167_PIN_34_URXD2__FUNC_I2S2_MCK (MTK_PIN_NO(34) | 6) +#define MT8167_PIN_34_URXD2__FUNC_DBG_MON_B_0 (MTK_PIN_NO(34) | 7) + +#define MT8167_PIN_35_UTXD2__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) +#define MT8167_PIN_35_UTXD2__FUNC_UTXD2 (MTK_PIN_NO(35) | 1) +#define MT8167_PIN_35_UTXD2__FUNC_DPI_HSYNC (MTK_PIN_NO(35) | 2) +#define MT8167_PIN_35_UTXD2__FUNC_URXD2 (MTK_PIN_NO(35) | 3) +#define MT8167_PIN_35_UTXD2__FUNC_DBG_SDA (MTK_PIN_NO(35) | 4) +#define MT8167_PIN_35_UTXD2__FUNC_DPI_D18 (MTK_PIN_NO(35) | 5) +#define MT8167_PIN_35_UTXD2__FUNC_I2S3_MCK (MTK_PIN_NO(35) | 6) +#define MT8167_PIN_35_UTXD2__FUNC_DBG_MON_B_1 (MTK_PIN_NO(35) | 7) + +#define MT8167_PIN_36_MRG_CLK__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) +#define MT8167_PIN_36_MRG_CLK__FUNC_MRG_CLK (MTK_PIN_NO(36) | 1) +#define MT8167_PIN_36_MRG_CLK__FUNC_DPI_D4 (MTK_PIN_NO(36) | 2) +#define MT8167_PIN_36_MRG_CLK__FUNC_I2S0_BCK (MTK_PIN_NO(36) | 3) +#define MT8167_PIN_36_MRG_CLK__FUNC_I2S3_BCK (MTK_PIN_NO(36) | 4) +#define MT8167_PIN_36_MRG_CLK__FUNC_PCM0_CLK (MTK_PIN_NO(36) | 5) +#define MT8167_PIN_36_MRG_CLK__FUNC_IR (MTK_PIN_NO(36) | 6) +#define MT8167_PIN_36_MRG_CLK__FUNC_DBG_MON_A_2 (MTK_PIN_NO(36) | 7) + +#define MT8167_PIN_37_MRG_SYNC__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) +#define MT8167_PIN_37_MRG_SYNC__FUNC_MRG_SYNC (MTK_PIN_NO(37) | 1) +#define MT8167_PIN_37_MRG_SYNC__FUNC_DPI_D3 (MTK_PIN_NO(37) | 2) +#define MT8167_PIN_37_MRG_SYNC__FUNC_I2S0_LRCK (MTK_PIN_NO(37) | 3) +#define MT8167_PIN_37_MRG_SYNC__FUNC_I2S3_LRCK (MTK_PIN_NO(37) | 4) +#define MT8167_PIN_37_MRG_SYNC__FUNC_PCM0_SYNC (MTK_PIN_NO(37) | 5) +#define MT8167_PIN_37_MRG_SYNC__FUNC_EXT_COL (MTK_PIN_NO(37) | 6) +#define MT8167_PIN_37_MRG_SYNC__FUNC_DBG_MON_A_3 (MTK_PIN_NO(37) | 7) + +#define MT8167_PIN_38_MRG_DI__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) +#define MT8167_PIN_38_MRG_DI__FUNC_MRG_DI (MTK_PIN_NO(38) | 1) +#define MT8167_PIN_38_MRG_DI__FUNC_DPI_D1 (MTK_PIN_NO(38) | 2) +#define MT8167_PIN_38_MRG_DI__FUNC_I2S0_DI (MTK_PIN_NO(38) | 3) +#define MT8167_PIN_38_MRG_DI__FUNC_I2S3_DO (MTK_PIN_NO(38) | 4) +#define MT8167_PIN_38_MRG_DI__FUNC_PCM0_DI (MTK_PIN_NO(38) | 5) +#define MT8167_PIN_38_MRG_DI__FUNC_EXT_MDIO (MTK_PIN_NO(38) | 6) +#define MT8167_PIN_38_MRG_DI__FUNC_DBG_MON_A_4 (MTK_PIN_NO(38) | 7) + +#define MT8167_PIN_39_MRG_DO__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) +#define MT8167_PIN_39_MRG_DO__FUNC_MRG_DO (MTK_PIN_NO(39) | 1) +#define MT8167_PIN_39_MRG_DO__FUNC_DPI_D2 (MTK_PIN_NO(39) | 2) +#define MT8167_PIN_39_MRG_DO__FUNC_I2S0_MCK (MTK_PIN_NO(39) | 3) +#define MT8167_PIN_39_MRG_DO__FUNC_I2S3_MCK (MTK_PIN_NO(39) | 4) +#define MT8167_PIN_39_MRG_DO__FUNC_PCM0_DO (MTK_PIN_NO(39) | 5) +#define MT8167_PIN_39_MRG_DO__FUNC_EXT_MDC (MTK_PIN_NO(39) | 6) +#define MT8167_PIN_39_MRG_DO__FUNC_DBG_MON_A_5 (MTK_PIN_NO(39) | 7) + +#define MT8167_PIN_40_KPROW0__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) +#define MT8167_PIN_40_KPROW0__FUNC_KPROW0 (MTK_PIN_NO(40) | 1) +#define MT8167_PIN_40_KPROW0__FUNC_IMG_TEST_CK (MTK_PIN_NO(40) | 4) +#define MT8167_PIN_40_KPROW0__FUNC_DBG_MON_B_4 (MTK_PIN_NO(40) | 7) + +#define MT8167_PIN_41_KPROW1__FUNC_GPIO41 (MTK_PIN_NO(41) | 0) +#define MT8167_PIN_41_KPROW1__FUNC_KPROW1 (MTK_PIN_NO(41) | 1) +#define MT8167_PIN_41_KPROW1__FUNC_IDDIG (MTK_PIN_NO(41) | 2) +#define MT8167_PIN_41_KPROW1__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(41) | 3) +#define MT8167_PIN_41_KPROW1__FUNC_MFG_TEST_CK (MTK_PIN_NO(41) | 4) +#define MT8167_PIN_41_KPROW1__FUNC_DBG_MON_B_5 (MTK_PIN_NO(41) | 7) + +#define MT8167_PIN_42_KPCOL0__FUNC_GPIO42 (MTK_PIN_NO(42) | 0) +#define MT8167_PIN_42_KPCOL0__FUNC_KPCOL0 (MTK_PIN_NO(42) | 1) +#define MT8167_PIN_42_KPCOL0__FUNC_DBG_MON_B_6 (MTK_PIN_NO(42) | 7) + +#define MT8167_PIN_43_KPCOL1__FUNC_GPIO43 (MTK_PIN_NO(43) | 0) +#define MT8167_PIN_43_KPCOL1__FUNC_KPCOL1 (MTK_PIN_NO(43) | 1) +#define MT8167_PIN_43_KPCOL1__FUNC_USB_DRVVBUS (MTK_PIN_NO(43) | 2) +#define MT8167_PIN_43_KPCOL1__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(43) | 3) +#define MT8167_PIN_43_KPCOL1__FUNC_TSF_IN (MTK_PIN_NO(43) | 4) +#define MT8167_PIN_43_KPCOL1__FUNC_DFD_NTRST_XI (MTK_PIN_NO(43) | 5) +#define MT8167_PIN_43_KPCOL1__FUNC_UDI_NTRST_XI (MTK_PIN_NO(43) | 6) +#define MT8167_PIN_43_KPCOL1__FUNC_DBG_MON_B_7 (MTK_PIN_NO(43) | 7) + +#define MT8167_PIN_44_JTMS__FUNC_GPIO44 (MTK_PIN_NO(44) | 0) +#define MT8167_PIN_44_JTMS__FUNC_JTMS (MTK_PIN_NO(44) | 1) +#define MT8167_PIN_44_JTMS__FUNC_CONN_MCU_TMS (MTK_PIN_NO(44) | 2) +#define MT8167_PIN_44_JTMS__FUNC_CONN_MCU_AICE_JMSC (MTK_PIN_NO(44) | 3) +#define MT8167_PIN_44_JTMS__FUNC_GPUDFD_TMS_XI (MTK_PIN_NO(44) | 4) +#define MT8167_PIN_44_JTMS__FUNC_DFD_TMS_XI (MTK_PIN_NO(44) | 5) +#define MT8167_PIN_44_JTMS__FUNC_UDI_TMS_XI (MTK_PIN_NO(44) | 6) + +#define MT8167_PIN_45_JTCK__FUNC_GPIO45 (MTK_PIN_NO(45) | 0) +#define MT8167_PIN_45_JTCK__FUNC_JTCK (MTK_PIN_NO(45) | 1) +#define MT8167_PIN_45_JTCK__FUNC_CONN_MCU_TCK (MTK_PIN_NO(45) | 2) +#define MT8167_PIN_45_JTCK__FUNC_CONN_MCU_AICE_JCKC (MTK_PIN_NO(45) | 3) +#define MT8167_PIN_45_JTCK__FUNC_GPUDFD_TCK_XI (MTK_PIN_NO(45) | 4) +#define MT8167_PIN_45_JTCK__FUNC_DFD_TCK_XI (MTK_PIN_NO(45) | 5) +#define MT8167_PIN_45_JTCK__FUNC_UDI_TCK_XI (MTK_PIN_NO(45) | 6) + +#define MT8167_PIN_46_JTDI__FUNC_GPIO46 (MTK_PIN_NO(46) | 0) +#define MT8167_PIN_46_JTDI__FUNC_JTDI (MTK_PIN_NO(46) | 1) +#define MT8167_PIN_46_JTDI__FUNC_CONN_MCU_TDI (MTK_PIN_NO(46) | 2) +#define MT8167_PIN_46_JTDI__FUNC_GPUDFD_TDI_XI (MTK_PIN_NO(46) | 4) +#define MT8167_PIN_46_JTDI__FUNC_DFD_TDI_XI (MTK_PIN_NO(46) | 5) +#define MT8167_PIN_46_JTDI__FUNC_UDI_TDI_XI (MTK_PIN_NO(46) | 6) + +#define MT8167_PIN_47_JTDO__FUNC_GPIO47 (MTK_PIN_NO(47) | 0) +#define MT8167_PIN_47_JTDO__FUNC_JTDO (MTK_PIN_NO(47) | 1) +#define MT8167_PIN_47_JTDO__FUNC_CONN_MCU_TDO (MTK_PIN_NO(47) | 2) +#define MT8167_PIN_47_JTDO__FUNC_GPUDFD_TDO (MTK_PIN_NO(47) | 4) +#define MT8167_PIN_47_JTDO__FUNC_DFD_TDO (MTK_PIN_NO(47) | 5) +#define MT8167_PIN_47_JTDO__FUNC_UDI_TDO (MTK_PIN_NO(47) | 6) + +#define MT8167_PIN_48_SPI_CS__FUNC_GPIO48 (MTK_PIN_NO(48) | 0) +#define MT8167_PIN_48_SPI_CS__FUNC_SPI_CSB (MTK_PIN_NO(48) | 1) +#define MT8167_PIN_48_SPI_CS__FUNC_I2S0_DI (MTK_PIN_NO(48) | 3) +#define MT8167_PIN_48_SPI_CS__FUNC_I2S2_BCK (MTK_PIN_NO(48) | 4) +#define MT8167_PIN_48_SPI_CS__FUNC_DBG_MON_A_23 (MTK_PIN_NO(48) | 7) + +#define MT8167_PIN_49_SPI_CK__FUNC_GPIO49 (MTK_PIN_NO(49) | 0) +#define MT8167_PIN_49_SPI_CK__FUNC_SPI_CLK (MTK_PIN_NO(49) | 1) +#define MT8167_PIN_49_SPI_CK__FUNC_I2S0_LRCK (MTK_PIN_NO(49) | 3) +#define MT8167_PIN_49_SPI_CK__FUNC_I2S2_DI (MTK_PIN_NO(49) | 4) +#define MT8167_PIN_49_SPI_CK__FUNC_DBG_MON_A_24 (MTK_PIN_NO(49) | 7) + +#define MT8167_PIN_50_SPI_MI__FUNC_GPIO50 (MTK_PIN_NO(50) | 0) +#define MT8167_PIN_50_SPI_MI__FUNC_SPI_MI (MTK_PIN_NO(50) | 1) +#define MT8167_PIN_50_SPI_MI__FUNC_SPI_MO (MTK_PIN_NO(50) | 2) +#define MT8167_PIN_50_SPI_MI__FUNC_I2S0_BCK (MTK_PIN_NO(50) | 3) +#define MT8167_PIN_50_SPI_MI__FUNC_I2S2_LRCK (MTK_PIN_NO(50) | 4) +#define MT8167_PIN_50_SPI_MI__FUNC_DBG_MON_A_25 (MTK_PIN_NO(50) | 7) + +#define MT8167_PIN_51_SPI_MO__FUNC_GPIO51 (MTK_PIN_NO(51) | 0) +#define MT8167_PIN_51_SPI_MO__FUNC_SPI_MO (MTK_PIN_NO(51) | 1) +#define MT8167_PIN_51_SPI_MO__FUNC_SPI_MI (MTK_PIN_NO(51) | 2) +#define MT8167_PIN_51_SPI_MO__FUNC_I2S0_MCK (MTK_PIN_NO(51) | 3) +#define MT8167_PIN_51_SPI_MO__FUNC_I2S2_MCK (MTK_PIN_NO(51) | 4) +#define MT8167_PIN_51_SPI_MO__FUNC_DBG_MON_A_26 (MTK_PIN_NO(51) | 7) + +#define MT8167_PIN_52_SDA1__FUNC_GPIO52 (MTK_PIN_NO(52) | 0) +#define MT8167_PIN_52_SDA1__FUNC_SDA1_0 (MTK_PIN_NO(52) | 1) + +#define MT8167_PIN_53_SCL1__FUNC_GPIO53 (MTK_PIN_NO(53) | 0) +#define MT8167_PIN_53_SCL1__FUNC_SCL1_0 (MTK_PIN_NO(53) | 1) + +#define MT8167_PIN_54_DISP_PWM__FUNC_GPIO54 (MTK_PIN_NO(54) | 0) +#define MT8167_PIN_54_DISP_PWM__FUNC_DISP_PWM (MTK_PIN_NO(54) | 1) +#define MT8167_PIN_54_DISP_PWM__FUNC_PWM_B (MTK_PIN_NO(54) | 2) +#define MT8167_PIN_54_DISP_PWM__FUNC_DBG_MON_B_2 (MTK_PIN_NO(54) | 7) + +#define MT8167_PIN_55_I2S_DATA_IN__FUNC_GPIO55 (MTK_PIN_NO(55) | 0) +#define MT8167_PIN_55_I2S_DATA_IN__FUNC_I2S0_DI (MTK_PIN_NO(55) | 1) +#define MT8167_PIN_55_I2S_DATA_IN__FUNC_UCTS0 (MTK_PIN_NO(55) | 2) +#define MT8167_PIN_55_I2S_DATA_IN__FUNC_I2S3_DO (MTK_PIN_NO(55) | 3) +#define MT8167_PIN_55_I2S_DATA_IN__FUNC_I2S_8CH_DO1 (MTK_PIN_NO(55) | 4) +#define MT8167_PIN_55_I2S_DATA_IN__FUNC_PWM_A (MTK_PIN_NO(55) | 5) +#define MT8167_PIN_55_I2S_DATA_IN__FUNC_I2S2_BCK (MTK_PIN_NO(55) | 6) +#define MT8167_PIN_55_I2S_DATA_IN__FUNC_DBG_MON_A_28 (MTK_PIN_NO(55) | 7) + +#define MT8167_PIN_56_I2S_LRCK__FUNC_GPIO56 (MTK_PIN_NO(56) | 0) +#define MT8167_PIN_56_I2S_LRCK__FUNC_I2S0_LRCK (MTK_PIN_NO(56) | 1) +#define MT8167_PIN_56_I2S_LRCK__FUNC_I2S3_LRCK (MTK_PIN_NO(56) | 3) +#define MT8167_PIN_56_I2S_LRCK__FUNC_I2S_8CH_LRCK (MTK_PIN_NO(56) | 4) +#define MT8167_PIN_56_I2S_LRCK__FUNC_PWM_B (MTK_PIN_NO(56) | 5) +#define MT8167_PIN_56_I2S_LRCK__FUNC_I2S2_DI (MTK_PIN_NO(56) | 6) +#define MT8167_PIN_56_I2S_LRCK__FUNC_DBG_MON_A_29 (MTK_PIN_NO(56) | 7) + +#define MT8167_PIN_57_I2S_BCK__FUNC_GPIO57 (MTK_PIN_NO(57) | 0) +#define MT8167_PIN_57_I2S_BCK__FUNC_I2S0_BCK (MTK_PIN_NO(57) | 1) +#define MT8167_PIN_57_I2S_BCK__FUNC_URTS0 (MTK_PIN_NO(57) | 2) +#define MT8167_PIN_57_I2S_BCK__FUNC_I2S3_BCK (MTK_PIN_NO(57) | 3) +#define MT8167_PIN_57_I2S_BCK__FUNC_I2S_8CH_BCK (MTK_PIN_NO(57) | 4) +#define MT8167_PIN_57_I2S_BCK__FUNC_PWM_C (MTK_PIN_NO(57) | 5) +#define MT8167_PIN_57_I2S_BCK__FUNC_I2S2_LRCK (MTK_PIN_NO(57) | 6) +#define MT8167_PIN_57_I2S_BCK__FUNC_DBG_MON_A_30 (MTK_PIN_NO(57) | 7) + +#define MT8167_PIN_58_SDA0__FUNC_GPIO58 (MTK_PIN_NO(58) | 0) +#define MT8167_PIN_58_SDA0__FUNC_SDA0_0 (MTK_PIN_NO(58) | 1) + +#define MT8167_PIN_59_SCL0__FUNC_GPIO59 (MTK_PIN_NO(59) | 0) +#define MT8167_PIN_59_SCL0__FUNC_SCL0_0 (MTK_PIN_NO(59) | 1) + +#define MT8167_PIN_60_SDA2__FUNC_GPIO60 (MTK_PIN_NO(60) | 0) +#define MT8167_PIN_60_SDA2__FUNC_SDA2_0 (MTK_PIN_NO(60) | 1) +#define MT8167_PIN_60_SDA2__FUNC_PWM_B (MTK_PIN_NO(60) | 2) + +#define MT8167_PIN_61_SCL2__FUNC_GPIO61 (MTK_PIN_NO(61) | 0) +#define MT8167_PIN_61_SCL2__FUNC_SCL2_0 (MTK_PIN_NO(61) | 1) +#define MT8167_PIN_61_SCL2__FUNC_PWM_C (MTK_PIN_NO(61) | 2) + +#define MT8167_PIN_62_URXD0__FUNC_GPIO62 (MTK_PIN_NO(62) | 0) +#define MT8167_PIN_62_URXD0__FUNC_URXD0 (MTK_PIN_NO(62) | 1) +#define MT8167_PIN_62_URXD0__FUNC_UTXD0 (MTK_PIN_NO(62) | 2) + +#define MT8167_PIN_63_UTXD0__FUNC_GPIO63 (MTK_PIN_NO(63) | 0) +#define MT8167_PIN_63_UTXD0__FUNC_UTXD0 (MTK_PIN_NO(63) | 1) +#define MT8167_PIN_63_UTXD0__FUNC_URXD0 (MTK_PIN_NO(63) | 2) + +#define MT8167_PIN_64_URXD1__FUNC_GPIO64 (MTK_PIN_NO(64) | 0) +#define MT8167_PIN_64_URXD1__FUNC_URXD1 (MTK_PIN_NO(64) | 1) +#define MT8167_PIN_64_URXD1__FUNC_UTXD1 (MTK_PIN_NO(64) | 2) +#define MT8167_PIN_64_URXD1__FUNC_DBG_MON_A_27 (MTK_PIN_NO(64) | 7) + +#define MT8167_PIN_65_UTXD1__FUNC_GPIO65 (MTK_PIN_NO(65) | 0) +#define MT8167_PIN_65_UTXD1__FUNC_UTXD1 (MTK_PIN_NO(65) | 1) +#define MT8167_PIN_65_UTXD1__FUNC_URXD1 (MTK_PIN_NO(65) | 2) +#define MT8167_PIN_65_UTXD1__FUNC_DBG_MON_A_31 (MTK_PIN_NO(65) | 7) + +#define MT8167_PIN_66_LCM_RST__FUNC_GPIO66 (MTK_PIN_NO(66) | 0) +#define MT8167_PIN_66_LCM_RST__FUNC_LCM_RST (MTK_PIN_NO(66) | 1) +#define MT8167_PIN_66_LCM_RST__FUNC_I2S0_MCK (MTK_PIN_NO(66) | 3) +#define MT8167_PIN_66_LCM_RST__FUNC_DBG_MON_B_3 (MTK_PIN_NO(66) | 7) + +#define MT8167_PIN_67_DSI_TE__FUNC_GPIO67 (MTK_PIN_NO(67) | 0) +#define MT8167_PIN_67_DSI_TE__FUNC_DSI_TE (MTK_PIN_NO(67) | 1) +#define MT8167_PIN_67_DSI_TE__FUNC_I2S_8CH_MCK (MTK_PIN_NO(67) | 3) +#define MT8167_PIN_67_DSI_TE__FUNC_DBG_MON_B_14 (MTK_PIN_NO(67) | 7) + +#define MT8167_PIN_68_MSDC2_CMD__FUNC_GPIO68 (MTK_PIN_NO(68) | 0) +#define MT8167_PIN_68_MSDC2_CMD__FUNC_MSDC2_CMD (MTK_PIN_NO(68) | 1) +#define MT8167_PIN_68_MSDC2_CMD__FUNC_I2S_8CH_DO4 (MTK_PIN_NO(68) | 2) +#define MT8167_PIN_68_MSDC2_CMD__FUNC_SDA1_0 (MTK_PIN_NO(68) | 3) +#define MT8167_PIN_68_MSDC2_CMD__FUNC_USB_SDA (MTK_PIN_NO(68) | 5) +#define MT8167_PIN_68_MSDC2_CMD__FUNC_I2S3_BCK (MTK_PIN_NO(68) | 6) +#define MT8167_PIN_68_MSDC2_CMD__FUNC_DBG_MON_B_15 (MTK_PIN_NO(68) | 7) + +#define MT8167_PIN_69_MSDC2_CLK__FUNC_GPIO69 (MTK_PIN_NO(69) | 0) +#define MT8167_PIN_69_MSDC2_CLK__FUNC_MSDC2_CLK (MTK_PIN_NO(69) | 1) +#define MT8167_PIN_69_MSDC2_CLK__FUNC_I2S_8CH_DO3 (MTK_PIN_NO(69) | 2) +#define MT8167_PIN_69_MSDC2_CLK__FUNC_SCL1_0 (MTK_PIN_NO(69) | 3) +#define MT8167_PIN_69_MSDC2_CLK__FUNC_DPI_D21 (MTK_PIN_NO(69) | 4) +#define MT8167_PIN_69_MSDC2_CLK__FUNC_USB_SCL (MTK_PIN_NO(69) | 5) +#define MT8167_PIN_69_MSDC2_CLK__FUNC_I2S3_LRCK (MTK_PIN_NO(69) | 6) +#define MT8167_PIN_69_MSDC2_CLK__FUNC_DBG_MON_B_16 (MTK_PIN_NO(69) | 7) + +#define MT8167_PIN_70_MSDC2_DAT0__FUNC_GPIO70 (MTK_PIN_NO(70) | 0) +#define MT8167_PIN_70_MSDC2_DAT0__FUNC_MSDC2_DAT0 (MTK_PIN_NO(70) | 1) +#define MT8167_PIN_70_MSDC2_DAT0__FUNC_I2S_8CH_DO2 (MTK_PIN_NO(70) | 2) +#define MT8167_PIN_70_MSDC2_DAT0__FUNC_DPI_D22 (MTK_PIN_NO(70) | 4) +#define MT8167_PIN_70_MSDC2_DAT0__FUNC_UTXD0 (MTK_PIN_NO(70) | 5) +#define MT8167_PIN_70_MSDC2_DAT0__FUNC_I2S3_DO (MTK_PIN_NO(70) | 6) +#define MT8167_PIN_70_MSDC2_DAT0__FUNC_DBG_MON_B_17 (MTK_PIN_NO(70) | 7) + +#define MT8167_PIN_71_MSDC2_DAT1__FUNC_GPIO71 (MTK_PIN_NO(71) | 0) +#define MT8167_PIN_71_MSDC2_DAT1__FUNC_MSDC2_DAT1 (MTK_PIN_NO(71) | 1) +#define MT8167_PIN_71_MSDC2_DAT1__FUNC_I2S_8CH_DO1 (MTK_PIN_NO(71) | 2) +#define MT8167_PIN_71_MSDC2_DAT1__FUNC_PWM_A (MTK_PIN_NO(71) | 3) +#define MT8167_PIN_71_MSDC2_DAT1__FUNC_I2S3_MCK (MTK_PIN_NO(71) | 4) +#define MT8167_PIN_71_MSDC2_DAT1__FUNC_URXD0 (MTK_PIN_NO(71) | 5) +#define MT8167_PIN_71_MSDC2_DAT1__FUNC_PWM_B (MTK_PIN_NO(71) | 6) +#define MT8167_PIN_71_MSDC2_DAT1__FUNC_DBG_MON_B_18 (MTK_PIN_NO(71) | 7) + +#define MT8167_PIN_72_MSDC2_DAT2__FUNC_GPIO72 (MTK_PIN_NO(72) | 0) +#define MT8167_PIN_72_MSDC2_DAT2__FUNC_MSDC2_DAT2 (MTK_PIN_NO(72) | 1) +#define MT8167_PIN_72_MSDC2_DAT2__FUNC_I2S_8CH_LRCK (MTK_PIN_NO(72) | 2) +#define MT8167_PIN_72_MSDC2_DAT2__FUNC_SDA2_0 (MTK_PIN_NO(72) | 3) +#define MT8167_PIN_72_MSDC2_DAT2__FUNC_DPI_D23 (MTK_PIN_NO(72) | 4) +#define MT8167_PIN_72_MSDC2_DAT2__FUNC_UTXD1 (MTK_PIN_NO(72) | 5) +#define MT8167_PIN_72_MSDC2_DAT2__FUNC_PWM_C (MTK_PIN_NO(72) | 6) +#define MT8167_PIN_72_MSDC2_DAT2__FUNC_DBG_MON_B_19 (MTK_PIN_NO(72) | 7) + +#define MT8167_PIN_73_MSDC2_DAT3__FUNC_GPIO73 (MTK_PIN_NO(73) | 0) +#define MT8167_PIN_73_MSDC2_DAT3__FUNC_MSDC2_DAT3 (MTK_PIN_NO(73) | 1) +#define MT8167_PIN_73_MSDC2_DAT3__FUNC_I2S_8CH_BCK (MTK_PIN_NO(73) | 2) +#define MT8167_PIN_73_MSDC2_DAT3__FUNC_SCL2_0 (MTK_PIN_NO(73) | 3) +#define MT8167_PIN_73_MSDC2_DAT3__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(73) | 4) +#define MT8167_PIN_73_MSDC2_DAT3__FUNC_URXD1 (MTK_PIN_NO(73) | 5) +#define MT8167_PIN_73_MSDC2_DAT3__FUNC_PWM_A (MTK_PIN_NO(73) | 6) +#define MT8167_PIN_73_MSDC2_DAT3__FUNC_DBG_MON_B_20 (MTK_PIN_NO(73) | 7) + +#define MT8167_PIN_74_TDN3__FUNC_GPI74 (MTK_PIN_NO(74) | 0) +#define MT8167_PIN_74_TDN3__FUNC_TDN3 (MTK_PIN_NO(74) | 1) + +#define MT8167_PIN_75_TDP3__FUNC_GPI75 (MTK_PIN_NO(75) | 0) +#define MT8167_PIN_75_TDP3__FUNC_TDP3 (MTK_PIN_NO(75) | 1) + +#define MT8167_PIN_76_TDN2__FUNC_GPI76 (MTK_PIN_NO(76) | 0) +#define MT8167_PIN_76_TDN2__FUNC_TDN2 (MTK_PIN_NO(76) | 1) + +#define MT8167_PIN_77_TDP2__FUNC_GPI77 (MTK_PIN_NO(77) | 0) +#define MT8167_PIN_77_TDP2__FUNC_TDP2 (MTK_PIN_NO(77) | 1) + +#define MT8167_PIN_78_TCN__FUNC_GPI78 (MTK_PIN_NO(78) | 0) +#define MT8167_PIN_78_TCN__FUNC_TCN (MTK_PIN_NO(78) | 1) + +#define MT8167_PIN_79_TCP__FUNC_GPI79 (MTK_PIN_NO(79) | 0) +#define MT8167_PIN_79_TCP__FUNC_TCP (MTK_PIN_NO(79) | 1) + +#define MT8167_PIN_80_TDN1__FUNC_GPI80 (MTK_PIN_NO(80) | 0) +#define MT8167_PIN_80_TDN1__FUNC_TDN1 (MTK_PIN_NO(80) | 1) + +#define MT8167_PIN_81_TDP1__FUNC_GPI81 (MTK_PIN_NO(81) | 0) +#define MT8167_PIN_81_TDP1__FUNC_TDP1 (MTK_PIN_NO(81) | 1) + +#define MT8167_PIN_82_TDN0__FUNC_GPI82 (MTK_PIN_NO(82) | 0) +#define MT8167_PIN_82_TDN0__FUNC_TDN0 (MTK_PIN_NO(82) | 1) + +#define MT8167_PIN_83_TDP0__FUNC_GPI83 (MTK_PIN_NO(83) | 0) +#define MT8167_PIN_83_TDP0__FUNC_TDP0 (MTK_PIN_NO(83) | 1) + +#define MT8167_PIN_84_RDN0__FUNC_GPI84 (MTK_PIN_NO(84) | 0) +#define MT8167_PIN_84_RDN0__FUNC_RDN0 (MTK_PIN_NO(84) | 1) + +#define MT8167_PIN_85_RDP0__FUNC_GPI85 (MTK_PIN_NO(85) | 0) +#define MT8167_PIN_85_RDP0__FUNC_RDP0 (MTK_PIN_NO(85) | 1) + +#define MT8167_PIN_86_RDN1__FUNC_GPI86 (MTK_PIN_NO(86) | 0) +#define MT8167_PIN_86_RDN1__FUNC_RDN1 (MTK_PIN_NO(86) | 1) + +#define MT8167_PIN_87_RDP1__FUNC_GPI87 (MTK_PIN_NO(87) | 0) +#define MT8167_PIN_87_RDP1__FUNC_RDP1 (MTK_PIN_NO(87) | 1) + +#define MT8167_PIN_88_RCN__FUNC_GPI88 (MTK_PIN_NO(88) | 0) +#define MT8167_PIN_88_RCN__FUNC_RCN (MTK_PIN_NO(88) | 1) + +#define MT8167_PIN_89_RCP__FUNC_GPI89 (MTK_PIN_NO(89) | 0) +#define MT8167_PIN_89_RCP__FUNC_RCP (MTK_PIN_NO(89) | 1) + +#define MT8167_PIN_90_RDN2__FUNC_GPI90 (MTK_PIN_NO(90) | 0) +#define MT8167_PIN_90_RDN2__FUNC_RDN2 (MTK_PIN_NO(90) | 1) +#define MT8167_PIN_90_RDN2__FUNC_CMDAT8 (MTK_PIN_NO(90) | 2) + +#define MT8167_PIN_91_RDP2__FUNC_GPI91 (MTK_PIN_NO(91) | 0) +#define MT8167_PIN_91_RDP2__FUNC_RDP2 (MTK_PIN_NO(91) | 1) +#define MT8167_PIN_91_RDP2__FUNC_CMDAT9 (MTK_PIN_NO(91) | 2) + +#define MT8167_PIN_92_RDN3__FUNC_GPI92 (MTK_PIN_NO(92) | 0) +#define MT8167_PIN_92_RDN3__FUNC_RDN3 (MTK_PIN_NO(92) | 1) +#define MT8167_PIN_92_RDN3__FUNC_CMDAT4 (MTK_PIN_NO(92) | 2) + +#define MT8167_PIN_93_RDP3__FUNC_GPI93 (MTK_PIN_NO(93) | 0) +#define MT8167_PIN_93_RDP3__FUNC_RDP3 (MTK_PIN_NO(93) | 1) +#define MT8167_PIN_93_RDP3__FUNC_CMDAT5 (MTK_PIN_NO(93) | 2) + +#define MT8167_PIN_94_RCN_A__FUNC_GPI94 (MTK_PIN_NO(94) | 0) +#define MT8167_PIN_94_RCN_A__FUNC_RCN_A (MTK_PIN_NO(94) | 1) +#define MT8167_PIN_94_RCN_A__FUNC_CMDAT6 (MTK_PIN_NO(94) | 2) + +#define MT8167_PIN_95_RCP_A__FUNC_GPI95 (MTK_PIN_NO(95) | 0) +#define MT8167_PIN_95_RCP_A__FUNC_RCP_A (MTK_PIN_NO(95) | 1) +#define MT8167_PIN_95_RCP_A__FUNC_CMDAT7 (MTK_PIN_NO(95) | 2) + +#define MT8167_PIN_96_RDN1_A__FUNC_GPI96 (MTK_PIN_NO(96) | 0) +#define MT8167_PIN_96_RDN1_A__FUNC_RDN1_A (MTK_PIN_NO(96) | 1) +#define MT8167_PIN_96_RDN1_A__FUNC_CMDAT2 (MTK_PIN_NO(96) | 2) +#define MT8167_PIN_96_RDN1_A__FUNC_CMCSD2 (MTK_PIN_NO(96) | 3) + +#define MT8167_PIN_97_RDP1_A__FUNC_GPI97 (MTK_PIN_NO(97) | 0) +#define MT8167_PIN_97_RDP1_A__FUNC_RDP1_A (MTK_PIN_NO(97) | 1) +#define MT8167_PIN_97_RDP1_A__FUNC_CMDAT3 (MTK_PIN_NO(97) | 2) +#define MT8167_PIN_97_RDP1_A__FUNC_CMCSD3 (MTK_PIN_NO(97) | 3) + +#define MT8167_PIN_98_RDN0_A__FUNC_GPI98 (MTK_PIN_NO(98) | 0) +#define MT8167_PIN_98_RDN0_A__FUNC_RDN0_A (MTK_PIN_NO(98) | 1) +#define MT8167_PIN_98_RDN0_A__FUNC_CMHSYNC (MTK_PIN_NO(98) | 2) + +#define MT8167_PIN_99_RDP0_A__FUNC_GPI99 (MTK_PIN_NO(99) | 0) +#define MT8167_PIN_99_RDP0_A__FUNC_RDP0_A (MTK_PIN_NO(99) | 1) +#define MT8167_PIN_99_RDP0_A__FUNC_CMVSYNC (MTK_PIN_NO(99) | 2) + +#define MT8167_PIN_100_CMDAT0__FUNC_GPIO100 (MTK_PIN_NO(100) | 0) +#define MT8167_PIN_100_CMDAT0__FUNC_CMDAT0 (MTK_PIN_NO(100) | 1) +#define MT8167_PIN_100_CMDAT0__FUNC_CMCSD0 (MTK_PIN_NO(100) | 2) +#define MT8167_PIN_100_CMDAT0__FUNC_ANT_SEL2 (MTK_PIN_NO(100) | 3) +#define MT8167_PIN_100_CMDAT0__FUNC_TDM_RX_MCK (MTK_PIN_NO(100) | 5) +#define MT8167_PIN_100_CMDAT0__FUNC_DBG_MON_B_21 (MTK_PIN_NO(100) | 7) + +#define MT8167_PIN_101_CMDAT1__FUNC_GPIO101 (MTK_PIN_NO(101) | 0) +#define MT8167_PIN_101_CMDAT1__FUNC_CMDAT1 (MTK_PIN_NO(101) | 1) +#define MT8167_PIN_101_CMDAT1__FUNC_CMCSD1 (MTK_PIN_NO(101) | 2) +#define MT8167_PIN_101_CMDAT1__FUNC_ANT_SEL3 (MTK_PIN_NO(101) | 3) +#define MT8167_PIN_101_CMDAT1__FUNC_CMFLASH (MTK_PIN_NO(101) | 4) +#define MT8167_PIN_101_CMDAT1__FUNC_TDM_RX_BCK (MTK_PIN_NO(101) | 5) +#define MT8167_PIN_101_CMDAT1__FUNC_DBG_MON_B_22 (MTK_PIN_NO(101) | 7) + +#define MT8167_PIN_102_CMMCLK__FUNC_GPIO102 (MTK_PIN_NO(102) | 0) +#define MT8167_PIN_102_CMMCLK__FUNC_CMMCLK (MTK_PIN_NO(102) | 1) +#define MT8167_PIN_102_CMMCLK__FUNC_ANT_SEL4 (MTK_PIN_NO(102) | 3) +#define MT8167_PIN_102_CMMCLK__FUNC_TDM_RX_LRCK (MTK_PIN_NO(102) | 5) +#define MT8167_PIN_102_CMMCLK__FUNC_DBG_MON_B_23 (MTK_PIN_NO(102) | 7) + +#define MT8167_PIN_103_CMPCLK__FUNC_GPIO103 (MTK_PIN_NO(103) | 0) +#define MT8167_PIN_103_CMPCLK__FUNC_CMPCLK (MTK_PIN_NO(103) | 1) +#define MT8167_PIN_103_CMPCLK__FUNC_CMCSK (MTK_PIN_NO(103) | 2) +#define MT8167_PIN_103_CMPCLK__FUNC_ANT_SEL5 (MTK_PIN_NO(103) | 3) +#define MT8167_PIN_103_CMPCLK__FUNC_TDM_RX_DI (MTK_PIN_NO(103) | 5) +#define MT8167_PIN_103_CMPCLK__FUNC_DBG_MON_B_24 (MTK_PIN_NO(103) | 7) + +#define MT8167_PIN_104_MSDC1_CMD__FUNC_GPIO104 (MTK_PIN_NO(104) | 0) +#define MT8167_PIN_104_MSDC1_CMD__FUNC_MSDC1_CMD (MTK_PIN_NO(104) | 1) +#define MT8167_PIN_104_MSDC1_CMD__FUNC_SQICS (MTK_PIN_NO(104) | 4) +#define MT8167_PIN_104_MSDC1_CMD__FUNC_DBG_MON_B_25 (MTK_PIN_NO(104) | 7) + +#define MT8167_PIN_105_MSDC1_CLK__FUNC_GPIO105 (MTK_PIN_NO(105) | 0) +#define MT8167_PIN_105_MSDC1_CLK__FUNC_MSDC1_CLK (MTK_PIN_NO(105) | 1) +#define MT8167_PIN_105_MSDC1_CLK__FUNC_UDI_NTRST_XI (MTK_PIN_NO(105) | 2) +#define MT8167_PIN_105_MSDC1_CLK__FUNC_DFD_NTRST_XI (MTK_PIN_NO(105) | 3) +#define MT8167_PIN_105_MSDC1_CLK__FUNC_SQISO (MTK_PIN_NO(105) | 4) +#define MT8167_PIN_105_MSDC1_CLK__FUNC_GPUEJ_NTRST_XI (MTK_PIN_NO(105) | 5) +#define MT8167_PIN_105_MSDC1_CLK__FUNC_DBG_MON_B_26 (MTK_PIN_NO(105) | 7) + +#define MT8167_PIN_106_MSDC1_DAT0__FUNC_GPIO106 (MTK_PIN_NO(106) | 0) +#define MT8167_PIN_106_MSDC1_DAT0__FUNC_MSDC1_DAT0 (MTK_PIN_NO(106) | 1) +#define MT8167_PIN_106_MSDC1_DAT0__FUNC_UDI_TMS_XI (MTK_PIN_NO(106) | 2) +#define MT8167_PIN_106_MSDC1_DAT0__FUNC_DFD_TMS_XI (MTK_PIN_NO(106) | 3) +#define MT8167_PIN_106_MSDC1_DAT0__FUNC_SQISI (MTK_PIN_NO(106) | 4) +#define MT8167_PIN_106_MSDC1_DAT0__FUNC_GPUEJ_TMS_XI (MTK_PIN_NO(106) | 5) +#define MT8167_PIN_106_MSDC1_DAT0__FUNC_DBG_MON_B_27 (MTK_PIN_NO(106) | 7) + +#define MT8167_PIN_107_MSDC1_DAT1__FUNC_GPIO107 (MTK_PIN_NO(107) | 0) +#define MT8167_PIN_107_MSDC1_DAT1__FUNC_MSDC1_DAT1 (MTK_PIN_NO(107) | 1) +#define MT8167_PIN_107_MSDC1_DAT1__FUNC_UDI_TCK_XI (MTK_PIN_NO(107) | 2) +#define MT8167_PIN_107_MSDC1_DAT1__FUNC_DFD_TCK_XI (MTK_PIN_NO(107) | 3) +#define MT8167_PIN_107_MSDC1_DAT1__FUNC_SQIWP (MTK_PIN_NO(107) | 4) +#define MT8167_PIN_107_MSDC1_DAT1__FUNC_GPUEJ_TCK_XI (MTK_PIN_NO(107) | 5) +#define MT8167_PIN_107_MSDC1_DAT1__FUNC_DBG_MON_B_28 (MTK_PIN_NO(107) | 7) + +#define MT8167_PIN_108_MSDC1_DAT2__FUNC_GPIO108 (MTK_PIN_NO(108) | 0) +#define MT8167_PIN_108_MSDC1_DAT2__FUNC_MSDC1_DAT2 (MTK_PIN_NO(108) | 1) +#define MT8167_PIN_108_MSDC1_DAT2__FUNC_UDI_TDI_XI (MTK_PIN_NO(108) | 2) +#define MT8167_PIN_108_MSDC1_DAT2__FUNC_DFD_TDI_XI (MTK_PIN_NO(108) | 3) +#define MT8167_PIN_108_MSDC1_DAT2__FUNC_SQIRST (MTK_PIN_NO(108) | 4) +#define MT8167_PIN_108_MSDC1_DAT2__FUNC_GPUEJ_TDI_XI (MTK_PIN_NO(108) | 5) +#define MT8167_PIN_108_MSDC1_DAT2__FUNC_DBG_MON_B_29 (MTK_PIN_NO(108) | 7) + +#define MT8167_PIN_109_MSDC1_DAT3__FUNC_GPIO109 (MTK_PIN_NO(109) | 0) +#define MT8167_PIN_109_MSDC1_DAT3__FUNC_MSDC1_DAT3 (MTK_PIN_NO(109) | 1) +#define MT8167_PIN_109_MSDC1_DAT3__FUNC_UDI_TDO (MTK_PIN_NO(109) | 2) +#define MT8167_PIN_109_MSDC1_DAT3__FUNC_DFD_TDO (MTK_PIN_NO(109) | 3) +#define MT8167_PIN_109_MSDC1_DAT3__FUNC_SQICK (MTK_PIN_NO(109) | 4) +#define MT8167_PIN_109_MSDC1_DAT3__FUNC_GPUEJ_TDO (MTK_PIN_NO(109) | 5) +#define MT8167_PIN_109_MSDC1_DAT3__FUNC_DBG_MON_B_30 (MTK_PIN_NO(109) | 7) + +#define MT8167_PIN_110_MSDC0_DAT7__FUNC_GPIO110 (MTK_PIN_NO(110) | 0) +#define MT8167_PIN_110_MSDC0_DAT7__FUNC_MSDC0_DAT7 (MTK_PIN_NO(110) | 1) +#define MT8167_PIN_110_MSDC0_DAT7__FUNC_NLD7 (MTK_PIN_NO(110) | 4) + +#define MT8167_PIN_111_MSDC0_DAT6__FUNC_GPIO111 (MTK_PIN_NO(111) | 0) +#define MT8167_PIN_111_MSDC0_DAT6__FUNC_MSDC0_DAT6 (MTK_PIN_NO(111) | 1) +#define MT8167_PIN_111_MSDC0_DAT6__FUNC_NLD6 (MTK_PIN_NO(111) | 4) + +#define MT8167_PIN_112_MSDC0_DAT5__FUNC_GPIO112 (MTK_PIN_NO(112) | 0) +#define MT8167_PIN_112_MSDC0_DAT5__FUNC_MSDC0_DAT5 (MTK_PIN_NO(112) | 1) +#define MT8167_PIN_112_MSDC0_DAT5__FUNC_NLD4 (MTK_PIN_NO(112) | 4) + +#define MT8167_PIN_113_MSDC0_DAT4__FUNC_GPIO113 (MTK_PIN_NO(113) | 0) +#define MT8167_PIN_113_MSDC0_DAT4__FUNC_MSDC0_DAT4 (MTK_PIN_NO(113) | 1) +#define MT8167_PIN_113_MSDC0_DAT4__FUNC_NLD3 (MTK_PIN_NO(113) | 4) + +#define MT8167_PIN_114_MSDC0_RSTB__FUNC_GPIO114 (MTK_PIN_NO(114) | 0) +#define MT8167_PIN_114_MSDC0_RSTB__FUNC_MSDC0_RSTB (MTK_PIN_NO(114) | 1) +#define MT8167_PIN_114_MSDC0_RSTB__FUNC_NLD0 (MTK_PIN_NO(114) | 4) + +#define MT8167_PIN_115_MSDC0_CMD__FUNC_GPIO115 (MTK_PIN_NO(115) | 0) +#define MT8167_PIN_115_MSDC0_CMD__FUNC_MSDC0_CMD (MTK_PIN_NO(115) | 1) +#define MT8167_PIN_115_MSDC0_CMD__FUNC_NALE (MTK_PIN_NO(115) | 4) + +#define MT8167_PIN_116_MSDC0_CLK__FUNC_GPIO116 (MTK_PIN_NO(116) | 0) +#define MT8167_PIN_116_MSDC0_CLK__FUNC_MSDC0_CLK (MTK_PIN_NO(116) | 1) +#define MT8167_PIN_116_MSDC0_CLK__FUNC_NWEB (MTK_PIN_NO(116) | 4) + +#define MT8167_PIN_117_MSDC0_DAT3__FUNC_GPIO117 (MTK_PIN_NO(117) | 0) +#define MT8167_PIN_117_MSDC0_DAT3__FUNC_MSDC0_DAT3 (MTK_PIN_NO(117) | 1) +#define MT8167_PIN_117_MSDC0_DAT3__FUNC_NLD1 (MTK_PIN_NO(117) | 4) + +#define MT8167_PIN_118_MSDC0_DAT2__FUNC_GPIO118 (MTK_PIN_NO(118) | 0) +#define MT8167_PIN_118_MSDC0_DAT2__FUNC_MSDC0_DAT2 (MTK_PIN_NO(118) | 1) +#define MT8167_PIN_118_MSDC0_DAT2__FUNC_NLD5 (MTK_PIN_NO(118) | 4) + +#define MT8167_PIN_119_MSDC0_DAT1__FUNC_GPIO119 (MTK_PIN_NO(119) | 0) +#define MT8167_PIN_119_MSDC0_DAT1__FUNC_MSDC0_DAT1 (MTK_PIN_NO(119) | 1) +#define MT8167_PIN_119_MSDC0_DAT1__FUNC_NLD8 (MTK_PIN_NO(119) | 4) + +#define MT8167_PIN_120_MSDC0_DAT0__FUNC_GPIO120 (MTK_PIN_NO(120) | 0) +#define MT8167_PIN_120_MSDC0_DAT0__FUNC_MSDC0_DAT0 (MTK_PIN_NO(120) | 1) +#define MT8167_PIN_120_MSDC0_DAT0__FUNC_WATCHDOG (MTK_PIN_NO(120) | 4) +#define MT8167_PIN_120_MSDC0_DAT0__FUNC_NLD2 (MTK_PIN_NO(120) | 5) + +#define MT8167_PIN_121_CEC__FUNC_GPIO121 (MTK_PIN_NO(121) | 0) +#define MT8167_PIN_121_CEC__FUNC_CEC (MTK_PIN_NO(121) | 1) + +#define MT8167_PIN_122_HTPLG__FUNC_GPIO122 (MTK_PIN_NO(122) | 0) +#define MT8167_PIN_122_HTPLG__FUNC_HTPLG (MTK_PIN_NO(122) | 1) + +#define MT8167_PIN_123_HDMISCK__FUNC_GPIO123 (MTK_PIN_NO(123) | 0) +#define MT8167_PIN_123_HDMISCK__FUNC_HDMISCK (MTK_PIN_NO(123) | 1) + +#define MT8167_PIN_124_HDMISD__FUNC_GPIO124 (MTK_PIN_NO(124) | 0) +#define MT8167_PIN_124_HDMISD__FUNC_HDMISD (MTK_PIN_NO(124) | 1) + +#endif /* __DTS_MT8167_PINFUNC_H */ diff --git a/arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dts new file mode 100644 index 000000000000..774a2f3fb4b2 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 BayLibre, SAS. + * Author: Fabien Parent <fparent@baylibre.com> + */ + +/dts-v1/; + +#include "mt8167.dtsi" +#include "pumpkin-common.dtsi" + +/ { + model = "Pumpkin MT8167"; + compatible = "mediatek,mt8167-pumpkin", "mediatek,mt8167"; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 0 0x80000000>; + }; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8167.dtsi b/arch/arm64/boot/dts/mediatek/mt8167.dtsi new file mode 100644 index 000000000000..1c5639ead622 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8167.dtsi @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 MediaTek Inc. + * Copyright (c) 2020 BayLibre, SAS. + * Author: Fabien Parent <fparent@baylibre.com> + */ + +#include <dt-bindings/clock/mt8167-clk.h> +#include <dt-bindings/memory/mt8167-larb-port.h> + +#include "mt8167-pinfunc.h" + +#include "mt8516.dtsi" + +/ { + compatible = "mediatek,mt8167"; + + soc { + topckgen: topckgen@10000000 { + compatible = "mediatek,mt8167-topckgen", "syscon"; + reg = <0 0x10000000 0 0x1000>; + #clock-cells = <1>; + }; + + infracfg: infracfg@10001000 { + compatible = "mediatek,mt8167-infracfg", "syscon"; + reg = <0 0x10001000 0 0x1000>; + #clock-cells = <1>; + }; + + apmixedsys: apmixedsys@10018000 { + compatible = "mediatek,mt8167-apmixedsys", "syscon"; + reg = <0 0x10018000 0 0x710>; + #clock-cells = <1>; + }; + + imgsys: syscon@15000000 { + compatible = "mediatek,mt8167-imgsys", "syscon"; + reg = <0 0x15000000 0 0x1000>; + #clock-cells = <1>; + }; + + vdecsys: syscon@16000000 { + compatible = "mediatek,mt8167-vdecsys", "syscon"; + reg = <0 0x16000000 0 0x1000>; + #clock-cells = <1>; + }; + + pio: pinctrl@1000b000 { + compatible = "mediatek,mt8167-pinctrl"; + reg = <0 0x1000b000 0 0x1000>; + mediatek,pctl-regmap = <&syscfg_pctl>; + pins-are-numbered; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi index 44a0346133cd..21452c51a20a 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi @@ -87,7 +87,6 @@ panel: panel { compatible = "lg,lp120up1"; power-supply = <&panel_fixed_3v3>; - ddc-i2c-bus = <&i2c0>; backlight = <&backlight>; port { diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 5e046f9d48ce..7fa870e4386a 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -450,16 +450,82 @@ }; }; - scpsys: power-controller@10006000 { - compatible = "mediatek,mt8173-scpsys"; - #power-domain-cells = <1>; + scpsys: syscon@10006000 { + compatible = "syscon", "simple-mfd"; reg = <0 0x10006000 0 0x1000>; - clocks = <&clk26m>, - <&topckgen CLK_TOP_MM_SEL>, - <&topckgen CLK_TOP_VENC_SEL>, - <&topckgen CLK_TOP_VENC_LT_SEL>; - clock-names = "mfg", "mm", "venc", "venc_lt"; - infracfg = <&infracfg>; + #power-domain-cells = <1>; + + /* System Power Manager */ + spm: power-controller { + compatible = "mediatek,mt8173-power-controller"; + #address-cells = <1>; + #size-cells = <0>; + #power-domain-cells = <1>; + + /* power domains of the SoC */ + power-domain@MT8173_POWER_DOMAIN_VDEC { + reg = <MT8173_POWER_DOMAIN_VDEC>; + clocks = <&topckgen CLK_TOP_MM_SEL>; + clock-names = "mm"; + #power-domain-cells = <0>; + }; + power-domain@MT8173_POWER_DOMAIN_VENC { + reg = <MT8173_POWER_DOMAIN_VENC>; + clocks = <&topckgen CLK_TOP_MM_SEL>, + <&topckgen CLK_TOP_VENC_SEL>; + clock-names = "mm", "venc"; + #power-domain-cells = <0>; + }; + power-domain@MT8173_POWER_DOMAIN_ISP { + reg = <MT8173_POWER_DOMAIN_ISP>; + clocks = <&topckgen CLK_TOP_MM_SEL>; + clock-names = "mm"; + #power-domain-cells = <0>; + }; + power-domain@MT8173_POWER_DOMAIN_MM { + reg = <MT8173_POWER_DOMAIN_MM>; + clocks = <&topckgen CLK_TOP_MM_SEL>; + clock-names = "mm"; + #power-domain-cells = <0>; + mediatek,infracfg = <&infracfg>; + }; + power-domain@MT8173_POWER_DOMAIN_VENC_LT { + reg = <MT8173_POWER_DOMAIN_VENC_LT>; + clocks = <&topckgen CLK_TOP_MM_SEL>, + <&topckgen CLK_TOP_VENC_LT_SEL>; + clock-names = "mm", "venclt"; + #power-domain-cells = <0>; + }; + power-domain@MT8173_POWER_DOMAIN_AUDIO { + reg = <MT8173_POWER_DOMAIN_AUDIO>; + #power-domain-cells = <0>; + }; + power-domain@MT8173_POWER_DOMAIN_USB { + reg = <MT8173_POWER_DOMAIN_USB>; + #power-domain-cells = <0>; + }; + power-domain@MT8173_POWER_DOMAIN_MFG_ASYNC { + reg = <MT8173_POWER_DOMAIN_MFG_ASYNC>; + clocks = <&clk26m>; + clock-names = "mfg"; + #address-cells = <1>; + #size-cells = <0>; + #power-domain-cells = <1>; + + power-domain@MT8173_POWER_DOMAIN_MFG_2D { + reg = <MT8173_POWER_DOMAIN_MFG_2D>; + #address-cells = <1>; + #size-cells = <0>; + #power-domain-cells = <1>; + + power-domain@MT8173_POWER_DOMAIN_MFG { + reg = <MT8173_POWER_DOMAIN_MFG>; + #power-domain-cells = <0>; + mediatek,infracfg = <&infracfg>; + }; + }; + }; + }; }; watchdog: watchdog@10007000 { @@ -792,7 +858,7 @@ compatible = "mediatek,mt8173-afe-pcm"; reg = <0 0x11220000 0 0x1000>; interrupts = <GIC_SPI 134 IRQ_TYPE_EDGE_FALLING>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_AUDIO>; + power-domains = <&spm MT8173_POWER_DOMAIN_AUDIO>; clocks = <&infracfg CLK_INFRA_AUDIO>, <&topckgen CLK_TOP_AUDIO_SEL>, <&topckgen CLK_TOP_AUD_INTBUS_SEL>, @@ -868,7 +934,7 @@ phys = <&u2port0 PHY_TYPE_USB2>, <&u3port0 PHY_TYPE_USB3>, <&u2port1 PHY_TYPE_USB2>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; + power-domains = <&spm MT8173_POWER_DOMAIN_USB>; clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>; clock-names = "sys_ck", "ref_ck"; mediatek,syscon-wakeup = <&pericfg 0x400 1>; @@ -882,7 +948,7 @@ reg = <0 0x11270000 0 0x1000>; reg-names = "mac"; interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; + power-domains = <&spm MT8173_POWER_DOMAIN_USB>; clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>; clock-names = "sys_ck", "ref_ck"; status = "disabled"; @@ -925,7 +991,7 @@ mmsys: syscon@14000000 { compatible = "mediatek,mt8173-mmsys", "syscon"; reg = <0 0x14000000 0 0x1000>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; assigned-clocks = <&topckgen CLK_TOP_MM_SEL>; assigned-clock-rates = <400000000>; #clock-cells = <1>; @@ -940,7 +1006,7 @@ reg = <0 0x14001000 0 0x1000>; clocks = <&mmsys CLK_MM_MDP_RDMA0>, <&mmsys CLK_MM_MUTEX_32K>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; iommus = <&iommu M4U_PORT_MDP_RDMA0>; mediatek,larb = <&larb0>; mediatek,vpu = <&vpu>; @@ -951,7 +1017,7 @@ reg = <0 0x14002000 0 0x1000>; clocks = <&mmsys CLK_MM_MDP_RDMA1>, <&mmsys CLK_MM_MUTEX_32K>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; iommus = <&iommu M4U_PORT_MDP_RDMA1>; mediatek,larb = <&larb4>; }; @@ -960,28 +1026,28 @@ compatible = "mediatek,mt8173-mdp-rsz"; reg = <0 0x14003000 0 0x1000>; clocks = <&mmsys CLK_MM_MDP_RSZ0>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; }; mdp_rsz1: rsz@14004000 { compatible = "mediatek,mt8173-mdp-rsz"; reg = <0 0x14004000 0 0x1000>; clocks = <&mmsys CLK_MM_MDP_RSZ1>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; }; mdp_rsz2: rsz@14005000 { compatible = "mediatek,mt8173-mdp-rsz"; reg = <0 0x14005000 0 0x1000>; clocks = <&mmsys CLK_MM_MDP_RSZ2>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; }; mdp_wdma0: wdma@14006000 { compatible = "mediatek,mt8173-mdp-wdma"; reg = <0 0x14006000 0 0x1000>; clocks = <&mmsys CLK_MM_MDP_WDMA>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; iommus = <&iommu M4U_PORT_MDP_WDMA>; mediatek,larb = <&larb0>; }; @@ -990,7 +1056,7 @@ compatible = "mediatek,mt8173-mdp-wrot"; reg = <0 0x14007000 0 0x1000>; clocks = <&mmsys CLK_MM_MDP_WROT0>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; iommus = <&iommu M4U_PORT_MDP_WROT0>; mediatek,larb = <&larb0>; }; @@ -999,7 +1065,7 @@ compatible = "mediatek,mt8173-mdp-wrot"; reg = <0 0x14008000 0 0x1000>; clocks = <&mmsys CLK_MM_MDP_WROT1>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; iommus = <&iommu M4U_PORT_MDP_WROT1>; mediatek,larb = <&larb4>; }; @@ -1008,7 +1074,7 @@ compatible = "mediatek,mt8173-disp-ovl"; reg = <0 0x1400c000 0 0x1000>; interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_OVL0>; iommus = <&iommu M4U_PORT_DISP_OVL0>; mediatek,larb = <&larb0>; @@ -1019,7 +1085,7 @@ compatible = "mediatek,mt8173-disp-ovl"; reg = <0 0x1400d000 0 0x1000>; interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_OVL1>; iommus = <&iommu M4U_PORT_DISP_OVL1>; mediatek,larb = <&larb4>; @@ -1030,7 +1096,7 @@ compatible = "mediatek,mt8173-disp-rdma"; reg = <0 0x1400e000 0 0x1000>; interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_RDMA0>; iommus = <&iommu M4U_PORT_DISP_RDMA0>; mediatek,larb = <&larb0>; @@ -1041,7 +1107,7 @@ compatible = "mediatek,mt8173-disp-rdma"; reg = <0 0x1400f000 0 0x1000>; interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_RDMA1>; iommus = <&iommu M4U_PORT_DISP_RDMA1>; mediatek,larb = <&larb4>; @@ -1052,7 +1118,7 @@ compatible = "mediatek,mt8173-disp-rdma"; reg = <0 0x14010000 0 0x1000>; interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_RDMA2>; iommus = <&iommu M4U_PORT_DISP_RDMA2>; mediatek,larb = <&larb4>; @@ -1063,7 +1129,7 @@ compatible = "mediatek,mt8173-disp-wdma"; reg = <0 0x14011000 0 0x1000>; interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_WDMA0>; iommus = <&iommu M4U_PORT_DISP_WDMA0>; mediatek,larb = <&larb0>; @@ -1074,7 +1140,7 @@ compatible = "mediatek,mt8173-disp-wdma"; reg = <0 0x14012000 0 0x1000>; interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_WDMA1>; iommus = <&iommu M4U_PORT_DISP_WDMA1>; mediatek,larb = <&larb4>; @@ -1085,7 +1151,7 @@ compatible = "mediatek,mt8173-disp-color"; reg = <0 0x14013000 0 0x1000>; interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_COLOR0>; mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x3000 0x1000>; }; @@ -1094,7 +1160,7 @@ compatible = "mediatek,mt8173-disp-color"; reg = <0 0x14014000 0 0x1000>; interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_COLOR1>; mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x4000 0x1000>; }; @@ -1103,7 +1169,7 @@ compatible = "mediatek,mt8173-disp-aal"; reg = <0 0x14015000 0 0x1000>; interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_AAL>; mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x5000 0x1000>; }; @@ -1112,7 +1178,7 @@ compatible = "mediatek,mt8173-disp-gamma"; reg = <0 0x14016000 0 0x1000>; interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_GAMMA>; mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x6000 0x1000>; }; @@ -1120,21 +1186,21 @@ merge@14017000 { compatible = "mediatek,mt8173-disp-merge"; reg = <0 0x14017000 0 0x1000>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_MERGE>; }; split0: split@14018000 { compatible = "mediatek,mt8173-disp-split"; reg = <0 0x14018000 0 0x1000>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_SPLIT0>; }; split1: split@14019000 { compatible = "mediatek,mt8173-disp-split"; reg = <0 0x14019000 0 0x1000>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_SPLIT1>; }; @@ -1142,7 +1208,7 @@ compatible = "mediatek,mt8173-disp-ufoe"; reg = <0 0x1401a000 0 0x1000>; interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DISP_UFOE>; }; @@ -1150,7 +1216,7 @@ compatible = "mediatek,mt8173-dsi"; reg = <0 0x1401b000 0 0x1000>; interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DSI0_ENGINE>, <&mmsys CLK_MM_DSI0_DIGITAL>, <&mipi_tx0>; @@ -1164,7 +1230,7 @@ compatible = "mediatek,mt8173-dsi"; reg = <0 0x1401c000 0 0x1000>; interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DSI1_ENGINE>, <&mmsys CLK_MM_DSI1_DIGITAL>, <&mipi_tx1>; @@ -1178,7 +1244,7 @@ compatible = "mediatek,mt8173-dpi"; reg = <0 0x1401d000 0 0x1000>; interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_DPI_PIXEL>, <&mmsys CLK_MM_DPI_ENGINE>, <&apmixedsys CLK_APMIXED_TVDPLL>; @@ -1218,7 +1284,7 @@ compatible = "mediatek,mt8173-disp-mutex"; reg = <0 0x14020000 0 0x1000>; interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_MUTEX_32K>; mediatek,gce-events = <CMDQ_EVENT_MUTEX0_STREAM_EOF>, <CMDQ_EVENT_MUTEX1_STREAM_EOF>; @@ -1228,7 +1294,7 @@ compatible = "mediatek,mt8173-smi-larb"; reg = <0 0x14021000 0 0x1000>; mediatek,smi = <&smi_common>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_SMI_LARB0>, <&mmsys CLK_MM_SMI_LARB0>; clock-names = "apb", "smi"; @@ -1237,7 +1303,7 @@ smi_common: smi@14022000 { compatible = "mediatek,mt8173-smi-common"; reg = <0 0x14022000 0 0x1000>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_SMI_COMMON>, <&mmsys CLK_MM_SMI_COMMON>; clock-names = "apb", "smi"; @@ -1285,7 +1351,7 @@ compatible = "mediatek,mt8173-smi-larb"; reg = <0 0x14027000 0 0x1000>; mediatek,smi = <&smi_common>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + power-domains = <&spm MT8173_POWER_DOMAIN_MM>; clocks = <&mmsys CLK_MM_SMI_LARB4>, <&mmsys CLK_MM_SMI_LARB4>; clock-names = "apb", "smi"; @@ -1301,7 +1367,7 @@ compatible = "mediatek,mt8173-smi-larb"; reg = <0 0x15001000 0 0x1000>; mediatek,smi = <&smi_common>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_ISP>; + power-domains = <&spm MT8173_POWER_DOMAIN_ISP>; clocks = <&imgsys CLK_IMG_LARB2_SMI>, <&imgsys CLK_IMG_LARB2_SMI>; clock-names = "apb", "smi"; @@ -1338,7 +1404,7 @@ <&iommu M4U_PORT_HW_VDEC_VLD_EXT>, <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>; mediatek,vpu = <&vpu>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>; + power-domains = <&spm MT8173_POWER_DOMAIN_VDEC>; clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>, <&topckgen CLK_TOP_UNIVPLL_D2>, <&topckgen CLK_TOP_CCI400_SEL>, @@ -1370,7 +1436,7 @@ compatible = "mediatek,mt8173-smi-larb"; reg = <0 0x16010000 0 0x1000>; mediatek,smi = <&smi_common>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>; + power-domains = <&spm MT8173_POWER_DOMAIN_VDEC>; clocks = <&vdecsys CLK_VDEC_CKEN>, <&vdecsys CLK_VDEC_LARB_CKEN>; clock-names = "apb", "smi"; @@ -1386,7 +1452,7 @@ compatible = "mediatek,mt8173-smi-larb"; reg = <0 0x18001000 0 0x1000>; mediatek,smi = <&smi_common>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_VENC>; + power-domains = <&spm MT8173_POWER_DOMAIN_VENC>; clocks = <&vencsys CLK_VENC_CKE1>, <&vencsys CLK_VENC_CKE0>; clock-names = "apb", "smi"; @@ -1443,7 +1509,7 @@ <&vencsys CLK_VENC_CKE3>; clock-names = "jpgdec-smi", "jpgdec"; - power-domains = <&scpsys MT8173_POWER_DOMAIN_VENC>; + power-domains = <&spm MT8173_POWER_DOMAIN_VENC>; mediatek,larb = <&larb3>; iommus = <&iommu M4U_PORT_JPGDEC_WDMA>, <&iommu M4U_PORT_JPGDEC_BSDMA>; @@ -1459,7 +1525,7 @@ compatible = "mediatek,mt8173-smi-larb"; reg = <0 0x19001000 0 0x1000>; mediatek,smi = <&smi_common>; - power-domains = <&scpsys MT8173_POWER_DOMAIN_VENC_LT>; + power-domains = <&spm MT8173_POWER_DOMAIN_VENC_LT>; clocks = <&vencltsys CLK_VENCLT_CKE1>, <&vencltsys CLK_VENCLT_CKE0>; clock-names = "apb", "smi"; diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi index 85f7c33ba446..bf2ad1294dd3 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi @@ -19,6 +19,17 @@ stdout-path = "serial0:115200n8"; }; + backlight_lcd0: backlight_lcd0 { + compatible = "pwm-backlight"; + pwms = <&pwm0 0 500000>; + power-supply = <&bl_pp5000>; + enable-gpios = <&pio 176 0>; + brightness-levels = <0 1023>; + num-interpolated-steps = <1023>; + default-brightness-level = <576>; + status = "okay"; + }; + memory@40000000 { device_type = "memory"; reg = <0 0x40000000 0 0x80000000>; @@ -536,6 +547,17 @@ }; }; + pwm0_pin_default: pwm0_pin_default { + pins1 { + pinmux = <PINMUX_GPIO176__FUNC_GPIO176>; + output-high; + bias-pull-up; + }; + pins2 { + pinmux = <PINMUX_GPIO43__FUNC_DISP_PWM>; + }; + }; + scp_pins: scp { pins_scp_uart { pinmux = <PINMUX_GPIO110__FUNC_TP_URXD1_AO>, @@ -670,6 +692,12 @@ }; }; +&pwm0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pin_default>; +}; + &scp { status = "okay"; pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi index 9cfd961c45eb..5b782a4769e7 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi @@ -6,8 +6,11 @@ */ #include <dt-bindings/clock/mt8183-clk.h> +#include <dt-bindings/gce/mt8173-gce.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/memory/mt8183-larb-port.h> +#include <dt-bindings/power/mt8183-power.h> #include <dt-bindings/reset-controller/mt8183-resets.h> #include <dt-bindings/phy/phy.h> #include "mt8183-pinfunc.h" @@ -31,6 +34,11 @@ i2c9 = &i2c9; i2c10 = &i2c10; i2c11 = &i2c11; + ovl0 = &ovl0; + ovl-2l0 = &ovl_2l0; + ovl-2l1 = &ovl_2l1; + rdma0 = &rdma0; + rdma1 = &rdma1; }; cpus { @@ -316,6 +324,167 @@ #interrupt-cells = <2>; }; + scpsys: syscon@10006000 { + compatible = "syscon", "simple-mfd"; + reg = <0 0x10006000 0 0x1000>; + #power-domain-cells = <1>; + + /* System Power Manager */ + spm: power-controller { + compatible = "mediatek,mt8183-power-controller"; + #address-cells = <1>; + #size-cells = <0>; + #power-domain-cells = <1>; + + /* power domain of the SoC */ + power-domain@MT8183_POWER_DOMAIN_AUDIO { + reg = <MT8183_POWER_DOMAIN_AUDIO>; + clocks = <&topckgen CLK_TOP_MUX_AUD_INTBUS>, + <&infracfg CLK_INFRA_AUDIO>, + <&infracfg CLK_INFRA_AUDIO_26M_BCLK>; + clock-names = "audio", "audio1", "audio2"; + #power-domain-cells = <0>; + }; + + power-domain@MT8183_POWER_DOMAIN_CONN { + reg = <MT8183_POWER_DOMAIN_CONN>; + mediatek,infracfg = <&infracfg>; + #power-domain-cells = <0>; + }; + + power-domain@MT8183_POWER_DOMAIN_MFG_ASYNC { + reg = <MT8183_POWER_DOMAIN_MFG_ASYNC>; + clocks = <&topckgen CLK_TOP_MUX_MFG>; + clock-names = "mfg"; + #address-cells = <1>; + #size-cells = <0>; + #power-domain-cells = <1>; + + power-domain@MT8183_POWER_DOMAIN_MFG { + reg = <MT8183_POWER_DOMAIN_MFG>; + #address-cells = <1>; + #size-cells = <0>; + #power-domain-cells = <1>; + + power-domain@MT8183_POWER_DOMAIN_MFG_CORE0 { + reg = <MT8183_POWER_DOMAIN_MFG_CORE0>; + #power-domain-cells = <0>; + }; + + power-domain@MT8183_POWER_DOMAIN_MFG_CORE1 { + reg = <MT8183_POWER_DOMAIN_MFG_CORE1>; + #power-domain-cells = <0>; + }; + + power-domain@MT8183_POWER_DOMAIN_MFG_2D { + reg = <MT8183_POWER_DOMAIN_MFG_2D>; + mediatek,infracfg = <&infracfg>; + #power-domain-cells = <0>; + }; + }; + }; + + power-domain@MT8183_POWER_DOMAIN_DISP { + reg = <MT8183_POWER_DOMAIN_DISP>; + clocks = <&topckgen CLK_TOP_MUX_MM>, + <&mmsys CLK_MM_SMI_COMMON>, + <&mmsys CLK_MM_SMI_LARB0>, + <&mmsys CLK_MM_SMI_LARB1>, + <&mmsys CLK_MM_GALS_COMM0>, + <&mmsys CLK_MM_GALS_COMM1>, + <&mmsys CLK_MM_GALS_CCU2MM>, + <&mmsys CLK_MM_GALS_IPU12MM>, + <&mmsys CLK_MM_GALS_IMG2MM>, + <&mmsys CLK_MM_GALS_CAM2MM>, + <&mmsys CLK_MM_GALS_IPU2MM>; + clock-names = "mm", "mm-0", "mm-1", "mm-2", "mm-3", + "mm-4", "mm-5", "mm-6", "mm-7", + "mm-8", "mm-9"; + mediatek,infracfg = <&infracfg>; + mediatek,smi = <&smi_common>; + #address-cells = <1>; + #size-cells = <0>; + #power-domain-cells = <1>; + + power-domain@MT8183_POWER_DOMAIN_CAM { + reg = <MT8183_POWER_DOMAIN_CAM>; + clocks = <&topckgen CLK_TOP_MUX_CAM>, + <&camsys CLK_CAM_LARB6>, + <&camsys CLK_CAM_LARB3>, + <&camsys CLK_CAM_SENINF>, + <&camsys CLK_CAM_CAMSV0>, + <&camsys CLK_CAM_CAMSV1>, + <&camsys CLK_CAM_CAMSV2>, + <&camsys CLK_CAM_CCU>; + clock-names = "cam", "cam-0", "cam-1", + "cam-2", "cam-3", "cam-4", + "cam-5", "cam-6"; + mediatek,infracfg = <&infracfg>; + mediatek,smi = <&smi_common>; + #power-domain-cells = <0>; + }; + + power-domain@MT8183_POWER_DOMAIN_ISP { + reg = <MT8183_POWER_DOMAIN_ISP>; + clocks = <&topckgen CLK_TOP_MUX_IMG>, + <&imgsys CLK_IMG_LARB5>, + <&imgsys CLK_IMG_LARB2>; + clock-names = "isp", "isp-0", "isp-1"; + mediatek,infracfg = <&infracfg>; + mediatek,smi = <&smi_common>; + #power-domain-cells = <0>; + }; + + power-domain@MT8183_POWER_DOMAIN_VDEC { + reg = <MT8183_POWER_DOMAIN_VDEC>; + mediatek,smi = <&smi_common>; + #power-domain-cells = <0>; + }; + + power-domain@MT8183_POWER_DOMAIN_VENC { + reg = <MT8183_POWER_DOMAIN_VENC>; + mediatek,smi = <&smi_common>; + #power-domain-cells = <0>; + }; + + power-domain@MT8183_POWER_DOMAIN_VPU_TOP { + reg = <MT8183_POWER_DOMAIN_VPU_TOP>; + clocks = <&topckgen CLK_TOP_MUX_IPU_IF>, + <&topckgen CLK_TOP_MUX_DSP>, + <&ipu_conn CLK_IPU_CONN_IPU>, + <&ipu_conn CLK_IPU_CONN_AHB>, + <&ipu_conn CLK_IPU_CONN_AXI>, + <&ipu_conn CLK_IPU_CONN_ISP>, + <&ipu_conn CLK_IPU_CONN_CAM_ADL>, + <&ipu_conn CLK_IPU_CONN_IMG_ADL>; + clock-names = "vpu", "vpu1", "vpu-0", "vpu-1", + "vpu-2", "vpu-3", "vpu-4", "vpu-5"; + mediatek,infracfg = <&infracfg>; + mediatek,smi = <&smi_common>; + #address-cells = <1>; + #size-cells = <0>; + #power-domain-cells = <1>; + + power-domain@MT8183_POWER_DOMAIN_VPU_CORE0 { + reg = <MT8183_POWER_DOMAIN_VPU_CORE0>; + clocks = <&topckgen CLK_TOP_MUX_DSP1>; + clock-names = "vpu2"; + mediatek,infracfg = <&infracfg>; + #power-domain-cells = <0>; + }; + + power-domain@MT8183_POWER_DOMAIN_VPU_CORE1 { + reg = <MT8183_POWER_DOMAIN_VPU_CORE1>; + clocks = <&topckgen CLK_TOP_MUX_DSP2>; + clock-names = "vpu3"; + mediatek,infracfg = <&infracfg>; + #power-domain-cells = <0>; + }; + }; + }; + }; + }; + watchdog: watchdog@10007000 { compatible = "mediatek,mt8183-wdt"; reg = <0 0x10007000 0 0x100>; @@ -359,11 +528,20 @@ clock-names = "clk13m"; }; + iommu: iommu@10205000 { + compatible = "mediatek,mt8183-m4u"; + reg = <0 0x10205000 0 0x1000>; + interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_LOW>; + mediatek,larbs = <&larb0 &larb1 &larb2 &larb3 + &larb4 &larb5 &larb6>; + #iommu-cells = <1>; + }; + gce: mailbox@10238000 { compatible = "mediatek,mt8183-gce"; reg = <0 0x10238000 0 0x4000>; interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_LOW>; - #mbox-cells = <3>; + #mbox-cells = <2>; clocks = <&infracfg CLK_INFRA_GCE>; clock-names = "gce"; }; @@ -479,6 +657,16 @@ status = "disabled"; }; + pwm0: pwm@1100e000 { + compatible = "mediatek,mt8183-disp-pwm"; + reg = <0 0x1100e000 0 0x1000>; + interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_LOW>; + #pwm-cells = <2>; + clocks = <&topckgen CLK_TOP_MUX_DISP_PWM>, + <&infracfg CLK_INFRA_DISP_PWM>; + clock-names = "main", "mm"; + }; + i2c3: i2c@1100f000 { compatible = "mediatek,mt8183-i2c"; reg = <0 0x1100f000 0 0x1000>, @@ -720,10 +908,27 @@ status = "disabled"; }; + mipi_tx0: mipi-dphy@11e50000 { + compatible = "mediatek,mt8183-mipi-tx"; + reg = <0 0x11e50000 0 0x1000>; + clocks = <&apmixedsys CLK_APMIXED_MIPID0_26M>; + clock-names = "ref_clk"; + #clock-cells = <0>; + #phy-cells = <0>; + clock-output-names = "mipi_tx0_pll"; + nvmem-cells = <&mipi_tx_calibration>; + nvmem-cell-names = "calibration-data"; + }; + efuse: efuse@11f10000 { compatible = "mediatek,mt8183-efuse", "mediatek,efuse"; reg = <0 0x11f10000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + mipi_tx_calibration: calib@190 { + reg = <0x190 0xc>; + }; }; u3phy: usb-phy@11f40000 { @@ -765,24 +970,205 @@ #clock-cells = <1>; }; + ovl0: ovl@14008000 { + compatible = "mediatek,mt8183-disp-ovl"; + reg = <0 0x14008000 0 0x1000>; + interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_LOW>; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_DISP_OVL0>; + iommus = <&iommu M4U_PORT_DISP_OVL0>; + mediatek,larb = <&larb0>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x8000 0x1000>; + }; + + ovl_2l0: ovl@14009000 { + compatible = "mediatek,mt8183-disp-ovl-2l"; + reg = <0 0x14009000 0 0x1000>; + interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_LOW>; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_DISP_OVL0_2L>; + iommus = <&iommu M4U_PORT_DISP_2L_OVL0_LARB0>; + mediatek,larb = <&larb0>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x9000 0x1000>; + }; + + ovl_2l1: ovl@1400a000 { + compatible = "mediatek,mt8183-disp-ovl-2l"; + reg = <0 0x1400a000 0 0x1000>; + interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_LOW>; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_DISP_OVL1_2L>; + iommus = <&iommu M4U_PORT_DISP_2L_OVL1_LARB0>; + mediatek,larb = <&larb0>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xa000 0x1000>; + }; + + rdma0: rdma@1400b000 { + compatible = "mediatek,mt8183-disp-rdma"; + reg = <0 0x1400b000 0 0x1000>; + interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_DISP_RDMA0>; + iommus = <&iommu M4U_PORT_DISP_RDMA0>; + mediatek,larb = <&larb0>; + mediatek,rdma_fifo_size = <5120>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xb000 0x1000>; + }; + + rdma1: rdma@1400c000 { + compatible = "mediatek,mt8183-disp-rdma"; + reg = <0 0x1400c000 0 0x1000>; + interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_DISP_RDMA1>; + iommus = <&iommu M4U_PORT_DISP_RDMA1>; + mediatek,larb = <&larb0>; + mediatek,rdma_fifo_size = <2048>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xc000 0x1000>; + }; + + color0: color@1400e000 { + compatible = "mediatek,mt8183-disp-color", + "mediatek,mt8173-disp-color"; + reg = <0 0x1400e000 0 0x1000>; + interrupts = <GIC_SPI 231 IRQ_TYPE_LEVEL_LOW>; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_DISP_COLOR0>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xe000 0x1000>; + }; + + ccorr0: ccorr@1400f000 { + compatible = "mediatek,mt8183-disp-ccorr"; + reg = <0 0x1400f000 0 0x1000>; + interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_DISP_CCORR0>; + }; + + aal0: aal@14010000 { + compatible = "mediatek,mt8183-disp-aal", + "mediatek,mt8173-disp-aal"; + reg = <0 0x14010000 0 0x1000>; + interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_LOW>; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_DISP_AAL0>; + }; + + gamma0: gamma@14011000 { + compatible = "mediatek,mt8183-disp-gamma", + "mediatek,mt8173-disp-gamma"; + reg = <0 0x14011000 0 0x1000>; + interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_LOW>; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_DISP_GAMMA0>; + }; + + dither0: dither@14012000 { + compatible = "mediatek,mt8183-disp-dither"; + reg = <0 0x14012000 0 0x1000>; + interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_LOW>; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_DISP_DITHER0>; + }; + + dsi0: dsi@14014000 { + compatible = "mediatek,mt8183-dsi"; + reg = <0 0x14014000 0 0x1000>; + interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_LOW>; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + mediatek,syscon-dsi = <&mmsys 0x140>; + clocks = <&mmsys CLK_MM_DSI0_MM>, + <&mmsys CLK_MM_DSI0_IF>, + <&mipi_tx0>; + clock-names = "engine", "digital", "hs"; + phys = <&mipi_tx0>; + phy-names = "dphy"; + }; + + mutex: mutex@14016000 { + compatible = "mediatek,mt8183-disp-mutex"; + reg = <0 0x14016000 0 0x1000>; + interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_LOW>; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + }; + + larb0: larb@14017000 { + compatible = "mediatek,mt8183-smi-larb"; + reg = <0 0x14017000 0 0x1000>; + mediatek,smi = <&smi_common>; + clocks = <&mmsys CLK_MM_SMI_LARB0>, + <&mmsys CLK_MM_SMI_LARB0>; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clock-names = "apb", "smi"; + }; + + smi_common: smi@14019000 { + compatible = "mediatek,mt8183-smi-common", "syscon"; + reg = <0 0x14019000 0 0x1000>; + clocks = <&mmsys CLK_MM_SMI_COMMON>, + <&mmsys CLK_MM_SMI_COMMON>, + <&mmsys CLK_MM_GALS_COMM0>, + <&mmsys CLK_MM_GALS_COMM1>; + clock-names = "apb", "smi", "gals0", "gals1"; + }; + imgsys: syscon@15020000 { compatible = "mediatek,mt8183-imgsys", "syscon"; reg = <0 0x15020000 0 0x1000>; #clock-cells = <1>; }; + larb5: larb@15021000 { + compatible = "mediatek,mt8183-smi-larb"; + reg = <0 0x15021000 0 0x1000>; + mediatek,smi = <&smi_common>; + clocks = <&imgsys CLK_IMG_LARB5>, <&imgsys CLK_IMG_LARB5>, + <&mmsys CLK_MM_GALS_IMG2MM>; + clock-names = "apb", "smi", "gals"; + power-domains = <&spm MT8183_POWER_DOMAIN_ISP>; + }; + + larb2: larb@1502f000 { + compatible = "mediatek,mt8183-smi-larb"; + reg = <0 0x1502f000 0 0x1000>; + mediatek,smi = <&smi_common>; + clocks = <&imgsys CLK_IMG_LARB2>, <&imgsys CLK_IMG_LARB2>, + <&mmsys CLK_MM_GALS_IPU2MM>; + clock-names = "apb", "smi", "gals"; + power-domains = <&spm MT8183_POWER_DOMAIN_ISP>; + }; + vdecsys: syscon@16000000 { compatible = "mediatek,mt8183-vdecsys", "syscon"; reg = <0 0x16000000 0 0x1000>; #clock-cells = <1>; }; + larb1: larb@16010000 { + compatible = "mediatek,mt8183-smi-larb"; + reg = <0 0x16010000 0 0x1000>; + mediatek,smi = <&smi_common>; + clocks = <&vdecsys CLK_VDEC_VDEC>, <&vdecsys CLK_VDEC_LARB1>; + clock-names = "apb", "smi"; + power-domains = <&spm MT8183_POWER_DOMAIN_VDEC>; + }; + vencsys: syscon@17000000 { compatible = "mediatek,mt8183-vencsys", "syscon"; reg = <0 0x17000000 0 0x1000>; #clock-cells = <1>; }; + larb4: larb@17010000 { + compatible = "mediatek,mt8183-smi-larb"; + reg = <0 0x17010000 0 0x1000>; + mediatek,smi = <&smi_common>; + clocks = <&vencsys CLK_VENC_LARB>, + <&vencsys CLK_VENC_LARB>; + clock-names = "apb", "smi"; + power-domains = <&spm MT8183_POWER_DOMAIN_VENC>; + }; + ipu_conn: syscon@19000000 { compatible = "mediatek,mt8183-ipu_conn", "syscon"; reg = <0 0x19000000 0 0x1000>; @@ -812,5 +1198,25 @@ reg = <0 0x1a000000 0 0x1000>; #clock-cells = <1>; }; + + larb6: larb@1a001000 { + compatible = "mediatek,mt8183-smi-larb"; + reg = <0 0x1a001000 0 0x1000>; + mediatek,smi = <&smi_common>; + clocks = <&camsys CLK_CAM_LARB6>, <&camsys CLK_CAM_LARB6>, + <&mmsys CLK_MM_GALS_CAM2MM>; + clock-names = "apb", "smi", "gals"; + power-domains = <&spm MT8183_POWER_DOMAIN_CAM>; + }; + + larb3: larb@1a002000 { + compatible = "mediatek,mt8183-smi-larb"; + reg = <0 0x1a002000 0 0x1000>; + mediatek,smi = <&smi_common>; + clocks = <&camsys CLK_CAM_LARB3>, <&camsys CLK_CAM_LARB3>, + <&mmsys CLK_MM_GALS_IPU12MM>; + clock-names = "apb", "smi", "gals"; + power-domains = <&spm MT8183_POWER_DOMAIN_CAM>; + }; }; }; diff --git a/arch/arm64/boot/dts/mediatek/mt8192-evb.dts b/arch/arm64/boot/dts/mediatek/mt8192-evb.dts new file mode 100644 index 000000000000..0205837fa698 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8192-evb.dts @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2020 MediaTek Inc. + * Author: Seiya Wang <seiya.wang@mediatek.com> + */ +/dts-v1/; +#include "mt8192.dtsi" + +/ { + model = "MediaTek MT8192 evaluation board"; + compatible = "mediatek,mt8192-evb", "mediatek,mt8192"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:921600n8"; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 0 0x80000000>; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi new file mode 100644 index 000000000000..e12e024de122 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi @@ -0,0 +1,512 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2020 MediaTek Inc. + * Author: Seiya Wang <seiya.wang@mediatek.com> + */ + +/dts-v1/; +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/pinctrl/mt8192-pinfunc.h> + +/ { + compatible = "mediatek,mt8192"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + clk26m: oscillator0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + clock-output-names = "clk26m"; + }; + + clk32k: oscillator1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "clk32k"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x000>; + enable-method = "psci"; + clock-frequency = <1701000000>; + next-level-cache = <&l2_0>; + capacity-dmips-mhz = <530>; + }; + + cpu1: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x100>; + enable-method = "psci"; + clock-frequency = <1701000000>; + next-level-cache = <&l2_0>; + capacity-dmips-mhz = <530>; + }; + + cpu2: cpu@200 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x200>; + enable-method = "psci"; + clock-frequency = <1701000000>; + next-level-cache = <&l2_0>; + capacity-dmips-mhz = <530>; + }; + + cpu3: cpu@300 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x300>; + enable-method = "psci"; + clock-frequency = <1701000000>; + next-level-cache = <&l2_0>; + capacity-dmips-mhz = <530>; + }; + + cpu4: cpu@400 { + device_type = "cpu"; + compatible = "arm,cortex-a76"; + reg = <0x400>; + enable-method = "psci"; + clock-frequency = <2171000000>; + next-level-cache = <&l2_1>; + capacity-dmips-mhz = <1024>; + }; + + cpu5: cpu@500 { + device_type = "cpu"; + compatible = "arm,cortex-a76"; + reg = <0x500>; + enable-method = "psci"; + clock-frequency = <2171000000>; + next-level-cache = <&l2_1>; + capacity-dmips-mhz = <1024>; + }; + + cpu6: cpu@600 { + device_type = "cpu"; + compatible = "arm,cortex-a76"; + reg = <0x600>; + enable-method = "psci"; + clock-frequency = <2171000000>; + next-level-cache = <&l2_1>; + capacity-dmips-mhz = <1024>; + }; + + cpu7: cpu@700 { + device_type = "cpu"; + compatible = "arm,cortex-a76"; + reg = <0x700>; + enable-method = "psci"; + clock-frequency = <2171000000>; + next-level-cache = <&l2_1>; + capacity-dmips-mhz = <1024>; + }; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + core1 { + cpu = <&cpu1>; + }; + core2 { + cpu = <&cpu2>; + }; + core3 { + cpu = <&cpu3>; + }; + }; + + cluster1 { + core0 { + cpu = <&cpu4>; + }; + core1 { + cpu = <&cpu5>; + }; + core2 { + cpu = <&cpu6>; + }; + core3 { + cpu = <&cpu7>; + }; + }; + }; + + l2_0: l2-cache0 { + compatible = "cache"; + next-level-cache = <&l3_0>; + }; + + l2_1: l2-cache1 { + compatible = "cache"; + next-level-cache = <&l3_0>; + }; + + l3_0: l3-cache { + compatible = "cache"; + }; + }; + + pmu-a55 { + compatible = "arm,cortex-a55-pmu"; + interrupt-parent = <&gic>; + interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_cluster0>; + }; + + pmu-a76 { + compatible = "arm,cortex-a76-pmu"; + interrupt-parent = <&gic>; + interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_cluster1>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + timer: timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>; + clock-frequency = <13000000>; + }; + + soc { + #address-cells = <2>; + #size-cells = <2>; + compatible = "simple-bus"; + ranges; + + gic: interrupt-controller@c000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <4>; + #redistributor-regions = <1>; + interrupt-parent = <&gic>; + interrupt-controller; + reg = <0 0x0c000000 0 0x40000>, + <0 0x0c040000 0 0x200000>; + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>; + + ppi-partitions { + ppi_cluster0: interrupt-partition-0 { + affinity = <&cpu0 &cpu1 &cpu2 &cpu3>; + }; + ppi_cluster1: interrupt-partition-1 { + affinity = <&cpu4 &cpu5 &cpu6 &cpu7>; + }; + }; + }; + + pio: pinctrl@10005000 { + compatible = "mediatek,mt8192-pinctrl"; + reg = <0 0x10005000 0 0x1000>, + <0 0x11c20000 0 0x1000>, + <0 0x11d10000 0 0x1000>, + <0 0x11d30000 0 0x1000>, + <0 0x11d40000 0 0x1000>, + <0 0x11e20000 0 0x1000>, + <0 0x11e70000 0 0x1000>, + <0 0x11ea0000 0 0x1000>, + <0 0x11f20000 0 0x1000>, + <0 0x11f30000 0 0x1000>, + <0 0x1000b000 0 0x1000>; + reg-names = "iocfg0", "iocfg_rm", "iocfg_bm", + "iocfg_bl", "iocfg_br", "iocfg_lm", + "iocfg_lb", "iocfg_rt", "iocfg_lt", + "iocfg_tl", "eint"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pio 0 0 220>; + interrupt-controller; + interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH 0>; + #interrupt-cells = <2>; + }; + + systimer: timer@10017000 { + compatible = "mediatek,mt8192-timer", + "mediatek,mt6765-timer"; + reg = <0 0x10017000 0 0x1000>; + interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>; + clock-names = "clk13m"; + }; + + uart0: serial@11002000 { + compatible = "mediatek,mt8192-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11002000 0 0x1000>; + interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, <&clk26m>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart1: serial@11003000 { + compatible = "mediatek,mt8192-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11003000 0 0x1000>; + interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, <&clk26m>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + spi0: spi@1100a000 { + compatible = "mediatek,mt8192-spi", + "mediatek,mt6765-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x1100a000 0 0x1000>; + interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, + <&clk26m>, + <&clk26m>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + status = "disabled"; + }; + + spi1: spi@11010000 { + compatible = "mediatek,mt8192-spi", + "mediatek,mt6765-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x11010000 0 0x1000>; + interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, + <&clk26m>, + <&clk26m>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + status = "disabled"; + }; + + spi2: spi@11012000 { + compatible = "mediatek,mt8192-spi", + "mediatek,mt6765-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x11012000 0 0x1000>; + interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, + <&clk26m>, + <&clk26m>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + status = "disabled"; + }; + + spi3: spi@11013000 { + compatible = "mediatek,mt8192-spi", + "mediatek,mt6765-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x11013000 0 0x1000>; + interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, + <&clk26m>, + <&clk26m>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + status = "disabled"; + }; + + spi4: spi@11018000 { + compatible = "mediatek,mt8192-spi", + "mediatek,mt6765-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x11018000 0 0x1000>; + interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, + <&clk26m>, + <&clk26m>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + status = "disabled"; + }; + + spi5: spi@11019000 { + compatible = "mediatek,mt8192-spi", + "mediatek,mt6765-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x11019000 0 0x1000>; + interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, + <&clk26m>, + <&clk26m>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + status = "disabled"; + }; + + spi6: spi@1101d000 { + compatible = "mediatek,mt8192-spi", + "mediatek,mt6765-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x1101d000 0 0x1000>; + interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, + <&clk26m>, + <&clk26m>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + status = "disabled"; + }; + + spi7: spi@1101e000 { + compatible = "mediatek,mt8192-spi", + "mediatek,mt6765-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x1101e000 0 0x1000>; + interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, + <&clk26m>, + <&clk26m>; + clock-names = "parent-clk", "sel-clk", "spi-clk"; + status = "disabled"; + }; + + i2c3: i2c3@11cb0000 { + compatible = "mediatek,mt8192-i2c"; + reg = <0 0x11cb0000 0 0x1000>, + <0 0x10217300 0 0x80>; + interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, <&clk26m>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c7: i2c7@11d00000 { + compatible = "mediatek,mt8192-i2c"; + reg = <0 0x11d00000 0 0x1000>, + <0 0x10217600 0 0x180>; + interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, <&clk26m>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c8: i2c8@11d01000 { + compatible = "mediatek,mt8192-i2c"; + reg = <0 0x11d01000 0 0x1000>, + <0 0x10217780 0 0x180>; + interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, <&clk26m>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c9: i2c9@11d02000 { + compatible = "mediatek,mt8192-i2c"; + reg = <0 0x11d02000 0 0x1000>, + <0 0x10217900 0 0x180>; + interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, <&clk26m>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c1@11d20000 { + compatible = "mediatek,mt8192-i2c"; + reg = <0 0x11d20000 0 0x1000>, + <0 0x10217100 0 0x80>; + interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, <&clk26m>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c2@11d21000 { + compatible = "mediatek,mt8192-i2c"; + reg = <0 0x11d21000 0 0x1000>, + <0 0x10217180 0 0x180>; + interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, <&clk26m>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c4: i2c4@11d22000 { + compatible = "mediatek,mt8192-i2c"; + reg = <0 0x11d22000 0 0x1000>, + <0 0x10217380 0 0x180>; + interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, <&clk26m>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c5: i2c5@11e00000 { + compatible = "mediatek,mt8192-i2c"; + reg = <0 0x11e00000 0 0x1000>, + <0 0x10217500 0 0x80>; + interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, <&clk26m>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c0: i2c0@11f00000 { + compatible = "mediatek,mt8192-i2c"; + reg = <0 0x11f00000 0 0x1000>, + <0 0x10217080 0 0x80>; + interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, <&clk26m>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c6: i2c6@11f01000 { + compatible = "mediatek,mt8192-i2c"; + reg = <0 0x11f01000 0 0x1000>, + <0 0x10217580 0 0x80>; + interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&clk26m>, <&clk26m>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi index 89af661e7f63..e6e4d9d60094 100644 --- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi @@ -237,6 +237,13 @@ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; }; + efuse: efuse@10009000 { + compatible = "mediatek,mt8516-efuse", "mediatek,efuse"; + reg = <0 0x10009000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + }; + pwrap: pwrap@1000f000 { compatible = "mediatek,mt8516-pwrap"; reg = <0 0x1000f000 0 0x1000>; @@ -455,7 +462,21 @@ status = "disabled"; }; - usb0_phy: usb@11110000 { + usb1: usb@11190000 { + compatible = "mediatek,mtk-musb"; + reg = <0 0x11190000 0 0x1000>; + interrupts = <GIC_SPI 210 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "mc"; + phys = <&usb1_port PHY_TYPE_USB2>; + clocks = <&topckgen CLK_TOP_USB>, + <&topckgen CLK_TOP_USBIF>, + <&topckgen CLK_TOP_USB_1P>; + clock-names = "main","mcu","univpll"; + dr_mode = "host"; + status = "disabled"; + }; + + usb_phy: usb@11110000 { compatible = "mediatek,generic-tphy-v1"; reg = <0 0x11110000 0 0x800>; #address-cells = <2>; @@ -469,6 +490,23 @@ clock-names = "ref"; #phy-cells = <1>; }; + + usb1_port: usb-phy@11110900 { + reg = <0 0x11110900 0 0x100>; + clocks = <&topckgen CLK_TOP_USB_PHY48M>; + clock-names = "ref"; + #phy-cells = <1>; + }; + }; + + auxadc: adc@11003000 { + compatible = "mediatek,mt8516-auxadc", + "mediatek,mt8173-auxadc"; + reg = <0 0x11003000 0 0x1000>; + clocks = <&topckgen CLK_TOP_AUX_ADC>; + clock-names = "main"; + #io-channel-cells = <1>; + status = "disabled"; }; }; }; diff --git a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi index 29d8cf6df46b..63fd70086bb8 100644 --- a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi +++ b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi @@ -63,91 +63,91 @@ gpio-controller; #gpio-cells = <2>; - eint20_mux_sel0 { + eint20-mux-sel0-hog { gpio-hog; gpios = <0 0>; input; line-name = "eint20_mux_sel0"; }; - expcon_mux_sel1 { + expcon-mux-sel1-hog { gpio-hog; gpios = <1 0>; input; line-name = "expcon_mux_sel1"; }; - mrg_di_mux_sel2 { + mrg-di-mux-sel2-hog { gpio-hog; gpios = <2 0>; input; line-name = "mrg_di_mux_sel2"; }; - sd_sdio_mux_sel3 { + sd-sdio-mux-sel3-hog { gpio-hog; gpios = <3 0>; input; line-name = "sd_sdio_mux_sel3"; }; - sd_sdio_mux_ctrl7 { + sd-sdio-mux-ctrl7-hog { gpio-hog; gpios = <7 0>; output-low; line-name = "sd_sdio_mux_ctrl7"; }; - hw_id0 { + hw-id0-hog { gpio-hog; gpios = <8 0>; input; line-name = "hw_id0"; }; - hw_id1 { + hw-id1-hog { gpio-hog; gpios = <9 0>; input; line-name = "hw_id1"; }; - hw_id2 { + hw-id2-hog { gpio-hog; gpios = <10 0>; input; line-name = "hw_id2"; }; - fg_int_n { + fg-int-n-hog { gpio-hog; gpios = <11 0>; input; line-name = "fg_int_n"; }; - usba_pwr_en { + usba-pwr-en-hog { gpio-hog; gpios = <12 0>; output-high; line-name = "usba_pwr_en"; }; - wifi_3v3_pg { + wifi-3v3-pg-hog { gpio-hog; gpios = <13 0>; input; line-name = "wifi_3v3_pg"; }; - cam_rst { + cam-rst-hog { gpio-hog; gpios = <14 0>; output-low; line-name = "cam_rst"; }; - cam_pwdn { + cam-pwdn-hog { gpio-hog; gpios = <15 0>; output-low; @@ -195,7 +195,7 @@ }; }; -&usb0_phy { +&usb_phy { status = "okay"; }; diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi b/arch/arm64/boot/dts/microchip/sparx5.dtsi index 3cb01c39c3c8..d64621d1213b 100644 --- a/arch/arm64/boot/dts/microchip/sparx5.dtsi +++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi @@ -135,6 +135,11 @@ }; }; + reset@611010008 { + compatible = "microchip,sparx5-chip-reset"; + reg = <0x6 0x11010008 0x4>; + }; + uart0: serial@600100000 { pinctrl-0 = <&uart_pins>; pinctrl-names = "default"; @@ -226,6 +231,22 @@ function = "si2"; }; + sgpio0_pins: sgpio-pins { + pins = "GPIO_0", "GPIO_1", "GPIO_2", "GPIO_3"; + function = "sg0"; + }; + + sgpio1_pins: sgpio1-pins { + pins = "GPIO_4", "GPIO_5", "GPIO_12", "GPIO_13"; + function = "sg1"; + }; + + sgpio2_pins: sgpio2-pins { + pins = "GPIO_30", "GPIO_31", "GPIO_32", + "GPIO_33"; + function = "sg2"; + }; + uart_pins: uart-pins { pins = "GPIO_10", "GPIO_11"; function = "uart"; @@ -256,6 +277,81 @@ }; }; + sgpio0: gpio@61101036c { + #address-cells = <1>; + #size-cells = <0>; + compatible = "microchip,sparx5-sgpio"; + status = "disabled"; + clocks = <&sys_clk>; + pinctrl-0 = <&sgpio0_pins>; + pinctrl-names = "default"; + reg = <0x6 0x1101036c 0x100>; + sgpio_in0: gpio@0 { + compatible = "microchip,sparx5-sgpio-bank"; + reg = <0>; + gpio-controller; + #gpio-cells = <3>; + ngpios = <96>; + }; + sgpio_out0: gpio@1 { + compatible = "microchip,sparx5-sgpio-bank"; + reg = <1>; + gpio-controller; + #gpio-cells = <3>; + ngpios = <96>; + }; + }; + + sgpio1: gpio@611010484 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "microchip,sparx5-sgpio"; + status = "disabled"; + clocks = <&sys_clk>; + pinctrl-0 = <&sgpio1_pins>; + pinctrl-names = "default"; + reg = <0x6 0x11010484 0x100>; + sgpio_in1: gpio@0 { + compatible = "microchip,sparx5-sgpio-bank"; + reg = <0>; + gpio-controller; + #gpio-cells = <3>; + ngpios = <96>; + }; + sgpio_out1: gpio@1 { + compatible = "microchip,sparx5-sgpio-bank"; + reg = <1>; + gpio-controller; + #gpio-cells = <3>; + ngpios = <96>; + }; + }; + + sgpio2: gpio@61101059c { + #address-cells = <1>; + #size-cells = <0>; + compatible = "microchip,sparx5-sgpio"; + status = "disabled"; + clocks = <&sys_clk>; + pinctrl-0 = <&sgpio2_pins>; + pinctrl-names = "default"; + reg = <0x6 0x1101059c 0x100>; + sgpio_in2: gpio@0 { + reg = <0>; + compatible = "microchip,sparx5-sgpio-bank"; + gpio-controller; + #gpio-cells = <3>; + ngpios = <96>; + }; + sgpio_out2: gpio@1 { + compatible = "microchip,sparx5-sgpio-bank"; + reg = <1>; + gpio-controller; + #gpio-cells = <3>; + ngpios = <96>; + }; + }; + i2c0: i2c@600101000 { compatible = "snps,designware-i2c"; status = "disabled"; diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts b/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts index 6b2da7c7520c..9baa085d7861 100644 --- a/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts +++ b/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts @@ -69,6 +69,11 @@ }; }; +&sgpio0 { + status = "okay"; + microchip,sgpio-port-ranges = <0 23>; +}; + &i2c1 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi index f37b478d6534..f0c915160990 100644 --- a/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi +++ b/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi @@ -36,6 +36,264 @@ gpios = <&gpio 37 GPIO_ACTIVE_LOW>; priority = <200>; }; + + leds { + compatible = "gpio-leds"; + led@0 { + label = "twr0:green"; + gpios = <&sgpio_out0 8 0 GPIO_ACTIVE_LOW>; + }; + led@1 { + label = "twr0:yellow"; + gpios = <&sgpio_out0 8 1 GPIO_ACTIVE_LOW>; + }; + led@2 { + label = "twr1:green"; + gpios = <&sgpio_out0 9 0 GPIO_ACTIVE_LOW>; + }; + led@3 { + label = "twr1:yellow"; + gpios = <&sgpio_out0 9 1 GPIO_ACTIVE_LOW>; + }; + led@4 { + label = "twr2:green"; + gpios = <&sgpio_out0 10 0 GPIO_ACTIVE_LOW>; + }; + led@5 { + label = "twr2:yellow"; + gpios = <&sgpio_out0 10 1 GPIO_ACTIVE_LOW>; + }; + led@6 { + label = "twr3:green"; + gpios = <&sgpio_out0 11 0 GPIO_ACTIVE_LOW>; + }; + led@7 { + label = "twr3:yellow"; + gpios = <&sgpio_out0 11 1 GPIO_ACTIVE_LOW>; + }; + led@8 { + label = "eth12:green"; + gpios = <&sgpio_out0 12 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@9 { + label = "eth12:yellow"; + gpios = <&sgpio_out0 12 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@10 { + label = "eth13:green"; + gpios = <&sgpio_out0 13 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@11 { + label = "eth13:yellow"; + gpios = <&sgpio_out0 13 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@12 { + label = "eth14:green"; + gpios = <&sgpio_out0 14 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@13 { + label = "eth14:yellow"; + gpios = <&sgpio_out0 14 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@14 { + label = "eth15:green"; + gpios = <&sgpio_out0 15 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@15 { + label = "eth15:yellow"; + gpios = <&sgpio_out0 15 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@16 { + label = "eth48:green"; + gpios = <&sgpio_out1 16 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@17 { + label = "eth48:yellow"; + gpios = <&sgpio_out1 16 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@18 { + label = "eth49:green"; + gpios = <&sgpio_out1 17 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@19 { + label = "eth49:yellow"; + gpios = <&sgpio_out1 17 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@20 { + label = "eth50:green"; + gpios = <&sgpio_out1 18 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@21 { + label = "eth50:yellow"; + gpios = <&sgpio_out1 18 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@22 { + label = "eth51:green"; + gpios = <&sgpio_out1 19 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@23 { + label = "eth51:yellow"; + gpios = <&sgpio_out1 19 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@24 { + label = "eth52:green"; + gpios = <&sgpio_out1 20 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@25 { + label = "eth52:yellow"; + gpios = <&sgpio_out1 20 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@26 { + label = "eth53:green"; + gpios = <&sgpio_out1 21 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@27 { + label = "eth53:yellow"; + gpios = <&sgpio_out1 21 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@28 { + label = "eth54:green"; + gpios = <&sgpio_out1 22 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@29 { + label = "eth54:yellow"; + gpios = <&sgpio_out1 22 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@30 { + label = "eth55:green"; + gpios = <&sgpio_out1 23 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@31 { + label = "eth55:yellow"; + gpios = <&sgpio_out1 23 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@32 { + label = "eth56:green"; + gpios = <&sgpio_out1 24 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@33 { + label = "eth56:yellow"; + gpios = <&sgpio_out1 24 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@34 { + label = "eth57:green"; + gpios = <&sgpio_out1 25 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@35 { + label = "eth57:yellow"; + gpios = <&sgpio_out1 25 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@36 { + label = "eth58:green"; + gpios = <&sgpio_out1 26 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@37 { + label = "eth58:yellow"; + gpios = <&sgpio_out1 26 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@38 { + label = "eth59:green"; + gpios = <&sgpio_out1 27 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@39 { + label = "eth59:yellow"; + gpios = <&sgpio_out1 27 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@40 { + label = "eth60:green"; + gpios = <&sgpio_out1 28 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@41 { + label = "eth60:yellow"; + gpios = <&sgpio_out1 28 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@42 { + label = "eth61:green"; + gpios = <&sgpio_out1 29 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@43 { + label = "eth61:yellow"; + gpios = <&sgpio_out1 29 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@44 { + label = "eth62:green"; + gpios = <&sgpio_out1 30 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@45 { + label = "eth62:yellow"; + gpios = <&sgpio_out1 30 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@46 { + label = "eth63:green"; + gpios = <&sgpio_out1 31 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led@47 { + label = "eth63:yellow"; + gpios = <&sgpio_out1 31 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; +}; + +&sgpio0 { + status = "okay"; + microchip,sgpio-port-ranges = <8 15>; + gpio@0 { + ngpios = <64>; + }; + gpio@1 { + ngpios = <64>; + }; +}; + +&sgpio1 { + status = "okay"; + microchip,sgpio-port-ranges = <24 31>; + gpio@0 { + ngpios = <64>; + }; + gpio@1 { + ngpios = <64>; + }; }; &spi0 { diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi index b02b8c8ce44d..e28c6dd16377 100644 --- a/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi +++ b/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi @@ -20,6 +20,50 @@ gpios = <&gpio 37 GPIO_ACTIVE_LOW>; priority = <200>; }; + + leds { + compatible = "gpio-leds"; + led@0 { + label = "eth60:yellow"; + gpios = <&sgpio_out1 28 0 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + led@1 { + label = "eth60:green"; + gpios = <&sgpio_out1 28 1 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + led@2 { + label = "eth61:yellow"; + gpios = <&sgpio_out1 29 0 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + led@3 { + label = "eth61:green"; + gpios = <&sgpio_out1 29 1 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + led@4 { + label = "eth62:yellow"; + gpios = <&sgpio_out1 30 0 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + led@5 { + label = "eth62:green"; + gpios = <&sgpio_out1 30 1 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + led@6 { + label = "eth63:yellow"; + gpios = <&sgpio_out1 31 0 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + led@7 { + label = "eth63:green"; + gpios = <&sgpio_out1 31 1 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + }; }; &gpio { @@ -83,6 +127,17 @@ }; }; +&sgpio1 { + status = "okay"; + microchip,sgpio-port-ranges = <24 31>; + gpio@0 { + ngpios = <64>; + }; + gpio@1 { + ngpios = <64>; + }; +}; + &axi { i2c0_imux: i2c0-imux@0 { compatible = "i2c-mux-pinctrl"; diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi index e40281510c0c..9928a87f593a 100644 --- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi @@ -629,9 +629,9 @@ <&tegra_car TEGRA124_CLK_PLL_E>; clock-names = "sata", "sata-oob", "cml1", "pll_e"; resets = <&tegra_car 124>, - <&tegra_car 123>, - <&tegra_car 129>; - reset-names = "sata", "sata-oob", "sata-cold"; + <&tegra_car 129>, + <&tegra_car 123>; + reset-names = "sata", "sata-cold", "sata-oob"; status = "disabled"; }; @@ -865,7 +865,9 @@ 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>; + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "thermal", "edp"; clocks = <&tegra_car TEGRA124_CLK_TSENSOR>, <&tegra_car TEGRA124_CLK_SOC_THERM>; clock-names = "tsensor", "soctherm"; @@ -925,6 +927,11 @@ hysteresis = <1000>; type = "critical"; }; + mem_throttle_trip { + temperature = <99000>; + hysteresis = <1000>; + type = "hot"; + }; }; cooling-maps { @@ -975,6 +982,11 @@ hysteresis = <1000>; type = "critical"; }; + pllx_throttle_trip { + temperature = <99000>; + hysteresis = <1000>; + type = "hot"; + }; }; cooling-maps { diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts index c28d51cc5797..6fd2e0542c27 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts @@ -285,6 +285,10 @@ }; }; + sata@3507000 { + status = "okay"; + }; + gpio-keys { compatible = "gpio-keys"; diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 0c46ab7bbbf3..58c51965df47 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -685,6 +685,7 @@ reg = <0x0 0x03520000 0x0 0x1000>, <0x0 0x03540000 0x0 0x1000>; reg-names = "padctl", "ao"; + interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>; resets = <&bpmp TEGRA186_RESET_XUSB_PADCTL>; reset-names = "padctl"; @@ -845,7 +846,9 @@ #interrupt-cells = <3>; interrupt-controller; reg = <0x0 0x03881000 0x0 0x1000>, - <0x0 0x03882000 0x0 0x2000>; + <0x0 0x03882000 0x0 0x2000>, + <0x0 0x03884000 0x0 0x2000>, + <0x0 0x03886000 0x0 0x2000>; interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; interrupt-parent = <&gic>; @@ -1501,6 +1504,34 @@ }; }; + sata@3507000 { + compatible = "nvidia,tegra186-ahci"; + reg = <0x0 0x03507000 0x0 0x00002000>, /* AHCI */ + <0x0 0x03500000 0x0 0x00007000>, /* SATA */ + <0x0 0x03A90000 0x0 0x00010000>; /* SATA AUX */ + interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>; + + power-domains = <&bpmp TEGRA186_POWER_DOMAIN_SAX>; + interconnects = <&mc TEGRA186_MEMORY_CLIENT_SATAR &emc>, + <&mc TEGRA186_MEMORY_CLIENT_SATAW &emc>; + interconnect-names = "dma-mem", "write"; + iommus = <&smmu TEGRA186_SID_SATA>; + + clocks = <&bpmp TEGRA186_CLK_SATA>, + <&bpmp TEGRA186_CLK_SATA_OOB>; + clock-names = "sata", "sata-oob"; + assigned-clocks = <&bpmp TEGRA186_CLK_SATA>, + <&bpmp TEGRA186_CLK_SATA_OOB>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLLP_OUT0>, + <&bpmp TEGRA186_CLK_PLLP>; + assigned-clock-rates = <102000000>, + <204000000>; + resets = <&bpmp TEGRA186_RESET_SATA>, + <&bpmp TEGRA186_RESET_SATACOLD>; + reset-names = "sata", "sata-cold"; + status = "disabled"; + }; + bpmp: bpmp { compatible = "nvidia,tegra186-bpmp"; interconnects = <&mc TEGRA186_MEMORY_CLIENT_BPMPR &emc>, @@ -1534,7 +1565,7 @@ #address-cells = <1>; #size-cells = <0>; - cpu@0 { + denver_0: cpu@0 { compatible = "nvidia,tegra186-denver"; device_type = "cpu"; i-cache-size = <0x20000>; @@ -1547,7 +1578,7 @@ reg = <0x000>; }; - cpu@1 { + denver_1: cpu@1 { compatible = "nvidia,tegra186-denver"; device_type = "cpu"; i-cache-size = <0x20000>; @@ -1560,7 +1591,7 @@ reg = <0x001>; }; - cpu@2 { + ca57_0: cpu@2 { compatible = "arm,cortex-a57"; device_type = "cpu"; i-cache-size = <0xC000>; @@ -1573,7 +1604,7 @@ reg = <0x100>; }; - cpu@3 { + ca57_1: cpu@3 { compatible = "arm,cortex-a57"; device_type = "cpu"; i-cache-size = <0xC000>; @@ -1586,7 +1617,7 @@ reg = <0x101>; }; - cpu@4 { + ca57_2: cpu@4 { compatible = "arm,cortex-a57"; device_type = "cpu"; i-cache-size = <0xC000>; @@ -1599,7 +1630,7 @@ reg = <0x102>; }; - cpu@5 { + ca57_3: cpu@5 { compatible = "arm,cortex-a57"; device_type = "cpu"; i-cache-size = <0xC000>; @@ -1631,6 +1662,22 @@ }; }; + pmu_denver { + compatible = "nvidia,denver-pmu", "arm,armv8-pmuv3"; + interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&denver_0 &denver_1>; + }; + + pmu_a57 { + compatible = "arm,cortex-a57-pmu", "arm,armv8-pmuv3"; + interrupts = <GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 297 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&ca57_0 &ca57_1 &ca57_2 &ca57_3>; + }; + thermal-zones { a57 { polling-delay = <0>; diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi index 93438d2b9469..25f36d6118f8 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi @@ -378,7 +378,7 @@ nvidia,schmitt = <TEGRA_PIN_DISABLE>; nvidia,lpdr = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_DISABLE>; - nvidia,io-high-voltage = <TEGRA_PIN_ENABLE>; + nvidia,io-hv = <TEGRA_PIN_ENABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>; }; @@ -390,7 +390,7 @@ nvidia,schmitt = <TEGRA_PIN_DISABLE>; nvidia,lpdr = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>; - nvidia,io-high-voltage = <TEGRA_PIN_ENABLE>; + nvidia,io-hv = <TEGRA_PIN_ENABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>; }; @@ -782,13 +782,13 @@ reg = <0x3510000 0x10000>; interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>; clocks = <&bpmp TEGRA194_CLK_HDA>, - <&bpmp TEGRA194_CLK_HDA2CODEC_2X>, - <&bpmp TEGRA194_CLK_HDA2HDMICODEC>; - clock-names = "hda", "hda2codec_2x", "hda2hdmi"; + <&bpmp TEGRA194_CLK_HDA2HDMICODEC>, + <&bpmp TEGRA194_CLK_HDA2CODEC_2X>; + clock-names = "hda", "hda2hdmi", "hda2codec_2x"; resets = <&bpmp TEGRA194_RESET_HDA>, - <&bpmp TEGRA194_RESET_HDA2CODEC_2X>, - <&bpmp TEGRA194_RESET_HDA2HDMICODEC>; - reset-names = "hda", "hda2codec_2x", "hda2hdmi"; + <&bpmp TEGRA194_RESET_HDA2HDMICODEC>, + <&bpmp TEGRA194_RESET_HDA2CODEC_2X>; + reset-names = "hda", "hda2hdmi", "hda2codec_2x"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISP>; interconnects = <&mc TEGRA194_MEMORY_CLIENT_HDAR &emc>, <&mc TEGRA194_MEMORY_CLIENT_HDAW &emc>; @@ -801,6 +801,7 @@ reg = <0x03520000 0x1000>, <0x03540000 0x1000>; reg-names = "padctl", "ao"; + interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>; resets = <&bpmp TEGRA194_RESET_XUSB_PADCTL>; reset-names = "padctl"; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts index 4c9c2a054642..69102dcea8b0 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts @@ -119,7 +119,7 @@ aconnect@702c0000 { status = "okay"; - dma@702e2000 { + dma-controller@702e2000 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts b/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts index 859241db4b4d..6a877decffc1 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts @@ -629,7 +629,7 @@ aconnect@702c0000 { status = "okay"; - dma@702e2000 { + dma-controller@702e2000 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts index bd78378248a6..131c064d6991 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts @@ -1717,7 +1717,7 @@ aconnect@702c0000 { status = "okay"; - dma@702e2000 { + dma-controller@702e2000 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index d47c88950d38..4fbf8c15b0a1 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -979,9 +979,9 @@ <&tegra_car TEGRA210_CLK_SATA_OOB>; clock-names = "sata", "sata-oob"; resets = <&tegra_car 124>, - <&tegra_car 123>, - <&tegra_car 129>; - reset-names = "sata", "sata-oob", "sata-cold"; + <&tegra_car 129>, + <&tegra_car 123>; + reset-names = "sata", "sata-cold", "sata-oob"; status = "disabled"; }; @@ -1040,6 +1040,7 @@ padctl: padctl@7009f000 { compatible = "nvidia,tegra210-xusb-padctl"; reg = <0x0 0x7009f000 0x0 0x1000>; + interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; resets = <&tegra_car 142>; reset-names = "padctl"; @@ -1344,7 +1345,7 @@ ranges = <0x702c0000 0x0 0x702c0000 0x00040000>; status = "disabled"; - adma: dma@702e2000 { + adma: dma-controller@702e2000 { compatible = "nvidia,tegra210-adma"; reg = <0x702e2000 0x2000>; interrupt-parent = <&agic>; @@ -1724,6 +1725,7 @@ throttle_heavy: heavy { nvidia,priority = <100>; nvidia,cpu-throt-percent = <85>; + nvidia,gpu-throt-level = <TEGRA_SOCTHERM_THROT_LEVEL_HIGH>; #cooling-cells = <2>; }; @@ -1780,6 +1782,12 @@ type = "active"; }; + mem-hot-trip { + temperature = <100000>; + hysteresis = <1000>; + type = "hot"; + }; + mem-shutdown-trip { temperature = <103000>; hysteresis = <0>; @@ -1842,6 +1850,12 @@ hysteresis = <0>; type = "critical"; }; + + pllx-throttle-trip { + temperature = <100000>; + hysteresis = <1000>; + type = "hot"; + }; }; cooling-maps { diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index fb4631f898fd..5113fac80b7a 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -12,6 +12,7 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8992-bullhead-rev-101.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8992-msft-lumia-talkman.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8992-xiaomi-libra.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8994-angler-rev-101.dtb +dtb-$(CONFIG_ARCH_QCOM) += msm8994-msft-lumia-cityman.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8994-sony-xperia-kitakami-sumire.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8996-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8998-asus-novago-tp370ql.dtb @@ -26,6 +27,9 @@ dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r0.dtb dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r1.dtb dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r1-kb.dtb dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r1-lte.dtb +dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r3.dtb +dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r3-kb.dtb +dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-lazor-r3-lte.dtb dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-r1.dtb dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-r1-lte.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm630-sony-xperia-ganges-kirin.dtb @@ -41,5 +45,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm845-db845c.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm845-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm845-xiaomi-beryllium.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm850-lenovo-yoga-c630.dtb +dtb-$(CONFIG_ARCH_QCOM) += sm8150-hdk.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8150-mtp.dtb +dtb-$(CONFIG_ARCH_QCOM) += sm8250-hdk.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8250-mtp.dtb diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 3c7f97539390..3a9538e1ec97 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -417,11 +417,6 @@ vdd_l4_l5_l6-supply = <&pm8916_s4>; vdd_l7-supply = <&pm8916_s4>; - s1 { - regulator-min-microvolt = <375000>; - regulator-max-microvolt = <1562000>; - }; - s3 { regulator-min-microvolt = <375000>; regulator-max-microvolt = <1562000>; @@ -445,11 +440,6 @@ regulator-max-microvolt = <1200000>; }; - l3 { - regulator-min-microvolt = <375000>; - regulator-max-microvolt = <1525000>; - }; - l4 { regulator-min-microvolt = <1750000>; regulator-max-microvolt = <3337000>; diff --git a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts index e8eaa958c199..99cefe88f6f2 100644 --- a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts +++ b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts @@ -62,3 +62,19 @@ bias-pull-down; }; }; + +&qpic_bam { + status = "okay"; +}; + +&qpic_nand { + status = "okay"; + + nand@0 { + reg = <0>; + + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + nand-bus-width = <8>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi index 59e0cbfa2214..9fa5b028e4f3 100644 --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi @@ -156,8 +156,8 @@ no-map; }; - tz: tz@48500000 { - reg = <0x0 0x48500000 0x0 0x00200000>; + tz: memory@4a600000 { + reg = <0x0 0x4a600000 0x0 0x00400000>; no-map; }; @@ -167,7 +167,7 @@ }; q6_region: memory@4ab00000 { - reg = <0x0 0x4ab00000 0x0 0x02800000>; + reg = <0x0 0x4ab00000 0x0 0x05500000>; no-map; }; }; @@ -192,7 +192,7 @@ clock-names = "core"; }; - cryptobam: dma@704000 { + cryptobam: dma-controller@704000 { compatible = "qcom,bam-v1.7.0"; reg = <0x0 0x00704000 0x0 0x20000>; interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>; @@ -231,6 +231,17 @@ drive-strength = <8>; bias-pull-down; }; + + qpic_pins: qpic-pins { + pins = "gpio1", "gpio3", "gpio4", + "gpio5", "gpio6", "gpio7", + "gpio8", "gpio10", "gpio11", + "gpio12", "gpio13", "gpio14", + "gpio15", "gpio17"; + function = "qpic_pad"; + drive-strength = <8>; + bias-disable; + }; }; gcc: gcc@1800000 { @@ -252,7 +263,7 @@ reg = <0x0 0x01945000 0x0 0xe000>; }; - blsp_dma: dma@7884000 { + blsp_dma: dma-controller@7884000 { compatible = "qcom,bam-v1.7.0"; reg = <0x0 0x07884000 0x0 0x2b000>; interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>; @@ -332,6 +343,36 @@ status = "disabled"; }; + qpic_bam: dma-controller@7984000 { + compatible = "qcom,bam-v1.7.0"; + reg = <0x0 0x07984000 0x0 0x1a000>; + interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_QPIC_CLK>, + <&gcc GCC_QPIC_AHB_CLK>; + clock-names = "iface_clk", "bam_clk"; + #dma-cells = <1>; + qcom,ee = <0>; + status = "disabled"; + }; + + qpic_nand: nand@79b0000 { + compatible = "qcom,ipq6018-nand"; + reg = <0x0 0x079b0000 0x0 0x10000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&gcc GCC_QPIC_CLK>, + <&gcc GCC_QPIC_AHB_CLK>; + clock-names = "core", "aon"; + + dmas = <&qpic_bam 0>, + <&qpic_bam 1>, + <&qpic_bam 2>; + dma-names = "tx", "rx", "cmd"; + pinctrl-0 = <&qpic_pins>; + pinctrl-names = "default"; + status = "disabled"; + }; + intc: interrupt-controller@b000000 { compatible = "qcom,msm-qgic2"; interrupt-controller; diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index 829e37ac82f6..a32e5e79ab0b 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -276,7 +276,7 @@ status = "disabled"; }; - blsp_dma: dma@7884000 { + blsp_dma: dma-controller@7884000 { compatible = "qcom,bam-v1.7.0"; reg = <0x07884000 0x2b000>; interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>; @@ -372,7 +372,7 @@ status = "disabled"; }; - qpic_bam: dma@7984000 { + qpic_bam: dma-controller@7984000 { compatible = "qcom,bam-v1.7.0"; reg = <0x07984000 0x1a000>; interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts index b9d3c5d98dd0..1e893c0b6fbc 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts @@ -5,6 +5,8 @@ #include "msm8916-pm8916.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/leds/common.h> / { model = "Longcheer L8150"; @@ -50,6 +52,139 @@ linux,code = <KEY_VOLUMEUP>; }; }; + + reg_ctp: regulator-ctp { + compatible = "regulator-fixed"; + regulator-name = "ctp"; + + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + gpio = <&msmgpio 17 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&ctp_pwr_en_default>; + }; + + flash-led-controller { + compatible = "sgmicro,sgm3140"; + flash-gpios = <&msmgpio 31 GPIO_ACTIVE_HIGH>; + enable-gpios = <&msmgpio 32 GPIO_ACTIVE_HIGH>; + + pinctrl-names = "default"; + pinctrl-0 = <&camera_flash_default>; + + flash_led: led { + function = LED_FUNCTION_FLASH; + color = <LED_COLOR_ID_WHITE>; + flash-max-timeout-us = <250000>; + }; + }; +}; + +&blsp_i2c1 { + status = "okay"; + + led-controller@45 { + compatible = "awinic,aw2013"; + reg = <0x45>; + #address-cells = <1>; + #size-cells = <0>; + + vcc-supply = <&pm8916_l17>; + + led@0 { + reg = <0>; + led-max-microamp = <5000>; + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_RED>; + }; + + led@1 { + reg = <1>; + led-max-microamp = <5000>; + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_GREEN>; + }; + + led@2 { + reg = <2>; + led-max-microamp = <5000>; + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_BLUE>; + }; + }; +}; + +&blsp_i2c2 { + status = "okay"; + + accelerometer@10 { + compatible = "bosch,bmc150_accel"; + reg = <0x10>; + + vdd-supply = <&pm8916_l17>; + vddio-supply = <&pm8916_l6>; + + mount-matrix = "0", "1", "0", + "-1", "0", "0", + "0", "0", "1"; + }; + + magnetometer@12 { + compatible = "bosch,bmc150_magn"; + reg = <0x12>; + + vdd-supply = <&pm8916_l17>; + vddio-supply = <&pm8916_l6>; + }; + + gyroscope@68 { + compatible = "bosch,bmg160"; + reg = <0x68>; + + interrupt-parent = <&msmgpio>; + interrupts = <23 IRQ_TYPE_EDGE_RISING>; + + pinctrl-names = "default"; + pinctrl-0 = <&gyro_int_default>; + + vdd-supply = <&pm8916_l17>; + vddio-supply = <&pm8916_l6>; + }; +}; + +&blsp_i2c5 { + status = "okay"; + + rmi4@20 { + compatible = "syna,rmi4-i2c"; + reg = <0x20>; + #address-cells = <1>; + #size-cells = <0>; + + interrupt-parent = <&msmgpio>; + interrupts = <13 IRQ_TYPE_EDGE_FALLING>; + + vdd-supply = <®_ctp>; + vio-supply = <&pm8916_l6>; + + pinctrl-names = "default"; + pinctrl-0 = <&tp_int_default>; + + syna,startup-delay-ms = <10>; + + rmi4-f01@1 { + reg = <0x1>; + syna,nosleep-mode = <1>; // Allow sleeping + }; + + rmi4-f12@12 { + reg = <0x12>; + syna,sensor-type = <1>; // Touchscreen + }; + }; }; &blsp1_uart2 { @@ -61,6 +196,10 @@ linux,code = <KEY_VOLUMEDOWN>; }; +&pm8916_vib { + status = "okay"; +}; + &pronto { status = "okay"; }; @@ -98,11 +237,6 @@ vdd_l4_l5_l6-supply = <&pm8916_s4>; vdd_l7-supply = <&pm8916_s4>; - s1 { - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1300000>; - }; - s3 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1300000>; @@ -123,11 +257,6 @@ regulator-max-microvolt = <1200000>; }; - l3 { - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1287500>; - }; - l4 { regulator-min-microvolt = <2050000>; regulator-max-microvolt = <2050000>; @@ -207,6 +336,22 @@ }; &msmgpio { + camera_flash_default: camera-flash-default { + pins = "gpio31", "gpio32"; + function = "gpio"; + + drive-strength = <2>; + bias-disable; + }; + + ctp_pwr_en_default: ctp-pwr-en-default { + pins = "gpio17"; + function = "gpio"; + + drive-strength = <2>; + bias-disable; + }; + gpio_keys_default: gpio-keys-default { pins = "gpio107"; function = "gpio"; @@ -215,6 +360,22 @@ bias-pull-up; }; + gyro_int_default: gyro-int-default { + pins = "gpio23"; + function = "gpio"; + + drive-strength = <2>; + bias-disable; + }; + + tp_int_default: tp-int-default { + pins = "gpio13"; + function = "gpio"; + + drive-strength = <2>; + bias-disable; + }; + usb_vbus_default: usb-vbus-default { pins = "gpio62"; function = "gpio"; diff --git a/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi index cd626e7db599..539823b2c36e 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi @@ -17,13 +17,10 @@ }; &mpss { - cx-supply = <&pm8916_s1>; - mx-supply = <&pm8916_l3>; pll-supply = <&pm8916_l7>; }; &pronto { - vddmx-supply = <&pm8916_l3>; vddpx-supply = <&pm8916_l7>; iris { @@ -53,13 +50,13 @@ smd_rpm_regulators: pm8916-regulators { compatible = "qcom,rpm-pm8916-regulators"; - pm8916_s1: s1 {}; + /* pm8916_s1 is managed by rpmpd (MSM8916_VDDCX) */ pm8916_s3: s3 {}; pm8916_s4: s4 {}; pm8916_l1: l1 {}; pm8916_l2: l2 {}; - pm8916_l3: l3 {}; + /* pm8916_l3 is managed by rpmpd (MSM8916_VDDMX) */ pm8916_l4: l4 {}; pm8916_l5: l5 {}; pm8916_l6: l6 {}; diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi index b18d21e42f59..f91269492d72 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi @@ -78,6 +78,9 @@ sda-gpios = <&msmgpio 105 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; scl-gpios = <&msmgpio 106 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>; + pinctrl-names = "default"; + pinctrl-0 = <&muic_i2c_default>; + #address-cells = <1>; #size-cells = <0>; @@ -164,11 +167,6 @@ vdd_l4_l5_l6-supply = <&pm8916_s4>; vdd_l7-supply = <&pm8916_s4>; - s1 { - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1300000>; - }; - s3 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1300000>; @@ -189,11 +187,6 @@ regulator-max-microvolt = <1200000>; }; - l3 { - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1287500>; - }; - l4 { regulator-min-microvolt = <2050000>; regulator-max-microvolt = <2050000>; @@ -314,6 +307,14 @@ }; }; + muic_i2c_default: muic-i2c-default { + pins = "gpio105", "gpio106"; + function = "gpio"; + + drive-strength = <2>; + bias-disable; + }; + muic_int_default: muic-int-default { pins = "gpio12"; function = "gpio"; diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts index 086f07ead5cb..661f41ad978b 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts @@ -28,6 +28,27 @@ "0", "0", "1"; }; +&blsp_i2c5 { + status = "okay"; + + touchscreen@20 { + compatible = "zinitix,bt541"; + + reg = <0x20>; + interrupt-parent = <&msmgpio>; + interrupts = <13 IRQ_TYPE_EDGE_FALLING>; + + touchscreen-size-x = <540>; + touchscreen-size-y = <960>; + + vdd-supply = <®_vdd_tsp>; + vddo-supply = <&pm8916_l6>; + + pinctrl-names = "default"; + pinctrl-0 = <&ts_int_default>; + }; +}; + &dsi0 { panel@0 { reg = <0>; @@ -59,4 +80,12 @@ drive-strength = <2>; bias-disable; }; + + ts_int_default: ts-int-default { + pins = "gpio13"; + function = "gpio"; + + drive-strength = <2>; + bias-disable; + }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index aaa21899f1a6..402e891a84ab 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -8,6 +8,7 @@ #include <dt-bindings/clock/qcom,rpmcc.h> #include <dt-bindings/interconnect/qcom,msm8916.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/reset/qcom,gcc-msm8916.h> #include <dt-bindings/thermal/thermal.h> @@ -289,6 +290,35 @@ compatible = "qcom,rpmcc-msm8916"; #clock-cells = <1>; }; + + rpmpd: power-controller { + compatible = "qcom,msm8916-rpmpd"; + #power-domain-cells = <1>; + operating-points-v2 = <&rpmpd_opp_table>; + + rpmpd_opp_table: opp-table { + compatible = "operating-points-v2"; + + rpmpd_opp_ret: opp1 { + opp-level = <1>; + }; + rpmpd_opp_svs_krait: opp2 { + opp-level = <2>; + }; + rpmpd_opp_svs_soc: opp3 { + opp-level = <3>; + }; + rpmpd_opp_nom: opp4 { + opp-level = <4>; + }; + rpmpd_opp_turbo: opp5 { + opp-level = <5>; + }; + rpmpd_opp_super_turbo: opp6 { + opp-level = <6>; + }; + }; + }; }; }; }; @@ -1263,6 +1293,10 @@ interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack"; + power-domains = <&rpmpd MSM8916_VDDCX>, + <&rpmpd MSM8916_VDDMX>; + power-domain-names = "cx", "mx"; + clocks = <&gcc GCC_MSS_CFG_AHB_CLK>, <&gcc GCC_MSS_Q6_BIMC_AXI_CLK>, <&gcc GCC_BOOT_ROM_AHB_CLK>, @@ -1391,7 +1425,7 @@ status = "disabled"; }; - blsp_dma: dma@7884000 { + blsp_dma: dma-controller@7884000 { compatible = "qcom,bam-v1.7.0"; reg = <0x07884000 0x23000>; interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>; @@ -1660,6 +1694,10 @@ <&wcnss_smp2p_in 3 IRQ_TYPE_EDGE_RISING>; interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack"; + power-domains = <&rpmpd MSM8916_VDDCX>, + <&rpmpd MSM8916_VDDMX>; + power-domain-names = "cx", "mx"; + qcom,state = <&wcnss_smp2p_out 0>; qcom,state-names = "stop"; diff --git a/arch/arm64/boot/dts/qcom/msm8992-msft-lumia-talkman.dts b/arch/arm64/boot/dts/qcom/msm8992-msft-lumia-talkman.dts index 3cc01f02219d..c337a86a5c77 100644 --- a/arch/arm64/boot/dts/qcom/msm8992-msft-lumia-talkman.dts +++ b/arch/arm64/boot/dts/qcom/msm8992-msft-lumia-talkman.dts @@ -32,6 +32,34 @@ }; }; +&blsp_i2c1 { + status = "okay"; + + rmi4-i2c-dev@4b { + compatible = "syna,rmi4-i2c"; + reg = <0x4b>; + #address-cells = <1>; + #size-cells = <0>; + + interrupt-parent = <&tlmm>; + interrupts = <77 IRQ_TYPE_EDGE_FALLING>; + + rmi4-f01@1 { + reg = <0x01>; + syna,nosleep-mode = <1>; + }; + + rmi4-f12@12 { + reg = <0x12>; + syna,sensor-type = <1>; + syna,clip-x-low = <0>; + syna,clip-x-high = <1440>; + syna,clip-y-low = <0>; + syna,clip-y-high = <2560>; + }; + }; +}; + &sdhc_1 { status = "okay"; diff --git a/arch/arm64/boot/dts/qcom/msm8992.dtsi b/arch/arm64/boot/dts/qcom/msm8992.dtsi index 8626b3a50eda..0c422af47917 100644 --- a/arch/arm64/boot/dts/qcom/msm8992.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8992.dtsi @@ -242,6 +242,37 @@ }; }; + usb3: usb@f92f8800 { + compatible = "qcom,msm8996-dwc3", "qcom,dwc3"; + reg = <0xf92f8800 0x400>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = <&gcc GCC_USB30_MASTER_CLK>, + <&gcc GCC_SYS_NOC_USB3_AXI_CLK>, + <&gcc GCC_USB30_SLEEP_CLK>, + <&gcc GCC_USB30_MOCK_UTMI_CLK>; + clock-names = "core", "iface", "sleep", "mock_utmi", "ref", "xo"; + + assigned-clocks = <&gcc GCC_USB30_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_MASTER_CLK>; + assigned-clock-rates = <19200000>, <120000000>; + + power-domains = <&gcc USB30_GDSC>; + qcom,select-utmi-as-pipe-clk; + + dwc3@f9200000 { + compatible = "snps,dwc3"; + reg = <0xf9200000 0xcc00>; + interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + maximum-speed = "high-speed"; + dr_mode = "peripheral"; + }; + }; + sdhc_1: sdhci@f9824900 { compatible = "qcom,sdhci-msm-v4"; reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>; @@ -269,6 +300,29 @@ status = "disabled"; }; + sdhc_2: sdhci@f98a4900 { + compatible = "qcom,sdhci-msm-v4"; + reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hc_irq", "pwr_irq"; + + clocks = <&gcc GCC_SDCC2_APPS_CLK>, + <&gcc GCC_SDCC2_AHB_CLK>, + <&xo_board>; + clock-names = "core", "iface", "xo"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>; + + cd-gpios = <&tlmm 100 0>; + bus-width = <4>; + status = "disabled"; + }; + blsp1_uart2: serial@f991e000 { compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; reg = <0xf991e000 0x1000>; @@ -282,6 +336,22 @@ status = "disabled"; }; + blsp_i2c1: i2c@f9923000 { + compatible = "qcom,i2c-qup-v2.2.1"; + reg = <0xf9923000 0x500>; + interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_AHB_CLK>, + <&gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>; + clock-names = "iface", "core"; + clock-frequency = <400000>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c1_default>; + pinctrl-1 = <&i2c1_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + blsp_i2c2: i2c@f9924000 { compatible = "qcom,i2c-qup-v2.2.1"; reg = <0xf9924000 0x500>; @@ -502,6 +572,20 @@ bias-pull-down; }; + i2c1_default: i2c1-default { + function = "blsp_i2c1"; + pins = "gpio2", "gpio3"; + drive-strength = <2>; + bias-disable; + }; + + i2c1_sleep: i2c1-sleep { + function = "gpio"; + pins = "gpio2", "gpio3"; + drive-strength = <2>; + bias-disable; + }; + i2c2_default: i2c2-default { function = "blsp_i2c2"; pins = "gpio6", "gpio7"; @@ -573,6 +657,42 @@ drive-strength = <2>; bias-disable; }; + + sdc2_clk_on: sdc2-clk-on { + pins = "sdc2_clk"; + bias-disable; + drive-strength = <16>; + }; + + sdc2_clk_off: sdc2-clk-off { + pins = "sdc2_clk"; + bias-disable; + drive-strength = <2>; + }; + + sdc2_cmd_on: sdc2-cmd-on { + pins = "sdc2_cmd"; + bias-pull-up; + drive-strength = <10>; + }; + + sdc2_cmd_off: sdc2-cmd-off { + pins = "sdc2_cmd"; + bias-pull-up; + drive-strength = <2>; + }; + + sdc2_data_on: sdc2-data-on { + pins = "sdc2_data"; + bias-pull-up; + drive-strength = <10>; + }; + + sdc2_data_off: sdc2-data-off { + pins = "sdc2_data"; + bias-pull-up; + drive-strength = <2>; + }; }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-cityman.dts b/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-cityman.dts new file mode 100644 index 000000000000..ed9034b96013 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-cityman.dts @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2020, Konrad Dybcio + */ + +/dts-v1/; + +#include "msm8994.dtsi" +#include "pm8994.dtsi" +#include "pmi8994.dtsi" + +/ { + model = "Microsoft Lumia 950 XL"; + compatible = "microsoft,cityman", "qcom,msm8994"; + + /* + * Most Lumia 950XL users use GRUB to load their kernels, + * hence there is no need for msm-id and friends. + */ + + /* + * This enables graphical output via bootloader-enabled display. + * acpi=no is required due to WP platforms having ACPI support, but + * only for Windows-based OSes. + */ + chosen { + bootargs = "earlycon=efifb console=efifb acpi=no"; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + }; +}; + +&blsp_i2c1 { + status = "okay"; + + rmi4-i2c-dev@4b { + compatible = "syna,rmi4-i2c"; + reg = <0x4b>; + #address-cells = <1>; + #size-cells = <0>; + + interrupt-parent = <&tlmm>; + interrupts = <77 IRQ_TYPE_EDGE_FALLING>; + + rmi4-f01@1 { + reg = <0x01>; + syna,nosleep-mode = <1>; + }; + + rmi4-f12@12 { + reg = <0x12>; + syna,sensor-type = <1>; + syna,clip-x-low = <0>; + syna,clip-x-high = <1440>; + syna,clip-y-low = <0>; + syna,clip-y-high = <2660>; + }; + }; +}; + +&blsp1_uart2 { + status = "okay"; +}; + +&blsp2_uart2 { + status = "okay"; +}; + +&sdhc1 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi index 6707f898607f..6e083a2f690b 100644 --- a/arch/arm64/boot/dts/qcom/msm8994.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi @@ -282,6 +282,37 @@ }; }; + usb3: usb@f92f8800 { + compatible = "qcom,msm8996-dwc3", "qcom,dwc3"; + reg = <0xf92f8800 0x400>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = <&gcc GCC_USB30_MASTER_CLK>, + <&gcc GCC_SYS_NOC_USB3_AXI_CLK>, + <&gcc GCC_USB30_SLEEP_CLK>, + <&gcc GCC_USB30_MOCK_UTMI_CLK>; + clock-names = "core", "iface", "sleep", "mock_utmi", "ref", "xo"; + + assigned-clocks = <&gcc GCC_USB30_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_MASTER_CLK>; + assigned-clock-rates = <19200000>, <120000000>; + + power-domains = <&gcc USB30_GDSC>; + qcom,select-utmi-as-pipe-clk; + + dwc3@f9200000 { + compatible = "snps,dwc3"; + reg = <0xf9200000 0xcc00>; + interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + maximum-speed = "high-speed"; + dr_mode = "peripheral"; + }; + }; + sdhc1: sdhci@f9824900 { compatible = "qcom,sdhci-msm-v4"; reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>; @@ -305,7 +336,30 @@ status = "disabled"; }; - blsp1_dma: dma@f9904000 { + sdhc2: sdhci@f98a4900 { + compatible = "qcom,sdhci-msm-v4"; + reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hc_irq", "pwr_irq"; + + clocks = <&gcc GCC_SDCC2_APPS_CLK>, + <&gcc GCC_SDCC2_AHB_CLK>, + <&xo_board>; + clock-names = "core", "iface", "xo"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>; + + cd-gpios = <&tlmm 100 0>; + bus-width = <4>; + status = "disabled"; + }; + + blsp1_dma: dma-controller@f9904000 { compatible = "qcom,bam-v1.7.0"; reg = <0xf9904000 0x19000>; interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>; @@ -401,7 +455,7 @@ status = "disabled"; }; - blsp2_dma: dma@f9944000 { + blsp2_dma: dma-controller@f9944000 { compatible = "qcom,bam-v1.7.0"; reg = <0xf9944000 0x19000>; interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>; @@ -683,6 +737,42 @@ pins = "sdc1_rclk"; bias-pull-down; }; + + sdc2_clk_on: sdc2-clk-on { + pins = "sdc2_clk"; + bias-disable; + drive-strength = <10>; + }; + + sdc2_clk_off: sdc2-clk-off { + pins = "sdc2_clk"; + bias-disable; + drive-strength = <2>; + }; + + sdc2_cmd_on: sdc2-cmd-on { + pins = "sdc2_cmd"; + bias-pull-up; + drive-strength = <10>; + }; + + sdc2_cmd_off: sdc2-cmd-off { + pins = "sdc2_cmd"; + bias-pull-up; + drive-strength = <2>; + }; + + sdc2_data_on: sdc2-data-on { + pins = "sdc2_data"; + bias-pull-up; + drive-strength = <10>; + }; + + sdc2_data_off: sdc2-data-off { + pins = "sdc2_data"; + bias-pull-up; + drive-strength = <2>; + }; }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index fd6ae5464dea..7eef07e73e25 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -1990,7 +1990,7 @@ }; }; - slimbam: dma@9184000 { + slimbam: dma-controller@9184000 { compatible = "qcom,bam-v1.7.0"; qcom,controlled-remotely; reg = <0x09184000 0x32000>; diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi index c45870600909..ebdaaf1dfca4 100644 --- a/arch/arm64/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi @@ -1754,7 +1754,7 @@ status = "disabled"; }; - blsp1_dma: dma@c144000 { + blsp1_dma: dma-controller@c144000 { compatible = "qcom,bam-v1.7.0"; reg = <0x0c144000 0x25000>; interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm64/boot/dts/qcom/pm6150.dtsi b/arch/arm64/boot/dts/qcom/pm6150.dtsi index 57af0b4a384d..8ab4f1f78bbf 100644 --- a/arch/arm64/boot/dts/qcom/pm6150.dtsi +++ b/arch/arm64/boot/dts/qcom/pm6150.dtsi @@ -52,6 +52,16 @@ }; }; + pm6150_adc_tm: adc-tm@3500 { + compatible = "qcom,spmi-adc-tm5"; + reg = <0x3500>; + interrupts = <0x0 0x35 0x0 IRQ_TYPE_EDGE_RISING>; + #thermal-sensor-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + pm6150_gpio: gpios@c000 { compatible = "qcom,pm6150-gpio", "qcom,spmi-gpio"; reg = <0xc000>; diff --git a/arch/arm64/boot/dts/qcom/pm6150l.dtsi b/arch/arm64/boot/dts/qcom/pm6150l.dtsi index f84027b505d1..b49860cd1387 100644 --- a/arch/arm64/boot/dts/qcom/pm6150l.dtsi +++ b/arch/arm64/boot/dts/qcom/pm6150l.dtsi @@ -11,6 +11,30 @@ #address-cells = <1>; #size-cells = <0>; + pm6150l_adc: adc@3100 { + compatible = "qcom,spmi-adc5"; + reg = <0x3100>; + interrupts = <0x4 0x31 0x0 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + + adc-chan@6 { + reg = <ADC5_DIE_TEMP>; + label = "die_temp"; + }; + }; + + pm6150l_adc_tm: adc-tm@3500 { + compatible = "qcom,spmi-adc-tm5"; + reg = <0x3500>; + interrupts = <0x4 0x35 0x0 IRQ_TYPE_EDGE_RISING>; + #thermal-sensor-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + pm6150l_gpio: gpios@c000 { compatible = "qcom,pm6150l-gpio", "qcom,spmi-gpio"; reg = <0xc000>; diff --git a/arch/arm64/boot/dts/qcom/pm8150.dtsi b/arch/arm64/boot/dts/qcom/pm8150.dtsi index 1b6406927509..a53eccf2b695 100644 --- a/arch/arm64/boot/dts/qcom/pm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8150.dtsi @@ -97,7 +97,7 @@ }; }; - rtc@6000 { + pm8150_rtc: rtc@6000 { compatible = "qcom,pm8941-rtc"; reg = <0x6000>; reg-names = "rtc", "alarm"; diff --git a/arch/arm64/boot/dts/qcom/pm8994.dtsi b/arch/arm64/boot/dts/qcom/pm8994.dtsi index 7e4f777746cb..5ffdf37d8e31 100644 --- a/arch/arm64/boot/dts/qcom/pm8994.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8994.dtsi @@ -1,7 +1,32 @@ // SPDX-License-Identifier: GPL-2.0 +#include <dt-bindings/iio/qcom,spmi-vadc.h> +#include <dt-bindings/input/linux-event-codes.h> #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/spmi/spmi.h> -#include <dt-bindings/input/linux-event-codes.h> + +/ { + thermal-zones { + pm8994 { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&pm8994_temp>; + + trips { + pm8994_alert0: pm8994-alert0 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + pm8994_crit: pm8994-crit { + temperature = <125000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + }; +}; &spmi_bus { @@ -35,33 +60,56 @@ }; + pm8994_temp: temp-alarm@2400 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0x2400>; + interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_RISING>; + io-channels = <&pm8994_vadc VADC_DIE_TEMP>; + io-channel-names = "thermal"; + #thermal-sensor-cells = <0>; + }; + + pm8994_vadc: adc@3100 { + compatible = "qcom,spmi-vadc"; + reg = <0x3100>; + interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + + adc-chan@7 { + reg = <VADC_VSYS>; + qcom,pre-scaling = <1 3>; + label = "vph_pwr"; + }; + adc-chan@8 { + reg = <VADC_DIE_TEMP>; + label = "die_temp"; + }; + adc-chan@9 { + reg = <VADC_REF_625MV>; + label = "ref_625mv"; + }; + adc-chan@a { + reg = <VADC_REF_1250MV>; + label = "ref_1250mv"; + }; + adc-chan@e { + reg = <VADC_GND_REF>; + }; + adc-chan@f { + reg = <VADC_VDD_VADC>; + }; + }; + pm8994_gpios: gpios@c000 { - compatible = "qcom,pm8994-gpio"; + compatible = "qcom,pm8994-gpio", "qcom,spmi-gpio"; reg = <0xc000>; gpio-controller; + gpio-ranges = <&pm8994_gpios 0 0 22>; #gpio-cells = <2>; - interrupts = <0 0xc0 0 IRQ_TYPE_NONE>, - <0 0xc1 0 IRQ_TYPE_NONE>, - <0 0xc2 0 IRQ_TYPE_NONE>, - <0 0xc3 0 IRQ_TYPE_NONE>, - <0 0xc4 0 IRQ_TYPE_NONE>, - <0 0xc5 0 IRQ_TYPE_NONE>, - <0 0xc6 0 IRQ_TYPE_NONE>, - <0 0xc7 0 IRQ_TYPE_NONE>, - <0 0xc8 0 IRQ_TYPE_NONE>, - <0 0xc9 0 IRQ_TYPE_NONE>, - <0 0xca 0 IRQ_TYPE_NONE>, - <0 0xcb 0 IRQ_TYPE_NONE>, - <0 0xcc 0 IRQ_TYPE_NONE>, - <0 0xcd 0 IRQ_TYPE_NONE>, - <0 0xce 0 IRQ_TYPE_NONE>, - <0 0xcf 0 IRQ_TYPE_NONE>, - <0 0xd0 0 IRQ_TYPE_NONE>, - <0 0xd1 0 IRQ_TYPE_NONE>, - <0 0xd2 0 IRQ_TYPE_NONE>, - <0 0xd3 0 IRQ_TYPE_NONE>, - <0 0xd4 0 IRQ_TYPE_NONE>, - <0 0xd5 0 IRQ_TYPE_NONE>; + interrupt-controller; + #interrupt-cells = <2>; }; pm8994_mpps: mpps@a000 { diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi index b654b802e95c..339790ba585d 100644 --- a/arch/arm64/boot/dts/qcom/qcs404.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi @@ -801,7 +801,7 @@ status = "disabled"; }; - blsp1_dma: dma@7884000 { + blsp1_dma: dma-controller@7884000 { compatible = "qcom,bam-v1.7.0"; reg = <0x07884000 0x25000>; interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>; @@ -1045,7 +1045,7 @@ status = "disabled"; }; - blsp2_dma: dma@7ac4000 { + blsp2_dma: dma-controller@7ac4000 { compatible = "qcom,bam-v1.7.0"; reg = <0x07ac4000 0x17000>; interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts index 1528a865f1f8..ce22d4fa383e 100644 --- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts @@ -18,12 +18,20 @@ aliases { serial0 = &uart12; + sdhc2 = &sdhc_2; }; chosen { stdout-path = "serial0:115200n8"; }; + /* Fixed crystal oscillator dedicated to MCP2518FD */ + clk40M: can_clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <40000000>; + }; + dc12v: dc12v-regulator { compatible = "regulator-fixed"; regulator-name = "DC12V"; @@ -459,6 +467,10 @@ "PM3003A_MODE"; }; +&pm8150_rtc { + status = "okay"; +}; + &qupv3_id_0 { status = "okay"; }; @@ -471,9 +483,33 @@ status = "okay"; }; +&sdhc_2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&sdc2_default_state &sdc2_card_det_n>; + vmmc-supply = <&vreg_l9c_2p96>; + vqmmc-supply = <&vreg_l6c_2p96>; + cd-gpios = <&tlmm 77 GPIO_ACTIVE_LOW>; + bus-width = <4>; + /* there seem to be issues with HS400-1.8V mode, so disable it */ + no-1-8-v; + no-sdio; + no-emmc; +}; + /* CAN */ &spi0 { status = "okay"; + + can@0 { + compatible = "microchip,mcp2518fd"; + reg = <0>; + clocks = <&clk40M>; + interrupts-extended = <&tlmm 15 IRQ_TYPE_LEVEL_LOW>; + spi-max-frequency = <10000000>; + vdd-supply = <&vdc_5v>; + xceiver-supply = <&vdc_5v>; + }; }; &tlmm { @@ -659,6 +695,32 @@ "HST_BLE_SNS_UART_RX", "HST_WLAN_UART_TX", "HST_WLAN_UART_RX"; + + sdc2_default_state: sdc2-default { + clk { + pins = "sdc2_clk"; + bias-disable; + drive-strength = <16>; + }; + + cmd { + pins = "sdc2_cmd"; + bias-pull-up; + drive-strength = <16>; + }; + + data { + pins = "sdc2_data"; + bias-pull-up; + drive-strength = <16>; + }; + }; + + sdc2_card_det_n: sd-card-det-n { + pins = "gpio77"; + function = "gpio"; + bias-pull-up; + }; }; &uart12 { @@ -684,3 +746,49 @@ vdda-pll-supply = <&vreg_l9a_1p2>; vdda-pll-max-microamp = <18800>; }; + +&usb_1 { + status = "okay"; +}; + +&usb_1_dwc3 { + dr_mode = "peripheral"; +}; + +&usb_1_hsphy { + status = "okay"; + + vdda-pll-supply = <&vreg_l5a_0p88>; + vdda33-supply = <&vreg_l2a_3p1>; + vdda18-supply = <&vreg_l12a_1p8>; +}; + +&usb_1_qmpphy { + status = "okay"; + + vdda-phy-supply = <&vreg_l9a_1p2>; + vdda-pll-supply = <&vreg_l18a_0p92>; +}; + +&usb_2 { + status = "okay"; +}; + +&usb_2_dwc3 { + dr_mode = "host"; +}; + +&usb_2_hsphy { + status = "okay"; + + vdda-pll-supply = <&vreg_l5a_0p88>; + vdda33-supply = <&vreg_l2a_3p1>; + vdda18-supply = <&vreg_l12a_1p8>; +}; + +&usb_2_qmpphy { + status = "okay"; + + vdda-phy-supply = <&vreg_l9a_1p2>; + vdda-pll-supply = <&vreg_l18a_0p92>; +}; diff --git a/arch/arm64/boot/dts/qcom/sc7180-lite.dtsi b/arch/arm64/boot/dts/qcom/sc7180-lite.dtsi new file mode 100644 index 000000000000..d8ed1d7b4ec7 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sc7180-lite.dtsi @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * SC7180 lite device tree source + * + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +&cpu6_opp10 { + opp-peak-kBps = <7216000 22425600>; +}; + +&cpu6_opp11 { + opp-peak-kBps = <7216000 22425600>; +}; + +&cpu6_opp12 { + opp-peak-kBps = <8532000 23347200>; +}; diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r0.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r0.dts index ae4c23a4fe65..30e3e769d2b4 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r0.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r0.dts @@ -14,6 +14,17 @@ compatible = "google,lazor-rev0", "qcom,sc7180"; }; +&pp3300_hub { + /* pp3300_l7c is used to power the USB hub */ + /delete-property/regulator-always-on; + /delete-property/regulator-boot-on; +}; + +&pp3300_l7c { + regulator-always-on; + regulator-boot-on; +}; + &sn65dsi86_out { /* * Lane 0 was incorrectly mapped on the cable, but we've now decided diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-kb.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-kb.dts index c3f426c3c30a..919bfaea6189 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-kb.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-kb.dts @@ -8,8 +8,8 @@ #include "sc7180-trogdor-lazor-r1.dts" / { - model = "Google Lazor (rev1+) with KB Backlight"; - compatible = "google,lazor-sku2", "qcom,sc7180"; + model = "Google Lazor (rev1 - 2) with KB Backlight"; + compatible = "google,lazor-rev1-sku2", "google,lazor-rev2-sku2", "qcom,sc7180"; }; &keyboard_backlight { diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-lte.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-lte.dts index 73e59cf7752a..e16ba7b01f25 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-lte.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-lte.dts @@ -9,8 +9,16 @@ #include "sc7180-trogdor-lte-sku.dtsi" / { - model = "Google Lazor (rev1+) with LTE"; - compatible = "google,lazor-sku0", "qcom,sc7180"; + model = "Google Lazor (rev1 - 2) with LTE"; + compatible = "google,lazor-rev1-sku0", "google,lazor-rev2-sku0", "qcom,sc7180"; +}; + +&ap_sar_sensor { + status = "okay"; +}; + +&ap_sar_sensor_i2c { + status = "okay"; }; &keyboard_backlight { diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts index 3151ae31c1cc..c2ef06367baf 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts @@ -10,6 +10,17 @@ #include "sc7180-trogdor-lazor.dtsi" / { - model = "Google Lazor (rev1+)"; - compatible = "google,lazor", "qcom,sc7180"; + model = "Google Lazor (rev1 - 2)"; + compatible = "google,lazor-rev1", "google,lazor-rev2", "qcom,sc7180"; +}; + +&pp3300_hub { + /* pp3300_l7c is used to power the USB hub */ + /delete-property/regulator-always-on; + /delete-property/regulator-boot-on; +}; + +&pp3300_l7c { + regulator-always-on; + regulator-boot-on; }; diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts new file mode 100644 index 000000000000..6985beb97e53 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Google Lazor board device tree source + * + * Copyright 2020 Google LLC. + */ + +#include "sc7180-trogdor-lazor-r3.dts" + +/ { + model = "Google Lazor (rev3+) with KB Backlight"; + compatible = "google,lazor-sku2", "qcom,sc7180"; +}; + +&keyboard_backlight { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts new file mode 100644 index 000000000000..0881f8dd02c9 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Google Lazor board device tree source + * + * Copyright 2020 Google LLC. + */ + +#include "sc7180-trogdor-lazor-r3.dts" +#include "sc7180-trogdor-lte-sku.dtsi" + +/ { + model = "Google Lazor (rev3+) with LTE"; + compatible = "google,lazor-sku0", "qcom,sc7180"; +}; + +&ap_sar_sensor { + status = "okay"; +}; + +&ap_sar_sensor_i2c { + status = "okay"; +}; + +&keyboard_backlight { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3.dts new file mode 100644 index 000000000000..1b9d2f46359e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Google Lazor board device tree source + * + * Copyright 2020 Google LLC. + */ + +/dts-v1/; + +#include "sc7180-trogdor-lazor.dtsi" + +/ { + model = "Google Lazor (rev3+)"; + compatible = "google,lazor", "qcom,sc7180"; +}; diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi index 180ef9e04306..89e5cd29ec09 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi @@ -30,7 +30,12 @@ ap_h1_spi: &spi0 {}; }; &ap_sar_sensor { - status = "okay"; + semtech,cs0-ground; + semtech,combined-sensors = <3>; + semtech,resolution = "fine"; + semtech,startup-sensor = <0>; + semtech,proxraw-strength = <8>; + semtech,avg-pos-strength = <64>; }; ap_ts_pen_1v8: &i2c4 { diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lte-sku.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lte-sku.dtsi index 44956e3165a1..469aad4e5948 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lte-sku.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lte-sku.dtsi @@ -9,6 +9,10 @@ label = "proximity-wifi-lte"; }; +&mpss_mem { + reg = <0x0 0x86000000 0x0 0x8c00000>; +}; + &remoteproc_mpss { firmware-name = "qcom/sc7180-trogdor/modem/mba.mbn", "qcom/sc7180-trogdor/modem/qdsp6sw.mbn"; diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts index 0a281c24841c..2cb522d6962e 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts @@ -34,11 +34,6 @@ ap_h1_spi: &spi0 {}; }; }; -&ap_sar_sensor_i2c { - /* Not hooked up */ - status = "disabled"; -}; - ap_ts_pen_1v8: &i2c4 { status = "okay"; clock-frequency = <400000>; @@ -58,6 +53,17 @@ ap_ts_pen_1v8: &i2c4 { }; }; +&pp3300_hub { + /* pp3300_l7c is used to power the USB hub */ + /delete-property/regulator-always-on; + /delete-property/regulator-boot-on; +}; + +&pp3300_l7c { + regulator-always-on; + regulator-boot-on; +}; + &sdhc_2 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi index bf875589d364..8ed7dd39f6e3 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi @@ -13,6 +13,23 @@ #include "pm6150.dtsi" #include "pm6150l.dtsi" +/ { + thermal-zones { + charger-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + + thermal-sensors = <&pm6150_adc_tm 1>; + + trips { + temperature = <125000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; +}; + /* * Reserved memory changes * @@ -39,7 +56,7 @@ }; mpss_mem: memory@86000000 { - reg = <0x0 0x86000000 0x0 0x8c00000>; + reg = <0x0 0x86000000 0x0 0x2000000>; no-map; }; @@ -174,11 +191,38 @@ vin-supply = <&pp3300_a>; }; + pp3300_hub: pp3300-hub { + compatible = "regulator-fixed"; + regulator-name = "pp3300_hub"; + + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 84 GPIO_ACTIVE_HIGH>; + enable-active-high; + pinctrl-names = "default"; + pinctrl-0 = <&en_pp3300_hub>; + + regulator-always-on; + regulator-boot-on; + + vin-supply = <&pp3300_a>; + }; + /* BOARD-SPECIFIC TOP LEVEL NODES */ backlight: backlight { compatible = "pwm-backlight"; + /* The panels don't seem to like anything below ~ 5% */ + brightness-levels = < + 196 256 324 400 484 576 676 784 900 1024 1156 1296 + 1444 1600 1764 1936 2116 2304 2500 2704 2916 3136 + 3364 3600 3844 4096 + >; + num-interpolated-steps = <64>; + default-brightness-level = <951>; + pwms = <&cros_ec_pwm 1>; enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>; power-supply = <&ppvar_sys>; @@ -192,7 +236,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pen_pdct_l>; - pen-insert { + pen_insert: pen-insert { label = "Pen Insert"; /* Insert = low, eject = high */ @@ -469,13 +513,10 @@ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; }; - pp3300_hub: pp3300_l7c: ldo7 { regulator-min-microvolt = <3304000>; regulator-max-microvolt = <3304000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - regulator-always-on; - regulator-boot-on; }; pp1800_brij_vccio: @@ -645,7 +686,6 @@ edp_brij_i2c: &i2c2 { }; ap_sar_sensor_i2c: &i2c5 { - status = "okay"; clock-frequency = <400000>; ap_sar_sensor: proximity@28 { @@ -733,6 +773,25 @@ hp_i2c: &i2c9 { status = "okay"; }; +&pm6150_adc { + charger-thermistor@4f { + reg = <ADC5_AMUX_THM3_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; +}; + +&pm6150_adc_tm { + status = "okay"; + + charger-thermistor@1 { + reg = <1>; + io-channels = <&pm6150_adc ADC5_AMUX_THM3_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; +}; + &pm6150_pwrkey { status = "disabled"; }; @@ -776,7 +835,20 @@ hp_i2c: &i2c9 { cd-gpios = <&tlmm 69 GPIO_ACTIVE_LOW>; }; +&spi0 { + pinctrl-0 = <&qup_spi0_cs_gpio>; + cs-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>; +}; + +&spi6 { + pinctrl-0 = <&qup_spi6_cs_gpio>; + cs-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>; +}; + ap_spi_fp: &spi10 { + pinctrl-0 = <&qup_spi10_cs_gpio>; + cs-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; + cros_ec_fp: ec@0 { compatible = "google,cros-ec-spi"; reg = <0>; @@ -937,7 +1009,7 @@ ap_spi_fp: &spi10 { }; }; -&qup_spi0_default { +&qup_spi0_cs_gpio { pinconf { pins = "gpio34", "gpio35", "gpio36", "gpio37"; drive-strength = <2>; @@ -945,7 +1017,7 @@ ap_spi_fp: &spi10 { }; }; -&qup_spi6_default { +&qup_spi6_cs_gpio { pinconf { pins = "gpio59", "gpio60", "gpio61", "gpio62"; drive-strength = <2>; @@ -953,7 +1025,7 @@ ap_spi_fp: &spi10 { }; }; -&qup_spi10_default { +&qup_spi10_cs_gpio { pinconf { pins = "gpio86", "gpio87", "gpio88", "gpio89"; drive-strength = <2>; @@ -1164,6 +1236,19 @@ ap_spi_fp: &spi10 { }; }; + en_pp3300_hub: en-pp3300-hub { + pinmux { + pins = "gpio84"; + function = "gpio"; + }; + + pinconf { + pins = "gpio84"; + drive-strength = <2>; + bias-disable; + }; + }; + fpmcu_boot0: fpmcu-boot0 { pinmux { pins = "gpio10"; @@ -1310,7 +1395,8 @@ ap_spi_fp: &spi10 { pinconf { pins = "gpio24"; - bias-pull-up; + /* Has external pullup */ + bias-disable; }; }; diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index 6678f1e8e395..22b832fc62e3 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -2,7 +2,7 @@ /* * SC7180 SoC device tree source * - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #include <dt-bindings/clock/qcom,dispcc-sc7180.h> @@ -31,6 +31,8 @@ chosen { }; aliases { + mmc1 = &sdhc_1; + mmc2 = &sdhc_2; i2c0 = &i2c0; i2c1 = &i2c1; i2c2 = &i2c2; @@ -525,6 +527,11 @@ opp-hz = /bits/ 64 <2400000000>; opp-peak-kBps = <8532000 23347200>; }; + + cpu6_opp16: opp-2553600000 { + opp-hz = /bits/ 64 <2553600000>; + opp-peak-kBps = <8532000 23347200>; + }; }; memory@80000000 { @@ -660,7 +667,7 @@ }; qfprom: efuse@784000 { - compatible = "qcom,qfprom"; + compatible = "qcom,sc7180-qfprom", "qcom,qfprom"; reg = <0 0x00784000 0 0x8ff>, <0 0x00780000 0 0x7a0>, <0 0x00782000 0 0x100>, @@ -1394,7 +1401,8 @@ ipa: ipa@1e40000 { compatible = "qcom,sc7180-ipa"; - iommus = <&apps_smmu 0x440 0x3>; + iommus = <&apps_smmu 0x440 0x0>, + <&apps_smmu 0x442 0x0>; reg = <0 0x1e40000 0 0x7000>, <0 0x1e47000 0 0x2000>, <0 0x1e04000 0 0x2c000>; @@ -1402,8 +1410,8 @@ "ipa-shared", "gsi"; - interrupts-extended = <&intc 0 311 IRQ_TYPE_EDGE_RISING>, - <&intc 0 432 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 311 IRQ_TYPE_EDGE_RISING>, + <&intc GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH>, <&ipa_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, <&ipa_smp2p_in 1 IRQ_TYPE_EDGE_RISING>; interrupt-names = "ipa", @@ -1595,6 +1603,19 @@ }; }; + qup_spi0_cs_gpio: qup-spi0-cs-gpio { + pinmux { + pins = "gpio34", "gpio35", + "gpio36"; + function = "qup00"; + }; + + pinmux-cs { + pins = "gpio37"; + function = "gpio"; + }; + }; + qup_spi1_default: qup-spi1-default { pinmux { pins = "gpio0", "gpio1", @@ -1603,6 +1624,19 @@ }; }; + qup_spi1_cs_gpio: qup-spi1-cs-gpio { + pinmux { + pins = "gpio0", "gpio1", + "gpio2"; + function = "qup01"; + }; + + pinmux-cs { + pins = "gpio3"; + function = "gpio"; + }; + }; + qup_spi3_default: qup-spi3-default { pinmux { pins = "gpio38", "gpio39", @@ -1611,6 +1645,19 @@ }; }; + qup_spi3_cs_gpio: qup-spi3-cs-gpio { + pinmux { + pins = "gpio38", "gpio39", + "gpio40"; + function = "qup03"; + }; + + pinmux-cs { + pins = "gpio41"; + function = "gpio"; + }; + }; + qup_spi5_default: qup-spi5-default { pinmux { pins = "gpio25", "gpio26", @@ -1619,6 +1666,19 @@ }; }; + qup_spi5_cs_gpio: qup-spi5-cs-gpio { + pinmux { + pins = "gpio25", "gpio26", + "gpio27"; + function = "qup05"; + }; + + pinmux-cs { + pins = "gpio28"; + function = "gpio"; + }; + }; + qup_spi6_default: qup-spi6-default { pinmux { pins = "gpio59", "gpio60", @@ -1627,6 +1687,19 @@ }; }; + qup_spi6_cs_gpio: qup-spi6-cs-gpio { + pinmux { + pins = "gpio59", "gpio60", + "gpio61"; + function = "qup10"; + }; + + pinmux-cs { + pins = "gpio62"; + function = "gpio"; + }; + }; + qup_spi8_default: qup-spi8-default { pinmux { pins = "gpio42", "gpio43", @@ -1635,6 +1708,19 @@ }; }; + qup_spi8_cs_gpio: qup-spi8-cs-gpio { + pinmux { + pins = "gpio42", "gpio43", + "gpio44"; + function = "qup12"; + }; + + pinmux-cs { + pins = "gpio45"; + function = "gpio"; + }; + }; + qup_spi10_default: qup-spi10-default { pinmux { pins = "gpio86", "gpio87", @@ -1643,6 +1729,19 @@ }; }; + qup_spi10_cs_gpio: qup-spi10-cs-gpio { + pinmux { + pins = "gpio86", "gpio87", + "gpio88"; + function = "qup14"; + }; + + pinmux-cs { + pins = "gpio89"; + function = "gpio"; + }; + }; + qup_spi11_default: qup-spi11-default { pinmux { pins = "gpio53", "gpio54", @@ -1651,6 +1750,19 @@ }; }; + qup_spi11_cs_gpio: qup-spi11-cs-gpio { + pinmux { + pins = "gpio53", "gpio54", + "gpio55"; + function = "qup15"; + }; + + pinmux-cs { + pins = "gpio56"; + function = "gpio"; + }; + }; + qup_uart0_default: qup-uart0-default { pinmux { pins = "gpio34", "gpio35", @@ -1742,6 +1854,45 @@ }; }; + sec_mi2s_active: sec-mi2s-active { + pinmux { + pins = "gpio49", "gpio50", "gpio51"; + function = "mi2s_1"; + }; + + pinconf { + pins = "gpio49", "gpio50", "gpio51"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + pri_mi2s_active: pri-mi2s-active { + pinmux { + pins = "gpio53", "gpio54", "gpio55", "gpio56"; + function = "mi2s_0"; + }; + + pinconf { + pins = "gpio53", "gpio54", "gpio55", "gpio56"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + pri_mi2s_mclk_active: pri-mi2s-mclk-active { + pinmux { + pins = "gpio57"; + function = "lpass_ext"; + }; + + pinconf { + pins = "gpio57"; + drive-strength = <8>; + bias-pull-up; + }; + }; + sdc1_on: sdc1-on { pinconf-clk { pins = "sdc1_clk"; @@ -1907,6 +2058,8 @@ operating-points-v2 = <&gpu_opp_table>; qcom,gmu = <&gmu>; + #cooling-cells = <2>; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "gfx-mem"; @@ -1958,7 +2111,7 @@ }; adreno_smmu: iommu@5040000 { - compatible = "qcom,sc7180-smmu-v2", "qcom,smmu-v2"; + compatible = "qcom,sc7180-smmu-v2", "qcom,adreno-smmu", "qcom,smmu-v2"; reg = <0 0x05040000 0 0x10000>; #iommu-cells = <1>; #global-interrupts = <2>; @@ -2792,6 +2945,18 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; + camcc: clock-controller@ad00000 { + compatible = "qcom,sc7180-camcc"; + reg = <0 0x0ad00000 0 0x10000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMERA_XO_CLK>; + clock-names = "bi_tcxo", "iface", "xo"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + mdss: mdss@ae00000 { compatible = "qcom,sc7180-mdss"; reg = <0 0x0ae00000 0 0x1000>; @@ -2811,7 +2976,7 @@ interrupt-controller; #interrupt-cells = <1>; - interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>; + interconnects = <&mmss_noc MASTER_MDP0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "mdp0-mem"; iommus = <&apps_smmu 0x800 0x2>; @@ -3389,6 +3554,36 @@ #power-domain-cells = <1>; }; + lpass_cpu: lpass@62f00000 { + compatible = "qcom,sc7180-lpass-cpu"; + + reg = <0 0x62f00000 0 0x29000>; + reg-names = "lpass-lpaif"; + + iommus = <&apps_smmu 0x1020 0>; + + power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>; + + clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>, + <&lpasscc LPASS_AUDIO_CORE_CORE_CLK>, + <&lpasscc LPASS_AUDIO_CORE_EXT_MCLK0_CLK>, + <&lpasscc LPASS_AUDIO_CORE_SYSNOC_MPORT_CORE_CLK>, + <&lpasscc LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK>, + <&lpasscc LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK>; + + clock-names = "pcnoc-sway-clk", "audio-core", + "mclk0", "pcnoc-mport-clk", + "mi2s-bit-clk0", "mi2s-bit-clk1"; + + + #sound-dai-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + + interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "lpass-irq-lpaif"; + }; + lpass_hm: clock-controller@63000000 { compatible = "qcom,sc7180-lpasshm"; reg = <0 0x63000000 0 0x28>; @@ -3402,7 +3597,7 @@ thermal-zones { cpu0-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 1>; @@ -3451,7 +3646,7 @@ }; cpu1-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 2>; @@ -3500,7 +3695,7 @@ }; cpu2-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 3>; @@ -3549,7 +3744,7 @@ }; cpu3-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 4>; @@ -3598,7 +3793,7 @@ }; cpu4-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 5>; @@ -3647,7 +3842,7 @@ }; cpu5-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 6>; @@ -3696,7 +3891,7 @@ }; cpu6-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 9>; @@ -3737,7 +3932,7 @@ }; cpu7-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 10>; @@ -3778,7 +3973,7 @@ }; cpu8-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 11>; @@ -3819,7 +4014,7 @@ }; cpu9-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 12>; @@ -3860,7 +4055,7 @@ }; aoss0-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 0>; @@ -3881,7 +4076,7 @@ }; cpuss0-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 7>; @@ -3901,7 +4096,7 @@ }; cpuss1-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 8>; @@ -3921,16 +4116,16 @@ }; gpuss0-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 13>; trips { gpuss0_alert0: trip-point0 { - temperature = <90000>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss0_crit: gpuss0_crit { @@ -3939,19 +4134,26 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss1-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens0 14>; trips { gpuss1_alert0: trip-point0 { - temperature = <90000>; + temperature = <95000>; hysteresis = <2000>; - type = "hot"; + type = "passive"; }; gpuss1_crit: gpuss1_crit { @@ -3960,10 +4162,17 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss1_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; aoss1-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens1 0>; @@ -3984,7 +4193,7 @@ }; cwlan-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens1 1>; @@ -4005,7 +4214,7 @@ }; audio-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens1 2>; @@ -4026,7 +4235,7 @@ }; ddr-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens1 3>; @@ -4047,7 +4256,7 @@ }; q6-hvx-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens1 4>; @@ -4068,7 +4277,7 @@ }; camera-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens1 5>; @@ -4089,7 +4298,7 @@ }; mdm-core-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens1 6>; @@ -4110,7 +4319,7 @@ }; mdm-dsp-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens1 7>; @@ -4131,7 +4340,7 @@ }; npu-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens1 8>; @@ -4152,7 +4361,7 @@ }; video-thermal { - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; thermal-sensors = <&tsens1 9>; diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi index deb928d303c2..37d5cc32f6b6 100644 --- a/arch/arm64/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi @@ -830,7 +830,7 @@ status = "disabled"; }; - blsp1_dma: dma@c144000 { + blsp1_dma: dma-controller@c144000 { compatible = "qcom,bam-v1.7.0"; reg = <0x0c144000 0x1f000>; interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>; @@ -944,7 +944,7 @@ status = "disabled"; }; - blsp2_dma: dma@c184000 { + blsp2_dma: dma-controller@c184000 { compatible = "qcom,bam-v1.7.0"; reg = <0x0c184000 0x1f000>; interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>; diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi index 64fc1bfd66fa..216a74f0057c 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi @@ -633,6 +633,15 @@ ap_ts_i2c: &i2c14 { status = "okay"; }; +/* + * Cheza fw does not properly program the GPU aperture to allow the + * GPU to update the SMMU pagetables for context switches. Work + * around this by dropping the "qcom,adreno-smmu" compat string. + */ +&adreno_smmu { + compatible = "qcom,sdm845-smmu-v2", "qcom,smmu-v2"; +}; + &mss_pil { iommus = <&apps_smmu 0x781 0x0>, <&apps_smmu 0x724 0x3>; @@ -644,10 +653,12 @@ ap_ts_i2c: &i2c14 { &qupv3_id_0 { status = "okay"; + iommus = <&apps_smmu 0x0 0x3>; }; &qupv3_id_1 { status = "okay"; + iommus = <&apps_smmu 0x6c0 0x3>; }; &sdhc_2 { diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index 40e8c11f23ab..bcf888381f14 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -1120,9 +1120,12 @@ clock-names = "m-ahb", "s-ahb"; clocks = <&gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, <&gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + iommus = <&apps_smmu 0x3 0x0>; #address-cells = <2>; #size-cells = <2>; ranges; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core"; status = "disabled"; i2c0: i2c@880000 { @@ -1137,6 +1140,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1150,6 +1157,9 @@ interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1163,6 +1173,9 @@ interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1178,6 +1191,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1191,6 +1208,9 @@ interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1204,6 +1224,9 @@ interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1219,6 +1242,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1232,6 +1259,9 @@ interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1245,6 +1275,9 @@ interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1260,6 +1293,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1273,6 +1310,9 @@ interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1286,6 +1326,9 @@ interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1301,6 +1344,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1314,6 +1361,9 @@ interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1327,6 +1377,9 @@ interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1342,6 +1395,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1355,6 +1412,9 @@ interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1368,6 +1428,9 @@ interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1383,6 +1446,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1396,6 +1463,9 @@ interrupts = <GIC_SPI 607 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1409,6 +1479,9 @@ interrupts = <GIC_SPI 607 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1437,6 +1510,9 @@ interrupts = <GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1450,6 +1526,9 @@ interrupts = <GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre1_noc MASTER_QUP_1 0 &config_noc SLAVE_BLSP_1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_1 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; }; @@ -1460,9 +1539,12 @@ clock-names = "m-ahb", "s-ahb"; clocks = <&gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + iommus = <&apps_smmu 0x6c3 0x0>; #address-cells = <2>; #size-cells = <2>; ranges; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core"; status = "disabled"; i2c8: i2c@a80000 { @@ -1477,6 +1559,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>, + <&aggre2_noc MASTER_QUP_2 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1490,6 +1576,9 @@ interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1503,6 +1592,9 @@ interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1518,6 +1610,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>, + <&aggre2_noc MASTER_QUP_2 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1531,6 +1627,9 @@ interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1544,6 +1643,9 @@ interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1559,6 +1661,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>, + <&aggre2_noc MASTER_QUP_2 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1572,6 +1678,9 @@ interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1585,6 +1694,9 @@ interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1600,6 +1712,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>, + <&aggre2_noc MASTER_QUP_2 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1613,6 +1729,9 @@ interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1626,6 +1745,9 @@ interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1641,6 +1763,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>, + <&aggre2_noc MASTER_QUP_2 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1654,6 +1780,9 @@ interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1667,6 +1796,9 @@ interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1682,6 +1814,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>, + <&aggre2_noc MASTER_QUP_2 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1695,6 +1831,9 @@ interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1708,6 +1847,9 @@ interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1723,6 +1865,10 @@ #size-cells = <0>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>, + <&aggre2_noc MASTER_QUP_2 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; }; @@ -1736,6 +1882,9 @@ interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1749,6 +1898,9 @@ interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1765,6 +1917,10 @@ power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; status = "disabled"; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>, + <&aggre2_noc MASTER_QUP_2 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; }; spi15: spi@a9c000 { @@ -1777,6 +1933,9 @@ interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1790,6 +1949,9 @@ interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SDM845_CX>; operating-points-v2 = <&qup_opp_table>; + interconnects = <&aggre2_noc MASTER_QUP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; }; @@ -2138,10 +2300,41 @@ }; }; + cryptobam: dma@1dc4000 { + compatible = "qcom,bam-v1.7.0"; + reg = <0 0x01dc4000 0 0x24000>; + interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rpmhcc 15>; + clock-names = "bam_clk"; + #dma-cells = <1>; + qcom,ee = <0>; + qcom,controlled-remotely = <1>; + iommus = <&apps_smmu 0x704 0x1>, + <&apps_smmu 0x706 0x1>, + <&apps_smmu 0x714 0x1>, + <&apps_smmu 0x716 0x1>; + }; + + crypto: crypto@1dfa000 { + compatible = "qcom,crypto-v5.4"; + reg = <0 0x01dfa000 0 0x6000>; + clocks = <&gcc GCC_CE1_AHB_CLK>, + <&gcc GCC_CE1_AHB_CLK>, + <&rpmhcc 15>; + clock-names = "iface", "bus", "core"; + dmas = <&cryptobam 6>, <&cryptobam 7>; + dma-names = "rx", "tx"; + iommus = <&apps_smmu 0x704 0x1>, + <&apps_smmu 0x706 0x1>, + <&apps_smmu 0x714 0x1>, + <&apps_smmu 0x716 0x1>; + }; + ipa: ipa@1e40000 { compatible = "qcom,sdm845-ipa"; - iommus = <&apps_smmu 0x720 0x3>; + iommus = <&apps_smmu 0x720 0x0>, + <&apps_smmu 0x722 0x0>; reg = <0 0x1e40000 0 0x7000>, <0 0x1e47000 0 0x2000>, <0 0x1e04000 0 0x2c000>; @@ -2149,8 +2342,8 @@ "ipa-shared", "gsi"; - interrupts-extended = <&intc 0 311 IRQ_TYPE_EDGE_RISING>, - <&intc 0 432 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 311 IRQ_TYPE_EDGE_RISING>, + <&intc GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH>, <&ipa_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, <&ipa_smp2p_in 1 IRQ_TYPE_EDGE_RISING>; interrupt-names = "ipa", @@ -3661,6 +3854,9 @@ iommus = <&apps_smmu 0x10a0 0x8>, <&apps_smmu 0x10b0 0x0>; memory-region = <&venus_mem>; + interconnects = <&mmss_noc MASTER_VIDEO_P0 0 &mem_noc SLAVE_EBI1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_VENUS_CFG 0>; + interconnect-names = "video-mem", "cpu-cfg"; video-core0 { compatible = "venus-decoder"; @@ -4103,7 +4299,7 @@ }; adreno_smmu: iommu@5040000 { - compatible = "qcom,sdm845-smmu-v2", "qcom,smmu-v2"; + compatible = "qcom,sdm845-smmu-v2", "qcom,adreno-smmu", "qcom,smmu-v2"; reg = <0 0x5040000 0 0x10000>; #iommu-cells = <1>; #global-interrupts = <2>; @@ -4484,7 +4680,7 @@ }; }; - slimbam: dma@17184000 { + slimbam: dma-controller@17184000 { compatible = "qcom,bam-v1.7.0"; qcom,controlled-remotely; reg = <0 0x17184000 0 0x2a000>; diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts index d03ca3190746..13fdd02cffe6 100644 --- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts @@ -8,6 +8,8 @@ /dts-v1/; #include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/gpio-keys.h> +#include <dt-bindings/input/input.h> #include <dt-bindings/regulator/qcom,rpmh-regulator.h> #include <dt-bindings/sound/qcom,q6afe.h> #include <dt-bindings/sound/qcom,q6asm.h> @@ -21,6 +23,47 @@ aliases { hsuart0 = &uart6; }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-names = "default"; + pinctrl-0 = <&lid_pin_active>, <&mode_pin_active>; + + lid { + gpios = <&tlmm 124 GPIO_ACTIVE_HIGH>; + linux,input-type = <EV_SW>; + linux,code = <SW_LID>; + wakeup-source; + wakeup-event-action = <EV_ACT_DEASSERTED>; + }; + + mode { + gpios = <&tlmm 95 GPIO_ACTIVE_HIGH>; + linux,input-type = <EV_SW>; + linux,code = <SW_TABLET_MODE>; + }; + }; + + panel { + compatible = "boe,nv133fhm-n61"; + no-hpd; + + ports { + port { + panel_in_edp: endpoint { + remote-endpoint = <&sn65dsi86_out>; + }; + }; + }; + }; + + sn65dsi86_refclk: sn65dsi86-refclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + + clock-frequency = <19200000>; + }; }; &adsp_pas { @@ -232,16 +275,30 @@ }; }; -&apps_smmu { - /* TODO: Figure out how to survive booting with this enabled */ - status = "disabled"; -}; - &cdsp_pas { firmware-name = "qcom/LENOVO/81JL/qccdsp850.mbn"; status = "okay"; }; +&dsi0 { + status = "okay"; + vdda-supply = <&vreg_l26a_1p2>; + + ports { + port@1 { + endpoint { + remote-endpoint = <&sn65dsi86_in_a>; + data-lanes = <0 1 2 3>; + }; + }; + }; +}; + +&dsi0_phy { + status = "okay"; + vdds-supply = <&vreg_l1a_0p875>; +}; + &gcc { protected-clocks = <GCC_QSPI_CORE_CLK>, <GCC_QSPI_CORE_CLK_SRC>, @@ -264,23 +321,28 @@ status = "okay"; clock-frequency = <400000>; - hid@15 { + tsel: hid@15 { compatible = "hid-over-i2c"; reg = <0x15>; hid-descr-addr = <0x1>; - interrupts-extended = <&tlmm 37 IRQ_TYPE_EDGE_RISING>; + interrupts-extended = <&tlmm 37 IRQ_TYPE_LEVEL_HIGH>; + + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_hid_active>; }; - hid@2c { + tsc2: hid@2c { compatible = "hid-over-i2c"; reg = <0x2c>; hid-descr-addr = <0x20>; - interrupts-extended = <&tlmm 37 IRQ_TYPE_EDGE_RISING>; + interrupts-extended = <&tlmm 37 IRQ_TYPE_LEVEL_HIGH>; pinctrl-names = "default"; - pinctrl-0 = <&i2c2_hid_active>; + pinctrl-0 = <&i2c3_hid_active>; + + status = "disabled"; }; }; @@ -288,15 +350,54 @@ status = "okay"; clock-frequency = <400000>; - hid@10 { + tsc1: hid@10 { compatible = "hid-over-i2c"; reg = <0x10>; hid-descr-addr = <0x1>; - interrupts-extended = <&tlmm 125 IRQ_TYPE_EDGE_FALLING>; + interrupts-extended = <&tlmm 125 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; - pinctrl-0 = <&i2c6_hid_active>; + pinctrl-0 = <&i2c5_hid_active>; + }; +}; + +&i2c10 { + status = "okay"; + clock-frequency = <400000>; + + sn65dsi86: bridge@2c { + compatible = "ti,sn65dsi86"; + reg = <0x2c>; + pinctrl-names = "default"; + pinctrl-0 = <&sn65dsi86_pin_active>; + + enable-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; + + vpll-supply = <&vreg_l14a_1p88>; + vccio-supply = <&vreg_l14a_1p88>; + + clocks = <&sn65dsi86_refclk>; + clock-names = "refclk"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + sn65dsi86_in_a: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + + port@1 { + reg = <1>; + sn65dsi86_out: endpoint { + remote-endpoint = <&panel_in_edp>; + }; + }; + }; }; }; @@ -304,7 +405,7 @@ status = "okay"; clock-frequency = <400000>; - hid@5c { + ecsh: hid@5c { compatible = "hid-over-i2c"; reg = <0x5c>; hid-descr-addr = <0x1>; @@ -312,14 +413,30 @@ interrupts-extended = <&tlmm 92 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; - pinctrl-0 = <&i2c12_hid_active>; + pinctrl-0 = <&i2c11_hid_active>; }; }; +&mdss { + status = "okay"; +}; + +&mdss_mdp { + status = "okay"; +}; + &mss_pil { firmware-name = "qcom/LENOVO/81JL/qcdsp1v2850.mbn", "qcom/LENOVO/81JL/qcdsp2850.mbn"; }; +&qup_i2c10_default { + pinconf { + pins = "gpio55", "gpio56"; + drive-strength = <2>; + bias-disable; + }; +}; + &qup_i2c12_default { drive-strength = <2>; bias-disable; @@ -426,8 +543,14 @@ &tlmm { gpio-reserved-ranges = <0 4>, <81 4>; - i2c2_hid_active: i2c2-hid-active { - pins = <37>; + sn65dsi86_pin_active: sn65dsi86-enable { + pins = "gpio96"; + drive-strength = <2>; + bias-disable; + }; + + i2c3_hid_active: i2c2-hid-active { + pins = "gpio37"; function = "gpio"; input-enable; @@ -435,8 +558,8 @@ drive-strength = <2>; }; - i2c6_hid_active: i2c6-hid-active { - pins = <125>; + i2c5_hid_active: i2c5-hid-active { + pins = "gpio125"; function = "gpio"; input-enable; @@ -444,8 +567,8 @@ drive-strength = <2>; }; - i2c12_hid_active: i2c12-hid-active { - pins = <92>; + i2c11_hid_active: i2c11-hid-active { + pins = "gpio92"; function = "gpio"; input-enable; @@ -454,13 +577,29 @@ }; wcd_intr_default: wcd_intr_default { - pins = <54>; + pins = "gpio54"; function = "gpio"; input-enable; bias-pull-down; drive-strength = <2>; }; + + lid_pin_active: lid-pin { + pins = "gpio124"; + function = "gpio"; + + input-enable; + bias-disable; + }; + + mode_pin_active: mode-pin { + pins = "gpio95"; + function = "gpio"; + + input-enable; + bias-disable; + }; }; &uart6 { diff --git a/arch/arm64/boot/dts/qcom/sm8150-hdk.dts b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts new file mode 100644 index 000000000000..fb2cf3d987a1 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts @@ -0,0 +1,463 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +/dts-v1/; + +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> +#include <dt-bindings/gpio/gpio.h> +#include "sm8150.dtsi" +#include "pm8150.dtsi" +#include "pm8150b.dtsi" +#include "pm8150l.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SM8150 HDK"; + compatible = "qcom,sm8150-hdk", "qcom,sm8150"; + + aliases { + serial0 = &uart2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + vph_pwr: vph-pwr-regulator { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + }; + + vreg_s4a_1p8: pm8150-s4 { + compatible = "regulator-fixed"; + regulator-name = "vreg_s4a_1p8"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-always-on; + regulator-boot-on; + + vin-supply = <&vph_pwr>; + }; + + gpio_keys { + compatible = "gpio-keys"; + + vol-up { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + gpios = <&pm8150_gpios 6 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&apps_rsc { + pm8150-rpmh-regulators { + compatible = "qcom,pm8150-rpmh-regulators"; + qcom,pmic-id = "a"; + + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s3-supply = <&vph_pwr>; + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + vdd-s6-supply = <&vph_pwr>; + vdd-s7-supply = <&vph_pwr>; + vdd-s8-supply = <&vph_pwr>; + vdd-s9-supply = <&vph_pwr>; + vdd-s10-supply = <&vph_pwr>; + + vdd-l1-l8-l11-supply = <&vreg_s6a_0p9>; + vdd-l2-l10-supply = <&vreg_bob>; + vdd-l3-l4-l5-l18-supply = <&vreg_s6a_0p9>; + vdd-l6-l9-supply = <&vreg_s8c_1p3>; + vdd-l7-l12-l14-l15-supply = <&vreg_s5a_2p0>; + vdd-l13-l16-l17-supply = <&vreg_bob>; + + vreg_s5a_2p0: smps5 { + regulator-min-microvolt = <1904000>; + regulator-max-microvolt = <2000000>; + }; + + vreg_s6a_0p9: smps6 { + regulator-min-microvolt = <920000>; + regulator-max-microvolt = <1128000>; + }; + + vdda_wcss_pll: + vreg_l1a_0p75: ldo1 { + regulator-min-microvolt = <752000>; + regulator-max-microvolt = <752000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdd_pdphy: + vdda_usb_hs_3p1: + vreg_l2a_3p1: ldo2 { + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3a_0p8: ldo3 { + regulator-min-microvolt = <480000>; + regulator-max-microvolt = <932000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdd_usb_hs_core: + vdda_csi_0_0p9: + vdda_csi_1_0p9: + vdda_csi_2_0p9: + vdda_csi_3_0p9: + vdda_dsi_0_0p9: + vdda_dsi_1_0p9: + vdda_dsi_0_pll_0p9: + vdda_dsi_1_pll_0p9: + vdda_pcie_1ln_core: + vdda_pcie_2ln_core: + vdda_pll_hv_cc_ebi01: + vdda_pll_hv_cc_ebi23: + vdda_qrefs_0p875_5: + vdda_sp_sensor: + vdda_ufs_2ln_core_1: + vdda_ufs_2ln_core_2: + vdda_usb_ss_dp_core_1: + vdda_usb_ss_dp_core_2: + vdda_qlink_lv: + vdda_qlink_lv_ck: + vreg_l5a_0p875: ldo5 { + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6a_1p2: ldo6 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7a_1p8: ldo7 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vddpx_10: + vreg_l9a_1p2: ldo9 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l10a_2p5: ldo10 { + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l11a_0p8: ldo11 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdd_qfprom: + vdd_qfprom_sp: + vdda_apc_cs_1p8: + vdda_gfx_cs_1p8: + vdda_usb_hs_1p8: + vdda_qrefs_vref_1p8: + vddpx_10_a: + vreg_l12a_1p8: ldo12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l13a_2p7: ldo13 { + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <2704000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l14a_1p8: ldo14 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l15a_1p7: ldo15 { + regulator-min-microvolt = <1704000>; + regulator-max-microvolt = <1704000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l16a_2p7: ldo16 { + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l17a_3p0: ldo17 { + regulator-min-microvolt = <2856000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + pm8150l-rpmh-regulators { + compatible = "qcom,pm8150l-rpmh-regulators"; + qcom,pmic-id = "c"; + + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s3-supply = <&vph_pwr>; + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + vdd-s6-supply = <&vph_pwr>; + vdd-s7-supply = <&vph_pwr>; + vdd-s8-supply = <&vph_pwr>; + + vdd-l1-l8-supply = <&vreg_s4a_1p8>; + vdd-l2-l3-supply = <&vreg_s8c_1p3>; + vdd-l4-l5-l6-supply = <&vreg_bob>; + vdd-l7-l11-supply = <&vreg_bob>; + vdd-l9-l10-supply = <&vreg_bob>; + + vdd-bob-supply = <&vph_pwr>; + vdd-flash-supply = <&vreg_bob>; + vdd-rgb-supply = <&vreg_bob>; + + vreg_bob: bob { + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <4000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-bypass; + }; + + vreg_s8c_1p3: smps8 { + regulator-min-microvolt = <1352000>; + regulator-max-microvolt = <1352000>; + }; + + vreg_l1c_1p8: ldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdda_wcss_adcdac_1: + vdda_wcss_adcdac_22: + vreg_l2c_1p3: ldo2 { + regulator-min-microvolt = <1304000>; + regulator-max-microvolt = <1304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdda_hv_ebi0: + vdda_hv_ebi1: + vdda_hv_ebi2: + vdda_hv_ebi3: + vdda_hv_refgen0: + vdda_qlink_hv_ck: + vreg_l3c_1p2: ldo3 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vddpx_5: + vreg_l4c_1p8: ldo4 { + regulator-min-microvolt = <1704000>; + regulator-max-microvolt = <2928000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vddpx_6: + vreg_l5c_1p8: ldo5 { + regulator-min-microvolt = <1704000>; + regulator-max-microvolt = <2928000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vddpx_2: + vreg_l6c_2p9: ldo6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7c_3p0: ldo7 { + regulator-min-microvolt = <2856000>; + regulator-max-microvolt = <3104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8c_1p8: ldo8 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l9c_2p9: ldo9 { + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l10c_3p3: ldo10 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3312000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l11c_3p3: ldo11 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3312000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + pm8009-rpmh-regulators { + compatible = "qcom,pm8009-rpmh-regulators"; + qcom,pmic-id = "f"; + + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vreg_bob>; + + vdd-l2-supply = <&vreg_s8c_1p3>; + vdd-l5-l6-supply = <&vreg_bob>; + + vreg_l2f_1p2: ldo2 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5f_2p85: ldo5 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6f_2p85: ldo6 { + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-min-microvolt = <2856000>; + regulator-max-microvolt = <2856000>; + }; + }; +}; + +&qupv3_id_1 { + status = "okay"; +}; + +&pon { + pwrkey { + status = "okay"; + }; + + resin { + compatible = "qcom,pm8941-resin"; + interrupts = <0x0 0x8 0x1 IRQ_TYPE_EDGE_BOTH>; + debounce = <15625>; + bias-pull-up; + linux,code = <KEY_VOLUMEDOWN>; + }; +}; + +&remoteproc_adsp { + status = "okay"; + + firmware-name = "qcom/sm8150/adsp.mbn"; +}; + +&remoteproc_cdsp { + status = "okay"; + + firmware-name = "qcom/sm8150/cdsp.mbn"; +}; + +&remoteproc_slpi { + status = "okay"; + + firmware-name = "qcom/sm8150/slpi.mbn"; +}; + +&tlmm { + gpio-reserved-ranges = <0 4>, <126 4>; +}; + +&uart2 { + status = "okay"; +}; + +&ufs_mem_hc { + status = "okay"; + + reset-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l10a_2p5>; + vcc-max-microamp = <750000>; + vccq-supply = <&vreg_l9a_1p2>; + vccq-max-microamp = <700000>; + vccq2-supply = <&vreg_s4a_1p8>; + vccq2-max-microamp = <750000>; +}; + +&ufs_mem_phy { + status = "okay"; + + vdda-phy-supply = <&vdda_ufs_2ln_core_1>; + vdda-max-microamp = <90200>; + vdda-pll-supply = <&vreg_l3c_1p2>; + vdda-pll-max-microamp = <19000>; +}; + +&usb_1_hsphy { + status = "okay"; + vdda-pll-supply = <&vdd_usb_hs_core>; + vdda33-supply = <&vdda_usb_hs_3p1>; + vdda18-supply = <&vdda_usb_hs_1p8>; +}; + +&usb_2_hsphy { + status = "okay"; + vdda-pll-supply = <&vdd_usb_hs_core>; + vdda33-supply = <&vdda_usb_hs_3p1>; + vdda18-supply = <&vdda_usb_hs_1p8>; +}; + +&usb_1_qmpphy { + status = "okay"; + vdda-phy-supply = <&vreg_l3c_1p2>; + vdda-pll-supply = <&vdda_usb_ss_dp_core_1>; +}; + +&usb_2_qmpphy { + status = "okay"; + vdda-phy-supply = <&vreg_l3c_1p2>; + vdda-pll-supply = <&vdda_usb_ss_dp_core_1>; +}; + +&usb_1 { + status = "okay"; +}; + +&usb_2 { + status = "okay"; +}; + +&usb_1_dwc3 { + dr_mode = "peripheral"; +}; + +&usb_2_dwc3 { + dr_mode = "host"; +}; diff --git a/arch/arm64/boot/dts/qcom/sm8150-mtp.dts b/arch/arm64/boot/dts/qcom/sm8150-mtp.dts index 6c6325c3af59..3774f8e63416 100644 --- a/arch/arm64/boot/dts/qcom/sm8150-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sm8150-mtp.dts @@ -369,14 +369,22 @@ &remoteproc_adsp { status = "okay"; + firmware-name = "qcom/sm8150/adsp.mdt"; }; &remoteproc_cdsp { status = "okay"; + firmware-name = "qcom/sm8150/cdsp.mdt"; +}; + +&remoteproc_mpss { + status = "okay"; + firmware-name = "qcom/sm8150/modem.mdt"; }; &remoteproc_slpi { status = "okay"; + firmware-name = "qcom/sm8150/slpi.mdt"; }; &tlmm { @@ -429,3 +437,12 @@ &usb_1_dwc3 { dr_mode = "peripheral"; }; + +&wifi { + status = "okay"; + + vdd-0.8-cx-mx-supply = <&vdda_wcss_pll>; + vdd-1.8-xo-supply = <&vreg_l7a_1p8>; + vdd-1.3-rfa-supply = <&vdda_wcss_adcdac_1>; + vdd-3.3-ch0-supply = <&vreg_l11c_3p3>; +}; diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi index f0a872e02686..5270bda7418f 100644 --- a/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi @@ -490,6 +490,13 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; + system-cache-controller@9200000 { + compatible = "qcom,sm8150-llcc"; + reg = <0 0x09200000 0 0x200000>, <0 0x09600000 0 0x50000>; + reg-names = "llcc_base", "llcc_broadcast_base"; + interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>; + }; + ufs_mem_hc: ufshc@1d84000 { compatible = "qcom,sm8150-ufshc", "qcom,ufshc", "jedec,ufs-2.0"; @@ -502,6 +509,8 @@ resets = <&gcc GCC_UFS_PHY_BCR>; reset-names = "rst"; + iommus = <&apps_smmu 0x300 0>; + clock-names = "core_clk", "bus_aggr_clk", @@ -789,6 +798,597 @@ }; }; + stm@6002000 { + compatible = "arm,coresight-stm", "arm,primecell"; + reg = <0 0x06002000 0 0x1000>, + <0 0x16280000 0 0x180000>; + reg-names = "stm-base", "stm-stimulus-base"; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + stm_out: endpoint { + remote-endpoint = <&funnel0_in7>; + }; + }; + }; + }; + + funnel@6041000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0 0x06041000 0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + funnel0_out: endpoint { + remote-endpoint = <&merge_funnel_in0>; + }; + }; + }; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@7 { + reg = <7>; + funnel0_in7: endpoint { + remote-endpoint = <&stm_out>; + }; + }; + }; + }; + + funnel@6042000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0 0x06042000 0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + funnel1_out: endpoint { + remote-endpoint = <&merge_funnel_in1>; + }; + }; + }; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@4 { + reg = <4>; + funnel1_in4: endpoint { + remote-endpoint = <&swao_replicator_out>; + }; + }; + }; + }; + + funnel@6043000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0 0x06043000 0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + funnel2_out: endpoint { + remote-endpoint = <&merge_funnel_in2>; + }; + }; + }; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@2 { + reg = <2>; + funnel2_in2: endpoint { + remote-endpoint = <&apss_merge_funnel_out>; + }; + }; + }; + }; + + funnel@6045000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0 0x06045000 0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + merge_funnel_out: endpoint { + remote-endpoint = <&etf_in>; + }; + }; + }; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + merge_funnel_in0: endpoint { + remote-endpoint = <&funnel0_out>; + }; + }; + + port@1 { + reg = <1>; + merge_funnel_in1: endpoint { + remote-endpoint = <&funnel1_out>; + }; + }; + + port@2 { + reg = <2>; + merge_funnel_in2: endpoint { + remote-endpoint = <&funnel2_out>; + }; + }; + }; + }; + + replicator@6046000 { + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; + reg = <0 0x06046000 0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + replicator_out0: endpoint { + remote-endpoint = <&etr_in>; + }; + }; + + port@1 { + reg = <1>; + replicator_out1: endpoint { + remote-endpoint = <&replicator1_in>; + }; + }; + }; + + in-ports { + port { + replicator_in0: endpoint { + remote-endpoint = <&etf_out>; + }; + }; + }; + }; + + etf@6047000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0 0x06047000 0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + etf_out: endpoint { + remote-endpoint = <&replicator_in0>; + }; + }; + }; + + in-ports { + port { + etf_in: endpoint { + remote-endpoint = <&merge_funnel_out>; + }; + }; + }; + }; + + etr@6048000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0 0x06048000 0 0x1000>; + iommus = <&apps_smmu 0x05e0 0x0>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + arm,scatter-gather; + + in-ports { + port { + etr_in: endpoint { + remote-endpoint = <&replicator_out0>; + }; + }; + }; + }; + + replicator@604a000 { + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; + reg = <0 0x0604a000 0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + replicator1_out: endpoint { + remote-endpoint = <&swao_funnel_in>; + }; + }; + }; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + replicator1_in: endpoint { + remote-endpoint = <&replicator_out1>; + }; + }; + }; + }; + + funnel@6b08000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0 0x06b08000 0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + swao_funnel_out: endpoint { + remote-endpoint = <&swao_etf_in>; + }; + }; + }; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@6 { + reg = <6>; + swao_funnel_in: endpoint { + remote-endpoint = <&replicator1_out>; + }; + }; + }; + }; + + etf@6b09000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0 0x06b09000 0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + swao_etf_out: endpoint { + remote-endpoint = <&swao_replicator_in>; + }; + }; + }; + + in-ports { + port { + swao_etf_in: endpoint { + remote-endpoint = <&swao_funnel_out>; + }; + }; + }; + }; + + replicator@6b0a000 { + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; + reg = <0 0x06b0a000 0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + qcom,replicator-loses-context; + + out-ports { + port { + swao_replicator_out: endpoint { + remote-endpoint = <&funnel1_in4>; + }; + }; + }; + + in-ports { + port { + swao_replicator_in: endpoint { + remote-endpoint = <&swao_etf_out>; + }; + }; + }; + }; + + etm@7040000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07040000 0 0x1000>; + + cpu = <&CPU0>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + arm,coresight-loses-context-with-cpu; + qcom,skip-power-up; + + out-ports { + port { + etm0_out: endpoint { + remote-endpoint = <&apss_funnel_in0>; + }; + }; + }; + }; + + etm@7140000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07140000 0 0x1000>; + + cpu = <&CPU1>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + arm,coresight-loses-context-with-cpu; + qcom,skip-power-up; + + out-ports { + port { + etm1_out: endpoint { + remote-endpoint = <&apss_funnel_in1>; + }; + }; + }; + }; + + etm@7240000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07240000 0 0x1000>; + + cpu = <&CPU2>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + arm,coresight-loses-context-with-cpu; + qcom,skip-power-up; + + out-ports { + port { + etm2_out: endpoint { + remote-endpoint = <&apss_funnel_in2>; + }; + }; + }; + }; + + etm@7340000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07340000 0 0x1000>; + + cpu = <&CPU3>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + arm,coresight-loses-context-with-cpu; + qcom,skip-power-up; + + out-ports { + port { + etm3_out: endpoint { + remote-endpoint = <&apss_funnel_in3>; + }; + }; + }; + }; + + etm@7440000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07440000 0 0x1000>; + + cpu = <&CPU4>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + arm,coresight-loses-context-with-cpu; + qcom,skip-power-up; + + out-ports { + port { + etm4_out: endpoint { + remote-endpoint = <&apss_funnel_in4>; + }; + }; + }; + }; + + etm@7540000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07540000 0 0x1000>; + + cpu = <&CPU5>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + arm,coresight-loses-context-with-cpu; + qcom,skip-power-up; + + out-ports { + port { + etm5_out: endpoint { + remote-endpoint = <&apss_funnel_in5>; + }; + }; + }; + }; + + etm@7640000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07640000 0 0x1000>; + + cpu = <&CPU6>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + arm,coresight-loses-context-with-cpu; + qcom,skip-power-up; + + out-ports { + port { + etm6_out: endpoint { + remote-endpoint = <&apss_funnel_in6>; + }; + }; + }; + }; + + etm@7740000 { + compatible = "arm,coresight-etm4x", "arm,primecell"; + reg = <0 0x07740000 0 0x1000>; + + cpu = <&CPU7>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + arm,coresight-loses-context-with-cpu; + qcom,skip-power-up; + + out-ports { + port { + etm7_out: endpoint { + remote-endpoint = <&apss_funnel_in7>; + }; + }; + }; + }; + + funnel@7800000 { /* APSS Funnel */ + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0 0x07800000 0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + apss_funnel_out: endpoint { + remote-endpoint = <&apss_merge_funnel_in>; + }; + }; + }; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + apss_funnel_in0: endpoint { + remote-endpoint = <&etm0_out>; + }; + }; + + port@1 { + reg = <1>; + apss_funnel_in1: endpoint { + remote-endpoint = <&etm1_out>; + }; + }; + + port@2 { + reg = <2>; + apss_funnel_in2: endpoint { + remote-endpoint = <&etm2_out>; + }; + }; + + port@3 { + reg = <3>; + apss_funnel_in3: endpoint { + remote-endpoint = <&etm3_out>; + }; + }; + + port@4 { + reg = <4>; + apss_funnel_in4: endpoint { + remote-endpoint = <&etm4_out>; + }; + }; + + port@5 { + reg = <5>; + apss_funnel_in5: endpoint { + remote-endpoint = <&etm5_out>; + }; + }; + + port@6 { + reg = <6>; + apss_funnel_in6: endpoint { + remote-endpoint = <&etm6_out>; + }; + }; + + port@7 { + reg = <7>; + apss_funnel_in7: endpoint { + remote-endpoint = <&etm7_out>; + }; + }; + }; + }; + + funnel@7810000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0 0x07810000 0 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + apss_merge_funnel_out: endpoint { + remote-endpoint = <&funnel2_in2>; + }; + }; + }; + + in-ports { + port { + apss_merge_funnel_in: endpoint { + remote-endpoint = <&apss_funnel_out>; + }; + }; + }; + }; + remoteproc_cdsp: remoteproc@8300000 { compatible = "qcom,sm8150-cdsp-pas"; reg = <0x0 0x08300000 0x0 0x4040>; @@ -836,6 +1436,19 @@ resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>; }; + usb_2_hsphy: phy@88e3000 { + compatible = "qcom,sm8150-usb-hs-phy", + "qcom,usb-snps-hs-7nm-phy"; + reg = <0 0x088e3000 0 0x400>; + status = "disabled"; + #phy-cells = <0>; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "ref"; + + resets = <&gcc GCC_QUSB2PHY_SEC_BCR>; + }; + usb_1_qmpphy: phy@88e9000 { compatible = "qcom,sm8150-qmp-usb3-phy"; reg = <0 0x088e9000 0 0x18c>, @@ -885,6 +1498,37 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; + usb_2_qmpphy: phy@88eb000 { + compatible = "qcom,sm8150-qmp-usb3-uni-phy"; + reg = <0 0x088eb000 0 0x200>; + status = "disabled"; + #clock-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>, + <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_USB3_SEC_CLKREF_CLK>, + <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>; + clock-names = "aux", "ref_clk_src", "ref", "com_aux"; + + resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR>, + <&gcc GCC_USB3_PHY_SEC_BCR>; + reset-names = "phy", "common"; + + usb_2_ssphy: lane@88eb200 { + reg = <0 0x088eb200 0 0x200>, + <0 0x088eb400 0 0x200>, + <0 0x088eb800 0 0x800>, + <0 0x088eb600 0 0x200>; + #phy-cells = <0>; + clocks = <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>; + clock-names = "pipe0"; + clock-output-names = "usb3_uni_phy_pipe_clk_src"; + }; + }; + usb_1: usb@a6f8800 { compatible = "qcom,sm8150-dwc3", "qcom,dwc3"; reg = <0 0x0a6f8800 0 0x400>; @@ -922,6 +1566,7 @@ compatible = "snps,dwc3"; reg = <0 0x0a600000 0 0xcd00>; interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; + iommus = <&apps_smmu 0x140 0>; snps,dis_u2_susphy_quirk; snps,dis_enblslpm_quirk; phys = <&usb_1_hsphy>, <&usb_1_ssphy>; @@ -929,6 +1574,51 @@ }; }; + usb_2: usb@a8f8800 { + compatible = "qcom,sm8150-dwc3", "qcom,dwc3"; + reg = <0 0x0a8f8800 0 0x400>; + status = "disabled"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + dma-ranges; + + clocks = <&gcc GCC_CFG_NOC_USB3_SEC_AXI_CLK>, + <&gcc GCC_USB30_SEC_MASTER_CLK>, + <&gcc GCC_AGGRE_USB3_SEC_AXI_CLK>, + <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_SEC_SLEEP_CLK>, + <&gcc GCC_USB3_SEC_CLKREF_CLK>; + clock-names = "cfg_noc", "core", "iface", "mock_utmi", + "sleep", "xo"; + + assigned-clocks = <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_SEC_MASTER_CLK>; + assigned-clock-rates = <19200000>, <200000000>; + + interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 490 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 491 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hs_phy_irq", "ss_phy_irq", + "dm_hs_phy_irq", "dp_hs_phy_irq"; + + power-domains = <&gcc USB30_SEC_GDSC>; + + resets = <&gcc GCC_USB30_SEC_BCR>; + + usb_2_dwc3: dwc3@a800000 { + compatible = "snps,dwc3"; + reg = <0 0x0a800000 0 0xcd00>; + interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>; + iommus = <&apps_smmu 0x160 0>; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + phys = <&usb_2_hsphy>, <&usb_2_ssphy>; + phy-names = "usb2-phy", "usb3-phy"; + }; + }; + camnoc_virt: interconnect@ac00000 { compatible = "qcom,sm8150-camnoc-virt"; reg = <0 0x0ac00000 0 0x1000>; @@ -987,6 +1677,94 @@ cell-index = <0>; }; + apps_smmu: iommu@15000000 { + compatible = "qcom,sm8150-smmu-500", "arm,mmu-500"; + reg = <0 0x15000000 0 0x100000>; + #iommu-cells = <2>; + #global-interrupts = <1>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>; + }; + remoteproc_adsp: remoteproc@17300000 { compatible = "qcom,sm8150-adsp-pas"; reg = <0x0 0x17300000 0x0 0x4040>; @@ -1206,6 +1984,29 @@ #freq-domain-cells = <1>; }; + + wifi: wifi@18800000 { + compatible = "qcom,wcn3990-wifi"; + reg = <0 0x18800000 0 0x800000>; + reg-names = "membase"; + memory-region = <&wlan_mem>; + clock-names = "cxo_ref_clk_pin", "qdss"; + clocks = <&rpmhcc RPMH_RF_CLK2>, <&aoss_qmp>; + interrupts = <GIC_SPI 414 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 415 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>; + iommus = <&apps_smmu 0x0640 0x1>; + status = "disabled"; + }; }; timer { diff --git a/arch/arm64/boot/dts/qcom/sm8250-hdk.dts b/arch/arm64/boot/dts/qcom/sm8250-hdk.dts new file mode 100644 index 000000000000..c3a2c5aa6fe9 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sm8250-hdk.dts @@ -0,0 +1,454 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +/dts-v1/; + +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> +#include <dt-bindings/gpio/gpio.h> +#include "sm8250.dtsi" +#include "pm8150.dtsi" +#include "pm8150b.dtsi" +#include "pm8150l.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SM8250 HDK"; + compatible = "qcom,sm8250-hdk", "qcom,sm8250"; + + aliases { + serial0 = &uart12; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + vph_pwr: vph-pwr-regulator { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + }; + + vreg_s4a_1p8: pm8150-s4 { + compatible = "regulator-fixed"; + regulator-name = "vreg_s4a_1p8"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-always-on; + regulator-boot-on; + + vin-supply = <&vph_pwr>; + }; + + vreg_s6c_0p88: smpc6-regulator { + compatible = "regulator-fixed"; + regulator-name = "vreg_s6c_0p88"; + + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-always-on; + vin-supply = <&vph_pwr>; + }; + + gpio_keys { + compatible = "gpio-keys"; + + vol-up { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + gpios = <&pm8150_gpios 6 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&apps_rsc { + pm8150-rpmh-regulators { + compatible = "qcom,pm8150-rpmh-regulators"; + qcom,pmic-id = "a"; + + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s3-supply = <&vph_pwr>; + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + vdd-s6-supply = <&vph_pwr>; + vdd-s7-supply = <&vph_pwr>; + vdd-s8-supply = <&vph_pwr>; + vdd-s9-supply = <&vph_pwr>; + vdd-s10-supply = <&vph_pwr>; + vdd-l1-l8-l11-supply = <&vreg_s6c_0p88>; + vdd-l2-l10-supply = <&vreg_bob>; + vdd-l3-l4-l5-l18-supply = <&vreg_s6a_0p95>; + vdd-l6-l9-supply = <&vreg_s8c_1p3>; + vdd-l7-l12-l14-l15-supply = <&vreg_s5a_1p9>; + vdd-l13-l16-l17-supply = <&vreg_bob>; + + vreg_s5a_1p9: smps5 { + regulator-name = "vreg_s5a_1p9"; + regulator-min-microvolt = <1824000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s6a_0p95: smps6 { + regulator-name = "vreg_s6a_0p95"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1128000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2a_3p1: ldo2 { + regulator-name = "vreg_l2a_3p1"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3a_0p9: ldo3 { + regulator-name = "vreg_l3a_0p9"; + regulator-min-microvolt = <928000>; + regulator-max-microvolt = <932000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5a_0p88: ldo5 { + regulator-name = "vreg_l5a_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6a_1p2: ldo6 { + regulator-name = "vreg_l6a_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7a_1p7: ldo7 { + regulator-name = "vreg_l7a_1p7"; + regulator-min-microvolt = <1704000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l9a_1p2: ldo9 { + regulator-name = "vreg_l9a_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l10a_1p8: ldo10 { + regulator-name = "vreg_l10a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l12a_1p8: ldo12 { + regulator-name = "vreg_l12a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l13a_ts_3p0: ldo13 { + regulator-name = "vreg_l13a_ts_3p0"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l14a_1p8: ldo14 { + regulator-name = "vreg_l14a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l15a_1p8: ldo15 { + regulator-name = "vreg_l15a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l16a_3p3: ldo16 { + regulator-name = "vreg_l16a_3p3"; + regulator-min-microvolt = <3024000>; + regulator-max-microvolt = <3304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l17a_2p96: ldo17 { + regulator-name = "vreg_l17a_2p96"; + regulator-min-microvolt = <2496000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l18a_0p92: ldo18 { + regulator-name = "vreg_l18a_0p92"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + pm8150l-rpmh-regulators { + compatible = "qcom,pm8150l-rpmh-regulators"; + qcom,pmic-id = "c"; + + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s3-supply = <&vph_pwr>; + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + vdd-s6-supply = <&vph_pwr>; + vdd-s7-supply = <&vph_pwr>; + vdd-s8-supply = <&vph_pwr>; + vdd-l1-l8-supply = <&vreg_s4a_1p8>; + vdd-l2-l3-supply = <&vreg_s8c_1p3>; + vdd-l4-l5-l6-supply = <&vreg_bob>; + vdd-l7-l11-supply = <&vreg_bob>; + vdd-l9-l10-supply = <&vreg_bob>; + vdd-bob-supply = <&vph_pwr>; + + vreg_bob: bob { + regulator-name = "vreg_bob"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_s8c_1p3: smps8 { + regulator-name = "vreg_s8c_1p3"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1400000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1c_1p8: ldo1 { + regulator-name = "vreg_l1c_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2c_1p2: ldo2 { + regulator-name = "vreg_l2c_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3c_0p8: ldo3 { + regulator-name = "vreg_l3c_0p8"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4c_1p8: ldo4 { + regulator-name = "vreg_l4c_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5c_1p8: ldo5 { + regulator-name = "vreg_l5c_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6c_2p96: ldo6 { + regulator-name = "vreg_l6c_2p96"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7c_cam_vcm0_2p85: ldo7 { + regulator-name = "vreg_l7c_cam_vcm0_2p85"; + regulator-min-microvolt = <2856000>; + regulator-max-microvolt = <3104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8c_1p8: ldo8 { + regulator-name = "vreg_l8c_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l9c_2p96: ldo9 { + regulator-name = "vreg_l9c_2p96"; + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l10c_3p0: ldo10 { + regulator-name = "vreg_l10c_3p0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3312000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l11c_3p3: ldo11 { + regulator-name = "vreg_l11c_3p3"; + regulator-min-microvolt = <3104000>; + regulator-max-microvolt = <3312000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + pm8009-rpmh-regulators { + compatible = "qcom,pm8009-rpmh-regulators"; + qcom,pmic-id = "f"; + + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vreg_bob>; + vdd-l2-supply = <&vreg_s8c_1p3>; + vdd-l5-l6-supply = <&vreg_bob>; + vdd-l7-supply = <&vreg_s4a_1p8>; + + vreg_l1f_cam_dvdd1_1p1: ldo1 { + regulator-name = "vreg_l1f_cam_dvdd1_1p1"; + regulator-min-microvolt = <1104000>; + regulator-max-microvolt = <1104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f_cam_dvdd0_1p2: ldo2 { + regulator-name = "vreg_l2f_cam_dvdd0_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3f_cam_dvdd2_1p05: ldo3 { + regulator-name = "vreg_l3f_cam_dvdd2_1p05"; + regulator-min-microvolt = <1056000>; + regulator-max-microvolt = <1056000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5f_cam_avdd0_2p85: ldo5 { + regulator-name = "vreg_l5f_cam_avdd0_2p85"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6f_cam_avdd1_2p8: ldo6 { + regulator-name = "vreg_l6f_cam_avdd1_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7f_1p8: ldo7 { + regulator-name = "vreg_l7f_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +&qupv3_id_1 { + status = "okay"; +}; + +&pon { + pwrkey { + status = "okay"; + }; + + resin { + compatible = "qcom,pm8941-resin"; + interrupts = <0x0 0x8 0x1 IRQ_TYPE_EDGE_BOTH>; + debounce = <15625>; + bias-pull-up; + linux,code = <KEY_VOLUMEDOWN>; + }; +}; + +&tlmm { + gpio-reserved-ranges = <28 4>, <40 4>; +}; + +&uart12 { + status = "okay"; +}; + +&ufs_mem_hc { + status = "okay"; + + vcc-supply = <&vreg_l17a_2p96>; + vcc-max-microamp = <800000>; + vccq-supply = <&vreg_l6a_1p2>; + vccq-max-microamp = <800000>; + vccq2-supply = <&vreg_s4a_1p8>; + vccq2-max-microamp = <800000>; +}; + +&ufs_mem_phy { + status = "okay"; + + vdda-phy-supply = <&vreg_l5a_0p88>; + vdda-max-microamp = <89900>; + vdda-pll-supply = <&vreg_l9a_1p2>; + vdda-pll-max-microamp = <18800>; +}; + +&usb_1_hsphy { + status = "okay"; + vdda-pll-supply = <&vreg_l5a_0p88>; + vdda33-supply = <&vreg_l2a_3p1>; + vdda18-supply = <&vreg_l12a_1p8>; +}; + +&usb_2_hsphy { + status = "okay"; + vdda-pll-supply = <&vreg_l5a_0p88>; + vdda33-supply = <&vreg_l2a_3p1>; + vdda18-supply = <&vreg_l12a_1p8>; +}; + +&usb_1_qmpphy { + status = "okay"; + vdda-phy-supply = <&vreg_l9a_1p2>; + vdda-pll-supply = <&vreg_l18a_0p92>; +}; + +&usb_2_qmpphy { + status = "okay"; + vdda-phy-supply = <&vreg_l9a_1p2>; + vdda-pll-supply = <&vreg_l18a_0p92>; +}; + +&usb_1 { + status = "okay"; +}; + +&usb_2 { + status = "okay"; +}; + +&usb_1_dwc3 { + dr_mode = "peripheral"; +}; + +&usb_2_dwc3 { + dr_mode = "host"; +}; diff --git a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts index fd194ed7fbc8..dea00f19711d 100644 --- a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts @@ -14,7 +14,7 @@ / { model = "Qualcomm Technologies, Inc. SM8250 MTP"; - compatible = "qcom,sm8250-mtp"; + compatible = "qcom,sm8250-mtp", "qcom,sm8250"; aliases { serial0 = &uart12; @@ -378,6 +378,10 @@ /* rtc6226 @ 64 */ }; +&pm8150_rtc { + status = "okay"; +}; + &qupv3_id_0 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi index d057d85a19fb..65acd1f381eb 100644 --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -93,10 +93,10 @@ qcom,freq-domain = <&cpufreq_hw 0>; #cooling-cells = <2>; L2_0: l2-cache { - compatible = "cache"; - next-level-cache = <&L3_0>; + compatible = "cache"; + next-level-cache = <&L3_0>; L3_0: l3-cache { - compatible = "cache"; + compatible = "cache"; }; }; }; @@ -110,8 +110,8 @@ qcom,freq-domain = <&cpufreq_hw 0>; #cooling-cells = <2>; L2_100: l2-cache { - compatible = "cache"; - next-level-cache = <&L3_0>; + compatible = "cache"; + next-level-cache = <&L3_0>; }; }; @@ -124,8 +124,8 @@ qcom,freq-domain = <&cpufreq_hw 0>; #cooling-cells = <2>; L2_200: l2-cache { - compatible = "cache"; - next-level-cache = <&L3_0>; + compatible = "cache"; + next-level-cache = <&L3_0>; }; }; @@ -138,8 +138,8 @@ qcom,freq-domain = <&cpufreq_hw 0>; #cooling-cells = <2>; L2_300: l2-cache { - compatible = "cache"; - next-level-cache = <&L3_0>; + compatible = "cache"; + next-level-cache = <&L3_0>; }; }; @@ -152,8 +152,8 @@ qcom,freq-domain = <&cpufreq_hw 1>; #cooling-cells = <2>; L2_400: l2-cache { - compatible = "cache"; - next-level-cache = <&L3_0>; + compatible = "cache"; + next-level-cache = <&L3_0>; }; }; @@ -166,8 +166,8 @@ qcom,freq-domain = <&cpufreq_hw 1>; #cooling-cells = <2>; L2_500: l2-cache { - compatible = "cache"; - next-level-cache = <&L3_0>; + compatible = "cache"; + next-level-cache = <&L3_0>; }; }; @@ -181,8 +181,8 @@ qcom,freq-domain = <&cpufreq_hw 1>; #cooling-cells = <2>; L2_600: l2-cache { - compatible = "cache"; - next-level-cache = <&L3_0>; + compatible = "cache"; + next-level-cache = <&L3_0>; }; }; @@ -195,8 +195,8 @@ qcom,freq-domain = <&cpufreq_hw 2>; #cooling-cells = <2>; L2_700: l2-cache { - compatible = "cache"; - next-level-cache = <&L3_0>; + compatible = "cache"; + next-level-cache = <&L3_0>; }; }; }; @@ -429,6 +429,13 @@ #mbox-cells = <2>; }; + rng: rng@793000 { + compatible = "qcom,prng-ee"; + reg = <0 0x00793000 0 0x1000>; + clocks = <&gcc GCC_PRNG_AHB_CLK>; + clock-names = "core"; + }; + qup_opp_table: qup-opp-table { compatible = "operating-points-v2"; @@ -456,6 +463,7 @@ <&gcc GCC_QUPV3_WRAP_2_S_AHB_CLK>; #address-cells = <2>; #size-cells = <2>; + iommus = <&apps_smmu 0x63 0x0>; ranges; status = "disabled"; @@ -662,6 +670,7 @@ <&gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; #address-cells = <2>; #size-cells = <2>; + iommus = <&apps_smmu 0x5a3 0x0>; ranges; status = "disabled"; @@ -924,6 +933,7 @@ <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; #address-cells = <2>; #size-cells = <2>; + iommus = <&apps_smmu 0x43 0x0>; ranges; status = "disabled"; @@ -1172,6 +1182,8 @@ power-domains = <&gcc UFS_PHY_GDSC>; + iommus = <&apps_smmu 0x0e0 0>, <&apps_smmu 0x4e0 0>; + clock-names = "core_clk", "bus_aggr_clk", @@ -1417,8 +1429,35 @@ mboxes = <&ipcc IPCC_CLIENT_SLPI IPCC_MPROC_SIGNAL_GLINK_QMP>; - label = "lpass"; + label = "slpi"; qcom,remote-pid = <3>; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "sdsp"; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@1 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <1>; + iommus = <&apps_smmu 0x0541 0x0>; + }; + + compute-cb@2 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <2>; + iommus = <&apps_smmu 0x0542 0x0>; + }; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + iommus = <&apps_smmu 0x0543 0x0>; + /* note: shared-cb = <4> in downstream */ + }; + }; }; }; @@ -1455,8 +1494,201 @@ mboxes = <&ipcc IPCC_CLIENT_CDSP IPCC_MPROC_SIGNAL_GLINK_QMP>; - label = "lpass"; + label = "cdsp"; qcom,remote-pid = <5>; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "cdsp"; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@1 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <1>; + iommus = <&apps_smmu 0x1001 0x0460>; + }; + + compute-cb@2 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <2>; + iommus = <&apps_smmu 0x1002 0x0460>; + }; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + iommus = <&apps_smmu 0x1003 0x0460>; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + iommus = <&apps_smmu 0x1004 0x0460>; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + iommus = <&apps_smmu 0x1005 0x0460>; + }; + + compute-cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + iommus = <&apps_smmu 0x1006 0x0460>; + }; + + compute-cb@7 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <7>; + iommus = <&apps_smmu 0x1007 0x0460>; + }; + + compute-cb@8 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <8>; + iommus = <&apps_smmu 0x1008 0x0460>; + }; + + /* note: secure cb9 in downstream */ + }; + }; + }; + + usb_1_hsphy: phy@88e3000 { + compatible = "qcom,sm8250-usb-hs-phy", + "qcom,usb-snps-hs-7nm-phy"; + reg = <0 0x088e3000 0 0x400>; + status = "disabled"; + #phy-cells = <0>; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "ref"; + + resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>; + }; + + usb_2_hsphy: phy@88e4000 { + compatible = "qcom,sm8250-usb-hs-phy", + "qcom,usb-snps-hs-7nm-phy"; + reg = <0 0x088e4000 0 0x400>; + status = "disabled"; + #phy-cells = <0>; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "ref"; + + resets = <&gcc GCC_QUSB2PHY_SEC_BCR>; + }; + + usb_1_qmpphy: phy@88e9000 { + compatible = "qcom,sm8250-qmp-usb3-phy"; + reg = <0 0x088e9000 0 0x200>, + <0 0x088e8000 0 0x20>; + reg-names = "reg-base", "dp_com"; + status = "disabled"; + #clock-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>, + <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>; + clock-names = "aux", "ref_clk_src", "com_aux"; + + resets = <&gcc GCC_USB3_DP_PHY_PRIM_BCR>, + <&gcc GCC_USB3_PHY_PRIM_BCR>; + reset-names = "phy", "common"; + + usb_1_ssphy: lanes@88e9200 { + reg = <0 0x088e9200 0 0x200>, + <0 0x088e9400 0 0x200>, + <0 0x088e9c00 0 0x400>, + <0 0x088e9600 0 0x200>, + <0 0x088e9800 0 0x200>, + <0 0x088e9a00 0 0x100>; + #phy-cells = <0>; + clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; + clock-names = "pipe0"; + clock-output-names = "usb3_phy_pipe_clk_src"; + }; + }; + + usb_2_qmpphy: phy@88eb000 { + compatible = "qcom,sm8250-qmp-usb3-uni-phy"; + reg = <0 0x088eb000 0 0x200>; + status = "disabled"; + #clock-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>, + <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_USB3_SEC_CLKREF_EN>, + <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>; + clock-names = "aux", "ref_clk_src", "ref", "com_aux"; + + resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR>, + <&gcc GCC_USB3_PHY_SEC_BCR>; + reset-names = "phy", "common"; + + usb_2_ssphy: lane@88eb200 { + reg = <0 0x088eb200 0 0x200>, + <0 0x088eb400 0 0x200>, + <0 0x088eb800 0 0x800>; + #phy-cells = <0>; + clocks = <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>; + clock-names = "pipe0"; + clock-output-names = "usb3_uni_phy_pipe_clk_src"; + }; + }; + + sdhc_2: sdhci@8804000 { + compatible = "qcom,sm8250-sdhci", "qcom,sdhci-msm-v5"; + reg = <0 0x08804000 0 0x1000>; + + interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hc_irq", "pwr_irq"; + + clocks = <&gcc GCC_SDCC2_AHB_CLK>, + <&gcc GCC_SDCC2_APPS_CLK>, + <&xo_board>; + clock-names = "iface", "core", "xo"; + iommus = <&apps_smmu 0x4a0 0x0>; + qcom,dll-config = <0x0007642c>; + qcom,ddr-config = <0x80040868>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&sdhc2_opp_table>; + + status = "disabled"; + + sdhc2_opp_table: sdhc2-opp-table { + compatible = "operating-points-v2"; + + opp-19200000 { + opp-hz = /bits/ 64 <19200000>; + required-opps = <&rpmhpd_opp_min_svs>; + }; + + opp-50000000 { + opp-hz = /bits/ 64 <50000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-202000000 { + opp-hz = /bits/ 64 <202000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; }; }; @@ -1481,6 +1713,96 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; + usb_1: usb@a6f8800 { + compatible = "qcom,sm8250-dwc3", "qcom,dwc3"; + reg = <0 0x0a6f8800 0 0x400>; + status = "disabled"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + dma-ranges; + + clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>, + <&gcc GCC_USB30_PRIM_MASTER_CLK>, + <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>, + <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_PRIM_SLEEP_CLK>, + <&gcc GCC_USB3_SEC_CLKREF_EN>; + clock-names = "cfg_noc", "core", "iface", "mock_utmi", + "sleep", "xo"; + + assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_PRIM_MASTER_CLK>; + assigned-clock-rates = <19200000>, <200000000>; + + interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 14 IRQ_TYPE_EDGE_BOTH>, + <&pdc 15 IRQ_TYPE_EDGE_BOTH>, + <&pdc 17 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hs_phy_irq", "dp_hs_phy_irq", + "dm_hs_phy_irq", "ss_phy_irq"; + + power-domains = <&gcc USB30_PRIM_GDSC>; + + resets = <&gcc GCC_USB30_PRIM_BCR>; + + usb_1_dwc3: dwc3@a600000 { + compatible = "snps,dwc3"; + reg = <0 0x0a600000 0 0xcd00>; + interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; + iommus = <&apps_smmu 0x0 0x0>; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + phys = <&usb_1_hsphy>, <&usb_1_ssphy>; + phy-names = "usb2-phy", "usb3-phy"; + }; + }; + + usb_2: usb@a8f8800 { + compatible = "qcom,sm8250-dwc3", "qcom,dwc3"; + reg = <0 0x0a8f8800 0 0x400>; + status = "disabled"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + dma-ranges; + + clocks = <&gcc GCC_CFG_NOC_USB3_SEC_AXI_CLK>, + <&gcc GCC_USB30_SEC_MASTER_CLK>, + <&gcc GCC_AGGRE_USB3_SEC_AXI_CLK>, + <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_SEC_SLEEP_CLK>, + <&gcc GCC_USB3_SEC_CLKREF_EN>; + clock-names = "cfg_noc", "core", "iface", "mock_utmi", + "sleep", "xo"; + + assigned-clocks = <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_SEC_MASTER_CLK>; + assigned-clock-rates = <19200000>, <200000000>; + + interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 12 IRQ_TYPE_EDGE_BOTH>, + <&pdc 13 IRQ_TYPE_EDGE_BOTH>, + <&pdc 16 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hs_phy_irq", "dp_hs_phy_irq", + "dm_hs_phy_irq", "ss_phy_irq"; + + power-domains = <&gcc USB30_SEC_GDSC>; + + resets = <&gcc GCC_USB30_SEC_BCR>; + + usb_2_dwc3: dwc3@a800000 { + compatible = "snps,dwc3"; + reg = <0 0x0a800000 0 0xcd00>; + interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>; + iommus = <&apps_smmu 0x20 0>; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + phys = <&usb_2_hsphy>, <&usb_2_ssphy>; + phy-names = "usb2-phy", "usb3-phy"; + }; + }; + pdc: interrupt-controller@b220000 { compatible = "qcom,sm8250-pdc", "qcom,pdc"; reg = <0 0x0b220000 0 0x30000>, <0 0x17c000f0 0 0x60>; @@ -2156,6 +2478,111 @@ }; }; + apps_smmu: iommu@15000000 { + compatible = "qcom,sm8250-smmu-500", "arm,mmu-500"; + reg = <0 0x15000000 0 0x100000>; + #iommu-cells = <2>; + #global-interrupts = <2>; + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 690 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 691 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 692 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 693 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 694 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 695 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 696 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 697 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>; + }; + adsp: remoteproc@17300000 { compatible = "qcom,sm8250-adsp-pas"; reg = <0 0x17300000 0 0x100>; @@ -2192,6 +2619,32 @@ label = "lpass"; qcom,remote-pid = <2>; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "adsp"; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + iommus = <&apps_smmu 0x1803 0x0>; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + iommus = <&apps_smmu 0x1804 0x0>; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + iommus = <&apps_smmu 0x1805 0x0>; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile index dffefe030a76..3b8b03705917 100644 --- a/arch/arm64/boot/dts/renesas/Makefile +++ b/arch/arm64/boot/dts/renesas/Makefile @@ -3,6 +3,7 @@ dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-beacon-rzg2m-kit.dtb dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m.dtb dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m-ex.dtb dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m-ex-idk-1110wr.dtb +dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m-ex-mipi-2.1.dtb dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m-rev2.dtb dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m-rev2-ex.dtb dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m-rev2-ex-idk-1110wr.dtb @@ -10,6 +11,7 @@ dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m-rev2-ex-idk-1110wr.dtb dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-hihope-rzg2n.dtb dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-hihope-rzg2n-ex.dtb dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-hihope-rzg2n-ex-idk-1110wr.dtb +dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-hihope-rzg2n-ex-mipi-2.1.dtb dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-hihope-rzg2n-rev2.dtb dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-hihope-rzg2n-rev2-ex.dtb dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-hihope-rzg2n-rev2-ex-idk-1110wr.dtb @@ -22,6 +24,7 @@ dtb-$(CONFIG_ARCH_R8A774C0) += r8a774c0-ek874-mipi-2.1.dtb dtb-$(CONFIG_ARCH_R8A774E1) += r8a774e1-hihope-rzg2h.dtb dtb-$(CONFIG_ARCH_R8A774E1) += r8a774e1-hihope-rzg2h-ex.dtb dtb-$(CONFIG_ARCH_R8A774E1) += r8a774e1-hihope-rzg2h-ex-idk-1110wr.dtb +dtb-$(CONFIG_ARCH_R8A774E1) += r8a774e1-hihope-rzg2h-ex-mipi-2.1.dtb dtb-$(CONFIG_ARCH_R8A77950) += r8a77950-salvator-x.dtb dtb-$(CONFIG_ARCH_R8A77950) += r8a77950-ulcb.dtb @@ -39,6 +42,7 @@ dtb-$(CONFIG_ARCH_R8A77960) += r8a77960-ulcb-kf.dtb dtb-$(CONFIG_ARCH_R8A77961) += r8a77961-salvator-xs.dtb dtb-$(CONFIG_ARCH_R8A77961) += r8a77961-ulcb.dtb +dtb-$(CONFIG_ARCH_R8A77961) += r8a77961-ulcb-kf.dtb dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-x.dtb dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-xs.dtb diff --git a/arch/arm64/boot/dts/renesas/aistarvision-mipi-adapter-2.1.dtsi b/arch/arm64/boot/dts/renesas/aistarvision-mipi-adapter-2.1.dtsi index dac6ff49020f..7ce986f0a06f 100644 --- a/arch/arm64/boot/dts/renesas/aistarvision-mipi-adapter-2.1.dtsi +++ b/arch/arm64/boot/dts/renesas/aistarvision-mipi-adapter-2.1.dtsi @@ -61,7 +61,7 @@ }; }; -&MIPI_PARENT_I2C { +&MIPI_OV5645_PARENT_I2C { ov5645: ov5645@3c { compatible = "ovti,ov5645"; reg = <0x3c>; @@ -77,7 +77,9 @@ }; }; }; +}; +&MIPI_IMX219_PARENT_I2C { imx219: imx219@10 { compatible = "sony,imx219"; reg = <0x10>; diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi index 66c9153b3101..e66b5b36e489 100644 --- a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi +++ b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi @@ -223,6 +223,29 @@ #clock-cells = <0>; clock-frequency = <25000000>; }; + + connector { + compatible = "usb-c-connector"; + label = "USB-C"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + hs_ep: endpoint { + remote-endpoint = <&usb3_hs_ep>; + }; + }; + port@1 { + reg = <1>; + ss_ep: endpoint { + remote-endpoint = <&hd3ss3220_in_ep>; + }; + }; + }; + }; }; &audio_clk_a { @@ -427,20 +450,19 @@ interrupt-parent = <&gpio6>; interrupts = <4 IRQ_TYPE_LEVEL_LOW>; - connector { - compatible = "usb-c-connector"; - label = "USB-C"; - data-role = "dual"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@1 { - reg = <1>; - hd3ss3220_ep: endpoint { - remote-endpoint = <&usb3_role_switch>; - }; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + hd3ss3220_in_ep: endpoint { + remote-endpoint = <&ss_ep>; + }; + }; + port@1 { + reg = <1>; + hd3ss3220_out_ep: endpoint { + remote-endpoint = <&usb3_role_switch>; }; }; }; @@ -714,9 +736,20 @@ status = "okay"; usb-role-switch; - port { - usb3_role_switch: endpoint { - remote-endpoint = <&hd3ss3220_ep>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + usb3_hs_ep: endpoint { + remote-endpoint = <&hs_ep>; + }; + }; + port@1 { + reg = <1>; + usb3_role_switch: endpoint { + remote-endpoint = <&hd3ss3220_out_ep>; + }; }; }; }; diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi index 97272f5fa0ab..8ac167aa18f0 100644 --- a/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi +++ b/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi @@ -55,7 +55,8 @@ pinctrl-0 = <&avb_pins>; pinctrl-names = "default"; phy-handle = <&phy0>; - phy-mode = "rgmii-id"; + rx-internal-delay-ps = <1800>; + tx-internal-delay-ps = <2000>; status = "okay"; phy0: ethernet-phy@0 { diff --git a/arch/arm64/boot/dts/renesas/cat875.dtsi b/arch/arm64/boot/dts/renesas/cat875.dtsi index 33daa9570684..801ea54b027c 100644 --- a/arch/arm64/boot/dts/renesas/cat875.dtsi +++ b/arch/arm64/boot/dts/renesas/cat875.dtsi @@ -21,7 +21,6 @@ status = "okay"; phy0: ethernet-phy@0 { - rxc-skew-ps = <1500>; reg = <0>; interrupt-parent = <&gpio2>; interrupts = <21 IRQ_TYPE_LEVEL_LOW>; diff --git a/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi b/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi index 3046c07a288b..929f4a1d3f90 100644 --- a/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi +++ b/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi @@ -91,7 +91,11 @@ #clock-cells = <1>; clock-frequency = <12288000 11289600>; - /* update <audio_clk_b> to <cs2000> */ + /* + * Update <audio_clk_b> to <cs2000> + * Switch SW2404 should be at position 1 so that clock from + * CS2000 is connected to AUDIO_CLKB_A + */ clocks = <&cpg CPG_MOD 1005>, <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>, <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>, diff --git a/arch/arm64/boot/dts/renesas/hihope-rzg2-ex-aistarvision-mipi-adapter-2.1.dtsi b/arch/arm64/boot/dts/renesas/hihope-rzg2-ex-aistarvision-mipi-adapter-2.1.dtsi new file mode 100644 index 000000000000..c62ddb9b2ba5 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/hihope-rzg2-ex-aistarvision-mipi-adapter-2.1.dtsi @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for the HiHope RZ/G2[HMN] MIPI common parts + * + * Copyright (C) 2020 Renesas Electronics Corp. + */ + +#define MIPI_OV5645_PARENT_I2C i2c2 +#define MIPI_IMX219_PARENT_I2C i2c3 +#include "aistarvision-mipi-adapter-2.1.dtsi" + +&csi20 { + status = "okay"; + + ports { + port@0 { + reg = <0>; + csi20_in: endpoint { + clock-lanes = <0>; + data-lanes = <1 2>; + remote-endpoint = <&ov5645_ep>; + }; + }; + }; +}; + +&csi40 { + status = "okay"; + + ports { + port@0 { + reg = <0>; + csi40_in: endpoint { + clock-lanes = <0>; + data-lanes = <1 2>; + remote-endpoint = <&imx219_ep>; + }; + }; + }; +}; + +&i2c3 { + pinctrl-0 = <&i2c3_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&imx219 { + port { + imx219_ep: endpoint { + clock-lanes = <0>; + data-lanes = <1 2>; + link-frequencies = /bits/ 64 <456000000>; + remote-endpoint = <&csi40_in>; + }; + }; +}; + +&ov5645 { + enable-gpios = <&gpio6 4 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio6 8 GPIO_ACTIVE_LOW>; + + port { + ov5645_ep: endpoint { + clock-lanes = <0>; + data-lanes = <1 2>; + remote-endpoint = <&csi20_in>; + }; + }; +}; + +&pfc { + i2c3_pins: i2c3 { + groups = "i2c3"; + function = "i2c3"; + }; +}; + +&vin0 { + status = "okay"; +}; + +&vin1 { + status = "okay"; +}; + +&vin2 { + status = "okay"; +}; + +&vin3 { + status = "okay"; +}; + +&vin4 { + status = "okay"; +}; + +&vin5 { + status = "okay"; +}; + +&vin6 { + status = "okay"; +}; + +&vin7 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/hihope-rzg2-ex.dtsi b/arch/arm64/boot/dts/renesas/hihope-rzg2-ex.dtsi index 178401a34cbf..202c4fc88bd5 100644 --- a/arch/arm64/boot/dts/renesas/hihope-rzg2-ex.dtsi +++ b/arch/arm64/boot/dts/renesas/hihope-rzg2-ex.dtsi @@ -19,11 +19,10 @@ pinctrl-0 = <&avb_pins>; pinctrl-names = "default"; phy-handle = <&phy0>; - phy-mode = "rgmii-txid"; + tx-internal-delay-ps = <2000>; status = "okay"; phy0: ethernet-phy@0 { - rxc-skew-ps = <1500>; reg = <0>; interrupt-parent = <&gpio2>; interrupts = <11 IRQ_TYPE_LEVEL_LOW>; diff --git a/arch/arm64/boot/dts/renesas/r8a774a1-hihope-rzg2m-ex-mipi-2.1.dts b/arch/arm64/boot/dts/renesas/r8a774a1-hihope-rzg2m-ex-mipi-2.1.dts new file mode 100644 index 000000000000..5c91e0d7e67b --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a774a1-hihope-rzg2m-ex-mipi-2.1.dts @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for the HiHope RZ/G2M board + * connected with aistarvision-mipi-v2-adapter board + * + * Copyright (C) 2020 Renesas Electronics Corp. + */ + +/dts-v1/; +#include "r8a774a1-hihope-rzg2m-ex.dts" +#include "hihope-rzg2-ex-aistarvision-mipi-adapter-2.1.dtsi" + +/ { + model = "HopeRun HiHope RZ/G2M with sub board connected with aistarvision-mipi-v2-adapter board"; + compatible = "hoperun,hihope-rzg2m", "renesas,r8a774a1"; +}; + +/* + * On RZ/G2M SoC LSI V1.3 CSI40 supports only 4 lane mode. + * HiHope RZ/G2M Rev.4.0 board is based on LSI V1.3 so disable csi40 and + * imx219 as the imx219 endpoint driver supports only 2 lane mode. + */ +&csi40 { + status = "disabled"; +}; + +&imx219 { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi index c15f1c571eb0..d37ec42a1caa 100644 --- a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi @@ -1115,6 +1115,8 @@ power-domains = <&sysc R8A774A1_PD_ALWAYS_ON>; resets = <&cpg 812>; phy-mode = "rgmii"; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <0>; iommus = <&ipmmu_ds0 16>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/renesas/r8a774b1-hihope-rzg2n-ex-mipi-2.1.dts b/arch/arm64/boot/dts/renesas/r8a774b1-hihope-rzg2n-ex-mipi-2.1.dts new file mode 100644 index 000000000000..ce8e3bcc7dc9 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a774b1-hihope-rzg2n-ex-mipi-2.1.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for the HiHope RZ/G2N board + * connected with aistarvision-mipi-v2-adapter board + * + * Copyright (C) 2020 Renesas Electronics Corp. + */ + +/dts-v1/; +#include "r8a774b1-hihope-rzg2n-ex.dts" +#include "hihope-rzg2-ex-aistarvision-mipi-adapter-2.1.dtsi" + +/ { + model = "HopeRun HiHope RZ/G2N with sub board connected with aistarvision-mipi-v2-adapter board"; + compatible = "hoperun,hihope-rzg2n", "renesas,r8a774b1"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi index 39a1a26ffb54..83523916d360 100644 --- a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi @@ -989,6 +989,8 @@ power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>; resets = <&cpg 812>; phy-mode = "rgmii"; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <0>; iommus = <&ipmmu_ds0 16>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts b/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts index 26aee004a44e..ea87cb5a459c 100644 --- a/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts +++ b/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts @@ -129,6 +129,29 @@ #clock-cells = <0>; clock-frequency = <74250000>; }; + + connector { + compatible = "usb-c-connector"; + label = "USB-C"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + hs_ep: endpoint { + remote-endpoint = <&usb3_hs_ep>; + }; + }; + port@1 { + reg = <1>; + ss_ep: endpoint { + remote-endpoint = <&hd3ss3220_in_ep>; + }; + }; + }; + }; }; &audio_clk_a { @@ -186,20 +209,19 @@ interrupt-parent = <&gpio6>; interrupts = <3 IRQ_TYPE_LEVEL_LOW>; - connector { - compatible = "usb-c-connector"; - label = "USB-C"; - data-role = "dual"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@1 { - reg = <1>; - hd3ss3220_ep: endpoint { - remote-endpoint = <&usb3_role_switch>; - }; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + hd3ss3220_in_ep: endpoint { + remote-endpoint = <&ss_ep>; + }; + }; + port@1 { + reg = <1>; + hd3ss3220_out_ep: endpoint { + remote-endpoint = <&usb3_role_switch>; }; }; }; @@ -405,9 +427,20 @@ status = "okay"; usb-role-switch; - port { - usb3_role_switch: endpoint { - remote-endpoint = <&hd3ss3220_ep>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + usb3_hs_ep: endpoint { + remote-endpoint = <&hs_ep>; + }; + }; + port@1 { + reg = <1>; + usb3_role_switch: endpoint { + remote-endpoint = <&hd3ss3220_out_ep>; + }; }; }; }; diff --git a/arch/arm64/boot/dts/renesas/r8a774c0-ek874-mipi-2.1.dts b/arch/arm64/boot/dts/renesas/r8a774c0-ek874-mipi-2.1.dts index f0829e905506..e7b4a929bb17 100644 --- a/arch/arm64/boot/dts/renesas/r8a774c0-ek874-mipi-2.1.dts +++ b/arch/arm64/boot/dts/renesas/r8a774c0-ek874-mipi-2.1.dts @@ -8,7 +8,8 @@ /dts-v1/; #include "r8a774c0-ek874.dts" -#define MIPI_PARENT_I2C i2c3 +#define MIPI_OV5645_PARENT_I2C i2c3 +#define MIPI_IMX219_PARENT_I2C i2c3 #include "aistarvision-mipi-adapter-2.1.dtsi" / { diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi index f27d9b2eb996..e0e54342cd4c 100644 --- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi @@ -960,6 +960,7 @@ power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>; resets = <&cpg 812>; phy-mode = "rgmii"; + rx-internal-delay-ps = <0>; iommus = <&ipmmu_ds0 16>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h-ex-mipi-2.1.dts b/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h-ex-mipi-2.1.dts new file mode 100644 index 000000000000..46adb6efb5e6 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h-ex-mipi-2.1.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for the HiHope RZ/G2H board + * connected with aistarvision-mipi-v2-adapter board + * + * Copyright (C) 2020 Renesas Electronics Corp. + */ + +/dts-v1/; +#include "r8a774e1-hihope-rzg2h-ex.dts" +#include "hihope-rzg2-ex-aistarvision-mipi-adapter-2.1.dtsi" + +/ { + model = "HopeRun HiHope RZ/G2H with sub board connected with aistarvision-mipi-v2-adapter board"; + compatible = "hoperun,hihope-rzg2h", "renesas,r8a774e1"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi index c29643442e91..1333b02d623a 100644 --- a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi @@ -1218,6 +1218,8 @@ power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; resets = <&cpg 812>; phy-mode = "rgmii"; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <0>; iommus = <&ipmmu_ds0 16>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/renesas/r8a77951-salvator-xs.dts b/arch/arm64/boot/dts/renesas/r8a77951-salvator-xs.dts index cef9da4376a3..e5922329a4b8 100644 --- a/arch/arm64/boot/dts/renesas/r8a77951-salvator-xs.dts +++ b/arch/arm64/boot/dts/renesas/r8a77951-salvator-xs.dts @@ -118,7 +118,7 @@ }; &pca9654 { - pcie_sata_switch { + pcie-sata-switch-hog { gpio-hog; gpios = <7 GPIO_ACTIVE_HIGH>; output-low; /* enable SATA by default */ diff --git a/arch/arm64/boot/dts/renesas/r8a77951.dtsi b/arch/arm64/boot/dts/renesas/r8a77951.dtsi index 18ce0face72b..9d60bcf69e4f 100644 --- a/arch/arm64/boot/dts/renesas/r8a77951.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77951.dtsi @@ -1250,6 +1250,8 @@ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; resets = <&cpg 812>; phy-mode = "rgmii"; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <0>; iommus = <&ipmmu_ds0 16>; #address-cells = <1>; #size-cells = <0>; @@ -2725,6 +2727,44 @@ status = "disabled"; }; + pciec0_ep: pcie-ep@fe000000 { + compatible = "renesas,r8a7795-pcie-ep", + "renesas,rcar-gen3-pcie-ep"; + reg = <0x0 0xfe000000 0 0x80000>, + <0x0 0xfe100000 0 0x100000>, + <0x0 0xfe200000 0 0x200000>, + <0x0 0x30000000 0 0x8000000>, + <0x0 0x38000000 0 0x8000000>; + reg-names = "apb-base", "memory0", "memory1", "memory2", "memory3"; + interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 319>; + clock-names = "pcie"; + resets = <&cpg 319>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + status = "disabled"; + }; + + pciec1_ep: pcie-ep@ee800000 { + compatible = "renesas,r8a7795-pcie-ep", + "renesas,rcar-gen3-pcie-ep"; + reg = <0x0 0xee800000 0 0x80000>, + <0x0 0xee900000 0 0x100000>, + <0x0 0xeea00000 0 0x200000>, + <0x0 0xc0000000 0 0x8000000>, + <0x0 0xc8000000 0 0x8000000>; + reg-names = "apb-base", "memory0", "memory1", "memory2", "memory3"; + interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 318>; + clock-names = "pcie"; + resets = <&cpg 318>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + status = "disabled"; + }; + imr-lx4@fe860000 { compatible = "renesas,r8a7795-imr-lx4", "renesas,imr-lx4"; diff --git a/arch/arm64/boot/dts/renesas/r8a77960.dtsi b/arch/arm64/boot/dts/renesas/r8a77960.dtsi index f379c8d1511d..53b9aa26c9b1 100644 --- a/arch/arm64/boot/dts/renesas/r8a77960.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77960.dtsi @@ -1126,6 +1126,8 @@ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; resets = <&cpg 812>; phy-mode = "rgmii"; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <0>; iommus = <&ipmmu_ds0 16>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/renesas/r8a77961-ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a77961-ulcb-kf.dts new file mode 100644 index 000000000000..6ec958348eb0 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a77961-ulcb-kf.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for the M3ULCB Kingfisher board + * + * Copyright (C) 2020 Eugeniu Rosca <rosca.eugeniu@gmail.com> + */ + +#include "r8a77961-ulcb.dts" +#include "ulcb-kf.dtsi" + +/ { + model = "Renesas M3ULCB Kingfisher board based on r8a77961"; + compatible = "shimafuji,kingfisher", "renesas,m3ulcb", + "renesas,r8a77961"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi index 1ba30313c8b8..4b737c616257 100644 --- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi @@ -1012,11 +1012,23 @@ power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; resets = <&cpg 812>; phy-mode = "rgmii"; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <0>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; }; + can0: can@e6c30000 { + reg = <0 0xe6c30000 0 0x1000>; + /* placeholder */ + }; + + can1: can@e6c38000 { + reg = <0 0xe6c38000 0 0x1000>; + /* placeholder */ + }; + pwm0: pwm@e6e30000 { compatible = "renesas,pwm-r8a77961", "renesas,pwm-rcar"; reg = <0 0xe6e30000 0 8>; @@ -1187,6 +1199,68 @@ status = "disabled"; }; + msiof0: spi@e6e90000 { + compatible = "renesas,msiof-r8a77961", + "renesas,rcar-gen3-msiof"; + reg = <0 0xe6e90000 0 0x0064>; + interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 211>; + dmas = <&dmac1 0x41>, <&dmac1 0x40>, + <&dmac2 0x41>, <&dmac2 0x40>; + dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 211>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof1: spi@e6ea0000 { + compatible = "renesas,msiof-r8a77961", + "renesas,rcar-gen3-msiof"; + reg = <0 0xe6ea0000 0 0x0064>; + interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 210>; + dmas = <&dmac1 0x43>, <&dmac1 0x42>, + <&dmac2 0x43>, <&dmac2 0x42>; + dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 210>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof2: spi@e6c00000 { + compatible = "renesas,msiof-r8a77961", + "renesas,rcar-gen3-msiof"; + reg = <0 0xe6c00000 0 0x0064>; + interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 209>; + dmas = <&dmac0 0x45>, <&dmac0 0x44>; + dma-names = "tx", "rx"; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 209>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof3: spi@e6c10000 { + compatible = "renesas,msiof-r8a77961", + "renesas,rcar-gen3-msiof"; + reg = <0 0xe6c10000 0 0x0064>; + interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 208>; + dmas = <&dmac0 0x47>, <&dmac0 0x46>; + dma-names = "tx", "rx"; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 208>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + vin0: video@e6ef0000 { reg = <0 0xe6ef0000 0 0x1000>; /* placeholder */ diff --git a/arch/arm64/boot/dts/renesas/r8a77965-salvator-xs.dts b/arch/arm64/boot/dts/renesas/r8a77965-salvator-xs.dts index 5cef64605464..d7e621101af7 100644 --- a/arch/arm64/boot/dts/renesas/r8a77965-salvator-xs.dts +++ b/arch/arm64/boot/dts/renesas/r8a77965-salvator-xs.dts @@ -55,7 +55,7 @@ }; &pca9654 { - pcie_sata_switch { + pcie-sata-switch-hog { gpio-hog; gpios = <7 GPIO_ACTIVE_HIGH>; output-low; /* enable SATA by default */ diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi index c355460e5f7f..4a913df17b1d 100644 --- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi @@ -988,6 +988,8 @@ power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; resets = <&cpg 812>; phy-mode = "rgmii"; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <0>; iommus = <&ipmmu_ds0 16>; #address-cells = <1>; #size-cells = <0>; @@ -1550,6 +1552,126 @@ }; }; + drif00: rif@e6f40000 { + compatible = "renesas,r8a77965-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f40000 0 0x84>; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 515>; + clock-names = "fck"; + dmas = <&dmac1 0x20>, <&dmac2 0x20>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; + resets = <&cpg 515>; + renesas,bonding = <&drif01>; + status = "disabled"; + }; + + drif01: rif@e6f50000 { + compatible = "renesas,r8a77965-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f50000 0 0x84>; + interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 514>; + clock-names = "fck"; + dmas = <&dmac1 0x22>, <&dmac2 0x22>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; + resets = <&cpg 514>; + renesas,bonding = <&drif00>; + status = "disabled"; + }; + + drif10: rif@e6f60000 { + compatible = "renesas,r8a77965-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f60000 0 0x84>; + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 513>; + clock-names = "fck"; + dmas = <&dmac1 0x24>, <&dmac2 0x24>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; + resets = <&cpg 513>; + renesas,bonding = <&drif11>; + status = "disabled"; + }; + + drif11: rif@e6f70000 { + compatible = "renesas,r8a77965-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f70000 0 0x84>; + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 512>; + clock-names = "fck"; + dmas = <&dmac1 0x26>, <&dmac2 0x26>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; + resets = <&cpg 512>; + renesas,bonding = <&drif10>; + status = "disabled"; + }; + + drif20: rif@e6f80000 { + compatible = "renesas,r8a77965-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f80000 0 0x84>; + interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 511>; + clock-names = "fck"; + dmas = <&dmac1 0x28>, <&dmac2 0x28>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; + resets = <&cpg 511>; + renesas,bonding = <&drif21>; + status = "disabled"; + }; + + drif21: rif@e6f90000 { + compatible = "renesas,r8a77965-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f90000 0 0x84>; + interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 510>; + clock-names = "fck"; + dmas = <&dmac1 0x2a>, <&dmac2 0x2a>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; + resets = <&cpg 510>; + renesas,bonding = <&drif20>; + status = "disabled"; + }; + + drif30: rif@e6fa0000 { + compatible = "renesas,r8a77965-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6fa0000 0 0x84>; + interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 509>; + clock-names = "fck"; + dmas = <&dmac1 0x2c>, <&dmac2 0x2c>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; + resets = <&cpg 509>; + renesas,bonding = <&drif31>; + status = "disabled"; + }; + + drif31: rif@e6fb0000 { + compatible = "renesas,r8a77965-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6fb0000 0 0x84>; + interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 508>; + clock-names = "fck"; + dmas = <&dmac1 0x2e>, <&dmac2 0x2e>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>; + resets = <&cpg 508>; + renesas,bonding = <&drif30>; + status = "disabled"; + }; + rcar_sound: sound@ec500000 { /* * #sound-dai-cells is required diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts index 5c28f303e911..874a7fc2730b 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts +++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts @@ -81,7 +81,8 @@ renesas,no-ether-link; phy-handle = <&phy0>; - phy-mode = "rgmii-id"; + rx-internal-delay-ps = <1800>; + tx-internal-delay-ps = <2000>; status = "okay"; phy0: ethernet-phy@0 { diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts index 668a1ece9af0..7417cf5fea0f 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts +++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts @@ -102,7 +102,8 @@ renesas,no-ether-link; phy-handle = <&phy0>; - phy-mode = "rgmii-id"; + rx-internal-delay-ps = <1800>; + tx-internal-delay-ps = <2000>; status = "okay"; phy0: ethernet-phy@0 { diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi index baf8cc821564..5a5d5649332a 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi @@ -615,6 +615,8 @@ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>; resets = <&cpg 812>; phy-mode = "rgmii"; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <0>; iommus = <&ipmmu_rt 3>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi index d6cae90d7fd9..ec7ca72399ec 100644 --- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi @@ -667,6 +667,8 @@ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>; resets = <&cpg 812>; phy-mode = "rgmii"; + rx-internal-delay-ps = <0>; + tx-internal-delay-ps = <2000>; iommus = <&ipmmu_ds1 33>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index 33d7e657bd9c..87d41bc076a9 100644 --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi @@ -938,6 +938,7 @@ power-domains = <&sysc R8A77990_PD_ALWAYS_ON>; resets = <&cpg 812>; phy-mode = "rgmii"; + rx-internal-delay-ps = <0>; iommus = <&ipmmu_ds0 16>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi index cd7ca9774196..e1af7c4782f4 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi @@ -628,6 +628,7 @@ power-domains = <&sysc R8A77995_PD_ALWAYS_ON>; resets = <&cpg 812>; phy-mode = "rgmii"; + rx-internal-delay-ps = <1800>; iommus = <&ipmmu_ds0 16>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/renesas/salvator-common.dtsi b/arch/arm64/boot/dts/renesas/salvator-common.dtsi index 1bf77957d2c2..6c643ed74fc5 100644 --- a/arch/arm64/boot/dts/renesas/salvator-common.dtsi +++ b/arch/arm64/boot/dts/renesas/salvator-common.dtsi @@ -324,7 +324,7 @@ pinctrl-0 = <&avb_pins>; pinctrl-names = "default"; phy-handle = <&phy0>; - phy-mode = "rgmii-txid"; + tx-internal-delay-ps = <2000>; status = "okay"; phy0: ethernet-phy@0 { diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi index 202177706cde..e9ed2597f1c2 100644 --- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi +++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi @@ -143,49 +143,49 @@ interrupt-parent = <&gpio6>; interrupts = <8 IRQ_TYPE_EDGE_FALLING>; - audio_out_off { + audio-out-off-hog { gpio-hog; gpios = <0 GPIO_ACTIVE_HIGH>; /* P00 */ output-high; line-name = "Audio_Out_OFF"; }; - hub_pwen { + hub-pwen-hog { gpio-hog; gpios = <6 GPIO_ACTIVE_HIGH>; output-high; line-name = "HUB pwen"; }; - hub_rst { + hub-rst-hog { gpio-hog; gpios = <7 GPIO_ACTIVE_HIGH>; output-high; line-name = "HUB rst"; }; - otg_extlpn { + otg-extlpn-hog { gpio-hog; gpios = <9 GPIO_ACTIVE_HIGH>; output-high; line-name = "OTG EXTLPn"; }; - otg_offvbusn { + otg-offvbusn-hog { gpio-hog; gpios = <8 GPIO_ACTIVE_HIGH>; output-low; line-name = "OTG OFFVBUSn"; }; - sd-wifi-mux { + sd-wifi-mux-hog { gpio-hog; gpios = <5 GPIO_ACTIVE_HIGH>; output-low; /* Connect WL1837 */ line-name = "SD WiFi mux"; }; - snd_rst { + snd-rst-hog { gpio-hog; gpios = <15 GPIO_ACTIVE_HIGH>; /* P17 */ output-high; diff --git a/arch/arm64/boot/dts/renesas/ulcb.dtsi b/arch/arm64/boot/dts/renesas/ulcb.dtsi index a2e085db87c5..8f8d7371d8e2 100644 --- a/arch/arm64/boot/dts/renesas/ulcb.dtsi +++ b/arch/arm64/boot/dts/renesas/ulcb.dtsi @@ -144,7 +144,7 @@ pinctrl-0 = <&avb_pins>; pinctrl-names = "default"; phy-handle = <&phy0>; - phy-mode = "rgmii-txid"; + tx-internal-delay-ps = <2000>; status = "okay"; phy0: ethernet-phy@0 { diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index 26661c7b736b..1ab55a124a87 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -1,5 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-ctouch2.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-ctouch2-of10.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-edimm2.2.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-roc-cc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a95x-z2.dtb @@ -26,6 +29,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-hugsun-x99.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge-captain.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge-v.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-kobol-helios64.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-leez-p710.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopc-t4.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-m4.dtb diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi new file mode 100644 index 000000000000..08b0b9fbcbc9 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Engicam srl + * Copyright (c) 2020 Amarula Solutions + * Copyright (c) 2020 Amarula Solutions(India) + */ + +/ { + vcc5v0_sys: vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; /* +5V */ + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&xin32k>; + clock-names = "ext_clock"; + post-power-on-delay-ms = <80>; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + }; + + vcc3v3_btreg: vcc3v3-btreg { + compatible = "regulator-gpio"; + enable-active-high; + pinctrl-names = "default"; + pinctrl-0 = <&bt_enable_h>; + regulator-name = "btreg-gpio-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + states = <3300000 0x0>; + }; + + vcc3v3_rf_aux_mod: vcc3v3-rf-aux-mod { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_rf_aux_mod"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc5v0_sys>; + }; + + xin32k: xin32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "xin32k"; + }; +}; + +&sdio { + #address-cells = <1>; + #size-cells = <0>; + bus-width = <4>; + clock-frequency = <50000000>; + cap-sdio-irq; + cap-sd-highspeed; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + sd-uhs-sdr104; + status = "okay"; + + brcmf: wifi@1 { + compatible = "brcm,bcm4329-fmac"; + reg = <1>; + }; +}; + +&gmac { + clock_in_out = "output"; + phy-supply = <&vcc_3v3>; /* +3V3_SOM */ + snps,reset-active-low; + snps,reset-delays-us = <0 50000 50000>; + snps,reset-gpio = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&pwm0 { + status = "okay"; +}; + +&sdmmc { + cap-sd-highspeed; + card-detect-delay = <800>; + vmmc-supply = <&vcc_3v3>; /* +3V3_SOM */ + vqmmc-supply = <&vcc_3v3>; + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +&uart2 { + pinctrl-0 = <&uart2m1_xfer>; + status = "okay"; +}; + +&usb20_otg { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi new file mode 100644 index 000000000000..bf10a3d29fca --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Engicam srl + * Copyright (c) 2020 Amarula Solutions + * Copyright (c) 2020 Amarula Solutions(India) + */ + +#include "px30-engicam-common.dtsi" + +&pinctrl { + bt { + bt_enable_h: bt-enable-h { + rockchip,pins = <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&sdio_pwrseq { + reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; +}; + +&vcc3v3_btreg { + enable-gpio = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>; +}; diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-edimm2.2.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-edimm2.2.dtsi new file mode 100644 index 000000000000..449b8eb6454e --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/px30-engicam-edimm2.2.dtsi @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Engicam srl + * Copyright (c) 2020 Amarula Solutions(India) + */ + +#include "px30-engicam-common.dtsi" + +/ { + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm0 0 25000 0>; + }; + + panel { + compatible = "yes-optoelectronics,ytc700tlag-05-201c"; + backlight = <&backlight>; + data-mapping = "vesa-24"; + power-supply = <&vcc3v3_lcd>; + + port { + panel_in_lvds: endpoint { + remote-endpoint = <&lvds_out_panel>; + }; + }; + }; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi_dphy { + status = "okay"; +}; + +/* LVDS_B(secondary) */ +&lvds { + status = "okay"; + + ports { + port@1 { + reg = <1>; + + lvds_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds>; + }; + }; + }; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2-of10.dts b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2-of10.dts new file mode 100644 index 000000000000..47aa30505a42 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2-of10.dts @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd + * Copyright (c) 2020 Engicam srl + * Copyright (c) 2020 Amarula Solutions(India) + */ + +/dts-v1/; +#include "px30.dtsi" +#include "px30-engicam-ctouch2.dtsi" +#include "px30-engicam-px30-core.dtsi" + +/ { + model = "Engicam PX30.Core C.TOUCH 2.0 10.1\" Open Frame"; + compatible = "engicam,px30-core-ctouch2-of10", "engicam,px30-core", + "rockchip,px30"; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm0 0 25000 0>; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + panel { + compatible = "ampire,am-1280800n3tzqw-t00h"; + backlight = <&backlight>; + power-supply = <&vcc3v3_lcd>; + data-mapping = "vesa-24"; + + port { + panel_in_lvds: endpoint { + remote-endpoint = <&lvds_out_panel>; + }; + }; + }; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi_dphy { + status = "okay"; +}; + +&lvds { + status = "okay"; + + ports { + port@1 { + reg = <1>; + + lvds_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds>; + }; + }; + }; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2.dts b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2.dts new file mode 100644 index 000000000000..5a0ecb8faecf --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2.dts @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd + * Copyright (c) 2020 Engicam srl + * Copyright (c) 2020 Amarula Solutions + * Copyright (c) 2020 Amarula Solutions(India) + */ + +/dts-v1/; +#include "px30.dtsi" +#include "px30-engicam-ctouch2.dtsi" +#include "px30-engicam-px30-core.dtsi" + +/ { + model = "Engicam PX30.Core C.TOUCH 2.0"; + compatible = "engicam,px30-core-ctouch2", "engicam,px30-core", + "rockchip,px30"; + + chosen { + stdout-path = "serial2:115200n8"; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts new file mode 100644 index 000000000000..d759478e1c84 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd + * Copyright (c) 2020 Engicam srl + * Copyright (c) 2020 Amarula Solutions(India) + */ + +/dts-v1/; +#include "px30.dtsi" +#include "px30-engicam-edimm2.2.dtsi" +#include "px30-engicam-px30-core.dtsi" + +/ { + model = "Engicam PX30.Core EDIMM2.2 Starter Kit"; + compatible = "engicam,px30-core-edimm2.2", "engicam,px30-core", + "rockchip,px30"; + + chosen { + stdout-path = "serial2:115200n8"; + }; +}; + +&pinctrl { + bt { + bt_enable_h: bt-enable-h { + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&sdio_pwrseq { + reset-gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_LOW>; +}; + +&vcc3v3_btreg { + enable-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>; +}; diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi new file mode 100644 index 000000000000..cdacd3483600 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd + * Copyright (c) 2020 Engicam srl + * Copyright (c) 2020 Amarula Solutons + * Copyright (c) 2020 Amarula Solutons(India) + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pinctrl/rockchip.h> + +/ { + compatible = "engicam,px30-core", "rockchip,px30"; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&emmc { + cap-mmc-highspeed; + mmc-hs200-1_8v; + non-removable; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PA7 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + clock-output-names = "rk808-clkout1", "rk808-clkout2"; + + vcc1-supply = <&vcc5v0_sys>; + vcc2-supply = <&vcc5v0_sys>; + vcc3-supply = <&vcc5v0_sys>; + vcc4-supply = <&vcc5v0_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc5v0_sys>; + + regulators { + vdd_log: DCDC_REG1 { + regulator-name = "vdd_log"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v3: DCDC_REG4 { + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc3v3_sys: DCDC_REG5 { + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_1v0: LDO_REG1 { + regulator-name = "vcc_1v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_1v8: LDO_REG2 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_1v0: LDO_REG3 { + regulator-name = "vdd_1v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v0_pmu: LDO_REG4 { + regulator-name = "vcc3v0_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + + }; + }; + + vccio_sd: LDO_REG5 { + regulator-name = "vccio_sd"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc3v3_lcd: SWITCH_REG1 { + regulator-boot-on; + regulator-name = "vcc3v3_lcd"; + }; + + vcc5v0_host: SWITCH_REG2 { + regulator-name = "vcc5v0_host"; + regulator-always-on; + regulator-boot-on; + }; + }; + }; +}; + +&io_domains { + vccio1-supply = <&vcc_3v3>; + vccio2-supply = <&vcc_3v3>; + vccio3-supply = <&vcc_3v3>; + vccio4-supply = <&vcc_3v3>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_1v8>; + status = "okay"; +}; + +&pinctrl { + pmic { + pmic_int: pmic_int { + rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc_3v3>; + pmuio2-supply = <&vcc_3v3>; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <1>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts b/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts index 337681038519..97fb93e1cc00 100644 --- a/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts +++ b/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts @@ -18,6 +18,30 @@ stdout-path = "serial2:115200n8"; }; + adc-joystick { + compatible = "adc-joystick"; + io-channels = <&saradc 1>, + <&saradc 2>; + #address-cells = <1>; + #size-cells = <0>; + + axis@0 { + reg = <0>; + abs-flat = <10>; + abs-fuzz = <10>; + abs-range = <172 772>; + linux,code = <ABS_X>; + }; + + axis@1 { + reg = <1>; + abs-flat = <10>; + abs-fuzz = <10>; + abs-range = <278 815>; + linux,code = <ABS_Y>; + }; + }; + backlight: backlight { compatible = "pwm-backlight"; power-supply = <&vcc_bl>; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts index b70ffb1c6a63..19959bfba451 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts @@ -104,6 +104,14 @@ }; }; +&analog_sound { + status = "okay"; +}; + +&codec { + status = "okay"; +}; + &cpu0 { cpu-supply = <&vdd_arm>; }; @@ -161,6 +169,10 @@ status = "okay"; }; +&hdmi_sound { + status = "okay"; +}; + &i2c1 { status = "okay"; @@ -270,6 +282,14 @@ }; }; +&i2s0 { + status = "okay"; +}; + +&i2s1 { + status = "okay"; +}; + &io_domains { status = "okay"; @@ -334,6 +354,7 @@ }; &usb20_otg { + dr_mode = "host"; status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index bbdb19a3e85d..db0d5c8e5f96 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -1237,8 +1237,8 @@ uart0 { uart0_xfer: uart0-xfer { - rockchip,pins = <1 RK_PB1 1 &pcfg_pull_up>, - <1 RK_PB0 1 &pcfg_pull_none>; + rockchip,pins = <1 RK_PB1 1 &pcfg_pull_none>, + <1 RK_PB0 1 &pcfg_pull_up>; }; uart0_cts: uart0-cts { @@ -1256,8 +1256,8 @@ uart1 { uart1_xfer: uart1-xfer { - rockchip,pins = <3 RK_PA4 4 &pcfg_pull_up>, - <3 RK_PA6 4 &pcfg_pull_none>; + rockchip,pins = <3 RK_PA4 4 &pcfg_pull_none>, + <3 RK_PA6 4 &pcfg_pull_up>; }; uart1_cts: uart1-cts { @@ -1275,15 +1275,15 @@ uart2-0 { uart2m0_xfer: uart2m0-xfer { - rockchip,pins = <1 RK_PA0 2 &pcfg_pull_up>, - <1 RK_PA1 2 &pcfg_pull_none>; + rockchip,pins = <1 RK_PA0 2 &pcfg_pull_none>, + <1 RK_PA1 2 &pcfg_pull_up>; }; }; uart2-1 { uart2m1_xfer: uart2m1-xfer { - rockchip,pins = <2 RK_PA0 1 &pcfg_pull_up>, - <2 RK_PA1 1 &pcfg_pull_none>; + rockchip,pins = <2 RK_PA0 1 &pcfg_pull_none>, + <2 RK_PA1 1 &pcfg_pull_up>; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi index 60cd1c18cd4e..beee5fbb3443 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi @@ -296,6 +296,52 @@ camera: &i2c7 { /* 24M mclk is shared between world and user cameras */ pinctrl-0 = <&i2c7_xfer &test_clkout1>; + + /* Rear-facing camera */ + wcam: camera@36 { + compatible = "ovti,ov5695"; + reg = <0x36>; + pinctrl-names = "default"; + pinctrl-0 = <&wcam_rst>; + + clocks = <&cru SCLK_TESTCLKOUT1>; + clock-names = "xvclk"; + + avdd-supply = <&pp2800_cam>; + dvdd-supply = <&pp1250_cam>; + dovdd-supply = <&pp1800_s0>; + reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; + + port { + wcam_out: endpoint { + remote-endpoint = <&mipi_in_wcam>; + data-lanes = <1 2>; + }; + }; + }; + + /* Front-facing camera */ + ucam: camera@3c { + compatible = "ovti,ov2685"; + reg = <0x3c>; + pinctrl-names = "default"; + pinctrl-0 = <&ucam_rst>; + + clocks = <&cru SCLK_TESTCLKOUT1>; + clock-names = "xvclk"; + + avdd-supply = <&pp2800_cam>; + dovdd-supply = <&pp1800_s0>; + dvdd-supply = <&pp1800_s0>; + reset-gpios = <&gpio2 3 GPIO_ACTIVE_LOW>; + + port { + ucam_out: endpoint { + remote-endpoint = <&mipi_in_ucam>; + data-lanes = <1>; + }; + }; + }; }; &cdn_dp { @@ -353,10 +399,38 @@ camera: &i2c7 { gpio1830-supply = <&pp1800_s0>; /* APIO4_VDD; 4c 4d */ }; +&isp0 { + status = "okay"; + + ports { + port@0 { + mipi_in_wcam: endpoint@0 { + reg = <0>; + remote-endpoint = <&wcam_out>; + data-lanes = <1 2>; + }; + + mipi_in_ucam: endpoint@1 { + reg = <1>; + remote-endpoint = <&ucam_out>; + data-lanes = <1>; + }; + }; + }; +}; + +&isp0_mmu { + status = "okay"; +}; + &max98357a { sdmode-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; }; +&mipi_dphy_rx0 { + status = "okay"; +}; + &mipi_dsi { status = "okay"; clock-master; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts new file mode 100644 index 000000000000..2a561be724b2 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts @@ -0,0 +1,372 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Aditya Prayoga <aditya@kobol.io> + */ + +/* + * The Kobol Helios64 is a board designed to operate as a NAS and optionally + * ships with an enclosing that can host five 2.5" hard disks. + * + * See https://wiki.kobol.io/helios64/intro/ for further details. + */ + +/dts-v1/; +#include "rk3399.dtsi" +#include "rk3399-opp.dtsi" + +/ { + model = "Kobol Helios64"; + compatible = "kobol,helios64", "rockchip,rk3399"; + + avdd_1v8_s0: avdd-1v8-s0 { + compatible = "regulator-fixed"; + regulator-name = "avdd_1v8_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys_s3>; + }; + + clkin_gmac: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "clkin_gmac"; + #clock-cells = <0>; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&sys_grn_led_on &sys_red_led_on>; + + led-0 { + label = "helios64:green:status"; + gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + led-1 { + label = "helios64:red:fault"; + gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; + default-state = "keep"; + }; + }; + + vcc1v8_sys_s0: vcc1v8-sys-s0 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v8_sys_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc1v8_sys_s3>; + }; + + vcc3v0_sd: vcc3v0-sd { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; + regulator-name = "vcc3v0_sd"; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_pwr_h>; + vin-supply = <&vcc3v3_sys_s3>; + }; + + vcc3v3_sys_s3: vcc_lan: vcc3v3-sys-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + 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>; + vin-supply = <&vcc12v_dcin_bkup>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc12v_dcin: vcc12v-dcin { + compatible = "regulator-fixed"; + regulator-name = "vcc12v_dcin"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vcc12v_dcin_bkup: vcc12v-dcin-bkup { + compatible = "regulator-fixed"; + regulator-name = "vcc12v_dcin_bkup"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + vin-supply = <&vcc12v_dcin>; + }; +}; + +/* + * The system doesn't run stable with cpu freq enabled, so disallow the lower + * frequencies until this problem is properly understood and resolved. + */ +&cluster0_opp { + /delete-node/ opp00; + /delete-node/ opp01; + /delete-node/ opp02; + /delete-node/ opp03; + /delete-node/ opp04; +}; + +&cluster1_opp { + /delete-node/ opp00; + /delete-node/ opp01; + /delete-node/ opp02; + /delete-node/ opp03; + /delete-node/ opp04; + /delete-node/ opp05; + /delete-node/ opp06; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_l>; +}; + +&emmc_phy { + status = "okay"; +}; + +&gmac { + assigned-clock-parents = <&clkin_gmac>; + assigned-clocks = <&cru SCLK_RMII_SRC>; + clock_in_out = "input"; + phy-mode = "rgmii"; + phy-supply = <&vcc_lan>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins &gphy_reset>; + rx_delay = <0x20>; + tx_delay = <0x28>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; + snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-rising-time-ns = <168>; + i2c-scl-falling-time-ns = <4>; + status = "okay"; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + interrupt-parent = <&gpio0>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + clock-output-names = "xin32k", "rk808-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + vcc1-supply = <&vcc5v0_sys>; + vcc2-supply = <&vcc5v0_sys>; + vcc3-supply = <&vcc5v0_sys>; + vcc4-supply = <&vcc5v0_sys>; + vcc6-supply = <&vcc5v0_sys>; + vcc7-supply = <&vcc5v0_sys>; + vcc8-supply = <&vcc3v3_sys_s3>; + vcc9-supply = <&vcc5v0_sys>; + vcc10-supply = <&vcc5v0_sys>; + vcc11-supply = <&vcc5v0_sys>; + vcc12-supply = <&vcc3v3_sys_s3>; + vddio-supply = <&vcc3v0_s3>; + wakeup-source; + #clock-cells = <1>; + + regulators { + vdd_cpu_l: DCDC_REG2 { + regulator-name = "vdd_cpu_l"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_sys_s3: DCDC_REG4 { + regulator-name = "vcc1v8_sys_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_sdio_s0: LDO_REG4 { + regulator-name = "vcc_sdio_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc3v0_s3: LDO_REG8 { + regulator-name = "vcc3v0_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + }; + }; + + vdd_cpu_b: regulator@40 { + compatible = "silergy,syr827"; + reg = <0x40>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu_b"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c2 { + clock-frequency = <400000>; + i2c-scl-rising-time-ns = <160>; + i2c-scl-falling-time-ns = <30>; + status = "okay"; + + temp@4c { + compatible = "national,lm75"; + reg = <0x4c>; + }; +}; + +&io_domains { + audio-supply = <&vcc1v8_sys_s0>; + bt656-supply = <&vcc1v8_sys_s0>; + gpio1830-supply = <&vcc3v0_s3>; + sdmmc-supply = <&vcc_sdio_s0>; + status = "okay"; +}; + +&pinctrl { + gmac { + gphy_reset: gphy-reset { + rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_output_low>; + }; + }; + + leds { + sys_grn_led_on: sys-grn-led-on { + rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + sys_red_led_on: sys-red-led-on { + rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + vcc3v0-sd { + sdmmc0_pwr_h: sdmmc0-pwr-h { + rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pmu_io_domains { + pmu1830-supply = <&vcc3v0_s3>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + mmc-hs200-1_8v; + non-removable; + vqmmc-supply = <&vcc1v8_sys_s0>; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; + disable-wp; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + vmmc-supply = <&vcc3v0_sd>; + vqmmc-supply = <&vcc_sdio_s0>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts index 6163ae8063a7..ad7c4d00888f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts @@ -7,6 +7,7 @@ #include "dt-bindings/pwm/pwm.h" #include "dt-bindings/input/input.h" +#include "dt-bindings/usb/pd.h" #include "rk3399.dtsi" #include "rk3399-opp.dtsi" @@ -531,6 +532,43 @@ pinctrl-names = "default"; pinctrl-0 = <&chg_cc_int_l>; vbus-supply = <&vbus_typec>; + + typec_con: connector { + compatible = "usb-c-connector"; + data-role = "host"; + label = "USB-C"; + op-sink-microwatt = <1000000>; + power-role = "dual"; + sink-pdos = + <PDO_FIXED(5000, 2500, PDO_FIXED_USB_COMM)>; + source-pdos = + <PDO_FIXED(5000, 1400, PDO_FIXED_USB_COMM)>; + try-power-role = "sink"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + typec_hs: endpoint { + remote-endpoint = <&u2phy0_typec_hs>; + }; + }; + port@1 { + reg = <1>; + typec_ss: endpoint { + remote-endpoint = <&tcphy0_typec_ss>; + }; + }; + port@2 { + reg = <2>; + typec_dp: endpoint { + remote-endpoint = <&tcphy0_typec_dp>; + }; + }; + }; + }; }; }; @@ -717,6 +755,22 @@ status = "okay"; }; +&tcphy0_dp { + port { + tcphy0_typec_dp: endpoint { + remote-endpoint = <&typec_dp>; + }; + }; +}; + +&tcphy0_usb3 { + port { + tcphy0_typec_ss: endpoint { + remote-endpoint = <&typec_ss>; + }; + }; +}; + &tcphy1 { status = "okay"; }; @@ -739,6 +793,12 @@ phy-supply = <&vcc5v0_host>; status = "okay"; }; + + port { + u2phy0_typec_hs: endpoint { + remote-endpoint = <&typec_hs>; + }; + }; }; &u2phy1 { @@ -799,7 +859,7 @@ &usbdrd_dwc3_0 { status = "okay"; - dr_mode = "otg"; + dr_mode = "host"; }; &usbdrd3_1 { diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi index 678a336010bf..fb7599f07af4 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi @@ -111,10 +111,6 @@ regulator-boot-on; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - - regulator-state-mem { - regulator-off-in-suspend; - }; }; vdd_log: vdd-log { @@ -362,8 +358,6 @@ regulator-name = "vcc_cam"; regulator-always-on; regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; regulator-state-mem { regulator-off-in-suspend; }; @@ -373,8 +367,6 @@ regulator-name = "vcc_mipi"; regulator-always-on; regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; regulator-state-mem { regulator-off-in-suspend; }; @@ -440,8 +432,9 @@ }; &i2s0 { - rockchip,playback-channels = <8>; - rockchip,capture-channels = <8>; + pinctrl-0 = <&i2s0_2ch_bus>; + rockchip,capture-channels = <2>; + rockchip,playback-channels = <2>; status = "okay"; }; @@ -680,7 +673,7 @@ &usbdrd_dwc3_0 { status = "okay"; - dr_mode = "otg"; + dr_mode = "host"; }; &usbdrd3_1 { diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 7a9a7aca86c6..f5dee5f447bb 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -331,7 +331,7 @@ status = "disabled"; }; - sdhci: sdhci@fe330000 { + sdhci: mmc@fe330000 { compatible = "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1"; reg = <0x0 0xfe330000 0x0 0x10000>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH 0>; @@ -1726,6 +1726,32 @@ status = "disabled"; }; + isp0: isp0@ff910000 { + compatible = "rockchip,rk3399-cif-isp"; + reg = <0x0 0xff910000 0x0 0x4000>; + interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&cru SCLK_ISP0>, + <&cru ACLK_ISP0_WRAPPER>, + <&cru HCLK_ISP0_WRAPPER>; + clock-names = "isp", "aclk", "hclk"; + iommus = <&isp0_mmu>; + phys = <&mipi_dphy_rx0>; + phy-names = "dphy"; + power-domains = <&power RK3399_PD_ISP0>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; + isp0_mmu: iommu@ff914000 { compatible = "rockchip,iommu"; reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi index 5d087be04af8..7257494d2831 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi @@ -353,6 +353,12 @@ }; }; + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + vbus_host { usb1_en_oc: usb1-en-oc { rockchip,pins = <4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; @@ -371,6 +377,16 @@ pmu1830-supply = <&vcc_1v8>; }; +&sdio_pwrseq { + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; +}; + &sdhci { bus-width = <8>; mmc-hs400-1_8v; diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi index 533525229a8d..12591a854020 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi @@ -119,7 +119,6 @@ #address-cells = <2>; #size-cells = <2>; ranges = <0x0 0x04e00000 0x00 0x04e00000 0x0 0x30000>; - status = "okay"; dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>, <&main_udmap 0x4001>; @@ -473,6 +472,7 @@ interrupt-controller; interrupt-parent = <&intr_main_navss>; msi-controller; + #interrupt-cells = <0>; ti,sci = <&dmsc>; ti,sci-dev-id = <179>; ti,interrupt-ranges = <0 0 256>; @@ -612,7 +612,6 @@ reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target"; ti,num-rings = <818>; ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */ - ti,dma-ring-reset-quirk; ti,sci = <&dmsc>; ti,sci-dev-id = <187>; msi-parent = <&inta_main_udmass>; @@ -770,8 +769,6 @@ clocks = <&k3_clks 104 0>; clock-names = "fck"; power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; mcasp1: mcasp@2b10000 { @@ -789,8 +786,6 @@ clocks = <&k3_clks 105 0>; clock-names = "fck"; power-domains = <&k3_pds 105 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; mcasp2: mcasp@2b20000 { @@ -808,8 +803,6 @@ clocks = <&k3_clks 106 0>; clock-names = "fck"; power-domains = <&k3_pds 106 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; cal: cal@6f03000 { @@ -834,7 +827,7 @@ }; }; - dss: dss@04a00000 { + dss: dss@4a00000 { compatible = "ti,am65x-dss"; reg = <0x0 0x04a00000 0x0 0x1000>, /* common */ <0x0 0x04a02000 0x0 0x1000>, /* vidl1 */ @@ -865,7 +858,7 @@ interrupts = <GIC_SPI 166 IRQ_TYPE_EDGE_RISING>; - status = "disabled"; + dma-coherent; dss_ports: ports { #address-cells = <1>; diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi index 29aaf8dca6f6..7454c8cec0cc 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi @@ -2,7 +2,7 @@ /* * Device Tree Source for AM6 SoC Family MCU Domain peripherals * - * Copyright (C) 2016-2018 Texas Instruments Incorporated - https://www.ti.com/ + * Copyright (C) 2016-2020 Texas Instruments Incorporated - https://www.ti.com/ */ &cbass_mcu { @@ -135,7 +135,6 @@ reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target"; ti,num-rings = <286>; ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */ - ti,dma-ring-reset-quirk; ti,sci = <&dmsc>; ti,sci-dev-id = <195>; msi-parent = <&inta_main_udmass>; @@ -269,4 +268,44 @@ }; }; }; + + mcu_r5fss0: r5fss@41000000 { + compatible = "ti,am654-r5fss"; + ti,cluster-mode = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x41000000 0x00 0x41000000 0x20000>, + <0x41400000 0x00 0x41400000 0x20000>; + power-domains = <&k3_pds 129 TI_SCI_PD_EXCLUSIVE>; + + mcu_r5fss0_core0: r5f@41000000 { + compatible = "ti,am654-r5f"; + reg = <0x41000000 0x00008000>, + <0x41010000 0x00008000>; + reg-names = "atcm", "btcm"; + ti,sci = <&dmsc>; + ti,sci-dev-id = <159>; + ti,sci-proc-ids = <0x01 0xff>; + resets = <&k3_reset 159 1>; + firmware-name = "am65x-mcu-r5f0_0-fw"; + ti,atcm-enable = <1>; + ti,btcm-enable = <1>; + ti,loczrama = <1>; + }; + + mcu_r5fss0_core1: r5f@41400000 { + compatible = "ti,am654-r5f"; + reg = <0x41400000 0x00008000>, + <0x41410000 0x00008000>; + reg-names = "atcm", "btcm"; + ti,sci = <&dmsc>; + ti,sci-dev-id = <245>; + ti,sci-proc-ids = <0x02 0xff>; + resets = <&k3_reset 245 1>; + firmware-name = "am65x-mcu-r5f0_1-fw"; + ti,atcm-enable = <1>; + ti,btcm-enable = <1>; + ti,loczrama = <1>; + }; + }; }; diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts index d12dd89f3405..fe3043943906 100644 --- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts +++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) 2016-2018 Texas Instruments Incorporated - https://www.ti.com/ + * Copyright (C) 2016-2020 Texas Instruments Incorporated - https://www.ti.com/ */ /dts-v1/; @@ -29,11 +29,42 @@ #address-cells = <2>; #size-cells = <2>; ranges; + secure_ddr: secure-ddr@9e800000 { reg = <0 0x9e800000 0 0x01800000>; /* for OP-TEE */ alignment = <0x1000>; no-map; }; + + mcu_r5fss0_core0_dma_memory_region: r5f-dma-memory@a0000000 { + compatible = "shared-dma-pool"; + reg = <0 0xa0000000 0 0x100000>; + no-map; + }; + + mcu_r5fss0_core0_memory_region: r5f-memory@a0100000 { + compatible = "shared-dma-pool"; + reg = <0 0xa0100000 0 0xf00000>; + no-map; + }; + + mcu_r5fss0_core1_dma_memory_region: r5f-dma-memory@a1000000 { + compatible = "shared-dma-pool"; + reg = <0 0xa1000000 0 0x100000>; + no-map; + }; + + mcu_r5fss0_core1_memory_region: r5f-memory@a1100000 { + compatible = "shared-dma-pool"; + reg = <0 0xa1100000 0 0xf00000>; + no-map; + }; + + rtos_ipc_memory_region: ipc-memories@a2000000 { + reg = <0x00 0xa2000000 0x00 0x00100000>; + alignment = <0x1000>; + no-map; + }; }; gpio-keys { @@ -211,7 +242,7 @@ &wkup_uart0 { /* Wakeup UART is used by System firmware */ - status = "disabled"; + status = "reserved"; }; &main_uart0 { @@ -325,14 +356,6 @@ disable-wp; }; -&dwc3_1 { - status = "okay"; -}; - -&usb1_phy { - status = "okay"; -}; - &usb1 { pinctrl-names = "default"; pinctrl-0 = <&usb1_pins_default>; @@ -441,6 +464,18 @@ status = "disabled"; }; +&mcu_r5fss0_core0 { + memory-region = <&mcu_r5fss0_core0_dma_memory_region>, + <&mcu_r5fss0_core0_memory_region>; + mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>; +}; + +&mcu_r5fss0_core1 { + memory-region = <&mcu_r5fss0_core1_dma_memory_region>, + <&mcu_r5fss0_core1_memory_region>; + mboxes = <&mailbox0_cluster1 &mbox_mcu_r5fss0_core1>; +}; + &ospi0 { pinctrl-names = "default"; pinctrl-0 = <&mcu_fss0_ospi0_pins_default>; @@ -486,3 +521,19 @@ phy-mode = "rgmii-rxid"; phy-handle = <&phy0>; }; + +&mcasp0 { + status = "disabled"; +}; + +&mcasp1 { + status = "disabled"; +}; + +&mcasp2 { + status = "disabled"; +}; + +&dss { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts index ef03e7636b66..331b388e1d1b 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts +++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts @@ -43,13 +43,6 @@ }; &main_pmx0 { - main_i2c0_pins_default: main-i2c0-pins-default { - pinctrl-single,pins = < - J721E_IOPAD(0xd4, PIN_INPUT_PULLUP, 0) /* (V3) I2C0_SCL */ - J721E_IOPAD(0xd8, PIN_INPUT_PULLUP, 0) /* (W2) I2C0_SDA */ - >; - }; - main_i2c1_pins_default: main-i2c1-pins-default { pinctrl-single,pins = < J721E_IOPAD(0xdc, PIN_INPUT_PULLUP, 3) /* (U3) ECAP0_IN_APWM_OUT.I2C1_SCL */ @@ -79,7 +72,7 @@ &wkup_uart0 { /* Wakeup UART is used by System firmware */ - status = "disabled"; + status = "reserved"; }; &main_uart0 { @@ -89,7 +82,7 @@ &main_uart2 { /* MAIN UART 2 is used by R5F firmware */ - status = "disabled"; + status = "reserved"; }; &main_uart3 { @@ -146,10 +139,6 @@ }; &main_i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&main_i2c0_pins_default>; - clock-frequency = <400000>; - exp1: gpio@20 { compatible = "ti,tca6416"; reg = <0x20>; @@ -165,16 +154,26 @@ }; }; +/* + * The j7200 CPB board is identical to the CPB used for J721E, the SOMs can be + * swapped on the CPB. + * + * main_i2c1 of J7200 is connected to the CPB i2c bus labeled as i2c3. + * The i2c1 of the CPB (as it is labeled) is not connected to j7200. + */ &main_i2c1 { pinctrl-names = "default"; pinctrl-0 = <&main_i2c1_pins_default>; clock-frequency = <400000>; - exp4: gpio@20 { + exp3: gpio@20 { compatible = "ti,tca6408"; reg = <0x20>; gpio-controller; #gpio-cells = <2>; + gpio-line-names = "CODEC_RSTz", "CODEC_SPARE1", "UB926_RESETn", + "UB926_LOCK", "UB926_PWR_SW_CNTRL", + "UB926_TUNER_RESET", "UB926_GPIO_SPARE", ""; }; }; @@ -213,3 +212,9 @@ dr_mode = "otg"; maximum-speed = "high-speed"; }; + +&tscadc0 { + adc { + ti,adc-channels = <0 1 2 3 4 5 6 7>; + }; +}; diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi index 72d6496e88dd..b0094212aa82 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi @@ -115,6 +115,120 @@ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; }; + hwspinlock: spinlock@30e00000 { + compatible = "ti,am654-hwspinlock"; + reg = <0x00 0x30e00000 0x00 0x1000>; + #hwlock-cells = <1>; + }; + + mailbox0_cluster0: mailbox@31f80000 { + compatible = "ti,am654-mailbox"; + reg = <0x00 0x31f80000 0x00 0x200>; + #mbox-cells = <1>; + ti,mbox-num-users = <4>; + ti,mbox-num-fifos = <16>; + interrupt-parent = <&main_navss_intr>; + }; + + mailbox0_cluster1: mailbox@31f81000 { + compatible = "ti,am654-mailbox"; + reg = <0x00 0x31f81000 0x00 0x200>; + #mbox-cells = <1>; + ti,mbox-num-users = <4>; + ti,mbox-num-fifos = <16>; + interrupt-parent = <&main_navss_intr>; + }; + + mailbox0_cluster2: mailbox@31f82000 { + compatible = "ti,am654-mailbox"; + reg = <0x00 0x31f82000 0x00 0x200>; + #mbox-cells = <1>; + ti,mbox-num-users = <4>; + ti,mbox-num-fifos = <16>; + interrupt-parent = <&main_navss_intr>; + }; + + mailbox0_cluster3: mailbox@31f83000 { + compatible = "ti,am654-mailbox"; + reg = <0x00 0x31f83000 0x00 0x200>; + #mbox-cells = <1>; + ti,mbox-num-users = <4>; + ti,mbox-num-fifos = <16>; + interrupt-parent = <&main_navss_intr>; + }; + + mailbox0_cluster4: mailbox@31f84000 { + compatible = "ti,am654-mailbox"; + reg = <0x00 0x31f84000 0x00 0x200>; + #mbox-cells = <1>; + ti,mbox-num-users = <4>; + ti,mbox-num-fifos = <16>; + interrupt-parent = <&main_navss_intr>; + }; + + mailbox0_cluster5: mailbox@31f85000 { + compatible = "ti,am654-mailbox"; + reg = <0x00 0x31f85000 0x00 0x200>; + #mbox-cells = <1>; + ti,mbox-num-users = <4>; + ti,mbox-num-fifos = <16>; + interrupt-parent = <&main_navss_intr>; + }; + + mailbox0_cluster6: mailbox@31f86000 { + compatible = "ti,am654-mailbox"; + reg = <0x00 0x31f86000 0x00 0x200>; + #mbox-cells = <1>; + ti,mbox-num-users = <4>; + ti,mbox-num-fifos = <16>; + interrupt-parent = <&main_navss_intr>; + }; + + mailbox0_cluster7: mailbox@31f87000 { + compatible = "ti,am654-mailbox"; + reg = <0x00 0x31f87000 0x00 0x200>; + #mbox-cells = <1>; + ti,mbox-num-users = <4>; + ti,mbox-num-fifos = <16>; + interrupt-parent = <&main_navss_intr>; + }; + + mailbox0_cluster8: mailbox@31f88000 { + compatible = "ti,am654-mailbox"; + reg = <0x00 0x31f88000 0x00 0x200>; + #mbox-cells = <1>; + ti,mbox-num-users = <4>; + ti,mbox-num-fifos = <16>; + interrupt-parent = <&main_navss_intr>; + }; + + mailbox0_cluster9: mailbox@31f89000 { + compatible = "ti,am654-mailbox"; + reg = <0x00 0x31f89000 0x00 0x200>; + #mbox-cells = <1>; + ti,mbox-num-users = <4>; + ti,mbox-num-fifos = <16>; + interrupt-parent = <&main_navss_intr>; + }; + + mailbox0_cluster10: mailbox@31f8a000 { + compatible = "ti,am654-mailbox"; + reg = <0x00 0x31f8a000 0x00 0x200>; + #mbox-cells = <1>; + ti,mbox-num-users = <4>; + ti,mbox-num-fifos = <16>; + interrupt-parent = <&main_navss_intr>; + }; + + mailbox0_cluster11: mailbox@31f8b000 { + compatible = "ti,am654-mailbox"; + reg = <0x00 0x31f8b000 0x00 0x200>; + #mbox-cells = <1>; + ti,mbox-num-users = <4>; + ti,mbox-num-fifos = <16>; + interrupt-parent = <&main_navss_intr>; + }; + main_ringacc: ringacc@3c000000 { compatible = "ti,am654-navss-ringacc"; reg = <0x00 0x3c000000 0x00 0x400000>, diff --git a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi index eb2a78a53512..bb1fe9c12e44 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi @@ -270,4 +270,23 @@ mux-controls = <&hbmc_mux 0>; }; }; + + tscadc0: tscadc@40200000 { + compatible = "ti,am3359-tscadc"; + reg = <0x00 0x40200000 0x00 0x1000>; + interrupts = <GIC_SPI 860 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&k3_pds 0 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 0 1>; + assigned-clocks = <&k3_clks 0 3>; + assigned-clock-rates = <60000000>; + clock-names = "adc_tsc_fck"; + dmas = <&main_udmap 0x7400>, + <&main_udmap 0x7401>; + dma-names = "fifo0", "fifo1"; + + adc { + #io-channel-cells = <1>; + compatible = "ti,am3359-adc"; + }; + }; }; diff --git a/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi index 6a98ba499bc2..7b5e9aa0324e 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi @@ -48,6 +48,15 @@ }; }; +&main_pmx0 { + main_i2c0_pins_default: main-i2c0-pins-default { + pinctrl-single,pins = < + J721E_IOPAD(0xd4, PIN_INPUT_PULLUP, 0) /* (V3) I2C0_SCL */ + J721E_IOPAD(0xd8, PIN_INPUT_PULLUP, 0) /* (W2) I2C0_SDA */ + >; + }; +}; + &hbmc { /* OSPI and HBMC are muxed inside FSS, Bootloader will enable * appropriate node based on board detection @@ -63,3 +72,88 @@ reg = <0x00 0x00 0x4000000>; }; }; + +&mailbox0_cluster0 { + interrupts = <436>; + + mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 { + ti,mbox-rx = <0 0 0>; + ti,mbox-tx = <1 0 0>; + }; + + mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 { + ti,mbox-rx = <2 0 0>; + ti,mbox-tx = <3 0 0>; + }; +}; + +&mailbox0_cluster1 { + interrupts = <432>; + + mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 { + ti,mbox-rx = <0 0 0>; + ti,mbox-tx = <1 0 0>; + }; + + mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 { + ti,mbox-rx = <2 0 0>; + ti,mbox-tx = <3 0 0>; + }; +}; + +&mailbox0_cluster2 { + status = "disabled"; +}; + +&mailbox0_cluster3 { + status = "disabled"; +}; + +&mailbox0_cluster4 { + status = "disabled"; +}; + +&mailbox0_cluster5 { + status = "disabled"; +}; + +&mailbox0_cluster6 { + status = "disabled"; +}; + +&mailbox0_cluster7 { + status = "disabled"; +}; + +&mailbox0_cluster8 { + status = "disabled"; +}; + +&mailbox0_cluster9 { + status = "disabled"; +}; + +&mailbox0_cluster10 { + status = "disabled"; +}; + +&mailbox0_cluster11 { + status = "disabled"; +}; + +&main_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&main_i2c0_pins_default>; + clock-frequency = <400000>; + + exp_som: gpio@21 { + compatible = "ti,tca6408"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "USB2.0_MUX_SEL", "CANUART_MUX1_SEL0", + "CANUART_MUX2_SEL0", "CANUART_MUX_SEL1", + "UART/LIN_MUX_SEL", "TRC_D17/AUDIO_REFCLK_SEL", + "GPIO_LIN_EN", "CAN_STB"; + }; +}; diff --git a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts index 52e121155563..60764366e22b 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts +++ b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts @@ -67,6 +67,31 @@ regulator-boot-on; }; + vdd_mmc1: fixedregulator-sd { + compatible = "regulator-fixed"; + regulator-name = "vdd_mmc1"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + enable-active-high; + vin-supply = <&vsys_3v3>; + gpio = <&exp2 2 GPIO_ACTIVE_HIGH>; + }; + + vdd_sd_dv_alt: gpio-regulator-TLV71033 { + compatible = "regulator-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&vdd_sd_dv_alt_pins_default>; + regulator-name = "tlv71033"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + vin-supply = <&vsys_5v0>; + gpios = <&main_gpio0 117 GPIO_ACTIVE_HIGH>; + states = <1800000 0x0>, + <3300000 0x1>; + }; + sound0: sound@0 { compatible = "ti,j721e-cpb-audio"; model = "j721e-cpb"; @@ -106,6 +131,12 @@ >; }; + vdd_sd_dv_alt_pins_default: vdd-sd-dv-alt-pins-default { + pinctrl-single,pins = < + J721E_IOPAD(0x1d8, PIN_INPUT, 7) /* (W4) SPI1_CS1.GPIO0_117 */ + >; + }; + main_usbss0_pins_default: main-usbss0-pins-default { pinctrl-single,pins = < J721E_IOPAD(0x290, PIN_OUTPUT, 0) /* (U6) USB0_DRVVBUS */ @@ -221,7 +252,7 @@ &wkup_uart0 { /* Wakeup UART is used by System firmware */ - status = "disabled"; + status = "reserved"; }; &main_uart0 { @@ -295,6 +326,8 @@ &main_sdhci1 { /* SD/MMC */ + vmmc-supply = <&vdd_mmc1>; + vqmmc-supply = <&vdd_sd_dv_alt>; pinctrl-names = "default"; pinctrl-0 = <&main_mmc1_pins_default>; ti,driver-strength-ohm = <50>; @@ -540,6 +573,46 @@ <&k3_clks 152 18>; /* PLL23_HSDIV0 */ }; +&mcasp0 { + status = "disabled"; +}; + +&mcasp1 { + status = "disabled"; +}; + +&mcasp2 { + status = "disabled"; +}; + +&mcasp3 { + status = "disabled"; +}; + +&mcasp4 { + status = "disabled"; +}; + +&mcasp5 { + status = "disabled"; +}; + +&mcasp6 { + status = "disabled"; +}; + +&mcasp7 { + status = "disabled"; +}; + +&mcasp8 { + status = "disabled"; +}; + +&mcasp9 { + status = "disabled"; +}; + &mcasp10 { #sound-dai-cells = <0>; @@ -556,8 +629,10 @@ >; tx-num-evt = <0>; rx-num-evt = <0>; +}; - status = "okay"; +&mcasp11 { + status = "disabled"; }; &serdes0 { @@ -639,3 +714,7 @@ &pcie3_ep { status = "disabled"; }; + +&dss { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi index e2a96b2c423c..b32df591c766 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi @@ -2,7 +2,7 @@ /* * Device Tree Source for J721E SoC Family Main Domain peripherals * - * Copyright (C) 2016-2019 Texas Instruments Incorporated - https://www.ti.com/ + * Copyright (C) 2016-2020 Texas Instruments Incorporated - https://www.ti.com/ */ #include <dt-bindings/phy/phy.h> #include <dt-bindings/mux/mux.h> @@ -148,6 +148,7 @@ interrupt-controller; interrupt-parent = <&main_navss_intr>; msi-controller; + #interrupt-cells = <0>; ti,sci = <&dmsc>; ti,sci-dev-id = <209>; ti,interrupt-ranges = <0 0 256>; @@ -345,8 +346,6 @@ #size-cells = <2>; ranges = <0x0 0x04e00000 0x00 0x04e00000 0x0 0x30000>; - status = "okay"; - dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>, <&main_udmap 0x4001>; dma-names = "tx", "rx1", "rx2"; @@ -1081,7 +1080,11 @@ bus-width = <8>; mmc-hs400-1_8v; mmc-ddr-1_8v; - ti,otap-del-sel = <0x2>; + ti,otap-del-sel-legacy = <0xf>; + ti,otap-del-sel-mmc-hs = <0xf>; + ti,otap-del-sel-ddr52 = <0x5>; + ti,otap-del-sel-hs200 = <0x6>; + ti,otap-del-sel-hs400 = <0x0>; ti,trm-icp = <0x8>; ti,strobe-sel = <0x77>; dma-coherent; @@ -1096,11 +1099,15 @@ clocks = <&k3_clks 92 0>, <&k3_clks 92 5>; assigned-clocks = <&k3_clks 92 0>; assigned-clock-parents = <&k3_clks 92 1>; - ti,otap-del-sel = <0x2>; + ti,otap-del-sel-legacy = <0x0>; + ti,otap-del-sel-sd-hs = <0xf>; + ti,otap-del-sel-sdr12 = <0xf>; + ti,otap-del-sel-sdr25 = <0xf>; + ti,otap-del-sel-sdr50 = <0xc>; + ti,otap-del-sel-ddr50 = <0xc>; ti,trm-icp = <0x8>; ti,clkbuf-sel = <0x7>; dma-coherent; - no-1-8-v; }; main_sdhci2: sdhci@4f98000 { @@ -1112,11 +1119,15 @@ clocks = <&k3_clks 93 0>, <&k3_clks 93 5>; assigned-clocks = <&k3_clks 93 0>; assigned-clock-parents = <&k3_clks 93 1>; - ti,otap-del-sel = <0x2>; + ti,otap-del-sel-legacy = <0x0>; + ti,otap-del-sel-sd-hs = <0xf>; + ti,otap-del-sel-sdr12 = <0xf>; + ti,otap-del-sel-sdr25 = <0xf>; + ti,otap-del-sel-sdr50 = <0xc>; + ti,otap-del-sel-ddr50 = <0xc>; ti,trm-icp = <0x8>; ti,clkbuf-sel = <0x7>; dma-coherent; - no-1-8-v; }; usbss0: cdns-usb@4104000 { @@ -1278,7 +1289,7 @@ }; }; - dss: dss@04a00000 { + dss: dss@4a00000 { compatible = "ti,j721e-dss"; reg = <0x00 0x04a00000 0x00 0x10000>, /* common_m */ @@ -1327,8 +1338,6 @@ "common_s1", "common_s2"; - status = "disabled"; - dss_ports: ports { #address-cells = <1>; #size-cells = <0>; @@ -1350,8 +1359,6 @@ clocks = <&k3_clks 174 1>; clock-names = "fck"; power-domains = <&k3_pds 174 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; mcasp1: mcasp@2b10000 { @@ -1369,8 +1376,6 @@ clocks = <&k3_clks 175 1>; clock-names = "fck"; power-domains = <&k3_pds 175 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; mcasp2: mcasp@2b20000 { @@ -1388,8 +1393,6 @@ clocks = <&k3_clks 176 1>; clock-names = "fck"; power-domains = <&k3_pds 176 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; mcasp3: mcasp@2b30000 { @@ -1407,8 +1410,6 @@ clocks = <&k3_clks 177 1>; clock-names = "fck"; power-domains = <&k3_pds 177 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; mcasp4: mcasp@2b40000 { @@ -1426,8 +1427,6 @@ clocks = <&k3_clks 178 1>; clock-names = "fck"; power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; mcasp5: mcasp@2b50000 { @@ -1445,8 +1444,6 @@ clocks = <&k3_clks 179 1>; clock-names = "fck"; power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; mcasp6: mcasp@2b60000 { @@ -1464,8 +1461,6 @@ clocks = <&k3_clks 180 1>; clock-names = "fck"; power-domains = <&k3_pds 180 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; mcasp7: mcasp@2b70000 { @@ -1483,8 +1478,6 @@ clocks = <&k3_clks 181 1>; clock-names = "fck"; power-domains = <&k3_pds 181 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; mcasp8: mcasp@2b80000 { @@ -1502,8 +1495,6 @@ clocks = <&k3_clks 182 1>; clock-names = "fck"; power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; mcasp9: mcasp@2b90000 { @@ -1521,8 +1512,6 @@ clocks = <&k3_clks 183 1>; clock-names = "fck"; power-domains = <&k3_pds 183 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; mcasp10: mcasp@2ba0000 { @@ -1540,8 +1529,6 @@ clocks = <&k3_clks 184 1>; clock-names = "fck"; power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; mcasp11: mcasp@2bb0000 { @@ -1559,8 +1546,6 @@ clocks = <&k3_clks 185 1>; clock-names = "fck"; power-domains = <&k3_pds 185 TI_SCI_PD_EXCLUSIVE>; - - status = "disabled"; }; watchdog0: watchdog@2200000 { @@ -1581,6 +1566,86 @@ assigned-clock-parents = <&k3_clks 253 5>; }; + main_r5fss0: r5fss@5c00000 { + compatible = "ti,j721e-r5fss"; + ti,cluster-mode = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x5c00000 0x00 0x5c00000 0x20000>, + <0x5d00000 0x00 0x5d00000 0x20000>; + power-domains = <&k3_pds 243 TI_SCI_PD_EXCLUSIVE>; + + main_r5fss0_core0: r5f@5c00000 { + compatible = "ti,j721e-r5f"; + reg = <0x5c00000 0x00008000>, + <0x5c10000 0x00008000>; + reg-names = "atcm", "btcm"; + ti,sci = <&dmsc>; + ti,sci-dev-id = <245>; + ti,sci-proc-ids = <0x06 0xff>; + resets = <&k3_reset 245 1>; + firmware-name = "j7-main-r5f0_0-fw"; + ti,atcm-enable = <1>; + ti,btcm-enable = <1>; + ti,loczrama = <1>; + }; + + main_r5fss0_core1: r5f@5d00000 { + compatible = "ti,j721e-r5f"; + reg = <0x5d00000 0x00008000>, + <0x5d10000 0x00008000>; + reg-names = "atcm", "btcm"; + ti,sci = <&dmsc>; + ti,sci-dev-id = <246>; + ti,sci-proc-ids = <0x07 0xff>; + resets = <&k3_reset 246 1>; + firmware-name = "j7-main-r5f0_1-fw"; + ti,atcm-enable = <1>; + ti,btcm-enable = <1>; + ti,loczrama = <1>; + }; + }; + + main_r5fss1: r5fss@5e00000 { + compatible = "ti,j721e-r5fss"; + ti,cluster-mode = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x5e00000 0x00 0x5e00000 0x20000>, + <0x5f00000 0x00 0x5f00000 0x20000>; + power-domains = <&k3_pds 244 TI_SCI_PD_EXCLUSIVE>; + + main_r5fss1_core0: r5f@5e00000 { + compatible = "ti,j721e-r5f"; + reg = <0x5e00000 0x00008000>, + <0x5e10000 0x00008000>; + reg-names = "atcm", "btcm"; + ti,sci = <&dmsc>; + ti,sci-dev-id = <247>; + ti,sci-proc-ids = <0x08 0xff>; + resets = <&k3_reset 247 1>; + firmware-name = "j7-main-r5f1_0-fw"; + ti,atcm-enable = <1>; + ti,btcm-enable = <1>; + ti,loczrama = <1>; + }; + + main_r5fss1_core1: r5f@5f00000 { + compatible = "ti,j721e-r5f"; + reg = <0x5f00000 0x00008000>, + <0x5f10000 0x00008000>; + reg-names = "atcm", "btcm"; + ti,sci = <&dmsc>; + ti,sci-dev-id = <248>; + ti,sci-proc-ids = <0x09 0xff>; + resets = <&k3_reset 248 1>; + firmware-name = "j7-main-r5f1_1-fw"; + ti,atcm-enable = <1>; + ti,btcm-enable = <1>; + ti,loczrama = <1>; + }; + }; + c66_0: dsp@4d80800000 { compatible = "ti,j721e-c66-dsp"; reg = <0x4d 0x80800000 0x00 0x00048000>, diff --git a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi index e581cb1d87ee..6c44afae9187 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi @@ -2,7 +2,7 @@ /* * Device Tree Source for J721E SoC Family MCU/WAKEUP Domain peripherals * - * Copyright (C) 2016-2019 Texas Instruments Incorporated - https://www.ti.com/ + * Copyright (C) 2016-2020 Texas Instruments Incorporated - https://www.ti.com/ */ &cbass_mcu_wakeup { @@ -353,4 +353,44 @@ ti,cpts-periodic-outputs = <2>; }; }; + + mcu_r5fss0: r5fss@41000000 { + compatible = "ti,j721e-r5fss"; + ti,cluster-mode = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x41000000 0x00 0x41000000 0x20000>, + <0x41400000 0x00 0x41400000 0x20000>; + power-domains = <&k3_pds 249 TI_SCI_PD_EXCLUSIVE>; + + mcu_r5fss0_core0: r5f@41000000 { + compatible = "ti,j721e-r5f"; + reg = <0x41000000 0x00008000>, + <0x41010000 0x00008000>; + reg-names = "atcm", "btcm"; + ti,sci = <&dmsc>; + ti,sci-dev-id = <250>; + ti,sci-proc-ids = <0x01 0xff>; + resets = <&k3_reset 250 1>; + firmware-name = "j7-mcu-r5f0_0-fw"; + ti,atcm-enable = <1>; + ti,btcm-enable = <1>; + ti,loczrama = <1>; + }; + + mcu_r5fss0_core1: r5f@41400000 { + compatible = "ti,j721e-r5f"; + reg = <0x41400000 0x00008000>, + <0x41410000 0x00008000>; + reg-names = "atcm", "btcm"; + ti,sci = <&dmsc>; + ti,sci-dev-id = <251>; + ti,sci-proc-ids = <0x02 0xff>; + resets = <&k3_reset 251 1>; + firmware-name = "j7-mcu-r5f0_1-fw"; + ti,atcm-enable = <1>; + ti,btcm-enable = <1>; + ti,loczrama = <1>; + }; + }; }; diff --git a/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi index 5dc3ba739131..57720e6a04c5 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/ + * Copyright (C) 2019-2020 Texas Instruments Incorporated - https://www.ti.com/ */ /dts-v1/; @@ -26,6 +26,78 @@ no-map; }; + mcu_r5fss0_core0_dma_memory_region: r5f-dma-memory@a0000000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa0000000 0x00 0x100000>; + no-map; + }; + + mcu_r5fss0_core0_memory_region: r5f-memory@a0100000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa0100000 0x00 0xf00000>; + no-map; + }; + + mcu_r5fss0_core1_dma_memory_region: r5f-dma-memory@a1000000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa1000000 0x00 0x100000>; + no-map; + }; + + mcu_r5fss0_core1_memory_region: r5f-memory@a1100000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa1100000 0x00 0xf00000>; + no-map; + }; + + main_r5fss0_core0_dma_memory_region: r5f-dma-memory@a2000000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa2000000 0x00 0x100000>; + no-map; + }; + + main_r5fss0_core0_memory_region: r5f-memory@a2100000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa2100000 0x00 0xf00000>; + no-map; + }; + + main_r5fss0_core1_dma_memory_region: r5f-dma-memory@a3000000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa3000000 0x00 0x100000>; + no-map; + }; + + main_r5fss0_core1_memory_region: r5f-memory@a3100000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa3100000 0x00 0xf00000>; + no-map; + }; + + main_r5fss1_core0_dma_memory_region: r5f-dma-memory@a4000000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa4000000 0x00 0x100000>; + no-map; + }; + + main_r5fss1_core0_memory_region: r5f-memory@a4100000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa4100000 0x00 0xf00000>; + no-map; + }; + + main_r5fss1_core1_dma_memory_region: r5f-dma-memory@a5000000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa5000000 0x00 0x100000>; + no-map; + }; + + main_r5fss1_core1_memory_region: r5f-memory@a5100000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa5100000 0x00 0xf00000>; + no-map; + }; + c66_1_dma_memory_region: c66-dma-memory@a6000000 { compatible = "shared-dma-pool"; reg = <0x00 0xa6000000 0x00 0x100000>; @@ -208,6 +280,42 @@ status = "disabled"; }; +&mcu_r5fss0_core0 { + mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>; + memory-region = <&mcu_r5fss0_core0_dma_memory_region>, + <&mcu_r5fss0_core0_memory_region>; +}; + +&mcu_r5fss0_core1 { + mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core1>; + memory-region = <&mcu_r5fss0_core1_dma_memory_region>, + <&mcu_r5fss0_core1_memory_region>; +}; + +&main_r5fss0_core0 { + mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core0>; + memory-region = <&main_r5fss0_core0_dma_memory_region>, + <&main_r5fss0_core0_memory_region>; +}; + +&main_r5fss0_core1 { + mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core1>; + memory-region = <&main_r5fss0_core1_dma_memory_region>, + <&main_r5fss0_core1_memory_region>; +}; + +&main_r5fss1_core0 { + mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core0>; + memory-region = <&main_r5fss1_core0_dma_memory_region>, + <&main_r5fss1_core0_memory_region>; +}; + +&main_r5fss1_core1 { + mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core1>; + memory-region = <&main_r5fss1_core1_dma_memory_region>, + <&main_r5fss1_core1_memory_region>; +}; + &c66_0 { mboxes = <&mailbox0_cluster3 &mbox_c66_0>; memory-region = <&c66_0_dma_memory_region>, diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index 771f60e0346d..68923fbd0e89 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -99,6 +99,29 @@ }; }; + zynqmp_ipi { + compatible = "xlnx,zynqmp-ipi-mailbox"; + interrupt-parent = <&gic>; + interrupts = <0 35 4>; + xlnx,ipi-id = <0>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + ipi_mailbox_pmu1: mailbox@ff990400 { + reg = <0x0 0xff9905c0 0x0 0x20>, + <0x0 0xff9905e0 0x0 0x20>, + <0x0 0xff990e80 0x0 0x20>, + <0x0 0xff990ea0 0x0 0x20>; + reg-names = "local_request_region", + "local_response_region", + "remote_request_region", + "remote_response_region"; + #mbox-cells = <1>; + xlnx,ipi-id = <4>; + }; + }; + dcc: dcc { compatible = "arm,dcc"; status = "disabled"; @@ -128,6 +151,8 @@ compatible = "xlnx,zynqmp-power"; interrupt-parent = <&gic>; interrupts = <0 35 4>; + mboxes = <&ipi_mailbox_pmu1 0>, <&ipi_mailbox_pmu1 1>; + mbox-names = "tx", "rx"; }; zynqmp_clk: clock-controller { @@ -182,25 +207,6 @@ ranges; }; - amba_apu: axi@0 { - compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - ranges = <0 0 0 0 0xffffffff>; - - gic: interrupt-controller@f9010000 { - compatible = "arm,gic-400"; - #interrupt-cells = <3>; - reg = <0x0 0xf9010000 0x10000>, - <0x0 0xf9020000 0x20000>, - <0x0 0xf9040000 0x20000>, - <0x0 0xf9060000 0x20000>; - interrupt-controller; - interrupt-parent = <&gic>; - interrupts = <1 9 0xf04>; - }; - }; - amba: axi { compatible = "simple-bus"; #address-cells = <2>; @@ -339,6 +345,18 @@ power-domains = <&zynqmp_firmware PD_GDMA>; }; + gic: interrupt-controller@f9010000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + reg = <0x0 0xf9010000 0x0 0x10000>, + <0x0 0xf9020000 0x0 0x20000>, + <0x0 0xf9040000 0x0 0x20000>, + <0x0 0xf9060000 0x0 0x20000>; + interrupt-controller; + interrupt-parent = <&gic>; + interrupts = <1 9 0xf04>; + }; + /* LPDDMA default allows only secured access. inorder to enable * These dma channels, Users should ensure that these dma * Channels are allowed for non secure access. @@ -542,8 +560,8 @@ <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 */ + ranges = <0x02000000 0x00000000 0xe0000000 0x00000000 0xe0000000 0x00000000 0x10000000>,/* non-prefetchable memory */ + <0x43000000 0x00000006 0x00000000 0x00000006 0x00000000 0x00000002 0x00000000>;/* prefetchable memory */ bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc 0x1>, diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index d93ffbdedfc0..838301650a79 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -32,6 +32,7 @@ CONFIG_ARCH_AGILEX=y CONFIG_ARCH_SUNXI=y CONFIG_ARCH_ALPINE=y CONFIG_ARCH_BCM2835=y +CONFIG_ARCH_BCM4908=y CONFIG_ARCH_BCM_IPROC=y CONFIG_ARCH_BERLIN=y CONFIG_ARCH_BRCMSTB=y @@ -93,12 +94,15 @@ CONFIG_ARM_IMX_CPUFREQ_DT=m CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y CONFIG_ARM_QCOM_CPUFREQ_HW=y CONFIG_ARM_RASPBERRYPI_CPUFREQ=m +CONFIG_ARM_SCMI_CPUFREQ=y CONFIG_ARM_TEGRA186_CPUFREQ=y CONFIG_QORIQ_CPUFREQ=y +CONFIG_ARM_SCMI_PROTOCOL=y CONFIG_ARM_SCPI_PROTOCOL=y CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_INTEL_STRATIX10_SERVICE=y CONFIG_INTEL_STRATIX10_RSU=m +CONFIG_QCOM_SCM=y CONFIG_EFI_CAPSULE_LOADER=y CONFIG_IMX_SCU=y CONFIG_IMX_SCU_PD=y @@ -240,6 +244,8 @@ CONFIG_HISILICON_LPC=y CONFIG_SIMPLE_PM_BUS=y CONFIG_FSL_MC_BUS=y CONFIG_TEGRA_ACONNECT=m +CONFIG_GNSS=m +CONFIG_GNSS_MTK_SERIAL=m CONFIG_MTD=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y @@ -381,6 +387,7 @@ CONFIG_KEYBOARD_IMX_SC_KEY=m CONFIG_KEYBOARD_CROS_EC=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ATMEL_MXT=m +CONFIG_TOUCHSCREEN_EDT_FT5X06=m CONFIG_INPUT_MISC=y CONFIG_INPUT_PM8941_PWRKEY=y CONFIG_INPUT_PM8XXX_VIBRATOR=m @@ -438,6 +445,7 @@ CONFIG_I2C_IMX=y CONFIG_I2C_IMX_LPI2C=y CONFIG_I2C_MESON=y CONFIG_I2C_MV64XXX=y +CONFIG_I2C_OMAP=y CONFIG_I2C_OWL=y CONFIG_I2C_PXA=y CONFIG_I2C_QCOM_CCI=m @@ -498,6 +506,7 @@ CONFIG_PINCTRL_SDM845=y CONFIG_PINCTRL_SM8150=y CONFIG_PINCTRL_SM8250=y CONFIG_GPIO_ALTERA=m +CONFIG_GPIO_DAVINCI=y CONFIG_GPIO_DWAPB=y CONFIG_GPIO_MB86S7X=y CONFIG_GPIO_MPC8XXX=y @@ -518,11 +527,15 @@ CONFIG_POWER_AVS=y CONFIG_QCOM_CPR=y CONFIG_ROCKCHIP_IODOMAIN=y CONFIG_POWER_RESET_MSM=y +CONFIG_POWER_RESET_QCOM_PON=m CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y CONFIG_SYSCON_REBOOT_MODE=y CONFIG_BATTERY_SBS=m CONFIG_BATTERY_BQ27XXX=y +CONFIG_SENSORS_ARM_SCMI=y +CONFIG_BATTERY_MAX17042=m +CONFIG_CHARGER_BQ25980=m CONFIG_SENSORS_ARM_SCPI=y CONFIG_SENSORS_LM90=m CONFIG_SENSORS_PWM_FAN=m @@ -597,6 +610,7 @@ CONFIG_REGULATOR_QCOM_SMD_RPM=y CONFIG_REGULATOR_QCOM_SPMI=y CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_S2MPS11=y +CONFIG_REGULATOR_TPS65132=m CONFIG_REGULATOR_VCTRL=m CONFIG_RC_CORE=m CONFIG_RC_DECODERS=y @@ -647,6 +661,7 @@ CONFIG_ROCKCHIP_CDN_DP=y CONFIG_ROCKCHIP_DW_HDMI=y CONFIG_ROCKCHIP_DW_MIPI_DSI=y CONFIG_ROCKCHIP_INNO_HDMI=y +CONFIG_ROCKCHIP_LVDS=y CONFIG_DRM_RCAR_DU=m CONFIG_DRM_RCAR_DW_HDMI=m CONFIG_DRM_SUN4I=m @@ -657,6 +672,7 @@ CONFIG_DRM_MSM=m CONFIG_DRM_TEGRA=m CONFIG_DRM_PANEL_LVDS=m CONFIG_DRM_PANEL_SIMPLE=m +CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m CONFIG_DRM_PANEL_RAYDIUM_RM67191=m CONFIG_DRM_PANEL_SITRONIX_ST7703=m CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m @@ -671,6 +687,7 @@ CONFIG_DRM_I2C_ADV7511=m CONFIG_DRM_I2C_ADV7511_AUDIO=y CONFIG_DRM_DW_HDMI_AHB_AUDIO=m CONFIG_DRM_DW_HDMI_CEC=m +CONFIG_DRM_IMX_DCSS=m CONFIG_DRM_VC4=m CONFIG_DRM_ETNAVIV=m CONFIG_DRM_HISI_HIBMC=m @@ -683,7 +700,6 @@ CONFIG_DRM_PANFROST=m CONFIG_FB=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_EFI=y -CONFIG_BACKLIGHT_GENERIC=m CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_LP855X=m CONFIG_LOGO=y @@ -696,6 +712,12 @@ CONFIG_SND_HDA_CODEC_HDMI=m CONFIG_SND_SOC=y CONFIG_SND_BCM2835_SOC_I2S=m CONFIG_SND_SOC_FSL_SAI=m +CONFIG_SND_SOC_FSL_ASRC=m +CONFIG_SND_SOC_FSL_MICFIL=m +CONFIG_SND_SOC_FSL_EASRC=m +CONFIG_SND_IMX_SOC=m +CONFIG_SND_SOC_IMX_SPDIF=m +CONFIG_SND_SOC_IMX_AUDMIX=m CONFIG_SND_MESON_AXG_SOUND_CARD=m CONFIG_SND_MESON_GX_SOUND_CARD=m CONFIG_SND_SOC_QCOM=m @@ -708,6 +730,7 @@ CONFIG_SND_SOC_ROCKCHIP_RT5645=m CONFIG_SND_SOC_RK3399_GRU_SOUND=m CONFIG_SND_SOC_SAMSUNG=y CONFIG_SND_SOC_RCAR=m +CONFIG_SND_SUN4I_I2S=m CONFIG_SND_SUN4I_SPDIF=m CONFIG_SND_SOC_TEGRA=m CONFIG_SND_SOC_TEGRA210_AHUB=m @@ -751,6 +774,7 @@ CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y CONFIG_USB_ISP1760=y CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_CP210X=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_HSIC_USB3503=y CONFIG_NOP_USB_XCEIV=y @@ -773,6 +797,7 @@ CONFIG_TYPEC=m CONFIG_TYPEC_TCPM=m CONFIG_TYPEC_FUSB302=m CONFIG_TYPEC_HD3SS3220=m +CONFIG_TYPEC_TPS6598X=m CONFIG_MMC=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_ARMMMCI=y @@ -802,6 +827,7 @@ CONFIG_MMC_SDHCI_AM654=y CONFIG_MMC_OWL=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y +CONFIG_LEDS_LM3692X=m CONFIG_LEDS_GPIO=y CONFIG_LEDS_PWM=y CONFIG_LEDS_SYSCON=y @@ -815,6 +841,7 @@ CONFIG_EDAC=y CONFIG_EDAC_GHES=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_HYM8563=m CONFIG_RTC_DRV_MAX77686=y CONFIG_RTC_DRV_RK808=m CONFIG_RTC_DRV_PCF85363=m @@ -866,6 +893,7 @@ CONFIG_CROS_EC=y CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_SPI=y CONFIG_CROS_EC_CHARDEV=m +CONFIG_COMMON_CLK_SCMI=y CONFIG_COMMON_CLK_RK808=y CONFIG_COMMON_CLK_SCPI=y CONFIG_COMMON_CLK_CS2000_CP=y @@ -931,6 +959,7 @@ CONFIG_RASPBERRYPI_POWER=y CONFIG_FSL_DPAA=y CONFIG_FSL_MC_DPIO=y CONFIG_QCOM_AOSS_QMP=y +CONFIG_QCOM_COMMAND_DB=y CONFIG_QCOM_GENI_SE=y CONFIG_QCOM_RMTFS_MEM=m CONFIG_QCOM_RPMH=y @@ -955,11 +984,13 @@ CONFIG_ARCH_R8A77970=y CONFIG_ARCH_R8A77980=y CONFIG_ARCH_R8A77990=y CONFIG_ARCH_R8A77995=y +CONFIG_ARCH_R8A779A0=y CONFIG_ROCKCHIP_PM_DOMAINS=y CONFIG_ARCH_TEGRA_132_SOC=y CONFIG_ARCH_TEGRA_210_SOC=y CONFIG_ARCH_TEGRA_186_SOC=y CONFIG_ARCH_TEGRA_194_SOC=y +CONFIG_ARCH_TEGRA_234_SOC=y CONFIG_ARCH_K3_AM6_SOC=y CONFIG_ARCH_K3_J721E_SOC=y CONFIG_TI_SCI_PM_DOMAINS=y @@ -974,8 +1005,10 @@ CONFIG_QCOM_SPMI_ADC5=m CONFIG_ROCKCHIP_SARADC=m CONFIG_IIO_CROS_EC_SENSORS_CORE=m CONFIG_IIO_CROS_EC_SENSORS=m +CONFIG_IIO_ST_LSM6DSX=m CONFIG_IIO_CROS_EC_LIGHT_PROX=m CONFIG_SENSORS_ISL29018=m +CONFIG_VCNL4000=m CONFIG_IIO_CROS_EC_BARO=m CONFIG_MPL3115=m CONFIG_PWM=y @@ -1011,6 +1044,7 @@ CONFIG_PHY_RCAR_GEN3_USB3=m CONFIG_PHY_ROCKCHIP_EMMC=y CONFIG_PHY_ROCKCHIP_INNO_HDMI=m CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=m CONFIG_PHY_ROCKCHIP_PCIE=m CONFIG_PHY_ROCKCHIP_TYPEC=y CONFIG_PHY_UNIPHIER_USB2=y @@ -1043,6 +1077,7 @@ CONFIG_MUX_MMIO=y CONFIG_INTERCONNECT=y CONFIG_INTERCONNECT_QCOM=y CONFIG_INTERCONNECT_QCOM_MSM8916=m +CONFIG_INTERCONNECT_QCOM_OSM_L3=m CONFIG_INTERCONNECT_QCOM_SDM845=m CONFIG_INTERCONNECT_QCOM_SM8150=m CONFIG_INTERCONNECT_QCOM_SM8250=m diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index ff9cbb631212..07ac208edc89 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 generic-y += early_ioremap.h -generic-y += local64.h generic-y += mcs_spinlock.h generic-y += qrwlock.h generic-y += qspinlock.h diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index ddbe6bf00e33..bf125c591116 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -473,7 +473,7 @@ USER(\label, ic ivau, \tmp2) // invalidate I line PoU #define NOKPROBE(x) #endif -#ifdef CONFIG_KASAN +#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) #define EXPORT_SYMBOL_NOKASAN(name) #else #define EXPORT_SYMBOL_NOKASAN(name) EXPORT_SYMBOL(name) diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h index 015ddffaf6ca..b56a4b2bc248 100644 --- a/arch/arm64/include/asm/atomic.h +++ b/arch/arm64/include/asm/atomic.h @@ -17,7 +17,7 @@ #include <asm/lse.h> #define ATOMIC_OP(op) \ -static inline void arch_##op(int i, atomic_t *v) \ +static __always_inline void arch_##op(int i, atomic_t *v) \ { \ __lse_ll_sc_body(op, i, v); \ } @@ -32,7 +32,7 @@ ATOMIC_OP(atomic_sub) #undef ATOMIC_OP #define ATOMIC_FETCH_OP(name, op) \ -static inline int arch_##op##name(int i, atomic_t *v) \ +static __always_inline int arch_##op##name(int i, atomic_t *v) \ { \ return __lse_ll_sc_body(op##name, i, v); \ } @@ -56,7 +56,7 @@ ATOMIC_FETCH_OPS(atomic_sub_return) #undef ATOMIC_FETCH_OPS #define ATOMIC64_OP(op) \ -static inline void arch_##op(long i, atomic64_t *v) \ +static __always_inline void arch_##op(long i, atomic64_t *v) \ { \ __lse_ll_sc_body(op, i, v); \ } @@ -71,7 +71,7 @@ ATOMIC64_OP(atomic64_sub) #undef ATOMIC64_OP #define ATOMIC64_FETCH_OP(name, op) \ -static inline long arch_##op##name(long i, atomic64_t *v) \ +static __always_inline long arch_##op##name(long i, atomic64_t *v) \ { \ return __lse_ll_sc_body(op##name, i, v); \ } @@ -94,7 +94,7 @@ ATOMIC64_FETCH_OPS(atomic64_sub_return) #undef ATOMIC64_FETCH_OP #undef ATOMIC64_FETCH_OPS -static inline long arch_atomic64_dec_if_positive(atomic64_t *v) +static __always_inline long arch_atomic64_dec_if_positive(atomic64_t *v) { return __lse_ll_sc_body(atomic64_dec_if_positive, v); } diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h index 63d43b5f82f6..77cbbe3625f2 100644 --- a/arch/arm64/include/asm/cache.h +++ b/arch/arm64/include/asm/cache.h @@ -6,6 +6,7 @@ #define __ASM_CACHE_H #include <asm/cputype.h> +#include <asm/mte-kasan.h> #define CTR_L1IP_SHIFT 14 #define CTR_L1IP_MASK 3 @@ -51,6 +52,8 @@ #ifdef CONFIG_KASAN_SW_TAGS #define ARCH_SLAB_MINALIGN (1ULL << KASAN_SHADOW_SCALE_SHIFT) +#elif defined(CONFIG_KASAN_HW_TAGS) +#define ARCH_SLAB_MINALIGN MTE_GRANULE_SIZE #endif #ifndef __ASSEMBLY__ diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index a7242ef2a2cd..b77d997b173b 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -19,7 +19,7 @@ #define ARM64_HAS_VIRT_HOST_EXTN 11 #define ARM64_WORKAROUND_CAVIUM_27456 12 #define ARM64_HAS_32BIT_EL0 13 -#define ARM64_HARDEN_EL2_VECTORS 14 +#define ARM64_SPECTRE_V3A 14 #define ARM64_HAS_CNP 15 #define ARM64_HAS_NO_FPSIMD 16 #define ARM64_WORKAROUND_REPEAT_TLBI 17 @@ -65,7 +65,8 @@ #define ARM64_MTE 57 #define ARM64_WORKAROUND_1508412 58 #define ARM64_HAS_LDAPR 59 +#define ARM64_KVM_PROTECTED_MODE 60 -#define ARM64_NCAPS 60 +#define ARM64_NCAPS 61 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 1c406e8ae27e..9a555809b89c 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -705,6 +705,11 @@ static inline bool system_supports_generic_auth(void) cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH); } +static inline bool system_has_full_ptr_auth(void) +{ + return system_supports_address_auth() && system_supports_generic_auth(); +} + static __always_inline bool system_uses_irq_prio_masking(void) { return IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) && diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 973b14415271..3578aba9c608 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -64,12 +64,6 @@ efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...); #define EFI_KIMG_ALIGN \ (SEGMENT_ALIGN > THREAD_ALIGN ? SEGMENT_ALIGN : THREAD_ALIGN) -/* on arm64, the FDT may be located anywhere in system RAM */ -static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr) -{ - return ULONG_MAX; -} - /* * On arm64, we have to ensure that the initrd ends up in the linear region, * which is a 1 GB aligned region of size '1UL << (VA_BITS_MIN - 1)' that is @@ -141,4 +135,9 @@ static inline void efi_set_pgd(struct mm_struct *mm) void efi_virtmap_load(void); void efi_virtmap_unload(void); +static inline void efi_capsule_flush_cache_range(void *addr, int size) +{ + __flush_dcache_area(addr, size); +} + #endif /* _ASM_EFI_H */ diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h new file mode 100644 index 000000000000..a7f5a1bbc8ac --- /dev/null +++ b/arch/arm64/include/asm/el2_setup.h @@ -0,0 +1,181 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2012,2013 - ARM Ltd + * Author: Marc Zyngier <marc.zyngier@arm.com> + */ + +#ifndef __ARM_KVM_INIT_H__ +#define __ARM_KVM_INIT_H__ + +#ifndef __ASSEMBLY__ +#error Assembly-only header +#endif + +#include <asm/kvm_arm.h> +#include <asm/ptrace.h> +#include <asm/sysreg.h> +#include <linux/irqchip/arm-gic-v3.h> + +.macro __init_el2_sctlr + mov_q x0, INIT_SCTLR_EL2_MMU_OFF + msr sctlr_el2, x0 + isb +.endm + +/* + * Allow Non-secure EL1 and EL0 to access physical timer and counter. + * This is not necessary for VHE, since the host kernel runs in EL2, + * and EL0 accesses are configured in the later stage of boot process. + * Note that when HCR_EL2.E2H == 1, CNTHCTL_EL2 has the same bit layout + * as CNTKCTL_EL1, and CNTKCTL_EL1 accessing instructions are redefined + * to access CNTHCTL_EL2. This allows the kernel designed to run at EL1 + * to transparently mess with the EL0 bits via CNTKCTL_EL1 access in + * EL2. + */ +.macro __init_el2_timers mode +.ifeqs "\mode", "nvhe" + mrs x0, cnthctl_el2 + orr x0, x0, #3 // Enable EL1 physical timers + msr cnthctl_el2, x0 +.endif + msr cntvoff_el2, xzr // Clear virtual offset +.endm + +.macro __init_el2_debug mode + mrs x1, id_aa64dfr0_el1 + sbfx x0, x1, #ID_AA64DFR0_PMUVER_SHIFT, #4 + cmp x0, #1 + b.lt 1f // Skip if no PMU present + mrs x0, pmcr_el0 // Disable debug access traps + ubfx x0, x0, #11, #5 // to EL2 and allow access to +1: + csel x2, xzr, x0, lt // all PMU counters from EL1 + + /* Statistical profiling */ + ubfx x0, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4 + cbz x0, 3f // Skip if SPE not present + +.ifeqs "\mode", "nvhe" + mrs_s x0, SYS_PMBIDR_EL1 // If SPE available at EL2, + and x0, x0, #(1 << SYS_PMBIDR_EL1_P_SHIFT) + cbnz x0, 2f // then permit sampling of physical + mov x0, #(1 << SYS_PMSCR_EL2_PCT_SHIFT | \ + 1 << SYS_PMSCR_EL2_PA_SHIFT) + msr_s SYS_PMSCR_EL2, x0 // addresses and physical counter +2: + mov x0, #(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT) + orr x2, x2, x0 // If we don't have VHE, then + // use EL1&0 translation. +.else + orr x2, x2, #MDCR_EL2_TPMS // For VHE, use EL2 translation + // and disable access from EL1 +.endif + +3: + msr mdcr_el2, x2 // Configure debug traps +.endm + +/* LORegions */ +.macro __init_el2_lor + mrs x1, id_aa64mmfr1_el1 + ubfx x0, x1, #ID_AA64MMFR1_LOR_SHIFT, 4 + cbz x0, 1f + msr_s SYS_LORC_EL1, xzr +1: +.endm + +/* Stage-2 translation */ +.macro __init_el2_stage2 + msr vttbr_el2, xzr +.endm + +/* GICv3 system register access */ +.macro __init_el2_gicv3 + mrs x0, id_aa64pfr0_el1 + ubfx x0, x0, #ID_AA64PFR0_GIC_SHIFT, #4 + cbz x0, 1f + + mrs_s x0, SYS_ICC_SRE_EL2 + orr x0, x0, #ICC_SRE_EL2_SRE // Set ICC_SRE_EL2.SRE==1 + orr x0, x0, #ICC_SRE_EL2_ENABLE // Set ICC_SRE_EL2.Enable==1 + msr_s SYS_ICC_SRE_EL2, x0 + isb // Make sure SRE is now set + mrs_s x0, SYS_ICC_SRE_EL2 // Read SRE back, + tbz x0, #0, 1f // and check that it sticks + msr_s SYS_ICH_HCR_EL2, xzr // Reset ICC_HCR_EL2 to defaults +1: +.endm + +.macro __init_el2_hstr + msr hstr_el2, xzr // Disable CP15 traps to EL2 +.endm + +/* Virtual CPU ID registers */ +.macro __init_el2_nvhe_idregs + mrs x0, midr_el1 + mrs x1, mpidr_el1 + msr vpidr_el2, x0 + msr vmpidr_el2, x1 +.endm + +/* Coprocessor traps */ +.macro __init_el2_nvhe_cptr + mov x0, #0x33ff + msr cptr_el2, x0 // Disable copro. traps to EL2 +.endm + +/* SVE register access */ +.macro __init_el2_nvhe_sve + mrs x1, id_aa64pfr0_el1 + ubfx x1, x1, #ID_AA64PFR0_SVE_SHIFT, #4 + cbz x1, 1f + + bic x0, x0, #CPTR_EL2_TZ // Also disable SVE traps + msr cptr_el2, x0 // Disable copro. traps to EL2 + isb + mov x1, #ZCR_ELx_LEN_MASK // SVE: Enable full vector + msr_s SYS_ZCR_EL2, x1 // length for EL1. +1: +.endm + +.macro __init_el2_nvhe_prepare_eret + mov x0, #INIT_PSTATE_EL1 + msr spsr_el2, x0 +.endm + +/** + * Initialize EL2 registers to sane values. This should be called early on all + * cores that were booted in EL2. + * + * Regs: x0, x1 and x2 are clobbered. + */ +.macro init_el2_state mode +.ifnes "\mode", "vhe" +.ifnes "\mode", "nvhe" +.error "Invalid 'mode' argument" +.endif +.endif + + __init_el2_sctlr + __init_el2_timers \mode + __init_el2_debug \mode + __init_el2_lor + __init_el2_stage2 + __init_el2_gicv3 + __init_el2_hstr + + /* + * When VHE is not in use, early init of EL2 needs to be done here. + * When VHE _is_ in use, EL1 will not be used in the host and + * requires no configuration, and all non-hyp-specific EL2 setup + * will be done via the _EL1 system register aliases in __cpu_setup. + */ +.ifeqs "\mode", "nvhe" + __init_el2_nvhe_idregs + __init_el2_nvhe_cptr + __init_el2_nvhe_sve + __init_el2_nvhe_prepare_eret +.endif +.endm + +#endif /* __ARM_KVM_INIT_H__ */ diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index 85a3e49f92f4..29f97eb3dad4 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -106,6 +106,7 @@ #define ESR_ELx_FSC_TYPE (0x3C) #define ESR_ELx_FSC_LEVEL (0x03) #define ESR_ELx_FSC_EXTABT (0x10) +#define ESR_ELx_FSC_MTE (0x11) #define ESR_ELx_FSC_SERROR (0x11) #define ESR_ELx_FSC_ACCESS (0x08) #define ESR_ELx_FSC_FAULT (0x04) diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h index 78537393b650..6546158d2f2d 100644 --- a/arch/arm64/include/asm/exception.h +++ b/arch/arm64/include/asm/exception.h @@ -31,6 +31,10 @@ static inline u32 disr_to_esr(u64 disr) return esr; } +asmlinkage void el1_sync_handler(struct pt_regs *regs); +asmlinkage void el0_sync_handler(struct pt_regs *regs); +asmlinkage void el0_sync_compat_handler(struct pt_regs *regs); + asmlinkage void noinstr enter_el1_irq_or_nmi(struct pt_regs *regs); asmlinkage void noinstr exit_el1_irq_or_nmi(struct pt_regs *regs); asmlinkage void enter_from_user_mode(void); diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index fd172c41df90..5ea8656a2030 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h @@ -201,6 +201,4 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size); extern int valid_phys_addr_range(phys_addr_t addr, size_t size); extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); -extern int devmem_is_allowed(unsigned long pfn); - #endif /* __ASM_IO_H */ diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h index b0dc4abc3589..0aaf9044cd6a 100644 --- a/arch/arm64/include/asm/kasan.h +++ b/arch/arm64/include/asm/kasan.h @@ -12,7 +12,9 @@ #define arch_kasan_reset_tag(addr) __tag_reset(addr) #define arch_kasan_get_tag(addr) __tag_get(addr) -#ifdef CONFIG_KASAN +#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) + +void kasan_init(void); /* * KASAN_SHADOW_START: beginning of the kernel virtual addresses. @@ -33,7 +35,6 @@ #define _KASAN_SHADOW_START(va) (KASAN_SHADOW_END - (1UL << ((va) - KASAN_SHADOW_SCALE_SHIFT))) #define KASAN_SHADOW_START _KASAN_SHADOW_START(vabits_actual) -void kasan_init(void); void kasan_copy_shadow(pgd_t *pgdir); asmlinkage void kasan_early_init(void); diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 64ce29378467..4e90c2debf70 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -80,6 +80,7 @@ HCR_FMO | HCR_IMO | HCR_PTW ) #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF) #define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_ATA) +#define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC) #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H) /* TCR_EL2 Registers bits */ diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 54387ccd1ab2..8a33d83ea843 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -34,8 +34,6 @@ */ #define KVM_VECTOR_PREAMBLE (2 * AARCH64_INSN_SIZE) -#define __SMCCC_WORKAROUND_1_SMC_SZ 36 - #define KVM_HOST_SMCCC_ID(id) \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ @@ -150,6 +148,14 @@ extern void *__vhe_undefined_symbol; #endif +struct kvm_nvhe_init_params { + unsigned long mair_el2; + unsigned long tcr_el2; + unsigned long tpidr_el2; + unsigned long stack_hyp_va; + phys_addr_t pgd_pa; +}; + /* Translate a kernel address @ptr into its equivalent linear mapping */ #define kvm_ksym_ref(ptr) \ ({ \ @@ -165,17 +171,14 @@ struct kvm_vcpu; struct kvm_s2_mmu; DECLARE_KVM_NVHE_SYM(__kvm_hyp_init); -DECLARE_KVM_NVHE_SYM(__kvm_hyp_host_vector); DECLARE_KVM_HYP_SYM(__kvm_hyp_vector); #define __kvm_hyp_init CHOOSE_NVHE_SYM(__kvm_hyp_init) -#define __kvm_hyp_host_vector CHOOSE_NVHE_SYM(__kvm_hyp_host_vector) #define __kvm_hyp_vector CHOOSE_HYP_SYM(__kvm_hyp_vector) extern unsigned long kvm_arm_hyp_percpu_base[NR_CPUS]; DECLARE_KVM_NVHE_SYM(__per_cpu_start); DECLARE_KVM_NVHE_SYM(__per_cpu_end); -extern atomic_t arm64_el2_vector_last_slot; DECLARE_KVM_HYP_SYM(__bp_harden_hyp_vecs); #define __bp_harden_hyp_vecs CHOOSE_HYP_SYM(__bp_harden_hyp_vecs) @@ -189,8 +192,6 @@ extern void __kvm_timer_set_cntvoff(u64 cntvoff); extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); -extern void __kvm_enable_ssbs(void); - extern u64 __vgic_v3_get_ich_vtr_el2(void); extern u64 __vgic_v3_read_vmcr(void); extern void __vgic_v3_write_vmcr(u32 vmcr); @@ -198,7 +199,11 @@ extern void __vgic_v3_init_lrs(void); extern u32 __kvm_get_mdcr_el2(void); -extern char __smccc_workaround_1_smc[__SMCCC_WORKAROUND_1_SMC_SZ]; +#if defined(GCC_VERSION) && GCC_VERSION < 50000 +#define SYM_CONSTRAINT "i" +#else +#define SYM_CONSTRAINT "S" +#endif /* * Obtain the PC-relative address of a kernel symbol @@ -216,7 +221,7 @@ extern char __smccc_workaround_1_smc[__SMCCC_WORKAROUND_1_SMC_SZ]; typeof(s) *addr; \ asm("adrp %0, %1\n" \ "add %0, %0, :lo12:%1\n" \ - : "=r" (addr) : "S" (&s)); \ + : "=r" (addr) : SYM_CONSTRAINT (&s)); \ addr; \ }) diff --git a/arch/arm64/include/asm/kvm_coproc.h b/arch/arm64/include/asm/kvm_coproc.h deleted file mode 100644 index d6bb40122fdb..000000000000 --- a/arch/arm64/include/asm/kvm_coproc.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2012,2013 - ARM Ltd - * Author: Marc Zyngier <marc.zyngier@arm.com> - * - * Derived from arch/arm/include/asm/kvm_coproc.h - * Copyright (C) 2012 Rusty Russell IBM Corporation - */ - -#ifndef __ARM64_KVM_COPROC_H__ -#define __ARM64_KVM_COPROC_H__ - -#include <linux/kvm_host.h> - -void kvm_reset_sys_regs(struct kvm_vcpu *vcpu); - -struct kvm_sys_reg_table { - const struct sys_reg_desc *table; - size_t num; -}; - -int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu); -int kvm_handle_cp14_32(struct kvm_vcpu *vcpu); -int kvm_handle_cp14_64(struct kvm_vcpu *vcpu); -int kvm_handle_cp15_32(struct kvm_vcpu *vcpu); -int kvm_handle_cp15_64(struct kvm_vcpu *vcpu); -int kvm_handle_sys_reg(struct kvm_vcpu *vcpu); - -#define kvm_coproc_table_init kvm_sys_reg_table_init -void kvm_sys_reg_table_init(void); - -struct kvm_one_reg; -int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices); -int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); -int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); -unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu); - -#endif /* __ARM64_KVM_COPROC_H__ */ diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 00bc6f1234ba..f612c090f2e4 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -21,20 +21,25 @@ #include <asm/cputype.h> #include <asm/virt.h> -unsigned long *vcpu_reg32(const struct kvm_vcpu *vcpu, u8 reg_num); -unsigned long vcpu_read_spsr32(const struct kvm_vcpu *vcpu); -void vcpu_write_spsr32(struct kvm_vcpu *vcpu, unsigned long v); +#define CURRENT_EL_SP_EL0_VECTOR 0x0 +#define CURRENT_EL_SP_ELx_VECTOR 0x200 +#define LOWER_EL_AArch64_VECTOR 0x400 +#define LOWER_EL_AArch32_VECTOR 0x600 + +enum exception_type { + except_type_sync = 0, + except_type_irq = 0x80, + except_type_fiq = 0x100, + except_type_serror = 0x180, +}; bool kvm_condition_valid32(const struct kvm_vcpu *vcpu); -void kvm_skip_instr32(struct kvm_vcpu *vcpu, bool is_wide_instr); +void kvm_skip_instr32(struct kvm_vcpu *vcpu); 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); -void kvm_inject_undef32(struct kvm_vcpu *vcpu); -void kvm_inject_dabt32(struct kvm_vcpu *vcpu, unsigned long addr); -void kvm_inject_pabt32(struct kvm_vcpu *vcpu, unsigned long addr); static __always_inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu) { @@ -168,30 +173,6 @@ static __always_inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num, vcpu_gp_regs(vcpu)->regs[reg_num] = val; } -static inline unsigned long vcpu_read_spsr(const struct kvm_vcpu *vcpu) -{ - if (vcpu_mode_is_32bit(vcpu)) - return vcpu_read_spsr32(vcpu); - - if (vcpu->arch.sysregs_loaded_on_cpu) - return read_sysreg_el1(SYS_SPSR); - else - return __vcpu_sys_reg(vcpu, SPSR_EL1); -} - -static inline void vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long v) -{ - if (vcpu_mode_is_32bit(vcpu)) { - vcpu_write_spsr32(vcpu, v); - return; - } - - if (vcpu->arch.sysregs_loaded_on_cpu) - write_sysreg_el1(v, SYS_SPSR); - else - __vcpu_sys_reg(vcpu, SPSR_EL1) = v; -} - /* * The layout of SPSR for an AArch32 state is different when observed from an * AArch64 SPSR_ELx or an AArch32 SPSR_*. This function generates the AArch32 @@ -477,32 +458,9 @@ static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu, return data; /* Leave LE untouched */ } -static __always_inline void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr) -{ - if (vcpu_mode_is_32bit(vcpu)) { - kvm_skip_instr32(vcpu, is_wide_instr); - } else { - *vcpu_pc(vcpu) += 4; - *vcpu_cpsr(vcpu) &= ~PSR_BTYPE_MASK; - } - - /* advance the singlestep state machine */ - *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; -} - -/* - * Skip an instruction which has been emulated at hyp while most guest sysregs - * are live. - */ -static __always_inline void __kvm_skip_instr(struct kvm_vcpu *vcpu) +static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu) { - *vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR); - vcpu_gp_regs(vcpu)->pstate = read_sysreg_el2(SYS_SPSR); - - kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); - - write_sysreg_el2(vcpu_gp_regs(vcpu)->pstate, SYS_SPSR); - write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR); + vcpu->arch.flags |= KVM_ARM64_INCREMENT_PC; } #endif /* __ARM64_KVM_EMULATE_H__ */ diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 0cd9f0f75c13..8fcfab0c2567 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -17,6 +17,7 @@ #include <linux/jump_label.h> #include <linux/kvm_types.h> #include <linux/percpu.h> +#include <linux/psci.h> #include <asm/arch_gicv3.h> #include <asm/barrier.h> #include <asm/cpufeature.h> @@ -50,6 +51,16 @@ #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ KVM_DIRTY_LOG_INITIALLY_SET) +/* + * Mode of operation configurable with kvm-arm.mode early param. + * See Documentation/admin-guide/kernel-parameters.txt for more information. + */ +enum kvm_mode { + KVM_MODE_DEFAULT, + KVM_MODE_PROTECTED, +}; +enum kvm_mode kvm_get_mode(void); + DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use); extern unsigned int kvm_sve_max_vl; @@ -58,8 +69,6 @@ int kvm_arm_init_sve(void); int __attribute_const__ kvm_target_cpu(void); int kvm_reset_vcpu(struct kvm_vcpu *vcpu); void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu); -int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long ext); -void __extended_idmap_trampoline(phys_addr_t boot_pgd, phys_addr_t idmap_start); struct kvm_vmid { /* The VMID generation used for the virt. memory system */ @@ -89,6 +98,9 @@ struct kvm_s2_mmu { struct kvm *kvm; }; +struct kvm_arch_memory_slot { +}; + struct kvm_arch { struct kvm_s2_mmu mmu; @@ -120,6 +132,7 @@ struct kvm_arch { unsigned int pmuver; u8 pfr0_csv2; + u8 pfr0_csv3; }; struct kvm_vcpu_fault_info { @@ -203,48 +216,6 @@ enum vcpu_sysreg { NR_SYS_REGS /* Nothing after this line! */ }; -/* 32bit mapping */ -#define c0_MPIDR (MPIDR_EL1 * 2) /* MultiProcessor ID Register */ -#define c0_CSSELR (CSSELR_EL1 * 2)/* Cache Size Selection Register */ -#define c1_SCTLR (SCTLR_EL1 * 2) /* System Control Register */ -#define c1_ACTLR (ACTLR_EL1 * 2) /* Auxiliary Control Register */ -#define c1_CPACR (CPACR_EL1 * 2) /* Coprocessor Access Control */ -#define c2_TTBR0 (TTBR0_EL1 * 2) /* Translation Table Base Register 0 */ -#define c2_TTBR0_high (c2_TTBR0 + 1) /* TTBR0 top 32 bits */ -#define c2_TTBR1 (TTBR1_EL1 * 2) /* Translation Table Base Register 1 */ -#define c2_TTBR1_high (c2_TTBR1 + 1) /* TTBR1 top 32 bits */ -#define c2_TTBCR (TCR_EL1 * 2) /* Translation Table Base Control R. */ -#define c3_DACR (DACR32_EL2 * 2)/* Domain Access Control Register */ -#define c5_DFSR (ESR_EL1 * 2) /* Data Fault Status Register */ -#define c5_IFSR (IFSR32_EL2 * 2)/* Instruction Fault Status Register */ -#define c5_ADFSR (AFSR0_EL1 * 2) /* Auxiliary Data Fault Status R */ -#define c5_AIFSR (AFSR1_EL1 * 2) /* Auxiliary Instr Fault Status R */ -#define c6_DFAR (FAR_EL1 * 2) /* Data Fault Address Register */ -#define c6_IFAR (c6_DFAR + 1) /* Instruction Fault Address Register */ -#define c7_PAR (PAR_EL1 * 2) /* Physical Address Register */ -#define c7_PAR_high (c7_PAR + 1) /* PAR top 32 bits */ -#define c10_PRRR (MAIR_EL1 * 2) /* Primary Region Remap Register */ -#define c10_NMRR (c10_PRRR + 1) /* Normal Memory Remap Register */ -#define c12_VBAR (VBAR_EL1 * 2) /* Vector Base Address Register */ -#define c13_CID (CONTEXTIDR_EL1 * 2) /* Context ID Register */ -#define c13_TID_URW (TPIDR_EL0 * 2) /* Thread ID, User R/W */ -#define c13_TID_URO (TPIDRRO_EL0 * 2)/* Thread ID, User R/O */ -#define c13_TID_PRIV (TPIDR_EL1 * 2) /* Thread ID, Privileged */ -#define c10_AMAIR0 (AMAIR_EL1 * 2) /* Aux Memory Attr Indirection Reg */ -#define c10_AMAIR1 (c10_AMAIR0 + 1)/* Aux Memory Attr Indirection Reg */ -#define c14_CNTKCTL (CNTKCTL_EL1 * 2) /* Timer Control Register (PL1) */ - -#define cp14_DBGDSCRext (MDSCR_EL1 * 2) -#define cp14_DBGBCR0 (DBGBCR0_EL1 * 2) -#define cp14_DBGBVR0 (DBGBVR0_EL1 * 2) -#define cp14_DBGBXVR0 (cp14_DBGBVR0 + 1) -#define cp14_DBGWCR0 (DBGWCR0_EL1 * 2) -#define cp14_DBGWVR0 (DBGWVR0_EL1 * 2) -#define cp14_DBGDCCINT (MDCCINT_EL1 * 2) -#define cp14_DBGVCR (DBGVCR32_EL2 * 2) - -#define NR_COPRO_REGS (NR_SYS_REGS * 2) - struct kvm_cpu_context { struct user_pt_regs regs; /* sp = sp_el0 */ @@ -255,10 +226,7 @@ struct kvm_cpu_context { struct user_fpsimd_state fp_regs; - union { - u64 sys_regs[NR_SYS_REGS]; - u32 copro[NR_COPRO_REGS]; - }; + u64 sys_regs[NR_SYS_REGS]; struct kvm_vcpu *__hyp_running_vcpu; }; @@ -273,6 +241,28 @@ struct kvm_host_data { struct kvm_pmu_events pmu_events; }; +struct kvm_host_psci_config { + /* PSCI version used by host. */ + u32 version; + + /* Function IDs used by host if version is v0.1. */ + struct psci_0_1_function_ids function_ids_0_1; + + bool psci_0_1_cpu_suspend_implemented; + bool psci_0_1_cpu_on_implemented; + bool psci_0_1_cpu_off_implemented; + bool psci_0_1_migrate_implemented; +}; + +extern struct kvm_host_psci_config kvm_nvhe_sym(kvm_host_psci_config); +#define kvm_host_psci_config CHOOSE_NVHE_SYM(kvm_host_psci_config) + +extern s64 kvm_nvhe_sym(hyp_physvirt_offset); +#define hyp_physvirt_offset CHOOSE_NVHE_SYM(hyp_physvirt_offset) + +extern u64 kvm_nvhe_sym(hyp_cpu_logical_map)[NR_CPUS]; +#define hyp_cpu_logical_map CHOOSE_NVHE_SYM(hyp_cpu_logical_map) + struct vcpu_reset_state { unsigned long pc; unsigned long r0; @@ -409,8 +399,33 @@ struct kvm_vcpu_arch { #define KVM_ARM64_GUEST_HAS_SVE (1 << 5) /* SVE exposed to guest */ #define KVM_ARM64_VCPU_SVE_FINALIZED (1 << 6) /* SVE config completed */ #define KVM_ARM64_GUEST_HAS_PTRAUTH (1 << 7) /* PTRAUTH exposed to guest */ +#define KVM_ARM64_PENDING_EXCEPTION (1 << 8) /* Exception pending */ +#define KVM_ARM64_EXCEPT_MASK (7 << 9) /* Target EL/MODE */ + +/* + * When KVM_ARM64_PENDING_EXCEPTION is set, KVM_ARM64_EXCEPT_MASK can + * take the following values: + * + * For AArch32 EL1: + */ +#define KVM_ARM64_EXCEPT_AA32_UND (0 << 9) +#define KVM_ARM64_EXCEPT_AA32_IABT (1 << 9) +#define KVM_ARM64_EXCEPT_AA32_DABT (2 << 9) +/* For AArch64: */ +#define KVM_ARM64_EXCEPT_AA64_ELx_SYNC (0 << 9) +#define KVM_ARM64_EXCEPT_AA64_ELx_IRQ (1 << 9) +#define KVM_ARM64_EXCEPT_AA64_ELx_FIQ (2 << 9) +#define KVM_ARM64_EXCEPT_AA64_ELx_SERR (3 << 9) +#define KVM_ARM64_EXCEPT_AA64_EL1 (0 << 11) +#define KVM_ARM64_EXCEPT_AA64_EL2 (1 << 11) + +/* + * Overlaps with KVM_ARM64_EXCEPT_MASK on purpose so that it can't be + * set together with an exception... + */ +#define KVM_ARM64_INCREMENT_PC (1 << 9) /* Increment PC */ -#define vcpu_has_sve(vcpu) (system_supports_sve() && \ +#define vcpu_has_sve(vcpu) (system_supports_sve() && \ ((vcpu)->arch.flags & KVM_ARM64_GUEST_HAS_SVE)) #ifdef CONFIG_ARM64_PTR_AUTH @@ -440,14 +455,96 @@ struct kvm_vcpu_arch { u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg); void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg); -/* - * CP14 and CP15 live in the same array, as they are backed by the - * same system registers. - */ -#define CPx_BIAS IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) +static inline bool __vcpu_read_sys_reg_from_cpu(int reg, u64 *val) +{ + /* + * *** VHE ONLY *** + * + * System registers listed in the switch are not saved on every + * exit from the guest but are only saved on vcpu_put. + * + * Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but + * should never be listed below, because the guest cannot modify its + * own MPIDR_EL1 and MPIDR_EL1 is accessed for VCPU A from VCPU B's + * thread when emulating cross-VCPU communication. + */ + if (!has_vhe()) + return false; + + switch (reg) { + case CSSELR_EL1: *val = read_sysreg_s(SYS_CSSELR_EL1); break; + case SCTLR_EL1: *val = read_sysreg_s(SYS_SCTLR_EL12); break; + case CPACR_EL1: *val = read_sysreg_s(SYS_CPACR_EL12); break; + case TTBR0_EL1: *val = read_sysreg_s(SYS_TTBR0_EL12); break; + case TTBR1_EL1: *val = read_sysreg_s(SYS_TTBR1_EL12); break; + case TCR_EL1: *val = read_sysreg_s(SYS_TCR_EL12); break; + case ESR_EL1: *val = read_sysreg_s(SYS_ESR_EL12); break; + case AFSR0_EL1: *val = read_sysreg_s(SYS_AFSR0_EL12); break; + case AFSR1_EL1: *val = read_sysreg_s(SYS_AFSR1_EL12); break; + case FAR_EL1: *val = read_sysreg_s(SYS_FAR_EL12); break; + case MAIR_EL1: *val = read_sysreg_s(SYS_MAIR_EL12); break; + case VBAR_EL1: *val = read_sysreg_s(SYS_VBAR_EL12); break; + case CONTEXTIDR_EL1: *val = read_sysreg_s(SYS_CONTEXTIDR_EL12);break; + case TPIDR_EL0: *val = read_sysreg_s(SYS_TPIDR_EL0); break; + case TPIDRRO_EL0: *val = read_sysreg_s(SYS_TPIDRRO_EL0); break; + case TPIDR_EL1: *val = read_sysreg_s(SYS_TPIDR_EL1); break; + case AMAIR_EL1: *val = read_sysreg_s(SYS_AMAIR_EL12); break; + case CNTKCTL_EL1: *val = read_sysreg_s(SYS_CNTKCTL_EL12); break; + case ELR_EL1: *val = read_sysreg_s(SYS_ELR_EL12); break; + case PAR_EL1: *val = read_sysreg_par(); break; + case DACR32_EL2: *val = read_sysreg_s(SYS_DACR32_EL2); break; + case IFSR32_EL2: *val = read_sysreg_s(SYS_IFSR32_EL2); break; + case DBGVCR32_EL2: *val = read_sysreg_s(SYS_DBGVCR32_EL2); break; + default: return false; + } + + return true; +} -#define vcpu_cp14(v,r) ((v)->arch.ctxt.copro[(r) ^ CPx_BIAS]) -#define vcpu_cp15(v,r) ((v)->arch.ctxt.copro[(r) ^ CPx_BIAS]) +static inline bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg) +{ + /* + * *** VHE ONLY *** + * + * System registers listed in the switch are not restored on every + * entry to the guest but are only restored on vcpu_load. + * + * Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but + * should never be listed below, because the MPIDR should only be set + * once, before running the VCPU, and never changed later. + */ + if (!has_vhe()) + return false; + + switch (reg) { + case CSSELR_EL1: write_sysreg_s(val, SYS_CSSELR_EL1); break; + case SCTLR_EL1: write_sysreg_s(val, SYS_SCTLR_EL12); break; + case CPACR_EL1: write_sysreg_s(val, SYS_CPACR_EL12); break; + case TTBR0_EL1: write_sysreg_s(val, SYS_TTBR0_EL12); break; + case TTBR1_EL1: write_sysreg_s(val, SYS_TTBR1_EL12); break; + case TCR_EL1: write_sysreg_s(val, SYS_TCR_EL12); break; + case ESR_EL1: write_sysreg_s(val, SYS_ESR_EL12); break; + case AFSR0_EL1: write_sysreg_s(val, SYS_AFSR0_EL12); break; + case AFSR1_EL1: write_sysreg_s(val, SYS_AFSR1_EL12); break; + case FAR_EL1: write_sysreg_s(val, SYS_FAR_EL12); break; + case MAIR_EL1: write_sysreg_s(val, SYS_MAIR_EL12); break; + case VBAR_EL1: write_sysreg_s(val, SYS_VBAR_EL12); break; + case CONTEXTIDR_EL1: write_sysreg_s(val, SYS_CONTEXTIDR_EL12);break; + case TPIDR_EL0: write_sysreg_s(val, SYS_TPIDR_EL0); break; + case TPIDRRO_EL0: write_sysreg_s(val, SYS_TPIDRRO_EL0); break; + case TPIDR_EL1: write_sysreg_s(val, SYS_TPIDR_EL1); break; + case AMAIR_EL1: write_sysreg_s(val, SYS_AMAIR_EL12); break; + case CNTKCTL_EL1: write_sysreg_s(val, SYS_CNTKCTL_EL12); break; + case ELR_EL1: write_sysreg_s(val, SYS_ELR_EL12); break; + case PAR_EL1: write_sysreg_s(val, SYS_PAR_EL1); break; + case DACR32_EL2: write_sysreg_s(val, SYS_DACR32_EL2); break; + case IFSR32_EL2: write_sysreg_s(val, SYS_IFSR32_EL2); break; + case DBGVCR32_EL2: write_sysreg_s(val, SYS_DBGVCR32_EL2); break; + default: return false; + } + + return true; +} struct kvm_vm_stat { ulong remote_tlb_flush; @@ -473,6 +570,12 @@ unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices); int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); + +unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu); +int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices); +int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); +int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); + int __kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu, struct kvm_vcpu_events *events); @@ -535,6 +638,17 @@ void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot); int handle_exit(struct kvm_vcpu *vcpu, int exception_index); void handle_exit_early(struct kvm_vcpu *vcpu, int exception_index); +int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu); +int kvm_handle_cp14_32(struct kvm_vcpu *vcpu); +int kvm_handle_cp14_64(struct kvm_vcpu *vcpu); +int kvm_handle_cp15_32(struct kvm_vcpu *vcpu); +int kvm_handle_cp15_64(struct kvm_vcpu *vcpu); +int kvm_handle_sys_reg(struct kvm_vcpu *vcpu); + +void kvm_reset_sys_regs(struct kvm_vcpu *vcpu); + +void kvm_sys_reg_table_init(void); + /* MMIO helpers */ void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data); unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len); @@ -654,4 +768,7 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu); #define kvm_arm_vcpu_sve_finalized(vcpu) \ ((vcpu)->arch.flags & KVM_ARM64_VCPU_SVE_FINALIZED) +#define kvm_vcpu_has_pmu(vcpu) \ + (test_bit(KVM_ARM_VCPU_PMU_V3, (vcpu)->arch.features)) + #endif /* __ARM64_KVM_HOST_H__ */ diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h index 6b664de5ec1f..c0450828378b 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -14,6 +14,7 @@ DECLARE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt); DECLARE_PER_CPU(unsigned long, kvm_hyp_vector); +DECLARE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params); #define read_sysreg_elx(r,nvh,vh) \ ({ \ @@ -92,10 +93,11 @@ void deactivate_traps_vhe_put(void); u64 __guest_enter(struct kvm_vcpu *vcpu); +bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt); + void __noreturn hyp_panic(void); #ifdef __KVM_NVHE_HYPERVISOR__ void __noreturn __hyp_do_panic(bool restore_host, u64 spsr, u64 elr, u64 par); #endif #endif /* __ARM64_KVM_HYP_H__ */ - diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 331394306cce..e52d82aeadca 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h @@ -72,6 +72,52 @@ alternative_cb kvm_update_va_mask alternative_cb_end .endm +/* + * Convert a kernel image address to a PA + * reg: kernel address to be converted in place + * tmp: temporary register + * + * The actual code generation takes place in kvm_get_kimage_voffset, and + * the instructions below are only there to reserve the space and + * perform the register allocation (kvm_get_kimage_voffset uses the + * specific registers encoded in the instructions). + */ +.macro kimg_pa reg, tmp +alternative_cb kvm_get_kimage_voffset + movz \tmp, #0 + movk \tmp, #0, lsl #16 + movk \tmp, #0, lsl #32 + movk \tmp, #0, lsl #48 +alternative_cb_end + + /* reg = __pa(reg) */ + sub \reg, \reg, \tmp +.endm + +/* + * Convert a kernel image address to a hyp VA + * reg: kernel address to be converted in place + * tmp: temporary register + * + * The actual code generation takes place in kvm_get_kimage_voffset, and + * the instructions below are only there to reserve the space and + * perform the register allocation (kvm_update_kimg_phys_offset uses the + * specific registers encoded in the instructions). + */ +.macro kimg_hyp_va reg, tmp +alternative_cb kvm_update_kimg_phys_offset + movz \tmp, #0 + movk \tmp, #0, lsl #16 + movk \tmp, #0, lsl #32 + movk \tmp, #0, lsl #48 +alternative_cb_end + + sub \reg, \reg, \tmp + mov_q \tmp, PAGE_OFFSET + orr \reg, \reg, \tmp + kern_hyp_va \reg +.endm + #else #include <linux/pgtable.h> @@ -98,6 +144,24 @@ static __always_inline unsigned long __kern_hyp_va(unsigned long v) #define kern_hyp_va(v) ((typeof(v))(__kern_hyp_va((unsigned long)(v)))) +static __always_inline unsigned long __kimg_hyp_va(unsigned long v) +{ + unsigned long offset; + + asm volatile(ALTERNATIVE_CB("movz %0, #0\n" + "movk %0, #0, lsl #16\n" + "movk %0, #0, lsl #32\n" + "movk %0, #0, lsl #48\n", + kvm_update_kimg_phys_offset) + : "=r" (offset)); + + return __kern_hyp_va((v - offset) | PAGE_OFFSET); +} + +#define kimg_fn_hyp_va(v) ((typeof(*v))(__kimg_hyp_va((unsigned long)(v)))) + +#define kimg_fn_ptr(x) (typeof(x) **)(x) + /* * We currently support using a VM-specified IPA size. For backward * compatibility, the default IPA size is fixed to 40bits. @@ -208,52 +272,6 @@ static inline int kvm_write_guest_lock(struct kvm *kvm, gpa_t gpa, return ret; } -/* - * EL2 vectors can be mapped and rerouted in a number of ways, - * depending on the kernel configuration and CPU present: - * - * - If the CPU is affected by Spectre-v2, the hardening sequence is - * placed in one of the vector slots, which is executed before jumping - * to the real vectors. - * - * - If the CPU also has the ARM64_HARDEN_EL2_VECTORS cap, the slot - * containing the hardening sequence is mapped next to the idmap page, - * and executed before jumping to the real vectors. - * - * - If the CPU only has the ARM64_HARDEN_EL2_VECTORS cap, then an - * empty slot is selected, mapped next to the idmap page, and - * executed before jumping to the real vectors. - * - * Note that ARM64_HARDEN_EL2_VECTORS is somewhat incompatible with - * VHE, as we don't have hypervisor-specific mappings. If the system - * is VHE and yet selects this capability, it will be ignored. - */ -extern void *__kvm_bp_vect_base; -extern int __kvm_harden_el2_vector_slot; - -static inline void *kvm_get_hyp_vector(void) -{ - struct bp_hardening_data *data = arm64_get_bp_hardening_data(); - void *vect = kern_hyp_va(kvm_ksym_ref(__kvm_hyp_vector)); - int slot = -1; - - if (cpus_have_const_cap(ARM64_SPECTRE_V2) && data->fn) { - vect = kern_hyp_va(kvm_ksym_ref(__bp_harden_hyp_vecs)); - slot = data->hyp_vectors_slot; - } - - if (this_cpu_has_cap(ARM64_HARDEN_EL2_VECTORS) && !has_vhe()) { - vect = __kvm_bp_vect_base; - if (slot == -1) - slot = __kvm_harden_el2_vector_slot; - } - - if (slot != -1) - vect += slot * SZ_2K; - - return vect; -} - #define kvm_phys_to_vttbr(addr) phys_to_ttbr(addr) static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu) diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index 556cb2d62b5b..18fce223b67b 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -72,7 +72,7 @@ * address space for the shadow region respectively. They can bloat the stack * significantly, so double the (minimum) stack size when they are in use. */ -#ifdef CONFIG_KASAN +#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) #define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL) #define KASAN_SHADOW_END ((UL(1) << (64 - KASAN_SHADOW_SCALE_SHIFT)) \ + KASAN_SHADOW_OFFSET) @@ -214,7 +214,7 @@ static inline unsigned long kaslr_offset(void) (__force __typeof__(addr))__addr; \ }) -#ifdef CONFIG_KASAN_SW_TAGS +#if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS) #define __tag_shifted(tag) ((u64)(tag) << 56) #define __tag_reset(addr) __untagged_addr(addr) #define __tag_get(addr) (__u8)((u64)(addr) >> 56) @@ -222,7 +222,7 @@ static inline unsigned long kaslr_offset(void) #define __tag_shifted(tag) 0UL #define __tag_reset(addr) (addr) #define __tag_get(addr) 0 -#endif /* CONFIG_KASAN_SW_TAGS */ +#endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */ static inline const void *__tag_set(const void *addr, u8 tag) { @@ -230,6 +230,15 @@ static inline const void *__tag_set(const void *addr, u8 tag) return (const void *)(__addr | __tag_shifted(tag)); } +#ifdef CONFIG_KASAN_HW_TAGS +#define arch_enable_tagging() mte_enable_kernel() +#define arch_init_tags(max_tag) mte_init_tags(max_tag) +#define arch_get_random_tag() mte_get_random_tag() +#define arch_get_mem_tag(addr) mte_get_mem_tag(addr) +#define arch_set_mem_tag_range(addr, size, tag) \ + mte_set_mem_tag_range((addr), (size), (tag)) +#endif /* CONFIG_KASAN_HW_TAGS */ + /* * Physical vs virtual RAM address space conversion. These are * private definitions which should NOT be used outside memory.h diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index b2e91c187e2a..75beffe2ee8a 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -12,9 +12,6 @@ #define USER_ASID_FLAG (UL(1) << USER_ASID_BIT) #define TTBR_ASID_MASK (UL(0xffff) << 48) -#define BP_HARDEN_EL2_SLOTS 4 -#define __BP_HARDEN_HYP_VECS_SZ (BP_HARDEN_EL2_SLOTS * SZ_2K) - #ifndef __ASSEMBLY__ #include <linux/refcount.h> @@ -41,32 +38,6 @@ static inline bool arm64_kernel_unmapped_at_el0(void) return cpus_have_const_cap(ARM64_UNMAP_KERNEL_AT_EL0); } -typedef void (*bp_hardening_cb_t)(void); - -struct bp_hardening_data { - int hyp_vectors_slot; - bp_hardening_cb_t fn; -}; - -DECLARE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data); - -static inline struct bp_hardening_data *arm64_get_bp_hardening_data(void) -{ - return this_cpu_ptr(&bp_hardening_data); -} - -static inline void arm64_apply_bp_hardening(void) -{ - struct bp_hardening_data *d; - - if (!cpus_have_const_cap(ARM64_SPECTRE_V2)) - return; - - d = arm64_get_bp_hardening_data(); - if (d->fn) - d->fn(); -} - extern void arm64_memblock_init(void); extern void paging_init(void); extern void bootmem_init(void); diff --git a/arch/arm64/include/asm/mte-def.h b/arch/arm64/include/asm/mte-def.h new file mode 100644 index 000000000000..2d73a1612f09 --- /dev/null +++ b/arch/arm64/include/asm/mte-def.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 ARM Ltd. + */ +#ifndef __ASM_MTE_DEF_H +#define __ASM_MTE_DEF_H + +#define MTE_GRANULE_SIZE UL(16) +#define MTE_GRANULE_MASK (~(MTE_GRANULE_SIZE - 1)) +#define MTE_TAG_SHIFT 56 +#define MTE_TAG_SIZE 4 +#define MTE_TAG_MASK GENMASK((MTE_TAG_SHIFT + (MTE_TAG_SIZE - 1)), MTE_TAG_SHIFT) + +#endif /* __ASM_MTE_DEF_H */ diff --git a/arch/arm64/include/asm/mte-kasan.h b/arch/arm64/include/asm/mte-kasan.h new file mode 100644 index 000000000000..26349a4b5e2e --- /dev/null +++ b/arch/arm64/include/asm/mte-kasan.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 ARM Ltd. + */ +#ifndef __ASM_MTE_KASAN_H +#define __ASM_MTE_KASAN_H + +#include <asm/mte-def.h> + +#ifndef __ASSEMBLY__ + +#include <linux/types.h> + +/* + * The functions below are meant to be used only for the + * KASAN_HW_TAGS interface defined in asm/memory.h. + */ +#ifdef CONFIG_ARM64_MTE + +static inline u8 mte_get_ptr_tag(void *ptr) +{ + /* Note: The format of KASAN tags is 0xF<x> */ + u8 tag = 0xF0 | (u8)(((u64)(ptr)) >> MTE_TAG_SHIFT); + + return tag; +} + +u8 mte_get_mem_tag(void *addr); +u8 mte_get_random_tag(void); +void *mte_set_mem_tag_range(void *addr, size_t size, u8 tag); + +void mte_enable_kernel(void); +void mte_init_tags(u64 max_tag); + +#else /* CONFIG_ARM64_MTE */ + +static inline u8 mte_get_ptr_tag(void *ptr) +{ + return 0xFF; +} + +static inline u8 mte_get_mem_tag(void *addr) +{ + return 0xFF; +} +static inline u8 mte_get_random_tag(void) +{ + return 0xFF; +} +static inline void *mte_set_mem_tag_range(void *addr, size_t size, u8 tag) +{ + return addr; +} + +static inline void mte_enable_kernel(void) +{ +} + +static inline void mte_init_tags(u64 max_tag) +{ +} + +#endif /* CONFIG_ARM64_MTE */ + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_MTE_KASAN_H */ diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h index 1c99fcadb58c..d02aff9f493d 100644 --- a/arch/arm64/include/asm/mte.h +++ b/arch/arm64/include/asm/mte.h @@ -5,17 +5,21 @@ #ifndef __ASM_MTE_H #define __ASM_MTE_H -#define MTE_GRANULE_SIZE UL(16) -#define MTE_GRANULE_MASK (~(MTE_GRANULE_SIZE - 1)) -#define MTE_TAG_SHIFT 56 -#define MTE_TAG_SIZE 4 +#include <asm/compiler.h> +#include <asm/mte-def.h> + +#define __MTE_PREAMBLE ARM64_ASM_PREAMBLE ".arch_extension memtag\n" #ifndef __ASSEMBLY__ +#include <linux/bitfield.h> #include <linux/page-flags.h> +#include <linux/types.h> #include <asm/pgtable-types.h> +extern u64 gcr_kernel_excl; + void mte_clear_page_tags(void *addr); unsigned long mte_copy_tags_from_user(void *to, const void __user *from, unsigned long n); @@ -45,7 +49,9 @@ long get_mte_ctrl(struct task_struct *task); int mte_ptrace_copy_tags(struct task_struct *child, long request, unsigned long addr, unsigned long data); -#else +void mte_assign_mem_tag_range(void *addr, size_t size); + +#else /* CONFIG_ARM64_MTE */ /* unused if !CONFIG_ARM64_MTE, silence the compiler */ #define PG_mte_tagged 0 @@ -80,7 +86,11 @@ static inline int mte_ptrace_copy_tags(struct task_struct *child, return -EIO; } -#endif +static inline void mte_assign_mem_tag_range(void *addr, size_t size) +{ +} + +#endif /* CONFIG_ARM64_MTE */ #endif /* __ASSEMBLY__ */ #endif /* __ASM_MTE_H */ diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h index 1599e17379d8..8f1661603b78 100644 --- a/arch/arm64/include/asm/percpu.h +++ b/arch/arm64/include/asm/percpu.h @@ -239,6 +239,12 @@ PERCPU_RET_OP(add, add, ldadd) #define this_cpu_cmpxchg_8(pcp, o, n) \ _pcp_protect_return(cmpxchg_relaxed, pcp, o, n) +#ifdef __KVM_NVHE_HYPERVISOR__ +extern unsigned long __hyp_per_cpu_offset(unsigned int cpu); +#define __per_cpu_offset +#define per_cpu_offset(cpu) __hyp_per_cpu_offset((cpu)) +#endif + #include <asm-generic/percpu.h> /* Redefine macros for nVHE hyp under DEBUG_PREEMPT to avoid its dependencies. */ diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 724249f37af5..ca2cd75d3286 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -152,7 +152,7 @@ struct thread_struct { #endif #ifdef CONFIG_ARM64_MTE u64 sctlr_tcf0; - u64 gcr_user_incl; + u64 gcr_user_excl; #endif }; diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h index 3994169985ef..8ff579361731 100644 --- a/arch/arm64/include/asm/sections.h +++ b/arch/arm64/include/asm/sections.h @@ -11,6 +11,7 @@ extern char __alt_instructions[], __alt_instructions_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 __hyp_data_ro_after_init_start[], __hyp_data_ro_after_init_end[]; extern char __idmap_text_start[], __idmap_text_end[]; extern char __initdata_begin[], __initdata_end[]; extern char __inittext_begin[], __inittext_end[]; diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index 2e7f529ec5a6..bcb01ca15325 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -46,9 +46,9 @@ DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number); * Logical CPU mapping. */ extern u64 __cpu_logical_map[NR_CPUS]; -extern u64 cpu_logical_map(int cpu); +extern u64 cpu_logical_map(unsigned int cpu); -static inline void set_cpu_logical_map(int cpu, u64 hwid) +static inline void set_cpu_logical_map(unsigned int cpu, u64 hwid) { __cpu_logical_map[cpu] = hwid; } diff --git a/arch/arm64/include/asm/spectre.h b/arch/arm64/include/asm/spectre.h index fcdfbce302bd..f62ca39da6c5 100644 --- a/arch/arm64/include/asm/spectre.h +++ b/arch/arm64/include/asm/spectre.h @@ -9,7 +9,15 @@ #ifndef __ASM_SPECTRE_H #define __ASM_SPECTRE_H +#define BP_HARDEN_EL2_SLOTS 4 +#define __BP_HARDEN_HYP_VECS_SZ ((BP_HARDEN_EL2_SLOTS - 1) * SZ_2K) + +#ifndef __ASSEMBLY__ + +#include <linux/percpu.h> + #include <asm/cpufeature.h> +#include <asm/virt.h> /* Watch out, ordering is important here. */ enum mitigation_state { @@ -20,13 +28,70 @@ enum mitigation_state { struct task_struct; +/* + * Note: the order of this enum corresponds to __bp_harden_hyp_vecs and + * we rely on having the direct vectors first. + */ +enum arm64_hyp_spectre_vector { + /* + * Take exceptions directly to __kvm_hyp_vector. This must be + * 0 so that it used by default when mitigations are not needed. + */ + HYP_VECTOR_DIRECT, + + /* + * Bounce via a slot in the hypervisor text mapping of + * __bp_harden_hyp_vecs, which contains an SMC call. + */ + HYP_VECTOR_SPECTRE_DIRECT, + + /* + * Bounce via a slot in a special mapping of __bp_harden_hyp_vecs + * next to the idmap page. + */ + HYP_VECTOR_INDIRECT, + + /* + * Bounce via a slot in a special mapping of __bp_harden_hyp_vecs + * next to the idmap page, which contains an SMC call. + */ + HYP_VECTOR_SPECTRE_INDIRECT, +}; + +typedef void (*bp_hardening_cb_t)(void); + +struct bp_hardening_data { + enum arm64_hyp_spectre_vector slot; + bp_hardening_cb_t fn; +}; + +DECLARE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data); + +static inline void arm64_apply_bp_hardening(void) +{ + struct bp_hardening_data *d; + + if (!cpus_have_const_cap(ARM64_SPECTRE_V2)) + return; + + d = this_cpu_ptr(&bp_hardening_data); + if (d->fn) + d->fn(); +} + enum mitigation_state arm64_get_spectre_v2_state(void); bool has_spectre_v2(const struct arm64_cpu_capabilities *cap, int scope); void spectre_v2_enable_mitigation(const struct arm64_cpu_capabilities *__unused); +bool has_spectre_v3a(const struct arm64_cpu_capabilities *cap, int scope); +void spectre_v3a_enable_mitigation(const struct arm64_cpu_capabilities *__unused); + enum mitigation_state arm64_get_spectre_v4_state(void); bool has_spectre_v4(const struct arm64_cpu_capabilities *cap, int scope); void spectre_v4_enable_mitigation(const struct arm64_cpu_capabilities *__unused); void spectre_v4_enable_task_mitigation(struct task_struct *tsk); +enum mitigation_state arm64_get_meltdown_state(void); + +#endif /* __ASSEMBLY__ */ #endif /* __ASM_SPECTRE_H */ diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h index b31e8e87a0db..3a3264ff47b9 100644 --- a/arch/arm64/include/asm/string.h +++ b/arch/arm64/include/asm/string.h @@ -5,7 +5,7 @@ #ifndef __ASM_STRING_H #define __ASM_STRING_H -#ifndef CONFIG_KASAN +#if !(defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) #define __HAVE_ARCH_STRRCHR extern char *strrchr(const char *, int c); @@ -48,7 +48,8 @@ extern void *__memset(void *, int, __kernel_size_t); void memcpy_flushcache(void *dst, const void *src, size_t cnt); #endif -#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) +#if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \ + !defined(__SANITIZE_ADDRESS__) /* * For files that are not instrumented (e.g. mm/slub.c) we diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index cf7922f23808..8b5e7e5c3cc8 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -469,6 +469,7 @@ #define SYS_PMCCFILTR_EL0 sys_reg(3, 3, 14, 15, 7) +#define SYS_SCTLR_EL2 sys_reg(3, 4, 1, 0, 0) #define SYS_ZCR_EL2 sys_reg(3, 4, 1, 2, 0) #define SYS_DACR32_EL2 sys_reg(3, 4, 3, 0, 0) #define SYS_SPSR_EL2 sys_reg(3, 4, 4, 0, 0) diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h index abb31aa1f8ca..f0fe0cc6abe0 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -159,8 +159,39 @@ static inline void __uaccess_enable_hw_pan(void) CONFIG_ARM64_PAN)); } +/* + * The Tag Check Flag (TCF) mode for MTE is per EL, hence TCF0 + * affects EL0 and TCF affects EL1 irrespective of which TTBR is + * used. + * The kernel accesses TTBR0 usually with LDTR/STTR instructions + * when UAO is available, so these would act as EL0 accesses using + * TCF0. + * However futex.h code uses exclusives which would be executed as + * EL1, this can potentially cause a tag check fault even if the + * user disables TCF0. + * + * To address the problem we set the PSTATE.TCO bit in uaccess_enable() + * and reset it in uaccess_disable(). + * + * The Tag check override (TCO) bit disables temporarily the tag checking + * preventing the issue. + */ +static inline void __uaccess_disable_tco(void) +{ + asm volatile(ALTERNATIVE("nop", SET_PSTATE_TCO(0), + ARM64_MTE, CONFIG_KASAN_HW_TAGS)); +} + +static inline void __uaccess_enable_tco(void) +{ + asm volatile(ALTERNATIVE("nop", SET_PSTATE_TCO(1), + ARM64_MTE, CONFIG_KASAN_HW_TAGS)); +} + static inline void uaccess_disable_privileged(void) { + __uaccess_disable_tco(); + if (uaccess_ttbr0_disable()) return; @@ -169,6 +200,8 @@ static inline void uaccess_disable_privileged(void) static inline void uaccess_enable_privileged(void) { + __uaccess_enable_tco(); + if (uaccess_ttbr0_enable()) return; diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h index b3b2019f8d16..86a9d7b3eabe 100644 --- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h @@ -38,7 +38,7 @@ #define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE + 5) #define __ARM_NR_COMPAT_END (__ARM_NR_COMPAT_BASE + 0x800) -#define __NR_compat_syscalls 441 +#define __NR_compat_syscalls 442 #endif #define __ARCH_WANT_SYS_CLONE diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h index 107f08e03b9f..cccfbbefbf95 100644 --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h @@ -889,6 +889,8 @@ __SYSCALL(__NR_pidfd_getfd, sys_pidfd_getfd) __SYSCALL(__NR_faccessat2, sys_faccessat2) #define __NR_process_madvise 440 __SYSCALL(__NR_process_madvise, sys_process_madvise) +#define __NR_epoll_pwait2 441 +__SYSCALL(__NR_epoll_pwait2, compat_sys_epoll_pwait2) /* * Please add new compat syscalls above this comment and update diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h index 6069be50baf9..ee6a48df89d9 100644 --- a/arch/arm64/include/asm/virt.h +++ b/arch/arm64/include/asm/virt.h @@ -65,9 +65,19 @@ extern u32 __boot_cpu_mode[2]; void __hyp_set_vectors(phys_addr_t phys_vector_base); void __hyp_reset_vectors(void); +DECLARE_STATIC_KEY_FALSE(kvm_protected_mode_initialized); + /* Reports the availability of HYP mode */ static inline bool is_hyp_mode_available(void) { + /* + * If KVM protected mode is initialized, all CPUs must have been booted + * in EL2. Avoid checking __boot_cpu_mode as CPUs now come up in EL1. + */ + if (IS_ENABLED(CONFIG_KVM) && + static_branch_likely(&kvm_protected_mode_initialized)) + return true; + return (__boot_cpu_mode[0] == BOOT_CPU_MODE_EL2 && __boot_cpu_mode[1] == BOOT_CPU_MODE_EL2); } @@ -75,6 +85,14 @@ static inline bool is_hyp_mode_available(void) /* Check if the bootloader has booted CPUs in different modes */ static inline bool is_hyp_mode_mismatched(void) { + /* + * If KVM protected mode is initialized, all CPUs must have been booted + * in EL2. Avoid checking __boot_cpu_mode as CPUs now come up in EL1. + */ + if (IS_ENABLED(CONFIG_KVM) && + static_branch_likely(&kvm_protected_mode_initialized)) + return false; + return __boot_cpu_mode[0] != __boot_cpu_mode[1]; } @@ -97,6 +115,14 @@ static __always_inline bool has_vhe(void) return cpus_have_final_cap(ARM64_HAS_VIRT_HOST_EXTN); } +static __always_inline bool is_protected_kvm_enabled(void) +{ + if (is_vhe_hyp_code()) + return false; + else + return cpus_have_final_cap(ARM64_KVM_PROTECTED_MODE); +} + #endif /* __ASSEMBLY__ */ #endif /* ! __ASM__VIRT_H */ diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index 1c17c3a24411..24223adae150 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -156,9 +156,6 @@ struct kvm_sync_regs { __u64 device_irq_level; }; -struct kvm_arch_memory_slot { -}; - /* * PMU filter structure. Describe a range of events with a particular * action. To be used with KVM_ARM_VCPU_PMU_V3_FILTER. diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index 679b19b8a7ff..301784463587 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -47,6 +47,9 @@ int main(void) DEFINE(THREAD_KEYS_USER, offsetof(struct task_struct, thread.keys_user)); DEFINE(THREAD_KEYS_KERNEL, offsetof(struct task_struct, thread.keys_kernel)); #endif +#ifdef CONFIG_ARM64_MTE + DEFINE(THREAD_GCR_EL1_USER, offsetof(struct task_struct, thread.gcr_user_excl)); +#endif BLANK(); DEFINE(S_X0, offsetof(struct pt_regs, regs[0])); DEFINE(S_X2, offsetof(struct pt_regs, regs[2])); @@ -72,7 +75,7 @@ int main(void) DEFINE(S_SDEI_TTBR1, offsetof(struct pt_regs, sdei_ttbr1)); DEFINE(S_PMR_SAVE, offsetof(struct pt_regs, pmr_save)); DEFINE(S_STACKFRAME, offsetof(struct pt_regs, stackframe)); - DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs)); + DEFINE(PT_REGS_SIZE, sizeof(struct pt_regs)); BLANK(); #ifdef CONFIG_COMPAT DEFINE(COMPAT_SIGFRAME_REGS_OFFSET, offsetof(struct compat_sigframe, uc.uc_mcontext.arm_r0)); @@ -109,6 +112,11 @@ int main(void) DEFINE(CPU_APGAKEYLO_EL1, offsetof(struct kvm_cpu_context, sys_regs[APGAKEYLO_EL1])); DEFINE(HOST_CONTEXT_VCPU, offsetof(struct kvm_cpu_context, __hyp_running_vcpu)); DEFINE(HOST_DATA_CONTEXT, offsetof(struct kvm_host_data, host_ctxt)); + DEFINE(NVHE_INIT_MAIR_EL2, offsetof(struct kvm_nvhe_init_params, mair_el2)); + DEFINE(NVHE_INIT_TCR_EL2, offsetof(struct kvm_nvhe_init_params, tcr_el2)); + DEFINE(NVHE_INIT_TPIDR_EL2, offsetof(struct kvm_nvhe_init_params, tpidr_el2)); + DEFINE(NVHE_INIT_STACK_HYP_VA, offsetof(struct kvm_nvhe_init_params, stack_hyp_va)); + DEFINE(NVHE_INIT_PGD_PA, offsetof(struct kvm_nvhe_init_params, pgd_pa)); #endif #ifdef CONFIG_CPU_PM DEFINE(CPU_CTX_SP, offsetof(struct cpu_suspend_ctx, sp)); diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index cafaf0da05b7..a63428301f42 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -196,16 +196,6 @@ has_neoverse_n1_erratum_1542419(const struct arm64_cpu_capabilities *entry, return is_midr_in_range(midr, &range) && has_dic; } -#ifdef CONFIG_RANDOMIZE_BASE - -static const struct midr_range ca57_a72[] = { - MIDR_ALL_VERSIONS(MIDR_CORTEX_A57), - MIDR_ALL_VERSIONS(MIDR_CORTEX_A72), - {}, -}; - -#endif - #ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = { #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1009 @@ -461,9 +451,12 @@ const struct arm64_cpu_capabilities arm64_errata[] = { }, #ifdef CONFIG_RANDOMIZE_BASE { - .desc = "EL2 vector hardening", - .capability = ARM64_HARDEN_EL2_VECTORS, - ERRATA_MIDR_RANGE_LIST(ca57_a72), + /* Must come after the Spectre-v2 entry */ + .desc = "Spectre-v3a", + .capability = ARM64_SPECTRE_V3A, + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + .matches = has_spectre_v3a, + .cpu_enable = spectre_v3a_enable_mitigation, }, #endif { diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 39138f6d3ba2..e99eddec0a46 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -70,10 +70,12 @@ #include <linux/types.h> #include <linux/mm.h> #include <linux/cpu.h> +#include <linux/kasan.h> #include <asm/cpu.h> #include <asm/cpufeature.h> #include <asm/cpu_ops.h> #include <asm/fpsimd.h> +#include <asm/kvm_host.h> #include <asm/mmu_context.h> #include <asm/mte.h> #include <asm/processor.h> @@ -1709,9 +1711,26 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) cleared_zero_page = true; mte_clear_page_tags(lm_alias(empty_zero_page)); } + + kasan_init_hw_tags_cpu(); } #endif /* CONFIG_ARM64_MTE */ +#ifdef CONFIG_KVM +static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused) +{ + if (kvm_get_mode() != KVM_MODE_PROTECTED) + return false; + + if (is_kernel_in_hyp_mode()) { + pr_warn("Protected KVM not available with VHE\n"); + return false; + } + + return true; +} +#endif /* CONFIG_KVM */ + /* Internal helper functions to match cpu capability type */ static bool cpucap_late_cpu_optional(const struct arm64_cpu_capabilities *cap) @@ -1803,6 +1822,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .field_pos = ID_AA64PFR0_EL1_SHIFT, .min_field_value = ID_AA64PFR0_EL1_32BIT_64BIT, }, + { + .desc = "Protected KVM", + .capability = ARM64_KVM_PROTECTED_MODE, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .matches = is_kvm_protected_mode, + }, #endif { .desc = "Kernel page table isolation (KPTI)", @@ -2543,7 +2568,7 @@ static void verify_hyp_capabilities(void) int parange, ipa_max; unsigned int safe_vmid_bits, vmid_bits; - if (!IS_ENABLED(CONFIG_KVM) || !IS_ENABLED(CONFIG_KVM_ARM_HOST)) + if (!IS_ENABLED(CONFIG_KVM)) return; safe_mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); @@ -2831,14 +2856,28 @@ static int __init enable_mrs_emulation(void) core_initcall(enable_mrs_emulation); +enum mitigation_state arm64_get_meltdown_state(void) +{ + if (__meltdown_safe) + return SPECTRE_UNAFFECTED; + + if (arm64_kernel_unmapped_at_el0()) + return SPECTRE_MITIGATED; + + return SPECTRE_VULNERABLE; +} + ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf) { - if (__meltdown_safe) + switch (arm64_get_meltdown_state()) { + case SPECTRE_UNAFFECTED: return sprintf(buf, "Not affected\n"); - if (arm64_kernel_unmapped_at_el0()) + case SPECTRE_MITIGATED: return sprintf(buf, "Mitigation: PTI\n"); - return sprintf(buf, "Vulnerable\n"); + default: + return sprintf(buf, "Vulnerable\n"); + } } diff --git a/arch/arm64/kernel/entry-ftrace.S b/arch/arm64/kernel/entry-ftrace.S index a338f40e64d3..b3e4f9a088b1 100644 --- a/arch/arm64/kernel/entry-ftrace.S +++ b/arch/arm64/kernel/entry-ftrace.S @@ -35,7 +35,7 @@ */ .macro ftrace_regs_entry, allregs=0 /* Make room for pt_regs, plus a callee frame */ - sub sp, sp, #(S_FRAME_SIZE + 16) + sub sp, sp, #(PT_REGS_SIZE + 16) /* Save function arguments (and x9 for simplicity) */ stp x0, x1, [sp, #S_X0] @@ -61,15 +61,15 @@ .endif /* Save the callsite's SP and LR */ - add x10, sp, #(S_FRAME_SIZE + 16) + add x10, sp, #(PT_REGS_SIZE + 16) stp x9, x10, [sp, #S_LR] /* Save the PC after the ftrace callsite */ str x30, [sp, #S_PC] /* Create a frame record for the callsite above pt_regs */ - stp x29, x9, [sp, #S_FRAME_SIZE] - add x29, sp, #S_FRAME_SIZE + stp x29, x9, [sp, #PT_REGS_SIZE] + add x29, sp, #PT_REGS_SIZE /* Create our frame record within pt_regs. */ stp x29, x30, [sp, #S_STACKFRAME] @@ -120,7 +120,7 @@ ftrace_common_return: ldr x9, [sp, #S_PC] /* Restore the callsite's SP */ - add sp, sp, #S_FRAME_SIZE + 16 + add sp, sp, #PT_REGS_SIZE + 16 ret x9 SYM_CODE_END(ftrace_common) @@ -130,7 +130,7 @@ SYM_CODE_START(ftrace_graph_caller) ldr x0, [sp, #S_PC] sub x0, x0, #AARCH64_INSN_SIZE // ip (callsite's BL insn) add x1, sp, #S_LR // parent_ip (callsite's LR) - ldr x2, [sp, #S_FRAME_SIZE] // parent fp (callsite's FP) + ldr x2, [sp, #PT_REGS_SIZE] // parent fp (callsite's FP) bl prepare_ftrace_return b ftrace_common_return SYM_CODE_END(ftrace_graph_caller) diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 51c762156099..c9bae73f2621 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -75,7 +75,7 @@ alternative_else_nop_endif .endif #endif - sub sp, sp, #S_FRAME_SIZE + sub sp, sp, #PT_REGS_SIZE #ifdef CONFIG_VMAP_STACK /* * Test whether the SP has overflowed, without corrupting a GPR. @@ -96,7 +96,7 @@ alternative_else_nop_endif * userspace, and can clobber EL0 registers to free up GPRs. */ - /* Stash the original SP (minus S_FRAME_SIZE) in tpidr_el0. */ + /* Stash the original SP (minus PT_REGS_SIZE) in tpidr_el0. */ msr tpidr_el0, x0 /* Recover the original x0 value and stash it in tpidrro_el0 */ @@ -173,6 +173,43 @@ alternative_else_nop_endif #endif .endm + .macro mte_set_gcr, tmp, tmp2 +#ifdef CONFIG_ARM64_MTE + /* + * Calculate and set the exclude mask preserving + * the RRND (bit[16]) setting. + */ + mrs_s \tmp2, SYS_GCR_EL1 + bfi \tmp2, \tmp, #0, #16 + msr_s SYS_GCR_EL1, \tmp2 +#endif + .endm + + .macro mte_set_kernel_gcr, tmp, tmp2 +#ifdef CONFIG_KASAN_HW_TAGS +alternative_if_not ARM64_MTE + b 1f +alternative_else_nop_endif + ldr_l \tmp, gcr_kernel_excl + + mte_set_gcr \tmp, \tmp2 + isb +1: +#endif + .endm + + .macro mte_set_user_gcr, tsk, tmp, tmp2 +#ifdef CONFIG_ARM64_MTE +alternative_if_not ARM64_MTE + b 1f +alternative_else_nop_endif + ldr \tmp, [\tsk, #THREAD_GCR_EL1_USER] + + mte_set_gcr \tmp, \tmp2 +1: +#endif + .endm + .macro kernel_entry, el, regsize = 64 .if \regsize == 32 mov w0, w0 // zero upper 32 bits of x0 @@ -212,9 +249,11 @@ alternative_else_nop_endif ptrauth_keys_install_kernel tsk, x20, x22, x23 + mte_set_kernel_gcr x22, x23 + scs_load tsk, x20 .else - add x21, sp, #S_FRAME_SIZE + add x21, sp, #PT_REGS_SIZE get_current_task tsk .endif /* \el == 0 */ mrs x22, elr_el1 @@ -315,6 +354,8 @@ alternative_else_nop_endif /* No kernel C function calls after this as user keys are set. */ ptrauth_keys_install_user tsk, x0, x1, x2 + mte_set_user_gcr tsk, x0, x1 + apply_ssbd 0, x0, x1 .endif @@ -336,7 +377,7 @@ alternative_else_nop_endif ldp x26, x27, [sp, #16 * 13] ldp x28, x29, [sp, #16 * 14] ldr lr, [sp, #S_LR] - add sp, sp, #S_FRAME_SIZE // restore sp + add sp, sp, #PT_REGS_SIZE // restore sp .if \el == 0 alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 @@ -539,12 +580,12 @@ __bad_stack: /* * Store the original GPRs to the new stack. The orginal SP (minus - * S_FRAME_SIZE) was stashed in tpidr_el0 by kernel_ventry. + * PT_REGS_SIZE) was stashed in tpidr_el0 by kernel_ventry. */ - sub sp, sp, #S_FRAME_SIZE + sub sp, sp, #PT_REGS_SIZE kernel_entry 1 mrs x0, tpidr_el0 - add x0, x0, #S_FRAME_SIZE + add x0, x0, #PT_REGS_SIZE str x0, [sp, #S_SP] /* Stash the regs for handle_bad_stack */ diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index f2eb206920a2..a0dc987724ed 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -11,7 +11,6 @@ #include <linux/linkage.h> #include <linux/init.h> -#include <linux/irqchip/arm-gic-v3.h> #include <linux/pgtable.h> #include <asm/asm_pointer_auth.h> @@ -21,6 +20,7 @@ #include <asm/asm-offsets.h> #include <asm/cache.h> #include <asm/cputype.h> +#include <asm/el2_setup.h> #include <asm/elf.h> #include <asm/image.h> #include <asm/kernel-pgtable.h> @@ -433,7 +433,7 @@ SYM_FUNC_START_LOCAL(__primary_switched) bl __pi_memset dsb ishst // Make zero page visible to PTW -#ifdef CONFIG_KASAN +#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) bl kasan_early_init #endif #ifdef CONFIG_RANDOMIZE_BASE @@ -493,155 +493,56 @@ SYM_INNER_LABEL(init_el1, SYM_L_LOCAL) eret SYM_INNER_LABEL(init_el2, SYM_L_LOCAL) - mov_q x0, INIT_SCTLR_EL2_MMU_OFF - msr sctlr_el2, x0 - #ifdef CONFIG_ARM64_VHE /* - * Check for VHE being present. For the rest of the EL2 setup, - * x2 being non-zero indicates that we do have VHE, and that the - * kernel is intended to run at EL2. + * Check for VHE being present. x2 being non-zero indicates that we + * do have VHE, and that the kernel is intended to run at EL2. */ mrs x2, id_aa64mmfr1_el1 ubfx x2, x2, #ID_AA64MMFR1_VHE_SHIFT, #4 #else mov x2, xzr #endif + cbz x2, init_el2_nvhe - /* Hyp configuration. */ - mov_q x0, HCR_HOST_NVHE_FLAGS - cbz x2, set_hcr + /* + * When VHE _is_ in use, EL1 will not be used in the host and + * requires no configuration, and all non-hyp-specific EL2 setup + * will be done via the _EL1 system register aliases in __cpu_setup. + */ mov_q x0, HCR_HOST_VHE_FLAGS -set_hcr: msr hcr_el2, x0 isb - /* - * Allow Non-secure EL1 and EL0 to access physical timer and counter. - * This is not necessary for VHE, since the host kernel runs in EL2, - * and EL0 accesses are configured in the later stage of boot process. - * Note that when HCR_EL2.E2H == 1, CNTHCTL_EL2 has the same bit layout - * as CNTKCTL_EL1, and CNTKCTL_EL1 accessing instructions are redefined - * to access CNTHCTL_EL2. This allows the kernel designed to run at EL1 - * to transparently mess with the EL0 bits via CNTKCTL_EL1 access in - * EL2. - */ - cbnz x2, 1f - mrs x0, cnthctl_el2 - orr x0, x0, #3 // Enable EL1 physical timers - msr cnthctl_el2, x0 -1: - msr cntvoff_el2, xzr // Clear virtual offset - -#ifdef CONFIG_ARM_GIC_V3 - /* GICv3 system register access */ - mrs x0, id_aa64pfr0_el1 - ubfx x0, x0, #ID_AA64PFR0_GIC_SHIFT, #4 - cbz x0, 3f - - mrs_s x0, SYS_ICC_SRE_EL2 - orr x0, x0, #ICC_SRE_EL2_SRE // Set ICC_SRE_EL2.SRE==1 - orr x0, x0, #ICC_SRE_EL2_ENABLE // Set ICC_SRE_EL2.Enable==1 - msr_s SYS_ICC_SRE_EL2, x0 - isb // Make sure SRE is now set - mrs_s x0, SYS_ICC_SRE_EL2 // Read SRE back, - tbz x0, #0, 3f // and check that it sticks - msr_s SYS_ICH_HCR_EL2, xzr // Reset ICC_HCR_EL2 to defaults - -3: -#endif - - /* Populate ID registers. */ - mrs x0, midr_el1 - mrs x1, mpidr_el1 - msr vpidr_el2, x0 - msr vmpidr_el2, x1 - -#ifdef CONFIG_COMPAT - msr hstr_el2, xzr // Disable CP15 traps to EL2 -#endif - - /* EL2 debug */ - mrs x1, id_aa64dfr0_el1 - sbfx x0, x1, #ID_AA64DFR0_PMUVER_SHIFT, #4 - cmp x0, #1 - b.lt 4f // Skip if no PMU present - mrs x0, pmcr_el0 // Disable debug access traps - ubfx x0, x0, #11, #5 // to EL2 and allow access to -4: - csel x3, xzr, x0, lt // all PMU counters from EL1 - - /* Statistical profiling */ - ubfx x0, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4 - cbz x0, 7f // Skip if SPE not present - cbnz x2, 6f // VHE? - mrs_s x4, SYS_PMBIDR_EL1 // If SPE available at EL2, - and x4, x4, #(1 << SYS_PMBIDR_EL1_P_SHIFT) - cbnz x4, 5f // then permit sampling of physical - mov x4, #(1 << SYS_PMSCR_EL2_PCT_SHIFT | \ - 1 << SYS_PMSCR_EL2_PA_SHIFT) - msr_s SYS_PMSCR_EL2, x4 // addresses and physical counter -5: - mov x1, #(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT) - orr x3, x3, x1 // If we don't have VHE, then - b 7f // use EL1&0 translation. -6: // For VHE, use EL2 translation - orr x3, x3, #MDCR_EL2_TPMS // and disable access from EL1 -7: - msr mdcr_el2, x3 // Configure debug traps - - /* LORegions */ - mrs x1, id_aa64mmfr1_el1 - ubfx x0, x1, #ID_AA64MMFR1_LOR_SHIFT, 4 - cbz x0, 1f - msr_s SYS_LORC_EL1, xzr -1: - - /* Stage-2 translation */ - msr vttbr_el2, xzr - - cbz x2, install_el2_stub + init_el2_state vhe isb + mov_q x0, INIT_PSTATE_EL2 msr spsr_el2, x0 msr elr_el2, lr mov w0, #BOOT_CPU_MODE_EL2 eret -SYM_INNER_LABEL(install_el2_stub, SYM_L_LOCAL) +SYM_INNER_LABEL(init_el2_nvhe, SYM_L_LOCAL) /* * When VHE is not in use, early init of EL2 and EL1 needs to be * done here. - * When VHE _is_ in use, EL1 will not be used in the host and - * requires no configuration, and all non-hyp-specific EL2 setup - * will be done via the _EL1 system register aliases in __cpu_setup. */ mov_q x0, INIT_SCTLR_EL1_MMU_OFF msr sctlr_el1, x0 - /* Coprocessor traps. */ - mov x0, #0x33ff - msr cptr_el2, x0 // Disable copro. traps to EL2 - - /* SVE register access */ - mrs x1, id_aa64pfr0_el1 - ubfx x1, x1, #ID_AA64PFR0_SVE_SHIFT, #4 - cbz x1, 7f - - bic x0, x0, #CPTR_EL2_TZ // Also disable SVE traps - msr cptr_el2, x0 // Disable copro. traps to EL2 + mov_q x0, HCR_HOST_NVHE_FLAGS + msr hcr_el2, x0 isb - mov x1, #ZCR_ELx_LEN_MASK // SVE: Enable full vector - msr_s SYS_ZCR_EL2, x1 // length for EL1. + + init_el2_state nvhe /* Hypervisor stub */ -7: adr_l x0, __hyp_stub_vectors + adr_l x0, __hyp_stub_vectors msr vbar_el2, x0 - isb - mov x0, #INIT_PSTATE_EL1 - msr spsr_el2, x0 + msr elr_el2, lr mov w0, #BOOT_CPU_MODE_EL2 eret diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c index 42003774d261..9c9f47e9f7f4 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c @@ -371,6 +371,11 @@ static void swsusp_mte_restore_tags(void) unsigned long pfn = xa_state.xa_index; struct page *page = pfn_to_online_page(pfn); + /* + * It is not required to invoke page_kasan_tag_reset(page) + * at this point since the tags stored in page->flags are + * already restored. + */ mte_restore_page_tags(page_address(page), tags); mte_free_tag_storage(tags); diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h index c615b285ff5b..f676243abac6 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -37,7 +37,7 @@ __efistub_strncmp = __pi_strncmp; __efistub_strrchr = __pi_strrchr; __efistub___clean_dcache_area_poc = __pi___clean_dcache_area_poc; -#ifdef CONFIG_KASAN +#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) __efistub___memcpy = __pi_memcpy; __efistub___memmove = __pi_memmove; __efistub___memset = __pi_memset; @@ -64,13 +64,12 @@ __efistub__ctype = _ctype; /* Alternative callbacks for init-time patching of nVHE hyp code. */ KVM_NVHE_ALIAS(kvm_patch_vector_branch); KVM_NVHE_ALIAS(kvm_update_va_mask); +KVM_NVHE_ALIAS(kvm_update_kimg_phys_offset); +KVM_NVHE_ALIAS(kvm_get_kimage_voffset); /* Global kernel state accessed by nVHE hyp code. */ KVM_NVHE_ALIAS(kvm_vgic_global_state); -/* Kernel constant needed to compute idmap addresses. */ -KVM_NVHE_ALIAS(kimage_voffset); - /* Kernel symbols used to call panic() from nVHE hyp code (via ERET). */ KVM_NVHE_ALIAS(__hyp_panic_string); KVM_NVHE_ALIAS(panic); @@ -78,9 +77,6 @@ KVM_NVHE_ALIAS(panic); /* Vectors installed by hyp-init on reset HVC. */ KVM_NVHE_ALIAS(__hyp_stub_vectors); -/* IDMAP TCR_EL1.T0SZ as computed by the EL1 init code */ -KVM_NVHE_ALIAS(idmap_t0sz); - /* Kernel symbol used by icache_is_vpipt(). */ KVM_NVHE_ALIAS(__icache_flags); @@ -103,6 +99,9 @@ KVM_NVHE_ALIAS(gic_nonsecure_priorities); KVM_NVHE_ALIAS(__start___kvm_ex_table); KVM_NVHE_ALIAS(__stop___kvm_ex_table); +/* Array containing bases of nVHE per-CPU memory regions. */ +KVM_NVHE_ALIAS(kvm_arm_hyp_percpu_base); + #endif /* CONFIG_KVM */ #endif /* __ARM64_KERNEL_IMAGE_VARS_H */ diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c index 0921aa1520b0..1c74c45b9494 100644 --- a/arch/arm64/kernel/kaslr.c +++ b/arch/arm64/kernel/kaslr.c @@ -161,7 +161,8 @@ u64 __init kaslr_early_init(u64 dt_phys) /* use the top 16 bits to randomize the linear region */ memstart_offset_seed = seed >> 48; - if (IS_ENABLED(CONFIG_KASAN)) + if (IS_ENABLED(CONFIG_KASAN_GENERIC) || + IS_ENABLED(CONFIG_KASAN_SW_TAGS)) /* * KASAN does not expect the module region to intersect the * vmalloc region, since shadow memory is allocated for each diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c index 2a1ad95d9b2c..fe21e0f06492 100644 --- a/arch/arm64/kernel/module.c +++ b/arch/arm64/kernel/module.c @@ -30,7 +30,8 @@ void *module_alloc(unsigned long size) if (IS_ENABLED(CONFIG_ARM64_MODULE_PLTS)) gfp_mask |= __GFP_NOWARN; - if (IS_ENABLED(CONFIG_KASAN)) + if (IS_ENABLED(CONFIG_KASAN_GENERIC) || + IS_ENABLED(CONFIG_KASAN_SW_TAGS)) /* don't exceed the static module region - see below */ module_alloc_end = MODULES_END; @@ -39,7 +40,8 @@ void *module_alloc(unsigned long size) NUMA_NO_NODE, __builtin_return_address(0)); if (!p && IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) && - !IS_ENABLED(CONFIG_KASAN)) + !IS_ENABLED(CONFIG_KASAN_GENERIC) && + !IS_ENABLED(CONFIG_KASAN_SW_TAGS)) /* * KASAN can only deal with module allocations being served * from the reserved module region, since the remainder of diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c index ef15c8a2a49d..dc9ada64feed 100644 --- a/arch/arm64/kernel/mte.c +++ b/arch/arm64/kernel/mte.c @@ -13,13 +13,18 @@ #include <linux/swap.h> #include <linux/swapops.h> #include <linux/thread_info.h> +#include <linux/types.h> #include <linux/uio.h> +#include <asm/barrier.h> #include <asm/cpufeature.h> #include <asm/mte.h> +#include <asm/mte-kasan.h> #include <asm/ptrace.h> #include <asm/sysreg.h> +u64 gcr_kernel_excl __ro_after_init; + static void mte_sync_page_tags(struct page *page, pte_t *ptep, bool check_swap) { pte_t old_pte = READ_ONCE(*ptep); @@ -31,6 +36,15 @@ static void mte_sync_page_tags(struct page *page, pte_t *ptep, bool check_swap) return; } + page_kasan_tag_reset(page); + /* + * We need smp_wmb() in between setting the flags and clearing the + * tags because if another thread reads page->flags and builds a + * tagged address out of it, there is an actual dependency to the + * memory access, but on the current thread we do not guarantee that + * the new page->flags are visible before the tags were updated. + */ + smp_wmb(); mte_clear_page_tags(page_address(page)); } @@ -72,6 +86,78 @@ int memcmp_pages(struct page *page1, struct page *page2) return ret; } +u8 mte_get_mem_tag(void *addr) +{ + if (!system_supports_mte()) + return 0xFF; + + asm(__MTE_PREAMBLE "ldg %0, [%0]" + : "+r" (addr)); + + return mte_get_ptr_tag(addr); +} + +u8 mte_get_random_tag(void) +{ + void *addr; + + if (!system_supports_mte()) + return 0xFF; + + asm(__MTE_PREAMBLE "irg %0, %0" + : "+r" (addr)); + + return mte_get_ptr_tag(addr); +} + +void *mte_set_mem_tag_range(void *addr, size_t size, u8 tag) +{ + void *ptr = addr; + + if ((!system_supports_mte()) || (size == 0)) + return addr; + + /* Make sure that size is MTE granule aligned. */ + WARN_ON(size & (MTE_GRANULE_SIZE - 1)); + + /* Make sure that the address is MTE granule aligned. */ + WARN_ON((u64)addr & (MTE_GRANULE_SIZE - 1)); + + tag = 0xF0 | tag; + ptr = (void *)__tag_set(ptr, tag); + + mte_assign_mem_tag_range(ptr, size); + + return ptr; +} + +void mte_init_tags(u64 max_tag) +{ + static bool gcr_kernel_excl_initialized; + + if (!gcr_kernel_excl_initialized) { + /* + * The format of the tags in KASAN is 0xFF and in MTE is 0xF. + * This conversion extracts an MTE tag from a KASAN tag. + */ + u64 incl = GENMASK(FIELD_GET(MTE_TAG_MASK >> MTE_TAG_SHIFT, + max_tag), 0); + + gcr_kernel_excl = ~incl & SYS_GCR_EL1_EXCL_MASK; + gcr_kernel_excl_initialized = true; + } + + /* Enable the kernel exclude mask for random tags generation. */ + write_sysreg_s(SYS_GCR_EL1_RRND | gcr_kernel_excl, SYS_GCR_EL1); +} + +void mte_enable_kernel(void) +{ + /* Enable MTE Sync Mode for EL1. */ + sysreg_clear_set(sctlr_el1, SCTLR_ELx_TCF_MASK, SCTLR_ELx_TCF_SYNC); + isb(); +} + static void update_sctlr_el1_tcf0(u64 tcf0) { /* ISB required for the kernel uaccess routines */ @@ -92,23 +178,26 @@ static void set_sctlr_el1_tcf0(u64 tcf0) preempt_enable(); } -static void update_gcr_el1_excl(u64 incl) +static void update_gcr_el1_excl(u64 excl) { - u64 excl = ~incl & SYS_GCR_EL1_EXCL_MASK; /* - * Note that 'incl' is an include mask (controlled by the user via - * prctl()) while GCR_EL1 accepts an exclude mask. + * Note that the mask controlled by the user via prctl() is an + * include while GCR_EL1 accepts an exclude mask. * No need for ISB since this only affects EL0 currently, implicit * with ERET. */ sysreg_clear_set_s(SYS_GCR_EL1, SYS_GCR_EL1_EXCL_MASK, excl); } -static void set_gcr_el1_excl(u64 incl) +static void set_gcr_el1_excl(u64 excl) { - current->thread.gcr_user_incl = incl; - update_gcr_el1_excl(incl); + current->thread.gcr_user_excl = excl; + + /* + * SYS_GCR_EL1 will be set to current->thread.gcr_user_excl value + * by mte_set_user_gcr() in kernel_exit, + */ } void flush_mte_state(void) @@ -123,7 +212,7 @@ void flush_mte_state(void) /* disable tag checking */ set_sctlr_el1_tcf0(SCTLR_EL1_TCF0_NONE); /* reset tag generation mask */ - set_gcr_el1_excl(0); + set_gcr_el1_excl(SYS_GCR_EL1_EXCL_MASK); } void mte_thread_switch(struct task_struct *next) @@ -134,7 +223,6 @@ void mte_thread_switch(struct task_struct *next) /* avoid expensive SCTLR_EL1 accesses if no change */ if (current->thread.sctlr_tcf0 != next->thread.sctlr_tcf0) update_sctlr_el1_tcf0(next->thread.sctlr_tcf0); - update_gcr_el1_excl(next->thread.gcr_user_incl); } void mte_suspend_exit(void) @@ -142,13 +230,14 @@ void mte_suspend_exit(void) if (!system_supports_mte()) return; - update_gcr_el1_excl(current->thread.gcr_user_incl); + update_gcr_el1_excl(gcr_kernel_excl); } long set_mte_ctrl(struct task_struct *task, unsigned long arg) { u64 tcf0; - u64 gcr_incl = (arg & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT; + u64 gcr_excl = ~((arg & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT) & + SYS_GCR_EL1_EXCL_MASK; if (!system_supports_mte()) return 0; @@ -169,10 +258,10 @@ long set_mte_ctrl(struct task_struct *task, unsigned long arg) if (task != current) { task->thread.sctlr_tcf0 = tcf0; - task->thread.gcr_user_incl = gcr_incl; + task->thread.gcr_user_excl = gcr_excl; } else { set_sctlr_el1_tcf0(tcf0); - set_gcr_el1_excl(gcr_incl); + set_gcr_el1_excl(gcr_excl); } return 0; @@ -181,11 +270,12 @@ long set_mte_ctrl(struct task_struct *task, unsigned long arg) long get_mte_ctrl(struct task_struct *task) { unsigned long ret; + u64 incl = ~task->thread.gcr_user_excl & SYS_GCR_EL1_EXCL_MASK; if (!system_supports_mte()) return 0; - ret = task->thread.gcr_user_incl << PR_MTE_TAG_SHIFT; + ret = incl << PR_MTE_TAG_SHIFT; switch (task->thread.sctlr_tcf0) { case SCTLR_EL1_TCF0_NONE: diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 38bb07eff872..3605f77ad4df 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -23,8 +23,6 @@ #include <linux/platform_device.h> #include <linux/sched_clock.h> #include <linux/smp.h> -#include <linux/nmi.h> -#include <linux/cpufreq.h> /* ARMv8 Cortex-A53 specific event types. */ #define ARMV8_A53_PERFCTR_PREF_LINEFILL 0xC2 @@ -1250,21 +1248,10 @@ static struct platform_driver armv8_pmu_driver = { static int __init armv8_pmu_driver_init(void) { - int ret; - if (acpi_disabled) - ret = platform_driver_register(&armv8_pmu_driver); + return platform_driver_register(&armv8_pmu_driver); else - ret = arm_pmu_acpi_probe(armv8_pmuv3_init); - - /* - * Try to re-initialize lockup detector after PMU init in - * case PMU events are triggered via NMIs. - */ - if (ret == 0 && arm_pmu_irq_is_nmi()) - lockup_detector_init(); - - return ret; + return arm_pmu_acpi_probe(armv8_pmuv3_init); } device_initcall(armv8_pmu_driver_init) @@ -1322,27 +1309,3 @@ void arch_perf_update_userpage(struct perf_event *event, userpg->cap_user_time_zero = 1; userpg->cap_user_time_short = 1; } - -#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF -/* - * Safe maximum CPU frequency in case a particular platform doesn't implement - * cpufreq driver. Although, architecture doesn't put any restrictions on - * maximum frequency but 5 GHz seems to be safe maximum given the available - * Arm CPUs in the market which are clocked much less than 5 GHz. On the other - * hand, we can't make it much higher as it would lead to a large hard-lockup - * detection timeout on parts which are running slower (eg. 1GHz on - * Developerbox) and doesn't possess a cpufreq driver. - */ -#define SAFE_MAX_CPU_FREQ 5000000000UL // 5 GHz -u64 hw_nmi_get_sample_period(int watchdog_thresh) -{ - unsigned int cpu = smp_processor_id(); - unsigned long max_cpu_freq; - - max_cpu_freq = cpufreq_get_hw_max_freq(cpu) * 1000UL; - if (!max_cpu_freq) - max_cpu_freq = SAFE_MAX_CPU_FREQ; - - return (u64)max_cpu_freq * watchdog_thresh; -} -#endif diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index 89c64ada8732..66aac2881ba8 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c @@ -352,8 +352,8 @@ kprobe_breakpoint_ss_handler(struct pt_regs *regs, unsigned int esr) unsigned long addr = instruction_pointer(regs); struct kprobe *cur = kprobe_running(); - if (cur && (kcb->kprobe_status == KPROBE_HIT_SS) - && ((unsigned long)&cur->ainsn.api.insn[1] == addr)) { + if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) && + ((unsigned long)&cur->ainsn.api.insn[1] == addr)) { kprobes_restore_local_irqflag(kcb, regs); post_kprobe_handler(cur, kcb, regs); diff --git a/arch/arm64/kernel/probes/kprobes_trampoline.S b/arch/arm64/kernel/probes/kprobes_trampoline.S index 890ca72c5a51..288a84e253cc 100644 --- a/arch/arm64/kernel/probes/kprobes_trampoline.S +++ b/arch/arm64/kernel/probes/kprobes_trampoline.S @@ -25,7 +25,7 @@ stp x24, x25, [sp, #S_X24] stp x26, x27, [sp, #S_X26] stp x28, x29, [sp, #S_X28] - add x0, sp, #S_FRAME_SIZE + add x0, sp, #PT_REGS_SIZE stp lr, x0, [sp, #S_LR] /* * Construct a useful saved PSTATE @@ -62,7 +62,7 @@ .endm SYM_CODE_START(kretprobe_trampoline) - sub sp, sp, #S_FRAME_SIZE + sub sp, sp, #PT_REGS_SIZE save_all_base_regs @@ -76,7 +76,7 @@ SYM_CODE_START(kretprobe_trampoline) restore_all_base_regs - add sp, sp, #S_FRAME_SIZE + add sp, sp, #PT_REGS_SIZE ret SYM_CODE_END(kretprobe_trampoline) diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c index 4c25c008504f..902e4084c477 100644 --- a/arch/arm64/kernel/proton-pack.c +++ b/arch/arm64/kernel/proton-pack.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Handle detection, reporting and mitigation of Spectre v1, v2 and v4, as + * Handle detection, reporting and mitigation of Spectre v1, v2, v3a and v4, as * detailed at: * * https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability @@ -27,6 +27,7 @@ #include <asm/insn.h> #include <asm/spectre.h> #include <asm/traps.h> +#include <asm/virt.h> /* * We try to ensure that the mitigation state can never change as the result of @@ -171,72 +172,26 @@ bool has_spectre_v2(const struct arm64_cpu_capabilities *entry, int scope) return true; } -DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data); - enum mitigation_state arm64_get_spectre_v2_state(void) { return spectre_v2_state; } -#ifdef CONFIG_KVM -#include <asm/cacheflush.h> -#include <asm/kvm_asm.h> - -atomic_t arm64_el2_vector_last_slot = ATOMIC_INIT(-1); - -static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start, - const char *hyp_vecs_end) -{ - void *dst = lm_alias(__bp_harden_hyp_vecs + slot * SZ_2K); - int i; - - for (i = 0; i < SZ_2K; i += 0x80) - memcpy(dst + i, hyp_vecs_start, hyp_vecs_end - hyp_vecs_start); - - __flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K); -} +DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data); static void install_bp_hardening_cb(bp_hardening_cb_t fn) { - static DEFINE_RAW_SPINLOCK(bp_lock); - int cpu, slot = -1; - const char *hyp_vecs_start = __smccc_workaround_1_smc; - const char *hyp_vecs_end = __smccc_workaround_1_smc + - __SMCCC_WORKAROUND_1_SMC_SZ; + __this_cpu_write(bp_hardening_data.fn, fn); /* * Vinz Clortho takes the hyp_vecs start/end "keys" at * the door when we're a guest. Skip the hyp-vectors work. */ - if (!is_hyp_mode_available()) { - __this_cpu_write(bp_hardening_data.fn, fn); + if (!is_hyp_mode_available()) return; - } - - raw_spin_lock(&bp_lock); - for_each_possible_cpu(cpu) { - if (per_cpu(bp_hardening_data.fn, cpu) == fn) { - slot = per_cpu(bp_hardening_data.hyp_vectors_slot, cpu); - break; - } - } - - if (slot == -1) { - slot = atomic_inc_return(&arm64_el2_vector_last_slot); - BUG_ON(slot >= BP_HARDEN_EL2_SLOTS); - __copy_hyp_vect_bpi(slot, hyp_vecs_start, hyp_vecs_end); - } - __this_cpu_write(bp_hardening_data.hyp_vectors_slot, slot); - __this_cpu_write(bp_hardening_data.fn, fn); - raw_spin_unlock(&bp_lock); -} -#else -static void install_bp_hardening_cb(bp_hardening_cb_t fn) -{ - __this_cpu_write(bp_hardening_data.fn, fn); + __this_cpu_write(bp_hardening_data.slot, HYP_VECTOR_SPECTRE_DIRECT); } -#endif /* CONFIG_KVM */ static void call_smc_arch_workaround_1(void) { @@ -318,6 +273,33 @@ void spectre_v2_enable_mitigation(const struct arm64_cpu_capabilities *__unused) } /* + * Spectre-v3a. + * + * Phew, there's not an awful lot to do here! We just instruct EL2 to use + * an indirect trampoline for the hyp vectors so that guests can't read + * VBAR_EL2 to defeat randomisation of the hypervisor VA layout. + */ +bool has_spectre_v3a(const struct arm64_cpu_capabilities *entry, int scope) +{ + static const struct midr_range spectre_v3a_unsafe_list[] = { + MIDR_ALL_VERSIONS(MIDR_CORTEX_A57), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A72), + {}, + }; + + WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); + return is_midr_in_range_list(read_cpuid_id(), spectre_v3a_unsafe_list); +} + +void spectre_v3a_enable_mitigation(const struct arm64_cpu_capabilities *__unused) +{ + struct bp_hardening_data *data = this_cpu_ptr(&bp_hardening_data); + + if (this_cpu_has_cap(ARM64_SPECTRE_V3A)) + data->slot += HYP_VECTOR_INDIRECT; +} + +/* * Spectre v4. * * If you thought Spectre v2 was nasty, wait until you see this mess. A CPU is diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 1a57a76e1cc2..c18aacde8bb0 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -276,7 +276,7 @@ arch_initcall(reserve_memblock_reserved_regions); u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID }; -u64 cpu_logical_map(int cpu) +u64 cpu_logical_map(unsigned int cpu) { return __cpu_logical_map[cpu]; } @@ -358,7 +358,7 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p) smp_build_mpidr_hash(); /* Init percpu seeds for random tags after cpus are set up. */ - kasan_init_tags(); + kasan_init_sw_tags(); #ifdef CONFIG_ARM64_SW_TTBR0_PAN /* diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index f71d6ce4673f..6237486ff6bb 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -914,13 +914,6 @@ static void do_signal(struct pt_regs *regs) asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags) { - /* - * 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) { /* Unmask Debug and SError for the next task */ diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S index 4be7f7eed875..6bdef7362c0e 100644 --- a/arch/arm64/kernel/sleep.S +++ b/arch/arm64/kernel/sleep.S @@ -133,7 +133,7 @@ SYM_FUNC_START(_cpu_resume) */ bl cpu_do_resume -#ifdef CONFIG_KASAN +#if defined(CONFIG_KASAN) && CONFIG_KASAN_STACK mov x0, sp bl kasan_unpoison_task_stack_below #endif diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 2499b895efea..ad00f99ee9b0 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -434,7 +434,7 @@ static void __init hyp_mode_check(void) "CPU: CPUs started in inconsistent modes"); else pr_info("CPU: All CPU(s) started at EL1\n"); - if (IS_ENABLED(CONFIG_KVM)) + if (IS_ENABLED(CONFIG_KVM) && !is_kernel_in_hyp_mode()) kvm_compute_layout(); } @@ -462,6 +462,8 @@ void __init smp_prepare_boot_cpu(void) /* Conditionally switch to GIC PMR for interrupt masking */ if (system_uses_irq_prio_masking()) init_gic_priority_masking(); + + kasan_init_hw_tags(); } static u64 __init of_get_cpu_mpidr(struct device_node *dn) @@ -805,11 +807,10 @@ int arch_show_interrupts(struct seq_file *p, int prec) unsigned int cpu, i; for (i = 0; i < NR_IPI; i++) { - unsigned int irq = irq_desc_get_irq(ipi_desc[i]); seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i, prec >= 4 ? " " : ""); for_each_online_cpu(cpu) - seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu)); + seq_printf(p, "%10u ", irq_desc_kstat_cpu(ipi_desc[i], cpu)); seq_printf(p, " %s\n", ipi_types[i]); } diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index f61e9d8cc55a..c2877c332f2d 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -9,6 +9,7 @@ #include <asm/daifflags.h> #include <asm/debug-monitors.h> +#include <asm/exception.h> #include <asm/fpsimd.h> #include <asm/syscall.h> #include <asm/thread_info.h> @@ -165,15 +166,8 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) { local_daif_mask(); flags = current_thread_info()->flags; - if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) { - /* - * We're off to userspace, where interrupts are - * always enabled after we restore the flags from - * the SPSR. - */ - trace_hardirqs_on(); + if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) return; - } local_daif_restore(DAIF_PROCCTX); } diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index c8308befdb1e..f6faa697e83e 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -314,7 +314,7 @@ void topology_scale_freq_tick(void) if (unlikely(core_cnt <= prev_core_cnt || const_cnt <= prev_const_cnt)) - goto store_and_exit; + return; /* * /\core arch_max_freq_scale @@ -331,10 +331,6 @@ void topology_scale_freq_tick(void) scale = min_t(unsigned long, scale, SCHED_CAPACITY_SCALE); this_cpu_write(freq_scale, (unsigned long)scale); - -store_and_exit: - this_cpu_write(arch_core_cycles_prev, core_cnt); - this_cpu_write(arch_const_cycles_prev, const_cnt); } #ifdef CONFIG_ACPI_CPPC_LIB diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 08156be75569..6895ce777e7f 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -42,7 +42,6 @@ #include <asm/smp.h> #include <asm/stack_pointer.h> #include <asm/stacktrace.h> -#include <asm/exception.h> #include <asm/system_misc.h> #include <asm/sysreg.h> diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile index a8f8e409e2bf..cd9c3fa25902 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile @@ -24,8 +24,7 @@ btildflags-$(CONFIG_ARM64_BTI_KERNEL) += -z force-bti # routines, as x86 does (see 6f121e548f83 ("x86, vdso: Reimplement vdso.so # preparation in build-time C")). ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \ - -Bsymbolic $(call ld-option, --no-eh-frame-hdr) --build-id=sha1 -n \ - $(btildflags-y) -T + -Bsymbolic --build-id=sha1 -n $(btildflags-y) -T ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18 ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S index d808ad31e01f..61dbb4c838ef 100644 --- a/arch/arm64/kernel/vdso/vdso.lds.S +++ b/arch/arm64/kernel/vdso/vdso.lds.S @@ -40,9 +40,6 @@ SECTIONS PROVIDE (_etext = .); PROVIDE (etext = .); - .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr - .eh_frame : { KEEP (*(.eh_frame)) } :text - .dynamic : { *(.dynamic) } :text :dynamic .rodata : { *(.rodata*) } :text @@ -54,6 +51,7 @@ SECTIONS *(.note.GNU-stack) *(.data .data.* .gnu.linkonce.d.* .sdata*) *(.bss .sbss .dynbss .dynsbss) + *(.eh_frame .eh_frame_hdr) } } @@ -66,7 +64,6 @@ PHDRS text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ note PT_NOTE FLAGS(4); /* PF_R */ - eh_frame_hdr PT_GNU_EH_FRAME; } /* diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 5d5857c5b025..4c0b0c89ad59 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -30,6 +30,13 @@ jiffies = jiffies_64; *(__kvm_ex_table) \ __stop___kvm_ex_table = .; +#define HYPERVISOR_DATA_SECTIONS \ + HYP_SECTION_NAME(.data..ro_after_init) : { \ + __hyp_data_ro_after_init_start = .; \ + *(HYP_SECTION_NAME(.data..ro_after_init)) \ + __hyp_data_ro_after_init_end = .; \ + } + #define HYPERVISOR_PERCPU_SECTION \ . = ALIGN(PAGE_SIZE); \ HYP_SECTION_NAME(.data..percpu) : { \ @@ -37,6 +44,7 @@ jiffies = jiffies_64; } #else /* CONFIG_KVM */ #define HYPERVISOR_EXTABLE +#define HYPERVISOR_DATA_SECTIONS #define HYPERVISOR_PERCPU_SECTION #endif @@ -232,6 +240,8 @@ SECTIONS _sdata = .; RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN) + HYPERVISOR_DATA_SECTIONS + /* * Data written with the MMU off but read with the MMU on requires * cache lines to be invalidated, discarding up to a Cache Writeback diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index 043756db8f6e..3964acf5451e 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -49,14 +49,6 @@ if KVM source "virt/kvm/Kconfig" -config KVM_ARM_PMU - bool "Virtual Performance Monitoring Unit (PMU) support" - depends on HW_PERF_EVENTS - default y - help - Adds support for a virtual Performance Monitoring Unit (PMU) in - virtual machines. - endif # KVM endif # VIRTUALIZATION diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 1504c81fbf5d..13b017284bf9 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -13,10 +13,10 @@ obj-$(CONFIG_KVM) += hyp/ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \ $(KVM)/vfio.o $(KVM)/irqchip.o \ arm.o mmu.o mmio.o psci.o perf.o hypercalls.o pvtime.o \ - inject_fault.o regmap.o va_layout.o handle_exit.o \ + inject_fault.o va_layout.o handle_exit.o \ guest.o debug.o reset.o sys_regs.o \ vgic-sys-reg-v3.o fpsimd.o pmu.o \ - aarch32.o arch_timer.o \ + arch_timer.o \ vgic/vgic.o vgic/vgic-init.o \ vgic/vgic-irqfd.o vgic/vgic-v2.o \ vgic/vgic-v3.o vgic/vgic-v4.o \ @@ -24,4 +24,4 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \ vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \ vgic/vgic-its.o vgic/vgic-debug.o -kvm-$(CONFIG_KVM_ARM_PMU) += pmu-emul.o +kvm-$(CONFIG_HW_PERF_EVENTS) += pmu-emul.o diff --git a/arch/arm64/kvm/aarch32.c b/arch/arm64/kvm/aarch32.c deleted file mode 100644 index 40a62a99fbf8..000000000000 --- a/arch/arm64/kvm/aarch32.c +++ /dev/null @@ -1,232 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * (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> - */ - -#include <linux/bits.h> -#include <linux/kvm_host.h> -#include <asm/kvm_emulate.h> -#include <asm/kvm_hyp.h> - -#define DFSR_FSC_EXTABT_LPAE 0x10 -#define DFSR_FSC_EXTABT_nLPAE 0x08 -#define DFSR_LPAE BIT(9) - -/* - * Table taken from ARMv8 ARM DDI0487B-B, table G1-10. - */ -static const u8 return_offsets[8][2] = { - [0] = { 0, 0 }, /* Reset, unused */ - [1] = { 4, 2 }, /* Undefined */ - [2] = { 0, 0 }, /* SVC, unused */ - [3] = { 4, 4 }, /* Prefetch abort */ - [4] = { 8, 8 }, /* Data abort */ - [5] = { 0, 0 }, /* HVC, unused */ - [6] = { 4, 4 }, /* IRQ, unused */ - [7] = { 4, 4 }, /* FIQ, unused */ -}; - -static bool pre_fault_synchronize(struct kvm_vcpu *vcpu) -{ - preempt_disable(); - if (vcpu->arch.sysregs_loaded_on_cpu) { - kvm_arch_vcpu_put(vcpu); - return true; - } - - preempt_enable(); - return false; -} - -static void post_fault_synchronize(struct kvm_vcpu *vcpu, bool loaded) -{ - if (loaded) { - kvm_arch_vcpu_load(vcpu, smp_processor_id()); - preempt_enable(); - } -} - -/* - * When an exception is taken, most CPSR fields are left unchanged in the - * handler. However, some are explicitly overridden (e.g. M[4:0]). - * - * The SPSR/SPSR_ELx layouts differ, and the below is intended to work with - * either format. Note: SPSR.J bit doesn't exist in SPSR_ELx, but this bit was - * obsoleted by the ARMv7 virtualization extensions and is RES0. - * - * For the SPSR layout seen from AArch32, see: - * - ARM DDI 0406C.d, page B1-1148 - * - ARM DDI 0487E.a, page G8-6264 - * - * For the SPSR_ELx layout for AArch32 seen from AArch64, see: - * - ARM DDI 0487E.a, page C5-426 - * - * Here we manipulate the fields in order of the AArch32 SPSR_ELx layout, from - * MSB to LSB. - */ -static unsigned long get_except32_cpsr(struct kvm_vcpu *vcpu, u32 mode) -{ - u32 sctlr = vcpu_cp15(vcpu, c1_SCTLR); - unsigned long old, new; - - old = *vcpu_cpsr(vcpu); - new = 0; - - new |= (old & PSR_AA32_N_BIT); - new |= (old & PSR_AA32_Z_BIT); - new |= (old & PSR_AA32_C_BIT); - new |= (old & PSR_AA32_V_BIT); - new |= (old & PSR_AA32_Q_BIT); - - // CPSR.IT[7:0] are set to zero upon any exception - // See ARM DDI 0487E.a, section G1.12.3 - // See ARM DDI 0406C.d, section B1.8.3 - - new |= (old & PSR_AA32_DIT_BIT); - - // CPSR.SSBS is set to SCTLR.DSSBS upon any exception - // See ARM DDI 0487E.a, page G8-6244 - if (sctlr & BIT(31)) - new |= PSR_AA32_SSBS_BIT; - - // CPSR.PAN is unchanged unless SCTLR.SPAN == 0b0 - // SCTLR.SPAN is RES1 when ARMv8.1-PAN is not implemented - // See ARM DDI 0487E.a, page G8-6246 - new |= (old & PSR_AA32_PAN_BIT); - if (!(sctlr & BIT(23))) - new |= PSR_AA32_PAN_BIT; - - // SS does not exist in AArch32, so ignore - - // CPSR.IL is set to zero upon any exception - // See ARM DDI 0487E.a, page G1-5527 - - new |= (old & PSR_AA32_GE_MASK); - - // CPSR.IT[7:0] are set to zero upon any exception - // See prior comment above - - // CPSR.E is set to SCTLR.EE upon any exception - // See ARM DDI 0487E.a, page G8-6245 - // See ARM DDI 0406C.d, page B4-1701 - if (sctlr & BIT(25)) - new |= PSR_AA32_E_BIT; - - // CPSR.A is unchanged upon an exception to Undefined, Supervisor - // CPSR.A is set upon an exception to other modes - // See ARM DDI 0487E.a, pages G1-5515 to G1-5516 - // See ARM DDI 0406C.d, page B1-1182 - new |= (old & PSR_AA32_A_BIT); - if (mode != PSR_AA32_MODE_UND && mode != PSR_AA32_MODE_SVC) - new |= PSR_AA32_A_BIT; - - // CPSR.I is set upon any exception - // See ARM DDI 0487E.a, pages G1-5515 to G1-5516 - // See ARM DDI 0406C.d, page B1-1182 - new |= PSR_AA32_I_BIT; - - // CPSR.F is set upon an exception to FIQ - // CPSR.F is unchanged upon an exception to other modes - // See ARM DDI 0487E.a, pages G1-5515 to G1-5516 - // See ARM DDI 0406C.d, page B1-1182 - new |= (old & PSR_AA32_F_BIT); - if (mode == PSR_AA32_MODE_FIQ) - new |= PSR_AA32_F_BIT; - - // CPSR.T is set to SCTLR.TE upon any exception - // See ARM DDI 0487E.a, page G8-5514 - // See ARM DDI 0406C.d, page B1-1181 - if (sctlr & BIT(30)) - new |= PSR_AA32_T_BIT; - - new |= mode; - - return new; -} - -static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset) -{ - unsigned long spsr = *vcpu_cpsr(vcpu); - bool is_thumb = (spsr & PSR_AA32_T_BIT); - u32 return_offset = return_offsets[vect_offset >> 2][is_thumb]; - u32 sctlr = vcpu_cp15(vcpu, c1_SCTLR); - - *vcpu_cpsr(vcpu) = get_except32_cpsr(vcpu, mode); - - /* Note: These now point to the banked copies */ - vcpu_write_spsr(vcpu, host_spsr_to_spsr32(spsr)); - *vcpu_reg32(vcpu, 14) = *vcpu_pc(vcpu) + return_offset; - - /* Branch to exception vector */ - if (sctlr & (1 << 13)) - vect_offset += 0xffff0000; - else /* always have security exceptions */ - vect_offset += vcpu_cp15(vcpu, c12_VBAR); - - *vcpu_pc(vcpu) = vect_offset; -} - -void kvm_inject_undef32(struct kvm_vcpu *vcpu) -{ - bool loaded = pre_fault_synchronize(vcpu); - - prepare_fault32(vcpu, PSR_AA32_MODE_UND, 4); - post_fault_synchronize(vcpu, loaded); -} - -/* - * Modelled after TakeDataAbortException() and TakePrefetchAbortException - * pseudocode. - */ -static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt, - unsigned long addr) -{ - u32 vect_offset; - u32 *far, *fsr; - bool is_lpae; - bool loaded; - - loaded = pre_fault_synchronize(vcpu); - - if (is_pabt) { - vect_offset = 12; - far = &vcpu_cp15(vcpu, c6_IFAR); - fsr = &vcpu_cp15(vcpu, c5_IFSR); - } else { /* !iabt */ - vect_offset = 16; - far = &vcpu_cp15(vcpu, c6_DFAR); - fsr = &vcpu_cp15(vcpu, c5_DFSR); - } - - prepare_fault32(vcpu, PSR_AA32_MODE_ABT, vect_offset); - - *far = addr; - - /* Give the guest an IMPLEMENTATION DEFINED exception */ - is_lpae = (vcpu_cp15(vcpu, c2_TTBCR) >> 31); - if (is_lpae) { - *fsr = DFSR_LPAE | DFSR_FSC_EXTABT_LPAE; - } else { - /* no need to shuffle FS[4] into DFSR[10] as its 0 */ - *fsr = DFSR_FSC_EXTABT_nLPAE; - } - - post_fault_synchronize(vcpu, loaded); -} - -void kvm_inject_dabt32(struct kvm_vcpu *vcpu, unsigned long addr) -{ - inject_abt32(vcpu, false, addr); -} - -void kvm_inject_pabt32(struct kvm_vcpu *vcpu, unsigned long addr) -{ - inject_abt32(vcpu, true, addr); -} diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 32ba6fbc3814..74e0699661e9 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -1129,9 +1129,10 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) if (!irqchip_in_kernel(vcpu->kvm)) goto no_vgic; - if (!vgic_initialized(vcpu->kvm)) - return -ENODEV; - + /* + * At this stage, we have the guarantee that the vgic is both + * available and initialized. + */ if (!timer_irqs_are_valid(vcpu)) { kvm_debug("incorrectly configured timer irqs\n"); return -EINVAL; diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index c0ffb019ca8b..fe60d25c000e 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -19,6 +19,7 @@ #include <linux/kvm_irqfd.h> #include <linux/irqbypass.h> #include <linux/sched/stat.h> +#include <linux/psci.h> #include <trace/events/kvm.h> #define CREATE_TRACE_POINTS @@ -35,7 +36,6 @@ #include <asm/kvm_asm.h> #include <asm/kvm_mmu.h> #include <asm/kvm_emulate.h> -#include <asm/kvm_coproc.h> #include <asm/sections.h> #include <kvm/arm_hypercalls.h> @@ -46,10 +46,14 @@ __asm__(".arch_extension virt"); #endif +static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT; +DEFINE_STATIC_KEY_FALSE(kvm_protected_mode_initialized); + DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector); static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page); unsigned long kvm_arm_hyp_percpu_base[NR_CPUS]; +DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params); /* The VMID used in the VTTBR */ static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1); @@ -102,7 +106,7 @@ static int kvm_arm_default_max_vcpus(void) return vgic_present ? kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS; } -static void set_default_csv2(struct kvm *kvm) +static void set_default_spectre(struct kvm *kvm) { /* * The default is to expose CSV2 == 1 if the HW isn't affected. @@ -114,6 +118,8 @@ static void set_default_csv2(struct kvm *kvm) */ if (arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED) kvm->arch.pfr0_csv2 = 1; + if (arm64_get_meltdown_state() == SPECTRE_UNAFFECTED) + kvm->arch.pfr0_csv3 = 1; } /** @@ -141,7 +147,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) /* The maximum number of VCPUs is limited by the host's GIC model */ kvm->arch.max_vcpus = kvm_arm_default_max_vcpus(); - set_default_csv2(kvm); + set_default_spectre(kvm); return ret; out_free_stage2_pgd: @@ -198,6 +204,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_ARM_IRQ_LINE_LAYOUT_2: case KVM_CAP_ARM_NISV_TO_USER: case KVM_CAP_ARM_INJECT_EXT_DABT: + case KVM_CAP_SET_GUEST_DEBUG: + case KVM_CAP_VCPU_ATTRIBUTES: r = 1; break; case KVM_CAP_ARM_SET_DEVICE_ADDR: @@ -229,10 +237,35 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_STEAL_TIME: r = kvm_arm_pvtime_supported(); break; - default: - r = kvm_arch_vm_ioctl_check_extension(kvm, ext); + case KVM_CAP_ARM_EL1_32BIT: + r = cpus_have_const_cap(ARM64_HAS_32BIT_EL1); + break; + case KVM_CAP_GUEST_DEBUG_HW_BPS: + r = get_num_brps(); + break; + case KVM_CAP_GUEST_DEBUG_HW_WPS: + r = get_num_wrps(); + break; + case KVM_CAP_ARM_PMU_V3: + r = kvm_arm_support_pmu_v3(); + break; + case KVM_CAP_ARM_INJECT_SERROR_ESR: + r = cpus_have_const_cap(ARM64_HAS_RAS_EXTN); + break; + case KVM_CAP_ARM_VM_IPA_SIZE: + r = get_kvm_ipa_limit(); break; + case KVM_CAP_ARM_SVE: + r = system_supports_sve(); + break; + case KVM_CAP_ARM_PTRAUTH_ADDRESS: + case KVM_CAP_ARM_PTRAUTH_GENERIC: + r = system_has_full_ptr_auth(); + break; + default: + r = 0; } + return r; } @@ -547,11 +580,9 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) * Map the VGIC hardware resources before running a vcpu the * first time on this VM. */ - if (unlikely(!vgic_ready(kvm))) { - ret = kvm_vgic_map_resources(kvm); - if (ret) - return ret; - } + ret = kvm_vgic_map_resources(kvm); + if (ret) + return ret; } else { /* * Tell the rest of the code that there are userspace irqchip @@ -1311,47 +1342,52 @@ static unsigned long nvhe_percpu_order(void) return size ? get_order(size) : 0; } -static int kvm_map_vectors(void) +/* A lookup table holding the hypervisor VA for each vector slot */ +static void *hyp_spectre_vector_selector[BP_HARDEN_EL2_SLOTS]; + +static int __kvm_vector_slot2idx(enum arm64_hyp_spectre_vector slot) { - /* - * SV2 = ARM64_SPECTRE_V2 - * HEL2 = ARM64_HARDEN_EL2_VECTORS - * - * !SV2 + !HEL2 -> use direct vectors - * SV2 + !HEL2 -> use hardened vectors in place - * !SV2 + HEL2 -> allocate one vector slot and use exec mapping - * SV2 + HEL2 -> use hardened vectors and use exec mapping - */ - if (cpus_have_const_cap(ARM64_SPECTRE_V2)) { - __kvm_bp_vect_base = kvm_ksym_ref(__bp_harden_hyp_vecs); - __kvm_bp_vect_base = kern_hyp_va(__kvm_bp_vect_base); - } + return slot - (slot != HYP_VECTOR_DIRECT); +} - if (cpus_have_const_cap(ARM64_HARDEN_EL2_VECTORS)) { - phys_addr_t vect_pa = __pa_symbol(__bp_harden_hyp_vecs); - unsigned long size = __BP_HARDEN_HYP_VECS_SZ; +static void kvm_init_vector_slot(void *base, enum arm64_hyp_spectre_vector slot) +{ + int idx = __kvm_vector_slot2idx(slot); - /* - * Always allocate a spare vector slot, as we don't - * know yet which CPUs have a BP hardening slot that - * we can reuse. - */ - __kvm_harden_el2_vector_slot = atomic_inc_return(&arm64_el2_vector_last_slot); - BUG_ON(__kvm_harden_el2_vector_slot >= BP_HARDEN_EL2_SLOTS); - return create_hyp_exec_mappings(vect_pa, size, - &__kvm_bp_vect_base); + hyp_spectre_vector_selector[slot] = base + (idx * SZ_2K); +} + +static int kvm_init_vector_slots(void) +{ + int err; + void *base; + + base = kern_hyp_va(kvm_ksym_ref(__kvm_hyp_vector)); + kvm_init_vector_slot(base, HYP_VECTOR_DIRECT); + + base = kern_hyp_va(kvm_ksym_ref(__bp_harden_hyp_vecs)); + kvm_init_vector_slot(base, HYP_VECTOR_SPECTRE_DIRECT); + + if (!cpus_have_const_cap(ARM64_SPECTRE_V3A)) + return 0; + + if (!has_vhe()) { + err = create_hyp_exec_mappings(__pa_symbol(__bp_harden_hyp_vecs), + __BP_HARDEN_HYP_VECS_SZ, &base); + if (err) + return err; } + kvm_init_vector_slot(base, HYP_VECTOR_INDIRECT); + kvm_init_vector_slot(base, HYP_VECTOR_SPECTRE_INDIRECT); return 0; } static void cpu_init_hyp_mode(void) { - phys_addr_t pgd_ptr; - unsigned long hyp_stack_ptr; - unsigned long vector_ptr; - unsigned long tpidr_el2; + struct kvm_nvhe_init_params *params = this_cpu_ptr_nvhe_sym(kvm_init_params); struct arm_smccc_res res; + unsigned long tcr; /* Switch from the HYP stub to our own HYP init vector */ __hyp_set_vectors(kvm_get_idmap_vector()); @@ -1360,14 +1396,40 @@ static void cpu_init_hyp_mode(void) * Calculate the raw per-cpu offset without a translation from the * kernel's mapping to the linear mapping, and store it in tpidr_el2 * so that we can use adr_l to access per-cpu variables in EL2. + * Also drop the KASAN tag which gets in the way... + */ + params->tpidr_el2 = (unsigned long)kasan_reset_tag(this_cpu_ptr_nvhe_sym(__per_cpu_start)) - + (unsigned long)kvm_ksym_ref(CHOOSE_NVHE_SYM(__per_cpu_start)); + + params->mair_el2 = read_sysreg(mair_el1); + + /* + * The ID map may be configured to use an extended virtual address + * range. This is only the case if system RAM is out of range for the + * currently configured page size and VA_BITS, in which case we will + * also need the extended virtual range for the HYP ID map, or we won't + * be able to enable the EL2 MMU. + * + * However, at EL2, there is only one TTBR register, and we can't switch + * between translation tables *and* update TCR_EL2.T0SZ at the same + * time. Bottom line: we need to use the extended range with *both* our + * translation tables. + * + * So use the same T0SZ value we use for the ID map. */ - tpidr_el2 = (unsigned long)this_cpu_ptr_nvhe_sym(__per_cpu_start) - - (unsigned long)kvm_ksym_ref(CHOOSE_NVHE_SYM(__per_cpu_start)); + tcr = (read_sysreg(tcr_el1) & TCR_EL2_MASK) | TCR_EL2_RES1; + tcr &= ~TCR_T0SZ_MASK; + tcr |= (idmap_t0sz & GENMASK(TCR_TxSZ_WIDTH - 1, 0)) << TCR_T0SZ_OFFSET; + params->tcr_el2 = tcr; - pgd_ptr = kvm_mmu_get_httbr(); - hyp_stack_ptr = __this_cpu_read(kvm_arm_hyp_stack_page) + PAGE_SIZE; - hyp_stack_ptr = kern_hyp_va(hyp_stack_ptr); - vector_ptr = (unsigned long)kern_hyp_va(kvm_ksym_ref(__kvm_hyp_host_vector)); + params->stack_hyp_va = kern_hyp_va(__this_cpu_read(kvm_arm_hyp_stack_page) + PAGE_SIZE); + params->pgd_pa = kvm_mmu_get_httbr(); + + /* + * Flush the init params from the data cache because the struct will + * be read while the MMU is off. + */ + kvm_flush_dcache_to_poc(params, sizeof(*params)); /* * Call initialization code, and switch to the full blown HYP code. @@ -1376,8 +1438,7 @@ static void cpu_init_hyp_mode(void) * cpus_have_const_cap() wrapper. */ BUG_ON(!system_capabilities_finalized()); - arm_smccc_1_1_hvc(KVM_HOST_SMCCC_FUNC(__kvm_hyp_init), - pgd_ptr, tpidr_el2, hyp_stack_ptr, vector_ptr, &res); + arm_smccc_1_1_hvc(KVM_HOST_SMCCC_FUNC(__kvm_hyp_init), virt_to_phys(params), &res); WARN_ON(res.a0 != SMCCC_RET_SUCCESS); /* @@ -1396,13 +1457,40 @@ static void cpu_hyp_reset(void) __hyp_reset_vectors(); } +/* + * EL2 vectors can be mapped and rerouted in a number of ways, + * depending on the kernel configuration and CPU present: + * + * - If the CPU is affected by Spectre-v2, the hardening sequence is + * placed in one of the vector slots, which is executed before jumping + * to the real vectors. + * + * - If the CPU also has the ARM64_SPECTRE_V3A cap, the slot + * containing the hardening sequence is mapped next to the idmap page, + * and executed before jumping to the real vectors. + * + * - If the CPU only has the ARM64_SPECTRE_V3A cap, then an + * empty slot is selected, mapped next to the idmap page, and + * executed before jumping to the real vectors. + * + * Note that ARM64_SPECTRE_V3A is somewhat incompatible with + * VHE, as we don't have hypervisor-specific mappings. If the system + * is VHE and yet selects this capability, it will be ignored. + */ +static void cpu_set_hyp_vector(void) +{ + struct bp_hardening_data *data = this_cpu_ptr(&bp_hardening_data); + void *vector = hyp_spectre_vector_selector[data->slot]; + + *this_cpu_ptr_hyp_sym(kvm_hyp_vector) = (unsigned long)vector; +} + static void cpu_hyp_reinit(void) { kvm_init_host_cpu_context(&this_cpu_ptr_hyp_sym(kvm_host_data)->host_ctxt); cpu_hyp_reset(); - - *this_cpu_ptr_hyp_sym(kvm_hyp_vector) = (unsigned long)kvm_get_hyp_vector(); + cpu_set_hyp_vector(); if (is_kernel_in_hyp_mode()) kvm_timer_init_vhe(); @@ -1439,7 +1527,8 @@ static void _kvm_arch_hardware_disable(void *discard) void kvm_arch_hardware_disable(void) { - _kvm_arch_hardware_disable(NULL); + if (!is_protected_kvm_enabled()) + _kvm_arch_hardware_disable(NULL); } #ifdef CONFIG_CPU_PM @@ -1480,13 +1569,15 @@ static struct notifier_block hyp_init_cpu_pm_nb = { .notifier_call = hyp_init_cpu_pm_notifier, }; -static void __init hyp_cpu_pm_init(void) +static void hyp_cpu_pm_init(void) { - cpu_pm_register_notifier(&hyp_init_cpu_pm_nb); + if (!is_protected_kvm_enabled()) + cpu_pm_register_notifier(&hyp_init_cpu_pm_nb); } -static void __init hyp_cpu_pm_exit(void) +static void hyp_cpu_pm_exit(void) { - cpu_pm_unregister_notifier(&hyp_init_cpu_pm_nb); + if (!is_protected_kvm_enabled()) + cpu_pm_unregister_notifier(&hyp_init_cpu_pm_nb); } #else static inline void hyp_cpu_pm_init(void) @@ -1497,6 +1588,46 @@ static inline void hyp_cpu_pm_exit(void) } #endif +static void init_cpu_logical_map(void) +{ + unsigned int cpu; + + /* + * Copy the MPIDR <-> logical CPU ID mapping to hyp. + * Only copy the set of online CPUs whose features have been chacked + * against the finalized system capabilities. The hypervisor will not + * allow any other CPUs from the `possible` set to boot. + */ + for_each_online_cpu(cpu) + hyp_cpu_logical_map[cpu] = cpu_logical_map(cpu); +} + +#define init_psci_0_1_impl_state(config, what) \ + config.psci_0_1_ ## what ## _implemented = psci_ops.what + +static bool init_psci_relay(void) +{ + /* + * If PSCI has not been initialized, protected KVM cannot install + * itself on newly booted CPUs. + */ + if (!psci_ops.get_version) { + kvm_err("Cannot initialize protected mode without PSCI\n"); + return false; + } + + kvm_host_psci_config.version = psci_ops.get_version(); + + if (kvm_host_psci_config.version == PSCI_VERSION(0, 1)) { + kvm_host_psci_config.function_ids_0_1 = get_psci_0_1_function_ids(); + init_psci_0_1_impl_state(kvm_host_psci_config, cpu_suspend); + init_psci_0_1_impl_state(kvm_host_psci_config, cpu_on); + init_psci_0_1_impl_state(kvm_host_psci_config, cpu_off); + init_psci_0_1_impl_state(kvm_host_psci_config, migrate); + } + return true; +} + static int init_common_resources(void) { return kvm_set_ipa_limit(); @@ -1541,10 +1672,11 @@ static int init_subsystems(void) goto out; kvm_perf_init(); - kvm_coproc_table_init(); + kvm_sys_reg_table_init(); out: - on_each_cpu(_kvm_arch_hardware_disable, NULL, 1); + if (err || !is_protected_kvm_enabled()) + on_each_cpu(_kvm_arch_hardware_disable, NULL, 1); return err; } @@ -1618,6 +1750,14 @@ static int init_hyp_mode(void) goto out_err; } + err = create_hyp_mappings(kvm_ksym_ref(__hyp_data_ro_after_init_start), + kvm_ksym_ref(__hyp_data_ro_after_init_end), + PAGE_HYP_RO); + if (err) { + kvm_err("Cannot map .hyp.data..ro_after_init section\n"); + goto out_err; + } + err = create_hyp_mappings(kvm_ksym_ref(__start_rodata), kvm_ksym_ref(__end_rodata), PAGE_HYP_RO); if (err) { @@ -1632,12 +1772,6 @@ static int init_hyp_mode(void) goto out_err; } - err = kvm_map_vectors(); - if (err) { - kvm_err("Cannot map vectors\n"); - goto out_err; - } - /* * Map the Hyp stack pages */ @@ -1667,6 +1801,13 @@ static int init_hyp_mode(void) } } + if (is_protected_kvm_enabled()) { + init_cpu_logical_map(); + + if (!init_psci_relay()) + goto out_err; + } + return 0; out_err: @@ -1781,14 +1922,24 @@ int kvm_arch_init(void *opaque) goto out_err; } + err = kvm_init_vector_slots(); + if (err) { + kvm_err("Cannot initialise vector slots\n"); + goto out_err; + } + err = init_subsystems(); if (err) goto out_hyp; - if (in_hyp_mode) + if (is_protected_kvm_enabled()) { + static_branch_enable(&kvm_protected_mode_initialized); + kvm_info("Protected nVHE mode initialized successfully\n"); + } else if (in_hyp_mode) { kvm_info("VHE mode initialized successfully\n"); - else + } else { kvm_info("Hyp mode initialized successfully\n"); + } return 0; @@ -1806,6 +1957,25 @@ void kvm_arch_exit(void) kvm_perf_teardown(); } +static int __init early_kvm_mode_cfg(char *arg) +{ + if (!arg) + return -EINVAL; + + if (strcmp(arg, "protected") == 0) { + kvm_mode = KVM_MODE_PROTECTED; + return 0; + } + + return -EINVAL; +} +early_param("kvm-arm.mode", early_kvm_mode_cfg); + +enum kvm_mode kvm_get_mode(void) +{ + return kvm_mode; +} + static int arm_init(void) { int rc = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index dfb5218137ca..9bbd30e62799 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -24,7 +24,6 @@ #include <asm/fpsimd.h> #include <asm/kvm.h> #include <asm/kvm_emulate.h> -#include <asm/kvm_coproc.h> #include <asm/sigcontext.h> #include "trace.h" @@ -252,10 +251,32 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) memcpy(addr, valp, KVM_REG_SIZE(reg->id)); if (*vcpu_cpsr(vcpu) & PSR_MODE32_BIT) { - int i; + int i, nr_reg; + + switch (*vcpu_cpsr(vcpu)) { + /* + * Either we are dealing with user mode, and only the + * first 15 registers (+ PC) must be narrowed to 32bit. + * AArch32 r0-r14 conveniently map to AArch64 x0-x14. + */ + case PSR_AA32_MODE_USR: + case PSR_AA32_MODE_SYS: + nr_reg = 15; + break; + + /* + * Otherwide, this is a priviledged mode, and *all* the + * registers must be narrowed to 32bit. + */ + default: + nr_reg = 31; + break; + } + + for (i = 0; i < nr_reg; i++) + vcpu_set_reg(vcpu, i, (u32)vcpu_get_reg(vcpu, i)); - for (i = 0; i < 16; i++) - *vcpu_reg32(vcpu, i) = (u32)*vcpu_reg32(vcpu, i); + *vcpu_pc(vcpu) = (u32)*vcpu_pc(vcpu); } out: return err; diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index 5d690d60ccad..cebe39f3b1b6 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -14,7 +14,6 @@ #include <asm/esr.h> #include <asm/exception.h> #include <asm/kvm_asm.h> -#include <asm/kvm_coproc.h> #include <asm/kvm_emulate.h> #include <asm/kvm_mmu.h> #include <asm/debug-monitors.h> @@ -61,7 +60,7 @@ static int handle_smc(struct kvm_vcpu *vcpu) * otherwise return to the same address... */ vcpu_set_reg(vcpu, 0, ~0UL); - kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); + kvm_incr_pc(vcpu); return 1; } @@ -100,7 +99,7 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu) kvm_clear_request(KVM_REQ_UNHALT, vcpu); } - kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); + kvm_incr_pc(vcpu); return 1; } @@ -221,7 +220,7 @@ static int handle_trap_exceptions(struct kvm_vcpu *vcpu) * that fail their condition code check" */ if (!kvm_condition_valid(vcpu)) { - kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); + kvm_incr_pc(vcpu); handled = 1; } else { exit_handle_fn exit_handler; @@ -241,23 +240,6 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index) { struct kvm_run *run = vcpu->run; - if (ARM_SERROR_PENDING(exception_index)) { - u8 esr_ec = ESR_ELx_EC(kvm_vcpu_get_esr(vcpu)); - - /* - * HVC/SMC already have an adjusted PC, which we need - * to correct in order to return to after having - * injected the SError. - */ - if (esr_ec == ESR_ELx_EC_HVC32 || esr_ec == ESR_ELx_EC_HVC64 || - esr_ec == ESR_ELx_EC_SMC32 || esr_ec == ESR_ELx_EC_SMC64) { - u32 adj = kvm_vcpu_trap_il_is32bit(vcpu) ? 4 : 2; - *vcpu_pc(vcpu) -= adj; - } - - return 1; - } - exception_index = ARM_EXCEPTION_CODE(exception_index); switch (exception_index) { diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile index 4a81eddabcd8..687598e41b21 100644 --- a/arch/arm64/kvm/hyp/Makefile +++ b/arch/arm64/kvm/hyp/Makefile @@ -10,4 +10,4 @@ subdir-ccflags-y := -I$(incdir) \ -DDISABLE_BRANCH_PROFILING \ $(DISABLE_STACKLEAK_PLUGIN) -obj-$(CONFIG_KVM) += vhe/ nvhe/ pgtable.o smccc_wa.o +obj-$(CONFIG_KVM) += vhe/ nvhe/ pgtable.o diff --git a/arch/arm64/kvm/hyp/aarch32.c b/arch/arm64/kvm/hyp/aarch32.c index ae56d8a4b382..f98cbe2626a1 100644 --- a/arch/arm64/kvm/hyp/aarch32.c +++ b/arch/arm64/kvm/hyp/aarch32.c @@ -123,13 +123,13 @@ static void kvm_adjust_itstate(struct kvm_vcpu *vcpu) * 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) +void kvm_skip_instr32(struct kvm_vcpu *vcpu) { u32 pc = *vcpu_pc(vcpu); bool is_thumb; is_thumb = !!(*vcpu_cpsr(vcpu) & PSR_AA32_T_BIT); - if (is_thumb && !is_wide_instr) + if (is_thumb && !kvm_vcpu_trap_il_is32bit(vcpu)) pc += 2; else pc += 4; diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c new file mode 100644 index 000000000000..73629094f903 --- /dev/null +++ b/arch/arm64/kvm/hyp/exception.c @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Fault injection for both 32 and 64bit 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> + */ + +#include <hyp/adjust_pc.h> +#include <linux/kvm_host.h> +#include <asm/kvm_emulate.h> + +#if !defined (__KVM_NVHE_HYPERVISOR__) && !defined (__KVM_VHE_HYPERVISOR__) +#error Hypervisor code only! +#endif + +static inline u64 __vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg) +{ + u64 val; + + if (__vcpu_read_sys_reg_from_cpu(reg, &val)) + return val; + + return __vcpu_sys_reg(vcpu, reg); +} + +static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg) +{ + if (__vcpu_write_sys_reg_to_cpu(val, reg)) + return; + + __vcpu_sys_reg(vcpu, reg) = val; +} + +static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, u64 val) +{ + write_sysreg_el1(val, SYS_SPSR); +} + +static void __vcpu_write_spsr_abt(struct kvm_vcpu *vcpu, u64 val) +{ + if (has_vhe()) + write_sysreg(val, spsr_abt); + else + vcpu->arch.ctxt.spsr_abt = val; +} + +static void __vcpu_write_spsr_und(struct kvm_vcpu *vcpu, u64 val) +{ + if (has_vhe()) + write_sysreg(val, spsr_und); + else + vcpu->arch.ctxt.spsr_und = val; +} + +/* + * This performs the exception entry at a given EL (@target_mode), stashing PC + * and PSTATE into ELR and SPSR respectively, and compute the new PC/PSTATE. + * The EL passed to this function *must* be a non-secure, privileged mode with + * bit 0 being set (PSTATE.SP == 1). + * + * When an exception is taken, most PSTATE fields are left unchanged in the + * handler. However, some are explicitly overridden (e.g. M[4:0]). Luckily all + * of the inherited bits have the same position in the AArch64/AArch32 SPSR_ELx + * layouts, so we don't need to shuffle these for exceptions from AArch32 EL0. + * + * For the SPSR_ELx layout for AArch64, see ARM DDI 0487E.a page C5-429. + * For the SPSR_ELx layout for AArch32, see ARM DDI 0487E.a page C5-426. + * + * Here we manipulate the fields in order of the AArch64 SPSR_ELx layout, from + * MSB to LSB. + */ +static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode, + enum exception_type type) +{ + unsigned long sctlr, vbar, old, new, mode; + u64 exc_offset; + + mode = *vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT); + + if (mode == target_mode) + exc_offset = CURRENT_EL_SP_ELx_VECTOR; + else if ((mode | PSR_MODE_THREAD_BIT) == target_mode) + exc_offset = CURRENT_EL_SP_EL0_VECTOR; + else if (!(mode & PSR_MODE32_BIT)) + exc_offset = LOWER_EL_AArch64_VECTOR; + else + exc_offset = LOWER_EL_AArch32_VECTOR; + + switch (target_mode) { + case PSR_MODE_EL1h: + vbar = __vcpu_read_sys_reg(vcpu, VBAR_EL1); + sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL1); + __vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL1); + break; + default: + /* Don't do that */ + BUG(); + } + + *vcpu_pc(vcpu) = vbar + exc_offset + type; + + old = *vcpu_cpsr(vcpu); + new = 0; + + new |= (old & PSR_N_BIT); + new |= (old & PSR_Z_BIT); + new |= (old & PSR_C_BIT); + new |= (old & PSR_V_BIT); + + // TODO: TCO (if/when ARMv8.5-MemTag is exposed to guests) + + new |= (old & PSR_DIT_BIT); + + // PSTATE.UAO is set to zero upon any exception to AArch64 + // See ARM DDI 0487E.a, page D5-2579. + + // PSTATE.PAN is unchanged unless SCTLR_ELx.SPAN == 0b0 + // SCTLR_ELx.SPAN is RES1 when ARMv8.1-PAN is not implemented + // See ARM DDI 0487E.a, page D5-2578. + new |= (old & PSR_PAN_BIT); + if (!(sctlr & SCTLR_EL1_SPAN)) + new |= PSR_PAN_BIT; + + // PSTATE.SS is set to zero upon any exception to AArch64 + // See ARM DDI 0487E.a, page D2-2452. + + // PSTATE.IL is set to zero upon any exception to AArch64 + // See ARM DDI 0487E.a, page D1-2306. + + // PSTATE.SSBS is set to SCTLR_ELx.DSSBS upon any exception to AArch64 + // See ARM DDI 0487E.a, page D13-3258 + if (sctlr & SCTLR_ELx_DSSBS) + new |= PSR_SSBS_BIT; + + // PSTATE.BTYPE is set to zero upon any exception to AArch64 + // See ARM DDI 0487E.a, pages D1-2293 to D1-2294. + + new |= PSR_D_BIT; + new |= PSR_A_BIT; + new |= PSR_I_BIT; + new |= PSR_F_BIT; + + new |= target_mode; + + *vcpu_cpsr(vcpu) = new; + __vcpu_write_spsr(vcpu, old); +} + +/* + * When an exception is taken, most CPSR fields are left unchanged in the + * handler. However, some are explicitly overridden (e.g. M[4:0]). + * + * The SPSR/SPSR_ELx layouts differ, and the below is intended to work with + * either format. Note: SPSR.J bit doesn't exist in SPSR_ELx, but this bit was + * obsoleted by the ARMv7 virtualization extensions and is RES0. + * + * For the SPSR layout seen from AArch32, see: + * - ARM DDI 0406C.d, page B1-1148 + * - ARM DDI 0487E.a, page G8-6264 + * + * For the SPSR_ELx layout for AArch32 seen from AArch64, see: + * - ARM DDI 0487E.a, page C5-426 + * + * Here we manipulate the fields in order of the AArch32 SPSR_ELx layout, from + * MSB to LSB. + */ +static unsigned long get_except32_cpsr(struct kvm_vcpu *vcpu, u32 mode) +{ + u32 sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL1); + unsigned long old, new; + + old = *vcpu_cpsr(vcpu); + new = 0; + + new |= (old & PSR_AA32_N_BIT); + new |= (old & PSR_AA32_Z_BIT); + new |= (old & PSR_AA32_C_BIT); + new |= (old & PSR_AA32_V_BIT); + new |= (old & PSR_AA32_Q_BIT); + + // CPSR.IT[7:0] are set to zero upon any exception + // See ARM DDI 0487E.a, section G1.12.3 + // See ARM DDI 0406C.d, section B1.8.3 + + new |= (old & PSR_AA32_DIT_BIT); + + // CPSR.SSBS is set to SCTLR.DSSBS upon any exception + // See ARM DDI 0487E.a, page G8-6244 + if (sctlr & BIT(31)) + new |= PSR_AA32_SSBS_BIT; + + // CPSR.PAN is unchanged unless SCTLR.SPAN == 0b0 + // SCTLR.SPAN is RES1 when ARMv8.1-PAN is not implemented + // See ARM DDI 0487E.a, page G8-6246 + new |= (old & PSR_AA32_PAN_BIT); + if (!(sctlr & BIT(23))) + new |= PSR_AA32_PAN_BIT; + + // SS does not exist in AArch32, so ignore + + // CPSR.IL is set to zero upon any exception + // See ARM DDI 0487E.a, page G1-5527 + + new |= (old & PSR_AA32_GE_MASK); + + // CPSR.IT[7:0] are set to zero upon any exception + // See prior comment above + + // CPSR.E is set to SCTLR.EE upon any exception + // See ARM DDI 0487E.a, page G8-6245 + // See ARM DDI 0406C.d, page B4-1701 + if (sctlr & BIT(25)) + new |= PSR_AA32_E_BIT; + + // CPSR.A is unchanged upon an exception to Undefined, Supervisor + // CPSR.A is set upon an exception to other modes + // See ARM DDI 0487E.a, pages G1-5515 to G1-5516 + // See ARM DDI 0406C.d, page B1-1182 + new |= (old & PSR_AA32_A_BIT); + if (mode != PSR_AA32_MODE_UND && mode != PSR_AA32_MODE_SVC) + new |= PSR_AA32_A_BIT; + + // CPSR.I is set upon any exception + // See ARM DDI 0487E.a, pages G1-5515 to G1-5516 + // See ARM DDI 0406C.d, page B1-1182 + new |= PSR_AA32_I_BIT; + + // CPSR.F is set upon an exception to FIQ + // CPSR.F is unchanged upon an exception to other modes + // See ARM DDI 0487E.a, pages G1-5515 to G1-5516 + // See ARM DDI 0406C.d, page B1-1182 + new |= (old & PSR_AA32_F_BIT); + if (mode == PSR_AA32_MODE_FIQ) + new |= PSR_AA32_F_BIT; + + // CPSR.T is set to SCTLR.TE upon any exception + // See ARM DDI 0487E.a, page G8-5514 + // See ARM DDI 0406C.d, page B1-1181 + if (sctlr & BIT(30)) + new |= PSR_AA32_T_BIT; + + new |= mode; + + return new; +} + +/* + * Table taken from ARMv8 ARM DDI0487B-B, table G1-10. + */ +static const u8 return_offsets[8][2] = { + [0] = { 0, 0 }, /* Reset, unused */ + [1] = { 4, 2 }, /* Undefined */ + [2] = { 0, 0 }, /* SVC, unused */ + [3] = { 4, 4 }, /* Prefetch abort */ + [4] = { 8, 8 }, /* Data abort */ + [5] = { 0, 0 }, /* HVC, unused */ + [6] = { 4, 4 }, /* IRQ, unused */ + [7] = { 4, 4 }, /* FIQ, unused */ +}; + +static void enter_exception32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset) +{ + unsigned long spsr = *vcpu_cpsr(vcpu); + bool is_thumb = (spsr & PSR_AA32_T_BIT); + u32 sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL1); + u32 return_address; + + *vcpu_cpsr(vcpu) = get_except32_cpsr(vcpu, mode); + return_address = *vcpu_pc(vcpu); + return_address += return_offsets[vect_offset >> 2][is_thumb]; + + /* KVM only enters the ABT and UND modes, so only deal with those */ + switch(mode) { + case PSR_AA32_MODE_ABT: + __vcpu_write_spsr_abt(vcpu, host_spsr_to_spsr32(spsr)); + vcpu_gp_regs(vcpu)->compat_lr_abt = return_address; + break; + + case PSR_AA32_MODE_UND: + __vcpu_write_spsr_und(vcpu, host_spsr_to_spsr32(spsr)); + vcpu_gp_regs(vcpu)->compat_lr_und = return_address; + break; + } + + /* Branch to exception vector */ + if (sctlr & (1 << 13)) + vect_offset += 0xffff0000; + else /* always have security exceptions */ + vect_offset += __vcpu_read_sys_reg(vcpu, VBAR_EL1); + + *vcpu_pc(vcpu) = vect_offset; +} + +void kvm_inject_exception(struct kvm_vcpu *vcpu) +{ + if (vcpu_el1_is_32bit(vcpu)) { + switch (vcpu->arch.flags & KVM_ARM64_EXCEPT_MASK) { + case KVM_ARM64_EXCEPT_AA32_UND: + enter_exception32(vcpu, PSR_AA32_MODE_UND, 4); + break; + case KVM_ARM64_EXCEPT_AA32_IABT: + enter_exception32(vcpu, PSR_AA32_MODE_ABT, 12); + break; + case KVM_ARM64_EXCEPT_AA32_DABT: + enter_exception32(vcpu, PSR_AA32_MODE_ABT, 16); + break; + default: + /* Err... */ + break; + } + } else { + switch (vcpu->arch.flags & KVM_ARM64_EXCEPT_MASK) { + case (KVM_ARM64_EXCEPT_AA64_ELx_SYNC | + KVM_ARM64_EXCEPT_AA64_EL1): + enter_exception64(vcpu, PSR_MODE_EL1h, except_type_sync); + break; + default: + /* + * Only EL1_SYNC makes sense so far, EL2_{SYNC,IRQ} + * will be implemented at some point. Everything + * else gets silently ignored. + */ + break; + } + } +} diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S index 0a5b36eb54b3..d179056e1af8 100644 --- a/arch/arm64/kvm/hyp/hyp-entry.S +++ b/arch/arm64/kvm/hyp/hyp-entry.S @@ -13,6 +13,7 @@ #include <asm/kvm_arm.h> #include <asm/kvm_asm.h> #include <asm/mmu.h> +#include <asm/spectre.h> .macro save_caller_saved_regs_vect /* x0 and x1 were saved in the vector entry */ @@ -187,52 +188,60 @@ SYM_CODE_START(__kvm_hyp_vector) valid_vect el1_error // Error 32-bit EL1 SYM_CODE_END(__kvm_hyp_vector) -.macro hyp_ventry - .align 7 +.macro spectrev2_smccc_wa1_smc + sub sp, sp, #(8 * 4) + stp x2, x3, [sp, #(8 * 0)] + stp x0, x1, [sp, #(8 * 2)] + mov w0, #ARM_SMCCC_ARCH_WORKAROUND_1 + smc #0 + ldp x2, x3, [sp, #(8 * 0)] + add sp, sp, #(8 * 2) +.endm + +.macro hyp_ventry indirect, spectrev2 + .align 7 1: esb - .rept 26 - nop - .endr -/* - * The default sequence is to directly branch to the KVM vectors, - * using the computed offset. This applies for VHE as well as - * !ARM64_HARDEN_EL2_VECTORS. The first vector must always run the preamble. - * - * For ARM64_HARDEN_EL2_VECTORS configurations, this gets replaced - * with: - * - * stp x0, x1, [sp, #-16]! - * movz x0, #(addr & 0xffff) - * movk x0, #((addr >> 16) & 0xffff), lsl #16 - * movk x0, #((addr >> 32) & 0xffff), lsl #32 - * br x0 - * - * Where: - * addr = kern_hyp_va(__kvm_hyp_vector) + vector-offset + KVM_VECTOR_PREAMBLE. - * See kvm_patch_vector_branch for details. - */ -alternative_cb kvm_patch_vector_branch + .if \spectrev2 != 0 + spectrev2_smccc_wa1_smc + .else stp x0, x1, [sp, #-16]! - b __kvm_hyp_vector + (1b - 0b + KVM_VECTOR_PREAMBLE) + .endif + .if \indirect != 0 + alternative_cb kvm_patch_vector_branch + /* + * For ARM64_SPECTRE_V3A configurations, these NOPs get replaced with: + * + * movz x0, #(addr & 0xffff) + * movk x0, #((addr >> 16) & 0xffff), lsl #16 + * movk x0, #((addr >> 32) & 0xffff), lsl #32 + * br x0 + * + * Where: + * addr = kern_hyp_va(__kvm_hyp_vector) + vector-offset + KVM_VECTOR_PREAMBLE. + * See kvm_patch_vector_branch for details. + */ nop nop nop -alternative_cb_end + nop + alternative_cb_end + .endif + b __kvm_hyp_vector + (1b - 0b + KVM_VECTOR_PREAMBLE) .endm -.macro generate_vectors +.macro generate_vectors indirect, spectrev2 0: .rept 16 - hyp_ventry + hyp_ventry \indirect, \spectrev2 .endr .org 0b + SZ_2K // Safety measure .endm .align 11 SYM_CODE_START(__bp_harden_hyp_vecs) - .rept BP_HARDEN_EL2_SLOTS - generate_vectors - .endr + generate_vectors indirect = 0, spectrev2 = 1 // HYP_VECTOR_SPECTRE_DIRECT + generate_vectors indirect = 1, spectrev2 = 0 // HYP_VECTOR_INDIRECT + generate_vectors indirect = 1, spectrev2 = 1 // HYP_VECTOR_SPECTRE_INDIRECT 1: .org __bp_harden_hyp_vecs + __BP_HARDEN_HYP_VECS_SZ .org 1b SYM_CODE_END(__bp_harden_hyp_vecs) diff --git a/arch/arm64/kvm/hyp/include/hyp/adjust_pc.h b/arch/arm64/kvm/hyp/include/hyp/adjust_pc.h new file mode 100644 index 000000000000..61716359035d --- /dev/null +++ b/arch/arm64/kvm/hyp/include/hyp/adjust_pc.h @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Guest PC manipulation helpers + * + * Copyright (C) 2012,2013 - ARM Ltd + * Copyright (C) 2020 - Google LLC + * Author: Marc Zyngier <maz@kernel.org> + */ + +#ifndef __ARM64_KVM_HYP_ADJUST_PC_H__ +#define __ARM64_KVM_HYP_ADJUST_PC_H__ + +#include <asm/kvm_emulate.h> +#include <asm/kvm_host.h> + +void kvm_inject_exception(struct kvm_vcpu *vcpu); + +static inline void kvm_skip_instr(struct kvm_vcpu *vcpu) +{ + if (vcpu_mode_is_32bit(vcpu)) { + kvm_skip_instr32(vcpu); + } else { + *vcpu_pc(vcpu) += 4; + *vcpu_cpsr(vcpu) &= ~PSR_BTYPE_MASK; + } + + /* advance the singlestep state machine */ + *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; +} + +/* + * Skip an instruction which has been emulated at hyp while most guest sysregs + * are live. + */ +static inline void __kvm_skip_instr(struct kvm_vcpu *vcpu) +{ + *vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR); + vcpu_gp_regs(vcpu)->pstate = read_sysreg_el2(SYS_SPSR); + + kvm_skip_instr(vcpu); + + write_sysreg_el2(vcpu_gp_regs(vcpu)->pstate, SYS_SPSR); + write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR); +} + +/* + * Adjust the guest PC on entry, depending on flags provided by EL1 + * for the purpose of emulation (MMIO, sysreg) or exception injection. + */ +static inline void __adjust_pc(struct kvm_vcpu *vcpu) +{ + if (vcpu->arch.flags & KVM_ARM64_PENDING_EXCEPTION) { + kvm_inject_exception(vcpu); + vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION | + KVM_ARM64_EXCEPT_MASK); + } else if (vcpu->arch.flags & KVM_ARM64_INCREMENT_PC) { + kvm_skip_instr(vcpu); + vcpu->arch.flags &= ~KVM_ARM64_INCREMENT_PC; + } +} + +/* + * Skip an instruction while host sysregs are live. + * Assumes host is always 64-bit. + */ +static inline void kvm_skip_host_instr(void) +{ + write_sysreg_el2(read_sysreg_el2(SYS_ELR) + 4, SYS_ELR); +} + +#endif diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h index 1f875a8f20c4..84473574c2e7 100644 --- a/arch/arm64/kvm/hyp/include/hyp/switch.h +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h @@ -7,6 +7,8 @@ #ifndef __ARM64_KVM_HYP_SWITCH_H__ #define __ARM64_KVM_HYP_SWITCH_H__ +#include <hyp/adjust_pc.h> + #include <linux/arm-smccc.h> #include <linux/kvm_host.h> #include <linux/types.h> @@ -409,6 +411,21 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) vcpu->arch.fault.esr_el2 = read_sysreg_el2(SYS_ESR); + if (ARM_SERROR_PENDING(*exit_code)) { + u8 esr_ec = kvm_vcpu_trap_get_class(vcpu); + + /* + * HVC already have an adjusted PC, which we need to + * correct in order to return to after having injected + * the SError. + * + * SMC, on the other hand, is *trapped*, meaning its + * preferred return address is the SMC itself. + */ + if (esr_ec == ESR_ELx_EC_HVC32 || esr_ec == ESR_ELx_EC_HVC64) + write_sysreg_el2(read_sysreg_el2(SYS_ELR) - 4, SYS_ELR); + } + /* * 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 diff --git a/arch/arm64/kvm/hyp/include/nvhe/trap_handler.h b/arch/arm64/kvm/hyp/include/nvhe/trap_handler.h new file mode 100644 index 000000000000..1e6d995968a1 --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/trap_handler.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Trap handler helpers. + * + * Copyright (C) 2020 - Google LLC + * Author: Marc Zyngier <maz@kernel.org> + */ + +#ifndef __ARM64_KVM_NVHE_TRAP_HANDLER_H__ +#define __ARM64_KVM_NVHE_TRAP_HANDLER_H__ + +#include <asm/kvm_host.h> + +#define cpu_reg(ctxt, r) (ctxt)->regs.regs[r] +#define DECLARE_REG(type, name, ctxt, reg) \ + type name = (type)cpu_reg(ctxt, (reg)) + +#endif /* __ARM64_KVM_NVHE_TRAP_HANDLER_H__ */ diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile index ddde15fe85f2..1f1e351c5fe2 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -6,9 +6,10 @@ asflags-y := -D__KVM_NVHE_HYPERVISOR__ ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o hyp-main.o +obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \ + hyp-main.o hyp-smp.o psci-relay.o obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \ - ../fpsimd.o ../hyp-entry.o + ../fpsimd.o ../hyp-entry.o ../exception.o ## ## Build rules for compiling nVHE hyp code diff --git a/arch/arm64/kvm/hyp/nvhe/host.S b/arch/arm64/kvm/hyp/nvhe/host.S index ed27f06a31ba..a820dfdc9c25 100644 --- a/arch/arm64/kvm/hyp/nvhe/host.S +++ b/arch/arm64/kvm/hyp/nvhe/host.S @@ -13,8 +13,6 @@ .text SYM_FUNC_START(__host_exit) - stp x0, x1, [sp, #-16]! - get_host_ctxt x0, x1 /* Store the host regs x2 and x3 */ @@ -41,6 +39,7 @@ SYM_FUNC_START(__host_exit) bl handle_trap /* Restore host regs x0-x17 */ +__host_enter_restore_full: ldp x0, x1, [x29, #CPU_XREG_OFFSET(0)] ldp x2, x3, [x29, #CPU_XREG_OFFSET(2)] ldp x4, x5, [x29, #CPU_XREG_OFFSET(4)] @@ -64,6 +63,14 @@ __host_enter_without_restoring: SYM_FUNC_END(__host_exit) /* + * void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt); + */ +SYM_FUNC_START(__host_enter) + mov x29, x0 + b __host_enter_restore_full +SYM_FUNC_END(__host_enter) + +/* * void __noreturn __hyp_do_panic(bool restore_host, u64 spsr, u64 elr, u64 par); */ SYM_FUNC_START(__hyp_do_panic) @@ -99,13 +106,15 @@ SYM_FUNC_END(__hyp_do_panic) mrs x0, esr_el2 lsr x0, x0, #ESR_ELx_EC_SHIFT cmp x0, #ESR_ELx_EC_HVC64 - ldp x0, x1, [sp], #16 b.ne __host_exit + ldp x0, x1, [sp] // Don't fixup the stack yet + /* Check for a stub HVC call */ cmp x0, #HVC_STUB_HCALL_NR b.hs __host_exit + add sp, sp, #16 /* * Compute the idmap address of __kvm_handle_stub_hvc and * jump there. Since we use kimage_voffset, do not use the @@ -115,10 +124,7 @@ SYM_FUNC_END(__hyp_do_panic) * Preserve x0-x4, which may contain stub parameters. */ ldr x5, =__kvm_handle_stub_hvc - ldr_l x6, kimage_voffset - - /* x5 = __pa(x5) */ - sub x5, x5, x6 + kimg_pa x5, x6 br x5 .L__vect_end\@: .if ((.L__vect_end\@ - .L__vect_start\@) > 0x80) @@ -183,3 +189,41 @@ SYM_CODE_START(__kvm_hyp_host_vector) invalid_host_el1_vect // FIQ 32-bit EL1 invalid_host_el1_vect // Error 32-bit EL1 SYM_CODE_END(__kvm_hyp_host_vector) + +/* + * Forward SMC with arguments in struct kvm_cpu_context, and + * store the result into the same struct. Assumes SMCCC 1.2 or older. + * + * x0: struct kvm_cpu_context* + */ +SYM_CODE_START(__kvm_hyp_host_forward_smc) + /* + * Use x18 to keep the pointer to the host context because + * x18 is callee-saved in SMCCC but not in AAPCS64. + */ + mov x18, x0 + + 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)] + + smc #0 + + stp x0, x1, [x18, #CPU_XREG_OFFSET(0)] + stp x2, x3, [x18, #CPU_XREG_OFFSET(2)] + stp x4, x5, [x18, #CPU_XREG_OFFSET(4)] + stp x6, x7, [x18, #CPU_XREG_OFFSET(6)] + stp x8, x9, [x18, #CPU_XREG_OFFSET(8)] + stp x10, x11, [x18, #CPU_XREG_OFFSET(10)] + stp x12, x13, [x18, #CPU_XREG_OFFSET(12)] + stp x14, x15, [x18, #CPU_XREG_OFFSET(14)] + stp x16, x17, [x18, #CPU_XREG_OFFSET(16)] + + ret +SYM_CODE_END(__kvm_hyp_host_forward_smc) diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-init.S b/arch/arm64/kvm/hyp/nvhe/hyp-init.S index b11a9d7db677..31b060a44045 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-init.S +++ b/arch/arm64/kvm/hyp/nvhe/hyp-init.S @@ -9,6 +9,7 @@ #include <asm/alternative.h> #include <asm/assembler.h> +#include <asm/el2_setup.h> #include <asm/kvm_arm.h> #include <asm/kvm_asm.h> #include <asm/kvm_mmu.h> @@ -47,10 +48,7 @@ __invalid: /* * x0: SMCCC function ID - * x1: HYP pgd - * x2: per-CPU offset - * x3: HYP stack - * x4: HYP vectors + * x1: struct kvm_nvhe_init_params PA */ __do_hyp_init: /* Check for a stub HVC call */ @@ -71,48 +69,53 @@ __do_hyp_init: mov x0, #SMCCC_RET_NOT_SUPPORTED eret -1: - /* Set tpidr_el2 for use by HYP to free a register */ - msr tpidr_el2, x2 +1: mov x0, x1 + mov x4, lr + bl ___kvm_hyp_init + mov lr, x4 - phys_to_ttbr x0, x1 -alternative_if ARM64_HAS_CNP - orr x0, x0, #TTBR_CNP_BIT + /* Hello, World! */ + mov x0, #SMCCC_RET_SUCCESS + eret +SYM_CODE_END(__kvm_hyp_init) + +/* + * Initialize the hypervisor in EL2. + * + * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers + * and leave x4 for the caller. + * + * x0: struct kvm_nvhe_init_params PA + */ +SYM_CODE_START_LOCAL(___kvm_hyp_init) +alternative_if ARM64_KVM_PROTECTED_MODE + mov_q x1, HCR_HOST_NVHE_PROTECTED_FLAGS + msr hcr_el2, x1 alternative_else_nop_endif - msr ttbr0_el2, x0 - mrs x0, tcr_el1 - mov_q x1, TCR_EL2_MASK - and x0, x0, x1 - mov x1, #TCR_EL2_RES1 - orr x0, x0, x1 + ldr x1, [x0, #NVHE_INIT_TPIDR_EL2] + msr tpidr_el2, x1 - /* - * The ID map may be configured to use an extended virtual address - * range. This is only the case if system RAM is out of range for the - * currently configured page size and VA_BITS, in which case we will - * also need the extended virtual range for the HYP ID map, or we won't - * be able to enable the EL2 MMU. - * - * However, at EL2, there is only one TTBR register, and we can't switch - * between translation tables *and* update TCR_EL2.T0SZ at the same - * time. Bottom line: we need to use the extended range with *both* our - * translation tables. - * - * So use the same T0SZ value we use for the ID map. - */ - ldr_l x1, idmap_t0sz - bfi x0, x1, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH + ldr x1, [x0, #NVHE_INIT_STACK_HYP_VA] + mov sp, x1 + + ldr x1, [x0, #NVHE_INIT_MAIR_EL2] + msr mair_el2, x1 + + ldr x1, [x0, #NVHE_INIT_PGD_PA] + phys_to_ttbr x2, x1 +alternative_if ARM64_HAS_CNP + orr x2, x2, #TTBR_CNP_BIT +alternative_else_nop_endif + msr ttbr0_el2, x2 /* * Set the PS bits in TCR_EL2. */ - tcr_compute_pa_size x0, #TCR_EL2_PS_SHIFT, x1, x2 + ldr x1, [x0, #NVHE_INIT_TCR_EL2] + tcr_compute_pa_size x1, #TCR_EL2_PS_SHIFT, x2, x3 + msr tcr_el2, x1 - msr tcr_el2, x0 - - mrs x0, mair_el1 - msr mair_el2, x0 isb /* Invalidate the stale TLBs from Bootloader */ @@ -134,14 +137,70 @@ alternative_else_nop_endif msr sctlr_el2, x0 isb - /* Set the stack and new vectors */ - mov sp, x3 - msr vbar_el2, x4 + /* Set the host vector */ + ldr x0, =__kvm_hyp_host_vector + kimg_hyp_va x0, x1 + msr vbar_el2, x0 - /* Hello, World! */ - mov x0, #SMCCC_RET_SUCCESS - eret -SYM_CODE_END(__kvm_hyp_init) + ret +SYM_CODE_END(___kvm_hyp_init) + +/* + * PSCI CPU_ON entry point + * + * x0: struct kvm_nvhe_init_params PA + */ +SYM_CODE_START(kvm_hyp_cpu_entry) + mov x1, #1 // is_cpu_on = true + b __kvm_hyp_init_cpu +SYM_CODE_END(kvm_hyp_cpu_entry) + +/* + * PSCI CPU_SUSPEND / SYSTEM_SUSPEND entry point + * + * x0: struct kvm_nvhe_init_params PA + */ +SYM_CODE_START(kvm_hyp_cpu_resume) + mov x1, #0 // is_cpu_on = false + b __kvm_hyp_init_cpu +SYM_CODE_END(kvm_hyp_cpu_resume) + +/* + * Common code for CPU entry points. Initializes EL2 state and + * installs the hypervisor before handing over to a C handler. + * + * x0: struct kvm_nvhe_init_params PA + * x1: bool is_cpu_on + */ +SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu) + mov x28, x0 // Stash arguments + mov x29, x1 + + /* Check that the core was booted in EL2. */ + mrs x0, CurrentEL + cmp x0, #CurrentEL_EL2 + b.eq 2f + + /* The core booted in EL1. KVM cannot be initialized on it. */ +1: wfe + wfi + b 1b + +2: msr SPsel, #1 // We want to use SP_EL{1,2} + + /* Initialize EL2 CPU state to sane values. */ + init_el2_state nvhe // Clobbers x0..x2 + + /* Enable MMU, set vectors and stack. */ + mov x0, x28 + bl ___kvm_hyp_init // Clobbers x0..x3 + + /* Leave idmap. */ + mov x0, x29 + ldr x1, =kvm_host_psci_cpu_entry + kimg_hyp_va x1, x2 + br x1 +SYM_CODE_END(__kvm_hyp_init_cpu) SYM_CODE_START(__kvm_handle_stub_hvc) cmp x0, #HVC_SOFT_RESTART @@ -176,6 +235,11 @@ reset: msr sctlr_el2, x5 isb +alternative_if ARM64_KVM_PROTECTED_MODE + mov_q x5, HCR_HOST_NVHE_FLAGS + msr hcr_el2, x5 +alternative_else_nop_endif + /* Install stub vectors */ adr_l x5, __hyp_stub_vectors msr vbar_el2, x5 diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index e2eafe2c93af..a906f9e2ff34 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -12,106 +12,175 @@ #include <asm/kvm_hyp.h> #include <asm/kvm_mmu.h> -#include <kvm/arm_hypercalls.h> +#include <nvhe/trap_handler.h> -static void handle_host_hcall(unsigned long func_id, - struct kvm_cpu_context *host_ctxt) +DEFINE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params); + +void __kvm_hyp_host_forward_smc(struct kvm_cpu_context *host_ctxt); + +static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt) { - unsigned long ret = 0; + DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1); - switch (func_id) { - case KVM_HOST_SMCCC_FUNC(__kvm_vcpu_run): { - unsigned long r1 = host_ctxt->regs.regs[1]; - struct kvm_vcpu *vcpu = (struct kvm_vcpu *)r1; + cpu_reg(host_ctxt, 1) = __kvm_vcpu_run(kern_hyp_va(vcpu)); +} - ret = __kvm_vcpu_run(kern_hyp_va(vcpu)); - break; - } - case KVM_HOST_SMCCC_FUNC(__kvm_flush_vm_context): - __kvm_flush_vm_context(); - break; - case KVM_HOST_SMCCC_FUNC(__kvm_tlb_flush_vmid_ipa): { - unsigned long r1 = host_ctxt->regs.regs[1]; - struct kvm_s2_mmu *mmu = (struct kvm_s2_mmu *)r1; - phys_addr_t ipa = host_ctxt->regs.regs[2]; - int level = host_ctxt->regs.regs[3]; +static void handle___kvm_flush_vm_context(struct kvm_cpu_context *host_ctxt) +{ + __kvm_flush_vm_context(); +} - __kvm_tlb_flush_vmid_ipa(kern_hyp_va(mmu), ipa, level); - break; - } - case KVM_HOST_SMCCC_FUNC(__kvm_tlb_flush_vmid): { - unsigned long r1 = host_ctxt->regs.regs[1]; - struct kvm_s2_mmu *mmu = (struct kvm_s2_mmu *)r1; +static void handle___kvm_tlb_flush_vmid_ipa(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); + DECLARE_REG(phys_addr_t, ipa, host_ctxt, 2); + DECLARE_REG(int, level, host_ctxt, 3); - __kvm_tlb_flush_vmid(kern_hyp_va(mmu)); - break; - } - case KVM_HOST_SMCCC_FUNC(__kvm_tlb_flush_local_vmid): { - unsigned long r1 = host_ctxt->regs.regs[1]; - struct kvm_s2_mmu *mmu = (struct kvm_s2_mmu *)r1; + __kvm_tlb_flush_vmid_ipa(kern_hyp_va(mmu), ipa, level); +} - __kvm_tlb_flush_local_vmid(kern_hyp_va(mmu)); - break; - } - case KVM_HOST_SMCCC_FUNC(__kvm_timer_set_cntvoff): { - u64 cntvoff = host_ctxt->regs.regs[1]; +static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); - __kvm_timer_set_cntvoff(cntvoff); - break; - } - case KVM_HOST_SMCCC_FUNC(__kvm_enable_ssbs): - __kvm_enable_ssbs(); - break; - case KVM_HOST_SMCCC_FUNC(__vgic_v3_get_ich_vtr_el2): - ret = __vgic_v3_get_ich_vtr_el2(); - break; - case KVM_HOST_SMCCC_FUNC(__vgic_v3_read_vmcr): - ret = __vgic_v3_read_vmcr(); - break; - case KVM_HOST_SMCCC_FUNC(__vgic_v3_write_vmcr): { - u32 vmcr = host_ctxt->regs.regs[1]; + __kvm_tlb_flush_vmid(kern_hyp_va(mmu)); +} - __vgic_v3_write_vmcr(vmcr); - break; - } - case KVM_HOST_SMCCC_FUNC(__vgic_v3_init_lrs): - __vgic_v3_init_lrs(); - break; - case KVM_HOST_SMCCC_FUNC(__kvm_get_mdcr_el2): - ret = __kvm_get_mdcr_el2(); - break; - case KVM_HOST_SMCCC_FUNC(__vgic_v3_save_aprs): { - unsigned long r1 = host_ctxt->regs.regs[1]; - struct vgic_v3_cpu_if *cpu_if = (struct vgic_v3_cpu_if *)r1; +static void handle___kvm_tlb_flush_local_vmid(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); - __vgic_v3_save_aprs(kern_hyp_va(cpu_if)); - break; - } - case KVM_HOST_SMCCC_FUNC(__vgic_v3_restore_aprs): { - unsigned long r1 = host_ctxt->regs.regs[1]; - struct vgic_v3_cpu_if *cpu_if = (struct vgic_v3_cpu_if *)r1; + __kvm_tlb_flush_local_vmid(kern_hyp_va(mmu)); +} - __vgic_v3_restore_aprs(kern_hyp_va(cpu_if)); - break; - } - default: - /* Invalid host HVC. */ - host_ctxt->regs.regs[0] = SMCCC_RET_NOT_SUPPORTED; - return; - } +static void handle___kvm_timer_set_cntvoff(struct kvm_cpu_context *host_ctxt) +{ + __kvm_timer_set_cntvoff(cpu_reg(host_ctxt, 1)); +} + +static void handle___kvm_enable_ssbs(struct kvm_cpu_context *host_ctxt) +{ + u64 tmp; + + tmp = read_sysreg_el2(SYS_SCTLR); + tmp |= SCTLR_ELx_DSSBS; + write_sysreg_el2(tmp, SYS_SCTLR); +} + +static void handle___vgic_v3_get_ich_vtr_el2(struct kvm_cpu_context *host_ctxt) +{ + cpu_reg(host_ctxt, 1) = __vgic_v3_get_ich_vtr_el2(); +} + +static void handle___vgic_v3_read_vmcr(struct kvm_cpu_context *host_ctxt) +{ + cpu_reg(host_ctxt, 1) = __vgic_v3_read_vmcr(); +} + +static void handle___vgic_v3_write_vmcr(struct kvm_cpu_context *host_ctxt) +{ + __vgic_v3_write_vmcr(cpu_reg(host_ctxt, 1)); +} + +static void handle___vgic_v3_init_lrs(struct kvm_cpu_context *host_ctxt) +{ + __vgic_v3_init_lrs(); +} + +static void handle___kvm_get_mdcr_el2(struct kvm_cpu_context *host_ctxt) +{ + cpu_reg(host_ctxt, 1) = __kvm_get_mdcr_el2(); +} + +static void handle___vgic_v3_save_aprs(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1); + + __vgic_v3_save_aprs(kern_hyp_va(cpu_if)); +} + +static void handle___vgic_v3_restore_aprs(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1); + + __vgic_v3_restore_aprs(kern_hyp_va(cpu_if)); +} + +typedef void (*hcall_t)(struct kvm_cpu_context *); + +#define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] = kimg_fn_ptr(handle_##x) + +static const hcall_t *host_hcall[] = { + HANDLE_FUNC(__kvm_vcpu_run), + HANDLE_FUNC(__kvm_flush_vm_context), + HANDLE_FUNC(__kvm_tlb_flush_vmid_ipa), + HANDLE_FUNC(__kvm_tlb_flush_vmid), + HANDLE_FUNC(__kvm_tlb_flush_local_vmid), + HANDLE_FUNC(__kvm_timer_set_cntvoff), + HANDLE_FUNC(__kvm_enable_ssbs), + HANDLE_FUNC(__vgic_v3_get_ich_vtr_el2), + HANDLE_FUNC(__vgic_v3_read_vmcr), + HANDLE_FUNC(__vgic_v3_write_vmcr), + HANDLE_FUNC(__vgic_v3_init_lrs), + HANDLE_FUNC(__kvm_get_mdcr_el2), + HANDLE_FUNC(__vgic_v3_save_aprs), + HANDLE_FUNC(__vgic_v3_restore_aprs), +}; + +static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(unsigned long, id, host_ctxt, 0); + const hcall_t *kfn; + hcall_t hfn; + + id -= KVM_HOST_SMCCC_ID(0); + + if (unlikely(id >= ARRAY_SIZE(host_hcall))) + goto inval; + + kfn = host_hcall[id]; + if (unlikely(!kfn)) + goto inval; - host_ctxt->regs.regs[0] = SMCCC_RET_SUCCESS; - host_ctxt->regs.regs[1] = ret; + cpu_reg(host_ctxt, 0) = SMCCC_RET_SUCCESS; + + hfn = kimg_fn_hyp_va(kfn); + hfn(host_ctxt); + + return; +inval: + cpu_reg(host_ctxt, 0) = SMCCC_RET_NOT_SUPPORTED; +} + +static void default_host_smc_handler(struct kvm_cpu_context *host_ctxt) +{ + __kvm_hyp_host_forward_smc(host_ctxt); +} + +static void handle_host_smc(struct kvm_cpu_context *host_ctxt) +{ + bool handled; + + handled = kvm_host_psci_handler(host_ctxt); + if (!handled) + default_host_smc_handler(host_ctxt); + + /* SMC was trapped, move ELR past the current PC. */ + kvm_skip_host_instr(); } void handle_trap(struct kvm_cpu_context *host_ctxt) { u64 esr = read_sysreg_el2(SYS_ESR); - unsigned long func_id; - if (ESR_ELx_EC(esr) != ESR_ELx_EC_HVC64) + switch (ESR_ELx_EC(esr)) { + case ESR_ELx_EC_HVC64: + handle_host_hcall(host_ctxt); + break; + case ESR_ELx_EC_SMC64: + handle_host_smc(host_ctxt); + break; + default: hyp_panic(); - - func_id = host_ctxt->regs.regs[0]; - handle_host_hcall(func_id, host_ctxt); + } } diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-smp.c b/arch/arm64/kvm/hyp/nvhe/hyp-smp.c new file mode 100644 index 000000000000..2997aa156d8e --- /dev/null +++ b/arch/arm64/kvm/hyp/nvhe/hyp-smp.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 - Google LLC + * Author: David Brazdil <dbrazdil@google.com> + */ + +#include <asm/kvm_asm.h> +#include <asm/kvm_hyp.h> +#include <asm/kvm_mmu.h> + +/* + * nVHE copy of data structures tracking available CPU cores. + * Only entries for CPUs that were online at KVM init are populated. + * Other CPUs should not be allowed to boot because their features were + * not checked against the finalized system capabilities. + */ +u64 __ro_after_init hyp_cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID }; + +u64 cpu_logical_map(unsigned int cpu) +{ + if (cpu >= ARRAY_SIZE(hyp_cpu_logical_map)) + hyp_panic(); + + return hyp_cpu_logical_map[cpu]; +} + +unsigned long __hyp_per_cpu_offset(unsigned int cpu) +{ + unsigned long *cpu_base_array; + unsigned long this_cpu_base; + unsigned long elf_base; + + if (cpu >= ARRAY_SIZE(kvm_arm_hyp_percpu_base)) + hyp_panic(); + + cpu_base_array = (unsigned long *)hyp_symbol_addr(kvm_arm_hyp_percpu_base); + this_cpu_base = kern_hyp_va(cpu_base_array[cpu]); + elf_base = (unsigned long)hyp_symbol_addr(__per_cpu_start); + return this_cpu_base - elf_base; +} diff --git a/arch/arm64/kvm/hyp/nvhe/hyp.lds.S b/arch/arm64/kvm/hyp/nvhe/hyp.lds.S index a797abace13f..1206d0d754d5 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp.lds.S +++ b/arch/arm64/kvm/hyp/nvhe/hyp.lds.S @@ -21,4 +21,5 @@ SECTIONS { HYP_SECTION_NAME(.data..percpu) : { PERCPU_INPUT(L1_CACHE_BYTES) } + HYP_SECTION(.data..ro_after_init) } diff --git a/arch/arm64/kvm/hyp/nvhe/psci-relay.c b/arch/arm64/kvm/hyp/nvhe/psci-relay.c new file mode 100644 index 000000000000..8e7128cb7667 --- /dev/null +++ b/arch/arm64/kvm/hyp/nvhe/psci-relay.c @@ -0,0 +1,306 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 - Google LLC + * Author: David Brazdil <dbrazdil@google.com> + */ + +#include <asm/kvm_asm.h> +#include <asm/kvm_hyp.h> +#include <asm/kvm_mmu.h> +#include <linux/arm-smccc.h> +#include <linux/kvm_host.h> +#include <uapi/linux/psci.h> + +#include <nvhe/trap_handler.h> + +void kvm_hyp_cpu_entry(unsigned long r0); +void kvm_hyp_cpu_resume(unsigned long r0); + +void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt); + +/* Config options set by the host. */ +struct kvm_host_psci_config __ro_after_init kvm_host_psci_config; +s64 __ro_after_init hyp_physvirt_offset; + +#define __hyp_pa(x) ((phys_addr_t)((x)) + hyp_physvirt_offset) + +#define INVALID_CPU_ID UINT_MAX + +struct psci_boot_args { + atomic_t lock; + unsigned long pc; + unsigned long r0; +}; + +#define PSCI_BOOT_ARGS_UNLOCKED 0 +#define PSCI_BOOT_ARGS_LOCKED 1 + +#define PSCI_BOOT_ARGS_INIT \ + ((struct psci_boot_args){ \ + .lock = ATOMIC_INIT(PSCI_BOOT_ARGS_UNLOCKED), \ + }) + +static DEFINE_PER_CPU(struct psci_boot_args, cpu_on_args) = PSCI_BOOT_ARGS_INIT; +static DEFINE_PER_CPU(struct psci_boot_args, suspend_args) = PSCI_BOOT_ARGS_INIT; + +#define is_psci_0_1(what, func_id) \ + (kvm_host_psci_config.psci_0_1_ ## what ## _implemented && \ + (func_id) == kvm_host_psci_config.function_ids_0_1.what) + +static bool is_psci_0_1_call(u64 func_id) +{ + return (is_psci_0_1(cpu_suspend, func_id) || + is_psci_0_1(cpu_on, func_id) || + is_psci_0_1(cpu_off, func_id) || + is_psci_0_1(migrate, func_id)); +} + +static bool is_psci_0_2_call(u64 func_id) +{ + /* SMCCC reserves IDs 0x00-1F with the given 32/64-bit base for PSCI. */ + return (PSCI_0_2_FN(0) <= func_id && func_id <= PSCI_0_2_FN(31)) || + (PSCI_0_2_FN64(0) <= func_id && func_id <= PSCI_0_2_FN64(31)); +} + +static unsigned long psci_call(unsigned long fn, unsigned long arg0, + unsigned long arg1, unsigned long arg2) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_smc(fn, arg0, arg1, arg2, &res); + return res.a0; +} + +static unsigned long psci_forward(struct kvm_cpu_context *host_ctxt) +{ + return psci_call(cpu_reg(host_ctxt, 0), cpu_reg(host_ctxt, 1), + cpu_reg(host_ctxt, 2), cpu_reg(host_ctxt, 3)); +} + +static unsigned int find_cpu_id(u64 mpidr) +{ + unsigned int i; + + /* Reject invalid MPIDRs */ + if (mpidr & ~MPIDR_HWID_BITMASK) + return INVALID_CPU_ID; + + for (i = 0; i < NR_CPUS; i++) { + if (cpu_logical_map(i) == mpidr) + return i; + } + + return INVALID_CPU_ID; +} + +static __always_inline bool try_acquire_boot_args(struct psci_boot_args *args) +{ + return atomic_cmpxchg_acquire(&args->lock, + PSCI_BOOT_ARGS_UNLOCKED, + PSCI_BOOT_ARGS_LOCKED) == + PSCI_BOOT_ARGS_UNLOCKED; +} + +static __always_inline void release_boot_args(struct psci_boot_args *args) +{ + atomic_set_release(&args->lock, PSCI_BOOT_ARGS_UNLOCKED); +} + +static int psci_cpu_on(u64 func_id, struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(u64, mpidr, host_ctxt, 1); + DECLARE_REG(unsigned long, pc, host_ctxt, 2); + DECLARE_REG(unsigned long, r0, host_ctxt, 3); + + unsigned int cpu_id; + struct psci_boot_args *boot_args; + struct kvm_nvhe_init_params *init_params; + int ret; + + /* + * Find the logical CPU ID for the given MPIDR. The search set is + * the set of CPUs that were online at the point of KVM initialization. + * Booting other CPUs is rejected because their cpufeatures were not + * checked against the finalized capabilities. This could be relaxed + * by doing the feature checks in hyp. + */ + cpu_id = find_cpu_id(mpidr); + if (cpu_id == INVALID_CPU_ID) + return PSCI_RET_INVALID_PARAMS; + + boot_args = per_cpu_ptr(hyp_symbol_addr(cpu_on_args), cpu_id); + init_params = per_cpu_ptr(hyp_symbol_addr(kvm_init_params), cpu_id); + + /* Check if the target CPU is already being booted. */ + if (!try_acquire_boot_args(boot_args)) + return PSCI_RET_ALREADY_ON; + + boot_args->pc = pc; + boot_args->r0 = r0; + wmb(); + + ret = psci_call(func_id, mpidr, + __hyp_pa(hyp_symbol_addr(kvm_hyp_cpu_entry)), + __hyp_pa(init_params)); + + /* If successful, the lock will be released by the target CPU. */ + if (ret != PSCI_RET_SUCCESS) + release_boot_args(boot_args); + + return ret; +} + +static int psci_cpu_suspend(u64 func_id, struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(u64, power_state, host_ctxt, 1); + DECLARE_REG(unsigned long, pc, host_ctxt, 2); + DECLARE_REG(unsigned long, r0, host_ctxt, 3); + + struct psci_boot_args *boot_args; + struct kvm_nvhe_init_params *init_params; + + boot_args = this_cpu_ptr(hyp_symbol_addr(suspend_args)); + init_params = this_cpu_ptr(hyp_symbol_addr(kvm_init_params)); + + /* + * No need to acquire a lock before writing to boot_args because a core + * can only suspend itself. Racy CPU_ON calls use a separate struct. + */ + boot_args->pc = pc; + boot_args->r0 = r0; + + /* + * Will either return if shallow sleep state, or wake up into the entry + * point if it is a deep sleep state. + */ + return psci_call(func_id, power_state, + __hyp_pa(hyp_symbol_addr(kvm_hyp_cpu_resume)), + __hyp_pa(init_params)); +} + +static int psci_system_suspend(u64 func_id, struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(unsigned long, pc, host_ctxt, 1); + DECLARE_REG(unsigned long, r0, host_ctxt, 2); + + struct psci_boot_args *boot_args; + struct kvm_nvhe_init_params *init_params; + + boot_args = this_cpu_ptr(hyp_symbol_addr(suspend_args)); + init_params = this_cpu_ptr(hyp_symbol_addr(kvm_init_params)); + + /* + * No need to acquire a lock before writing to boot_args because a core + * can only suspend itself. Racy CPU_ON calls use a separate struct. + */ + boot_args->pc = pc; + boot_args->r0 = r0; + + /* Will only return on error. */ + return psci_call(func_id, + __hyp_pa(hyp_symbol_addr(kvm_hyp_cpu_resume)), + __hyp_pa(init_params), 0); +} + +asmlinkage void __noreturn kvm_host_psci_cpu_entry(bool is_cpu_on) +{ + struct psci_boot_args *boot_args; + struct kvm_cpu_context *host_ctxt; + + host_ctxt = &this_cpu_ptr(hyp_symbol_addr(kvm_host_data))->host_ctxt; + + if (is_cpu_on) + boot_args = this_cpu_ptr(hyp_symbol_addr(cpu_on_args)); + else + boot_args = this_cpu_ptr(hyp_symbol_addr(suspend_args)); + + cpu_reg(host_ctxt, 0) = boot_args->r0; + write_sysreg_el2(boot_args->pc, SYS_ELR); + + if (is_cpu_on) + release_boot_args(boot_args); + + __host_enter(host_ctxt); +} + +static unsigned long psci_0_1_handler(u64 func_id, struct kvm_cpu_context *host_ctxt) +{ + if (is_psci_0_1(cpu_off, func_id) || is_psci_0_1(migrate, func_id)) + return psci_forward(host_ctxt); + if (is_psci_0_1(cpu_on, func_id)) + return psci_cpu_on(func_id, host_ctxt); + if (is_psci_0_1(cpu_suspend, func_id)) + return psci_cpu_suspend(func_id, host_ctxt); + + return PSCI_RET_NOT_SUPPORTED; +} + +static unsigned long psci_0_2_handler(u64 func_id, struct kvm_cpu_context *host_ctxt) +{ + switch (func_id) { + case PSCI_0_2_FN_PSCI_VERSION: + case PSCI_0_2_FN_CPU_OFF: + case PSCI_0_2_FN64_AFFINITY_INFO: + case PSCI_0_2_FN64_MIGRATE: + case PSCI_0_2_FN_MIGRATE_INFO_TYPE: + case PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU: + return psci_forward(host_ctxt); + /* + * SYSTEM_OFF/RESET should not return according to the spec. + * Allow it so as to stay robust to broken firmware. + */ + case PSCI_0_2_FN_SYSTEM_OFF: + case PSCI_0_2_FN_SYSTEM_RESET: + return psci_forward(host_ctxt); + case PSCI_0_2_FN64_CPU_SUSPEND: + return psci_cpu_suspend(func_id, host_ctxt); + case PSCI_0_2_FN64_CPU_ON: + return psci_cpu_on(func_id, host_ctxt); + default: + return PSCI_RET_NOT_SUPPORTED; + } +} + +static unsigned long psci_1_0_handler(u64 func_id, struct kvm_cpu_context *host_ctxt) +{ + switch (func_id) { + case PSCI_1_0_FN_PSCI_FEATURES: + case PSCI_1_0_FN_SET_SUSPEND_MODE: + case PSCI_1_1_FN64_SYSTEM_RESET2: + return psci_forward(host_ctxt); + case PSCI_1_0_FN64_SYSTEM_SUSPEND: + return psci_system_suspend(func_id, host_ctxt); + default: + return psci_0_2_handler(func_id, host_ctxt); + } +} + +bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(u64, func_id, host_ctxt, 0); + unsigned long ret; + + switch (kvm_host_psci_config.version) { + case PSCI_VERSION(0, 1): + if (!is_psci_0_1_call(func_id)) + return false; + ret = psci_0_1_handler(func_id, host_ctxt); + break; + case PSCI_VERSION(0, 2): + if (!is_psci_0_2_call(func_id)) + return false; + ret = psci_0_2_handler(func_id, host_ctxt); + break; + default: + if (!is_psci_0_2_call(func_id)) + return false; + ret = psci_1_0_handler(func_id, host_ctxt); + break; + } + + cpu_reg(host_ctxt, 0) = ret; + cpu_reg(host_ctxt, 1) = 0; + cpu_reg(host_ctxt, 2) = 0; + cpu_reg(host_ctxt, 3) = 0; + return true; +} diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c index 8ae8160bc93a..f3d0e9eca56c 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -4,6 +4,7 @@ * Author: Marc Zyngier <marc.zyngier@arm.com> */ +#include <hyp/adjust_pc.h> #include <hyp/switch.h> #include <hyp/sysreg-sr.h> @@ -96,7 +97,10 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu) mdcr_el2 |= MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT; write_sysreg(mdcr_el2, mdcr_el2); - write_sysreg(HCR_HOST_NVHE_FLAGS, hcr_el2); + if (is_protected_kvm_enabled()) + write_sysreg(HCR_HOST_NVHE_PROTECTED_FLAGS, hcr_el2); + else + write_sysreg(HCR_HOST_NVHE_FLAGS, hcr_el2); write_sysreg(CPTR_EL2_DEFAULT, cptr_el2); write_sysreg(__kvm_hyp_host_vector, vbar_el2); } @@ -189,6 +193,8 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) __sysreg_save_state_nvhe(host_ctxt); + __adjust_pc(vcpu); + /* * We must restore the 32-bit state before the sysregs, thanks * to erratum #852523 (Cortex-A57) or #853709 (Cortex-A72). diff --git a/arch/arm64/kvm/hyp/nvhe/sysreg-sr.c b/arch/arm64/kvm/hyp/nvhe/sysreg-sr.c index 88a25fc8fcd3..29305022bc04 100644 --- a/arch/arm64/kvm/hyp/nvhe/sysreg-sr.c +++ b/arch/arm64/kvm/hyp/nvhe/sysreg-sr.c @@ -33,14 +33,3 @@ void __sysreg_restore_state_nvhe(struct kvm_cpu_context *ctxt) __sysreg_restore_user_state(ctxt); __sysreg_restore_el2_return_state(ctxt); } - -void __kvm_enable_ssbs(void) -{ - u64 tmp; - - asm volatile( - "mrs %0, sctlr_el2\n" - "orr %0, %0, %1\n" - "msr sctlr_el2, %0" - : "=&r" (tmp) : "L" (SCTLR_ELx_DSSBS)); -} diff --git a/arch/arm64/kvm/hyp/smccc_wa.S b/arch/arm64/kvm/hyp/smccc_wa.S deleted file mode 100644 index b0441dbdf68b..000000000000 --- a/arch/arm64/kvm/hyp/smccc_wa.S +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2015-2018 - ARM Ltd - * Author: Marc Zyngier <marc.zyngier@arm.com> - */ - -#include <linux/arm-smccc.h> -#include <linux/linkage.h> - -#include <asm/kvm_asm.h> -#include <asm/kvm_mmu.h> - - /* - * This is not executed directly and is instead copied into the vectors - * by install_bp_hardening_cb(). - */ - .data - .pushsection .rodata - .global __smccc_workaround_1_smc -SYM_DATA_START(__smccc_workaround_1_smc) - esb - sub sp, sp, #(8 * 4) - stp x2, x3, [sp, #(8 * 0)] - stp x0, x1, [sp, #(8 * 2)] - mov w0, #ARM_SMCCC_ARCH_WORKAROUND_1 - smc #0 - ldp x2, x3, [sp, #(8 * 0)] - ldp x0, x1, [sp, #(8 * 2)] - add sp, sp, #(8 * 4) -1: .org __smccc_workaround_1_smc + __SMCCC_WORKAROUND_1_SMC_SZ - .org 1b -SYM_DATA_END(__smccc_workaround_1_smc) diff --git a/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c b/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c index bd1bab551d48..8f0585640241 100644 --- a/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c +++ b/arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c @@ -4,6 +4,8 @@ * Author: Marc Zyngier <marc.zyngier@arm.com> */ +#include <hyp/adjust_pc.h> + #include <linux/compiler.h> #include <linux/irqchip/arm-gic.h> #include <linux/kvm_host.h> diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c index 452f4cacd674..80406f463c28 100644 --- a/arch/arm64/kvm/hyp/vgic-v3-sr.c +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c @@ -4,6 +4,8 @@ * Author: Marc Zyngier <marc.zyngier@arm.com> */ +#include <hyp/adjust_pc.h> + #include <linux/compiler.h> #include <linux/irqchip/arm-gic-v3.h> #include <linux/kvm_host.h> diff --git a/arch/arm64/kvm/hyp/vhe/Makefile b/arch/arm64/kvm/hyp/vhe/Makefile index 461e97c375cc..96bec0ecf9dd 100644 --- a/arch/arm64/kvm/hyp/vhe/Makefile +++ b/arch/arm64/kvm/hyp/vhe/Makefile @@ -8,4 +8,4 @@ ccflags-y := -D__KVM_VHE_HYPERVISOR__ obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \ - ../fpsimd.o ../hyp-entry.o + ../fpsimd.o ../hyp-entry.o ../exception.o diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c index 62546e20b251..af8e940d0f03 100644 --- a/arch/arm64/kvm/hyp/vhe/switch.c +++ b/arch/arm64/kvm/hyp/vhe/switch.c @@ -4,6 +4,7 @@ * Author: Marc Zyngier <marc.zyngier@arm.com> */ +#include <hyp/adjust_pc.h> #include <hyp/switch.h> #include <linux/arm-smccc.h> @@ -133,6 +134,8 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu) __load_guest_stage2(vcpu->arch.hw_mmu); __activate_traps(vcpu); + __adjust_pc(vcpu); + sysreg_restore_guest_state_vhe(guest_ctxt); __debug_switch_to_guest(vcpu); diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c index 34a96ab244fa..b47df73e98d7 100644 --- a/arch/arm64/kvm/inject_fault.c +++ b/arch/arm64/kvm/inject_fault.c @@ -14,119 +14,15 @@ #include <asm/kvm_emulate.h> #include <asm/esr.h> -#define CURRENT_EL_SP_EL0_VECTOR 0x0 -#define CURRENT_EL_SP_ELx_VECTOR 0x200 -#define LOWER_EL_AArch64_VECTOR 0x400 -#define LOWER_EL_AArch32_VECTOR 0x600 - -enum exception_type { - except_type_sync = 0, - except_type_irq = 0x80, - except_type_fiq = 0x100, - except_type_serror = 0x180, -}; - -/* - * This performs the exception entry at a given EL (@target_mode), stashing PC - * and PSTATE into ELR and SPSR respectively, and compute the new PC/PSTATE. - * The EL passed to this function *must* be a non-secure, privileged mode with - * bit 0 being set (PSTATE.SP == 1). - * - * When an exception is taken, most PSTATE fields are left unchanged in the - * handler. However, some are explicitly overridden (e.g. M[4:0]). Luckily all - * of the inherited bits have the same position in the AArch64/AArch32 SPSR_ELx - * layouts, so we don't need to shuffle these for exceptions from AArch32 EL0. - * - * For the SPSR_ELx layout for AArch64, see ARM DDI 0487E.a page C5-429. - * For the SPSR_ELx layout for AArch32, see ARM DDI 0487E.a page C5-426. - * - * Here we manipulate the fields in order of the AArch64 SPSR_ELx layout, from - * MSB to LSB. - */ -static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode, - enum exception_type type) -{ - unsigned long sctlr, vbar, old, new, mode; - u64 exc_offset; - - mode = *vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT); - - if (mode == target_mode) - exc_offset = CURRENT_EL_SP_ELx_VECTOR; - else if ((mode | PSR_MODE_THREAD_BIT) == target_mode) - exc_offset = CURRENT_EL_SP_EL0_VECTOR; - else if (!(mode & PSR_MODE32_BIT)) - exc_offset = LOWER_EL_AArch64_VECTOR; - else - exc_offset = LOWER_EL_AArch32_VECTOR; - - switch (target_mode) { - case PSR_MODE_EL1h: - vbar = vcpu_read_sys_reg(vcpu, VBAR_EL1); - sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL1); - vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL1); - break; - default: - /* Don't do that */ - BUG(); - } - - *vcpu_pc(vcpu) = vbar + exc_offset + type; - - old = *vcpu_cpsr(vcpu); - new = 0; - - new |= (old & PSR_N_BIT); - new |= (old & PSR_Z_BIT); - new |= (old & PSR_C_BIT); - new |= (old & PSR_V_BIT); - - // TODO: TCO (if/when ARMv8.5-MemTag is exposed to guests) - - new |= (old & PSR_DIT_BIT); - - // PSTATE.UAO is set to zero upon any exception to AArch64 - // See ARM DDI 0487E.a, page D5-2579. - - // PSTATE.PAN is unchanged unless SCTLR_ELx.SPAN == 0b0 - // SCTLR_ELx.SPAN is RES1 when ARMv8.1-PAN is not implemented - // See ARM DDI 0487E.a, page D5-2578. - new |= (old & PSR_PAN_BIT); - if (!(sctlr & SCTLR_EL1_SPAN)) - new |= PSR_PAN_BIT; - - // PSTATE.SS is set to zero upon any exception to AArch64 - // See ARM DDI 0487E.a, page D2-2452. - - // PSTATE.IL is set to zero upon any exception to AArch64 - // See ARM DDI 0487E.a, page D1-2306. - - // PSTATE.SSBS is set to SCTLR_ELx.DSSBS upon any exception to AArch64 - // See ARM DDI 0487E.a, page D13-3258 - if (sctlr & SCTLR_ELx_DSSBS) - new |= PSR_SSBS_BIT; - - // PSTATE.BTYPE is set to zero upon any exception to AArch64 - // See ARM DDI 0487E.a, pages D1-2293 to D1-2294. - - new |= PSR_D_BIT; - new |= PSR_A_BIT; - new |= PSR_I_BIT; - new |= PSR_F_BIT; - - new |= target_mode; - - *vcpu_cpsr(vcpu) = new; - vcpu_write_spsr(vcpu, old); -} - static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr) { unsigned long cpsr = *vcpu_cpsr(vcpu); bool is_aarch32 = vcpu_mode_is_32bit(vcpu); u32 esr = 0; - enter_exception64(vcpu, PSR_MODE_EL1h, except_type_sync); + vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1 | + KVM_ARM64_EXCEPT_AA64_ELx_SYNC | + KVM_ARM64_PENDING_EXCEPTION); vcpu_write_sys_reg(vcpu, addr, FAR_EL1); @@ -156,7 +52,9 @@ static void inject_undef64(struct kvm_vcpu *vcpu) { u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT); - enter_exception64(vcpu, PSR_MODE_EL1h, except_type_sync); + vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1 | + KVM_ARM64_EXCEPT_AA64_ELx_SYNC | + KVM_ARM64_PENDING_EXCEPTION); /* * Build an unknown exception, depending on the instruction @@ -168,6 +66,53 @@ static void inject_undef64(struct kvm_vcpu *vcpu) vcpu_write_sys_reg(vcpu, esr, ESR_EL1); } +#define DFSR_FSC_EXTABT_LPAE 0x10 +#define DFSR_FSC_EXTABT_nLPAE 0x08 +#define DFSR_LPAE BIT(9) +#define TTBCR_EAE BIT(31) + +static void inject_undef32(struct kvm_vcpu *vcpu) +{ + vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA32_UND | + KVM_ARM64_PENDING_EXCEPTION); +} + +/* + * Modelled after TakeDataAbortException() and TakePrefetchAbortException + * pseudocode. + */ +static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt, u32 addr) +{ + u64 far; + u32 fsr; + + /* Give the guest an IMPLEMENTATION DEFINED exception */ + if (vcpu_read_sys_reg(vcpu, TCR_EL1) & TTBCR_EAE) { + fsr = DFSR_LPAE | DFSR_FSC_EXTABT_LPAE; + } else { + /* no need to shuffle FS[4] into DFSR[10] as its 0 */ + fsr = DFSR_FSC_EXTABT_nLPAE; + } + + far = vcpu_read_sys_reg(vcpu, FAR_EL1); + + if (is_pabt) { + vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA32_IABT | + KVM_ARM64_PENDING_EXCEPTION); + far &= GENMASK(31, 0); + far |= (u64)addr << 32; + vcpu_write_sys_reg(vcpu, fsr, IFSR32_EL2); + } else { /* !iabt */ + vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA32_DABT | + KVM_ARM64_PENDING_EXCEPTION); + far &= GENMASK(63, 32); + far |= addr; + vcpu_write_sys_reg(vcpu, fsr, ESR_EL1); + } + + vcpu_write_sys_reg(vcpu, far, FAR_EL1); +} + /** * kvm_inject_dabt - inject a data abort into the guest * @vcpu: The VCPU to receive the data abort @@ -179,7 +124,7 @@ static void inject_undef64(struct kvm_vcpu *vcpu) void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr) { if (vcpu_el1_is_32bit(vcpu)) - kvm_inject_dabt32(vcpu, addr); + inject_abt32(vcpu, false, addr); else inject_abt64(vcpu, false, addr); } @@ -195,7 +140,7 @@ void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr) void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr) { if (vcpu_el1_is_32bit(vcpu)) - kvm_inject_pabt32(vcpu, addr); + inject_abt32(vcpu, true, addr); else inject_abt64(vcpu, true, addr); } @@ -210,7 +155,7 @@ void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr) void kvm_inject_undefined(struct kvm_vcpu *vcpu) { if (vcpu_el1_is_32bit(vcpu)) - kvm_inject_undef32(vcpu); + inject_undef32(vcpu); else inject_undef64(vcpu); } diff --git a/arch/arm64/kvm/mmio.c b/arch/arm64/kvm/mmio.c index 6a2826f1bf5e..3e2d8ba11a02 100644 --- a/arch/arm64/kvm/mmio.c +++ b/arch/arm64/kvm/mmio.c @@ -115,7 +115,7 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu) * The MMIO instruction is emulated and should not be re-executed * in the guest. */ - kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); + kvm_incr_pc(vcpu); return 0; } diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 75814a02d189..7d2257cc5438 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1023,7 +1023,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) * cautious, and skip the instruction. */ if (kvm_is_error_hva(hva) && kvm_vcpu_dabt_is_cm(vcpu)) { - kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); + kvm_incr_pc(vcpu); ret = 1; goto out_unlock; } diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index 2ed5ef8f274b..247422ac78a9 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -384,7 +384,7 @@ static void kvm_pmu_update_state(struct kvm_vcpu *vcpu) struct kvm_pmu *pmu = &vcpu->arch.pmu; bool overflow; - if (!kvm_arm_pmu_v3_ready(vcpu)) + if (!kvm_vcpu_has_pmu(vcpu)) return; overflow = !!kvm_pmu_overflow_status(vcpu); @@ -788,7 +788,7 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1) { unsigned long *bmap = vcpu->kvm->arch.pmu_filter; u64 val, mask = 0; - int base, i; + int base, i, nr_events; if (!pmceid1) { val = read_sysreg(pmceid0_el0); @@ -801,13 +801,17 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1) if (!bmap) return val; + nr_events = kvm_pmu_event_mask(vcpu->kvm) + 1; + for (i = 0; i < 32; i += 8) { u64 byte; byte = bitmap_get_value8(bmap, base + i); mask |= byte << i; - byte = bitmap_get_value8(bmap, 0x4000 + base + i); - mask |= byte << (32 + i); + if (nr_events >= (0x4000 + base + 32)) { + byte = bitmap_get_value8(bmap, 0x4000 + base + i); + mask |= byte << (32 + i); + } } return val & mask; @@ -825,9 +829,12 @@ bool kvm_arm_support_pmu_v3(void) int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu) { - if (!vcpu->arch.pmu.created) + if (!kvm_vcpu_has_pmu(vcpu)) return 0; + if (!vcpu->arch.pmu.created) + return -EINVAL; + /* * A valid interrupt configuration for the PMU is either to have a * properly configured interrupt number and using an in-kernel @@ -835,9 +842,6 @@ int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu) */ if (irqchip_in_kernel(vcpu->kvm)) { int irq = vcpu->arch.pmu.irq_num; - if (!kvm_arm_pmu_irq_initialized(vcpu)) - return -EINVAL; - /* * If we are using an in-kernel vgic, at this point we know * the vgic will be initialized, so we can check the PMU irq @@ -850,9 +854,6 @@ int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu) return -EINVAL; } - kvm_pmu_vcpu_reset(vcpu); - vcpu->arch.pmu.ready = true; - return 0; } @@ -913,8 +914,7 @@ static bool pmu_irq_is_valid(struct kvm *kvm, int irq) int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) { - if (!kvm_arm_support_pmu_v3() || - !test_bit(KVM_ARM_VCPU_PMU_V3, vcpu->arch.features)) + if (!kvm_vcpu_has_pmu(vcpu)) return -ENODEV; if (vcpu->arch.pmu.created) @@ -1015,7 +1015,7 @@ int kvm_arm_pmu_v3_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) if (!irqchip_in_kernel(vcpu->kvm)) return -EINVAL; - if (!test_bit(KVM_ARM_VCPU_PMU_V3, vcpu->arch.features)) + if (!kvm_vcpu_has_pmu(vcpu)) return -ENODEV; if (!kvm_arm_pmu_irq_initialized(vcpu)) @@ -1035,8 +1035,7 @@ int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) case KVM_ARM_VCPU_PMU_V3_IRQ: case KVM_ARM_VCPU_PMU_V3_INIT: case KVM_ARM_VCPU_PMU_V3_FILTER: - if (kvm_arm_support_pmu_v3() && - test_bit(KVM_ARM_VCPU_PMU_V3, vcpu->arch.features)) + if (kvm_vcpu_has_pmu(vcpu)) return 0; } diff --git a/arch/arm64/kvm/pvtime.c b/arch/arm64/kvm/pvtime.c index 920ac43077ad..78a09f7a6637 100644 --- a/arch/arm64/kvm/pvtime.c +++ b/arch/arm64/kvm/pvtime.c @@ -53,7 +53,6 @@ gpa_t kvm_init_stolen_time(struct kvm_vcpu *vcpu) struct pvclock_vcpu_stolen_time init_values = {}; struct kvm *kvm = vcpu->kvm; u64 base = vcpu->arch.steal.base; - int idx; if (base == GPA_INVALID) return base; @@ -63,10 +62,7 @@ gpa_t kvm_init_stolen_time(struct kvm_vcpu *vcpu) * the feature enabled. */ vcpu->arch.steal.last_steal = current->sched_info.run_delay; - - idx = srcu_read_lock(&kvm->srcu); - kvm_write_guest(kvm, base, &init_values, sizeof(init_values)); - srcu_read_unlock(&kvm->srcu, idx); + kvm_write_guest_lock(kvm, base, &init_values, sizeof(init_values)); return base; } diff --git a/arch/arm64/kvm/regmap.c b/arch/arm64/kvm/regmap.c deleted file mode 100644 index accc1d5fba61..000000000000 --- a/arch/arm64/kvm/regmap.c +++ /dev/null @@ -1,224 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2012,2013 - ARM Ltd - * Author: Marc Zyngier <marc.zyngier@arm.com> - * - * Derived from arch/arm/kvm/emulate.c: - * Copyright (C) 2012 - Virtual Open Systems and Columbia University - * Author: Christoffer Dall <c.dall@virtualopensystems.com> - */ - -#include <linux/mm.h> -#include <linux/kvm_host.h> -#include <asm/kvm_emulate.h> -#include <asm/ptrace.h> - -#define VCPU_NR_MODES 6 -#define REG_OFFSET(_reg) \ - (offsetof(struct user_pt_regs, _reg) / sizeof(unsigned long)) - -#define USR_REG_OFFSET(R) REG_OFFSET(compat_usr(R)) - -static const unsigned long vcpu_reg_offsets[VCPU_NR_MODES][16] = { - /* USR Registers */ - { - USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2), - USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5), - USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8), - USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11), - USR_REG_OFFSET(12), USR_REG_OFFSET(13), USR_REG_OFFSET(14), - REG_OFFSET(pc) - }, - - /* FIQ Registers */ - { - USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2), - USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5), - USR_REG_OFFSET(6), USR_REG_OFFSET(7), - REG_OFFSET(compat_r8_fiq), /* r8 */ - REG_OFFSET(compat_r9_fiq), /* r9 */ - REG_OFFSET(compat_r10_fiq), /* r10 */ - REG_OFFSET(compat_r11_fiq), /* r11 */ - REG_OFFSET(compat_r12_fiq), /* r12 */ - REG_OFFSET(compat_sp_fiq), /* r13 */ - REG_OFFSET(compat_lr_fiq), /* r14 */ - REG_OFFSET(pc) - }, - - /* IRQ Registers */ - { - USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2), - USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5), - USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8), - USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11), - USR_REG_OFFSET(12), - REG_OFFSET(compat_sp_irq), /* r13 */ - REG_OFFSET(compat_lr_irq), /* r14 */ - REG_OFFSET(pc) - }, - - /* SVC Registers */ - { - USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2), - USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5), - USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8), - USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11), - USR_REG_OFFSET(12), - REG_OFFSET(compat_sp_svc), /* r13 */ - REG_OFFSET(compat_lr_svc), /* r14 */ - REG_OFFSET(pc) - }, - - /* ABT Registers */ - { - USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2), - USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5), - USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8), - USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11), - USR_REG_OFFSET(12), - REG_OFFSET(compat_sp_abt), /* r13 */ - REG_OFFSET(compat_lr_abt), /* r14 */ - REG_OFFSET(pc) - }, - - /* UND Registers */ - { - USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2), - USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5), - USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8), - USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11), - USR_REG_OFFSET(12), - REG_OFFSET(compat_sp_und), /* r13 */ - REG_OFFSET(compat_lr_und), /* r14 */ - REG_OFFSET(pc) - }, -}; - -/* - * Return a pointer to the register number valid in the current mode of - * the virtual CPU. - */ -unsigned long *vcpu_reg32(const struct kvm_vcpu *vcpu, u8 reg_num) -{ - unsigned long *reg_array = (unsigned long *)&vcpu->arch.ctxt.regs; - unsigned long mode = *vcpu_cpsr(vcpu) & PSR_AA32_MODE_MASK; - - switch (mode) { - case PSR_AA32_MODE_USR ... PSR_AA32_MODE_SVC: - mode &= ~PSR_MODE32_BIT; /* 0 ... 3 */ - break; - - case PSR_AA32_MODE_ABT: - mode = 4; - break; - - case PSR_AA32_MODE_UND: - mode = 5; - break; - - case PSR_AA32_MODE_SYS: - mode = 0; /* SYS maps to USR */ - break; - - default: - BUG(); - } - - return reg_array + vcpu_reg_offsets[mode][reg_num]; -} - -/* - * Return the SPSR for the current mode of the virtual CPU. - */ -static int vcpu_spsr32_mode(const struct kvm_vcpu *vcpu) -{ - unsigned long mode = *vcpu_cpsr(vcpu) & PSR_AA32_MODE_MASK; - switch (mode) { - case PSR_AA32_MODE_SVC: return KVM_SPSR_SVC; - case PSR_AA32_MODE_ABT: return KVM_SPSR_ABT; - case PSR_AA32_MODE_UND: return KVM_SPSR_UND; - case PSR_AA32_MODE_IRQ: return KVM_SPSR_IRQ; - case PSR_AA32_MODE_FIQ: return KVM_SPSR_FIQ; - default: BUG(); - } -} - -unsigned long vcpu_read_spsr32(const struct kvm_vcpu *vcpu) -{ - int spsr_idx = vcpu_spsr32_mode(vcpu); - - if (!vcpu->arch.sysregs_loaded_on_cpu) { - switch (spsr_idx) { - case KVM_SPSR_SVC: - return __vcpu_sys_reg(vcpu, SPSR_EL1); - case KVM_SPSR_ABT: - return vcpu->arch.ctxt.spsr_abt; - case KVM_SPSR_UND: - return vcpu->arch.ctxt.spsr_und; - case KVM_SPSR_IRQ: - return vcpu->arch.ctxt.spsr_irq; - case KVM_SPSR_FIQ: - return vcpu->arch.ctxt.spsr_fiq; - } - } - - switch (spsr_idx) { - case KVM_SPSR_SVC: - return read_sysreg_el1(SYS_SPSR); - case KVM_SPSR_ABT: - return read_sysreg(spsr_abt); - case KVM_SPSR_UND: - return read_sysreg(spsr_und); - case KVM_SPSR_IRQ: - return read_sysreg(spsr_irq); - case KVM_SPSR_FIQ: - return read_sysreg(spsr_fiq); - default: - BUG(); - } -} - -void vcpu_write_spsr32(struct kvm_vcpu *vcpu, unsigned long v) -{ - int spsr_idx = vcpu_spsr32_mode(vcpu); - - if (!vcpu->arch.sysregs_loaded_on_cpu) { - switch (spsr_idx) { - case KVM_SPSR_SVC: - __vcpu_sys_reg(vcpu, SPSR_EL1) = v; - break; - case KVM_SPSR_ABT: - vcpu->arch.ctxt.spsr_abt = v; - break; - case KVM_SPSR_UND: - vcpu->arch.ctxt.spsr_und = v; - break; - case KVM_SPSR_IRQ: - vcpu->arch.ctxt.spsr_irq = v; - break; - case KVM_SPSR_FIQ: - vcpu->arch.ctxt.spsr_fiq = v; - break; - } - - return; - } - - switch (spsr_idx) { - case KVM_SPSR_SVC: - write_sysreg_el1(v, SYS_SPSR); - break; - case KVM_SPSR_ABT: - write_sysreg(v, spsr_abt); - break; - case KVM_SPSR_UND: - write_sysreg(v, spsr_und); - break; - case KVM_SPSR_IRQ: - write_sysreg(v, spsr_irq); - break; - case KVM_SPSR_FIQ: - write_sysreg(v, spsr_fiq); - break; - } -} diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c index f32490229a4c..47f3f035f3ea 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -25,7 +25,6 @@ #include <asm/ptrace.h> #include <asm/kvm_arm.h> #include <asm/kvm_asm.h> -#include <asm/kvm_coproc.h> #include <asm/kvm_emulate.h> #include <asm/kvm_mmu.h> #include <asm/virt.h> @@ -42,58 +41,6 @@ static u32 kvm_ipa_limit; #define VCPU_RESET_PSTATE_SVC (PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | \ PSR_AA32_I_BIT | PSR_AA32_F_BIT) -static bool system_has_full_ptr_auth(void) -{ - return system_supports_address_auth() && system_supports_generic_auth(); -} - -/** - * kvm_arch_vm_ioctl_check_extension - * - * We currently assume that the number of HW registers is uniform - * across all CPUs (see cpuinfo_sanity_check). - */ -int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long ext) -{ - int r; - - switch (ext) { - case KVM_CAP_ARM_EL1_32BIT: - r = cpus_have_const_cap(ARM64_HAS_32BIT_EL1); - break; - case KVM_CAP_GUEST_DEBUG_HW_BPS: - r = get_num_brps(); - break; - case KVM_CAP_GUEST_DEBUG_HW_WPS: - r = get_num_wrps(); - break; - case KVM_CAP_ARM_PMU_V3: - r = kvm_arm_support_pmu_v3(); - break; - case KVM_CAP_ARM_INJECT_SERROR_ESR: - r = cpus_have_const_cap(ARM64_HAS_RAS_EXTN); - break; - case KVM_CAP_SET_GUEST_DEBUG: - case KVM_CAP_VCPU_ATTRIBUTES: - r = 1; - break; - case KVM_CAP_ARM_VM_IPA_SIZE: - r = kvm_ipa_limit; - break; - case KVM_CAP_ARM_SVE: - r = system_supports_sve(); - break; - case KVM_CAP_ARM_PTRAUTH_ADDRESS: - case KVM_CAP_ARM_PTRAUTH_GENERIC: - r = system_has_full_ptr_auth(); - break; - default: - r = 0; - } - - return r; -} - unsigned int kvm_sve_max_vl; int kvm_arm_init_sve(void) @@ -286,6 +233,10 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) pstate = VCPU_RESET_PSTATE_EL1; } + if (kvm_vcpu_has_pmu(vcpu) && !kvm_arm_support_pmu_v3()) { + ret = -EINVAL; + goto out; + } break; } diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index c1fac9836af1..7c4f79532406 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -20,7 +20,6 @@ #include <asm/debug-monitors.h> #include <asm/esr.h> #include <asm/kvm_arm.h> -#include <asm/kvm_coproc.h> #include <asm/kvm_emulate.h> #include <asm/kvm_hyp.h> #include <asm/kvm_mmu.h> @@ -44,6 +43,10 @@ * 64bit interface. */ +#define reg_to_encoding(x) \ + sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \ + (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2) + static bool read_from_write_only(struct kvm_vcpu *vcpu, struct sys_reg_params *params, const struct sys_reg_desc *r) @@ -64,87 +67,6 @@ static bool write_to_read_only(struct kvm_vcpu *vcpu, return false; } -static bool __vcpu_read_sys_reg_from_cpu(int reg, u64 *val) -{ - /* - * System registers listed in the switch are not saved on every - * exit from the guest but are only saved on vcpu_put. - * - * Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but - * should never be listed below, because the guest cannot modify its - * own MPIDR_EL1 and MPIDR_EL1 is accessed for VCPU A from VCPU B's - * thread when emulating cross-VCPU communication. - */ - switch (reg) { - case CSSELR_EL1: *val = read_sysreg_s(SYS_CSSELR_EL1); break; - case SCTLR_EL1: *val = read_sysreg_s(SYS_SCTLR_EL12); break; - case CPACR_EL1: *val = read_sysreg_s(SYS_CPACR_EL12); break; - case TTBR0_EL1: *val = read_sysreg_s(SYS_TTBR0_EL12); break; - case TTBR1_EL1: *val = read_sysreg_s(SYS_TTBR1_EL12); break; - case TCR_EL1: *val = read_sysreg_s(SYS_TCR_EL12); break; - case ESR_EL1: *val = read_sysreg_s(SYS_ESR_EL12); break; - case AFSR0_EL1: *val = read_sysreg_s(SYS_AFSR0_EL12); break; - case AFSR1_EL1: *val = read_sysreg_s(SYS_AFSR1_EL12); break; - case FAR_EL1: *val = read_sysreg_s(SYS_FAR_EL12); break; - case MAIR_EL1: *val = read_sysreg_s(SYS_MAIR_EL12); break; - case VBAR_EL1: *val = read_sysreg_s(SYS_VBAR_EL12); break; - case CONTEXTIDR_EL1: *val = read_sysreg_s(SYS_CONTEXTIDR_EL12);break; - case TPIDR_EL0: *val = read_sysreg_s(SYS_TPIDR_EL0); break; - case TPIDRRO_EL0: *val = read_sysreg_s(SYS_TPIDRRO_EL0); break; - case TPIDR_EL1: *val = read_sysreg_s(SYS_TPIDR_EL1); break; - case AMAIR_EL1: *val = read_sysreg_s(SYS_AMAIR_EL12); break; - case CNTKCTL_EL1: *val = read_sysreg_s(SYS_CNTKCTL_EL12); break; - case ELR_EL1: *val = read_sysreg_s(SYS_ELR_EL12); break; - case PAR_EL1: *val = read_sysreg_par(); break; - case DACR32_EL2: *val = read_sysreg_s(SYS_DACR32_EL2); break; - case IFSR32_EL2: *val = read_sysreg_s(SYS_IFSR32_EL2); break; - case DBGVCR32_EL2: *val = read_sysreg_s(SYS_DBGVCR32_EL2); break; - default: return false; - } - - return true; -} - -static bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg) -{ - /* - * System registers listed in the switch are not restored on every - * entry to the guest but are only restored on vcpu_load. - * - * Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but - * should never be listed below, because the MPIDR should only be set - * once, before running the VCPU, and never changed later. - */ - switch (reg) { - case CSSELR_EL1: write_sysreg_s(val, SYS_CSSELR_EL1); break; - case SCTLR_EL1: write_sysreg_s(val, SYS_SCTLR_EL12); break; - case CPACR_EL1: write_sysreg_s(val, SYS_CPACR_EL12); break; - case TTBR0_EL1: write_sysreg_s(val, SYS_TTBR0_EL12); break; - case TTBR1_EL1: write_sysreg_s(val, SYS_TTBR1_EL12); break; - case TCR_EL1: write_sysreg_s(val, SYS_TCR_EL12); break; - case ESR_EL1: write_sysreg_s(val, SYS_ESR_EL12); break; - case AFSR0_EL1: write_sysreg_s(val, SYS_AFSR0_EL12); break; - case AFSR1_EL1: write_sysreg_s(val, SYS_AFSR1_EL12); break; - case FAR_EL1: write_sysreg_s(val, SYS_FAR_EL12); break; - case MAIR_EL1: write_sysreg_s(val, SYS_MAIR_EL12); break; - case VBAR_EL1: write_sysreg_s(val, SYS_VBAR_EL12); break; - case CONTEXTIDR_EL1: write_sysreg_s(val, SYS_CONTEXTIDR_EL12);break; - case TPIDR_EL0: write_sysreg_s(val, SYS_TPIDR_EL0); break; - case TPIDRRO_EL0: write_sysreg_s(val, SYS_TPIDRRO_EL0); break; - case TPIDR_EL1: write_sysreg_s(val, SYS_TPIDR_EL1); break; - case AMAIR_EL1: write_sysreg_s(val, SYS_AMAIR_EL12); break; - case CNTKCTL_EL1: write_sysreg_s(val, SYS_CNTKCTL_EL12); break; - case ELR_EL1: write_sysreg_s(val, SYS_ELR_EL12); break; - case PAR_EL1: write_sysreg_s(val, SYS_PAR_EL1); break; - case DACR32_EL2: write_sysreg_s(val, SYS_DACR32_EL2); break; - case IFSR32_EL2: write_sysreg_s(val, SYS_IFSR32_EL2); break; - case DBGVCR32_EL2: write_sysreg_s(val, SYS_DBGVCR32_EL2); break; - default: return false; - } - - return true; -} - u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg) { u64 val = 0x8badf00d8badf00d; @@ -169,7 +91,7 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg) static u32 cache_levels; /* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */ -#define CSSELR_MAX 12 +#define CSSELR_MAX 14 /* Which cache CCSIDR represents depends on CSSELR value. */ static u32 get_ccsidr(u32 csselr) @@ -209,6 +131,24 @@ static bool access_dcsw(struct kvm_vcpu *vcpu, return true; } +static void get_access_mask(const struct sys_reg_desc *r, u64 *mask, u64 *shift) +{ + switch (r->aarch32_map) { + case AA32_LO: + *mask = GENMASK_ULL(31, 0); + *shift = 0; + break; + case AA32_HI: + *mask = GENMASK_ULL(63, 32); + *shift = 32; + break; + default: + *mask = GENMASK_ULL(63, 0); + *shift = 0; + break; + } +} + /* * Generic accessor for VM registers. Only called as long as HCR_TVM * is set. If the guest enables the MMU, we stop trapping the VM @@ -219,26 +159,21 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { bool was_enabled = vcpu_has_cache_enabled(vcpu); - u64 val; - int reg = r->reg; + u64 val, mask, shift; BUG_ON(!p->is_write); - /* See the 32bit mapping in kvm_host.h */ - if (p->is_aarch32) - reg = r->reg / 2; + get_access_mask(r, &mask, &shift); - if (!p->is_aarch32 || !p->is_32bit) { - val = p->regval; + if (~mask) { + val = vcpu_read_sys_reg(vcpu, r->reg); + val &= ~mask; } else { - val = vcpu_read_sys_reg(vcpu, reg); - if (r->reg % 2) - val = (p->regval << 32) | (u64)lower_32_bits(val); - else - val = ((u64)upper_32_bits(val) << 32) | - lower_32_bits(p->regval); + val = 0; } - vcpu_write_sys_reg(vcpu, val, reg); + + val |= (p->regval & (mask >> shift)) << shift; + vcpu_write_sys_reg(vcpu, val, r->reg); kvm_toggle_cache(vcpu, was_enabled); return true; @@ -248,17 +183,13 @@ static bool access_actlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { + u64 mask, shift; + if (p->is_write) return ignore_write(vcpu, p); - p->regval = vcpu_read_sys_reg(vcpu, ACTLR_EL1); - - if (p->is_aarch32) { - if (r->Op2 & 2) - p->regval = upper_32_bits(p->regval); - else - p->regval = lower_32_bits(p->regval); - } + get_access_mask(r, &mask, &shift); + p->regval = (vcpu_read_sys_reg(vcpu, r->reg) & mask) >> shift; return true; } @@ -285,7 +216,7 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu, * equivalent to ICC_SGI0R_EL1, as there is no "alternative" secure * group. */ - if (p->is_aarch32) { + if (p->Op0 == 0) { /* AArch32 */ switch (p->Op1) { default: /* Keep GCC quiet */ case 0: /* ICC_SGI1R */ @@ -296,7 +227,7 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu, g1 = false; break; } - } else { + } else { /* AArch64 */ switch (p->Op2) { default: /* Keep GCC quiet */ case 5: /* ICC_SGI1R_EL1 */ @@ -346,8 +277,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); - u32 sr = sys_reg((u32)r->Op0, (u32)r->Op1, - (u32)r->CRn, (u32)r->CRm, (u32)r->Op2); + u32 sr = reg_to_encoding(r); if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) { kvm_inject_undefined(vcpu); @@ -438,26 +368,30 @@ static bool trap_debug_regs(struct kvm_vcpu *vcpu, */ static void reg_to_dbg(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *rd, u64 *dbg_reg) { - u64 val = p->regval; + u64 mask, shift, val; - if (p->is_32bit) { - val &= 0xffffffffUL; - val |= ((*dbg_reg >> 32) << 32); - } + get_access_mask(rd, &mask, &shift); + val = *dbg_reg; + val &= ~mask; + val |= (p->regval & (mask >> shift)) << shift; *dbg_reg = val; + vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY; } static void dbg_to_reg(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *rd, u64 *dbg_reg) { - p->regval = *dbg_reg; - if (p->is_32bit) - p->regval &= 0xffffffffUL; + u64 mask, shift; + + get_access_mask(rd, &mask, &shift); + p->regval = (*dbg_reg & mask) >> shift; } static bool trap_bvr(struct kvm_vcpu *vcpu, @@ -467,9 +401,9 @@ static bool trap_bvr(struct kvm_vcpu *vcpu, u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg]; if (p->is_write) - reg_to_dbg(vcpu, p, dbg_reg); + reg_to_dbg(vcpu, p, rd, dbg_reg); else - dbg_to_reg(vcpu, p, dbg_reg); + dbg_to_reg(vcpu, p, rd, dbg_reg); trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg); @@ -509,9 +443,9 @@ static bool trap_bcr(struct kvm_vcpu *vcpu, u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg]; if (p->is_write) - reg_to_dbg(vcpu, p, dbg_reg); + reg_to_dbg(vcpu, p, rd, dbg_reg); else - dbg_to_reg(vcpu, p, dbg_reg); + dbg_to_reg(vcpu, p, rd, dbg_reg); trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg); @@ -552,9 +486,9 @@ static bool trap_wvr(struct kvm_vcpu *vcpu, u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg]; if (p->is_write) - reg_to_dbg(vcpu, p, dbg_reg); + reg_to_dbg(vcpu, p, rd, dbg_reg); else - dbg_to_reg(vcpu, p, dbg_reg); + dbg_to_reg(vcpu, p, rd, dbg_reg); trace_trap_reg(__func__, rd->reg, p->is_write, vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg]); @@ -595,9 +529,9 @@ static bool trap_wcr(struct kvm_vcpu *vcpu, u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg]; if (p->is_write) - reg_to_dbg(vcpu, p, dbg_reg); + reg_to_dbg(vcpu, p, rd, dbg_reg); else - dbg_to_reg(vcpu, p, dbg_reg); + dbg_to_reg(vcpu, p, rd, dbg_reg); trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg); @@ -659,10 +593,23 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) vcpu_write_sys_reg(vcpu, (1ULL << 31) | mpidr, MPIDR_EL1); } +static unsigned int pmu_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + if (kvm_vcpu_has_pmu(vcpu)) + return 0; + + return REG_HIDDEN; +} + static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { u64 pmcr, val; + /* No PMU available, PMCR_EL0 may UNDEF... */ + if (!kvm_arm_support_pmu_v3()) + return; + pmcr = read_sysreg(pmcr_el0); /* * Writable bits of PMCR_EL0 (ARMV8_PMU_PMCR_MASK) are reset to UNKNOWN @@ -711,9 +658,6 @@ static bool access_pmcr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, { u64 val; - if (!kvm_arm_pmu_v3_ready(vcpu)) - return trap_raz_wi(vcpu, p, r); - if (pmu_access_el0_disabled(vcpu)) return false; @@ -740,9 +684,6 @@ static bool access_pmcr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, static bool access_pmselr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { - if (!kvm_arm_pmu_v3_ready(vcpu)) - return trap_raz_wi(vcpu, p, r); - if (pmu_access_event_counter_el0_disabled(vcpu)) return false; @@ -761,9 +702,6 @@ static bool access_pmceid(struct kvm_vcpu *vcpu, struct sys_reg_params *p, { u64 pmceid; - if (!kvm_arm_pmu_v3_ready(vcpu)) - return trap_raz_wi(vcpu, p, r); - BUG_ON(p->is_write); if (pmu_access_el0_disabled(vcpu)) @@ -794,10 +732,7 @@ static bool access_pmu_evcntr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { - u64 idx; - - if (!kvm_arm_pmu_v3_ready(vcpu)) - return trap_raz_wi(vcpu, p, r); + u64 idx = ~0UL; if (r->CRn == 9 && r->CRm == 13) { if (r->Op2 == 2) { @@ -813,8 +748,6 @@ static bool access_pmu_evcntr(struct kvm_vcpu *vcpu, return false; idx = ARMV8_PMU_CYCLE_IDX; - } else { - return false; } } else if (r->CRn == 0 && r->CRm == 9) { /* PMCCNTR */ @@ -828,10 +761,11 @@ static bool access_pmu_evcntr(struct kvm_vcpu *vcpu, return false; idx = ((r->CRm & 3) << 3) | (r->Op2 & 7); - } else { - return false; } + /* Catch any decoding mistake */ + WARN_ON(idx == ~0UL); + if (!pmu_counter_idx_valid(vcpu, idx)) return false; @@ -852,9 +786,6 @@ static bool access_pmu_evtyper(struct kvm_vcpu *vcpu, struct sys_reg_params *p, { u64 idx, reg; - if (!kvm_arm_pmu_v3_ready(vcpu)) - return trap_raz_wi(vcpu, p, r); - if (pmu_access_el0_disabled(vcpu)) return false; @@ -892,9 +823,6 @@ static bool access_pmcnten(struct kvm_vcpu *vcpu, struct sys_reg_params *p, { u64 val, mask; - if (!kvm_arm_pmu_v3_ready(vcpu)) - return trap_raz_wi(vcpu, p, r); - if (pmu_access_el0_disabled(vcpu)) return false; @@ -923,13 +851,8 @@ static bool access_pminten(struct kvm_vcpu *vcpu, struct sys_reg_params *p, { u64 mask = kvm_pmu_valid_counter_mask(vcpu); - if (!kvm_arm_pmu_v3_ready(vcpu)) - return trap_raz_wi(vcpu, p, r); - - if (!vcpu_mode_priv(vcpu)) { - kvm_inject_undefined(vcpu); + if (check_pmu_access_disabled(vcpu, 0)) return false; - } if (p->is_write) { u64 val = p->regval & mask; @@ -952,9 +875,6 @@ static bool access_pmovs(struct kvm_vcpu *vcpu, struct sys_reg_params *p, { u64 mask = kvm_pmu_valid_counter_mask(vcpu); - if (!kvm_arm_pmu_v3_ready(vcpu)) - return trap_raz_wi(vcpu, p, r); - if (pmu_access_el0_disabled(vcpu)) return false; @@ -977,9 +897,6 @@ static bool access_pmswinc(struct kvm_vcpu *vcpu, struct sys_reg_params *p, { u64 mask; - if (!kvm_arm_pmu_v3_ready(vcpu)) - return trap_raz_wi(vcpu, p, r); - if (!p->is_write) return read_from_write_only(vcpu, p, r); @@ -994,9 +911,6 @@ static bool access_pmswinc(struct kvm_vcpu *vcpu, struct sys_reg_params *p, static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { - if (!kvm_arm_pmu_v3_ready(vcpu)) - return trap_raz_wi(vcpu, p, r); - if (p->is_write) { if (!vcpu_mode_priv(vcpu)) { kvm_inject_undefined(vcpu); @@ -1013,10 +927,6 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, return true; } -#define reg_to_encoding(x) \ - sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \ - (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2); - /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */ #define DBG_BCR_BVR_WCR_WVR_EL1(n) \ { SYS_DESC(SYS_DBGBVRn_EL1(n)), \ @@ -1028,15 +938,18 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, { SYS_DESC(SYS_DBGWCRn_EL1(n)), \ trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr } +#define PMU_SYS_REG(r) \ + SYS_DESC(r), .reset = reset_unknown, .visibility = pmu_visibility + /* Macro to expand the PMEVCNTRn_EL0 register */ #define PMU_PMEVCNTR_EL0(n) \ - { SYS_DESC(SYS_PMEVCNTRn_EL0(n)), \ - access_pmu_evcntr, reset_unknown, (PMEVCNTR0_EL0 + n), } + { PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)), \ + .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), } /* Macro to expand the PMEVTYPERn_EL0 register */ #define PMU_PMEVTYPER_EL0(n) \ - { SYS_DESC(SYS_PMEVTYPERn_EL0(n)), \ - access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), } + { PMU_SYS_REG(SYS_PMEVTYPERn_EL0(n)), \ + .access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), } static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) @@ -1112,8 +1025,7 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu, static u64 read_id_reg(const struct kvm_vcpu *vcpu, struct sys_reg_desc const *r, bool raz) { - u32 id = sys_reg((u32)r->Op0, (u32)r->Op1, - (u32)r->CRn, (u32)r->CRm, (u32)r->Op2); + u32 id = reg_to_encoding(r); u64 val = raz ? 0 : read_sanitised_ftr_reg(id); if (id == SYS_ID_AA64PFR0_EL1) { @@ -1122,6 +1034,8 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, val &= ~(0xfUL << ID_AA64PFR0_AMU_SHIFT); val &= ~(0xfUL << ID_AA64PFR0_CSV2_SHIFT); val |= ((u64)vcpu->kvm->arch.pfr0_csv2 << ID_AA64PFR0_CSV2_SHIFT); + val &= ~(0xfUL << ID_AA64PFR0_CSV3_SHIFT); + val |= ((u64)vcpu->kvm->arch.pfr0_csv3 << ID_AA64PFR0_CSV3_SHIFT); } else if (id == SYS_ID_AA64PFR1_EL1) { val &= ~(0xfUL << ID_AA64PFR1_MTE_SHIFT); } else if (id == SYS_ID_AA64ISAR1_EL1 && !vcpu_has_ptrauth(vcpu)) { @@ -1130,10 +1044,15 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, (0xfUL << ID_AA64ISAR1_GPA_SHIFT) | (0xfUL << ID_AA64ISAR1_GPI_SHIFT)); } else if (id == SYS_ID_AA64DFR0_EL1) { + u64 cap = 0; + /* Limit guests to PMUv3 for ARMv8.1 */ + if (kvm_vcpu_has_pmu(vcpu)) + cap = ID_AA64DFR0_PMUVER_8_1; + val = cpuid_feature_cap_perfmon_field(val, ID_AA64DFR0_PMUVER_SHIFT, - ID_AA64DFR0_PMUVER_8_1); + cap); } else if (id == SYS_ID_DFR0_EL1) { /* Limit guests to PMUv3 for ARMv8.1 */ val = cpuid_feature_cap_perfmon_field(val, @@ -1147,8 +1066,7 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, static unsigned int id_visibility(const struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { - u32 id = sys_reg((u32)r->Op0, (u32)r->Op1, - (u32)r->CRn, (u32)r->CRm, (u32)r->Op2); + u32 id = reg_to_encoding(r); switch (id) { case SYS_ID_AA64ZFR0_EL1: @@ -1209,9 +1127,9 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg, void __user *uaddr) { const u64 id = sys_reg_to_index(rd); + u8 csv2, csv3; int err; u64 val; - u8 csv2; err = reg_from_user(&val, uaddr, id); if (err) @@ -1227,13 +1145,21 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, (csv2 && arm64_get_spectre_v2_state() != SPECTRE_UNAFFECTED)) return -EINVAL; - /* We can only differ with CSV2, and anything else is an error */ + /* Same thing for CSV3 */ + csv3 = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR0_CSV3_SHIFT); + if (csv3 > 1 || + (csv3 && arm64_get_meltdown_state() != SPECTRE_UNAFFECTED)) + return -EINVAL; + + /* We can only differ with CSV[23], and anything else is an error */ val ^= read_id_reg(vcpu, rd, false); - val &= ~(0xFUL << ID_AA64PFR0_CSV2_SHIFT); + val &= ~((0xFUL << ID_AA64PFR0_CSV2_SHIFT) | + (0xFUL << ID_AA64PFR0_CSV3_SHIFT)); if (val) return -EINVAL; vcpu->kvm->arch.pfr0_csv2 = csv2; + vcpu->kvm->arch.pfr0_csv3 = csv3 ; return 0; } @@ -1327,10 +1253,6 @@ static bool access_csselr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, { int reg = r->reg; - /* See the 32bit mapping in kvm_host.h */ - if (p->is_aarch32) - reg = r->reg / 2; - if (p->is_write) vcpu_write_sys_reg(vcpu, p->regval, reg); else @@ -1567,8 +1489,10 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 }, { SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 }, - { SYS_DESC(SYS_PMINTENSET_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 }, - { SYS_DESC(SYS_PMINTENCLR_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 }, + { PMU_SYS_REG(SYS_PMINTENSET_EL1), + .access = access_pminten, .reg = PMINTENSET_EL1 }, + { PMU_SYS_REG(SYS_PMINTENCLR_EL1), + .access = access_pminten, .reg = PMINTENSET_EL1 }, { SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 }, { SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 }, @@ -1607,23 +1531,36 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 }, { SYS_DESC(SYS_CTR_EL0), access_ctr }, - { SYS_DESC(SYS_PMCR_EL0), access_pmcr, reset_pmcr, PMCR_EL0 }, - { SYS_DESC(SYS_PMCNTENSET_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 }, - { SYS_DESC(SYS_PMCNTENCLR_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 }, - { SYS_DESC(SYS_PMOVSCLR_EL0), access_pmovs, reset_unknown, PMOVSSET_EL0 }, - { SYS_DESC(SYS_PMSWINC_EL0), access_pmswinc, reset_unknown, PMSWINC_EL0 }, - { SYS_DESC(SYS_PMSELR_EL0), access_pmselr, reset_unknown, PMSELR_EL0 }, - { SYS_DESC(SYS_PMCEID0_EL0), access_pmceid }, - { SYS_DESC(SYS_PMCEID1_EL0), access_pmceid }, - { SYS_DESC(SYS_PMCCNTR_EL0), access_pmu_evcntr, reset_unknown, PMCCNTR_EL0 }, - { SYS_DESC(SYS_PMXEVTYPER_EL0), access_pmu_evtyper }, - { SYS_DESC(SYS_PMXEVCNTR_EL0), access_pmu_evcntr }, + { PMU_SYS_REG(SYS_PMCR_EL0), .access = access_pmcr, + .reset = reset_pmcr, .reg = PMCR_EL0 }, + { PMU_SYS_REG(SYS_PMCNTENSET_EL0), + .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, + { PMU_SYS_REG(SYS_PMCNTENCLR_EL0), + .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, + { PMU_SYS_REG(SYS_PMOVSCLR_EL0), + .access = access_pmovs, .reg = PMOVSSET_EL0 }, + { PMU_SYS_REG(SYS_PMSWINC_EL0), + .access = access_pmswinc, .reg = PMSWINC_EL0 }, + { PMU_SYS_REG(SYS_PMSELR_EL0), + .access = access_pmselr, .reg = PMSELR_EL0 }, + { PMU_SYS_REG(SYS_PMCEID0_EL0), + .access = access_pmceid, .reset = NULL }, + { PMU_SYS_REG(SYS_PMCEID1_EL0), + .access = access_pmceid, .reset = NULL }, + { PMU_SYS_REG(SYS_PMCCNTR_EL0), + .access = access_pmu_evcntr, .reg = PMCCNTR_EL0 }, + { PMU_SYS_REG(SYS_PMXEVTYPER_EL0), + .access = access_pmu_evtyper, .reset = NULL }, + { PMU_SYS_REG(SYS_PMXEVCNTR_EL0), + .access = access_pmu_evcntr, .reset = NULL }, /* * PMUSERENR_EL0 resets as unknown in 64bit mode while it resets as zero * in 32bit mode. Here we choose to reset it as zero for consistency. */ - { SYS_DESC(SYS_PMUSERENR_EL0), access_pmuserenr, reset_val, PMUSERENR_EL0, 0 }, - { SYS_DESC(SYS_PMOVSSET_EL0), access_pmovs, reset_unknown, PMOVSSET_EL0 }, + { PMU_SYS_REG(SYS_PMUSERENR_EL0), .access = access_pmuserenr, + .reset = reset_val, .reg = PMUSERENR_EL0, .val = 0 }, + { PMU_SYS_REG(SYS_PMOVSSET_EL0), + .access = access_pmovs, .reg = PMOVSSET_EL0 }, { SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 }, { SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 }, @@ -1775,7 +1712,8 @@ static const struct sys_reg_desc sys_reg_descs[] = { * PMCCFILTR_EL0 resets as unknown in 64bit mode while it resets as zero * in 32bit mode. Here we choose to reset it as zero for consistency. */ - { SYS_DESC(SYS_PMCCFILTR_EL0), access_pmu_evtyper, reset_val, PMCCFILTR_EL0, 0 }, + { PMU_SYS_REG(SYS_PMCCFILTR_EL0), .access = access_pmu_evtyper, + .reset = reset_val, .reg = PMCCFILTR_EL0, .val = 0 }, { SYS_DESC(SYS_DACR32_EL2), NULL, reset_unknown, DACR32_EL2 }, { SYS_DESC(SYS_IFSR32_EL2), NULL, reset_unknown, IFSR32_EL2 }, @@ -1801,66 +1739,27 @@ static bool trap_dbgidr(struct kvm_vcpu *vcpu, } } -static bool trap_debug32(struct kvm_vcpu *vcpu, - struct sys_reg_params *p, - const struct sys_reg_desc *r) -{ - if (p->is_write) { - vcpu_cp14(vcpu, r->reg) = p->regval; - vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY; - } else { - p->regval = vcpu_cp14(vcpu, r->reg); - } - - return true; -} - -/* AArch32 debug register mappings +/* + * AArch32 debug register mappings * * AArch32 DBGBVRn is mapped to DBGBVRn_EL1[31:0] * AArch32 DBGBXVRn is mapped to DBGBVRn_EL1[63:32] * - * All control registers and watchpoint value registers are mapped to - * the lower 32 bits of their AArch64 equivalents. We share the trap - * handlers with the above AArch64 code which checks what mode the - * system is in. + * None of the other registers share their location, so treat them as + * if they were 64bit. */ - -static bool trap_xvr(struct kvm_vcpu *vcpu, - struct sys_reg_params *p, - const struct sys_reg_desc *rd) -{ - u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg]; - - if (p->is_write) { - u64 val = *dbg_reg; - - val &= 0xffffffffUL; - val |= p->regval << 32; - *dbg_reg = val; - - vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY; - } else { - p->regval = *dbg_reg >> 32; - } - - trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg); - - return true; -} - -#define DBG_BCR_BVR_WCR_WVR(n) \ - /* DBGBVRn */ \ - { Op1( 0), CRn( 0), CRm((n)), Op2( 4), trap_bvr, NULL, n }, \ - /* DBGBCRn */ \ - { Op1( 0), CRn( 0), CRm((n)), Op2( 5), trap_bcr, NULL, n }, \ - /* DBGWVRn */ \ - { Op1( 0), CRn( 0), CRm((n)), Op2( 6), trap_wvr, NULL, n }, \ - /* DBGWCRn */ \ +#define DBG_BCR_BVR_WCR_WVR(n) \ + /* DBGBVRn */ \ + { AA32(LO), Op1( 0), CRn( 0), CRm((n)), Op2( 4), trap_bvr, NULL, n }, \ + /* DBGBCRn */ \ + { Op1( 0), CRn( 0), CRm((n)), Op2( 5), trap_bcr, NULL, n }, \ + /* DBGWVRn */ \ + { Op1( 0), CRn( 0), CRm((n)), Op2( 6), trap_wvr, NULL, n }, \ + /* DBGWCRn */ \ { Op1( 0), CRn( 0), CRm((n)), Op2( 7), trap_wcr, NULL, n } -#define DBGBXVR(n) \ - { Op1( 0), CRn( 1), CRm((n)), Op2( 1), trap_xvr, NULL, n } +#define DBGBXVR(n) \ + { AA32(HI), Op1( 0), CRn( 1), CRm((n)), Op2( 1), trap_bvr, NULL, n } /* * Trapped cp14 registers. We generally ignore most of the external @@ -1878,9 +1777,9 @@ static const struct sys_reg_desc cp14_regs[] = { { Op1( 0), CRn( 0), CRm( 1), Op2( 0), trap_raz_wi }, DBG_BCR_BVR_WCR_WVR(1), /* DBGDCCINT */ - { Op1( 0), CRn( 0), CRm( 2), Op2( 0), trap_debug32, NULL, cp14_DBGDCCINT }, + { Op1( 0), CRn( 0), CRm( 2), Op2( 0), trap_debug_regs, NULL, MDCCINT_EL1 }, /* DBGDSCRext */ - { Op1( 0), CRn( 0), CRm( 2), Op2( 2), trap_debug32, NULL, cp14_DBGDSCRext }, + { Op1( 0), CRn( 0), CRm( 2), Op2( 2), trap_debug_regs, NULL, MDSCR_EL1 }, DBG_BCR_BVR_WCR_WVR(2), /* DBGDTR[RT]Xint */ { Op1( 0), CRn( 0), CRm( 3), Op2( 0), trap_raz_wi }, @@ -1895,7 +1794,7 @@ static const struct sys_reg_desc cp14_regs[] = { { Op1( 0), CRn( 0), CRm( 6), Op2( 2), trap_raz_wi }, DBG_BCR_BVR_WCR_WVR(6), /* DBGVCR */ - { Op1( 0), CRn( 0), CRm( 7), Op2( 0), trap_debug32, NULL, cp14_DBGVCR }, + { Op1( 0), CRn( 0), CRm( 7), Op2( 0), trap_debug_regs, NULL, DBGVCR32_EL2 }, DBG_BCR_BVR_WCR_WVR(7), DBG_BCR_BVR_WCR_WVR(8), DBG_BCR_BVR_WCR_WVR(9), @@ -1981,19 +1880,29 @@ static const struct sys_reg_desc cp14_64_regs[] = { */ static const struct sys_reg_desc cp15_regs[] = { { Op1( 0), CRn( 0), CRm( 0), Op2( 1), access_ctr }, - { Op1( 0), CRn( 1), CRm( 0), Op2( 0), access_vm_reg, NULL, c1_SCTLR }, - { Op1( 0), CRn( 1), CRm( 0), Op2( 1), access_actlr }, - { Op1( 0), CRn( 1), CRm( 0), Op2( 3), access_actlr }, - { Op1( 0), CRn( 2), CRm( 0), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, - { Op1( 0), CRn( 2), CRm( 0), Op2( 1), access_vm_reg, NULL, c2_TTBR1 }, - { Op1( 0), CRn( 2), CRm( 0), Op2( 2), access_vm_reg, NULL, c2_TTBCR }, - { Op1( 0), CRn( 3), CRm( 0), Op2( 0), access_vm_reg, NULL, c3_DACR }, - { Op1( 0), CRn( 5), CRm( 0), Op2( 0), access_vm_reg, NULL, c5_DFSR }, - { Op1( 0), CRn( 5), CRm( 0), Op2( 1), access_vm_reg, NULL, c5_IFSR }, - { Op1( 0), CRn( 5), CRm( 1), Op2( 0), access_vm_reg, NULL, c5_ADFSR }, - { Op1( 0), CRn( 5), CRm( 1), Op2( 1), access_vm_reg, NULL, c5_AIFSR }, - { Op1( 0), CRn( 6), CRm( 0), Op2( 0), access_vm_reg, NULL, c6_DFAR }, - { Op1( 0), CRn( 6), CRm( 0), Op2( 2), access_vm_reg, NULL, c6_IFAR }, + { Op1( 0), CRn( 1), CRm( 0), Op2( 0), access_vm_reg, NULL, SCTLR_EL1 }, + /* ACTLR */ + { AA32(LO), Op1( 0), CRn( 1), CRm( 0), Op2( 1), access_actlr, NULL, ACTLR_EL1 }, + /* ACTLR2 */ + { AA32(HI), Op1( 0), CRn( 1), CRm( 0), Op2( 3), access_actlr, NULL, ACTLR_EL1 }, + { Op1( 0), CRn( 2), CRm( 0), Op2( 0), access_vm_reg, NULL, TTBR0_EL1 }, + { Op1( 0), CRn( 2), CRm( 0), Op2( 1), access_vm_reg, NULL, TTBR1_EL1 }, + /* TTBCR */ + { AA32(LO), Op1( 0), CRn( 2), CRm( 0), Op2( 2), access_vm_reg, NULL, TCR_EL1 }, + /* TTBCR2 */ + { AA32(HI), Op1( 0), CRn( 2), CRm( 0), Op2( 3), access_vm_reg, NULL, TCR_EL1 }, + { Op1( 0), CRn( 3), CRm( 0), Op2( 0), access_vm_reg, NULL, DACR32_EL2 }, + /* DFSR */ + { Op1( 0), CRn( 5), CRm( 0), Op2( 0), access_vm_reg, NULL, ESR_EL1 }, + { Op1( 0), CRn( 5), CRm( 0), Op2( 1), access_vm_reg, NULL, IFSR32_EL2 }, + /* ADFSR */ + { Op1( 0), CRn( 5), CRm( 1), Op2( 0), access_vm_reg, NULL, AFSR0_EL1 }, + /* AIFSR */ + { Op1( 0), CRn( 5), CRm( 1), Op2( 1), access_vm_reg, NULL, AFSR1_EL1 }, + /* DFAR */ + { AA32(LO), Op1( 0), CRn( 6), CRm( 0), Op2( 0), access_vm_reg, NULL, FAR_EL1 }, + /* IFAR */ + { AA32(HI), Op1( 0), CRn( 6), CRm( 0), Op2( 2), access_vm_reg, NULL, FAR_EL1 }, /* * DC{C,I,CI}SW operations: @@ -2019,15 +1928,19 @@ static const struct sys_reg_desc cp15_regs[] = { { Op1( 0), CRn( 9), CRm(14), Op2( 2), access_pminten }, { Op1( 0), CRn( 9), CRm(14), Op2( 3), access_pmovs }, - { Op1( 0), CRn(10), CRm( 2), Op2( 0), access_vm_reg, NULL, c10_PRRR }, - { Op1( 0), CRn(10), CRm( 2), Op2( 1), access_vm_reg, NULL, c10_NMRR }, - { Op1( 0), CRn(10), CRm( 3), Op2( 0), access_vm_reg, NULL, c10_AMAIR0 }, - { Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, c10_AMAIR1 }, + /* PRRR/MAIR0 */ + { AA32(LO), Op1( 0), CRn(10), CRm( 2), Op2( 0), access_vm_reg, NULL, MAIR_EL1 }, + /* NMRR/MAIR1 */ + { AA32(HI), Op1( 0), CRn(10), CRm( 2), Op2( 1), access_vm_reg, NULL, MAIR_EL1 }, + /* AMAIR0 */ + { AA32(LO), Op1( 0), CRn(10), CRm( 3), Op2( 0), access_vm_reg, NULL, AMAIR_EL1 }, + /* AMAIR1 */ + { AA32(HI), Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, AMAIR_EL1 }, /* ICC_SRE */ { Op1( 0), CRn(12), CRm(12), Op2( 5), access_gic_sre }, - { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID }, + { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, CONTEXTIDR_EL1 }, /* Arch Tmers */ { SYS_DESC(SYS_AARCH32_CNTP_TVAL), access_arch_timer }, @@ -2102,14 +2015,14 @@ static const struct sys_reg_desc cp15_regs[] = { { Op1(1), CRn( 0), CRm( 0), Op2(0), access_ccsidr }, { Op1(1), CRn( 0), CRm( 0), Op2(1), access_clidr }, - { Op1(2), CRn( 0), CRm( 0), Op2(0), access_csselr, NULL, c0_CSSELR }, + { Op1(2), CRn( 0), CRm( 0), Op2(0), access_csselr, NULL, CSSELR_EL1 }, }; static const struct sys_reg_desc cp15_64_regs[] = { - { Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, + { Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, TTBR0_EL1 }, { Op1( 0), CRn( 0), CRm( 9), Op2( 0), access_pmu_evcntr }, { Op1( 0), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_SGI1R */ - { Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR1 }, + { Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, TTBR1_EL1 }, { Op1( 1), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_ASGI1R */ { Op1( 2), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_SGI0R */ { SYS_DESC(SYS_AARCH32_CNTP_CVAL), access_arch_timer }, @@ -2180,7 +2093,7 @@ static void perform_access(struct kvm_vcpu *vcpu, /* Skip instruction if instructed so */ if (likely(r->access(vcpu, params, r))) - kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); + kvm_incr_pc(vcpu); } /* @@ -2253,8 +2166,6 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, int Rt = kvm_vcpu_sys_get_rt(vcpu); int Rt2 = (esr >> 10) & 0x1f; - params.is_aarch32 = true; - params.is_32bit = false; params.CRm = (esr >> 1) & 0xf; params.is_write = ((esr & 1) == 0); @@ -2304,8 +2215,6 @@ static int kvm_handle_cp_32(struct kvm_vcpu *vcpu, u32 esr = kvm_vcpu_get_esr(vcpu); int Rt = kvm_vcpu_sys_get_rt(vcpu); - params.is_aarch32 = true; - params.is_32bit = true; params.CRm = (esr >> 1) & 0xf; params.regval = vcpu_get_reg(vcpu, Rt); params.is_write = ((esr & 1) == 0); @@ -2399,8 +2308,6 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu) trace_kvm_handle_sys_reg(esr); - params.is_aarch32 = false; - params.is_32bit = false; params.Op0 = (esr >> 20) & 3; params.Op1 = (esr >> 14) & 0x7; params.CRn = (esr >> 10) & 0xf; diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h index 0f95964339b1..9d0621417c2a 100644 --- a/arch/arm64/kvm/sys_regs.h +++ b/arch/arm64/kvm/sys_regs.h @@ -19,14 +19,18 @@ struct sys_reg_params { u8 Op2; u64 regval; bool is_write; - bool is_aarch32; - bool is_32bit; /* Only valid if is_aarch32 is true */ }; struct sys_reg_desc { /* Sysreg string for debug */ const char *name; + enum { + AA32_ZEROHIGH, + AA32_LO, + AA32_HI, + } aarch32_map; + /* MRS/MSR instruction which accesses it. */ u8 Op0; u8 Op1; @@ -153,6 +157,7 @@ const struct sys_reg_desc *find_reg_by_id(u64 id, const struct sys_reg_desc table[], unsigned int num); +#define AA32(_x) .aarch32_map = AA32_##_x #define Op0(_x) .Op0 = _x #define Op1(_x) .Op1 = _x #define CRn(_x) .CRn = _x diff --git a/arch/arm64/kvm/va_layout.c b/arch/arm64/kvm/va_layout.c index e0404bcab019..70fcd6a12fe1 100644 --- a/arch/arm64/kvm/va_layout.c +++ b/arch/arm64/kvm/va_layout.c @@ -11,6 +11,7 @@ #include <asm/debug-monitors.h> #include <asm/insn.h> #include <asm/kvm_mmu.h> +#include <asm/memory.h> /* * The LSB of the HYP VA tag @@ -23,6 +24,29 @@ static u64 tag_val; static u64 va_mask; /* + * Compute HYP VA by using the same computation as kern_hyp_va(). + */ +static u64 __early_kern_hyp_va(u64 addr) +{ + addr &= va_mask; + addr |= tag_val << tag_lsb; + return addr; +} + +/* + * Store a hyp VA <-> PA offset into a EL2-owned variable. + */ +static void init_hyp_physvirt_offset(void) +{ + u64 kern_va, hyp_va; + + /* Compute the offset from the hyp VA and PA of a random symbol. */ + kern_va = (u64)lm_alias(__hyp_text_start); + hyp_va = __early_kern_hyp_va(kern_va); + hyp_physvirt_offset = (s64)__pa(kern_va) - (s64)hyp_va; +} + +/* * We want to generate a hyp VA with the following format (with V == * vabits_actual): * @@ -53,6 +77,8 @@ __init void kvm_compute_layout(void) tag_val |= get_random_long() & GENMASK_ULL(vabits_actual - 2, tag_lsb); } tag_val >>= tag_lsb; + + init_hyp_physvirt_offset(); } static u32 compute_instruction(int n, u32 rd, u32 rn) @@ -131,28 +157,21 @@ void __init kvm_update_va_mask(struct alt_instr *alt, } } -void *__kvm_bp_vect_base; -int __kvm_harden_el2_vector_slot; - void kvm_patch_vector_branch(struct alt_instr *alt, __le32 *origptr, __le32 *updptr, int nr_inst) { u64 addr; u32 insn; - BUG_ON(nr_inst != 5); + BUG_ON(nr_inst != 4); - if (has_vhe() || !cpus_have_const_cap(ARM64_HARDEN_EL2_VECTORS)) { - WARN_ON_ONCE(cpus_have_const_cap(ARM64_HARDEN_EL2_VECTORS)); + if (!cpus_have_const_cap(ARM64_SPECTRE_V3A) || WARN_ON_ONCE(has_vhe())) return; - } /* * Compute HYP VA by using the same computation as kern_hyp_va() */ - addr = (uintptr_t)kvm_ksym_ref(__kvm_hyp_vector); - addr &= va_mask; - addr |= tag_val << tag_lsb; + addr = __early_kern_hyp_va((u64)kvm_ksym_ref(__kvm_hyp_vector)); /* Use PC[10:7] to branch to the same vector in KVM */ addr |= ((u64)origptr & GENMASK_ULL(10, 7)); @@ -163,15 +182,6 @@ void kvm_patch_vector_branch(struct alt_instr *alt, */ addr += KVM_VECTOR_PREAMBLE; - /* stp x0, x1, [sp, #-16]! */ - insn = aarch64_insn_gen_load_store_pair(AARCH64_INSN_REG_0, - AARCH64_INSN_REG_1, - AARCH64_INSN_REG_SP, - -16, - AARCH64_INSN_VARIANT_64BIT, - AARCH64_INSN_LDST_STORE_PAIR_PRE_INDEX); - *updptr++ = cpu_to_le32(insn); - /* movz x0, #(addr & 0xffff) */ insn = aarch64_insn_gen_movewide(AARCH64_INSN_REG_0, (u16)addr, @@ -201,3 +211,58 @@ void kvm_patch_vector_branch(struct alt_instr *alt, AARCH64_INSN_BRANCH_NOLINK); *updptr++ = cpu_to_le32(insn); } + +static void generate_mov_q(u64 val, __le32 *origptr, __le32 *updptr, int nr_inst) +{ + u32 insn, oinsn, rd; + + BUG_ON(nr_inst != 4); + + /* Compute target register */ + oinsn = le32_to_cpu(*origptr); + rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, oinsn); + + /* movz rd, #(val & 0xffff) */ + insn = aarch64_insn_gen_movewide(rd, + (u16)val, + 0, + AARCH64_INSN_VARIANT_64BIT, + AARCH64_INSN_MOVEWIDE_ZERO); + *updptr++ = cpu_to_le32(insn); + + /* movk rd, #((val >> 16) & 0xffff), lsl #16 */ + insn = aarch64_insn_gen_movewide(rd, + (u16)(val >> 16), + 16, + AARCH64_INSN_VARIANT_64BIT, + AARCH64_INSN_MOVEWIDE_KEEP); + *updptr++ = cpu_to_le32(insn); + + /* movk rd, #((val >> 32) & 0xffff), lsl #32 */ + insn = aarch64_insn_gen_movewide(rd, + (u16)(val >> 32), + 32, + AARCH64_INSN_VARIANT_64BIT, + AARCH64_INSN_MOVEWIDE_KEEP); + *updptr++ = cpu_to_le32(insn); + + /* movk rd, #((val >> 48) & 0xffff), lsl #48 */ + insn = aarch64_insn_gen_movewide(rd, + (u16)(val >> 48), + 48, + AARCH64_INSN_VARIANT_64BIT, + AARCH64_INSN_MOVEWIDE_KEEP); + *updptr++ = cpu_to_le32(insn); +} + +void kvm_update_kimg_phys_offset(struct alt_instr *alt, + __le32 *origptr, __le32 *updptr, int nr_inst) +{ + generate_mov_q(kimage_voffset + PHYS_OFFSET, origptr, updptr, nr_inst); +} + +void kvm_get_kimage_voffset(struct alt_instr *alt, + __le32 *origptr, __le32 *updptr, int nr_inst) +{ + generate_mov_q(kimage_voffset, origptr, updptr, nr_inst); +} diff --git a/arch/arm64/kvm/vgic-sys-reg-v3.c b/arch/arm64/kvm/vgic-sys-reg-v3.c index 2f92bdcb1188..07d5271e9f05 100644 --- a/arch/arm64/kvm/vgic-sys-reg-v3.c +++ b/arch/arm64/kvm/vgic-sys-reg-v3.c @@ -268,8 +268,6 @@ int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id, params.regval = *reg; params.is_write = is_write; - params.is_aarch32 = false; - params.is_32bit = false; if (find_reg_by_id(sysreg, ¶ms, gic_v3_icc_reg_descs, ARRAY_SIZE(gic_v3_icc_reg_descs))) @@ -288,8 +286,6 @@ int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id, if (is_write) params.regval = *reg; params.is_write = is_write; - params.is_aarch32 = false; - params.is_32bit = false; r = find_reg_by_id(sysreg, ¶ms, gic_v3_icc_reg_descs, ARRAY_SIZE(gic_v3_icc_reg_descs)); diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 32e32d67a127..052917deb149 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -419,7 +419,8 @@ int vgic_lazy_init(struct kvm *kvm) * Map the MMIO regions depending on the VGIC model exposed to the guest * called on the first VCPU run. * Also map the virtual CPU interface into the VM. - * v2/v3 derivatives call vgic_init if not already done. + * v2 calls vgic_init() if not already done. + * v3 and derivatives return an error if the VGIC is not initialized. * vgic_ready() returns true if this function has succeeded. * @kvm: kvm struct pointer */ @@ -428,7 +429,13 @@ int kvm_vgic_map_resources(struct kvm *kvm) struct vgic_dist *dist = &kvm->arch.vgic; int ret = 0; + if (likely(vgic_ready(kvm))) + return 0; + mutex_lock(&kvm->lock); + if (vgic_ready(kvm)) + goto out; + if (!irqchip_in_kernel(kvm)) goto out; @@ -439,6 +446,8 @@ int kvm_vgic_map_resources(struct kvm *kvm) if (ret) __kvm_vgic_destroy(kvm); + else + dist->ready = true; out: mutex_unlock(&kvm->lock); diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c index ebf53a4e1296..11934c2af2f4 100644 --- a/arch/arm64/kvm/vgic/vgic-v2.c +++ b/arch/arm64/kvm/vgic/vgic-v2.c @@ -306,20 +306,15 @@ int vgic_v2_map_resources(struct kvm *kvm) struct vgic_dist *dist = &kvm->arch.vgic; int ret = 0; - if (vgic_ready(kvm)) - goto out; - if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base) || IS_VGIC_ADDR_UNDEF(dist->vgic_cpu_base)) { kvm_err("Need to set vgic cpu and dist addresses first\n"); - ret = -ENXIO; - goto out; + return -ENXIO; } if (!vgic_v2_check_base(dist->vgic_dist_base, dist->vgic_cpu_base)) { kvm_err("VGIC CPU and dist frames overlap\n"); - ret = -EINVAL; - goto out; + return -EINVAL; } /* @@ -329,13 +324,13 @@ int vgic_v2_map_resources(struct kvm *kvm) ret = vgic_init(kvm); if (ret) { kvm_err("Unable to initialize VGIC dynamic data structures\n"); - goto out; + return ret; } ret = vgic_register_dist_iodev(kvm, dist->vgic_dist_base, VGIC_V2); if (ret) { kvm_err("Unable to register VGIC MMIO regions\n"); - goto out; + return ret; } if (!static_branch_unlikely(&vgic_v2_cpuif_trap)) { @@ -344,14 +339,11 @@ int vgic_v2_map_resources(struct kvm *kvm) KVM_VGIC_V2_CPU_SIZE, true); if (ret) { kvm_err("Unable to remap VGIC CPU to VCPU\n"); - goto out; + return ret; } } - dist->ready = true; - -out: - return ret; + return 0; } DEFINE_STATIC_KEY_FALSE(vgic_v2_cpuif_trap); diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index 9cdf39a94a63..52915b342351 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -500,29 +500,23 @@ int vgic_v3_map_resources(struct kvm *kvm) int ret = 0; int c; - if (vgic_ready(kvm)) - goto out; - kvm_for_each_vcpu(c, vcpu, kvm) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; if (IS_VGIC_ADDR_UNDEF(vgic_cpu->rd_iodev.base_addr)) { kvm_debug("vcpu %d redistributor base not set\n", c); - ret = -ENXIO; - goto out; + return -ENXIO; } } if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base)) { kvm_err("Need to set vgic distributor addresses first\n"); - ret = -ENXIO; - goto out; + return -ENXIO; } if (!vgic_v3_check_base(kvm)) { kvm_err("VGIC redist and dist frames overlap\n"); - ret = -EINVAL; - goto out; + return -EINVAL; } /* @@ -530,22 +524,19 @@ int vgic_v3_map_resources(struct kvm *kvm) * the VGIC before we need to use it. */ if (!vgic_initialized(kvm)) { - ret = -EBUSY; - goto out; + return -EBUSY; } ret = vgic_register_dist_iodev(kvm, dist->vgic_dist_base, VGIC_V3); if (ret) { kvm_err("Unable to register VGICv3 dist MMIO regions\n"); - goto out; + return ret; } if (kvm_vgic_global_state.has_gicv4_1) vgic_v4_configure_vsgis(kvm); - dist->ready = true; -out: - return ret; + return 0; } DEFINE_STATIC_KEY_FALSE(vgic_v3_cpuif_trap); diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c index b5fa73c9fd35..66508b03094f 100644 --- a/arch/arm64/kvm/vgic/vgic-v4.c +++ b/arch/arm64/kvm/vgic/vgic-v4.c @@ -353,6 +353,18 @@ int vgic_v4_load(struct kvm_vcpu *vcpu) return err; } +void vgic_v4_commit(struct kvm_vcpu *vcpu) +{ + struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe; + + /* + * No need to wait for the vPE to be ready across a shallow guest + * exit, as only a vcpu_put will invalidate it. + */ + if (!vpe->ready) + its_commit_vpe(vpe); +} + static struct vgic_its *vgic_get_its(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *irq_entry) { diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c index c3643b7f101b..1c597c9885fa 100644 --- a/arch/arm64/kvm/vgic/vgic.c +++ b/arch/arm64/kvm/vgic/vgic.c @@ -915,6 +915,9 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) if (can_access_vgic_from_kernel()) vgic_restore_state(vcpu); + + if (vgic_supports_direct_msis(vcpu->kvm)) + vgic_v4_commit(vcpu); } void kvm_vgic_load(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/lib/mte.S b/arch/arm64/lib/mte.S index 351537c12f36..9e1a12e10053 100644 --- a/arch/arm64/lib/mte.S +++ b/arch/arm64/lib/mte.S @@ -149,3 +149,19 @@ SYM_FUNC_START(mte_restore_page_tags) ret SYM_FUNC_END(mte_restore_page_tags) + +/* + * Assign allocation tags for a region of memory based on the pointer tag + * x0 - source pointer + * x1 - size + * + * Note: The address must be non-NULL and MTE_GRANULE_SIZE aligned and + * size must be non-zero and MTE_GRANULE_SIZE aligned. + */ +SYM_FUNC_START(mte_assign_mem_tag_range) +1: stg x0, [x0] + add x0, x0, #MTE_GRANULE_SIZE + subs x1, x1, #MTE_GRANULE_SIZE + b.gt 1b + ret +SYM_FUNC_END(mte_assign_mem_tag_range) diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c index 70a71f38b6a9..b5447e53cd73 100644 --- a/arch/arm64/mm/copypage.c +++ b/arch/arm64/mm/copypage.c @@ -23,6 +23,15 @@ void copy_highpage(struct page *to, struct page *from) if (system_supports_mte() && test_bit(PG_mte_tagged, &from->flags)) { set_bit(PG_mte_tagged, &to->flags); + page_kasan_tag_reset(to); + /* + * We need smp_wmb() in between setting the flags and clearing the + * tags because if another thread reads page->flags and builds a + * tagged address out of it, there is an actual dependency to the + * memory access, but on the current thread we do not guarantee that + * the new page->flags are visible before the tags were updated. + */ + smp_wmb(); mte_copy_page_tags(kto, kfrom); } } diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 2848952b178d..35d75c60e2b8 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -14,6 +14,7 @@ #include <linux/mm.h> #include <linux/hardirq.h> #include <linux/init.h> +#include <linux/kasan.h> #include <linux/kprobes.h> #include <linux/uaccess.h> #include <linux/page-flags.h> @@ -33,6 +34,7 @@ #include <asm/debug-monitors.h> #include <asm/esr.h> #include <asm/kprobes.h> +#include <asm/mte.h> #include <asm/processor.h> #include <asm/sysreg.h> #include <asm/system_misc.h> @@ -296,6 +298,57 @@ static void die_kernel_fault(const char *msg, unsigned long addr, do_exit(SIGKILL); } +#ifdef CONFIG_KASAN_HW_TAGS +static void report_tag_fault(unsigned long addr, unsigned int esr, + struct pt_regs *regs) +{ + bool is_write = ((esr & ESR_ELx_WNR) >> ESR_ELx_WNR_SHIFT) != 0; + + /* + * SAS bits aren't set for all faults reported in EL1, so we can't + * find out access size. + */ + kasan_report(addr, 0, is_write, regs->pc); +} +#else +/* Tag faults aren't enabled without CONFIG_KASAN_HW_TAGS. */ +static inline void report_tag_fault(unsigned long addr, unsigned int esr, + struct pt_regs *regs) { } +#endif + +static void do_tag_recovery(unsigned long addr, unsigned int esr, + struct pt_regs *regs) +{ + static bool reported; + + if (!READ_ONCE(reported)) { + report_tag_fault(addr, esr, regs); + WRITE_ONCE(reported, true); + } + + /* + * Disable MTE Tag Checking on the local CPU for the current EL. + * It will be done lazily on the other CPUs when they will hit a + * tag fault. + */ + sysreg_clear_set(sctlr_el1, SCTLR_ELx_TCF_MASK, SCTLR_ELx_TCF_NONE); + isb(); +} + +static bool is_el1_mte_sync_tag_check_fault(unsigned int esr) +{ + unsigned int ec = ESR_ELx_EC(esr); + unsigned int fsc = esr & ESR_ELx_FSC; + + if (ec != ESR_ELx_EC_DABT_CUR) + return false; + + if (fsc == ESR_ELx_FSC_MTE) + return true; + + return false; +} + static void __do_kernel_fault(unsigned long addr, unsigned int esr, struct pt_regs *regs) { @@ -312,6 +365,12 @@ static void __do_kernel_fault(unsigned long addr, unsigned int esr, "Ignoring spurious kernel translation fault at virtual address %016lx\n", addr)) return; + if (is_el1_mte_sync_tag_check_fault(esr)) { + do_tag_recovery(addr, esr, regs); + + return; + } + if (is_el1_permission_fault(addr, esr, regs)) { if (esr & ESR_ELx_WNR) msg = "write to read-only memory"; @@ -650,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr, struct pt_regs *regs) { /* - * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN for tag - * check faults. Mask them out now so that userspace doesn't see them. + * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN + * for tag check faults. Set them to corresponding bits in the untagged + * address. */ - far &= (1UL << 60) - 1; + far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK); do_bad_area(far, esr, regs); return 0; } diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 69d4251ee079..709d98fea90c 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -53,13 +53,13 @@ s64 memstart_addr __ro_after_init = -1; EXPORT_SYMBOL(memstart_addr); /* - * We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of - * memory as some devices, namely the Raspberry Pi 4, have peripherals with - * this limited view of the memory. ZONE_DMA32 will cover the rest of the 32 - * bit addressable memory area. + * If the corresponding config options are enabled, we create both ZONE_DMA + * and ZONE_DMA32. By default ZONE_DMA covers the 32-bit addressable memory + * unless restricted on specific platforms (e.g. 30-bit on Raspberry Pi 4). + * In such case, ZONE_DMA32 covers the rest of the 32-bit addressable memory, + * otherwise it is empty. */ phys_addr_t arm64_dma_phys_limit __ro_after_init; -static phys_addr_t arm64_dma32_phys_limit __ro_after_init; #ifdef CONFIG_KEXEC_CORE /* @@ -84,7 +84,7 @@ static void __init reserve_crashkernel(void) if (crash_base == 0) { /* Current arm64 boot protocol requires 2MB alignment */ - crash_base = memblock_find_in_range(0, arm64_dma32_phys_limit, + crash_base = memblock_find_in_range(0, arm64_dma_phys_limit, crash_size, SZ_2M); if (crash_base == 0) { pr_warn("cannot allocate crashkernel (size:0x%llx)\n", @@ -196,6 +196,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) unsigned long max_zone_pfns[MAX_NR_ZONES] = {0}; unsigned int __maybe_unused acpi_zone_dma_bits; unsigned int __maybe_unused dt_zone_dma_bits; + phys_addr_t __maybe_unused dma32_phys_limit = max_zone_phys(32); #ifdef CONFIG_ZONE_DMA acpi_zone_dma_bits = fls64(acpi_iort_dma_get_max_cpu_address()); @@ -205,8 +206,12 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit); #endif #ifdef CONFIG_ZONE_DMA32 - max_zone_pfns[ZONE_DMA32] = PFN_DOWN(arm64_dma32_phys_limit); + max_zone_pfns[ZONE_DMA32] = PFN_DOWN(dma32_phys_limit); + if (!arm64_dma_phys_limit) + arm64_dma_phys_limit = dma32_phys_limit; #endif + if (!arm64_dma_phys_limit) + arm64_dma_phys_limit = PHYS_MASK + 1; max_zone_pfns[ZONE_NORMAL] = max; free_area_init(max_zone_pfns); @@ -295,6 +300,9 @@ void __init arm64_memblock_init(void) memstart_addr = round_down(memblock_start_of_DRAM(), ARM64_MEMSTART_ALIGN); + if ((memblock_end_of_DRAM() - memstart_addr) > linear_region_size) + pr_warn("Memory doesn't fit in the linear mapping, VA_BITS too small\n"); + /* * Remove the memory that we will not be able to cover with the * linear mapping. Take care not to clip the kernel which may be @@ -391,16 +399,9 @@ void __init arm64_memblock_init(void) early_init_fdt_scan_reserved_mem(); - if (IS_ENABLED(CONFIG_ZONE_DMA32)) - arm64_dma32_phys_limit = max_zone_phys(32); - else - arm64_dma32_phys_limit = PHYS_MASK + 1; - reserve_elfcorehdr(); high_memory = __va(memblock_end_of_DRAM() - 1) + 1; - - dma_contiguous_reserve(arm64_dma32_phys_limit); } void __init bootmem_init(void) @@ -436,6 +437,11 @@ void __init bootmem_init(void) zone_sizes_init(min, max); /* + * Reserve the CMA area after arm64_dma_phys_limit was initialised. + */ + dma_contiguous_reserve(arm64_dma_phys_limit); + + /* * request_standard_resources() depends on crashkernel's memory being * reserved, so do it here. */ @@ -452,7 +458,7 @@ void __init bootmem_init(void) void __init mem_init(void) { if (swiotlb_force == SWIOTLB_FORCE || - max_pfn > PFN_DOWN(arm64_dma_phys_limit ? : arm64_dma32_phys_limit)) + max_pfn > PFN_DOWN(arm64_dma_phys_limit)) swiotlb_init(1); else swiotlb_force = SWIOTLB_NO_FORCE; diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c index b24e43d20667..d8e66c78440e 100644 --- a/arch/arm64/mm/kasan_init.c +++ b/arch/arm64/mm/kasan_init.c @@ -21,6 +21,8 @@ #include <asm/sections.h> #include <asm/tlbflush.h> +#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) + static pgd_t tmp_pg_dir[PTRS_PER_PGD] __initdata __aligned(PGD_SIZE); /* @@ -208,7 +210,7 @@ static void __init clear_pgds(unsigned long start, set_pgd(pgd_offset_k(start), __pgd(0)); } -void __init kasan_init(void) +static void __init kasan_init_shadow(void) { u64 kimg_shadow_start, kimg_shadow_end; u64 mod_shadow_start, mod_shadow_end; @@ -269,8 +271,21 @@ void __init kasan_init(void) memset(kasan_early_shadow_page, KASAN_SHADOW_INIT, PAGE_SIZE); cpu_replace_ttbr1(lm_alias(swapper_pg_dir)); +} - /* At this point kasan is fully initialized. Enable error messages */ +static void __init kasan_init_depth(void) +{ init_task.kasan_depth = 0; +} + +void __init kasan_init(void) +{ + kasan_init_shadow(); + kasan_init_depth(); +#if defined(CONFIG_KASAN_GENERIC) + /* CONFIG_KASAN_SW_TAGS also requires kasan_init_sw_tags(). */ pr_info("KernelAddressSanitizer initialized\n"); +#endif } + +#endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c index 3028bacbc4e9..07937b49cb88 100644 --- a/arch/arm64/mm/mmap.c +++ b/arch/arm64/mm/mmap.c @@ -47,24 +47,3 @@ int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) { return !(((pfn << PAGE_SHIFT) + size) & ~PHYS_MASK); } - -#ifdef CONFIG_STRICT_DEVMEM - -#include <linux/ioport.h> - -/* - * devmem_is_allowed() checks to see if /dev/mem access to a certain address - * is valid. The argument is a physical page number. We mimic x86 here by - * disallowing access to system RAM as well as device-exclusive MMIO regions. - * This effectively disable read()/write() on /dev/mem. - */ -int devmem_is_allowed(unsigned long pfn) -{ - if (iomem_is_exclusive(pfn << PAGE_SHIFT)) - return 0; - if (!page_is_ram(pfn)) - return 1; - return 0; -} - -#endif diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c index c52c1847079c..7c4ef56265ee 100644 --- a/arch/arm64/mm/mteswap.c +++ b/arch/arm64/mm/mteswap.c @@ -53,6 +53,15 @@ bool mte_restore_tags(swp_entry_t entry, struct page *page) if (!tags) return false; + page_kasan_tag_reset(page); + /* + * We need smp_wmb() in between setting the flags and clearing the + * tags because if another thread reads page->flags and builds a + * tagged address out of it, there is an actual dependency to the + * memory access, but on the current thread we do not guarantee that + * the new page->flags are visible before the tags were updated. + */ + smp_wmb(); mte_restore_page_tags(page_address(page), tags); return true; diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index a0831bf8a018..1f7ee8c8b7b8 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -40,9 +40,15 @@ #define TCR_CACHE_FLAGS TCR_IRGN_WBWA | TCR_ORGN_WBWA #ifdef CONFIG_KASAN_SW_TAGS -#define TCR_KASAN_FLAGS TCR_TBI1 | TCR_TBID1 +#define TCR_KASAN_SW_FLAGS TCR_TBI1 | TCR_TBID1 #else -#define TCR_KASAN_FLAGS 0 +#define TCR_KASAN_SW_FLAGS 0 +#endif + +#ifdef CONFIG_KASAN_HW_TAGS +#define TCR_KASAN_HW_FLAGS SYS_TCR_EL1_TCMA1 | TCR_TBI1 | TCR_TBID1 +#else +#define TCR_KASAN_HW_FLAGS 0 #endif /* @@ -427,6 +433,10 @@ SYM_FUNC_START(__cpu_setup) */ mov_q x5, MAIR_EL1_SET #ifdef CONFIG_ARM64_MTE + mte_tcr .req x20 + + mov mte_tcr, #0 + /* * Update MAIR_EL1, GCR_EL1 and TFSR*_EL1 if MTE is supported * (ID_AA64PFR1_EL1[11:8] > 1). @@ -447,6 +457,9 @@ SYM_FUNC_START(__cpu_setup) /* clear any pending tag check faults in TFSR*_EL1 */ msr_s SYS_TFSR_EL1, xzr msr_s SYS_TFSRE0_EL1, xzr + + /* set the TCR_EL1 bits */ + mov_q mte_tcr, TCR_KASAN_HW_FLAGS 1: #endif msr mair_el1, x5 @@ -456,7 +469,11 @@ SYM_FUNC_START(__cpu_setup) */ mov_q x10, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \ TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \ - TCR_TBI0 | TCR_A1 | TCR_KASAN_FLAGS + TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS +#ifdef CONFIG_ARM64_MTE + orr x10, x10, mte_tcr + .unreq mte_tcr +#endif tcr_clear_errata_bits x10, x9, x5 #ifdef CONFIG_ARM64_VA_BITS_52 diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c index 807dc634bbd2..04137a8f3d2d 100644 --- a/arch/arm64/mm/ptdump.c +++ b/arch/arm64/mm/ptdump.c @@ -29,7 +29,7 @@ enum address_markers_idx { PAGE_OFFSET_NR = 0, PAGE_END_NR, -#ifdef CONFIG_KASAN +#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) KASAN_START_NR, #endif }; @@ -37,7 +37,7 @@ enum address_markers_idx { static struct addr_marker address_markers[] = { { PAGE_OFFSET, "Linear Mapping start" }, { 0 /* PAGE_END */, "Linear Mapping end" }, -#ifdef CONFIG_KASAN +#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) { 0 /* KASAN_SHADOW_START */, "Kasan shadow start" }, { KASAN_SHADOW_END, "Kasan shadow end" }, #endif @@ -383,7 +383,7 @@ void ptdump_check_wx(void) static int ptdump_init(void) { address_markers[PAGE_END_NR].start_address = PAGE_END; -#ifdef CONFIG_KASAN +#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) address_markers[KASAN_START_NR].start_address = KASAN_SHADOW_START; #endif ptdump_initialize(); diff --git a/arch/csky/include/asm/Kbuild b/arch/csky/include/asm/Kbuild index 93372255984d..cc24bb8e539f 100644 --- a/arch/csky/include/asm/Kbuild +++ b/arch/csky/include/asm/Kbuild @@ -2,7 +2,6 @@ generic-y += asm-offsets.h generic-y += gpio.h generic-y += kvm_para.h -generic-y += local64.h generic-y += qrwlock.h generic-y += user.h generic-y += vmlinux.lds.h diff --git a/arch/csky/kernel/probes/ftrace.c b/arch/csky/kernel/probes/ftrace.c index 5264763d05be..ae2b1c7b3b5c 100644 --- a/arch/csky/kernel/probes/ftrace.c +++ b/arch/csky/kernel/probes/ftrace.c @@ -11,18 +11,25 @@ int arch_check_ftrace_location(struct kprobe *p) /* Ftrace callback handler for kprobes -- called under preepmt disabed */ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, - struct ftrace_ops *ops, struct pt_regs *regs) + struct ftrace_ops *ops, struct ftrace_regs *fregs) { + int bit; bool lr_saver = false; struct kprobe *p; struct kprobe_ctlblk *kcb; + struct pt_regs *regs; - /* Preempt is disabled by ftrace */ + bit = ftrace_test_recursion_trylock(ip, parent_ip); + if (bit < 0) + return; + + regs = ftrace_get_regs(fregs); + preempt_disable_notrace(); p = get_kprobe((kprobe_opcode_t *)ip); if (!p) { p = get_kprobe((kprobe_opcode_t *)(ip - MCOUNT_INSN_SIZE)); if (unlikely(!p) || kprobe_disabled(p)) - return; + goto out; lr_saver = true; } @@ -56,6 +63,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, */ __this_cpu_write(current_kprobe, NULL); } +out: + preempt_enable_notrace(); + ftrace_test_recursion_unlock(bit); } NOKPROBE_SYMBOL(kprobe_ftrace_handler); diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild index ddf04f32b546..60ee7f0d60a8 100644 --- a/arch/h8300/include/asm/Kbuild +++ b/arch/h8300/include/asm/Kbuild @@ -2,7 +2,6 @@ generic-y += asm-offsets.h generic-y += extable.h generic-y += kvm_para.h -generic-y += local64.h generic-y += mcs_spinlock.h generic-y += parport.h generic-y += spinlock.h diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild index 373964bb177e..3ece3c93fe08 100644 --- a/arch/hexagon/include/asm/Kbuild +++ b/arch/hexagon/include/asm/Kbuild @@ -2,5 +2,4 @@ generic-y += extable.h generic-y += iomap.h generic-y += kvm_para.h -generic-y += local64.h generic-y += mcs_spinlock.h diff --git a/arch/ia64/include/asm/local64.h b/arch/ia64/include/asm/local64.h deleted file mode 100644 index 36c93b5cc239..000000000000 --- a/arch/ia64/include/asm/local64.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/local64.h> diff --git a/arch/ia64/include/asm/sparsemem.h b/arch/ia64/include/asm/sparsemem.h index dd8c166ffd7b..42ed5248fae9 100644 --- a/arch/ia64/include/asm/sparsemem.h +++ b/arch/ia64/include/asm/sparsemem.h @@ -3,6 +3,7 @@ #define _ASM_IA64_SPARSEMEM_H #ifdef CONFIG_SPARSEMEM +#include <asm/page.h> /* * SECTION_SIZE_BITS 2^N: how big each section will be * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space diff --git a/arch/ia64/kernel/syscalls/syscall.tbl b/arch/ia64/kernel/syscalls/syscall.tbl index b96ed8b8a508..bfc00f2bd437 100644 --- a/arch/ia64/kernel/syscalls/syscall.tbl +++ b/arch/ia64/kernel/syscalls/syscall.tbl @@ -361,3 +361,4 @@ 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 440 common process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 9b5acf8fb092..e76386a3479e 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -536,7 +536,7 @@ virtual_memmap_init(u64 start, u64 end, void *arg) if (map_start < map_end) memmap_init_zone((unsigned long)(map_end - map_start), - args->nid, args->zone, page_to_pfn(map_start), + args->nid, args->zone, page_to_pfn(map_start), page_to_pfn(map_end), MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); return 0; } @@ -546,7 +546,7 @@ memmap_init (unsigned long size, int nid, unsigned long zone, unsigned long start_pfn) { if (!vmem_map) { - memmap_init_zone(size, nid, zone, start_pfn, + memmap_init_zone(size, nid, zone, start_pfn, start_pfn + size, MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); } else { struct page *start; diff --git a/arch/ia64/scripts/unwcheck.py b/arch/ia64/scripts/unwcheck.py index c55276e31b6b..bfd1b671e35f 100644 --- a/arch/ia64/scripts/unwcheck.py +++ b/arch/ia64/scripts/unwcheck.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # SPDX-License-Identifier: GPL-2.0 # # Usage: unwcheck.py FILE diff --git a/arch/m68k/68000/Makefile b/arch/m68k/68000/Makefile index 4f7d4b45a46f..674541fdf5b8 100644 --- a/arch/m68k/68000/Makefile +++ b/arch/m68k/68000/Makefile @@ -10,10 +10,11 @@ # 68328, 68EZ328, 68VZ328 -obj-y += entry.o ints.o timers.o -obj-$(CONFIG_M68328) += m68328.o -obj-$(CONFIG_M68EZ328) += m68EZ328.o -obj-$(CONFIG_M68VZ328) += m68VZ328.o +obj-y += entry.o ints.o timers.o m68328.o obj-$(CONFIG_ROM) += romvec.o +obj-$(CONFIG_DRAGEN2) += dragen2.o +obj-$(CONFIG_UCSIMM) += ucsimm.o +obj-$(CONFIG_UCDIMM) += ucsimm.o + extra-y := head.o diff --git a/arch/m68k/68000/dragen2.c b/arch/m68k/68000/dragen2.c new file mode 100644 index 000000000000..584893c57c37 --- /dev/null +++ b/arch/m68k/68000/dragen2.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 1993 Hamish Macdonald + * Copyright (C) 1999 D. Jeff Dionne + * Copyright (C) 2001 Georges Menie, Ken Desmet + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <asm/machdep.h> +#include <asm/MC68VZ328.h> + +/***************************************************************************/ +/* Init Drangon Engine hardware */ +/***************************************************************************/ + +static void dragen2_reset(void) +{ + local_irq_disable(); + +#ifdef CONFIG_INIT_LCD + PBDATA |= 0x20; /* disable CCFL light */ + PKDATA |= 0x4; /* disable LCD controller */ + LCKCON = 0; +#endif + + __asm__ __volatile__( + "reset\n\t" + "moveal #0x04000000, %a0\n\t" + "moveal 0(%a0), %sp\n\t" + "moveal 4(%a0), %a0\n\t" + "jmp (%a0)" + ); +} + +void __init init_dragen2(char *command, int size) +{ + mach_reset = dragen2_reset; + +#ifdef CONFIG_DIRECT_IO_ACCESS + SCR = 0x10; /* allow user access to internal registers */ +#endif + + /* CSGB Init */ + CSGBB = 0x4000; + CSB = 0x1a1; + + /* CS8900 init */ + /* PK3: hardware sleep function pin, active low */ + PKSEL |= PK(3); /* select pin as I/O */ + PKDIR |= PK(3); /* select pin as output */ + PKDATA |= PK(3); /* set pin high */ + + /* PF5: hardware reset function pin, active high */ + PFSEL |= PF(5); /* select pin as I/O */ + PFDIR |= PF(5); /* select pin as output */ + PFDATA &= ~PF(5); /* set pin low */ + + /* cs8900 hardware reset */ + PFDATA |= PF(5); + { int i; for (i = 0; i < 32000; ++i); } + PFDATA &= ~PF(5); + + /* INT1 enable (cs8900 IRQ) */ + PDPOL &= ~PD(1); /* active high signal */ + PDIQEG &= ~PD(1); + PDIRQEN |= PD(1); /* IRQ enabled */ + +#ifdef CONFIG_INIT_LCD + /* initialize LCD controller */ + LSSA = (long) screen_bits; + LVPW = 0x14; + LXMAX = 0x140; + LYMAX = 0xef; + LRRA = 0; + LPXCD = 3; + LPICF = 0x08; + LPOLCF = 0; + LCKCON = 0x80; + PCPDEN = 0xff; + PCSEL = 0; + + /* Enable LCD controller */ + PKDIR |= 0x4; + PKSEL |= 0x4; + PKDATA &= ~0x4; + + /* Enable CCFL backlighting circuit */ + PBDIR |= 0x20; + PBSEL |= 0x20; + PBDATA &= ~0x20; + + /* contrast control register */ + PFDIR |= 0x1; + PFSEL &= ~0x1; + PWMR = 0x037F; +#endif +} diff --git a/arch/m68k/68000/m68328.c b/arch/m68k/68000/m68328.c index 419751b15ec8..eab08da058c6 100644 --- a/arch/m68k/68000/m68328.c +++ b/arch/m68k/68000/m68328.c @@ -1,10 +1,11 @@ /***************************************************************************/ /* - * m68328.c - 68328 specific config + * m68328.c - 68328/68EZ328/68VZ328 specific config * * Copyright (C) 1993 Hamish Macdonald * Copyright (C) 1999 D. Jeff Dionne + * Copyright (C) 2001 Georges Menie, Ken Desmet * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive @@ -20,18 +21,18 @@ #include <linux/kernel.h> #include <linux/rtc.h> #include <asm/machdep.h> -#include <asm/MC68328.h> -#if defined(CONFIG_PILOT) || defined(CONFIG_INIT_LCD) + +#if defined(CONFIG_INIT_LCD) && defined(CONFIG_M68VZ328) +#include "bootlogo-vz.h" +#elif defined(CONFIG_PILOT) || defined(CONFIG_INIT_LCD) #include "bootlogo.h" #endif -/***************************************************************************/ - -int m68328_hwclk(int set, struct rtc_time *t); +#include "m68328.h" /***************************************************************************/ -void m68328_reset (void) +static void m68328_reset(void) { local_irq_disable(); asm volatile ("moveal #0x10c00000, %a0;\n\t" @@ -45,12 +46,19 @@ void m68328_reset (void) void __init config_BSP(char *command, int len) { - pr_info("68328 support D. Jeff Dionne <jeff@uclinux.org>\n"); - pr_info("68328 support Kenneth Albanowski <kjahds@kjshds.com>\n"); - pr_info("68328/Pilot support Bernhard Kuhn <kuhn@lpr.e-technik.tu-muenchen.de>\n"); + mach_sched_init = hw_timer_init; + mach_hwclk = m68328_hwclk; + mach_reset = m68328_reset; - mach_hwclk = m68328_hwclk; - mach_reset = m68328_reset; +#if defined(CONFIG_PILOT) && defined(CONFIG_M68328) + mach_sched_init = NULL; +#elif defined(CONFIG_UCSIMM) + init_ucsimm(command, len); +#elif defined(CONFIG_UCDIMM) + init_ucsimm(command, len); +#elif defined(CONFIG_DRAGEN2) + init_dragen2(command, len); +#endif } /***************************************************************************/ diff --git a/arch/m68k/68000/m68328.h b/arch/m68k/68000/m68328.h new file mode 100644 index 000000000000..f6047c3168d4 --- /dev/null +++ b/arch/m68k/68000/m68328.h @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 +void init_dragen2(char *command, int size); +void init_ucsimm(char *command, int size); +struct rtc_time; +int m68328_hwclk(int set, struct rtc_time *t); diff --git a/arch/m68k/68000/m68EZ328.c b/arch/m68k/68000/m68EZ328.c deleted file mode 100644 index 05f137dc257e..000000000000 --- a/arch/m68k/68000/m68EZ328.c +++ /dev/null @@ -1,77 +0,0 @@ -/***************************************************************************/ - -/* - * m68EZ328.c - 68EZ328 specific config - * - * Copyright (C) 1993 Hamish Macdonald - * Copyright (C) 1999 D. Jeff Dionne - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -/***************************************************************************/ - -#include <linux/init.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/rtc.h> -#include <linux/pgtable.h> -#include <asm/machdep.h> -#include <asm/MC68EZ328.h> -#ifdef CONFIG_UCSIMM -#include <asm/bootstd.h> -#endif - -/***************************************************************************/ - -int m68328_hwclk(int set, struct rtc_time *t); - -/***************************************************************************/ - -void m68ez328_reset(void) -{ - local_irq_disable(); - asm volatile ( - "moveal #0x10c00000, %a0;\n" - "moveb #0, 0xFFFFF300;\n" - "moveal 0(%a0), %sp;\n" - "moveal 4(%a0), %a0;\n" - "jmp (%a0);\n" - ); -} - -/***************************************************************************/ - -unsigned char *cs8900a_hwaddr; -static int errno; - -#ifdef CONFIG_UCSIMM -_bsc0(char *, getserialnum) -_bsc1(unsigned char *, gethwaddr, int, a) -_bsc1(char *, getbenv, char *, a) -#endif - -void __init config_BSP(char *command, int len) -{ - unsigned char *p; - - pr_info("68EZ328 DragonBallEZ support (C) 1999 Rt-Control, Inc\n"); - -#ifdef CONFIG_UCSIMM - pr_info("uCsimm serial string [%s]\n", getserialnum()); - p = cs8900a_hwaddr = gethwaddr(0); - pr_info("uCsimm hwaddr %pM\n", p); - - p = getbenv("APPEND"); - if (p) strcpy(p,command); - else command[0] = 0; -#endif - - mach_sched_init = hw_timer_init; - mach_hwclk = m68328_hwclk; - mach_reset = m68ez328_reset; -} - -/***************************************************************************/ diff --git a/arch/m68k/68000/m68VZ328.c b/arch/m68k/68000/m68VZ328.c deleted file mode 100644 index ada87b23afdc..000000000000 --- a/arch/m68k/68000/m68VZ328.c +++ /dev/null @@ -1,189 +0,0 @@ -/***************************************************************************/ - -/* - * m68VZ328.c - 68VZ328 specific config - * - * Copyright (C) 1993 Hamish Macdonald - * Copyright (C) 1999 D. Jeff Dionne - * Copyright (C) 2001 Georges Menie, Ken Desmet - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -/***************************************************************************/ - -#include <linux/init.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/kd.h> -#include <linux/netdevice.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/rtc.h> -#include <linux/pgtable.h> - -#include <asm/machdep.h> -#include <asm/MC68VZ328.h> -#include <asm/bootstd.h> - -#ifdef CONFIG_INIT_LCD -#include "bootlogo-vz.h" -#endif - -/***************************************************************************/ - -int m68328_hwclk(int set, struct rtc_time *t); - -/***************************************************************************/ -/* Init Drangon Engine hardware */ -/***************************************************************************/ -#if defined(CONFIG_DRAGEN2) - -static void m68vz328_reset(void) -{ - local_irq_disable(); - -#ifdef CONFIG_INIT_LCD - PBDATA |= 0x20; /* disable CCFL light */ - PKDATA |= 0x4; /* disable LCD controller */ - LCKCON = 0; -#endif - - __asm__ __volatile__( - "reset\n\t" - "moveal #0x04000000, %a0\n\t" - "moveal 0(%a0), %sp\n\t" - "moveal 4(%a0), %a0\n\t" - "jmp (%a0)" - ); -} - -static void __init init_hardware(char *command, int size) -{ -#ifdef CONFIG_DIRECT_IO_ACCESS - SCR = 0x10; /* allow user access to internal registers */ -#endif - - /* CSGB Init */ - CSGBB = 0x4000; - CSB = 0x1a1; - - /* CS8900 init */ - /* PK3: hardware sleep function pin, active low */ - PKSEL |= PK(3); /* select pin as I/O */ - PKDIR |= PK(3); /* select pin as output */ - PKDATA |= PK(3); /* set pin high */ - - /* PF5: hardware reset function pin, active high */ - PFSEL |= PF(5); /* select pin as I/O */ - PFDIR |= PF(5); /* select pin as output */ - PFDATA &= ~PF(5); /* set pin low */ - - /* cs8900 hardware reset */ - PFDATA |= PF(5); - { int i; for (i = 0; i < 32000; ++i); } - PFDATA &= ~PF(5); - - /* INT1 enable (cs8900 IRQ) */ - PDPOL &= ~PD(1); /* active high signal */ - PDIQEG &= ~PD(1); - PDIRQEN |= PD(1); /* IRQ enabled */ - -#ifdef CONFIG_INIT_LCD - /* initialize LCD controller */ - LSSA = (long) screen_bits; - LVPW = 0x14; - LXMAX = 0x140; - LYMAX = 0xef; - LRRA = 0; - LPXCD = 3; - LPICF = 0x08; - LPOLCF = 0; - LCKCON = 0x80; - PCPDEN = 0xff; - PCSEL = 0; - - /* Enable LCD controller */ - PKDIR |= 0x4; - PKSEL |= 0x4; - PKDATA &= ~0x4; - - /* Enable CCFL backlighting circuit */ - PBDIR |= 0x20; - PBSEL |= 0x20; - PBDATA &= ~0x20; - - /* contrast control register */ - PFDIR |= 0x1; - PFSEL &= ~0x1; - PWMR = 0x037F; -#endif -} - -/***************************************************************************/ -/* Init RT-Control uCdimm hardware */ -/***************************************************************************/ -#elif defined(CONFIG_UCDIMM) - -static void m68vz328_reset(void) -{ - local_irq_disable(); - asm volatile ( - "moveal #0x10c00000, %a0;\n\t" - "moveb #0, 0xFFFFF300;\n\t" - "moveal 0(%a0), %sp;\n\t" - "moveal 4(%a0), %a0;\n\t" - "jmp (%a0);\n" - ); -} - -unsigned char *cs8900a_hwaddr; -static int errno; - -_bsc0(char *, getserialnum) -_bsc1(unsigned char *, gethwaddr, int, a) -_bsc1(char *, getbenv, char *, a) - -static void __init init_hardware(char *command, int size) -{ - char *p; - - pr_info("uCdimm serial string [%s]\n", getserialnum()); - p = cs8900a_hwaddr = gethwaddr(0); - pr_info("uCdimm hwaddr %pM\n", p); - p = getbenv("APPEND"); - if (p) - strcpy(p, command); - else - command[0] = 0; -} - -/***************************************************************************/ -#else - -static void m68vz328_reset(void) -{ -} - -static void __init init_hardware(char *command, int size) -{ -} - -/***************************************************************************/ -#endif -/***************************************************************************/ - -void __init config_BSP(char *command, int size) -{ - pr_info("68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n"); - - init_hardware(command, size); - - mach_sched_init = hw_timer_init; - mach_hwclk = m68328_hwclk; - mach_reset = m68vz328_reset; -} - -/***************************************************************************/ diff --git a/arch/m68k/68000/ucsimm.c b/arch/m68k/68000/ucsimm.c new file mode 100644 index 000000000000..7c6cbf643712 --- /dev/null +++ b/arch/m68k/68000/ucsimm.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 1993 Hamish Macdonald + * Copyright (C) 1999 D. Jeff Dionne + * Copyright (C) 2001 Georges Menie, Ken Desmet + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <asm/bootstd.h> +#include <asm/machdep.h> +#include <asm/MC68VZ328.h> + + +#include "m68328.h" + +unsigned char *cs8900a_hwaddr; +static int errno; + +_bsc0(char *, getserialnum) +_bsc1(unsigned char *, gethwaddr, int, a) +_bsc1(char *, getbenv, char *, a) + +void __init init_ucsimm(char *command, int size) +{ + char *p; + + pr_info("uCsimm/uCdimm serial string [%s]\n", getserialnum()); + p = cs8900a_hwaddr = gethwaddr(0); + pr_info("uCsimm/uCdimm hwaddr %pM\n", p); + p = getbenv("APPEND"); + if (p) + strcpy(p, command); + else + command[0] = 0; +} diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index 7246aa50298e..f4d23977d2a5 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu @@ -36,7 +36,7 @@ endchoice if M68KCLASSIC config M68000 - bool "MC68000" + bool depends on !MMU select CPU_HAS_NO_BITFIELDS select CPU_HAS_NO_MULDIV64 @@ -103,7 +103,7 @@ config M68060 processor, say Y. Otherwise, say N. config M68328 - bool "MC68328" + bool depends on !MMU select LEGACY_TIMER_TICK select M68000 @@ -111,7 +111,7 @@ config M68328 Motorola 68328 processor support. config M68EZ328 - bool "MC68EZ328" + bool depends on !MMU select LEGACY_TIMER_TICK select M68000 @@ -119,7 +119,7 @@ config M68EZ328 Motorola 68EX328 processor support. config M68VZ328 - bool "MC68VZ328" + bool depends on !MMU select LEGACY_TIMER_TICK select M68000 diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine index cf6961d4e657..4d59ec2f5b8d 100644 --- a/arch/m68k/Kconfig.machine +++ b/arch/m68k/Kconfig.machine @@ -145,14 +145,13 @@ config SUN3 If you don't want to compile a kernel exclusively for a Sun 3, say N. -endif # M68KCLASSIC - config PILOT bool config PILOT3 bool "Pilot 1000/5000, PalmPilot Personal/Pro, or PalmIII support" - depends on M68328 + depends on !MMU + select M68328 select PILOT help Support for the Palm Pilot 1000/5000, Personal/Pro and PalmIII. @@ -165,19 +164,22 @@ config XCOPILOT_BUGS config UCSIMM bool "uCsimm module support" - depends on M68EZ328 + depends on !MMU + select M68EZ328 help Support for the Arcturus Networks uCsimm module. config UCDIMM bool "uDsimm module support" - depends on M68VZ328 + depends on !MMU + select M68VZ328 help Support for the Arcturus Networks uDsimm module. config DRAGEN2 bool "DragenEngine II board support" - depends on M68VZ328 + depends on !MMU + select M68VZ328 help Support for the DragenEngine II board. @@ -200,6 +202,8 @@ config MEMORY_RESERVE help Reserve certain memory regions on 68x328 based boards. +endif # M68KCLASSIC + config ARN5206 bool "Arnewsh 5206 board support" depends on M5206 diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index 1bff55aa2d54..0dbf9c5c6fae 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild @@ -2,6 +2,5 @@ generated-y += syscall_table.h generic-y += extable.h generic-y += kvm_para.h -generic-y += local64.h generic-y += mcs_spinlock.h generic-y += spinlock.h diff --git a/arch/m68k/kernel/setup_no.c b/arch/m68k/kernel/setup_no.c index e377b4219528..d1b7988efc91 100644 --- a/arch/m68k/kernel/setup_no.c +++ b/arch/m68k/kernel/setup_no.c @@ -106,8 +106,16 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_UCDIMM pr_info("uCdimm by Lineo, Inc. <www.lineo.com>\n"); #endif +#ifdef CONFIG_M68328 + pr_info("68328 support D. Jeff Dionne <jeff@uclinux.org>\n"); + pr_info("68328 support Kenneth Albanowski <kjahds@kjshds.com>\n"); +#endif +#ifdef CONFIG_M68EZ328 + pr_info("68EZ328 DragonBallEZ support (C) 1999 Rt-Control, Inc\n"); +#endif #ifdef CONFIG_M68VZ328 pr_info("M68VZ328 support by Evan Stawnyczy <e@lineo.ca>\n"); + pr_info("68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n"); #endif #ifdef CONFIG_COLDFIRE pr_info("COLDFIRE port done by Greg Ungerer, gerg@snapgear.com\n"); @@ -121,6 +129,7 @@ void __init setup_arch(char **cmdline_p) pr_info("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n"); #if defined( CONFIG_PILOT ) && defined( CONFIG_M68328 ) + pr_info("68328/Pilot support Bernhard Kuhn <kuhn@lpr.e-technik.tu-muenchen.de>\n"); pr_info("TRG SuperPilot FLASH card support <info@trgnet.com>\n"); #endif #if defined( CONFIG_PILOT ) && defined( CONFIG_M68EZ328 ) diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl index 625fb6d32842..7fe4e45c864c 100644 --- a/arch/m68k/kernel/syscalls/syscall.tbl +++ b/arch/m68k/kernel/syscalls/syscall.tbl @@ -440,3 +440,4 @@ 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 440 common process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 diff --git a/arch/m68k/kernel/vmlinux-nommu.lds b/arch/m68k/kernel/vmlinux-nommu.lds index 396e126a4258..387f334e87d3 100644 --- a/arch/m68k/kernel/vmlinux-nommu.lds +++ b/arch/m68k/kernel/vmlinux-nommu.lds @@ -81,7 +81,7 @@ SECTIONS { __init_end = .; } - BSS_SECTION(0, 0, 0) + BSS_SECTION(4, 0, 4) _end = .; diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild index 63bce836b9f1..29b0e557aa7c 100644 --- a/arch/microblaze/include/asm/Kbuild +++ b/arch/microblaze/include/asm/Kbuild @@ -2,7 +2,6 @@ generated-y += syscall_table.h generic-y += extable.h generic-y += kvm_para.h -generic-y += local64.h generic-y += mcs_spinlock.h generic-y += parport.h generic-y += syscalls.h diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl index aae729c95cf9..a522adf194ab 100644 --- a/arch/microblaze/kernel/syscalls/syscall.tbl +++ b/arch/microblaze/kernel/syscalls/syscall.tbl @@ -446,3 +446,4 @@ 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 440 common process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c index c61c641674e6..e3946b06e840 100644 --- a/arch/mips/boot/compressed/decompress.c +++ b/arch/mips/boot/compressed/decompress.c @@ -13,6 +13,7 @@ #include <linux/libfdt.h> #include <asm/addrspace.h> +#include <asm/unaligned.h> /* * These two variables specify the free mem region @@ -117,7 +118,7 @@ void decompress_kernel(unsigned long boot_heap_start) dtb_size = fdt_totalsize((void *)&__appended_dtb); /* last four bytes is always image size in little endian */ - image_size = le32_to_cpup((void *)&__image_end - 4); + image_size = get_unaligned_le32((void *)&__image_end - 4); /* copy dtb to where the booted kernel will expect it */ memcpy((void *)VMLINUX_LOAD_ADDRESS_ULL + image_size, diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index bd47e15d02c7..be5d4afcd30f 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -1444,7 +1444,7 @@ static void octeon_irq_setup_secondary_ciu2(void) static int __init octeon_irq_init_ciu( struct device_node *ciu_node, struct device_node *parent) { - unsigned int i, r; + int i, r; struct irq_chip *chip; struct irq_chip *chip_edge; struct irq_chip *chip_mbox; diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index 198b3bafdac9..95b4fa7bd0d1 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild @@ -6,7 +6,6 @@ generated-y += syscall_table_64_n64.h generated-y += syscall_table_64_o32.h generic-y += export.h generic-y += kvm_para.h -generic-y += local64.h generic-y += mcs_spinlock.h generic-y += parport.h generic-y += qrwlock.h diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h index 19edf8e69971..292d0425717f 100644 --- a/arch/mips/include/asm/highmem.h +++ b/arch/mips/include/asm/highmem.h @@ -51,6 +51,7 @@ extern void kmap_flush_tlb(unsigned long addr); #define flush_cache_kmaps() BUG_ON(cpu_has_dc_aliases) +#define arch_kmap_local_set_pte(mm, vaddr, ptep, ptev) set_pte(ptep, ptev) #define arch_kmap_local_post_map(vaddr, pteval) local_flush_tlb_one(vaddr) #define arch_kmap_local_post_unmap(vaddr) local_flush_tlb_one(vaddr) diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c index 6ee3f7218c67..c4441416e96b 100644 --- a/arch/mips/kernel/binfmt_elfn32.c +++ b/arch/mips/kernel/binfmt_elfn32.c @@ -103,4 +103,11 @@ jiffies_to_old_timeval32(unsigned long jiffies, struct old_timeval32 *value) #undef ns_to_kernel_old_timeval #define ns_to_kernel_old_timeval ns_to_old_timeval32 +/* + * Some data types as stored in coredump. + */ +#define user_long_t compat_long_t +#define user_siginfo_t compat_siginfo_t +#define copy_siginfo_to_external copy_siginfo_to_external32 + #include "../../../fs/binfmt_elf.c" diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index 6dd103d3cebb..7b2a23f48c1a 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c @@ -106,4 +106,11 @@ jiffies_to_old_timeval32(unsigned long jiffies, struct old_timeval32 *value) #undef ns_to_kernel_old_timeval #define ns_to_kernel_old_timeval ns_to_old_timeval32 +/* + * Some data types as stored in coredump. + */ +#define user_long_t compat_long_t +#define user_siginfo_t compat_siginfo_t +#define copy_siginfo_to_external copy_siginfo_to_external32 + #include "../../../fs/binfmt_elf.c" diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c index 47aeb3350a76..0e365b7c742d 100644 --- a/arch/mips/kernel/relocate.c +++ b/arch/mips/kernel/relocate.c @@ -187,8 +187,14 @@ static int __init relocate_exception_table(long offset) static inline __init unsigned long rotate_xor(unsigned long hash, const void *area, size_t size) { - size_t i; - unsigned long *ptr = (unsigned long *)area; + const typeof(hash) *ptr = PTR_ALIGN(area, sizeof(hash)); + size_t diff, i; + + diff = (void *)ptr - area; + if (unlikely(size < diff + sizeof(hash))) + return hash; + + size = ALIGN_DOWN(size - diff, sizeof(hash)); for (i = 0; i < size / sizeof(hash); i++) { /* Rotate by odd number of bits and XOR. */ diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl index 32817c954435..0f03ad223f33 100644 --- a/arch/mips/kernel/syscalls/syscall_n32.tbl +++ b/arch/mips/kernel/syscalls/syscall_n32.tbl @@ -379,3 +379,4 @@ 438 n32 pidfd_getfd sys_pidfd_getfd 439 n32 faccessat2 sys_faccessat2 440 n32 process_madvise sys_process_madvise +441 n32 epoll_pwait2 compat_sys_epoll_pwait2 diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl index 9e4ea3c31b1c..91649690b52f 100644 --- a/arch/mips/kernel/syscalls/syscall_n64.tbl +++ b/arch/mips/kernel/syscalls/syscall_n64.tbl @@ -355,3 +355,4 @@ 438 n64 pidfd_getfd sys_pidfd_getfd 439 n64 faccessat2 sys_faccessat2 440 n64 process_madvise sys_process_madvise +441 n64 epoll_pwait2 sys_epoll_pwait2 diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl index 29f5f28cf5ce..4bad0c40aed6 100644 --- a/arch/mips/kernel/syscalls/syscall_o32.tbl +++ b/arch/mips/kernel/syscalls/syscall_o32.tbl @@ -428,3 +428,4 @@ 438 o32 pidfd_getfd sys_pidfd_getfd 439 o32 faccessat2 sys_faccessat2 440 o32 process_madvise sys_process_madvise +441 o32 epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 diff --git a/arch/nds32/include/asm/Kbuild b/arch/nds32/include/asm/Kbuild index ff1e94299317..82a4453c9c2d 100644 --- a/arch/nds32/include/asm/Kbuild +++ b/arch/nds32/include/asm/Kbuild @@ -4,6 +4,5 @@ generic-y += cmpxchg.h generic-y += export.h generic-y += gpio.h generic-y += kvm_para.h -generic-y += local64.h generic-y += parport.h generic-y += user.h diff --git a/arch/nds32/kernel/ftrace.c b/arch/nds32/kernel/ftrace.c index 3763b3f8c3db..414f8a780cc3 100644 --- a/arch/nds32/kernel/ftrace.c +++ b/arch/nds32/kernel/ftrace.c @@ -10,7 +10,7 @@ extern void (*ftrace_trace_function)(unsigned long, unsigned long, extern void ftrace_graph_caller(void); noinline void __naked ftrace_stub(unsigned long ip, unsigned long parent_ip, - struct ftrace_ops *op, struct pt_regs *regs) + struct ftrace_ops *op, struct ftrace_regs *fregs) { __asm__ (""); /* avoid to optimize as pure function */ } @@ -38,7 +38,7 @@ EXPORT_SYMBOL(_mcount); #else /* CONFIG_DYNAMIC_FTRACE */ noinline void __naked ftrace_stub(unsigned long ip, unsigned long parent_ip, - struct ftrace_ops *op, struct pt_regs *regs) + struct ftrace_ops *op, struct ftrace_regs *fregs) { __asm__ (""); /* avoid to optimize as pure function */ } diff --git a/arch/openrisc/boot/dts/or1klitex.dts b/arch/openrisc/boot/dts/or1klitex.dts new file mode 100644 index 000000000000..3f9867aa3844 --- /dev/null +++ b/arch/openrisc/boot/dts/or1klitex.dts @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * LiteX-based System on Chip + * + * Copyright (C) 2019 Antmicro <www.antmicro.com> + */ + +/dts-v1/; +/ { + compatible = "opencores,or1ksim"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&pic>; + + aliases { + serial0 = &serial0; + }; + + chosen { + bootargs = "console=liteuart"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x10000000>; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu@0 { + compatible = "opencores,or1200-rtlsvn481"; + reg = <0>; + clock-frequency = <100000000>; + }; + }; + + pic: pic { + compatible = "opencores,or1k-pic"; + #interrupt-cells = <1>; + interrupt-controller; + }; + + serial0: serial@e0002000 { + device_type = "serial"; + compatible = "litex,liteuart"; + reg = <0xe0002000 0x100>; + }; + + soc_ctrl0: soc_controller@e0000000 { + compatible = "litex,soc-controller"; + reg = <0xe0000000 0xc>; + status = "okay"; + }; +}; diff --git a/arch/openrisc/configs/or1klitex_defconfig b/arch/openrisc/configs/or1klitex_defconfig new file mode 100644 index 000000000000..3c2c70d3d740 --- /dev/null +++ b/arch/openrisc/configs/or1klitex_defconfig @@ -0,0 +1,18 @@ +CONFIG_BLK_DEV_INITRD=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_BUG_ON_DATA_CORRUPTION=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_EMBEDDED=y +CONFIG_HZ_100=y +CONFIG_INITRAMFS_SOURCE="openrisc-rootfs.cpio.gz" +CONFIG_OF_OVERLAY=y +CONFIG_OPENRISC_BUILTIN_DTB="or1klitex" +CONFIG_PANIC_ON_OOPS=y +CONFIG_PRINTK_TIME=y +CONFIG_LITEX_SOC_CONTROLLER=y +CONFIG_SERIAL_LITEUART=y +CONFIG_SERIAL_LITEUART_CONSOLE=y +CONFIG_SOFTLOCKUP_DETECTOR=y +CONFIG_TTY_PRINTK=y diff --git a/arch/openrisc/include/asm/io.h b/arch/openrisc/include/asm/io.h index 7d6b4a77b379..c298061c70a7 100644 --- a/arch/openrisc/include/asm/io.h +++ b/arch/openrisc/include/asm/io.h @@ -31,7 +31,7 @@ void __iomem *ioremap(phys_addr_t offset, unsigned long size); #define iounmap iounmap -extern void iounmap(void *addr); +extern void iounmap(void __iomem *addr); #include <asm-generic/io.h> diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c index 206e5325e61b..4d61333c2623 100644 --- a/arch/openrisc/kernel/traps.c +++ b/arch/openrisc/kernel/traps.c @@ -238,9 +238,7 @@ void __init trap_init(void) asmlinkage void do_trap(struct pt_regs *regs, unsigned long address) { - force_sig_fault(SIGTRAP, TRAP_TRACE, (void __user *)address); - - regs->pc += 4; + force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc); } asmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address) diff --git a/arch/openrisc/mm/ioremap.c b/arch/openrisc/mm/ioremap.c index 5aed97a18bac..daae13a76743 100644 --- a/arch/openrisc/mm/ioremap.c +++ b/arch/openrisc/mm/ioremap.c @@ -77,7 +77,7 @@ void __iomem *__ref ioremap(phys_addr_t addr, unsigned long size) } EXPORT_SYMBOL(ioremap); -void iounmap(void *addr) +void iounmap(void __iomem *addr) { /* If the page is from the fixmap pool then we just clear out * the fixmap mapping. diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 78b17621ee4a..278462186ac4 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -202,9 +202,8 @@ config PREFETCH depends on PA8X00 || PA7200 config MLONGCALLS - bool "Enable the -mlong-calls compiler option for big kernels" - default y if !MODULES || UBSAN || FTRACE - default n + def_bool y if !MODULES || UBSAN || FTRACE + bool "Enable the -mlong-calls compiler option for big kernels" if MODULES && !UBSAN && !FTRACE depends on PA8X00 help If you configure the kernel to include many drivers built-in instead diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig index 7e2d7026285e..8f81fcbf04c4 100644 --- a/arch/parisc/configs/generic-64bit_defconfig +++ b/arch/parisc/configs/generic-64bit_defconfig @@ -191,7 +191,6 @@ CONFIG_DRM=y CONFIG_DRM_RADEON=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y -# CONFIG_BACKLIGHT_GENERIC is not set CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_HIDRAW=y CONFIG_HID_PID=y diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild index f16c4db80116..4406475a2304 100644 --- a/arch/parisc/include/asm/Kbuild +++ b/arch/parisc/include/asm/Kbuild @@ -3,6 +3,5 @@ generated-y += syscall_table_32.h generated-y += syscall_table_64.h generated-y += syscall_table_c32.h generic-y += kvm_para.h -generic-y += local64.h generic-y += mcs_spinlock.h generic-y += user.h diff --git a/arch/parisc/include/asm/irq.h b/arch/parisc/include/asm/irq.h index 959e79cd2c14..378f63c4015b 100644 --- a/arch/parisc/include/asm/irq.h +++ b/arch/parisc/include/asm/irq.h @@ -47,7 +47,4 @@ extern unsigned long txn_affinity_addr(unsigned int irq, int cpu); extern int cpu_claim_irq(unsigned int irq, struct irq_chip *, void *); extern int cpu_check_affinity(struct irq_data *d, const struct cpumask *dest); -/* soft power switch support (power.c) */ -extern struct tasklet_struct power_tasklet; - #endif /* _ASM_PARISC_IRQ_H */ diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index beba9816cc6c..4d37cc9cba37 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -997,10 +997,17 @@ intr_do_preempt: bb,<,n %r20, 31 - PSW_SM_I, intr_restore nop + /* ssm PSW_SM_I done later in intr_restore */ +#ifdef CONFIG_MLONGCALLS + ldil L%intr_restore, %r2 + load32 preempt_schedule_irq, %r1 + bv %r0(%r1) + ldo R%intr_restore(%r2), %r2 +#else + ldil L%intr_restore, %r1 BL preempt_schedule_irq, %r2 - nop - - b,n intr_restore /* ssm PSW_SM_I done by intr_restore */ + ldo R%intr_restore(%r1), %r2 +#endif #endif /* CONFIG_PREEMPTION */ /* diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c index 63e3ecb9da81..0a1e75af5382 100644 --- a/arch/parisc/kernel/ftrace.c +++ b/arch/parisc/kernel/ftrace.c @@ -51,7 +51,7 @@ static void __hot prepare_ftrace_return(unsigned long *parent, void notrace __hot ftrace_function_trampoline(unsigned long parent, unsigned long self_addr, unsigned long org_sp_gr3, - struct pt_regs *regs) + struct ftrace_regs *fregs) { #ifndef CONFIG_DYNAMIC_FTRACE extern ftrace_func_t ftrace_trace_function; @@ -61,7 +61,7 @@ void notrace __hot ftrace_function_trampoline(unsigned long parent, if (function_trace_op->flags & FTRACE_OPS_FL_ENABLED && ftrace_trace_function != ftrace_stub) ftrace_trace_function(self_addr, parent, - function_trace_op, regs); + function_trace_op, fregs); #ifdef CONFIG_FUNCTION_GRAPH_TRACER if (dereference_function_descriptor(ftrace_graph_return) != @@ -204,17 +204,26 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, #ifdef CONFIG_KPROBES_ON_FTRACE void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, - struct ftrace_ops *ops, struct pt_regs *regs) + struct ftrace_ops *ops, struct ftrace_regs *fregs) { struct kprobe_ctlblk *kcb; - struct kprobe *p = get_kprobe((kprobe_opcode_t *)ip); + struct pt_regs *regs; + struct kprobe *p; + int bit; - if (unlikely(!p) || kprobe_disabled(p)) + bit = ftrace_test_recursion_trylock(ip, parent_ip); + if (bit < 0) return; + regs = ftrace_get_regs(fregs); + preempt_disable_notrace(); + p = get_kprobe((kprobe_opcode_t *)ip); + if (unlikely(!p) || kprobe_disabled(p)) + goto out; + if (kprobe_running()) { kprobes_inc_nmissed_count(p); - return; + goto out; } __this_cpu_write(current_kprobe, p); @@ -235,6 +244,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, } } __this_cpu_write(current_kprobe, NULL); +out: + preempt_enable_notrace(); + ftrace_test_recursion_unlock(bit); } NOKPROBE_SYMBOL(kprobe_ftrace_handler); diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index e76c86619949..49cd6d2caefb 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -216,12 +216,9 @@ int show_interrupts(struct seq_file *p, void *v) if (!action) goto skip; seq_printf(p, "%3d: ", i); -#ifdef CONFIG_SMP + for_each_online_cpu(j) - seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); -#else - seq_printf(p, "%10u ", kstat_irqs(i)); -#endif + seq_printf(p, "%10u ", irq_desc_kstat_cpu(desc, j)); seq_printf(p, " %14s", irq_desc_get_chip(desc)->name); #ifndef PARISC_IRQ_CR16_COUNTS diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl index f375ea528e59..6bcc31966b44 100644 --- a/arch/parisc/kernel/syscalls/syscall.tbl +++ b/arch/parisc/kernel/syscalls/syscall.tbl @@ -438,3 +438,4 @@ 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 440 common process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index e307f777d942..107bb4319e0e 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -66,7 +66,7 @@ config NEED_PER_CPU_PAGE_FIRST_CHUNK config NR_IRQS int "Number of virtual interrupt numbers" - range 32 32768 + range 32 1048576 default "512" help This defines the number of virtual interrupt numbers the kernel @@ -87,7 +87,7 @@ config PPC_WATCHDOG help This is a placeholder when the powerpc hardlockup detector watchdog is selected (arch/powerpc/kernel/watchdog.c). It is - seleted via the generic lockup detector menu which is why we + selected via the generic lockup detector menu which is why we have no standalone config option for it here. config STACKTRACE_SUPPORT @@ -161,6 +161,7 @@ config PPC select DCACHE_WORD_ACCESS if PPC64 && CPU_LITTLE_ENDIAN select DMA_OPS if PPC64 select DMA_OPS_BYPASS if PPC64 + select ARCH_HAS_DMA_MAP_DIRECT if PPC64 && PPC_PSERIES select DYNAMIC_FTRACE if FUNCTION_TRACER select EDAC_ATOMIC_SCRUB select EDAC_SUPPORT @@ -177,6 +178,7 @@ config PPC select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER select GENERIC_TIME_VSYSCALL + select GENERIC_GETTIMEOFDAY select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_HUGE_VMAP if PPC_BOOK3S_64 && PPC_RADIX_MMU select HAVE_ARCH_JUMP_LABEL @@ -207,6 +209,7 @@ config PPC select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_GCC_PLUGINS if GCC_VERSION >= 50200 # plugin support on gcc <= 5.1 is buggy on PPC + select HAVE_GENERIC_VDSO select HAVE_HW_BREAKPOINT if PERF_EVENTS && (PPC_BOOK3S || PPC_8xx) select HAVE_IDE select HAVE_IOREMAP_PROT @@ -312,6 +315,10 @@ config GENERIC_BUG default y depends on BUG +config GENERIC_BUG_RELATIVE_POINTERS + def_bool y + depends on GENERIC_BUG + config SYS_SUPPORTS_APM_EMULATION default y if PMAC_APM_EMU bool @@ -418,6 +425,7 @@ config HUGETLB_PAGE_SIZE_VARIABLE config MATH_EMULATION bool "Math emulation" depends on 4xx || PPC_8xx || PPC_MPC832x || BOOKE + select PPC_FPU_REGS help Some PowerPC chips designed for embedded applications do not have a floating-point unit and therefore do not implement the @@ -657,9 +665,15 @@ config IRQ_ALL_CPUS reported with SMP Power Macintoshes with this option enabled. config NUMA - bool "NUMA support" - depends on PPC64 - default y if SMP && PPC_PSERIES + bool "NUMA Memory Allocation and Scheduler Support" + depends on PPC64 && SMP + default y if PPC_PSERIES || PPC_POWERNV + help + Enable NUMA (Non-Uniform Memory Access) support. + + The kernel will try to allocate memory used by a CPU on the + local memory controller of the CPU and add some more + NUMA awareness to the kernel. config NODES_SHIFT int @@ -793,8 +807,7 @@ config DATA_SHIFT_BOOL bool "Set custom data alignment" depends on ADVANCED_OPTIONS depends on STRICT_KERNEL_RWX || DEBUG_PAGEALLOC - depends on PPC_BOOK3S_32 || (PPC_8xx && !PIN_TLB_DATA && \ - (!PIN_TLB_TEXT || !STRICT_KERNEL_RWX)) + depends on PPC_BOOK3S_32 || (PPC_8xx && !PIN_TLB_DATA && !STRICT_KERNEL_RWX) help This option allows you to set the kernel data alignment. When RAM is mapped by blocks, the alignment needs to fit the size and diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 5c8c06215dd4..08cf0eade56a 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -374,6 +374,11 @@ ppc64le_allmodconfig: $(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/powerpc/configs/le.config \ -f $(srctree)/Makefile allmodconfig +PHONY += ppc64le_allnoconfig +ppc64le_allnoconfig: + $(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/powerpc/configs/ppc64le.config \ + -f $(srctree)/Makefile allnoconfig + PHONY += ppc64_book3e_allmodconfig ppc64_book3e_allmodconfig: $(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/powerpc/configs/85xx-64bit.config \ @@ -405,18 +410,24 @@ PHONY += install install: $(Q)$(MAKE) $(build)=$(boot) install -PHONY += vdso_install -vdso_install: -ifdef CONFIG_PPC64 - $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso64 $@ -endif -ifdef CONFIG_VDSO32 - $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso32 $@ -endif - archclean: $(Q)$(MAKE) $(clean)=$(boot) +ifeq ($(KBUILD_EXTMOD),) +# We need to generate vdso-offsets.h before compiling certain files in kernel/. +# In order to do that, we should use the archprepare target, but we can't since +# asm-offsets.h is included in some files used to generate vdso-offsets.h, and +# asm-offsets.h is built in prepare0, for which archprepare is a dependency. +# Therefore we need to generate the header after prepare0 has been made, hence +# this hack. +prepare: vdso_prepare +vdso_prepare: prepare0 + $(if $(CONFIG_VDSO32),$(Q)$(MAKE) \ + $(build)=arch/powerpc/kernel/vdso32 include/generated/vdso32-offsets.h) + $(if $(CONFIG_PPC64),$(Q)$(MAKE) \ + $(build)=arch/powerpc/kernel/vdso64 include/generated/vdso64-offsets.h) +endif + archprepare: checkbin archheaders: diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 1659963a8f1d..2b8da923ceca 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -21,7 +21,11 @@ all: $(obj)/zImage ifdef CROSS32_COMPILE +ifdef CONFIG_CC_IS_CLANG + BOOTCC := $(CROSS32_COMPILE)clang +else BOOTCC := $(CROSS32_COMPILE)gcc +endif BOOTAR := $(CROSS32_COMPILE)ar else BOOTCC := $(CC) @@ -369,6 +373,8 @@ initrd-y := $(filter-out $(image-y), $(initrd-y)) targets += $(image-y) $(initrd-y) targets += $(foreach x, dtbImage uImage cuImage simpleImage treeImage, \ $(patsubst $(x).%, dts/%.dtb, $(filter $(x).%, $(image-y)))) +targets += $(foreach x, dtbImage uImage cuImage simpleImage treeImage, \ + $(patsubst $(x).%, dts/fsl/%.dtb, $(filter $(x).%, $(image-y)))) $(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz diff --git a/arch/powerpc/boot/ps3.c b/arch/powerpc/boot/ps3.c index 6e4efbdb6b7c..f157717ae814 100644 --- a/arch/powerpc/boot/ps3.c +++ b/arch/powerpc/boot/ps3.c @@ -21,13 +21,6 @@ extern int lv1_get_logical_ppe_id(u64 *out_1); extern int lv1_get_repository_node_value(u64 in_1, u64 in_2, u64 in_3, u64 in_4, u64 in_5, u64 *out_1, u64 *out_2); -#ifdef DEBUG -#define DBG(fmt...) printf(fmt) -#else -static inline int __attribute__ ((format (printf, 1, 2))) DBG( - const char *fmt, ...) {return 0;} -#endif - BSS_STACK(4096); /* A buffer that may be edited by tools operating on a zImage binary so as to diff --git a/arch/powerpc/boot/util.S b/arch/powerpc/boot/util.S index d03cdb7606dc..6a92376daf3f 100644 --- a/arch/powerpc/boot/util.S +++ b/arch/powerpc/boot/util.S @@ -42,14 +42,11 @@ udelay: * (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns * timebase_period_ns defaults to 60 (16.6MHz) */ mflr r5 - bl 0f + bcl 20,31,0f 0: mflr r6 mtlr r5 - lis r5,0b@ha - addi r5,r5,0b@l - subf r5,r5,r6 /* In case we're relocated */ - addis r5,r5,timebase_period_ns@ha - lwz r5,timebase_period_ns@l(r5) + addis r5,r6,(timebase_period_ns-0b)@ha + lwz r5,(timebase_period_ns-0b)@l(r5) add r4,r4,r5 addi r4,r4,-1 divw r4,r4,r5 /* BUS ticks */ diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index cd58a62e810d..41fa0a8715e3 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -46,6 +46,8 @@ compression=.gz uboot_comp=gzip pie= format= +notext= +rodynamic= # cross-compilation prefix CROSS= @@ -353,6 +355,8 @@ epapr) platformo="$object/pseries-head.o $object/epapr.o $object/epapr-wrapper.o" link_address='0x20000000' pie=-pie + notext='-z notext' + rodynamic=$(if ${CROSS}ld -V 2>&1 | grep -q LLD ; then echo "-z rodynamic"; fi) ;; mvme5100) platformo="$object/fixed-head.o $object/mvme5100.o" @@ -493,7 +497,7 @@ if [ "$platform" != "miboot" ]; then text_start="-Ttext $link_address" fi #link everything - ${CROSS}ld -m $format -T $lds $text_start $pie $nodl -o "$ofile" $map \ + ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $rodynamic $notext -o "$ofile" $map \ $platformo $tmp $object/wrapper.a rm $tmp fi diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S index a21f3a76e06f..d6f072865627 100644 --- a/arch/powerpc/boot/zImage.lds.S +++ b/arch/powerpc/boot/zImage.lds.S @@ -34,6 +34,17 @@ SECTIONS __dynamic_start = .; *(.dynamic) } + +#ifdef CONFIG_PPC64_BOOT_WRAPPER + . = ALIGN(256); + .got : + { + __toc_start = .; + *(.got) + *(.toc) + } +#endif + .hash : { *(.hash) } .interp : { *(.interp) } .rela.dyn : @@ -76,16 +87,6 @@ SECTIONS _esm_blob_end = .; } -#ifdef CONFIG_PPC64_BOOT_WRAPPER - . = ALIGN(256); - .got : - { - __toc_start = .; - *(.got) - *(.toc) - } -#endif - . = ALIGN(4096); .bss : { diff --git a/arch/powerpc/configs/disable-werror.config b/arch/powerpc/configs/disable-werror.config new file mode 100644 index 000000000000..6ea12a12432c --- /dev/null +++ b/arch/powerpc/configs/disable-werror.config @@ -0,0 +1 @@ +CONFIG_PPC_DISABLE_WERROR=y diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig index cf30fc24413b..60a30fffeda0 100644 --- a/arch/powerpc/configs/powernv_defconfig +++ b/arch/powerpc/configs/powernv_defconfig @@ -208,7 +208,6 @@ CONFIG_FB_MATROX_G=y CONFIG_FB_RADEON=m CONFIG_FB_IBM_GXT4500=m CONFIG_LCD_PLATFORM=m -CONFIG_BACKLIGHT_GENERIC=m # CONFIG_VGA_CONSOLE is not set CONFIG_LOGO=y CONFIG_HID_A4TECH=m diff --git a/arch/powerpc/configs/ppc64le.config b/arch/powerpc/configs/ppc64le.config new file mode 100644 index 000000000000..14dca1062c1b --- /dev/null +++ b/arch/powerpc/configs/ppc64le.config @@ -0,0 +1,2 @@ +CONFIG_PPC64=y +CONFIG_CPU_LITTLE_ENDIAN=y diff --git a/arch/powerpc/configs/security.config b/arch/powerpc/configs/security.config new file mode 100644 index 000000000000..1c91a35c6a73 --- /dev/null +++ b/arch/powerpc/configs/security.config @@ -0,0 +1,15 @@ +# This is the equivalent of booting with lockdown=integrity +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_LOCKDOWN_LSM=y +CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y +CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY=y + +# These are some general, reasonably inexpensive hardening options +CONFIG_HARDENED_USERCOPY=y +CONFIG_FORTIFY_SOURCE=y +CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y + +# UBSAN bounds checking is very cheap and good for hardening +CONFIG_UBSAN=y +# CONFIG_UBSAN_MISC is not set
\ No newline at end of file diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild index 90cd5c53af66..e1f9b4ea1c53 100644 --- a/arch/powerpc/include/asm/Kbuild +++ b/arch/powerpc/include/asm/Kbuild @@ -5,7 +5,6 @@ generated-y += syscall_table_c32.h generated-y += syscall_table_spu.h generic-y += export.h generic-y += kvm_types.h -generic-y += local64.h generic-y += mcs_spinlock.h generic-y += qrwlock.h generic-y += vtime.h diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h index 8a55eb8cc97b..61c6e8b200e8 100644 --- a/arch/powerpc/include/asm/atomic.h +++ b/arch/powerpc/include/asm/atomic.h @@ -10,6 +10,7 @@ #include <linux/types.h> #include <asm/cmpxchg.h> #include <asm/barrier.h> +#include <asm/asm-const.h> /* * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with @@ -26,14 +27,14 @@ static __inline__ int atomic_read(const atomic_t *v) { int t; - __asm__ __volatile__("lwz%U1%X1 %0,%1" : "=r"(t) : "m"(v->counter)); + __asm__ __volatile__("lwz%U1%X1 %0,%1" : "=r"(t) : "m"UPD_CONSTR(v->counter)); return t; } static __inline__ void atomic_set(atomic_t *v, int i) { - __asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i)); + __asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"UPD_CONSTR(v->counter) : "r"(i)); } #define ATOMIC_OP(op, asm_op) \ @@ -316,14 +317,14 @@ static __inline__ s64 atomic64_read(const atomic64_t *v) { s64 t; - __asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : "m"(v->counter)); + __asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : "m"UPD_CONSTR(v->counter)); return t; } static __inline__ void atomic64_set(atomic64_t *v, s64 i) { - __asm__ __volatile__("std%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i)); + __asm__ __volatile__("std%U0%X0 %1,%0" : "=m"UPD_CONSTR(v->counter) : "r"(i)); } #define ATOMIC64_OP(op, asm_op) \ diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h index f53c42380832..aecfde829d5d 100644 --- a/arch/powerpc/include/asm/barrier.h +++ b/arch/powerpc/include/asm/barrier.h @@ -40,7 +40,7 @@ #define wmb() __asm__ __volatile__ ("sync" : : : "memory") /* The sub-arch has lwsync */ -#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC) +#if defined(CONFIG_PPC64) || defined(CONFIG_PPC_E500MC) # define SMPWMB LWSYNC #else # define SMPWMB eieio diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h index 4a4d3afd5340..299ab33505a6 100644 --- a/arch/powerpc/include/asm/bitops.h +++ b/arch/powerpc/include/asm/bitops.h @@ -216,15 +216,34 @@ static inline void arch___clear_bit_unlock(int nr, volatile unsigned long *addr) */ static inline int fls(unsigned int x) { - return 32 - __builtin_clz(x); + int lz; + + if (__builtin_constant_p(x)) + return x ? 32 - __builtin_clz(x) : 0; + asm("cntlzw %0,%1" : "=r" (lz) : "r" (x)); + return 32 - lz; } #include <asm-generic/bitops/builtin-__fls.h> +/* + * 64-bit can do this using one cntlzd (count leading zeroes doubleword) + * instruction; for 32-bit we use the generic version, which does two + * 32-bit fls calls. + */ +#ifdef CONFIG_PPC64 static inline int fls64(__u64 x) { - return 64 - __builtin_clzll(x); + int lz; + + if (__builtin_constant_p(x)) + return x ? 64 - __builtin_clzll(x) : 0; + asm("cntlzd %0,%1" : "=r" (lz) : "r" (x)); + return 64 - lz; } +#else +#include <asm-generic/bitops/fls64.h> +#endif #ifdef CONFIG_PPC64 unsigned int __arch_hweight8(unsigned int w); diff --git a/arch/powerpc/include/asm/book3s/32/kup.h b/arch/powerpc/include/asm/book3s/32/kup.h index 32fd4452e960..a0117a9d5b06 100644 --- a/arch/powerpc/include/asm/book3s/32/kup.h +++ b/arch/powerpc/include/asm/book3s/32/kup.h @@ -183,11 +183,7 @@ bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) unsigned long begin = regs->kuap & 0xf0000000; unsigned long end = regs->kuap << 28; - if (!is_write) - return false; - - return WARN(address < begin || address >= end, - "Bug: write fault blocked by segment registers !"); + return is_write && (address < begin || address >= end); } #endif /* CONFIG_PPC_KUAP */ diff --git a/arch/powerpc/include/asm/book3s/32/mmu-hash.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h index 2e277ca0170f..685c589e723f 100644 --- a/arch/powerpc/include/asm/book3s/32/mmu-hash.h +++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h @@ -90,10 +90,11 @@ struct hash_pte { typedef struct { unsigned long id; - unsigned long vdso_base; + void __user *vdso; } mm_context_t; void update_bats(void); +static inline void cleanup_cpu_mmu_context(void) { }; /* patch sites */ extern s32 patch__hash_page_A0, patch__hash_page_A1, patch__hash_page_A2; diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h index 1376be95e975..415ae29fa73a 100644 --- a/arch/powerpc/include/asm/book3s/32/pgtable.h +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h @@ -240,8 +240,14 @@ extern void add_hash_page(unsigned context, unsigned long va, unsigned long pmdval); /* Flush an entry from the TLB/hash table */ -extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, - unsigned long address); +static inline void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long addr) +{ + if (mmu_has_feature(MMU_FTR_HPTE_TABLE)) { + unsigned long ptephys = __pa(ptep) & PAGE_MASK; + + flush_hash_pages(mm->context.id, addr, ptephys, 1); + } +} /* * PTE updates. This function is called whenever an existing @@ -293,10 +299,9 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm, { unsigned long old; old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0); - if (old & _PAGE_HASHPTE) { - unsigned long ptephys = __pa(ptep) & PAGE_MASK; - flush_hash_pages(mm->context.id, addr, ptephys, 1); - } + if (old & _PAGE_HASHPTE) + flush_hash_entry(mm, ptep, addr); + return (old & _PAGE_ACCESSED) != 0; } #define ptep_test_and_clear_young(__vma, __addr, __ptep) \ @@ -524,9 +529,9 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, if (pte_val(*ptep) & _PAGE_HASHPTE) flush_hash_entry(mm, ptep, addr); __asm__ __volatile__("\ - stw%U0%X0 %2,%0\n\ + stw%X0 %2,%0\n\ eieio\n\ - stw%U0%X0 %L2,%1" + stw%X1 %L2,%1" : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) : "r" (pte) : "memory"); diff --git a/arch/powerpc/include/asm/book3s/32/tlbflush.h b/arch/powerpc/include/asm/book3s/32/tlbflush.h index 068085b709fb..d941c06d4f2e 100644 --- a/arch/powerpc/include/asm/book3s/32/tlbflush.h +++ b/arch/powerpc/include/asm/book3s/32/tlbflush.h @@ -6,12 +6,69 @@ /* * TLB flushing for "classic" hash-MMU 32-bit CPUs, 6xx, 7xx, 7xxx */ -extern void flush_tlb_mm(struct mm_struct *mm); -extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); -extern void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr); -extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end); -extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); +void hash__flush_tlb_mm(struct mm_struct *mm); +void hash__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); +void hash__flush_range(struct mm_struct *mm, unsigned long start, unsigned long end); + +#ifdef CONFIG_SMP +void _tlbie(unsigned long address); +#else +static inline void _tlbie(unsigned long address) +{ + asm volatile ("tlbie %0; sync" : : "r" (address) : "memory"); +} +#endif +void _tlbia(void); + +/* + * Called at the end of a mmu_gather operation to make sure the + * TLB flush is completely done. + */ +static inline void tlb_flush(struct mmu_gather *tlb) +{ + /* 603 needs to flush the whole TLB here since it doesn't use a hash table. */ + if (!mmu_has_feature(MMU_FTR_HPTE_TABLE)) + _tlbia(); +} + +static inline void flush_range(struct mm_struct *mm, unsigned long start, unsigned long end) +{ + start &= PAGE_MASK; + if (mmu_has_feature(MMU_FTR_HPTE_TABLE)) + hash__flush_range(mm, start, end); + else if (end - start <= PAGE_SIZE) + _tlbie(start); + else + _tlbia(); +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + if (mmu_has_feature(MMU_FTR_HPTE_TABLE)) + hash__flush_tlb_mm(mm); + else + _tlbia(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) +{ + if (mmu_has_feature(MMU_FTR_HPTE_TABLE)) + hash__flush_tlb_page(vma, vmaddr); + else + _tlbie(vmaddr); +} + +static inline void +flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) +{ + flush_range(vma->vm_mm, start, end); +} + +static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + flush_range(&init_mm, start, end); +} + static inline void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) { diff --git a/arch/powerpc/include/asm/book3s/64/hash-pkey.h b/arch/powerpc/include/asm/book3s/64/hash-pkey.h index 795010897e5d..f1e60d579f6c 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-pkey.h +++ b/arch/powerpc/include/asm/book3s/64/hash-pkey.h @@ -2,6 +2,9 @@ #ifndef _ASM_POWERPC_BOOK3S_64_HASH_PKEY_H #define _ASM_POWERPC_BOOK3S_64_HASH_PKEY_H +/* We use key 3 for KERNEL */ +#define HASH_DEFAULT_KERNEL_KEY (HPTE_R_KEY_BIT0 | HPTE_R_KEY_BIT1) + static inline u64 hash__vmflag_to_pte_pkey_bits(u64 vm_flags) { return (((vm_flags & VM_PKEY_BIT0) ? H_PTE_PKEY_BIT0 : 0x0UL) | @@ -11,13 +14,23 @@ static inline u64 hash__vmflag_to_pte_pkey_bits(u64 vm_flags) ((vm_flags & VM_PKEY_BIT4) ? H_PTE_PKEY_BIT4 : 0x0UL)); } -static inline u64 pte_to_hpte_pkey_bits(u64 pteflags) +static inline u64 pte_to_hpte_pkey_bits(u64 pteflags, unsigned long flags) { - return (((pteflags & H_PTE_PKEY_BIT4) ? HPTE_R_KEY_BIT4 : 0x0UL) | - ((pteflags & H_PTE_PKEY_BIT3) ? HPTE_R_KEY_BIT3 : 0x0UL) | - ((pteflags & H_PTE_PKEY_BIT2) ? HPTE_R_KEY_BIT2 : 0x0UL) | - ((pteflags & H_PTE_PKEY_BIT1) ? HPTE_R_KEY_BIT1 : 0x0UL) | - ((pteflags & H_PTE_PKEY_BIT0) ? HPTE_R_KEY_BIT0 : 0x0UL)); + unsigned long pte_pkey; + + pte_pkey = (((pteflags & H_PTE_PKEY_BIT4) ? HPTE_R_KEY_BIT4 : 0x0UL) | + ((pteflags & H_PTE_PKEY_BIT3) ? HPTE_R_KEY_BIT3 : 0x0UL) | + ((pteflags & H_PTE_PKEY_BIT2) ? HPTE_R_KEY_BIT2 : 0x0UL) | + ((pteflags & H_PTE_PKEY_BIT1) ? HPTE_R_KEY_BIT1 : 0x0UL) | + ((pteflags & H_PTE_PKEY_BIT0) ? HPTE_R_KEY_BIT0 : 0x0UL)); + + if (mmu_has_feature(MMU_FTR_BOOK3S_KUAP) || + mmu_has_feature(MMU_FTR_BOOK3S_KUEP)) { + if ((pte_pkey == 0) && (flags & HPTE_USE_KERNEL_KEY)) + return HASH_DEFAULT_KERNEL_KEY; + } + + return pte_pkey; } static inline u16 hash__pte_to_pkey_bits(u64 pteflags) diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 73ad038ed10b..d959b0195ad9 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -145,7 +145,7 @@ extern void hash__mark_initmem_nx(void); extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned long pte, int huge); -extern unsigned long htab_convert_pte_flags(unsigned long pteflags); +unsigned long htab_convert_pte_flags(unsigned long pteflags, unsigned long flags); /* Atomic PTE updates */ static inline unsigned long hash__pte_update(struct mm_struct *mm, unsigned long addr, diff --git a/arch/powerpc/include/asm/book3s/64/kexec.h b/arch/powerpc/include/asm/book3s/64/kexec.h index 6b5c3a248ba2..d4b9d476ecba 100644 --- a/arch/powerpc/include/asm/book3s/64/kexec.h +++ b/arch/powerpc/include/asm/book3s/64/kexec.h @@ -3,6 +3,7 @@ #ifndef _ASM_POWERPC_BOOK3S_64_KEXEC_H_ #define _ASM_POWERPC_BOOK3S_64_KEXEC_H_ +#include <asm/plpar_wrappers.h> #define reset_sprs reset_sprs static inline void reset_sprs(void) @@ -14,6 +15,10 @@ static inline void reset_sprs(void) if (cpu_has_feature(CPU_FTR_ARCH_207S)) { mtspr(SPRN_IAMR, 0); + if (cpu_has_feature(CPU_FTR_HVMODE)) + mtspr(SPRN_CIABR, 0); + else + plpar_set_ciabr(0); } /* Do we need isync()? We are going via a kexec reset */ diff --git a/arch/powerpc/include/asm/book3s/64/kup-radix.h b/arch/powerpc/include/asm/book3s/64/kup-radix.h deleted file mode 100644 index a39e2d193fdc..000000000000 --- a/arch/powerpc/include/asm/book3s/64/kup-radix.h +++ /dev/null @@ -1,205 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _ASM_POWERPC_BOOK3S_64_KUP_RADIX_H -#define _ASM_POWERPC_BOOK3S_64_KUP_RADIX_H - -#include <linux/const.h> -#include <asm/reg.h> - -#define AMR_KUAP_BLOCK_READ UL(0x4000000000000000) -#define AMR_KUAP_BLOCK_WRITE UL(0x8000000000000000) -#define AMR_KUAP_BLOCKED (AMR_KUAP_BLOCK_READ | AMR_KUAP_BLOCK_WRITE) -#define AMR_KUAP_SHIFT 62 - -#ifdef __ASSEMBLY__ - -.macro kuap_restore_amr gpr1, gpr2 -#ifdef CONFIG_PPC_KUAP - BEGIN_MMU_FTR_SECTION_NESTED(67) - mfspr \gpr1, SPRN_AMR - ld \gpr2, STACK_REGS_KUAP(r1) - cmpd \gpr1, \gpr2 - beq 998f - isync - mtspr SPRN_AMR, \gpr2 - /* No isync required, see kuap_restore_amr() */ -998: - END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_RADIX_KUAP, 67) -#endif -.endm - -#ifdef CONFIG_PPC_KUAP -.macro kuap_check_amr gpr1, gpr2 -#ifdef CONFIG_PPC_KUAP_DEBUG - BEGIN_MMU_FTR_SECTION_NESTED(67) - mfspr \gpr1, SPRN_AMR - li \gpr2, (AMR_KUAP_BLOCKED >> AMR_KUAP_SHIFT) - sldi \gpr2, \gpr2, AMR_KUAP_SHIFT -999: tdne \gpr1, \gpr2 - EMIT_BUG_ENTRY 999b, __FILE__, __LINE__, (BUGFLAG_WARNING | BUGFLAG_ONCE) - END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_RADIX_KUAP, 67) -#endif -.endm -#endif - -.macro kuap_save_amr_and_lock gpr1, gpr2, use_cr, msr_pr_cr -#ifdef CONFIG_PPC_KUAP - BEGIN_MMU_FTR_SECTION_NESTED(67) - .ifnb \msr_pr_cr - bne \msr_pr_cr, 99f - .endif - mfspr \gpr1, SPRN_AMR - std \gpr1, STACK_REGS_KUAP(r1) - li \gpr2, (AMR_KUAP_BLOCKED >> AMR_KUAP_SHIFT) - sldi \gpr2, \gpr2, AMR_KUAP_SHIFT - cmpd \use_cr, \gpr1, \gpr2 - beq \use_cr, 99f - // We don't isync here because we very recently entered via rfid - mtspr SPRN_AMR, \gpr2 - isync -99: - END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_RADIX_KUAP, 67) -#endif -.endm - -#else /* !__ASSEMBLY__ */ - -#include <linux/jump_label.h> - -DECLARE_STATIC_KEY_FALSE(uaccess_flush_key); - -#ifdef CONFIG_PPC_KUAP - -#include <asm/mmu.h> -#include <asm/ptrace.h> - -static inline void kuap_restore_amr(struct pt_regs *regs, unsigned long amr) -{ - if (mmu_has_feature(MMU_FTR_RADIX_KUAP) && unlikely(regs->kuap != amr)) { - isync(); - mtspr(SPRN_AMR, regs->kuap); - /* - * No isync required here because we are about to RFI back to - * previous context before any user accesses would be made, - * which is a CSI. - */ - } -} - -static inline unsigned long kuap_get_and_check_amr(void) -{ - if (mmu_has_feature(MMU_FTR_RADIX_KUAP)) { - unsigned long amr = mfspr(SPRN_AMR); - if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG)) /* kuap_check_amr() */ - WARN_ON_ONCE(amr != AMR_KUAP_BLOCKED); - return amr; - } - return 0; -} - -static inline void kuap_check_amr(void) -{ - if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG) && mmu_has_feature(MMU_FTR_RADIX_KUAP)) - WARN_ON_ONCE(mfspr(SPRN_AMR) != AMR_KUAP_BLOCKED); -} - -/* - * We support individually allowing read or write, but we don't support nesting - * because that would require an expensive read/modify write of the AMR. - */ - -static inline unsigned long get_kuap(void) -{ - /* - * We return AMR_KUAP_BLOCKED when we don't support KUAP because - * prevent_user_access_return needs to return AMR_KUAP_BLOCKED to - * cause restore_user_access to do a flush. - * - * This has no effect in terms of actually blocking things on hash, - * so it doesn't break anything. - */ - if (!early_mmu_has_feature(MMU_FTR_RADIX_KUAP)) - return AMR_KUAP_BLOCKED; - - return mfspr(SPRN_AMR); -} - -static inline void set_kuap(unsigned long value) -{ - if (!early_mmu_has_feature(MMU_FTR_RADIX_KUAP)) - return; - - /* - * ISA v3.0B says we need a CSI (Context Synchronising Instruction) both - * before and after the move to AMR. See table 6 on page 1134. - */ - isync(); - mtspr(SPRN_AMR, value); - isync(); -} - -static inline bool -bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) -{ - return WARN(mmu_has_feature(MMU_FTR_RADIX_KUAP) && - (regs->kuap & (is_write ? AMR_KUAP_BLOCK_WRITE : AMR_KUAP_BLOCK_READ)), - "Bug: %s fault blocked by AMR!", is_write ? "Write" : "Read"); -} -#else /* CONFIG_PPC_KUAP */ -static inline void kuap_restore_amr(struct pt_regs *regs, unsigned long amr) { } - -static inline unsigned long kuap_get_and_check_amr(void) -{ - return 0UL; -} - -static inline unsigned long get_kuap(void) -{ - return AMR_KUAP_BLOCKED; -} - -static inline void set_kuap(unsigned long value) { } -#endif /* !CONFIG_PPC_KUAP */ - -static __always_inline void allow_user_access(void __user *to, const void __user *from, - unsigned long size, unsigned long dir) -{ - // This is written so we can resolve to a single case at build time - BUILD_BUG_ON(!__builtin_constant_p(dir)); - if (dir == KUAP_READ) - set_kuap(AMR_KUAP_BLOCK_WRITE); - else if (dir == KUAP_WRITE) - set_kuap(AMR_KUAP_BLOCK_READ); - else if (dir == KUAP_READ_WRITE) - set_kuap(0); - else - BUILD_BUG(); -} - -static inline void prevent_user_access(void __user *to, const void __user *from, - unsigned long size, unsigned long dir) -{ - set_kuap(AMR_KUAP_BLOCKED); - if (static_branch_unlikely(&uaccess_flush_key)) - do_uaccess_flush(); -} - -static inline unsigned long prevent_user_access_return(void) -{ - unsigned long flags = get_kuap(); - - set_kuap(AMR_KUAP_BLOCKED); - if (static_branch_unlikely(&uaccess_flush_key)) - do_uaccess_flush(); - - return flags; -} - -static inline void restore_user_access(unsigned long flags) -{ - set_kuap(flags); - if (static_branch_unlikely(&uaccess_flush_key) && flags == AMR_KUAP_BLOCKED) - do_uaccess_flush(); -} -#endif /* __ASSEMBLY__ */ - -#endif /* _ASM_POWERPC_BOOK3S_64_KUP_RADIX_H */ diff --git a/arch/powerpc/include/asm/book3s/64/kup.h b/arch/powerpc/include/asm/book3s/64/kup.h new file mode 100644 index 000000000000..f50f72e535aa --- /dev/null +++ b/arch/powerpc/include/asm/book3s/64/kup.h @@ -0,0 +1,442 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_BOOK3S_64_KUP_H +#define _ASM_POWERPC_BOOK3S_64_KUP_H + +#include <linux/const.h> +#include <asm/reg.h> + +#define AMR_KUAP_BLOCK_READ UL(0x5455555555555555) +#define AMR_KUAP_BLOCK_WRITE UL(0xa8aaaaaaaaaaaaaa) +#define AMR_KUEP_BLOCKED UL(0x5455555555555555) +#define AMR_KUAP_BLOCKED (AMR_KUAP_BLOCK_READ | AMR_KUAP_BLOCK_WRITE) + +#ifdef __ASSEMBLY__ + +.macro kuap_user_restore gpr1, gpr2 +#if defined(CONFIG_PPC_PKEY) + BEGIN_MMU_FTR_SECTION_NESTED(67) + b 100f // skip_restore_amr + END_MMU_FTR_SECTION_NESTED_IFCLR(MMU_FTR_PKEY, 67) + /* + * AMR and IAMR are going to be different when + * returning to userspace. + */ + ld \gpr1, STACK_REGS_AMR(r1) + + /* + * If kuap feature is not enabled, do the mtspr + * only if AMR value is different. + */ + BEGIN_MMU_FTR_SECTION_NESTED(68) + mfspr \gpr2, SPRN_AMR + cmpd \gpr1, \gpr2 + beq 99f + END_MMU_FTR_SECTION_NESTED_IFCLR(MMU_FTR_BOOK3S_KUAP, 68) + + isync + mtspr SPRN_AMR, \gpr1 +99: + /* + * Restore IAMR only when returning to userspace + */ + ld \gpr1, STACK_REGS_IAMR(r1) + + /* + * If kuep feature is not enabled, do the mtspr + * only if IAMR value is different. + */ + BEGIN_MMU_FTR_SECTION_NESTED(69) + mfspr \gpr2, SPRN_IAMR + cmpd \gpr1, \gpr2 + beq 100f + END_MMU_FTR_SECTION_NESTED_IFCLR(MMU_FTR_BOOK3S_KUEP, 69) + + isync + mtspr SPRN_IAMR, \gpr1 + +100: //skip_restore_amr + /* No isync required, see kuap_user_restore() */ +#endif +.endm + +.macro kuap_kernel_restore gpr1, gpr2 +#if defined(CONFIG_PPC_PKEY) + + BEGIN_MMU_FTR_SECTION_NESTED(67) + /* + * AMR is going to be mostly the same since we are + * returning to the kernel. Compare and do a mtspr. + */ + ld \gpr2, STACK_REGS_AMR(r1) + mfspr \gpr1, SPRN_AMR + cmpd \gpr1, \gpr2 + beq 100f + isync + mtspr SPRN_AMR, \gpr2 + /* + * No isync required, see kuap_restore_amr() + * No need to restore IAMR when returning to kernel space. + */ +100: + END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_BOOK3S_KUAP, 67) +#endif +.endm + +#ifdef CONFIG_PPC_KUAP +.macro kuap_check_amr gpr1, gpr2 +#ifdef CONFIG_PPC_KUAP_DEBUG + BEGIN_MMU_FTR_SECTION_NESTED(67) + mfspr \gpr1, SPRN_AMR + /* Prevent access to userspace using any key values */ + LOAD_REG_IMMEDIATE(\gpr2, AMR_KUAP_BLOCKED) +999: tdne \gpr1, \gpr2 + EMIT_BUG_ENTRY 999b, __FILE__, __LINE__, (BUGFLAG_WARNING | BUGFLAG_ONCE) + END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_BOOK3S_KUAP, 67) +#endif +.endm +#endif + +/* + * if (pkey) { + * + * save AMR -> stack; + * if (kuap) { + * if (AMR != BLOCKED) + * KUAP_BLOCKED -> AMR; + * } + * if (from_user) { + * save IAMR -> stack; + * if (kuep) { + * KUEP_BLOCKED ->IAMR + * } + * } + * return; + * } + * + * if (kuap) { + * if (from_kernel) { + * save AMR -> stack; + * if (AMR != BLOCKED) + * KUAP_BLOCKED -> AMR; + * } + * + * } + */ +.macro kuap_save_amr_and_lock gpr1, gpr2, use_cr, msr_pr_cr +#if defined(CONFIG_PPC_PKEY) + + /* + * if both pkey and kuap is disabled, nothing to do + */ + BEGIN_MMU_FTR_SECTION_NESTED(68) + b 100f // skip_save_amr + END_MMU_FTR_SECTION_NESTED_IFCLR(MMU_FTR_PKEY | MMU_FTR_BOOK3S_KUAP, 68) + + /* + * if pkey is disabled and we are entering from userspace + * don't do anything. + */ + BEGIN_MMU_FTR_SECTION_NESTED(67) + .ifnb \msr_pr_cr + /* + * Without pkey we are not changing AMR outside the kernel + * hence skip this completely. + */ + bne \msr_pr_cr, 100f // from userspace + .endif + END_MMU_FTR_SECTION_NESTED_IFCLR(MMU_FTR_PKEY, 67) + + /* + * pkey is enabled or pkey is disabled but entering from kernel + */ + mfspr \gpr1, SPRN_AMR + std \gpr1, STACK_REGS_AMR(r1) + + /* + * update kernel AMR with AMR_KUAP_BLOCKED only + * if KUAP feature is enabled + */ + BEGIN_MMU_FTR_SECTION_NESTED(69) + LOAD_REG_IMMEDIATE(\gpr2, AMR_KUAP_BLOCKED) + cmpd \use_cr, \gpr1, \gpr2 + beq \use_cr, 102f + /* + * We don't isync here because we very recently entered via an interrupt + */ + mtspr SPRN_AMR, \gpr2 + isync +102: + END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_BOOK3S_KUAP, 69) + + /* + * if entering from kernel we don't need save IAMR + */ + .ifnb \msr_pr_cr + beq \msr_pr_cr, 100f // from kernel space + mfspr \gpr1, SPRN_IAMR + std \gpr1, STACK_REGS_IAMR(r1) + + /* + * update kernel IAMR with AMR_KUEP_BLOCKED only + * if KUEP feature is enabled + */ + BEGIN_MMU_FTR_SECTION_NESTED(70) + LOAD_REG_IMMEDIATE(\gpr2, AMR_KUEP_BLOCKED) + mtspr SPRN_IAMR, \gpr2 + isync + END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_BOOK3S_KUEP, 70) + .endif + +100: // skip_save_amr +#endif +.endm + +#else /* !__ASSEMBLY__ */ + +#include <linux/jump_label.h> + +DECLARE_STATIC_KEY_FALSE(uaccess_flush_key); + +#ifdef CONFIG_PPC_PKEY + +#include <asm/mmu.h> +#include <asm/ptrace.h> + +/* + * For kernel thread that doesn't have thread.regs return + * default AMR/IAMR values. + */ +static inline u64 current_thread_amr(void) +{ + if (current->thread.regs) + return current->thread.regs->amr; + return AMR_KUAP_BLOCKED; +} + +static inline u64 current_thread_iamr(void) +{ + if (current->thread.regs) + return current->thread.regs->iamr; + return AMR_KUEP_BLOCKED; +} +#endif /* CONFIG_PPC_PKEY */ + +#ifdef CONFIG_PPC_KUAP + +static inline void kuap_user_restore(struct pt_regs *regs) +{ + bool restore_amr = false, restore_iamr = false; + unsigned long amr, iamr; + + if (!mmu_has_feature(MMU_FTR_PKEY)) + return; + + if (!mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) { + amr = mfspr(SPRN_AMR); + if (amr != regs->amr) + restore_amr = true; + } else { + restore_amr = true; + } + + if (!mmu_has_feature(MMU_FTR_BOOK3S_KUEP)) { + iamr = mfspr(SPRN_IAMR); + if (iamr != regs->iamr) + restore_iamr = true; + } else { + restore_iamr = true; + } + + + if (restore_amr || restore_iamr) { + isync(); + if (restore_amr) + mtspr(SPRN_AMR, regs->amr); + if (restore_iamr) + mtspr(SPRN_IAMR, regs->iamr); + } + /* + * No isync required here because we are about to rfi + * back to previous context before any user accesses + * would be made, which is a CSI. + */ +} + +static inline void kuap_kernel_restore(struct pt_regs *regs, + unsigned long amr) +{ + if (mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) { + if (unlikely(regs->amr != amr)) { + isync(); + mtspr(SPRN_AMR, regs->amr); + /* + * No isync required here because we are about to rfi + * back to previous context before any user accesses + * would be made, which is a CSI. + */ + } + } + /* + * No need to restore IAMR when returning to kernel space. + */ +} + +static inline unsigned long kuap_get_and_check_amr(void) +{ + if (mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) { + unsigned long amr = mfspr(SPRN_AMR); + if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG)) /* kuap_check_amr() */ + WARN_ON_ONCE(amr != AMR_KUAP_BLOCKED); + return amr; + } + return 0; +} + +#else /* CONFIG_PPC_PKEY */ + +static inline void kuap_user_restore(struct pt_regs *regs) +{ +} + +static inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long amr) +{ +} + +static inline unsigned long kuap_get_and_check_amr(void) +{ + return 0; +} + +#endif /* CONFIG_PPC_PKEY */ + + +#ifdef CONFIG_PPC_KUAP + +static inline void kuap_check_amr(void) +{ + if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG) && mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) + WARN_ON_ONCE(mfspr(SPRN_AMR) != AMR_KUAP_BLOCKED); +} + +/* + * We support individually allowing read or write, but we don't support nesting + * because that would require an expensive read/modify write of the AMR. + */ + +static inline unsigned long get_kuap(void) +{ + /* + * We return AMR_KUAP_BLOCKED when we don't support KUAP because + * prevent_user_access_return needs to return AMR_KUAP_BLOCKED to + * cause restore_user_access to do a flush. + * + * This has no effect in terms of actually blocking things on hash, + * so it doesn't break anything. + */ + if (!early_mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) + return AMR_KUAP_BLOCKED; + + return mfspr(SPRN_AMR); +} + +static inline void set_kuap(unsigned long value) +{ + if (!early_mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) + return; + + /* + * ISA v3.0B says we need a CSI (Context Synchronising Instruction) both + * before and after the move to AMR. See table 6 on page 1134. + */ + isync(); + mtspr(SPRN_AMR, value); + isync(); +} + +static inline bool bad_kuap_fault(struct pt_regs *regs, unsigned long address, + bool is_write) +{ + if (!mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) + return false; + /* + * For radix this will be a storage protection fault (DSISR_PROTFAULT). + * For hash this will be a key fault (DSISR_KEYFAULT) + */ + /* + * We do have exception table entry, but accessing the + * userspace results in fault. This could be because we + * didn't unlock the AMR or access is denied by userspace + * using a key value that blocks access. We are only interested + * in catching the use case of accessing without unlocking + * the AMR. Hence check for BLOCK_WRITE/READ against AMR. + */ + if (is_write) { + return (regs->amr & AMR_KUAP_BLOCK_WRITE) == AMR_KUAP_BLOCK_WRITE; + } + return (regs->amr & AMR_KUAP_BLOCK_READ) == AMR_KUAP_BLOCK_READ; +} + +static __always_inline void allow_user_access(void __user *to, const void __user *from, + unsigned long size, unsigned long dir) +{ + unsigned long thread_amr = 0; + + // This is written so we can resolve to a single case at build time + BUILD_BUG_ON(!__builtin_constant_p(dir)); + + if (mmu_has_feature(MMU_FTR_PKEY)) + thread_amr = current_thread_amr(); + + if (dir == KUAP_READ) + set_kuap(thread_amr | AMR_KUAP_BLOCK_WRITE); + else if (dir == KUAP_WRITE) + set_kuap(thread_amr | AMR_KUAP_BLOCK_READ); + else if (dir == KUAP_READ_WRITE) + set_kuap(thread_amr); + else + BUILD_BUG(); +} + +#else /* CONFIG_PPC_KUAP */ + +static inline unsigned long get_kuap(void) +{ + return AMR_KUAP_BLOCKED; +} + +static inline void set_kuap(unsigned long value) { } + +static __always_inline void allow_user_access(void __user *to, const void __user *from, + unsigned long size, unsigned long dir) +{ } + +#endif /* !CONFIG_PPC_KUAP */ + +static inline void prevent_user_access(void __user *to, const void __user *from, + unsigned long size, unsigned long dir) +{ + set_kuap(AMR_KUAP_BLOCKED); + if (static_branch_unlikely(&uaccess_flush_key)) + do_uaccess_flush(); +} + +static inline unsigned long prevent_user_access_return(void) +{ + unsigned long flags = get_kuap(); + + set_kuap(AMR_KUAP_BLOCKED); + if (static_branch_unlikely(&uaccess_flush_key)) + do_uaccess_flush(); + + return flags; +} + +static inline void restore_user_access(unsigned long flags) +{ + set_kuap(flags); + if (static_branch_unlikely(&uaccess_flush_key) && flags == AMR_KUAP_BLOCKED) + do_uaccess_flush(); +} +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_POWERPC_BOOK3S_64_KUP_H */ diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h index 683a9c7d1b03..066b1d34c7bc 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h +++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h @@ -452,6 +452,7 @@ static inline unsigned long hpt_hash(unsigned long vpn, #define HPTE_LOCAL_UPDATE 0x1 #define HPTE_NOHPTE_UPDATE 0x2 +#define HPTE_USE_KERNEL_KEY 0x4 extern int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, pte_t *ptep, unsigned long trap, @@ -842,6 +843,32 @@ static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize) unsigned htab_shift_for_mem_size(unsigned long mem_size); -#endif /* __ASSEMBLY__ */ +enum slb_index { + LINEAR_INDEX = 0, /* Kernel linear map (0xc000000000000000) */ + KSTACK_INDEX = 1, /* Kernel stack map */ +}; +#define slb_esid_mask(ssize) \ + (((ssize) == MMU_SEGSIZE_256M) ? ESID_MASK : ESID_MASK_1T) + +static inline unsigned long mk_esid_data(unsigned long ea, int ssize, + enum slb_index index) +{ + return (ea & slb_esid_mask(ssize)) | SLB_ESID_V | index; +} + +static inline unsigned long __mk_vsid_data(unsigned long vsid, int ssize, + unsigned long flags) +{ + return (vsid << slb_vsid_shift(ssize)) | flags | + ((unsigned long)ssize << SLB_VSID_SSIZE_SHIFT); +} + +static inline unsigned long mk_vsid_data(unsigned long ea, int ssize, + unsigned long flags) +{ + return __mk_vsid_data(get_kernel_vsid(ea, ssize), ssize, flags); +} + +#endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_BOOK3S_64_MMU_HASH_H_ */ diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h index 750918451dd2..995bbcdd0ef8 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu.h +++ b/arch/powerpc/include/asm/book3s/64/mmu.h @@ -111,7 +111,7 @@ typedef struct { struct hash_mm_context *hash_context; - unsigned long vdso_base; + void __user *vdso; /* * pagetable fragment support */ @@ -199,7 +199,7 @@ extern int mmu_io_psize; void mmu_early_init_devtree(void); void hash__early_init_devtree(void); void radix__early_init_devtree(void); -#ifdef CONFIG_PPC_MEM_KEYS +#ifdef CONFIG_PPC_PKEY void pkey_early_init_devtree(void); #else static inline void pkey_early_init_devtree(void) {} diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index cd3feeac6e87..a39886681629 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -1231,13 +1231,28 @@ static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b) return hash__pmd_same(pmd_a, pmd_b); } -static inline pmd_t pmd_mkhuge(pmd_t pmd) +static inline pmd_t __pmd_mkhuge(pmd_t pmd) { if (radix_enabled()) return radix__pmd_mkhuge(pmd); return hash__pmd_mkhuge(pmd); } +/* + * pfn_pmd return a pmd_t that can be used as pmd pte entry. + */ +static inline pmd_t pmd_mkhuge(pmd_t pmd) +{ +#ifdef CONFIG_DEBUG_VM + if (radix_enabled()) + WARN_ON((pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE)) == 0); + else + WARN_ON((pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE | H_PAGE_THP_HUGE)) != + cpu_to_be64(_PAGE_PTE | H_PAGE_THP_HUGE)); +#endif + return pmd; +} + #define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS extern int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp, diff --git a/arch/powerpc/include/asm/book3s/64/pkeys.h b/arch/powerpc/include/asm/book3s/64/pkeys.h index b7d9f4267bcd..3b8640498f5b 100644 --- a/arch/powerpc/include/asm/book3s/64/pkeys.h +++ b/arch/powerpc/include/asm/book3s/64/pkeys.h @@ -6,6 +6,8 @@ #include <asm/book3s/64/hash-pkey.h> extern u64 __ro_after_init default_uamor; +extern u64 __ro_after_init default_amr; +extern u64 __ro_after_init default_iamr; static inline u64 vmflag_to_pte_pkey_bits(u64 vm_flags) { diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h index 338f36cd9934..464f8ca8a5c9 100644 --- a/arch/powerpc/include/asm/bug.h +++ b/arch/powerpc/include/asm/bug.h @@ -12,7 +12,7 @@ #ifdef CONFIG_DEBUG_BUGVERBOSE .macro EMIT_BUG_ENTRY addr,file,line,flags .section __bug_table,"aw" -5001: PPC_LONG \addr, 5002f +5001: .4byte \addr - 5001b, 5002f - 5001b .short \line, \flags .org 5001b+BUG_ENTRY_SIZE .previous @@ -23,7 +23,7 @@ #else .macro EMIT_BUG_ENTRY addr,file,line,flags .section __bug_table,"aw" -5001: PPC_LONG \addr +5001: .4byte \addr - 5001b .short \flags .org 5001b+BUG_ENTRY_SIZE .previous @@ -36,14 +36,14 @@ #ifdef CONFIG_DEBUG_BUGVERBOSE #define _EMIT_BUG_ENTRY \ ".section __bug_table,\"aw\"\n" \ - "2:\t" PPC_LONG "1b, %0\n" \ + "2:\t.4byte 1b - 2b, %0 - 2b\n" \ "\t.short %1, %2\n" \ ".org 2b+%3\n" \ ".previous\n" #else #define _EMIT_BUG_ENTRY \ ".section __bug_table,\"aw\"\n" \ - "2:\t" PPC_LONG "1b\n" \ + "2:\t.4byte 1b - 2b\n" \ "\t.short %2\n" \ ".org 2b+%3\n" \ ".previous\n" @@ -113,6 +113,7 @@ struct pt_regs; extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long); extern void bad_page_fault(struct pt_regs *, unsigned long, int); +void __bad_page_fault(struct pt_regs *regs, unsigned long address, int sig); extern void _exception(int, struct pt_regs *, int, unsigned long); extern void _exception_pkey(struct pt_regs *, unsigned long, int); extern void die(const char *, struct pt_regs *, long); diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h index 82f099ba2411..d5da7ddbf0fc 100644 --- a/arch/powerpc/include/asm/checksum.h +++ b/arch/powerpc/include/asm/checksum.h @@ -163,7 +163,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) */ __wsum __csum_partial(const void *buff, int len, __wsum sum); -static inline __wsum csum_partial(const void *buff, int len, __wsum sum) +static __always_inline __wsum csum_partial(const void *buff, int len, __wsum sum) { if (__builtin_constant_p(len) && len <= 16 && (len & 1) == 0) { if (len == 2) diff --git a/arch/powerpc/include/asm/clocksource.h b/arch/powerpc/include/asm/clocksource.h new file mode 100644 index 000000000000..0a26ef13a34a --- /dev/null +++ b/arch/powerpc/include/asm/clocksource.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_CLOCKSOURCE_H +#define _ASM_POWERPC_CLOCKSOURCE_H + +#include <asm/vdso/clocksource.h> + +#endif /* _ASM_POWERPC_CLOCKSOURCE_H */ diff --git a/arch/powerpc/include/asm/cpm1.h b/arch/powerpc/include/asm/cpm1.h index a116fe931789..3bdd74739cb8 100644 --- a/arch/powerpc/include/asm/cpm1.h +++ b/arch/powerpc/include/asm/cpm1.h @@ -68,6 +68,7 @@ extern void cpm_reset(void); #define PROFF_SPI ((uint)0x0180) #define PROFF_SCC3 ((uint)0x0200) #define PROFF_SMC1 ((uint)0x0280) +#define PROFF_DSP1 ((uint)0x02c0) #define PROFF_SCC4 ((uint)0x0300) #define PROFF_SMC2 ((uint)0x0380) diff --git a/arch/powerpc/include/asm/cpu_setup_power.h b/arch/powerpc/include/asm/cpu_setup_power.h new file mode 100644 index 000000000000..24be9131f803 --- /dev/null +++ b/arch/powerpc/include/asm/cpu_setup_power.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2020 IBM Corporation + */ +void __setup_cpu_power7(unsigned long offset, struct cpu_spec *spec); +void __restore_cpu_power7(void); +void __setup_cpu_power8(unsigned long offset, struct cpu_spec *spec); +void __restore_cpu_power8(void); +void __setup_cpu_power9(unsigned long offset, struct cpu_spec *spec); +void __restore_cpu_power9(void); +void __setup_cpu_power10(unsigned long offset, struct cpu_spec *spec); +void __restore_cpu_power10(void); diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 3d2f94afc13a..5f21a5bab467 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -41,7 +41,6 @@ extern int machine_check_4xx(struct pt_regs *regs); extern int machine_check_440A(struct pt_regs *regs); extern int machine_check_e500mc(struct pt_regs *regs); extern int machine_check_e500(struct pt_regs *regs); -extern int machine_check_e200(struct pt_regs *regs); extern int machine_check_47x(struct pt_regs *regs); int machine_check_8xx(struct pt_regs *regs); int machine_check_83xx(struct pt_regs *regs); @@ -137,7 +136,7 @@ static inline void cpu_feature_keys_init(void) { } #define CPU_FTR_DBELL ASM_CONST(0x00000004) #define CPU_FTR_CAN_NAP ASM_CONST(0x00000008) #define CPU_FTR_DEBUG_LVL_EXC ASM_CONST(0x00000010) -#define CPU_FTR_NODSISRALIGN ASM_CONST(0x00000020) +// ASM_CONST(0x00000020) Free #define CPU_FTR_FPU_UNAVAILABLE ASM_CONST(0x00000040) #define CPU_FTR_LWSYNC ASM_CONST(0x00000080) #define CPU_FTR_NOEXECUTE ASM_CONST(0x00000100) @@ -219,9 +218,7 @@ static inline void cpu_feature_keys_init(void) { } #ifndef __ASSEMBLY__ -#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN) - -#define MMU_FTR_PPCAS_ARCH_V2 (MMU_FTR_TLBIEL | MMU_FTR_16M_PAGE) +#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_NOEXECUTE) /* We only set the altivec features if the kernel was compiled with altivec * support @@ -369,7 +366,7 @@ static inline void cpu_feature_keys_init(void) { } CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX) #define CPU_FTRS_82XX (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_NOEXECUTE) #define CPU_FTRS_G2_LE (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \ - CPU_FTR_MAYBE_CAN_NAP) + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NOEXECUTE) #define CPU_FTRS_E300 (CPU_FTR_MAYBE_CAN_DOZE | \ CPU_FTR_MAYBE_CAN_NAP | \ CPU_FTR_COMMON | CPU_FTR_NOEXECUTE) @@ -378,38 +375,33 @@ static inline void cpu_feature_keys_init(void) { } CPU_FTR_COMMON | CPU_FTR_FPU_UNAVAILABLE | CPU_FTR_NOEXECUTE) #define CPU_FTRS_CLASSIC32 (CPU_FTR_COMMON) #define CPU_FTRS_8XX (CPU_FTR_NOEXECUTE) -#define CPU_FTRS_40X (CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE) -#define CPU_FTRS_44X (CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE) -#define CPU_FTRS_440x6 (CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE | \ +#define CPU_FTRS_40X (CPU_FTR_NOEXECUTE) +#define CPU_FTRS_44X (CPU_FTR_NOEXECUTE) +#define CPU_FTRS_440x6 (CPU_FTR_NOEXECUTE | \ CPU_FTR_INDEXED_DCR) #define CPU_FTRS_47X (CPU_FTRS_440x6) -#define CPU_FTRS_E200 (CPU_FTR_SPE_COMP | \ - CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \ - CPU_FTR_NOEXECUTE | \ - CPU_FTR_DEBUG_LVL_EXC) #define CPU_FTRS_E500 (CPU_FTR_MAYBE_CAN_DOZE | \ - CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \ + CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | \ CPU_FTR_NOEXECUTE) #define CPU_FTRS_E500_2 (CPU_FTR_MAYBE_CAN_DOZE | \ CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | \ - CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE) -#define CPU_FTRS_E500MC (CPU_FTR_NODSISRALIGN | \ + CPU_FTR_NOEXECUTE) +#define CPU_FTRS_E500MC ( \ CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ CPU_FTR_DBELL | CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV) /* * e5500/e6500 erratum A-006958 is a timebase bug that can use the * same workaround as CPU_FTR_CELL_TB_BUG. */ -#define CPU_FTRS_E5500 (CPU_FTR_NODSISRALIGN | \ +#define CPU_FTRS_E5500 ( \ CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_CELL_TB_BUG) -#define CPU_FTRS_E6500 (CPU_FTR_NODSISRALIGN | \ +#define CPU_FTRS_E6500 ( \ CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP | \ CPU_FTR_CELL_TB_BUG | CPU_FTR_SMT) -#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) /* 64-bit CPUs */ #define CPU_FTRS_PPC970 (CPU_FTR_LWSYNC | \ @@ -489,7 +481,7 @@ static inline void cpu_feature_keys_init(void) { } CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_DABRX) #define CPU_FTRS_COMPATIBLE (CPU_FTR_PPCAS_ARCH_V2) -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC_BOOK3E #define CPU_FTRS_POSSIBLE (CPU_FTRS_E6500 | CPU_FTRS_E5500) #else @@ -510,18 +502,19 @@ static inline void cpu_feature_keys_init(void) { } #else enum { CPU_FTRS_POSSIBLE = -#ifdef CONFIG_PPC_BOOK3S_32 - CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU | +#ifdef CONFIG_PPC_BOOK3S_604 + CPU_FTRS_604 | CPU_FTRS_740_NOTAU | CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 | CPU_FTRS_750FX2 | CPU_FTRS_750FX | CPU_FTRS_750GX | CPU_FTRS_7400_NOTAU | CPU_FTRS_7400 | CPU_FTRS_7450_20 | CPU_FTRS_7450_21 | CPU_FTRS_7450_23 | CPU_FTRS_7455_1 | CPU_FTRS_7455_20 | CPU_FTRS_7455 | CPU_FTRS_7447_10 | - CPU_FTRS_7447 | CPU_FTRS_7447A | CPU_FTRS_82XX | - CPU_FTRS_G2_LE | CPU_FTRS_E300 | CPU_FTRS_E300C2 | + CPU_FTRS_7447 | CPU_FTRS_7447A | CPU_FTRS_CLASSIC32 | -#else - CPU_FTRS_GENERIC_32 | +#endif +#ifdef CONFIG_PPC_BOOK3S_603 + CPU_FTRS_603 | CPU_FTRS_82XX | + CPU_FTRS_G2_LE | CPU_FTRS_E300 | CPU_FTRS_E300C2 | #endif #ifdef CONFIG_PPC_8xx CPU_FTRS_8XX | @@ -529,14 +522,10 @@ enum { #ifdef CONFIG_40x CPU_FTRS_40X | #endif -#ifdef CONFIG_44x - CPU_FTRS_44X | CPU_FTRS_440x6 | -#endif #ifdef CONFIG_PPC_47x CPU_FTRS_47X | CPU_FTR_476_DD2 | -#endif -#ifdef CONFIG_E200 - CPU_FTRS_E200 | +#elif defined(CONFIG_44x) + CPU_FTRS_44X | CPU_FTRS_440x6 | #endif #ifdef CONFIG_E500 CPU_FTRS_E500 | CPU_FTRS_E500_2 | @@ -548,7 +537,7 @@ enum { }; #endif /* __powerpc64__ */ -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC_BOOK3E #define CPU_FTRS_ALWAYS (CPU_FTRS_E6500 & CPU_FTRS_E5500) #else @@ -557,7 +546,6 @@ enum { #define CPU_FTRS_DT_CPU_BASE \ (CPU_FTR_LWSYNC | \ CPU_FTR_FPU_UNAVAILABLE | \ - CPU_FTR_NODSISRALIGN | \ CPU_FTR_NOEXECUTE | \ CPU_FTR_COHERENT_ICACHE | \ CPU_FTR_STCX_CHECKS_ADDRESS | \ @@ -586,18 +574,19 @@ enum { #else enum { CPU_FTRS_ALWAYS = -#ifdef CONFIG_PPC_BOOK3S_32 - CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU & +#ifdef CONFIG_PPC_BOOK3S_604 + CPU_FTRS_604 & CPU_FTRS_740_NOTAU & CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 & CPU_FTRS_750FX2 & CPU_FTRS_750FX & CPU_FTRS_750GX & CPU_FTRS_7400_NOTAU & CPU_FTRS_7400 & CPU_FTRS_7450_20 & CPU_FTRS_7450_21 & CPU_FTRS_7450_23 & CPU_FTRS_7455_1 & CPU_FTRS_7455_20 & CPU_FTRS_7455 & CPU_FTRS_7447_10 & - CPU_FTRS_7447 & CPU_FTRS_7447A & CPU_FTRS_82XX & - CPU_FTRS_G2_LE & CPU_FTRS_E300 & CPU_FTRS_E300C2 & + CPU_FTRS_7447 & CPU_FTRS_7447A & CPU_FTRS_CLASSIC32 & -#else - CPU_FTRS_GENERIC_32 & +#endif +#ifdef CONFIG_PPC_BOOK3S_603 + CPU_FTRS_603 & CPU_FTRS_82XX & + CPU_FTRS_G2_LE & CPU_FTRS_E300 & CPU_FTRS_E300C2 & #endif #ifdef CONFIG_PPC_8xx CPU_FTRS_8XX & @@ -605,12 +594,11 @@ enum { #ifdef CONFIG_40x CPU_FTRS_40X & #endif -#ifdef CONFIG_44x +#ifdef CONFIG_PPC_47x + CPU_FTRS_47X & +#elif defined(CONFIG_44x) CPU_FTRS_44X & CPU_FTRS_440x6 & #endif -#ifdef CONFIG_E200 - CPU_FTRS_E200 & -#endif #ifdef CONFIG_E500 CPU_FTRS_E500 & CPU_FTRS_E500_2 & #endif diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h index 53ed2ca40151..b8425e3cfd81 100644 --- a/arch/powerpc/include/asm/elf.h +++ b/arch/powerpc/include/asm/elf.h @@ -168,8 +168,8 @@ do { \ /* Cache size items */ \ NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize); \ NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \ - NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \ - VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso_base); \ + NEW_AUX_ENT(AT_UCACHEBSIZE, 0); \ + VDSO_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long)current->mm->context.vdso);\ ARCH_DLINFO_CACHE_GEOMETRY; \ } while (0) diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 1d32b174ab6a..c1a8aac01cf9 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -63,6 +63,12 @@ nop; \ nop; +#define SCV_ENTRY_FLUSH_SLOT \ + SCV_ENTRY_FLUSH_FIXUP_SECTION; \ + nop; \ + nop; \ + nop; + /* * r10 must be free to use, r13 must be paca */ @@ -71,6 +77,13 @@ ENTRY_FLUSH_SLOT /* + * r10, ctr must be free to use, r13 must be paca + */ +#define SCV_INTERRUPT_TO_KERNEL \ + STF_ENTRY_BARRIER_SLOT; \ + SCV_ENTRY_FLUSH_SLOT + +/* * Macros for annotating the expected destination of (h)rfid * * The nop instructions allow us to insert one or more instructions to flush the diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h index fbd406cd6916..ac605fc369c4 100644 --- a/arch/powerpc/include/asm/feature-fixups.h +++ b/arch/powerpc/include/asm/feature-fixups.h @@ -36,6 +36,24 @@ label##2: \ .align 2; \ label##3: + +#ifndef CONFIG_CC_IS_CLANG +#define CHECK_ALT_SIZE(else_size, body_size) \ + .ifgt (else_size) - (body_size); \ + .error "Feature section else case larger than body"; \ + .endif; +#else +/* + * If we use the ifgt syntax above, clang's assembler complains about the + * expression being non-absolute when the code appears in an inline assembly + * statement. + * As a workaround use an .org directive that has no effect if the else case + * instructions are smaller than the body, but fails otherwise. + */ +#define CHECK_ALT_SIZE(else_size, body_size) \ + .org . + ((else_size) > (body_size)); +#endif + #define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect) \ label##4: \ .popsection; \ @@ -48,9 +66,7 @@ label##5: \ FTR_ENTRY_OFFSET label##2b-label##5b; \ FTR_ENTRY_OFFSET label##3b-label##5b; \ FTR_ENTRY_OFFSET label##4b-label##5b; \ - .ifgt (label##4b- label##3b)-(label##2b- label##1b); \ - .error "Feature section else case larger than body"; \ - .endif; \ + CHECK_ALT_SIZE((label##4b-label##3b), (label##2b-label##1b)); \ .popsection; @@ -100,6 +116,9 @@ label##5: \ #define END_MMU_FTR_SECTION_NESTED_IFSET(msk, label) \ END_MMU_FTR_SECTION_NESTED((msk), (msk), label) +#define END_MMU_FTR_SECTION_NESTED_IFCLR(msk, label) \ + END_MMU_FTR_SECTION_NESTED((msk), 0, label) + #define END_MMU_FTR_SECTION_IFSET(msk) END_MMU_FTR_SECTION((msk), (msk)) #define END_MMU_FTR_SECTION_IFCLR(msk) END_MMU_FTR_SECTION((msk), 0) @@ -221,6 +240,14 @@ label##3: \ FTR_ENTRY_OFFSET 957b-958b; \ .popsection; +#define SCV_ENTRY_FLUSH_FIXUP_SECTION \ +957: \ + .pushsection __scv_entry_flush_fixup,"a"; \ + .align 2; \ +958: \ + FTR_ENTRY_OFFSET 957b-958b; \ + .popsection; + #define RFI_FLUSH_FIXUP_SECTION \ 951: \ .pushsection __rfi_flush_fixup,"a"; \ @@ -254,10 +281,12 @@ label##3: \ extern long stf_barrier_fallback; extern long entry_flush_fallback; +extern long scv_entry_flush_fallback; extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup; extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup; extern long __start___uaccess_flush_fixup, __stop___uaccess_flush_fixup; extern long __start___entry_flush_fixup, __stop___entry_flush_fixup; +extern long __start___scv_entry_flush_fixup, __stop___scv_entry_flush_fixup; extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup; extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup; extern long __start__btb_flush_fixup, __stop__btb_flush_fixup; diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h index 0b295bdb201e..aa6a5ef5d483 100644 --- a/arch/powerpc/include/asm/firmware.h +++ b/arch/powerpc/include/asm/firmware.h @@ -134,12 +134,6 @@ extern int ibm_nmi_interlock_token; extern unsigned int __start___fw_ftr_fixup, __stop___fw_ftr_fixup; -#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_KVM_GUEST) -bool is_kvm_guest(void); -#else -static inline bool is_kvm_guest(void) { return false; } -#endif - #ifdef CONFIG_PPC_PSERIES void pseries_probe_fw_features(void); #else diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h index 80a5ae771c65..c0fcd1bbdba9 100644 --- a/arch/powerpc/include/asm/highmem.h +++ b/arch/powerpc/include/asm/highmem.h @@ -58,6 +58,8 @@ extern pte_t *pkmap_page_table; #define flush_cache_kmaps() flush_cache_all() +#define arch_kmap_local_set_pte(mm, vaddr, ptep, ptev) \ + __set_pte_at(mm, vaddr, ptep, ptev, 1) #define arch_kmap_local_post_map(vaddr, pteval) \ local_flush_tlb_page(NULL, vaddr) #define arch_kmap_local_post_unmap(vaddr) \ diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index c1fbccb04390..c98f5141e3fc 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -155,6 +155,14 @@ #define H_VASI_RESUMED 5 #define H_VASI_COMPLETED 6 +/* VASI signal codes. Only the Cancel code is valid for H_VASI_SIGNAL. */ +#define H_VASI_SIGNAL_CANCEL 1 +#define H_VASI_SIGNAL_ABORT 2 +#define H_VASI_SIGNAL_SUSPEND 3 +#define H_VASI_SIGNAL_COMPLETE 4 +#define H_VASI_SIGNAL_ENABLE 5 +#define H_VASI_SIGNAL_FAILOVER 6 + /* Each control block has to be on a 4K boundary */ #define H_CB_ALIGNMENT 4096 @@ -261,6 +269,7 @@ #define H_ADD_CONN 0x284 #define H_DEL_CONN 0x288 #define H_JOIN 0x298 +#define H_VASI_SIGNAL 0x2A0 #define H_VASI_STATE 0x2A4 #define H_VIOCTL 0x2A8 #define H_ENABLE_CRQ 0x2B0 diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index 58635960403c..273edd208ec5 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -122,7 +122,7 @@ static inline u##size name(const volatile u##size __iomem *addr) \ { \ u##size ret; \ __asm__ __volatile__("sync;"#insn"%U1%X1 %0,%1;twi 0,%0,0;isync"\ - : "=r" (ret) : "m" (*addr) : "memory"); \ + : "=r" (ret) : "m"UPD_CONSTR (*addr) : "memory"); \ return ret; \ } @@ -130,7 +130,7 @@ static inline u##size name(const volatile u##size __iomem *addr) \ static inline void name(volatile u##size __iomem *addr, u##size val) \ { \ __asm__ __volatile__("sync;"#insn"%U0%X0 %1,%0" \ - : "=m" (*addr) : "r" (val) : "memory"); \ + : "=m"UPD_CONSTR (*addr) : "r" (val) : "memory"); \ mmiowb_set_pending(); \ } @@ -302,41 +302,56 @@ static inline unsigned char __raw_readb(const volatile void __iomem *addr) { return *(volatile unsigned char __force *)PCI_FIX_ADDR(addr); } +#define __raw_readb __raw_readb + static inline unsigned short __raw_readw(const volatile void __iomem *addr) { return *(volatile unsigned short __force *)PCI_FIX_ADDR(addr); } +#define __raw_readw __raw_readw + static inline unsigned int __raw_readl(const volatile void __iomem *addr) { return *(volatile unsigned int __force *)PCI_FIX_ADDR(addr); } +#define __raw_readl __raw_readl + static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr) { *(volatile unsigned char __force *)PCI_FIX_ADDR(addr) = v; } +#define __raw_writeb __raw_writeb + static inline void __raw_writew(unsigned short v, volatile void __iomem *addr) { *(volatile unsigned short __force *)PCI_FIX_ADDR(addr) = v; } +#define __raw_writew __raw_writew + static inline void __raw_writel(unsigned int v, volatile void __iomem *addr) { *(volatile unsigned int __force *)PCI_FIX_ADDR(addr) = v; } +#define __raw_writel __raw_writel #ifdef __powerpc64__ static inline unsigned long __raw_readq(const volatile void __iomem *addr) { return *(volatile unsigned long __force *)PCI_FIX_ADDR(addr); } +#define __raw_readq __raw_readq + static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr) { *(volatile unsigned long __force *)PCI_FIX_ADDR(addr) = v; } +#define __raw_writeq __raw_writeq static inline void __raw_writeq_be(unsigned long v, volatile void __iomem *addr) { __raw_writeq((__force unsigned long)cpu_to_be64(v), addr); } +#define __raw_writeq_be __raw_writeq_be /* * Real mode versions of the above. Those instructions are only supposed @@ -609,10 +624,37 @@ static inline void name at \ /* Some drivers check for the presence of readq & writeq with * a #ifdef, so we make them happy here. */ +#define readb readb +#define readw readw +#define readl readl +#define writeb writeb +#define writew writew +#define writel writel +#define readsb readsb +#define readsw readsw +#define readsl readsl +#define writesb writesb +#define writesw writesw +#define writesl writesl +#define inb inb +#define inw inw +#define inl inl +#define outb outb +#define outw outw +#define outl outl +#define insb insb +#define insw insw +#define insl insl +#define outsb outsb +#define outsw outsw +#define outsl outsl #ifdef __powerpc64__ #define readq readq #define writeq writeq #endif +#define memset_io memset_io +#define memcpy_fromio memcpy_fromio +#define memcpy_toio memcpy_toio /* * Convert a physical pointer to a virtual kernel pointer for /dev/mem @@ -637,7 +679,106 @@ static inline void name at \ #define writel_relaxed(v, addr) writel(v, addr) #define writeq_relaxed(v, addr) writeq(v, addr) +#ifdef CONFIG_GENERIC_IOMAP #include <asm-generic/iomap.h> +#else +/* + * Here comes the implementation of the IOMAP interfaces. + */ +static inline unsigned int ioread16be(const void __iomem *addr) +{ + return readw_be(addr); +} +#define ioread16be ioread16be + +static inline unsigned int ioread32be(const void __iomem *addr) +{ + return readl_be(addr); +} +#define ioread32be ioread32be + +#ifdef __powerpc64__ +static inline u64 ioread64_lo_hi(const void __iomem *addr) +{ + return readq(addr); +} +#define ioread64_lo_hi ioread64_lo_hi + +static inline u64 ioread64_hi_lo(const void __iomem *addr) +{ + return readq(addr); +} +#define ioread64_hi_lo ioread64_hi_lo + +static inline u64 ioread64be(const void __iomem *addr) +{ + return readq_be(addr); +} +#define ioread64be ioread64be + +static inline u64 ioread64be_lo_hi(const void __iomem *addr) +{ + return readq_be(addr); +} +#define ioread64be_lo_hi ioread64be_lo_hi + +static inline u64 ioread64be_hi_lo(const void __iomem *addr) +{ + return readq_be(addr); +} +#define ioread64be_hi_lo ioread64be_hi_lo +#endif /* __powerpc64__ */ + +static inline void iowrite16be(u16 val, void __iomem *addr) +{ + writew_be(val, addr); +} +#define iowrite16be iowrite16be + +static inline void iowrite32be(u32 val, void __iomem *addr) +{ + writel_be(val, addr); +} +#define iowrite32be iowrite32be + +#ifdef __powerpc64__ +static inline void iowrite64_lo_hi(u64 val, void __iomem *addr) +{ + writeq(val, addr); +} +#define iowrite64_lo_hi iowrite64_lo_hi + +static inline void iowrite64_hi_lo(u64 val, void __iomem *addr) +{ + writeq(val, addr); +} +#define iowrite64_hi_lo iowrite64_hi_lo + +static inline void iowrite64be(u64 val, void __iomem *addr) +{ + writeq_be(val, addr); +} +#define iowrite64be iowrite64be + +static inline void iowrite64be_lo_hi(u64 val, void __iomem *addr) +{ + writeq_be(val, addr); +} +#define iowrite64be_lo_hi iowrite64be_lo_hi + +static inline void iowrite64be_hi_lo(u64 val, void __iomem *addr) +{ + writeq_be(val, addr); +} +#define iowrite64be_hi_lo iowrite64be_hi_lo +#endif /* __powerpc64__ */ + +struct pci_dev; +void pci_iounmap(struct pci_dev *dev, void __iomem *addr); +#define pci_iounmap pci_iounmap +void __iomem *ioport_map(unsigned long port, unsigned int len); +#define ioport_map ioport_map +#endif static inline void iosync(void) { @@ -670,7 +811,6 @@ static inline void iosync(void) #define IO_SPACE_LIMIT ~(0UL) - /** * ioremap - map bus memory into CPU space * @address: bus address of the memory @@ -706,7 +846,13 @@ extern void __iomem *ioremap(phys_addr_t address, unsigned long size); extern void __iomem *ioremap_prot(phys_addr_t address, unsigned long size, unsigned long flags); extern void __iomem *ioremap_wc(phys_addr_t address, unsigned long size); +#define ioremap_wc ioremap_wc + +#ifdef CONFIG_PPC32 void __iomem *ioremap_wt(phys_addr_t address, unsigned long size); +#define ioremap_wt ioremap_wt +#endif + void __iomem *ioremap_coherent(phys_addr_t address, unsigned long size); #define ioremap_uc(addr, size) ioremap((addr), (size)) #define ioremap_cache(addr, size) \ @@ -766,6 +912,7 @@ static inline unsigned long virt_to_phys(volatile void * address) return __pa((unsigned long)address); } +#define virt_to_phys virt_to_phys /** * phys_to_virt - map physical address to virtual @@ -783,6 +930,7 @@ static inline void * phys_to_virt(unsigned long address) { return (void *)__va(address); } +#define phys_to_virt phys_to_virt /* * Change "struct page" to physical address. @@ -810,6 +958,7 @@ static inline unsigned long virt_to_bus(volatile void * address) return 0; return __pa(address) + PCI_DRAM_OFFSET; } +#define virt_to_bus virt_to_bus static inline void * bus_to_virt(unsigned long address) { @@ -817,6 +966,7 @@ static inline void * bus_to_virt(unsigned long address) return NULL; return __va(address - PCI_DRAM_OFFSET); } +#define bus_to_virt bus_to_virt #define page_to_bus(page) (page_to_phys(page) + PCI_DRAM_OFFSET) @@ -855,6 +1005,8 @@ static inline void * bus_to_virt(unsigned long address) #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) +#include <asm-generic/io.h> + #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_IO_H */ diff --git a/arch/powerpc/include/asm/kup.h b/arch/powerpc/include/asm/kup.h index 0d93331d0fab..bf221a2a523e 100644 --- a/arch/powerpc/include/asm/kup.h +++ b/arch/powerpc/include/asm/kup.h @@ -15,11 +15,13 @@ #define KUAP_CURRENT (KUAP_CURRENT_READ | KUAP_CURRENT_WRITE) #ifdef CONFIG_PPC_BOOK3S_64 -#include <asm/book3s/64/kup-radix.h> +#include <asm/book3s/64/kup.h> #endif + #ifdef CONFIG_PPC_8xx #include <asm/nohash/32/kup-8xx.h> #endif + #ifdef CONFIG_PPC_BOOK3S_32 #include <asm/book3s/32/kup.h> #endif @@ -42,9 +44,10 @@ #else /* !__ASSEMBLY__ */ -#include <linux/pgtable.h> +extern bool disable_kuep; +extern bool disable_kuap; -void setup_kup(void); +#include <linux/pgtable.h> #ifdef CONFIG_PPC_KUEP void setup_kuep(bool disabled); @@ -80,6 +83,12 @@ static inline void restore_user_access(unsigned long flags) { } #endif /* CONFIG_PPC_BOOK3S_64 */ #endif /* CONFIG_PPC_KUAP */ +static __always_inline void setup_kup(void) +{ + setup_kuep(disable_kuep); + setup_kuap(disable_kuap); +} + static inline void allow_read_from_user(const void __user *from, unsigned long size) { allow_user_access(NULL, from, size, KUAP_READ); diff --git a/arch/powerpc/include/asm/kvm_guest.h b/arch/powerpc/include/asm/kvm_guest.h new file mode 100644 index 000000000000..2fca299f7e19 --- /dev/null +++ b/arch/powerpc/include/asm/kvm_guest.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 IBM Corporation + */ + +#ifndef _ASM_POWERPC_KVM_GUEST_H_ +#define _ASM_POWERPC_KVM_GUEST_H_ + +#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_KVM_GUEST) +#include <linux/jump_label.h> + +DECLARE_STATIC_KEY_FALSE(kvm_guest); + +static inline bool is_kvm_guest(void) +{ + return static_branch_unlikely(&kvm_guest); +} + +bool check_kvm_guest(void); +#else +static inline bool is_kvm_guest(void) { return false; } +static inline bool check_kvm_guest(void) { return false; } +#endif + +#endif /* _ASM_POWERPC_KVM_GUEST_H_ */ diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h index 744612054c94..abe1b5e82547 100644 --- a/arch/powerpc/include/asm/kvm_para.h +++ b/arch/powerpc/include/asm/kvm_para.h @@ -8,7 +8,7 @@ #ifndef __POWERPC_KVM_PARA_H__ #define __POWERPC_KVM_PARA_H__ -#include <asm/firmware.h> +#include <asm/kvm_guest.h> #include <uapi/asm/kvm_para.h> diff --git a/arch/powerpc/include/asm/livepatch.h b/arch/powerpc/include/asm/livepatch.h index 4a3d5d25fed5..ae25e6e72997 100644 --- a/arch/powerpc/include/asm/livepatch.h +++ b/arch/powerpc/include/asm/livepatch.h @@ -12,8 +12,10 @@ #include <linux/sched/task_stack.h> #ifdef CONFIG_LIVEPATCH -static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip) +static inline void klp_arch_set_pc(struct ftrace_regs *fregs, unsigned long ip) { + struct pt_regs *regs = ftrace_get_regs(fregs); + regs->nip = ip; } diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 475687f24f4a..cf6ebbc16cb4 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -207,7 +207,6 @@ struct machdep_calls { void (*suspend_disable_irqs)(void); void (*suspend_enable_irqs)(void); #endif - int (*suspend_disable_cpu)(void); #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE ssize_t (*cpu_probe)(const char *, size_t); diff --git a/arch/powerpc/include/asm/mce.h b/arch/powerpc/include/asm/mce.h index 89aa8248a57d..e6c27ae843dc 100644 --- a/arch/powerpc/include/asm/mce.h +++ b/arch/powerpc/include/asm/mce.h @@ -228,6 +228,7 @@ int mce_register_notifier(struct notifier_block *nb); int mce_unregister_notifier(struct notifier_block *nb); #ifdef CONFIG_PPC_BOOK3S_64 void flush_and_reload_slb(void); +void flush_erat(void); long __machine_check_early_realmode_p7(struct pt_regs *regs); long __machine_check_early_realmode_p8(struct pt_regs *regs); long __machine_check_early_realmode_p9(struct pt_regs *regs); diff --git a/arch/powerpc/include/asm/mm-arch-hooks.h b/arch/powerpc/include/asm/mm-arch-hooks.h deleted file mode 100644 index dce274be824a..000000000000 --- a/arch/powerpc/include/asm/mm-arch-hooks.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Architecture specific mm hooks - * - * Copyright (C) 2015, IBM Corporation - * Author: Laurent Dufour <ldufour@linux.vnet.ibm.com> - */ - -#ifndef _ASM_POWERPC_MM_ARCH_HOOKS_H -#define _ASM_POWERPC_MM_ARCH_HOOKS_H - -static inline void arch_remap(struct mm_struct *mm, - unsigned long old_start, unsigned long old_end, - unsigned long new_start, unsigned long new_end) -{ - /* - * mremap() doesn't allow moving multiple vmas so we can limit the - * check to old_start == vdso_base. - */ - if (old_start == mm->context.vdso_base) - mm->context.vdso_base = new_start; -} -#define arch_remap arch_remap - -#endif /* _ASM_POWERPC_MM_ARCH_HOOKS_H */ diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 255a1837e9f7..80b27f5d9648 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h @@ -29,9 +29,18 @@ */ /* - * Support for KUEP feature. + * Supports KUAP feature + * key 0 controlling userspace addresses on radix + * Key 3 on hash */ -#define MMU_FTR_KUEP ASM_CONST(0x00000400) +#define MMU_FTR_BOOK3S_KUAP ASM_CONST(0x00000200) + +/* + * Supports KUEP feature + * key 0 controlling userspace addresses on radix + * Key 3 on hash + */ +#define MMU_FTR_BOOK3S_KUEP ASM_CONST(0x00000400) /* * Support for memory protection keys. @@ -120,14 +129,8 @@ */ #define MMU_FTR_1T_SEGMENT ASM_CONST(0x40000000) -/* - * Supports KUAP (key 0 controlling userspace addresses) on radix - */ -#define MMU_FTR_RADIX_KUAP ASM_CONST(0x80000000) - /* MMU feature bit sets for various CPUs */ -#define MMU_FTRS_DEFAULT_HPTE_ARCH_V2 \ - MMU_FTR_HPTE_TABLE | MMU_FTR_PPCAS_ARCH_V2 +#define MMU_FTRS_DEFAULT_HPTE_ARCH_V2 (MMU_FTR_HPTE_TABLE | MMU_FTR_TLBIEL | MMU_FTR_16M_PAGE) #define MMU_FTRS_POWER MMU_FTRS_DEFAULT_HPTE_ARCH_V2 #define MMU_FTRS_PPC970 MMU_FTRS_POWER | MMU_FTR_TLBIE_CROP_VA #define MMU_FTRS_POWER5 MMU_FTRS_POWER | MMU_FTR_LOCKLESS_TLBIE @@ -154,7 +157,7 @@ DECLARE_PER_CPU(int, next_tlbcam_idx); enum { MMU_FTRS_POSSIBLE = -#ifdef CONFIG_PPC_BOOK3S +#if defined(CONFIG_PPC_BOOK3S_64) || defined(CONFIG_PPC_BOOK3S_604) MMU_FTR_HPTE_TABLE | #endif #ifdef CONFIG_PPC_8xx @@ -163,17 +166,19 @@ enum { #ifdef CONFIG_40x MMU_FTR_TYPE_40x | #endif -#ifdef CONFIG_44x +#ifdef CONFIG_PPC_47x + MMU_FTR_TYPE_47x | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL | +#elif defined(CONFIG_44x) MMU_FTR_TYPE_44x | #endif -#if defined(CONFIG_E200) || defined(CONFIG_E500) +#ifdef CONFIG_E500 MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS | MMU_FTR_USE_TLBILX | #endif -#ifdef CONFIG_PPC_47x - MMU_FTR_TYPE_47x | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL | -#endif #ifdef CONFIG_PPC_BOOK3S_32 - MMU_FTR_USE_HIGH_BATS | MMU_FTR_NEED_DTLB_SW_LRU | + MMU_FTR_USE_HIGH_BATS | +#endif +#ifdef CONFIG_PPC_83xx + MMU_FTR_NEED_DTLB_SW_LRU | #endif #ifdef CONFIG_PPC_BOOK3E_64 MMU_FTR_USE_TLBRSRV | MMU_FTR_USE_PAIRED_MAS | @@ -187,22 +192,47 @@ enum { #ifdef CONFIG_PPC_RADIX_MMU MMU_FTR_TYPE_RADIX | MMU_FTR_GTSE | +#endif /* CONFIG_PPC_RADIX_MMU */ #ifdef CONFIG_PPC_KUAP - MMU_FTR_RADIX_KUAP | + MMU_FTR_BOOK3S_KUAP | #endif /* CONFIG_PPC_KUAP */ -#endif /* CONFIG_PPC_RADIX_MMU */ #ifdef CONFIG_PPC_MEM_KEYS MMU_FTR_PKEY | #endif #ifdef CONFIG_PPC_KUEP - MMU_FTR_KUEP | + MMU_FTR_BOOK3S_KUEP | #endif /* CONFIG_PPC_KUAP */ 0, }; +#if defined(CONFIG_PPC_BOOK3S_604) && !defined(CONFIG_PPC_BOOK3S_603) +#define MMU_FTRS_ALWAYS MMU_FTR_HPTE_TABLE +#endif +#ifdef CONFIG_PPC_8xx +#define MMU_FTRS_ALWAYS MMU_FTR_TYPE_8xx +#endif +#ifdef CONFIG_40x +#define MMU_FTRS_ALWAYS MMU_FTR_TYPE_40x +#endif +#ifdef CONFIG_PPC_47x +#define MMU_FTRS_ALWAYS MMU_FTR_TYPE_47x +#elif defined(CONFIG_44x) +#define MMU_FTRS_ALWAYS MMU_FTR_TYPE_44x +#endif +#if defined(CONFIG_E200) || defined(CONFIG_E500) +#define MMU_FTRS_ALWAYS MMU_FTR_TYPE_FSL_E +#endif + +#ifndef MMU_FTRS_ALWAYS +#define MMU_FTRS_ALWAYS 0 +#endif + static inline bool early_mmu_has_feature(unsigned long feature) { + if (MMU_FTRS_ALWAYS & feature) + return true; + return !!(MMU_FTRS_POSSIBLE & cur_cpu_spec->mmu_features & feature); } @@ -231,6 +261,9 @@ static __always_inline bool mmu_has_feature(unsigned long feature) } #endif + if (MMU_FTRS_ALWAYS & feature) + return true; + if (!(MMU_FTRS_POSSIBLE & feature)) return false; diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index b42813359f49..d5821834dba9 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -263,8 +263,10 @@ extern void arch_exit_mmap(struct mm_struct *mm); static inline void arch_unmap(struct mm_struct *mm, unsigned long start, unsigned long end) { - if (start <= mm->context.vdso_base && mm->context.vdso_base < end) - mm->context.vdso_base = 0; + unsigned long vdso_base = (unsigned long)mm->context.vdso - PAGE_SIZE; + + if (start <= vdso_base && vdso_base < end) + mm->context.vdso = NULL; } #ifdef CONFIG_PPC_MEM_KEYS @@ -285,7 +287,7 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, #define thread_pkey_regs_init(thread) #define arch_dup_pkeys(oldmm, mm) -static inline u64 pte_to_hpte_pkey_bits(u64 pteflags) +static inline u64 pte_to_hpte_pkey_bits(u64 pteflags, unsigned long flags) { return 0x0UL; } diff --git a/arch/powerpc/include/asm/nohash/32/kup-8xx.h b/arch/powerpc/include/asm/nohash/32/kup-8xx.h index 567cdc557402..17a4a616436f 100644 --- a/arch/powerpc/include/asm/nohash/32/kup-8xx.h +++ b/arch/powerpc/include/asm/nohash/32/kup-8xx.h @@ -63,8 +63,7 @@ static inline void restore_user_access(unsigned long flags) static inline bool bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) { - return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xff000000), - "Bug: fault blocked by AP register !"); + return !((regs->kuap ^ MD_APG_KUAP) & 0xff000000); } #endif /* !__ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/nohash/32/mmu-40x.h b/arch/powerpc/include/asm/nohash/32/mmu-40x.h index 74f4edb5916e..8a8f13a22cf4 100644 --- a/arch/powerpc/include/asm/nohash/32/mmu-40x.h +++ b/arch/powerpc/include/asm/nohash/32/mmu-40x.h @@ -57,7 +57,7 @@ typedef struct { unsigned int id; unsigned int active; - unsigned long vdso_base; + void __user *vdso; } mm_context_t; #endif /* !__ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/nohash/32/mmu-44x.h b/arch/powerpc/include/asm/nohash/32/mmu-44x.h index 28aa3b339c5e..2d92a39d8f2e 100644 --- a/arch/powerpc/include/asm/nohash/32/mmu-44x.h +++ b/arch/powerpc/include/asm/nohash/32/mmu-44x.h @@ -108,7 +108,7 @@ extern unsigned int tlb_44x_index; typedef struct { unsigned int id; unsigned int active; - unsigned long vdso_base; + void __user *vdso; } mm_context_t; /* patch sites */ diff --git a/arch/powerpc/include/asm/nohash/32/mmu-8xx.h b/arch/powerpc/include/asm/nohash/32/mmu-8xx.h index 0bd1b144eb76..478249959baa 100644 --- a/arch/powerpc/include/asm/nohash/32/mmu-8xx.h +++ b/arch/powerpc/include/asm/nohash/32/mmu-8xx.h @@ -181,7 +181,7 @@ void mmu_pin_tlb(unsigned long top, bool readonly); typedef struct { unsigned int id; unsigned int active; - unsigned long vdso_base; + void __user *vdso; void *pte_frag; } mm_context_t; diff --git a/arch/powerpc/include/asm/nohash/mmu-book3e.h b/arch/powerpc/include/asm/nohash/mmu-book3e.h index b41004664312..e43a418d3ccd 100644 --- a/arch/powerpc/include/asm/nohash/mmu-book3e.h +++ b/arch/powerpc/include/asm/nohash/mmu-book3e.h @@ -238,7 +238,7 @@ extern unsigned int tlbcam_index; typedef struct { unsigned int id; unsigned int active; - unsigned long vdso_base; + void __user *vdso; } mm_context_t; /* Page size definitions, common between 32 and 64-bit diff --git a/arch/powerpc/include/asm/nohash/pgtable.h b/arch/powerpc/include/asm/nohash/pgtable.h index 6277e7596ae5..ac75f4ab0dba 100644 --- a/arch/powerpc/include/asm/nohash/pgtable.h +++ b/arch/powerpc/include/asm/nohash/pgtable.h @@ -192,9 +192,9 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, */ if (IS_ENABLED(CONFIG_PPC32) && IS_ENABLED(CONFIG_PTE_64BIT) && !percpu) { __asm__ __volatile__("\ - stw%U0%X0 %2,%0\n\ + stw%X0 %2,%0\n\ eieio\n\ - stw%U0%X0 %L2,%1" + stw%X1 %L2,%1" : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) : "r" (pte) : "memory"); return; diff --git a/arch/powerpc/include/asm/nohash/tlbflush.h b/arch/powerpc/include/asm/nohash/tlbflush.h index b1d8fec29169..1edb7243e515 100644 --- a/arch/powerpc/include/asm/nohash/tlbflush.h +++ b/arch/powerpc/include/asm/nohash/tlbflush.h @@ -10,7 +10,6 @@ * - local_flush_tlb_mm(mm, full) flushes the specified mm context on * the local processor * - local_flush_tlb_page(vma, vmaddr) flushes one page on the local processor - * - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB * - flush_tlb_range(vma, start, end) flushes a range of pages * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages * diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index 1dffa3cb16ba..0b63ba7d5917 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -1091,9 +1091,9 @@ enum { OPAL_XIVE_IRQ_TRIGGER_PAGE = 0x00000001, OPAL_XIVE_IRQ_STORE_EOI = 0x00000002, OPAL_XIVE_IRQ_LSI = 0x00000004, - OPAL_XIVE_IRQ_SHIFT_BUG = 0x00000008, - OPAL_XIVE_IRQ_MASK_VIA_FW = 0x00000010, - OPAL_XIVE_IRQ_EOI_VIA_FW = 0x00000020, + OPAL_XIVE_IRQ_SHIFT_BUG = 0x00000008, /* P9 DD1.0 workaround */ + OPAL_XIVE_IRQ_MASK_VIA_FW = 0x00000010, /* P9 DD1.0 workaround */ + OPAL_XIVE_IRQ_EOI_VIA_FW = 0x00000020, /* P9 DD1.0 workaround */ }; /* Flags for OPAL_XIVE_GET/SET_QUEUE_INFO */ diff --git a/arch/powerpc/include/asm/page_32.h b/arch/powerpc/include/asm/page_32.h index d64dfe3ac712..56f217606327 100644 --- a/arch/powerpc/include/asm/page_32.h +++ b/arch/powerpc/include/asm/page_32.h @@ -16,12 +16,6 @@ #define ARCH_DMA_MINALIGN L1_CACHE_BYTES #endif -#ifdef CONFIG_PTE_64BIT -#define PTE_FLAGS_OFFSET 4 /* offset of PTE flags, in bytes */ -#else -#define PTE_FLAGS_OFFSET 0 -#endif - #if defined(CONFIG_PPC_256K_PAGES) || \ (defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)) #define PTE_SHIFT (PAGE_SHIFT - PTE_T_LOG2 - 2) /* 1/4 of a page */ diff --git a/arch/powerpc/include/asm/paravirt.h b/arch/powerpc/include/asm/paravirt.h index 9362c94fe3aa..edc08f04aef7 100644 --- a/arch/powerpc/include/asm/paravirt.h +++ b/arch/powerpc/include/asm/paravirt.h @@ -10,6 +10,9 @@ #endif #ifdef CONFIG_PPC_SPLPAR +#include <asm/kvm_guest.h> +#include <asm/cputhreads.h> + DECLARE_STATIC_KEY_FALSE(shared_processor); static inline bool is_shared_processor(void) @@ -74,6 +77,21 @@ static inline bool vcpu_is_preempted(int cpu) { if (!is_shared_processor()) return false; + +#ifdef CONFIG_PPC_SPLPAR + if (!is_kvm_guest()) { + int first_cpu = cpu_first_thread_sibling(smp_processor_id()); + + /* + * Preemption can only happen at core granularity. This CPU + * is not preempted if one of the CPU of this core is not + * preempted. + */ + if (cpu_first_thread_sibling(cpu) == first_cpu) + return false; + } +#endif + if (yield_count_of(cpu) & 1) return true; return false; diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h index f6acabb6c9be..3b7baba01c92 100644 --- a/arch/powerpc/include/asm/perf_event_server.h +++ b/arch/powerpc/include/asm/perf_event_server.h @@ -82,6 +82,7 @@ struct power_pmu { #define PPMU_ARCH_207S 0x00000080 /* PMC is architecture v2.07S */ #define PPMU_NO_SIAR 0x00000100 /* Do not use SIAR */ #define PPMU_ARCH_31 0x00000200 /* Has MMCR3, SIER2 and SIER3 */ +#define PPMU_P10_DD1 0x00000400 /* Is power10 DD1 processor version */ /* * Values for flags to get_alternatives() diff --git a/arch/powerpc/include/asm/pnv-ocxl.h b/arch/powerpc/include/asm/pnv-ocxl.h index d37ededca3ee..9acd1fbf1197 100644 --- a/arch/powerpc/include/asm/pnv-ocxl.h +++ b/arch/powerpc/include/asm/pnv-ocxl.h @@ -3,12 +3,59 @@ #ifndef _ASM_PNV_OCXL_H #define _ASM_PNV_OCXL_H +#include <linux/bitfield.h> #include <linux/pci.h> #define PNV_OCXL_TL_MAX_TEMPLATE 63 #define PNV_OCXL_TL_BITS_PER_RATE 4 #define PNV_OCXL_TL_RATE_BUF_SIZE ((PNV_OCXL_TL_MAX_TEMPLATE+1) * PNV_OCXL_TL_BITS_PER_RATE / 8) +#define PNV_OCXL_ATSD_TIMEOUT 1 + +/* TLB Management Instructions */ +#define PNV_OCXL_ATSD_LNCH 0x00 +/* Radix Invalidate */ +#define PNV_OCXL_ATSD_LNCH_R PPC_BIT(0) +/* Radix Invalidation Control + * 0b00 Just invalidate TLB. + * 0b01 Invalidate just Page Walk Cache. + * 0b10 Invalidate TLB, Page Walk Cache, and any + * caching of Partition and Process Table Entries. + */ +#define PNV_OCXL_ATSD_LNCH_RIC PPC_BITMASK(1, 2) +/* Number and Page Size of translations to be invalidated */ +#define PNV_OCXL_ATSD_LNCH_LP PPC_BITMASK(3, 10) +/* Invalidation Criteria + * 0b00 Invalidate just the target VA. + * 0b01 Invalidate matching PID. + */ +#define PNV_OCXL_ATSD_LNCH_IS PPC_BITMASK(11, 12) +/* 0b1: Process Scope, 0b0: Partition Scope */ +#define PNV_OCXL_ATSD_LNCH_PRS PPC_BIT(13) +/* Invalidation Flag */ +#define PNV_OCXL_ATSD_LNCH_B PPC_BIT(14) +/* Actual Page Size to be invalidated + * 000 4KB + * 101 64KB + * 001 2MB + * 010 1GB + */ +#define PNV_OCXL_ATSD_LNCH_AP PPC_BITMASK(15, 17) +/* Defines the large page select + * L=0b0 for 4KB pages + * L=0b1 for large pages) + */ +#define PNV_OCXL_ATSD_LNCH_L PPC_BIT(18) +/* Process ID */ +#define PNV_OCXL_ATSD_LNCH_PID PPC_BITMASK(19, 38) +/* NoFlush – Assumed to be 0b0 */ +#define PNV_OCXL_ATSD_LNCH_F PPC_BIT(39) +#define PNV_OCXL_ATSD_LNCH_OCAPI_SLBI PPC_BIT(40) +#define PNV_OCXL_ATSD_LNCH_OCAPI_SINGLETON PPC_BIT(41) +#define PNV_OCXL_ATSD_AVA 0x08 +#define PNV_OCXL_ATSD_AVA_AVA PPC_BITMASK(0, 51) +#define PNV_OCXL_ATSD_STAT 0x10 + int pnv_ocxl_get_actag(struct pci_dev *dev, u16 *base, u16 *enabled, u16 *supported); int pnv_ocxl_get_pasid_count(struct pci_dev *dev, int *count); @@ -28,4 +75,11 @@ int pnv_ocxl_spa_setup(struct pci_dev *dev, void *spa_mem, int PE_mask, void **p void pnv_ocxl_spa_release(void *platform_data); int pnv_ocxl_spa_remove_pe_from_cache(void *platform_data, int pe_handle); +int pnv_ocxl_map_lpar(struct pci_dev *dev, uint64_t lparid, + uint64_t lpcr, void __iomem **arva); +void pnv_ocxl_unmap_lpar(void __iomem *arva); +void pnv_ocxl_tlb_invalidate(void __iomem *arva, + unsigned long pid, + unsigned long addr, + unsigned long page_size); #endif /* _ASM_PNV_OCXL_H */ diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index a6e3700c4566..ed161ef2b3ca 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -78,6 +78,9 @@ #define IMM_L(i) ((uintptr_t)(i) & 0xffff) #define IMM_DS(i) ((uintptr_t)(i) & 0xfffc) +#define IMM_DQ(i) ((uintptr_t)(i) & 0xfff0) +#define IMM_D0(i) (((uintptr_t)(i) >> 16) & 0x3ffff) +#define IMM_D1(i) IMM_L(i) /* * 16-bit immediate helper macros: HA() is for use with sign-extending instrs @@ -230,7 +233,6 @@ #define PPC_INST_POPCNTB_MASK 0xfc0007fe #define PPC_INST_RFEBB 0x4c000124 #define PPC_INST_RFID 0x4c000024 -#define PPC_INST_MFSPR 0x7c0002a6 #define PPC_INST_MFSPR_DSCR 0x7c1102a6 #define PPC_INST_MFSPR_DSCR_MASK 0xfc1ffffe #define PPC_INST_MTSPR_DSCR 0x7c1103a6 @@ -295,6 +297,8 @@ #define __PPC_XB(b) ((((b) & 0x1f) << 11) | (((b) & 0x20) >> 4)) #define __PPC_XS(s) ((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5)) #define __PPC_XT(s) __PPC_XS(s) +#define __PPC_XSP(s) ((((s) & 0x1e) | (((s) >> 5) & 0x1)) << 21) +#define __PPC_XTP(s) __PPC_XSP(s) #define __PPC_T_TLB(t) (((t) & 0x3) << 21) #define __PPC_WC(w) (((w) & 0x3) << 21) #define __PPC_WS(w) (((w) & 0x1f) << 11) @@ -395,6 +399,14 @@ #define PPC_RAW_XVCPSGNDP(t, a, b) ((0xf0000780 | VSX_XX3((t), (a), (b)))) #define PPC_RAW_VPERMXOR(vrt, vra, vrb, vrc) \ ((0x1000002d | ___PPC_RT(vrt) | ___PPC_RA(vra) | ___PPC_RB(vrb) | (((vrc) & 0x1f) << 6))) +#define PPC_RAW_LXVP(xtp, a, i) (0x18000000 | __PPC_XTP(xtp) | ___PPC_RA(a) | IMM_DQ(i)) +#define PPC_RAW_STXVP(xsp, a, i) (0x18000001 | __PPC_XSP(xsp) | ___PPC_RA(a) | IMM_DQ(i)) +#define PPC_RAW_LXVPX(xtp, a, b) (0x7c00029a | __PPC_XTP(xtp) | ___PPC_RA(a) | ___PPC_RB(b)) +#define PPC_RAW_STXVPX(xsp, a, b) (0x7c00039a | __PPC_XSP(xsp) | ___PPC_RA(a) | ___PPC_RB(b)) +#define PPC_RAW_PLXVP(xtp, i, a, pr) \ + ((PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_D0(i)) << 32 | (0xe8000000 | __PPC_XTP(xtp) | ___PPC_RA(a) | IMM_D1(i))) +#define PPC_RAW_PSTXVP(xsp, i, a, pr) \ + ((PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_D0(i)) << 32 | (0xf8000000 | __PPC_XSP(xsp) | ___PPC_RA(a) | IMM_D1(i))) #define PPC_RAW_NAP (0x4c000364) #define PPC_RAW_SLEEP (0x4c0003a4) #define PPC_RAW_WINKLE (0x4c0003e4) @@ -507,6 +519,8 @@ #define PPC_RAW_NEG(d, a) (0x7c0000d0 | ___PPC_RT(d) | ___PPC_RA(a)) +#define PPC_RAW_MFSPR(d, spr) (0x7c0002a6 | ___PPC_RT(d) | __PPC_SPR(spr)) + /* Deal with instructions that older assemblers aren't aware of */ #define PPC_BCCTR_FLUSH stringify_in_c(.long PPC_INST_BCCTR_FLUSH) #define PPC_CP_ABORT stringify_in_c(.long PPC_RAW_CP_ABORT) diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 511786f0e40d..cc1bca571332 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -180,7 +180,12 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) #define VCPU_GPR(n) __VCPU_GPR(__REG_##n) #ifdef __KERNEL__ -#ifdef CONFIG_PPC64 + +/* + * We use __powerpc64__ here because we want the compat VDSO to use the 32-bit + * version below in the else case of the ifdef. + */ +#ifdef __powerpc64__ #define STACKFRAMESIZE 256 #define __STK_REG(i) (112 + ((i)-14)*8) @@ -251,6 +256,8 @@ n: #define _GLOBAL_TOC(name) _GLOBAL(name) +#define DOTSYM(a) a + #endif /* @@ -495,15 +502,9 @@ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96) #endif #ifdef CONFIG_PPC_BOOK3S_64 -#define RFI rfid #define MTMSRD(r) mtmsrd r #define MTMSR_EERI(reg) mtmsrd reg,1 #else -#ifndef CONFIG_40x -#define RFI rfi -#else -#define RFI rfi; b . /* Prevent prefetch past rfi */ -#endif #define MTMSRD(r) mtmsr r #define MTMSR_EERI(reg) mtmsr reg #endif diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index c61c859b51a8..8acc3590c971 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -6,6 +6,8 @@ * Copyright (C) 2001 PPC 64 Team, IBM Corp */ +#include <vdso/processor.h> + #include <asm/reg.h> #ifdef CONFIG_VSX @@ -63,14 +65,6 @@ extern int _chrp_type; #endif /* defined(__KERNEL__) && defined(CONFIG_PPC32) */ -/* Macros for adjusting thread priority (hardware multi-threading) */ -#define HMT_very_low() asm volatile("or 31,31,31 # very low priority") -#define HMT_low() asm volatile("or 1,1,1 # low priority") -#define HMT_medium_low() asm volatile("or 6,6,6 # medium low priority") -#define HMT_medium() asm volatile("or 2,2,2 # medium priority") -#define HMT_medium_high() asm volatile("or 5,5,5 # medium high priority") -#define HMT_high() asm volatile("or 3,3,3 # high priority") - #ifdef __KERNEL__ #ifdef CONFIG_PPC64 @@ -170,8 +164,10 @@ struct thread_struct { #endif /* Debug Registers */ struct debug_reg debug; +#ifdef CONFIG_PPC_FPU_REGS struct thread_fp_state fp_state; struct thread_fp_state *fp_save_area; +#endif int fpexc_mode; /* floating-point exception mode */ unsigned int align_ctl; /* alignment handling control */ #ifdef CONFIG_HAVE_HW_BREAKPOINT @@ -230,10 +226,6 @@ struct thread_struct { struct thread_vr_state ckvr_state; /* Checkpointed VR state */ unsigned long ckvrsave; /* Checkpointed VRSAVE */ #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -#ifdef CONFIG_PPC_MEM_KEYS - unsigned long amr; - unsigned long iamr; -#endif #ifdef CONFIG_KVM_BOOK3S_32_HANDLER void* kvm_shadow_vcpu; /* KVM internal data */ #endif /* CONFIG_KVM_BOOK3S_32_HANDLER */ @@ -344,7 +336,6 @@ static inline unsigned long __pack_fe01(unsigned int fpmode) } #ifdef CONFIG_PPC64 -#define cpu_relax() do { HMT_low(); HMT_medium(); barrier(); } while (0) #define spin_begin() HMT_low() @@ -363,8 +354,6 @@ do { \ } \ } while (0) -#else -#define cpu_relax() barrier() #endif /* Check that a certain kernel stack pointer is valid in task_struct p */ @@ -398,20 +387,6 @@ static inline void prefetchw(const void *x) #define HAVE_ARCH_PICK_MMAP_LAYOUT -#ifdef CONFIG_PPC64 -static inline unsigned long get_clean_sp(unsigned long sp, int is_32) -{ - if (is_32) - return sp & 0x0ffffffffUL; - return sp; -} -#else -static inline unsigned long get_clean_sp(unsigned long sp, int is_32) -{ - return sp; -} -#endif - /* asm stubs */ extern unsigned long isa300_idle_stop_noloss(unsigned long psscr_val); extern unsigned long isa300_idle_stop_mayloss(unsigned long psscr_val); diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h index cb89e4bf55ce..e646c7f218bc 100644 --- a/arch/powerpc/include/asm/ps3.h +++ b/arch/powerpc/include/asm/ps3.h @@ -378,8 +378,8 @@ struct ps3_system_bus_driver { enum ps3_match_sub_id match_sub_id; struct device_driver core; int (*probe)(struct ps3_system_bus_device *); - int (*remove)(struct ps3_system_bus_device *); - int (*shutdown)(struct ps3_system_bus_device *); + void (*remove)(struct ps3_system_bus_device *); + void (*shutdown)(struct ps3_system_bus_device *); /* int (*suspend)(struct ps3_system_bus_device *, pm_message_t); */ /* int (*resume)(struct ps3_system_bus_device *); */ }; diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index e2c778c176a3..58f9dc060a7b 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h @@ -53,11 +53,19 @@ struct pt_regs #ifdef CONFIG_PPC64 unsigned long ppr; #endif + union { #ifdef CONFIG_PPC_KUAP - unsigned long kuap; + unsigned long kuap; +#endif +#ifdef CONFIG_PPC_PKEY + unsigned long amr; +#endif + }; +#ifdef CONFIG_PPC_PKEY + unsigned long iamr; #endif }; - unsigned long __pad[2]; /* Maintain 16 byte interrupt stack alignment */ + unsigned long __pad[4]; /* Maintain 16 byte interrupt stack alignment */ }; }; #endif @@ -171,12 +179,6 @@ static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) set_thread_flag(TIF_NOERROR); \ } while(0) -struct task_struct; -extern int ptrace_get_reg(struct task_struct *task, int regno, - unsigned long *data); -extern int ptrace_put_reg(struct task_struct *task, int regno, - unsigned long data); - #define current_pt_regs() \ ((struct pt_regs *)((unsigned long)task_stack_page(current) + THREAD_SIZE) - 1) diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index f877a576b338..e40a921d78f9 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -29,7 +29,6 @@ #include <asm/reg_8xx.h> #define MSR_SF_LG 63 /* Enable 64 bit mode */ -#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ #define MSR_HV_LG 60 /* Hypervisor state */ #define MSR_TS_T_LG 34 /* Trans Mem state: Transactional */ #define MSR_TS_S_LG 33 /* Trans Mem state: Suspended */ @@ -69,13 +68,11 @@ #ifdef CONFIG_PPC64 #define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */ -#define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */ #define MSR_HV __MASK(MSR_HV_LG) /* Hypervisor state */ #define MSR_S __MASK(MSR_S_LG) /* Secure state */ #else /* so tests for these bits fail on 32-bit */ #define MSR_SF 0 -#define MSR_ISF 0 #define MSR_HV 0 #define MSR_S 0 #endif @@ -134,7 +131,7 @@ #define MSR_64BIT MSR_SF /* Server variant */ -#define __MSR (MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF |MSR_HV) +#define __MSR (MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_HV) #ifdef __BIG_ENDIAN__ #define MSR_ __MSR #define MSR_IDLE (MSR_ME | MSR_SF | MSR_HV) @@ -864,6 +861,7 @@ #define MMCR0_BHRBA 0x00200000UL /* BHRB Access allowed in userspace */ #define MMCR0_EBE 0x00100000UL /* Event based branch enable */ #define MMCR0_PMCC 0x000c0000UL /* PMC control */ +#define MMCR0_PMCCEXT ASM_CONST(0x00000200) /* PMCCEXT control */ #define MMCR0_PMCC_U6 0x00080000UL /* PMC1-6 are R/W by user (PR) */ #define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/ #define MMCR0_PMCjCE ASM_CONST(0x00004000) /* PMCj count enable*/ @@ -1203,7 +1201,7 @@ #ifdef CONFIG_PPC_BOOK3S_32 #define SPRN_SPRG_SCRATCH0 SPRN_SPRG0 #define SPRN_SPRG_SCRATCH1 SPRN_SPRG1 -#define SPRN_SPRG_PGDIR SPRN_SPRG2 +#define SPRN_SPRG_SCRATCH2 SPRN_SPRG2 #define SPRN_SPRG_603_LRU SPRN_SPRG4 #endif @@ -1232,14 +1230,9 @@ #define SPRN_SPRG_WSCRATCH_MC SPRN_SPRG1 #define SPRN_SPRG_RSCRATCH4 SPRN_SPRG7R #define SPRN_SPRG_WSCRATCH4 SPRN_SPRG7W -#ifdef CONFIG_E200 -#define SPRN_SPRG_RSCRATCH_DBG SPRN_SPRG6R -#define SPRN_SPRG_WSCRATCH_DBG SPRN_SPRG6W -#else #define SPRN_SPRG_RSCRATCH_DBG SPRN_SPRG9 #define SPRN_SPRG_WSCRATCH_DBG SPRN_SPRG9 #endif -#endif #ifdef CONFIG_PPC_8xx #define SPRN_SPRG_SCRATCH0 SPRN_SPRG0 @@ -1419,37 +1412,6 @@ static inline void msr_check_and_clear(unsigned long bits) __msr_check_and_clear(bits); } -#if defined(CONFIG_PPC_CELL) || defined(CONFIG_E500) -#define mftb() ({unsigned long rval; \ - asm volatile( \ - "90: mfspr %0, %2;\n" \ - ASM_FTR_IFSET( \ - "97: cmpwi %0,0;\n" \ - " beq- 90b;\n", "", %1) \ - : "=r" (rval) \ - : "i" (CPU_FTR_CELL_TB_BUG), "i" (SPRN_TBRL) : "cr0"); \ - rval;}) -#elif defined(CONFIG_PPC_8xx) -#define mftb() ({unsigned long rval; \ - asm volatile("mftbl %0" : "=r" (rval)); rval;}) -#else -#define mftb() ({unsigned long rval; \ - asm volatile("mfspr %0, %1" : \ - "=r" (rval) : "i" (SPRN_TBRL)); rval;}) -#endif /* !CONFIG_PPC_CELL */ - -#if defined(CONFIG_PPC_8xx) -#define mftbu() ({unsigned long rval; \ - asm volatile("mftbu %0" : "=r" (rval)); rval;}) -#else -#define mftbu() ({unsigned long rval; \ - asm volatile("mfspr %0, %1" : "=r" (rval) : \ - "i" (SPRN_TBRU)); rval;}) -#endif - -#define mttbl(v) asm volatile("mttbl %0":: "r"(v)) -#define mttbu(v) asm volatile("mttbu %0":: "r"(v)) - #ifdef CONFIG_PPC32 #define mfsrin(v) ({unsigned int rval; \ asm volatile("mfsrin %0,%1" : "=r" (rval) : "r" (v)); \ diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index 29a948e0c0f2..262782f08fd4 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -281,18 +281,6 @@ #define MSRP_PMMP 0x00000004 /* Protect MSR[PMM] */ #endif -#ifdef CONFIG_E200 -#define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */ -#define MCSR_CP_PERR 0x20000000UL /* Cache Push Parity Error */ -#define MCSR_CPERR 0x10000000UL /* Cache Parity Error */ -#define MCSR_EXCP_ERR 0x08000000UL /* ISI, ITLB, or Bus Error on 1st insn - fetch for an exception handler */ -#define MCSR_BUS_IRERR 0x00000010UL /* Read Bus Error on instruction fetch*/ -#define MCSR_BUS_DRERR 0x00000008UL /* Read Bus Error on data load */ -#define MCSR_BUS_WRERR 0x00000004UL /* Write Bus Error on buffered - store or cache line push */ -#endif - /* Bit definitions for the HID1 */ #ifdef CONFIG_E500 /* e500v1/v2 */ diff --git a/arch/powerpc/include/asm/rtas-types.h b/arch/powerpc/include/asm/rtas-types.h index aa420561bc10..8df6235d64d1 100644 --- a/arch/powerpc/include/asm/rtas-types.h +++ b/arch/powerpc/include/asm/rtas-types.h @@ -23,14 +23,6 @@ struct rtas_t { struct device_node *dev; /* virtual address pointer */ }; -struct rtas_suspend_me_data { - atomic_t working; /* number of cpus accessing this struct */ - atomic_t done; - int token; /* ibm,suspend-me */ - atomic_t error; - struct completion *complete; /* wait on this until working == 0 */ -}; - struct rtas_error_log { /* Byte 0 */ u8 byte0; /* Architectural version */ diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 55f9a154c95d..332e1000ca0f 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h @@ -23,11 +23,16 @@ #define RTAS_RMOBUF_MAX (64 * 1024) /* RTAS return status codes */ -#define RTAS_NOT_SUSPENDABLE -9004 #define RTAS_BUSY -2 /* RTAS Busy */ #define RTAS_EXTENDED_DELAY_MIN 9900 #define RTAS_EXTENDED_DELAY_MAX 9905 +/* statuses specific to ibm,suspend-me */ +#define RTAS_SUSPEND_ABORTED 9000 /* Suspension aborted */ +#define RTAS_NOT_SUSPENDABLE -9004 /* Partition not suspendable */ +#define RTAS_THREADS_ACTIVE -9005 /* Multiple processor threads active */ +#define RTAS_OUTSTANDING_COPROC -9006 /* Outstanding coprocessor operations */ + /* * In general to call RTAS use rtas_token("string") to lookup * an RTAS token for the given string (e.g. "event-scan"). @@ -242,6 +247,7 @@ extern void __noreturn rtas_restart(char *cmd); extern void rtas_power_off(void); extern void __noreturn rtas_halt(void); extern void rtas_os_term(char *str); +void rtas_activate_firmware(void); extern int rtas_get_sensor(int sensor, int index, int *state); extern int rtas_get_sensor_fast(int sensor, int index, int *state); extern int rtas_get_power_level(int powerdomain, int *level); @@ -250,9 +256,7 @@ extern bool rtas_indicator_present(int token, int *maxindex); extern int rtas_set_indicator(int indicator, int index, int new_value); extern int rtas_set_indicator_fast(int indicator, int index, int new_value); extern void rtas_progress(char *s, unsigned short hex); -extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data); -extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data); -extern int rtas_ibm_suspend_me(u64 handle); +int rtas_ibm_suspend_me(int *fw_status); struct rtc_time; extern time64_t rtas_get_boot_time(void); @@ -272,8 +276,13 @@ extern time64_t last_rtas_event; extern int clobbering_unread_rtas_event(void); extern int pseries_devicetree_update(s32 scope); extern void post_mobility_fixup(void); +int rtas_syscall_dispatch_ibm_suspend_me(u64 handle); #else static inline int clobbering_unread_rtas_event(void) { return 0; } +static inline int rtas_syscall_dispatch_ibm_suspend_me(u64 handle) +{ + return -EINVAL; +} #endif #ifdef CONFIG_PPC_RTAS_DAEMON diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index b2035b2f57ce..c4e2d53acd2b 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -134,6 +134,7 @@ static inline struct cpumask *cpu_smallcore_mask(int cpu) extern int cpu_to_core_id(int cpu); extern bool has_big_cores; +extern bool thread_group_shares_l2; #define cpu_smt_mask cpu_smt_mask #ifdef CONFIG_SCHED_SMT @@ -187,6 +188,7 @@ extern void __cpu_die(unsigned int cpu); /* for UP */ #define hard_smp_processor_id() get_hard_smp_processor_id(0) #define smp_setup_cpu_maps() +#define thread_group_shares_l2 0 static inline void inhibit_secondary_onlining(void) {} static inline void uninhibit_secondary_onlining(void) {} static inline const struct cpumask *cpu_sibling_mask(int cpu) @@ -199,6 +201,10 @@ static inline const struct cpumask *cpu_smallcore_mask(int cpu) return cpumask_of(cpu); } +static inline const struct cpumask *cpu_l2_cache_mask(int cpu) +{ + return cpumask_of(cpu); +} #endif /* CONFIG_SMP */ #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index 53115ae61495..3d8a47af7a25 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h @@ -77,10 +77,8 @@ struct thread_info { /* how to get the thread information struct from C */ extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); -#ifdef CONFIG_PPC_BOOK3S_64 void arch_setup_new_exec(void); #define arch_setup_new_exec arch_setup_new_exec -#endif #endif /* __ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index 2f566c1a754c..8f789b597bae 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h @@ -15,6 +15,7 @@ #include <asm/processor.h> #include <asm/cpu_has_feature.h> +#include <asm/vdso/timebase.h> /* time.c */ extern unsigned long tb_ticks_per_jiffy; @@ -38,42 +39,12 @@ struct div_result { u64 result_low; }; -/* For compatibility, get_tbl() is defined as get_tb() on ppc64 */ -static inline unsigned long get_tbl(void) -{ - return mftb(); -} - static inline u64 get_vtb(void) { -#ifdef CONFIG_PPC_BOOK3S_64 if (cpu_has_feature(CPU_FTR_ARCH_207S)) return mfspr(SPRN_VTB); -#endif - return 0; -} - -static inline u64 get_tb(void) -{ - unsigned int tbhi, tblo, tbhi2; - - if (IS_ENABLED(CONFIG_PPC64)) - return mftb(); - do { - tbhi = mftbu(); - tblo = mftb(); - tbhi2 = mftbu(); - } while (tbhi != tbhi2); - - return ((u64)tbhi << 32) | tblo; -} - -static inline void set_tb(unsigned int upper, unsigned int lower) -{ - mtspr(SPRN_TBWL, 0); - mtspr(SPRN_TBWU, upper); - mtspr(SPRN_TBWL, lower); + return 0; } /* Accessor functions for the decrementer register. diff --git a/arch/powerpc/include/asm/timex.h b/arch/powerpc/include/asm/timex.h index 95988870a57b..fa2e76e4093a 100644 --- a/arch/powerpc/include/asm/timex.h +++ b/arch/powerpc/include/asm/timex.h @@ -9,7 +9,7 @@ */ #include <asm/cputable.h> -#include <asm/reg.h> +#include <asm/vdso/timebase.h> #define CLOCK_TICK_RATE 1024000 /* Underlying HZ */ diff --git a/arch/powerpc/include/asm/tlb.h b/arch/powerpc/include/asm/tlb.h index d97f061fecac..160422a439aa 100644 --- a/arch/powerpc/include/asm/tlb.h +++ b/arch/powerpc/include/asm/tlb.h @@ -40,9 +40,6 @@ extern void tlb_flush(struct mmu_gather *tlb); /* Get the generic bits... */ #include <asm-generic/tlb.h> -extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, - unsigned long address); - static inline void __tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep, unsigned long address) { diff --git a/arch/powerpc/include/asm/vdso.h b/arch/powerpc/include/asm/vdso.h index 2ff884853f97..8542e9bbeead 100644 --- a/arch/powerpc/include/asm/vdso.h +++ b/arch/powerpc/include/asm/vdso.h @@ -1,12 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __PPC64_VDSO_H__ -#define __PPC64_VDSO_H__ - -#ifdef __KERNEL__ - -/* Default link addresses for the vDSOs */ -#define VDSO32_LBASE 0x0 -#define VDSO64_LBASE 0x0 +#ifndef _ASM_POWERPC_VDSO_H +#define _ASM_POWERPC_VDSO_H /* Default map addresses for 32bit vDSO */ #define VDSO32_MBASE 0x100000 @@ -15,10 +9,17 @@ #ifndef __ASSEMBLY__ -/* Offsets relative to thread->vdso_base */ -extern unsigned long vdso64_rt_sigtramp; -extern unsigned long vdso32_sigtramp; -extern unsigned long vdso32_rt_sigtramp; +#ifdef CONFIG_PPC64 +#include <generated/vdso64-offsets.h> +#endif + +#ifdef CONFIG_VDSO32 +#include <generated/vdso32-offsets.h> +#endif + +#define VDSO64_SYMBOL(base, name) ((unsigned long)(base) + (vdso64_offset_##name)) + +#define VDSO32_SYMBOL(base, name) ((unsigned long)(base) + (vdso32_offset_##name)) int vdso_getcpu_init(void); @@ -51,6 +52,4 @@ int vdso_getcpu_init(void); #endif /* __ASSEMBLY__ */ -#endif /* __KERNEL__ */ - -#endif /* __PPC64_VDSO_H__ */ +#endif /* _ASM_POWERPC_VDSO_H */ diff --git a/arch/powerpc/include/asm/vdso/clocksource.h b/arch/powerpc/include/asm/vdso/clocksource.h new file mode 100644 index 000000000000..c1ba56b82ee5 --- /dev/null +++ b/arch/powerpc/include/asm/vdso/clocksource.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_VDSO_CLOCKSOURCE_H +#define _ASM_POWERPC_VDSO_CLOCKSOURCE_H + +#define VDSO_ARCH_CLOCKMODES VDSO_CLOCKMODE_ARCHTIMER + +#endif diff --git a/arch/powerpc/include/asm/vdso/gettimeofday.h b/arch/powerpc/include/asm/vdso/gettimeofday.h new file mode 100644 index 000000000000..77c635c2c90d --- /dev/null +++ b/arch/powerpc/include/asm/vdso/gettimeofday.h @@ -0,0 +1,215 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_VDSO_GETTIMEOFDAY_H +#define _ASM_POWERPC_VDSO_GETTIMEOFDAY_H + +#ifdef __ASSEMBLY__ + +#include <asm/ppc_asm.h> + +/* + * The macros sets two stack frames, one for the caller and one for the callee + * because there are no requirement for the caller to set a stack frame when + * calling VDSO so it may have omitted to set one, especially on PPC64 + */ + +.macro cvdso_call funct + .cfi_startproc + PPC_STLU r1, -PPC_MIN_STKFRM(r1) + mflr r0 + .cfi_register lr, r0 + PPC_STLU r1, -PPC_MIN_STKFRM(r1) + PPC_STL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) +#ifdef __powerpc64__ + PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1) +#endif + get_datapage r5 + addi r5, r5, VDSO_DATA_OFFSET + bl DOTSYM(\funct) + PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) +#ifdef __powerpc64__ + PPC_LL r2, PPC_MIN_STKFRM + STK_GOT(r1) +#endif + cmpwi r3, 0 + mtlr r0 + .cfi_restore lr + addi r1, r1, 2 * PPC_MIN_STKFRM + crclr so + beqlr+ + crset so + neg r3, r3 + blr + .cfi_endproc +.endm + +.macro cvdso_call_time funct + .cfi_startproc + PPC_STLU r1, -PPC_MIN_STKFRM(r1) + mflr r0 + .cfi_register lr, r0 + PPC_STLU r1, -PPC_MIN_STKFRM(r1) + PPC_STL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) +#ifdef __powerpc64__ + PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1) +#endif + get_datapage r4 + addi r4, r4, VDSO_DATA_OFFSET + bl DOTSYM(\funct) + PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) +#ifdef __powerpc64__ + PPC_LL r2, PPC_MIN_STKFRM + STK_GOT(r1) +#endif + crclr so + mtlr r0 + .cfi_restore lr + addi r1, r1, 2 * PPC_MIN_STKFRM + blr + .cfi_endproc +.endm + +#else + +#include <asm/vdso/timebase.h> +#include <asm/barrier.h> +#include <asm/unistd.h> +#include <uapi/linux/time.h> + +#define VDSO_HAS_CLOCK_GETRES 1 + +#define VDSO_HAS_TIME 1 + +static __always_inline int do_syscall_2(const unsigned long _r0, const unsigned long _r3, + const unsigned long _r4) +{ + register long r0 asm("r0") = _r0; + register unsigned long r3 asm("r3") = _r3; + register unsigned long r4 asm("r4") = _r4; + register int ret asm ("r3"); + + asm volatile( + " sc\n" + " bns+ 1f\n" + " neg %0, %0\n" + "1:\n" + : "=r" (ret), "+r" (r4), "+r" (r0) + : "r" (r3) + : "memory", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cr0", "ctr"); + + return ret; +} + +static __always_inline +int gettimeofday_fallback(struct __kernel_old_timeval *_tv, struct timezone *_tz) +{ + return do_syscall_2(__NR_gettimeofday, (unsigned long)_tv, (unsigned long)_tz); +} + +#ifdef __powerpc64__ + +static __always_inline +int clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) +{ + return do_syscall_2(__NR_clock_gettime, _clkid, (unsigned long)_ts); +} + +static __always_inline +int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) +{ + return do_syscall_2(__NR_clock_getres, _clkid, (unsigned long)_ts); +} + +#else + +#define BUILD_VDSO32 1 + +static __always_inline +int clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) +{ + return do_syscall_2(__NR_clock_gettime64, _clkid, (unsigned long)_ts); +} + +static __always_inline +int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts) +{ + return do_syscall_2(__NR_clock_getres_time64, _clkid, (unsigned long)_ts); +} + +static __always_inline +int clock_gettime32_fallback(clockid_t _clkid, struct old_timespec32 *_ts) +{ + return do_syscall_2(__NR_clock_gettime, _clkid, (unsigned long)_ts); +} + +static __always_inline +int clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts) +{ + return do_syscall_2(__NR_clock_getres, _clkid, (unsigned long)_ts); +} +#endif + +static __always_inline u64 __arch_get_hw_counter(s32 clock_mode, + const struct vdso_data *vd) +{ + return get_tb(); +} + +const struct vdso_data *__arch_get_vdso_data(void); + +static inline bool vdso_clocksource_ok(const struct vdso_data *vd) +{ + return true; +} +#define vdso_clocksource_ok vdso_clocksource_ok + +/* + * powerpc specific delta calculation. + * + * This variant removes the masking of the subtraction because the + * clocksource mask of all VDSO capable clocksources on powerpc is U64_MAX + * which would result in a pointless operation. The compiler cannot + * optimize it away as the mask comes from the vdso data and is not compile + * time constant. + */ +static __always_inline u64 vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 mult) +{ + return (cycles - last) * mult; +} +#define vdso_calc_delta vdso_calc_delta + +#ifndef __powerpc64__ +static __always_inline u64 vdso_shift_ns(u64 ns, unsigned long shift) +{ + u32 hi = ns >> 32; + u32 lo = ns; + + lo >>= shift; + lo |= hi << (32 - shift); + hi >>= shift; + + if (likely(hi == 0)) + return lo; + + return ((u64)hi << 32) | lo; +} +#define vdso_shift_ns vdso_shift_ns +#endif + +#ifdef __powerpc64__ +int __c_kernel_clock_gettime(clockid_t clock, struct __kernel_timespec *ts, + const struct vdso_data *vd); +int __c_kernel_clock_getres(clockid_t clock_id, struct __kernel_timespec *res, + const struct vdso_data *vd); +#else +int __c_kernel_clock_gettime(clockid_t clock, struct old_timespec32 *ts, + const struct vdso_data *vd); +int __c_kernel_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts, + const struct vdso_data *vd); +int __c_kernel_clock_getres(clockid_t clock_id, struct old_timespec32 *res, + const struct vdso_data *vd); +#endif +int __c_kernel_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz, + const struct vdso_data *vd); +__kernel_old_time_t __c_kernel_time(__kernel_old_time_t *time, + const struct vdso_data *vd); +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_POWERPC_VDSO_GETTIMEOFDAY_H */ diff --git a/arch/powerpc/include/asm/vdso/processor.h b/arch/powerpc/include/asm/vdso/processor.h new file mode 100644 index 000000000000..e072577bc7c0 --- /dev/null +++ b/arch/powerpc/include/asm/vdso/processor.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _ASM_POWERPC_VDSO_PROCESSOR_H +#define _ASM_POWERPC_VDSO_PROCESSOR_H + +#ifndef __ASSEMBLY__ + +/* Macros for adjusting thread priority (hardware multi-threading) */ +#define HMT_very_low() asm volatile("or 31, 31, 31 # very low priority") +#define HMT_low() asm volatile("or 1, 1, 1 # low priority") +#define HMT_medium_low() asm volatile("or 6, 6, 6 # medium low priority") +#define HMT_medium() asm volatile("or 2, 2, 2 # medium priority") +#define HMT_medium_high() asm volatile("or 5, 5, 5 # medium high priority") +#define HMT_high() asm volatile("or 3, 3, 3 # high priority") + +#ifdef CONFIG_PPC64 +#define cpu_relax() do { HMT_low(); HMT_medium(); barrier(); } while (0) +#else +#define cpu_relax() barrier() +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_POWERPC_VDSO_PROCESSOR_H */ diff --git a/arch/powerpc/include/asm/vdso/timebase.h b/arch/powerpc/include/asm/vdso/timebase.h new file mode 100644 index 000000000000..881f655caa0a --- /dev/null +++ b/arch/powerpc/include/asm/vdso/timebase.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Common timebase prototypes and such for all ppc machines. + */ + +#ifndef _ASM_POWERPC_VDSO_TIMEBASE_H +#define _ASM_POWERPC_VDSO_TIMEBASE_H + +#include <asm/reg.h> + +/* + * We use __powerpc64__ here because we want the compat VDSO to use the 32-bit + * version below in the else case of the ifdef. + */ +#if defined(__powerpc64__) && (defined(CONFIG_PPC_CELL) || defined(CONFIG_E500)) +#define mftb() ({unsigned long rval; \ + asm volatile( \ + "90: mfspr %0, %2;\n" \ + ASM_FTR_IFSET( \ + "97: cmpwi %0,0;\n" \ + " beq- 90b;\n", "", %1) \ + : "=r" (rval) \ + : "i" (CPU_FTR_CELL_TB_BUG), "i" (SPRN_TBRL) : "cr0"); \ + rval;}) +#elif defined(CONFIG_PPC_8xx) +#define mftb() ({unsigned long rval; \ + asm volatile("mftbl %0" : "=r" (rval)); rval;}) +#else +#define mftb() ({unsigned long rval; \ + asm volatile("mfspr %0, %1" : \ + "=r" (rval) : "i" (SPRN_TBRL)); rval;}) +#endif /* !CONFIG_PPC_CELL */ + +#if defined(CONFIG_PPC_8xx) +#define mftbu() ({unsigned long rval; \ + asm volatile("mftbu %0" : "=r" (rval)); rval;}) +#else +#define mftbu() ({unsigned long rval; \ + asm volatile("mfspr %0, %1" : "=r" (rval) : \ + "i" (SPRN_TBRU)); rval;}) +#endif + +#define mttbl(v) asm volatile("mttbl %0":: "r"(v)) +#define mttbu(v) asm volatile("mttbu %0":: "r"(v)) + +/* For compatibility, get_tbl() is defined as get_tb() on ppc64 */ +static inline unsigned long get_tbl(void) +{ + return mftb(); +} + +static __always_inline u64 get_tb(void) +{ + unsigned int tbhi, tblo, tbhi2; + + /* + * We use __powerpc64__ here not CONFIG_PPC64 because we want the compat + * VDSO to use the 32-bit compatible version in the while loop below. + */ + if (__is_defined(__powerpc64__)) + return mftb(); + + do { + tbhi = mftbu(); + tblo = mftb(); + tbhi2 = mftbu(); + } while (tbhi != tbhi2); + + return ((u64)tbhi << 32) | tblo; +} + +static inline void set_tb(unsigned int upper, unsigned int lower) +{ + mtspr(SPRN_TBWL, 0); + mtspr(SPRN_TBWU, upper); + mtspr(SPRN_TBWL, lower); +} + +#endif /* _ASM_POWERPC_VDSO_TIMEBASE_H */ diff --git a/arch/powerpc/include/asm/vdso/vsyscall.h b/arch/powerpc/include/asm/vdso/vsyscall.h new file mode 100644 index 000000000000..48cf23f1e273 --- /dev/null +++ b/arch/powerpc/include/asm/vdso/vsyscall.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_VDSO_VSYSCALL_H +#define _ASM_POWERPC_VDSO_VSYSCALL_H + +#ifndef __ASSEMBLY__ + +#include <linux/timekeeper_internal.h> +#include <asm/vdso_datapage.h> + +/* + * Update the vDSO data page to keep in sync with kernel timekeeping. + */ +static __always_inline +struct vdso_data *__arch_get_k_vdso_data(void) +{ + return vdso_data->data; +} +#define __arch_get_k_vdso_data __arch_get_k_vdso_data + +/* The asm-generic header needs to be included after the definitions above */ +#include <asm-generic/vdso/vsyscall.h> + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_POWERPC_VDSO_VSYSCALL_H */ diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h index b9ef6cf50ea5..3f958ecf2beb 100644 --- a/arch/powerpc/include/asm/vdso_datapage.h +++ b/arch/powerpc/include/asm/vdso_datapage.h @@ -36,6 +36,7 @@ #include <linux/unistd.h> #include <linux/time.h> +#include <vdso/datapage.h> #define SYSCALL_MAP_SIZE ((NR_syscalls + 31) / 32) @@ -45,7 +46,7 @@ #ifdef CONFIG_PPC64 -struct vdso_data { +struct vdso_arch_data { __u8 eye_catcher[16]; /* Eyecatcher: SYSTEMCFG:PPC64 0x00 */ struct { /* Systemcfg version numbers */ __u32 major; /* Major number 0x10 */ @@ -59,13 +60,13 @@ struct vdso_data { __u32 processor; /* Processor type 0x1C */ __u64 processorCount; /* # of physical processors 0x20 */ __u64 physicalMemorySize; /* Size of real memory(B) 0x28 */ - __u64 tb_orig_stamp; /* Timebase at boot 0x30 */ + __u64 tb_orig_stamp; /* (NU) Timebase at boot 0x30 */ __u64 tb_ticks_per_sec; /* Timebase tics / sec 0x38 */ - __u64 tb_to_xs; /* Inverse of TB to 2^20 0x40 */ - __u64 stamp_xsec; /* 0x48 */ - __u64 tb_update_count; /* Timebase atomicity ctr 0x50 */ - __u32 tz_minuteswest; /* Minutes west of Greenwich 0x58 */ - __u32 tz_dsttime; /* Type of dst correction 0x5C */ + __u64 tb_to_xs; /* (NU) Inverse of TB to 2^20 0x40 */ + __u64 stamp_xsec; /* (NU) 0x48 */ + __u64 tb_update_count; /* (NU) Timebase atomicity ctr 0x50 */ + __u32 tz_minuteswest; /* (NU) Min. west of Greenwich 0x58 */ + __u32 tz_dsttime; /* (NU) Type of dst correction 0x5C */ __u32 dcache_size; /* L1 d-cache size 0x60 */ __u32 dcache_line_size; /* L1 d-cache line size 0x64 */ __u32 icache_size; /* L1 i-cache size 0x68 */ @@ -78,14 +79,10 @@ struct vdso_data { __u32 icache_block_size; /* L1 i-cache block size */ __u32 dcache_log_block_size; /* L1 d-cache log block size */ __u32 icache_log_block_size; /* L1 i-cache log block size */ - __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */ - __s32 wtom_clock_nsec; /* Wall to monotonic clock nsec */ - __s64 wtom_clock_sec; /* Wall to monotonic clock sec */ - __s64 stamp_xtime_sec; /* xtime secs as at tb_orig_stamp */ - __s64 stamp_xtime_nsec; /* xtime nsecs as at tb_orig_stamp */ - __u32 hrtimer_res; /* hrtimer resolution */ - __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */ - __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ + __u32 syscall_map[SYSCALL_MAP_SIZE]; /* Map of syscalls */ + __u32 compat_syscall_map[SYSCALL_MAP_SIZE]; /* Map of compat syscalls */ + + struct vdso_data data[CS_BASES]; }; #else /* CONFIG_PPC64 */ @@ -93,35 +90,27 @@ struct vdso_data { /* * And here is the simpler 32 bits version */ -struct vdso_data { - __u64 tb_orig_stamp; /* Timebase at boot 0x30 */ +struct vdso_arch_data { __u64 tb_ticks_per_sec; /* Timebase tics / sec 0x38 */ - __u64 tb_to_xs; /* Inverse of TB to 2^20 0x40 */ - __u64 stamp_xsec; /* 0x48 */ - __u32 tb_update_count; /* Timebase atomicity ctr 0x50 */ - __u32 tz_minuteswest; /* Minutes west of Greenwich 0x58 */ - __u32 tz_dsttime; /* Type of dst correction 0x5C */ - __s32 wtom_clock_sec; /* Wall to monotonic clock */ - __s32 wtom_clock_nsec; - __s32 stamp_xtime_sec; /* xtime seconds as at tb_orig_stamp */ - __s32 stamp_xtime_nsec; /* xtime nsecs as at tb_orig_stamp */ - __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */ - __u32 hrtimer_res; /* hrtimer resolution */ - __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ + __u32 syscall_map[SYSCALL_MAP_SIZE]; /* Map of syscalls */ + __u32 compat_syscall_map[0]; /* No compat syscalls on PPC32 */ + struct vdso_data data[CS_BASES]; }; #endif /* CONFIG_PPC64 */ -extern struct vdso_data *vdso_data; +extern struct vdso_arch_data *vdso_data; #else /* __ASSEMBLY__ */ -.macro get_datapage ptr, tmp +.macro get_datapage ptr bcl 20, 31, .+4 +999: mflr \ptr - addi \ptr, \ptr, (__kernel_datapage_offset - (.-4))@l - lwz \tmp, 0(\ptr) - add \ptr, \tmp, \ptr +#if CONFIG_PPC_PAGE_SHIFT > 14 + addis \ptr, \ptr, (_vdso_datapage - 999b)@ha +#endif + addi \ptr, \ptr, (_vdso_datapage - 999b)@l .endm #endif /* __ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h index 309b4d65b74f..9a312b975ca8 100644 --- a/arch/powerpc/include/asm/xive.h +++ b/arch/powerpc/include/asm/xive.h @@ -60,13 +60,13 @@ struct xive_irq_data { }; #define XIVE_IRQ_FLAG_STORE_EOI 0x01 #define XIVE_IRQ_FLAG_LSI 0x02 -#define XIVE_IRQ_FLAG_SHIFT_BUG 0x04 -#define XIVE_IRQ_FLAG_MASK_FW 0x08 -#define XIVE_IRQ_FLAG_EOI_FW 0x10 +/* #define XIVE_IRQ_FLAG_SHIFT_BUG 0x04 */ /* P9 DD1.0 workaround */ +/* #define XIVE_IRQ_FLAG_MASK_FW 0x08 */ /* P9 DD1.0 workaround */ +/* #define XIVE_IRQ_FLAG_EOI_FW 0x10 */ /* P9 DD1.0 workaround */ #define XIVE_IRQ_FLAG_H_INT_ESB 0x20 /* Special flag set by KVM for excalation interrupts */ -#define XIVE_IRQ_NO_EOI 0x80 +#define XIVE_IRQ_FLAG_NO_EOI 0x80 #define XIVE_INVALID_CHIP_ID -1 diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index bf0bf1b900d2..fe2ef598e2ea 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -173,6 +173,9 @@ KCOV_INSTRUMENT_cputable.o := n KCOV_INSTRUMENT_setup_64.o := n KCOV_INSTRUMENT_paca.o := n +CFLAGS_setup_64.o += -fno-stack-protector +CFLAGS_paca.o += -fno-stack-protector + extra-$(CONFIG_PPC_FPU) += fpu.o extra-$(CONFIG_ALTIVEC) += vector.o extra-$(CONFIG_PPC64) += entry_64.o diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index c2722ff36e98..b12d7c049bfe 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -110,9 +110,11 @@ int main(void) #ifdef CONFIG_BOOKE OFFSET(THREAD_NORMSAVES, thread_struct, normsave[0]); #endif +#ifdef CONFIG_PPC_FPU OFFSET(THREAD_FPEXC_MODE, thread_struct, fpexc_mode); OFFSET(THREAD_FPSTATE, thread_struct, fp_state.fpr); OFFSET(THREAD_FPSAVEAREA, thread_struct, fp_save_area); +#endif OFFSET(FPSTATE_FPSCR, thread_fp_state, fpscr); OFFSET(THREAD_LOAD_FP, thread_struct, load_fp); #ifdef CONFIG_ALTIVEC @@ -354,10 +356,15 @@ int main(void) STACK_PT_REGS_OFFSET(_PPR, ppr); #endif /* CONFIG_PPC64 */ +#ifdef CONFIG_PPC_PKEY + STACK_PT_REGS_OFFSET(STACK_REGS_AMR, amr); + STACK_PT_REGS_OFFSET(STACK_REGS_IAMR, iamr); +#endif #ifdef CONFIG_PPC_KUAP STACK_PT_REGS_OFFSET(STACK_REGS_KUAP, kuap); #endif + #if defined(CONFIG_PPC32) #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) DEFINE(EXC_LVL_SIZE, STACK_EXC_LVL_FRAME_SIZE); @@ -398,47 +405,18 @@ int main(void) #endif /* ! CONFIG_PPC64 */ /* datapage offsets for use by vdso */ - OFFSET(CFG_TB_ORIG_STAMP, vdso_data, tb_orig_stamp); - OFFSET(CFG_TB_TICKS_PER_SEC, vdso_data, tb_ticks_per_sec); - OFFSET(CFG_TB_TO_XS, vdso_data, tb_to_xs); - OFFSET(CFG_TB_UPDATE_COUNT, vdso_data, tb_update_count); - OFFSET(CFG_TZ_MINUTEWEST, vdso_data, tz_minuteswest); - OFFSET(CFG_TZ_DSTTIME, vdso_data, tz_dsttime); - OFFSET(CFG_SYSCALL_MAP32, vdso_data, syscall_map_32); - OFFSET(WTOM_CLOCK_SEC, vdso_data, wtom_clock_sec); - OFFSET(WTOM_CLOCK_NSEC, vdso_data, wtom_clock_nsec); - OFFSET(STAMP_XTIME_SEC, vdso_data, stamp_xtime_sec); - OFFSET(STAMP_XTIME_NSEC, vdso_data, stamp_xtime_nsec); - OFFSET(STAMP_SEC_FRAC, vdso_data, stamp_sec_fraction); - OFFSET(CLOCK_HRTIMER_RES, vdso_data, hrtimer_res); + OFFSET(VDSO_DATA_OFFSET, vdso_arch_data, data); + OFFSET(CFG_TB_TICKS_PER_SEC, vdso_arch_data, tb_ticks_per_sec); #ifdef CONFIG_PPC64 - OFFSET(CFG_ICACHE_BLOCKSZ, vdso_data, icache_block_size); - OFFSET(CFG_DCACHE_BLOCKSZ, vdso_data, dcache_block_size); - OFFSET(CFG_ICACHE_LOGBLOCKSZ, vdso_data, icache_log_block_size); - OFFSET(CFG_DCACHE_LOGBLOCKSZ, vdso_data, dcache_log_block_size); - OFFSET(CFG_SYSCALL_MAP64, vdso_data, syscall_map_64); - OFFSET(TVAL64_TV_SEC, __kernel_old_timeval, tv_sec); - OFFSET(TVAL64_TV_USEC, __kernel_old_timeval, tv_usec); -#endif - OFFSET(TSPC64_TV_SEC, __kernel_timespec, tv_sec); - OFFSET(TSPC64_TV_NSEC, __kernel_timespec, tv_nsec); - OFFSET(TVAL32_TV_SEC, old_timeval32, tv_sec); - OFFSET(TVAL32_TV_USEC, old_timeval32, tv_usec); - OFFSET(TSPC32_TV_SEC, old_timespec32, tv_sec); - OFFSET(TSPC32_TV_NSEC, old_timespec32, tv_nsec); - /* timeval/timezone offsets for use by vdso */ - OFFSET(TZONE_TZ_MINWEST, timezone, tz_minuteswest); - OFFSET(TZONE_TZ_DSTTIME, timezone, tz_dsttime); - - /* Other bits used by the vdso */ - DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); - DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); - DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); - DEFINE(CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE); - DEFINE(CLOCK_MAX, CLOCK_TAI); - DEFINE(NSEC_PER_SEC, NSEC_PER_SEC); - DEFINE(EINVAL, EINVAL); - DEFINE(KTIME_LOW_RES, KTIME_LOW_RES); + OFFSET(CFG_ICACHE_BLOCKSZ, vdso_arch_data, icache_block_size); + OFFSET(CFG_DCACHE_BLOCKSZ, vdso_arch_data, dcache_block_size); + OFFSET(CFG_ICACHE_LOGBLOCKSZ, vdso_arch_data, icache_log_block_size); + OFFSET(CFG_DCACHE_LOGBLOCKSZ, vdso_arch_data, dcache_log_block_size); + OFFSET(CFG_SYSCALL_MAP64, vdso_arch_data, syscall_map); + OFFSET(CFG_SYSCALL_MAP32, vdso_arch_data, compat_syscall_map); +#else + OFFSET(CFG_SYSCALL_MAP32, vdso_arch_data, syscall_map); +#endif #ifdef CONFIG_BUG DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry)); diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index 65ab9fcebd31..6f903e9aa20b 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -655,11 +655,27 @@ static unsigned int index_dir_to_cpu(struct cache_index_dir *index) * On big-core systems, each core has two groups of CPUs each of which * has its own L1-cache. The thread-siblings which share l1-cache with * @cpu can be obtained via cpu_smallcore_mask(). + * + * On some big-core systems, the L2 cache is shared only between some + * groups of siblings. This is already parsed and encoded in + * cpu_l2_cache_mask(). + * + * TODO: cache_lookup_or_instantiate() needs to be made aware of the + * "ibm,thread-groups" property so that cache->shared_cpu_map + * reflects the correct siblings on platforms that have this + * device-tree property. This helper function is only a stop-gap + * solution so that we report the correct siblings to the + * userspace via sysfs. */ -static const struct cpumask *get_big_core_shared_cpu_map(int cpu, struct cache *cache) +static const struct cpumask *get_shared_cpu_map(struct cache_index_dir *index, struct cache *cache) { - if (cache->level == 1) - return cpu_smallcore_mask(cpu); + if (has_big_cores) { + int cpu = index_dir_to_cpu(index); + if (cache->level == 1) + return cpu_smallcore_mask(cpu); + if (cache->level == 2 && thread_group_shares_l2) + return cpu_l2_cache_mask(cpu); + } return &cache->shared_cpu_map; } @@ -670,17 +686,11 @@ show_shared_cpumap(struct kobject *k, struct kobj_attribute *attr, char *buf, bo struct cache_index_dir *index; struct cache *cache; const struct cpumask *mask; - int cpu; index = kobj_to_cache_index_dir(k); cache = index->cache; - if (has_big_cores) { - cpu = index_dir_to_cpu(index); - mask = get_big_core_shared_cpu_map(cpu, cache); - } else { - mask = &cache->shared_cpu_map; - } + mask = get_shared_cpu_map(index, cache); return cpumap_print_to_pagebuf(list, buf, mask); } diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index 1d308780e0d3..4bf33f1b4193 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S @@ -108,15 +108,6 @@ _GLOBAL(__setup_cpu_e6500) #endif /* CONFIG_PPC_E500MC */ #ifdef CONFIG_PPC32 -#ifdef CONFIG_E200 -_GLOBAL(__setup_cpu_e200) - /* enable dedicated debug exception handling resources (Debug APU) */ - mfspr r3,SPRN_HID0 - ori r3,r3,HID0_DAPUEN@l - mtspr SPRN_HID0,r3 - b __setup_e200_ivors -#endif /* CONFIG_E200 */ - #ifdef CONFIG_E500 #ifndef CONFIG_PPC_E500MC _GLOBAL(__setup_cpu_e500v1) diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S deleted file mode 100644 index 704e8b9501ee..000000000000 --- a/arch/powerpc/kernel/cpu_setup_power.S +++ /dev/null @@ -1,252 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * This file contains low level CPU setup functions. - * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org) - */ - -#include <asm/processor.h> -#include <asm/page.h> -#include <asm/cputable.h> -#include <asm/ppc_asm.h> -#include <asm/asm-offsets.h> -#include <asm/cache.h> -#include <asm/book3s/64/mmu-hash.h> - -/* Entry: r3 = crap, r4 = ptr to cputable entry - * - * Note that we can be called twice for pseudo-PVRs - */ -_GLOBAL(__setup_cpu_power7) - mflr r11 - bl __init_hvmode_206 - mtlr r11 - beqlr - li r0,0 - mtspr SPRN_LPID,r0 - LOAD_REG_IMMEDIATE(r0, PCR_MASK) - mtspr SPRN_PCR,r0 - mfspr r3,SPRN_LPCR - li r4,(LPCR_LPES1 >> LPCR_LPES_SH) - bl __init_LPCR_ISA206 - mtlr r11 - blr - -_GLOBAL(__restore_cpu_power7) - mflr r11 - mfmsr r3 - rldicl. r0,r3,4,63 - beqlr - li r0,0 - mtspr SPRN_LPID,r0 - LOAD_REG_IMMEDIATE(r0, PCR_MASK) - mtspr SPRN_PCR,r0 - mfspr r3,SPRN_LPCR - li r4,(LPCR_LPES1 >> LPCR_LPES_SH) - bl __init_LPCR_ISA206 - mtlr r11 - blr - -_GLOBAL(__setup_cpu_power8) - mflr r11 - bl __init_FSCR - bl __init_PMU - bl __init_PMU_ISA207 - bl __init_hvmode_206 - mtlr r11 - beqlr - li r0,0 - mtspr SPRN_LPID,r0 - LOAD_REG_IMMEDIATE(r0, PCR_MASK) - mtspr SPRN_PCR,r0 - mfspr r3,SPRN_LPCR - ori r3, r3, LPCR_PECEDH - li r4,0 /* LPES = 0 */ - bl __init_LPCR_ISA206 - bl __init_HFSCR - bl __init_PMU_HV - bl __init_PMU_HV_ISA207 - mtlr r11 - blr - -_GLOBAL(__restore_cpu_power8) - mflr r11 - bl __init_FSCR - bl __init_PMU - bl __init_PMU_ISA207 - mfmsr r3 - rldicl. r0,r3,4,63 - mtlr r11 - beqlr - li r0,0 - mtspr SPRN_LPID,r0 - LOAD_REG_IMMEDIATE(r0, PCR_MASK) - mtspr SPRN_PCR,r0 - mfspr r3,SPRN_LPCR - ori r3, r3, LPCR_PECEDH - li r4,0 /* LPES = 0 */ - bl __init_LPCR_ISA206 - bl __init_HFSCR - bl __init_PMU_HV - bl __init_PMU_HV_ISA207 - mtlr r11 - blr - -_GLOBAL(__setup_cpu_power10) - mflr r11 - bl __init_FSCR_power10 - bl __init_PMU - bl __init_PMU_ISA31 - b 1f - -_GLOBAL(__setup_cpu_power9) - mflr r11 - bl __init_FSCR_power9 - bl __init_PMU -1: bl __init_hvmode_206 - mtlr r11 - beqlr - li r0,0 - mtspr SPRN_PSSCR,r0 - mtspr SPRN_LPID,r0 - mtspr SPRN_PID,r0 - LOAD_REG_IMMEDIATE(r0, PCR_MASK) - mtspr SPRN_PCR,r0 - mfspr r3,SPRN_LPCR - LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC) - or r3, r3, r4 - LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR) - andc r3, r3, r4 - li r4,0 /* LPES = 0 */ - bl __init_LPCR_ISA300 - bl __init_HFSCR - bl __init_PMU_HV - mtlr r11 - blr - -_GLOBAL(__restore_cpu_power10) - mflr r11 - bl __init_FSCR_power10 - bl __init_PMU - bl __init_PMU_ISA31 - b 1f - -_GLOBAL(__restore_cpu_power9) - mflr r11 - bl __init_FSCR_power9 - bl __init_PMU -1: mfmsr r3 - rldicl. r0,r3,4,63 - mtlr r11 - beqlr - li r0,0 - mtspr SPRN_PSSCR,r0 - mtspr SPRN_LPID,r0 - mtspr SPRN_PID,r0 - LOAD_REG_IMMEDIATE(r0, PCR_MASK) - mtspr SPRN_PCR,r0 - mfspr r3,SPRN_LPCR - LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC) - or r3, r3, r4 - LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR) - andc r3, r3, r4 - li r4,0 /* LPES = 0 */ - bl __init_LPCR_ISA300 - bl __init_HFSCR - bl __init_PMU_HV - mtlr r11 - blr - -__init_hvmode_206: - /* Disable CPU_FTR_HVMODE and exit if MSR:HV is not set */ - mfmsr r3 - rldicl. r0,r3,4,63 - bnelr - ld r5,CPU_SPEC_FEATURES(r4) - LOAD_REG_IMMEDIATE(r6,CPU_FTR_HVMODE | CPU_FTR_P9_TM_HV_ASSIST) - andc r5,r5,r6 - std r5,CPU_SPEC_FEATURES(r4) - blr - -__init_LPCR_ISA206: - /* Setup a sane LPCR: - * Called with initial LPCR in R3 and desired LPES 2-bit value in R4 - * - * LPES = 0b01 (HSRR0/1 used for 0x500) - * PECE = 0b111 - * DPFD = 4 - * HDICE = 0 - * VC = 0b100 (VPM0=1, VPM1=0, ISL=0) - * VRMASD = 0b10000 (L=1, LP=00) - * - * Other bits untouched for now - */ - li r5,0x10 - rldimi r3,r5, LPCR_VRMASD_SH, 64-LPCR_VRMASD_SH-5 - - /* POWER9 has no VRMASD */ -__init_LPCR_ISA300: - rldimi r3,r4, LPCR_LPES_SH, 64-LPCR_LPES_SH-2 - ori r3,r3,(LPCR_PECE0|LPCR_PECE1|LPCR_PECE2) - li r5,4 - rldimi r3,r5, LPCR_DPFD_SH, 64-LPCR_DPFD_SH-3 - clrrdi r3,r3,1 /* clear HDICE */ - li r5,4 - rldimi r3,r5, LPCR_VC_SH, 0 - mtspr SPRN_LPCR,r3 - isync - blr - -__init_FSCR_power10: - mfspr r3, SPRN_FSCR - ori r3, r3, FSCR_PREFIX - mtspr SPRN_FSCR, r3 - // fall through - -__init_FSCR_power9: - mfspr r3, SPRN_FSCR - ori r3, r3, FSCR_SCV - mtspr SPRN_FSCR, r3 - // fall through - -__init_FSCR: - mfspr r3,SPRN_FSCR - ori r3,r3,FSCR_TAR|FSCR_EBB - mtspr SPRN_FSCR,r3 - blr - -__init_HFSCR: - mfspr r3,SPRN_HFSCR - ori r3,r3,HFSCR_TAR|HFSCR_TM|HFSCR_BHRB|HFSCR_PM|\ - HFSCR_DSCR|HFSCR_VECVSX|HFSCR_FP|HFSCR_EBB|HFSCR_MSGP - mtspr SPRN_HFSCR,r3 - blr - -__init_PMU_HV: - li r5,0 - mtspr SPRN_MMCRC,r5 - blr - -__init_PMU_HV_ISA207: - li r5,0 - mtspr SPRN_MMCRH,r5 - blr - -__init_PMU: - li r5,0 - mtspr SPRN_MMCRA,r5 - mtspr SPRN_MMCR0,r5 - mtspr SPRN_MMCR1,r5 - mtspr SPRN_MMCR2,r5 - blr - -__init_PMU_ISA207: - li r5,0 - mtspr SPRN_MMCRS,r5 - blr - -__init_PMU_ISA31: - li r5,0 - mtspr SPRN_MMCR3,r5 - LOAD_REG_IMMEDIATE(r5, MMCRA_BHRB_DISABLE) - mtspr SPRN_MMCRA,r5 - blr diff --git a/arch/powerpc/kernel/cpu_setup_power.c b/arch/powerpc/kernel/cpu_setup_power.c new file mode 100644 index 000000000000..3cca88ee96d7 --- /dev/null +++ b/arch/powerpc/kernel/cpu_setup_power.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2020, Jordan Niethe, IBM Corporation. + * + * This file contains low level CPU setup functions. + * Originally written in assembly by Benjamin Herrenschmidt & various other + * authors. + */ + +#include <asm/reg.h> +#include <asm/synch.h> +#include <linux/bitops.h> +#include <asm/cputable.h> +#include <asm/cpu_setup_power.h> + +/* Disable CPU_FTR_HVMODE and return false if MSR:HV is not set */ +static bool init_hvmode_206(struct cpu_spec *t) +{ + u64 msr; + + msr = mfmsr(); + if (msr & MSR_HV) + return true; + + t->cpu_features &= ~(CPU_FTR_HVMODE | CPU_FTR_P9_TM_HV_ASSIST); + return false; +} + +static void init_LPCR_ISA300(u64 lpcr, u64 lpes) +{ + /* POWER9 has no VRMASD */ + lpcr |= (lpes << LPCR_LPES_SH) & LPCR_LPES; + lpcr |= LPCR_PECE0|LPCR_PECE1|LPCR_PECE2; + lpcr |= (4ull << LPCR_DPFD_SH) & LPCR_DPFD; + lpcr &= ~LPCR_HDICE; /* clear HDICE */ + lpcr |= (4ull << LPCR_VC_SH); + mtspr(SPRN_LPCR, lpcr); + isync(); +} + +/* + * Setup a sane LPCR: + * Called with initial LPCR and desired LPES 2-bit value + * + * LPES = 0b01 (HSRR0/1 used for 0x500) + * PECE = 0b111 + * DPFD = 4 + * HDICE = 0 + * VC = 0b100 (VPM0=1, VPM1=0, ISL=0) + * VRMASD = 0b10000 (L=1, LP=00) + * + * Other bits untouched for now + */ +static void init_LPCR_ISA206(u64 lpcr, u64 lpes) +{ + lpcr |= (0x10ull << LPCR_VRMASD_SH) & LPCR_VRMASD; + init_LPCR_ISA300(lpcr, lpes); +} + +static void init_FSCR(void) +{ + u64 fscr; + + fscr = mfspr(SPRN_FSCR); + fscr |= FSCR_TAR|FSCR_EBB; + mtspr(SPRN_FSCR, fscr); +} + +static void init_FSCR_power9(void) +{ + u64 fscr; + + fscr = mfspr(SPRN_FSCR); + fscr |= FSCR_SCV; + mtspr(SPRN_FSCR, fscr); + init_FSCR(); +} + +static void init_FSCR_power10(void) +{ + u64 fscr; + + fscr = mfspr(SPRN_FSCR); + fscr |= FSCR_PREFIX; + mtspr(SPRN_FSCR, fscr); + init_FSCR_power9(); +} + +static void init_HFSCR(void) +{ + u64 hfscr; + + hfscr = mfspr(SPRN_HFSCR); + hfscr |= HFSCR_TAR|HFSCR_TM|HFSCR_BHRB|HFSCR_PM|HFSCR_DSCR|\ + HFSCR_VECVSX|HFSCR_FP|HFSCR_EBB|HFSCR_MSGP; + mtspr(SPRN_HFSCR, hfscr); +} + +static void init_PMU_HV(void) +{ + mtspr(SPRN_MMCRC, 0); +} + +static void init_PMU_HV_ISA207(void) +{ + mtspr(SPRN_MMCRH, 0); +} + +static void init_PMU(void) +{ + mtspr(SPRN_MMCRA, 0); + mtspr(SPRN_MMCR0, 0); + mtspr(SPRN_MMCR1, 0); + mtspr(SPRN_MMCR2, 0); +} + +static void init_PMU_ISA207(void) +{ + mtspr(SPRN_MMCRS, 0); +} + +static void init_PMU_ISA31(void) +{ + mtspr(SPRN_MMCR3, 0); + mtspr(SPRN_MMCRA, MMCRA_BHRB_DISABLE); + mtspr(SPRN_MMCR0, MMCR0_PMCCEXT); +} + +/* + * Note that we can be called twice of pseudo-PVRs. + * The parameter offset is not used. + */ + +void __setup_cpu_power7(unsigned long offset, struct cpu_spec *t) +{ + if (!init_hvmode_206(t)) + return; + + mtspr(SPRN_LPID, 0); + mtspr(SPRN_PCR, PCR_MASK); + init_LPCR_ISA206(mfspr(SPRN_LPCR), LPCR_LPES1 >> LPCR_LPES_SH); +} + +void __restore_cpu_power7(void) +{ + u64 msr; + + msr = mfmsr(); + if (!(msr & MSR_HV)) + return; + + mtspr(SPRN_LPID, 0); + mtspr(SPRN_PCR, PCR_MASK); + init_LPCR_ISA206(mfspr(SPRN_LPCR), LPCR_LPES1 >> LPCR_LPES_SH); +} + +void __setup_cpu_power8(unsigned long offset, struct cpu_spec *t) +{ + init_FSCR(); + init_PMU(); + init_PMU_ISA207(); + + if (!init_hvmode_206(t)) + return; + + mtspr(SPRN_LPID, 0); + mtspr(SPRN_PCR, PCR_MASK); + init_LPCR_ISA206(mfspr(SPRN_LPCR) | LPCR_PECEDH, 0); /* LPES = 0 */ + init_HFSCR(); + init_PMU_HV(); + init_PMU_HV_ISA207(); +} + +void __restore_cpu_power8(void) +{ + u64 msr; + + init_FSCR(); + init_PMU(); + init_PMU_ISA207(); + + msr = mfmsr(); + if (!(msr & MSR_HV)) + return; + + mtspr(SPRN_LPID, 0); + mtspr(SPRN_PCR, PCR_MASK); + init_LPCR_ISA206(mfspr(SPRN_LPCR) | LPCR_PECEDH, 0); /* LPES = 0 */ + init_HFSCR(); + init_PMU_HV(); + init_PMU_HV_ISA207(); +} + +void __setup_cpu_power9(unsigned long offset, struct cpu_spec *t) +{ + init_FSCR_power9(); + init_PMU(); + + if (!init_hvmode_206(t)) + return; + + mtspr(SPRN_PSSCR, 0); + mtspr(SPRN_LPID, 0); + mtspr(SPRN_PID, 0); + mtspr(SPRN_PCR, PCR_MASK); + init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\ + LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0); + init_HFSCR(); + init_PMU_HV(); +} + +void __restore_cpu_power9(void) +{ + u64 msr; + + init_FSCR_power9(); + init_PMU(); + + msr = mfmsr(); + if (!(msr & MSR_HV)) + return; + + mtspr(SPRN_PSSCR, 0); + mtspr(SPRN_LPID, 0); + mtspr(SPRN_PID, 0); + mtspr(SPRN_PCR, PCR_MASK); + init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\ + LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0); + init_HFSCR(); + init_PMU_HV(); +} + +void __setup_cpu_power10(unsigned long offset, struct cpu_spec *t) +{ + init_FSCR_power10(); + init_PMU(); + init_PMU_ISA31(); + + if (!init_hvmode_206(t)) + return; + + mtspr(SPRN_PSSCR, 0); + mtspr(SPRN_LPID, 0); + mtspr(SPRN_PID, 0); + mtspr(SPRN_PCR, PCR_MASK); + init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\ + LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0); + init_HFSCR(); + init_PMU_HV(); +} + +void __restore_cpu_power10(void) +{ + u64 msr; + + init_FSCR_power10(); + init_PMU(); + init_PMU_ISA31(); + + msr = mfmsr(); + if (!(msr & MSR_HV)) + return; + + mtspr(SPRN_PSSCR, 0); + mtspr(SPRN_LPID, 0); + mtspr(SPRN_PID, 0); + mtspr(SPRN_PCR, PCR_MASK); + init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\ + LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0); + init_HFSCR(); + init_PMU_HV(); +} diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 29de58d4dfb7..65f35ec052d4 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -36,7 +36,6 @@ const char *powerpc_base_platform; * and ppc64 */ #ifdef CONFIG_PPC32 -extern void __setup_cpu_e200(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_e500v1(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_e500v2(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_e500mc(unsigned long offset, struct cpu_spec* spec); @@ -60,19 +59,15 @@ extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec); #endif /* CONFIG_PPC32 */ #ifdef CONFIG_PPC64 +#include <asm/cpu_setup_power.h> extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_ppc970MP(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_pa6t(unsigned long offset, struct cpu_spec* spec); extern void __restore_cpu_pa6t(void); extern void __restore_cpu_ppc970(void); -extern void __setup_cpu_power7(unsigned long offset, struct cpu_spec* spec); -extern void __restore_cpu_power7(void); -extern void __setup_cpu_power8(unsigned long offset, struct cpu_spec* spec); -extern void __restore_cpu_power8(void); -extern void __setup_cpu_power9(unsigned long offset, struct cpu_spec* spec); -extern void __restore_cpu_power9(void); -extern void __setup_cpu_power10(unsigned long offset, struct cpu_spec* spec); -extern void __restore_cpu_power10(void); +extern long __machine_check_early_realmode_p7(struct pt_regs *regs); +extern long __machine_check_early_realmode_p8(struct pt_regs *regs); +extern long __machine_check_early_realmode_p9(struct pt_regs *regs); #endif /* CONFIG_PPC64 */ #if defined(CONFIG_E500) extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec); @@ -616,46 +611,8 @@ static struct cpu_spec __initdata cpu_specs[] = { #endif /* CONFIG_PPC_BOOK3S_64 */ #ifdef CONFIG_PPC32 -#ifdef CONFIG_PPC_BOOK3S_6xx - { /* 603 */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00030000, - .cpu_name = "603", - .cpu_features = CPU_FTRS_603, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, - .mmu_features = 0, - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, - .machine_check = machine_check_generic, - .platform = "ppc603", - }, - { /* 603e */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00060000, - .cpu_name = "603e", - .cpu_features = CPU_FTRS_603, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, - .mmu_features = 0, - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, - .machine_check = machine_check_generic, - .platform = "ppc603", - }, - { /* 603ev */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00070000, - .cpu_name = "603ev", - .cpu_features = CPU_FTRS_603, - .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, - .mmu_features = 0, - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, - .machine_check = machine_check_generic, - .platform = "ppc603", - }, +#ifdef CONFIG_PPC_BOOK3S_32 +#ifdef CONFIG_PPC_BOOK3S_604 { /* 604 */ .pvr_mask = 0xffff0000, .pvr_value = 0x00040000, @@ -1145,6 +1102,47 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_generic, .platform = "ppc7450", }, +#endif /* CONFIG_PPC_BOOK3S_604 */ +#ifdef CONFIG_PPC_BOOK3S_603 + { /* 603 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00030000, + .cpu_name = "603", + .cpu_features = CPU_FTRS_603, + .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .mmu_features = 0, + .icache_bsize = 32, + .dcache_bsize = 32, + .cpu_setup = __setup_cpu_603, + .machine_check = machine_check_generic, + .platform = "ppc603", + }, + { /* 603e */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00060000, + .cpu_name = "603e", + .cpu_features = CPU_FTRS_603, + .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .mmu_features = 0, + .icache_bsize = 32, + .dcache_bsize = 32, + .cpu_setup = __setup_cpu_603, + .machine_check = machine_check_generic, + .platform = "ppc603", + }, + { /* 603ev */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00070000, + .cpu_name = "603ev", + .cpu_features = CPU_FTRS_603, + .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, + .mmu_features = 0, + .icache_bsize = 32, + .dcache_bsize = 32, + .cpu_setup = __setup_cpu_603, + .machine_check = machine_check_generic, + .platform = "ppc603", + }, { /* 82xx (8240, 8245, 8260 are all 603e cores) */ .pvr_mask = 0x7fff0000, .pvr_value = 0x00810000, @@ -1234,6 +1232,8 @@ static struct cpu_spec __initdata cpu_specs[] = { .platform = "ppc603", }, #endif +#endif /* CONFIG_PPC_BOOK3S_603 */ +#ifdef CONFIG_PPC_BOOK3S_604 { /* default match, we assume split I/D cache & TB (non-601)... */ .pvr_mask = 0x00000000, .pvr_value = 0x00000000, @@ -1246,7 +1246,8 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_generic, .platform = "ppc603", }, -#endif /* CONFIG_PPC_BOOK3S_6xx */ +#endif /* CONFIG_PPC_BOOK3S_604 */ +#endif /* CONFIG_PPC_BOOK3S_32 */ #ifdef CONFIG_PPC_8xx { /* 8xx */ .pvr_mask = 0xffff0000, @@ -1540,6 +1541,7 @@ static struct cpu_spec __initdata cpu_specs[] = { #endif /* CONFIG_40x */ #ifdef CONFIG_44x +#ifndef CONFIG_PPC_47x { .pvr_mask = 0xf0000fff, .pvr_value = 0x40000850, @@ -1822,7 +1824,19 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_440A, .platform = "ppc440", }, -#ifdef CONFIG_PPC_47x + { /* default match */ + .pvr_mask = 0x00000000, + .pvr_value = 0x00000000, + .cpu_name = "(generic 44x PPC)", + .cpu_features = CPU_FTRS_44X, + .cpu_user_features = COMMON_USER_BOOKE, + .mmu_features = MMU_FTR_TYPE_44x, + .icache_bsize = 32, + .dcache_bsize = 32, + .machine_check = machine_check_4xx, + .platform = "ppc440", + } +#else /* CONFIG_PPC_47x */ { /* 476 DD2 core */ .pvr_mask = 0xffffffff, .pvr_value = 0x11a52080, @@ -1879,65 +1893,20 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_47x, .platform = "ppc470", }, -#endif /* CONFIG_PPC_47x */ { /* default match */ .pvr_mask = 0x00000000, .pvr_value = 0x00000000, - .cpu_name = "(generic 44x PPC)", - .cpu_features = CPU_FTRS_44X, + .cpu_name = "(generic 47x PPC)", + .cpu_features = CPU_FTRS_47X, .cpu_user_features = COMMON_USER_BOOKE, - .mmu_features = MMU_FTR_TYPE_44x, + .mmu_features = MMU_FTR_TYPE_47x, .icache_bsize = 32, - .dcache_bsize = 32, - .machine_check = machine_check_4xx, - .platform = "ppc440", + .dcache_bsize = 128, + .machine_check = machine_check_47x, + .platform = "ppc470", } +#endif /* CONFIG_PPC_47x */ #endif /* CONFIG_44x */ -#ifdef CONFIG_E200 - { /* e200z5 */ - .pvr_mask = 0xfff00000, - .pvr_value = 0x81000000, - .cpu_name = "e200z5", - /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ - .cpu_features = CPU_FTRS_E200, - .cpu_user_features = COMMON_USER_BOOKE | - PPC_FEATURE_HAS_EFP_SINGLE | - PPC_FEATURE_UNIFIED_CACHE, - .mmu_features = MMU_FTR_TYPE_FSL_E, - .dcache_bsize = 32, - .machine_check = machine_check_e200, - .platform = "ppc5554", - }, - { /* e200z6 */ - .pvr_mask = 0xfff00000, - .pvr_value = 0x81100000, - .cpu_name = "e200z6", - /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ - .cpu_features = CPU_FTRS_E200, - .cpu_user_features = COMMON_USER_BOOKE | - PPC_FEATURE_HAS_SPE_COMP | - PPC_FEATURE_HAS_EFP_SINGLE_COMP | - PPC_FEATURE_UNIFIED_CACHE, - .mmu_features = MMU_FTR_TYPE_FSL_E, - .dcache_bsize = 32, - .machine_check = machine_check_e200, - .platform = "ppc5554", - }, - { /* default match */ - .pvr_mask = 0x00000000, - .pvr_value = 0x00000000, - .cpu_name = "(generic E200 PPC)", - .cpu_features = CPU_FTRS_E200, - .cpu_user_features = COMMON_USER_BOOKE | - PPC_FEATURE_HAS_EFP_SINGLE | - PPC_FEATURE_UNIFIED_CACHE, - .mmu_features = MMU_FTR_TYPE_FSL_E, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_e200, - .machine_check = machine_check_e200, - .platform = "ppc5554", - } -#endif /* CONFIG_E200 */ #endif /* CONFIG_PPC32 */ #ifdef CONFIG_E500 #ifdef CONFIG_PPC32 diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index a1c744194018..111249fd619d 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -10,6 +10,63 @@ #include <linux/pci.h> #include <asm/iommu.h> +#ifdef CONFIG_ARCH_HAS_DMA_MAP_DIRECT +#define can_map_direct(dev, addr) \ + ((dev)->bus_dma_limit >= phys_to_dma((dev), (addr))) + +bool arch_dma_map_page_direct(struct device *dev, phys_addr_t addr) +{ + if (likely(!dev->bus_dma_limit)) + return false; + + return can_map_direct(dev, addr); +} + +#define is_direct_handle(dev, h) ((h) >= (dev)->archdata.dma_offset) + +bool arch_dma_unmap_page_direct(struct device *dev, dma_addr_t dma_handle) +{ + if (likely(!dev->bus_dma_limit)) + return false; + + return is_direct_handle(dev, dma_handle); +} + +bool arch_dma_map_sg_direct(struct device *dev, struct scatterlist *sg, + int nents) +{ + struct scatterlist *s; + int i; + + if (likely(!dev->bus_dma_limit)) + return false; + + for_each_sg(sg, s, nents, i) { + if (!can_map_direct(dev, sg_phys(s) + s->offset + s->length)) + return false; + } + + return true; +} + +bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg, + int nents) +{ + struct scatterlist *s; + int i; + + if (likely(!dev->bus_dma_limit)) + return false; + + for_each_sg(sg, s, nents, i) { + if (!is_direct_handle(dev, s->dma_address + s->length)) + return false; + } + + return true; +} +#endif /* CONFIG_ARCH_HAS_DMA_MAP_DIRECT */ + /* * Generic iommu implementation */ @@ -90,8 +147,18 @@ int dma_iommu_dma_supported(struct device *dev, u64 mask) struct iommu_table *tbl = get_iommu_table_base(dev); if (dev_is_pci(dev) && dma_iommu_bypass_supported(dev, mask)) { - dev->dma_ops_bypass = true; - dev_dbg(dev, "iommu: 64-bit OK, using fixed ops\n"); + /* + * dma_iommu_bypass_supported() sets dma_max when there is + * 1:1 mapping but it is somehow limited. + * ibm,pmemory is one example. + */ + dev->dma_ops_bypass = dev->bus_dma_limit == 0; + if (!dev->dma_ops_bypass) + dev_warn(dev, + "iommu: 64-bit OK but direct DMA is limited by %llx\n", + dev->bus_dma_limit); + else + dev_dbg(dev, "iommu: 64-bit OK, using fixed ops\n"); return 1; } diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c index 1098863e17ee..b5478b72c08c 100644 --- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c @@ -69,7 +69,6 @@ static int hv_mode; static struct { u64 lpcr; - u64 lpcr_clear; u64 hfscr; u64 fscr; u64 pcr; @@ -79,24 +78,7 @@ static void (*init_pmu_registers)(void); static void __restore_cpu_cpufeatures(void) { - u64 lpcr; - - /* - * LPCR is restored by the power on engine already. It can be changed - * after early init e.g., by radix enable, and we have no unified API - * for saving and restoring such SPRs. - * - * This ->restore hook should really be removed from idle and register - * restore moved directly into the idle restore code, because this code - * doesn't know how idle is implemented or what it needs restored here. - * - * The best we can do to accommodate secondary boot and idle restore - * for now is "or" LPCR with existing. - */ - lpcr = mfspr(SPRN_LPCR); - lpcr |= system_registers.lpcr; - lpcr &= ~system_registers.lpcr_clear; - mtspr(SPRN_LPCR, lpcr); + mtspr(SPRN_LPCR, system_registers.lpcr); if (hv_mode) { mtspr(SPRN_LPID, 0); mtspr(SPRN_HFSCR, system_registers.hfscr); @@ -273,13 +255,6 @@ static int __init feat_enable_idle_nap(struct dt_cpu_feature *f) return 1; } -static int __init feat_enable_align_dsisr(struct dt_cpu_feature *f) -{ - cur_cpu_spec->cpu_features &= ~CPU_FTR_NODSISRALIGN; - - return 1; -} - static int __init feat_enable_idle_stop(struct dt_cpu_feature *f) { u64 lpcr; @@ -317,7 +292,6 @@ static int __init feat_enable_mmu_hash_v3(struct dt_cpu_feature *f) { u64 lpcr; - system_registers.lpcr_clear |= (LPCR_ISL | LPCR_UPRT | LPCR_HR); lpcr = mfspr(SPRN_LPCR); lpcr &= ~(LPCR_ISL | LPCR_UPRT | LPCR_HR); mtspr(SPRN_LPCR, lpcr); @@ -454,6 +428,7 @@ static void init_pmu_power10(void) mtspr(SPRN_MMCR3, 0); mtspr(SPRN_MMCRA, MMCRA_BHRB_DISABLE); + mtspr(SPRN_MMCR0, MMCR0_PMCCEXT); } static int __init feat_enable_pmu_power10(struct dt_cpu_feature *f) @@ -641,7 +616,7 @@ static struct dt_cpu_feature_match __initdata {"tm-suspend-hypervisor-assist", feat_enable, CPU_FTR_P9_TM_HV_ASSIST}, {"tm-suspend-xer-so-bug", feat_enable, CPU_FTR_P9_TM_XER_SO_BUG}, {"idle-nap", feat_enable_idle_nap, 0}, - {"alignment-interrupt-dsisr", feat_enable_align_dsisr, 0}, + /* alignment-interrupt-dsisr ignored */ {"idle-stop", feat_enable_idle_stop, 0}, {"machine-check-power8", feat_enable_mce_power8, 0}, {"performance-monitor-power8", feat_enable_pmu_power8, 0}, diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 8cdc8bcde703..1c9b0ccc2172 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -234,7 +234,10 @@ transfer_to_handler_cont: mtspr SPRN_SRR0,r11 mtspr SPRN_SRR1,r10 mtlr r9 - RFI /* jump to handler, enable MMU */ + rfi /* jump to handler, enable MMU */ +#ifdef CONFIG_40x + b . /* Prevent prefetch past rfi */ +#endif #if defined (CONFIG_PPC_BOOK3S_32) || defined(CONFIG_E500) 4: rlwinm r12,r12,0,~_TLF_NAPPING @@ -263,7 +266,10 @@ _ASM_NOKPROBE_SYMBOL(transfer_to_handler_cont) LOAD_REG_IMMEDIATE(r0, MSR_KERNEL) mtspr SPRN_SRR0,r12 mtspr SPRN_SRR1,r0 - RFI + rfi +#ifdef CONFIG_40x + b . /* Prevent prefetch past rfi */ +#endif reenable_mmu: /* @@ -321,7 +327,10 @@ stack_ovf: #endif mtspr SPRN_SRR0,r9 mtspr SPRN_SRR1,r10 - RFI + rfi +#ifdef CONFIG_40x + b . /* Prevent prefetch past rfi */ +#endif _ASM_NOKPROBE_SYMBOL(stack_ovf) #endif @@ -439,15 +448,13 @@ syscall_exit_cont: andis. r10,r0,DBCR0_IDM@h bnel- load_dbcr0 #endif -#ifdef CONFIG_44x -BEGIN_MMU_FTR_SECTION +#ifdef CONFIG_PPC_47x lis r4,icache_44x_need_flush@ha lwz r5,icache_44x_need_flush@l(r4) cmplwi cr0,r5,0 bne- 2f +#endif /* CONFIG_PPC_47x */ 1: -END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_47x) -#endif /* CONFIG_44x */ BEGIN_FTR_SECTION lwarx r7,0,r1 END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) @@ -470,7 +477,10 @@ syscall_exit_finish: #endif mtspr SPRN_SRR0,r7 mtspr SPRN_SRR1,r8 - RFI + rfi +#ifdef CONFIG_40x + b . /* Prevent prefetch past rfi */ +#endif _ASM_NOKPROBE_SYMBOL(syscall_exit_finish) #ifdef CONFIG_44x 2: li r7,0 @@ -600,7 +610,10 @@ ret_from_kernel_syscall: #endif mtspr SPRN_SRR0, r9 mtspr SPRN_SRR1, r10 - RFI + rfi +#ifdef CONFIG_40x + b . /* Prevent prefetch past rfi */ +#endif _ASM_NOKPROBE_SYMBOL(ret_from_kernel_syscall) /* @@ -671,7 +684,7 @@ handle_page_fault: mr r5,r3 addi r3,r1,STACK_FRAME_OVERHEAD lwz r4,_DAR(r1) - bl bad_page_fault + bl __bad_page_fault b ret_from_except_full #ifdef CONFIG_PPC_BOOK3S_32 @@ -803,7 +816,10 @@ fast_exception_return: REST_GPR(9, r11) REST_GPR(12, r11) lwz r11,GPR11(r11) - RFI + rfi +#ifdef CONFIG_40x + b . /* Prevent prefetch past rfi */ +#endif _ASM_NOKPROBE_SYMBOL(fast_exception_return) #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) @@ -948,10 +964,7 @@ restore_kuap: /* interrupts are hard-disabled at this point */ restore: -#ifdef CONFIG_44x -BEGIN_MMU_FTR_SECTION - b 1f -END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) +#if defined(CONFIG_44x) && !defined(CONFIG_PPC_47x) lis r4,icache_44x_need_flush@ha lwz r5,icache_44x_need_flush@l(r4) cmplwi cr0,r5,0 @@ -1027,7 +1040,7 @@ exc_exit_restart: lwz r1,GPR1(r1) .globl exc_exit_restart_end exc_exit_restart_end: - RFI + rfi _ASM_NOKPROBE_SYMBOL(exc_exit_restart) _ASM_NOKPROBE_SYMBOL(exc_exit_restart_end) @@ -1356,7 +1369,7 @@ _GLOBAL(enter_rtas) stw r7, THREAD + RTAS_SP(r2) mtspr SPRN_SRR0,r8 mtspr SPRN_SRR1,r9 - RFI + rfi 1: tophys_novmstack r9, r1 #ifdef CONFIG_VMAP_STACK li r0, MSR_KERNEL & ~MSR_IR /* can take DTLB miss */ @@ -1371,6 +1384,6 @@ _GLOBAL(enter_rtas) stw r0, THREAD + RTAS_SP(r7) mtspr SPRN_SRR0,r8 mtspr SPRN_SRR1,r9 - RFI /* return to caller */ + rfi /* return to caller */ _ASM_NOKPROBE_SYMBOL(enter_rtas) #endif /* CONFIG_PPC_RTAS */ diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 2f3846192ec7..33ddfeef4fe9 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -75,7 +75,7 @@ BEGIN_FTR_SECTION bne .Ltabort_syscall END_FTR_SECTION_IFSET(CPU_FTR_TM) #endif - INTERRUPT_TO_KERNEL + SCV_INTERRUPT_TO_KERNEL mr r10,r1 ld r1,PACAKSAVE(r13) std r10,0(r1) @@ -653,8 +653,8 @@ _ASM_NOKPROBE_SYMBOL(fast_interrupt_return) kuap_check_amr r3, r4 ld r5,_MSR(r1) andi. r0,r5,MSR_PR - bne .Lfast_user_interrupt_return - kuap_restore_amr r3, r4 + bne .Lfast_user_interrupt_return_amr + kuap_kernel_restore r3, r4 andi. r0,r5,MSR_RI li r3,0 /* 0 return value, no EMULATE_STACK_STORE */ bne+ .Lfast_kernel_interrupt_return @@ -674,6 +674,8 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return) cmpdi r3,0 bne- .Lrestore_nvgprs +.Lfast_user_interrupt_return_amr: + kuap_user_restore r3, r4 .Lfast_user_interrupt_return: ld r11,_NIP(r1) ld r12,_MSR(r1) @@ -967,7 +969,7 @@ _GLOBAL(enter_prom) mtsrr1 r11 rfi #else /* CONFIG_PPC_BOOK3E */ - LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE) + LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_LE) andc r11,r11,r12 mtsrr1 r11 RFI_TO_KERNEL diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index f579ce46eef2..74d07dc0bb48 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S @@ -1023,7 +1023,7 @@ storage_fault_common: mr r5,r3 addi r3,r1,STACK_FRAME_OVERHEAD ld r4,_DAR(r1) - bl bad_page_fault + bl __bad_page_fault b ret_from_except /* diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 4d01f09ecf80..6e53f7638737 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1059,7 +1059,7 @@ EXC_COMMON_BEGIN(system_reset_common) ld r10,SOFTE(r1) stb r10,PACAIRQSOFTMASK(r13) - kuap_restore_amr r9, r10 + kuap_kernel_restore r9, r10 EXCEPTION_RESTORE_REGS RFI_TO_USER_OR_KERNEL @@ -2875,7 +2875,7 @@ EXC_COMMON_BEGIN(soft_nmi_common) ld r10,SOFTE(r1) stb r10,PACAIRQSOFTMASK(r13) - kuap_restore_amr r9, r10 + kuap_kernel_restore r9, r10 EXCEPTION_RESTORE_REGS hsrr=0 RFI_TO_KERNEL @@ -2993,6 +2993,25 @@ TRAMP_REAL_BEGIN(entry_flush_fallback) ld r11,PACA_EXRFI+EX_R11(r13) blr +/* + * The SCV entry flush happens with interrupts enabled, so it must disable + * to prevent EXRFI being clobbered by NMIs (e.g., soft_nmi_common). r10 + * (containing LR) does not need to be preserved here because scv entry + * puts 0 in the pt_regs, CTR can be clobbered for the same reason. + */ +TRAMP_REAL_BEGIN(scv_entry_flush_fallback) + li r10,0 + mtmsrd r10,1 + lbz r10,PACAIRQHAPPENED(r13) + ori r10,r10,PACA_IRQ_HARD_DIS + stb r10,PACAIRQHAPPENED(r13) + std r11,PACA_EXRFI+EX_R11(r13) + L1D_DISPLACEMENT_FLUSH + ld r11,PACA_EXRFI+EX_R11(r13) + li r10,MSR_RI + mtmsrd r10,1 + blr + TRAMP_REAL_BEGIN(rfi_flush_fallback) SET_SCRATCH0(r13); GET_PACA(r13); @@ -3259,7 +3278,7 @@ handle_page_fault: mr r5,r3 addi r3,r1,STACK_FRAME_OVERHEAD ld r4,_DAR(r1) - bl bad_page_fault + bl __bad_page_fault b interrupt_return /* We have a data breakpoint exception - handle it */ diff --git a/arch/powerpc/kernel/firmware.c b/arch/powerpc/kernel/firmware.c index fe48d319d490..c9e2819b095a 100644 --- a/arch/powerpc/kernel/firmware.c +++ b/arch/powerpc/kernel/firmware.c @@ -14,6 +14,7 @@ #include <linux/of.h> #include <asm/firmware.h> +#include <asm/kvm_guest.h> #ifdef CONFIG_PPC64 unsigned long powerpc_firmware_features __read_mostly; @@ -21,17 +22,19 @@ EXPORT_SYMBOL_GPL(powerpc_firmware_features); #endif #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_KVM_GUEST) -bool is_kvm_guest(void) +DEFINE_STATIC_KEY_FALSE(kvm_guest); +bool check_kvm_guest(void) { struct device_node *hyper_node; hyper_node = of_find_node_by_path("/hypervisor"); if (!hyper_node) - return 0; + return false; if (!of_device_is_compatible(hyper_node, "linux,kvm")) - return 0; + return false; - return 1; + static_branch_enable(&kvm_guest); + return true; } #endif diff --git a/arch/powerpc/kernel/head_32.h b/arch/powerpc/kernel/head_32.h index 7c767765071d..a2f72c966baf 100644 --- a/arch/powerpc/kernel/head_32.h +++ b/arch/powerpc/kernel/head_32.h @@ -40,38 +40,31 @@ .macro EXCEPTION_PROLOG_1 for_rtas=0 #ifdef CONFIG_VMAP_STACK - mr r11, r1 + mtspr SPRN_SPRG_SCRATCH2,r1 subi r1, r1, INT_FRAME_SIZE /* use r1 if kernel */ beq 1f mfspr r1,SPRN_SPRG_THREAD lwz r1,TASK_STACK-THREAD(r1) addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE +1: + mtcrf 0x7f, r1 + bt 32 - THREAD_ALIGN_SHIFT, stack_overflow #else subi r11, r1, INT_FRAME_SIZE /* use r1 if kernel */ beq 1f mfspr r11,SPRN_SPRG_THREAD lwz r11,TASK_STACK-THREAD(r11) addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE -#endif -1: - tophys_novmstack r11, r11 -#ifdef CONFIG_VMAP_STACK - mtcrf 0x7f, r1 - bt 32 - THREAD_ALIGN_SHIFT, stack_overflow +1: tophys(r11, r11) #endif .endm .macro EXCEPTION_PROLOG_2 handle_dar_dsisr=0 #ifdef CONFIG_VMAP_STACK - mtcr r10 - li r10, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */ - mtmsr r10 + li r11, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */ + mtmsr r11 isync -#else - stw r10,_CCR(r11) /* save registers */ -#endif - mfspr r10, SPRN_SPRG_SCRATCH0 -#ifdef CONFIG_VMAP_STACK + mfspr r11, SPRN_SPRG_SCRATCH2 stw r11,GPR1(r1) stw r11,0(r1) mr r11, r1 @@ -80,14 +73,12 @@ stw r1,0(r11) tovirt(r1, r11) /* set new kernel sp */ #endif + stw r10,_CCR(r11) /* save registers */ stw r12,GPR12(r11) stw r9,GPR9(r11) - stw r10,GPR10(r11) -#ifdef CONFIG_VMAP_STACK - mfcr r10 - stw r10, _CCR(r11) -#endif + mfspr r10,SPRN_SPRG_SCRATCH0 mfspr r12,SPRN_SPRG_SCRATCH1 + stw r10,GPR10(r11) stw r12,GPR11(r11) mflr r10 stw r10,_LINK(r11) @@ -101,7 +92,6 @@ stw r10, _DSISR(r11) .endif lwz r9, SRR1(r12) - andi. r10, r9, MSR_PR lwz r12, SRR0(r12) #else mfspr r12,SPRN_SRR0 @@ -131,18 +121,28 @@ #ifdef CONFIG_VMAP_STACK mfspr r11, SPRN_SRR0 mtctr r11 -#endif andi. r11, r9, MSR_PR - lwz r11,TASK_STACK-THREAD(r12) + mr r11, r1 + lwz r1,TASK_STACK-THREAD(r12) beq- 99f - addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE -#ifdef CONFIG_VMAP_STACK + addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE li r10, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */ mtmsr r10 isync + tovirt(r12, r12) + stw r11,GPR1(r1) + stw r11,0(r1) + mr r11, r1 +#else + andi. r11, r9, MSR_PR + lwz r11,TASK_STACK-THREAD(r12) + beq- 99f + addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE + tophys(r11, r11) + stw r1,GPR1(r11) + stw r1,0(r11) + tovirt(r1, r11) /* set new kernel sp */ #endif - tovirt_vmstack r12, r12 - tophys_novmstack r11, r11 mflr r10 stw r10, _LINK(r11) #ifdef CONFIG_VMAP_STACK @@ -150,9 +150,6 @@ #else mfspr r10,SPRN_SRR0 #endif - stw r1,GPR1(r11) - stw r1,0(r11) - tovirt_novmstack r1, r11 /* set new kernel sp */ stw r10,_NIP(r11) mfcr r10 rlwinm r10,r10,0,4,2 /* Clear SO bit in CR */ @@ -222,7 +219,10 @@ #endif mtspr SPRN_SRR1,r10 mtspr SPRN_SRR0,r11 - RFI /* jump to handler, enable MMU */ + rfi /* jump to handler, enable MMU */ +#ifdef CONFIG_40x + b . /* Prevent prefetch past rfi */ +#endif 99: b ret_from_kernel_syscall .endm diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 1510b2a56669..ece7f97bafff 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -41,6 +41,11 @@ #include <asm/ppc-opcode.h> #include <asm/export.h> #include <asm/feature-fixups.h> +#ifdef CONFIG_PPC_BOOK3S +#include <asm/exception-64s.h> +#else +#include <asm/exception-64e.h> +#endif /* The physical memory is laid out such that the secondary processor * spin code sits at 0x0000...0x00ff. On server, the vectors follow @@ -417,6 +422,10 @@ generic_secondary_common_init: /* From now on, r24 is expected to be logical cpuid */ mr r24,r5 + /* Create a temp kernel stack for use before relocation is on. */ + ld r1,PACAEMERGSP(r13) + subi r1,r1,STACK_FRAME_OVERHEAD + /* See if we need to call a cpu state restore handler */ LOAD_REG_ADDR(r23, cur_cpu_spec) ld r23,0(r23) @@ -445,10 +454,6 @@ generic_secondary_common_init: sync /* order paca.run and cur_cpu_spec */ isync /* In case code patching happened */ - /* Create a temp kernel stack for use before relocation is on. */ - ld r1,PACAEMERGSP(r13) - subi r1,r1,STACK_FRAME_OVERHEAD - b __secondary_start #endif /* SMP */ @@ -829,7 +834,7 @@ __secondary_start: mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 - RFI + RFI_TO_KERNEL b . /* prevent speculative execution */ /* @@ -865,8 +870,7 @@ enable_64b_mode: oris r11,r11,0x8000 /* CM bit set, we'll set ICM later */ mtmsr r11 #else /* CONFIG_PPC_BOOK3E */ - li r12,(MSR_64BIT | MSR_ISF)@highest - sldi r12,r12,48 + LOAD_REG_IMMEDIATE(r12, MSR_64BIT) or r11,r11,r12 mtmsrd r11 isync @@ -966,7 +970,7 @@ start_here_multiplatform: ld r4,PACAKMSR(r13) mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 - RFI + RFI_TO_KERNEL b . /* prevent speculative execution */ /* This is where all platforms converge execution */ @@ -990,7 +994,7 @@ start_here_common: bl start_kernel /* Not reached */ - trap +0: trap EMIT_BUG_ENTRY 0b, __FILE__, __LINE__, 0 .previous diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index ee0bfebc375f..52702f3db6df 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -43,16 +43,6 @@ .endm /* - * We need an ITLB miss handler for kernel addresses if: - * - Either we have modules - * - Or we have not pinned the first 8M - */ -#if defined(CONFIG_MODULES) || !defined(CONFIG_PIN_TLB_TEXT) || \ - defined(CONFIG_DEBUG_PAGEALLOC) -#define ITLB_MISS_KERNEL 1 -#endif - -/* * Value for the bits that have fixed value in RPN entries. * Also used for tagging DAR for DTLBerror. */ @@ -190,32 +180,31 @@ SystemCall: */ #ifdef CONFIG_8xx_CPU15 -#define INVALIDATE_ADJACENT_PAGES_CPU15(addr) \ - addi addr, addr, PAGE_SIZE; \ - tlbie addr; \ - addi addr, addr, -(PAGE_SIZE << 1); \ - tlbie addr; \ - addi addr, addr, PAGE_SIZE +#define INVALIDATE_ADJACENT_PAGES_CPU15(addr, tmp) \ + addi tmp, addr, PAGE_SIZE; \ + tlbie tmp; \ + addi tmp, addr, -PAGE_SIZE; \ + tlbie tmp #else -#define INVALIDATE_ADJACENT_PAGES_CPU15(addr) +#define INVALIDATE_ADJACENT_PAGES_CPU15(addr, tmp) #endif InstructionTLBMiss: - mtspr SPRN_SPRG_SCRATCH0, r10 - mtspr SPRN_SPRG_SCRATCH1, r11 + mtspr SPRN_SPRG_SCRATCH2, r10 + mtspr SPRN_M_TW, r11 /* If we are faulting a kernel address, we have to use the * kernel page tables. */ mfspr r10, SPRN_SRR0 /* Get effective address of fault */ - INVALIDATE_ADJACENT_PAGES_CPU15(r10) + INVALIDATE_ADJACENT_PAGES_CPU15(r10, r11) mtspr SPRN_MD_EPN, r10 -#ifdef ITLB_MISS_KERNEL +#ifdef CONFIG_MODULES mfcr r11 compare_to_kernel_boundary r10, r10 #endif mfspr r10, SPRN_M_TWB /* Get level 1 table */ -#ifdef ITLB_MISS_KERNEL +#ifdef CONFIG_MODULES blt+ 3f rlwinm r10, r10, 0, 20, 31 oris r10, r10, (swapper_pg_dir - PAGE_OFFSET)@ha @@ -241,8 +230,8 @@ InstructionTLBMiss: mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ /* Restore registers */ -0: mfspr r10, SPRN_SPRG_SCRATCH0 - mfspr r11, SPRN_SPRG_SCRATCH1 +0: mfspr r10, SPRN_SPRG_SCRATCH2 + mfspr r11, SPRN_M_TW rfi patch_site 0b, patch__itlbmiss_exit_1 @@ -251,14 +240,14 @@ InstructionTLBMiss: 0: lwz r10, (itlb_miss_counter - PAGE_OFFSET)@l(0) addi r10, r10, 1 stw r10, (itlb_miss_counter - PAGE_OFFSET)@l(0) - mfspr r10, SPRN_SPRG_SCRATCH0 - mfspr r11, SPRN_SPRG_SCRATCH1 + mfspr r10, SPRN_SPRG_SCRATCH2 + mfspr r11, SPRN_M_TW rfi #endif . = 0x1200 DataStoreTLBMiss: - mtspr SPRN_DAR, r10 + mtspr SPRN_SPRG_SCRATCH2, r10 mtspr SPRN_M_TW, r11 mfcr r11 @@ -297,11 +286,11 @@ DataStoreTLBMiss: li r11, RPN_PATTERN rlwimi r10, r11, 0, 24, 27 /* Set 24-27 */ mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ + mtspr SPRN_DAR, r11 /* Tag DAR */ /* Restore registers */ -0: mfspr r10, SPRN_DAR - mtspr SPRN_DAR, r11 /* Tag DAR */ +0: mfspr r10, SPRN_SPRG_SCRATCH2 mfspr r11, SPRN_M_TW rfi patch_site 0b, patch__dtlbmiss_exit_1 @@ -311,8 +300,7 @@ DataStoreTLBMiss: 0: lwz r10, (dtlb_miss_counter - PAGE_OFFSET)@l(0) addi r10, r10, 1 stw r10, (dtlb_miss_counter - PAGE_OFFSET)@l(0) - mfspr r10, SPRN_DAR - mtspr SPRN_DAR, r11 /* Tag DAR */ + mfspr r10, SPRN_SPRG_SCRATCH2 mfspr r11, SPRN_M_TW rfi #endif @@ -619,10 +607,6 @@ start_here: lis r0, (MD_TWAM | MD_RSV4I)@h mtspr SPRN_MD_CTR, r0 #endif -#ifndef CONFIG_PIN_TLB_TEXT - li r0, 0 - mtspr SPRN_MI_CTR, r0 -#endif #if !defined(CONFIG_PIN_TLB_DATA) && !defined(CONFIG_PIN_TLB_IMMR) lis r0, MD_TWAM@h mtspr SPRN_MD_CTR, r0 @@ -718,7 +702,6 @@ initial_mmu: mtspr SPRN_DER, r8 blr -#ifdef CONFIG_PIN_TLB _GLOBAL(mmu_pin_tlb) lis r9, (1f - PAGE_OFFSET)@h ori r9, r9, (1f - PAGE_OFFSET)@l @@ -740,7 +723,6 @@ _GLOBAL(mmu_pin_tlb) mtspr SPRN_MD_CTR, r6 tlbia -#ifdef CONFIG_PIN_TLB_TEXT LOAD_REG_IMMEDIATE(r5, 28 << 8) LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET) LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG | _PMD_ACCESSED) @@ -761,7 +743,7 @@ _GLOBAL(mmu_pin_tlb) bdnzt lt, 2b lis r0, MI_RSV4I@h mtspr SPRN_MI_CTR, r0 -#endif + LOAD_REG_IMMEDIATE(r5, 28 << 8 | MD_TWAM) #ifdef CONFIG_PIN_TLB_DATA LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET) @@ -819,7 +801,6 @@ _GLOBAL(mmu_pin_tlb) mtspr SPRN_SRR1, r10 mtspr SPRN_SRR0, r11 rfi -#endif /* CONFIG_PIN_TLB */ /* * We put a few things here that have to be page-aligned. diff --git a/arch/powerpc/kernel/head_book3s_32.S b/arch/powerpc/kernel/head_book3s_32.S index a0dda2a1f2df..858fbc8b19f3 100644 --- a/arch/powerpc/kernel/head_book3s_32.S +++ b/arch/powerpc/kernel/head_book3s_32.S @@ -155,10 +155,8 @@ __after_mmu_off: bl initial_bats bl load_segment_registers -BEGIN_MMU_FTR_SECTION bl reloc_offset bl early_hash_table -END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) #if defined(CONFIG_BOOTX_TEXT) bl setup_disp_bat #endif @@ -207,7 +205,7 @@ turn_on_mmu: lis r0,start_here@h ori r0,r0,start_here@l mtspr SPRN_SRR0,r0 - RFI /* enables MMU */ + rfi /* enables MMU */ /* * We need __secondary_hold as a place to hold the other cpus on @@ -262,10 +260,19 @@ __secondary_hold_acknowledge: MachineCheck: EXCEPTION_PROLOG_0 #ifdef CONFIG_PPC_CHRP +#ifdef CONFIG_VMAP_STACK + mtspr SPRN_SPRG_SCRATCH2,r1 + mfspr r1, SPRN_SPRG_THREAD + lwz r1, RTAS_SP(r1) + cmpwi cr1, r1, 0 + bne cr1, 7f + mfspr r1, SPRN_SPRG_SCRATCH2 +#else mfspr r11, SPRN_SPRG_THREAD lwz r11, RTAS_SP(r11) cmpwi cr1, r11, 0 bne cr1, 7f +#endif #endif /* CONFIG_PPC_CHRP */ EXCEPTION_PROLOG_1 for_rtas=1 7: EXCEPTION_PROLOG_2 @@ -288,51 +295,35 @@ MachineCheck: DO_KVM 0x300 DataAccess: #ifdef CONFIG_VMAP_STACK - mtspr SPRN_SPRG_SCRATCH0,r10 - mfspr r10, SPRN_SPRG_THREAD BEGIN_MMU_FTR_SECTION + mtspr SPRN_SPRG_SCRATCH2,r10 + mfspr r10, SPRN_SPRG_THREAD stw r11, THR11(r10) mfspr r10, SPRN_DSISR mfcr r11 -#ifdef CONFIG_PPC_KUAP - andis. r10, r10, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH | DSISR_PROTFAULT)@h -#else andis. r10, r10, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h -#endif mfspr r10, SPRN_SPRG_THREAD beq hash_page_dsi .Lhash_page_dsi_cont: mtcr r11 lwz r11, THR11(r10) -END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) - mtspr SPRN_SPRG_SCRATCH1,r11 - mfspr r11, SPRN_DAR - stw r11, DAR(r10) - mfspr r11, SPRN_DSISR - stw r11, DSISR(r10) - mfspr r11, SPRN_SRR0 - stw r11, SRR0(r10) - mfspr r11, SPRN_SRR1 /* check whether user or kernel */ - stw r11, SRR1(r10) - mfcr r10 - andi. r11, r11, MSR_PR - + mfspr r10, SPRN_SPRG_SCRATCH2 +MMU_FTR_SECTION_ELSE + b 1f +ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE) +1: EXCEPTION_PROLOG_0 handle_dar_dsisr=1 EXCEPTION_PROLOG_1 b handle_page_fault_tramp_1 #else /* CONFIG_VMAP_STACK */ EXCEPTION_PROLOG handle_dar_dsisr=1 get_and_save_dar_dsisr_on_stack r4, r5, r11 BEGIN_MMU_FTR_SECTION -#ifdef CONFIG_PPC_KUAP - andis. r0, r5, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH | DSISR_PROTFAULT)@h -#else andis. r0, r5, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h -#endif bne handle_page_fault_tramp_2 /* if not, try to put a PTE */ rlwinm r3, r5, 32 - 15, 21, 21 /* DSISR_STORE -> _PAGE_RW */ bl hash_page b handle_page_fault_tramp_1 -FTR_SECTION_ELSE +MMU_FTR_SECTION_ELSE b handle_page_fault_tramp_2 ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE) #endif /* CONFIG_VMAP_STACK */ @@ -394,6 +385,7 @@ Alignment: . = 0x800 DO_KVM 0x800 FPUnavailable: +#ifdef CONFIG_PPC_FPU BEGIN_FTR_SECTION /* * Certain Freescale cores don't have a FPU and treat fp instructions @@ -407,6 +399,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE) b fast_exception_return 1: addi r3,r1,STACK_FRAME_OVERHEAD EXC_XFER_LITE(0x800, kernel_fp_unavailable_exception) +#else + b ProgramCheck +#endif /* Decrementer */ EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE) @@ -453,13 +448,14 @@ InstructionTLBMiss: */ /* Get PTE (linux-style) and check access */ mfspr r3,SPRN_IMISS -#if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) +#ifdef CONFIG_MODULES lis r1, TASK_SIZE@h /* check if kernel address */ cmplw 0,r1,r3 #endif - mfspr r2, SPRN_SPRG_PGDIR + mfspr r2, SPRN_SDR1 li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC -#if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) + rlwinm r2, r2, 28, 0xfffff000 +#ifdef CONFIG_MODULES bgt- 112f lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ @@ -519,8 +515,9 @@ DataLoadTLBMiss: mfspr r3,SPRN_DMISS lis r1, TASK_SIZE@h /* check if kernel address */ cmplw 0,r1,r3 - mfspr r2, SPRN_SPRG_PGDIR + mfspr r2, SPRN_SDR1 li r1, _PAGE_PRESENT | _PAGE_ACCESSED + rlwinm r2, r2, 28, 0xfffff000 bgt- 112f lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ @@ -595,8 +592,9 @@ DataStoreTLBMiss: mfspr r3,SPRN_DMISS lis r1, TASK_SIZE@h /* check if kernel address */ cmplw 0,r1,r3 - mfspr r2, SPRN_SPRG_PGDIR + mfspr r2, SPRN_SDR1 li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED + rlwinm r2, r2, 28, 0xfffff000 bgt- 112f lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ @@ -757,14 +755,14 @@ fast_hash_page_return: /* DSI */ mtcr r11 lwz r11, THR11(r10) - mfspr r10, SPRN_SPRG_SCRATCH0 - RFI + mfspr r10, SPRN_SPRG_SCRATCH2 + rfi 1: /* ISI */ mtcr r11 mfspr r11, SPRN_SPRG_SCRATCH1 mfspr r10, SPRN_SPRG_SCRATCH0 - RFI + rfi stack_overflow: vmap_stack_overflow_exception @@ -889,9 +887,12 @@ __secondary_start: tophys(r4,r2) addi r4,r4,THREAD /* phys address of our thread_struct */ mtspr SPRN_SPRG_THREAD,r4 +BEGIN_MMU_FTR_SECTION lis r4, (swapper_pg_dir - PAGE_OFFSET)@h ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l - mtspr SPRN_SPRG_PGDIR, r4 + rlwinm r4, r4, 4, 0xffff01ff + mtspr SPRN_SDR1, r4 +END_MMU_FTR_SECTION_IFCLR(MMU_FTR_HPTE_TABLE) /* enable MMU and jump to start_secondary */ li r4,MSR_KERNEL @@ -899,7 +900,7 @@ __secondary_start: ori r3,r3,start_secondary@l mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 - RFI + rfi #endif /* CONFIG_SMP */ #ifdef CONFIG_KVM_BOOK3S_HANDLER @@ -920,9 +921,6 @@ early_hash_table: lis r6, early_hash - PAGE_OFFSET@h ori r6, r6, 3 /* 256kB table */ mtspr SPRN_SDR1, r6 - lis r6, early_hash@h - addis r3, r3, Hash@ha - stw r6, Hash@l(r3) blr load_up_mmu: @@ -931,11 +929,13 @@ load_up_mmu: tlbia /* Clear all TLB entries */ sync /* wait for tlbia/tlbie to finish */ TLBSYNC /* ... on all CPUs */ +BEGIN_MMU_FTR_SECTION /* Load the SDR1 register (hash table base & size) */ lis r6,_SDR1@ha tophys(r6,r6) lwz r6,_SDR1@l(r6) mtspr SPRN_SDR1,r6 +END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) /* Load the BAT registers with the values set up by MMU_init. */ lis r3,BATS@ha @@ -991,9 +991,12 @@ start_here: tophys(r4,r2) addi r4,r4,THREAD /* init task's THREAD */ mtspr SPRN_SPRG_THREAD,r4 +BEGIN_MMU_FTR_SECTION lis r4, (swapper_pg_dir - PAGE_OFFSET)@h ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l - mtspr SPRN_SPRG_PGDIR, r4 + rlwinm r4, r4, 4, 0xffff01ff + mtspr SPRN_SDR1, r4 +END_MMU_FTR_SECTION_IFCLR(MMU_FTR_HPTE_TABLE) /* stack */ lis r1,init_thread_union@ha @@ -1027,7 +1030,7 @@ start_here: .align 4 mtspr SPRN_SRR0,r4 mtspr SPRN_SRR1,r3 - RFI + rfi /* Load up the kernel context */ 2: bl load_up_mmu @@ -1051,7 +1054,7 @@ start_here: ori r3,r3,start_kernel@l mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 - RFI + rfi /* * void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next); @@ -1073,16 +1076,22 @@ _ENTRY(switch_mmu_context) li r0,NUM_USER_SEGMENTS mtctr r0 - lwz r4, MM_PGD(r4) #ifdef CONFIG_BDI_SWITCH /* Context switch the PTE pointer for the Abatron BDI2000. * The PGDIR is passed as second argument. */ + lwz r4, MM_PGD(r4) lis r5, abatron_pteptrs@ha stw r4, abatron_pteptrs@l + 0x4(r5) #endif +BEGIN_MMU_FTR_SECTION +#ifndef CONFIG_BDI_SWITCH + lwz r4, MM_PGD(r4) +#endif tophys(r4, r4) - mtspr SPRN_SPRG_PGDIR, r4 + rlwinm r4, r4, 4, 0xffff01ff + mtspr SPRN_SDR1, r4 +END_MMU_FTR_SECTION_IFCLR(MMU_FTR_HPTE_TABLE) li r4,0 isync 3: @@ -1166,7 +1175,7 @@ _ENTRY(update_bats) .align 4 mtspr SPRN_SRR0, r4 mtspr SPRN_SRR1, r3 - RFI + rfi 1: bl clear_bats lis r3, BATS@ha addi r3, r3, BATS@l @@ -1185,7 +1194,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) mtmsr r3 mtspr SPRN_SRR0, r7 mtspr SPRN_SRR1, r6 - RFI + rfi flush_tlbs: lis r10, 0x40 @@ -1206,7 +1215,7 @@ mmu_off: mtspr SPRN_SRR0,r4 mtspr SPRN_SRR1,r3 sync - RFI + rfi /* We use one BAT to map up to 256M of RAM at _PAGE_OFFSET */ initial_bats: diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index 71c359d438b5..74e230c200fb 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -176,7 +176,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV) #endif mtspr SPRN_SRR1,r10 mtspr SPRN_SRR0,r11 - RFI /* jump to handler, enable MMU */ + rfi /* jump to handler, enable MMU */ 99: b ret_from_kernel_syscall .endm @@ -185,7 +185,6 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV) * * On 40x critical is the only additional level * On 44x/e500 we have critical and machine check - * On e200 we have critical and debug (machine check occurs via critical) * * Additionally we reserve a SPRG for each priority level so we can free up a * GPR to use as the base for indirect access to the exception stacks. This @@ -201,7 +200,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV) #define MC_STACK_BASE mcheckirq_ctx #define CRIT_STACK_BASE critirq_ctx -/* only on e500mc/e200 */ +/* only on e500mc */ #define DBG_STACK_BASE dbgirq_ctx #define EXC_LVL_FRAME_OVERHEAD (THREAD_SIZE - INT_FRAME_SIZE - EXC_LVL_SIZE) diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 586a6ac501e9..fdd4d274c245 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -187,9 +187,6 @@ set_ivor: /* Setup the defaults for TLB entries */ li r2,(MAS4_TSIZED(BOOK3E_PAGESZ_4K))@l -#ifdef CONFIG_E200 - oris r2,r2,MAS4_TLBSELD(1)@h -#endif mtspr SPRN_MAS4, r2 #if !defined(CONFIG_BDI_SWITCH) @@ -362,13 +359,7 @@ interrupt_base: CRITICAL_EXCEPTION(0x0100, CRITICAL, CriticalInput, unknown_exception) /* Machine Check Interrupt */ -#ifdef CONFIG_E200 - /* no RFMCI, MCSRRs on E200 */ - CRITICAL_EXCEPTION(0x0200, MACHINE_CHECK, MachineCheck, \ - machine_check_exception) -#else MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception) -#endif /* Data Storage Interrupt */ START_EXCEPTION(DataStorage) @@ -400,15 +391,9 @@ interrupt_base: #ifdef CONFIG_PPC_FPU FP_UNAVAILABLE_EXCEPTION #else -#ifdef CONFIG_E200 - /* E200 treats 'normal' floating point instructions as FP Unavail exception */ - EXCEPTION(0x0800, FP_UNAVAIL, FloatingPointUnavailable, \ - program_check_exception, EXC_XFER_STD) -#else EXCEPTION(0x0800, FP_UNAVAIL, FloatingPointUnavailable, \ unknown_exception, EXC_XFER_STD) #endif -#endif /* System Call Interrupt */ START_EXCEPTION(SystemCall) @@ -625,7 +610,7 @@ END_BTB_FLUSH_SECTION mfspr r10, SPRN_SPRG_RSCRATCH0 b InstructionStorage -/* Define SPE handlers for e200 and e500v2 */ +/* Define SPE handlers for e500v2 */ #ifdef CONFIG_SPE /* SPE Unavailable */ START_EXCEPTION(SPEUnavailable) @@ -807,31 +792,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS) #endif 3: mtspr SPRN_MAS2, r12 -#ifdef CONFIG_E200 - /* Round robin TLB1 entries assignment */ - mfspr r12, SPRN_MAS0 - - /* Extract TLB1CFG(NENTRY) */ - mfspr r11, SPRN_TLB1CFG - andi. r11, r11, 0xfff - - /* Extract MAS0(NV) */ - andi. r13, r12, 0xfff - addi r13, r13, 1 - cmpw 0, r13, r11 - addi r12, r12, 1 - - /* check if we need to wrap */ - blt 7f - - /* wrap back to first free tlbcam entry */ - lis r13, tlbcam_index@ha - lwz r13, tlbcam_index@l(r13) - rlwimi r12, r13, 0, 20, 31 -7: - mtspr SPRN_MAS0,r12 -#endif /* CONFIG_E200 */ - tlb_write_entry: tlbwe @@ -933,21 +893,6 @@ get_phys_addr: * Global functions */ -#ifdef CONFIG_E200 -/* Adjust or setup IVORs for e200 */ -_GLOBAL(__setup_e200_ivors) - li r3,DebugDebug@l - mtspr SPRN_IVOR15,r3 - li r3,SPEUnavailable@l - mtspr SPRN_IVOR32,r3 - li r3,SPEFloatingPointData@l - mtspr SPRN_IVOR33,r3 - li r3,SPEFloatingPointRound@l - mtspr SPRN_IVOR34,r3 - sync - blr -#endif - #ifdef CONFIG_E500 #ifndef CONFIG_PPC_E500MC /* Adjust or setup IVORs for e500v1/v2 */ diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index f4e8f21046f5..8fc7a14e4d71 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c @@ -499,6 +499,11 @@ static bool is_larx_stcx_instr(int type) return type == LARX || type == STCX; } +static bool is_octword_vsx_instr(int type, int size) +{ + return ((type == LOAD_VSX || type == STORE_VSX) && size == 32); +} + /* * We've failed in reliably handling the hw-breakpoint. Unregister * it and throw a warning message to let the user know about it. @@ -549,6 +554,58 @@ static bool stepping_handler(struct pt_regs *regs, struct perf_event **bp, return true; } +static void handle_p10dd1_spurious_exception(struct arch_hw_breakpoint **info, + int *hit, unsigned long ea) +{ + int i; + unsigned long hw_end_addr; + + /* + * Handle spurious exception only when any bp_per_reg is set. + * Otherwise this might be created by xmon and not actually a + * spurious exception. + */ + for (i = 0; i < nr_wp_slots(); i++) { + if (!info[i]) + continue; + + hw_end_addr = ALIGN(info[i]->address + info[i]->len, HW_BREAKPOINT_SIZE); + + /* + * Ending address of DAWR range is less than starting + * address of op. + */ + if ((hw_end_addr - 1) >= ea) + continue; + + /* + * Those addresses need to be in the same or in two + * consecutive 512B blocks; + */ + if (((hw_end_addr - 1) >> 10) != (ea >> 10)) + continue; + + /* + * 'op address + 64B' generates an address that has a + * carry into bit 52 (crosses 2K boundary). + */ + if ((ea & 0x800) == ((ea + 64) & 0x800)) + continue; + + break; + } + + if (i == nr_wp_slots()) + return; + + for (i = 0; i < nr_wp_slots(); i++) { + if (info[i]) { + hit[i] = 1; + info[i]->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ; + } + } +} + int hw_breakpoint_handler(struct die_args *args) { bool err = false; @@ -607,8 +664,14 @@ int hw_breakpoint_handler(struct die_args *args) goto reset; if (!nr_hit) { - rc = NOTIFY_DONE; - goto out; + /* Workaround for Power10 DD1 */ + if (!IS_ENABLED(CONFIG_PPC_8xx) && mfspr(SPRN_PVR) == 0x800100 && + is_octword_vsx_instr(type, size)) { + handle_p10dd1_spurious_exception(info, hit, ea); + } else { + rc = NOTIFY_DONE; + goto out; + } } /* diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c index 9fe4fb3b08aa..72862a4d3a5d 100644 --- a/arch/powerpc/kernel/iomap.c +++ b/arch/powerpc/kernel/iomap.c @@ -11,177 +11,11 @@ #include <asm/pci-bridge.h> #include <asm/isa-bridge.h> -/* - * Here comes the ppc64 implementation of the IOMAP - * interfaces. - */ -unsigned int ioread8(const void __iomem *addr) -{ - return readb(addr); -} -unsigned int ioread16(const void __iomem *addr) -{ - return readw(addr); -} -unsigned int ioread16be(const void __iomem *addr) -{ - return readw_be(addr); -} -unsigned int ioread32(const void __iomem *addr) -{ - return readl(addr); -} -unsigned int ioread32be(const void __iomem *addr) -{ - return readl_be(addr); -} -EXPORT_SYMBOL(ioread8); -EXPORT_SYMBOL(ioread16); -EXPORT_SYMBOL(ioread16be); -EXPORT_SYMBOL(ioread32); -EXPORT_SYMBOL(ioread32be); -#ifdef __powerpc64__ -u64 ioread64(const void __iomem *addr) -{ - return readq(addr); -} -u64 ioread64_lo_hi(const void __iomem *addr) -{ - return readq(addr); -} -u64 ioread64_hi_lo(const void __iomem *addr) -{ - return readq(addr); -} -u64 ioread64be(const void __iomem *addr) -{ - return readq_be(addr); -} -u64 ioread64be_lo_hi(const void __iomem *addr) -{ - return readq_be(addr); -} -u64 ioread64be_hi_lo(const void __iomem *addr) -{ - return readq_be(addr); -} -EXPORT_SYMBOL(ioread64); -EXPORT_SYMBOL(ioread64_lo_hi); -EXPORT_SYMBOL(ioread64_hi_lo); -EXPORT_SYMBOL(ioread64be); -EXPORT_SYMBOL(ioread64be_lo_hi); -EXPORT_SYMBOL(ioread64be_hi_lo); -#endif /* __powerpc64__ */ - -void iowrite8(u8 val, void __iomem *addr) -{ - writeb(val, addr); -} -void iowrite16(u16 val, void __iomem *addr) -{ - writew(val, addr); -} -void iowrite16be(u16 val, void __iomem *addr) -{ - writew_be(val, addr); -} -void iowrite32(u32 val, void __iomem *addr) -{ - writel(val, addr); -} -void iowrite32be(u32 val, void __iomem *addr) -{ - writel_be(val, addr); -} -EXPORT_SYMBOL(iowrite8); -EXPORT_SYMBOL(iowrite16); -EXPORT_SYMBOL(iowrite16be); -EXPORT_SYMBOL(iowrite32); -EXPORT_SYMBOL(iowrite32be); -#ifdef __powerpc64__ -void iowrite64(u64 val, void __iomem *addr) -{ - writeq(val, addr); -} -void iowrite64_lo_hi(u64 val, void __iomem *addr) -{ - writeq(val, addr); -} -void iowrite64_hi_lo(u64 val, void __iomem *addr) -{ - writeq(val, addr); -} -void iowrite64be(u64 val, void __iomem *addr) -{ - writeq_be(val, addr); -} -void iowrite64be_lo_hi(u64 val, void __iomem *addr) -{ - writeq_be(val, addr); -} -void iowrite64be_hi_lo(u64 val, void __iomem *addr) -{ - writeq_be(val, addr); -} -EXPORT_SYMBOL(iowrite64); -EXPORT_SYMBOL(iowrite64_lo_hi); -EXPORT_SYMBOL(iowrite64_hi_lo); -EXPORT_SYMBOL(iowrite64be); -EXPORT_SYMBOL(iowrite64be_lo_hi); -EXPORT_SYMBOL(iowrite64be_hi_lo); -#endif /* __powerpc64__ */ - -/* - * These are the "repeat read/write" functions. Note the - * non-CPU byte order. We do things in "IO byteorder" - * here. - * - * FIXME! We could make these do EEH handling if we really - * wanted. Not clear if we do. - */ -void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count) -{ - readsb(addr, dst, count); -} -void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count) -{ - readsw(addr, dst, count); -} -void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count) -{ - readsl(addr, dst, count); -} -EXPORT_SYMBOL(ioread8_rep); -EXPORT_SYMBOL(ioread16_rep); -EXPORT_SYMBOL(ioread32_rep); - -void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count) -{ - writesb(addr, src, count); -} -void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count) -{ - writesw(addr, src, count); -} -void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count) -{ - writesl(addr, src, count); -} -EXPORT_SYMBOL(iowrite8_rep); -EXPORT_SYMBOL(iowrite16_rep); -EXPORT_SYMBOL(iowrite32_rep); - void __iomem *ioport_map(unsigned long port, unsigned int len) { return (void __iomem *) (port + _IO_BASE); } - -void ioport_unmap(void __iomem *addr) -{ - /* Nothing to do */ -} EXPORT_SYMBOL(ioport_map); -EXPORT_SYMBOL(ioport_unmap); #ifdef CONFIG_PCI void pci_iounmap(struct pci_dev *dev, void __iomem *addr) diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 7d0f7682d01d..6b1eca53e36c 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -102,14 +102,6 @@ static inline notrace unsigned long get_irq_happened(void) return happened; } -static inline notrace int decrementer_check_overflow(void) -{ - u64 now = get_tb(); - u64 *next_tb = this_cpu_ptr(&decrementers_next_tb); - - return now >= *next_tb; -} - #ifdef CONFIG_PPC_BOOK3E /* This is called whenever we are re-enabling interrupts @@ -142,35 +134,6 @@ notrace unsigned int __check_irq_replay(void) trace_hardirqs_on(); trace_hardirqs_off(); - /* - * We are always hard disabled here, but PACA_IRQ_HARD_DIS may - * not be set, which means interrupts have only just been hard - * disabled as part of the local_irq_restore or interrupt return - * code. In that case, skip the decrementr check becaus it's - * expensive to read the TB. - * - * HARD_DIS then gets cleared here, but it's reconciled later. - * Either local_irq_disable will replay the interrupt and that - * will reconcile state like other hard interrupts. Or interrupt - * retur will replay the interrupt and in that case it sets - * PACA_IRQ_HARD_DIS by hand (see comments in entry_64.S). - */ - if (happened & PACA_IRQ_HARD_DIS) { - local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS; - - /* - * We may have missed a decrementer interrupt if hard disabled. - * Check the decrementer register in case we had a rollover - * while hard disabled. - */ - if (!(happened & PACA_IRQ_DEC)) { - if (decrementer_check_overflow()) { - local_paca->irq_happened |= PACA_IRQ_DEC; - happened |= PACA_IRQ_DEC; - } - } - } - if (happened & PACA_IRQ_DEC) { local_paca->irq_happened &= ~PACA_IRQ_DEC; return 0x900; @@ -186,6 +149,9 @@ notrace unsigned int __check_irq_replay(void) return 0x280; } + if (happened & PACA_IRQ_HARD_DIS) + local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS; + /* There should be nothing left ! */ BUG_ON(local_paca->irq_happened != 0); @@ -229,18 +195,6 @@ again: if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) WARN_ON_ONCE(mfmsr() & MSR_EE); - if (happened & PACA_IRQ_HARD_DIS) { - /* - * We may have missed a decrementer interrupt if hard disabled. - * Check the decrementer register in case we had a rollover - * while hard disabled. - */ - if (!(happened & PACA_IRQ_DEC)) { - if (decrementer_check_overflow()) - happened |= PACA_IRQ_DEC; - } - } - /* * Force the delivery of pending soft-disabled interrupts on PS3. * Any HV call will have this side effect. @@ -345,6 +299,7 @@ notrace void arch_local_irq_restore(unsigned long mask) if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) WARN_ON_ONCE(!(mfmsr() & MSR_EE)); __hard_irq_disable(); + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; } else { /* * We should already be hard disabled here. We had bugs diff --git a/arch/powerpc/kernel/kprobes-ftrace.c b/arch/powerpc/kernel/kprobes-ftrace.c index 972cb28174b2..660138f6c4b2 100644 --- a/arch/powerpc/kernel/kprobes-ftrace.c +++ b/arch/powerpc/kernel/kprobes-ftrace.c @@ -14,14 +14,22 @@ /* Ftrace callback handler for kprobes */ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip, - struct ftrace_ops *ops, struct pt_regs *regs) + struct ftrace_ops *ops, struct ftrace_regs *fregs) { struct kprobe *p; struct kprobe_ctlblk *kcb; + struct pt_regs *regs; + int bit; + bit = ftrace_test_recursion_trylock(nip, parent_nip); + if (bit < 0) + return; + + regs = ftrace_get_regs(fregs); + preempt_disable_notrace(); p = get_kprobe((kprobe_opcode_t *)nip); if (unlikely(!p) || kprobe_disabled(p)) - return; + goto out; kcb = get_kprobe_ctlblk(); if (kprobe_running()) { @@ -52,6 +60,9 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip, */ __this_cpu_write(current_kprobe, NULL); } +out: + preempt_enable_notrace(); + ftrace_test_recursion_unlock(bit); } NOKPROBE_SYMBOL(kprobe_ftrace_handler); diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c index 63702c0badb9..9f3e133b57b7 100644 --- a/arch/powerpc/kernel/mce.c +++ b/arch/powerpc/kernel/mce.c @@ -555,7 +555,7 @@ void machine_check_print_event_info(struct machine_check_event *evt, } printk("%sMCE: CPU%d: machine check (%s) %s %s %s %s[%s]\n", - level, evt->cpu, sevstr, in_guest ? "Guest" : "Host", + level, evt->cpu, sevstr, in_guest ? "Guest" : "", err_type, subtype, dar_str, evt->disposition == MCE_DISPOSITION_RECOVERED ? "Recovered" : "Not recovered"); @@ -577,7 +577,7 @@ void machine_check_print_event_info(struct machine_check_event *evt, #ifdef CONFIG_PPC_BOOK3S_64 /* Display faulty slb contents for SLB errors. */ - if (evt->error_type == MCE_ERROR_TYPE_SLB) + if (evt->error_type == MCE_ERROR_TYPE_SLB && !in_guest) slb_dump_contents(local_paca->mce_faulty_slbs); #endif } diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c index b7e173754a2e..667104d4c455 100644 --- a/arch/powerpc/kernel/mce_power.c +++ b/arch/powerpc/kernel/mce_power.c @@ -62,6 +62,20 @@ out: return pfn; } +static bool mce_in_guest(void) +{ +#ifdef CONFIG_KVM_BOOK3S_HANDLER + /* + * If machine check is hit when in guest context or low level KVM + * code, avoid looking up any translations or making any attempts + * to recover, just record the event and pass to KVM. + */ + if (get_paca()->kvm_hstate.in_guest) + return true; +#endif + return false; +} + /* flush SLBs and reload */ #ifdef CONFIG_PPC_BOOK3S_64 void flush_and_reload_slb(void) @@ -69,14 +83,6 @@ void flush_and_reload_slb(void) /* Invalidate all SLBs */ slb_flush_all_realmode(); -#ifdef CONFIG_KVM_BOOK3S_HANDLER - /* - * If machine check is hit when in guest or in transition, we will - * only flush the SLBs and continue. - */ - if (get_paca()->kvm_hstate.in_guest) - return; -#endif if (early_radix_enabled()) return; @@ -91,7 +97,7 @@ void flush_and_reload_slb(void) } #endif -static void flush_erat(void) +void flush_erat(void) { #ifdef CONFIG_PPC_BOOK3S_64 if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) { @@ -490,19 +496,21 @@ static int mce_handle_ierror(struct pt_regs *regs, if ((srr1 & table[i].srr1_mask) != table[i].srr1_value) continue; - /* attempt to correct the error */ - switch (table[i].error_type) { - case MCE_ERROR_TYPE_SLB: - if (local_paca->in_mce == 1) - slb_save_contents(local_paca->mce_faulty_slbs); - handled = mce_flush(MCE_FLUSH_SLB); - break; - case MCE_ERROR_TYPE_ERAT: - handled = mce_flush(MCE_FLUSH_ERAT); - break; - case MCE_ERROR_TYPE_TLB: - handled = mce_flush(MCE_FLUSH_TLB); - break; + if (!mce_in_guest()) { + /* attempt to correct the error */ + switch (table[i].error_type) { + case MCE_ERROR_TYPE_SLB: + if (local_paca->in_mce == 1) + slb_save_contents(local_paca->mce_faulty_slbs); + handled = mce_flush(MCE_FLUSH_SLB); + break; + case MCE_ERROR_TYPE_ERAT: + handled = mce_flush(MCE_FLUSH_ERAT); + break; + case MCE_ERROR_TYPE_TLB: + handled = mce_flush(MCE_FLUSH_TLB); + break; + } } /* now fill in mce_error_info */ @@ -534,7 +542,7 @@ static int mce_handle_ierror(struct pt_regs *regs, mce_err->sync_error = table[i].sync_error; mce_err->severity = table[i].severity; mce_err->initiator = table[i].initiator; - if (table[i].nip_valid) { + if (table[i].nip_valid && !mce_in_guest()) { *addr = regs->nip; if (mce_err->sync_error && table[i].error_type == MCE_ERROR_TYPE_UE) { @@ -577,22 +585,24 @@ static int mce_handle_derror(struct pt_regs *regs, if (!(dsisr & table[i].dsisr_value)) continue; - /* attempt to correct the error */ - switch (table[i].error_type) { - case MCE_ERROR_TYPE_SLB: - if (local_paca->in_mce == 1) - slb_save_contents(local_paca->mce_faulty_slbs); - if (mce_flush(MCE_FLUSH_SLB)) - handled = 1; - break; - case MCE_ERROR_TYPE_ERAT: - if (mce_flush(MCE_FLUSH_ERAT)) - handled = 1; - break; - case MCE_ERROR_TYPE_TLB: - if (mce_flush(MCE_FLUSH_TLB)) - handled = 1; - break; + if (!mce_in_guest()) { + /* attempt to correct the error */ + switch (table[i].error_type) { + case MCE_ERROR_TYPE_SLB: + if (local_paca->in_mce == 1) + slb_save_contents(local_paca->mce_faulty_slbs); + if (mce_flush(MCE_FLUSH_SLB)) + handled = 1; + break; + case MCE_ERROR_TYPE_ERAT: + if (mce_flush(MCE_FLUSH_ERAT)) + handled = 1; + break; + case MCE_ERROR_TYPE_TLB: + if (mce_flush(MCE_FLUSH_TLB)) + handled = 1; + break; + } } /* @@ -634,7 +644,7 @@ static int mce_handle_derror(struct pt_regs *regs, mce_err->initiator = table[i].initiator; if (table[i].dar_valid) *addr = regs->dar; - else if (mce_err->sync_error && + else if (mce_err->sync_error && !mce_in_guest() && table[i].error_type == MCE_ERROR_TYPE_UE) { /* * We do a maximum of 4 nested MCE calls, see @@ -662,7 +672,8 @@ static int mce_handle_derror(struct pt_regs *regs, static long mce_handle_ue_error(struct pt_regs *regs, struct mce_error_info *mce_err) { - long handled = 0; + if (mce_in_guest()) + return 0; mce_common_process_ue(regs, mce_err); if (mce_err->ignore_event) @@ -677,9 +688,10 @@ static long mce_handle_ue_error(struct pt_regs *regs, if (ppc_md.mce_check_early_recovery) { if (ppc_md.mce_check_early_recovery(regs)) - handled = 1; + return 1; } - return handled; + + return 0; } static long mce_handle_error(struct pt_regs *regs, diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 0ad15768d762..7f5aae3c387d 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -208,7 +208,7 @@ static struct rtas_args * __init new_rtas_args(int cpu, unsigned long limit) struct paca_struct **paca_ptrs __read_mostly; EXPORT_SYMBOL(paca_ptrs); -void __init __nostackprotector initialise_paca(struct paca_struct *new_paca, int cpu) +void __init initialise_paca(struct paca_struct *new_paca, int cpu) { #ifdef CONFIG_PPC_PSERIES new_paca->lppaca_ptr = NULL; @@ -241,7 +241,7 @@ void __init __nostackprotector initialise_paca(struct paca_struct *new_paca, int } /* Put the paca pointer into r13 and SPRG_PACA */ -void __nostackprotector setup_paca(struct paca_struct *new_paca) +void setup_paca(struct paca_struct *new_paca) { /* Setup r13 */ local_paca = new_paca; diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index be108616a721..2b555997b295 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -353,6 +353,55 @@ struct pci_controller *pci_find_controller_for_domain(int domain_nr) return NULL; } +struct pci_intx_virq { + int virq; + struct kref kref; + struct list_head list_node; +}; + +static LIST_HEAD(intx_list); +static DEFINE_MUTEX(intx_mutex); + +static void ppc_pci_intx_release(struct kref *kref) +{ + struct pci_intx_virq *vi = container_of(kref, struct pci_intx_virq, kref); + + list_del(&vi->list_node); + irq_dispose_mapping(vi->virq); + kfree(vi); +} + +static int ppc_pci_unmap_irq_line(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct pci_dev *pdev = to_pci_dev(data); + + if (action == BUS_NOTIFY_DEL_DEVICE) { + struct pci_intx_virq *vi; + + mutex_lock(&intx_mutex); + list_for_each_entry(vi, &intx_list, list_node) { + if (vi->virq == pdev->irq) { + kref_put(&vi->kref, ppc_pci_intx_release); + break; + } + } + mutex_unlock(&intx_mutex); + } + + return NOTIFY_DONE; +} + +static struct notifier_block ppc_pci_unmap_irq_notifier = { + .notifier_call = ppc_pci_unmap_irq_line, +}; + +static int ppc_pci_register_irq_notifier(void) +{ + return bus_register_notifier(&pci_bus_type, &ppc_pci_unmap_irq_notifier); +} +arch_initcall(ppc_pci_register_irq_notifier); + /* * Reads the interrupt pin to determine if interrupt is use by card. * If the interrupt is used, then gets the interrupt line from the @@ -361,6 +410,12 @@ struct pci_controller *pci_find_controller_for_domain(int domain_nr) static int pci_read_irq_line(struct pci_dev *pci_dev) { int virq; + struct pci_intx_virq *vi, *vitmp; + + /* Preallocate vi as rewind is complex if this fails after mapping */ + vi = kzalloc(sizeof(struct pci_intx_virq), GFP_KERNEL); + if (!vi) + return -1; pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev)); @@ -377,12 +432,12 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) * function. */ if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin)) - return -1; + goto error_exit; if (pin == 0) - return -1; + goto error_exit; if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) || line == 0xff || line == 0) { - return -1; + goto error_exit; } pr_debug(" No map ! Using line %d (pin %d) from PCI config\n", line, pin); @@ -394,14 +449,33 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) if (!virq) { pr_debug(" Failed to map !\n"); - return -1; + goto error_exit; } pr_debug(" Mapped to linux irq %d\n", virq); pci_dev->irq = virq; + mutex_lock(&intx_mutex); + list_for_each_entry(vitmp, &intx_list, list_node) { + if (vitmp->virq == virq) { + kref_get(&vitmp->kref); + kfree(vi); + vi = NULL; + break; + } + } + if (vi) { + vi->virq = virq; + kref_init(&vi->kref); + list_add_tail(&vi->list_node, &intx_list); + } + mutex_unlock(&intx_mutex); + return 0; +error_exit: + kfree(vi); + return -1; } /* diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index d421a2c7f822..a66f435dabbf 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -589,7 +589,6 @@ static void save_all(struct task_struct *tsk) __giveup_spe(tsk); msr_check_and_clear(msr_all_available); - thread_pkey_regs_save(&tsk->thread); } void flush_all_to_thread(struct task_struct *tsk) @@ -807,29 +806,6 @@ static void switch_hw_breakpoint(struct task_struct *new) #endif /* !CONFIG_HAVE_HW_BREAKPOINT */ #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ -#ifdef CONFIG_PPC_ADV_DEBUG_REGS -static inline int __set_dabr(unsigned long dabr, unsigned long dabrx) -{ - mtspr(SPRN_DAC1, dabr); - if (IS_ENABLED(CONFIG_PPC_47x)) - isync(); - return 0; -} -#elif defined(CONFIG_PPC_BOOK3S) -static inline int __set_dabr(unsigned long dabr, unsigned long dabrx) -{ - mtspr(SPRN_DABR, dabr); - if (cpu_has_feature(CPU_FTR_DABRX)) - mtspr(SPRN_DABRX, dabrx); - return 0; -} -#else -static inline int __set_dabr(unsigned long dabr, unsigned long dabrx) -{ - return -EINVAL; -} -#endif - static inline int set_dabr(struct arch_hw_breakpoint *brk) { unsigned long dabr, dabrx; @@ -840,7 +816,19 @@ static inline int set_dabr(struct arch_hw_breakpoint *brk) if (ppc_md.set_dabr) return ppc_md.set_dabr(dabr, dabrx); - return __set_dabr(dabr, dabrx); + if (IS_ENABLED(CONFIG_PPC_ADV_DEBUG_REGS)) { + mtspr(SPRN_DAC1, dabr); + if (IS_ENABLED(CONFIG_PPC_47x)) + isync(); + return 0; + } else if (IS_ENABLED(CONFIG_PPC_BOOK3S)) { + mtspr(SPRN_DABR, dabr); + if (cpu_has_feature(CPU_FTR_DABRX)) + mtspr(SPRN_DABRX, dabrx); + return 0; + } else { + return -EINVAL; + } } static inline int set_breakpoint_8xx(struct arch_hw_breakpoint *brk) @@ -1160,8 +1148,6 @@ static inline void save_sprs(struct thread_struct *t) t->tar = mfspr(SPRN_TAR); } #endif - - thread_pkey_regs_save(t); } static inline void restore_sprs(struct thread_struct *old_thread, @@ -1202,7 +1188,6 @@ static inline void restore_sprs(struct thread_struct *old_thread, mtspr(SPRN_TIDR, new_thread->tidr); #endif - thread_pkey_regs_restore(new_thread, old_thread); } struct task_struct *__switch_to(struct task_struct *prev, @@ -1466,12 +1451,10 @@ static void print_msr_bits(unsigned long val) #define LAST_VOLATILE 12 #endif -void show_regs(struct pt_regs * regs) +static void __show_regs(struct pt_regs *regs) { int i, trap; - show_regs_print_info(KERN_DEFAULT); - printk("NIP: "REG" LR: "REG" CTR: "REG"\n", regs->nip, regs->link, regs->ctr); printk("REGS: %px TRAP: %04lx %s (%s)\n", @@ -1513,6 +1496,12 @@ void show_regs(struct pt_regs * regs) printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip); printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link); } +} + +void show_regs(struct pt_regs *regs) +{ + show_regs_print_info(KERN_DEFAULT); + __show_regs(regs); show_stack(current, (unsigned long *) regs->gpr[1], KERN_DEFAULT); if (!user_mode(regs)) show_instructions(regs); @@ -1527,14 +1516,27 @@ void flush_thread(void) #endif /* CONFIG_HAVE_HW_BREAKPOINT */ } -#ifdef CONFIG_PPC_BOOK3S_64 void arch_setup_new_exec(void) { - if (radix_enabled()) - return; - hash__setup_new_exec(); -} + +#ifdef CONFIG_PPC_BOOK3S_64 + if (!radix_enabled()) + hash__setup_new_exec(); #endif + /* + * If we exec out of a kernel thread then thread.regs will not be + * set. Do it now. + */ + if (!current->thread.regs) { + struct pt_regs *regs = task_stack_page(current) + THREAD_SIZE; + current->thread.regs = regs - 1; + } + +#ifdef CONFIG_PPC_MEM_KEYS + current->thread.regs->amr = default_amr; + current->thread.regs->iamr = default_iamr; +#endif +} #ifdef CONFIG_PPC64 /** @@ -1730,7 +1732,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, p->thread.ptrace_bps[i] = NULL; #endif +#ifdef CONFIG_PPC_FPU_REGS p->thread.fp_save_area = NULL; +#endif #ifdef CONFIG_ALTIVEC p->thread.vr_save_area = NULL; #endif @@ -1747,6 +1751,16 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, p->thread.tidr = 0; #endif + /* + * Run with the current AMR value of the kernel + */ +#ifdef CONFIG_PPC_PKEY + if (mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) + kregs->amr = AMR_KUAP_BLOCKED; + + if (mmu_has_feature(MMU_FTR_BOOK3S_KUEP)) + kregs->iamr = AMR_KUEP_BLOCKED; +#endif kregs->nip = ppc_function_entry(f); return 0; } @@ -1765,15 +1779,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) preload_new_slb_context(start, sp); #endif - /* - * If we exec out of a kernel thread then thread.regs will not be - * set. Do it now. - */ - if (!current->thread.regs) { - struct pt_regs *regs = task_stack_page(current) + THREAD_SIZE; - current->thread.regs = regs - 1; - } - #ifdef CONFIG_PPC_TRANSACTIONAL_MEM /* * Clear any transactional state, we're exec()ing. The cause is @@ -1855,8 +1860,10 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) #endif current->thread.load_slb = 0; current->thread.load_fp = 0; +#ifdef CONFIG_PPC_FPU_REGS memset(¤t->thread.fp_state, 0, sizeof(current->thread.fp_state)); current->thread.fp_save_area = NULL; +#endif #ifdef CONFIG_ALTIVEC memset(¤t->thread.vr_state, 0, sizeof(current->thread.vr_state)); current->thread.vr_state.vscr.u[3] = 0x00010000; /* Java mode disabled */ @@ -1878,7 +1885,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) current->thread.load_tm = 0; #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ - thread_pkey_regs_init(¤t->thread); } EXPORT_SYMBOL(start_thread); @@ -2174,10 +2180,14 @@ void show_stack(struct task_struct *tsk, unsigned long *stack, && stack[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) { struct pt_regs *regs = (struct pt_regs *) (sp + STACK_FRAME_OVERHEAD); + lr = regs->link; - printk("%s--- interrupt: %lx at %pS\n LR = %pS\n", - loglvl, regs->trap, - (void *)regs->nip, (void *)lr); + printk("%s--- interrupt: %lx at %pS\n", + loglvl, regs->trap, (void *)regs->nip); + __show_regs(regs); + printk("%s--- interrupt: %lx\n", + loglvl, regs->trap); + firstframe = 1; } diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index c1545f22c077..ae3c41730367 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -165,7 +165,6 @@ static struct ibm_pa_feature { #ifdef CONFIG_PPC_RADIX_MMU { .pabyte = 40, .pabit = 0, .mmu_features = MMU_FTR_TYPE_RADIX | MMU_FTR_GTSE }, #endif - { .pabyte = 1, .pabit = 1, .invert = 1, .cpu_features = CPU_FTR_NODSISRALIGN }, { .pabyte = 5, .pabit = 0, .cpu_features = CPU_FTR_REAL_LE, .cpu_user_ftrs = PPC_FEATURE_TRUE_LE }, /* diff --git a/arch/powerpc/kernel/ptrace/Makefile b/arch/powerpc/kernel/ptrace/Makefile index c2f2402ebc8c..8ebc11d1168d 100644 --- a/arch/powerpc/kernel/ptrace/Makefile +++ b/arch/powerpc/kernel/ptrace/Makefile @@ -6,10 +6,11 @@ CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' obj-y += ptrace.o ptrace-view.o +obj-$(CONFIG_PPC_FPU_REGS) += ptrace-fpu.o obj-$(CONFIG_COMPAT) += ptrace32.o obj-$(CONFIG_VSX) += ptrace-vsx.o ifneq ($(CONFIG_VSX),y) -obj-y += ptrace-novsx.o +obj-$(CONFIG_PPC_FPU_REGS) += ptrace-novsx.o endif obj-$(CONFIG_ALTIVEC) += ptrace-altivec.o obj-$(CONFIG_SPE) += ptrace-spe.o diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h index 67447a6197eb..3487f2c9735c 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-decl.h +++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h @@ -159,8 +159,29 @@ int tm_cgpr32_set(struct task_struct *target, const struct user_regset *regset, /* ptrace-view */ +int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data); +int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data); + extern const struct user_regset_view user_ppc_native_view; +/* ptrace-fpu */ +#ifdef CONFIG_PPC_FPU_REGS +int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data); +int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data); +#else +static inline int +ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data) +{ + return -EIO; +} + +static inline int +ptrace_put_fpr(struct task_struct *child, int index, unsigned long data) +{ + return -EIO; +} +#endif + /* ptrace-(no)adv */ void ppc_gethwdinfo(struct ppc_debug_info *dbginfo); int ptrace_get_debugreg(struct task_struct *child, unsigned long addr, diff --git a/arch/powerpc/kernel/ptrace/ptrace-fpu.c b/arch/powerpc/kernel/ptrace/ptrace-fpu.c new file mode 100644 index 000000000000..8301cb52dd99 --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace-fpu.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/regset.h> + +#include <asm/switch_to.h> + +#include "ptrace-decl.h" + +int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data) +{ + unsigned int fpidx = index - PT_FPR0; + + if (index > PT_FPSCR) + return -EIO; + + flush_fp_to_thread(child); + if (fpidx < (PT_FPSCR - PT_FPR0)) + memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long)); + else + *data = child->thread.fp_state.fpscr; + + return 0; +} + +int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data) +{ + unsigned int fpidx = index - PT_FPR0; + + if (index > PT_FPSCR) + return -EIO; + + flush_fp_to_thread(child); + if (fpidx < (PT_FPSCR - PT_FPR0)) + memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long)); + else + child->thread.fp_state.fpscr = data; + + return 0; +} + diff --git a/arch/powerpc/kernel/ptrace/ptrace-tm.c b/arch/powerpc/kernel/ptrace/ptrace-tm.c index 54f2d076206f..44045363a903 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-tm.c +++ b/arch/powerpc/kernel/ptrace/ptrace-tm.c @@ -86,6 +86,11 @@ int tm_cgpr_active(struct task_struct *target, const struct user_regset *regset) int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset, struct membuf to) { + struct membuf to_msr = membuf_at(&to, offsetof(struct pt_regs, msr)); +#ifdef CONFIG_PPC64 + struct membuf to_softe = membuf_at(&to, offsetof(struct pt_regs, softe)); +#endif + if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV; @@ -96,16 +101,12 @@ int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset, flush_fp_to_thread(target); flush_altivec_to_thread(target); - membuf_write(&to, &target->thread.ckpt_regs, - offsetof(struct pt_regs, msr)); - membuf_store(&to, get_user_ckpt_msr(target)); - - BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != - offsetof(struct pt_regs, msr) + sizeof(long)); + membuf_write(&to, &target->thread.ckpt_regs, sizeof(struct user_pt_regs)); - membuf_write(&to, &target->thread.ckpt_regs.orig_gpr3, - sizeof(struct user_pt_regs) - - offsetof(struct pt_regs, orig_gpr3)); + membuf_store(&to_msr, get_user_ckpt_msr(target)); +#ifdef CONFIG_PPC64 + membuf_store(&to_softe, 0x1ul); +#endif return membuf_zero(&to, ELF_NGREG * sizeof(unsigned long) - sizeof(struct user_pt_regs)); } diff --git a/arch/powerpc/kernel/ptrace/ptrace-view.c b/arch/powerpc/kernel/ptrace/ptrace-view.c index 7e6478e7ed07..2bad8068f598 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-view.c +++ b/arch/powerpc/kernel/ptrace/ptrace-view.c @@ -217,6 +217,10 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data) static int gpr_get(struct task_struct *target, const struct user_regset *regset, struct membuf to) { + struct membuf to_msr = membuf_at(&to, offsetof(struct pt_regs, msr)); +#ifdef CONFIG_PPC64 + struct membuf to_softe = membuf_at(&to, offsetof(struct pt_regs, softe)); +#endif int i; if (target->thread.regs == NULL) @@ -228,15 +232,12 @@ static int gpr_get(struct task_struct *target, const struct user_regset *regset, target->thread.regs->gpr[i] = NV_REG_POISON; } - membuf_write(&to, target->thread.regs, offsetof(struct pt_regs, msr)); - membuf_store(&to, get_user_msr(target)); - - BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != - offsetof(struct pt_regs, msr) + sizeof(long)); + membuf_write(&to, target->thread.regs, sizeof(struct user_pt_regs)); - membuf_write(&to, &target->thread.regs->orig_gpr3, - sizeof(struct user_pt_regs) - - offsetof(struct pt_regs, orig_gpr3)); + membuf_store(&to_msr, get_user_msr(target)); +#ifdef CONFIG_PPC64 + membuf_store(&to_softe, 0x1ul); +#endif return membuf_zero(&to, ELF_NGREG * sizeof(unsigned long) - sizeof(struct user_pt_regs)); } @@ -470,12 +471,12 @@ static int pkey_active(struct task_struct *target, const struct user_regset *reg static int pkey_get(struct task_struct *target, const struct user_regset *regset, struct membuf to) { - BUILD_BUG_ON(TSO(amr) + sizeof(unsigned long) != TSO(iamr)); if (!arch_pkeys_enabled()) return -ENODEV; - membuf_write(&to, &target->thread.amr, 2 * sizeof(unsigned long)); + membuf_store(&to, target->thread.regs->amr); + membuf_store(&to, target->thread.regs->iamr); return membuf_store(&to, default_uamor); } @@ -508,7 +509,8 @@ static int pkey_set(struct task_struct *target, const struct user_regset *regset * Pick the AMR values for the keys that kernel is using. This * will be indicated by the ~default_uamor bits. */ - target->thread.amr = (new_amr & default_uamor) | (target->thread.amr & ~default_uamor); + target->thread.regs->amr = (new_amr & default_uamor) | + (target->thread.regs->amr & ~default_uamor); return 0; } @@ -520,11 +522,13 @@ static const struct user_regset native_regsets[] = { .size = sizeof(long), .align = sizeof(long), .regset_get = gpr_get, .set = gpr_set }, +#ifdef CONFIG_PPC_FPU_REGS [REGSET_FPR] = { .core_note_type = NT_PRFPREG, .n = ELF_NFPREG, .size = sizeof(double), .align = sizeof(double), .regset_get = fpr_get, .set = fpr_set }, +#endif #ifdef CONFIG_ALTIVEC [REGSET_VMX] = { .core_note_type = NT_PPC_VMX, .n = 34, diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c index f6e51be47c6e..3d44b73adb83 100644 --- a/arch/powerpc/kernel/ptrace/ptrace.c +++ b/arch/powerpc/kernel/ptrace/ptrace.c @@ -55,31 +55,18 @@ long arch_ptrace(struct task_struct *child, long request, ret = -EIO; /* convert to index and check */ -#ifdef CONFIG_PPC32 - index = addr >> 2; - if ((addr & 3) || (index > PT_FPSCR) - || (child->thread.regs == NULL)) -#else - index = addr >> 3; - if ((addr & 7) || (index > PT_FPSCR)) -#endif + index = addr / sizeof(long); + if ((addr & (sizeof(long) - 1)) || !child->thread.regs) break; CHECK_FULL_REGS(child->thread.regs); - if (index < PT_FPR0) { + if (index < PT_FPR0) ret = ptrace_get_reg(child, (int) index, &tmp); - if (ret) - break; - } else { - unsigned int fpidx = index - PT_FPR0; - - flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) - memcpy(&tmp, &child->thread.TS_FPR(fpidx), - sizeof(long)); - else - tmp = child->thread.fp_state.fpscr; - } + else + ret = ptrace_get_fpr(child, index, &tmp); + + if (ret) + break; ret = put_user(tmp, datalp); break; } @@ -90,30 +77,15 @@ long arch_ptrace(struct task_struct *child, long request, ret = -EIO; /* convert to index and check */ -#ifdef CONFIG_PPC32 - index = addr >> 2; - if ((addr & 3) || (index > PT_FPSCR) - || (child->thread.regs == NULL)) -#else - index = addr >> 3; - if ((addr & 7) || (index > PT_FPSCR)) -#endif + index = addr / sizeof(long); + if ((addr & (sizeof(long) - 1)) || !child->thread.regs) break; CHECK_FULL_REGS(child->thread.regs); - if (index < PT_FPR0) { + if (index < PT_FPR0) ret = ptrace_put_reg(child, index, data); - } else { - unsigned int fpidx = index - PT_FPR0; - - flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) - memcpy(&child->thread.TS_FPR(fpidx), &data, - sizeof(long)); - else - child->thread.fp_state.fpscr = data; - ret = 0; - } + else + ret = ptrace_put_fpr(child, index, data); break; } diff --git a/arch/powerpc/kernel/ptrace/ptrace32.c b/arch/powerpc/kernel/ptrace/ptrace32.c index 7589a9665ffb..d30b9ad70edc 100644 --- a/arch/powerpc/kernel/ptrace/ptrace32.c +++ b/arch/powerpc/kernel/ptrace/ptrace32.c @@ -23,6 +23,8 @@ #include <asm/switch_to.h> +#include "ptrace-decl.h" + /* * does not yet catch signals sent when the child dies. * in exit.c or in signal.c. diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 954f41676f69..d126d71ea5bd 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -684,6 +684,63 @@ int rtas_set_indicator_fast(int indicator, int index, int new_value) return rc; } +/** + * rtas_ibm_suspend_me() - Call ibm,suspend-me to suspend the LPAR. + * + * @fw_status: RTAS call status will be placed here if not NULL. + * + * rtas_ibm_suspend_me() should be called only on a CPU which has + * received H_CONTINUE from the H_JOIN hcall. All other active CPUs + * should be waiting to return from H_JOIN. + * + * rtas_ibm_suspend_me() may suspend execution of the OS + * indefinitely. Callers should take appropriate measures upon return, such as + * resetting watchdog facilities. + * + * Callers may choose to retry this call if @fw_status is + * %RTAS_THREADS_ACTIVE. + * + * Return: + * 0 - The partition has resumed from suspend, possibly after + * migration to a different host. + * -ECANCELED - The operation was aborted. + * -EAGAIN - There were other CPUs not in H_JOIN at the time of the call. + * -EBUSY - Some other condition prevented the suspend from succeeding. + * -EIO - Hardware/platform error. + */ +int rtas_ibm_suspend_me(int *fw_status) +{ + int fwrc; + int ret; + + fwrc = rtas_call(rtas_token("ibm,suspend-me"), 0, 1, NULL); + + switch (fwrc) { + case 0: + ret = 0; + break; + case RTAS_SUSPEND_ABORTED: + ret = -ECANCELED; + break; + case RTAS_THREADS_ACTIVE: + ret = -EAGAIN; + break; + case RTAS_NOT_SUSPENDABLE: + case RTAS_OUTSTANDING_COPROC: + ret = -EBUSY; + break; + case -1: + default: + ret = -EIO; + break; + } + + if (fw_status) + *fw_status = fwrc; + + return ret; +} + void __noreturn rtas_restart(char *cmd) { if (rtas_flash_term_hook) @@ -741,163 +798,38 @@ void rtas_os_term(char *str) printk(KERN_EMERG "ibm,os-term call failed %d\n", status); } -static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; -#ifdef CONFIG_PPC_PSERIES -static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_when_done) -{ - u16 slb_size = mmu_slb_size; - int rc = H_MULTI_THREADS_ACTIVE; - int cpu; - - slb_set_size(SLB_MIN_SIZE); - printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", smp_processor_id()); - - while (rc == H_MULTI_THREADS_ACTIVE && !atomic_read(&data->done) && - !atomic_read(&data->error)) - rc = rtas_call(data->token, 0, 1, NULL); - - if (rc || atomic_read(&data->error)) { - printk(KERN_DEBUG "ibm,suspend-me returned %d\n", rc); - slb_set_size(slb_size); - } - - if (atomic_read(&data->error)) - rc = atomic_read(&data->error); - - atomic_set(&data->error, rc); - pSeries_coalesce_init(); - - if (wake_when_done) { - atomic_set(&data->done, 1); - - for_each_online_cpu(cpu) - plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu)); - } - - if (atomic_dec_return(&data->working) == 0) - complete(data->complete); - - return rc; -} - -int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data) -{ - atomic_inc(&data->working); - return __rtas_suspend_last_cpu(data, 0); -} - -static int __rtas_suspend_cpu(struct rtas_suspend_me_data *data, int wake_when_done) -{ - long rc = H_SUCCESS; - unsigned long msr_save; - int cpu; - - atomic_inc(&data->working); - - /* really need to ensure MSR.EE is off for H_JOIN */ - msr_save = mfmsr(); - mtmsr(msr_save & ~(MSR_EE)); - - while (rc == H_SUCCESS && !atomic_read(&data->done) && !atomic_read(&data->error)) - rc = plpar_hcall_norets(H_JOIN); - - mtmsr(msr_save); - - if (rc == H_SUCCESS) { - /* This cpu was prodded and the suspend is complete. */ - goto out; - } else if (rc == H_CONTINUE) { - /* All other cpus are in H_JOIN, this cpu does - * the suspend. - */ - return __rtas_suspend_last_cpu(data, wake_when_done); - } else { - printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n", - smp_processor_id(), rc); - atomic_set(&data->error, rc); - } - - if (wake_when_done) { - atomic_set(&data->done, 1); - - /* This cpu did the suspend or got an error; in either case, - * we need to prod all other other cpus out of join state. - * Extra prods are harmless. - */ - for_each_online_cpu(cpu) - plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu)); - } -out: - if (atomic_dec_return(&data->working) == 0) - complete(data->complete); - return rc; -} - -int rtas_suspend_cpu(struct rtas_suspend_me_data *data) -{ - return __rtas_suspend_cpu(data, 0); -} - -static void rtas_percpu_suspend_me(void *info) +/** + * rtas_activate_firmware() - Activate a new version of firmware. + * + * Activate a new version of partition firmware. The OS must call this + * after resuming from a partition hibernation or migration in order + * to maintain the ability to perform live firmware updates. It's not + * catastrophic for this method to be absent or to fail; just log the + * condition in that case. + * + * Context: This function may sleep. + */ +void rtas_activate_firmware(void) { - __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1); -} + int token; + int fwrc; -int rtas_ibm_suspend_me(u64 handle) -{ - long state; - long rc; - unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; - struct rtas_suspend_me_data data; - DECLARE_COMPLETION_ONSTACK(done); - - if (!rtas_service_present("ibm,suspend-me")) - return -ENOSYS; - - /* Make sure the state is valid */ - rc = plpar_hcall(H_VASI_STATE, retbuf, handle); - - state = retbuf[0]; - - if (rc) { - printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc); - return rc; - } else if (state == H_VASI_ENABLED) { - return -EAGAIN; - } else if (state != H_VASI_SUSPENDING) { - printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned state %ld\n", - state); - return -EIO; + token = rtas_token("ibm,activate-firmware"); + if (token == RTAS_UNKNOWN_SERVICE) { + pr_notice("ibm,activate-firmware method unavailable\n"); + return; } - atomic_set(&data.working, 0); - atomic_set(&data.done, 0); - atomic_set(&data.error, 0); - data.token = rtas_token("ibm,suspend-me"); - data.complete = &done; - - lock_device_hotplug(); - - cpu_hotplug_disable(); - - /* Call function on all CPUs. One of us will make the - * rtas call - */ - on_each_cpu(rtas_percpu_suspend_me, &data, 0); - - wait_for_completion(&done); - - if (atomic_read(&data.error) != 0) - printk(KERN_ERR "Error doing global join\n"); - - - cpu_hotplug_enable(); - - unlock_device_hotplug(); + do { + fwrc = rtas_call(token, 0, 1, NULL); + } while (rtas_busy_delay(fwrc)); - return atomic_read(&data.error); + if (fwrc) + pr_err("ibm,activate-firmware failed (%i)\n", fwrc); } +static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; +#ifdef CONFIG_PPC_PSERIES /** * rtas_call_reentrant() - Used for reentrant rtas calls * @token: Token for desired reentrant RTAS call @@ -948,12 +880,7 @@ int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...) return ret; } -#else /* CONFIG_PPC_PSERIES */ -int rtas_ibm_suspend_me(u64 handle) -{ - return -ENOSYS; -} -#endif +#endif /* CONFIG_PPC_PSERIES */ /** * Find a specific pseries error log in an RTAS extended event log. @@ -1030,7 +957,7 @@ static struct rtas_filter rtas_filters[] __ro_after_init = { { "ibm,display-message", -1, 0, -1, -1, -1 }, { "ibm,errinjct", -1, 2, -1, -1, -1, 1024 }, { "ibm,close-errinjct", -1, -1, -1, -1, -1 }, - { "ibm,open-errinct", -1, -1, -1, -1, -1 }, + { "ibm,open-errinjct", -1, -1, -1, -1, -1 }, { "ibm,get-config-addr-info2", -1, -1, -1, -1, -1 }, { "ibm,get-dynamic-sensor-state", -1, 1, -1, -1, -1 }, { "ibm,get-indices", -1, 2, 3, -1, -1 }, @@ -1050,9 +977,11 @@ static struct rtas_filter rtas_filters[] __ro_after_init = { { "set-time-for-power-on", -1, -1, -1, -1, -1 }, { "ibm,set-system-parameter", -1, 1, -1, -1, -1 }, { "set-time-of-day", -1, -1, -1, -1, -1 }, +#ifdef CONFIG_CPU_BIG_ENDIAN { "ibm,suspend-me", -1, -1, -1, -1, -1 }, { "ibm,update-nodes", -1, 0, -1, -1, -1, 4096 }, { "ibm,update-properties", -1, 0, -1, -1, -1, 4096 }, +#endif { "ibm,physical-attestation", -1, 0, 1, -1, -1 }, }; @@ -1183,7 +1112,7 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs) int rc = 0; u64 handle = ((u64)be32_to_cpu(args.args[0]) << 32) | be32_to_cpu(args.args[1]); - rc = rtas_ibm_suspend_me(handle); + rc = rtas_syscall_dispatch_ibm_suspend_me(handle); if (rc == -EAGAIN) args.rets[0] = cpu_to_be32(RTAS_NOT_SUSPENDABLE); else if (rc == -EIO) diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 808ec9fab605..71f38e9248be 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -90,8 +90,6 @@ EXPORT_SYMBOL_GPL(boot_cpuid); */ int dcache_bsize; int icache_bsize; -int ucache_bsize; - unsigned long klimit = (unsigned long) _end; @@ -802,8 +800,6 @@ static __init void print_system_info(void) pr_info("dcache_bsize = 0x%x\n", dcache_bsize); pr_info("icache_bsize = 0x%x\n", icache_bsize); - if (ucache_bsize != 0) - pr_info("ucache_bsize = 0x%x\n", ucache_bsize); pr_info("cpu_features = 0x%016lx\n", cur_cpu_spec->cpu_features); pr_info(" possible = 0x%016lx\n", @@ -919,8 +915,6 @@ void __init setup_arch(char **cmdline_p) /* On BookE, setup per-core TLB data structures. */ setup_tlb_core_data(); - - smp_release_cpus(); #endif /* Print various info about the machine that has been gathered so far. */ @@ -944,6 +938,8 @@ void __init setup_arch(char **cmdline_p) exc_lvl_early_init(); emergency_stack_init(); + smp_release_cpus(); + initmem_init(); early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT); diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h index 2ec835574cc9..2dd0d9cb5a20 100644 --- a/arch/powerpc/kernel/setup.h +++ b/arch/powerpc/kernel/setup.h @@ -8,12 +8,6 @@ #ifndef __ARCH_POWERPC_KERNEL_SETUP_H #define __ARCH_POWERPC_KERNEL_SETUP_H -#ifdef CONFIG_CC_IS_CLANG -#define __nostackprotector -#else -#define __nostackprotector __attribute__((__optimize__("no-stack-protector"))) -#endif - void initialize_cache_info(void); void irqstack_early_init(void); diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 057d6b8e9bb0..8ba49a6bf515 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -222,7 +222,4 @@ __init void initialize_cache_info(void) */ dcache_bsize = cur_cpu_spec->dcache_bsize; icache_bsize = cur_cpu_spec->icache_bsize; - ucache_bsize = 0; - if (IS_ENABLED(CONFIG_E200)) - ucache_bsize = icache_bsize = dcache_bsize; } diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 74fd47f46fa5..c28e949cc222 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -283,7 +283,7 @@ void __init record_spr_defaults(void) * device-tree is not accessible via normal means at this point. */ -void __init __nostackprotector early_setup(unsigned long dt_ptr) +void __init early_setup(unsigned long dt_ptr) { static __initdata struct paca_struct boot_paca; diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index a8bb0aca1d02..53782aa60ade 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -133,36 +133,6 @@ unsigned long copy_ckvsx_from_user(struct task_struct *task, return 0; } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -#else -inline unsigned long copy_fpr_to_user(void __user *to, - struct task_struct *task) -{ - return __copy_to_user(to, task->thread.fp_state.fpr, - ELF_NFPREG * sizeof(double)); -} - -inline unsigned long copy_fpr_from_user(struct task_struct *task, - void __user *from) -{ - return __copy_from_user(task->thread.fp_state.fpr, from, - ELF_NFPREG * sizeof(double)); -} - -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM -inline unsigned long copy_ckfpr_to_user(void __user *to, - struct task_struct *task) -{ - return __copy_to_user(to, task->thread.ckfp_state.fpr, - ELF_NFPREG * sizeof(double)); -} - -inline unsigned long copy_ckfpr_from_user(struct task_struct *task, - void __user *from) -{ - return __copy_from_user(task->thread.ckfp_state.fpr, from, - ELF_NFPREG * sizeof(double)); -} -#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ #endif /* Log an error when sending an unhandled signal to a process. Controlled @@ -174,20 +144,22 @@ int show_unhandled_signals = 1; /* * Allocate space for the signal frame */ -void __user *get_sigframe(struct ksignal *ksig, unsigned long sp, - size_t frame_size, int is_32) +static unsigned long get_tm_stackpointer(struct task_struct *tsk); + +void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk, + size_t frame_size, int is_32) { unsigned long oldsp, newsp; + unsigned long sp = get_tm_stackpointer(tsk); /* Default to using normal stack */ - oldsp = get_clean_sp(sp, is_32); + if (is_32) + oldsp = sp & 0x0ffffffffUL; + else + oldsp = sp; oldsp = sigsp(oldsp, ksig); newsp = (oldsp - frame_size) & ~0xFUL; - /* Check access */ - if (!access_ok((void __user *)newsp, oldsp - newsp)) - return NULL; - return (void __user *)newsp; } @@ -331,7 +303,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) user_enter(); } -unsigned long get_tm_stackpointer(struct task_struct *tsk) +static unsigned long get_tm_stackpointer(struct task_struct *tsk) { /* When in an active transaction that takes a signal, we need to be * careful with the stack. It's possible that the stack has moved back @@ -379,3 +351,14 @@ unsigned long get_tm_stackpointer(struct task_struct *tsk) #endif return ret; } + +static const char fm32[] = KERN_INFO "%s[%d]: bad frame in %s: %p nip %08lx lr %08lx\n"; +static const char fm64[] = KERN_INFO "%s[%d]: bad frame in %s: %p nip %016lx lr %016lx\n"; + +void signal_fault(struct task_struct *tsk, struct pt_regs *regs, + const char *where, void __user *ptr) +{ + if (show_unhandled_signals) + printk_ratelimited(regs->msr & MSR_64BIT ? fm64 : fm32, tsk->comm, + task_pid_nr(tsk), where, ptr, regs->nip, regs->link); +} diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index d396efca4068..2559a681536e 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -10,8 +10,8 @@ #ifndef _POWERPC_ARCH_SIGNAL_H #define _POWERPC_ARCH_SIGNAL_H -extern void __user *get_sigframe(struct ksignal *ksig, unsigned long sp, - size_t frame_size, int is_32); +void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk, + size_t frame_size, int is_32); extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset, struct task_struct *tsk); @@ -19,16 +19,6 @@ extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset, extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, struct task_struct *tsk); -extern unsigned long copy_fpr_to_user(void __user *to, - struct task_struct *task); -extern unsigned long copy_ckfpr_to_user(void __user *to, - struct task_struct *task); -extern unsigned long copy_fpr_from_user(struct task_struct *task, - void __user *from); -extern unsigned long copy_ckfpr_from_user(struct task_struct *task, - void __user *from); -extern unsigned long get_tm_stackpointer(struct task_struct *tsk); - #ifdef CONFIG_VSX extern unsigned long copy_vsx_to_user(void __user *to, struct task_struct *task); @@ -38,6 +28,104 @@ extern unsigned long copy_vsx_from_user(struct task_struct *task, void __user *from); extern unsigned long copy_ckvsx_from_user(struct task_struct *task, void __user *from); +unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task); +unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task); +unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from); +unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from); + +#define unsafe_copy_fpr_to_user(to, task, label) do { \ + struct task_struct *__t = task; \ + u64 __user *buf = (u64 __user *)to; \ + int i; \ + \ + for (i = 0; i < ELF_NFPREG - 1 ; i++) \ + unsafe_put_user(__t->thread.TS_FPR(i), &buf[i], label); \ + unsafe_put_user(__t->thread.fp_state.fpscr, &buf[i], label); \ +} while (0) + +#define unsafe_copy_vsx_to_user(to, task, label) do { \ + struct task_struct *__t = task; \ + u64 __user *buf = (u64 __user *)to; \ + int i; \ + \ + for (i = 0; i < ELF_NVSRHALFREG ; i++) \ + unsafe_put_user(__t->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \ + &buf[i], label);\ +} while (0) + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +#define unsafe_copy_ckfpr_to_user(to, task, label) do { \ + struct task_struct *__t = task; \ + u64 __user *buf = (u64 __user *)to; \ + int i; \ + \ + for (i = 0; i < ELF_NFPREG - 1 ; i++) \ + unsafe_put_user(__t->thread.TS_CKFPR(i), &buf[i], label);\ + unsafe_put_user(__t->thread.ckfp_state.fpscr, &buf[i], label); \ +} while (0) + +#define unsafe_copy_ckvsx_to_user(to, task, label) do { \ + struct task_struct *__t = task; \ + u64 __user *buf = (u64 __user *)to; \ + int i; \ + \ + for (i = 0; i < ELF_NVSRHALFREG ; i++) \ + unsafe_put_user(__t->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \ + &buf[i], label);\ +} while (0) +#endif +#elif defined(CONFIG_PPC_FPU_REGS) + +#define unsafe_copy_fpr_to_user(to, task, label) \ + unsafe_copy_to_user(to, (task)->thread.fp_state.fpr, \ + ELF_NFPREG * sizeof(double), label) + +static inline unsigned long +copy_fpr_to_user(void __user *to, struct task_struct *task) +{ + return __copy_to_user(to, task->thread.fp_state.fpr, + ELF_NFPREG * sizeof(double)); +} + +static inline unsigned long +copy_fpr_from_user(struct task_struct *task, void __user *from) +{ + return __copy_from_user(task->thread.fp_state.fpr, from, + ELF_NFPREG * sizeof(double)); +} + +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +#define unsafe_copy_ckfpr_to_user(to, task, label) \ + unsafe_copy_to_user(to, (task)->thread.ckfp_state.fpr, \ + ELF_NFPREG * sizeof(double), label) + +inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task) +{ + return __copy_to_user(to, task->thread.ckfp_state.fpr, + ELF_NFPREG * sizeof(double)); +} + +static inline unsigned long +copy_ckfpr_from_user(struct task_struct *task, void __user *from) +{ + return __copy_from_user(task->thread.ckfp_state.fpr, from, + ELF_NFPREG * sizeof(double)); +} +#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ +#else +#define unsafe_copy_fpr_to_user(to, task, label) do { } while (0) + +static inline unsigned long +copy_fpr_to_user(void __user *to, struct task_struct *task) +{ + return 0; +} + +static inline unsigned long +copy_fpr_from_user(struct task_struct *task, void __user *from) +{ + return 0; +} #endif #ifdef CONFIG_PPC64 @@ -58,4 +146,7 @@ static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, #endif /* !defined(CONFIG_PPC64) */ +void signal_fault(struct task_struct *tsk, struct pt_regs *regs, + const char *where, void __user *ptr); + #endif /* _POWERPC_ARCH_SIGNAL_H */ diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 96950f189b5a..934cbdf6dd10 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -58,8 +58,6 @@ #define mcontext mcontext32 #define ucontext ucontext32 -#define __save_altstack __compat_save_altstack - /* * Userspace code may pass a ucontext which doesn't include VSX added * at the end. We need to check for this case. @@ -84,10 +82,7 @@ * Functions for flipping sigsets (thanks to brain dead generic * implementation that makes things simple for little endian only) */ -static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) -{ - return put_compat_sigset(uset, set, sizeof(*uset)); -} +#define unsafe_put_sigset_t unsafe_put_compat_sigset static inline int get_sigset_t(sigset_t *set, const compat_sigset_t __user *uset) @@ -98,8 +93,8 @@ static inline int get_sigset_t(sigset_t *set, #define to_user_ptr(p) ptr_to_compat(p) #define from_user_ptr(p) compat_ptr(p) -static inline int save_general_regs(struct pt_regs *regs, - struct mcontext __user *frame) +static __always_inline int +save_general_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame) { elf_greg_t64 *gregs = (elf_greg_t64 *)regs; int val, i; @@ -113,10 +108,12 @@ static inline int save_general_regs(struct pt_regs *regs, else val = gregs[i]; - if (__put_user(val, &frame->mc_gregs[i])) - return -EFAULT; + unsafe_put_user(val, &frame->mc_gregs[i], failed); } return 0; + +failed: + return 1; } static inline int restore_general_regs(struct pt_regs *regs, @@ -138,10 +135,12 @@ static inline int restore_general_regs(struct pt_regs *regs, #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) -static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) -{ - return copy_to_user(uset, set, sizeof(*uset)); -} +#define unsafe_put_sigset_t(uset, set, label) do { \ + sigset_t __user *__us = uset ; \ + const sigset_t *__s = set; \ + \ + unsafe_copy_to_user(__us, __s, sizeof(*__us), label); \ +} while (0) static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset) { @@ -151,11 +150,15 @@ static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset) #define to_user_ptr(p) ((unsigned long)(p)) #define from_user_ptr(p) ((void __user *)(p)) -static inline int save_general_regs(struct pt_regs *regs, - struct mcontext __user *frame) +static __always_inline int +save_general_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame) { WARN_ON(!FULL_REGS(regs)); - return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE); + unsafe_copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE, failed); + return 0; + +failed: + return 1; } static inline int restore_general_regs(struct pt_regs *regs, @@ -173,6 +176,11 @@ static inline int restore_general_regs(struct pt_regs *regs, } #endif +#define unsafe_save_general_regs(regs, frame, label) do { \ + if (save_general_regs_unsafe(regs, frame)) \ + goto label; \ +} while (0) + /* * When we have signals to deliver, we set up on the * user stack, going down from the original stack pointer: @@ -199,9 +207,6 @@ struct sigframe { int abigap[56]; }; -/* We use the mc_pad field for the signal return trampoline. */ -#define tramp mc_pad - /* * When we have rt signals to deliver, we set up on the * user stack, going down from the original stack pointer: @@ -235,26 +240,39 @@ struct rt_sigframe { * We only save the altivec/spe registers if the process has used * altivec/spe instructions at some point. */ -static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, - struct mcontext __user *tm_frame, int sigret, - int ctx_has_vsx_region) +static void prepare_save_user_regs(int ctx_has_vsx_region) { - unsigned long msr = regs->msr; - /* Make sure floating point registers are stored in regs */ flush_fp_to_thread(current); +#ifdef CONFIG_ALTIVEC + if (current->thread.used_vr) + flush_altivec_to_thread(current); + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + current->thread.vrsave = mfspr(SPRN_VRSAVE); +#endif +#ifdef CONFIG_VSX + if (current->thread.used_vsr && ctx_has_vsx_region) + flush_vsx_to_thread(current); +#endif +#ifdef CONFIG_SPE + if (current->thread.used_spe) + flush_spe_to_thread(current); +#endif +} + +static int save_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame, + struct mcontext __user *tm_frame, int ctx_has_vsx_region) +{ + unsigned long msr = regs->msr; /* save general registers */ - if (save_general_regs(regs, frame)) - return 1; + unsafe_save_general_regs(regs, frame, failed); #ifdef CONFIG_ALTIVEC /* save altivec registers */ if (current->thread.used_vr) { - flush_altivec_to_thread(current); - if (__copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; + unsafe_copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state, + ELF_NVRREG * sizeof(vector128), failed); /* set MSR_VEC in the saved MSR value to indicate that frame->mc_vregs contains valid data */ msr |= MSR_VEC; @@ -267,13 +285,10 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, * most significant bits of that same vector. --BenH * Note that the current VRSAVE value is in the SPR at this point. */ - if (cpu_has_feature(CPU_FTR_ALTIVEC)) - current->thread.vrsave = mfspr(SPRN_VRSAVE); - if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32])) - return 1; + unsafe_put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32], + failed); #endif /* CONFIG_ALTIVEC */ - if (copy_fpr_to_user(&frame->mc_fregs, current)) - return 1; + unsafe_copy_fpr_to_user(&frame->mc_fregs, current, failed); /* * Clear the MSR VSX bit to indicate there is no valid state attached @@ -288,19 +303,15 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, * contains valid data */ if (current->thread.used_vsr && ctx_has_vsx_region) { - flush_vsx_to_thread(current); - if (copy_vsx_to_user(&frame->mc_vsregs, current)) - return 1; + unsafe_copy_vsx_to_user(&frame->mc_vsregs, current, failed); msr |= MSR_VSX; } #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE /* save spe registers */ if (current->thread.used_spe) { - flush_spe_to_thread(current); - if (__copy_to_user(&frame->mc_vregs, current->thread.evr, - ELF_NEVRREG * sizeof(u32))) - return 1; + unsafe_copy_to_user(&frame->mc_vregs, current->thread.evr, + ELF_NEVRREG * sizeof(u32), failed); /* set MSR_SPE in the saved MSR value to indicate that frame->mc_vregs contains valid data */ msr |= MSR_SPE; @@ -308,30 +319,29 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, /* else assert((regs->msr & MSR_SPE) == 0) */ /* We always copy to/from spefscr */ - if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG)) - return 1; + unsafe_put_user(current->thread.spefscr, + (u32 __user *)&frame->mc_vregs + ELF_NEVRREG, failed); #endif /* CONFIG_SPE */ - if (__put_user(msr, &frame->mc_gregs[PT_MSR])) - return 1; + unsafe_put_user(msr, &frame->mc_gregs[PT_MSR], failed); + /* We need to write 0 the MSR top 32 bits in the tm frame so that we * can check it on the restore to see if TM is active */ - if (tm_frame && __put_user(0, &tm_frame->mc_gregs[PT_MSR])) - return 1; - - if (sigret) { - /* Set up the sigreturn trampoline: li 0,sigret; sc */ - if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0]) - || __put_user(PPC_INST_SC, &frame->tramp[1])) - return 1; - flush_icache_range((unsigned long) &frame->tramp[0], - (unsigned long) &frame->tramp[2]); - } + if (tm_frame) + unsafe_put_user(0, &tm_frame->mc_gregs[PT_MSR], failed); return 0; + +failed: + return 1; } +#define unsafe_save_user_regs(regs, frame, tm_frame, has_vsx, label) do { \ + if (save_user_regs_unsafe(regs, frame, tm_frame, has_vsx)) \ + goto label; \ +} while (0) + #ifdef CONFIG_PPC_TRANSACTIONAL_MEM /* * Save the current user registers on the user stack. @@ -340,19 +350,28 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, * We also save the transactional registers to a second ucontext in the * frame. * - * See save_user_regs() and signal_64.c:setup_tm_sigcontexts(). + * See save_user_regs_unsafe() and signal_64.c:setup_tm_sigcontexts(). */ -static int save_tm_user_regs(struct pt_regs *regs, - struct mcontext __user *frame, - struct mcontext __user *tm_frame, int sigret, - unsigned long msr) +static void prepare_save_tm_user_regs(void) { WARN_ON(tm_suspend_disabled); +#ifdef CONFIG_ALTIVEC + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + current->thread.ckvrsave = mfspr(SPRN_VRSAVE); +#endif +#ifdef CONFIG_SPE + if (current->thread.used_spe) + flush_spe_to_thread(current); +#endif +} + +static int save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame, + struct mcontext __user *tm_frame, unsigned long msr) +{ /* Save both sets of general registers */ - if (save_general_regs(¤t->thread.ckpt_regs, frame) - || save_general_regs(regs, tm_frame)) - return 1; + unsafe_save_general_regs(¤t->thread.ckpt_regs, frame, failed); + unsafe_save_general_regs(regs, tm_frame, failed); /* Stash the top half of the 64bit MSR into the 32bit MSR word * of the transactional mcontext. This way we have a backward-compatible @@ -360,26 +379,21 @@ static int save_tm_user_regs(struct pt_regs *regs, * also look at what type of transaction (T or S) was active at the * time of the signal. */ - if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR])) - return 1; + unsafe_put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR], failed); #ifdef CONFIG_ALTIVEC /* save altivec registers */ if (current->thread.used_vr) { - if (__copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; - if (msr & MSR_VEC) { - if (__copy_to_user(&tm_frame->mc_vregs, - ¤t->thread.vr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; - } else { - if (__copy_to_user(&tm_frame->mc_vregs, - ¤t->thread.ckvr_state, - ELF_NVRREG * sizeof(vector128))) - return 1; - } + unsafe_copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state, + ELF_NVRREG * sizeof(vector128), failed); + if (msr & MSR_VEC) + unsafe_copy_to_user(&tm_frame->mc_vregs, + ¤t->thread.vr_state, + ELF_NVRREG * sizeof(vector128), failed); + else + unsafe_copy_to_user(&tm_frame->mc_vregs, + ¤t->thread.ckvr_state, + ELF_NVRREG * sizeof(vector128), failed); /* set MSR_VEC in the saved MSR value to indicate that * frame->mc_vregs contains valid data @@ -392,31 +406,21 @@ static int save_tm_user_regs(struct pt_regs *regs, * significant bits of a vector, we "cheat" and stuff VRSAVE in the * most significant bits of that same vector. --BenH */ - if (cpu_has_feature(CPU_FTR_ALTIVEC)) - current->thread.ckvrsave = mfspr(SPRN_VRSAVE); - if (__put_user(current->thread.ckvrsave, - (u32 __user *)&frame->mc_vregs[32])) - return 1; - if (msr & MSR_VEC) { - if (__put_user(current->thread.vrsave, - (u32 __user *)&tm_frame->mc_vregs[32])) - return 1; - } else { - if (__put_user(current->thread.ckvrsave, - (u32 __user *)&tm_frame->mc_vregs[32])) - return 1; - } + unsafe_put_user(current->thread.ckvrsave, + (u32 __user *)&frame->mc_vregs[32], failed); + if (msr & MSR_VEC) + unsafe_put_user(current->thread.vrsave, + (u32 __user *)&tm_frame->mc_vregs[32], failed); + else + unsafe_put_user(current->thread.ckvrsave, + (u32 __user *)&tm_frame->mc_vregs[32], failed); #endif /* CONFIG_ALTIVEC */ - if (copy_ckfpr_to_user(&frame->mc_fregs, current)) - return 1; - if (msr & MSR_FP) { - if (copy_fpr_to_user(&tm_frame->mc_fregs, current)) - return 1; - } else { - if (copy_ckfpr_to_user(&tm_frame->mc_fregs, current)) - return 1; - } + unsafe_copy_ckfpr_to_user(&frame->mc_fregs, current, failed); + if (msr & MSR_FP) + unsafe_copy_fpr_to_user(&tm_frame->mc_fregs, current, failed); + else + unsafe_copy_ckfpr_to_user(&tm_frame->mc_fregs, current, failed); #ifdef CONFIG_VSX /* @@ -426,54 +430,54 @@ static int save_tm_user_regs(struct pt_regs *regs, * contains valid data */ if (current->thread.used_vsr) { - if (copy_ckvsx_to_user(&frame->mc_vsregs, current)) - return 1; - if (msr & MSR_VSX) { - if (copy_vsx_to_user(&tm_frame->mc_vsregs, - current)) - return 1; - } else { - if (copy_ckvsx_to_user(&tm_frame->mc_vsregs, current)) - return 1; - } + unsafe_copy_ckvsx_to_user(&frame->mc_vsregs, current, failed); + if (msr & MSR_VSX) + unsafe_copy_vsx_to_user(&tm_frame->mc_vsregs, current, failed); + else + unsafe_copy_ckvsx_to_user(&tm_frame->mc_vsregs, current, failed); msr |= MSR_VSX; } #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE /* SPE regs are not checkpointed with TM, so this section is - * simply the same as in save_user_regs(). + * simply the same as in save_user_regs_unsafe(). */ if (current->thread.used_spe) { - flush_spe_to_thread(current); - if (__copy_to_user(&frame->mc_vregs, current->thread.evr, - ELF_NEVRREG * sizeof(u32))) - return 1; + unsafe_copy_to_user(&frame->mc_vregs, current->thread.evr, + ELF_NEVRREG * sizeof(u32), failed); /* set MSR_SPE in the saved MSR value to indicate that * frame->mc_vregs contains valid data */ msr |= MSR_SPE; } /* We always copy to/from spefscr */ - if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG)) - return 1; + unsafe_put_user(current->thread.spefscr, + (u32 __user *)&frame->mc_vregs + ELF_NEVRREG, failed); #endif /* CONFIG_SPE */ - if (__put_user(msr, &frame->mc_gregs[PT_MSR])) - return 1; - if (sigret) { - /* Set up the sigreturn trampoline: li 0,sigret; sc */ - if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0]) - || __put_user(PPC_INST_SC, &frame->tramp[1])) - return 1; - flush_icache_range((unsigned long) &frame->tramp[0], - (unsigned long) &frame->tramp[2]); - } + unsafe_put_user(msr, &frame->mc_gregs[PT_MSR], failed); return 0; + +failed: + return 1; +} +#else +static void prepare_save_tm_user_regs(void) { } + +static int save_tm_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame, + struct mcontext __user *tm_frame, unsigned long msr) +{ + return 0; } #endif +#define unsafe_save_tm_user_regs(regs, frame, tm_frame, msr, label) do { \ + if (save_tm_user_regs_unsafe(regs, frame, tm_frame, msr)) \ + goto label; \ +} while (0) + /* * Restore the current user register values from the user stack, * (except for MSR). @@ -751,96 +755,189 @@ static long restore_tm_user_regs(struct pt_regs *regs, int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, struct task_struct *tsk) { - struct rt_sigframe __user *rt_sf; - struct mcontext __user *frame; - struct mcontext __user *tm_frame = NULL; - void __user *addr; + struct rt_sigframe __user *frame; + struct mcontext __user *mctx; + struct mcontext __user *tm_mctx = NULL; unsigned long newsp = 0; - int sigret; unsigned long tramp; struct pt_regs *regs = tsk->thread.regs; -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM /* Save the thread's msr before get_tm_stackpointer() changes it */ unsigned long msr = regs->msr; -#endif - - BUG_ON(tsk != current); /* Set up Signal Frame */ - /* Put a Real Time Context onto stack */ - rt_sf = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*rt_sf), 1); - addr = rt_sf; - if (unlikely(rt_sf == NULL)) + frame = get_sigframe(ksig, tsk, sizeof(*frame), 1); + mctx = &frame->uc.uc_mcontext; +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + tm_mctx = &frame->uc_transact.uc_mcontext; +#endif + if (MSR_TM_ACTIVE(msr)) + prepare_save_tm_user_regs(); + else + prepare_save_user_regs(1); + + if (!user_write_access_begin(frame, sizeof(*frame))) goto badframe; /* Put the siginfo & fill in most of the ucontext */ - if (copy_siginfo_to_user(&rt_sf->info, &ksig->info) - || __put_user(0, &rt_sf->uc.uc_flags) - || __save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1]) - || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext), - &rt_sf->uc.uc_regs) - || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset)) - goto badframe; + unsafe_put_user(0, &frame->uc.uc_flags, failed); +#ifdef CONFIG_PPC64 + unsafe_compat_save_altstack(&frame->uc.uc_stack, regs->gpr[1], failed); +#else + unsafe_save_altstack(&frame->uc.uc_stack, regs->gpr[1], failed); +#endif + unsafe_put_user(to_user_ptr(&frame->uc.uc_mcontext), &frame->uc.uc_regs, failed); - /* Save user registers on the stack */ - frame = &rt_sf->uc.uc_mcontext; - addr = frame; - if (vdso32_rt_sigtramp && tsk->mm->context.vdso_base) { - sigret = 0; - tramp = tsk->mm->context.vdso_base + vdso32_rt_sigtramp; + if (MSR_TM_ACTIVE(msr)) { +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + unsafe_put_user((unsigned long)&frame->uc_transact, + &frame->uc.uc_link, failed); + unsafe_put_user((unsigned long)tm_mctx, + &frame->uc_transact.uc_regs, failed); +#endif + unsafe_save_tm_user_regs(regs, mctx, tm_mctx, msr, failed); } else { - sigret = __NR_rt_sigreturn; - tramp = (unsigned long) frame->tramp; + unsafe_put_user(0, &frame->uc.uc_link, failed); + unsafe_save_user_regs(regs, mctx, tm_mctx, 1, failed); } -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - tm_frame = &rt_sf->uc_transact.uc_mcontext; - if (MSR_TM_ACTIVE(msr)) { - if (__put_user((unsigned long)&rt_sf->uc_transact, - &rt_sf->uc.uc_link) || - __put_user((unsigned long)tm_frame, - &rt_sf->uc_transact.uc_regs)) - goto badframe; - if (save_tm_user_regs(regs, frame, tm_frame, sigret, msr)) - goto badframe; - } - else -#endif - { - if (__put_user(0, &rt_sf->uc.uc_link)) - goto badframe; - if (save_user_regs(regs, frame, tm_frame, sigret, 1)) - goto badframe; + /* Save user registers on the stack */ + if (tsk->mm->context.vdso) { + tramp = VDSO32_SYMBOL(tsk->mm->context.vdso, sigtramp_rt32); + } else { + tramp = (unsigned long)mctx->mc_pad; + /* Set up the sigreturn trampoline: li r0,sigret; sc */ + unsafe_put_user(PPC_INST_ADDI + __NR_rt_sigreturn, &mctx->mc_pad[0], + failed); + unsafe_put_user(PPC_INST_SC, &mctx->mc_pad[1], failed); } + unsafe_put_sigset_t(&frame->uc.uc_sigmask, oldset, failed); + + user_write_access_end(); + + if (copy_siginfo_to_user(&frame->info, &ksig->info)) + goto badframe; + + if (tramp == (unsigned long)mctx->mc_pad) + flush_icache_range(tramp, tramp + 2 * sizeof(unsigned long)); + regs->link = tramp; +#ifdef CONFIG_PPC_FPU_REGS tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */ +#endif /* create a stack frame for the caller of the handler */ - newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16); - addr = (void __user *)regs->gpr[1]; + newsp = ((unsigned long)frame) - (__SIGNAL_FRAMESIZE + 16); if (put_user(regs->gpr[1], (u32 __user *)newsp)) goto badframe; /* Fill registers for signal handler */ regs->gpr[1] = newsp; regs->gpr[3] = ksig->sig; - regs->gpr[4] = (unsigned long) &rt_sf->info; - regs->gpr[5] = (unsigned long) &rt_sf->uc; - regs->gpr[6] = (unsigned long) rt_sf; + regs->gpr[4] = (unsigned long)&frame->info; + regs->gpr[5] = (unsigned long)&frame->uc; + regs->gpr[6] = (unsigned long)frame; regs->nip = (unsigned long) ksig->ka.sa.sa_handler; /* enter the signal handler in native-endian mode */ regs->msr &= ~MSR_LE; regs->msr |= (MSR_KERNEL & MSR_LE); return 0; +failed: + user_write_access_end(); + +badframe: + signal_fault(tsk, regs, "handle_rt_signal32", frame); + + return 1; +} + +/* + * OK, we're invoking a handler + */ +int handle_signal32(struct ksignal *ksig, sigset_t *oldset, + struct task_struct *tsk) +{ + struct sigcontext __user *sc; + struct sigframe __user *frame; + struct mcontext __user *mctx; + struct mcontext __user *tm_mctx = NULL; + unsigned long newsp = 0; + unsigned long tramp; + struct pt_regs *regs = tsk->thread.regs; + /* Save the thread's msr before get_tm_stackpointer() changes it */ + unsigned long msr = regs->msr; + + /* Set up Signal Frame */ + frame = get_sigframe(ksig, tsk, sizeof(*frame), 1); + mctx = &frame->mctx; +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + tm_mctx = &frame->mctx_transact; +#endif + if (MSR_TM_ACTIVE(msr)) + prepare_save_tm_user_regs(); + else + prepare_save_user_regs(1); + + if (!user_write_access_begin(frame, sizeof(*frame))) + goto badframe; + sc = (struct sigcontext __user *) &frame->sctx; + +#if _NSIG != 64 +#error "Please adjust handle_signal()" +#endif + unsafe_put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler, failed); + unsafe_put_user(oldset->sig[0], &sc->oldmask, failed); +#ifdef CONFIG_PPC64 + unsafe_put_user((oldset->sig[0] >> 32), &sc->_unused[3], failed); +#else + unsafe_put_user(oldset->sig[1], &sc->_unused[3], failed); +#endif + unsafe_put_user(to_user_ptr(mctx), &sc->regs, failed); + unsafe_put_user(ksig->sig, &sc->signal, failed); + + if (MSR_TM_ACTIVE(msr)) + unsafe_save_tm_user_regs(regs, mctx, tm_mctx, msr, failed); + else + unsafe_save_user_regs(regs, mctx, tm_mctx, 1, failed); + + if (tsk->mm->context.vdso) { + tramp = VDSO32_SYMBOL(tsk->mm->context.vdso, sigtramp32); + } else { + tramp = (unsigned long)mctx->mc_pad; + /* Set up the sigreturn trampoline: li r0,sigret; sc */ + unsafe_put_user(PPC_INST_ADDI + __NR_sigreturn, &mctx->mc_pad[0], failed); + unsafe_put_user(PPC_INST_SC, &mctx->mc_pad[1], failed); + } + user_write_access_end(); + + if (tramp == (unsigned long)mctx->mc_pad) + flush_icache_range(tramp, tramp + 2 * sizeof(unsigned long)); + + regs->link = tramp; + +#ifdef CONFIG_PPC_FPU_REGS + tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */ +#endif + + /* create a stack frame for the caller of the handler */ + newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE; + if (put_user(regs->gpr[1], (u32 __user *)newsp)) + goto badframe; + + regs->gpr[1] = newsp; + regs->gpr[3] = ksig->sig; + regs->gpr[4] = (unsigned long) sc; + regs->nip = (unsigned long)ksig->ka.sa.sa_handler; + /* enter the signal handler in big-endian mode */ + regs->msr &= ~MSR_LE; + return 0; + +failed: + user_write_access_end(); + badframe: - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO - "%s[%d]: bad frame in handle_rt_signal32: " - "%p nip %08lx lr %08lx\n", - tsk->comm, tsk->pid, - addr, regs->nip, regs->link); + signal_fault(tsk, regs, "handle_signal32", frame); return 1; } @@ -967,11 +1064,13 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx, */ mctx = (struct mcontext __user *) ((unsigned long) &old_ctx->uc_mcontext & ~0xfUL); - if (!access_ok(old_ctx, ctx_size) - || save_user_regs(regs, mctx, NULL, 0, ctx_has_vsx_region) - || put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked) - || __put_user(to_user_ptr(mctx), &old_ctx->uc_regs)) + prepare_save_user_regs(ctx_has_vsx_region); + if (!user_write_access_begin(old_ctx, ctx_size)) return -EFAULT; + unsafe_save_user_regs(regs, mctx, NULL, ctx_has_vsx_region, failed); + unsafe_put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked, failed); + unsafe_put_user(to_user_ptr(mctx), &old_ctx->uc_regs, failed); + user_write_access_end(); } if (new_ctx == NULL) return 0; @@ -995,6 +1094,10 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx, set_thread_flag(TIF_RESTOREALL); return 0; + +failed: + user_write_access_end(); + return -EFAULT; } #ifdef CONFIG_PPC64 @@ -1092,12 +1195,7 @@ SYSCALL_DEFINE0(rt_sigreturn) return 0; bad: - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO - "%s[%d]: bad frame in sys_rt_sigreturn: " - "%p nip %08lx lr %08lx\n", - current->comm, current->pid, - rt_sf, regs->nip, regs->link); + signal_fault(current, regs, "sys_rt_sigreturn", rt_sf); force_sig(SIGSEGV); return 0; @@ -1181,12 +1279,7 @@ SYSCALL_DEFINE3(debug_setcontext, struct ucontext __user *, ctx, * We kill the task with a SIGSEGV in this situation. */ if (do_setcontext(ctx, regs, 1)) { - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO "%s[%d]: bad frame in " - "sys_debug_setcontext: %p nip %08lx " - "lr %08lx\n", - current->comm, current->pid, - ctx, regs->nip, regs->link); + signal_fault(current, regs, "sys_debug_setcontext", ctx); force_sig(SIGSEGV); goto out; @@ -1208,96 +1301,6 @@ SYSCALL_DEFINE3(debug_setcontext, struct ucontext __user *, ctx, #endif /* - * OK, we're invoking a handler - */ -int handle_signal32(struct ksignal *ksig, sigset_t *oldset, - struct task_struct *tsk) -{ - struct sigcontext __user *sc; - struct sigframe __user *frame; - struct mcontext __user *tm_mctx = NULL; - unsigned long newsp = 0; - int sigret; - unsigned long tramp; - struct pt_regs *regs = tsk->thread.regs; -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - /* Save the thread's msr before get_tm_stackpointer() changes it */ - unsigned long msr = regs->msr; -#endif - - BUG_ON(tsk != current); - - /* Set up Signal Frame */ - frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 1); - if (unlikely(frame == NULL)) - goto badframe; - sc = (struct sigcontext __user *) &frame->sctx; - -#if _NSIG != 64 -#error "Please adjust handle_signal()" -#endif - if (__put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler) - || __put_user(oldset->sig[0], &sc->oldmask) -#ifdef CONFIG_PPC64 - || __put_user((oldset->sig[0] >> 32), &sc->_unused[3]) -#else - || __put_user(oldset->sig[1], &sc->_unused[3]) -#endif - || __put_user(to_user_ptr(&frame->mctx), &sc->regs) - || __put_user(ksig->sig, &sc->signal)) - goto badframe; - - if (vdso32_sigtramp && tsk->mm->context.vdso_base) { - sigret = 0; - tramp = tsk->mm->context.vdso_base + vdso32_sigtramp; - } else { - sigret = __NR_sigreturn; - tramp = (unsigned long) frame->mctx.tramp; - } - -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - tm_mctx = &frame->mctx_transact; - if (MSR_TM_ACTIVE(msr)) { - if (save_tm_user_regs(regs, &frame->mctx, &frame->mctx_transact, - sigret, msr)) - goto badframe; - } - else -#endif - { - if (save_user_regs(regs, &frame->mctx, tm_mctx, sigret, 1)) - goto badframe; - } - - regs->link = tramp; - - tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */ - - /* create a stack frame for the caller of the handler */ - newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE; - if (put_user(regs->gpr[1], (u32 __user *)newsp)) - goto badframe; - - regs->gpr[1] = newsp; - regs->gpr[3] = ksig->sig; - regs->gpr[4] = (unsigned long) sc; - regs->nip = (unsigned long) (unsigned long)ksig->ka.sa.sa_handler; - /* enter the signal handler in big-endian mode */ - regs->msr &= ~MSR_LE; - return 0; - -badframe: - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO - "%s[%d]: bad frame in handle_signal32: " - "%p nip %08lx lr %08lx\n", - tsk->comm, tsk->pid, - frame, regs->nip, regs->link); - - return 1; -} - -/* * Do a signal return; undo the signal stack. */ #ifdef CONFIG_PPC64 @@ -1363,12 +1366,7 @@ SYSCALL_DEFINE0(sigreturn) return 0; badframe: - if (show_unhandled_signals) - printk_ratelimited(KERN_INFO - "%s[%d]: bad frame in sys_sigreturn: " - "%p nip %08lx lr %08lx\n", - current->comm, current->pid, - addr, regs->nip, regs->link); + signal_fault(current, regs, "sys_sigreturn", addr); force_sig(SIGSEGV); return 0; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index bfc939360bad..f9e4a1ac440f 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -66,11 +66,6 @@ struct rt_sigframe { char abigap[USER_REDZONE_SIZE]; } __attribute__ ((aligned (16))); -static const char fmt32[] = KERN_INFO \ - "%s[%d]: bad frame in %s: %08lx nip %08lx lr %08lx\n"; -static const char fmt64[] = KERN_INFO \ - "%s[%d]: bad frame in %s: %016lx nip %016lx lr %016lx\n"; - /* * This computes a quad word aligned pointer inside the vmx_reserve array * element. For historical reasons sigcontext might not be quad word aligned, @@ -801,10 +796,7 @@ SYSCALL_DEFINE0(rt_sigreturn) return 0; badframe: - if (show_unhandled_signals) - printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32, - current->comm, current->pid, "rt_sigreturn", - (long)uc, regs->nip, regs->link); + signal_fault(current, regs, "rt_sigreturn", uc); force_sig(SIGSEGV); return 0; @@ -822,10 +814,8 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, unsigned long msr = regs->msr; #endif - BUG_ON(tsk != current); - - frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 0); - if (unlikely(frame == NULL)) + frame = get_sigframe(ksig, tsk, sizeof(*frame), 0); + if (!access_ok(frame, sizeof(*frame))) goto badframe; err |= __put_user(&frame->info, &frame->pinfo); @@ -864,8 +854,8 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, tsk->thread.fp_state.fpscr = 0; /* Set up to return from userspace. */ - if (vdso64_rt_sigtramp && tsk->mm->context.vdso_base) { - regs->nip = tsk->mm->context.vdso_base + vdso64_rt_sigtramp; + if (tsk->mm->context.vdso) { + regs->nip = VDSO64_SYMBOL(tsk->mm->context.vdso, sigtramp_rt64); } else { err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]); if (err) @@ -913,10 +903,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, return 0; badframe: - if (show_unhandled_signals) - printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32, - tsk->comm, tsk->pid, "setup_rt_frame", - (long)frame, regs->nip, regs->link); + signal_fault(current, regs, "handle_rt_signal64", frame); return 1; } diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 8c2857cbd960..9e2246e80efd 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -76,6 +76,7 @@ static DEFINE_PER_CPU(int, cpu_state) = { 0 }; struct task_struct *secondary_current; bool has_big_cores; bool coregroup_enabled; +bool thread_group_shares_l2; DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); DEFINE_PER_CPU(cpumask_var_t, cpu_smallcore_map); @@ -99,6 +100,7 @@ enum { #define MAX_THREAD_LIST_SIZE 8 #define THREAD_GROUP_SHARE_L1 1 +#define THREAD_GROUP_SHARE_L2 2 struct thread_groups { unsigned int property; unsigned int nr_groups; @@ -106,11 +108,27 @@ struct thread_groups { unsigned int thread_list[MAX_THREAD_LIST_SIZE]; }; +/* Maximum number of properties that groups of threads within a core can share */ +#define MAX_THREAD_GROUP_PROPERTIES 2 + +struct thread_groups_list { + unsigned int nr_properties; + struct thread_groups property_tgs[MAX_THREAD_GROUP_PROPERTIES]; +}; + +static struct thread_groups_list tgl[NR_CPUS] __initdata; /* - * On big-cores system, cpu_l1_cache_map for each CPU corresponds to + * On big-cores system, thread_group_l1_cache_map for each CPU corresponds to * the set its siblings that share the L1-cache. */ -DEFINE_PER_CPU(cpumask_var_t, cpu_l1_cache_map); +DEFINE_PER_CPU(cpumask_var_t, thread_group_l1_cache_map); + +/* + * On some big-cores system, thread_group_l2_cache_map for each CPU + * corresponds to the set its siblings within the core that share the + * L2-cache. + */ +DEFINE_PER_CPU(cpumask_var_t, thread_group_l2_cache_map); /* SMP operations for this machine */ struct smp_ops_t *smp_ops; @@ -695,81 +713,100 @@ static void or_cpumasks_related(int i, int j, struct cpumask *(*srcmask)(int), /* * parse_thread_groups: Parses the "ibm,thread-groups" device tree * property for the CPU device node @dn and stores - * the parsed output in the thread_groups - * structure @tg if the ibm,thread-groups[0] - * matches @property. + * the parsed output in the thread_groups_list + * structure @tglp. * * @dn: The device node of the CPU device. - * @tg: Pointer to a thread group structure into which the parsed + * @tglp: Pointer to a thread group list structure into which the parsed * output of "ibm,thread-groups" is stored. - * @property: The property of the thread-group that the caller is - * interested in. * * ibm,thread-groups[0..N-1] array defines which group of threads in * the CPU-device node can be grouped together based on the property. * - * ibm,thread-groups[0] tells us the property based on which the + * This array can represent thread groupings for multiple properties. + * + * ibm,thread-groups[i + 0] tells us the property based on which the * threads are being grouped together. If this value is 1, it implies - * that the threads in the same group share L1, translation cache. + * that the threads in the same group share L1, translation cache. If + * the value is 2, it implies that the threads in the same group share + * the same L2 cache. * - * ibm,thread-groups[1] tells us how many such thread groups exist. + * ibm,thread-groups[i+1] tells us how many such thread groups exist for the + * property ibm,thread-groups[i] * - * ibm,thread-groups[2] tells us the number of threads in each such + * ibm,thread-groups[i+2] tells us the number of threads in each such * group. + * Suppose k = (ibm,thread-groups[i+1] * ibm,thread-groups[i+2]), then, * - * ibm,thread-groups[3..N-1] is the list of threads identified by + * ibm,thread-groups[i+3..i+k+2] (is the list of threads identified by * "ibm,ppc-interrupt-server#s" arranged as per their membership in * the grouping. * - * Example: If ibm,thread-groups = [1,2,4,5,6,7,8,9,10,11,12] it - * implies that there are 2 groups of 4 threads each, where each group - * of threads share L1, translation cache. + * Example: + * If "ibm,thread-groups" = [1,2,4,8,10,12,14,9,11,13,15,2,2,4,8,10,12,14,9,11,13,15] + * This can be decomposed up into two consecutive arrays: + * a) [1,2,4,8,10,12,14,9,11,13,15] + * b) [2,2,4,8,10,12,14,9,11,13,15] + * + * where in, + * + * a) provides information of Property "1" being shared by "2" groups, + * each with "4" threads each. The "ibm,ppc-interrupt-server#s" of + * the first group is {8,10,12,14} and the + * "ibm,ppc-interrupt-server#s" of the second group is + * {9,11,13,15}. Property "1" is indicative of the thread in the + * group sharing L1 cache, translation cache and Instruction Data + * flow. * - * The "ibm,ppc-interrupt-server#s" of the first group is {5,6,7,8} - * and the "ibm,ppc-interrupt-server#s" of the second group is {9, 10, - * 11, 12} structure + * b) provides information of Property "2" being shared by "2" groups, + * each group with "4" threads. The "ibm,ppc-interrupt-server#s" of + * the first group is {8,10,12,14} and the + * "ibm,ppc-interrupt-server#s" of the second group is + * {9,11,13,15}. Property "2" indicates that the threads in each + * group share the L2-cache. * * Returns 0 on success, -EINVAL if the property does not exist, * -ENODATA if property does not have a value, and -EOVERFLOW if the * property data isn't large enough. */ static int parse_thread_groups(struct device_node *dn, - struct thread_groups *tg, - unsigned int property) + struct thread_groups_list *tglp) { - int i; - u32 thread_group_array[3 + MAX_THREAD_LIST_SIZE]; - u32 *thread_list; + unsigned int property_idx = 0; + u32 *thread_group_array; size_t total_threads; - int ret; + int ret = 0, count; + u32 *thread_list; + int i = 0; + count = of_property_count_u32_elems(dn, "ibm,thread-groups"); + thread_group_array = kcalloc(count, sizeof(u32), GFP_KERNEL); ret = of_property_read_u32_array(dn, "ibm,thread-groups", - thread_group_array, 3); + thread_group_array, count); if (ret) - return ret; - - tg->property = thread_group_array[0]; - tg->nr_groups = thread_group_array[1]; - tg->threads_per_group = thread_group_array[2]; - if (tg->property != property || - tg->nr_groups < 1 || - tg->threads_per_group < 1) - return -ENODATA; + goto out_free; - total_threads = tg->nr_groups * tg->threads_per_group; + while (i < count && property_idx < MAX_THREAD_GROUP_PROPERTIES) { + int j; + struct thread_groups *tg = &tglp->property_tgs[property_idx++]; - ret = of_property_read_u32_array(dn, "ibm,thread-groups", - thread_group_array, - 3 + total_threads); - if (ret) - return ret; + tg->property = thread_group_array[i]; + tg->nr_groups = thread_group_array[i + 1]; + tg->threads_per_group = thread_group_array[i + 2]; + total_threads = tg->nr_groups * tg->threads_per_group; - thread_list = &thread_group_array[3]; + thread_list = &thread_group_array[i + 3]; - for (i = 0 ; i < total_threads; i++) - tg->thread_list[i] = thread_list[i]; + for (j = 0; j < total_threads; j++) + tg->thread_list[j] = thread_list[j]; + i = i + 3 + total_threads; + } - return 0; + tglp->nr_properties = property_idx; + +out_free: + kfree(thread_group_array); + return ret; } /* @@ -805,50 +842,84 @@ static int get_cpu_thread_group_start(int cpu, struct thread_groups *tg) return -1; } -static int init_cpu_l1_cache_map(int cpu) - +static struct thread_groups *__init get_thread_groups(int cpu, + int group_property, + int *err) { struct device_node *dn = of_get_cpu_node(cpu, NULL); - struct thread_groups tg = {.property = 0, - .nr_groups = 0, - .threads_per_group = 0}; + struct thread_groups_list *cpu_tgl = &tgl[cpu]; + struct thread_groups *tg = NULL; + int i; + *err = 0; + + if (!dn) { + *err = -ENODATA; + return NULL; + } + + if (!cpu_tgl->nr_properties) { + *err = parse_thread_groups(dn, cpu_tgl); + if (*err) + goto out; + } + + for (i = 0; i < cpu_tgl->nr_properties; i++) { + if (cpu_tgl->property_tgs[i].property == group_property) { + tg = &cpu_tgl->property_tgs[i]; + break; + } + } + + if (!tg) + *err = -EINVAL; +out: + of_node_put(dn); + return tg; +} + +static int __init init_thread_group_cache_map(int cpu, int cache_property) + +{ int first_thread = cpu_first_thread_sibling(cpu); int i, cpu_group_start = -1, err = 0; + struct thread_groups *tg = NULL; + cpumask_var_t *mask = NULL; - if (!dn) - return -ENODATA; + if (cache_property != THREAD_GROUP_SHARE_L1 && + cache_property != THREAD_GROUP_SHARE_L2) + return -EINVAL; - err = parse_thread_groups(dn, &tg, THREAD_GROUP_SHARE_L1); - if (err) - goto out; + tg = get_thread_groups(cpu, cache_property, &err); + if (!tg) + return err; - cpu_group_start = get_cpu_thread_group_start(cpu, &tg); + cpu_group_start = get_cpu_thread_group_start(cpu, tg); if (unlikely(cpu_group_start == -1)) { WARN_ON_ONCE(1); - err = -ENODATA; - goto out; + return -ENODATA; } - zalloc_cpumask_var_node(&per_cpu(cpu_l1_cache_map, cpu), - GFP_KERNEL, cpu_to_node(cpu)); + if (cache_property == THREAD_GROUP_SHARE_L1) + mask = &per_cpu(thread_group_l1_cache_map, cpu); + else if (cache_property == THREAD_GROUP_SHARE_L2) + mask = &per_cpu(thread_group_l2_cache_map, cpu); + + zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cpu)); for (i = first_thread; i < first_thread + threads_per_core; i++) { - int i_group_start = get_cpu_thread_group_start(i, &tg); + int i_group_start = get_cpu_thread_group_start(i, tg); if (unlikely(i_group_start == -1)) { WARN_ON_ONCE(1); - err = -ENODATA; - goto out; + return -ENODATA; } if (i_group_start == cpu_group_start) - cpumask_set_cpu(i, per_cpu(cpu_l1_cache_map, cpu)); + cpumask_set_cpu(i, *mask); } -out: - of_node_put(dn); - return err; + return 0; } static bool shared_caches; @@ -919,12 +990,12 @@ static struct sched_domain_topology_level powerpc_topology[] = { { NULL, }, }; -static int init_big_cores(void) +static int __init init_big_cores(void) { int cpu; for_each_possible_cpu(cpu) { - int err = init_cpu_l1_cache_map(cpu); + int err = init_thread_group_cache_map(cpu, THREAD_GROUP_SHARE_L1); if (err) return err; @@ -935,6 +1006,16 @@ static int init_big_cores(void) } has_big_cores = true; + + for_each_possible_cpu(cpu) { + int err = init_thread_group_cache_map(cpu, THREAD_GROUP_SHARE_L2); + + if (err) + return err; + } + + thread_group_shares_l2 = true; + pr_debug("L2 cache only shared by the threads in the small core\n"); return 0; } @@ -1249,6 +1330,28 @@ static bool update_mask_by_l2(int cpu, cpumask_var_t *mask) if (has_big_cores) submask_fn = cpu_smallcore_mask; + /* + * If the threads in a thread-group share L2 cache, then the + * L2-mask can be obtained from thread_group_l2_cache_map. + */ + if (thread_group_shares_l2) { + cpumask_set_cpu(cpu, cpu_l2_cache_mask(cpu)); + + for_each_cpu(i, per_cpu(thread_group_l2_cache_map, cpu)) { + if (cpu_online(i)) + set_cpus_related(i, cpu, cpu_l2_cache_mask); + } + + /* Verify that L1-cache siblings are a subset of L2 cache-siblings */ + if (!cpumask_equal(submask_fn(cpu), cpu_l2_cache_mask(cpu)) && + !cpumask_subset(submask_fn(cpu), cpu_l2_cache_mask(cpu))) { + pr_warn_once("CPU %d : Inconsistent L1 and L2 cache siblings\n", + cpu); + } + + return true; + } + l2_cache = cpu_to_l2cache(cpu); if (!l2_cache || !*mask) { /* Assume only core siblings share cache with this CPU */ @@ -1320,7 +1423,7 @@ static inline void add_cpu_to_smallcore_masks(int cpu) cpumask_set_cpu(cpu, cpu_smallcore_mask(cpu)); - for_each_cpu(i, per_cpu(cpu_l1_cache_map, cpu)) { + for_each_cpu(i, per_cpu(thread_group_l1_cache_map, cpu)) { if (cpu_online(i)) set_cpus_related(i, cpu, cpu_smallcore_mask); } diff --git a/arch/powerpc/kernel/syscall_64.c b/arch/powerpc/kernel/syscall_64.c index 310bcd768cd5..7c85ed04a164 100644 --- a/arch/powerpc/kernel/syscall_64.c +++ b/arch/powerpc/kernel/syscall_64.c @@ -35,7 +35,31 @@ notrace long system_call_exception(long r3, long r4, long r5, BUG_ON(!FULL_REGS(regs)); BUG_ON(regs->softe != IRQS_ENABLED); - kuap_check_amr(); +#ifdef CONFIG_PPC_PKEY + if (mmu_has_feature(MMU_FTR_PKEY)) { + unsigned long amr, iamr; + bool flush_needed = false; + /* + * When entering from userspace we mostly have the AMR/IAMR + * different from kernel default values. Hence don't compare. + */ + amr = mfspr(SPRN_AMR); + iamr = mfspr(SPRN_IAMR); + regs->amr = amr; + regs->iamr = iamr; + if (mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) { + mtspr(SPRN_AMR, AMR_KUAP_BLOCKED); + flush_needed = true; + } + if (mmu_has_feature(MMU_FTR_BOOK3S_KUEP)) { + mtspr(SPRN_IAMR, AMR_KUEP_BLOCKED); + flush_needed = true; + } + if (flush_needed) + isync(); + } else +#endif + kuap_check_amr(); account_cpu_user_entry(); @@ -245,6 +269,12 @@ again: account_cpu_user_exit(); +#ifdef CONFIG_PPC_BOOK3S /* BOOK3E not yet using this */ + /* + * We do this at the end so that we do context switch with KERNEL AMR + */ + kuap_user_restore(regs); +#endif return ret; } @@ -330,6 +360,10 @@ again: account_cpu_user_exit(); + /* + * We do this at the end so that we do context switch with KERNEL AMR + */ + kuap_user_restore(regs); return ret; } @@ -400,7 +434,7 @@ again: * which would cause Read-After-Write stalls. Hence, we take the AMR * value from the check above. */ - kuap_restore_amr(regs, amr); + kuap_kernel_restore(regs, amr); return ret; } diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl index 1275daec7fec..f744eb5cba88 100644 --- a/arch/powerpc/kernel/syscalls/syscall.tbl +++ b/arch/powerpc/kernel/syscalls/syscall.tbl @@ -530,3 +530,4 @@ 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 440 common process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index cf3f8db7e0e3..67feb3524460 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -82,6 +82,7 @@ static struct clocksource clocksource_timebase = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, .mask = CLOCKSOURCE_MASK(64), .read = timebase_read, + .vdso_clock_mode = VDSO_CLOCKMODE_ARCHTIMER, }; #define DECREMENTER_DEFAULT_MAX 0x7FFFFFFF @@ -576,14 +577,11 @@ void timer_interrupt(struct pt_regs *regs) struct pt_regs *old_regs; u64 now; - /* Some implementations of hotplug will get timer interrupts while - * offline, just ignore these and we also need to set - * decrementers_next_tb as MAX to make sure __check_irq_replay - * don't replay timer interrupt when return, otherwise we'll trap - * here infinitely :( + /* + * Some implementations of hotplug will get timer interrupts while + * offline, just ignore these. */ if (unlikely(!cpu_online(smp_processor_id()))) { - *next_tb = ~(u64)0; set_dec(decrementer_max); return; } @@ -855,95 +853,6 @@ static notrace u64 timebase_read(struct clocksource *cs) return (u64)get_tb(); } - -void update_vsyscall(struct timekeeper *tk) -{ - struct timespec64 xt; - struct clocksource *clock = tk->tkr_mono.clock; - u32 mult = tk->tkr_mono.mult; - u32 shift = tk->tkr_mono.shift; - u64 cycle_last = tk->tkr_mono.cycle_last; - u64 new_tb_to_xs, new_stamp_xsec; - u64 frac_sec; - - if (clock != &clocksource_timebase) - return; - - xt.tv_sec = tk->xtime_sec; - xt.tv_nsec = (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift); - - /* Make userspace gettimeofday spin until we're done. */ - ++vdso_data->tb_update_count; - smp_mb(); - - /* - * This computes ((2^20 / 1e9) * mult) >> shift as a - * 0.64 fixed-point fraction. - * The computation in the else clause below won't overflow - * (as long as the timebase frequency is >= 1.049 MHz) - * but loses precision because we lose the low bits of the constant - * in the shift. Note that 19342813113834067 ~= 2^(20+64) / 1e9. - * For a shift of 24 the error is about 0.5e-9, or about 0.5ns - * over a second. (Shift values are usually 22, 23 or 24.) - * For high frequency clocks such as the 512MHz timebase clock - * on POWER[6789], the mult value is small (e.g. 32768000) - * and so we can shift the constant by 16 initially - * (295147905179 ~= 2^(20+64-16) / 1e9) and then do the - * remaining shifts after the multiplication, which gives a - * more accurate result (e.g. with mult = 32768000, shift = 24, - * the error is only about 1.2e-12, or 0.7ns over 10 minutes). - */ - if (mult <= 62500000 && clock->shift >= 16) - new_tb_to_xs = ((u64) mult * 295147905179ULL) >> (clock->shift - 16); - else - new_tb_to_xs = (u64) mult * (19342813113834067ULL >> clock->shift); - - /* - * Compute the fractional second in units of 2^-32 seconds. - * The fractional second is tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift - * in nanoseconds, so multiplying that by 2^32 / 1e9 gives - * it in units of 2^-32 seconds. - * We assume shift <= 32 because clocks_calc_mult_shift() - * generates shift values in the range 0 - 32. - */ - frac_sec = tk->tkr_mono.xtime_nsec << (32 - shift); - do_div(frac_sec, NSEC_PER_SEC); - - /* - * Work out new stamp_xsec value for any legacy users of systemcfg. - * stamp_xsec is in units of 2^-20 seconds. - */ - new_stamp_xsec = frac_sec >> 12; - new_stamp_xsec += tk->xtime_sec * XSEC_PER_SEC; - - /* - * tb_update_count is used to allow the userspace gettimeofday code - * to assure itself that it sees a consistent view of the tb_to_xs and - * stamp_xsec variables. It reads the tb_update_count, then reads - * tb_to_xs and stamp_xsec and then reads tb_update_count again. If - * the two values of tb_update_count match and are even then the - * tb_to_xs and stamp_xsec values are consistent. If not, then it - * loops back and reads them again until this criteria is met. - */ - vdso_data->tb_orig_stamp = cycle_last; - vdso_data->stamp_xsec = new_stamp_xsec; - vdso_data->tb_to_xs = new_tb_to_xs; - vdso_data->wtom_clock_sec = tk->wall_to_monotonic.tv_sec; - vdso_data->wtom_clock_nsec = tk->wall_to_monotonic.tv_nsec; - vdso_data->stamp_xtime_sec = xt.tv_sec; - vdso_data->stamp_xtime_nsec = xt.tv_nsec; - vdso_data->stamp_sec_fraction = frac_sec; - vdso_data->hrtimer_res = hrtimer_resolution; - smp_wmb(); - ++(vdso_data->tb_update_count); -} - -void update_vsyscall_tz(void) -{ - vdso_data->tz_minuteswest = sys_tz.tz_minuteswest; - vdso_data->tz_dsttime = sys_tz.tz_dsttime; -} - static void __init clocksource_init(void) { struct clocksource *clock = &clocksource_timebase; @@ -1103,7 +1012,6 @@ void __init time_init(void) sys_tz.tz_dsttime = 0; } - vdso_data->tb_update_count = 0; vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; /* initialise and enable the large decrementer (if we have one) */ diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 5006dcbe1d9f..3ec7b443fe6b 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -347,12 +347,6 @@ static bool exception_common(int signr, struct pt_regs *regs, int code, current->thread.trap_nr = code; - /* - * Save all the pkey registers AMR/IAMR/UAMOR. Eg: Core dumps need - * to capture the content, if the task gets killed. - */ - thread_pkey_regs_save(¤t->thread); - return true; } @@ -757,31 +751,6 @@ int machine_check_generic(struct pt_regs *regs) { return 0; } -#elif defined(CONFIG_E200) -int machine_check_e200(struct pt_regs *regs) -{ - unsigned long reason = mfspr(SPRN_MCSR); - - printk("Machine check in kernel mode.\n"); - printk("Caused by (from MCSR=%lx): ", reason); - - if (reason & MCSR_MCP) - pr_cont("Machine Check Signal\n"); - if (reason & MCSR_CP_PERR) - pr_cont("Cache Push Parity Error\n"); - if (reason & MCSR_CPERR) - pr_cont("Cache Parity Error\n"); - if (reason & MCSR_EXCP_ERR) - pr_cont("ISI, ITLB, or Bus Error on first instruction fetch for an exception handler\n"); - if (reason & MCSR_BUS_IRERR) - pr_cont("Bus - Read Bus Error on instruction fetch\n"); - if (reason & MCSR_BUS_DRERR) - pr_cont("Bus - Read Bus Error on data load\n"); - if (reason & MCSR_BUS_WRERR) - pr_cont("Bus - Write Bus Error on buffered store or cache line push\n"); - - return 0; -} #elif defined(CONFIG_PPC32) int machine_check_generic(struct pt_regs *regs) { @@ -1190,7 +1159,9 @@ static void parse_fpe(struct pt_regs *regs) flush_fp_to_thread(current); +#ifdef CONFIG_PPC_FPU_REGS code = __parse_fpscr(current->thread.fp_state.fpscr); +#endif _exception(SIGFPE, regs, code, regs->nip); } diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 8dad44262e75..e839a906fdf2 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -17,7 +17,10 @@ #include <linux/elf.h> #include <linux/security.h> #include <linux/memblock.h> +#include <linux/syscalls.h> +#include <vdso/datapage.h> +#include <asm/syscall.h> #include <asm/processor.h> #include <asm/mmu.h> #include <asm/mmu_context.h> @@ -30,39 +33,11 @@ #include <asm/vdso_datapage.h> #include <asm/setup.h> -#undef DEBUG - -#ifdef DEBUG -#define DBG(fmt...) printk(fmt) -#else -#define DBG(fmt...) -#endif - -/* Max supported size for symbol names */ -#define MAX_SYMNAME 64 - /* The alignment of the vDSO */ #define VDSO_ALIGNMENT (1 << 16) -static unsigned int vdso32_pages; -static void *vdso32_kbase; -static struct page **vdso32_pagelist; -unsigned long vdso32_sigtramp; -unsigned long vdso32_rt_sigtramp; - -#ifdef CONFIG_VDSO32 extern char vdso32_start, vdso32_end; -#endif - -#ifdef CONFIG_PPC64 extern char vdso64_start, vdso64_end; -static void *vdso64_kbase = &vdso64_start; -static unsigned int vdso64_pages; -static struct page **vdso64_pagelist; -unsigned long vdso64_rt_sigtramp; -#endif /* CONFIG_PPC64 */ - -static int vdso_ready; /* * The vdso data page (aka. systemcfg for old ppc64 fans) is here. @@ -70,77 +45,63 @@ static int vdso_ready; * with it, it will become dynamically allocated */ static union { - struct vdso_data data; + struct vdso_arch_data data; u8 page[PAGE_SIZE]; } vdso_data_store __page_aligned_data; -struct vdso_data *vdso_data = &vdso_data_store.data; +struct vdso_arch_data *vdso_data = &vdso_data_store.data; -/* Format of the patch table */ -struct vdso_patch_def +static int vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *new_vma, + unsigned long text_size) { - unsigned long ftr_mask, ftr_value; - const char *gen_name; - const char *fix_name; -}; + unsigned long new_size = new_vma->vm_end - new_vma->vm_start; -/* Table of functions to patch based on the CPU type/revision - * - * Currently, we only change sync_dicache to do nothing on processors - * with a coherent icache - */ -static struct vdso_patch_def vdso_patches[] = { - { - CPU_FTR_COHERENT_ICACHE, CPU_FTR_COHERENT_ICACHE, - "__kernel_sync_dicache", "__kernel_sync_dicache_p5" - }, -}; + if (new_size != text_size + PAGE_SIZE) + return -EINVAL; -/* - * Some infos carried around for each of them during parsing at - * boot time. - */ -struct lib32_elfinfo + current->mm->context.vdso = (void __user *)new_vma->vm_start + PAGE_SIZE; + + return 0; +} + +static int vdso32_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *new_vma) { - Elf32_Ehdr *hdr; /* ptr to ELF */ - Elf32_Sym *dynsym; /* ptr to .dynsym section */ - unsigned long dynsymsize; /* size of .dynsym section */ - char *dynstr; /* ptr to .dynstr section */ - unsigned long text; /* offset of .text section in .so */ -}; + return vdso_mremap(sm, new_vma, &vdso32_end - &vdso32_start); +} -struct lib64_elfinfo +static int vdso64_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *new_vma) { - Elf64_Ehdr *hdr; - Elf64_Sym *dynsym; - unsigned long dynsymsize; - char *dynstr; - unsigned long text; + return vdso_mremap(sm, new_vma, &vdso64_end - &vdso64_start); +} + +static struct vm_special_mapping vdso32_spec __ro_after_init = { + .name = "[vdso]", + .mremap = vdso32_mremap, }; +static struct vm_special_mapping vdso64_spec __ro_after_init = { + .name = "[vdso]", + .mremap = vdso64_mremap, +}; /* * This is called from binfmt_elf, we create the special vma for the * vDSO and insert it into the mm struct tree */ -int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) +static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) { struct mm_struct *mm = current->mm; - struct page **vdso_pagelist; - unsigned long vdso_pages; + struct vm_special_mapping *vdso_spec; + struct vm_area_struct *vma; + unsigned long vdso_size; unsigned long vdso_base; - int rc; - - if (!vdso_ready) - return 0; -#ifdef CONFIG_PPC64 if (is_32bit_task()) { - vdso_pagelist = vdso32_pagelist; - vdso_pages = vdso32_pages; + vdso_spec = &vdso32_spec; + vdso_size = &vdso32_end - &vdso32_start; vdso_base = VDSO32_MBASE; } else { - vdso_pagelist = vdso64_pagelist; - vdso_pages = vdso64_pages; + vdso_spec = &vdso64_spec; + vdso_size = &vdso64_end - &vdso64_start; /* * On 64bit we don't have a preferred map address. This * allows get_unmapped_area to find an area near other mmaps @@ -148,21 +109,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) */ vdso_base = 0; } -#else - vdso_pagelist = vdso32_pagelist; - vdso_pages = vdso32_pages; - vdso_base = VDSO32_MBASE; -#endif - current->mm->context.vdso_base = 0; - - /* vDSO has a problem and was disabled, just don't "enable" it for the - * process - */ - if (vdso_pages == 0) - return 0; /* Add a page to the vdso size for the data page */ - vdso_pages ++; + vdso_size += PAGE_SIZE; /* * pick a base address for the vDSO in process space. We try to put it @@ -170,16 +119,11 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) * and end up putting it elsewhere. * Add enough to the size so that the result can be aligned. */ - if (mmap_write_lock_killable(mm)) - return -EINTR; vdso_base = get_unmapped_area(NULL, vdso_base, - (vdso_pages << PAGE_SHIFT) + - ((VDSO_ALIGNMENT - 1) & PAGE_MASK), + vdso_size + ((VDSO_ALIGNMENT - 1) & PAGE_MASK), 0, 0); - if (IS_ERR_VALUE(vdso_base)) { - rc = vdso_base; - goto fail_mmapsem; - } + if (IS_ERR_VALUE(vdso_base)) + return vdso_base; /* Add required alignment. */ vdso_base = ALIGN(vdso_base, VDSO_ALIGNMENT); @@ -187,9 +131,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) /* * Put vDSO base into mm struct. We need to do this before calling * install_special_mapping or the perf counter mmap tracking code - * will fail to recognise it as a vDSO (since arch_vma_name fails). + * will fail to recognise it as a vDSO. */ - current->mm->context.vdso_base = vdso_base; + mm->context.vdso = (void __user *)vdso_base + PAGE_SIZE; /* * our vma flags don't have VM_WRITE so by default, the process isn't @@ -201,434 +145,54 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) * It's fine to use that for setting breakpoints in the vDSO code * pages though. */ - rc = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT, - VM_READ|VM_EXEC| - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, - vdso_pagelist); - if (rc) { - current->mm->context.vdso_base = 0; - goto fail_mmapsem; - } - - mmap_write_unlock(mm); - return 0; - - fail_mmapsem: - mmap_write_unlock(mm); - return rc; -} - -const char *arch_vma_name(struct vm_area_struct *vma) -{ - if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso_base) - return "[vdso]"; - return NULL; -} - - - -#ifdef CONFIG_VDSO32 -static void * __init find_section32(Elf32_Ehdr *ehdr, const char *secname, - unsigned long *size) -{ - Elf32_Shdr *sechdrs; - unsigned int i; - char *secnames; - - /* Grab section headers and strings so we can tell who is who */ - sechdrs = (void *)ehdr + ehdr->e_shoff; - secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset; - - /* Find the section they want */ - for (i = 1; i < ehdr->e_shnum; i++) { - if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) { - if (size) - *size = sechdrs[i].sh_size; - return (void *)ehdr + sechdrs[i].sh_offset; - } - } - *size = 0; - return NULL; -} - -static Elf32_Sym * __init find_symbol32(struct lib32_elfinfo *lib, - const char *symname) -{ - unsigned int i; - char name[MAX_SYMNAME], *c; - - for (i = 0; i < (lib->dynsymsize / sizeof(Elf32_Sym)); i++) { - if (lib->dynsym[i].st_name == 0) - continue; - strlcpy(name, lib->dynstr + lib->dynsym[i].st_name, - MAX_SYMNAME); - c = strchr(name, '@'); - if (c) - *c = 0; - if (strcmp(symname, name) == 0) - return &lib->dynsym[i]; - } - return NULL; -} - -/* Note that we assume the section is .text and the symbol is relative to - * the library base - */ -static unsigned long __init find_function32(struct lib32_elfinfo *lib, - const char *symname) -{ - Elf32_Sym *sym = find_symbol32(lib, symname); - - if (sym == NULL) { - printk(KERN_WARNING "vDSO32: function %s not found !\n", - symname); - return 0; - } - return sym->st_value - VDSO32_LBASE; -} - -static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64, - const char *orig, const char *fix) -{ - Elf32_Sym *sym32_gen, *sym32_fix; - - sym32_gen = find_symbol32(v32, orig); - if (sym32_gen == NULL) { - printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", orig); - return -1; - } - if (fix == NULL) { - sym32_gen->st_name = 0; - return 0; - } - sym32_fix = find_symbol32(v32, fix); - if (sym32_fix == NULL) { - printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", fix); - return -1; - } - sym32_gen->st_value = sym32_fix->st_value; - sym32_gen->st_size = sym32_fix->st_size; - sym32_gen->st_info = sym32_fix->st_info; - sym32_gen->st_other = sym32_fix->st_other; - sym32_gen->st_shndx = sym32_fix->st_shndx; - - return 0; -} -#else /* !CONFIG_VDSO32 */ -static unsigned long __init find_function32(struct lib32_elfinfo *lib, - const char *symname) -{ - return 0; -} - -static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64, - const char *orig, const char *fix) -{ - return 0; -} -#endif /* CONFIG_VDSO32 */ - - -#ifdef CONFIG_PPC64 - -static void * __init find_section64(Elf64_Ehdr *ehdr, const char *secname, - unsigned long *size) -{ - Elf64_Shdr *sechdrs; - unsigned int i; - char *secnames; - - /* Grab section headers and strings so we can tell who is who */ - sechdrs = (void *)ehdr + ehdr->e_shoff; - secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset; - - /* Find the section they want */ - for (i = 1; i < ehdr->e_shnum; i++) { - if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) { - if (size) - *size = sechdrs[i].sh_size; - return (void *)ehdr + sechdrs[i].sh_offset; - } - } - if (size) - *size = 0; - return NULL; -} - -static Elf64_Sym * __init find_symbol64(struct lib64_elfinfo *lib, - const char *symname) -{ - unsigned int i; - char name[MAX_SYMNAME], *c; - - for (i = 0; i < (lib->dynsymsize / sizeof(Elf64_Sym)); i++) { - if (lib->dynsym[i].st_name == 0) - continue; - strlcpy(name, lib->dynstr + lib->dynsym[i].st_name, - MAX_SYMNAME); - c = strchr(name, '@'); - if (c) - *c = 0; - if (strcmp(symname, name) == 0) - return &lib->dynsym[i]; - } - return NULL; -} - -/* Note that we assume the section is .text and the symbol is relative to - * the library base - */ -static unsigned long __init find_function64(struct lib64_elfinfo *lib, - const char *symname) -{ - Elf64_Sym *sym = find_symbol64(lib, symname); - - if (sym == NULL) { - printk(KERN_WARNING "vDSO64: function %s not found !\n", - symname); - return 0; - } - return sym->st_value - VDSO64_LBASE; -} - -static int __init vdso_do_func_patch64(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64, - const char *orig, const char *fix) -{ - Elf64_Sym *sym64_gen, *sym64_fix; - - sym64_gen = find_symbol64(v64, orig); - if (sym64_gen == NULL) { - printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", orig); - return -1; - } - if (fix == NULL) { - sym64_gen->st_name = 0; - return 0; - } - sym64_fix = find_symbol64(v64, fix); - if (sym64_fix == NULL) { - printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", fix); - return -1; - } - sym64_gen->st_value = sym64_fix->st_value; - sym64_gen->st_size = sym64_fix->st_size; - sym64_gen->st_info = sym64_fix->st_info; - sym64_gen->st_other = sym64_fix->st_other; - sym64_gen->st_shndx = sym64_fix->st_shndx; - - return 0; + vma = _install_special_mapping(mm, vdso_base, vdso_size, + VM_READ | VM_EXEC | VM_MAYREAD | + VM_MAYWRITE | VM_MAYEXEC, vdso_spec); + return PTR_ERR_OR_ZERO(vma); } -#endif /* CONFIG_PPC64 */ - - -static __init int vdso_do_find_sections(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64) -{ - void *sect; - - /* - * Locate symbol tables & text section - */ - -#ifdef CONFIG_VDSO32 - v32->dynsym = find_section32(v32->hdr, ".dynsym", &v32->dynsymsize); - v32->dynstr = find_section32(v32->hdr, ".dynstr", NULL); - if (v32->dynsym == NULL || v32->dynstr == NULL) { - printk(KERN_ERR "vDSO32: required symbol section not found\n"); - return -1; - } - sect = find_section32(v32->hdr, ".text", NULL); - if (sect == NULL) { - printk(KERN_ERR "vDSO32: the .text section was not found\n"); - return -1; - } - v32->text = sect - vdso32_kbase; -#endif - -#ifdef CONFIG_PPC64 - v64->dynsym = find_section64(v64->hdr, ".dynsym", &v64->dynsymsize); - v64->dynstr = find_section64(v64->hdr, ".dynstr", NULL); - if (v64->dynsym == NULL || v64->dynstr == NULL) { - printk(KERN_ERR "vDSO64: required symbol section not found\n"); - return -1; - } - sect = find_section64(v64->hdr, ".text", NULL); - if (sect == NULL) { - printk(KERN_ERR "vDSO64: the .text section was not found\n"); - return -1; - } - v64->text = sect - vdso64_kbase; -#endif /* CONFIG_PPC64 */ - - return 0; -} - -static __init void vdso_setup_trampolines(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64) +int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) { - /* - * Find signal trampolines - */ - -#ifdef CONFIG_PPC64 - vdso64_rt_sigtramp = find_function64(v64, "__kernel_sigtramp_rt64"); -#endif - vdso32_sigtramp = find_function32(v32, "__kernel_sigtramp32"); - vdso32_rt_sigtramp = find_function32(v32, "__kernel_sigtramp_rt32"); -} + struct mm_struct *mm = current->mm; + int rc; -static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64) -{ -#ifdef CONFIG_VDSO32 - Elf32_Sym *sym32; -#endif -#ifdef CONFIG_PPC64 - Elf64_Sym *sym64; + mm->context.vdso = NULL; - sym64 = find_symbol64(v64, "__kernel_datapage_offset"); - if (sym64 == NULL) { - printk(KERN_ERR "vDSO64: Can't find symbol " - "__kernel_datapage_offset !\n"); - return -1; - } - *((int *)(vdso64_kbase + sym64->st_value - VDSO64_LBASE)) = - (vdso64_pages << PAGE_SHIFT) - - (sym64->st_value - VDSO64_LBASE); -#endif /* CONFIG_PPC64 */ + if (mmap_write_lock_killable(mm)) + return -EINTR; -#ifdef CONFIG_VDSO32 - sym32 = find_symbol32(v32, "__kernel_datapage_offset"); - if (sym32 == NULL) { - printk(KERN_ERR "vDSO32: Can't find symbol " - "__kernel_datapage_offset !\n"); - return -1; - } - *((int *)(vdso32_kbase + (sym32->st_value - VDSO32_LBASE))) = - (vdso32_pages << PAGE_SHIFT) - - (sym32->st_value - VDSO32_LBASE); -#endif + rc = __arch_setup_additional_pages(bprm, uses_interp); + if (rc) + mm->context.vdso = NULL; - return 0; + mmap_write_unlock(mm); + return rc; } +#define VDSO_DO_FIXUPS(type, value, bits, sec) do { \ + void *__start = (void *)VDSO##bits##_SYMBOL(&vdso##bits##_start, sec##_start); \ + void *__end = (void *)VDSO##bits##_SYMBOL(&vdso##bits##_start, sec##_end); \ + \ + do_##type##_fixups((value), __start, __end); \ +} while (0) -static __init int vdso_fixup_features(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64) +static void __init vdso_fixup_features(void) { - unsigned long size; - void *start; - #ifdef CONFIG_PPC64 - start = find_section64(v64->hdr, "__ftr_fixup", &size); - if (start) - do_feature_fixups(cur_cpu_spec->cpu_features, - start, start + size); - - start = find_section64(v64->hdr, "__mmu_ftr_fixup", &size); - if (start) - do_feature_fixups(cur_cpu_spec->mmu_features, - start, start + size); - - start = find_section64(v64->hdr, "__fw_ftr_fixup", &size); - if (start) - do_feature_fixups(powerpc_firmware_features, - start, start + size); - - start = find_section64(v64->hdr, "__lwsync_fixup", &size); - if (start) - do_lwsync_fixups(cur_cpu_spec->cpu_features, - start, start + size); + VDSO_DO_FIXUPS(feature, cur_cpu_spec->cpu_features, 64, ftr_fixup); + VDSO_DO_FIXUPS(feature, cur_cpu_spec->mmu_features, 64, mmu_ftr_fixup); + VDSO_DO_FIXUPS(feature, powerpc_firmware_features, 64, fw_ftr_fixup); + VDSO_DO_FIXUPS(lwsync, cur_cpu_spec->cpu_features, 64, lwsync_fixup); #endif /* CONFIG_PPC64 */ #ifdef CONFIG_VDSO32 - start = find_section32(v32->hdr, "__ftr_fixup", &size); - if (start) - do_feature_fixups(cur_cpu_spec->cpu_features, - start, start + size); - - start = find_section32(v32->hdr, "__mmu_ftr_fixup", &size); - if (start) - do_feature_fixups(cur_cpu_spec->mmu_features, - start, start + size); - + VDSO_DO_FIXUPS(feature, cur_cpu_spec->cpu_features, 32, ftr_fixup); + VDSO_DO_FIXUPS(feature, cur_cpu_spec->mmu_features, 32, mmu_ftr_fixup); #ifdef CONFIG_PPC64 - start = find_section32(v32->hdr, "__fw_ftr_fixup", &size); - if (start) - do_feature_fixups(powerpc_firmware_features, - start, start + size); + VDSO_DO_FIXUPS(feature, powerpc_firmware_features, 32, fw_ftr_fixup); #endif /* CONFIG_PPC64 */ - - start = find_section32(v32->hdr, "__lwsync_fixup", &size); - if (start) - do_lwsync_fixups(cur_cpu_spec->cpu_features, - start, start + size); + VDSO_DO_FIXUPS(lwsync, cur_cpu_spec->cpu_features, 32, lwsync_fixup); #endif - - return 0; -} - -static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(vdso_patches); i++) { - struct vdso_patch_def *patch = &vdso_patches[i]; - int match = (cur_cpu_spec->cpu_features & patch->ftr_mask) - == patch->ftr_value; - if (!match) - continue; - - DBG("replacing %s with %s...\n", patch->gen_name, - patch->fix_name ? "NONE" : patch->fix_name); - - /* - * Patch the 32 bits and 64 bits symbols. Note that we do not - * patch the "." symbol on 64 bits. - * It would be easy to do, but doesn't seem to be necessary, - * patching the OPD symbol is enough. - */ - vdso_do_func_patch32(v32, v64, patch->gen_name, - patch->fix_name); -#ifdef CONFIG_PPC64 - vdso_do_func_patch64(v32, v64, patch->gen_name, - patch->fix_name); -#endif /* CONFIG_PPC64 */ - } - - return 0; -} - - -static __init int vdso_setup(void) -{ - struct lib32_elfinfo v32; - struct lib64_elfinfo v64; - - v32.hdr = vdso32_kbase; -#ifdef CONFIG_PPC64 - v64.hdr = vdso64_kbase; -#endif - if (vdso_do_find_sections(&v32, &v64)) - return -1; - - if (vdso_fixup_datapage(&v32, &v64)) - return -1; - - if (vdso_fixup_features(&v32, &v64)) - return -1; - - if (vdso_fixup_alt_funcs(&v32, &v64)) - return -1; - - vdso_setup_trampolines(&v32, &v64); - - return 0; } /* @@ -638,27 +202,13 @@ static __init int vdso_setup(void) static void __init vdso_setup_syscall_map(void) { unsigned int i; - extern unsigned long *sys_call_table; -#ifdef CONFIG_PPC64 - extern unsigned long *compat_sys_call_table; -#endif - extern unsigned long sys_ni_syscall; - for (i = 0; i < NR_syscalls; i++) { -#ifdef CONFIG_PPC64 - if (sys_call_table[i] != sys_ni_syscall) - vdso_data->syscall_map_64[i >> 5] |= - 0x80000000UL >> (i & 0x1f); + if (sys_call_table[i] != (unsigned long)&sys_ni_syscall) + vdso_data->syscall_map[i >> 5] |= 0x80000000UL >> (i & 0x1f); if (IS_ENABLED(CONFIG_COMPAT) && - compat_sys_call_table[i] != sys_ni_syscall) - vdso_data->syscall_map_32[i >> 5] |= - 0x80000000UL >> (i & 0x1f); -#else /* CONFIG_PPC64 */ - if (sys_call_table[i] != sys_ni_syscall) - vdso_data->syscall_map_32[i >> 5] |= - 0x80000000UL >> (i & 0x1f); -#endif /* CONFIG_PPC64 */ + compat_sys_call_table[i] != (unsigned long)&sys_ni_syscall) + vdso_data->compat_syscall_map[i >> 5] |= 0x80000000UL >> (i & 0x1f); } } @@ -689,10 +239,26 @@ int vdso_getcpu_init(void) early_initcall(vdso_getcpu_init); #endif -static int __init vdso_init(void) +static struct page ** __init vdso_setup_pages(void *start, void *end) { int i; + struct page **pagelist; + int pages = (end - start) >> PAGE_SHIFT; + + pagelist = kcalloc(pages + 1, sizeof(struct page *), GFP_KERNEL); + if (!pagelist) + panic("%s: Cannot allocate page list for VDSO", __func__); + + pagelist[0] = virt_to_page(vdso_data); + + for (i = 0; i < pages; i++) + pagelist[i + 1] = virt_to_page(start + i * PAGE_SIZE); + + return pagelist; +} +static int __init vdso_init(void) +{ #ifdef CONFIG_PPC64 /* * Fill up the "systemcfg" stuff for backward compatibility @@ -717,75 +283,19 @@ static int __init vdso_init(void) vdso_data->icache_block_size = ppc64_caches.l1i.block_size; vdso_data->dcache_log_block_size = ppc64_caches.l1d.log_block_size; vdso_data->icache_log_block_size = ppc64_caches.l1i.log_block_size; - - /* - * Calculate the size of the 64 bits vDSO - */ - vdso64_pages = (&vdso64_end - &vdso64_start) >> PAGE_SHIFT; - DBG("vdso64_kbase: %p, 0x%x pages\n", vdso64_kbase, vdso64_pages); #endif /* CONFIG_PPC64 */ - -#ifdef CONFIG_VDSO32 - vdso32_kbase = &vdso32_start; - - /* - * Calculate the size of the 32 bits vDSO - */ - vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT; - DBG("vdso32_kbase: %p, 0x%x pages\n", vdso32_kbase, vdso32_pages); -#endif - - - /* - * Setup the syscall map in the vDOS - */ vdso_setup_syscall_map(); - /* - * Initialize the vDSO images in memory, that is do necessary - * fixups of vDSO symbols, locate trampolines, etc... - */ - if (vdso_setup()) { - printk(KERN_ERR "vDSO setup failure, not enabled !\n"); - vdso32_pages = 0; -#ifdef CONFIG_PPC64 - vdso64_pages = 0; -#endif - return 0; - } + vdso_fixup_features(); -#ifdef CONFIG_VDSO32 - /* Make sure pages are in the correct state */ - vdso32_pagelist = kcalloc(vdso32_pages + 2, sizeof(struct page *), - GFP_KERNEL); - BUG_ON(vdso32_pagelist == NULL); - for (i = 0; i < vdso32_pages; i++) { - struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE); - get_page(pg); - vdso32_pagelist[i] = pg; - } - vdso32_pagelist[i++] = virt_to_page(vdso_data); - vdso32_pagelist[i] = NULL; -#endif - -#ifdef CONFIG_PPC64 - vdso64_pagelist = kcalloc(vdso64_pages + 2, sizeof(struct page *), - GFP_KERNEL); - BUG_ON(vdso64_pagelist == NULL); - for (i = 0; i < vdso64_pages; i++) { - struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE); - get_page(pg); - vdso64_pagelist[i] = pg; - } - vdso64_pagelist[i++] = virt_to_page(vdso_data); - vdso64_pagelist[i] = NULL; -#endif /* CONFIG_PPC64 */ + if (IS_ENABLED(CONFIG_VDSO32)) + vdso32_spec.pages = vdso_setup_pages(&vdso32_start, &vdso32_end); - get_page(virt_to_page(vdso_data)); + if (IS_ENABLED(CONFIG_PPC64)) + vdso64_spec.pages = vdso_setup_pages(&vdso64_start, &vdso64_end); smp_wmb(); - vdso_ready = 1; return 0; } diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile index 73eada6bc8cd..9cb6f524854b 100644 --- a/arch/powerpc/kernel/vdso32/Makefile +++ b/arch/powerpc/kernel/vdso32/Makefile @@ -2,8 +2,20 @@ # List of files in the vdso, has to be asm only for now +ARCH_REL_TYPE_ABS := R_PPC_JUMP_SLOT|R_PPC_GLOB_DAT|R_PPC_ADDR32|R_PPC_ADDR24|R_PPC_ADDR16|R_PPC_ADDR16_LO|R_PPC_ADDR16_HI|R_PPC_ADDR16_HA|R_PPC_ADDR14|R_PPC_ADDR14_BRTAKEN|R_PPC_ADDR14_BRNTAKEN|R_PPC_REL24 +include $(srctree)/lib/vdso/Makefile + obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o getcpu.o +ifneq ($(c-gettimeofday-y),) + CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y) + CFLAGS_vgettimeofday.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) + CFLAGS_vgettimeofday.o += $(call cc-option, -fno-stack-protector) + CFLAGS_vgettimeofday.o += -DDISABLE_BRANCH_PROFILING + CFLAGS_vgettimeofday.o += -ffreestanding -fasynchronous-unwind-tables + CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) +endif + # Build rules ifdef CROSS32_COMPILE @@ -15,14 +27,16 @@ endif CC32FLAGS := ifdef CONFIG_PPC64 CC32FLAGS += -m32 +KBUILD_CFLAGS := $(filter-out -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc,$(KBUILD_CFLAGS)) endif -targets := $(obj-vdso32) vdso32.so vdso32.so.dbg +targets := $(obj-vdso32) vdso32.so.dbg obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) GCOV_PROFILE := n KCOV_INSTRUMENT := n UBSAN_SANITIZE := n +KASAN_SANITIZE := n ccflags-y := -shared -fno-common -fno-builtin -nostdlib \ -Wl,-soname=linux-vdso32.so.1 -Wl,--hash-style=both @@ -33,33 +47,30 @@ targets += vdso32.lds CPPFLAGS_vdso32.lds += -P -C -Upowerpc # Force dependency (incbin is bad) -$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so +$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so.dbg # link rule for the .so file, .lds has to be first -$(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32) FORCE - $(call if_changed,vdso32ld) - -# strip rule for the .so file -$(obj)/%.so: OBJCOPYFLAGS := -S -$(obj)/%.so: $(obj)/%.so.dbg FORCE - $(call if_changed,objcopy) +$(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32) $(obj)/vgettimeofday.o FORCE + $(call if_changed,vdso32ld_and_check) # assembly rules for the .S files $(obj-vdso32): %.o: %.S FORCE $(call if_changed_dep,vdso32as) +$(obj)/vgettimeofday.o: %.o: %.c FORCE + $(call if_changed_dep,vdso32cc) + +# Generate VDSO offsets using helper script +gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh +quiet_cmd_vdsosym = VDSOSYM $@ + cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ + +include/generated/vdso32-offsets.h: $(obj)/vdso32.so.dbg FORCE + $(call if_changed,vdsosym) # actual build commands -quiet_cmd_vdso32ld = VDSO32L $@ - cmd_vdso32ld = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) +quiet_cmd_vdso32ld_and_check = VDSO32L $@ + cmd_vdso32ld_and_check = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) ; $(cmd_vdso_check) quiet_cmd_vdso32as = VDSO32A $@ cmd_vdso32as = $(VDSOCC) $(a_flags) $(CC32FLAGS) -c -o $@ $< - -# install commands for the unstripped file -quiet_cmd_vdso_install = INSTALL $@ - cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ - -vdso32.so: $(obj)/vdso32.so.dbg - @mkdir -p $(MODLIB)/vdso - $(call cmd,vdso_install) - -vdso_install: vdso32.so +quiet_cmd_vdso32cc = VDSO32C $@ + cmd_vdso32cc = $(VDSOCC) $(c_flags) $(CC32FLAGS) -c -o $@ $< diff --git a/arch/powerpc/kernel/vdso32/cacheflush.S b/arch/powerpc/kernel/vdso32/cacheflush.S index 3440ddf21c8b..f340e82d1981 100644 --- a/arch/powerpc/kernel/vdso32/cacheflush.S +++ b/arch/powerpc/kernel/vdso32/cacheflush.S @@ -24,11 +24,15 @@ */ V_FUNCTION_BEGIN(__kernel_sync_dicache) .cfi_startproc +BEGIN_FTR_SECTION + b 3f +END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) #ifdef CONFIG_PPC64 mflr r12 .cfi_register lr,r12 - get_datapage r10, r0 + get_datapage r10 mtlr r12 + .cfi_restore lr #endif #ifdef CONFIG_PPC64 @@ -84,20 +88,11 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) isync li r3,0 blr - .cfi_endproc -V_FUNCTION_END(__kernel_sync_dicache) - - -/* - * POWER5 version of __kernel_sync_dicache - */ -V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) - .cfi_startproc +3: crclr cr0*4+so sync isync li r3,0 blr .cfi_endproc -V_FUNCTION_END(__kernel_sync_dicache_p5) - +V_FUNCTION_END(__kernel_sync_dicache) diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S index 1d23e2771dba..65244416ab94 100644 --- a/arch/powerpc/kernel/vdso32/datapage.S +++ b/arch/powerpc/kernel/vdso32/datapage.S @@ -13,9 +13,6 @@ #include <asm/vdso_datapage.h> .text - .global __kernel_datapage_offset; -__kernel_datapage_offset: - .long 0 /* * void *__kernel_get_syscall_map(unsigned int *syscall_count) ; @@ -31,7 +28,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map) mflr r12 .cfi_register lr,r12 mr. r4,r3 - get_datapage r3, r0 + get_datapage r3 mtlr r12 addi r3,r3,CFG_SYSCALL_MAP32 beqlr @@ -51,7 +48,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq) .cfi_startproc mflr r12 .cfi_register lr,r12 - get_datapage r3, r0 + get_datapage r3 lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3) lwz r3,CFG_TB_TICKS_PER_SEC(r3) mtlr r12 diff --git a/arch/powerpc/kernel/vdso32/gen_vdso_offsets.sh b/arch/powerpc/kernel/vdso32/gen_vdso_offsets.sh new file mode 100755 index 000000000000..c7b54a5dcd3e --- /dev/null +++ b/arch/powerpc/kernel/vdso32/gen_vdso_offsets.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +# +# Match symbols in the DSO that look like VDSO_*; produce a header file +# of constant offsets into the shared object. +# +# Doing this inside the Makefile will break the $(filter-out) function, +# causing Kbuild to rebuild the vdso-offsets header file every time. +# +# Author: Will Deacon <will.deacon@arm.com +# + +LC_ALL=C +sed -n -e 's/^00*/0/' -e \ +'s/^\([0-9a-fA-F]*\) . VDSO_\([a-zA-Z0-9_]*\)$/\#define vdso32_offset_\2\t0x\1/p' diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index e7f8f9f1b3f4..a6e29f880e0e 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S @@ -12,13 +12,7 @@ #include <asm/vdso_datapage.h> #include <asm/asm-offsets.h> #include <asm/unistd.h> - -/* Offset for the low 32-bit part of a field of long type */ -#ifdef CONFIG_PPC64 -#define LOPART 4 -#else -#define LOPART 0 -#endif +#include <asm/vdso/gettimeofday.h> .text /* @@ -28,32 +22,7 @@ * */ V_FUNCTION_BEGIN(__kernel_gettimeofday) - .cfi_startproc - mflr r12 - .cfi_register lr,r12 - - mr. r10,r3 /* r10 saves tv */ - mr r11,r4 /* r11 saves tz */ - get_datapage r9, r0 - beq 3f - LOAD_REG_IMMEDIATE(r7, 1000000) /* load up USEC_PER_SEC */ - bl __do_get_tspec@local /* get sec/usec from tb & kernel */ - stw r3,TVAL32_TV_SEC(r10) - stw r4,TVAL32_TV_USEC(r10) - -3: cmplwi r11,0 /* check if tz is NULL */ - mtlr r12 - crclr cr0*4+so - li r3,0 - beqlr - - lwz r4,CFG_TZ_MINUTEWEST(r9)/* fill tz */ - lwz r5,CFG_TZ_DSTTIME(r9) - stw r4,TZONE_TZ_MINWEST(r11) - stw r5,TZONE_TZ_DSTTIME(r11) - - blr - .cfi_endproc + cvdso_call __c_kernel_gettimeofday V_FUNCTION_END(__kernel_gettimeofday) /* @@ -63,129 +32,18 @@ V_FUNCTION_END(__kernel_gettimeofday) * */ V_FUNCTION_BEGIN(__kernel_clock_gettime) - .cfi_startproc - /* Check for supported clock IDs */ - cmpli cr0,r3,CLOCK_REALTIME - cmpli cr1,r3,CLOCK_MONOTONIC - cror cr0*4+eq,cr0*4+eq,cr1*4+eq - - cmpli cr5,r3,CLOCK_REALTIME_COARSE - cmpli cr6,r3,CLOCK_MONOTONIC_COARSE - cror cr5*4+eq,cr5*4+eq,cr6*4+eq - - cror cr0*4+eq,cr0*4+eq,cr5*4+eq - bne cr0, .Lgettime_fallback - - mflr r12 /* r12 saves lr */ - .cfi_register lr,r12 - mr r11,r4 /* r11 saves tp */ - get_datapage r9, r0 - LOAD_REG_IMMEDIATE(r7, NSEC_PER_SEC) /* load up NSEC_PER_SEC */ - beq cr5, .Lcoarse_clocks -.Lprecise_clocks: - bl __do_get_tspec@local /* get sec/nsec from tb & kernel */ - bne cr1, .Lfinish /* not monotonic -> all done */ - - /* - * CLOCK_MONOTONIC - */ - - /* now we must fixup using wall to monotonic. We need to snapshot - * that value and do the counter trick again. Fortunately, we still - * have the counter value in r8 that was returned by __do_get_xsec. - * At this point, r3,r4 contain our sec/nsec values, r5 and r6 - * can be used, r7 contains NSEC_PER_SEC. - */ - - lwz r5,(WTOM_CLOCK_SEC+LOPART)(r9) - lwz r6,WTOM_CLOCK_NSEC(r9) - - /* We now have our offset in r5,r6. We create a fake dependency - * on that value and re-check the counter - */ - or r0,r6,r5 - xor r0,r0,r0 - add r9,r9,r0 - lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) - cmpl cr0,r8,r0 /* check if updated */ - bne- .Lprecise_clocks - b .Lfinish_monotonic - - /* - * For coarse clocks we get data directly from the vdso data page, so - * we don't need to call __do_get_tspec, but we still need to do the - * counter trick. - */ -.Lcoarse_clocks: - lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9) - andi. r0,r8,1 /* pending update ? loop */ - bne- .Lcoarse_clocks - add r9,r9,r0 /* r0 is already 0 */ - - /* - * CLOCK_REALTIME_COARSE, below values are needed for MONOTONIC_COARSE - * too - */ - lwz r3,STAMP_XTIME_SEC+LOPART(r9) - lwz r4,STAMP_XTIME_NSEC+LOPART(r9) - bne cr6,1f - - /* CLOCK_MONOTONIC_COARSE */ - lwz r5,(WTOM_CLOCK_SEC+LOPART)(r9) - lwz r6,WTOM_CLOCK_NSEC(r9) - - /* check if counter has updated */ - or r0,r6,r5 -1: or r0,r0,r3 - or r0,r0,r4 - xor r0,r0,r0 - add r3,r3,r0 - lwz r0,CFG_TB_UPDATE_COUNT+LOPART(r9) - cmpl cr0,r0,r8 /* check if updated */ - bne- .Lcoarse_clocks - - /* Counter has not updated, so continue calculating proper values for - * sec and nsec if monotonic coarse, or just return with the proper - * values for realtime. - */ - bne cr6, .Lfinish - - /* Calculate and store result. Note that this mimics the C code, - * which may cause funny results if nsec goes negative... is that - * possible at all ? - */ -.Lfinish_monotonic: - add r3,r3,r5 - add r4,r4,r6 - cmpw cr0,r4,r7 - cmpwi cr1,r4,0 - blt 1f - subf r4,r7,r4 - addi r3,r3,1 -1: bge cr1, .Lfinish - addi r3,r3,-1 - add r4,r4,r7 - -.Lfinish: - stw r3,TSPC32_TV_SEC(r11) - stw r4,TSPC32_TV_NSEC(r11) - - mtlr r12 - crclr cr0*4+so - li r3,0 - blr - - /* - * syscall fallback - */ -.Lgettime_fallback: - li r0,__NR_clock_gettime - .cfi_restore lr - sc - blr - .cfi_endproc + cvdso_call __c_kernel_clock_gettime V_FUNCTION_END(__kernel_clock_gettime) +/* + * Exact prototype of clock_gettime64() + * + * int __kernel_clock_gettime64(clockid_t clock_id, struct __timespec64 *ts); + * + */ +V_FUNCTION_BEGIN(__kernel_clock_gettime64) + cvdso_call __c_kernel_clock_gettime64 +V_FUNCTION_END(__kernel_clock_gettime64) /* * Exact prototype of clock_getres() @@ -194,37 +52,7 @@ V_FUNCTION_END(__kernel_clock_gettime) * */ V_FUNCTION_BEGIN(__kernel_clock_getres) - .cfi_startproc - /* Check for supported clock IDs */ - cmplwi cr0, r3, CLOCK_MAX - cmpwi cr1, r3, CLOCK_REALTIME_COARSE - cmpwi cr7, r3, CLOCK_MONOTONIC_COARSE - bgt cr0, 99f - LOAD_REG_IMMEDIATE(r5, KTIME_LOW_RES) - beq cr1, 1f - beq cr7, 1f - - mflr r12 - .cfi_register lr,r12 - get_datapage r3, r0 - lwz r5, CLOCK_HRTIMER_RES(r3) - mtlr r12 -1: li r3,0 - cmpli cr0,r4,0 - crclr cr0*4+so - beqlr - stw r3,TSPC32_TV_SEC(r4) - stw r5,TSPC32_TV_NSEC(r4) - blr - - /* - * syscall fallback - */ -99: - li r0,__NR_clock_getres - sc - blr - .cfi_endproc + cvdso_call __c_kernel_clock_getres V_FUNCTION_END(__kernel_clock_getres) @@ -235,105 +63,5 @@ V_FUNCTION_END(__kernel_clock_getres) * */ V_FUNCTION_BEGIN(__kernel_time) - .cfi_startproc - mflr r12 - .cfi_register lr,r12 - - mr r11,r3 /* r11 holds t */ - get_datapage r9, r0 - - lwz r3,STAMP_XTIME_SEC+LOPART(r9) - - cmplwi r11,0 /* check if t is NULL */ - mtlr r12 - crclr cr0*4+so - beqlr - stw r3,0(r11) /* store result at *t */ - blr - .cfi_endproc + cvdso_call_time __c_kernel_time V_FUNCTION_END(__kernel_time) - -/* - * This is the core of clock_gettime() and gettimeofday(), - * it returns the current time in r3 (seconds) and r4. - * On entry, r7 gives the resolution of r4, either USEC_PER_SEC - * or NSEC_PER_SEC, giving r4 in microseconds or nanoseconds. - * It expects the datapage ptr in r9 and doesn't clobber it. - * It clobbers r0, r5 and r6. - * On return, r8 contains the counter value that can be reused. - * This clobbers cr0 but not any other cr field. - */ -__do_get_tspec: - .cfi_startproc - /* Check for update count & load values. We use the low - * order 32 bits of the update count - */ -1: lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9) - andi. r0,r8,1 /* pending update ? loop */ - bne- 1b - xor r0,r8,r8 /* create dependency */ - add r9,r9,r0 - - /* Load orig stamp (offset to TB) */ - lwz r5,CFG_TB_ORIG_STAMP(r9) - lwz r6,(CFG_TB_ORIG_STAMP+4)(r9) - - /* Get a stable TB value */ -2: MFTBU(r3) - MFTBL(r4) - MFTBU(r0) - cmplw cr0,r3,r0 - bne- 2b - - /* Subtract tb orig stamp and shift left 12 bits. - */ - subfc r4,r6,r4 - subfe r0,r5,r3 - slwi r0,r0,12 - rlwimi. r0,r4,12,20,31 - slwi r4,r4,12 - - /* - * Load scale factor & do multiplication. - * We only use the high 32 bits of the tb_to_xs value. - * Even with a 1GHz timebase clock, the high 32 bits of - * tb_to_xs will be at least 4 million, so the error from - * ignoring the low 32 bits will be no more than 0.25ppm. - * The error will just make the clock run very very slightly - * slow until the next time the kernel updates the VDSO data, - * at which point the clock will catch up to the kernel's value, - * so there is no long-term error accumulation. - */ - lwz r5,CFG_TB_TO_XS(r9) /* load values */ - mulhwu r4,r4,r5 - li r3,0 - - beq+ 4f /* skip high part computation if 0 */ - mulhwu r3,r0,r5 - mullw r5,r0,r5 - addc r4,r4,r5 - addze r3,r3 -4: - /* At this point, we have seconds since the xtime stamp - * as a 32.32 fixed-point number in r3 and r4. - * Load & add the xtime stamp. - */ - lwz r5,STAMP_XTIME_SEC+LOPART(r9) - lwz r6,STAMP_SEC_FRAC(r9) - addc r4,r4,r6 - adde r3,r3,r5 - - /* We create a fake dependency on the result in r3/r4 - * and re-check the counter - */ - or r6,r4,r3 - xor r0,r6,r6 - add r9,r9,r0 - lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) - cmplw cr0,r8,r0 /* check if updated */ - bne- 1b - - mulhwu r4,r4,r7 /* convert to micro or nanoseconds */ - - blr - .cfi_endproc diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S index 7eadac74c7f9..a4b806b0d618 100644 --- a/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S @@ -4,6 +4,8 @@ * library */ #include <asm/vdso.h> +#include <asm/page.h> +#include <asm-generic/vmlinux.lds.h> #ifdef __LITTLE_ENDIAN__ OUTPUT_FORMAT("elf32-powerpcle", "elf32-powerpcle", "elf32-powerpcle") @@ -15,7 +17,8 @@ ENTRY(_start) SECTIONS { - . = VDSO32_LBASE + SIZEOF_HEADERS; + PROVIDE(_vdso_datapage = . - PAGE_SIZE); + . = SIZEOF_HEADERS; .hash : { *(.hash) } :text .gnu.hash : { *(.gnu.hash) } @@ -36,17 +39,25 @@ SECTIONS PROVIDE(etext = .); . = ALIGN(8); + VDSO_ftr_fixup_start = .; __ftr_fixup : { *(__ftr_fixup) } + VDSO_ftr_fixup_end = .; . = ALIGN(8); + VDSO_mmu_ftr_fixup_start = .; __mmu_ftr_fixup : { *(__mmu_ftr_fixup) } + VDSO_mmu_ftr_fixup_end = .; . = ALIGN(8); + VDSO_lwsync_fixup_start = .; __lwsync_fixup : { *(__lwsync_fixup) } + VDSO_lwsync_fixup_end = .; #ifdef CONFIG_PPC64 . = ALIGN(8); + VDSO_fw_ftr_fixup_start = .; __fw_ftr_fixup : { *(__fw_ftr_fixup) } + VDSO_fw_ftr_fixup_end = .; #endif /* @@ -68,49 +79,15 @@ SECTIONS __end = .; PROVIDE(end = .); - /* - * Stabs debugging sections are here too. - */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - - /* - * DWARF debug sections. - * Symbols in the DWARF debugging sections are relative to the beginning - * of the section so we begin them at 0. - */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } + STABS_DEBUG + DWARF_DEBUG + ELF_DETAILS /DISCARD/ : { *(.note.GNU-stack) *(.data .data.* .gnu.linkonce.d.* .sdata*) *(.bss .sbss .dynbss .dynsbss) + *(.got1) } } @@ -138,19 +115,14 @@ VERSION { VDSO_VERSION_STRING { global: - /* - * Has to be there for the kernel to find - */ - __kernel_datapage_offset; - __kernel_get_syscall_map; __kernel_gettimeofday; __kernel_clock_gettime; + __kernel_clock_gettime64; __kernel_clock_getres; __kernel_time; __kernel_get_tbfreq; __kernel_sync_dicache; - __kernel_sync_dicache_p5; __kernel_sigtramp32; __kernel_sigtramp_rt32; #if defined(CONFIG_PPC64) || !defined(CONFIG_SMP) @@ -160,3 +132,9 @@ VERSION local: *; }; } + +/* + * Make the sigreturn code visible to the kernel. + */ +VDSO_sigtramp32 = __kernel_sigtramp32; +VDSO_sigtramp_rt32 = __kernel_sigtramp_rt32; diff --git a/arch/powerpc/kernel/vdso32/vgettimeofday.c b/arch/powerpc/kernel/vdso32/vgettimeofday.c new file mode 100644 index 000000000000..65fb03fb1731 --- /dev/null +++ b/arch/powerpc/kernel/vdso32/vgettimeofday.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Powerpc userspace implementations of gettimeofday() and similar. + */ +#include <linux/types.h> + +int __c_kernel_clock_gettime(clockid_t clock, struct old_timespec32 *ts, + const struct vdso_data *vd) +{ + return __cvdso_clock_gettime32_data(vd, clock, ts); +} + +int __c_kernel_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts, + const struct vdso_data *vd) +{ + return __cvdso_clock_gettime_data(vd, clock, ts); +} + +int __c_kernel_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz, + const struct vdso_data *vd) +{ + return __cvdso_gettimeofday_data(vd, tv, tz); +} + +int __c_kernel_clock_getres(clockid_t clock_id, struct old_timespec32 *res, + const struct vdso_data *vd) +{ + return __cvdso_clock_getres_time32_data(vd, clock_id, res); +} + +__kernel_old_time_t __c_kernel_time(__kernel_old_time_t *time, const struct vdso_data *vd) +{ + return __cvdso_time_data(vd, time); +} diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile index dfd34f68bfa1..bf363ff37152 100644 --- a/arch/powerpc/kernel/vdso64/Makefile +++ b/arch/powerpc/kernel/vdso64/Makefile @@ -1,16 +1,29 @@ # SPDX-License-Identifier: GPL-2.0 # List of files in the vdso, has to be asm only for now +ARCH_REL_TYPE_ABS := R_PPC_JUMP_SLOT|R_PPC_GLOB_DAT|R_PPC_ADDR32|R_PPC_ADDR24|R_PPC_ADDR16|R_PPC_ADDR16_LO|R_PPC_ADDR16_HI|R_PPC_ADDR16_HA|R_PPC_ADDR14|R_PPC_ADDR14_BRTAKEN|R_PPC_ADDR14_BRNTAKEN|R_PPC_REL24 +include $(srctree)/lib/vdso/Makefile + obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o getcpu.o +ifneq ($(c-gettimeofday-y),) + CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y) + CFLAGS_vgettimeofday.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) + CFLAGS_vgettimeofday.o += $(call cc-option, -fno-stack-protector) + CFLAGS_vgettimeofday.o += -DDISABLE_BRANCH_PROFILING + CFLAGS_vgettimeofday.o += -ffreestanding -fasynchronous-unwind-tables + CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) +endif + # Build rules -targets := $(obj-vdso64) vdso64.so vdso64.so.dbg +targets := $(obj-vdso64) vdso64.so.dbg obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64)) GCOV_PROFILE := n KCOV_INSTRUMENT := n UBSAN_SANITIZE := n +KASAN_SANITIZE := n ccflags-y := -shared -fno-common -fno-builtin -nostdlib \ -Wl,-soname=linux-vdso64.so.1 -Wl,--hash-style=both @@ -20,28 +33,23 @@ obj-y += vdso64_wrapper.o targets += vdso64.lds CPPFLAGS_vdso64.lds += -P -C -U$(ARCH) +$(obj)/vgettimeofday.o: %.o: %.c FORCE + # Force dependency (incbin is bad) -$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so +$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so.dbg # link rule for the .so file, .lds has to be first -$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) FORCE - $(call if_changed,vdso64ld) +$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) $(obj)/vgettimeofday.o FORCE + $(call if_changed,vdso64ld_and_check) -# strip rule for the .so file -$(obj)/%.so: OBJCOPYFLAGS := -S -$(obj)/%.so: $(obj)/%.so.dbg FORCE - $(call if_changed,objcopy) +# Generate VDSO offsets using helper script +gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh +quiet_cmd_vdsosym = VDSOSYM $@ + cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ -# actual build commands -quiet_cmd_vdso64ld = VDSO64L $@ - cmd_vdso64ld = $(CC) $(c_flags) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) +include/generated/vdso64-offsets.h: $(obj)/vdso64.so.dbg FORCE + $(call if_changed,vdsosym) -# install commands for the unstripped file -quiet_cmd_vdso_install = INSTALL $@ - cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ - -vdso64.so: $(obj)/vdso64.so.dbg - @mkdir -p $(MODLIB)/vdso - $(call cmd,vdso_install) - -vdso_install: vdso64.so +# actual build commands +quiet_cmd_vdso64ld_and_check = VDSO64L $@ + cmd_vdso64ld_and_check = $(CC) $(c_flags) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^); $(cmd_vdso_check) diff --git a/arch/powerpc/kernel/vdso64/cacheflush.S b/arch/powerpc/kernel/vdso64/cacheflush.S index cab14324242b..76c3c8cf8ece 100644 --- a/arch/powerpc/kernel/vdso64/cacheflush.S +++ b/arch/powerpc/kernel/vdso64/cacheflush.S @@ -23,10 +23,14 @@ */ V_FUNCTION_BEGIN(__kernel_sync_dicache) .cfi_startproc +BEGIN_FTR_SECTION + b 3f +END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) mflr r12 .cfi_register lr,r12 - get_datapage r10, r0 + get_datapage r10 mtlr r12 + .cfi_restore lr lwz r7,CFG_DCACHE_BLOCKSZ(r10) addi r5,r7,-1 @@ -61,19 +65,11 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) isync li r3,0 blr - .cfi_endproc -V_FUNCTION_END(__kernel_sync_dicache) - - -/* - * POWER5 version of __kernel_sync_dicache - */ -V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) - .cfi_startproc +3: crclr cr0*4+so sync isync li r3,0 blr .cfi_endproc -V_FUNCTION_END(__kernel_sync_dicache_p5) +V_FUNCTION_END(__kernel_sync_dicache) diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S index 067247d3efb9..00760dc69d68 100644 --- a/arch/powerpc/kernel/vdso64/datapage.S +++ b/arch/powerpc/kernel/vdso64/datapage.S @@ -13,9 +13,6 @@ #include <asm/vdso_datapage.h> .text -.global __kernel_datapage_offset; -__kernel_datapage_offset: - .long 0 /* * void *__kernel_get_syscall_map(unsigned int *syscall_count) ; @@ -31,7 +28,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map) mflr r12 .cfi_register lr,r12 mr r4,r3 - get_datapage r3, r0 + get_datapage r3 mtlr r12 addi r3,r3,CFG_SYSCALL_MAP64 cmpldi cr0,r4,0 @@ -53,7 +50,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq) .cfi_startproc mflr r12 .cfi_register lr,r12 - get_datapage r3, r0 + get_datapage r3 ld r3,CFG_TB_TICKS_PER_SEC(r3) mtlr r12 crclr cr0*4+so diff --git a/arch/powerpc/kernel/vdso64/gen_vdso_offsets.sh b/arch/powerpc/kernel/vdso64/gen_vdso_offsets.sh new file mode 100755 index 000000000000..4bf15ffd5933 --- /dev/null +++ b/arch/powerpc/kernel/vdso64/gen_vdso_offsets.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 + +# +# Match symbols in the DSO that look like VDSO_*; produce a header file +# of constant offsets into the shared object. +# +# Doing this inside the Makefile will break the $(filter-out) function, +# causing Kbuild to rebuild the vdso-offsets header file every time. +# +# Author: Will Deacon <will.deacon@arm.com +# + +LC_ALL=C +sed -n -e 's/^00*/0/' -e \ +'s/^\([0-9a-fA-F]*\) . VDSO_\([a-zA-Z0-9_]*\)$/\#define vdso64_offset_\2\t0x\1/p' diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index 20f8be40c653..d7a7bfb51081 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S @@ -12,6 +12,7 @@ #include <asm/vdso_datapage.h> #include <asm/asm-offsets.h> #include <asm/unistd.h> +#include <asm/vdso/gettimeofday.h> .text /* @@ -21,31 +22,7 @@ * */ V_FUNCTION_BEGIN(__kernel_gettimeofday) - .cfi_startproc - mflr r12 - .cfi_register lr,r12 - - mr r11,r3 /* r11 holds tv */ - mr r10,r4 /* r10 holds tz */ - get_datapage r3, r0 - cmpldi r11,0 /* check if tv is NULL */ - beq 2f - lis r7,1000000@ha /* load up USEC_PER_SEC */ - addi r7,r7,1000000@l - bl V_LOCAL_FUNC(__do_get_tspec) /* get sec/us from tb & kernel */ - std r4,TVAL64_TV_SEC(r11) /* store sec in tv */ - std r5,TVAL64_TV_USEC(r11) /* store usec in tv */ -2: cmpldi r10,0 /* check if tz is NULL */ - beq 1f - lwz r4,CFG_TZ_MINUTEWEST(r3)/* fill tz */ - lwz r5,CFG_TZ_DSTTIME(r3) - stw r4,TZONE_TZ_MINWEST(r10) - stw r5,TZONE_TZ_DSTTIME(r10) -1: mtlr r12 - crclr cr0*4+so - li r3,0 /* always success */ - blr - .cfi_endproc + cvdso_call __c_kernel_gettimeofday V_FUNCTION_END(__kernel_gettimeofday) @@ -56,120 +33,7 @@ V_FUNCTION_END(__kernel_gettimeofday) * */ V_FUNCTION_BEGIN(__kernel_clock_gettime) - .cfi_startproc - /* Check for supported clock IDs */ - cmpwi cr0,r3,CLOCK_REALTIME - cmpwi cr1,r3,CLOCK_MONOTONIC - cror cr0*4+eq,cr0*4+eq,cr1*4+eq - - cmpwi cr5,r3,CLOCK_REALTIME_COARSE - cmpwi cr6,r3,CLOCK_MONOTONIC_COARSE - cror cr5*4+eq,cr5*4+eq,cr6*4+eq - - cror cr0*4+eq,cr0*4+eq,cr5*4+eq - bne cr0,99f - - mflr r12 /* r12 saves lr */ - .cfi_register lr,r12 - mr r11,r4 /* r11 saves tp */ - get_datapage r3, r0 - lis r7,NSEC_PER_SEC@h /* want nanoseconds */ - ori r7,r7,NSEC_PER_SEC@l - beq cr5,70f -50: bl V_LOCAL_FUNC(__do_get_tspec) /* get time from tb & kernel */ - bne cr1,80f /* if not monotonic, all done */ - - /* - * CLOCK_MONOTONIC - */ - - /* now we must fixup using wall to monotonic. We need to snapshot - * that value and do the counter trick again. Fortunately, we still - * have the counter value in r8 that was returned by __do_get_tspec. - * At this point, r4,r5 contain our sec/nsec values. - */ - - ld r6,WTOM_CLOCK_SEC(r3) - lwa r9,WTOM_CLOCK_NSEC(r3) - - /* We now have our result in r6,r9. We create a fake dependency - * on that result and re-check the counter - */ - or r0,r6,r9 - xor r0,r0,r0 - add r3,r3,r0 - ld r0,CFG_TB_UPDATE_COUNT(r3) - cmpld cr0,r0,r8 /* check if updated */ - bne- 50b - b 78f - - /* - * For coarse clocks we get data directly from the vdso data page, so - * we don't need to call __do_get_tspec, but we still need to do the - * counter trick. - */ -70: ld r8,CFG_TB_UPDATE_COUNT(r3) - andi. r0,r8,1 /* pending update ? loop */ - bne- 70b - add r3,r3,r0 /* r0 is already 0 */ - - /* - * CLOCK_REALTIME_COARSE, below values are needed for MONOTONIC_COARSE - * too - */ - ld r4,STAMP_XTIME_SEC(r3) - ld r5,STAMP_XTIME_NSEC(r3) - bne cr6,75f - - /* CLOCK_MONOTONIC_COARSE */ - ld r6,WTOM_CLOCK_SEC(r3) - lwa r9,WTOM_CLOCK_NSEC(r3) - - /* check if counter has updated */ - or r0,r6,r9 -75: or r0,r0,r4 - or r0,r0,r5 - xor r0,r0,r0 - add r3,r3,r0 - ld r0,CFG_TB_UPDATE_COUNT(r3) - cmpld cr0,r0,r8 /* check if updated */ - bne- 70b - - /* Counter has not updated, so continue calculating proper values for - * sec and nsec if monotonic coarse, or just return with the proper - * values for realtime. - */ - bne cr6,80f - - /* Add wall->monotonic offset and check for overflow or underflow */ -78: add r4,r4,r6 - add r5,r5,r9 - cmpd cr0,r5,r7 - cmpdi cr1,r5,0 - blt 79f - subf r5,r7,r5 - addi r4,r4,1 -79: bge cr1,80f - addi r4,r4,-1 - add r5,r5,r7 - -80: std r4,TSPC64_TV_SEC(r11) - std r5,TSPC64_TV_NSEC(r11) - - mtlr r12 - crclr cr0*4+so - li r3,0 - blr - - /* - * syscall fallback - */ -99: - li r0,__NR_clock_gettime - .cfi_restore lr - sc - blr - .cfi_endproc + cvdso_call __c_kernel_clock_gettime V_FUNCTION_END(__kernel_clock_gettime) @@ -180,34 +44,7 @@ V_FUNCTION_END(__kernel_clock_gettime) * */ V_FUNCTION_BEGIN(__kernel_clock_getres) - .cfi_startproc - /* Check for supported clock IDs */ - cmpwi cr0,r3,CLOCK_REALTIME - cmpwi cr1,r3,CLOCK_MONOTONIC - cror cr0*4+eq,cr0*4+eq,cr1*4+eq - bne cr0,99f - - mflr r12 - .cfi_register lr,r12 - get_datapage r3, r0 - lwz r5, CLOCK_HRTIMER_RES(r3) - mtlr r12 - li r3,0 - cmpldi cr0,r4,0 - crclr cr0*4+so - beqlr - std r3,TSPC64_TV_SEC(r4) - std r5,TSPC64_TV_NSEC(r4) - blr - - /* - * syscall fallback - */ -99: - li r0,__NR_clock_getres - sc - blr - .cfi_endproc + cvdso_call __c_kernel_clock_getres V_FUNCTION_END(__kernel_clock_getres) /* @@ -217,74 +54,5 @@ V_FUNCTION_END(__kernel_clock_getres) * */ V_FUNCTION_BEGIN(__kernel_time) - .cfi_startproc - mflr r12 - .cfi_register lr,r12 - - mr r11,r3 /* r11 holds t */ - get_datapage r3, r0 - - ld r4,STAMP_XTIME_SEC(r3) - - cmpldi r11,0 /* check if t is NULL */ - beq 2f - std r4,0(r11) /* store result at *t */ -2: mtlr r12 - crclr cr0*4+so - mr r3,r4 - blr - .cfi_endproc + cvdso_call_time __c_kernel_time V_FUNCTION_END(__kernel_time) - - -/* - * This is the core of clock_gettime() and gettimeofday(), - * it returns the current time in r4 (seconds) and r5. - * On entry, r7 gives the resolution of r5, either USEC_PER_SEC - * or NSEC_PER_SEC, giving r5 in microseconds or nanoseconds. - * It expects the datapage ptr in r3 and doesn't clobber it. - * It clobbers r0, r6 and r9. - * On return, r8 contains the counter value that can be reused. - * This clobbers cr0 but not any other cr field. - */ -V_FUNCTION_BEGIN(__do_get_tspec) - .cfi_startproc - /* check for update count & load values */ -1: ld r8,CFG_TB_UPDATE_COUNT(r3) - andi. r0,r8,1 /* pending update ? loop */ - bne- 1b - xor r0,r8,r8 /* create dependency */ - add r3,r3,r0 - - /* Get TB & offset it. We use the MFTB macro which will generate - * workaround code for Cell. - */ - MFTB(r6) - ld r9,CFG_TB_ORIG_STAMP(r3) - subf r6,r9,r6 - - /* Scale result */ - ld r5,CFG_TB_TO_XS(r3) - sldi r6,r6,12 /* compute time since stamp_xtime */ - mulhdu r6,r6,r5 /* in units of 2^-32 seconds */ - - /* Add stamp since epoch */ - ld r4,STAMP_XTIME_SEC(r3) - lwz r5,STAMP_SEC_FRAC(r3) - or r0,r4,r5 - or r0,r0,r6 - xor r0,r0,r0 - add r3,r3,r0 - ld r0,CFG_TB_UPDATE_COUNT(r3) - cmpld r0,r8 /* check if updated */ - bne- 1b /* reload if so */ - - /* convert to seconds & nanoseconds and add to stamp */ - add r6,r6,r5 /* add on fractional seconds of xtime */ - mulhwu r5,r6,r7 /* compute micro or nanoseconds and */ - srdi r6,r6,32 /* seconds since stamp_xtime */ - clrldi r5,r5,32 - add r4,r4,r6 - blr - .cfi_endproc -V_FUNCTION_END(__do_get_tspec) diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index 256fb9720298..6164d1a1ba11 100644 --- a/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S @@ -4,6 +4,8 @@ * library */ #include <asm/vdso.h> +#include <asm/page.h> +#include <asm-generic/vmlinux.lds.h> #ifdef __LITTLE_ENDIAN__ OUTPUT_FORMAT("elf64-powerpcle", "elf64-powerpcle", "elf64-powerpcle") @@ -15,7 +17,8 @@ ENTRY(_start) SECTIONS { - . = VDSO64_LBASE + SIZEOF_HEADERS; + PROVIDE(_vdso_datapage = . - PAGE_SIZE); + . = SIZEOF_HEADERS; .hash : { *(.hash) } :text .gnu.hash : { *(.gnu.hash) } @@ -37,16 +40,24 @@ SECTIONS PROVIDE(etext = .); . = ALIGN(8); + VDSO_ftr_fixup_start = .; __ftr_fixup : { *(__ftr_fixup) } + VDSO_ftr_fixup_end = .; . = ALIGN(8); + VDSO_mmu_ftr_fixup_start = .; __mmu_ftr_fixup : { *(__mmu_ftr_fixup) } + VDSO_mmu_ftr_fixup_end = .; . = ALIGN(8); + VDSO_lwsync_fixup_start = .; __lwsync_fixup : { *(__lwsync_fixup) } + VDSO_lwsync_fixup_end = .; . = ALIGN(8); + VDSO_fw_ftr_fixup_start = .; __fw_ftr_fixup : { *(__fw_ftr_fixup) } + VDSO_fw_ftr_fixup_end = .; /* * Other stuff is appended to the text segment: @@ -61,56 +72,21 @@ SECTIONS .gcc_except_table : { *(.gcc_except_table) } .rela.dyn ALIGN(8) : { *(.rela.dyn) } - .opd ALIGN(8) : { KEEP (*(.opd)) } .got ALIGN(8) : { *(.got .toc) } _end = .; PROVIDE(end = .); - /* - * Stabs debugging sections are here too. - */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - - /* - * DWARF debug sections. - * Symbols in the DWARF debugging sections are relative to the beginning - * of the section so we begin them at 0. - */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } + STABS_DEBUG + DWARF_DEBUG + ELF_DETAILS /DISCARD/ : { *(.note.GNU-stack) *(.branch_lt) *(.data .data.* .gnu.linkonce.d.* .sdata*) *(.bss .sbss .dynbss .dynsbss) + *(.opd) } } @@ -138,18 +114,12 @@ VERSION { VDSO_VERSION_STRING { global: - /* - * Has to be there for the kernel to find - */ - __kernel_datapage_offset; - __kernel_get_syscall_map; __kernel_gettimeofday; __kernel_clock_gettime; __kernel_clock_getres; __kernel_get_tbfreq; __kernel_sync_dicache; - __kernel_sync_dicache_p5; __kernel_sigtramp_rt64; __kernel_getcpu; __kernel_time; @@ -157,3 +127,8 @@ VERSION local: *; }; } + +/* + * Make the sigreturn code visible to the kernel. + */ +VDSO_sigtramp_rt64 = __kernel_sigtramp_rt64; diff --git a/arch/powerpc/kernel/vdso64/vgettimeofday.c b/arch/powerpc/kernel/vdso64/vgettimeofday.c new file mode 100644 index 000000000000..5b5500058344 --- /dev/null +++ b/arch/powerpc/kernel/vdso64/vgettimeofday.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Powerpc userspace implementations of gettimeofday() and similar. + */ +#include <linux/time.h> +#include <linux/types.h> + +int __c_kernel_clock_gettime(clockid_t clock, struct __kernel_timespec *ts, + const struct vdso_data *vd) +{ + return __cvdso_clock_gettime_data(vd, clock, ts); +} + +int __c_kernel_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz, + const struct vdso_data *vd) +{ + return __cvdso_gettimeofday_data(vd, tv, tz); +} + +int __c_kernel_clock_getres(clockid_t clock_id, struct __kernel_timespec *res, + const struct vdso_data *vd) +{ + return __cvdso_clock_getres_data(vd, clock_id, res); +} + +__kernel_old_time_t __c_kernel_time(__kernel_old_time_t *time, const struct vdso_data *vd) +{ + return __cvdso_time_data(vd, time); +} diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index e184d17387f6..72fa3c00229a 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -85,7 +85,7 @@ SECTIONS ALIGN_FUNCTION(); #endif /* careful! __ftr_alt_* sections need to be close to .text */ - *(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text); + *(.text.hot .text.hot.* TEXT_MAIN .text.fixup .text.unlikely .text.unlikely.* .fixup __ftr_alt_* .ref.text); #ifdef CONFIG_PPC64 *(.tramp.ftrace.text); #endif @@ -146,6 +146,13 @@ SECTIONS } . = ALIGN(8); + __scv_entry_flush_fixup : AT(ADDR(__scv_entry_flush_fixup) - LOAD_OFFSET) { + __start___scv_entry_flush_fixup = .; + *(__scv_entry_flush_fixup) + __stop___scv_entry_flush_fixup = .; + } + + . = ALIGN(8); __stf_exit_barrier_fixup : AT(ADDR(__stf_exit_barrier_fixup) - LOAD_OFFSET) { __start___stf_exit_barrier_fixup = .; *(__stf_exit_barrier_fixup) @@ -187,6 +194,12 @@ SECTIONS .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { _sinittext = .; INIT_TEXT + + /* + *.init.text might be RO so we must ensure this section ends on + * a page boundary. + */ + . = ALIGN(PAGE_SIZE); _einittext = .; #ifdef CONFIG_PPC64 *(.tramp.ftrace.init); @@ -200,21 +213,9 @@ SECTIONS EXIT_TEXT } - .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { - INIT_DATA - } - - .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { - INIT_SETUP(16) - } - - .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { - INIT_CALLS - } + . = ALIGN(PAGE_SIZE); - .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { - CON_INITCALL - } + INIT_DATA_SECTION(16) . = ALIGN(8); __ftr_fixup : AT(ADDR(__ftr_fixup) - LOAD_OFFSET) { @@ -242,9 +243,6 @@ SECTIONS __stop___fw_ftr_fixup = .; } #endif - .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { - INIT_RAM_FS - } PERCPU_SECTION(L1_CACHE_BYTES) diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 0effd48c8f4d..b08cc15f31c7 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -840,6 +840,9 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) case SPRN_MMCR1: case SPRN_MMCR2: case SPRN_UMMCR2: + case SPRN_UAMOR: + case SPRN_IAMR: + case SPRN_AMR: #endif break; unprivileged: @@ -1004,6 +1007,9 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val case SPRN_MMCR2: case SPRN_UMMCR2: case SPRN_TIR: + case SPRN_UAMOR: + case SPRN_IAMR: + case SPRN_AMR: #endif *spr_val = 0; break; diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index e3b1839fc251..6f612d240392 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -1241,9 +1241,9 @@ static int kvmppc_emulate_doorbell_instr(struct kvm_vcpu *vcpu) switch (get_xop(inst)) { case OP_31_XOP_MSGSNDP: arg = kvmppc_get_gpr(vcpu, rb); - if (((arg >> 27) & 0xf) != PPC_DBELL_SERVER) + if (((arg >> 27) & 0x1f) != PPC_DBELL_SERVER) break; - arg &= 0x3f; + arg &= 0x7f; if (arg >= kvm->arch.emul_smt_mode) break; tvcpu = kvmppc_find_vcpu(kvm, vcpu->vcpu_id - thr + arg); @@ -1256,7 +1256,7 @@ static int kvmppc_emulate_doorbell_instr(struct kvm_vcpu *vcpu) break; case OP_31_XOP_MSGCLRP: arg = kvmppc_get_gpr(vcpu, rb); - if (((arg >> 27) & 0xf) != PPC_DBELL_SERVER) + if (((arg >> 27) & 0x1f) != PPC_DBELL_SERVER) break; vcpu->arch.vcore->dpdes = 0; vcpu->arch.doorbell_request = 0; @@ -1327,9 +1327,15 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, case BOOK3S_INTERRUPT_SYSTEM_RESET: r = RESUME_GUEST; break; - case BOOK3S_INTERRUPT_MACHINE_CHECK: - /* Print the MCE event to host console. */ - machine_check_print_event_info(&vcpu->arch.mce_evt, false, true); + case BOOK3S_INTERRUPT_MACHINE_CHECK: { + static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST); + /* + * Print the MCE event to host console. Ratelimit so the guest + * can't flood the host log. + */ + if (__ratelimit(&rs)) + machine_check_print_event_info(&vcpu->arch.mce_evt,false, true); /* * If the guest can do FWNMI, exit to userspace so it can @@ -1357,6 +1363,7 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, r = RESUME_HOST; break; + } case BOOK3S_INTERRUPT_PROGRAM: { ulong flags; @@ -1516,11 +1523,16 @@ static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu) r = RESUME_GUEST; break; case BOOK3S_INTERRUPT_MACHINE_CHECK: + { + static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST); /* Pass the machine check to the L1 guest */ r = RESUME_HOST; /* Print the MCE event to host console. */ - machine_check_print_event_info(&vcpu->arch.mce_evt, false, true); + if (__ratelimit(&rs)) + machine_check_print_event_info(&vcpu->arch.mce_evt, false, true); break; + } /* * We get these next two if the guest accesses a page which it thinks * it has mapped but which is not actually present, either because @@ -4949,7 +4961,12 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm) * Work out how many sets the TLB has, for the use of * the TLB invalidation loop in book3s_hv_rmhandlers.S. */ - if (radix_enabled()) + if (cpu_has_feature(CPU_FTR_ARCH_31)) { + /* + * P10 will flush all the congruence class with a single tlbiel + */ + kvm->arch.tlb_sets = 1; + } else if (radix_enabled()) kvm->arch.tlb_sets = POWER9_TLB_SETS_RADIX; /* 128 */ else if (cpu_has_feature(CPU_FTR_ARCH_300)) kvm->arch.tlb_sets = POWER9_TLB_SETS_HASH; /* 256 */ diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 8f58dd20b362..8053efdf7ea7 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -694,6 +694,7 @@ static void wait_for_sync(struct kvm_split_mode *sip, int phase) void kvmhv_p9_set_lpcr(struct kvm_split_mode *sip) { + int num_sets; unsigned long rb, set; /* wait for every other thread to get to real mode */ @@ -704,11 +705,19 @@ void kvmhv_p9_set_lpcr(struct kvm_split_mode *sip) mtspr(SPRN_LPID, sip->lpidr_req); isync(); + /* + * P10 will flush all the congruence class with a single tlbiel + */ + if (cpu_has_feature(CPU_FTR_ARCH_31)) + num_sets = 1; + else + num_sets = POWER9_TLB_SETS_RADIX; + /* Invalidate the TLB on thread 0 */ if (local_paca->kvm_hstate.tid == 0) { sip->do_set = 0; asm volatile("ptesync" : : : "memory"); - for (set = 0; set < POWER9_TLB_SETS_RADIX; ++set) { + for (set = 0; set < num_sets; ++set) { rb = TLBIEL_INVAL_SET_LPID + (set << TLBIEL_INVAL_SET_SHIFT); asm volatile(PPC_TLBIEL(%0, %1, 0, 0, 0) : : diff --git a/arch/powerpc/kvm/book3s_hv_ras.c b/arch/powerpc/kvm/book3s_hv_ras.c index 6028628ea3ac..d4bca93b79f6 100644 --- a/arch/powerpc/kvm/book3s_hv_ras.c +++ b/arch/powerpc/kvm/book3s_hv_ras.c @@ -65,10 +65,9 @@ static void reload_slb(struct kvm_vcpu *vcpu) * On POWER7, see if we can handle a machine check that occurred inside * the guest in real mode, without switching to the host partition. */ -static void kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu) +static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu) { unsigned long srr1 = vcpu->arch.shregs.msr; - struct machine_check_event mce_evt; long handled = 1; if (srr1 & SRR1_MC_LDSTERR) { @@ -106,6 +105,21 @@ static void kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu) handled = 0; } + return handled; +} + +void kvmppc_realmode_machine_check(struct kvm_vcpu *vcpu) +{ + struct machine_check_event mce_evt; + long handled; + + if (vcpu->kvm->arch.fwnmi_enabled) { + /* FWNMI guests handle their own recovery */ + handled = 0; + } else { + handled = kvmppc_realmode_mc_power7(vcpu); + } + /* * Now get the event and stash it in the vcpu struct so it can * be handled by the primary thread in virtual mode. We can't @@ -122,11 +136,6 @@ static void kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu) vcpu->arch.mce_evt = mce_evt; } -void kvmppc_realmode_machine_check(struct kvm_vcpu *vcpu) -{ - kvmppc_realmode_mc_power7(vcpu); -} - /* Check if dynamic split is in force and return subcore size accordingly. */ static inline int kvmppc_cur_subcore_size(void) { diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index b1fefa63e125..913944dc3620 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -239,7 +239,7 @@ static void kvmppc_recalc_shadow_msr(struct kvm_vcpu *vcpu) smsr |= (guest_msr & vcpu->arch.guest_owned_ext); /* 64-bit Process MSR values */ #ifdef CONFIG_PPC_BOOK3S_64 - smsr |= MSR_ISF | MSR_HV; + smsr |= MSR_HV; #endif #ifdef CONFIG_PPC_TRANSACTIONAL_MEM /* diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S index 3dc129a254b5..b45b750fa77a 100644 --- a/arch/powerpc/kvm/book3s_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_rmhandlers.S @@ -36,8 +36,8 @@ #define FUNC(name) name -#define RFI_TO_KERNEL RFI -#define RFI_TO_GUEST RFI +#define RFI_TO_KERNEL rfi +#define RFI_TO_GUEST rfi .macro INTERRUPT_TRAMPOLINE intno diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index 5fee5a11550d..303e3cb096db 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c @@ -473,7 +473,7 @@ static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, arch_spin_unlock(&ics->lock); local_irq_restore(flags); new_irq = reject; - check_resend = 0; + check_resend = false; goto again; } } else { @@ -501,7 +501,7 @@ static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, state->resend = 0; arch_spin_unlock(&ics->lock); local_irq_restore(flags); - check_resend = 0; + check_resend = false; goto again; } } diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index a0ebc29f30b2..30dfeac731c6 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -219,7 +219,7 @@ int kvmppc_xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio, /* In single escalation mode, we grab the ESB MMIO of the * interrupt and mask it. Also populate the VCPU v/raddr * of the ESB page for use by asm entry/exit code. Finally - * set the XIVE_IRQ_NO_EOI flag which will prevent the + * set the XIVE_IRQ_FLAG_NO_EOI flag which will prevent the * core code from performing an EOI on the escalation * interrupt, thus leaving it effectively masked after * it fires once. @@ -231,7 +231,7 @@ int kvmppc_xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio, xive_vm_esb_load(xd, XIVE_ESB_SET_PQ_01); vcpu->arch.xive_esc_raddr = xd->eoi_page; vcpu->arch.xive_esc_vaddr = (__force u64)xd->eoi_mmio; - xd->flags |= XIVE_IRQ_NO_EOI; + xd->flags |= XIVE_IRQ_FLAG_NO_EOI; } return 0; @@ -419,37 +419,16 @@ static u8 xive_lock_and_mask(struct kvmppc_xive *xive, /* Get the right irq */ kvmppc_xive_select_irq(state, &hw_num, &xd); + /* Set PQ to 10, return old P and old Q and remember them */ + val = xive_vm_esb_load(xd, XIVE_ESB_SET_PQ_10); + state->old_p = !!(val & 2); + state->old_q = !!(val & 1); + /* - * If the interrupt is marked as needing masking via - * firmware, we do it here. Firmware masking however - * is "lossy", it won't return the old p and q bits - * and won't set the interrupt to a state where it will - * record queued ones. If this is an issue we should do - * lazy masking instead. - * - * For now, we work around this in unmask by forcing - * an interrupt whenever we unmask a non-LSI via FW - * (if ever). + * Synchronize hardware to sensure the queues are updated when + * masking */ - if (xd->flags & OPAL_XIVE_IRQ_MASK_VIA_FW) { - xive_native_configure_irq(hw_num, - kvmppc_xive_vp(xive, state->act_server), - MASKED, state->number); - /* set old_p so we can track if an H_EOI was done */ - state->old_p = true; - state->old_q = false; - } else { - /* Set PQ to 10, return old P and old Q and remember them */ - val = xive_vm_esb_load(xd, XIVE_ESB_SET_PQ_10); - state->old_p = !!(val & 2); - state->old_q = !!(val & 1); - - /* - * Synchronize hardware to sensure the queues are updated - * when masking - */ - xive_native_sync_source(hw_num); - } + xive_native_sync_source(hw_num); return old_prio; } @@ -483,23 +462,6 @@ static void xive_finish_unmask(struct kvmppc_xive *xive, /* Get the right irq */ kvmppc_xive_select_irq(state, &hw_num, &xd); - /* - * See comment in xive_lock_and_mask() concerning masking - * via firmware. - */ - if (xd->flags & OPAL_XIVE_IRQ_MASK_VIA_FW) { - xive_native_configure_irq(hw_num, - kvmppc_xive_vp(xive, state->act_server), - state->act_priority, state->number); - /* If an EOI is needed, do it here */ - if (!state->old_p) - xive_vm_source_eoi(hw_num, xd); - /* If this is not an LSI, force a trigger */ - if (!(xd->flags & OPAL_XIVE_IRQ_LSI)) - xive_irq_trigger(xd); - goto bail; - } - /* Old Q set, set PQ to 11 */ if (state->old_q) xive_vm_esb_load(xd, XIVE_ESB_SET_PQ_11); @@ -2125,9 +2087,8 @@ int kvmppc_xive_debug_show_queues(struct seq_file *m, struct kvm_vcpu *vcpu) if (!q->qpage && !xc->esc_virq[i]) continue; - seq_printf(m, " [q%d]: ", i); - if (q->qpage) { + seq_printf(m, " q[%d]: ", i); idx = q->idx; i0 = be32_to_cpup(q->qpage + idx); idx = (idx + 1) & q->msk; @@ -2141,16 +2102,54 @@ int kvmppc_xive_debug_show_queues(struct seq_file *m, struct kvm_vcpu *vcpu) irq_data_get_irq_handler_data(d); u64 pq = xive_vm_esb_load(xd, XIVE_ESB_GET); - seq_printf(m, "E:%c%c I(%d:%llx:%llx)", - (pq & XIVE_ESB_VAL_P) ? 'P' : 'p', - (pq & XIVE_ESB_VAL_Q) ? 'Q' : 'q', - xc->esc_virq[i], pq, xd->eoi_page); + seq_printf(m, " ESC %d %c%c EOI @%llx", + xc->esc_virq[i], + (pq & XIVE_ESB_VAL_P) ? 'P' : '-', + (pq & XIVE_ESB_VAL_Q) ? 'Q' : '-', + xd->eoi_page); seq_puts(m, "\n"); } } return 0; } +void kvmppc_xive_debug_show_sources(struct seq_file *m, + struct kvmppc_xive_src_block *sb) +{ + int i; + + seq_puts(m, " LISN HW/CHIP TYPE PQ EISN CPU/PRIO\n"); + for (i = 0; i < KVMPPC_XICS_IRQ_PER_ICS; i++) { + struct kvmppc_xive_irq_state *state = &sb->irq_state[i]; + struct xive_irq_data *xd; + u64 pq; + u32 hw_num; + + if (!state->valid) + continue; + + kvmppc_xive_select_irq(state, &hw_num, &xd); + + pq = xive_vm_esb_load(xd, XIVE_ESB_GET); + + seq_printf(m, "%08x %08x/%02x", state->number, hw_num, + xd->src_chip); + if (state->lsi) + seq_printf(m, " %cLSI", state->asserted ? '^' : ' '); + else + seq_puts(m, " MSI"); + + seq_printf(m, " %s %c%c %08x % 4d/%d", + state->ipi_number == hw_num ? "IPI" : " PT", + pq & XIVE_ESB_VAL_P ? 'P' : '-', + pq & XIVE_ESB_VAL_Q ? 'Q' : '-', + state->eisn, state->act_server, + state->act_priority); + + seq_puts(m, "\n"); + } +} + static int xive_debug_show(struct seq_file *m, void *private) { struct kvmppc_xive *xive = m->private; @@ -2171,7 +2170,7 @@ static int xive_debug_show(struct seq_file *m, void *private) if (!kvm) return 0; - seq_printf(m, "=========\nVCPU state\n=========\n"); + seq_puts(m, "=========\nVCPU state\n=========\n"); kvm_for_each_vcpu(i, vcpu, kvm) { struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; @@ -2179,11 +2178,12 @@ static int xive_debug_show(struct seq_file *m, void *private) if (!xc) continue; - seq_printf(m, "cpu server %#x VP:%#x CPPR:%#x HWCPPR:%#x" - " MFRR:%#x PEND:%#x h_xirr: R=%lld V=%lld\n", - xc->server_num, xc->vp_id, xc->cppr, xc->hw_cppr, - xc->mfrr, xc->pending, - xc->stat_rm_h_xirr, xc->stat_vm_h_xirr); + seq_printf(m, "VCPU %d: VP:%#x/%02x\n" + " CPPR:%#x HWCPPR:%#x MFRR:%#x PEND:%#x h_xirr: R=%lld V=%lld\n", + xc->server_num, xc->vp_id, xc->vp_chip_id, + xc->cppr, xc->hw_cppr, + xc->mfrr, xc->pending, + xc->stat_rm_h_xirr, xc->stat_vm_h_xirr); kvmppc_xive_debug_show_queues(m, vcpu); @@ -2199,13 +2199,25 @@ static int xive_debug_show(struct seq_file *m, void *private) t_vm_h_ipi += xc->stat_vm_h_ipi; } - seq_printf(m, "Hcalls totals\n"); + seq_puts(m, "Hcalls totals\n"); seq_printf(m, " H_XIRR R=%10lld V=%10lld\n", t_rm_h_xirr, t_vm_h_xirr); seq_printf(m, " H_IPOLL R=%10lld V=%10lld\n", t_rm_h_ipoll, t_vm_h_ipoll); seq_printf(m, " H_CPPR R=%10lld V=%10lld\n", t_rm_h_cppr, t_vm_h_cppr); seq_printf(m, " H_EOI R=%10lld V=%10lld\n", t_rm_h_eoi, t_vm_h_eoi); seq_printf(m, " H_IPI R=%10lld V=%10lld\n", t_rm_h_ipi, t_vm_h_ipi); + seq_puts(m, "=========\nSources\n=========\n"); + + for (i = 0; i <= xive->max_sbid; i++) { + struct kvmppc_xive_src_block *sb = xive->src_blocks[i]; + + if (sb) { + arch_spin_lock(&sb->lock); + kvmppc_xive_debug_show_sources(m, sb); + arch_spin_unlock(&sb->lock); + } + } + return 0; } diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index 382e3a56e789..86c24a4ad809 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -218,6 +218,17 @@ static inline struct kvmppc_xive_src_block *kvmppc_xive_find_source(struct kvmpp return xive->src_blocks[bid]; } +/* + * When the XIVE resources are allocated at the HW level, the VP + * structures describing the vCPUs of a guest are distributed among + * the chips to optimize the PowerBUS usage. For best performance, the + * guest vCPUs can be pinned to match the VP structure distribution. + * + * Currently, the VP identifiers are deduced from the vCPU id using + * the kvmppc_pack_vcpu_id() routine which is not incorrect but not + * optimal either. It VSMT is used, the result is not continuous and + * the constraints on HW resources described above can not be met. + */ static inline u32 kvmppc_xive_vp(struct kvmppc_xive *xive, u32 server) { return xive->vp_base + kvmppc_pack_vcpu_id(xive->kvm, server); @@ -290,6 +301,8 @@ extern int (*__xive_vm_h_eoi)(struct kvm_vcpu *vcpu, unsigned long xirr); */ void kvmppc_xive_disable_vcpu_interrupts(struct kvm_vcpu *vcpu); int kvmppc_xive_debug_show_queues(struct seq_file *m, struct kvm_vcpu *vcpu); +void kvmppc_xive_debug_show_sources(struct seq_file *m, + struct kvmppc_xive_src_block *sb); struct kvmppc_xive_src_block *kvmppc_xive_create_src_block( struct kvmppc_xive *xive, int irq); void kvmppc_xive_free_sources(struct kvmppc_xive_src_block *sb); diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index a59a94f02733..76800c84f2a3 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -37,9 +37,6 @@ static u8 xive_vm_esb_load(struct xive_irq_data *xd, u32 offset) * ordering. */ - if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG) - offset |= offset << 4; - val = in_be64(xd->eoi_mmio + offset); return (u8)val; } @@ -1219,18 +1216,31 @@ static int xive_native_debug_show(struct seq_file *m, void *private) if (!xc) continue; - seq_printf(m, "cpu server %#x VP=%#x NSR=%02x CPPR=%02x IBP=%02x PIPR=%02x w01=%016llx w2=%08x\n", - xc->server_num, xc->vp_id, + seq_printf(m, "VCPU %d: VP=%#x/%02x\n" + " NSR=%02x CPPR=%02x IBP=%02x PIPR=%02x w01=%016llx w2=%08x\n", + xc->server_num, xc->vp_id, xc->vp_chip_id, vcpu->arch.xive_saved_state.nsr, vcpu->arch.xive_saved_state.cppr, vcpu->arch.xive_saved_state.ipb, vcpu->arch.xive_saved_state.pipr, - vcpu->arch.xive_saved_state.w01, - (u32) vcpu->arch.xive_cam_word); + be64_to_cpu(vcpu->arch.xive_saved_state.w01), + be32_to_cpu(vcpu->arch.xive_cam_word)); kvmppc_xive_debug_show_queues(m, vcpu); } + seq_puts(m, "=========\nSources\n=========\n"); + + for (i = 0; i <= xive->max_sbid; i++) { + struct kvmppc_xive_src_block *sb = xive->src_blocks[i]; + + if (sb) { + arch_spin_lock(&sb->lock); + kvmppc_xive_debug_show_sources(m, sb); + arch_spin_unlock(&sb->lock); + } + } + return 0; } diff --git a/arch/powerpc/kvm/book3s_xive_template.c b/arch/powerpc/kvm/book3s_xive_template.c index 4ad3c0279458..b0015e05d99a 100644 --- a/arch/powerpc/kvm/book3s_xive_template.c +++ b/arch/powerpc/kvm/book3s_xive_template.c @@ -61,9 +61,6 @@ static u8 GLUE(X_PFX,esb_load)(struct xive_irq_data *xd, u32 offset) if (offset == XIVE_ESB_SET_PQ_10 && xd->flags & XIVE_IRQ_FLAG_STORE_EOI) offset |= XIVE_ESB_LD_ST_MO; - if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG) - offset |= offset << 4; - val =__x_readq(__x_eoi_page(xd) + offset); #ifdef __LITTLE_ENDIAN__ val >>= 64-8; @@ -77,8 +74,6 @@ static void GLUE(X_PFX,source_eoi)(u32 hw_irq, struct xive_irq_data *xd) /* If the XIVE supports the new "store EOI facility, use it */ if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI) __x_writeq(0, __x_eoi_page(xd) + XIVE_ESB_STORE_EOI); - else if (hw_irq && xd->flags & XIVE_IRQ_FLAG_EOI_FW) - opal_int_eoi(hw_irq); else if (xd->flags & XIVE_IRQ_FLAG_LSI) { /* * For LSIs the HW EOI cycle is used rather than PQ bits, diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index b1abcb816439..288a9820ec01 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -500,11 +500,11 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, vcpu->arch.regs.nip = vcpu->arch.ivpr | vcpu->arch.ivor[priority]; - if (update_esr == true) + if (update_esr) kvmppc_set_esr(vcpu, vcpu->arch.queued_esr); - if (update_dear == true) + if (update_dear) kvmppc_set_dar(vcpu, vcpu->arch.queued_dear); - if (update_epr == true) { + if (update_epr) { if (vcpu->arch.epr_flags & KVMPPC_EPR_USER) kvm_make_request(KVM_REQ_EPR_EXIT, vcpu); else if (vcpu->arch.epr_flags & KVMPPC_EPR_KERNEL) { diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 13999123b735..cf52d26f49cd 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -1087,7 +1087,7 @@ static inline u64 sp_to_dp(u32 fprs) preempt_disable(); enable_kernel_fp(); - asm ("lfs%U1%X1 0,%1; stfd%U0%X0 0,%0" : "=m" (fprd) : "m" (fprs) + asm ("lfs%U1%X1 0,%1; stfd%U0%X0 0,%0" : "=m"UPD_CONSTR (fprd) : "m"UPD_CONSTR (fprs) : "fr0"); preempt_enable(); return fprd; @@ -1099,7 +1099,7 @@ static inline u32 dp_to_sp(u64 fprd) preempt_disable(); enable_kernel_fp(); - asm ("lfd%U1%X1 0,%1; stfs%U0%X0 0,%0" : "=m" (fprs) : "m" (fprd) + asm ("lfd%U1%X1 0,%1; stfs%U0%X0 0,%0" : "=m"UPD_CONSTR (fprs) : "m"UPD_CONSTR (fprd) : "fr0"); preempt_enable(); return fprs; diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index 321c12a9ef6b..1fd31b4b0e13 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c @@ -124,7 +124,7 @@ static void do_stf_entry_barrier_fixups(enum stf_barrier_type types) long *start, *end; int i; - start = PTRRELOC(&__start___stf_entry_barrier_fixup), + start = PTRRELOC(&__start___stf_entry_barrier_fixup); end = PTRRELOC(&__stop___stf_entry_barrier_fixup); instrs[0] = 0x60000000; /* nop */ @@ -176,7 +176,7 @@ static void do_stf_exit_barrier_fixups(enum stf_barrier_type types) long *start, *end; int i; - start = PTRRELOC(&__start___stf_exit_barrier_fixup), + start = PTRRELOC(&__start___stf_exit_barrier_fixup); end = PTRRELOC(&__stop___stf_exit_barrier_fixup); instrs[0] = 0x60000000; /* nop */ @@ -290,9 +290,6 @@ void do_entry_flush_fixups(enum l1d_flush_type types) long *start, *end; int i; - start = PTRRELOC(&__start___entry_flush_fixup); - end = PTRRELOC(&__stop___entry_flush_fixup); - instrs[0] = 0x60000000; /* nop */ instrs[1] = 0x60000000; /* nop */ instrs[2] = 0x60000000; /* nop */ @@ -312,6 +309,8 @@ void do_entry_flush_fixups(enum l1d_flush_type types) if (types & L1D_FLUSH_MTTRIG) instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */ + start = PTRRELOC(&__start___entry_flush_fixup); + end = PTRRELOC(&__stop___entry_flush_fixup); for (i = 0; start < end; start++, i++) { dest = (void *)start + *start; @@ -328,6 +327,25 @@ void do_entry_flush_fixups(enum l1d_flush_type types) patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2])); } + start = PTRRELOC(&__start___scv_entry_flush_fixup); + end = PTRRELOC(&__stop___scv_entry_flush_fixup); + for (; start < end; start++, i++) { + dest = (void *)start + *start; + + pr_devel("patching dest %lx\n", (unsigned long)dest); + + patch_instruction((struct ppc_inst *)dest, ppc_inst(instrs[0])); + + if (types == L1D_FLUSH_FALLBACK) + patch_branch((struct ppc_inst *)(dest + 1), (unsigned long)&scv_entry_flush_fallback, + BRANCH_SET_LINK); + else + patch_instruction((struct ppc_inst *)(dest + 1), ppc_inst(instrs[1])); + + patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2])); + } + + printk(KERN_DEBUG "entry-flush: patched %d locations (%s flush)\n", i, (types == L1D_FLUSH_NONE) ? "no" : (types == L1D_FLUSH_FALLBACK) ? "fallback displacement" : @@ -344,7 +362,7 @@ void do_rfi_flush_fixups(enum l1d_flush_type types) long *start, *end; int i; - start = PTRRELOC(&__start___rfi_flush_fixup), + start = PTRRELOC(&__start___rfi_flush_fixup); end = PTRRELOC(&__stop___rfi_flush_fixup); instrs[0] = 0x60000000; /* nop */ @@ -417,7 +435,7 @@ void do_barrier_nospec_fixups(bool enable) { void *start, *end; - start = PTRRELOC(&__start___barrier_nospec_fixup), + start = PTRRELOC(&__start___barrier_nospec_fixup); end = PTRRELOC(&__stop___barrier_nospec_fixup); do_barrier_nospec_fixups_range(enable, start, end); diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 855457ed09b5..bf7a7d62ae8b 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -32,6 +32,10 @@ extern char system_call_vectored_emulate[]; #define XER_OV32 0x00080000U #define XER_CA32 0x00040000U +#ifdef CONFIG_VSX +#define VSX_REGISTER_XTP(rd) ((((rd) & 1) << 5) | ((rd) & 0xfe)) +#endif + #ifdef CONFIG_PPC_FPU /* * Functions in ldstfp.S @@ -279,6 +283,19 @@ static nokprobe_inline void do_byte_reverse(void *ptr, int nb) up[1] = tmp; break; } + case 32: { + unsigned long *up = (unsigned long *)ptr; + unsigned long tmp; + + tmp = byterev_8(up[0]); + up[0] = byterev_8(up[3]); + up[3] = tmp; + tmp = byterev_8(up[2]); + up[2] = byterev_8(up[1]); + up[1] = tmp; + break; + } + #endif default: WARN_ON_ONCE(1); @@ -709,6 +726,8 @@ void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, reg->d[0] = reg->d[1] = 0; switch (op->element_size) { + case 32: + /* [p]lxvp[x] */ case 16: /* whole vector; lxv[x] or lxvl[l] */ if (size == 0) @@ -717,7 +736,7 @@ void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, if (IS_LE && (op->vsx_flags & VSX_LDLEFT)) rev = !rev; if (rev) - do_byte_reverse(reg, 16); + do_byte_reverse(reg, size); break; case 8: /* scalar loads, lxvd2x, lxvdsx */ @@ -793,6 +812,20 @@ void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg, size = GETSIZE(op->type); switch (op->element_size) { + case 32: + /* [p]stxvp[x] */ + if (size == 0) + break; + if (rev) { + /* reverse 32 bytes */ + buf.d[0] = byterev_8(reg->d[3]); + buf.d[1] = byterev_8(reg->d[2]); + buf.d[2] = byterev_8(reg->d[1]); + buf.d[3] = byterev_8(reg->d[0]); + reg = &buf; + } + memcpy(mem, reg, size); + break; case 16: /* stxv, stxvx, stxvl, stxvll */ if (size == 0) @@ -861,28 +894,43 @@ static nokprobe_inline int do_vsx_load(struct instruction_op *op, bool cross_endian) { int reg = op->reg; - u8 mem[16]; - union vsx_reg buf; + int i, j, nr_vsx_regs; + u8 mem[32]; + union vsx_reg buf[2]; int size = GETSIZE(op->type); if (!address_ok(regs, ea, size) || copy_mem_in(mem, ea, size, regs)) return -EFAULT; - emulate_vsx_load(op, &buf, mem, cross_endian); + nr_vsx_regs = size / sizeof(__vector128); + emulate_vsx_load(op, buf, mem, cross_endian); preempt_disable(); if (reg < 32) { /* FP regs + extensions */ if (regs->msr & MSR_FP) { - load_vsrn(reg, &buf); + for (i = 0; i < nr_vsx_regs; i++) { + j = IS_LE ? nr_vsx_regs - i - 1 : i; + load_vsrn(reg + i, &buf[j].v); + } } else { - current->thread.fp_state.fpr[reg][0] = buf.d[0]; - current->thread.fp_state.fpr[reg][1] = buf.d[1]; + for (i = 0; i < nr_vsx_regs; i++) { + j = IS_LE ? nr_vsx_regs - i - 1 : i; + current->thread.fp_state.fpr[reg + i][0] = buf[j].d[0]; + current->thread.fp_state.fpr[reg + i][1] = buf[j].d[1]; + } } } else { - if (regs->msr & MSR_VEC) - load_vsrn(reg, &buf); - else - current->thread.vr_state.vr[reg - 32] = buf.v; + if (regs->msr & MSR_VEC) { + for (i = 0; i < nr_vsx_regs; i++) { + j = IS_LE ? nr_vsx_regs - i - 1 : i; + load_vsrn(reg + i, &buf[j].v); + } + } else { + for (i = 0; i < nr_vsx_regs; i++) { + j = IS_LE ? nr_vsx_regs - i - 1 : i; + current->thread.vr_state.vr[reg - 32 + i] = buf[j].v; + } + } } preempt_enable(); return 0; @@ -893,30 +941,45 @@ static nokprobe_inline int do_vsx_store(struct instruction_op *op, bool cross_endian) { int reg = op->reg; - u8 mem[16]; - union vsx_reg buf; + int i, j, nr_vsx_regs; + u8 mem[32]; + union vsx_reg buf[2]; int size = GETSIZE(op->type); if (!address_ok(regs, ea, size)) return -EFAULT; + nr_vsx_regs = size / sizeof(__vector128); preempt_disable(); if (reg < 32) { /* FP regs + extensions */ if (regs->msr & MSR_FP) { - store_vsrn(reg, &buf); + for (i = 0; i < nr_vsx_regs; i++) { + j = IS_LE ? nr_vsx_regs - i - 1 : i; + store_vsrn(reg + i, &buf[j].v); + } } else { - buf.d[0] = current->thread.fp_state.fpr[reg][0]; - buf.d[1] = current->thread.fp_state.fpr[reg][1]; + for (i = 0; i < nr_vsx_regs; i++) { + j = IS_LE ? nr_vsx_regs - i - 1 : i; + buf[j].d[0] = current->thread.fp_state.fpr[reg + i][0]; + buf[j].d[1] = current->thread.fp_state.fpr[reg + i][1]; + } } } else { - if (regs->msr & MSR_VEC) - store_vsrn(reg, &buf); - else - buf.v = current->thread.vr_state.vr[reg - 32]; + if (regs->msr & MSR_VEC) { + for (i = 0; i < nr_vsx_regs; i++) { + j = IS_LE ? nr_vsx_regs - i - 1 : i; + store_vsrn(reg + i, &buf[j].v); + } + } else { + for (i = 0; i < nr_vsx_regs; i++) { + j = IS_LE ? nr_vsx_regs - i - 1 : i; + buf[j].v = current->thread.vr_state.vr[reg - 32 + i]; + } + } } preempt_enable(); - emulate_vsx_store(op, &buf, mem, cross_endian); + emulate_vsx_store(op, buf, mem, cross_endian); return copy_mem_out(mem, ea, size, regs); } #endif /* CONFIG_VSX */ @@ -1346,6 +1409,9 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, switch (opcode) { #ifdef __powerpc64__ case 1: + if (!cpu_has_feature(CPU_FTR_ARCH_31)) + return -1; + prefix_r = GET_PREFIX_R(word); ra = GET_PREFIX_RA(suffix); rd = (suffix >> 21) & 0x1f; @@ -2400,6 +2466,14 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->vsx_flags = VSX_SPLAT; break; + case 333: /* lxvpx */ + if (!cpu_has_feature(CPU_FTR_ARCH_31)) + return -1; + op->reg = VSX_REGISTER_XTP(rd); + op->type = MKOP(LOAD_VSX, 0, 32); + op->element_size = 32; + break; + case 364: /* lxvwsx */ op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 4); @@ -2428,6 +2502,13 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, VSX_CHECK_VEC; break; } + case 461: /* stxvpx */ + if (!cpu_has_feature(CPU_FTR_ARCH_31)) + return -1; + op->reg = VSX_REGISTER_XTP(rd); + op->type = MKOP(STORE_VSX, 0, 32); + op->element_size = 32; + break; case 524: /* lxsspx */ op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 4); @@ -2669,6 +2750,22 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, #endif #ifdef CONFIG_VSX + case 6: + if (!cpu_has_feature(CPU_FTR_ARCH_31)) + return -1; + op->ea = dqform_ea(word, regs); + op->reg = VSX_REGISTER_XTP(rd); + op->element_size = 32; + switch (word & 0xf) { + case 0: /* lxvp */ + op->type = MKOP(LOAD_VSX, 0, 32); + break; + case 1: /* stxvp */ + op->type = MKOP(STORE_VSX, 0, 32); + break; + } + break; + case 61: /* stfdp, lxv, stxsd, stxssp, stxv */ switch (word & 7) { case 0: /* stfdp with LSB of DS field = 0 */ @@ -2733,6 +2830,9 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, } break; case 1: /* Prefixed instructions */ + if (!cpu_has_feature(CPU_FTR_ARCH_31)) + return -1; + prefix_r = GET_PREFIX_R(word); ra = GET_PREFIX_RA(suffix); op->update_reg = ra; @@ -2751,6 +2851,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 41: /* plwa */ op->type = MKOP(LOAD, PREFIXED | SIGNEXT, 4); break; +#ifdef CONFIG_VSX case 42: /* plxsd */ op->reg = rd + 32; op->type = MKOP(LOAD_VSX, PREFIXED, 8); @@ -2791,18 +2892,33 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->element_size = 16; op->vsx_flags = VSX_CHECK_VEC; break; +#endif /* CONFIG_VSX */ case 56: /* plq */ op->type = MKOP(LOAD, PREFIXED, 16); break; case 57: /* pld */ op->type = MKOP(LOAD, PREFIXED, 8); break; - case 60: /* stq */ +#ifdef CONFIG_VSX + case 58: /* plxvp */ + op->reg = VSX_REGISTER_XTP(rd); + op->type = MKOP(LOAD_VSX, PREFIXED, 32); + op->element_size = 32; + break; +#endif /* CONFIG_VSX */ + case 60: /* pstq */ op->type = MKOP(STORE, PREFIXED, 16); break; case 61: /* pstd */ op->type = MKOP(STORE, PREFIXED, 8); break; +#ifdef CONFIG_VSX + case 62: /* pstxvp */ + op->reg = VSX_REGISTER_XTP(rd); + op->type = MKOP(STORE_VSX, PREFIXED, 32); + op->element_size = 32; + break; +#endif /* CONFIG_VSX */ } break; case 1: /* Type 01 Eight-Byte Register-to-Register */ diff --git a/arch/powerpc/lib/test_emulate_step.c b/arch/powerpc/lib/test_emulate_step.c index 0a201b771477..783d1b85ecfe 100644 --- a/arch/powerpc/lib/test_emulate_step.c +++ b/arch/powerpc/lib/test_emulate_step.c @@ -612,6 +612,273 @@ static void __init test_lxvd2x_stxvd2x(void) } #endif /* CONFIG_VSX */ +#ifdef CONFIG_VSX +static void __init test_lxvp_stxvp(void) +{ + struct pt_regs regs; + union { + vector128 a; + u32 b[4]; + } c[2]; + u32 cached_b[8]; + int stepped = -1; + + if (!cpu_has_feature(CPU_FTR_ARCH_31)) { + show_result("lxvp", "SKIP (!CPU_FTR_ARCH_31)"); + show_result("stxvp", "SKIP (!CPU_FTR_ARCH_31)"); + return; + } + + init_pt_regs(®s); + + /*** lxvp ***/ + + cached_b[0] = c[0].b[0] = 18233; + cached_b[1] = c[0].b[1] = 34863571; + cached_b[2] = c[0].b[2] = 834; + cached_b[3] = c[0].b[3] = 6138911; + cached_b[4] = c[1].b[0] = 1234; + cached_b[5] = c[1].b[1] = 5678; + cached_b[6] = c[1].b[2] = 91011; + cached_b[7] = c[1].b[3] = 121314; + + regs.gpr[4] = (unsigned long)&c[0].a; + + /* + * lxvp XTp,DQ(RA) + * XTp = 32xTX + 2xTp + * let TX=1 Tp=1 RA=4 DQ=0 + */ + stepped = emulate_step(®s, ppc_inst(PPC_RAW_LXVP(34, 4, 0))); + + if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) { + show_result("lxvp", "PASS"); + } else { + if (!cpu_has_feature(CPU_FTR_VSX)) + show_result("lxvp", "PASS (!CPU_FTR_VSX)"); + else + show_result("lxvp", "FAIL"); + } + + /*** stxvp ***/ + + c[0].b[0] = 21379463; + c[0].b[1] = 87; + c[0].b[2] = 374234; + c[0].b[3] = 4; + c[1].b[0] = 90; + c[1].b[1] = 122; + c[1].b[2] = 555; + c[1].b[3] = 32144; + + /* + * stxvp XSp,DQ(RA) + * XSp = 32xSX + 2xSp + * let SX=1 Sp=1 RA=4 DQ=0 + */ + stepped = emulate_step(®s, ppc_inst(PPC_RAW_STXVP(34, 4, 0))); + + if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] && + cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] && + cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] && + cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] && + cpu_has_feature(CPU_FTR_VSX)) { + show_result("stxvp", "PASS"); + } else { + if (!cpu_has_feature(CPU_FTR_VSX)) + show_result("stxvp", "PASS (!CPU_FTR_VSX)"); + else + show_result("stxvp", "FAIL"); + } +} +#else +static void __init test_lxvp_stxvp(void) +{ + show_result("lxvp", "SKIP (CONFIG_VSX is not set)"); + show_result("stxvp", "SKIP (CONFIG_VSX is not set)"); +} +#endif /* CONFIG_VSX */ + +#ifdef CONFIG_VSX +static void __init test_lxvpx_stxvpx(void) +{ + struct pt_regs regs; + union { + vector128 a; + u32 b[4]; + } c[2]; + u32 cached_b[8]; + int stepped = -1; + + if (!cpu_has_feature(CPU_FTR_ARCH_31)) { + show_result("lxvpx", "SKIP (!CPU_FTR_ARCH_31)"); + show_result("stxvpx", "SKIP (!CPU_FTR_ARCH_31)"); + return; + } + + init_pt_regs(®s); + + /*** lxvpx ***/ + + cached_b[0] = c[0].b[0] = 18233; + cached_b[1] = c[0].b[1] = 34863571; + cached_b[2] = c[0].b[2] = 834; + cached_b[3] = c[0].b[3] = 6138911; + cached_b[4] = c[1].b[0] = 1234; + cached_b[5] = c[1].b[1] = 5678; + cached_b[6] = c[1].b[2] = 91011; + cached_b[7] = c[1].b[3] = 121314; + + regs.gpr[3] = (unsigned long)&c[0].a; + regs.gpr[4] = 0; + + /* + * lxvpx XTp,RA,RB + * XTp = 32xTX + 2xTp + * let TX=1 Tp=1 RA=3 RB=4 + */ + stepped = emulate_step(®s, ppc_inst(PPC_RAW_LXVPX(34, 3, 4))); + + if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) { + show_result("lxvpx", "PASS"); + } else { + if (!cpu_has_feature(CPU_FTR_VSX)) + show_result("lxvpx", "PASS (!CPU_FTR_VSX)"); + else + show_result("lxvpx", "FAIL"); + } + + /*** stxvpx ***/ + + c[0].b[0] = 21379463; + c[0].b[1] = 87; + c[0].b[2] = 374234; + c[0].b[3] = 4; + c[1].b[0] = 90; + c[1].b[1] = 122; + c[1].b[2] = 555; + c[1].b[3] = 32144; + + /* + * stxvpx XSp,RA,RB + * XSp = 32xSX + 2xSp + * let SX=1 Sp=1 RA=3 RB=4 + */ + stepped = emulate_step(®s, ppc_inst(PPC_RAW_STXVPX(34, 3, 4))); + + if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] && + cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] && + cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] && + cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] && + cpu_has_feature(CPU_FTR_VSX)) { + show_result("stxvpx", "PASS"); + } else { + if (!cpu_has_feature(CPU_FTR_VSX)) + show_result("stxvpx", "PASS (!CPU_FTR_VSX)"); + else + show_result("stxvpx", "FAIL"); + } +} +#else +static void __init test_lxvpx_stxvpx(void) +{ + show_result("lxvpx", "SKIP (CONFIG_VSX is not set)"); + show_result("stxvpx", "SKIP (CONFIG_VSX is not set)"); +} +#endif /* CONFIG_VSX */ + +#ifdef CONFIG_VSX +static void __init test_plxvp_pstxvp(void) +{ + struct ppc_inst instr; + struct pt_regs regs; + union { + vector128 a; + u32 b[4]; + } c[2]; + u32 cached_b[8]; + int stepped = -1; + + if (!cpu_has_feature(CPU_FTR_ARCH_31)) { + show_result("plxvp", "SKIP (!CPU_FTR_ARCH_31)"); + show_result("pstxvp", "SKIP (!CPU_FTR_ARCH_31)"); + return; + } + + /*** plxvp ***/ + + cached_b[0] = c[0].b[0] = 18233; + cached_b[1] = c[0].b[1] = 34863571; + cached_b[2] = c[0].b[2] = 834; + cached_b[3] = c[0].b[3] = 6138911; + cached_b[4] = c[1].b[0] = 1234; + cached_b[5] = c[1].b[1] = 5678; + cached_b[6] = c[1].b[2] = 91011; + cached_b[7] = c[1].b[3] = 121314; + + init_pt_regs(®s); + regs.gpr[3] = (unsigned long)&c[0].a; + + /* + * plxvp XTp,D(RA),R + * XTp = 32xTX + 2xTp + * let RA=3 R=0 D=d0||d1=0 R=0 Tp=1 TX=1 + */ + instr = ppc_inst_prefix(PPC_RAW_PLXVP(34, 0, 3, 0) >> 32, + PPC_RAW_PLXVP(34, 0, 3, 0) & 0xffffffff); + + stepped = emulate_step(®s, instr); + if (stepped == 1 && cpu_has_feature(CPU_FTR_VSX)) { + show_result("plxvp", "PASS"); + } else { + if (!cpu_has_feature(CPU_FTR_VSX)) + show_result("plxvp", "PASS (!CPU_FTR_VSX)"); + else + show_result("plxvp", "FAIL"); + } + + /*** pstxvp ***/ + + c[0].b[0] = 21379463; + c[0].b[1] = 87; + c[0].b[2] = 374234; + c[0].b[3] = 4; + c[1].b[0] = 90; + c[1].b[1] = 122; + c[1].b[2] = 555; + c[1].b[3] = 32144; + + /* + * pstxvp XSp,D(RA),R + * XSp = 32xSX + 2xSp + * let RA=3 D=d0||d1=0 R=0 Sp=1 SX=1 + */ + instr = ppc_inst_prefix(PPC_RAW_PSTXVP(34, 0, 3, 0) >> 32, + PPC_RAW_PSTXVP(34, 0, 3, 0) & 0xffffffff); + + stepped = emulate_step(®s, instr); + + if (stepped == 1 && cached_b[0] == c[0].b[0] && cached_b[1] == c[0].b[1] && + cached_b[2] == c[0].b[2] && cached_b[3] == c[0].b[3] && + cached_b[4] == c[1].b[0] && cached_b[5] == c[1].b[1] && + cached_b[6] == c[1].b[2] && cached_b[7] == c[1].b[3] && + cpu_has_feature(CPU_FTR_VSX)) { + show_result("pstxvp", "PASS"); + } else { + if (!cpu_has_feature(CPU_FTR_VSX)) + show_result("pstxvp", "PASS (!CPU_FTR_VSX)"); + else + show_result("pstxvp", "FAIL"); + } +} +#else +static void __init test_plxvp_pstxvp(void) +{ + show_result("plxvp", "SKIP (CONFIG_VSX is not set)"); + show_result("pstxvp", "SKIP (CONFIG_VSX is not set)"); +} +#endif /* CONFIG_VSX */ + static void __init run_tests_load_store(void) { test_ld(); @@ -628,6 +895,9 @@ static void __init run_tests_load_store(void) test_plfd_pstfd(); test_lvx_stvx(); test_lxvd2x_stxvd2x(); + test_lxvp_stxvp(); + test_lxvpx_stxvpx(); + test_plxvp_pstxvp(); } struct compute_test { diff --git a/arch/powerpc/mm/book3s32/Makefile b/arch/powerpc/mm/book3s32/Makefile index 1732eaa740a9..3f972db17761 100644 --- a/arch/powerpc/mm/book3s32/Makefile +++ b/arch/powerpc/mm/book3s32/Makefile @@ -6,4 +6,4 @@ ifdef CONFIG_KASAN CFLAGS_mmu.o += -DDISABLE_BRANCH_PROFILING endif -obj-y += mmu.o hash_low.o mmu_context.o tlb.o +obj-y += mmu.o hash_low.o mmu_context.o tlb.o nohash_low.o diff --git a/arch/powerpc/mm/book3s32/hash_low.S b/arch/powerpc/mm/book3s32/hash_low.S index b2c912e517b9..0e6dc830c38b 100644 --- a/arch/powerpc/mm/book3s32/hash_low.S +++ b/arch/powerpc/mm/book3s32/hash_low.S @@ -26,12 +26,11 @@ #include <asm/feature-fixups.h> #include <asm/code-patching-asm.h> -#ifdef CONFIG_SMP - .section .bss - .align 2 -mmu_hash_lock: - .space 4 -#endif /* CONFIG_SMP */ +#ifdef CONFIG_PTE_64BIT +#define PTE_FLAGS_OFFSET 4 /* offset of PTE flags, in bytes */ +#else +#define PTE_FLAGS_OFFSET 0 +#endif /* * Load a PTE into the hash table, if possible. @@ -65,13 +64,14 @@ _GLOBAL(hash_page) /* Get PTE (linux-style) and check access */ lis r0, TASK_SIZE@h /* check if kernel address */ cmplw 0,r4,r0 + mfspr r8,SPRN_SPRG_THREAD /* current task's THREAD (phys) */ ori r3,r3,_PAGE_USER|_PAGE_PRESENT /* test low addresses as user */ - mfspr r5, SPRN_SPRG_PGDIR /* phys page-table root */ + lwz r5,PGDIR(r8) /* virt page-table root */ blt+ 112f /* assume user more likely */ - lis r5, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ - addi r5 ,r5 ,(swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ + lis r5,swapper_pg_dir@ha /* if kernel address, use */ + addi r5,r5,swapper_pg_dir@l /* kernel page table */ rlwimi r3,r9,32-12,29,29 /* MSR_PR -> _PAGE_USER */ -112: +112: tophys(r5, r5) #ifndef CONFIG_PTE_64BIT rlwimi r5,r4,12,20,29 /* insert top 10 bits of address */ lwz r8,0(r5) /* get pmd entry */ @@ -94,25 +94,33 @@ _GLOBAL(hash_page) rlwimi r8,r4,22,20,29 /* insert next 10 bits of address */ #else rlwimi r8,r4,23,20,28 /* compute pte address */ + /* + * If PTE_64BIT is set, the low word is the flags word; use that + * word for locking since it contains all the interesting bits. + */ + addi r8,r8,PTE_FLAGS_OFFSET #endif - rlwinm r0,r3,32-3,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ - ori r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE /* * Update the linux PTE atomically. We do the lwarx up-front * because almost always, there won't be a permission violation * and there won't already be an HPTE, and thus we will have * to update the PTE to set _PAGE_HASHPTE. -- paulus. - * - * If PTE_64BIT is set, the low word is the flags word; use that - * word for locking since it contains all the interesting bits. */ -#if (PTE_FLAGS_OFFSET != 0) - addi r8,r8,PTE_FLAGS_OFFSET -#endif .Lretry: lwarx r6,0,r8 /* get linux-style pte, flag word */ +#ifdef CONFIG_PPC_KUAP + mfsrin r5,r4 + rlwinm r0,r9,28,_PAGE_RW /* MSR[PR] => _PAGE_RW */ + rlwinm r5,r5,12,_PAGE_RW /* Ks => _PAGE_RW */ + andc r5,r5,r0 /* Ks & ~MSR[PR] */ + andc r5,r6,r5 /* Clear _PAGE_RW when Ks = 1 && MSR[PR] = 0 */ + andc. r5,r3,r5 /* check access & ~permission */ +#else andc. r5,r3,r6 /* check access & ~permission */ +#endif + rlwinm r0,r3,32-3,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ + ori r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE #ifdef CONFIG_SMP bne- .Lhash_page_out /* return if access not permitted */ #else @@ -179,12 +187,6 @@ _GLOBAL(add_hash_page) mflr r0 stw r0,4(r1) - /* Convert context and va to VSID */ - mulli r3,r3,897*16 /* multiply context by context skew */ - rlwinm r0,r4,4,28,31 /* get ESID (top 4 bits of va) */ - mulli r0,r0,0x111 /* multiply by ESID skew */ - add r3,r3,r0 /* note create_hpte trims to 24 bits */ - #ifdef CONFIG_SMP lwz r8,TASK_CPU(r2) /* to go in mmu_hash_lock */ oris r8,r8,12 @@ -248,6 +250,12 @@ _GLOBAL(add_hash_page) stwcx. r5,0,r8 bne- 1b + /* Convert context and va to VSID */ + mulli r3,r3,897*16 /* multiply context by context skew */ + rlwinm r0,r4,4,28,31 /* get ESID (top 4 bits of va) */ + mulli r0,r0,0x111 /* multiply by ESID skew */ + add r3,r3,r0 /* note create_hpte trims to 24 bits */ + bl create_hpte 9: @@ -350,11 +358,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) beq+ 10f /* no PTE: go look for an empty slot */ tlbie r4 - lis r4, (htab_hash_searches - PAGE_OFFSET)@ha - lwz r6, (htab_hash_searches - PAGE_OFFSET)@l(r4) - addi r6,r6,1 /* count how many searches we do */ - stw r6, (htab_hash_searches - PAGE_OFFSET)@l(r4) - /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */ mtctr r0 addi r4,r3,-HPTE_SIZE @@ -384,12 +387,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ beq+ .Lfound_empty - /* update counter of times that the primary PTEG is full */ - lis r4, (primary_pteg_full - PAGE_OFFSET)@ha - lwz r6, (primary_pteg_full - PAGE_OFFSET)@l(r4) - addi r6,r6,1 - stw r6, (primary_pteg_full - PAGE_OFFSET)@l(r4) - patch_site 0f, patch__hash_page_C /* Search the secondary PTEG for an empty slot */ ori r5,r5,PTE_H /* set H (secondary hash) bit */ @@ -411,30 +408,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) * and we know there is a definite (although small) speed * advantage to putting the PTE in the primary PTEG, we always * put the PTE in the primary PTEG. - * - * In addition, we skip any slot that is mapping kernel text in - * order to avoid a deadlock when not using BAT mappings if - * trying to hash in the kernel hash code itself after it has - * already taken the hash table lock. This works in conjunction - * with pre-faulting of the kernel text. - * - * If the hash table bucket is full of kernel text entries, we'll - * lockup here but that shouldn't happen */ -1: lis r4, (next_slot - PAGE_OFFSET)@ha /* get next evict slot */ + lis r4, (next_slot - PAGE_OFFSET)@ha /* get next evict slot */ lwz r6, (next_slot - PAGE_OFFSET)@l(r4) addi r6,r6,HPTE_SIZE /* search for candidate */ andi. r6,r6,7*HPTE_SIZE stw r6,next_slot@l(r4) add r4,r3,r6 - LDPTE r0,HPTE_SIZE/2(r4) /* get PTE second word */ - clrrwi r0,r0,12 - lis r6,etext@h - ori r6,r6,etext@l /* get etext */ - tophys(r6,r6) - cmpl cr0,r0,r6 /* compare and try again */ - blt 1b #ifndef CONFIG_SMP /* Store PTE in PTEG */ @@ -482,10 +463,6 @@ _ASM_NOKPROBE_SYMBOL(create_hpte) .align 2 next_slot: .space 4 -primary_pteg_full: - .space 4 -htab_hash_searches: - .space 4 .previous /* @@ -517,8 +494,9 @@ _GLOBAL(flush_hash_pages) rlwimi r5,r4,22,20,29 #else rlwimi r5,r4,23,20,28 + addi r5,r5,PTE_FLAGS_OFFSET #endif -1: lwz r0,PTE_FLAGS_OFFSET(r5) +1: lwz r0,0(r5) cmpwi cr1,r6,1 andi. r0,r0,_PAGE_HASHPTE bne 2f @@ -562,9 +540,6 @@ _GLOBAL(flush_hash_pages) * already clear, we're done (for this pte). If not, * clear it (atomically) and proceed. -- paulus. */ -#if (PTE_FLAGS_OFFSET != 0) - addi r5,r5,PTE_FLAGS_OFFSET -#endif 33: lwarx r8,0,r5 /* fetch the pte flags word */ andi. r0,r8,_PAGE_HASHPTE beq 8f /* done if HASHPTE is already clear */ @@ -633,77 +608,3 @@ _GLOBAL(flush_hash_pages) .previous EXPORT_SYMBOL(flush_hash_pages) _ASM_NOKPROBE_SYMBOL(flush_hash_pages) - -/* - * Flush an entry from the TLB - */ -_GLOBAL(_tlbie) -#ifdef CONFIG_SMP - lwz r8,TASK_CPU(r2) - oris r8,r8,11 - mfmsr r10 - rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ - rlwinm r0,r0,0,28,26 /* clear DR */ - mtmsr r0 - isync - lis r9,mmu_hash_lock@h - ori r9,r9,mmu_hash_lock@l - tophys(r9,r9) -10: lwarx r7,0,r9 - cmpwi 0,r7,0 - bne- 10b - stwcx. r8,0,r9 - bne- 10b - eieio - tlbie r3 - sync - TLBSYNC - li r0,0 - stw r0,0(r9) /* clear mmu_hash_lock */ - mtmsr r10 - isync -#else /* CONFIG_SMP */ - tlbie r3 - sync -#endif /* CONFIG_SMP */ - blr -_ASM_NOKPROBE_SYMBOL(_tlbie) - -/* - * Flush the entire TLB. 603/603e only - */ -_GLOBAL(_tlbia) -#if defined(CONFIG_SMP) - lwz r8,TASK_CPU(r2) - oris r8,r8,10 - mfmsr r10 - rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ - rlwinm r0,r0,0,28,26 /* clear DR */ - mtmsr r0 - isync - lis r9,mmu_hash_lock@h - ori r9,r9,mmu_hash_lock@l - tophys(r9,r9) -10: lwarx r7,0,r9 - cmpwi 0,r7,0 - bne- 10b - stwcx. r8,0,r9 - bne- 10b -#endif /* CONFIG_SMP */ - li r5, 32 - lis r4, KERNELBASE@h - mtctr r5 - sync -0: tlbie r4 - addi r4, r4, 0x1000 - bdnz 0b - sync -#ifdef CONFIG_SMP - TLBSYNC - li r0,0 - stw r0,0(r9) /* clear mmu_hash_lock */ - mtmsr r10 - isync -#endif /* CONFIG_SMP */ - blr -_ASM_NOKPROBE_SYMBOL(_tlbia) diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c index a59e7ec98180..859e5bd603ac 100644 --- a/arch/powerpc/mm/book3s32/mmu.c +++ b/arch/powerpc/mm/book3s32/mmu.c @@ -33,19 +33,23 @@ u8 __initdata early_hash[SZ_256K] __aligned(SZ_256K) = {0}; -struct hash_pte *Hash; -static unsigned long Hash_size, Hash_mask; -unsigned long _SDR1; -static unsigned int hash_mb, hash_mb2; +static struct hash_pte __initdata *Hash = (struct hash_pte *)early_hash; +static unsigned long __initdata Hash_size, Hash_mask; +static unsigned int __initdata hash_mb, hash_mb2; +unsigned long __initdata _SDR1; struct ppc_bat BATS[8][2]; /* 8 pairs of IBAT, DBAT */ -struct batrange { /* stores address ranges mapped by BATs */ +static struct batrange { /* stores address ranges mapped by BATs */ unsigned long start; unsigned long limit; phys_addr_t phys; } bat_addrs[8]; +#ifdef CONFIG_SMP +unsigned long mmu_hash_lock; +#endif + /* * Return PA for this VA if it is mapped by a BAT, or 0 */ @@ -157,11 +161,9 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top) unsigned long done; unsigned long border = (unsigned long)__init_begin - PAGE_OFFSET; - if (__map_without_bats) { - pr_debug("RAM mapped without BATs\n"); - return base; - } - if (debug_pagealloc_enabled()) { + + if (debug_pagealloc_enabled() || __map_without_bats) { + pr_debug_once("Read-Write memory mapped without BATs\n"); if (base >= border) return base; if (top >= border) @@ -304,11 +306,11 @@ void __init setbat(int index, unsigned long virt, phys_addr_t phys, /* * Preload a translation in the hash table */ -void hash_preload(struct mm_struct *mm, unsigned long ea) +static void hash_preload(struct mm_struct *mm, unsigned long ea) { pmd_t *pmd; - if (!Hash) + if (!mmu_has_feature(MMU_FTR_HPTE_TABLE)) return; pmd = pmd_off(mm, ea); if (!pmd_none(*pmd)) @@ -469,3 +471,7 @@ void __init setup_kuap(bool disabled) pr_warn("KUAP cannot be disabled yet on 6xx when compiled in\n"); } #endif + +void __init early_init_mmu(void) +{ +} diff --git a/arch/powerpc/mm/book3s32/nohash_low.S b/arch/powerpc/mm/book3s32/nohash_low.S new file mode 100644 index 000000000000..19f418b0ed2d --- /dev/null +++ b/arch/powerpc/mm/book3s32/nohash_low.S @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * This file contains low-level assembler routines for managing + * the PowerPC 603 tlb invalidation. + */ + +#include <asm/page.h> +#include <asm/ppc_asm.h> +#include <asm/asm-offsets.h> + +/* + * Flush an entry from the TLB + */ +#ifdef CONFIG_SMP +_GLOBAL(_tlbie) + lwz r8,TASK_CPU(r2) + oris r8,r8,11 + mfmsr r10 + rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ + rlwinm r0,r0,0,28,26 /* clear DR */ + mtmsr r0 + isync + lis r9,mmu_hash_lock@h + ori r9,r9,mmu_hash_lock@l + tophys(r9,r9) +10: lwarx r7,0,r9 + cmpwi 0,r7,0 + bne- 10b + stwcx. r8,0,r9 + bne- 10b + eieio + tlbie r3 + sync + TLBSYNC + li r0,0 + stw r0,0(r9) /* clear mmu_hash_lock */ + mtmsr r10 + isync + blr +_ASM_NOKPROBE_SYMBOL(_tlbie) +#endif /* CONFIG_SMP */ + +/* + * Flush the entire TLB. 603/603e only + */ +_GLOBAL(_tlbia) +#if defined(CONFIG_SMP) + lwz r8,TASK_CPU(r2) + oris r8,r8,10 + mfmsr r10 + rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ + rlwinm r0,r0,0,28,26 /* clear DR */ + mtmsr r0 + isync + lis r9,mmu_hash_lock@h + ori r9,r9,mmu_hash_lock@l + tophys(r9,r9) +10: lwarx r7,0,r9 + cmpwi 0,r7,0 + bne- 10b + stwcx. r8,0,r9 + bne- 10b +#endif /* CONFIG_SMP */ + li r5, 32 + lis r4, KERNELBASE@h + mtctr r5 + sync +0: tlbie r4 + addi r4, r4, 0x1000 + bdnz 0b + sync +#ifdef CONFIG_SMP + TLBSYNC + li r0,0 + stw r0,0(r9) /* clear mmu_hash_lock */ + mtmsr r10 + isync +#endif /* CONFIG_SMP */ + blr +_ASM_NOKPROBE_SYMBOL(_tlbia) diff --git a/arch/powerpc/mm/book3s32/tlb.c b/arch/powerpc/mm/book3s32/tlb.c index b6c7427daa6f..19f0ef950d77 100644 --- a/arch/powerpc/mm/book3s32/tlb.c +++ b/arch/powerpc/mm/book3s32/tlb.c @@ -30,35 +30,6 @@ #include <mm/mmu_decl.h> /* - * Called when unmapping pages to flush entries from the TLB/hash table. - */ -void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long addr) -{ - unsigned long ptephys; - - if (Hash) { - ptephys = __pa(ptep) & PAGE_MASK; - flush_hash_pages(mm->context.id, addr, ptephys, 1); - } -} -EXPORT_SYMBOL(flush_hash_entry); - -/* - * Called at the end of a mmu_gather operation to make sure the - * TLB flush is completely done. - */ -void tlb_flush(struct mmu_gather *tlb) -{ - if (!Hash) { - /* - * 603 needs to flush the whole TLB here since - * it doesn't use a hash table. - */ - _tlbia(); - } -} - -/* * TLB flushing: * * - flush_tlb_mm(mm) flushes the specified mm context TLB's @@ -71,8 +42,12 @@ void tlb_flush(struct mmu_gather *tlb) * -- Cort */ -static void flush_range(struct mm_struct *mm, unsigned long start, - unsigned long end) +/* + * For each address in the range, find the pte for the address + * and check _PAGE_HASHPTE bit; if it is set, find and destroy + * the corresponding HPTE. + */ +void hash__flush_range(struct mm_struct *mm, unsigned long start, unsigned long end) { pmd_t *pmd; unsigned long pmd_end; @@ -80,13 +55,6 @@ static void flush_range(struct mm_struct *mm, unsigned long start, unsigned int ctx = mm->context.id; start &= PAGE_MASK; - if (!Hash) { - if (end - start <= PAGE_SIZE) - _tlbie(start); - else - _tlbia(); - return; - } if (start >= end) return; end = (end - 1) | ~PAGE_MASK; @@ -105,28 +73,15 @@ static void flush_range(struct mm_struct *mm, unsigned long start, ++pmd; } } - -/* - * Flush kernel TLB entries in the given range - */ -void flush_tlb_kernel_range(unsigned long start, unsigned long end) -{ - flush_range(&init_mm, start, end); -} -EXPORT_SYMBOL(flush_tlb_kernel_range); +EXPORT_SYMBOL(hash__flush_range); /* * Flush all the (user) entries for the address space described by mm. */ -void flush_tlb_mm(struct mm_struct *mm) +void hash__flush_tlb_mm(struct mm_struct *mm) { struct vm_area_struct *mp; - if (!Hash) { - _tlbia(); - return; - } - /* * It is safe to go down the mm's list of vmas when called * from dup_mmap, holding mmap_lock. It would also be safe from @@ -134,38 +89,18 @@ void flush_tlb_mm(struct mm_struct *mm) * but it seems dup_mmap is the only SMP case which gets here. */ for (mp = mm->mmap; mp != NULL; mp = mp->vm_next) - flush_range(mp->vm_mm, mp->vm_start, mp->vm_end); + hash__flush_range(mp->vm_mm, mp->vm_start, mp->vm_end); } -EXPORT_SYMBOL(flush_tlb_mm); +EXPORT_SYMBOL(hash__flush_tlb_mm); -void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) +void hash__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) { struct mm_struct *mm; pmd_t *pmd; - if (!Hash) { - _tlbie(vmaddr); - return; - } mm = (vmaddr < TASK_SIZE)? vma->vm_mm: &init_mm; pmd = pmd_off(mm, vmaddr); if (!pmd_none(*pmd)) flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1); } -EXPORT_SYMBOL(flush_tlb_page); - -/* - * For each address in the range, find the pte for the address - * and check _PAGE_HASHPTE bit; if it is set, find and destroy - * the corresponding HPTE. - */ -void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - flush_range(vma->vm_mm, start, end); -} -EXPORT_SYMBOL(flush_tlb_range); - -void __init early_init_mmu(void) -{ -} +EXPORT_SYMBOL(hash__flush_tlb_page); diff --git a/arch/powerpc/mm/book3s64/Makefile b/arch/powerpc/mm/book3s64/Makefile index fd393b8be14f..1b56d3af47d4 100644 --- a/arch/powerpc/mm/book3s64/Makefile +++ b/arch/powerpc/mm/book3s64/Makefile @@ -17,7 +17,7 @@ endif obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += hash_hugepage.o obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage_prot.o obj-$(CONFIG_SPAPR_TCE_IOMMU) += iommu_api.o -obj-$(CONFIG_PPC_MEM_KEYS) += pkeys.o +obj-$(CONFIG_PPC_PKEY) += pkeys.o # Instrumenting the SLB fault path can lead to duplicate SLB entries KCOV_INSTRUMENT_slb.o := n diff --git a/arch/powerpc/mm/book3s64/hash_4k.c b/arch/powerpc/mm/book3s64/hash_4k.c index 22e787123cdf..7de1a8a0c62a 100644 --- a/arch/powerpc/mm/book3s64/hash_4k.c +++ b/arch/powerpc/mm/book3s64/hash_4k.c @@ -54,7 +54,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, * PP bits. _PAGE_USER is already PP bit 0x2, so we only * need to add in 0x1 if it's a read-only user page */ - rflags = htab_convert_pte_flags(new_pte); + rflags = htab_convert_pte_flags(new_pte, flags); rpte = __real_pte(__pte(old_pte), ptep, PTRS_PER_PTE); if (cpu_has_feature(CPU_FTR_NOEXECUTE) && diff --git a/arch/powerpc/mm/book3s64/hash_64k.c b/arch/powerpc/mm/book3s64/hash_64k.c index 7084ce2951e6..998c6817ed47 100644 --- a/arch/powerpc/mm/book3s64/hash_64k.c +++ b/arch/powerpc/mm/book3s64/hash_64k.c @@ -72,7 +72,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, * Handle the subpage protection bits */ subpg_pte = new_pte & ~subpg_prot; - rflags = htab_convert_pte_flags(subpg_pte); + rflags = htab_convert_pte_flags(subpg_pte, flags); if (cpu_has_feature(CPU_FTR_NOEXECUTE) && !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) { @@ -260,7 +260,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access, new_pte |= _PAGE_DIRTY; } while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte))); - rflags = htab_convert_pte_flags(new_pte); + rflags = htab_convert_pte_flags(new_pte, flags); rpte = __real_pte(__pte(old_pte), ptep, PTRS_PER_PTE); if (cpu_has_feature(CPU_FTR_NOEXECUTE) && diff --git a/arch/powerpc/mm/book3s64/hash_hugepage.c b/arch/powerpc/mm/book3s64/hash_hugepage.c index 440823797de7..c0fabe6c5a12 100644 --- a/arch/powerpc/mm/book3s64/hash_hugepage.c +++ b/arch/powerpc/mm/book3s64/hash_hugepage.c @@ -57,7 +57,7 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid, if (!(old_pmd & (H_PAGE_THP_HUGE | _PAGE_DEVMAP))) return 0; - rflags = htab_convert_pte_flags(new_pmd); + rflags = htab_convert_pte_flags(new_pmd, flags); #if 0 if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) { diff --git a/arch/powerpc/mm/book3s64/hash_hugetlbpage.c b/arch/powerpc/mm/book3s64/hash_hugetlbpage.c index 964467b3a776..b5e9fff8c217 100644 --- a/arch/powerpc/mm/book3s64/hash_hugetlbpage.c +++ b/arch/powerpc/mm/book3s64/hash_hugetlbpage.c @@ -70,7 +70,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, if (old_pte & (H_PAGE_THP_HUGE | _PAGE_DEVMAP)) return 0; - rflags = htab_convert_pte_flags(new_pte); + rflags = htab_convert_pte_flags(new_pte, flags); if (unlikely(mmu_psize == MMU_PAGE_16G)) offset = PTRS_PER_PUD; else diff --git a/arch/powerpc/mm/book3s64/hash_pgtable.c b/arch/powerpc/mm/book3s64/hash_pgtable.c index fd9c7f91b092..567e0c6b3978 100644 --- a/arch/powerpc/mm/book3s64/hash_pgtable.c +++ b/arch/powerpc/mm/book3s64/hash_pgtable.c @@ -443,7 +443,7 @@ void hash__mark_initmem_nx(void) start = (unsigned long)__init_begin; end = (unsigned long)__init_end; - pp = htab_convert_pte_flags(pgprot_val(PAGE_KERNEL)); + pp = htab_convert_pte_flags(pgprot_val(PAGE_KERNEL), HPTE_USE_KERNEL_KEY); WARN_ON(!hash__change_memory_range(start, end, pp)); } diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c index 24702c0a92e0..73b06adb6eeb 100644 --- a/arch/powerpc/mm/book3s64/hash_utils.c +++ b/arch/powerpc/mm/book3s64/hash_utils.c @@ -112,6 +112,7 @@ int mmu_linear_psize = MMU_PAGE_4K; EXPORT_SYMBOL_GPL(mmu_linear_psize); int mmu_virtual_psize = MMU_PAGE_4K; int mmu_vmalloc_psize = MMU_PAGE_4K; +EXPORT_SYMBOL_GPL(mmu_vmalloc_psize); #ifdef CONFIG_SPARSEMEM_VMEMMAP int mmu_vmemmap_psize = MMU_PAGE_4K; #endif @@ -186,7 +187,7 @@ static struct mmu_psize_def mmu_psize_defaults_gp[] = { * - We make sure R is always set and never lost * - C is _PAGE_DIRTY, and *should* always be set for a writeable mapping */ -unsigned long htab_convert_pte_flags(unsigned long pteflags) +unsigned long htab_convert_pte_flags(unsigned long pteflags, unsigned long flags) { unsigned long rflags = 0; @@ -240,7 +241,7 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags) */ rflags |= HPTE_R_M; - rflags |= pte_to_hpte_pkey_bits(pteflags); + rflags |= pte_to_hpte_pkey_bits(pteflags, flags); return rflags; } @@ -255,7 +256,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, shift = mmu_psize_defs[psize].shift; step = 1 << shift; - prot = htab_convert_pte_flags(prot); + prot = htab_convert_pte_flags(prot, HPTE_USE_KERNEL_KEY); DBG("htab_bolt_mapping(%lx..%lx -> %lx (%lx,%d,%d)\n", vstart, vend, pstart, prot, psize, ssize); @@ -845,7 +846,6 @@ int hash__remove_section_mapping(unsigned long start, unsigned long end) { int rc = htab_remove_mapping(start, end, mmu_linear_psize, mmu_kernel_ssize); - WARN_ON(rc < 0); if (resize_hpt_for_hotplug(memblock_phys_mem_size()) == -ENOSPC) pr_warn("Hash collision while resizing HPT\n"); @@ -1317,12 +1317,14 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, vsid = get_kernel_vsid(ea, mmu_kernel_ssize); psize = mmu_vmalloc_psize; ssize = mmu_kernel_ssize; + flags |= HPTE_USE_KERNEL_KEY; break; case IO_REGION_ID: vsid = get_kernel_vsid(ea, mmu_kernel_ssize); psize = mmu_io_psize; ssize = mmu_kernel_ssize; + flags |= HPTE_USE_KERNEL_KEY; break; default: /* @@ -1901,7 +1903,7 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) unsigned long hash; unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize); unsigned long vpn = hpt_vpn(vaddr, vsid, mmu_kernel_ssize); - unsigned long mode = htab_convert_pte_flags(pgprot_val(PAGE_KERNEL)); + unsigned long mode = htab_convert_pte_flags(pgprot_val(PAGE_KERNEL), HPTE_USE_KERNEL_KEY); long ret; hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize); diff --git a/arch/powerpc/mm/book3s64/iommu_api.c b/arch/powerpc/mm/book3s64/iommu_api.c index 563faa10bb66..685d7bb3d26f 100644 --- a/arch/powerpc/mm/book3s64/iommu_api.c +++ b/arch/powerpc/mm/book3s64/iommu_api.c @@ -263,7 +263,7 @@ long mm_iommu_put(struct mm_struct *mm, struct mm_iommu_table_group_mem_t *mem) goto unlock_exit; /* Are there still mappings? */ - if (atomic_cmpxchg(&mem->mapped, 1, 0) != 1) { + if (atomic64_cmpxchg(&mem->mapped, 1, 0) != 1) { ++mem->used; ret = -EBUSY; goto unlock_exit; diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c index e18ae50a275c..5b3a3bae21aa 100644 --- a/arch/powerpc/mm/book3s64/pgtable.c +++ b/arch/powerpc/mm/book3s64/pgtable.c @@ -136,12 +136,18 @@ static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot) return __pmd(pmd_val(pmd) | pgprot_val(pgprot)); } +/* + * At some point we should be able to get rid of + * pmd_mkhuge() and mk_huge_pmd() when we update all the + * other archs to mark the pmd huge in pfn_pmd() + */ pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot) { unsigned long pmdv; pmdv = (pfn << PAGE_SHIFT) & PTE_RPN_MASK; - return pmd_set_protbits(__pmd(pmdv), pgprot); + + return __pmd_mkhuge(pmd_set_protbits(__pmd(pmdv), pgprot)); } pmd_t mk_pmd(struct page *page, pgprot_t pgprot) diff --git a/arch/powerpc/mm/book3s64/pkeys.c b/arch/powerpc/mm/book3s64/pkeys.c index b1d091a97611..f1c6f264ed91 100644 --- a/arch/powerpc/mm/book3s64/pkeys.c +++ b/arch/powerpc/mm/book3s64/pkeys.c @@ -9,9 +9,12 @@ #include <asm/mmu_context.h> #include <asm/mmu.h> #include <asm/setup.h> +#include <asm/smp.h> + #include <linux/pkeys.h> #include <linux/of_fdt.h> + int num_pkey; /* Max number of pkeys supported */ /* * Keys marked in the reservation list cannot be allocated by userspace @@ -25,8 +28,8 @@ static u32 initial_allocation_mask __ro_after_init; * Even if we allocate keys with sys_pkey_alloc(), we need to make sure * other thread still find the access denied using the same keys. */ -static u64 default_amr = ~0x0UL; -static u64 default_iamr = 0x5555555555555555UL; +u64 default_amr __ro_after_init = ~0x0UL; +u64 default_iamr __ro_after_init = 0x5555555555555555UL; u64 default_uamor __ro_after_init; /* * Key used to implement PROT_EXEC mmap. Denies READ/WRITE @@ -89,12 +92,14 @@ static int scan_pkey_feature(void) } } +#ifdef CONFIG_PPC_MEM_KEYS /* * Adjust the upper limit, based on the number of bits supported by * arch-neutral code. */ pkeys_total = min_t(int, pkeys_total, ((ARCH_VM_PKEY_FLAGS >> VM_PKEY_SHIFT) + 1)); +#endif return pkeys_total; } @@ -102,6 +107,7 @@ void __init pkey_early_init_devtree(void) { int pkeys_total, i; +#ifdef CONFIG_PPC_MEM_KEYS /* * We define PKEY_DISABLE_EXECUTE in addition to the arch-neutral * generic defines for PKEY_DISABLE_ACCESS and PKEY_DISABLE_WRITE. @@ -117,7 +123,7 @@ void __init pkey_early_init_devtree(void) BUILD_BUG_ON(__builtin_clzl(ARCH_VM_PKEY_FLAGS >> VM_PKEY_SHIFT) + __builtin_popcountl(ARCH_VM_PKEY_FLAGS >> VM_PKEY_SHIFT) != (sizeof(u64) * BITS_PER_BYTE)); - +#endif /* * Only P7 and above supports SPRN_AMR update with MSR[PR] = 1 */ @@ -179,6 +185,27 @@ void __init pkey_early_init_devtree(void) default_uamor &= ~(0x3ul << pkeyshift(execute_only_key)); } + if (unlikely(num_pkey <= 3)) { + /* + * Insufficient number of keys to support + * KUAP/KUEP feature. + */ + disable_kuep = true; + disable_kuap = true; + WARN(1, "Disabling kernel user protection due to low (%d) max supported keys\n", num_pkey); + } else { + /* handle key which is used by kernel for KAUP */ + reserved_allocation_mask |= (0x1 << 3); + /* + * Mark access for kup_key in default amr so that + * we continue to operate with that AMR in + * copy_to/from_user(). + */ + default_amr &= ~(0x3ul << pkeyshift(3)); + default_iamr &= ~(0x1ul << pkeyshift(3)); + default_uamor &= ~(0x3ul << pkeyshift(3)); + } + /* * Allow access for only key 0. And prevent any other modification. */ @@ -223,54 +250,92 @@ out: return; } -void pkey_mm_init(struct mm_struct *mm) +#ifdef CONFIG_PPC_KUEP +void setup_kuep(bool disabled) { - if (!mmu_has_feature(MMU_FTR_PKEY)) + if (disabled) return; - mm_pkey_allocation_map(mm) = initial_allocation_mask; - mm->context.execute_only_pkey = execute_only_key; + /* + * On hash if PKEY feature is not enabled, disable KUAP too. + */ + if (!early_radix_enabled() && !early_mmu_has_feature(MMU_FTR_PKEY)) + return; + + if (smp_processor_id() == boot_cpuid) { + pr_info("Activating Kernel Userspace Execution Prevention\n"); + cur_cpu_spec->mmu_features |= MMU_FTR_BOOK3S_KUEP; + } + + /* + * Radix always uses key0 of the IAMR to determine if an access is + * allowed. We set bit 0 (IBM bit 1) of key0, to prevent instruction + * fetch. + */ + mtspr(SPRN_IAMR, AMR_KUEP_BLOCKED); + isync(); } +#endif -static inline u64 read_amr(void) +#ifdef CONFIG_PPC_KUAP +void setup_kuap(bool disabled) { - return mfspr(SPRN_AMR); + if (disabled) + return; + /* + * On hash if PKEY feature is not enabled, disable KUAP too. + */ + if (!early_radix_enabled() && !early_mmu_has_feature(MMU_FTR_PKEY)) + return; + + if (smp_processor_id() == boot_cpuid) { + pr_info("Activating Kernel Userspace Access Prevention\n"); + cur_cpu_spec->mmu_features |= MMU_FTR_BOOK3S_KUAP; + } + + /* + * Set the default kernel AMR values on all cpus. + */ + mtspr(SPRN_AMR, AMR_KUAP_BLOCKED); + isync(); } +#endif -static inline void write_amr(u64 value) +static inline void update_current_thread_amr(u64 value) { - mtspr(SPRN_AMR, value); + current->thread.regs->amr = value; } -static inline u64 read_iamr(void) +static inline void update_current_thread_iamr(u64 value) { if (!likely(pkey_execute_disable_supported)) - return 0x0UL; + return; - return mfspr(SPRN_IAMR); + current->thread.regs->iamr = value; } -static inline void write_iamr(u64 value) +#ifdef CONFIG_PPC_MEM_KEYS +void pkey_mm_init(struct mm_struct *mm) { - if (!likely(pkey_execute_disable_supported)) + if (!mmu_has_feature(MMU_FTR_PKEY)) return; - - mtspr(SPRN_IAMR, value); + mm_pkey_allocation_map(mm) = initial_allocation_mask; + mm->context.execute_only_pkey = execute_only_key; } static inline void init_amr(int pkey, u8 init_bits) { u64 new_amr_bits = (((u64)init_bits & 0x3UL) << pkeyshift(pkey)); - u64 old_amr = read_amr() & ~((u64)(0x3ul) << pkeyshift(pkey)); + u64 old_amr = current_thread_amr() & ~((u64)(0x3ul) << pkeyshift(pkey)); - write_amr(old_amr | new_amr_bits); + update_current_thread_amr(old_amr | new_amr_bits); } static inline void init_iamr(int pkey, u8 init_bits) { u64 new_iamr_bits = (((u64)init_bits & 0x1UL) << pkeyshift(pkey)); - u64 old_iamr = read_iamr() & ~((u64)(0x1ul) << pkeyshift(pkey)); + u64 old_iamr = current_thread_iamr() & ~((u64)(0x1ul) << pkeyshift(pkey)); - write_iamr(old_iamr | new_iamr_bits); + update_current_thread_iamr(old_iamr | new_iamr_bits); } /* @@ -313,42 +378,6 @@ int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey, return 0; } -void thread_pkey_regs_save(struct thread_struct *thread) -{ - if (!mmu_has_feature(MMU_FTR_PKEY)) - return; - - /* - * TODO: Skip saving registers if @thread hasn't used any keys yet. - */ - thread->amr = read_amr(); - thread->iamr = read_iamr(); -} - -void thread_pkey_regs_restore(struct thread_struct *new_thread, - struct thread_struct *old_thread) -{ - if (!mmu_has_feature(MMU_FTR_PKEY)) - return; - - if (old_thread->amr != new_thread->amr) - write_amr(new_thread->amr); - if (old_thread->iamr != new_thread->iamr) - write_iamr(new_thread->iamr); -} - -void thread_pkey_regs_init(struct thread_struct *thread) -{ - if (!mmu_has_feature(MMU_FTR_PKEY)) - return; - - thread->amr = default_amr; - thread->iamr = default_iamr; - - write_amr(default_amr); - write_iamr(default_iamr); -} - int execute_only_pkey(struct mm_struct *mm) { return mm->context.execute_only_pkey; @@ -397,9 +426,9 @@ static bool pkey_access_permitted(int pkey, bool write, bool execute) pkey_shift = pkeyshift(pkey); if (execute) - return !(read_iamr() & (IAMR_EX_BIT << pkey_shift)); + return !(current_thread_iamr() & (IAMR_EX_BIT << pkey_shift)); - amr = read_amr(); + amr = current_thread_amr(); if (write) return !(amr & (AMR_WR_BIT << pkey_shift)); @@ -445,3 +474,5 @@ void arch_dup_pkeys(struct mm_struct *oldmm, struct mm_struct *mm) mm_pkey_allocation_map(mm) = mm_pkey_allocation_map(oldmm); mm->context.execute_only_pkey = oldmm->context.execute_only_pkey; } + +#endif /* CONFIG_PPC_MEM_KEYS */ diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c index 3adcf730f478..98f0b243c1ab 100644 --- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -589,48 +589,6 @@ static void radix_init_amor(void) mtspr(SPRN_AMOR, (3ul << 62)); } -#ifdef CONFIG_PPC_KUEP -void setup_kuep(bool disabled) -{ - if (disabled || !early_radix_enabled()) - return; - - if (smp_processor_id() == boot_cpuid) { - pr_info("Activating Kernel Userspace Execution Prevention\n"); - cur_cpu_spec->mmu_features |= MMU_FTR_KUEP; - } - - /* - * Radix always uses key0 of the IAMR to determine if an access is - * allowed. We set bit 0 (IBM bit 1) of key0, to prevent instruction - * fetch. - */ - mtspr(SPRN_IAMR, (1ul << 62)); -} -#endif - -#ifdef CONFIG_PPC_KUAP -void setup_kuap(bool disabled) -{ - if (disabled || !early_radix_enabled()) - return; - - if (smp_processor_id() == boot_cpuid) { - pr_info("Activating Kernel Userspace Access Prevention\n"); - cur_cpu_spec->mmu_features |= MMU_FTR_RADIX_KUAP; - } - - /* Make sure userspace can't change the AMR */ - mtspr(SPRN_UAMOR, 0); - - /* - * Set the default kernel AMR values on all cpus. - */ - mtspr(SPRN_AMR, AMR_KUAP_BLOCKED); - isync(); -} -#endif - void __init radix__early_init_mmu(void) { unsigned long lpcr; @@ -721,6 +679,9 @@ void radix__early_init_mmu_secondary(void) radix__switch_mmu_context(NULL, &init_mm); tlbiel_all(); + + /* Make sure userspace can't change the AMR */ + mtspr(SPRN_UAMOR, 0); } void radix__mmu_cleanup_all(void) diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c index b487b489d4b6..fb66d154b26c 100644 --- a/arch/powerpc/mm/book3s64/radix_tlb.c +++ b/arch/powerpc/mm/book3s64/radix_tlb.c @@ -56,14 +56,21 @@ static void tlbiel_all_isa300(unsigned int num_sets, unsigned int is) if (early_cpu_has_feature(CPU_FTR_HVMODE)) { /* MSR[HV] should flush partition scope translations first. */ tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 0); - for (set = 1; set < num_sets; set++) - tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 0); + + if (!early_cpu_has_feature(CPU_FTR_ARCH_31)) { + for (set = 1; set < num_sets; set++) + tlbiel_radix_set_isa300(set, is, 0, + RIC_FLUSH_TLB, 0); + } } /* Flush process scoped entries. */ tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 1); - for (set = 1; set < num_sets; set++) - tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 1); + + if (!early_cpu_has_feature(CPU_FTR_ARCH_31)) { + for (set = 1; set < num_sets; set++) + tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 1); + } ppc_after_tlbiel_barrier(); } @@ -300,9 +307,11 @@ static __always_inline void _tlbiel_pid(unsigned long pid, unsigned long ric) return; } - /* For the remaining sets, just flush the TLB */ - for (set = 1; set < POWER9_TLB_SETS_RADIX ; set++) - __tlbiel_pid(pid, set, RIC_FLUSH_TLB); + if (!cpu_has_feature(CPU_FTR_ARCH_31)) { + /* For the remaining sets, just flush the TLB */ + for (set = 1; set < POWER9_TLB_SETS_RADIX ; set++) + __tlbiel_pid(pid, set, RIC_FLUSH_TLB); + } ppc_after_tlbiel_barrier(); asm volatile(PPC_RADIX_INVALIDATE_ERAT_USER "; isync" : : :"memory"); diff --git a/arch/powerpc/mm/book3s64/slb.c b/arch/powerpc/mm/book3s64/slb.c index c30fcbfa0e32..584567970c11 100644 --- a/arch/powerpc/mm/book3s64/slb.c +++ b/arch/powerpc/mm/book3s64/slb.c @@ -28,35 +28,8 @@ #include "internal.h" -enum slb_index { - LINEAR_INDEX = 0, /* Kernel linear map (0xc000000000000000) */ - KSTACK_INDEX = 1, /* Kernel stack map */ -}; - static long slb_allocate_user(struct mm_struct *mm, unsigned long ea); -#define slb_esid_mask(ssize) \ - (((ssize) == MMU_SEGSIZE_256M)? ESID_MASK: ESID_MASK_1T) - -static inline unsigned long mk_esid_data(unsigned long ea, int ssize, - enum slb_index index) -{ - return (ea & slb_esid_mask(ssize)) | SLB_ESID_V | index; -} - -static inline unsigned long __mk_vsid_data(unsigned long vsid, int ssize, - unsigned long flags) -{ - return (vsid << slb_vsid_shift(ssize)) | flags | - ((unsigned long) ssize << SLB_VSID_SSIZE_SHIFT); -} - -static inline unsigned long mk_vsid_data(unsigned long ea, int ssize, - unsigned long flags) -{ - return __mk_vsid_data(get_kernel_vsid(ea, ssize), ssize, flags); -} - bool stress_slb_enabled __initdata; static int __init parse_stress_slb(char *p) @@ -255,7 +228,6 @@ void slb_dump_contents(struct slb_entry *slb_ptr) return; pr_err("SLB contents of cpu 0x%x\n", smp_processor_id()); - pr_err("Last SLB entry inserted at slot %d\n", get_paca()->stab_rr); for (i = 0; i < mmu_slb_size; i++) { e = slb_ptr->esid; @@ -265,34 +237,38 @@ void slb_dump_contents(struct slb_entry *slb_ptr) if (!e && !v) continue; - pr_err("%02d %016lx %016lx\n", i, e, v); + pr_err("%02d %016lx %016lx %s\n", i, e, v, + (e & SLB_ESID_V) ? "VALID" : "NOT VALID"); - if (!(e & SLB_ESID_V)) { - pr_err("\n"); + if (!(e & SLB_ESID_V)) continue; - } + llp = v & SLB_VSID_LLP; if (v & SLB_VSID_B_1T) { - pr_err(" 1T ESID=%9lx VSID=%13lx LLP:%3lx\n", + pr_err(" 1T ESID=%9lx VSID=%13lx LLP:%3lx\n", GET_ESID_1T(e), (v & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T, llp); } else { - pr_err(" 256M ESID=%9lx VSID=%13lx LLP:%3lx\n", + pr_err(" 256M ESID=%9lx VSID=%13lx LLP:%3lx\n", GET_ESID(e), (v & ~SLB_VSID_B) >> SLB_VSID_SHIFT, llp); } } - pr_err("----------------------------------\n"); - - /* Dump slb cache entires as well. */ - pr_err("SLB cache ptr value = %d\n", get_paca()->slb_save_cache_ptr); - pr_err("Valid SLB cache entries:\n"); - n = min_t(int, get_paca()->slb_save_cache_ptr, SLB_CACHE_ENTRIES); - for (i = 0; i < n; i++) - pr_err("%02d EA[0-35]=%9x\n", i, get_paca()->slb_cache[i]); - pr_err("Rest of SLB cache entries:\n"); - for (i = n; i < SLB_CACHE_ENTRIES; i++) - pr_err("%02d EA[0-35]=%9x\n", i, get_paca()->slb_cache[i]); + + if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) { + /* RR is not so useful as it's often not used for allocation */ + pr_err("SLB RR allocator index %d\n", get_paca()->stab_rr); + + /* Dump slb cache entires as well. */ + pr_err("SLB cache ptr value = %d\n", get_paca()->slb_save_cache_ptr); + pr_err("Valid SLB cache entries:\n"); + n = min_t(int, get_paca()->slb_save_cache_ptr, SLB_CACHE_ENTRIES); + for (i = 0; i < n; i++) + pr_err("%02d EA[0-35]=%9x\n", i, get_paca()->slb_cache[i]); + pr_err("Rest of SLB cache entries:\n"); + for (i = n; i < SLB_CACHE_ENTRIES; i++) + pr_err("%02d EA[0-35]=%9x\n", i, get_paca()->slb_cache[i]); + } } void slb_vmalloc_update(void) diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 0add963a849b..8961b44f350c 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -210,28 +210,26 @@ static bool bad_kernel_fault(struct pt_regs *regs, unsigned long error_code, return true; } - if (!is_exec && address < TASK_SIZE && (error_code & DSISR_PROTFAULT) && - !search_exception_tables(regs->nip)) { - pr_crit_ratelimited("Kernel attempted to access user page (%lx) - exploit attempt? (uid: %d)\n", - address, - from_kuid(&init_user_ns, current_uid())); - } - // Kernel fault on kernel address is bad if (address >= TASK_SIZE) return true; - // Fault on user outside of certain regions (eg. copy_tofrom_user()) is bad - if (!search_exception_tables(regs->nip)) - return true; + // Read/write fault blocked by KUAP is bad, it can never succeed. + if (bad_kuap_fault(regs, address, is_write)) { + pr_crit_ratelimited("Kernel attempted to %s user page (%lx) - exploit attempt? (uid: %d)\n", + is_write ? "write" : "read", address, + from_kuid(&init_user_ns, current_uid())); - // Read/write fault in a valid region (the exception table search passed - // above), but blocked by KUAP is bad, it can never succeed. - if (bad_kuap_fault(regs, address, is_write)) - return true; + // Fault on user outside of certain regions (eg. copy_tofrom_user()) is bad + if (!search_exception_tables(regs->nip)) + return true; + + // Read/write fault in a valid region (the exception table search passed + // above), but blocked by KUAP is bad, it can never succeed. + return WARN(true, "Bug: %s fault blocked by KUAP!", is_write ? "Write" : "Read"); + } - // What's left? Kernel fault on user in well defined regions (extable - // matched), and allowed by KUAP in the faulting context. + // What's left? Kernel fault on user and allowed by KUAP in the faulting context. return false; } @@ -303,7 +301,6 @@ static inline void cmo_account_page_fault(void) static inline void cmo_account_page_fault(void) { } #endif /* CONFIG_PPC_SMLPAR */ -#ifdef CONFIG_PPC_BOOK3S static void sanity_check_fault(bool is_write, bool is_user, unsigned long error_code, unsigned long address) { @@ -320,6 +317,9 @@ static void sanity_check_fault(bool is_write, bool is_user, return; } + if (!IS_ENABLED(CONFIG_PPC_BOOK3S)) + return; + /* * For hash translation mode, we should never get a * PROTFAULT. Any update to pte to reduce access will result in us @@ -354,10 +354,6 @@ static void sanity_check_fault(bool is_write, bool is_user, WARN_ON_ONCE(error_code & DSISR_PROTFAULT); } -#else -static void sanity_check_fault(bool is_write, bool is_user, - unsigned long error_code, unsigned long address) { } -#endif /* CONFIG_PPC_BOOK3S */ /* * Define the correct "is_write" bit in error_code based @@ -365,17 +361,19 @@ static void sanity_check_fault(bool is_write, bool is_user, */ #if (defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) #define page_fault_is_write(__err) ((__err) & ESR_DST) -#define page_fault_is_bad(__err) (0) #else #define page_fault_is_write(__err) ((__err) & DSISR_ISSTORE) -#if defined(CONFIG_PPC_8xx) +#endif + +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) +#define page_fault_is_bad(__err) (0) +#elif defined(CONFIG_PPC_8xx) #define page_fault_is_bad(__err) ((__err) & DSISR_NOEXEC_OR_G) #elif defined(CONFIG_PPC64) #define page_fault_is_bad(__err) ((__err) & DSISR_BAD_FAULT_64S) #else #define page_fault_is_bad(__err) ((__err) & DSISR_BAD_FAULT_32S) #endif -#endif /* * For 600- and 800-family processors, the error_code parameter is DSISR @@ -547,10 +545,20 @@ NOKPROBE_SYMBOL(__do_page_fault); int do_page_fault(struct pt_regs *regs, unsigned long address, unsigned long error_code) { + const struct exception_table_entry *entry; enum ctx_state prev_state = exception_enter(); int rc = __do_page_fault(regs, address, error_code); exception_exit(prev_state); - return rc; + if (likely(!rc)) + return 0; + + entry = search_exception_tables(regs->nip); + if (unlikely(!entry)) + return rc; + + instruction_pointer_set(regs, extable_fixup(entry)); + + return 0; } NOKPROBE_SYMBOL(do_page_fault); @@ -559,17 +567,10 @@ NOKPROBE_SYMBOL(do_page_fault); * It is called from the DSI and ISI handlers in head.S and from some * of the procedures in traps.c. */ -void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) +void __bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) { - const struct exception_table_entry *entry; int is_write = page_fault_is_write(regs->dsisr); - /* Are we prepared to handle this fault? */ - if ((entry = search_exception_tables(regs->nip)) != NULL) { - regs->nip = extable_fixup(entry); - return; - } - /* kernel has accessed a bad area */ switch (TRAP(regs)) { @@ -603,3 +604,15 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) die("Kernel access of bad area", regs, sig); } + +void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) +{ + const struct exception_table_entry *entry; + + /* Are we prepared to handle this fault? */ + entry = search_exception_tables(instruction_pointer(regs)); + if (entry) + instruction_pointer_set(regs, extable_fixup(entry)); + else + __bad_page_fault(regs, address, sig); +} diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 36c3800769fb..8b3cc4d688e8 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -294,6 +294,21 @@ static void hugepd_free(struct mmu_gather *tlb, void *hugepte) static inline void hugepd_free(struct mmu_gather *tlb, void *hugepte) {} #endif +/* Return true when the entry to be freed maps more than the area being freed */ +static bool range_is_outside_limits(unsigned long start, unsigned long end, + unsigned long floor, unsigned long ceiling, + unsigned long mask) +{ + if ((start & mask) < floor) + return true; + if (ceiling) { + ceiling &= mask; + if (!ceiling) + return true; + } + return end - 1 > ceiling - 1; +} + static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshift, unsigned long start, unsigned long end, unsigned long floor, unsigned long ceiling) @@ -309,15 +324,7 @@ static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshif if (shift > pdshift) num_hugepd = 1 << (shift - pdshift); - start &= pdmask; - if (start < floor) - return; - if (ceiling) { - ceiling &= pdmask; - if (! ceiling) - return; - } - if (end - 1 > ceiling - 1) + if (range_is_outside_limits(start, end, floor, ceiling, pdmask)) return; for (i = 0; i < num_hugepd; i++, hpdp++) @@ -334,18 +341,9 @@ static void hugetlb_free_pte_range(struct mmu_gather *tlb, pmd_t *pmd, unsigned long addr, unsigned long end, unsigned long floor, unsigned long ceiling) { - unsigned long start = addr; pgtable_t token = pmd_pgtable(*pmd); - start &= PMD_MASK; - if (start < floor) - return; - if (ceiling) { - ceiling &= PMD_MASK; - if (!ceiling) - return; - } - if (end - 1 > ceiling - 1) + if (range_is_outside_limits(addr, end, floor, ceiling, PMD_MASK)) return; pmd_clear(pmd); @@ -395,20 +393,12 @@ static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, addr, next, floor, ceiling); } while (addr = next, addr != end); - start &= PUD_MASK; - if (start < floor) - return; - if (ceiling) { - ceiling &= PUD_MASK; - if (!ceiling) - return; - } - if (end - 1 > ceiling - 1) + if (range_is_outside_limits(start, end, floor, ceiling, PUD_MASK)) return; - pmd = pmd_offset(pud, start); + pmd = pmd_offset(pud, start & PUD_MASK); pud_clear(pud); - pmd_free_tlb(tlb, pmd, start); + pmd_free_tlb(tlb, pmd, start & PUD_MASK); mm_dec_nr_pmds(tlb->mm); } @@ -446,20 +436,12 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, p4d_t *p4d, } } while (addr = next, addr != end); - start &= PGDIR_MASK; - if (start < floor) - return; - if (ceiling) { - ceiling &= PGDIR_MASK; - if (!ceiling) - return; - } - if (end - 1 > ceiling - 1) + if (range_is_outside_limits(start, end, floor, ceiling, PGDIR_MASK)) return; - pud = pud_offset(p4d, start); + pud = pud_offset(p4d, start & PGDIR_MASK); p4d_clear(p4d); - pud_free_tlb(tlb, pud, start); + pud_free_tlb(tlb, pud, start & PGDIR_MASK); mm_dec_nr_puds(tlb->mm); } diff --git a/arch/powerpc/mm/init-common.c b/arch/powerpc/mm/init-common.c index 8e0d792ac296..3a82f89827a5 100644 --- a/arch/powerpc/mm/init-common.c +++ b/arch/powerpc/mm/init-common.c @@ -28,8 +28,8 @@ EXPORT_SYMBOL_GPL(kernstart_addr); unsigned long kernstart_virt_addr __ro_after_init = KERNELBASE; EXPORT_SYMBOL_GPL(kernstart_virt_addr); -static bool disable_kuep = !IS_ENABLED(CONFIG_PPC_KUEP); -static bool disable_kuap = !IS_ENABLED(CONFIG_PPC_KUAP); +bool disable_kuep = !IS_ENABLED(CONFIG_PPC_KUEP); +bool disable_kuap = !IS_ENABLED(CONFIG_PPC_KUAP); static int __init parse_nosmep(char *p) { @@ -47,12 +47,6 @@ static int __init parse_nosmap(char *p) } early_param("nosmap", parse_nosmap); -void __ref setup_kup(void) -{ - setup_kuep(disable_kuep); - setup_kuap(disable_kuap); -} - #define CTOR(shift) static void ctor_##shift(void *addr) \ { \ memset(addr, 0, sizeof(void *) << (shift)); \ diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 25284fdb300c..afab328d0887 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -54,11 +54,7 @@ #include <mm/mmu_decl.h> -#ifndef CPU_FTR_COHERENT_ICACHE -#define CPU_FTR_COHERENT_ICACHE 0 /* XXX for now */ -#define CPU_FTR_NOEXECUTE 0 -#endif - +static DEFINE_MUTEX(linear_mapping_mutex); unsigned long long memory_limit; bool init_mem_is_free; @@ -116,46 +112,70 @@ static void flush_dcache_range_chunked(unsigned long start, unsigned long stop, } } -int __ref arch_add_memory(int nid, u64 start, u64 size, - struct mhp_params *params) +int __ref arch_create_linear_mapping(int nid, u64 start, u64 size, + struct mhp_params *params) { - unsigned long start_pfn = start >> PAGE_SHIFT; - unsigned long nr_pages = size >> PAGE_SHIFT; int rc; start = (unsigned long)__va(start); + mutex_lock(&linear_mapping_mutex); rc = create_section_mapping(start, start + size, nid, params->pgprot); + mutex_unlock(&linear_mapping_mutex); if (rc) { - pr_warn("Unable to create mapping for hot added memory 0x%llx..0x%llx: %d\n", + pr_warn("Unable to create linear mapping for 0x%llx..0x%llx: %d\n", start, start + size, rc); return -EFAULT; } - - return __add_pages(nid, start_pfn, nr_pages, params); + return 0; } -void __ref arch_remove_memory(int nid, u64 start, u64 size, - struct vmem_altmap *altmap) +void __ref arch_remove_linear_mapping(u64 start, u64 size) { - unsigned long start_pfn = start >> PAGE_SHIFT; - unsigned long nr_pages = size >> PAGE_SHIFT; int ret; - __remove_pages(start_pfn, nr_pages, altmap); - /* Remove htab bolted mappings for this section of memory */ start = (unsigned long)__va(start); flush_dcache_range_chunked(start, start + size, FLUSH_CHUNK_SIZE); + mutex_lock(&linear_mapping_mutex); ret = remove_section_mapping(start, start + size); - WARN_ON_ONCE(ret); + mutex_unlock(&linear_mapping_mutex); + if (ret) + pr_warn("Unable to remove linear mapping for 0x%llx..0x%llx: %d\n", + start, start + size, ret); /* Ensure all vmalloc mappings are flushed in case they also * hit that section of memory */ vm_unmap_aliases(); } + +int __ref arch_add_memory(int nid, u64 start, u64 size, + struct mhp_params *params) +{ + unsigned long start_pfn = start >> PAGE_SHIFT; + unsigned long nr_pages = size >> PAGE_SHIFT; + int rc; + + rc = arch_create_linear_mapping(nid, start, size, params); + if (rc) + return rc; + rc = __add_pages(nid, start_pfn, nr_pages, params); + if (rc) + arch_remove_linear_mapping(start, size); + return rc; +} + +void __ref arch_remove_memory(int nid, u64 start, u64 size, + struct vmem_altmap *altmap) +{ + unsigned long start_pfn = start >> PAGE_SHIFT; + unsigned long nr_pages = size >> PAGE_SHIFT; + + __remove_pages(start_pfn, nr_pages, altmap); + arch_remove_linear_mapping(start, size); +} #endif #ifndef CONFIG_NEED_MULTIPLE_NODES @@ -525,7 +545,7 @@ void __flush_dcache_icache(void *p) * space occurs, before returning to user space. */ - if (cpu_has_feature(MMU_FTR_TYPE_44x)) + if (mmu_has_feature(MMU_FTR_TYPE_44x)) return; invalidate_icache_range(addr, addr + PAGE_SIZE); diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 1b6d39e9baed..998810e68562 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -82,17 +82,12 @@ static inline void print_system_hash_info(void) {} #else /* CONFIG_PPC_MMU_NOHASH */ -extern void _tlbie(unsigned long address); -extern void _tlbia(void); - void print_system_hash_info(void); #endif /* CONFIG_PPC_MMU_NOHASH */ #ifdef CONFIG_PPC32 -void hash_preload(struct mm_struct *mm, unsigned long ea); - extern void mapin_ram(void); extern void setbat(int index, unsigned long virt, phys_addr_t phys, unsigned int size, pgprot_t prot); @@ -101,7 +96,6 @@ extern int __map_without_bats; extern unsigned int rtas_data, rtas_size; struct hash_pte; -extern struct hash_pte *Hash; extern u8 early_hash[]; #endif /* CONFIG_PPC32 */ diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c index 231ca95f9ffb..19a3eec1d8c5 100644 --- a/arch/powerpc/mm/nohash/8xx.c +++ b/arch/powerpc/mm/nohash/8xx.c @@ -186,8 +186,7 @@ void mmu_mark_initmem_nx(void) mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_TEXT, false); mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL, false); - if (IS_ENABLED(CONFIG_PIN_TLB_TEXT)) - mmu_pin_tlb(block_mapped_ram, false); + mmu_pin_tlb(block_mapped_ram, false); } #ifdef CONFIG_STRICT_KERNEL_RWX diff --git a/arch/powerpc/mm/nohash/fsl_booke.c b/arch/powerpc/mm/nohash/fsl_booke.c index 36bda962d3b3..03dacbe940e5 100644 --- a/arch/powerpc/mm/nohash/fsl_booke.c +++ b/arch/powerpc/mm/nohash/fsl_booke.c @@ -223,15 +223,9 @@ void flush_instruction_cache(void) { unsigned long tmp; - if (IS_ENABLED(CONFIG_E200)) { - tmp = mfspr(SPRN_L1CSR0); - tmp |= L1CSR0_CFI | L1CSR0_CLFC; - mtspr(SPRN_L1CSR0, tmp); - } else { - tmp = mfspr(SPRN_L1CSR1); - tmp |= L1CSR1_ICFI | L1CSR1_ICLFR; - mtspr(SPRN_L1CSR1, tmp); - } + tmp = mfspr(SPRN_L1CSR1); + tmp |= L1CSR1_ICFI | L1CSR1_ICLFR; + mtspr(SPRN_L1CSR1, tmp); isync(); } diff --git a/arch/powerpc/mm/nohash/tlb_low.S b/arch/powerpc/mm/nohash/tlb_low.S index eaeee402f96e..68797e072f55 100644 --- a/arch/powerpc/mm/nohash/tlb_low.S +++ b/arch/powerpc/mm/nohash/tlb_low.S @@ -92,36 +92,25 @@ _GLOBAL(__tlbil_va) tlbsx. r6,0,r3 bne 10f sync -BEGIN_MMU_FTR_SECTION - b 2f -END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) +#ifndef CONFIG_PPC_47x /* On 440 There are only 64 TLB entries, so r3 < 64, which means bit * 22, is clear. Since 22 is the V bit in the TLB_PAGEID, loading this * value will invalidate the TLB entry. */ tlbwe r6,r6,PPC44x_TLB_PAGEID - isync -10: wrtee r10 - blr -2: -#ifdef CONFIG_PPC_47x +#else oris r7,r6,0x8000 /* specify way explicitly */ clrrwi r4,r3,12 /* get an EPN for the hashing with V = 0 */ ori r4,r4,PPC47x_TLBE_SIZE tlbwe r4,r7,0 /* write it */ +#endif /* !CONFIG_PPC_47x */ isync - wrtee r10 +10: wrtee r10 blr -#else /* CONFIG_PPC_47x */ -1: trap - EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0; -#endif /* !CONFIG_PPC_47x */ _GLOBAL(_tlbil_all) _GLOBAL(_tlbil_pid) -BEGIN_MMU_FTR_SECTION - b 2f -END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) +#ifndef CONFIG_PPC_47x li r3,0 sync @@ -136,8 +125,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) isync blr -2: -#ifdef CONFIG_PPC_47x +#else /* 476 variant. There's not simple way to do this, hopefully we'll * try to limit the amount of such full invalidates */ @@ -179,11 +167,8 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) b 1b /* Then loop */ 1: isync /* Sync shadows */ wrtee r11 -#else /* CONFIG_PPC_47x */ -1: trap - EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0; -#endif /* !CONFIG_PPC_47x */ blr +#endif /* !CONFIG_PPC_47x */ #ifdef CONFIG_PPC_47x diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 079159e97bca..e0ec67a16887 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -84,7 +84,7 @@ int __ref map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot) pg = pte_alloc_kernel(pd, va); else pg = early_pte_alloc_kernel(pd, va); - if (pg != 0) { + if (pg) { err = 0; /* The PTE should never be already set nor present in the * hash table @@ -112,10 +112,6 @@ static void __init __mapin_ram_chunk(unsigned long offset, unsigned long top) ktext = ((char *)v >= _stext && (char *)v < etext) || ((char *)v >= _sinittext && (char *)v < _einittext); map_kernel_page(v, p, ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL); -#ifdef CONFIG_PPC_BOOK3S_32 - if (ktext) - hash_preload(&init_mm, v); -#endif v += PAGE_SIZE; p += PAGE_SIZE; } diff --git a/arch/powerpc/perf/8xx-pmu.c b/arch/powerpc/perf/8xx-pmu.c index e53c3c161257..f970d1510d3d 100644 --- a/arch/powerpc/perf/8xx-pmu.c +++ b/arch/powerpc/perf/8xx-pmu.c @@ -153,6 +153,8 @@ static void mpc8xx_pmu_read(struct perf_event *event) static void mpc8xx_pmu_del(struct perf_event *event, int flags) { + struct ppc_inst insn = ppc_inst(PPC_RAW_MFSPR(10, SPRN_SPRG_SCRATCH2)); + mpc8xx_pmu_read(event); /* If it was the last user, stop counting to avoid useles overhead */ @@ -164,22 +166,12 @@ static void mpc8xx_pmu_del(struct perf_event *event, int flags) mtspr(SPRN_ICTRL, 7); break; case PERF_8xx_ID_ITLB_LOAD_MISS: - if (atomic_dec_return(&itlb_miss_ref) == 0) { - /* mfspr r10, SPRN_SPRG_SCRATCH0 */ - struct ppc_inst insn = ppc_inst(PPC_INST_MFSPR | __PPC_RS(R10) | - __PPC_SPR(SPRN_SPRG_SCRATCH0)); - + if (atomic_dec_return(&itlb_miss_ref) == 0) patch_instruction_site(&patch__itlbmiss_exit_1, insn); - } break; case PERF_8xx_ID_DTLB_LOAD_MISS: - if (atomic_dec_return(&dtlb_miss_ref) == 0) { - /* mfspr r10, SPRN_DAR */ - struct ppc_inst insn = ppc_inst(PPC_INST_MFSPR | __PPC_RS(R10) | - __PPC_SPR(SPRN_DAR)); - + if (atomic_dec_return(&dtlb_miss_ref) == 0) patch_instruction_site(&patch__dtlbmiss_exit_1, insn); - } break; } } diff --git a/arch/powerpc/perf/callchain.h b/arch/powerpc/perf/callchain.h index ae24d4a00da6..d6fa6e25234f 100644 --- a/arch/powerpc/perf/callchain.h +++ b/arch/powerpc/perf/callchain.h @@ -33,7 +33,7 @@ static inline int __read_user_stack(const void __user *ptr, void *ret, rc = copy_from_user_nofault(ret, ptr, size); - if (IS_ENABLED(CONFIG_PPC64) && rc) + if (IS_ENABLED(CONFIG_PPC64) && !radix_enabled() && rc) return read_user_stack_slow(ptr, ret, size); return rc; diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c index 64e4013d8060..b83c47b7947f 100644 --- a/arch/powerpc/perf/callchain_32.c +++ b/arch/powerpc/perf/callchain_32.c @@ -59,8 +59,8 @@ static int is_sigreturn_32_address(unsigned int nip, unsigned int fp) { if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad)) return 1; - if (vdso32_sigtramp && current->mm->context.vdso_base && - nip == current->mm->context.vdso_base + vdso32_sigtramp) + if (current->mm->context.vdso && + nip == VDSO32_SYMBOL(current->mm->context.vdso, sigtramp32)) return 1; return 0; } @@ -70,8 +70,8 @@ static int is_rt_sigreturn_32_address(unsigned int nip, unsigned int fp) if (nip == fp + offsetof(struct rt_signal_frame_32, uc.uc_mcontext.mc_pad)) return 1; - if (vdso32_rt_sigtramp && current->mm->context.vdso_base && - nip == current->mm->context.vdso_base + vdso32_rt_sigtramp) + if (current->mm->context.vdso && + nip == VDSO32_SYMBOL(current->mm->context.vdso, sigtramp_rt32)) return 1; return 0; } diff --git a/arch/powerpc/perf/callchain_64.c b/arch/powerpc/perf/callchain_64.c index fed90e827f3a..8d0df4226328 100644 --- a/arch/powerpc/perf/callchain_64.c +++ b/arch/powerpc/perf/callchain_64.c @@ -21,7 +21,8 @@ /* * On 64-bit we don't want to invoke hash_page on user addresses from * interrupt context, so if the access faults, we read the page tables - * to find which page (if any) is mapped and access it directly. + * to find which page (if any) is mapped and access it directly. Radix + * has no need for this so it doesn't use read_user_stack_slow. */ int read_user_stack_slow(const void __user *ptr, void *buf, int nb) { @@ -67,8 +68,8 @@ static int is_sigreturn_64_address(unsigned long nip, unsigned long fp) { if (nip == fp + offsetof(struct signal_frame_64, tramp)) return 1; - if (vdso64_rt_sigtramp && current->mm->context.vdso_base && - nip == current->mm->context.vdso_base + vdso64_rt_sigtramp) + if (current->mm->context.vdso && + nip == VDSO64_SYMBOL(current->mm->context.vdso, sigtramp_rt64)) return 1; return 0; } diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 6586f7e71cfb..28206b1fe172 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -95,6 +95,7 @@ static unsigned int freeze_events_kernel = MMCR0_FCS; #define SPRN_SIER3 0 #define MMCRA_SAMPLE_ENABLE 0 #define MMCRA_BHRB_DISABLE 0 +#define MMCR0_PMCCEXT 0 static inline unsigned long perf_ip_adjust(struct pt_regs *regs) { @@ -137,6 +138,9 @@ static void pmao_restore_workaround(bool ebb) { } bool is_sier_available(void) { + if (!ppmu) + return false; + if (ppmu->flags & PPMU_HAS_SIER) return true; @@ -250,11 +254,32 @@ static inline u32 perf_flags_from_msr(struct pt_regs *regs) static inline u32 perf_get_misc_flags(struct pt_regs *regs) { bool use_siar = regs_use_siar(regs); + unsigned long mmcra = regs->dsisr; + int marked = mmcra & MMCRA_SAMPLE_ENABLE; if (!use_siar) return perf_flags_from_msr(regs); /* + * Check the address in SIAR to identify the + * privilege levels since the SIER[MSR_HV, MSR_PR] + * bits are not set for marked events in power10 + * DD1. + */ + if (marked && (ppmu->flags & PPMU_P10_DD1)) { + unsigned long siar = mfspr(SPRN_SIAR); + if (siar) { + if (is_kernel_addr(siar)) + return PERF_RECORD_MISC_KERNEL; + return PERF_RECORD_MISC_USER; + } else { + if (is_kernel_addr(regs->nip)) + return PERF_RECORD_MISC_KERNEL; + return PERF_RECORD_MISC_USER; + } + } + + /* * If we don't have flags in MMCRA, rather than using * the MSR, we intuit the flags from the address in * SIAR which should give slightly more reliable @@ -350,7 +375,14 @@ static inline int siar_valid(struct pt_regs *regs) int marked = mmcra & MMCRA_SAMPLE_ENABLE; if (marked) { - if (ppmu->flags & PPMU_HAS_SIER) + /* + * SIER[SIAR_VALID] is not set for some + * marked events on power10 DD1, so drop + * the check for SIER[SIAR_VALID] and return true. + */ + if (ppmu->flags & PPMU_P10_DD1) + return 0x1; + else if (ppmu->flags & PPMU_HAS_SIER) return regs->dar & SIER_SIAR_VALID; if (ppmu->flags & PPMU_SIAR_VALID) @@ -1242,6 +1274,9 @@ static void power_pmu_disable(struct pmu *pmu) val |= MMCR0_FC; val &= ~(MMCR0_EBE | MMCR0_BHRBA | MMCR0_PMCC | MMCR0_PMAO | MMCR0_FC56); + /* Set mmcr0 PMCCEXT for p10 */ + if (ppmu->flags & PPMU_ARCH_31) + val |= MMCR0_PMCCEXT; /* * The barrier is to make sure the mtspr has been @@ -1881,7 +1916,7 @@ static bool is_event_blacklisted(u64 ev) static int power_pmu_event_init(struct perf_event *event) { u64 ev; - unsigned long flags; + unsigned long flags, irq_flags; struct perf_event *ctrs[MAX_HWEVENTS]; u64 events[MAX_HWEVENTS]; unsigned int cflags[MAX_HWEVENTS]; @@ -1989,7 +2024,9 @@ static int power_pmu_event_init(struct perf_event *event) if (check_excludes(ctrs, cflags, n, 1)) return -EINVAL; - cpuhw = &get_cpu_var(cpu_hw_events); + local_irq_save(irq_flags); + cpuhw = this_cpu_ptr(&cpu_hw_events); + err = power_check_constraints(cpuhw, events, cflags, n + 1); if (has_branch_stack(event)) { @@ -2000,13 +2037,13 @@ static int power_pmu_event_init(struct perf_event *event) event->attr.branch_sample_type); if (bhrb_filter == -1) { - put_cpu_var(cpu_hw_events); + local_irq_restore(irq_flags); return -EOPNOTSUPP; } cpuhw->bhrb_filter = bhrb_filter; } - put_cpu_var(cpu_hw_events); + local_irq_restore(irq_flags); if (err) return -EINVAL; @@ -2125,6 +2162,16 @@ static void record_and_restart(struct perf_event *event, unsigned long val, perf_event_update_userpage(event); /* + * Due to hardware limitation, sometimes SIAR could sample a kernel + * address even when freeze on supervisor state (kernel) is set in + * MMCR2. Check attr.exclude_kernel and address to drop the sample in + * these cases. + */ + if (event->attr.exclude_kernel && record) + if (is_kernel_addr(mfspr(SPRN_SIAR))) + record = 0; + + /* * Finally record data if requested. */ if (record) { @@ -2180,8 +2227,14 @@ unsigned long perf_misc_flags(struct pt_regs *regs) unsigned long perf_instruction_pointer(struct pt_regs *regs) { bool use_siar = regs_use_siar(regs); + unsigned long siar = mfspr(SPRN_SIAR); - if (use_siar && siar_valid(regs)) + if (ppmu->flags & PPMU_P10_DD1) { + if (siar) + return siar; + else + return regs->nip; + } else if (use_siar && siar_valid(regs)) return mfspr(SPRN_SIAR) + perf_ip_adjust(regs); else if (use_siar) return 0; // no valid instruction pointer diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c index 2848904df638..6ab5b272090a 100644 --- a/arch/powerpc/perf/isa207-common.c +++ b/arch/powerpc/perf/isa207-common.c @@ -247,6 +247,9 @@ void isa207_get_mem_weight(u64 *weight) u64 sier = mfspr(SPRN_SIER); u64 val = (sier & ISA207_SIER_TYPE_MASK) >> ISA207_SIER_TYPE_SHIFT; + if (cpu_has_feature(CPU_FTR_ARCH_31)) + mantissa = P10_MMCRA_THR_CTR_MANT(mmcra); + if (val == 0 || val == 7) *weight = 0; else @@ -311,9 +314,11 @@ int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp) } if (unit >= 6 && unit <= 9) { - if (cpu_has_feature(CPU_FTR_ARCH_31) && (unit == 6)) { - mask |= CNST_L2L3_GROUP_MASK; - value |= CNST_L2L3_GROUP_VAL(event >> p10_L2L3_EVENT_SHIFT); + if (cpu_has_feature(CPU_FTR_ARCH_31)) { + if (unit == 6) { + mask |= CNST_L2L3_GROUP_MASK; + value |= CNST_L2L3_GROUP_VAL(event >> p10_L2L3_EVENT_SHIFT); + } } else if (cpu_has_feature(CPU_FTR_ARCH_300)) { mask |= CNST_CACHE_GROUP_MASK; value |= CNST_CACHE_GROUP_VAL(event & 0xff); @@ -339,12 +344,22 @@ int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp) value |= CNST_L1_QUAL_VAL(cache); } + if (cpu_has_feature(CPU_FTR_ARCH_31)) { + mask |= CNST_RADIX_SCOPE_GROUP_MASK; + value |= CNST_RADIX_SCOPE_GROUP_VAL(event >> p10_EVENT_RADIX_SCOPE_QUAL_SHIFT); + } + if (is_event_marked(event)) { mask |= CNST_SAMPLE_MASK; value |= CNST_SAMPLE_VAL(event >> EVENT_SAMPLE_SHIFT); } - if (cpu_has_feature(CPU_FTR_ARCH_300)) { + if (cpu_has_feature(CPU_FTR_ARCH_31)) { + if (event_is_threshold(event)) { + mask |= CNST_THRESH_CTL_SEL_MASK; + value |= CNST_THRESH_CTL_SEL_VAL(event >> EVENT_THRESH_SHIFT); + } + } else if (cpu_has_feature(CPU_FTR_ARCH_300)) { if (event_is_threshold(event) && is_thresh_cmp_valid(event)) { mask |= CNST_THRESH_MASK; value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT); @@ -456,6 +471,13 @@ int isa207_compute_mmcr(u64 event[], int n_ev, } } + /* Set RADIX_SCOPE_QUAL bit */ + if (cpu_has_feature(CPU_FTR_ARCH_31)) { + val = (event[i] >> p10_EVENT_RADIX_SCOPE_QUAL_SHIFT) & + p10_EVENT_RADIX_SCOPE_QUAL_MASK; + mmcr1 |= val << p10_MMCR1_RADIX_SCOPE_QUAL_SHIFT; + } + if (is_event_marked(event[i])) { mmcra |= MMCRA_SAMPLE_ENABLE; @@ -539,6 +561,14 @@ int isa207_compute_mmcr(u64 event[], int n_ev, if (!(pmc_inuse & 0x60)) mmcr->mmcr0 |= MMCR0_FC56; + /* + * Set mmcr0 (PMCCEXT) for p10 which + * will restrict access to group B registers + * when MMCR0 PMCC=0b00. + */ + if (cpu_has_feature(CPU_FTR_ARCH_31)) + mmcr->mmcr0 |= MMCR0_PMCCEXT; + mmcr->mmcr1 = mmcr1; mmcr->mmcra = mmcra; mmcr->mmcr2 = mmcr2; diff --git a/arch/powerpc/perf/isa207-common.h b/arch/powerpc/perf/isa207-common.h index 7025de5e60e7..454b32c31440 100644 --- a/arch/powerpc/perf/isa207-common.h +++ b/arch/powerpc/perf/isa207-common.h @@ -101,6 +101,9 @@ #define p10_EVENT_CACHE_SEL_MASK 0x3ull #define p10_EVENT_MMCR3_MASK 0x7fffull #define p10_EVENT_MMCR3_SHIFT 45 +#define p10_EVENT_RADIX_SCOPE_QUAL_SHIFT 9 +#define p10_EVENT_RADIX_SCOPE_QUAL_MASK 0x1 +#define p10_MMCR1_RADIX_SCOPE_QUAL_SHIFT 45 #define p10_EVENT_VALID_MASK \ ((p10_SDAR_MODE_MASK << p10_SDAR_MODE_SHIFT | \ @@ -112,6 +115,7 @@ (p9_EVENT_COMBINE_MASK << p9_EVENT_COMBINE_SHIFT) | \ (p10_EVENT_MMCR3_MASK << p10_EVENT_MMCR3_SHIFT) | \ (EVENT_MARKED_MASK << EVENT_MARKED_SHIFT) | \ + (p10_EVENT_RADIX_SCOPE_QUAL_MASK << p10_EVENT_RADIX_SCOPE_QUAL_SHIFT) | \ EVENT_LINUX_MASK | \ EVENT_PSEL_MASK)) /* @@ -125,9 +129,9 @@ * * 28 24 20 16 12 8 4 0 * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - * [ ] | [ ] [ sample ] [ ] [6] [5] [4] [3] [2] [1] - * | | | | - * BHRB IFM -* | | | Count of events for each PMC. + * [ ] | [ ] | [ sample ] [ ] [6] [5] [4] [3] [2] [1] + * | | | | | + * BHRB IFM -* | | |*radix_scope | Count of events for each PMC. * EBB -* | | p1, p2, p3, p4, p5, p6. * L1 I/D qualifier -* | * nc - number of counters -* @@ -145,6 +149,9 @@ #define CNST_THRESH_VAL(v) (((v) & EVENT_THRESH_MASK) << 32) #define CNST_THRESH_MASK CNST_THRESH_VAL(EVENT_THRESH_MASK) +#define CNST_THRESH_CTL_SEL_VAL(v) (((v) & 0x7ffull) << 32) +#define CNST_THRESH_CTL_SEL_MASK CNST_THRESH_CTL_SEL_VAL(0x7ff) + #define CNST_EBB_VAL(v) (((v) & EVENT_EBB_MASK) << 24) #define CNST_EBB_MASK CNST_EBB_VAL(EVENT_EBB_MASK) @@ -165,6 +172,9 @@ #define CNST_L2L3_GROUP_VAL(v) (((v) & 0x1full) << 55) #define CNST_L2L3_GROUP_MASK CNST_L2L3_GROUP_VAL(0x1f) +#define CNST_RADIX_SCOPE_GROUP_VAL(v) (((v) & 0x1ull) << 21) +#define CNST_RADIX_SCOPE_GROUP_MASK CNST_RADIX_SCOPE_GROUP_VAL(1) + /* * For NC we are counting up to 4 events. This requires three bits, and we need * the fifth event to overflow and set the 4th bit. To achieve that we bias the @@ -221,6 +231,10 @@ #define MMCRA_THR_CTR_EXP(v) (((v) >> MMCRA_THR_CTR_EXP_SHIFT) &\ MMCRA_THR_CTR_EXP_MASK) +#define P10_MMCRA_THR_CTR_MANT_MASK 0xFFul +#define P10_MMCRA_THR_CTR_MANT(v) (((v) >> MMCRA_THR_CTR_MANT_SHIFT) &\ + P10_MMCRA_THR_CTR_MANT_MASK) + /* MMCRA Threshold Compare bit constant for power9 */ #define p9_MMCRA_THR_CMP_SHIFT 45 diff --git a/arch/powerpc/perf/power10-events-list.h b/arch/powerpc/perf/power10-events-list.h index 60c1b8111082..e45dafe818ed 100644 --- a/arch/powerpc/perf/power10-events-list.h +++ b/arch/powerpc/perf/power10-events-list.h @@ -15,6 +15,9 @@ EVENT(PM_EXEC_STALL, 0x30008); EVENT(PM_RUN_INST_CMPL, 0x500fa); EVENT(PM_BR_CMPL, 0x4d05e); EVENT(PM_BR_MPRED_CMPL, 0x400f6); +EVENT(PM_BR_FIN, 0x2f04a); +EVENT(PM_MPRED_BR_FIN, 0x3e098); +EVENT(PM_LD_DEMAND_MISS_L1_FIN, 0x400f0); /* All L1 D cache load references counted at finish, gated by reject */ EVENT(PM_LD_REF_L1, 0x100fc); @@ -36,6 +39,12 @@ EVENT(PM_IC_PREF_REQ, 0x040a0); EVENT(PM_DATA_FROM_L3, 0x01340000001c040); /* Demand LD - L3 Miss (not L2 hit and not L3 hit) */ EVENT(PM_DATA_FROM_L3MISS, 0x300fe); +/* All successful D-side store dispatches for this thread */ +EVENT(PM_L2_ST, 0x010000046080); +/* All successful D-side store dispatches for this thread that were L2 Miss */ +EVENT(PM_L2_ST_MISS, 0x26880); +/* Total HW L3 prefetches(Load+store) */ +EVENT(PM_L3_PF_MISS_L3, 0x100000016080); /* Data PTEG reload */ EVENT(PM_DTLB_MISS, 0x300fc); /* ITLB Reloaded */ diff --git a/arch/powerpc/perf/power10-pmu.c b/arch/powerpc/perf/power10-pmu.c index 9dbe8f9b89b4..79e0206ca454 100644 --- a/arch/powerpc/perf/power10-pmu.c +++ b/arch/powerpc/perf/power10-pmu.c @@ -23,10 +23,10 @@ * * 28 24 20 16 12 8 4 0 * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - * [ ] [ sample ] [ ] [ ] [ pmc ] [unit ] [ ] m [ pmcxsel ] - * | | | | | | - * | | | | | *- mark - * | | | *- L1/L2/L3 cache_sel | + * [ ] [ sample ] [ ] [ ] [ pmc ] [unit ] [ ] | m [ pmcxsel ] + * | | | | | | | + * | | | | | | *- mark + * | | | *- L1/L2/L3 cache_sel | |*-radix_scope_qual * | | sdar_mode | * | *- sampling mode for marked events *- combine * | @@ -59,6 +59,7 @@ * * MMCR1[16] = cache_sel[0] * MMCR1[17] = cache_sel[1] + * MMCR1[18] = radix_scope_qual * * if mark: * MMCRA[63] = 1 (SAMPLE_ENABLE) @@ -113,6 +114,9 @@ GENERIC_EVENT_ATTR(cache-references, PM_LD_REF_L1); GENERIC_EVENT_ATTR(cache-misses, PM_LD_MISS_L1); GENERIC_EVENT_ATTR(mem-loads, MEM_LOADS); GENERIC_EVENT_ATTR(mem-stores, MEM_STORES); +GENERIC_EVENT_ATTR(branch-instructions, PM_BR_FIN); +GENERIC_EVENT_ATTR(branch-misses, PM_MPRED_BR_FIN); +GENERIC_EVENT_ATTR(cache-misses, PM_LD_DEMAND_MISS_L1_FIN); CACHE_EVENT_ATTR(L1-dcache-load-misses, PM_LD_MISS_L1); CACHE_EVENT_ATTR(L1-dcache-loads, PM_LD_REF_L1); @@ -123,12 +127,15 @@ CACHE_EVENT_ATTR(L1-icache-loads, PM_INST_FROM_L1); CACHE_EVENT_ATTR(L1-icache-prefetches, PM_IC_PREF_REQ); CACHE_EVENT_ATTR(LLC-load-misses, PM_DATA_FROM_L3MISS); CACHE_EVENT_ATTR(LLC-loads, PM_DATA_FROM_L3); +CACHE_EVENT_ATTR(LLC-prefetches, PM_L3_PF_MISS_L3); +CACHE_EVENT_ATTR(LLC-store-misses, PM_L2_ST_MISS); +CACHE_EVENT_ATTR(LLC-stores, PM_L2_ST); CACHE_EVENT_ATTR(branch-load-misses, PM_BR_MPRED_CMPL); CACHE_EVENT_ATTR(branch-loads, PM_BR_CMPL); CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS); CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS); -static struct attribute *power10_events_attr[] = { +static struct attribute *power10_events_attr_dd1[] = { GENERIC_EVENT_PTR(PM_RUN_CYC), GENERIC_EVENT_PTR(PM_RUN_INST_CMPL), GENERIC_EVENT_PTR(PM_BR_CMPL), @@ -153,6 +160,39 @@ static struct attribute *power10_events_attr[] = { NULL }; +static struct attribute *power10_events_attr[] = { + GENERIC_EVENT_PTR(PM_RUN_CYC), + GENERIC_EVENT_PTR(PM_RUN_INST_CMPL), + GENERIC_EVENT_PTR(PM_BR_FIN), + GENERIC_EVENT_PTR(PM_MPRED_BR_FIN), + GENERIC_EVENT_PTR(PM_LD_REF_L1), + GENERIC_EVENT_PTR(PM_LD_DEMAND_MISS_L1_FIN), + GENERIC_EVENT_PTR(MEM_LOADS), + GENERIC_EVENT_PTR(MEM_STORES), + CACHE_EVENT_PTR(PM_LD_MISS_L1), + CACHE_EVENT_PTR(PM_LD_REF_L1), + CACHE_EVENT_PTR(PM_LD_PREFETCH_CACHE_LINE_MISS), + CACHE_EVENT_PTR(PM_ST_MISS_L1), + CACHE_EVENT_PTR(PM_L1_ICACHE_MISS), + CACHE_EVENT_PTR(PM_INST_FROM_L1), + CACHE_EVENT_PTR(PM_IC_PREF_REQ), + CACHE_EVENT_PTR(PM_DATA_FROM_L3MISS), + CACHE_EVENT_PTR(PM_DATA_FROM_L3), + CACHE_EVENT_PTR(PM_L3_PF_MISS_L3), + CACHE_EVENT_PTR(PM_L2_ST_MISS), + CACHE_EVENT_PTR(PM_L2_ST), + CACHE_EVENT_PTR(PM_BR_MPRED_CMPL), + CACHE_EVENT_PTR(PM_BR_CMPL), + CACHE_EVENT_PTR(PM_DTLB_MISS), + CACHE_EVENT_PTR(PM_ITLB_MISS), + NULL +}; + +static struct attribute_group power10_pmu_events_group_dd1 = { + .name = "events", + .attrs = power10_events_attr_dd1, +}; + static struct attribute_group power10_pmu_events_group = { .name = "events", .attrs = power10_events_attr, @@ -175,6 +215,7 @@ PMU_FORMAT_ATTR(src_sel, "config:45-46"); PMU_FORMAT_ATTR(invert_bit, "config:47"); PMU_FORMAT_ATTR(src_mask, "config:48-53"); PMU_FORMAT_ATTR(src_match, "config:54-59"); +PMU_FORMAT_ATTR(radix_scope, "config:9"); static struct attribute *power10_pmu_format_attr[] = { &format_attr_event.attr, @@ -194,6 +235,7 @@ static struct attribute *power10_pmu_format_attr[] = { &format_attr_invert_bit.attr, &format_attr_src_mask.attr, &format_attr_src_match.attr, + &format_attr_radix_scope.attr, NULL, }; @@ -202,13 +244,19 @@ static struct attribute_group power10_pmu_format_group = { .attrs = power10_pmu_format_attr, }; +static const struct attribute_group *power10_pmu_attr_groups_dd1[] = { + &power10_pmu_format_group, + &power10_pmu_events_group_dd1, + NULL, +}; + static const struct attribute_group *power10_pmu_attr_groups[] = { &power10_pmu_format_group, &power10_pmu_events_group, NULL, }; -static int power10_generic_events[] = { +static int power10_generic_events_dd1[] = { [PERF_COUNT_HW_CPU_CYCLES] = PM_RUN_CYC, [PERF_COUNT_HW_INSTRUCTIONS] = PM_RUN_INST_CMPL, [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BR_CMPL, @@ -217,6 +265,15 @@ static int power10_generic_events[] = { [PERF_COUNT_HW_CACHE_MISSES] = PM_LD_MISS_L1, }; +static int power10_generic_events[] = { + [PERF_COUNT_HW_CPU_CYCLES] = PM_RUN_CYC, + [PERF_COUNT_HW_INSTRUCTIONS] = PM_RUN_INST_CMPL, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BR_FIN, + [PERF_COUNT_HW_BRANCH_MISSES] = PM_MPRED_BR_FIN, + [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1, + [PERF_COUNT_HW_CACHE_MISSES] = PM_LD_DEMAND_MISS_L1_FIN, +}; + static u64 power10_bhrb_filter_map(u64 branch_sample_type) { u64 pmu_bhrb_filter = 0; @@ -273,7 +330,7 @@ static void power10_config_bhrb(u64 pmu_bhrb_filter) * 0 means not supported, -1 means nonsensical, other values * are event codes. */ -static u64 power10_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { +static u64 power10_cache_events_dd1[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { [C(L1D)] = { [C(OP_READ)] = { [C(RESULT_ACCESS)] = PM_LD_REF_L1, @@ -374,6 +431,107 @@ static u64 power10_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { }, }; +static u64 power10_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { + [C(L1D)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = PM_LD_REF_L1, + [C(RESULT_MISS)] = PM_LD_MISS_L1, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = 0, + [C(RESULT_MISS)] = PM_ST_MISS_L1, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = PM_LD_PREFETCH_CACHE_LINE_MISS, + [C(RESULT_MISS)] = 0, + }, + }, + [C(L1I)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = PM_INST_FROM_L1, + [C(RESULT_MISS)] = PM_L1_ICACHE_MISS, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = PM_INST_FROM_L1MISS, + [C(RESULT_MISS)] = -1, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = PM_IC_PREF_REQ, + [C(RESULT_MISS)] = 0, + }, + }, + [C(LL)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = PM_DATA_FROM_L3, + [C(RESULT_MISS)] = PM_DATA_FROM_L3MISS, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = PM_L2_ST, + [C(RESULT_MISS)] = PM_L2_ST_MISS, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = PM_L3_PF_MISS_L3, + [C(RESULT_MISS)] = 0, + }, + }, + [C(DTLB)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = 0, + [C(RESULT_MISS)] = PM_DTLB_MISS, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, + }, + [C(ITLB)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = 0, + [C(RESULT_MISS)] = PM_ITLB_MISS, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, + }, + [C(BPU)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = PM_BR_CMPL, + [C(RESULT_MISS)] = PM_BR_MPRED_CMPL, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, + }, + [C(NODE)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = -1, + [C(RESULT_MISS)] = -1, + }, + }, +}; + #undef C static struct power_pmu power10_pmu = { @@ -403,6 +561,7 @@ static struct power_pmu power10_pmu = { int init_power10_pmu(void) { + unsigned int pvr; int rc; /* Comes from cpu_specs[] */ @@ -410,9 +569,20 @@ int init_power10_pmu(void) strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power10")) return -ENODEV; + pvr = mfspr(SPRN_PVR); + /* Add the ppmu flag for power10 DD1 */ + if ((PVR_CFG(pvr) == 1)) + power10_pmu.flags |= PPMU_P10_DD1; + /* Set the PERF_REG_EXTENDED_MASK here */ PERF_REG_EXTENDED_MASK = PERF_REG_PMU_MASK_31; + if ((PVR_CFG(pvr) == 1)) { + power10_pmu.generic_events = power10_generic_events_dd1; + power10_pmu.attr_groups = power10_pmu_attr_groups_dd1; + power10_pmu.cache_events = &power10_cache_events_dd1; + } + rc = register_power_pmu(&power10_pmu); if (rc) return rc; diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c index 6aa8defb5857..8d6029099848 100644 --- a/arch/powerpc/platforms/85xx/corenet_generic.c +++ b/arch/powerpc/platforms/85xx/corenet_generic.c @@ -106,6 +106,7 @@ int __init corenet_gen_publish_devices(void) { return of_platform_bus_probe(NULL, of_device_ids, NULL); } +machine_arch_initcall(corenet_generic, corenet_gen_publish_devices); static const char * const boards[] __initconst = { "fsl,P2041RDB", @@ -206,5 +207,3 @@ define_machine(corenet_generic) { .power_save = e500_idle, #endif }; - -machine_arch_initcall(corenet_generic, corenet_gen_publish_devices); diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig index abb2b45b2789..60cc5b537a98 100644 --- a/arch/powerpc/platforms/8xx/Kconfig +++ b/arch/powerpc/platforms/8xx/Kconfig @@ -194,13 +194,6 @@ config PIN_TLB_IMMR CONFIG_PIN_TLB_DATA is also selected, it will reduce CONFIG_PIN_TLB_DATA to 24 Mbytes. -config PIN_TLB_TEXT - bool "Pinned TLB for TEXT" - depends on PIN_TLB - default y - help - This pins kernel text with 8M pages. - endmenu endmenu diff --git a/arch/powerpc/platforms/8xx/micropatch.c b/arch/powerpc/platforms/8xx/micropatch.c index aed4bc75f352..aef179fcbd4f 100644 --- a/arch/powerpc/platforms/8xx/micropatch.c +++ b/arch/powerpc/platforms/8xx/micropatch.c @@ -360,6 +360,17 @@ void __init cpm_load_patch(cpm8xx_t *cp) if (IS_ENABLED(CONFIG_SMC_UCODE_PATCH)) { smc_uart_t *smp; + if (IS_ENABLED(CONFIG_PPC_EARLY_DEBUG_CPM)) { + int i; + + for (i = 0; i < sizeof(*smp); i += 4) { + u32 __iomem *src = (u32 __iomem *)&cp->cp_dparam[PROFF_SMC1 + i]; + u32 __iomem *dst = (u32 __iomem *)&cp->cp_dparam[PROFF_DSP1 + i]; + + out_be32(dst, in_be32(src)); + } + } + smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1]; out_be16(&smp->smc_rpbase, 0x1ec0); smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2]; diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index c194c4ae8bc7..3ce907523b1e 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -11,9 +11,6 @@ config PPC64 This option selects whether a 32-bit or a 64-bit kernel will be built. -config PPC_BOOK3S_32 - bool - menu "Processor support" choice prompt "Processor Type" @@ -23,20 +20,19 @@ choice The most common ones are the desktop and server CPUs (603, 604, 740, 750, 74xx) CPUs from Freescale and IBM, with their embedded 512x/52xx/82xx/83xx/86xx counterparts. - The other embedded parts, namely 4xx, 8xx, e200 (55xx) and e500 + The other embedded parts, namely 4xx, 8xx and e500 (85xx) each form a family of their own that is not compatible with the others. If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx. -config PPC_BOOK3S_6xx +config PPC_BOOK3S_32 bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx" - select PPC_BOOK3S_32 - select PPC_FPU + imply PPC_FPU select PPC_HAVE_PMU_SUPPORT select PPC_HAVE_KUEP select PPC_HAVE_KUAP - select HAVE_ARCH_VMAP_STACK if !ADB_PMU + select HAVE_ARCH_VMAP_STACK config PPC_85xx bool "Freescale 85xx" @@ -66,11 +62,24 @@ config 44x select HAVE_PCI select PHYS_64BIT -config E200 - bool "Freescale e200" - endchoice +config PPC_BOOK3S_603 + bool "Support for 603 SW loaded TLB" + depends on PPC_BOOK3S_32 + default y + help + Provide support for processors based on the 603 cores. Those + processors don't have a HASH MMU and provide SW TLB loading. + +config PPC_BOOK3S_604 + bool "Support for 604+ HASH MMU" if PPC_BOOK3S_603 + depends on PPC_BOOK3S_32 + default y + help + Provide support for processors not based on the 603 cores. + Those processors have a HASH MMU. + choice prompt "Processor Type" depends on PPC64 @@ -218,9 +227,20 @@ config PPC_E500MC such as e5500/e6500), and must be disabled for running on e500v1 or e500v2. -config PPC_FPU +config PPC_FPU_REGS bool + +config PPC_FPU + bool "Support for Floating Point Unit (FPU)" if PPC_MPC832x default y if PPC64 + select PPC_FPU_REGS + help + This must be enabled to support the Floating Point Unit + Most 6xx have an FPU but e300c2 core (mpc832x) don't have + an FPU, so when building an embedded kernel for that target + you can disable FPU support. + + If unsure say Y. config FSL_EMB_PERFMON bool "Freescale Embedded Perfmon" @@ -247,12 +267,12 @@ config 4xx config BOOKE bool - depends on E200 || E500 || 44x || PPC_BOOK3E + depends on E500 || 44x || PPC_BOOK3E default y config FSL_BOOKE bool - depends on (E200 || E500) && PPC32 + depends on E500 && PPC32 default y # this is for common code between PPC32 & PPC64 FSL BOOKE @@ -317,7 +337,7 @@ config VSX config SPE_POSSIBLE def_bool y - depends on E200 || (E500 && !PPC_E500MC) + depends on E500 && !PPC_E500MC config SPE bool "SPE Support" @@ -395,6 +415,11 @@ config PPC_KUAP_DEBUG Add extra debugging for Kernel Userspace Access Protection (KUAP) If you're unsure, say N. +config PPC_PKEY + def_bool y + depends on PPC_BOOK3S_64 + depends on PPC_MEM_KEYS || PPC_KUAP || PPC_KUEP + config ARCH_ENABLE_HUGEPAGE_MIGRATION def_bool y depends on PPC_BOOK3S_64 && HUGETLB_PAGE && MIGRATION @@ -464,7 +489,7 @@ config NR_CPUS config NOT_COHERENT_CACHE bool - depends on 4xx || PPC_8xx || E200 || PPC_MPC512x || \ + depends on 4xx || PPC_8xx || PPC_MPC512x || \ GAMECUBE_COMMON || AMIGAONE select ARCH_HAS_DMA_PREP_COHERENT select ARCH_HAS_SYNC_DMA_FOR_DEVICE diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S index 7e0f8ba6e54a..d497a60003d2 100644 --- a/arch/powerpc/platforms/powermac/sleep.S +++ b/arch/powerpc/platforms/powermac/sleep.S @@ -44,7 +44,8 @@ #define SL_TB 0xa0 #define SL_R2 0xa8 #define SL_CR 0xac -#define SL_R12 0xb0 /* r12 to r31 */ +#define SL_LR 0xb0 +#define SL_R12 0xb4 /* r12 to r31 */ #define SL_SIZE (SL_R12 + 80) .section .text @@ -63,105 +64,107 @@ _GLOBAL(low_sleep_handler) blr #else mflr r0 - stw r0,4(r1) - stwu r1,-SL_SIZE(r1) + lis r11,sleep_storage@ha + addi r11,r11,sleep_storage@l + stw r0,SL_LR(r11) mfcr r0 - stw r0,SL_CR(r1) - stw r2,SL_R2(r1) - stmw r12,SL_R12(r1) + stw r0,SL_CR(r11) + stw r1,SL_SP(r11) + stw r2,SL_R2(r11) + stmw r12,SL_R12(r11) /* Save MSR & SDR1 */ mfmsr r4 - stw r4,SL_MSR(r1) + stw r4,SL_MSR(r11) mfsdr1 r4 - stw r4,SL_SDR1(r1) + stw r4,SL_SDR1(r11) /* Get a stable timebase and save it */ 1: mftbu r4 - stw r4,SL_TB(r1) + stw r4,SL_TB(r11) mftb r5 - stw r5,SL_TB+4(r1) + stw r5,SL_TB+4(r11) mftbu r3 cmpw r3,r4 bne 1b /* Save SPRGs */ mfsprg r4,0 - stw r4,SL_SPRG0(r1) + stw r4,SL_SPRG0(r11) mfsprg r4,1 - stw r4,SL_SPRG0+4(r1) + stw r4,SL_SPRG0+4(r11) mfsprg r4,2 - stw r4,SL_SPRG0+8(r1) + stw r4,SL_SPRG0+8(r11) mfsprg r4,3 - stw r4,SL_SPRG0+12(r1) + stw r4,SL_SPRG0+12(r11) /* Save BATs */ mfdbatu r4,0 - stw r4,SL_DBAT0(r1) + stw r4,SL_DBAT0(r11) mfdbatl r4,0 - stw r4,SL_DBAT0+4(r1) + stw r4,SL_DBAT0+4(r11) mfdbatu r4,1 - stw r4,SL_DBAT1(r1) + stw r4,SL_DBAT1(r11) mfdbatl r4,1 - stw r4,SL_DBAT1+4(r1) + stw r4,SL_DBAT1+4(r11) mfdbatu r4,2 - stw r4,SL_DBAT2(r1) + stw r4,SL_DBAT2(r11) mfdbatl r4,2 - stw r4,SL_DBAT2+4(r1) + stw r4,SL_DBAT2+4(r11) mfdbatu r4,3 - stw r4,SL_DBAT3(r1) + stw r4,SL_DBAT3(r11) mfdbatl r4,3 - stw r4,SL_DBAT3+4(r1) + stw r4,SL_DBAT3+4(r11) mfibatu r4,0 - stw r4,SL_IBAT0(r1) + stw r4,SL_IBAT0(r11) mfibatl r4,0 - stw r4,SL_IBAT0+4(r1) + stw r4,SL_IBAT0+4(r11) mfibatu r4,1 - stw r4,SL_IBAT1(r1) + stw r4,SL_IBAT1(r11) mfibatl r4,1 - stw r4,SL_IBAT1+4(r1) + stw r4,SL_IBAT1+4(r11) mfibatu r4,2 - stw r4,SL_IBAT2(r1) + stw r4,SL_IBAT2(r11) mfibatl r4,2 - stw r4,SL_IBAT2+4(r1) + stw r4,SL_IBAT2+4(r11) mfibatu r4,3 - stw r4,SL_IBAT3(r1) + stw r4,SL_IBAT3(r11) mfibatl r4,3 - stw r4,SL_IBAT3+4(r1) + stw r4,SL_IBAT3+4(r11) BEGIN_MMU_FTR_SECTION mfspr r4,SPRN_DBAT4U - stw r4,SL_DBAT4(r1) + stw r4,SL_DBAT4(r11) mfspr r4,SPRN_DBAT4L - stw r4,SL_DBAT4+4(r1) + stw r4,SL_DBAT4+4(r11) mfspr r4,SPRN_DBAT5U - stw r4,SL_DBAT5(r1) + stw r4,SL_DBAT5(r11) mfspr r4,SPRN_DBAT5L - stw r4,SL_DBAT5+4(r1) + stw r4,SL_DBAT5+4(r11) mfspr r4,SPRN_DBAT6U - stw r4,SL_DBAT6(r1) + stw r4,SL_DBAT6(r11) mfspr r4,SPRN_DBAT6L - stw r4,SL_DBAT6+4(r1) + stw r4,SL_DBAT6+4(r11) mfspr r4,SPRN_DBAT7U - stw r4,SL_DBAT7(r1) + stw r4,SL_DBAT7(r11) mfspr r4,SPRN_DBAT7L - stw r4,SL_DBAT7+4(r1) + stw r4,SL_DBAT7+4(r11) mfspr r4,SPRN_IBAT4U - stw r4,SL_IBAT4(r1) + stw r4,SL_IBAT4(r11) mfspr r4,SPRN_IBAT4L - stw r4,SL_IBAT4+4(r1) + stw r4,SL_IBAT4+4(r11) mfspr r4,SPRN_IBAT5U - stw r4,SL_IBAT5(r1) + stw r4,SL_IBAT5(r11) mfspr r4,SPRN_IBAT5L - stw r4,SL_IBAT5+4(r1) + stw r4,SL_IBAT5+4(r11) mfspr r4,SPRN_IBAT6U - stw r4,SL_IBAT6(r1) + stw r4,SL_IBAT6(r11) mfspr r4,SPRN_IBAT6L - stw r4,SL_IBAT6+4(r1) + stw r4,SL_IBAT6+4(r11) mfspr r4,SPRN_IBAT7U - stw r4,SL_IBAT7(r1) + stw r4,SL_IBAT7(r11) mfspr r4,SPRN_IBAT7L - stw r4,SL_IBAT7+4(r1) + stw r4,SL_IBAT7+4(r11) END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) /* Backup various CPU config stuffs */ @@ -180,9 +183,9 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) lis r5,grackle_wake_up@ha addi r5,r5,grackle_wake_up@l tophys(r5,r5) - stw r5,SL_PC(r1) + stw r5,SL_PC(r11) lis r4,KERNELBASE@h - tophys(r5,r1) + tophys(r5,r11) addi r5,r5,SL_PC lis r6,MAGIC@ha addi r6,r6,MAGIC@l @@ -194,12 +197,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) tophys(r3,r3) stw r3,0x80(r4) stw r5,0x84(r4) - /* Store a pointer to our backup storage into - * a kernel global - */ - lis r3,sleep_storage@ha - addi r3,r3,sleep_storage@l - stw r5,0(r3) .globl low_cpu_offline_self low_cpu_offline_self: @@ -279,7 +276,7 @@ _GLOBAL(core99_wake_up) lis r3,sleep_storage@ha addi r3,r3,sleep_storage@l tophys(r3,r3) - lwz r1,0(r3) + addi r1,r3,SL_PC /* Pass thru to older resume code ... */ _ASM_NOKPROBE_SYMBOL(core99_wake_up) @@ -399,13 +396,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) blt 1b sync - /* restore the MSR and turn on the MMU */ - lwz r3,SL_MSR(r1) - bl turn_on_mmu - - /* get back the stack pointer */ - tovirt(r1,r1) - /* Restore TB */ li r3,0 mttbl r3 @@ -419,28 +409,24 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) mtcr r0 lwz r2,SL_R2(r1) lmw r12,SL_R12(r1) - addi r1,r1,SL_SIZE - lwz r0,4(r1) - mtlr r0 - blr -_ASM_NOKPROBE_SYMBOL(grackle_wake_up) -turn_on_mmu: - mflr r4 - tovirt(r4,r4) + /* restore the MSR and SP and turn on the MMU and return */ + lwz r3,SL_MSR(r1) + lwz r4,SL_LR(r1) + lwz r1,SL_SP(r1) mtsrr0 r4 mtsrr1 r3 sync isync rfi -_ASM_NOKPROBE_SYMBOL(turn_on_mmu) +_ASM_NOKPROBE_SYMBOL(grackle_wake_up) #endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */ - .section .data + .section .bss .balign L1_CACHE_BYTES sleep_storage: - .long 0 + .space SL_SIZE .balign L1_CACHE_BYTES, 0 #endif /* CONFIG_PPC_BOOK3S_32 */ diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig index 938803eab0ad..619b093a0657 100644 --- a/arch/powerpc/platforms/powernv/Kconfig +++ b/arch/powerpc/platforms/powernv/Kconfig @@ -27,11 +27,11 @@ config OPAL_PRD recovery diagnostics on OpenPower machines config PPC_MEMTRACE - bool "Enable removal of RAM from kernel mappings for tracing" - depends on PPC_POWERNV && MEMORY_HOTREMOVE + bool "Enable runtime allocation of RAM for tracing" + depends on PPC_POWERNV && MEMORY_HOTPLUG && CONTIG_ALLOC help - Enabling this option allows for the removal of memory (RAM) - from the kernel mappings to be used for hardware tracing. + Enabling this option allows for runtime allocation of memory (RAM) + for hardware tracing. config PPC_VAS bool "IBM Virtual Accelerator Switchboard (VAS)" diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index 1ed7c5286487..e6f461812856 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -589,6 +589,7 @@ struct p9_sprs { u64 spurr; u64 dscr; u64 wort; + u64 ciabr; u64 mmcra; u32 mmcr0; @@ -668,6 +669,7 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on) sprs.spurr = mfspr(SPRN_SPURR); sprs.dscr = mfspr(SPRN_DSCR); sprs.wort = mfspr(SPRN_WORT); + sprs.ciabr = mfspr(SPRN_CIABR); sprs.mmcra = mfspr(SPRN_MMCRA); sprs.mmcr0 = mfspr(SPRN_MMCR0); @@ -785,6 +787,7 @@ core_woken: mtspr(SPRN_SPURR, sprs.spurr); mtspr(SPRN_DSCR, sprs.dscr); mtspr(SPRN_WORT, sprs.wort); + mtspr(SPRN_CIABR, sprs.ciabr); mtspr(SPRN_MMCRA, sprs.mmcra); mtspr(SPRN_MMCR0, sprs.mmcr0); diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c index 6828108486f8..5fc9408bb0b3 100644 --- a/arch/powerpc/platforms/powernv/memtrace.c +++ b/arch/powerpc/platforms/powernv/memtrace.c @@ -30,6 +30,7 @@ struct memtrace_entry { char name[16]; }; +static DEFINE_MUTEX(memtrace_mutex); static u64 memtrace_size; static struct memtrace_entry *memtrace_array; @@ -50,84 +51,52 @@ static const struct file_operations memtrace_fops = { .open = simple_open, }; -static int check_memblock_online(struct memory_block *mem, void *arg) +static void memtrace_clear_range(unsigned long start_pfn, + unsigned long nr_pages) { - if (mem->state != MEM_ONLINE) - return -1; + unsigned long pfn; - return 0; -} - -static int change_memblock_state(struct memory_block *mem, void *arg) -{ - unsigned long state = (unsigned long)arg; - - mem->state = state; - - return 0; -} - -/* called with device_hotplug_lock held */ -static bool memtrace_offline_pages(u32 nid, u64 start_pfn, u64 nr_pages) -{ - const unsigned long start = PFN_PHYS(start_pfn); - const unsigned long size = PFN_PHYS(nr_pages); - - if (walk_memory_blocks(start, size, NULL, check_memblock_online)) - return false; - - walk_memory_blocks(start, size, (void *)MEM_GOING_OFFLINE, - change_memblock_state); - - if (offline_pages(start_pfn, nr_pages)) { - walk_memory_blocks(start, size, (void *)MEM_ONLINE, - change_memblock_state); - return false; + /* As HIGHMEM does not apply, use clear_page() directly. */ + for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { + if (IS_ALIGNED(pfn, PAGES_PER_SECTION)) + cond_resched(); + clear_page(__va(PFN_PHYS(pfn))); } - - walk_memory_blocks(start, size, (void *)MEM_OFFLINE, - change_memblock_state); - - - return true; } static u64 memtrace_alloc_node(u32 nid, u64 size) { - u64 start_pfn, end_pfn, nr_pages, pfn; - u64 base_pfn; - u64 bytes = memory_block_size_bytes(); + const unsigned long nr_pages = PHYS_PFN(size); + unsigned long pfn, start_pfn; + struct page *page; - if (!node_spanned_pages(nid)) + /* + * Trace memory needs to be aligned to the size, which is guaranteed + * by alloc_contig_pages(). + */ + page = alloc_contig_pages(nr_pages, GFP_KERNEL | __GFP_THISNODE | + __GFP_NOWARN, nid, NULL); + if (!page) return 0; + start_pfn = page_to_pfn(page); - start_pfn = node_start_pfn(nid); - end_pfn = node_end_pfn(nid); - nr_pages = size >> PAGE_SHIFT; - - /* Trace memory needs to be aligned to the size */ - end_pfn = round_down(end_pfn - nr_pages, nr_pages); - - lock_device_hotplug(); - for (base_pfn = end_pfn; base_pfn > start_pfn; base_pfn -= nr_pages) { - if (memtrace_offline_pages(nid, base_pfn, nr_pages) == true) { - /* - * Remove memory in memory block size chunks so that - * iomem resources are always split to the same size and - * we never try to remove memory that spans two iomem - * resources. - */ - end_pfn = base_pfn + nr_pages; - for (pfn = base_pfn; pfn < end_pfn; pfn += bytes>> PAGE_SHIFT) { - __remove_memory(nid, pfn << PAGE_SHIFT, bytes); - } - unlock_device_hotplug(); - return base_pfn << PAGE_SHIFT; - } - } - unlock_device_hotplug(); + /* + * Clear the range while we still have a linear mapping. + * + * TODO: use __GFP_ZERO with alloc_contig_pages() once supported. + */ + memtrace_clear_range(start_pfn, nr_pages); - return 0; + /* + * Set pages PageOffline(), to indicate that nobody (e.g., hibernation, + * dumping, ...) should be touching these pages. + */ + for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) + __SetPageOffline(pfn_to_page(pfn)); + + arch_remove_linear_mapping(PFN_PHYS(start_pfn), size); + + return PFN_PHYS(start_pfn); } static int memtrace_init_regions_runtime(u64 size) @@ -197,16 +166,30 @@ static int memtrace_init_debugfs(void) return ret; } -static int online_mem_block(struct memory_block *mem, void *arg) +static int memtrace_free(int nid, u64 start, u64 size) { - return device_online(&mem->dev); + struct mhp_params params = { .pgprot = PAGE_KERNEL }; + const unsigned long nr_pages = PHYS_PFN(size); + const unsigned long start_pfn = PHYS_PFN(start); + unsigned long pfn; + int ret; + + ret = arch_create_linear_mapping(nid, start, size, ¶ms); + if (ret) + return ret; + + for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) + __ClearPageOffline(pfn_to_page(pfn)); + + free_contig_range(start_pfn, nr_pages); + return 0; } /* - * Iterate through the chunks of memory we have removed from the kernel - * and attempt to add them back to the kernel. + * Iterate through the chunks of memory we allocated and attempt to expose + * them back to the kernel. */ -static int memtrace_online(void) +static int memtrace_free_regions(void) { int i, ret = 0; struct memtrace_entry *ent; @@ -214,7 +197,7 @@ static int memtrace_online(void) for (i = memtrace_array_nr - 1; i >= 0; i--) { ent = &memtrace_array[i]; - /* We have onlined this chunk previously */ + /* We have freed this chunk previously */ if (ent->nid == NUMA_NO_NODE) continue; @@ -224,30 +207,25 @@ static int memtrace_online(void) ent->mem = 0; } - if (add_memory(ent->nid, ent->start, ent->size, MHP_NONE)) { - pr_err("Failed to add trace memory to node %d\n", + if (memtrace_free(ent->nid, ent->start, ent->size)) { + pr_err("Failed to free trace memory on node %d\n", ent->nid); ret += 1; continue; } - lock_device_hotplug(); - walk_memory_blocks(ent->start, ent->size, NULL, - online_mem_block); - unlock_device_hotplug(); - /* - * Memory was added successfully so clean up references to it - * so on reentry we can tell that this chunk was added. + * Memory was freed successfully so clean up references to it + * so on reentry we can tell that this chunk was freed. */ debugfs_remove_recursive(ent->dir); - pr_info("Added trace memory back to node %d\n", ent->nid); + pr_info("Freed trace memory back on node %d\n", ent->nid); ent->size = ent->start = ent->nid = NUMA_NO_NODE; } if (ret) return ret; - /* If all chunks of memory were added successfully, reset globals */ + /* If all chunks of memory were freed successfully, reset globals */ kfree(memtrace_array); memtrace_array = NULL; memtrace_size = 0; @@ -257,6 +235,7 @@ static int memtrace_online(void) static int memtrace_enable_set(void *data, u64 val) { + int rc = -EAGAIN; u64 bytes; /* @@ -269,25 +248,29 @@ static int memtrace_enable_set(void *data, u64 val) return -EINVAL; } - /* Re-add/online previously removed/offlined memory */ - if (memtrace_size) { - if (memtrace_online()) - return -EAGAIN; - } + mutex_lock(&memtrace_mutex); - if (!val) - return 0; + /* Free all previously allocated memory. */ + if (memtrace_size && memtrace_free_regions()) + goto out_unlock; + + if (!val) { + rc = 0; + goto out_unlock; + } - /* Offline and remove memory */ + /* Allocate memory. */ if (memtrace_init_regions_runtime(val)) - return -EINVAL; + goto out_unlock; if (memtrace_init_debugfs()) - return -EINVAL; + goto out_unlock; memtrace_size = val; - - return 0; + rc = 0; +out_unlock: + mutex_unlock(&memtrace_mutex); + return rc; } static int memtrace_enable_get(void *data, u64 *val) diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c index abeaa533b976..b711dc3262a3 100644 --- a/arch/powerpc/platforms/powernv/npu-dma.c +++ b/arch/powerpc/platforms/powernv/npu-dma.c @@ -385,7 +385,8 @@ static void pnv_npu_peers_take_ownership(struct iommu_table_group *table_group) for (i = 0; i < npucomp->pe_num; ++i) { struct pnv_ioda_pe *pe = npucomp->pe[i]; - if (!pe->table_group.ops->take_ownership) + if (!pe->table_group.ops || + !pe->table_group.ops->take_ownership) continue; pe->table_group.ops->take_ownership(&pe->table_group); } @@ -401,7 +402,8 @@ static void pnv_npu_peers_release_ownership( for (i = 0; i < npucomp->pe_num; ++i) { struct pnv_ioda_pe *pe = npucomp->pe[i]; - if (!pe->table_group.ops->release_ownership) + if (!pe->table_group.ops || + !pe->table_group.ops->release_ownership) continue; pe->table_group.ops->release_ownership(&pe->table_group); } @@ -623,6 +625,11 @@ int pnv_npu2_map_lpar_dev(struct pci_dev *gpdev, unsigned int lparid, return -ENODEV; hose = pci_bus_to_host(npdev->bus); + if (hose->npu == NULL) { + dev_info_once(&npdev->dev, "Nvlink1 does not support contexts"); + return 0; + } + nphb = hose->private_data; dev_dbg(&gpdev->dev, "Map LPAR opalid=%llu lparid=%u\n", @@ -670,6 +677,11 @@ int pnv_npu2_unmap_lpar_dev(struct pci_dev *gpdev) return -ENODEV; hose = pci_bus_to_host(npdev->bus); + if (hose->npu == NULL) { + dev_info_once(&npdev->dev, "Nvlink1 does not support contexts"); + return 0; + } + nphb = hose->private_data; dev_dbg(&gpdev->dev, "destroy context opalid=%llu\n", diff --git a/arch/powerpc/platforms/powernv/ocxl.c b/arch/powerpc/platforms/powernv/ocxl.c index ecdad219d704..9105efcf242a 100644 --- a/arch/powerpc/platforms/powernv/ocxl.c +++ b/arch/powerpc/platforms/powernv/ocxl.c @@ -483,3 +483,117 @@ int pnv_ocxl_spa_remove_pe_from_cache(void *platform_data, int pe_handle) return rc; } EXPORT_SYMBOL_GPL(pnv_ocxl_spa_remove_pe_from_cache); + +int pnv_ocxl_map_lpar(struct pci_dev *dev, uint64_t lparid, + uint64_t lpcr, void __iomem **arva) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + struct pnv_phb *phb = hose->private_data; + u64 mmio_atsd; + int rc; + + /* ATSD physical address. + * ATSD LAUNCH register: write access initiates a shoot down to + * initiate the TLB Invalidate command. + */ + rc = of_property_read_u64_index(hose->dn, "ibm,mmio-atsd", + 0, &mmio_atsd); + if (rc) { + dev_info(&dev->dev, "No available ATSD found\n"); + return rc; + } + + /* Assign a register set to a Logical Partition and MMIO ATSD + * LPARID register to the required value. + */ + rc = opal_npu_map_lpar(phb->opal_id, pci_dev_id(dev), + lparid, lpcr); + if (rc) { + dev_err(&dev->dev, "Error mapping device to LPAR: %d\n", rc); + return rc; + } + + *arva = ioremap(mmio_atsd, 24); + if (!(*arva)) { + dev_warn(&dev->dev, "ioremap failed - mmio_atsd: %#llx\n", mmio_atsd); + rc = -ENOMEM; + } + + return rc; +} +EXPORT_SYMBOL_GPL(pnv_ocxl_map_lpar); + +void pnv_ocxl_unmap_lpar(void __iomem *arva) +{ + iounmap(arva); +} +EXPORT_SYMBOL_GPL(pnv_ocxl_unmap_lpar); + +void pnv_ocxl_tlb_invalidate(void __iomem *arva, + unsigned long pid, + unsigned long addr, + unsigned long page_size) +{ + unsigned long timeout = jiffies + (HZ * PNV_OCXL_ATSD_TIMEOUT); + u64 val = 0ull; + int pend; + u8 size; + + if (!(arva)) + return; + + if (addr) { + /* load Abbreviated Virtual Address register with + * the necessary value + */ + val |= FIELD_PREP(PNV_OCXL_ATSD_AVA_AVA, addr >> (63-51)); + out_be64(arva + PNV_OCXL_ATSD_AVA, val); + } + + /* Write access initiates a shoot down to initiate the + * TLB Invalidate command + */ + val = PNV_OCXL_ATSD_LNCH_R; + val |= FIELD_PREP(PNV_OCXL_ATSD_LNCH_RIC, 0b10); + if (addr) + val |= FIELD_PREP(PNV_OCXL_ATSD_LNCH_IS, 0b00); + else { + val |= FIELD_PREP(PNV_OCXL_ATSD_LNCH_IS, 0b01); + val |= PNV_OCXL_ATSD_LNCH_OCAPI_SINGLETON; + } + val |= PNV_OCXL_ATSD_LNCH_PRS; + /* Actual Page Size to be invalidated + * 000 4KB + * 101 64KB + * 001 2MB + * 010 1GB + */ + size = 0b101; + if (page_size == 0x1000) + size = 0b000; + if (page_size == 0x200000) + size = 0b001; + if (page_size == 0x40000000) + size = 0b010; + val |= FIELD_PREP(PNV_OCXL_ATSD_LNCH_AP, size); + val |= FIELD_PREP(PNV_OCXL_ATSD_LNCH_PID, pid); + out_be64(arva + PNV_OCXL_ATSD_LNCH, val); + + /* Poll the ATSD status register to determine when the + * TLB Invalidate has been completed. + */ + val = in_be64(arva + PNV_OCXL_ATSD_STAT); + pend = val >> 63; + + while (pend) { + if (time_after_eq(jiffies, timeout)) { + pr_err("%s - Timeout while reading XTS MMIO ATSD status register (val=%#llx, pidr=0x%lx)\n", + __func__, val, pid); + return; + } + cpu_relax(); + val = in_be64(arva + PNV_OCXL_ATSD_STAT); + pend = val >> 63; + } +} +EXPORT_SYMBOL_GPL(pnv_ocxl_tlb_invalidate); diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c index 37b380eef41a..5821b0fa8614 100644 --- a/arch/powerpc/platforms/powernv/opal-elog.c +++ b/arch/powerpc/platforms/powernv/opal-elog.c @@ -171,8 +171,8 @@ static ssize_t raw_attr_read(struct file *filep, struct kobject *kobj, opal_rc = opal_read_elog(__pa(elog->buffer), elog->size, elog->id); if (opal_rc != OPAL_SUCCESS) { - pr_err("ELOG: log read failed for log-id=%llx\n", - elog->id); + pr_err_ratelimited("ELOG: log read failed for log-id=%llx\n", + elog->id); kfree(elog->buffer); elog->buffer = NULL; return -EIO; diff --git a/arch/powerpc/platforms/powernv/opal-hmi.c b/arch/powerpc/platforms/powernv/opal-hmi.c index 3e1f064a18db..f0c1830deb51 100644 --- a/arch/powerpc/platforms/powernv/opal-hmi.c +++ b/arch/powerpc/platforms/powernv/opal-hmi.c @@ -213,6 +213,8 @@ static void print_hmi_event_info(struct OpalHMIEvent *hmi_evt) "A hypervisor resource error occurred", "CAPP recovery process is in progress", }; + static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST); /* Print things out */ if (hmi_evt->version < OpalHMIEvt_V1) { @@ -240,19 +242,22 @@ static void print_hmi_event_info(struct OpalHMIEvent *hmi_evt) break; } - printk("%s%s Hypervisor Maintenance interrupt [%s]\n", - level, sevstr, - hmi_evt->disposition == OpalHMI_DISPOSITION_RECOVERED ? - "Recovered" : "Not recovered"); - error_info = hmi_evt->type < ARRAY_SIZE(hmi_error_types) ? - hmi_error_types[hmi_evt->type] - : "Unknown"; - printk("%s Error detail: %s\n", level, error_info); - printk("%s HMER: %016llx\n", level, be64_to_cpu(hmi_evt->hmer)); - if ((hmi_evt->type == OpalHMI_ERROR_TFAC) || - (hmi_evt->type == OpalHMI_ERROR_TFMR_PARITY)) - printk("%s TFMR: %016llx\n", level, + if (hmi_evt->severity != OpalHMI_SEV_NO_ERROR || __ratelimit(&rs)) { + printk("%s%s Hypervisor Maintenance interrupt [%s]\n", + level, sevstr, + hmi_evt->disposition == OpalHMI_DISPOSITION_RECOVERED ? + "Recovered" : "Not recovered"); + error_info = hmi_evt->type < ARRAY_SIZE(hmi_error_types) ? + hmi_error_types[hmi_evt->type] + : "Unknown"; + printk("%s Error detail: %s\n", level, error_info); + printk("%s HMER: %016llx\n", level, + be64_to_cpu(hmi_evt->hmer)); + if ((hmi_evt->type == OpalHMI_ERROR_TFAC) || + (hmi_evt->type == OpalHMI_ERROR_TFMR_PARITY)) + printk("%s TFMR: %016llx\n", level, be64_to_cpu(hmi_evt->tfmr)); + } if (hmi_evt->version < OpalHMIEvt_V2) return; diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index d95954ad4c0a..c61c3b62c8c6 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -731,7 +731,7 @@ int opal_hmi_exception_early2(struct pt_regs *regs) return 1; } -/* HMI exception handler called in virtual mode during check_irq_replay. */ +/* HMI exception handler called in virtual mode when irqs are next enabled. */ int opal_handle_hmi_exception(struct pt_regs *regs) { /* diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 2b4ceb5e6ce4..c4f72cdc9b51 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2613,8 +2613,10 @@ static bool pnv_pci_enable_device_hook(struct pci_dev *dev) return true; pdn = pci_get_pdn(dev); - if (!pdn || pdn->pe_number == IODA_INVALID_PE) + if (!pdn || pdn->pe_number == IODA_INVALID_PE) { + pci_err(dev, "pci_enable_device() blocked, no PE assigned.\n"); return false; + } return true; } diff --git a/arch/powerpc/platforms/powernv/pci-sriov.c b/arch/powerpc/platforms/powernv/pci-sriov.c index c4434f20f42f..28aac933a439 100644 --- a/arch/powerpc/platforms/powernv/pci-sriov.c +++ b/arch/powerpc/platforms/powernv/pci-sriov.c @@ -422,7 +422,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) { struct pnv_iov_data *iov; struct pnv_phb *phb; - unsigned int win; + int win; struct resource *res; int i, j; int64_t rc; diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index c62aaa29a9d5..b431f41c6cb5 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -382,7 +382,6 @@ static int ps3_system_bus_probe(struct device *_dev) static int ps3_system_bus_remove(struct device *_dev) { - int result = 0; struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); struct ps3_system_bus_driver *drv; @@ -393,13 +392,13 @@ static int ps3_system_bus_remove(struct device *_dev) BUG_ON(!drv); if (drv->remove) - result = drv->remove(dev); + drv->remove(dev); else dev_dbg(&dev->core, "%s:%d %s: no remove method\n", __func__, __LINE__, drv->core.name); pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core)); - return result; + return 0; } static void ps3_system_bus_shutdown(struct device *_dev) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index a02012f1b04a..12cbffd3c2e3 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -746,6 +746,7 @@ static int dlpar_cpu_add_by_count(u32 cpus_to_add) parent = of_find_node_by_path("/cpus"); if (!parent) { pr_warn("Could not find CPU root node in device tree\n"); + kfree(cpu_drcs); return -1; } diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 7efe6ec5d14a..8377f1f7c78e 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -479,7 +479,7 @@ static int dlpar_memory_remove_by_index(u32 drc_index) int lmb_found; int rc; - pr_info("Attempting to hot-remove LMB, drc index %x\n", drc_index); + pr_debug("Attempting to hot-remove LMB, drc index %x\n", drc_index); lmb_found = 0; for_each_drmem_lmb(lmb) { @@ -497,10 +497,10 @@ static int dlpar_memory_remove_by_index(u32 drc_index) rc = -EINVAL; if (rc) - pr_info("Failed to hot-remove memory at %llx\n", - lmb->base_addr); + pr_debug("Failed to hot-remove memory at %llx\n", + lmb->base_addr); else - pr_info("Memory at %llx was hot-removed\n", lmb->base_addr); + pr_debug("Memory at %llx was hot-removed\n", lmb->base_addr); return rc; } @@ -717,8 +717,8 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add) if (!drmem_lmb_reserved(lmb)) continue; - pr_info("Memory at %llx (drc index %x) was hot-added\n", - lmb->base_addr, lmb->drc_index); + pr_debug("Memory at %llx (drc index %x) was hot-added\n", + lmb->base_addr, lmb->drc_index); drmem_remove_lmb_reservation(lmb); } rc = 0; diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index e4198700ed1a..9fc5217f0c8e 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -839,7 +839,7 @@ static void remove_ddw(struct device_node *np, bool remove_prop) np, ret); } -static u64 find_existing_ddw(struct device_node *pdn) +static u64 find_existing_ddw(struct device_node *pdn, int *window_shift) { struct direct_window *window; const struct dynamic_dma_window_prop *direct64; @@ -851,6 +851,7 @@ static u64 find_existing_ddw(struct device_node *pdn) if (window->device == pdn) { direct64 = window->prop; dma_addr = be64_to_cpu(direct64->dma_base); + *window_shift = be32_to_cpu(direct64->window_shift); break; } } @@ -1111,11 +1112,12 @@ static void reset_dma_window(struct pci_dev *dev, struct device_node *par_dn) */ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) { - int len, ret; + int len = 0, ret; + int max_ram_len = order_base_2(ddw_memory_hotplug_max()); struct ddw_query_response query; struct ddw_create_response create; int page_shift; - u64 dma_addr, max_addr; + u64 dma_addr; struct device_node *dn; u32 ddw_avail[DDW_APPLICABLE_SIZE]; struct direct_window *window; @@ -1123,10 +1125,15 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) struct dynamic_dma_window_prop *ddwprop; struct failed_ddw_pdn *fpdn; bool default_win_removed = false; + bool pmem_present; + + dn = of_find_node_by_type(NULL, "ibm,pmemory"); + pmem_present = dn != NULL; + of_node_put(dn); mutex_lock(&direct_window_init_mutex); - dma_addr = find_existing_ddw(pdn); + dma_addr = find_existing_ddw(pdn, &len); if (dma_addr != 0) goto out_unlock; @@ -1212,14 +1219,29 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) } /* verify the window * number of ptes will map the partition */ /* check largest block * page size > max memory hotplug addr */ - max_addr = ddw_memory_hotplug_max(); - if (query.largest_available_block < (max_addr >> page_shift)) { - dev_dbg(&dev->dev, "can't map partition max 0x%llx with %llu " - "%llu-sized pages\n", max_addr, query.largest_available_block, - 1ULL << page_shift); + /* + * The "ibm,pmemory" can appear anywhere in the address space. + * Assuming it is still backed by page structs, try MAX_PHYSMEM_BITS + * for the upper limit and fallback to max RAM otherwise but this + * disables device::dma_ops_bypass. + */ + len = max_ram_len; + if (pmem_present) { + if (query.largest_available_block >= + (1ULL << (MAX_PHYSMEM_BITS - page_shift))) + len = MAX_PHYSMEM_BITS - page_shift; + else + dev_info(&dev->dev, "Skipping ibm,pmemory"); + } + + if (query.largest_available_block < (1ULL << (len - page_shift))) { + dev_dbg(&dev->dev, + "can't map partition max 0x%llx with %llu %llu-sized pages\n", + 1ULL << len, + query.largest_available_block, + 1ULL << page_shift); goto out_failed; } - len = order_base_2(max_addr); win64 = kzalloc(sizeof(struct property), GFP_KERNEL); if (!win64) { dev_info(&dev->dev, @@ -1299,6 +1321,15 @@ out_failed: out_unlock: mutex_unlock(&direct_window_init_mutex); + + /* + * If we have persistent memory and the window size is only as big + * as RAM, then we failed to create a window to cover persistent + * memory and need to set the DMA limit. + */ + if (pmem_present && dma_addr && (len == max_ram_len)) + dev->dev.bus_dma_limit = dma_addr + (1ULL << len); + return dma_addr; } diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index 2f73cb5bf12d..ea4d6a660e0d 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -12,9 +12,11 @@ #include <linux/cpu.h> #include <linux/kernel.h> #include <linux/kobject.h> +#include <linux/nmi.h> #include <linux/sched.h> #include <linux/smp.h> #include <linux/stat.h> +#include <linux/stop_machine.h> #include <linux/completion.h> #include <linux/device.h> #include <linux/delay.h> @@ -59,18 +61,10 @@ static int mobility_rtas_call(int token, char *buf, s32 scope) return rc; } -static int delete_dt_node(__be32 phandle) +static int delete_dt_node(struct device_node *dn) { - struct device_node *dn; - - dn = of_find_node_by_phandle(be32_to_cpu(phandle)); - if (!dn) - return -ENOENT; - pr_debug("removing node %pOFfp\n", dn); - dlpar_detach_node(dn); - of_node_put(dn); return 0; } @@ -135,10 +129,9 @@ static int update_dt_property(struct device_node *dn, struct property **prop, return 0; } -static int update_dt_node(__be32 phandle, s32 scope) +static int update_dt_node(struct device_node *dn, s32 scope) { struct update_props_workarea *upwa; - struct device_node *dn; struct property *prop = NULL; int i, rc, rtas_rc; char *prop_data; @@ -155,14 +148,8 @@ static int update_dt_node(__be32 phandle, s32 scope) if (!rtas_buf) return -ENOMEM; - dn = of_find_node_by_phandle(be32_to_cpu(phandle)); - if (!dn) { - kfree(rtas_buf); - return -ENOENT; - } - upwa = (struct update_props_workarea *)&rtas_buf[0]; - upwa->phandle = phandle; + upwa->phandle = cpu_to_be32(dn->phandle); do { rtas_rc = mobility_rtas_call(update_properties_token, rtas_buf, @@ -208,11 +195,12 @@ static int update_dt_node(__be32 phandle, s32 scope) rc = update_dt_property(dn, &prop, prop_name, vd, prop_data); if (rc) { - printk(KERN_ERR "Could not update %s" - " property\n", prop_name); + pr_err("updating %s property failed: %d\n", + prop_name, rc); } prop_data += vd; + break; } cond_resched(); @@ -221,26 +209,18 @@ static int update_dt_node(__be32 phandle, s32 scope) cond_resched(); } while (rtas_rc == 1); - of_node_put(dn); kfree(rtas_buf); return 0; } -static int add_dt_node(__be32 parent_phandle, __be32 drc_index) +static int add_dt_node(struct device_node *parent_dn, __be32 drc_index) { struct device_node *dn; - struct device_node *parent_dn; int rc; - parent_dn = of_find_node_by_phandle(be32_to_cpu(parent_phandle)); - if (!parent_dn) - return -ENOENT; - dn = dlpar_configure_connector(drc_index, parent_dn); - if (!dn) { - of_node_put(parent_dn); + if (!dn) return -ENOENT; - } rc = dlpar_attach_node(dn, parent_dn); if (rc) @@ -248,7 +228,6 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index) pr_debug("added node %pOFfp\n", dn); - of_node_put(parent_dn); return rc; } @@ -261,7 +240,7 @@ int pseries_devicetree_update(s32 scope) update_nodes_token = rtas_token("ibm,update-nodes"); if (update_nodes_token == RTAS_UNKNOWN_SERVICE) - return -EINVAL; + return 0; rtas_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); if (!rtas_buf) @@ -281,22 +260,31 @@ int pseries_devicetree_update(s32 scope) data++; for (i = 0; i < node_count; i++) { + struct device_node *np; __be32 phandle = *data++; __be32 drc_index; + np = of_find_node_by_phandle(be32_to_cpu(phandle)); + if (!np) { + pr_warn("Failed lookup: phandle 0x%x for action 0x%x\n", + be32_to_cpu(phandle), action); + continue; + } + switch (action) { case DELETE_DT_NODE: - delete_dt_node(phandle); + delete_dt_node(np); break; case UPDATE_DT_NODE: - update_dt_node(phandle, scope); + update_dt_node(np, scope); break; case ADD_DT_NODE: drc_index = *data++; - add_dt_node(phandle, drc_index); + add_dt_node(np, drc_index); break; } + of_node_put(np); cond_resched(); } } @@ -311,21 +299,8 @@ int pseries_devicetree_update(s32 scope) void post_mobility_fixup(void) { int rc; - int activate_fw_token; - - activate_fw_token = rtas_token("ibm,activate-firmware"); - if (activate_fw_token == RTAS_UNKNOWN_SERVICE) { - printk(KERN_ERR "Could not make post-mobility " - "activate-fw call.\n"); - return; - } - - do { - rc = rtas_call(activate_fw_token, 0, 1, NULL); - } while (rtas_busy_delay(rc)); - if (rc) - printk(KERN_ERR "Post-mobility activate-fw failed: %d\n", rc); + rtas_activate_firmware(); /* * We don't want CPUs to go online/offline while the device @@ -342,8 +317,7 @@ void post_mobility_fixup(void) rc = pseries_devicetree_update(MIGRATION_SCOPE); if (rc) - printk(KERN_ERR "Post-mobility device tree update " - "failed: %d\n", rc); + pr_err("device tree update failed: %d\n", rc); cacheinfo_rebuild(); @@ -358,6 +332,279 @@ void post_mobility_fixup(void) return; } +static int poll_vasi_state(u64 handle, unsigned long *res) +{ + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + long hvrc; + int ret; + + hvrc = plpar_hcall(H_VASI_STATE, retbuf, handle); + switch (hvrc) { + case H_SUCCESS: + ret = 0; + *res = retbuf[0]; + break; + case H_PARAMETER: + ret = -EINVAL; + break; + case H_FUNCTION: + ret = -EOPNOTSUPP; + break; + case H_HARDWARE: + default: + pr_err("unexpected H_VASI_STATE result %ld\n", hvrc); + ret = -EIO; + break; + } + return ret; +} + +static int wait_for_vasi_session_suspending(u64 handle) +{ + unsigned long state; + int ret; + + /* + * Wait for transition from H_VASI_ENABLED to + * H_VASI_SUSPENDING. Treat anything else as an error. + */ + while (true) { + ret = poll_vasi_state(handle, &state); + + if (ret != 0 || state == H_VASI_SUSPENDING) { + break; + } else if (state == H_VASI_ENABLED) { + ssleep(1); + } else { + pr_err("unexpected H_VASI_STATE result %lu\n", state); + ret = -EIO; + break; + } + } + + /* + * Proceed even if H_VASI_STATE is unavailable. If H_JOIN or + * ibm,suspend-me are also unimplemented, we'll recover then. + */ + if (ret == -EOPNOTSUPP) + ret = 0; + + return ret; +} + +static void prod_single(unsigned int target_cpu) +{ + long hvrc; + int hwid; + + hwid = get_hard_smp_processor_id(target_cpu); + hvrc = plpar_hcall_norets(H_PROD, hwid); + if (hvrc == H_SUCCESS) + return; + pr_err_ratelimited("H_PROD of CPU %u (hwid %d) error: %ld\n", + target_cpu, hwid, hvrc); +} + +static void prod_others(void) +{ + unsigned int cpu; + + for_each_online_cpu(cpu) { + if (cpu != smp_processor_id()) + prod_single(cpu); + } +} + +static u16 clamp_slb_size(void) +{ + u16 prev = mmu_slb_size; + + slb_set_size(SLB_MIN_SIZE); + + return prev; +} + +static int do_suspend(void) +{ + u16 saved_slb_size; + int status; + int ret; + + pr_info("calling ibm,suspend-me on CPU %i\n", smp_processor_id()); + + /* + * The destination processor model may have fewer SLB entries + * than the source. We reduce mmu_slb_size to a safe minimum + * before suspending in order to minimize the possibility of + * programming non-existent entries on the destination. If + * suspend fails, we restore it before returning. On success + * the OF reconfig path will update it from the new device + * tree after resuming on the destination. + */ + saved_slb_size = clamp_slb_size(); + + ret = rtas_ibm_suspend_me(&status); + if (ret != 0) { + pr_err("ibm,suspend-me error: %d\n", status); + slb_set_size(saved_slb_size); + } + + return ret; +} + +static int do_join(void *arg) +{ + atomic_t *counter = arg; + long hvrc; + int ret; + + /* Must ensure MSR.EE off for H_JOIN. */ + hard_irq_disable(); + hvrc = plpar_hcall_norets(H_JOIN); + + switch (hvrc) { + case H_CONTINUE: + /* + * All other CPUs are offline or in H_JOIN. This CPU + * attempts the suspend. + */ + ret = do_suspend(); + break; + case H_SUCCESS: + /* + * The suspend is complete and this cpu has received a + * prod. + */ + ret = 0; + break; + case H_BAD_MODE: + case H_HARDWARE: + default: + ret = -EIO; + pr_err_ratelimited("H_JOIN error %ld on CPU %i\n", + hvrc, smp_processor_id()); + break; + } + + if (atomic_inc_return(counter) == 1) { + pr_info("CPU %u waking all threads\n", smp_processor_id()); + prod_others(); + } + /* + * Execution may have been suspended for several seconds, so + * reset the watchdog. + */ + touch_nmi_watchdog(); + return ret; +} + +/* + * Abort reason code byte 0. We use only the 'Migrating partition' value. + */ +enum vasi_aborting_entity { + ORCHESTRATOR = 1, + VSP_SOURCE = 2, + PARTITION_FIRMWARE = 3, + PLATFORM_FIRMWARE = 4, + VSP_TARGET = 5, + MIGRATING_PARTITION = 6, +}; + +static void pseries_cancel_migration(u64 handle, int err) +{ + u32 reason_code; + u32 detail; + u8 entity; + long hvrc; + + entity = MIGRATING_PARTITION; + detail = abs(err) & 0xffffff; + reason_code = (entity << 24) | detail; + + hvrc = plpar_hcall_norets(H_VASI_SIGNAL, handle, + H_VASI_SIGNAL_CANCEL, reason_code); + if (hvrc) + pr_err("H_VASI_SIGNAL error: %ld\n", hvrc); +} + +static int pseries_suspend(u64 handle) +{ + const unsigned int max_attempts = 5; + unsigned int retry_interval_ms = 1; + unsigned int attempt = 1; + int ret; + + while (true) { + atomic_t counter = ATOMIC_INIT(0); + unsigned long vasi_state; + int vasi_err; + + ret = stop_machine(do_join, &counter, cpu_online_mask); + if (ret == 0) + break; + /* + * Encountered an error. If the VASI stream is still + * in Suspending state, it's likely a transient + * condition related to some device in the partition + * and we can retry in the hope that the cause has + * cleared after some delay. + * + * A better design would allow drivers etc to prepare + * for the suspend and avoid conditions which prevent + * the suspend from succeeding. For now, we have this + * mitigation. + */ + pr_notice("Partition suspend attempt %u of %u error: %d\n", + attempt, max_attempts, ret); + + if (attempt == max_attempts) + break; + + vasi_err = poll_vasi_state(handle, &vasi_state); + if (vasi_err == 0) { + if (vasi_state != H_VASI_SUSPENDING) { + pr_notice("VASI state %lu after failed suspend\n", + vasi_state); + break; + } + } else if (vasi_err != -EOPNOTSUPP) { + pr_err("VASI state poll error: %d", vasi_err); + break; + } + + pr_notice("Will retry partition suspend after %u ms\n", + retry_interval_ms); + + msleep(retry_interval_ms); + retry_interval_ms *= 10; + attempt++; + } + + return ret; +} + +static int pseries_migrate_partition(u64 handle) +{ + int ret; + + ret = wait_for_vasi_session_suspending(handle); + if (ret) + return ret; + + ret = pseries_suspend(handle); + if (ret == 0) + post_mobility_fixup(); + else + pseries_cancel_migration(handle, ret); + + return ret; +} + +int rtas_syscall_dispatch_ibm_suspend_me(u64 handle) +{ + return pseries_migrate_partition(handle); +} + static ssize_t migration_store(struct class *class, struct class_attribute *attr, const char *buf, size_t count) @@ -369,17 +616,10 @@ static ssize_t migration_store(struct class *class, if (rc) return rc; - do { - rc = rtas_ibm_suspend_me(streamid); - if (rc == -EAGAIN) - ssleep(1); - } while (rc == -EAGAIN); - + rc = pseries_migrate_partition(streamid); if (rc) return rc; - post_mobility_fixup(); - return count; } diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index 911534b89c85..72a4d4167849 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c @@ -290,6 +290,25 @@ static void fixup_winbond_82c105(struct pci_dev* dev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, fixup_winbond_82c105); +static enum pci_bus_speed prop_to_pci_speed(u32 prop) +{ + switch (prop) { + case 0x01: + return PCIE_SPEED_2_5GT; + case 0x02: + return PCIE_SPEED_5_0GT; + case 0x04: + return PCIE_SPEED_8_0GT; + case 0x08: + return PCIE_SPEED_16_0GT; + case 0x10: + return PCIE_SPEED_32_0GT; + default: + pr_debug("Unexpected PCI link speed property value\n"); + return PCI_SPEED_UNKNOWN; + } +} + int pseries_root_bridge_prepare(struct pci_host_bridge *bridge) { struct device_node *dn, *pdn; @@ -322,35 +341,7 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge) return 0; } - switch (pcie_link_speed_stats[0]) { - case 0x01: - bus->max_bus_speed = PCIE_SPEED_2_5GT; - break; - case 0x02: - bus->max_bus_speed = PCIE_SPEED_5_0GT; - break; - case 0x04: - bus->max_bus_speed = PCIE_SPEED_8_0GT; - break; - default: - bus->max_bus_speed = PCI_SPEED_UNKNOWN; - break; - } - - switch (pcie_link_speed_stats[1]) { - case 0x01: - bus->cur_bus_speed = PCIE_SPEED_2_5GT; - break; - case 0x02: - bus->cur_bus_speed = PCIE_SPEED_5_0GT; - break; - case 0x04: - bus->cur_bus_speed = PCIE_SPEED_8_0GT; - break; - default: - bus->cur_bus_speed = PCI_SPEED_UNKNOWN; - break; - } - + bus->max_bus_speed = prop_to_pci_speed(pcie_link_speed_stats[0]); + bus->cur_bus_speed = prop_to_pci_speed(pcie_link_speed_stats[1]); return 0; } diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index b2b245b25edb..149cec2212e6 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -526,8 +526,11 @@ static int mce_handle_err_realmode(int disposition, u8 error_type) #ifdef CONFIG_PPC_BOOK3S_64 if (disposition == RTAS_DISP_NOT_RECOVERED) { switch (error_type) { - case MC_ERROR_TYPE_SLB: case MC_ERROR_TYPE_ERAT: + flush_erat(); + disposition = RTAS_DISP_FULLY_RECOVERED; + break; + case MC_ERROR_TYPE_SLB: /* * Store the old slb content in paca before flushing. * Print this when we go to virtual mode. diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 92922491a81c..c70b4be9f0a5 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -42,6 +42,7 @@ #include <asm/plpar_wrappers.h> #include <asm/code-patching.h> #include <asm/svm.h> +#include <asm/kvm_guest.h> #include "pseries.h" @@ -210,7 +211,7 @@ static __init void pSeries_smp_probe(void) if (!cpu_has_feature(CPU_FTR_SMT)) return; - if (is_kvm_guest()) { + if (check_kvm_guest()) { /* * KVM emulates doorbells by disabling FSCR[MSGP] so msgsndp * faults to the hypervisor which then reads the instruction diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c index 81e0ac58d620..1b902cbf85c5 100644 --- a/arch/powerpc/platforms/pseries/suspend.c +++ b/arch/powerpc/platforms/pseries/suspend.c @@ -13,13 +13,8 @@ #include <asm/mmu.h> #include <asm/rtas.h> #include <asm/topology.h> -#include "../../kernel/cacheinfo.h" -static u64 stream_id; static struct device suspend_dev; -static DECLARE_COMPLETION(suspend_work); -static struct rtas_suspend_me_data suspend_data; -static atomic_t suspending; /** * pseries_suspend_begin - First phase of hibernation @@ -29,7 +24,7 @@ static atomic_t suspending; * Return value: * 0 on success / other on failure **/ -static int pseries_suspend_begin(suspend_state_t state) +static int pseries_suspend_begin(u64 stream_id) { long vasi_state, rc; unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; @@ -49,41 +44,10 @@ static int pseries_suspend_begin(suspend_state_t state) vasi_state); return -EIO; } - - return 0; -} - -/** - * pseries_suspend_cpu - Suspend a single CPU - * - * Makes the H_JOIN call to suspend the CPU - * - **/ -static int pseries_suspend_cpu(void) -{ - if (atomic_read(&suspending)) - return rtas_suspend_cpu(&suspend_data); return 0; } /** - * pseries_suspend_enable_irqs - * - * Post suspend configuration updates - * - **/ -static void pseries_suspend_enable_irqs(void) -{ - /* - * Update configuration which can be modified based on device tree - * changes during resume. - */ - cacheinfo_cpu_offline(smp_processor_id()); - post_mobility_fixup(); - cacheinfo_cpu_online(smp_processor_id()); -} - -/** * pseries_suspend_enter - Final phase of hibernation * * Return value: @@ -91,28 +55,7 @@ static void pseries_suspend_enable_irqs(void) **/ static int pseries_suspend_enter(suspend_state_t state) { - int rc = rtas_suspend_last_cpu(&suspend_data); - - atomic_set(&suspending, 0); - atomic_set(&suspend_data.done, 1); - return rc; -} - -/** - * pseries_prepare_late - Prepare to suspend all other CPUs - * - * Return value: - * 0 on success / other on failure - **/ -static int pseries_prepare_late(void) -{ - atomic_set(&suspending, 1); - atomic_set(&suspend_data.working, 0); - atomic_set(&suspend_data.done, 0); - atomic_set(&suspend_data.error, 0); - suspend_data.complete = &suspend_work; - reinit_completion(&suspend_work); - return 0; + return rtas_ibm_suspend_me(NULL); } /** @@ -132,6 +75,7 @@ static ssize_t store_hibernate(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + u64 stream_id; int rc; if (!capable(CAP_SYS_ADMIN)) @@ -140,7 +84,7 @@ static ssize_t store_hibernate(struct device *dev, stream_id = simple_strtoul(buf, NULL, 16); do { - rc = pseries_suspend_begin(PM_SUSPEND_MEM); + rc = pseries_suspend_begin(stream_id); if (rc == -EAGAIN) ssleep(1); } while (rc == -EAGAIN); @@ -148,10 +92,11 @@ static ssize_t store_hibernate(struct device *dev, if (!rc) rc = pm_suspend(PM_SUSPEND_MEM); - stream_id = 0; - - if (!rc) + if (!rc) { rc = count; + post_mobility_fixup(); + } + return rc; } @@ -187,8 +132,6 @@ static struct bus_type suspend_subsys = { static const struct platform_suspend_ops pseries_suspend_ops = { .valid = suspend_valid_only_mem, - .begin = pseries_suspend_begin, - .prepare_late = pseries_prepare_late, .enter = pseries_suspend_enter, }; @@ -231,15 +174,9 @@ static int __init pseries_suspend_init(void) if (!firmware_has_feature(FW_FEATURE_LPAR)) return 0; - suspend_data.token = rtas_token("ibm,suspend-me"); - if (suspend_data.token == RTAS_UNKNOWN_SERVICE) - return 0; - if ((rc = pseries_suspend_sysfs_register(&suspend_dev))) return rc; - ppc_md.suspend_disable_cpu = pseries_suspend_cpu; - ppc_md.suspend_enable_irqs = pseries_suspend_enable_irqs; suspend_set_ops(&pseries_suspend_ops); return 0; } diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c index f6b253e2be40..36ec0bdd8b63 100644 --- a/arch/powerpc/sysdev/mpic_msgr.c +++ b/arch/powerpc/sysdev/mpic_msgr.c @@ -191,7 +191,7 @@ static int mpic_msgr_probe(struct platform_device *dev) /* IO map the message register block. */ of_address_to_resource(np, 0, &rsrc); - msgr_block_addr = ioremap(rsrc.start, resource_size(&rsrc)); + msgr_block_addr = devm_ioremap(&dev->dev, rsrc.start, resource_size(&rsrc)); if (!msgr_block_addr) { dev_err(&dev->dev, "Failed to iomap MPIC message registers"); return -EFAULT; diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index a80440af491a..595310e056f4 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -200,10 +200,6 @@ static notrace u8 xive_esb_read(struct xive_irq_data *xd, u32 offset) if (offset == XIVE_ESB_SET_PQ_10 && xd->flags & XIVE_IRQ_FLAG_STORE_EOI) offset |= XIVE_ESB_LD_ST_MO; - /* Handle HW errata */ - if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG) - offset |= offset << 4; - if ((xd->flags & XIVE_IRQ_FLAG_H_INT_ESB) && xive_ops->esb_rw) val = xive_ops->esb_rw(xd->hw_irq, offset, 0, 0); else @@ -214,10 +210,6 @@ static notrace u8 xive_esb_read(struct xive_irq_data *xd, u32 offset) static void xive_esb_write(struct xive_irq_data *xd, u32 offset, u64 data) { - /* Handle HW errata */ - if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG) - offset |= offset << 4; - if ((xd->flags & XIVE_IRQ_FLAG_H_INT_ESB) && xive_ops->esb_rw) xive_ops->esb_rw(xd->hw_irq, offset, data, 1); else @@ -356,50 +348,40 @@ static void xive_do_queue_eoi(struct xive_cpu *xc) * EOI an interrupt at the source. There are several methods * to do this depending on the HW version and source type */ -static void xive_do_source_eoi(u32 hw_irq, struct xive_irq_data *xd) +static void xive_do_source_eoi(struct xive_irq_data *xd) { + u8 eoi_val; + xd->stale_p = false; + /* If the XIVE supports the new "store EOI facility, use it */ - if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI) + if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI) { xive_esb_write(xd, XIVE_ESB_STORE_EOI, 0); - else if (hw_irq && xd->flags & XIVE_IRQ_FLAG_EOI_FW) { - /* - * The FW told us to call it. This happens for some - * interrupt sources that need additional HW whacking - * beyond the ESB manipulation. For example LPC interrupts - * on P9 DD1.0 needed a latch to be clared in the LPC bridge - * itself. The Firmware will take care of it. - */ - if (WARN_ON_ONCE(!xive_ops->eoi)) - return; - xive_ops->eoi(hw_irq); - } else { - u8 eoi_val; + return; + } - /* - * Otherwise for EOI, we use the special MMIO that does - * a clear of both P and Q and returns the old Q, - * except for LSIs where we use the "EOI cycle" special - * load. - * - * This allows us to then do a re-trigger if Q was set - * rather than synthesizing an interrupt in software - * - * For LSIs the HW EOI cycle is used rather than PQ bits, - * as they are automatically re-triggred in HW when still - * pending. - */ - if (xd->flags & XIVE_IRQ_FLAG_LSI) - xive_esb_read(xd, XIVE_ESB_LOAD_EOI); - else { - eoi_val = xive_esb_read(xd, XIVE_ESB_SET_PQ_00); - DBG_VERBOSE("eoi_val=%x\n", eoi_val); - - /* Re-trigger if needed */ - if ((eoi_val & XIVE_ESB_VAL_Q) && xd->trig_mmio) - out_be64(xd->trig_mmio, 0); - } + /* + * For LSIs, we use the "EOI cycle" special load rather than + * PQ bits, as they are automatically re-triggered in HW when + * still pending. + */ + if (xd->flags & XIVE_IRQ_FLAG_LSI) { + xive_esb_read(xd, XIVE_ESB_LOAD_EOI); + return; } + + /* + * Otherwise, we use the special MMIO that does a clear of + * both P and Q and returns the old Q. This allows us to then + * do a re-trigger if Q was set rather than synthesizing an + * interrupt in software + */ + eoi_val = xive_esb_read(xd, XIVE_ESB_SET_PQ_00); + DBG_VERBOSE("eoi_val=%x\n", eoi_val); + + /* Re-trigger if needed */ + if ((eoi_val & XIVE_ESB_VAL_Q) && xd->trig_mmio) + out_be64(xd->trig_mmio, 0); } /* irq_chip eoi callback, called with irq descriptor lock held */ @@ -416,8 +398,8 @@ static void xive_irq_eoi(struct irq_data *d) * been passed-through to a KVM guest */ if (!irqd_irq_disabled(d) && !irqd_is_forwarded_to_vcpu(d) && - !(xd->flags & XIVE_IRQ_NO_EOI)) - xive_do_source_eoi(irqd_to_hwirq(d), xd); + !(xd->flags & XIVE_IRQ_FLAG_NO_EOI)) + xive_do_source_eoi(xd); else xd->stale_p = true; @@ -432,9 +414,7 @@ static void xive_irq_eoi(struct irq_data *d) } /* - * Helper used to mask and unmask an interrupt source. This - * is only called for normal interrupts that do not require - * masking/unmasking via firmware. + * Helper used to mask and unmask an interrupt source. */ static void xive_do_source_set_mask(struct xive_irq_data *xd, bool mask) @@ -681,20 +661,6 @@ static void xive_irq_unmask(struct irq_data *d) pr_devel("xive_irq_unmask: irq %d data @%p\n", d->irq, xd); - /* - * This is a workaround for PCI LSI problems on P9, for - * these, we call FW to set the mask. The problems might - * be fixed by P9 DD2.0, if that is the case, firmware - * will no longer set that flag. - */ - if (xd->flags & XIVE_IRQ_FLAG_MASK_FW) { - unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); - xive_ops->configure_irq(hw_irq, - get_hard_smp_processor_id(xd->target), - xive_irq_priority, d->irq); - return; - } - xive_do_source_set_mask(xd, false); } @@ -704,20 +670,6 @@ static void xive_irq_mask(struct irq_data *d) pr_devel("xive_irq_mask: irq %d data @%p\n", d->irq, xd); - /* - * This is a workaround for PCI LSI problems on P9, for - * these, we call OPAL to set the mask. The problems might - * be fixed by P9 DD2.0, if that is the case, firmware - * will no longer set that flag. - */ - if (xd->flags & XIVE_IRQ_FLAG_MASK_FW) { - unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); - xive_ops->configure_irq(hw_irq, - get_hard_smp_processor_id(xd->target), - 0xff, d->irq); - return; - } - xive_do_source_set_mask(xd, true); } @@ -837,14 +789,7 @@ static int xive_irq_retrigger(struct irq_data *d) * 11, then perform an EOI. */ xive_esb_read(xd, XIVE_ESB_SET_PQ_11); - - /* - * Note: We pass "0" to the hw_irq argument in order to - * avoid calling into the backend EOI code which we don't - * want to do in the case of a re-trigger. Backends typically - * only do EOI for LSIs anyway. - */ - xive_do_source_eoi(0, xd); + xive_do_source_eoi(xd); return 1; } @@ -861,13 +806,6 @@ static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state) u8 pq; /* - * We only support this on interrupts that do not require - * firmware calls for masking and unmasking - */ - if (xd->flags & XIVE_IRQ_FLAG_MASK_FW) - return -EIO; - - /* * This is called by KVM with state non-NULL for enabling * pass-through or NULL for disabling it */ @@ -966,7 +904,7 @@ static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state) * while masked, the generic code will re-mask it anyway. */ if (!xd->saved_p) - xive_do_source_eoi(hw_irq, xd); + xive_do_source_eoi(xd); } return 0; @@ -1110,7 +1048,7 @@ static void xive_ipi_eoi(struct irq_data *d) DBG_VERBOSE("IPI eoi: irq=%d [0x%lx] (HW IRQ 0x%x) pending=%02x\n", d->irq, irqd_to_hwirq(d), xc->hw_ipi, xc->pending_prio); - xive_do_source_eoi(xc->hw_ipi, &xc->ipi_data); + xive_do_source_eoi(&xc->ipi_data); xive_do_queue_eoi(xc); } @@ -1142,7 +1080,7 @@ static void __init xive_request_ipi(void) return; /* Initialize it */ - virq = irq_create_mapping(xive_irq_domain, 0); + virq = irq_create_mapping(xive_irq_domain, XIVE_IPI_HW_IRQ); xive_ipi_irq = virq; WARN_ON(request_irq(virq, xive_muxed_ipi_action, @@ -1242,7 +1180,7 @@ static int xive_irq_domain_map(struct irq_domain *h, unsigned int virq, #ifdef CONFIG_SMP /* IPIs are special and come up with HW number 0 */ - if (hw == 0) { + if (hw == XIVE_IPI_HW_IRQ) { /* * IPIs are marked per-cpu. We use separate HW interrupts under * the hood but associated with the same "linux" interrupt @@ -1271,7 +1209,7 @@ static void xive_irq_domain_unmap(struct irq_domain *d, unsigned int virq) if (!data) return; hw_irq = (unsigned int)irqd_to_hwirq(data); - if (hw_irq) + if (hw_irq != XIVE_IPI_HW_IRQ) xive_irq_free_data(virq); } @@ -1303,16 +1241,71 @@ static int xive_irq_domain_match(struct irq_domain *h, struct device_node *node, return xive_ops->match(node); } +#ifdef CONFIG_GENERIC_IRQ_DEBUGFS +static const char * const esb_names[] = { "RESET", "OFF", "PENDING", "QUEUED" }; + +static const struct { + u64 mask; + char *name; +} xive_irq_flags[] = { + { XIVE_IRQ_FLAG_STORE_EOI, "STORE_EOI" }, + { XIVE_IRQ_FLAG_LSI, "LSI" }, + { XIVE_IRQ_FLAG_H_INT_ESB, "H_INT_ESB" }, + { XIVE_IRQ_FLAG_NO_EOI, "NO_EOI" }, +}; + +static void xive_irq_domain_debug_show(struct seq_file *m, struct irq_domain *d, + struct irq_data *irqd, int ind) +{ + struct xive_irq_data *xd; + u64 val; + int i; + + /* No IRQ domain level information. To be done */ + if (!irqd) + return; + + if (!is_xive_irq(irq_data_get_irq_chip(irqd))) + return; + + seq_printf(m, "%*sXIVE:\n", ind, ""); + ind++; + + xd = irq_data_get_irq_handler_data(irqd); + if (!xd) { + seq_printf(m, "%*snot assigned\n", ind, ""); + return; + } + + val = xive_esb_read(xd, XIVE_ESB_GET); + seq_printf(m, "%*sESB: %s\n", ind, "", esb_names[val & 0x3]); + seq_printf(m, "%*sPstate: %s %s\n", ind, "", xd->stale_p ? "stale" : "", + xd->saved_p ? "saved" : ""); + seq_printf(m, "%*sTarget: %d\n", ind, "", xd->target); + seq_printf(m, "%*sChip: %d\n", ind, "", xd->src_chip); + seq_printf(m, "%*sTrigger: 0x%016llx\n", ind, "", xd->trig_page); + seq_printf(m, "%*sEOI: 0x%016llx\n", ind, "", xd->eoi_page); + seq_printf(m, "%*sFlags: 0x%llx\n", ind, "", xd->flags); + for (i = 0; i < ARRAY_SIZE(xive_irq_flags); i++) { + if (xd->flags & xive_irq_flags[i].mask) + seq_printf(m, "%*s%s\n", ind + 12, "", xive_irq_flags[i].name); + } +} +#endif + static const struct irq_domain_ops xive_irq_domain_ops = { .match = xive_irq_domain_match, .map = xive_irq_domain_map, .unmap = xive_irq_domain_unmap, .xlate = xive_irq_domain_xlate, +#ifdef CONFIG_GENERIC_IRQ_DEBUGFS + .debug_show = xive_irq_domain_debug_show, +#endif }; -static void __init xive_init_host(void) +static void __init xive_init_host(struct device_node *np) { - xive_irq_domain = irq_domain_add_nomap(NULL, XIVE_MAX_IRQ, + xive_irq_domain = irq_domain_add_nomap(np, XIVE_MAX_IRQ, &xive_irq_domain_ops, NULL); if (WARN_ON(xive_irq_domain == NULL)) return; @@ -1421,7 +1414,7 @@ static void xive_flush_cpu_queue(unsigned int cpu, struct xive_cpu *xc) * Ignore anything that isn't a XIVE irq and ignore * IPIs, so can just be dropped. */ - if (d->domain != xive_irq_domain || hw_irq == 0) + if (d->domain != xive_irq_domain || hw_irq == XIVE_IPI_HW_IRQ) continue; /* @@ -1446,7 +1439,7 @@ static void xive_flush_cpu_queue(unsigned int cpu, struct xive_cpu *xc) * still asserted. Otherwise do an MSI retrigger. */ if (xd->flags & XIVE_IRQ_FLAG_LSI) - xive_do_source_eoi(irqd_to_hwirq(d), xd); + xive_do_source_eoi(xd); else xive_irq_retrigger(d); @@ -1513,8 +1506,8 @@ void xive_shutdown(void) xive_ops->shutdown(); } -bool __init xive_core_init(const struct xive_ops *ops, void __iomem *area, u32 offset, - u8 max_prio) +bool __init xive_core_init(struct device_node *np, const struct xive_ops *ops, + void __iomem *area, u32 offset, u8 max_prio) { xive_tima = area; xive_tima_offset = offset; @@ -1525,7 +1518,7 @@ bool __init xive_core_init(const struct xive_ops *ops, void __iomem *area, u32 o __xive_enabled = true; pr_devel("Initializing host..\n"); - xive_init_host(); + xive_init_host(np); pr_devel("Initializing boot CPU..\n"); @@ -1655,7 +1648,7 @@ static int xive_core_debug_show(struct seq_file *m, void *private) hw_irq = (unsigned int)irqd_to_hwirq(d); /* IPIs are special (HW number 0) */ - if (hw_irq) + if (hw_irq != XIVE_IPI_HW_IRQ) xive_debug_show_irq(m, hw_irq, d); } return 0; diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index cb58ec7ce77a..05a800a3104e 100644 --- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c @@ -64,12 +64,6 @@ int xive_native_populate_irq_data(u32 hw_irq, struct xive_irq_data *data) data->flags |= XIVE_IRQ_FLAG_STORE_EOI; if (opal_flags & OPAL_XIVE_IRQ_LSI) data->flags |= XIVE_IRQ_FLAG_LSI; - if (opal_flags & OPAL_XIVE_IRQ_SHIFT_BUG) - data->flags |= XIVE_IRQ_FLAG_SHIFT_BUG; - if (opal_flags & OPAL_XIVE_IRQ_MASK_VIA_FW) - data->flags |= XIVE_IRQ_FLAG_MASK_FW; - if (opal_flags & OPAL_XIVE_IRQ_EOI_VIA_FW) - data->flags |= XIVE_IRQ_FLAG_EOI_FW; data->eoi_page = be64_to_cpu(eoi_page); data->trig_page = be64_to_cpu(trig_page); data->esb_shift = be32_to_cpu(esb_shift); @@ -128,6 +122,8 @@ static int xive_native_get_irq_config(u32 hw_irq, u32 *target, u8 *prio, return rc == 0 ? 0 : -ENXIO; } +#define vp_err(vp, fmt, ...) pr_err("VP[0x%x]: " fmt, vp, ##__VA_ARGS__) + /* This can be called multiple time to change a queue configuration */ int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio, __be32 *qpage, u32 order, bool can_escalate) @@ -155,7 +151,7 @@ int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio, &esc_irq_be, NULL); if (rc) { - pr_err("Error %lld getting queue info prio %d\n", rc, prio); + vp_err(vp_id, "Failed to get queue %d info : %lld\n", prio, rc); rc = -EIO; goto fail; } @@ -178,7 +174,7 @@ int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio, msleep(OPAL_BUSY_DELAY_MS); } if (rc) { - pr_err("Error %lld setting queue for prio %d\n", rc, prio); + vp_err(vp_id, "Failed to set queue %d info: %lld\n", prio, rc); rc = -EIO; } else { /* @@ -205,7 +201,7 @@ static void __xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio) msleep(OPAL_BUSY_DELAY_MS); } if (rc) - pr_err("Error %lld disabling queue for prio %d\n", rc, prio); + vp_err(vp_id, "Failed to disable queue %d : %lld\n", prio, rc); } void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio) @@ -384,15 +380,6 @@ static void xive_native_update_pending(struct xive_cpu *xc) } } -static void xive_native_eoi(u32 hw_irq) -{ - /* - * Not normally used except if specific interrupts need - * a workaround on EOI. - */ - opal_int_eoi(hw_irq); -} - static void xive_native_setup_cpu(unsigned int cpu, struct xive_cpu *xc) { s64 rc; @@ -475,7 +462,6 @@ static const struct xive_ops xive_native_ops = { .match = xive_native_match, .shutdown = xive_native_shutdown, .update_pending = xive_native_update_pending, - .eoi = xive_native_eoi, .setup_cpu = xive_native_setup_cpu, .teardown_cpu = xive_native_teardown_cpu, .sync_source = xive_native_sync_source, @@ -622,7 +608,7 @@ bool __init xive_native_init(void) xive_native_setup_pools(); /* Initialize XIVE core with our backend */ - if (!xive_core_init(&xive_native_ops, tima, TM_QW3_HV_PHYS, + if (!xive_core_init(np, &xive_native_ops, tima, TM_QW3_HV_PHYS, max_prio)) { opal_xive_reset(OPAL_XIVE_MODE_EMU); return false; @@ -714,6 +700,8 @@ int xive_native_enable_vp(u32 vp_id, bool single_escalation) break; msleep(OPAL_BUSY_DELAY_MS); } + if (rc) + vp_err(vp_id, "Failed to enable VP : %lld\n", rc); return rc ? -EIO : 0; } EXPORT_SYMBOL_GPL(xive_native_enable_vp); @@ -728,6 +716,8 @@ int xive_native_disable_vp(u32 vp_id) break; msleep(OPAL_BUSY_DELAY_MS); } + if (rc) + vp_err(vp_id, "Failed to disable VP : %lld\n", rc); return rc ? -EIO : 0; } EXPORT_SYMBOL_GPL(xive_native_disable_vp); @@ -739,8 +729,10 @@ int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id) s64 rc; rc = opal_xive_get_vp_info(vp_id, NULL, &vp_cam_be, NULL, &vp_chip_id_be); - if (rc) + if (rc) { + vp_err(vp_id, "Failed to get VP info : %lld\n", rc); return -EIO; + } *out_cam_id = be64_to_cpu(vp_cam_be) & 0xffffffffu; *out_chip_id = be32_to_cpu(vp_chip_id_be); @@ -771,8 +763,7 @@ int xive_native_get_queue_info(u32 vp_id, u32 prio, rc = opal_xive_get_queue_info(vp_id, prio, &qpage, &qsize, &qeoi_page, &escalate_irq, &qflags); if (rc) { - pr_err("OPAL failed to get queue info for VCPU %d/%d : %lld\n", - vp_id, prio, rc); + vp_err(vp_id, "failed to get queue %d info : %lld\n", prio, rc); return -EIO; } @@ -800,8 +791,7 @@ int xive_native_get_queue_state(u32 vp_id, u32 prio, u32 *qtoggle, u32 *qindex) rc = opal_xive_get_queue_state(vp_id, prio, &opal_qtoggle, &opal_qindex); if (rc) { - pr_err("OPAL failed to get queue state for VCPU %d/%d : %lld\n", - vp_id, prio, rc); + vp_err(vp_id, "failed to get queue %d state : %lld\n", prio, rc); return -EIO; } @@ -820,8 +810,7 @@ int xive_native_set_queue_state(u32 vp_id, u32 prio, u32 qtoggle, u32 qindex) rc = opal_xive_set_queue_state(vp_id, prio, qtoggle, qindex); if (rc) { - pr_err("OPAL failed to set queue state for VCPU %d/%d : %lld\n", - vp_id, prio, rc); + vp_err(vp_id, "failed to set queue %d state : %lld\n", prio, rc); return -EIO; } @@ -843,8 +832,7 @@ int xive_native_get_vp_state(u32 vp_id, u64 *out_state) rc = opal_xive_get_vp_state(vp_id, &state); if (rc) { - pr_err("OPAL failed to get vp state for VCPU %d : %lld\n", - vp_id, rc); + vp_err(vp_id, "failed to get vp state : %lld\n", rc); return -EIO; } diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c index 1e3674d7ea7b..01ccc0786ada 100644 --- a/arch/powerpc/sysdev/xive/spapr.c +++ b/arch/powerpc/sysdev/xive/spapr.c @@ -628,11 +628,6 @@ static void xive_spapr_update_pending(struct xive_cpu *xc) } } -static void xive_spapr_eoi(u32 hw_irq) -{ - /* Not used */; -} - static void xive_spapr_setup_cpu(unsigned int cpu, struct xive_cpu *xc) { /* Only some debug on the TIMA settings */ @@ -677,7 +672,6 @@ static const struct xive_ops xive_spapr_ops = { .match = xive_spapr_match, .shutdown = xive_spapr_shutdown, .update_pending = xive_spapr_update_pending, - .eoi = xive_spapr_eoi, .setup_cpu = xive_spapr_setup_cpu, .teardown_cpu = xive_spapr_teardown_cpu, .sync_source = xive_spapr_sync_source, @@ -857,7 +851,7 @@ bool __init xive_spapr_init(void) } /* Initialize XIVE core with our backend */ - if (!xive_core_init(&xive_spapr_ops, tima, TM_QW1_OS, max_prio)) + if (!xive_core_init(np, &xive_spapr_ops, tima, TM_QW1_OS, max_prio)) return false; pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10)); diff --git a/arch/powerpc/sysdev/xive/xive-internal.h b/arch/powerpc/sysdev/xive/xive-internal.h index b7b901da2168..9cf57c722faa 100644 --- a/arch/powerpc/sysdev/xive/xive-internal.h +++ b/arch/powerpc/sysdev/xive/xive-internal.h @@ -5,6 +5,8 @@ #ifndef __XIVE_INTERNAL_H #define __XIVE_INTERNAL_H +#define XIVE_IPI_HW_IRQ 0 /* interrupt source # for IPIs */ + /* * A "disabled" interrupt should never fire, to catch problems * we set its logical number to this @@ -50,7 +52,6 @@ struct xive_ops { void (*shutdown)(void); void (*update_pending)(struct xive_cpu *xc); - void (*eoi)(u32 hw_irq); void (*sync_source)(u32 hw_irq); u64 (*esb_rw)(u32 hw_irq, u32 offset, u64 data, bool write); #ifdef CONFIG_SMP @@ -61,8 +62,8 @@ struct xive_ops { const char *name; }; -bool xive_core_init(const struct xive_ops *ops, void __iomem *area, u32 offset, - u8 max_prio); +bool xive_core_init(struct device_node *np, const struct xive_ops *ops, + void __iomem *area, u32 offset, u8 max_prio); __be32 *xive_queue_page_alloc(unsigned int cpu, u32 queue_shift); int xive_core_debug_init(void); diff --git a/arch/powerpc/xmon/nonstdio.c b/arch/powerpc/xmon/nonstdio.c index 5c1a50912229..9b0d85bff021 100644 --- a/arch/powerpc/xmon/nonstdio.c +++ b/arch/powerpc/xmon/nonstdio.c @@ -178,7 +178,7 @@ void xmon_printf(const char *format, ...) if (n && rc == 0) { /* No udbg hooks, fallback to printk() - dangerous */ - printk("%s", xmon_outbuf); + pr_cont("%s", xmon_outbuf); } } diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 55c43a6c9111..dcd817ca2edf 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -1383,6 +1383,7 @@ static long check_bp_loc(unsigned long addr) return 1; } +#ifndef CONFIG_PPC_8xx static int find_free_data_bpt(void) { int i; @@ -1394,6 +1395,7 @@ static int find_free_data_bpt(void) printf("Couldn't find free breakpoint register\n"); return -1; } +#endif static void print_data_bpts(void) { @@ -1745,9 +1747,9 @@ static void print_bug_trap(struct pt_regs *regs) #ifdef CONFIG_DEBUG_BUGVERBOSE printf("kernel BUG at %s:%u!\n", - bug->file, bug->line); + (char *)bug + bug->file_disp, bug->line); #else - printf("kernel BUG at %px!\n", (void *)bug->bug_addr); + printf("kernel BUG at %px!\n", (void *)bug + bug->bug_addr_disp); #endif #endif /* CONFIG_BUG */ } diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 880c2b3b65d0..e9e2c1f0a690 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -15,6 +15,7 @@ config RISCV select ARCH_CLOCKSOURCE_INIT select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_SUPPORTS_DEBUG_PAGEALLOC if MMU + select ARCH_STACKWALK select ARCH_HAS_BINFMT_FLAT select ARCH_HAS_DEBUG_VM_PGTABLE select ARCH_HAS_DEBUG_VIRTUAL if MMU @@ -43,6 +44,7 @@ config RISCV select GENERIC_IOREMAP select GENERIC_IRQ_MULTI_HANDLER select GENERIC_IRQ_SHOW + select GENERIC_LIB_DEVMEM_IS_ALLOWED select GENERIC_PCI_IOMAP select GENERIC_PTDUMP if MMU select GENERIC_SCHED_CLOCK @@ -68,6 +70,7 @@ config RISCV select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_GCC_PLUGINS select HAVE_GENERIC_VDSO if MMU && 64BIT + select HAVE_IRQ_TIME_ACCOUNTING select HAVE_PCI select HAVE_PERF_EVENTS select HAVE_PERF_REGS @@ -134,7 +137,7 @@ config PA_BITS config PAGE_OFFSET hex - default 0xC0000000 if 32BIT && MAXPHYSMEM_2GB + default 0xC0000000 if 32BIT && MAXPHYSMEM_1GB default 0x80000000 if 64BIT && !MMU default 0xffffffff80000000 if 64BIT && MAXPHYSMEM_2GB default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB @@ -244,10 +247,12 @@ config MODULE_SECTIONS choice prompt "Maximum Physical Memory" - default MAXPHYSMEM_2GB if 32BIT + default MAXPHYSMEM_1GB if 32BIT default MAXPHYSMEM_2GB if 64BIT && CMODEL_MEDLOW default MAXPHYSMEM_128GB if 64BIT && CMODEL_MEDANY + config MAXPHYSMEM_1GB + bool "1GiB" config MAXPHYSMEM_2GB bool "2GiB" config MAXPHYSMEM_128GB diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs index 8a55f6156661..3284d5c291be 100644 --- a/arch/riscv/Kconfig.socs +++ b/arch/riscv/Kconfig.socs @@ -5,7 +5,7 @@ config SOC_SIFIVE select SERIAL_SIFIVE if TTY select SERIAL_SIFIVE_CONSOLE if TTY select CLK_SIFIVE - select CLK_SIFIVE_FU540_PRCI + select CLK_SIFIVE_PRCI select SIFIVE_PLIC help This enables support for SiFive SoC platform hardware. diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 0289a97325d1..8c29e553ef7f 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -96,5 +96,11 @@ $(BOOT_TARGETS): vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ @$(kecho) ' Kernel: $(boot)/$@ is ready' +Image.%: Image + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ + zinstall install: $(Q)$(MAKE) $(build)=$(boot) $@ + +archclean: + $(Q)$(MAKE) $(clean)=$(boot) diff --git a/arch/riscv/boot/.gitignore b/arch/riscv/boot/.gitignore index 574c10f8ff68..90e66adb7de5 100644 --- a/arch/riscv/boot/.gitignore +++ b/arch/riscv/boot/.gitignore @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only Image -Image.gz +Image.* loader loader.lds +loader.bin diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile index c59fca695f9d..03404c84f971 100644 --- a/arch/riscv/boot/Makefile +++ b/arch/riscv/boot/Makefile @@ -18,7 +18,7 @@ KCOV_INSTRUMENT := n OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S -targets := Image loader +targets := Image Image.* loader loader.o loader.lds loader.bin $(obj)/Image: vmlinux FORCE $(call if_changed,objcopy) diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts index 4a2729f5ca3f..24d75a146e02 100644 --- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts +++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts @@ -88,7 +88,9 @@ phy-mode = "gmii"; phy-handle = <&phy0>; phy0: ethernet-phy@0 { + compatible = "ethernet-phy-id0007.0771"; reg = <0>; + reset-gpios = <&gpio 12 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig index d222d353d86d..8c3d1e451703 100644 --- a/arch/riscv/configs/defconfig +++ b/arch/riscv/configs/defconfig @@ -64,6 +64,8 @@ CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_VIRTIO=y CONFIG_SPI=y CONFIG_SPI_SIFIVE=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SIFIVE=y # CONFIG_PTP_1588_CLOCK is not set CONFIG_POWER_RESET=y CONFIG_DRM=y diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild index 59dd7be55005..445ccc97305a 100644 --- a/arch/riscv/include/asm/Kbuild +++ b/arch/riscv/include/asm/Kbuild @@ -3,6 +3,5 @@ generic-y += early_ioremap.h generic-y += extable.h generic-y += flat.h generic-y += kvm_para.h -generic-y += local64.h generic-y += user.h generic-y += vmlinux.lds.h diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h index 7542282f1141..6d98cd999680 100644 --- a/arch/riscv/include/asm/efi.h +++ b/arch/riscv/include/asm/efi.h @@ -27,12 +27,6 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); #define ARCH_EFI_IRQ_FLAGS_MASK (SR_IE | SR_SPIE) -/* on RISC-V, the FDT may be located anywhere in system RAM */ -static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr) -{ - return ULONG_MAX; -} - /* Load initrd at enough distance from DRAM start */ static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr) { diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 41a72861987c..251e1db088fa 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -99,7 +99,6 @@ | _PAGE_DIRTY) #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) -#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL | _PAGE_EXEC) #define PAGE_KERNEL_READ __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) #define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL | _PAGE_EXEC) #define PAGE_KERNEL_READ_EXEC __pgprot((_PAGE_KERNEL & ~_PAGE_WRITE) \ diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h index 3a9971b1210f..1595c5b60cfd 100644 --- a/arch/riscv/include/asm/sections.h +++ b/arch/riscv/include/asm/sections.h @@ -9,5 +9,7 @@ extern char _start[]; extern char _start_kernel[]; +extern char __init_data_begin[], __init_data_end[]; +extern char __init_text_begin[], __init_text_end[]; #endif /* __ASM_SECTIONS_H */ diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h index d690b08dff2a..211eb8244a45 100644 --- a/arch/riscv/include/asm/set_memory.h +++ b/arch/riscv/include/asm/set_memory.h @@ -15,11 +15,15 @@ int set_memory_ro(unsigned long addr, int numpages); int set_memory_rw(unsigned long addr, int numpages); int set_memory_x(unsigned long addr, int numpages); int set_memory_nx(unsigned long addr, int numpages); +int set_memory_rw_nx(unsigned long addr, int numpages); +void protect_kernel_text_data(void); #else static inline int set_memory_ro(unsigned long addr, int numpages) { return 0; } static inline int set_memory_rw(unsigned long addr, int numpages) { return 0; } static inline int set_memory_x(unsigned long addr, int numpages) { return 0; } static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; } +static inline void protect_kernel_text_data(void) {}; +static inline int set_memory_rw_nx(unsigned long addr, int numpages) { return 0; } #endif int set_direct_map_invalid_noflush(struct page *page); diff --git a/arch/riscv/include/asm/stacktrace.h b/arch/riscv/include/asm/stacktrace.h new file mode 100644 index 000000000000..470a65c4ccdc --- /dev/null +++ b/arch/riscv/include/asm/stacktrace.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _ASM_RISCV_STACKTRACE_H +#define _ASM_RISCV_STACKTRACE_H + +#include <linux/sched.h> +#include <asm/ptrace.h> + +struct stackframe { + unsigned long fp; + unsigned long ra; +}; + +extern void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, + bool (*fn)(void *, unsigned long), void *arg); + +#endif /* _ASM_RISCV_STACKTRACE_H */ diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h index 924af13f8555..5477e7ecb6e1 100644 --- a/arch/riscv/include/asm/string.h +++ b/arch/riscv/include/asm/string.h @@ -12,16 +12,16 @@ #define __HAVE_ARCH_MEMSET extern asmlinkage void *memset(void *, int, size_t); extern asmlinkage void *__memset(void *, int, size_t); - #define __HAVE_ARCH_MEMCPY extern asmlinkage void *memcpy(void *, const void *, size_t); extern asmlinkage void *__memcpy(void *, const void *, size_t); - +#define __HAVE_ARCH_MEMMOVE +extern asmlinkage void *memmove(void *, const void *, size_t); +extern asmlinkage void *__memmove(void *, const void *, size_t); /* For those files which don't want to check by kasan. */ #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) - #define memcpy(dst, src, len) __memcpy(dst, src, len) #define memset(s, c, n) __memset(s, c, n) - +#define memmove(dst, src, len) __memmove(dst, src, len) #endif #endif /* _ASM_RISCV_STRING_H */ diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h index 8454f746bbfd..1453a2f563bc 100644 --- a/arch/riscv/include/asm/vdso.h +++ b/arch/riscv/include/asm/vdso.h @@ -10,7 +10,7 @@ #include <linux/types.h> -#ifndef GENERIC_TIME_VSYSCALL +#ifndef CONFIG_GENERIC_TIME_VSYSCALL struct vdso_data { }; #endif diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index fa896c5f7ccb..f6caf4d9ca15 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -56,5 +56,3 @@ obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o obj-$(CONFIG_EFI) += efi.o - -clean: diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c index db203442c08f..b79ffa3561fd 100644 --- a/arch/riscv/kernel/asm-offsets.c +++ b/arch/riscv/kernel/asm-offsets.c @@ -11,6 +11,8 @@ #include <asm/thread_info.h> #include <asm/ptrace.h> +void asm_offsets(void); + void asm_offsets(void) { OFFSET(TASK_THREAD_RA, task_struct, thread.ra); diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c index de59dd457b41..d86781357044 100644 --- a/arch/riscv/kernel/cacheinfo.c +++ b/arch/riscv/kernel/cacheinfo.c @@ -26,7 +26,16 @@ cache_get_priv_group(struct cacheinfo *this_leaf) static struct cacheinfo *get_cacheinfo(u32 level, enum cache_type type) { - struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(smp_processor_id()); + /* + * Using raw_smp_processor_id() elides a preemptability check, but this + * is really indicative of a larger problem: the cacheinfo UABI assumes + * that cores have a homonogenous view of the cache hierarchy. That + * happens to be the case for the current set of RISC-V systems, but + * likely won't be true in general. Since there's no way to provide + * correct information for these systems via the current UABI we're + * just eliding the check for now. + */ + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(raw_smp_processor_id()); struct cacheinfo *this_leaf; int index; diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S index 524d918f3601..744f3209c48d 100644 --- a/arch/riscv/kernel/entry.S +++ b/arch/riscv/kernel/entry.S @@ -124,15 +124,15 @@ skip_context_tracking: REG_L a1, (a1) jr a1 1: -#ifdef CONFIG_TRACE_IRQFLAGS - call trace_hardirqs_on -#endif /* * Exceptions run with interrupts enabled or disabled depending on the * state of SR_PIE in m/sstatus. */ andi t0, s1, SR_PIE beqz t0, 1f +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_on +#endif csrs CSR_STATUS, SR_IE 1: @@ -155,6 +155,15 @@ skip_context_tracking: tail do_trap_unknown handle_syscall: +#ifdef CONFIG_RISCV_M_MODE + /* + * When running is M-Mode (no MMU config), MPIE does not get set. + * As a result, we need to force enable interrupts here because + * handle_exception did not do set SR_IE as it always sees SR_PIE + * being cleared. + */ + csrs CSR_STATUS, SR_IE +#endif #if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING) /* Recover a0 - a7 for system calls */ REG_L a0, PT_A0(sp) @@ -186,14 +195,7 @@ check_syscall_nr: * Syscall number held in a7. * If syscall number is above allowed value, redirect to ni_syscall. */ - bge a7, t0, 1f - /* - * Check if syscall is rejected by tracer, i.e., a7 == -1. - * If yes, we pretend it was executed. - */ - li t1, -1 - beq a7, t1, ret_from_syscall_rejected - blt a7, t1, 1f + bgeu a7, t0, 1f /* Call syscall */ la s0, sys_call_table slli t0, a7, RISCV_LGPTR diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S index 7e849797c9c3..16e9941900c4 100644 --- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S @@ -182,7 +182,6 @@ setup_trap_vector: END(_start) - __INIT ENTRY(_start_kernel) /* Mask all interrupts */ csrw CSR_IE, zero diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c index cf190197a22f..0bb1854dce83 100644 --- a/arch/riscv/kernel/perf_callchain.c +++ b/arch/riscv/kernel/perf_callchain.c @@ -4,11 +4,7 @@ #include <linux/perf_event.h> #include <linux/uaccess.h> -/* Kernel callchain */ -struct stackframe { - unsigned long fp; - unsigned long ra; -}; +#include <asm/stacktrace.h> /* * Get the return address for a single stackframe and return a pointer to the @@ -74,13 +70,11 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry, fp = user_backtrace(entry, fp, 0); } -bool fill_callchain(unsigned long pc, void *entry) +static bool fill_callchain(void *entry, unsigned long pc) { return perf_callchain_store(entry, pc); } -void notrace walk_stackframe(struct task_struct *task, - struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg); void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { diff --git a/arch/riscv/kernel/riscv_ksyms.c b/arch/riscv/kernel/riscv_ksyms.c index 450492e1cb4e..5ab1c7e1a6ed 100644 --- a/arch/riscv/kernel/riscv_ksyms.c +++ b/arch/riscv/kernel/riscv_ksyms.c @@ -11,5 +11,7 @@ */ EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memcpy); +EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(__memset); EXPORT_SYMBOL(__memcpy); +EXPORT_SYMBOL(__memmove); diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 117f3212a8e4..3fa3f26dde85 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -4,6 +4,8 @@ * Chen Liqin <liqin.chen@sunplusct.com> * Lennox Wu <lennox.wu@sunplusct.com> * Copyright (C) 2012 Regents of the University of California + * Copyright (C) 2020 FORTH-ICS/CARV + * Nick Kossifidis <mick@ics.forth.gr> */ #include <linux/init.h> @@ -22,6 +24,7 @@ #include <asm/cpu_ops.h> #include <asm/early_ioremap.h> #include <asm/setup.h> +#include <asm/set_memory.h> #include <asm/sections.h> #include <asm/sbi.h> #include <asm/tlbflush.h> @@ -51,6 +54,165 @@ atomic_t hart_lottery __section(".sdata"); unsigned long boot_cpu_hartid; static DEFINE_PER_CPU(struct cpu, cpu_devices); +/* + * Place kernel memory regions on the resource tree so that + * kexec-tools can retrieve them from /proc/iomem. While there + * also add "System RAM" regions for compatibility with other + * archs, and the rest of the known regions for completeness. + */ +static struct resource code_res = { .name = "Kernel code", }; +static struct resource data_res = { .name = "Kernel data", }; +static struct resource rodata_res = { .name = "Kernel rodata", }; +static struct resource bss_res = { .name = "Kernel bss", }; + +static int __init add_resource(struct resource *parent, + struct resource *res) +{ + int ret = 0; + + ret = insert_resource(parent, res); + if (ret < 0) { + pr_err("Failed to add a %s resource at %llx\n", + res->name, (unsigned long long) res->start); + return ret; + } + + return 1; +} + +static int __init add_kernel_resources(struct resource *res) +{ + int ret = 0; + + /* + * The memory region of the kernel image is continuous and + * was reserved on setup_bootmem, find it here and register + * it as a resource, then register the various segments of + * the image as child nodes + */ + if (!(res->start <= code_res.start && res->end >= data_res.end)) + return 0; + + res->name = "Kernel image"; + res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; + + /* + * We removed a part of this region on setup_bootmem so + * we need to expand the resource for the bss to fit in. + */ + res->end = bss_res.end; + + ret = add_resource(&iomem_resource, res); + if (ret < 0) + return ret; + + ret = add_resource(res, &code_res); + if (ret < 0) + return ret; + + ret = add_resource(res, &rodata_res); + if (ret < 0) + return ret; + + ret = add_resource(res, &data_res); + if (ret < 0) + return ret; + + ret = add_resource(res, &bss_res); + + return ret; +} + +static void __init init_resources(void) +{ + struct memblock_region *region = NULL; + struct resource *res = NULL; + struct resource *mem_res = NULL; + size_t mem_res_sz = 0; + int ret = 0, i = 0; + + code_res.start = __pa_symbol(_text); + code_res.end = __pa_symbol(_etext) - 1; + code_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; + + rodata_res.start = __pa_symbol(__start_rodata); + rodata_res.end = __pa_symbol(__end_rodata) - 1; + rodata_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; + + data_res.start = __pa_symbol(_data); + data_res.end = __pa_symbol(_edata) - 1; + data_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; + + bss_res.start = __pa_symbol(__bss_start); + bss_res.end = __pa_symbol(__bss_stop) - 1; + bss_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; + + mem_res_sz = (memblock.memory.cnt + memblock.reserved.cnt) * sizeof(*mem_res); + mem_res = memblock_alloc(mem_res_sz, SMP_CACHE_BYTES); + if (!mem_res) + panic("%s: Failed to allocate %zu bytes\n", __func__, mem_res_sz); + /* + * Start by adding the reserved regions, if they overlap + * with /memory regions, insert_resource later on will take + * care of it. + */ + for_each_reserved_mem_region(region) { + res = &mem_res[i++]; + + res->name = "Reserved"; + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res->start = __pfn_to_phys(memblock_region_reserved_base_pfn(region)); + res->end = __pfn_to_phys(memblock_region_reserved_end_pfn(region)) - 1; + + ret = add_kernel_resources(res); + if (ret < 0) + goto error; + else if (ret) + continue; + + /* + * Ignore any other reserved regions within + * system memory. + */ + if (memblock_is_memory(res->start)) { + memblock_free((phys_addr_t) res, sizeof(struct resource)); + continue; + } + + ret = add_resource(&iomem_resource, res); + if (ret < 0) + goto error; + } + + /* Add /memory regions to the resource tree */ + for_each_mem_region(region) { + res = &mem_res[i++]; + + if (unlikely(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; + + ret = add_resource(&iomem_resource, res); + if (ret < 0) + goto error; + } + + return; + + error: + /* Better an empty resource tree than an inconsistent one */ + release_child_resources(&iomem_resource); + memblock_free((phys_addr_t) mem_res, mem_res_sz); +} + + static void __init parse_dtb(void) { /* Early scan of device tree from init memory */ @@ -81,6 +243,7 @@ void __init setup_arch(char **cmdline_p) efi_init(); setup_bootmem(); paging_init(); + init_resources(); #if IS_ENABLED(CONFIG_BUILTIN_DTB) unflatten_and_copy_device_tree(); #else @@ -90,6 +253,11 @@ void __init setup_arch(char **cmdline_p) pr_err("No DTB found in kernel mappings\n"); #endif + if (IS_ENABLED(CONFIG_RISCV_SBI)) + sbi_init(); + + if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) + protect_kernel_text_data(); #ifdef CONFIG_SWIOTLB swiotlb_init(1); #endif @@ -98,10 +266,6 @@ void __init setup_arch(char **cmdline_p) kasan_init(); #endif -#if IS_ENABLED(CONFIG_RISCV_SBI) - sbi_init(); -#endif - #ifdef CONFIG_SMP setup_smp(); #endif @@ -123,3 +287,12 @@ static int __init topology_init(void) return 0; } subsys_initcall(topology_init); + +void free_initmem(void) +{ + unsigned long init_begin = (unsigned long)__init_begin; + unsigned long init_end = (unsigned long)__init_end; + + set_memory_rw_nx(init_begin, (init_end - init_begin) >> PAGE_SHIFT); + free_initmem_default(POISON_FREE_INITMEM); +} diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c index 595342910c3f..df5d2da7c40b 100644 --- a/arch/riscv/kernel/stacktrace.c +++ b/arch/riscv/kernel/stacktrace.c @@ -12,17 +12,14 @@ #include <linux/stacktrace.h> #include <linux/ftrace.h> -register unsigned long sp_in_global __asm__("sp"); +#include <asm/stacktrace.h> -#ifdef CONFIG_FRAME_POINTER +register const unsigned long sp_in_global __asm__("sp"); -struct stackframe { - unsigned long fp; - unsigned long ra; -}; +#ifdef CONFIG_FRAME_POINTER void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, - bool (*fn)(unsigned long, void *), void *arg) + bool (*fn)(void *, unsigned long), void *arg) { unsigned long fp, sp, pc; @@ -31,9 +28,8 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, sp = user_stack_pointer(regs); pc = instruction_pointer(regs); } else if (task == NULL || task == current) { - const register unsigned long current_sp = sp_in_global; fp = (unsigned long)__builtin_frame_address(0); - sp = current_sp; + sp = sp_in_global; pc = (unsigned long)walk_stackframe; } else { /* task blocked in __switch_to */ @@ -46,7 +42,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, unsigned long low, high; struct stackframe *frame; - if (unlikely(!__kernel_text_address(pc) || fn(pc, arg))) + if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc))) break; /* Validate frame pointer */ @@ -66,7 +62,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, #else /* !CONFIG_FRAME_POINTER */ void notrace walk_stackframe(struct task_struct *task, - struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg) + struct pt_regs *regs, bool (*fn)(void *, unsigned long), void *arg) { unsigned long sp, pc; unsigned long *ksp; @@ -88,7 +84,7 @@ void notrace walk_stackframe(struct task_struct *task, ksp = (unsigned long *)sp; while (!kstack_end(ksp)) { - if (__kernel_text_address(pc) && unlikely(fn(pc, arg))) + if (__kernel_text_address(pc) && unlikely(!fn(arg, pc))) break; pc = (*ksp++) - 0x4; } @@ -96,13 +92,12 @@ void notrace walk_stackframe(struct task_struct *task, #endif /* CONFIG_FRAME_POINTER */ - -static bool print_trace_address(unsigned long pc, void *arg) +static bool print_trace_address(void *arg, unsigned long pc) { const char *loglvl = arg; print_ip_sym(loglvl, pc); - return false; + return true; } void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl) @@ -111,14 +106,14 @@ void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl) walk_stackframe(task, NULL, print_trace_address, (void *)loglvl); } -static bool save_wchan(unsigned long pc, void *arg) +static bool save_wchan(void *arg, unsigned long pc) { if (!in_sched_functions(pc)) { unsigned long *p = arg; *p = pc; - return true; + return false; } - return false; + return true; } unsigned long get_wchan(struct task_struct *task) @@ -130,42 +125,12 @@ unsigned long get_wchan(struct task_struct *task) return pc; } - #ifdef CONFIG_STACKTRACE -static bool __save_trace(unsigned long pc, void *arg, bool nosched) -{ - struct stack_trace *trace = arg; - - if (unlikely(nosched && in_sched_functions(pc))) - return false; - if (unlikely(trace->skip > 0)) { - trace->skip--; - return false; - } - - trace->entries[trace->nr_entries++] = pc; - return (trace->nr_entries >= trace->max_entries); -} - -static bool save_trace(unsigned long pc, void *arg) -{ - return __save_trace(pc, arg, false); -} - -/* - * Save stack-backtrace addresses into a stack_trace buffer. - */ -void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) -{ - walk_stackframe(tsk, NULL, save_trace, trace); -} -EXPORT_SYMBOL_GPL(save_stack_trace_tsk); - -void save_stack_trace(struct stack_trace *trace) +void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, + struct task_struct *task, struct pt_regs *regs) { - save_stack_trace_tsk(NULL, trace); + walk_stackframe(task, regs, consume_entry, cookie); } -EXPORT_SYMBOL_GPL(save_stack_trace); #endif /* CONFIG_STACKTRACE */ diff --git a/arch/riscv/kernel/time.c b/arch/riscv/kernel/time.c index 4d3a1048ad8b..8a5cf99c0776 100644 --- a/arch/riscv/kernel/time.c +++ b/arch/riscv/kernel/time.c @@ -4,6 +4,7 @@ * Copyright (C) 2017 SiFive */ +#include <linux/of_clk.h> #include <linux/clocksource.h> #include <linux/delay.h> #include <asm/sbi.h> @@ -24,6 +25,8 @@ void __init time_init(void) riscv_timebase = prop; lpj_fine = riscv_timebase / HZ; + + of_clk_init(NULL); timer_probe(); } diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c index 678204231700..3f1d35e7c98a 100644 --- a/arch/riscv/kernel/vdso.c +++ b/arch/riscv/kernel/vdso.c @@ -12,7 +12,7 @@ #include <linux/binfmts.h> #include <linux/err.h> #include <asm/page.h> -#ifdef GENERIC_TIME_VSYSCALL +#ifdef CONFIG_GENERIC_TIME_VSYSCALL #include <vdso/datapage.h> #else #include <asm/vdso.h> diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S index 3ffbd6cbdb86..de03cb22d0e9 100644 --- a/arch/riscv/kernel/vmlinux.lds.S +++ b/arch/riscv/kernel/vmlinux.lds.S @@ -29,8 +29,30 @@ SECTIONS HEAD_TEXT_SECTION . = ALIGN(PAGE_SIZE); + .text : { + _text = .; + _stext = .; + TEXT_TEXT + SCHED_TEXT + CPUIDLE_TEXT + LOCK_TEXT + KPROBES_TEXT + ENTRY_TEXT + IRQENTRY_TEXT + SOFTIRQENTRY_TEXT + *(.fixup) + _etext = .; + } + + . = ALIGN(SECTION_ALIGN); __init_begin = .; - INIT_TEXT_SECTION(PAGE_SIZE) + __init_text_begin = .; + .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) ALIGN(SECTION_ALIGN) { \ + _sinittext = .; \ + INIT_TEXT \ + _einittext = .; \ + } + . = ALIGN(8); __soc_early_init_table : { __soc_early_init_table_start = .; @@ -47,35 +69,28 @@ SECTIONS { EXIT_TEXT } + + __init_text_end = .; + . = ALIGN(SECTION_ALIGN); +#ifdef CONFIG_EFI + . = ALIGN(PECOFF_SECTION_ALIGNMENT); + __pecoff_text_end = .; +#endif + /* Start of init data section */ + __init_data_begin = .; + INIT_DATA_SECTION(16) .exit.data : { EXIT_DATA } PERCPU_SECTION(L1_CACHE_BYTES) - __init_end = .; - . = ALIGN(SECTION_ALIGN); - .text : { - _text = .; - _stext = .; - TEXT_TEXT - SCHED_TEXT - CPUIDLE_TEXT - LOCK_TEXT - KPROBES_TEXT - ENTRY_TEXT - IRQENTRY_TEXT - SOFTIRQENTRY_TEXT - *(.fixup) - _etext = .; + .rel.dyn : { + *(.rel.dyn*) } -#ifdef CONFIG_EFI - . = ALIGN(PECOFF_SECTION_ALIGNMENT); - __pecoff_text_end = .; -#endif - - INIT_DATA_SECTION(16) + __init_data_end = .; + __init_end = .; /* Start of data section */ _sdata = .; @@ -105,10 +120,6 @@ SECTIONS BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 0) - .rel.dyn : { - *(.rel.dyn*) - } - #ifdef CONFIG_EFI . = ALIGN(PECOFF_SECTION_ALIGNMENT); __pecoff_data_virt_size = ABSOLUTE(. - __pecoff_text_end); diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index 47e7a8204460..ac6171e9c19e 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -2,5 +2,6 @@ lib-y += delay.o lib-y += memcpy.o lib-y += memset.o +lib-y += memmove.o lib-$(CONFIG_MMU) += uaccess.o lib-$(CONFIG_64BIT) += tishift.o diff --git a/arch/riscv/lib/memmove.S b/arch/riscv/lib/memmove.S new file mode 100644 index 000000000000..07d1d2152ba5 --- /dev/null +++ b/arch/riscv/lib/memmove.S @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include <linux/linkage.h> +#include <asm/asm.h> + +ENTRY(__memmove) +WEAK(memmove) + move t0, a0 + move t1, a1 + + beq a0, a1, exit_memcpy + beqz a2, exit_memcpy + srli t2, a2, 0x2 + + slt t3, a0, a1 + beqz t3, do_reverse + + andi a2, a2, 0x3 + li t4, 1 + beqz t2, byte_copy + +word_copy: + lw t3, 0(a1) + addi t2, t2, -1 + addi a1, a1, 4 + sw t3, 0(a0) + addi a0, a0, 4 + bnez t2, word_copy + beqz a2, exit_memcpy + j byte_copy + +do_reverse: + add a0, a0, a2 + add a1, a1, a2 + andi a2, a2, 0x3 + li t4, -1 + beqz t2, reverse_byte_copy + +reverse_word_copy: + addi a1, a1, -4 + addi t2, t2, -1 + lw t3, 0(a1) + addi a0, a0, -4 + sw t3, 0(a0) + bnez t2, reverse_word_copy + beqz a2, exit_memcpy + +reverse_byte_copy: + addi a0, a0, -1 + addi a1, a1, -1 + +byte_copy: + lb t3, 0(a1) + addi a2, a2, -1 + sb t3, 0(a0) + add a1, a1, t4 + add a0, a0, t4 + bnez a2, byte_copy + +exit_memcpy: + move a0, t0 + move a1, t1 + ret +END(__memmove) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 8e577f14f120..7cd4993f4ff2 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -13,6 +13,7 @@ #include <linux/of_fdt.h> #include <linux/libfdt.h> #include <linux/set_memory.h> +#include <linux/dma-map-ops.h> #include <asm/fixmap.h> #include <asm/tlbflush.h> @@ -41,13 +42,14 @@ struct pt_alloc_ops { #endif }; +static phys_addr_t dma32_phys_limit __ro_after_init; + static void __init zone_sizes_init(void) { unsigned long max_zone_pfns[MAX_NR_ZONES] = { 0, }; #ifdef CONFIG_ZONE_DMA32 - max_zone_pfns[ZONE_DMA32] = PFN_DOWN(min(4UL * SZ_1G, - (unsigned long) PFN_PHYS(max_low_pfn))); + max_zone_pfns[ZONE_DMA32] = PFN_DOWN(dma32_phys_limit); #endif max_zone_pfns[ZONE_NORMAL] = max_low_pfn; @@ -155,9 +157,10 @@ disable: void __init setup_bootmem(void) { phys_addr_t mem_start = 0; - phys_addr_t start, end = 0; + phys_addr_t start, dram_end, end = 0; phys_addr_t vmlinux_end = __pa_symbol(&_end); phys_addr_t vmlinux_start = __pa_symbol(&_start); + phys_addr_t max_mapped_addr = __pa(~(ulong)0); u64 i; /* Find the memory region containing the kernel */ @@ -174,13 +177,25 @@ void __init setup_bootmem(void) * Make sure that any memory beyond mem_start + (-PAGE_OFFSET) is removed * as it is unusable by kernel. */ - memblock_enforce_memory_limit(mem_start - PAGE_OFFSET); + memblock_enforce_memory_limit(-PAGE_OFFSET); /* Reserve from the start of the kernel to the end of the kernel */ memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); - max_pfn = PFN_DOWN(memblock_end_of_DRAM()); + dram_end = memblock_end_of_DRAM(); + + /* + * memblock allocator is not aware of the fact that last 4K bytes of + * the addressable memory can not be mapped because of IS_ERR_VALUE + * macro. Make sure that last 4k bytes are not usable by memblock + * if end of dram is equal to maximum addressable memory. + */ + if (max_mapped_addr == (dram_end - 1)) + memblock_set_current_limit(max_mapped_addr - 4096); + + max_pfn = PFN_DOWN(dram_end); max_low_pfn = max_pfn; + dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn)); set_max_mapnr(max_low_pfn); #ifdef CONFIG_BLK_DEV_INITRD @@ -194,6 +209,7 @@ void __init setup_bootmem(void) memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va)); early_init_fdt_scan_reserved_mem(); + dma_contiguous_reserve(dma32_phys_limit); memblock_allow_resize(); memblock_dump_all(); } @@ -618,48 +634,33 @@ static inline void setup_vm_final(void) #endif /* CONFIG_MMU */ #ifdef CONFIG_STRICT_KERNEL_RWX -void mark_rodata_ro(void) +void protect_kernel_text_data(void) { - unsigned long text_start = (unsigned long)_text; - unsigned long text_end = (unsigned long)_etext; + unsigned long text_start = (unsigned long)_start; + unsigned long init_text_start = (unsigned long)__init_text_begin; + unsigned long init_data_start = (unsigned long)__init_data_begin; unsigned long rodata_start = (unsigned long)__start_rodata; unsigned long data_start = (unsigned long)_data; unsigned long max_low = (unsigned long)(__va(PFN_PHYS(max_low_pfn))); - set_memory_ro(text_start, (text_end - text_start) >> PAGE_SHIFT); - set_memory_ro(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT); + set_memory_ro(text_start, (init_text_start - text_start) >> PAGE_SHIFT); + set_memory_ro(init_text_start, (init_data_start - init_text_start) >> PAGE_SHIFT); + set_memory_nx(init_data_start, (rodata_start - init_data_start) >> PAGE_SHIFT); + /* rodata section is marked readonly in mark_rodata_ro */ set_memory_nx(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT); set_memory_nx(data_start, (max_low - data_start) >> PAGE_SHIFT); - - debug_checkwx(); } -#endif -static void __init resource_init(void) +void mark_rodata_ro(void) { - struct memblock_region *region; - - for_each_mem_region(region) { - struct resource *res; - - res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES); - if (!res) - panic("%s: Failed to allocate %zu bytes\n", __func__, - sizeof(struct resource)); + unsigned long rodata_start = (unsigned long)__start_rodata; + unsigned long data_start = (unsigned long)_data; - if (memblock_is_nomap(region)) { - res->name = "reserved"; - res->flags = IORESOURCE_MEM; - } 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; + set_memory_ro(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT); - request_resource(&iomem_resource, res); - } + debug_checkwx(); } +#endif void __init paging_init(void) { @@ -667,7 +668,6 @@ void __init paging_init(void) sparse_init(); setup_zero_page(); zone_sizes_init(); - resource_init(); } #ifdef CONFIG_SPARSEMEM_VMEMMAP diff --git a/arch/riscv/mm/kasan_init.c b/arch/riscv/mm/kasan_init.c index 12ddd1f6bf70..a8a2ffd9114a 100644 --- a/arch/riscv/mm/kasan_init.c +++ b/arch/riscv/mm/kasan_init.c @@ -93,8 +93,8 @@ void __init kasan_init(void) VMALLOC_END)); for_each_mem_range(i, &_start, &_end) { - void *start = (void *)_start; - void *end = (void *)_end; + void *start = (void *)__va(_start); + void *end = (void *)__va(_end); if (start >= end) break; diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c index 87ba5a68bbb8..5e49e4b4a4cc 100644 --- a/arch/riscv/mm/pageattr.c +++ b/arch/riscv/mm/pageattr.c @@ -128,6 +128,12 @@ static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask, return ret; } +int set_memory_rw_nx(unsigned long addr, int numpages) +{ + return __set_memory(addr, numpages, __pgprot(_PAGE_READ | _PAGE_WRITE), + __pgprot(_PAGE_EXEC)); +} + int set_memory_ro(unsigned long addr, int numpages) { return __set_memory(addr, numpages, __pgprot(_PAGE_READ), diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index f795eebf648f..c72874f09741 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -54,17 +54,23 @@ config KASAN_SHADOW_OFFSET config S390 def_bool y + # + # Note: keep this list sorted alphabetically + # + imply IMA_SECURE_AND_OR_TRUSTED_BOOT select ARCH_BINFMT_ELF_STATE select ARCH_HAS_DEBUG_VM_PGTABLE select ARCH_HAS_DEBUG_WX select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_ELF_RANDOMIZE + select ARCH_HAS_FORCE_DMA_UNENCRYPTED select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_GIGANTIC_PAGE select ARCH_HAS_KCOV select ARCH_HAS_MEM_ENCRYPT select ARCH_HAS_PTE_SPECIAL + select ARCH_HAS_SCALED_CPUTIME select ARCH_HAS_SET_MEMORY select ARCH_HAS_STRICT_KERNEL_RWX select ARCH_HAS_STRICT_MODULE_RWX @@ -111,8 +117,10 @@ config S390 select ARCH_WANT_IPC_PARSE_VERSION select BUILDTIME_TABLE_SORT select CLONE_BACKWARDS2 + select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES select DMA_OPS if PCI select DYNAMIC_FTRACE if FUNCTION_TRACER + select GENERIC_ALLOCATOR select GENERIC_CPU_AUTOPROBE select GENERIC_CPU_VULNERABILITIES select GENERIC_FIND_FIRST_BIT @@ -126,22 +134,21 @@ config S390 select HAVE_ARCH_JUMP_LABEL_RELATIVE select HAVE_ARCH_KASAN select HAVE_ARCH_KASAN_VMALLOC - select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_SOFT_DIRTY select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_ARCH_VMAP_STACK select HAVE_ASM_MODVERSIONS - select HAVE_EBPF_JIT if PACK_STACK && HAVE_MARCH_Z196_FEATURES select HAVE_CMPXCHG_DOUBLE select HAVE_CMPXCHG_LOCAL select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_CONTIGUOUS select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS - select HAVE_FAST_GUP + select HAVE_EBPF_JIT if PACK_STACK && HAVE_MARCH_Z196_FEATURES select HAVE_EFFICIENT_UNALIGNED_ACCESS + select HAVE_FAST_GUP select HAVE_FENTRY select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_ERROR_INJECTION @@ -150,6 +157,7 @@ config S390 select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_GCC_PLUGINS select HAVE_GENERIC_VDSO + select HAVE_IRQ_EXIT_ON_IRQ_STACK select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZ4 @@ -162,16 +170,15 @@ config S390 select HAVE_KRETPROBES select HAVE_KVM select HAVE_LIVEPATCH - select HAVE_PERF_REGS - select HAVE_PERF_USER_STACK_DUMP select HAVE_MEMBLOCK_PHYS_MAP - select MMU_GATHER_NO_GATHER select HAVE_MOD_ARCH_SPECIFIC + select HAVE_NMI select HAVE_NOP_MCOUNT select HAVE_OPROFILE select HAVE_PCI select HAVE_PERF_EVENTS - select MMU_GATHER_RCU_TABLE_FREE + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_RELIABLE_STACKTRACE select HAVE_RSEQ @@ -180,6 +187,8 @@ config S390 select HAVE_VIRT_CPU_ACCOUNTING_IDLE select IOMMU_HELPER if PCI select IOMMU_SUPPORT if PCI + select MMU_GATHER_NO_GATHER + select MMU_GATHER_RCU_TABLE_FREE select MODULES_USE_ELF_RELA select NEED_DMA_MAP_STATE if PCI select NEED_SG_DMA_LENGTH if PCI @@ -189,17 +198,12 @@ config S390 select PCI_MSI if PCI select PCI_MSI_ARCH_FALLBACKS if PCI_MSI select SPARSE_IRQ + select SWIOTLB select SYSCTL_EXCEPTION_TRACE select THREAD_INFO_IN_TASK select TTY select VIRT_CPU_ACCOUNTING - select ARCH_HAS_SCALED_CPUTIME - select HAVE_NMI - select ARCH_HAS_FORCE_DMA_UNENCRYPTED - select SWIOTLB - select GENERIC_ALLOCATOR - imply IMA_SECURE_AND_OR_TRUSTED_BOOT - + # Note: keep the above list sorted alphabetically config SCHED_OMIT_FRAME_POINTER def_bool y diff --git a/arch/s390/boot/string.c b/arch/s390/boot/string.c index b11e8108773a..faccb33b462c 100644 --- a/arch/s390/boot/string.c +++ b/arch/s390/boot/string.c @@ -3,6 +3,7 @@ #include <linux/kernel.h> #include <linux/errno.h> #undef CONFIG_KASAN +#undef CONFIG_KASAN_GENERIC #include "../lib/string.c" int strncmp(const char *cs, const char *ct, size_t count) diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig index 1be32fcf6f2e..c4f6ff98a612 100644 --- a/arch/s390/configs/debug_defconfig +++ b/arch/s390/configs/debug_defconfig @@ -61,7 +61,9 @@ CONFIG_OPROFILE=m CONFIG_KPROBES=y CONFIG_JUMP_LABEL=y CONFIG_STATIC_KEYS_SELFTEST=y +CONFIG_SECCOMP_CACHE_DEBUG=y CONFIG_LOCK_EVENT_COUNTS=y +# CONFIG_GCC_PLUGINS is not set CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_UNLOAD=y @@ -410,12 +412,12 @@ CONFIG_SCSI_ENCLOSURE=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SPI_ATTRS=m -CONFIG_SCSI_FC_ATTRS=y +CONFIG_SCSI_FC_ATTRS=m CONFIG_SCSI_SAS_LIBSAS=m CONFIG_SCSI_SRP_ATTRS=m CONFIG_ISCSI_TCP=m CONFIG_SCSI_DEBUG=m -CONFIG_ZFCP=y +CONFIG_ZFCP=m CONFIG_SCSI_VIRTIO=m CONFIG_SCSI_DH=y CONFIG_SCSI_DH_RDAC=m @@ -444,6 +446,7 @@ CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH_QL=m CONFIG_DM_MULTIPATH_ST=m CONFIG_DM_MULTIPATH_HST=m +CONFIG_DM_MULTIPATH_IOA=m CONFIG_DM_DELAY=m CONFIG_DM_UEVENT=y CONFIG_DM_FLAKEY=m @@ -542,7 +545,6 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set CONFIG_LEGACY_PTY_COUNT=0 -CONFIG_NULL_TTY=m CONFIG_VIRTIO_CONSOLE=y CONFIG_HW_RANDOM_VIRTIO=m CONFIG_RAW_DRIVER=m @@ -574,6 +576,7 @@ CONFIG_VIRTIO_BALLOON=m CONFIG_VIRTIO_INPUT=y CONFIG_VHOST_NET=m CONFIG_VHOST_VSOCK=m +# CONFIG_SURFACE_PLATFORMS is not set CONFIG_S390_CCW_IOMMU=y CONFIG_S390_AP_IOMMU=y CONFIG_EXT4_FS=y @@ -655,6 +658,7 @@ CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y # CONFIG_CIFS_DEBUG is not set CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_SWN_UPCALL=y CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=m CONFIG_NLS_CODEPAGE_850=m @@ -826,6 +830,8 @@ CONFIG_FTRACE_SYSCALLS=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_BPF_KPROBE_OVERRIDE=y CONFIG_HIST_TRIGGERS=y +CONFIG_FTRACE_STARTUP_TEST=y +# CONFIG_EVENT_TRACE_STARTUP_TEST is not set CONFIG_DEBUG_USER_ASCE=y CONFIG_NOTIFIER_ERROR_INJECTION=m CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig index e2171a008809..51135893cffe 100644 --- a/arch/s390/configs/defconfig +++ b/arch/s390/configs/defconfig @@ -58,6 +58,7 @@ CONFIG_S390_UNWIND_SELFTEST=m CONFIG_OPROFILE=m CONFIG_KPROBES=y CONFIG_JUMP_LABEL=y +# CONFIG_GCC_PLUGINS is not set CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_UNLOAD=y @@ -95,7 +96,6 @@ CONFIG_ZSMALLOC_STAT=y CONFIG_DEFERRED_STRUCT_PAGE_INIT=y CONFIG_IDLE_PAGE_TRACKING=y CONFIG_PERCPU_STATS=y -CONFIG_GUP_TEST=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_PACKET_DIAG=m @@ -403,12 +403,12 @@ CONFIG_SCSI_ENCLOSURE=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SPI_ATTRS=m -CONFIG_SCSI_FC_ATTRS=y +CONFIG_SCSI_FC_ATTRS=m CONFIG_SCSI_SAS_LIBSAS=m CONFIG_SCSI_SRP_ATTRS=m CONFIG_ISCSI_TCP=m CONFIG_SCSI_DEBUG=m -CONFIG_ZFCP=y +CONFIG_ZFCP=m CONFIG_SCSI_VIRTIO=m CONFIG_SCSI_DH=y CONFIG_SCSI_DH_RDAC=m @@ -437,6 +437,7 @@ CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH_QL=m CONFIG_DM_MULTIPATH_ST=m CONFIG_DM_MULTIPATH_HST=m +CONFIG_DM_MULTIPATH_IOA=m CONFIG_DM_DELAY=m CONFIG_DM_UEVENT=y CONFIG_DM_FLAKEY=m @@ -536,7 +537,6 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set CONFIG_LEGACY_PTY_COUNT=0 -CONFIG_NULL_TTY=m CONFIG_VIRTIO_CONSOLE=y CONFIG_HW_RANDOM_VIRTIO=m CONFIG_RAW_DRIVER=m @@ -568,6 +568,7 @@ CONFIG_VIRTIO_BALLOON=m CONFIG_VIRTIO_INPUT=y CONFIG_VHOST_NET=m CONFIG_VHOST_VSOCK=m +# CONFIG_SURFACE_PLATFORMS is not set CONFIG_S390_CCW_IOMMU=y CONFIG_S390_AP_IOMMU=y CONFIG_EXT4_FS=y @@ -645,6 +646,7 @@ CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y # CONFIG_CIFS_DEBUG is not set CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_SWN_UPCALL=y CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=m CONFIG_NLS_CODEPAGE_850=m @@ -778,6 +780,7 @@ CONFIG_FTRACE_SYSCALLS=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_BPF_KPROBE_OVERRIDE=y CONFIG_HIST_TRIGGERS=y +CONFIG_DEBUG_USER_ASCE=y CONFIG_LKDTM=m CONFIG_PERCPU_TEST=m CONFIG_ATOMIC64_SELFTEST=y diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig index a302630341ef..1ef211dae77a 100644 --- a/arch/s390/configs/zfcpdump_defconfig +++ b/arch/s390/configs/zfcpdump_defconfig @@ -22,6 +22,7 @@ CONFIG_CRASH_DUMP=y # CONFIG_VIRTUALIZATION is not set # CONFIG_S390_GUEST is not set # CONFIG_SECCOMP is not set +# CONFIG_GCC_PLUGINS is not set CONFIG_PARTITION_ADVANCED=y CONFIG_IBM_PARTITION=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set @@ -58,6 +59,7 @@ CONFIG_RAW_DRIVER=y # CONFIG_HID is not set # CONFIG_VIRTIO_MENU is not set # CONFIG_VHOST_MENU is not set +# CONFIG_SURFACE_PLATFORMS is not set # CONFIG_IOMMU_SUPPORT is not set # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild index 319efa0e6d02..1a18d7b82f86 100644 --- a/arch/s390/include/asm/Kbuild +++ b/arch/s390/include/asm/Kbuild @@ -7,5 +7,4 @@ generated-y += unistd_nr.h generic-y += asm-offsets.h generic-y += export.h generic-y += kvm_types.h -generic-y += local64.h generic-y += mcs_spinlock.h diff --git a/arch/s390/include/asm/delay.h b/arch/s390/include/asm/delay.h index 4a08379cd1eb..21a8fe18fe66 100644 --- a/arch/s390/include/asm/delay.h +++ b/arch/s390/include/asm/delay.h @@ -13,14 +13,12 @@ #ifndef _S390_DELAY_H #define _S390_DELAY_H -void udelay_enable(void); -void __ndelay(unsigned long long nsecs); -void __udelay(unsigned long long usecs); -void udelay_simple(unsigned long long usecs); +void __ndelay(unsigned long nsecs); +void __udelay(unsigned long usecs); void __delay(unsigned long loops); -#define ndelay(n) __ndelay((unsigned long long) (n)) -#define udelay(n) __udelay((unsigned long long) (n)) -#define mdelay(n) __udelay((unsigned long long) (n) * 1000) +#define ndelay(n) __ndelay((unsigned long)(n)) +#define udelay(n) __udelay((unsigned long)(n)) +#define mdelay(n) __udelay((unsigned long)(n) * 1000) #endif /* defined(_S390_DELAY_H) */ diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 463c24e26000..74f9a036bab2 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -459,6 +459,7 @@ struct kvm_vcpu_stat { u64 diagnose_308; u64 diagnose_500; u64 diagnose_other; + u64 pfault_sync; }; #define PGM_OPERATION 0x01 diff --git a/arch/s390/include/asm/livepatch.h b/arch/s390/include/asm/livepatch.h index 818612b784cd..d578a8c76676 100644 --- a/arch/s390/include/asm/livepatch.h +++ b/arch/s390/include/asm/livepatch.h @@ -11,10 +11,13 @@ #ifndef ASM_LIVEPATCH_H #define ASM_LIVEPATCH_H +#include <linux/ftrace.h> #include <asm/ptrace.h> -static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip) +static inline void klp_arch_set_pc(struct ftrace_regs *fregs, unsigned long ip) { + struct pt_regs *regs = ftrace_get_regs(fregs); + regs->psw.addr = ip; } diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 6b7269f51f83..2058a435add4 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -16,14 +16,12 @@ #define CIF_NOHZ_DELAY 2 /* delay HZ disable for a tick */ #define CIF_FPU 3 /* restore FPU registers */ -#define CIF_IGNORE_IRQ 4 /* ignore interrupt (for udelay) */ #define CIF_ENABLED_WAIT 5 /* in enabled wait state */ #define CIF_MCCK_GUEST 6 /* machine check happening in guest */ #define CIF_DEDICATED_CPU 7 /* this CPU is dedicated */ #define _CIF_NOHZ_DELAY BIT(CIF_NOHZ_DELAY) #define _CIF_FPU BIT(CIF_FPU) -#define _CIF_IGNORE_IRQ BIT(CIF_IGNORE_IRQ) #define _CIF_ENABLED_WAIT BIT(CIF_ENABLED_WAIT) #define _CIF_MCCK_GUEST BIT(CIF_MCCK_GUEST) #define _CIF_DEDICATED_CPU BIT(CIF_DEDICATED_CPU) @@ -293,11 +291,6 @@ static inline unsigned long __rewind_psw(psw_t psw, unsigned long ilc) } /* - * Function to stop a processor until the next interrupt occurs - */ -void enabled_wait(void); - -/* * Function to drop a processor into disabled wait state */ static __always_inline void __noreturn disabled_wait(void) diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 1f4659203f8c..f1ba197b10c0 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -414,6 +414,7 @@ ENTRY(system_call) mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC stg %r14,__PT_FLAGS(%r11) + xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) ENABLE_INTS .Lsysc_do_svc: # clear user controlled register to prevent speculative use @@ -430,7 +431,6 @@ ENTRY(system_call) jnl .Lsysc_nr_ok slag %r8,%r1,3 .Lsysc_nr_ok: - xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) stg %r2,__PT_ORIG_GPR2(%r11) stg %r7,STACK_FRAME_OVERHEAD(%r15) lg %r9,0(%r8,%r10) # get system call add. @@ -699,8 +699,8 @@ ENTRY(pgm_check_handler) mvc __THREAD_per_address(8,%r14),__LC_PER_ADDRESS mvc __THREAD_per_cause(2,%r14),__LC_PER_CODE mvc __THREAD_per_paid(1,%r14),__LC_PER_ACCESS_ID -6: RESTORE_SM_CLEAR_PER - xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) +6: xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) + RESTORE_SM_CLEAR_PER larl %r1,pgm_check_table llgh %r10,__PT_INT_CODE+2(%r11) nill %r10,0x007f @@ -731,8 +731,8 @@ ENTRY(pgm_check_handler) # PER event in supervisor state, must be kprobes # .Lpgm_kprobe: - RESTORE_SM_CLEAR_PER xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) + RESTORE_SM_CLEAR_PER lgr %r2,%r11 # pass pointer to pt_regs brasl %r14,do_per_trap j .Lpgm_return @@ -778,10 +778,8 @@ ENTRY(io_int_handler) .Lio_skip_asce: mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) - TSTMSK __LC_CPU_FLAGS,_CIF_IGNORE_IRQ - jo .Lio_restore - TRACE_IRQS_OFF xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) + TRACE_IRQS_OFF .Lio_loop: lgr %r2,%r11 # pass pointer to pt_regs lghi %r3,IO_INTERRUPT @@ -966,10 +964,8 @@ ENTRY(ext_int_handler) mvc __PT_INT_PARM(4,%r11),__LC_EXT_PARAMS mvc __PT_INT_PARM_LONG(8,%r11),0(%r1) xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) - TSTMSK __LC_CPU_FLAGS,_CIF_IGNORE_IRQ - jo .Lio_restore - TRACE_IRQS_OFF xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) + TRACE_IRQS_OFF lgr %r2,%r11 # pass pointer to pt_regs lghi %r3,EXT_INTERRUPT brasl %r14,do_IRQ diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index ebc1284a618b..c6ddeb5029b4 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -163,17 +163,26 @@ int ftrace_disable_ftrace_graph_caller(void) #ifdef CONFIG_KPROBES_ON_FTRACE void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, - struct ftrace_ops *ops, struct pt_regs *regs) + struct ftrace_ops *ops, struct ftrace_regs *fregs) { struct kprobe_ctlblk *kcb; - struct kprobe *p = get_kprobe((kprobe_opcode_t *)ip); + struct pt_regs *regs; + struct kprobe *p; + int bit; - if (unlikely(!p) || kprobe_disabled(p)) + bit = ftrace_test_recursion_trylock(ip, parent_ip); + if (bit < 0) return; + regs = ftrace_get_regs(fregs); + preempt_disable_notrace(); + p = get_kprobe((kprobe_opcode_t *)ip); + if (unlikely(!p) || kprobe_disabled(p)) + goto out; + if (kprobe_running()) { kprobes_inc_nmissed_count(p); - return; + goto out; } __this_cpu_write(current_kprobe, p); @@ -193,6 +202,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, } } __this_cpu_write(current_kprobe, NULL); +out: + preempt_enable_notrace(); + ftrace_test_recursion_unlock(bit); } NOKPROBE_SYMBOL(kprobe_ftrace_handler); diff --git a/arch/s390/kernel/idle.c b/arch/s390/kernel/idle.c index 2b85096964f8..a5d4d80d6ede 100644 --- a/arch/s390/kernel/idle.c +++ b/arch/s390/kernel/idle.c @@ -9,7 +9,6 @@ #include <linux/kernel.h> #include <linux/kernel_stat.h> -#include <linux/kprobes.h> #include <linux/notifier.h> #include <linux/init.h> #include <linux/cpu.h> @@ -21,22 +20,19 @@ static DEFINE_PER_CPU(struct s390_idle_data, s390_idle); -void enabled_wait(void) +void arch_cpu_idle(void) { struct s390_idle_data *idle = this_cpu_ptr(&s390_idle); unsigned long long idle_time; - unsigned long psw_mask, flags; - + unsigned long psw_mask; /* Wait for external, I/O or machine check interrupt. */ psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; clear_cpu_flag(CIF_NOHZ_DELAY); - raw_local_irq_save(flags); - /* Call the assembler magic in entry.S */ + /* psw_idle() returns with interrupts disabled. */ psw_idle(idle, psw_mask); - raw_local_irq_restore(flags); /* Account time spent with enabled wait psw loaded as idle time. */ raw_write_seqcount_begin(&idle->seqcount); @@ -46,8 +42,8 @@ void enabled_wait(void) idle->idle_count++; account_idle_time(cputime_to_nsecs(idle_time)); raw_write_seqcount_end(&idle->seqcount); + raw_local_irq_enable(); } -NOKPROBE_SYMBOL(enabled_wait); static ssize_t show_idle_count(struct device *dev, struct device_attribute *attr, char *buf) @@ -120,12 +116,6 @@ void arch_cpu_idle_enter(void) { } -void arch_cpu_idle(void) -{ - enabled_wait(); - raw_local_irq_enable(); -} - void arch_cpu_idle_exit(void) { } diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 98b3aca1de8e..7a21eca498aa 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -1512,7 +1512,7 @@ static void diag308_dump(void *dump_block) while (1) { if (diag308(DIAG308_LOAD_NORMAL_DUMP, NULL) != 0x302) break; - udelay_simple(USEC_PER_SEC); + udelay(USEC_PER_SEC); } } diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 3514420f0259..f8a8b9428ae2 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -124,7 +124,7 @@ static void show_msi_interrupt(struct seq_file *p, int irq) raw_spin_lock_irqsave(&desc->lock, flags); seq_printf(p, "%3d: ", irq); for_each_online_cpu(cpu) - seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu)); + seq_printf(p, "%10u ", irq_desc_kstat_cpu(desc, cpu)); if (desc->irq_data.chip) seq_printf(p, " %8s", desc->irq_data.chip->name); diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 1f16a03be995..1fbed91c73bc 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -335,7 +335,6 @@ int __init arch_early_irq_init(void) if (!stack) panic("Couldn't allocate async stack"); S390_lowcore.async_stack = stack + STACK_INIT_OFFSET; - udelay_enable(); return 0; } diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl index 28c168000483..d443423495e5 100644 --- a/arch/s390/kernel/syscalls/syscall.tbl +++ b/arch/s390/kernel/syscalls/syscall.tbl @@ -443,3 +443,4 @@ 438 common pidfd_getfd sys_pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 sys_faccessat2 440 common process_madvise sys_process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 diff --git a/arch/s390/kvm/guestdbg.c b/arch/s390/kvm/guestdbg.c index 394a5f53805b..3765c4223bf9 100644 --- a/arch/s390/kvm/guestdbg.c +++ b/arch/s390/kvm/guestdbg.c @@ -184,7 +184,7 @@ static int __import_wp_info(struct kvm_vcpu *vcpu, if (wp_info->len < 0 || wp_info->len > MAX_WP_SIZE) return -EINVAL; - wp_info->old_data = kmalloc(bp_data->len, GFP_KERNEL); + wp_info->old_data = kmalloc(bp_data->len, GFP_KERNEL_ACCOUNT); if (!wp_info->old_data) return -ENOMEM; /* try to backup the original value */ @@ -234,7 +234,7 @@ int kvm_s390_import_bp_data(struct kvm_vcpu *vcpu, if (nr_wp > 0) { wp_info = kmalloc_array(nr_wp, sizeof(*wp_info), - GFP_KERNEL); + GFP_KERNEL_ACCOUNT); if (!wp_info) { ret = -ENOMEM; goto error; @@ -243,7 +243,7 @@ int kvm_s390_import_bp_data(struct kvm_vcpu *vcpu, if (nr_bp > 0) { bp_info = kmalloc_array(nr_bp, sizeof(*bp_info), - GFP_KERNEL); + GFP_KERNEL_ACCOUNT); if (!bp_info) { ret = -ENOMEM; goto error; @@ -349,7 +349,7 @@ static struct kvm_hw_wp_info_arch *any_wp_changed(struct kvm_vcpu *vcpu) if (!wp_info || !wp_info->old_data || wp_info->len <= 0) continue; - temp = kmalloc(wp_info->len, GFP_KERNEL); + temp = kmalloc(wp_info->len, GFP_KERNEL_ACCOUNT); if (!temp) continue; diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index e7a7c499a73f..72b25b7cc6ae 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c @@ -398,7 +398,7 @@ int handle_sthyi(struct kvm_vcpu *vcpu) if (!kvm_s390_pv_cpu_is_protected(vcpu) && (addr & ~PAGE_MASK)) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); - sctns = (void *)get_zeroed_page(GFP_KERNEL); + sctns = (void *)get_zeroed_page(GFP_KERNEL_ACCOUNT); if (!sctns) return -ENOMEM; diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 2f177298c663..e3183bd05910 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -1792,7 +1792,7 @@ struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, goto out; } gisa_out: - tmp_inti = kzalloc(sizeof(*inti), GFP_KERNEL); + tmp_inti = kzalloc(sizeof(*inti), GFP_KERNEL_ACCOUNT); if (tmp_inti) { tmp_inti->type = KVM_S390_INT_IO(1, 0, 0, 0); tmp_inti->io.io_int_word = isc_to_int_word(isc); @@ -2015,7 +2015,7 @@ int kvm_s390_inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti; int rc; - inti = kzalloc(sizeof(*inti), GFP_KERNEL); + inti = kzalloc(sizeof(*inti), GFP_KERNEL_ACCOUNT); if (!inti) return -ENOMEM; @@ -2414,7 +2414,7 @@ static int enqueue_floating_irq(struct kvm_device *dev, return -EINVAL; while (len >= sizeof(struct kvm_s390_irq)) { - inti = kzalloc(sizeof(*inti), GFP_KERNEL); + inti = kzalloc(sizeof(*inti), GFP_KERNEL_ACCOUNT); if (!inti) return -ENOMEM; @@ -2462,7 +2462,7 @@ static int register_io_adapter(struct kvm_device *dev, if (dev->kvm->arch.adapters[adapter_info.id] != NULL) return -EINVAL; - adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); + adapter = kzalloc(sizeof(*adapter), GFP_KERNEL_ACCOUNT); if (!adapter) return -ENOMEM; @@ -3290,7 +3290,7 @@ int kvm_s390_gib_init(u8 nisc) goto out; } - gib = (struct kvm_s390_gib *)get_zeroed_page(GFP_KERNEL | GFP_DMA); + gib = (struct kvm_s390_gib *)get_zeroed_page(GFP_KERNEL_ACCOUNT | GFP_DMA); if (!gib) { rc = -ENOMEM; goto out; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 425d3d75320b..dbafd057ca6a 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -60,6 +60,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { VCPU_STAT("userspace_handled", exit_userspace), VCPU_STAT("exit_null", exit_null), + VCPU_STAT("pfault_sync", pfault_sync), VCPU_STAT("exit_validity", exit_validity), VCPU_STAT("exit_stop_request", exit_stop_request), VCPU_STAT("exit_external_request", exit_external_request), @@ -1254,7 +1255,7 @@ static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr) ret = -EBUSY; goto out; } - proc = kzalloc(sizeof(*proc), GFP_KERNEL); + proc = kzalloc(sizeof(*proc), GFP_KERNEL_ACCOUNT); if (!proc) { ret = -ENOMEM; goto out; @@ -1416,7 +1417,7 @@ static int kvm_s390_get_processor(struct kvm *kvm, struct kvm_device_attr *attr) struct kvm_s390_vm_cpu_processor *proc; int ret = 0; - proc = kzalloc(sizeof(*proc), GFP_KERNEL); + proc = kzalloc(sizeof(*proc), GFP_KERNEL_ACCOUNT); if (!proc) { ret = -ENOMEM; goto out; @@ -1444,7 +1445,7 @@ static int kvm_s390_get_machine(struct kvm *kvm, struct kvm_device_attr *attr) struct kvm_s390_vm_cpu_machine *mach; int ret = 0; - mach = kzalloc(sizeof(*mach), GFP_KERNEL); + mach = kzalloc(sizeof(*mach), GFP_KERNEL_ACCOUNT); if (!mach) { ret = -ENOMEM; goto out; @@ -1812,7 +1813,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args) if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX) return -EINVAL; - keys = kvmalloc_array(args->count, sizeof(uint8_t), GFP_KERNEL); + keys = kvmalloc_array(args->count, sizeof(uint8_t), GFP_KERNEL_ACCOUNT); if (!keys) return -ENOMEM; @@ -1857,7 +1858,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args) if (args->count < 1 || args->count > KVM_S390_SKEYS_MAX) return -EINVAL; - keys = kvmalloc_array(args->count, sizeof(uint8_t), GFP_KERNEL); + keys = kvmalloc_array(args->count, sizeof(uint8_t), GFP_KERNEL_ACCOUNT); if (!keys) return -ENOMEM; @@ -2625,7 +2626,7 @@ static void sca_dispose(struct kvm *kvm) int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) { - gfp_t alloc_flags = GFP_KERNEL; + gfp_t alloc_flags = GFP_KERNEL_ACCOUNT; int i, rc; char debug_name[16]; static unsigned long sca_offset; @@ -2670,7 +2671,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) BUILD_BUG_ON(sizeof(struct sie_page2) != 4096); kvm->arch.sie_page2 = - (struct sie_page2 *) get_zeroed_page(GFP_KERNEL | GFP_DMA); + (struct sie_page2 *) get_zeroed_page(GFP_KERNEL_ACCOUNT | GFP_DMA); if (!kvm->arch.sie_page2) goto out_err; @@ -2900,7 +2901,7 @@ static int sca_switch_to_extended(struct kvm *kvm) if (kvm->arch.use_esca) return 0; - new_sca = alloc_pages_exact(sizeof(*new_sca), GFP_KERNEL|__GFP_ZERO); + new_sca = alloc_pages_exact(sizeof(*new_sca), GFP_KERNEL_ACCOUNT | __GFP_ZERO); if (!new_sca) return -ENOMEM; @@ -3133,7 +3134,7 @@ void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu) int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu) { - vcpu->arch.sie_block->cbrlo = get_zeroed_page(GFP_KERNEL); + vcpu->arch.sie_block->cbrlo = get_zeroed_page(GFP_KERNEL_ACCOUNT); if (!vcpu->arch.sie_block->cbrlo) return -ENOMEM; return 0; @@ -3243,7 +3244,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) int rc; BUILD_BUG_ON(sizeof(struct sie_page) != 4096); - sie_page = (struct sie_page *) get_zeroed_page(GFP_KERNEL); + sie_page = (struct sie_page *) get_zeroed_page(GFP_KERNEL_ACCOUNT); if (!sie_page) return -ENOMEM; @@ -4109,6 +4110,7 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) current->thread.gmap_pfault = 0; if (kvm_arch_setup_async_pf(vcpu)) return 0; + vcpu->stat.pfault_sync++; return kvm_arch_fault_in_page(vcpu, current->thread.gmap_addr, 1); } return vcpu_post_run_fault_in_sie(vcpu); diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index cd74989ce0b0..9928f785c677 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -879,7 +879,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu) switch (fc) { case 1: /* same handling for 1 and 2 */ case 2: - mem = get_zeroed_page(GFP_KERNEL); + mem = get_zeroed_page(GFP_KERNEL_ACCOUNT); if (!mem) goto out_no_data; if (stsi((void *) mem, fc, sel1, sel2)) @@ -888,7 +888,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu) case 3: if (sel1 != 2 || sel2 != 2) goto out_no_data; - mem = get_zeroed_page(GFP_KERNEL); + mem = get_zeroed_page(GFP_KERNEL_ACCOUNT); if (!mem) goto out_no_data; handle_stsi_3_2_2(vcpu, (void *) mem); diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c index f5847f9dec7c..813b6e93dc83 100644 --- a/arch/s390/kvm/pv.c +++ b/arch/s390/kvm/pv.c @@ -60,7 +60,7 @@ int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc) if (kvm_s390_pv_cpu_get_handle(vcpu)) return -EINVAL; - vcpu->arch.pv.stor_base = __get_free_pages(GFP_KERNEL, + vcpu->arch.pv.stor_base = __get_free_pages(GFP_KERNEL_ACCOUNT, get_order(uv_info.guest_cpu_stor_len)); if (!vcpu->arch.pv.stor_base) return -ENOMEM; @@ -72,7 +72,7 @@ int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc) uvcb.stor_origin = (u64)vcpu->arch.pv.stor_base; /* Alloc Secure Instruction Data Area Designation */ - vcpu->arch.sie_block->sidad = __get_free_page(GFP_KERNEL | __GFP_ZERO); + vcpu->arch.sie_block->sidad = __get_free_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); if (!vcpu->arch.sie_block->sidad) { free_pages(vcpu->arch.pv.stor_base, get_order(uv_info.guest_cpu_stor_len)); @@ -120,7 +120,7 @@ static int kvm_s390_pv_alloc_vm(struct kvm *kvm) struct kvm_memory_slot *memslot; kvm->arch.pv.stor_var = NULL; - kvm->arch.pv.stor_base = __get_free_pages(GFP_KERNEL, get_order(base)); + kvm->arch.pv.stor_base = __get_free_pages(GFP_KERNEL_ACCOUNT, get_order(base)); if (!kvm->arch.pv.stor_base) return -ENOMEM; diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index 4f3cbf6003a9..c5d0a58b2c29 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c @@ -1234,7 +1234,7 @@ static struct vsie_page *get_vsie_page(struct kvm *kvm, unsigned long addr) mutex_lock(&kvm->arch.vsie.mutex); if (kvm->arch.vsie.page_count < nr_vcpus) { - page = alloc_page(GFP_KERNEL | __GFP_ZERO | GFP_DMA); + page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO | GFP_DMA); if (!page) { mutex_unlock(&kvm->arch.vsie.mutex); return ERR_PTR(-ENOMEM); @@ -1336,7 +1336,7 @@ out_put: void kvm_s390_vsie_init(struct kvm *kvm) { mutex_init(&kvm->arch.vsie.mutex); - INIT_RADIX_TREE(&kvm->arch.vsie.addr_to_page, GFP_KERNEL); + INIT_RADIX_TREE(&kvm->arch.vsie.addr_to_page, GFP_KERNEL_ACCOUNT); } /* Destroy the vsie data structures. To be called when a vm is destroyed. */ diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 68d61f2835df..f289afeb3f31 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c @@ -19,13 +19,6 @@ #include <asm/div64.h> #include <asm/idle.h> -static DEFINE_STATIC_KEY_FALSE(udelay_ready); - -void __init udelay_enable(void) -{ - static_branch_enable(&udelay_ready); -} - void __delay(unsigned long loops) { /* @@ -39,105 +32,25 @@ void __delay(unsigned long loops) } EXPORT_SYMBOL(__delay); -static void __udelay_disabled(unsigned long long usecs) +static void delay_loop(unsigned long delta) { - unsigned long cr0, cr0_new, psw_mask; - struct s390_idle_data idle; - u64 end; + unsigned long end; - end = get_tod_clock() + (usecs << 12); - __ctl_store(cr0, 0, 0); - cr0_new = cr0 & ~CR0_IRQ_SUBCLASS_MASK; - cr0_new |= (1UL << (63 - 52)); /* enable clock comparator irq */ - __ctl_load(cr0_new, 0, 0); - psw_mask = __extract_psw() | PSW_MASK_EXT | PSW_MASK_WAIT; - set_clock_comparator(end); - set_cpu_flag(CIF_IGNORE_IRQ); - psw_idle(&idle, psw_mask); - trace_hardirqs_off(); - clear_cpu_flag(CIF_IGNORE_IRQ); - set_clock_comparator(S390_lowcore.clock_comparator); - __ctl_load(cr0, 0, 0); + end = get_tod_clock_monotonic() + delta; + while (!tod_after(get_tod_clock_monotonic(), end)) + cpu_relax(); } -static void __udelay_enabled(unsigned long long usecs) +void __udelay(unsigned long usecs) { - u64 clock_saved, end; - - end = get_tod_clock_fast() + (usecs << 12); - do { - clock_saved = 0; - if (tod_after(S390_lowcore.clock_comparator, end)) { - clock_saved = local_tick_disable(); - set_clock_comparator(end); - } - enabled_wait(); - if (clock_saved) - local_tick_enable(clock_saved); - } while (get_tod_clock_fast() < end); -} - -/* - * Waits for 'usecs' microseconds using the TOD clock comparator. - */ -void __udelay(unsigned long long usecs) -{ - unsigned long flags; - - if (!static_branch_likely(&udelay_ready)) { - udelay_simple(usecs); - return; - } - - preempt_disable(); - local_irq_save(flags); - if (in_irq()) { - __udelay_disabled(usecs); - goto out; - } - if (in_softirq()) { - if (raw_irqs_disabled_flags(flags)) - __udelay_disabled(usecs); - else - __udelay_enabled(usecs); - goto out; - } - if (raw_irqs_disabled_flags(flags)) { - local_bh_disable(); - __udelay_disabled(usecs); - _local_bh_enable(); - goto out; - } - __udelay_enabled(usecs); -out: - local_irq_restore(flags); - preempt_enable(); + delay_loop(usecs << 12); } EXPORT_SYMBOL(__udelay); -/* - * Simple udelay variant. To be used on startup and reboot - * when the interrupt handler isn't working. - */ -void udelay_simple(unsigned long long usecs) -{ - u64 end; - - end = get_tod_clock_fast() + (usecs << 12); - while (get_tod_clock_fast() < end) - cpu_relax(); -} - -void __ndelay(unsigned long long nsecs) +void __ndelay(unsigned long nsecs) { - u64 end; - nsecs <<= 9; do_div(nsecs, 125); - end = get_tod_clock_fast() + nsecs; - if (nsecs & ~0xfffUL) - __udelay(nsecs >> 12); - while (get_tod_clock_fast() < end) - barrier(); + delay_loop(nsecs); } EXPORT_SYMBOL(__ndelay); diff --git a/arch/s390/lib/test_unwind.c b/arch/s390/lib/test_unwind.c index 7c988994931f..dcd8946255be 100644 --- a/arch/s390/lib/test_unwind.c +++ b/arch/s390/lib/test_unwind.c @@ -9,12 +9,12 @@ #include <linux/kallsyms.h> #include <linux/kthread.h> #include <linux/module.h> +#include <linux/timer.h> #include <linux/slab.h> #include <linux/string.h> #include <linux/kprobes.h> #include <linux/wait.h> #include <asm/irq.h> -#include <asm/delay.h> #define BT_BUF_SIZE (PAGE_SIZE * 4) @@ -205,12 +205,15 @@ static noinline int unwindme_func3(struct unwindme *u) /* This function must appear in the backtrace. */ static noinline int unwindme_func2(struct unwindme *u) { + unsigned long flags; int rc; if (u->flags & UWM_SWITCH_STACK) { - preempt_disable(); + local_irq_save(flags); + local_mcck_disable(); rc = CALL_ON_STACK(unwindme_func3, S390_lowcore.nodat_stack, 1, u); - preempt_enable(); + local_mcck_enable(); + local_irq_restore(flags); return rc; } else { return unwindme_func3(u); @@ -223,31 +226,27 @@ static noinline int unwindme_func1(void *u) return unwindme_func2((struct unwindme *)u); } -static void unwindme_irq_handler(struct ext_code ext_code, - unsigned int param32, - unsigned long param64) +static void unwindme_timer_fn(struct timer_list *unused) { struct unwindme *u = READ_ONCE(unwindme); - if (u && u->task == current) { + if (u) { unwindme = NULL; u->task = NULL; u->ret = unwindme_func1(u); + complete(&u->task_ready); } } +static struct timer_list unwind_timer; + static int test_unwind_irq(struct unwindme *u) { - preempt_disable(); - if (register_external_irq(EXT_IRQ_CLK_COMP, unwindme_irq_handler)) { - pr_info("Couldn't register external interrupt handler"); - return -1; - } - u->task = current; unwindme = u; - udelay(1); - unregister_external_irq(EXT_IRQ_CLK_COMP, unwindme_irq_handler); - preempt_enable(); + init_completion(&u->task_ready); + timer_setup(&unwind_timer, unwindme_timer_fn, 0); + mod_timer(&unwind_timer, jiffies + 1); + wait_for_completion(&u->task_ready); return u->ret; } diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 64795d034926..9bb2c7512cd5 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -2,7 +2,7 @@ /* * KVM guest address space mapping code * - * Copyright IBM Corp. 2007, 2016, 2018 + * Copyright IBM Corp. 2007, 2020 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> * David Hildenbrand <david@redhat.com> * Janosch Frank <frankja@linux.vnet.ibm.com> @@ -56,19 +56,19 @@ static struct gmap *gmap_alloc(unsigned long limit) atype = _ASCE_TYPE_REGION1; etype = _REGION1_ENTRY_EMPTY; } - gmap = kzalloc(sizeof(struct gmap), GFP_KERNEL); + gmap = kzalloc(sizeof(struct gmap), GFP_KERNEL_ACCOUNT); if (!gmap) goto out; INIT_LIST_HEAD(&gmap->crst_list); INIT_LIST_HEAD(&gmap->children); INIT_LIST_HEAD(&gmap->pt_list); - INIT_RADIX_TREE(&gmap->guest_to_host, GFP_KERNEL); - INIT_RADIX_TREE(&gmap->host_to_guest, GFP_ATOMIC); - INIT_RADIX_TREE(&gmap->host_to_rmap, GFP_ATOMIC); + INIT_RADIX_TREE(&gmap->guest_to_host, GFP_KERNEL_ACCOUNT); + INIT_RADIX_TREE(&gmap->host_to_guest, GFP_ATOMIC | __GFP_ACCOUNT); + INIT_RADIX_TREE(&gmap->host_to_rmap, GFP_ATOMIC | __GFP_ACCOUNT); spin_lock_init(&gmap->guest_table_lock); spin_lock_init(&gmap->shadow_lock); refcount_set(&gmap->ref_count, 1); - page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); + page = alloc_pages(GFP_KERNEL_ACCOUNT, CRST_ALLOC_ORDER); if (!page) goto out_free; page->index = 0; @@ -309,7 +309,7 @@ static int gmap_alloc_table(struct gmap *gmap, unsigned long *table, unsigned long *new; /* since we dont free the gmap table until gmap_free we can unlock */ - page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); + page = alloc_pages(GFP_KERNEL_ACCOUNT, CRST_ALLOC_ORDER); if (!page) return -ENOMEM; new = (unsigned long *) page_to_phys(page); @@ -594,7 +594,7 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr) if (pmd_large(*pmd) && !gmap->mm->context.allow_gmap_hpage_1m) return -EFAULT; /* Link gmap segment table entry location to page table. */ - rc = radix_tree_preload(GFP_KERNEL); + rc = radix_tree_preload(GFP_KERNEL_ACCOUNT); if (rc) return rc; ptl = pmd_lock(mm, pmd); @@ -1218,11 +1218,11 @@ static int gmap_protect_rmap(struct gmap *sg, unsigned long raddr, vmaddr = __gmap_translate(parent, paddr); if (IS_ERR_VALUE(vmaddr)) return vmaddr; - rmap = kzalloc(sizeof(*rmap), GFP_KERNEL); + rmap = kzalloc(sizeof(*rmap), GFP_KERNEL_ACCOUNT); if (!rmap) return -ENOMEM; rmap->raddr = raddr; - rc = radix_tree_preload(GFP_KERNEL); + rc = radix_tree_preload(GFP_KERNEL_ACCOUNT); if (rc) { kfree(rmap); return rc; @@ -1741,7 +1741,7 @@ int gmap_shadow_r2t(struct gmap *sg, unsigned long saddr, unsigned long r2t, BUG_ON(!gmap_is_shadow(sg)); /* Allocate a shadow region second table */ - page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); + page = alloc_pages(GFP_KERNEL_ACCOUNT, CRST_ALLOC_ORDER); if (!page) return -ENOMEM; page->index = r2t & _REGION_ENTRY_ORIGIN; @@ -1825,7 +1825,7 @@ int gmap_shadow_r3t(struct gmap *sg, unsigned long saddr, unsigned long r3t, BUG_ON(!gmap_is_shadow(sg)); /* Allocate a shadow region second table */ - page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); + page = alloc_pages(GFP_KERNEL_ACCOUNT, CRST_ALLOC_ORDER); if (!page) return -ENOMEM; page->index = r3t & _REGION_ENTRY_ORIGIN; @@ -1909,7 +1909,7 @@ int gmap_shadow_sgt(struct gmap *sg, unsigned long saddr, unsigned long sgt, BUG_ON(!gmap_is_shadow(sg) || (sgt & _REGION3_ENTRY_LARGE)); /* Allocate a shadow segment table */ - page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); + page = alloc_pages(GFP_KERNEL_ACCOUNT, CRST_ALLOC_ORDER); if (!page) return -ENOMEM; page->index = sgt & _REGION_ENTRY_ORIGIN; @@ -2116,7 +2116,7 @@ int gmap_shadow_page(struct gmap *sg, unsigned long saddr, pte_t pte) parent = sg->parent; prot = (pte_val(pte) & _PAGE_PROTECT) ? PROT_READ : PROT_WRITE; - rmap = kzalloc(sizeof(*rmap), GFP_KERNEL); + rmap = kzalloc(sizeof(*rmap), GFP_KERNEL_ACCOUNT); if (!rmap) return -ENOMEM; rmap->raddr = (saddr & PAGE_MASK) | _SHADOW_RMAP_PGTABLE; @@ -2128,7 +2128,7 @@ int gmap_shadow_page(struct gmap *sg, unsigned long saddr, pte_t pte) rc = vmaddr; break; } - rc = radix_tree_preload(GFP_KERNEL); + rc = radix_tree_preload(GFP_KERNEL_ACCOUNT); if (rc) break; rc = -EAGAIN; diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 5fa580219a86..52646f52f130 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -29,7 +29,6 @@ config SUPERH select HAVE_ARCH_KGDB select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK - select HAVE_COPY_THREAD_TLS select HAVE_DEBUG_BUGVERBOSE select HAVE_DEBUG_KMEMLEAK select HAVE_DYNAMIC_FTRACE diff --git a/arch/sh/boards/mach-sh03/rtc.c b/arch/sh/boards/mach-sh03/rtc.c index 8b23ed7c201c..7fb474844a2d 100644 --- a/arch/sh/boards/mach-sh03/rtc.c +++ b/arch/sh/boards/mach-sh03/rtc.c @@ -11,7 +11,6 @@ #include <linux/sched.h> #include <linux/time.h> #include <linux/bcd.h> -#include <linux/rtc.h> #include <linux/spinlock.h> #include <linux/io.h> #include <linux/rtc.h> diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c index bffbe69b2236..921d76fc3358 100644 --- a/arch/sh/boards/of-generic.c +++ b/arch/sh/boards/of-generic.c @@ -6,10 +6,10 @@ */ #include <linux/of.h> +#include <linux/of_clk.h> #include <linux/of_fdt.h> #include <linux/clocksource.h> #include <linux/irqchip.h> -#include <linux/clk-provider.h> #include <asm/machvec.h> #include <asm/rtc.h> diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig index ba6ec042606f..e6c5ddf070c0 100644 --- a/arch/sh/configs/landisk_defconfig +++ b/arch/sh/configs/landisk_defconfig @@ -27,13 +27,12 @@ CONFIG_NETFILTER=y CONFIG_ATALK=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_OFFBOARD=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_AEC62XX=y +CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_ATP867X=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y CONFIG_SCSI_MULTI_LUN=y CONFIG_MD=y CONFIG_BLK_DEV_MD=m diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig index c65667d00313..e9825196dd66 100644 --- a/arch/sh/configs/microdev_defconfig +++ b/arch/sh/configs/microdev_defconfig @@ -20,8 +20,6 @@ CONFIG_IP_PNP=y # CONFIG_IPV6 is not set # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig index d10a0414123a..d00376eb044f 100644 --- a/arch/sh/configs/sdk7780_defconfig +++ b/arch/sh/configs/sdk7780_defconfig @@ -44,16 +44,14 @@ CONFIG_NET_SCHED=y CONFIG_PARPORT=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_PLATFORM=y -CONFIG_BLK_DEV_GENERIC=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_PLATFORM=y CONFIG_MD=y CONFIG_BLK_DEV_DM=y CONFIG_NETDEVICES=y diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig index 61bec46ebd66..4a44cac640bc 100644 --- a/arch/sh/configs/sdk7786_defconfig +++ b/arch/sh/configs/sdk7786_defconfig @@ -116,9 +116,6 @@ CONFIG_MTD_UBI_GLUEBI=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=y CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_PLATFORM=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y CONFIG_SCSI_MULTI_LUN=y diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig index 3f1c13799d79..4defc7628a49 100644 --- a/arch/sh/configs/se7750_defconfig +++ b/arch/sh/configs/se7750_defconfig @@ -29,7 +29,6 @@ CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_ROM=y -CONFIG_IDE=y CONFIG_SCSI=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig index f0073ed39947..48b457d59e79 100644 --- a/arch/sh/configs/sh03_defconfig +++ b/arch/sh/configs/sh03_defconfig @@ -39,9 +39,6 @@ CONFIG_IP_PNP_RARP=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=m -CONFIG_BLK_DEV_IDETAPE=m CONFIG_SCSI=m CONFIG_BLK_DEV_SD=m CONFIG_BLK_DEV_SR=m diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig index d0de378beefe..7d54f284ce10 100644 --- a/arch/sh/drivers/dma/Kconfig +++ b/arch/sh/drivers/dma/Kconfig @@ -63,8 +63,7 @@ config PVR2_DMA config G2_DMA tristate "G2 Bus DMA support" - depends on SH_DREAMCAST - select SH_DMA_API + depends on SH_DREAMCAST && SH_DMA_API help This enables support for the DMA controller for the Dreamcast's G2 bus. Drivers that want this will generally enable this on diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index 4468289ab2ca..4d499476c33a 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -12,7 +12,7 @@ #include <linux/io.h> #include <linux/async.h> #include <linux/delay.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/slab.h> #include <linux/clk.h> #include <linux/sh_clk.h> diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild index 7435182ef846..fc44d9c88b41 100644 --- a/arch/sh/include/asm/Kbuild +++ b/arch/sh/include/asm/Kbuild @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 generated-y += syscall_table.h generic-y += kvm_para.h -generic-y += local64.h generic-y += mcs_spinlock.h generic-y += parport.h diff --git a/arch/sh/include/asm/gpio.h b/arch/sh/include/asm/gpio.h index 351918894e86..d643250f0a0f 100644 --- a/arch/sh/include/asm/gpio.h +++ b/arch/sh/include/asm/gpio.h @@ -16,7 +16,6 @@ #include <cpu/gpio.h> #endif -#define ARCH_NR_GPIOS 512 #include <asm-generic/gpio.h> #ifdef CONFIG_GPIOLIB diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index 25eb80905416..e48b3dd996f5 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S @@ -14,7 +14,6 @@ #include <cpu/mmu_context.h> #include <asm/page.h> #include <asm/cache.h> -#include <asm/thread_info.h> ! NOTE: ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl index 783738448ff5..9df40ac0ebc0 100644 --- a/arch/sh/kernel/syscalls/syscall.tbl +++ b/arch/sh/kernel/syscalls/syscall.tbl @@ -443,3 +443,4 @@ 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 440 common process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 703d3069997c..77aa2f802d8d 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -105,7 +105,7 @@ config VSYSCALL (the default value) say Y. config NUMA - bool "Non Uniform Memory Access (NUMA) Support" + bool "Non-Uniform Memory Access (NUMA) Support" depends on MMU && SYS_SUPPORTS_NUMA select ARCH_WANT_NUMA_VARIABLE_LOCALITY default n diff --git a/arch/sh/mm/asids-debugfs.c b/arch/sh/mm/asids-debugfs.c index 4c1ca197e9c5..d16d6f5ec774 100644 --- a/arch/sh/mm/asids-debugfs.c +++ b/arch/sh/mm/asids-debugfs.c @@ -26,7 +26,7 @@ #include <asm/processor.h> #include <asm/mmu_context.h> -static int asids_seq_show(struct seq_file *file, void *iter) +static int asids_debugfs_show(struct seq_file *file, void *iter) { struct task_struct *p; @@ -48,18 +48,7 @@ static int asids_seq_show(struct seq_file *file, void *iter) return 0; } -static int asids_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, asids_seq_show, inode->i_private); -} - -static const struct file_operations asids_debugfs_fops = { - .owner = THIS_MODULE, - .open = asids_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(asids_debugfs); static int __init asids_debugfs_init(void) { diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c index 17d780794497..b0f185169dfa 100644 --- a/arch/sh/mm/cache-debugfs.c +++ b/arch/sh/mm/cache-debugfs.c @@ -22,7 +22,7 @@ enum cache_type { CACHE_TYPE_UNIFIED, }; -static int cache_seq_show(struct seq_file *file, void *iter) +static int cache_debugfs_show(struct seq_file *file, void *iter) { unsigned int cache_type = (unsigned int)file->private; struct cache_info *cache; @@ -94,18 +94,7 @@ static int cache_seq_show(struct seq_file *file, void *iter) return 0; } -static int cache_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, cache_seq_show, inode->i_private); -} - -static const struct file_operations cache_debugfs_fops = { - .owner = THIS_MODULE, - .open = cache_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(cache_debugfs); static int __init cache_debugfs_init(void) { diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index b20aba6e1b37..68eb7cc6e564 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -812,7 +812,7 @@ bool __in_29bit_mode(void) return (__raw_readl(PMB_PASCR) & PASCR_SE) == 0; } -static int pmb_seq_show(struct seq_file *file, void *iter) +static int pmb_debugfs_show(struct seq_file *file, void *iter) { int i; @@ -846,18 +846,7 @@ static int pmb_seq_show(struct seq_file *file, void *iter) return 0; } -static int pmb_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, pmb_seq_show, NULL); -} - -static const struct file_operations pmb_debugfs_fops = { - .owner = THIS_MODULE, - .open = pmb_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(pmb_debugfs); static int __init pmb_debugfs_init(void) { diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index 5269a704801f..3688fdae50e4 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild @@ -6,5 +6,4 @@ generated-y += syscall_table_64.h generated-y += syscall_table_c32.h generic-y += export.h generic-y += kvm_para.h -generic-y += local64.h generic-y += mcs_spinlock.h diff --git a/arch/sparc/include/asm/highmem.h b/arch/sparc/include/asm/highmem.h index 875116209ec1..c7b2e208328b 100644 --- a/arch/sparc/include/asm/highmem.h +++ b/arch/sparc/include/asm/highmem.h @@ -50,10 +50,11 @@ extern pte_t *pkmap_page_table; #define flush_cache_kmaps() flush_cache_all() -/* FIXME: Use __flush_tlb_one(vaddr) instead of flush_cache_all() -- Anton */ -#define arch_kmap_local_post_map(vaddr, pteval) flush_cache_all() -#define arch_kmap_local_post_unmap(vaddr) flush_cache_all() - +/* FIXME: Use __flush_*_one(vaddr) instead of flush_*_all() -- Anton */ +#define arch_kmap_local_pre_map(vaddr, pteval) flush_cache_all() +#define arch_kmap_local_pre_unmap(vaddr) flush_cache_all() +#define arch_kmap_local_post_map(vaddr, pteval) flush_tlb_all() +#define arch_kmap_local_post_unmap(vaddr) flush_tlb_all() #endif /* __KERNEL__ */ diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl index 78160260991b..40d8c7cd8298 100644 --- a/arch/sparc/kernel/syscalls/syscall.tbl +++ b/arch/sparc/kernel/syscalls/syscall.tbl @@ -486,3 +486,4 @@ 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 440 common process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 43333e36e0ba..34d302d1a07f 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -15,6 +15,7 @@ config UML select HAVE_DEBUG_KMEMLEAK select HAVE_DEBUG_BUGVERBOSE select NO_DMA + select ARCH_HAS_SET_MEMORY select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES select HAVE_GCC_PLUGINS @@ -191,3 +192,8 @@ config UML_TIME_TRAVEL_SUPPORT endmenu source "arch/um/drivers/Kconfig" + +config ARCH_SUSPEND_POSSIBLE + def_bool y + +source "kernel/power/Kconfig" diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 4d80526a4236..d8845d4aac6a 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -26,10 +26,10 @@ int generic_read(int fd, char *c_out, void *unused) n = read(fd, c_out, sizeof(*c_out)); if (n > 0) return n; - else if (errno == EAGAIN) - return 0; else if (n == 0) return -EIO; + else if (errno == EAGAIN) + return 0; return -errno; } diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 14ad9f495fe6..1c70a31e7c5b 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -262,19 +262,25 @@ static irqreturn_t line_write_interrupt(int irq, void *data) int line_setup_irq(int fd, int input, int output, struct line *line, void *data) { const struct line_driver *driver = line->driver; - int err = 0; + int err; - if (input) + if (input) { err = um_request_irq(driver->read_irq, fd, IRQ_READ, line_interrupt, IRQF_SHARED, driver->read_irq_name, data); - if (err) - return err; - if (output) + if (err < 0) + return err; + } + + if (output) { err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, line_write_interrupt, IRQF_SHARED, driver->write_irq_name, data); - return err; + if (err < 0) + return err; + } + + return 0; } static int line_activate(struct tty_port *port, struct tty_struct *tty) @@ -608,7 +614,6 @@ static void free_winch(struct winch *winch) winch->fd = -1; if (fd != -1) os_close_file(fd); - list_del(&winch->list); __free_winch(&winch->work); } @@ -709,6 +714,8 @@ static void unregister_winch(struct tty_struct *tty) winch = list_entry(ele, struct winch, list); wtty = tty_port_tty_get(winch->port); if (wtty == tty) { + list_del(&winch->list); + spin_unlock(&winch_handler_lock); free_winch(winch); break; } @@ -719,14 +726,17 @@ static void unregister_winch(struct tty_struct *tty) static void winch_cleanup(void) { - struct list_head *ele, *next; struct winch *winch; spin_lock(&winch_handler_lock); + while ((winch = list_first_entry_or_null(&winch_handlers, + struct winch, list))) { + list_del(&winch->list); + spin_unlock(&winch_handler_lock); - list_for_each_safe(ele, next, &winch_handlers) { - winch = list_entry(ele, struct winch, list); free_winch(winch); + + spin_lock(&winch_handler_lock); } spin_unlock(&winch_handler_lock); diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index a2e680f7d39f..6d00af25ec6b 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -738,7 +738,7 @@ static int __init mconsole_init(void) err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, IRQF_SHARED, "mconsole", (void *)sock); - if (err) { + if (err < 0) { printk(KERN_ERR "Failed to get IRQ for management console\n"); goto out; } diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 1802cf4ef5a5..2fc0b038ff8a 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -160,7 +160,7 @@ static int uml_net_open(struct net_device *dev) err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt, IRQF_SHARED, dev->name, dev); - if (err != 0) { + if (err < 0) { printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err); err = -ENETUNREACH; goto out_close; diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index a47ca5376d9d..efa8b7304090 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -100,7 +100,7 @@ static int port_accept(struct port_list *port) .port = port }); if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, - IRQF_SHARED, "telnetd", conn)) { + IRQF_SHARED, "telnetd", conn) < 0) { printk(KERN_ERR "port_accept : failed to get IRQ for " "telnetd\n"); goto out_free; @@ -182,7 +182,7 @@ void *port_data(int port_num) } if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, - IRQF_SHARED, "port", port)) { + IRQF_SHARED, "port", port) < 0) { printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); goto out_close; } diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index ce115fce52f0..433a3f8f2ef3 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c @@ -11,6 +11,7 @@ #include <linux/fs.h> #include <linux/interrupt.h> #include <linux/miscdevice.h> +#include <linux/hw_random.h> #include <linux/delay.h> #include <linux/uaccess.h> #include <init.h> @@ -18,9 +19,8 @@ #include <os.h> /* - * core module and version information + * core module information */ -#define RNG_VERSION "1.0.0" #define RNG_MODULE_NAME "hw_random" /* Changed at init time, in the non-modular case, and at module load @@ -28,88 +28,36 @@ * protects against a module being loaded twice at the same time. */ static int random_fd = -1; -static DECLARE_WAIT_QUEUE_HEAD(host_read_wait); +static struct hwrng hwrng = { 0, }; +static DECLARE_COMPLETION(have_data); -static int rng_dev_open (struct inode *inode, struct file *filp) +static int rng_dev_read(struct hwrng *rng, void *buf, size_t max, bool block) { - /* enforce read-only access to this chrdev */ - if ((filp->f_mode & FMODE_READ) == 0) - return -EINVAL; - if ((filp->f_mode & FMODE_WRITE) != 0) - return -EINVAL; + int ret; - return 0; -} - -static atomic_t host_sleep_count = ATOMIC_INIT(0); - -static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size, - loff_t *offp) -{ - u32 data; - int n, ret = 0, have_data; - - while (size) { - n = os_read_file(random_fd, &data, sizeof(data)); - if (n > 0) { - have_data = n; - while (have_data && size) { - if (put_user((u8) data, buf++)) { - ret = ret ? : -EFAULT; - break; - } - size--; - ret++; - have_data--; - data >>= 8; - } - } - else if (n == -EAGAIN) { - DECLARE_WAITQUEUE(wait, current); - - if (filp->f_flags & O_NONBLOCK) - return ret ? : -EAGAIN; - - atomic_inc(&host_sleep_count); + for (;;) { + ret = os_read_file(random_fd, buf, max); + if (block && ret == -EAGAIN) { add_sigio_fd(random_fd); - add_wait_queue(&host_read_wait, &wait); - set_current_state(TASK_INTERRUPTIBLE); + ret = wait_for_completion_killable(&have_data); - schedule(); - remove_wait_queue(&host_read_wait, &wait); + ignore_sigio_fd(random_fd); + deactivate_fd(random_fd, RANDOM_IRQ); - if (atomic_dec_and_test(&host_sleep_count)) { - ignore_sigio_fd(random_fd); - deactivate_fd(random_fd, RANDOM_IRQ); - } + if (ret < 0) + break; + } else { + break; } - else - return n; - - if (signal_pending (current)) - return ret ? : -ERESTARTSYS; } - return ret; -} - -static const struct file_operations rng_chrdev_ops = { - .owner = THIS_MODULE, - .open = rng_dev_open, - .read = rng_dev_read, - .llseek = noop_llseek, -}; -/* rng_init shouldn't be called more than once at boot time */ -static struct miscdevice rng_miscdev = { - HWRNG_MINOR, - RNG_MODULE_NAME, - &rng_chrdev_ops, -}; + return ret != -EAGAIN ? ret : 0; +} static irqreturn_t random_interrupt(int irq, void *data) { - wake_up(&host_read_wait); + complete(&have_data); return IRQ_HANDLED; } @@ -126,18 +74,19 @@ static int __init rng_init (void) goto out; random_fd = err; - err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt, 0, "random", NULL); - if (err) + if (err < 0) goto err_out_cleanup_hw; - sigio_broken(random_fd, 1); + sigio_broken(random_fd); + hwrng.name = RNG_MODULE_NAME; + hwrng.read = rng_dev_read; + hwrng.quality = 1024; - err = misc_register (&rng_miscdev); + err = hwrng_register(&hwrng); if (err) { - printk (KERN_ERR RNG_MODULE_NAME ": misc device register " - "failed\n"); + pr_err(RNG_MODULE_NAME " registering failed (%d)\n", err); goto err_out_cleanup_hw; } out: @@ -161,8 +110,8 @@ static void cleanup(void) static void __exit rng_cleanup(void) { + hwrng_unregister(&hwrng); os_close_file(random_fd); - misc_deregister (&rng_miscdev); } module_init (rng_init); diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index eae8c83364f7..13b1fe694b90 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -47,18 +47,25 @@ /* Max request size is determined by sector mask - 32K */ #define UBD_MAX_REQUEST (8 * sizeof(long)) +struct io_desc { + char *buffer; + unsigned long length; + unsigned long sector_mask; + unsigned long long cow_offset; + unsigned long bitmap_words[2]; +}; + struct io_thread_req { struct request *req; int fds[2]; unsigned long offsets[2]; unsigned long long offset; - unsigned long length; - char *buffer; int sectorsize; - unsigned long sector_mask; - unsigned long long cow_offset; - unsigned long bitmap_words[2]; int error; + + int desc_cnt; + /* io_desc has to be the last element of the struct */ + struct io_desc io_desc[]; }; @@ -148,6 +155,7 @@ struct ubd { /* name (and fd, below) of the file opened for writing, either the * backing or the cow file. */ char *file; + char *serial; int count; int fd; __u64 size; @@ -173,6 +181,7 @@ struct ubd { #define DEFAULT_UBD { \ .file = NULL, \ + .serial = NULL, \ .count = 0, \ .fd = -1, \ .size = -1, \ @@ -265,7 +274,7 @@ static int ubd_setup_common(char *str, int *index_out, char **error_out) { struct ubd *ubd_dev; struct openflags flags = global_openflags; - char *backing_file; + char *file, *backing_file, *serial; int n, err = 0, i; if(index_out) *index_out = -1; @@ -361,24 +370,27 @@ static int ubd_setup_common(char *str, int *index_out, char **error_out) goto out; break_loop: - backing_file = strchr(str, ','); + file = strsep(&str, ",:"); + if (*file == '\0') + file = NULL; - if (backing_file == NULL) - backing_file = strchr(str, ':'); + backing_file = strsep(&str, ",:"); + if (*backing_file == '\0') + backing_file = NULL; - if(backing_file != NULL){ - if(ubd_dev->no_cow){ - *error_out = "Can't specify both 'd' and a cow file"; - goto out; - } - else { - *backing_file = '\0'; - backing_file++; - } + serial = strsep(&str, ",:"); + if (*serial == '\0') + serial = NULL; + + if (backing_file && ubd_dev->no_cow) { + *error_out = "Can't specify both 'd' and a cow file"; + goto out; } + err = 0; - ubd_dev->file = str; + ubd_dev->file = file; ubd_dev->cow.file = backing_file; + ubd_dev->serial = serial; ubd_dev->boot_openflags = flags; out: mutex_unlock(&ubd_lock); @@ -399,7 +411,7 @@ static int ubd_setup(char *str) __setup("ubd", ubd_setup); __uml_help(ubd_setup, -"ubd<n><flags>=<filename>[(:|,)<filename2>]\n" +"ubd<n><flags>=<filename>[(:|,)<filename2>][(:|,)<serial>]\n" " This is used to associate a device with a file in the underlying\n" " filesystem. When specifying two filenames, the first one is the\n" " COW name and the second is the backing file name. As separator you can\n" @@ -422,6 +434,12 @@ __uml_help(ubd_setup, " UMLs and file locking will be turned off - this is appropriate for a\n" " cluster filesystem and inappropriate at almost all other times.\n\n" " 't' will disable trim/discard support on the device (enabled by default).\n\n" +" An optional device serial number can be exposed using the serial parameter\n" +" on the cmdline which is exposed as a sysfs entry. This is particularly\n" +" useful when a unique number should be given to the device. Note when\n" +" specifying a label, the filename2 must be also presented. It can be\n" +" an empty string, in which case the backing file is not used:\n" +" ubd0=File,,Serial\n" ); static int udb_setup(char *str) @@ -525,12 +543,7 @@ static void ubd_handler(void) blk_queue_max_write_zeroes_sectors(io_req->req->q, 0); blk_queue_flag_clear(QUEUE_FLAG_DISCARD, io_req->req->q); } - if ((io_req->error) || (io_req->buffer == NULL)) - blk_mq_end_request(io_req->req, io_req->error); - else { - if (!blk_update_request(io_req->req, io_req->error, io_req->length)) - __blk_mq_end_request(io_req->req, io_req->error); - } + blk_mq_end_request(io_req->req, io_req->error); kfree(io_req); } } @@ -866,6 +879,41 @@ static void ubd_device_release(struct device *dev) *ubd_dev = ((struct ubd) DEFAULT_UBD); } +static ssize_t serial_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gendisk *disk = dev_to_disk(dev); + struct ubd *ubd_dev = disk->private_data; + + if (!ubd_dev) + return 0; + + return sprintf(buf, "%s", ubd_dev->serial); +} + +static DEVICE_ATTR_RO(serial); + +static struct attribute *ubd_attrs[] = { + &dev_attr_serial.attr, + NULL, +}; + +static umode_t ubd_attrs_are_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + return a->mode; +} + +static const struct attribute_group ubd_attr_group = { + .attrs = ubd_attrs, + .is_visible = ubd_attrs_are_visible, +}; + +static const struct attribute_group *ubd_attr_groups[] = { + &ubd_attr_group, + NULL, +}; + static int ubd_disk_register(int major, u64 size, int unit, struct gendisk **disk_out) { @@ -897,7 +945,7 @@ static int ubd_disk_register(int major, u64 size, int unit, disk->private_data = &ubd_devs[unit]; disk->queue = ubd_devs[unit].queue; - device_add_disk(parent, disk, NULL); + device_add_disk(parent, disk, ubd_attr_groups); *disk_out = disk; return 0; @@ -946,6 +994,7 @@ static int ubd_add(int n, char **error_out) blk_queue_write_cache(ubd_dev->queue, true, false); blk_queue_max_segments(ubd_dev->queue, MAX_SG); + blk_queue_segment_boundary(ubd_dev->queue, PAGE_SIZE - 1); err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]); if(err){ *error_out = "Failed to register device"; @@ -1192,7 +1241,7 @@ static int __init ubd_driver_init(void){ /* Letting ubd=sync be like using ubd#s= instead of ubd#= is * enough. So use anyway the io thread. */ } - stack = alloc_stack(0, 0); + stack = alloc_stack(0); io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), &thread_fd); if(io_pid < 0){ @@ -1204,7 +1253,7 @@ static int __init ubd_driver_init(void){ } err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 0, "ubd", ubd_devs); - if(err != 0) + if(err < 0) printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); return 0; } @@ -1289,37 +1338,74 @@ static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, *cow_offset += bitmap_offset; } -static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, +static void cowify_req(struct io_thread_req *req, struct io_desc *segment, + unsigned long offset, unsigned long *bitmap, __u64 bitmap_offset, __u64 bitmap_len) { - __u64 sector = req->offset >> SECTOR_SHIFT; + __u64 sector = offset >> SECTOR_SHIFT; int i; - if (req->length > (sizeof(req->sector_mask) * 8) << SECTOR_SHIFT) + if (segment->length > (sizeof(segment->sector_mask) * 8) << SECTOR_SHIFT) panic("Operation too long"); if (req_op(req->req) == REQ_OP_READ) { - for (i = 0; i < req->length >> SECTOR_SHIFT; i++) { + for (i = 0; i < segment->length >> SECTOR_SHIFT; i++) { if(ubd_test_bit(sector + i, (unsigned char *) bitmap)) ubd_set_bit(i, (unsigned char *) - &req->sector_mask); + &segment->sector_mask); } + } else { + cowify_bitmap(offset, segment->length, &segment->sector_mask, + &segment->cow_offset, bitmap, bitmap_offset, + segment->bitmap_words, bitmap_len); } - else cowify_bitmap(req->offset, req->length, &req->sector_mask, - &req->cow_offset, bitmap, bitmap_offset, - req->bitmap_words, bitmap_len); } -static int ubd_queue_one_vec(struct blk_mq_hw_ctx *hctx, struct request *req, - u64 off, struct bio_vec *bvec) +static void ubd_map_req(struct ubd *dev, struct io_thread_req *io_req, + struct request *req) +{ + struct bio_vec bvec; + struct req_iterator iter; + int i = 0; + unsigned long byte_offset = io_req->offset; + int op = req_op(req); + + if (op == REQ_OP_WRITE_ZEROES || op == REQ_OP_DISCARD) { + io_req->io_desc[0].buffer = NULL; + io_req->io_desc[0].length = blk_rq_bytes(req); + } else { + rq_for_each_segment(bvec, req, iter) { + BUG_ON(i >= io_req->desc_cnt); + + io_req->io_desc[i].buffer = + page_address(bvec.bv_page) + bvec.bv_offset; + io_req->io_desc[i].length = bvec.bv_len; + i++; + } + } + + if (dev->cow.file) { + for (i = 0; i < io_req->desc_cnt; i++) { + cowify_req(io_req, &io_req->io_desc[i], byte_offset, + dev->cow.bitmap, dev->cow.bitmap_offset, + dev->cow.bitmap_len); + byte_offset += io_req->io_desc[i].length; + } + + } +} + +static struct io_thread_req *ubd_alloc_req(struct ubd *dev, struct request *req, + int desc_cnt) { - struct ubd *dev = hctx->queue->queuedata; struct io_thread_req *io_req; - int ret; + int i; - io_req = kmalloc(sizeof(struct io_thread_req), GFP_ATOMIC); + io_req = kmalloc(sizeof(*io_req) + + (desc_cnt * sizeof(struct io_desc)), + GFP_ATOMIC); if (!io_req) - return -ENOMEM; + return NULL; io_req->req = req; if (dev->cow.file) @@ -1327,26 +1413,41 @@ static int ubd_queue_one_vec(struct blk_mq_hw_ctx *hctx, struct request *req, else io_req->fds[0] = dev->fd; io_req->error = 0; - - if (bvec != NULL) { - io_req->buffer = page_address(bvec->bv_page) + bvec->bv_offset; - io_req->length = bvec->bv_len; - } else { - io_req->buffer = NULL; - io_req->length = blk_rq_bytes(req); - } - io_req->sectorsize = SECTOR_SIZE; io_req->fds[1] = dev->fd; - io_req->cow_offset = -1; - io_req->offset = off; - io_req->sector_mask = 0; + io_req->offset = (u64) blk_rq_pos(req) << SECTOR_SHIFT; io_req->offsets[0] = 0; io_req->offsets[1] = dev->cow.data_offset; - if (dev->cow.file) - cowify_req(io_req, dev->cow.bitmap, - dev->cow.bitmap_offset, dev->cow.bitmap_len); + for (i = 0 ; i < desc_cnt; i++) { + io_req->io_desc[i].sector_mask = 0; + io_req->io_desc[i].cow_offset = -1; + } + + return io_req; +} + +static int ubd_submit_request(struct ubd *dev, struct request *req) +{ + int segs = 0; + struct io_thread_req *io_req; + int ret; + int op = req_op(req); + + if (op == REQ_OP_FLUSH) + segs = 0; + else if (op == REQ_OP_WRITE_ZEROES || op == REQ_OP_DISCARD) + segs = 1; + else + segs = blk_rq_nr_phys_segments(req); + + io_req = ubd_alloc_req(dev, req, segs); + if (!io_req) + return -ENOMEM; + + io_req->desc_cnt = segs; + if (segs) + ubd_map_req(dev, io_req, req); ret = os_write_file(thread_fd, &io_req, sizeof(io_req)); if (ret != sizeof(io_req)) { @@ -1357,22 +1458,6 @@ static int ubd_queue_one_vec(struct blk_mq_hw_ctx *hctx, struct request *req, return ret; } -static int queue_rw_req(struct blk_mq_hw_ctx *hctx, struct request *req) -{ - struct req_iterator iter; - struct bio_vec bvec; - int ret; - u64 off = (u64)blk_rq_pos(req) << SECTOR_SHIFT; - - rq_for_each_segment(bvec, req, iter) { - ret = ubd_queue_one_vec(hctx, req, off, &bvec); - if (ret < 0) - return ret; - off += bvec.bv_len; - } - return 0; -} - static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { @@ -1385,17 +1470,12 @@ static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx, spin_lock_irq(&ubd_dev->lock); switch (req_op(req)) { - /* operations with no lentgth/offset arguments */ case REQ_OP_FLUSH: - ret = ubd_queue_one_vec(hctx, req, 0, NULL); - break; case REQ_OP_READ: case REQ_OP_WRITE: - ret = queue_rw_req(hctx, req); - break; case REQ_OP_DISCARD: case REQ_OP_WRITE_ZEROES: - ret = ubd_queue_one_vec(hctx, req, (u64)blk_rq_pos(req) << 9, NULL); + ret = ubd_submit_request(ubd_dev, req); break; default: WARN_ON_ONCE(1); @@ -1483,22 +1563,22 @@ static int map_error(int error_code) * will result in unpredictable behaviour and/or crashes. */ -static int update_bitmap(struct io_thread_req *req) +static int update_bitmap(struct io_thread_req *req, struct io_desc *segment) { int n; - if(req->cow_offset == -1) + if (segment->cow_offset == -1) return map_error(0); - n = os_pwrite_file(req->fds[1], &req->bitmap_words, - sizeof(req->bitmap_words), req->cow_offset); - if (n != sizeof(req->bitmap_words)) + n = os_pwrite_file(req->fds[1], &segment->bitmap_words, + sizeof(segment->bitmap_words), segment->cow_offset); + if (n != sizeof(segment->bitmap_words)) return map_error(-n); return map_error(0); } -static void do_io(struct io_thread_req *req) +static void do_io(struct io_thread_req *req, struct io_desc *desc) { char *buf = NULL; unsigned long len; @@ -1513,21 +1593,20 @@ static void do_io(struct io_thread_req *req) return; } - nsectors = req->length / req->sectorsize; + nsectors = desc->length / req->sectorsize; start = 0; do { - bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask); + bit = ubd_test_bit(start, (unsigned char *) &desc->sector_mask); end = start; while((end < nsectors) && - (ubd_test_bit(end, (unsigned char *) - &req->sector_mask) == bit)) + (ubd_test_bit(end, (unsigned char *) &desc->sector_mask) == bit)) end++; off = req->offset + req->offsets[bit] + start * req->sectorsize; len = (end - start) * req->sectorsize; - if (req->buffer != NULL) - buf = &req->buffer[start * req->sectorsize]; + if (desc->buffer != NULL) + buf = &desc->buffer[start * req->sectorsize]; switch (req_op(req->req)) { case REQ_OP_READ: @@ -1567,7 +1646,8 @@ static void do_io(struct io_thread_req *req) start = end; } while(start < nsectors); - req->error = update_bitmap(req); + req->offset += len; + req->error = update_bitmap(req, desc); } /* Changed in start_io_thread, which is serialized by being called only @@ -1600,8 +1680,13 @@ int io_thread(void *arg) } for (count = 0; count < n/sizeof(struct io_thread_req *); count++) { + struct io_thread_req *req = (*io_req_buffer)[count]; + int i; + io_count++; - do_io((*io_req_buffer)[count]); + for (i = 0; !req->error && i < req->desc_cnt; i++) + do_io(req, &(req->io_desc[i])); + } written = 0; diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c index 555203e3e7b4..47a02e60898d 100644 --- a/arch/um/drivers/vector_kern.c +++ b/arch/um/drivers/vector_kern.c @@ -1196,9 +1196,9 @@ static int vector_net_close(struct net_device *dev) /* TX tasklet */ -static void vector_tx_poll(unsigned long data) +static void vector_tx_poll(struct tasklet_struct *t) { - struct vector_private *vp = (struct vector_private *)data; + struct vector_private *vp = from_tasklet(vp, t, tx_poll); vp->estats.tx_kicks++; vector_send(vp->tx_queue); @@ -1271,7 +1271,7 @@ static int vector_net_open(struct net_device *dev) irq_rr + VECTOR_BASE_IRQ, vp->fds->rx_fd, IRQ_READ, vector_rx_interrupt, IRQF_SHARED, dev->name, dev); - if (err != 0) { + if (err < 0) { netdev_err(dev, "vector_open: failed to get rx irq(%d)\n", err); err = -ENETUNREACH; goto out_close; @@ -1286,7 +1286,7 @@ static int vector_net_open(struct net_device *dev) irq_rr + VECTOR_BASE_IRQ, vp->fds->tx_fd, IRQ_WRITE, vector_tx_interrupt, IRQF_SHARED, dev->name, dev); - if (err != 0) { + if (err < 0) { netdev_err(dev, "vector_open: failed to get tx irq(%d)\n", err); err = -ENETUNREACH; @@ -1629,7 +1629,7 @@ static void vector_eth_configure( }); dev->features = dev->hw_features = (NETIF_F_SG | NETIF_F_FRAGLIST); - tasklet_init(&vp->tx_poll, vector_tx_poll, (unsigned long)vp); + tasklet_setup(&vp->tx_poll, vector_tx_poll); INIT_WORK(&vp->reset_tx, vector_reset_tx); timer_setup(&vp->tl, vector_timer_expire, 0); diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index a6c4bb6c2c01..27e92d3881ff 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -33,11 +33,6 @@ #include <os.h> #include "vhost_user.h" -/* Workaround due to a conflict between irq_user.h and irqreturn.h */ -#ifdef IRQ_NONE -#undef IRQ_NONE -#endif - #define MAX_SUPPORTED_QUEUE_SIZE 256 #define to_virtio_uml_device(_vdev) \ @@ -55,7 +50,7 @@ struct virtio_uml_device { struct platform_device *pdev; spinlock_t sock_lock; - int sock, req_fd; + int sock, req_fd, irq; u64 features; u64 protocol_features; u8 status; @@ -409,12 +404,14 @@ static int vhost_user_init_slave_req(struct virtio_uml_device *vu_dev) return rc; vu_dev->req_fd = req_fds[0]; - rc = um_request_irq(VIRTIO_IRQ, vu_dev->req_fd, IRQ_READ, + rc = um_request_irq(UM_IRQ_ALLOC, vu_dev->req_fd, IRQ_READ, vu_req_interrupt, IRQF_SHARED, vu_dev->pdev->name, vu_dev); - if (rc) + if (rc < 0) goto err_close; + vu_dev->irq = rc; + rc = vhost_user_send_no_payload_fd(vu_dev, VHOST_USER_SET_SLAVE_REQ_FD, req_fds[1]); if (rc) @@ -423,7 +420,7 @@ static int vhost_user_init_slave_req(struct virtio_uml_device *vu_dev) goto out; err_free_irq: - um_free_irq(VIRTIO_IRQ, vu_dev); + um_free_irq(vu_dev->irq, vu_dev); err_close: os_close_file(req_fds[0]); out: @@ -802,7 +799,11 @@ static void vu_del_vq(struct virtqueue *vq) struct virtio_uml_vq_info *info = vq->priv; if (info->call_fd >= 0) { - um_free_irq(VIRTIO_IRQ, vq); + struct virtio_uml_device *vu_dev; + + vu_dev = to_virtio_uml_device(vq->vdev); + + um_free_irq(vu_dev->irq, vq); os_close_file(info->call_fd); } @@ -852,9 +853,9 @@ static int vu_setup_vq_call_fd(struct virtio_uml_device *vu_dev, return rc; info->call_fd = call_fds[0]; - rc = um_request_irq(VIRTIO_IRQ, info->call_fd, IRQ_READ, + rc = um_request_irq(vu_dev->irq, info->call_fd, IRQ_READ, vu_interrupt, IRQF_SHARED, info->name, vq); - if (rc) + if (rc < 0) goto close_both; rc = vhost_user_set_vring_call(vu_dev, vq->index, call_fds[1]); @@ -864,7 +865,7 @@ static int vu_setup_vq_call_fd(struct virtio_uml_device *vu_dev, goto out; release_irq: - um_free_irq(VIRTIO_IRQ, vq); + um_free_irq(vu_dev->irq, vq); close_both: os_close_file(call_fds[0]); out: @@ -969,7 +970,7 @@ static struct virtqueue *vu_setup_vq(struct virtio_device *vdev, error_setup: if (info->call_fd >= 0) { - um_free_irq(VIRTIO_IRQ, vq); + um_free_irq(vu_dev->irq, vq); os_close_file(info->call_fd); } error_call: @@ -1078,7 +1079,7 @@ static void virtio_uml_release_dev(struct device *d) /* might not have been opened due to not negotiating the feature */ if (vu_dev->req_fd >= 0) { - um_free_irq(VIRTIO_IRQ, vu_dev); + um_free_irq(vu_dev->irq, vu_dev); os_close_file(vu_dev->req_fd); } diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index fc7f1e746703..87ca4a47cd66 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -18,6 +18,7 @@ struct xterm_chan { int pid; int helper_pid; + int chan_fd; char *title; int device; int raw; @@ -33,6 +34,7 @@ static void *xterm_init(char *str, int device, const struct chan_opts *opts) return NULL; *data = ((struct xterm_chan) { .pid = -1, .helper_pid = -1, + .chan_fd = -1, .device = device, .title = opts->xterm_title, .raw = opts->raw } ); @@ -149,6 +151,7 @@ static int xterm_open(int input, int output, int primary, void *d, goto out_kill; } + data->chan_fd = fd; new = xterm_fd(fd, &data->helper_pid); if (new < 0) { err = new; @@ -206,6 +209,8 @@ static void xterm_close(int fd, void *d) os_kill_process(data->helper_pid, 0); data->helper_pid = -1; + if (data->chan_fd != -1) + os_close_file(data->chan_fd); os_close_file(fd); } diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c index d64ef6d0d463..50f11b7b4774 100644 --- a/arch/um/drivers/xterm_kern.c +++ b/arch/um/drivers/xterm_kern.c @@ -51,7 +51,7 @@ int xterm_fd(int socket, int *pid_out) err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, IRQF_SHARED, "xterm", data); - if (err) { + if (err < 0) { printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " "err = %d\n", err); ret = err; diff --git a/arch/um/include/asm/irq.h b/arch/um/include/asm/irq.h index 42c6205e2dc4..547bff7b3a89 100644 --- a/arch/um/include/asm/irq.h +++ b/arch/um/include/asm/irq.h @@ -17,21 +17,20 @@ #define TELNETD_IRQ 12 #define XTERM_IRQ 13 #define RANDOM_IRQ 14 -#define VIRTIO_IRQ 15 #ifdef CONFIG_UML_NET_VECTOR -#define VECTOR_BASE_IRQ (VIRTIO_IRQ + 1) +#define VECTOR_BASE_IRQ (RANDOM_IRQ + 1) #define VECTOR_IRQ_SPACE 8 -#define LAST_IRQ (VECTOR_IRQ_SPACE + VECTOR_BASE_IRQ - 1) +#define UM_FIRST_DYN_IRQ (VECTOR_IRQ_SPACE + VECTOR_BASE_IRQ) #else -#define LAST_IRQ VIRTIO_IRQ +#define UM_FIRST_DYN_IRQ (RANDOM_IRQ + 1) #endif -#define NR_IRQS (LAST_IRQ + 1) +#define NR_IRQS 64 #endif diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h index def376194dce..39376bb63abf 100644 --- a/arch/um/include/asm/pgtable.h +++ b/arch/um/include/asm/pgtable.h @@ -55,12 +55,15 @@ extern unsigned long end_iomem; #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) #define __PAGE_KERNEL_EXEC \ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) +#define __PAGE_KERNEL_RO \ + (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED) #define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) #define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) +#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) /* * The i386 can't do page protection for execute, and considers that the same diff --git a/arch/um/include/asm/set_memory.h b/arch/um/include/asm/set_memory.h new file mode 100644 index 000000000000..24266c63720d --- /dev/null +++ b/arch/um/include/asm/set_memory.h @@ -0,0 +1 @@ +#include <asm-generic/set_memory.h> diff --git a/arch/um/include/linux/time-internal.h b/arch/um/include/linux/time-internal.h index f3b03d39a854..68e45e950137 100644 --- a/arch/um/include/linux/time-internal.h +++ b/arch/um/include/linux/time-internal.h @@ -28,7 +28,7 @@ struct time_travel_event { extern enum time_travel_mode time_travel_mode; -void time_travel_sleep(unsigned long long duration); +void time_travel_sleep(void); static inline void time_travel_set_event_fn(struct time_travel_event *e, @@ -60,7 +60,7 @@ struct time_travel_event { #define time_travel_mode TT_MODE_OFF -static inline void time_travel_sleep(unsigned long long duration) +static inline void time_travel_sleep(void) { } diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h index 4e99fe05576a..16a51a8c800f 100644 --- a/arch/um/include/shared/common-offsets.h +++ b/arch/um/include/shared/common-offsets.h @@ -40,3 +40,6 @@ DEFINE(UML_CONFIG_UML_X86, CONFIG_UML_X86); #ifdef CONFIG_64BIT DEFINE(UML_CONFIG_64BIT, CONFIG_64BIT); #endif +#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT +DEFINE(UML_CONFIG_UML_TIME_TRAVEL_SUPPORT, CONFIG_UML_TIME_TRAVEL_SUPPORT); +#endif diff --git a/arch/um/include/shared/irq_kern.h b/arch/um/include/shared/irq_kern.h index 7cd1a10c6244..7807de593bda 100644 --- a/arch/um/include/shared/irq_kern.h +++ b/arch/um/include/shared/irq_kern.h @@ -8,11 +8,12 @@ #include <linux/interrupt.h> #include <asm/ptrace.h> +#include "irq_user.h" -extern int um_request_irq(unsigned int irq, int fd, int type, - irq_handler_t handler, - unsigned long irqflags, const char * devname, - void *dev_id); -void um_free_irq(unsigned int irq, void *dev); -#endif +#define UM_IRQ_ALLOC -1 +int um_request_irq(int irq, int fd, enum um_irq_type type, + irq_handler_t handler, unsigned long irqflags, + const char *devname, void *dev_id); +void um_free_irq(int irq, void *dev_id); +#endif diff --git a/arch/um/include/shared/irq_user.h b/arch/um/include/shared/irq_user.h index 107751dce153..07239e801a5b 100644 --- a/arch/um/include/shared/irq_user.h +++ b/arch/um/include/shared/irq_user.h @@ -9,25 +9,12 @@ #include <sysdep/ptrace.h> #include <stdbool.h> -struct irq_fd { - struct irq_fd *next; - void *id; - int fd; - int type; - int irq; - int events; - bool active; - bool pending; - bool purge; +enum um_irq_type { + IRQ_READ, + IRQ_WRITE, + NUM_IRQ_TYPES, }; -#define IRQ_READ 0 -#define IRQ_WRITE 1 -#define IRQ_NONE 2 -#define MAX_IRQ_TYPE (IRQ_NONE + 1) - - - struct siginfo; extern void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); extern void free_irq_by_fd(int fd); diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index ccafb62e8cce..d8c279e3312f 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h @@ -19,7 +19,7 @@ extern int kmalloc_ok; #define UML_ROUND_UP(addr) \ ((((unsigned long) addr) + PAGE_SIZE - 1) & PAGE_MASK) -extern unsigned long alloc_stack(int order, int atomic); +extern unsigned long alloc_stack(int atomic); extern void free_stack(unsigned long stack, int order); struct pt_regs; @@ -39,6 +39,8 @@ extern int is_syscall(unsigned long addr); extern void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); +extern void uml_pm_wake(void); + extern int start_uml(void); extern void paging_init(void); @@ -66,5 +68,6 @@ extern void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs); extern void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); extern void fatal_sigsegv(void) __attribute__ ((noreturn)); +void um_idle_sleep(void); #endif diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index f467d28fc0b4..13d86f94cf0f 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -233,6 +233,7 @@ extern void timer_set_signal_handler(void); extern void set_sigstack(void *sig_stack, int size); extern void remove_sigstack(void); extern void set_handler(int sig); +extern void send_sigio_to_self(void); extern int change_sig(int signal, int on); extern void block_signals(void); extern void unblock_signals(void); @@ -241,6 +242,7 @@ extern int set_signals(int enable); extern int set_signals_trace(int enable); extern int os_is_signal_stack(void); extern void deliver_alarm(void); +extern void register_pm_wake_signal(void); /* util.c */ extern void stack_protections(unsigned long address); @@ -256,7 +258,7 @@ extern void os_warn(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); /* time.c */ -extern void os_idle_sleep(unsigned long long nsecs); +extern void os_idle_sleep(void); extern int os_timer_create(void); extern int os_timer_set_interval(unsigned long long nsecs); extern int os_timer_one_shot(unsigned long long nsecs); @@ -299,19 +301,29 @@ extern void reboot_skas(void); extern int os_waiting_for_events_epoll(void); extern void *os_epoll_get_data_pointer(int index); extern int os_epoll_triggered(int index, int events); -extern int os_event_mask(int irq_type); +extern int os_event_mask(enum um_irq_type irq_type); extern int os_setup_epoll(void); extern int os_add_epoll_fd(int events, int fd, void *data); extern int os_mod_epoll_fd(int events, int fd, void *data); extern int os_del_epoll_fd(int fd); extern void os_set_ioignore(void); extern void os_close_epoll_fd(void); +extern void um_irqs_suspend(void); +extern void um_irqs_resume(void); /* sigio.c */ extern int add_sigio_fd(int fd); extern int ignore_sigio_fd(int fd); -extern void maybe_sigio_broken(int fd, int read); -extern void sigio_broken(int fd, int read); +extern void maybe_sigio_broken(int fd); +extern void sigio_broken(int fd); +/* + * unlocked versions for IRQ controller code. + * + * This is safe because it's used at suspend/resume and nothing + * else is running. + */ +extern int __add_sigio_fd(int fd); +extern int __ignore_sigio_fd(int fd); /* prctl.c */ extern int os_arch_prctl(int pid, int option, unsigned long *arg2); @@ -330,4 +342,7 @@ extern void unblock_signals_trace(void); extern void um_trace_signals_on(void); extern void um_trace_signals_off(void); +/* time-travel */ +extern void deliver_time_travel_irqs(void); + #endif diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 3577118bb4a5..3741d2380060 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -19,27 +19,40 @@ #include <kern_util.h> #include <os.h> #include <irq_user.h> +#include <irq_kern.h> +#include <as-layout.h> extern void free_irqs(void); /* When epoll triggers we do not know why it did so * we can also have different IRQs for read and write. - * This is why we keep a small irq_fd array for each fd - + * This is why we keep a small irq_reg array for each fd - * one entry per IRQ type */ +struct irq_reg { + void *id; + int irq; + /* it's cheaper to store this than to query it */ + int events; + bool active; + bool pending; + bool wakeup; +}; struct irq_entry { - struct irq_entry *next; + struct list_head list; int fd; - struct irq_fd *irq_array[MAX_IRQ_TYPE + 1]; + struct irq_reg reg[NUM_IRQ_TYPES]; + bool suspended; + bool sigio_workaround; }; -static struct irq_entry *active_fds; - static DEFINE_SPINLOCK(irq_lock); +static LIST_HEAD(active_fds); +static DECLARE_BITMAP(irqs_allocated, NR_IRQS); -static void irq_io_loop(struct irq_fd *irq, struct uml_pt_regs *regs) +static void irq_io_loop(struct irq_reg *irq, struct uml_pt_regs *regs) { /* * irq->active guards against reentry @@ -49,23 +62,27 @@ static void irq_io_loop(struct irq_fd *irq, struct uml_pt_regs *regs) */ if (irq->active) { irq->active = false; + do { irq->pending = false; do_IRQ(irq->irq, regs); - } while (irq->pending && (!irq->purge)); - if (!irq->purge) - irq->active = true; + } while (irq->pending); + + irq->active = true; } else { irq->pending = true; } } +void sigio_handler_suspend(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) +{ + /* nothing */ +} + void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) { struct irq_entry *irq_entry; - struct irq_fd *irq; - - int n, i, j; + int n, i; while (1) { /* This is now lockless - epoll keeps back-referencesto the irqs @@ -84,21 +101,18 @@ void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) } for (i = 0; i < n ; i++) { - /* Epoll back reference is the entry with 3 irq_fd - * leaves - one for each irq type. - */ - irq_entry = (struct irq_entry *) - os_epoll_get_data_pointer(i); - for (j = 0; j < MAX_IRQ_TYPE ; j++) { - irq = irq_entry->irq_array[j]; - if (irq == NULL) + enum um_irq_type t; + + irq_entry = os_epoll_get_data_pointer(i); + + for (t = 0; t < NUM_IRQ_TYPES; t++) { + int events = irq_entry->reg[t].events; + + if (!events) continue; - if (os_epoll_triggered(i, irq->events) > 0) - irq_io_loop(irq, regs); - if (irq->purge) { - irq_entry->irq_array[j] = NULL; - kfree(irq); - } + + if (os_epoll_triggered(i, events) > 0) + irq_io_loop(&irq_entry->reg[t], regs); } } } @@ -106,32 +120,59 @@ void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) free_irqs(); } -static int assign_epoll_events_to_irq(struct irq_entry *irq_entry) +static struct irq_entry *get_irq_entry_by_fd(int fd) { - int i; - int events = 0; - struct irq_fd *irq; + struct irq_entry *walk; - for (i = 0; i < MAX_IRQ_TYPE ; i++) { - irq = irq_entry->irq_array[i]; - if (irq != NULL) - events = irq->events | events; - } - if (events > 0) { - /* os_add_epoll will call os_mod_epoll if this already exists */ - return os_add_epoll_fd(events, irq_entry->fd, irq_entry); + lockdep_assert_held(&irq_lock); + + list_for_each_entry(walk, &active_fds, list) { + if (walk->fd == fd) + return walk; } - /* No events - delete */ - return os_del_epoll_fd(irq_entry->fd); + + return NULL; } +static void free_irq_entry(struct irq_entry *to_free, bool remove) +{ + if (!to_free) + return; + + if (remove) + os_del_epoll_fd(to_free->fd); + list_del(&to_free->list); + kfree(to_free); +} + +static bool update_irq_entry(struct irq_entry *entry) +{ + enum um_irq_type i; + int events = 0; + + for (i = 0; i < NUM_IRQ_TYPES; i++) + events |= entry->reg[i].events; + + if (events) { + /* will modify (instead of add) if needed */ + os_add_epoll_fd(events, entry->fd, entry); + return true; + } + + os_del_epoll_fd(entry->fd); + return false; +} +static void update_or_free_irq_entry(struct irq_entry *entry) +{ + if (!update_irq_entry(entry)) + free_irq_entry(entry, false); +} -static int activate_fd(int irq, int fd, int type, void *dev_id) +static int activate_fd(int irq, int fd, enum um_irq_type type, void *dev_id) { - struct irq_fd *new_fd; struct irq_entry *irq_entry; - int i, err, events; + int err, events = os_event_mask(type); unsigned long flags; err = os_set_fd_async(fd); @@ -139,73 +180,34 @@ static int activate_fd(int irq, int fd, int type, void *dev_id) goto out; spin_lock_irqsave(&irq_lock, flags); - - /* Check if we have an entry for this fd */ - - err = -EBUSY; - for (irq_entry = active_fds; - irq_entry != NULL; irq_entry = irq_entry->next) { - if (irq_entry->fd == fd) - break; - } - - if (irq_entry == NULL) { - /* This needs to be atomic as it may be called from an - * IRQ context. - */ - irq_entry = kmalloc(sizeof(struct irq_entry), GFP_ATOMIC); - if (irq_entry == NULL) { - printk(KERN_ERR - "Failed to allocate new IRQ entry\n"); + irq_entry = get_irq_entry_by_fd(fd); + if (irq_entry) { + /* cannot register the same FD twice with the same type */ + if (WARN_ON(irq_entry->reg[type].events)) { + err = -EALREADY; goto out_unlock; } - irq_entry->fd = fd; - for (i = 0; i < MAX_IRQ_TYPE; i++) - irq_entry->irq_array[i] = NULL; - irq_entry->next = active_fds; - active_fds = irq_entry; - } - - /* Check if we are trying to re-register an interrupt for a - * particular fd - */ - if (irq_entry->irq_array[type] != NULL) { - printk(KERN_ERR - "Trying to reregister IRQ %d FD %d TYPE %d ID %p\n", - irq, fd, type, dev_id - ); - goto out_unlock; + /* temporarily disable to avoid IRQ-side locking */ + os_del_epoll_fd(fd); } else { - /* New entry for this fd */ - - err = -ENOMEM; - new_fd = kmalloc(sizeof(struct irq_fd), GFP_ATOMIC); - if (new_fd == NULL) + irq_entry = kzalloc(sizeof(*irq_entry), GFP_ATOMIC); + if (!irq_entry) { + err = -ENOMEM; goto out_unlock; - - events = os_event_mask(type); - - *new_fd = ((struct irq_fd) { - .id = dev_id, - .irq = irq, - .type = type, - .events = events, - .active = true, - .pending = false, - .purge = false - }); - /* Turn off any IO on this fd - allows us to - * avoid locking the IRQ loop - */ - os_del_epoll_fd(irq_entry->fd); - irq_entry->irq_array[type] = new_fd; + } + irq_entry->fd = fd; + list_add_tail(&irq_entry->list, &active_fds); + maybe_sigio_broken(fd); } - /* Turn back IO on with the correct (new) IO event mask */ - assign_epoll_events_to_irq(irq_entry); + irq_entry->reg[type].id = dev_id; + irq_entry->reg[type].irq = irq; + irq_entry->reg[type].active = true; + irq_entry->reg[type].events = events; + + WARN_ON(!update_irq_entry(irq_entry)); spin_unlock_irqrestore(&irq_lock, flags); - maybe_sigio_broken(fd, (type != IRQ_NONE)); return 0; out_unlock: @@ -215,104 +217,10 @@ out: } /* - * Walk the IRQ list and dispose of any unused entries. - * Should be done under irq_lock. + * Remove the entry or entries for a specific FD, if you + * don't want to remove all the possible entries then use + * um_free_irq() or deactivate_fd() instead. */ - -static void garbage_collect_irq_entries(void) -{ - int i; - bool reap; - struct irq_entry *walk; - struct irq_entry *previous = NULL; - struct irq_entry *to_free; - - if (active_fds == NULL) - return; - walk = active_fds; - while (walk != NULL) { - reap = true; - for (i = 0; i < MAX_IRQ_TYPE ; i++) { - if (walk->irq_array[i] != NULL) { - reap = false; - break; - } - } - if (reap) { - if (previous == NULL) - active_fds = walk->next; - else - previous->next = walk->next; - to_free = walk; - } else { - to_free = NULL; - } - walk = walk->next; - kfree(to_free); - } -} - -/* - * Walk the IRQ list and get the descriptor for our FD - */ - -static struct irq_entry *get_irq_entry_by_fd(int fd) -{ - struct irq_entry *walk = active_fds; - - while (walk != NULL) { - if (walk->fd == fd) - return walk; - walk = walk->next; - } - return NULL; -} - - -/* - * Walk the IRQ list and dispose of an entry for a specific - * device, fd and number. Note - if sharing an IRQ for read - * and writefor the same FD it will be disposed in either case. - * If this behaviour is undesirable use different IRQ ids. - */ - -#define IGNORE_IRQ 1 -#define IGNORE_DEV (1<<1) - -static void do_free_by_irq_and_dev( - struct irq_entry *irq_entry, - unsigned int irq, - void *dev, - int flags -) -{ - int i; - struct irq_fd *to_free; - - for (i = 0; i < MAX_IRQ_TYPE ; i++) { - if (irq_entry->irq_array[i] != NULL) { - if ( - ((flags & IGNORE_IRQ) || - (irq_entry->irq_array[i]->irq == irq)) && - ((flags & IGNORE_DEV) || - (irq_entry->irq_array[i]->id == dev)) - ) { - /* Turn off any IO on this fd - allows us to - * avoid locking the IRQ loop - */ - os_del_epoll_fd(irq_entry->fd); - to_free = irq_entry->irq_array[i]; - irq_entry->irq_array[i] = NULL; - assign_epoll_events_to_irq(irq_entry); - if (to_free->active) - to_free->purge = true; - else - kfree(to_free); - } - } - } -} - void free_irq_by_fd(int fd) { struct irq_entry *to_free; @@ -320,58 +228,64 @@ void free_irq_by_fd(int fd) spin_lock_irqsave(&irq_lock, flags); to_free = get_irq_entry_by_fd(fd); - if (to_free != NULL) { - do_free_by_irq_and_dev( - to_free, - -1, - NULL, - IGNORE_IRQ | IGNORE_DEV - ); - } - garbage_collect_irq_entries(); + free_irq_entry(to_free, true); spin_unlock_irqrestore(&irq_lock, flags); } EXPORT_SYMBOL(free_irq_by_fd); static void free_irq_by_irq_and_dev(unsigned int irq, void *dev) { - struct irq_entry *to_free; + struct irq_entry *entry; unsigned long flags; spin_lock_irqsave(&irq_lock, flags); - to_free = active_fds; - while (to_free != NULL) { - do_free_by_irq_and_dev( - to_free, - irq, - dev, - 0 - ); - to_free = to_free->next; + list_for_each_entry(entry, &active_fds, list) { + enum um_irq_type i; + + for (i = 0; i < NUM_IRQ_TYPES; i++) { + struct irq_reg *reg = &entry->reg[i]; + + if (!reg->events) + continue; + if (reg->irq != irq) + continue; + if (reg->id != dev) + continue; + + os_del_epoll_fd(entry->fd); + reg->events = 0; + update_or_free_irq_entry(entry); + goto out; + } } - garbage_collect_irq_entries(); +out: spin_unlock_irqrestore(&irq_lock, flags); } - void deactivate_fd(int fd, int irqnum) { - struct irq_entry *to_free; + struct irq_entry *entry; unsigned long flags; + enum um_irq_type i; os_del_epoll_fd(fd); + spin_lock_irqsave(&irq_lock, flags); - to_free = get_irq_entry_by_fd(fd); - if (to_free != NULL) { - do_free_by_irq_and_dev( - to_free, - irqnum, - NULL, - IGNORE_DEV - ); + entry = get_irq_entry_by_fd(fd); + if (!entry) + goto out; + + for (i = 0; i < NUM_IRQ_TYPES; i++) { + if (!entry->reg[i].events) + continue; + if (entry->reg[i].irq == irqnum) + entry->reg[i].events = 0; } - garbage_collect_irq_entries(); + + update_or_free_irq_entry(entry); +out: spin_unlock_irqrestore(&irq_lock, flags); + ignore_sigio_fd(fd); } EXPORT_SYMBOL(deactivate_fd); @@ -384,24 +298,17 @@ EXPORT_SYMBOL(deactivate_fd); */ int deactivate_all_fds(void) { - struct irq_entry *to_free; + struct irq_entry *entry; /* Stop IO. The IRQ loop has no lock so this is our * only way of making sure we are safe to dispose * of all IRQ handlers */ os_set_ioignore(); - to_free = active_fds; - while (to_free != NULL) { - do_free_by_irq_and_dev( - to_free, - -1, - NULL, - IGNORE_IRQ | IGNORE_DEV - ); - to_free = to_free->next; - } - /* don't garbage collect - we can no longer call kfree() here */ + + /* we can no longer call kfree() here so just deactivate */ + list_for_each_entry(entry, &active_fds, list) + os_del_epoll_fd(entry->fd); os_close_epoll_fd(); return 0; } @@ -421,31 +328,146 @@ unsigned int do_IRQ(int irq, struct uml_pt_regs *regs) return 1; } -void um_free_irq(unsigned int irq, void *dev) +void um_free_irq(int irq, void *dev) { + if (WARN(irq < 0 || irq > NR_IRQS, "freeing invalid irq %d", irq)) + return; + free_irq_by_irq_and_dev(irq, dev); free_irq(irq, dev); + clear_bit(irq, irqs_allocated); } EXPORT_SYMBOL(um_free_irq); -int um_request_irq(unsigned int irq, int fd, int type, - irq_handler_t handler, - unsigned long irqflags, const char * devname, - void *dev_id) +int um_request_irq(int irq, int fd, enum um_irq_type type, + irq_handler_t handler, unsigned long irqflags, + const char *devname, void *dev_id) { int err; + if (irq == UM_IRQ_ALLOC) { + int i; + + for (i = UM_FIRST_DYN_IRQ; i < NR_IRQS; i++) { + if (!test_and_set_bit(i, irqs_allocated)) { + irq = i; + break; + } + } + } + + if (irq < 0) + return -ENOSPC; + if (fd != -1) { err = activate_fd(irq, fd, type, dev_id); if (err) - return err; + goto error; } - return request_irq(irq, handler, irqflags, devname, dev_id); -} + err = request_irq(irq, handler, irqflags, devname, dev_id); + if (err < 0) + goto error; + return irq; +error: + clear_bit(irq, irqs_allocated); + return err; +} EXPORT_SYMBOL(um_request_irq); +#ifdef CONFIG_PM_SLEEP +void um_irqs_suspend(void) +{ + struct irq_entry *entry; + unsigned long flags; + + sig_info[SIGIO] = sigio_handler_suspend; + + spin_lock_irqsave(&irq_lock, flags); + list_for_each_entry(entry, &active_fds, list) { + enum um_irq_type t; + bool wake = false; + + for (t = 0; t < NUM_IRQ_TYPES; t++) { + if (!entry->reg[t].events) + continue; + + /* + * For the SIGIO_WRITE_IRQ, which is used to handle the + * SIGIO workaround thread, we need special handling: + * enable wake for it itself, but below we tell it about + * any FDs that should be suspended. + */ + if (entry->reg[t].wakeup || + entry->reg[t].irq == SIGIO_WRITE_IRQ) { + wake = true; + break; + } + } + + if (!wake) { + entry->suspended = true; + os_clear_fd_async(entry->fd); + entry->sigio_workaround = + !__ignore_sigio_fd(entry->fd); + } + } + spin_unlock_irqrestore(&irq_lock, flags); +} + +void um_irqs_resume(void) +{ + struct irq_entry *entry; + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + list_for_each_entry(entry, &active_fds, list) { + if (entry->suspended) { + int err = os_set_fd_async(entry->fd); + + WARN(err < 0, "os_set_fd_async returned %d\n", err); + entry->suspended = false; + + if (entry->sigio_workaround) { + err = __add_sigio_fd(entry->fd); + WARN(err < 0, "add_sigio_returned %d\n", err); + } + } + } + spin_unlock_irqrestore(&irq_lock, flags); + + sig_info[SIGIO] = sigio_handler; + send_sigio_to_self(); +} + +static int normal_irq_set_wake(struct irq_data *d, unsigned int on) +{ + struct irq_entry *entry; + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + list_for_each_entry(entry, &active_fds, list) { + enum um_irq_type t; + + for (t = 0; t < NUM_IRQ_TYPES; t++) { + if (!entry->reg[t].events) + continue; + + if (entry->reg[t].irq != d->irq) + continue; + entry->reg[t].wakeup = on; + goto unlock; + } + } +unlock: + spin_unlock_irqrestore(&irq_lock, flags); + return 0; +} +#else +#define normal_irq_set_wake NULL +#endif + /* * irq_chip must define at least enable/disable and ack when * the edge handler is used. @@ -454,7 +476,7 @@ static void dummy(struct irq_data *d) { } -/* This is used for everything else than the timer. */ +/* This is used for everything other than the timer. */ static struct irq_chip normal_irq_type = { .name = "SIGIO", .irq_disable = dummy, @@ -462,10 +484,11 @@ static struct irq_chip normal_irq_type = { .irq_ack = dummy, .irq_mask = dummy, .irq_unmask = dummy, + .irq_set_wake = normal_irq_set_wake, }; -static struct irq_chip SIGVTALRM_irq_type = { - .name = "SIGVTALRM", +static struct irq_chip alarm_irq_type = { + .name = "SIGALRM", .irq_disable = dummy, .irq_enable = dummy, .irq_ack = dummy, @@ -477,10 +500,9 @@ void __init init_IRQ(void) { int i; - irq_set_chip_and_handler(TIMER_IRQ, &SIGVTALRM_irq_type, handle_edge_irq); - + irq_set_chip_and_handler(TIMER_IRQ, &alarm_irq_type, handle_edge_irq); - for (i = 1; i <= LAST_IRQ; i++) + for (i = 1; i < NR_IRQS; i++) irq_set_chip_and_handler(i, &normal_irq_type, handle_edge_irq); /* Initialize EPOLL Loop */ os_setup_epoll(); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 0fcdc374a9a1..2a986ece5478 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -32,6 +32,7 @@ #include <os.h> #include <skas.h> #include <linux/time-internal.h> +#include <asm/set_memory.h> /* * This is a per-cpu array. A processor only modifies its entry and it only @@ -62,16 +63,18 @@ void free_stack(unsigned long stack, int order) free_pages(stack, order); } -unsigned long alloc_stack(int order, int atomic) +unsigned long alloc_stack(int atomic) { - unsigned long page; + unsigned long addr; gfp_t flags = GFP_KERNEL; if (atomic) flags = GFP_ATOMIC; - page = __get_free_pages(flags, order); + addr = __get_free_pages(flags, 1); - return page; + set_memory_ro(addr, 1); + + return addr + PAGE_SIZE; } static inline void set_current(struct task_struct *task) @@ -203,15 +206,12 @@ void initial_thread_cb(void (*proc)(void *), void *arg) kmalloc_ok = save_kmalloc_ok; } -static void um_idle_sleep(void) +void um_idle_sleep(void) { - unsigned long long duration = UM_NSEC_PER_SEC; - - if (time_travel_mode != TT_MODE_OFF) { - time_travel_sleep(duration); - } else { - os_idle_sleep(duration); - } + if (time_travel_mode != TT_MODE_OFF) + time_travel_sleep(); + else + os_idle_sleep(); } void arch_cpu_idle(void) diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c index d1cffc2a7f21..5085a50c3b8c 100644 --- a/arch/um/kernel/sigio.c +++ b/arch/um/kernel/sigio.c @@ -25,7 +25,7 @@ int write_sigio_irq(int fd) err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, 0, "write sigio", NULL); - if (err) { + if (err < 0) { printk(KERN_ERR "write_sigio_irq : um_request_irq failed, " "err = %d\n", err); return -1; diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 3d109ff3309b..f4db89b5b5a6 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -31,6 +31,7 @@ static bool time_travel_start_set; static unsigned long long time_travel_start; static unsigned long long time_travel_time; static LIST_HEAD(time_travel_events); +static LIST_HEAD(time_travel_irqs); static unsigned long long time_travel_timer_interval; static unsigned long long time_travel_next_event; static struct time_travel_event time_travel_timer_event; @@ -46,6 +47,9 @@ static void time_travel_set_time(unsigned long long ns) if (unlikely(ns < time_travel_time)) panic("time-travel: time goes backwards %lld -> %lld\n", time_travel_time, ns); + else if (unlikely(ns >= S64_MAX)) + panic("The system was going to sleep forever, aborting"); + time_travel_time = ns; } @@ -180,6 +184,14 @@ static void time_travel_ext_update_request(unsigned long long time) time == time_travel_ext_prev_request) return; + /* + * if we're running and are allowed to run past the request + * then we don't need to update it either + */ + if (!time_travel_ext_waiting && time_travel_ext_free_until_valid && + time < time_travel_ext_free_until) + return; + time_travel_ext_prev_request = time; time_travel_ext_prev_request_valid = true; time_travel_ext_req(UM_TIMETRAVEL_REQUEST, time); @@ -187,7 +199,13 @@ static void time_travel_ext_update_request(unsigned long long time) void __time_travel_propagate_time(void) { + static unsigned long long last_propagated; + + if (last_propagated == time_travel_time) + return; + time_travel_ext_req(UM_TIMETRAVEL_UPDATE, time_travel_time); + last_propagated = time_travel_time; } EXPORT_SYMBOL_GPL(__time_travel_propagate_time); @@ -214,6 +232,7 @@ static void time_travel_ext_wait(bool idle) }; time_travel_ext_prev_request_valid = false; + time_travel_ext_free_until_valid = false; time_travel_ext_waiting++; time_travel_ext_req(UM_TIMETRAVEL_WAIT, -1); @@ -260,11 +279,6 @@ static void __time_travel_add_event(struct time_travel_event *e, struct time_travel_event *tmp; bool inserted = false; - if (WARN(time_travel_mode == TT_MODE_BASIC && - e != &time_travel_timer_event, - "only timer events can be handled in basic mode")) - return; - if (e->pending) return; @@ -311,6 +325,35 @@ void time_travel_periodic_timer(struct time_travel_event *e) deliver_alarm(); } +void deliver_time_travel_irqs(void) +{ + struct time_travel_event *e; + unsigned long flags; + + /* + * Don't do anything for most cases. Note that because here we have + * to disable IRQs (and re-enable later) we'll actually recurse at + * the end of the function, so this is strictly necessary. + */ + if (likely(list_empty(&time_travel_irqs))) + return; + + local_irq_save(flags); + irq_enter(); + while ((e = list_first_entry_or_null(&time_travel_irqs, + struct time_travel_event, + list))) { + WARN(e->time != time_travel_time, + "time moved from %lld to %lld before IRQ delivery\n", + time_travel_time, e->time); + list_del(&e->list); + e->pending = false; + e->fn(e); + } + irq_exit(); + local_irq_restore(flags); +} + static void time_travel_deliver_event(struct time_travel_event *e) { if (e == &time_travel_timer_event) { @@ -319,6 +362,14 @@ static void time_travel_deliver_event(struct time_travel_event *e) * by itself, so must handle it specially here */ e->fn(e); + } else if (irqs_disabled()) { + list_add_tail(&e->list, &time_travel_irqs); + /* + * set pending again, it was set to false when the + * event was deleted from the original list, but + * now it's still pending until we deliver the IRQ. + */ + e->pending = true; } else { unsigned long flags; @@ -404,9 +455,14 @@ static void time_travel_oneshot_timer(struct time_travel_event *e) deliver_alarm(); } -void time_travel_sleep(unsigned long long duration) +void time_travel_sleep(void) { - unsigned long long next = time_travel_time + duration; + /* + * Wait "forever" (using S64_MAX because there are some potential + * wrapping issues, especially with the current TT_MODE_EXTERNAL + * controller application. + */ + unsigned long long next = S64_MAX; if (time_travel_mode == TT_MODE_BASIC) os_timer_disable(); @@ -483,6 +539,7 @@ invalid_number: #define time_travel_start_set 0 #define time_travel_start 0 #define time_travel_time 0 +#define time_travel_ext_waiting 0 static inline void time_travel_update_time(unsigned long long ns, bool retearly) { @@ -628,7 +685,8 @@ static u64 timer_read(struct clocksource *cs) * "what do I do next" and onstack event we use to know when * to return from time_travel_update_time(). */ - if (!irqs_disabled() && !in_interrupt() && !in_softirq()) + if (!irqs_disabled() && !in_interrupt() && !in_softirq() && + !time_travel_ext_waiting) time_travel_update_time(time_travel_time + TIMER_MULTIPLIER, false); @@ -673,10 +731,8 @@ void read_persistent_clock64(struct timespec64 *ts) { long long nsecs; - if (time_travel_start_set) + if (time_travel_mode != TT_MODE_OFF) nsecs = time_travel_start + time_travel_time; - else if (time_travel_mode == TT_MODE_EXTERNAL) - nsecs = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1); else nsecs = os_persistent_clock_emulation(); @@ -686,6 +742,25 @@ void read_persistent_clock64(struct timespec64 *ts) void __init time_init(void) { +#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT + switch (time_travel_mode) { + case TT_MODE_EXTERNAL: + time_travel_start = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1); + /* controller gave us the *current* time, so adjust by that */ + time_travel_ext_get_time(); + time_travel_start -= time_travel_time; + break; + case TT_MODE_INFCPU: + case TT_MODE_BASIC: + if (!time_travel_start_set) + time_travel_start = os_persistent_clock_emulation(); + break; + case TT_MODE_OFF: + /* we just read the host clock with os_persistent_clock_emulation() */ + break; + } +#endif + timer_set_signal_handler(); late_time_init = um_timer_setup; } diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 61776790cd67..437d1f1cc5ec 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -608,3 +608,57 @@ void force_flush_all(void) vma = vma->vm_next; } } + +struct page_change_data { + unsigned int set_mask, clear_mask; +}; + +static int change_page_range(pte_t *ptep, unsigned long addr, void *data) +{ + struct page_change_data *cdata = data; + pte_t pte = READ_ONCE(*ptep); + + pte_clear_bits(pte, cdata->clear_mask); + pte_set_bits(pte, cdata->set_mask); + + set_pte(ptep, pte); + return 0; +} + +static int change_memory(unsigned long start, unsigned long pages, + unsigned int set_mask, unsigned int clear_mask) +{ + unsigned long size = pages * PAGE_SIZE; + struct page_change_data data; + int ret; + + data.set_mask = set_mask; + data.clear_mask = clear_mask; + + ret = apply_to_page_range(&init_mm, start, size, change_page_range, + &data); + + flush_tlb_kernel_range(start, start + size); + + return ret; +} + +int set_memory_ro(unsigned long addr, int numpages) +{ + return change_memory(addr, numpages, 0, _PAGE_RW); +} + +int set_memory_rw(unsigned long addr, int numpages) +{ + return change_memory(addr, numpages, _PAGE_RW, 0); +} + +int set_memory_nx(unsigned long addr, int numpages) +{ + return -EOPNOTSUPP; +} + +int set_memory_x(unsigned long addr, int numpages) +{ + return -EOPNOTSUPP; +} diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 76b37297b7d4..31d356b1ffd8 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -13,6 +13,7 @@ #include <linux/sched.h> #include <linux/sched/task.h> #include <linux/kmsg_dump.h> +#include <linux/suspend.h> #include <asm/processor.h> #include <asm/sections.h> @@ -377,3 +378,69 @@ void *text_poke(void *addr, const void *opcode, size_t len) void text_poke_sync(void) { } + +void uml_pm_wake(void) +{ + pm_system_wakeup(); +} + +#ifdef CONFIG_PM_SLEEP +static int um_suspend_valid(suspend_state_t state) +{ + return state == PM_SUSPEND_MEM; +} + +static int um_suspend_prepare(void) +{ + um_irqs_suspend(); + return 0; +} + +static int um_suspend_enter(suspend_state_t state) +{ + if (WARN_ON(state != PM_SUSPEND_MEM)) + return -EINVAL; + + /* + * This is identical to the idle sleep, but we've just + * (during suspend) turned off all interrupt sources + * except for the ones we want, so now we can only wake + * up on something we actually want to wake up on. All + * timing has also been suspended. + */ + um_idle_sleep(); + return 0; +} + +static void um_suspend_finish(void) +{ + um_irqs_resume(); +} + +const struct platform_suspend_ops um_suspend_ops = { + .valid = um_suspend_valid, + .prepare = um_suspend_prepare, + .enter = um_suspend_enter, + .finish = um_suspend_finish, +}; + +static int init_pm_wake_signal(void) +{ + /* + * In external time-travel mode we can't use signals to wake up + * since that would mess with the scheduling. We'll have to do + * some additional work to support wakeup on virtio devices or + * similar, perhaps implementing a fake RTC controller that can + * trigger wakeup (and request the appropriate scheduling from + * the external scheduler when going to suspend.) + */ + if (time_travel_mode != TT_MODE_EXTERNAL) + register_pm_wake_signal(); + + suspend_set_ops(&um_suspend_ops); + + return 0; +} + +late_initcall(init_pm_wake_signal); +#endif diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index 839915b8c31c..77ac50baa3f8 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -10,6 +10,8 @@ obj-y = execvp.o file.o helper.o irq.o main.o mem.o process.o \ registers.o sigio.o signal.o start_up.o time.o tty.o \ umid.o user_syms.o util.o drivers/ skas/ +CFLAGS_signal.o += -Wframe-larger-than=4096 + obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o USER_OBJS := $(user-objs-y) elf_aux.o execvp.o file.o helper.o irq.o \ diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index 9fa6e4187d4f..feb48d796e00 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -45,7 +45,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) unsigned long stack, sp; int pid, fds[2], ret, n; - stack = alloc_stack(0, __cant_sleep()); + stack = alloc_stack(__cant_sleep()); if (stack == 0) return -ENOMEM; @@ -116,7 +116,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, unsigned long stack, sp; int pid, status, err; - stack = alloc_stack(0, __cant_sleep()); + stack = alloc_stack(__cant_sleep()); if (stack == 0) return -ENOMEM; diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index d508310ee5e1..98ea910ef87c 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c @@ -45,10 +45,10 @@ int os_epoll_triggered(int index, int events) * access to the right includes/defines for EPOLL constants. */ -int os_event_mask(int irq_type) +int os_event_mask(enum um_irq_type irq_type) { if (irq_type == IRQ_READ) - return EPOLLIN | EPOLLPRI; + return EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP | EPOLLRDHUP; if (irq_type == IRQ_WRITE) return EPOLLOUT; return 0; diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 75558080d0bf..6597ea1986ff 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -164,45 +164,55 @@ static void update_thread(void) set_signals_trace(flags); } -int add_sigio_fd(int fd) +int __add_sigio_fd(int fd) { struct pollfd *p; - int err = 0, i, n; + int err, i, n; - sigio_lock(); for (i = 0; i < all_sigio_fds.used; i++) { if (all_sigio_fds.poll[i].fd == fd) break; } if (i == all_sigio_fds.used) - goto out; + return -ENOSPC; p = &all_sigio_fds.poll[i]; for (i = 0; i < current_poll.used; i++) { if (current_poll.poll[i].fd == fd) - goto out; + return 0; } n = current_poll.used; err = need_poll(&next_poll, n + 1); if (err) - goto out; + return err; memcpy(next_poll.poll, current_poll.poll, current_poll.used * sizeof(struct pollfd)); next_poll.poll[n] = *p; next_poll.used = n + 1; update_thread(); - out: + + return 0; +} + + +int add_sigio_fd(int fd) +{ + int err; + + sigio_lock(); + err = __add_sigio_fd(fd); sigio_unlock(); + return err; } -int ignore_sigio_fd(int fd) +int __ignore_sigio_fd(int fd) { struct pollfd *p; - int err = 0, i, n = 0; + int err, i, n = 0; /* * This is called from exitcalls elsewhere in UML - if @@ -212,17 +222,16 @@ int ignore_sigio_fd(int fd) if (write_sigio_pid == -1) return -EIO; - sigio_lock(); for (i = 0; i < current_poll.used; i++) { if (current_poll.poll[i].fd == fd) break; } if (i == current_poll.used) - goto out; + return -ENOENT; err = need_poll(&next_poll, current_poll.used - 1); if (err) - goto out; + return err; for (i = 0; i < current_poll.used; i++) { p = ¤t_poll.poll[i]; @@ -232,8 +241,18 @@ int ignore_sigio_fd(int fd) next_poll.used = current_poll.used - 1; update_thread(); - out: + + return 0; +} + +int ignore_sigio_fd(int fd) +{ + int err; + + sigio_lock(); + err = __ignore_sigio_fd(fd); sigio_unlock(); + return err; } @@ -336,7 +355,7 @@ out_close1: close(l_write_sigio_fds[1]); } -void sigio_broken(int fd, int read) +void sigio_broken(int fd) { int err; @@ -352,7 +371,7 @@ void sigio_broken(int fd, int read) all_sigio_fds.poll[all_sigio_fds.used++] = ((struct pollfd) { .fd = fd, - .events = read ? POLLIN : POLLOUT, + .events = POLLIN, .revents = 0 }); out: sigio_unlock(); @@ -360,17 +379,16 @@ out: /* Changed during early boot */ static int pty_output_sigio; -static int pty_close_sigio; -void maybe_sigio_broken(int fd, int read) +void maybe_sigio_broken(int fd) { if (!isatty(fd)) return; - if ((read || pty_output_sigio) && (!read || pty_close_sigio)) + if (pty_output_sigio) return; - sigio_broken(fd, read); + sigio_broken(fd); } static void sigio_cleanup(void) @@ -514,19 +532,6 @@ static void tty_output(int master, int slave) printk(UM_KERN_CONT "tty_output : read failed, err = %d\n", n); } -static void tty_close(int master, int slave) -{ - printk(UM_KERN_INFO "Checking that host ptys support SIGIO on " - "close..."); - - close(slave); - if (got_sigio) { - printk(UM_KERN_CONT "Yes\n"); - pty_close_sigio = 1; - } else - printk(UM_KERN_CONT "No, enabling workaround\n"); -} - static void __init check_sigio(void) { if ((access("/dev/ptmx", R_OK) < 0) && @@ -536,7 +541,6 @@ static void __init check_sigio(void) return; } check_one_sigio(tty_output); - check_one_sigio(tty_close); } /* Here because it only does the SIGIO testing for now */ diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index b58bc68cbe64..96f511d1aabe 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -136,6 +136,16 @@ void set_sigstack(void *sig_stack, int size) panic("enabling signal stack failed, errno = %d\n", errno); } +static void sigusr1_handler(int sig, struct siginfo *unused_si, mcontext_t *mc) +{ + uml_pm_wake(); +} + +void register_pm_wake_signal(void) +{ + set_handler(SIGUSR1); +} + static void (*handlers[_NSIG])(int sig, struct siginfo *si, mcontext_t *mc) = { [SIGSEGV] = sig_handler, [SIGBUS] = sig_handler, @@ -145,7 +155,9 @@ static void (*handlers[_NSIG])(int sig, struct siginfo *si, mcontext_t *mc) = { [SIGIO] = sig_handler, [SIGWINCH] = sig_handler, - [SIGALRM] = timer_alarm_handler + [SIGALRM] = timer_alarm_handler, + + [SIGUSR1] = sigusr1_handler, }; static void hard_handler(int sig, siginfo_t *si, void *p) @@ -222,6 +234,11 @@ void set_handler(int sig) panic("sigprocmask failed - errno = %d\n", errno); } +void send_sigio_to_self(void) +{ + kill(os_getpid(), SIGIO); +} + int change_sig(int signal, int on) { sigset_t sigset; @@ -254,6 +271,9 @@ void unblock_signals(void) return; signals_enabled = 1; +#ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT + deliver_time_travel_irqs(); +#endif /* * We loop because the IRQ handler returns with interrupts off. So, diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 4fb877b99dde..0621d521208e 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -400,7 +400,20 @@ void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs) if (WIFSTOPPED(status)) { int sig = WSTOPSIG(status); - ptrace(PTRACE_GETSIGINFO, pid, 0, (struct siginfo *)&si); + /* These signal handlers need the si argument. + * The SIGIO and SIGALARM handlers which constitute the + * majority of invocations, do not use it. + */ + switch (sig) { + case SIGSEGV: + case SIGTRAP: + case SIGILL: + case SIGBUS: + case SIGFPE: + case SIGWINCH: + ptrace(PTRACE_GETSIGINFO, pid, 0, (struct siginfo *)&si); + break; + } switch (sig) { case SIGSEGV: diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 90f6de224c70..a61cbf73a179 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -7,6 +7,7 @@ */ #include <stddef.h> +#include <unistd.h> #include <errno.h> #include <signal.h> #include <time.h> @@ -99,19 +100,9 @@ long long os_nsecs(void) } /** - * os_idle_sleep() - sleep for a given time of nsecs - * @nsecs: nanoseconds to sleep + * os_idle_sleep() - sleep until interrupted */ -void os_idle_sleep(unsigned long long nsecs) +void os_idle_sleep(void) { - struct timespec ts = { - .tv_sec = nsecs / UM_NSEC_PER_SEC, - .tv_nsec = nsecs % UM_NSEC_PER_SEC - }; - - /* - * Relay the signal if clock_nanosleep is interrupted. - */ - if (clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL)) - deliver_alarm(); + pause(); } diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index 1d7558dac75f..a3dd61521d24 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c @@ -137,20 +137,13 @@ static inline int is_umdir_used(char *dir) { char pid[sizeof("nnnnnnnnn")], *end, *file; int dead, fd, p, n, err; - size_t filelen; + size_t filelen = strlen(dir) + sizeof("/pid") + 1; - err = asprintf(&file, "%s/pid", dir); - if (err < 0) - return 0; - - filelen = strlen(file); + file = malloc(filelen); + if (!file) + return -ENOMEM; - n = snprintf(file, filelen, "%s/pid", dir); - if (n >= filelen) { - printk(UM_KERN_ERR "is_umdir_used - pid filename too long\n"); - err = -E2BIG; - goto out; - } + snprintf(file, filelen, "%s/pid", dir); dead = 0; fd = open(file, O_RDONLY); diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index a8bd298e45b1..21f851179ff0 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -19,6 +19,7 @@ config X86_32 select KMAP_LOCAL select MODULES_USE_ELF_REL select OLD_SIGACTION + select ARCH_SPLIT_ARG64 config X86_64 def_bool y @@ -171,6 +172,7 @@ config X86 select HAVE_DMA_CONTIGUOUS select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS + select HAVE_DYNAMIC_FTRACE_WITH_ARGS if X86_64 select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS select HAVE_EBPF_JIT select HAVE_EFFICIENT_UNALIGNED_ACCESS diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 40b8fd375d52..e0bc3988c3fa 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -35,7 +35,7 @@ cflags-$(CONFIG_X86_32) := -march=i386 cflags-$(CONFIG_X86_64) := -mcmodel=small -mno-red-zone KBUILD_CFLAGS += $(cflags-y) KBUILD_CFLAGS += -mno-mmx -mno-sse -KBUILD_CFLAGS += -ffreestanding +KBUILD_CFLAGS += -ffreestanding -fshort-wchar KBUILD_CFLAGS += -fno-stack-protector KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) KBUILD_CFLAGS += $(call cc-disable-warning, gnu) diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index d9a631c5973c..901ea5ebec22 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -12,6 +12,7 @@ #undef CONFIG_PARAVIRT_XXL #undef CONFIG_PARAVIRT_SPINLOCKS #undef CONFIG_KASAN +#undef CONFIG_KASAN_GENERIC /* cpu_feature_enabled() cannot be used this early */ #define USE_EARLY_PGTABLE_L5 diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 18d8f17f755c..0904f5676e4d 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -73,10 +73,8 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, unsigned int nr) { if (likely(nr < IA32_NR_syscalls)) { - instrumentation_begin(); nr = array_index_nospec(nr, IA32_NR_syscalls); regs->ax = ia32_sys_call_table[nr](regs); - instrumentation_end(); } } @@ -91,8 +89,11 @@ __visible noinstr void do_int80_syscall_32(struct pt_regs *regs) * or may not be necessary, but it matches the old asm behavior. */ nr = (unsigned int)syscall_enter_from_user_mode(regs, nr); + instrumentation_begin(); do_syscall_32_irqs_on(regs, nr); + + instrumentation_end(); syscall_exit_to_user_mode(regs); } @@ -121,11 +122,12 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs) res = get_user(*(u32 *)®s->bp, (u32 __user __force *)(unsigned long)(u32)regs->sp); } - instrumentation_end(); if (res) { /* User code screwed up. */ regs->ax = -EFAULT; + + instrumentation_end(); syscall_exit_to_user_mode(regs); return false; } @@ -135,6 +137,8 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs) /* Now this is just like a normal syscall. */ do_syscall_32_irqs_on(regs, nr); + + instrumentation_end(); syscall_exit_to_user_mode(regs); return true; } diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl index 0d0667a9fbd7..874aeacde2dd 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl @@ -445,3 +445,4 @@ 438 i386 pidfd_getfd sys_pidfd_getfd 439 i386 faccessat2 sys_faccessat2 440 i386 process_madvise sys_process_madvise +441 i386 epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl index 379819244b91..78672124d28b 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl @@ -362,6 +362,7 @@ 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 440 common process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 # # Due to a historical design error, certain syscalls are numbered differently diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index e04d90af4c27..6375967a8244 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -16,6 +16,7 @@ #include <asm/hyperv-tlfs.h> #include <asm/mshyperv.h> #include <asm/idtentry.h> +#include <linux/kexec.h> #include <linux/version.h> #include <linux/vmalloc.h> #include <linux/mm.h> @@ -26,6 +27,8 @@ #include <linux/syscore_ops.h> #include <clocksource/hyperv_timer.h> +int hyperv_init_cpuhp; + void *hv_hypercall_pg; EXPORT_SYMBOL_GPL(hv_hypercall_pg); @@ -312,6 +315,25 @@ static struct syscore_ops hv_syscore_ops = { .resume = hv_resume, }; +static void (* __initdata old_setup_percpu_clockev)(void); + +static void __init hv_stimer_setup_percpu_clockev(void) +{ + /* + * Ignore any errors in setting up stimer clockevents + * as we can run with the LAPIC timer as a fallback. + */ + (void)hv_stimer_alloc(); + + /* + * Still register the LAPIC timer, because the direct-mode STIMER is + * not supported by old versions of Hyper-V. This also allows users + * to switch to LAPIC timer via /sys, if they want to. + */ + if (old_setup_percpu_clockev) + old_setup_percpu_clockev(); +} + /* * This function is to be invoked early in the boot sequence after the * hypervisor has been detected. @@ -390,10 +412,14 @@ void __init hyperv_init(void) wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); /* - * Ignore any errors in setting up stimer clockevents - * as we can run with the LAPIC timer as a fallback. + * hyperv_init() is called before LAPIC is initialized: see + * apic_intr_mode_init() -> x86_platform.apic_post_init() and + * apic_bsp_setup() -> setup_local_APIC(). The direct-mode STIMER + * depends on LAPIC, so hv_stimer_alloc() should be called from + * x86_init.timers.setup_percpu_clockev. */ - (void)hv_stimer_alloc(); + old_setup_percpu_clockev = x86_init.timers.setup_percpu_clockev; + x86_init.timers.setup_percpu_clockev = hv_stimer_setup_percpu_clockev; hv_apic_init(); @@ -401,6 +427,7 @@ void __init hyperv_init(void) register_syscore_ops(&hv_syscore_ops); + hyperv_init_cpuhp = cpuhp; return; remove_cpuhp_state: diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c index 5208ba49c89a..2c87350c1fb0 100644 --- a/arch/x86/hyperv/mmu.c +++ b/arch/x86/hyperv/mmu.c @@ -66,11 +66,17 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus, if (!hv_hypercall_pg) goto do_native; - if (cpumask_empty(cpus)) - return; - local_irq_save(flags); + /* + * Only check the mask _after_ interrupt has been disabled to avoid the + * mask changing under our feet. + */ + if (cpumask_empty(cpus)) { + local_irq_restore(flags); + return; + } + flush_pcpu = (struct hv_tlb_flush **) this_cpu_ptr(hyperv_pcpu_input_arg); diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index f5ef2d5b9231..84b887825f12 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -237,6 +237,7 @@ #define X86_FEATURE_VMCALL ( 8*32+18) /* "" Hypervisor supports the VMCALL instruction */ #define X86_FEATURE_VMW_VMMCALL ( 8*32+19) /* "" VMware prefers VMMCALL hypercall instruction */ #define X86_FEATURE_SEV_ES ( 8*32+20) /* AMD Secure Encrypted Virtualization - Encrypted State */ +#define X86_FEATURE_VM_PAGE_FLUSH ( 8*32+21) /* "" VM Page Flush MSR is supported */ /* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */ #define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/ @@ -376,6 +377,7 @@ #define X86_FEATURE_TSXLDTRK (18*32+16) /* TSX Suspend Load Address Tracking */ #define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */ #define X86_FEATURE_ARCH_LBR (18*32+19) /* Intel ARCH LBR */ +#define X86_FEATURE_AVX512_FP16 (18*32+23) /* AVX512 FP16 */ #define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */ #define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */ #define X86_FEATURE_FLUSH_L1D (18*32+28) /* Flush L1D cache */ diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index bc9758ef292e..c98f78330b09 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -213,8 +213,6 @@ static inline bool efi_is_64bit(void) static inline bool efi_is_native(void) { - if (!IS_ENABLED(CONFIG_X86_64)) - return true; return efi_is_64bit(); } @@ -382,4 +380,7 @@ static inline void efi_fake_memmap_early(void) } #endif +#define arch_ima_efi_boot_mode \ + ({ extern struct boot_params boot_params; boot_params.secure_boot; }) + #endif /* _ASM_X86_EFI_H */ diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h index a5aba4ab0224..67a4f1cb2aac 100644 --- a/arch/x86/include/asm/fpu/api.h +++ b/arch/x86/include/asm/fpu/api.h @@ -16,14 +16,25 @@ * Use kernel_fpu_begin/end() if you intend to use FPU in kernel context. It * disables preemption so be careful if you intend to use it for long periods * of time. - * If you intend to use the FPU in softirq you need to check first with + * If you intend to use the FPU in irq/softirq you need to check first with * irq_fpu_usable() if it is possible. */ -extern void kernel_fpu_begin(void); + +/* Kernel FPU states to initialize in kernel_fpu_begin_mask() */ +#define KFPU_387 _BITUL(0) /* 387 state will be initialized */ +#define KFPU_MXCSR _BITUL(1) /* MXCSR will be initialized */ + +extern void kernel_fpu_begin_mask(unsigned int kfpu_mask); extern void kernel_fpu_end(void); extern bool irq_fpu_usable(void); extern void fpregs_mark_activate(void); +/* Code that is unaware of kernel_fpu_begin_mask() can use this */ +static inline void kernel_fpu_begin(void) +{ + kernel_fpu_begin_mask(KFPU_387 | KFPU_MXCSR); +} + /* * Use fpregs_lock() while editing CPU's FPU registers or fpu->state. * A context switch will (and softirq might) save CPU's FPU registers to diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h index 84b9449be080..9f3130f40807 100644 --- a/arch/x86/include/asm/ftrace.h +++ b/arch/x86/include/asm/ftrace.h @@ -41,6 +41,24 @@ static inline void arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned regs->orig_ax = addr; } +#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS +struct ftrace_regs { + struct pt_regs regs; +}; + +static __always_inline struct pt_regs * +arch_ftrace_get_regs(struct ftrace_regs *fregs) +{ + /* Only when FL_SAVE_REGS is set, cs will be non zero */ + if (!fregs->regs.cs) + return NULL; + return &fregs->regs; +} + +#define ftrace_instruction_pointer_set(fregs, _ip) \ + do { (fregs)->regs.ip = (_ip); } while (0) +#endif + #ifdef CONFIG_DYNAMIC_FTRACE struct dyn_arch_ftrace { diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index 5e658ba2654a..9abe842dbd84 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -97,6 +97,7 @@ #define INTEL_FAM6_LAKEFIELD 0x8A #define INTEL_FAM6_ALDERLAKE 0x97 +#define INTEL_FAM6_ALDERLAKE_L 0x9A /* "Small Core" Processors (Atom) */ diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 7e5f33a0d0e2..3d6616f6f6ef 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -614,6 +614,7 @@ struct kvm_vcpu_arch { struct kvm_pio_request pio; void *pio_data; + void *guest_ins_data; u8 event_exit_inst_len; @@ -805,6 +806,9 @@ struct kvm_vcpu_arch { */ bool enforce; } pv_cpuid; + + /* Protected Guests */ + bool guest_state_protected; }; struct kvm_lpage_info { @@ -1006,9 +1010,21 @@ struct kvm_arch { */ bool tdp_mmu_enabled; - /* List of struct tdp_mmu_pages being used as roots */ + /* + * List of struct kvmp_mmu_pages being used as roots. + * All struct kvm_mmu_pages in the list should have + * tdp_mmu_page set. + * All struct kvm_mmu_pages in the list should have a positive + * root_count except when a thread holds the MMU lock and is removing + * an entry from the list. + */ struct list_head tdp_mmu_roots; - /* List of struct tdp_mmu_pages not being used as roots */ + + /* + * List of struct kvmp_mmu_pages not being used as roots. + * All struct kvm_mmu_pages in the list should have + * tdp_mmu_page set and a root_count of 0. + */ struct list_head tdp_mmu_pages; }; @@ -1088,7 +1104,7 @@ struct kvm_x86_ops { void (*hardware_disable)(void); void (*hardware_unsetup)(void); bool (*cpu_has_accelerated_tpr)(void); - bool (*has_emulated_msr)(u32 index); + bool (*has_emulated_msr)(struct kvm *kvm, u32 index); void (*vcpu_after_set_cpuid)(struct kvm_vcpu *vcpu); unsigned int vm_size; @@ -1115,7 +1131,8 @@ struct kvm_x86_ops { struct kvm_segment *var, int seg); void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l); void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0); - int (*set_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4); + bool (*is_valid_cr4)(struct kvm_vcpu *vcpu, unsigned long cr0); + void (*set_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4); int (*set_efer)(struct kvm_vcpu *vcpu, u64 efer); void (*get_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); void (*set_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); @@ -1231,6 +1248,7 @@ struct kvm_x86_ops { void (*enable_log_dirty_pt_masked)(struct kvm *kvm, struct kvm_memory_slot *slot, gfn_t offset, unsigned long mask); + int (*cpu_dirty_log_size)(void); /* pmu operations of sub-arch */ const struct kvm_pmu_ops *pmu_ops; @@ -1280,6 +1298,9 @@ struct kvm_x86_ops { void (*migrate_timers)(struct kvm_vcpu *vcpu); void (*msr_filter_changed)(struct kvm_vcpu *vcpu); + int (*complete_emulated_msr)(struct kvm_vcpu *vcpu, int err); + + void (*vcpu_deliver_sipi_vector)(struct kvm_vcpu *vcpu, u8 vector); }; struct kvm_x86_nested_ops { @@ -1461,6 +1482,7 @@ int kvm_fast_pio(struct kvm_vcpu *vcpu, int size, unsigned short port, int in); int kvm_emulate_cpuid(struct kvm_vcpu *vcpu); int kvm_emulate_halt(struct kvm_vcpu *vcpu); int kvm_vcpu_halt(struct kvm_vcpu *vcpu); +int kvm_emulate_ap_reset_hold(struct kvm_vcpu *vcpu); int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu); void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); @@ -1470,6 +1492,10 @@ void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector); int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index, int reason, bool has_error_code, u32 error_code); +void kvm_free_guest_fpu(struct kvm_vcpu *vcpu); + +void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned long cr0); +void kvm_post_set_cr4(struct kvm_vcpu *vcpu, unsigned long old_cr4, unsigned long cr4); int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); @@ -1696,7 +1722,8 @@ void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu); int kvm_is_in_guest(void); -int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size); +void __user *__x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, + u32 size); bool kvm_vcpu_is_reset_bsp(struct kvm_vcpu *vcpu); bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu); @@ -1743,4 +1770,6 @@ static inline int kvm_cpu_get_apicid(int mps_cpu) #define GET_SMSTATE(type, buf, offset) \ (*(type *)((buf) + (offset) - 0x7e00)) +int kvm_cpu_dirty_log_size(void); + #endif /* _ASM_X86_KVM_HOST_H */ diff --git a/arch/x86/include/asm/livepatch.h b/arch/x86/include/asm/livepatch.h index 1fde1ab6559e..7c5cc6660e4b 100644 --- a/arch/x86/include/asm/livepatch.h +++ b/arch/x86/include/asm/livepatch.h @@ -12,9 +12,9 @@ #include <asm/setup.h> #include <linux/ftrace.h> -static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip) +static inline void klp_arch_set_pc(struct ftrace_regs *fregs, unsigned long ip) { - regs->ip = ip; + ftrace_instruction_pointer_set(fregs, ip); } #endif /* _ASM_X86_LIVEPATCH_H */ diff --git a/arch/x86/include/asm/local64.h b/arch/x86/include/asm/local64.h deleted file mode 100644 index 36c93b5cc239..000000000000 --- a/arch/x86/include/asm/local64.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/local64.h> diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index ffc289992d1b..30f76b966857 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -74,6 +74,8 @@ static inline void hv_disable_stimer0_percpu_irq(int irq) {} #if IS_ENABLED(CONFIG_HYPERV) +extern int hyperv_init_cpuhp; + extern void *hv_hypercall_pg; extern void __percpu **hyperv_pcpu_input_arg; diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 2b5fc9accec4..546d6ecf0a35 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -472,6 +472,7 @@ #define MSR_AMD64_ICIBSEXTDCTL 0xc001103c #define MSR_AMD64_IBSOPDATA4 0xc001103d #define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */ +#define MSR_AMD64_VM_PAGE_FLUSH 0xc001011e #define MSR_AMD64_SEV_ES_GHCB 0xc0010130 #define MSR_AMD64_SEV 0xc0010131 #define MSR_AMD64_SEV_ENABLED_BIT 0 diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 0b4920a7238e..e16cccdd0420 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -86,7 +86,7 @@ static inline void do_trace_rdpmc(unsigned int msr, u64 val, int failed) {} * think of extending them - you will be slapped with a stinking trout or a frozen * shark will reach you, wherever you are! You've been warned. */ -static inline unsigned long long notrace __rdmsr(unsigned int msr) +static __always_inline unsigned long long __rdmsr(unsigned int msr) { DECLARE_ARGS(val, low, high); @@ -98,7 +98,7 @@ static inline unsigned long long notrace __rdmsr(unsigned int msr) return EAX_EDX_VAL(val, low, high); } -static inline void notrace __wrmsr(unsigned int msr, u32 low, u32 high) +static __always_inline void __wrmsr(unsigned int msr, u32 low, u32 high) { asm volatile("1: wrmsr\n" "2:\n" diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 71d630bb5e08..1c561945b426 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -98,6 +98,16 @@ enum { INTERCEPT_MWAIT_COND, INTERCEPT_XSETBV, INTERCEPT_RDPRU, + TRAP_EFER_WRITE, + TRAP_CR0_WRITE, + TRAP_CR1_WRITE, + TRAP_CR2_WRITE, + TRAP_CR3_WRITE, + TRAP_CR4_WRITE, + TRAP_CR5_WRITE, + TRAP_CR6_WRITE, + TRAP_CR7_WRITE, + TRAP_CR8_WRITE, /* Byte offset 014h (word 5) */ INTERCEPT_INVLPGB = 160, INTERCEPT_INVLPGB_ILLEGAL, @@ -130,7 +140,7 @@ struct __attribute__ ((__packed__)) vmcb_control_area { u32 exit_int_info_err; u64 nested_ctl; u64 avic_vapic_bar; - u8 reserved_4[8]; + u64 ghcb_gpa; u32 event_inj; u32 event_inj_err; u64 nested_cr3; @@ -144,6 +154,8 @@ struct __attribute__ ((__packed__)) vmcb_control_area { u8 reserved_6[8]; /* Offset 0xe8 */ u64 avic_logical_id; /* Offset 0xf0 */ u64 avic_physical_id; /* Offset 0xf8 */ + u8 reserved_7[8]; + u64 vmsa_pa; /* Used for an SEV-ES guest */ }; @@ -178,7 +190,8 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define LBR_CTL_ENABLE_MASK BIT_ULL(0) #define VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK BIT_ULL(1) -#define SVM_INTERRUPT_SHADOW_MASK 1 +#define SVM_INTERRUPT_SHADOW_MASK BIT_ULL(0) +#define SVM_GUEST_INTERRUPT_MASK BIT_ULL(1) #define SVM_IOIO_STR_SHIFT 2 #define SVM_IOIO_REP_SHIFT 3 @@ -197,6 +210,7 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define SVM_NESTED_CTL_NP_ENABLE BIT(0) #define SVM_NESTED_CTL_SEV_ENABLE BIT(1) +#define SVM_NESTED_CTL_SEV_ES_ENABLE BIT(2) struct vmcb_seg { u16 selector; @@ -220,7 +234,8 @@ struct vmcb_save_area { u8 cpl; u8 reserved_2[4]; u64 efer; - u8 reserved_3[112]; + u8 reserved_3[104]; + u64 xss; /* Valid for SEV-ES only */ u64 cr4; u64 cr3; u64 cr0; @@ -251,9 +266,12 @@ struct vmcb_save_area { /* * The following part of the save area is valid only for - * SEV-ES guests when referenced through the GHCB. + * SEV-ES guests when referenced through the GHCB or for + * saving to the host save area. */ - u8 reserved_7[104]; + u8 reserved_7[80]; + u32 pkru; + u8 reserved_7a[20]; u64 reserved_8; /* rax already available at 0x01f8 */ u64 rcx; u64 rdx; @@ -294,7 +312,7 @@ struct ghcb { #define EXPECTED_VMCB_SAVE_AREA_SIZE 1032 -#define EXPECTED_VMCB_CONTROL_AREA_SIZE 256 +#define EXPECTED_VMCB_CONTROL_AREA_SIZE 272 #define EXPECTED_GHCB_SIZE PAGE_SIZE static inline void __unused_size_checks(void) @@ -379,6 +397,16 @@ struct vmcb { (unsigned long *)&ghcb->save.valid_bitmap); \ } \ \ + static inline u64 ghcb_get_##field(struct ghcb *ghcb) \ + { \ + return ghcb->save.field; \ + } \ + \ + static inline u64 ghcb_get_##field##_if_valid(struct ghcb *ghcb) \ + { \ + return ghcb_##field##_is_valid(ghcb) ? ghcb->save.field : 0; \ + } \ + \ static inline void ghcb_set_##field(struct ghcb *ghcb, u64 value) \ { \ __set_bit(GHCB_BITMAP_IDX(field), \ diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 488a8e848754..9239399e5491 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -110,6 +110,8 @@ extern const struct cpumask *cpu_coregroup_mask(int cpu); #define topology_die_id(cpu) (cpu_data(cpu).cpu_die_id) #define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) +extern unsigned int __max_die_per_package; + #ifdef CONFIG_SMP #define topology_die_cpumask(cpu) (per_cpu(cpu_die_map, cpu)) #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) @@ -118,8 +120,6 @@ extern const struct cpumask *cpu_coregroup_mask(int cpu); extern unsigned int __max_logical_packages; #define topology_max_packages() (__max_logical_packages) -extern unsigned int __max_die_per_package; - static inline int topology_max_die_per_package(void) { return __max_die_per_package; diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index f8ba5289ecb0..38ca445a8429 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -113,6 +113,7 @@ #define VMX_MISC_PREEMPTION_TIMER_RATE_MASK 0x0000001f #define VMX_MISC_SAVE_EFER_LMA 0x00000020 #define VMX_MISC_ACTIVITY_HLT 0x00000040 +#define VMX_MISC_ACTIVITY_WAIT_SIPI 0x00000100 #define VMX_MISC_ZERO_LEN_INS 0x40000000 #define VMX_MISC_MSR_LIST_MULTIPLIER 512 diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 5941e18edd5a..1a162e559753 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h @@ -355,7 +355,7 @@ unsigned long arbitrary_virt_to_mfn(void *vaddr); void make_lowmem_page_readonly(void *vaddr); void make_lowmem_page_readwrite(void *vaddr); -#define xen_remap(cookie, size) ioremap((cookie), (size)); +#define xen_remap(cookie, size) ioremap((cookie), (size)) #define xen_unmap(cookie) iounmap((cookie)) static inline bool xen_arch_need_swiotlb(struct device *dev, diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h index 89e5f3d1bba8..8e76d3701db3 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -12,6 +12,7 @@ #define KVM_PIO_PAGE_OFFSET 1 #define KVM_COALESCED_MMIO_PAGE_OFFSET 2 +#define KVM_DIRTY_LOG_PAGE_OFFSET 64 #define DE_VECTOR 0 #define DB_VECTOR 1 diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h index f1d8307454e0..554f75fe013c 100644 --- a/arch/x86/include/uapi/asm/svm.h +++ b/arch/x86/include/uapi/asm/svm.h @@ -77,10 +77,28 @@ #define SVM_EXIT_MWAIT_COND 0x08c #define SVM_EXIT_XSETBV 0x08d #define SVM_EXIT_RDPRU 0x08e +#define SVM_EXIT_EFER_WRITE_TRAP 0x08f +#define SVM_EXIT_CR0_WRITE_TRAP 0x090 +#define SVM_EXIT_CR1_WRITE_TRAP 0x091 +#define SVM_EXIT_CR2_WRITE_TRAP 0x092 +#define SVM_EXIT_CR3_WRITE_TRAP 0x093 +#define SVM_EXIT_CR4_WRITE_TRAP 0x094 +#define SVM_EXIT_CR5_WRITE_TRAP 0x095 +#define SVM_EXIT_CR6_WRITE_TRAP 0x096 +#define SVM_EXIT_CR7_WRITE_TRAP 0x097 +#define SVM_EXIT_CR8_WRITE_TRAP 0x098 +#define SVM_EXIT_CR9_WRITE_TRAP 0x099 +#define SVM_EXIT_CR10_WRITE_TRAP 0x09a +#define SVM_EXIT_CR11_WRITE_TRAP 0x09b +#define SVM_EXIT_CR12_WRITE_TRAP 0x09c +#define SVM_EXIT_CR13_WRITE_TRAP 0x09d +#define SVM_EXIT_CR14_WRITE_TRAP 0x09e +#define SVM_EXIT_CR15_WRITE_TRAP 0x09f #define SVM_EXIT_INVPCID 0x0a2 #define SVM_EXIT_NPF 0x400 #define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401 #define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402 +#define SVM_EXIT_VMGEXIT 0x403 /* SEV-ES software-defined VMGEXIT events */ #define SVM_VMGEXIT_MMIO_READ 0x80000001 @@ -183,10 +201,20 @@ { SVM_EXIT_MONITOR, "monitor" }, \ { SVM_EXIT_MWAIT, "mwait" }, \ { SVM_EXIT_XSETBV, "xsetbv" }, \ + { SVM_EXIT_EFER_WRITE_TRAP, "write_efer_trap" }, \ + { SVM_EXIT_CR0_WRITE_TRAP, "write_cr0_trap" }, \ + { SVM_EXIT_CR4_WRITE_TRAP, "write_cr4_trap" }, \ + { SVM_EXIT_CR8_WRITE_TRAP, "write_cr8_trap" }, \ { SVM_EXIT_INVPCID, "invpcid" }, \ { SVM_EXIT_NPF, "npf" }, \ { SVM_EXIT_AVIC_INCOMPLETE_IPI, "avic_incomplete_ipi" }, \ { SVM_EXIT_AVIC_UNACCELERATED_ACCESS, "avic_unaccelerated_access" }, \ + { SVM_EXIT_VMGEXIT, "vmgexit" }, \ + { SVM_VMGEXIT_MMIO_READ, "vmgexit_mmio_read" }, \ + { SVM_VMGEXIT_MMIO_WRITE, "vmgexit_mmio_write" }, \ + { SVM_VMGEXIT_NMI_COMPLETE, "vmgexit_nmi_complete" }, \ + { SVM_VMGEXIT_AP_HLT_LOOP, "vmgexit_ap_hlt_loop" }, \ + { SVM_VMGEXIT_AP_JUMP_TABLE, "vmgexit_ap_jump_table" }, \ { SVM_EXIT_ERR, "invalid_guest_state" } diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h index b8ff9e8ac0d5..ada955c5ebb6 100644 --- a/arch/x86/include/uapi/asm/vmx.h +++ b/arch/x86/include/uapi/asm/vmx.h @@ -32,6 +32,7 @@ #define EXIT_REASON_EXTERNAL_INTERRUPT 1 #define EXIT_REASON_TRIPLE_FAULT 2 #define EXIT_REASON_INIT_SIGNAL 3 +#define EXIT_REASON_SIPI_SIGNAL 4 #define EXIT_REASON_INTERRUPT_WINDOW 7 #define EXIT_REASON_NMI_WINDOW 8 @@ -94,6 +95,7 @@ { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, \ { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, \ { EXIT_REASON_INIT_SIGNAL, "INIT_SIGNAL" }, \ + { EXIT_REASON_SIPI_SIGNAL, "SIPI_SIGNAL" }, \ { EXIT_REASON_INTERRUPT_WINDOW, "INTERRUPT_WINDOW" }, \ { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, \ { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, \ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 68608bd892c0..5eeb808eb024 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -161,5 +161,3 @@ ifeq ($(CONFIG_X86_64),y) obj-$(CONFIG_MMCONF_FAM10H) += mmconf-fam10h_64.o obj-y += vsmp_64.o endif - -obj-$(CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT) += ima_arch.o diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index c8daa92f38dc..5d3a0b8fd379 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S @@ -112,7 +112,7 @@ SYM_FUNC_START(do_suspend_lowlevel) movq pt_regs_r14(%rax), %r14 movq pt_regs_r15(%rax), %r15 -#ifdef CONFIG_KASAN +#if defined(CONFIG_KASAN) && CONFIG_KASAN_STACK /* * The suspend path may have poisoned some areas deeper in the stack, * which we now need to unpoison. diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index f8ca66f3d861..347a956f71ca 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -542,12 +542,12 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) u32 ecx; ecx = cpuid_ecx(0x8000001e); - nodes_per_socket = ((ecx >> 8) & 7) + 1; + __max_die_per_package = nodes_per_socket = ((ecx >> 8) & 7) + 1; } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) { u64 value; rdmsrl(MSR_FAM10H_NODE_ID, value); - nodes_per_socket = ((value >> 3) & 7) + 1; + __max_die_per_package = nodes_per_socket = ((value >> 3) & 7) + 1; } if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) && diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-deps.c index d502241995a3..42af31b64c2c 100644 --- a/arch/x86/kernel/cpu/cpuid-deps.c +++ b/arch/x86/kernel/cpu/cpuid-deps.c @@ -69,6 +69,7 @@ static const struct cpuid_dep cpuid_deps[] = { { X86_FEATURE_CQM_MBM_TOTAL, X86_FEATURE_CQM_LLC }, { X86_FEATURE_CQM_MBM_LOCAL, X86_FEATURE_CQM_LLC }, { X86_FEATURE_AVX512_BF16, X86_FEATURE_AVX512VL }, + { X86_FEATURE_AVX512_FP16, X86_FEATURE_AVX512BW }, { X86_FEATURE_ENQCMD, X86_FEATURE_XSAVES }, { X86_FEATURE_PER_THREAD_MBA, X86_FEATURE_MBA }, {} diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index 13d3f1cbda17..e133ce1e562b 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -1992,10 +1992,9 @@ static __always_inline void exc_machine_check_kernel(struct pt_regs *regs) * that out because it's an indirect call. Annotate it. */ instrumentation_begin(); - trace_hardirqs_off_finish(); + machine_check_vector(regs); - if (regs->flags & X86_EFLAGS_IF) - trace_hardirqs_on_prepare(); + instrumentation_end(); irqentry_nmi_exit(regs, irq_state); } @@ -2004,7 +2003,9 @@ static __always_inline void exc_machine_check_user(struct pt_regs *regs) { irqentry_enter_from_user_mode(regs); instrumentation_begin(); + machine_check_vector(regs); + instrumentation_end(); irqentry_exit_to_user_mode(regs); } diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index f628e3dc150f..43b54bef5448 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -135,14 +135,32 @@ static void hv_machine_shutdown(void) { if (kexec_in_progress && hv_kexec_handler) hv_kexec_handler(); + + /* + * Call hv_cpu_die() on all the CPUs, otherwise later the hypervisor + * corrupts the old VP Assist Pages and can crash the kexec kernel. + */ + if (kexec_in_progress && hyperv_init_cpuhp > 0) + cpuhp_remove_state(hyperv_init_cpuhp); + + /* The function calls stop_other_cpus(). */ native_machine_shutdown(); + + /* Disable the hypercall page when there is only 1 active CPU. */ + if (kexec_in_progress) + hyperv_cleanup(); } static void hv_machine_crash_shutdown(struct pt_regs *regs) { if (hv_crash_handler) hv_crash_handler(regs); + + /* The function calls crash_smp_send_stop(). */ native_machine_crash_shutdown(regs); + + /* Disable the hypercall page when there is only 1 active CPU. */ + hyperv_cleanup(); } #endif /* CONFIG_KEXEC_CORE */ #endif /* CONFIG_HYPERV */ diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 23ad8e953dfb..a29997e6cf9e 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -167,9 +167,6 @@ static u8 mtrr_type_lookup_variable(u64 start, u64 end, u64 *partial_end, *repeat = 0; *uniform = 1; - /* Make end inclusive instead of exclusive */ - end--; - prev_match = MTRR_TYPE_INVALID; for (i = 0; i < num_var_ranges; ++i) { unsigned short start_state, end_state, inclusive; @@ -261,6 +258,9 @@ u8 mtrr_type_lookup(u64 start, u64 end, u8 *uniform) int repeat; u64 partial_end; + /* Make end inclusive instead of exclusive */ + end--; + if (!mtrr_state_set) return MTRR_TYPE_INVALID; diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index 29ffb95b25ff..460f3e0df106 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -525,89 +525,70 @@ static void rdtgroup_remove(struct rdtgroup *rdtgrp) kfree(rdtgrp); } -struct task_move_callback { - struct callback_head work; - struct rdtgroup *rdtgrp; -}; - -static void move_myself(struct callback_head *head) +static void _update_task_closid_rmid(void *task) { - struct task_move_callback *callback; - struct rdtgroup *rdtgrp; - - callback = container_of(head, struct task_move_callback, work); - rdtgrp = callback->rdtgrp; - /* - * If resource group was deleted before this task work callback - * was invoked, then assign the task to root group and free the - * resource group. + * If the task is still current on this CPU, update PQR_ASSOC MSR. + * Otherwise, the MSR is updated when the task is scheduled in. */ - if (atomic_dec_and_test(&rdtgrp->waitcount) && - (rdtgrp->flags & RDT_DELETED)) { - current->closid = 0; - current->rmid = 0; - rdtgroup_remove(rdtgrp); - } - - if (unlikely(current->flags & PF_EXITING)) - goto out; - - preempt_disable(); - /* update PQR_ASSOC MSR to make resource group go into effect */ - resctrl_sched_in(); - preempt_enable(); + if (task == current) + resctrl_sched_in(); +} -out: - kfree(callback); +static void update_task_closid_rmid(struct task_struct *t) +{ + if (IS_ENABLED(CONFIG_SMP) && task_curr(t)) + smp_call_function_single(task_cpu(t), _update_task_closid_rmid, t, 1); + else + _update_task_closid_rmid(t); } static int __rdtgroup_move_task(struct task_struct *tsk, struct rdtgroup *rdtgrp) { - struct task_move_callback *callback; - int ret; - - callback = kzalloc(sizeof(*callback), GFP_KERNEL); - if (!callback) - return -ENOMEM; - callback->work.func = move_myself; - callback->rdtgrp = rdtgrp; + /* If the task is already in rdtgrp, no need to move the task. */ + if ((rdtgrp->type == RDTCTRL_GROUP && tsk->closid == rdtgrp->closid && + tsk->rmid == rdtgrp->mon.rmid) || + (rdtgrp->type == RDTMON_GROUP && tsk->rmid == rdtgrp->mon.rmid && + tsk->closid == rdtgrp->mon.parent->closid)) + return 0; /* - * Take a refcount, so rdtgrp cannot be freed before the - * callback has been invoked. + * Set the task's closid/rmid before the PQR_ASSOC MSR can be + * updated by them. + * + * For ctrl_mon groups, move both closid and rmid. + * For monitor groups, can move the tasks only from + * their parent CTRL group. */ - atomic_inc(&rdtgrp->waitcount); - ret = task_work_add(tsk, &callback->work, TWA_RESUME); - if (ret) { - /* - * Task is exiting. Drop the refcount and free the callback. - * No need to check the refcount as the group cannot be - * deleted before the write function unlocks rdtgroup_mutex. - */ - atomic_dec(&rdtgrp->waitcount); - kfree(callback); - rdt_last_cmd_puts("Task exited\n"); - } else { - /* - * For ctrl_mon groups move both closid and rmid. - * For monitor groups, can move the tasks only from - * their parent CTRL group. - */ - if (rdtgrp->type == RDTCTRL_GROUP) { - tsk->closid = rdtgrp->closid; + + if (rdtgrp->type == RDTCTRL_GROUP) { + tsk->closid = rdtgrp->closid; + tsk->rmid = rdtgrp->mon.rmid; + } else if (rdtgrp->type == RDTMON_GROUP) { + if (rdtgrp->mon.parent->closid == tsk->closid) { tsk->rmid = rdtgrp->mon.rmid; - } else if (rdtgrp->type == RDTMON_GROUP) { - if (rdtgrp->mon.parent->closid == tsk->closid) { - tsk->rmid = rdtgrp->mon.rmid; - } else { - rdt_last_cmd_puts("Can't move task to different control group\n"); - ret = -EINVAL; - } + } else { + rdt_last_cmd_puts("Can't move task to different control group\n"); + return -EINVAL; } } - return ret; + + /* + * Ensure the task's closid and rmid are written before determining if + * the task is current that will decide if it will be interrupted. + */ + barrier(); + + /* + * By now, the task's closid and rmid are set. If the task is current + * on a CPU, the PQR_ASSOC MSR needs to be updated to make the resource + * group go into effect. If the task is not current, the MSR will be + * updated when the task is scheduled in. + */ + update_task_closid_rmid(tsk); + + return 0; } static bool is_closid_match(struct task_struct *t, struct rdtgroup *r) diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index 866c9a9bcdee..236924930bf0 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c @@ -44,6 +44,7 @@ static const struct cpuid_bit cpuid_bits[] = { { X86_FEATURE_SEV, CPUID_EAX, 1, 0x8000001f, 0 }, { X86_FEATURE_SEV_ES, CPUID_EAX, 3, 0x8000001f, 0 }, { X86_FEATURE_SME_COHERENT, CPUID_EAX, 10, 0x8000001f, 0 }, + { X86_FEATURE_VM_PAGE_FLUSH, CPUID_EAX, 2, 0x8000001f, 0 }, { 0, 0, 0, 0, 0 } }; diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c index 1068002c8532..8678864ce712 100644 --- a/arch/x86/kernel/cpu/topology.c +++ b/arch/x86/kernel/cpu/topology.c @@ -25,10 +25,10 @@ #define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f) #define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff) -#ifdef CONFIG_SMP unsigned int __max_die_per_package __read_mostly = 1; EXPORT_SYMBOL(__max_die_per_package); +#ifdef CONFIG_SMP /* * Check if given CPUID extended toplogy "leaf" is implemented */ diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 924571fe5864..c6ede3b3d302 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c @@ -501,12 +501,12 @@ static bool vmware_sev_es_hcall_finish(struct ghcb *ghcb, struct pt_regs *regs) ghcb_rbp_is_valid(ghcb))) return false; - regs->bx = ghcb->save.rbx; - regs->cx = ghcb->save.rcx; - regs->dx = ghcb->save.rdx; - regs->si = ghcb->save.rsi; - regs->di = ghcb->save.rdi; - regs->bp = ghcb->save.rbp; + regs->bx = ghcb_get_rbx(ghcb); + regs->cx = ghcb_get_rcx(ghcb); + regs->dx = ghcb_get_rdx(ghcb); + regs->si = ghcb_get_rsi(ghcb); + regs->di = ghcb_get_rdi(ghcb); + regs->bp = ghcb_get_rbp(ghcb); return true; } diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index eb86a2b831b1..571220ac8bea 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -121,7 +121,7 @@ int copy_fpregs_to_fpstate(struct fpu *fpu) } EXPORT_SYMBOL(copy_fpregs_to_fpstate); -void kernel_fpu_begin(void) +void kernel_fpu_begin_mask(unsigned int kfpu_mask) { preempt_disable(); @@ -141,13 +141,14 @@ void kernel_fpu_begin(void) } __cpu_invalidate_fpregs_state(); - if (boot_cpu_has(X86_FEATURE_XMM)) + /* Put sane initial values into the control registers. */ + if (likely(kfpu_mask & KFPU_MXCSR) && boot_cpu_has(X86_FEATURE_XMM)) ldmxcsr(MXCSR_DEFAULT); - if (boot_cpu_has(X86_FEATURE_FPU)) + if (unlikely(kfpu_mask & KFPU_387) && boot_cpu_has(X86_FEATURE_FPU)) asm volatile ("fninit"); } -EXPORT_SYMBOL_GPL(kernel_fpu_begin); +EXPORT_SYMBOL_GPL(kernel_fpu_begin_mask); void kernel_fpu_end(void) { diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S index ac3d5f22fe64..0d54099c2a3a 100644 --- a/arch/x86/kernel/ftrace_64.S +++ b/arch/x86/kernel/ftrace_64.S @@ -140,16 +140,27 @@ SYM_FUNC_START(ftrace_caller) /* save_mcount_regs fills in first two parameters */ save_mcount_regs + /* Stack - skipping return address of ftrace_caller */ + leaq MCOUNT_REG_SIZE+8(%rsp), %rcx + movq %rcx, RSP(%rsp) + SYM_INNER_LABEL(ftrace_caller_op_ptr, SYM_L_GLOBAL) /* Load the ftrace_ops into the 3rd parameter */ movq function_trace_op(%rip), %rdx - /* regs go into 4th parameter (but make it NULL) */ - movq $0, %rcx + /* regs go into 4th parameter */ + leaq (%rsp), %rcx + + /* Only ops with REGS flag set should have CS register set */ + movq $0, CS(%rsp) SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL) call ftrace_stub + /* Handlers can change the RIP */ + movq RIP(%rsp), %rax + movq %rax, MCOUNT_REG_SIZE(%rsp) + restore_mcount_regs /* diff --git a/arch/x86/kernel/ima_arch.c b/arch/x86/kernel/ima_arch.c deleted file mode 100644 index 7dfb1e808928..000000000000 --- a/arch/x86/kernel/ima_arch.c +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (C) 2018 IBM Corporation - */ -#include <linux/efi.h> -#include <linux/module.h> -#include <linux/ima.h> - -extern struct boot_params boot_params; - -static enum efi_secureboot_mode get_sb_mode(void) -{ - efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID; - efi_status_t status; - unsigned long size; - u8 secboot, setupmode; - - size = sizeof(secboot); - - if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) { - pr_info("ima: secureboot mode unknown, no efi\n"); - return efi_secureboot_mode_unknown; - } - - /* Get variable contents into buffer */ - status = efi.get_variable(L"SecureBoot", &efi_variable_guid, - NULL, &size, &secboot); - if (status == EFI_NOT_FOUND) { - pr_info("ima: secureboot mode disabled\n"); - return efi_secureboot_mode_disabled; - } - - if (status != EFI_SUCCESS) { - pr_info("ima: secureboot mode unknown\n"); - return efi_secureboot_mode_unknown; - } - - size = sizeof(setupmode); - status = efi.get_variable(L"SetupMode", &efi_variable_guid, - NULL, &size, &setupmode); - - if (status != EFI_SUCCESS) /* ignore unknown SetupMode */ - setupmode = 0; - - if (secboot == 0 || setupmode == 1) { - pr_info("ima: secureboot mode disabled\n"); - return efi_secureboot_mode_disabled; - } - - pr_info("ima: secureboot mode enabled\n"); - return efi_secureboot_mode_enabled; -} - -bool arch_ima_get_secureboot(void) -{ - static enum efi_secureboot_mode sb_mode; - static bool initialized; - - if (!initialized && efi_enabled(EFI_BOOT)) { - sb_mode = boot_params.secure_boot; - - if (sb_mode == efi_secureboot_mode_unset) - sb_mode = get_sb_mode(); - initialized = true; - } - - if (sb_mode == efi_secureboot_mode_enabled) - return true; - else - return false; -} - -/* secureboot arch rules */ -static const char * const sb_arch_rules[] = { -#if !IS_ENABLED(CONFIG_KEXEC_SIG) - "appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig", -#endif /* CONFIG_KEXEC_SIG */ - "measure func=KEXEC_KERNEL_CHECK", -#if !IS_ENABLED(CONFIG_MODULE_SIG) - "appraise func=MODULE_CHECK appraise_type=imasig", -#endif - "measure func=MODULE_CHECK", - NULL -}; - -const char * const *arch_get_ima_policy(void) -{ - if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) && arch_ima_get_secureboot()) { - if (IS_ENABLED(CONFIG_MODULE_SIG)) - set_module_sig_enforced(); - return sb_arch_rules; - } - return NULL; -} diff --git a/arch/x86/kernel/kprobes/ftrace.c b/arch/x86/kernel/kprobes/ftrace.c index 681a4b36e9bb..373e5fa3ce1f 100644 --- a/arch/x86/kernel/kprobes/ftrace.c +++ b/arch/x86/kernel/kprobes/ftrace.c @@ -14,15 +14,21 @@ /* Ftrace callback handler for kprobes -- called under preepmt disabed */ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, - struct ftrace_ops *ops, struct pt_regs *regs) + struct ftrace_ops *ops, struct ftrace_regs *fregs) { + struct pt_regs *regs = ftrace_get_regs(fregs); struct kprobe *p; struct kprobe_ctlblk *kcb; + int bit; - /* Preempt is disabled by ftrace */ + bit = ftrace_test_recursion_trylock(ip, parent_ip); + if (bit < 0) + return; + + preempt_disable_notrace(); p = get_kprobe((kprobe_opcode_t *)ip); if (unlikely(!p) || kprobe_disabled(p)) - return; + goto out; kcb = get_kprobe_ctlblk(); if (kprobe_running()) { @@ -52,6 +58,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, */ __this_cpu_write(current_kprobe, NULL); } +out: + preempt_enable_notrace(); + ftrace_test_recursion_unlock(bit); } NOKPROBE_SYMBOL(kprobe_ftrace_handler); diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 34b18f6eeb2c..aa593743acf6 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -44,7 +44,6 @@ static int __init parse_no_kvmclock_vsyscall(char *arg) early_param("no-kvmclock-vsyscall", parse_no_kvmclock_vsyscall); /* Aligned to page sizes to match whats mapped via vsyscalls to userspace */ -#define HV_CLOCK_SIZE (sizeof(struct pvclock_vsyscall_time_info) * NR_CPUS) #define HVC_BOOT_ARRAY_SIZE \ (PAGE_SIZE / sizeof(struct pvclock_vsyscall_time_info)) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 740f3bdb3f61..3412c4595efd 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -661,17 +661,6 @@ static void __init trim_platform_memory_ranges(void) static void __init trim_bios_range(void) { /* - * A special case is the first 4Kb of memory; - * This is a BIOS owned area, not kernel ram, but generally - * not listed as such in the E820 table. - * - * This typically reserves additional memory (64KiB by default) - * since some BIOSes are known to corrupt low memory. See the - * Kconfig help text for X86_RESERVE_LOW. - */ - e820__range_update(0, PAGE_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED); - - /* * special case: Some BIOSes report the PC BIOS * area (640Kb -> 1Mb) as RAM even though it is not. * take them out. @@ -728,6 +717,15 @@ early_param("reservelow", parse_reservelow); static void __init trim_low_memory_range(void) { + /* + * A special case is the first 4Kb of memory; + * This is a BIOS owned area, not kernel ram, but generally + * not listed as such in the E820 table. + * + * This typically reserves additional memory (64KiB by default) + * since some BIOSes are known to corrupt low memory. See the + * Kconfig help text for X86_RESERVE_LOW. + */ memblock_reserve(0, ALIGN(reserve_low, PAGE_SIZE)); } diff --git a/arch/x86/kernel/sev-es-shared.c b/arch/x86/kernel/sev-es-shared.c index 7d04b356d44d..cdc04d091242 100644 --- a/arch/x86/kernel/sev-es-shared.c +++ b/arch/x86/kernel/sev-es-shared.c @@ -305,14 +305,14 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) case 0xe4: case 0xe5: *exitinfo |= IOIO_TYPE_IN; - *exitinfo |= (u64)insn->immediate.value << 16; + *exitinfo |= (u8)insn->immediate.value << 16; break; /* OUT immediate opcodes */ case 0xe6: case 0xe7: *exitinfo |= IOIO_TYPE_OUT; - *exitinfo |= (u64)insn->immediate.value << 16; + *exitinfo |= (u8)insn->immediate.value << 16; break; /* IN register opcodes */ diff --git a/arch/x86/kernel/sev-es.c b/arch/x86/kernel/sev-es.c index 0bd1a0fc587e..84c1821819af 100644 --- a/arch/x86/kernel/sev-es.c +++ b/arch/x86/kernel/sev-es.c @@ -225,7 +225,7 @@ static inline u64 sev_es_rd_ghcb_msr(void) return __rdmsr(MSR_AMD64_SEV_ES_GHCB); } -static inline void sev_es_wr_ghcb_msr(u64 val) +static __always_inline void sev_es_wr_ghcb_msr(u64 val) { u32 low, high; @@ -286,6 +286,12 @@ static enum es_result vc_write_mem(struct es_em_ctxt *ctxt, u16 d2; u8 d1; + /* If instruction ran in kernel mode and the I/O buffer is in kernel space */ + if (!user_mode(ctxt->regs) && !access_ok(target, size)) { + memcpy(dst, buf, size); + return ES_OK; + } + switch (size) { case 1: memcpy(&d1, buf, 1); @@ -335,6 +341,12 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt, u16 d2; u8 d1; + /* If instruction ran in kernel mode and the I/O buffer is in kernel space */ + if (!user_mode(ctxt->regs) && !access_ok(s, size)) { + memcpy(buf, src, size); + return ES_OK; + } + switch (size) { case 1: if (get_user(d1, s)) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 8ca66af96a54..117e24fbfd8a 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -56,6 +56,7 @@ #include <linux/numa.h> #include <linux/pgtable.h> #include <linux/overflow.h> +#include <linux/syscore_ops.h> #include <asm/acpi.h> #include <asm/desc.h> @@ -2083,6 +2084,23 @@ static void init_counter_refs(void) this_cpu_write(arch_prev_mperf, mperf); } +#ifdef CONFIG_PM_SLEEP +static struct syscore_ops freq_invariance_syscore_ops = { + .resume = init_counter_refs, +}; + +static void register_freq_invariance_syscore_ops(void) +{ + /* Bail out if registered already. */ + if (freq_invariance_syscore_ops.node.prev) + return; + + register_syscore_ops(&freq_invariance_syscore_ops); +} +#else +static inline void register_freq_invariance_syscore_ops(void) {} +#endif + static void init_freq_invariance(bool secondary, bool cppc_ready) { bool ret = false; @@ -2109,6 +2127,7 @@ static void init_freq_invariance(bool secondary, bool cppc_ready) if (ret) { init_counter_refs(); static_branch_enable(&arch_scale_freq_key); + register_freq_invariance_syscore_ops(); pr_info("Estimated ratio of average max frequency by base frequency (times 1024): %llu\n", arch_max_freq_ratio); } else { pr_debug("Couldn't determine max cpu frequency, necessary for scale-invariant accounting.\n"); diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c index 0a2ec801b63f..f5477eab5692 100644 --- a/arch/x86/kernel/topology.c +++ b/arch/x86/kernel/topology.c @@ -25,6 +25,7 @@ * * Send feedback to <colpatch@us.ibm.com> */ +#include <linux/interrupt.h> #include <linux/nodemask.h> #include <linux/export.h> #include <linux/mmzone.h> diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index fb55981f2a0d..7f5aec758f0e 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -303,11 +303,12 @@ DEFINE_IDTENTRY_ERRORCODE(exc_alignment_check) local_irq_enable(); if (handle_user_split_lock(regs, error_code)) - return; + goto out; do_trap(X86_TRAP_AC, SIGBUS, "alignment check", regs, error_code, BUS_ADRALN, NULL); +out: local_irq_disable(); } diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index f92dfd8ef10d..7ac592664c52 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -100,7 +100,8 @@ config KVM_AMD_SEV depends on KVM_AMD && X86_64 depends on CRYPTO_DEV_SP_PSP && !(KVM_AMD=y && CRYPTO_DEV_CCP_DD=m) help - Provides support for launching Encrypted VMs on AMD processors. + Provides support for launching Encrypted VMs (SEV) and Encrypted VMs + with Encrypted State (SEV-ES) on AMD processors. config KVM_MMU_AUDIT bool "Audit KVM MMU" diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index b804444e16d4..4bd14ab01323 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -10,7 +10,8 @@ endif KVM := ../../../virt/kvm kvm-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ - $(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o + $(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o \ + $(KVM)/dirty_ring.o kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o kvm-y += x86.o emulate.o i8259.o irq.o lapic.o \ diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 83637a2ff605..13036cf0b912 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -146,6 +146,7 @@ void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu) MSR_IA32_MISC_ENABLE_MWAIT); } } +EXPORT_SYMBOL_GPL(kvm_update_cpuid_runtime); static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) { @@ -418,7 +419,7 @@ void kvm_set_cpu_caps(void) F(AVX512_4VNNIW) | F(AVX512_4FMAPS) | F(SPEC_CTRL) | F(SPEC_CTRL_SSBD) | F(ARCH_CAPABILITIES) | F(INTEL_STIBP) | F(MD_CLEAR) | F(AVX512_VP2INTERSECT) | F(FSRM) | - F(SERIALIZE) | F(TSXLDTRK) + F(SERIALIZE) | F(TSXLDTRK) | F(AVX512_FP16) ); /* TSC_ADJUST and ARCH_CAPABILITIES are emulated in software. */ diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index f7a6e8f83783..dc921d76e42e 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -264,6 +264,20 @@ static inline int guest_cpuid_stepping(struct kvm_vcpu *vcpu) return x86_stepping(best->eax); } +static inline bool guest_has_spec_ctrl_msr(struct kvm_vcpu *vcpu) +{ + return (guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL) || + guest_cpuid_has(vcpu, X86_FEATURE_AMD_STIBP) || + guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBRS) || + guest_cpuid_has(vcpu, X86_FEATURE_AMD_SSBD)); +} + +static inline bool guest_has_pred_cmd_msr(struct kvm_vcpu *vcpu) +{ + return (guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL) || + guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBPB)); +} + static inline bool supports_cpuid_fault(struct kvm_vcpu *vcpu) { return vcpu->arch.msr_platform_info & MSR_PLATFORM_INFO_CPUID_FAULT; diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 5c7c4060b45c..922c69dcca4d 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -1951,8 +1951,8 @@ int kvm_vm_ioctl_hv_eventfd(struct kvm *kvm, struct kvm_hyperv_eventfd *args) return kvm_hv_eventfd_assign(kvm, args->conn_id, args->fd); } -int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, - struct kvm_cpuid_entry2 __user *entries) +int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, + struct kvm_cpuid_entry2 __user *entries) { uint16_t evmcs_ver = 0; struct kvm_cpuid_entry2 cpuid_entries[] = { @@ -2037,7 +2037,7 @@ int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, * Direct Synthetic timers only make sense with in-kernel * LAPIC */ - if (lapic_in_kernel(vcpu)) + if (!vcpu || lapic_in_kernel(vcpu)) ent->edx |= HV_STIMER_DIRECT_MODE_AVAILABLE; break; diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h index e68c6c2e9649..6d7def2b0aad 100644 --- a/arch/x86/kvm/hyperv.h +++ b/arch/x86/kvm/hyperv.h @@ -126,7 +126,7 @@ void kvm_hv_setup_tsc_page(struct kvm *kvm, void kvm_hv_init_vm(struct kvm *kvm); void kvm_hv_destroy_vm(struct kvm *kvm); int kvm_vm_ioctl_hv_eventfd(struct kvm *kvm, struct kvm_hyperv_eventfd *args); -int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, - struct kvm_cpuid_entry2 __user *entries); +int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, + struct kvm_cpuid_entry2 __user *entries); #endif diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 86c33d53c90a..43cceadd073e 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -674,7 +674,7 @@ static bool pv_eoi_get_pending(struct kvm_vcpu *vcpu) (unsigned long long)vcpu->arch.pv_eoi.msr_val); return false; } - return val & 0x1; + return val & KVM_PV_EOI_ENABLED; } static void pv_eoi_set_pending(struct kvm_vcpu *vcpu) @@ -2843,14 +2843,35 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu) { struct kvm_lapic *apic = vcpu->arch.apic; u8 sipi_vector; + int r; unsigned long pe; - if (!lapic_in_kernel(vcpu) || !apic->pending_events) + if (!lapic_in_kernel(vcpu)) return; /* + * Read pending events before calling the check_events + * callback. + */ + pe = smp_load_acquire(&apic->pending_events); + if (!pe) + return; + + if (is_guest_mode(vcpu)) { + r = kvm_x86_ops.nested_ops->check_events(vcpu); + if (r < 0) + return; + /* + * If an event has happened and caused a vmexit, + * we know INITs are latched and therefore + * we will not incorrectly deliver an APIC + * event instead of a vmexit. + */ + } + + /* * INITs are latched while CPU is in specific states - * (SMM, VMX non-root mode, SVM with GIF=0). + * (SMM, VMX root mode, SVM with GIF=0). * Because a CPU cannot be in these states immediately * after it has processed an INIT signal (and thus in * KVM_MP_STATE_INIT_RECEIVED state), just eat SIPIs @@ -2858,26 +2879,28 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu) */ if (kvm_vcpu_latch_init(vcpu)) { WARN_ON_ONCE(vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED); - if (test_bit(KVM_APIC_SIPI, &apic->pending_events)) + if (test_bit(KVM_APIC_SIPI, &pe)) clear_bit(KVM_APIC_SIPI, &apic->pending_events); return; } - pe = xchg(&apic->pending_events, 0); if (test_bit(KVM_APIC_INIT, &pe)) { + clear_bit(KVM_APIC_INIT, &apic->pending_events); kvm_vcpu_reset(vcpu, true); if (kvm_vcpu_is_bsp(apic->vcpu)) vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; else vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED; } - if (test_bit(KVM_APIC_SIPI, &pe) && - vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) { - /* evaluate pending_events before reading the vector */ - smp_rmb(); - sipi_vector = apic->sipi_vector; - kvm_vcpu_deliver_sipi_vector(vcpu, sipi_vector); - vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; + if (test_bit(KVM_APIC_SIPI, &pe)) { + clear_bit(KVM_APIC_SIPI, &apic->pending_events); + if (vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) { + /* evaluate pending_events before reading the vector */ + smp_rmb(); + sipi_vector = apic->sipi_vector; + kvm_x86_ops.vcpu_deliver_sipi_vector(vcpu, sipi_vector); + vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; + } } } diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 9c4a9c8e43d9..261be1d2032b 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -44,12 +44,19 @@ #define PT32_ROOT_LEVEL 2 #define PT32E_ROOT_LEVEL 3 -static inline u64 rsvd_bits(int s, int e) +static __always_inline u64 rsvd_bits(int s, int e) { + BUILD_BUG_ON(__builtin_constant_p(e) && __builtin_constant_p(s) && e < s); + + if (__builtin_constant_p(e)) + BUILD_BUG_ON(e > 63); + else + e &= 63; + if (e < s) return 0; - return ((1ULL << (e - s + 1)) - 1) << s; + return ((2ULL << (e - s)) - 1) << s; } void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 access_mask); diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 7a6ae9e90bd7..6d16481aa29d 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -820,7 +820,7 @@ gfn_to_memslot_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t gfn, slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn); if (!slot || slot->flags & KVM_MEMSLOT_INVALID) return NULL; - if (no_dirty_log && slot->dirty_bitmap) + if (no_dirty_log && kvm_slot_dirty_track_enabled(slot)) return NULL; return slot; @@ -1289,6 +1289,14 @@ void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm, kvm_mmu_write_protect_pt_masked(kvm, slot, gfn_offset, mask); } +int kvm_cpu_dirty_log_size(void) +{ + if (kvm_x86_ops.cpu_dirty_log_size) + return kvm_x86_ops.cpu_dirty_log_size(); + + return 0; +} + bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm, struct kvm_memory_slot *slot, u64 gfn) { @@ -3485,26 +3493,25 @@ static bool mmio_info_in_cache(struct kvm_vcpu *vcpu, u64 addr, bool direct) * Return the level of the lowest level SPTE added to sptes. * That SPTE may be non-present. */ -static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes) +static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, int *root_level) { struct kvm_shadow_walk_iterator iterator; - int leaf = vcpu->arch.mmu->root_level; + int leaf = -1; u64 spte; - walk_shadow_page_lockless_begin(vcpu); - for (shadow_walk_init(&iterator, vcpu, addr); + for (shadow_walk_init(&iterator, vcpu, addr), + *root_level = iterator.level; shadow_walk_okay(&iterator); __shadow_walk_next(&iterator, spte)) { leaf = iterator.level; spte = mmu_spte_get_lockless(iterator.sptep); - sptes[leaf - 1] = spte; + sptes[leaf] = spte; if (!is_shadow_present_pte(spte)) break; - } walk_shadow_page_lockless_end(vcpu); @@ -3512,14 +3519,12 @@ static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes) return leaf; } -/* return true if reserved bit is detected on spte. */ +/* return true if reserved bit(s) are detected on a valid, non-MMIO SPTE. */ static bool get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep) { - u64 sptes[PT64_ROOT_MAX_LEVEL]; + u64 sptes[PT64_ROOT_MAX_LEVEL + 1]; struct rsvd_bits_validate *rsvd_check; - int root = vcpu->arch.mmu->shadow_root_level; - int leaf; - int level; + int root, leaf, level; bool reserved = false; if (!VALID_PAGE(vcpu->arch.mmu->root_hpa)) { @@ -3528,35 +3533,45 @@ static bool get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep) } if (is_tdp_mmu_root(vcpu->kvm, vcpu->arch.mmu->root_hpa)) - leaf = kvm_tdp_mmu_get_walk(vcpu, addr, sptes); + leaf = kvm_tdp_mmu_get_walk(vcpu, addr, sptes, &root); else - leaf = get_walk(vcpu, addr, sptes); + leaf = get_walk(vcpu, addr, sptes, &root); + + if (unlikely(leaf < 0)) { + *sptep = 0ull; + return reserved; + } + + *sptep = sptes[leaf]; + + /* + * Skip reserved bits checks on the terminal leaf if it's not a valid + * SPTE. Note, this also (intentionally) skips MMIO SPTEs, which, by + * design, always have reserved bits set. The purpose of the checks is + * to detect reserved bits on non-MMIO SPTEs. i.e. buggy SPTEs. + */ + if (!is_shadow_present_pte(sptes[leaf])) + leaf++; rsvd_check = &vcpu->arch.mmu->shadow_zero_check; - for (level = root; level >= leaf; level--) { - if (!is_shadow_present_pte(sptes[level - 1])) - break; + for (level = root; level >= leaf; level--) /* * Use a bitwise-OR instead of a logical-OR to aggregate the * reserved bit and EPT's invalid memtype/XWR checks to avoid * adding a Jcc in the loop. */ - reserved |= __is_bad_mt_xwr(rsvd_check, sptes[level - 1]) | - __is_rsvd_bits_set(rsvd_check, sptes[level - 1], - level); - } + reserved |= __is_bad_mt_xwr(rsvd_check, sptes[level]) | + __is_rsvd_bits_set(rsvd_check, sptes[level], level); if (reserved) { pr_err("%s: detect reserved bits on spte, addr 0x%llx, dump hierarchy:\n", __func__, addr); for (level = root; level >= leaf; level--) pr_err("------ spte 0x%llx level %d.\n", - sptes[level - 1], level); + sptes[level], level); } - *sptep = sptes[leaf - 1]; - return reserved; } diff --git a/arch/x86/kvm/mmu/mmutrace.h b/arch/x86/kvm/mmu/mmutrace.h index 213699b27b44..e798489b56b5 100644 --- a/arch/x86/kvm/mmu/mmutrace.h +++ b/arch/x86/kvm/mmu/mmutrace.h @@ -381,6 +381,35 @@ TRACE_EVENT( ) ); +TRACE_EVENT( + kvm_tdp_mmu_spte_changed, + TP_PROTO(int as_id, gfn_t gfn, int level, u64 old_spte, u64 new_spte), + TP_ARGS(as_id, gfn, level, old_spte, new_spte), + + TP_STRUCT__entry( + __field(u64, gfn) + __field(u64, old_spte) + __field(u64, new_spte) + /* Level cannot be larger than 5 on x86, so it fits in a u8. */ + __field(u8, level) + /* as_id can only be 0 or 1 x86, so it fits in a u8. */ + __field(u8, as_id) + ), + + TP_fast_assign( + __entry->gfn = gfn; + __entry->old_spte = old_spte; + __entry->new_spte = new_spte; + __entry->level = level; + __entry->as_id = as_id; + ), + + TP_printk("as id %d gfn %llx level %d old_spte %llx new_spte %llx", + __entry->as_id, __entry->gfn, __entry->level, + __entry->old_spte, __entry->new_spte + ) +); + #endif /* _TRACE_KVMMMU_H */ #undef TRACE_INCLUDE_PATH diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index 84c8f06bec26..2ef8615f9dba 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -7,6 +7,8 @@ #include "tdp_mmu.h" #include "spte.h" +#include <trace/events/kvm.h> + #ifdef CONFIG_X86_64 static bool __read_mostly tdp_mmu_enabled = false; module_param_named(tdp_mmu, tdp_mmu_enabled, bool, 0644); @@ -42,7 +44,48 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm) WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); } -#define for_each_tdp_mmu_root(_kvm, _root) \ +static void tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root) +{ + if (kvm_mmu_put_root(kvm, root)) + kvm_tdp_mmu_free_root(kvm, root); +} + +static inline bool tdp_mmu_next_root_valid(struct kvm *kvm, + struct kvm_mmu_page *root) +{ + lockdep_assert_held(&kvm->mmu_lock); + + if (list_entry_is_head(root, &kvm->arch.tdp_mmu_roots, link)) + return false; + + kvm_mmu_get_root(kvm, root); + return true; + +} + +static inline struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm, + struct kvm_mmu_page *root) +{ + struct kvm_mmu_page *next_root; + + next_root = list_next_entry(root, link); + tdp_mmu_put_root(kvm, root); + return next_root; +} + +/* + * Note: this iterator gets and puts references to the roots it iterates over. + * This makes it safe to release the MMU lock and yield within the loop, but + * if exiting the loop early, the caller must drop the reference to the most + * recent root. (Unless keeping a live reference is desirable.) + */ +#define for_each_tdp_mmu_root_yield_safe(_kvm, _root) \ + for (_root = list_first_entry(&_kvm->arch.tdp_mmu_roots, \ + typeof(*_root), link); \ + tdp_mmu_next_root_valid(_kvm, _root); \ + _root = tdp_mmu_next_root(_kvm, _root)) + +#define for_each_tdp_mmu_root(_kvm, _root) \ list_for_each_entry(_root, &_kvm->arch.tdp_mmu_roots, link) bool is_tdp_mmu_root(struct kvm *kvm, hpa_t hpa) @@ -108,6 +151,8 @@ static struct kvm_mmu_page *alloc_tdp_mmu_page(struct kvm_vcpu *vcpu, gfn_t gfn, sp->gfn = gfn; sp->tdp_mmu_page = true; + trace_kvm_mmu_get_page(sp, true); + return sp; } @@ -185,7 +230,7 @@ static void handle_changed_spte_dirty_log(struct kvm *kvm, int as_id, gfn_t gfn, if ((!is_writable_pte(old_spte) || pfn_changed) && is_writable_pte(new_spte)) { slot = __gfn_to_memslot(__kvm_memslots(kvm, as_id), gfn); - mark_page_dirty_in_slot(slot, gfn); + mark_page_dirty_in_slot(kvm, slot, gfn); } } @@ -244,6 +289,8 @@ static void __handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn, if (old_spte == new_spte) return; + trace_kvm_tdp_mmu_spte_changed(as_id, gfn, level, old_spte, new_spte); + /* * The only times a SPTE should be changed from a non-present to * non-present state is when an MMIO entry is installed/modified/ @@ -278,6 +325,8 @@ static void __handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn, pt = spte_to_child_pt(old_spte, level); sp = sptep_to_sp(pt); + trace_kvm_mmu_prepare_zap_page(sp); + list_del(&sp->link); if (sp->lpage_disallowed) @@ -439,18 +488,9 @@ bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, gfn_t end) struct kvm_mmu_page *root; bool flush = false; - for_each_tdp_mmu_root(kvm, root) { - /* - * Take a reference on the root so that it cannot be freed if - * this thread releases the MMU lock and yields in this loop. - */ - kvm_mmu_get_root(kvm, root); - + for_each_tdp_mmu_root_yield_safe(kvm, root) flush |= zap_gfn_range(kvm, root, start, end, true); - kvm_mmu_put_root(kvm, root); - } - return flush; } @@ -480,11 +520,13 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu, int write, if (unlikely(is_noslot_pfn(pfn))) { new_spte = make_mmio_spte(vcpu, iter->gfn, ACC_ALL); trace_mark_mmio_spte(iter->sptep, iter->gfn, new_spte); - } else + } else { make_spte_ret = make_spte(vcpu, ACC_ALL, iter->level, iter->gfn, pfn, iter->old_spte, prefault, true, map_writable, !shadow_accessed_mask, &new_spte); + trace_kvm_mmu_set_spte(iter->level, iter->gfn, iter->sptep); + } if (new_spte == iter->old_spte) ret = RET_PF_SPURIOUS; @@ -609,13 +651,7 @@ static int kvm_tdp_mmu_handle_hva_range(struct kvm *kvm, unsigned long start, int ret = 0; int as_id; - for_each_tdp_mmu_root(kvm, root) { - /* - * Take a reference on the root so that it cannot be freed if - * this thread releases the MMU lock and yields in this loop. - */ - kvm_mmu_get_root(kvm, root); - + for_each_tdp_mmu_root_yield_safe(kvm, root) { as_id = kvm_mmu_page_as_id(root); slots = __kvm_memslots(kvm, as_id); kvm_for_each_memslot(memslot, slots) { @@ -637,8 +673,6 @@ static int kvm_tdp_mmu_handle_hva_range(struct kvm *kvm, unsigned long start, ret |= handler(kvm, memslot, root, gfn_start, gfn_end, data); } - - kvm_mmu_put_root(kvm, root); } return ret; @@ -698,6 +732,8 @@ static int age_gfn_range(struct kvm *kvm, struct kvm_memory_slot *slot, tdp_mmu_set_spte_no_acc_track(kvm, &iter, new_spte); young = 1; + + trace_kvm_age_page(iter.gfn, iter.level, slot, young); } return young; @@ -826,21 +862,13 @@ bool kvm_tdp_mmu_wrprot_slot(struct kvm *kvm, struct kvm_memory_slot *slot, int root_as_id; bool spte_set = false; - for_each_tdp_mmu_root(kvm, root) { + for_each_tdp_mmu_root_yield_safe(kvm, root) { root_as_id = kvm_mmu_page_as_id(root); if (root_as_id != slot->as_id) continue; - /* - * Take a reference on the root so that it cannot be freed if - * this thread releases the MMU lock and yields in this loop. - */ - kvm_mmu_get_root(kvm, root); - spte_set |= wrprot_gfn_range(kvm, root, slot->base_gfn, slot->base_gfn + slot->npages, min_level); - - kvm_mmu_put_root(kvm, root); } return spte_set; @@ -894,21 +922,13 @@ bool kvm_tdp_mmu_clear_dirty_slot(struct kvm *kvm, struct kvm_memory_slot *slot) int root_as_id; bool spte_set = false; - for_each_tdp_mmu_root(kvm, root) { + for_each_tdp_mmu_root_yield_safe(kvm, root) { root_as_id = kvm_mmu_page_as_id(root); if (root_as_id != slot->as_id) continue; - /* - * Take a reference on the root so that it cannot be freed if - * this thread releases the MMU lock and yields in this loop. - */ - kvm_mmu_get_root(kvm, root); - spte_set |= clear_dirty_gfn_range(kvm, root, slot->base_gfn, slot->base_gfn + slot->npages); - - kvm_mmu_put_root(kvm, root); } return spte_set; @@ -1017,21 +1037,13 @@ bool kvm_tdp_mmu_slot_set_dirty(struct kvm *kvm, struct kvm_memory_slot *slot) int root_as_id; bool spte_set = false; - for_each_tdp_mmu_root(kvm, root) { + for_each_tdp_mmu_root_yield_safe(kvm, root) { root_as_id = kvm_mmu_page_as_id(root); if (root_as_id != slot->as_id) continue; - /* - * Take a reference on the root so that it cannot be freed if - * this thread releases the MMU lock and yields in this loop. - */ - kvm_mmu_get_root(kvm, root); - spte_set |= set_dirty_gfn_range(kvm, root, slot->base_gfn, slot->base_gfn + slot->npages); - - kvm_mmu_put_root(kvm, root); } return spte_set; } @@ -1077,21 +1089,13 @@ void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, struct kvm_mmu_page *root; int root_as_id; - for_each_tdp_mmu_root(kvm, root) { + for_each_tdp_mmu_root_yield_safe(kvm, root) { root_as_id = kvm_mmu_page_as_id(root); if (root_as_id != slot->as_id) continue; - /* - * Take a reference on the root so that it cannot be freed if - * this thread releases the MMU lock and yields in this loop. - */ - kvm_mmu_get_root(kvm, root); - zap_collapsible_spte_range(kvm, root, slot->base_gfn, slot->base_gfn + slot->npages); - - kvm_mmu_put_root(kvm, root); } } @@ -1148,16 +1152,19 @@ bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, * Return the level of the lowest level SPTE added to sptes. * That SPTE may be non-present. */ -int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes) +int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, + int *root_level) { struct tdp_iter iter; struct kvm_mmu *mmu = vcpu->arch.mmu; - int leaf = vcpu->arch.mmu->shadow_root_level; gfn_t gfn = addr >> PAGE_SHIFT; + int leaf = -1; + + *root_level = vcpu->arch.mmu->shadow_root_level; tdp_mmu_for_each_pte(iter, mmu, gfn, gfn + 1) { leaf = iter.level; - sptes[leaf - 1] = iter.old_spte; + sptes[leaf] = iter.old_spte; } return leaf; diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h index 556e065503f6..cbbdbadd1526 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.h +++ b/arch/x86/kvm/mmu/tdp_mmu.h @@ -44,5 +44,7 @@ void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, struct kvm_memory_slot *slot, gfn_t gfn); -int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes); +int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, + int *root_level); + #endif /* __KVM_X86_MMU_TDP_MMU_H */ diff --git a/arch/x86/kvm/mtrr.c b/arch/x86/kvm/mtrr.c index 7f0059aa30e1..f472fdb6ae7e 100644 --- a/arch/x86/kvm/mtrr.c +++ b/arch/x86/kvm/mtrr.c @@ -84,12 +84,8 @@ bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data) } else /* MTRR mask */ mask |= 0x7ff; - if (data & mask) { - kvm_inject_gp(vcpu, 0); - return false; - } - return true; + return (data & mask) == 0; } EXPORT_SYMBOL_GPL(kvm_mtrr_valid); diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c index 8c550999ace0..0ef84d57b72e 100644 --- a/arch/x86/kvm/svm/avic.c +++ b/arch/x86/kvm/svm/avic.c @@ -233,7 +233,8 @@ static u64 *avic_get_physical_id_entry(struct kvm_vcpu *vcpu, */ static int avic_update_access_page(struct kvm *kvm, bool activate) { - int ret = 0; + void __user *ret; + int r = 0; mutex_lock(&kvm->slots_lock); /* @@ -249,13 +250,15 @@ static int avic_update_access_page(struct kvm *kvm, bool activate) APIC_ACCESS_PAGE_PRIVATE_MEMSLOT, APIC_DEFAULT_PHYS_BASE, activate ? PAGE_SIZE : 0); - if (ret) + if (IS_ERR(ret)) { + r = PTR_ERR(ret); goto out; + } kvm->arch.apic_access_page_done = activate; out: mutex_unlock(&kvm->slots_lock); - return ret; + return r; } static int avic_init_backing_page(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 9e4c226dbf7d..7a605ad8254d 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -199,6 +199,10 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); + + if (WARN_ON(!is_guest_mode(vcpu))) + return true; + if (!nested_svm_vmrun_msrpm(svm)) { vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; vcpu->run->internal.suberror = @@ -254,7 +258,7 @@ static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12) (vmcb12->save.cr3 & MSR_CR3_LONG_MBZ_MASK)) return false; } - if (kvm_valid_cr4(&svm->vcpu, vmcb12->save.cr4)) + if (!kvm_is_valid_cr4(&svm->vcpu, vmcb12->save.cr4)) return false; return nested_vmcb_check_controls(&vmcb12->control); @@ -381,7 +385,7 @@ static void nested_prepare_vmcb_save(struct vcpu_svm *svm, struct vmcb *vmcb12) svm->vmcb->save.ds = vmcb12->save.ds; svm->vmcb->save.gdtr = vmcb12->save.gdtr; svm->vmcb->save.idtr = vmcb12->save.idtr; - kvm_set_rflags(&svm->vcpu, vmcb12->save.rflags); + kvm_set_rflags(&svm->vcpu, vmcb12->save.rflags | X86_EFLAGS_FIXED); svm_set_efer(&svm->vcpu, vmcb12->save.efer); svm_set_cr0(&svm->vcpu, vmcb12->save.cr0); svm_set_cr4(&svm->vcpu, vmcb12->save.cr4); @@ -394,8 +398,8 @@ static void nested_prepare_vmcb_save(struct vcpu_svm *svm, struct vmcb *vmcb12) svm->vmcb->save.rax = vmcb12->save.rax; svm->vmcb->save.rsp = vmcb12->save.rsp; svm->vmcb->save.rip = vmcb12->save.rip; - svm->vmcb->save.dr7 = vmcb12->save.dr7; - svm->vcpu.arch.dr6 = vmcb12->save.dr6; + svm->vmcb->save.dr7 = vmcb12->save.dr7 | DR7_FIXED_1; + svm->vcpu.arch.dr6 = vmcb12->save.dr6 | DR6_FIXED_1 | DR6_RTM; svm->vmcb->save.cpl = vmcb12->save.cpl; } @@ -595,6 +599,8 @@ int nested_svm_vmexit(struct vcpu_svm *svm) svm->nested.vmcb12_gpa = 0; WARN_ON_ONCE(svm->nested.nested_run_pending); + kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, &svm->vcpu); + /* in case we halted in L2 */ svm->vcpu.arch.mp_state = KVM_MP_STATE_RUNNABLE; @@ -660,13 +666,14 @@ int nested_svm_vmexit(struct vcpu_svm *svm) svm->vmcb->save.gdtr = hsave->save.gdtr; svm->vmcb->save.idtr = hsave->save.idtr; kvm_set_rflags(&svm->vcpu, hsave->save.rflags); + kvm_set_rflags(&svm->vcpu, hsave->save.rflags | X86_EFLAGS_FIXED); svm_set_efer(&svm->vcpu, hsave->save.efer); svm_set_cr0(&svm->vcpu, hsave->save.cr0 | X86_CR0_PE); svm_set_cr4(&svm->vcpu, hsave->save.cr4); kvm_rax_write(&svm->vcpu, hsave->save.rax); kvm_rsp_write(&svm->vcpu, hsave->save.rsp); kvm_rip_write(&svm->vcpu, hsave->save.rip); - svm->vmcb->save.dr7 = 0; + svm->vmcb->save.dr7 = DR7_FIXED_1; svm->vmcb->save.cpl = 0; svm->vmcb->control.exit_int_info = 0; @@ -753,6 +760,7 @@ void svm_leave_nested(struct vcpu_svm *svm) leave_guest_mode(&svm->vcpu); copy_vmcb_control_area(&vmcb->control, &hsave->control); nested_svm_uninit_mmu_context(&svm->vcpu); + vmcb_mark_all_dirty(svm->vmcb); } kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, &svm->vcpu); @@ -1193,6 +1201,10 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, * in the registers, the save area of the nested state instead * contains saved L1 state. */ + + svm->nested.nested_run_pending = + !!(kvm_state->flags & KVM_STATE_NESTED_RUN_PENDING); + copy_vmcb_control_area(&hsave->control, &svm->vmcb->control); hsave->save = *save; diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 566f4d18185b..ac652bc476ae 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -14,10 +14,20 @@ #include <linux/psp-sev.h> #include <linux/pagemap.h> #include <linux/swap.h> +#include <linux/processor.h> +#include <linux/trace_events.h> +#include <asm/fpu/internal.h> + +#include <asm/trapnr.h> #include "x86.h" #include "svm.h" +#include "cpuid.h" +#include "trace.h" + +#define __ex(x) __kvm_handle_fault_on_reboot(x) +static u8 sev_enc_bit; static int sev_flush_asids(void); static DECLARE_RWSEM(sev_deactivate_lock); static DEFINE_MUTEX(sev_bitmap_lock); @@ -25,7 +35,6 @@ unsigned int max_sev_asid; static unsigned int min_sev_asid; static unsigned long *sev_asid_bitmap; static unsigned long *sev_reclaim_asid_bitmap; -#define __sme_page_pa(x) __sme_set(page_to_pfn(x) << PAGE_SHIFT) struct enc_region { struct list_head list; @@ -57,19 +66,19 @@ static int sev_flush_asids(void) } /* Must be called with the sev_bitmap_lock held */ -static bool __sev_recycle_asids(void) +static bool __sev_recycle_asids(int min_asid, int max_asid) { int pos; /* Check if there are any ASIDs to reclaim before performing a flush */ - pos = find_next_bit(sev_reclaim_asid_bitmap, - max_sev_asid, min_sev_asid - 1); - if (pos >= max_sev_asid) + pos = find_next_bit(sev_reclaim_asid_bitmap, max_sev_asid, min_asid); + if (pos >= max_asid) return false; if (sev_flush_asids()) return false; + /* The flush process will flush all reclaimable SEV and SEV-ES ASIDs */ bitmap_xor(sev_asid_bitmap, sev_asid_bitmap, sev_reclaim_asid_bitmap, max_sev_asid); bitmap_zero(sev_reclaim_asid_bitmap, max_sev_asid); @@ -77,20 +86,23 @@ static bool __sev_recycle_asids(void) return true; } -static int sev_asid_new(void) +static int sev_asid_new(struct kvm_sev_info *sev) { + int pos, min_asid, max_asid; bool retry = true; - int pos; mutex_lock(&sev_bitmap_lock); /* - * SEV-enabled guest must use asid from min_sev_asid to max_sev_asid. + * SEV-enabled guests must use asid from min_sev_asid to max_sev_asid. + * SEV-ES-enabled guest can use from 1 to min_sev_asid - 1. */ + min_asid = sev->es_active ? 0 : min_sev_asid - 1; + max_asid = sev->es_active ? min_sev_asid - 1 : max_sev_asid; again: - pos = find_next_zero_bit(sev_asid_bitmap, max_sev_asid, min_sev_asid - 1); - if (pos >= max_sev_asid) { - if (retry && __sev_recycle_asids()) { + pos = find_next_zero_bit(sev_asid_bitmap, max_sev_asid, min_asid); + if (pos >= max_asid) { + if (retry && __sev_recycle_asids(min_asid, max_asid)) { retry = false; goto again; } @@ -172,7 +184,7 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) if (unlikely(sev->active)) return ret; - asid = sev_asid_new(); + asid = sev_asid_new(sev); if (asid < 0) return ret; @@ -191,6 +203,16 @@ e_free: return ret; } +static int sev_es_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) +{ + if (!sev_es) + return -ENOTTY; + + to_kvm_svm(kvm)->sev_info.es_active = true; + + return sev_guest_init(kvm, argp); +} + static int sev_bind_asid(struct kvm *kvm, unsigned int handle, int *error) { struct sev_data_activate *data; @@ -490,6 +512,96 @@ e_free: return ret; } +static int sev_es_sync_vmsa(struct vcpu_svm *svm) +{ + struct vmcb_save_area *save = &svm->vmcb->save; + + /* Check some debug related fields before encrypting the VMSA */ + if (svm->vcpu.guest_debug || (save->dr7 & ~DR7_FIXED_1)) + return -EINVAL; + + /* Sync registgers */ + save->rax = svm->vcpu.arch.regs[VCPU_REGS_RAX]; + save->rbx = svm->vcpu.arch.regs[VCPU_REGS_RBX]; + save->rcx = svm->vcpu.arch.regs[VCPU_REGS_RCX]; + save->rdx = svm->vcpu.arch.regs[VCPU_REGS_RDX]; + save->rsp = svm->vcpu.arch.regs[VCPU_REGS_RSP]; + save->rbp = svm->vcpu.arch.regs[VCPU_REGS_RBP]; + save->rsi = svm->vcpu.arch.regs[VCPU_REGS_RSI]; + save->rdi = svm->vcpu.arch.regs[VCPU_REGS_RDI]; +#ifdef CONFIG_X86_64 + save->r8 = svm->vcpu.arch.regs[VCPU_REGS_R8]; + save->r9 = svm->vcpu.arch.regs[VCPU_REGS_R9]; + save->r10 = svm->vcpu.arch.regs[VCPU_REGS_R10]; + save->r11 = svm->vcpu.arch.regs[VCPU_REGS_R11]; + save->r12 = svm->vcpu.arch.regs[VCPU_REGS_R12]; + save->r13 = svm->vcpu.arch.regs[VCPU_REGS_R13]; + save->r14 = svm->vcpu.arch.regs[VCPU_REGS_R14]; + save->r15 = svm->vcpu.arch.regs[VCPU_REGS_R15]; +#endif + save->rip = svm->vcpu.arch.regs[VCPU_REGS_RIP]; + + /* Sync some non-GPR registers before encrypting */ + save->xcr0 = svm->vcpu.arch.xcr0; + save->pkru = svm->vcpu.arch.pkru; + save->xss = svm->vcpu.arch.ia32_xss; + + /* + * SEV-ES will use a VMSA that is pointed to by the VMCB, not + * the traditional VMSA that is part of the VMCB. Copy the + * traditional VMSA as it has been built so far (in prep + * for LAUNCH_UPDATE_VMSA) to be the initial SEV-ES state. + */ + memcpy(svm->vmsa, save, sizeof(*save)); + + return 0; +} + +static int sev_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp) +{ + struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; + struct sev_data_launch_update_vmsa *vmsa; + int i, ret; + + if (!sev_es_guest(kvm)) + return -ENOTTY; + + vmsa = kzalloc(sizeof(*vmsa), GFP_KERNEL); + if (!vmsa) + return -ENOMEM; + + for (i = 0; i < kvm->created_vcpus; i++) { + struct vcpu_svm *svm = to_svm(kvm->vcpus[i]); + + /* Perform some pre-encryption checks against the VMSA */ + ret = sev_es_sync_vmsa(svm); + if (ret) + goto e_free; + + /* + * The LAUNCH_UPDATE_VMSA command will perform in-place + * encryption of the VMSA memory content (i.e it will write + * the same memory region with the guest's key), so invalidate + * it first. + */ + clflush_cache_range(svm->vmsa, PAGE_SIZE); + + vmsa->handle = sev->handle; + vmsa->address = __sme_pa(svm->vmsa); + vmsa->len = PAGE_SIZE; + ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_UPDATE_VMSA, vmsa, + &argp->error); + if (ret) + goto e_free; + + svm->vcpu.arch.guest_state_protected = true; + } + +e_free: + kfree(vmsa); + return ret; +} + static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp) { void __user *measure = (void __user *)(uintptr_t)argp->data; @@ -932,7 +1044,7 @@ int svm_mem_enc_op(struct kvm *kvm, void __user *argp) struct kvm_sev_cmd sev_cmd; int r; - if (!svm_sev_enabled()) + if (!svm_sev_enabled() || !sev) return -ENOTTY; if (!argp) @@ -947,12 +1059,18 @@ int svm_mem_enc_op(struct kvm *kvm, void __user *argp) case KVM_SEV_INIT: r = sev_guest_init(kvm, &sev_cmd); break; + case KVM_SEV_ES_INIT: + r = sev_es_guest_init(kvm, &sev_cmd); + break; case KVM_SEV_LAUNCH_START: r = sev_launch_start(kvm, &sev_cmd); break; case KVM_SEV_LAUNCH_UPDATE_DATA: r = sev_launch_update_data(kvm, &sev_cmd); break; + case KVM_SEV_LAUNCH_UPDATE_VMSA: + r = sev_launch_update_vmsa(kvm, &sev_cmd); + break; case KVM_SEV_LAUNCH_MEASURE: r = sev_launch_measure(kvm, &sev_cmd); break; @@ -1125,49 +1243,61 @@ void sev_vm_destroy(struct kvm *kvm) sev_asid_free(sev->asid); } -int __init sev_hardware_setup(void) +void __init sev_hardware_setup(void) { - struct sev_user_data_status *status; - int rc; + unsigned int eax, ebx, ecx, edx; + bool sev_es_supported = false; + bool sev_supported = false; + + /* Does the CPU support SEV? */ + if (!boot_cpu_has(X86_FEATURE_SEV)) + goto out; + + /* Retrieve SEV CPUID information */ + cpuid(0x8000001f, &eax, &ebx, &ecx, &edx); + + /* Set encryption bit location for SEV-ES guests */ + sev_enc_bit = ebx & 0x3f; /* Maximum number of encrypted guests supported simultaneously */ - max_sev_asid = cpuid_ecx(0x8000001F); + max_sev_asid = ecx; if (!svm_sev_enabled()) - return 1; + goto out; /* Minimum ASID value that should be used for SEV guest */ - min_sev_asid = cpuid_edx(0x8000001F); + min_sev_asid = edx; /* Initialize SEV ASID bitmaps */ sev_asid_bitmap = bitmap_zalloc(max_sev_asid, GFP_KERNEL); if (!sev_asid_bitmap) - return 1; + goto out; sev_reclaim_asid_bitmap = bitmap_zalloc(max_sev_asid, GFP_KERNEL); if (!sev_reclaim_asid_bitmap) - return 1; + goto out; - status = kmalloc(sizeof(*status), GFP_KERNEL); - if (!status) - return 1; + pr_info("SEV supported: %u ASIDs\n", max_sev_asid - min_sev_asid + 1); + sev_supported = true; - /* - * Check SEV platform status. - * - * PLATFORM_STATUS can be called in any state, if we failed to query - * the PLATFORM status then either PSP firmware does not support SEV - * feature or SEV firmware is dead. - */ - rc = sev_platform_status(status, NULL); - if (rc) - goto err; + /* SEV-ES support requested? */ + if (!sev_es) + goto out; - pr_info("SEV supported\n"); + /* Does the CPU support SEV-ES? */ + if (!boot_cpu_has(X86_FEATURE_SEV_ES)) + goto out; -err: - kfree(status); - return rc; + /* Has the system been allocated ASIDs for SEV-ES? */ + if (min_sev_asid == 1) + goto out; + + pr_info("SEV-ES supported: %u ASIDs\n", min_sev_asid - 1); + sev_es_supported = true; + +out: + sev = sev_supported; + sev_es = sev_es_supported; } void sev_hardware_teardown(void) @@ -1181,13 +1311,327 @@ void sev_hardware_teardown(void) sev_flush_asids(); } +/* + * Pages used by hardware to hold guest encrypted state must be flushed before + * returning them to the system. + */ +static void sev_flush_guest_memory(struct vcpu_svm *svm, void *va, + unsigned long len) +{ + /* + * If hardware enforced cache coherency for encrypted mappings of the + * same physical page is supported, nothing to do. + */ + if (boot_cpu_has(X86_FEATURE_SME_COHERENT)) + return; + + /* + * If the VM Page Flush MSR is supported, use it to flush the page + * (using the page virtual address and the guest ASID). + */ + if (boot_cpu_has(X86_FEATURE_VM_PAGE_FLUSH)) { + struct kvm_sev_info *sev; + unsigned long va_start; + u64 start, stop; + + /* Align start and stop to page boundaries. */ + va_start = (unsigned long)va; + start = (u64)va_start & PAGE_MASK; + stop = PAGE_ALIGN((u64)va_start + len); + + if (start < stop) { + sev = &to_kvm_svm(svm->vcpu.kvm)->sev_info; + + while (start < stop) { + wrmsrl(MSR_AMD64_VM_PAGE_FLUSH, + start | sev->asid); + + start += PAGE_SIZE; + } + + return; + } + + WARN(1, "Address overflow, using WBINVD\n"); + } + + /* + * Hardware should always have one of the above features, + * but if not, use WBINVD and issue a warning. + */ + WARN_ONCE(1, "Using WBINVD to flush guest memory\n"); + wbinvd_on_all_cpus(); +} + +void sev_free_vcpu(struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm; + + if (!sev_es_guest(vcpu->kvm)) + return; + + svm = to_svm(vcpu); + + if (vcpu->arch.guest_state_protected) + sev_flush_guest_memory(svm, svm->vmsa, PAGE_SIZE); + __free_page(virt_to_page(svm->vmsa)); + + if (svm->ghcb_sa_free) + kfree(svm->ghcb_sa); +} + +static void dump_ghcb(struct vcpu_svm *svm) +{ + struct ghcb *ghcb = svm->ghcb; + unsigned int nbits; + + /* Re-use the dump_invalid_vmcb module parameter */ + if (!dump_invalid_vmcb) { + pr_warn_ratelimited("set kvm_amd.dump_invalid_vmcb=1 to dump internal KVM state.\n"); + return; + } + + nbits = sizeof(ghcb->save.valid_bitmap) * 8; + + pr_err("GHCB (GPA=%016llx):\n", svm->vmcb->control.ghcb_gpa); + pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_code", + ghcb->save.sw_exit_code, ghcb_sw_exit_code_is_valid(ghcb)); + pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_info_1", + ghcb->save.sw_exit_info_1, ghcb_sw_exit_info_1_is_valid(ghcb)); + pr_err("%-20s%016llx is_valid: %u\n", "sw_exit_info_2", + ghcb->save.sw_exit_info_2, ghcb_sw_exit_info_2_is_valid(ghcb)); + pr_err("%-20s%016llx is_valid: %u\n", "sw_scratch", + ghcb->save.sw_scratch, ghcb_sw_scratch_is_valid(ghcb)); + pr_err("%-20s%*pb\n", "valid_bitmap", nbits, ghcb->save.valid_bitmap); +} + +static void sev_es_sync_to_ghcb(struct vcpu_svm *svm) +{ + struct kvm_vcpu *vcpu = &svm->vcpu; + struct ghcb *ghcb = svm->ghcb; + + /* + * The GHCB protocol so far allows for the following data + * to be returned: + * GPRs RAX, RBX, RCX, RDX + * + * Copy their values, even if they may not have been written during the + * VM-Exit. It's the guest's responsibility to not consume random data. + */ + ghcb_set_rax(ghcb, vcpu->arch.regs[VCPU_REGS_RAX]); + ghcb_set_rbx(ghcb, vcpu->arch.regs[VCPU_REGS_RBX]); + ghcb_set_rcx(ghcb, vcpu->arch.regs[VCPU_REGS_RCX]); + ghcb_set_rdx(ghcb, vcpu->arch.regs[VCPU_REGS_RDX]); +} + +static void sev_es_sync_from_ghcb(struct vcpu_svm *svm) +{ + struct vmcb_control_area *control = &svm->vmcb->control; + struct kvm_vcpu *vcpu = &svm->vcpu; + struct ghcb *ghcb = svm->ghcb; + u64 exit_code; + + /* + * The GHCB protocol so far allows for the following data + * to be supplied: + * GPRs RAX, RBX, RCX, RDX + * XCR0 + * CPL + * + * VMMCALL allows the guest to provide extra registers. KVM also + * expects RSI for hypercalls, so include that, too. + * + * Copy their values to the appropriate location if supplied. + */ + memset(vcpu->arch.regs, 0, sizeof(vcpu->arch.regs)); + + vcpu->arch.regs[VCPU_REGS_RAX] = ghcb_get_rax_if_valid(ghcb); + vcpu->arch.regs[VCPU_REGS_RBX] = ghcb_get_rbx_if_valid(ghcb); + vcpu->arch.regs[VCPU_REGS_RCX] = ghcb_get_rcx_if_valid(ghcb); + vcpu->arch.regs[VCPU_REGS_RDX] = ghcb_get_rdx_if_valid(ghcb); + vcpu->arch.regs[VCPU_REGS_RSI] = ghcb_get_rsi_if_valid(ghcb); + + svm->vmcb->save.cpl = ghcb_get_cpl_if_valid(ghcb); + + if (ghcb_xcr0_is_valid(ghcb)) { + vcpu->arch.xcr0 = ghcb_get_xcr0(ghcb); + kvm_update_cpuid_runtime(vcpu); + } + + /* Copy the GHCB exit information into the VMCB fields */ + exit_code = ghcb_get_sw_exit_code(ghcb); + control->exit_code = lower_32_bits(exit_code); + control->exit_code_hi = upper_32_bits(exit_code); + control->exit_info_1 = ghcb_get_sw_exit_info_1(ghcb); + control->exit_info_2 = ghcb_get_sw_exit_info_2(ghcb); + + /* Clear the valid entries fields */ + memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap)); +} + +static int sev_es_validate_vmgexit(struct vcpu_svm *svm) +{ + struct kvm_vcpu *vcpu; + struct ghcb *ghcb; + u64 exit_code = 0; + + ghcb = svm->ghcb; + + /* Only GHCB Usage code 0 is supported */ + if (ghcb->ghcb_usage) + goto vmgexit_err; + + /* + * Retrieve the exit code now even though is may not be marked valid + * as it could help with debugging. + */ + exit_code = ghcb_get_sw_exit_code(ghcb); + + if (!ghcb_sw_exit_code_is_valid(ghcb) || + !ghcb_sw_exit_info_1_is_valid(ghcb) || + !ghcb_sw_exit_info_2_is_valid(ghcb)) + goto vmgexit_err; + + switch (ghcb_get_sw_exit_code(ghcb)) { + case SVM_EXIT_READ_DR7: + break; + case SVM_EXIT_WRITE_DR7: + if (!ghcb_rax_is_valid(ghcb)) + goto vmgexit_err; + break; + case SVM_EXIT_RDTSC: + break; + case SVM_EXIT_RDPMC: + if (!ghcb_rcx_is_valid(ghcb)) + goto vmgexit_err; + break; + case SVM_EXIT_CPUID: + if (!ghcb_rax_is_valid(ghcb) || + !ghcb_rcx_is_valid(ghcb)) + goto vmgexit_err; + if (ghcb_get_rax(ghcb) == 0xd) + if (!ghcb_xcr0_is_valid(ghcb)) + goto vmgexit_err; + break; + case SVM_EXIT_INVD: + break; + case SVM_EXIT_IOIO: + if (ghcb_get_sw_exit_info_1(ghcb) & SVM_IOIO_STR_MASK) { + if (!ghcb_sw_scratch_is_valid(ghcb)) + goto vmgexit_err; + } else { + if (!(ghcb_get_sw_exit_info_1(ghcb) & SVM_IOIO_TYPE_MASK)) + if (!ghcb_rax_is_valid(ghcb)) + goto vmgexit_err; + } + break; + case SVM_EXIT_MSR: + if (!ghcb_rcx_is_valid(ghcb)) + goto vmgexit_err; + if (ghcb_get_sw_exit_info_1(ghcb)) { + if (!ghcb_rax_is_valid(ghcb) || + !ghcb_rdx_is_valid(ghcb)) + goto vmgexit_err; + } + break; + case SVM_EXIT_VMMCALL: + if (!ghcb_rax_is_valid(ghcb) || + !ghcb_cpl_is_valid(ghcb)) + goto vmgexit_err; + break; + case SVM_EXIT_RDTSCP: + break; + case SVM_EXIT_WBINVD: + break; + case SVM_EXIT_MONITOR: + if (!ghcb_rax_is_valid(ghcb) || + !ghcb_rcx_is_valid(ghcb) || + !ghcb_rdx_is_valid(ghcb)) + goto vmgexit_err; + break; + case SVM_EXIT_MWAIT: + if (!ghcb_rax_is_valid(ghcb) || + !ghcb_rcx_is_valid(ghcb)) + goto vmgexit_err; + break; + case SVM_VMGEXIT_MMIO_READ: + case SVM_VMGEXIT_MMIO_WRITE: + if (!ghcb_sw_scratch_is_valid(ghcb)) + goto vmgexit_err; + break; + case SVM_VMGEXIT_NMI_COMPLETE: + case SVM_VMGEXIT_AP_HLT_LOOP: + case SVM_VMGEXIT_AP_JUMP_TABLE: + case SVM_VMGEXIT_UNSUPPORTED_EVENT: + break; + default: + goto vmgexit_err; + } + + return 0; + +vmgexit_err: + vcpu = &svm->vcpu; + + if (ghcb->ghcb_usage) { + vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n", + ghcb->ghcb_usage); + } else { + vcpu_unimpl(vcpu, "vmgexit: exit reason %#llx is not valid\n", + exit_code); + dump_ghcb(svm); + } + + vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; + vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON; + vcpu->run->internal.ndata = 2; + vcpu->run->internal.data[0] = exit_code; + vcpu->run->internal.data[1] = vcpu->arch.last_vmentry_cpu; + + return -EINVAL; +} + +static void pre_sev_es_run(struct vcpu_svm *svm) +{ + if (!svm->ghcb) + return; + + if (svm->ghcb_sa_free) { + /* + * The scratch area lives outside the GHCB, so there is a + * buffer that, depending on the operation performed, may + * need to be synced, then freed. + */ + if (svm->ghcb_sa_sync) { + kvm_write_guest(svm->vcpu.kvm, + ghcb_get_sw_scratch(svm->ghcb), + svm->ghcb_sa, svm->ghcb_sa_len); + svm->ghcb_sa_sync = false; + } + + kfree(svm->ghcb_sa); + svm->ghcb_sa = NULL; + svm->ghcb_sa_free = false; + } + + trace_kvm_vmgexit_exit(svm->vcpu.vcpu_id, svm->ghcb); + + sev_es_sync_to_ghcb(svm); + + kvm_vcpu_unmap(&svm->vcpu, &svm->ghcb_map, true); + svm->ghcb = NULL; +} + void pre_sev_run(struct vcpu_svm *svm, int cpu) { struct svm_cpu_data *sd = per_cpu(svm_data, cpu); int asid = sev_get_asid(svm->vcpu.kvm); + /* Perform any SEV-ES pre-run actions */ + pre_sev_es_run(svm); + /* Assign the asid allocated with this SEV guest */ - svm->vmcb->control.asid = asid; + svm->asid = asid; /* * Flush guest TLB: @@ -1203,3 +1647,415 @@ void pre_sev_run(struct vcpu_svm *svm, int cpu) svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ASID; vmcb_mark_dirty(svm->vmcb, VMCB_ASID); } + +#define GHCB_SCRATCH_AREA_LIMIT (16ULL * PAGE_SIZE) +static bool setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) +{ + struct vmcb_control_area *control = &svm->vmcb->control; + struct ghcb *ghcb = svm->ghcb; + u64 ghcb_scratch_beg, ghcb_scratch_end; + u64 scratch_gpa_beg, scratch_gpa_end; + void *scratch_va; + + scratch_gpa_beg = ghcb_get_sw_scratch(ghcb); + if (!scratch_gpa_beg) { + pr_err("vmgexit: scratch gpa not provided\n"); + return false; + } + + scratch_gpa_end = scratch_gpa_beg + len; + if (scratch_gpa_end < scratch_gpa_beg) { + pr_err("vmgexit: scratch length (%#llx) not valid for scratch address (%#llx)\n", + len, scratch_gpa_beg); + return false; + } + + if ((scratch_gpa_beg & PAGE_MASK) == control->ghcb_gpa) { + /* Scratch area begins within GHCB */ + ghcb_scratch_beg = control->ghcb_gpa + + offsetof(struct ghcb, shared_buffer); + ghcb_scratch_end = control->ghcb_gpa + + offsetof(struct ghcb, reserved_1); + + /* + * If the scratch area begins within the GHCB, it must be + * completely contained in the GHCB shared buffer area. + */ + if (scratch_gpa_beg < ghcb_scratch_beg || + scratch_gpa_end > ghcb_scratch_end) { + pr_err("vmgexit: scratch area is outside of GHCB shared buffer area (%#llx - %#llx)\n", + scratch_gpa_beg, scratch_gpa_end); + return false; + } + + scratch_va = (void *)svm->ghcb; + scratch_va += (scratch_gpa_beg - control->ghcb_gpa); + } else { + /* + * The guest memory must be read into a kernel buffer, so + * limit the size + */ + if (len > GHCB_SCRATCH_AREA_LIMIT) { + pr_err("vmgexit: scratch area exceeds KVM limits (%#llx requested, %#llx limit)\n", + len, GHCB_SCRATCH_AREA_LIMIT); + return false; + } + scratch_va = kzalloc(len, GFP_KERNEL); + if (!scratch_va) + return false; + + if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, len)) { + /* Unable to copy scratch area from guest */ + pr_err("vmgexit: kvm_read_guest for scratch area failed\n"); + + kfree(scratch_va); + return false; + } + + /* + * The scratch area is outside the GHCB. The operation will + * dictate whether the buffer needs to be synced before running + * the vCPU next time (i.e. a read was requested so the data + * must be written back to the guest memory). + */ + svm->ghcb_sa_sync = sync; + svm->ghcb_sa_free = true; + } + + svm->ghcb_sa = scratch_va; + svm->ghcb_sa_len = len; + + return true; +} + +static void set_ghcb_msr_bits(struct vcpu_svm *svm, u64 value, u64 mask, + unsigned int pos) +{ + svm->vmcb->control.ghcb_gpa &= ~(mask << pos); + svm->vmcb->control.ghcb_gpa |= (value & mask) << pos; +} + +static u64 get_ghcb_msr_bits(struct vcpu_svm *svm, u64 mask, unsigned int pos) +{ + return (svm->vmcb->control.ghcb_gpa >> pos) & mask; +} + +static void set_ghcb_msr(struct vcpu_svm *svm, u64 value) +{ + svm->vmcb->control.ghcb_gpa = value; +} + +static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm) +{ + struct vmcb_control_area *control = &svm->vmcb->control; + struct kvm_vcpu *vcpu = &svm->vcpu; + u64 ghcb_info; + int ret = 1; + + ghcb_info = control->ghcb_gpa & GHCB_MSR_INFO_MASK; + + trace_kvm_vmgexit_msr_protocol_enter(svm->vcpu.vcpu_id, + control->ghcb_gpa); + + switch (ghcb_info) { + case GHCB_MSR_SEV_INFO_REQ: + set_ghcb_msr(svm, GHCB_MSR_SEV_INFO(GHCB_VERSION_MAX, + GHCB_VERSION_MIN, + sev_enc_bit)); + break; + case GHCB_MSR_CPUID_REQ: { + u64 cpuid_fn, cpuid_reg, cpuid_value; + + cpuid_fn = get_ghcb_msr_bits(svm, + GHCB_MSR_CPUID_FUNC_MASK, + GHCB_MSR_CPUID_FUNC_POS); + + /* Initialize the registers needed by the CPUID intercept */ + vcpu->arch.regs[VCPU_REGS_RAX] = cpuid_fn; + vcpu->arch.regs[VCPU_REGS_RCX] = 0; + + ret = svm_invoke_exit_handler(svm, SVM_EXIT_CPUID); + if (!ret) { + ret = -EINVAL; + break; + } + + cpuid_reg = get_ghcb_msr_bits(svm, + GHCB_MSR_CPUID_REG_MASK, + GHCB_MSR_CPUID_REG_POS); + if (cpuid_reg == 0) + cpuid_value = vcpu->arch.regs[VCPU_REGS_RAX]; + else if (cpuid_reg == 1) + cpuid_value = vcpu->arch.regs[VCPU_REGS_RBX]; + else if (cpuid_reg == 2) + cpuid_value = vcpu->arch.regs[VCPU_REGS_RCX]; + else + cpuid_value = vcpu->arch.regs[VCPU_REGS_RDX]; + + set_ghcb_msr_bits(svm, cpuid_value, + GHCB_MSR_CPUID_VALUE_MASK, + GHCB_MSR_CPUID_VALUE_POS); + + set_ghcb_msr_bits(svm, GHCB_MSR_CPUID_RESP, + GHCB_MSR_INFO_MASK, + GHCB_MSR_INFO_POS); + break; + } + case GHCB_MSR_TERM_REQ: { + u64 reason_set, reason_code; + + reason_set = get_ghcb_msr_bits(svm, + GHCB_MSR_TERM_REASON_SET_MASK, + GHCB_MSR_TERM_REASON_SET_POS); + reason_code = get_ghcb_msr_bits(svm, + GHCB_MSR_TERM_REASON_MASK, + GHCB_MSR_TERM_REASON_POS); + pr_info("SEV-ES guest requested termination: %#llx:%#llx\n", + reason_set, reason_code); + fallthrough; + } + default: + ret = -EINVAL; + } + + trace_kvm_vmgexit_msr_protocol_exit(svm->vcpu.vcpu_id, + control->ghcb_gpa, ret); + + return ret; +} + +int sev_handle_vmgexit(struct vcpu_svm *svm) +{ + struct vmcb_control_area *control = &svm->vmcb->control; + u64 ghcb_gpa, exit_code; + struct ghcb *ghcb; + int ret; + + /* Validate the GHCB */ + ghcb_gpa = control->ghcb_gpa; + if (ghcb_gpa & GHCB_MSR_INFO_MASK) + return sev_handle_vmgexit_msr_protocol(svm); + + if (!ghcb_gpa) { + vcpu_unimpl(&svm->vcpu, "vmgexit: GHCB gpa is not set\n"); + return -EINVAL; + } + + if (kvm_vcpu_map(&svm->vcpu, ghcb_gpa >> PAGE_SHIFT, &svm->ghcb_map)) { + /* Unable to map GHCB from guest */ + vcpu_unimpl(&svm->vcpu, "vmgexit: error mapping GHCB [%#llx] from guest\n", + ghcb_gpa); + return -EINVAL; + } + + svm->ghcb = svm->ghcb_map.hva; + ghcb = svm->ghcb_map.hva; + + trace_kvm_vmgexit_enter(svm->vcpu.vcpu_id, ghcb); + + exit_code = ghcb_get_sw_exit_code(ghcb); + + ret = sev_es_validate_vmgexit(svm); + if (ret) + return ret; + + sev_es_sync_from_ghcb(svm); + ghcb_set_sw_exit_info_1(ghcb, 0); + ghcb_set_sw_exit_info_2(ghcb, 0); + + ret = -EINVAL; + switch (exit_code) { + case SVM_VMGEXIT_MMIO_READ: + if (!setup_vmgexit_scratch(svm, true, control->exit_info_2)) + break; + + ret = kvm_sev_es_mmio_read(&svm->vcpu, + control->exit_info_1, + control->exit_info_2, + svm->ghcb_sa); + break; + case SVM_VMGEXIT_MMIO_WRITE: + if (!setup_vmgexit_scratch(svm, false, control->exit_info_2)) + break; + + ret = kvm_sev_es_mmio_write(&svm->vcpu, + control->exit_info_1, + control->exit_info_2, + svm->ghcb_sa); + break; + case SVM_VMGEXIT_NMI_COMPLETE: + ret = svm_invoke_exit_handler(svm, SVM_EXIT_IRET); + break; + case SVM_VMGEXIT_AP_HLT_LOOP: + ret = kvm_emulate_ap_reset_hold(&svm->vcpu); + break; + case SVM_VMGEXIT_AP_JUMP_TABLE: { + struct kvm_sev_info *sev = &to_kvm_svm(svm->vcpu.kvm)->sev_info; + + switch (control->exit_info_1) { + case 0: + /* Set AP jump table address */ + sev->ap_jump_table = control->exit_info_2; + break; + case 1: + /* Get AP jump table address */ + ghcb_set_sw_exit_info_2(ghcb, sev->ap_jump_table); + break; + default: + pr_err("svm: vmgexit: unsupported AP jump table request - exit_info_1=%#llx\n", + control->exit_info_1); + ghcb_set_sw_exit_info_1(ghcb, 1); + ghcb_set_sw_exit_info_2(ghcb, + X86_TRAP_UD | + SVM_EVTINJ_TYPE_EXEPT | + SVM_EVTINJ_VALID); + } + + ret = 1; + break; + } + case SVM_VMGEXIT_UNSUPPORTED_EVENT: + vcpu_unimpl(&svm->vcpu, + "vmgexit: unsupported event - exit_info_1=%#llx, exit_info_2=%#llx\n", + control->exit_info_1, control->exit_info_2); + break; + default: + ret = svm_invoke_exit_handler(svm, exit_code); + } + + return ret; +} + +int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in) +{ + if (!setup_vmgexit_scratch(svm, in, svm->vmcb->control.exit_info_2)) + return -EINVAL; + + return kvm_sev_es_string_io(&svm->vcpu, size, port, + svm->ghcb_sa, svm->ghcb_sa_len, in); +} + +void sev_es_init_vmcb(struct vcpu_svm *svm) +{ + struct kvm_vcpu *vcpu = &svm->vcpu; + + svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ES_ENABLE; + svm->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK; + + /* + * An SEV-ES guest requires a VMSA area that is a separate from the + * VMCB page. Do not include the encryption mask on the VMSA physical + * address since hardware will access it using the guest key. + */ + svm->vmcb->control.vmsa_pa = __pa(svm->vmsa); + + /* Can't intercept CR register access, HV can't modify CR registers */ + svm_clr_intercept(svm, INTERCEPT_CR0_READ); + svm_clr_intercept(svm, INTERCEPT_CR4_READ); + svm_clr_intercept(svm, INTERCEPT_CR8_READ); + svm_clr_intercept(svm, INTERCEPT_CR0_WRITE); + svm_clr_intercept(svm, INTERCEPT_CR4_WRITE); + svm_clr_intercept(svm, INTERCEPT_CR8_WRITE); + + svm_clr_intercept(svm, INTERCEPT_SELECTIVE_CR0); + + /* Track EFER/CR register changes */ + svm_set_intercept(svm, TRAP_EFER_WRITE); + svm_set_intercept(svm, TRAP_CR0_WRITE); + svm_set_intercept(svm, TRAP_CR4_WRITE); + svm_set_intercept(svm, TRAP_CR8_WRITE); + + /* No support for enable_vmware_backdoor */ + clr_exception_intercept(svm, GP_VECTOR); + + /* Can't intercept XSETBV, HV can't modify XCR0 directly */ + svm_clr_intercept(svm, INTERCEPT_XSETBV); + + /* Clear intercepts on selected MSRs */ + set_msr_interception(vcpu, svm->msrpm, MSR_EFER, 1, 1); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_CR_PAT, 1, 1); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, 1, 1); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1); +} + +void sev_es_create_vcpu(struct vcpu_svm *svm) +{ + /* + * Set the GHCB MSR value as per the GHCB specification when creating + * a vCPU for an SEV-ES guest. + */ + set_ghcb_msr(svm, GHCB_MSR_SEV_INFO(GHCB_VERSION_MAX, + GHCB_VERSION_MIN, + sev_enc_bit)); +} + +void sev_es_vcpu_load(struct vcpu_svm *svm, int cpu) +{ + struct svm_cpu_data *sd = per_cpu(svm_data, cpu); + struct vmcb_save_area *hostsa; + unsigned int i; + + /* + * As an SEV-ES guest, hardware will restore the host state on VMEXIT, + * of which one step is to perform a VMLOAD. Since hardware does not + * perform a VMSAVE on VMRUN, the host savearea must be updated. + */ + asm volatile(__ex("vmsave %0") : : "a" (__sme_page_pa(sd->save_area)) : "memory"); + + /* + * Certain MSRs are restored on VMEXIT, only save ones that aren't + * restored. + */ + for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) { + if (host_save_user_msrs[i].sev_es_restored) + continue; + + rdmsrl(host_save_user_msrs[i].index, svm->host_user_msrs[i]); + } + + /* XCR0 is restored on VMEXIT, save the current host value */ + hostsa = (struct vmcb_save_area *)(page_address(sd->save_area) + 0x400); + hostsa->xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK); + + /* PKRU is restored on VMEXIT, save the curent host value */ + hostsa->pkru = read_pkru(); + + /* MSR_IA32_XSS is restored on VMEXIT, save the currnet host value */ + hostsa->xss = host_xss; +} + +void sev_es_vcpu_put(struct vcpu_svm *svm) +{ + unsigned int i; + + /* + * Certain MSRs are restored on VMEXIT and were saved with vmsave in + * sev_es_vcpu_load() above. Only restore ones that weren't. + */ + for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) { + if (host_save_user_msrs[i].sev_es_restored) + continue; + + wrmsrl(host_save_user_msrs[i].index, svm->host_user_msrs[i]); + } +} + +void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + /* First SIPI: Use the values as initially set by the VMM */ + if (!svm->received_first_sipi) { + svm->received_first_sipi = true; + return; + } + + /* + * Subsequent SIPI: Return from an AP Reset Hold VMGEXIT, where + * the guest will set the CS and RIP. Set SW_EXIT_INFO_2 to a + * non-zero value. + */ + ghcb_set_sw_exit_info_2(svm->ghcb, 1); +} diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index da7eb4aaf44f..f923e14e87df 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -33,9 +33,9 @@ #include <asm/debugreg.h> #include <asm/kvm_para.h> #include <asm/irq_remapping.h> -#include <asm/mce.h> #include <asm/spec-ctrl.h> #include <asm/cpu_device_id.h> +#include <asm/traps.h> #include <asm/virtext.h> #include "trace.h" @@ -90,7 +90,7 @@ static DEFINE_PER_CPU(u64, current_tsc_ratio); static const struct svm_direct_access_msrs { u32 index; /* Index of the MSR */ - bool always; /* True if intercept is always on */ + bool always; /* True if intercept is initially cleared */ } direct_access_msrs[MAX_DIRECT_ACCESS_MSRS] = { { .index = MSR_STAR, .always = true }, { .index = MSR_IA32_SYSENTER_CS, .always = true }, @@ -108,6 +108,9 @@ static const struct svm_direct_access_msrs { { .index = MSR_IA32_LASTBRANCHTOIP, .always = false }, { .index = MSR_IA32_LASTINTFROMIP, .always = false }, { .index = MSR_IA32_LASTINTTOIP, .always = false }, + { .index = MSR_EFER, .always = false }, + { .index = MSR_IA32_CR_PAT, .always = false }, + { .index = MSR_AMD64_SEV_ES_GHCB, .always = true }, { .index = MSR_INVALID, .always = false }, }; @@ -187,10 +190,14 @@ static int vgif = true; module_param(vgif, int, 0444); /* enable/disable SEV support */ -static int sev = IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT); +int sev = IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT); module_param(sev, int, 0444); -static bool __read_mostly dump_invalid_vmcb = 0; +/* enable/disable SEV-ES support */ +int sev_es = IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT); +module_param(sev_es, int, 0444); + +bool __read_mostly dump_invalid_vmcb; module_param(dump_invalid_vmcb, bool, 0644); static u8 rsm_ins_bytes[] = "\x0f\xaa"; @@ -336,6 +343,13 @@ static int skip_emulated_instruction(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); + /* + * SEV-ES does not expose the next RIP. The RIP update is controlled by + * the type of exit and the #VC handler in the guest. + */ + if (sev_es_guest(vcpu->kvm)) + goto done; + if (nrips && svm->vmcb->control.next_rip != 0) { WARN_ON_ONCE(!static_cpu_has(X86_FEATURE_NRIPS)); svm->next_rip = svm->vmcb->control.next_rip; @@ -347,6 +361,8 @@ static int skip_emulated_instruction(struct kvm_vcpu *vcpu) } else { kvm_rip_write(vcpu, svm->next_rip); } + +done: svm_set_interrupt_shadow(vcpu, 0); return 1; @@ -484,7 +500,7 @@ static int svm_hardware_enable(void) wrmsrl(MSR_EFER, efer | EFER_SVME); - wrmsrl(MSR_VM_HSAVE_PA, page_to_pfn(sd->save_area) << PAGE_SHIFT); + wrmsrl(MSR_VM_HSAVE_PA, __sme_page_pa(sd->save_area)); if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) { wrmsrl(MSR_AMD64_TSC_RATIO, TSC_RATIO_DEFAULT); @@ -552,6 +568,7 @@ static int svm_cpu_init(int cpu) sd->save_area = alloc_page(GFP_KERNEL); if (!sd->save_area) goto free_cpu_data; + clear_page(page_address(sd->save_area)); if (svm_sev_enabled()) { sd->sev_vmcbs = kmalloc_array(max_sev_asid + 1, @@ -662,8 +679,8 @@ static void set_msr_interception_bitmap(struct kvm_vcpu *vcpu, u32 *msrpm, msrpm[offset] = tmp; } -static void set_msr_interception(struct kvm_vcpu *vcpu, u32 *msrpm, u32 msr, - int read, int write) +void set_msr_interception(struct kvm_vcpu *vcpu, u32 *msrpm, u32 msr, + int read, int write) { set_shadow_msr_intercept(vcpu, msr, read, write); set_msr_interception_bitmap(vcpu, msrpm, msr, read, write); @@ -959,15 +976,11 @@ static __init int svm_hardware_setup(void) kvm_enable_efer_bits(EFER_SVME | EFER_LMSLE); } - if (sev) { - if (boot_cpu_has(X86_FEATURE_SEV) && - IS_ENABLED(CONFIG_KVM_AMD_SEV)) { - r = sev_hardware_setup(); - if (r) - sev = false; - } else { - sev = false; - } + if (IS_ENABLED(CONFIG_KVM_AMD_SEV) && sev) { + sev_hardware_setup(); + } else { + sev = false; + sev_es = false; } svm_adjust_mmio_mask(); @@ -1215,6 +1228,7 @@ static void init_vmcb(struct vcpu_svm *svm) save->cr4 = 0; } svm->asid_generation = 0; + svm->asid = 0; svm->nested.vmcb12_gpa = 0; svm->vcpu.arch.hflags = 0; @@ -1252,6 +1266,11 @@ static void init_vmcb(struct vcpu_svm *svm) if (sev_guest(svm->vcpu.kvm)) { svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ENABLE; clr_exception_intercept(svm, UD_VECTOR); + + if (sev_es_guest(svm->vcpu.kvm)) { + /* Perform SEV-ES specific VMCB updates */ + sev_es_init_vmcb(svm); + } } vmcb_mark_all_dirty(svm->vmcb); @@ -1288,6 +1307,7 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm; struct page *vmcb_page; + struct page *vmsa_page = NULL; int err; BUILD_BUG_ON(offsetof(struct vcpu_svm, vcpu) != 0); @@ -1298,9 +1318,27 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu) if (!vmcb_page) goto out; + if (sev_es_guest(svm->vcpu.kvm)) { + /* + * SEV-ES guests require a separate VMSA page used to contain + * the encrypted register state of the guest. + */ + vmsa_page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); + if (!vmsa_page) + goto error_free_vmcb_page; + + /* + * SEV-ES guests maintain an encrypted version of their FPU + * state which is restored and saved on VMRUN and VMEXIT. + * Free the fpu structure to prevent KVM from attempting to + * access the FPU state. + */ + kvm_free_guest_fpu(vcpu); + } + err = avic_init_vcpu(svm); if (err) - goto error_free_vmcb_page; + goto error_free_vmsa_page; /* We initialize this flag to true to make sure that the is_running * bit would be set the first time the vcpu is loaded. @@ -1311,21 +1349,32 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu) svm->msrpm = svm_vcpu_alloc_msrpm(); if (!svm->msrpm) { err = -ENOMEM; - goto error_free_vmcb_page; + goto error_free_vmsa_page; } svm_vcpu_init_msrpm(vcpu, svm->msrpm); svm->vmcb = page_address(vmcb_page); svm->vmcb_pa = __sme_set(page_to_pfn(vmcb_page) << PAGE_SHIFT); + + if (vmsa_page) + svm->vmsa = page_address(vmsa_page); + svm->asid_generation = 0; init_vmcb(svm); svm_init_osvw(vcpu); vcpu->arch.microcode_version = 0x01000065; + if (sev_es_guest(svm->vcpu.kvm)) + /* Perform SEV-ES specific VMCB creation updates */ + sev_es_create_vcpu(svm); + return 0; +error_free_vmsa_page: + if (vmsa_page) + __free_page(vmsa_page); error_free_vmcb_page: __free_page(vmcb_page); out: @@ -1353,6 +1402,8 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu) svm_free_nested(svm); + sev_free_vcpu(vcpu); + __free_page(pfn_to_page(__sme_clr(svm->vmcb_pa) >> PAGE_SHIFT)); __free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER); } @@ -1368,15 +1419,20 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) vmcb_mark_all_dirty(svm->vmcb); } + if (sev_es_guest(svm->vcpu.kvm)) { + sev_es_vcpu_load(svm, cpu); + } else { #ifdef CONFIG_X86_64 - rdmsrl(MSR_GS_BASE, to_svm(vcpu)->host.gs_base); + rdmsrl(MSR_GS_BASE, to_svm(vcpu)->host.gs_base); #endif - savesegment(fs, svm->host.fs); - savesegment(gs, svm->host.gs); - svm->host.ldt = kvm_read_ldt(); + savesegment(fs, svm->host.fs); + savesegment(gs, svm->host.gs); + svm->host.ldt = kvm_read_ldt(); - for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) - rdmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); + for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) + rdmsrl(host_save_user_msrs[i].index, + svm->host_user_msrs[i]); + } if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) { u64 tsc_ratio = vcpu->arch.tsc_scaling_ratio; @@ -1404,18 +1460,24 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu) avic_vcpu_put(vcpu); ++vcpu->stat.host_state_reload; - kvm_load_ldt(svm->host.ldt); + if (sev_es_guest(svm->vcpu.kvm)) { + sev_es_vcpu_put(svm); + } else { + kvm_load_ldt(svm->host.ldt); #ifdef CONFIG_X86_64 - loadsegment(fs, svm->host.fs); - wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gsbase); - load_gs_index(svm->host.gs); + loadsegment(fs, svm->host.fs); + wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gsbase); + load_gs_index(svm->host.gs); #else #ifdef CONFIG_X86_32_LAZY_GS - loadsegment(gs, svm->host.gs); + loadsegment(gs, svm->host.gs); #endif #endif - for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) - wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); + + for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) + wrmsrl(host_save_user_msrs[i].index, + svm->host_user_msrs[i]); + } } static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu) @@ -1633,9 +1695,18 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) static void update_cr0_intercept(struct vcpu_svm *svm) { - ulong gcr0 = svm->vcpu.arch.cr0; - u64 *hcr0 = &svm->vmcb->save.cr0; + ulong gcr0; + u64 *hcr0; + /* + * SEV-ES guests must always keep the CR intercepts cleared. CR + * tracking is done using the CR write traps. + */ + if (sev_es_guest(svm->vcpu.kvm)) + return; + + gcr0 = svm->vcpu.arch.cr0; + hcr0 = &svm->vmcb->save.cr0; *hcr0 = (*hcr0 & ~SVM_CR0_SELECTIVE_MASK) | (gcr0 & SVM_CR0_SELECTIVE_MASK); @@ -1655,7 +1726,7 @@ void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) struct vcpu_svm *svm = to_svm(vcpu); #ifdef CONFIG_X86_64 - if (vcpu->arch.efer & EFER_LME) { + if (vcpu->arch.efer & EFER_LME && !vcpu->arch.guest_state_protected) { if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) { vcpu->arch.efer |= EFER_LMA; svm->vmcb->save.efer |= EFER_LMA | EFER_LME; @@ -1684,13 +1755,15 @@ void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) update_cr0_intercept(svm); } -int svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) +static bool svm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) { - unsigned long host_cr4_mce = cr4_read_shadow() & X86_CR4_MCE; - unsigned long old_cr4 = to_svm(vcpu)->vmcb->save.cr4; + return true; +} - if (cr4 & X86_CR4_VMXE) - return 1; +void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) +{ + unsigned long host_cr4_mce = cr4_read_shadow() & X86_CR4_MCE; + unsigned long old_cr4 = vcpu->arch.cr4; if (npt_enabled && ((old_cr4 ^ cr4) & X86_CR4_PGE)) svm_flush_tlb(vcpu); @@ -1701,7 +1774,9 @@ int svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) cr4 |= host_cr4_mce; to_svm(vcpu)->vmcb->save.cr4 = cr4; vmcb_mark_dirty(to_svm(vcpu)->vmcb, VMCB_CR); - return 0; + + if ((cr4 ^ old_cr4) & (X86_CR4_OSXSAVE | X86_CR4_PKE)) + kvm_update_cpuid_runtime(vcpu); } static void svm_set_segment(struct kvm_vcpu *vcpu, @@ -1753,18 +1828,20 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd) ++sd->asid_generation; sd->next_asid = sd->min_asid; svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID; + vmcb_mark_dirty(svm->vmcb, VMCB_ASID); } svm->asid_generation = sd->asid_generation; - svm->vmcb->control.asid = sd->next_asid++; - - vmcb_mark_dirty(svm->vmcb, VMCB_ASID); + svm->asid = sd->next_asid++; } static void svm_set_dr6(struct vcpu_svm *svm, unsigned long value) { struct vmcb *vmcb = svm->vmcb; + if (svm->vcpu.arch.guest_state_protected) + return; + if (unlikely(value != vmcb->save.dr6)) { vmcb->save.dr6 = value; vmcb_mark_dirty(vmcb, VMCB_DR); @@ -1775,6 +1852,9 @@ static void svm_sync_dirty_debug_regs(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); + if (vcpu->arch.guest_state_protected) + return; + get_debugreg(vcpu->arch.db[0], 0); get_debugreg(vcpu->arch.db[1], 1); get_debugreg(vcpu->arch.db[2], 2); @@ -1793,6 +1873,9 @@ static void svm_set_dr7(struct kvm_vcpu *vcpu, unsigned long value) { struct vcpu_svm *svm = to_svm(vcpu); + if (vcpu->arch.guest_state_protected) + return; + svm->vmcb->save.dr7 = value; vmcb_mark_dirty(svm->vmcb, VMCB_DR); } @@ -1931,25 +2014,6 @@ static bool is_erratum_383(void) return true; } -/* - * Trigger machine check on the host. We assume all the MSRs are already set up - * by the CPU and that we still run on the same CPU as the MCE occurred on. - * We pass a fake environment to the machine check handler because we want - * the guest to be always treated like user space, no matter what context - * it used internally. - */ -static void kvm_machine_check(void) -{ -#if defined(CONFIG_X86_MCE) - struct pt_regs regs = { - .cs = 3, /* Fake ring 3 no matter what the guest ran on */ - .flags = X86_EFLAGS_IF, - }; - - do_machine_check(®s); -#endif -} - static void svm_handle_mce(struct vcpu_svm *svm) { if (is_erratum_383()) { @@ -1981,6 +2045,13 @@ static int shutdown_interception(struct vcpu_svm *svm) struct kvm_run *kvm_run = svm->vcpu.run; /* + * The VM save area has already been encrypted so it + * cannot be reinitialized - just terminate. + */ + if (sev_es_guest(svm->vcpu.kvm)) + return -EINVAL; + + /* * VMCB is undefined after a SHUTDOWN intercept * so reinitialize it. */ @@ -2001,11 +2072,16 @@ static int io_interception(struct vcpu_svm *svm) ++svm->vcpu.stat.io_exits; string = (io_info & SVM_IOIO_STR_MASK) != 0; in = (io_info & SVM_IOIO_TYPE_MASK) != 0; - if (string) - return kvm_emulate_instruction(vcpu, 0); - port = io_info >> 16; size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT; + + if (string) { + if (sev_es_guest(vcpu->kvm)) + return sev_es_string_io(svm, size, port, in); + else + return kvm_emulate_instruction(vcpu, 0); + } + svm->next_rip = svm->vmcb->control.exit_info_2; return kvm_fast_pio(&svm->vcpu, size, port, in); @@ -2269,9 +2345,11 @@ static int cpuid_interception(struct vcpu_svm *svm) static int iret_interception(struct vcpu_svm *svm) { ++svm->vcpu.stat.nmi_window_exits; - svm_clr_intercept(svm, INTERCEPT_IRET); svm->vcpu.arch.hflags |= HF_IRET_MASK; - svm->nmi_iret_rip = kvm_rip_read(&svm->vcpu); + if (!sev_es_guest(svm->vcpu.kvm)) { + svm_clr_intercept(svm, INTERCEPT_IRET); + svm->nmi_iret_rip = kvm_rip_read(&svm->vcpu); + } kvm_make_request(KVM_REQ_EVENT, &svm->vcpu); return 1; } @@ -2408,6 +2486,41 @@ static int cr_interception(struct vcpu_svm *svm) return kvm_complete_insn_gp(&svm->vcpu, err); } +static int cr_trap(struct vcpu_svm *svm) +{ + struct kvm_vcpu *vcpu = &svm->vcpu; + unsigned long old_value, new_value; + unsigned int cr; + int ret = 0; + + new_value = (unsigned long)svm->vmcb->control.exit_info_1; + + cr = svm->vmcb->control.exit_code - SVM_EXIT_CR0_WRITE_TRAP; + switch (cr) { + case 0: + old_value = kvm_read_cr0(vcpu); + svm_set_cr0(vcpu, new_value); + + kvm_post_set_cr0(vcpu, old_value, new_value); + break; + case 4: + old_value = kvm_read_cr4(vcpu); + svm_set_cr4(vcpu, new_value); + + kvm_post_set_cr4(vcpu, old_value, new_value); + break; + case 8: + ret = kvm_set_cr8(&svm->vcpu, new_value); + break; + default: + WARN(1, "unhandled CR%d write trap", cr); + kvm_queue_exception(vcpu, UD_VECTOR); + return 1; + } + + return kvm_complete_insn_gp(vcpu, ret); +} + static int dr_interception(struct vcpu_svm *svm) { int reg, dr; @@ -2461,6 +2574,25 @@ static int cr8_write_interception(struct vcpu_svm *svm) return 0; } +static int efer_trap(struct vcpu_svm *svm) +{ + struct msr_data msr_info; + int ret; + + /* + * Clear the EFER_SVME bit from EFER. The SVM code always sets this + * bit in svm_set_efer(), but __kvm_valid_efer() checks it against + * whether the guest has X86_FEATURE_SVM - this avoids a failure if + * the guest doesn't have X86_FEATURE_SVM. + */ + msr_info.host_initiated = false; + msr_info.index = MSR_EFER; + msr_info.data = svm->vmcb->control.exit_info_1 & ~EFER_SVME; + ret = kvm_set_msr_common(&svm->vcpu, &msr_info); + + return kvm_complete_insn_gp(&svm->vcpu, ret); +} + static int svm_get_msr_feature(struct kvm_msr_entry *msr) { msr->data = 0; @@ -2543,10 +2675,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) break; case MSR_IA32_SPEC_CTRL: if (!msr_info->host_initiated && - !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL) && - !guest_cpuid_has(vcpu, X86_FEATURE_AMD_STIBP) && - !guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBRS) && - !guest_cpuid_has(vcpu, X86_FEATURE_AMD_SSBD)) + !guest_has_spec_ctrl_msr(vcpu)) return 1; msr_info->data = svm->spec_ctrl; @@ -2584,6 +2713,20 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return 0; } +static int svm_complete_emulated_msr(struct kvm_vcpu *vcpu, int err) +{ + struct vcpu_svm *svm = to_svm(vcpu); + if (!sev_es_guest(svm->vcpu.kvm) || !err) + return kvm_complete_insn_gp(&svm->vcpu, err); + + ghcb_set_sw_exit_info_1(svm->ghcb, 1); + ghcb_set_sw_exit_info_2(svm->ghcb, + X86_TRAP_GP | + SVM_EVTINJ_TYPE_EXEPT | + SVM_EVTINJ_VALID); + return 1; +} + static int rdmsr_interception(struct vcpu_svm *svm) { return kvm_emulate_rdmsr(&svm->vcpu); @@ -2630,10 +2773,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) break; case MSR_IA32_SPEC_CTRL: if (!msr->host_initiated && - !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL) && - !guest_cpuid_has(vcpu, X86_FEATURE_AMD_STIBP) && - !guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBRS) && - !guest_cpuid_has(vcpu, X86_FEATURE_AMD_SSBD)) + !guest_has_spec_ctrl_msr(vcpu)) return 1; if (kvm_spec_ctrl_test_value(data)) @@ -2658,12 +2798,12 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) break; case MSR_IA32_PRED_CMD: if (!msr->host_initiated && - !guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBPB)) + !guest_has_pred_cmd_msr(vcpu)) return 1; if (data & ~PRED_CMD_IBPB) return 1; - if (!boot_cpu_has(X86_FEATURE_AMD_IBPB)) + if (!boot_cpu_has(X86_FEATURE_IBPB)) return 1; if (!data) break; @@ -2805,7 +2945,14 @@ static int interrupt_window_interception(struct vcpu_svm *svm) static int pause_interception(struct vcpu_svm *svm) { struct kvm_vcpu *vcpu = &svm->vcpu; - bool in_kernel = (svm_get_cpl(vcpu) == 0); + bool in_kernel; + + /* + * CPL is not made available for an SEV-ES guest, therefore + * vcpu->arch.preempted_in_kernel can never be true. Just + * set in_kernel to false as well. + */ + in_kernel = !sev_es_guest(svm->vcpu.kvm) && svm_get_cpl(vcpu) == 0; if (!kvm_pause_in_guest(vcpu->kvm)) grow_ple_window(vcpu); @@ -2920,11 +3067,16 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { [SVM_EXIT_MWAIT] = mwait_interception, [SVM_EXIT_XSETBV] = xsetbv_interception, [SVM_EXIT_RDPRU] = rdpru_interception, + [SVM_EXIT_EFER_WRITE_TRAP] = efer_trap, + [SVM_EXIT_CR0_WRITE_TRAP] = cr_trap, + [SVM_EXIT_CR4_WRITE_TRAP] = cr_trap, + [SVM_EXIT_CR8_WRITE_TRAP] = cr_trap, [SVM_EXIT_INVPCID] = invpcid_interception, [SVM_EXIT_NPF] = npf_interception, [SVM_EXIT_RSM] = rsm_interception, [SVM_EXIT_AVIC_INCOMPLETE_IPI] = avic_incomplete_ipi_interception, [SVM_EXIT_AVIC_UNACCELERATED_ACCESS] = avic_unaccelerated_access_interception, + [SVM_EXIT_VMGEXIT] = sev_handle_vmgexit, }; static void dump_vmcb(struct kvm_vcpu *vcpu) @@ -2966,6 +3118,7 @@ static void dump_vmcb(struct kvm_vcpu *vcpu) pr_err("%-20s%lld\n", "nested_ctl:", control->nested_ctl); pr_err("%-20s%016llx\n", "nested_cr3:", control->nested_cr3); pr_err("%-20s%016llx\n", "avic_vapic_bar:", control->avic_vapic_bar); + pr_err("%-20s%016llx\n", "ghcb:", control->ghcb_gpa); pr_err("%-20s%08x\n", "event_inj:", control->event_inj); pr_err("%-20s%08x\n", "event_inj_err:", control->event_inj_err); pr_err("%-20s%lld\n", "virt_ext:", control->virt_ext); @@ -2973,6 +3126,7 @@ static void dump_vmcb(struct kvm_vcpu *vcpu) pr_err("%-20s%016llx\n", "avic_backing_page:", control->avic_backing_page); pr_err("%-20s%016llx\n", "avic_logical_id:", control->avic_logical_id); pr_err("%-20s%016llx\n", "avic_physical_id:", control->avic_physical_id); + pr_err("%-20s%016llx\n", "vmsa_pa:", control->vmsa_pa); pr_err("VMCB State Save Area:\n"); pr_err("%-5s s: %04x a: %04x l: %08x b: %016llx\n", "es:", @@ -3045,6 +3199,43 @@ static void dump_vmcb(struct kvm_vcpu *vcpu) "excp_to:", save->last_excp_to); } +static int svm_handle_invalid_exit(struct kvm_vcpu *vcpu, u64 exit_code) +{ + if (exit_code < ARRAY_SIZE(svm_exit_handlers) && + svm_exit_handlers[exit_code]) + return 0; + + vcpu_unimpl(vcpu, "svm: unexpected exit reason 0x%llx\n", exit_code); + dump_vmcb(vcpu); + vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; + vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON; + vcpu->run->internal.ndata = 2; + vcpu->run->internal.data[0] = exit_code; + vcpu->run->internal.data[1] = vcpu->arch.last_vmentry_cpu; + + return -EINVAL; +} + +int svm_invoke_exit_handler(struct vcpu_svm *svm, u64 exit_code) +{ + if (svm_handle_invalid_exit(&svm->vcpu, exit_code)) + return 0; + +#ifdef CONFIG_RETPOLINE + if (exit_code == SVM_EXIT_MSR) + return msr_interception(svm); + else if (exit_code == SVM_EXIT_VINTR) + return interrupt_window_interception(svm); + else if (exit_code == SVM_EXIT_INTR) + return intr_interception(svm); + else if (exit_code == SVM_EXIT_HLT) + return halt_interception(svm); + else if (exit_code == SVM_EXIT_NPF) + return npf_interception(svm); +#endif + return svm_exit_handlers[exit_code](svm); +} + static void svm_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2, u32 *intr_info, u32 *error_code) { @@ -3068,10 +3259,13 @@ static int handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) trace_kvm_exit(exit_code, vcpu, KVM_ISA_SVM); - if (!svm_is_intercept(svm, INTERCEPT_CR0_WRITE)) - vcpu->arch.cr0 = svm->vmcb->save.cr0; - if (npt_enabled) - vcpu->arch.cr3 = svm->vmcb->save.cr3; + /* SEV-ES guests must use the CR write traps to track CR registers. */ + if (!sev_es_guest(vcpu->kvm)) { + if (!svm_is_intercept(svm, INTERCEPT_CR0_WRITE)) + vcpu->arch.cr0 = svm->vmcb->save.cr0; + if (npt_enabled) + vcpu->arch.cr3 = svm->vmcb->save.cr3; + } if (is_guest_mode(vcpu)) { int vmexit; @@ -3108,32 +3302,7 @@ static int handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) if (exit_fastpath != EXIT_FASTPATH_NONE) return 1; - if (exit_code >= ARRAY_SIZE(svm_exit_handlers) - || !svm_exit_handlers[exit_code]) { - vcpu_unimpl(vcpu, "svm: unexpected exit reason 0x%x\n", exit_code); - dump_vmcb(vcpu); - vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; - vcpu->run->internal.suberror = - KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON; - vcpu->run->internal.ndata = 2; - vcpu->run->internal.data[0] = exit_code; - vcpu->run->internal.data[1] = vcpu->arch.last_vmentry_cpu; - return 0; - } - -#ifdef CONFIG_RETPOLINE - if (exit_code == SVM_EXIT_MSR) - return msr_interception(svm); - else if (exit_code == SVM_EXIT_VINTR) - return interrupt_window_interception(svm); - else if (exit_code == SVM_EXIT_INTR) - return intr_interception(svm); - else if (exit_code == SVM_EXIT_HLT) - return halt_interception(svm); - else if (exit_code == SVM_EXIT_NPF) - return npf_interception(svm); -#endif - return svm_exit_handlers[exit_code](svm); + return svm_invoke_exit_handler(svm, exit_code); } static void reload_tss(struct kvm_vcpu *vcpu) @@ -3162,7 +3331,8 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_NMI; vcpu->arch.hflags |= HF_NMI_MASK; - svm_set_intercept(svm, INTERCEPT_IRET); + if (!sev_es_guest(svm->vcpu.kvm)) + svm_set_intercept(svm, INTERCEPT_IRET); ++vcpu->stat.nmi_injections; } @@ -3183,6 +3353,13 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) { struct vcpu_svm *svm = to_svm(vcpu); + /* + * SEV-ES guests must always keep the CR intercepts cleared. CR + * tracking is done using the CR write traps. + */ + if (sev_es_guest(vcpu->kvm)) + return; + if (nested_svm_virtualize_tpr(vcpu)) return; @@ -3239,10 +3416,12 @@ static void svm_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked) if (masked) { svm->vcpu.arch.hflags |= HF_NMI_MASK; - svm_set_intercept(svm, INTERCEPT_IRET); + if (!sev_es_guest(svm->vcpu.kvm)) + svm_set_intercept(svm, INTERCEPT_IRET); } else { svm->vcpu.arch.hflags &= ~HF_NMI_MASK; - svm_clr_intercept(svm, INTERCEPT_IRET); + if (!sev_es_guest(svm->vcpu.kvm)) + svm_clr_intercept(svm, INTERCEPT_IRET); } } @@ -3254,7 +3433,14 @@ bool svm_interrupt_blocked(struct kvm_vcpu *vcpu) if (!gif_set(svm)) return true; - if (is_guest_mode(vcpu)) { + if (sev_es_guest(svm->vcpu.kvm)) { + /* + * SEV-ES guests to not expose RFLAGS. Use the VMCB interrupt mask + * bit to determine the state of the IF flag. + */ + if (!(vmcb->control.int_state & SVM_GUEST_INTERRUPT_MASK)) + return true; + } else if (is_guest_mode(vcpu)) { /* As long as interrupts are being delivered... */ if ((svm->nested.ctl.int_ctl & V_INTR_MASKING_MASK) ? !(svm->nested.hsave->save.rflags & X86_EFLAGS_IF) @@ -3413,8 +3599,9 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) * If we've made progress since setting HF_IRET_MASK, we've * executed an IRET and can allow NMI injection. */ - if ((svm->vcpu.arch.hflags & HF_IRET_MASK) - && kvm_rip_read(&svm->vcpu) != svm->nmi_iret_rip) { + if ((svm->vcpu.arch.hflags & HF_IRET_MASK) && + (sev_es_guest(svm->vcpu.kvm) || + kvm_rip_read(&svm->vcpu) != svm->nmi_iret_rip)) { svm->vcpu.arch.hflags &= ~(HF_NMI_MASK | HF_IRET_MASK); kvm_make_request(KVM_REQ_EVENT, &svm->vcpu); } @@ -3437,6 +3624,12 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) break; case SVM_EXITINTINFO_TYPE_EXEPT: /* + * Never re-inject a #VC exception. + */ + if (vector == X86_TRAP_VC) + break; + + /* * In case of software exceptions, do not reinject the vector, * but re-execute the instruction instead. Rewind RIP first * if we emulated INT3 before. @@ -3484,8 +3677,6 @@ static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu) return EXIT_FASTPATH_NONE; } -void __svm_vcpu_run(unsigned long vmcb_pa, unsigned long *regs); - static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, struct vcpu_svm *svm) { @@ -3509,16 +3700,20 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, guest_enter_irqoff(); lockdep_hardirqs_on(CALLER_ADDR0); - __svm_vcpu_run(svm->vmcb_pa, (unsigned long *)&svm->vcpu.arch.regs); + if (sev_es_guest(svm->vcpu.kvm)) { + __svm_sev_es_vcpu_run(svm->vmcb_pa); + } else { + __svm_vcpu_run(svm->vmcb_pa, (unsigned long *)&svm->vcpu.arch.regs); #ifdef CONFIG_X86_64 - native_wrmsrl(MSR_GS_BASE, svm->host.gs_base); + native_wrmsrl(MSR_GS_BASE, svm->host.gs_base); #else - loadsegment(fs, svm->host.fs); + loadsegment(fs, svm->host.fs); #ifndef CONFIG_X86_32_LAZY_GS - loadsegment(gs, svm->host.gs); + loadsegment(gs, svm->host.gs); #endif #endif + } /* * VMEXIT disables interrupts (host state), but tracing and lockdep @@ -3544,6 +3739,8 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); + trace_kvm_entry(vcpu); + svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX]; svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP]; svm->vmcb->save.rip = vcpu->arch.regs[VCPU_REGS_RIP]; @@ -3568,6 +3765,10 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) sync_lapic_to_cr8(vcpu); + if (unlikely(svm->asid != svm->vmcb->control.asid)) { + svm->vmcb->control.asid = svm->asid; + vmcb_mark_dirty(svm->vmcb, VMCB_ASID); + } svm->vmcb->save.cr2 = vcpu->arch.cr2; /* @@ -3612,14 +3813,17 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) if (unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))) svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL); - reload_tss(vcpu); + if (!sev_es_guest(svm->vcpu.kvm)) + reload_tss(vcpu); x86_spec_ctrl_restore_host(svm->spec_ctrl, svm->virt_spec_ctrl); - vcpu->arch.cr2 = svm->vmcb->save.cr2; - vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax; - vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; - vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip; + if (!sev_es_guest(svm->vcpu.kvm)) { + vcpu->arch.cr2 = svm->vmcb->save.cr2; + vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax; + vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; + vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip; + } if (unlikely(svm->vmcb->control.exit_code == SVM_EXIT_NMI)) kvm_before_interrupt(&svm->vcpu); @@ -3722,12 +3926,21 @@ static bool svm_cpu_has_accelerated_tpr(void) return false; } -static bool svm_has_emulated_msr(u32 index) +/* + * The kvm parameter can be NULL (module initialization, or invocation before + * VM creation). Be sure to check the kvm parameter before using it. + */ +static bool svm_has_emulated_msr(struct kvm *kvm, u32 index) { switch (index) { case MSR_IA32_MCG_EXT_CTL: case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC: return false; + case MSR_IA32_SMBASE: + /* SEV-ES guests do not support SMM, so report false */ + if (kvm && sev_es_guest(kvm)) + return false; + break; default: break; } @@ -4086,6 +4299,12 @@ static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, void *insn, int i unsigned long cr4; /* + * When the guest is an SEV-ES guest, emulation is not possible. + */ + if (sev_es_guest(vcpu->kvm)) + return false; + + /* * Detect and workaround Errata 1096 Fam_17h_00_0Fh. * * Errata: @@ -4165,6 +4384,14 @@ static bool svm_apic_init_signal_blocked(struct kvm_vcpu *vcpu) (vmcb_is_intercept(&svm->vmcb->control, INTERCEPT_INIT)); } +static void svm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) +{ + if (!sev_es_guest(vcpu->kvm)) + return kvm_vcpu_deliver_sipi_vector(vcpu, vector); + + sev_vcpu_deliver_sipi_vector(vcpu, vector); +} + static void svm_vm_destroy(struct kvm *kvm) { avic_vm_destroy(kvm); @@ -4217,6 +4444,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { .get_cpl = svm_get_cpl, .get_cs_db_l_bits = kvm_get_cs_db_l_bits, .set_cr0 = svm_set_cr0, + .is_valid_cr4 = svm_is_valid_cr4, .set_cr4 = svm_set_cr4, .set_efer = svm_set_efer, .get_idt = svm_get_idt, @@ -4305,6 +4533,9 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { .apic_init_signal_blocked = svm_apic_init_signal_blocked, .msr_filter_changed = svm_msr_filter_changed, + .complete_emulated_msr = svm_complete_emulated_msr, + + .vcpu_deliver_sipi_vector = svm_vcpu_deliver_sipi_vector, }; static struct kvm_x86_init_ops svm_init_ops __initdata = { diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 1d853fe4c778..0fe874ae5498 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -17,21 +17,32 @@ #include <linux/kvm_types.h> #include <linux/kvm_host.h> +#include <linux/bits.h> #include <asm/svm.h> -static const u32 host_save_user_msrs[] = { +#define __sme_page_pa(x) __sme_set(page_to_pfn(x) << PAGE_SHIFT) + +static const struct svm_host_save_msrs { + u32 index; /* Index of the MSR */ + bool sev_es_restored; /* True if MSR is restored on SEV-ES VMEXIT */ +} host_save_user_msrs[] = { #ifdef CONFIG_X86_64 - MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE, - MSR_FS_BASE, + { .index = MSR_STAR, .sev_es_restored = true }, + { .index = MSR_LSTAR, .sev_es_restored = true }, + { .index = MSR_CSTAR, .sev_es_restored = true }, + { .index = MSR_SYSCALL_MASK, .sev_es_restored = true }, + { .index = MSR_KERNEL_GS_BASE, .sev_es_restored = true }, + { .index = MSR_FS_BASE, .sev_es_restored = true }, #endif - MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, - MSR_TSC_AUX, + { .index = MSR_IA32_SYSENTER_CS, .sev_es_restored = true }, + { .index = MSR_IA32_SYSENTER_ESP, .sev_es_restored = true }, + { .index = MSR_IA32_SYSENTER_EIP, .sev_es_restored = true }, + { .index = MSR_TSC_AUX, .sev_es_restored = false }, }; - #define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs) -#define MAX_DIRECT_ACCESS_MSRS 15 +#define MAX_DIRECT_ACCESS_MSRS 18 #define MSRPM_OFFSETS 16 extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly; extern bool npt_enabled; @@ -61,11 +72,13 @@ enum { struct kvm_sev_info { bool active; /* SEV enabled guest */ + bool es_active; /* SEV-ES enabled guest */ unsigned int asid; /* ASID used for this guest */ unsigned int handle; /* SEV firmware handle */ int fd; /* SEV device fd */ unsigned long pages_locked; /* Number of pages locked */ struct list_head regions_list; /* List of registered regions */ + u64 ap_jump_table; /* SEV-ES AP Jump Table address */ }; struct kvm_svm { @@ -106,6 +119,7 @@ struct vcpu_svm { struct vmcb *vmcb; unsigned long vmcb_pa; struct svm_cpu_data *svm_data; + u32 asid; uint64_t asid_generation; uint64_t sysenter_esp; uint64_t sysenter_eip; @@ -166,6 +180,18 @@ struct vcpu_svm { DECLARE_BITMAP(read, MAX_DIRECT_ACCESS_MSRS); DECLARE_BITMAP(write, MAX_DIRECT_ACCESS_MSRS); } shadow_msr_intercept; + + /* SEV-ES support */ + struct vmcb_save_area *vmsa; + struct ghcb *ghcb; + struct kvm_host_map ghcb_map; + bool received_first_sipi; + + /* SEV-ES scratch area support */ + void *ghcb_sa; + u64 ghcb_sa_len; + bool ghcb_sa_sync; + bool ghcb_sa_free; }; struct svm_cpu_data { @@ -193,6 +219,28 @@ static inline struct kvm_svm *to_kvm_svm(struct kvm *kvm) return container_of(kvm, struct kvm_svm, kvm); } +static inline bool sev_guest(struct kvm *kvm) +{ +#ifdef CONFIG_KVM_AMD_SEV + struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; + + return sev->active; +#else + return false; +#endif +} + +static inline bool sev_es_guest(struct kvm *kvm) +{ +#ifdef CONFIG_KVM_AMD_SEV + struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; + + return sev_guest(kvm) && sev->es_active; +#else + return false; +#endif +} + static inline void vmcb_mark_all_dirty(struct vmcb *vmcb) { vmcb->control.clean = 0; @@ -244,21 +292,24 @@ static inline void set_dr_intercepts(struct vcpu_svm *svm) { struct vmcb *vmcb = get_host_vmcb(svm); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR0_READ); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR1_READ); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR2_READ); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR3_READ); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR4_READ); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR5_READ); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR6_READ); + if (!sev_es_guest(svm->vcpu.kvm)) { + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR0_READ); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR1_READ); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR2_READ); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR3_READ); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR4_READ); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR5_READ); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR6_READ); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR0_WRITE); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR1_WRITE); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR2_WRITE); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR3_WRITE); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR4_WRITE); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR5_WRITE); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR6_WRITE); + } + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_READ); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR0_WRITE); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR1_WRITE); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR2_WRITE); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR3_WRITE); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR4_WRITE); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR5_WRITE); - vmcb_set_intercept(&vmcb->control, INTERCEPT_DR6_WRITE); vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_WRITE); recalc_intercepts(svm); @@ -270,6 +321,12 @@ static inline void clr_dr_intercepts(struct vcpu_svm *svm) vmcb->control.intercepts[INTERCEPT_DR] = 0; + /* DR7 access must remain intercepted for an SEV-ES guest */ + if (sev_es_guest(svm->vcpu.kvm)) { + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_READ); + vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_WRITE); + } + recalc_intercepts(svm); } @@ -351,6 +408,10 @@ static inline bool gif_set(struct vcpu_svm *svm) #define MSR_CR3_LONG_MBZ_MASK 0xfff0000000000000U #define MSR_INVALID 0xffffffffU +extern int sev; +extern int sev_es; +extern bool dump_invalid_vmcb; + u32 svm_msrpm_offset(u32 msr); u32 *svm_vcpu_alloc_msrpm(void); void svm_vcpu_init_msrpm(struct kvm_vcpu *vcpu, u32 *msrpm); @@ -358,13 +419,16 @@ void svm_vcpu_free_msrpm(u32 *msrpm); int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer); void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); -int svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); +void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); void svm_flush_tlb(struct kvm_vcpu *vcpu); void disable_nmi_singlestep(struct vcpu_svm *svm); bool svm_smi_blocked(struct kvm_vcpu *vcpu); bool svm_nmi_blocked(struct kvm_vcpu *vcpu); bool svm_interrupt_blocked(struct kvm_vcpu *vcpu); void svm_set_gif(struct vcpu_svm *svm, bool value); +int svm_invoke_exit_handler(struct vcpu_svm *svm, u64 exit_code); +void set_msr_interception(struct kvm_vcpu *vcpu, u32 *msrpm, u32 msr, + int read, int write); /* nested.c */ @@ -470,18 +534,42 @@ void svm_vcpu_unblocking(struct kvm_vcpu *vcpu); /* sev.c */ -extern unsigned int max_sev_asid; +#define GHCB_VERSION_MAX 1ULL +#define GHCB_VERSION_MIN 1ULL + +#define GHCB_MSR_INFO_POS 0 +#define GHCB_MSR_INFO_MASK (BIT_ULL(12) - 1) + +#define GHCB_MSR_SEV_INFO_RESP 0x001 +#define GHCB_MSR_SEV_INFO_REQ 0x002 +#define GHCB_MSR_VER_MAX_POS 48 +#define GHCB_MSR_VER_MAX_MASK 0xffff +#define GHCB_MSR_VER_MIN_POS 32 +#define GHCB_MSR_VER_MIN_MASK 0xffff +#define GHCB_MSR_CBIT_POS 24 +#define GHCB_MSR_CBIT_MASK 0xff +#define GHCB_MSR_SEV_INFO(_max, _min, _cbit) \ + ((((_max) & GHCB_MSR_VER_MAX_MASK) << GHCB_MSR_VER_MAX_POS) | \ + (((_min) & GHCB_MSR_VER_MIN_MASK) << GHCB_MSR_VER_MIN_POS) | \ + (((_cbit) & GHCB_MSR_CBIT_MASK) << GHCB_MSR_CBIT_POS) | \ + GHCB_MSR_SEV_INFO_RESP) + +#define GHCB_MSR_CPUID_REQ 0x004 +#define GHCB_MSR_CPUID_RESP 0x005 +#define GHCB_MSR_CPUID_FUNC_POS 32 +#define GHCB_MSR_CPUID_FUNC_MASK 0xffffffff +#define GHCB_MSR_CPUID_VALUE_POS 32 +#define GHCB_MSR_CPUID_VALUE_MASK 0xffffffff +#define GHCB_MSR_CPUID_REG_POS 30 +#define GHCB_MSR_CPUID_REG_MASK 0x3 + +#define GHCB_MSR_TERM_REQ 0x100 +#define GHCB_MSR_TERM_REASON_SET_POS 12 +#define GHCB_MSR_TERM_REASON_SET_MASK 0xf +#define GHCB_MSR_TERM_REASON_POS 16 +#define GHCB_MSR_TERM_REASON_MASK 0xff -static inline bool sev_guest(struct kvm *kvm) -{ -#ifdef CONFIG_KVM_AMD_SEV - struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; - - return sev->active; -#else - return false; -#endif -} +extern unsigned int max_sev_asid; static inline bool svm_sev_enabled(void) { @@ -495,7 +583,20 @@ int svm_register_enc_region(struct kvm *kvm, int svm_unregister_enc_region(struct kvm *kvm, struct kvm_enc_region *range); void pre_sev_run(struct vcpu_svm *svm, int cpu); -int __init sev_hardware_setup(void); +void __init sev_hardware_setup(void); void sev_hardware_teardown(void); +void sev_free_vcpu(struct kvm_vcpu *vcpu); +int sev_handle_vmgexit(struct vcpu_svm *svm); +int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in); +void sev_es_init_vmcb(struct vcpu_svm *svm); +void sev_es_create_vcpu(struct vcpu_svm *svm); +void sev_es_vcpu_load(struct vcpu_svm *svm, int cpu); +void sev_es_vcpu_put(struct vcpu_svm *svm); +void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector); + +/* vmenter.S */ + +void __svm_sev_es_vcpu_run(unsigned long vmcb_pa); +void __svm_vcpu_run(unsigned long vmcb_pa, unsigned long *regs); #endif diff --git a/arch/x86/kvm/svm/vmenter.S b/arch/x86/kvm/svm/vmenter.S index 1ec1ac40e328..6feb8c08f45a 100644 --- a/arch/x86/kvm/svm/vmenter.S +++ b/arch/x86/kvm/svm/vmenter.S @@ -168,3 +168,53 @@ SYM_FUNC_START(__svm_vcpu_run) pop %_ASM_BP ret SYM_FUNC_END(__svm_vcpu_run) + +/** + * __svm_sev_es_vcpu_run - Run a SEV-ES vCPU via a transition to SVM guest mode + * @vmcb_pa: unsigned long + */ +SYM_FUNC_START(__svm_sev_es_vcpu_run) + push %_ASM_BP +#ifdef CONFIG_X86_64 + push %r15 + push %r14 + push %r13 + push %r12 +#else + push %edi + push %esi +#endif + push %_ASM_BX + + /* Enter guest mode */ + mov %_ASM_ARG1, %_ASM_AX + sti + +1: vmrun %_ASM_AX + jmp 3f +2: cmpb $0, kvm_rebooting + jne 3f + ud2 + _ASM_EXTABLE(1b, 2b) + +3: cli + +#ifdef CONFIG_RETPOLINE + /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */ + FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE +#endif + + pop %_ASM_BX + +#ifdef CONFIG_X86_64 + pop %r12 + pop %r13 + pop %r14 + pop %r15 +#else + pop %esi + pop %edi +#endif + pop %_ASM_BP + ret +SYM_FUNC_END(__svm_sev_es_vcpu_run) diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index aef960f90f26..2de30c20bc26 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -1578,6 +1578,103 @@ TRACE_EVENT(kvm_hv_syndbg_get_msr, __entry->vcpu_id, __entry->vp_index, __entry->msr, __entry->data) ); + +/* + * Tracepoint for the start of VMGEXIT processing + */ +TRACE_EVENT(kvm_vmgexit_enter, + TP_PROTO(unsigned int vcpu_id, struct ghcb *ghcb), + TP_ARGS(vcpu_id, ghcb), + + TP_STRUCT__entry( + __field(unsigned int, vcpu_id) + __field(u64, exit_reason) + __field(u64, info1) + __field(u64, info2) + ), + + TP_fast_assign( + __entry->vcpu_id = vcpu_id; + __entry->exit_reason = ghcb->save.sw_exit_code; + __entry->info1 = ghcb->save.sw_exit_info_1; + __entry->info2 = ghcb->save.sw_exit_info_2; + ), + + TP_printk("vcpu %u, exit_reason %llx, exit_info1 %llx, exit_info2 %llx", + __entry->vcpu_id, __entry->exit_reason, + __entry->info1, __entry->info2) +); + +/* + * Tracepoint for the end of VMGEXIT processing + */ +TRACE_EVENT(kvm_vmgexit_exit, + TP_PROTO(unsigned int vcpu_id, struct ghcb *ghcb), + TP_ARGS(vcpu_id, ghcb), + + TP_STRUCT__entry( + __field(unsigned int, vcpu_id) + __field(u64, exit_reason) + __field(u64, info1) + __field(u64, info2) + ), + + TP_fast_assign( + __entry->vcpu_id = vcpu_id; + __entry->exit_reason = ghcb->save.sw_exit_code; + __entry->info1 = ghcb->save.sw_exit_info_1; + __entry->info2 = ghcb->save.sw_exit_info_2; + ), + + TP_printk("vcpu %u, exit_reason %llx, exit_info1 %llx, exit_info2 %llx", + __entry->vcpu_id, __entry->exit_reason, + __entry->info1, __entry->info2) +); + +/* + * Tracepoint for the start of VMGEXIT MSR procotol processing + */ +TRACE_EVENT(kvm_vmgexit_msr_protocol_enter, + TP_PROTO(unsigned int vcpu_id, u64 ghcb_gpa), + TP_ARGS(vcpu_id, ghcb_gpa), + + TP_STRUCT__entry( + __field(unsigned int, vcpu_id) + __field(u64, ghcb_gpa) + ), + + TP_fast_assign( + __entry->vcpu_id = vcpu_id; + __entry->ghcb_gpa = ghcb_gpa; + ), + + TP_printk("vcpu %u, ghcb_gpa %016llx", + __entry->vcpu_id, __entry->ghcb_gpa) +); + +/* + * Tracepoint for the end of VMGEXIT MSR procotol processing + */ +TRACE_EVENT(kvm_vmgexit_msr_protocol_exit, + TP_PROTO(unsigned int vcpu_id, u64 ghcb_gpa, int result), + TP_ARGS(vcpu_id, ghcb_gpa, result), + + TP_STRUCT__entry( + __field(unsigned int, vcpu_id) + __field(u64, ghcb_gpa) + __field(int, result) + ), + + TP_fast_assign( + __entry->vcpu_id = vcpu_id; + __entry->ghcb_gpa = ghcb_gpa; + __entry->result = result; + ), + + TP_printk("vcpu %u, ghcb_gpa %016llx, result %d", + __entry->vcpu_id, __entry->ghcb_gpa, __entry->result) +); + #endif /* _TRACE_KVM_H */ #undef TRACE_INCLUDE_PATH diff --git a/arch/x86/kvm/vmx/evmcs.c b/arch/x86/kvm/vmx/evmcs.c index f3199bb02f22..41f24661af04 100644 --- a/arch/x86/kvm/vmx/evmcs.c +++ b/arch/x86/kvm/vmx/evmcs.c @@ -326,7 +326,6 @@ bool nested_enlightened_vmentry(struct kvm_vcpu *vcpu, u64 *evmcs_gpa) uint16_t nested_get_evmcs_version(struct kvm_vcpu *vcpu) { - struct vcpu_vmx *vmx = to_vmx(vcpu); /* * vmcs_version represents the range of supported Enlightened VMCS * versions: lower 8 bits is the minimal version, higher 8 bits is the @@ -334,7 +333,7 @@ uint16_t nested_get_evmcs_version(struct kvm_vcpu *vcpu) * KVM_EVMCS_VERSION. */ if (kvm_cpu_cap_get(X86_FEATURE_VMX) && - vmx->nested.enlightened_vmcs_enabled) + (!vcpu || to_vmx(vcpu)->nested.enlightened_vmcs_enabled)) return (KVM_EVMCS_VERSION << 8) | 1; return 0; diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 89af692deb7e..f2b9bfb58206 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2952,7 +2952,8 @@ static int nested_vmx_check_vmcs_link_ptr(struct kvm_vcpu *vcpu, static int nested_check_guest_non_reg_state(struct vmcs12 *vmcs12) { if (CC(vmcs12->guest_activity_state != GUEST_ACTIVITY_ACTIVE && - vmcs12->guest_activity_state != GUEST_ACTIVITY_HLT)) + vmcs12->guest_activity_state != GUEST_ACTIVITY_HLT && + vmcs12->guest_activity_state != GUEST_ACTIVITY_WAIT_SIPI)) return -EINVAL; return 0; @@ -3123,13 +3124,9 @@ static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu) return 0; } -static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) +static bool nested_get_evmcs_page(struct kvm_vcpu *vcpu) { - struct vmcs12 *vmcs12 = get_vmcs12(vcpu); struct vcpu_vmx *vmx = to_vmx(vcpu); - struct kvm_host_map *map; - struct page *page; - u64 hpa; /* * hv_evmcs may end up being not mapped after migration (when @@ -3152,6 +3149,17 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) } } + return true; +} + +static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) +{ + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); + struct vcpu_vmx *vmx = to_vmx(vcpu); + struct kvm_host_map *map; + struct page *page; + u64 hpa; + if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) { /* * Translate L1 physical address to host physical @@ -3220,6 +3228,18 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) exec_controls_setbit(vmx, CPU_BASED_USE_MSR_BITMAPS); else exec_controls_clearbit(vmx, CPU_BASED_USE_MSR_BITMAPS); + + return true; +} + +static bool vmx_get_nested_state_pages(struct kvm_vcpu *vcpu) +{ + if (!nested_get_evmcs_page(vcpu)) + return false; + + if (is_guest_mode(vcpu) && !nested_get_vmcs12_pages(vcpu)) + return false; + return true; } @@ -3559,19 +3579,29 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) */ nested_cache_shadow_vmcs12(vcpu, vmcs12); - /* - * If we're entering a halted L2 vcpu and the L2 vcpu won't be - * awakened by event injection or by an NMI-window VM-exit or - * by an interrupt-window VM-exit, halt the vcpu. - */ - if ((vmcs12->guest_activity_state == GUEST_ACTIVITY_HLT) && - !(vmcs12->vm_entry_intr_info_field & INTR_INFO_VALID_MASK) && - !(vmcs12->cpu_based_vm_exec_control & CPU_BASED_NMI_WINDOW_EXITING) && - !((vmcs12->cpu_based_vm_exec_control & CPU_BASED_INTR_WINDOW_EXITING) && - (vmcs12->guest_rflags & X86_EFLAGS_IF))) { + switch (vmcs12->guest_activity_state) { + case GUEST_ACTIVITY_HLT: + /* + * If we're entering a halted L2 vcpu and the L2 vcpu won't be + * awakened by event injection or by an NMI-window VM-exit or + * by an interrupt-window VM-exit, halt the vcpu. + */ + if (!(vmcs12->vm_entry_intr_info_field & INTR_INFO_VALID_MASK) && + !nested_cpu_has(vmcs12, CPU_BASED_NMI_WINDOW_EXITING) && + !(nested_cpu_has(vmcs12, CPU_BASED_INTR_WINDOW_EXITING) && + (vmcs12->guest_rflags & X86_EFLAGS_IF))) { + vmx->nested.nested_run_pending = 0; + return kvm_vcpu_halt(vcpu); + } + break; + case GUEST_ACTIVITY_WAIT_SIPI: vmx->nested.nested_run_pending = 0; - return kvm_vcpu_halt(vcpu); + vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED; + break; + default: + break; } + return 1; vmentry_failed: @@ -3797,7 +3827,20 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu) return -EBUSY; nested_vmx_update_pending_dbg(vcpu); clear_bit(KVM_APIC_INIT, &apic->pending_events); - nested_vmx_vmexit(vcpu, EXIT_REASON_INIT_SIGNAL, 0, 0); + if (vcpu->arch.mp_state != KVM_MP_STATE_INIT_RECEIVED) + nested_vmx_vmexit(vcpu, EXIT_REASON_INIT_SIGNAL, 0, 0); + return 0; + } + + if (lapic_in_kernel(vcpu) && + test_bit(KVM_APIC_SIPI, &apic->pending_events)) { + if (block_nested_events) + return -EBUSY; + + clear_bit(KVM_APIC_SIPI, &apic->pending_events); + if (vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) + nested_vmx_vmexit(vcpu, EXIT_REASON_SIPI_SIGNAL, 0, + apic->sipi_vector & 0xFFUL); return 0; } @@ -4036,6 +4079,8 @@ static void sync_vmcs02_to_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED) vmcs12->guest_activity_state = GUEST_ACTIVITY_HLT; + else if (vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) + vmcs12->guest_activity_state = GUEST_ACTIVITY_WAIT_SIPI; else vmcs12->guest_activity_state = GUEST_ACTIVITY_ACTIVE; @@ -4416,6 +4461,8 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, /* trying to cancel vmlaunch/vmresume is a bug */ WARN_ON_ONCE(vmx->nested.nested_run_pending); + kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); + /* Service the TLB flush request for L2 before switching to L1. */ if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) kvm_vcpu_flush_tlb_current(vcpu); @@ -4814,7 +4861,7 @@ static int handle_vmon(struct kvm_vcpu *vcpu) /* * The Intel VMX Instruction Reference lists a bunch of bits that are * prerequisite to running VMXON, most notably cr4.VMXE must be set to - * 1 (see vmx_set_cr4() for when we allow the guest to set this). + * 1 (see vmx_is_valid_cr4() for when we allow the guest to set this). * Otherwise, we should fail with #UD. But most faulting conditions * have already been checked by hardware, prior to the VM-exit for * VMXON. We do test guest cr4.VMXE because processor CR4 always has @@ -6049,11 +6096,14 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu, if (is_guest_mode(vcpu)) { sync_vmcs02_to_vmcs12(vcpu, vmcs12); sync_vmcs02_to_vmcs12_rare(vcpu, vmcs12); - } else if (!vmx->nested.need_vmcs12_to_shadow_sync) { - if (vmx->nested.hv_evmcs) - copy_enlightened_to_vmcs12(vmx); - else if (enable_shadow_vmcs) - copy_shadow_to_vmcs12(vmx); + } else { + copy_vmcs02_to_vmcs12_rare(vcpu, get_vmcs12(vcpu)); + if (!vmx->nested.need_vmcs12_to_shadow_sync) { + if (vmx->nested.hv_evmcs) + copy_enlightened_to_vmcs12(vmx); + else if (enable_shadow_vmcs) + copy_shadow_to_vmcs12(vmx); + } } BUILD_BUG_ON(sizeof(user_vmx_nested_state->vmcs12) < VMCS12_SIZE); @@ -6483,7 +6533,8 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps) msrs->misc_low |= MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS | VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE | - VMX_MISC_ACTIVITY_HLT; + VMX_MISC_ACTIVITY_HLT | + VMX_MISC_ACTIVITY_WAIT_SIPI; msrs->misc_high = 0; /* @@ -6573,7 +6624,7 @@ struct kvm_x86_nested_ops vmx_nested_ops = { .hv_timer_pending = nested_vmx_preemption_timer_pending, .get_state = vmx_get_nested_state, .set_state = vmx_set_nested_state, - .get_nested_state_pages = nested_get_vmcs12_pages, + .get_nested_state_pages = vmx_get_nested_state_pages, .write_log_dirty = nested_vmx_write_pml_buffer, .enable_evmcs = nested_enable_evmcs, .get_evmcs_version = nested_get_evmcs_version, diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index a886a47daebd..cdf5f34518f4 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -29,7 +29,7 @@ static struct kvm_event_hw_type_mapping intel_arch_events[] = { [4] = { 0x2e, 0x41, PERF_COUNT_HW_CACHE_MISSES }, [5] = { 0xc4, 0x00, PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, [6] = { 0xc5, 0x00, PERF_COUNT_HW_BRANCH_MISSES }, - [7] = { 0x00, 0x30, PERF_COUNT_HW_REF_CPU_CYCLES }, + [7] = { 0x00, 0x03, PERF_COUNT_HW_REF_CPU_CYCLES }, }; /* mapping between fixed pmc index and intel_arch_events array */ @@ -345,7 +345,9 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) pmu->nr_arch_gp_counters = min_t(int, eax.split.num_counters, x86_pmu.num_counters_gp); + eax.split.bit_width = min_t(int, eax.split.bit_width, x86_pmu.bit_width_gp); pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << eax.split.bit_width) - 1; + eax.split.mask_length = min_t(int, eax.split.mask_length, x86_pmu.events_mask_len); pmu->available_event_types = ~entry->ebx & ((1ull << eax.split.mask_length) - 1); @@ -355,6 +357,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) pmu->nr_arch_fixed_counters = min_t(int, edx.split.num_counters_fixed, x86_pmu.num_counters_fixed); + edx.split.bit_width_fixed = min_t(int, + edx.split.bit_width_fixed, x86_pmu.bit_width_fixed); pmu->counter_bitmask[KVM_PMC_FIXED] = ((u64)1 << edx.split.bit_width_fixed) - 1; } diff --git a/arch/x86/kvm/vmx/vmenter.S b/arch/x86/kvm/vmx/vmenter.S index 90ad7a6246e3..e85aa5faa22d 100644 --- a/arch/x86/kvm/vmx/vmenter.S +++ b/arch/x86/kvm/vmx/vmenter.S @@ -132,7 +132,7 @@ SYM_FUNC_START(__vmx_vcpu_run) mov (%_ASM_SP), %_ASM_AX /* Check if vmlaunch or vmresume is needed */ - cmpb $0, %bl + testb %bl, %bl /* Load guest registers. Don't clobber flags. */ mov VCPU_RCX(%_ASM_AX), %_ASM_CX diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 47b8357b9751..cc60b1fc3ee7 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -40,7 +40,6 @@ #include <asm/irq_remapping.h> #include <asm/kexec.h> #include <asm/perf_event.h> -#include <asm/mce.h> #include <asm/mmu_context.h> #include <asm/mshyperv.h> #include <asm/mwait.h> @@ -1826,7 +1825,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) break; case MSR_IA32_SPEC_CTRL: if (!msr_info->host_initiated && - !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL)) + !guest_has_spec_ctrl_msr(vcpu)) return 1; msr_info->data = to_vmx(vcpu)->spec_ctrl; @@ -2028,7 +2027,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) break; case MSR_IA32_SPEC_CTRL: if (!msr_info->host_initiated && - !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL)) + !guest_has_spec_ctrl_msr(vcpu)) return 1; if (kvm_spec_ctrl_test_value(data)) @@ -2063,12 +2062,12 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) goto find_uret_msr; case MSR_IA32_PRED_CMD: if (!msr_info->host_initiated && - !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL)) + !guest_has_pred_cmd_msr(vcpu)) return 1; if (data & ~PRED_CMD_IBPB) return 1; - if (!boot_cpu_has(X86_FEATURE_SPEC_CTRL)) + if (!boot_cpu_has(X86_FEATURE_IBPB)) return 1; if (!data) break; @@ -3095,8 +3094,25 @@ static void vmx_load_mmu_pgd(struct kvm_vcpu *vcpu, unsigned long pgd, vmcs_writel(GUEST_CR3, guest_cr3); } -int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) +static bool vmx_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) { + /* + * We operate under the default treatment of SMM, so VMX cannot be + * enabled under SMM. Note, whether or not VMXE is allowed at all is + * handled by kvm_is_valid_cr4(). + */ + if ((cr4 & X86_CR4_VMXE) && is_smm(vcpu)) + return false; + + if (to_vmx(vcpu)->nested.vmxon && !nested_cr4_valid(vcpu, cr4)) + return false; + + return true; +} + +void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) +{ + unsigned long old_cr4 = vcpu->arch.cr4; struct vcpu_vmx *vmx = to_vmx(vcpu); /* * Pass through host's Machine Check Enable value to hw_cr4, which @@ -3123,21 +3139,6 @@ int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) } } - if (cr4 & X86_CR4_VMXE) { - /* - * To use VMXON (and later other VMX instructions), a guest - * must first be able to turn on cr4.VMXE (see handle_vmon()). - * So basically the check on whether to allow nested VMX - * is here. We operate under the default treatment of SMM, - * so VMX cannot be enabled under SMM. - */ - if (!nested_vmx_allowed(vcpu) || is_smm(vcpu)) - return 1; - } - - if (vmx->nested.vmxon && !nested_cr4_valid(vcpu, cr4)) - return 1; - vcpu->arch.cr4 = cr4; kvm_register_mark_available(vcpu, VCPU_EXREG_CR4); @@ -3168,7 +3169,9 @@ int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) vmcs_writel(CR4_READ_SHADOW, cr4); vmcs_writel(GUEST_CR4, hw_cr4); - return 0; + + if ((cr4 ^ old_cr4) & (X86_CR4_OSXSAVE | X86_CR4_PKE)) + kvm_update_cpuid_runtime(vcpu); } void vmx_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) @@ -3515,42 +3518,33 @@ bool __vmx_guest_state_valid(struct kvm_vcpu *vcpu) return true; } -static int init_rmode_tss(struct kvm *kvm) +static int init_rmode_tss(struct kvm *kvm, void __user *ua) { - gfn_t fn; - u16 data = 0; - int idx, r; + const void *zero_page = (const void *) __va(page_to_phys(ZERO_PAGE(0))); + u16 data; + int i; + + for (i = 0; i < 3; i++) { + if (__copy_to_user(ua + PAGE_SIZE * i, zero_page, PAGE_SIZE)) + return -EFAULT; + } - idx = srcu_read_lock(&kvm->srcu); - fn = to_kvm_vmx(kvm)->tss_addr >> PAGE_SHIFT; - r = kvm_clear_guest_page(kvm, fn, 0, PAGE_SIZE); - if (r < 0) - goto out; data = TSS_BASE_SIZE + TSS_REDIRECTION_SIZE; - r = kvm_write_guest_page(kvm, fn++, &data, - TSS_IOPB_BASE_OFFSET, sizeof(u16)); - if (r < 0) - goto out; - r = kvm_clear_guest_page(kvm, fn++, 0, PAGE_SIZE); - if (r < 0) - goto out; - r = kvm_clear_guest_page(kvm, fn, 0, PAGE_SIZE); - if (r < 0) - goto out; + if (__copy_to_user(ua + TSS_IOPB_BASE_OFFSET, &data, sizeof(u16))) + return -EFAULT; + data = ~0; - r = kvm_write_guest_page(kvm, fn, &data, - RMODE_TSS_SIZE - 2 * PAGE_SIZE - 1, - sizeof(u8)); -out: - srcu_read_unlock(&kvm->srcu, idx); - return r; + if (__copy_to_user(ua + RMODE_TSS_SIZE - 1, &data, sizeof(u8))) + return -EFAULT; + + return 0; } static int init_rmode_identity_map(struct kvm *kvm) { struct kvm_vmx *kvm_vmx = to_kvm_vmx(kvm); int i, r = 0; - kvm_pfn_t identity_map_pfn; + void __user *uaddr; u32 tmp; /* Protect kvm_vmx->ept_identity_pagetable_done. */ @@ -3561,24 +3555,24 @@ static int init_rmode_identity_map(struct kvm *kvm) if (!kvm_vmx->ept_identity_map_addr) kvm_vmx->ept_identity_map_addr = VMX_EPT_IDENTITY_PAGETABLE_ADDR; - identity_map_pfn = kvm_vmx->ept_identity_map_addr >> PAGE_SHIFT; - r = __x86_set_memory_region(kvm, IDENTITY_PAGETABLE_PRIVATE_MEMSLOT, - kvm_vmx->ept_identity_map_addr, PAGE_SIZE); - if (r < 0) + uaddr = __x86_set_memory_region(kvm, + IDENTITY_PAGETABLE_PRIVATE_MEMSLOT, + kvm_vmx->ept_identity_map_addr, + PAGE_SIZE); + if (IS_ERR(uaddr)) { + r = PTR_ERR(uaddr); goto out; + } - r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE); - if (r < 0) - goto out; /* Set up identity-mapping pagetable for EPT in real mode */ for (i = 0; i < PT32_ENT_PER_PAGE; i++) { tmp = (i << 22) + (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE); - r = kvm_write_guest_page(kvm, identity_map_pfn, - &tmp, i * sizeof(tmp), sizeof(tmp)); - if (r < 0) + if (__copy_to_user(uaddr + i * sizeof(tmp), &tmp, sizeof(tmp))) { + r = -EFAULT; goto out; + } } kvm_vmx->ept_identity_pagetable_done = true; @@ -3605,19 +3599,22 @@ static void seg_setup(int seg) static int alloc_apic_access_page(struct kvm *kvm) { struct page *page; - int r = 0; + void __user *hva; + int ret = 0; mutex_lock(&kvm->slots_lock); if (kvm->arch.apic_access_page_done) goto out; - r = __x86_set_memory_region(kvm, APIC_ACCESS_PAGE_PRIVATE_MEMSLOT, - APIC_DEFAULT_PHYS_BASE, PAGE_SIZE); - if (r) + hva = __x86_set_memory_region(kvm, APIC_ACCESS_PAGE_PRIVATE_MEMSLOT, + APIC_DEFAULT_PHYS_BASE, PAGE_SIZE); + if (IS_ERR(hva)) { + ret = PTR_ERR(hva); goto out; + } page = gfn_to_page(kvm, APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT); if (is_error_page(page)) { - r = -EFAULT; + ret = -EFAULT; goto out; } @@ -3629,7 +3626,7 @@ static int alloc_apic_access_page(struct kvm *kvm) kvm->arch.apic_access_page_done = true; out: mutex_unlock(&kvm->slots_lock); - return r; + return ret; } int allocate_vpid(void) @@ -4638,7 +4635,7 @@ static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu, bool for_injection) static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr) { - int ret; + void __user *ret; if (enable_unrestricted_guest) return 0; @@ -4648,10 +4645,12 @@ static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr) PAGE_SIZE * 3); mutex_unlock(&kvm->slots_lock); - if (ret) - return ret; + if (IS_ERR(ret)) + return PTR_ERR(ret); + to_kvm_vmx(kvm)->tss_addr = addr; - return init_rmode_tss(kvm); + + return init_rmode_tss(kvm, ret); } static int vmx_set_identity_map_addr(struct kvm *kvm, u64 ident_addr) @@ -4716,25 +4715,6 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu, return 1; } -/* - * Trigger machine check on the host. We assume all the MSRs are already set up - * by the CPU and that we still run on the same CPU as the MCE occurred on. - * We pass a fake environment to the machine check handler because we want - * the guest to be always treated like user space, no matter what context - * it used internally. - */ -static void kvm_machine_check(void) -{ -#if defined(CONFIG_X86_MCE) - struct pt_regs regs = { - .cs = 3, /* Fake ring 3 no matter what the guest ran on */ - .flags = X86_EFLAGS_IF, - }; - - do_machine_check(®s); -#endif -} - static int handle_machine_check(struct kvm_vcpu *vcpu) { /* handled by vmx_vcpu_run() */ @@ -6399,7 +6379,11 @@ static void vmx_handle_exit_irqoff(struct kvm_vcpu *vcpu) handle_exception_nmi_irqoff(vmx); } -static bool vmx_has_emulated_msr(u32 index) +/* + * The kvm parameter can be NULL (module initialization, or invocation before + * VM creation). Be sure to check the kvm parameter before using it. + */ +static bool vmx_has_emulated_msr(struct kvm *kvm, u32 index) { switch (index) { case MSR_IA32_SMBASE: @@ -6669,6 +6653,8 @@ reenter_guest: if (vmx->emulation_required) return EXIT_FASTPATH_NONE; + trace_kvm_entry(vcpu); + if (vmx->ple_window_dirty) { vmx->ple_window_dirty = false; vmcs_write32(PLE_WINDOW, vmx->ple_window); @@ -7558,7 +7544,7 @@ static void enable_smi_window(struct kvm_vcpu *vcpu) static bool vmx_apic_init_signal_blocked(struct kvm_vcpu *vcpu) { - return to_vmx(vcpu)->nested.vmxon; + return to_vmx(vcpu)->nested.vmxon && !is_guest_mode(vcpu); } static void vmx_migrate_timers(struct kvm_vcpu *vcpu) @@ -7587,6 +7573,11 @@ static bool vmx_check_apicv_inhibit_reasons(ulong bit) return supported & BIT(bit); } +static int vmx_cpu_dirty_log_size(void) +{ + return enable_pml ? PML_ENTITY_NUM : 0; +} + static struct kvm_x86_ops vmx_x86_ops __initdata = { .hardware_unsetup = hardware_unsetup, @@ -7616,6 +7607,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { .get_cpl = vmx_get_cpl, .get_cs_db_l_bits = vmx_get_cs_db_l_bits, .set_cr0 = vmx_set_cr0, + .is_valid_cr4 = vmx_is_valid_cr4, .set_cr4 = vmx_set_cr4, .set_efer = vmx_set_efer, .get_idt = vmx_get_idt, @@ -7715,6 +7707,10 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { .migrate_timers = vmx_migrate_timers, .msr_filter_changed = vmx_msr_filter_changed, + .complete_emulated_msr = kvm_complete_insn_gp, + .cpu_dirty_log_size = vmx_cpu_dirty_log_size, + + .vcpu_deliver_sipi_vector = kvm_vcpu_deliver_sipi_vector, }; static __init int hardware_setup(void) @@ -7832,6 +7828,7 @@ static __init int hardware_setup(void) vmx_x86_ops.slot_disable_log_dirty = NULL; vmx_x86_ops.flush_log_dirty = NULL; vmx_x86_ops.enable_log_dirty_pt_masked = NULL; + vmx_x86_ops.cpu_dirty_log_size = NULL; } if (!cpu_has_vmx_preemption_timer()) diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index f6f66e5c6510..9d3a557949ac 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -321,7 +321,7 @@ u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu); void vmx_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask); int vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer); void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); -int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); +void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); void set_cr4_guest_host_mask(struct vcpu_vmx *vmx); void ept_save_pdptrs(struct kvm_vcpu *vcpu); void vmx_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e545a8a613b1..76bce832cade 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -105,6 +105,7 @@ static u64 __read_mostly cr4_reserved_bits = CR4_RESERVED_BITS; static void update_cr8_intercept(struct kvm_vcpu *vcpu); static void process_nmi(struct kvm_vcpu *vcpu); +static void process_smi(struct kvm_vcpu *vcpu); static void enter_smm(struct kvm_vcpu *vcpu); static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags); static void store_regs(struct kvm_vcpu *vcpu); @@ -197,7 +198,8 @@ EXPORT_SYMBOL_GPL(host_efer); bool __read_mostly allow_smaller_maxphyaddr = 0; EXPORT_SYMBOL_GPL(allow_smaller_maxphyaddr); -static u64 __read_mostly host_xss; +u64 __read_mostly host_xss; +EXPORT_SYMBOL_GPL(host_xss); u64 __read_mostly supported_xss; EXPORT_SYMBOL_GPL(supported_xss); @@ -804,11 +806,29 @@ bool pdptrs_changed(struct kvm_vcpu *vcpu) } EXPORT_SYMBOL_GPL(pdptrs_changed); +void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned long cr0) +{ + unsigned long update_bits = X86_CR0_PG | X86_CR0_WP; + + if ((cr0 ^ old_cr0) & X86_CR0_PG) { + kvm_clear_async_pf_completion_queue(vcpu); + kvm_async_pf_hash_reset(vcpu); + } + + if ((cr0 ^ old_cr0) & update_bits) + kvm_mmu_reset_context(vcpu); + + if (((cr0 ^ old_cr0) & X86_CR0_CD) && + kvm_arch_has_noncoherent_dma(vcpu->kvm) && + !kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED)) + kvm_zap_gfn_range(vcpu->kvm, 0, ~0ULL); +} +EXPORT_SYMBOL_GPL(kvm_post_set_cr0); + int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) { unsigned long old_cr0 = kvm_read_cr0(vcpu); unsigned long pdptr_bits = X86_CR0_CD | X86_CR0_NW | X86_CR0_PG; - unsigned long update_bits = X86_CR0_PG | X86_CR0_WP; cr0 |= X86_CR0_ET; @@ -847,18 +867,7 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) kvm_x86_ops.set_cr0(vcpu, cr0); - if ((cr0 ^ old_cr0) & X86_CR0_PG) { - kvm_clear_async_pf_completion_queue(vcpu); - kvm_async_pf_hash_reset(vcpu); - } - - if ((cr0 ^ old_cr0) & update_bits) - kvm_mmu_reset_context(vcpu); - - if (((cr0 ^ old_cr0) & X86_CR0_CD) && - kvm_arch_has_noncoherent_dma(vcpu->kvm) && - !kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED)) - kvm_zap_gfn_range(vcpu->kvm, 0, ~0ULL); + kvm_post_set_cr0(vcpu, old_cr0, cr0); return 0; } @@ -872,6 +881,9 @@ EXPORT_SYMBOL_GPL(kvm_lmsw); void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu) { + if (vcpu->arch.guest_state_protected) + return; + if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE)) { if (vcpu->arch.xcr0 != host_xcr0) @@ -892,6 +904,9 @@ EXPORT_SYMBOL_GPL(kvm_load_guest_xsave_state); void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu) { + if (vcpu->arch.guest_state_protected) + return; + if (static_cpu_has(X86_FEATURE_PKU) && (kvm_read_cr4_bits(vcpu, X86_CR4_PKE) || (vcpu->arch.xcr0 & XFEATURE_MASK_PKRU))) { @@ -964,26 +979,36 @@ int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) } EXPORT_SYMBOL_GPL(kvm_set_xcr); -int kvm_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) +bool kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) { if (cr4 & cr4_reserved_bits) - return -EINVAL; + return false; if (cr4 & vcpu->arch.cr4_guest_rsvd_bits) - return -EINVAL; + return false; - return 0; + return kvm_x86_ops.is_valid_cr4(vcpu, cr4); +} +EXPORT_SYMBOL_GPL(kvm_is_valid_cr4); + +void kvm_post_set_cr4(struct kvm_vcpu *vcpu, unsigned long old_cr4, unsigned long cr4) +{ + unsigned long mmu_role_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE | + X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE; + + if (((cr4 ^ old_cr4) & mmu_role_bits) || + (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE))) + kvm_mmu_reset_context(vcpu); } -EXPORT_SYMBOL_GPL(kvm_valid_cr4); +EXPORT_SYMBOL_GPL(kvm_post_set_cr4); int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) { unsigned long old_cr4 = kvm_read_cr4(vcpu); unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_SMEP; - unsigned long mmu_role_bits = pdptr_bits | X86_CR4_SMAP | X86_CR4_PKE; - if (kvm_valid_cr4(vcpu, cr4)) + if (!kvm_is_valid_cr4(vcpu, cr4)) return 1; if (is_long_mode(vcpu)) { @@ -1006,15 +1031,9 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) return 1; } - if (kvm_x86_ops.set_cr4(vcpu, cr4)) - return 1; + kvm_x86_ops.set_cr4(vcpu, cr4); - if (((cr4 ^ old_cr4) & mmu_role_bits) || - (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE))) - kvm_mmu_reset_context(vcpu); - - if ((cr4 ^ old_cr4) & (X86_CR4_OSXSAVE | X86_CR4_PKE)) - kvm_update_cpuid_runtime(vcpu); + kvm_post_set_cr4(vcpu, old_cr4, cr4); return 0; } @@ -1638,27 +1657,20 @@ int kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data) } EXPORT_SYMBOL_GPL(kvm_set_msr); -static int complete_emulated_msr(struct kvm_vcpu *vcpu, bool is_read) +static int complete_emulated_rdmsr(struct kvm_vcpu *vcpu) { - if (vcpu->run->msr.error) { - kvm_inject_gp(vcpu, 0); - return 1; - } else if (is_read) { + int err = vcpu->run->msr.error; + if (!err) { kvm_rax_write(vcpu, (u32)vcpu->run->msr.data); kvm_rdx_write(vcpu, vcpu->run->msr.data >> 32); } - return kvm_skip_emulated_instruction(vcpu); -} - -static int complete_emulated_rdmsr(struct kvm_vcpu *vcpu) -{ - return complete_emulated_msr(vcpu, true); + return kvm_x86_ops.complete_emulated_msr(vcpu, err); } static int complete_emulated_wrmsr(struct kvm_vcpu *vcpu) { - return complete_emulated_msr(vcpu, false); + return kvm_x86_ops.complete_emulated_msr(vcpu, vcpu->run->msr.error); } static u64 kvm_msr_reason(int r) @@ -1721,18 +1733,16 @@ int kvm_emulate_rdmsr(struct kvm_vcpu *vcpu) return 0; } - /* MSR read failed? Inject a #GP */ - if (r) { + if (!r) { + trace_kvm_msr_read(ecx, data); + + kvm_rax_write(vcpu, data & -1u); + kvm_rdx_write(vcpu, (data >> 32) & -1u); + } else { trace_kvm_msr_read_ex(ecx); - kvm_inject_gp(vcpu, 0); - return 1; } - trace_kvm_msr_read(ecx, data); - - kvm_rax_write(vcpu, data & -1u); - kvm_rdx_write(vcpu, (data >> 32) & -1u); - return kvm_skip_emulated_instruction(vcpu); + return kvm_x86_ops.complete_emulated_msr(vcpu, r); } EXPORT_SYMBOL_GPL(kvm_emulate_rdmsr); @@ -1753,15 +1763,12 @@ int kvm_emulate_wrmsr(struct kvm_vcpu *vcpu) if (r < 0) return r; - /* MSR write failed? Inject a #GP */ - if (r > 0) { + if (!r) + trace_kvm_msr_write(ecx, data); + else trace_kvm_msr_write_ex(ecx, data); - kvm_inject_gp(vcpu, 0); - return 1; - } - trace_kvm_msr_write(ecx, data); - return kvm_skip_emulated_instruction(vcpu); + return kvm_x86_ops.complete_emulated_msr(vcpu, r); } EXPORT_SYMBOL_GPL(kvm_emulate_wrmsr); @@ -3678,6 +3685,27 @@ static inline bool kvm_can_mwait_in_guest(void) boot_cpu_has(X86_FEATURE_ARAT); } +static int kvm_ioctl_get_supported_hv_cpuid(struct kvm_vcpu *vcpu, + struct kvm_cpuid2 __user *cpuid_arg) +{ + struct kvm_cpuid2 cpuid; + int r; + + r = -EFAULT; + if (copy_from_user(&cpuid, cpuid_arg, sizeof(cpuid))) + return r; + + r = kvm_get_hv_cpuid(vcpu, &cpuid, cpuid_arg->entries); + if (r) + return r; + + r = -EFAULT; + if (copy_to_user(cpuid_arg, &cpuid, sizeof(cpuid))) + return r; + + return 0; +} + int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) { int r = 0; @@ -3714,6 +3742,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_HYPERV_TLBFLUSH: case KVM_CAP_HYPERV_SEND_IPI: case KVM_CAP_HYPERV_CPUID: + case KVM_CAP_SYS_HYPERV_CPUID: case KVM_CAP_PCI_SEGMENT: case KVM_CAP_DEBUGREGS: case KVM_CAP_X86_ROBUST_SINGLESTEP: @@ -3762,7 +3791,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) * fringe case that is not enabled except via specific settings * of the module parameters. */ - r = kvm_x86_ops.has_emulated_msr(MSR_IA32_SMBASE); + r = kvm_x86_ops.has_emulated_msr(kvm, MSR_IA32_SMBASE); break; case KVM_CAP_VAPIC: r = !kvm_x86_ops.cpu_has_accelerated_tpr(); @@ -3899,6 +3928,9 @@ long kvm_arch_dev_ioctl(struct file *filp, case KVM_GET_MSRS: r = msr_io(NULL, argp, do_get_msr_feature, 1); break; + case KVM_GET_SUPPORTED_HV_CPUID: + r = kvm_ioctl_get_supported_hv_cpuid(NULL, argp); + break; default: r = -EINVAL; break; @@ -3997,7 +4029,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { int idx; - if (vcpu->preempted) + if (vcpu->preempted && !vcpu->arch.guest_state_protected) vcpu->arch.preempted_in_kernel = !kvm_x86_ops.get_cpl(vcpu); /* @@ -4199,6 +4231,9 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, { process_nmi(vcpu); + if (kvm_check_request(KVM_REQ_SMI, vcpu)) + process_smi(vcpu); + /* * In guest mode, payload delivery should be deferred, * so that the L1 hypervisor can intercept #PF before @@ -4481,6 +4516,9 @@ static void load_xsave(struct kvm_vcpu *vcpu, u8 *src) static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, struct kvm_xsave *guest_xsave) { + if (!vcpu->arch.guest_fpu) + return; + if (boot_cpu_has(X86_FEATURE_XSAVE)) { memset(guest_xsave, 0, sizeof(struct kvm_xsave)); fill_xsave((u8 *) guest_xsave->region, vcpu); @@ -4498,9 +4536,14 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, struct kvm_xsave *guest_xsave) { - u64 xstate_bv = - *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)]; - u32 mxcsr = *(u32 *)&guest_xsave->region[XSAVE_MXCSR_OFFSET / sizeof(u32)]; + u64 xstate_bv; + u32 mxcsr; + + if (!vcpu->arch.guest_fpu) + return 0; + + xstate_bv = *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)]; + mxcsr = *(u32 *)&guest_xsave->region[XSAVE_MXCSR_OFFSET / sizeof(u32)]; if (boot_cpu_has(X86_FEATURE_XSAVE)) { /* @@ -4977,25 +5020,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, srcu_read_unlock(&vcpu->kvm->srcu, idx); break; } - case KVM_GET_SUPPORTED_HV_CPUID: { - struct kvm_cpuid2 __user *cpuid_arg = argp; - struct kvm_cpuid2 cpuid; - - r = -EFAULT; - if (copy_from_user(&cpuid, cpuid_arg, sizeof(cpuid))) - goto out; - - r = kvm_vcpu_ioctl_get_hv_cpuid(vcpu, &cpuid, - cpuid_arg->entries); - if (r) - goto out; - - r = -EFAULT; - if (copy_to_user(cpuid_arg, &cpuid, sizeof(cpuid))) - goto out; - r = 0; + case KVM_GET_SUPPORTED_HV_CPUID: + r = kvm_ioctl_get_supported_hv_cpuid(vcpu, argp); break; - } default: r = -EINVAL; } @@ -5776,7 +5803,7 @@ static void kvm_init_msr_list(void) } for (i = 0; i < ARRAY_SIZE(emulated_msrs_all); i++) { - if (!kvm_x86_ops.has_emulated_msr(emulated_msrs_all[i])) + if (!kvm_x86_ops.has_emulated_msr(NULL, emulated_msrs_all[i])) continue; emulated_msrs[num_emulated_msrs++] = emulated_msrs_all[i]; @@ -7953,17 +7980,22 @@ void kvm_arch_exit(void) kmem_cache_destroy(x86_fpu_cache); } -int kvm_vcpu_halt(struct kvm_vcpu *vcpu) +static int __kvm_vcpu_halt(struct kvm_vcpu *vcpu, int state, int reason) { ++vcpu->stat.halt_exits; if (lapic_in_kernel(vcpu)) { - vcpu->arch.mp_state = KVM_MP_STATE_HALTED; + vcpu->arch.mp_state = state; return 1; } else { - vcpu->run->exit_reason = KVM_EXIT_HLT; + vcpu->run->exit_reason = reason; return 0; } } + +int kvm_vcpu_halt(struct kvm_vcpu *vcpu) +{ + return __kvm_vcpu_halt(vcpu, KVM_MP_STATE_HALTED, KVM_EXIT_HLT); +} EXPORT_SYMBOL_GPL(kvm_vcpu_halt); int kvm_emulate_halt(struct kvm_vcpu *vcpu) @@ -7977,6 +8009,14 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu) } EXPORT_SYMBOL_GPL(kvm_emulate_halt); +int kvm_emulate_ap_reset_hold(struct kvm_vcpu *vcpu) +{ + int ret = kvm_skip_emulated_instruction(vcpu); + + return __kvm_vcpu_halt(vcpu, KVM_MP_STATE_AP_RESET_HOLD, KVM_EXIT_AP_RESET_HOLD) && ret; +} +EXPORT_SYMBOL_GPL(kvm_emulate_ap_reset_hold); + #ifdef CONFIG_X86_64 static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr, unsigned long clock_type) @@ -8158,7 +8198,14 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu) { struct kvm_run *kvm_run = vcpu->run; - kvm_run->if_flag = (kvm_get_rflags(vcpu) & X86_EFLAGS_IF) != 0; + /* + * if_flag is obsolete and useless, so do not bother + * setting it for SEV-ES guests. Userspace can just + * use kvm_run->ready_for_interrupt_injection. + */ + kvm_run->if_flag = !vcpu->arch.guest_state_protected + && (kvm_get_rflags(vcpu) & X86_EFLAGS_IF) != 0; + kvm_run->flags = is_smm(vcpu) ? KVM_RUN_X86_SMM : 0; kvm_run->cr8 = kvm_get_cr8(vcpu); kvm_run->apic_base = kvm_get_apic_base(vcpu); @@ -8748,6 +8795,15 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) bool req_immediate_exit = false; + /* Forbid vmenter if vcpu dirty ring is soft-full */ + if (unlikely(vcpu->kvm->dirty_ring_size && + kvm_dirty_ring_soft_full(&vcpu->dirty_ring))) { + vcpu->run->exit_reason = KVM_EXIT_DIRTY_RING_FULL; + trace_kvm_dirty_ring_exit(vcpu); + r = 0; + goto out; + } + if (kvm_request_pending(vcpu)) { if (kvm_check_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu)) { if (unlikely(!kvm_x86_ops.nested_ops->get_nested_state_pages(vcpu))) { @@ -8934,8 +8990,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) kvm_x86_ops.request_immediate_exit(vcpu); } - trace_kvm_entry(vcpu); - fpregs_assert_state_consistent(); if (test_thread_flag(TIF_NEED_FPU_LOAD)) switch_fpu_return(); @@ -9055,6 +9109,7 @@ static inline int vcpu_block(struct kvm *kvm, struct kvm_vcpu *vcpu) kvm_apic_accept_events(vcpu); switch(vcpu->arch.mp_state) { case KVM_MP_STATE_HALTED: + case KVM_MP_STATE_AP_RESET_HOLD: vcpu->arch.pv.pv_unhalted = false; vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; @@ -9223,9 +9278,14 @@ static void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) kvm_save_current_fpu(vcpu->arch.user_fpu); - /* PKRU is separately restored in kvm_x86_ops.run. */ - __copy_kernel_to_fpregs(&vcpu->arch.guest_fpu->state, - ~XFEATURE_MASK_PKRU); + /* + * Guests with protected state can't have it set by the hypervisor, + * so skip trying to set it. + */ + if (vcpu->arch.guest_fpu) + /* PKRU is separately restored in kvm_x86_ops.run. */ + __copy_kernel_to_fpregs(&vcpu->arch.guest_fpu->state, + ~XFEATURE_MASK_PKRU); fpregs_mark_activate(); fpregs_unlock(); @@ -9238,7 +9298,12 @@ static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) { fpregs_lock(); - kvm_save_current_fpu(vcpu->arch.guest_fpu); + /* + * Guests with protected state can't have it read by the hypervisor, + * so skip trying to save it. + */ + if (vcpu->arch.guest_fpu) + kvm_save_current_fpu(vcpu->arch.guest_fpu); copy_kernel_to_fpregs(&vcpu->arch.user_fpu->state); @@ -9417,6 +9482,9 @@ static void __get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) { struct desc_ptr dt; + if (vcpu->arch.guest_state_protected) + goto skip_protected_regs; + kvm_get_segment(vcpu, &sregs->cs, VCPU_SREG_CS); kvm_get_segment(vcpu, &sregs->ds, VCPU_SREG_DS); kvm_get_segment(vcpu, &sregs->es, VCPU_SREG_ES); @@ -9434,9 +9502,11 @@ static void __get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) sregs->gdt.limit = dt.size; sregs->gdt.base = dt.address; - sregs->cr0 = kvm_read_cr0(vcpu); sregs->cr2 = vcpu->arch.cr2; sregs->cr3 = kvm_read_cr3(vcpu); + +skip_protected_regs: + sregs->cr0 = kvm_read_cr0(vcpu); sregs->cr4 = kvm_read_cr4(vcpu); sregs->cr8 = kvm_get_cr8(vcpu); sregs->efer = vcpu->arch.efer; @@ -9466,8 +9536,9 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, kvm_load_guest_fpu(vcpu); kvm_apic_accept_events(vcpu); - if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED && - vcpu->arch.pv.pv_unhalted) + if ((vcpu->arch.mp_state == KVM_MP_STATE_HALTED || + vcpu->arch.mp_state == KVM_MP_STATE_AP_RESET_HOLD) && + vcpu->arch.pv.pv_unhalted) mp_state->mp_state = KVM_MP_STATE_RUNNABLE; else mp_state->mp_state = vcpu->arch.mp_state; @@ -9535,7 +9606,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index, } EXPORT_SYMBOL_GPL(kvm_task_switch); -static int kvm_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +static bool kvm_is_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) { if ((sregs->efer & EFER_LME) && (sregs->cr0 & X86_CR0_PG)) { /* @@ -9543,31 +9614,29 @@ static int kvm_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) * 64-bit mode (though maybe in a 32-bit code segment). * CR4.PAE and EFER.LMA must be set. */ - if (!(sregs->cr4 & X86_CR4_PAE) - || !(sregs->efer & EFER_LMA)) - return -EINVAL; + if (!(sregs->cr4 & X86_CR4_PAE) || !(sregs->efer & EFER_LMA)) + return false; } else { /* * Not in 64-bit mode: EFER.LMA is clear and the code * segment cannot be 64-bit. */ if (sregs->efer & EFER_LMA || sregs->cs.l) - return -EINVAL; + return false; } - return kvm_valid_cr4(vcpu, sregs->cr4); + return kvm_is_valid_cr4(vcpu, sregs->cr4); } static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) { struct msr_data apic_base_msr; int mmu_reset_needed = 0; - int cpuid_update_needed = 0; int pending_vec, max_bits, idx; struct desc_ptr dt; int ret = -EINVAL; - if (kvm_valid_sregs(vcpu, sregs)) + if (!kvm_is_valid_sregs(vcpu, sregs)) goto out; apic_base_msr.data = sregs->apic_base; @@ -9575,6 +9644,9 @@ static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) if (kvm_set_apic_base(vcpu, &apic_base_msr)) goto out; + if (vcpu->arch.guest_state_protected) + goto skip_protected_regs; + dt.size = sregs->idt.limit; dt.address = sregs->idt.base; kvm_x86_ops.set_idt(vcpu, &dt); @@ -9597,11 +9669,7 @@ static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) vcpu->arch.cr0 = sregs->cr0; mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4; - cpuid_update_needed |= ((kvm_read_cr4(vcpu) ^ sregs->cr4) & - (X86_CR4_OSXSAVE | X86_CR4_PKE)); kvm_x86_ops.set_cr4(vcpu, sregs->cr4); - if (cpuid_update_needed) - kvm_update_cpuid_runtime(vcpu); idx = srcu_read_lock(&vcpu->kvm->srcu); if (is_pae_paging(vcpu)) { @@ -9613,14 +9681,6 @@ static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) if (mmu_reset_needed) kvm_mmu_reset_context(vcpu); - max_bits = KVM_NR_INTERRUPTS; - pending_vec = find_first_bit( - (const unsigned long *)sregs->interrupt_bitmap, max_bits); - if (pending_vec < max_bits) { - kvm_queue_interrupt(vcpu, pending_vec, false); - pr_debug("Set back pending irq %d\n", pending_vec); - } - kvm_set_segment(vcpu, &sregs->cs, VCPU_SREG_CS); kvm_set_segment(vcpu, &sregs->ds, VCPU_SREG_DS); kvm_set_segment(vcpu, &sregs->es, VCPU_SREG_ES); @@ -9639,6 +9699,15 @@ static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) !is_protmode(vcpu)) vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; +skip_protected_regs: + max_bits = KVM_NR_INTERRUPTS; + pending_vec = find_first_bit( + (const unsigned long *)sregs->interrupt_bitmap, max_bits); + if (pending_vec < max_bits) { + kvm_queue_interrupt(vcpu, pending_vec, false); + pr_debug("Set back pending irq %d\n", pending_vec); + } + kvm_make_request(KVM_REQ_EVENT, vcpu); ret = 0; @@ -9663,6 +9732,9 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, unsigned long rflags; int i, r; + if (vcpu->arch.guest_state_protected) + return -EINVAL; + vcpu_load(vcpu); if (dbg->control & (KVM_GUESTDBG_INJECT_DB | KVM_GUESTDBG_INJECT_BP)) { @@ -9742,6 +9814,9 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { struct fxregs_state *fxsave; + if (!vcpu->arch.guest_fpu) + return 0; + vcpu_load(vcpu); fxsave = &vcpu->arch.guest_fpu->state.fxsave; @@ -9762,6 +9837,9 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { struct fxregs_state *fxsave; + if (!vcpu->arch.guest_fpu) + return 0; + vcpu_load(vcpu); fxsave = &vcpu->arch.guest_fpu->state.fxsave; @@ -9820,6 +9898,9 @@ static int sync_regs(struct kvm_vcpu *vcpu) static void fx_init(struct kvm_vcpu *vcpu) { + if (!vcpu->arch.guest_fpu) + return; + fpstate_init(&vcpu->arch.guest_fpu->state); if (boot_cpu_has(X86_FEATURE_XSAVES)) vcpu->arch.guest_fpu->state.xsave.header.xcomp_bv = @@ -9833,6 +9914,15 @@ static void fx_init(struct kvm_vcpu *vcpu) vcpu->arch.cr0 |= X86_CR0_ET; } +void kvm_free_guest_fpu(struct kvm_vcpu *vcpu) +{ + if (vcpu->arch.guest_fpu) { + kmem_cache_free(x86_fpu_cache, vcpu->arch.guest_fpu); + vcpu->arch.guest_fpu = NULL; + } +} +EXPORT_SYMBOL_GPL(kvm_free_guest_fpu); + int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id) { if (kvm_check_tsc_unstable() && atomic_read(&kvm->online_vcpus) != 0) @@ -9869,7 +9959,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) r = -ENOMEM; - page = alloc_page(GFP_KERNEL | __GFP_ZERO); + page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); if (!page) goto fail_free_lapic; vcpu->arch.pio_data = page_address(page); @@ -9928,7 +10018,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) return 0; free_guest_fpu: - kmem_cache_free(x86_fpu_cache, vcpu->arch.guest_fpu); + kvm_free_guest_fpu(vcpu); free_user_fpu: kmem_cache_free(x86_fpu_cache, vcpu->arch.user_fpu); free_emulate_ctxt: @@ -9982,7 +10072,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) kmem_cache_free(x86_emulator_cache, vcpu->arch.emulate_ctxt); free_cpumask_var(vcpu->arch.wbinvd_dirty_mask); kmem_cache_free(x86_fpu_cache, vcpu->arch.user_fpu); - kmem_cache_free(x86_fpu_cache, vcpu->arch.guest_fpu); + kvm_free_guest_fpu(vcpu); kvm_hv_vcpu_uninit(vcpu); kvm_pmu_destroy(vcpu); @@ -10030,7 +10120,7 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) kvm_async_pf_hash_reset(vcpu); vcpu->arch.apf.halted = false; - if (kvm_mpx_supported()) { + if (vcpu->arch.guest_fpu && kvm_mpx_supported()) { void *mpx_state_buffer; /* @@ -10079,6 +10169,7 @@ void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) kvm_set_segment(vcpu, &cs, VCPU_SREG_CS); kvm_rip_write(vcpu, 0); } +EXPORT_SYMBOL_GPL(kvm_vcpu_deliver_sipi_vector); int kvm_arch_hardware_enable(void) { @@ -10349,7 +10440,32 @@ void kvm_arch_sync_events(struct kvm *kvm) kvm_free_pit(kvm); } -int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size) +#define ERR_PTR_USR(e) ((void __user *)ERR_PTR(e)) + +/** + * __x86_set_memory_region: Setup KVM internal memory slot + * + * @kvm: the kvm pointer to the VM. + * @id: the slot ID to setup. + * @gpa: the GPA to install the slot (unused when @size == 0). + * @size: the size of the slot. Set to zero to uninstall a slot. + * + * This function helps to setup a KVM internal memory slot. Specify + * @size > 0 to install a new slot, while @size == 0 to uninstall a + * slot. The return code can be one of the following: + * + * HVA: on success (uninstall will return a bogus HVA) + * -errno: on error + * + * The caller should always use IS_ERR() to check the return value + * before use. Note, the KVM internal memory slots are guaranteed to + * remain valid and unchanged until the VM is destroyed, i.e., the + * GPA->HVA translation will not change. However, the HVA is a user + * address, i.e. its accessibility is not guaranteed, and must be + * accessed via __copy_{to,from}_user(). + */ +void __user * __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, + u32 size) { int i, r; unsigned long hva, old_npages; @@ -10358,12 +10474,12 @@ int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size) /* Called with kvm->slots_lock held. */ if (WARN_ON(id >= KVM_MEM_SLOTS_NUM)) - return -EINVAL; + return ERR_PTR_USR(-EINVAL); slot = id_to_memslot(slots, id); if (size) { if (slot && slot->npages) - return -EEXIST; + return ERR_PTR_USR(-EEXIST); /* * MAP_SHARED to prevent internal slot pages from being moved @@ -10372,7 +10488,7 @@ int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size) hva = vm_mmap(NULL, 0, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0); if (IS_ERR((void *)hva)) - return PTR_ERR((void *)hva); + return (void __user *)hva; } else { if (!slot || !slot->npages) return 0; @@ -10391,13 +10507,13 @@ int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size) m.memory_size = size; r = __kvm_set_memory_region(kvm, &m); if (r < 0) - return r; + return ERR_PTR_USR(r); } if (!size) vm_munmap(hva, old_npages * PAGE_SIZE); - return 0; + return (void __user *)hva; } EXPORT_SYMBOL_GPL(__x86_set_memory_region); @@ -10754,6 +10870,10 @@ int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu) unsigned long kvm_get_linear_rip(struct kvm_vcpu *vcpu) { + /* Can't read the RIP when guest state is protected, just return 0 */ + if (vcpu->arch.guest_state_protected) + return 0; + if (is_64_bit_mode(vcpu)) return kvm_rip_read(vcpu); return (u32)(get_segment_base(vcpu, VCPU_SREG_CS) + @@ -11263,6 +11383,180 @@ int kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsigned long type, gva_t gva) } EXPORT_SYMBOL_GPL(kvm_handle_invpcid); +static int complete_sev_es_emulated_mmio(struct kvm_vcpu *vcpu) +{ + struct kvm_run *run = vcpu->run; + struct kvm_mmio_fragment *frag; + unsigned int len; + + BUG_ON(!vcpu->mmio_needed); + + /* Complete previous fragment */ + frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment]; + len = min(8u, frag->len); + if (!vcpu->mmio_is_write) + memcpy(frag->data, run->mmio.data, len); + + if (frag->len <= 8) { + /* Switch to the next fragment. */ + frag++; + vcpu->mmio_cur_fragment++; + } else { + /* Go forward to the next mmio piece. */ + frag->data += len; + frag->gpa += len; + frag->len -= len; + } + + if (vcpu->mmio_cur_fragment >= vcpu->mmio_nr_fragments) { + vcpu->mmio_needed = 0; + + // VMG change, at this point, we're always done + // RIP has already been advanced + return 1; + } + + // More MMIO is needed + run->mmio.phys_addr = frag->gpa; + run->mmio.len = min(8u, frag->len); + run->mmio.is_write = vcpu->mmio_is_write; + if (run->mmio.is_write) + memcpy(run->mmio.data, frag->data, min(8u, frag->len)); + run->exit_reason = KVM_EXIT_MMIO; + + vcpu->arch.complete_userspace_io = complete_sev_es_emulated_mmio; + + return 0; +} + +int kvm_sev_es_mmio_write(struct kvm_vcpu *vcpu, gpa_t gpa, unsigned int bytes, + void *data) +{ + int handled; + struct kvm_mmio_fragment *frag; + + if (!data) + return -EINVAL; + + handled = write_emultor.read_write_mmio(vcpu, gpa, bytes, data); + if (handled == bytes) + return 1; + + bytes -= handled; + gpa += handled; + data += handled; + + /*TODO: Check if need to increment number of frags */ + frag = vcpu->mmio_fragments; + vcpu->mmio_nr_fragments = 1; + frag->len = bytes; + frag->gpa = gpa; + frag->data = data; + + vcpu->mmio_needed = 1; + vcpu->mmio_cur_fragment = 0; + + vcpu->run->mmio.phys_addr = gpa; + vcpu->run->mmio.len = min(8u, frag->len); + vcpu->run->mmio.is_write = 1; + memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len)); + vcpu->run->exit_reason = KVM_EXIT_MMIO; + + vcpu->arch.complete_userspace_io = complete_sev_es_emulated_mmio; + + return 0; +} +EXPORT_SYMBOL_GPL(kvm_sev_es_mmio_write); + +int kvm_sev_es_mmio_read(struct kvm_vcpu *vcpu, gpa_t gpa, unsigned int bytes, + void *data) +{ + int handled; + struct kvm_mmio_fragment *frag; + + if (!data) + return -EINVAL; + + handled = read_emultor.read_write_mmio(vcpu, gpa, bytes, data); + if (handled == bytes) + return 1; + + bytes -= handled; + gpa += handled; + data += handled; + + /*TODO: Check if need to increment number of frags */ + frag = vcpu->mmio_fragments; + vcpu->mmio_nr_fragments = 1; + frag->len = bytes; + frag->gpa = gpa; + frag->data = data; + + vcpu->mmio_needed = 1; + vcpu->mmio_cur_fragment = 0; + + vcpu->run->mmio.phys_addr = gpa; + vcpu->run->mmio.len = min(8u, frag->len); + vcpu->run->mmio.is_write = 0; + vcpu->run->exit_reason = KVM_EXIT_MMIO; + + vcpu->arch.complete_userspace_io = complete_sev_es_emulated_mmio; + + return 0; +} +EXPORT_SYMBOL_GPL(kvm_sev_es_mmio_read); + +static int complete_sev_es_emulated_ins(struct kvm_vcpu *vcpu) +{ + memcpy(vcpu->arch.guest_ins_data, vcpu->arch.pio_data, + vcpu->arch.pio.count * vcpu->arch.pio.size); + vcpu->arch.pio.count = 0; + + return 1; +} + +static int kvm_sev_es_outs(struct kvm_vcpu *vcpu, unsigned int size, + unsigned int port, void *data, unsigned int count) +{ + int ret; + + ret = emulator_pio_out_emulated(vcpu->arch.emulate_ctxt, size, port, + data, count); + if (ret) + return ret; + + vcpu->arch.pio.count = 0; + + return 0; +} + +static int kvm_sev_es_ins(struct kvm_vcpu *vcpu, unsigned int size, + unsigned int port, void *data, unsigned int count) +{ + int ret; + + ret = emulator_pio_in_emulated(vcpu->arch.emulate_ctxt, size, port, + data, count); + if (ret) { + vcpu->arch.pio.count = 0; + } else { + vcpu->arch.guest_ins_data = data; + vcpu->arch.complete_userspace_io = complete_sev_es_emulated_ins; + } + + return 0; +} + +int kvm_sev_es_string_io(struct kvm_vcpu *vcpu, unsigned int size, + unsigned int port, void *data, unsigned int count, + int in) +{ + return in ? kvm_sev_es_ins(vcpu, size, port, data, count) + : kvm_sev_es_outs(vcpu, size, port, data, count); +} +EXPORT_SYMBOL_GPL(kvm_sev_es_string_io); + +EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_entry); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_fast_mmio); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq); @@ -11285,3 +11579,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_unaccelerated_access); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_incomplete_ipi); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_ga_log); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_apicv_update_request); +EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_enter); +EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_exit); +EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_msr_protocol_enter); +EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_msr_protocol_exit); diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index e7ca622a468f..c5ee0f5ce0f1 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -3,6 +3,7 @@ #define ARCH_X86_KVM_X86_H #include <linux/kvm_host.h> +#include <asm/mce.h> #include <asm/pvclock.h> #include "kvm_cache_regs.h" #include "kvm_emulate.h" @@ -278,6 +279,7 @@ fastpath_t handle_fastpath_set_msr_irqoff(struct kvm_vcpu *vcpu); extern u64 host_xcr0; extern u64 supported_xcr0; +extern u64 host_xss; extern u64 supported_xss; static inline bool kvm_mpx_supported(void) @@ -366,10 +368,29 @@ static inline bool kvm_dr6_valid(u64 data) return !(data >> 32); } +/* + * Trigger machine check on the host. We assume all the MSRs are already set up + * by the CPU and that we still run on the same CPU as the MCE occurred on. + * We pass a fake environment to the machine check handler because we want + * the guest to be always treated like user space, no matter what context + * it used internally. + */ +static inline void kvm_machine_check(void) +{ +#if defined(CONFIG_X86_MCE) + struct pt_regs regs = { + .cs = 3, /* Fake ring 3 no matter what the guest ran on */ + .flags = X86_EFLAGS_IF, + }; + + do_machine_check(®s); +#endif +} + void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu); void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu); int kvm_spec_ctrl_test_value(u64 value); -int kvm_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); +bool kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu); int kvm_handle_memory_failure(struct kvm_vcpu *vcpu, int r, struct x86_exception *e); @@ -407,4 +428,12 @@ bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type); __reserved_bits; \ }) +int kvm_sev_es_mmio_write(struct kvm_vcpu *vcpu, gpa_t src, unsigned int bytes, + void *dst); +int kvm_sev_es_mmio_read(struct kvm_vcpu *vcpu, gpa_t src, unsigned int bytes, + void *dst); +int kvm_sev_es_string_io(struct kvm_vcpu *vcpu, unsigned int size, + unsigned int port, void *data, unsigned int count, + int in); + #endif diff --git a/arch/x86/lib/mmx_32.c b/arch/x86/lib/mmx_32.c index 4321fa02e18d..419365c48b2a 100644 --- a/arch/x86/lib/mmx_32.c +++ b/arch/x86/lib/mmx_32.c @@ -26,6 +26,16 @@ #include <asm/fpu/api.h> #include <asm/asm.h> +/* + * Use KFPU_387. MMX instructions are not affected by MXCSR, + * but both AMD and Intel documentation states that even integer MMX + * operations will result in #MF if an exception is pending in FCW. + * + * EMMS is not needed afterwards because, after calling kernel_fpu_end(), + * any subsequent user of the 387 stack will reinitialize it using + * KFPU_387. + */ + void *_mmx_memcpy(void *to, const void *from, size_t len) { void *p; @@ -37,7 +47,7 @@ void *_mmx_memcpy(void *to, const void *from, size_t len) p = to; i = len >> 6; /* len/64 */ - kernel_fpu_begin(); + kernel_fpu_begin_mask(KFPU_387); __asm__ __volatile__ ( "1: prefetch (%0)\n" /* This set is 28 bytes */ @@ -127,7 +137,7 @@ static void fast_clear_page(void *page) { int i; - kernel_fpu_begin(); + kernel_fpu_begin_mask(KFPU_387); __asm__ __volatile__ ( " pxor %%mm0, %%mm0\n" : : @@ -160,7 +170,7 @@ static void fast_copy_page(void *to, void *from) { int i; - kernel_fpu_begin(); + kernel_fpu_begin_mask(KFPU_387); /* * maybe the prefetch stuff can go before the expensive fnsave... @@ -247,7 +257,7 @@ static void fast_clear_page(void *page) { int i; - kernel_fpu_begin(); + kernel_fpu_begin_mask(KFPU_387); __asm__ __volatile__ ( " pxor %%mm0, %%mm0\n" : : @@ -282,7 +292,7 @@ static void fast_copy_page(void *to, void *from) { int i; - kernel_fpu_begin(); + kernel_fpu_begin_mask(KFPU_387); __asm__ __volatile__ ( "1: prefetch (%0)\n" diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index dfd82f51ba66..f6a9e2e36642 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -829,6 +829,8 @@ int pud_free_pmd_page(pud_t *pud, unsigned long addr) } free_page((unsigned long)pmd_sv); + + pgtable_pmd_page_dtor(virt_to_page(pmd)); free_page((unsigned long)pmd); return 1; diff --git a/arch/x86/pci/sta2x11-fixup.c b/arch/x86/pci/sta2x11-fixup.c index 5701d5ba3df4..7d2525691854 100644 --- a/arch/x86/pci/sta2x11-fixup.c +++ b/arch/x86/pci/sta2x11-fixup.c @@ -11,7 +11,8 @@ #include <linux/pci_ids.h> #include <linux/export.h> #include <linux/list.h> -#include <linux/dma-direct.h> +#include <linux/dma-map-ops.h> +#include <linux/swiotlb.h> #include <asm/iommu.h> #define STA2X11_SWIOTLB_SIZE (4*1024*1024) diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig index 218acbd5c7a0..afc1da68b06d 100644 --- a/arch/x86/xen/Kconfig +++ b/arch/x86/xen/Kconfig @@ -26,6 +26,19 @@ config XEN_PV help Support running as a Xen PV guest. +config XEN_512GB + bool "Limit Xen pv-domain memory to 512GB" + depends on XEN_PV + default y + help + Limit paravirtualized user domains to 512GB of RAM. + + The Xen tools and crash dump analysis tools might not support + pv-domains with more than 512 GB of RAM. This option controls the + default setting of the kernel to use only up to 512 GB or more. + It is always possible to change the default via specifying the + boot parameter "xen_512gb_limit". + config XEN_PV_SMP def_bool y depends on XEN_PV && SMP @@ -39,28 +52,19 @@ config XEN_DOM0 Support running as a Xen PV Dom0 guest. config XEN_PVHVM - bool "Xen PVHVM guest support" - default y - depends on XEN && PCI && X86_LOCAL_APIC - help - Support running as a Xen PVHVM guest. + def_bool y + depends on XEN && X86_LOCAL_APIC config XEN_PVHVM_SMP def_bool y depends on XEN_PVHVM && SMP -config XEN_512GB - bool "Limit Xen pv-domain memory to 512GB" - depends on XEN_PV +config XEN_PVHVM_GUEST + bool "Xen PVHVM guest support" default y + depends on XEN_PVHVM && PCI help - Limit paravirtualized user domains to 512GB of RAM. - - The Xen tools and crash dump analysis tools might not support - pv-domains with more than 512 GB of RAM. This option controls the - default setting of the kernel to use only up to 512 GB or more. - It is always possible to change the default via specifying the - boot parameter "xen_512gb_limit". + Support running as a Xen PVHVM guest. config XEN_SAVE_RESTORE bool @@ -76,7 +80,9 @@ config XEN_DEBUG_FS Enabling this option may incur a significant performance overhead. config XEN_PVH - bool "Support for running as a Xen PVH guest" + bool "Xen PVH guest support" depends on XEN && XEN_PVHVM && ACPI select PVH def_bool n + help + Support for running as a Xen PVH guest. diff --git a/arch/x86/xen/efi.c b/arch/x86/xen/efi.c index 205a9bc981b0..7d7ffb9c826a 100644 --- a/arch/x86/xen/efi.c +++ b/arch/x86/xen/efi.c @@ -93,37 +93,22 @@ static efi_system_table_t __init *xen_efi_probe(void) /* * Determine whether we're in secure boot mode. - * - * Please keep the logic in sync with - * drivers/firmware/efi/libstub/secureboot.c:efi_get_secureboot(). */ static enum efi_secureboot_mode xen_efi_get_secureboot(void) { - static efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID; static efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID; + enum efi_secureboot_mode mode; efi_status_t status; - u8 moksbstate, secboot, setupmode; + u8 moksbstate; unsigned long size; - size = sizeof(secboot); - status = efi.get_variable(L"SecureBoot", &efi_variable_guid, - NULL, &size, &secboot); - - if (status == EFI_NOT_FOUND) - return efi_secureboot_mode_disabled; - - if (status != EFI_SUCCESS) - goto out_efi_err; - - size = sizeof(setupmode); - status = efi.get_variable(L"SetupMode", &efi_variable_guid, - NULL, &size, &setupmode); - - if (status != EFI_SUCCESS) - goto out_efi_err; - - if (secboot == 0 || setupmode == 1) - return efi_secureboot_mode_disabled; + mode = efi_get_secureboot_mode(efi.get_variable); + if (mode == efi_secureboot_mode_unknown) { + pr_err("Could not determine UEFI Secure Boot status.\n"); + return efi_secureboot_mode_unknown; + } + if (mode != efi_secureboot_mode_enabled) + return mode; /* See if a user has put the shim into insecure mode. */ size = sizeof(moksbstate); @@ -140,10 +125,6 @@ static enum efi_secureboot_mode xen_efi_get_secureboot(void) secure_boot_enabled: pr_info("UEFI Secure Boot is enabled.\n"); return efi_secureboot_mode_enabled; - - out_efi_err: - pr_err("Could not determine UEFI Secure Boot status.\n"); - return efi_secureboot_mode_unknown; } void __init xen_efi_init(struct boot_params *boot_params) diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c index 9e87ab010c82..e68ea5f4ad1c 100644 --- a/arch/x86/xen/enlighten_hvm.c +++ b/arch/x86/xen/enlighten_hvm.c @@ -164,10 +164,10 @@ static int xen_cpu_up_prepare_hvm(unsigned int cpu) else per_cpu(xen_vcpu_id, cpu) = cpu; rc = xen_vcpu_setup(cpu); - if (rc) + if (rc || !xen_have_vector_callback) return rc; - if (xen_have_vector_callback && xen_feature(XENFEAT_hvm_safe_pvclock)) + if (xen_feature(XENFEAT_hvm_safe_pvclock)) xen_setup_timer(cpu); rc = xen_smp_intr_init(cpu); @@ -188,6 +188,8 @@ static int xen_cpu_dead_hvm(unsigned int cpu) return 0; } +static bool no_vector_callback __initdata; + static void __init xen_hvm_guest_init(void) { if (xen_pv_domain()) @@ -207,7 +209,7 @@ static void __init xen_hvm_guest_init(void) xen_panic_handler_init(); - if (xen_feature(XENFEAT_hvm_callback_vector)) + if (!no_vector_callback && xen_feature(XENFEAT_hvm_callback_vector)) xen_have_vector_callback = 1; xen_hvm_smp_init(); @@ -233,6 +235,13 @@ static __init int xen_parse_nopv(char *arg) } early_param("xen_nopv", xen_parse_nopv); +static __init int xen_parse_no_vector_callback(char *arg) +{ + no_vector_callback = true; + return 0; +} +early_param("xen_no_vector_callback", xen_parse_no_vector_callback); + bool __init xen_hvm_need_lapic(void) { if (xen_pv_domain()) diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index be4151f42611..3301875dd196 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -795,17 +795,7 @@ static int p2m_dump_show(struct seq_file *m, void *v) return 0; } -static int p2m_dump_open(struct inode *inode, struct file *filp) -{ - return single_open(filp, p2m_dump_show, NULL); -} - -static const struct file_operations p2m_dump_fops = { - .open = p2m_dump_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(p2m_dump); static struct dentry *d_mmu_debug; diff --git a/arch/x86/xen/smp_hvm.c b/arch/x86/xen/smp_hvm.c index f5e7db4f82ab..6ff3c887e0b9 100644 --- a/arch/x86/xen/smp_hvm.c +++ b/arch/x86/xen/smp_hvm.c @@ -33,9 +33,11 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) int cpu; native_smp_prepare_cpus(max_cpus); - WARN_ON(xen_smp_intr_init(0)); - xen_init_lock_cpu(0); + if (xen_have_vector_callback) { + WARN_ON(xen_smp_intr_init(0)); + xen_init_lock_cpu(0); + } for_each_possible_cpu(cpu) { if (cpu == 0) @@ -50,9 +52,11 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) static void xen_hvm_cpu_die(unsigned int cpu) { if (common_cpu_die(cpu) == 0) { - xen_smp_intr_free(cpu); - xen_uninit_lock_cpu(cpu); - xen_teardown_timer(cpu); + if (xen_have_vector_callback) { + xen_smp_intr_free(cpu); + xen_uninit_lock_cpu(cpu); + xen_teardown_timer(cpu); + } } } #else @@ -64,14 +68,19 @@ static void xen_hvm_cpu_die(unsigned int cpu) void __init xen_hvm_smp_init(void) { - if (!xen_have_vector_callback) + smp_ops.smp_prepare_boot_cpu = xen_hvm_smp_prepare_boot_cpu; + smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; + smp_ops.smp_cpus_done = xen_smp_cpus_done; + smp_ops.cpu_die = xen_hvm_cpu_die; + + if (!xen_have_vector_callback) { +#ifdef CONFIG_PARAVIRT_SPINLOCKS + nopvspin = true; +#endif return; + } - smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; smp_ops.smp_send_reschedule = xen_smp_send_reschedule; - smp_ops.cpu_die = xen_hvm_cpu_die; smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi; smp_ops.send_call_func_single_ipi = xen_smp_send_call_function_single_ipi; - smp_ops.smp_prepare_boot_cpu = xen_hvm_smp_prepare_boot_cpu; - smp_ops.smp_cpus_done = xen_smp_cpus_done; } diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild index 9718e9593564..854c5e07e867 100644 --- a/arch/xtensa/include/asm/Kbuild +++ b/arch/xtensa/include/asm/Kbuild @@ -2,7 +2,6 @@ generated-y += syscall_table.h generic-y += extable.h generic-y += kvm_para.h -generic-y += local64.h generic-y += mcs_spinlock.h generic-y += param.h generic-y += qrwlock.h diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl index b070f272995d..46116a28eeed 100644 --- a/arch/xtensa/kernel/syscalls/syscall.tbl +++ b/arch/xtensa/kernel/syscalls/syscall.tbl @@ -411,3 +411,4 @@ 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 440 common process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 77971fe4cc95..e8ceb1528608 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -13,7 +13,7 @@ */ #include <linux/clk.h> -#include <linux/clk-provider.h> +#include <linux/of_clk.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/time.h> |