diff options
author | Marc Zyngier <maz@kernel.org> | 2020-11-12 21:20:43 +0000 |
---|---|---|
committer | Marc Zyngier <maz@kernel.org> | 2020-11-12 21:20:43 +0000 |
commit | 4f6b838c378a52ea3ae0b15f12ca8a20849072fa (patch) | |
tree | fbd8c2346320f97eda221b9150d787f9006e8b35 /arch | |
parent | c512298eed0360923d0cbc4a1f30bc0509af0d50 (diff) | |
parent | 3650b228f83adda7e5ee532e2b90429c03f7b9ec (diff) | |
download | lwn-4f6b838c378a52ea3ae0b15f12ca8a20849072fa.tar.gz lwn-4f6b838c378a52ea3ae0b15f12ca8a20849072fa.zip |
Merge tag 'v5.10-rc1' into kvmarm-master/next
Linux 5.10-rc1
Signed-off-by: Marc Zyngier <maz@kernel.org>
Diffstat (limited to 'arch')
2425 files changed, 62536 insertions, 61079 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index af14a567b493..56b6ccc0e32d 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -24,6 +24,9 @@ config KEXEC_ELF config HAVE_IMA_KEXEC bool +config SET_FS + bool + config HOTPLUG_SMT bool @@ -106,6 +109,12 @@ config STATIC_KEYS_SELFTEST help Boot time self-test of the branch patching code. +config STATIC_CALL_SELFTEST + bool "Static call selftest" + depends on HAVE_STATIC_CALL + help + Boot time self-test of the call patching code. + config OPTPROBES def_bool y depends on KPROBES && HAVE_OPTPROBES @@ -414,6 +423,13 @@ config MMU_GATHER_NO_GATHER bool depends on MMU_GATHER_TABLE_FREE +config ARCH_WANT_IRQS_OFF_ACTIVATE_MM + bool + help + Temporary select until all architectures can be converted to have + irqs disabled over activate_mm. Architectures that do IPI based TLB + shootdowns should enable this. + config ARCH_HAVE_NMI_SAFE_CMPXCHG bool @@ -444,10 +460,23 @@ config ARCH_WANT_OLD_COMPAT_IPC select ARCH_WANT_COMPAT_IPC_PARSE_VERSION bool +config HAVE_ARCH_SECCOMP + bool + help + An arch should select this symbol to support seccomp mode 1 (the fixed + syscall policy), and must provide an overrides for __NR_seccomp_sigreturn, + and compat syscalls if the asm-generic/seccomp.h defaults need adjustment: + - __NR_seccomp_read_32 + - __NR_seccomp_write_32 + - __NR_seccomp_exit_32 + - __NR_seccomp_sigreturn_32 + config HAVE_ARCH_SECCOMP_FILTER bool + select HAVE_ARCH_SECCOMP help An arch should select this symbol if it provides all of these things: + - all the requirements for HAVE_ARCH_SECCOMP - syscall_get_arch() - syscall_get_arguments() - syscall_rollback() @@ -458,6 +487,23 @@ config HAVE_ARCH_SECCOMP_FILTER results in the system call being skipped immediately. - seccomp syscall wired up +config SECCOMP + prompt "Enable seccomp to safely execute untrusted bytecode" + def_bool y + depends on HAVE_ARCH_SECCOMP + help + This kernel feature is useful for number crunching applications + that may need to handle untrusted bytecode during their + execution. By using pipes or other transports made available + to the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in their + own address space using seccomp. Once seccomp is enabled via + prctl(PR_SET_SECCOMP) or the seccomp() syscall, it cannot be + disabled and the task is only allowed to execute a few safe + syscalls defined by each seccomp mode. + + If unsure, say Y. + config SECCOMP_FILTER def_bool y depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET @@ -975,6 +1021,13 @@ config HAVE_SPARSE_SYSCALL_NR config ARCH_HAS_VDSO_DATA bool +config HAVE_STATIC_CALL + bool + +config HAVE_STATIC_CALL_INLINE + bool + depends on HAVE_STATIC_CALL + source "kernel/gcov/Kconfig" source "scripts/gcc-plugins/Kconfig" diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 9c5f06e8eb9b..d6e9fc7a7b19 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -39,6 +39,7 @@ config ALPHA select OLD_SIGSUSPEND select CPU_NO_EFFICIENT_FFS if !ALPHA_EV67 select MMU_GATHER_NO_RANGE + select SET_FS help The Alpha is a 64-bit general-purpose processor designed and marketed by the Digital Equipment Corporation of blessed memory, diff --git a/arch/alpha/include/asm/checksum.h b/arch/alpha/include/asm/checksum.h index 0eac81624d01..99d631e146b2 100644 --- a/arch/alpha/include/asm/checksum.h +++ b/arch/alpha/include/asm/checksum.h @@ -42,9 +42,10 @@ extern __wsum csum_partial(const void *buff, int len, __wsum sum); * better 64-bit) boundary */ #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER -__wsum csum_and_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *errp); +#define _HAVE_ARCH_CSUM_AND_COPY +__wsum csum_and_copy_from_user(const void __user *src, void *dst, int len); -__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum); +__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len); /* diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 81037907268d..d84b19aa8e9d 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -11,7 +11,7 @@ #include <linux/export.h> #include <linux/scatterlist.h> #include <linux/log2.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/iommu-helper.h> #include <asm/io.h> @@ -141,12 +141,7 @@ iommu_arena_find_pages(struct device *dev, struct pci_iommu_arena *arena, unsigned long boundary_size; base = arena->dma_base >> PAGE_SHIFT; - if (dev) { - boundary_size = dma_get_seg_boundary(dev) + 1; - boundary_size >>= PAGE_SHIFT; - } else { - boundary_size = 1UL << (32 - PAGE_SHIFT); - } + boundary_size = dma_get_seg_boundary_nr_pages(dev, PAGE_SHIFT); /* Search forward for the first mask-aligned sequence of N free ptes */ ptes = arena->ptes; @@ -957,5 +952,7 @@ const struct dma_map_ops alpha_pci_ops = { .dma_supported = alpha_pci_supported, .mmap = dma_common_mmap, .get_sgtable = dma_common_get_sgtable, + .alloc_pages = dma_common_alloc_pages, + .free_pages = dma_common_free_pages, }; EXPORT_SYMBOL(alpha_pci_ops); diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index 15bc9d1e79f4..3739efce1ec0 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c @@ -531,7 +531,6 @@ do_work_pending(struct pt_regs *regs, unsigned long thread_flags, do_signal(regs, r0, r19); r0 = 0; } else { - clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); } } diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl index ec8bed9e7b75..ee7b01bb7346 100644 --- a/arch/alpha/kernel/syscalls/syscall.tbl +++ b/arch/alpha/kernel/syscalls/syscall.tbl @@ -479,3 +479,4 @@ 547 common openat2 sys_openat2 548 common pidfd_getfd sys_pidfd_getfd 549 common faccessat2 sys_faccessat2 +550 common process_madvise sys_process_madvise diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S index bc6f727278fd..5b78d640725d 100644 --- a/arch/alpha/kernel/vmlinux.lds.S +++ b/arch/alpha/kernel/vmlinux.lds.S @@ -72,6 +72,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + ELF_DETAILS DISCARDS } diff --git a/arch/alpha/lib/csum_partial_copy.c b/arch/alpha/lib/csum_partial_copy.c index af1dad74e933..dc68efbe9367 100644 --- a/arch/alpha/lib/csum_partial_copy.c +++ b/arch/alpha/lib/csum_partial_copy.c @@ -39,12 +39,11 @@ __asm__ __volatile__("insql %1,%2,%0":"=r" (z):"r" (x),"r" (y)) #define insqh(x,y,z) \ __asm__ __volatile__("insqh %1,%2,%0":"=r" (z):"r" (x),"r" (y)) - -#define __get_user_u(x,ptr) \ +#define __get_word(insn,x,ptr) \ ({ \ long __guu_err; \ __asm__ __volatile__( \ - "1: ldq_u %0,%2\n" \ + "1: "#insn" %0,%2\n" \ "2:\n" \ EXC(1b,2b,%0,%1) \ : "=r"(x), "=r"(__guu_err) \ @@ -52,19 +51,6 @@ __asm__ __volatile__("insqh %1,%2,%0":"=r" (z):"r" (x),"r" (y)) __guu_err; \ }) -#define __put_user_u(x,ptr) \ -({ \ - long __puu_err; \ - __asm__ __volatile__( \ - "1: stq_u %2,%1\n" \ - "2:\n" \ - EXC(1b,2b,$31,%0) \ - : "=r"(__puu_err) \ - : "m"(__m(addr)), "rJ"(x), "0"(0)); \ - __puu_err; \ -}) - - static inline unsigned short from64to16(unsigned long x) { /* Using extract instructions is a bit more efficient @@ -95,15 +81,15 @@ static inline unsigned short from64to16(unsigned long x) */ static inline unsigned long csum_partial_cfu_aligned(const unsigned long __user *src, unsigned long *dst, - long len, unsigned long checksum, - int *errp) + long len) { + unsigned long checksum = ~0U; unsigned long carry = 0; - int err = 0; while (len >= 0) { unsigned long word; - err |= __get_user(word, src); + if (__get_word(ldq, word, src)) + return 0; checksum += carry; src++; checksum += word; @@ -116,7 +102,8 @@ csum_partial_cfu_aligned(const unsigned long __user *src, unsigned long *dst, checksum += carry; if (len) { unsigned long word, tmp; - err |= __get_user(word, src); + if (__get_word(ldq, word, src)) + return 0; tmp = *dst; mskql(word, len, word); checksum += word; @@ -125,7 +112,6 @@ csum_partial_cfu_aligned(const unsigned long __user *src, unsigned long *dst, *dst = word | tmp; checksum += carry; } - if (err && errp) *errp = err; return checksum; } @@ -137,20 +123,21 @@ static inline unsigned long csum_partial_cfu_dest_aligned(const unsigned long __user *src, unsigned long *dst, unsigned long soff, - long len, unsigned long checksum, - int *errp) + long len) { unsigned long first; unsigned long word, carry; unsigned long lastsrc = 7+len+(unsigned long)src; - int err = 0; + unsigned long checksum = ~0U; - err |= __get_user_u(first,src); + if (__get_word(ldq_u, first,src)) + return 0; carry = 0; while (len >= 0) { unsigned long second; - err |= __get_user_u(second, src+1); + if (__get_word(ldq_u, second, src+1)) + return 0; extql(first, soff, word); len -= 8; src++; @@ -168,7 +155,8 @@ csum_partial_cfu_dest_aligned(const unsigned long __user *src, if (len) { unsigned long tmp; unsigned long second; - err |= __get_user_u(second, lastsrc); + if (__get_word(ldq_u, second, lastsrc)) + return 0; tmp = *dst; extql(first, soff, word); extqh(second, soff, first); @@ -180,7 +168,6 @@ csum_partial_cfu_dest_aligned(const unsigned long __user *src, *dst = word | tmp; checksum += carry; } - if (err && errp) *errp = err; return checksum; } @@ -191,18 +178,18 @@ static inline unsigned long csum_partial_cfu_src_aligned(const unsigned long __user *src, unsigned long *dst, unsigned long doff, - long len, unsigned long checksum, - unsigned long partial_dest, - int *errp) + long len, + unsigned long partial_dest) { unsigned long carry = 0; unsigned long word; unsigned long second_dest; - int err = 0; + unsigned long checksum = ~0U; mskql(partial_dest, doff, partial_dest); while (len >= 0) { - err |= __get_user(word, src); + if (__get_word(ldq, word, src)) + return 0; len -= 8; insql(word, doff, second_dest); checksum += carry; @@ -216,7 +203,8 @@ csum_partial_cfu_src_aligned(const unsigned long __user *src, len += 8; if (len) { checksum += carry; - err |= __get_user(word, src); + if (__get_word(ldq, word, src)) + return 0; mskql(word, len, word); len -= 8; checksum += word; @@ -237,7 +225,6 @@ csum_partial_cfu_src_aligned(const unsigned long __user *src, stq_u(partial_dest | second_dest, dst); out: checksum += carry; - if (err && errp) *errp = err; return checksum; } @@ -249,23 +236,23 @@ static inline unsigned long csum_partial_cfu_unaligned(const unsigned long __user * src, unsigned long * dst, unsigned long soff, unsigned long doff, - long len, unsigned long checksum, - unsigned long partial_dest, - int *errp) + long len, unsigned long partial_dest) { unsigned long carry = 0; unsigned long first; unsigned long lastsrc; - int err = 0; + unsigned long checksum = ~0U; - err |= __get_user_u(first, src); + if (__get_word(ldq_u, first, src)) + return 0; lastsrc = 7+len+(unsigned long)src; mskql(partial_dest, doff, partial_dest); while (len >= 0) { unsigned long second, word; unsigned long second_dest; - err |= __get_user_u(second, src+1); + if (__get_word(ldq_u, second, src+1)) + return 0; extql(first, soff, word); checksum += carry; len -= 8; @@ -286,7 +273,8 @@ csum_partial_cfu_unaligned(const unsigned long __user * src, unsigned long second, word; unsigned long second_dest; - err |= __get_user_u(second, lastsrc); + if (__get_word(ldq_u, second, lastsrc)) + return 0; extql(first, soff, word); extqh(second, soff, first); word |= first; @@ -307,7 +295,8 @@ csum_partial_cfu_unaligned(const unsigned long __user * src, unsigned long second, word; unsigned long second_dest; - err |= __get_user_u(second, lastsrc); + if (__get_word(ldq_u, second, lastsrc)) + return 0; extql(first, soff, word); extqh(second, soff, first); word |= first; @@ -320,66 +309,55 @@ csum_partial_cfu_unaligned(const unsigned long __user * src, stq_u(partial_dest | word | second_dest, dst); checksum += carry; } - if (err && errp) *errp = err; return checksum; } -__wsum -csum_and_copy_from_user(const void __user *src, void *dst, int len, - __wsum sum, int *errp) +static __wsum __csum_and_copy(const void __user *src, void *dst, int len) { - unsigned long checksum = (__force u32) sum; unsigned long soff = 7 & (unsigned long) src; unsigned long doff = 7 & (unsigned long) dst; - - if (len) { - if (!access_ok(src, len)) { - if (errp) *errp = -EFAULT; - memset(dst, 0, len); - return sum; - } - if (!doff) { - if (!soff) - checksum = csum_partial_cfu_aligned( - (const unsigned long __user *) src, - (unsigned long *) dst, - len-8, checksum, errp); - else - checksum = csum_partial_cfu_dest_aligned( - (const unsigned long __user *) src, - (unsigned long *) dst, - soff, len-8, checksum, errp); - } else { - unsigned long partial_dest; - ldq_u(partial_dest, dst); - if (!soff) - checksum = csum_partial_cfu_src_aligned( - (const unsigned long __user *) src, - (unsigned long *) dst, - doff, len-8, checksum, - partial_dest, errp); - else - checksum = csum_partial_cfu_unaligned( - (const unsigned long __user *) src, - (unsigned long *) dst, - soff, doff, len-8, checksum, - partial_dest, errp); - } - checksum = from64to16 (checksum); + unsigned long checksum; + + if (!doff) { + if (!soff) + checksum = csum_partial_cfu_aligned( + (const unsigned long __user *) src, + (unsigned long *) dst, len-8); + else + checksum = csum_partial_cfu_dest_aligned( + (const unsigned long __user *) src, + (unsigned long *) dst, + soff, len-8); + } else { + unsigned long partial_dest; + ldq_u(partial_dest, dst); + if (!soff) + checksum = csum_partial_cfu_src_aligned( + (const unsigned long __user *) src, + (unsigned long *) dst, + doff, len-8, partial_dest); + else + checksum = csum_partial_cfu_unaligned( + (const unsigned long __user *) src, + (unsigned long *) dst, + soff, doff, len-8, partial_dest); } - return (__force __wsum)checksum; + return (__force __wsum)from64to16 (checksum); +} + +__wsum +csum_and_copy_from_user(const void __user *src, void *dst, int len) +{ + if (!access_ok(src, len)) + return 0; + return __csum_and_copy(src, dst, len); } EXPORT_SYMBOL(csum_and_copy_from_user); __wsum -csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) +csum_partial_copy_nocheck(const void *src, void *dst, int len) { - __wsum checksum; - mm_segment_t oldfs = get_fs(); - set_fs(KERNEL_DS); - checksum = csum_and_copy_from_user((__force const void __user *)src, - dst, len, sum, NULL); - set_fs(oldfs); - return checksum; + return __csum_and_copy((__force const void __user *)src, + dst, len); } EXPORT_SYMBOL(csum_partial_copy_nocheck); diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index ba00c4e1e1c2..0a89cc9def65 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -48,6 +48,7 @@ config ARC select PCI_SYSCALL if PCI select PERF_USE_VMALLOC if ARC_CACHE_VIPT_ALIASING select HAVE_ARCH_JUMP_LABEL if ISA_ARCV2 && !CPU_ENDIAN_BE32 + select SET_FS config ARCH_HAS_CACHE_LINE_SIZE def_bool y @@ -96,8 +97,6 @@ menu "ARC Platform/SoC/Board" source "arch/arc/plat-tb10x/Kconfig" source "arch/arc/plat-axs10x/Kconfig" -#New platform adds here -source "arch/arc/plat-eznps/Kconfig" source "arch/arc/plat-hsdk/Kconfig" endmenu diff --git a/arch/arc/Makefile b/arch/arc/Makefile index d00f8b8afd08..0c6bf0d1df7a 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -94,13 +94,8 @@ core-y += arch/arc/boot/dts/ core-y += arch/arc/plat-sim/ core-$(CONFIG_ARC_PLAT_TB10X) += arch/arc/plat-tb10x/ core-$(CONFIG_ARC_PLAT_AXS10X) += arch/arc/plat-axs10x/ -core-$(CONFIG_ARC_PLAT_EZNPS) += arch/arc/plat-eznps/ core-$(CONFIG_ARC_SOC_HSDK) += arch/arc/plat-hsdk/ -ifdef CONFIG_ARC_PLAT_EZNPS -KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include -endif - drivers-$(CONFIG_OPROFILE) += arch/arc/oprofile/ libs-y += arch/arc/lib/ $(LIBGCC) diff --git a/arch/arc/boot/dts/axc001.dtsi b/arch/arc/boot/dts/axc001.dtsi index 79ec27c043c1..2a151607b080 100644 --- a/arch/arc/boot/dts/axc001.dtsi +++ b/arch/arc/boot/dts/axc001.dtsi @@ -91,7 +91,7 @@ * avoid duplicating the MB dtsi file given that IRQ from * this intc to cpu intc are different for axs101 and axs103 */ - mb_intc: dw-apb-ictl@e0012000 { + mb_intc: interrupt-controller@e0012000 { #interrupt-cells = <1>; compatible = "snps,dw-apb-ictl"; reg = < 0x0 0xe0012000 0x0 0x200 >; diff --git a/arch/arc/boot/dts/axc003.dtsi b/arch/arc/boot/dts/axc003.dtsi index ac8e1b463a70..cd1edcf4f95e 100644 --- a/arch/arc/boot/dts/axc003.dtsi +++ b/arch/arc/boot/dts/axc003.dtsi @@ -129,7 +129,7 @@ * avoid duplicating the MB dtsi file given that IRQ from * this intc to cpu intc are different for axs101 and axs103 */ - mb_intc: dw-apb-ictl@e0012000 { + mb_intc: interrupt-controller@e0012000 { #interrupt-cells = <1>; compatible = "snps,dw-apb-ictl"; reg = < 0x0 0xe0012000 0x0 0x200 >; diff --git a/arch/arc/boot/dts/axc003_idu.dtsi b/arch/arc/boot/dts/axc003_idu.dtsi index 9da21e7fd246..70779386ca79 100644 --- a/arch/arc/boot/dts/axc003_idu.dtsi +++ b/arch/arc/boot/dts/axc003_idu.dtsi @@ -135,7 +135,7 @@ * avoid duplicating the MB dtsi file given that IRQ from * this intc to cpu intc are different for axs101 and axs103 */ - mb_intc: dw-apb-ictl@e0012000 { + mb_intc: interrupt-controller@e0012000 { #interrupt-cells = <1>; compatible = "snps,dw-apb-ictl"; reg = < 0x0 0xe0012000 0x0 0x200 >; diff --git a/arch/arc/boot/dts/eznps.dts b/arch/arc/boot/dts/eznps.dts deleted file mode 100644 index a7e2e8d8ff06..000000000000 --- a/arch/arc/boot/dts/eznps.dts +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright(c) 2015 EZchip Technologies. - */ - -/dts-v1/; - -/ { - compatible = "ezchip,arc-nps"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&intc>; - present-cpus = "0-1,16-17"; - possible-cpus = "0-4095"; - - aliases { - ethernet0 = &gmac0; - }; - - chosen { - bootargs = "earlycon=uart8250,mmio32be,0xf7209000,115200n8 console=ttyS0,115200n8"; - }; - - memory { - device_type = "memory"; - reg = <0x80000000 0x20000000>; /* 512M */ - }; - - clocks { - sysclk: sysclk { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <83333333>; - }; - }; - - soc { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - - /* child and parent address space 1:1 mapped */ - ranges; - - intc: interrupt-controller { - compatible = "ezchip,nps400-ic"; - interrupt-controller; - #interrupt-cells = <1>; - }; - - timer0: timer_clkevt { - compatible = "snps,arc-timer"; - interrupts = <3>; - clocks = <&sysclk>; - }; - - timer1: timer_clksrc { - compatible = "ezchip,nps400-timer"; - clocks = <&sysclk>; - clock-names="sysclk"; - }; - - uart@f7209000 { - compatible = "snps,dw-apb-uart"; - device_type = "serial"; - reg = <0xf7209000 0x100>; - interrupts = <6>; - clocks = <&sysclk>; - clock-names="baudclk"; - baud = <115200>; - reg-shift = <2>; - reg-io-width = <4>; - native-endian; - }; - - gmac0: ethernet@f7470000 { - compatible = "ezchip,nps-mgt-enet"; - reg = <0xf7470000 0x1940>; - interrupts = <7>; - /* Filled in by U-Boot */ - mac-address = [ 00 C0 00 F0 04 03 ]; - }; - }; -}; diff --git a/arch/arc/boot/dts/vdk_axc003.dtsi b/arch/arc/boot/dts/vdk_axc003.dtsi index f8be7ba8dad4..c21d0eb07bf6 100644 --- a/arch/arc/boot/dts/vdk_axc003.dtsi +++ b/arch/arc/boot/dts/vdk_axc003.dtsi @@ -46,7 +46,7 @@ }; - mb_intc: dw-apb-ictl@e0012000 { + mb_intc: interrupt-controller@e0012000 { #interrupt-cells = <1>; compatible = "snps,dw-apb-ictl"; reg = < 0xe0012000 0x200 >; diff --git a/arch/arc/boot/dts/vdk_axc003_idu.dtsi b/arch/arc/boot/dts/vdk_axc003_idu.dtsi index 0afa3e53a4e3..4d348853ac7c 100644 --- a/arch/arc/boot/dts/vdk_axc003_idu.dtsi +++ b/arch/arc/boot/dts/vdk_axc003_idu.dtsi @@ -54,7 +54,7 @@ }; - mb_intc: dw-apb-ictl@e0012000 { + mb_intc: interrupt-controller@e0012000 { #interrupt-cells = <1>; compatible = "snps,dw-apb-ictl"; reg = < 0xe0012000 0x200 >; diff --git a/arch/arc/configs/nps_defconfig b/arch/arc/configs/nps_defconfig deleted file mode 100644 index f7a978dfdf1d..000000000000 --- a/arch/arc/configs/nps_defconfig +++ /dev/null @@ -1,80 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_NO_HZ_IDLE=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3=y -# CONFIG_EPOLL is not set -# CONFIG_SIGNALFD is not set -# CONFIG_TIMERFD is not set -# CONFIG_EVENTFD is not set -# CONFIG_AIO is not set -CONFIG_EMBEDDED=y -CONFIG_PERF_EVENTS=y -# CONFIG_COMPAT_BRK is not set -CONFIG_ISA_ARCOMPACT=y -CONFIG_KPROBES=y -CONFIG_MODULES=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_ARC_PLAT_EZNPS=y -CONFIG_SMP=y -CONFIG_NR_CPUS=4096 -CONFIG_ARC_CACHE_LINE_SHIFT=5 -# CONFIG_ARC_CACHE_PAGES is not set -# CONFIG_ARC_HAS_LLSC is not set -CONFIG_ARC_KVADDR_SIZE=402 -CONFIG_ARC_EMUL_UNALIGNED=y -CONFIG_PREEMPT=y -CONFIG_NET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_DIAG is not set -# CONFIG_IPV6 is not set -# CONFIG_WIRELESS is not set -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=1 -CONFIG_BLK_DEV_RAM_SIZE=2048 -CONFIG_NETDEVICES=y -CONFIG_NETCONSOLE=y -# CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_VENDOR_MICREL is not set -# CONFIG_NET_VENDOR_STMICRO is not set -# CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=1 -CONFIG_SERIAL_8250_RUNTIME_UARTS=1 -CONFIG_SERIAL_8250_DW=y -CONFIG_SERIAL_OF_PLATFORM=y -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_DNOTIFY is not set -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -# CONFIG_MISC_FILESYSTEMS is not set -CONFIG_NFS_FS=y -CONFIG_NFS_V3_ACL=y -CONFIG_ROOT_NFS=y -CONFIG_DEBUG_INFO=y -# CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_MEMORY_INIT=y -CONFIG_ENABLE_DEFAULT_TRACERS=y diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h index c614857eb209..5afc79c9b2f5 100644 --- a/arch/arc/include/asm/atomic.h +++ b/arch/arc/include/asm/atomic.h @@ -14,8 +14,6 @@ #include <asm/barrier.h> #include <asm/smp.h> -#ifndef CONFIG_ARC_PLAT_EZNPS - #define atomic_read(v) READ_ONCE((v)->counter) #ifdef CONFIG_ARC_HAS_LLSC @@ -45,7 +43,7 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \ \ /* \ * Explicit full memory barrier needed before/after as \ - * LLOCK/SCOND thmeselves don't provide any such semantics \ + * LLOCK/SCOND themselves don't provide any such semantics \ */ \ smp_mb(); \ \ @@ -71,7 +69,7 @@ static inline int atomic_fetch_##op(int i, atomic_t *v) \ \ /* \ * Explicit full memory barrier needed before/after as \ - * LLOCK/SCOND thmeselves don't provide any such semantics \ + * LLOCK/SCOND themselves don't provide any such semantics \ */ \ smp_mb(); \ \ @@ -195,108 +193,6 @@ ATOMIC_OPS(andnot, &= ~, bic) ATOMIC_OPS(or, |=, or) ATOMIC_OPS(xor, ^=, xor) -#else /* CONFIG_ARC_PLAT_EZNPS */ - -static inline int atomic_read(const atomic_t *v) -{ - int temp; - - __asm__ __volatile__( - " ld.di %0, [%1]" - : "=r"(temp) - : "r"(&v->counter) - : "memory"); - return temp; -} - -static inline void atomic_set(atomic_t *v, int i) -{ - __asm__ __volatile__( - " st.di %0,[%1]" - : - : "r"(i), "r"(&v->counter) - : "memory"); -} - -#define ATOMIC_OP(op, c_op, asm_op) \ -static inline void atomic_##op(int i, atomic_t *v) \ -{ \ - __asm__ __volatile__( \ - " mov r2, %0\n" \ - " mov r3, %1\n" \ - " .word %2\n" \ - : \ - : "r"(i), "r"(&v->counter), "i"(asm_op) \ - : "r2", "r3", "memory"); \ -} \ - -#define ATOMIC_OP_RETURN(op, c_op, asm_op) \ -static inline int atomic_##op##_return(int i, atomic_t *v) \ -{ \ - unsigned int temp = i; \ - \ - /* Explicit full memory barrier needed before/after */ \ - smp_mb(); \ - \ - __asm__ __volatile__( \ - " mov r2, %0\n" \ - " mov r3, %1\n" \ - " .word %2\n" \ - " mov %0, r2" \ - : "+r"(temp) \ - : "r"(&v->counter), "i"(asm_op) \ - : "r2", "r3", "memory"); \ - \ - smp_mb(); \ - \ - temp c_op i; \ - \ - return temp; \ -} - -#define ATOMIC_FETCH_OP(op, c_op, asm_op) \ -static inline int atomic_fetch_##op(int i, atomic_t *v) \ -{ \ - unsigned int temp = i; \ - \ - /* Explicit full memory barrier needed before/after */ \ - smp_mb(); \ - \ - __asm__ __volatile__( \ - " mov r2, %0\n" \ - " mov r3, %1\n" \ - " .word %2\n" \ - " mov %0, r2" \ - : "+r"(temp) \ - : "r"(&v->counter), "i"(asm_op) \ - : "r2", "r3", "memory"); \ - \ - smp_mb(); \ - \ - return temp; \ -} - -#define ATOMIC_OPS(op, c_op, asm_op) \ - ATOMIC_OP(op, c_op, asm_op) \ - ATOMIC_OP_RETURN(op, c_op, asm_op) \ - ATOMIC_FETCH_OP(op, c_op, asm_op) - -ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3) -#define atomic_sub(i, v) atomic_add(-(i), (v)) -#define atomic_sub_return(i, v) atomic_add_return(-(i), (v)) -#define atomic_fetch_sub(i, v) atomic_fetch_add(-(i), (v)) - -#undef ATOMIC_OPS -#define ATOMIC_OPS(op, c_op, asm_op) \ - ATOMIC_OP(op, c_op, asm_op) \ - ATOMIC_FETCH_OP(op, c_op, asm_op) - -ATOMIC_OPS(and, &=, CTOP_INST_AAND_DI_R2_R2_R3) -ATOMIC_OPS(or, |=, CTOP_INST_AOR_DI_R2_R2_R3) -ATOMIC_OPS(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3) - -#endif /* CONFIG_ARC_PLAT_EZNPS */ - #undef ATOMIC_OPS #undef ATOMIC_FETCH_OP #undef ATOMIC_OP_RETURN diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h index 7823811e7cf5..4637de9e02fa 100644 --- a/arch/arc/include/asm/barrier.h +++ b/arch/arc/include/asm/barrier.h @@ -27,7 +27,7 @@ #define rmb() asm volatile("dmb 1\n" : : : "memory") #define wmb() asm volatile("dmb 2\n" : : : "memory") -#elif !defined(CONFIG_ARC_PLAT_EZNPS) /* CONFIG_ISA_ARCOMPACT */ +#else /* * ARCompact based cores (ARC700) only have SYNC instruction which is super @@ -37,13 +37,6 @@ #define mb() asm volatile("sync\n" : : : "memory") -#else /* CONFIG_ARC_PLAT_EZNPS */ - -#include <plat/ctop.h> - -#define mb() asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory") -#define rmb() asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RD) : "memory") - #endif #include <asm-generic/barrier.h> diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h index 50eb3f64a77c..c6606f4d20d6 100644 --- a/arch/arc/include/asm/bitops.h +++ b/arch/arc/include/asm/bitops.h @@ -85,7 +85,7 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long * return (old & (1 << nr)) != 0; \ } -#elif !defined(CONFIG_ARC_PLAT_EZNPS) +#else /* !CONFIG_ARC_HAS_LLSC */ /* * Non hardware assisted Atomic-R-M-W @@ -136,55 +136,7 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long * return (old & (1UL << (nr & 0x1f))) != 0; \ } -#else /* CONFIG_ARC_PLAT_EZNPS */ - -#define BIT_OP(op, c_op, asm_op) \ -static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\ -{ \ - m += nr >> 5; \ - \ - nr = (1UL << (nr & 0x1f)); \ - if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3) \ - nr = ~nr; \ - \ - __asm__ __volatile__( \ - " mov r2, %0\n" \ - " mov r3, %1\n" \ - " .word %2\n" \ - : \ - : "r"(nr), "r"(m), "i"(asm_op) \ - : "r2", "r3", "memory"); \ -} - -#define TEST_N_BIT_OP(op, c_op, asm_op) \ -static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *m)\ -{ \ - unsigned long old; \ - \ - m += nr >> 5; \ - \ - nr = old = (1UL << (nr & 0x1f)); \ - if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3) \ - old = ~old; \ - \ - /* Explicit full memory barrier needed before/after */ \ - smp_mb(); \ - \ - __asm__ __volatile__( \ - " mov r2, %0\n" \ - " mov r3, %1\n" \ - " .word %2\n" \ - " mov %0, r2" \ - : "+r"(old) \ - : "r"(m), "i"(asm_op) \ - : "r2", "r3", "memory"); \ - \ - smp_mb(); \ - \ - return (old & nr) != 0; \ -} - -#endif /* CONFIG_ARC_PLAT_EZNPS */ +#endif /*************************************** * Non atomic variants @@ -226,15 +178,9 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long /* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\ __TEST_N_BIT_OP(op, c_op, asm_op) -#ifndef CONFIG_ARC_PLAT_EZNPS BIT_OPS(set, |, bset) BIT_OPS(clear, & ~, bclr) BIT_OPS(change, ^, bxor) -#else -BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3) -BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3) -BIT_OPS(change, ^, CTOP_INST_AXOR_DI_R2_R2_R3) -#endif /* * This routine doesn't need to be atomic. diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h index c11398160240..9b87e162e539 100644 --- a/arch/arc/include/asm/cmpxchg.h +++ b/arch/arc/include/asm/cmpxchg.h @@ -20,7 +20,7 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new) /* * Explicit full memory barrier needed before/after as - * LLOCK/SCOND thmeselves don't provide any such semantics + * LLOCK/SCOND themselves don't provide any such semantics */ smp_mb(); @@ -41,7 +41,7 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new) return prev; } -#elif !defined(CONFIG_ARC_PLAT_EZNPS) +#else /* !CONFIG_ARC_HAS_LLSC */ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new) @@ -61,33 +61,7 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new) return prev; } -#else /* CONFIG_ARC_PLAT_EZNPS */ - -static inline unsigned long -__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new) -{ - /* - * Explicit full memory barrier needed before/after - */ - smp_mb(); - - write_aux_reg(CTOP_AUX_GPA1, expected); - - __asm__ __volatile__( - " mov r2, %0\n" - " mov r3, %1\n" - " .word %2\n" - " mov %0, r2" - : "+r"(new) - : "r"(ptr), "i"(CTOP_INST_EXC_DI_R2_R2_R3) - : "r2", "r3", "memory"); - - smp_mb(); - - return new; -} - -#endif /* CONFIG_ARC_HAS_LLSC */ +#endif #define cmpxchg(ptr, o, n) ({ \ (typeof(*(ptr)))__cmpxchg((ptr), \ @@ -104,8 +78,6 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new) #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) -#ifndef CONFIG_ARC_PLAT_EZNPS - /* * xchg (reg with memory) based on "Native atomic" EX insn */ @@ -168,44 +140,6 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr, #endif -#else /* CONFIG_ARC_PLAT_EZNPS */ - -static inline unsigned long __xchg(unsigned long val, volatile void *ptr, - int size) -{ - extern unsigned long __xchg_bad_pointer(void); - - switch (size) { - case 4: - /* - * Explicit full memory barrier needed before/after - */ - smp_mb(); - - __asm__ __volatile__( - " mov r2, %0\n" - " mov r3, %1\n" - " .word %2\n" - " mov %0, r2\n" - : "+r"(val) - : "r"(ptr), "i"(CTOP_INST_XEX_DI_R2_R2_R3) - : "r2", "r3", "memory"); - - smp_mb(); - - return val; - } - return __xchg_bad_pointer(); -} - -#define xchg(ptr, with) ({ \ - (typeof(*(ptr)))__xchg((unsigned long)(with), \ - (ptr), \ - sizeof(*(ptr))); \ -}) - -#endif /* CONFIG_ARC_PLAT_EZNPS */ - /* * "atomic" variant of xchg() * REQ: It needs to follow the same serialization rules as other atomic_xxx() diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h index c3aa775878dc..6dbf5cecc8cc 100644 --- a/arch/arc/include/asm/entry-compact.h +++ b/arch/arc/include/asm/entry-compact.h @@ -33,10 +33,6 @@ #include <asm/irqflags-compact.h> #include <asm/thread_info.h> /* For THREAD_SIZE */ -#ifdef CONFIG_ARC_PLAT_EZNPS -#include <plat/ctop.h> -#endif - /*-------------------------------------------------------------- * Switch to Kernel Mode stack if SP points to User Mode stack * @@ -189,12 +185,6 @@ PUSHAX lp_start PUSHAX erbta -#ifdef CONFIG_ARC_PLAT_EZNPS - .word CTOP_INST_SCHD_RW - PUSHAX CTOP_AUX_GPA1 - PUSHAX CTOP_AUX_EFLAGS -#endif - lr r10, [ecr] st r10, [sp, PT_event] /* EV_Trap expects r10 to have ECR */ .endm @@ -211,11 +201,6 @@ * by hardware and that is not good. *-------------------------------------------------------------*/ .macro EXCEPTION_EPILOGUE -#ifdef CONFIG_ARC_PLAT_EZNPS - .word CTOP_INST_SCHD_RW - POPAX CTOP_AUX_EFLAGS - POPAX CTOP_AUX_GPA1 -#endif POPAX erbta POPAX lp_start @@ -278,11 +263,6 @@ PUSHAX lp_start PUSHAX bta_l\LVL\() -#ifdef CONFIG_ARC_PLAT_EZNPS - .word CTOP_INST_SCHD_RW - PUSHAX CTOP_AUX_GPA1 - PUSHAX CTOP_AUX_EFLAGS -#endif .endm /*-------------------------------------------------------------- @@ -295,11 +275,6 @@ * by hardware and that is not good. *-------------------------------------------------------------*/ .macro INTERRUPT_EPILOGUE LVL -#ifdef CONFIG_ARC_PLAT_EZNPS - .word CTOP_INST_SCHD_RW - POPAX CTOP_AUX_EFLAGS - POPAX CTOP_AUX_GPA1 -#endif POPAX bta_l\LVL\() POPAX lp_start @@ -327,13 +302,11 @@ bic \reg, sp, (THREAD_SIZE - 1) .endm -#ifndef CONFIG_ARC_PLAT_EZNPS /* Get CPU-ID of this core */ .macro GET_CPU_ID reg lr \reg, [identity] lsr \reg, \reg, 8 bmsk \reg, \reg, 7 .endm -#endif #endif /* __ASM_ARC_ENTRY_COMPACT_H */ diff --git a/arch/arc/include/asm/linkage.h b/arch/arc/include/asm/linkage.h index fe19f1d412e7..c9434ff3aa4c 100644 --- a/arch/arc/include/asm/linkage.h +++ b/arch/arc/include/asm/linkage.h @@ -64,15 +64,15 @@ #else /* !__ASSEMBLY__ */ #ifdef CONFIG_ARC_HAS_ICCM -#define __arcfp_code __section(.text.arcfp) +#define __arcfp_code __section(".text.arcfp") #else -#define __arcfp_code __section(.text) +#define __arcfp_code __section(".text") #endif #ifdef CONFIG_ARC_HAS_DCCM -#define __arcfp_data __section(.data.arcfp) +#define __arcfp_data __section(".data.arcfp") #else -#define __arcfp_data __section(.data) +#define __arcfp_data __section(".data") #endif #endif /* __ASSEMBLY__ */ diff --git a/arch/arc/include/asm/mach_desc.h b/arch/arc/include/asm/mach_desc.h index 73746ed5b834..c4e197059379 100644 --- a/arch/arc/include/asm/mach_desc.h +++ b/arch/arc/include/asm/mach_desc.h @@ -53,7 +53,7 @@ extern const struct machine_desc __arch_info_begin[], __arch_info_end[]; */ #define MACHINE_START(_type, _name) \ static const struct machine_desc __mach_desc_##_type \ -__used __section(.arch.info.init) = { \ +__used __section(".arch.info.init") = { \ .name = _name, #define MACHINE_END \ diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h index 0fcea5bad343..e4031ecd3c8c 100644 --- a/arch/arc/include/asm/processor.h +++ b/arch/arc/include/asm/processor.h @@ -17,13 +17,6 @@ #include <asm/dsp.h> #include <asm/fpu.h> -#ifdef CONFIG_ARC_PLAT_EZNPS -struct eznps_dp { - unsigned int eflags; - unsigned int gpa1; -}; -#endif - /* Arch specific stuff which needs to be saved per task. * However these items are not so important so as to earn a place in * struct thread_info @@ -38,9 +31,6 @@ struct thread_struct { #ifdef CONFIG_ARC_FPU_SAVE_RESTORE struct arc_fpu fpu; #endif -#ifdef CONFIG_ARC_PLAT_EZNPS - struct eznps_dp dp; -#endif }; #define INIT_THREAD { \ @@ -60,17 +50,8 @@ struct task_struct; * A lot of busy-wait loops in SMP are based off of non-volatile data otherwise * get optimised away by gcc */ -#ifndef CONFIG_EZNPS_MTM_EXT - #define cpu_relax() barrier() -#else - -#define cpu_relax() \ - __asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory") - -#endif - #define KSTK_EIP(tsk) (task_pt_regs(tsk)->ret) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->sp) @@ -118,25 +99,7 @@ extern unsigned int get_wchan(struct task_struct *p); #define USER_KERNEL_GUTTER (VMALLOC_START - TASK_SIZE) -#ifdef CONFIG_ARC_PLAT_EZNPS -/* NPS architecture defines special window of 129M in user address space for - * special memory areas, when accessing this window the MMU do not use TLB. - * Instead MMU direct the access to: - * 0x57f00000:0x57ffffff -- 1M of closely coupled memory (aka CMEM) - * 0x58000000:0x5fffffff -- 16 huge pages, 8M each, with fixed map (aka FMTs) - * - * CMEM - is the fastest memory we got and its size is 16K. - * FMT - is used to map either to internal/external memory. - * Internal memory is the second fast memory and its size is 16M - * External memory is the biggest memory (16G) and also the slowest. - * - * STACK_TOP need to be PMD align (21bit) that is why we supply 0x57e00000. - */ -#define STACK_TOP 0x57e00000 -#else #define STACK_TOP TASK_SIZE -#endif - #define STACK_TOP_MAX STACK_TOP /* This decides where the kernel will search for a free chunk of vm diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index 2fdb87addadc..4c3c9be5bd16 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h @@ -16,11 +16,6 @@ #ifdef CONFIG_ISA_ARCOMPACT struct pt_regs { -#ifdef CONFIG_ARC_PLAT_EZNPS - unsigned long eflags; /* Extended FLAGS */ - unsigned long gpa1; /* General Purpose Aux */ -#endif - /* Real registers */ unsigned long bta; /* bta_l1, bta_l2, erbta */ diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h index 61a97fe70b86..01f85478170d 100644 --- a/arch/arc/include/asm/setup.h +++ b/arch/arc/include/asm/setup.h @@ -9,11 +9,7 @@ #include <linux/types.h> #include <uapi/asm/setup.h> -#ifdef CONFIG_ARC_PLAT_EZNPS -#define COMMAND_LINE_SIZE 2048 -#else #define COMMAND_LINE_SIZE 256 -#endif /* * Data structure to map a ID to string diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h index 94bbed88e3fc..192871608925 100644 --- a/arch/arc/include/asm/spinlock.h +++ b/arch/arc/include/asm/spinlock.h @@ -232,15 +232,9 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) __asm__ __volatile__( "1: ex %0, [%1] \n" -#ifdef CONFIG_EZNPS_MTM_EXT - " .word %3 \n" -#endif " breq %0, %2, 1b \n" : "+&r" (val) : "r"(&(lock->slock)), "ir"(__ARCH_SPIN_LOCK_LOCKED__) -#ifdef CONFIG_EZNPS_MTM_EXT - , "i"(CTOP_INST_SCHD_RW) -#endif : "memory"); smp_mb(); diff --git a/arch/arc/include/asm/switch_to.h b/arch/arc/include/asm/switch_to.h index 4a3d67989d19..1f85de8288b1 100644 --- a/arch/arc/include/asm/switch_to.h +++ b/arch/arc/include/asm/switch_to.h @@ -12,19 +12,10 @@ #include <asm/dsp-impl.h> #include <asm/fpu.h> -#ifdef CONFIG_ARC_PLAT_EZNPS -extern void dp_save_restore(struct task_struct *p, struct task_struct *n); -#define ARC_EZNPS_DP_PREV(p, n) dp_save_restore(p, n) -#else -#define ARC_EZNPS_DP_PREV(p, n) - -#endif /* !CONFIG_ARC_PLAT_EZNPS */ - struct task_struct *__switch_to(struct task_struct *p, struct task_struct *n); #define switch_to(prev, next, last) \ do { \ - ARC_EZNPS_DP_PREV(prev, next); \ dsp_save_restore(prev, next); \ fpu_save_restore(prev, next); \ last = __switch_to(prev, next);\ diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c index e172c3333a84..1a76f2d6f694 100644 --- a/arch/arc/kernel/ctx_sw.c +++ b/arch/arc/kernel/ctx_sw.c @@ -14,9 +14,6 @@ #include <asm/asm-offsets.h> #include <linux/sched.h> #include <linux/sched/debug.h> -#ifdef CONFIG_ARC_PLAT_EZNPS -#include <plat/ctop.h> -#endif #define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4) @@ -68,16 +65,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) #ifndef CONFIG_SMP "st %2, [@_current_task] \n\t" #else -#ifdef CONFIG_ARC_PLAT_EZNPS - "lr r24, [%4] \n\t" -#ifndef CONFIG_EZNPS_MTM_EXT - "lsr r24, r24, 4 \n\t" -#endif -#else "lr r24, [identity] \n\t" "lsr r24, r24, 8 \n\t" "bmsk r24, r24, 7 \n\t" -#endif "add2 r24, @_current_task, r24 \n\t" "st %2, [r24] \n\t" #endif @@ -115,9 +105,6 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) : "=r"(tmp) : "n"(KSP_WORD_OFF), "r"(next), "r"(prev) -#ifdef CONFIG_ARC_PLAT_EZNPS - , "i"(CTOP_AUX_LOGIC_GLOBAL_ID) -#endif : "blink" ); diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c index fa86d13df5ed..721d465f1580 100644 --- a/arch/arc/kernel/devtree.c +++ b/arch/arc/kernel/devtree.c @@ -29,8 +29,6 @@ static void __init arc_set_early_base_baud(unsigned long dt_root) else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp") || of_flat_dt_is_compatible(dt_root, "snps,hsdk")) arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x & HSDK) */ - else if (of_flat_dt_is_compatible(dt_root, "ezchip,arc-nps")) - arc_base_baud = 800000000; /* Fixed 800MHz clk (NPS) */ else arc_base_baud = 50000000; /* Fixed default 50MHz */ } diff --git a/arch/arc/kernel/kprobes.c b/arch/arc/kernel/kprobes.c index 7d3efe83cba7..cabef45f11df 100644 --- a/arch/arc/kernel/kprobes.c +++ b/arch/arc/kernel/kprobes.c @@ -388,6 +388,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, { ri->ret_addr = (kprobe_opcode_t *) regs->blink; + ri->fp = NULL; /* Replace the return addr with trampoline addr */ regs->blink = (unsigned long)&kretprobe_trampoline; @@ -396,58 +397,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, static int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *tmp; - unsigned long flags, orig_ret_address = 0; - unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; - - INIT_HLIST_HEAD(&empty_rp); - kretprobe_hash_lock(current, &head, &flags); - - /* - * It is possible to have multiple instances associated with a given - * task either because an multiple functions in the call path - * have a return probe installed on them, and/or more than one return - * return probe was registered for a target function. - * - * We can handle this because: - * - instances are always inserted at the head of the list - * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the - * real return address, and all the rest will point to - * kretprobe_trampoline - */ - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - if (ri->rp && ri->rp->handler) - ri->rp->handler(ri, regs); - - orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); - - if (orig_ret_address != trampoline_address) { - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - } - - kretprobe_assert(ri, orig_ret_address, trampoline_address); - regs->ret = orig_ret_address; - - kretprobe_hash_unlock(current, &flags); - - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } + regs->ret = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); /* By returning a non zero value, we are telling the kprobe handler * that we don't want the post_handler to run diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c index 79849f37e782..145722f80c9b 100644 --- a/arch/arc/kernel/perf_event.c +++ b/arch/arc/kernel/perf_event.c @@ -562,7 +562,7 @@ static int arc_pmu_device_probe(struct platform_device *pdev) { struct arc_reg_pct_build pct_bcr; struct arc_reg_cc_build cc_bcr; - int i, has_interrupts, irq; + int i, has_interrupts, irq = -1; int counter_size; /* in bits */ union cc_name { @@ -637,19 +637,28 @@ static int arc_pmu_device_probe(struct platform_device *pdev) .attr_groups = arc_pmu->attr_groups, }; - if (has_interrupts && (irq = platform_get_irq(pdev, 0) >= 0)) { + if (has_interrupts) { + irq = platform_get_irq(pdev, 0); + if (irq >= 0) { + int ret; - arc_pmu->irq = irq; + arc_pmu->irq = irq; - /* intc map function ensures irq_set_percpu_devid() called */ - request_percpu_irq(irq, arc_pmu_intr, "ARC perf counters", - this_cpu_ptr(&arc_pmu_cpu)); + /* intc map function ensures irq_set_percpu_devid() called */ + ret = request_percpu_irq(irq, arc_pmu_intr, "ARC perf counters", + this_cpu_ptr(&arc_pmu_cpu)); + + if (!ret) + on_each_cpu(arc_cpu_pmu_irq_init, &irq, 1); + else + irq = -1; + } - on_each_cpu(arc_cpu_pmu_irq_init, &irq, 1); - } else { - arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT; } + if (irq == -1) + arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT; + /* * perf parser doesn't really like '-' symbol in events name, so let's * use '_' in arc pct name as it goes to kernel PMU event prefix. diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index efeba1fe7252..37f724ad5e39 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c @@ -116,17 +116,6 @@ void arch_cpu_idle(void) :"I"(arg)); /* can't be "r" has to be embedded const */ } -#elif defined(CONFIG_EZNPS_MTM_EXT) /* ARC700 variant in NPS */ - -void arch_cpu_idle(void) -{ - /* only the calling HW thread needs to sleep */ - __asm__ __volatile__( - ".word %0 \n" - : - :"i"(CTOP_INST_HWSCHD_WFT_IE12)); -} - #else /* ARC700 */ void arch_cpu_idle(void) @@ -278,10 +267,6 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp) */ regs->status32 = STATUS_U_MASK | STATUS_L_MASK | ISA_INIT_STATUS_BITS; -#ifdef CONFIG_EZNPS_MTM_EXT - regs->eflags = 0; -#endif - fpu_init_task(regs); /* bogus seed values for debugging */ diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c index 8222f8c54690..2be55fb96d87 100644 --- a/arch/arc/kernel/signal.c +++ b/arch/arc/kernel/signal.c @@ -394,6 +394,6 @@ void do_notify_resume(struct pt_regs *regs) * ASM glue gaurantees that this is only called when returning to * user mode */ - if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) + if (test_thread_flag(TIF_NOTIFY_RESUME)) tracehook_notify_resume(regs); } diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c index eca35e02ce06..52906d314537 100644 --- a/arch/arc/kernel/smp.c +++ b/arch/arc/kernel/smp.c @@ -226,7 +226,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) } if (!cpu_online(cpu)) { - pr_info("Timeout: CPU%u FAILED to comeup !!!\n", cpu); + pr_info("Timeout: CPU%u FAILED to come up !!!\n", cpu); return -1; } diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S index 54139a6f469b..33ce59d91461 100644 --- a/arch/arc/kernel/vmlinux.lds.S +++ b/arch/arc/kernel/vmlinux.lds.S @@ -122,6 +122,7 @@ SECTIONS _end = . ; STABS_DEBUG + ELF_DETAILS DISCARDS .arcextmap 0 : { diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index e947572a521e..517988e60cfc 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -3,7 +3,7 @@ * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) */ -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <asm/cache.h> #include <asm/cacheflush.h> diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S index 31f54bdd95f2..062fae46c3f8 100644 --- a/arch/arc/mm/tlbex.S +++ b/arch/arc/mm/tlbex.S @@ -281,13 +281,6 @@ ex_saved_reg1: .macro COMMIT_ENTRY_TO_MMU #if (CONFIG_ARC_MMU_VER < 4) -#ifdef CONFIG_EZNPS_MTM_EXT - /* verify if entry for this vaddr+ASID already exists */ - sr TLBProbe, [ARC_REG_TLBCOMMAND] - lr r0, [ARC_REG_TLBINDEX] - bbit0 r0, 31, 88f -#endif - /* Get free TLB slot: Set = computed from vaddr, way = random */ sr TLBGetIndex, [ARC_REG_TLBCOMMAND] diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig deleted file mode 100644 index a645bca5899a..000000000000 --- a/arch/arc/plat-eznps/Kconfig +++ /dev/null @@ -1,58 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# For a description of the syntax of this configuration file, -# see Documentation/kbuild/kconfig-language.rst. -# - -menuconfig ARC_PLAT_EZNPS - bool "\"EZchip\" ARC dev platform" - depends on ISA_ARCOMPACT - select CPU_BIG_ENDIAN - select CLKSRC_NPS if !PHYS_ADDR_T_64BIT - select EZNPS_GIC - select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET - help - Support for EZchip development platforms, - based on ARC700 cores. - We handle few flavors: - - Hardware Emulator AKA HE which is FPGA based chassis - - Simulator based on MetaWare nSIM - - NPS400 chip based on ASIC - -config EZNPS_MTM_EXT - bool "ARC-EZchip MTM Extensions" - select CPUMASK_OFFSTACK - depends on ARC_PLAT_EZNPS && SMP - default y - help - Here we add new hierarchy for CPUs topology. - We got: - Core - Thread - At the new thread level each CPU represent one HW thread. - At highest hierarchy each core contain 16 threads, - any of them seem like CPU from Linux point of view. - All threads within same core share the execution unit of the - core and HW scheduler round robin between them. - -config EZNPS_MEM_ERROR_ALIGN - bool "ARC-EZchip Memory error as an exception" - depends on EZNPS_MTM_EXT - default n - help - On the real chip of the NPS, user memory errors are handled - as a machine check exception, which is fatal, whereas on - simulator platform for NPS, is handled as a Level 2 interrupt - (just a stock ARC700) which is recoverable. This option makes - simulator behave like hardware. - -config EZNPS_SHARED_AUX_REGS - bool "ARC-EZchip Shared Auxiliary Registers Per Core" - depends on ARC_PLAT_EZNPS - default y - help - On the real chip of the NPS, auxiliary registers are shared between - all the cpus of the core, whereas on simulator platform for NPS, - each cpu has a different set of auxiliary registers. Configuration - should be unset if auxiliary registers are not shared between the cpus - of the core, so there will be a need to initialize them per cpu. diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile deleted file mode 100644 index ebb9723002cf..000000000000 --- a/arch/arc/plat-eznps/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile for the linux kernel. -# - -obj-y := entry.o platform.o ctop.o -obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o diff --git a/arch/arc/plat-eznps/ctop.c b/arch/arc/plat-eznps/ctop.c deleted file mode 100644 index b398e6e838a9..000000000000 --- a/arch/arc/plat-eznps/ctop.c +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright(c) 2015 EZchip Technologies. - */ - -#include <linux/sched.h> -#include <asm/processor.h> -#include <plat/ctop.h> - -void dp_save_restore(struct task_struct *prev, struct task_struct *next) -{ - struct eznps_dp *prev_task_dp = &prev->thread.dp; - struct eznps_dp *next_task_dp = &next->thread.dp; - - /* Here we save all Data Plane related auxiliary registers */ - prev_task_dp->eflags = read_aux_reg(CTOP_AUX_EFLAGS); - write_aux_reg(CTOP_AUX_EFLAGS, next_task_dp->eflags); - - prev_task_dp->gpa1 = read_aux_reg(CTOP_AUX_GPA1); - write_aux_reg(CTOP_AUX_GPA1, next_task_dp->gpa1); -} diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S deleted file mode 100644 index 3f18c0108e72..000000000000 --- a/arch/arc/plat-eznps/entry.S +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/******************************************************************************* - - EZNPS CPU startup Code - Copyright(c) 2012 EZchip Technologies. - - -*******************************************************************************/ -#include <linux/linkage.h> -#include <asm/entry.h> -#include <asm/cache.h> -#include <plat/ctop.h> - - .cpu A7 - - .section .init.text, "ax",@progbits - .align 1024 ; HW requierment for restart first PC - -ENTRY(res_service) -#if defined(CONFIG_EZNPS_MTM_EXT) && defined(CONFIG_EZNPS_SHARED_AUX_REGS) - ; There is no work for HW thread id != 0 - lr r3, [CTOP_AUX_THREAD_ID] - cmp r3, 0 - jne stext -#endif - -#ifdef CONFIG_ARC_HAS_DCACHE - ; With no cache coherency mechanism D$ need to be used very carefully. - ; Address space: - ; 0G-2G: We disable CONFIG_ARC_CACHE_PAGES. - ; 2G-3G: We disable D$ by setting this bit. - ; 3G-4G: D$ is disabled by architecture. - ; FMT are huge pages for user application reside at 0-2G. - ; Only FMT left as one who can use D$ where each such page got - ; disable/enable bit for cachability. - ; Programmer will use FMT pages for private data so cache coherency - ; would not be a problem. - ; First thing we invalidate D$ - sr 1, [ARC_REG_DC_IVDC] - sr HW_COMPLY_KRN_NOT_D_CACHED, [CTOP_AUX_HW_COMPLY] -#endif - -#ifdef CONFIG_SMP - ; We set logical cpuid to be used by GET_CPUID - ; We do not use physical cpuid since we want ids to be continious when - ; it comes to cpus on the same quad cluster. - ; This is useful for applications that used shared resources of a quad - ; cluster such SRAMS. - lr r3, [CTOP_AUX_CORE_ID] - sr r3, [CTOP_AUX_LOGIC_CORE_ID] - lr r3, [CTOP_AUX_CLUSTER_ID] - ; Set logical is acheived by swap of 2 middle bits of cluster id (4 bit) - ; r3 is used since we use short instruction and we need q-class reg - .short CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST - .word CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM - sr r3, [CTOP_AUX_LOGIC_CLUSTER_ID] -#endif - - j stext -END(res_service) diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h deleted file mode 100644 index 77712c5ffe84..000000000000 --- a/arch/arc/plat-eznps/include/plat/ctop.h +++ /dev/null @@ -1,208 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright(c) 2015 EZchip Technologies. - */ - -#ifndef _PLAT_EZNPS_CTOP_H -#define _PLAT_EZNPS_CTOP_H - -#ifndef CONFIG_ARC_PLAT_EZNPS -#error "Incorrect ctop.h include" -#endif - -#include <linux/bits.h> -#include <linux/types.h> -#include <soc/nps/common.h> - -/* core auxiliary registers */ -#ifdef __ASSEMBLY__ -#define CTOP_AUX_BASE (-0x800) -#else -#define CTOP_AUX_BASE 0xFFFFF800 -#endif - -#define CTOP_AUX_GLOBAL_ID (CTOP_AUX_BASE + 0x000) -#define CTOP_AUX_CLUSTER_ID (CTOP_AUX_BASE + 0x004) -#define CTOP_AUX_CORE_ID (CTOP_AUX_BASE + 0x008) -#define CTOP_AUX_THREAD_ID (CTOP_AUX_BASE + 0x00C) -#define CTOP_AUX_LOGIC_GLOBAL_ID (CTOP_AUX_BASE + 0x010) -#define CTOP_AUX_LOGIC_CLUSTER_ID (CTOP_AUX_BASE + 0x014) -#define CTOP_AUX_LOGIC_CORE_ID (CTOP_AUX_BASE + 0x018) -#define CTOP_AUX_MT_CTRL (CTOP_AUX_BASE + 0x020) -#define CTOP_AUX_HW_COMPLY (CTOP_AUX_BASE + 0x024) -#define CTOP_AUX_DPC (CTOP_AUX_BASE + 0x02C) -#define CTOP_AUX_LPC (CTOP_AUX_BASE + 0x030) -#define CTOP_AUX_EFLAGS (CTOP_AUX_BASE + 0x080) -#define CTOP_AUX_GPA1 (CTOP_AUX_BASE + 0x08C) -#define CTOP_AUX_UDMC (CTOP_AUX_BASE + 0x300) - -/* EZchip core instructions */ -#define CTOP_INST_HWSCHD_WFT_IE12 0x3E6F7344 -#define CTOP_INST_HWSCHD_OFF_R4 0x3C6F00BF -#define CTOP_INST_HWSCHD_RESTORE_R4 0x3E6F7103 -#define CTOP_INST_SCHD_RW 0x3E6F7004 -#define CTOP_INST_SCHD_RD 0x3E6F7084 -#define CTOP_INST_ASRI_0_R3 0x3B56003E -#define CTOP_INST_XEX_DI_R2_R2_R3 0x4A664C00 -#define CTOP_INST_EXC_DI_R2_R2_R3 0x4A664C01 -#define CTOP_INST_AADD_DI_R2_R2_R3 0x4A664C02 -#define CTOP_INST_AAND_DI_R2_R2_R3 0x4A664C04 -#define CTOP_INST_AOR_DI_R2_R2_R3 0x4A664C05 -#define CTOP_INST_AXOR_DI_R2_R2_R3 0x4A664C06 - -/* Do not use D$ for address in 2G-3G */ -#define HW_COMPLY_KRN_NOT_D_CACHED BIT(28) - -#define NPS_MSU_EN_CFG 0x80 -#define NPS_CRG_BLKID 0x480 -#define NPS_CRG_SYNC_BIT BIT(0) -#define NPS_GIM_BLKID 0x5C0 - -/* GIM registers and fields*/ -#define NPS_GIM_UART_LINE BIT(7) -#define NPS_GIM_DBG_LAN_EAST_TX_DONE_LINE BIT(10) -#define NPS_GIM_DBG_LAN_EAST_RX_RDY_LINE BIT(11) -#define NPS_GIM_DBG_LAN_WEST_TX_DONE_LINE BIT(25) -#define NPS_GIM_DBG_LAN_WEST_RX_RDY_LINE BIT(26) - -#ifndef __ASSEMBLY__ -/* Functional registers definition */ -struct nps_host_reg_mtm_cfg { - union { - struct { - u32 gen:1, gdis:1, clk_gate_dis:1, asb:1, - __reserved:9, nat:3, ten:16; - }; - u32 value; - }; -}; - -struct nps_host_reg_mtm_cpu_cfg { - union { - struct { - u32 csa:22, dmsid:6, __reserved:3, cs:1; - }; - u32 value; - }; -}; - -struct nps_host_reg_thr_init { - union { - struct { - u32 str:1, __reserved:27, thr_id:4; - }; - u32 value; - }; -}; - -struct nps_host_reg_thr_init_sts { - union { - struct { - u32 bsy:1, err:1, __reserved:26, thr_id:4; - }; - u32 value; - }; -}; - -struct nps_host_reg_msu_en_cfg { - union { - struct { - u32 __reserved1:11, - rtc_en:1, ipc_en:1, gim_1_en:1, - gim_0_en:1, ipi_en:1, buff_e_rls_bmuw:1, - buff_e_alc_bmuw:1, buff_i_rls_bmuw:1, buff_i_alc_bmuw:1, - buff_e_rls_bmue:1, buff_e_alc_bmue:1, buff_i_rls_bmue:1, - buff_i_alc_bmue:1, __reserved2:1, buff_e_pre_en:1, - buff_i_pre_en:1, pmuw_ja_en:1, pmue_ja_en:1, - pmuw_nj_en:1, pmue_nj_en:1, msu_en:1; - }; - u32 value; - }; -}; - -struct nps_host_reg_gim_p_int_dst { - union { - struct { - u32 int_out_en:1, __reserved1:4, - is:1, intm:2, __reserved2:4, - nid:4, __reserved3:4, cid:4, - __reserved4:4, tid:4; - }; - u32 value; - }; -}; - -/* AUX registers definition */ -struct nps_host_reg_aux_dpc { - union { - struct { - u32 ien:1, men:1, hen:1, reserved:29; - }; - u32 value; - }; -}; - -struct nps_host_reg_aux_udmc { - union { - struct { - u32 dcp:1, cme:1, __reserved:19, nat:3, - __reserved2:5, dcas:3; - }; - u32 value; - }; -}; - -struct nps_host_reg_aux_mt_ctrl { - union { - struct { - u32 mten:1, hsen:1, scd:1, sten:1, - st_cnt:8, __reserved:8, - hs_cnt:8, __reserved1:4; - }; - u32 value; - }; -}; - -struct nps_host_reg_aux_hw_comply { - union { - struct { - u32 me:1, le:1, te:1, knc:1, __reserved:28; - }; - u32 value; - }; -}; - -struct nps_host_reg_aux_lpc { - union { - struct { - u32 mep:1, __reserved:31; - }; - u32 value; - }; -}; - -/* CRG registers */ -#define REG_GEN_PURP_0 nps_host_reg_non_cl(NPS_CRG_BLKID, 0x1BF) - -/* GIM registers */ -#define REG_GIM_P_INT_EN_0 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x100) -#define REG_GIM_P_INT_POL_0 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x110) -#define REG_GIM_P_INT_SENS_0 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x114) -#define REG_GIM_P_INT_BLK_0 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x118) -#define REG_GIM_P_INT_DST_10 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13A) -#define REG_GIM_P_INT_DST_11 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13B) -#define REG_GIM_P_INT_DST_25 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x149) -#define REG_GIM_P_INT_DST_26 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x14A) - -#else - -.macro GET_CPU_ID reg - lr \reg, [CTOP_AUX_LOGIC_GLOBAL_ID] -#ifndef CONFIG_EZNPS_MTM_EXT - lsr \reg, \reg, 4 -#endif -.endm - -#endif /* __ASSEMBLY__ */ - -#endif /* _PLAT_EZNPS_CTOP_H */ diff --git a/arch/arc/plat-eznps/include/plat/mtm.h b/arch/arc/plat-eznps/include/plat/mtm.h deleted file mode 100644 index 7c55becc891b..000000000000 --- a/arch/arc/plat-eznps/include/plat/mtm.h +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright(c) 2015 EZchip Technologies. - */ - -#ifndef _PLAT_EZNPS_MTM_H -#define _PLAT_EZNPS_MTM_H - -#include <plat/ctop.h> - -static inline void *nps_mtm_reg_addr(u32 cpu, u32 reg) -{ - struct global_id gid; - u32 core, blkid; - - gid.value = cpu; - core = gid.core; - blkid = (((core & 0x0C) << 2) | (core & 0x03)); - - return nps_host_reg(cpu, blkid, reg); -} - -#ifdef CONFIG_EZNPS_MTM_EXT -#define NPS_CPU_TO_THREAD_NUM(cpu) \ - ({ struct global_id gid; gid.value = cpu; gid.thread; }) - -/* MTM registers */ -#define MTM_CFG(cpu) nps_mtm_reg_addr(cpu, 0x81) -#define MTM_THR_INIT(cpu) nps_mtm_reg_addr(cpu, 0x92) -#define MTM_THR_INIT_STS(cpu) nps_mtm_reg_addr(cpu, 0x93) - -#define get_thread(map) map.thread -#define eznps_max_cpus 4096 -#define eznps_cpus_per_cluster 256 - -void mtm_enable_core(unsigned int cpu); -int mtm_enable_thread(int cpu); -#else /* !CONFIG_EZNPS_MTM_EXT */ - -#define get_thread(map) 0 -#define eznps_max_cpus 256 -#define eznps_cpus_per_cluster 16 -#define mtm_enable_core(cpu) -#define mtm_enable_thread(cpu) 1 -#define NPS_CPU_TO_THREAD_NUM(cpu) 0 - -#endif /* CONFIG_EZNPS_MTM_EXT */ - -#endif /* _PLAT_EZNPS_MTM_H */ diff --git a/arch/arc/plat-eznps/include/plat/smp.h b/arch/arc/plat-eznps/include/plat/smp.h deleted file mode 100644 index e433f118bdca..000000000000 --- a/arch/arc/plat-eznps/include/plat/smp.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright(c) 2015 EZchip Technologies. - */ - -#ifndef __PLAT_EZNPS_SMP_H -#define __PLAT_EZNPS_SMP_H - -#ifdef CONFIG_SMP - -extern void res_service(void); - -#endif /* CONFIG_SMP */ - -#endif diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c deleted file mode 100644 index 3dcf5a9e2976..000000000000 --- a/arch/arc/plat-eznps/mtm.c +++ /dev/null @@ -1,166 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright(c) 2015 EZchip Technologies. - */ - -#include <linux/smp.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/io.h> -#include <linux/log2.h> -#include <asm/arcregs.h> -#include <plat/mtm.h> -#include <plat/smp.h> - -#define MT_HS_CNT_MIN 0x01 -#define MT_HS_CNT_MAX 0xFF -#define MT_CTRL_ST_CNT 0xF -#define NPS_NUM_HW_THREADS 0x10 - -static int mtm_hs_ctr = MT_HS_CNT_MAX; - -#ifdef CONFIG_EZNPS_MEM_ERROR_ALIGN -int do_memory_error(unsigned long address, struct pt_regs *regs) -{ - die("Invalid Mem Access", regs, address); - - return 1; -} -#endif - -static void mtm_init_nat(int cpu) -{ - struct nps_host_reg_mtm_cfg mtm_cfg; - struct nps_host_reg_aux_udmc udmc; - int log_nat, nat = 0, i, t; - - /* Iterate core threads and update nat */ - for (i = 0, t = cpu; i < NPS_NUM_HW_THREADS; i++, t++) - nat += test_bit(t, cpumask_bits(cpu_possible_mask)); - - log_nat = ilog2(nat); - - udmc.value = read_aux_reg(CTOP_AUX_UDMC); - udmc.nat = log_nat; - write_aux_reg(CTOP_AUX_UDMC, udmc.value); - - mtm_cfg.value = ioread32be(MTM_CFG(cpu)); - mtm_cfg.nat = log_nat; - iowrite32be(mtm_cfg.value, MTM_CFG(cpu)); -} - -static void mtm_init_thread(int cpu) -{ - int i, tries = 5; - struct nps_host_reg_thr_init thr_init; - struct nps_host_reg_thr_init_sts thr_init_sts; - - /* Set thread init register */ - thr_init.value = 0; - iowrite32be(thr_init.value, MTM_THR_INIT(cpu)); - thr_init.thr_id = NPS_CPU_TO_THREAD_NUM(cpu); - thr_init.str = 1; - iowrite32be(thr_init.value, MTM_THR_INIT(cpu)); - - /* Poll till thread init is done */ - for (i = 0; i < tries; i++) { - thr_init_sts.value = ioread32be(MTM_THR_INIT_STS(cpu)); - if (thr_init_sts.thr_id == thr_init.thr_id) { - if (thr_init_sts.bsy) - continue; - else if (thr_init_sts.err) - pr_warn("Failed to thread init cpu %u\n", cpu); - break; - } - - pr_warn("Wrong thread id in thread init for cpu %u\n", cpu); - break; - } - - if (i == tries) - pr_warn("Got thread init timeout for cpu %u\n", cpu); -} - -int mtm_enable_thread(int cpu) -{ - struct nps_host_reg_mtm_cfg mtm_cfg; - - if (NPS_CPU_TO_THREAD_NUM(cpu) == 0) - return 1; - - /* Enable thread in mtm */ - mtm_cfg.value = ioread32be(MTM_CFG(cpu)); - mtm_cfg.ten |= (1 << (NPS_CPU_TO_THREAD_NUM(cpu))); - iowrite32be(mtm_cfg.value, MTM_CFG(cpu)); - - return 0; -} - -void mtm_enable_core(unsigned int cpu) -{ - int i; - struct nps_host_reg_aux_mt_ctrl mt_ctrl; - struct nps_host_reg_mtm_cfg mtm_cfg; - struct nps_host_reg_aux_dpc dpc; - - /* - * Initializing dpc register in each CPU. - * Overwriting the init value of the DPC - * register so that CMEM and FMT virtual address - * spaces are accessible, and Data Plane HW - * facilities are enabled. - */ - dpc.ien = 1; - dpc.men = 1; - write_aux_reg(CTOP_AUX_DPC, dpc.value); - - if (NPS_CPU_TO_THREAD_NUM(cpu) != 0) - return; - - /* Initialize Number of Active Threads */ - mtm_init_nat(cpu); - - /* Initialize mtm_cfg */ - mtm_cfg.value = ioread32be(MTM_CFG(cpu)); - mtm_cfg.ten = 1; - iowrite32be(mtm_cfg.value, MTM_CFG(cpu)); - - /* Initialize all other threads in core */ - for (i = 1; i < NPS_NUM_HW_THREADS; i++) - mtm_init_thread(cpu + i); - - - /* Enable HW schedule, stall counter, mtm */ - mt_ctrl.value = 0; - mt_ctrl.hsen = 1; - mt_ctrl.hs_cnt = mtm_hs_ctr; - mt_ctrl.mten = 1; - write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value); - - /* - * HW scheduling mechanism will start working - * Only after call to instruction "schd.rw". - * cpu_relax() calls "schd.rw" instruction. - */ - cpu_relax(); -} - -/* Verify and set the value of the mtm hs counter */ -static int __init set_mtm_hs_ctr(char *ctr_str) -{ - int hs_ctr; - int ret; - - ret = kstrtoint(ctr_str, 0, &hs_ctr); - - if (ret || hs_ctr > MT_HS_CNT_MAX || hs_ctr < MT_HS_CNT_MIN) { - pr_err("** Invalid @nps_mtm_hs_ctr [%d] needs to be [%d:%d] (incl)\n", - hs_ctr, MT_HS_CNT_MIN, MT_HS_CNT_MAX); - return -EINVAL; - } - - mtm_hs_ctr = hs_ctr; - - return 0; -} -early_param("nps_mtm_hs_ctr", set_mtm_hs_ctr); diff --git a/arch/arc/plat-eznps/platform.c b/arch/arc/plat-eznps/platform.c deleted file mode 100644 index 6de2fe840043..000000000000 --- a/arch/arc/plat-eznps/platform.c +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright(c) 2015 EZchip Technologies. - */ - -#include <linux/init.h> -#include <linux/io.h> -#include <asm/mach_desc.h> -#include <plat/mtm.h> - -static void __init eznps_configure_msu(void) -{ - int cpu; - struct nps_host_reg_msu_en_cfg msu_en_cfg = {.value = 0}; - - msu_en_cfg.msu_en = 1; - msu_en_cfg.ipi_en = 1; - msu_en_cfg.gim_0_en = 1; - msu_en_cfg.gim_1_en = 1; - - /* enable IPI and GIM messages on all clusters */ - for (cpu = 0 ; cpu < eznps_max_cpus; cpu += eznps_cpus_per_cluster) - iowrite32be(msu_en_cfg.value, - nps_host_reg(cpu, NPS_MSU_BLKID, NPS_MSU_EN_CFG)); -} - -static void __init eznps_configure_gim(void) -{ - u32 reg_value; - u32 gim_int_lines; - struct nps_host_reg_gim_p_int_dst gim_p_int_dst = {.value = 0}; - - gim_int_lines = NPS_GIM_UART_LINE; - gim_int_lines |= NPS_GIM_DBG_LAN_EAST_TX_DONE_LINE; - gim_int_lines |= NPS_GIM_DBG_LAN_EAST_RX_RDY_LINE; - gim_int_lines |= NPS_GIM_DBG_LAN_WEST_TX_DONE_LINE; - gim_int_lines |= NPS_GIM_DBG_LAN_WEST_RX_RDY_LINE; - - /* - * IRQ polarity - * low or high level - * negative or positive edge - */ - reg_value = ioread32be(REG_GIM_P_INT_POL_0); - reg_value &= ~gim_int_lines; - iowrite32be(reg_value, REG_GIM_P_INT_POL_0); - - /* IRQ type level or edge */ - reg_value = ioread32be(REG_GIM_P_INT_SENS_0); - reg_value |= NPS_GIM_DBG_LAN_EAST_TX_DONE_LINE; - reg_value |= NPS_GIM_DBG_LAN_WEST_TX_DONE_LINE; - iowrite32be(reg_value, REG_GIM_P_INT_SENS_0); - - /* - * GIM interrupt select type for - * dbg_lan TX and RX interrupts - * should be type 1 - * type 0 = IRQ line 6 - * type 1 = IRQ line 7 - */ - gim_p_int_dst.is = 1; - iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_10); - iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_11); - iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_25); - iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_26); - - /* - * CTOP IRQ lines should be defined - * as blocking in GIM - */ - iowrite32be(gim_int_lines, REG_GIM_P_INT_BLK_0); - - /* enable CTOP IRQ lines in GIM */ - iowrite32be(gim_int_lines, REG_GIM_P_INT_EN_0); -} - -static void __init eznps_early_init(void) -{ - eznps_configure_msu(); - eznps_configure_gim(); -} - -static const char *eznps_compat[] __initconst = { - "ezchip,arc-nps", - NULL, -}; - -MACHINE_START(NPS, "nps") - .dt_compat = eznps_compat, - .init_early = eznps_early_init, -MACHINE_END diff --git a/arch/arc/plat-eznps/smp.c b/arch/arc/plat-eznps/smp.c deleted file mode 100644 index f119cb7de2ae..000000000000 --- a/arch/arc/plat-eznps/smp.c +++ /dev/null @@ -1,138 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright(c) 2015 EZchip Technologies. - */ - -#include <linux/smp.h> -#include <linux/of_fdt.h> -#include <linux/io.h> -#include <linux/irqdomain.h> -#include <asm/irq.h> -#include <plat/ctop.h> -#include <plat/smp.h> -#include <plat/mtm.h> - -#define NPS_DEFAULT_MSID 0x34 -#define NPS_MTM_CPU_CFG 0x90 - -static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"}; - -/* Get cpu map from device tree */ -static int __init eznps_get_map(const char *name, struct cpumask *cpumask) -{ - unsigned long dt_root = of_get_flat_dt_root(); - const char *buf; - - buf = of_get_flat_dt_prop(dt_root, name, NULL); - if (!buf) - return 1; - - cpulist_parse(buf, cpumask); - - return 0; -} - -/* Update board cpu maps */ -static void __init eznps_init_cpumasks(void) -{ - struct cpumask cpumask; - - if (eznps_get_map("present-cpus", &cpumask)) { - pr_err("Failed to get present-cpus from dtb"); - return; - } - init_cpu_present(&cpumask); - - if (eznps_get_map("possible-cpus", &cpumask)) { - pr_err("Failed to get possible-cpus from dtb"); - return; - } - init_cpu_possible(&cpumask); -} - -static void eznps_init_core(unsigned int cpu) -{ - u32 sync_value; - struct nps_host_reg_aux_hw_comply hw_comply; - struct nps_host_reg_aux_lpc lpc; - - if (NPS_CPU_TO_THREAD_NUM(cpu) != 0) - return; - - hw_comply.value = read_aux_reg(CTOP_AUX_HW_COMPLY); - hw_comply.me = 1; - hw_comply.le = 1; - hw_comply.te = 1; - write_aux_reg(CTOP_AUX_HW_COMPLY, hw_comply.value); - - /* Enable MMU clock */ - lpc.mep = 1; - write_aux_reg(CTOP_AUX_LPC, lpc.value); - - /* Boot CPU only */ - if (!cpu) { - /* Write to general purpose register in CRG */ - sync_value = ioread32be(REG_GEN_PURP_0); - sync_value |= NPS_CRG_SYNC_BIT; - iowrite32be(sync_value, REG_GEN_PURP_0); - } -} - -/* - * Master kick starting another CPU - */ -static void __init eznps_smp_wakeup_cpu(int cpu, unsigned long pc) -{ - struct nps_host_reg_mtm_cpu_cfg cpu_cfg; - - if (mtm_enable_thread(cpu) == 0) - return; - - /* set PC, dmsid, and start CPU */ - cpu_cfg.value = (u32)res_service; - cpu_cfg.dmsid = NPS_DEFAULT_MSID; - cpu_cfg.cs = 1; - iowrite32be(cpu_cfg.value, nps_mtm_reg_addr(cpu, NPS_MTM_CPU_CFG)); -} - -static void eznps_ipi_send(int cpu) -{ - struct global_id gid; - struct { - union { - struct { - u32 num:8, cluster:8, core:8, thread:8; - }; - u32 value; - }; - } ipi; - - gid.value = cpu; - ipi.thread = get_thread(gid); - ipi.core = gid.core; - ipi.cluster = nps_cluster_logic_to_phys(gid.cluster); - ipi.num = NPS_IPI_IRQ; - - __asm__ __volatile__( - " mov r3, %0\n" - " .word %1\n" - : - : "r"(ipi.value), "i"(CTOP_INST_ASRI_0_R3) - : "r3"); -} - -static void eznps_init_per_cpu(int cpu) -{ - smp_ipi_irq_setup(cpu, NPS_IPI_IRQ); - - eznps_init_core(cpu); - mtm_enable_core(cpu); -} - -struct plat_smp_ops plat_smp_ops = { - .info = smp_cpuinfo_buf, - .init_early_smp = eznps_init_cpumasks, - .cpu_kick = eznps_smp_wakeup_cpu, - .ipi_send = eznps_ipi_send, - .init_per_cpu = eznps_init_per_cpu, -}; diff --git a/arch/arc/plat-hsdk/Kconfig b/arch/arc/plat-hsdk/Kconfig index ce8101834518..6b5c54576f54 100644 --- a/arch/arc/plat-hsdk/Kconfig +++ b/arch/arc/plat-hsdk/Kconfig @@ -8,5 +8,6 @@ menuconfig ARC_SOC_HSDK select ARC_HAS_ACCL_REGS select ARC_IRQ_NO_AUTOSAVE select CLK_HSDK + select RESET_CONTROLLER select RESET_HSDK select HAVE_PCI diff --git a/arch/arc/plat-hsdk/platform.c b/arch/arc/plat-hsdk/platform.c index 0b961a2a10b8..0b63fc095b99 100644 --- a/arch/arc/plat-hsdk/platform.c +++ b/arch/arc/plat-hsdk/platform.c @@ -13,7 +13,7 @@ #include <asm/io.h> #include <asm/mach_desc.h> -int arc_hsdk_axi_dmac_coherent __section(.data) = 0; +int arc_hsdk_axi_dmac_coherent __section(".data") = 0; #define ARC_CCM_UNUSED_ADDR 0x60000000 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e00d94b16658..fe2f17eb2b50 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -49,6 +49,7 @@ config ARM select GENERIC_ARCH_TOPOLOGY if ARM_CPU_TOPOLOGY select GENERIC_ATOMIC64 if CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI select GENERIC_CLOCKEVENTS_BROADCAST if SMP + select GENERIC_IRQ_IPI if SMP select GENERIC_CPU_AUTOPROBE select GENERIC_EARLY_IOREMAP select GENERIC_IDLE_POLL_SETUP @@ -67,6 +68,7 @@ config ARM select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU select HAVE_ARCH_MMAP_RND_BITS if MMU + select HAVE_ARCH_SECCOMP select HAVE_ARCH_SECCOMP_FILTER if AEABI && !OABI_COMPAT select HAVE_ARCH_THREAD_STRUCT_WHITELIST select HAVE_ARCH_TRACEHOOK @@ -83,7 +85,7 @@ config ARM select HAVE_FAST_GUP if ARM_LPAE select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG - select HAVE_FUNCTION_TRACER if !XIP_KERNEL && (CC_IS_GCC || CLANG_VERSION >= 100000) + select HAVE_FUNCTION_TRACER if !XIP_KERNEL select HAVE_GCC_PLUGINS select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7) select HAVE_IDE if PCI || ISA || PCMCIA @@ -118,6 +120,7 @@ config ARM select PCI_SYSCALL if PCI select PERF_USE_VMALLOC select RTC_LIB + select SET_FS select SYS_SUPPORTS_APM_EMULATION # Above selects are sorted alphabetically; please add new ones # according to that. Thanks. @@ -265,9 +268,7 @@ config PHYS_OFFSET depends on !ARM_PATCH_PHYS_VIRT default DRAM_BASE if !MMU default 0x00000000 if ARCH_EBSA110 || \ - ARCH_FOOTBRIDGE || \ - ARCH_INTEGRATOR || \ - ARCH_REALVIEW + ARCH_FOOTBRIDGE default 0x10000000 if ARCH_OMAP1 || ARCH_RPC default 0x20000000 if ARCH_S5PV210 default 0xc0000000 if ARCH_SA1100 @@ -503,11 +504,12 @@ config ARCH_S3C24XX select GPIOLIB select GENERIC_IRQ_MULTI_HANDLER select HAVE_S3C2410_I2C if I2C - select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS select NEED_MACH_IO_H + select S3C2410_WATCHDOG select SAMSUNG_ATAGS select USE_OF + select WATCHDOG help Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443 and S3C2450 SoCs based systems, such as the Simtec Electronics BAST @@ -636,7 +638,6 @@ source "arch/arm/mach-dove/Kconfig" source "arch/arm/mach-ep93xx/Kconfig" source "arch/arm/mach-exynos/Kconfig" -source "arch/arm/plat-samsung/Kconfig" source "arch/arm/mach-footbridge/Kconfig" @@ -709,9 +710,7 @@ source "arch/arm/mach-realview/Kconfig" source "arch/arm/mach-rockchip/Kconfig" -source "arch/arm/mach-s3c24xx/Kconfig" - -source "arch/arm/mach-s3c64xx/Kconfig" +source "arch/arm/mach-s3c/Kconfig" source "arch/arm/mach-s5pv210/Kconfig" @@ -1617,20 +1616,6 @@ config UACCESS_WITH_MEMCPY However, if the CPU data cache is using a write-allocate mode, this option is unlikely to provide any performance gain. -config SECCOMP - bool - prompt "Enable seccomp to safely compute untrusted bytecode" - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via prctl(PR_SET_SECCOMP), it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - config PARAVIRT bool "Enable paravirtualization code" help diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 80000a66a4e3..8986a91a6f31 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1005,7 +1005,7 @@ choice via SCIFA4 on Renesas SH-Mobile AG5 (SH73A0). config DEBUG_S3C_UART0 - depends on PLAT_SAMSUNG + depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS select DEBUG_EXYNOS_UART if ARCH_EXYNOS select DEBUG_S3C24XX_UART if ARCH_S3C24XX select DEBUG_S3C64XX_UART if ARCH_S3C64XX @@ -1017,7 +1017,7 @@ choice by the boot-loader before use. config DEBUG_S3C_UART1 - depends on PLAT_SAMSUNG + depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS select DEBUG_EXYNOS_UART if ARCH_EXYNOS select DEBUG_S3C24XX_UART if ARCH_S3C24XX select DEBUG_S3C64XX_UART if ARCH_S3C64XX @@ -1029,7 +1029,7 @@ choice by the boot-loader before use. config DEBUG_S3C_UART2 - depends on PLAT_SAMSUNG + depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS select DEBUG_EXYNOS_UART if ARCH_EXYNOS select DEBUG_S3C24XX_UART if ARCH_S3C24XX select DEBUG_S3C64XX_UART if ARCH_S3C64XX @@ -1041,7 +1041,7 @@ choice by the boot-loader before use. config DEBUG_S3C_UART3 - depends on PLAT_SAMSUNG && (ARCH_EXYNOS || ARCH_S5PV210) + depends on ARCH_EXYNOS || ARCH_S5PV210 select DEBUG_EXYNOS_UART if ARCH_EXYNOS select DEBUG_S3C64XX_UART if ARCH_S3C64XX select DEBUG_S5PV210_UART if ARCH_S5PV210 @@ -1086,6 +1086,14 @@ choice on SA-11x0 UART ports. The kernel will check for the first enabled UART in a sequence 3-1-2. + config DEBUG_SD5203_UART + bool "Hisilicon SD5203 Debug UART" + depends on ARCH_SD5203 + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support + on SD5203 UART. + config DEBUG_SOCFPGA_UART0 depends on ARCH_SOCFPGA bool "Use SOCFPGA UART0 for low-level debug" @@ -1497,6 +1505,16 @@ config DEBUG_S3C64XX_UART config DEBUG_S5PV210_UART bool +config DEBUG_S3C_UART + depends on DEBUG_S3C2410_UART || DEBUG_S3C24XX_UART || \ + DEBUG_S3C64XX_UART || DEBUG_S5PV210_UART || \ + DEBUG_EXYNOS_UART + int + default "0" if DEBUG_S3C_UART0 + default "1" if DEBUG_S3C_UART1 + default "2" if DEBUG_S3C_UART2 + default "3" if DEBUG_S3C_UART3 + config DEBUG_OMAP2PLUS_UART bool depends on ARCH_OMAP2PLUS @@ -1546,6 +1564,17 @@ config DEBUG_SIRFSOC_UART bool depends on ARCH_SIRF +config DEBUG_UART_FLOW_CONTROL + bool "Enable flow control (CTS) for the debug UART" + depends on DEBUG_LL + default y if ARCH_EBSA110 || DEBUG_FOOTBRIDGE_COM1 || DEBUG_GEMINI || ARCH_RPC + help + Some UART ports are connected to terminals that will use modem + control signals to indicate whether they are ready to receive text. + In practice this means that the terminal is asserting the special + control signal CTS (Clear To Send). If your debug UART supports + this and your debug terminal will require it, enable this option. + config DEBUG_LL_INCLUDE string default "debug/sa1100.S" if DEBUG_SA1100 @@ -1639,6 +1668,7 @@ config DEBUG_UART_PHYS default 0x11006000 if DEBUG_MT6589_UART0 default 0x11009000 if DEBUG_MT8135_UART3 default 0x16000000 if DEBUG_INTEGRATOR + default 0x1600d000 if DEBUG_SD5203_UART default 0x18000300 if DEBUG_BCM_5301X default 0x18000400 if DEBUG_BCM_HR2 default 0x18010000 if DEBUG_SIRFATLAS7_UART0 @@ -1841,7 +1871,7 @@ config DEBUG_UART_VIRT default 0xfec60000 if DEBUG_SIRFPRIMA2_UART1 default 0xfec90000 if DEBUG_RK32_UART2 default 0xfed0c000 if DEBUG_DAVINCI_DA8XX_UART1 - default 0xfed0d000 if DEBUG_DAVINCI_DA8XX_UART2 + default 0xfed0d000 if DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_SD5203_UART default 0xfed60000 if DEBUG_RK29_UART0 default 0xfed64000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 default 0xfed68000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3 @@ -1893,11 +1923,6 @@ config DEBUG_UART_8250_PALMCHIP except for having a different register layout. Say Y here if the debug UART is of this type. -config DEBUG_UART_8250_FLOW_CONTROL - bool "Enable flow control for 8250 UART" - depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 - default y if ARCH_EBSA110 || DEBUG_FOOTBRIDGE_COM1 || DEBUG_GEMINI || ARCH_RPC - config DEBUG_UNCOMPRESS bool "Enable decompressor debugging via DEBUG_LL output" depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG || ARM_SINGLE_ARMV7M diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 4e877354515f..4d76eab2b22d 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -16,9 +16,9 @@ LDFLAGS_vmlinux += --be8 KBUILD_LDFLAGS_MODULE += --be8 endif -ifeq ($(CONFIG_ARM_MODULE_PLTS),y) -KBUILD_LDS_MODULE += $(srctree)/arch/arm/kernel/module.lds -endif +# We never want expected sections to be placed heuristically by the +# linker. All sections should be explicitly named in the linker script. +LDFLAGS_vmlinux += $(call ld-option, --orphan-handling=warn) GZFLAGS :=-9 #KBUILD_CFLAGS +=-pipe @@ -139,6 +139,9 @@ head-y := arch/arm/kernel/head$(MMUEXT).o # Text offset. This list is sorted numerically by address in order to # provide a means to avoid/resolve conflicts in multi-arch kernels. +# Note: the 32kB below this value is reserved for use by the kernel +# during boot, and this offset is critical to the functioning of +# kexec-tools. textofs-y := 0x00008000 # We don't want the htc bootloader to corrupt kernel during resume textofs-$(CONFIG_PM_H1940) := 0x00108000 @@ -209,8 +212,7 @@ machine-$(CONFIG_ARCH_REALTEK) += realtek machine-$(CONFIG_ARCH_REALVIEW) += realview machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip machine-$(CONFIG_ARCH_RPC) += rpc -machine-$(CONFIG_ARCH_S3C24XX) += s3c24xx -machine-$(CONFIG_ARCH_S3C64XX) += s3c64xx +machine-$(CONFIG_PLAT_SAMSUNG) += s3c machine-$(CONFIG_ARCH_S5PV210) += s5pv210 machine-$(CONFIG_ARCH_SA1100) += sa1100 machine-$(CONFIG_ARCH_RENESAS) += shmobile @@ -232,13 +234,9 @@ machine-$(CONFIG_PLAT_SPEAR) += spear # Platform directory name. This list is sorted alphanumerically # by CONFIG_* macro name. -plat-$(CONFIG_ARCH_EXYNOS) += samsung plat-$(CONFIG_ARCH_OMAP) += omap -plat-$(CONFIG_ARCH_S3C64XX) += samsung -plat-$(CONFIG_ARCH_S5PV210) += samsung plat-$(CONFIG_PLAT_ORION) += orion plat-$(CONFIG_PLAT_PXA) += pxa -plat-$(CONFIG_PLAT_S3C24XX) += samsung plat-$(CONFIG_PLAT_VERSATILE) += versatile ifeq ($(CONFIG_ARCH_EBSA110),y) diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index b1147b7f2c8d..47f001ca5499 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -7,11 +7,11 @@ OBJS = -AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET) HEAD = head.o OBJS += misc.o decompress.o ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y) OBJS += debug.o +AFLAGS_head.o += -DDEBUG endif FONTC = $(srctree)/lib/fonts/font_acorn_8x8.c @@ -68,7 +68,12 @@ ZTEXTADDR := 0 ZBSSADDR := ALIGN(8) endif +MALLOC_SIZE := 65536 + +AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET) -DMALLOC_SIZE=$(MALLOC_SIZE) CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)" +CPPFLAGS_vmlinux.lds += -DTEXT_OFFSET="$(TEXT_OFFSET)" +CPPFLAGS_vmlinux.lds += -DMALLOC_SIZE="$(MALLOC_SIZE)" compress-$(CONFIG_KERNEL_GZIP) = gzip compress-$(CONFIG_KERNEL_LZO) = lzo @@ -123,6 +128,8 @@ endif LDFLAGS_vmlinux += --no-undefined # Delete all temporary local symbols LDFLAGS_vmlinux += -X +# Report orphan sections +LDFLAGS_vmlinux += $(call ld-option, --orphan-handling=warn) # Next argument is a linker script LDFLAGS_vmlinux += -T diff --git a/arch/arm/boot/compressed/debug.S b/arch/arm/boot/compressed/debug.S index 6bf2917a4621..fac40a717fcf 100644 --- a/arch/arm/boot/compressed/debug.S +++ b/arch/arm/boot/compressed/debug.S @@ -8,7 +8,10 @@ ENTRY(putc) addruart r1, r2, r3 - waituart r3, r1 +#ifdef CONFIG_DEBUG_UART_FLOW_CONTROL + waituartcts r3, r1 +#endif + waituarttxrdy r3, r1 senduart r0, r1 busyuart r3, r1 mov pc, lr diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 434a16982e34..2e04ec5b5446 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -28,19 +28,19 @@ #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7) .macro loadsp, rb, tmp1, tmp2 .endm - .macro writeb, ch, rb + .macro writeb, ch, rb, tmp mcr p14, 0, \ch, c0, c5, 0 .endm #elif defined(CONFIG_CPU_XSCALE) .macro loadsp, rb, tmp1, tmp2 .endm - .macro writeb, ch, rb + .macro writeb, ch, rb, tmp mcr p14, 0, \ch, c8, c0, 0 .endm #else .macro loadsp, rb, tmp1, tmp2 .endm - .macro writeb, ch, rb + .macro writeb, ch, rb, tmp mcr p14, 0, \ch, c1, c0, 0 .endm #endif @@ -49,8 +49,13 @@ #include CONFIG_DEBUG_LL_INCLUDE - .macro writeb, ch, rb + .macro writeb, ch, rb, tmp +#ifdef CONFIG_DEBUG_UART_FLOW_CONTROL + waituartcts \tmp, \rb +#endif + waituarttxrdy \tmp, \rb senduart \ch, \rb + busyuart \tmp, \rb .endm #if defined(CONFIG_ARCH_SA1100) @@ -81,42 +86,11 @@ bl phex .endm - .macro debug_reloc_start -#ifdef DEBUG - kputc #'\n' - kphex r6, 8 /* processor id */ - kputc #':' - kphex r7, 8 /* architecture id */ -#ifdef CONFIG_CPU_CP15 - kputc #':' - mrc p15, 0, r0, c1, c0 - kphex r0, 8 /* control reg */ -#endif - kputc #'\n' - kphex r5, 8 /* decompressed kernel start */ - kputc #'-' - kphex r9, 8 /* decompressed kernel end */ - kputc #'>' - kphex r4, 8 /* kernel execution address */ - kputc #'\n' -#endif - .endm - - .macro debug_reloc_end -#ifdef DEBUG - kphex r5, 8 /* end of kernel */ - kputc #'\n' - mov r0, r4 - bl memdump /* dump 256 bytes at start of kernel */ -#endif - .endm - /* * Debug kernel copy by printing the memory addresses involved */ .macro dbgkc, begin, end, cbegin, cend #ifdef DEBUG - kputc #'\n' kputc #'C' kputc #':' kputc #'0' @@ -136,7 +110,28 @@ kputc #'x' kphex \cend, 8 /* End of kernel copy */ kputc #'\n' - kputc #'\r' +#endif + .endm + + /* + * Debug print of the final appended DTB location + */ + .macro dbgadtb, begin, end +#ifdef DEBUG + kputc #'D' + kputc #'T' + kputc #'B' + kputc #':' + kputc #'0' + kputc #'x' + kphex \begin, 8 /* Start of appended DTB */ + kputc #' ' + kputc #'(' + kputc #'0' + kputc #'x' + kphex \end, 8 /* End of appended DTB */ + kputc #')' + kputc #'\n' #endif .endm @@ -303,7 +298,7 @@ restart: adr r0, LC1 #ifndef CONFIG_ZBOOT_ROM /* malloc space is above the relocated stack (64k max) */ - add r10, sp, #0x10000 + add r10, sp, #MALLOC_SIZE #else /* * With ZBOOT_ROM the bss/stack is non relocatable, @@ -357,6 +352,7 @@ restart: adr r0, LC1 mov r5, r5, ror #8 eor r5, r5, r1, lsr #8 #endif + dbgadtb r6, r5 /* 50% DTB growth should be good enough */ add r5, r5, r5, lsr #1 /* preserve 64-bit alignment */ @@ -614,7 +610,7 @@ not_relocated: mov r0, #0 */ mov r0, r4 mov r1, sp @ malloc space above stack - add r2, sp, #0x10000 @ 64k max + add r2, sp, #MALLOC_SIZE @ 64k max mov r3, r7 bl decompress_kernel @@ -1356,7 +1352,7 @@ puts: loadsp r3, r2, r1 1: ldrb r2, [r0], #1 teq r2, #0 moveq pc, lr -2: writeb r2, r3 +2: writeb r2, r3, r1 mov r1, #0x00020000 3: subs r1, r1, #1 bne 3b diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S index 09ac33f52814..1bcb68ac4b01 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.S +++ b/arch/arm/boot/compressed/vmlinux.lds.S @@ -2,6 +2,7 @@ /* * Copyright (C) 2000 Russell King */ +#include <asm/vmlinux.lds.h> #ifdef CONFIG_CPU_ENDIAN_BE8 #define ZIMAGE_MAGIC(x) ( (((x) >> 24) & 0x000000ff) | \ @@ -17,8 +18,11 @@ ENTRY(_start) SECTIONS { /DISCARD/ : { + COMMON_DISCARDS *(.ARM.exidx*) *(.ARM.extab*) + *(.note.*) + *(.rel.*) /* * Discard any r/w data - this produces a link error if we have any, * which is required for PIC decompression. Local data generates @@ -36,16 +40,16 @@ SECTIONS *(.start) *(.text) *(.text.*) - *(.gnu.warning) - *(.glue_7t) - *(.glue_7) + ARM_STUBS_TEXT } .table : ALIGN(4) { _table_start = .; - LONG(ZIMAGE_MAGIC(4)) + LONG(ZIMAGE_MAGIC(6)) LONG(ZIMAGE_MAGIC(0x5a534c4b)) LONG(ZIMAGE_MAGIC(__piggy_size_addr - _start)) LONG(ZIMAGE_MAGIC(_kernel_bss_size)) + LONG(ZIMAGE_MAGIC(TEXT_OFFSET)) + LONG(ZIMAGE_MAGIC(MALLOC_SIZE)) LONG(0) _table_end = .; } @@ -128,12 +132,10 @@ SECTIONS PROVIDE(__pecoff_data_size = ALIGN(512) - ADDR(.data)); PROVIDE(__pecoff_end = ALIGN(512)); - .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) } + STABS_DEBUG + DWARF_DEBUG + ARM_DETAILS + + ARM_ASSERTS } ASSERT(_edata_real == _edata, "error: zImage file size is incorrect"); diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 4572db3fa5ae..ce66ffd5a1bb 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -43,6 +43,7 @@ dtb-$(CONFIG_SOC_AT91SAM9) += \ at91-smartkiz.dtb \ at91-wb45n.dtb \ at91sam9g15ek.dtb \ + at91sam9g25-gardena-smart-gateway.dtb \ at91sam9g25ek.dtb \ at91sam9g35ek.dtb \ at91sam9x25ek.dtb \ @@ -127,6 +128,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \ bcm47094-luxul-xwr-3150-v1.dtb \ bcm47094-netgear-r8500.dtb \ bcm47094-phicomm-k3.dtb \ + bcm53016-meraki-mr32.dtb \ bcm94708.dtb \ bcm94709.dtb \ bcm953012er.dtb \ @@ -357,6 +359,8 @@ dtb-$(CONFIG_ARCH_MPS2) += \ mps2-an399.dtb dtb-$(CONFIG_ARCH_MOXART) += \ moxart-uc7112lx.dtb +dtb-$(CONFIG_ARCH_SD5203) += \ + sd5203.dtb dtb-$(CONFIG_SOC_IMX1) += \ imx1-ads.dtb \ imx1-apf9328.dtb @@ -482,6 +486,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6dl-wandboard-revd1.dtb \ imx6dl-yapp4-draco.dtb \ imx6dl-yapp4-hydra.dtb \ + imx6dl-yapp4-orion.dtb \ imx6dl-yapp4-ursa.dtb \ imx6q-apalis-eval.dtb \ imx6q-apalis-ixora.dtb \ @@ -531,6 +536,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6q-icore-ofcap12.dtb \ imx6q-icore-rqs.dtb \ imx6q-kp-tpc.dtb \ + imx6q-logicpd.dtb \ imx6q-marsboard.dtb \ imx6q-mccmon6.dtb \ imx6q-nitrogen6x.dtb \ @@ -585,6 +591,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6qp-zii-rdu2.dtb dtb-$(CONFIG_SOC_IMX6SL) += \ imx6sl-evk.dtb \ + imx6sl-tolino-shine2hd.dtb \ imx6sl-tolino-shine3.dtb \ imx6sl-warp.dtb dtb-$(CONFIG_SOC_IMX6SLL) += \ @@ -868,7 +875,12 @@ dtb-$(CONFIG_ARCH_ORION5X) += \ dtb-$(CONFIG_ARCH_ACTIONS) += \ owl-s500-cubieboard6.dtb \ owl-s500-guitar-bb-rev-b.dtb \ + owl-s500-labrador-base-m.dtb \ + owl-s500-roseapplepi.dtb \ owl-s500-sparky.dtb +dtb-$(CONFIG_ARCH_PICOXCELL) += \ + picoxcell-pc7302-pc3x2.dtb \ + picoxcell-pc7302-pc3x3.dtb dtb-$(CONFIG_ARCH_PRIMA2) += \ prima2-evb.dtb dtb-$(CONFIG_ARCH_PXA) += \ @@ -1047,6 +1059,7 @@ dtb-$(CONFIG_ARCH_STM32) += \ stm32746g-eval.dtb \ stm32h743i-eval.dtb \ stm32h743i-disco.dtb \ + stm32mp153c-dhcom-drc02.dtb \ stm32mp157a-avenger96.dtb \ stm32mp157a-dhcor-avenger96.dtb \ stm32mp157a-dk1.dtb \ @@ -1056,7 +1069,8 @@ dtb-$(CONFIG_ARCH_STM32) += \ stm32mp157c-dk2.dtb \ stm32mp157c-ed1.dtb \ stm32mp157c-ev1.dtb \ - stm32mp157c-lxa-mc1.dtb + stm32mp157c-lxa-mc1.dtb \ + stm32mp157c-odyssey.dtb dtb-$(CONFIG_MACH_SUN4I) += \ sun4i-a10-a1000.dtb \ sun4i-a10-ba10-tvbox.dtb \ @@ -1194,6 +1208,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \ sun8i-r16-parrot.dtb \ sun8i-r40-bananapi-m2-ultra.dtb \ sun8i-s3-lichee-zero-plus.dtb \ + sun8i-s3-pinecube.dtb \ sun8i-t3-cqa3t-bv3.dtb \ sun8i-v3s-licheepi-zero.dtb \ sun8i-v3s-licheepi-zero-dock.dtb \ @@ -1356,9 +1371,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt8135-evbp1.dtb dtb-$(CONFIG_ARCH_MILBEAUT) += milbeaut-m10v-evb.dtb dtb-$(CONFIG_ARCH_MSTARV7) += \ - infinity-msc313-breadbee_crust.dtb \ - infinity3-msc313e-breadbee.dtb \ - mercury5-ssc8336n-midrived08.dtb + mstar-infinity-msc313-breadbee_crust.dtb \ + mstar-infinity3-msc313e-breadbee.dtb \ + mstar-mercury5-ssc8336n-midrived08.dtb dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb dtb-$(CONFIG_ARCH_ASPEED) += \ aspeed-ast2500-evb.dtb \ @@ -1371,6 +1386,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ aspeed-bmc-facebook-tiogapass.dtb \ aspeed-bmc-facebook-wedge40.dtb \ aspeed-bmc-facebook-wedge100.dtb \ + aspeed-bmc-facebook-wedge400.dtb \ aspeed-bmc-facebook-yamp.dtb \ aspeed-bmc-facebook-yosemitev2.dtb \ aspeed-bmc-ibm-rainier.dtb \ @@ -1381,6 +1397,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ aspeed-bmc-microsoft-olympus.dtb \ aspeed-bmc-opp-lanyang.dtb \ aspeed-bmc-opp-mihawk.dtb \ + aspeed-bmc-opp-mowgli.dtb \ aspeed-bmc-opp-nicole.dtb \ aspeed-bmc-opp-palmetto.dtb \ aspeed-bmc-opp-romulus.dtb \ diff --git a/arch/arm/boot/dts/alpine.dtsi b/arch/arm/boot/dts/alpine.dtsi index d3036ea823d1..3b0675a1c460 100644 --- a/arch/arm/boot/dts/alpine.dtsi +++ b/arch/arm/boot/dts/alpine.dtsi @@ -91,7 +91,7 @@ }; /* Interrupt Controller */ - gic: gic@fb001000 { + gic: interrupt-controller@fb001000 { compatible = "arm,cortex-a15-gic"; #interrupt-cells = <3>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/am335x-lxm.dts b/arch/arm/boot/dts/am335x-lxm.dts index cd55f11260ea..0f078465297a 100644 --- a/arch/arm/boot/dts/am335x-lxm.dts +++ b/arch/arm/boot/dts/am335x-lxm.dts @@ -160,11 +160,15 @@ serial_config1: serial_config1@20 { compatible = "nxp,pca9539"; reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; }; serial_config2: serial_config2@21 { compatible = "nxp,pca9539"; reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; }; tps: tps@2d { diff --git a/arch/arm/boot/dts/am335x-moxa-uc-8100-common.dtsi b/arch/arm/boot/dts/am335x-moxa-uc-8100-common.dtsi new file mode 100644 index 000000000000..98d8ed4ad967 --- /dev/null +++ b/arch/arm/boot/dts/am335x-moxa-uc-8100-common.dtsi @@ -0,0 +1,427 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 MOXA Inc. - https://www.moxa.com/ + * + * Author: Johnson Chen <johnsonch.chen@moxa.com> + */ + +#include "am33xx.dtsi" + +/ { + + cpus { + cpu@0 { + cpu0-supply = <&vdd1_reg>; + }; + }; + + vbat: vbat-regulator { + compatible = "regulator-fixed"; + }; + + /* Power supply provides a fixed 3.3V @3A */ + vmmcsd_fixed: vmmcsd-regulator { + compatible = "regulator-fixed"; + regulator-name = "vmmcsd_fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + buttons: push_button { + compatible = "gpio-keys"; + }; + +}; + +&am33xx_pinmux { + pinctrl-names = "default"; + pinctrl-0 = <&minipcie_pins>; + + minipcie_pins: pinmux_minipcie { + pinctrl-single,pins = < + AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_INPUT_PULLDOWN, MUX_MODE7) /* lcd_pclk.gpio2_24 */ + AM33XX_PADCONF(AM335X_PIN_LCD_AC_BIAS_EN, PIN_INPUT_PULLDOWN, MUX_MODE7) /* lcd_ac_bias_en.gpio2_25 */ + AM33XX_PADCONF(AM335X_PIN_LCD_VSYNC, PIN_INPUT_PULLDOWN, MUX_MODE7) /* lcd_vsync.gpio2_22 Power off PIN*/ + >; + }; + + push_button_pins: pinmux_push_button { + pinctrl-single,pins = < + AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKX, PIN_INPUT_PULLDOWN, MUX_MODE7) /* mcasp0_ahcklx.gpio3_21 */ + >; + }; + + i2c0_pins: pinmux_i2c0_pins { + pinctrl-single,pins = < + AM33XX_PADCONF(AM335X_PIN_I2C0_SDA, PIN_INPUT_PULLUP, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_I2C0_SCL, PIN_INPUT_PULLUP, MUX_MODE0) + >; + }; + + + i2c1_pins: pinmux_i2c1_pins { + pinctrl-single,pins = < + AM33XX_PADCONF(AM335X_PIN_UART0_CTSN, PIN_INPUT_PULLUP, MUX_MODE3) /* uart0_ctsn.i2c1_sda */ + AM33XX_PADCONF(AM335X_PIN_UART0_RTSN, PIN_INPUT_PULLUP, MUX_MODE3) /* uart0_rtsn.i2c1_scl */ + >; + }; + + uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + AM33XX_PADCONF(AM335X_PIN_UART0_RXD, PIN_INPUT_PULLUP, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_UART0_TXD, PIN_OUTPUT_PULLDOWN, MUX_MODE0) + >; + }; + + uart1_pins: pinmux_uart1_pins { + pinctrl-single,pins = < + AM33XX_PADCONF(AM335X_PIN_UART1_CTSN, PIN_INPUT, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_UART1_RTSN, PIN_OUTPUT_PULLDOWN, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_UART1_RXD, PIN_INPUT_PULLUP, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_UART1_TXD, PIN_OUTPUT, MUX_MODE0) + >; + }; + + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + AM33XX_PADCONF(AM335X_PIN_LCD_DATA14, PIN_INPUT, MUX_MODE6) /* lcd_data14.uart5_ctsn */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA15, PIN_OUTPUT_PULLDOWN, MUX_MODE6) /* lcd_data15.uart5_rtsn */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA9, PIN_INPUT_PULLUP, MUX_MODE4) /* lcd_data9.uart5_rxd */ + AM33XX_PADCONF(AM335X_PIN_LCD_DATA8, PIN_OUTPUT, MUX_MODE4) /* lcd_data8.uart5_txd */ + >; + }; + + cpsw_default: cpsw_default { + pinctrl-single,pins = < + /* Slave 1 */ + AM33XX_PADCONF(AM335X_PIN_MII1_CRS, PIN_INPUT_PULLDOWN, MUX_MODE1) + AM33XX_PADCONF(AM335X_PIN_MII1_RX_ER, PIN_INPUT_PULLUP, MUX_MODE1) + AM33XX_PADCONF(AM335X_PIN_MII1_TX_EN, PIN_OUTPUT_PULLDOWN, MUX_MODE1) + AM33XX_PADCONF(AM335X_PIN_MII1_TXD1, PIN_OUTPUT_PULLDOWN, MUX_MODE1) + AM33XX_PADCONF(AM335X_PIN_MII1_TXD0, PIN_OUTPUT_PULLDOWN, MUX_MODE1) + AM33XX_PADCONF(AM335X_PIN_MII1_RXD1, PIN_INPUT_PULLUP, MUX_MODE1) + AM33XX_PADCONF(AM335X_PIN_MII1_RXD0, PIN_INPUT_PULLUP, MUX_MODE1) + AM33XX_PADCONF(AM335X_PIN_RMII1_REF_CLK, PIN_INPUT_PULLDOWN, MUX_MODE0) + + /* Slave 2 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_WAIT0, PIN_INPUT_PULLDOWN, MUX_MODE3) /* rmii2_crs_dv */ + AM33XX_PADCONF(AM335X_PIN_GPMC_WPN, PIN_INPUT_PULLDOWN, MUX_MODE3) /* rmii2_rxer */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A0, PIN_OUTPUT_PULLDOWN, MUX_MODE3) /* rmii2_txen */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A4, PIN_OUTPUT_PULLDOWN, MUX_MODE3) /* rmii2_td1 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A5, PIN_OUTPUT_PULLDOWN, MUX_MODE3) /* rmii2_td0 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A10, PIN_INPUT_PULLDOWN, MUX_MODE3) /* rmii2_rd1 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_A11, PIN_INPUT_PULLDOWN, MUX_MODE3) /* rmii2_rd0 */ + AM33XX_PADCONF(AM335X_PIN_MII1_COL, PIN_INPUT_PULLDOWN, MUX_MODE1) /* rmii2_refclk */ + + >; + }; + + davinci_mdio_default: davinci_mdio_default { + pinctrl-single,pins = < + /* MDIO */ + AM33XX_PADCONF(AM335X_PIN_MDIO, PIN_INPUT_PULLUP | SLEWCTRL_FAST, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_MDC, PIN_OUTPUT_PULLUP, MUX_MODE0) + >; + }; + + mmc0_pins_default: pinmux_mmc0_pins { + pinctrl-single,pins = < + AM33XX_PADCONF(AM335X_PIN_MMC0_DAT3, PIN_INPUT_PULLUP, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_MMC0_DAT2, PIN_INPUT_PULLUP, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_MMC0_DAT1, PIN_INPUT_PULLUP, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_MMC0_DAT0, PIN_INPUT_PULLUP, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_MMC0_CLK, PIN_INPUT_PULLUP, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_MMC0_CMD, PIN_INPUT_PULLUP, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKX, PIN_INPUT_PULLUP, MUX_MODE7) /* mcasp0_aclkx.gpio3_14 */ + AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKR, PIN_INPUT_PULLUP, MUX_MODE7) /* mcasp0_aclkx.gpio3_18 */ + >; + }; + + mmc2_pins_default: pinmux_mmc2_pins { + pinctrl-single,pins = < + /* eMMC */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD12, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad12.mmc2_dat0 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD13, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad13.mmc2_dat1 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD14, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad14.mmc2_dat2 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD15, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad15.mmc2_dat3 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD8, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad8.mmc2_dat4 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD9, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad9.mmc2_dat5 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD10, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad10.mmc2_dat6 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_AD11, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad11.mmc2_dat7 */ + AM33XX_PADCONF(AM335X_PIN_GPMC_CSN3, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_csn3.mmc2_cmd */ + AM33XX_PADCONF(AM335X_PIN_GPMC_CLK, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_clk.mmc2_clk */ + >; + }; + + spi0_pins: pinmux_spi0 { + pinctrl-single,pins = < + AM33XX_PADCONF(AM335X_PIN_SPI0_SCLK, PIN_INPUT_PULLUP, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_SPI0_CS0, PIN_INPUT_PULLUP, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_SPI0_D0, PIN_INPUT_PULLUP, MUX_MODE0) + AM33XX_PADCONF(AM335X_PIN_SPI0_D1, PIN_INPUT_PULLUP, MUX_MODE0) + >; + }; + +}; + +&uart0 { + /* Console */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; +}; + +&uart1 { + /* UART 1 setting */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; +}; + +&uart5 { + /* UART 2 setting */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + + status = "okay"; + clock-frequency = <400000>; + + tps: tps@2d { + compatible = "ti,tps65910"; + reg = <0x2d>; + }; + + eeprom: eeprom@50 { + compatible = "atmel,24c16"; + pagesize = <16>; + reg = <0x50>; + }; + + rtc_wdt: rtc_wdt@68 { + compatible = "dallas,ds1374"; + reg = <0x68>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + + status = "okay"; + clock-frequency = <400000>; + gpio_xten: gpio_xten@27 { + compatible = "nxp,pca9535"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x27>; + }; +}; + +&usb0 { + dr_mode = "host"; +}; + +&usb1 { + dr_mode = "host"; +}; + + +#include "tps65910.dtsi" +&tps { + vcc1-supply = <&vbat>; + vcc2-supply = <&vbat>; + vcc3-supply = <&vbat>; + vcc4-supply = <&vbat>; + vcc5-supply = <&vbat>; + vcc6-supply = <&vbat>; + vcc7-supply = <&vbat>; + vccio-supply = <&vbat>; + + regulators { + vrtc_reg: regulator@0 { + regulator-always-on; + }; + + vio_reg: regulator@1 { + regulator-always-on; + }; + + vdd1_reg: regulator@2 { + regulator-always-on; + }; + + vdd2_reg: regulator@3 { + regulator-always-on; + }; + + vdd3_reg: regulator@4 { + regulator-always-on; + }; + + vdig1_reg: regulator@5 { + regulator-always-on; + }; + + vdig2_reg: regulator@6 { + regulator-always-on; + }; + + vpll_reg: regulator@7 { + regulator-always-on; + }; + + vdac_reg: regulator@8 { + regulator-always-on; + }; + + vaux1_reg: regulator@9 { + regulator-always-on; + }; + + vaux2_reg: regulator@10 { + regulator-always-on; + }; + + vaux33_reg: regulator@11 { + regulator-always-on; + }; + + vmmc_reg: regulator@12 { + compatible = "regulator-fixed"; + regulator-name = "vmmc_reg"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; +}; + +/* Power */ +&vbat { + regulator-name = "vbat"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; +}; + +&mac { + pinctrl-names = "default"; + pinctrl-0 = <&cpsw_default>; + dual_emac = <1>; + status = "okay"; +}; + +&davinci_mdio { + pinctrl-names = "default"; + pinctrl-0 = <&davinci_mdio_default>; + status = "okay"; + + ethphy0: ethernet-phy@4 { + reg = <4>; + }; + + ethphy1: ethernet-phy@5 { + reg = <5>; + }; +}; + +&cpsw_emac0 { + status = "okay"; + phy-handle = <ðphy0>; + phy-mode = "rmii"; + dual_emac_res_vlan = <1>; +}; + +&cpsw_emac1 { + status = "okay"; + phy-handle = <ðphy1>; + phy-mode = "rmii"; + dual_emac_res_vlan = <2>; +}; + +&sham { + status = "okay"; +}; + +&aes { + status = "okay"; +}; + +&gpio0 { + ti,no-reset-on-init; +}; + +&mmc1 { + pinctrl-names = "default"; + vmmc-supply = <&vmmcsd_fixed>; + bus-width = <4>; + pinctrl-0 = <&mmc0_pins_default>; + cd-gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>; + wp-gpios = <&gpio3 18 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&mmc3 { + dmas = <&edma_xbar 12 0 1 + &edma_xbar 13 0 2>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + vmmc-supply = <&vmmcsd_fixed>; + bus-width = <8>; + pinctrl-0 = <&mmc2_pins_default>; + ti,non-removable; + status = "okay"; +}; + +&buttons { + pinctrl-names = "default"; + pinctrl-0 = <&push_button_pins>; + #address-cells = <1>; + #size-cells = <0>; + + button@0 { + label = "push_button"; + linux,code = <0x100>; + gpios = <&gpio3 21 GPIO_ACTIVE_LOW>; + }; +}; + +/* SPI Busses */ +&spi0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + + m25p80@0 { + compatible = "mx25l6405d"; + spi-max-frequency = <40000000>; + + reg = <0>; + spi-cpol; + spi-cpha; + #address-cells = <1>; + #size-cells = <1>; + + /* reg : The partition's offset and size within the mtd bank. */ + partitions@0 { + label = "MLO"; + reg = <0x0 0x80000>; + }; + + partitions@1 { + label = "U-Boot"; + reg = <0x80000 0x100000>; + }; + + partitions@2 { + label = "U-Boot Env"; + reg = <0x180000 0x20000>; + }; + }; +}; diff --git a/arch/arm/boot/dts/am335x-moxa-uc-8100-me-t.dts b/arch/arm/boot/dts/am335x-moxa-uc-8100-me-t.dts index f03e72cada41..0c7949d21bd9 100644 --- a/arch/arm/boot/dts/am335x-moxa-uc-8100-me-t.dts +++ b/arch/arm/boot/dts/am335x-moxa-uc-8100-me-t.dts @@ -4,39 +4,19 @@ * * Author: SZ Lin (林上智) <sz.lin@moxa.com> */ - /dts-v1/; -#include "am33xx.dtsi" +#include "am335x-moxa-uc-8100-common.dtsi" / { model = "Moxa UC-8100-ME-T"; compatible = "moxa,uc-8100-me-t", "ti,am33xx"; - cpus { - cpu@0 { - cpu0-supply = <&vdd1_reg>; - }; - }; - memory { device_type = "memory"; reg = <0x80000000 0x20000000>; /* 512 MB */ }; - vbat: vbat-regulator { - compatible = "regulator-fixed"; - }; - - /* Power supply provides a fixed 3.3V @3A */ - vmmcsd_fixed: vmmcsd-regulator { - compatible = "regulator-fixed"; - regulator-name = "vmmcsd_fixed"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - }; - leds { compatible = "gpio-leds"; led1 { @@ -88,237 +68,17 @@ default-state = "off"; }; }; - - buttons: push_button { - compatible = "gpio-keys"; - }; - -}; - -&am33xx_pinmux { - pinctrl-names = "default"; - pinctrl-0 = <&minipcie_pins>; - - minipcie_pins: pinmux_minipcie { - pinctrl-single,pins = < - AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_INPUT_PULLDOWN, MUX_MODE7) /* lcd_pclk.gpio2_24 */ - AM33XX_PADCONF(AM335X_PIN_LCD_AC_BIAS_EN, PIN_INPUT_PULLDOWN, MUX_MODE7) /* lcd_ac_bias_en.gpio2_25 */ - AM33XX_PADCONF(AM335X_PIN_LCD_VSYNC, PIN_INPUT_PULLDOWN, MUX_MODE7) /* lcd_vsync.gpio2_22 Power off PIN*/ - >; - }; - - push_button_pins: pinmux_push_button { - pinctrl-single,pins = < - AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKX, PIN_INPUT_PULLDOWN, MUX_MODE7) /* mcasp0_ahcklx.gpio3_21 */ - >; - }; - - i2c0_pins: pinmux_i2c0_pins { - pinctrl-single,pins = < - AM33XX_PADCONF(AM335X_PIN_I2C0_SDA, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_I2C0_SCL, PIN_INPUT_PULLUP, MUX_MODE0) - >; - }; - - - i2c1_pins: pinmux_i2c1_pins { - pinctrl-single,pins = < - AM33XX_PADCONF(AM335X_PIN_UART0_CTSN, PIN_INPUT_PULLUP, MUX_MODE3) /* uart0_ctsn.i2c1_sda */ - AM33XX_PADCONF(AM335X_PIN_UART0_RTSN, PIN_INPUT_PULLUP, MUX_MODE3) /* uart0_rtsn.i2c1_scl */ - >; - }; - - uart0_pins: pinmux_uart0_pins { - pinctrl-single,pins = < - AM33XX_PADCONF(AM335X_PIN_UART0_RXD, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_UART0_TXD, PIN_OUTPUT_PULLDOWN, MUX_MODE0) - >; - }; - - uart1_pins: pinmux_uart1_pins { - pinctrl-single,pins = < - AM33XX_PADCONF(AM335X_PIN_UART1_CTSN, PIN_INPUT, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_UART1_RTSN, PIN_OUTPUT_PULLDOWN, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_UART1_RXD, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_UART1_TXD, PIN_OUTPUT, MUX_MODE0) - >; - }; - - uart2_pins: pinmux_uart2_pins { - pinctrl-single,pins = < - AM33XX_PADCONF(AM335X_PIN_LCD_DATA14, PIN_INPUT, MUX_MODE6) /* lcd_data14.uart5_ctsn */ - AM33XX_PADCONF(AM335X_PIN_LCD_DATA15, PIN_OUTPUT_PULLDOWN, MUX_MODE6) /* lcd_data15.uart5_rtsn */ - AM33XX_PADCONF(AM335X_PIN_LCD_DATA9, PIN_INPUT_PULLUP, MUX_MODE4) /* lcd_data9.uart5_rxd */ - AM33XX_PADCONF(AM335X_PIN_LCD_DATA8, PIN_OUTPUT, MUX_MODE4) /* lcd_data8.uart5_txd */ - >; - }; - - cpsw_default: cpsw_default { - pinctrl-single,pins = < - /* Slave 1 */ - AM33XX_PADCONF(AM335X_PIN_MII1_CRS, PIN_INPUT_PULLDOWN, MUX_MODE1) - AM33XX_PADCONF(AM335X_PIN_MII1_RX_ER, PIN_INPUT_PULLUP, MUX_MODE1) - AM33XX_PADCONF(AM335X_PIN_MII1_TX_EN, PIN_OUTPUT_PULLDOWN, MUX_MODE1) - AM33XX_PADCONF(AM335X_PIN_MII1_TXD1, PIN_OUTPUT_PULLDOWN, MUX_MODE1) - AM33XX_PADCONF(AM335X_PIN_MII1_TXD0, PIN_OUTPUT_PULLDOWN, MUX_MODE1) - AM33XX_PADCONF(AM335X_PIN_MII1_RXD1, PIN_INPUT_PULLUP, MUX_MODE1) - AM33XX_PADCONF(AM335X_PIN_MII1_RXD0, PIN_INPUT_PULLUP, MUX_MODE1) - AM33XX_PADCONF(AM335X_PIN_RMII1_REF_CLK, PIN_INPUT_PULLDOWN, MUX_MODE0) - - /* Slave 2 */ - AM33XX_PADCONF(AM335X_PIN_GPMC_WAIT0, PIN_INPUT_PULLDOWN, MUX_MODE3) /* rmii2_crs_dv */ - AM33XX_PADCONF(AM335X_PIN_GPMC_WPN, PIN_INPUT_PULLDOWN, MUX_MODE3) /* rmii2_rxer */ - AM33XX_PADCONF(AM335X_PIN_GPMC_A0, PIN_OUTPUT_PULLDOWN, MUX_MODE3) /* rmii2_txen */ - AM33XX_PADCONF(AM335X_PIN_GPMC_A4, PIN_OUTPUT_PULLDOWN, MUX_MODE3) /* rmii2_td1 */ - AM33XX_PADCONF(AM335X_PIN_GPMC_A5, PIN_OUTPUT_PULLDOWN, MUX_MODE3) /* rmii2_td0 */ - AM33XX_PADCONF(AM335X_PIN_GPMC_A10, PIN_INPUT_PULLDOWN, MUX_MODE3) /* rmii2_rd1 */ - AM33XX_PADCONF(AM335X_PIN_GPMC_A11, PIN_INPUT_PULLDOWN, MUX_MODE3) /* rmii2_rd0 */ - AM33XX_PADCONF(AM335X_PIN_MII1_COL, PIN_INPUT_PULLDOWN, MUX_MODE1) /* rmii2_refclk */ - - >; - }; - - davinci_mdio_default: davinci_mdio_default { - pinctrl-single,pins = < - /* MDIO */ - AM33XX_PADCONF(AM335X_PIN_MDIO, PIN_INPUT_PULLUP | SLEWCTRL_FAST, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_MDC, PIN_OUTPUT_PULLUP, MUX_MODE0) - >; - }; - - mmc0_pins_default: pinmux_mmc0_pins { - pinctrl-single,pins = < - AM33XX_PADCONF(AM335X_PIN_MMC0_DAT3, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_MMC0_DAT2, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_MMC0_DAT1, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_MMC0_DAT0, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_MMC0_CLK, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_MMC0_CMD, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKX, PIN_INPUT_PULLUP, MUX_MODE7) /* mcasp0_aclkx.gpio3_14 */ - AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKR, PIN_INPUT_PULLUP, MUX_MODE7) /* mcasp0_aclkx.gpio3_18 */ - >; - }; - - mmc2_pins_default: pinmux_mmc2_pins { - pinctrl-single,pins = < - /* eMMC */ - AM33XX_PADCONF(AM335X_PIN_GPMC_AD12, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad12.mmc2_dat0 */ - AM33XX_PADCONF(AM335X_PIN_GPMC_AD13, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad13.mmc2_dat1 */ - AM33XX_PADCONF(AM335X_PIN_GPMC_AD14, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad14.mmc2_dat2 */ - AM33XX_PADCONF(AM335X_PIN_GPMC_AD15, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad15.mmc2_dat3 */ - AM33XX_PADCONF(AM335X_PIN_GPMC_AD8, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad8.mmc2_dat4 */ - AM33XX_PADCONF(AM335X_PIN_GPMC_AD9, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad9.mmc2_dat5 */ - AM33XX_PADCONF(AM335X_PIN_GPMC_AD10, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad10.mmc2_dat6 */ - AM33XX_PADCONF(AM335X_PIN_GPMC_AD11, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_ad11.mmc2_dat7 */ - AM33XX_PADCONF(AM335X_PIN_GPMC_CSN3, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_csn3.mmc2_cmd */ - AM33XX_PADCONF(AM335X_PIN_GPMC_CLK, PIN_INPUT_PULLUP, MUX_MODE3) /* gpmc_clk.mmc2_clk */ - >; - }; - - spi0_pins: pinmux_spi0 { - pinctrl-single,pins = < - AM33XX_PADCONF(AM335X_PIN_SPI0_SCLK, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_SPI0_CS0, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_SPI0_D0, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_SPI0_D1, PIN_INPUT_PULLUP, MUX_MODE0) - >; - }; - -}; - -&uart0 { - /* Console */ - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins>; -}; - -&uart1 { - /* UART 1 setting */ - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&uart1_pins>; -}; - -&uart5 { - /* UART 2 setting */ - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&uart2_pins>; }; &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; - - status = "okay"; - clock-frequency = <400000>; - tpm: tpm@20 { compatible = "infineon,slb9645tt"; reg = <0x20>; }; - - tps: tps@2d { - compatible = "ti,tps65910"; - reg = <0x2d>; - }; - - eeprom: eeprom@50 { - compatible = "atmel,24c16"; - pagesize = <16>; - reg = <0x50>; - }; - - rtc_wdt: rtc_wdt@68 { - compatible = "dallas,ds1374"; - reg = <0x68>; - }; }; -&i2c1 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c1_pins>; - - status = "okay"; - clock-frequency = <400000>; - gpio_xten: gpio_xten@27 { - compatible = "nxp,pca9535"; - gpio-controller; - #gpio-cells = <2>; - reg = <0x27>; - }; -}; - -&usb0 { - dr_mode = "host"; -}; - -&usb1 { - dr_mode = "host"; -}; - -#include "tps65910.dtsi" - &tps { - vcc1-supply = <&vbat>; - vcc2-supply = <&vbat>; - vcc3-supply = <&vbat>; - vcc4-supply = <&vbat>; - vcc5-supply = <&vbat>; - vcc6-supply = <&vbat>; - vcc7-supply = <&vbat>; - vccio-supply = <&vbat>; - regulators { - vrtc_reg: regulator@0 { - regulator-always-on; - }; - - vio_reg: regulator@1 { - regulator-always-on; - }; - vdd1_reg: regulator@2 { /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */ regulator-name = "vdd_mpu"; @@ -336,168 +96,6 @@ regulator-boot-on; regulator-always-on; }; - - vdd3_reg: regulator@4 { - regulator-always-on; - }; - - vdig1_reg: regulator@5 { - regulator-always-on; - }; - - vdig2_reg: regulator@6 { - regulator-always-on; - }; - - vpll_reg: regulator@7 { - regulator-always-on; - }; - - vdac_reg: regulator@8 { - regulator-always-on; - }; - - vaux1_reg: regulator@9 { - regulator-always-on; - }; - - vaux2_reg: regulator@10 { - regulator-always-on; - }; - - vaux33_reg: regulator@11 { - regulator-always-on; - }; - - vmmc_reg: regulator@12 { - compatible = "regulator-fixed"; - regulator-name = "vmmc_reg"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - }; - }; -}; - -/* Power */ -&vbat { - regulator-name = "vbat"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; -}; - -&mac { - pinctrl-names = "default"; - pinctrl-0 = <&cpsw_default>; - dual_emac = <1>; - status = "okay"; -}; - -&davinci_mdio { - pinctrl-names = "default"; - pinctrl-0 = <&davinci_mdio_default>; - status = "okay"; - - ethphy0: ethernet-phy@4 { - reg = <4>; - }; - - ethphy1: ethernet-phy@5 { - reg = <5>; - }; -}; - -&cpsw_emac0 { - status = "okay"; - phy-handle = <ðphy0>; - phy-mode = "rmii"; - dual_emac_res_vlan = <1>; -}; - -&cpsw_emac1 { - status = "okay"; - phy-handle = <ðphy1>; - phy-mode = "rmii"; - dual_emac_res_vlan = <2>; -}; - -&sham { - status = "okay"; -}; - -&aes { - status = "okay"; -}; - -&gpio0 { - ti,no-reset-on-init; -}; - -&mmc1 { - pinctrl-names = "default"; - vmmc-supply = <&vmmcsd_fixed>; - bus-width = <4>; - pinctrl-0 = <&mmc0_pins_default>; - cd-gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>; - wp-gpios = <&gpio3 18 GPIO_ACTIVE_HIGH>; - status = "okay"; -}; - -&mmc3 { - dmas = <&edma_xbar 12 0 1 - &edma_xbar 13 0 2>; - dma-names = "tx", "rx"; - pinctrl-names = "default"; - vmmc-supply = <&vmmcsd_fixed>; - bus-width = <8>; - pinctrl-0 = <&mmc2_pins_default>; - non-removable; - status = "okay"; -}; - -&buttons { - pinctrl-names = "default"; - pinctrl-0 = <&push_button_pins>; - #address-cells = <1>; - #size-cells = <0>; - - button@0 { - label = "push_button"; - linux,code = <0x100>; - gpios = <&gpio3 21 GPIO_ACTIVE_LOW>; }; }; -/* SPI Busses */ -&spi0 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; - - m25p80@0 { - compatible = "mx25l6405d"; - spi-max-frequency = <40000000>; - - reg = <0>; - spi-cpol; - spi-cpha; - #address-cells = <1>; - #size-cells = <1>; - - /* reg : The partition's offset and size within the mtd bank. */ - partitions@0 { - label = "MLO"; - reg = <0x0 0x80000>; - }; - - partitions@1 { - label = "U-Boot"; - reg = <0x80000 0x100000>; - }; - - partitions@2 { - label = "U-Boot Env"; - reg = <0x180000 0x20000>; - }; - }; -}; diff --git a/arch/arm/boot/dts/am335x-sbc-t335.dts b/arch/arm/boot/dts/am335x-sbc-t335.dts index a3f6bc4072d9..81e4453687ba 100644 --- a/arch/arm/boot/dts/am335x-sbc-t335.dts +++ b/arch/arm/boot/dts/am335x-sbc-t335.dts @@ -155,13 +155,13 @@ gpio-controller; #gpio-cells = <2>; reg = <0x26>; - dvi_ena { + dvi-ena-hog { gpio-hog; gpios = <13 GPIO_ACTIVE_HIGH>; output-high; line-name = "dvi-enable"; }; - lcd_ena { + lcd-ena-hog { gpio-hog; gpios = <11 GPIO_ACTIVE_HIGH>; output-high; diff --git a/arch/arm/boot/dts/am33xx-l4.dtsi b/arch/arm/boot/dts/am33xx-l4.dtsi index b88d0caa4b2d..ea20e4bdf040 100644 --- a/arch/arm/boot/dts/am33xx-l4.dtsi +++ b/arch/arm/boot/dts/am33xx-l4.dtsi @@ -425,7 +425,6 @@ target-module@3e000 { /* 0x44e3e000, ap 35 60.0 */ compatible = "ti,sysc-omap4-simple", "ti,sysc"; - ti,hwmods = "rtc"; reg = <0x3e074 0x4>, <0x3e078 0x4>; reg-names = "rev", "sysc"; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 5cb4cc37cb6d..4c2298024137 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -172,7 +172,7 @@ * for the moment, just use a fake OCP bus entry to represent * the whole bus hierarchy. */ - ocp { + ocp: ocp { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -578,6 +578,7 @@ <SYSC_IDLE_SMART>; clocks = <&gfx_l3_clkctrl AM3_GFX_L3_GFX_CLKCTRL 0>; clock-names = "fck"; + power-domains = <&prm_gfx>; resets = <&prm_gfx 0>; reset-names = "rstctrl"; #address-cells = <1>; @@ -617,6 +618,7 @@ prm_gfx: prm@1100 { compatible = "ti,am3-prm-inst", "ti,omap-prm-inst"; reg = <0x1100 0x100>; + #power-domain-cells = <0>; #reset-cells = <1>; }; }; diff --git a/arch/arm/boot/dts/am3517-evm-ui.dtsi b/arch/arm/boot/dts/am3517-evm-ui.dtsi index 250c40da2535..7d8f32bf70db 100644 --- a/arch/arm/boot/dts/am3517-evm-ui.dtsi +++ b/arch/arm/boot/dts/am3517-evm-ui.dtsi @@ -183,14 +183,14 @@ }; &mcbsp1 { - status = "ok"; + status = "okay"; #sound-dai-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&mcbsp1_pins>; }; &mcbsp2 { - status = "ok"; + status = "okay"; #sound-dai-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&mcbsp2_pins>; diff --git a/arch/arm/boot/dts/am3517-evm.dts b/arch/arm/boot/dts/am3517-evm.dts index 04f20e7680b1..0d2fac98ce7d 100644 --- a/arch/arm/boot/dts/am3517-evm.dts +++ b/arch/arm/boot/dts/am3517-evm.dts @@ -176,7 +176,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dss_dpi_pins>; diff --git a/arch/arm/boot/dts/am3874-iceboard.dts b/arch/arm/boot/dts/am3874-iceboard.dts index 1bb57019d082..9423e9feaa10 100644 --- a/arch/arm/boot/dts/am3874-iceboard.dts +++ b/arch/arm/boot/dts/am3874-iceboard.dts @@ -195,7 +195,7 @@ "FMCA_PG_C2M", "FMCA_PRSNT_M2C_L", "FMCA_CLK_DIR", "SFP_LOS", "FMCB_EN_12V0", "FMCB_EN_3V3", "FMCB_EN_VADJ", "FMCB_PG_M2C", "FMCB_PG_C2M", "FMCB_PRSNT_M2C_L", "FMCB_CLK_DIR", "SFP_ModPrsL"; - reset_gpios = <&gpio2 11 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio2 11 GPIO_ACTIVE_LOW>; }; u42: pca9575@21 { @@ -208,7 +208,7 @@ "QSFPA_LPMode", "QSFPB_ModPrsL", "QSFPB_IntL", "QSFPB_ResetL", "SFP_TxFault", "SFP_TxDisable", "SFP_RS0", "SFP_RS1", "QSFPB_ModSelL", "QSFPB_LPMode", "SEL_SFP", "ARM_MR"; - reset_gpios = <&gpio2 11 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio2 11 GPIO_ACTIVE_LOW>; }; u48: pca9575@22 { @@ -227,7 +227,7 @@ "GP_SW5", "GP_SW6", "GP_SW7", "GP_SW8", "GP_LED8", "GP_LED7", "GP_LED6", "GP_LED5", "GP_LED4", "GP_LED3", "GP_LED2", "GP_LED1"; - reset_gpios = <&gpio2 11 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio2 11 GPIO_ACTIVE_LOW>; }; u59: pca9575@23 { @@ -240,7 +240,7 @@ "GTX1V8PowerFault", "PHYAPowerFault", "PHYBPowerFault", "ArmPowerFault", "BP_SLOW_GPIO0", "BP_SLOW_GPIO1", "BP_SLOW_GPIO2", "BP_SLOW_GPIO3", "BP_SLOW_GPIO4", "BP_SLOW_GPIO5", "__unused_u59_p16", "__unused_u59_p17"; - reset_gpios = <&gpio2 11 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio2 11 GPIO_ACTIVE_LOW>; }; tmp100@48 { compatible = "ti,tmp100"; reg = <0x48>; }; diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 14314046256c..878406b120be 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -35,8 +35,8 @@ serial3 = &uart3; serial4 = &uart4; serial5 = &uart5; - ethernet0 = &cpsw_emac0; - ethernet1 = &cpsw_emac1; + ethernet0 = &cpsw_port1; + ethernet1 = &cpsw_port2; spi0 = &qspi; }; @@ -517,6 +517,7 @@ <SYSC_IDLE_SMART>; clocks = <&gfx_l3_clkctrl AM4_GFX_L3_GFX_CLKCTRL 0>; clock-names = "fck"; + power-domains = <&prm_gfx>; resets = <&prm_gfx 0>; reset-names = "rstctrl"; #address-cells = <1>; @@ -533,6 +534,7 @@ prm_gfx: prm@400 { compatible = "ti,am4-prm-inst", "ti,omap-prm-inst"; reg = <0x400 0x100>; + #power-domain-cells = <0>; #reset-cells = <1>; }; diff --git a/arch/arm/boot/dts/am437x-cm-t43.dts b/arch/arm/boot/dts/am437x-cm-t43.dts index a6b4fca8626a..a83f46ed0c9a 100644 --- a/arch/arm/boot/dts/am437x-cm-t43.dts +++ b/arch/arm/boot/dts/am437x-cm-t43.dts @@ -325,17 +325,15 @@ }; }; -&mac { +&mac_sw { pinctrl-names = "default"; pinctrl-0 = <&cpsw_default>; - dual_emac = <1>; status = "okay"; }; -&davinci_mdio { +&davinci_mdio_sw { pinctrl-names = "default"; pinctrl-0 = <&davinci_mdio_default>; - status = "okay"; ethphy0: ethernet-phy@0 { reg = <0>; @@ -346,16 +344,16 @@ }; }; -&cpsw_emac0 { +&cpsw_port1 { phy-handle = <ðphy0>; phy-mode = "rgmii-txid"; - dual_emac_res_vlan = <1>; + ti,dual-emac-pvid = <1>; }; -&cpsw_emac1 { +&cpsw_port2 { phy-handle = <ðphy1>; phy-mode = "rgmii-txid"; - dual_emac_res_vlan = <2>; + ti,dual-emac-pvid = <2>; }; &dwc3_1 { diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts index b28e5c8cd02a..6e4d05d649e9 100644 --- a/arch/arm/boot/dts/am437x-gp-evm.dts +++ b/arch/arm/boot/dts/am437x-gp-evm.dts @@ -906,28 +906,31 @@ status = "okay"; }; -&mac { - slaves = <1>; +&mac_sw { pinctrl-names = "default", "sleep"; pinctrl-0 = <&cpsw_default>; pinctrl-1 = <&cpsw_sleep>; status = "okay"; }; -&davinci_mdio { +&davinci_mdio_sw { pinctrl-names = "default", "sleep"; pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; - status = "okay"; ethphy0: ethernet-phy@0 { reg = <0>; }; }; -&cpsw_emac0 { +&cpsw_port1 { phy-handle = <ðphy0>; phy-mode = "rgmii-rxid"; + ti,dual-emac-pvid = <1>; +}; + +&cpsw_port2 { + status = "disabled"; }; &elm { @@ -1024,7 +1027,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dss_pins>; diff --git a/arch/arm/boot/dts/am437x-idk-evm.dts b/arch/arm/boot/dts/am437x-idk-evm.dts index 8b986c45f09d..2dc525512266 100644 --- a/arch/arm/boot/dts/am437x-idk-evm.dts +++ b/arch/arm/boot/dts/am437x-idk-evm.dts @@ -483,28 +483,31 @@ }; }; -&mac { - slaves = <1>; +&mac_sw { pinctrl-names = "default", "sleep"; pinctrl-0 = <&cpsw_default>; pinctrl-1 = <&cpsw_sleep>; status = "okay"; }; -&davinci_mdio { +&davinci_mdio_sw { pinctrl-names = "default", "sleep"; pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; - status = "okay"; ethphy0: ethernet-phy@0 { reg = <0>; }; }; -&cpsw_emac0 { +&cpsw_port1 { phy-handle = <ðphy0>; phy-mode = "rgmii-rxid"; + ti,dual-emac-pvid = <1>; +}; + +&cpsw_port2 { + status = "disabled"; }; &rtc { diff --git a/arch/arm/boot/dts/am437x-l4.dtsi b/arch/arm/boot/dts/am437x-l4.dtsi index 3d393fe252c6..c220dc3c4e0f 100644 --- a/arch/arm/boot/dts/am437x-l4.dtsi +++ b/arch/arm/boot/dts/am437x-l4.dtsi @@ -409,9 +409,8 @@ ranges = <0x0 0x39000 0x1000>; }; - target-module@3e000 { /* 0x44e3e000, ap 34 60.0 */ + rtc_target: target-module@3e000 { /* 0x44e3e000, ap 34 60.0 */ compatible = "ti,sysc-omap4-simple", "ti,sysc"; - ti,hwmods = "rtc"; reg = <0x3e074 0x4>, <0x3e078 0x4>; reg-names = "rev", "sysc"; @@ -521,54 +520,57 @@ #size-cells = <1>; ranges = <0x0 0x100000 0x8000>; - mac: ethernet@0 { - compatible = "ti,am4372-cpsw","ti,cpsw"; - reg = <0x0 0x800 - 0x1200 0x100>; + mac_sw: switch@0 { + compatible = "ti,am4372-cpsw","ti,cpsw-switch"; + reg = <0x0 0x4000>; + ranges = <0 0 0x4000>; + clocks = <&cpsw_125mhz_gclk>, <&dpll_clksel_mac_clk>; + clock-names = "fck", "50mclk"; + assigned-clocks = <&dpll_clksel_mac_clk>; + assigned-clock-rates = <50000000>; + #address-cells = <1>; + #size-cells = <1>; + syscon = <&scm_conf>; + status = "disabled"; + interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; - #address-cells = <1>; - #size-cells = <1>; - clocks = <&cpsw_125mhz_gclk>, <&cpsw_cpts_rft_clk>, - <&dpll_clksel_mac_clk>; - clock-names = "fck", "cpts", "50mclk"; - assigned-clocks = <&dpll_clksel_mac_clk>; - assigned-clock-rates = <50000000>; - status = "disabled"; - cpdma_channels = <8>; - ale_entries = <1024>; - bd_ram_size = <0x2000>; - mac_control = <0x20>; - slaves = <2>; - active_slave = <0>; - cpts_clock_mult = <0x80000000>; - cpts_clock_shift = <29>; - ranges = <0 0 0x8000>; - syscon = <&scm_conf>; + interrupt-names = "rx_thresh", "rx", "tx", "misc"; - davinci_mdio: mdio@1000 { - compatible = "ti,am4372-mdio","ti,cpsw-mdio","ti,davinci_mdio"; - reg = <0x1000 0x100>; - clocks = <&cpsw_125mhz_clkctrl AM4_CPSW_125MHZ_CPGMAC0_CLKCTRL 0>; - clock-names = "fck"; + ethernet-ports { #address-cells = <1>; #size-cells = <0>; - bus_freq = <1000000>; - status = "disabled"; + + cpsw_port1: port@1 { + reg = <1>; + label = "port1"; + mac-address = [ 00 00 00 00 00 00 ]; + phys = <&phy_gmii_sel 1 0>; + }; + + cpsw_port2: port@2 { + reg = <2>; + label = "port2"; + mac-address = [ 00 00 00 00 00 00 ]; + phys = <&phy_gmii_sel 2 0>; + }; }; - cpsw_emac0: slave@200 { - /* Filled in by U-Boot */ - mac-address = [ 00 00 00 00 00 00 ]; - phys = <&phy_gmii_sel 1 0>; + davinci_mdio_sw: mdio@1000 { + compatible = "ti,am4372-mdio", "ti,cpsw-mdio","ti,davinci_mdio"; + clocks = <&cpsw_125mhz_gclk>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <0>; + bus_freq = <1000000>; + reg = <0x1000 0x100>; }; - cpsw_emac1: slave@300 { - /* Filled in by U-Boot */ - mac-address = [ 00 00 00 00 00 00 ]; - phys = <&phy_gmii_sel 2 0>; + cpts { + clocks = <&cpsw_cpts_rft_clk>; + clock-names = "cpts"; }; }; }; diff --git a/arch/arm/boot/dts/am437x-sbc-t43.dts b/arch/arm/boot/dts/am437x-sbc-t43.dts index 94cf07ea27f7..8ea3780f939d 100644 --- a/arch/arm/boot/dts/am437x-sbc-t43.dts +++ b/arch/arm/boot/dts/am437x-sbc-t43.dts @@ -136,7 +136,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dss_pinctrl_default>; diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts b/arch/arm/boot/dts/am437x-sk-evm.dts index 5fffdce853b1..496ed34f7755 100644 --- a/arch/arm/boot/dts/am437x-sk-evm.dts +++ b/arch/arm/boot/dts/am437x-sk-evm.dts @@ -792,19 +792,17 @@ }; }; -&mac { +&mac_sw { pinctrl-names = "default", "sleep"; pinctrl-0 = <&cpsw_default>; pinctrl-1 = <&cpsw_sleep>; - dual_emac = <1>; status = "okay"; }; -&davinci_mdio { +&davinci_mdio_sw { pinctrl-names = "default", "sleep"; pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; - status = "okay"; ethphy0: ethernet-phy@4 { reg = <4>; @@ -815,16 +813,16 @@ }; }; -&cpsw_emac0 { +&cpsw_port1 { phy-handle = <ðphy0>; phy-mode = "rgmii-rxid"; - dual_emac_res_vlan = <1>; + ti,dual-emac-pvid = <1>; }; -&cpsw_emac1 { +&cpsw_port2 { phy-handle = <ðphy1>; phy-mode = "rgmii-rxid"; - dual_emac_res_vlan = <2>; + ti,dual-emac-pvid = <2>; }; &elm { diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts index de4fc78498a0..f517d1e843cf 100644 --- a/arch/arm/boot/dts/am43x-epos-evm.dts +++ b/arch/arm/boot/dts/am43x-epos-evm.dts @@ -550,29 +550,32 @@ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; }; -&mac { +&mac_sw { pinctrl-names = "default", "sleep"; pinctrl-0 = <&cpsw_default>; pinctrl-1 = <&cpsw_sleep>; status = "okay"; - slaves = <1>; }; -&davinci_mdio { +&davinci_mdio_sw { pinctrl-names = "default", "sleep"; pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; - status = "okay"; ethphy0: ethernet-phy@16 { reg = <16>; }; }; -&cpsw_emac0 { +&cpsw_port1 { phy-handle = <ðphy0>; phy-mode = "rmii"; phys = <&phy_gmii_sel 1 1>; + ti,dual-emac-pvid = <1>; +}; + +&cpsw_port2 { + status = "disabled"; }; &i2c0 { @@ -833,6 +836,10 @@ status = "okay"; }; +&rtc_target { + status = "disabled"; +}; + &tscadc { status = "okay"; @@ -948,7 +955,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dss_pins>; diff --git a/arch/arm/boot/dts/am571x-idk.dts b/arch/arm/boot/dts/am571x-idk.dts index 391a92e24472..e81078c2d00d 100644 --- a/arch/arm/boot/dts/am571x-idk.dts +++ b/arch/arm/boot/dts/am571x-idk.dts @@ -208,30 +208,3 @@ pinctrl-1 = <&mmc2_pins_hs>; pinctrl-2 = <&mmc2_pins_ddr_rev20 &mmc2_iodelay_ddr_conf>; }; - -&mac_sw { - pinctrl-names = "default", "sleep"; - status = "okay"; -}; - -&cpsw_port1 { - phy-handle = <ðphy0_sw>; - phy-mode = "rgmii-rxid"; - ti,dual-emac-pvid = <1>; -}; - -&cpsw_port2 { - phy-handle = <ðphy1_sw>; - phy-mode = "rgmii-rxid"; - ti,dual-emac-pvid = <2>; -}; - -&davinci_mdio_sw { - ethphy0_sw: ethernet-phy@0 { - reg = <0>; - }; - - ethphy1_sw: ethernet-phy@1 { - reg = <1>; - }; -}; diff --git a/arch/arm/boot/dts/am5729-beagleboneai.dts b/arch/arm/boot/dts/am5729-beagleboneai.dts index e9c7f44126e7..149cfafb90bf 100644 --- a/arch/arm/boot/dts/am5729-beagleboneai.dts +++ b/arch/arm/boot/dts/am5729-beagleboneai.dts @@ -488,25 +488,29 @@ status = "okay"; }; -&davinci_mdio { +&davinci_mdio_sw { reset-gpios = <&gpio2 23 GPIO_ACTIVE_LOW>; reset-delay-us = <2>; - phy0: ethernet-phy@1 { + phy0: ethernet-phy@4 { reg = <4>; eee-broken-100tx; eee-broken-1000t; }; }; -&mac { - slaves = <1>; +&mac_sw { status = "okay"; }; -&cpsw_emac0 { +&cpsw_port1 { phy-handle = <&phy0>; phy-mode = "rgmii-rxid"; + ti,dual-emac-pvid = <1>; +}; + +&cpsw_port2 { + status = "disabled"; }; &ocp { diff --git a/arch/arm/boot/dts/am572x-idk.dts b/arch/arm/boot/dts/am572x-idk.dts index 1a3af4b54308..6504265f3f7e 100644 --- a/arch/arm/boot/dts/am572x-idk.dts +++ b/arch/arm/boot/dts/am572x-idk.dts @@ -27,8 +27,3 @@ pinctrl-1 = <&mmc2_pins_hs>; pinctrl-2 = <&mmc2_pins_ddr_rev20>; }; - -&mac { - status = "okay"; - dual_emac; -}; diff --git a/arch/arm/boot/dts/am574x-idk.dts b/arch/arm/boot/dts/am574x-idk.dts index c9275d0c62cf..37758761cd88 100644 --- a/arch/arm/boot/dts/am574x-idk.dts +++ b/arch/arm/boot/dts/am574x-idk.dts @@ -36,11 +36,6 @@ pinctrl-2 = <&mmc2_pins_default>; }; -&mac { - status = "okay"; - dual_emac; -}; - &m_can0 { status = "disabled"; }; diff --git a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi index b3a0206ebd6c..6b82ecf803c5 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi +++ b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi @@ -451,7 +451,7 @@ <&dra7_pmx_core 0x3f8>; }; -&davinci_mdio { +&davinci_mdio_sw { phy0: ethernet-phy@1 { reg = <1>; }; @@ -461,21 +461,20 @@ }; }; -&mac { +&mac_sw { status = "okay"; - dual_emac; }; -&cpsw_emac0 { +&cpsw_port1 { phy-handle = <&phy0>; phy-mode = "rgmii-rxid"; - dual_emac_res_vlan = <1>; + ti,dual-emac-pvid = <1>; }; -&cpsw_emac1 { +&cpsw_port2 { phy-handle = <&phy1>; phy-mode = "rgmii-rxid"; - dual_emac_res_vlan = <2>; + ti,dual-emac-pvid = <2>; }; &mmc1 { @@ -582,13 +581,13 @@ }; &dss { - status = "ok"; + status = "okay"; vdda_video-supply = <&ldoln_reg>; }; &hdmi { - status = "ok"; + status = "okay"; vdda-supply = <&ldo4_reg>; port { @@ -599,7 +598,7 @@ }; &pcie1_rc { - status = "ok"; + status = "okay"; gpios = <&gpio2 8 GPIO_ACTIVE_LOW>; }; diff --git a/arch/arm/boot/dts/am57xx-cl-som-am57x.dts b/arch/arm/boot/dts/am57xx-cl-som-am57x.dts index 34ca761aeded..0d5fe2bfb683 100644 --- a/arch/arm/boot/dts/am57xx-cl-som-am57x.dts +++ b/arch/arm/boot/dts/am57xx-cl-som-am57x.dts @@ -546,27 +546,26 @@ }; }; -&mac { +&mac_sw { status = "okay"; pinctrl-names = "default", "sleep"; pinctrl-0 = <&cpsw_pins_default>; pinctrl-1 = <&cpsw_pins_sleep>; - dual_emac; }; -&cpsw_emac0 { +&cpsw_port1 { phy-handle = <ðphy0>; phy-mode = "rgmii-txid"; - dual_emac_res_vlan = <0>; + ti,dual-emac-pvid = <1>; }; -&cpsw_emac1 { +&cpsw_port2 { phy-handle = <ðphy1>; phy-mode = "rgmii-txid"; - dual_emac_res_vlan = <1>; + ti,dual-emac-pvid = <2>; }; -&davinci_mdio { +&davinci_mdio_sw { pinctrl-names = "default", "sleep"; pinctrl-0 = <&davinci_mdio_pins_default>; pinctrl-1 = <&davinci_mdio_pins_sleep>; diff --git a/arch/arm/boot/dts/am57xx-idk-common.dtsi b/arch/arm/boot/dts/am57xx-idk-common.dtsi index 1c77006cccd1..9fcb8944aa3e 100644 --- a/arch/arm/boot/dts/am57xx-idk-common.dtsi +++ b/arch/arm/boot/dts/am57xx-idk-common.dtsi @@ -448,19 +448,23 @@ ext-clk-src; }; -&cpsw_emac0 { +&mac_sw { + status = "okay"; +}; + +&cpsw_port1 { phy-handle = <ðphy0>; phy-mode = "rgmii-rxid"; - dual_emac_res_vlan = <1>; + ti,dual-emac-pvid = <1>; }; -&cpsw_emac1 { +&cpsw_port2 { phy-handle = <ðphy1>; phy-mode = "rgmii-rxid"; - dual_emac_res_vlan = <2>; + ti,dual-emac-pvid = <2>; }; -&davinci_mdio { +&davinci_mdio_sw { ethphy0: ethernet-phy@0 { reg = <0>; }; diff --git a/arch/arm/boot/dts/am57xx-sbc-am57x.dts b/arch/arm/boot/dts/am57xx-sbc-am57x.dts index ce5bf1d92eab..beef63e8a005 100644 --- a/arch/arm/boot/dts/am57xx-sbc-am57x.dts +++ b/arch/arm/boot/dts/am57xx-sbc-am57x.dts @@ -120,7 +120,7 @@ }; &dss { - status = "ok"; + status = "okay"; vdda_video-supply = <&ldoln_reg>; @@ -148,7 +148,7 @@ }; &hdmi { - status = "ok"; + status = "okay"; vdda-supply = <&ldo4_reg>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/animeo_ip.dts b/arch/arm/boot/dts/animeo_ip.dts index c36d28c295d6..7da718abbd85 100644 --- a/arch/arm/boot/dts/animeo_ip.dts +++ b/arch/arm/boot/dts/animeo_ip.dts @@ -26,7 +26,7 @@ stdout-path = &usart2; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; @@ -81,6 +81,7 @@ pinctrl-0 = <&pinctrl_mmc0_clk &pinctrl_mmc0_slot1_cmd_dat0 &pinctrl_mmc0_slot1_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@1 { diff --git a/arch/arm/boot/dts/arm-realview-eb.dtsi b/arch/arm/boot/dts/arm-realview-eb.dtsi index fe0207b88053..a534a8e444d9 100644 --- a/arch/arm/boot/dts/arm-realview-eb.dtsi +++ b/arch/arm/boot/dts/arm-realview-eb.dtsi @@ -390,7 +390,7 @@ compatible = "arm,sp805", "arm,primecell"; reg = <0x10010000 0x1000>; clocks = <&wdogclk>, <&pclk>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/arm-realview-pb11mp.dts b/arch/arm/boot/dts/arm-realview-pb11mp.dts index 9748e0fe800f..0c7dabef4a5f 100644 --- a/arch/arm/boot/dts/arm-realview-pb11mp.dts +++ b/arch/arm/boot/dts/arm-realview-pb11mp.dts @@ -546,7 +546,7 @@ interrupt-parent = <&intc_pb11mp>; interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>; clocks = <&wdogclk>, <&pclk>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; status = "disabled"; }; @@ -556,7 +556,7 @@ interrupt-parent = <&intc_pb11mp>; interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>; clocks = <&wdogclk>, <&pclk>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; }; timer01: timer@10011000 { @@ -568,8 +568,8 @@ clocks = <&sp810_syscon 0>, <&sp810_syscon 1>, <&pclk>; - clock-names = "timerclk0", - "timerclk1", + clock-names = "timer0clk", + "timer1clk", "apb_pclk"; }; @@ -582,8 +582,8 @@ clocks = <&sp810_syscon 2>, <&sp810_syscon 3>, <&pclk>; - clock-names = "timerclk2", - "timerclk3", + clock-names = "timer0clk", + "timer1clk", "apb_pclk"; }; @@ -645,16 +645,16 @@ timer45: timer@10018000 { compatible = "arm,sp804", "arm,primecell"; reg = <0x10018000 0x1000>; - clocks = <&timclk>, <&pclk>; - clock-names = "timer", "apb_pclk"; + clocks = <&timclk>, <&timclk>, <&pclk>; + clock-names = "timer0clk", "timer1clk", "apb_pclk"; status = "disabled"; }; timer67: timer@10019000 { compatible = "arm,sp804", "arm,primecell"; reg = <0x10019000 0x1000>; - clocks = <&timclk>, <&pclk>; - clock-names = "timer", "apb_pclk"; + clocks = <&timclk>, <&timclk>, <&pclk>; + clock-names = "timer0clk", "timer1clk", "apb_pclk"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/arm-realview-pbx.dtsi b/arch/arm/boot/dts/arm-realview-pbx.dtsi index f61bd59ae5ba..ac95667ed781 100644 --- a/arch/arm/boot/dts/arm-realview-pbx.dtsi +++ b/arch/arm/boot/dts/arm-realview-pbx.dtsi @@ -381,7 +381,7 @@ compatible = "arm,sp805", "arm,primecell"; reg = <0x1000f000 0x1000>; clocks = <&wdogclk>, <&pclk>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; status = "disabled"; }; @@ -389,7 +389,7 @@ compatible = "arm,sp805", "arm,primecell"; reg = <0x10010000 0x1000>; clocks = <&wdogclk>, <&pclk>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-cmm.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-cmm.dts index 7bc7df7ed428..2fb8b147f489 100644 --- a/arch/arm/boot/dts/aspeed-bmc-facebook-cmm.dts +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-cmm.dts @@ -1571,3 +1571,20 @@ &sdhci1 { status = "disabled"; }; + +&fmc_flash0 { +#include "facebook-bmc-flash-layout.dtsi" +}; + +&fmc_flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + flash1@0 { + reg = <0x0 0x2000000>; + label = "flash1"; + }; + }; +}; diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts index 88ce4ff9f47e..c34741dbd268 100644 --- a/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts @@ -88,17 +88,60 @@ */ &fmc_flash0 { partitions { - data0@1c00000 { - reg = <0x1c00000 0x2400000>; + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* + * u-boot partition: 384KB. + */ + u-boot@0 { + reg = <0x0 0x60000>; + label = "u-boot"; }; + + /* + * u-boot environment variables: 128KB. + */ + u-boot-env@60000 { + reg = <0x60000 0x20000>; + label = "env"; + }; + + /* + * FIT image: 59.5 MB. + */ + fit@80000 { + reg = <0x80000 0x3b80000>; + label = "fit"; + }; + + /* + * "data0" partition (4MB) is reserved for persistent + * data store. + */ + data0@3800000 { + reg = <0x3c00000 0x400000>; + label = "data0"; + }; + + /* + * "flash0" partition (covering the entire flash) is + * explicitly created to avoid breaking legacy applications. + */ flash0@0 { reg = <0x0 0x4000000>; + label = "flash0"; }; }; }; &fmc_flash1 { partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + flash1@0 { reg = <0x0 0x4000000>; }; diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-wedge40.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge40.dts index 8ac23ff6b09e..8c426ba2f8ab 100644 --- a/arch/arm/boot/dts/aspeed-bmc-facebook-wedge40.dts +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge40.dts @@ -48,7 +48,7 @@ flash@0 { status = "okay"; m25p,fast-read; - label = "fmc0"; + label = "spi0.0"; #include "facebook-bmc-flash-layout.dtsi" }; }; @@ -71,7 +71,8 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_txd4_default - &pinctrl_rxd4_default>; + &pinctrl_rxd4_default + &pinctrl_ndts4_default>; }; &uart5 { diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts new file mode 100644 index 000000000000..ad1fcad3676c --- /dev/null +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts @@ -0,0 +1,420 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2019 Facebook Inc. +/dts-v1/; + +#include <dt-bindings/gpio/aspeed-gpio.h> +#include "ast2500-facebook-netbmc-common.dtsi" + +/ { + model = "Facebook Wedge 400 BMC"; + compatible = "facebook,wedge400-bmc", "aspeed,ast2500"; + + aliases { + /* + * PCA9548 (2-0070) provides 8 channels connecting to + * SCM (System Controller Module). + */ + i2c16 = &imux16; + i2c17 = &imux17; + i2c18 = &imux18; + i2c19 = &imux19; + i2c20 = &imux20; + i2c21 = &imux21; + i2c22 = &imux22; + i2c23 = &imux23; + + /* + * PCA9548 (8-0070) provides 8 channels connecting to + * SMB (Switch Main Board). + */ + i2c24 = &imux24; + i2c25 = &imux25; + i2c26 = &imux26; + i2c27 = &imux27; + i2c28 = &imux28; + i2c29 = &imux29; + i2c30 = &imux30; + i2c31 = &imux31; + + /* + * PCA9548 (11-0076) provides 8 channels connecting to + * FCM (Fan Controller Module). + */ + i2c32 = &imux32; + i2c33 = &imux33; + i2c34 = &imux34; + i2c35 = &imux35; + i2c36 = &imux36; + i2c37 = &imux37; + i2c38 = &imux38; + i2c39 = &imux39; + + spi2 = &spi_gpio; + }; + + chosen { + stdout-path = &uart1; + bootargs = "console=ttyS0,9600n8 root=/dev/ram rw"; + }; + + ast-adc-hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>, <&adc 4>; + }; + + /* + * GPIO-based SPI Master is required to access SPI TPM, because + * full-duplex SPI transactions are not supported by ASPEED SPI + * Controllers. + */ + spi_gpio: spi-gpio { + status = "okay"; + compatible = "spi-gpio"; + #address-cells = <1>; + #size-cells = <0>; + + cs-gpios = <&gpio ASPEED_GPIO(R, 2) GPIO_ACTIVE_LOW>; + gpio-sck = <&gpio ASPEED_GPIO(R, 3) GPIO_ACTIVE_HIGH>; + gpio-mosi = <&gpio ASPEED_GPIO(R, 4) GPIO_ACTIVE_HIGH>; + gpio-miso = <&gpio ASPEED_GPIO(R, 5) GPIO_ACTIVE_HIGH>; + num-chipselects = <1>; + + tpmdev@0 { + compatible = "tcg,tpm_tis-spi"; + spi-max-frequency = <33000000>; + reg = <0>; + }; + }; +}; + +/* + * Both firmware flashes are 128MB on Wedge400 BMC. + */ +&fmc_flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* + * u-boot partition: 384KB. + */ + u-boot@0 { + reg = <0x0 0x60000>; + label = "u-boot"; + }; + + /* + * u-boot environment variables: 128KB. + */ + u-boot-env@60000 { + reg = <0x60000 0x20000>; + label = "env"; + }; + + /* + * FIT image: 123.5 MB. + */ + fit@80000 { + reg = <0x80000 0x7b80000>; + label = "fit"; + }; + + /* + * "data0" partition (4MB) is reserved for persistent + * data store. + */ + data0@3800000 { + reg = <0x7c00000 0x800000>; + label = "data0"; + }; + + /* + * "flash0" partition (covering the entire flash) is + * explicitly created to avoid breaking legacy applications. + */ + flash0@0 { + reg = <0x0 0x8000000>; + label = "flash0"; + }; + }; +}; + +&fmc_flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + flash1@0 { + reg = <0x0 0x8000000>; + label = "flash1"; + }; + }; +}; + +&uart2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_txd2_default + &pinctrl_rxd2_default>; +}; + +&uart4 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_txd4_default + &pinctrl_rxd4_default>; +}; + +/* + * I2C bus #0 is multi-master environment dedicated for BMC and Bridge IC + * communication. + */ +&i2c0 { + status = "okay"; + multi-master; + bus-frequency = <1000000>; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; + + i2c-switch@70 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x70>; + i2c-mux-idle-disconnect; + + imux16: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux17: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux18: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux19: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux20: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux21: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux22: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux23: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; +}; + +&i2c3 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; +}; + +&i2c5 { + status = "okay"; +}; + +&i2c6 { + status = "okay"; +}; + +&i2c7 { + status = "okay"; +}; + +&i2c8 { + status = "okay"; + + i2c-switch@70 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x70>; + i2c-mux-idle-disconnect; + + imux24: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux25: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux26: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux27: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux28: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux29: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux30: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux31: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + + }; +}; + +&i2c9 { + status = "okay"; +}; + +&i2c10 { + status = "okay"; +}; + +&i2c11 { + status = "okay"; + + i2c-switch@76 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x76>; + i2c-mux-idle-disconnect; + + imux32: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + imux33: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + + imux34: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + + imux35: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + + imux36: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + + imux37: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + + imux38: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + + imux39: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + + }; +}; + +&i2c12 { + status = "okay"; +}; + +&i2c13 { + status = "okay"; +}; + +&adc { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&uhci { + status = "okay"; +}; + +&sdhci1 { + /* + * DMA mode needs to be disabled to avoid conflicts with UHCI + * Controller in AST2500 SoC. + */ + sdhci-caps-mask = <0x0 0x580000>; +}; diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-yamp.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-yamp.dts index fe2e11c2da15..5e6105874217 100644 --- a/arch/arm/boot/dts/aspeed-bmc-facebook-yamp.dts +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-yamp.dts @@ -108,3 +108,20 @@ &i2c13 { status = "okay"; }; + +&fmc_flash0 { +#include "facebook-bmc-flash-layout.dtsi" +}; + +&fmc_flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + flash1@0 { + reg = <0x0 0x2000000>; + label = "flash1"; + }; + }; +}; diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts index b94421f6cbd5..21ae880c7530 100644 --- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts +++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts @@ -4,6 +4,7 @@ #include "aspeed-g6.dtsi" #include <dt-bindings/gpio/aspeed-gpio.h> +#include <dt-bindings/i2c/i2c.h> #include <dt-bindings/leds/leds-pca955x.h> / { @@ -52,9 +53,10 @@ }; vga_memory: region@bf000000 { - no-map; - reg = <0xbf000000 0x01000000>; /* 16M */ - }; + no-map; + compatible = "shared-dma-pool"; + reg = <0xbf000000 0x01000000>; /* 16M */ + }; }; gpio-keys { @@ -178,6 +180,10 @@ status = "okay"; }; +&pinctrl_emmc_default { + bias-disable; +}; + &emmc { status = "okay"; }; @@ -698,6 +704,7 @@ }; &i2c7 { + multi-master; status = "okay"; si7021-a20@20 { @@ -831,6 +838,11 @@ }; }; + ibm-panel@62 { + compatible = "ibm,op-panel"; + reg = <(0x62 | I2C_OWN_SLAVE_ADDRESS)>; + }; + dps: dps310@76 { compatible = "infineon,dps310"; reg = <0x76>; @@ -1121,3 +1133,8 @@ spi-max-frequency = <100000000>; }; }; + +&xdma { + status = "okay"; + memory-region = <&vga_memory>; +}; diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-mowgli.dts b/arch/arm/boot/dts/aspeed-bmc-opp-mowgli.dts new file mode 100644 index 000000000000..b648e468e9db --- /dev/null +++ b/arch/arm/boot/dts/aspeed-bmc-opp-mowgli.dts @@ -0,0 +1,662 @@ +// SPDX-License-Identifier: GPL-2.0+ +/dts-v1/; +#include "aspeed-g5.dtsi" +#include <dt-bindings/gpio/aspeed-gpio.h> +#include <dt-bindings/leds/leds-pca955x.h> + +/ { + model = "Mowgli BMC"; + compatible = "ibm,mowgli-bmc", "aspeed,ast2500"; + + + chosen { + stdout-path = &uart5; + bootargs = "console=ttyS4,115200 earlyprintk"; + }; + + memory@80000000 { + reg = <0x80000000 0x20000000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + flash_memory: region@98000000 { + no-map; + reg = <0x98000000 0x04000000>; /* 64M */ + }; + + gfx_memory: framebuffer { + size = <0x01000000>; + alignment = <0x01000000>; + compatible = "shared-dma-pool"; + reusable; + }; + + video_engine_memory: jpegbuffer { + size = <0x02000000>; + alignment = <0x01000000>; + compatible = "shared-dma-pool"; + reusable; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + air-water { + label = "air-water"; + gpios = <&gpio ASPEED_GPIO(F, 6) GPIO_ACTIVE_LOW>; + linux,code = <ASPEED_GPIO(F, 6)>; + }; + + checkstop { + label = "checkstop"; + gpios = <&gpio ASPEED_GPIO(J, 2) GPIO_ACTIVE_LOW>; + linux,code = <ASPEED_GPIO(J, 2)>; + }; + + ps0-presence { + label = "ps0-presence"; + gpios = <&gpio ASPEED_GPIO(Z, 2) GPIO_ACTIVE_LOW>; + linux,code = <ASPEED_GPIO(Z, 2)>; + }; + + ps1-presence { + label = "ps1-presence"; + gpios = <&gpio ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>; + linux,code = <ASPEED_GPIO(Z, 0)>; + }; + + id-button { + label = "id-button"; + gpios = <&gpio ASPEED_GPIO(F, 1) GPIO_ACTIVE_LOW>; + linux,code = <ASPEED_GPIO(F, 1)>; + }; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + poll-interval = <1000>; + + fan0-presence { + label = "fan0-presence"; + gpios = <&pca9552 9 GPIO_ACTIVE_LOW>; + linux,code = <9>; + }; + + fan1-presence { + label = "fan1-presence"; + gpios = <&pca9552 10 GPIO_ACTIVE_LOW>; + linux,code = <10>; + }; + + fan2-presence { + label = "fan2-presence"; + gpios = <&pca9552 11 GPIO_ACTIVE_LOW>; + linux,code = <11>; + }; + + fan3-presence { + label = "fan3-presence"; + gpios = <&pca9552 12 GPIO_ACTIVE_LOW>; + linux,code = <12>; + }; + + fan4-presence { + label = "fan4-presence"; + gpios = <&pca9552 13 GPIO_ACTIVE_LOW>; + linux,code = <13>; + }; + }; + + leds { + compatible = "gpio-leds"; + + front-fault { + retain-state-shutdown; + default-state = "keep"; + gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_LOW>; + }; + + power-button { + retain-state-shutdown; + default-state = "keep"; + gpios = <&gpio ASPEED_GPIO(AA, 1) GPIO_ACTIVE_LOW>; + }; + + front-id { + retain-state-shutdown; + default-state = "keep"; + gpios = <&gpio ASPEED_GPIO(AA, 2) GPIO_ACTIVE_LOW>; + }; + + fan0 { + retain-state-shutdown; + default-state = "keep"; + gpios = <&pca9552 0 GPIO_ACTIVE_LOW>; + }; + + fan1 { + retain-state-shutdown; + default-state = "keep"; + gpios = <&pca9552 1 GPIO_ACTIVE_LOW>; + }; + + fan2 { + retain-state-shutdown; + default-state = "keep"; + gpios = <&pca9552 2 GPIO_ACTIVE_LOW>; + }; + + fan3 { + retain-state-shutdown; + default-state = "keep"; + gpios = <&pca9552 3 GPIO_ACTIVE_LOW>; + }; + + fan4 { + retain-state-shutdown; + default-state = "keep"; + gpios = <&pca9552 4 GPIO_ACTIVE_LOW>; + }; + }; + + fsi: gpio-fsi { + compatible = "fsi-master-gpio", "fsi-master"; + #address-cells = <2>; + #size-cells = <0>; + no-gpio-delays; + + clock-gpios = <&gpio ASPEED_GPIO(E, 6) GPIO_ACTIVE_HIGH>; + data-gpios = <&gpio ASPEED_GPIO(E, 7) GPIO_ACTIVE_HIGH>; + mux-gpios = <&gpio ASPEED_GPIO(R, 2) GPIO_ACTIVE_HIGH>; + enable-gpios = <&gpio ASPEED_GPIO(D, 0) GPIO_ACTIVE_HIGH>; + trans-gpios = <&gpio ASPEED_GPIO(E, 5) GPIO_ACTIVE_HIGH>; + }; + + iio-hwmon-12v { + compatible = "iio-hwmon"; + io-channels = <&adc 0>; + }; + + iio-hwmon-5v { + compatible = "iio-hwmon"; + io-channels = <&adc 1>; + }; + + iio-hwmon-3v { + compatible = "iio-hwmon"; + io-channels = <&adc 2>; + }; + + iio-hwmon-vdd { + compatible = "iio-hwmon"; + io-channels = <&adc 3>; + }; + + iio-hwmon-vcs { + compatible = "iio-hwmon"; + io-channels = <&adc 5>; + }; + + iio-hwmon-vdn { + compatible = "iio-hwmon"; + io-channels = <&adc 7>; + }; + + iio-hwmon-vio { + compatible = "iio-hwmon"; + io-channels = <&adc 9>; + }; + + iio-hwmon-vddra { + compatible = "iio-hwmon"; + io-channels = <&adc 11>; + }; + + iio-hwmon-battery { + compatible = "iio-hwmon"; + io-channels = <&adc 12>; + }; + + iio-hwmon-vddrb { + compatible = "iio-hwmon"; + io-channels = <&adc 13>; + }; +}; + +&pwm_tacho { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default + &pinctrl_pwm2_default &pinctrl_pwm3_default + &pinctrl_pwm4_default>; + + fan@0 { + reg = <0x00>; + aspeed,fan-tach-ch = /bits/ 8 <0x00>; + }; + + fan@1 { + reg = <0x01>; + aspeed,fan-tach-ch = /bits/ 8 <0x01>; + }; + + fan@2 { + reg = <0x02>; + aspeed,fan-tach-ch = /bits/ 8 <0x02>; + }; + + fan@3 { + reg = <0x03>; + aspeed,fan-tach-ch = /bits/ 8 <0x03>; + }; + + fan@4 { + reg = <0x04>; + aspeed,fan-tach-ch = /bits/ 8 <0x04>; + }; + + fan@5 { + reg = <0x00>; + aspeed,fan-tach-ch = /bits/ 8 <0x05>; + }; + + fan@6 { + reg = <0x01>; + aspeed,fan-tach-ch = /bits/ 8 <0x06>; + }; + + fan@7 { + reg = <0x02>; + aspeed,fan-tach-ch = /bits/ 8 <0x07>; + }; + + fan@8 { + reg = <0x03>; + aspeed,fan-tach-ch = /bits/ 8 <0x08>; + }; + + fan@9 { + reg = <0x04>; + aspeed,fan-tach-ch = /bits/ 8 <0x09>; + }; +}; + +&fmc { + status = "okay"; + flash@0 { + status = "okay"; + label = "bmc"; + m25p,fast-read; + spi-max-frequency = <50000000>; + partitions { + #address-cells = < 1 >; + #size-cells = < 1 >; + compatible = "fixed-partitions"; + u-boot@0 { + reg = < 0 0x60000 >; + label = "u-boot"; + }; + u-boot-env@60000 { + reg = < 0x60000 0x20000 >; + label = "u-boot-env"; + }; + obmc-ubi@80000 { + reg = < 0x80000 0x1F80000 >; + label = "obmc-ubi"; + }; + }; + }; + flash@1 { + status = "okay"; + label = "alt-bmc"; + m25p,fast-read; + spi-max-frequency = <50000000>; + partitions { + #address-cells = < 1 >; + #size-cells = < 1 >; + compatible = "fixed-partitions"; + u-boot@0 { + reg = < 0 0x60000 >; + label = "alt-u-boot"; + }; + u-boot-env@60000 { + reg = < 0x60000 0x20000 >; + label = "alt-u-boot-env"; + }; + obmc-ubi@80000 { + reg = < 0x80000 0x1F80000 >; + label = "alt-obmc-ubi"; + }; + }; + }; +}; + +&spi1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1_default>; + + flash@0 { + status = "okay"; + label = "pnor"; + m25p,fast-read; + spi-max-frequency = <100000000>; + }; +}; + +&lpc_ctrl { + status = "okay"; + memory-region = <&flash_memory>; + flash = <&spi1>; +}; + +&uart1 { + /* Rear RS-232 connector */ + 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 { + /* APSS */ + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_txd2_default &pinctrl_rxd2_default>; +}; + +&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"; + + tmp275@48 { + compatible = "ti,tmp275"; + reg = <0x48>; + }; +}; + +&i2c1 { + status = "disabled"; +}; + +&i2c2 { + status = "okay"; + + /* CPU MFG CONN */ + +}; + +&i2c3 { + status = "okay"; + + /* APSS */ + /* CPLD */ + + /* PCA9516 (repeater) -> + * CLK Buffer 9FGS9092 + * Power Supply 0 + * Power Supply 1 + * PCA 9552 LED + */ + + pca9552: pca9552@60 { + compatible = "nxp,pca9552"; + reg = <0x60>; + #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>; + }; + }; + + power-supply@68 { + compatible = "ibm,cffps1"; + reg = <0x68>; + }; + + power-supply@69 { + compatible = "ibm,cffps1"; + reg = <0x69>; + }; +}; + +&i2c4 { + status = "okay"; + + /* CP0 VDD & VCS : IR35221 */ + /* CP0 VDN & VIO : IR35221 */ + /* CP0 VDDR : IR35221 */ + + ir35221@28 { + compatible = "infineon,ir35221"; + reg = <0x28>; + }; + + ir35221@29 { + compatible = "infineon,ir35221"; + reg = <0x29>; + }; + + ir35221@2d { + compatible = "infineon,ir35221"; + reg = <0x2d>; + }; + +}; + +&i2c5 { + status = "disabled"; +}; + +&i2c6 { + status = "disabled"; +}; + +&i2c7 { + status = "disabled"; +}; + +&i2c8 { + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c64"; + reg = <0x50>; + }; +}; + +&i2c9 { + status = "okay"; + + /* PCIe G3 x16 slot */ +}; + +&i2c10 { + status = "disabled"; +}; + +&i2c11 { + status = "okay"; + + /* CPLD */ + /* TPM */ + /* RTC RX8900CE */ + /* TMP275A */ + /* TMP275A */ + + tmp275@48 { + compatible = "ti,tmp275"; + reg = <0x48>; + }; + + tmp275@49 { + compatible = "ti,tmp275"; + reg = <0x49>; + }; + +}; + +&i2c12 { + status = "disabled"; +}; + +&i2c13 { + status = "disabled"; +}; + +&vuart { + status = "okay"; +}; + +&gfx { + status = "okay"; + memory-region = <&gfx_memory>; +}; + +&adc { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adc0_default + &pinctrl_adc1_default + &pinctrl_adc2_default + &pinctrl_adc3_default + &pinctrl_adc4_default + &pinctrl_adc5_default + &pinctrl_adc6_default + &pinctrl_adc7_default + &pinctrl_adc8_default + &pinctrl_adc9_default + &pinctrl_adc10_default + &pinctrl_adc11_default + &pinctrl_adc12_default + &pinctrl_adc13_default + &pinctrl_adc14_default + &pinctrl_adc15_default>; +}; + +&wdt1 { + aspeed,reset-type = "none"; + aspeed,external-signal; + aspeed,ext-push-pull; + aspeed,ext-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdtrst1_default>; +}; + +&wdt2 { + aspeed,alt-boot; +}; + +&ibt { + status = "okay"; +}; + +&vhub { + status = "okay"; +}; + +&video { + status = "okay"; + memory-region = <&video_engine_memory>; +}; + +#include "ibm-power9-dual.dtsi" diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts b/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts index 5f4ee67ac787..4d070d6ba09f 100644 --- a/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts +++ b/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts @@ -4,6 +4,7 @@ #include "aspeed-g6.dtsi" #include <dt-bindings/gpio/aspeed-gpio.h> +#include <dt-bindings/i2c/i2c.h> #include <dt-bindings/leds/leds-pca955x.h> / { @@ -438,7 +439,13 @@ }; &i2c0 { + multi-master; status = "okay"; + + ibm-panel@62 { + compatible = "ibm,op-panel"; + reg = <(0x62 | I2C_OWN_SLAVE_ADDRESS)>; + }; }; &i2c1 { diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index 9c91afb2b404..a93009aa2f04 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -425,7 +425,6 @@ interrupts = <8>; clocks = <&syscon ASPEED_CLK_APB>; no-loopback-test; - aspeed,sirq-polarity-sense = <&syscon 0x70 25>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/ast2500-facebook-netbmc-common.dtsi b/arch/arm/boot/dts/ast2500-facebook-netbmc-common.dtsi index 7468f102bd76..c0c43b8644ee 100644 --- a/arch/arm/boot/dts/ast2500-facebook-netbmc-common.dtsi +++ b/arch/arm/boot/dts/ast2500-facebook-netbmc-common.dtsi @@ -47,25 +47,12 @@ status = "okay"; m25p,fast-read; label = "spi0.0"; - -#include "facebook-bmc-flash-layout.dtsi" }; fmc_flash1: 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"; - }; - }; }; }; diff --git a/arch/arm/boot/dts/at91-ariag25.dts b/arch/arm/boot/dts/at91-ariag25.dts index dbfefef2869d..713d18f80356 100644 --- a/arch/arm/boot/dts/at91-ariag25.dts +++ b/arch/arm/boot/dts/at91-ariag25.dts @@ -22,7 +22,7 @@ bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait"; }; - memory { + memory@20000000 { /* 128 MB, change this for 256 MB revision */ reg = <0x20000000 0x8000000>; }; @@ -93,6 +93,7 @@ pinctrl-0 = < &pinctrl_mmc0_slot0_clk_cmd_dat0 &pinctrl_mmc0_slot0_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@0 { diff --git a/arch/arm/boot/dts/at91-ariettag25.dts b/arch/arm/boot/dts/at91-ariettag25.dts index 0267e72c074a..2c52a71752c2 100644 --- a/arch/arm/boot/dts/at91-ariettag25.dts +++ b/arch/arm/boot/dts/at91-ariettag25.dts @@ -15,7 +15,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x8000000>; }; @@ -48,6 +48,7 @@ pinctrl-0 = < &pinctrl_mmc0_slot0_clk_cmd_dat0 &pinctrl_mmc0_slot0_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@0 { diff --git a/arch/arm/boot/dts/at91-cosino.dtsi b/arch/arm/boot/dts/at91-cosino.dtsi index feebd54f670e..ee0f5da6d819 100644 --- a/arch/arm/boot/dts/at91-cosino.dtsi +++ b/arch/arm/boot/dts/at91-cosino.dtsi @@ -20,7 +20,7 @@ bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait"; }; - memory { + memory@20000000 { reg = <0x20000000 0x8000000>; }; @@ -112,6 +112,7 @@ &pinctrl_board_mmc0 &pinctrl_mmc0_slot0_clk_cmd_dat0 &pinctrl_mmc0_slot0_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@0 { diff --git a/arch/arm/boot/dts/at91-cosino_mega2560.dts b/arch/arm/boot/dts/at91-cosino_mega2560.dts index 73e88d1ba4ed..04cb7bee937d 100644 --- a/arch/arm/boot/dts/at91-cosino_mega2560.dts +++ b/arch/arm/boot/dts/at91-cosino_mega2560.dts @@ -34,6 +34,7 @@ pinctrl-0 = < &pinctrl_mmc1_slot0_clk_cmd_dat0 &pinctrl_mmc1_slot0_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@0 { diff --git a/arch/arm/boot/dts/at91-foxg20.dts b/arch/arm/boot/dts/at91-foxg20.dts index 683b9e37f9c5..7edf057047f8 100644 --- a/arch/arm/boot/dts/at91-foxg20.dts +++ b/arch/arm/boot/dts/at91-foxg20.dts @@ -17,7 +17,7 @@ bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; @@ -55,6 +55,7 @@ &pinctrl_mmc0_clk &pinctrl_mmc0_slot1_cmd_dat0 &pinctrl_mmc0_slot1_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@1 { diff --git a/arch/arm/boot/dts/at91-kizbox.dts b/arch/arm/boot/dts/at91-kizbox.dts index 7d938ccf71b0..7add151f6250 100644 --- a/arch/arm/boot/dts/at91-kizbox.dts +++ b/arch/arm/boot/dts/at91-kizbox.dts @@ -18,7 +18,7 @@ stdout-path = &dbgu; }; - memory { + memory@20000000 { reg = <0x20000000 0x2000000>; }; diff --git a/arch/arm/boot/dts/at91-kizbox2-common.dtsi b/arch/arm/boot/dts/at91-kizbox2-common.dtsi index af38253a6e7a..25f761065106 100644 --- a/arch/arm/boot/dts/at91-kizbox2-common.dtsi +++ b/arch/arm/boot/dts/at91-kizbox2-common.dtsi @@ -17,7 +17,7 @@ stdout-path = &dbgu; }; - memory { + memory@20000000 { reg = <0x20000000 0x10000000>; }; diff --git a/arch/arm/boot/dts/at91-kizboxmini-common.dtsi b/arch/arm/boot/dts/at91-kizboxmini-common.dtsi index fddf267b2d17..d37724c10695 100644 --- a/arch/arm/boot/dts/at91-kizboxmini-common.dtsi +++ b/arch/arm/boot/dts/at91-kizboxmini-common.dtsi @@ -16,7 +16,7 @@ stdout-path = &dbgu; }; - memory { + memory@20000000 { reg = <0x20000000 0x8000000>; }; diff --git a/arch/arm/boot/dts/at91-linea.dtsi b/arch/arm/boot/dts/at91-linea.dtsi index 41f163955b1e..533a440d5583 100644 --- a/arch/arm/boot/dts/at91-linea.dtsi +++ b/arch/arm/boot/dts/at91-linea.dtsi @@ -13,7 +13,7 @@ compatible = "axentia,linea", "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5"; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; }; diff --git a/arch/arm/boot/dts/at91-qil_a9260.dts b/arch/arm/boot/dts/at91-qil_a9260.dts index a50b7fd2149f..969d990767fc 100644 --- a/arch/arm/boot/dts/at91-qil_a9260.dts +++ b/arch/arm/boot/dts/at91-qil_a9260.dts @@ -14,7 +14,7 @@ bootargs = "console=ttyS0,115200"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; @@ -52,6 +52,7 @@ &pinctrl_mmc0_clk &pinctrl_mmc0_slot0_cmd_dat0 &pinctrl_mmc0_slot0_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@0 { reg = <0>; diff --git a/arch/arm/boot/dts/at91-sam9_l9260.dts b/arch/arm/boot/dts/at91-sam9_l9260.dts index 954404ed8158..1e2a28c2f365 100644 --- a/arch/arm/boot/dts/at91-sam9_l9260.dts +++ b/arch/arm/boot/dts/at91-sam9_l9260.dts @@ -15,7 +15,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; @@ -49,6 +49,7 @@ &pinctrl_mmc0_clk &pinctrl_mmc0_slot1_cmd_dat0 &pinctrl_mmc0_slot1_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@1 { diff --git a/arch/arm/boot/dts/at91-sam9x60ek.dts b/arch/arm/boot/dts/at91-sam9x60ek.dts index ca15ff8fea18..eae28b82c7fd 100644 --- a/arch/arm/boot/dts/at91-sam9x60ek.dts +++ b/arch/arm/boot/dts/at91-sam9x60ek.dts @@ -563,6 +563,12 @@ atmel,pins = <AT91_PIOD 18 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; }; }; + + usb0 { + pinctrl_usba_vbus: usba_vbus { + atmel,pins = <AT91_PIOB 16 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; + }; + }; }; /* pinctrl */ &pmc { @@ -666,6 +672,13 @@ }; }; +&usb0 { + atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usba_vbus>; + status = "okay"; +}; + &usb1 { num-ports = <3>; atmel,vbus-gpio = <0 diff --git a/arch/arm/boot/dts/at91-sama5d2_icp.dts b/arch/arm/boot/dts/at91-sama5d2_icp.dts index 8d19925fc09e..6783cf16ff81 100644 --- a/arch/arm/boot/dts/at91-sama5d2_icp.dts +++ b/arch/arm/boot/dts/at91-sama5d2_icp.dts @@ -116,7 +116,6 @@ switch0: ksz8563@0 { compatible = "microchip,ksz8563"; reg = <0>; - phy-mode = "mii"; reset-gpios = <&pioA PIN_PD4 GPIO_ACTIVE_LOW>; spi-max-frequency = <500000>; @@ -140,6 +139,7 @@ reg = <2>; label = "cpu"; ethernet = <&macb0>; + phy-mode = "mii"; fixed-link { speed = <100>; full-duplex; diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts index 7abf555cd2fe..cf13632edd44 100644 --- a/arch/arm/boot/dts/at91-sama5d3_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts @@ -16,7 +16,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x10000000>; }; diff --git a/arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi b/arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi index 0be184a870eb..710cb72bda5a 100644 --- a/arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi +++ b/arch/arm/boot/dts/at91-sama5d4_ma5d4.dtsi @@ -9,7 +9,7 @@ model = "Aries/DENX MA5D4"; compatible = "aries,ma5d4", "denx,ma5d4", "atmel,sama5d4", "atmel,sama5"; - memory { + memory@20000000 { reg = <0x20000000 0x10000000>; }; diff --git a/arch/arm/boot/dts/at91-sama5d4_xplained.dts b/arch/arm/boot/dts/at91-sama5d4_xplained.dts index 924d9491780d..e5974a17374c 100644 --- a/arch/arm/boot/dts/at91-sama5d4_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d4_xplained.dts @@ -16,7 +16,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x20000000>; }; diff --git a/arch/arm/boot/dts/at91-sama5d4ek.dts b/arch/arm/boot/dts/at91-sama5d4ek.dts index 0cc1cff13e46..fe432b6b7e95 100644 --- a/arch/arm/boot/dts/at91-sama5d4ek.dts +++ b/arch/arm/boot/dts/at91-sama5d4ek.dts @@ -16,7 +16,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x20000000>; }; diff --git a/arch/arm/boot/dts/at91-som60.dtsi b/arch/arm/boot/dts/at91-som60.dtsi index 241682a207c5..39474a112b16 100644 --- a/arch/arm/boot/dts/at91-som60.dtsi +++ b/arch/arm/boot/dts/at91-som60.dtsi @@ -16,7 +16,7 @@ stdout-path = &dbgu; }; - memory { + memory@20000000 { reg = <0x20000000 0x8000000>; }; diff --git a/arch/arm/boot/dts/at91-vinco.dts b/arch/arm/boot/dts/at91-vinco.dts index 15050fdd479d..a51a3372afa1 100644 --- a/arch/arm/boot/dts/at91-vinco.dts +++ b/arch/arm/boot/dts/at91-vinco.dts @@ -17,7 +17,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; diff --git a/arch/arm/boot/dts/at91-wb45n.dtsi b/arch/arm/boot/dts/at91-wb45n.dtsi index ebe61a25ca96..430c75358086 100644 --- a/arch/arm/boot/dts/at91-wb45n.dtsi +++ b/arch/arm/boot/dts/at91-wb45n.dtsi @@ -17,7 +17,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; @@ -145,6 +145,7 @@ }; &mmc0 { + pinctrl-names = "default"; pinctrl-0 = < &pinctrl_mmc0_slot0_clk_cmd_dat0 &pinctrl_mmc0_slot0_dat1_3>; diff --git a/arch/arm/boot/dts/at91-wb50n.dtsi b/arch/arm/boot/dts/at91-wb50n.dtsi index 1487b893cfa7..74b249bb6351 100644 --- a/arch/arm/boot/dts/at91-wb50n.dtsi +++ b/arch/arm/boot/dts/at91-wb50n.dtsi @@ -17,7 +17,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; }; diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi index a5040f5ea641..d1181ead18e5 100644 --- a/arch/arm/boot/dts/at91rm9200.dtsi +++ b/arch/arm/boot/dts/at91rm9200.dtsi @@ -39,16 +39,17 @@ ssc2 = &ssc2; }; cpus { - #address-cells = <0>; + #address-cells = <1>; #size-cells = <0>; - cpu { + cpu@0 { compatible = "arm,arm920t"; device_type = "cpu"; + reg = <0>; }; }; - memory { + memory@20000000 { device_type = "memory"; reg = <0x20000000 0x04000000>; }; @@ -70,6 +71,9 @@ sram: sram@200000 { compatible = "mmio-sram"; reg = <0x00200000 0x4000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00200000 0x4000>; }; ahb { @@ -169,7 +173,6 @@ clock-names = "mci_clk"; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91rm9200ek.dts b/arch/arm/boot/dts/at91rm9200ek.dts index 1e0bf5afa913..e1ef4e44e663 100644 --- a/arch/arm/boot/dts/at91rm9200ek.dts +++ b/arch/arm/boot/dts/at91rm9200ek.dts @@ -15,7 +15,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 6afbb48e7ff0..82c5d7fd9811 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -36,16 +36,17 @@ ssc0 = &ssc0; }; cpus { - #address-cells = <0>; + #address-cells = <1>; #size-cells = <0>; - cpu { + cpu@0 { compatible = "arm,arm926ej-s"; device_type = "cpu"; + reg = <0>; }; }; - memory { + memory@20000000 { device_type = "memory"; reg = <0x20000000 0x04000000>; }; @@ -73,6 +74,9 @@ sram0: sram@2ff000 { compatible = "mmio-sram"; reg = <0x002ff000 0x2000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x002ff000 0x2000>; }; ahb { @@ -650,7 +654,6 @@ interrupts = <9 IRQ_TYPE_LEVEL_HIGH 0>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; clocks = <&pmc PMC_TYPE_PERIPHERAL 9>; clock-names = "mci_clk"; status = "disabled"; diff --git a/arch/arm/boot/dts/at91sam9260ek.dts b/arch/arm/boot/dts/at91sam9260ek.dts index 81f808a10931..d3446e42b598 100644 --- a/arch/arm/boot/dts/at91sam9260ek.dts +++ b/arch/arm/boot/dts/at91sam9260ek.dts @@ -16,7 +16,7 @@ stdout-path = &dbgu; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; @@ -55,6 +55,7 @@ &pinctrl_mmc0_clk &pinctrl_mmc0_slot1_cmd_dat0 &pinctrl_mmc0_slot1_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@1 { reg = <1>; diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi index 5ed3d745ac86..7adc36ca8a46 100644 --- a/arch/arm/boot/dts/at91sam9261.dtsi +++ b/arch/arm/boot/dts/at91sam9261.dtsi @@ -33,16 +33,17 @@ }; cpus { - #address-cells = <0>; + #address-cells = <1>; #size-cells = <0>; - cpu { + cpu@0 { compatible = "arm,arm926ej-s"; device_type = "cpu"; + reg = <0>; }; }; - memory { + memory@20000000 { device_type = "memory"; reg = <0x20000000 0x08000000>; }; @@ -64,6 +65,9 @@ sram: sram@300000 { compatible = "mmio-sram"; reg = <0x00300000 0x28000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00300000 0x28000>; }; ahb { diff --git a/arch/arm/boot/dts/at91sam9261ek.dts b/arch/arm/boot/dts/at91sam9261ek.dts index c4ef74fea97c..beed819609e8 100644 --- a/arch/arm/boot/dts/at91sam9261ek.dts +++ b/arch/arm/boot/dts/at91sam9261ek.dts @@ -16,7 +16,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 5c990cfae254..fe45d96239c9 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -35,16 +35,17 @@ }; cpus { - #address-cells = <0>; + #address-cells = <1>; #size-cells = <0>; - cpu { + cpu@0 { compatible = "arm,arm926ej-s"; device_type = "cpu"; + reg = <0>; }; }; - memory { + memory@20000000 { device_type = "memory"; reg = <0x20000000 0x08000000>; }; @@ -66,11 +67,17 @@ sram0: sram@300000 { compatible = "mmio-sram"; reg = <0x00300000 0x14000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00300000 0x14000>; }; sram1: sram@500000 { compatible = "mmio-sram"; reg = <0x00500000 0x4000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00500000 0x4000>; }; ahb { @@ -647,7 +654,6 @@ compatible = "atmel,hsmci"; reg = <0xfff80000 0x600>; interrupts = <10 IRQ_TYPE_LEVEL_HIGH 0>; - pinctrl-names = "default"; #address-cells = <1>; #size-cells = <0>; clocks = <&pmc PMC_TYPE_PERIPHERAL 10>; @@ -659,7 +665,6 @@ compatible = "atmel,hsmci"; reg = <0xfff84000 0x600>; interrupts = <11 IRQ_TYPE_LEVEL_HIGH 0>; - pinctrl-names = "default"; #address-cells = <1>; #size-cells = <0>; clocks = <&pmc PMC_TYPE_PERIPHERAL 11>; diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts index 62d218542a48..71f60576761a 100644 --- a/arch/arm/boot/dts/at91sam9263ek.dts +++ b/arch/arm/boot/dts/at91sam9263ek.dts @@ -16,7 +16,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; @@ -72,6 +72,7 @@ &pinctrl_mmc0_clk &pinctrl_mmc0_slot0_cmd_dat0 &pinctrl_mmc0_slot0_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@0 { reg = <0>; diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi index 4117cf880508..708e1646b7f4 100644 --- a/arch/arm/boot/dts/at91sam9g20.dtsi +++ b/arch/arm/boot/dts/at91sam9g20.dtsi @@ -11,7 +11,7 @@ model = "Atmel AT91SAM9G20 family SoC"; compatible = "atmel,at91sam9g20"; - memory { + memory@20000000 { reg = <0x20000000 0x08000000>; }; @@ -22,6 +22,9 @@ sram1: sram@2fc000 { compatible = "mmio-sram"; reg = <0x002fc000 0x8000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x002fc000 0x8000>; }; ahb { diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index bda22700110c..6e6e672c0b86 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @@ -13,7 +13,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; @@ -93,6 +93,7 @@ &pinctrl_mmc0_clk &pinctrl_mmc0_slot1_cmd_dat0 &pinctrl_mmc0_slot1_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@1 { reg = <1>; diff --git a/arch/arm/boot/dts/at91sam9g25-gardena-smart-gateway.dts b/arch/arm/boot/dts/at91sam9g25-gardena-smart-gateway.dts new file mode 100644 index 000000000000..7da70aeeb528 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9g25-gardena-smart-gateway.dts @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Device Tree file for the GARDENA smart Gateway (Article No. 19000) + * + * Copyright (C) 2020 GARDENA GmbH + */ + +/dts-v1/; + +#include "at91sam9g25.dtsi" +#include "at91sam9x5ek.dtsi" +#include <dt-bindings/input/input.h> + +/ { + model = "GARDENA smart Gateway (Article No. 19000)"; + compatible = "gardena,smart-gateway-at91sam", "atmel,at91sam9g25", "atmel,at91sam9x5", + "atmel,at91sam9"; + + aliases { + serial1 = &usart3; + }; + + gpio-keys { + compatible = "gpio-keys"; + + user_btn1 { + label = "USER_BTN1"; + gpios = <&pioA 24 GPIO_ACTIVE_LOW>; + linux,code = <KEY_PROG1>; + }; + }; + + 1wire_cm { + status = "disabled"; + }; + + leds { + compatible = "gpio-leds"; + + power_blue { + label = "smartgw:power:blue"; + gpios = <&pioC 21 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + power_green { + label = "smartgw:power:green"; + gpios = <&pioC 20 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + power_red { + label = "smartgw:power:red"; + gpios = <&pioC 19 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + radio_blue { + label = "smartgw:radio:blue"; + gpios = <&pioC 18 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + radio_green { + label = "smartgw:radio:green"; + gpios = <&pioC 17 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + radio_red { + label = "smartgw:radio:red"; + gpios = <&pioC 16 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + internet_blue { + label = "smartgw:internet:blue"; + gpios = <&pioC 15 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + internet_green { + label = "smartgw:internet:green"; + gpios = <&pioC 14 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + internet_red { + label = "smartgw:internet:red"; + gpios = <&pioC 13 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + heartbeat { + label = "smartgw:heartbeat"; + gpios = <&pioB 8 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + + pb18 { + status = "disabled"; + }; + + pd21 { + status = "disabled"; + }; + }; +}; + +&macb0 { + phy-mode = "rmii"; + status = "okay"; +}; + +&usart0 { + status = "disabled"; +}; + +&usart2 { + status = "disabled"; +}; + +&usart3 { + status = "okay"; + + pinctrl-0 = <&pinctrl_usart3 + &pinctrl_usart3_rts + &pinctrl_usart3_cts + >; +}; + +&watchdog { + status = "okay"; +}; + +&mmc0 { + status = "disabled"; +}; + +&mmc1 { + status = "disabled"; +}; + +&spi0 { + status = "disabled"; +}; + +&i2c0 { + status = "disabled"; +}; + +&adc0 { + status = "disabled"; +}; + +&ssc0 { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 1fbee2a7785f..19fc748a87c5 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -41,16 +41,17 @@ pwm0 = &pwm0; }; cpus { - #address-cells = <0>; + #address-cells = <1>; #size-cells = <0>; - cpu { + cpu@0 { compatible = "arm,arm926ej-s"; device_type = "cpu"; + reg = <0>; }; }; - memory { + memory@70000000 { device_type = "memory"; reg = <0x70000000 0x10000000>; }; @@ -78,6 +79,9 @@ sram: sram@300000 { compatible = "mmio-sram"; reg = <0x00300000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00300000 0x10000>; }; ahb { @@ -871,7 +875,6 @@ compatible = "atmel,hsmci"; reg = <0xfff80000 0x600>; interrupts = <11 IRQ_TYPE_LEVEL_HIGH 0>; - pinctrl-names = "default"; dmas = <&dma 1 AT91_DMA_CFG_PER_ID(0)>; dma-names = "rxtx"; #address-cells = <1>; @@ -885,7 +888,6 @@ compatible = "atmel,hsmci"; reg = <0xfffd0000 0x600>; interrupts = <29 IRQ_TYPE_LEVEL_HIGH 0>; - pinctrl-names = "default"; dmas = <&dma 1 AT91_DMA_CFG_PER_ID(13)>; dma-names = "rxtx"; #address-cells = <1>; diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index a3a5c82d9f29..9734667abbfc 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -18,7 +18,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@70000000 { reg = <0x70000000 0x4000000>; }; @@ -99,6 +99,7 @@ &pinctrl_board_mmc0 &pinctrl_mmc0_slot0_clk_cmd_dat0 &pinctrl_mmc0_slot0_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@0 { reg = <0>; @@ -112,6 +113,7 @@ &pinctrl_board_mmc1 &pinctrl_mmc1_slot0_clk_cmd_dat0 &pinctrl_mmc1_slot0_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@0 { reg = <0>; diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index a994d076dc7e..0785389f5507 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -37,16 +37,17 @@ pwm0 = &pwm0; }; cpus { - #address-cells = <0>; + #address-cells = <1>; #size-cells = <0>; - cpu { + cpu@0 { compatible = "arm,arm926ej-s"; device_type = "cpu"; + reg = <0>; }; }; - memory { + memory@20000000 { device_type = "memory"; reg = <0x20000000 0x10000000>; }; @@ -68,6 +69,9 @@ sram: sram@300000 { compatible = "mmio-sram"; reg = <0x00300000 0x8000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00300000 0x8000>; }; ahb { diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts index 870b83ff6b97..2bc4e6e0a923 100644 --- a/arch/arm/boot/dts/at91sam9n12ek.dts +++ b/arch/arm/boot/dts/at91sam9n12ek.dts @@ -17,7 +17,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x8000000>; }; diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi index 4d70194fd808..5653e70c84b4 100644 --- a/arch/arm/boot/dts/at91sam9rl.dtsi +++ b/arch/arm/boot/dts/at91sam9rl.dtsi @@ -38,16 +38,17 @@ }; cpus { - #address-cells = <0>; + #address-cells = <1>; #size-cells = <0>; - cpu { + cpu@0 { compatible = "arm,arm926ej-s"; device_type = "cpu"; + reg = <0>; }; }; - memory { + memory@20000000 { device_type = "memory"; reg = <0x20000000 0x04000000>; }; @@ -75,6 +76,9 @@ sram: sram@300000 { compatible = "mmio-sram"; reg = <0x00300000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00300000 0x10000>; }; ahb { diff --git a/arch/arm/boot/dts/at91sam9rlek.dts b/arch/arm/boot/dts/at91sam9rlek.dts index 0de75d3c4f18..1590862f16f2 100644 --- a/arch/arm/boot/dts/at91sam9rlek.dts +++ b/arch/arm/boot/dts/at91sam9rlek.dts @@ -17,7 +17,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 948fe99ab6c3..4cdb05079cc7 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -39,16 +39,17 @@ pwm0 = &pwm0; }; cpus { - #address-cells = <0>; + #address-cells = <1>; #size-cells = <0>; - cpu { + cpu@0 { compatible = "arm,arm926ej-s"; device_type = "cpu"; + reg = <0>; }; }; - memory { + memory@20000000 { device_type = "memory"; reg = <0x20000000 0x10000000>; }; @@ -76,6 +77,9 @@ sram: sram@300000 { compatible = "mmio-sram"; reg = <0x00300000 0x8000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00300000 0x8000>; }; ahb { @@ -647,7 +651,6 @@ interrupts = <12 IRQ_TYPE_LEVEL_HIGH 0>; dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(0)>; dma-names = "rxtx"; - pinctrl-names = "default"; clocks = <&pmc PMC_TYPE_PERIPHERAL 12>; clock-names = "mci_clk"; #address-cells = <1>; @@ -661,7 +664,6 @@ interrupts = <26 IRQ_TYPE_LEVEL_HIGH 0>; dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(0)>; dma-names = "rxtx"; - pinctrl-names = "default"; clocks = <&pmc PMC_TYPE_PERIPHERAL 26>; clock-names = "mci_clk"; #address-cells = <1>; diff --git a/arch/arm/boot/dts/at91sam9x5cm.dtsi b/arch/arm/boot/dts/at91sam9x5cm.dtsi index 75d2f7fd314f..cdd37f67280b 100644 --- a/arch/arm/boot/dts/at91sam9x5cm.dtsi +++ b/arch/arm/boot/dts/at91sam9x5cm.dtsi @@ -7,7 +7,7 @@ */ / { - memory { + memory@20000000 { reg = <0x20000000 0x8000000>; }; diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi index c934928742b0..6d1264de6060 100644 --- a/arch/arm/boot/dts/at91sam9x5ek.dtsi +++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi @@ -56,6 +56,7 @@ &pinctrl_board_mmc0 &pinctrl_mmc0_slot0_clk_cmd_dat0 &pinctrl_mmc0_slot0_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@0 { @@ -70,6 +71,7 @@ &pinctrl_board_mmc1 &pinctrl_mmc1_slot0_clk_cmd_dat0 &pinctrl_mmc1_slot0_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@0 { diff --git a/arch/arm/boot/dts/at91sam9xe.dtsi b/arch/arm/boot/dts/at91sam9xe.dtsi index 3f9d8caf8b0a..f571f77779c3 100644 --- a/arch/arm/boot/dts/at91sam9xe.dtsi +++ b/arch/arm/boot/dts/at91sam9xe.dtsi @@ -19,5 +19,8 @@ sram1: sram@300000 { compatible = "mmio-sram"; reg = <0x00300000 0x4000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00300000 0x4000>; }; }; diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi index 35bdd0969f0a..dacaef2c14ca 100644 --- a/arch/arm/boot/dts/bcm-cygnus.dtsi +++ b/arch/arm/boot/dts/bcm-cygnus.dtsi @@ -234,8 +234,8 @@ compatible = "arm,sp805" , "arm,primecell"; reg = <0x18009000 0x1000>; interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&axi81_clk>; - clock-names = "apb_pclk"; + clocks = <&axi81_clk>, <&axi81_clk>; + clock-names = "wdog_clk", "apb_pclk"; }; gpio_ccm: gpio@1800a000 { diff --git a/arch/arm/boot/dts/bcm-hr2.dtsi b/arch/arm/boot/dts/bcm-hr2.dtsi index cbebed5f050e..e8df458aad39 100644 --- a/arch/arm/boot/dts/bcm-hr2.dtsi +++ b/arch/arm/boot/dts/bcm-hr2.dtsi @@ -217,7 +217,7 @@ }; qspi: spi@27200 { - compatible = "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi"; + compatible = "brcm,spi-nsp-qspi", "brcm,spi-bcm-qspi"; reg = <0x027200 0x184>, <0x027000 0x124>, <0x11c408 0x004>, diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi index 0346ea621f0f..e895f7cb8c9f 100644 --- a/arch/arm/boot/dts/bcm-nsp.dtsi +++ b/arch/arm/boot/dts/bcm-nsp.dtsi @@ -284,7 +284,7 @@ }; qspi: spi@27200 { - compatible = "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi"; + compatible = "brcm,spi-nsp-qspi", "brcm,spi-bcm-qspi"; reg = <0x027200 0x184>, <0x027000 0x124>, <0x11c408 0x004>, @@ -368,7 +368,7 @@ }; ccbtimer0: timer@34000 { - compatible = "arm,sp804"; + compatible = "arm,sp804", "arm,primecell"; reg = <0x34000 0x1000>; interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; @@ -377,7 +377,7 @@ }; ccbtimer1: timer@35000 { - compatible = "arm,sp804"; + compatible = "arm,sp804", "arm,primecell"; reg = <0x35000 0x1000>; interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; @@ -438,7 +438,7 @@ reg = <0x39000 0x1000>; interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; clocks = <&iprocslow>, <&iprocslow>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; }; lcpll0: lcpll0@3f100 { diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts index 222d7825e1ab..09a1182c2936 100644 --- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts @@ -4,6 +4,8 @@ #include "bcm2835-rpi.dtsi" #include "bcm283x-rpi-usb-peripheral.dtsi" +#include <dt-bindings/reset/raspberrypi,firmware-reset.h> + / { compatible = "raspberrypi,4-model-b", "brcm,bcm2711"; model = "Raspberry Pi 4 Model B"; @@ -68,6 +70,14 @@ }; }; +&ddc0 { + status = "okay"; +}; + +&ddc1 { + status = "okay"; +}; + &firmware { firmware_clocks: clocks { compatible = "raspberrypi,firmware-clocks"; @@ -88,6 +98,11 @@ ""; status = "okay"; }; + + reset: reset { + compatible = "raspberrypi,firmware-reset"; + #reset-cells = <1>; + }; }; &gpio { @@ -163,6 +178,38 @@ "RGMII_TXD3"; }; +&hdmi0 { + clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>; + clock-names = "hdmi", "bvb", "audio", "cec"; + status = "okay"; +}; + +&hdmi1 { + clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>; + clock-names = "hdmi", "bvb", "audio", "cec"; + status = "okay"; +}; + +&hvs { + clocks = <&firmware_clocks 4>; +}; + +&pixelvalve0 { + status = "okay"; +}; + +&pixelvalve1 { + status = "okay"; +}; + +&pixelvalve2 { + status = "okay"; +}; + +&pixelvalve4 { + status = "okay"; +}; + &pwm1 { pinctrl-names = "default"; pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>; @@ -207,6 +254,21 @@ }; }; +&pcie0 { + pci@1,0 { + #address-cells = <3>; + #size-cells = <2>; + ranges; + + reg = <0 0 0 0 0>; + + usb@1,0 { + reg = <0x10000 0 0 0 0>; + resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>; + }; + }; +}; + /* uart0 communicates with the BT module */ &uart0 { pinctrl-names = "default"; @@ -231,3 +293,11 @@ &vchiq { interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; }; + +&vc4 { + status = "okay"; +}; + +&vec { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi index 00bcaed1be32..4847dd305317 100644 --- a/arch/arm/boot/dts/bcm2711.dtsi +++ b/arch/arm/boot/dts/bcm2711.dtsi @@ -12,6 +12,18 @@ interrupt-parent = <&gicv2>; + vc4: gpu { + compatible = "brcm,bcm2711-vc5"; + status = "disabled"; + }; + + clk_27MHz: clk-27M { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <27000000>; + clock-output-names = "27MHz-clock"; + }; + clk_108MHz: clk-108M { #clock-cells = <0>; compatible = "fixed-clock"; @@ -238,6 +250,27 @@ status = "disabled"; }; + pixelvalve0: pixelvalve@7e206000 { + compatible = "brcm,bcm2711-pixelvalve0"; + reg = <0x7e206000 0x100>; + interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + pixelvalve1: pixelvalve@7e207000 { + compatible = "brcm,bcm2711-pixelvalve1"; + reg = <0x7e207000 0x100>; + interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + pixelvalve2: pixelvalve@7e20a000 { + compatible = "brcm,bcm2711-pixelvalve2"; + reg = <0x7e20a000 0x100>; + interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + pwm1: pwm@7e20c800 { compatible = "brcm,bcm2835-pwm"; reg = <0x7e20c800 0x28>; @@ -248,10 +281,25 @@ status = "disabled"; }; - hvs@7e400000 { + pixelvalve4: pixelvalve@7e216000 { + compatible = "brcm,bcm2711-pixelvalve4"; + reg = <0x7e216000 0x100>; + interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + hvs: hvs@7e400000 { + compatible = "brcm,bcm2711-hvs"; interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; }; + pixelvalve3: pixelvalve@7ec12000 { + compatible = "brcm,bcm2711-pixelvalve3"; + reg = <0x7ec12000 0x100>; + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + dvp: clock@7ef00000 { compatible = "brcm,brcm2711-dvp"; reg = <0x7ef00000 0x10>; @@ -259,6 +307,78 @@ #clock-cells = <1>; #reset-cells = <1>; }; + + hdmi0: hdmi@7ef00700 { + compatible = "brcm,bcm2711-hdmi0"; + reg = <0x7ef00700 0x300>, + <0x7ef00300 0x200>, + <0x7ef00f00 0x80>, + <0x7ef00f80 0x80>, + <0x7ef01b00 0x200>, + <0x7ef01f00 0x400>, + <0x7ef00200 0x80>, + <0x7ef04300 0x100>, + <0x7ef20000 0x100>; + reg-names = "hdmi", + "dvp", + "phy", + "rm", + "packet", + "metadata", + "csc", + "cec", + "hd"; + clock-names = "hdmi", "bvb", "audio", "cec"; + resets = <&dvp 0>; + ddc = <&ddc0>; + dmas = <&dma 10>; + dma-names = "audio-rx"; + status = "disabled"; + }; + + ddc0: i2c@7ef04500 { + compatible = "brcm,bcm2711-hdmi-i2c"; + reg = <0x7ef04500 0x100>, <0x7ef00b00 0x300>; + reg-names = "bsc", "auto-i2c"; + clock-frequency = <97500>; + status = "disabled"; + }; + + hdmi1: hdmi@7ef05700 { + compatible = "brcm,bcm2711-hdmi1"; + reg = <0x7ef05700 0x300>, + <0x7ef05300 0x200>, + <0x7ef05f00 0x80>, + <0x7ef05f80 0x80>, + <0x7ef06b00 0x200>, + <0x7ef06f00 0x400>, + <0x7ef00280 0x80>, + <0x7ef09300 0x100>, + <0x7ef20000 0x100>; + reg-names = "hdmi", + "dvp", + "phy", + "rm", + "packet", + "metadata", + "csc", + "cec", + "hd"; + ddc = <&ddc1>; + clock-names = "hdmi", "bvb", "audio", "cec"; + resets = <&dvp 1>; + dmas = <&dma 17>; + dma-names = "audio-rx"; + status = "disabled"; + }; + + ddc1: i2c@7ef09500 { + compatible = "brcm,bcm2711-hdmi-i2c"; + reg = <0x7ef09500 0x100>, <0x7ef05b00 0x300>; + reg-names = "bsc", "auto-i2c"; + clock-frequency = <97500>; + status = "disabled"; + }; }; /* diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi index f7ae5a4530b8..d94357b21f7e 100644 --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi @@ -13,7 +13,7 @@ soc { firmware: firmware { - compatible = "raspberrypi,bcm2835-firmware", "simple-bus"; + compatible = "raspberrypi,bcm2835-firmware", "simple-mfd"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts new file mode 100644 index 000000000000..3b978dc8997a --- /dev/null +++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Broadcom BCM470X / BCM5301X ARM platform code. + * DTS for Meraki MR32 / Codename: Espresso + * + * Copyright (C) 2018-2020 Christian Lamparter <chunkeey@gmail.com> + */ + +/dts-v1/; + +#include "bcm4708.dtsi" +#include "bcm5301x-nand-cs0-bch8.dtsi" +#include <dt-bindings/leds/common.h> + +/ { + compatible = "meraki,mr32", "brcm,brcm53016", "brcm,bcm4708"; + model = "Meraki MR32"; + + chosen { + bootargs = " console=ttyS0,115200n8 earlycon"; + }; + + memory { + reg = <0x00000000 0x08000000>; + device_type = "memory"; + }; + + aliases { + serial1 = &uart2; + }; + + leds { + compatible = "gpio-leds"; + + sysled3 { + function = LED_FUNCTION_FAULT; + color = <LED_COLOR_ID_AMBER>; + gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>; + panic-indicator; + }; + sysled2 { + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_WHITE>; + gpios = <&chipcommon 19 GPIO_ACTIVE_HIGH>; + }; + }; + + keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + restart { + label = "Reset"; + linux,code = <KEY_RESTART>; + gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>; + }; + }; + + pwm-leds { + compatible = "pwm-leds"; + + red { + /* SYS-LED 1 - Tricolor */ + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_RED>; + pwms = <&pwm 0 50000 0>; + max-brightness = <255>; + }; + + green { + /* SYS-LED 1 - Tricolor */ + function = LED_FUNCTION_POWER; + color = <LED_COLOR_ID_GREEN>; + pwms = <&pwm 1 50000 0>; + max-brightness = <255>; + }; + + blue { + /* SYS-LED 1 - Tricolor */ + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_BLUE>; + pwms = <&pwm 2 50000 0>; + max-brightness = <255>; + }; + }; + + i2c { + /* + * The platform provided I2C does not budge. + * This is a replacement until I can figure + * out what are the missing bits... + */ + + compatible = "i2c-gpio"; + sda-gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>; + scl-gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>; + i2c-gpio,delay-us = <10>; /* close to 100 kHz */ + #address-cells = <1>; + #size-cells = <0>; + + current_sense: ina219@45 { + compatible = "ti,ina219"; + reg = <0x45>; + shunt-resistor = <60000>; /* = 60 mOhms */ + }; + + eeprom: eeprom@50 { + compatible = "atmel,24c64"; + reg = <0x50>; + pagesize = <32>; + read-only; + }; + }; +}; + +&uart0 { + clock-frequency = <62500000>; + /delete-property/ clocks; +}; + +&uart1 { + status = "disabled"; +}; + +&uart2 { + status = "okay"; + /* + * bluetooth-le { + * compatible = "brcm,bcm20732"; + * enable-gpios = <&chipcommon 20 GPIO_ACTIVE_HIGH>; + *}; + */ +}; + +&gmac1 { + status = "disabled"; +}; +&gmac2 { + status = "disabled"; +}; +&gmac3 { + status = "disabled"; +}; + +&pwm { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_pwm>; +}; + +&nandcs { + nand-ecc-algo = "hw"; + + partitions { + /* + * The partition autodetection does not work for this device. + * It will only detect the "nvram" partition with an incorrect size. + * [ 1.721667] 1 bcm47xxpart partitions found on MTD device brcmnand.0 + * [ 1.727962] Creating 1 MTD partitions on "brcmnand.0": + * [ 1.733117] 0x000000400000-0x000008000000 : "nvram" + */ + + compatible = "fixed-partitions"; + #address-cells = <0x1>; + #size-cells = <0x1>; + + partition0@0 { + label = "u-boot"; + reg = <0x0 0x100000>; + read-only; + }; + + partition1@100000 { + label = "bootkernel1"; + reg = <0x100000 0x300000>; + read-only; + }; + + partition2@400000 { + label = "nvram"; + reg = <0x400000 0x100000>; + read-only; + }; + + partition3@500000 { + label = "bootkernel2"; + reg = <0x500000 0x300000>; + read-only; + }; + + partition4@800000 { + label = "ubi"; + reg = <0x800000 0x7780000>; + }; + }; +}; diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi index 2d9b4dd05830..ac3a99cf2079 100644 --- a/arch/arm/boot/dts/bcm5301x.dtsi +++ b/arch/arm/boot/dts/bcm5301x.dtsi @@ -252,6 +252,10 @@ reg = <0x00013000 0x1000>; }; + pcie2: pcie@14000 { + reg = <0x00014000 0x1000>; + }; + usb2: usb2@21000 { reg = <0x00021000 0x1000>; @@ -350,6 +354,14 @@ }; }; + pwm: pwm@18002000 { + compatible = "brcm,iproc-pwm"; + reg = <0x18002000 0x28>; + clocks = <&osc>; + #pwm-cells = <3>; + status = "disabled"; + }; + mdio: mdio@18003000 { compatible = "brcm,iproc-mdio"; reg = <0x18003000 0x8>; @@ -384,6 +396,15 @@ reg = <0x18105000 0x1000>; }; + uart2: serial@18008000 { + compatible = "ns16550a"; + reg = <0x18008000 0x20>; + clocks = <&iprocslow>; + interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + status = "disabled"; + }; + i2c0: i2c@18009000 { compatible = "brcm,iproc-i2c"; reg = <0x18009000 0x50>; @@ -417,12 +438,12 @@ function = "spi"; }; - i2c { + pinmux_i2c: i2c { groups = "i2c_grp"; function = "i2c"; }; - pwm { + pinmux_pwm: pwm { groups = "pwm0_grp", "pwm1_grp", "pwm2_grp", "pwm3_grp"; function = "pwm"; @@ -488,7 +509,7 @@ }; spi@18029200 { - compatible = "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi"; + compatible = "brcm,spi-nsp-qspi", "brcm,spi-bcm-qspi"; reg = <0x18029200 0x184>, <0x18029000 0x124>, <0x1811b408 0x004>, diff --git a/arch/arm/boot/dts/bcm958525xmc.dts b/arch/arm/boot/dts/bcm958525xmc.dts index 716da62f5788..21f922dc6019 100644 --- a/arch/arm/boot/dts/bcm958525xmc.dts +++ b/arch/arm/boot/dts/bcm958525xmc.dts @@ -196,7 +196,7 @@ }; &sdio { - status = "ok"; + status = "okay"; }; &uart0 { diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts index 7b84b54436ed..7782b61c51a1 100644 --- a/arch/arm/boot/dts/bcm958625k.dts +++ b/arch/arm/boot/dts/bcm958625k.dts @@ -208,7 +208,7 @@ &sdio { bus-width = <4>; no-1-8-v; - status = "ok"; + status = "okay"; }; &srab { diff --git a/arch/arm/boot/dts/cros-ec-keyboard.dtsi b/arch/arm/boot/dts/cros-ec-keyboard.dtsi index 4a0c1037fbc0..165c5bcd510e 100644 --- a/arch/arm/boot/dts/cros-ec-keyboard.dtsi +++ b/arch/arm/boot/dts/cros-ec-keyboard.dtsi @@ -46,6 +46,7 @@ MATRIX_KEY(0x02, 0x09, KEY_F8) MATRIX_KEY(0x02, 0x0a, KEY_YEN) + MATRIX_KEY(0x03, 0x00, KEY_LEFTMETA) MATRIX_KEY(0x03, 0x01, KEY_GRAVE) MATRIX_KEY(0x03, 0x02, KEY_F2) MATRIX_KEY(0x03, 0x03, KEY_5) diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index a952d934fcf2..38530dbb89a0 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -537,24 +537,23 @@ ti,no-idle-on-init; }; -&mac { +&mac_sw { status = "okay"; - dual_emac; }; -&cpsw_emac0 { +&cpsw_port1 { phy-handle = <ðphy0>; phy-mode = "rgmii"; - dual_emac_res_vlan = <1>; + ti,dual-emac-pvid = <1>; }; -&cpsw_emac1 { +&cpsw_port2 { phy-handle = <ðphy1>; phy-mode = "rgmii"; - dual_emac_res_vlan = <2>; + ti,dual-emac-pvid = <2>; }; -&davinci_mdio { +&davinci_mdio_sw { ethphy0: ethernet-phy@2 { reg = <2>; }; @@ -565,7 +564,7 @@ }; &dcan1 { - status = "ok"; + status = "okay"; pinctrl-names = "default", "sleep", "active"; pinctrl-0 = <&dcan1_pins_sleep>; pinctrl-1 = <&dcan1_pins_sleep>; diff --git a/arch/arm/boot/dts/dra7-l4.dtsi b/arch/arm/boot/dts/dra7-l4.dtsi index 27a6a83cc60c..3bf90d9e3335 100644 --- a/arch/arm/boot/dts/dra7-l4.dtsi +++ b/arch/arm/boot/dts/dra7-l4.dtsi @@ -3038,60 +3038,6 @@ */ ti,no-idle; - mac: ethernet@0 { - compatible = "ti,dra7-cpsw","ti,cpsw"; - clocks = <&gmac_main_clk>, <&gmac_clkctrl DRA7_GMAC_GMAC_CLKCTRL 25>; - clock-names = "fck", "cpts"; - cpdma_channels = <8>; - ale_entries = <1024>; - bd_ram_size = <0x2000>; - mac_control = <0x20>; - slaves = <2>; - active_slave = <0>; - cpts_clock_mult = <0x784CFE14>; - cpts_clock_shift = <29>; - reg = <0x0 0x1000 - 0x1200 0x2e00>; - #address-cells = <1>; - #size-cells = <1>; - - /* - * rx_thresh_pend - * rx_pend - * tx_pend - * misc_pend - */ - interrupts = <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>; - ranges = <0 0 0x4000>; - syscon = <&scm_conf>; - status = "disabled"; - - davinci_mdio: mdio@1000 { - compatible = "ti,cpsw-mdio","ti,davinci_mdio"; - clocks = <&gmac_main_clk>; - clock-names = "fck"; - #address-cells = <1>; - #size-cells = <0>; - bus_freq = <1000000>; - reg = <0x1000 0x100>; - }; - - cpsw_emac0: slave@200 { - /* Filled in by U-Boot */ - mac-address = [ 00 00 00 00 00 00 ]; - phys = <&phy_gmii_sel 1>; - }; - - cpsw_emac1: slave@300 { - /* Filled in by U-Boot */ - mac-address = [ 00 00 00 00 00 00 ]; - phys = <&phy_gmii_sel 2>; - }; - }; - mac_sw: switch@0 { compatible = "ti,dra7-cpsw-switch","ti,cpsw-switch"; reg = <0x0 0x4000>; @@ -3561,7 +3507,6 @@ rtctarget: target-module@38000 { /* 0x48838000, ap 29 12.0 */ compatible = "ti,sysc-omap4-simple", "ti,sysc"; - ti,hwmods = "rtcss"; reg = <0x38074 0x4>, <0x38078 0x4>; reg-names = "rev", "sysc"; diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index cca6b123856f..4e1bbc0198eb 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -37,8 +37,8 @@ serial7 = &uart8; serial8 = &uart9; serial9 = &uart10; - ethernet0 = &cpsw_emac0; - ethernet1 = &cpsw_emac1; + ethernet0 = &cpsw_port1; + ethernet1 = &cpsw_port2; d_can0 = &dcan1; d_can1 = &dcan2; spi0 = &qspi; diff --git a/arch/arm/boot/dts/dra71-evm.dts b/arch/arm/boot/dts/dra71-evm.dts index 10da51bee42f..cad58f733bd6 100644 --- a/arch/arm/boot/dts/dra71-evm.dts +++ b/arch/arm/boot/dts/dra71-evm.dts @@ -219,26 +219,26 @@ vqmmc-supply = <&evm_1v8_sw>; }; -&mac { +&mac_sw { mode-gpios = <&pcf_gpio_21 4 GPIO_ACTIVE_LOW>, <&pcf_hdmi 9 GPIO_ACTIVE_LOW>, /* P11 */ <&pcf_hdmi 10 GPIO_ACTIVE_LOW>; /* P12 */ - dual_emac; + status = "okay"; }; -&cpsw_emac0 { +&cpsw_port1 { phy-handle = <&dp83867_0>; phy-mode = "rgmii-id"; - dual_emac_res_vlan = <1>; + ti,dual-emac-pvid = <1>; }; -&cpsw_emac1 { +&cpsw_port2 { phy-handle = <&dp83867_1>; phy-mode = "rgmii-id"; - dual_emac_res_vlan = <2>; + ti,dual-emac-pvid = <2>; }; -&davinci_mdio { +&davinci_mdio_sw { dp83867_0: ethernet-phy@2 { reg = <2>; ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>; diff --git a/arch/arm/boot/dts/dra72-evm-common.dtsi b/arch/arm/boot/dts/dra72-evm-common.dtsi index 9273a7d6fa29..b65b2dd094d0 100644 --- a/arch/arm/boot/dts/dra72-evm-common.dtsi +++ b/arch/arm/boot/dts/dra72-evm-common.dtsi @@ -462,12 +462,8 @@ }; }; -&mac { - status = "okay"; -}; - &dcan1 { - status = "ok"; + status = "okay"; pinctrl-names = "default", "sleep", "active"; pinctrl-0 = <&dcan1_pins_sleep>; pinctrl-1 = <&dcan1_pins_sleep>; @@ -536,11 +532,11 @@ }; &dss { - status = "ok"; + status = "okay"; }; &hdmi { - status = "ok"; + status = "okay"; port { hdmi_out: endpoint { diff --git a/arch/arm/boot/dts/dra72-evm-revc.dts b/arch/arm/boot/dts/dra72-evm-revc.dts index 54dab0f212d1..f242b937f88c 100644 --- a/arch/arm/boot/dts/dra72-evm-revc.dts +++ b/arch/arm/boot/dts/dra72-evm-revc.dts @@ -77,26 +77,26 @@ interrupts = <30 IRQ_TYPE_EDGE_FALLING>; }; -&mac { +&mac_sw { mode-gpios = <&pcf_gpio_21 4 GPIO_ACTIVE_LOW>, <&pcf_hdmi 9 GPIO_ACTIVE_LOW>, /* P11 */ <&pcf_hdmi 10 GPIO_ACTIVE_LOW>; /* P12 */ - dual_emac; + status = "okay"; }; -&cpsw_emac0 { +&cpsw_port1 { phy-handle = <&dp83867_0>; phy-mode = "rgmii-id"; - dual_emac_res_vlan = <1>; + ti,dual-emac-pvid = <1>; }; -&cpsw_emac1 { +&cpsw_port2 { phy-handle = <&dp83867_1>; phy-mode = "rgmii-id"; - dual_emac_res_vlan = <2>; + ti,dual-emac-pvid = <2>; }; -&davinci_mdio { +&davinci_mdio_sw { dp83867_0: ethernet-phy@2 { reg = <2>; ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>; diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts index 6ea9936f7d9c..5f62f92eb96c 100644 --- a/arch/arm/boot/dts/dra72-evm.dts +++ b/arch/arm/boot/dts/dra72-evm.dts @@ -69,17 +69,22 @@ interrupts = <11 IRQ_TYPE_EDGE_FALLING>; }; -&mac { - slaves = <1>; +&mac_sw { mode-gpios = <&pcf_gpio_21 4 GPIO_ACTIVE_HIGH>; + status = "okay"; }; -&cpsw_emac0 { +&cpsw_port1 { phy-handle = <ðphy0>; phy-mode = "rgmii"; + ti,dual-emac-pvid = <1>; +}; + +&cpsw_port2 { + status = "disabled"; }; -&davinci_mdio { +&davinci_mdio_sw { ethphy0: ethernet-phy@3 { reg = <3>; }; diff --git a/arch/arm/boot/dts/dra76-evm.dts b/arch/arm/boot/dts/dra76-evm.dts index 803981cc762e..9bd01ae40b1d 100644 --- a/arch/arm/boot/dts/dra76-evm.dts +++ b/arch/arm/boot/dts/dra76-evm.dts @@ -475,25 +475,23 @@ status = "disabled"; }; -&mac { +&mac_sw { status = "okay"; - - dual_emac; }; -&cpsw_emac0 { +&cpsw_port1 { phy-handle = <&dp83867_0>; phy-mode = "rgmii-id"; - dual_emac_res_vlan = <1>; + ti,dual-emac-pvid = <1>; }; -&cpsw_emac1 { +&cpsw_port2 { phy-handle = <&dp83867_1>; phy-mode = "rgmii-id"; - dual_emac_res_vlan = <2>; + ti,dual-emac-pvid = <2>; }; -&davinci_mdio { +&davinci_mdio_sw { dp83867_0: ethernet-phy@2 { reg = <2>; ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>; @@ -522,12 +520,12 @@ }; &dss { - status = "ok"; + status = "okay"; vdda_video-supply = <&ldo5_reg>; }; &hdmi { - status = "ok"; + status = "okay"; vdda-supply = <&ldo1_reg>; diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi index 96678ddbb4e6..ecfaa0b7523e 100644 --- a/arch/arm/boot/dts/emev2.dtsi +++ b/arch/arm/boot/dts/emev2.dtsi @@ -195,7 +195,7 @@ clock-names = "sclk"; }; - pfc: pin-controller@e0140200 { + pfc: pinctrl@e0140200 { compatible = "renesas,pfc-emev2"; reg = <0xe0140200 0x100>; }; diff --git a/arch/arm/boot/dts/ethernut5.dts b/arch/arm/boot/dts/ethernut5.dts index 052a52f947ce..ad7a0850252a 100644 --- a/arch/arm/boot/dts/ethernut5.dts +++ b/arch/arm/boot/dts/ethernut5.dts @@ -15,7 +15,7 @@ bootargs = "console=ttyS0,115200 root=/dev/mtdblock0 rw rootfstype=jffs2"; }; - memory { + memory@20000000 { reg = <0x20000000 0x08000000>; }; diff --git a/arch/arm/boot/dts/exynos3250-artik5.dtsi b/arch/arm/boot/dts/exynos3250-artik5.dtsi index 6c2f320be2f4..12887b3924af 100644 --- a/arch/arm/boot/dts/exynos3250-artik5.dtsi +++ b/arch/arm/boot/dts/exynos3250-artik5.dtsi @@ -55,6 +55,10 @@ assigned-clock-rates = <6000000>; }; +&cmu { + clocks = <&xusbxti>; +}; + &cpu0 { cpu0-supply = <&buck2_reg>; }; diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts index ca29d7ed8216..c1a68e612037 100644 --- a/arch/arm/boot/dts/exynos3250-monk.dts +++ b/arch/arm/boot/dts/exynos3250-monk.dts @@ -26,7 +26,7 @@ memory@40000000 { device_type = "memory"; - reg = <0x40000000 0x1ff00000>; + reg = <0x40000000 0x1ff00000>; }; firmware@205f000 { @@ -164,6 +164,10 @@ status = "okay"; }; +&cmu { + clocks = <&xusbxti>; +}; + &cpu0 { cpu0-supply = <&buck2_reg>; }; diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index aba8350cfdaf..b55afaaa691e 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -30,7 +30,7 @@ memory@40000000 { device_type = "memory"; - reg = <0x40000000 0x1ff00000>; + reg = <0x40000000 0x1ff00000>; }; firmware@205f000 { @@ -205,6 +205,10 @@ status = "okay"; }; +&cmu { + clocks = <&xusbxti>; +}; + &cpu0 { cpu0-supply = <&buck2_reg>; }; diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi index d3fb45a56527..a1e93fb7f694 100644 --- a/arch/arm/boot/dts/exynos3250.dtsi +++ b/arch/arm/boot/dts/exynos3250.dtsi @@ -97,33 +97,25 @@ }; }; - fixed-rate-clocks { - #address-cells = <1>; - #size-cells = <0>; - - xusbxti: clock@0 { - compatible = "fixed-clock"; - reg = <0>; - clock-frequency = <0>; - #clock-cells = <0>; - clock-output-names = "xusbxti"; - }; + xusbxti: clock-0 { + compatible = "fixed-clock"; + clock-frequency = <0>; + #clock-cells = <0>; + clock-output-names = "xusbxti"; + }; - xxti: clock@1 { - compatible = "fixed-clock"; - reg = <1>; - clock-frequency = <0>; - #clock-cells = <0>; - clock-output-names = "xxti"; - }; + xxti: clock-1 { + compatible = "fixed-clock"; + clock-frequency = <0>; + #clock-cells = <0>; + clock-output-names = "xxti"; + }; - xtcxo: clock@2 { - compatible = "fixed-clock"; - reg = <2>; - clock-frequency = <0>; - #clock-cells = <0>; - clock-output-names = "xtcxo"; - }; + xtcxo: clock-2 { + compatible = "fixed-clock"; + clock-frequency = <0>; + #clock-cells = <0>; + clock-output-names = "xtcxo"; }; pmu { @@ -362,7 +354,7 @@ }; hsotg: hsotg@12480000 { - compatible = "samsung,s3c6400-hsotg", "snps,dwc2"; + compatible = "samsung,s3c6400-hsotg"; reg = <0x12480000 0x20000>; interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cmu CLK_USBOTG>; diff --git a/arch/arm/boot/dts/exynos4210-i9100.dts b/arch/arm/boot/dts/exynos4210-i9100.dts index 6d0c04d77a39..5370ee477186 100644 --- a/arch/arm/boot/dts/exynos4210-i9100.dts +++ b/arch/arm/boot/dts/exynos4210-i9100.dts @@ -123,7 +123,7 @@ reset-gpios = <&gpl1 2 GPIO_ACTIVE_LOW>; }; - i2c_max17042_fuel: i2c-gpio { + i2c_max17042_fuel: i2c-gpio-0 { compatible = "i2c-gpio"; #address-cells = <1>; #size-cells = <0>; @@ -147,7 +147,7 @@ }; }; - spi-lcd { + spi-3 { compatible = "spi-gpio"; #address-cells = <1>; #size-cells = <0>; @@ -209,20 +209,12 @@ compatible = "samsung,clock-xusbxti"; clock-frequency = <24000000>; }; - }; - thermal-zones { - cpu_thermal: cpu-thermal { - cooling-maps { - map0 { - /* Corresponds to 800MHz */ - cooling-device = <&cpu0 2 2>; - }; - map1 { - /* Corresponds to 200MHz */ - cooling-device = <&cpu0 4 4>; - }; - }; + pmic_ap_clk: pmic-ap-clk { + /* Workaround for missing clock on max8997 PMIC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; }; }; }; @@ -235,6 +227,19 @@ cpu0-supply = <&varm_breg>; }; +&cpu_thermal { + cooling-maps { + map0 { + /* Corresponds to 800MHz */ + cooling-device = <&cpu0 2 2>; + }; + map1 { + /* Corresponds to 200MHz */ + cooling-device = <&cpu0 4 4>; + }; + }; +}; + &ehci { status = "okay"; @@ -304,8 +309,6 @@ status = "okay"; mali-supply = <&vg3d_breg>; - regulator-microvolt-offset = <50000>; - regulator-microsecs-delay = <50>; }; &hsotg { @@ -524,6 +527,7 @@ regulator-name = "G3D_1.1V"; regulator-min-microvolt = <900000>; regulator-max-microvolt = <1200000>; + regulator-microvolt-offset = <50000>; regulator-always-on; }; @@ -569,6 +573,16 @@ regulator-max-microvolt = <4100000>; regulator-always-on; }; + + EN32KHZ_AP { + regulator-name = "EN32KHZ_AP"; + regulator-always-on; + }; + + EN32KHZ_CP { + regulator-name = "EN32KHZ_CP"; + regulator-always-on; + }; }; }; }; @@ -667,7 +681,7 @@ samsung,pin-val = <0>; }; - mag_mhl_gpio: mag-mhl-gpio { + mag_mhl_gpio: mag-mhl { samsung,pins = "gpd0-2"; samsung,pin-function = <EXYNOS_PIN_FUNC_3>; samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; @@ -689,6 +703,12 @@ }; }; +&rtc { + status = "okay"; + clocks = <&clock CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; +}; + &sdhci_0 { status = "okay"; diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts index 890525b10d22..7d2cfbafefb2 100644 --- a/arch/arm/boot/dts/exynos4210-origen.dts +++ b/arch/arm/boot/dts/exynos4210-origen.dts @@ -100,6 +100,13 @@ compatible = "samsung,clock-xusbxti"; clock-frequency = <24000000>; }; + + pmic_ap_clk: pmic-ap-clk { + /* Workaround for missing clock on max8997 PMIC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; }; display-timings { @@ -122,6 +129,19 @@ cpu0-supply = <&buck1_reg>; }; +&cpu_thermal { + cooling-maps { + map0 { + /* Corresponds to 800MHz */ + cooling-device = <&cpu0 2 2>; + }; + map1 { + /* Corresponds to 200MHz */ + cooling-device = <&cpu0 4 4>; + }; + }; +}; + &exynos_usbphy { status = "okay"; }; @@ -286,6 +306,11 @@ regulator-boot-on; regulator-always-on; }; + + EN32KHZ_AP { + regulator-name = "EN32KHZ_AP"; + regulator-always-on; + }; }; }; }; @@ -331,6 +356,8 @@ &rtc { status = "okay"; + clocks = <&clock CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; }; &tmu { diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts index 77fc11e593ad..c5609afa6101 100644 --- a/arch/arm/boot/dts/exynos4210-smdkv310.dts +++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts @@ -40,6 +40,26 @@ compatible = "samsung,clock-xusbxti"; clock-frequency = <24000000>; }; + + pmic_ap_clk: pmic-ap-clk { + /* Workaround for missing clock on PMIC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; +}; + +&cpu_thermal { + cooling-maps { + map0 { + /* Corresponds to 800MHz */ + cooling-device = <&cpu0 2 2>; + }; + map1 { + /* Corresponds to 200MHz */ + cooling-device = <&cpu0 4 4>; + }; }; }; @@ -148,6 +168,11 @@ }; }; +&rtc { + clocks = <&clock CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; +}; + &sdhci_2 { bus-width = <4>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts index 5cc96f04a4fa..a226bec56a45 100644 --- a/arch/arm/boot/dts/exynos4210-trats.dts +++ b/arch/arm/boot/dts/exynos4210-trats.dts @@ -132,23 +132,14 @@ compatible = "samsung,clock-xusbxti"; clock-frequency = <24000000>; }; - }; - thermal-zones { - cpu_thermal: cpu-thermal { - cooling-maps { - map0 { - /* Corresponds to 800MHz at freq_table */ - cooling-device = <&cpu0 2 2>, <&cpu1 2 2>; - }; - map1 { - /* Corresponds to 200MHz at freq_table */ - cooling-device = <&cpu0 4 4>, <&cpu1 4 4>; - }; - }; + pmic_ap_clk: pmic-ap-clk { + /* Workaround for missing clock on max8997 PMIC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; }; }; - }; &camera { @@ -161,6 +152,19 @@ cpu0-supply = <&varm_breg>; }; +&cpu_thermal { + cooling-maps { + map0 { + /* Corresponds to 800MHz at freq_table */ + cooling-device = <&cpu0 2 2>, <&cpu1 2 2>; + }; + map1 { + /* Corresponds to 200MHz at freq_table */ + cooling-device = <&cpu0 4 4>, <&cpu1 4 4>; + }; + }; +}; + &dsi_0 { vddcore-supply = <&vusb_reg>; vddio-supply = <&vmipi_reg>; @@ -314,140 +318,156 @@ regulators { valive_reg: LDO2 { - regulator-name = "VALIVE_1.1V_C210"; - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; - regulator-always-on; + regulator-name = "VALIVE_1.1V_C210"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; }; vusb_reg: LDO3 { - regulator-name = "VUSB_1.1V_C210"; - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; + regulator-name = "VUSB_1.1V_C210"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; }; vmipi_reg: LDO4 { - regulator-name = "VMIPI_1.8V"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; + regulator-name = "VMIPI_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; }; vpda_reg: LDO6 { - regulator-name = "VCC_1.8V_PDA"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-always-on; + regulator-name = "VCC_1.8V_PDA"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; }; vcam_reg: LDO7 { - regulator-name = "CAM_ISP_1.8V"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; + regulator-name = "CAM_ISP_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; }; vusbdac_reg: LDO8 { - regulator-name = "VUSB+VDAC_3.3V_C210"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; + regulator-name = "VUSB+VDAC_3.3V_C210"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; }; vccpda_reg: LDO9 { - regulator-name = "VCC_2.8V_PDA"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - regulator-always-on; + regulator-name = "VCC_2.8V_PDA"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; }; vpll_reg: LDO10 { - regulator-name = "VPLL_1.1V_C210"; - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; - regulator-always-on; + regulator-name = "VPLL_1.1V_C210"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; }; vtcam_reg: LDO12 { - regulator-name = "VT_CAM_1.8V"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; + regulator-name = "VT_CAM_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; }; vcclcd_reg: LDO13 { - regulator-name = "VCC_3.3V_LCD"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; + regulator-name = "VCC_3.3V_LCD"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; }; vlcd_reg: LDO15 { - regulator-name = "VLCD_2.2V"; - regulator-min-microvolt = <2200000>; - regulator-max-microvolt = <2200000>; + regulator-name = "VLCD_2.2V"; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <2200000>; }; camsensor_reg: LDO16 { - regulator-name = "CAM_SENSOR_IO_1.8V"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; + regulator-name = "CAM_SENSOR_IO_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; }; tflash_reg: LDO17 { - regulator-name = "VTF_2.8V"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; + regulator-name = "VTF_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; }; vddq_reg: LDO21 { - regulator-name = "VDDQ_M1M2_1.2V"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-always-on; + regulator-name = "VDDQ_M1M2_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; }; varm_breg: BUCK1 { - regulator-name = "VARM_1.2V_C210"; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <1350000>; - regulator-always-on; + regulator-name = "VARM_1.2V_C210"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; }; vint_breg: BUCK2 { - regulator-name = "VINT_1.1V_C210"; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <1100000>; - regulator-always-on; + regulator-name = "VINT_1.1V_C210"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; }; camisp_breg: BUCK4 { - regulator-name = "CAM_ISP_CORE_1.2V"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; + regulator-name = "CAM_ISP_CORE_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; }; vmem_breg: BUCK5 { - regulator-name = "VMEM_1.2V_C210"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-always-on; + regulator-name = "VMEM_1.2V_C210"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; }; vccsub_breg: BUCK7 { - regulator-name = "VCC_SUB_2.0V"; - regulator-min-microvolt = <2000000>; - regulator-max-microvolt = <2000000>; - regulator-always-on; + regulator-name = "VCC_SUB_2.0V"; + regulator-min-microvolt = <2000000>; + regulator-max-microvolt = <2000000>; + regulator-always-on; }; safe1_sreg: ESAFEOUT1 { - regulator-name = "SAFEOUT1"; + regulator-name = "SAFEOUT1"; }; safe2_sreg: ESAFEOUT2 { - regulator-name = "SAFEOUT2"; - regulator-boot-on; + regulator-name = "SAFEOUT2"; + regulator-boot-on; + }; + + EN32KHZ_AP { + regulator-name = "EN32KHZ_AP"; + regulator-always-on; + }; + + EN32KHZ_CP { + regulator-name = "EN32KHZ_CP"; + regulator-always-on; }; }; }; }; +&rtc { + status = "okay"; + clocks = <&clock CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; +}; + &sdhci_0 { bus-width = <8>; non-removable; diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts index 99ce53b120ac..08284e8f3624 100644 --- a/arch/arm/boot/dts/exynos4210-universal_c210.dts +++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts @@ -39,10 +39,17 @@ compatible = "samsung,clock-xusbxti"; clock-frequency = <24000000>; }; + + pmic_ap_clk: pmic-ap-clk { + /* Workaround for missing clock on PMIC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; }; vemmc_reg: voltage-regulator { - compatible = "regulator-fixed"; + compatible = "regulator-fixed"; regulator-name = "VMEM_VDD_2_8V"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -104,7 +111,7 @@ }; tsp_reg: voltage-regulator { - compatible = "regulator-fixed"; + compatible = "regulator-fixed"; regulator-name = "TSP_2_8V"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -112,13 +119,13 @@ enable-active-high; }; - spi-lcd { + spi-3 { compatible = "spi-gpio"; #address-cells = <1>; #size-cells = <0>; - gpio-sck = <&gpy3 1 GPIO_ACTIVE_HIGH>; - gpio-mosi = <&gpy3 3 GPIO_ACTIVE_HIGH>; + sck-gpios = <&gpy3 1 GPIO_ACTIVE_HIGH>; + mosi-gpios = <&gpy3 3 GPIO_ACTIVE_HIGH>; num-chipselects = <1>; cs-gpios = <&gpy4 3 GPIO_ACTIVE_LOW>; @@ -192,6 +199,19 @@ cpu0-supply = <&vdd_arm_reg>; }; +&cpu_thermal { + cooling-maps { + map0 { + /* Corresponds to 800MHz */ + cooling-device = <&cpu0 2 2>; + }; + map1 { + /* Corresponds to 200MHz */ + cooling-device = <&cpu0 4 4>; + }; + }; +}; + &ehci { status = "okay"; phys = <&exynos_usbphy 1>; @@ -537,6 +557,12 @@ status = "okay"; }; +&rtc { + status = "okay"; + clocks = <&clock CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; +}; + &sdhci_0 { bus-width = <8>; non-removable; diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi index 33435ce79ce4..fddc661ded28 100644 --- a/arch/arm/boot/dts/exynos4210.dtsi +++ b/arch/arm/boot/dts/exynos4210.dtsi @@ -102,6 +102,8 @@ reg = <0x10502000 0x1000>; cache-unified; cache-level = <2>; + prefetch-data = <1>; + prefetch-instr = <1>; arm,tag-latency = <2 2 1>; arm,data-latency = <2 2 1>; }; @@ -363,26 +365,24 @@ }; }; }; +}; - thermal-zones { - cpu_thermal: cpu-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; - thermal-sensors = <&tmu 0>; - - trips { - cpu_alert0: cpu-alert-0 { - temperature = <85000>; /* millicelsius */ - }; - cpu_alert1: cpu-alert-1 { - temperature = <100000>; /* millicelsius */ - }; - cpu_alert2: cpu-alert-2 { - temperature = <110000>; /* millicelsius */ - }; - }; - }; - }; +&cpu_alert0 { + temperature = <85000>; /* millicelsius */ +}; + +&cpu_alert1 { + temperature = <100000>; /* millicelsius */ +}; + +&cpu_alert2 { + temperature = <110000>; /* millicelsius */ +}; + +&cpu_thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tmu 0>; }; &gic { diff --git a/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi b/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi index 53b3ca3effab..89ed81fb348d 100644 --- a/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi +++ b/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi @@ -33,7 +33,7 @@ }; }; - lcd_vdd3_reg: voltage-regulator-7 { + lcd_vdd3_reg: voltage-regulator-10 { compatible = "regulator-fixed"; regulator-name = "LCD_VDD_2.2V"; regulator-min-microvolt = <2200000>; @@ -42,7 +42,7 @@ enable-active-high; }; - ps_als_reg: voltage-regulator-8 { + ps_als_reg: voltage-regulator-11 { compatible = "regulator-fixed"; regulator-name = "LED_A_3.0V"; regulator-min-microvolt = <3000000>; @@ -171,6 +171,44 @@ status = "okay"; }; +&sound { + samsung,audio-routing = + "HP", "HPOUT1L", + "HP", "HPOUT1R", + + "SPK", "SPKOUTLN", + "SPK", "SPKOUTLP", + "SPK", "SPKOUTRN", + "SPK", "SPKOUTRP", + + "RCV", "HPOUT2N", + "RCV", "HPOUT2P", + + "HDMI", "LINEOUT1N", + "HDMI", "LINEOUT1P", + + "LINE", "LINEOUT2N", + "LINE", "LINEOUT2P", + + "IN1LP", "MICBIAS1", + "IN1LN", "MICBIAS1", + "Main Mic", "MICBIAS1", + + "IN1RP", "Sub Mic", + "IN1RN", "Sub Mic", + + "IN2LP:VXRN", "MICBIAS2", + "Headset Mic", "MICBIAS2", + + "IN2RN", "FM In", + "IN2RP:VXRP", "FM In"; +}; + +&submic_bias_reg { + gpio = <&gpf2 0 GPIO_ACTIVE_HIGH>; + enable-active-high; +}; + &touchkey_reg { gpio = <&gpm0 0 GPIO_ACTIVE_HIGH>; status = "okay"; diff --git a/arch/arm/boot/dts/exynos4412-i9300.dts b/arch/arm/boot/dts/exynos4412-i9300.dts index f8125a945f8d..07fbcf845c49 100644 --- a/arch/arm/boot/dts/exynos4412-i9300.dts +++ b/arch/arm/boot/dts/exynos4412-i9300.dts @@ -17,6 +17,10 @@ memory@40000000 { device_type = "memory"; - reg = <0x40000000 0x40000000>; + reg = <0x40000000 0x40000000>; }; }; + +&sound { + fm-sel-gpios = <&gpl0 3 GPIO_ACTIVE_HIGH>; +}; diff --git a/arch/arm/boot/dts/exynos4412-i9305.dts b/arch/arm/boot/dts/exynos4412-i9305.dts index 54a2a55dbf70..6bc3d897f432 100644 --- a/arch/arm/boot/dts/exynos4412-i9305.dts +++ b/arch/arm/boot/dts/exynos4412-i9305.dts @@ -10,7 +10,7 @@ memory@40000000 { device_type = "memory"; - reg = <0x40000000 0x80000000>; + reg = <0x40000000 0x80000000>; }; }; diff --git a/arch/arm/boot/dts/exynos4412-midas.dtsi b/arch/arm/boot/dts/exynos4412-midas.dtsi index 2c8111c6b065..7e7c243ff196 100644 --- a/arch/arm/boot/dts/exynos4412-midas.dtsi +++ b/arch/arm/boot/dts/exynos4412-midas.dtsi @@ -37,12 +37,12 @@ fixed-rate-clocks { xxti { - compatible = "samsung,clock-xxti", "fixed-clock"; + compatible = "samsung,clock-xxti"; clock-frequency = <0>; }; xusbxti { - compatible = "samsung,clock-xusbxti", "fixed-clock"; + compatible = "samsung,clock-xusbxti"; clock-frequency = <24000000>; }; }; @@ -102,6 +102,30 @@ status = "disabled"; }; + vbatt_reg: voltage-regulator-7 { + compatible = "regulator-fixed"; + regulator-name = "VBATT"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + mic_bias_reg: voltage-regulator-8 { + compatible = "regulator-fixed"; + regulator-name = "MICBIAS_LDO_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + gpio = <&gpf1 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + submic_bias_reg: voltage-regulator-9 { + compatible = "regulator-fixed"; + regulator-name = "SUB_MICBIAS_LDO_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + gpio-keys { compatible = "gpio-keys"; pinctrl-names = "default"; @@ -266,16 +290,18 @@ clock-names = "ext_clock"; }; - sound { - compatible = "samsung,trats2-audio"; - samsung,i2s-controller = <&i2s0>; - samsung,model = "Trats2"; - samsung,audio-codec = <&wm1811>; - samsung,audio-routing = - "SPK", "SPKOUTLN", - "SPK", "SPKOUTLP", - "SPK", "SPKOUTRN", - "SPK", "SPKOUTRP"; + sound: sound { + compatible = "samsung,midas-audio"; + model = "Midas"; + mic-bias-supply = <&mic_bias_reg>; + submic-bias-supply = <&submic_bias_reg>; + + cpu { + sound-dai = <&i2s0 0>; + }; + codec { + sound-dai = <&wm1811>; + }; }; thermistor-ap { @@ -293,25 +319,6 @@ pulldown-ohm = <100000>; /* 100K */ io-channels = <&adc 2>; /* Battery temperature */ }; - - thermal-zones { - cpu_thermal: 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>; - }; - }; - }; - }; }; &adc { @@ -380,6 +387,21 @@ 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>; + }; + }; +}; + &csis_0 { status = "okay"; vddcore-supply = <&ldo8_reg>; @@ -597,11 +619,37 @@ wm1811: wm1811@1a { compatible = "wlf,wm1811"; reg = <0x1a>; - clocks = <&pmu_system_controller 0>; - clock-names = "MCLK1"; - DCVDD-supply = <&ldo3_reg>; + clocks = <&pmu_system_controller 0>, + <&max77686 MAX77686_CLK_PMIC>; + clock-names = "MCLK1", "MCLK2"; + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&gpx3>; + interrupts = <6 IRQ_TYPE_LEVEL_HIGH>; + + gpio-controller; + #gpio-cells = <2>; + #sound-dai-cells = <0>; + + wlf,gpio-cfg = <0x3 0x0 0x0 0x0 0x0 0x0 + 0x0 0x8000 0x0 0x0 0x0>; + wlf,micbias-cfg = <0x2f 0x2b>; + + wlf,lineout1-feedback; + wlf,lineout1-se; + wlf,lineout2-se; + wlf,ldoena-always-driven; + + AVDD2-supply = <&vbatt_reg>; DBVDD1-supply = <&ldo3_reg>; + DBVDD2-supply = <&vbatt_reg>; + DBVDD3-supply = <&vbatt_reg>; + DCVDD-supply = <&ldo3_reg>; + CPVDD-supply = <&vbatt_reg>; + SPKVDD1-supply = <&vbatt_reg>; + SPKVDD2-supply = <&vbatt_reg>; wlf,ldo1ena = <&gpj0 4 0>; + wlf,ldo2ena = <&gpj0 4 0>; }; }; diff --git a/arch/arm/boot/dts/exynos4412-n710x.dts b/arch/arm/boot/dts/exynos4412-n710x.dts index 4189e1fb204c..a47b7f35fc80 100644 --- a/arch/arm/boot/dts/exynos4412-n710x.dts +++ b/arch/arm/boot/dts/exynos4412-n710x.dts @@ -8,12 +8,12 @@ memory@40000000 { device_type = "memory"; - reg = <0x40000000 0x80000000>; + reg = <0x40000000 0x80000000>; }; /* bootargs are passed in by bootloader */ - cam_vdda_reg: voltage-regulator-7 { + cam_vdda_reg: voltage-regulator-10 { compatible = "regulator-fixed"; regulator-name = "CAM_SENSOR_CORE_1.2V"; regulator-min-microvolt = <1200000>; @@ -74,6 +74,41 @@ status = "okay"; }; +&sound { + samsung,audio-routing = + "HP", "HPOUT1L", + "HP", "HPOUT1R", + + "SPK", "SPKOUTLN", + "SPK", "SPKOUTLP", + + "RCV", "HPOUT2N", + "RCV", "HPOUT2P", + + "HDMI", "LINEOUT1N", + "HDMI", "LINEOUT1P", + + "LINE", "LINEOUT2N", + "LINE", "LINEOUT2P", + + "IN1LP", "MICBIAS2", + "IN1LN", "MICBIAS2", + "Headset Mic", "MICBIAS2", + + "IN1RP", "Sub Mic", + "IN1RN", "Sub Mic", + + "IN2LP:VXRN", "Main Mic", + "IN2LN", "Main Mic", + + "IN2RN", "FM In", + "IN2RP:VXRP", "FM In"; +}; + +&submic_bias_reg { + regulator-always-on; +}; + &touchkey_reg { gpio = <&gpm0 5 GPIO_ACTIVE_HIGH>; status = "okay"; diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index a5c1ce1e396c..ab291cec650a 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -66,25 +66,6 @@ clock-frequency = <24000000>; }; }; - - thermal-zones { - cpu_thermal: cpu-thermal { - cooling-maps { - cooling_map0: map0 { - /* Corresponds to 800MHz at freq_table */ - cooling-device = <&cpu0 7 7>, <&cpu1 7 7>, - <&cpu2 7 7>, <&cpu3 7 7>; - }; - cooling_map1: map1 { - /* Corresponds to 200MHz at freq_table */ - cooling-device = <&cpu0 13 13>, - <&cpu1 13 13>, - <&cpu2 13 13>, - <&cpu3 13 13>; - }; - }; - }; - }; }; &bus_dmc { @@ -141,6 +122,7 @@ }; &clock { + clocks = <&clock CLK_XUSBXTI>; assigned-clocks = <&clock CLK_FOUT_EPLL>; assigned-clock-rates = <45158401>; }; @@ -174,6 +156,21 @@ }; }; +&cpu_thermal { + cooling-maps { + cooling_map0: map0 { + /* Corresponds to 800MHz at freq_table */ + cooling-device = <&cpu0 7 7>, <&cpu1 7 7>, + <&cpu2 7 7>, <&cpu3 7 7>; + }; + cooling_map1: map1 { + /* Corresponds to 200MHz at freq_table */ + cooling-device = <&cpu0 13 13>, <&cpu1 13 13>, + <&cpu2 13 13>, <&cpu3 13 13>; + }; + }; +}; + &pinctrl_1 { gpio_power_key: power_key { samsung,pins = "gpx1-3"; diff --git a/arch/arm/boot/dts/exynos4412-odroidu3.dts b/arch/arm/boot/dts/exynos4412-odroidu3.dts index 8ff243ba4542..b8549d846f86 100644 --- a/arch/arm/boot/dts/exynos4412-odroidu3.dts +++ b/arch/arm/boot/dts/exynos4412-odroidu3.dts @@ -37,31 +37,6 @@ #cooling-cells = <2>; cooling-levels = <0 102 170 230>; }; - - thermal-zones { - cpu_thermal: cpu-thermal { - cooling-maps { - map0 { - trip = <&cpu_alert1>; - cooling-device = <&cpu0 9 9>, <&cpu1 9 9>, - <&cpu2 9 9>, <&cpu3 9 9>, - <&fan0 1 2>; - }; - map1 { - trip = <&cpu_alert2>; - cooling-device = <&cpu0 15 15>, - <&cpu1 15 15>, - <&cpu2 15 15>, - <&cpu3 15 15>, - <&fan0 2 3>; - }; - map2 { - trip = <&cpu_alert0>; - cooling-device = <&fan0 0 1>; - }; - }; - }; - }; }; &adc { @@ -76,6 +51,27 @@ regulator-max-microvolt = <3300000>; }; +&cpu_thermal { + cooling-maps { + map0 { + trip = <&cpu_alert1>; + cooling-device = <&cpu0 9 9>, <&cpu1 9 9>, + <&cpu2 9 9>, <&cpu3 9 9>, + <&fan0 1 2>; + }; + map1 { + trip = <&cpu_alert2>; + cooling-device = <&cpu0 15 15>, <&cpu1 15 15>, + <&cpu2 15 15>, <&cpu3 15 15>, + <&fan0 2 3>; + }; + map2 { + trip = <&cpu_alert0>; + cooling-device = <&fan0 0 1>; + }; + }; +}; + &hdmicec { needs-hpd; }; diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts index 8b11ad391252..c2e793b69e7d 100644 --- a/arch/arm/boot/dts/exynos4412-origen.dts +++ b/arch/arm/boot/dts/exynos4412-origen.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "exynos4412.dtsi" +#include <dt-bindings/clock/samsung,s2mps11.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> #include "exynos-mfc-reserved-memory.dtsi" @@ -74,6 +75,21 @@ cpu0-supply = <&buck2_reg>; }; +&cpu_thermal { + cooling-maps { + cooling_map0: map0 { + /* Corresponds to 800MHz at freq_table */ + cooling-device = <&cpu0 7 7>, <&cpu1 7 7>, + <&cpu2 7 7>, <&cpu3 7 7>; + }; + cooling_map1: 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"; }; @@ -129,6 +145,13 @@ <1200000>, <1200000>, <1200000>, <1200000>; + s5m8767_osc: clocks { + compatible = "samsung,s5m8767-clk"; + #clock-cells = <1>; + clock-output-names = "s5m8767_ap", "s5m8767_cp", + "s5m8767_bt"; + }; + regulators { ldo1_reg: LDO1 { regulator-name = "VDD_ALIVE"; @@ -499,6 +522,8 @@ &rtc { status = "okay"; + clocks = <&clock CLK_RTC>, <&s5m8767_osc S2MPS11_CLK_AP>; + clock-names = "rtc", "rtc_src"; }; &sdhci_2 { diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts index e70fb6e601f0..49971203a8aa 100644 --- a/arch/arm/boot/dts/exynos4412-smdk4412.dts +++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts @@ -37,6 +37,28 @@ compatible = "samsung,clock-xusbxti"; clock-frequency = <24000000>; }; + + pmic_ap_clk: pmic-ap-clk { + /* Workaround for missing clock on PMIC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; +}; + +&cpu_thermal { + cooling-maps { + cooling_map0: map0 { + /* Corresponds to 800MHz at freq_table */ + cooling-device = <&cpu0 7 7>, <&cpu1 7 7>, + <&cpu2 7 7>, <&cpu3 7 7>; + }; + cooling_map1: map1 { + /* Corresponds to 200MHz at freq_table */ + cooling-device = <&cpu0 13 13>, <&cpu1 13 13>, + <&cpu2 13 13>, <&cpu3 13 13>; + }; }; }; @@ -127,6 +149,11 @@ }; }; +&rtc { + clocks = <&clock CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; +}; + &sdhci_2 { bus-width = <4>; pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>; diff --git a/arch/arm/boot/dts/exynos4412-tiny4412.dts b/arch/arm/boot/dts/exynos4412-tiny4412.dts index 3a91de8a8082..017b26108bb0 100644 --- a/arch/arm/boot/dts/exynos4412-tiny4412.dts +++ b/arch/arm/boot/dts/exynos4412-tiny4412.dts @@ -65,6 +65,13 @@ compatible = "samsung,clock-xusbxti"; clock-frequency = <24000000>; }; + + pmic_ap_clk: pmic-ap-clk { + /* Workaround for missing clock on PMIC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; }; panel { @@ -78,6 +85,21 @@ }; }; +&cpu_thermal { + cooling-maps { + cooling_map0: map0 { + /* Corresponds to 800MHz at freq_table */ + cooling-device = <&cpu0 7 7>, <&cpu1 7 7>, + <&cpu2 7 7>, <&cpu3 7 7>; + }; + cooling_map1: map1 { + /* Corresponds to 200MHz at freq_table */ + cooling-device = <&cpu0 13 13>, <&cpu1 13 13>, + <&cpu2 13 13>, <&cpu3 13 13>; + }; + }; +}; + &fimd { pinctrl-0 = <&lcd_clk>, <&lcd_data24>; pinctrl-names = "default"; @@ -95,6 +117,8 @@ &rtc { status = "okay"; + clocks = <&clock CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; }; &sdhci_2 { diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index aac533933c61..7b447b63007e 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -18,7 +18,7 @@ memory@40000000 { device_type = "memory"; - reg = <0x40000000 0x40000000>; + reg = <0x40000000 0x40000000>; }; chosen { diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi index 7002832eb4c0..e76881dc0014 100644 --- a/arch/arm/boot/dts/exynos4412.dtsi +++ b/arch/arm/boot/dts/exynos4412.dtsi @@ -76,7 +76,7 @@ }; }; - cpu0_opp_table: opp_table0 { + cpu0_opp_table: opp-table0 { compatible = "operating-points-v2"; opp-shared; @@ -218,6 +218,8 @@ reg = <0x10502000 0x1000>; cache-unified; cache-level = <2>; + prefetch-data = <1>; + prefetch-instr = <1>; arm,tag-latency = <2 2 1>; arm,data-latency = <3 2 1>; arm,double-linefill = <1>; @@ -400,7 +402,7 @@ status = "disabled"; }; - bus_dmc_opp_table: opp_table1 { + bus_dmc_opp_table: opp-table1 { compatible = "operating-points-v2"; opp-shared; @@ -427,7 +429,7 @@ }; }; - bus_acp_opp_table: opp_table2 { + bus_acp_opp_table: opp-table2 { compatible = "operating-points-v2"; opp-shared; @@ -493,7 +495,7 @@ status = "disabled"; }; - bus_leftbus_opp_table: opp_table3 { + bus_leftbus_opp_table: opp-table3 { compatible = "operating-points-v2"; opp-shared; @@ -516,7 +518,7 @@ }; }; - bus_display_opp_table: opp_table4 { + bus_display_opp_table: opp-table4 { compatible = "operating-points-v2"; opp-shared; @@ -528,7 +530,7 @@ }; }; - bus_fsys_opp_table: opp_table5 { + bus_fsys_opp_table: opp-table5 { compatible = "operating-points-v2"; opp-shared; @@ -540,7 +542,7 @@ }; }; - bus_peri_opp_table: opp_table6 { + bus_peri_opp_table: opp-table6 { compatible = "operating-points-v2"; opp-shared; @@ -732,7 +734,7 @@ "pmu"; 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/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi index 22eb951c614c..9ce9fb3fc190 100644 --- a/arch/arm/boot/dts/exynos5.dtsi +++ b/arch/arm/boot/dts/exynos5.dtsi @@ -86,7 +86,7 @@ }; gic: interrupt-controller@10481000 { - compatible = "arm,gic-400", "arm,cortex-a15-gic", "arm,cortex-a9-gic"; + compatible = "arm,gic-400", "arm,cortex-a15-gic"; #interrupt-cells = <3>; interrupt-controller; reg = <0x10481000 0x1000>, @@ -211,13 +211,13 @@ }; prng: rng@10830400 { - compatible = "samsung,exynos5250-prng"; - reg = <0x10830400 0x200>; + compatible = "samsung,exynos5250-prng"; + reg = <0x10830400 0x200>; }; trng: rng@10830600 { - compatible = "samsung,exynos5250-trng"; - reg = <0x10830600 0x100>; + compatible = "samsung,exynos5250-trng"; + reg = <0x10830600 0x100>; }; g2d: g2d@10850000 { diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index 59872d83da6e..79546f11af26 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -243,11 +243,11 @@ s5m8767,pmic-buck3-dvs-voltage = <1100000>; s5m8767,pmic-buck4-dvs-voltage = <1200000>; s5m8767,pmic-buck-dvs-gpios = <&gpd1 0 GPIO_ACTIVE_HIGH>, - <&gpd1 1 GPIO_ACTIVE_HIGH>, - <&gpd1 2 GPIO_ACTIVE_HIGH>; + <&gpd1 1 GPIO_ACTIVE_HIGH>, + <&gpd1 2 GPIO_ACTIVE_HIGH>; s5m8767,pmic-buck-ds-gpios = <&gpx2 3 GPIO_ACTIVE_HIGH>, - <&gpx2 4 GPIO_ACTIVE_HIGH>, - <&gpx2 5 GPIO_ACTIVE_HIGH>; + <&gpx2 4 GPIO_ACTIVE_HIGH>, + <&gpx2 5 GPIO_ACTIVE_HIGH>; s5m8767_osc: clocks { compatible = "samsung,s5m8767-clk"; @@ -542,12 +542,6 @@ status = "okay"; samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <40000>; - samsung,i2c-slave-addr = <0x38>; - - sata_phy_i2c:sata-phy@38 { - compatible = "samsung,exynos-sataphy-i2c"; - reg = <0x38>; - }; }; &i2s0 { @@ -619,12 +613,16 @@ samsung,exynos-sataphy-i2c-phandle = <&sata_phy_i2c>; }; +&sata_phy_i2c { + status = "okay"; +}; + &soc { /* * For unknown reasons HDMI-DDC does not work with Exynos I2C * controllers. Lets use software I2C over GPIO pins as a workaround. */ - i2c_ddc: i2c-gpio { + i2c_ddc: i2c-10 { pinctrl-names = "default"; pinctrl-0 = <&i2c2_gpio_bus>; status = "okay"; diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts index 5c42df024adf..186790f39e4d 100644 --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -7,6 +7,7 @@ */ /dts-v1/; +#include <dt-bindings/clock/maxim,max77686.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/irq.h> #include "exynos5250.dtsi" @@ -129,13 +130,14 @@ reg = <0x50>; }; - max77686@9 { + max77686: pmic@9 { compatible = "maxim,max77686"; reg = <0x09>; interrupt-parent = <&gpx3>; interrupts = <2 IRQ_TYPE_NONE>; pinctrl-names = "default"; pinctrl-0 = <&max77686_irq>; + #clock-cells = <1>; wakeup-source; voltage-regulators { @@ -324,12 +326,6 @@ status = "okay"; samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <40000>; - samsung,i2c-slave-addr = <0x38>; - - sata_phy_i2c: sata-phy@38 { - compatible = "samsung,exynos-sataphy-i2c"; - reg = <0x38>; - }; }; &i2s0 { @@ -368,6 +364,8 @@ &rtc { status = "okay"; + clocks = <&clock CLK_RTC>, <&max77686 MAX77686_CLK_AP>; + clock-names = "rtc", "rtc_src"; }; &sata { @@ -379,6 +377,10 @@ samsung,exynos-sataphy-i2c-phandle = <&sata_phy_i2c>; }; +&sata_phy_i2c { + status = "okay"; +}; + &spi_1 { status = "okay"; cs-gpios = <&gpa2 5 GPIO_ACTIVE_HIGH>; diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts index 3d501926c227..a92ade33779c 100644 --- a/arch/arm/boot/dts/exynos5250-spring.dts +++ b/arch/arm/boot/dts/exynos5250-spring.dts @@ -7,6 +7,7 @@ */ /dts-v1/; +#include <dt-bindings/clock/samsung,s2mps11.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/input/input.h> @@ -114,12 +115,12 @@ wakeup-source; s5m8767,pmic-buck-dvs-gpios = <&gpd1 0 GPIO_ACTIVE_LOW>, /* DVS1 */ - <&gpd1 1 GPIO_ACTIVE_LOW>, /* DVS2 */ - <&gpd1 2 GPIO_ACTIVE_LOW>; /* DVS3 */ + <&gpd1 1 GPIO_ACTIVE_LOW>, /* DVS2 */ + <&gpd1 2 GPIO_ACTIVE_LOW>; /* DVS3 */ s5m8767,pmic-buck-ds-gpios = <&gpx2 3 GPIO_ACTIVE_LOW>, /* SET1 */ - <&gpx2 4 GPIO_ACTIVE_LOW>, /* SET2 */ - <&gpx2 5 GPIO_ACTIVE_LOW>; /* SET3 */ + <&gpx2 4 GPIO_ACTIVE_LOW>, /* SET2 */ + <&gpx2 5 GPIO_ACTIVE_LOW>; /* SET3 */ /* * The following arrays of DVS voltages are not used, since we are @@ -127,26 +128,26 @@ * to please the driver. */ s5m8767,pmic-buck2-dvs-voltage = <1350000>, <1300000>, - <1250000>, <1200000>, - <1150000>, <1100000>, - <1000000>, <950000>; + <1250000>, <1200000>, + <1150000>, <1100000>, + <1000000>, <950000>; s5m8767,pmic-buck3-dvs-voltage = <1100000>, <1100000>, - <1100000>, <1100000>, - <1000000>, <1000000>, - <1000000>, <1000000>; + <1100000>, <1100000>, + <1000000>, <1000000>, + <1000000>, <1000000>; s5m8767,pmic-buck4-dvs-voltage = <1200000>, <1200000>, - <1200000>, <1200000>, - <1200000>, <1200000>, - <1200000>, <1200000>; + <1200000>, <1200000>, + <1200000>, <1200000>, + <1200000>, <1200000>; - clocks { + s5m8767_osc: clocks { compatible = "samsung,s5m8767-clk"; #clock-cells = <1>; clock-output-names = "en32khz_ap", - "en32khz_cp", - "en32khz_bt"; + "en32khz_cp", + "en32khz_bt"; }; regulators { @@ -456,7 +457,7 @@ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>; }; - dp_hpd_gpio: dp-hpd-gpio { + dp_hpd_gpio: dp-hpd { samsung,pins = "gpc3-0"; samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>; samsung,pin-pud = <EXYNOS_PIN_PULL_UP>; @@ -522,6 +523,12 @@ }; }; +&rtc { + status = "okay"; + clocks = <&clock CLK_RTC>, <&s5m8767_osc S2MPS11_CLK_AP>; + clock-names = "rtc", "rtc_src"; +}; + &sd1_bus4 { samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>; }; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index e3dbe4166836..bd2d8835dd36 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -330,7 +330,7 @@ power-domains = <&pd_g3d>; status = "disabled"; - gpu_opp_table: gpu-opp-table { + gpu_opp_table: opp-table { compatible = "operating-points-v2"; opp-100000000 { @@ -473,6 +473,12 @@ clocks = <&clock CLK_SATA_PHYI2C>; clock-names = "i2c"; status = "disabled"; + + sata_phy_i2c: sata-phy-i2c@38 { + compatible = "samsung,exynos-sataphy-i2c"; + reg = <0x38>; + status = "disabled"; + }; }; spi_0: spi@12d20000 { @@ -723,7 +729,7 @@ #dma-requests = <1>; }; - gsc_0: gsc@13e00000 { + gsc_0: gsc@13e00000 { compatible = "samsung,exynos5250-gsc", "samsung,exynos5-gsc"; reg = <0x13e00000 0x1000>; interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; @@ -733,7 +739,7 @@ iommus = <&sysmmu_gsc0>; }; - gsc_1: gsc@13e10000 { + gsc_1: gsc@13e10000 { compatible = "samsung,exynos5250-gsc", "samsung,exynos5-gsc"; reg = <0x13e10000 0x1000>; interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; @@ -743,7 +749,7 @@ iommus = <&sysmmu_gsc1>; }; - gsc_2: gsc@13e20000 { + gsc_2: gsc@13e20000 { compatible = "samsung,exynos5250-gsc", "samsung,exynos5-gsc"; reg = <0x13e20000 0x1000>; interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; @@ -753,7 +759,7 @@ iommus = <&sysmmu_gsc2>; }; - gsc_3: gsc@13e30000 { + gsc_3: gsc@13e30000 { compatible = "samsung,exynos5250-gsc", "samsung,exynos5-gsc"; reg = <0x13e30000 0x1000>; interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>; @@ -1085,26 +1091,6 @@ }; }; - thermal-zones { - cpu_thermal: cpu-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; - thermal-sensors = <&tmu 0>; - - cooling-maps { - map0 { - /* Corresponds to 800MHz at freq_table */ - cooling-device = <&cpu0 9 9>, <&cpu1 9 9>; - }; - map1 { - /* Corresponds to 200MHz at freq_table */ - cooling-device = <&cpu0 15 15>, - <&cpu1 15 15>; - }; - }; - }; - }; - timer { compatible = "arm,armv7-timer"; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, @@ -1120,6 +1106,24 @@ }; }; +&cpu_thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tmu 0>; + + cooling-maps { + map0 { + /* Corresponds to 800MHz at freq_table */ + cooling-device = <&cpu0 9 9>, <&cpu1 9 9>; + }; + map1 { + /* Corresponds to 200MHz at freq_table */ + cooling-device = <&cpu0 15 15>, + <&cpu1 15 15>; + }; + }; +}; + &dp { power-domains = <&pd_disp1>; clocks = <&clock CLK_DP>; diff --git a/arch/arm/boot/dts/exynos5260.dtsi b/arch/arm/boot/dts/exynos5260.dtsi index 154df70128f3..973448c4ad93 100644 --- a/arch/arm/boot/dts/exynos5260.dtsi +++ b/arch/arm/boot/dts/exynos5260.dtsi @@ -162,10 +162,8 @@ }; gic: interrupt-controller@10481000 { - compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; + compatible = "arm,gic-400", "arm,cortex-a15-gic"; #interrupt-cells = <3>; - #address-cells = <0>; - #size-cells = <0>; interrupt-controller; reg = <0x10481000 0x1000>, <0x10482000 0x2000>, diff --git a/arch/arm/boot/dts/exynos5410-odroidxu.dts b/arch/arm/boot/dts/exynos5410-odroidxu.dts index 4f9297ae0763..75b4150c26d7 100644 --- a/arch/arm/boot/dts/exynos5410-odroidxu.dts +++ b/arch/arm/boot/dts/exynos5410-odroidxu.dts @@ -109,10 +109,10 @@ assigned-clock-parents = <&clock CLK_FOUT_EPLL>, <&clock_audss EXYNOS_MOUT_AUDSS>; - assigned-clock-rates = <0>, - <0>, - <96000000>, - <19200000>; + assigned-clock-rates = <0>, + <0>, + <96000000>, + <19200000>; }; &cpu0_thermal { diff --git a/arch/arm/boot/dts/exynos5410-smdk5410.dts b/arch/arm/boot/dts/exynos5410-smdk5410.dts index 5282b5deca86..2a3ade77a2de 100644 --- a/arch/arm/boot/dts/exynos5410-smdk5410.dts +++ b/arch/arm/boot/dts/exynos5410-smdk5410.dts @@ -29,6 +29,13 @@ #clock-cells = <0>; }; + pmic_ap_clk: pmic-ap-clk { + /* Workaround for missing PMIC and its clock */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + firmware@2037000 { compatible = "samsung,secure-firmware"; reg = <0x02037000 0x1000>; @@ -79,6 +86,11 @@ }; }; +&rtc { + clocks = <&clock CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; +}; + &sromc { pinctrl-names = "default"; pinctrl-0 = <&srom_ctl>, <&srom_ebi>; diff --git a/arch/arm/boot/dts/exynos5410.dtsi b/arch/arm/boot/dts/exynos5410.dtsi index abe75b9e39f5..60a87684b1af 100644 --- a/arch/arm/boot/dts/exynos5410.dtsi +++ b/arch/arm/boot/dts/exynos5410.dtsi @@ -238,16 +238,16 @@ #include "exynos5420-trip-points.dtsi" }; cpu1_thermal: cpu1-thermal { - thermal-sensors = <&tmu_cpu1>; - #include "exynos5420-trip-points.dtsi" + thermal-sensors = <&tmu_cpu1>; + #include "exynos5420-trip-points.dtsi" }; cpu2_thermal: cpu2-thermal { - thermal-sensors = <&tmu_cpu2>; - #include "exynos5420-trip-points.dtsi" + thermal-sensors = <&tmu_cpu2>; + #include "exynos5420-trip-points.dtsi" }; cpu3_thermal: cpu3-thermal { - thermal-sensors = <&tmu_cpu3>; - #include "exynos5420-trip-points.dtsi" + thermal-sensors = <&tmu_cpu3>; + #include "exynos5420-trip-points.dtsi" }; }; }; diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts index 83fa800fa1eb..4e49d8095b29 100644 --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts @@ -9,6 +9,7 @@ /dts-v1/; #include "exynos5420.dtsi" #include "exynos5420-cpus.dtsi" +#include <dt-bindings/clock/samsung,s2mps11.h> #include <dt-bindings/gpio/gpio.h> / { @@ -401,6 +402,8 @@ &rtc { status = "okay"; + clocks = <&clock CLK_RTC>, <&s2mps11_osc S2MPS11_CLK_AP>; + clock-names = "rtc", "rtc_src"; }; &usbdrd_phy0 { diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index c76460b70532..83580f076a58 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -1199,20 +1199,20 @@ #include "exynos5420-trip-points.dtsi" }; cpu1_thermal: cpu1-thermal { - thermal-sensors = <&tmu_cpu1>; - #include "exynos5420-trip-points.dtsi" + thermal-sensors = <&tmu_cpu1>; + #include "exynos5420-trip-points.dtsi" }; cpu2_thermal: cpu2-thermal { - thermal-sensors = <&tmu_cpu2>; - #include "exynos5420-trip-points.dtsi" + thermal-sensors = <&tmu_cpu2>; + #include "exynos5420-trip-points.dtsi" }; cpu3_thermal: cpu3-thermal { - thermal-sensors = <&tmu_cpu3>; - #include "exynos5420-trip-points.dtsi" + thermal-sensors = <&tmu_cpu3>; + #include "exynos5420-trip-points.dtsi" }; gpu_thermal: gpu-thermal { - thermal-sensors = <&tmu_gpu>; - #include "exynos5420-trip-points.dtsi" + thermal-sensors = <&tmu_gpu>; + #include "exynos5420-trip-points.dtsi" }; }; }; diff --git a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi index afe090578e8f..b1cf9414ce17 100644 --- a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi @@ -333,8 +333,8 @@ compatible = "samsung,K3QF2F20DB", "jedec,lpddr3"; density = <16384>; io-width = <32>; - #address-cells = <1>; - #size-cells = <0>; + #address-cells = <1>; + #size-cells = <0>; tRFC-min-tck = <17>; tRRD-min-tck = <2>; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi index c3c2d85267da..b5ec4f47eb3a 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi @@ -29,30 +29,6 @@ "HiFi Playback", "Mixer DAI TX", "Mixer DAI RX", "HiFi Capture"; - assigned-clocks = <&clock CLK_MOUT_EPLL>, - <&clock CLK_MOUT_MAU_EPLL>, - <&clock CLK_MOUT_USER_MAU_EPLL>, - <&clock_audss EXYNOS_MOUT_AUDSS>, - <&clock_audss EXYNOS_MOUT_I2S>, - <&clock_audss EXYNOS_DOUT_SRP>, - <&clock_audss EXYNOS_DOUT_AUD_BUS>, - <&clock_audss EXYNOS_DOUT_I2S>; - - assigned-clock-parents = <&clock CLK_FOUT_EPLL>, - <&clock CLK_MOUT_EPLL>, - <&clock CLK_MOUT_MAU_EPLL>, - <&clock CLK_MAU_EPLL>, - <&clock_audss EXYNOS_MOUT_AUDSS>; - - assigned-clock-rates = <0>, - <0>, - <0>, - <0>, - <0>, - <196608001>, - <(196608002 / 2)>, - <196608000>; - cpu { sound-dai = <&i2s0 0>, <&i2s0 1>; }; @@ -62,13 +38,6 @@ }; }; -&clock_audss { - assigned-clocks = <&clock_audss EXYNOS_DOUT_SRP>, - <&clock CLK_FOUT_EPLL>; - assigned-clock-rates = <(196608000 / 256)>, - <196608000>; -}; - &hsi2c_5 { status = "okay"; max98090: max98090@10 { @@ -84,6 +53,31 @@ &i2s0 { status = "okay"; - assigned-clocks = <&i2s0 CLK_I2S_RCLK_SRC>; - assigned-clock-parents = <&clock_audss EXYNOS_SCLK_I2S>; + assigned-clocks = <&clock CLK_MOUT_EPLL>, + <&clock CLK_MOUT_MAU_EPLL>, + <&clock CLK_MOUT_USER_MAU_EPLL>, + <&clock_audss EXYNOS_MOUT_AUDSS>, + <&clock_audss EXYNOS_MOUT_I2S>, + <&i2s0 CLK_I2S_RCLK_SRC>, + <&clock_audss EXYNOS_DOUT_SRP>, + <&clock_audss EXYNOS_DOUT_AUD_BUS>, + <&clock_audss EXYNOS_DOUT_I2S>; + + assigned-clock-parents = <&clock CLK_FOUT_EPLL>, + <&clock CLK_MOUT_EPLL>, + <&clock CLK_MOUT_MAU_EPLL>, + <&clock CLK_MAU_EPLL>, + <&clock_audss EXYNOS_MOUT_AUDSS>, + <&clock_audss EXYNOS_SCLK_I2S>; + + assigned-clock-rates = <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <196608001>, + <(196608002 / 2)>, + <196608000>; + }; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu4.dts b/arch/arm/boot/dts/exynos5422-odroidxu4.dts index 892d389d6d09..ddd55d3bcadd 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu4.dts +++ b/arch/arm/boot/dts/exynos5422-odroidxu4.dts @@ -35,30 +35,6 @@ samsung,audio-routing = "I2S Playback", "Mixer DAI TX"; - assigned-clocks = <&clock CLK_MOUT_EPLL>, - <&clock CLK_MOUT_MAU_EPLL>, - <&clock CLK_MOUT_USER_MAU_EPLL>, - <&clock_audss EXYNOS_MOUT_AUDSS>, - <&clock_audss EXYNOS_MOUT_I2S>, - <&clock_audss EXYNOS_DOUT_SRP>, - <&clock_audss EXYNOS_DOUT_AUD_BUS>, - <&clock_audss EXYNOS_DOUT_I2S>; - - assigned-clock-parents = <&clock CLK_FOUT_EPLL>, - <&clock CLK_MOUT_EPLL>, - <&clock CLK_MOUT_MAU_EPLL>, - <&clock CLK_MAU_EPLL>, - <&clock_audss EXYNOS_MOUT_AUDSS>; - - assigned-clock-rates = <0>, - <0>, - <0>, - <0>, - <0>, - <196608001>, - <(196608002 / 2)>, - <196608000>; - cpu { sound-dai = <&i2s0 0>, <&i2s0 1>; }; @@ -69,17 +45,35 @@ }; }; -&clock_audss { - assigned-clocks = <&clock_audss EXYNOS_DOUT_SRP>, - <&clock CLK_FOUT_EPLL>; - assigned-clock-rates = <(196608000 / 256)>, - <196608000>; -}; - &i2s0 { status = "okay"; - assigned-clocks = <&i2s0 CLK_I2S_RCLK_SRC>; - assigned-clock-parents = <&clock_audss EXYNOS_SCLK_I2S>; + + assigned-clocks = <&clock CLK_MOUT_EPLL>, + <&clock CLK_MOUT_MAU_EPLL>, + <&clock CLK_MOUT_USER_MAU_EPLL>, + <&clock_audss EXYNOS_MOUT_AUDSS>, + <&clock_audss EXYNOS_MOUT_I2S>, + <&i2s0 CLK_I2S_RCLK_SRC>, + <&clock_audss EXYNOS_DOUT_SRP>, + <&clock_audss EXYNOS_DOUT_AUD_BUS>, + <&clock_audss EXYNOS_DOUT_I2S>; + + assigned-clock-parents = <&clock CLK_FOUT_EPLL>, + <&clock CLK_MOUT_EPLL>, + <&clock CLK_MOUT_MAU_EPLL>, + <&clock CLK_MAU_EPLL>, + <&clock_audss EXYNOS_MOUT_AUDSS>, + <&clock_audss EXYNOS_SCLK_I2S>; + + assigned-clock-rates = <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <196608001>, + <(196608002 / 2)>, + <196608000>; }; &pwm { diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi index f0af1bf2b4d8..f683440ee569 100644 --- a/arch/arm/boot/dts/hi3620.dtsi +++ b/arch/arm/boot/dts/hi3620.dtsi @@ -89,7 +89,7 @@ }; sysctrl: system-controller@802000 { - compatible = "hisilicon,sysctrl"; + compatible = "hisilicon,sysctrl", "syscon"; #address-cells = <1>; #size-cells = <1>; ranges = <0 0x802000 0x1000>; @@ -111,8 +111,10 @@ reg = <0x800000 0x1000>; /* timer00 & timer01 */ interrupts = <0 0 4>, <0 1 4>; - clocks = <&clock HI3620_TIMER0_MUX>, <&clock HI3620_TIMER1_MUX>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_TIMER0_MUX>, + <&clock HI3620_TIMER1_MUX>, + <&clock HI3620_TIMER0_MUX>; + clock-names = "timer0clk", "timer1clk", "apb_pclk"; status = "disabled"; }; @@ -121,8 +123,10 @@ reg = <0x801000 0x1000>; /* timer10 & timer11 */ interrupts = <0 2 4>, <0 3 4>; - clocks = <&clock HI3620_TIMER2_MUX>, <&clock HI3620_TIMER3_MUX>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_TIMER2_MUX>, + <&clock HI3620_TIMER3_MUX>, + <&clock HI3620_TIMER2_MUX>; + clock-names = "timer0clk", "timer1clk", "apb_pclk"; status = "disabled"; }; @@ -131,8 +135,10 @@ reg = <0xa01000 0x1000>; /* timer20 & timer21 */ interrupts = <0 4 4>, <0 5 4>; - clocks = <&clock HI3620_TIMER4_MUX>, <&clock HI3620_TIMER5_MUX>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_TIMER4_MUX>, + <&clock HI3620_TIMER5_MUX>, + <&clock HI3620_TIMER4_MUX>; + clock-names = "timer0lck", "timer1clk", "apb_pclk"; status = "disabled"; }; @@ -141,8 +147,10 @@ reg = <0xa02000 0x1000>; /* timer30 & timer31 */ interrupts = <0 6 4>, <0 7 4>; - clocks = <&clock HI3620_TIMER6_MUX>, <&clock HI3620_TIMER7_MUX>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_TIMER6_MUX>, + <&clock HI3620_TIMER7_MUX>, + <&clock HI3620_TIMER6_MUX>; + clock-names = "timer0clk", "timer1clk", "apb_pclk"; status = "disabled"; }; @@ -151,8 +159,10 @@ reg = <0xa03000 0x1000>; /* timer40 & timer41 */ interrupts = <0 96 4>, <0 97 4>; - clocks = <&clock HI3620_TIMER8_MUX>, <&clock HI3620_TIMER9_MUX>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_TIMER8_MUX>, + <&clock HI3620_TIMER9_MUX>, + <&clock HI3620_TIMER8_MUX>; + clock-names = "timer0clk", "timer1clk", "apb_pclk"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/hip04.dtsi b/arch/arm/boot/dts/hip04.dtsi index 4263a9339c2e..555bc6b6720f 100644 --- a/arch/arm/boot/dts/hip04.dtsi +++ b/arch/arm/boot/dts/hip04.dtsi @@ -213,7 +213,7 @@ }; sysctrl: sysctrl { - compatible = "hisilicon,sysctrl"; + compatible = "hisilicon,sysctrl", "syscon"; reg = <0x3e00000 0x00100000>; }; @@ -226,8 +226,8 @@ compatible = "arm,sp804", "arm,primecell"; reg = <0x3000000 0x1000>; interrupts = <0 224 4>; - clocks = <&clk_50m>, <&clk_50m>; - clock-names = "apb_pclk"; + clocks = <&clk_50m>, <&clk_50m>, <&clk_50m>; + clock-names = "timer0clk", "timer1clk", "apb_pclk"; }; arm-pmu { diff --git a/arch/arm/boot/dts/hisi-x5hd2.dtsi b/arch/arm/boot/dts/hisi-x5hd2.dtsi index 3ee7967c202d..e2dbf1d8a67b 100644 --- a/arch/arm/boot/dts/hisi-x5hd2.dtsi +++ b/arch/arm/boot/dts/hisi-x5hd2.dtsi @@ -370,8 +370,9 @@ arm,primecell-periphid = <0x00141805>; reg = <0xa2c000 0x1000>; interrupts = <0 29 4>; - clocks = <&clock HIX5HD2_WDG0_RST>; - clock-names = "apb_pclk"; + clocks = <&clock HIX5HD2_WDG0_RST>, + <&clock HIX5HD2_WDG0_RST>; + clock-names = "wdog_clk", "apb_pclk"; }; }; diff --git a/arch/arm/boot/dts/imx23-evk.dts b/arch/arm/boot/dts/imx23-evk.dts index 0b2701ca2921..8cbaf1c81174 100644 --- a/arch/arm/boot/dts/imx23-evk.dts +++ b/arch/arm/boot/dts/imx23-evk.dts @@ -53,7 +53,7 @@ apb@80000000 { apbh@80000000 { - gpmi-nand@8000c000 { + nand-controller@8000c000 { pinctrl-names = "default"; pinctrl-0 = <&gpmi_pins_a &gpmi_pins_fixup>; status = "okay"; diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi index 18289f6fb1f3..7f4c602454a5 100644 --- a/arch/arm/boot/dts/imx23.dtsi +++ b/arch/arm/boot/dts/imx23.dtsi @@ -76,7 +76,7 @@ status = "disabled"; }; - gpmi-nand@8000c000 { + nand-controller@8000c000 { compatible = "fsl,imx23-gpmi-nand"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx25-pinfunc.h b/arch/arm/boot/dts/imx25-pinfunc.h index 111bfdcbe552..f984b702efc5 100644 --- a/arch/arm/boot/dts/imx25-pinfunc.h +++ b/arch/arm/boot/dts/imx25-pinfunc.h @@ -87,6 +87,7 @@ #define MX25_PAD_EB1__EB1 0x044 0x25c 0x000 0x00 0x000 #define MX25_PAD_EB1__AUD4_RXD 0x044 0x25c 0x460 0x04 0x000 #define MX25_PAD_EB1__GPIO_2_13 0x044 0x25c 0x000 0x05 0x000 +#define MX25_PAD_EB1__CSPI3_SS1 0x044 0x25c 0x4c0 0x06 0x000 #define MX25_PAD_OE__OE 0x048 0x260 0x000 0x00 0x000 #define MX25_PAD_OE__AUD4_TXC 0x048 0x260 0x000 0x04 0x000 @@ -112,6 +113,7 @@ #define MX25_PAD_CS5__CSPI3_MISO 0x058 0x268 0x4b4 0x06 0x000 #define MX25_PAD_NF_CE0__NF_CE0 0x05c 0x26c 0x000 0x00 0x000 +#define MX25_PAD_NF_CE0__CSPI1_SS3 0x05c 0x26c 0x490 0x01 0x000 #define MX25_PAD_NF_CE0__GPIO_3_22 0x05c 0x26c 0x000 0x05 0x000 #define MX25_PAD_ECB__ECB 0x060 0x270 0x000 0x00 0x000 @@ -122,6 +124,7 @@ #define MX25_PAD_LBA__LBA 0x064 0x274 0x000 0x00 0x000 #define MX25_PAD_LBA__UART5_RXD 0x064 0x274 0x578 0x03 0x000 #define MX25_PAD_LBA__GPIO_3_24 0x064 0x274 0x000 0x05 0x000 +#define MX25_PAD_LBA__CSPI3_RDY 0x064 0x274 0x4b0 0x06 0x000 #define MX25_PAD_BCLK__BCLK 0x068 0x000 0x000 0x00 0x000 #define MX25_PAD_BCLK__GPIO_4_4 0x068 0x000 0x000 0x05 0x000 @@ -285,7 +288,8 @@ #define MX25_PAD_OE_ACD__GPIO_1_25 0x114 0x30c 0x000 0x05 0x000 #define MX25_PAD_CONTRAST__CONTRAST 0x118 0x310 0x000 0x00 0x000 -#define MX25_PAD_CONTRAST__CC4 0x118 0x310 0x000 0x01 0x000 +#define MX25_PAD_CONTRAST__GPT4_CAPIN1 0x118 0x310 0x000 0x01 0x000 +#define MX25_PAD_CONTRAST__CSPI2_SS1 0x118 0x310 0x4a8 0x02 0x000 #define MX25_PAD_CONTRAST__PWM4_PWMO 0x118 0x310 0x000 0x04 0x000 #define MX25_PAD_CONTRAST__FEC_CRS 0x118 0x310 0x508 0x05 0x001 #define MX25_PAD_CONTRAST__USBH2_PWR 0x118 0x310 0x000 0x06 0x000 @@ -298,7 +302,7 @@ #define MX25_PAD_CSI_D2__UART5_RXD 0x120 0x318 0x578 0x01 0x001 #define MX25_PAD_CSI_D2__SIM1_CLK0 0x120 0x318 0x000 0x04 0x000 #define MX25_PAD_CSI_D2__GPIO_1_27 0x120 0x318 0x000 0x05 0x000 -#define MX25_PAD_CSI_D2__CSPI3_MOSI 0x120 0x318 0x000 0x07 0x000 +#define MX25_PAD_CSI_D2__CSPI3_MOSI 0x120 0x318 0x4b8 0x07 0x001 #define MX25_PAD_CSI_D3__CSI_D3 0x124 0x31c 0x000 0x00 0x000 #define MX25_PAD_CSI_D3__UART5_TXD 0x124 0x31c 0x000 0x01 0x000 @@ -310,23 +314,25 @@ #define MX25_PAD_CSI_D4__UART5_RTS 0x128 0x320 0x574 0x01 0x001 #define MX25_PAD_CSI_D4__SIM1_VEN0 0x128 0x320 0x000 0x04 0x000 #define MX25_PAD_CSI_D4__GPIO_1_29 0x128 0x320 0x000 0x05 0x000 -#define MX25_PAD_CSI_D4__CSPI3_SCLK 0x128 0x320 0x000 0x07 0x000 +#define MX25_PAD_CSI_D4__CSPI3_SCLK 0x128 0x320 0x4ac 0x07 0x001 #define MX25_PAD_CSI_D5__CSI_D5 0x12c 0x324 0x000 0x00 0x000 #define MX25_PAD_CSI_D5__UART5_CTS 0x12c 0x324 0x000 0x01 0x000 #define MX25_PAD_CSI_D5__SIM1_TX0 0x12c 0x324 0x000 0x04 0x000 #define MX25_PAD_CSI_D5__GPIO_1_30 0x12c 0x324 0x000 0x05 0x000 -#define MX25_PAD_CSI_D5__CSPI3_RDY 0x12c 0x324 0x000 0x07 0x000 +#define MX25_PAD_CSI_D5__CSPI3_RDY 0x12c 0x324 0x4b0 0x07 0x001 #define MX25_PAD_CSI_D6__CSI_D6 0x130 0x328 0x000 0x00 0x000 /* SION must be set; see the comment for MX25_PAD_SD1_CMD__ESDHC1_CMD. */ #define MX25_PAD_CSI_D6__ESDHC2_CMD 0x130 0x328 0x4e0 0x12 0x001 #define MX25_PAD_CSI_D6__SIM1_PD0 0x130 0x328 0x000 0x04 0x000 #define MX25_PAD_CSI_D6__GPIO_1_31 0x130 0x328 0x000 0x05 0x000 +#define MX25_PAD_CSI_D6__CSPI3_SS0 0x130 0x328 0x4bc 0x07 0x001 #define MX25_PAD_CSI_D7__CSI_D7 0x134 0x32c 0x000 0x00 0x000 #define MX25_PAD_CSI_D7__ESDHC2_CLK 0x134 0x32C 0x4dc 0x02 0x001 #define MX25_PAD_CSI_D7__GPIO_1_6 0x134 0x32c 0x000 0x05 0x000 +#define MX25_PAD_CSI_D7__CSPI3_SS1 0x134 0x32c 0x4c0 0x07 0x001 #define MX25_PAD_CSI_D8__CSI_D8 0x138 0x330 0x000 0x00 0x000 #define MX25_PAD_CSI_D8__AUD6_RXC 0x138 0x330 0x000 0x02 0x000 @@ -398,7 +404,7 @@ #define MX25_PAD_UART1_RTS__UART1_RTS 0x178 0x370 0x000 0x00 0x000 #define MX25_PAD_UART1_RTS__CSI_D0 0x178 0x370 0x488 0x01 0x001 -#define MX25_PAD_UART1_RTS__CC3 0x178 0x370 0x000 0x02 0x000 +#define MX25_PAD_UART1_RTS__GPT3_CAPIN1 0x178 0x370 0x000 0x02 0x000 #define MX25_PAD_UART1_RTS__UART2_DCD 0x178 0x370 0x000 0x03 0x000 #define MX25_PAD_UART1_RTS__GPIO_4_24 0x178 0x370 0x000 0x05 0x000 @@ -415,12 +421,14 @@ #define MX25_PAD_UART2_RTS__UART2_RTS 0x188 0x380 0x000 0x00 0x000 #define MX25_PAD_UART2_RTS__FEC_COL 0x188 0x380 0x504 0x02 0x002 -#define MX25_PAD_UART2_RTS__CC1 0x188 0x380 0x000 0x03 0x000 +#define MX25_PAD_UART2_RTS__GPT1_CAPIN1 0x188 0x380 0x000 0x03 0x000 #define MX25_PAD_UART2_RTS__GPIO_4_28 0x188 0x380 0x000 0x05 0x000 +#define MX25_PAD_UART2_RTS__CSPI2_SS3 0x188 0x380 0x000 0x06 0x000 #define MX25_PAD_UART2_CTS__UART2_CTS 0x18c 0x384 0x000 0x00 0x000 #define MX25_PAD_UART2_CTS__FEC_RX_ERR 0x18c 0x384 0x518 0x02 0x002 #define MX25_PAD_UART2_CTS__GPIO_4_29 0x18c 0x384 0x000 0x05 0x000 +#define MX25_PAD_UART2_CTS__CSPI3_SS3 0x18c 0x384 0x4c8 0x06 0x001 /* * Removing the SION bit from MX25_PAD_*__ESDHCn_CMD breaks detecting an SD @@ -446,14 +454,17 @@ #define MX25_PAD_SD1_DATA0__GPIO_2_25 0x198 0x390 0x000 0x05 0x000 #define MX25_PAD_SD1_DATA1__ESDHC1_DAT1 0x19c 0x394 0x000 0x00 0x000 +#define MX25_PAD_SD1_DATA1__CSPI2_RDY 0x19c 0x394 0x498 0x01 0x001 #define MX25_PAD_SD1_DATA1__AUD7_RXD 0x19c 0x394 0x478 0x03 0x000 #define MX25_PAD_SD1_DATA1__GPIO_2_26 0x19c 0x394 0x000 0x05 0x000 #define MX25_PAD_SD1_DATA2__ESDHC1_DAT2 0x1a0 0x398 0x000 0x00 0x000 +#define MX25_PAD_SD1_DATA2__CSPI2_SS0 0x1a0 0x398 0x4a4 0x01 0x001 #define MX25_PAD_SD1_DATA2__FEC_RX_CLK 0x1a0 0x398 0x514 0x02 0x002 #define MX25_PAD_SD1_DATA2__GPIO_2_27 0x1a0 0x398 0x000 0x05 0x000 #define MX25_PAD_SD1_DATA3__ESDHC1_DAT3 0x1a4 0x39c 0x000 0x00 0x000 +#define MX25_PAD_SD1_DATA3__CSPI2_SS1 0x1a4 0x39c 0x4a8 0x01 0x001 #define MX25_PAD_SD1_DATA3__FEC_CRS 0x1a4 0x39c 0x508 0x02 0x002 #define MX25_PAD_SD1_DATA3__GPIO_2_28 0x1a4 0x39c 0x000 0x05 0x000 @@ -564,11 +575,15 @@ #define MX25_PAD_GPIO_C__PWM4_PWMO 0x1fc 0x3f8 0x000 0x01 0x000 #define MX25_PAD_GPIO_C__I2C2_SCL 0x1fc 0x3f8 0x51c 0x02 0x001 #define MX25_PAD_GPIO_C__KPP_COL4 0x1fc 0x3f8 0x52c 0x03 0x001 +#define MX25_PAD_GPIO_C__GPT2_CAPIN1 0x1fc 0x3f8 0x000 0x04 0x000 +#define MX25_PAD_GPIO_C__CSPI1_SS2 0x1fc 0x3f8 0x000 0x05 0x000 #define MX25_PAD_GPIO_C__CAN2_TX 0x1fc 0x3f8 0x000 0x06 0x000 +#define MX25_PAD_GPIO_C__CSPI2_SS2 0x1fc 0x3f8 0x000 0x07 0x000 #define MX25_PAD_GPIO_D__GPIO_D 0x200 0x3fc 0x000 0x00 0x000 #define MX25_PAD_GPIO_D__I2C2_SDA 0x200 0x3fc 0x520 0x02 0x001 #define MX25_PAD_GPIO_D__CAN2_RX 0x200 0x3fc 0x484 0x06 0x001 +#define MX25_PAD_GPIO_D__CSPI3_SS2 0x200 0x3fc 0x4c4 0x07 0x001 #define MX25_PAD_GPIO_E__GPIO_E 0x204 0x400 0x000 0x00 0x000 #define MX25_PAD_GPIO_E__I2C3_CLK 0x204 0x400 0x524 0x01 0x002 @@ -593,6 +608,7 @@ #define MX25_PAD_VSTBY_REQ__UART4_RTS 0x214 0x408 0x56c 0x06 0x002 #define MX25_PAD_VSTBY_ACK__VSTBY_ACK 0x218 0x40c 0x000 0x00 0x000 +#define MX25_PAD_VSTBY_ACK__CSPI1_SS3 0x218 0x40c 0x490 0x02 0x001 #define MX25_PAD_VSTBY_ACK__GPIO_3_18 0x218 0x40c 0x000 0x05 0x000 #define MX25_PAD_POWER_FAIL__POWER_FAIL 0x21c 0x410 0x000 0x00 0x000 diff --git a/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi b/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi index 52c95248e25d..303f920201c5 100644 --- a/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi +++ b/arch/arm/boot/dts/imx27-phytec-phycard-s-som.dtsi @@ -18,8 +18,8 @@ }; &cspi1 { - cs-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>, - <&gpio4 27 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>, + <&gpio4 27 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts b/arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts index bf883e45576a..344e77790152 100644 --- a/arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts +++ b/arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts @@ -65,7 +65,7 @@ &cspi1 { pinctrl-0 = <&pinctrl_cspi1>, <&pinctrl_cspi1cs1>; - cs-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>, + cs-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>, <&gpio4 27 GPIO_ACTIVE_LOW>; }; diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi index fc0b318f8733..7bc132737a37 100644 --- a/arch/arm/boot/dts/imx27.dtsi +++ b/arch/arm/boot/dts/imx27.dtsi @@ -558,7 +558,7 @@ }; }; - nfc: nand@d8000000 { + nfc: nand-controller@d8000000 { #address-cells = <1>; #size-cells = <1>; compatible = "fsl,imx27-nand"; diff --git a/arch/arm/boot/dts/imx28-apf28.dts b/arch/arm/boot/dts/imx28-apf28.dts index 3ed2b328f7ef..14a92fe59770 100644 --- a/arch/arm/boot/dts/imx28-apf28.dts +++ b/arch/arm/boot/dts/imx28-apf28.dts @@ -17,7 +17,7 @@ apb@80000000 { apbh@80000000 { - gpmi-nand@8000c000 { + nand-controller@8000c000 { pinctrl-names = "default"; pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg>; status = "okay"; diff --git a/arch/arm/boot/dts/imx28-apx4devkit.dts b/arch/arm/boot/dts/imx28-apx4devkit.dts index c5acc19c982d..b86be320496b 100644 --- a/arch/arm/boot/dts/imx28-apx4devkit.dts +++ b/arch/arm/boot/dts/imx28-apx4devkit.dts @@ -13,7 +13,7 @@ apb@80000000 { apbh@80000000 { - gpmi-nand@8000c000 { + nand-controller@8000c000 { pinctrl-names = "default"; pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg>; status = "okay"; diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts index 96c1d106bc64..7e2b0f198dfa 100644 --- a/arch/arm/boot/dts/imx28-evk.dts +++ b/arch/arm/boot/dts/imx28-evk.dts @@ -97,7 +97,7 @@ apb@80000000 { apbh@80000000 { - gpmi-nand@8000c000 { + nand-controller@8000c000 { pinctrl-names = "default"; pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg &gpmi_pins_evk>; diff --git a/arch/arm/boot/dts/imx28-m28.dtsi b/arch/arm/boot/dts/imx28-m28.dtsi index 0bac72d5351f..2bdb4c093545 100644 --- a/arch/arm/boot/dts/imx28-m28.dtsi +++ b/arch/arm/boot/dts/imx28-m28.dtsi @@ -16,7 +16,7 @@ apb@80000000 { apbh@80000000 { - gpmi-nand@8000c000 { + nand-controller@8000c000 { #address-cells = <1>; #size-cells = <1>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/imx28-m28cu3.dts b/arch/arm/boot/dts/imx28-m28cu3.dts index 91bd6deffee5..865ac3d573c7 100644 --- a/arch/arm/boot/dts/imx28-m28cu3.dts +++ b/arch/arm/boot/dts/imx28-m28cu3.dts @@ -17,7 +17,7 @@ apb@80000000 { apbh@80000000 { - gpmi-nand@8000c000 { + nand-controller@8000c000 { #address-cells = <1>; #size-cells = <1>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi index a2b799c56f8f..94dfbf5b3f34 100644 --- a/arch/arm/boot/dts/imx28.dtsi +++ b/arch/arm/boot/dts/imx28.dtsi @@ -100,7 +100,7 @@ status = "disabled"; }; - gpmi: gpmi-nand@8000c000 { + gpmi: nand-controller@8000c000 { compatible = "fsl,imx28-gpmi-nand"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx50-evk.dts b/arch/arm/boot/dts/imx50-evk.dts index a25da415cb02..878e89c20190 100644 --- a/arch/arm/boot/dts/imx50-evk.dts +++ b/arch/arm/boot/dts/imx50-evk.dts @@ -20,7 +20,7 @@ &cspi { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_cspi>; - cs-gpios = <&gpio4 11 0>, <&gpio4 13 0>; + cs-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>, <&gpio4 13 GPIO_ACTIVE_LOW>; status = "okay"; flash: m25p32@1 { diff --git a/arch/arm/boot/dts/imx51-apf51dev.dts b/arch/arm/boot/dts/imx51-apf51dev.dts index 563c1aae8c0c..c66f274ba4e9 100644 --- a/arch/arm/boot/dts/imx51-apf51dev.dts +++ b/arch/arm/boot/dts/imx51-apf51dev.dts @@ -74,8 +74,8 @@ &ecspi1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; - cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>, - <&gpio4 25 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>, + <&gpio4 25 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx53-m53menlo.dts b/arch/arm/boot/dts/imx53-m53menlo.dts index 719ed5ca454a..f98691ae4415 100644 --- a/arch/arm/boot/dts/imx53-m53menlo.dts +++ b/arch/arm/boot/dts/imx53-m53menlo.dts @@ -104,7 +104,7 @@ &ecspi2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; - cs-gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>, <&gpio2 27 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>, <&gpio2 27 GPIO_ACTIVE_LOW>; status = "okay"; spidev@0 { diff --git a/arch/arm/boot/dts/imx53-smd.dts b/arch/arm/boot/dts/imx53-smd.dts index ec9fb8940ffa..9be44e807188 100644 --- a/arch/arm/boot/dts/imx53-smd.dts +++ b/arch/arm/boot/dts/imx53-smd.dts @@ -58,7 +58,7 @@ &ecspi1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; - cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>; + cs-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>, <&gpio3 19 GPIO_ACTIVE_LOW>; status = "okay"; zigbee: mc1323@0 { diff --git a/arch/arm/boot/dts/imx53-tqma53.dtsi b/arch/arm/boot/dts/imx53-tqma53.dtsi index 9a6cb138adf3..7e7f9f3b3906 100644 --- a/arch/arm/boot/dts/imx53-tqma53.dtsi +++ b/arch/arm/boot/dts/imx53-tqma53.dtsi @@ -50,8 +50,8 @@ &ecspi1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; - cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>, - <&gpio3 24 0>, <&gpio3 25 0>; + cs-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>, <&gpio3 19 GPIO_ACTIVE_LOW>, + <&gpio3 24 GPIO_ACTIVE_LOW>, <&gpio3 25 GPIO_ACTIVE_LOW>; status = "disabled"; }; @@ -251,8 +251,8 @@ &cspi { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_cspi>; - cs-gpios = <&gpio1 18 0>, <&gpio1 19 0>, - <&gpio1 21 0>; + cs-gpios = <&gpio1 18 GPIO_ACTIVE_LOW>, <&gpio1 19 GPIO_ACTIVE_LOW>, + <&gpio1 21 GPIO_ACTIVE_LOW>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi b/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi index 289feab42b88..24859d0c09c1 100644 --- a/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi +++ b/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi @@ -119,7 +119,8 @@ &ecspi1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; - cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>, <&gpio2 16 0>, <&gpio2 17 0>; + cs-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>, <&gpio3 19 GPIO_ACTIVE_LOW>, + <&gpio2 16 GPIO_ACTIVE_LOW>, <&gpio2 17 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6-logicpd-baseboard.dtsi b/arch/arm/boot/dts/imx6-logicpd-baseboard.dtsi index 9e027b9a5f91..665d63765cdc 100644 --- a/arch/arm/boot/dts/imx6-logicpd-baseboard.dtsi +++ b/arch/arm/boot/dts/imx6-logicpd-baseboard.dtsi @@ -212,6 +212,7 @@ &ecspi1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; + cs-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; status = "disabled"; }; @@ -383,7 +384,7 @@ MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x100b1 MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x100b1 MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x100b1 - MX6QDL_PAD_KEY_ROW1__ECSPI1_SS0 0x100b1 + MX6QDL_PAD_KEY_ROW1__GPIO4_IO09 0x1b0b0 >; }; diff --git a/arch/arm/boot/dts/imx6dl-aristainetos_4.dts b/arch/arm/boot/dts/imx6dl-aristainetos_4.dts index 809ca5611072..5c7e85300695 100644 --- a/arch/arm/boot/dts/imx6dl-aristainetos_4.dts +++ b/arch/arm/boot/dts/imx6dl-aristainetos_4.dts @@ -61,7 +61,7 @@ }; &ecspi2 { - cs-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6dl-eckelmann-ci4x10.dts b/arch/arm/boot/dts/imx6dl-eckelmann-ci4x10.dts index 9eb2b73951b2..b4a9523e325b 100644 --- a/arch/arm/boot/dts/imx6dl-eckelmann-ci4x10.dts +++ b/arch/arm/boot/dts/imx6dl-eckelmann-ci4x10.dts @@ -67,7 +67,7 @@ &ecspi2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; - cs-gpios = <&gpio5 12 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio5 12 GPIO_ACTIVE_LOW>; status = "okay"; flash@0 { @@ -80,7 +80,7 @@ &ecspi1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; - cs-gpios = <&gpio5 25 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>; status = "okay"; tpm@0 { diff --git a/arch/arm/boot/dts/imx6dl-prtrvt.dts b/arch/arm/boot/dts/imx6dl-prtrvt.dts index fa882458957b..5ac84445e9cc 100644 --- a/arch/arm/boot/dts/imx6dl-prtrvt.dts +++ b/arch/arm/boot/dts/imx6dl-prtrvt.dts @@ -37,7 +37,7 @@ }; &ecspi1 { - cs-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; @@ -52,7 +52,7 @@ }; &ecspi3 { - cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6dl-prtvt7.dts b/arch/arm/boot/dts/imx6dl-prtvt7.dts index 306b4f7bf762..ae6da241f13e 100644 --- a/arch/arm/boot/dts/imx6dl-prtvt7.dts +++ b/arch/arm/boot/dts/imx6dl-prtvt7.dts @@ -219,7 +219,7 @@ }; &ecspi2 { - cs-gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6dl-tqma6a.dtsi b/arch/arm/boot/dts/imx6dl-tqma6a.dtsi new file mode 100644 index 000000000000..e891ef9b0091 --- /dev/null +++ b/arch/arm/boot/dts/imx6dl-tqma6a.dtsi @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2013 Sascha Hauer, Pengutronix + * Copyright 2013-2017 Markus Niebel <Markus.Niebel@tq-group.com> + */ + +#include "imx6dl.dtsi" +#include "imx6qdl-tqma6a.dtsi" +#include "imx6qdl-tqma6.dtsi" + +/ { + memory@10000000 { + device_type = "memory"; + reg = <0x10000000 0x20000000>; + }; +}; diff --git a/arch/arm/boot/dts/imx6dl-tqma6b.dtsi b/arch/arm/boot/dts/imx6dl-tqma6b.dtsi new file mode 100644 index 000000000000..38cd8501a886 --- /dev/null +++ b/arch/arm/boot/dts/imx6dl-tqma6b.dtsi @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2013 Sascha Hauer, Pengutronix + * Copyright 2013-2017 Markus Niebel <Markus.Niebel@tq-group.com> + */ + +#include "imx6dl.dtsi" +#include "imx6qdl-tqma6b.dtsi" +#include "imx6qdl-tqma6.dtsi" + +/ { + memory@10000000 { + device_type = "memory"; + reg = <0x10000000 0x20000000>; + }; +}; diff --git a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi index c4a235d212b6..7d2c72562c73 100644 --- a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi +++ b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi @@ -8,6 +8,11 @@ #include <dt-bindings/pwm/pwm.h> / { + aliases: aliases { + ethernet1 = ð1; + ethernet2 = ð2; + }; + backlight: backlight { compatible = "pwm-backlight"; pwms = <&pwm1 0 500000 PWM_POLARITY_INVERTED>; @@ -135,13 +140,13 @@ }; }; - port@2 { + eth2: port@2 { reg = <2>; label = "eth2"; phy-handle = <&phy_port2>; }; - port@3 { + eth1: port@3 { reg = <3>; label = "eth1"; phy-handle = <&phy_port3>; @@ -258,29 +263,35 @@ reg = <0x30>; clock-mode = /bits/ 8 <1>; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; - chan0 { + chan@0 { chan-name = "R"; led-cur = /bits/ 8 <0x20>; max-cur = /bits/ 8 <0x60>; + reg = <0>; }; - chan1 { + chan@1 { chan-name = "G"; led-cur = /bits/ 8 <0x20>; max-cur = /bits/ 8 <0x60>; + reg = <1>; }; - chan2 { + chan@2 { chan-name = "B"; led-cur = /bits/ 8 <0x20>; max-cur = /bits/ 8 <0x60>; + reg = <2>; }; - chan3 { + chan@3 { chan-name = "W"; led-cur = /bits/ 8 <0x0>; max-cur = /bits/ 8 <0x0>; + reg = <3>; }; }; @@ -311,7 +322,20 @@ pinctrl-0 = <&pinctrl_i2c3>; status = "okay"; - oled: oled@3d { + oled_1309: oled@3c { + compatible = "solomon,ssd1309fb-i2c"; + reg = <0x3c>; + solomon,height = <64>; + solomon,width = <128>; + solomon,page-offset = <0>; + solomon,segment-no-remap; + solomon,prechargep2 = <15>; + reset-gpios = <&gpio_oled 1 GPIO_ACTIVE_LOW>; + vbat-supply = <&sw2_reg>; + status = "disabled"; + }; + + oled_1305: oled@3d { compatible = "solomon,ssd1305fb-i2c"; reg = <0x3d>; solomon,height = <64>; diff --git a/arch/arm/boot/dts/imx6dl-yapp4-hydra.dts b/arch/arm/boot/dts/imx6dl-yapp4-hydra.dts index 6010d3d872ab..a19609c7c7c0 100644 --- a/arch/arm/boot/dts/imx6dl-yapp4-hydra.dts +++ b/arch/arm/boot/dts/imx6dl-yapp4-hydra.dts @@ -29,7 +29,11 @@ status = "okay"; }; -&oled { +&oled_1305 { + status = "okay"; +}; + +&oled_1309 { status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6dl-yapp4-orion.dts b/arch/arm/boot/dts/imx6dl-yapp4-orion.dts new file mode 100644 index 000000000000..884b236746bb --- /dev/null +++ b/arch/arm/boot/dts/imx6dl-yapp4-orion.dts @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (C) 2020 Y Soft Corporation, a.s. + +/dts-v1/; + +#include "imx6dl.dtsi" +#include "imx6dl-yapp4-common.dtsi" + +/ { + model = "Y Soft IOTA Orion i.MX6DualLite board"; + compatible = "ysoft,imx6dl-yapp4-orion", "fsl,imx6dl"; + + memory@10000000 { + device_type = "memory"; + reg = <0x10000000 0xf0000000>; + }; +}; + +&gpio_oled { + status = "okay"; +}; + +&leds { + status = "okay"; +}; + +&oled_1305 { + status = "okay"; +}; + +&oled_1309 { + status = "okay"; +}; + +®_usb_h1_vbus { + status = "okay"; +}; + +&touchkeys { + status = "okay"; +}; + +&uart2 { + status = "disabled"; +}; + +&usbh1 { + status = "okay"; +}; + +&usbphy2 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx6dl-yapp4-ursa.dts b/arch/arm/boot/dts/imx6dl-yapp4-ursa.dts index a1173bf5bff5..f6ae24efd4aa 100644 --- a/arch/arm/boot/dts/imx6dl-yapp4-ursa.dts +++ b/arch/arm/boot/dts/imx6dl-yapp4-ursa.dts @@ -17,6 +17,10 @@ }; }; +&aliases { + /delete-property/ ethernet1; +}; + &backlight { status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi index 77b65a402e19..fdd81fdc3f35 100644 --- a/arch/arm/boot/dts/imx6dl.dtsi +++ b/arch/arm/boot/dts/imx6dl.dtsi @@ -88,10 +88,6 @@ }; aips1: bus@2000000 { - iomuxc: pinctrl@20e0000 { - compatible = "fsl,imx6dl-iomuxc"; - }; - pxp: pxp@20f0000 { reg = <0x020f0000 0x4000>; interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>; @@ -298,6 +294,10 @@ compatible = "fsl,imx6dl-hdmi"; }; +&iomuxc { + compatible = "fsl,imx6dl-iomuxc"; +}; + &ipu1_csi1 { ipu1_csi1_from_ipu1_csi1_mux: endpoint { remote-endpoint = <&ipu1_csi1_mux_to_ipu1_csi1>; diff --git a/arch/arm/boot/dts/imx6q-b450v3.dts b/arch/arm/boot/dts/imx6q-b450v3.dts index fb0980190aa0..604f2420370f 100644 --- a/arch/arm/boot/dts/imx6q-b450v3.dts +++ b/arch/arm/boot/dts/imx6q-b450v3.dts @@ -84,19 +84,19 @@ }; &pca9539 { - P04 { + P04-hog { gpio-hog; gpios = <4 0>; output-low; line-name = "PCA9539-P04"; }; - P07 { - gpio-hog; - gpios = <7 0>; - output-low; - line-name = "PCA9539-P07"; - }; + P07-hog { + gpio-hog; + gpios = <7 0>; + output-low; + line-name = "PCA9539-P07"; + }; }; &pci_root { diff --git a/arch/arm/boot/dts/imx6q-b650v3.dts b/arch/arm/boot/dts/imx6q-b650v3.dts index 8f762d9c5ae9..56d2aeb1900c 100644 --- a/arch/arm/boot/dts/imx6q-b650v3.dts +++ b/arch/arm/boot/dts/imx6q-b650v3.dts @@ -84,12 +84,12 @@ }; &pca9539 { - P07 { - gpio-hog; - gpios = <7 0>; - output-low; - line-name = "PCA9539-P07"; - }; + P07-hog { + gpio-hog; + gpios = <7 0>; + output-low; + line-name = "PCA9539-P07"; + }; }; &usbphy1 { diff --git a/arch/arm/boot/dts/imx6q-b850v3.dts b/arch/arm/boot/dts/imx6q-b850v3.dts index 1ea64ecf4291..3d6b757bf325 100644 --- a/arch/arm/boot/dts/imx6q-b850v3.dts +++ b/arch/arm/boot/dts/imx6q-b850v3.dts @@ -199,14 +199,14 @@ }; &pca9539 { - P10 { + P10-hog { gpio-hog; gpios = <8 0>; output-low; line-name = "PCA9539-P10"; }; - P11 { + P11-hog { gpio-hog; gpios = <9 0>; output-low; diff --git a/arch/arm/boot/dts/imx6q-ba16.dtsi b/arch/arm/boot/dts/imx6q-ba16.dtsi index fc81f2f4b62d..e4578ed3371e 100644 --- a/arch/arm/boot/dts/imx6q-ba16.dtsi +++ b/arch/arm/boot/dts/imx6q-ba16.dtsi @@ -134,7 +134,7 @@ }; &ecspi1 { - cs-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6q-bx50v3.dtsi b/arch/arm/boot/dts/imx6q-bx50v3.dtsi index 1938b04199c4..2a98cc657595 100644 --- a/arch/arm/boot/dts/imx6q-bx50v3.dtsi +++ b/arch/arm/boot/dts/imx6q-bx50v3.dtsi @@ -102,10 +102,15 @@ #address-cells = <1>; #size-cells = <0>; - switch@0 { + switch: switch@0 { compatible = "marvell,mv88e6085"; /* 88e6240*/ reg = <0>; + interrupt-parent = <&gpio2>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells = <2>; + switch_ports: ports { #address-cells = <1>; #size-cells = <0>; @@ -117,22 +122,32 @@ switchphy0: switchphy@0 { reg = <0>; + interrupt-parent = <&switch>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; }; switchphy1: switchphy@1 { reg = <1>; + interrupt-parent = <&switch>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; }; switchphy2: switchphy@2 { reg = <2>; + interrupt-parent = <&switch>; + interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; }; switchphy3: switchphy@3 { reg = <3>; + interrupt-parent = <&switch>; + interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; }; switchphy4: switchphy@4 { reg = <4>; + interrupt-parent = <&switch>; + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; }; }; }; @@ -140,7 +155,7 @@ }; &ecspi5 { - cs-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi5>; status = "okay"; @@ -233,42 +248,42 @@ interrupt-parent = <&gpio2>; interrupts = <3 IRQ_TYPE_LEVEL_LOW>; - P12 { + P12-hog { gpio-hog; gpios = <10 0>; output-low; line-name = "PCA9539-P12"; }; - P13 { + P13-hog { gpio-hog; gpios = <11 0>; output-low; line-name = "PCA9539-P13"; }; - P14 { + P14-hog { gpio-hog; gpios = <12 0>; output-low; line-name = "PCA9539-P14"; }; - P15 { + P15-hog { gpio-hog; gpios = <13 0>; output-low; line-name = "PCA9539-P15"; }; - P16 { + P16-hog { gpio-hog; gpios = <14 0>; output-low; line-name = "PCA9539-P16"; }; - P17 { + P17-hog { gpio-hog; gpios = <15 0>; output-low; diff --git a/arch/arm/boot/dts/imx6q-cm-fx6.dts b/arch/arm/boot/dts/imx6q-cm-fx6.dts index cab9e92531c7..bfb530f29d9d 100644 --- a/arch/arm/boot/dts/imx6q-cm-fx6.dts +++ b/arch/arm/boot/dts/imx6q-cm-fx6.dts @@ -255,7 +255,7 @@ }; &ecspi1 { - cs-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>, <&gpio3 19 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>, <&gpio3 19 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi index 87f0aa897086..236fc205c389 100644 --- a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi +++ b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi @@ -59,7 +59,7 @@ }; &ecspi1 { - cs-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>, <&gpio4 11 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>, <&gpio4 11 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts index f9df207b2778..fa2307d8ce86 100644 --- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts +++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts @@ -99,7 +99,7 @@ &ecspi5 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi5>; - cs-gpios = <&gpio1 12 0>; + cs-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; status = "okay"; flash: m25p80@0 { diff --git a/arch/arm/boot/dts/imx6q-dms-ba16.dts b/arch/arm/boot/dts/imx6q-dms-ba16.dts index 57761f3172fa..48fb47e715f6 100644 --- a/arch/arm/boot/dts/imx6q-dms-ba16.dts +++ b/arch/arm/boot/dts/imx6q-dms-ba16.dts @@ -42,7 +42,7 @@ }; &ecspi5 { - cs-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi5>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6q-gw5400-a.dts b/arch/arm/boot/dts/imx6q-gw5400-a.dts index b6e2b580051d..4cde45d5c90c 100644 --- a/arch/arm/boot/dts/imx6q-gw5400-a.dts +++ b/arch/arm/boot/dts/imx6q-gw5400-a.dts @@ -132,7 +132,7 @@ }; &ecspi1 { - cs-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6q-kontron-samx6i.dtsi b/arch/arm/boot/dts/imx6q-kontron-samx6i.dtsi index 2618eccfe50d..4d6a0c3e8455 100644 --- a/arch/arm/boot/dts/imx6q-kontron-samx6i.dtsi +++ b/arch/arm/boot/dts/imx6q-kontron-samx6i.dtsi @@ -14,10 +14,9 @@ /* Quad/Dual SoMs have 3 chip-select signals */ &ecspi4 { - fsl,spi-num-chipselects = <3>; - cs-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>, - <&gpio3 29 GPIO_ACTIVE_HIGH>, - <&gpio3 25 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>, + <&gpio3 29 GPIO_ACTIVE_LOW>, + <&gpio3 25 GPIO_ACTIVE_LOW>; }; &pinctrl_ecspi4 { diff --git a/arch/arm/boot/dts/imx6q-logicpd.dts b/arch/arm/boot/dts/imx6q-logicpd.dts index 7a3d1d3e54a9..46a4ddedb423 100644 --- a/arch/arm/boot/dts/imx6q-logicpd.dts +++ b/arch/arm/boot/dts/imx6q-logicpd.dts @@ -9,11 +9,11 @@ / { model = "Logic PD i.MX6QD SOM-M3"; - compatible = "fsl,imx6q"; + compatible = "logicpd,imx6q-logicpd", "fsl,imx6q"; backlight: backlight-lvds { compatible = "pwm-backlight"; - pwms = <&pwm3 0 20000>; + pwms = <&pwm3 0 20000 0>; brightness-levels = <0 4 8 16 32 64 128 255>; default-brightness-level = <6>; power-supply = <®_lcd>; diff --git a/arch/arm/boot/dts/imx6q-prti6q.dts b/arch/arm/boot/dts/imx6q-prti6q.dts index de6cbaab8b49..d112b50f8c5d 100644 --- a/arch/arm/boot/dts/imx6q-prti6q.dts +++ b/arch/arm/boot/dts/imx6q-prti6q.dts @@ -158,7 +158,7 @@ }; &ecspi1 { - cs-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; @@ -171,7 +171,7 @@ }; &ecspi2 { - cs-gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>, <&gpio4 25 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>, <&gpio4 25 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2 &pinctrl_ecspi2_cs>; status = "okay"; @@ -195,7 +195,7 @@ }; &ecspi3 { - cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6q-prtwd2.dts b/arch/arm/boot/dts/imx6q-prtwd2.dts index dffafbcaa7af..349959d38020 100644 --- a/arch/arm/boot/dts/imx6q-prtwd2.dts +++ b/arch/arm/boot/dts/imx6q-prtwd2.dts @@ -30,7 +30,7 @@ }; /* PRTWD2 rev 1 bitbang I2C for Ethernet Switch */ - i2c@4 { + i2c { compatible = "i2c-gpio"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c4>; diff --git a/arch/arm/boot/dts/imx6q-tqma6a.dtsi b/arch/arm/boot/dts/imx6q-tqma6a.dtsi new file mode 100644 index 000000000000..ab4c07c13a13 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-tqma6a.dtsi @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2013 Sascha Hauer, Pengutronix + * Copyright 2013-2017 Markus Niebel <Markus.Niebel@tq-group.com> + */ + +#include "imx6q.dtsi" +#include "imx6qdl-tqma6a.dtsi" +#include "imx6qdl-tqma6.dtsi" + +/ { + memory@10000000 { + device_type = "memory"; + reg = <0x10000000 0x40000000>; + }; +}; diff --git a/arch/arm/boot/dts/imx6q-tqma6b.dtsi b/arch/arm/boot/dts/imx6q-tqma6b.dtsi new file mode 100644 index 000000000000..7224c376c318 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-tqma6b.dtsi @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2013 Sascha Hauer, Pengutronix + */ + +#include "imx6q.dtsi" +#include "imx6qdl-tqma6b.dtsi" +#include "imx6qdl-tqma6.dtsi" + +/ { + memory@10000000 { + device_type = "memory"; + reg = <0x10000000 0x40000000>; + }; +}; diff --git a/arch/arm/boot/dts/imx6q-var-dt6customboard.dts b/arch/arm/boot/dts/imx6q-var-dt6customboard.dts index a57c2e3a8435..63550351340d 100644 --- a/arch/arm/boot/dts/imx6q-var-dt6customboard.dts +++ b/arch/arm/boot/dts/imx6q-var-dt6customboard.dts @@ -144,8 +144,8 @@ }; &ecspi1 { - cs-gpios = <&gpio4 9 GPIO_ACTIVE_HIGH>, - <&gpio4 10 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>, + <&gpio4 10 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index 78a4d64929f3..5277e3903291 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -182,10 +182,6 @@ status = "disabled"; }; }; - - iomuxc: pinctrl@20e0000 { - compatible = "fsl,imx6q-iomuxc"; - }; }; sata: sata@2200000 { @@ -427,6 +423,10 @@ }; }; +&iomuxc { + compatible = "fsl,imx6q-iomuxc"; +}; + &ipu1_csi1 { ipu1_csi1_from_mipi_vc1: endpoint { remote-endpoint = <&mipi_vc1_to_ipu1_csi1>; diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/imx6qdl-apalis.dtsi index dbdd7db60325..30fa349f9d05 100644 --- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi +++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi @@ -127,7 +127,7 @@ /* Apalis SPI1 */ &ecspi1 { - cs-gpios = <&gpio5 25 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "disabled"; @@ -135,7 +135,7 @@ /* Apalis SPI2 */ &ecspi2 { - cs-gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; status = "disabled"; diff --git a/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi b/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi index d954661fa055..e21f6ac864e5 100644 --- a/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi +++ b/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi @@ -91,7 +91,7 @@ }; &ecspi4 { - cs-gpios = <&gpio3 20 0>; + cs-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi4>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi b/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi index d38630d4b892..ead7ba27e105 100644 --- a/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi +++ b/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi @@ -110,23 +110,23 @@ }; &ecspi1 { - cs-gpios = <&gpio4 9 GPIO_ACTIVE_HIGH - &gpio4 10 GPIO_ACTIVE_HIGH - &gpio4 11 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 9 GPIO_ACTIVE_LOW + &gpio4 10 GPIO_ACTIVE_LOW + &gpio4 11 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; }; &ecspi2 { - cs-gpios = <&gpio2 26 GPIO_ACTIVE_HIGH &gpio2 27 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW &gpio2 27 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; status = "okay"; }; &ecspi4 { - cs-gpios = <&gpio3 29 GPIO_ACTIVE_HIGH &gpio5 2 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio3 29 GPIO_ACTIVE_LOW &gpio5 2 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi4>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-colibri.dtsi b/arch/arm/boot/dts/imx6qdl-colibri.dtsi index 0930194fd960..4e2a309c93fa 100644 --- a/arch/arm/boot/dts/imx6qdl-colibri.dtsi +++ b/arch/arm/boot/dts/imx6qdl-colibri.dtsi @@ -94,7 +94,7 @@ /* Colibri SSP */ &ecspi4 { - cs-gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio5 2 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi4>; status = "disabled"; diff --git a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi index ebe7a8bddf04..648f5fcb72e6 100644 --- a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi +++ b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi @@ -30,7 +30,7 @@ }; &ecspi3 { - cs-gpios = <&gpio4 24 0>; + cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-emcon.dtsi b/arch/arm/boot/dts/imx6qdl-emcon.dtsi index 35e230f991f1..7228b894a763 100644 --- a/arch/arm/boot/dts/imx6qdl-emcon.dtsi +++ b/arch/arm/boot/dts/imx6qdl-emcon.dtsi @@ -168,8 +168,8 @@ &ecspi2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; - cs-gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>, - <&gpio2 27 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>, + <&gpio2 27 GPIO_ACTIVE_LOW>; }; &ecspi4 { diff --git a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi index 7705285d9e3c..3c04b5a4f3cb 100644 --- a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi @@ -5,6 +5,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> / { /* these are used by bootloader for disabling nodes */ @@ -22,8 +23,6 @@ gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; user-pb { label = "user_pb"; @@ -154,7 +153,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi index a46ea98228c2..736074f1c3ef 100644 --- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi @@ -5,6 +5,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> / { /* these are used by bootloader for disabling nodes */ @@ -182,7 +183,7 @@ }; &ecspi3 { - cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; status = "okay"; @@ -217,7 +218,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi index a28e79463d0c..8072ed47c6bb 100644 --- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi @@ -5,6 +5,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> / { /* these are used by bootloader for disabling nodes */ @@ -210,7 +211,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi index b5f934b8a239..8c9bcdd39830 100644 --- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi @@ -5,6 +5,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/sound/fsl-imx-audmux.h> / { @@ -212,7 +213,7 @@ }; &ecspi2 { - cs-gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; status = "okay"; @@ -247,7 +248,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #address-cells = <1>; diff --git a/arch/arm/boot/dts/imx6qdl-gw551x.dtsi b/arch/arm/boot/dts/imx6qdl-gw551x.dtsi index 1516e2b0bcde..e5d803d023c8 100644 --- a/arch/arm/boot/dts/imx6qdl-gw551x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw551x.dtsi @@ -48,6 +48,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/media/tda1997x.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/sound/fsl-imx-audmux.h> / { @@ -219,7 +220,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi index 0da6e6f7482b..290a607fede9 100644 --- a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi @@ -5,6 +5,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> / { /* these are used by bootloader for disabling nodes */ @@ -144,7 +145,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx6qdl-gw553x.dtsi b/arch/arm/boot/dts/imx6qdl-gw553x.dtsi index db30de5d6490..c15b9cc63bf8 100644 --- a/arch/arm/boot/dts/imx6qdl-gw553x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw553x.dtsi @@ -47,6 +47,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> / { /* these are used by bootloader for disabling nodes */ @@ -64,8 +65,6 @@ gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; user-pb { label = "user_pb"; @@ -182,7 +181,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx6qdl-gw560x.dtsi b/arch/arm/boot/dts/imx6qdl-gw560x.dtsi index d6b074597518..093a219a77ae 100644 --- a/arch/arm/boot/dts/imx6qdl-gw560x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw560x.dtsi @@ -47,6 +47,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> +#include <dt-bindings/interrupt-controller/irq.h> / { /* these are used by bootloader for disabling nodes */ @@ -252,7 +253,7 @@ }; &ecspi3 { - cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; status = "okay"; @@ -294,7 +295,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx6qdl-gw5903.dtsi b/arch/arm/boot/dts/imx6qdl-gw5903.dtsi index fbe6c32bd756..e1c8dd233cab 100644 --- a/arch/arm/boot/dts/imx6qdl-gw5903.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw5903.dtsi @@ -47,6 +47,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> / { chosen { @@ -235,7 +236,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx6qdl-gw5904.dtsi b/arch/arm/boot/dts/imx6qdl-gw5904.dtsi index 23c6e4047621..3cd2e717c1da 100644 --- a/arch/arm/boot/dts/imx6qdl-gw5904.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw5904.dtsi @@ -47,6 +47,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> / { /* these are used by bootloader for disabling nodes */ @@ -257,7 +258,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx6qdl-gw5907.dtsi b/arch/arm/boot/dts/imx6qdl-gw5907.dtsi index b1ff7c859c4d..21c68a55bcb9 100644 --- a/arch/arm/boot/dts/imx6qdl-gw5907.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw5907.dtsi @@ -5,6 +5,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> / { /* these are used by bootloader for disabling nodes */ @@ -154,7 +155,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx6qdl-gw5910.dtsi b/arch/arm/boot/dts/imx6qdl-gw5910.dtsi index 11f84ee7b88f..ed4e22259959 100644 --- a/arch/arm/boot/dts/imx6qdl-gw5910.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw5910.dtsi @@ -5,6 +5,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> / { /* these are used by bootloader for disabling nodes */ @@ -134,7 +135,7 @@ &ecspi3 { - cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; status = "okay"; @@ -163,7 +164,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx6qdl-gw5912.dtsi b/arch/arm/boot/dts/imx6qdl-gw5912.dtsi index 0a1ffff9eb75..797f160249f7 100644 --- a/arch/arm/boot/dts/imx6qdl-gw5912.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw5912.dtsi @@ -5,6 +5,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> / { /* these are used by bootloader for disabling nodes */ @@ -129,7 +130,7 @@ }; &ecspi2 { - cs-gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; status = "okay"; @@ -158,7 +159,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #address-cells = <1>; diff --git a/arch/arm/boot/dts/imx6qdl-gw5913.dtsi b/arch/arm/boot/dts/imx6qdl-gw5913.dtsi index d62a8da49367..4cd7d290f5b2 100644 --- a/arch/arm/boot/dts/imx6qdl-gw5913.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw5913.dtsi @@ -5,6 +5,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> / { /* these are used by bootloader for disabling nodes */ @@ -139,7 +140,7 @@ compatible = "gw,gsc"; reg = <0x20>; interrupt-parent = <&gpio1>; - interrupts = <4 GPIO_ACTIVE_LOW>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi index e4231331f04e..eb1ad28946d3 100644 --- a/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi +++ b/arch/arm/boot/dts/imx6qdl-hummingboard2.dtsi @@ -203,7 +203,7 @@ &ecspi2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hummingboard2_ecspi2>; - cs-gpios = <&gpio2 26 0>; + cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi index 81c7ebb4b3fb..265f5f3dbff6 100644 --- a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi +++ b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi @@ -245,16 +245,16 @@ &ecspi2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; - cs-gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>, - <&gpio2 27 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>, + <&gpio2 27 GPIO_ACTIVE_LOW>; }; /* SPI0 */ &ecspi4 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi4>; - cs-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>, - <&gpio3 29 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>, + <&gpio3 29 GPIO_ACTIVE_LOW>; status = "okay"; /* default boot source: workaround #1 for errata ERR006282 */ diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi index 185a1a31ca39..a0917823c244 100644 --- a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi +++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi @@ -316,7 +316,7 @@ }; &ecspi1 { - cs-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi index 4bbe54e1ddb5..92d09a3ebe0e 100644 --- a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi +++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi @@ -247,7 +247,7 @@ }; &ecspi1 { - cs-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi index c63e1bc1ad3a..1243677b5f97 100644 --- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi @@ -232,7 +232,7 @@ }; &ecspi1 { - cs-gpios = <&gpio3 19 0>; + cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index bc43c75f1745..e361df26a168 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -71,7 +71,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; status = "okay"; - cs-gpios = <&gpio4 24 0>; + cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>; som_flash: flash@0 { compatible = "m25p80", "jedec,spi-nor"; diff --git a/arch/arm/boot/dts/imx6qdl-pico.dtsi b/arch/arm/boot/dts/imx6qdl-pico.dtsi index 39dfd90c2c6b..5de4ccb97916 100644 --- a/arch/arm/boot/dts/imx6qdl-pico.dtsi +++ b/arch/arm/boot/dts/imx6qdl-pico.dtsi @@ -167,7 +167,7 @@ &ecspi2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; - cs-gpios = <&gpio2 27 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 27 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi index 55f736dbee0b..afe477f32984 100644 --- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi @@ -267,7 +267,7 @@ }; &ecspi1 { - cs-gpios = <&gpio3 19 0>; + cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>; status = "disabled"; /* pin conflict with WEIM NOR */ diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi index 95f9ddab5996..fdc3aa9d544d 100644 --- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi @@ -308,7 +308,7 @@ }; &ecspi1 { - cs-gpios = <&gpio3 19 0>; + cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi index 68b3e68cb8df..f824c9abd11a 100644 --- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi @@ -105,9 +105,13 @@ "Ext Spk", "SPKOUTL", "Ext Spk", "SPKOUTR", "AMIC", "MICBIAS", - "IN3R", "AMIC"; + "IN3R", "AMIC", + "DMIC", "MICBIAS", + "DMICDAT", "DMIC"; mux-int-port = <2>; mux-ext-port = <3>; + hp-det-gpio = <&gpio7 8 GPIO_ACTIVE_LOW>; + mic-det-gpio = <&gpio1 9 GPIO_ACTIVE_LOW>; }; backlight_lvds: backlight-lvds { @@ -185,7 +189,7 @@ }; &ecspi1 { - cs-gpios = <&gpio4 9 0>; + cs-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-tqma6.dtsi b/arch/arm/boot/dts/imx6qdl-tqma6.dtsi new file mode 100644 index 000000000000..b18b83ac6aee --- /dev/null +++ b/arch/arm/boot/dts/imx6qdl-tqma6.dtsi @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2013 Sascha Hauer, Pengutronix + * Copyright 2013-2017 Markus Niebel <Markus.Niebel@tq-group.com> + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "supply-3p3v"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; +}; + +&ecspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1>; + cs-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + status = "okay"; + + m25p80: flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <50000000>; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + m25p,fast-read; + }; +}; + +&iomuxc { + pinctrl_ecspi1: ecspi1grp { + fsl,pins = < + /* HYS, SPEED = MED, 100k up, DSE = 011, SRE_FAST */ + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x1b099 + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0xb099 + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0xb099 + /* eCSPI1 SS1 */ + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0xb099 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b899 + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b899 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b899 + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b899 + >; + }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + MX6QDL_PAD_NANDF_RB0__GPIO6_IO10 0x1b099 /* PMIC irq */ + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059 + >; + }; +}; + +&pmic { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic>; + interrupt-parent = <&gpio6>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + + regulators { + reg_vddcore: sw1ab { + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-always-on; + }; + + reg_vddsoc: sw1c { + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-always-on; + }; + + reg_gen_3v3: sw2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_ddr_1v5a: sw3a { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1975000>; + regulator-always-on; + }; + + reg_ddr_1v5b: sw3b { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1975000>; + regulator-always-on; + }; + + sw4_reg: sw4 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_5v_600mA: swbst { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5150000>; + regulator-always-on; + }; + + reg_snvs_3v: vsnvs { + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + }; + + reg_vrefddr: vrefddr { + regulator-boot-on; + regulator-always-on; + }; + + reg_vgen1_1v5: vgen1 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + /* not used */ + }; + + reg_vgen2_1v2_eth: vgen2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + regulator-always-on; + }; + + reg_vgen3_2v8: vgen3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_vgen4_1v8: vgen4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_vgen5_1v8_eth: vgen5 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_vgen6_3v3: vgen6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; +}; + +/* eMMC */ +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3>; + vmmc-supply = <®_3p3v>; + non-removable; + disable-wp; + no-sd; + no-sdio; + bus-width = <8>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + mmccard: mmccard@0 { + reg = <0>; + compatible = "mmc-card"; + broken-hpi; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi b/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi new file mode 100644 index 000000000000..b679bec78e6c --- /dev/null +++ b/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2013 Sascha Hauer, Pengutronix + * Copyright 2013-2017 Markus Niebel <Markus.Niebel@tq-group.com> + */ + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + clock-frequency = <100000>; + status = "okay"; + + pmic: pmic@8 { + compatible = "fsl,pfuze100"; + reg = <0x08>; + }; + + sensor@48 { + compatible = "national,lm75"; + reg = <0x48>; + }; + + eeprom@50 { + compatible = "st,24c64", "atmel,24c64"; + reg = <0x50>; + pagesize = <32>; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-tqma6b.dtsi b/arch/arm/boot/dts/imx6qdl-tqma6b.dtsi new file mode 100644 index 000000000000..49c472285c06 --- /dev/null +++ b/arch/arm/boot/dts/imx6qdl-tqma6b.dtsi @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2013 Sascha Hauer, Pengutronix + * Copyright 2013-2017 Markus Niebel <Markus.Niebel@tq-group.com> + */ + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + clock-frequency = <100000>; + status = "okay"; + + pmic: pmic@8 { + compatible = "fsl,pfuze100"; + reg = <0x08>; + }; + + sensor@48 { + compatible = "national,lm75"; + reg = <0x48>; + }; + + eeprom@50 { + compatible = "st,24c64", "atmel,24c64"; + reg = <0x50>; + pagesize = <32>; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-ts4900.dtsi b/arch/arm/boot/dts/imx6qdl-ts4900.dtsi index 267c956d8910..f88da757edda 100644 --- a/arch/arm/boot/dts/imx6qdl-ts4900.dtsi +++ b/arch/arm/boot/dts/imx6qdl-ts4900.dtsi @@ -95,7 +95,7 @@ }; &ecspi1 { - cs-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; @@ -108,7 +108,7 @@ }; &ecspi2 { - cs-gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-ts7970.dtsi b/arch/arm/boot/dts/imx6qdl-ts7970.dtsi index f0be516dc28e..e6aa0c33754d 100644 --- a/arch/arm/boot/dts/imx6qdl-ts7970.dtsi +++ b/arch/arm/boot/dts/imx6qdl-ts7970.dtsi @@ -165,7 +165,7 @@ }; &ecspi1 { - cs-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; @@ -179,9 +179,9 @@ &ecspi2 { cs-gpios = < - &gpio5 31 GPIO_ACTIVE_HIGH - &gpio7 12 GPIO_ACTIVE_HIGH - &gpio5 18 GPIO_ACTIVE_HIGH + &gpio5 31 GPIO_ACTIVE_LOW + &gpio7 12 GPIO_ACTIVE_LOW + &gpio5 18 GPIO_ACTIVE_LOW >; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; diff --git a/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi b/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi index 5af9ce977b12..66b15748e287 100644 --- a/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi +++ b/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi @@ -316,7 +316,7 @@ &ecspi1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; - cs-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>; status = "okay"; flash@0 { diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 43edbf1156c7..7a8837cbe21b 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -159,7 +159,7 @@ clocks = <&clks IMX6QDL_CLK_APBH_DMA>; }; - gpmi: gpmi-nand@112000 { + gpmi: nand-controller@112000 { compatible = "fsl,imx6q-gpmi-nand"; reg = <0x00112000 0x2000>, <0x00114000 0x2000>; reg-names = "gpmi-nand", "bch"; @@ -1043,8 +1043,9 @@ <0 119 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6QDL_CLK_ENET>, <&clks IMX6QDL_CLK_ENET>, + <&clks IMX6QDL_CLK_ENET_REF>, <&clks IMX6QDL_CLK_ENET_REF>; - clock-names = "ipg", "ahb", "ptp"; + clock-names = "ipg", "ahb", "ptp", "enet_out"; fsl,stop-mode = <&gpr 0x34 27>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6qp-sabreauto.dts b/arch/arm/boot/dts/imx6qp-sabreauto.dts index 639d9dd35377..2bb3bfb18ec3 100644 --- a/arch/arm/boot/dts/imx6qp-sabreauto.dts +++ b/arch/arm/boot/dts/imx6qp-sabreauto.dts @@ -47,7 +47,8 @@ }; &pcie { - status = "disabled"; + reset-gpio = <&max7310_c 5 GPIO_ACTIVE_LOW>; + status = "okay"; }; &sata { diff --git a/arch/arm/boot/dts/imx6qp-tqma6b.dtsi b/arch/arm/boot/dts/imx6qp-tqma6b.dtsi new file mode 100644 index 000000000000..bb6ff7c64b27 --- /dev/null +++ b/arch/arm/boot/dts/imx6qp-tqma6b.dtsi @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2013 Sascha Hauer, Pengutronix + */ + +#include "imx6q.dtsi" +#include "imx6qp.dtsi" +#include "imx6qdl-tqma6b.dtsi" +#include "imx6qdl-tqma6.dtsi" + +/ { + memory@10000000 { + device_type = "memory"; + reg = <0x10000000 0x40000000>; + }; +}; diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts index b1b069e723d2..25f6f2fb1555 100644 --- a/arch/arm/boot/dts/imx6sl-evk.dts +++ b/arch/arm/boot/dts/imx6sl-evk.dts @@ -94,6 +94,8 @@ sound { compatible = "fsl,imx6sl-evk-wm8962", "fsl,imx-audio-wm8962"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hp>; model = "wm8962-audio"; ssi-controller = <&ssi2>; audio-codec = <&codec>; @@ -106,6 +108,7 @@ "IN3R", "AMIC"; mux-int-port = <2>; mux-ext-port = <3>; + hp-det-gpio = <&gpio4 19 GPIO_ACTIVE_LOW>; }; panel { @@ -129,7 +132,7 @@ }; &ecspi1 { - cs-gpios = <&gpio4 11 0>; + cs-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; @@ -343,6 +346,12 @@ >; }; + pinctrl_hp: hpgrp { + fsl,pins = < + MX6SL_PAD_FEC_RX_ER__GPIO4_IO19 0x1b0b0 + >; + }; + pinctrl_i2c1: i2c1grp { fsl,pins = < MX6SL_PAD_I2C1_SCL__I2C1_SCL 0x4001b8b1 diff --git a/arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts b/arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts new file mode 100644 index 000000000000..caa279608803 --- /dev/null +++ b/arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts @@ -0,0 +1,588 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device tree for the Tolino Shine 2 HD ebook reader + * + * Name on mainboard is: 37NB-E60QF0+4A2 or 37NB-E60QF0+4A3 + * Serials start with: E60QF2 + * + * Copyright 2020 Andreas Kemnade + */ + +/dts-v1/; + +#include <dt-bindings/input/input.h> +#include <dt-bindings/gpio/gpio.h> +#include "imx6sl.dtsi" + +/ { + model = "Tolino Shine 2 HD"; + compatible = "kobo,tolino-shine2hd", "fsl,imx6sl"; + + chosen { + stdout-path = &uart1; + }; + + gpio_keys: gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_keys>; + + cover { + label = "Cover"; + gpios = <&gpio5 12 GPIO_ACTIVE_LOW>; + linux,code = <SW_LID>; + linux,input-type = <EV_SW>; + wakeup-source; + }; + + fl { + label = "Frontlight"; + gpios = <&gpio3 26 GPIO_ACTIVE_LOW>; + linux,code = <KEY_BRIGHTNESS_CYCLE>; + }; + + home { + label = "Home"; + gpios = <&gpio3 25 GPIO_ACTIVE_LOW>; + linux,code = <KEY_HOME>; + }; + + power { + label = "Power"; + gpios = <&gpio5 8 GPIO_ACTIVE_LOW>; + linux,code = <KEY_POWER>; + wakeup-source; + }; + }; + + leds: leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_led>; + + on { + label = "tolinoshine2hd:white:on"; + gpios = <&gpio5 13 GPIO_ACTIVE_LOW>; + linux,default-trigger = "timer"; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x20000000>; + }; + + reg_wifi: regulator-wifi { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wifi_power>; + regulator-name = "SD3_SPWR"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + gpio = <&gpio4 29 GPIO_ACTIVE_LOW>; + }; + + wifi_pwrseq: wifi_pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wifi_reset>; + post-power-on-delay-ms = <20>; + reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; + }; +}; + +&i2c1 { + pinctrl-names = "default","sleep"; + pinctrl-0 = <&pinctrl_i2c1>; + pinctrl-1 = <&pinctrl_i2c1_sleep>; + status = "okay"; + + /* TODO: embedded controller at 0x43 (driver missing) */ + +}; + +&i2c2 { + pinctrl-names = "default","sleep"; + pinctrl-0 = <&pinctrl_i2c2>; + pinctrl-1 = <&pinctrl_i2c2_sleep>; + clock-frequency = <100000>; + status = "okay"; + + zforce: touchscreen@50 { + compatible = "neonode,zforce"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_zforce>; + reg = <0x50>; + interrupt-parent = <&gpio5>; + interrupts = <6 IRQ_TYPE_EDGE_FALLING>; + vdd-supply = <&ldo1_reg>; + reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; + x-size = <1072>; + y-size = <1448>; + }; + + /* TODO: TPS65185 PMIC for E Ink at 0x68 */ + +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + clock-frequency = <400000>; + status = "okay"; + + ricoh619: pmic@32 { + compatible = "ricoh,rc5t619"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ricoh_gpio>; + reg = <0x32>; + interrupt-parent = <&gpio5>; + interrupts = <11 IRQ_TYPE_EDGE_FALLING>; + system-power-controller; + + regulators { + dcdc1_reg: DCDC1 { + regulator-name = "DCDC1"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-max-microvolt = <900000>; + regulator-suspend-min-microvolt = <900000>; + }; + }; + + /* Core3_3V3 */ + dcdc2_reg: DCDC2 { + regulator-name = "DCDC2"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-max-microvolt = <3100000>; + regulator-suspend-min-microvolt = <3100000>; + }; + }; + + dcdc3_reg: DCDC3 { + regulator-name = "DCDC3"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-max-microvolt = <1140000>; + regulator-suspend-min-microvolt = <1140000>; + }; + }; + + /* Core4_1V2 */ + dcdc4_reg: DCDC4 { + regulator-name = "DCDC4"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-max-microvolt = <1140000>; + regulator-suspend-min-microvolt = <1140000>; + }; + }; + + /* Core4_1V8 */ + dcdc5_reg: DCDC5 { + regulator-name = "DCDC5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-max-microvolt = <1700000>; + regulator-suspend-min-microvolt = <1700000>; + }; + }; + + /* IR_3V3 */ + ldo1_reg: LDO1 { + regulator-name = "LDO1"; + regulator-boot-on; + }; + + /* Core1_3V3 */ + ldo2_reg: LDO2 { + regulator-name = "LDO2"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-max-microvolt = <3000000>; + regulator-suspend-min-microvolt = <3000000>; + }; + }; + + /* Core5_1V2 */ + ldo3_reg: LDO3 { + regulator-name = "LDO3"; + regulator-always-on; + regulator-boot-on; + }; + + ldo4_reg: LDO4 { + regulator-name = "LDO4"; + regulator-boot-on; + }; + + /* SPD_3V3 */ + ldo5_reg: LDO5 { + regulator-name = "LDO5"; + regulator-always-on; + regulator-boot-on; + }; + + /* DDR_0V6 */ + ldo6_reg: LDO6 { + regulator-name = "LDO6"; + regulator-always-on; + regulator-boot-on; + }; + + /* VDD_PWM */ + ldo7_reg: LDO7 { + regulator-name = "LDO7"; + regulator-always-on; + regulator-boot-on; + }; + + /* ldo_1v8 */ + ldo8_reg: LDO8 { + regulator-name = "LDO8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo9_reg: LDO9 { + regulator-name = "LDO9"; + regulator-boot-on; + }; + + ldo10_reg: LDO10 { + regulator-name = "LDO10"; + regulator-boot-on; + }; + + ldortc1_reg: LDORTC1 { + regulator-name = "LDORTC1"; + regulator-always-on; + regulator-boot-on; + }; + }; + }; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + pinctrl_gpio_keys: gpio-keysgrp { + fsl,pins = < + MX6SL_PAD_SD1_DAT1__GPIO5_IO08 0x17059 + MX6SL_PAD_SD1_DAT4__GPIO5_IO12 0x17059 + MX6SL_PAD_KEY_COL1__GPIO3_IO26 0x17059 + MX6SL_PAD_KEY_ROW0__GPIO3_IO25 0x17059 + >; + }; + + pinctrl_hog: hoggrp { + fsl,pins = < + MX6SL_PAD_LCD_DAT0__GPIO2_IO20 0x79 + MX6SL_PAD_LCD_DAT1__GPIO2_IO21 0x79 + MX6SL_PAD_LCD_DAT2__GPIO2_IO22 0x79 + MX6SL_PAD_LCD_DAT3__GPIO2_IO23 0x79 + MX6SL_PAD_LCD_DAT4__GPIO2_IO24 0x79 + MX6SL_PAD_LCD_DAT5__GPIO2_IO25 0x79 + MX6SL_PAD_LCD_DAT6__GPIO2_IO26 0x79 + MX6SL_PAD_LCD_DAT7__GPIO2_IO27 0x79 + MX6SL_PAD_LCD_DAT8__GPIO2_IO28 0x79 + MX6SL_PAD_LCD_DAT9__GPIO2_IO29 0x79 + MX6SL_PAD_LCD_DAT10__GPIO2_IO30 0x79 + MX6SL_PAD_LCD_DAT11__GPIO2_IO31 0x79 + MX6SL_PAD_LCD_DAT12__GPIO3_IO00 0x79 + MX6SL_PAD_LCD_DAT13__GPIO3_IO01 0x79 + MX6SL_PAD_LCD_DAT14__GPIO3_IO02 0x79 + MX6SL_PAD_LCD_DAT15__GPIO3_IO03 0x79 + MX6SL_PAD_LCD_DAT16__GPIO3_IO04 0x79 + MX6SL_PAD_LCD_DAT17__GPIO3_IO05 0x79 + MX6SL_PAD_LCD_DAT18__GPIO3_IO06 0x79 + MX6SL_PAD_LCD_DAT19__GPIO3_IO07 0x79 + MX6SL_PAD_LCD_DAT20__GPIO3_IO08 0x79 + MX6SL_PAD_LCD_DAT21__GPIO3_IO09 0x79 + MX6SL_PAD_LCD_DAT22__GPIO3_IO10 0x79 + MX6SL_PAD_LCD_DAT23__GPIO3_IO11 0x79 + MX6SL_PAD_LCD_CLK__GPIO2_IO15 0x79 + MX6SL_PAD_LCD_ENABLE__GPIO2_IO16 0x79 + MX6SL_PAD_LCD_HSYNC__GPIO2_IO17 0x79 + MX6SL_PAD_LCD_VSYNC__GPIO2_IO18 0x79 + MX6SL_PAD_LCD_RESET__GPIO2_IO19 0x79 + MX6SL_PAD_KEY_COL3__GPIO3_IO30 0x79 + MX6SL_PAD_KEY_ROW7__GPIO4_IO07 0x79 + MX6SL_PAD_ECSPI2_MOSI__GPIO4_IO13 0x79 + MX6SL_PAD_KEY_COL5__GPIO4_IO02 0x79 + MX6SL_PAD_KEY_ROW6__GPIO4_IO05 0x79 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6SL_PAD_I2C1_SCL__I2C1_SCL 0x4001f8b1 + MX6SL_PAD_I2C1_SDA__I2C1_SDA 0x4001f8b1 + >; + }; + + pinctrl_i2c1_sleep: i2c1grp-sleep { + fsl,pins = < + MX6SL_PAD_I2C1_SCL__I2C1_SCL 0x400108b1 + MX6SL_PAD_I2C1_SDA__I2C1_SDA 0x400108b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6SL_PAD_I2C2_SCL__I2C2_SCL 0x4001f8b1 + MX6SL_PAD_I2C2_SDA__I2C2_SDA 0x4001f8b1 + >; + }; + + pinctrl_i2c2_sleep: i2c2grp-sleep { + fsl,pins = < + MX6SL_PAD_I2C2_SCL__I2C2_SCL 0x400108b1 + MX6SL_PAD_I2C2_SDA__I2C2_SDA 0x400108b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6SL_PAD_REF_CLK_24M__I2C3_SCL 0x4001f8b1 + MX6SL_PAD_REF_CLK_32K__I2C3_SDA 0x4001f8b1 + >; + }; + + pinctrl_led: ledgrp { + fsl,pins = < + MX6SL_PAD_SD1_DAT2__GPIO5_IO13 0x17059 + >; + }; + + pinctrl_ricoh_gpio: ricoh_gpiogrp { + fsl,pins = < + MX6SL_PAD_SD1_CLK__GPIO5_IO15 0x1b8b1 /* ricoh619 chg */ + MX6SL_PAD_SD1_DAT0__GPIO5_IO11 0x1b8b1 /* ricoh619 irq */ + MX6SL_PAD_KEY_COL2__GPIO3_IO28 0x1b8b1 /* ricoh619 bat_low_int */ + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x1b0b1 + MX6SL_PAD_UART1_RXD__UART1_TX_DATA 0x1b0b1 + >; + }; + + pinctrl_usbotg1: usbotg1grp { + fsl,pins = < + MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x17059 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6SL_PAD_SD2_CMD__SD2_CMD 0x17059 + MX6SL_PAD_SD2_CLK__SD2_CLK 0x13059 + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x17059 + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x17059 + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x17059 + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x17059 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2grp-100mhz { + fsl,pins = < + MX6SL_PAD_SD2_CMD__SD2_CMD 0x170b9 + MX6SL_PAD_SD2_CLK__SD2_CLK 0x130b9 + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170b9 + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170b9 + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170b9 + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170b9 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2grp-200mhz { + fsl,pins = < + MX6SL_PAD_SD2_CMD__SD2_CMD 0x170f9 + MX6SL_PAD_SD2_CLK__SD2_CLK 0x130f9 + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170f9 + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170f9 + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170f9 + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170f9 + >; + }; + + pinctrl_usdhc2_sleep: usdhc2grp-sleep { + fsl,pins = < + MX6SL_PAD_SD2_CMD__GPIO5_IO04 0x100f9 + MX6SL_PAD_SD2_CLK__GPIO5_IO05 0x100f9 + MX6SL_PAD_SD2_DAT0__GPIO5_IO01 0x100f9 + MX6SL_PAD_SD2_DAT1__GPIO4_IO30 0x100f9 + MX6SL_PAD_SD2_DAT2__GPIO5_IO03 0x100f9 + MX6SL_PAD_SD2_DAT3__GPIO4_IO28 0x100f9 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6SL_PAD_SD3_CMD__SD3_CMD 0x11059 + MX6SL_PAD_SD3_CLK__SD3_CLK 0x11059 + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x11059 + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x11059 + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x11059 + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x11059 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3grp-100mhz { + fsl,pins = < + MX6SL_PAD_SD3_CMD__SD3_CMD 0x170b9 + MX6SL_PAD_SD3_CLK__SD3_CLK 0x170b9 + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170b9 + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170b9 + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170b9 + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170b9 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3grp-200mhz { + fsl,pins = < + MX6SL_PAD_SD3_CMD__SD3_CMD 0x170f9 + MX6SL_PAD_SD3_CLK__SD3_CLK 0x170f9 + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170f9 + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170f9 + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170f9 + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170f9 + >; + }; + + pinctrl_usdhc3_sleep: usdhc3grp-sleep { + fsl,pins = < + MX6SL_PAD_SD3_CMD__GPIO5_IO21 0x100c1 + MX6SL_PAD_SD3_CLK__GPIO5_IO18 0x100c1 + MX6SL_PAD_SD3_DAT0__GPIO5_IO19 0x100c1 + MX6SL_PAD_SD3_DAT1__GPIO5_IO20 0x100c1 + MX6SL_PAD_SD3_DAT2__GPIO5_IO16 0x100c1 + MX6SL_PAD_SD3_DAT3__GPIO5_IO17 0x100c1 + >; + }; + + pinctrl_wifi_power: wifi-powergrp { + fsl,pins = < + MX6SL_PAD_SD2_DAT6__GPIO4_IO29 0x10059 /* WIFI_3V3_ON */ + >; + }; + + pinctrl_wifi_reset: wifi-resetgrp { + fsl,pins = < + MX6SL_PAD_SD2_DAT7__GPIO5_IO00 0x10059 /* WIFI_RST */ + >; + }; + + pinctrl_zforce: zforcegrp { + fsl,pins = < + MX6SL_PAD_SD1_DAT3__GPIO5_IO06 0x17059 /* TP_INT */ + MX6SL_PAD_SD1_DAT5__GPIO5_IO09 0x10059 /* TP_RST */ + >; + }; +}; + +®_vdd1p1 { + vin-supply = <&dcdc2_reg>; +}; + +®_vdd2p5 { + vin-supply = <&dcdc2_reg>; +}; + +®_arm { + vin-supply = <&dcdc3_reg>; +}; + +®_soc { + vin-supply = <&dcdc1_reg>; +}; + +®_pu { + vin-supply = <&dcdc1_reg>; +}; + +&snvs_rtc { + /* + * We are using the RTC in the PMIC, but this one is not disabled + * in imx6sl.dtsi. + */ + status = "disabled"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + pinctrl-0 = <&pinctrl_usdhc2>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>; + pinctrl-3 = <&pinctrl_usdhc2_sleep>; + non-removable; + status = "okay"; + + /* internal uSD card */ +}; + +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + pinctrl-3 = <&pinctrl_usdhc3_sleep>; + vmmc-supply = <®_wifi>; + mmc-pwrseq = <&wifi_pwrseq>; + cap-power-off-card; + non-removable; + status = "okay"; + + /* + * 37NB-E60QF0+4A2: CyberTan WC121 (BCM43362) SDIO WiFi + * 37NB-E60QF0+4A3: RTL8189F SDIO WiFi + */ +}; + +&usbotg1 { + pinctrl-names = "default"; + disable-over-current; + srp-disable; + hnp-disable; + adp-disable; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 1c7180f28539..91a8c54d5e11 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -939,8 +939,10 @@ }; rngb: rngb@21b4000 { + compatible = "fsl,imx6sl-rngb", "fsl,imx25-rngb"; reg = <0x021b4000 0x4000>; interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX6SL_CLK_DUMMY>; }; weim: weim@21b8000 { diff --git a/arch/arm/boot/dts/imx6sll-evk.dts b/arch/arm/boot/dts/imx6sll-evk.dts index c755cbdb7cde..32b3d82fec53 100644 --- a/arch/arm/boot/dts/imx6sll-evk.dts +++ b/arch/arm/boot/dts/imx6sll-evk.dts @@ -132,6 +132,31 @@ }; }; }; + + sound { + compatible = "fsl,imx6sl-evk-wm8962", "fsl,imx-audio-wm8962"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hp>; + model = "wm8962-audio"; + audio-cpu = <&ssi2>; + audio-codec = <&wm8962>; + audio-routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "Ext Spk", "SPKOUTL", + "Ext Spk", "SPKOUTR", + "AMIC", "MICBIAS", + "IN3R", "AMIC"; + mux-int-port = <2>; + mux-ext-port = <3>; + hp-det-gpio = <&gpio4 24 GPIO_ACTIVE_LOW>; + }; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux3>; + status = "okay"; }; &cpu0 { @@ -247,6 +272,27 @@ }; }; +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + wm8962: audio-codec@1a { + compatible = "wlf,wm8962"; + reg = <0x1a>; + clocks = <&clks IMX6SLL_CLK_EXTERN_AUDIO>; + DCVDD-supply = <&vgen3_reg>; + DBVDD-supply = <®_aud3v>; + AVDD-supply = <&vgen3_reg>; + CPVDD-supply = <&vgen3_reg>; + MICVDD-supply = <®_aud3v>; + PLLVDD-supply = <&vgen3_reg>; + SPKVDD1-supply = <®_aud4v>; + SPKVDD2-supply = <®_aud4v>; + }; +}; + &lcdif { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lcd>; @@ -274,6 +320,10 @@ status = "okay"; }; +&ssi2 { + status = "okay"; +}; + &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; @@ -330,6 +380,22 @@ }; &iomuxc { + pinctrl_audmux3: audmux3grp { + fsl,pins = < + MX6SLL_PAD_AUD_TXC__AUD3_TXC 0x4130b0 + MX6SLL_PAD_AUD_TXFS__AUD3_TXFS 0x4130b0 + MX6SLL_PAD_AUD_TXD__AUD3_TXD 0x4110b0 + MX6SLL_PAD_AUD_RXD__AUD3_RXD 0x4130b0 + MX6SLL_PAD_AUD_MCLK__AUDIO_CLK_OUT 0x4130b0 + >; + }; + + pinctrl_hp: hpgrp { + fsl,pins = < + MX6SLL_PAD_GPIO4_IO24__GPIO4_IO24 0x17059 /* HP DETECT */ + >; + }; + pinctrl_reg_sd3_vmmc: sd3vmmcgrp { fsl,pins = < MX6SLL_PAD_KEY_COL6__GPIO4_IO04 0x17059 @@ -449,6 +515,13 @@ >; }; + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6SLL_PAD_AUD_RXFS__I2C3_SCL 0x4041b8b1 + MX6SLL_PAD_AUD_RXC__I2C3_SDA 0x4041b8b1 + >; + }; + pinctrl_lcd: lcdgrp { fsl,pins = < MX6SLL_PAD_LCD_DATA00__LCD_DATA00 0x79 diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi index fb5d3bc50c6b..0b622201a1f3 100644 --- a/arch/arm/boot/dts/imx6sll.dtsi +++ b/arch/arm/boot/dts/imx6sll.dtsi @@ -786,6 +786,13 @@ clocks = <&clks IMX6SLL_CLK_MMDC_P0_IPG>; }; + rngb: rng@21b4000 { + compatible = "fsl,imx6sll-rngb", "fsl,imx25-rngb"; + reg = <0x021b4000 0x4000>; + interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX6SLL_CLK_DUMMY>; + }; + ocotp: efuse@21bc000 { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx6sx-pinfunc.h b/arch/arm/boot/dts/imx6sx-pinfunc.h index 0b02c7e60c17..f4dc46207954 100644 --- a/arch/arm/boot/dts/imx6sx-pinfunc.h +++ b/arch/arm/boot/dts/imx6sx-pinfunc.h @@ -1026,7 +1026,7 @@ #define MX6SX_PAD_QSPI1B_DQS__SIM_M_HADDR_15 0x01B0 0x04F8 0x0000 0x7 0x0 #define MX6SX_PAD_QSPI1B_SCLK__QSPI1_B_SCLK 0x01B4 0x04FC 0x0000 0x0 0x0 #define MX6SX_PAD_QSPI1B_SCLK__UART3_DCE_RX 0x01B4 0x04FC 0x0840 0x1 0x4 -#define MX6SX_PAD_QSPI1B_SCLK__UART3_DTE_TX 0x01B4 0x04FC 0x0000 0x0 0x0 +#define MX6SX_PAD_QSPI1B_SCLK__UART3_DTE_TX 0x01B4 0x04FC 0x0000 0x1 0x0 #define MX6SX_PAD_QSPI1B_SCLK__ECSPI3_SCLK 0x01B4 0x04FC 0x0730 0x2 0x1 #define MX6SX_PAD_QSPI1B_SCLK__ESAI_RX_HF_CLK 0x01B4 0x04FC 0x0780 0x3 0x2 #define MX6SX_PAD_QSPI1B_SCLK__CSI1_DATA_16 0x01B4 0x04FC 0x06DC 0x4 0x1 diff --git a/arch/arm/boot/dts/imx6sx-sdb.dtsi b/arch/arm/boot/dts/imx6sx-sdb.dtsi index b8c23eba9dc7..1351d7f70a54 100644 --- a/arch/arm/boot/dts/imx6sx-sdb.dtsi +++ b/arch/arm/boot/dts/imx6sx-sdb.dtsi @@ -153,6 +153,8 @@ sound { compatible = "fsl,imx6sx-sdb-wm8962", "fsl,imx-audio-wm8962"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hp>; model = "wm8962-audio"; ssi-controller = <&ssi2>; audio-codec = <&codec>; @@ -165,6 +167,7 @@ "IN3R", "AMIC"; mux-int-port = <2>; mux-ext-port = <6>; + hp-det-gpio = <&gpio1 17 GPIO_ACTIVE_LOW>; }; panel { @@ -468,6 +471,12 @@ >; }; + pinctrl_hp: hpgrp { + fsl,pins = < + MX6SX_PAD_CSI_DATA03__GPIO1_IO_17 0x17059 + >; + }; + pinctrl_i2c1: i2c1grp { fsl,pins = < MX6SX_PAD_GPIO1_IO01__I2C1_SDA 0x4001b8b1 diff --git a/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts b/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts index d25e27d0315f..5547916870c7 100644 --- a/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts +++ b/arch/arm/boot/dts/imx6sx-softing-vining-2000.dts @@ -93,7 +93,7 @@ &ecspi4 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi4>; - cs-gpios = <&gpio7 4 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio7 4 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi index b480dfa9e251..dfdca1804f9f 100644 --- a/arch/arm/boot/dts/imx6sx.dtsi +++ b/arch/arm/boot/dts/imx6sx.dtsi @@ -213,7 +213,7 @@ clocks = <&clks IMX6SX_CLK_APBH_DMA>; }; - gpmi: gpmi-nand@1806000{ + gpmi: nand-controller@1806000{ compatible = "fsl,imx6sx-gpmi-nand"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx6ul-kontron-n6x1x-s.dtsi b/arch/arm/boot/dts/imx6ul-kontron-n6x1x-s.dtsi index a35be2a369b3..770f59b23102 100644 --- a/arch/arm/boot/dts/imx6ul-kontron-n6x1x-s.dtsi +++ b/arch/arm/boot/dts/imx6ul-kontron-n6x1x-s.dtsi @@ -84,7 +84,7 @@ }; &ecspi1 { - cs-gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 26 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6ul-kontron-n6x1x-som-common.dtsi b/arch/arm/boot/dts/imx6ul-kontron-n6x1x-som-common.dtsi index 61ba21a605a8..2a449a3c1ae2 100644 --- a/arch/arm/boot/dts/imx6ul-kontron-n6x1x-som-common.dtsi +++ b/arch/arm/boot/dts/imx6ul-kontron-n6x1x-som-common.dtsi @@ -14,7 +14,7 @@ }; &ecspi2 { - cs-gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6ul-phytec-segin.dtsi b/arch/arm/boot/dts/imx6ul-phytec-segin.dtsi index 8d5f8dc6ad58..f1513e676c2f 100644 --- a/arch/arm/boot/dts/imx6ul-phytec-segin.dtsi +++ b/arch/arm/boot/dts/imx6ul-phytec-segin.dtsi @@ -106,7 +106,7 @@ &ecspi3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; - cs-gpios = <&gpio1 20 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi index 2b088f210331..d7d9f3e46b92 100644 --- a/arch/arm/boot/dts/imx6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul.dtsi @@ -174,7 +174,7 @@ clocks = <&clks IMX6UL_CLK_APBHDMA>; }; - gpmi: gpmi-nand@1806000 { + gpmi: nand-controller@1806000 { compatible = "fsl,imx6q-gpmi-nand"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx6ull-colibri.dtsi b/arch/arm/boot/dts/imx6ull-colibri.dtsi index 6cf95939121d..4436556624d6 100644 --- a/arch/arm/boot/dts/imx6ull-colibri.dtsi +++ b/arch/arm/boot/dts/imx6ull-colibri.dtsi @@ -68,7 +68,7 @@ /* Colibri SPI */ &ecspi1 { - cs-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio3 26 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>; }; diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi index fcde7f77ae42..9bf67490ac49 100644 --- a/arch/arm/boot/dts/imx6ull.dtsi +++ b/arch/arm/boot/dts/imx6ull.dtsi @@ -68,6 +68,13 @@ clock-names = "dcp"; }; + rngb: rng@2284000 { + compatible = "fsl,imx6ull-rngb", "fsl,imx25-rngb"; + reg = <0x02284000 0x4000>; + interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX6UL_CLK_DUMMY>; + }; + iomuxc_snvs: iomuxc-snvs@2290000 { compatible = "fsl,imx6ull-iomuxc-snvs"; reg = <0x02290000 0x4000>; diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi index e18e89dec879..62b771c1d5a9 100644 --- a/arch/arm/boot/dts/imx7-colibri.dtsi +++ b/arch/arm/boot/dts/imx7-colibri.dtsi @@ -60,7 +60,7 @@ &ecspi3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3 &pinctrl_ecspi3_cs>; - cs-gpios = <&gpio4 11 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; }; &fec1 { diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts index 17cca8a9f77b..ac0751bc1177 100644 --- a/arch/arm/boot/dts/imx7d-sdb.dts +++ b/arch/arm/boot/dts/imx7d-sdb.dts @@ -146,6 +146,24 @@ }; }; }; + + sound { + compatible = "fsl,imx7d-evk-wm8960", + "fsl,imx-audio-wm8960"; + model = "wm8960-audio"; + audio-cpu = <&sai1>; + audio-codec = <&codec>; + hp-det-gpio = <&gpio2 28 GPIO_ACTIVE_HIGH>; + audio-routing = + "Headphone Jack", "HP_L", + "Headphone Jack", "HP_R", + "Ext Spk", "SPK_LP", + "Ext Spk", "SPK_LN", + "Ext Spk", "SPK_RP", + "Ext Spk", "SPK_RN", + "LINPUT1", "AMIC", + "AMIC", "MICB"; + }; }; &adc1 { @@ -169,7 +187,7 @@ &ecspi3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; - cs-gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; status = "okay"; tsc2046@0 { @@ -363,6 +381,13 @@ clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; clock-names = "mclk"; wlf,shared-lrclk; + wlf,hp-cfg = <2 2 3>; + wlf,gpio-cfg = <1 3>; + assigned-clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_SRC>, + <&clks IMX7D_PLL_AUDIO_POST_DIV>, + <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>; + assigned-clock-rates = <0>, <884736000>, <12288000>; }; }; @@ -391,6 +416,28 @@ vin-supply = <&sw2_reg>; }; +&sai1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai1>; + assigned-clocks = <&clks IMX7D_SAI1_ROOT_SRC>, + <&clks IMX7D_PLL_AUDIO_POST_DIV>, + <&clks IMX7D_SAI1_ROOT_CLK>; + assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>; + assigned-clock-rates = <0>, <884736000>, <36864000>; + status = "okay"; +}; + +&sai3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai3 &pinctrl_sai3_mclk>; + assigned-clocks = <&clks IMX7D_SAI3_ROOT_SRC>, + <&clks IMX7D_PLL_AUDIO_POST_DIV>, + <&clks IMX7D_SAI3_ROOT_CLK>; + assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>; + assigned-clock-rates = <0>, <884736000>, <36864000>; + status = "okay"; +}; + &snvs_pwrkey { status = "okay"; }; @@ -550,6 +597,7 @@ pinctrl_hog: hoggrp { fsl,pins = < MX7D_PAD_ECSPI2_SS0__GPIO4_IO23 0x34 /* bt reg on */ + MX7D_PAD_EPDC_BDR0__GPIO2_IO28 0x59 /* headphone detect */ >; }; @@ -615,6 +663,33 @@ >; }; + pinctrl_sai1: sai1grp { + fsl,pins = < + MX7D_PAD_SAI1_MCLK__SAI1_MCLK 0x1f + MX7D_PAD_ENET1_RX_CLK__SAI1_TX_BCLK 0x1f + MX7D_PAD_ENET1_CRS__SAI1_TX_SYNC 0x1f + MX7D_PAD_ENET1_COL__SAI1_TX_DATA0 0x30 + MX7D_PAD_ENET1_TX_CLK__SAI1_RX_DATA0 0x1f + >; + }; + + pinctrl_sai2: sai2grp { + fsl,pins = < + MX7D_PAD_SAI2_TX_BCLK__SAI2_TX_BCLK 0x1f + MX7D_PAD_SAI2_TX_SYNC__SAI2_TX_SYNC 0x1f + MX7D_PAD_SAI2_TX_DATA__SAI2_TX_DATA0 0x30 + MX7D_PAD_SAI2_RX_DATA__SAI2_RX_DATA0 0x1f + >; + }; + + pinctrl_sai3: sai3grp { + fsl,pins = < + MX7D_PAD_UART3_TX_DATA__SAI3_TX_BCLK 0x1f + MX7D_PAD_UART3_CTS_B__SAI3_TX_SYNC 0x1f + MX7D_PAD_UART3_RTS_B__SAI3_TX_DATA0 0x30 + >; + }; + pinctrl_spi4: spi4grp { fsl,pins = < MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x59 @@ -776,4 +851,10 @@ MX7D_PAD_LPSR_GPIO1_IO07__GPIO1_IO7 0x14 >; }; + + pinctrl_sai3_mclk: sai3grp_mclk { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO03__SAI3_MCLK 0x1f + >; + }; }; diff --git a/arch/arm/boot/dts/imx7d-zii-rmu2.dts b/arch/arm/boot/dts/imx7d-zii-rmu2.dts index e5e20b07f184..1065941807e8 100644 --- a/arch/arm/boot/dts/imx7d-zii-rmu2.dts +++ b/arch/arm/boot/dts/imx7d-zii-rmu2.dts @@ -39,7 +39,7 @@ &ecspi1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; - cs-gpios = <&gpio4 19 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 19 GPIO_ACTIVE_LOW>; status = "okay"; flash@0 { @@ -58,7 +58,7 @@ <&clks IMX7D_ENET1_TIME_ROOT_CLK>; assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>; assigned-clock-rates = <0>, <100000000>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-handle = <&fec1_phy>; status = "okay"; diff --git a/arch/arm/boot/dts/imx7d-zii-rpu2.dts b/arch/arm/boot/dts/imx7d-zii-rpu2.dts index cbf0dbb4c198..893bd30aa2a3 100644 --- a/arch/arm/boot/dts/imx7d-zii-rpu2.dts +++ b/arch/arm/boot/dts/imx7d-zii-rpu2.dts @@ -193,7 +193,7 @@ &ecspi1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; - cs-gpios = <&gpio4 19 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio4 19 GPIO_ACTIVE_LOW>; status = "okay"; flash@0 { diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index 1cfaf410aa43..84d9cc13afb9 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi @@ -1162,6 +1162,19 @@ status = "disabled"; }; + qspi: spi@30bb0000 { + compatible = "fsl,imx7d-qspi"; + reg = <0x30bb0000 0x10000>, <0x60000000 0x10000000>; + reg-names = "QuadSPI", "QuadSPI-memory"; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX7D_QSPI_ROOT_CLK>, + <&clks IMX7D_QSPI_ROOT_CLK>; + clock-names = "qspi_en", "qspi"; + status = "disabled"; + }; + sdma: sdma@30bd0000 { compatible = "fsl,imx7d-sdma", "fsl,imx35-sdma"; reg = <0x30bd0000 0x10000>; @@ -1208,7 +1221,7 @@ clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>; }; - gpmi: gpmi-nand@33002000{ + gpmi: nand-controller@33002000{ compatible = "fsl,imx7d-gpmi-nand"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/imx7ulp.dtsi b/arch/arm/boot/dts/imx7ulp.dtsi index 367439639da9..b7ea37ad4e55 100644 --- a/arch/arm/boot/dts/imx7ulp.dtsi +++ b/arch/arm/boot/dts/imx7ulp.dtsi @@ -394,7 +394,7 @@ clocks = <&pcc2 IMX7ULP_CLK_RGPIO2P1>, <&pcc3 IMX7ULP_CLK_PCTLC>; clock-names = "gpio", "port"; - gpio-ranges = <&iomuxc1 0 0 32>; + gpio-ranges = <&iomuxc1 0 0 20>; }; gpio_ptd: gpio@40af0000 { @@ -408,7 +408,7 @@ clocks = <&pcc2 IMX7ULP_CLK_RGPIO2P1>, <&pcc3 IMX7ULP_CLK_PCTLD>; clock-names = "gpio", "port"; - gpio-ranges = <&iomuxc1 0 32 32>; + gpio-ranges = <&iomuxc1 0 32 12>; }; gpio_pte: gpio@40b00000 { @@ -422,7 +422,7 @@ clocks = <&pcc2 IMX7ULP_CLK_RGPIO2P1>, <&pcc3 IMX7ULP_CLK_PCTLE>; clock-names = "gpio", "port"; - gpio-ranges = <&iomuxc1 0 64 32>; + gpio-ranges = <&iomuxc1 0 64 16>; }; gpio_ptf: gpio@40b10000 { @@ -436,7 +436,7 @@ clocks = <&pcc2 IMX7ULP_CLK_RGPIO2P1>, <&pcc3 IMX7ULP_CLK_PCTLF>; clock-names = "gpio", "port"; - gpio-ranges = <&iomuxc1 0 96 32>; + gpio-ranges = <&iomuxc1 0 96 20>; }; }; diff --git a/arch/arm/boot/dts/iwg20d-q7-common.dtsi b/arch/arm/boot/dts/iwg20d-q7-common.dtsi index ebbe1518ef8a..63cafd220dba 100644 --- a/arch/arm/boot/dts/iwg20d-q7-common.dtsi +++ b/arch/arm/boot/dts/iwg20d-q7-common.dtsi @@ -57,7 +57,7 @@ lvds-receiver { compatible = "ti,ds90cf384a", "lvds-decoder"; - powerdown-gpios = <&gpio7 25 GPIO_ACTIVE_LOW>; + power-supply = <&vcc_3v3_tft1>; ports { #address-cells = <1>; @@ -81,6 +81,7 @@ panel { compatible = "edt,etm0700g0dh6"; backlight = <&lcd_backlight>; + power-supply = <&vcc_3v3_tft1>; port { panel_in: endpoint { @@ -113,6 +114,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 = <&gpio7 25 GPIO_ACTIVE_HIGH>; + }; + vcc_sdhi1: regulator-vcc-sdhi1 { compatible = "regulator-fixed"; @@ -207,6 +219,7 @@ reg = <0x38>; interrupt-parent = <&gpio2>; interrupts = <12 IRQ_TYPE_EDGE_FALLING>; + vcc-supply = <&vcc_3v3_tft1>; }; }; diff --git a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi index 100396f6c2fe..7d0468a23781 100644 --- a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi +++ b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi @@ -51,6 +51,8 @@ &mcbsp2 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&mcbsp2_pins>; }; &charger { @@ -77,7 +79,7 @@ }; &dss { - status = "ok"; + status = "okay"; vdds_dsi-supply = <&vpll2>; vdda_video-supply = <&video_reg>; pinctrl-names = "default"; @@ -102,35 +104,18 @@ regulator-max-microvolt = <3300000>; }; - lcd0: display@0 { - compatible = "panel-dpi"; - label = "28"; - status = "okay"; - /* default-on; */ + lcd0: display { + /* This isn't the exact LCD, but the timings meet spec */ + compatible = "logicpd,type28"; pinctrl-names = "default"; pinctrl-0 = <&lcd_enable_pin>; - enable-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>; /* gpio155, lcd INI */ + backlight = <&bl>; + enable-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>; port { lcd_in: endpoint { remote-endpoint = <&dpi_out>; }; }; - - panel-timing { - clock-frequency = <9000000>; - hactive = <480>; - vactive = <272>; - hfront-porch = <3>; - hback-porch = <2>; - hsync-len = <42>; - vback-porch = <3>; - vfront-porch = <2>; - vsync-len = <11>; - hsync-active = <1>; - vsync-active = <1>; - de-active = <1>; - pixelclk-active = <0>; - }; }; bl: backlight { diff --git a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi index 381f0e82bb70..533a47bc4a53 100644 --- a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi +++ b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi @@ -81,6 +81,8 @@ }; &mcbsp2 { + pinctrl-names = "default"; + pinctrl-0 = <&mcbsp2_pins>; status = "okay"; }; @@ -113,7 +115,7 @@ }; &dss { - status = "ok"; + status = "okay"; vdds_dsi-supply = <&vpll2>; vdda_video-supply = <&vpll2>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 069af9a19bb6..827373ef1a54 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -182,7 +182,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x0 0x1550000 0x0 0x10000>, - <0x0 0x40000000 0x0 0x40000000>; + <0x0 0x40000000 0x0 0x20000000>; reg-names = "QuadSPI", "QuadSPI-memory"; interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; clock-names = "qspi_en", "qspi"; diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi index eadb0832bcfc..7649dd1e0b9e 100644 --- a/arch/arm/boot/dts/meson.dtsi +++ b/arch/arm/boot/dts/meson.dtsi @@ -11,13 +11,6 @@ #size-cells = <1>; interrupt-parent = <&gic>; - L2: cache-controller@c4200000 { - compatible = "arm,pl310-cache"; - reg = <0xc4200000 0x1000>; - cache-unified; - cache-level = <2>; - }; - soc { compatible = "simple-bus"; #address-cells = <1>; @@ -172,6 +165,13 @@ }; }; + L2: cache-controller@c4200000 { + compatible = "arm,pl310-cache"; + reg = <0xc4200000 0x1000>; + cache-unified; + cache-level = <2>; + }; + periph: bus@c4300000 { compatible = "simple-bus"; reg = <0xc4300000 0x10000>; diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi index 277c0bb10453..04688e8abce2 100644 --- a/arch/arm/boot/dts/meson8.dtsi +++ b/arch/arm/boot/dts/meson8.dtsi @@ -240,8 +240,6 @@ <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>, diff --git a/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/motorola-mapphone-common.dtsi index 1990239cc6af..d5ded4f794df 100644 --- a/arch/arm/boot/dts/motorola-mapphone-common.dtsi +++ b/arch/arm/boot/dts/motorola-mapphone-common.dtsi @@ -207,8 +207,9 @@ }; }; - lcd0: display { - compatible = "panel-dsi-cm"; + lcd0: panel@0 { + compatible = "motorola,droid4-panel", "panel-dsi-cm"; + reg = <0>; label = "lcd0"; vddi-supply = <&lcd_regulator>; reset-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>; /* gpio101 */ @@ -217,6 +218,7 @@ width-mm = <50>; height-mm = <89>; + rotation = <90>; panel-timing { clock-frequency = <0>; /* Calculated by dsi */ diff --git a/arch/arm/boot/dts/mpa1600.dts b/arch/arm/boot/dts/mpa1600.dts index a5c91c240db9..005c2758e229 100644 --- a/arch/arm/boot/dts/mpa1600.dts +++ b/arch/arm/boot/dts/mpa1600.dts @@ -11,7 +11,7 @@ model = "Phontech MPA 1600"; compatible = "phontech,mpa1600", "atmel,at91rm9200"; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; diff --git a/arch/arm/boot/dts/mps2.dtsi b/arch/arm/boot/dts/mps2.dtsi index 96fb5a5cf4d3..37f5023f529c 100644 --- a/arch/arm/boot/dts/mps2.dtsi +++ b/arch/arm/boot/dts/mps2.dtsi @@ -161,9 +161,11 @@ }; timer2: dual-timer@2000 { - compatible = "arm,sp804"; + compatible = "arm,sp804", "arm,primecell"; reg = <0x2000 0x1000>; - clocks = <&sysclk>; + clocks = <&sysclk>, <&sysclk>, <&sysclk>; + clock-names = "timer0clk", "timer1clk", + "apb_pclk"; interrupts = <10>; status = "disabled"; }; @@ -197,8 +199,8 @@ arm,primecell-periphid = <0x00141805>; reg = <0x8000 0x1000>; interrupts = <0>; - clocks = <&sysclk>; - clock-names = "apb_pclk"; + clocks = <&sysclk>, <&sysclk>; + clock-names = "wdog_clk", "apb_pclk"; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/infinity-msc313-breadbee_crust.dts b/arch/arm/boot/dts/mstar-infinity-msc313-breadbee_crust.dts index f24c5580d3e4..f9db2ff86f2d 100644 --- a/arch/arm/boot/dts/infinity-msc313-breadbee_crust.dts +++ b/arch/arm/boot/dts/mstar-infinity-msc313-breadbee_crust.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include "infinity-msc313.dtsi" +#include "mstar-infinity-msc313.dtsi" / { model = "BreadBee Crust"; diff --git a/arch/arm/boot/dts/infinity3-msc313e.dtsi b/arch/arm/boot/dts/mstar-infinity-msc313.dtsi index 4e7239afd823..3499fde263be 100644 --- a/arch/arm/boot/dts/infinity3-msc313e.dtsi +++ b/arch/arm/boot/dts/mstar-infinity-msc313.dtsi @@ -4,7 +4,7 @@ * Author: Daniel Palmer <daniel@thingy.jp> */ -#include "infinity3.dtsi" +#include "mstar-infinity.dtsi" / { memory@20000000 { diff --git a/arch/arm/boot/dts/infinity.dtsi b/arch/arm/boot/dts/mstar-infinity.dtsi index cd911adef014..cd911adef014 100644 --- a/arch/arm/boot/dts/infinity.dtsi +++ b/arch/arm/boot/dts/mstar-infinity.dtsi diff --git a/arch/arm/boot/dts/infinity3-msc313e-breadbee.dts b/arch/arm/boot/dts/mstar-infinity3-msc313e-breadbee.dts index 1f93401c8530..f0eda80a95cc 100644 --- a/arch/arm/boot/dts/infinity3-msc313e-breadbee.dts +++ b/arch/arm/boot/dts/mstar-infinity3-msc313e-breadbee.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include "infinity3-msc313e.dtsi" +#include "mstar-infinity3-msc313e.dtsi" / { model = "BreadBee"; diff --git a/arch/arm/boot/dts/mercury5-ssc8336n.dtsi b/arch/arm/boot/dts/mstar-infinity3-msc313e.dtsi index 7d4a4630c25c..f581b6f89555 100644 --- a/arch/arm/boot/dts/mercury5-ssc8336n.dtsi +++ b/arch/arm/boot/dts/mstar-infinity3-msc313e.dtsi @@ -4,7 +4,7 @@ * Author: Daniel Palmer <daniel@thingy.jp> */ -#include "mercury5.dtsi" +#include "mstar-infinity3.dtsi" / { memory@20000000 { diff --git a/arch/arm/boot/dts/infinity3.dtsi b/arch/arm/boot/dts/mstar-infinity3.dtsi index 9b918c802654..9857e2a9934d 100644 --- a/arch/arm/boot/dts/infinity3.dtsi +++ b/arch/arm/boot/dts/mstar-infinity3.dtsi @@ -4,7 +4,7 @@ * Author: Daniel Palmer <daniel@thingy.jp> */ -#include "infinity.dtsi" +#include "mstar-infinity.dtsi" &imi { reg = <0xa0000000 0x20000>; diff --git a/arch/arm/boot/dts/mercury5-ssc8336n-midrived08.dts b/arch/arm/boot/dts/mstar-mercury5-ssc8336n-midrived08.dts index f24bd8cb8e60..7306b737d9c4 100644 --- a/arch/arm/boot/dts/mercury5-ssc8336n-midrived08.dts +++ b/arch/arm/boot/dts/mstar-mercury5-ssc8336n-midrived08.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include "mercury5-ssc8336n.dtsi" +#include "mstar-mercury5-ssc8336n.dtsi" / { model = "70mai Midrive D08"; diff --git a/arch/arm/boot/dts/infinity-msc313.dtsi b/arch/arm/boot/dts/mstar-mercury5-ssc8336n.dtsi index 42f2b5552c77..3f5a4c029744 100644 --- a/arch/arm/boot/dts/infinity-msc313.dtsi +++ b/arch/arm/boot/dts/mstar-mercury5-ssc8336n.dtsi @@ -4,7 +4,7 @@ * Author: Daniel Palmer <daniel@thingy.jp> */ -#include "infinity.dtsi" +#include "mstar-mercury5.dtsi" / { memory@20000000 { diff --git a/arch/arm/boot/dts/mercury5.dtsi b/arch/arm/boot/dts/mstar-mercury5.dtsi index a7d0dd9d6132..a7d0dd9d6132 100644 --- a/arch/arm/boot/dts/mercury5.dtsi +++ b/arch/arm/boot/dts/mstar-mercury5.dtsi diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi index 3b7b9b793736..f07880561e11 100644 --- a/arch/arm/boot/dts/mstar-v7.dtsi +++ b/arch/arm/boot/dts/mstar-v7.dtsi @@ -85,6 +85,25 @@ mask = <0x79>; }; + intc_fiq: interrupt-controller@201310 { + compatible = "mstar,mst-intc"; + reg = <0x201310 0x40>; + #interrupt-cells = <3>; + interrupt-controller; + interrupt-parent = <&gic>; + mstar,irqs-map-range = <96 127>; + }; + + intc_irq: interrupt-controller@201350 { + compatible = "mstar,mst-intc"; + reg = <0x201350 0x40>; + #interrupt-cells = <3>; + interrupt-controller; + interrupt-parent = <&gic>; + mstar,irqs-map-range = <32 95>; + mstar,intc-no-eoi; + }; + l3bridge: l3bridge@204400 { compatible = "mstar,l3bridge"; reg = <0x204400 0x200>; @@ -94,6 +113,7 @@ compatible = "ns16550a"; reg = <0x221000 0x100>; reg-shift = <3>; + interrupts-extended = <&intc_irq GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; clock-frequency = <172000000>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi index 39b3a2f4bef4..fade14284017 100644 --- a/arch/arm/boot/dts/mt2701.dtsi +++ b/arch/arm/boot/dts/mt2701.dtsi @@ -569,6 +569,19 @@ <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>; }; + jpegenc: jpegenc@1500a000 { + compatible = "mediatek,mt2701-jpgenc", + "mediatek,mtk-jpgenc"; + reg = <0 0x1500a000 0 0x1000>; + interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_LOW>; + clocks = <&imgsys CLK_IMG_VENC>; + clock-names = "jpgenc"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; + mediatek,larb = <&larb2>; + iommus = <&iommu MT2701_M4U_PORT_JPGENC_RDMA>, + <&iommu MT2701_M4U_PORT_JPGENC_BSDMA>; + }; + vdecsys: syscon@16000000 { compatible = "mediatek,mt2701-vdecsys", "syscon"; reg = <0 0x16000000 0 0x1000>; diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi index 3a6b856e5b74..aea6809500d7 100644 --- a/arch/arm/boot/dts/mt7623.dtsi +++ b/arch/arm/boot/dts/mt7623.dtsi @@ -14,7 +14,6 @@ #include <dt-bindings/power/mt2701-power.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/phy/phy.h> -#include <dt-bindings/memory/mt2701-larb-port.h> #include <dt-bindings/reset/mt2701-resets.h> #include <dt-bindings/thermal/thermal.h> @@ -297,17 +296,6 @@ clock-names = "system-clk", "rtc-clk"; }; - smi_common: smi@1000c000 { - compatible = "mediatek,mt7623-smi-common", - "mediatek,mt2701-smi-common"; - reg = <0 0x1000c000 0 0x1000>; - clocks = <&infracfg CLK_INFRA_SMI>, - <&mmsys CLK_MM_SMI_COMMON>, - <&infracfg CLK_INFRA_SMI>; - clock-names = "apb", "smi", "async"; - power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; - }; - pwrap: pwrap@1000d000 { compatible = "mediatek,mt7623-pwrap", "mediatek,mt2701-pwrap"; @@ -339,17 +327,6 @@ reg = <0 0x10200100 0 0x1c>; }; - iommu: mmsys_iommu@10205000 { - compatible = "mediatek,mt7623-m4u", - "mediatek,mt2701-m4u"; - reg = <0 0x10205000 0 0x1000>; - interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_LOW>; - clocks = <&infracfg CLK_INFRA_M4U>; - clock-names = "bclk"; - mediatek,larbs = <&larb0 &larb1 &larb2>; - #iommu-cells = <1>; - }; - efuse: efuse@10206000 { compatible = "mediatek,mt7623-efuse", "mediatek,mt8173-efuse"; @@ -725,94 +702,6 @@ status = "disabled"; }; - g3dsys: syscon@13000000 { - compatible = "mediatek,mt7623-g3dsys", - "mediatek,mt2701-g3dsys", - "syscon"; - reg = <0 0x13000000 0 0x200>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - - mali: gpu@13040000 { - compatible = "mediatek,mt7623-mali", "arm,mali-450"; - reg = <0 0x13040000 0 0x30000>; - interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_LOW>, - <GIC_SPI 171 IRQ_TYPE_LEVEL_LOW>, - <GIC_SPI 172 IRQ_TYPE_LEVEL_LOW>, - <GIC_SPI 173 IRQ_TYPE_LEVEL_LOW>, - <GIC_SPI 174 IRQ_TYPE_LEVEL_LOW>, - <GIC_SPI 175 IRQ_TYPE_LEVEL_LOW>, - <GIC_SPI 176 IRQ_TYPE_LEVEL_LOW>, - <GIC_SPI 177 IRQ_TYPE_LEVEL_LOW>, - <GIC_SPI 178 IRQ_TYPE_LEVEL_LOW>, - <GIC_SPI 179 IRQ_TYPE_LEVEL_LOW>, - <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>; - interrupt-names = "gp", "gpmmu", "pp0", "ppmmu0", "pp1", - "ppmmu1", "pp2", "ppmmu2", "pp3", "ppmmu3", - "pp"; - clocks = <&topckgen CLK_TOP_MMPLL>, - <&g3dsys CLK_G3DSYS_CORE>; - clock-names = "bus", "core"; - power-domains = <&scpsys MT2701_POWER_DOMAIN_MFG>; - resets = <&g3dsys MT2701_G3DSYS_CORE_RST>; - }; - - mmsys: syscon@14000000 { - compatible = "mediatek,mt7623-mmsys", - "mediatek,mt2701-mmsys", - "syscon"; - reg = <0 0x14000000 0 0x1000>; - #clock-cells = <1>; - }; - - larb0: larb@14010000 { - compatible = "mediatek,mt7623-smi-larb", - "mediatek,mt2701-smi-larb"; - reg = <0 0x14010000 0 0x1000>; - mediatek,smi = <&smi_common>; - mediatek,larb-id = <0>; - clocks = <&mmsys CLK_MM_SMI_LARB0>, - <&mmsys CLK_MM_SMI_LARB0>; - clock-names = "apb", "smi"; - power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; - }; - - imgsys: syscon@15000000 { - compatible = "mediatek,mt7623-imgsys", - "mediatek,mt2701-imgsys", - "syscon"; - reg = <0 0x15000000 0 0x1000>; - #clock-cells = <1>; - }; - - larb2: larb@15001000 { - compatible = "mediatek,mt7623-smi-larb", - "mediatek,mt2701-smi-larb"; - reg = <0 0x15001000 0 0x1000>; - mediatek,smi = <&smi_common>; - mediatek,larb-id = <2>; - clocks = <&imgsys CLK_IMG_SMI_COMM>, - <&imgsys CLK_IMG_SMI_COMM>; - clock-names = "apb", "smi"; - power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; - }; - - jpegdec: jpegdec@15004000 { - compatible = "mediatek,mt7623-jpgdec", - "mediatek,mt2701-jpgdec"; - reg = <0 0x15004000 0 0x1000>; - interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_LOW>; - clocks = <&imgsys CLK_IMG_JPGDEC_SMI>, - <&imgsys CLK_IMG_JPGDEC>; - clock-names = "jpgdec-smi", - "jpgdec"; - power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; - mediatek,larb = <&larb2>; - iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>, - <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>; - }; - vdecsys: syscon@16000000 { compatible = "mediatek,mt7623-vdecsys", "mediatek,mt2701-vdecsys", @@ -821,18 +710,6 @@ #clock-cells = <1>; }; - larb1: larb@16010000 { - compatible = "mediatek,mt7623-smi-larb", - "mediatek,mt2701-smi-larb"; - reg = <0 0x16010000 0 0x1000>; - mediatek,smi = <&smi_common>; - mediatek,larb-id = <1>; - clocks = <&vdecsys CLK_VDEC_CKGEN>, - <&vdecsys CLK_VDEC_LARB>; - clock-names = "apb", "smi"; - power-domains = <&scpsys MT2701_POWER_DOMAIN_VDEC>; - }; - hifsys: syscon@1a000000 { compatible = "mediatek,mt7623-hifsys", "mediatek,mt2701-hifsys", diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts index 2b760f90f38c..e96aa0ed1ebd 100644 --- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts @@ -6,7 +6,7 @@ /dts-v1/; #include <dt-bindings/input/input.h> -#include "mt7623.dtsi" +#include "mt7623n.dtsi" #include "mt6323.dtsi" / { @@ -21,6 +21,19 @@ stdout-path = "serial2:115200n8"; }; + connector { + compatible = "hdmi-connector"; + label = "hdmi"; + type = "d"; + ddc-i2c-bus = <&hdmiddc0>; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi0_out>; + }; + }; + }; + cpus { cpu@0 { proc-supply = <&mt6323_vproc_reg>; @@ -66,6 +79,13 @@ regulator-always-on; }; + reg_vgpu: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "vdd_fixed_vgpu"; + regulator-min-microvolt = <1150000>; + regulator-max-microvolt = <1150000>; + }; + gpio-keys { compatible = "gpio-keys"; pinctrl-names = "default"; @@ -114,10 +134,18 @@ }; }; +&bls { + status = "okay"; +}; + &btif { status = "okay"; }; +&cec { + status = "okay"; +}; + &cir { pinctrl-names = "default"; pinctrl-0 = <&cir_pins_a>; @@ -128,6 +156,21 @@ status = "okay"; }; +&dpi0 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + dpi0_out: endpoint { + remote-endpoint = <&hdmi0_in>; + }; + }; + }; +}; + ð { status = "okay"; @@ -192,6 +235,7 @@ fixed-link { speed = <1000>; full-duplex; + pause; }; }; }; @@ -199,6 +243,42 @@ }; }; +&hdmi0 { + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_pins_a>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + hdmi0_in: endpoint { + remote-endpoint = <&dpi0_out>; + }; + }; + + port@1 { + reg = <1>; + hdmi0_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; + }; + }; +}; + +&hdmiddc0 { + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_ddc_pins_a>; + status = "okay"; +}; + +&hdmi_phy { + mediatek,ibias = <0xa>; + mediatek,ibias_up = <0x1c>; + status = "okay"; +}; + &i2c0 { pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins_a>; @@ -211,6 +291,11 @@ status = "okay"; }; +&mali { + mali-supply = <®_vgpu>; + status = "okay"; +}; + &mmc0 { pinctrl-names = "default", "state_uhs"; pinctrl-0 = <&mmc0_pins_default>; @@ -330,4 +415,3 @@ &u3phy2 { status = "okay"; }; - diff --git a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts index 0447748f9fa0..1b9b9a8145a7 100644 --- a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts +++ b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts @@ -7,7 +7,7 @@ /dts-v1/; #include <dt-bindings/input/input.h> -#include "mt7623.dtsi" +#include "mt7623n.dtsi" #include "mt6323.dtsi" / { @@ -24,6 +24,19 @@ stdout-path = "serial2:115200n8"; }; + connector { + compatible = "hdmi-connector"; + label = "hdmi"; + type = "d"; + ddc-i2c-bus = <&hdmiddc0>; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi0_out>; + }; + }; + }; + cpus { cpu@0 { proc-supply = <&mt6323_vproc_reg>; @@ -106,10 +119,18 @@ }; }; +&bls { + status = "okay"; +}; + &btif { status = "okay"; }; +&cec { + status = "okay"; +}; + &cir { pinctrl-names = "default"; pinctrl-0 = <&cir_pins_a>; @@ -120,6 +141,21 @@ status = "okay"; }; +&dpi0 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + dpi0_out: endpoint { + remote-endpoint = <&hdmi0_in>; + }; + }; + }; +}; + ð { status = "okay"; @@ -203,6 +239,42 @@ }; }; +&hdmi0 { + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_pins_a>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + hdmi0_in: endpoint { + remote-endpoint = <&dpi0_out>; + }; + }; + + port@1 { + reg = <1>; + hdmi0_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; + }; + }; +}; + +&hdmiddc0 { + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_ddc_pins_a>; + status = "okay"; +}; + +&hdmi_phy { + mediatek,ibias = <0xa>; + mediatek,ibias_up = <0x1c>; + status = "okay"; +}; + &i2c0 { pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins_a>; diff --git a/arch/arm/boot/dts/mt7623n.dtsi b/arch/arm/boot/dts/mt7623n.dtsi new file mode 100644 index 000000000000..1880ac9e32cf --- /dev/null +++ b/arch/arm/boot/dts/mt7623n.dtsi @@ -0,0 +1,306 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright © 2017-2020 MediaTek Inc. + * Author: Sean Wang <sean.wang@mediatek.com> + * Ryder Lee <ryder.lee@mediatek.com> + * + */ + +#include "mt7623.dtsi" +#include <dt-bindings/memory/mt2701-larb-port.h> + +/ { + aliases { + rdma0 = &rdma0; + rdma1 = &rdma1; + }; + + g3dsys: syscon@13000000 { + compatible = "mediatek,mt7623-g3dsys", + "mediatek,mt2701-g3dsys", + "syscon"; + reg = <0 0x13000000 0 0x200>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + mali: gpu@13040000 { + compatible = "mediatek,mt7623-mali", "arm,mali-450"; + reg = <0 0x13040000 0 0x30000>; + interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 171 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 172 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 173 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 174 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 175 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 176 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 177 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 178 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 179 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "gp", "gpmmu", "pp0", "ppmmu0", "pp1", + "ppmmu1", "pp2", "ppmmu2", "pp3", "ppmmu3", + "pp"; + clocks = <&topckgen CLK_TOP_MMPLL>, + <&g3dsys CLK_G3DSYS_CORE>; + clock-names = "bus", "core"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_MFG>; + resets = <&g3dsys MT2701_G3DSYS_CORE_RST>; + }; + + mmsys: syscon@14000000 { + compatible = "mediatek,mt7623-mmsys", + "mediatek,mt2701-mmsys", + "syscon"; + reg = <0 0x14000000 0 0x1000>; + #clock-cells = <1>; + }; + + larb0: larb@14010000 { + compatible = "mediatek,mt7623-smi-larb", + "mediatek,mt2701-smi-larb"; + reg = <0 0x14010000 0 0x1000>; + mediatek,smi = <&smi_common>; + mediatek,larb-id = <0>; + clocks = <&mmsys CLK_MM_SMI_LARB0>, + <&mmsys CLK_MM_SMI_LARB0>; + clock-names = "apb", "smi"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; + }; + + larb1: larb@16010000 { + compatible = "mediatek,mt7623-smi-larb", + "mediatek,mt2701-smi-larb"; + reg = <0 0x16010000 0 0x1000>; + mediatek,smi = <&smi_common>; + mediatek,larb-id = <1>; + clocks = <&vdecsys CLK_VDEC_CKGEN>, + <&vdecsys CLK_VDEC_LARB>; + clock-names = "apb", "smi"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_VDEC>; + }; + + larb2: larb@15001000 { + compatible = "mediatek,mt7623-smi-larb", + "mediatek,mt2701-smi-larb"; + reg = <0 0x15001000 0 0x1000>; + mediatek,smi = <&smi_common>; + mediatek,larb-id = <2>; + clocks = <&imgsys CLK_IMG_SMI_COMM>, + <&imgsys CLK_IMG_SMI_COMM>; + clock-names = "apb", "smi"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; + }; + + imgsys: syscon@15000000 { + compatible = "mediatek,mt7623-imgsys", + "mediatek,mt2701-imgsys", + "syscon"; + reg = <0 0x15000000 0 0x1000>; + #clock-cells = <1>; + }; + + iommu: mmsys_iommu@10205000 { + compatible = "mediatek,mt7623-m4u", + "mediatek,mt2701-m4u"; + reg = <0 0x10205000 0 0x1000>; + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_LOW>; + clocks = <&infracfg CLK_INFRA_M4U>; + clock-names = "bclk"; + mediatek,larbs = <&larb0 &larb1 &larb2>; + #iommu-cells = <1>; + }; + + jpegdec: jpegdec@15004000 { + compatible = "mediatek,mt7623-jpgdec", + "mediatek,mt2701-jpgdec"; + reg = <0 0x15004000 0 0x1000>; + interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_LOW>; + clocks = <&imgsys CLK_IMG_JPGDEC_SMI>, + <&imgsys CLK_IMG_JPGDEC>; + clock-names = "jpgdec-smi", + "jpgdec"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; + mediatek,larb = <&larb2>; + iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>, + <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>; + }; + + smi_common: smi@1000c000 { + compatible = "mediatek,mt7623-smi-common", + "mediatek,mt2701-smi-common"; + reg = <0 0x1000c000 0 0x1000>; + clocks = <&infracfg CLK_INFRA_SMI>, + <&mmsys CLK_MM_SMI_COMMON>, + <&infracfg CLK_INFRA_SMI>; + clock-names = "apb", "smi", "async"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; + }; + + ovl: ovl@14007000 { + compatible = "mediatek,mt7623-disp-ovl", + "mediatek,mt2701-disp-ovl"; + reg = <0 0x14007000 0 0x1000>; + interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_LOW>; + clocks = <&mmsys CLK_MM_DISP_OVL>; + iommus = <&iommu MT2701_M4U_PORT_DISP_OVL_0>; + mediatek,larb = <&larb0>; + }; + + rdma0: rdma@14008000 { + compatible = "mediatek,mt7623-disp-rdma", + "mediatek,mt2701-disp-rdma"; + reg = <0 0x14008000 0 0x1000>; + interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_LOW>; + clocks = <&mmsys CLK_MM_DISP_RDMA>; + iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA>; + mediatek,larb = <&larb0>; + }; + + wdma@14009000 { + compatible = "mediatek,mt7623-disp-wdma", + "mediatek,mt2701-disp-wdma"; + reg = <0 0x14009000 0 0x1000>; + interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_LOW>; + clocks = <&mmsys CLK_MM_DISP_WDMA>; + iommus = <&iommu MT2701_M4U_PORT_DISP_WDMA>; + mediatek,larb = <&larb0>; + }; + + bls: pwm@1400a000 { + compatible = "mediatek,mt7623-disp-pwm", + "mediatek,mt2701-disp-pwm"; + reg = <0 0x1400a000 0 0x1000>; + #pwm-cells = <2>; + clocks = <&mmsys CLK_MM_MDP_BLS_26M>, + <&mmsys CLK_MM_DISP_BLS>; + clock-names = "main", "mm"; + status = "disabled"; + }; + + color: color@1400b000 { + compatible = "mediatek,mt7623-disp-color", + "mediatek,mt2701-disp-color"; + reg = <0 0x1400b000 0 0x1000>; + interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_LOW>; + clocks = <&mmsys CLK_MM_DISP_COLOR>; + }; + + dsi: dsi@1400c000 { + compatible = "mediatek,mt7623-dsi", + "mediatek,mt2701-dsi"; + reg = <0 0x1400c000 0 0x1000>; + interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_LOW>; + clocks = <&mmsys CLK_MM_DSI_ENGINE>, + <&mmsys CLK_MM_DSI_DIG>, + <&mipi_tx0>; + clock-names = "engine", "digital", "hs"; + phys = <&mipi_tx0>; + phy-names = "dphy"; + status = "disabled"; + }; + + mutex: mutex@1400e000 { + compatible = "mediatek,mt7623-disp-mutex", + "mediatek,mt2701-disp-mutex"; + reg = <0 0x1400e000 0 0x1000>; + interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_LOW>; + clocks = <&mmsys CLK_MM_MUTEX_32K>; + }; + + rdma1: rdma@14012000 { + compatible = "mediatek,mt7623-disp-rdma", + "mediatek,mt2701-disp-rdma"; + reg = <0 0x14012000 0 0x1000>; + interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_LOW>; + clocks = <&mmsys CLK_MM_DISP_RDMA1>; + iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA1>; + mediatek,larb = <&larb0>; + }; + + dpi0: dpi@14014000 { + compatible = "mediatek,mt7623-dpi", + "mediatek,mt2701-dpi"; + reg = <0 0x14014000 0 0x1000>; + interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; + clocks = <&mmsys CLK_MM_DPI1_DIGL>, + <&mmsys CLK_MM_DPI1_ENGINE>, + <&apmixedsys CLK_APMIXED_TVDPLL>; + clock-names = "pixel", "engine", "pll"; + status = "disabled"; + }; + + hdmi0: hdmi@14015000 { + compatible = "mediatek,mt7623-hdmi", + "mediatek,mt2701-hdmi"; + reg = <0 0x14015000 0 0x400>; + clocks = <&mmsys CLK_MM_HDMI_PIXEL>, + <&mmsys CLK_MM_HDMI_PLL>, + <&mmsys CLK_MM_HDMI_AUDIO>, + <&mmsys CLK_MM_HDMI_SPDIF>; + clock-names = "pixel", "pll", "bclk", "spdif"; + phys = <&hdmi_phy>; + phy-names = "hdmi"; + mediatek,syscon-hdmi = <&mmsys 0x900>; + cec = <&cec>; + status = "disabled"; + }; + + mipi_tx0: mipi-dphy@10010000 { + compatible = "mediatek,mt7623-mipi-tx", + "mediatek,mt2701-mipi-tx"; + reg = <0 0x10010000 0 0x90>; + clocks = <&clk26m>; + clock-output-names = "mipi_tx0_pll"; + #clock-cells = <0>; + #phy-cells = <0>; + }; + + cec: cec@10012000 { + compatible = "mediatek,mt7623-cec", + "mediatek,mt8173-cec"; + reg = <0 0x10012000 0 0xbc>; + interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>; + clocks = <&infracfg CLK_INFRA_CEC>; + status = "disabled"; + }; + + hdmi_phy: phy@10209100 { + compatible = "mediatek,mt7623-hdmi-phy", + "mediatek,mt2701-hdmi-phy"; + reg = <0 0x10209100 0 0x24>; + clocks = <&apmixedsys CLK_APMIXED_HDMI_REF>; + clock-names = "pll_ref"; + clock-output-names = "hdmitx_dig_cts"; + #clock-cells = <0>; + #phy-cells = <0>; + status = "disabled"; + }; + + hdmiddc0: i2c@11013000 { + compatible = "mediatek,mt7623-hdmi-ddc", + "mediatek,mt8173-hdmi-ddc"; + interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_LOW>; + reg = <0 0x11013000 0 0x1C>; + clocks = <&pericfg CLK_PERI_I2C3>; + clock-names = "ddc-i2c"; + status = "disabled"; + }; +}; + +&pio { + hdmi_pins_a: hdmi-default { + pins-hdmi { + pinmux = <MT7623_PIN_123_HTPLG_FUNC_HTPLG>; + input-enable; + bias-pull-down; + }; + }; + + hdmi_ddc_pins_a: hdmi_ddc-default { + pins-hdmi-ddc { + pinmux = <MT7623_PIN_124_GPIO124_FUNC_HDMISCK>, + <MT7623_PIN_125_GPIO125_FUNC_HDMISD>; + }; + }; +}; diff --git a/arch/arm/boot/dts/nspire.dtsi b/arch/arm/boot/dts/nspire.dtsi index d9a0fd7524dc..90e033d9141f 100644 --- a/arch/arm/boot/dts/nspire.dtsi +++ b/arch/arm/boot/dts/nspire.dtsi @@ -145,15 +145,19 @@ timer0: timer@900C0000 { reg = <0x900C0000 0x1000>; - - clocks = <&timer_clk>; + clocks = <&timer_clk>, <&timer_clk>, + <&timer_clk>; + clock-names = "timer0clk", "timer1clk", + "apb_pclk"; }; timer1: timer@900D0000 { reg = <0x900D0000 0x1000>; interrupts = <19>; - - clocks = <&timer_clk>; + clocks = <&timer_clk>, <&timer_clk>, + <&timer_clk>; + clock-names = "timer0clk", "timer1clk", + "apb_pclk"; }; watchdog: watchdog@90060000 { diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts index 05077f3c75cd..252507cf300b 100644 --- a/arch/arm/boot/dts/omap3-beagle-xm.dts +++ b/arch/arm/boot/dts/omap3-beagle-xm.dts @@ -389,7 +389,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = < @@ -406,7 +406,7 @@ }; &venc { - status = "ok"; + status = "okay"; vdda-supply = <&vdac>; diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index 79bc710c05fc..f9f34b8458e9 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -386,7 +386,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dss_dpi_pins>; @@ -400,7 +400,7 @@ }; &venc { - status = "ok"; + status = "okay"; vdda-supply = <&vdac>; @@ -413,7 +413,7 @@ }; &gpmc { - status = "ok"; + status = "okay"; ranges = <0 0 0x30000000 0x1000000>; /* CS0 space, 16MB */ /* Chip select 0 */ diff --git a/arch/arm/boot/dts/omap3-cm-t3517.dts b/arch/arm/boot/dts/omap3-cm-t3517.dts index 632f52efdf98..3b8349094baa 100644 --- a/arch/arm/boot/dts/omap3-cm-t3517.dts +++ b/arch/arm/boot/dts/omap3-cm-t3517.dts @@ -147,7 +147,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = < diff --git a/arch/arm/boot/dts/omap3-cm-t3530.dts b/arch/arm/boot/dts/omap3-cm-t3530.dts index 32dbaeaed147..bc545ee23e71 100644 --- a/arch/arm/boot/dts/omap3-cm-t3530.dts +++ b/arch/arm/boot/dts/omap3-cm-t3530.dts @@ -49,7 +49,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = < diff --git a/arch/arm/boot/dts/omap3-cm-t3730.dts b/arch/arm/boot/dts/omap3-cm-t3730.dts index 683819bf0915..48e48b0c8190 100644 --- a/arch/arm/boot/dts/omap3-cm-t3730.dts +++ b/arch/arm/boot/dts/omap3-cm-t3730.dts @@ -87,7 +87,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = < diff --git a/arch/arm/boot/dts/omap3-cm-t3x.dtsi b/arch/arm/boot/dts/omap3-cm-t3x.dtsi index cdb632df152a..e61b8a2bfb7d 100644 --- a/arch/arm/boot/dts/omap3-cm-t3x.dtsi +++ b/arch/arm/boot/dts/omap3-cm-t3x.dtsi @@ -246,7 +246,7 @@ }; &venc { - status = "ok"; + status = "okay"; port { venc_out: endpoint { @@ -257,7 +257,7 @@ }; &mcbsp2 { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&mcbsp2_pins>; diff --git a/arch/arm/boot/dts/omap3-cpu-thermal.dtsi b/arch/arm/boot/dts/omap3-cpu-thermal.dtsi index aee46fa8c055..1ed837859374 100644 --- a/arch/arm/boot/dts/omap3-cpu-thermal.dtsi +++ b/arch/arm/boot/dts/omap3-cpu-thermal.dtsi @@ -17,4 +17,25 @@ cpu_thermal: cpu_thermal { /* sensor ID */ thermal-sensors = <&bandgap 0>; + + cpu_trips: trips { + cpu_alert0: cpu_alert { + temperature = <80000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + cpu_crit: cpu_crit { + temperature = <90000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cpu_cooling_maps: cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = + <&cpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi index ac3d996cec5c..2c19d6e255bd 100644 --- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi +++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi @@ -337,7 +337,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dss_dpi_pins>; @@ -361,7 +361,7 @@ }; &venc { - status = "ok"; + status = "okay"; vdda-supply = <&vdac>; diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi index ecc45862b4f3..c8745bc800f7 100644 --- a/arch/arm/boot/dts/omap3-gta04.dtsi +++ b/arch/arm/boot/dts/omap3-gta04.dtsi @@ -822,27 +822,27 @@ }; &mcbsp1 { /* FM Transceiver PCM */ - status = "ok"; + status = "okay"; #sound-dai-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&mcbsp1_pins>; }; &mcbsp2 { /* TPS65950 I2S */ - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&mcbsp2_pins>; }; &mcbsp3 { /* Bluetooth PCM */ - status = "ok"; + status = "okay"; #sound-dai-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&mcbsp3_pins>; }; &mcbsp4 { /* GSM voice PCM */ - status = "ok"; + status = "okay"; #sound-dai-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&mcbsp4_pins>; diff --git a/arch/arm/boot/dts/omap3-ha-lcd.dts b/arch/arm/boot/dts/omap3-ha-lcd.dts index b3f7f9966c3c..643283f0c3db 100644 --- a/arch/arm/boot/dts/omap3-ha-lcd.dts +++ b/arch/arm/boot/dts/omap3-ha-lcd.dts @@ -100,7 +100,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dss_dpi_pins>; diff --git a/arch/arm/boot/dts/omap3-igep0020-common.dtsi b/arch/arm/boot/dts/omap3-igep0020-common.dtsi index 91caa50b74c4..af8aa5f0feb7 100644 --- a/arch/arm/boot/dts/omap3-igep0020-common.dtsi +++ b/arch/arm/boot/dts/omap3-igep0020-common.dtsi @@ -245,7 +245,7 @@ }; &dss { - status = "ok"; + status = "okay"; port { dpi_out: endpoint { diff --git a/arch/arm/boot/dts/omap3-n9.dts b/arch/arm/boot/dts/omap3-n9.dts index 2495a696cec6..d211bcc31174 100644 --- a/arch/arm/boot/dts/omap3-n9.dts +++ b/arch/arm/boot/dts/omap3-n9.dts @@ -23,7 +23,6 @@ vana-supply = <&vaux3>; clocks = <&isp 0>; clock-frequency = <9600000>; - nokia,nvm-size = <(16 * 64)>; flash-leds = <&as3645a_flash &as3645a_indicator>; port { smia_1_1: endpoint { diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index bc24e3dc7cda..32335d4ce478 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -1083,7 +1083,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dss_sdi_pins>; @@ -1106,7 +1106,7 @@ }; &venc { - status = "ok"; + status = "okay"; vdda-supply = <&vdac>; @@ -1119,7 +1119,7 @@ }; &mcbsp2 { - status = "ok"; + status = "okay"; }; &ssi_port1 { diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts index 31d47a1fad84..b2f480022ff6 100644 --- a/arch/arm/boot/dts/omap3-n950.dts +++ b/arch/arm/boot/dts/omap3-n950.dts @@ -76,7 +76,6 @@ vana-supply = <&vaux3>; clocks = <&isp 0>; clock-frequency = <9600000>; - nokia,nvm-size = <(16 * 64)>; flash-leds = <&as3645a_flash &as3645a_indicator>; port { smia_1_1: endpoint { @@ -205,13 +204,13 @@ }; &dss { - status = "ok"; + status = "okay"; vdda_video-supply = <&vdac>; }; &dsi { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dsi_pins>; @@ -225,8 +224,9 @@ }; }; - lcd0: display { + lcd0: panel@0 { compatible = "nokia,himalaya", "panel-dsi-cm"; + reg = <0>; label = "lcd0"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/omap3-overo-common-dvi.dtsi b/arch/arm/boot/dts/omap3-overo-common-dvi.dtsi index c9e62e414abb..339a51fa4119 100644 --- a/arch/arm/boot/dts/omap3-overo-common-dvi.dtsi +++ b/arch/arm/boot/dts/omap3-overo-common-dvi.dtsi @@ -48,7 +48,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dss_dpi_pins>; diff --git a/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi b/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi index 185ce53de0ec..1d6e88f99eb3 100644 --- a/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi +++ b/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi @@ -76,7 +76,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dss_dpi_pins>; diff --git a/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi b/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi index 7fe0f9148232..7e30f9d45790 100644 --- a/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi +++ b/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi @@ -75,7 +75,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dss_dpi_pins>; diff --git a/arch/arm/boot/dts/omap3-pandora-common.dtsi b/arch/arm/boot/dts/omap3-pandora-common.dtsi index 150d5be42d27..37608af6c07f 100644 --- a/arch/arm/boot/dts/omap3-pandora-common.dtsi +++ b/arch/arm/boot/dts/omap3-pandora-common.dtsi @@ -702,7 +702,7 @@ }; &venc { - status = "ok"; + status = "okay"; vdda-supply = <&vdac>; @@ -718,7 +718,7 @@ pinctrl-names = "default"; pinctrl-0 = < &dss_dpi_pins >; - status = "ok"; + status = "okay"; vdds_dsi-supply = <&vpll2>; port { diff --git a/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi b/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi index b8b9fcc41ef1..2dbb687d4df2 100644 --- a/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi +++ b/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi @@ -46,7 +46,7 @@ }; &dss { - status = "ok"; + status = "okay"; port { dpi_out: endpoint { remote-endpoint = <&lcd_in>; diff --git a/arch/arm/boot/dts/omap3-thunder.dts b/arch/arm/boot/dts/omap3-thunder.dts index f7930f198ce5..d82cab8e213a 100644 --- a/arch/arm/boot/dts/omap3-thunder.dts +++ b/arch/arm/boot/dts/omap3-thunder.dts @@ -64,7 +64,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dss_dpi_pins>; diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index cf22a7e1c63c..9dcae1f2bc99 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -941,6 +941,9 @@ ti,hwmods = "dss_dsi1"; clocks = <&dss1_alwon_fck>, <&dss2_alwon_fck>; clock-names = "fck", "sys_clk"; + + #address-cells = <1>; + #size-cells = <0>; }; rfbi: encoder@48050800 { diff --git a/arch/arm/boot/dts/omap34xx.dtsi b/arch/arm/boot/dts/omap34xx.dtsi index 9c3ee4ac8165..feaa43b78535 100644 --- a/arch/arm/boot/dts/omap34xx.dtsi +++ b/arch/arm/boot/dts/omap34xx.dtsi @@ -20,6 +20,7 @@ operating-points-v2 = <&cpu0_opp_table>; clock-latency = <300000>; /* From legacy driver */ + #cooling-cells = <2>; }; }; @@ -182,7 +183,7 @@ }; &ssi { - status = "ok"; + status = "okay"; clocks = <&ssi_ssr_fck>, <&ssi_sst_fck>, diff --git a/arch/arm/boot/dts/omap36xx.dtsi b/arch/arm/boot/dts/omap36xx.dtsi index 9c3beefc0fe0..05fe5ed127b0 100644 --- a/arch/arm/boot/dts/omap36xx.dtsi +++ b/arch/arm/boot/dts/omap36xx.dtsi @@ -25,6 +25,7 @@ vbb-supply = <&abb_mpu_iva>; clock-latency = <300000>; /* From omap-cpufreq driver */ + #cooling-cells = <2>; }; }; @@ -234,7 +235,7 @@ }; &ssi { - status = "ok"; + status = "okay"; clocks = <&ssi_ssr_fck>, <&ssi_sst_fck>, diff --git a/arch/arm/boot/dts/omap4-duovero-parlor.dts b/arch/arm/boot/dts/omap4-duovero-parlor.dts index 4548d87534e3..b294c22177cb 100644 --- a/arch/arm/boot/dts/omap4-duovero-parlor.dts +++ b/arch/arm/boot/dts/omap4-duovero-parlor.dts @@ -171,11 +171,11 @@ }; &dss { - status = "ok"; + status = "okay"; }; &hdmi { - status = "ok"; + status = "okay"; vdda-supply = <&vdac>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/omap4-l4-abe.dtsi b/arch/arm/boot/dts/omap4-l4-abe.dtsi index b2cf5f41e222..a9573d441dea 100644 --- a/arch/arm/boot/dts/omap4-l4-abe.dtsi +++ b/arch/arm/boot/dts/omap4-l4-abe.dtsi @@ -1,14 +1,16 @@ &l4_abe { /* 0x40100000 */ - compatible = "ti,omap4-l4-abe", "simple-bus"; + compatible = "ti,omap4-l4-abe", "simple-pm-bus"; reg = <0x40100000 0x400>, <0x40100400 0x400>; reg-names = "la", "ap"; + power-domains = <&prm_abe>; + /* OMAP4_L4_ABE_CLKCTRL is read-only */ #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x40100000 0x100000>, /* segment 0 */ <0x49000000 0x49000000 0x100000>; segment@0 { /* 0x40100000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = diff --git a/arch/arm/boot/dts/omap4-panda-common.dtsi b/arch/arm/boot/dts/omap4-panda-common.dtsi index 3e78caefa2b8..609a8dea946b 100644 --- a/arch/arm/boot/dts/omap4-panda-common.dtsi +++ b/arch/arm/boot/dts/omap4-panda-common.dtsi @@ -566,7 +566,7 @@ }; &dss { - status = "ok"; + status = "okay"; port { dpi_out: endpoint { @@ -577,12 +577,12 @@ }; &dsi2 { - status = "ok"; + status = "okay"; vdd-supply = <&vcxio>; }; &hdmi { - status = "ok"; + status = "okay"; vdda-supply = <&vdac>; port { diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts index 79e7a41ecb7e..afb49a2d6963 100644 --- a/arch/arm/boot/dts/omap4-sdp.dts +++ b/arch/arm/boot/dts/omap4-sdp.dts @@ -648,11 +648,11 @@ }; &dss { - status = "ok"; + status = "okay"; }; &dsi1 { - status = "ok"; + status = "okay"; vdd-supply = <&vcxio>; port { @@ -662,8 +662,9 @@ }; }; - lcd0: display { + lcd0: panel@0 { compatible = "tpo,taal", "panel-dsi-cm"; + reg = <0>; label = "lcd0"; reset-gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102 */ @@ -677,7 +678,7 @@ }; &dsi2 { - status = "ok"; + status = "okay"; vdd-supply = <&vcxio>; port { @@ -687,8 +688,9 @@ }; }; - lcd1: display { + lcd1: panel@0 { compatible = "tpo,taal", "panel-dsi-cm"; + reg = <0>; label = "lcd1"; reset-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* 104 */ @@ -702,7 +704,7 @@ }; &hdmi { - status = "ok"; + status = "okay"; vdda-supply = <&vdac>; port { diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 0282b9de3384..d6475cc6a91a 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -410,7 +410,7 @@ status = "disabled"; }; - target-module@56000000 { + sgx_module: target-module@56000000 { compatible = "ti,sysc-omap4", "ti,sysc"; reg = <0x5600fe00 0x4>, <0x5600fe10 0x4>; @@ -572,6 +572,9 @@ clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>, <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; clock-names = "fck", "sys_clk"; + + #address-cells = <1>; + #size-cells = <0>; }; }; @@ -604,6 +607,9 @@ clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>, <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; clock-names = "fck", "sys_clk"; + + #address-cells = <1>; + #size-cells = <0>; }; }; @@ -658,6 +664,12 @@ #reset-cells = <1>; }; + prm_abe: prm@500 { + compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; + reg = <0x500 0x100>; + #power-domain-cells = <0>; + }; + prm_core: prm@700 { compatible = "ti,omap4-prm-inst", "ti,omap-prm-inst"; reg = <0x700 0x100>; diff --git a/arch/arm/boot/dts/omap443x.dtsi b/arch/arm/boot/dts/omap443x.dtsi index 8ed510ab00c5..cb309743de5d 100644 --- a/arch/arm/boot/dts/omap443x.dtsi +++ b/arch/arm/boot/dts/omap443x.dtsi @@ -74,3 +74,13 @@ }; /include/ "omap443x-clocks.dtsi" + +/* + * Use dpll_per for sgx at 153.6MHz like droid4 stock v3.0.8 Android kernel + */ +&sgx_module { + assigned-clocks = <&l3_gfx_clkctrl OMAP4_GPU_CLKCTRL 24>, + <&dpll_per_m7x2_ck>; + assigned-clock-rates = <0>, <153600000>; + assigned-clock-parents = <&dpll_per_m7x2_ck>; +}; diff --git a/arch/arm/boot/dts/omap5-board-common.dtsi b/arch/arm/boot/dts/omap5-board-common.dtsi index edf1906016c8..d8f13626cfd1 100644 --- a/arch/arm/boot/dts/omap5-board-common.dtsi +++ b/arch/arm/boot/dts/omap5-board-common.dtsi @@ -743,11 +743,11 @@ }; &dss { - status = "ok"; + status = "okay"; }; &hdmi { - status = "ok"; + status = "okay"; /* vdda-supply populated in board specific dts file */ diff --git a/arch/arm/boot/dts/omap5-cm-t54.dts b/arch/arm/boot/dts/omap5-cm-t54.dts index e78d3718f145..ca759b7b8a58 100644 --- a/arch/arm/boot/dts/omap5-cm-t54.dts +++ b/arch/arm/boot/dts/omap5-cm-t54.dts @@ -653,7 +653,7 @@ }; &dss { - status = "ok"; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dss_dpi_pins>; @@ -677,12 +677,12 @@ }; &dsi2 { - status = "ok"; + status = "okay"; vdd-supply = <&ldo4_reg>; }; &hdmi { - status = "ok"; + status = "okay"; vdda-supply = <&ldo4_reg>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/omap5-l4-abe.dtsi b/arch/arm/boot/dts/omap5-l4-abe.dtsi index 25b7fce8de2d..a03bca5a3584 100644 --- a/arch/arm/boot/dts/omap5-l4-abe.dtsi +++ b/arch/arm/boot/dts/omap5-l4-abe.dtsi @@ -1,14 +1,16 @@ &l4_abe { /* 0x40100000 */ - compatible = "ti,omap5-l4-abe", "simple-bus"; + compatible = "ti,omap5-l4-abe", "simple-pm-bus"; reg = <0x40100000 0x400>, <0x40100400 0x400>; reg-names = "la", "ap"; + power-domains = <&prm_abe>; + /* OMAP5_L4_ABE_CLKCTRL is read-only */ #address-cells = <1>; #size-cells = <1>; ranges = <0x00000000 0x40100000 0x100000>, /* segment 0 */ <0x49000000 0x49000000 0x100000>; segment@0 { /* 0x40100000 */ - compatible = "simple-bus"; + compatible = "simple-pm-bus"; #address-cells = <1>; #size-cells = <1>; ranges = diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index 5da9cff7a53c..2bf2e5839a7f 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -488,11 +488,11 @@ }; }; - target-module@5000 { + target-module@4000 { compatible = "ti,sysc-omap2", "ti,sysc"; - reg = <0x5000 0x4>, - <0x5010 0x4>, - <0x5014 0x4>; + reg = <0x4000 0x4>, + <0x4010 0x4>, + <0x4014 0x4>; reg-names = "rev", "sysc", "syss"; ti,sysc-sidle = <SYSC_IDLE_FORCE>, <SYSC_IDLE_NO>, @@ -504,7 +504,7 @@ ti,syss-mask = <1>; #address-cells = <1>; #size-cells = <1>; - ranges = <0 0x5000 0x1000>; + ranges = <0 0x4000 0x1000>; dsi1: encoder@0 { compatible = "ti,omap5-dsi"; @@ -514,8 +514,9 @@ reg-names = "proto", "phy", "pll"; interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; - clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>; - clock-names = "fck"; + clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>, + <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>; + clock-names = "fck", "sys_clk"; }; }; @@ -545,8 +546,9 @@ reg-names = "proto", "phy", "pll"; interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; - clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>; - clock-names = "fck"; + clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>, + <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 10>; + clock-names = "fck", "sys_clk"; }; }; @@ -674,6 +676,12 @@ #reset-cells = <1>; }; + prm_abe: prm@500 { + compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; + reg = <0x500 0x100>; + #power-domain-cells = <0>; + }; + prm_core: prm@700 { compatible = "ti,omap5-prm-inst", "ti,omap-prm-inst"; reg = <0x700 0x100>; diff --git a/arch/arm/boot/dts/owl-s500-labrador-base-m.dts b/arch/arm/boot/dts/owl-s500-labrador-base-m.dts new file mode 100644 index 000000000000..c92f8bdcb331 --- /dev/null +++ b/arch/arm/boot/dts/owl-s500-labrador-base-m.dts @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Caninos Labrador Base Board + * + * Copyright (c) 2019-2020 Matheus Castello + */ + +/dts-v1/; + +#include "owl-s500-labrador-v2.dtsi" + +/ { + model = "Caninos Labrador Core v2 on Labrador Base-M v1"; + compatible = "caninos,labrador-base-m", + "caninos,labrador-v2", "actions,s500"; + + aliases { + serial3 = &uart3; + }; + + chosen { + stdout-path = "serial3:115200n8"; + }; + + uart3_clk: uart3-clk { + compatible = "fixed-clock"; + clock-frequency = <921600>; + #clock-cells = <0>; + }; +}; + +&uart3 { + status = "okay"; + clocks = <&uart3_clk>; +}; diff --git a/arch/arm/boot/dts/owl-s500-labrador-v2.dtsi b/arch/arm/boot/dts/owl-s500-labrador-v2.dtsi new file mode 100644 index 000000000000..883ff2f9886d --- /dev/null +++ b/arch/arm/boot/dts/owl-s500-labrador-v2.dtsi @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Caninos Labrador SoM V2 + * + * Copyright (c) 2019-2020 Matheus Castello + */ + +#include "owl-s500.dtsi" + +/ { + model = "Caninos Labrador Core V2.1"; + compatible = "caninos,labrador-v2", "actions,s500"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x80000000>; + }; +}; + +&timer { + clocks = <&hosc>; +}; diff --git a/arch/arm/boot/dts/owl-s500-roseapplepi.dts b/arch/arm/boot/dts/owl-s500-roseapplepi.dts new file mode 100644 index 000000000000..a2087e617cb2 --- /dev/null +++ b/arch/arm/boot/dts/owl-s500-roseapplepi.dts @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Roseapple Pi + * + * Copyright (C) 2020 Cristian Ciocaltea <cristian.ciocaltea@gmail.com> + */ + +/dts-v1/; + +#include "owl-s500.dtsi" + +/ { + compatible = "roseapplepi,roseapplepi", "actions,s500"; + model = "Roseapple Pi"; + + aliases { + serial2 = &uart2; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x80000000>; /* 2GB */ + }; + + uart2_clk: uart2-clk { + compatible = "fixed-clock"; + clock-frequency = <921600>; + #clock-cells = <0>; + }; +}; + +&twd_timer { + status = "okay"; +}; + +&timer { + clocks = <&hosc>; +}; + +&uart2 { + status = "okay"; + clocks = <&uart2_clk>; +}; diff --git a/arch/arm/boot/dts/owl-s500.dtsi b/arch/arm/boot/dts/owl-s500.dtsi index 5ceb6cc4451d..1dbe4e8b38ac 100644 --- a/arch/arm/boot/dts/owl-s500.dtsi +++ b/arch/arm/boot/dts/owl-s500.dtsi @@ -84,21 +84,21 @@ global_timer: timer@b0020200 { compatible = "arm,cortex-a9-global-timer"; reg = <0xb0020200 0x100>; - interrupts = <GIC_PPI 0 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>; + interrupts = <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>; status = "disabled"; }; twd_timer: timer@b0020600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0xb0020600 0x20>; - interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>; status = "disabled"; }; twd_wdt: wdt@b0020620 { compatible = "arm,cortex-a9-twd-wdt"; reg = <0xb0020620 0xe0>; - interrupts = <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>; + interrupts = <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/picoxcell-pc3x2.dtsi b/arch/arm/boot/dts/picoxcell-pc3x2.dtsi index 5ae860788339..c4c6c7e9e37b 100644 --- a/arch/arm/boot/dts/picoxcell-pc3x2.dtsi +++ b/arch/arm/boot/dts/picoxcell-pc3x2.dtsi @@ -160,7 +160,6 @@ reg = <0x20000 0x1000>; #address-cells = <1>; #size-cells = <0>; - reg-io-width = <4>; banka: gpio-controller@0 { compatible = "snps,dw-apb-gpio-bank"; diff --git a/arch/arm/boot/dts/picoxcell-pc3x3.dtsi b/arch/arm/boot/dts/picoxcell-pc3x3.dtsi index fa93155fadb7..0e85bb6bd150 100644 --- a/arch/arm/boot/dts/picoxcell-pc3x3.dtsi +++ b/arch/arm/boot/dts/picoxcell-pc3x3.dtsi @@ -243,7 +243,6 @@ reg = <0x20000 0x1000>; #address-cells = <1>; #size-cells = <0>; - reg-io-width = <4>; banka: gpio-controller@0 { compatible = "snps,dw-apb-gpio-bank"; diff --git a/arch/arm/boot/dts/pm9g45.dts b/arch/arm/boot/dts/pm9g45.dts index 4dfe0f15d7bd..c349fd3758a6 100644 --- a/arch/arm/boot/dts/pm9g45.dts +++ b/arch/arm/boot/dts/pm9g45.dts @@ -15,7 +15,7 @@ bootargs = "console=ttyS0,115200"; }; - memory { + memory@70000000 { reg = <0x70000000 0x8000000>; }; @@ -68,6 +68,7 @@ &pinctrl_board_mmc &pinctrl_mmc0_slot0_clk_cmd_dat0 &pinctrl_mmc0_slot0_dat1_3>; + pinctrl-names = "default"; status = "okay"; slot@0 { reg = <0>; diff --git a/arch/arm/boot/dts/prima2.dtsi b/arch/arm/boot/dts/prima2.dtsi index 9c7b46b90c3c..7d3d93c22ed9 100644 --- a/arch/arm/boot/dts/prima2.dtsi +++ b/arch/arm/boot/dts/prima2.dtsi @@ -50,7 +50,7 @@ #size-cells = <1>; ranges = <0x40000000 0x40000000 0x80000000>; - l2-cache-controller@80040000 { + cache-controller@80040000 { compatible = "arm,pl310-cache"; reg = <0x80040000 0x1000>; interrupts = <59>; diff --git a/arch/arm/boot/dts/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom-mdm9615.dtsi index 347b4f7d7889..dda2ceec6591 100644 --- a/arch/arm/boot/dts/qcom-mdm9615.dtsi +++ b/arch/arm/boot/dts/qcom-mdm9615.dtsi @@ -98,7 +98,7 @@ ranges; compatible = "simple-bus"; - L2: l2-cache@2040000 { + L2: cache-controller@2040000 { compatible = "arm,pl310-cache"; reg = <0x02040000 0x1000>; arm,data-latency = <2 2 0>; diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi index b9b138888048..45cf75b5824c 100644 --- a/arch/arm/boot/dts/r7s72100.dtsi +++ b/arch/arm/boot/dts/r7s72100.dtsi @@ -499,7 +499,7 @@ clock-output-names = "sdhi00", "sdhi01", "sdhi10", "sdhi11"; }; - pinctrl: pin-controller@fcfe3000 { + pinctrl: pinctrl@fcfe3000 { compatible = "renesas,r7s72100-ports"; reg = <0xfcfe3000 0x4230>; diff --git a/arch/arm/boot/dts/r7s9210.dtsi b/arch/arm/boot/dts/r7s9210.dtsi index 838920aef992..85c0399b1339 100644 --- a/arch/arm/boot/dts/r7s9210.dtsi +++ b/arch/arm/boot/dts/r7s9210.dtsi @@ -489,7 +489,7 @@ interrupt-map-mask = <7 0>; }; - pinctrl: pin-controller@fcffe000 { + pinctrl: pinctrl@fcffe000 { compatible = "renesas,r7s9210-pinctrl"; reg = <0xfcffe000 0x1000>; diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi index b92e72579836..e5fb1ce261f7 100644 --- a/arch/arm/boot/dts/r8a73a4.dtsi +++ b/arch/arm/boot/dts/r8a73a4.dtsi @@ -221,7 +221,7 @@ power-domains = <&pd_c4>; }; - pfc: pin-controller@e6050000 { + pfc: pinctrl@e6050000 { compatible = "renesas,pfc-r8a73a4"; reg = <0 0xe6050000 0 0x9000>; gpio-controller; diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi index 8048303037ee..1b2cf5fa322b 100644 --- a/arch/arm/boot/dts/r8a7740.dtsi +++ b/arch/arm/boot/dts/r8a7740.dtsi @@ -311,7 +311,7 @@ status = "disabled"; }; - pfc: pin-controller@e6050000 { + pfc: pinctrl@e6050000 { compatible = "renesas,pfc-r8a7740"; reg = <0xe6050000 0x8000>, <0xe605800c 0x20>; 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 1479ced50873..961c0f2eeefb 100644 --- a/arch/arm/boot/dts/r8a7742-iwg21d-q7-dbcm-ca.dts +++ b/arch/arm/boot/dts/r8a7742-iwg21d-q7-dbcm-ca.dts @@ -27,6 +27,12 @@ status = "disabled"; }; +&can0 { + pinctrl-0 = <&can0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + ðer { pinctrl-0 = <ðer_pins>; pinctrl-names = "default"; @@ -49,6 +55,11 @@ }; &pfc { + can0_pins: can0 { + groups = "can0_data_d"; + function = "can0"; + }; + ether_pins: ether { groups = "eth_mdio", "eth_rmii"; function = "eth"; diff --git a/arch/arm/boot/dts/r8a7742-iwg21d-q7.dts b/arch/arm/boot/dts/r8a7742-iwg21d-q7.dts index e90aaf1c94f0..c2c05c9685d1 100644 --- a/arch/arm/boot/dts/r8a7742-iwg21d-q7.dts +++ b/arch/arm/boot/dts/r8a7742-iwg21d-q7.dts @@ -52,6 +52,16 @@ clock-frequency = <26000000>; }; + leds { + compatible = "gpio-leds"; + + sdhi2_led { + label = "sdio-led"; + gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc1"; + }; + }; + reg_1p5v: 1p5v { compatible = "regulator-fixed"; regulator-name = "1P5V"; @@ -131,17 +141,109 @@ }; }; +&can1 { + pinctrl-0 = <&can1_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&cmt0 { + status = "okay"; +}; + +&gpio1 { + can-trx-en-gpio{ + gpio-hog; + gpios = <28 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "can-trx-en-gpio"; + }; +}; + +&hsusb { + pinctrl-0 = <&usb0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&msiof0 { + pinctrl-0 = <&msiof0_pins>; + pinctrl-names = "default"; + cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>; + + status = "okay"; + + flash1: flash@0 { + compatible = "sst,sst25vf016b", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + m25p,fast-read; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "user"; + reg = <0x00000000 0x00200000>; + }; + }; + }; +}; + +&pci0 { + pinctrl-0 = <&usb0_pins>; + pinctrl-names = "default"; + /* Disable hsusb to enable USB2.0 host mode support on J2 */ + /* status = "okay"; */ +}; + +&pci1 { + pinctrl-0 = <&usb1_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&pci2 { + /* Disable xhci to enable USB2.0 host mode support on J23 bottom port */ + /* status = "okay"; */ +}; + +&pcie_bus_clk { + clock-frequency = <100000000>; +}; + +&pciec { + /* SW2[6] determines which connector is activated + * ON = PCIe X4 (connector-J7) + * OFF = mini-PCIe (connector-J26) + */ + status = "okay"; +}; + &pfc { avb_pins: avb { groups = "avb_mdio", "avb_gmii"; function = "avb"; }; + can1_pins: can1 { + groups = "can1_data_b"; + function = "can1"; + }; + i2c2_pins: i2c2 { groups = "i2c2_b"; function = "i2c2"; }; + msiof0_pins: msiof0 { + groups = "msiof0_clk", "msiof0_sync", "msiof0_tx", "msiof0_rx"; + function = "msiof0"; + }; + scifa2_pins: scifa2 { groups = "scifa2_data_c"; function = "scifa2"; @@ -168,6 +270,16 @@ groups = "ssi34_ctrl", "ssi3_data", "ssi4_data"; function = "ssi"; }; + + usb0_pins: usb0 { + groups = "usb0"; + function = "usb0"; + }; + + usb1_pins: usb1 { + groups = "usb1_pwen"; + function = "usb1"; + }; }; &rcar_sound { @@ -222,3 +334,11 @@ &ssi4 { shared-pin; }; + +&usbphy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/r8a7742-iwg21m.dtsi b/arch/arm/boot/dts/r8a7742-iwg21m.dtsi index 85aff429d408..5621c9ed698f 100644 --- a/arch/arm/boot/dts/r8a7742-iwg21m.dtsi +++ b/arch/arm/boot/dts/r8a7742-iwg21m.dtsi @@ -35,10 +35,28 @@ clock-frequency = <20000000>; }; -&pfc { - mmc1_pins: mmc1 { - groups = "mmc1_data4", "mmc1_ctrl"; - function = "mmc1"; +&gpio0 { + /* GP0_18 set low to select QSPI. Doing so will disable VIN2 */ + qspi_en { + gpio-hog; + gpios = <18 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "QSPI_EN"; + }; +}; + +&i2c0 { + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + + status = "okay"; + clock-frequency = <400000>; + + rtc@68 { + compatible = "ti,bq32000"; + reg = <0x68>; + interrupt-parent = <&gpio1>; + interrupts = <1 IRQ_TYPE_EDGE_FALLING>; }; }; @@ -51,3 +69,56 @@ non-removable; status = "okay"; }; + +&pfc { + i2c0_pins: i2c0 { + groups = "i2c0"; + function = "i2c0"; + }; + + mmc1_pins: mmc1 { + groups = "mmc1_data4", "mmc1_ctrl"; + function = "mmc1"; + }; + + qspi_pins: qspi { + groups = "qspi_ctrl", "qspi_data2"; + function = "qspi"; + }; +}; + +&qspi { + pinctrl-0 = <&qspi_pins>; + pinctrl-names = "default"; + + status = "okay"; + + flash: flash@0 { + compatible = "sst,sst25vf016b", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + m25p,fast-read; + spi-cpol; + spi-cpha; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "bootloader"; + reg = <0x00000000 0x000c0000>; + read-only; + }; + partition@c0000 { + label = "env"; + reg = <0x000c0000 0x00002000>; + }; + partition@c2000 { + label = "user"; + reg = <0x000c2000 0x0013e000>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/r8a7742.dtsi b/arch/arm/boot/dts/r8a7742.dtsi index 9743b4242801..6a78c813057b 100644 --- a/arch/arm/boot/dts/r8a7742.dtsi +++ b/arch/arm/boot/dts/r8a7742.dtsi @@ -36,6 +36,14 @@ clock-frequency = <0>; }; + /* External CAN clock */ + can_clk: can { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -188,6 +196,13 @@ clock-frequency = <0>; }; + /* External PCIe clock - can be overridden by the board */ + pcie_bus_clk: pcie_bus { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + }; + pmu-0 { compatible = "arm,cortex-a15-pmu"; interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, @@ -323,11 +338,22 @@ resets = <&cpg 907>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a7742"; reg = <0 0xe6060000 0 0x250>; }; + tpu: pwm@e60f0000 { + compatible = "renesas,tpu-r8a7742", "renesas,tpu"; + reg = <0 0xe60f0000 0 0x148>; + interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 304>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 304>; + #pwm-cells = <3>; + status = "disabled"; + }; + cpg: clock-controller@e6150000 { compatible = "renesas,r8a7742-cpg-mssr"; reg = <0 0xe6150000 0 0x1000>; @@ -386,6 +412,54 @@ #thermal-sensor-cells = <0>; }; + ipmmu_sy0: iommu@e6280000 { + compatible = "renesas,ipmmu-r8a7742", + "renesas,ipmmu-vmsa"; + reg = <0 0xe6280000 0 0x1000>; + interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_sy1: iommu@e6290000 { + compatible = "renesas,ipmmu-r8a7742", + "renesas,ipmmu-vmsa"; + reg = <0 0xe6290000 0 0x1000>; + interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_ds: iommu@e6740000 { + compatible = "renesas,ipmmu-r8a7742", + "renesas,ipmmu-vmsa"; + reg = <0 0xe6740000 0 0x1000>; + interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_mp: iommu@ec680000 { + compatible = "renesas,ipmmu-r8a7742", + "renesas,ipmmu-vmsa"; + reg = <0 0xec680000 0 0x1000>; + interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + status = "disabled"; + }; + + ipmmu_mx: iommu@fe951000 { + compatible = "renesas,ipmmu-r8a7742", + "renesas,ipmmu-vmsa"; + reg = <0 0xfe951000 0 0x1000>; + interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + status = "disabled"; + }; + icram0: sram@e63a0000 { compatible = "mmio-sram"; reg = <0 0xe63a0000 0 0x12000>; @@ -683,6 +757,22 @@ status = "disabled"; }; + qspi: spi@e6b10000 { + compatible = "renesas,qspi-r8a7742", "renesas,qspi"; + reg = <0 0xe6b10000 0 0x2c>; + interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 917>; + dmas = <&dmac0 0x17>, <&dmac0 0x18>, + <&dmac1 0x17>, <&dmac1 0x18>; + dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 917>; + num-cs = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a7742", "renesas,rcar-gen2-scifa", "renesas,scifa"; @@ -917,6 +1007,146 @@ status = "disabled"; }; + can0: can@e6e80000 { + compatible = "renesas,can-r8a7742", + "renesas,rcar-gen2-can"; + reg = <0 0xe6e80000 0 0x1000>; + interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 916>, + <&cpg CPG_CORE R8A7742_CLK_RCAN>, <&can_clk>; + clock-names = "clkp1", "clkp2", "can_clk"; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 916>; + status = "disabled"; + }; + + can1: can@e6e88000 { + compatible = "renesas,can-r8a7742", + "renesas,rcar-gen2-can"; + reg = <0 0xe6e88000 0 0x1000>; + interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 915>, + <&cpg CPG_CORE R8A7742_CLK_RCAN>, <&can_clk>; + clock-names = "clkp1", "clkp2", "can_clk"; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 915>; + status = "disabled"; + }; + + pwm0: pwm@e6e30000 { + compatible = "renesas,pwm-r8a7742", "renesas,pwm-rcar"; + reg = <0 0xe6e30000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 523>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm1: pwm@e6e31000 { + compatible = "renesas,pwm-r8a7742", "renesas,pwm-rcar"; + reg = <0 0xe6e31000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 523>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm2: pwm@e6e32000 { + compatible = "renesas,pwm-r8a7742", "renesas,pwm-rcar"; + reg = <0 0xe6e32000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 523>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm3: pwm@e6e33000 { + compatible = "renesas,pwm-r8a7742", "renesas,pwm-rcar"; + reg = <0 0xe6e33000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 523>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm4: pwm@e6e34000 { + compatible = "renesas,pwm-r8a7742", "renesas,pwm-rcar"; + reg = <0 0xe6e34000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 523>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm5: pwm@e6e35000 { + compatible = "renesas,pwm-r8a7742", "renesas,pwm-rcar"; + reg = <0 0xe6e35000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 523>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm6: pwm@e6e36000 { + compatible = "renesas,pwm-r8a7742", "renesas,pwm-rcar"; + reg = <0 0xe6e36000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 523>; + #pwm-cells = <2>; + status = "disabled"; + }; + + vin0: video@e6ef0000 { + compatible = "renesas,vin-r8a7742", + "renesas,rcar-gen2-vin"; + reg = <0 0xe6ef0000 0 0x1000>; + interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 811>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 811>; + status = "disabled"; + }; + + vin1: video@e6ef1000 { + compatible = "renesas,vin-r8a7742", + "renesas,rcar-gen2-vin"; + reg = <0 0xe6ef1000 0 0x1000>; + interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 810>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 810>; + status = "disabled"; + }; + + vin2: video@e6ef2000 { + compatible = "renesas,vin-r8a7742", + "renesas,rcar-gen2-vin"; + reg = <0 0xe6ef2000 0 0x1000>; + interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 809>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 809>; + status = "disabled"; + }; + + vin3: video@e6ef3000 { + compatible = "renesas,vin-r8a7742", + "renesas,rcar-gen2-vin"; + reg = <0 0xe6ef3000 0 0x1000>; + interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 808>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 808>; + status = "disabled"; + }; + rcar_sound: sound@ec500000 { /* * #sound-dai-cells is required @@ -1428,6 +1658,159 @@ resets = <&cpg 408>; }; + pciec: pcie@fe000000 { + compatible = "renesas,pcie-r8a7742", + "renesas,pcie-rcar-gen2"; + reg = <0 0xfe000000 0 0x80000>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x00 0xff>; + device_type = "pci"; + ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000>, + <0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000>, + <0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>, + <0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>; + /* Map all possible DDR as inbound ranges */ + dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>, + <0x43000000 1 0x80000000 1 0x80000000 0 0x80000000>; + interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>; + clock-names = "pcie", "pcie_bus"; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 319>; + status = "disabled"; + }; + + vsp@fe920000 { + compatible = "renesas,vsp1"; + reg = <0 0xfe920000 0 0x8000>; + interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 130>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 130>; + }; + + vsp@fe928000 { + compatible = "renesas,vsp1"; + reg = <0 0xfe928000 0 0x8000>; + interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 131>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 131>; + }; + + vsp@fe930000 { + compatible = "renesas,vsp1"; + reg = <0 0xfe930000 0 0x8000>; + interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 128>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 128>; + }; + + vsp@fe938000 { + compatible = "renesas,vsp1"; + reg = <0 0xfe938000 0 0x8000>; + interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 127>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 127>; + }; + + du: display@feb00000 { + compatible = "renesas,du-r8a7742"; + reg = <0 0xfeb00000 0 0x70000>; + interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>; + clock-names = "du.0", "du.1", "du.2"; + resets = <&cpg 724>; + reset-names = "du.0"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + du_out_rgb: endpoint { + }; + }; + port@1 { + reg = <1>; + du_out_lvds0: endpoint { + remote-endpoint = <&lvds0_in>; + }; + }; + port@2 { + reg = <2>; + du_out_lvds1: endpoint { + remote-endpoint = <&lvds1_in>; + }; + }; + }; + }; + + lvds0: lvds@feb90000 { + compatible = "renesas,r8a7742-lvds"; + reg = <0 0xfeb90000 0 0x14>; + clocks = <&cpg CPG_MOD 726>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 726>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + lvds0_in: endpoint { + remote-endpoint = <&du_out_lvds0>; + }; + }; + port@1 { + reg = <1>; + lvds0_out: endpoint { + }; + }; + }; + }; + + lvds1: lvds@feb94000 { + compatible = "renesas,r8a7742-lvds"; + reg = <0 0xfeb94000 0 0x14>; + clocks = <&cpg CPG_MOD 725>; + power-domains = <&sysc R8A7742_PD_ALWAYS_ON>; + resets = <&cpg 725>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + lvds1_in: endpoint { + remote-endpoint = <&du_out_lvds1>; + }; + }; + port@1 { + reg = <1>; + lvds1_out: endpoint { + }; + }; + }; + }; + prr: chipid@ff000044 { compatible = "renesas,prr"; reg = <0 0xff000044 0 4>; diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi index 896916a00b84..f444e418f408 100644 --- a/arch/arm/boot/dts/r8a7743.dtsi +++ b/arch/arm/boot/dts/r8a7743.dtsi @@ -265,7 +265,7 @@ resets = <&cpg 904>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a7743"; reg = <0 0xe6060000 0 0x250>; }; diff --git a/arch/arm/boot/dts/r8a7744.dtsi b/arch/arm/boot/dts/r8a7744.dtsi index 6b56aa286337..0442aad4f9db 100644 --- a/arch/arm/boot/dts/r8a7744.dtsi +++ b/arch/arm/boot/dts/r8a7744.dtsi @@ -265,7 +265,7 @@ resets = <&cpg 904>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a7744"; reg = <0 0xe6060000 0 0x250>; }; diff --git a/arch/arm/boot/dts/r8a7745-iwg22d-sodimm.dts b/arch/arm/boot/dts/r8a7745-iwg22d-sodimm.dts index b15b1b088a32..1c7b37a01f0a 100644 --- a/arch/arm/boot/dts/r8a7745-iwg22d-sodimm.dts +++ b/arch/arm/boot/dts/r8a7745-iwg22d-sodimm.dts @@ -53,42 +53,6 @@ clock-frequency = <26000000>; }; - rsnd_sgtl5000: sound { - compatible = "simple-audio-card"; - simple-audio-card,format = "i2s"; - simple-audio-card,bitclock-master = <&sndcodec>; - simple-audio-card,frame-master = <&sndcodec>; - - sndcpu: simple-audio-card,cpu { - sound-dai = <&rcar_sound>; - }; - - sndcodec: simple-audio-card,codec { - sound-dai = <&sgtl5000>; - }; - }; - - vccq_sdhi0: regulator-vccq-sdhi0 { - compatible = "regulator-gpio"; - - regulator-name = "SDHI0 VccQ"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - - gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; - gpios-states = <1>; - states = <3300000 1>, <1800000 0>; - }; - - vccq_panel: regulator-vccq-panel { - compatible = "regulator-fixed"; - regulator-name = "Panel VccQ"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&gpio1 13 GPIO_ACTIVE_LOW>; - enable-active-high; - }; - backlight_lcd: backlight { compatible = "pwm-backlight"; pwms = <&tpu 3 5000000 PWM_POLARITY_INVERTED>; @@ -107,19 +71,40 @@ }; }; }; -}; -&du { - pinctrl-0 = <&du0_pins>; - pinctrl-names = "default"; + vccq_panel: regulator-vccq-panel { + compatible = "regulator-fixed"; + regulator-name = "Panel VccQ"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 13 GPIO_ACTIVE_LOW>; + enable-active-high; + }; - status = "okay"; + vccq_sdhi0: regulator-vccq-sdhi0 { + compatible = "regulator-gpio"; - ports { - port@0 { - endpoint { - remote-endpoint = <&lcd_in>; - }; + regulator-name = "SDHI0 VccQ"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; + gpios-states = <1>; + states = <3300000 1>, <1800000 0>; + }; + + rsnd_sgtl5000: sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&sndcodec>; + simple-audio-card,frame-master = <&sndcodec>; + + sndcpu: simple-audio-card,cpu { + sound-dai = <&rcar_sound>; + }; + + sndcodec: simple-audio-card,codec { + sound-dai = <&sgtl5000>; }; }; }; @@ -150,6 +135,21 @@ status = "okay"; }; +&du { + pinctrl-0 = <&du0_pins>; + pinctrl-names = "default"; + + status = "okay"; + + ports { + port@0 { + endpoint { + remote-endpoint = <&lcd_in>; + }; + }; + }; +}; + &hscif1 { pinctrl-0 = <&hscif1_pins>; pinctrl-names = "default"; @@ -171,6 +171,15 @@ status = "okay"; clock-frequency = <400000>; + sgtl5000: codec@a { + compatible = "fsl,sgtl5000"; + #sound-dai-cells = <0>; + reg = <0x0a>; + clocks = <&audio_clock>; + VDDA-supply = <®_3p3v>; + VDDIO-supply = <®_3p3v>; + }; + stmpe811@44 { compatible = "st,stmpe811"; reg = <0x44>; @@ -179,7 +188,7 @@ /* 3.25 MHz ADC clock speed */ st,adc-freq = <1>; - /* ADC converstion time: 80 clocks */ + /* ADC conversion time: 80 clocks */ st,sample-time = <4>; /* 12-bit ADC */ st,mod-12b = <1>; @@ -203,15 +212,6 @@ st,touch-det-delay = <5>; }; }; - - sgtl5000: codec@a { - compatible = "fsl,sgtl5000"; - #sound-dai-cells = <0>; - reg = <0x0a>; - clocks = <&audio_clock>; - VDDA-supply = <®_3p3v>; - VDDIO-supply = <®_3p3v>; - }; }; &pci1 { diff --git a/arch/arm/boot/dts/r8a7745.dtsi b/arch/arm/boot/dts/r8a7745.dtsi index 636248f370e0..0f14ac22921d 100644 --- a/arch/arm/boot/dts/r8a7745.dtsi +++ b/arch/arm/boot/dts/r8a7745.dtsi @@ -230,7 +230,7 @@ resets = <&cpg 905>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a7745"; reg = <0 0xe6060000 0 0x11c>; }; diff --git a/arch/arm/boot/dts/r8a77470.dtsi b/arch/arm/boot/dts/r8a77470.dtsi index 6baa126b6590..691b1a131c87 100644 --- a/arch/arm/boot/dts/r8a77470.dtsi +++ b/arch/arm/boot/dts/r8a77470.dtsi @@ -187,7 +187,7 @@ resets = <&cpg 907>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a77470"; reg = <0 0xe6060000 0 0x118>; }; diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi index 1612b003fb55..c9f8735860bf 100644 --- a/arch/arm/boot/dts/r8a7778.dtsi +++ b/arch/arm/boot/dts/r8a7778.dtsi @@ -142,7 +142,7 @@ interrupt-controller; }; - pfc: pin-controller@fffc0000 { + pfc: pinctrl@fffc0000 { compatible = "renesas,pfc-r8a7778"; reg = <0xfffc0000 0x118>; }; diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index c5634daef96f..74d7e9084eab 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -321,7 +321,7 @@ status = "disabled"; }; - pfc: pin-controller@fffc0000 { + pfc: pinctrl@fffc0000 { compatible = "renesas,pfc-r8a7779"; reg = <0xfffc0000 0x23c>; }; diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 769ba2a33d39..b0569b4ea5c8 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -363,7 +363,7 @@ resets = <&cpg 907>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a7790"; reg = <0 0xe6060000 0 0x250>; }; diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 499cf388735f..87f0d6dc3e5a 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -286,7 +286,7 @@ resets = <&cpg 904>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a7791"; reg = <0 0xe6060000 0 0x250>; }; diff --git a/arch/arm/boot/dts/r8a7792.dtsi b/arch/arm/boot/dts/r8a7792.dtsi index 597848ad4dfa..f5b299bfcb23 100644 --- a/arch/arm/boot/dts/r8a7792.dtsi +++ b/arch/arm/boot/dts/r8a7792.dtsi @@ -296,7 +296,7 @@ resets = <&cpg 913>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a7792"; reg = <0 0xe6060000 0 0x144>; }; diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index 6d507091b163..f930f69f7bcc 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -271,7 +271,7 @@ resets = <&cpg 904>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a7793"; reg = <0 0xe6060000 0 0x250>; }; diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index 5f340397ab64..cd5e2904068a 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -238,7 +238,7 @@ resets = <&cpg 905>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a7794"; reg = <0 0xe6060000 0 0x11c>; }; diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi index ee59cc84f212..c47896e4ab58 100644 --- a/arch/arm/boot/dts/r9a06g032.dtsi +++ b/arch/arm/boot/dts/r9a06g032.dtsi @@ -165,7 +165,7 @@ status = "disabled"; }; - pinctrl: pin-controller@40067000 { + pinctrl: pinctrl@40067000 { compatible = "renesas,r9a06g032-pinctrl", "renesas,rzn1-pinctrl"; reg = <0x40067000 0x1000>, <0x51000000 0x480>; clocks = <&sysctrl R9A06G032_HCLK_PINCONFIG>; diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts index 0a56a2f1bc4d..eba7a1344976 100644 --- a/arch/arm/boot/dts/rk3066a-bqcurie2.dts +++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts @@ -63,7 +63,11 @@ }; &cpu0 { - cpu0-supply = <&vdd_arm>; + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; }; &i2c1 { diff --git a/arch/arm/boot/dts/rk3066a-marsboard.dts b/arch/arm/boot/dts/rk3066a-marsboard.dts index 7e01f6406a86..6b121658d93c 100644 --- a/arch/arm/boot/dts/rk3066a-marsboard.dts +++ b/arch/arm/boot/dts/rk3066a-marsboard.dts @@ -47,7 +47,11 @@ }; &cpu0 { - cpu0-supply = <&vdd_arm>; + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; }; &i2c1 { diff --git a/arch/arm/boot/dts/rk3066a-rayeager.dts b/arch/arm/boot/dts/rk3066a-rayeager.dts index f9db6bb9fa11..309518403d86 100644 --- a/arch/arm/boot/dts/rk3066a-rayeager.dts +++ b/arch/arm/boot/dts/rk3066a-rayeager.dts @@ -128,7 +128,11 @@ }; &cpu0 { - cpu0-supply = <&vdd_arm>; + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; }; &emac { diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index b599394d149d..252750c97f97 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -36,7 +36,7 @@ clock-latency = <40000>; clocks = <&cru ARMCLK>; }; - cpu@1 { + cpu1: cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a9"; next-level-cache = <&L2>; diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi index 018802df4c0e..c4ca73b40d4a 100644 --- a/arch/arm/boot/dts/rk3288-evb.dtsi +++ b/arch/arm/boot/dts/rk3288-evb.dtsi @@ -247,7 +247,7 @@ pinctrl-0 = <&rgmii_pins>; tx_delay = <0x30>; rx_delay = <0x10>; - status = "ok"; + status = "okay"; }; &gpu { diff --git a/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi b/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi index 61435d8ee37b..36efa36b7190 100644 --- a/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi +++ b/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi @@ -61,7 +61,7 @@ snps,reset-gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_LOW>; tx_delay = <0x30>; rx_delay = <0x10>; - status = "ok"; + status = "okay"; }; &i2c0 { diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi index e5c4fd4ea67e..7fb582302b32 100644 --- a/arch/arm/boot/dts/rk3288-firefly.dtsi +++ b/arch/arm/boot/dts/rk3288-firefly.dtsi @@ -191,7 +191,7 @@ snps,reset-gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_LOW>; tx_delay = <0x30>; rx_delay = <0x10>; - status = "ok"; + status = "okay"; }; &gpu { diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts index 213c9eb84f76..cf54d5ffff2f 100644 --- a/arch/arm/boot/dts/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rk3288-miqi.dts @@ -81,7 +81,19 @@ }; &cpu0 { - cpu0-supply = <&vdd_cpu>; + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; }; &emmc { @@ -108,7 +120,7 @@ snps,reset-gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_LOW>; tx_delay = <0x30>; rx_delay = <0x10>; - status = "ok"; + status = "okay"; }; &hdmi { diff --git a/arch/arm/boot/dts/rk3288-popmetal.dts b/arch/arm/boot/dts/rk3288-popmetal.dts index 6a51940398b5..8c7376d64bc4 100644 --- a/arch/arm/boot/dts/rk3288-popmetal.dts +++ b/arch/arm/boot/dts/rk3288-popmetal.dts @@ -103,7 +103,19 @@ }; &cpu0 { - cpu0-supply = <&vdd_cpu>; + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; }; &emmc { @@ -149,7 +161,7 @@ pinctrl-0 = <&rgmii_pins>; tx_delay = <0x30>; rx_delay = <0x10>; - status = "ok"; + status = "okay"; }; &hdmi { diff --git a/arch/arm/boot/dts/rk3288-r89.dts b/arch/arm/boot/dts/rk3288-r89.dts index a258c7ae5329..55467bc30fa6 100644 --- a/arch/arm/boot/dts/rk3288-r89.dts +++ b/arch/arm/boot/dts/rk3288-r89.dts @@ -91,7 +91,19 @@ }; &cpu0 { - cpu0-supply = <&vdd_cpu>; + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; }; &gmac { @@ -107,7 +119,7 @@ pinctrl-0 = <&rgmii_pins>; tx_delay = <0x30>; rx_delay = <0x10>; - status = "ok"; + status = "okay"; }; &hdmi { diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts index 3cca4d0f9b09..c4d1d142d8c6 100644 --- a/arch/arm/boot/dts/rk3288-rock2-square.dts +++ b/arch/arm/boot/dts/rk3288-rock2-square.dts @@ -156,7 +156,7 @@ }; &gmac { - status = "ok"; + status = "okay"; }; &hdmi { diff --git a/arch/arm/boot/dts/rk3288-tinker.dtsi b/arch/arm/boot/dts/rk3288-tinker.dtsi index 90e9be443fe6..9c1e38c54eae 100644 --- a/arch/arm/boot/dts/rk3288-tinker.dtsi +++ b/arch/arm/boot/dts/rk3288-tinker.dtsi @@ -137,7 +137,7 @@ snps,reset-delays-us = <0 10000 1000000>; tx_delay = <0x30>; rx_delay = <0x10>; - status = "ok"; + status = "okay"; }; &gpu { diff --git a/arch/arm/boot/dts/rk3288-vyasa.dts b/arch/arm/boot/dts/rk3288-vyasa.dts index 1a20854a1317..aa50f8ed4ca0 100644 --- a/arch/arm/boot/dts/rk3288-vyasa.dts +++ b/arch/arm/boot/dts/rk3288-vyasa.dts @@ -125,7 +125,19 @@ }; &cpu0 { - cpu0-supply = <&vdd_cpu>; + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; }; &emmc { diff --git a/arch/arm/boot/dts/s3c2416-smdk2416.dts b/arch/arm/boot/dts/s3c2416-smdk2416.dts index 811bfdef4e9b..47626ede6fdd 100644 --- a/arch/arm/boot/dts/s3c2416-smdk2416.dts +++ b/arch/arm/boot/dts/s3c2416-smdk2416.dts @@ -17,18 +17,11 @@ reg = <0x30000000 0x4000000>; }; - clocks { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - xti: xti@0 { - compatible = "fixed-clock"; - reg = <0>; - clock-frequency = <12000000>; - clock-output-names = "xti"; - #clock-cells = <0>; - }; + xti: clock-0 { + compatible = "fixed-clock"; + clock-frequency = <12000000>; + clock-output-names = "xti"; + #clock-cells = <0>; }; }; diff --git a/arch/arm/boot/dts/s3c2416.dtsi b/arch/arm/boot/dts/s3c2416.dtsi index 6adf64ea3ff2..4f084f4fe44f 100644 --- a/arch/arm/boot/dts/s3c2416.dtsi +++ b/arch/arm/boot/dts/s3c2416.dtsi @@ -18,54 +18,22 @@ }; cpus { - cpu { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; compatible = "arm,arm926ej-s"; + reg = <0x0>; }; }; - interrupt-controller@4a000000 { - compatible = "samsung,s3c2416-irq"; - }; - clocks: clock-controller@4c000000 { compatible = "samsung,s3c2416-clock"; reg = <0x4c000000 0x40>; #clock-cells = <1>; }; - pinctrl@56000000 { - compatible = "samsung,s3c2416-pinctrl"; - }; - - timer@51000000 { - clocks = <&clocks PCLK_PWM>; - clock-names = "timers"; - }; - - uart_0: serial@50000000 { - compatible = "samsung,s3c2440-uart"; - clock-names = "uart", "clk_uart_baud2", - "clk_uart_baud3"; - clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>, - <&clocks SCLK_UART>; - }; - - uart_1: serial@50004000 { - compatible = "samsung,s3c2440-uart"; - clock-names = "uart", "clk_uart_baud2", - "clk_uart_baud3"; - clocks = <&clocks PCLK_UART1>, <&clocks PCLK_UART1>, - <&clocks SCLK_UART>; - }; - - uart_2: serial@50008000 { - compatible = "samsung,s3c2440-uart"; - clock-names = "uart", "clk_uart_baud2", - "clk_uart_baud3"; - clocks = <&clocks PCLK_UART2>, <&clocks PCLK_UART2>, - <&clocks SCLK_UART>; - }; - uart_3: serial@5000c000 { compatible = "samsung,s3c2440-uart"; reg = <0x5000C000 0x4000>; @@ -98,22 +66,59 @@ <&clocks MUX_HSMMC1>; status = "disabled"; }; +}; - watchdog: watchdog@53000000 { - interrupts = <1 9 27 3>; - clocks = <&clocks PCLK_WDT>; - clock-names = "watchdog"; - }; +&i2c { + compatible = "samsung,s3c2440-i2c"; + clocks = <&clocks PCLK_I2C0>; + clock-names = "i2c"; +}; - rtc: rtc@57000000 { - compatible = "samsung,s3c2416-rtc"; - clocks = <&clocks PCLK_RTC>; - clock-names = "rtc"; - }; +&intc { + compatible = "samsung,s3c2416-irq"; +}; - i2c@54000000 { - compatible = "samsung,s3c2440-i2c"; - clocks = <&clocks PCLK_I2C0>; - clock-names = "i2c"; - }; +&pinctrl_0 { + compatible = "samsung,s3c2416-pinctrl"; +}; + +&rtc { + compatible = "samsung,s3c2416-rtc"; + clocks = <&clocks PCLK_RTC>; + clock-names = "rtc"; +}; + +&timer { + clocks = <&clocks PCLK_PWM>; + clock-names = "timers"; +}; + +&uart_0 { + compatible = "samsung,s3c2440-uart"; + clock-names = "uart", "clk_uart_baud2", + "clk_uart_baud3"; + clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>, + <&clocks SCLK_UART>; +}; + +&uart_1 { + compatible = "samsung,s3c2440-uart"; + clock-names = "uart", "clk_uart_baud2", + "clk_uart_baud3"; + clocks = <&clocks PCLK_UART1>, <&clocks PCLK_UART1>, + <&clocks SCLK_UART>; +}; + +&uart_2 { + compatible = "samsung,s3c2440-uart"; + clock-names = "uart", "clk_uart_baud2", + "clk_uart_baud3"; + clocks = <&clocks PCLK_UART2>, <&clocks PCLK_UART2>, + <&clocks SCLK_UART>; +}; + +&watchdog { + interrupts = <1 9 27 3>; + clocks = <&clocks PCLK_WDT>; + clock-names = "watchdog"; }; diff --git a/arch/arm/boot/dts/s3c24xx.dtsi b/arch/arm/boot/dts/s3c24xx.dtsi index 6d8dd3cdd3c0..06f82c7e458e 100644 --- a/arch/arm/boot/dts/s3c24xx.dtsi +++ b/arch/arm/boot/dts/s3c24xx.dtsi @@ -13,12 +13,12 @@ aliases { pinctrl0 = &pinctrl_0; - serial0 = &uart0; - serial1 = &uart1; - serial2 = &uart2; + serial0 = &uart_0; + serial1 = &uart_1; + serial2 = &uart_2; }; - intc:interrupt-controller@4a000000 { + intc: interrupt-controller@4a000000 { compatible = "samsung,s3c2410-irq"; reg = <0x4a000000 0x100>; interrupt-controller; @@ -39,49 +39,49 @@ }; }; - timer@51000000 { + timer: pwm@51000000 { compatible = "samsung,s3c2410-pwm"; reg = <0x51000000 0x1000>; interrupts = <0 0 10 3>, <0 0 11 3>, <0 0 12 3>, <0 0 13 3>, <0 0 14 3>; - #pwm-cells = <4>; + #pwm-cells = <3>; }; - uart0: serial@50000000 { + uart_0: serial@50000000 { compatible = "samsung,s3c2410-uart"; reg = <0x50000000 0x4000>; interrupts = <1 28 0 4>, <1 28 1 4>; status = "disabled"; }; - uart1: serial@50004000 { + uart_1: serial@50004000 { compatible = "samsung,s3c2410-uart"; reg = <0x50004000 0x4000>; interrupts = <1 23 3 4>, <1 23 4 4>; status = "disabled"; }; - uart2: serial@50008000 { + uart_2: serial@50008000 { compatible = "samsung,s3c2410-uart"; reg = <0x50008000 0x4000>; interrupts = <1 15 6 4>, <1 15 7 4>; status = "disabled"; }; - watchdog@53000000 { + watchdog: watchdog@53000000 { compatible = "samsung,s3c2410-wdt"; reg = <0x53000000 0x100>; interrupts = <0 0 9 3>; status = "disabled"; }; - rtc@57000000 { + rtc: rtc@57000000 { compatible = "samsung,s3c2410-rtc"; reg = <0x57000000 0x100>; interrupts = <0 0 30 3>, <0 0 8 3>; status = "disabled"; }; - i2c@54000000 { + i2c: i2c@54000000 { compatible = "samsung,s3c2410-i2c"; reg = <0x54000000 0x100>; interrupts = <0 0 27 3>; diff --git a/arch/arm/boot/dts/s3c6410-mini6410.dts b/arch/arm/boot/dts/s3c6410-mini6410.dts index 1aeac33b0d34..285555b9ed94 100644 --- a/arch/arm/boot/dts/s3c6410-mini6410.dts +++ b/arch/arm/boot/dts/s3c6410-mini6410.dts @@ -28,29 +28,21 @@ bootargs = "console=ttySAC0,115200n8 earlyprintk rootwait root=/dev/mmcblk0p1"; }; - clocks { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - fin_pll: oscillator@0 { - compatible = "fixed-clock"; - reg = <0>; - clock-frequency = <12000000>; - clock-output-names = "fin_pll"; - #clock-cells = <0>; - }; + fin_pll: oscillator-0 { + compatible = "fixed-clock"; + clock-frequency = <12000000>; + clock-output-names = "fin_pll"; + #clock-cells = <0>; + }; - xusbxti: oscillator@1 { - compatible = "fixed-clock"; - reg = <1>; - clock-output-names = "xusbxti"; - clock-frequency = <48000000>; - #clock-cells = <0>; - }; + xusbxti: oscillator-1 { + compatible = "fixed-clock"; + clock-output-names = "xusbxti"; + clock-frequency = <48000000>; + #clock-cells = <0>; }; - srom-cs1@18000000 { + srom-cs1-bus@18000000 { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/s3c6410-smdk6410.dts b/arch/arm/boot/dts/s3c6410-smdk6410.dts index 96267f5f02a8..69c9ec4cf381 100644 --- a/arch/arm/boot/dts/s3c6410-smdk6410.dts +++ b/arch/arm/boot/dts/s3c6410-smdk6410.dts @@ -28,29 +28,21 @@ bootargs = "console=ttySAC0,115200n8 earlyprintk rootwait root=/dev/mmcblk0p1"; }; - clocks { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - fin_pll: oscillator@0 { - compatible = "fixed-clock"; - reg = <0>; - clock-frequency = <12000000>; - clock-output-names = "fin_pll"; - #clock-cells = <0>; - }; + fin_pll: oscillator-0 { + compatible = "fixed-clock"; + clock-frequency = <12000000>; + clock-output-names = "fin_pll"; + #clock-cells = <0>; + }; - xusbxti: oscillator@1 { - compatible = "fixed-clock"; - reg = <1>; - clock-output-names = "xusbxti"; - clock-frequency = <48000000>; - #clock-cells = <0>; - }; + xusbxti: oscillator-1 { + compatible = "fixed-clock"; + clock-output-names = "xusbxti"; + clock-frequency = <48000000>; + #clock-cells = <0>; }; - srom-cs1@18000000 { + srom-cs1-bus@18000000 { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/s3c64xx.dtsi b/arch/arm/boot/dts/s3c64xx.dtsi index 2e611df37911..cb11a87dbc42 100644 --- a/arch/arm/boot/dts/s3c64xx.dtsi +++ b/arch/arm/boot/dts/s3c64xx.dtsi @@ -34,7 +34,7 @@ cpu@0 { device_type = "cpu"; - compatible = "arm,arm1176jzf-s", "arm,arm1176"; + compatible = "arm,arm1176jzf-s"; reg = <0x0>; }; }; diff --git a/arch/arm/boot/dts/s5pv210-aquila.dts b/arch/arm/boot/dts/s5pv210-aquila.dts index 14969b6529e8..8e57e5a1f0c5 100644 --- a/arch/arm/boot/dts/s5pv210-aquila.dts +++ b/arch/arm/boot/dts/s5pv210-aquila.dts @@ -11,6 +11,7 @@ */ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> #include "s5pv210.dtsi" @@ -32,42 +33,40 @@ 0x40000000 0x18000000>; }; - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; + pmic_ap_clk: clock-0 { + /* Workaround for missing clock on PMIC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; - vtf_reg: fixed-regulator@0 { - compatible = "regulator-fixed"; - reg = <0>; - regulator-name = "V_TF_2.8V"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - gpio = <&mp05 4 0>; - enable-active-high; - }; + vtf_reg: regulator-0 { + compatible = "regulator-fixed"; + regulator-name = "V_TF_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + gpio = <&mp05 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; - pda_reg: fixed-regulator@1 { - compatible = "regulator-fixed"; - regulator-name = "VCC_1.8V_PDA"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - reg = <1>; - }; + pda_reg: regulator-1 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1.8V_PDA"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; - bat_reg: fixed-regulator@2 { - compatible = "regulator-fixed"; - regulator-name = "V_BAT"; - regulator-min-microvolt = <3700000>; - regulator-max-microvolt = <3700000>; - reg = <2>; - }; + bat_reg: regulator-2 { + compatible = "regulator-fixed"; + regulator-name = "V_BAT"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; }; i2c_pmic: i2c-pmic { compatible = "i2c-gpio"; - gpios = <&gpj4 0 0>, /* sda */ - <&gpj4 3 0>; /* scl */ + sda-gpios = <&gpj4 0 GPIO_ACTIVE_HIGH>; + scl-gpios = <&gpj4 3 GPIO_ACTIVE_HIGH>; i2c-gpio,delay-us = <2>; /* ~100 kHz */ #address-cells = <1>; #size-cells = <0>; @@ -77,13 +76,13 @@ reg = <0x66>; max8998,pmic-buck1-default-dvs-idx = <0>; - max8998,pmic-buck1-dvs-gpios = <&gph0 3 0>, - <&gph0 4 0>; + max8998,pmic-buck1-dvs-gpios = <&gph0 3 GPIO_ACTIVE_HIGH>, + <&gph0 4 GPIO_ACTIVE_HIGH>; max8998,pmic-buck1-dvs-voltage = <1200000>, <1200000>, <1200000>, <1200000>; max8998,pmic-buck2-default-dvs-idx = <0>; - max8998,pmic-buck2-dvs-gpio = <&gph0 5 0>; + max8998,pmic-buck2-dvs-gpio = <&gph0 5 GPIO_ACTIVE_HIGH>; max8998,pmic-buck2-dvs-voltage = <1200000>, <1200000>; regulators { @@ -228,6 +227,11 @@ regulator-always-on; }; + ap32khz_reg: EN32KHz-AP { + regulator-name = "32KHz AP"; + regulator-always-on; + }; + vichg_reg: ENVICHG { regulator-name = "VICHG"; }; @@ -326,6 +330,11 @@ status = "okay"; }; +&rtc { + clocks = <&clocks CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; +}; + &sdhci0 { bus-width = <4>; non-removable; diff --git a/arch/arm/boot/dts/s5pv210-aries.dtsi b/arch/arm/boot/dts/s5pv210-aries.dtsi index 822207f63ee0..bd4450dbdcb6 100644 --- a/arch/arm/boot/dts/s5pv210-aries.dtsi +++ b/arch/arm/boot/dts/s5pv210-aries.dtsi @@ -47,6 +47,18 @@ }; }; + pmic_ap_clk: clock-0 { + /* Workaround for missing clock on PMIC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + bt_codec: bt_sco { + compatible = "linux,bt-sco"; + #sound-dai-cells = <0>; + }; + vibrator_pwr: regulator-fixed-0 { compatible = "regulator-fixed"; regulator-name = "vibrator-en"; @@ -54,7 +66,7 @@ gpio = <&gpj1 1 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; - pinctr-0 = <&vibrator_ena>; + pinctrl-0 = <&vibrator_ena>; }; touchkey_vdd: regulator-fixed-1 { @@ -533,7 +545,7 @@ value = <0x5200>; }; - spi_lcd: spi-gpio-0 { + spi_lcd: spi-2 { compatible = "spi-gpio"; #address-cells = <1>; #size-cells = <0>; @@ -624,6 +636,11 @@ }; }; +&i2s0 { + dmas = <&pdma0 9>, <&pdma0 10>, <&pdma0 11>; + status = "okay"; +}; + &mfc { memory-region = <&mfc_left>, <&mfc_right>; }; @@ -815,6 +832,11 @@ samsung,pwm-outputs = <1>; }; +&rtc { + clocks = <&clocks CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; +}; + &sdhci1 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/s5pv210-fascinate4g.dts b/arch/arm/boot/dts/s5pv210-fascinate4g.dts index 65eed01cfced..ca064359dd30 100644 --- a/arch/arm/boot/dts/s5pv210-fascinate4g.dts +++ b/arch/arm/boot/dts/s5pv210-fascinate4g.dts @@ -35,6 +35,80 @@ linux,code = <KEY_VOLUMEUP>; }; }; + + headset_micbias_reg: regulator-fixed-3 { + compatible = "regulator-fixed"; + regulator-name = "Headset_Micbias"; + gpio = <&gpj2 5 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&headset_micbias_ena>; + }; + + main_micbias_reg: regulator-fixed-4 { + compatible = "regulator-fixed"; + regulator-name = "Main_Micbias"; + gpio = <&gpj4 2 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&main_micbias_ena>; + }; + + sound { + compatible = "samsung,fascinate4g-wm8994"; + + model = "Fascinate4G"; + + extcon = <&fsa9480>; + + main-micbias-supply = <&main_micbias_reg>; + headset-micbias-supply = <&headset_micbias_reg>; + + earpath-sel-gpios = <&gpj2 6 GPIO_ACTIVE_HIGH>; + + io-channels = <&adc 3>; + io-channel-names = "headset-detect"; + headset-detect-gpios = <&gph0 6 GPIO_ACTIVE_HIGH>; + headset-key-gpios = <&gph3 6 GPIO_ACTIVE_HIGH>; + + samsung,audio-routing = + "HP", "HPOUT1L", + "HP", "HPOUT1R", + + "SPK", "SPKOUTLN", + "SPK", "SPKOUTLP", + + "RCV", "HPOUT2N", + "RCV", "HPOUT2P", + + "LINE", "LINEOUT2N", + "LINE", "LINEOUT2P", + + "IN1LP", "Main Mic", + "IN1LN", "Main Mic", + + "IN1RP", "Headset Mic", + "IN1RN", "Headset Mic", + + "Modem Out", "Modem TX", + "Modem RX", "Modem In", + + "Bluetooth SPK", "TX", + "RX", "Bluetooth Mic"; + + pinctrl-names = "default"; + pinctrl-0 = <&headset_det &earpath_sel>; + + cpu { + sound-dai = <&i2s0>, <&bt_codec>; + }; + + codec { + sound-dai = <&wm8994>; + }; + }; }; &fg { @@ -51,6 +125,12 @@ pinctrl-names = "default"; pinctrl-0 = <&sleep_cfg>; + headset_det: headset-det { + samsung,pins = "gph0-6", "gph3-6"; + samsung,pin-function = <EXYNOS_PIN_FUNC_F>; + samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>; + }; + fg_irq: fg-irq { samsung,pins = "gph3-3"; samsung,pin-function = <EXYNOS_PIN_FUNC_F>; @@ -58,6 +138,24 @@ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>; }; + headset_micbias_ena: headset-micbias-ena { + samsung,pins = "gpj2-5"; + samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>; + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>; + }; + + earpath_sel: earpath-sel { + samsung,pins = "gpj2-6"; + samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>; + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>; + }; + + main_micbias_ena: main-micbias-ena { + samsung,pins = "gpj4-2"; + samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>; + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>; + }; + /* Based on vendor kernel v2.6.35.7 */ sleep_cfg: sleep-cfg { PIN_SLP(gpa0-0, PREV, NONE); diff --git a/arch/arm/boot/dts/s5pv210-galaxys.dts b/arch/arm/boot/dts/s5pv210-galaxys.dts index 5d10dd67eacc..560f830b6f6b 100644 --- a/arch/arm/boot/dts/s5pv210-galaxys.dts +++ b/arch/arm/boot/dts/s5pv210-galaxys.dts @@ -72,6 +72,73 @@ pinctrl-0 = <&fm_irq &fm_rst>; }; }; + + micbias_reg: regulator-fixed-3 { + compatible = "regulator-fixed"; + regulator-name = "MICBIAS"; + gpio = <&gpj4 2 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&micbias_reg_ena>; + }; + + sound { + compatible = "samsung,aries-wm8994"; + + model = "Aries"; + + extcon = <&fsa9480>; + + main-micbias-supply = <&micbias_reg>; + headset-micbias-supply = <&micbias_reg>; + + earpath-sel-gpios = <&gpj2 6 GPIO_ACTIVE_HIGH>; + + io-channels = <&adc 3>; + io-channel-names = "headset-detect"; + headset-detect-gpios = <&gph0 6 GPIO_ACTIVE_LOW>; + headset-key-gpios = <&gph3 6 GPIO_ACTIVE_HIGH>; + + samsung,audio-routing = + "HP", "HPOUT1L", + "HP", "HPOUT1R", + + "SPK", "SPKOUTLN", + "SPK", "SPKOUTLP", + + "RCV", "HPOUT2N", + "RCV", "HPOUT2P", + + "LINE", "LINEOUT2N", + "LINE", "LINEOUT2P", + + "IN1LP", "Main Mic", + "IN1LN", "Main Mic", + + "IN1RP", "Headset Mic", + "IN1RN", "Headset Mic", + + "IN2LN", "FM In", + "IN2RN", "FM In", + + "Modem Out", "Modem TX", + "Modem RX", "Modem In", + + "Bluetooth SPK", "TX", + "RX", "Bluetooth Mic"; + + pinctrl-names = "default"; + pinctrl-0 = <&headset_det &earpath_sel>; + + cpu { + sound-dai = <&i2s0>, <&bt_codec>; + }; + + codec { + sound-dai = <&wm8994>; + }; + }; }; &aliases { @@ -88,6 +155,12 @@ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>; }; + headset_det: headset-det { + samsung,pins = "gph0-6", "gph3-6"; + samsung,pin-function = <EXYNOS_PIN_FUNC_F>; + samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>; + }; + fm_irq: fm-irq { samsung,pins = "gpj2-4"; samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>; @@ -102,6 +175,12 @@ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>; }; + earpath_sel: earpath-sel { + samsung,pins = "gpj2-6"; + samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>; + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>; + }; + massmemory_en: massmemory-en { samsung,pins = "gpj2-7"; samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; @@ -109,6 +188,12 @@ samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>; }; + micbias_reg_ena: micbias-reg-ena { + samsung,pins = "gpj4-2"; + samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>; + samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>; + }; + /* Based on CyanogenMod 3.0.101 kernel */ sleep_cfg: sleep-cfg { PIN_SLP(gpa0-0, PREV, NONE); diff --git a/arch/arm/boot/dts/s5pv210-goni.dts b/arch/arm/boot/dts/s5pv210-goni.dts index fbbd93707404..ad8d5d2fa32d 100644 --- a/arch/arm/boot/dts/s5pv210-goni.dts +++ b/arch/arm/boot/dts/s5pv210-goni.dts @@ -11,6 +11,8 @@ */ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/input/input.h> #include "s5pv210.dtsi" @@ -33,52 +35,49 @@ 0x50000000 0x08000000>; }; - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; + pmic_ap_clk: clock-0 { + /* Workaround for missing clock on PMIC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; - vtf_reg: fixed-regulator@0 { - compatible = "regulator-fixed"; - regulator-name = "V_TF_2.8V"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - reg = <0>; - gpio = <&mp05 4 0>; - enable-active-high; - }; + vtf_reg: regulator-0 { + compatible = "regulator-fixed"; + regulator-name = "V_TF_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + gpio = <&mp05 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; - pda_reg: fixed-regulator@1 { - compatible = "regulator-fixed"; - regulator-name = "VCC_1.8V_PDA"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - reg = <1>; - }; + pda_reg: regulator-1 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1.8V_PDA"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; - bat_reg: fixed-regulator@2 { - compatible = "regulator-fixed"; - regulator-name = "V_BAT"; - regulator-min-microvolt = <3700000>; - regulator-max-microvolt = <3700000>; - reg = <2>; - }; + bat_reg: regulator-2 { + compatible = "regulator-fixed"; + regulator-name = "V_BAT"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + }; - tsp_reg: fixed-regulator@3 { - compatible = "regulator-fixed"; - regulator-name = "TSP_VDD"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - reg = <3>; - gpio = <&gpj1 3 0>; - enable-active-high; - }; + tsp_reg: regulator-3 { + compatible = "regulator-fixed"; + regulator-name = "TSP_VDD"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + gpio = <&gpj1 3 GPIO_ACTIVE_HIGH>; + enable-active-high; }; i2c_pmic: i2c-pmic { compatible = "i2c-gpio"; - gpios = <&gpj4 0 0>, /* sda */ - <&gpj4 3 0>; /* scl */ + sda-gpios = <&gpj4 0 GPIO_ACTIVE_HIGH>; + scl-gpios = <&gpj4 3 GPIO_ACTIVE_HIGH>; i2c-gpio,delay-us = <2>; /* ~100 kHz */ #address-cells = <1>; #size-cells = <0>; @@ -88,13 +87,13 @@ reg = <0x66>; max8998,pmic-buck1-default-dvs-idx = <0>; - max8998,pmic-buck1-dvs-gpios = <&gph0 3 0>, - <&gph0 4 0>; + max8998,pmic-buck1-dvs-gpios = <&gph0 3 GPIO_ACTIVE_HIGH>, + <&gph0 4 GPIO_ACTIVE_HIGH>; max8998,pmic-buck1-dvs-voltage = <1200000>, <1200000>, <1200000>, <1200000>; max8998,pmic-buck2-default-dvs-idx = <0>; - max8998,pmic-buck2-dvs-gpio = <&gph0 5 0>; + max8998,pmic-buck2-dvs-gpio = <&gph0 5 GPIO_ACTIVE_HIGH>; max8998,pmic-buck2-dvs-voltage = <1200000>, <1200000>; regulators { @@ -224,6 +223,11 @@ regulator-max-microvolt = <1200000>; regulator-always-on; }; + + ap32khz_reg: EN32KHz-AP { + regulator-name = "32KHz AP"; + regulator-always-on; + }; }; }; }; @@ -308,6 +312,11 @@ status = "okay"; }; +&rtc { + clocks = <&clocks CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; +}; + &sdhci0 { bus-width = <4>; non-removable; @@ -348,7 +357,7 @@ compatible = "atmel,maxtouch"; reg = <0x4a>; interrupt-parent = <&gpj0>; - interrupts = <5 2>; + interrupts = <5 IRQ_TYPE_EDGE_FALLING>; atmel,x-line = <17>; atmel,y-line = <11>; @@ -378,8 +387,8 @@ clock-frequency = <16000000>; clocks = <&camera 0>; clock-names = "mclk"; - nreset-gpios = <&gpb 2 0>; - nstby-gpios = <&gpb 0 0>; + nreset-gpios = <&gpb 2 GPIO_ACTIVE_HIGH>; + nstby-gpios = <&gpb 0 GPIO_ACTIVE_HIGH>; port { noon010pc30_ep: endpoint { diff --git a/arch/arm/boot/dts/s5pv210-smdkc110.dts b/arch/arm/boot/dts/s5pv210-smdkc110.dts index e5aec6c526fb..0c623b78af72 100644 --- a/arch/arm/boot/dts/s5pv210-smdkc110.dts +++ b/arch/arm/boot/dts/s5pv210-smdkc110.dts @@ -30,6 +30,13 @@ device_type = "memory"; reg = <0x20000000 0x20000000>; }; + + pmic_ap_clk: clock-0 { + /* Workaround for missing PMIC and its clock */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; }; &xusbxti { @@ -54,6 +61,8 @@ &rtc { status = "okay"; + clocks = <&clocks CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; }; &i2c0 { diff --git a/arch/arm/boot/dts/s5pv210-smdkv210.dts b/arch/arm/boot/dts/s5pv210-smdkv210.dts index 84b38f185199..7459e41e8ef1 100644 --- a/arch/arm/boot/dts/s5pv210-smdkv210.dts +++ b/arch/arm/boot/dts/s5pv210-smdkv210.dts @@ -15,6 +15,7 @@ */ /dts-v1/; +#include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/input/input.h> #include "s5pv210.dtsi" @@ -31,11 +32,18 @@ reg = <0x20000000 0x40000000>; }; - ethernet@18000000 { + pmic_ap_clk: clock-0 { + /* Workaround for missing PMIC and its clock */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + ethernet@a8000000 { compatible = "davicom,dm9000"; reg = <0xA8000000 0x2 0xA8000002 0x2>; interrupt-parent = <&gph1>; - interrupts = <1 4>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; local-mac-address = [00 00 de ad be ef]; davicom,no-eeprom; }; @@ -147,6 +155,8 @@ &rtc { status = "okay"; + clocks = <&clocks CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; }; &sdhci0 { diff --git a/arch/arm/boot/dts/s5pv210-torbreck.dts b/arch/arm/boot/dts/s5pv210-torbreck.dts index cd25e72ccd84..e18259737684 100644 --- a/arch/arm/boot/dts/s5pv210-torbreck.dts +++ b/arch/arm/boot/dts/s5pv210-torbreck.dts @@ -30,6 +30,13 @@ device_type = "memory"; reg = <0x20000000 0x20000000>; }; + + pmic_ap_clk: clock-0 { + /* Workaround for missing PMIC and its clock */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; }; &xusbxti { @@ -54,6 +61,8 @@ &rtc { status = "okay"; + clocks = <&clocks CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; }; &sdhci0 { diff --git a/arch/arm/boot/dts/s5pv210.dtsi b/arch/arm/boot/dts/s5pv210.dtsi index 1b0ee884e91d..2871351ab907 100644 --- a/arch/arm/boot/dts/s5pv210.dtsi +++ b/arch/arm/boot/dts/s5pv210.dtsi @@ -52,34 +52,26 @@ }; }; + xxti: oscillator-0 { + compatible = "fixed-clock"; + clock-frequency = <0>; + clock-output-names = "xxti"; + #clock-cells = <0>; + }; + + xusbxti: oscillator-1 { + compatible = "fixed-clock"; + clock-frequency = <0>; + clock-output-names = "xusbxti"; + #clock-cells = <0>; + }; + soc { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; - external-clocks { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - xxti: oscillator@0 { - compatible = "fixed-clock"; - reg = <0>; - clock-frequency = <0>; - clock-output-names = "xxti"; - #clock-cells = <0>; - }; - - xusbxti: oscillator@1 { - compatible = "fixed-clock"; - reg = <1>; - clock-frequency = <0>; - clock-output-names = "xusbxti"; - #clock-cells = <0>; - }; - }; - onenand: onenand@b0600000 { compatible = "samsung,s5pv210-onenand"; reg = <0xb0600000 0x2000>, @@ -100,19 +92,16 @@ }; clocks: clock-controller@e0100000 { - compatible = "samsung,s5pv210-clock", "simple-bus"; + compatible = "samsung,s5pv210-clock"; reg = <0xe0100000 0x10000>; clock-names = "xxti", "xusbxti"; clocks = <&xxti>, <&xusbxti>; #clock-cells = <1>; - #address-cells = <1>; - #size-cells = <1>; - ranges; + }; - pmu_syscon: syscon@e0108000 { - compatible = "samsung-s5pv210-pmu", "syscon"; - reg = <0xe0108000 0x8000>; - }; + pmu_syscon: syscon@e0108000 { + compatible = "samsung-s5pv210-pmu", "syscon"; + reg = <0xe0108000 0x8000>; }; pinctrl0: pinctrl@e0200000 { @@ -128,35 +117,28 @@ }; }; - amba { - #address-cells = <1>; - #size-cells = <1>; - compatible = "simple-bus"; - ranges; - - pdma0: dma@e0900000 { - compatible = "arm,pl330", "arm,primecell"; - reg = <0xe0900000 0x1000>; - interrupt-parent = <&vic0>; - interrupts = <19>; - clocks = <&clocks CLK_PDMA0>; - clock-names = "apb_pclk"; - #dma-cells = <1>; - #dma-channels = <8>; - #dma-requests = <32>; - }; + pdma0: dma@e0900000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0xe0900000 0x1000>; + interrupt-parent = <&vic0>; + interrupts = <19>; + clocks = <&clocks CLK_PDMA0>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + #dma-channels = <8>; + #dma-requests = <32>; + }; - pdma1: dma@e0a00000 { - compatible = "arm,pl330", "arm,primecell"; - reg = <0xe0a00000 0x1000>; - interrupt-parent = <&vic0>; - interrupts = <20>; - clocks = <&clocks CLK_PDMA1>; - clock-names = "apb_pclk"; - #dma-cells = <1>; - #dma-channels = <8>; - #dma-requests = <32>; - }; + pdma1: dma@e0a00000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0xe0a00000 0x1000>; + interrupt-parent = <&vic0>; + interrupts = <20>; + clocks = <&clocks CLK_PDMA1>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + #dma-channels = <8>; + #dma-requests = <32>; }; adc: adc@e1700000 { @@ -241,43 +223,36 @@ status = "disabled"; }; - audio-subsystem { - compatible = "samsung,s5pv210-audss", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - clk_audss: clock-controller@eee10000 { - compatible = "samsung,s5pv210-audss-clock"; - reg = <0xeee10000 0x1000>; - clock-names = "hclk", "xxti", - "fout_epll", - "sclk_audio0"; - clocks = <&clocks DOUT_HCLKP>, <&xxti>, - <&clocks FOUT_EPLL>, - <&clocks SCLK_AUDIO0>; - #clock-cells = <1>; - }; + clk_audss: clock-controller@eee10000 { + compatible = "samsung,s5pv210-audss-clock"; + reg = <0xeee10000 0x1000>; + clock-names = "hclk", "xxti", + "fout_epll", + "sclk_audio0"; + clocks = <&clocks DOUT_HCLKP>, <&xxti>, + <&clocks FOUT_EPLL>, + <&clocks SCLK_AUDIO0>; + #clock-cells = <1>; + }; - i2s0: i2s@eee30000 { - compatible = "samsung,s5pv210-i2s"; - reg = <0xeee30000 0x1000>; - interrupt-parent = <&vic2>; - interrupts = <16>; - dma-names = "rx", "tx", "tx-sec"; - dmas = <&pdma1 9>, <&pdma1 10>, <&pdma1 11>; - clock-names = "iis", - "i2s_opclk0", - "i2s_opclk1"; - clocks = <&clk_audss CLK_I2S>, - <&clk_audss CLK_I2S>, - <&clk_audss CLK_DOUT_AUD_BUS>; - samsung,idma-addr = <0xc0010000>; - pinctrl-names = "default"; - pinctrl-0 = <&i2s0_bus>; - #sound-dai-cells = <0>; - status = "disabled"; - }; + i2s0: i2s@eee30000 { + compatible = "samsung,s5pv210-i2s"; + reg = <0xeee30000 0x1000>; + interrupt-parent = <&vic2>; + interrupts = <16>; + dma-names = "rx", "tx", "tx-sec"; + dmas = <&pdma1 9>, <&pdma1 10>, <&pdma1 11>; + clock-names = "iis", + "i2s_opclk0", + "i2s_opclk1"; + clocks = <&clk_audss CLK_I2S>, + <&clk_audss CLK_I2S>, + <&clk_audss CLK_DOUT_AUD_BUS>; + samsung,idma-addr = <0xc0010000>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s0_bus>; + #sound-dai-cells = <0>; + status = "disabled"; }; i2s1: i2s@e2100000 { diff --git a/arch/arm/boot/dts/sam9x60.dtsi b/arch/arm/boot/dts/sam9x60.dtsi index d10843da4a85..84066c1298df 100644 --- a/arch/arm/boot/dts/sam9x60.dtsi +++ b/arch/arm/boot/dts/sam9x60.dtsi @@ -32,16 +32,17 @@ }; cpus { - #address-cells = <0>; + #address-cells = <1>; #size-cells = <0>; - cpu { + cpu@0 { compatible = "arm,arm926ej-s"; device_type = "cpu"; + reg = <0>; }; }; - memory { + memory@20000000 { device_type = "memory"; reg = <0x20000000 0x10000000>; }; @@ -61,6 +62,9 @@ sram: sram@300000 { compatible = "mmio-sram"; reg = <0x00300000 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00300000 0x100000>; }; ahb { @@ -69,6 +73,20 @@ #size-cells = <1>; ranges; + usb0: gadget@500000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "microchip,sam9x60-udc"; + reg = <0x00500000 0x100000 + 0xf803c000 0x400>; + interrupts = <23 IRQ_TYPE_LEVEL_HIGH 2>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 23>, <&pmc PMC_TYPE_CORE PMC_UTMI>; + clock-names = "pclk", "hclk"; + assigned-clocks = <&pmc PMC_TYPE_CORE PMC_UTMI>; + assigned-clock-rates = <480000000>; + status = "disabled"; + }; + usb1: ohci@600000 { compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00600000 0x100000>; diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi index d7f25706892d..2ddc85dff8ce 100644 --- a/arch/arm/boot/dts/sama5d2.dtsi +++ b/arch/arm/boot/dts/sama5d2.dtsi @@ -72,7 +72,7 @@ }; }; - memory { + memory@20000000 { device_type = "memory"; reg = <0x20000000 0x20000000>; }; @@ -94,6 +94,9 @@ ns_sram: sram@200000 { compatible = "mmio-sram"; reg = <0x00200000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00200000 0x20000>; }; ahb { @@ -106,6 +109,10 @@ compatible = "mmio-sram"; no-memory-wc; reg = <0x00100000 0x2400>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00100000 0x2400>; + }; usb0: gadget@300000 { @@ -535,6 +542,8 @@ compatible = "atmel,at91rm9200-spi"; reg = <0x400 0x200>; interrupts = <19 IRQ_TYPE_LEVEL_HIGH 7>; + #address-cells = <1>; + #size-cells = <0>; clocks = <&pmc PMC_TYPE_PERIPHERAL 19>; clock-names = "spi_clk"; dmas = <&dma0 @@ -603,6 +612,8 @@ compatible = "atmel,at91rm9200-spi"; reg = <0x400 0x200>; interrupts = <20 IRQ_TYPE_LEVEL_HIGH 7>; + #address-cells = <1>; + #size-cells = <0>; clocks = <&pmc PMC_TYPE_PERIPHERAL 20>; clock-names = "spi_clk"; dmas = <&dma0 @@ -810,6 +821,8 @@ compatible = "atmel,at91rm9200-spi"; reg = <0x400 0x200>; interrupts = <21 IRQ_TYPE_LEVEL_HIGH 7>; + #address-cells = <1>; + #size-cells = <0>; clocks = <&pmc PMC_TYPE_PERIPHERAL 21>; clock-names = "spi_clk"; dmas = <&dma0 @@ -878,6 +891,8 @@ compatible = "atmel,at91rm9200-spi"; reg = <0x400 0x200>; interrupts = <22 IRQ_TYPE_LEVEL_HIGH 7>; + #address-cells = <1>; + #size-cells = <0>; clocks = <&pmc PMC_TYPE_PERIPHERAL 22>; clock-names = "spi_clk"; dmas = <&dma0 @@ -947,6 +962,8 @@ compatible = "atmel,at91rm9200-spi"; reg = <0x400 0x200>; interrupts = <23 IRQ_TYPE_LEVEL_HIGH 7>; + #address-cells = <1>; + #size-cells = <0>; clocks = <&pmc PMC_TYPE_PERIPHERAL 23>; clock-names = "spi_clk"; dmas = <&dma0 diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index 0bb5b6fa0748..86137f8d2b45 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi @@ -55,7 +55,7 @@ interrupts = <46 IRQ_TYPE_LEVEL_HIGH 0>; }; - memory { + memory@20000000 { device_type = "memory"; reg = <0x20000000 0x8000000>; }; @@ -83,6 +83,9 @@ sram: sram@300000 { compatible = "mmio-sram"; reg = <0x00300000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00300000 0x20000>; }; ahb { @@ -1073,6 +1076,9 @@ compatible = "mmio-sram"; no-memory-wc; reg = <0x200000 0x2400>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x200000 0x2400>; }; usb0: gadget@500000 { diff --git a/arch/arm/boot/dts/sama5d3xcm.dtsi b/arch/arm/boot/dts/sama5d3xcm.dtsi index 65566e4b78d8..384335635792 100644 --- a/arch/arm/boot/dts/sama5d3xcm.dtsi +++ b/arch/arm/boot/dts/sama5d3xcm.dtsi @@ -14,7 +14,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x20000000>; }; diff --git a/arch/arm/boot/dts/sama5d3xcm_cmp.dtsi b/arch/arm/boot/dts/sama5d3xcm_cmp.dtsi index 9d2563602cbe..5579c955f141 100644 --- a/arch/arm/boot/dts/sama5d3xcm_cmp.dtsi +++ b/arch/arm/boot/dts/sama5d3xcm_cmp.dtsi @@ -12,7 +12,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x20000000>; }; diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 2d9f853ab15f..04f24cf752d3 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -53,7 +53,7 @@ }; }; - memory { + memory@20000000 { device_type = "memory"; reg = <0x20000000 0x20000000>; }; @@ -81,6 +81,9 @@ ns_sram: sram@210000 { compatible = "mmio-sram"; reg = <0x00210000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00210000 0x10000>; }; ahb { @@ -93,6 +96,9 @@ compatible = "mmio-sram"; no-memory-wc; reg = <0x100000 0x2400>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x100000 0x2400>; }; usb0: gadget@400000 { diff --git a/arch/arm/boot/dts/sd5203.dts b/arch/arm/boot/dts/sd5203.dts new file mode 100644 index 000000000000..3cc9a23910be --- /dev/null +++ b/arch/arm/boot/dts/sd5203.dts @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020 Hisilicon Limited. + * + * DTS file for Hisilicon SD5203 Board + */ + +/dts-v1/; + +/ { + model = "Hisilicon SD5203"; + compatible = "H836ASDJ", "hisilicon,sd5203"; + interrupt-parent = <&vic>; + #address-cells = <1>; + #size-cells = <1>; + + chosen { + bootargs="console=ttyS0,9600 earlycon=uart8250,mmio32,0x1600d000"; + }; + + aliases { + serial0 = &uart0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0 { + device_type = "cpu"; + compatible = "arm,arm926ej-s"; + reg = <0x0>; + }; + }; + + memory@30000000 { + device_type = "memory"; + reg = <0x30000000 0x8000000>; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + + vic: interrupt-controller@10130000 { + compatible = "snps,dw-apb-ictl"; + reg = <0x10130000 0x1000>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + refclk125mhz: refclk125mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + + timer0: timer@16002000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x16002000 0x1000>; + interrupts = <4>; + clocks = <&refclk125mhz>; + clock-names = "apb_pclk"; + }; + + timer1: timer@16003000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x16003000 0x1000>; + interrupts = <5>; + clocks = <&refclk125mhz>; + clock-names = "apb_pclk"; + }; + + uart0: serial@1600d000 { + compatible = "snps,dw-apb-uart"; + reg = <0x1600d000 0x1000>; + bus_id = "uart0"; + clocks = <&refclk125mhz>; + clock-names = "baudclk", "apb_pclk"; + reg-shift = <2>; + interrupts = <17>; + }; + + uart1: serial@1600c000 { + compatible = "snps,dw-apb-uart"; + reg = <0x1600c000 0x1000>; + clocks = <&refclk125mhz>; + clock-names = "baudclk", "apb_pclk"; + reg-shift = <2>; + interrupts = <16>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi index a4d63125ac56..30c67acc4e35 100644 --- a/arch/arm/boot/dts/sh73a0.dtsi +++ b/arch/arm/boot/dts/sh73a0.dtsi @@ -448,7 +448,7 @@ status = "disabled"; }; - pfc: pin-controller@e6050000 { + pfc: pinctrl@e6050000 { compatible = "renesas,pfc-sh73a0"; reg = <0xe6050000 0x8000>, <0xe605801c 0x1c>; diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi index fc4abef143a0..0013ec3463c4 100644 --- a/arch/arm/boot/dts/socfpga_arria10.dtsi +++ b/arch/arm/boot/dts/socfpga_arria10.dtsi @@ -821,7 +821,7 @@ timer3: timer3@ffd00100 { compatible = "snps,dw-apb-timer"; interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>; - reg = <0xffd01000 0x100>; + reg = <0xffd00100 0x100>; clocks = <&l4_sys_free_clk>; clock-names = "timer"; resets = <&rst L4SYSTIMER1_RESET>; diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi index f187da4485f4..c87b881b2c8b 100644 --- a/arch/arm/boot/dts/spear13xx.dtsi +++ b/arch/arm/boot/dts/spear13xx.dtsi @@ -43,7 +43,7 @@ 0 7 0x04>; }; - L2: l2-cache { + L2: cache-controller { compatible = "arm,pl310-cache"; reg = <0xed000000 0x1000>; cache-unified; diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi index 33e3b0b3c53d..ff47cbf6ed3b 100644 --- a/arch/arm/boot/dts/ste-href.dtsi +++ b/arch/arm/boot/dts/ste-href.dtsi @@ -58,16 +58,21 @@ reg = <0x33>; label = "lp5521_pri"; clock-mode = /bits/ 8 <2>; - chan0 { + #address-cells = <1>; + #size-cells = <0>; + chan@0 { + reg = <0>; led-cur = /bits/ 8 <0x2f>; max-cur = /bits/ 8 <0x5f>; linux,default-trigger = "heartbeat"; }; - chan1 { + chan@1 { + reg = <1>; led-cur = /bits/ 8 <0x2f>; max-cur = /bits/ 8 <0x5f>; }; - chan2 { + chan@2 { + reg = <2>; led-cur = /bits/ 8 <0x2f>; max-cur = /bits/ 8 <0x5f>; }; @@ -77,15 +82,20 @@ reg = <0x34>; label = "lp5521_sec"; clock-mode = /bits/ 8 <2>; - chan0 { + #address-cells = <1>; + #size-cells = <0>; + chan@0 { + reg = <0>; led-cur = /bits/ 8 <0x2f>; max-cur = /bits/ 8 <0x5f>; }; - chan1 { + chan@1 { + reg = <1>; led-cur = /bits/ 8 <0x2f>; max-cur = /bits/ 8 <0x5f>; }; - chan2 { + chan@2 { + reg = <2>; led-cur = /bits/ 8 <0x2f>; max-cur = /bits/ 8 <0x5f>; }; diff --git a/arch/arm/boot/dts/ste-ux500-samsung-golden.dts b/arch/arm/boot/dts/ste-ux500-samsung-golden.dts index 1e26b711d43d..a1093cb37dc7 100644 --- a/arch/arm/boot/dts/ste-ux500-samsung-golden.dts +++ b/arch/arm/boot/dts/ste-ux500-samsung-golden.dts @@ -316,6 +316,28 @@ }; }; }; + + mcde@a0350000 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&dsi_default_mode>; + + dsi-controller@a0351000 { + panel@0 { + compatible = "samsung,s6e63m0"; + reg = <0>; + vdd3-supply = <&panel_reg_3v0>; + vci-supply = <&panel_reg_1v8>; + reset-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; + /* ESD (electrostatic discharge) detection interrupt */ + interrupt-parent = <&gpio2>; + interrupts = <18 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "esd"; + pinctrl-names = "default"; + pinctrl-0 = <&display_default_mode>; + }; + }; + }; }; gpio-keys { @@ -415,6 +437,40 @@ pinctrl-names = "default"; pinctrl-0 = <&wlan_en_default>; }; + + /* MIC5366 GPIO-controlled regulator */ + panel_reg_1v8: regulator-panel-1v8 { + compatible = "regulator-fixed"; + + regulator-name = "panel-fixed-supply"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + /* GPIO219 */ + gpio = <&gpio6 27 GPIO_ACTIVE_HIGH>; + + startup-delay-us = <200>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&panel_reg_default_mode>; + }; + + /* MIC5366 GPIO-controlled regulator */ + panel_reg_3v0: regulator-panel-3v0 { + compatible = "regulator-fixed"; + + regulator-name = "panel-fixed-supply"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + /* GPIO219 */ + gpio = <&gpio6 27 GPIO_ACTIVE_HIGH>; + + startup-delay-us = <200>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&panel_reg_default_mode>; + }; }; &pinctrl { @@ -476,6 +532,41 @@ }; }; + mcde { + dsi_default_mode: dsi_default { + default_mux1 { + /* Mux in VSI0 used for DSI TE */ + function = "lcd"; + groups = + "lcdvsi0_a_1"; /* VSI0 for LCD */ + }; + default_cfg1 { + pins = + "GPIO68_E1"; /* VSI0 */ + ste,config = <&in_nopull>; + }; + }; + }; + + display { + display_default_mode: display_default { + golden_cfg1 { + pins = "GPIO139_C9"; /* MIPI_DSI0_RESET_N */ + ste,config = <&gpio_out_lo>; + }; + golden_cfg2 { + pins = "GPIO82_C1"; /* LDI_ESD_DET */ + ste,config = <&gpio_in_pu>; + }; + }; + panel_reg_default_mode: panel_reg_default { + golden_cfg1 { + pins = "GPIO219_AG10"; /* LCD_PWR_EN */ + ste,config = <&gpio_out_lo>; + }; + }; + }; + proximity { proximity_default: proximity_default { golden_cfg1 { diff --git a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts index d6f6ac04a48a..27722c42b61c 100644 --- a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts +++ b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts @@ -108,15 +108,12 @@ }; }; - /* - * FIXME: this is not quite GPIO backlight. This is a - * KTD253 one-wire GPIO-controlled backlight. It can - * work as a GPIO backlight. - */ - gpio_bl: backlight { - compatible = "gpio-backlight"; + ktd253: backlight { + compatible = "kinetic,ktd253"; /* GPIO 69 */ - gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>; + enable-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>; + /* Default to 13/32 brightness */ + default-brightness = <13>; pinctrl-names = "default"; pinctrl-0 = <&gpio_backlight_default_mode>; }; @@ -409,7 +406,7 @@ reset-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&display_default_mode>; - backlight = <&gpio_bl>; + backlight = <&ktd253>; }; }; }; diff --git a/arch/arm/boot/dts/stm32h743.dtsi b/arch/arm/boot/dts/stm32h743.dtsi index 69e2f1e78ed6..7febe19e780d 100644 --- a/arch/arm/boot/dts/stm32h743.dtsi +++ b/arch/arm/boot/dts/stm32h743.dtsi @@ -110,6 +110,7 @@ compatible = "st,stm32h7-spi"; reg = <0x40003800 0x400>; interrupts = <36>; + resets = <&rcc STM32H7_APB1L_RESET(SPI2)>; clocks = <&rcc SPI2_CK>; status = "disabled"; @@ -121,12 +122,13 @@ compatible = "st,stm32h7-spi"; reg = <0x40003c00 0x400>; interrupts = <51>; + resets = <&rcc STM32H7_APB1L_RESET(SPI3)>; clocks = <&rcc SPI3_CK>; status = "disabled"; }; usart2: serial@40004400 { - compatible = "st,stm32f7-uart"; + compatible = "st,stm32h7-uart"; reg = <0x40004400 0x400>; interrupts = <38>; status = "disabled"; @@ -194,7 +196,7 @@ }; usart1: serial@40011000 { - compatible = "st,stm32f7-uart"; + compatible = "st,stm32h7-uart"; reg = <0x40011000 0x400>; interrupts = <37>; status = "disabled"; @@ -207,6 +209,7 @@ compatible = "st,stm32h7-spi"; reg = <0x40013000 0x400>; interrupts = <35>; + resets = <&rcc STM32H7_APB2_RESET(SPI1)>; clocks = <&rcc SPI1_CK>; status = "disabled"; }; @@ -217,6 +220,7 @@ compatible = "st,stm32h7-spi"; reg = <0x40013400 0x400>; interrupts = <84>; + resets = <&rcc STM32H7_APB2_RESET(SPI4)>; clocks = <&rcc SPI4_CK>; status = "disabled"; }; @@ -227,6 +231,7 @@ compatible = "st,stm32h7-spi"; reg = <0x40015000 0x400>; interrupts = <85>; + resets = <&rcc STM32H7_APB2_RESET(SPI5)>; clocks = <&rcc SPI5_CK>; status = "disabled"; }; @@ -329,6 +334,16 @@ status = "disabled"; }; + ltdc: display-controller@50001000 { + compatible = "st,stm32-ltdc"; + reg = <0x50001000 0x200>; + interrupts = <88>, <89>; + resets = <&rcc STM32H7_APB3_RESET(LTDC)>; + clocks = <&rcc LTDC_CK>; + clock-names = "lcd"; + status = "disabled"; + }; + mdma1: dma-controller@52000000 { compatible = "st,stm32h7-mdma"; reg = <0x52000000 0x1000>; @@ -372,6 +387,7 @@ compatible = "st,stm32h7-spi"; reg = <0x58001400 0x400>; interrupts = <86>; + resets = <&rcc STM32H7_APB4_RESET(SPI6)>; clocks = <&rcc SPI6_CK>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi index b5a66429670c..d84686e00370 100644 --- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi +++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi @@ -1437,6 +1437,24 @@ }; }; + sdmmc2_d47_pins_d: sdmmc2-d47-3 { + pins { + pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */ + <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */ + <STM32_PINMUX('E', 5, AF9)>, /* SDMMC2_D6 */ + <STM32_PINMUX('C', 7, AF10)>; /* SDMMC2_D7 */ + }; + }; + + sdmmc2_d47_sleep_pins_d: sdmmc2-d47-sleep-3 { + pins { + pinmux = <STM32_PINMUX('A', 8, ANALOG)>, /* SDMMC2_D4 */ + <STM32_PINMUX('A', 9, ANALOG)>, /* SDMMC2_D5 */ + <STM32_PINMUX('E', 5, ANALOG)>, /* SDMMC2_D6 */ + <STM32_PINMUX('C', 7, ANALOG)>; /* SDMMC2_D7 */ + }; + }; + sdmmc3_b4_pins_a: sdmmc3-b4-0 { pins1 { pinmux = <STM32_PINMUX('F', 0, AF9)>, /* SDMMC3_D0 */ @@ -1700,6 +1718,14 @@ }; }; + uart8_rtscts_pins_a: uart8rtscts-0 { + pins { + pinmux = <STM32_PINMUX('G', 7, AF8)>, /* UART8_RTS */ + <STM32_PINMUX('G', 10, AF8)>; /* UART8_CTS */ + bias-disable; + }; + }; + spi4_pins_a: spi4-0 { pins { pinmux = <STM32_PINMUX('E', 12, AF5)>, /* SPI4_SCK */ diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi index bfe29023fbd5..84757901cd8d 100644 --- a/arch/arm/boot/dts/stm32mp151.dtsi +++ b/arch/arm/boot/dts/stm32mp151.dtsi @@ -23,6 +23,13 @@ }; }; + arm-pmu { + compatible = "arm,cortex-a7-pmu"; + interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&cpu0>; + interrupt-parent = <&intc>; + }; + psci { compatible = "arm,psci-1.0"; method = "smc"; @@ -1302,23 +1309,38 @@ dma-requests = <48>; }; - fmc: nand-controller@58002000 { - compatible = "st,stm32mp15-fmc2"; - reg = <0x58002000 0x1000>, - <0x80000000 0x1000>, - <0x88010000 0x1000>, - <0x88020000 0x1000>, - <0x81000000 0x1000>, - <0x89010000 0x1000>, - <0x89020000 0x1000>; - interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; - dmas = <&mdma1 20 0x10 0x12000a02 0x0 0x0>, - <&mdma1 20 0x10 0x12000a08 0x0 0x0>, - <&mdma1 21 0x10 0x12000a0a 0x0 0x0>; - dma-names = "tx", "rx", "ecc"; + fmc: memory-controller@58002000 { + #address-cells = <2>; + #size-cells = <1>; + compatible = "st,stm32mp1-fmc2-ebi"; + reg = <0x58002000 0x1000>; clocks = <&rcc FMC_K>; resets = <&rcc FMC_R>; status = "disabled"; + + ranges = <0 0 0x60000000 0x04000000>, /* EBI CS 1 */ + <1 0 0x64000000 0x04000000>, /* EBI CS 2 */ + <2 0 0x68000000 0x04000000>, /* EBI CS 3 */ + <3 0 0x6c000000 0x04000000>, /* EBI CS 4 */ + <4 0 0x80000000 0x10000000>; /* NAND */ + + nand-controller@4,0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32mp1-fmc2-nfc"; + reg = <4 0x00000000 0x1000>, + <4 0x08010000 0x1000>, + <4 0x08020000 0x1000>, + <4 0x01000000 0x1000>, + <4 0x09010000 0x1000>, + <4 0x09020000 0x1000>; + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&mdma1 20 0x2 0x12000a02 0x0 0x0>, + <&mdma1 20 0x2 0x12000a08 0x0 0x0>, + <&mdma1 21 0x2 0x12000a0a 0x0 0x0>; + dma-names = "tx", "rx", "ecc"; + status = "disabled"; + }; }; qspi: spi@58003000 { diff --git a/arch/arm/boot/dts/stm32mp153.dtsi b/arch/arm/boot/dts/stm32mp153.dtsi index 6d9ab08667fc..1c1889b194cf 100644 --- a/arch/arm/boot/dts/stm32mp153.dtsi +++ b/arch/arm/boot/dts/stm32mp153.dtsi @@ -16,6 +16,12 @@ }; }; + arm-pmu { + interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&cpu0>, <&cpu1>; + }; + soc { m_can1: can@4400e000 { compatible = "bosch,m_can"; diff --git a/arch/arm/boot/dts/stm32mp153c-dhcom-drc02.dts b/arch/arm/boot/dts/stm32mp153c-dhcom-drc02.dts new file mode 100644 index 000000000000..02a39132958e --- /dev/null +++ b/arch/arm/boot/dts/stm32mp153c-dhcom-drc02.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-STM32MP153C-C065-R102-F0819-SPI-E2-CAN2-RTC-I-01D2 + * DHCOM PCB number: 587-200 or newer + * DRC02 PCB number: 568-100 or newer + */ +/dts-v1/; + +#include "stm32mp153.dtsi" +#include "stm32mp15xc.dtsi" +#include "stm32mp15xx-dhcom-som.dtsi" +#include "stm32mp15xx-dhcom-drc02.dtsi" + +/ { + model = "DH electronics STM32MP153C DHCOM DRC02"; + compatible = "dh,stm32mp153c-dhcom-drc02", "dh,stm32mp153c-dhcom-som", + "st,stm32mp153"; +}; + +&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-dhcom-pdk2.dts b/arch/arm/boot/dts/stm32mp157c-dhcom-pdk2.dts index 197aa98d49e2..d3b81382f97c 100644 --- a/arch/arm/boot/dts/stm32mp157c-dhcom-pdk2.dts +++ b/arch/arm/boot/dts/stm32mp157c-dhcom-pdk2.dts @@ -4,7 +4,7 @@ * * DHCOM STM32MP1 variant: * DHCM-STM32MP157C-C065-R102-F0819-SPI-E2-CAN2-SDR104-RTC-WBT-T-DSI-I-01D2 - * DHCOR PCB number: 587-200 or newer + * DHCOM PCB number: 587-200 or newer * PDK2 PCB number: 516-400 or newer */ /dts-v1/; @@ -15,7 +15,7 @@ #include "stm32mp15xx-dhcom-pdk2.dtsi" / { - model = "DH Electronics STM32MP157C DHCOM Premium Developer Kit (2)"; + model = "DH electronics STM32MP157C DHCOM Premium Developer Kit (2)"; compatible = "dh,stm32mp157c-dhcom-pdk2", "dh,stm32mp157c-dhcom-som", "st,stm32mp157"; }; diff --git a/arch/arm/boot/dts/stm32mp157c-ev1.dts b/arch/arm/boot/dts/stm32mp157c-ev1.dts index 85628e16d2d5..a55e80ce2602 100644 --- a/arch/arm/boot/dts/stm32mp157c-ev1.dts +++ b/arch/arm/boot/dts/stm32mp157c-ev1.dts @@ -158,14 +158,16 @@ pinctrl-0 = <&fmc_pins_a>; pinctrl-1 = <&fmc_sleep_pins_a>; status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - nand@0 { - reg = <0>; - nand-on-flash-bbt; - #address-cells = <1>; - #size-cells = <1>; + nand-controller@4,0 { + status = "okay"; + + nand@0 { + reg = <0>; + nand-on-flash-bbt; + #address-cells = <1>; + #size-cells = <1>; + }; }; }; diff --git a/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts b/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts index 5700e6b700d3..1e5333fd437f 100644 --- a/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts +++ b/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts @@ -121,8 +121,6 @@ reset-gpios = <&gpiog 0 GPIO_ACTIVE_LOW>; /* ETH_RST# */ interrupt-parent = <&gpioa>; interrupts = <6 IRQ_TYPE_EDGE_FALLING>; /* ETH_MDINT# */ - rxc-skew-ps = <1860>; - txc-skew-ps = <1860>; reset-assert-us = <10000>; reset-deassert-us = <300>; micrel,force-master; @@ -214,6 +212,7 @@ pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_b>; pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_b>; bus-width = <8>; + mmc-ddr-3_3v; no-1-8-v; no-sd; no-sdio; diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi b/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi new file mode 100644 index 000000000000..6cf49a0a9e69 --- /dev/null +++ b/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) 2020 Marcin Sloniewski <marcin.sloniewski@gmail.com>. + */ + +/dts-v1/; + +#include "stm32mp157.dtsi" +#include "stm32mp15xc.dtsi" +#include "stm32mp15-pinctrl.dtsi" +#include "stm32mp15xxac-pinctrl.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/mfd/st,stpmic1.h> + +/ { + model = "Seeed Studio Odyssey-STM32MP157C SOM"; + compatible = "seeed,stm32mp157c-odyssey-som", "st,stm32mp157"; + + memory@c0000000 { + device_type = "memory"; + reg = <0xc0000000 0x20000000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + mcuram2: mcuram2@10000000 { + compatible = "shared-dma-pool"; + reg = <0x10000000 0x40000>; + no-map; + }; + + vdev0vring0: vdev0vring0@10040000 { + compatible = "shared-dma-pool"; + reg = <0x10040000 0x1000>; + no-map; + }; + + vdev0vring1: vdev0vring1@10041000 { + compatible = "shared-dma-pool"; + reg = <0x10041000 0x1000>; + no-map; + }; + + vdev0buffer: vdev0buffer@10042000 { + compatible = "shared-dma-pool"; + reg = <0x10042000 0x4000>; + no-map; + }; + + mcuram: mcuram@30000000 { + compatible = "shared-dma-pool"; + reg = <0x30000000 0x40000>; + no-map; + }; + + retram: retram@38000000 { + compatible = "shared-dma-pool"; + reg = <0x38000000 0x10000>; + no-map; + }; + + gpu_reserved: gpu@d4000000 { + reg = <0xd4000000 0x4000000>; + no-map; + }; + }; + + led { + compatible = "gpio-leds"; + led-blue { + color = <LED_COLOR_ID_BLUE>; + function = LED_FUNCTION_HEARTBEAT; + gpios = <&gpiog 3 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; +}; + +&gpu { + contiguous-area = <&gpu_reserved>; + status = "okay"; +}; + +&i2c2 { + 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; + + pmic: stpmic@33 { + compatible = "st,stpmic1"; + reg = <0x33>; + interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <2>; + + regulators { + compatible = "st,stpmic1-regulators"; + ldo1-supply = <&v3v3>; + ldo3-supply = <&vdd_ddr>; + ldo6-supply = <&v3v3>; + pwr_sw1-supply = <&bst_out>; + pwr_sw2-supply = <&bst_out>; + + vddcore: buck1 { + regulator-name = "vddcore"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + vdd_ddr: buck2 { + regulator-name = "vdd_ddr"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + vdd: buck3 { + regulator-name = "vdd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + st,mask-reset; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + v3v3: buck4 { + regulator-name = "v3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-over-current-protection; + regulator-initial-mode = <0>; + }; + + v1v8_audio: ldo1 { + regulator-name = "v1v8_audio"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + interrupts = <IT_CURLIM_LDO1 0>; + }; + + v3v3_hdmi: ldo2 { + regulator-name = "v3v3_hdmi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + interrupts = <IT_CURLIM_LDO2 0>; + }; + + vtt_ddr: ldo3 { + regulator-name = "vtt_ddr"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <750000>; + regulator-always-on; + regulator-over-current-protection; + }; + + vdd_usb: ldo4 { + regulator-name = "vdd_usb"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + interrupts = <IT_CURLIM_LDO4 0>; + }; + + vdda: ldo5 { + regulator-name = "vdda"; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + interrupts = <IT_CURLIM_LDO5 0>; + regulator-boot-on; + }; + + v1v2_hdmi: ldo6 { + regulator-name = "v1v2_hdmi"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + interrupts = <IT_CURLIM_LDO6 0>; + }; + + vref_ddr: vref_ddr { + regulator-name = "vref_ddr"; + regulator-always-on; + regulator-over-current-protection; + }; + + bst_out: boost { + regulator-name = "bst_out"; + interrupts = <IT_OCP_BOOST 0>; + }; + + vbus_otg: pwr_sw1 { + regulator-name = "vbus_otg"; + interrupts = <IT_OCP_OTG 0>; + }; + + vbus_sw: pwr_sw2 { + regulator-name = "vbus_sw"; + interrupts = <IT_OCP_SWOUT 0>; + regulator-active-discharge; + }; + }; + + onkey { + compatible = "st,stpmic1-onkey"; + interrupts = <IT_PONKEY_F 0>, <IT_PONKEY_R 0>; + interrupt-names = "onkey-falling", "onkey-rising"; + power-off-time-sec = <10>; + }; + + watchdog { + compatible = "st,stpmic1-wdt"; + status = "disabled"; + }; + }; +}; + +&ipcc { + status = "okay"; +}; + +&iwdg2 { + timeout-sec = <32>; + status = "okay"; +}; + +&m4_rproc { + memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, + <&vdev0vring1>, <&vdev0buffer>; + mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; + mbox-names = "vq0", "vq1", "shutdown"; + interrupt-parent = <&exti>; + interrupts = <68 1>; + status = "okay"; +}; + +&rng1 { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&sdmmc2 { + pinctrl-names = "default", "opendrain", "sleep"; + pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_d>; + pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_d>; + pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_d>; + non-removable; + no-sd; + no-sdio; + st,neg-edge; + bus-width = <8>; + vmmc-supply = <&v3v3>; + vqmmc-supply = <&v3v3>; + mmc-ddr-3_3v; + status = "okay"; +}; + diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey.dts b/arch/arm/boot/dts/stm32mp157c-odyssey.dts new file mode 100644 index 000000000000..a7ffec8f1516 --- /dev/null +++ b/arch/arm/boot/dts/stm32mp157c-odyssey.dts @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) 2020 Marcin Sloniewski <marcin.sloniewski@gmail.com>. + */ + +/dts-v1/; + +#include "stm32mp157c-odyssey-som.dtsi" + +/ { + model = "Seeed Studio Odyssey-STM32MP157C Board"; + compatible = "seeed,stm32mp157c-odyssey", + "seeed,stm32mp157c-odyssey-som", "st,stm32mp157"; + + aliases { + ethernet0 = ðernet0; + serial0 = &uart4; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +ðernet0 { + status = "okay"; + pinctrl-0 = <ðernet0_rgmii_pins_a>; + pinctrl-1 = <ðernet0_rgmii_sleep_pins_a>; + pinctrl-names = "default", "sleep"; + phy-mode = "rgmii-id"; + max-speed = <1000>; + phy-handle = <&phy0>; + assigned-clocks = <&rcc ETHCK_K>, <&rcc PLL4_P>; + assigned-clock-parents = <&rcc PLL4_P>; + assigned-clock-rates = <125000000>; /* Clock PLL4 to 750Mhz in ATF/U-Boot */ + st,eth-clk-sel; + + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + phy0: ethernet-phy@7 { /* KSZ9031RN */ + reg = <7>; + reset-gpios = <&gpiog 0 GPIO_ACTIVE_LOW>; /* ETH_RST# */ + reset-assert-us = <10000>; + reset-deassert-us = <300>; + }; + }; +}; + +&i2c1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c1_pins_a>; + pinctrl-1 = <&i2c1_sleep_pins_a>; + i2c-scl-rising-time-ns = <100>; + i2c-scl-falling-time-ns = <7>; + status = "okay"; + /delete-property/dmas; + /delete-property/dma-names; +}; + +&sdmmc1 { + pinctrl-names = "default", "opendrain", "sleep"; + pinctrl-0 = <&sdmmc1_b4_pins_a>; + pinctrl-1 = <&sdmmc1_b4_od_pins_a>; + pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; + cd-gpios = <&gpiob 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + disable-wp; + st,neg-edge; + bus-width = <4>; + vmmc-supply = <&v3v3>; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_pins_a>; + status = "okay"; +}; + diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi new file mode 100644 index 000000000000..62ab23824a3e --- /dev/null +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi @@ -0,0 +1,157 @@ +// 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"; + }; +}; + +&adc { + status = "disabled"; +}; + +&dac { + status = "disabled"; +}; + +&gpiob { + /* + * NOTE: On DRC02, the RS485_RX_En is controlled by a separate + * GPIO line, however the STM32 UART driver assumes RX happens + * during TX anyway and that it only controls drive enable DE + * line. Hence, the RX is always enabled here. + */ + rs485-rx-en { + gpio-hog; + gpios = <8 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "rs485-rx-en"; + }; +}; + +&gpiod { + gpio-line-names = "", "", "", "", + "", "", "", "", + "", "", "", "Out1", + "Out2", "", "", ""; +}; + +&gpioi { + gpio-line-names = "In1", "", "", "", + "", "", "", "", + "In2", "", "", "", + "", "", "", ""; + + /* + * NOTE: The USB Hub on the DRC02 needs a reset signal to be + * pulled high in order to be detected by the USB Controller. + * This signal should be handled by USB power sequencing in + * order to reset the Hub when USB bus is powered down, but + * so far there is no such functionality. + */ + usb-hub { + gpio-hog; + gpios = <2 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "usb-hub-reset"; + }; +}; + +&i2c2 { + 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; + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c04"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +&i2c5 { /* TP7/TP8 */ + 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; +}; + +&sdmmc3 { + /* + * On DRC02, the SoM does not have SDIO WiFi. The pins + * are used for on-board microSD slot instead. + */ + /delete-property/broken-cd; + cd-gpios = <&gpioi 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + disable-wp; +}; + +&spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&spi1_pins_a>; + cs-gpios = <&gpioz 3 0>; + /* Use PIO for the display */ + /delete-property/dmas; + /delete-property/dma-names; + status = "disabled"; /* Enable once there is display driver */ + /* + * Note: PF3/GPIO_A , PD6/GPIO_B , PG0/GPIO_C , PC6/GPIO_E are + * also connected to the display board connector. + */ +}; + +&usart3 { + pinctrl-names = "default"; + pinctrl-0 = <&usart3_pins_a>; + status = "okay"; +}; + +/* + * Note: PI3 is UART1_RTS and PI5 is UART1_CTS on DRC02 (uart4 of STM32MP1), + * however the STM32MP1 pinmux cannot map them to UART4 . + */ + +&uart8 { /* RS485 */ + linux,rs485-enabled-at-boot-time; + pinctrl-names = "default"; + pinctrl-0 = <&uart8_pins_a>; + rts-gpios = <&gpioe 6 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&usbh_ehci { + phys = <&usbphyc_port0>; + status = "okay"; +}; + +&usbphyc { + status = "okay"; +}; + +&usbphyc_port0 { + phy-supply = <&vdd_usb>; + vdda1v1-supply = <®11>; + vdda1v8-supply = <®18>; +}; diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi index 7c4bd615b311..5dff24e39af8 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi @@ -11,7 +11,6 @@ serial0 = &uart4; serial1 = &usart3; serial2 = &uart8; - ethernet0 = ðernet0; }; chosen { @@ -26,23 +25,13 @@ display_bl: display-bl { compatible = "pwm-backlight"; - pwms = <&pwm2 0 500000 PWM_POLARITY_INVERTED>; + pwms = <&pwm2 3 500000 PWM_POLARITY_INVERTED>; brightness-levels = <0 16 22 30 40 55 75 102 138 188 255>; default-brightness-level = <8>; enable-gpios = <&gpioi 0 GPIO_ACTIVE_HIGH>; status = "okay"; }; - ethernet_vio: vioregulator { - compatible = "regulator-fixed"; - regulator-name = "vio"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&gpiog 3 GPIO_ACTIVE_LOW>; - regulator-always-on; - regulator-boot-on; - }; - gpio-keys-polled { compatible = "gpio-keys-polled"; #size-cells = <0>; @@ -141,28 +130,6 @@ status = "okay"; }; -ðernet0 { - status = "okay"; - pinctrl-0 = <ðernet0_rmii_pins_a>; - pinctrl-1 = <ðernet0_rmii_sleep_pins_a>; - pinctrl-names = "default", "sleep"; - phy-mode = "rmii"; - max-speed = <100>; - phy-handle = <&phy0>; - st,eth-ref-clk-sel; - phy-reset-gpios = <&gpioh 15 GPIO_ACTIVE_LOW>; - - mdio0 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "snps,dwmac-mdio"; - - phy0: ethernet-phy@1 { - reg = <1>; - }; - }; -}; - &i2c2 { /* Header X22 */ pinctrl-names = "default"; pinctrl-0 = <&i2c2_pins_a>; @@ -304,7 +271,8 @@ &uart8 { pinctrl-names = "default"; - pinctrl-0 = <&uart8_pins_a>; + pinctrl-0 = <&uart8_pins_a &uart8_rtscts_pins_a>; + uart-has-rtscts; status = "okay"; }; @@ -314,9 +282,12 @@ }; &usbotg_hs { - dr_mode = "peripheral"; - phys = <&usbphyc_port1 0>; + 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"; }; diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi index ba905196fb54..b4b52cf634af 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi @@ -9,6 +9,10 @@ #include <dt-bindings/mfd/st,stpmic1.h> / { + aliases { + ethernet0 = ðernet0; + }; + memory@c0000000 { device_type = "memory"; reg = <0xC0000000 0x40000000>; @@ -55,6 +59,16 @@ no-map; }; }; + + ethernet_vio: vioregulator { + compatible = "regulator-fixed"; + regulator-name = "vio"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpiog 3 GPIO_ACTIVE_LOW>; + regulator-always-on; + regulator-boot-on; + }; }; &adc { @@ -94,6 +108,28 @@ status = "okay"; }; +ðernet0 { + status = "okay"; + pinctrl-0 = <ðernet0_rmii_pins_a>; + pinctrl-1 = <ðernet0_rmii_sleep_pins_a>; + pinctrl-names = "default", "sleep"; + phy-mode = "rmii"; + max-speed = <100>; + phy-handle = <&phy0>; + st,eth-ref-clk-sel; + phy-reset-gpios = <&gpioh 3 GPIO_ACTIVE_LOW>; + + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + + phy0: ethernet-phy@1 { + reg = <1>; + }; + }; +}; + &i2c4 { pinctrl-names = "default"; pinctrl-0 = <&i2c4_pins_a>; @@ -249,7 +285,7 @@ compatible = "ti,tsc2004"; reg = <0x49>; vio-supply = <&v3v3>; - interrupts-extended = <&gpioh 3 IRQ_TYPE_EDGE_FALLING>; + interrupts-extended = <&gpioh 15 IRQ_TYPE_EDGE_FALLING>; }; eeprom@50 { @@ -285,8 +321,8 @@ &qspi { pinctrl-names = "default", "sleep"; - pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>; - pinctrl-1 = <&qspi_clk_sleep_pins_a &qspi_bk1_sleep_pins_a &qspi_bk2_sleep_pins_a>; + pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a>; + pinctrl-1 = <&qspi_clk_sleep_pins_a &qspi_bk1_sleep_pins_a>; reg = <0x58003000 0x1000>, <0x70000000 0x4000000>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi index 930202742a3f..ec02cee1dd9b 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi @@ -295,9 +295,9 @@ &sdmmc2 { pinctrl-names = "default", "opendrain", "sleep"; - pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_b>; - pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_b>; - pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_b>; + pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_c>; + pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_c>; + pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_c>; bus-width = <8>; mmc-ddr-1_8v; no-sd; @@ -351,6 +351,7 @@ label = "LS-UART0"; pinctrl-names = "default"; pinctrl-0 = <&uart7_pins_a>; + uart-has-rtscts; status = "okay"; }; diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts index 8692b11a83c3..af8ab736fd3c 100644 --- a/arch/arm/boot/dts/sun4i-a10-a1000.dts +++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts @@ -60,6 +60,17 @@ stdout-path = "serial0:115200n8"; }; + hdmi-connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + leds { compatible = "gpio-leds"; @@ -133,6 +144,20 @@ status = "okay"; }; +&de { + status = "okay"; +}; + +&hdmi { + status = "okay"; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + &i2c0 { status = "okay"; diff --git a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts index 3d78169cdeed..a1953b2872d0 100644 --- a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts +++ b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts @@ -194,8 +194,8 @@ "Headphone", "Headphone Jack"; /* Board level routing. First 2 routes copied from SoC level */ simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", + "Left DAC", "DACL", + "Right DAC", "DACR", "HP", "HPCOM", "Headphone Jack", "HP", "MIC1", "Microphone Jack", diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi index cfd3858afb3e..c458f5fb124f 100644 --- a/arch/arm/boot/dts/sun8i-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a33.dtsi @@ -189,8 +189,8 @@ simple-audio-card,mclk-fs = <128>; simple-audio-card,aux-devs = <&codec_analog>; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right"; + "Left DAC", "DACL", + "Right DAC", "DACR"; status = "disabled"; simple-audio-card,cpu { diff --git a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts index 42d62d1ba1dc..2fc62ef0cb3e 100644 --- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts +++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts @@ -164,6 +164,10 @@ #include "axp22x.dtsi" +&ir0 { + status = "okay"; +}; + &mmc0 { vmmc-supply = <®_dcdc1>; bus-width = <4>; @@ -223,16 +227,16 @@ }; ®_dc1sw { - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; regulator-name = "vcc-gmac-phy"; }; ®_dcdc1 { regulator-always-on; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - regulator-name = "vcc-3v0"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; }; ®_dcdc2 { diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi index b782041e0e04..7907569e7b5c 100644 --- a/arch/arm/boot/dts/sun8i-r40.dtsi +++ b/arch/arm/boot/dts/sun8i-r40.dtsi @@ -190,6 +190,29 @@ }; }; + syscon: system-control@1c00000 { + compatible = "allwinner,sun8i-r40-system-control", + "allwinner,sun4i-a10-system-control"; + reg = <0x01c00000 0x30>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram_c: sram@1d00000 { + compatible = "mmio-sram"; + reg = <0x01d00000 0xd0000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x01d00000 0xd0000>; + + ve_sram: sram-section@0 { + compatible = "allwinner,sun8i-r40-sram-c1", + "allwinner,sun4i-a10-sram-c1"; + reg = <0x000000 0x80000>; + }; + }; + }; + nmi_intc: interrupt-controller@1c00030 { compatible = "allwinner,sun7i-a20-sc-nmi"; interrupt-controller; @@ -198,6 +221,18 @@ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; }; + dma: dma-controller@1c02000 { + compatible = "allwinner,sun8i-r40-dma", + "allwinner,sun50i-a64-dma"; + reg = <0x01c02000 0x1000>; + interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_DMA>; + dma-channels = <16>; + dma-requests = <31>; + resets = <&ccu RST_BUS_DMA>; + #dma-cells = <1>; + }; + spi0: spi@1c05000 { compatible = "allwinner,sun8i-r40-spi", "allwinner,sun8i-h3-spi"; @@ -238,6 +273,17 @@ status = "disabled"; }; + video-codec@1c0e000 { + compatible = "allwinner,sun8i-r40-video-engine"; + reg = <0x01c0e000 0x1000>; + clocks = <&ccu CLK_BUS_VE>, <&ccu CLK_VE>, + <&ccu CLK_DRAM_VE>; + clock-names = "ahb", "mod", "ram"; + resets = <&ccu RST_BUS_VE>; + interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; + allwinner,sram = <&ve_sram 1>; + }; + mmc0: mmc@1c0f000 { compatible = "allwinner,sun8i-r40-mmc", "allwinner,sun50i-a64-mmc"; @@ -501,6 +547,16 @@ function = "i2c4"; }; + ir0_pins: ir0-pins { + pins = "PB4"; + function = "ir0"; + }; + + ir1_pins: ir1-pins { + pins = "PB23"; + function = "ir1"; + }; + mmc0_pins: mmc0-pins { pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5"; @@ -579,6 +635,32 @@ clocks = <&osc24M>; }; + ir0: ir@1c21800 { + compatible = "allwinner,sun8i-r40-ir", + "allwinner,sun6i-a31-ir"; + reg = <0x01c21800 0x400>; + pinctrl-0 = <&ir0_pins>; + pinctrl-names = "default"; + clocks = <&ccu CLK_BUS_IR0>, <&ccu CLK_IR0>; + clock-names = "apb", "ir"; + interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; + resets = <&ccu RST_BUS_IR0>; + status = "disabled"; + }; + + ir1: ir@1c21c00 { + compatible = "allwinner,sun8i-r40-ir", + "allwinner,sun6i-a31-ir"; + reg = <0x01c21c00 0x400>; + pinctrl-0 = <&ir1_pins>; + pinctrl-names = "default"; + clocks = <&ccu CLK_BUS_IR1>, <&ccu CLK_IR1>; + clock-names = "apb", "ir"; + interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; + resets = <&ccu RST_BUS_IR1>; + status = "disabled"; + }; + ths: thermal-sensor@1c24c00 { compatible = "allwinner,sun8i-r40-ths"; reg = <0x01c24c00 0x100>; @@ -743,6 +825,28 @@ #size-cells = <0>; }; + mali: gpu@1c40000 { + compatible = "allwinner,sun8i-r40-mali", "arm,mali-400"; + reg = <0x01c40000 0x10000>; + interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "gp", + "gpmmu", + "pp0", + "ppmmu0", + "pp1", + "ppmmu1", + "pmu"; + clocks = <&ccu CLK_BUS_GPU>, <&ccu CLK_GPU>; + clock-names = "bus", "core"; + resets = <&ccu RST_BUS_GPU>; + }; + gmac: ethernet@1c50000 { compatible = "allwinner,sun8i-r40-gmac"; syscon = <&ccu>; diff --git a/arch/arm/boot/dts/sun8i-s3-pinecube.dts b/arch/arm/boot/dts/sun8i-s3-pinecube.dts new file mode 100644 index 000000000000..9bab6b7f4014 --- /dev/null +++ b/arch/arm/boot/dts/sun8i-s3-pinecube.dts @@ -0,0 +1,235 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR X11) +/* + * Copyright 2019 Icenowy Zheng <icenowy@aosc.io> + */ + +/dts-v1/; +#include "sun8i-v3.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> + +/ { + model = "PineCube IP Camera"; + compatible = "pine64,pinecube", "allwinner,sun8i-s3"; + + aliases { + serial0 = &uart2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + led1 { + label = "pine64:ir:led1"; + gpios = <&pio 1 10 GPIO_ACTIVE_LOW>; /* PB10 */ + }; + + led2 { + label = "pine64:ir:led2"; + gpios = <&pio 1 12 GPIO_ACTIVE_LOW>; /* PB12 */ + }; + }; + + reg_vcc5v0: vcc5v0 { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_vcc_wifi: vcc-wifi { + compatible = "regulator-fixed"; + regulator-name = "vcc-wifi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&pio 1 2 GPIO_ACTIVE_LOW>; /* PB2 WIFI-EN */ + vin-supply = <®_dcdc3>; + startup-delay-us = <200000>; + }; + + wifi_pwrseq: wifi_pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&pio 1 3 GPIO_ACTIVE_LOW>; /* PB3 WIFI-RST */ + post-power-on-delay-ms = <200>; + }; +}; + +&csi1 { + pinctrl-names = "default"; + pinctrl-0 = <&csi1_8bit_pins>; + status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + csi1_ep: endpoint { + remote-endpoint = <&ov5640_ep>; + bus-width = <8>; + hsync-active = <1>; /* Active high */ + vsync-active = <0>; /* Active low */ + data-active = <1>; /* Active high */ + pclk-sample = <1>; /* Rising */ + }; + }; +}; + +&emac { + phy-handle = <&int_mii_phy>; + phy-mode = "mii"; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + axp209: pmic@34 { + compatible = "x-powers,axp203", + "x-powers,axp209"; + reg = <0x34>; + interrupt-parent = <&gic>; + interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <1>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pe_pins>; + status = "okay"; + + ov5640: camera@3c { + compatible = "ovti,ov5640"; + reg = <0x3c>; + pinctrl-names = "default"; + pinctrl-0 = <&csi1_mclk_pin>; + clocks = <&ccu CLK_CSI1_MCLK>; + clock-names = "xclk"; + + AVDD-supply = <®_ldo3>; + DOVDD-supply = <®_ldo3>; + DVDD-supply = <®_ldo4>; + reset-gpios = <&pio 4 23 GPIO_ACTIVE_LOW>; /* PE23 */ + powerdown-gpios = <&pio 4 24 GPIO_ACTIVE_HIGH>; /* PE24 */ + + port { + ov5640_ep: endpoint { + remote-endpoint = <&csi1_ep>; + bus-width = <8>; + hsync-active = <1>; /* Active high */ + vsync-active = <0>; /* Active low */ + data-active = <1>; /* Active high */ + pclk-sample = <1>; /* Rising */ + }; + }; + }; +}; + +&lradc { + vref-supply = <®_ldo2>; + status = "okay"; + + button-200 { + label = "Setup"; + linux,code = <KEY_SETUP>; + channel = <0>; + voltage = <190000>; + }; +}; + +&mmc0 { + vmmc-supply = <®_dcdc3>; + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&mmc1 { + vmmc-supply = <®_vcc_wifi>; + vqmmc-supply = <®_dcdc3>; + mmc-pwrseq = <&wifi_pwrseq>; + bus-width = <4>; + non-removable; + status = "okay"; +}; + +&pio { + vcc-pd-supply = <®_dcdc3>; + vcc-pe-supply = <®_ldo3>; +}; + +#include "axp209.dtsi" + +&ac_power_supply { + status = "okay"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + regulator-name = "vdd-sys-cpu-ephy"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; +}; + +®_ldo1 { + regulator-name = "vdd-rtc"; +}; + +®_ldo2 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "avcc"; +}; + +®_ldo3 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-name = "avdd-dovdd-2v8-csi"; + regulator-soft-start; + regulator-ramp-delay = <1600>; +}; + +®_ldo4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "dvdd-1v8-csi"; +}; + +&spi0 { + status = "okay"; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "winbond,w25q128", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + }; +}; + +&uart2 { + status = "okay"; +}; + +&usb_otg { + dr_mode = "host"; + status = "okay"; +}; + +&usbphy { + usb0_vbus-supply = <®_vcc5v0>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-v3.dtsi b/arch/arm/boot/dts/sun8i-v3.dtsi index 6ae8645ade50..ca4672ed2e02 100644 --- a/arch/arm/boot/dts/sun8i-v3.dtsi +++ b/arch/arm/boot/dts/sun8i-v3.dtsi @@ -9,6 +9,19 @@ compatible = "allwinner,sun8i-v3-ccu"; }; +&emac { + /delete-property/ phy-handle; + /delete-property/ phy-mode; +}; + +&mdio_mux { + external_mdio: mdio@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; + &pio { compatible = "allwinner,sun8i-v3-pinctrl"; }; diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi index e5312869c0d2..0c7341676921 100644 --- a/arch/arm/boot/dts/sun8i-v3s.dtsi +++ b/arch/arm/boot/dts/sun8i-v3s.dtsi @@ -43,12 +43,28 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/clock/sun8i-v3s-ccu.h> #include <dt-bindings/reset/sun8i-v3s-ccu.h> +#include <dt-bindings/clock/sun8i-de2.h> / { #address-cells = <1>; #size-cells = <1>; interrupt-parent = <&gic>; + chosen { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + framebuffer-lcd { + compatible = "allwinner,simple-framebuffer", + "simple-framebuffer"; + allwinner,pipeline = "mixer0-lcd0"; + clocks = <&display_clocks CLK_MIXER0>, + <&ccu CLK_TCON0>; + status = "disabled"; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -138,6 +154,15 @@ }; }; + syscon: system-control@1c00000 { + compatible = "allwinner,sun8i-v3s-system-control", + "allwinner,sun8i-h3-system-control"; + reg = <0x01c00000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + }; + tcon0: lcd-controller@1c0c000 { compatible = "allwinner,sun8i-v3s-tcon"; reg = <0x01c0c000 0x1000>; @@ -234,6 +259,17 @@ #size-cells = <0>; }; + crypto@1c15000 { + compatible = "allwinner,sun8i-v3s-crypto", + "allwinner,sun8i-a33-crypto"; + reg = <0x01c15000 0x1000>; + interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_CE>, <&ccu CLK_CE>; + clock-names = "ahb", "mod"; + resets = <&ccu RST_BUS_CE>; + reset-names = "ahb"; + }; + usb_otg: usb@1c19000 { compatible = "allwinner,sun8i-h3-musb"; reg = <0x01c19000 0x0400>; @@ -292,16 +328,41 @@ interrupt-controller; #interrupt-cells = <3>; + /omit-if-no-ref/ + csi1_8bit_pins: csi1-8bit-pins { + pins = "PE0", "PE2", "PE3", "PE8", "PE9", + "PE10", "PE11", "PE12", "PE13", "PE14", + "PE15"; + function = "csi"; + }; + + /omit-if-no-ref/ + csi1_mclk_pin: csi1-mclk-pin { + pins = "PE1"; + function = "csi"; + }; + i2c0_pins: i2c0-pins { pins = "PB6", "PB7"; function = "i2c0"; }; + /omit-if-no-ref/ + i2c1_pe_pins: i2c1-pe-pins { + pins = "PE21", "PE22"; + function = "i2c1"; + }; + uart0_pb_pins: uart0-pb-pins { pins = "PB8", "PB9"; function = "uart0"; }; + uart2_pins: uart2-pins { + pins = "PB0", "PB1"; + function = "uart2"; + }; + mmc0_pins: mmc0-pins { pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5"; @@ -377,6 +438,8 @@ reg-io-width = <4>; clocks = <&ccu CLK_BUS_UART2>; resets = <&ccu RST_BUS_UART2>; + pinctrl-0 = <&uart2_pins>; + pinctrl-names = "default"; status = "disabled"; }; @@ -404,6 +467,49 @@ #size-cells = <0>; }; + emac: ethernet@1c30000 { + compatible = "allwinner,sun8i-v3s-emac"; + syscon = <&syscon>; + reg = <0x01c30000 0x10000>; + interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; + resets = <&ccu RST_BUS_EMAC>; + reset-names = "stmmaceth"; + clocks = <&ccu CLK_BUS_EMAC>; + clock-names = "stmmaceth"; + phy-handle = <&int_mii_phy>; + phy-mode = "mii"; + status = "disabled"; + + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + }; + + mdio_mux: mdio-mux { + compatible = "allwinner,sun8i-h3-mdio-mux"; + #address-cells = <1>; + #size-cells = <0>; + + mdio-parent-bus = <&mdio>; + /* Only one MDIO is usable at the time */ + internal_mdio: mdio@1 { + compatible = "allwinner,sun8i-h3-mdio-internal"; + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + int_mii_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + clocks = <&ccu CLK_BUS_EPHY>; + resets = <&ccu RST_BUS_EPHY>; + }; + }; + }; + }; + spi0: spi@1c68000 { compatible = "allwinner,sun8i-h3-spi"; reg = <0x01c68000 0x1000>; @@ -418,6 +524,18 @@ #size-cells = <0>; }; + csi1: camera@1cb4000 { + compatible = "allwinner,sun8i-v3s-csi"; + reg = <0x01cb4000 0x3000>; + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_CSI>, + <&ccu CLK_CSI1_SCLK>, + <&ccu CLK_DRAM_CSI>; + clock-names = "bus", "mod", "ram"; + resets = <&ccu RST_BUS_CSI>; + status = "disabled"; + }; + gic: interrupt-controller@1c81000 { compatible = "arm,gic-400"; reg = <0x01c81000 0x1000>, diff --git a/arch/arm/boot/dts/tango4-common.dtsi b/arch/arm/boot/dts/tango4-common.dtsi index 54fd522badfc..d584da314500 100644 --- a/arch/arm/boot/dts/tango4-common.dtsi +++ b/arch/arm/boot/dts/tango4-common.dtsi @@ -51,7 +51,7 @@ }; }; - l2cc: l2-cache-controller@20100000 { + l2cc: cache-controller@20100000 { compatible = "arm,pl310-cache"; reg = <0x20100000 0x1000>; cache-level = <2>; diff --git a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts index 2d683c9a1a5d..a0b829738e8f 100644 --- a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts +++ b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts @@ -14,6 +14,10 @@ compatible = "acer,picasso", "nvidia,tegra20"; aliases { + mmc0 = &sdmmc4; /* eMMC */ + mmc1 = &sdmmc3; /* MicroSD */ + mmc2 = &sdmmc1; /* WiFi */ + rtc0 = &pmic; rtc1 = "/rtc@7000e000"; @@ -314,16 +318,24 @@ nvidia,pins = "drive_ddc", "drive_vi1", "drive_sdio1"; + nvidia,pull-up-strength = <31>; + nvidia,pull-down-strength = <31>; nvidia,schmitt = <TEGRA_PIN_ENABLE>; - nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_4>; + nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>; + nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>; + nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOWEST>; + nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOWEST>; }; drive_dbg { nvidia,pins = "drive_dbg", "drive_vi2", "drive_at1", "drive_ao1"; + nvidia,pull-up-strength = <31>; + nvidia,pull-down-strength = <31>; nvidia,schmitt = <TEGRA_PIN_ENABLE>; - nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_4>; + nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>; + nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>; nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>; nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>; }; @@ -431,8 +443,6 @@ compatible = "atmel,maxtouch"; reg = <0x4c>; - atmel,cfg_name = "maxtouch-acer-iconia-tab-a500.cfg"; - interrupt-parent = <&gpio>; interrupts = <TEGRA_GPIO(V, 6) IRQ_TYPE_LEVEL_LOW>; @@ -720,13 +730,17 @@ power-off-delay-us = <300>; }; - mmc@c8000000 { + sdmmc1: mmc@c8000000 { status = "okay"; #address-cells = <1>; #size-cells = <0>; - max-frequency = <25000000>; + assigned-clocks = <&tegra_car TEGRA20_CLK_SDMMC1>; + assigned-clock-parents = <&tegra_car TEGRA20_CLK_PLL_C>; + assigned-clock-rates = <50000000>; + + max-frequency = <50000000>; keep-power-in-suspend; bus-width = <4>; non-removable; @@ -745,7 +759,7 @@ }; }; - mmc@c8000400 { + sdmmc3: mmc@c8000400 { status = "okay"; bus-width = <4>; cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; @@ -754,7 +768,7 @@ vqmmc-supply = <&vdd_3v3_sys>; }; - mmc@c8000600 { + sdmmc4: mmc@c8000600 { status = "okay"; bus-width = <8>; vmmc-supply = <&vcore_emmc>; diff --git a/arch/arm/boot/dts/tegra20-cpu-opp-microvolt.dtsi b/arch/arm/boot/dts/tegra20-cpu-opp-microvolt.dtsi index dce85d39480d..6f3e8c5fc5f0 100644 --- a/arch/arm/boot/dts/tegra20-cpu-opp-microvolt.dtsi +++ b/arch/arm/boot/dts/tegra20-cpu-opp-microvolt.dtsi @@ -26,14 +26,6 @@ opp-microvolt = <800000 800000 1125000>; }; - opp@456000000,800,2,2 { - opp-microvolt = <800000 800000 1125000>; - }; - - opp@456000000,800,3,2 { - opp-microvolt = <800000 800000 1125000>; - }; - opp@456000000,825 { opp-microvolt = <825000 825000 1125000>; }; @@ -46,10 +38,6 @@ opp-microvolt = <800000 800000 1125000>; }; - opp@608000000,800,3,2 { - opp-microvolt = <800000 800000 1125000>; - }; - opp@608000000,825 { opp-microvolt = <825000 825000 1125000>; }; @@ -78,18 +66,6 @@ opp-microvolt = <875000 875000 1125000>; }; - opp@760000000,875,1,1 { - opp-microvolt = <875000 875000 1125000>; - }; - - opp@760000000,875,0,2 { - opp-microvolt = <875000 875000 1125000>; - }; - - opp@760000000,875,1,2 { - opp-microvolt = <875000 875000 1125000>; - }; - opp@760000000,900 { opp-microvolt = <900000 900000 1125000>; }; @@ -134,14 +110,6 @@ opp-microvolt = <950000 950000 1125000>; }; - opp@912000000,950,0,2 { - opp-microvolt = <950000 950000 1125000>; - }; - - opp@912000000,950,2,2 { - opp-microvolt = <950000 950000 1125000>; - }; - opp@912000000,1000 { opp-microvolt = <1000000 1000000 1125000>; }; @@ -170,10 +138,6 @@ opp-microvolt = <1000000 1000000 1125000>; }; - opp@1000000000,1000,0,2 { - opp-microvolt = <1000000 1000000 1125000>; - }; - opp@1000000000,1025 { opp-microvolt = <1025000 1025000 1125000>; }; diff --git a/arch/arm/boot/dts/tegra20-cpu-opp.dtsi b/arch/arm/boot/dts/tegra20-cpu-opp.dtsi index 9b8fedb57a1b..702a635e88e7 100644 --- a/arch/arm/boot/dts/tegra20-cpu-opp.dtsi +++ b/arch/arm/boot/dts/tegra20-cpu-opp.dtsi @@ -37,19 +37,8 @@ opp@456000000,800 { clock-latency-ns = <400000>; - opp-supported-hw = <0x03 0x0006>; - opp-hz = /bits/ 64 <456000000>; - }; - - opp@456000000,800,2,2 { - clock-latency-ns = <400000>; - opp-supported-hw = <0x04 0x0004>; - opp-hz = /bits/ 64 <456000000>; - }; - - opp@456000000,800,3,2 { - clock-latency-ns = <400000>; - opp-supported-hw = <0x08 0x0004>; + opp-supported-hw = <0x03 0x0006>, <0x04 0x0004>, + <0x08 0x0004>; opp-hz = /bits/ 64 <456000000>; }; @@ -67,13 +56,7 @@ opp@608000000,800 { clock-latency-ns = <400000>; - opp-supported-hw = <0x04 0x0006>; - opp-hz = /bits/ 64 <608000000>; - }; - - opp@608000000,800,3,2 { - clock-latency-ns = <400000>; - opp-supported-hw = <0x08 0x0004>; + opp-supported-hw = <0x04 0x0006>, <0x08 0x0004>; opp-hz = /bits/ 64 <608000000>; }; @@ -115,25 +98,8 @@ opp@760000000,875 { clock-latency-ns = <400000>; - opp-supported-hw = <0x04 0x0001>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,875,1,1 { - clock-latency-ns = <400000>; - opp-supported-hw = <0x02 0x0002>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,875,0,2 { - clock-latency-ns = <400000>; - opp-supported-hw = <0x01 0x0004>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,875,1,2 { - clock-latency-ns = <400000>; - opp-supported-hw = <0x02 0x0004>; + opp-supported-hw = <0x04 0x0001>, <0x02 0x0002>, + <0x01 0x0004>, <0x02 0x0004>; opp-hz = /bits/ 64 <760000000>; }; @@ -199,19 +165,8 @@ opp@912000000,950 { clock-latency-ns = <400000>; - opp-supported-hw = <0x02 0x0006>; - opp-hz = /bits/ 64 <912000000>; - }; - - opp@912000000,950,0,2 { - clock-latency-ns = <400000>; - opp-supported-hw = <0x01 0x0004>; - opp-hz = /bits/ 64 <912000000>; - }; - - opp@912000000,950,2,2 { - clock-latency-ns = <400000>; - opp-supported-hw = <0x04 0x0004>; + opp-supported-hw = <0x02 0x0006>, <0x01 0x0004>, + <0x04 0x0004>; opp-hz = /bits/ 64 <912000000>; }; @@ -253,13 +208,7 @@ opp@1000000000,1000 { clock-latency-ns = <400000>; - opp-supported-hw = <0x02 0x0006>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,1000,0,2 { - clock-latency-ns = <400000>; - opp-supported-hw = <0x01 0x0004>; + opp-supported-hw = <0x02 0x0006>, <0x01 0x0004>; opp-hz = /bits/ 64 <1000000000>; }; 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 3922517145e7..88ca03f57b3b 100644 --- a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi +++ b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi @@ -2,6 +2,7 @@ #include <dt-bindings/input/gpio-keys.h> #include <dt-bindings/input/input.h> +#include <dt-bindings/power/summit,smb347-charger.h> #include <dt-bindings/thermal/thermal.h> #include "tegra30.dtsi" @@ -10,6 +11,9 @@ / { aliases { + mmc0 = &sdmmc4; /* eMMC */ + mmc1 = &sdmmc3; /* WiFi */ + rtc0 = &pmic; rtc1 = "/rtc@7000e000"; @@ -836,6 +840,24 @@ i2c@7000c400 { clock-frequency = <400000>; status = "okay"; + + touchscreen@10 { + compatible ="elan,ektf3624"; + reg = <0x10>; + + interrupt-parent = <&gpio>; + interrupts = <TEGRA_GPIO(H, 4) IRQ_TYPE_LEVEL_LOW>; + + reset-gpios = <&gpio TEGRA_GPIO(H, 6) GPIO_ACTIVE_LOW>; + + vcc33-supply = <&vcc_3v3_ts>; + vccio-supply = <&vcc_3v3_ts>; + + touchscreen-size-x = <2112>; + touchscreen-size-y = <1280>; + touchscreen-swapped-x-y; + touchscreen-inverted-x; + }; }; i2c@7000c500 { @@ -901,9 +923,24 @@ #thermal-sensor-cells = <1>; }; - battery@55 { + fuel-gauge@55 { compatible = "ti,bq27541"; reg = <0x55>; + power-supplies = <&power_supply>; + monitored-battery = <&battery_cell>; + }; + + power_supply: charger@6a { + compatible = "summit,smb347"; + reg = <0x6a>; + + interrupt-parent = <&gpio>; + interrupts = <TEGRA_GPIO(V, 1) IRQ_TYPE_EDGE_BOTH>; + + summit,enable-charge-control = <SMB3XX_CHG_ENABLE_PIN_ACTIVE_LOW>; + summit,enable-usb-charging; + + monitored-battery = <&battery_cell>; }; }; @@ -936,12 +973,17 @@ power-off-delay-us = <300>; }; - mmc@78000400 { + 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; @@ -960,7 +1002,7 @@ }; }; - mmc@78000600 { + sdmmc4: mmc@78000600 { status = "okay"; bus-width = <8>; vmmc-supply = <&vcore_emmc>; @@ -993,6 +1035,12 @@ default-brightness-level = <15>; }; + battery_cell: battery-cell { + compatible = "simple-battery"; + constant-charge-current-max-microamp = <1800000>; + operating-range-celsius = <0 45>; + }; + /* PMIC has a built-in 32KHz oscillator which is used by PMC */ clk32k_in: clock@0 { compatible = "fixed-clock"; diff --git a/arch/arm/boot/dts/tegra30-cpu-opp-microvolt.dtsi b/arch/arm/boot/dts/tegra30-cpu-opp-microvolt.dtsi index d682f7437146..1be715d2a442 100644 --- a/arch/arm/boot/dts/tegra30-cpu-opp-microvolt.dtsi +++ b/arch/arm/boot/dts/tegra30-cpu-opp-microvolt.dtsi @@ -74,22 +74,6 @@ opp-microvolt = <850000 850000 1250000>; }; - opp@475000000,850,0,1 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@475000000,850,0,4 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@475000000,850,0,7 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@475000000,850,0,8 { - opp-microvolt = <850000 850000 1250000>; - }; - opp@608000000,850 { opp-microvolt = <850000 850000 1250000>; }; @@ -106,62 +90,6 @@ opp-microvolt = <850000 850000 1250000>; }; - opp@640000000,850,1,1 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@640000000,850,2,1 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@640000000,850,3,1 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@640000000,850,1,4 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@640000000,850,2,4 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@640000000,850,3,4 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@640000000,850,1,7 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@640000000,850,2,7 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@640000000,850,3,7 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@640000000,850,4,7 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@640000000,850,1,8 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@640000000,850,2,8 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@640000000,850,3,8 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@640000000,850,4,8 { - opp-microvolt = <850000 850000 1250000>; - }; - opp@640000000,900 { opp-microvolt = <900000 900000 1250000>; }; @@ -170,94 +98,10 @@ opp-microvolt = <850000 850000 1250000>; }; - opp@760000000,850,3,1 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@760000000,850,3,2 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@760000000,850,3,3 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@760000000,850,3,4 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@760000000,850,3,7 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@760000000,850,4,7 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@760000000,850,3,8 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@760000000,850,4,8 { - opp-microvolt = <850000 850000 1250000>; - }; - - opp@760000000,850,0,10 { - opp-microvolt = <850000 850000 1250000>; - }; - opp@760000000,900 { opp-microvolt = <900000 900000 1250000>; }; - opp@760000000,900,1,1 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@760000000,900,2,1 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@760000000,900,1,2 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@760000000,900,2,2 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@760000000,900,1,3 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@760000000,900,2,3 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@760000000,900,1,4 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@760000000,900,2,4 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@760000000,900,1,7 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@760000000,900,2,7 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@760000000,900,1,8 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@760000000,900,2,8 { - opp-microvolt = <900000 900000 1250000>; - }; - opp@760000000,912 { opp-microvolt = <912000 912000 1250000>; }; @@ -282,90 +126,10 @@ opp-microvolt = <900000 900000 1250000>; }; - opp@860000000,900,2,1 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@860000000,900,3,1 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@860000000,900,2,2 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@860000000,900,3,2 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@860000000,900,2,3 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@860000000,900,3,3 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@860000000,900,2,4 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@860000000,900,3,4 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@860000000,900,2,7 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@860000000,900,3,7 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@860000000,900,4,7 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@860000000,900,2,8 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@860000000,900,3,8 { - opp-microvolt = <900000 900000 1250000>; - }; - - opp@860000000,900,4,8 { - opp-microvolt = <900000 900000 1250000>; - }; - opp@860000000,975 { opp-microvolt = <975000 975000 1250000>; }; - opp@860000000,975,1,1 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@860000000,975,1,2 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@860000000,975,1,3 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@860000000,975,1,4 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@860000000,975,1,7 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@860000000,975,1,8 { - opp-microvolt = <975000 975000 1250000>; - }; - opp@860000000,1000 { opp-microvolt = <1000000 1000000 1250000>; }; @@ -382,62 +146,6 @@ opp-microvolt = <975000 975000 1250000>; }; - opp@1000000000,975,2,1 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1000000000,975,3,1 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1000000000,975,2,2 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1000000000,975,3,2 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1000000000,975,2,3 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1000000000,975,3,3 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1000000000,975,2,4 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1000000000,975,3,4 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1000000000,975,2,7 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1000000000,975,3,7 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1000000000,975,4,7 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1000000000,975,2,8 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1000000000,975,3,8 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1000000000,975,4,8 { - opp-microvolt = <975000 975000 1250000>; - }; - opp@1000000000,1000 { opp-microvolt = <1000000 1000000 1250000>; }; @@ -454,66 +162,10 @@ opp-microvolt = <975000 975000 1250000>; }; - opp@1100000000,975,3,1 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1100000000,975,3,2 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1100000000,975,3,3 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1100000000,975,3,4 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1100000000,975,3,7 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1100000000,975,4,7 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1100000000,975,3,8 { - opp-microvolt = <975000 975000 1250000>; - }; - - opp@1100000000,975,4,8 { - opp-microvolt = <975000 975000 1250000>; - }; - opp@1100000000,1000 { opp-microvolt = <1000000 1000000 1250000>; }; - opp@1100000000,1000,2,1 { - opp-microvolt = <1000000 1000000 1250000>; - }; - - opp@1100000000,1000,2,2 { - opp-microvolt = <1000000 1000000 1250000>; - }; - - opp@1100000000,1000,2,3 { - opp-microvolt = <1000000 1000000 1250000>; - }; - - opp@1100000000,1000,2,4 { - opp-microvolt = <1000000 1000000 1250000>; - }; - - opp@1100000000,1000,2,7 { - opp-microvolt = <1000000 1000000 1250000>; - }; - - opp@1100000000,1000,2,8 { - opp-microvolt = <1000000 1000000 1250000>; - }; - opp@1100000000,1025 { opp-microvolt = <1025000 1025000 1250000>; }; @@ -534,66 +186,10 @@ opp-microvolt = <1000000 1000000 1250000>; }; - opp@1200000000,1000,3,1 { - opp-microvolt = <1000000 1000000 1250000>; - }; - - opp@1200000000,1000,3,2 { - opp-microvolt = <1000000 1000000 1250000>; - }; - - opp@1200000000,1000,3,3 { - opp-microvolt = <1000000 1000000 1250000>; - }; - - opp@1200000000,1000,3,4 { - opp-microvolt = <1000000 1000000 1250000>; - }; - - opp@1200000000,1000,3,7 { - opp-microvolt = <1000000 1000000 1250000>; - }; - - opp@1200000000,1000,4,7 { - opp-microvolt = <1000000 1000000 1250000>; - }; - - opp@1200000000,1000,3,8 { - opp-microvolt = <1000000 1000000 1250000>; - }; - - opp@1200000000,1000,4,8 { - opp-microvolt = <1000000 1000000 1250000>; - }; - opp@1200000000,1025 { opp-microvolt = <1025000 1025000 1250000>; }; - opp@1200000000,1025,2,1 { - opp-microvolt = <1025000 1025000 1250000>; - }; - - opp@1200000000,1025,2,2 { - opp-microvolt = <1025000 1025000 1250000>; - }; - - opp@1200000000,1025,2,3 { - opp-microvolt = <1025000 1025000 1250000>; - }; - - opp@1200000000,1025,2,4 { - opp-microvolt = <1025000 1025000 1250000>; - }; - - opp@1200000000,1025,2,7 { - opp-microvolt = <1025000 1025000 1250000>; - }; - - opp@1200000000,1025,2,8 { - opp-microvolt = <1025000 1025000 1250000>; - }; - opp@1200000000,1050 { opp-microvolt = <1050000 1050000 1250000>; }; @@ -610,90 +206,18 @@ opp-microvolt = <1000000 1000000 1250000>; }; - opp@1300000000,1000,4,7 { - opp-microvolt = <1000000 1000000 1250000>; - }; - - opp@1300000000,1000,4,8 { - opp-microvolt = <1000000 1000000 1250000>; - }; - opp@1300000000,1025 { opp-microvolt = <1025000 1025000 1250000>; }; - opp@1300000000,1025,3,1 { - opp-microvolt = <1025000 1025000 1250000>; - }; - - opp@1300000000,1025,3,7 { - opp-microvolt = <1025000 1025000 1250000>; - }; - - opp@1300000000,1025,3,8 { - opp-microvolt = <1025000 1025000 1250000>; - }; - opp@1300000000,1050 { opp-microvolt = <1050000 1050000 1250000>; }; - opp@1300000000,1050,2,1 { - opp-microvolt = <1050000 1050000 1250000>; - }; - - opp@1300000000,1050,3,2 { - opp-microvolt = <1050000 1050000 1250000>; - }; - - opp@1300000000,1050,3,3 { - opp-microvolt = <1050000 1050000 1250000>; - }; - - opp@1300000000,1050,3,4 { - opp-microvolt = <1050000 1050000 1250000>; - }; - - opp@1300000000,1050,3,5 { - opp-microvolt = <1050000 1050000 1250000>; - }; - - opp@1300000000,1050,3,6 { - opp-microvolt = <1050000 1050000 1250000>; - }; - - opp@1300000000,1050,2,7 { - opp-microvolt = <1050000 1050000 1250000>; - }; - - opp@1300000000,1050,2,8 { - opp-microvolt = <1050000 1050000 1250000>; - }; - - opp@1300000000,1050,3,12 { - opp-microvolt = <1050000 1050000 1250000>; - }; - - opp@1300000000,1050,3,13 { - opp-microvolt = <1050000 1050000 1250000>; - }; - opp@1300000000,1075 { opp-microvolt = <1075000 1075000 1250000>; }; - opp@1300000000,1075,2,2 { - opp-microvolt = <1075000 1075000 1250000>; - }; - - opp@1300000000,1075,2,3 { - opp-microvolt = <1075000 1075000 1250000>; - }; - - opp@1300000000,1075,2,4 { - opp-microvolt = <1075000 1075000 1250000>; - }; - opp@1300000000,1100 { opp-microvolt = <1100000 1100000 1250000>; }; @@ -722,10 +246,6 @@ opp-microvolt = <1150000 1150000 1250000>; }; - opp@1400000000,1150,2,4 { - opp-microvolt = <1150000 1150000 1250000>; - }; - opp@1400000000,1175 { opp-microvolt = <1175000 1175000 1250000>; }; @@ -738,42 +258,10 @@ opp-microvolt = <1125000 1125000 1250000>; }; - opp@1500000000,1125,4,5 { - opp-microvolt = <1125000 1125000 1250000>; - }; - - opp@1500000000,1125,4,6 { - opp-microvolt = <1125000 1125000 1250000>; - }; - - opp@1500000000,1125,4,12 { - opp-microvolt = <1125000 1125000 1250000>; - }; - - opp@1500000000,1125,4,13 { - opp-microvolt = <1125000 1125000 1250000>; - }; - opp@1500000000,1150 { opp-microvolt = <1150000 1150000 1250000>; }; - opp@1500000000,1150,3,5 { - opp-microvolt = <1150000 1150000 1250000>; - }; - - opp@1500000000,1150,3,6 { - opp-microvolt = <1150000 1150000 1250000>; - }; - - opp@1500000000,1150,3,12 { - opp-microvolt = <1150000 1150000 1250000>; - }; - - opp@1500000000,1150,3,13 { - opp-microvolt = <1150000 1150000 1250000>; - }; - opp@1500000000,1200 { opp-microvolt = <1200000 1200000 1250000>; }; diff --git a/arch/arm/boot/dts/tegra30-cpu-opp.dtsi b/arch/arm/boot/dts/tegra30-cpu-opp.dtsi index 8e434f6713cd..0f7135006d19 100644 --- a/arch/arm/boot/dts/tegra30-cpu-opp.dtsi +++ b/arch/arm/boot/dts/tegra30-cpu-opp.dtsi @@ -109,31 +109,9 @@ opp@475000000,850 { clock-latency-ns = <100000>; - opp-supported-hw = <0x0F 0x0001>; - opp-hz = /bits/ 64 <475000000>; - }; - - opp@475000000,850,0,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x01 0x0002>; - opp-hz = /bits/ 64 <475000000>; - }; - - opp@475000000,850,0,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x01 0x0010>; - opp-hz = /bits/ 64 <475000000>; - }; - - opp@475000000,850,0,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x01 0x0080>; - opp-hz = /bits/ 64 <475000000>; - }; - - opp@475000000,850,0,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x01 0x0100>; + opp-supported-hw = <0x0F 0x0001>, <0x01 0x0002>, + <0x01 0x0010>, <0x01 0x0080>, + <0x01 0x0100>; opp-hz = /bits/ 64 <475000000>; }; @@ -157,91 +135,14 @@ opp@640000000,850 { clock-latency-ns = <100000>; - opp-supported-hw = <0x0F 0x0001>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,1,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0002>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,2,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0002>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,3,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0002>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,1,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0010>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,2,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0010>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,3,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0010>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,1,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0080>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,2,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0080>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,3,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0080>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,4,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0080>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,1,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0100>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,2,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0100>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,3,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0100>; - opp-hz = /bits/ 64 <640000000>; - }; - - opp@640000000,850,4,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0100>; + opp-supported-hw = <0x0F 0x0001>, <0x02 0x0002>, + <0x04 0x0002>, <0x08 0x0002>, + <0x02 0x0010>, <0x04 0x0010>, + <0x08 0x0010>, <0x02 0x0080>, + <0x04 0x0080>, <0x08 0x0080>, + <0x10 0x0080>, <0x02 0x0100>, + <0x04 0x0100>, <0x08 0x0100>, + <0x10 0x0100>; opp-hz = /bits/ 64 <640000000>; }; @@ -253,139 +154,23 @@ opp@760000000,850 { clock-latency-ns = <100000>; - opp-supported-hw = <0x1E 0x3461>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,850,3,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0002>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,850,3,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0004>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,850,3,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0008>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,850,3,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0010>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,850,3,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0080>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,850,4,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0080>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,850,3,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0100>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,850,4,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0100>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,850,0,10 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x01 0x0400>; + opp-supported-hw = <0x1E 0x3461>, <0x08 0x0002>, + <0x08 0x0004>, <0x08 0x0008>, + <0x08 0x0010>, <0x08 0x0080>, + <0x10 0x0080>, <0x08 0x0100>, + <0x10 0x0100>, <0x01 0x0400>; opp-hz = /bits/ 64 <760000000>; }; opp@760000000,900 { clock-latency-ns = <100000>; - opp-supported-hw = <0x01 0x0001>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,900,1,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0002>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,900,2,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0002>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,900,1,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0004>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,900,2,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0004>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,900,1,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0008>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,900,2,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0008>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,900,1,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0010>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,900,2,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0010>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,900,1,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0080>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,900,2,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0080>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,900,1,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0100>; - opp-hz = /bits/ 64 <760000000>; - }; - - opp@760000000,900,2,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0100>; + opp-supported-hw = <0x01 0x0001>, <0x02 0x0002>, + <0x04 0x0002>, <0x02 0x0004>, + <0x04 0x0004>, <0x02 0x0008>, + <0x04 0x0008>, <0x02 0x0010>, + <0x04 0x0010>, <0x02 0x0080>, + <0x04 0x0080>, <0x02 0x0100>, + <0x04 0x0100>; opp-hz = /bits/ 64 <760000000>; }; @@ -421,133 +206,23 @@ opp@860000000,900 { clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0001>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,2,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0002>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,3,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0002>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,2,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0004>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,3,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0004>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,2,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0008>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,3,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0008>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,2,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0010>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,3,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0010>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,2,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0080>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,3,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0080>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,4,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0080>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,2,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0100>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,3,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0100>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,900,4,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0100>; + opp-supported-hw = <0x02 0x0001>, <0x04 0x0002>, + <0x08 0x0002>, <0x04 0x0004>, + <0x08 0x0004>, <0x04 0x0008>, + <0x08 0x0008>, <0x04 0x0010>, + <0x08 0x0010>, <0x04 0x0080>, + <0x08 0x0080>, <0x10 0x0080>, + <0x04 0x0100>, <0x08 0x0100>, + <0x10 0x0100>; opp-hz = /bits/ 64 <860000000>; }; opp@860000000,975 { clock-latency-ns = <100000>; - opp-supported-hw = <0x01 0x0001>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,975,1,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0002>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,975,1,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0004>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,975,1,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0008>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,975,1,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0010>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,975,1,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0080>; - opp-hz = /bits/ 64 <860000000>; - }; - - opp@860000000,975,1,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0100>; + opp-supported-hw = <0x01 0x0001>, <0x02 0x0002>, + <0x02 0x0004>, <0x02 0x0008>, + <0x02 0x0010>, <0x02 0x0080>, + <0x02 0x0100>; opp-hz = /bits/ 64 <860000000>; }; @@ -571,91 +246,14 @@ opp@1000000000,975 { clock-latency-ns = <100000>; - opp-supported-hw = <0x03 0x0001>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,2,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0002>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,3,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0002>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,2,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0004>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,3,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0004>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,2,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0008>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,3,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0008>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,2,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0010>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,3,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0010>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,2,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0080>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,3,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0080>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,4,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0080>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,2,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0100>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,3,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0100>; - opp-hz = /bits/ 64 <1000000000>; - }; - - opp@1000000000,975,4,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0100>; + opp-supported-hw = <0x03 0x0001>, <0x04 0x0002>, + <0x08 0x0002>, <0x04 0x0004>, + <0x08 0x0004>, <0x04 0x0008>, + <0x08 0x0008>, <0x04 0x0010>, + <0x08 0x0010>, <0x04 0x0080>, + <0x08 0x0080>, <0x10 0x0080>, + <0x04 0x0100>, <0x08 0x0100>, + <0x10 0x0100>; opp-hz = /bits/ 64 <1000000000>; }; @@ -679,97 +277,20 @@ opp@1100000000,975 { clock-latency-ns = <100000>; - opp-supported-hw = <0x06 0x0001>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,975,3,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0002>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,975,3,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0004>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,975,3,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0008>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,975,3,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0010>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,975,3,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0080>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,975,4,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0080>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,975,3,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0100>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,975,4,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0100>; + opp-supported-hw = <0x06 0x0001>, <0x08 0x0002>, + <0x08 0x0004>, <0x08 0x0008>, + <0x08 0x0010>, <0x08 0x0080>, + <0x10 0x0080>, <0x08 0x0100>, + <0x10 0x0100>; opp-hz = /bits/ 64 <1100000000>; }; opp@1100000000,1000 { clock-latency-ns = <100000>; - opp-supported-hw = <0x01 0x0001>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,1000,2,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0002>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,1000,2,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0004>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,1000,2,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0008>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,1000,2,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0010>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,1000,2,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0080>; - opp-hz = /bits/ 64 <1100000000>; - }; - - opp@1100000000,1000,2,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0100>; + opp-supported-hw = <0x01 0x0001>, <0x04 0x0002>, + <0x04 0x0004>, <0x04 0x0008>, + <0x04 0x0010>, <0x04 0x0080>, + <0x04 0x0100>; opp-hz = /bits/ 64 <1100000000>; }; @@ -799,97 +320,20 @@ opp@1200000000,1000 { clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0001>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1000,3,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0002>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1000,3,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0004>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1000,3,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0008>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1000,3,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0010>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1000,3,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0080>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1000,4,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0080>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1000,3,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0100>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1000,4,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0100>; + opp-supported-hw = <0x04 0x0001>, <0x08 0x0002>, + <0x08 0x0004>, <0x08 0x0008>, + <0x08 0x0010>, <0x08 0x0080>, + <0x10 0x0080>, <0x08 0x0100>, + <0x10 0x0100>; opp-hz = /bits/ 64 <1200000000>; }; opp@1200000000,1025 { clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0001>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1025,2,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0002>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1025,2,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0004>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1025,2,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0008>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1025,2,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0010>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1025,2,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0080>; - opp-hz = /bits/ 64 <1200000000>; - }; - - opp@1200000000,1025,2,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0100>; + opp-supported-hw = <0x02 0x0001>, <0x04 0x0002>, + <0x04 0x0004>, <0x04 0x0008>, + <0x04 0x0010>, <0x04 0x0080>, + <0x04 0x0100>; opp-hz = /bits/ 64 <1200000000>; }; @@ -913,133 +357,33 @@ opp@1300000000,1000 { clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0001>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1000,4,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0080>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1000,4,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0100>; + opp-supported-hw = <0x08 0x0001>, <0x10 0x0080>, + <0x10 0x0100>; opp-hz = /bits/ 64 <1300000000>; }; opp@1300000000,1025 { clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0001>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1025,3,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0002>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1025,3,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0080>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1025,3,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0100>; + opp-supported-hw = <0x04 0x0001>, <0x08 0x0002>, + <0x08 0x0080>, <0x08 0x0100>; opp-hz = /bits/ 64 <1300000000>; }; opp@1300000000,1050 { clock-latency-ns = <100000>; - opp-supported-hw = <0x12 0x3061>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1050,2,1 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0002>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1050,3,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0004>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1050,3,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0008>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1050,3,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0010>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1050,3,5 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0020>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1050,3,6 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0040>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1050,2,7 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0080>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1050,2,8 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0100>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1050,3,12 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x1000>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1050,3,13 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x2000>; + opp-supported-hw = <0x12 0x3061>, <0x04 0x0002>, + <0x08 0x0004>, <0x08 0x0008>, + <0x08 0x0010>, <0x08 0x0020>, + <0x08 0x0040>, <0x04 0x0080>, + <0x04 0x0100>, <0x08 0x1000>, + <0x08 0x2000>; opp-hz = /bits/ 64 <1300000000>; }; opp@1300000000,1075 { clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x0182>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1075,2,2 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0004>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1075,2,3 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0008>; - opp-hz = /bits/ 64 <1300000000>; - }; - - opp@1300000000,1075,2,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0010>; + opp-supported-hw = <0x02 0x0182>, <0x04 0x0004>, + <0x04 0x0008>, <0x04 0x0010>; opp-hz = /bits/ 64 <1300000000>; }; @@ -1081,13 +425,7 @@ opp@1400000000,1150 { clock-latency-ns = <100000>; - opp-supported-hw = <0x02 0x000C>; - opp-hz = /bits/ 64 <1400000000>; - }; - - opp@1400000000,1150,2,4 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0010>; + opp-supported-hw = <0x02 0x000C>, <0x04 0x0010>; opp-hz = /bits/ 64 <1400000000>; }; @@ -1105,61 +443,17 @@ opp@1500000000,1125 { clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0010>; - opp-hz = /bits/ 64 <1500000000>; - }; - - opp@1500000000,1125,4,5 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0020>; - opp-hz = /bits/ 64 <1500000000>; - }; - - opp@1500000000,1125,4,6 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x0040>; - opp-hz = /bits/ 64 <1500000000>; - }; - - opp@1500000000,1125,4,12 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x1000>; - opp-hz = /bits/ 64 <1500000000>; - }; - - opp@1500000000,1125,4,13 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x10 0x2000>; + opp-supported-hw = <0x08 0x0010>, <0x10 0x0020>, + <0x10 0x0040>, <0x10 0x1000>, + <0x10 0x2000>; opp-hz = /bits/ 64 <1500000000>; }; opp@1500000000,1150 { clock-latency-ns = <100000>; - opp-supported-hw = <0x04 0x0010>; - opp-hz = /bits/ 64 <1500000000>; - }; - - opp@1500000000,1150,3,5 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0020>; - opp-hz = /bits/ 64 <1500000000>; - }; - - opp@1500000000,1150,3,6 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x0040>; - opp-hz = /bits/ 64 <1500000000>; - }; - - opp@1500000000,1150,3,12 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x1000>; - opp-hz = /bits/ 64 <1500000000>; - }; - - opp@1500000000,1150,3,13 { - clock-latency-ns = <100000>; - opp-supported-hw = <0x08 0x2000>; + opp-supported-hw = <0x04 0x0010>, <0x08 0x0020>, + <0x08 0x0040>, <0x08 0x1000>, + <0x08 0x2000>; opp-hz = /bits/ 64 <1500000000>; }; diff --git a/arch/arm/boot/dts/tny_a9260_common.dtsi b/arch/arm/boot/dts/tny_a9260_common.dtsi index dd6957b20772..70e5635c78ed 100644 --- a/arch/arm/boot/dts/tny_a9260_common.dtsi +++ b/arch/arm/boot/dts/tny_a9260_common.dtsi @@ -10,7 +10,7 @@ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock6 rw rootfstype=ubifs"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; diff --git a/arch/arm/boot/dts/tny_a9263.dts b/arch/arm/boot/dts/tny_a9263.dts index 2820635952e3..62b7d9f9a926 100644 --- a/arch/arm/boot/dts/tny_a9263.dts +++ b/arch/arm/boot/dts/tny_a9263.dts @@ -15,7 +15,7 @@ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; diff --git a/arch/arm/boot/dts/usb_a9260.dts b/arch/arm/boot/dts/usb_a9260.dts index ec8cd86b260d..6cfa83921ac2 100644 --- a/arch/arm/boot/dts/usb_a9260.dts +++ b/arch/arm/boot/dts/usb_a9260.dts @@ -16,7 +16,7 @@ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; diff --git a/arch/arm/boot/dts/usb_a9263.dts b/arch/arm/boot/dts/usb_a9263.dts index e7a705fddda9..8a0cfbfd0c45 100644 --- a/arch/arm/boot/dts/usb_a9263.dts +++ b/arch/arm/boot/dts/usb_a9263.dts @@ -15,7 +15,7 @@ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; diff --git a/arch/arm/boot/dts/usb_a9g20_common.dtsi b/arch/arm/boot/dts/usb_a9g20_common.dtsi index adbe75024739..7d10b36db1ee 100644 --- a/arch/arm/boot/dts/usb_a9g20_common.dtsi +++ b/arch/arm/boot/dts/usb_a9g20_common.dtsi @@ -14,7 +14,7 @@ stdout-path = "serial0:115200n8"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi index a88ee5294d35..4f7220b11f2d 100644 --- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi +++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi @@ -280,7 +280,7 @@ reg = <0x0f0000 0x1000>; interrupts = <0>; clocks = <&v2m_refclk32khz>, <&smbclk>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; }; v2m_timer01: timer@110000 { diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi index 5e48b641068a..2ac41ed3a57c 100644 --- a/arch/arm/boot/dts/vexpress-v2m.dtsi +++ b/arch/arm/boot/dts/vexpress-v2m.dtsi @@ -198,7 +198,7 @@ reg = <0x0f000 0x1000>; interrupts = <0>; clocks = <&v2m_refclk32khz>, <&smbclk>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; }; v2m_timer01: timer@11000 { diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts index f82fa34c90be..e63c5c0bfb43 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts @@ -87,8 +87,8 @@ status = "disabled"; reg = <0 0x2b060000 0 0x1000>; interrupts = <0 98 4>; - clocks = <&sys_pll>; - clock-names = "apb_pclk"; + clocks = <&sys_pll>, <&sys_pll>; + clock-names = "wdog_clk", "apb_pclk"; }; gic: interrupt-controller@2c001000 { diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts index 3ac95a179452..012d40a7228c 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts @@ -128,7 +128,7 @@ reg = <0 0x2a490000 0 0x1000>; interrupts = <0 98 4>; clocks = <&oscclk6a>, <&oscclk6a>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; }; hdlcd@2b000000 { diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts index 623246f37448..4c5847955856 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts @@ -122,8 +122,8 @@ reg = <0x100e4000 0x1000>; interrupts = <0 48 4>, <0 49 4>; - clocks = <&oscclk2>, <&oscclk2>; - clock-names = "timclk", "apb_pclk"; + clocks = <&oscclk2>, <&oscclk2>, <&oscclk2>; + clock-names = "timer0clk", "timer1clk", "apb_pclk"; status = "disabled"; }; @@ -132,7 +132,7 @@ reg = <0x100e5000 0x1000>; interrupts = <0 51 4>; clocks = <&oscclk2>, <&oscclk2>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; }; scu@1e000000 { diff --git a/arch/arm/boot/dts/vf610-zii-cfu1.dts b/arch/arm/boot/dts/vf610-zii-cfu1.dts index 64e0e9509226..96495d965163 100644 --- a/arch/arm/boot/dts/vf610-zii-cfu1.dts +++ b/arch/arm/boot/dts/vf610-zii-cfu1.dts @@ -172,7 +172,6 @@ interrupts = <2 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; #interrupt-cells = <2>; - reset-gpios = <&gpio3 11 GPIO_ACTIVE_LOW>; ports { #address-cells = <1>; @@ -226,6 +225,7 @@ compatible = "nxp,pca9554"; reg = <0x22>; gpio-controller; + #gpio-cells = <2>; }; lm75@48 { @@ -356,7 +356,6 @@ pinctrl_switch: switch-grp { fsl,pins = < VF610_PAD_PTB28__GPIO_98 0x3061 - VF610_PAD_PTE2__GPIO_107 0x1042 >; }; diff --git a/arch/arm/boot/dts/vf610-zii-spb4.dts b/arch/arm/boot/dts/vf610-zii-spb4.dts index 9e5187ba3fa6..6c6ec46fd015 100644 --- a/arch/arm/boot/dts/vf610-zii-spb4.dts +++ b/arch/arm/boot/dts/vf610-zii-spb4.dts @@ -129,7 +129,6 @@ pinctrl-names = "default"; reg = <0>; eeprom-length = <65536>; - reset-gpios = <&gpio3 11 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio3>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; @@ -326,7 +325,6 @@ pinctrl_gpio_switch0: pinctrl-gpio-switch0 { fsl,pins = < - VF610_PAD_PTE2__GPIO_107 0x31c2 VF610_PAD_PTB28__GPIO_98 0x219d >; }; diff --git a/arch/arm/boot/dts/vf610-zii-ssmb-dtu.dts b/arch/arm/boot/dts/vf610-zii-ssmb-dtu.dts index 569614b08f04..73fdace4cb42 100644 --- a/arch/arm/boot/dts/vf610-zii-ssmb-dtu.dts +++ b/arch/arm/boot/dts/vf610-zii-ssmb-dtu.dts @@ -118,7 +118,6 @@ pinctrl-names = "default"; reg = <0>; eeprom-length = <65536>; - reset-gpios = <&gpio3 11 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio3>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; @@ -293,7 +292,6 @@ pinctrl_gpio_switch0: pinctrl-gpio-switch0 { fsl,pins = < - VF610_PAD_PTE2__GPIO_107 0x31c2 VF610_PAD_PTB28__GPIO_98 0x219d >; }; diff --git a/arch/arm/boot/dts/vf610-zii-ssmb-spu3.dts b/arch/arm/boot/dts/vf610-zii-ssmb-spu3.dts index b6b0f302b7b4..fe600ab2e4bd 100644 --- a/arch/arm/boot/dts/vf610-zii-ssmb-spu3.dts +++ b/arch/arm/boot/dts/vf610-zii-ssmb-spu3.dts @@ -143,7 +143,6 @@ pinctrl-names = "default"; reg = <0>; eeprom-length = <65536>; - reset-gpios = <&gpio3 11 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio3>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; @@ -333,7 +332,6 @@ pinctrl_gpio_switch0: pinctrl-gpio-switch0 { fsl,pins = < - VF610_PAD_PTE2__GPIO_107 0x31c2 VF610_PAD_PTB28__GPIO_98 0x219d >; }; diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi index 0fe03aa0367f..2259d11af721 100644 --- a/arch/arm/boot/dts/vfxxx.dtsi +++ b/arch/arm/boot/dts/vfxxx.dtsi @@ -495,7 +495,7 @@ }; ocotp: ocotp@400a5000 { - compatible = "fsl,vf610-ocotp"; + compatible = "fsl,vf610-ocotp", "syscon"; reg = <0x400a5000 0x1000>; clocks = <&clks VF610_CLK_OCOTP>; }; diff --git a/arch/arm/boot/dts/zx296702.dtsi b/arch/arm/boot/dts/zx296702.dtsi index afd98de029be..f378c661b3bf 100644 --- a/arch/arm/boot/dts/zx296702.dtsi +++ b/arch/arm/boot/dts/zx296702.dtsi @@ -58,7 +58,7 @@ clocks = <&topclk ZX296702_A9_PERIPHCLK>; }; - l2cc: l2-cache-controller@c00000 { + l2cc: cache-controller@c00000 { compatible = "arm,pl310-cache"; reg = <0x00c00000 0x1000>; cache-unified; diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index f4b719bde763..7996c04393d5 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c @@ -24,7 +24,8 @@ #include <linux/slab.h> #include <linux/page-flags.h> #include <linux/device.h> -#include <linux/dma-mapping.h> +#include <linux/dma-direct.h> +#include <linux/dma-map-ops.h> #include <linux/dmapool.h> #include <linux/list.h> #include <linux/scatterlist.h> diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index c98ebae1aeac..f89c1ea327a2 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -22,7 +22,7 @@ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/spinlock.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/clk.h> #include <linux/io.h> diff --git a/arch/arm/configs/aspeed_g4_defconfig b/arch/arm/configs/aspeed_g4_defconfig index 303f75a3baec..58d293b63581 100644 --- a/arch/arm/configs/aspeed_g4_defconfig +++ b/arch/arm/configs/aspeed_g4_defconfig @@ -160,7 +160,8 @@ CONFIG_SENSORS_TMP421=y CONFIG_SENSORS_W83773G=y CONFIG_WATCHDOG_SYSFS=y CONFIG_MEDIA_SUPPORT=y -CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_SUPPORT_FILTER=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_VIDEO_ASPEED=y CONFIG_DRM=y diff --git a/arch/arm/configs/aspeed_g5_defconfig b/arch/arm/configs/aspeed_g5_defconfig index b0d056d49abe..047975eccefb 100644 --- a/arch/arm/configs/aspeed_g5_defconfig +++ b/arch/arm/configs/aspeed_g5_defconfig @@ -128,6 +128,8 @@ CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y CONFIG_KEYBOARD_GPIO_POLLED=y # CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_IBM_PANEL=y # CONFIG_SERIO is not set # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set @@ -147,10 +149,12 @@ CONFIG_HW_RANDOM_TIMERIOMEM=y # CONFIG_I2C_COMPAT is not set CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_GPIO=y CONFIG_I2C_MUX_PCA9541=y CONFIG_I2C_MUX_PCA954x=y CONFIG_I2C_ASPEED=y CONFIG_I2C_FSI=y +CONFIG_I2C_SLAVE=y CONFIG_SPI=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y @@ -175,7 +179,8 @@ CONFIG_SENSORS_TMP421=y CONFIG_SENSORS_W83773G=y CONFIG_WATCHDOG_SYSFS=y CONFIG_MEDIA_SUPPORT=y -CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_SUPPORT_FILTER=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_VIDEO_ASPEED=y CONFIG_DRM=y diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index 6e8b5ff0859c..cf82c9d23a08 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -191,11 +191,14 @@ CONFIG_REGULATOR_S2MPS11=y CONFIG_REGULATOR_S5M8767=y CONFIG_REGULATOR_TPS65090=y CONFIG_REGULATOR_WM8994=y +CONFIG_MEDIA_CEC_SUPPORT=y +CONFIG_CEC_SAMSUNG_S5P=m CONFIG_MEDIA_SUPPORT=m +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set CONFIG_MEDIA_CAMERA_SUPPORT=y -CONFIG_MEDIA_CEC_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y CONFIG_MEDIA_USB_SUPPORT=y CONFIG_USB_VIDEO_CLASS=m CONFIG_V4L_PLATFORM_DRIVERS=y @@ -210,9 +213,6 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=m CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m CONFIG_V4L_TEST_DRIVERS=y CONFIG_VIDEO_VIVID=m -CONFIG_CEC_PLATFORM_DRIVERS=y -CONFIG_CEC_SAMSUNG_S5P=m -# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set CONFIG_VIDEO_S5K6A3=m CONFIG_VIDEO_S5C73M3=m CONFIG_DRM=y diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig index f5f1111f2118..aeb1209e0804 100644 --- a/arch/arm/configs/imx_v4_v5_defconfig +++ b/arch/arm/configs/imx_v4_v5_defconfig @@ -20,9 +20,9 @@ CONFIG_MACH_MX27ADS=y CONFIG_MACH_MX27_3DS=y CONFIG_MACH_IMX27_VISSTRIM_M10=y CONFIG_MACH_PCA100=y -CONFIG_MACH_IMX27_DT=y CONFIG_SOC_IMX1=y CONFIG_SOC_IMX25=y +CONFIG_SOC_IMX27=y CONFIG_AEABI=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 82d3ffb18e70..0fa79bd00219 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -15,20 +15,8 @@ CONFIG_PERF_EVENTS=y # CONFIG_COMPAT_BRK is not set CONFIG_ARCH_MULTI_V6=y CONFIG_ARCH_MXC=y -CONFIG_MACH_MX31LILLY=y -CONFIG_MACH_MX31LITE=y -CONFIG_MACH_PCM037=y -CONFIG_MACH_PCM037_EET=y -CONFIG_MACH_MX31_3DS=y -CONFIG_MACH_MX31MOBOARD=y -CONFIG_MACH_QONG=y -CONFIG_MACH_ARMADILLO5X0=y -CONFIG_MACH_KZM_ARM11_01=y -CONFIG_MACH_IMX31_DT=y -CONFIG_MACH_IMX35_DT=y -CONFIG_MACH_PCM043=y -CONFIG_MACH_MX35_3DS=y -CONFIG_MACH_VPR200=y +CONFIG_SOC_IMX31=y +CONFIG_SOC_IMX35=y CONFIG_SOC_IMX50=y CONFIG_SOC_IMX51=y CONFIG_SOC_IMX53=y @@ -218,6 +206,9 @@ CONFIG_SPI_GPIO=y CONFIG_SPI_IMX=y CONFIG_SPI_FSL_DSPI=y CONFIG_PINCTRL_IMX8MM=y +CONFIG_PINCTRL_IMX8MN=y +CONFIG_PINCTRL_IMX8MP=y +CONFIG_PINCTRL_IMX8MQ=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_SIOX=m CONFIG_GPIO_MAX732X=y @@ -407,6 +398,9 @@ CONFIG_STAGING_MEDIA=y CONFIG_VIDEO_IMX_MEDIA=y CONFIG_COMMON_CLK_PWM=y CONFIG_CLK_IMX8MM=y +CONFIG_CLK_IMX8MN=y +CONFIG_CLK_IMX8MP=y +CONFIG_CLK_IMX8MQ=y CONFIG_SOC_IMX8M=y CONFIG_IIO=y CONFIG_MMA8452=y diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig index a9755c501bec..b06e537d5149 100644 --- a/arch/arm/configs/integrator_defconfig +++ b/arch/arm/configs/integrator_defconfig @@ -1,13 +1,11 @@ CONFIG_SYSVIPC=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y +CONFIG_PREEMPT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_MULTI_V4T=y CONFIG_ARCH_MULTI_V5=y # CONFIG_ARCH_MULTI_V7 is not set @@ -15,19 +13,17 @@ CONFIG_ARCH_INTEGRATOR=y CONFIG_ARCH_INTEGRATOR_AP=y CONFIG_INTEGRATOR_IMPD1=y CONFIG_ARCH_INTEGRATOR_CP=y -CONFIG_PCI=y -CONFIG_PREEMPT=y CONFIG_AEABI=y # CONFIG_ATAGS is not set -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="console=ttyAM0,38400n8 root=/dev/nfs ip=bootp" CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPUFREQ_DT=y -CONFIG_CMA=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -37,6 +33,7 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IPV6 is not set +CONFIG_PCI=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_AFS_PARTS=y @@ -52,9 +49,12 @@ CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_NETDEVICES=y CONFIG_E100=y CONFIG_SMC91X=y +CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_GPIO=y # CONFIG_SERIO_SERPORT is not set CONFIG_DRM=y +CONFIG_DRM_DISPLAY_CONNECTOR=y CONFIG_DRM_SIMPLE_BRIDGE=y CONFIG_DRM_PL111=y CONFIG_FB_MODE_HELPERS=y diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig index 2724fb3155cd..70b709a669d2 100644 --- a/arch/arm/configs/multi_v5_defconfig +++ b/arch/arm/configs/multi_v5_defconfig @@ -29,8 +29,8 @@ CONFIG_MACH_MX27ADS=y CONFIG_MACH_MX27_3DS=y CONFIG_MACH_IMX27_VISSTRIM_M10=y CONFIG_MACH_PCA100=y -CONFIG_MACH_IMX27_DT=y CONFIG_SOC_IMX25=y +CONFIG_SOC_IMX27=y CONFIG_ARCH_MVEBU=y CONFIG_MACH_KIRKWOOD=y CONFIG_ARCH_ORION5X=y diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index e9e76e32f10f..e731cdf7c88c 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -43,10 +43,12 @@ CONFIG_SOC_IMX51=y CONFIG_SOC_IMX53=y CONFIG_SOC_IMX6Q=y CONFIG_SOC_IMX6SL=y +CONFIG_SOC_IMX6SLL=y CONFIG_SOC_IMX6SX=y CONFIG_SOC_IMX6UL=y CONFIG_SOC_LS1021A=y CONFIG_SOC_IMX7D=y +CONFIG_SOC_IMX7ULP=y CONFIG_SOC_VF610=y CONFIG_ARCH_KEYSTONE=y CONFIG_ARCH_MEDIATEK=y @@ -182,7 +184,7 @@ CONFIG_PCIEPORTBUS=y CONFIG_PCI_MVEBU=y CONFIG_PCI_TEGRA=y CONFIG_PCI_RCAR_GEN2=y -CONFIG_PCIE_RCAR=y +CONFIG_PCIE_RCAR_HOST=y CONFIG_PCI_DRA7XX_EP=y CONFIG_PCI_ENDPOINT=y CONFIG_PCI_ENDPOINT_CONFIGFS=y @@ -1011,6 +1013,7 @@ CONFIG_EXTCON_MAX14577=m CONFIG_EXTCON_MAX77693=m CONFIG_EXTCON_MAX8997=m CONFIG_TI_AEMIF=y +CONFIG_STM32_FMC2_EBI=y CONFIG_EXYNOS5422_DMC=m CONFIG_IIO=y CONFIG_IIO_SW_TRIGGER=y @@ -1121,6 +1124,7 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m CONFIG_CRYPTO_USER_API_RNG=m CONFIG_CRYPTO_USER_API_AEAD=m CONFIG_CRYPTO_DEV_SUN4I_SS=m +CONFIG_CRYPTO_DEV_FSL_CAAM=m CONFIG_CRYPTO_DEV_MARVELL_CESA=m CONFIG_CRYPTO_DEV_EXYNOS_RNG=m CONFIG_CRYPTO_DEV_S5P=m diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index fe383f5a92fb..34793aabdb65 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -95,7 +95,18 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y CONFIG_NETFILTER=y +CONFIG_BRIDGE=m +CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_VLAN_8021Q=m CONFIG_PHONET=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_CLS_FLOWER=m +CONFIG_NET_CLS_MATCHALL=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m CONFIG_NET_SWITCHDEV=y CONFIG_CAN=m CONFIG_CAN_C_CAN=m @@ -510,6 +521,7 @@ CONFIG_IIO_ST_ACCEL_3AXIS=m CONFIG_CPCAP_ADC=m CONFIG_INA2XX_ADC=m CONFIG_TI_AM335X_ADC=m +CONFIG_TWL4030_MADC=m CONFIG_SENSORS_ISL29028=m CONFIG_BMP280=m CONFIG_PWM=y diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig index 70e2c74a9f32..483c400dd391 100644 --- a/arch/arm/configs/realview_defconfig +++ b/arch/arm/configs/realview_defconfig @@ -5,9 +5,6 @@ CONFIG_HIGH_RES_TIMERS=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_PERF_EVENTS=y CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set CONFIG_ARCH_MULTI_V6=y CONFIG_ARCH_REALVIEW=y CONFIG_MACH_REALVIEW_EB=y @@ -20,11 +17,12 @@ CONFIG_MACH_REALVIEW_PB1176=y CONFIG_MACH_REALVIEW_PBA8=y CONFIG_MACH_REALVIEW_PBX=y CONFIG_SMP=y -CONFIG_CMA=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M" CONFIG_VFP=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_CMA=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -59,8 +57,12 @@ CONFIG_I2C_VERSATILE=y CONFIG_SPI=y CONFIG_GPIOLIB=y # CONFIG_HWMON is not set +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_DRM=y CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_DRM_DISPLAY_CONNECTOR=y +CONFIG_DRM_SIMPLE_BRIDGE=y CONFIG_DRM_PL111=y CONFIG_FB_MODE_HELPERS=y CONFIG_BACKLIGHT_CLASS_DEVICE=y @@ -78,6 +80,7 @@ CONFIG_MMC=y CONFIG_MMC_ARMMMCI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y +CONFIG_LEDS_SYSCON=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_CPU=y @@ -93,10 +96,9 @@ CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=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 CONFIG_DEBUG_USER=y -# CONFIG_CRYPTO_HW is not set diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index bbedc42bb2d9..4a161b3c35b9 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -37,7 +37,7 @@ CONFIG_CAN_RCAR=y CONFIG_PCI=y CONFIG_PCI_MSI=y CONFIG_PCI_RCAR_GEN2=y -CONFIG_PCIE_RCAR=y +CONFIG_PCIE_RCAR_HOST=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_SIMPLE_PM_BUS=y @@ -64,6 +64,7 @@ CONFIG_KEYBOARD_GPIO=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_EDT_FT5X06=y CONFIG_TOUCHSCREEN_ST1232=y +CONFIG_TOUCHSCREEN_STMPE=y CONFIG_INPUT_MISC=y CONFIG_INPUT_DA9063_ONKEY=y CONFIG_INPUT_ADXL34X=y @@ -104,6 +105,7 @@ CONFIG_RENESAS_WDT=y CONFIG_RENESAS_RZAWDT=y CONFIG_MFD_AS3711=y CONFIG_MFD_DA9063=y +CONFIG_MFD_STMPE=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_AS3711=y CONFIG_REGULATOR_DA9210=y @@ -134,7 +136,6 @@ CONFIG_DRM_SIMPLE_BRIDGE=y CONFIG_DRM_I2C_ADV7511=y CONFIG_DRM_I2C_ADV7511_AUDIO=y CONFIG_FB_SH_MOBILE_LCDC=y -# CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_PWM=y CONFIG_BACKLIGHT_AS3711=y CONFIG_SOUND=y diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig index 767935337413..e7ecfb365e91 100644 --- a/arch/arm/configs/versatile_defconfig +++ b/arch/arm/configs/versatile_defconfig @@ -9,8 +9,6 @@ CONFIG_SLAB=y CONFIG_ARCH_VERSATILE=y CONFIG_AEABI=y CONFIG_OABI_COMPAT=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="root=1f03 mem=32M" CONFIG_FPE_NWFPE=y CONFIG_VFP=y @@ -59,6 +57,7 @@ CONFIG_GPIO_PL061=y CONFIG_DRM=y CONFIG_DRM_PANEL_ARM_VERSATILE=y CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_DRM_DISPLAY_CONNECTOR=y CONFIG_DRM_SIMPLE_BRIDGE=y CONFIG_DRM_PL111=y CONFIG_FB_MODE_HELPERS=y @@ -91,8 +90,8 @@ CONFIG_NLS_CODEPAGE_850=m CONFIG_NLS_ISO8859_1=m CONFIG_FONTS=y CONFIG_FONT_ACORN_8x8=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_USER=y CONFIG_DEBUG_LL=y diff --git a/arch/arm/crypto/aes-neonbs-core.S b/arch/arm/crypto/aes-neonbs-core.S index cfaed4e67535..7d0cc7f226a5 100644 --- a/arch/arm/crypto/aes-neonbs-core.S +++ b/arch/arm/crypto/aes-neonbs-core.S @@ -77,11 +77,6 @@ vldr \out\()h, \sym + 8 .endm - .macro __adr, reg, lbl - adr \reg, \lbl -THUMB( orr \reg, \reg, #1 ) - .endm - .macro in_bs_ch, b0, b1, b2, b3, b4, b5, b6, b7 veor \b2, \b2, \b1 veor \b5, \b5, \b6 @@ -629,11 +624,11 @@ ENDPROC(aesbs_decrypt8) push {r4-r6, lr} ldr r5, [sp, #16] // number of blocks -99: __adr ip, 0f +99: adr ip, 0f and lr, r5, #7 cmp r5, #8 sub ip, ip, lr, lsl #2 - bxlt ip // computed goto if blocks < 8 + movlt pc, ip // computed goto if blocks < 8 vld1.8 {q0}, [r1]! vld1.8 {q1}, [r1]! @@ -648,11 +643,11 @@ ENDPROC(aesbs_decrypt8) mov rounds, r3 bl \do8 - __adr ip, 1f + adr ip, 1f and lr, r5, #7 cmp r5, #8 sub ip, ip, lr, lsl #2 - bxlt ip // computed goto if blocks < 8 + movlt pc, ip // computed goto if blocks < 8 vst1.8 {\o0}, [r0]! vst1.8 {\o1}, [r0]! @@ -689,12 +684,12 @@ ENTRY(aesbs_cbc_decrypt) push {r4-r6, lr} ldm ip, {r5-r6} // load args 4-5 -99: __adr ip, 0f +99: adr ip, 0f and lr, r5, #7 cmp r5, #8 sub ip, ip, lr, lsl #2 mov lr, r1 - bxlt ip // computed goto if blocks < 8 + movlt pc, ip // computed goto if blocks < 8 vld1.8 {q0}, [lr]! vld1.8 {q1}, [lr]! @@ -718,11 +713,11 @@ ENTRY(aesbs_cbc_decrypt) vmov q14, q8 vmov q15, q8 - __adr ip, 1f + adr ip, 1f and lr, r5, #7 cmp r5, #8 sub ip, ip, lr, lsl #2 - bxlt ip // computed goto if blocks < 8 + movlt pc, ip // computed goto if blocks < 8 vld1.8 {q9}, [r1]! vld1.8 {q10}, [r1]! @@ -733,9 +728,9 @@ ENTRY(aesbs_cbc_decrypt) vld1.8 {q15}, [r1]! W(nop) -1: __adr ip, 2f +1: adr ip, 2f sub ip, ip, lr, lsl #3 - bxlt ip // computed goto if blocks < 8 + movlt pc, ip // computed goto if blocks < 8 veor q0, q0, q8 vst1.8 {q0}, [r0]! @@ -804,13 +799,13 @@ ENTRY(aesbs_ctr_encrypt) vmov q6, q0 vmov q7, q0 - __adr ip, 0f + adr ip, 0f sub lr, r5, #1 and lr, lr, #7 cmp r5, #8 sub ip, ip, lr, lsl #5 sub ip, ip, lr, lsl #2 - bxlt ip // computed goto if blocks < 8 + movlt pc, ip // computed goto if blocks < 8 next_ctr q1 next_ctr q2 @@ -824,13 +819,13 @@ ENTRY(aesbs_ctr_encrypt) mov rounds, r3 bl aesbs_encrypt8 - __adr ip, 1f + adr ip, 1f and lr, r5, #7 cmp r5, #8 movgt r4, #0 ldrle r4, [sp, #40] // load final in the last round sub ip, ip, lr, lsl #2 - bxlt ip // computed goto if blocks < 8 + movlt pc, ip // computed goto if blocks < 8 vld1.8 {q8}, [r1]! vld1.8 {q9}, [r1]! @@ -843,10 +838,10 @@ ENTRY(aesbs_ctr_encrypt) 1: bne 2f vld1.8 {q15}, [r1]! -2: __adr ip, 3f +2: adr ip, 3f cmp r5, #8 sub ip, ip, lr, lsl #3 - bxlt ip // computed goto if blocks < 8 + movlt pc, ip // computed goto if blocks < 8 veor q0, q0, q8 vst1.8 {q0}, [r0]! @@ -900,12 +895,12 @@ __xts_prepare8: vshr.u64 d30, d31, #7 vmov q12, q14 - __adr ip, 0f + adr ip, 0f and r4, r6, #7 cmp r6, #8 sub ip, ip, r4, lsl #5 mov r4, sp - bxlt ip // computed goto if blocks < 8 + movlt pc, ip // computed goto if blocks < 8 vld1.8 {q0}, [r1]! next_tweak q12, q14, q15, q13 @@ -961,8 +956,7 @@ ENDPROC(__xts_prepare8) push {r4-r8, lr} mov r5, sp // preserve sp ldrd r6, r7, [sp, #24] // get blocks and iv args - ldr r8, [sp, #32] // reorder final tweak? - rsb r8, r8, #1 + rsb r8, ip, #1 sub ip, sp, #128 // make room for 8x tweak bic ip, ip, #0xf // align sp to 16 bytes mov sp, ip @@ -973,12 +967,12 @@ ENDPROC(__xts_prepare8) mov rounds, r3 bl \do8 - __adr ip, 0f + adr ip, 0f and lr, r6, #7 cmp r6, #8 sub ip, ip, lr, lsl #2 mov r4, sp - bxlt ip // computed goto if blocks < 8 + movlt pc, ip // computed goto if blocks < 8 vld1.8 {q8}, [r4, :128]! vld1.8 {q9}, [r4, :128]! @@ -989,9 +983,9 @@ ENDPROC(__xts_prepare8) vld1.8 {q14}, [r4, :128]! vld1.8 {q15}, [r4, :128] -0: __adr ip, 1f +0: adr ip, 1f sub ip, ip, lr, lsl #3 - bxlt ip // computed goto if blocks < 8 + movlt pc, ip // computed goto if blocks < 8 veor \o0, \o0, q8 vst1.8 {\o0}, [r0]! @@ -1018,9 +1012,11 @@ ENDPROC(__xts_prepare8) .endm ENTRY(aesbs_xts_encrypt) + mov ip, #0 // never reorder final tweak __xts_crypt aesbs_encrypt8, q0, q1, q4, q6, q3, q7, q2, q5 ENDPROC(aesbs_xts_encrypt) ENTRY(aesbs_xts_decrypt) + ldr ip, [sp, #8] // reorder final tweak? __xts_crypt aesbs_decrypt8, q0, q1, q6, q4, q2, q7, q3, q5 ENDPROC(aesbs_xts_decrypt) diff --git a/arch/arm/crypto/aes-neonbs-glue.c b/arch/arm/crypto/aes-neonbs-glue.c index e6fd32919c81..bda8bf17631e 100644 --- a/arch/arm/crypto/aes-neonbs-glue.c +++ b/arch/arm/crypto/aes-neonbs-glue.c @@ -8,7 +8,6 @@ #include <asm/neon.h> #include <asm/simd.h> #include <crypto/aes.h> -#include <crypto/cbc.h> #include <crypto/ctr.h> #include <crypto/internal/simd.h> #include <crypto/internal/skcipher.h> @@ -49,7 +48,7 @@ struct aesbs_ctx { struct aesbs_cbc_ctx { struct aesbs_ctx key; - struct crypto_cipher *enc_tfm; + struct crypto_skcipher *enc_tfm; }; struct aesbs_xts_ctx { @@ -140,19 +139,23 @@ static int aesbs_cbc_setkey(struct crypto_skcipher *tfm, const u8 *in_key, kernel_neon_end(); memzero_explicit(&rk, sizeof(rk)); - return crypto_cipher_setkey(ctx->enc_tfm, in_key, key_len); + return crypto_skcipher_setkey(ctx->enc_tfm, in_key, key_len); } -static void cbc_encrypt_one(struct crypto_skcipher *tfm, const u8 *src, u8 *dst) +static int cbc_encrypt(struct skcipher_request *req) { + struct skcipher_request *subreq = skcipher_request_ctx(req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm); - crypto_cipher_encrypt_one(ctx->enc_tfm, dst, src); -} + skcipher_request_set_tfm(subreq, ctx->enc_tfm); + skcipher_request_set_callback(subreq, + skcipher_request_flags(req), + NULL, NULL); + skcipher_request_set_crypt(subreq, req->src, req->dst, + req->cryptlen, req->iv); -static int cbc_encrypt(struct skcipher_request *req) -{ - return crypto_cbc_encrypt_walk(req, cbc_encrypt_one); + return crypto_skcipher_encrypt(subreq); } static int cbc_decrypt(struct skcipher_request *req) @@ -183,20 +186,27 @@ static int cbc_decrypt(struct skcipher_request *req) return err; } -static int cbc_init(struct crypto_tfm *tfm) +static int cbc_init(struct crypto_skcipher *tfm) { - struct aesbs_cbc_ctx *ctx = crypto_tfm_ctx(tfm); + struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm); + unsigned int reqsize; - ctx->enc_tfm = crypto_alloc_cipher("aes", 0, 0); + ctx->enc_tfm = crypto_alloc_skcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(ctx->enc_tfm)) + return PTR_ERR(ctx->enc_tfm); - return PTR_ERR_OR_ZERO(ctx->enc_tfm); + reqsize = sizeof(struct skcipher_request); + reqsize += crypto_skcipher_reqsize(ctx->enc_tfm); + crypto_skcipher_set_reqsize(tfm, reqsize); + + return 0; } -static void cbc_exit(struct crypto_tfm *tfm) +static void cbc_exit(struct crypto_skcipher *tfm) { - struct aesbs_cbc_ctx *ctx = crypto_tfm_ctx(tfm); + struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm); - crypto_free_cipher(ctx->enc_tfm); + crypto_free_skcipher(ctx->enc_tfm); } static int aesbs_ctr_setkey_sync(struct crypto_skcipher *tfm, const u8 *in_key, @@ -304,9 +314,9 @@ static int aesbs_xts_setkey(struct crypto_skcipher *tfm, const u8 *in_key, return aesbs_setkey(tfm, in_key, key_len); } -static int xts_init(struct crypto_tfm *tfm) +static int xts_init(struct crypto_skcipher *tfm) { - struct aesbs_xts_ctx *ctx = crypto_tfm_ctx(tfm); + struct aesbs_xts_ctx *ctx = crypto_skcipher_ctx(tfm); ctx->cts_tfm = crypto_alloc_cipher("aes", 0, 0); if (IS_ERR(ctx->cts_tfm)) @@ -319,9 +329,9 @@ static int xts_init(struct crypto_tfm *tfm) return PTR_ERR_OR_ZERO(ctx->tweak_tfm); } -static void xts_exit(struct crypto_tfm *tfm) +static void xts_exit(struct crypto_skcipher *tfm) { - struct aesbs_xts_ctx *ctx = crypto_tfm_ctx(tfm); + struct aesbs_xts_ctx *ctx = crypto_skcipher_ctx(tfm); crypto_free_cipher(ctx->tweak_tfm); crypto_free_cipher(ctx->cts_tfm); @@ -432,8 +442,6 @@ static struct skcipher_alg aes_algs[] = { { .base.cra_ctxsize = sizeof(struct aesbs_cbc_ctx), .base.cra_module = THIS_MODULE, .base.cra_flags = CRYPTO_ALG_INTERNAL, - .base.cra_init = cbc_init, - .base.cra_exit = cbc_exit, .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, @@ -442,6 +450,8 @@ static struct skcipher_alg aes_algs[] = { { .setkey = aesbs_cbc_setkey, .encrypt = cbc_encrypt, .decrypt = cbc_decrypt, + .init = cbc_init, + .exit = cbc_exit, }, { .base.cra_name = "__ctr(aes)", .base.cra_driver_name = "__ctr-aes-neonbs", @@ -483,8 +493,6 @@ static struct skcipher_alg aes_algs[] = { { .base.cra_ctxsize = sizeof(struct aesbs_xts_ctx), .base.cra_module = THIS_MODULE, .base.cra_flags = CRYPTO_ALG_INTERNAL, - .base.cra_init = xts_init, - .base.cra_exit = xts_exit, .min_keysize = 2 * AES_MIN_KEY_SIZE, .max_keysize = 2 * AES_MAX_KEY_SIZE, @@ -493,6 +501,8 @@ static struct skcipher_alg aes_algs[] = { { .setkey = aesbs_xts_setkey, .encrypt = xts_encrypt, .decrypt = xts_decrypt, + .init = xts_init, + .exit = xts_exit, } }; static struct simd_skcipher_alg *aes_simd_algs[ARRAY_SIZE(aes_algs)]; diff --git a/arch/arm/crypto/curve25519-glue.c b/arch/arm/crypto/curve25519-glue.c index 776ae07e0469..31eb75b6002f 100644 --- a/arch/arm/crypto/curve25519-glue.c +++ b/arch/arm/crypto/curve25519-glue.c @@ -16,6 +16,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/jump_label.h> +#include <linux/scatterlist.h> #include <crypto/curve25519.h> asmlinkage void curve25519_neon(u8 mypublic[CURVE25519_KEY_SIZE], diff --git a/arch/arm/crypto/poly1305-glue.c b/arch/arm/crypto/poly1305-glue.c index 13cfef4ae22e..3023c1acfa19 100644 --- a/arch/arm/crypto/poly1305-glue.c +++ b/arch/arm/crypto/poly1305-glue.c @@ -20,6 +20,7 @@ void poly1305_init_arm(void *state, const u8 *key); void poly1305_blocks_arm(void *state, const u8 *src, u32 len, u32 hibit); +void poly1305_blocks_neon(void *state, const u8 *src, u32 len, u32 hibit); void poly1305_emit_arm(void *state, u8 *digest, const u32 *nonce); void __weak poly1305_blocks_neon(void *state, const u8 *src, u32 len, u32 hibit) diff --git a/arch/arm/crypto/sha256-armv4.pl b/arch/arm/crypto/sha256-armv4.pl index 9f96ff48e4a8..f3a2b54efd4e 100644 --- a/arch/arm/crypto/sha256-armv4.pl +++ b/arch/arm/crypto/sha256-armv4.pl @@ -175,7 +175,6 @@ $code=<<___; #else .syntax unified # ifdef __thumb2__ -# define adrl adr .thumb # else .code 32 @@ -471,7 +470,8 @@ sha256_block_data_order_neon: stmdb sp!,{r4-r12,lr} sub $H,sp,#16*4+16 - adrl $Ktbl,K256 + adr $Ktbl,.Lsha256_block_data_order + sub $Ktbl,$Ktbl,#.Lsha256_block_data_order-K256 bic $H,$H,#15 @ align for 128-bit stores mov $t2,sp mov sp,$H @ alloca diff --git a/arch/arm/crypto/sha256-core.S_shipped b/arch/arm/crypto/sha256-core.S_shipped index ea04b2ab0c33..6363014a50d7 100644 --- a/arch/arm/crypto/sha256-core.S_shipped +++ b/arch/arm/crypto/sha256-core.S_shipped @@ -56,7 +56,6 @@ #else .syntax unified # ifdef __thumb2__ -# define adrl adr .thumb # else .code 32 @@ -1885,7 +1884,8 @@ sha256_block_data_order_neon: stmdb sp!,{r4-r12,lr} sub r11,sp,#16*4+16 - adrl r14,K256 + adr r14,.Lsha256_block_data_order + sub r14,r14,#.Lsha256_block_data_order-K256 bic r11,r11,#15 @ align for 128-bit stores mov r12,sp mov sp,r11 @ alloca diff --git a/arch/arm/crypto/sha512-armv4.pl b/arch/arm/crypto/sha512-armv4.pl index 69df68981acd..2fc3516912fa 100644 --- a/arch/arm/crypto/sha512-armv4.pl +++ b/arch/arm/crypto/sha512-armv4.pl @@ -212,7 +212,6 @@ $code=<<___; #else .syntax unified # ifdef __thumb2__ -# define adrl adr .thumb # else .code 32 @@ -602,7 +601,8 @@ sha512_block_data_order_neon: dmb @ errata #451034 on early Cortex A8 add $len,$inp,$len,lsl#7 @ len to point at the end of inp VFP_ABI_PUSH - adrl $Ktbl,K512 + adr $Ktbl,.Lsha512_block_data_order + sub $Ktbl,$Ktbl,.Lsha512_block_data_order-K512 vldmia $ctx,{$A-$H} @ load context .Loop_neon: ___ diff --git a/arch/arm/crypto/sha512-core.S_shipped b/arch/arm/crypto/sha512-core.S_shipped index cb147db5cbfe..03014624f2ab 100644 --- a/arch/arm/crypto/sha512-core.S_shipped +++ b/arch/arm/crypto/sha512-core.S_shipped @@ -79,7 +79,6 @@ #else .syntax unified # ifdef __thumb2__ -# define adrl adr .thumb # else .code 32 @@ -543,7 +542,8 @@ sha512_block_data_order_neon: dmb @ errata #451034 on early Cortex A8 add r2,r1,r2,lsl#7 @ len to point at the end of inp VFP_ABI_PUSH - adrl r3,K512 + adr r3,.Lsha512_block_data_order + sub r3,r3,.Lsha512_block_data_order-K512 vldmia r0,{d16-d23} @ load context .Loop_neon: vshr.u64 d24,d20,#14 @ 0 diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h index 1d65ed3a2755..e3ea34558ada 100644 --- a/arch/arm/include/asm/cache.h +++ b/arch/arm/include/asm/cache.h @@ -24,6 +24,6 @@ #define ARCH_SLAB_MINALIGN 8 #endif -#define __read_mostly __attribute__((__section__(".data..read_mostly"))) +#define __read_mostly __section(".data..read_mostly") #endif diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h index ed6073fee338..f0f54aef3724 100644 --- a/arch/arm/include/asm/checksum.h +++ b/arch/arm/include/asm/checksum.h @@ -35,23 +35,20 @@ __wsum csum_partial(const void *buff, int len, __wsum sum); */ __wsum -csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum); +csum_partial_copy_nocheck(const void *src, void *dst, int len); __wsum -csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr); +csum_partial_copy_from_user(const void __user *src, void *dst, int len); #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER +#define _HAVE_ARCH_CSUM_AND_COPY static inline -__wsum csum_and_copy_from_user (const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) +__wsum csum_and_copy_from_user(const void __user *src, void *dst, int len) { - if (access_ok(src, len)) - return csum_partial_copy_from_user(src, dst, len, sum, err_ptr); + if (!access_ok(src, len)) + return 0; - if (len) - *err_ptr = -EFAULT; - - return sum; + return csum_partial_copy_from_user(src, dst, len); } /* diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h index 6b2ff7243b4b..0d67ed682e07 100644 --- a/arch/arm/include/asm/cpuidle.h +++ b/arch/arm/include/asm/cpuidle.h @@ -42,7 +42,7 @@ struct of_cpuidle_method { #define CPUIDLE_METHOD_OF_DECLARE(name, _method, _ops) \ static const struct of_cpuidle_method __cpuidle_method_of_table_##name \ - __used __section(__cpuidle_method_of_table) \ + __used __section("__cpuidle_method_of_table") \ = { .method = _method, .ops = _ops } extern int arm_cpuidle_suspend(int index); diff --git a/arch/arm/include/asm/dma-contiguous.h b/arch/arm/include/asm/dma-contiguous.h deleted file mode 100644 index d785187a6f8a..000000000000 --- a/arch/arm/include/asm/dma-contiguous.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef ASMARM_DMA_CONTIGUOUS_H -#define ASMARM_DMA_CONTIGUOUS_H - -#ifdef __KERNEL__ -#ifdef CONFIG_DMA_CMA - -#include <linux/types.h> - -void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size); - -#endif -#endif - -#endif diff --git a/arch/arm/include/asm/dma-direct.h b/arch/arm/include/asm/dma-direct.h index 7c3001a6a775..77fcb7ee5ec9 100644 --- a/arch/arm/include/asm/dma-direct.h +++ b/arch/arm/include/asm/dma-direct.h @@ -2,13 +2,44 @@ #ifndef ASM_ARM_DMA_DIRECT_H #define ASM_ARM_DMA_DIRECT_H 1 -static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +#include <asm/memory.h> + +/* + * dma_to_pfn/pfn_to_dma/virt_to_dma are architecture private + * functions used internally by the DMA-mapping API to provide DMA + * addresses. They must not be used by drivers. + */ +static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn) +{ + if (dev && dev->dma_range_map) + pfn = PFN_DOWN(translate_phys_to_dma(dev, PFN_PHYS(pfn))); + return (dma_addr_t)__pfn_to_bus(pfn); +} + +static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr) +{ + unsigned long pfn = __bus_to_pfn(addr); + + if (dev && dev->dma_range_map) + pfn = PFN_DOWN(translate_dma_to_phys(dev, PFN_PHYS(pfn))); + return pfn; +} + +static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) +{ + if (dev) + return pfn_to_dma(dev, virt_to_pfn(addr)); + + return (dma_addr_t)__virt_to_bus((unsigned long)(addr)); +} + +static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { unsigned int offset = paddr & ~PAGE_MASK; return pfn_to_dma(dev, __phys_to_pfn(paddr)) + offset; } -static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dev_addr) +static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr) { unsigned int offset = dev_addr & ~PAGE_MASK; return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset; diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h index 86405cc81385..fe9ef6f79e9c 100644 --- a/arch/arm/include/asm/dma-iommu.h +++ b/arch/arm/include/asm/dma-iommu.h @@ -6,7 +6,6 @@ #include <linux/mm_types.h> #include <linux/scatterlist.h> -#include <linux/dma-debug.h> #include <linux/kref.h> struct dma_iommu_mapping { diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index bdd80ddbca34..77082246a5e1 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -6,9 +6,6 @@ #include <linux/mm_types.h> #include <linux/scatterlist.h> -#include <linux/dma-debug.h> - -#include <asm/memory.h> #include <xen/xen.h> #include <asm/xen/hypervisor.h> @@ -23,74 +20,6 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) return NULL; } -#ifdef __arch_page_to_dma -#error Please update to __arch_pfn_to_dma -#endif - -/* - * dma_to_pfn/pfn_to_dma/dma_to_virt/virt_to_dma are architecture private - * functions used internally by the DMA-mapping API to provide DMA - * addresses. They must not be used by drivers. - */ -#ifndef __arch_pfn_to_dma -static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn) -{ - if (dev) - pfn -= dev->dma_pfn_offset; - return (dma_addr_t)__pfn_to_bus(pfn); -} - -static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr) -{ - unsigned long pfn = __bus_to_pfn(addr); - - if (dev) - pfn += dev->dma_pfn_offset; - - return pfn; -} - -static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) -{ - if (dev) { - unsigned long pfn = dma_to_pfn(dev, addr); - - return phys_to_virt(__pfn_to_phys(pfn)); - } - - return (void *)__bus_to_virt((unsigned long)addr); -} - -static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) -{ - if (dev) - return pfn_to_dma(dev, virt_to_pfn(addr)); - - return (dma_addr_t)__virt_to_bus((unsigned long)(addr)); -} - -#else -static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn) -{ - return __arch_pfn_to_dma(dev, pfn); -} - -static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr) -{ - return __arch_dma_to_pfn(dev, addr); -} - -static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) -{ - return __arch_dma_to_virt(dev, addr); -} - -static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) -{ - return __arch_virt_to_dma(dev, addr); -} -#endif - /** * arm_dma_alloc - allocate consistent memory for DMA * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h index 5dcf3c6011b7..3ee4f4381985 100644 --- a/arch/arm/include/asm/efi.h +++ b/arch/arm/include/asm/efi.h @@ -66,25 +66,24 @@ static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) #define MAX_UNCOMP_KERNEL_SIZE SZ_32M /* - * The kernel zImage should preferably be located between 32 MB and 128 MB - * from the base of DRAM. The min address leaves space for a maximal size - * uncompressed image, and the max address is due to how the zImage decompressor - * picks a destination address. + * 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. */ -#define ZIMAGE_OFFSET_LIMIT SZ_128M -#define MIN_ZIMAGE_OFFSET MAX_UNCOMP_KERNEL_SIZE +#define EFI_PHYS_ALIGN SZ_16M -/* on ARM, the FDT should be located in the first 128 MB of RAM */ -static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base) +/* 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 dram_base + ZIMAGE_OFFSET_LIMIT; + return round_down(image_addr, EFI_PHYS_ALIGN) + SZ_512M; } /* on ARM, the initrd should be loaded in a lowmem region */ -static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, - unsigned long image_addr) +static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr) { - return dram_base + SZ_512M; + return round_down(image_addr, EFI_PHYS_ALIGN) + SZ_512M; } struct efi_arm_entry_state { diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h index 7a88f160b1fb..b95848ed2bc7 100644 --- a/arch/arm/include/asm/hardirq.h +++ b/arch/arm/include/asm/hardirq.h @@ -6,29 +6,12 @@ #include <linux/threads.h> #include <asm/irq.h> -/* number of IPIS _not_ including IPI_CPU_BACKTRACE */ -#define NR_IPI 7 - typedef struct { unsigned int __softirq_pending; -#ifdef CONFIG_SMP - unsigned int ipi_irqs[NR_IPI]; -#endif } ____cacheline_aligned irq_cpustat_t; #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -#define __inc_irq_stat(cpu, member) __IRQ_STAT(cpu, member)++ -#define __get_irq_stat(cpu, member) __IRQ_STAT(cpu, member) - -#ifdef CONFIG_SMP -u64 smp_irq_stat_cpu(unsigned int cpu); -#else -#define smp_irq_stat_cpu(cpu) 0 -#endif - -#define arch_irq_stat_cpu smp_irq_stat_cpu - #define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 #endif /* __ASM_HARDIRQ_H */ diff --git a/arch/arm/include/asm/idmap.h b/arch/arm/include/asm/idmap.h index aab7e8358e6a..baebb67b3512 100644 --- a/arch/arm/include/asm/idmap.h +++ b/arch/arm/include/asm/idmap.h @@ -6,7 +6,7 @@ #include <linux/pgtable.h> /* Tag a function as requiring to be executed via an identity mapping. */ -#define __idmap __section(.idmap.text) noinline notrace +#define __idmap __section(".idmap.text") noinline notrace extern pgd_t *idmap_pgd; diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index e7df5a822cab..eec0c0bda766 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -81,7 +81,7 @@ extern const struct machine_desc __arch_info_begin[], __arch_info_end[]; #define MACHINE_START(_type,_name) \ static const struct machine_desc __mach_desc_##_type \ __used \ - __attribute__((__section__(".arch.info.init"))) = { \ + __section(".arch.info.init") = { \ .nr = MACH_TYPE_##_type, \ .name = _name, @@ -91,7 +91,7 @@ static const struct machine_desc __mach_desc_##_type \ #define DT_MACHINE_START(_name, _namestr) \ static const struct machine_desc __mach_desc_##_name \ __used \ - __attribute__((__section__(".arch.info.init"))) = { \ + __section(".arch.info.init") = { \ .nr = ~0, \ .name = _namestr, diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h index 83d340702680..ea9bd08895b7 100644 --- a/arch/arm/include/asm/mach/pci.h +++ b/arch/arm/include/asm/mach/pci.h @@ -17,10 +17,8 @@ struct pci_host_bridge; struct device; struct hw_pci { - struct msi_controller *msi_ctrl; struct pci_ops *ops; int nr_controllers; - unsigned int io_optional:1; void **private_data; int (*setup)(int nr, struct pci_sys_data *); int (*scan)(int nr, struct pci_host_bridge *); @@ -28,11 +26,6 @@ struct hw_pci { void (*postinit)(void); u8 (*swizzle)(struct pci_dev *dev, u8 *pin); int (*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); - resource_size_t (*align_resource)(struct pci_dev *dev, - const struct resource *res, - resource_size_t start, - resource_size_t size, - resource_size_t align); }; /* diff --git a/arch/arm/kernel/module.lds b/arch/arm/include/asm/module.lds.h index 79cb6af565e5..0e7cb4e314b4 100644 --- a/arch/arm/kernel/module.lds +++ b/arch/arm/include/asm/module.lds.h @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ +#ifdef CONFIG_ARM_MODULE_PLTS SECTIONS { .plt : { BYTE(0) } .init.plt : { BYTE(0) } } +#endif diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index 67d20712cb48..3ae68a1b3de6 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h @@ -14,7 +14,7 @@ #include <uapi/asm/setup.h> -#define __tag __used __attribute__((__section__(".taglist.init"))) +#define __tag __used __section(".taglist.init") #define __tagtable(tag, fn) \ static const struct tagtable __tagtable_##fn __tag = { tag, fn } diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index a91f21e3c5b5..5d508f5d56c4 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h @@ -39,11 +39,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs); */ extern void smp_init_cpus(void); - /* - * Provide a function to raise an IPI cross call on CPUs in callmap. + * Register IPI interrupts with the arch SMP code */ -extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int)); +extern void set_smp_ipi_range(int ipi_base, int nr_ipi); /* * Called from platform specific assembly code, this is the @@ -113,7 +112,7 @@ struct of_cpu_method { #define CPU_METHOD_OF_DECLARE(name, _method, _ops) \ static const struct of_cpu_method __cpu_method_of_table_##name \ - __used __section(__cpu_method_of_table) \ + __used __section("__cpu_method_of_table") \ = { .method = _method, .ops = _ops } /* * set platform specific SMP operations diff --git a/arch/arm/include/asm/tcm.h b/arch/arm/include/asm/tcm.h index b845b10fe29a..d8bd8a4b0ede 100644 --- a/arch/arm/include/asm/tcm.h +++ b/arch/arm/include/asm/tcm.h @@ -16,13 +16,13 @@ #include <linux/compiler.h> /* Tag variables with this */ -#define __tcmdata __section(.tcm.data) +#define __tcmdata __section(".tcm.data") /* Tag constants with this */ -#define __tcmconst __section(.tcm.rodata) +#define __tcmconst __section(".tcm.rodata") /* Tag functions inside TCM called from outside TCM with this */ -#define __tcmfunc __attribute__((long_call)) __section(.tcm.text) noinline +#define __tcmfunc __attribute__((long_call)) __section(".tcm.text") noinline /* Tag function inside TCM called from inside TCM with this */ -#define __tcmlocalfunc __section(.tcm.text) +#define __tcmlocalfunc __section(".tcm.text") void *tcm_alloc(size_t len); void tcm_free(void *addr, size_t len); diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h index 9415222b49ad..b8cbe03ad260 100644 --- a/arch/arm/include/asm/tlb.h +++ b/arch/arm/include/asm/tlb.h @@ -59,6 +59,7 @@ __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr) #ifdef CONFIG_ARM_LPAE struct page *page = virt_to_page(pmdp); + pgtable_pmd_page_dtor(page); tlb_remove_table(tlb, page); #endif } diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h index e0593cf095d0..470299ee2fba 100644 --- a/arch/arm/include/asm/topology.h +++ b/arch/arm/include/asm/topology.h @@ -7,8 +7,13 @@ #include <linux/cpumask.h> #include <linux/arch_topology.h> +/* big.LITTLE switcher is incompatible with frequency invariance */ +#ifndef CONFIG_BL_SWITCHER /* Replace task scheduler's default frequency-invariant accounting */ +#define arch_set_freq_scale topology_set_freq_scale #define arch_scale_freq_capacity topology_get_freq_scale +#define arch_scale_freq_invariant topology_scale_freq_invariant +#endif /* Replace task scheduler's default cpu-invariant accounting */ #define arch_scale_cpu_capacity topology_get_cpu_scale diff --git a/arch/arm/kernel/vmlinux.lds.h b/arch/arm/include/asm/vmlinux.lds.h index 381a8e105fa5..4a91428c324d 100644 --- a/arch/arm/kernel/vmlinux.lds.h +++ b/arch/arm/include/asm/vmlinux.lds.h @@ -1,4 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ +#include <asm-generic/vmlinux.lds.h> #ifdef CONFIG_HOTPLUG_CPU #define ARM_CPU_DISCARD(x) @@ -49,8 +50,29 @@ EXIT_CALL \ ARM_MMU_DISCARD(*(.text.fixup)) \ ARM_MMU_DISCARD(*(__ex_table)) \ - *(.discard) \ - *(.discard.*) + COMMON_DISCARDS + +/* + * Sections that should stay zero sized, which is safer to explicitly + * check instead of blindly discarding. + */ +#define ARM_ASSERTS \ + .plt : { \ + *(.iplt) *(.rel.iplt) *(.iplt) *(.igot.plt) \ + } \ + ASSERT(SIZEOF(.plt) == 0, \ + "Unexpected run-time procedure linkages detected!") + +#define ARM_DETAILS \ + ELF_DETAILS \ + .ARM.attributes 0 : { *(.ARM.attributes) } + +#define ARM_STUBS_TEXT \ + *(.gnu.warning) \ + *(.glue_7) \ + *(.glue_7t) \ + *(.vfp11_veneer) \ + *(.v4_bx) #define ARM_TEXT \ IDMAP_TEXT \ @@ -64,9 +86,7 @@ CPUIDLE_TEXT \ LOCK_TEXT \ KPROBES_TEXT \ - *(.gnu.warning) \ - *(.glue_7) \ - *(.glue_7t) \ + ARM_STUBS_TEXT \ . = ALIGN(4); \ *(.got) /* Global offset table */ \ ARM_CPU_KEEP(PROC_INFO) diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h index 31bbc803cecb..dc7f6e91aafa 100644 --- a/arch/arm/include/asm/xen/page.h +++ b/arch/arm/include/asm/xen/page.h @@ -1 +1,6 @@ #include <xen/arm/page.h> + +static inline bool xen_kernel_unmapped_at_usr(void) +{ + return false; +} diff --git a/arch/arm/include/debug/8250.S b/arch/arm/include/debug/8250.S index e4a036f082c2..e3692a37cede 100644 --- a/arch/arm/include/debug/8250.S +++ b/arch/arm/include/debug/8250.S @@ -45,10 +45,11 @@ bne 1002b .endm - .macro waituart,rd,rx -#ifdef CONFIG_DEBUG_UART_8250_FLOW_CONTROL + .macro waituarttxrdy,rd,rx + .endm + + .macro waituartcts,rd,rx 1001: load \rd, [\rx, #UART_MSR << UART_SHIFT] tst \rd, #UART_MSR_CTS beq 1001b -#endif .endm diff --git a/arch/arm/include/debug/asm9260.S b/arch/arm/include/debug/asm9260.S index 0da1eb625331..5a0ce145c44a 100644 --- a/arch/arm/include/debug/asm9260.S +++ b/arch/arm/include/debug/asm9260.S @@ -11,7 +11,10 @@ ldr \rv, = CONFIG_DEBUG_UART_VIRT .endm - .macro waituart,rd,rx + .macro waituarttxrdy,rd,rx + .endm + + .macro waituartcts,rd,rx .endm .macro senduart,rd,rx diff --git a/arch/arm/include/debug/at91.S b/arch/arm/include/debug/at91.S index 6c91cbaaa20b..17722824e2f2 100644 --- a/arch/arm/include/debug/at91.S +++ b/arch/arm/include/debug/at91.S @@ -19,12 +19,15 @@ strb \rd, [\rx, #(AT91_DBGU_THR)] @ Write to Transmitter Holding Register .endm - .macro waituart,rd,rx + .macro waituarttxrdy,rd,rx 1001: ldr \rd, [\rx, #(AT91_DBGU_SR)] @ Read Status Register tst \rd, #AT91_DBGU_TXRDY @ DBGU_TXRDY = 1 when ready to transmit beq 1001b .endm + .macro waituartcts,rd,rx + .endm + .macro busyuart,rd,rx 1001: ldr \rd, [\rx, #(AT91_DBGU_SR)] @ Read Status Register tst \rd, #AT91_DBGU_TXEMPTY @ DBGU_TXEMPTY = 1 when transmission complete diff --git a/arch/arm/include/debug/bcm63xx.S b/arch/arm/include/debug/bcm63xx.S index 06a896227396..da65abb6738d 100644 --- a/arch/arm/include/debug/bcm63xx.S +++ b/arch/arm/include/debug/bcm63xx.S @@ -17,12 +17,15 @@ strb \rd, [\rx, #UART_FIFO_REG] .endm - .macro waituart, rd, rx + .macro waituarttxrdy, rd, rx 1001: ldr \rd, [\rx, #UART_IR_REG] tst \rd, #(1 << UART_IR_TXEMPTY) beq 1001b .endm + .macro waituartcts, rd, rx + .endm + .macro busyuart, rd, rx 1002: ldr \rd, [\rx, #UART_IR_REG] tst \rd, #(1 << UART_IR_TXTRESH) diff --git a/arch/arm/include/debug/brcmstb.S b/arch/arm/include/debug/brcmstb.S index 132a20c4a676..0ff32ffc610c 100644 --- a/arch/arm/include/debug/brcmstb.S +++ b/arch/arm/include/debug/brcmstb.S @@ -32,6 +32,8 @@ #define UARTA_7271 UARTA_7268 #define UARTA_7278 REG_PHYS_ADDR_V7(0x40c000) #define UARTA_7216 UARTA_7278 +#define UARTA_72164 UARTA_7278 +#define UARTA_72165 UARTA_7278 #define UARTA_7364 REG_PHYS_ADDR(0x40b000) #define UARTA_7366 UARTA_7364 #define UARTA_74371 REG_PHYS_ADDR(0x406b00) @@ -84,17 +86,19 @@ ARM_BE8( rev \rv, \rv ) /* Chip specific detection starts here */ 20: checkuart(\rp, \rv, 0x33900000, 3390) 21: checkuart(\rp, \rv, 0x72160000, 7216) -22: checkuart(\rp, \rv, 0x72500000, 7250) -23: checkuart(\rp, \rv, 0x72550000, 7255) -24: checkuart(\rp, \rv, 0x72600000, 7260) -25: checkuart(\rp, \rv, 0x72680000, 7268) -26: checkuart(\rp, \rv, 0x72710000, 7271) -27: checkuart(\rp, \rv, 0x72780000, 7278) -28: checkuart(\rp, \rv, 0x73640000, 7364) -29: checkuart(\rp, \rv, 0x73660000, 7366) -30: checkuart(\rp, \rv, 0x07437100, 74371) -31: checkuart(\rp, \rv, 0x74390000, 7439) -32: checkuart(\rp, \rv, 0x74450000, 7445) +22: checkuart(\rp, \rv, 0x07216400, 72164) +23: checkuart(\rp, \rv, 0x07216500, 72165) +24: checkuart(\rp, \rv, 0x72500000, 7250) +25: checkuart(\rp, \rv, 0x72550000, 7255) +26: checkuart(\rp, \rv, 0x72600000, 7260) +27: checkuart(\rp, \rv, 0x72680000, 7268) +28: checkuart(\rp, \rv, 0x72710000, 7271) +29: checkuart(\rp, \rv, 0x72780000, 7278) +30: checkuart(\rp, \rv, 0x73640000, 7364) +31: checkuart(\rp, \rv, 0x73660000, 7366) +32: checkuart(\rp, \rv, 0x07437100, 74371) +33: checkuart(\rp, \rv, 0x74390000, 7439) +34: checkuart(\rp, \rv, 0x74450000, 7445) /* No valid UART found */ 90: mov \rp, #0 @@ -142,7 +146,10 @@ ARM_BE8( rev \rd, \rd ) bne 1002b .endm - .macro waituart,rd,rx + .macro waituarttxrdy,rd,rx + .endm + + .macro waituartcts,rd,rx .endm /* diff --git a/arch/arm/include/debug/clps711x.S b/arch/arm/include/debug/clps711x.S index 774a67ac3877..a983d12a6515 100644 --- a/arch/arm/include/debug/clps711x.S +++ b/arch/arm/include/debug/clps711x.S @@ -20,7 +20,10 @@ ldr \rp, =CLPS711X_UART_PADDR .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx .endm .macro senduart,rd,rx diff --git a/arch/arm/include/debug/dc21285.S b/arch/arm/include/debug/dc21285.S index d7e8c71706ab..4ec0e5e31704 100644 --- a/arch/arm/include/debug/dc21285.S +++ b/arch/arm/include/debug/dc21285.S @@ -34,5 +34,8 @@ bne 1001b .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx .endm diff --git a/arch/arm/include/debug/digicolor.S b/arch/arm/include/debug/digicolor.S index 256f5f4da275..443674cad76a 100644 --- a/arch/arm/include/debug/digicolor.S +++ b/arch/arm/include/debug/digicolor.S @@ -21,7 +21,10 @@ strb \rd, [\rx, #UA0_EMI_REC] .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx .endm .macro busyuart,rd,rx diff --git a/arch/arm/include/debug/efm32.S b/arch/arm/include/debug/efm32.S index 5ed5028306f4..b0083d6e31e8 100644 --- a/arch/arm/include/debug/efm32.S +++ b/arch/arm/include/debug/efm32.S @@ -29,7 +29,10 @@ strb \rd, [\rx, #UARTn_TXDATA] .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx 1001: ldr \rd, [\rx, #UARTn_STATUS] tst \rd, #UARTn_STATUS_TXBL beq 1001b diff --git a/arch/arm/include/debug/icedcc.S b/arch/arm/include/debug/icedcc.S index 74a0dd036a17..d5e65da8a687 100644 --- a/arch/arm/include/debug/icedcc.S +++ b/arch/arm/include/debug/icedcc.S @@ -23,7 +23,10 @@ beq 1001b .endm - .macro waituart, rd, rx + .macro waituartcts, rd, rx + .endm + + .macro waituarttxrdy, rd, rx mov \rd, #0x2000000 1001: subs \rd, \rd, #1 @@ -47,7 +50,10 @@ beq 1001b .endm - .macro waituart, rd, rx + .macro waituartcts, rd, rx + .endm + + .macro waituarttxrdy, rd, rx mov \rd, #0x10000000 1001: subs \rd, \rd, #1 @@ -72,7 +78,10 @@ .endm - .macro waituart, rd, rx + .macro waituartcts, rd, rx + .endm + + .macro waituarttxrdy, rd, rx mov \rd, #0x2000000 1001: subs \rd, \rd, #1 diff --git a/arch/arm/include/debug/imx.S b/arch/arm/include/debug/imx.S index 1c1b9d1da4c8..bb7b9550580c 100644 --- a/arch/arm/include/debug/imx.S +++ b/arch/arm/include/debug/imx.S @@ -35,7 +35,10 @@ str \rd, [\rx, #0x40] @ TXDATA .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx .endm .macro busyuart,rd,rx diff --git a/arch/arm/include/debug/meson.S b/arch/arm/include/debug/meson.S index 1e501a0054ae..7b60e4401225 100644 --- a/arch/arm/include/debug/meson.S +++ b/arch/arm/include/debug/meson.S @@ -25,7 +25,10 @@ beq 1002b .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx 1001: ldr \rd, [\rx, #MESON_AO_UART_STATUS] tst \rd, #MESON_AO_UART_TX_FIFO_FULL bne 1001b diff --git a/arch/arm/include/debug/msm.S b/arch/arm/include/debug/msm.S index 9405b71461da..530edc74f9a3 100644 --- a/arch/arm/include/debug/msm.S +++ b/arch/arm/include/debug/msm.S @@ -17,7 +17,10 @@ ARM_BE8(rev \rd, \rd ) str \rd, [\rx, #0x70] .endm - .macro waituart, rd, rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy, rd, rx @ check for TX_EMT in UARTDM_SR ldr \rd, [\rx, #0x08] ARM_BE8(rev \rd, \rd ) diff --git a/arch/arm/include/debug/omap2plus.S b/arch/arm/include/debug/omap2plus.S index b5696a33ba0f..0680be6c79d3 100644 --- a/arch/arm/include/debug/omap2plus.S +++ b/arch/arm/include/debug/omap2plus.S @@ -75,5 +75,8 @@ omap_uart_lsr: .word 0 bne 1001b .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx .endm diff --git a/arch/arm/include/debug/pl01x.S b/arch/arm/include/debug/pl01x.S index a2a553afe7b8..0c7bfa4c10db 100644 --- a/arch/arm/include/debug/pl01x.S +++ b/arch/arm/include/debug/pl01x.S @@ -26,7 +26,10 @@ strb \rd, [\rx, #UART01x_DR] .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx 1001: ldr \rd, [\rx, #UART01x_FR] ARM_BE8( rev \rd, \rd ) tst \rd, #UART01x_FR_TXFF diff --git a/arch/arm/include/debug/renesas-scif.S b/arch/arm/include/debug/renesas-scif.S index 25f06663a9a4..8e433e981bbe 100644 --- a/arch/arm/include/debug/renesas-scif.S +++ b/arch/arm/include/debug/renesas-scif.S @@ -33,7 +33,10 @@ ldr \rv, =SCIF_VIRT .endm - .macro waituart, rd, rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy, rd, rx 1001: ldrh \rd, [\rx, #FSR] tst \rd, #TDFE beq 1001b diff --git a/arch/arm/include/debug/sa1100.S b/arch/arm/include/debug/sa1100.S index 6109e6058e5b..7968ea52df3d 100644 --- a/arch/arm/include/debug/sa1100.S +++ b/arch/arm/include/debug/sa1100.S @@ -51,7 +51,10 @@ str \rd, [\rx, #UTDR] .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx 1001: ldr \rd, [\rx, #UTSR1] tst \rd, #UTSR1_TNF beq 1001b diff --git a/arch/arm/include/debug/samsung.S b/arch/arm/include/debug/samsung.S index 69201d7fb48f..ab474d564a90 100644 --- a/arch/arm/include/debug/samsung.S +++ b/arch/arm/include/debug/samsung.S @@ -69,7 +69,10 @@ ARM_BE8(rev \rd, \rd) 1002: @ exit busyuart .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx ldr \rd, [\rx, # S3C2410_UFCON] ARM_BE8(rev \rd, \rd) tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled? diff --git a/arch/arm/include/debug/sirf.S b/arch/arm/include/debug/sirf.S index e73e4de0a015..3612c7b9cbe7 100644 --- a/arch/arm/include/debug/sirf.S +++ b/arch/arm/include/debug/sirf.S @@ -29,7 +29,10 @@ .macro busyuart,rd,rx .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx 1001: ldr \rd, [\rx, #SIRF_LLUART_TXFIFO_STATUS] tst \rd, #SIRF_LLUART_TXFIFO_EMPTY beq 1001b diff --git a/arch/arm/include/debug/sti.S b/arch/arm/include/debug/sti.S index 6b42c91f217d..72d052511890 100644 --- a/arch/arm/include/debug/sti.S +++ b/arch/arm/include/debug/sti.S @@ -45,7 +45,10 @@ strb \rd, [\rx, #ASC_TX_BUF_OFF] .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx 1001: ldr \rd, [\rx, #ASC_STA_OFF] tst \rd, #ASC_STA_TX_FULL bne 1001b diff --git a/arch/arm/include/debug/stm32.S b/arch/arm/include/debug/stm32.S index f3c4a37210ed..b6d9df30e37d 100644 --- a/arch/arm/include/debug/stm32.S +++ b/arch/arm/include/debug/stm32.S @@ -27,7 +27,10 @@ strb \rd, [\rx, #STM32_USART_TDR_OFF] .endm -.macro waituart,rd,rx +.macro waituartcts,rd,rx +.endm + +.macro waituarttxrdy,rd,rx 1001: ldr \rd, [\rx, #(STM32_USART_SR_OFF)] @ Read Status Register tst \rd, #STM32_USART_TXE @ TXE = 1 = tx empty beq 1001b diff --git a/arch/arm/include/debug/tegra.S b/arch/arm/include/debug/tegra.S index 2148d0f88591..98daa7f48314 100644 --- a/arch/arm/include/debug/tegra.S +++ b/arch/arm/include/debug/tegra.S @@ -178,15 +178,16 @@ 1002: .endm - .macro waituart, rd, rx -#ifdef FLOW_CONTROL + .macro waituartcts, rd, rx cmp \rx, #0 beq 1002f 1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT] tst \rd, #UART_MSR_CTS beq 1001b 1002: -#endif + .endm + + .macro waituarttxrdy,rd,rx .endm /* diff --git a/arch/arm/include/debug/vf.S b/arch/arm/include/debug/vf.S index 854d9bd82770..035bcbf117ab 100644 --- a/arch/arm/include/debug/vf.S +++ b/arch/arm/include/debug/vf.S @@ -29,5 +29,8 @@ beq 1001b @ wait until transmit done .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx .endm diff --git a/arch/arm/include/debug/vt8500.S b/arch/arm/include/debug/vt8500.S index 8dc1df2d91b8..d01094fdbc8c 100644 --- a/arch/arm/include/debug/vt8500.S +++ b/arch/arm/include/debug/vt8500.S @@ -28,7 +28,10 @@ bne 1001b .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx .endm #endif diff --git a/arch/arm/include/debug/zynq.S b/arch/arm/include/debug/zynq.S index 58d77c972fd6..5d42cc35ecf3 100644 --- a/arch/arm/include/debug/zynq.S +++ b/arch/arm/include/debug/zynq.S @@ -33,7 +33,10 @@ strb \rd, [\rx, #UART_FIFO_OFFSET] @ TXDATA .endm - .macro waituart,rd,rx + .macro waituartcts,rd,rx + .endm + + .macro waituarttxrdy,rd,rx 1001: ldr \rd, [\rx, #UART_SR_OFFSET] ARM_BE8( rev \rd, \rd ) tst \rd, #UART_SR_TXEMPTY diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index eecec16aa708..e7ef2b5bea9c 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -394,8 +394,7 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return irq; } -static int pcibios_init_resource(int busnr, struct pci_sys_data *sys, - int io_optional) +static int pcibios_init_resource(int busnr, struct pci_sys_data *sys) { int ret; struct resource_entry *window; @@ -405,14 +404,6 @@ static int pcibios_init_resource(int busnr, struct pci_sys_data *sys, &iomem_resource, sys->mem_offset); } - /* - * If a platform says I/O port support is optional, we don't add - * the default I/O space. The platform is responsible for adding - * any I/O space it needs. - */ - if (io_optional) - return 0; - resource_list_for_each_entry(window, &sys->resources) if (resource_type(window->res) == IORESOURCE_IO) return 0; @@ -462,7 +453,7 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, if (ret > 0) { - ret = pcibios_init_resource(nr, sys, hw->io_optional); + ret = pcibios_init_resource(nr, sys); if (ret) { pci_free_host_bridge(bridge); break; @@ -480,9 +471,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, bridge->sysdata = sys; bridge->busnr = sys->busnr; bridge->ops = hw->ops; - bridge->msi = hw->msi_ctrl; - bridge->align_resource = - hw->align_resource; ret = pci_scan_root_bus_bridge(bridge); } diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c index 093368e0d020..e1684623e1b2 100644 --- a/arch/arm/kernel/cpuidle.c +++ b/arch/arm/kernel/cpuidle.c @@ -11,7 +11,7 @@ extern struct of_cpuidle_method __cpuidle_method_of_table[]; static const struct of_cpuidle_method __cpuidle_method_of_table_sentinel - __used __section(__cpuidle_method_of_table_end); + __used __section("__cpuidle_method_of_table_end"); static struct cpuidle_ops cpuidle_ops[NR_CPUS] __ro_after_init; diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index e112072b579d..d92f44bdf438 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -89,11 +89,18 @@ ENTRY(printascii) 2: teq r1, #'\n' bne 3f mov r1, #'\r' - waituart r2, r3 +#ifdef CONFIG_DEBUG_UART_FLOW_CONTROL + waituartcts r2, r3 +#endif + waituarttxrdy r2, r3 senduart r1, r3 busyuart r2, r3 mov r1, #'\n' -3: waituart r2, r3 +3: +#ifdef CONFIG_DEBUG_UART_FLOW_CONTROL + waituartcts r2, r3 +#endif + waituarttxrdy r2, r3 senduart r1, r3 busyuart r2, r3 b 1b diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 39c978698406..7f0745a97e20 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -29,7 +29,7 @@ extern struct of_cpu_method __cpu_method_of_table[]; static const struct of_cpu_method __cpu_method_of_table_sentinel - __used __section(__cpu_method_of_table_end); + __used __section("__cpu_method_of_table_end"); static int __init set_smp_ops_by_method(struct device_node *node) diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 7a4853b1213a..08660ae9dcbc 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -683,6 +683,40 @@ static void disable_single_step(struct perf_event *bp) arch_install_hw_breakpoint(bp); } +/* + * Arm32 hardware does not always report a watchpoint hit address that matches + * one of the watchpoints set. It can also report an address "near" the + * watchpoint if a single instruction access both watched and unwatched + * addresses. There is no straight-forward way, short of disassembling the + * offending instruction, to map that address back to the watchpoint. This + * function computes the distance of the memory access from the watchpoint as a + * heuristic for the likelyhood that a given access triggered the watchpoint. + * + * See this same function in the arm64 platform code, which has the same + * problem. + * + * The function returns the distance of the address from the bytes watched by + * the watchpoint. In case of an exact match, it returns 0. + */ +static u32 get_distance_from_watchpoint(unsigned long addr, u32 val, + struct arch_hw_breakpoint_ctrl *ctrl) +{ + u32 wp_low, wp_high; + u32 lens, lene; + + lens = __ffs(ctrl->len); + lene = __fls(ctrl->len); + + wp_low = val + lens; + wp_high = val + lene; + if (addr < wp_low) + return wp_low - addr; + else if (addr > wp_high) + return addr - wp_high; + else + return 0; +} + static int watchpoint_fault_on_uaccess(struct pt_regs *regs, struct arch_hw_breakpoint *info) { @@ -692,23 +726,25 @@ static int watchpoint_fault_on_uaccess(struct pt_regs *regs, static void watchpoint_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { - int i, access; - u32 val, ctrl_reg, alignment_mask; + int i, access, closest_match = 0; + u32 min_dist = -1, dist; + u32 val, ctrl_reg; struct perf_event *wp, **slots; struct arch_hw_breakpoint *info; struct arch_hw_breakpoint_ctrl ctrl; slots = this_cpu_ptr(wp_on_reg); + /* + * Find all watchpoints that match the reported address. If no exact + * match is found. Attribute the hit to the closest watchpoint. + */ + rcu_read_lock(); for (i = 0; i < core_num_wrps; ++i) { - rcu_read_lock(); - wp = slots[i]; - if (wp == NULL) - goto unlock; + continue; - info = counter_arch_bp(wp); /* * The DFAR is an unknown value on debug architectures prior * to 7.1. Since we only allow a single watchpoint on these @@ -717,33 +753,31 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr, */ if (debug_arch < ARM_DEBUG_ARCH_V7_1) { BUG_ON(i > 0); + info = counter_arch_bp(wp); info->trigger = wp->attr.bp_addr; } else { - if (info->ctrl.len == ARM_BREAKPOINT_LEN_8) - alignment_mask = 0x7; - else - alignment_mask = 0x3; - - /* Check if the watchpoint value matches. */ - val = read_wb_reg(ARM_BASE_WVR + i); - if (val != (addr & ~alignment_mask)) - goto unlock; - - /* Possible match, check the byte address select. */ - ctrl_reg = read_wb_reg(ARM_BASE_WCR + i); - decode_ctrl_reg(ctrl_reg, &ctrl); - if (!((1 << (addr & alignment_mask)) & ctrl.len)) - goto unlock; - /* Check that the access type matches. */ if (debug_exception_updates_fsr()) { access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W : HW_BREAKPOINT_R; if (!(access & hw_breakpoint_type(wp))) - goto unlock; + continue; } + val = read_wb_reg(ARM_BASE_WVR + i); + ctrl_reg = read_wb_reg(ARM_BASE_WCR + i); + decode_ctrl_reg(ctrl_reg, &ctrl); + dist = get_distance_from_watchpoint(addr, val, &ctrl); + if (dist < min_dist) { + min_dist = dist; + closest_match = i; + } + /* Is this an exact match? */ + if (dist != 0) + continue; + /* We have a winner. */ + info = counter_arch_bp(wp); info->trigger = addr; } @@ -765,13 +799,23 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr, * we can single-step over the watchpoint trigger. */ if (!is_default_overflow_handler(wp)) - goto unlock; - + continue; step: enable_single_step(wp, instruction_pointer(regs)); -unlock: - rcu_read_unlock(); } + + if (min_dist > 0 && min_dist != -1) { + /* No exact match found. */ + wp = slots[closest_match]; + info = counter_arch_bp(wp); + info->trigger = addr; + pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); + perf_bp_event(wp, regs); + if (is_default_overflow_handler(wp)) + enable_single_step(wp, instruction_pointer(regs)); + } + + rcu_read_unlock(); } static void watchpoint_single_step_handler(unsigned long pc) diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index ee514034c0a1..698b6f636156 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -18,7 +18,6 @@ * IRQ's are in fact implemented a bit like signal handlers for the kernel. * Naturally it's not a 1:1 relation, but there are similarities. */ -#include <linux/kernel_stat.h> #include <linux/signal.h> #include <linux/ioport.h> #include <linux/interrupt.h> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index d8e18cdd96d3..3f65d0ac9f63 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -843,20 +843,26 @@ early_param("mem", early_mem); static void __init request_standard_resources(const struct machine_desc *mdesc) { - struct memblock_region *region; + phys_addr_t start, end, res_end; struct resource *res; + u64 i; kernel_code.start = virt_to_phys(_text); kernel_code.end = virt_to_phys(__init_begin - 1); kernel_data.start = virt_to_phys(_sdata); kernel_data.end = virt_to_phys(_end - 1); - for_each_memblock(memory, region) { - phys_addr_t start = __pfn_to_phys(memblock_region_memory_base_pfn(region)); - phys_addr_t end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1; + for_each_mem_range(i, &start, &end) { unsigned long boot_alias_start; /* + * In memblock, end points to the first byte after the + * range while in resourses, end points to the last byte in + * the range. + */ + res_end = end - 1; + + /* * Some systems have a special memory alias which is only * used for booting. We need to advertise this region to * kexec-tools so they know where bootable RAM is located. @@ -869,7 +875,7 @@ static void __init request_standard_resources(const struct machine_desc *mdesc) __func__, sizeof(*res)); res->name = "System RAM (boot alias)"; res->start = boot_alias_start; - res->end = phys_to_idmap(end); + res->end = phys_to_idmap(res_end); res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); } @@ -880,7 +886,7 @@ static void __init request_standard_resources(const struct machine_desc *mdesc) sizeof(*res)); res->name = "System RAM"; res->start = start; - res->end = end; + res->end = res_end; res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index c1892f733f20..585edbfccf6d 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -669,7 +669,6 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) } else if (thread_flags & _TIF_UPROBE) { uprobe_notify_resume(regs); } else { - clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); rseq_handle_notify_resume(NULL, regs); } diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 5d9da61eff62..48099c6e1e4a 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -26,6 +26,7 @@ #include <linux/completion.h> #include <linux/cpufreq.h> #include <linux/irq_work.h> +#include <linux/kernel_stat.h> #include <linux/atomic.h> #include <asm/bugs.h> @@ -65,18 +66,26 @@ enum ipi_msg_type { IPI_CPU_STOP, IPI_IRQ_WORK, IPI_COMPLETION, + NR_IPI, /* * CPU_BACKTRACE is special and not included in NR_IPI * or tracable with trace_ipi_* */ - IPI_CPU_BACKTRACE, + IPI_CPU_BACKTRACE = NR_IPI, /* * SGI8-15 can be reserved by secure firmware, and thus may * not be usable by the kernel. Please keep the above limited * to at most 8 entries. */ + MAX_IPI }; +static int ipi_irq_base __read_mostly; +static int nr_ipi __read_mostly = NR_IPI; +static struct irq_desc *ipi_desc[MAX_IPI] __read_mostly; + +static void ipi_setup(int cpu); + static DECLARE_COMPLETION(cpu_running); static struct smp_operations smp_ops __ro_after_init; @@ -226,6 +235,17 @@ int platform_can_hotplug_cpu(unsigned int cpu) return cpu != 0; } +static void ipi_teardown(int cpu) +{ + int i; + + if (WARN_ON_ONCE(!ipi_irq_base)) + return; + + for (i = 0; i < nr_ipi; i++) + disable_percpu_irq(ipi_irq_base + i); +} + /* * __cpu_disable runs on the processor to be shutdown. */ @@ -247,6 +267,7 @@ int __cpu_disable(void) * and we must not schedule until we're ready to give up the cpu. */ set_cpu_online(cpu, false); + ipi_teardown(cpu); /* * OK - migrate IRQs away from this CPU @@ -422,6 +443,8 @@ asmlinkage void secondary_start_kernel(void) notify_cpu_starting(cpu); + ipi_setup(cpu); + calibrate_delay(); smp_store_cpu_info(cpu); @@ -500,14 +523,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } } -static void (*__smp_cross_call)(const struct cpumask *, unsigned int); - -void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) -{ - if (!__smp_cross_call) - __smp_cross_call = fn; -} - static const char *ipi_types[NR_IPI] __tracepoint_string = { #define S(x,s) [x] = s S(IPI_WAKEUP, "CPU wakeup interrupts"), @@ -519,38 +534,28 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = { S(IPI_COMPLETION, "completion interrupts"), }; -static void smp_cross_call(const struct cpumask *target, unsigned int ipinr) -{ - trace_ipi_raise_rcuidle(target, ipi_types[ipinr]); - __smp_cross_call(target, ipinr); -} +static void smp_cross_call(const struct cpumask *target, unsigned int ipinr); void show_ipi_list(struct seq_file *p, int prec) { unsigned int cpu, i; for (i = 0; i < NR_IPI; i++) { + unsigned int irq; + + if (!ipi_desc[i]) + continue; + + irq = irq_desc_get_irq(ipi_desc[i]); seq_printf(p, "%*s%u: ", prec - 1, "IPI", i); for_each_online_cpu(cpu) - seq_printf(p, "%10u ", - __get_irq_stat(cpu, ipi_irqs[i])); + seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu)); seq_printf(p, " %s\n", ipi_types[i]); } } -u64 smp_irq_stat_cpu(unsigned int cpu) -{ - u64 sum = 0; - int i; - - for (i = 0; i < NR_IPI; i++) - sum += __get_irq_stat(cpu, ipi_irqs[i]); - - return sum; -} - void arch_send_call_function_ipi_mask(const struct cpumask *mask) { smp_cross_call(mask, IPI_CALL_FUNC); @@ -627,15 +632,12 @@ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs) handle_IPI(ipinr, regs); } -void handle_IPI(int ipinr, struct pt_regs *regs) +static void do_handle_IPI(int ipinr) { unsigned int cpu = smp_processor_id(); - struct pt_regs *old_regs = set_irq_regs(regs); - if ((unsigned)ipinr < NR_IPI) { + if ((unsigned)ipinr < NR_IPI) trace_ipi_entry_rcuidle(ipi_types[ipinr]); - __inc_irq_stat(cpu, ipi_irqs[ipinr]); - } switch (ipinr) { case IPI_WAKEUP: @@ -643,9 +645,7 @@ void handle_IPI(int ipinr, struct pt_regs *regs) #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST case IPI_TIMER: - irq_enter(); tick_receive_broadcast(); - irq_exit(); break; #endif @@ -654,36 +654,26 @@ void handle_IPI(int ipinr, struct pt_regs *regs) break; case IPI_CALL_FUNC: - irq_enter(); generic_smp_call_function_interrupt(); - irq_exit(); break; case IPI_CPU_STOP: - irq_enter(); ipi_cpu_stop(cpu); - irq_exit(); break; #ifdef CONFIG_IRQ_WORK case IPI_IRQ_WORK: - irq_enter(); irq_work_run(); - irq_exit(); break; #endif case IPI_COMPLETION: - irq_enter(); ipi_complete(cpu); - irq_exit(); break; case IPI_CPU_BACKTRACE: printk_nmi_enter(); - irq_enter(); - nmi_cpu_backtrace(regs); - irq_exit(); + nmi_cpu_backtrace(get_irq_regs()); printk_nmi_exit(); break; @@ -695,9 +685,67 @@ void handle_IPI(int ipinr, struct pt_regs *regs) if ((unsigned)ipinr < NR_IPI) trace_ipi_exit_rcuidle(ipi_types[ipinr]); +} + +/* Legacy version, should go away once all irqchips have been converted */ +void handle_IPI(int ipinr, struct pt_regs *regs) +{ + struct pt_regs *old_regs = set_irq_regs(regs); + + irq_enter(); + do_handle_IPI(ipinr); + irq_exit(); + set_irq_regs(old_regs); } +static irqreturn_t ipi_handler(int irq, void *data) +{ + do_handle_IPI(irq - ipi_irq_base); + return IRQ_HANDLED; +} + +static void smp_cross_call(const struct cpumask *target, unsigned int ipinr) +{ + trace_ipi_raise_rcuidle(target, ipi_types[ipinr]); + __ipi_send_mask(ipi_desc[ipinr], target); +} + +static void ipi_setup(int cpu) +{ + int i; + + if (WARN_ON_ONCE(!ipi_irq_base)) + return; + + for (i = 0; i < nr_ipi; i++) + enable_percpu_irq(ipi_irq_base + i, 0); +} + +void __init set_smp_ipi_range(int ipi_base, int n) +{ + int i; + + WARN_ON(n < MAX_IPI); + nr_ipi = min(n, MAX_IPI); + + for (i = 0; i < nr_ipi; i++) { + int err; + + err = request_percpu_irq(ipi_base + i, ipi_handler, + "IPI", &irq_stat); + WARN_ON(err); + + ipi_desc[i] = irq_to_desc(ipi_base + i); + irq_set_status_flags(ipi_base + i, IRQ_HIDDEN); + } + + ipi_irq_base = ipi_base; + + /* Setup the boot CPU immediately */ + ipi_setup(smp_processor_id()); +} + void smp_send_reschedule(int cpu) { smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); @@ -805,7 +853,7 @@ core_initcall(register_cpufreq_notifier); static void raise_nmi(cpumask_t *mask) { - __smp_cross_call(mask, IPI_CPU_BACKTRACE); + __ipi_send_mask(ipi_desc[IPI_CPU_BACKTRACE], mask); } void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index b5adaf744630..ef0058de432b 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -178,15 +178,6 @@ static inline void update_cpu_capacity(unsigned int cpuid) {} #endif /* - * The current assumption is that we can power gate each core independently. - * This will be superseded by DT binding once available. - */ -const struct cpumask *cpu_corepower_mask(int cpu) -{ - return &cpu_topology[cpu].thread_sibling; -} - -/* * store_cpu_topology is called at boot when only one cpu is running * and with the mutex cpu_hotplug.lock locked, when several cpus have booted, * which prevents simultaneous write access to cpu_topology array @@ -241,20 +232,6 @@ topology_populated: update_siblings_masks(cpuid); } -static inline int cpu_corepower_flags(void) -{ - return SD_SHARE_PKG_RESOURCES | SD_SHARE_POWERDOMAIN; -} - -static struct sched_domain_topology_level arm_topology[] = { -#ifdef CONFIG_SCHED_MC - { cpu_corepower_mask, cpu_corepower_flags, SD_INIT_NAME(GMC) }, - { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) }, -#endif - { cpu_cpu_mask, SD_INIT_NAME(DIE) }, - { NULL, }, -}; - /* * init_cpu_topology is called at boot when only one cpu is running * which prevent simultaneous write access to cpu_topology array @@ -265,7 +242,4 @@ void __init init_cpu_topology(void) smp_wmb(); parse_dt_topology(); - - /* Set scheduler topology descriptor */ - set_sched_topology(arm_topology); } diff --git a/arch/arm/kernel/vmlinux-xip.lds.S b/arch/arm/kernel/vmlinux-xip.lds.S index 6d2be994ae58..50136828f5b5 100644 --- a/arch/arm/kernel/vmlinux-xip.lds.S +++ b/arch/arm/kernel/vmlinux-xip.lds.S @@ -9,15 +9,13 @@ #include <linux/sizes.h> -#include <asm-generic/vmlinux.lds.h> +#include <asm/vmlinux.lds.h> #include <asm/cache.h> #include <asm/thread_info.h> #include <asm/memory.h> #include <asm/mpu.h> #include <asm/page.h> -#include "vmlinux.lds.h" - OUTPUT_ARCH(arm) ENTRY(stext) @@ -152,6 +150,10 @@ SECTIONS _end = .; STABS_DEBUG + DWARF_DEBUG + ARM_DETAILS + + ARM_ASSERTS } /* diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 7f24bc08403e..5f4922e858d0 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -9,15 +9,13 @@ #else #include <linux/pgtable.h> -#include <asm-generic/vmlinux.lds.h> +#include <asm/vmlinux.lds.h> #include <asm/cache.h> #include <asm/thread_info.h> #include <asm/memory.h> #include <asm/mpu.h> #include <asm/page.h> -#include "vmlinux.lds.h" - OUTPUT_ARCH(arm) ENTRY(stext) @@ -151,6 +149,10 @@ SECTIONS _end = .; STABS_DEBUG + DWARF_DEBUG + ARM_DETAILS + + ARM_ASSERTS } #ifdef CONFIG_STRICT_KERNEL_RWX diff --git a/arch/arm/lib/csumpartialcopy.S b/arch/arm/lib/csumpartialcopy.S index 184d97254a7a..1ca6aadd649c 100644 --- a/arch/arm/lib/csumpartialcopy.S +++ b/arch/arm/lib/csumpartialcopy.S @@ -9,8 +9,8 @@ .text -/* Function: __u32 csum_partial_copy_nocheck(const char *src, char *dst, int len, __u32 sum) - * Params : r0 = src, r1 = dst, r2 = len, r3 = checksum +/* Function: __u32 csum_partial_copy_nocheck(const char *src, char *dst, int len) + * Params : r0 = src, r1 = dst, r2 = len * Returns : r0 = new checksum */ diff --git a/arch/arm/lib/csumpartialcopygeneric.S b/arch/arm/lib/csumpartialcopygeneric.S index 0b706a39a677..0fd5c10e90a7 100644 --- a/arch/arm/lib/csumpartialcopygeneric.S +++ b/arch/arm/lib/csumpartialcopygeneric.S @@ -86,6 +86,7 @@ sum .req r3 FN_ENTRY save_regs + mov sum, #-1 cmp len, #8 @ Ensure that we have at least blo .Lless8 @ 8 bytes to copy. diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S index 6bd3a93eaa3c..6928781e6bee 100644 --- a/arch/arm/lib/csumpartialcopyuser.S +++ b/arch/arm/lib/csumpartialcopyuser.S @@ -62,9 +62,9 @@ /* * unsigned int - * csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr) - * r0 = src, r1 = dst, r2 = len, r3 = sum, [sp] = *err_ptr - * Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT + * csum_partial_copy_from_user(const char *src, char *dst, int len) + * r0 = src, r1 = dst, r2 = len + * Returns : r0 = checksum or 0 */ #define FN_ENTRY ENTRY(csum_partial_copy_from_user) @@ -73,25 +73,11 @@ #include "csumpartialcopygeneric.S" /* - * FIXME: minor buglet here - * We don't return the checksum for the data present in the buffer. To do - * so properly, we would have to add in whatever registers were loaded before - * the fault, which, with the current asm above is not predictable. + * We report fault by returning 0 csum - impossible in normal case, since + * we start with 0xffffffff for initial sum. */ .pushsection .text.fixup,"ax" .align 4 -9001: mov r4, #-EFAULT -#ifdef CONFIG_CPU_SW_DOMAIN_PAN - ldr r5, [sp, #9*4] @ *err_ptr -#else - ldr r5, [sp, #8*4] @ *err_ptr -#endif - str r4, [r5] - ldmia sp, {r1, r2} @ retrieve dst, len - add r2, r2, r1 - mov r0, #0 @ zero the buffer -9002: teq r2, r1 - strbne r0, [r1], #1 - bne 9002b +9001: mov r0, #0 load_regs .popsection diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 2aab043441e8..120f9aa6fff3 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -51,10 +51,11 @@ static struct at91_soc_pm soc_pm = { }; static const match_table_t pm_modes __initconst = { - { AT91_PM_STANDBY, "standby" }, - { AT91_PM_ULP0, "ulp0" }, - { AT91_PM_ULP1, "ulp1" }, - { AT91_PM_BACKUP, "backup" }, + { AT91_PM_STANDBY, "standby" }, + { AT91_PM_ULP0, "ulp0" }, + { AT91_PM_ULP0_FAST, "ulp0-fast" }, + { AT91_PM_ULP1, "ulp1" }, + { AT91_PM_BACKUP, "backup" }, { -1, NULL }, }; @@ -557,11 +558,6 @@ static void at91rm9200_idle(void) writel(AT91_PMC_PCK, soc_pm.data.pmc + AT91_PMC_SCDR); } -static void at91sam9x60_idle(void) -{ - cpu_do_idle(); -} - static void at91sam9_idle(void) { writel(AT91_PMC_PCK, soc_pm.data.pmc + AT91_PMC_SCDR); @@ -789,6 +785,51 @@ static const struct of_device_id atmel_pmc_ids[] __initconst = { { /* sentinel */ }, }; +static void __init at91_pm_modes_validate(const int *modes, int len) +{ + u8 i, standby = 0, suspend = 0; + int mode; + + for (i = 0; i < len; i++) { + if (standby && suspend) + break; + + if (modes[i] == soc_pm.data.standby_mode && !standby) { + standby = 1; + continue; + } + + if (modes[i] == soc_pm.data.suspend_mode && !suspend) { + suspend = 1; + continue; + } + } + + if (!standby) { + if (soc_pm.data.suspend_mode == AT91_PM_STANDBY) + mode = AT91_PM_ULP0; + else + mode = AT91_PM_STANDBY; + + pr_warn("AT91: PM: %s mode not supported! Using %s.\n", + pm_modes[soc_pm.data.standby_mode].pattern, + pm_modes[mode].pattern); + soc_pm.data.standby_mode = mode; + } + + if (!suspend) { + if (soc_pm.data.standby_mode == AT91_PM_ULP0) + mode = AT91_PM_STANDBY; + else + mode = AT91_PM_ULP0; + + pr_warn("AT91: PM: %s mode not supported! Using %s.\n", + pm_modes[soc_pm.data.suspend_mode].pattern, + pm_modes[mode].pattern); + soc_pm.data.suspend_mode = mode; + } +} + static void __init at91_pm_init(void (*pm_idle)(void)) { struct device_node *pmc_np; @@ -800,6 +841,7 @@ static void __init at91_pm_init(void (*pm_idle)(void)) pmc_np = of_find_matching_node_and_match(NULL, atmel_pmc_ids, &of_id); soc_pm.data.pmc = of_iomap(pmc_np, 0); + of_node_put(pmc_np); if (!soc_pm.data.pmc) { pr_err("AT91: PM not supported, PMC not found\n"); return; @@ -830,6 +872,14 @@ void __init at91rm9200_pm_init(void) if (!IS_ENABLED(CONFIG_SOC_AT91RM9200)) return; + /* + * Force STANDBY and ULP0 mode to avoid calling + * at91_pm_modes_validate() which may increase booting time. + * Platform supports anyway only STANDBY and ULP0 modes. + */ + soc_pm.data.standby_mode = AT91_PM_STANDBY; + soc_pm.data.suspend_mode = AT91_PM_ULP0; + at91_dt_ramc(); /* @@ -842,12 +892,17 @@ void __init at91rm9200_pm_init(void) void __init sam9x60_pm_init(void) { + static const int modes[] __initconst = { + AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1, + }; + if (!IS_ENABLED(CONFIG_SOC_SAM9X60)) return; + at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); at91_pm_modes_init(); at91_dt_ramc(); - at91_pm_init(at91sam9x60_idle); + at91_pm_init(NULL); soc_pm.ws_ids = sam9x60_ws_ids; soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws; @@ -858,26 +913,46 @@ void __init at91sam9_pm_init(void) if (!IS_ENABLED(CONFIG_SOC_AT91SAM9)) return; + /* + * Force STANDBY and ULP0 mode to avoid calling + * at91_pm_modes_validate() which may increase booting time. + * Platform supports anyway only STANDBY and ULP0 modes. + */ + soc_pm.data.standby_mode = AT91_PM_STANDBY; + soc_pm.data.suspend_mode = AT91_PM_ULP0; + at91_dt_ramc(); at91_pm_init(at91sam9_idle); } void __init sama5_pm_init(void) { + static const int modes[] __initconst = { + AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, + }; + if (!IS_ENABLED(CONFIG_SOC_SAMA5)) return; + at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); at91_dt_ramc(); at91_pm_init(NULL); } void __init sama5d2_pm_init(void) { + static const int modes[] __initconst = { + AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1, + AT91_PM_BACKUP, + }; + if (!IS_ENABLED(CONFIG_SOC_SAMA5D2)) return; + at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); at91_pm_modes_init(); - sama5_pm_init(); + at91_dt_ramc(); + at91_pm_init(NULL); soc_pm.ws_ids = sama5d2_ws_ids; soc_pm.config_shdwc_ws = at91_sama5d2_config_shdwc_ws; diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index 218e8d1a30fb..bfb260be371e 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h @@ -19,8 +19,9 @@ #define AT91_PM_STANDBY 0x00 #define AT91_PM_ULP0 0x01 -#define AT91_PM_ULP1 0x02 -#define AT91_PM_BACKUP 0x03 +#define AT91_PM_ULP0_FAST 0x02 +#define AT91_PM_ULP1 0x03 +#define AT91_PM_BACKUP 0x04 #ifndef __ASSEMBLY__ struct at91_pm_data { diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S index be9764e8d3fa..0184de05c1be 100644 --- a/arch/arm/mach-at91/pm_suspend.S +++ b/arch/arm/mach-at91/pm_suspend.S @@ -164,7 +164,22 @@ ENDPROC(at91_backup_mode) .macro at91_pm_ulp0_mode ldr pmc, .pmc_base + ldr tmp2, .pm_mode + ldr tmp3, .mckr_offset + + /* Check if ULP0 fast variant has been requested. */ + cmp tmp2, #AT91_PM_ULP0_FAST + bne 0f + + /* Set highest prescaler for power saving */ + ldr tmp1, [pmc, tmp3] + bic tmp1, tmp1, #AT91_PMC_PRES + orr tmp1, tmp1, #AT91_PMC_PRES_64 + str tmp1, [pmc, tmp3] + wait_mckrdy + b 1f +0: /* Turn off the crystal oscillator */ ldr tmp1, [pmc, #AT91_CKGR_MOR] bic tmp1, tmp1, #AT91_PMC_MOSCEN @@ -192,7 +207,18 @@ ENDPROC(at91_backup_mode) /* Wait for interrupt */ 1: at91_cpu_idle - /* Restore RC oscillator state */ + /* Check if ULP0 fast variant has been requested. */ + cmp tmp2, #AT91_PM_ULP0_FAST + bne 5f + + /* Set lowest prescaler for fast resume. */ + ldr tmp1, [pmc, tmp3] + bic tmp1, tmp1, #AT91_PMC_PRES + str tmp1, [pmc, tmp3] + wait_mckrdy + b 6f + +5: /* Restore RC oscillator state */ ldr tmp1, .saved_osc_status tst tmp1, #AT91_PMC_MOSCRCS beq 4f @@ -216,6 +242,7 @@ ENDPROC(at91_backup_mode) str tmp1, [pmc, #AT91_CKGR_MOR] wait_moscrdy +6: .endm /** @@ -473,23 +500,29 @@ ENDPROC(at91_backup_mode) ENTRY(at91_ulp_mode) ldr pmc, .pmc_base ldr tmp2, .mckr_offset + ldr tmp3, .pm_mode /* Save Master clock setting */ ldr tmp1, [pmc, tmp2] str tmp1, .saved_mckr /* - * Set the Master clock source to slow clock + * Set master clock source to: + * - MAINCK if using ULP0 fast variant + * - slow clock, otherwise */ bic tmp1, tmp1, #AT91_PMC_CSS + cmp tmp3, #AT91_PM_ULP0_FAST + bne save_mck + orr tmp1, tmp1, #AT91_PMC_CSS_MAIN +save_mck: str tmp1, [pmc, tmp2] wait_mckrdy at91_plla_disable - ldr r0, .pm_mode - cmp r0, #AT91_PM_ULP1 + cmp tmp3, #AT91_PM_ULP1 beq ulp1_mode at91_pm_ulp0_mode diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 1df0ee01ee02..ae790908fc74 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -208,6 +208,7 @@ config ARCH_BRCMSTB select ARM_GIC select ARM_ERRATA_798181 if SMP select HAVE_ARM_ARCH_TIMER + select BCM7038_L1_IRQ select BRCMSTB_L2_IRQ select BCM7120_L2_IRQ select ARCH_HAS_HOLES_MEMORYMODEL diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 1076886938b6..a20ba12d876c 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -306,7 +306,7 @@ static struct davinci_nand_pdata da830_evm_nand_pdata = { .core_chipsel = 1, .parts = da830_evm_nand_partitions, .nr_parts = ARRAY_SIZE(da830_evm_nand_partitions), - .ecc_mode = NAND_ECC_HW, + .engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST, .ecc_bits = 4, .bbt_options = NAND_BBT_USE_FLASH, .bbt_td = &da830_evm_nand_bbt_main_descr, diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 6751292e5f8f..428012687a80 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -239,7 +239,7 @@ static struct davinci_nand_pdata da850_evm_nandflash_data = { .core_chipsel = 1, .parts = da850_evm_nandflash_partition, .nr_parts = ARRAY_SIZE(da850_evm_nandflash_partition), - .ecc_mode = NAND_ECC_HW, + .engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST, .ecc_bits = 4, .bbt_options = NAND_BBT_USE_FLASH, .timing = &da850_evm_nandflash_timing, diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 5113273fda69..3c5a9e3c128a 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -82,7 +82,7 @@ static struct davinci_nand_pdata davinci_nand_data = { .mask_chipsel = BIT(14), .parts = davinci_nand_partitions, .nr_parts = ARRAY_SIZE(davinci_nand_partitions), - .ecc_mode = NAND_ECC_HW, + .engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST, .bbt_options = NAND_BBT_USE_FLASH, .ecc_bits = 4, }; diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index b9e9950dd300..e475b2113e70 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -76,7 +76,8 @@ static struct davinci_nand_pdata davinci_nand_data = { .mask_chipsel = BIT(14), .parts = davinci_nand_partitions, .nr_parts = ARRAY_SIZE(davinci_nand_partitions), - .ecc_mode = NAND_ECC_HW_SYNDROME, + .engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST, + .ecc_placement = NAND_ECC_PLACEMENT_INTERLEAVED, .ecc_bits = 4, .bbt_options = NAND_BBT_USE_FLASH, }; diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 2328b15ac067..bdf31eb77620 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -146,7 +146,7 @@ static struct davinci_nand_pdata davinci_nand_data = { .mask_chipsel = BIT(14), .parts = davinci_nand_partitions, .nr_parts = ARRAY_SIZE(davinci_nand_partitions), - .ecc_mode = NAND_ECC_HW, + .engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST, .bbt_options = NAND_BBT_USE_FLASH, .ecc_bits = 4, }; diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index a5d3708fedf6..7755cccec550 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -162,7 +162,7 @@ static struct davinci_nand_pdata davinci_evm_nandflash_data = { .core_chipsel = 0, .parts = davinci_evm_nandflash_partition, .nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition), - .ecc_mode = NAND_ECC_HW, + .engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST, .ecc_bits = 1, .bbt_options = NAND_BBT_USE_FLASH, .timing = &davinci_evm_nandflash_timing, @@ -548,8 +548,7 @@ static const struct property_entry eeprom_properties[] = { */ static struct i2c_client *dm6446evm_msp; -static int dm6446evm_msp_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int dm6446evm_msp_probe(struct i2c_client *client) { dm6446evm_msp = client; return 0; @@ -569,7 +568,7 @@ static const struct i2c_device_id dm6446evm_msp_ids[] = { static struct i2c_driver dm6446evm_msp_driver = { .driver.name = "dm6446evm_msp", .id_table = dm6446evm_msp_ids, - .probe = dm6446evm_msp_probe, + .probe_new = dm6446evm_msp_probe, .remove = dm6446evm_msp_remove, }; diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index dd7d60f4139a..952ddabc743e 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -91,7 +91,7 @@ static struct davinci_nand_pdata davinci_nand_data = { .mask_ale = 0x40000, .parts = davinci_nand_partitions, .nr_parts = ARRAY_SIZE(davinci_nand_partitions), - .ecc_mode = NAND_ECC_HW, + .engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST, .ecc_bits = 1, .options = 0, }; @@ -160,8 +160,7 @@ static struct platform_device davinci_aemif_device = { #define DM646X_EVM_ATA_PWD BIT(1) /* CPLD Register 0 Client: used for I/O Control */ -static int cpld_reg0_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cpld_reg0_probe(struct i2c_client *client) { if (HAS_ATA) { u8 data; @@ -197,7 +196,7 @@ static const struct i2c_device_id cpld_reg_ids[] = { static struct i2c_driver dm6467evm_cpld_driver = { .driver.name = "cpld_reg0", .id_table = cpld_reg_ids, - .probe = cpld_reg0_probe, + .probe_new = cpld_reg0_probe, }; /* LEDS */ @@ -397,8 +396,7 @@ static struct snd_platform_data dm646x_evm_snd_data[] = { #ifdef CONFIG_I2C static struct i2c_client *cpld_client; -static int cpld_video_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int cpld_video_probe(struct i2c_client *client) { cpld_client = client; return 0; @@ -419,7 +417,7 @@ static struct i2c_driver cpld_video_driver = { .driver = { .name = "cpld_video", }, - .probe = cpld_video_probe, + .probe_new = cpld_video_probe, .remove = cpld_video_remove, .id_table = cpld_video_id, }; diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index 3382b93d9a2a..5205008c8061 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -432,7 +432,7 @@ static struct davinci_nand_pdata mityomapl138_nandflash_data = { .core_chipsel = 1, .parts = mityomapl138_nandflash_partition, .nr_parts = ARRAY_SIZE(mityomapl138_nandflash_partition), - .ecc_mode = NAND_ECC_HW, + .engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST, .bbt_options = NAND_BBT_USE_FLASH, .options = NAND_BUSWIDTH_16, .ecc_bits = 1, /* 4 bit mode is not supported with 16 bit NAND */ diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index 6cf46bbc7e1d..b4843f68bb57 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -90,7 +90,7 @@ static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = { .core_chipsel = 0, .parts = davinci_ntosd2_nandflash_partition, .nr_parts = ARRAY_SIZE(davinci_ntosd2_nandflash_partition), - .ecc_mode = NAND_ECC_HW, + .engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST, .ecc_bits = 1, .bbt_options = NAND_BBT_USE_FLASH, }; diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 6c79039002c9..88df8011a4e6 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -206,7 +206,7 @@ static struct davinci_nand_pdata omapl138_hawk_nandflash_data = { .core_chipsel = 1, .parts = omapl138_hawk_nandflash_partition, .nr_parts = ARRAY_SIZE(omapl138_hawk_nandflash_partition), - .ecc_mode = NAND_ECC_HW, + .engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST, .ecc_bits = 4, .bbt_options = NAND_BBT_USE_FLASH, .options = NAND_BUSWIDTH_16, diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index feb206bdf6e1..bb368938fc49 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -10,7 +10,7 @@ #include <linux/clk-provider.h> #include <linux/clk.h> #include <linux/clkdev.h> -#include <linux/dma-contiguous.h> +#include <linux/dma-map-ops.h> #include <linux/dmaengine.h> #include <linux/init.h> #include <linux/io.h> @@ -884,6 +884,7 @@ early_param("rproc_mem", early_rproc_mem); void __init da8xx_rproc_reserve_cma(void) { + struct cma *cma; int ret; if (!rproc_base || !rproc_size) { @@ -897,13 +898,16 @@ void __init da8xx_rproc_reserve_cma(void) pr_info("%s: reserving 0x%lx @ 0x%lx...\n", __func__, rproc_size, (unsigned long)rproc_base); - ret = dma_declare_contiguous(&da8xx_dsp.dev, rproc_size, rproc_base, 0); - if (ret) - pr_err("%s: dma_declare_contiguous failed %d\n", __func__, ret); - else - rproc_mem_inited = true; + ret = dma_contiguous_reserve_area(rproc_size, rproc_base, 0, &cma, + true); + if (ret) { + pr_err("%s: dma_contiguous_reserve_area failed %d\n", + __func__, ret); + return; + } + da8xx_dsp.dev.cma_area = cma; + rproc_mem_inited = true; } - #else void __init da8xx_rproc_reserve_cma(void) diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index f185cd3d4c62..d2d249706ebb 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -24,7 +24,6 @@ menuconfig ARCH_EXYNOS select HAVE_ARM_ARCH_TIMER if ARCH_EXYNOS5 select HAVE_ARM_SCU if SMP select HAVE_S3C2410_I2C if I2C - select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS select PINCTRL select PINCTRL_EXYNOS diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index 0fd3fcf8bfb0..53fa363c8e44 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile @@ -3,10 +3,6 @@ # Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. # http://www.samsung.com/ -ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include -I$(srctree)/arch/arm/plat-samsung/include - -# Core - obj-$(CONFIG_ARCH_EXYNOS) += exynos.o exynos-smc.o firmware.o obj-$(CONFIG_EXYNOS_CPU_SUSPEND) += pm.o sleep.o diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index afd988a92836..29eb075b24a4 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h @@ -24,12 +24,12 @@ #define EXYNOS5800_SOC_ID 0xE5422000 #define EXYNOS5_SOC_MASK 0xFFFFF000 -extern unsigned long samsung_cpu_id; +extern unsigned long exynos_cpu_id; #define IS_SAMSUNG_CPU(name, id, mask) \ static inline int is_samsung_##name(void) \ { \ - return ((samsung_cpu_id & mask) == (id & mask)); \ + return ((exynos_cpu_id & mask) == (id & mask)); \ } IS_SAMSUNG_CPU(exynos3250, EXYNOS3250_SOC_ID, EXYNOS3_SOC_MASK) @@ -147,7 +147,7 @@ extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data; extern void exynos_set_delayed_reset_assertion(bool enable); -extern unsigned int samsung_rev(void); +extern unsigned int exynos_rev(void); extern void exynos_core_restart(u32 core_id); extern int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr); extern int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr); diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index 36c37444485a..700763e07083 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -19,11 +19,12 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/map.h> -#include <plat/cpu.h> - #include "common.h" +#define S3C_ADDR_BASE 0xF6000000 +#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x)) +#define S5P_VA_CHIPID S3C_ADDR(0x02000000) + static struct platform_device exynos_cpuidle = { .name = "exynos_cpuidle", #ifdef CONFIG_ARM_EXYNOS_CPUIDLE @@ -36,6 +37,14 @@ void __iomem *sysram_base_addr __ro_after_init; phys_addr_t sysram_base_phys __ro_after_init; void __iomem *sysram_ns_base_addr __ro_after_init; +unsigned long exynos_cpu_id; +static unsigned int exynos_cpu_rev; + +unsigned int exynos_rev(void) +{ + return exynos_cpu_rev; +} + void __init exynos_sysram_init(void) { struct device_node *node; @@ -86,7 +95,11 @@ static void __init exynos_init_io(void) of_scan_flat_dt(exynos_fdt_map_chipid, NULL); /* detect cpu id and rev. */ - s5p_init_cpu(S5P_VA_CHIPID); + exynos_cpu_id = readl_relaxed(S5P_VA_CHIPID); + exynos_cpu_rev = exynos_cpu_id & 0xFF; + + pr_info("Samsung CPU ID: 0x%08lx\n", exynos_cpu_id); + } /* @@ -193,8 +206,8 @@ static void __init exynos_dt_fixup(void) } DT_MACHINE_START(EXYNOS_DT, "Samsung Exynos (Flattened Device Tree)") - .l2c_aux_val = 0x3c400000, - .l2c_aux_mask = 0xc20fffff, + .l2c_aux_val = 0x38400000, + .l2c_aux_mask = 0xc60fffff, .smp = smp_ops(exynos_smp_ops), .map_io = exynos_init_io, .init_early = exynos_firmware_init, diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h deleted file mode 100644 index 8d58faa54ff7..000000000000 --- a/arch/arm/mach-exynos/include/mach/map.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Exynos - Memory map definitions - */ - -#ifndef __ASM_ARCH_MAP_H -#define __ASM_ARCH_MAP_H __FILE__ - -#include <plat/map-base.h> - -#include <plat/map-s5p.h> - -#define EXYNOS_PA_CHIPID 0x10000000 - -#endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 0cbbae8bf1f8..d7fedbb2eefe 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -22,8 +22,6 @@ #include <asm/smp_scu.h> #include <asm/firmware.h> -#include <mach/map.h> - #include "common.h" extern void exynos4_secondary_startup(void); @@ -188,7 +186,7 @@ void exynos_scu_enable(void) static void __iomem *cpu_boot_reg_base(void) { - if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1) + if (soc_is_exynos4210() && exynos_rev() == EXYNOS4210_REV_1_1) return pmu_base_addr + S5P_INFORM5; return sysram_base_addr; } diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index 78af34cc89cc..30f4e55bf39e 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -26,18 +26,18 @@ static inline void __iomem *exynos_boot_vector_addr(void) { - if (samsung_rev() == EXYNOS4210_REV_1_1) + if (exynos_rev() == EXYNOS4210_REV_1_1) return pmu_base_addr + S5P_INFORM7; - else if (samsung_rev() == EXYNOS4210_REV_1_0) + else if (exynos_rev() == EXYNOS4210_REV_1_0) return sysram_base_addr + 0x24; return pmu_base_addr + S5P_INFORM0; } static inline void __iomem *exynos_boot_vector_flag(void) { - if (samsung_rev() == EXYNOS4210_REV_1_1) + if (exynos_rev() == EXYNOS4210_REV_1_1) return pmu_base_addr + S5P_INFORM6; - else if (samsung_rev() == EXYNOS4210_REV_1_0) + else if (exynos_rev() == EXYNOS4210_REV_1_0) return sysram_base_addr + 0x20; return pmu_base_addr + S5P_INFORM1; } diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c index 56bf29523c65..db607955a7e4 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c @@ -5,7 +5,7 @@ #include <linux/clk.h> #include <linux/clkdev.h> #include <linux/clocksource.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/input.h> #include <linux/io.h> #include <linux/irqchip.h> diff --git a/arch/arm/mach-hisi/Kconfig b/arch/arm/mach-hisi/Kconfig index 3b010fe7c0e9..2e980f834a6a 100644 --- a/arch/arm/mach-hisi/Kconfig +++ b/arch/arm/mach-hisi/Kconfig @@ -1,9 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-only config ARCH_HISI bool "Hisilicon SoC Support" - depends on ARCH_MULTI_V7 + depends on ARCH_MULTI_V7 || ARCH_MULTI_V5 select ARM_AMBA - select ARM_GIC + select ARM_GIC if ARCH_MULTI_V7 select ARM_TIMER_SP804 select POWER_RESET select POWER_RESET_HISI @@ -15,6 +15,7 @@ menu "Hisilicon platform type" config ARCH_HI3xxx bool "Hisilicon Hi36xx family" + depends on ARCH_MULTI_V7 select CACHE_L2X0 select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP @@ -25,6 +26,7 @@ config ARCH_HI3xxx config ARCH_HIP01 bool "Hisilicon HIP01 family" + depends on ARCH_MULTI_V7 select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP select ARM_GLOBAL_TIMER @@ -33,6 +35,7 @@ config ARCH_HIP01 config ARCH_HIP04 bool "Hisilicon HiP04 Cortex A15 family" + depends on ARCH_MULTI_V7 select ARM_ERRATA_798181 if SMP select HAVE_ARM_ARCH_TIMER select MCPM if SMP @@ -43,6 +46,7 @@ config ARCH_HIP04 config ARCH_HIX5HD2 bool "Hisilicon X5HD2 family" + depends on ARCH_MULTI_V7 select CACHE_L2X0 select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP @@ -50,6 +54,14 @@ config ARCH_HIX5HD2 select PINCTRL_SINGLE help Support for Hisilicon HIX5HD2 SoC family + +config ARCH_SD5203 + bool "Hisilicon SD5203 family" + depends on ARCH_MULTI_V5 + select DW_APB_ICTL + help + Support for Hisilicon SD5203 SoC family + endmenu endif diff --git a/arch/arm/mach-imx/3ds_debugboard.c b/arch/arm/mach-imx/3ds_debugboard.c deleted file mode 100644 index 0e018000715a..000000000000 --- a/arch/arm/mach-imx/3ds_debugboard.c +++ /dev/null @@ -1,207 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2010 Jason Wang <jason77.wang@gmail.com> - */ - -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/irqdomain.h> -#include <linux/io.h> -#include <linux/platform_device.h> -#include <linux/gpio.h> -#include <linux/module.h> -#include <linux/smsc911x.h> -#include <linux/regulator/machine.h> -#include <linux/regulator/fixed.h> -#include "3ds_debugboard.h" -#include "hardware.h" - -/* LAN9217 ethernet base address */ -#define LAN9217_BASE_ADDR(n) (n + 0x0) -/* External UART */ -#define UARTA_BASE_ADDR(n) (n + 0x8000) -#define UARTB_BASE_ADDR(n) (n + 0x10000) - -#define BOARD_IO_ADDR(n) (n + 0x20000) -/* LED switchs */ -#define LED_SWITCH_REG 0x00 -/* buttons */ -#define SWITCH_BUTTONS_REG 0x08 -/* status, interrupt */ -#define INTR_STATUS_REG 0x10 -#define INTR_MASK_REG 0x38 -#define INTR_RESET_REG 0x20 -/* magic word for debug CPLD */ -#define MAGIC_NUMBER1_REG 0x40 -#define MAGIC_NUMBER2_REG 0x48 -/* CPLD code version */ -#define CPLD_CODE_VER_REG 0x50 -/* magic word for debug CPLD */ -#define MAGIC_NUMBER3_REG 0x58 -/* module reset register*/ -#define MODULE_RESET_REG 0x60 -/* CPU ID and Personality ID */ -#define MCU_BOARD_ID_REG 0x68 - -#define MXC_MAX_EXP_IO_LINES 16 - -/* interrupts like external uart , external ethernet etc*/ -#define EXPIO_INT_ENET 0 -#define EXPIO_INT_XUART_A 1 -#define EXPIO_INT_XUART_B 2 -#define EXPIO_INT_BUTTON_A 3 -#define EXPIO_INT_BUTTON_B 4 - -static void __iomem *brd_io; -static struct irq_domain *domain; - -static struct resource smsc911x_resources[] = { - { - .flags = IORESOURCE_MEM, - } , { - .flags = IORESOURCE_IRQ, - }, -}; - -static struct smsc911x_platform_config smsc911x_config = { - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, - .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY, -}; - -static struct platform_device smsc_lan9217_device = { - .name = "smsc911x", - .id = -1, - .dev = { - .platform_data = &smsc911x_config, - }, - .num_resources = ARRAY_SIZE(smsc911x_resources), - .resource = smsc911x_resources, -}; - -static void mxc_expio_irq_handler(struct irq_desc *desc) -{ - u32 imr_val; - u32 int_valid; - u32 expio_irq; - - /* irq = gpio irq number */ - desc->irq_data.chip->irq_mask(&desc->irq_data); - - imr_val = imx_readw(brd_io + INTR_MASK_REG); - int_valid = imx_readw(brd_io + INTR_STATUS_REG) & ~imr_val; - - expio_irq = 0; - for (; int_valid != 0; int_valid >>= 1, expio_irq++) { - if ((int_valid & 1) == 0) - continue; - generic_handle_irq(irq_find_mapping(domain, expio_irq)); - } - - desc->irq_data.chip->irq_ack(&desc->irq_data); - desc->irq_data.chip->irq_unmask(&desc->irq_data); -} - -/* - * Disable an expio pin's interrupt by setting the bit in the imr. - * Irq is an expio virtual irq number - */ -static void expio_mask_irq(struct irq_data *d) -{ - u16 reg; - u32 expio = d->hwirq; - - reg = imx_readw(brd_io + INTR_MASK_REG); - reg |= (1 << expio); - imx_writew(reg, brd_io + INTR_MASK_REG); -} - -static void expio_ack_irq(struct irq_data *d) -{ - u32 expio = d->hwirq; - - imx_writew(1 << expio, brd_io + INTR_RESET_REG); - imx_writew(0, brd_io + INTR_RESET_REG); - expio_mask_irq(d); -} - -static void expio_unmask_irq(struct irq_data *d) -{ - u16 reg; - u32 expio = d->hwirq; - - reg = imx_readw(brd_io + INTR_MASK_REG); - reg &= ~(1 << expio); - imx_writew(reg, brd_io + INTR_MASK_REG); -} - -static struct irq_chip expio_irq_chip = { - .irq_ack = expio_ack_irq, - .irq_mask = expio_mask_irq, - .irq_unmask = expio_unmask_irq, -}; - -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vdd33a", "smsc911x"), - REGULATOR_SUPPLY("vddvario", "smsc911x"), -}; - -int __init mxc_expio_init(u32 base, u32 intr_gpio) -{ - u32 p_irq = gpio_to_irq(intr_gpio); - int irq_base; - int i; - - brd_io = ioremap(BOARD_IO_ADDR(base), SZ_4K); - if (brd_io == NULL) - return -ENOMEM; - - if ((imx_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) || - (imx_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) || - (imx_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) { - pr_info("3-Stack Debug board not detected\n"); - iounmap(brd_io); - brd_io = NULL; - return -ENODEV; - } - - pr_info("3-Stack Debug board detected, rev = 0x%04X\n", - readw(brd_io + CPLD_CODE_VER_REG)); - - /* - * Configure INT line as GPIO input - */ - gpio_request(intr_gpio, "expio_pirq"); - gpio_direction_input(intr_gpio); - - /* disable the interrupt and clear the status */ - imx_writew(0, brd_io + INTR_MASK_REG); - imx_writew(0xFFFF, brd_io + INTR_RESET_REG); - imx_writew(0, brd_io + INTR_RESET_REG); - imx_writew(0x1F, brd_io + INTR_MASK_REG); - - irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id()); - WARN_ON(irq_base < 0); - - domain = irq_domain_add_legacy(NULL, MXC_MAX_EXP_IO_LINES, irq_base, 0, - &irq_domain_simple_ops, NULL); - WARN_ON(!domain); - - for (i = irq_base; i < irq_base + MXC_MAX_EXP_IO_LINES; i++) { - irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq); - irq_clear_status_flags(i, IRQ_NOREQUEST); - } - irq_set_irq_type(p_irq, IRQF_TRIGGER_LOW); - irq_set_chained_handler(p_irq, mxc_expio_irq_handler); - - /* Register Lan device on the debugboard */ - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - - smsc911x_resources[0].start = LAN9217_BASE_ADDR(base); - smsc911x_resources[0].end = LAN9217_BASE_ADDR(base) + 0x100 - 1; - smsc911x_resources[1].start = irq_find_mapping(domain, EXPIO_INT_ENET); - smsc911x_resources[1].end = irq_find_mapping(domain, EXPIO_INT_ENET); - platform_device_register(&smsc_lan9217_device); - - return 0; -} diff --git a/arch/arm/mach-imx/3ds_debugboard.h b/arch/arm/mach-imx/3ds_debugboard.h deleted file mode 100644 index a4d04d099c61..000000000000 --- a/arch/arm/mach-imx/3ds_debugboard.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -#ifndef __ASM_ARCH_MXC_3DS_DB_H__ -#define __ASM_ARCH_MXC_3DS_DB_H__ - -extern int __init mxc_expio_init(u32 base, u32 intr_gpio); - -#endif /* __ASM_ARCH_MXC_3DS_DB_H__ */ diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index e7d7b90e2cf8..52902782cc5f 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -47,371 +47,26 @@ config HAVE_IMX_SRC def_bool y if SMP select ARCH_HAS_RESET_CONTROLLER -config IMX_HAVE_IOMUX_V1 - bool +if ARCH_MULTI_V6 -config ARCH_MXC_IOMUX_V3 - bool - -config SOC_IMX21 - bool - select CPU_ARM926T - select IMX_HAVE_IOMUX_V1 - select MXC_AVIC - -config SOC_IMX27 - bool - select CPU_ARM926T - select IMX_HAVE_IOMUX_V1 - select MXC_AVIC - select PINCTRL_IMX27 +comment "ARM1136 platforms" config SOC_IMX31 - bool + bool "i.MX31 support" select CPU_V6 select MXC_AVIC + help + This enables support for Freescale i.MX31 processor config SOC_IMX35 - bool - select ARCH_MXC_IOMUX_V3 + bool "i.MX35 support" select MXC_AVIC select PINCTRL_IMX35 - -if ARCH_MULTI_V5 - -comment "MX21 platforms:" - -config MACH_MX21ADS - bool "MX21ADS platform" - select IMX_HAVE_PLATFORM_IMX_FB - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_MXC_MMC - select IMX_HAVE_PLATFORM_MXC_NAND - select SOC_IMX21 - help - Include support for MX21ADS platform. This includes specific - configurations for the board and its peripherals. - -comment "MX27 platforms:" - -config MACH_MX27ADS - bool "MX27ADS platform" - select IMX_HAVE_PLATFORM_IMX_FB - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_MXC_MMC - select IMX_HAVE_PLATFORM_MXC_NAND - select IMX_HAVE_PLATFORM_MXC_W1 - select SOC_IMX27 - help - Include support for MX27ADS platform. This includes specific - configurations for the board and its peripherals. - -config MACH_MX27_3DS - bool "MX27PDK platform" - select IMX_HAVE_PLATFORM_FSL_USB2_UDC - select IMX_HAVE_PLATFORM_IMX2_WDT - select IMX_HAVE_PLATFORM_IMX_FB - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_KEYPAD - select IMX_HAVE_PLATFORM_IMX_SSI - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_MX2_CAMERA - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_MMC - select IMX_HAVE_PLATFORM_SPI_IMX - select MXC_DEBUG_BOARD - select USB_ULPI_VIEWPORT if USB_ULPI - select SOC_IMX27 - help - Include support for MX27PDK platform. This includes specific - configurations for the board and its peripherals. - -config MACH_IMX27_VISSTRIM_M10 - bool "Vista Silicon i.MX27 Visstrim_m10" - select IMX_HAVE_PLATFORM_GPIO_KEYS - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_SSI - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_MX2_CAMERA - select IMX_HAVE_PLATFORM_MX2_EMMA - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_MMC - select LEDS_GPIO_REGISTER - select SOC_IMX27 - help - Include support for Visstrim_m10 platform and its different variants. - This includes specific configurations for the board and its - peripherals. - -config MACH_PCA100 - bool "Phytec phyCARD-s (pca100)" - select IMX_HAVE_PLATFORM_FSL_USB2_UDC - select IMX_HAVE_PLATFORM_IMX2_WDT - select IMX_HAVE_PLATFORM_IMX_FB - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_SSI - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_MMC - select IMX_HAVE_PLATFORM_MXC_NAND - select IMX_HAVE_PLATFORM_MXC_W1 - select IMX_HAVE_PLATFORM_SPI_IMX - select USB_ULPI_VIEWPORT if USB_ULPI - select SOC_IMX27 - help - Include support for phyCARD-s (aka pca100) platform. This - includes specific configurations for the module and its peripherals. - -config MACH_IMX27_DT - bool "Support i.MX27 platforms from device tree" - select SOC_IMX27 - help - Include support for Freescale i.MX27 based platforms - using the device tree for discovery - -endif - -if ARCH_MULTI_V6 - -comment "MX31 platforms:" - -config MACH_MX31ADS - bool "Support MX31ADS platforms" - default y - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_SSI - select IMX_HAVE_PLATFORM_IMX_UART - select SOC_IMX31 - help - Include support for MX31ADS platform. This includes specific - configurations for the board and its peripherals. - -config MACH_MX31ADS_WM1133_EV1 - bool "Support Wolfson Microelectronics 1133-EV1 module" - depends on MACH_MX31ADS - depends on MFD_WM8350_I2C - depends on REGULATOR_WM8350 = y help - Include support for the Wolfson Microelectronics 1133-EV1 PMU - and audio module for the MX31ADS platform. - -config MACH_MX31LILLY - bool "Support MX31 LILLY-1131 platforms (INCO startec)" - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_IPU_CORE - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_MMC - select IMX_HAVE_PLATFORM_SPI_IMX - select USB_ULPI_VIEWPORT if USB_ULPI - select SOC_IMX31 - help - Include support for mx31 based LILLY1131 modules. This includes - specific configurations for the board and its peripherals. - -config MACH_MX31LITE - bool "Support MX31 LITEKIT (LogicPD)" - select IMX_HAVE_PLATFORM_IMX2_WDT - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_MMC - select IMX_HAVE_PLATFORM_MXC_NAND - select IMX_HAVE_PLATFORM_MXC_RTC - select IMX_HAVE_PLATFORM_SPI_IMX - select LEDS_GPIO_REGISTER - select USB_ULPI_VIEWPORT if USB_ULPI - select SOC_IMX31 - help - Include support for MX31 LITEKIT platform. This includes specific - configurations for the board and its peripherals. - -config MACH_PCM037 - bool "Support Phytec pcm037 (i.MX31) platforms" - select IMX_HAVE_PLATFORM_FSL_USB2_UDC - select IMX_HAVE_PLATFORM_IMX2_WDT - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_IPU_CORE - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_MMC - select IMX_HAVE_PLATFORM_MXC_NAND - select IMX_HAVE_PLATFORM_MXC_W1 - select USB_ULPI_VIEWPORT if USB_ULPI - select SOC_IMX31 - help - Include support for Phytec pcm037 platform. This includes - specific configurations for the board and its peripherals. - -config MACH_PCM037_EET - bool "Support pcm037 EET board extensions" - depends on MACH_PCM037 - select IMX_HAVE_PLATFORM_GPIO_KEYS - select IMX_HAVE_PLATFORM_SPI_IMX - help - Add support for PCM037 EET baseboard extensions. If you are using the - OLED display with EET, use "video=mx3fb:CMEL-OLED" kernel - command-line parameter. - -config MACH_MX31_3DS - bool "Support MX31PDK (3DS)" - select IMX_HAVE_PLATFORM_FSL_USB2_UDC - select IMX_HAVE_PLATFORM_IMX2_WDT - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_KEYPAD - select IMX_HAVE_PLATFORM_IMX_SSI - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_IPU_CORE - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_MMC - select IMX_HAVE_PLATFORM_MXC_NAND - select IMX_HAVE_PLATFORM_SPI_IMX - select MXC_DEBUG_BOARD - select USB_ULPI_VIEWPORT if USB_ULPI - select SOC_IMX31 - help - Include support for MX31PDK (3DS) platform. This includes specific - configurations for the board and its peripherals. - -config MACH_MX31_3DS_MXC_NAND_USE_BBT - bool "Make the MXC NAND driver use the in flash Bad Block Table" - depends on MACH_MX31_3DS - depends on MTD_NAND_MXC - help - Enable this if you want that the MXC NAND driver uses the in flash - Bad Block Table to know what blocks are bad instead of scanning the - entire flash looking for bad block markers. - -config MACH_MX31MOBOARD - bool "Support mx31moboard platforms (EPFL Mobots group)" - select IMX_HAVE_PLATFORM_FSL_USB2_UDC - select IMX_HAVE_PLATFORM_IMX2_WDT - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_SSI - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_IPU_CORE - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_MMC - select IMX_HAVE_PLATFORM_SPI_IMX - select LEDS_GPIO_REGISTER - select USB_ULPI_VIEWPORT if USB_ULPI - select SOC_IMX31 - help - Include support for mx31moboard platform. This includes specific - configurations for the board and its peripherals. - -config MACH_QONG - bool "Support Dave/DENX QongEVB-LITE platform" - select IMX_HAVE_PLATFORM_IMX2_WDT - select IMX_HAVE_PLATFORM_IMX_UART - select SOC_IMX31 - help - Include support for Dave/DENX QongEVB-LITE platform. This includes - specific configurations for the board and its peripherals. - -config MACH_ARMADILLO5X0 - bool "Support Atmark Armadillo-500 Development Base Board" - select IMX_HAVE_PLATFORM_GPIO_KEYS - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_IPU_CORE - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_MMC - select IMX_HAVE_PLATFORM_MXC_NAND - select USB_ULPI_VIEWPORT if USB_ULPI - select SOC_IMX31 - help - Include support for Atmark Armadillo-500 platform. This includes - specific configurations for the board and its peripherals. - -config MACH_KZM_ARM11_01 - bool "Support KZM-ARM11-01(Kyoto Microcomputer)" - select IMX_HAVE_PLATFORM_IMX_UART - select SOC_IMX31 - help - Include support for KZM-ARM11-01. This includes specific - configurations for the board and its peripherals. - -config MACH_BUG - bool "Support Buglabs BUGBase platform" - default y - select IMX_HAVE_PLATFORM_IMX_UART - select SOC_IMX31 - help - Include support for BUGBase 1.3 platform. This includes specific - configurations for the board and its peripherals. - -config MACH_IMX31_DT - bool "Support i.MX31 platforms from device tree" - select SOC_IMX31 - help - Include support for Freescale i.MX31 based platforms - using the device tree for discovery. - -comment "MX35 platforms:" - -config MACH_IMX35_DT - bool "Support i.MX35 platforms from device tree" - select SOC_IMX35 - help - Include support for Freescale i.MX35 based platforms - using the device tree for discovery. - -config MACH_PCM043 - bool "Support Phytec pcm043 (i.MX35) platforms" - select IMX_HAVE_PLATFORM_FLEXCAN - select IMX_HAVE_PLATFORM_FSL_USB2_UDC - select IMX_HAVE_PLATFORM_IMX2_WDT - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_SSI - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_IPU_CORE - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_NAND - select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX - select USB_ULPI_VIEWPORT if USB_ULPI - select SOC_IMX35 - help - Include support for Phytec pcm043 platform. This includes - specific configurations for the board and its peripherals. - -config MACH_MX35_3DS - bool "Support MX35PDK platform" - select IMX_HAVE_PLATFORM_FSL_USB2_UDC - select IMX_HAVE_PLATFORM_IMX2_WDT - select IMX_HAVE_PLATFORM_IMX_FB - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_IPU_CORE - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_NAND - select IMX_HAVE_PLATFORM_MXC_RTC - select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX - select MXC_DEBUG_BOARD - select SOC_IMX35 - help - Include support for MX35PDK platform. This includes specific - configurations for the board and its peripherals. - -config MACH_VPR200 - bool "Support VPR200 platform" - select IMX_HAVE_PLATFORM_FSL_USB2_UDC - select IMX_HAVE_PLATFORM_GPIO_KEYS - select IMX_HAVE_PLATFORM_IMX2_WDT - select IMX_HAVE_PLATFORM_IMX_I2C - select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_IPU_CORE - select IMX_HAVE_PLATFORM_MXC_EHCI - select IMX_HAVE_PLATFORM_MXC_NAND - select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX - select SOC_IMX35 - help - Include support for VPR200 platform. This includes specific - configurations for the board and its peripherals. + This enables support for Freescale i.MX31 processor endif -comment "Device tree only" - if ARCH_MULTI_V4T config SOC_IMX1 @@ -428,12 +83,20 @@ if ARCH_MULTI_V5 config SOC_IMX25 bool "i.MX25 support" - select ARCH_MXC_IOMUX_V3 select CPU_ARM926T select MXC_AVIC select PINCTRL_IMX25 help This enables support for Freescale i.MX25 processor + +config SOC_IMX27 + bool "i.MX27 support" + select CPU_ARM926T + select MXC_AVIC + select PINCTRL_IMX27 + help + This enables support for Freescale i.MX27 processor + endif if ARCH_MULTI_V7 @@ -541,10 +204,10 @@ config SOC_LS1021A endif -comment "Cortex-A/Cortex-M asymmetric multiprocessing platforms" - if ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M +comment "Cortex-A/Cortex-M asymmetric multiprocessing platforms" + config SOC_IMX7D_CA7 bool select ARM_GIC @@ -607,6 +270,4 @@ endchoice endif -source "arch/arm/mach-imx/devices/Kconfig" - endif diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index e7364e6c8c6b..9cebd360d58e 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -1,22 +1,16 @@ # SPDX-License-Identifier: GPL-2.0 obj-y := cpu.o system.o irq-common.o -obj-$(CONFIG_SOC_IMX21) += mm-imx21.o - obj-$(CONFIG_SOC_IMX25) += cpu-imx25.o mach-imx25.o pm-imx25.o -obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o -obj-$(CONFIG_SOC_IMX27) += mm-imx27.o ehci-imx27.o +obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o mach-imx27.o -obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o iomux-imx31.o ehci-imx31.o -obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o ehci-imx35.o +obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o mach-imx31.o +obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o mach-imx35.o imx5-pm-$(CONFIG_PM) += pm-imx5.o obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o $(imx5-pm-y) -obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o -obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o - obj-$(CONFIG_MXC_TZIC) += tzic.o obj-$(CONFIG_MXC_AVIC) += avic.o @@ -37,37 +31,6 @@ obj-y += ssi-fiq.o obj-y += ssi-fiq-ksym.o endif -# i.MX21 based machines -obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o - -# i.MX27 based machines -obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o -obj-$(CONFIG_MACH_MX27_3DS) += mach-mx27_3ds.o -obj-$(CONFIG_MACH_IMX27_VISSTRIM_M10) += mach-imx27_visstrim_m10.o -obj-$(CONFIG_MACH_PCA100) += mach-pca100.o -obj-$(CONFIG_MACH_IMX27_DT) += imx27-dt.o - -# i.MX31 based machines -obj-$(CONFIG_MACH_MX31ADS) += mach-mx31ads.o -obj-$(CONFIG_MACH_MX31LILLY) += mach-mx31lilly.o mx31lilly-db.o -obj-$(CONFIG_MACH_MX31LITE) += mach-mx31lite.o mx31lite-db.o -obj-$(CONFIG_MACH_PCM037) += mach-pcm037.o -obj-$(CONFIG_MACH_PCM037_EET) += mach-pcm037_eet.o -obj-$(CONFIG_MACH_MX31_3DS) += mach-mx31_3ds.o -obj-$(CONFIG_MACH_MX31MOBOARD) += mach-mx31moboard.o mx31moboard-devboard.o \ - mx31moboard-marxbot.o mx31moboard-smartbot.o -obj-$(CONFIG_MACH_QONG) += mach-qong.o -obj-$(CONFIG_MACH_ARMADILLO5X0) += mach-armadillo5x0.o -obj-$(CONFIG_MACH_KZM_ARM11_01) += mach-kzm_arm11_01.o -obj-$(CONFIG_MACH_BUG) += mach-bug.o -obj-$(CONFIG_MACH_IMX31_DT) += imx31-dt.o - -# i.MX35 based machines -obj-$(CONFIG_MACH_PCM043) += mach-pcm043.o -obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o -obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o -obj-$(CONFIG_MACH_IMX35_DT) += imx35-dt.o - obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o @@ -105,5 +68,3 @@ obj-$(CONFIG_SOC_IMX53) += mach-imx53.o obj-$(CONFIG_SOC_VF610) += mach-vf610.o obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o - -obj-y += devices/ diff --git a/arch/arm/mach-imx/board-mx31lilly.h b/arch/arm/mach-imx/board-mx31lilly.h deleted file mode 100644 index 3508c598c588..000000000000 --- a/arch/arm/mach-imx/board-mx31lilly.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2009 Daniel Mack <daniel@caiaq.de> - * - * Based on code for mobots boards, - * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group - */ - -#ifndef __ASM_ARCH_MXC_BOARD_MX31LILLY_H__ -#define __ASM_ARCH_MXC_BOARD_MX31LILLY_H__ - -#ifndef __ASSEMBLY__ - -enum mx31lilly_boards { - MX31LILLY_NOBOARD = 0, - MX31LILLY_DB = 1, -}; - -/* - * This CPU module needs a baseboard to work. After basic initializing - * its own devices, it calls the baseboard's init function. - */ - -extern void mx31lilly_db_init(void); - -#endif - -#endif /* __ASM_ARCH_MXC_BOARD_MX31LILLY_H__ */ diff --git a/arch/arm/mach-imx/board-mx31lite.h b/arch/arm/mach-imx/board-mx31lite.h deleted file mode 100644 index 7d7c6219b25f..000000000000 --- a/arch/arm/mach-imx/board-mx31lite.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2009 Daniel Mack <daniel@caiaq.de> - * - * Based on code for mobots boards, - * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group - */ - -#ifndef __ASM_ARCH_MXC_BOARD_MX31LITE_H__ -#define __ASM_ARCH_MXC_BOARD_MX31LITE_H__ - -#ifndef __ASSEMBLY__ - -enum mx31lite_boards { - MX31LITE_NOBOARD = 0, - MX31LITE_DB = 1, -}; - -/* - * This CPU module needs a baseboard to work. After basic initializing - * its own devices, it calls the baseboard's init function. - */ - -extern void mx31lite_db_init(void); - -#endif - -#endif /* __ASM_ARCH_MXC_BOARD_MX31LITE_H__ */ diff --git a/arch/arm/mach-imx/board-mx31moboard.h b/arch/arm/mach-imx/board-mx31moboard.h deleted file mode 100644 index 6f3ff4d4ebc1..000000000000 --- a/arch/arm/mach-imx/board-mx31moboard.h +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group - */ - -#ifndef __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ -#define __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ - -#ifndef __ASSEMBLY__ - -enum mx31moboard_boards { - MX31NOBOARD = 0, - MX31DEVBOARD = 1, - MX31MARXBOT = 2, - MX31SMARTBOT = 3, - MX31EYEBOT = 4, -}; - -/* - * This CPU module needs a baseboard to work. After basic initializing - * its own devices, it calls the baseboard's init function. - */ - -extern void mx31moboard_devboard_init(void); -extern void mx31moboard_marxbot_init(void); -extern void mx31moboard_smartbot_init(int board); - -#endif - -#endif /* __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ */ diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 72c3fcc32910..2d76e2c6c99e 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -17,29 +17,14 @@ struct device_node; enum mxc_cpu_pwr_mode; struct of_device_id; -void mx21_map_io(void); -void mx27_map_io(void); void mx31_map_io(void); void mx35_map_io(void); void imx21_init_early(void); -void imx27_init_early(void); void imx31_init_early(void); void imx35_init_early(void); void mxc_init_irq(void __iomem *); -void mx21_init_irq(void); -void mx27_init_irq(void); void mx31_init_irq(void); void mx35_init_irq(void); -void imx21_soc_init(void); -void imx27_soc_init(void); -void imx31_soc_init(void); -void imx35_soc_init(void); -int mx21_clocks_init(unsigned long lref, unsigned long fref); -int mx27_clocks_init(unsigned long fref); -int mx31_clocks_init(unsigned long fref); -int mx35_clocks_init(void); -struct platform_device *mxc_register_gpio(char *name, int id, - resource_size_t iobase, resource_size_t iosize, int irq, int irq_high); void mxc_set_cpu_type(unsigned int type); void mxc_restart(enum reboot_mode, const char *); void mxc_arch_reset_init(void __iomem *); diff --git a/arch/arm/mach-imx/cpu-imx27.c b/arch/arm/mach-imx/cpu-imx27.c index a969aa71b60f..bf70e13bbe9e 100644 --- a/arch/arm/mach-imx/cpu-imx27.c +++ b/arch/arm/mach-imx/cpu-imx27.c @@ -9,6 +9,7 @@ */ #include <linux/io.h> +#include <linux/of_address.h> #include <linux/module.h> #include "hardware.h" @@ -17,16 +18,23 @@ static int mx27_cpu_rev = -1; static int mx27_cpu_partnumber; #define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */ +#define SYSCTRL_OFFSET 0x800 /* Offset from CCM base address */ static int mx27_read_cpu_rev(void) { + void __iomem *ccm_base; + struct device_node *np; u32 val; + + np = of_find_compatible_node(NULL, NULL, "fsl,imx27-ccm"); + ccm_base = of_iomap(np, 0); + BUG_ON(!ccm_base); /* * now we have access to the IO registers. As we need * the silicon revision very early we read it here to * avoid any further hooks */ - val = imx_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR + SYS_CHIP_ID)); + val = imx_readl(ccm_base + SYSCTRL_OFFSET + SYS_CHIP_ID); mx27_cpu_partnumber = (int)((val >> 12) & 0xFFFF); diff --git a/arch/arm/mach-imx/cpu-imx31.c b/arch/arm/mach-imx/cpu-imx31.c index 3ee684b71006..b9c24b851d1a 100644 --- a/arch/arm/mach-imx/cpu-imx31.c +++ b/arch/arm/mach-imx/cpu-imx31.c @@ -6,6 +6,7 @@ */ #include <linux/module.h> +#include <linux/of_address.h> #include <linux/io.h> #include "common.h" @@ -32,10 +33,16 @@ static struct { static int mx31_read_cpu_rev(void) { + void __iomem *iim_base; + struct device_node *np; u32 i, srev; + np = of_find_compatible_node(NULL, NULL, "fsl,imx31-iim"); + iim_base = of_iomap(np, 0); + BUG_ON(!iim_base); + /* read SREV register from IIM module */ - srev = imx_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV)); + srev = imx_readl(iim_base + MXC_IIMSREV); srev &= 0xff; for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++) diff --git a/arch/arm/mach-imx/cpu-imx35.c b/arch/arm/mach-imx/cpu-imx35.c index ebb3cdabd506..80e7d8ab9f1b 100644 --- a/arch/arm/mach-imx/cpu-imx35.c +++ b/arch/arm/mach-imx/cpu-imx35.c @@ -5,6 +5,7 @@ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> */ #include <linux/module.h> +#include <linux/of_address.h> #include <linux/io.h> #include "hardware.h" @@ -14,9 +15,15 @@ static int mx35_cpu_rev = -1; static int mx35_read_cpu_rev(void) { + void __iomem *iim_base; + struct device_node *np; u32 rev; - rev = imx_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV)); + np = of_find_compatible_node(NULL, NULL, "fsl,imx35-iim"); + iim_base = of_iomap(np, 0); + BUG_ON(!iim_base); + + rev = imx_readl(iim_base + MXC_IIMSREV); switch (rev) { case 0x00: return IMX_CHIP_REVISION_1_0; diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c index 24dd5bbe60e4..094337dc1bc7 100644 --- a/arch/arm/mach-imx/cpuidle-imx6q.c +++ b/arch/arm/mach-imx/cpuidle-imx6q.c @@ -24,7 +24,9 @@ static int imx6q_enter_wait(struct cpuidle_device *dev, imx6_set_lpm(WAIT_UNCLOCKED); raw_spin_unlock(&cpuidle_lock); + rcu_idle_enter(); cpu_do_idle(); + rcu_idle_exit(); raw_spin_lock(&cpuidle_lock); if (num_idle_cpus-- == num_online_cpus()) @@ -44,7 +46,7 @@ static struct cpuidle_driver imx6q_cpuidle_driver = { { .exit_latency = 50, .target_residency = 75, - .flags = CPUIDLE_FLAG_TIMER_STOP, + .flags = CPUIDLE_FLAG_TIMER_STOP | CPUIDLE_FLAG_RCU_IDLE, .enter = imx6q_enter_wait, .name = "WAIT", .desc = "Clock off", diff --git a/arch/arm/mach-imx/devices-imx21.h b/arch/arm/mach-imx/devices-imx21.h deleted file mode 100644 index 3679d1de84d4..000000000000 --- a/arch/arm/mach-imx/devices-imx21.h +++ /dev/null @@ -1,56 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "devices/devices-common.h" - -extern const struct imx_imx21_hcd_data imx21_imx21_hcd_data; -#define imx21_add_imx21_hcd(pdata) \ - imx_add_imx21_hcd(&imx21_imx21_hcd_data, pdata) - -extern const struct imx_imx2_wdt_data imx21_imx2_wdt_data; -#define imx21_add_imx2_wdt() \ - imx_add_imx2_wdt(&imx21_imx2_wdt_data) - -extern const struct imx_imx_fb_data imx21_imx_fb_data; -#define imx21_add_imx_fb(pdata) \ - imx_add_imx_fb(&imx21_imx_fb_data, pdata) - -extern const struct imx_imx_i2c_data imx21_imx_i2c_data; -#define imx21_add_imx_i2c(pdata) \ - imx_add_imx_i2c(&imx21_imx_i2c_data, pdata) - -extern const struct imx_imx_keypad_data imx21_imx_keypad_data; -#define imx21_add_imx_keypad(pdata) \ - imx_add_imx_keypad(&imx21_imx_keypad_data, pdata) - -extern const struct imx_imx_ssi_data imx21_imx_ssi_data[]; -#define imx21_add_imx_ssi(id, pdata) \ - imx_add_imx_ssi(&imx21_imx_ssi_data[id], pdata) - -extern const struct imx_imx_uart_1irq_data imx21_imx_uart_data[]; -#define imx21_add_imx_uart(id, pdata) \ - imx_add_imx_uart_1irq(&imx21_imx_uart_data[id], pdata) -#define imx21_add_imx_uart0(pdata) imx21_add_imx_uart(0, pdata) -#define imx21_add_imx_uart1(pdata) imx21_add_imx_uart(1, pdata) -#define imx21_add_imx_uart2(pdata) imx21_add_imx_uart(2, pdata) -#define imx21_add_imx_uart3(pdata) imx21_add_imx_uart(3, pdata) - -extern const struct imx_mxc_mmc_data imx21_mxc_mmc_data[]; -#define imx21_add_mxc_mmc(id, pdata) \ - imx_add_mxc_mmc(&imx21_mxc_mmc_data[id], pdata) - -extern const struct imx_mxc_nand_data imx21_mxc_nand_data; -#define imx21_add_mxc_nand(pdata) \ - imx_add_mxc_nand(&imx21_mxc_nand_data, pdata) - -extern const struct imx_mxc_w1_data imx21_mxc_w1_data; -#define imx21_add_mxc_w1() \ - imx_add_mxc_w1(&imx21_mxc_w1_data) - -extern const struct imx_spi_imx_data imx21_cspi_data[]; -#define imx21_add_cspi(id, pdata) \ - imx_add_spi_imx(&imx21_cspi_data[id], pdata) -#define imx21_add_spi_imx0(pdata) imx21_add_cspi(0, pdata) -#define imx21_add_spi_imx1(pdata) imx21_add_cspi(1, pdata) diff --git a/arch/arm/mach-imx/devices-imx27.h b/arch/arm/mach-imx/devices-imx27.h deleted file mode 100644 index 583a1d773d68..000000000000 --- a/arch/arm/mach-imx/devices-imx27.h +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "devices/devices-common.h" - -extern const struct imx_fec_data imx27_fec_data; -#define imx27_add_fec(pdata) \ - imx_add_fec(&imx27_fec_data, pdata) - -extern const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data; -#define imx27_add_fsl_usb2_udc(pdata) \ - imx_add_fsl_usb2_udc(&imx27_fsl_usb2_udc_data, pdata) - -extern const struct imx_imx27_coda_data imx27_coda_data; -#define imx27_add_coda() \ - imx_add_imx27_coda(&imx27_coda_data) - -extern const struct imx_imx2_wdt_data imx27_imx2_wdt_data; -#define imx27_add_imx2_wdt() \ - imx_add_imx2_wdt(&imx27_imx2_wdt_data) - -extern const struct imx_imx_fb_data imx27_imx_fb_data; -#define imx27_add_imx_fb(pdata) \ - imx_add_imx_fb(&imx27_imx_fb_data, pdata) - -extern const struct imx_imx_i2c_data imx27_imx_i2c_data[]; -#define imx27_add_imx_i2c(id, pdata) \ - imx_add_imx_i2c(&imx27_imx_i2c_data[id], pdata) - -extern const struct imx_imx_keypad_data imx27_imx_keypad_data; -#define imx27_add_imx_keypad(pdata) \ - imx_add_imx_keypad(&imx27_imx_keypad_data, pdata) - -extern const struct imx_imx_ssi_data imx27_imx_ssi_data[]; -#define imx27_add_imx_ssi(id, pdata) \ - imx_add_imx_ssi(&imx27_imx_ssi_data[id], pdata) - -extern const struct imx_imx_uart_1irq_data imx27_imx_uart_data[]; -#define imx27_add_imx_uart(id, pdata) \ - imx_add_imx_uart_1irq(&imx27_imx_uart_data[id], pdata) -#define imx27_add_imx_uart0(pdata) imx27_add_imx_uart(0, pdata) -#define imx27_add_imx_uart1(pdata) imx27_add_imx_uart(1, pdata) -#define imx27_add_imx_uart2(pdata) imx27_add_imx_uart(2, pdata) -#define imx27_add_imx_uart3(pdata) imx27_add_imx_uart(3, pdata) -#define imx27_add_imx_uart4(pdata) imx27_add_imx_uart(4, pdata) -#define imx27_add_imx_uart5(pdata) imx27_add_imx_uart(5, pdata) - -extern const struct imx_mx2_camera_data imx27_mx2_camera_data; -#define imx27_add_mx2_camera(pdata) \ - imx_add_mx2_camera(&imx27_mx2_camera_data, pdata) - -extern const struct imx_mx2_emma_data imx27_mx2_emmaprp_data; -#define imx27_add_mx2_emmaprp() \ - imx_add_mx2_emmaprp(&imx27_mx2_emmaprp_data) - -extern const struct imx_mxc_ehci_data imx27_mxc_ehci_otg_data; -#define imx27_add_mxc_ehci_otg(pdata) \ - imx_add_mxc_ehci(&imx27_mxc_ehci_otg_data, pdata) -extern const struct imx_mxc_ehci_data imx27_mxc_ehci_hs_data[]; -#define imx27_add_mxc_ehci_hs(id, pdata) \ - imx_add_mxc_ehci(&imx27_mxc_ehci_hs_data[id - 1], pdata) - -extern const struct imx_mxc_mmc_data imx27_mxc_mmc_data[]; -#define imx27_add_mxc_mmc(id, pdata) \ - imx_add_mxc_mmc(&imx27_mxc_mmc_data[id], pdata) - -extern const struct imx_mxc_nand_data imx27_mxc_nand_data; -#define imx27_add_mxc_nand(pdata) \ - imx_add_mxc_nand(&imx27_mxc_nand_data, pdata) - -extern const struct imx_mxc_w1_data imx27_mxc_w1_data; -#define imx27_add_mxc_w1() \ - imx_add_mxc_w1(&imx27_mxc_w1_data) - -extern const struct imx_spi_imx_data imx27_cspi_data[]; -#define imx27_add_cspi(id, gtable) \ - imx_add_spi_imx(&imx27_cspi_data[id], gtable) -#define imx27_add_spi_imx0(gtable) imx27_add_cspi(0, gtable) -#define imx27_add_spi_imx1(gtable) imx27_add_cspi(1, gtable) -#define imx27_add_spi_imx2(gtable) imx27_add_cspi(2, gtable) - -extern const struct imx_pata_imx_data imx27_pata_imx_data; -#define imx27_add_pata_imx() \ - imx_add_pata_imx(&imx27_pata_imx_data) diff --git a/arch/arm/mach-imx/devices-imx31.h b/arch/arm/mach-imx/devices-imx31.h deleted file mode 100644 index f7cc62372532..000000000000 --- a/arch/arm/mach-imx/devices-imx31.h +++ /dev/null @@ -1,80 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "devices/devices-common.h" - -extern const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data; -#define imx31_add_fsl_usb2_udc(pdata) \ - imx_add_fsl_usb2_udc(&imx31_fsl_usb2_udc_data, pdata) - -extern const struct imx_imx2_wdt_data imx31_imx2_wdt_data; -#define imx31_add_imx2_wdt() \ - imx_add_imx2_wdt(&imx31_imx2_wdt_data) - -extern const struct imx_imx_i2c_data imx31_imx_i2c_data[]; -#define imx31_add_imx_i2c(id, pdata) \ - imx_add_imx_i2c(&imx31_imx_i2c_data[id], pdata) -#define imx31_add_imx_i2c0(pdata) imx31_add_imx_i2c(0, pdata) -#define imx31_add_imx_i2c1(pdata) imx31_add_imx_i2c(1, pdata) -#define imx31_add_imx_i2c2(pdata) imx31_add_imx_i2c(2, pdata) - -extern const struct imx_imx_keypad_data imx31_imx_keypad_data; -#define imx31_add_imx_keypad(pdata) \ - imx_add_imx_keypad(&imx31_imx_keypad_data, pdata) - -extern const struct imx_imx_ssi_data imx31_imx_ssi_data[]; -#define imx31_add_imx_ssi(id, pdata) \ - imx_add_imx_ssi(&imx31_imx_ssi_data[id], pdata) - -extern const struct imx_imx_uart_1irq_data imx31_imx_uart_data[]; -#define imx31_add_imx_uart(id, pdata) \ - imx_add_imx_uart_1irq(&imx31_imx_uart_data[id], pdata) -#define imx31_add_imx_uart0(pdata) imx31_add_imx_uart(0, pdata) -#define imx31_add_imx_uart1(pdata) imx31_add_imx_uart(1, pdata) -#define imx31_add_imx_uart2(pdata) imx31_add_imx_uart(2, pdata) -#define imx31_add_imx_uart3(pdata) imx31_add_imx_uart(3, pdata) -#define imx31_add_imx_uart4(pdata) imx31_add_imx_uart(4, pdata) - -extern const struct imx_ipu_core_data imx31_ipu_core_data; -#define imx31_add_ipu_core() \ - imx_add_ipu_core(&imx31_ipu_core_data) -#define imx31_alloc_mx3_camera(pdata) \ - imx_alloc_mx3_camera(&imx31_ipu_core_data, pdata) -#define imx31_add_mx3_sdc_fb(pdata) \ - imx_add_mx3_sdc_fb(&imx31_ipu_core_data, pdata) - -extern const struct imx_mxc_ehci_data imx31_mxc_ehci_otg_data; -#define imx31_add_mxc_ehci_otg(pdata) \ - imx_add_mxc_ehci(&imx31_mxc_ehci_otg_data, pdata) -extern const struct imx_mxc_ehci_data imx31_mxc_ehci_hs_data[]; -#define imx31_add_mxc_ehci_hs(id, pdata) \ - imx_add_mxc_ehci(&imx31_mxc_ehci_hs_data[id - 1], pdata) - -extern const struct imx_mxc_mmc_data imx31_mxc_mmc_data[]; -#define imx31_add_mxc_mmc(id, pdata) \ - imx_add_mxc_mmc(&imx31_mxc_mmc_data[id], pdata) - -extern const struct imx_mxc_nand_data imx31_mxc_nand_data; -#define imx31_add_mxc_nand(pdata) \ - imx_add_mxc_nand(&imx31_mxc_nand_data, pdata) - -extern const struct imx_mxc_rtc_data imx31_mxc_rtc_data; -#define imx31_add_mxc_rtc() \ - imx_add_mxc_rtc(&imx31_mxc_rtc_data) - -extern const struct imx_mxc_w1_data imx31_mxc_w1_data; -#define imx31_add_mxc_w1() \ - imx_add_mxc_w1(&imx31_mxc_w1_data) - -extern const struct imx_spi_imx_data imx31_cspi_data[]; -#define imx31_add_cspi(id, gtable) \ - imx_add_spi_imx(&imx31_cspi_data[id], gtable) -#define imx31_add_spi_imx0(gtable) imx31_add_cspi(0, gtable) -#define imx31_add_spi_imx1(gtable) imx31_add_cspi(1, gtable) -#define imx31_add_spi_imx2(gtable) imx31_add_cspi(2, gtable) - -extern const struct imx_pata_imx_data imx31_pata_imx_data; -#define imx31_add_pata_imx() \ - imx_add_pata_imx(&imx31_pata_imx_data) diff --git a/arch/arm/mach-imx/devices-imx35.h b/arch/arm/mach-imx/devices-imx35.h deleted file mode 100644 index 1b1bdadea15b..000000000000 --- a/arch/arm/mach-imx/devices-imx35.h +++ /dev/null @@ -1,87 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "devices/devices-common.h" - -extern const struct imx_fec_data imx35_fec_data; -#define imx35_add_fec(pdata) \ - imx_add_fec(&imx35_fec_data, pdata) - -extern const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data; -#define imx35_add_fsl_usb2_udc(pdata) \ - imx_add_fsl_usb2_udc(&imx35_fsl_usb2_udc_data, pdata) - -extern const struct imx_flexcan_data imx35_flexcan_data[]; -#define imx35_add_flexcan(id) \ - imx_add_flexcan(&imx35_flexcan_data[id]) -#define imx35_add_flexcan0() imx35_add_flexcan(0) -#define imx35_add_flexcan1() imx35_add_flexcan(1) - -extern const struct imx_imx2_wdt_data imx35_imx2_wdt_data; -#define imx35_add_imx2_wdt() \ - imx_add_imx2_wdt(&imx35_imx2_wdt_data) - -extern const struct imx_imx_i2c_data imx35_imx_i2c_data[]; -#define imx35_add_imx_i2c(id, pdata) \ - imx_add_imx_i2c(&imx35_imx_i2c_data[id], pdata) -#define imx35_add_imx_i2c0(pdata) imx35_add_imx_i2c(0, pdata) -#define imx35_add_imx_i2c1(pdata) imx35_add_imx_i2c(1, pdata) -#define imx35_add_imx_i2c2(pdata) imx35_add_imx_i2c(2, pdata) - -extern const struct imx_imx_keypad_data imx35_imx_keypad_data; -#define imx35_add_imx_keypad(pdata) \ - imx_add_imx_keypad(&imx35_imx_keypad_data, pdata) - -extern const struct imx_imx_ssi_data imx35_imx_ssi_data[]; -#define imx35_add_imx_ssi(id, pdata) \ - imx_add_imx_ssi(&imx35_imx_ssi_data[id], pdata) - -extern const struct imx_imx_uart_1irq_data imx35_imx_uart_data[]; -#define imx35_add_imx_uart(id, pdata) \ - imx_add_imx_uart_1irq(&imx35_imx_uart_data[id], pdata) -#define imx35_add_imx_uart0(pdata) imx35_add_imx_uart(0, pdata) -#define imx35_add_imx_uart1(pdata) imx35_add_imx_uart(1, pdata) -#define imx35_add_imx_uart2(pdata) imx35_add_imx_uart(2, pdata) - -extern const struct imx_ipu_core_data imx35_ipu_core_data; -#define imx35_add_ipu_core() \ - imx_add_ipu_core(&imx35_ipu_core_data) -#define imx35_alloc_mx3_camera(pdata) \ - imx_alloc_mx3_camera(&imx35_ipu_core_data, pdata) -#define imx35_add_mx3_sdc_fb(pdata) \ - imx_add_mx3_sdc_fb(&imx35_ipu_core_data, pdata) - -extern const struct imx_mxc_ehci_data imx35_mxc_ehci_otg_data; -#define imx35_add_mxc_ehci_otg(pdata) \ - imx_add_mxc_ehci(&imx35_mxc_ehci_otg_data, pdata) -extern const struct imx_mxc_ehci_data imx35_mxc_ehci_hs_data; -#define imx35_add_mxc_ehci_hs(pdata) \ - imx_add_mxc_ehci(&imx35_mxc_ehci_hs_data, pdata) - -extern const struct imx_mxc_nand_data imx35_mxc_nand_data; -#define imx35_add_mxc_nand(pdata) \ - imx_add_mxc_nand(&imx35_mxc_nand_data, pdata) - -extern const struct imx_mxc_rtc_data imx35_mxc_rtc_data; -#define imx35_add_mxc_rtc() \ - imx_add_mxc_rtc(&imx35_mxc_rtc_data) - -extern const struct imx_mxc_w1_data imx35_mxc_w1_data; -#define imx35_add_mxc_w1() \ - imx_add_mxc_w1(&imx35_mxc_w1_data) - -extern const struct imx_sdhci_esdhc_imx_data imx35_sdhci_esdhc_imx_data[]; -#define imx35_add_sdhci_esdhc_imx(id, pdata) \ - imx_add_sdhci_esdhc_imx(&imx35_sdhci_esdhc_imx_data[id], pdata) - -extern const struct imx_spi_imx_data imx35_cspi_data[]; -#define imx35_add_cspi(id, pdata) \ - imx_add_spi_imx(&imx35_cspi_data[id], pdata) -#define imx35_add_spi_imx0(pdata) imx35_add_cspi(0, pdata) -#define imx35_add_spi_imx1(pdata) imx35_add_cspi(1, pdata) - -extern const struct imx_pata_imx_data imx35_pata_imx_data; -#define imx35_add_pata_imx() \ - imx_add_pata_imx(&imx35_pata_imx_data) diff --git a/arch/arm/mach-imx/devices/Kconfig b/arch/arm/mach-imx/devices/Kconfig deleted file mode 100644 index fdca73d117e6..000000000000 --- a/arch/arm/mach-imx/devices/Kconfig +++ /dev/null @@ -1,71 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config IMX_HAVE_PLATFORM_FEC - bool - default y if SOC_IMX25 || SOC_IMX27 || SOC_IMX35 - -config IMX_HAVE_PLATFORM_FLEXCAN - bool - -config IMX_HAVE_PLATFORM_FSL_USB2_UDC - bool - -config IMX_HAVE_PLATFORM_GPIO_KEYS - bool - -config IMX_HAVE_PLATFORM_IMX21_HCD - bool - -config IMX_HAVE_PLATFORM_IMX27_CODA - bool - default y if SOC_IMX27 - -config IMX_HAVE_PLATFORM_IMX2_WDT - bool - -config IMX_HAVE_PLATFORM_IMX_FB - bool - -config IMX_HAVE_PLATFORM_IMX_I2C - bool - -config IMX_HAVE_PLATFORM_IMX_KEYPAD - bool - -config IMX_HAVE_PLATFORM_PATA_IMX - bool - -config IMX_HAVE_PLATFORM_IMX_SSI - bool - -config IMX_HAVE_PLATFORM_IMX_UART - bool - -config IMX_HAVE_PLATFORM_IPU_CORE - bool - -config IMX_HAVE_PLATFORM_MX2_CAMERA - bool - -config IMX_HAVE_PLATFORM_MX2_EMMA - bool - -config IMX_HAVE_PLATFORM_MXC_EHCI - bool - -config IMX_HAVE_PLATFORM_MXC_MMC - bool - -config IMX_HAVE_PLATFORM_MXC_NAND - bool - -config IMX_HAVE_PLATFORM_MXC_RTC - bool - -config IMX_HAVE_PLATFORM_MXC_W1 - bool - -config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX - bool - -config IMX_HAVE_PLATFORM_SPI_IMX - bool diff --git a/arch/arm/mach-imx/devices/Makefile b/arch/arm/mach-imx/devices/Makefile deleted file mode 100644 index e44758aaa11c..000000000000 --- a/arch/arm/mach-imx/devices/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-y := devices.o - -obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o -obj-y += platform-gpio-mxc.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX27_CODA) += platform-imx27-coda.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o -obj-y += platform-imx-dma.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_FB) += platform-imx-fb.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_KEYPAD) += platform-imx-keypad.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_PATA_IMX) += platform-pata_imx.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SSI) += platform-imx-ssi.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UART) += platform-imx-uart.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_IPU_CORE) += platform-ipu-core.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_MX2_CAMERA) += platform-mx2-camera.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI) += platform-mxc-ehci.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_MMC) += platform-mxc-mmc.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_NAND) += platform-mxc_nand.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RTC) += platform-mxc_rtc.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_MX2_EMMA) += platform-mx2-emma.o diff --git a/arch/arm/mach-imx/devices/devices-common.h b/arch/arm/mach-imx/devices/devices-common.h deleted file mode 100644 index 327a1de7dce1..000000000000 --- a/arch/arm/mach-imx/devices/devices-common.h +++ /dev/null @@ -1,293 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2009-2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/init.h> -#include <linux/gpio/machine.h> -#include <linux/platform_data/dma-imx-sdma.h> - -extern struct device mxc_aips_bus; -extern struct device mxc_ahb_bus; - -static inline struct platform_device *imx_add_platform_device_dmamask( - const char *name, int id, - const struct resource *res, unsigned int num_resources, - const void *data, size_t size_data, u64 dmamask) -{ - struct platform_device_info pdevinfo = { - .name = name, - .id = id, - .res = res, - .num_res = num_resources, - .data = data, - .size_data = size_data, - .dma_mask = dmamask, - }; - return platform_device_register_full(&pdevinfo); -} - -static inline struct platform_device *imx_add_platform_device( - const char *name, int id, - const struct resource *res, unsigned int num_resources, - const void *data, size_t size_data) -{ - return imx_add_platform_device_dmamask( - name, id, res, num_resources, data, size_data, 0); -} - -#include <linux/fec.h> -struct imx_fec_data { - const char *devid; - resource_size_t iobase; - resource_size_t irq; -}; -struct platform_device *__init imx_add_fec( - const struct imx_fec_data *data, - const struct fec_platform_data *pdata); - -struct imx_flexcan_data { - int id; - resource_size_t iobase; - resource_size_t iosize; - resource_size_t irq; -}; -struct platform_device *__init imx_add_flexcan( - const struct imx_flexcan_data *data); - -#include <linux/fsl_devices.h> -struct imx_fsl_usb2_udc_data { - const char *devid; - resource_size_t iobase; - resource_size_t irq; -}; -struct platform_device *__init imx_add_fsl_usb2_udc( - const struct imx_fsl_usb2_udc_data *data, - const struct fsl_usb2_platform_data *pdata); - -#include <linux/gpio_keys.h> -struct platform_device *__init imx_add_gpio_keys( - const struct gpio_keys_platform_data *pdata); - -#include <linux/platform_data/usb-mx2.h> -struct imx_imx21_hcd_data { - resource_size_t iobase; - resource_size_t irq; -}; -struct platform_device *__init imx_add_imx21_hcd( - const struct imx_imx21_hcd_data *data, - const struct mx21_usbh_platform_data *pdata); - -struct imx_imx27_coda_data { - resource_size_t iobase; - resource_size_t iosize; - resource_size_t irq; -}; -struct platform_device *__init imx_add_imx27_coda( - const struct imx_imx27_coda_data *data); - -struct imx_imx2_wdt_data { - int id; - resource_size_t iobase; - resource_size_t iosize; -}; -struct platform_device *__init imx_add_imx2_wdt( - const struct imx_imx2_wdt_data *data); - -struct imx_imxdi_rtc_data { - resource_size_t iobase; - resource_size_t irq; -}; -struct platform_device *__init imx_add_imxdi_rtc( - const struct imx_imxdi_rtc_data *data); - -#include <linux/platform_data/video-imxfb.h> -struct imx_imx_fb_data { - const char *devid; - resource_size_t iobase; - resource_size_t iosize; - resource_size_t irq; -}; -struct platform_device *__init imx_add_imx_fb( - const struct imx_imx_fb_data *data, - const struct imx_fb_platform_data *pdata); - -#include <linux/platform_data/i2c-imx.h> -struct imx_imx_i2c_data { - const char *devid; - int id; - resource_size_t iobase; - resource_size_t iosize; - resource_size_t irq; -}; -struct platform_device *__init imx_add_imx_i2c( - const struct imx_imx_i2c_data *data, - const struct imxi2c_platform_data *pdata); - -#include <linux/input/matrix_keypad.h> -struct imx_imx_keypad_data { - resource_size_t iobase; - resource_size_t iosize; - resource_size_t irq; -}; -struct platform_device *__init imx_add_imx_keypad( - const struct imx_imx_keypad_data *data, - const struct matrix_keymap_data *pdata); - -#include <linux/platform_data/asoc-imx-ssi.h> -struct imx_imx_ssi_data { - int id; - resource_size_t iobase; - resource_size_t iosize; - resource_size_t irq; - resource_size_t dmatx0; - resource_size_t dmarx0; - resource_size_t dmatx1; - resource_size_t dmarx1; -}; -struct platform_device *__init imx_add_imx_ssi( - const struct imx_imx_ssi_data *data, - const struct imx_ssi_platform_data *pdata); - -#include <linux/platform_data/serial-imx.h> -struct imx_imx_uart_1irq_data { - int id; - resource_size_t iobase; - resource_size_t iosize; - resource_size_t irq; -}; -struct platform_device *__init imx_add_imx_uart_1irq( - const struct imx_imx_uart_1irq_data *data, - const struct imxuart_platform_data *pdata); - -#include <linux/platform_data/video-mx3fb.h> -#include <linux/platform_data/media/camera-mx3.h> -struct imx_ipu_core_data { - resource_size_t iobase; - resource_size_t synirq; - resource_size_t errirq; -}; -struct platform_device *__init imx_add_ipu_core( - const struct imx_ipu_core_data *data); -struct platform_device *__init imx_alloc_mx3_camera( - const struct imx_ipu_core_data *data, - const struct mx3_camera_pdata *pdata); -struct platform_device *__init imx_add_mx3_sdc_fb( - const struct imx_ipu_core_data *data, - struct mx3fb_platform_data *pdata); - -#include <linux/platform_data/media/camera-mx2.h> -struct imx_mx2_camera_data { - const char *devid; - resource_size_t iobasecsi; - resource_size_t iosizecsi; - resource_size_t irqcsi; - resource_size_t iobaseemmaprp; - resource_size_t iosizeemmaprp; - resource_size_t irqemmaprp; -}; -struct platform_device *__init imx_add_mx2_camera( - const struct imx_mx2_camera_data *data, - const struct mx2_camera_platform_data *pdata); - - -struct imx_mx2_emma_data { - resource_size_t iobase; - resource_size_t iosize; - resource_size_t irq; -}; -struct platform_device *__init imx_add_mx2_emmaprp( - const struct imx_mx2_emma_data *data); - -#include <linux/platform_data/usb-ehci-mxc.h> -struct imx_mxc_ehci_data { - int id; - resource_size_t iobase; - resource_size_t irq; -}; -struct platform_device *__init imx_add_mxc_ehci( - const struct imx_mxc_ehci_data *data, - const struct mxc_usbh_platform_data *pdata); - -#include <linux/platform_data/mmc-mxcmmc.h> -struct imx_mxc_mmc_data { - const char *devid; - int id; - resource_size_t iobase; - resource_size_t iosize; - resource_size_t irq; - resource_size_t dmareq; -}; -struct platform_device *__init imx_add_mxc_mmc( - const struct imx_mxc_mmc_data *data, - const struct imxmmc_platform_data *pdata); - -#include <linux/platform_data/mtd-mxc_nand.h> -struct imx_mxc_nand_data { - const char *devid; - /* - * id is traditionally 0, but -1 is more appropriate. We use -1 for new - * machines but don't change existing devices as the nand device usually - * appears in the kernel command line to pass its partitioning. - */ - int id; - resource_size_t iobase; - resource_size_t iosize; - resource_size_t axibase; - resource_size_t irq; -}; -struct platform_device *__init imx_add_mxc_nand( - const struct imx_mxc_nand_data *data, - const struct mxc_nand_platform_data *pdata); - -struct imx_pata_imx_data { - resource_size_t iobase; - resource_size_t iosize; - resource_size_t irq; -}; -struct platform_device *__init imx_add_pata_imx( - const struct imx_pata_imx_data *data); - -/* mxc_rtc */ -struct imx_mxc_rtc_data { - const char *devid; - resource_size_t iobase; - resource_size_t irq; -}; -struct platform_device *__init imx_add_mxc_rtc( - const struct imx_mxc_rtc_data *data); - -/* mxc_w1 */ -struct imx_mxc_w1_data { - resource_size_t iobase; -}; -struct platform_device *__init imx_add_mxc_w1( - const struct imx_mxc_w1_data *data); - -#include <linux/platform_data/mmc-esdhc-imx.h> -struct imx_sdhci_esdhc_imx_data { - const char *devid; - int id; - resource_size_t iobase; - resource_size_t irq; -}; -struct platform_device *__init imx_add_sdhci_esdhc_imx( - const struct imx_sdhci_esdhc_imx_data *data, - const struct esdhc_platform_data *pdata); - -struct imx_spi_imx_data { - const char *devid; - int id; - resource_size_t iobase; - resource_size_t iosize; - int irq; -}; -struct platform_device *__init imx_add_spi_imx( - const struct imx_spi_imx_data *data, struct gpiod_lookup_table *gtable); - -struct platform_device *imx_add_imx_dma(char *name, resource_size_t iobase, - int irq); -struct platform_device *imx_add_imx_sdma(char *name, - resource_size_t iobase, int irq, struct sdma_platform_data *pdata); diff --git a/arch/arm/mach-imx/devices/devices.c b/arch/arm/mach-imx/devices/devices.c deleted file mode 100644 index cd72f0894196..000000000000 --- a/arch/arm/mach-imx/devices/devices.c +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2008 Sascha Hauer, kernel@pengutronix.de - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/err.h> -#include <linux/platform_device.h> - -#include "../common.h" -#include "devices-common.h" - -struct device mxc_aips_bus = { - .init_name = "mxc_aips", -}; - -struct device mxc_ahb_bus = { - .init_name = "mxc_ahb", -}; - -int __init mxc_device_init(void) -{ - int ret; - - ret = device_register(&mxc_aips_bus); - if (ret < 0) - goto done; - - ret = device_register(&mxc_ahb_bus); - -done: - return ret; -} diff --git a/arch/arm/mach-imx/devices/platform-fec.c b/arch/arm/mach-imx/devices/platform-fec.c deleted file mode 100644 index 88e853d7fb01..000000000000 --- a/arch/arm/mach-imx/devices/platform-fec.c +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include <linux/dma-mapping.h> -#include <linux/sizes.h> - -#include "../hardware.h" -#include "devices-common.h" - -#define imx_fec_data_entry_single(soc, _devid) \ - { \ - .devid = _devid, \ - .iobase = soc ## _FEC_BASE_ADDR, \ - .irq = soc ## _INT_FEC, \ - } - -#ifdef CONFIG_SOC_IMX27 -const struct imx_fec_data imx27_fec_data __initconst = - imx_fec_data_entry_single(MX27, "imx27-fec"); -#endif /* ifdef CONFIG_SOC_IMX27 */ - -#ifdef CONFIG_SOC_IMX35 -/* i.mx35 has the i.mx27 type fec */ -const struct imx_fec_data imx35_fec_data __initconst = - imx_fec_data_entry_single(MX35, "imx27-fec"); -#endif - -struct platform_device *__init imx_add_fec( - const struct imx_fec_data *data, - const struct fec_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - - return imx_add_platform_device_dmamask(data->devid, 0, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata), DMA_BIT_MASK(32)); -} diff --git a/arch/arm/mach-imx/devices/platform-flexcan.c b/arch/arm/mach-imx/devices/platform-flexcan.c deleted file mode 100644 index e4eed35c1fe2..000000000000 --- a/arch/arm/mach-imx/devices/platform-flexcan.c +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de> - */ -#include "../hardware.h" -#include "devices-common.h" - -#define imx_flexcan_data_entry_single(soc, _id, _hwid, _size) \ - { \ - .id = _id, \ - .iobase = soc ## _CAN ## _hwid ## _BASE_ADDR, \ - .iosize = _size, \ - .irq = soc ## _INT_CAN ## _hwid, \ - } - -#define imx_flexcan_data_entry(soc, _id, _hwid, _size) \ - [_id] = imx_flexcan_data_entry_single(soc, _id, _hwid, _size) - -#ifdef CONFIG_SOC_IMX35 -const struct imx_flexcan_data imx35_flexcan_data[] __initconst = { -#define imx35_flexcan_data_entry(_id, _hwid) \ - imx_flexcan_data_entry(MX35, _id, _hwid, SZ_16K) - imx35_flexcan_data_entry(0, 1), - imx35_flexcan_data_entry(1, 2), -}; -#endif /* ifdef CONFIG_SOC_IMX35 */ - -struct platform_device *__init imx_add_flexcan( - const struct imx_flexcan_data *data) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + data->iosize - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - - return imx_add_platform_device("flexcan", data->id, - res, ARRAY_SIZE(res), NULL, 0); -} diff --git a/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c b/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c deleted file mode 100644 index cc86de4d7acb..000000000000 --- a/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include <linux/dma-mapping.h> - -#include "../hardware.h" -#include "devices-common.h" - -#define imx_fsl_usb2_udc_data_entry_single(soc, _devid) \ - { \ - .devid = _devid, \ - .iobase = soc ## _USB_OTG_BASE_ADDR, \ - .irq = soc ## _INT_USB_OTG, \ - } - -#ifdef CONFIG_SOC_IMX27 -const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data __initconst = - imx_fsl_usb2_udc_data_entry_single(MX27, "imx-udc-mx27"); -#endif /* ifdef CONFIG_SOC_IMX27 */ - -#ifdef CONFIG_SOC_IMX31 -const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data __initconst = - imx_fsl_usb2_udc_data_entry_single(MX31, "imx-udc-mx27"); -#endif /* ifdef CONFIG_SOC_IMX31 */ - -#ifdef CONFIG_SOC_IMX35 -const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data __initconst = - imx_fsl_usb2_udc_data_entry_single(MX35, "imx-udc-mx27"); -#endif /* ifdef CONFIG_SOC_IMX35 */ - -struct platform_device *__init imx_add_fsl_usb2_udc( - const struct imx_fsl_usb2_udc_data *data, - const struct fsl_usb2_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - return imx_add_platform_device_dmamask(data->devid, -1, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata), DMA_BIT_MASK(32)); -} diff --git a/arch/arm/mach-imx/devices/platform-gpio-mxc.c b/arch/arm/mach-imx/devices/platform-gpio-mxc.c deleted file mode 100644 index 355de845224c..000000000000 --- a/arch/arm/mach-imx/devices/platform-gpio-mxc.c +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2011 Linaro Limited - */ -#include "devices-common.h" -#include "../common.h" - -struct platform_device *__init mxc_register_gpio(char *name, int id, - resource_size_t iobase, resource_size_t iosize, int irq, int irq_high) -{ - struct resource res[] = { - { - .start = iobase, - .end = iobase + iosize - 1, - .flags = IORESOURCE_MEM, - }, { - .start = irq, - .end = irq, - .flags = IORESOURCE_IRQ, - }, { - .start = irq_high, - .end = irq_high, - .flags = IORESOURCE_IRQ, - }, - }; - unsigned int nres; - - nres = irq_high ? ARRAY_SIZE(res) : ARRAY_SIZE(res) - 1; - return platform_device_register_resndata(&mxc_aips_bus, name, id, res, nres, NULL, 0); -} diff --git a/arch/arm/mach-imx/devices/platform-gpio_keys.c b/arch/arm/mach-imx/devices/platform-gpio_keys.c deleted file mode 100644 index 488678403ac8..000000000000 --- a/arch/arm/mach-imx/devices/platform-gpio_keys.c +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - */ -#include <linux/sizes.h> - -#include "../hardware.h" -#include "devices-common.h" - -struct platform_device *__init imx_add_gpio_keys( - const struct gpio_keys_platform_data *pdata) -{ - return imx_add_platform_device("gpio-keys", -1, NULL, - 0, pdata, sizeof(*pdata)); -} diff --git a/arch/arm/mach-imx/devices/platform-imx-dma.c b/arch/arm/mach-imx/devices/platform-imx-dma.c deleted file mode 100644 index 12656f24ad0d..000000000000 --- a/arch/arm/mach-imx/devices/platform-imx-dma.c +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "devices-common.h" - -struct platform_device __init __maybe_unused *imx_add_imx_dma(char *name, - resource_size_t iobase, int irq) -{ - struct resource res[] = { - { - .start = iobase, - .end = iobase + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = irq, - .end = irq, - .flags = IORESOURCE_IRQ, - }, - }; - - return platform_device_register_resndata(&mxc_ahb_bus, - name, -1, res, ARRAY_SIZE(res), NULL, 0); -} - -struct platform_device __init __maybe_unused *imx_add_imx_sdma(char *name, - resource_size_t iobase, int irq, struct sdma_platform_data *pdata) -{ - struct resource res[] = { - { - .start = iobase, - .end = iobase + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = irq, - .end = irq, - .flags = IORESOURCE_IRQ, - }, - }; - - return platform_device_register_resndata(&mxc_ahb_bus, name, - -1, res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); -} diff --git a/arch/arm/mach-imx/devices/platform-imx-fb.c b/arch/arm/mach-imx/devices/platform-imx-fb.c deleted file mode 100644 index e553d014506a..000000000000 --- a/arch/arm/mach-imx/devices/platform-imx-fb.c +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include <linux/dma-mapping.h> - -#include "../hardware.h" -#include "devices-common.h" - -#define imx_imx_fb_data_entry_single(soc, _devid, _size) \ - { \ - .devid = _devid, \ - .iobase = soc ## _LCDC_BASE_ADDR, \ - .iosize = _size, \ - .irq = soc ## _INT_LCDC, \ - } - -#ifdef CONFIG_SOC_IMX21 -const struct imx_imx_fb_data imx21_imx_fb_data __initconst = - imx_imx_fb_data_entry_single(MX21, "imx21-fb", SZ_4K); -#endif /* ifdef CONFIG_SOC_IMX21 */ - -#ifdef CONFIG_SOC_IMX27 -const struct imx_imx_fb_data imx27_imx_fb_data __initconst = - imx_imx_fb_data_entry_single(MX27, "imx21-fb", SZ_4K); -#endif /* ifdef CONFIG_SOC_IMX27 */ - -struct platform_device *__init imx_add_imx_fb( - const struct imx_imx_fb_data *data, - const struct imx_fb_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + data->iosize - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - return imx_add_platform_device_dmamask(data->devid, 0, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata), DMA_BIT_MASK(32)); -} diff --git a/arch/arm/mach-imx/devices/platform-imx-i2c.c b/arch/arm/mach-imx/devices/platform-imx-i2c.c deleted file mode 100644 index 81d317bfadd8..000000000000 --- a/arch/arm/mach-imx/devices/platform-imx-i2c.c +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009-2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "../hardware.h" -#include "devices-common.h" - -#define imx_imx_i2c_data_entry_single(soc, _devid, _id, _hwid, _size) \ - { \ - .devid = _devid, \ - .id = _id, \ - .iobase = soc ## _I2C ## _hwid ## _BASE_ADDR, \ - .iosize = _size, \ - .irq = soc ## _INT_I2C ## _hwid, \ - } - -#define imx_imx_i2c_data_entry(soc, _devid, _id, _hwid, _size) \ - [_id] = imx_imx_i2c_data_entry_single(soc, _devid, _id, _hwid, _size) - -#ifdef CONFIG_SOC_IMX21 -const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst = - imx_imx_i2c_data_entry_single(MX21, "imx21-i2c", 0, , SZ_4K); -#endif /* ifdef CONFIG_SOC_IMX21 */ - -#ifdef CONFIG_SOC_IMX27 -const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst = { -#define imx27_imx_i2c_data_entry(_id, _hwid) \ - imx_imx_i2c_data_entry(MX27, "imx21-i2c", _id, _hwid, SZ_4K) - imx27_imx_i2c_data_entry(0, 1), - imx27_imx_i2c_data_entry(1, 2), -}; -#endif /* ifdef CONFIG_SOC_IMX27 */ - -#ifdef CONFIG_SOC_IMX31 -const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst = { -#define imx31_imx_i2c_data_entry(_id, _hwid) \ - imx_imx_i2c_data_entry(MX31, "imx21-i2c", _id, _hwid, SZ_4K) - imx31_imx_i2c_data_entry(0, 1), - imx31_imx_i2c_data_entry(1, 2), - imx31_imx_i2c_data_entry(2, 3), -}; -#endif /* ifdef CONFIG_SOC_IMX31 */ - -#ifdef CONFIG_SOC_IMX35 -const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst = { -#define imx35_imx_i2c_data_entry(_id, _hwid) \ - imx_imx_i2c_data_entry(MX35, "imx21-i2c", _id, _hwid, SZ_4K) - imx35_imx_i2c_data_entry(0, 1), - imx35_imx_i2c_data_entry(1, 2), - imx35_imx_i2c_data_entry(2, 3), -}; -#endif /* ifdef CONFIG_SOC_IMX35 */ - -struct platform_device *__init imx_add_imx_i2c( - const struct imx_imx_i2c_data *data, - const struct imxi2c_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + data->iosize - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - - return imx_add_platform_device(data->devid, data->id, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata)); -} diff --git a/arch/arm/mach-imx/devices/platform-imx-keypad.c b/arch/arm/mach-imx/devices/platform-imx-keypad.c deleted file mode 100644 index de2e03ec2d89..000000000000 --- a/arch/arm/mach-imx/devices/platform-imx-keypad.c +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "../hardware.h" -#include "devices-common.h" - -#define imx_imx_keypad_data_entry_single(soc, _size) \ - { \ - .iobase = soc ## _KPP_BASE_ADDR, \ - .iosize = _size, \ - .irq = soc ## _INT_KPP, \ - } - -#ifdef CONFIG_SOC_IMX21 -const struct imx_imx_keypad_data imx21_imx_keypad_data __initconst = - imx_imx_keypad_data_entry_single(MX21, SZ_16); -#endif /* ifdef CONFIG_SOC_IMX21 */ - -#ifdef CONFIG_SOC_IMX27 -const struct imx_imx_keypad_data imx27_imx_keypad_data __initconst = - imx_imx_keypad_data_entry_single(MX27, SZ_16); -#endif /* ifdef CONFIG_SOC_IMX27 */ - -#ifdef CONFIG_SOC_IMX31 -const struct imx_imx_keypad_data imx31_imx_keypad_data __initconst = - imx_imx_keypad_data_entry_single(MX31, SZ_16); -#endif /* ifdef CONFIG_SOC_IMX31 */ - -#ifdef CONFIG_SOC_IMX35 -const struct imx_imx_keypad_data imx35_imx_keypad_data __initconst = - imx_imx_keypad_data_entry_single(MX35, SZ_16); -#endif /* ifdef CONFIG_SOC_IMX35 */ - -struct platform_device *__init imx_add_imx_keypad( - const struct imx_imx_keypad_data *data, - const struct matrix_keymap_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + data->iosize - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - - return imx_add_platform_device("imx-keypad", -1, - res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); -} diff --git a/arch/arm/mach-imx/devices/platform-imx-ssi.c b/arch/arm/mach-imx/devices/platform-imx-ssi.c deleted file mode 100644 index ed8c66438af0..000000000000 --- a/arch/arm/mach-imx/devices/platform-imx-ssi.c +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "../hardware.h" -#include "devices-common.h" - -#define imx_imx_ssi_data_entry(soc, _id, _hwid, _size) \ - [_id] = { \ - .id = _id, \ - .iobase = soc ## _SSI ## _hwid ## _BASE_ADDR, \ - .iosize = _size, \ - .irq = soc ## _INT_SSI ## _hwid, \ - .dmatx0 = soc ## _DMA_REQ_SSI ## _hwid ## _TX0, \ - .dmarx0 = soc ## _DMA_REQ_SSI ## _hwid ## _RX0, \ - .dmatx1 = soc ## _DMA_REQ_SSI ## _hwid ## _TX1, \ - .dmarx1 = soc ## _DMA_REQ_SSI ## _hwid ## _RX1, \ - } - -#ifdef CONFIG_SOC_IMX21 -const struct imx_imx_ssi_data imx21_imx_ssi_data[] __initconst = { -#define imx21_imx_ssi_data_entry(_id, _hwid) \ - imx_imx_ssi_data_entry(MX21, _id, _hwid, SZ_4K) - imx21_imx_ssi_data_entry(0, 1), - imx21_imx_ssi_data_entry(1, 2), -}; -#endif /* ifdef CONFIG_SOC_IMX21 */ - -#ifdef CONFIG_SOC_IMX27 -const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst = { -#define imx27_imx_ssi_data_entry(_id, _hwid) \ - imx_imx_ssi_data_entry(MX27, _id, _hwid, SZ_4K) - imx27_imx_ssi_data_entry(0, 1), - imx27_imx_ssi_data_entry(1, 2), -}; -#endif /* ifdef CONFIG_SOC_IMX27 */ - -#ifdef CONFIG_SOC_IMX31 -const struct imx_imx_ssi_data imx31_imx_ssi_data[] __initconst = { -#define imx31_imx_ssi_data_entry(_id, _hwid) \ - imx_imx_ssi_data_entry(MX31, _id, _hwid, SZ_4K) - imx31_imx_ssi_data_entry(0, 1), - imx31_imx_ssi_data_entry(1, 2), -}; -#endif /* ifdef CONFIG_SOC_IMX31 */ - -#ifdef CONFIG_SOC_IMX35 -const struct imx_imx_ssi_data imx35_imx_ssi_data[] __initconst = { -#define imx35_imx_ssi_data_entry(_id, _hwid) \ - imx_imx_ssi_data_entry(MX35, _id, _hwid, SZ_4K) - imx35_imx_ssi_data_entry(0, 1), - imx35_imx_ssi_data_entry(1, 2), -}; -#endif /* ifdef CONFIG_SOC_IMX35 */ - -struct platform_device *__init imx_add_imx_ssi( - const struct imx_imx_ssi_data *data, - const struct imx_ssi_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + data->iosize - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, -#define DMARES(_name) { \ - .name = #_name, \ - .start = data->dma ## _name, \ - .end = data->dma ## _name, \ - .flags = IORESOURCE_DMA, \ -} - DMARES(tx0), - DMARES(rx0), - DMARES(tx1), - DMARES(rx1), - }; - - return imx_add_platform_device("imx-ssi", data->id, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata)); -} diff --git a/arch/arm/mach-imx/devices/platform-imx-uart.c b/arch/arm/mach-imx/devices/platform-imx-uart.c deleted file mode 100644 index c8f01deedd80..000000000000 --- a/arch/arm/mach-imx/devices/platform-imx-uart.c +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009-2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "../hardware.h" -#include "devices-common.h" - -#define imx_imx_uart_3irq_data_entry(soc, _id, _hwid, _size) \ - [_id] = { \ - .id = _id, \ - .iobase = soc ## _UART ## _hwid ## _BASE_ADDR, \ - .iosize = _size, \ - .irqrx = soc ## _INT_UART ## _hwid ## RX, \ - .irqtx = soc ## _INT_UART ## _hwid ## TX, \ - .irqrts = soc ## _INT_UART ## _hwid ## RTS, \ - } - -#define imx_imx_uart_1irq_data_entry(soc, _id, _hwid, _size) \ - [_id] = { \ - .id = _id, \ - .iobase = soc ## _UART ## _hwid ## _BASE_ADDR, \ - .iosize = _size, \ - .irq = soc ## _INT_UART ## _hwid, \ - } - -#ifdef CONFIG_SOC_IMX21 -const struct imx_imx_uart_1irq_data imx21_imx_uart_data[] __initconst = { -#define imx21_imx_uart_data_entry(_id, _hwid) \ - imx_imx_uart_1irq_data_entry(MX21, _id, _hwid, SZ_4K) - imx21_imx_uart_data_entry(0, 1), - imx21_imx_uart_data_entry(1, 2), - imx21_imx_uart_data_entry(2, 3), - imx21_imx_uart_data_entry(3, 4), -}; -#endif - -#ifdef CONFIG_SOC_IMX27 -const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst = { -#define imx27_imx_uart_data_entry(_id, _hwid) \ - imx_imx_uart_1irq_data_entry(MX27, _id, _hwid, SZ_4K) - imx27_imx_uart_data_entry(0, 1), - imx27_imx_uart_data_entry(1, 2), - imx27_imx_uart_data_entry(2, 3), - imx27_imx_uart_data_entry(3, 4), - imx27_imx_uart_data_entry(4, 5), - imx27_imx_uart_data_entry(5, 6), -}; -#endif /* ifdef CONFIG_SOC_IMX27 */ - -#ifdef CONFIG_SOC_IMX31 -const struct imx_imx_uart_1irq_data imx31_imx_uart_data[] __initconst = { -#define imx31_imx_uart_data_entry(_id, _hwid) \ - imx_imx_uart_1irq_data_entry(MX31, _id, _hwid, SZ_4K) - imx31_imx_uart_data_entry(0, 1), - imx31_imx_uart_data_entry(1, 2), - imx31_imx_uart_data_entry(2, 3), - imx31_imx_uart_data_entry(3, 4), - imx31_imx_uart_data_entry(4, 5), -}; -#endif /* ifdef CONFIG_SOC_IMX31 */ - -#ifdef CONFIG_SOC_IMX35 -const struct imx_imx_uart_1irq_data imx35_imx_uart_data[] __initconst = { -#define imx35_imx_uart_data_entry(_id, _hwid) \ - imx_imx_uart_1irq_data_entry(MX35, _id, _hwid, SZ_16K) - imx35_imx_uart_data_entry(0, 1), - imx35_imx_uart_data_entry(1, 2), - imx35_imx_uart_data_entry(2, 3), -}; -#endif /* ifdef CONFIG_SOC_IMX35 */ - -struct platform_device *__init imx_add_imx_uart_1irq( - const struct imx_imx_uart_1irq_data *data, - const struct imxuart_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + data->iosize - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - - /* i.mx21 type uart runs on all i.mx except i.mx1 */ - return imx_add_platform_device("imx21-uart", data->id, - res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); -} diff --git a/arch/arm/mach-imx/devices/platform-imx2-wdt.c b/arch/arm/mach-imx/devices/platform-imx2-wdt.c deleted file mode 100644 index fdd355ae4d5f..000000000000 --- a/arch/arm/mach-imx/devices/platform-imx2-wdt.c +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include <linux/sizes.h> - -#include "../hardware.h" -#include "devices-common.h" - -#define imx_imx2_wdt_data_entry_single(soc, _id, _hwid, _size) \ - { \ - .id = _id, \ - .iobase = soc ## _WDOG ## _hwid ## _BASE_ADDR, \ - .iosize = _size, \ - } -#define imx_imx2_wdt_data_entry(soc, _id, _hwid, _size) \ - [_id] = imx_imx2_wdt_data_entry_single(soc, _id, _hwid, _size) - -#ifdef CONFIG_SOC_IMX21 -const struct imx_imx2_wdt_data imx21_imx2_wdt_data __initconst = - imx_imx2_wdt_data_entry_single(MX21, 0, , SZ_4K); -#endif /* ifdef CONFIG_SOC_IMX21 */ - -#ifdef CONFIG_SOC_IMX27 -const struct imx_imx2_wdt_data imx27_imx2_wdt_data __initconst = - imx_imx2_wdt_data_entry_single(MX27, 0, , SZ_4K); -#endif /* ifdef CONFIG_SOC_IMX27 */ - -#ifdef CONFIG_SOC_IMX31 -const struct imx_imx2_wdt_data imx31_imx2_wdt_data __initconst = - imx_imx2_wdt_data_entry_single(MX31, 0, , SZ_16K); -#endif /* ifdef CONFIG_SOC_IMX31 */ - -#ifdef CONFIG_SOC_IMX35 -const struct imx_imx2_wdt_data imx35_imx2_wdt_data __initconst = - imx_imx2_wdt_data_entry_single(MX35, 0, , SZ_16K); -#endif /* ifdef CONFIG_SOC_IMX35 */ - -struct platform_device *__init imx_add_imx2_wdt( - const struct imx_imx2_wdt_data *data) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + data->iosize - 1, - .flags = IORESOURCE_MEM, - }, - }; - return imx_add_platform_device("imx2-wdt", data->id, - res, ARRAY_SIZE(res), NULL, 0); -} diff --git a/arch/arm/mach-imx/devices/platform-imx21-hcd.c b/arch/arm/mach-imx/devices/platform-imx21-hcd.c deleted file mode 100644 index f55763c36d26..000000000000 --- a/arch/arm/mach-imx/devices/platform-imx21-hcd.c +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "../hardware.h" -#include "devices-common.h" - -#define imx_imx21_hcd_data_entry_single(soc) \ - { \ - .iobase = soc ## _USBOTG_BASE_ADDR, \ - .irq = soc ## _INT_USBHOST, \ - } - -#ifdef CONFIG_SOC_IMX21 -const struct imx_imx21_hcd_data imx21_imx21_hcd_data __initconst = - imx_imx21_hcd_data_entry_single(MX21); -#endif /* ifdef CONFIG_SOC_IMX21 */ - -struct platform_device *__init imx_add_imx21_hcd( - const struct imx_imx21_hcd_data *data, - const struct mx21_usbh_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + SZ_8K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - return imx_add_platform_device_dmamask("imx21-hcd", 0, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata), DMA_BIT_MASK(32)); -} diff --git a/arch/arm/mach-imx/devices/platform-imx27-coda.c b/arch/arm/mach-imx/devices/platform-imx27-coda.c deleted file mode 100644 index 66a116e6c6bc..000000000000 --- a/arch/arm/mach-imx/devices/platform-imx27-coda.c +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2012 Vista Silicon - * Javier Martin <javier.martin@vista-silicon.com> - */ - -#include "../hardware.h" -#include "devices-common.h" - -#ifdef CONFIG_SOC_IMX27 -const struct imx_imx27_coda_data imx27_coda_data __initconst = { - .iobase = MX27_VPU_BASE_ADDR, - .iosize = SZ_512, - .irq = MX27_INT_VPU, -}; -#endif - -struct platform_device *__init imx_add_imx27_coda( - const struct imx_imx27_coda_data *data) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + data->iosize - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - return imx_add_platform_device_dmamask("coda-imx27", 0, res, 2, NULL, - 0, DMA_BIT_MASK(32)); -} diff --git a/arch/arm/mach-imx/devices/platform-ipu-core.c b/arch/arm/mach-imx/devices/platform-ipu-core.c deleted file mode 100644 index b4290760f49f..000000000000 --- a/arch/arm/mach-imx/devices/platform-ipu-core.c +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2011 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include <linux/dma-mapping.h> - -#include "../hardware.h" -#include "devices-common.h" - -#define imx_ipu_core_entry_single(soc) \ -{ \ - .iobase = soc ## _IPU_CTRL_BASE_ADDR, \ - .synirq = soc ## _INT_IPU_SYN, \ - .errirq = soc ## _INT_IPU_ERR, \ -} - -#ifdef CONFIG_SOC_IMX31 -const struct imx_ipu_core_data imx31_ipu_core_data __initconst = - imx_ipu_core_entry_single(MX31); -#endif - -#ifdef CONFIG_SOC_IMX35 -const struct imx_ipu_core_data imx35_ipu_core_data __initconst = - imx_ipu_core_entry_single(MX35); -#endif - -static struct platform_device *imx_ipu_coredev __initdata; - -struct platform_device *__init imx_add_ipu_core( - const struct imx_ipu_core_data *data) -{ - /* The resource order is important! */ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + 0x5f, - .flags = IORESOURCE_MEM, - }, { - .start = data->iobase + 0x88, - .end = data->iobase + 0xb3, - .flags = IORESOURCE_MEM, - }, { - .start = data->synirq, - .end = data->synirq, - .flags = IORESOURCE_IRQ, - }, { - .start = data->errirq, - .end = data->errirq, - .flags = IORESOURCE_IRQ, - }, - }; - - return imx_ipu_coredev = imx_add_platform_device("ipu-core", -1, - res, ARRAY_SIZE(res), NULL, 0); -} - -struct platform_device *__init imx_alloc_mx3_camera( - const struct imx_ipu_core_data *data, - const struct mx3_camera_pdata *pdata) -{ - struct resource res[] = { - { - .start = data->iobase + 0x60, - .end = data->iobase + 0x87, - .flags = IORESOURCE_MEM, - }, - }; - int ret = -ENOMEM; - struct platform_device *pdev; - - if (IS_ERR_OR_NULL(imx_ipu_coredev)) - return ERR_PTR(-ENODEV); - - pdev = platform_device_alloc("mx3-camera", 0); - if (!pdev) - return ERR_PTR(-ENOMEM); - - pdev->dev.dma_mask = kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); - if (!pdev->dev.dma_mask) - goto err; - - *pdev->dev.dma_mask = DMA_BIT_MASK(32); - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - - ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res)); - if (ret) - goto err; - - if (pdata) { - struct mx3_camera_pdata *copied_pdata; - - ret = platform_device_add_data(pdev, pdata, sizeof(*pdata)); - if (ret) { -err: - kfree(pdev->dev.dma_mask); - platform_device_put(pdev); - return ERR_PTR(-ENODEV); - } - copied_pdata = dev_get_platdata(&pdev->dev); - copied_pdata->dma_dev = &imx_ipu_coredev->dev; - } - - return pdev; -} - -struct platform_device *__init imx_add_mx3_sdc_fb( - const struct imx_ipu_core_data *data, - struct mx3fb_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase + 0xb4, - .end = data->iobase + 0x1bf, - .flags = IORESOURCE_MEM, - }, - }; - - if (IS_ERR_OR_NULL(imx_ipu_coredev)) - return ERR_PTR(-ENODEV); - - pdata->dma_dev = &imx_ipu_coredev->dev; - - return imx_add_platform_device_dmamask("mx3_sdc_fb", -1, - res, ARRAY_SIZE(res), pdata, sizeof(*pdata), - DMA_BIT_MASK(32)); -} diff --git a/arch/arm/mach-imx/devices/platform-mx2-camera.c b/arch/arm/mach-imx/devices/platform-mx2-camera.c deleted file mode 100644 index 5375f8b3d079..000000000000 --- a/arch/arm/mach-imx/devices/platform-mx2-camera.c +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "../hardware.h" -#include "devices-common.h" - -#define imx_mx2_camera_data_entry_single(soc, _devid) \ - { \ - .devid = _devid, \ - .iobasecsi = soc ## _CSI_BASE_ADDR, \ - .iosizecsi = SZ_4K, \ - .irqcsi = soc ## _INT_CSI, \ - } -#define imx_mx2_camera_data_entry_single_emma(soc, _devid) \ - { \ - .devid = _devid, \ - .iobasecsi = soc ## _CSI_BASE_ADDR, \ - .iosizecsi = SZ_32, \ - .irqcsi = soc ## _INT_CSI, \ - .iobaseemmaprp = soc ## _EMMAPRP_BASE_ADDR, \ - .iosizeemmaprp = SZ_32, \ - .irqemmaprp = soc ## _INT_EMMAPRP, \ - } - -#ifdef CONFIG_SOC_IMX27 -const struct imx_mx2_camera_data imx27_mx2_camera_data __initconst = - imx_mx2_camera_data_entry_single_emma(MX27, "imx27-camera"); -#endif /* ifdef CONFIG_SOC_IMX27 */ - -struct platform_device *__init imx_add_mx2_camera( - const struct imx_mx2_camera_data *data, - const struct mx2_camera_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobasecsi, - .end = data->iobasecsi + data->iosizecsi - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irqcsi, - .end = data->irqcsi, - .flags = IORESOURCE_IRQ, - }, { - .start = data->iobaseemmaprp, - .end = data->iobaseemmaprp + data->iosizeemmaprp - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irqemmaprp, - .end = data->irqemmaprp, - .flags = IORESOURCE_IRQ, - }, - }; - return imx_add_platform_device_dmamask(data->devid, 0, - res, data->iobaseemmaprp ? 4 : 2, - pdata, sizeof(*pdata), DMA_BIT_MASK(32)); -} - diff --git a/arch/arm/mach-imx/devices/platform-mx2-emma.c b/arch/arm/mach-imx/devices/platform-mx2-emma.c deleted file mode 100644 index 20f28ba16f36..000000000000 --- a/arch/arm/mach-imx/devices/platform-mx2-emma.c +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "../hardware.h" -#include "devices-common.h" - -#define imx_mx2_emmaprp_data_entry_single(soc) \ - { \ - .iobase = soc ## _EMMAPRP_BASE_ADDR, \ - .iosize = SZ_256, \ - .irq = soc ## _INT_EMMAPRP, \ - } - -#ifdef CONFIG_SOC_IMX27 -const struct imx_mx2_emma_data imx27_mx2_emmaprp_data __initconst = - imx_mx2_emmaprp_data_entry_single(MX27); -#endif /* ifdef CONFIG_SOC_IMX27 */ - -struct platform_device *__init imx_add_mx2_emmaprp( - const struct imx_mx2_emma_data *data) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + data->iosize - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - return imx_add_platform_device_dmamask("m2m-emmaprp", 0, - res, 2, NULL, 0, DMA_BIT_MASK(32)); -} diff --git a/arch/arm/mach-imx/devices/platform-mxc-ehci.c b/arch/arm/mach-imx/devices/platform-mxc-ehci.c deleted file mode 100644 index d9d7cc71633f..000000000000 --- a/arch/arm/mach-imx/devices/platform-mxc-ehci.c +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include <linux/dma-mapping.h> - -#include "../hardware.h" -#include "devices-common.h" - -#define imx_mxc_ehci_data_entry_single(soc, _id, hs) \ - { \ - .id = _id, \ - .iobase = soc ## _USB_ ## hs ## _BASE_ADDR, \ - .irq = soc ## _INT_USB_ ## hs, \ - } - -#ifdef CONFIG_SOC_IMX27 -const struct imx_mxc_ehci_data imx27_mxc_ehci_otg_data __initconst = - imx_mxc_ehci_data_entry_single(MX27, 0, OTG); -const struct imx_mxc_ehci_data imx27_mxc_ehci_hs_data[] __initconst = { - imx_mxc_ehci_data_entry_single(MX27, 1, HS1), - imx_mxc_ehci_data_entry_single(MX27, 2, HS2), -}; -#endif /* ifdef CONFIG_SOC_IMX27 */ - -#ifdef CONFIG_SOC_IMX31 -const struct imx_mxc_ehci_data imx31_mxc_ehci_otg_data __initconst = - imx_mxc_ehci_data_entry_single(MX31, 0, OTG); -const struct imx_mxc_ehci_data imx31_mxc_ehci_hs_data[] __initconst = { - imx_mxc_ehci_data_entry_single(MX31, 1, HS1), - imx_mxc_ehci_data_entry_single(MX31, 2, HS2), -}; -#endif /* ifdef CONFIG_SOC_IMX31 */ - -#ifdef CONFIG_SOC_IMX35 -const struct imx_mxc_ehci_data imx35_mxc_ehci_otg_data __initconst = - imx_mxc_ehci_data_entry_single(MX35, 0, OTG); -const struct imx_mxc_ehci_data imx35_mxc_ehci_hs_data __initconst = - imx_mxc_ehci_data_entry_single(MX35, 1, HS); -#endif /* ifdef CONFIG_SOC_IMX35 */ - -struct platform_device *__init imx_add_mxc_ehci( - const struct imx_mxc_ehci_data *data, - const struct mxc_usbh_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - return imx_add_platform_device_dmamask("mxc-ehci", data->id, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata), DMA_BIT_MASK(32)); -} diff --git a/arch/arm/mach-imx/devices/platform-mxc-mmc.c b/arch/arm/mach-imx/devices/platform-mxc-mmc.c deleted file mode 100644 index cd4c502bc152..000000000000 --- a/arch/arm/mach-imx/devices/platform-mxc-mmc.c +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include <linux/dma-mapping.h> - -#include "../hardware.h" -#include "devices-common.h" - -#define imx_mxc_mmc_data_entry_single(soc, _devid, _id, _hwid, _size) \ - { \ - .devid = _devid, \ - .id = _id, \ - .iobase = soc ## _SDHC ## _hwid ## _BASE_ADDR, \ - .iosize = _size, \ - .irq = soc ## _INT_SDHC ## _hwid, \ - .dmareq = soc ## _DMA_REQ_SDHC ## _hwid, \ - } -#define imx_mxc_mmc_data_entry(soc, _devid, _id, _hwid, _size) \ - [_id] = imx_mxc_mmc_data_entry_single(soc, _devid, _id, _hwid, _size) - -#ifdef CONFIG_SOC_IMX21 -const struct imx_mxc_mmc_data imx21_mxc_mmc_data[] __initconst = { -#define imx21_mxc_mmc_data_entry(_id, _hwid) \ - imx_mxc_mmc_data_entry(MX21, "imx21-mmc", _id, _hwid, SZ_4K) - imx21_mxc_mmc_data_entry(0, 1), - imx21_mxc_mmc_data_entry(1, 2), -}; -#endif /* ifdef CONFIG_SOC_IMX21 */ - -#ifdef CONFIG_SOC_IMX27 -const struct imx_mxc_mmc_data imx27_mxc_mmc_data[] __initconst = { -#define imx27_mxc_mmc_data_entry(_id, _hwid) \ - imx_mxc_mmc_data_entry(MX27, "imx21-mmc", _id, _hwid, SZ_4K) - imx27_mxc_mmc_data_entry(0, 1), - imx27_mxc_mmc_data_entry(1, 2), -}; -#endif /* ifdef CONFIG_SOC_IMX27 */ - -#ifdef CONFIG_SOC_IMX31 -const struct imx_mxc_mmc_data imx31_mxc_mmc_data[] __initconst = { -#define imx31_mxc_mmc_data_entry(_id, _hwid) \ - imx_mxc_mmc_data_entry(MX31, "imx31-mmc", _id, _hwid, SZ_16K) - imx31_mxc_mmc_data_entry(0, 1), - imx31_mxc_mmc_data_entry(1, 2), -}; -#endif /* ifdef CONFIG_SOC_IMX31 */ - -struct platform_device *__init imx_add_mxc_mmc( - const struct imx_mxc_mmc_data *data, - const struct imxmmc_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + data->iosize - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, { - .start = data->dmareq, - .end = data->dmareq, - .flags = IORESOURCE_DMA, - }, - }; - return imx_add_platform_device_dmamask(data->devid, data->id, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata), DMA_BIT_MASK(32)); -} diff --git a/arch/arm/mach-imx/devices/platform-mxc_nand.c b/arch/arm/mach-imx/devices/platform-mxc_nand.c deleted file mode 100644 index 0f5f741f897f..000000000000 --- a/arch/arm/mach-imx/devices/platform-mxc_nand.c +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009-2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include <linux/sizes.h> - -#include "../hardware.h" -#include "devices-common.h" - -#define imx_mxc_nand_data_entry_single(soc, _devid, _size) \ - { \ - .devid = _devid, \ - .iobase = soc ## _NFC_BASE_ADDR, \ - .iosize = _size, \ - .irq = soc ## _INT_NFC \ - } - -#define imx_mxc_nandv3_data_entry_single(soc, _devid, _size) \ - { \ - .devid = _devid, \ - .id = -1, \ - .iobase = soc ## _NFC_BASE_ADDR, \ - .iosize = _size, \ - .axibase = soc ## _NFC_AXI_BASE_ADDR, \ - .irq = soc ## _INT_NFC \ - } - -#ifdef CONFIG_SOC_IMX21 -const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst = - imx_mxc_nand_data_entry_single(MX21, "imx21-nand", SZ_4K); -#endif /* ifdef CONFIG_SOC_IMX21 */ - -#ifdef CONFIG_SOC_IMX27 -const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst = - imx_mxc_nand_data_entry_single(MX27, "imx27-nand", SZ_4K); -#endif /* ifdef CONFIG_SOC_IMX27 */ - -#ifdef CONFIG_SOC_IMX31 -const struct imx_mxc_nand_data imx31_mxc_nand_data __initconst = - imx_mxc_nand_data_entry_single(MX31, "imx27-nand", SZ_4K); -#endif - -#ifdef CONFIG_SOC_IMX35 -const struct imx_mxc_nand_data imx35_mxc_nand_data __initconst = - imx_mxc_nand_data_entry_single(MX35, "imx25-nand", SZ_8K); -#endif - -struct platform_device *__init imx_add_mxc_nand( - const struct imx_mxc_nand_data *data, - const struct mxc_nand_platform_data *pdata) -{ - /* AXI has to come first, that's how the mxc_nand driver expect it */ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + data->iosize - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, { - .start = data->axibase, - .end = data->axibase + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - }; - return imx_add_platform_device(data->devid, data->id, - res, ARRAY_SIZE(res) - !data->axibase, - pdata, sizeof(*pdata)); -} diff --git a/arch/arm/mach-imx/devices/platform-mxc_rtc.c b/arch/arm/mach-imx/devices/platform-mxc_rtc.c deleted file mode 100644 index 0c746de1dd1d..000000000000 --- a/arch/arm/mach-imx/devices/platform-mxc_rtc.c +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010-2011 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "../hardware.h" -#include "devices-common.h" - -#define imx_mxc_rtc_data_entry_single(soc, _devid) \ - { \ - .devid = _devid, \ - .iobase = soc ## _RTC_BASE_ADDR, \ - .irq = soc ## _INT_RTC, \ - } - -#ifdef CONFIG_SOC_IMX31 -const struct imx_mxc_rtc_data imx31_mxc_rtc_data __initconst = - imx_mxc_rtc_data_entry_single(MX31, "imx21-rtc"); -#endif /* ifdef CONFIG_SOC_IMX31 */ - -#ifdef CONFIG_SOC_IMX35 -const struct imx_mxc_rtc_data imx35_mxc_rtc_data __initconst = - imx_mxc_rtc_data_entry_single(MX35, "imx21-rtc"); -#endif /* ifdef CONFIG_SOC_IMX35 */ - -struct platform_device *__init imx_add_mxc_rtc( - const struct imx_mxc_rtc_data *data) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - - return imx_add_platform_device(data->devid, -1, - res, ARRAY_SIZE(res), NULL, 0); -} diff --git a/arch/arm/mach-imx/devices/platform-mxc_w1.c b/arch/arm/mach-imx/devices/platform-mxc_w1.c deleted file mode 100644 index ab42c6b0542c..000000000000 --- a/arch/arm/mach-imx/devices/platform-mxc_w1.c +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include "../hardware.h" -#include "devices-common.h" - -#define imx_mxc_w1_data_entry_single(soc) \ - { \ - .iobase = soc ## _OWIRE_BASE_ADDR, \ - } - -#ifdef CONFIG_SOC_IMX21 -const struct imx_mxc_w1_data imx21_mxc_w1_data __initconst = - imx_mxc_w1_data_entry_single(MX21); -#endif /* ifdef CONFIG_SOC_IMX21 */ - -#ifdef CONFIG_SOC_IMX27 -const struct imx_mxc_w1_data imx27_mxc_w1_data __initconst = - imx_mxc_w1_data_entry_single(MX27); -#endif /* ifdef CONFIG_SOC_IMX27 */ - -#ifdef CONFIG_SOC_IMX31 -const struct imx_mxc_w1_data imx31_mxc_w1_data __initconst = - imx_mxc_w1_data_entry_single(MX31); -#endif /* ifdef CONFIG_SOC_IMX31 */ - -#ifdef CONFIG_SOC_IMX35 -const struct imx_mxc_w1_data imx35_mxc_w1_data __initconst = - imx_mxc_w1_data_entry_single(MX35); -#endif /* ifdef CONFIG_SOC_IMX35 */ - -struct platform_device *__init imx_add_mxc_w1( - const struct imx_mxc_w1_data *data) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - }; - - return imx_add_platform_device("mxc_w1", 0, - res, ARRAY_SIZE(res), NULL, 0); -} diff --git a/arch/arm/mach-imx/devices/platform-pata_imx.c b/arch/arm/mach-imx/devices/platform-pata_imx.c deleted file mode 100644 index 0e985fffba78..000000000000 --- a/arch/arm/mach-imx/devices/platform-pata_imx.c +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include "../hardware.h" -#include "devices-common.h" - -#define imx_pata_imx_data_entry_single(soc, _size) \ - { \ - .iobase = soc ## _ATA_BASE_ADDR, \ - .iosize = _size, \ - .irq = soc ## _INT_ATA, \ - } - -#ifdef CONFIG_SOC_IMX27 -const struct imx_pata_imx_data imx27_pata_imx_data __initconst = - imx_pata_imx_data_entry_single(MX27, SZ_4K); -#endif /* ifdef CONFIG_SOC_IMX27 */ - -#ifdef CONFIG_SOC_IMX31 -const struct imx_pata_imx_data imx31_pata_imx_data __initconst = - imx_pata_imx_data_entry_single(MX31, SZ_16K); -#endif /* ifdef CONFIG_SOC_IMX31 */ - -#ifdef CONFIG_SOC_IMX35 -const struct imx_pata_imx_data imx35_pata_imx_data __initconst = - imx_pata_imx_data_entry_single(MX35, SZ_16K); -#endif /* ifdef CONFIG_SOC_IMX35 */ - -struct platform_device *__init imx_add_pata_imx( - const struct imx_pata_imx_data *data) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + data->iosize - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - return imx_add_platform_device("pata_imx", -1, - res, ARRAY_SIZE(res), NULL, 0); -} - diff --git a/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c b/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c deleted file mode 100644 index 40c261071144..000000000000 --- a/arch/arm/mach-imx/devices/platform-sdhci-esdhc-imx.c +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Pengutronix, Wolfram Sang <kernel@pengutronix.de> - */ - -#include <linux/platform_data/mmc-esdhc-imx.h> - -#include "../hardware.h" -#include "devices-common.h" - -#define imx_sdhci_esdhc_imx_data_entry_single(soc, _devid, _id, hwid) \ - { \ - .devid = _devid, \ - .id = _id, \ - .iobase = soc ## _ESDHC ## hwid ## _BASE_ADDR, \ - .irq = soc ## _INT_ESDHC ## hwid, \ - } - -#define imx_sdhci_esdhc_imx_data_entry(soc, devid, id, hwid) \ - [id] = imx_sdhci_esdhc_imx_data_entry_single(soc, devid, id, hwid) - -#ifdef CONFIG_SOC_IMX35 -const struct imx_sdhci_esdhc_imx_data -imx35_sdhci_esdhc_imx_data[] __initconst = { -#define imx35_sdhci_esdhc_imx_data_entry(_id, _hwid) \ - imx_sdhci_esdhc_imx_data_entry(MX35, "sdhci-esdhc-imx35", _id, _hwid) - imx35_sdhci_esdhc_imx_data_entry(0, 1), - imx35_sdhci_esdhc_imx_data_entry(1, 2), - imx35_sdhci_esdhc_imx_data_entry(2, 3), -}; -#endif /* ifdef CONFIG_SOC_IMX35 */ - -static const struct esdhc_platform_data default_esdhc_pdata __initconst = { - .wp_type = ESDHC_WP_NONE, - .cd_type = ESDHC_CD_NONE, -}; - -struct platform_device *__init imx_add_sdhci_esdhc_imx( - const struct imx_sdhci_esdhc_imx_data *data, - const struct esdhc_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - - /* - * If machine does not provide pdata, use the default one - * which means no WP/CD support - */ - if (!pdata) - pdata = &default_esdhc_pdata; - - return imx_add_platform_device_dmamask(data->devid, data->id, res, - ARRAY_SIZE(res), pdata, sizeof(*pdata), - DMA_BIT_MASK(32)); -} diff --git a/arch/arm/mach-imx/devices/platform-spi_imx.c b/arch/arm/mach-imx/devices/platform-spi_imx.c deleted file mode 100644 index 27747bf628a3..000000000000 --- a/arch/arm/mach-imx/devices/platform-spi_imx.c +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009-2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - */ -#include <linux/gpio/machine.h> -#include "../hardware.h" -#include "devices-common.h" - -#define imx_spi_imx_data_entry_single(soc, type, _devid, _id, hwid, _size) \ - { \ - .devid = _devid, \ - .id = _id, \ - .iobase = soc ## _ ## type ## hwid ## _BASE_ADDR, \ - .iosize = _size, \ - .irq = soc ## _INT_ ## type ## hwid, \ - } - -#define imx_spi_imx_data_entry(soc, type, devid, id, hwid, size) \ - [id] = imx_spi_imx_data_entry_single(soc, type, devid, id, hwid, size) - -#ifdef CONFIG_SOC_IMX21 -const struct imx_spi_imx_data imx21_cspi_data[] __initconst = { -#define imx21_cspi_data_entry(_id, _hwid) \ - imx_spi_imx_data_entry(MX21, CSPI, "imx21-cspi", _id, _hwid, SZ_4K) - imx21_cspi_data_entry(0, 1), - imx21_cspi_data_entry(1, 2), -}; -#endif - -#ifdef CONFIG_SOC_IMX27 -const struct imx_spi_imx_data imx27_cspi_data[] __initconst = { -#define imx27_cspi_data_entry(_id, _hwid) \ - imx_spi_imx_data_entry(MX27, CSPI, "imx27-cspi", _id, _hwid, SZ_4K) - imx27_cspi_data_entry(0, 1), - imx27_cspi_data_entry(1, 2), - imx27_cspi_data_entry(2, 3), -}; -#endif /* ifdef CONFIG_SOC_IMX27 */ - -#ifdef CONFIG_SOC_IMX31 -const struct imx_spi_imx_data imx31_cspi_data[] __initconst = { -#define imx31_cspi_data_entry(_id, _hwid) \ - imx_spi_imx_data_entry(MX31, CSPI, "imx31-cspi", _id, _hwid, SZ_4K) - imx31_cspi_data_entry(0, 1), - imx31_cspi_data_entry(1, 2), - imx31_cspi_data_entry(2, 3), -}; -#endif /* ifdef CONFIG_SOC_IMX31 */ - -#ifdef CONFIG_SOC_IMX35 -const struct imx_spi_imx_data imx35_cspi_data[] __initconst = { -#define imx35_cspi_data_entry(_id, _hwid) \ - imx_spi_imx_data_entry(MX35, CSPI, "imx35-cspi", _id, _hwid, SZ_4K) - imx35_cspi_data_entry(0, 1), - imx35_cspi_data_entry(1, 2), -}; -#endif /* ifdef CONFIG_SOC_IMX35 */ - -struct platform_device *__init imx_add_spi_imx( - const struct imx_spi_imx_data *data, struct gpiod_lookup_table *gtable) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + data->iosize - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - if (gtable) - gpiod_add_lookup_table(gtable); - return imx_add_platform_device(data->devid, data->id, - res, ARRAY_SIZE(res), NULL, 0); -} diff --git a/arch/arm/mach-imx/ehci-imx27.c b/arch/arm/mach-imx/ehci-imx27.c deleted file mode 100644 index 83962ce75983..000000000000 --- a/arch/arm/mach-imx/ehci-imx27.c +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> - * Copyright (C) 2010 Freescale Semiconductor, Inc. - */ - -#include <linux/platform_device.h> -#include <linux/io.h> -#include <linux/platform_data/usb-ehci-mxc.h> - -#include "ehci.h" -#include "hardware.h" - -#define USBCTRL_OTGBASE_OFFSET 0x600 - -#define MX27_OTG_SIC_SHIFT 29 -#define MX27_OTG_SIC_MASK (0x3 << MX27_OTG_SIC_SHIFT) -#define MX27_OTG_PM_BIT (1 << 24) - -#define MX27_H2_SIC_SHIFT 21 -#define MX27_H2_SIC_MASK (0x3 << MX27_H2_SIC_SHIFT) -#define MX27_H2_PM_BIT (1 << 16) -#define MX27_H2_DT_BIT (1 << 5) - -#define MX27_H1_SIC_SHIFT 13 -#define MX27_H1_SIC_MASK (0x3 << MX27_H1_SIC_SHIFT) -#define MX27_H1_PM_BIT (1 << 8) -#define MX27_H1_DT_BIT (1 << 4) - -int mx27_initialize_usb_hw(int port, unsigned int flags) -{ - unsigned int v; - - v = readl(MX27_IO_ADDRESS(MX27_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); - - switch (port) { - case 0: /* OTG port */ - v &= ~(MX27_OTG_SIC_MASK | MX27_OTG_PM_BIT); - v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_OTG_SIC_SHIFT; - - if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) - v |= MX27_OTG_PM_BIT; - break; - case 1: /* H1 port */ - v &= ~(MX27_H1_SIC_MASK | MX27_H1_PM_BIT | MX27_H1_DT_BIT); - v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_H1_SIC_SHIFT; - - if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) - v |= MX27_H1_PM_BIT; - - if (!(flags & MXC_EHCI_TTL_ENABLED)) - v |= MX27_H1_DT_BIT; - - break; - case 2: /* H2 port */ - v &= ~(MX27_H2_SIC_MASK | MX27_H2_PM_BIT | MX27_H2_DT_BIT); - v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_H2_SIC_SHIFT; - - if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) - v |= MX27_H2_PM_BIT; - - if (!(flags & MXC_EHCI_TTL_ENABLED)) - v |= MX27_H2_DT_BIT; - - break; - default: - return -EINVAL; - } - - writel(v, MX27_IO_ADDRESS(MX27_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); - - return 0; -} - diff --git a/arch/arm/mach-imx/ehci-imx31.c b/arch/arm/mach-imx/ehci-imx31.c deleted file mode 100644 index d6d794d53a63..000000000000 --- a/arch/arm/mach-imx/ehci-imx31.c +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> - * Copyright (C) 2010 Freescale Semiconductor, Inc. - */ - -#include <linux/platform_device.h> -#include <linux/io.h> -#include <linux/platform_data/usb-ehci-mxc.h> - -#include "ehci.h" -#include "hardware.h" - -#define USBCTRL_OTGBASE_OFFSET 0x600 - -#define MX31_OTG_SIC_SHIFT 29 -#define MX31_OTG_SIC_MASK (0x3 << MX31_OTG_SIC_SHIFT) -#define MX31_OTG_PM_BIT (1 << 24) - -#define MX31_H2_SIC_SHIFT 21 -#define MX31_H2_SIC_MASK (0x3 << MX31_H2_SIC_SHIFT) -#define MX31_H2_PM_BIT (1 << 16) -#define MX31_H2_DT_BIT (1 << 5) - -#define MX31_H1_SIC_SHIFT 13 -#define MX31_H1_SIC_MASK (0x3 << MX31_H1_SIC_SHIFT) -#define MX31_H1_PM_BIT (1 << 8) -#define MX31_H1_DT_BIT (1 << 4) - -int mx31_initialize_usb_hw(int port, unsigned int flags) -{ - unsigned int v; - - v = readl(MX31_IO_ADDRESS(MX31_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); - - switch (port) { - case 0: /* OTG port */ - v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); - v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_OTG_SIC_SHIFT; - - if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) - v |= MX31_OTG_PM_BIT; - - break; - case 1: /* H1 port */ - v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT); - v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H1_SIC_SHIFT; - - if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) - v |= MX31_H1_PM_BIT; - - if (!(flags & MXC_EHCI_TTL_ENABLED)) - v |= MX31_H1_DT_BIT; - - break; - case 2: /* H2 port */ - v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT); - v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H2_SIC_SHIFT; - - if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) - v |= MX31_H2_PM_BIT; - - if (!(flags & MXC_EHCI_TTL_ENABLED)) - v |= MX31_H2_DT_BIT; - - break; - default: - return -EINVAL; - } - - writel(v, MX31_IO_ADDRESS(MX31_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); - - return 0; -} diff --git a/arch/arm/mach-imx/ehci-imx35.c b/arch/arm/mach-imx/ehci-imx35.c deleted file mode 100644 index e6ba965c5c5b..000000000000 --- a/arch/arm/mach-imx/ehci-imx35.c +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> - * Copyright (C) 2010 Freescale Semiconductor, Inc. - */ - -#include <linux/platform_device.h> -#include <linux/io.h> -#include <linux/platform_data/usb-ehci-mxc.h> - -#include "ehci.h" -#include "hardware.h" - -#define USBCTRL_OTGBASE_OFFSET 0x600 - -#define MX35_OTG_SIC_SHIFT 29 -#define MX35_OTG_SIC_MASK (0x3 << MX35_OTG_SIC_SHIFT) -#define MX35_OTG_PM_BIT (1 << 24) -#define MX35_OTG_PP_BIT (1 << 11) -#define MX35_OTG_OCPOL_BIT (1 << 3) - -#define MX35_H1_SIC_SHIFT 21 -#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT) -#define MX35_H1_PP_BIT (1 << 18) -#define MX35_H1_PM_BIT (1 << 16) -#define MX35_H1_IPPUE_UP_BIT (1 << 7) -#define MX35_H1_IPPUE_DOWN_BIT (1 << 6) -#define MX35_H1_TLL_BIT (1 << 5) -#define MX35_H1_USBTE_BIT (1 << 4) -#define MX35_H1_OCPOL_BIT (1 << 2) - -int mx35_initialize_usb_hw(int port, unsigned int flags) -{ - unsigned int v; - - v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); - - switch (port) { - case 0: /* OTG port */ - v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT | MX35_OTG_PP_BIT | - MX35_OTG_OCPOL_BIT); - v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_OTG_SIC_SHIFT; - - if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) - v |= MX35_OTG_PM_BIT; - - if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH) - v |= MX35_OTG_PP_BIT; - - if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW)) - v |= MX35_OTG_OCPOL_BIT; - - break; - case 1: /* H1 port */ - v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_PP_BIT | - MX35_H1_OCPOL_BIT | MX35_H1_TLL_BIT | MX35_H1_USBTE_BIT | - MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT); - v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_H1_SIC_SHIFT; - - if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) - v |= MX35_H1_PM_BIT; - - if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH) - v |= MX35_H1_PP_BIT; - - if (!(flags & MXC_EHCI_OC_PIN_ACTIVE_LOW)) - v |= MX35_H1_OCPOL_BIT; - - if (!(flags & MXC_EHCI_TTL_ENABLED)) - v |= MX35_H1_TLL_BIT; - - if (flags & MXC_EHCI_INTERNAL_PHY) - v |= MX35_H1_USBTE_BIT; - - if (flags & MXC_EHCI_IPPUE_DOWN) - v |= MX35_H1_IPPUE_DOWN_BIT; - - if (flags & MXC_EHCI_IPPUE_UP) - v |= MX35_H1_IPPUE_UP_BIT; - - break; - default: - return -EINVAL; - } - - writel(v, MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); - - return 0; -} diff --git a/arch/arm/mach-imx/ehci.h b/arch/arm/mach-imx/ehci.h deleted file mode 100644 index b7ad6175f5bf..000000000000 --- a/arch/arm/mach-imx/ehci.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __MACH_IMX_EHCI_H -#define __MACH_IMX_EHCI_H - -/* values for portsc field */ -#define MXC_EHCI_PHY_LOW_POWER_SUSPEND (1 << 23) -#define MXC_EHCI_FORCE_FS (1 << 24) -#define MXC_EHCI_UTMI_8BIT (0 << 28) -#define MXC_EHCI_UTMI_16BIT (1 << 28) -#define MXC_EHCI_SERIAL (1 << 29) -#define MXC_EHCI_MODE_UTMI (0 << 30) -#define MXC_EHCI_MODE_PHILIPS (1 << 30) -#define MXC_EHCI_MODE_ULPI (2 << 30) -#define MXC_EHCI_MODE_SERIAL (3 << 30) - -/* values for flags field */ -#define MXC_EHCI_INTERFACE_DIFF_UNI (0 << 0) -#define MXC_EHCI_INTERFACE_DIFF_BI (1 << 0) -#define MXC_EHCI_INTERFACE_SINGLE_UNI (2 << 0) -#define MXC_EHCI_INTERFACE_SINGLE_BI (3 << 0) -#define MXC_EHCI_INTERFACE_MASK (0xf) - -#define MXC_EHCI_POWER_PINS_ENABLED (1 << 5) -#define MXC_EHCI_PWR_PIN_ACTIVE_HIGH (1 << 6) -#define MXC_EHCI_OC_PIN_ACTIVE_LOW (1 << 7) -#define MXC_EHCI_TTL_ENABLED (1 << 8) - -#define MXC_EHCI_INTERNAL_PHY (1 << 9) -#define MXC_EHCI_IPPUE_DOWN (1 << 10) -#define MXC_EHCI_IPPUE_UP (1 << 11) -#define MXC_EHCI_WAKEUP_ENABLED (1 << 12) -#define MXC_EHCI_ITC_NO_THRESHOLD (1 << 13) - -#define MXC_USBCTRL_OFFSET 0 -#define MXC_USB_PHY_CTR_FUNC_OFFSET 0x8 -#define MXC_USB_PHY_CTR_FUNC2_OFFSET 0xc -#define MXC_USBH2CTRL_OFFSET 0x14 - -int mx25_initialize_usb_hw(int port, unsigned int flags); -int mx31_initialize_usb_hw(int port, unsigned int flags); -int mx35_initialize_usb_hw(int port, unsigned int flags); -int mx27_initialize_usb_hw(int port, unsigned int flags); - -#endif /* __MACH_IMX_EHCI_H */ diff --git a/arch/arm/mach-imx/hardware.h b/arch/arm/mach-imx/hardware.h index 92c5a9c9f94b..7acf7ce467ed 100644 --- a/arch/arm/mach-imx/hardware.h +++ b/arch/arm/mach-imx/hardware.h @@ -97,7 +97,6 @@ #include "mx31.h" #include "mx35.h" #include "mx2x.h" -#include "mx21.h" #include "mx27.h" #define imx_map_entry(soc, name, _type) { \ diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c deleted file mode 100644 index 29d97bd64381..000000000000 --- a/arch/arm/mach-imx/imx27-dt.c +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2012 Sascha Hauer, Pengutronix - */ - -#include <linux/irq.h> -#include <linux/of_irq.h> -#include <linux/of_platform.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> - -#include "common.h" -#include "mx27.h" - -static const char * const imx27_dt_board_compat[] __initconst = { - "fsl,imx27", - NULL -}; - -DT_MACHINE_START(IMX27_DT, "Freescale i.MX27 (Device Tree Support)") - .map_io = mx27_map_io, - .init_early = imx27_init_early, - .init_irq = mx27_init_irq, - .init_late = imx27_pm_init, - .dt_compat = imx27_dt_board_compat, -MACHINE_END diff --git a/arch/arm/mach-imx/iomux-imx31.c b/arch/arm/mach-imx/iomux-imx31.c deleted file mode 100644 index abfc306655c8..000000000000 --- a/arch/arm/mach-imx/iomux-imx31.c +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> - * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch> - */ -#include <linux/gpio.h> -#include <linux/module.h> -#include <linux/spinlock.h> -#include <linux/io.h> -#include <linux/kernel.h> - -#include "hardware.h" -#include "iomux-mx3.h" - -/* - * IOMUX register (base) addresses - */ -#define IOMUX_BASE MX31_IO_ADDRESS(MX31_IOMUXC_BASE_ADDR) -#define IOMUXINT_OBS1 (IOMUX_BASE + 0x000) -#define IOMUXINT_OBS2 (IOMUX_BASE + 0x004) -#define IOMUXGPR (IOMUX_BASE + 0x008) -#define IOMUXSW_MUX_CTL (IOMUX_BASE + 0x00C) -#define IOMUXSW_PAD_CTL (IOMUX_BASE + 0x154) - -static DEFINE_SPINLOCK(gpio_mux_lock); - -#define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3) - -static DECLARE_BITMAP(mxc_pin_alloc_map, NB_PORTS * 32); -/* - * set the mode for a IOMUX pin. - */ -void mxc_iomux_mode(unsigned int pin_mode) -{ - u32 field; - u32 l; - u32 mode; - void __iomem *reg; - - reg = IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK); - field = pin_mode & 0x3; - mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT; - - spin_lock(&gpio_mux_lock); - - l = imx_readl(reg); - l &= ~(0xff << (field * 8)); - l |= mode << (field * 8); - imx_writel(l, reg); - - spin_unlock(&gpio_mux_lock); -} - -/* - * This function configures the pad value for a IOMUX pin. - */ -void mxc_iomux_set_pad(enum iomux_pins pin, u32 config) -{ - u32 field, l; - void __iomem *reg; - - pin &= IOMUX_PADNUM_MASK; - reg = IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4; - field = (pin + 2) % 3; - - pr_debug("%s: reg offset = 0x%x, field = %d\n", - __func__, (pin + 2) / 3, field); - - spin_lock(&gpio_mux_lock); - - l = imx_readl(reg); - l &= ~(0x1ff << (field * 10)); - l |= config << (field * 10); - imx_writel(l, reg); - - spin_unlock(&gpio_mux_lock); -} - -/* - * allocs a single pin: - * - reserves the pin so that it is not claimed by another driver - * - setups the iomux according to the configuration - */ -int mxc_iomux_alloc_pin(unsigned int pin, const char *label) -{ - unsigned pad = pin & IOMUX_PADNUM_MASK; - - if (pad >= (PIN_MAX + 1)) { - printk(KERN_ERR "mxc_iomux: Attempt to request nonexistent pin %u for \"%s\"\n", - pad, label ? label : "?"); - return -EINVAL; - } - - if (test_and_set_bit(pad, mxc_pin_alloc_map)) { - printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n", - pad, label ? label : "?"); - return -EBUSY; - } - mxc_iomux_mode(pin); - - return 0; -} - -int mxc_iomux_setup_multiple_pins(const unsigned int *pin_list, unsigned count, - const char *label) -{ - const unsigned int *p = pin_list; - int i; - int ret = -EINVAL; - - for (i = 0; i < count; i++) { - ret = mxc_iomux_alloc_pin(*p, label); - if (ret) - goto setup_error; - p++; - } - return 0; - -setup_error: - mxc_iomux_release_multiple_pins(pin_list, i); - return ret; -} - -void mxc_iomux_release_pin(unsigned int pin) -{ - unsigned pad = pin & IOMUX_PADNUM_MASK; - - if (pad < (PIN_MAX + 1)) - clear_bit(pad, mxc_pin_alloc_map); -} - -void mxc_iomux_release_multiple_pins(const unsigned int *pin_list, int count) -{ - const unsigned int *p = pin_list; - int i; - - for (i = 0; i < count; i++) { - mxc_iomux_release_pin(*p); - p++; - } -} - -/* - * This function enables/disables the general purpose function for a particular - * signal. - */ -void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en) -{ - u32 l; - - spin_lock(&gpio_mux_lock); - l = imx_readl(IOMUXGPR); - if (en) - l |= gp; - else - l &= ~gp; - - imx_writel(l, IOMUXGPR); - spin_unlock(&gpio_mux_lock); -} diff --git a/arch/arm/mach-imx/iomux-mx21.h b/arch/arm/mach-imx/iomux-mx21.h deleted file mode 100644 index 6eab3478fb80..000000000000 --- a/arch/arm/mach-imx/iomux-mx21.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.de> - */ -#ifndef __MACH_IOMUX_MX21_H__ -#define __MACH_IOMUX_MX21_H__ - -#include "iomux-mx2x.h" -#include "iomux-v1.h" - -/* Primary GPIO pin functions */ - -#define PB22_PF_USBH1_BYP (GPIO_PORTB | GPIO_PF | 22) -#define PB25_PF_USBH1_ON (GPIO_PORTB | GPIO_PF | 25) -#define PC5_PF_USBOTG_SDA (GPIO_PORTC | GPIO_PF | 5) -#define PC6_PF_USBOTG_SCL (GPIO_PORTC | GPIO_PF | 6) -#define PC7_PF_USBOTG_ON (GPIO_PORTC | GPIO_PF | 7) -#define PC8_PF_USBOTG_FS (GPIO_PORTC | GPIO_PF | 8) -#define PC9_PF_USBOTG_OE (GPIO_PORTC | GPIO_PF | 9) -#define PC10_PF_USBOTG_TXDM (GPIO_PORTC | GPIO_PF | 10) -#define PC11_PF_USBOTG_TXDP (GPIO_PORTC | GPIO_PF | 11) -#define PC12_PF_USBOTG_RXDM (GPIO_PORTC | GPIO_PF | 12) -#define PC13_PF_USBOTG_RXDP (GPIO_PORTC | GPIO_PF | 13) -#define PC16_PF_SAP_FS (GPIO_PORTC | GPIO_PF | 16) -#define PC17_PF_SAP_RXD (GPIO_PORTC | GPIO_PF | 17) -#define PC18_PF_SAP_TXD (GPIO_PORTC | GPIO_PF | 18) -#define PC19_PF_SAP_CLK (GPIO_PORTC | GPIO_PF | 19) -#define PE0_PF_TEST_WB2 (GPIO_PORTE | GPIO_PF | 0) -#define PE1_PF_TEST_WB1 (GPIO_PORTE | GPIO_PF | 1) -#define PE2_PF_TEST_WB0 (GPIO_PORTE | GPIO_PF | 2) -#define PF1_PF_NFCE (GPIO_PORTF | GPIO_PF | 1) -#define PF3_PF_NFCLE (GPIO_PORTF | GPIO_PF | 3) -#define PF7_PF_NFIO0 (GPIO_PORTF | GPIO_PF | 7) -#define PF8_PF_NFIO1 (GPIO_PORTF | GPIO_PF | 8) -#define PF9_PF_NFIO2 (GPIO_PORTF | GPIO_PF | 9) -#define PF10_PF_NFIO3 (GPIO_PORTF | GPIO_PF | 10) -#define PF11_PF_NFIO4 (GPIO_PORTF | GPIO_PF | 11) -#define PF12_PF_NFIO5 (GPIO_PORTF | GPIO_PF | 12) -#define PF13_PF_NFIO6 (GPIO_PORTF | GPIO_PF | 13) -#define PF14_PF_NFIO7 (GPIO_PORTF | GPIO_PF | 14) -#define PF16_PF_RES (GPIO_PORTF | GPIO_PF | 16) - -/* Alternate GPIO pin functions */ - -#define PA5_AF_BMI_CLK_CS (GPIO_PORTA | GPIO_AF | 5) -#define PA6_AF_BMI_D0 (GPIO_PORTA | GPIO_AF | 6) -#define PA7_AF_BMI_D1 (GPIO_PORTA | GPIO_AF | 7) -#define PA8_AF_BMI_D2 (GPIO_PORTA | GPIO_AF | 8) -#define PA9_AF_BMI_D3 (GPIO_PORTA | GPIO_AF | 9) -#define PA10_AF_BMI_D4 (GPIO_PORTA | GPIO_AF | 10) -#define PA11_AF_BMI_D5 (GPIO_PORTA | GPIO_AF | 11) -#define PA12_AF_BMI_D6 (GPIO_PORTA | GPIO_AF | 12) -#define PA13_AF_BMI_D7 (GPIO_PORTA | GPIO_AF | 13) -#define PA14_AF_BMI_D8 (GPIO_PORTA | GPIO_AF | 14) -#define PA15_AF_BMI_D9 (GPIO_PORTA | GPIO_AF | 15) -#define PA16_AF_BMI_D10 (GPIO_PORTA | GPIO_AF | 16) -#define PA17_AF_BMI_D11 (GPIO_PORTA | GPIO_AF | 17) -#define PA18_AF_BMI_D12 (GPIO_PORTA | GPIO_AF | 18) -#define PA19_AF_BMI_D13 (GPIO_PORTA | GPIO_AF | 19) -#define PA20_AF_BMI_D14 (GPIO_PORTA | GPIO_AF | 20) -#define PA21_AF_BMI_D15 (GPIO_PORTA | GPIO_AF | 21) -#define PA22_AF_BMI_READ_REQ (GPIO_PORTA | GPIO_AF | 22) -#define PA23_AF_BMI_WRITE (GPIO_PORTA | GPIO_AF | 23) -#define PA29_AF_BMI_RX_FULL (GPIO_PORTA | GPIO_AF | 29) -#define PA30_AF_BMI_READ (GPIO_PORTA | GPIO_AF | 30) - -/* AIN GPIO pin functions */ - -#define PC14_AIN_SYS_CLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14) -#define PD21_AIN_USBH2_FS (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 21) -#define PD22_AIN_USBH2_OE (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 22) -#define PD23_AIN_USBH2_TXDM (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 23) -#define PD24_AIN_USBH2_TXDP (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 24) -#define PE8_AIN_IR_TXD (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 8) -#define PF0_AIN_PC_RST (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 0) -#define PF1_AIN_PC_CE1 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 1) -#define PF2_AIN_PC_CE2 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 2) -#define PF3_AIN_PC_POE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 3) -#define PF4_AIN_PC_OE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 4) -#define PF5_AIN_PC_RW (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 5) - -/* BIN GPIO pin functions */ - -#define PC14_BIN_SYS_CLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14) -#define PD27_BIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_BIN | GPIO_OUT | 27) - -/* CIN GPIO pin functions */ - -#define PB26_CIN_USBH1_RXDAT (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 26) - -/* AOUT GPIO pin functions */ - -#define PA29_AOUT_BMI_WAIT (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 29) -#define PD19_AOUT_USBH2_RXDM (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 19) -#define PD20_AOUT_USBH2_RXDP (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 20) -#define PD25_AOUT_EXT_DMAREQ (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 25) -#define PD26_AOUT_USBOTG_RXDAT (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 26) -#define PE9_AOUT_IR_RXD (GPIO_PORTE | GPIO_AOUT | GPIO_IN | 9) -#define PF6_AOUT_PC_BVD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 6) -#define PF7_AOUT_PC_BVD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 7) -#define PF8_AOUT_PC_VS2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 8) -#define PF9_AOUT_PC_VS1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 9) -#define PF10_AOUT_PC_WP (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 10) -#define PF11_AOUT_PC_READY (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 11) -#define PF12_AOUT_PC_WAIT (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 12) -#define PF13_AOUT_PC_CD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 13) -#define PF14_AOUT_PC_CD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 14) - -#endif /* ifndef __MACH_IOMUX_MX21_H__ */ diff --git a/arch/arm/mach-imx/iomux-mx27.h b/arch/arm/mach-imx/iomux-mx27.h deleted file mode 100644 index 4d848d1ef1e3..000000000000 --- a/arch/arm/mach-imx/iomux-mx27.h +++ /dev/null @@ -1,192 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> - * Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.de> - */ -#ifndef __MACH_IOMUX_MX27_H__ -#define __MACH_IOMUX_MX27_H__ - -#include "iomux-mx2x.h" -#include "iomux-v1.h" - -/* Primary GPIO pin functions */ - -#define PA0_PF_USBH2_CLK (GPIO_PORTA | GPIO_PF | 0) -#define PA1_PF_USBH2_DIR (GPIO_PORTA | GPIO_PF | 1) -#define PA2_PF_USBH2_DATA7 (GPIO_PORTA | GPIO_PF | 2) -#define PA3_PF_USBH2_NXT (GPIO_PORTA | GPIO_PF | 3) -#define PA4_PF_USBH2_STP (GPIO_PORTA | GPIO_PF | 4) -#define PB22_PF_USBH1_SUSP (GPIO_PORTB | GPIO_PF | 22) -#define PB25_PF_USBH1_RCV (GPIO_PORTB | GPIO_PF | 25) -#define PC5_PF_I2C2_SDA (GPIO_PORTC | GPIO_PF | GPIO_IN | 5) -#define PC6_PF_I2C2_SCL (GPIO_PORTC | GPIO_PF | GPIO_IN | 6) -#define PC7_PF_USBOTG_DATA5 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 7) -#define PC8_PF_USBOTG_DATA6 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 8) -#define PC9_PF_USBOTG_DATA0 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9) -#define PC10_PF_USBOTG_DATA2 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 10) -#define PC11_PF_USBOTG_DATA1 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11) -#define PC12_PF_USBOTG_DATA4 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 12) -#define PC13_PF_USBOTG_DATA3 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 13) -#define PC16_PF_SSI4_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 16) -#define PC17_PF_SSI4_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 17) -#define PC18_PF_SSI4_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 18) -#define PC19_PF_SSI4_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 19) -#define PD0_PF_SD3_CMD (GPIO_PORTD | GPIO_PF | 0) -#define PD1_PF_SD3_CLK (GPIO_PORTD | GPIO_PF | 1) -#define PD2_PF_ATA_DATA0 (GPIO_PORTD | GPIO_PF | 2) -#define PD3_PF_ATA_DATA1 (GPIO_PORTD | GPIO_PF | 3) -#define PD4_PF_ATA_DATA2 (GPIO_PORTD | GPIO_PF | 4) -#define PD5_PF_ATA_DATA3 (GPIO_PORTD | GPIO_PF | 5) -#define PD6_PF_ATA_DATA4 (GPIO_PORTD | GPIO_PF | 6) -#define PD7_PF_ATA_DATA5 (GPIO_PORTD | GPIO_PF | 7) -#define PD8_PF_ATA_DATA6 (GPIO_PORTD | GPIO_PF | 8) -#define PD9_PF_ATA_DATA7 (GPIO_PORTD | GPIO_PF | 9) -#define PD10_PF_ATA_DATA8 (GPIO_PORTD | GPIO_PF | 10) -#define PD11_PF_ATA_DATA9 (GPIO_PORTD | GPIO_PF | 11) -#define PD12_PF_ATA_DATA10 (GPIO_PORTD | GPIO_PF | 12) -#define PD13_PF_ATA_DATA11 (GPIO_PORTD | GPIO_PF | 13) -#define PD14_PF_ATA_DATA12 (GPIO_PORTD | GPIO_PF | 14) -#define PD15_PF_ATA_DATA13 (GPIO_PORTD | GPIO_PF | 15) -#define PD16_PF_ATA_DATA14 (GPIO_PORTD | GPIO_PF | 16) -#define PE0_PF_USBOTG_NXT (GPIO_PORTE | GPIO_PF | GPIO_OUT | 0) -#define PE1_PF_USBOTG_STP (GPIO_PORTE | GPIO_PF | GPIO_OUT | 1) -#define PE2_PF_USBOTG_DIR (GPIO_PORTE | GPIO_PF | GPIO_OUT | 2) -#define PE24_PF_USBOTG_CLK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 24) -#define PE25_PF_USBOTG_DATA7 (GPIO_PORTE | GPIO_PF | GPIO_OUT | 25) -#define PF1_PF_NFCLE (GPIO_PORTF | GPIO_PF | 1) -#define PF3_PF_NFCE (GPIO_PORTF | GPIO_PF | 3) -#define PF7_PF_PC_POE (GPIO_PORTF | GPIO_PF | 7) -#define PF8_PF_PC_RW (GPIO_PORTF | GPIO_PF | 8) -#define PF9_PF_PC_IOIS16 (GPIO_PORTF | GPIO_PF | 9) -#define PF10_PF_PC_RST (GPIO_PORTF | GPIO_PF | 10) -#define PF11_PF_PC_BVD2 (GPIO_PORTF | GPIO_PF | 11) -#define PF12_PF_PC_BVD1 (GPIO_PORTF | GPIO_PF | 12) -#define PF13_PF_PC_VS2 (GPIO_PORTF | GPIO_PF | 13) -#define PF14_PF_PC_VS1 (GPIO_PORTF | GPIO_PF | 14) -#define PF16_PF_PC_PWRON (GPIO_PORTF | GPIO_PF | 16) -#define PF17_PF_PC_READY (GPIO_PORTF | GPIO_PF | 17) -#define PF18_PF_PC_WAIT (GPIO_PORTF | GPIO_PF | 18) -#define PF19_PF_PC_CD2 (GPIO_PORTF | GPIO_PF | 19) -#define PF20_PF_PC_CD1 (GPIO_PORTF | GPIO_PF | 20) -#define PF23_PF_ATA_DATA15 (GPIO_PORTF | GPIO_PF | 23) - -/* Alternate GPIO pin functions */ - -#define PB4_AF_MSHC_DATA0 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 4) -#define PB5_AF_MSHC_DATA1 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 5) -#define PB6_AF_MSHC_DATA2 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 6) -#define PB7_AF_MSHC_DATA4 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 7) -#define PB8_AF_MSHC_BS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 8) -#define PB9_AF_MSHC_SCLK (GPIO_PORTB | GPIO_AF | GPIO_OUT | 9) -#define PB10_AF_UART6_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 10) -#define PB11_AF_UART6_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 11) -#define PB12_AF_UART6_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 12) -#define PB13_AF_UART6_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 13) -#define PB18_AF_UART5_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 18) -#define PB19_AF_UART5_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 19) -#define PB20_AF_UART5_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 20) -#define PB21_AF_UART5_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 21) -#define PC8_AF_FEC_MDIO (GPIO_PORTC | GPIO_AF | GPIO_IN | 8) -#define PC24_AF_GPT5_TOUT (GPIO_PORTC | GPIO_AF | 24) -#define PC25_AF_GPT5_TIN (GPIO_PORTC | GPIO_AF | 25) -#define PC26_AF_GPT4_TOUT (GPIO_PORTC | GPIO_AF | 26) -#define PC27_AF_GPT4_TIN (GPIO_PORTC | GPIO_AF | 27) -#define PD1_AF_ETMTRACE_PKT15 (GPIO_PORTD | GPIO_AF | 1) -#define PD6_AF_ETMTRACE_PKT14 (GPIO_PORTD | GPIO_AF | 6) -#define PD7_AF_ETMTRACE_PKT13 (GPIO_PORTD | GPIO_AF | 7) -#define PD9_AF_ETMTRACE_PKT12 (GPIO_PORTD | GPIO_AF | 9) -#define PD2_AF_SD3_D0 (GPIO_PORTD | GPIO_AF | 2) -#define PD3_AF_SD3_D1 (GPIO_PORTD | GPIO_AF | 3) -#define PD4_AF_SD3_D2 (GPIO_PORTD | GPIO_AF | 4) -#define PD5_AF_SD3_D3 (GPIO_PORTD | GPIO_AF | 5) -#define PD8_AF_FEC_MDIO (GPIO_PORTD | GPIO_AF | GPIO_IN | 8) -#define PD10_AF_ETMTRACE_PKT11 (GPIO_PORTD | GPIO_AF | 10) -#define PD11_AF_ETMTRACE_PKT10 (GPIO_PORTD | GPIO_AF | 11) -#define PD12_AF_ETMTRACE_PKT9 (GPIO_PORTD | GPIO_AF | 12) -#define PD13_AF_ETMTRACE_PKT8 (GPIO_PORTD | GPIO_AF | 13) -#define PD14_AF_ETMTRACE_PKT7 (GPIO_PORTD | GPIO_AF | 14) -#define PD15_AF_ETMTRACE_PKT6 (GPIO_PORTD | GPIO_AF | 15) -#define PD16_AF_ETMTRACE_PKT5 (GPIO_PORTD | GPIO_AF | 16) -#define PF1_AF_ETMTRACE_PKT0 (GPIO_PORTF | GPIO_AF | 1) -#define PF3_AF_ETMTRACE_PKT2 (GPIO_PORTF | GPIO_AF | 3) -#define PF5_AF_ETMPIPESTAT11 (GPIO_PORTF | GPIO_AF | 5) -#define PF7_AF_ATA_BUFFER_EN (GPIO_PORTF | GPIO_AF | 7) -#define PF8_AF_ATA_IORDY (GPIO_PORTF | GPIO_AF | 8) -#define PF9_AF_ATA_INTRQ (GPIO_PORTF | GPIO_AF | 9) -#define PF10_AF_ATA_RESET (GPIO_PORTF | GPIO_AF | 10) -#define PF11_AF_ATA_DMACK (GPIO_PORTF | GPIO_AF | 11) -#define PF12_AF_ATA_DMAREQ (GPIO_PORTF | GPIO_AF | 12) -#define PF13_AF_ATA_DA0 (GPIO_PORTF | GPIO_AF | 13) -#define PF14_AF_ATA_DA1 (GPIO_PORTF | GPIO_AF | 14) -#define PF15_AF_ETMTRACE_SYNC (GPIO_PORTF | GPIO_AF | 15) -#define PF16_AF_ATA_DA2 (GPIO_PORTF | GPIO_AF | 16) -#define PF17_AF_ATA_CS0 (GPIO_PORTF | GPIO_AF | 17) -#define PF18_AF_ATA_CS1 (GPIO_PORTF | GPIO_AF | 18) -#define PF19_AF_ATA_DIOW (GPIO_PORTF | GPIO_AF | 19) -#define PF20_AF_ATA_DIOR (GPIO_PORTF | GPIO_AF | 20) -#define PF22_AF_ETMTRACE_CLK (GPIO_PORTF | GPIO_AF | 22) -#define PF23_AF_ETMTRACE_PKT4 (GPIO_PORTF | GPIO_AF | 23) - -/* AIN GPIO pin functions */ - -#define PC14_AIN_SSI1_MCLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14) -#define PC15_AIN_GPT6_TOUT (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 15) -#define PD0_AIN_FEC_TXD0 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 0) -#define PD1_AIN_FEC_TXD1 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 1) -#define PD2_AIN_FEC_TXD2 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 2) -#define PD3_AIN_FEC_TXD3 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 3) -#define PD9_AIN_FEC_MDC (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 9) -#define PD16_AIN_FEC_TX_ER (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 16) -#define PD27_AIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 27) -#define PF23_AIN_FEC_TX_EN (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 23) - -/* BIN GPIO pin functions */ - -#define PC14_BIN_SSI2_MCLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14) - -/* CIN GPIO pin functions */ - -#define PD2_CIN_SLCDC1_DAT0 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 2) -#define PD3_CIN_SLCDC1_DAT1 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 3) -#define PD4_CIN_SLCDC1_DAT2 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 4) -#define PD5_CIN_SLCDC1_DAT3 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 5) -#define PD6_CIN_SLCDC1_DAT4 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 6) -#define PD7_CIN_SLCDC1_DAT5 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 7) -#define PD8_CIN_SLCDC1_DAT6 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 8) -#define PD9_CIN_SLCDC1_DAT7 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 9) -#define PD10_CIN_SLCDC1_DAT8 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 10) -#define PD11_CIN_SLCDC1_DAT9 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 11) -#define PD12_CIN_SLCDC1_DAT10 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 12) -#define PD13_CIN_SLCDC1_DAT11 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 13) -#define PD14_CIN_SLCDC1_DAT12 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 14) -#define PD15_CIN_SLCDC1_DAT13 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 15) -#define PD16_CIN_SLCDC1_DAT14 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 16) -#define PD23_CIN_SLCDC1_DAT15 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 23) -#define PF27_CIN_EXT_DMA_GRANT (GPIO_PORTF | GPIO_CIN | GPIO_OUT | 27) -/* LCDC_TESTx on PBxx omitted, because it's not clear what they do */ - -/* AOUT GPIO pin functions */ - -#define PC14_AOUT_GPT6_TIN (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 14) -#define PD4_AOUT_FEC_RX_ER (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 4) -#define PD5_AOUT_FEC_RXD1 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 5) -#define PD6_AOUT_FEC_RXD2 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 6) -#define PD7_AOUT_FEC_RXD3 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 7) -#define PD10_AOUT_FEC_CRS (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 10) -#define PD11_AOUT_FEC_TX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 11) -#define PD12_AOUT_FEC_RXD0 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 12) -#define PD13_AOUT_FEC_RX_DV (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 13) -#define PD14_AOUT_FEC_RX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 14) -#define PD15_AOUT_FEC_COL (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 15) - -/* BOUT GPIO pin functions */ - -#define PC17_BOUT_PC_IOIS16 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 17) -#define PC18_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 18) -#define PC19_BOUT_PC_BVD1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 19) -#define PC28_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 28) -#define PC29_BOUT_PC_VS1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 29) -#define PC30_BOUT_PC_READY (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 30) -#define PC31_BOUT_PC_WAIT (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 31) - -#endif /* __MACH_IOMUX_MX27_H__ */ diff --git a/arch/arm/mach-imx/iomux-mx2x.h b/arch/arm/mach-imx/iomux-mx2x.h deleted file mode 100644 index ce6b6d20a4f0..000000000000 --- a/arch/arm/mach-imx/iomux-mx2x.h +++ /dev/null @@ -1,217 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> - * Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.de> - */ -#ifndef __MACH_IOMUX_MX2x_H__ -#define __MACH_IOMUX_MX2x_H__ - -/* Primary GPIO pin functions */ - -#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_PF | GPIO_OUT | 5) -#define PA6_PF_LD0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 6) -#define PA7_PF_LD1 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 7) -#define PA8_PF_LD2 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 8) -#define PA9_PF_LD3 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 9) -#define PA10_PF_LD4 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 10) -#define PA11_PF_LD5 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 11) -#define PA12_PF_LD6 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 12) -#define PA13_PF_LD7 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 13) -#define PA14_PF_LD8 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 14) -#define PA15_PF_LD9 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15) -#define PA16_PF_LD10 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16) -#define PA17_PF_LD11 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 17) -#define PA18_PF_LD12 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 18) -#define PA19_PF_LD13 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 19) -#define PA20_PF_LD14 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 20) -#define PA21_PF_LD15 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 21) -#define PA22_PF_LD16 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 22) -#define PA23_PF_LD17 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 23) -#define PA24_PF_REV (GPIO_PORTA | GPIO_PF | GPIO_OUT | 24) -#define PA25_PF_CLS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 25) -#define PA26_PF_PS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 26) -#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_PF | GPIO_OUT | 27) -#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 28) -#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 29) -#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_PF | GPIO_OUT | 30) -#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_PF | GPIO_OUT | 31) -#define PB4_PF_SD2_D0 (GPIO_PORTB | GPIO_PF | 4) -#define PB5_PF_SD2_D1 (GPIO_PORTB | GPIO_PF | 5) -#define PB6_PF_SD2_D2 (GPIO_PORTB | GPIO_PF | 6) -#define PB7_PF_SD2_D3 (GPIO_PORTB | GPIO_PF | 7) -#define PB8_PF_SD2_CMD (GPIO_PORTB | GPIO_PF | 8) -#define PB9_PF_SD2_CLK (GPIO_PORTB | GPIO_PF | 9) -#define PB10_PF_CSI_D0 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 10) -#define PB11_PF_CSI_D1 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 11) -#define PB12_PF_CSI_D2 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 12) -#define PB13_PF_CSI_D3 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 13) -#define PB14_PF_CSI_D4 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 14) -#define PB15_PF_CSI_MCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 15) -#define PB16_PF_CSI_PIXCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 16) -#define PB17_PF_CSI_D5 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 17) -#define PB18_PF_CSI_D6 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 18) -#define PB19_PF_CSI_D7 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 19) -#define PB20_PF_CSI_VSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 20) -#define PB21_PF_CSI_HSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 21) -#define PB23_PF_USB_PWR (GPIO_PORTB | GPIO_PF | 23) -#define PB24_PF_USB_OC (GPIO_PORTB | GPIO_PF | 24) -#define PB26_PF_USBH1_FS (GPIO_PORTB | GPIO_PF | 26) -#define PB27_PF_USBH1_OE (GPIO_PORTB | GPIO_PF | 27) -#define PB28_PF_USBH1_TXDM (GPIO_PORTB | GPIO_PF | 28) -#define PB29_PF_USBH1_TXDP (GPIO_PORTB | GPIO_PF | 29) -#define PB30_PF_USBH1_RXDM (GPIO_PORTB | GPIO_PF | 30) -#define PB31_PF_USBH1_RXDP (GPIO_PORTB | GPIO_PF | 31) -#define PC14_PF_TOUT (GPIO_PORTC | GPIO_PF | 14) -#define PC15_PF_TIN (GPIO_PORTC | GPIO_PF | 15) -#define PC20_PF_SSI1_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 20) -#define PC21_PF_SSI1_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 21) -#define PC22_PF_SSI1_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 22) -#define PC23_PF_SSI1_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 23) -#define PC24_PF_SSI2_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 24) -#define PC25_PF_SSI2_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 25) -#define PC26_PF_SSI2_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 26) -#define PC27_PF_SSI2_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 27) -#define PC28_PF_SSI3_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 28) -#define PC29_PF_SSI3_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 29) -#define PC30_PF_SSI3_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 30) -#define PC31_PF_SSI3_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 31) -#define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17) -#define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18) -#define PD19_PF_CSPI2_SS2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 19) -#define PD20_PF_CSPI2_SS1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 20) -#define PD21_PF_CSPI2_SS0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 21) -#define PD22_PF_CSPI2_SCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 22) -#define PD23_PF_CSPI2_MISO (GPIO_PORTD | GPIO_PF | GPIO_IN | 23) -#define PD24_PF_CSPI2_MOSI (GPIO_PORTD | GPIO_PF | GPIO_OUT | 24) -#define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25) -#define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26) -#define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27) -#define PD28_PF_CSPI1_SS0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28) -#define PD29_PF_CSPI1_SCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29) -#define PD30_PF_CSPI1_MISO (GPIO_PORTD | GPIO_PF | GPIO_IN | 30) -#define PD31_PF_CSPI1_MOSI (GPIO_PORTD | GPIO_PF | GPIO_OUT | 31) -#define PE3_PF_UART2_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 3) -#define PE4_PF_UART2_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 4) -#define PE5_PF_PWMO (GPIO_PORTE | GPIO_PF | 5) -#define PE6_PF_UART2_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 6) -#define PE7_PF_UART2_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 7) -#define PE8_PF_UART3_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 8) -#define PE9_PF_UART3_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 9) -#define PE10_PF_UART3_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 10) -#define PE11_PF_UART3_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 11) -#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 12) -#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 13) -#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 14) -#define PE15_PF_UART1_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 15) -#define PE16_PF_RTCK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 16) -#define PE17_PF_RESET_OUT (GPIO_PORTE | GPIO_PF | 17) -#define PE18_PF_SD1_D0 (GPIO_PORTE | GPIO_PF | 18) -#define PE19_PF_SD1_D1 (GPIO_PORTE | GPIO_PF | 19) -#define PE20_PF_SD1_D2 (GPIO_PORTE | GPIO_PF | 20) -#define PE21_PF_SD1_D3 (GPIO_PORTE | GPIO_PF | 21) -#define PE22_PF_SD1_CMD (GPIO_PORTE | GPIO_PF | 22) -#define PE23_PF_SD1_CLK (GPIO_PORTE | GPIO_PF | 23) -#define PF0_PF_NRFB (GPIO_PORTF | GPIO_PF | 0) -#define PF2_PF_NFWP (GPIO_PORTF | GPIO_PF | 2) -#define PF4_PF_NFALE (GPIO_PORTF | GPIO_PF | 4) -#define PF5_PF_NFRE (GPIO_PORTF | GPIO_PF | 5) -#define PF6_PF_NFWE (GPIO_PORTF | GPIO_PF | 6) -#define PF15_PF_CLKO (GPIO_PORTF | GPIO_PF | 15) -#define PF21_PF_CS4 (GPIO_PORTF | GPIO_PF | 21) -#define PF22_PF_CS5 (GPIO_PORTF | GPIO_PF | 22) - -/* Alternate GPIO pin functions */ - -#define PB26_AF_UART4_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 26) -#define PB28_AF_UART4_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 28) -#define PB29_AF_UART4_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 29) -#define PB31_AF_UART4_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 31) -#define PC28_AF_SLCDC2_D0 (GPIO_PORTC | GPIO_AF | 28) -#define PC29_AF_SLCDC2_RS (GPIO_PORTC | GPIO_AF | 29) -#define PC30_AF_SLCDC2_CS (GPIO_PORTC | GPIO_AF | 30) -#define PC31_AF_SLCDC2_CLK (GPIO_PORTC | GPIO_AF | 31) -#define PD19_AF_USBH2_DATA4 (GPIO_PORTD | GPIO_AF | 19) -#define PD20_AF_USBH2_DATA3 (GPIO_PORTD | GPIO_AF | 20) -#define PD21_AF_USBH2_DATA6 (GPIO_PORTD | GPIO_AF | 21) -#define PD22_AF_USBH2_DATA0 (GPIO_PORTD | GPIO_AF | 22) -#define PD23_AF_USBH2_DATA2 (GPIO_PORTD | GPIO_AF | 23) -#define PD24_AF_USBH2_DATA1 (GPIO_PORTD | GPIO_AF | 24) -#define PD26_AF_USBH2_DATA5 (GPIO_PORTD | GPIO_AF | 26) -#define PE0_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 0) -#define PE1_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 1) -#define PE2_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 2) -#define PE3_AF_KP_COL7 (GPIO_PORTE | GPIO_AF | 3) -#define PE4_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 4) -#define PE6_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 6) -#define PE7_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 7) -#define PE16_AF_OWIRE (GPIO_PORTE | GPIO_AF | 16) -#define PE18_AF_CSPI3_MISO (GPIO_PORTE | GPIO_AF | GPIO_IN | 18) -#define PE21_AF_CSPI3_SS (GPIO_PORTE | GPIO_AF | GPIO_OUT | 21) -#define PE22_AF_CSPI3_MOSI (GPIO_PORTE | GPIO_AF | GPIO_OUT | 22) -#define PE23_AF_CSPI3_SCLK (GPIO_PORTE | GPIO_AF | GPIO_OUT | 23) - -/* AIN GPIO pin functions */ - -#define PA6_AIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 6) -#define PA7_AIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 7) -#define PA8_AIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 8) -#define PA0_AIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0) -#define PA11_AIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 11) -#define PA13_AIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 13) -#define PA15_AIN_SLCDC1_DAT9 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 15) -#define PA17_AIN_SLCDC1_DAT11 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17) -#define PA19_AIN_SLCDC1_DAT13 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 19) -#define PA21_AIN_SLCDC1_DAT15 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 21) -#define PA22_AIN_EXT_DMAGRANT (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 22) -#define PA24_AIN_SLCDC1_D0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 24) -#define PA25_AIN_SLCDC1_RS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 25) -#define PA26_AIN_SLCDC1_CS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 26) -#define PA27_AIN_SLCDC1_CLK (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 27) -#define PB6_AIN_SLCDC1_D0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 6) -#define PB7_AIN_SLCDC1_RS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 7) -#define PB8_AIN_SLCDC1_CS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 8) -#define PB9_AIN_SLCDC1_CLK (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 9) -#define PB25_AIN_SLCDC1_DAT0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 25) -#define PB26_AIN_SLCDC1_DAT1 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 26) -#define PB27_AIN_SLCDC1_DAT2 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 27) -#define PB28_AIN_SLCDC1_DAT3 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 28) -#define PB29_AIN_SLCDC1_DAT4 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 29) -#define PB30_AIN_SLCDC1_DAT5 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 30) -#define PB31_AIN_SLCDC1_DAT6 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 31) -#define PC5_AIN_SLCDC1_DAT7 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 5) -#define PC6_AIN_SLCDC1_DAT8 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 6) -#define PC7_AIN_SLCDC1_DAT9 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 7) -#define PC8_AIN_SLCDC1_DAT10 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 8) -#define PC9_AIN_SLCDC1_DAT11 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 9) -#define PC10_AIN_SLCDC1_DAT12 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 10) -#define PC11_AIN_SLCDC1_DAT13 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 11) -#define PC12_AIN_SLCDC1_DAT14 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 12) -#define PC13_AIN_SLCDC1_DAT15 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 13) -#define PE5_AIN_PC_SPKOUT (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 5) - -/* BIN GPIO pin functions */ - -#define PE5_BIN_TOUT2 (GPIO_PORTE | GPIO_BIN | GPIO_OUT | 5) - -/* CIN GPIO pin functions */ - -#define PA14_CIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 14) -#define PA15_CIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 15) -#define PA16_CIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 16) -#define PA17_CIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 17) -#define PA18_CIN_SLCDC1_DAT4 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 18) -#define PA19_CIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 19) -#define PA20_CIN_SLCDC1_DAT6 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 20) -#define PA21_CIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 21) -#define PB30_CIN_UART4_CTS (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 30) -#define PE5_CIN_TOUT3 (GPIO_PORTE | GPIO_CIN | GPIO_OUT | 5) - -/* AOUT GPIO pin functions */ - -#define PB29_AOUT_UART4_RXD (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 29) -#define PB31_AOUT_UART4_RTS (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 31) -#define PC8_AOUT_USBOTG_TXR_INT (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 8) -#define PC15_AOUT_WKGD (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 15) -#define PF21_AOUT_DTACK (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 21) - -#endif /* ifndef __MACH_IOMUX_MX2x_H__ */ diff --git a/arch/arm/mach-imx/iomux-mx3.h b/arch/arm/mach-imx/iomux-mx3.h deleted file mode 100644 index 99270a183d47..000000000000 --- a/arch/arm/mach-imx/iomux-mx3.h +++ /dev/null @@ -1,706 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> - */ -#ifndef __MACH_IOMUX_MX3_H__ -#define __MACH_IOMUX_MX3_H__ - -#include <linux/types.h> -/* - * various IOMUX output functions - */ - -#define IOMUX_OCONFIG_GPIO (0 << 4) /* used as GPIO */ -#define IOMUX_OCONFIG_FUNC (1 << 4) /* used as function */ -#define IOMUX_OCONFIG_ALT1 (2 << 4) /* used as alternate function 1 */ -#define IOMUX_OCONFIG_ALT2 (3 << 4) /* used as alternate function 2 */ -#define IOMUX_OCONFIG_ALT3 (4 << 4) /* used as alternate function 3 */ -#define IOMUX_OCONFIG_ALT4 (5 << 4) /* used as alternate function 4 */ -#define IOMUX_OCONFIG_ALT5 (6 << 4) /* used as alternate function 5 */ -#define IOMUX_OCONFIG_ALT6 (7 << 4) /* used as alternate function 6 */ -#define IOMUX_ICONFIG_NONE 0 /* not configured for input */ -#define IOMUX_ICONFIG_GPIO 1 /* used as GPIO */ -#define IOMUX_ICONFIG_FUNC 2 /* used as function */ -#define IOMUX_ICONFIG_ALT1 4 /* used as alternate function 1 */ -#define IOMUX_ICONFIG_ALT2 8 /* used as alternate function 2 */ - -#define IOMUX_CONFIG_GPIO (IOMUX_OCONFIG_GPIO | IOMUX_ICONFIG_GPIO) -#define IOMUX_CONFIG_FUNC (IOMUX_OCONFIG_FUNC | IOMUX_ICONFIG_FUNC) -#define IOMUX_CONFIG_ALT1 (IOMUX_OCONFIG_ALT1 | IOMUX_ICONFIG_ALT1) -#define IOMUX_CONFIG_ALT2 (IOMUX_OCONFIG_ALT2 | IOMUX_ICONFIG_ALT2) - -/* - * various IOMUX pad functions - */ -enum iomux_pad_config { - PAD_CTL_NOLOOPBACK = 0x0 << 9, - PAD_CTL_LOOPBACK = 0x1 << 9, - PAD_CTL_PKE_NONE = 0x0 << 8, - PAD_CTL_PKE_ENABLE = 0x1 << 8, - PAD_CTL_PUE_KEEPER = 0x0 << 7, - PAD_CTL_PUE_PUD = 0x1 << 7, - PAD_CTL_100K_PD = 0x0 << 5, - PAD_CTL_100K_PU = 0x1 << 5, - PAD_CTL_47K_PU = 0x2 << 5, - PAD_CTL_22K_PU = 0x3 << 5, - PAD_CTL_HYS_CMOS = 0x0 << 4, - PAD_CTL_HYS_SCHMITZ = 0x1 << 4, - PAD_CTL_ODE_CMOS = 0x0 << 3, - PAD_CTL_ODE_OpenDrain = 0x1 << 3, - PAD_CTL_DRV_NORMAL = 0x0 << 1, - PAD_CTL_DRV_HIGH = 0x1 << 1, - PAD_CTL_DRV_MAX = 0x2 << 1, - PAD_CTL_SRE_SLOW = 0x0 << 0, - PAD_CTL_SRE_FAST = 0x1 << 0 -}; - -/* - * various IOMUX general purpose functions - */ -enum iomux_gp_func { - MUX_PGP_FIRI = 1 << 0, - MUX_DDR_MODE = 1 << 1, - MUX_PGP_CSPI_BB = 1 << 2, - MUX_PGP_ATA_1 = 1 << 3, - MUX_PGP_ATA_2 = 1 << 4, - MUX_PGP_ATA_3 = 1 << 5, - MUX_PGP_ATA_4 = 1 << 6, - MUX_PGP_ATA_5 = 1 << 7, - MUX_PGP_ATA_6 = 1 << 8, - MUX_PGP_ATA_7 = 1 << 9, - MUX_PGP_ATA_8 = 1 << 10, - MUX_PGP_UH2 = 1 << 11, - MUX_SDCTL_CSD0_SEL = 1 << 12, - MUX_SDCTL_CSD1_SEL = 1 << 13, - MUX_CSPI1_UART3 = 1 << 14, - MUX_EXTDMAREQ2_MBX_SEL = 1 << 15, - MUX_TAMPER_DETECT_EN = 1 << 16, - MUX_PGP_USB_4WIRE = 1 << 17, - MUX_PGP_USB_COMMON = 1 << 18, - MUX_SDHC_MEMSTICK1 = 1 << 19, - MUX_SDHC_MEMSTICK2 = 1 << 20, - MUX_PGP_SPLL_BYP = 1 << 21, - MUX_PGP_UPLL_BYP = 1 << 22, - MUX_PGP_MSHC1_CLK_SEL = 1 << 23, - MUX_PGP_MSHC2_CLK_SEL = 1 << 24, - MUX_CSPI3_UART5_SEL = 1 << 25, - MUX_PGP_ATA_9 = 1 << 26, - MUX_PGP_USB_SUSPEND = 1 << 27, - MUX_PGP_USB_OTG_LOOPBACK = 1 << 28, - MUX_PGP_USB_HS1_LOOPBACK = 1 << 29, - MUX_PGP_USB_HS2_LOOPBACK = 1 << 30, - MUX_CLKO_DDR_MODE = 1 << 31, -}; - -/* - * setups a single pin: - * - reserves the pin so that it is not claimed by another driver - * - setups the iomux according to the configuration - * - if the pin is configured as a GPIO, we claim it through kernel gpiolib - */ -int mxc_iomux_alloc_pin(unsigned int pin, const char *label); -/* - * setups multiple pins - * convenient way to call the above function with tables - */ -int mxc_iomux_setup_multiple_pins(const unsigned int *pin_list, unsigned count, - const char *label); - -/* - * releases a single pin: - * - make it available for a future use by another driver - * - frees the GPIO if the pin was configured as GPIO - * - DOES NOT reconfigure the IOMUX in its reset state - */ -void mxc_iomux_release_pin(unsigned int pin); -/* - * releases multiple pins - * convenvient way to call the above function with tables - */ -void mxc_iomux_release_multiple_pins(const unsigned int *pin_list, int count); - -/* - * This function enables/disables the general purpose function for a particular - * signal. - */ -void mxc_iomux_set_gpr(enum iomux_gp_func, bool en); - -/* - * This function only configures the iomux hardware. - * It is called by the setup functions and should not be called directly anymore. - * It is here visible for backward compatibility - */ -void mxc_iomux_mode(unsigned int pin_mode); - -#define IOMUX_PADNUM_MASK 0x1ff -#define IOMUX_GPIONUM_SHIFT 9 -#define IOMUX_GPIONUM_MASK (0xff << IOMUX_GPIONUM_SHIFT) -#define IOMUX_MODE_SHIFT 17 -#define IOMUX_MODE_MASK (0xff << IOMUX_MODE_SHIFT) - -#define IOMUX_PIN(gpionum, padnum) \ - (((gpionum << IOMUX_GPIONUM_SHIFT) & IOMUX_GPIONUM_MASK) | \ - (padnum & IOMUX_PADNUM_MASK)) - -#define IOMUX_MODE(pin, mode) (pin | mode << IOMUX_MODE_SHIFT) - -#define IOMUX_TO_GPIO(iomux_pin) \ - ((iomux_pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT) - -/* - * This enumeration is constructed based on the Section - * "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated - * value is constructed based on the rules described above. - */ - -enum iomux_pins { - MX31_PIN_TTM_PAD = IOMUX_PIN(0xff, 0), - MX31_PIN_CSPI3_SPI_RDY = IOMUX_PIN(0xff, 1), - MX31_PIN_CSPI3_SCLK = IOMUX_PIN(0xff, 2), - MX31_PIN_CSPI3_MISO = IOMUX_PIN(0xff, 3), - MX31_PIN_CSPI3_MOSI = IOMUX_PIN(0xff, 4), - MX31_PIN_CLKSS = IOMUX_PIN(0xff, 5), - MX31_PIN_CE_CONTROL = IOMUX_PIN(0xff, 6), - MX31_PIN_ATA_RESET_B = IOMUX_PIN(95, 7), - MX31_PIN_ATA_DMACK = IOMUX_PIN(94, 8), - MX31_PIN_ATA_DIOW = IOMUX_PIN(93, 9), - MX31_PIN_ATA_DIOR = IOMUX_PIN(92, 10), - MX31_PIN_ATA_CS1 = IOMUX_PIN(91, 11), - MX31_PIN_ATA_CS0 = IOMUX_PIN(90, 12), - MX31_PIN_SD1_DATA3 = IOMUX_PIN(63, 13), - MX31_PIN_SD1_DATA2 = IOMUX_PIN(62, 14), - MX31_PIN_SD1_DATA1 = IOMUX_PIN(61, 15), - MX31_PIN_SD1_DATA0 = IOMUX_PIN(60, 16), - MX31_PIN_SD1_CLK = IOMUX_PIN(59, 17), - MX31_PIN_SD1_CMD = IOMUX_PIN(58, 18), - MX31_PIN_D3_SPL = IOMUX_PIN(0xff, 19), - MX31_PIN_D3_CLS = IOMUX_PIN(0xff, 20), - MX31_PIN_D3_REV = IOMUX_PIN(0xff, 21), - MX31_PIN_CONTRAST = IOMUX_PIN(0xff, 22), - MX31_PIN_VSYNC3 = IOMUX_PIN(0xff, 23), - MX31_PIN_READ = IOMUX_PIN(0xff, 24), - MX31_PIN_WRITE = IOMUX_PIN(0xff, 25), - MX31_PIN_PAR_RS = IOMUX_PIN(0xff, 26), - MX31_PIN_SER_RS = IOMUX_PIN(89, 27), - MX31_PIN_LCS1 = IOMUX_PIN(88, 28), - MX31_PIN_LCS0 = IOMUX_PIN(87, 29), - MX31_PIN_SD_D_CLK = IOMUX_PIN(86, 30), - MX31_PIN_SD_D_IO = IOMUX_PIN(85, 31), - MX31_PIN_SD_D_I = IOMUX_PIN(84, 32), - MX31_PIN_DRDY0 = IOMUX_PIN(0xff, 33), - MX31_PIN_FPSHIFT = IOMUX_PIN(0xff, 34), - MX31_PIN_HSYNC = IOMUX_PIN(0xff, 35), - MX31_PIN_VSYNC0 = IOMUX_PIN(0xff, 36), - MX31_PIN_LD17 = IOMUX_PIN(0xff, 37), - MX31_PIN_LD16 = IOMUX_PIN(0xff, 38), - MX31_PIN_LD15 = IOMUX_PIN(0xff, 39), - MX31_PIN_LD14 = IOMUX_PIN(0xff, 40), - MX31_PIN_LD13 = IOMUX_PIN(0xff, 41), - MX31_PIN_LD12 = IOMUX_PIN(0xff, 42), - MX31_PIN_LD11 = IOMUX_PIN(0xff, 43), - MX31_PIN_LD10 = IOMUX_PIN(0xff, 44), - MX31_PIN_LD9 = IOMUX_PIN(0xff, 45), - MX31_PIN_LD8 = IOMUX_PIN(0xff, 46), - MX31_PIN_LD7 = IOMUX_PIN(0xff, 47), - MX31_PIN_LD6 = IOMUX_PIN(0xff, 48), - MX31_PIN_LD5 = IOMUX_PIN(0xff, 49), - MX31_PIN_LD4 = IOMUX_PIN(0xff, 50), - MX31_PIN_LD3 = IOMUX_PIN(0xff, 51), - MX31_PIN_LD2 = IOMUX_PIN(0xff, 52), - MX31_PIN_LD1 = IOMUX_PIN(0xff, 53), - MX31_PIN_LD0 = IOMUX_PIN(0xff, 54), - MX31_PIN_USBH2_DATA1 = IOMUX_PIN(0xff, 55), - MX31_PIN_USBH2_DATA0 = IOMUX_PIN(0xff, 56), - MX31_PIN_USBH2_NXT = IOMUX_PIN(0xff, 57), - MX31_PIN_USBH2_STP = IOMUX_PIN(0xff, 58), - MX31_PIN_USBH2_DIR = IOMUX_PIN(0xff, 59), - MX31_PIN_USBH2_CLK = IOMUX_PIN(0xff, 60), - MX31_PIN_USBOTG_DATA7 = IOMUX_PIN(0xff, 61), - MX31_PIN_USBOTG_DATA6 = IOMUX_PIN(0xff, 62), - MX31_PIN_USBOTG_DATA5 = IOMUX_PIN(0xff, 63), - MX31_PIN_USBOTG_DATA4 = IOMUX_PIN(0xff, 64), - MX31_PIN_USBOTG_DATA3 = IOMUX_PIN(0xff, 65), - MX31_PIN_USBOTG_DATA2 = IOMUX_PIN(0xff, 66), - MX31_PIN_USBOTG_DATA1 = IOMUX_PIN(0xff, 67), - MX31_PIN_USBOTG_DATA0 = IOMUX_PIN(0xff, 68), - MX31_PIN_USBOTG_NXT = IOMUX_PIN(0xff, 69), - MX31_PIN_USBOTG_STP = IOMUX_PIN(0xff, 70), - MX31_PIN_USBOTG_DIR = IOMUX_PIN(0xff, 71), - MX31_PIN_USBOTG_CLK = IOMUX_PIN(0xff, 72), - MX31_PIN_USB_BYP = IOMUX_PIN(31, 73), - MX31_PIN_USB_OC = IOMUX_PIN(30, 74), - MX31_PIN_USB_PWR = IOMUX_PIN(29, 75), - MX31_PIN_SJC_MOD = IOMUX_PIN(0xff, 76), - MX31_PIN_DE_B = IOMUX_PIN(0xff, 77), - MX31_PIN_TRSTB = IOMUX_PIN(0xff, 78), - MX31_PIN_TDO = IOMUX_PIN(0xff, 79), - MX31_PIN_TDI = IOMUX_PIN(0xff, 80), - MX31_PIN_TMS = IOMUX_PIN(0xff, 81), - MX31_PIN_TCK = IOMUX_PIN(0xff, 82), - MX31_PIN_RTCK = IOMUX_PIN(0xff, 83), - MX31_PIN_KEY_COL7 = IOMUX_PIN(57, 84), - MX31_PIN_KEY_COL6 = IOMUX_PIN(56, 85), - MX31_PIN_KEY_COL5 = IOMUX_PIN(55, 86), - MX31_PIN_KEY_COL4 = IOMUX_PIN(54, 87), - MX31_PIN_KEY_COL3 = IOMUX_PIN(0xff, 88), - MX31_PIN_KEY_COL2 = IOMUX_PIN(0xff, 89), - MX31_PIN_KEY_COL1 = IOMUX_PIN(0xff, 90), - MX31_PIN_KEY_COL0 = IOMUX_PIN(0xff, 91), - MX31_PIN_KEY_ROW7 = IOMUX_PIN(53, 92), - MX31_PIN_KEY_ROW6 = IOMUX_PIN(52, 93), - MX31_PIN_KEY_ROW5 = IOMUX_PIN(51, 94), - MX31_PIN_KEY_ROW4 = IOMUX_PIN(50, 95), - MX31_PIN_KEY_ROW3 = IOMUX_PIN(0xff, 96), - MX31_PIN_KEY_ROW2 = IOMUX_PIN(0xff, 97), - MX31_PIN_KEY_ROW1 = IOMUX_PIN(0xff, 98), - MX31_PIN_KEY_ROW0 = IOMUX_PIN(0xff, 99), - MX31_PIN_BATT_LINE = IOMUX_PIN(49, 100), - MX31_PIN_CTS2 = IOMUX_PIN(0xff, 101), - MX31_PIN_RTS2 = IOMUX_PIN(0xff, 102), - MX31_PIN_TXD2 = IOMUX_PIN(28, 103), - MX31_PIN_RXD2 = IOMUX_PIN(27, 104), - MX31_PIN_DTR_DCE2 = IOMUX_PIN(48, 105), - MX31_PIN_DCD_DTE1 = IOMUX_PIN(47, 106), - MX31_PIN_RI_DTE1 = IOMUX_PIN(46, 107), - MX31_PIN_DSR_DTE1 = IOMUX_PIN(45, 108), - MX31_PIN_DTR_DTE1 = IOMUX_PIN(44, 109), - MX31_PIN_DCD_DCE1 = IOMUX_PIN(43, 110), - MX31_PIN_RI_DCE1 = IOMUX_PIN(42, 111), - MX31_PIN_DSR_DCE1 = IOMUX_PIN(41, 112), - MX31_PIN_DTR_DCE1 = IOMUX_PIN(40, 113), - MX31_PIN_CTS1 = IOMUX_PIN(39, 114), - MX31_PIN_RTS1 = IOMUX_PIN(38, 115), - MX31_PIN_TXD1 = IOMUX_PIN(37, 116), - MX31_PIN_RXD1 = IOMUX_PIN(36, 117), - MX31_PIN_CSPI2_SPI_RDY = IOMUX_PIN(0xff, 118), - MX31_PIN_CSPI2_SCLK = IOMUX_PIN(0xff, 119), - MX31_PIN_CSPI2_SS2 = IOMUX_PIN(0xff, 120), - MX31_PIN_CSPI2_SS1 = IOMUX_PIN(0xff, 121), - MX31_PIN_CSPI2_SS0 = IOMUX_PIN(0xff, 122), - MX31_PIN_CSPI2_MISO = IOMUX_PIN(0xff, 123), - MX31_PIN_CSPI2_MOSI = IOMUX_PIN(0xff, 124), - MX31_PIN_CSPI1_SPI_RDY = IOMUX_PIN(0xff, 125), - MX31_PIN_CSPI1_SCLK = IOMUX_PIN(0xff, 126), - MX31_PIN_CSPI1_SS2 = IOMUX_PIN(0xff, 127), - MX31_PIN_CSPI1_SS1 = IOMUX_PIN(0xff, 128), - MX31_PIN_CSPI1_SS0 = IOMUX_PIN(0xff, 129), - MX31_PIN_CSPI1_MISO = IOMUX_PIN(0xff, 130), - MX31_PIN_CSPI1_MOSI = IOMUX_PIN(0xff, 131), - MX31_PIN_SFS6 = IOMUX_PIN(26, 132), - MX31_PIN_SCK6 = IOMUX_PIN(25, 133), - MX31_PIN_SRXD6 = IOMUX_PIN(24, 134), - MX31_PIN_STXD6 = IOMUX_PIN(23, 135), - MX31_PIN_SFS5 = IOMUX_PIN(0xff, 136), - MX31_PIN_SCK5 = IOMUX_PIN(0xff, 137), - MX31_PIN_SRXD5 = IOMUX_PIN(22, 138), - MX31_PIN_STXD5 = IOMUX_PIN(21, 139), - MX31_PIN_SFS4 = IOMUX_PIN(0xff, 140), - MX31_PIN_SCK4 = IOMUX_PIN(0xff, 141), - MX31_PIN_SRXD4 = IOMUX_PIN(20, 142), - MX31_PIN_STXD4 = IOMUX_PIN(19, 143), - MX31_PIN_SFS3 = IOMUX_PIN(0xff, 144), - MX31_PIN_SCK3 = IOMUX_PIN(0xff, 145), - MX31_PIN_SRXD3 = IOMUX_PIN(18, 146), - MX31_PIN_STXD3 = IOMUX_PIN(17, 147), - MX31_PIN_I2C_DAT = IOMUX_PIN(0xff, 148), - MX31_PIN_I2C_CLK = IOMUX_PIN(0xff, 149), - MX31_PIN_CSI_PIXCLK = IOMUX_PIN(83, 150), - MX31_PIN_CSI_HSYNC = IOMUX_PIN(82, 151), - MX31_PIN_CSI_VSYNC = IOMUX_PIN(81, 152), - MX31_PIN_CSI_MCLK = IOMUX_PIN(80, 153), - MX31_PIN_CSI_D15 = IOMUX_PIN(79, 154), - MX31_PIN_CSI_D14 = IOMUX_PIN(78, 155), - MX31_PIN_CSI_D13 = IOMUX_PIN(77, 156), - MX31_PIN_CSI_D12 = IOMUX_PIN(76, 157), - MX31_PIN_CSI_D11 = IOMUX_PIN(75, 158), - MX31_PIN_CSI_D10 = IOMUX_PIN(74, 159), - MX31_PIN_CSI_D9 = IOMUX_PIN(73, 160), - MX31_PIN_CSI_D8 = IOMUX_PIN(72, 161), - MX31_PIN_CSI_D7 = IOMUX_PIN(71, 162), - MX31_PIN_CSI_D6 = IOMUX_PIN(70, 163), - MX31_PIN_CSI_D5 = IOMUX_PIN(69, 164), - MX31_PIN_CSI_D4 = IOMUX_PIN(68, 165), - MX31_PIN_M_GRANT = IOMUX_PIN(0xff, 166), - MX31_PIN_M_REQUEST = IOMUX_PIN(0xff, 167), - MX31_PIN_PC_POE = IOMUX_PIN(0xff, 168), - MX31_PIN_PC_RW_B = IOMUX_PIN(0xff, 169), - MX31_PIN_IOIS16 = IOMUX_PIN(0xff, 170), - MX31_PIN_PC_RST = IOMUX_PIN(0xff, 171), - MX31_PIN_PC_BVD2 = IOMUX_PIN(0xff, 172), - MX31_PIN_PC_BVD1 = IOMUX_PIN(0xff, 173), - MX31_PIN_PC_VS2 = IOMUX_PIN(0xff, 174), - MX31_PIN_PC_VS1 = IOMUX_PIN(0xff, 175), - MX31_PIN_PC_PWRON = IOMUX_PIN(0xff, 176), - MX31_PIN_PC_READY = IOMUX_PIN(0xff, 177), - MX31_PIN_PC_WAIT_B = IOMUX_PIN(0xff, 178), - MX31_PIN_PC_CD2_B = IOMUX_PIN(0xff, 179), - MX31_PIN_PC_CD1_B = IOMUX_PIN(0xff, 180), - MX31_PIN_D0 = IOMUX_PIN(0xff, 181), - MX31_PIN_D1 = IOMUX_PIN(0xff, 182), - MX31_PIN_D2 = IOMUX_PIN(0xff, 183), - MX31_PIN_D3 = IOMUX_PIN(0xff, 184), - MX31_PIN_D4 = IOMUX_PIN(0xff, 185), - MX31_PIN_D5 = IOMUX_PIN(0xff, 186), - MX31_PIN_D6 = IOMUX_PIN(0xff, 187), - MX31_PIN_D7 = IOMUX_PIN(0xff, 188), - MX31_PIN_D8 = IOMUX_PIN(0xff, 189), - MX31_PIN_D9 = IOMUX_PIN(0xff, 190), - MX31_PIN_D10 = IOMUX_PIN(0xff, 191), - MX31_PIN_D11 = IOMUX_PIN(0xff, 192), - MX31_PIN_D12 = IOMUX_PIN(0xff, 193), - MX31_PIN_D13 = IOMUX_PIN(0xff, 194), - MX31_PIN_D14 = IOMUX_PIN(0xff, 195), - MX31_PIN_D15 = IOMUX_PIN(0xff, 196), - MX31_PIN_NFRB = IOMUX_PIN(16, 197), - MX31_PIN_NFCE_B = IOMUX_PIN(15, 198), - MX31_PIN_NFWP_B = IOMUX_PIN(14, 199), - MX31_PIN_NFCLE = IOMUX_PIN(13, 200), - MX31_PIN_NFALE = IOMUX_PIN(12, 201), - MX31_PIN_NFRE_B = IOMUX_PIN(11, 202), - MX31_PIN_NFWE_B = IOMUX_PIN(10, 203), - MX31_PIN_SDQS3 = IOMUX_PIN(0xff, 204), - MX31_PIN_SDQS2 = IOMUX_PIN(0xff, 205), - MX31_PIN_SDQS1 = IOMUX_PIN(0xff, 206), - MX31_PIN_SDQS0 = IOMUX_PIN(0xff, 207), - MX31_PIN_SDCLK_B = IOMUX_PIN(0xff, 208), - MX31_PIN_SDCLK = IOMUX_PIN(0xff, 209), - MX31_PIN_SDCKE1 = IOMUX_PIN(0xff, 210), - MX31_PIN_SDCKE0 = IOMUX_PIN(0xff, 211), - MX31_PIN_SDWE = IOMUX_PIN(0xff, 212), - MX31_PIN_CAS = IOMUX_PIN(0xff, 213), - MX31_PIN_RAS = IOMUX_PIN(0xff, 214), - MX31_PIN_RW = IOMUX_PIN(0xff, 215), - MX31_PIN_BCLK = IOMUX_PIN(0xff, 216), - MX31_PIN_LBA = IOMUX_PIN(0xff, 217), - MX31_PIN_ECB = IOMUX_PIN(0xff, 218), - MX31_PIN_CS5 = IOMUX_PIN(0xff, 219), - MX31_PIN_CS4 = IOMUX_PIN(0xff, 220), - MX31_PIN_CS3 = IOMUX_PIN(0xff, 221), - MX31_PIN_CS2 = IOMUX_PIN(0xff, 222), - MX31_PIN_CS1 = IOMUX_PIN(0xff, 223), - MX31_PIN_CS0 = IOMUX_PIN(0xff, 224), - MX31_PIN_OE = IOMUX_PIN(0xff, 225), - MX31_PIN_EB1 = IOMUX_PIN(0xff, 226), - MX31_PIN_EB0 = IOMUX_PIN(0xff, 227), - MX31_PIN_DQM3 = IOMUX_PIN(0xff, 228), - MX31_PIN_DQM2 = IOMUX_PIN(0xff, 229), - MX31_PIN_DQM1 = IOMUX_PIN(0xff, 230), - MX31_PIN_DQM0 = IOMUX_PIN(0xff, 231), - MX31_PIN_SD31 = IOMUX_PIN(0xff, 232), - MX31_PIN_SD30 = IOMUX_PIN(0xff, 233), - MX31_PIN_SD29 = IOMUX_PIN(0xff, 234), - MX31_PIN_SD28 = IOMUX_PIN(0xff, 235), - MX31_PIN_SD27 = IOMUX_PIN(0xff, 236), - MX31_PIN_SD26 = IOMUX_PIN(0xff, 237), - MX31_PIN_SD25 = IOMUX_PIN(0xff, 238), - MX31_PIN_SD24 = IOMUX_PIN(0xff, 239), - MX31_PIN_SD23 = IOMUX_PIN(0xff, 240), - MX31_PIN_SD22 = IOMUX_PIN(0xff, 241), - MX31_PIN_SD21 = IOMUX_PIN(0xff, 242), - MX31_PIN_SD20 = IOMUX_PIN(0xff, 243), - MX31_PIN_SD19 = IOMUX_PIN(0xff, 244), - MX31_PIN_SD18 = IOMUX_PIN(0xff, 245), - MX31_PIN_SD17 = IOMUX_PIN(0xff, 246), - MX31_PIN_SD16 = IOMUX_PIN(0xff, 247), - MX31_PIN_SD15 = IOMUX_PIN(0xff, 248), - MX31_PIN_SD14 = IOMUX_PIN(0xff, 249), - MX31_PIN_SD13 = IOMUX_PIN(0xff, 250), - MX31_PIN_SD12 = IOMUX_PIN(0xff, 251), - MX31_PIN_SD11 = IOMUX_PIN(0xff, 252), - MX31_PIN_SD10 = IOMUX_PIN(0xff, 253), - MX31_PIN_SD9 = IOMUX_PIN(0xff, 254), - MX31_PIN_SD8 = IOMUX_PIN(0xff, 255), - MX31_PIN_SD7 = IOMUX_PIN(0xff, 256), - MX31_PIN_SD6 = IOMUX_PIN(0xff, 257), - MX31_PIN_SD5 = IOMUX_PIN(0xff, 258), - MX31_PIN_SD4 = IOMUX_PIN(0xff, 259), - MX31_PIN_SD3 = IOMUX_PIN(0xff, 260), - MX31_PIN_SD2 = IOMUX_PIN(0xff, 261), - MX31_PIN_SD1 = IOMUX_PIN(0xff, 262), - MX31_PIN_SD0 = IOMUX_PIN(0xff, 263), - MX31_PIN_SDBA0 = IOMUX_PIN(0xff, 264), - MX31_PIN_SDBA1 = IOMUX_PIN(0xff, 265), - MX31_PIN_A25 = IOMUX_PIN(0xff, 266), - MX31_PIN_A24 = IOMUX_PIN(0xff, 267), - MX31_PIN_A23 = IOMUX_PIN(0xff, 268), - MX31_PIN_A22 = IOMUX_PIN(0xff, 269), - MX31_PIN_A21 = IOMUX_PIN(0xff, 270), - MX31_PIN_A20 = IOMUX_PIN(0xff, 271), - MX31_PIN_A19 = IOMUX_PIN(0xff, 272), - MX31_PIN_A18 = IOMUX_PIN(0xff, 273), - MX31_PIN_A17 = IOMUX_PIN(0xff, 274), - MX31_PIN_A16 = IOMUX_PIN(0xff, 275), - MX31_PIN_A14 = IOMUX_PIN(0xff, 276), - MX31_PIN_A15 = IOMUX_PIN(0xff, 277), - MX31_PIN_A13 = IOMUX_PIN(0xff, 278), - MX31_PIN_A12 = IOMUX_PIN(0xff, 279), - MX31_PIN_A11 = IOMUX_PIN(0xff, 280), - MX31_PIN_MA10 = IOMUX_PIN(0xff, 281), - MX31_PIN_A10 = IOMUX_PIN(0xff, 282), - MX31_PIN_A9 = IOMUX_PIN(0xff, 283), - MX31_PIN_A8 = IOMUX_PIN(0xff, 284), - MX31_PIN_A7 = IOMUX_PIN(0xff, 285), - MX31_PIN_A6 = IOMUX_PIN(0xff, 286), - MX31_PIN_A5 = IOMUX_PIN(0xff, 287), - MX31_PIN_A4 = IOMUX_PIN(0xff, 288), - MX31_PIN_A3 = IOMUX_PIN(0xff, 289), - MX31_PIN_A2 = IOMUX_PIN(0xff, 290), - MX31_PIN_A1 = IOMUX_PIN(0xff, 291), - MX31_PIN_A0 = IOMUX_PIN(0xff, 292), - MX31_PIN_VPG1 = IOMUX_PIN(0xff, 293), - MX31_PIN_VPG0 = IOMUX_PIN(0xff, 294), - MX31_PIN_DVFS1 = IOMUX_PIN(0xff, 295), - MX31_PIN_DVFS0 = IOMUX_PIN(0xff, 296), - MX31_PIN_VSTBY = IOMUX_PIN(0xff, 297), - MX31_PIN_POWER_FAIL = IOMUX_PIN(0xff, 298), - MX31_PIN_CKIL = IOMUX_PIN(0xff, 299), - MX31_PIN_BOOT_MODE4 = IOMUX_PIN(0xff, 300), - MX31_PIN_BOOT_MODE3 = IOMUX_PIN(0xff, 301), - MX31_PIN_BOOT_MODE2 = IOMUX_PIN(0xff, 302), - MX31_PIN_BOOT_MODE1 = IOMUX_PIN(0xff, 303), - MX31_PIN_BOOT_MODE0 = IOMUX_PIN(0xff, 304), - MX31_PIN_CLKO = IOMUX_PIN(0xff, 305), - MX31_PIN_POR_B = IOMUX_PIN(0xff, 306), - MX31_PIN_RESET_IN_B = IOMUX_PIN(0xff, 307), - MX31_PIN_CKIH = IOMUX_PIN(0xff, 308), - MX31_PIN_SIMPD0 = IOMUX_PIN(35, 309), - MX31_PIN_SRX0 = IOMUX_PIN(34, 310), - MX31_PIN_STX0 = IOMUX_PIN(33, 311), - MX31_PIN_SVEN0 = IOMUX_PIN(32, 312), - MX31_PIN_SRST0 = IOMUX_PIN(67, 313), - MX31_PIN_SCLK0 = IOMUX_PIN(66, 314), - MX31_PIN_GPIO3_1 = IOMUX_PIN(65, 315), - MX31_PIN_GPIO3_0 = IOMUX_PIN(64, 316), - MX31_PIN_GPIO1_6 = IOMUX_PIN( 6, 317), - MX31_PIN_GPIO1_5 = IOMUX_PIN( 5, 318), - MX31_PIN_GPIO1_4 = IOMUX_PIN( 4, 319), - MX31_PIN_GPIO1_3 = IOMUX_PIN( 3, 320), - MX31_PIN_GPIO1_2 = IOMUX_PIN( 2, 321), - MX31_PIN_GPIO1_1 = IOMUX_PIN( 1, 322), - MX31_PIN_GPIO1_0 = IOMUX_PIN( 0, 323), - MX31_PIN_PWMO = IOMUX_PIN( 9, 324), - MX31_PIN_WATCHDOG_RST = IOMUX_PIN(0xff, 325), - MX31_PIN_COMPARE = IOMUX_PIN( 8, 326), - MX31_PIN_CAPTURE = IOMUX_PIN( 7, 327), -}; - -#define PIN_MAX 327 -#define NB_PORTS 12 /* NB_PINS/32, we chose 32 pins per "PORT" */ - -/* - * Convenience values for use with mxc_iomux_mode() - * - * Format here is MX31_PIN_(pin name)__(function) - */ -#define MX31_PIN_CSPI3_MOSI__RXD3 IOMUX_MODE(MX31_PIN_CSPI3_MOSI, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CSPI3_MISO__TXD3 IOMUX_MODE(MX31_PIN_CSPI3_MISO, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CSPI3_SCLK__RTS3 IOMUX_MODE(MX31_PIN_CSPI3_SCLK, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CSPI3_SPI_RDY__CTS3 IOMUX_MODE(MX31_PIN_CSPI3_SPI_RDY, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CTS1__CTS1 IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_RTS1__RTS1 IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_RTS1__SFS IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_ALT2) -#define MX31_PIN_TXD1__TXD1 IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_TXD1__SCK IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_ALT2) -#define MX31_PIN_RXD1__RXD1 IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_RXD1__STXDA IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_ALT2) -#define MX31_PIN_DCD_DCE1__DCD_DCE1 IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_RI_DCE1__RI_DCE1 IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_DSR_DCE1__DSR_DCE1 IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_DTR_DCE1__DTR_DCE1 IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_DTR_DCE1__SRXDA IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_ALT2) -#define MX31_PIN_CTS2__CTS2 IOMUX_MODE(MX31_PIN_CTS2, IOMUX_CONFIG_FUNC) -#define MX31_PIN_RTS2__RTS2 IOMUX_MODE(MX31_PIN_RTS2, IOMUX_CONFIG_FUNC) -#define MX31_PIN_TXD2__TXD2 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_FUNC) -#define MX31_PIN_RXD2__RXD2 IOMUX_MODE(MX31_PIN_RXD2, IOMUX_CONFIG_FUNC) -#define MX31_PIN_DCD_DTE1__DCD_DTE2 IOMUX_MODE(MX31_PIN_DCD_DTE1, IOMUX_CONFIG_ALT1) -#define MX31_PIN_RI_DTE1__RI_DTE2 IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_ALT1) -#define MX31_PIN_DSR_DTE1__DSR_DTE2 IOMUX_MODE(MX31_PIN_DSR_DTE1, IOMUX_CONFIG_ALT1) -#define MX31_PIN_DTR_DTE1__DTR_DTE2 IOMUX_MODE(MX31_PIN_DTR_DTE1, IOMUX_OCONFIG_ALT3 | IOMUX_ICONFIG_NONE) -#define MX31_PIN_PC_RST__CTS5 IOMUX_MODE(MX31_PIN_PC_RST, IOMUX_CONFIG_ALT2) -#define MX31_PIN_PC_VS2__RTS5 IOMUX_MODE(MX31_PIN_PC_VS2, IOMUX_CONFIG_ALT2) -#define MX31_PIN_PC_BVD2__TXD5 IOMUX_MODE(MX31_PIN_PC_BVD2, IOMUX_CONFIG_ALT2) -#define MX31_PIN_PC_BVD1__RXD5 IOMUX_MODE(MX31_PIN_PC_BVD1, IOMUX_CONFIG_ALT2) -#define MX31_PIN_CSPI1_MOSI__MOSI IOMUX_MODE(MX31_PIN_CSPI1_MOSI, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI1_MISO__MISO IOMUX_MODE(MX31_PIN_CSPI1_MISO, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI1_SCLK__SCLK IOMUX_MODE(MX31_PIN_CSPI1_SCLK, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI1_SPI_RDY__SPI_RDY IOMUX_MODE(MX31_PIN_CSPI1_SPI_RDY, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI1_SS0__SS0 IOMUX_MODE(MX31_PIN_CSPI1_SS0, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI1_SS1__SS1 IOMUX_MODE(MX31_PIN_CSPI1_SS1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI1_SS2__SS2 IOMUX_MODE(MX31_PIN_CSPI1_SS2, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI2_MOSI__MOSI IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI2_MOSI__SCL IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CSPI2_MISO__MISO IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI2_MISO__SDA IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CSPI2_SCLK__SCLK IOMUX_MODE(MX31_PIN_CSPI2_SCLK, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI2_SPI_RDY__SPI_RDY IOMUX_MODE(MX31_PIN_CSPI2_SPI_RDY, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI2_SS0__SS0 IOMUX_MODE(MX31_PIN_CSPI2_SS0, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI2_SS1__SS1 IOMUX_MODE(MX31_PIN_CSPI2_SS1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI2_SS2__SS2 IOMUX_MODE(MX31_PIN_CSPI2_SS2, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI3_MOSI__MOSI IOMUX_MODE(MX31_PIN_CSPI3_MOSI, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI3_MISO__MISO IOMUX_MODE(MX31_PIN_CSPI3_MISO, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI3_SCLK__SCLK IOMUX_MODE(MX31_PIN_CSPI3_SCLK, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI3_SPI_RDY__SPI_RDY IOMUX_MODE(MX31_PIN_CSPI3_SPI_RDY, IOMUX_CONFIG_FUNC) -#define MX31_PIN_BATT_LINE__OWIRE IOMUX_MODE(MX31_PIN_BATT_LINE, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CS4__CS4 IOMUX_MODE(MX31_PIN_CS4, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SD1_DATA3__SD1_DATA3 IOMUX_MODE(MX31_PIN_SD1_DATA3, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SD1_DATA2__SD1_DATA2 IOMUX_MODE(MX31_PIN_SD1_DATA2, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SD1_DATA1__SD1_DATA1 IOMUX_MODE(MX31_PIN_SD1_DATA1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SD1_DATA0__SD1_DATA0 IOMUX_MODE(MX31_PIN_SD1_DATA0, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SD1_CLK__SD1_CLK IOMUX_MODE(MX31_PIN_SD1_CLK, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SD1_CMD__SD1_CMD IOMUX_MODE(MX31_PIN_SD1_CMD, IOMUX_CONFIG_FUNC) -#define MX31_PIN_ATA_CS0__GPIO3_26 IOMUX_MODE(MX31_PIN_ATA_CS0, IOMUX_CONFIG_GPIO) -#define MX31_PIN_ATA_CS1__GPIO3_27 IOMUX_MODE(MX31_PIN_ATA_CS1, IOMUX_CONFIG_GPIO) -#define MX31_PIN_PC_PWRON__SD2_DATA3 IOMUX_MODE(MX31_PIN_PC_PWRON, IOMUX_CONFIG_ALT1) -#define MX31_PIN_PC_VS1__SD2_DATA2 IOMUX_MODE(MX31_PIN_PC_VS1, IOMUX_CONFIG_ALT1) -#define MX31_PIN_PC_READY__SD2_DATA1 IOMUX_MODE(MX31_PIN_PC_READY, IOMUX_CONFIG_ALT1) -#define MX31_PIN_PC_WAIT_B__SD2_DATA0 IOMUX_MODE(MX31_PIN_PC_WAIT_B, IOMUX_CONFIG_ALT1) -#define MX31_PIN_PC_CD2_B__SD2_CLK IOMUX_MODE(MX31_PIN_PC_CD2_B, IOMUX_CONFIG_ALT1) -#define MX31_PIN_PC_CD1_B__SD2_CMD IOMUX_MODE(MX31_PIN_PC_CD1_B, IOMUX_CONFIG_ALT1) -#define MX31_PIN_ATA_DIOR__GPIO3_28 IOMUX_MODE(MX31_PIN_ATA_DIOR, IOMUX_CONFIG_GPIO) -#define MX31_PIN_ATA_DIOW__GPIO3_29 IOMUX_MODE(MX31_PIN_ATA_DIOW, IOMUX_CONFIG_GPIO) -#define MX31_PIN_LD0__LD0 IOMUX_MODE(MX31_PIN_LD0, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD1__LD1 IOMUX_MODE(MX31_PIN_LD1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD2__LD2 IOMUX_MODE(MX31_PIN_LD2, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD3__LD3 IOMUX_MODE(MX31_PIN_LD3, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD4__LD4 IOMUX_MODE(MX31_PIN_LD4, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD5__LD5 IOMUX_MODE(MX31_PIN_LD5, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD6__LD6 IOMUX_MODE(MX31_PIN_LD6, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD7__LD7 IOMUX_MODE(MX31_PIN_LD7, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD8__LD8 IOMUX_MODE(MX31_PIN_LD8, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD9__LD9 IOMUX_MODE(MX31_PIN_LD9, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD10__LD10 IOMUX_MODE(MX31_PIN_LD10, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD11__LD11 IOMUX_MODE(MX31_PIN_LD11, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD12__LD12 IOMUX_MODE(MX31_PIN_LD12, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD13__LD13 IOMUX_MODE(MX31_PIN_LD13, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD14__LD14 IOMUX_MODE(MX31_PIN_LD14, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD15__LD15 IOMUX_MODE(MX31_PIN_LD15, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD16__LD16 IOMUX_MODE(MX31_PIN_LD16, IOMUX_CONFIG_FUNC) -#define MX31_PIN_LD17__LD17 IOMUX_MODE(MX31_PIN_LD17, IOMUX_CONFIG_FUNC) -#define MX31_PIN_VSYNC3__VSYNC3 IOMUX_MODE(MX31_PIN_VSYNC3, IOMUX_CONFIG_FUNC) -#define MX31_PIN_HSYNC__HSYNC IOMUX_MODE(MX31_PIN_HSYNC, IOMUX_CONFIG_FUNC) -#define MX31_PIN_FPSHIFT__FPSHIFT IOMUX_MODE(MX31_PIN_FPSHIFT, IOMUX_CONFIG_FUNC) -#define MX31_PIN_DRDY0__DRDY0 IOMUX_MODE(MX31_PIN_DRDY0, IOMUX_CONFIG_FUNC) -#define MX31_PIN_D3_REV__D3_REV IOMUX_MODE(MX31_PIN_D3_REV, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CONTRAST__CONTRAST IOMUX_MODE(MX31_PIN_CONTRAST, IOMUX_CONFIG_FUNC) -#define MX31_PIN_D3_SPL__D3_SPL IOMUX_MODE(MX31_PIN_D3_SPL, IOMUX_CONFIG_FUNC) -#define MX31_PIN_D3_CLS__D3_CLS IOMUX_MODE(MX31_PIN_D3_CLS, IOMUX_CONFIG_FUNC) -#define MX31_PIN_GPIO1_1__GPIO IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO) -#define MX31_PIN_DCD_DTE1__I2C2_SDA IOMUX_MODE(MX31_PIN_DCD_DTE1, IOMUX_CONFIG_ALT2) -#define MX31_PIN_RI_DTE1__I2C2_SCL IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_ALT2) -#define MX31_PIN_CSPI2_SS2__I2C3_SDA IOMUX_MODE(MX31_PIN_CSPI2_SS2, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CSPI2_SCLK__I2C3_SCL IOMUX_MODE(MX31_PIN_CSPI2_SCLK, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CSI_D4__CSI_D4 IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D5__CSI_D5 IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D6__CSI_D6 IOMUX_MODE(MX31_PIN_CSI_D6, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D7__CSI_D7 IOMUX_MODE(MX31_PIN_CSI_D7, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D8__CSI_D8 IOMUX_MODE(MX31_PIN_CSI_D8, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D9__CSI_D9 IOMUX_MODE(MX31_PIN_CSI_D9, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D10__CSI_D10 IOMUX_MODE(MX31_PIN_CSI_D10, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D11__CSI_D11 IOMUX_MODE(MX31_PIN_CSI_D11, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D12__CSI_D12 IOMUX_MODE(MX31_PIN_CSI_D12, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D13__CSI_D13 IOMUX_MODE(MX31_PIN_CSI_D13, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D14__CSI_D14 IOMUX_MODE(MX31_PIN_CSI_D14, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_D15__CSI_D15 IOMUX_MODE(MX31_PIN_CSI_D15, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_HSYNC__CSI_HSYNC IOMUX_MODE(MX31_PIN_CSI_HSYNC, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_MCLK__CSI_MCLK IOMUX_MODE(MX31_PIN_CSI_MCLK, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_PIXCLK__CSI_PIXCLK IOMUX_MODE(MX31_PIN_CSI_PIXCLK, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSI_VSYNC__CSI_VSYNC IOMUX_MODE(MX31_PIN_CSI_VSYNC, IOMUX_CONFIG_FUNC) -#define MX31_PIN_GPIO3_0__GPIO3_0 IOMUX_MODE(MX31_PIN_GPIO3_0, IOMUX_CONFIG_GPIO) -#define MX31_PIN_GPIO3_1__GPIO3_1 IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO) -#define MX31_PIN_TXD2__GPIO1_28 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_GPIO) -#define MX31_PIN_CSI_D4__GPIO3_4 IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_GPIO) -#define MX31_PIN_CSI_D5__GPIO3_5 IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO) -#define MX31_PIN_USBOTG_DATA0__USBOTG_DATA0 IOMUX_MODE(MX31_PIN_USBOTG_DATA0, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBOTG_DATA1__USBOTG_DATA1 IOMUX_MODE(MX31_PIN_USBOTG_DATA1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBOTG_DATA2__USBOTG_DATA2 IOMUX_MODE(MX31_PIN_USBOTG_DATA2, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBOTG_DATA3__USBOTG_DATA3 IOMUX_MODE(MX31_PIN_USBOTG_DATA3, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBOTG_DATA4__USBOTG_DATA4 IOMUX_MODE(MX31_PIN_USBOTG_DATA4, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBOTG_DATA5__USBOTG_DATA5 IOMUX_MODE(MX31_PIN_USBOTG_DATA5, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBOTG_DATA6__USBOTG_DATA6 IOMUX_MODE(MX31_PIN_USBOTG_DATA6, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBOTG_DATA7__USBOTG_DATA7 IOMUX_MODE(MX31_PIN_USBOTG_DATA7, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBOTG_CLK__USBOTG_CLK IOMUX_MODE(MX31_PIN_USBOTG_CLK, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBOTG_DIR__USBOTG_DIR IOMUX_MODE(MX31_PIN_USBOTG_DIR, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBOTG_NXT__USBOTG_NXT IOMUX_MODE(MX31_PIN_USBOTG_NXT, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBOTG_STP__USBOTG_STP IOMUX_MODE(MX31_PIN_USBOTG_STP, IOMUX_CONFIG_FUNC) -#define MX31_PIN_CSPI1_MOSI__USBH1_RXDM IOMUX_MODE(MX31_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CSPI1_MISO__USBH1_RXDP IOMUX_MODE(MX31_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CSPI1_SS0__USBH1_TXDM IOMUX_MODE(MX31_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CSPI1_SS1__USBH1_TXDP IOMUX_MODE(MX31_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CSPI1_SS2__USBH1_RCV IOMUX_MODE(MX31_PIN_CSPI1_SS2, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CSPI1_SCLK__USBH1_OEB IOMUX_MODE(MX31_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT1) -#define MX31_PIN_CSPI1_SPI_RDY__USBH1_FS IOMUX_MODE(MX31_PIN_CSPI1_SPI_RDY, IOMUX_CONFIG_ALT1) -#define MX31_PIN_SFS6__USBH1_SUSPEND IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_FUNC) -#define MX31_PIN_NFRE_B__GPIO1_11 IOMUX_MODE(MX31_PIN_NFRE_B, IOMUX_CONFIG_GPIO) -#define MX31_PIN_NFALE__GPIO1_12 IOMUX_MODE(MX31_PIN_NFALE, IOMUX_CONFIG_GPIO) -#define MX31_PIN_USBH2_DATA0__USBH2_DATA0 IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBH2_DATA1__USBH2_DATA1 IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_STXD3__USBH2_DATA2 IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SRXD3__USBH2_DATA3 IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SCK3__USBH2_DATA4 IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SFS3__USBH2_DATA5 IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC) -#define MX31_PIN_STXD6__USBH2_DATA6 IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SRXD6__USBH2_DATA7 IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBH2_CLK__USBH2_CLK IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBH2_DIR__USBH2_DIR IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBH2_NXT__USBH2_NXT IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC) -#define MX31_PIN_USBH2_STP__USBH2_STP IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SCK6__GPIO1_25 IOMUX_MODE(MX31_PIN_SCK6, IOMUX_CONFIG_GPIO) -#define MX31_PIN_USB_OC__GPIO1_30 IOMUX_MODE(MX31_PIN_USB_OC, IOMUX_CONFIG_GPIO) -#define MX31_PIN_I2C_DAT__I2C1_SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC) -#define MX31_PIN_I2C_CLK__I2C1_SCL IOMUX_MODE(MX31_PIN_I2C_CLK, IOMUX_CONFIG_FUNC) -#define MX31_PIN_GPIO1_0__GPIO1_0 IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO) -#define MX31_PIN_SVEN0__GPIO2_0 IOMUX_MODE(MX31_PIN_SVEN0, IOMUX_CONFIG_GPIO) -#define MX31_PIN_STX0__GPIO2_1 IOMUX_MODE(MX31_PIN_STX0, IOMUX_CONFIG_GPIO) -#define MX31_PIN_SRX0__GPIO2_2 IOMUX_MODE(MX31_PIN_SRX0, IOMUX_CONFIG_GPIO) -#define MX31_PIN_SIMPD0__GPIO2_3 IOMUX_MODE(MX31_PIN_SIMPD0, IOMUX_CONFIG_GPIO) -#define MX31_PIN_DTR_DCE1__GPIO2_8 IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO) -#define MX31_PIN_DSR_DCE1__GPIO2_9 IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_GPIO) -#define MX31_PIN_RI_DCE1__GPIO2_10 IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_GPIO) -#define MX31_PIN_DCD_DCE1__GPIO2_11 IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_GPIO) -#define MX31_PIN_STXD5__GPIO1_21 IOMUX_MODE(MX31_PIN_STXD5, IOMUX_CONFIG_GPIO) -#define MX31_PIN_SRXD5__GPIO1_22 IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_GPIO) -#define MX31_PIN_GPIO1_3__GPIO1_3 IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO) -#define MX31_PIN_CSPI2_SS1__CSPI3_SS1 IOMUX_MODE(MX31_PIN_CSPI2_SS1, IOMUX_CONFIG_ALT1) -#define MX31_PIN_RTS1__GPIO2_6 IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_GPIO) -#define MX31_PIN_CTS1__GPIO2_7 IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_GPIO) -#define MX31_PIN_LCS0__GPIO3_23 IOMUX_MODE(MX31_PIN_LCS0, IOMUX_CONFIG_GPIO) -#define MX31_PIN_STXD4__STXD4 IOMUX_MODE(MX31_PIN_STXD4, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SRXD4__SRXD4 IOMUX_MODE(MX31_PIN_SRXD4, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SCK4__SCK4 IOMUX_MODE(MX31_PIN_SCK4, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SFS4__SFS4 IOMUX_MODE(MX31_PIN_SFS4, IOMUX_CONFIG_FUNC) -#define MX31_PIN_STXD5__STXD5 IOMUX_MODE(MX31_PIN_STXD5, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SRXD5__SRXD5 IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SCK5__SCK5 IOMUX_MODE(MX31_PIN_SCK5, IOMUX_CONFIG_FUNC) -#define MX31_PIN_SFS5__SFS5 IOMUX_MODE(MX31_PIN_SFS5, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_ROW0_KEY_ROW0 IOMUX_MODE(MX31_PIN_KEY_ROW0, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_ROW1_KEY_ROW1 IOMUX_MODE(MX31_PIN_KEY_ROW1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_ROW2_KEY_ROW2 IOMUX_MODE(MX31_PIN_KEY_ROW2, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_ROW3_KEY_ROW3 IOMUX_MODE(MX31_PIN_KEY_ROW3, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_ROW4_KEY_ROW4 IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_ROW4_GPIO IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_GPIO) -#define MX31_PIN_KEY_ROW5_KEY_ROW5 IOMUX_MODE(MX31_PIN_KEY_ROW5, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_ROW6_KEY_ROW6 IOMUX_MODE(MX31_PIN_KEY_ROW6, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_ROW7_KEY_ROW7 IOMUX_MODE(MX31_PIN_KEY_ROW7, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_COL0_KEY_COL0 IOMUX_MODE(MX31_PIN_KEY_COL0, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_COL1_KEY_COL1 IOMUX_MODE(MX31_PIN_KEY_COL1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_COL2_KEY_COL2 IOMUX_MODE(MX31_PIN_KEY_COL2, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_COL3_KEY_COL3 IOMUX_MODE(MX31_PIN_KEY_COL3, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_COL4_KEY_COL4 IOMUX_MODE(MX31_PIN_KEY_COL4, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_COL5_KEY_COL5 IOMUX_MODE(MX31_PIN_KEY_COL5, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_COL6_KEY_COL6 IOMUX_MODE(MX31_PIN_KEY_COL6, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_COL7_KEY_COL7 IOMUX_MODE(MX31_PIN_KEY_COL7, IOMUX_CONFIG_FUNC) -#define MX31_PIN_WATCHDOG_RST__WATCHDOG_RST IOMUX_MODE(MX31_PIN_WATCHDOG_RST, IOMUX_CONFIG_FUNC) - - -/* - * XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed with cspi2_ss0, - * cspi2_ss1, cspi1_ss0 cspi1_ss1 - */ - -/* - * This function configures the pad value for a IOMUX pin. - */ -void mxc_iomux_set_pad(enum iomux_pins, u32); - -#endif /* ifndef __MACH_IOMUX_MX3_H__ */ diff --git a/arch/arm/mach-imx/iomux-mx35.h b/arch/arm/mach-imx/iomux-mx35.h deleted file mode 100644 index 7fb5259b3ee0..000000000000 --- a/arch/arm/mach-imx/iomux-mx35.h +++ /dev/null @@ -1,1254 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de> - */ - -#ifndef __MACH_IOMUX_MX35_H__ -#define __MACH_IOMUX_MX35_H__ - -#include "iomux-v3.h" - -/* - * The naming convention for the pad modes is MX35_PAD_<padname>__<padmode> - * If <padname> or <padmode> refers to a GPIO, it is named - * GPIO_<unit>_<num> see also iomux-v3.h - */ - -/* PAD MUX ALT INPSE PATH */ -#define MX35_PAD_CAPTURE__GPT_CAPIN1 IOMUX_PAD(0x328, 0x004, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CAPTURE__GPT_CMPOUT2 IOMUX_PAD(0x328, 0x004, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CAPTURE__CSPI2_SS1 IOMUX_PAD(0x328, 0x004, 2, 0x7f4, 0, NO_PAD_CTRL) -#define MX35_PAD_CAPTURE__EPIT1_EPITO IOMUX_PAD(0x328, 0x004, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CAPTURE__CCM_CLK32K IOMUX_PAD(0x328, 0x004, 4, 0x7d0, 0, NO_PAD_CTRL) -#define MX35_PAD_CAPTURE__GPIO1_4 IOMUX_PAD(0x328, 0x004, 5, 0x850, 0, NO_PAD_CTRL) - -#define MX35_PAD_COMPARE__GPT_CMPOUT1 IOMUX_PAD(0x32c, 0x008, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_COMPARE__GPT_CAPIN2 IOMUX_PAD(0x32c, 0x008, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_COMPARE__GPT_CMPOUT3 IOMUX_PAD(0x32c, 0x008, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_COMPARE__EPIT2_EPITO IOMUX_PAD(0x32c, 0x008, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_COMPARE__GPIO1_5 IOMUX_PAD(0x32c, 0x008, 5, 0x854, 0, NO_PAD_CTRL) -#define MX35_PAD_COMPARE__SDMA_EXTDMA_2 IOMUX_PAD(0x32c, 0x008, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_WDOG_RST__WDOG_WDOG_B IOMUX_PAD(0x330, 0x00c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_WDOG_RST__IPU_FLASH_STROBE IOMUX_PAD(0x330, 0x00c, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_WDOG_RST__GPIO1_6 IOMUX_PAD(0x330, 0x00c, 5, 0x858, 0, NO_PAD_CTRL) - -#define MX35_PAD_GPIO1_0__GPIO1_0 IOMUX_PAD(0x334, 0x010, 0, 0x82c, 0, NO_PAD_CTRL) -#define MX35_PAD_GPIO1_0__CCM_PMIC_RDY IOMUX_PAD(0x334, 0x010, 1, 0x7d4, 0, NO_PAD_CTRL) -#define MX35_PAD_GPIO1_0__OWIRE_LINE IOMUX_PAD(0x334, 0x010, 2, 0x990, 0, NO_PAD_CTRL) -#define MX35_PAD_GPIO1_0__SDMA_EXTDMA_0 IOMUX_PAD(0x334, 0x010, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_GPIO1_1__GPIO1_1 IOMUX_PAD(0x338, 0x014, 0, 0x838, 0, NO_PAD_CTRL) -#define MX35_PAD_GPIO1_1__PWM_PWMO IOMUX_PAD(0x338, 0x014, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_GPIO1_1__CSPI1_SS2 IOMUX_PAD(0x338, 0x014, 3, 0x7d8, 0, NO_PAD_CTRL) -#define MX35_PAD_GPIO1_1__SCC_TAMPER_DETECT IOMUX_PAD(0x338, 0x014, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_GPIO1_1__SDMA_EXTDMA_1 IOMUX_PAD(0x338, 0x014, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_GPIO2_0__GPIO2_0 IOMUX_PAD(0x33c, 0x018, 0, 0x868, 0, NO_PAD_CTRL) -#define MX35_PAD_GPIO2_0__USB_TOP_USBOTG_CLK IOMUX_PAD(0x33c, 0x018, 1, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_GPIO3_0__GPIO3_0 IOMUX_PAD(0x340, 0x01c, 0, 0x8e8, 0, NO_PAD_CTRL) -#define MX35_PAD_GPIO3_0__USB_TOP_USBH2_CLK IOMUX_PAD(0x340, 0x01c, 1, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_RESET_IN_B__CCM_RESET_IN_B IOMUX_PAD(0x344, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_POR_B__CCM_POR_B IOMUX_PAD(0x348, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CLKO__CCM_CLKO IOMUX_PAD(0x34c, 0x020, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CLKO__GPIO1_8 IOMUX_PAD(0x34c, 0x020, 5, 0x860, 0, NO_PAD_CTRL) - -#define MX35_PAD_BOOT_MODE0__CCM_BOOT_MODE_0 IOMUX_PAD(0x350, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_BOOT_MODE1__CCM_BOOT_MODE_1 IOMUX_PAD(0x354, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CLK_MODE0__CCM_CLK_MODE_0 IOMUX_PAD(0x358, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CLK_MODE1__CCM_CLK_MODE_1 IOMUX_PAD(0x35c, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_POWER_FAIL__CCM_DSM_WAKEUP_INT_26 IOMUX_PAD(0x360, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_VSTBY__CCM_VSTBY IOMUX_PAD(0x364, 0x024, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_VSTBY__GPIO1_7 IOMUX_PAD(0x364, 0x024, 5, 0x85c, 0, NO_PAD_CTRL) - -#define MX35_PAD_A0__EMI_EIM_DA_L_0 IOMUX_PAD(0x368, 0x028, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A1__EMI_EIM_DA_L_1 IOMUX_PAD(0x36c, 0x02c, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A2__EMI_EIM_DA_L_2 IOMUX_PAD(0x370, 0x030, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A3__EMI_EIM_DA_L_3 IOMUX_PAD(0x374, 0x034, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A4__EMI_EIM_DA_L_4 IOMUX_PAD(0x378, 0x038, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A5__EMI_EIM_DA_L_5 IOMUX_PAD(0x37c, 0x03c, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A6__EMI_EIM_DA_L_6 IOMUX_PAD(0x380, 0x040, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A7__EMI_EIM_DA_L_7 IOMUX_PAD(0x384, 0x044, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A8__EMI_EIM_DA_H_8 IOMUX_PAD(0x388, 0x048, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A9__EMI_EIM_DA_H_9 IOMUX_PAD(0x38c, 0x04c, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A10__EMI_EIM_DA_H_10 IOMUX_PAD(0x390, 0x050, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_MA10__EMI_MA10 IOMUX_PAD(0x394, 0x054, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A11__EMI_EIM_DA_H_11 IOMUX_PAD(0x398, 0x058, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A12__EMI_EIM_DA_H_12 IOMUX_PAD(0x39c, 0x05c, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A13__EMI_EIM_DA_H_13 IOMUX_PAD(0x3a0, 0x060, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A14__EMI_EIM_DA_H2_14 IOMUX_PAD(0x3a4, 0x064, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A15__EMI_EIM_DA_H2_15 IOMUX_PAD(0x3a8, 0x068, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A16__EMI_EIM_A_16 IOMUX_PAD(0x3ac, 0x06c, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A17__EMI_EIM_A_17 IOMUX_PAD(0x3b0, 0x070, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A18__EMI_EIM_A_18 IOMUX_PAD(0x3b4, 0x074, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A19__EMI_EIM_A_19 IOMUX_PAD(0x3b8, 0x078, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A20__EMI_EIM_A_20 IOMUX_PAD(0x3bc, 0x07c, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A21__EMI_EIM_A_21 IOMUX_PAD(0x3c0, 0x080, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A22__EMI_EIM_A_22 IOMUX_PAD(0x3c4, 0x084, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A23__EMI_EIM_A_23 IOMUX_PAD(0x3c8, 0x088, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A24__EMI_EIM_A_24 IOMUX_PAD(0x3cc, 0x08c, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_A25__EMI_EIM_A_25 IOMUX_PAD(0x3d0, 0x090, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SDBA1__EMI_EIM_SDBA1 IOMUX_PAD(0x3d4, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SDBA0__EMI_EIM_SDBA0 IOMUX_PAD(0x3d8, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD0__EMI_DRAM_D_0 IOMUX_PAD(0x3dc, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD1__EMI_DRAM_D_1 IOMUX_PAD(0x3e0, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD2__EMI_DRAM_D_2 IOMUX_PAD(0x3e4, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD3__EMI_DRAM_D_3 IOMUX_PAD(0x3e8, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD4__EMI_DRAM_D_4 IOMUX_PAD(0x3ec, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD5__EMI_DRAM_D_5 IOMUX_PAD(0x3f0, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD6__EMI_DRAM_D_6 IOMUX_PAD(0x3f4, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD7__EMI_DRAM_D_7 IOMUX_PAD(0x3f8, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD8__EMI_DRAM_D_8 IOMUX_PAD(0x3fc, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD9__EMI_DRAM_D_9 IOMUX_PAD(0x400, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD10__EMI_DRAM_D_10 IOMUX_PAD(0x404, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD11__EMI_DRAM_D_11 IOMUX_PAD(0x408, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD12__EMI_DRAM_D_12 IOMUX_PAD(0x40c, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD13__EMI_DRAM_D_13 IOMUX_PAD(0x410, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD14__EMI_DRAM_D_14 IOMUX_PAD(0x414, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD15__EMI_DRAM_D_15 IOMUX_PAD(0x418, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD16__EMI_DRAM_D_16 IOMUX_PAD(0x41c, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD17__EMI_DRAM_D_17 IOMUX_PAD(0x420, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD18__EMI_DRAM_D_18 IOMUX_PAD(0x424, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD19__EMI_DRAM_D_19 IOMUX_PAD(0x428, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD20__EMI_DRAM_D_20 IOMUX_PAD(0x42c, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD21__EMI_DRAM_D_21 IOMUX_PAD(0x430, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD22__EMI_DRAM_D_22 IOMUX_PAD(0x434, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD23__EMI_DRAM_D_23 IOMUX_PAD(0x438, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD24__EMI_DRAM_D_24 IOMUX_PAD(0x43c, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD25__EMI_DRAM_D_25 IOMUX_PAD(0x440, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD26__EMI_DRAM_D_26 IOMUX_PAD(0x444, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD27__EMI_DRAM_D_27 IOMUX_PAD(0x448, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD28__EMI_DRAM_D_28 IOMUX_PAD(0x44c, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD29__EMI_DRAM_D_29 IOMUX_PAD(0x450, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD30__EMI_DRAM_D_30 IOMUX_PAD(0x454, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD31__EMI_DRAM_D_31 IOMUX_PAD(0x458, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_DQM0__EMI_DRAM_DQM_0 IOMUX_PAD(0x45c, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_DQM1__EMI_DRAM_DQM_1 IOMUX_PAD(0x460, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_DQM2__EMI_DRAM_DQM_2 IOMUX_PAD(0x464, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_DQM3__EMI_DRAM_DQM_3 IOMUX_PAD(0x468, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_EB0__EMI_EIM_EB0_B IOMUX_PAD(0x46c, 0x094, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_EB1__EMI_EIM_EB1_B IOMUX_PAD(0x470, 0x098, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_OE__EMI_EIM_OE IOMUX_PAD(0x474, 0x09c, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CS0__EMI_EIM_CS0 IOMUX_PAD(0x478, 0x0a0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CS1__EMI_EIM_CS1 IOMUX_PAD(0x47c, 0x0a4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CS1__EMI_NANDF_CE3 IOMUX_PAD(0x47c, 0x0a4, 3, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CS2__EMI_EIM_CS2 IOMUX_PAD(0x480, 0x0a8, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CS3__EMI_EIM_CS3 IOMUX_PAD(0x484, 0x0ac, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CS4__EMI_EIM_CS4 IOMUX_PAD(0x488, 0x0b0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CS4__EMI_DTACK_B IOMUX_PAD(0x488, 0x0b0, 1, 0x800, 0, NO_PAD_CTRL) -#define MX35_PAD_CS4__EMI_NANDF_CE1 IOMUX_PAD(0x488, 0x0b0, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CS4__GPIO1_20 IOMUX_PAD(0x488, 0x0b0, 5, 0x83c, 0, NO_PAD_CTRL) - -#define MX35_PAD_CS5__EMI_EIM_CS5 IOMUX_PAD(0x48c, 0x0b4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CS5__CSPI2_SS2 IOMUX_PAD(0x48c, 0x0b4, 1, 0x7f8, 0, NO_PAD_CTRL) -#define MX35_PAD_CS5__CSPI1_SS2 IOMUX_PAD(0x48c, 0x0b4, 2, 0x7d8, 1, NO_PAD_CTRL) -#define MX35_PAD_CS5__EMI_NANDF_CE2 IOMUX_PAD(0x48c, 0x0b4, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CS5__GPIO1_21 IOMUX_PAD(0x48c, 0x0b4, 5, 0x840, 0, NO_PAD_CTRL) - -#define MX35_PAD_NF_CE0__EMI_NANDF_CE0 IOMUX_PAD(0x490, 0x0b8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_NF_CE0__GPIO1_22 IOMUX_PAD(0x490, 0x0b8, 5, 0x844, 0, NO_PAD_CTRL) - -#define MX35_PAD_ECB__EMI_EIM_ECB IOMUX_PAD(0x494, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LBA__EMI_EIM_LBA IOMUX_PAD(0x498, 0x0bc, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_BCLK__EMI_EIM_BCLK IOMUX_PAD(0x49c, 0x0c0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_RW__EMI_EIM_RW IOMUX_PAD(0x4a0, 0x0c4, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_RAS__EMI_DRAM_RAS IOMUX_PAD(0x4a4, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CAS__EMI_DRAM_CAS IOMUX_PAD(0x4a8, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SDWE__EMI_DRAM_SDWE IOMUX_PAD(0x4ac, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SDCKE0__EMI_DRAM_SDCKE_0 IOMUX_PAD(0x4b0, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SDCKE1__EMI_DRAM_SDCKE_1 IOMUX_PAD(0x4b4, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SDCLK__EMI_DRAM_SDCLK IOMUX_PAD(0x4b8, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SDQS0__EMI_DRAM_SDQS_0 IOMUX_PAD(0x4bc, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SDQS1__EMI_DRAM_SDQS_1 IOMUX_PAD(0x4c0, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SDQS2__EMI_DRAM_SDQS_2 IOMUX_PAD(0x4c4, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SDQS3__EMI_DRAM_SDQS_3 IOMUX_PAD(0x4c8, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_NFWE_B__EMI_NANDF_WE_B IOMUX_PAD(0x4cc, 0x0c8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFWE_B__USB_TOP_USBH2_DATA_3 IOMUX_PAD(0x4cc, 0x0c8, 1, 0x9d8, 0, NO_PAD_CTRL) -#define MX35_PAD_NFWE_B__IPU_DISPB_D0_VSYNC IOMUX_PAD(0x4cc, 0x0c8, 2, 0x924, 0, NO_PAD_CTRL) -#define MX35_PAD_NFWE_B__GPIO2_18 IOMUX_PAD(0x4cc, 0x0c8, 5, 0x88c, 0, NO_PAD_CTRL) -#define MX35_PAD_NFWE_B__ARM11P_TOP_TRACE_0 IOMUX_PAD(0x4cc, 0x0c8, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_NFRE_B__EMI_NANDF_RE_B IOMUX_PAD(0x4d0, 0x0cc, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFRE_B__USB_TOP_USBH2_DIR IOMUX_PAD(0x4d0, 0x0cc, 1, 0x9ec, 0, NO_PAD_CTRL) -#define MX35_PAD_NFRE_B__IPU_DISPB_BCLK IOMUX_PAD(0x4d0, 0x0cc, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFRE_B__GPIO2_19 IOMUX_PAD(0x4d0, 0x0cc, 5, 0x890, 0, NO_PAD_CTRL) -#define MX35_PAD_NFRE_B__ARM11P_TOP_TRACE_1 IOMUX_PAD(0x4d0, 0x0cc, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_NFALE__EMI_NANDF_ALE IOMUX_PAD(0x4d4, 0x0d0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFALE__USB_TOP_USBH2_STP IOMUX_PAD(0x4d4, 0x0d0, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFALE__IPU_DISPB_CS0 IOMUX_PAD(0x4d4, 0x0d0, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFALE__GPIO2_20 IOMUX_PAD(0x4d4, 0x0d0, 5, 0x898, 0, NO_PAD_CTRL) -#define MX35_PAD_NFALE__ARM11P_TOP_TRACE_2 IOMUX_PAD(0x4d4, 0x0d0, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_NFCLE__EMI_NANDF_CLE IOMUX_PAD(0x4d8, 0x0d4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFCLE__USB_TOP_USBH2_NXT IOMUX_PAD(0x4d8, 0x0d4, 1, 0x9f0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFCLE__IPU_DISPB_PAR_RS IOMUX_PAD(0x4d8, 0x0d4, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFCLE__GPIO2_21 IOMUX_PAD(0x4d8, 0x0d4, 5, 0x89c, 0, NO_PAD_CTRL) -#define MX35_PAD_NFCLE__ARM11P_TOP_TRACE_3 IOMUX_PAD(0x4d8, 0x0d4, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_NFWP_B__EMI_NANDF_WP_B IOMUX_PAD(0x4dc, 0x0d8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFWP_B__USB_TOP_USBH2_DATA_7 IOMUX_PAD(0x4dc, 0x0d8, 1, 0x9e8, 0, NO_PAD_CTRL) -#define MX35_PAD_NFWP_B__IPU_DISPB_WR IOMUX_PAD(0x4dc, 0x0d8, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFWP_B__GPIO2_22 IOMUX_PAD(0x4dc, 0x0d8, 5, 0x8a0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFWP_B__ARM11P_TOP_TRCTL IOMUX_PAD(0x4dc, 0x0d8, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_NFRB__EMI_NANDF_RB IOMUX_PAD(0x4e0, 0x0dc, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFRB__IPU_DISPB_RD IOMUX_PAD(0x4e0, 0x0dc, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_NFRB__GPIO2_23 IOMUX_PAD(0x4e0, 0x0dc, 5, 0x8a4, 0, NO_PAD_CTRL) -#define MX35_PAD_NFRB__ARM11P_TOP_TRCLK IOMUX_PAD(0x4e0, 0x0dc, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D15__EMI_EIM_D_15 IOMUX_PAD(0x4e4, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D14__EMI_EIM_D_14 IOMUX_PAD(0x4e8, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D13__EMI_EIM_D_13 IOMUX_PAD(0x4ec, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D12__EMI_EIM_D_12 IOMUX_PAD(0x4f0, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D11__EMI_EIM_D_11 IOMUX_PAD(0x4f4, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D10__EMI_EIM_D_10 IOMUX_PAD(0x4f8, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D9__EMI_EIM_D_9 IOMUX_PAD(0x4fc, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D8__EMI_EIM_D_8 IOMUX_PAD(0x500, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D7__EMI_EIM_D_7 IOMUX_PAD(0x504, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D6__EMI_EIM_D_6 IOMUX_PAD(0x508, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D5__EMI_EIM_D_5 IOMUX_PAD(0x50c, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D4__EMI_EIM_D_4 IOMUX_PAD(0x510, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D3__EMI_EIM_D_3 IOMUX_PAD(0x514, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D2__EMI_EIM_D_2 IOMUX_PAD(0x518, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D1__EMI_EIM_D_1 IOMUX_PAD(0x51c, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D0__EMI_EIM_D_0 IOMUX_PAD(0x520, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSI_D8__IPU_CSI_D_8 IOMUX_PAD(0x524, 0x0e0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D8__KPP_COL_0 IOMUX_PAD(0x524, 0x0e0, 1, 0x950, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D8__GPIO1_20 IOMUX_PAD(0x524, 0x0e0, 5, 0x83c, 1, NO_PAD_CTRL) -#define MX35_PAD_CSI_D8__ARM11P_TOP_EVNTBUS_13 IOMUX_PAD(0x524, 0x0e0, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSI_D9__IPU_CSI_D_9 IOMUX_PAD(0x528, 0x0e4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D9__KPP_COL_1 IOMUX_PAD(0x528, 0x0e4, 1, 0x954, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D9__GPIO1_21 IOMUX_PAD(0x528, 0x0e4, 5, 0x840, 1, NO_PAD_CTRL) -#define MX35_PAD_CSI_D9__ARM11P_TOP_EVNTBUS_14 IOMUX_PAD(0x528, 0x0e4, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSI_D10__IPU_CSI_D_10 IOMUX_PAD(0x52c, 0x0e8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D10__KPP_COL_2 IOMUX_PAD(0x52c, 0x0e8, 1, 0x958, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D10__GPIO1_22 IOMUX_PAD(0x52c, 0x0e8, 5, 0x844, 1, NO_PAD_CTRL) -#define MX35_PAD_CSI_D10__ARM11P_TOP_EVNTBUS_15 IOMUX_PAD(0x52c, 0x0e8, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSI_D11__IPU_CSI_D_11 IOMUX_PAD(0x530, 0x0ec, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D11__KPP_COL_3 IOMUX_PAD(0x530, 0x0ec, 1, 0x95c, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D11__GPIO1_23 IOMUX_PAD(0x530, 0x0ec, 5, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSI_D12__IPU_CSI_D_12 IOMUX_PAD(0x534, 0x0f0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D12__KPP_ROW_0 IOMUX_PAD(0x534, 0x0f0, 1, 0x970, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D12__GPIO1_24 IOMUX_PAD(0x534, 0x0f0, 5, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSI_D13__IPU_CSI_D_13 IOMUX_PAD(0x538, 0x0f4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D13__KPP_ROW_1 IOMUX_PAD(0x538, 0x0f4, 1, 0x974, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D13__GPIO1_25 IOMUX_PAD(0x538, 0x0f4, 5, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSI_D14__IPU_CSI_D_14 IOMUX_PAD(0x53c, 0x0f8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D14__KPP_ROW_2 IOMUX_PAD(0x53c, 0x0f8, 1, 0x978, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D14__GPIO1_26 IOMUX_PAD(0x53c, 0x0f8, 5, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSI_D15__IPU_CSI_D_15 IOMUX_PAD(0x540, 0x0fc, 0, 0x97c, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D15__KPP_ROW_3 IOMUX_PAD(0x540, 0x0fc, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_D15__GPIO1_27 IOMUX_PAD(0x540, 0x0fc, 5, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSI_MCLK__IPU_CSI_MCLK IOMUX_PAD(0x544, 0x100, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_MCLK__GPIO1_28 IOMUX_PAD(0x544, 0x100, 5, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSI_VSYNC__IPU_CSI_VSYNC IOMUX_PAD(0x548, 0x104, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_VSYNC__GPIO1_29 IOMUX_PAD(0x548, 0x104, 5, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSI_HSYNC__IPU_CSI_HSYNC IOMUX_PAD(0x54c, 0x108, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_HSYNC__GPIO1_30 IOMUX_PAD(0x54c, 0x108, 5, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSI_PIXCLK__IPU_CSI_PIXCLK IOMUX_PAD(0x550, 0x10c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSI_PIXCLK__GPIO1_31 IOMUX_PAD(0x550, 0x10c, 5, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_I2C1_CLK__I2C1_SCL IOMUX_PAD(0x554, 0x110, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_I2C1_CLK__GPIO2_24 IOMUX_PAD(0x554, 0x110, 5, 0x8a8, 0, NO_PAD_CTRL) -#define MX35_PAD_I2C1_CLK__CCM_USB_BYP_CLK IOMUX_PAD(0x554, 0x110, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_I2C1_DAT__I2C1_SDA IOMUX_PAD(0x558, 0x114, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_I2C1_DAT__GPIO2_25 IOMUX_PAD(0x558, 0x114, 5, 0x8ac, 0, NO_PAD_CTRL) - -#define MX35_PAD_I2C2_CLK__I2C2_SCL IOMUX_PAD(0x55c, 0x118, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_I2C2_CLK__CAN1_TXCAN IOMUX_PAD(0x55c, 0x118, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR IOMUX_PAD(0x55c, 0x118, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_I2C2_CLK__GPIO2_26 IOMUX_PAD(0x55c, 0x118, 5, 0x8b0, 0, NO_PAD_CTRL) -#define MX35_PAD_I2C2_CLK__SDMA_DEBUG_BUS_DEVICE_2 IOMUX_PAD(0x55c, 0x118, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_I2C2_DAT__I2C2_SDA IOMUX_PAD(0x560, 0x11c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_I2C2_DAT__CAN1_RXCAN IOMUX_PAD(0x560, 0x11c, 1, 0x7c8, 0, NO_PAD_CTRL) -#define MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC IOMUX_PAD(0x560, 0x11c, 2, 0x9f4, 0, NO_PAD_CTRL) -#define MX35_PAD_I2C2_DAT__GPIO2_27 IOMUX_PAD(0x560, 0x11c, 5, 0x8b4, 0, NO_PAD_CTRL) -#define MX35_PAD_I2C2_DAT__SDMA_DEBUG_BUS_DEVICE_3 IOMUX_PAD(0x560, 0x11c, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_STXD4__AUDMUX_AUD4_TXD IOMUX_PAD(0x564, 0x120, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_STXD4__GPIO2_28 IOMUX_PAD(0x564, 0x120, 5, 0x8b8, 0, NO_PAD_CTRL) -#define MX35_PAD_STXD4__ARM11P_TOP_ARM_COREASID0 IOMUX_PAD(0x564, 0x120, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SRXD4__AUDMUX_AUD4_RXD IOMUX_PAD(0x568, 0x124, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SRXD4__GPIO2_29 IOMUX_PAD(0x568, 0x124, 5, 0x8bc, 0, NO_PAD_CTRL) -#define MX35_PAD_SRXD4__ARM11P_TOP_ARM_COREASID1 IOMUX_PAD(0x568, 0x124, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SCK4__AUDMUX_AUD4_TXC IOMUX_PAD(0x56c, 0x128, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SCK4__GPIO2_30 IOMUX_PAD(0x56c, 0x128, 5, 0x8c4, 0, NO_PAD_CTRL) -#define MX35_PAD_SCK4__ARM11P_TOP_ARM_COREASID2 IOMUX_PAD(0x56c, 0x128, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS IOMUX_PAD(0x570, 0x12c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_STXFS4__GPIO2_31 IOMUX_PAD(0x570, 0x12c, 5, 0x8c8, 0, NO_PAD_CTRL) -#define MX35_PAD_STXFS4__ARM11P_TOP_ARM_COREASID3 IOMUX_PAD(0x570, 0x12c, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_STXD5__AUDMUX_AUD5_TXD IOMUX_PAD(0x574, 0x130, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_STXD5__SPDIF_SPDIF_OUT1 IOMUX_PAD(0x574, 0x130, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_STXD5__CSPI2_MOSI IOMUX_PAD(0x574, 0x130, 2, 0x7ec, 0, NO_PAD_CTRL) -#define MX35_PAD_STXD5__GPIO1_0 IOMUX_PAD(0x574, 0x130, 5, 0x82c, 1, NO_PAD_CTRL) -#define MX35_PAD_STXD5__ARM11P_TOP_ARM_COREASID4 IOMUX_PAD(0x574, 0x130, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SRXD5__AUDMUX_AUD5_RXD IOMUX_PAD(0x578, 0x134, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SRXD5__SPDIF_SPDIF_IN1 IOMUX_PAD(0x578, 0x134, 1, 0x998, 0, NO_PAD_CTRL) -#define MX35_PAD_SRXD5__CSPI2_MISO IOMUX_PAD(0x578, 0x134, 2, 0x7e8, 0, NO_PAD_CTRL) -#define MX35_PAD_SRXD5__GPIO1_1 IOMUX_PAD(0x578, 0x134, 5, 0x838, 1, NO_PAD_CTRL) -#define MX35_PAD_SRXD5__ARM11P_TOP_ARM_COREASID5 IOMUX_PAD(0x578, 0x134, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SCK5__AUDMUX_AUD5_TXC IOMUX_PAD(0x57c, 0x138, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SCK5__SPDIF_SPDIF_EXTCLK IOMUX_PAD(0x57c, 0x138, 1, 0x994, 0, NO_PAD_CTRL) -#define MX35_PAD_SCK5__CSPI2_SCLK IOMUX_PAD(0x57c, 0x138, 2, 0x7e0, 0, NO_PAD_CTRL) -#define MX35_PAD_SCK5__GPIO1_2 IOMUX_PAD(0x57c, 0x138, 5, 0x848, 0, NO_PAD_CTRL) -#define MX35_PAD_SCK5__ARM11P_TOP_ARM_COREASID6 IOMUX_PAD(0x57c, 0x138, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_STXFS5__AUDMUX_AUD5_TXFS IOMUX_PAD(0x580, 0x13c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_STXFS5__CSPI2_RDY IOMUX_PAD(0x580, 0x13c, 2, 0x7e4, 0, NO_PAD_CTRL) -#define MX35_PAD_STXFS5__GPIO1_3 IOMUX_PAD(0x580, 0x13c, 5, 0x84c, 0, NO_PAD_CTRL) -#define MX35_PAD_STXFS5__ARM11P_TOP_ARM_COREASID7 IOMUX_PAD(0x580, 0x13c, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SCKR__ESAI_SCKR IOMUX_PAD(0x584, 0x140, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SCKR__GPIO1_4 IOMUX_PAD(0x584, 0x140, 5, 0x850, 1, NO_PAD_CTRL) -#define MX35_PAD_SCKR__ARM11P_TOP_EVNTBUS_10 IOMUX_PAD(0x584, 0x140, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FSR__ESAI_FSR IOMUX_PAD(0x588, 0x144, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FSR__GPIO1_5 IOMUX_PAD(0x588, 0x144, 5, 0x854, 1, NO_PAD_CTRL) -#define MX35_PAD_FSR__ARM11P_TOP_EVNTBUS_11 IOMUX_PAD(0x588, 0x144, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_HCKR__ESAI_HCKR IOMUX_PAD(0x58c, 0x148, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_HCKR__AUDMUX_AUD5_RXFS IOMUX_PAD(0x58c, 0x148, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_HCKR__CSPI2_SS0 IOMUX_PAD(0x58c, 0x148, 2, 0x7f0, 0, NO_PAD_CTRL) -#define MX35_PAD_HCKR__IPU_FLASH_STROBE IOMUX_PAD(0x58c, 0x148, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_HCKR__GPIO1_6 IOMUX_PAD(0x58c, 0x148, 5, 0x858, 1, NO_PAD_CTRL) -#define MX35_PAD_HCKR__ARM11P_TOP_EVNTBUS_12 IOMUX_PAD(0x58c, 0x148, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SCKT__ESAI_SCKT IOMUX_PAD(0x590, 0x14c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SCKT__GPIO1_7 IOMUX_PAD(0x590, 0x14c, 5, 0x85c, 1, NO_PAD_CTRL) -#define MX35_PAD_SCKT__IPU_CSI_D_0 IOMUX_PAD(0x590, 0x14c, 6, 0x930, 0, NO_PAD_CTRL) -#define MX35_PAD_SCKT__KPP_ROW_2 IOMUX_PAD(0x590, 0x14c, 7, 0x978, 1, NO_PAD_CTRL) - -#define MX35_PAD_FST__ESAI_FST IOMUX_PAD(0x594, 0x150, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FST__GPIO1_8 IOMUX_PAD(0x594, 0x150, 5, 0x860, 1, NO_PAD_CTRL) -#define MX35_PAD_FST__IPU_CSI_D_1 IOMUX_PAD(0x594, 0x150, 6, 0x934, 0, NO_PAD_CTRL) -#define MX35_PAD_FST__KPP_ROW_3 IOMUX_PAD(0x594, 0x150, 7, 0x97c, 1, NO_PAD_CTRL) - -#define MX35_PAD_HCKT__ESAI_HCKT IOMUX_PAD(0x598, 0x154, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_HCKT__AUDMUX_AUD5_RXC IOMUX_PAD(0x598, 0x154, 1, 0x7a8, 0, NO_PAD_CTRL) -#define MX35_PAD_HCKT__GPIO1_9 IOMUX_PAD(0x598, 0x154, 5, 0x864, 0, NO_PAD_CTRL) -#define MX35_PAD_HCKT__IPU_CSI_D_2 IOMUX_PAD(0x598, 0x154, 6, 0x938, 0, NO_PAD_CTRL) -#define MX35_PAD_HCKT__KPP_COL_3 IOMUX_PAD(0x598, 0x154, 7, 0x95c, 1, NO_PAD_CTRL) - -#define MX35_PAD_TX5_RX0__ESAI_TX5_RX0 IOMUX_PAD(0x59c, 0x158, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX5_RX0__AUDMUX_AUD4_RXC IOMUX_PAD(0x59c, 0x158, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX5_RX0__CSPI2_SS2 IOMUX_PAD(0x59c, 0x158, 2, 0x7f8, 1, NO_PAD_CTRL) -#define MX35_PAD_TX5_RX0__CAN2_TXCAN IOMUX_PAD(0x59c, 0x158, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX5_RX0__UART2_DTR IOMUX_PAD(0x59c, 0x158, 4, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX5_RX0__GPIO1_10 IOMUX_PAD(0x59c, 0x158, 5, 0x830, 0, NO_PAD_CTRL) -#define MX35_PAD_TX5_RX0__EMI_M3IF_CHOSEN_MASTER_0 IOMUX_PAD(0x59c, 0x158, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_TX4_RX1__ESAI_TX4_RX1 IOMUX_PAD(0x5a0, 0x15c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX4_RX1__AUDMUX_AUD4_RXFS IOMUX_PAD(0x5a0, 0x15c, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX4_RX1__CSPI2_SS3 IOMUX_PAD(0x5a0, 0x15c, 2, 0x7fc, 0, NO_PAD_CTRL) -#define MX35_PAD_TX4_RX1__CAN2_RXCAN IOMUX_PAD(0x5a0, 0x15c, 3, 0x7cc, 0, NO_PAD_CTRL) -#define MX35_PAD_TX4_RX1__UART2_DSR IOMUX_PAD(0x5a0, 0x15c, 4, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX4_RX1__GPIO1_11 IOMUX_PAD(0x5a0, 0x15c, 5, 0x834, 0, NO_PAD_CTRL) -#define MX35_PAD_TX4_RX1__IPU_CSI_D_3 IOMUX_PAD(0x5a0, 0x15c, 6, 0x93c, 0, NO_PAD_CTRL) -#define MX35_PAD_TX4_RX1__KPP_ROW_0 IOMUX_PAD(0x5a0, 0x15c, 7, 0x970, 1, NO_PAD_CTRL) - -#define MX35_PAD_TX3_RX2__ESAI_TX3_RX2 IOMUX_PAD(0x5a4, 0x160, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX3_RX2__I2C3_SCL IOMUX_PAD(0x5a4, 0x160, 1, 0x91c, 0, NO_PAD_CTRL) -#define MX35_PAD_TX3_RX2__EMI_NANDF_CE1 IOMUX_PAD(0x5a4, 0x160, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX3_RX2__GPIO1_12 IOMUX_PAD(0x5a4, 0x160, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX3_RX2__IPU_CSI_D_4 IOMUX_PAD(0x5a4, 0x160, 6, 0x940, 0, NO_PAD_CTRL) -#define MX35_PAD_TX3_RX2__KPP_ROW_1 IOMUX_PAD(0x5a4, 0x160, 7, 0x974, 1, NO_PAD_CTRL) - -#define MX35_PAD_TX2_RX3__ESAI_TX2_RX3 IOMUX_PAD(0x5a8, 0x164, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX2_RX3__I2C3_SDA IOMUX_PAD(0x5a8, 0x164, 1, 0x920, 0, NO_PAD_CTRL) -#define MX35_PAD_TX2_RX3__EMI_NANDF_CE2 IOMUX_PAD(0x5a8, 0x164, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX2_RX3__GPIO1_13 IOMUX_PAD(0x5a8, 0x164, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX2_RX3__IPU_CSI_D_5 IOMUX_PAD(0x5a8, 0x164, 6, 0x944, 0, NO_PAD_CTRL) -#define MX35_PAD_TX2_RX3__KPP_COL_0 IOMUX_PAD(0x5a8, 0x164, 7, 0x950, 1, NO_PAD_CTRL) - -#define MX35_PAD_TX1__ESAI_TX1 IOMUX_PAD(0x5ac, 0x168, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX1__CCM_PMIC_RDY IOMUX_PAD(0x5ac, 0x168, 1, 0x7d4, 1, NO_PAD_CTRL) -#define MX35_PAD_TX1__CSPI1_SS2 IOMUX_PAD(0x5ac, 0x168, 2, 0x7d8, 2, NO_PAD_CTRL) -#define MX35_PAD_TX1__EMI_NANDF_CE3 IOMUX_PAD(0x5ac, 0x168, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX1__UART2_RI IOMUX_PAD(0x5ac, 0x168, 4, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX1__GPIO1_14 IOMUX_PAD(0x5ac, 0x168, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX1__IPU_CSI_D_6 IOMUX_PAD(0x5ac, 0x168, 6, 0x948, 0, NO_PAD_CTRL) -#define MX35_PAD_TX1__KPP_COL_1 IOMUX_PAD(0x5ac, 0x168, 7, 0x954, 1, NO_PAD_CTRL) - -#define MX35_PAD_TX0__ESAI_TX0 IOMUX_PAD(0x5b0, 0x16c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX0__SPDIF_SPDIF_EXTCLK IOMUX_PAD(0x5b0, 0x16c, 1, 0x994, 1, NO_PAD_CTRL) -#define MX35_PAD_TX0__CSPI1_SS3 IOMUX_PAD(0x5b0, 0x16c, 2, 0x7dc, 0, NO_PAD_CTRL) -#define MX35_PAD_TX0__EMI_DTACK_B IOMUX_PAD(0x5b0, 0x16c, 3, 0x800, 1, NO_PAD_CTRL) -#define MX35_PAD_TX0__UART2_DCD IOMUX_PAD(0x5b0, 0x16c, 4, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX0__GPIO1_15 IOMUX_PAD(0x5b0, 0x16c, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TX0__IPU_CSI_D_7 IOMUX_PAD(0x5b0, 0x16c, 6, 0x94c, 0, NO_PAD_CTRL) -#define MX35_PAD_TX0__KPP_COL_2 IOMUX_PAD(0x5b0, 0x16c, 7, 0x958, 1, NO_PAD_CTRL) - -#define MX35_PAD_CSPI1_MOSI__CSPI1_MOSI IOMUX_PAD(0x5b4, 0x170, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_MOSI__GPIO1_16 IOMUX_PAD(0x5b4, 0x170, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_MOSI__ECT_CTI_TRIG_OUT1_2 IOMUX_PAD(0x5b4, 0x170, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSPI1_MISO__CSPI1_MISO IOMUX_PAD(0x5b8, 0x174, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_MISO__GPIO1_17 IOMUX_PAD(0x5b8, 0x174, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_MISO__ECT_CTI_TRIG_OUT1_3 IOMUX_PAD(0x5b8, 0x174, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSPI1_SS0__CSPI1_SS0 IOMUX_PAD(0x5bc, 0x178, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SS0__OWIRE_LINE IOMUX_PAD(0x5bc, 0x178, 1, 0x990, 1, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SS0__CSPI2_SS3 IOMUX_PAD(0x5bc, 0x178, 2, 0x7fc, 1, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SS0__GPIO1_18 IOMUX_PAD(0x5bc, 0x178, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SS0__ECT_CTI_TRIG_OUT1_4 IOMUX_PAD(0x5bc, 0x178, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSPI1_SS1__CSPI1_SS1 IOMUX_PAD(0x5c0, 0x17c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SS1__PWM_PWMO IOMUX_PAD(0x5c0, 0x17c, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SS1__CCM_CLK32K IOMUX_PAD(0x5c0, 0x17c, 2, 0x7d0, 1, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SS1__GPIO1_19 IOMUX_PAD(0x5c0, 0x17c, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SS1__IPU_DIAGB_29 IOMUX_PAD(0x5c0, 0x17c, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SS1__ECT_CTI_TRIG_OUT1_5 IOMUX_PAD(0x5c0, 0x17c, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSPI1_SCLK__CSPI1_SCLK IOMUX_PAD(0x5c4, 0x180, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SCLK__GPIO3_4 IOMUX_PAD(0x5c4, 0x180, 5, 0x904, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SCLK__IPU_DIAGB_30 IOMUX_PAD(0x5c4, 0x180, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SCLK__EMI_M3IF_CHOSEN_MASTER_1 IOMUX_PAD(0x5c4, 0x180, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CSPI1_SPI_RDY__CSPI1_RDY IOMUX_PAD(0x5c8, 0x184, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SPI_RDY__GPIO3_5 IOMUX_PAD(0x5c8, 0x184, 5, 0x908, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SPI_RDY__IPU_DIAGB_31 IOMUX_PAD(0x5c8, 0x184, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CSPI1_SPI_RDY__EMI_M3IF_CHOSEN_MASTER_2 IOMUX_PAD(0x5c8, 0x184, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_RXD1__UART1_RXD_MUX IOMUX_PAD(0x5cc, 0x188, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_RXD1__CSPI2_MOSI IOMUX_PAD(0x5cc, 0x188, 1, 0x7ec, 1, NO_PAD_CTRL) -#define MX35_PAD_RXD1__KPP_COL_4 IOMUX_PAD(0x5cc, 0x188, 4, 0x960, 0, NO_PAD_CTRL) -#define MX35_PAD_RXD1__GPIO3_6 IOMUX_PAD(0x5cc, 0x188, 5, 0x90c, 0, NO_PAD_CTRL) -#define MX35_PAD_RXD1__ARM11P_TOP_EVNTBUS_16 IOMUX_PAD(0x5cc, 0x188, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_TXD1__UART1_TXD_MUX IOMUX_PAD(0x5d0, 0x18c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TXD1__CSPI2_MISO IOMUX_PAD(0x5d0, 0x18c, 1, 0x7e8, 1, NO_PAD_CTRL) -#define MX35_PAD_TXD1__KPP_COL_5 IOMUX_PAD(0x5d0, 0x18c, 4, 0x964, 0, NO_PAD_CTRL) -#define MX35_PAD_TXD1__GPIO3_7 IOMUX_PAD(0x5d0, 0x18c, 5, 0x910, 0, NO_PAD_CTRL) -#define MX35_PAD_TXD1__ARM11P_TOP_EVNTBUS_17 IOMUX_PAD(0x5d0, 0x18c, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_RTS1__UART1_RTS IOMUX_PAD(0x5d4, 0x190, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_RTS1__CSPI2_SCLK IOMUX_PAD(0x5d4, 0x190, 1, 0x7e0, 1, NO_PAD_CTRL) -#define MX35_PAD_RTS1__I2C3_SCL IOMUX_PAD(0x5d4, 0x190, 2, 0x91c, 1, NO_PAD_CTRL) -#define MX35_PAD_RTS1__IPU_CSI_D_0 IOMUX_PAD(0x5d4, 0x190, 3, 0x930, 1, NO_PAD_CTRL) -#define MX35_PAD_RTS1__KPP_COL_6 IOMUX_PAD(0x5d4, 0x190, 4, 0x968, 0, NO_PAD_CTRL) -#define MX35_PAD_RTS1__GPIO3_8 IOMUX_PAD(0x5d4, 0x190, 5, 0x914, 0, NO_PAD_CTRL) -#define MX35_PAD_RTS1__EMI_NANDF_CE1 IOMUX_PAD(0x5d4, 0x190, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_RTS1__ARM11P_TOP_EVNTBUS_18 IOMUX_PAD(0x5d4, 0x190, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CTS1__UART1_CTS IOMUX_PAD(0x5d8, 0x194, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CTS1__CSPI2_RDY IOMUX_PAD(0x5d8, 0x194, 1, 0x7e4, 1, NO_PAD_CTRL) -#define MX35_PAD_CTS1__I2C3_SDA IOMUX_PAD(0x5d8, 0x194, 2, 0x920, 1, NO_PAD_CTRL) -#define MX35_PAD_CTS1__IPU_CSI_D_1 IOMUX_PAD(0x5d8, 0x194, 3, 0x934, 1, NO_PAD_CTRL) -#define MX35_PAD_CTS1__KPP_COL_7 IOMUX_PAD(0x5d8, 0x194, 4, 0x96c, 0, NO_PAD_CTRL) -#define MX35_PAD_CTS1__GPIO3_9 IOMUX_PAD(0x5d8, 0x194, 5, 0x918, 0, NO_PAD_CTRL) -#define MX35_PAD_CTS1__EMI_NANDF_CE2 IOMUX_PAD(0x5d8, 0x194, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CTS1__ARM11P_TOP_EVNTBUS_19 IOMUX_PAD(0x5d8, 0x194, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_RXD2__UART2_RXD_MUX IOMUX_PAD(0x5dc, 0x198, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_RXD2__KPP_ROW_4 IOMUX_PAD(0x5dc, 0x198, 4, 0x980, 0, NO_PAD_CTRL) -#define MX35_PAD_RXD2__GPIO3_10 IOMUX_PAD(0x5dc, 0x198, 5, 0x8ec, 0, NO_PAD_CTRL) - -#define MX35_PAD_TXD2__UART2_TXD_MUX IOMUX_PAD(0x5e0, 0x19c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_TXD2__SPDIF_SPDIF_EXTCLK IOMUX_PAD(0x5e0, 0x19c, 1, 0x994, 2, NO_PAD_CTRL) -#define MX35_PAD_TXD2__KPP_ROW_5 IOMUX_PAD(0x5e0, 0x19c, 4, 0x984, 0, NO_PAD_CTRL) -#define MX35_PAD_TXD2__GPIO3_11 IOMUX_PAD(0x5e0, 0x19c, 5, 0x8f0, 0, NO_PAD_CTRL) - -#define MX35_PAD_RTS2__UART2_RTS IOMUX_PAD(0x5e4, 0x1a0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_RTS2__SPDIF_SPDIF_IN1 IOMUX_PAD(0x5e4, 0x1a0, 1, 0x998, 1, NO_PAD_CTRL) -#define MX35_PAD_RTS2__CAN2_RXCAN IOMUX_PAD(0x5e4, 0x1a0, 2, 0x7cc, 1, NO_PAD_CTRL) -#define MX35_PAD_RTS2__IPU_CSI_D_2 IOMUX_PAD(0x5e4, 0x1a0, 3, 0x938, 1, NO_PAD_CTRL) -#define MX35_PAD_RTS2__KPP_ROW_6 IOMUX_PAD(0x5e4, 0x1a0, 4, 0x988, 0, NO_PAD_CTRL) -#define MX35_PAD_RTS2__GPIO3_12 IOMUX_PAD(0x5e4, 0x1a0, 5, 0x8f4, 0, NO_PAD_CTRL) -#define MX35_PAD_RTS2__AUDMUX_AUD5_RXC IOMUX_PAD(0x5e4, 0x1a0, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_RTS2__UART3_RXD_MUX IOMUX_PAD(0x5e4, 0x1a0, 7, 0x9a0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CTS2__UART2_CTS IOMUX_PAD(0x5e8, 0x1a4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CTS2__SPDIF_SPDIF_OUT1 IOMUX_PAD(0x5e8, 0x1a4, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CTS2__CAN2_TXCAN IOMUX_PAD(0x5e8, 0x1a4, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CTS2__IPU_CSI_D_3 IOMUX_PAD(0x5e8, 0x1a4, 3, 0x93c, 1, NO_PAD_CTRL) -#define MX35_PAD_CTS2__KPP_ROW_7 IOMUX_PAD(0x5e8, 0x1a4, 4, 0x98c, 0, NO_PAD_CTRL) -#define MX35_PAD_CTS2__GPIO3_13 IOMUX_PAD(0x5e8, 0x1a4, 5, 0x8f8, 0, NO_PAD_CTRL) -#define MX35_PAD_CTS2__AUDMUX_AUD5_RXFS IOMUX_PAD(0x5e8, 0x1a4, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CTS2__UART3_TXD_MUX IOMUX_PAD(0x5e8, 0x1a4, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_RTCK__ARM11P_TOP_RTCK IOMUX_PAD(0x5ec, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_TCK__SJC_TCK IOMUX_PAD(0x5f0, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_TMS__SJC_TMS IOMUX_PAD(0x5f4, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_TDI__SJC_TDI IOMUX_PAD(0x5f8, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_TDO__SJC_TDO IOMUX_PAD(0x5fc, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_TRSTB__SJC_TRSTB IOMUX_PAD(0x600, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_DE_B__SJC_DE_B IOMUX_PAD(0x604, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SJC_MOD__SJC_MOD IOMUX_PAD(0x608, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR IOMUX_PAD(0x60c, 0x1a8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_USBOTG_PWR__USB_TOP_USBH2_PWR IOMUX_PAD(0x60c, 0x1a8, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_USBOTG_PWR__GPIO3_14 IOMUX_PAD(0x60c, 0x1a8, 5, 0x8fc, 0, NO_PAD_CTRL) - -#define MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC IOMUX_PAD(0x610, 0x1ac, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_USBOTG_OC__USB_TOP_USBH2_OC IOMUX_PAD(0x610, 0x1ac, 1, 0x9f4, 1, NO_PAD_CTRL) -#define MX35_PAD_USBOTG_OC__GPIO3_15 IOMUX_PAD(0x610, 0x1ac, 5, 0x900, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD0__IPU_DISPB_DAT_0 IOMUX_PAD(0x614, 0x1b0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD0__GPIO2_0 IOMUX_PAD(0x614, 0x1b0, 5, 0x868, 1, NO_PAD_CTRL) -#define MX35_PAD_LD0__SDMA_SDMA_DEBUG_PC_0 IOMUX_PAD(0x614, 0x1b0, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD1__IPU_DISPB_DAT_1 IOMUX_PAD(0x618, 0x1b4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD1__GPIO2_1 IOMUX_PAD(0x618, 0x1b4, 5, 0x894, 0, NO_PAD_CTRL) -#define MX35_PAD_LD1__SDMA_SDMA_DEBUG_PC_1 IOMUX_PAD(0x618, 0x1b4, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD2__IPU_DISPB_DAT_2 IOMUX_PAD(0x61c, 0x1b8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD2__GPIO2_2 IOMUX_PAD(0x61c, 0x1b8, 5, 0x8c0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD2__SDMA_SDMA_DEBUG_PC_2 IOMUX_PAD(0x61c, 0x1b8, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD3__IPU_DISPB_DAT_3 IOMUX_PAD(0x620, 0x1bc, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD3__GPIO2_3 IOMUX_PAD(0x620, 0x1bc, 5, 0x8cc, 0, NO_PAD_CTRL) -#define MX35_PAD_LD3__SDMA_SDMA_DEBUG_PC_3 IOMUX_PAD(0x620, 0x1bc, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD4__IPU_DISPB_DAT_4 IOMUX_PAD(0x624, 0x1c0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD4__GPIO2_4 IOMUX_PAD(0x624, 0x1c0, 5, 0x8d0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD4__SDMA_SDMA_DEBUG_PC_4 IOMUX_PAD(0x624, 0x1c0, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD5__IPU_DISPB_DAT_5 IOMUX_PAD(0x628, 0x1c4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD5__GPIO2_5 IOMUX_PAD(0x628, 0x1c4, 5, 0x8d4, 0, NO_PAD_CTRL) -#define MX35_PAD_LD5__SDMA_SDMA_DEBUG_PC_5 IOMUX_PAD(0x628, 0x1c4, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD6__IPU_DISPB_DAT_6 IOMUX_PAD(0x62c, 0x1c8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD6__GPIO2_6 IOMUX_PAD(0x62c, 0x1c8, 5, 0x8d8, 0, NO_PAD_CTRL) -#define MX35_PAD_LD6__SDMA_SDMA_DEBUG_PC_6 IOMUX_PAD(0x62c, 0x1c8, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD7__IPU_DISPB_DAT_7 IOMUX_PAD(0x630, 0x1cc, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD7__GPIO2_7 IOMUX_PAD(0x630, 0x1cc, 5, 0x8dc, 0, NO_PAD_CTRL) -#define MX35_PAD_LD7__SDMA_SDMA_DEBUG_PC_7 IOMUX_PAD(0x630, 0x1cc, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD8__IPU_DISPB_DAT_8 IOMUX_PAD(0x634, 0x1d0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD8__GPIO2_8 IOMUX_PAD(0x634, 0x1d0, 5, 0x8e0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD8__SDMA_SDMA_DEBUG_PC_8 IOMUX_PAD(0x634, 0x1d0, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD9__IPU_DISPB_DAT_9 IOMUX_PAD(0x638, 0x1d4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD9__GPIO2_9 IOMUX_PAD(0x638, 0x1d4, 5, 0x8e4, 0, NO_PAD_CTRL) -#define MX35_PAD_LD9__SDMA_SDMA_DEBUG_PC_9 IOMUX_PAD(0x638, 0x1d4, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD10__IPU_DISPB_DAT_10 IOMUX_PAD(0x63c, 0x1d8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD10__GPIO2_10 IOMUX_PAD(0x63c, 0x1d8, 5, 0x86c, 0, NO_PAD_CTRL) -#define MX35_PAD_LD10__SDMA_SDMA_DEBUG_PC_10 IOMUX_PAD(0x63c, 0x1d8, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD11__IPU_DISPB_DAT_11 IOMUX_PAD(0x640, 0x1dc, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD11__GPIO2_11 IOMUX_PAD(0x640, 0x1dc, 5, 0x870, 0, NO_PAD_CTRL) -#define MX35_PAD_LD11__SDMA_SDMA_DEBUG_PC_11 IOMUX_PAD(0x640, 0x1dc, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD11__ARM11P_TOP_TRACE_4 IOMUX_PAD(0x640, 0x1dc, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD12__IPU_DISPB_DAT_12 IOMUX_PAD(0x644, 0x1e0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD12__GPIO2_12 IOMUX_PAD(0x644, 0x1e0, 5, 0x874, 0, NO_PAD_CTRL) -#define MX35_PAD_LD12__SDMA_SDMA_DEBUG_PC_12 IOMUX_PAD(0x644, 0x1e0, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD12__ARM11P_TOP_TRACE_5 IOMUX_PAD(0x644, 0x1e0, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD13__IPU_DISPB_DAT_13 IOMUX_PAD(0x648, 0x1e4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD13__GPIO2_13 IOMUX_PAD(0x648, 0x1e4, 5, 0x878, 0, NO_PAD_CTRL) -#define MX35_PAD_LD13__SDMA_SDMA_DEBUG_PC_13 IOMUX_PAD(0x648, 0x1e4, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD13__ARM11P_TOP_TRACE_6 IOMUX_PAD(0x648, 0x1e4, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD14__IPU_DISPB_DAT_14 IOMUX_PAD(0x64c, 0x1e8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD14__GPIO2_14 IOMUX_PAD(0x64c, 0x1e8, 5, 0x87c, 0, NO_PAD_CTRL) -#define MX35_PAD_LD14__SDMA_SDMA_DEBUG_EVENT_CHANNEL_0 IOMUX_PAD(0x64c, 0x1e8, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD14__ARM11P_TOP_TRACE_7 IOMUX_PAD(0x64c, 0x1e8, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD15__IPU_DISPB_DAT_15 IOMUX_PAD(0x650, 0x1ec, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD15__GPIO2_15 IOMUX_PAD(0x650, 0x1ec, 5, 0x880, 0, NO_PAD_CTRL) -#define MX35_PAD_LD15__SDMA_SDMA_DEBUG_EVENT_CHANNEL_1 IOMUX_PAD(0x650, 0x1ec, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD15__ARM11P_TOP_TRACE_8 IOMUX_PAD(0x650, 0x1ec, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD16__IPU_DISPB_DAT_16 IOMUX_PAD(0x654, 0x1f0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD16__IPU_DISPB_D12_VSYNC IOMUX_PAD(0x654, 0x1f0, 2, 0x928, 0, NO_PAD_CTRL) -#define MX35_PAD_LD16__GPIO2_16 IOMUX_PAD(0x654, 0x1f0, 5, 0x884, 0, NO_PAD_CTRL) -#define MX35_PAD_LD16__SDMA_SDMA_DEBUG_EVENT_CHANNEL_2 IOMUX_PAD(0x654, 0x1f0, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD16__ARM11P_TOP_TRACE_9 IOMUX_PAD(0x654, 0x1f0, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD17__IPU_DISPB_DAT_17 IOMUX_PAD(0x658, 0x1f4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD17__IPU_DISPB_CS2 IOMUX_PAD(0x658, 0x1f4, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD17__GPIO2_17 IOMUX_PAD(0x658, 0x1f4, 5, 0x888, 0, NO_PAD_CTRL) -#define MX35_PAD_LD17__SDMA_SDMA_DEBUG_EVENT_CHANNEL_3 IOMUX_PAD(0x658, 0x1f4, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD17__ARM11P_TOP_TRACE_10 IOMUX_PAD(0x658, 0x1f4, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD18__IPU_DISPB_DAT_18 IOMUX_PAD(0x65c, 0x1f8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD18__IPU_DISPB_D0_VSYNC IOMUX_PAD(0x65c, 0x1f8, 1, 0x924, 1, NO_PAD_CTRL) -#define MX35_PAD_LD18__IPU_DISPB_D12_VSYNC IOMUX_PAD(0x65c, 0x1f8, 2, 0x928, 1, NO_PAD_CTRL) -#define MX35_PAD_LD18__ESDHC3_CMD IOMUX_PAD(0x65c, 0x1f8, 3, 0x818, 0, NO_PAD_CTRL) -#define MX35_PAD_LD18__USB_TOP_USBOTG_DATA_3 IOMUX_PAD(0x65c, 0x1f8, 4, 0x9b0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD18__GPIO3_24 IOMUX_PAD(0x65c, 0x1f8, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD18__SDMA_SDMA_DEBUG_EVENT_CHANNEL_4 IOMUX_PAD(0x65c, 0x1f8, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD18__ARM11P_TOP_TRACE_11 IOMUX_PAD(0x65c, 0x1f8, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD19__IPU_DISPB_DAT_19 IOMUX_PAD(0x660, 0x1fc, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD19__IPU_DISPB_BCLK IOMUX_PAD(0x660, 0x1fc, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD19__IPU_DISPB_CS1 IOMUX_PAD(0x660, 0x1fc, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD19__ESDHC3_CLK IOMUX_PAD(0x660, 0x1fc, 3, 0x814, 0, NO_PAD_CTRL) -#define MX35_PAD_LD19__USB_TOP_USBOTG_DIR IOMUX_PAD(0x660, 0x1fc, 4, 0x9c4, 0, NO_PAD_CTRL) -#define MX35_PAD_LD19__GPIO3_25 IOMUX_PAD(0x660, 0x1fc, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD19__SDMA_SDMA_DEBUG_EVENT_CHANNEL_5 IOMUX_PAD(0x660, 0x1fc, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD19__ARM11P_TOP_TRACE_12 IOMUX_PAD(0x660, 0x1fc, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD20__IPU_DISPB_DAT_20 IOMUX_PAD(0x664, 0x200, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD20__IPU_DISPB_CS0 IOMUX_PAD(0x664, 0x200, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD20__IPU_DISPB_SD_CLK IOMUX_PAD(0x664, 0x200, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD20__ESDHC3_DAT0 IOMUX_PAD(0x664, 0x200, 3, 0x81c, 0, NO_PAD_CTRL) -#define MX35_PAD_LD20__GPIO3_26 IOMUX_PAD(0x664, 0x200, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD20__SDMA_SDMA_DEBUG_CORE_STATUS_3 IOMUX_PAD(0x664, 0x200, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD20__ARM11P_TOP_TRACE_13 IOMUX_PAD(0x664, 0x200, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD21__IPU_DISPB_DAT_21 IOMUX_PAD(0x668, 0x204, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD21__IPU_DISPB_PAR_RS IOMUX_PAD(0x668, 0x204, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD21__IPU_DISPB_SER_RS IOMUX_PAD(0x668, 0x204, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD21__ESDHC3_DAT1 IOMUX_PAD(0x668, 0x204, 3, 0x820, 0, NO_PAD_CTRL) -#define MX35_PAD_LD21__USB_TOP_USBOTG_STP IOMUX_PAD(0x668, 0x204, 4, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD21__GPIO3_27 IOMUX_PAD(0x668, 0x204, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD21__SDMA_DEBUG_EVENT_CHANNEL_SEL IOMUX_PAD(0x668, 0x204, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD21__ARM11P_TOP_TRACE_14 IOMUX_PAD(0x668, 0x204, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD22__IPU_DISPB_DAT_22 IOMUX_PAD(0x66c, 0x208, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD22__IPU_DISPB_WR IOMUX_PAD(0x66c, 0x208, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD22__IPU_DISPB_SD_D_I IOMUX_PAD(0x66c, 0x208, 2, 0x92c, 0, NO_PAD_CTRL) -#define MX35_PAD_LD22__ESDHC3_DAT2 IOMUX_PAD(0x66c, 0x208, 3, 0x824, 0, NO_PAD_CTRL) -#define MX35_PAD_LD22__USB_TOP_USBOTG_NXT IOMUX_PAD(0x66c, 0x208, 4, 0x9c8, 0, NO_PAD_CTRL) -#define MX35_PAD_LD22__GPIO3_28 IOMUX_PAD(0x66c, 0x208, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD22__SDMA_DEBUG_BUS_ERROR IOMUX_PAD(0x66c, 0x208, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD22__ARM11P_TOP_TRCTL IOMUX_PAD(0x66c, 0x208, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_LD23__IPU_DISPB_DAT_23 IOMUX_PAD(0x670, 0x20c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD23__IPU_DISPB_RD IOMUX_PAD(0x670, 0x20c, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD23__IPU_DISPB_SD_D_IO IOMUX_PAD(0x670, 0x20c, 2, 0x92c, 1, NO_PAD_CTRL) -#define MX35_PAD_LD23__ESDHC3_DAT3 IOMUX_PAD(0x670, 0x20c, 3, 0x828, 0, NO_PAD_CTRL) -#define MX35_PAD_LD23__USB_TOP_USBOTG_DATA_7 IOMUX_PAD(0x670, 0x20c, 4, 0x9c0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD23__GPIO3_29 IOMUX_PAD(0x670, 0x20c, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD23__SDMA_DEBUG_MATCHED_DMBUS IOMUX_PAD(0x670, 0x20c, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD23__ARM11P_TOP_TRCLK IOMUX_PAD(0x670, 0x20c, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC IOMUX_PAD(0x674, 0x210, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_HSYNC__IPU_DISPB_SD_D_IO IOMUX_PAD(0x674, 0x210, 2, 0x92c, 2, NO_PAD_CTRL) -#define MX35_PAD_D3_HSYNC__GPIO3_30 IOMUX_PAD(0x674, 0x210, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_HSYNC__SDMA_DEBUG_RTBUFFER_WRITE IOMUX_PAD(0x674, 0x210, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_HSYNC__ARM11P_TOP_TRACE_15 IOMUX_PAD(0x674, 0x210, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK IOMUX_PAD(0x678, 0x214, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_FPSHIFT__IPU_DISPB_SD_CLK IOMUX_PAD(0x678, 0x214, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_FPSHIFT__GPIO3_31 IOMUX_PAD(0x678, 0x214, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_FPSHIFT__SDMA_SDMA_DEBUG_CORE_STATUS_0 IOMUX_PAD(0x678, 0x214, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_FPSHIFT__ARM11P_TOP_TRACE_16 IOMUX_PAD(0x678, 0x214, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY IOMUX_PAD(0x67c, 0x218, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_DRDY__IPU_DISPB_SD_D_O IOMUX_PAD(0x67c, 0x218, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_DRDY__GPIO1_0 IOMUX_PAD(0x67c, 0x218, 5, 0x82c, 2, NO_PAD_CTRL) -#define MX35_PAD_D3_DRDY__SDMA_SDMA_DEBUG_CORE_STATUS_1 IOMUX_PAD(0x67c, 0x218, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_DRDY__ARM11P_TOP_TRACE_17 IOMUX_PAD(0x67c, 0x218, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_CONTRAST__IPU_DISPB_CONTR IOMUX_PAD(0x680, 0x21c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CONTRAST__GPIO1_1 IOMUX_PAD(0x680, 0x21c, 5, 0x838, 2, NO_PAD_CTRL) -#define MX35_PAD_CONTRAST__SDMA_SDMA_DEBUG_CORE_STATUS_2 IOMUX_PAD(0x680, 0x21c, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_CONTRAST__ARM11P_TOP_TRACE_18 IOMUX_PAD(0x680, 0x21c, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC IOMUX_PAD(0x684, 0x220, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_VSYNC__IPU_DISPB_CS1 IOMUX_PAD(0x684, 0x220, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_VSYNC__GPIO1_2 IOMUX_PAD(0x684, 0x220, 5, 0x848, 1, NO_PAD_CTRL) -#define MX35_PAD_D3_VSYNC__SDMA_DEBUG_YIELD IOMUX_PAD(0x684, 0x220, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_VSYNC__ARM11P_TOP_TRACE_19 IOMUX_PAD(0x684, 0x220, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D3_REV__IPU_DISPB_D3_REV IOMUX_PAD(0x688, 0x224, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_REV__IPU_DISPB_SER_RS IOMUX_PAD(0x688, 0x224, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_REV__GPIO1_3 IOMUX_PAD(0x688, 0x224, 5, 0x84c, 1, NO_PAD_CTRL) -#define MX35_PAD_D3_REV__SDMA_DEBUG_BUS_RWB IOMUX_PAD(0x688, 0x224, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_REV__ARM11P_TOP_TRACE_20 IOMUX_PAD(0x688, 0x224, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS IOMUX_PAD(0x68c, 0x228, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_CLS__IPU_DISPB_CS2 IOMUX_PAD(0x68c, 0x228, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_CLS__GPIO1_4 IOMUX_PAD(0x68c, 0x228, 5, 0x850, 2, NO_PAD_CTRL) -#define MX35_PAD_D3_CLS__SDMA_DEBUG_BUS_DEVICE_0 IOMUX_PAD(0x68c, 0x228, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_CLS__ARM11P_TOP_TRACE_21 IOMUX_PAD(0x68c, 0x228, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_D3_SPL__IPU_DISPB_D3_SPL IOMUX_PAD(0x690, 0x22c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_SPL__IPU_DISPB_D12_VSYNC IOMUX_PAD(0x690, 0x22c, 2, 0x928, 2, NO_PAD_CTRL) -#define MX35_PAD_D3_SPL__GPIO1_5 IOMUX_PAD(0x690, 0x22c, 5, 0x854, 2, NO_PAD_CTRL) -#define MX35_PAD_D3_SPL__SDMA_DEBUG_BUS_DEVICE_1 IOMUX_PAD(0x690, 0x22c, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_D3_SPL__ARM11P_TOP_TRACE_22 IOMUX_PAD(0x690, 0x22c, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD1_CMD__ESDHC1_CMD IOMUX_PAD(0x694, 0x230, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_CMD__MSHC_SCLK IOMUX_PAD(0x694, 0x230, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_CMD__IPU_DISPB_D0_VSYNC IOMUX_PAD(0x694, 0x230, 3, 0x924, 2, NO_PAD_CTRL) -#define MX35_PAD_SD1_CMD__USB_TOP_USBOTG_DATA_4 IOMUX_PAD(0x694, 0x230, 4, 0x9b4, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_CMD__GPIO1_6 IOMUX_PAD(0x694, 0x230, 5, 0x858, 2, NO_PAD_CTRL) -#define MX35_PAD_SD1_CMD__ARM11P_TOP_TRCTL IOMUX_PAD(0x694, 0x230, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD1_CLK__ESDHC1_CLK IOMUX_PAD(0x698, 0x234, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_CLK__MSHC_BS IOMUX_PAD(0x698, 0x234, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_CLK__IPU_DISPB_BCLK IOMUX_PAD(0x698, 0x234, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_CLK__USB_TOP_USBOTG_DATA_5 IOMUX_PAD(0x698, 0x234, 4, 0x9b8, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_CLK__GPIO1_7 IOMUX_PAD(0x698, 0x234, 5, 0x85c, 2, NO_PAD_CTRL) -#define MX35_PAD_SD1_CLK__ARM11P_TOP_TRCLK IOMUX_PAD(0x698, 0x234, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD1_DATA0__ESDHC1_DAT0 IOMUX_PAD(0x69c, 0x238, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA0__MSHC_DATA_0 IOMUX_PAD(0x69c, 0x238, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA0__IPU_DISPB_CS0 IOMUX_PAD(0x69c, 0x238, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA0__USB_TOP_USBOTG_DATA_6 IOMUX_PAD(0x69c, 0x238, 4, 0x9bc, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA0__GPIO1_8 IOMUX_PAD(0x69c, 0x238, 5, 0x860, 2, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA0__ARM11P_TOP_TRACE_23 IOMUX_PAD(0x69c, 0x238, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD1_DATA1__ESDHC1_DAT1 IOMUX_PAD(0x6a0, 0x23c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA1__MSHC_DATA_1 IOMUX_PAD(0x6a0, 0x23c, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA1__IPU_DISPB_PAR_RS IOMUX_PAD(0x6a0, 0x23c, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA1__USB_TOP_USBOTG_DATA_0 IOMUX_PAD(0x6a0, 0x23c, 4, 0x9a4, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA1__GPIO1_9 IOMUX_PAD(0x6a0, 0x23c, 5, 0x864, 1, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA1__ARM11P_TOP_TRACE_24 IOMUX_PAD(0x6a0, 0x23c, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD1_DATA2__ESDHC1_DAT2 IOMUX_PAD(0x6a4, 0x240, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA2__MSHC_DATA_2 IOMUX_PAD(0x6a4, 0x240, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA2__IPU_DISPB_WR IOMUX_PAD(0x6a4, 0x240, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA2__USB_TOP_USBOTG_DATA_1 IOMUX_PAD(0x6a4, 0x240, 4, 0x9a8, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA2__GPIO1_10 IOMUX_PAD(0x6a4, 0x240, 5, 0x830, 1, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA2__ARM11P_TOP_TRACE_25 IOMUX_PAD(0x6a4, 0x240, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD1_DATA3__ESDHC1_DAT3 IOMUX_PAD(0x6a8, 0x244, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA3__MSHC_DATA_3 IOMUX_PAD(0x6a8, 0x244, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA3__IPU_DISPB_RD IOMUX_PAD(0x6a8, 0x244, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA3__USB_TOP_USBOTG_DATA_2 IOMUX_PAD(0x6a8, 0x244, 4, 0x9ac, 0, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA3__GPIO1_11 IOMUX_PAD(0x6a8, 0x244, 5, 0x834, 1, NO_PAD_CTRL) -#define MX35_PAD_SD1_DATA3__ARM11P_TOP_TRACE_26 IOMUX_PAD(0x6a8, 0x244, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD2_CMD__ESDHC2_CMD IOMUX_PAD(0x6ac, 0x248, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_CMD__I2C3_SCL IOMUX_PAD(0x6ac, 0x248, 1, 0x91c, 2, NO_PAD_CTRL) -#define MX35_PAD_SD2_CMD__ESDHC1_DAT4 IOMUX_PAD(0x6ac, 0x248, 2, 0x804, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_CMD__IPU_CSI_D_2 IOMUX_PAD(0x6ac, 0x248, 3, 0x938, 2, NO_PAD_CTRL) -#define MX35_PAD_SD2_CMD__USB_TOP_USBH2_DATA_4 IOMUX_PAD(0x6ac, 0x248, 4, 0x9dc, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_CMD__GPIO2_0 IOMUX_PAD(0x6ac, 0x248, 5, 0x868, 2, NO_PAD_CTRL) -#define MX35_PAD_SD2_CMD__SPDIF_SPDIF_OUT1 IOMUX_PAD(0x6ac, 0x248, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_CMD__IPU_DISPB_D12_VSYNC IOMUX_PAD(0x6ac, 0x248, 7, 0x928, 3, NO_PAD_CTRL) - -#define MX35_PAD_SD2_CLK__ESDHC2_CLK IOMUX_PAD(0x6b0, 0x24c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_CLK__I2C3_SDA IOMUX_PAD(0x6b0, 0x24c, 1, 0x920, 2, NO_PAD_CTRL) -#define MX35_PAD_SD2_CLK__ESDHC1_DAT5 IOMUX_PAD(0x6b0, 0x24c, 2, 0x808, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_CLK__IPU_CSI_D_3 IOMUX_PAD(0x6b0, 0x24c, 3, 0x93c, 2, NO_PAD_CTRL) -#define MX35_PAD_SD2_CLK__USB_TOP_USBH2_DATA_5 IOMUX_PAD(0x6b0, 0x24c, 4, 0x9e0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_CLK__GPIO2_1 IOMUX_PAD(0x6b0, 0x24c, 5, 0x894, 1, NO_PAD_CTRL) -#define MX35_PAD_SD2_CLK__SPDIF_SPDIF_IN1 IOMUX_PAD(0x6b0, 0x24c, 6, 0x998, 2, NO_PAD_CTRL) -#define MX35_PAD_SD2_CLK__IPU_DISPB_CS2 IOMUX_PAD(0x6b0, 0x24c, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_SD2_DATA0__ESDHC2_DAT0 IOMUX_PAD(0x6b4, 0x250, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA0__UART3_RXD_MUX IOMUX_PAD(0x6b4, 0x250, 1, 0x9a0, 1, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA0__ESDHC1_DAT6 IOMUX_PAD(0x6b4, 0x250, 2, 0x80c, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA0__IPU_CSI_D_4 IOMUX_PAD(0x6b4, 0x250, 3, 0x940, 1, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA0__USB_TOP_USBH2_DATA_6 IOMUX_PAD(0x6b4, 0x250, 4, 0x9e4, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA0__GPIO2_2 IOMUX_PAD(0x6b4, 0x250, 5, 0x8c0, 1, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA0__SPDIF_SPDIF_EXTCLK IOMUX_PAD(0x6b4, 0x250, 6, 0x994, 3, NO_PAD_CTRL) - -#define MX35_PAD_SD2_DATA1__ESDHC2_DAT1 IOMUX_PAD(0x6b8, 0x254, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA1__UART3_TXD_MUX IOMUX_PAD(0x6b8, 0x254, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA1__ESDHC1_DAT7 IOMUX_PAD(0x6b8, 0x254, 2, 0x810, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA1__IPU_CSI_D_5 IOMUX_PAD(0x6b8, 0x254, 3, 0x944, 1, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA1__USB_TOP_USBH2_DATA_0 IOMUX_PAD(0x6b8, 0x254, 4, 0x9cc, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA1__GPIO2_3 IOMUX_PAD(0x6b8, 0x254, 5, 0x8cc, 1, NO_PAD_CTRL) - -#define MX35_PAD_SD2_DATA2__ESDHC2_DAT2 IOMUX_PAD(0x6bc, 0x258, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA2__UART3_RTS IOMUX_PAD(0x6bc, 0x258, 1, 0x99c, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA2__CAN1_RXCAN IOMUX_PAD(0x6bc, 0x258, 2, 0x7c8, 1, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA2__IPU_CSI_D_6 IOMUX_PAD(0x6bc, 0x258, 3, 0x948, 1, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA2__USB_TOP_USBH2_DATA_1 IOMUX_PAD(0x6bc, 0x258, 4, 0x9d0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA2__GPIO2_4 IOMUX_PAD(0x6bc, 0x258, 5, 0x8d0, 1, NO_PAD_CTRL) - -#define MX35_PAD_SD2_DATA3__ESDHC2_DAT3 IOMUX_PAD(0x6c0, 0x25c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA3__UART3_CTS IOMUX_PAD(0x6c0, 0x25c, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA3__CAN1_TXCAN IOMUX_PAD(0x6c0, 0x25c, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA3__IPU_CSI_D_7 IOMUX_PAD(0x6c0, 0x25c, 3, 0x94c, 1, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA3__USB_TOP_USBH2_DATA_2 IOMUX_PAD(0x6c0, 0x25c, 4, 0x9d4, 0, NO_PAD_CTRL) -#define MX35_PAD_SD2_DATA3__GPIO2_5 IOMUX_PAD(0x6c0, 0x25c, 5, 0x8d4, 1, NO_PAD_CTRL) - -#define MX35_PAD_ATA_CS0__ATA_CS0 IOMUX_PAD(0x6c4, 0x260, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_CS0__CSPI1_SS3 IOMUX_PAD(0x6c4, 0x260, 1, 0x7dc, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_CS0__IPU_DISPB_CS1 IOMUX_PAD(0x6c4, 0x260, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_CS0__GPIO2_6 IOMUX_PAD(0x6c4, 0x260, 5, 0x8d8, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_CS0__IPU_DIAGB_0 IOMUX_PAD(0x6c4, 0x260, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_CS0__ARM11P_TOP_MAX1_HMASTER_0 IOMUX_PAD(0x6c4, 0x260, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_CS1__ATA_CS1 IOMUX_PAD(0x6c8, 0x264, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_CS1__IPU_DISPB_CS2 IOMUX_PAD(0x6c8, 0x264, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_CS1__CSPI2_SS0 IOMUX_PAD(0x6c8, 0x264, 4, 0x7f0, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_CS1__GPIO2_7 IOMUX_PAD(0x6c8, 0x264, 5, 0x8dc, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_CS1__IPU_DIAGB_1 IOMUX_PAD(0x6c8, 0x264, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_CS1__ARM11P_TOP_MAX1_HMASTER_1 IOMUX_PAD(0x6c8, 0x264, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DIOR__ATA_DIOR IOMUX_PAD(0x6cc, 0x268, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOR__ESDHC3_DAT0 IOMUX_PAD(0x6cc, 0x268, 1, 0x81c, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOR__USB_TOP_USBOTG_DIR IOMUX_PAD(0x6cc, 0x268, 2, 0x9c4, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOR__IPU_DISPB_BE0 IOMUX_PAD(0x6cc, 0x268, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOR__CSPI2_SS1 IOMUX_PAD(0x6cc, 0x268, 4, 0x7f4, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOR__GPIO2_8 IOMUX_PAD(0x6cc, 0x268, 5, 0x8e0, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOR__IPU_DIAGB_2 IOMUX_PAD(0x6cc, 0x268, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOR__ARM11P_TOP_MAX1_HMASTER_2 IOMUX_PAD(0x6cc, 0x268, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DIOW__ATA_DIOW IOMUX_PAD(0x6d0, 0x26c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOW__ESDHC3_DAT1 IOMUX_PAD(0x6d0, 0x26c, 1, 0x820, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOW__USB_TOP_USBOTG_STP IOMUX_PAD(0x6d0, 0x26c, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOW__IPU_DISPB_BE1 IOMUX_PAD(0x6d0, 0x26c, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOW__CSPI2_MOSI IOMUX_PAD(0x6d0, 0x26c, 4, 0x7ec, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOW__GPIO2_9 IOMUX_PAD(0x6d0, 0x26c, 5, 0x8e4, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOW__IPU_DIAGB_3 IOMUX_PAD(0x6d0, 0x26c, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DIOW__ARM11P_TOP_MAX1_HMASTER_3 IOMUX_PAD(0x6d0, 0x26c, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DMACK__ATA_DMACK IOMUX_PAD(0x6d4, 0x270, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DMACK__ESDHC3_DAT2 IOMUX_PAD(0x6d4, 0x270, 1, 0x824, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DMACK__USB_TOP_USBOTG_NXT IOMUX_PAD(0x6d4, 0x270, 2, 0x9c8, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DMACK__CSPI2_MISO IOMUX_PAD(0x6d4, 0x270, 4, 0x7e8, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DMACK__GPIO2_10 IOMUX_PAD(0x6d4, 0x270, 5, 0x86c, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DMACK__IPU_DIAGB_4 IOMUX_PAD(0x6d4, 0x270, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DMACK__ARM11P_TOP_MAX0_HMASTER_0 IOMUX_PAD(0x6d4, 0x270, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_RESET_B__ATA_RESET_B IOMUX_PAD(0x6d8, 0x274, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_RESET_B__ESDHC3_DAT3 IOMUX_PAD(0x6d8, 0x274, 1, 0x828, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_RESET_B__USB_TOP_USBOTG_DATA_0 IOMUX_PAD(0x6d8, 0x274, 2, 0x9a4, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_RESET_B__IPU_DISPB_SD_D_O IOMUX_PAD(0x6d8, 0x274, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_RESET_B__CSPI2_RDY IOMUX_PAD(0x6d8, 0x274, 4, 0x7e4, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_RESET_B__GPIO2_11 IOMUX_PAD(0x6d8, 0x274, 5, 0x870, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_RESET_B__IPU_DIAGB_5 IOMUX_PAD(0x6d8, 0x274, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_RESET_B__ARM11P_TOP_MAX0_HMASTER_1 IOMUX_PAD(0x6d8, 0x274, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_IORDY__ATA_IORDY IOMUX_PAD(0x6dc, 0x278, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_IORDY__ESDHC3_DAT4 IOMUX_PAD(0x6dc, 0x278, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_IORDY__USB_TOP_USBOTG_DATA_1 IOMUX_PAD(0x6dc, 0x278, 2, 0x9a8, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_IORDY__IPU_DISPB_SD_D_IO IOMUX_PAD(0x6dc, 0x278, 3, 0x92c, 3, NO_PAD_CTRL) -#define MX35_PAD_ATA_IORDY__ESDHC2_DAT4 IOMUX_PAD(0x6dc, 0x278, 4, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_IORDY__GPIO2_12 IOMUX_PAD(0x6dc, 0x278, 5, 0x874, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_IORDY__IPU_DIAGB_6 IOMUX_PAD(0x6dc, 0x278, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_IORDY__ARM11P_TOP_MAX0_HMASTER_2 IOMUX_PAD(0x6dc, 0x278, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA0__ATA_DATA_0 IOMUX_PAD(0x6e0, 0x27c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA0__ESDHC3_DAT5 IOMUX_PAD(0x6e0, 0x27c, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA0__USB_TOP_USBOTG_DATA_2 IOMUX_PAD(0x6e0, 0x27c, 2, 0x9ac, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA0__IPU_DISPB_D12_VSYNC IOMUX_PAD(0x6e0, 0x27c, 3, 0x928, 4, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA0__ESDHC2_DAT5 IOMUX_PAD(0x6e0, 0x27c, 4, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA0__GPIO2_13 IOMUX_PAD(0x6e0, 0x27c, 5, 0x878, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA0__IPU_DIAGB_7 IOMUX_PAD(0x6e0, 0x27c, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA0__ARM11P_TOP_MAX0_HMASTER_3 IOMUX_PAD(0x6e0, 0x27c, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA1__ATA_DATA_1 IOMUX_PAD(0x6e4, 0x280, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA1__ESDHC3_DAT6 IOMUX_PAD(0x6e4, 0x280, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA1__USB_TOP_USBOTG_DATA_3 IOMUX_PAD(0x6e4, 0x280, 2, 0x9b0, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA1__IPU_DISPB_SD_CLK IOMUX_PAD(0x6e4, 0x280, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA1__ESDHC2_DAT6 IOMUX_PAD(0x6e4, 0x280, 4, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA1__GPIO2_14 IOMUX_PAD(0x6e4, 0x280, 5, 0x87c, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA1__IPU_DIAGB_8 IOMUX_PAD(0x6e4, 0x280, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA1__ARM11P_TOP_TRACE_27 IOMUX_PAD(0x6e4, 0x280, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA2__ATA_DATA_2 IOMUX_PAD(0x6e8, 0x284, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA2__ESDHC3_DAT7 IOMUX_PAD(0x6e8, 0x284, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA2__USB_TOP_USBOTG_DATA_4 IOMUX_PAD(0x6e8, 0x284, 2, 0x9b4, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA2__IPU_DISPB_SER_RS IOMUX_PAD(0x6e8, 0x284, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA2__ESDHC2_DAT7 IOMUX_PAD(0x6e8, 0x284, 4, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA2__GPIO2_15 IOMUX_PAD(0x6e8, 0x284, 5, 0x880, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA2__IPU_DIAGB_9 IOMUX_PAD(0x6e8, 0x284, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA2__ARM11P_TOP_TRACE_28 IOMUX_PAD(0x6e8, 0x284, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA3__ATA_DATA_3 IOMUX_PAD(0x6ec, 0x288, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA3__ESDHC3_CLK IOMUX_PAD(0x6ec, 0x288, 1, 0x814, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA3__USB_TOP_USBOTG_DATA_5 IOMUX_PAD(0x6ec, 0x288, 2, 0x9b8, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA3__CSPI2_SCLK IOMUX_PAD(0x6ec, 0x288, 4, 0x7e0, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA3__GPIO2_16 IOMUX_PAD(0x6ec, 0x288, 5, 0x884, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA3__IPU_DIAGB_10 IOMUX_PAD(0x6ec, 0x288, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA3__ARM11P_TOP_TRACE_29 IOMUX_PAD(0x6ec, 0x288, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA4__ATA_DATA_4 IOMUX_PAD(0x6f0, 0x28c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA4__ESDHC3_CMD IOMUX_PAD(0x6f0, 0x28c, 1, 0x818, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA4__USB_TOP_USBOTG_DATA_6 IOMUX_PAD(0x6f0, 0x28c, 2, 0x9bc, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA4__GPIO2_17 IOMUX_PAD(0x6f0, 0x28c, 5, 0x888, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA4__IPU_DIAGB_11 IOMUX_PAD(0x6f0, 0x28c, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA4__ARM11P_TOP_TRACE_30 IOMUX_PAD(0x6f0, 0x28c, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA5__ATA_DATA_5 IOMUX_PAD(0x6f4, 0x290, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA5__USB_TOP_USBOTG_DATA_7 IOMUX_PAD(0x6f4, 0x290, 2, 0x9c0, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA5__GPIO2_18 IOMUX_PAD(0x6f4, 0x290, 5, 0x88c, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA5__IPU_DIAGB_12 IOMUX_PAD(0x6f4, 0x290, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA5__ARM11P_TOP_TRACE_31 IOMUX_PAD(0x6f4, 0x290, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA6__ATA_DATA_6 IOMUX_PAD(0x6f8, 0x294, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA6__CAN1_TXCAN IOMUX_PAD(0x6f8, 0x294, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA6__UART1_DTR IOMUX_PAD(0x6f8, 0x294, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA6__AUDMUX_AUD6_TXD IOMUX_PAD(0x6f8, 0x294, 3, 0x7b4, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA6__GPIO2_19 IOMUX_PAD(0x6f8, 0x294, 5, 0x890, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA6__IPU_DIAGB_13 IOMUX_PAD(0x6f8, 0x294, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA7__ATA_DATA_7 IOMUX_PAD(0x6fc, 0x298, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA7__CAN1_RXCAN IOMUX_PAD(0x6fc, 0x298, 1, 0x7c8, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA7__UART1_DSR IOMUX_PAD(0x6fc, 0x298, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA7__AUDMUX_AUD6_RXD IOMUX_PAD(0x6fc, 0x298, 3, 0x7b0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA7__GPIO2_20 IOMUX_PAD(0x6fc, 0x298, 5, 0x898, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA7__IPU_DIAGB_14 IOMUX_PAD(0x6fc, 0x298, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA8__ATA_DATA_8 IOMUX_PAD(0x700, 0x29c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA8__UART3_RTS IOMUX_PAD(0x700, 0x29c, 1, 0x99c, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA8__UART1_RI IOMUX_PAD(0x700, 0x29c, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA8__AUDMUX_AUD6_TXC IOMUX_PAD(0x700, 0x29c, 3, 0x7c0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA8__GPIO2_21 IOMUX_PAD(0x700, 0x29c, 5, 0x89c, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA8__IPU_DIAGB_15 IOMUX_PAD(0x700, 0x29c, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA9__ATA_DATA_9 IOMUX_PAD(0x704, 0x2a0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA9__UART3_CTS IOMUX_PAD(0x704, 0x2a0, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA9__UART1_DCD IOMUX_PAD(0x704, 0x2a0, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA9__AUDMUX_AUD6_TXFS IOMUX_PAD(0x704, 0x2a0, 3, 0x7c4, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA9__GPIO2_22 IOMUX_PAD(0x704, 0x2a0, 5, 0x8a0, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA9__IPU_DIAGB_16 IOMUX_PAD(0x704, 0x2a0, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA10__ATA_DATA_10 IOMUX_PAD(0x708, 0x2a4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA10__UART3_RXD_MUX IOMUX_PAD(0x708, 0x2a4, 1, 0x9a0, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA10__AUDMUX_AUD6_RXC IOMUX_PAD(0x708, 0x2a4, 3, 0x7b8, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA10__GPIO2_23 IOMUX_PAD(0x708, 0x2a4, 5, 0x8a4, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA10__IPU_DIAGB_17 IOMUX_PAD(0x708, 0x2a4, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA11__ATA_DATA_11 IOMUX_PAD(0x70c, 0x2a8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA11__UART3_TXD_MUX IOMUX_PAD(0x70c, 0x2a8, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA11__AUDMUX_AUD6_RXFS IOMUX_PAD(0x70c, 0x2a8, 3, 0x7bc, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA11__GPIO2_24 IOMUX_PAD(0x70c, 0x2a8, 5, 0x8a8, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA11__IPU_DIAGB_18 IOMUX_PAD(0x70c, 0x2a8, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA12__ATA_DATA_12 IOMUX_PAD(0x710, 0x2ac, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA12__I2C3_SCL IOMUX_PAD(0x710, 0x2ac, 1, 0x91c, 3, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA12__GPIO2_25 IOMUX_PAD(0x710, 0x2ac, 5, 0x8ac, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA12__IPU_DIAGB_19 IOMUX_PAD(0x710, 0x2ac, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA13__ATA_DATA_13 IOMUX_PAD(0x714, 0x2b0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA13__I2C3_SDA IOMUX_PAD(0x714, 0x2b0, 1, 0x920, 3, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA13__GPIO2_26 IOMUX_PAD(0x714, 0x2b0, 5, 0x8b0, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA13__IPU_DIAGB_20 IOMUX_PAD(0x714, 0x2b0, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA14__ATA_DATA_14 IOMUX_PAD(0x718, 0x2b4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA14__IPU_CSI_D_0 IOMUX_PAD(0x718, 0x2b4, 1, 0x930, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA14__KPP_ROW_0 IOMUX_PAD(0x718, 0x2b4, 3, 0x970, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA14__GPIO2_27 IOMUX_PAD(0x718, 0x2b4, 5, 0x8b4, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA14__IPU_DIAGB_21 IOMUX_PAD(0x718, 0x2b4, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DATA15__ATA_DATA_15 IOMUX_PAD(0x71c, 0x2b8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA15__IPU_CSI_D_1 IOMUX_PAD(0x71c, 0x2b8, 1, 0x934, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA15__KPP_ROW_1 IOMUX_PAD(0x71c, 0x2b8, 3, 0x974, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA15__GPIO2_28 IOMUX_PAD(0x71c, 0x2b8, 5, 0x8b8, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DATA15__IPU_DIAGB_22 IOMUX_PAD(0x71c, 0x2b8, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_INTRQ__ATA_INTRQ IOMUX_PAD(0x720, 0x2bc, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_INTRQ__IPU_CSI_D_2 IOMUX_PAD(0x720, 0x2bc, 1, 0x938, 3, NO_PAD_CTRL) -#define MX35_PAD_ATA_INTRQ__KPP_ROW_2 IOMUX_PAD(0x720, 0x2bc, 3, 0x978, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_INTRQ__GPIO2_29 IOMUX_PAD(0x720, 0x2bc, 5, 0x8bc, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_INTRQ__IPU_DIAGB_23 IOMUX_PAD(0x720, 0x2bc, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_BUFF_EN__ATA_BUFFER_EN IOMUX_PAD(0x724, 0x2c0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_BUFF_EN__IPU_CSI_D_3 IOMUX_PAD(0x724, 0x2c0, 1, 0x93c, 3, NO_PAD_CTRL) -#define MX35_PAD_ATA_BUFF_EN__KPP_ROW_3 IOMUX_PAD(0x724, 0x2c0, 3, 0x97c, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_BUFF_EN__GPIO2_30 IOMUX_PAD(0x724, 0x2c0, 5, 0x8c4, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_BUFF_EN__IPU_DIAGB_24 IOMUX_PAD(0x724, 0x2c0, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DMARQ__ATA_DMARQ IOMUX_PAD(0x728, 0x2c4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DMARQ__IPU_CSI_D_4 IOMUX_PAD(0x728, 0x2c4, 1, 0x940, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DMARQ__KPP_COL_0 IOMUX_PAD(0x728, 0x2c4, 3, 0x950, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DMARQ__GPIO2_31 IOMUX_PAD(0x728, 0x2c4, 5, 0x8c8, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DMARQ__IPU_DIAGB_25 IOMUX_PAD(0x728, 0x2c4, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DMARQ__ECT_CTI_TRIG_IN1_4 IOMUX_PAD(0x728, 0x2c4, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DA0__ATA_DA_0 IOMUX_PAD(0x72c, 0x2c8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA0__IPU_CSI_D_5 IOMUX_PAD(0x72c, 0x2c8, 1, 0x944, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA0__KPP_COL_1 IOMUX_PAD(0x72c, 0x2c8, 3, 0x954, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA0__GPIO3_0 IOMUX_PAD(0x72c, 0x2c8, 5, 0x8e8, 1, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA0__IPU_DIAGB_26 IOMUX_PAD(0x72c, 0x2c8, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA0__ECT_CTI_TRIG_IN1_5 IOMUX_PAD(0x72c, 0x2c8, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DA1__ATA_DA_1 IOMUX_PAD(0x730, 0x2cc, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA1__IPU_CSI_D_6 IOMUX_PAD(0x730, 0x2cc, 1, 0x948, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA1__KPP_COL_2 IOMUX_PAD(0x730, 0x2cc, 3, 0x958, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA1__GPIO3_1 IOMUX_PAD(0x730, 0x2cc, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA1__IPU_DIAGB_27 IOMUX_PAD(0x730, 0x2cc, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA1__ECT_CTI_TRIG_IN1_6 IOMUX_PAD(0x730, 0x2cc, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_ATA_DA2__ATA_DA_2 IOMUX_PAD(0x734, 0x2d0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA2__IPU_CSI_D_7 IOMUX_PAD(0x734, 0x2d0, 1, 0x94c, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA2__KPP_COL_3 IOMUX_PAD(0x734, 0x2d0, 3, 0x95c, 2, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA2__GPIO3_2 IOMUX_PAD(0x734, 0x2d0, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA2__IPU_DIAGB_28 IOMUX_PAD(0x734, 0x2d0, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_ATA_DA2__ECT_CTI_TRIG_IN1_7 IOMUX_PAD(0x734, 0x2d0, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_MLB_CLK__MLB_MLBCLK IOMUX_PAD(0x738, 0x2d4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_MLB_CLK__GPIO3_3 IOMUX_PAD(0x738, 0x2d4, 5, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_MLB_DAT__MLB_MLBDAT IOMUX_PAD(0x73c, 0x2d8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_MLB_DAT__GPIO3_4 IOMUX_PAD(0x73c, 0x2d8, 5, 0x904, 1, NO_PAD_CTRL) - -#define MX35_PAD_MLB_SIG__MLB_MLBSIG IOMUX_PAD(0x740, 0x2dc, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_MLB_SIG__GPIO3_5 IOMUX_PAD(0x740, 0x2dc, 5, 0x908, 1, NO_PAD_CTRL) - -#define MX35_PAD_FEC_TX_CLK__FEC_TX_CLK IOMUX_PAD(0x744, 0x2e0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_CLK__ESDHC1_DAT4 IOMUX_PAD(0x744, 0x2e0, 1, 0x804, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_CLK__UART3_RXD_MUX IOMUX_PAD(0x744, 0x2e0, 2, 0x9a0, 3, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_CLK__USB_TOP_USBH2_DIR IOMUX_PAD(0x744, 0x2e0, 3, 0x9ec, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_CLK__CSPI2_MOSI IOMUX_PAD(0x744, 0x2e0, 4, 0x7ec, 3, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_CLK__GPIO3_6 IOMUX_PAD(0x744, 0x2e0, 5, 0x90c, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_CLK__IPU_DISPB_D12_VSYNC IOMUX_PAD(0x744, 0x2e0, 6, 0x928, 5, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_CLK__ARM11P_TOP_EVNTBUS_0 IOMUX_PAD(0x744, 0x2e0, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_RX_CLK__FEC_RX_CLK IOMUX_PAD(0x748, 0x2e4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_CLK__ESDHC1_DAT5 IOMUX_PAD(0x748, 0x2e4, 1, 0x808, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_CLK__UART3_TXD_MUX IOMUX_PAD(0x748, 0x2e4, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_CLK__USB_TOP_USBH2_STP IOMUX_PAD(0x748, 0x2e4, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_CLK__CSPI2_MISO IOMUX_PAD(0x748, 0x2e4, 4, 0x7e8, 3, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_CLK__GPIO3_7 IOMUX_PAD(0x748, 0x2e4, 5, 0x910, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_CLK__IPU_DISPB_SD_D_I IOMUX_PAD(0x748, 0x2e4, 6, 0x92c, 4, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_CLK__ARM11P_TOP_EVNTBUS_1 IOMUX_PAD(0x748, 0x2e4, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_RX_DV__FEC_RX_DV IOMUX_PAD(0x74c, 0x2e8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_DV__ESDHC1_DAT6 IOMUX_PAD(0x74c, 0x2e8, 1, 0x80c, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_DV__UART3_RTS IOMUX_PAD(0x74c, 0x2e8, 2, 0x99c, 2, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_DV__USB_TOP_USBH2_NXT IOMUX_PAD(0x74c, 0x2e8, 3, 0x9f0, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_DV__CSPI2_SCLK IOMUX_PAD(0x74c, 0x2e8, 4, 0x7e0, 3, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_DV__GPIO3_8 IOMUX_PAD(0x74c, 0x2e8, 5, 0x914, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_DV__IPU_DISPB_SD_CLK IOMUX_PAD(0x74c, 0x2e8, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_DV__ARM11P_TOP_EVNTBUS_2 IOMUX_PAD(0x74c, 0x2e8, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_COL__FEC_COL IOMUX_PAD(0x750, 0x2ec, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_COL__ESDHC1_DAT7 IOMUX_PAD(0x750, 0x2ec, 1, 0x810, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_COL__UART3_CTS IOMUX_PAD(0x750, 0x2ec, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_COL__USB_TOP_USBH2_DATA_0 IOMUX_PAD(0x750, 0x2ec, 3, 0x9cc, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_COL__CSPI2_RDY IOMUX_PAD(0x750, 0x2ec, 4, 0x7e4, 3, NO_PAD_CTRL) -#define MX35_PAD_FEC_COL__GPIO3_9 IOMUX_PAD(0x750, 0x2ec, 5, 0x918, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_COL__IPU_DISPB_SER_RS IOMUX_PAD(0x750, 0x2ec, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_COL__ARM11P_TOP_EVNTBUS_3 IOMUX_PAD(0x750, 0x2ec, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_RDATA0__FEC_RDATA_0 IOMUX_PAD(0x754, 0x2f0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA0__PWM_PWMO IOMUX_PAD(0x754, 0x2f0, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA0__UART3_DTR IOMUX_PAD(0x754, 0x2f0, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA0__USB_TOP_USBH2_DATA_1 IOMUX_PAD(0x754, 0x2f0, 3, 0x9d0, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA0__CSPI2_SS0 IOMUX_PAD(0x754, 0x2f0, 4, 0x7f0, 2, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA0__GPIO3_10 IOMUX_PAD(0x754, 0x2f0, 5, 0x8ec, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA0__IPU_DISPB_CS1 IOMUX_PAD(0x754, 0x2f0, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA0__ARM11P_TOP_EVNTBUS_4 IOMUX_PAD(0x754, 0x2f0, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_TDATA0__FEC_TDATA_0 IOMUX_PAD(0x758, 0x2f4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA0__SPDIF_SPDIF_OUT1 IOMUX_PAD(0x758, 0x2f4, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA0__UART3_DSR IOMUX_PAD(0x758, 0x2f4, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA0__USB_TOP_USBH2_DATA_2 IOMUX_PAD(0x758, 0x2f4, 3, 0x9d4, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA0__CSPI2_SS1 IOMUX_PAD(0x758, 0x2f4, 4, 0x7f4, 2, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA0__GPIO3_11 IOMUX_PAD(0x758, 0x2f4, 5, 0x8f0, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA0__IPU_DISPB_CS0 IOMUX_PAD(0x758, 0x2f4, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA0__ARM11P_TOP_EVNTBUS_5 IOMUX_PAD(0x758, 0x2f4, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_TX_EN__FEC_TX_EN IOMUX_PAD(0x75c, 0x2f8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_EN__SPDIF_SPDIF_IN1 IOMUX_PAD(0x75c, 0x2f8, 1, 0x998, 3, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_EN__UART3_RI IOMUX_PAD(0x75c, 0x2f8, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_EN__USB_TOP_USBH2_DATA_3 IOMUX_PAD(0x75c, 0x2f8, 3, 0x9d8, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_EN__GPIO3_12 IOMUX_PAD(0x75c, 0x2f8, 5, 0x8f4, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_EN__IPU_DISPB_PAR_RS IOMUX_PAD(0x75c, 0x2f8, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_EN__ARM11P_TOP_EVNTBUS_6 IOMUX_PAD(0x75c, 0x2f8, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x760, 0x2fc, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_MDC__CAN2_TXCAN IOMUX_PAD(0x760, 0x2fc, 1, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_MDC__UART3_DCD IOMUX_PAD(0x760, 0x2fc, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_MDC__USB_TOP_USBH2_DATA_4 IOMUX_PAD(0x760, 0x2fc, 3, 0x9dc, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_MDC__GPIO3_13 IOMUX_PAD(0x760, 0x2fc, 5, 0x8f8, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_MDC__IPU_DISPB_WR IOMUX_PAD(0x760, 0x2fc, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_MDC__ARM11P_TOP_EVNTBUS_7 IOMUX_PAD(0x760, 0x2fc, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_MDIO__FEC_MDIO IOMUX_PAD(0x764, 0x300, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_MDIO__CAN2_RXCAN IOMUX_PAD(0x764, 0x300, 1, 0x7cc, 2, NO_PAD_CTRL) -#define MX35_PAD_FEC_MDIO__USB_TOP_USBH2_DATA_5 IOMUX_PAD(0x764, 0x300, 3, 0x9e0, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_MDIO__GPIO3_14 IOMUX_PAD(0x764, 0x300, 5, 0x8fc, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_MDIO__IPU_DISPB_RD IOMUX_PAD(0x764, 0x300, 6, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_MDIO__ARM11P_TOP_EVNTBUS_8 IOMUX_PAD(0x764, 0x300, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_TX_ERR__FEC_TX_ERR IOMUX_PAD(0x768, 0x304, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_ERR__OWIRE_LINE IOMUX_PAD(0x768, 0x304, 1, 0x990, 2, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_ERR__SPDIF_SPDIF_EXTCLK IOMUX_PAD(0x768, 0x304, 2, 0x994, 4, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_ERR__USB_TOP_USBH2_DATA_6 IOMUX_PAD(0x768, 0x304, 3, 0x9e4, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_ERR__GPIO3_15 IOMUX_PAD(0x768, 0x304, 5, 0x900, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_ERR__IPU_DISPB_D0_VSYNC IOMUX_PAD(0x768, 0x304, 6, 0x924, 3, NO_PAD_CTRL) -#define MX35_PAD_FEC_TX_ERR__ARM11P_TOP_EVNTBUS_9 IOMUX_PAD(0x768, 0x304, 7, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_RX_ERR__FEC_RX_ERR IOMUX_PAD(0x76c, 0x308, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_ERR__IPU_CSI_D_0 IOMUX_PAD(0x76c, 0x308, 1, 0x930, 3, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_ERR__USB_TOP_USBH2_DATA_7 IOMUX_PAD(0x76c, 0x308, 3, 0x9e8, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_ERR__KPP_COL_4 IOMUX_PAD(0x76c, 0x308, 4, 0x960, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_ERR__GPIO3_16 IOMUX_PAD(0x76c, 0x308, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RX_ERR__IPU_DISPB_SD_D_IO IOMUX_PAD(0x76c, 0x308, 6, 0x92c, 5, NO_PAD_CTRL) - -#define MX35_PAD_FEC_CRS__FEC_CRS IOMUX_PAD(0x770, 0x30c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_CRS__IPU_CSI_D_1 IOMUX_PAD(0x770, 0x30c, 1, 0x934, 3, NO_PAD_CTRL) -#define MX35_PAD_FEC_CRS__USB_TOP_USBH2_PWR IOMUX_PAD(0x770, 0x30c, 3, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_CRS__KPP_COL_5 IOMUX_PAD(0x770, 0x30c, 4, 0x964, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_CRS__GPIO3_17 IOMUX_PAD(0x770, 0x30c, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_CRS__IPU_FLASH_STROBE IOMUX_PAD(0x770, 0x30c, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_RDATA1__FEC_RDATA_1 IOMUX_PAD(0x774, 0x310, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA1__IPU_CSI_D_2 IOMUX_PAD(0x774, 0x310, 1, 0x938, 4, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA1__AUDMUX_AUD6_RXC IOMUX_PAD(0x774, 0x310, 2, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA1__USB_TOP_USBH2_OC IOMUX_PAD(0x774, 0x310, 3, 0x9f4, 2, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA1__KPP_COL_6 IOMUX_PAD(0x774, 0x310, 4, 0x968, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA1__GPIO3_18 IOMUX_PAD(0x774, 0x310, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA1__IPU_DISPB_BE0 IOMUX_PAD(0x774, 0x310, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_TDATA1__FEC_TDATA_1 IOMUX_PAD(0x778, 0x314, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA1__IPU_CSI_D_3 IOMUX_PAD(0x778, 0x314, 1, 0x93c, 4, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA1__AUDMUX_AUD6_RXFS IOMUX_PAD(0x778, 0x314, 2, 0x7bc, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA1__KPP_COL_7 IOMUX_PAD(0x778, 0x314, 4, 0x96c, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA1__GPIO3_19 IOMUX_PAD(0x778, 0x314, 5, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA1__IPU_DISPB_BE1 IOMUX_PAD(0x778, 0x314, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_RDATA2__FEC_RDATA_2 IOMUX_PAD(0x77c, 0x318, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA2__IPU_CSI_D_4 IOMUX_PAD(0x77c, 0x318, 1, 0x940, 3, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA2__AUDMUX_AUD6_TXD IOMUX_PAD(0x77c, 0x318, 2, 0x7b4, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA2__KPP_ROW_4 IOMUX_PAD(0x77c, 0x318, 4, 0x980, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA2__GPIO3_20 IOMUX_PAD(0x77c, 0x318, 5, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_TDATA2__FEC_TDATA_2 IOMUX_PAD(0x780, 0x31c, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA2__IPU_CSI_D_5 IOMUX_PAD(0x780, 0x31c, 1, 0x944, 3, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA2__AUDMUX_AUD6_RXD IOMUX_PAD(0x780, 0x31c, 2, 0x7b0, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA2__KPP_ROW_5 IOMUX_PAD(0x780, 0x31c, 4, 0x984, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA2__GPIO3_21 IOMUX_PAD(0x780, 0x31c, 5, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_RDATA3__FEC_RDATA_3 IOMUX_PAD(0x784, 0x320, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA3__IPU_CSI_D_6 IOMUX_PAD(0x784, 0x320, 1, 0x948, 3, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA3__AUDMUX_AUD6_TXC IOMUX_PAD(0x784, 0x320, 2, 0x7c0, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA3__KPP_ROW_6 IOMUX_PAD(0x784, 0x320, 4, 0x988, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_RDATA3__GPIO3_22 IOMUX_PAD(0x784, 0x320, 6, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_FEC_TDATA3__FEC_TDATA_3 IOMUX_PAD(0x788, 0x324, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA3__IPU_CSI_D_7 IOMUX_PAD(0x788, 0x324, 1, 0x94c, 3, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA3__AUDMUX_AUD6_TXFS IOMUX_PAD(0x788, 0x324, 2, 0x7c4, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA3__KPP_ROW_7 IOMUX_PAD(0x788, 0x324, 4, 0x98c, 1, NO_PAD_CTRL) -#define MX35_PAD_FEC_TDATA3__GPIO3_23 IOMUX_PAD(0x788, 0x324, 5, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_EXT_ARMCLK__CCM_EXT_ARMCLK IOMUX_PAD(0x78c, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - -#define MX35_PAD_TEST_MODE__TCU_TEST_MODE IOMUX_PAD(0x790, 0x0, 0, 0x0, 0, NO_PAD_CTRL) - - -#endif /* __MACH_IOMUX_MX35_H__ */ diff --git a/arch/arm/mach-imx/iomux-v1.c b/arch/arm/mach-imx/iomux-v1.c deleted file mode 100644 index a4bec3b9b2b3..000000000000 --- a/arch/arm/mach-imx/iomux-v1.c +++ /dev/null @@ -1,174 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * arch/arm/plat-mxc/iomux-v1.c - * - * Copyright (C) 2004 Sascha Hauer, Synertronixx GmbH - * Copyright (C) 2009 Uwe Kleine-Koenig, Pengutronix - * - * Common code for i.MX1, i.MX21 and i.MX27 - */ - -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/gpio.h> - -#include <asm/mach/map.h> - -#include "hardware.h" -#include "iomux-v1.h" - -static void __iomem *imx_iomuxv1_baseaddr; -static unsigned imx_iomuxv1_numports; - -static inline unsigned long imx_iomuxv1_readl(unsigned offset) -{ - return imx_readl(imx_iomuxv1_baseaddr + offset); -} - -static inline void imx_iomuxv1_writel(unsigned long val, unsigned offset) -{ - imx_writel(val, imx_iomuxv1_baseaddr + offset); -} - -static inline void imx_iomuxv1_rmwl(unsigned offset, - unsigned long mask, unsigned long value) -{ - unsigned long reg = imx_iomuxv1_readl(offset); - - reg &= ~mask; - reg |= value; - - imx_iomuxv1_writel(reg, offset); -} - -static inline void imx_iomuxv1_set_puen( - unsigned int port, unsigned int pin, int on) -{ - unsigned long mask = 1 << pin; - - imx_iomuxv1_rmwl(MXC_PUEN(port), mask, on ? mask : 0); -} - -static inline void imx_iomuxv1_set_ddir( - unsigned int port, unsigned int pin, int out) -{ - unsigned long mask = 1 << pin; - - imx_iomuxv1_rmwl(MXC_DDIR(port), mask, out ? mask : 0); -} - -static inline void imx_iomuxv1_set_gpr( - unsigned int port, unsigned int pin, int af) -{ - unsigned long mask = 1 << pin; - - imx_iomuxv1_rmwl(MXC_GPR(port), mask, af ? mask : 0); -} - -static inline void imx_iomuxv1_set_gius( - unsigned int port, unsigned int pin, int inuse) -{ - unsigned long mask = 1 << pin; - - imx_iomuxv1_rmwl(MXC_GIUS(port), mask, inuse ? mask : 0); -} - -static inline void imx_iomuxv1_set_ocr( - unsigned int port, unsigned int pin, unsigned int ocr) -{ - unsigned long shift = (pin & 0xf) << 1; - unsigned long mask = 3 << shift; - unsigned long value = ocr << shift; - unsigned long offset = pin < 16 ? MXC_OCR1(port) : MXC_OCR2(port); - - imx_iomuxv1_rmwl(offset, mask, value); -} - -static inline void imx_iomuxv1_set_iconfa( - unsigned int port, unsigned int pin, unsigned int aout) -{ - unsigned long shift = (pin & 0xf) << 1; - unsigned long mask = 3 << shift; - unsigned long value = aout << shift; - unsigned long offset = pin < 16 ? MXC_ICONFA1(port) : MXC_ICONFA2(port); - - imx_iomuxv1_rmwl(offset, mask, value); -} - -static inline void imx_iomuxv1_set_iconfb( - unsigned int port, unsigned int pin, unsigned int bout) -{ - unsigned long shift = (pin & 0xf) << 1; - unsigned long mask = 3 << shift; - unsigned long value = bout << shift; - unsigned long offset = pin < 16 ? MXC_ICONFB1(port) : MXC_ICONFB2(port); - - imx_iomuxv1_rmwl(offset, mask, value); -} - -int mxc_gpio_mode(int gpio_mode) -{ - unsigned int pin = gpio_mode & GPIO_PIN_MASK; - unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; - unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT; - unsigned int aout = (gpio_mode >> GPIO_AOUT_SHIFT) & 3; - unsigned int bout = (gpio_mode >> GPIO_BOUT_SHIFT) & 3; - - if (port >= imx_iomuxv1_numports) - return -EINVAL; - - /* Pullup enable */ - imx_iomuxv1_set_puen(port, pin, gpio_mode & GPIO_PUEN); - - /* Data direction */ - imx_iomuxv1_set_ddir(port, pin, gpio_mode & GPIO_OUT); - - /* Primary / alternate function */ - imx_iomuxv1_set_gpr(port, pin, gpio_mode & GPIO_AF); - - /* use as gpio? */ - imx_iomuxv1_set_gius(port, pin, !(gpio_mode & (GPIO_PF | GPIO_AF))); - - imx_iomuxv1_set_ocr(port, pin, ocr); - - imx_iomuxv1_set_iconfa(port, pin, aout); - - imx_iomuxv1_set_iconfb(port, pin, bout); - - return 0; -} - -static int imx_iomuxv1_setup_multiple(const int *list, unsigned count) -{ - size_t i; - int ret = 0; - - for (i = 0; i < count; ++i) { - ret = mxc_gpio_mode(list[i]); - - if (ret) - return ret; - } - - return ret; -} - -int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, - const char *label) -{ - int ret; - - ret = imx_iomuxv1_setup_multiple(pin_list, count); - return ret; -} - -int __init imx_iomuxv1_init(void __iomem *base, int numports) -{ - imx_iomuxv1_baseaddr = base; - imx_iomuxv1_numports = numports; - - return 0; -} diff --git a/arch/arm/mach-imx/iomux-v1.h b/arch/arm/mach-imx/iomux-v1.h deleted file mode 100644 index b94852970c7f..000000000000 --- a/arch/arm/mach-imx/iomux-v1.h +++ /dev/null @@ -1,81 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> - * Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.de> - */ -#ifndef __MACH_IOMUX_V1_H__ -#define __MACH_IOMUX_V1_H__ - -/* -* GPIO Module and I/O Multiplexer -* x = 0..3 for reg_A, reg_B, reg_C, reg_D -*/ -#define MXC_DDIR(x) (0x00 + ((x) << 8)) -#define MXC_OCR1(x) (0x04 + ((x) << 8)) -#define MXC_OCR2(x) (0x08 + ((x) << 8)) -#define MXC_ICONFA1(x) (0x0c + ((x) << 8)) -#define MXC_ICONFA2(x) (0x10 + ((x) << 8)) -#define MXC_ICONFB1(x) (0x14 + ((x) << 8)) -#define MXC_ICONFB2(x) (0x18 + ((x) << 8)) -#define MXC_DR(x) (0x1c + ((x) << 8)) -#define MXC_GIUS(x) (0x20 + ((x) << 8)) -#define MXC_SSR(x) (0x24 + ((x) << 8)) -#define MXC_ICR1(x) (0x28 + ((x) << 8)) -#define MXC_ICR2(x) (0x2c + ((x) << 8)) -#define MXC_IMR(x) (0x30 + ((x) << 8)) -#define MXC_ISR(x) (0x34 + ((x) << 8)) -#define MXC_GPR(x) (0x38 + ((x) << 8)) -#define MXC_SWR(x) (0x3c + ((x) << 8)) -#define MXC_PUEN(x) (0x40 + ((x) << 8)) - -#define MX1_NUM_GPIO_PORT 4 -#define MX21_NUM_GPIO_PORT 6 -#define MX27_NUM_GPIO_PORT 6 - -#define GPIO_PIN_MASK 0x1f - -#define GPIO_PORT_SHIFT 5 -#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT) - -#define GPIO_PORTA (0 << GPIO_PORT_SHIFT) -#define GPIO_PORTB (1 << GPIO_PORT_SHIFT) -#define GPIO_PORTC (2 << GPIO_PORT_SHIFT) -#define GPIO_PORTD (3 << GPIO_PORT_SHIFT) -#define GPIO_PORTE (4 << GPIO_PORT_SHIFT) -#define GPIO_PORTF (5 << GPIO_PORT_SHIFT) - -#define GPIO_OUT (1 << 8) -#define GPIO_IN (0 << 8) -#define GPIO_PUEN (1 << 9) - -#define GPIO_PF (1 << 10) -#define GPIO_AF (1 << 11) - -#define GPIO_OCR_SHIFT 12 -#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT) -#define GPIO_AIN (0 << GPIO_OCR_SHIFT) -#define GPIO_BIN (1 << GPIO_OCR_SHIFT) -#define GPIO_CIN (2 << GPIO_OCR_SHIFT) -#define GPIO_GPIO (3 << GPIO_OCR_SHIFT) - -#define GPIO_AOUT_SHIFT 14 -#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT) - -#define GPIO_BOUT_SHIFT 16 -#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT) - -extern int mxc_gpio_mode(int gpio_mode); -extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, - const char *label); - -extern int imx_iomuxv1_init(void __iomem *base, int numports); - -#endif /* __MACH_IOMUX_V1_H__ */ diff --git a/arch/arm/mach-imx/iomux-v3.c b/arch/arm/mach-imx/iomux-v3.c deleted file mode 100644 index 043cf3c7cacf..000000000000 --- a/arch/arm/mach-imx/iomux-v3.c +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> - * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH, - * <armlinux@phytec.de> - */ -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/gpio.h> - -#include <asm/mach/map.h> - -#include "hardware.h" -#include "iomux-v3.h" - -static void __iomem *base; - -/* - * configures a single pad in the iomuxer - */ -int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad) -{ - u32 mux_ctrl_ofs = (pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT; - u32 mux_mode = (pad & MUX_MODE_MASK) >> MUX_MODE_SHIFT; - u32 sel_input_ofs = (pad & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT; - u32 sel_input = (pad & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT; - u32 pad_ctrl_ofs = (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT; - u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT; - - if (mux_ctrl_ofs) - imx_writel(mux_mode, base + mux_ctrl_ofs); - - if (sel_input_ofs) - imx_writel(sel_input, base + sel_input_ofs); - - if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs) - imx_writel(pad_ctrl, base + pad_ctrl_ofs); - - return 0; -} - -int mxc_iomux_v3_setup_multiple_pads(const iomux_v3_cfg_t *pad_list, - unsigned count) -{ - const iomux_v3_cfg_t *p = pad_list; - int i; - int ret; - - for (i = 0; i < count; i++) { - ret = mxc_iomux_v3_setup_pad(*p); - if (ret) - return ret; - p++; - } - return 0; -} - -void mxc_iomux_v3_init(void __iomem *iomux_v3_base) -{ - base = iomux_v3_base; -} diff --git a/arch/arm/mach-imx/iomux-v3.h b/arch/arm/mach-imx/iomux-v3.h deleted file mode 100644 index 7db8ec926ff1..000000000000 --- a/arch/arm/mach-imx/iomux-v3.h +++ /dev/null @@ -1,130 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH, - * <armlinux@phytec.de> - */ - -#ifndef __MACH_IOMUX_V3_H__ -#define __MACH_IOMUX_V3_H__ - -/* - * build IOMUX_PAD structure - * - * This iomux scheme is based around pads, which are the physical balls - * on the processor. - * - * - Each pad has a pad control register (IOMUXC_SW_PAD_CTRL_x) which controls - * things like driving strength and pullup/pulldown. - * - Each pad can have but not necessarily does have an output routing register - * (IOMUXC_SW_MUX_CTL_PAD_x). - * - Each pad can have but not necessarily does have an input routing register - * (IOMUXC_x_SELECT_INPUT) - * - * The three register sets do not have a fixed offset to each other, - * hence we order this table by pad control registers (which all pads - * have) and put the optional i/o routing registers into additional - * fields. - * - * The naming convention for the pad modes is MX35_PAD_<padname>__<padmode> - * If <padname> or <padmode> refers to a GPIO, it is named - * GPIO_<unit>_<num> - * - * IOMUX/PAD Bit field definitions - * - * MUX_CTRL_OFS: 0..11 (12) - * PAD_CTRL_OFS: 12..23 (12) - * SEL_INPUT_OFS: 24..35 (12) - * MUX_MODE + SION: 36..40 (5) - * PAD_CTRL + NO_PAD_CTRL: 41..57 (17) - * SEL_INP: 58..61 (4) - * reserved: 63 (1) -*/ - -typedef u64 iomux_v3_cfg_t; - -#define MUX_CTRL_OFS_SHIFT 0 -#define MUX_CTRL_OFS_MASK ((iomux_v3_cfg_t)0xfff << MUX_CTRL_OFS_SHIFT) -#define MUX_PAD_CTRL_OFS_SHIFT 12 -#define MUX_PAD_CTRL_OFS_MASK ((iomux_v3_cfg_t)0xfff << MUX_PAD_CTRL_OFS_SHIFT) -#define MUX_SEL_INPUT_OFS_SHIFT 24 -#define MUX_SEL_INPUT_OFS_MASK ((iomux_v3_cfg_t)0xfff << MUX_SEL_INPUT_OFS_SHIFT) - -#define MUX_MODE_SHIFT 36 -#define MUX_MODE_MASK ((iomux_v3_cfg_t)0x1f << MUX_MODE_SHIFT) -#define MUX_PAD_CTRL_SHIFT 41 -#define MUX_PAD_CTRL_MASK ((iomux_v3_cfg_t)0x1ffff << MUX_PAD_CTRL_SHIFT) -#define MUX_SEL_INPUT_SHIFT 58 -#define MUX_SEL_INPUT_MASK ((iomux_v3_cfg_t)0xf << MUX_SEL_INPUT_SHIFT) - -#define MUX_PAD_CTRL(x) ((iomux_v3_cfg_t)(x) << MUX_PAD_CTRL_SHIFT) - -#define IOMUX_PAD(_pad_ctrl_ofs, _mux_ctrl_ofs, _mux_mode, _sel_input_ofs, \ - _sel_input, _pad_ctrl) \ - (((iomux_v3_cfg_t)(_mux_ctrl_ofs) << MUX_CTRL_OFS_SHIFT) | \ - ((iomux_v3_cfg_t)(_mux_mode) << MUX_MODE_SHIFT) | \ - ((iomux_v3_cfg_t)(_pad_ctrl_ofs) << MUX_PAD_CTRL_OFS_SHIFT) | \ - ((iomux_v3_cfg_t)(_pad_ctrl) << MUX_PAD_CTRL_SHIFT) | \ - ((iomux_v3_cfg_t)(_sel_input_ofs) << MUX_SEL_INPUT_OFS_SHIFT) | \ - ((iomux_v3_cfg_t)(_sel_input) << MUX_SEL_INPUT_SHIFT)) - -#define NEW_PAD_CTRL(cfg, pad) (((cfg) & ~MUX_PAD_CTRL_MASK) | MUX_PAD_CTRL(pad)) -/* - * Use to set PAD control - */ - -#define NO_PAD_CTRL (1 << 16) -#define PAD_CTL_DVS (1 << 13) -#define PAD_CTL_HYS (1 << 8) - -#define PAD_CTL_PKE (1 << 7) -#define PAD_CTL_PUE (1 << 6 | PAD_CTL_PKE) -#define PAD_CTL_PUS_100K_DOWN (0 << 4 | PAD_CTL_PUE) -#define PAD_CTL_PUS_47K_UP (1 << 4 | PAD_CTL_PUE) -#define PAD_CTL_PUS_100K_UP (2 << 4 | PAD_CTL_PUE) -#define PAD_CTL_PUS_22K_UP (3 << 4 | PAD_CTL_PUE) - -#define PAD_CTL_ODE (1 << 3) - -#define PAD_CTL_DSE_LOW (0 << 1) -#define PAD_CTL_DSE_MED (1 << 1) -#define PAD_CTL_DSE_HIGH (2 << 1) -#define PAD_CTL_DSE_MAX (3 << 1) - -#define PAD_CTL_SRE_FAST (1 << 0) -#define PAD_CTL_SRE_SLOW (0 << 0) - -#define IOMUX_CONFIG_SION (0x1 << 4) - -#define MX51_NUM_GPIO_PORT 4 - -#define GPIO_PIN_MASK 0x1f - -#define GPIO_PORT_SHIFT 5 -#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT) - -#define GPIO_PORTA (0 << GPIO_PORT_SHIFT) -#define GPIO_PORTB (1 << GPIO_PORT_SHIFT) -#define GPIO_PORTC (2 << GPIO_PORT_SHIFT) -#define GPIO_PORTD (3 << GPIO_PORT_SHIFT) -#define GPIO_PORTE (4 << GPIO_PORT_SHIFT) -#define GPIO_PORTF (5 << GPIO_PORT_SHIFT) - -/* - * setups a single pad in the iomuxer - */ -int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad); - -/* - * setups multiple pads - * convenient way to call the above function with tables - */ -int mxc_iomux_v3_setup_multiple_pads(const iomux_v3_cfg_t *pad_list, - unsigned count); - -/* - * Initialise the iomux controller - */ -void mxc_iomux_v3_init(void __iomem *iomux_v3_base); - -#endif /* __MACH_IOMUX_V3_H__*/ - diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c deleted file mode 100644 index 4d9a56fb6989..000000000000 --- a/arch/arm/mach-imx/mach-armadillo5x0.c +++ /dev/null @@ -1,562 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * armadillo5x0.c - * - * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> - * updates in http://alberdroid.blogspot.com/ - * - * Based on Atmark Techno, Inc. armadillo 500 BSP 2008 - * Based on mx31ads.c and pcm037.c Great Work! - */ - -#include <linux/types.h> -#include <linux/init.h> -#include <linux/clk.h> -#include <linux/platform_device.h> -#include <linux/gpio.h> -#include <linux/smsc911x.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/mtd/physmap.h> -#include <linux/io.h> -#include <linux/input.h> -#include <linux/i2c.h> -#include <linux/usb/otg.h> -#include <linux/usb/ulpi.h> -#include <linux/delay.h> -#include <linux/regulator/machine.h> -#include <linux/regulator/fixed.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/memory.h> -#include <asm/mach/map.h> - -#include "common.h" -#include "devices-imx31.h" -#include "crmregs-imx3.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx3.h" -#include "ulpi.h" - -static int armadillo5x0_pins[] = { - /* UART1 */ - MX31_PIN_CTS1__CTS1, - MX31_PIN_RTS1__RTS1, - MX31_PIN_TXD1__TXD1, - MX31_PIN_RXD1__RXD1, - /* UART2 */ - MX31_PIN_CTS2__CTS2, - MX31_PIN_RTS2__RTS2, - MX31_PIN_TXD2__TXD2, - MX31_PIN_RXD2__RXD2, - /* LAN9118_IRQ */ - IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO), - /* SDHC1 */ - MX31_PIN_SD1_DATA3__SD1_DATA3, - MX31_PIN_SD1_DATA2__SD1_DATA2, - MX31_PIN_SD1_DATA1__SD1_DATA1, - MX31_PIN_SD1_DATA0__SD1_DATA0, - MX31_PIN_SD1_CLK__SD1_CLK, - MX31_PIN_SD1_CMD__SD1_CMD, - /* Framebuffer */ - MX31_PIN_LD0__LD0, - MX31_PIN_LD1__LD1, - MX31_PIN_LD2__LD2, - MX31_PIN_LD3__LD3, - MX31_PIN_LD4__LD4, - MX31_PIN_LD5__LD5, - MX31_PIN_LD6__LD6, - MX31_PIN_LD7__LD7, - MX31_PIN_LD8__LD8, - MX31_PIN_LD9__LD9, - MX31_PIN_LD10__LD10, - MX31_PIN_LD11__LD11, - MX31_PIN_LD12__LD12, - MX31_PIN_LD13__LD13, - MX31_PIN_LD14__LD14, - MX31_PIN_LD15__LD15, - MX31_PIN_LD16__LD16, - MX31_PIN_LD17__LD17, - MX31_PIN_VSYNC3__VSYNC3, - MX31_PIN_HSYNC__HSYNC, - MX31_PIN_FPSHIFT__FPSHIFT, - MX31_PIN_DRDY0__DRDY0, - IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/ - /* I2C2 */ - MX31_PIN_CSPI2_MOSI__SCL, - MX31_PIN_CSPI2_MISO__SDA, - /* OTG */ - MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, - MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, - MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, - MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, - MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, - MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, - MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, - MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, - MX31_PIN_USBOTG_CLK__USBOTG_CLK, - MX31_PIN_USBOTG_DIR__USBOTG_DIR, - MX31_PIN_USBOTG_NXT__USBOTG_NXT, - MX31_PIN_USBOTG_STP__USBOTG_STP, - /* USB host 2 */ - IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC), -}; - -/* USB */ - -#define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4) -#define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6) -#define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3) - -#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ - PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) - -static int usbotg_init(struct platform_device *pdev) -{ - int err; - - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG); - - /* Chip already enabled by hardware */ - /* OTG phy reset*/ - err = gpio_request(OTG_RESET, "USB-OTG-RESET"); - if (err) { - pr_err("Failed to request the usb otg reset gpio\n"); - return err; - } - - err = gpio_direction_output(OTG_RESET, 1/*HIGH*/); - if (err) { - pr_err("Failed to reset the usb otg phy\n"); - goto otg_free_reset; - } - - gpio_set_value(OTG_RESET, 0/*LOW*/); - mdelay(5); - gpio_set_value(OTG_RESET, 1/*HIGH*/); - mdelay(10); - - return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED | - MXC_EHCI_INTERFACE_DIFF_UNI); - -otg_free_reset: - gpio_free(OTG_RESET); - return err; -} - -static int usbh2_init(struct platform_device *pdev) -{ - int err; - - mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG); - - mxc_iomux_set_gpr(MUX_PGP_UH2, true); - - - /* Enable the chip */ - err = gpio_request(USBH2_CS, "USB-H2-CS"); - if (err) { - pr_err("Failed to request the usb host 2 CS gpio\n"); - return err; - } - - err = gpio_direction_output(USBH2_CS, 0/*Enabled*/); - if (err) { - pr_err("Failed to drive the usb host 2 CS gpio\n"); - goto h2_free_cs; - } - - /* H2 phy reset*/ - err = gpio_request(USBH2_RESET, "USB-H2-RESET"); - if (err) { - pr_err("Failed to request the usb host 2 reset gpio\n"); - goto h2_free_cs; - } - - err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/); - if (err) { - pr_err("Failed to reset the usb host 2 phy\n"); - goto h2_free_reset; - } - - gpio_set_value(USBH2_RESET, 0/*LOW*/); - mdelay(5); - gpio_set_value(USBH2_RESET, 1/*HIGH*/); - mdelay(10); - - return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED | - MXC_EHCI_INTERFACE_DIFF_UNI); - -h2_free_reset: - gpio_free(USBH2_RESET); -h2_free_cs: - gpio_free(USBH2_CS); - return err; -} - -static struct mxc_usbh_platform_data usbotg_pdata __initdata = { - .init = usbotg_init, - .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, -}; - -static struct mxc_usbh_platform_data usbh2_pdata __initdata = { - .init = usbh2_init, - .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, -}; - -/* RTC over I2C*/ -#define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4) - -static struct i2c_board_info armadillo5x0_i2c_rtc = { - I2C_BOARD_INFO("s35390a", 0x30), -}; - -/* GPIO BUTTONS */ -static struct gpio_keys_button armadillo5x0_buttons[] = { - { - .code = KEY_ENTER, /*28*/ - .gpio = IOMUX_TO_GPIO(MX31_PIN_SCLK0), - .active_low = 1, - .desc = "menu", - .wakeup = 1, - }, { - .code = KEY_BACK, /*158*/ - .gpio = IOMUX_TO_GPIO(MX31_PIN_SRST0), - .active_low = 1, - .desc = "back", - .wakeup = 1, - } -}; - -static const struct gpio_keys_platform_data - armadillo5x0_button_data __initconst = { - .buttons = armadillo5x0_buttons, - .nbuttons = ARRAY_SIZE(armadillo5x0_buttons), -}; - -/* - * NAND Flash - */ -static const struct mxc_nand_platform_data -armadillo5x0_nand_board_info __initconst = { - .width = 1, - .hw_ecc = 1, -}; - -/* - * MTD NOR Flash - */ -static struct mtd_partition armadillo5x0_nor_flash_partitions[] = { - { - .name = "nor.bootloader", - .offset = 0x00000000, - .size = 4*32*1024, - }, { - .name = "nor.kernel", - .offset = MTDPART_OFS_APPEND, - .size = 16*128*1024, - }, { - .name = "nor.userland", - .offset = MTDPART_OFS_APPEND, - .size = 110*128*1024, - }, { - .name = "nor.config", - .offset = MTDPART_OFS_APPEND, - .size = 1*128*1024, - }, -}; - -static const struct physmap_flash_data - armadillo5x0_nor_flash_pdata __initconst = { - .width = 2, - .parts = armadillo5x0_nor_flash_partitions, - .nr_parts = ARRAY_SIZE(armadillo5x0_nor_flash_partitions), -}; - -static const struct resource armadillo5x0_nor_flash_resource __initconst = { - .flags = IORESOURCE_MEM, - .start = MX31_CS0_BASE_ADDR, - .end = MX31_CS0_BASE_ADDR + SZ_64M - 1, -}; - -/* - * FB support - */ -static const struct fb_videomode fb_modedb[] = { - { /* 640x480 @ 60 Hz */ - .name = "CRT-VGA", - .refresh = 60, - .xres = 640, - .yres = 480, - .pixclock = 39721, - .left_margin = 35, - .right_margin = 115, - .upper_margin = 43, - .lower_margin = 1, - .hsync_len = 10, - .vsync_len = 1, - .sync = FB_SYNC_OE_ACT_HIGH, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, {/* 800x600 @ 56 Hz */ - .name = "CRT-SVGA", - .refresh = 56, - .xres = 800, - .yres = 600, - .pixclock = 30000, - .left_margin = 30, - .right_margin = 108, - .upper_margin = 13, - .lower_margin = 10, - .hsync_len = 10, - .vsync_len = 1, - .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_HOR_HIGH_ACT | - FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, -}; - -static struct mx3fb_platform_data mx3fb_pdata __initdata = { - .name = "CRT-VGA", - .mode = fb_modedb, - .num_modes = ARRAY_SIZE(fb_modedb), -}; - -/* - * SDHC 1 - * MMC support - */ -static int armadillo5x0_sdhc1_get_ro(struct device *dev) -{ - return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B)); -} - -static int armadillo5x0_sdhc1_init(struct device *dev, - irq_handler_t detect_irq, void *data) -{ - int ret; - int gpio_det, gpio_wp; - - gpio_det = IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK); - gpio_wp = IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B); - - ret = gpio_request(gpio_det, "sdhc-card-detect"); - if (ret) - return ret; - - gpio_direction_input(gpio_det); - - ret = gpio_request(gpio_wp, "sdhc-write-protect"); - if (ret) - goto err_gpio_free; - - gpio_direction_input(gpio_wp); - - /* When supported the trigger type have to be BOTH */ - ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK)), - detect_irq, IRQF_TRIGGER_FALLING, - "sdhc-detect", data); - - if (ret) - goto err_gpio_free_2; - - return 0; - -err_gpio_free_2: - gpio_free(gpio_wp); - -err_gpio_free: - gpio_free(gpio_det); - - return ret; - -} - -static void armadillo5x0_sdhc1_exit(struct device *dev, void *data) -{ - free_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK)), data); - gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK)); - gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B)); -} - -static const struct imxmmc_platform_data sdhc_pdata __initconst = { - .get_ro = armadillo5x0_sdhc1_get_ro, - .init = armadillo5x0_sdhc1_init, - .exit = armadillo5x0_sdhc1_exit, -}; - -/* - * SMSC 9118 - * Network support - */ -static struct resource armadillo5x0_smc911x_resources[] = { - { - .start = MX31_CS3_BASE_ADDR, - .end = MX31_CS3_BASE_ADDR + SZ_32M - 1, - .flags = IORESOURCE_MEM, - }, { - /* irq number is run-time assigned */ - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, - }, -}; - -static struct smsc911x_platform_config smsc911x_info = { - .flags = SMSC911X_USE_16BIT, - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, - .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, -}; - -static struct platform_device armadillo5x0_smc911x_device = { - .name = "smsc911x", - .id = -1, - .num_resources = ARRAY_SIZE(armadillo5x0_smc911x_resources), - .resource = armadillo5x0_smc911x_resources, - .dev = { - .platform_data = &smsc911x_info, - }, -}; - -/* UART device data */ -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static struct platform_device *devices[] __initdata = { - &armadillo5x0_smc911x_device, -}; - -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vdd33a", "smsc911x"), - REGULATOR_SUPPLY("vddvario", "smsc911x"), -}; - -/* - * Perform board specific initializations - */ -static void __init armadillo5x0_init(void) -{ - imx31_soc_init(); - - mxc_iomux_setup_multiple_pins(armadillo5x0_pins, - ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0"); - - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - - imx31_add_imx_i2c1(NULL); - - /* Register UART */ - imx31_add_imx_uart0(&uart_pdata); - imx31_add_imx_uart1(&uart_pdata); - - /* Register FB */ - imx31_add_ipu_core(); - imx31_add_mx3_sdc_fb(&mx3fb_pdata); - - /* Register NOR Flash */ - platform_device_register_resndata(NULL, "physmap-flash", -1, - &armadillo5x0_nor_flash_resource, 1, - &armadillo5x0_nor_flash_pdata, - sizeof(armadillo5x0_nor_flash_pdata)); - - /* Register NAND Flash */ - imx31_add_mxc_nand(&armadillo5x0_nand_board_info); - - /* set NAND page size to 2k if not configured via boot mode pins */ - imx_writel(imx_readl(mx3_ccm_base + MXC_CCM_RCSR) | (1 << 30), - mx3_ccm_base + MXC_CCM_RCSR); -} - -static void __init armadillo5x0_late(void) -{ - armadillo5x0_smc911x_resources[1].start = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)); - armadillo5x0_smc911x_resources[1].end = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)); - platform_add_devices(devices, ARRAY_SIZE(devices)); - - imx_add_gpio_keys(&armadillo5x0_button_data); - - /* SMSC9118 IRQ pin */ - gpio_direction_input(MX31_PIN_GPIO1_0); - - /* Register SDHC */ - imx31_add_mxc_mmc(0, &sdhc_pdata); - - /* RTC */ - /* Get RTC IRQ and register the chip */ - if (!gpio_request(ARMADILLO5X0_RTC_GPIO, "rtc")) { - if (!gpio_direction_input(ARMADILLO5X0_RTC_GPIO)) - armadillo5x0_i2c_rtc.irq = - gpio_to_irq(ARMADILLO5X0_RTC_GPIO); - else - gpio_free(ARMADILLO5X0_RTC_GPIO); - } - - if (armadillo5x0_i2c_rtc.irq == 0) - pr_warn("armadillo5x0_init: failed to get RTC IRQ\n"); - i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1); - - /* USB */ - usbotg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | - ULPI_OTG_DRVVBUS_EXT); - if (usbotg_pdata.otg) - imx31_add_mxc_ehci_otg(&usbotg_pdata); - usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | - ULPI_OTG_DRVVBUS_EXT); - if (usbh2_pdata.otg) - imx31_add_mxc_ehci_hs(2, &usbh2_pdata); -} - -static void __init armadillo5x0_timer_init(void) -{ - mx31_clocks_init(26000000); -} - -MACHINE_START(ARMADILLO5X0, "Armadillo-500") - /* Maintainer: Alberto Panizzo */ - .atag_offset = 0x100, - .map_io = mx31_map_io, - .init_early = imx31_init_early, - .init_irq = mx31_init_irq, - .init_time = armadillo5x0_timer_init, - .init_machine = armadillo5x0_init, - .init_late = armadillo5x0_late, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-bug.c b/arch/arm/mach-imx/mach-bug.c deleted file mode 100644 index 3929208600f2..000000000000 --- a/arch/arm/mach-imx/mach-bug.c +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright (C) 2002 Shane Nay (shane@minirl.com) - * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2011 Denis 'GNUtoo' Carikli <GNUtoo@no-log.org> - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/platform_device.h> - -#include <asm/mach/time.h> -#include <asm/mach/arch.h> -#include <asm/mach-types.h> - -#include "common.h" -#include "devices-imx31.h" -#include "hardware.h" -#include "iomux-mx3.h" - -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static const unsigned int bug_pins[] __initconst = { - MX31_PIN_PC_RST__CTS5, - MX31_PIN_PC_VS2__RTS5, - MX31_PIN_PC_BVD2__TXD5, - MX31_PIN_PC_BVD1__RXD5, -}; - -static void __init bug_board_init(void) -{ - imx31_soc_init(); - - mxc_iomux_setup_multiple_pins(bug_pins, - ARRAY_SIZE(bug_pins), "uart-4"); - imx31_add_imx_uart4(&uart_pdata); -} - -static void __init bug_timer_init(void) -{ - mx31_clocks_init(26000000); -} - -MACHINE_START(BUG, "BugLabs BUGBase") - .map_io = mx31_map_io, - .init_early = imx31_init_early, - .init_irq = mx31_init_irq, - .init_time = bug_timer_init, - .init_machine = bug_board_init, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-imx27.c b/arch/arm/mach-imx/mach-imx27.c new file mode 100644 index 000000000000..262422a9c196 --- /dev/null +++ b/arch/arm/mach-imx/mach-imx27.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2012 Sascha Hauer, Pengutronix + */ + +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <linux/mm.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/time.h> + +#include "common.h" +#include "hardware.h" +#include "mx27.h" + +/* MX27 memory map definition */ +static struct map_desc imx27_io_desc[] __initdata = { + /* + * this fixed mapping covers: + * - AIPI1 + * - AIPI2 + * - AITC + * - ROM Patch + * - and some reserved space + */ + imx_map_entry(MX27, AIPI, MT_DEVICE), + /* + * this fixed mapping covers: + * - CSI + * - ATA + */ + imx_map_entry(MX27, SAHB1, MT_DEVICE), + /* + * this fixed mapping covers: + * - EMI + */ + imx_map_entry(MX27, X_MEMC, MT_DEVICE), +}; + +/* + * Initialize the memory map. It is called during the + * system startup to create static physical to virtual + * memory map for the IO modules. + */ +static void __init mx27_map_io(void) +{ + iotable_init(imx27_io_desc, ARRAY_SIZE(imx27_io_desc)); +} + +static void __init imx27_init_early(void) +{ + mxc_set_cpu_type(MXC_CPU_MX27); +} + +static void __init mx27_init_irq(void) +{ + void __iomem *avic_base; + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "fsl,avic"); + avic_base = of_iomap(np, 0); + BUG_ON(!avic_base); + mxc_init_irq(avic_base); +} + +static const char * const imx27_dt_board_compat[] __initconst = { + "fsl,imx27", + NULL +}; + +DT_MACHINE_START(IMX27_DT, "Freescale i.MX27 (Device Tree Support)") + .map_io = mx27_map_io, + .init_early = imx27_init_early, + .init_irq = mx27_init_irq, + .init_late = imx27_pm_init, + .dt_compat = imx27_dt_board_compat, +MACHINE_END diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c deleted file mode 100644 index 3da4c0920198..000000000000 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ /dev/null @@ -1,562 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * mach-imx27_visstrim_m10.c - * - * Copyright 2010 Javier Martin <javier.martin@vista-silicon.com> - * - * Based on mach-pcm038.c, mach-pca100.c, mach-mx27ads.c and others. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/platform_device.h> -#include <linux/mtd/physmap.h> -#include <linux/i2c.h> -#include <linux/platform_data/pca953x.h> -#include <linux/input.h> -#include <linux/gpio.h> -#include <linux/delay.h> -#include <linux/dma-mapping.h> -#include <linux/leds.h> -#include <linux/platform_data/asoc-mx27vis.h> -#include <sound/tlv320aic32x4.h> -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/system_info.h> -#include <asm/memblock.h> - -#include "common.h" -#include "devices-imx27.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx27.h" - -#define TVP5150_RSTN (GPIO_PORTC + 18) -#define TVP5150_PWDN (GPIO_PORTC + 19) -#define OTG_PHY_CS_GPIO (GPIO_PORTF + 17) -#define SDHC1_IRQ_GPIO IMX_GPIO_NR(2, 25) - -#define VERSION_MASK 0x7 -#define MOTHERBOARD_SHIFT 4 -#define EXPBOARD_SHIFT 0 - -#define MOTHERBOARD_BIT2 (GPIO_PORTD + 31) -#define MOTHERBOARD_BIT1 (GPIO_PORTD + 30) -#define MOTHERBOARD_BIT0 (GPIO_PORTD + 29) - -#define EXPBOARD_BIT2 (GPIO_PORTD + 25) -#define EXPBOARD_BIT1 (GPIO_PORTD + 27) -#define EXPBOARD_BIT0 (GPIO_PORTD + 28) - -#define AMP_GAIN_0 (GPIO_PORTF + 9) -#define AMP_GAIN_1 (GPIO_PORTF + 8) -#define AMP_MUTE_SDL (GPIO_PORTE + 5) -#define AMP_MUTE_SDR (GPIO_PORTF + 7) - -static const int visstrim_m10_pins[] __initconst = { - /* UART1 (console) */ - PE12_PF_UART1_TXD, - PE13_PF_UART1_RXD, - PE14_PF_UART1_CTS, - PE15_PF_UART1_RTS, - /* FEC */ - PD0_AIN_FEC_TXD0, - PD1_AIN_FEC_TXD1, - PD2_AIN_FEC_TXD2, - PD3_AIN_FEC_TXD3, - PD4_AOUT_FEC_RX_ER, - PD5_AOUT_FEC_RXD1, - PD6_AOUT_FEC_RXD2, - PD7_AOUT_FEC_RXD3, - PD8_AF_FEC_MDIO, - PD9_AIN_FEC_MDC, - PD10_AOUT_FEC_CRS, - PD11_AOUT_FEC_TX_CLK, - PD12_AOUT_FEC_RXD0, - PD13_AOUT_FEC_RX_DV, - PD14_AOUT_FEC_RX_CLK, - PD15_AOUT_FEC_COL, - PD16_AIN_FEC_TX_ER, - PF23_AIN_FEC_TX_EN, - /* SSI1 */ - PC20_PF_SSI1_FS, - PC21_PF_SSI1_RXD, - PC22_PF_SSI1_TXD, - PC23_PF_SSI1_CLK, - /* SDHC1 */ - PE18_PF_SD1_D0, - PE19_PF_SD1_D1, - PE20_PF_SD1_D2, - PE21_PF_SD1_D3, - PE22_PF_SD1_CMD, - PE23_PF_SD1_CLK, - /* Both I2Cs */ - PD17_PF_I2C_DATA, - PD18_PF_I2C_CLK, - PC5_PF_I2C2_SDA, - PC6_PF_I2C2_SCL, - /* USB OTG */ - OTG_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT, - PC9_PF_USBOTG_DATA0, - PC11_PF_USBOTG_DATA1, - PC10_PF_USBOTG_DATA2, - PC13_PF_USBOTG_DATA3, - PC12_PF_USBOTG_DATA4, - PC7_PF_USBOTG_DATA5, - PC8_PF_USBOTG_DATA6, - PE25_PF_USBOTG_DATA7, - PE24_PF_USBOTG_CLK, - PE2_PF_USBOTG_DIR, - PE0_PF_USBOTG_NXT, - PE1_PF_USBOTG_STP, - PB23_PF_USB_PWR, - PB24_PF_USB_OC, - /* CSI */ - TVP5150_RSTN | GPIO_GPIO | GPIO_OUT, - TVP5150_PWDN | GPIO_GPIO | GPIO_OUT, - PB10_PF_CSI_D0, - PB11_PF_CSI_D1, - PB12_PF_CSI_D2, - PB13_PF_CSI_D3, - PB14_PF_CSI_D4, - PB15_PF_CSI_MCLK, - PB16_PF_CSI_PIXCLK, - PB17_PF_CSI_D5, - PB18_PF_CSI_D6, - PB19_PF_CSI_D7, - PB20_PF_CSI_VSYNC, - PB21_PF_CSI_HSYNC, - /* mother board version */ - MOTHERBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN, - MOTHERBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN, - MOTHERBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN, - /* expansion board version */ - EXPBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN, - EXPBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN, - EXPBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN, - /* Audio AMP control */ - AMP_GAIN_0 | GPIO_GPIO | GPIO_OUT, - AMP_GAIN_1 | GPIO_GPIO | GPIO_OUT, - AMP_MUTE_SDL | GPIO_GPIO | GPIO_OUT, - AMP_MUTE_SDR | GPIO_GPIO | GPIO_OUT, -}; - -static struct gpio visstrim_m10_version_gpios[] = { - { EXPBOARD_BIT0, GPIOF_IN, "exp-version-0" }, - { EXPBOARD_BIT1, GPIOF_IN, "exp-version-1" }, - { EXPBOARD_BIT2, GPIOF_IN, "exp-version-2" }, - { MOTHERBOARD_BIT0, GPIOF_IN, "mother-version-0" }, - { MOTHERBOARD_BIT1, GPIOF_IN, "mother-version-1" }, - { MOTHERBOARD_BIT2, GPIOF_IN, "mother-version-2" }, -}; - -static const struct gpio visstrim_m10_gpios[] __initconst = { - { - .gpio = TVP5150_RSTN, - .flags = GPIOF_DIR_OUT | GPIOF_INIT_HIGH, - .label = "tvp5150_rstn", - }, - { - .gpio = TVP5150_PWDN, - .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW, - .label = "tvp5150_pwdn", - }, - { - .gpio = OTG_PHY_CS_GPIO, - .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW, - .label = "usbotg_cs", - }, - { - .gpio = AMP_GAIN_0, - .flags = GPIOF_DIR_OUT, - .label = "amp-gain-0", - }, - { - .gpio = AMP_GAIN_1, - .flags = GPIOF_DIR_OUT, - .label = "amp-gain-1", - }, - { - .gpio = AMP_MUTE_SDL, - .flags = GPIOF_DIR_OUT, - .label = "amp-mute-sdl", - }, - { - .gpio = AMP_MUTE_SDR, - .flags = GPIOF_DIR_OUT, - .label = "amp-mute-sdr", - }, -}; - -/* Camera */ -static struct mx2_camera_platform_data visstrim_camera = { - .flags = MX2_CAMERA_CCIR | MX2_CAMERA_CCIR_INTERLACE | - MX2_CAMERA_PCLK_SAMPLE_RISING, - .clk = 100000, -}; - -static phys_addr_t mx2_camera_base __initdata; -#define MX2_CAMERA_BUF_SIZE SZ_8M - -static void __init visstrim_analog_camera_init(void) -{ - struct platform_device *pdev; - - gpio_set_value(TVP5150_PWDN, 1); - ndelay(1); - gpio_set_value(TVP5150_RSTN, 0); - ndelay(500); - gpio_set_value(TVP5150_RSTN, 1); - ndelay(200000); - - pdev = imx27_add_mx2_camera(&visstrim_camera); - if (IS_ERR(pdev)) - return; - - dma_declare_coherent_memory(&pdev->dev, mx2_camera_base, - mx2_camera_base, MX2_CAMERA_BUF_SIZE); -} - -static void __init visstrim_reserve(void) -{ - /* reserve 4 MiB for mx2-camera */ - mx2_camera_base = arm_memblock_steal(3 * MX2_CAMERA_BUF_SIZE, - MX2_CAMERA_BUF_SIZE); -} - -/* GPIOs used as events for applications */ -static struct gpio_keys_button visstrim_gpio_keys[] = { - { - .type = EV_KEY, - .code = KEY_RESTART, - .gpio = (GPIO_PORTC + 15), - .desc = "Default config", - .active_low = 0, - .wakeup = 1, - }, - { - .type = EV_KEY, - .code = KEY_RECORD, - .gpio = (GPIO_PORTF + 14), - .desc = "Record", - .active_low = 0, - .wakeup = 1, - }, - { - .type = EV_KEY, - .code = KEY_STOP, - .gpio = (GPIO_PORTF + 13), - .desc = "Stop", - .active_low = 0, - .wakeup = 1, - } -}; - -static const struct gpio_keys_platform_data - visstrim_gpio_keys_platform_data __initconst = { - .buttons = visstrim_gpio_keys, - .nbuttons = ARRAY_SIZE(visstrim_gpio_keys), -}; - -/* led */ -static const struct gpio_led visstrim_m10_leds[] __initconst = { - { - .name = "visstrim:ld0", - .default_trigger = "nand-disk", - .gpio = (GPIO_PORTC + 29), - }, - { - .name = "visstrim:ld1", - .default_trigger = "nand-disk", - .gpio = (GPIO_PORTC + 24), - }, - { - .name = "visstrim:ld2", - .default_trigger = "nand-disk", - .gpio = (GPIO_PORTC + 28), - }, - { - .name = "visstrim:ld3", - .default_trigger = "nand-disk", - .gpio = (GPIO_PORTC + 25), - }, -}; - -static const struct gpio_led_platform_data visstrim_m10_led_data __initconst = { - .leds = visstrim_m10_leds, - .num_leds = ARRAY_SIZE(visstrim_m10_leds), -}; - -/* Visstrim_SM10 has a microSD slot connected to sdhc1 */ -static int visstrim_m10_sdhc1_init(struct device *dev, - irq_handler_t detect_irq, void *data) -{ - int ret; - - ret = request_irq(gpio_to_irq(SDHC1_IRQ_GPIO), detect_irq, - IRQF_TRIGGER_FALLING, "mmc-detect", data); - return ret; -} - -static void visstrim_m10_sdhc1_exit(struct device *dev, void *data) -{ - free_irq(gpio_to_irq(SDHC1_IRQ_GPIO), data); -} - -static const struct imxmmc_platform_data visstrim_m10_sdhc_pdata __initconst = { - .init = visstrim_m10_sdhc1_init, - .exit = visstrim_m10_sdhc1_exit, -}; - -/* Visstrim_SM10 NOR flash */ -static struct physmap_flash_data visstrim_m10_flash_data = { - .width = 2, -}; - -static struct resource visstrim_m10_flash_resource = { - .start = 0xc0000000, - .end = 0xc0000000 + SZ_64M - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device visstrim_m10_nor_mtd_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &visstrim_m10_flash_data, - }, - .num_resources = 1, - .resource = &visstrim_m10_flash_resource, -}; - -static struct platform_device *platform_devices[] __initdata = { - &visstrim_m10_nor_mtd_device, -}; - -/* Visstrim_M10 uses UART0 as console */ -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -/* I2C */ -static const struct imxi2c_platform_data visstrim_m10_i2c_data __initconst = { - .bitrate = 100000, -}; - -static struct pca953x_platform_data visstrim_m10_pca9555_pdata = { - .gpio_base = 240, /* After MX27 internal GPIOs */ - .invert = 0, -}; - -static struct aic32x4_pdata visstrim_m10_aic32x4_pdata = { - .power_cfg = AIC32X4_PWR_MICBIAS_2075_LDOIN | - AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE | - AIC32X4_PWR_AIC32X4_LDO_ENABLE | - AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36 | - AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED, - .micpga_routing = AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K | - AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K, - .swapdacs = false, -}; - -static struct i2c_board_info visstrim_m10_i2c_devices[] = { - { - I2C_BOARD_INFO("pca9555", 0x20), - .platform_data = &visstrim_m10_pca9555_pdata, - }, - { - I2C_BOARD_INFO("tlv320aic32x4", 0x18), - .platform_data = &visstrim_m10_aic32x4_pdata, - }, - { - I2C_BOARD_INFO("m41t00", 0x68), - } -}; - -/* USB OTG */ -static int otg_phy_init(struct platform_device *pdev) -{ - return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); -} - -static const struct mxc_usbh_platform_data -visstrim_m10_usbotg_pdata __initconst = { - .init = otg_phy_init, - .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, -}; - -/* SSI */ -static const struct imx_ssi_platform_data visstrim_m10_ssi_pdata __initconst = { - .flags = IMX_SSI_DMA | IMX_SSI_SYN, -}; - -/* coda */ - -static void __init visstrim_coda_init(void) -{ - struct platform_device *pdev; - - pdev = imx27_add_coda(); - dma_declare_coherent_memory(&pdev->dev, - mx2_camera_base + MX2_CAMERA_BUF_SIZE, - mx2_camera_base + MX2_CAMERA_BUF_SIZE, - MX2_CAMERA_BUF_SIZE); -} - -/* DMA deinterlace */ -static struct platform_device visstrim_deinterlace = { - .name = "m2m-deinterlace", - .id = 0, -}; - -static void __init visstrim_deinterlace_init(void) -{ - int ret = -ENOMEM; - struct platform_device *pdev = &visstrim_deinterlace; - - ret = platform_device_register(pdev); - - dma_declare_coherent_memory(&pdev->dev, - mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE, - mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE, - MX2_CAMERA_BUF_SIZE); -} - -/* Emma-PrP for format conversion */ -static void __init visstrim_emmaprp_init(void) -{ - struct platform_device *pdev; - int ret; - - pdev = imx27_add_mx2_emmaprp(); - if (IS_ERR(pdev)) - return; - - /* - * Use the same memory area as the analog camera since both - * devices are, by nature, exclusive. - */ - ret = dma_declare_coherent_memory(&pdev->dev, - mx2_camera_base, mx2_camera_base, - MX2_CAMERA_BUF_SIZE); - if (ret) - pr_err("Failed to declare memory for emmaprp\n"); -} - -/* Audio */ -static const struct snd_mx27vis_platform_data snd_mx27vis_pdata __initconst = { - .amp_gain0_gpio = AMP_GAIN_0, - .amp_gain1_gpio = AMP_GAIN_1, - .amp_mutel_gpio = AMP_MUTE_SDL, - .amp_muter_gpio = AMP_MUTE_SDR, -}; - -static void __init visstrim_m10_revision(void) -{ - int exp_version = 0; - int mo_version = 0; - int ret; - - ret = gpio_request_array(visstrim_m10_version_gpios, - ARRAY_SIZE(visstrim_m10_version_gpios)); - if (ret) { - pr_err("Failed to request version gpios"); - return; - } - - /* Get expansion board version (negative logic) */ - exp_version |= !gpio_get_value(EXPBOARD_BIT2) << 2; - exp_version |= !gpio_get_value(EXPBOARD_BIT1) << 1; - exp_version |= !gpio_get_value(EXPBOARD_BIT0); - - /* Get mother board version (negative logic) */ - mo_version |= !gpio_get_value(MOTHERBOARD_BIT2) << 2; - mo_version |= !gpio_get_value(MOTHERBOARD_BIT1) << 1; - mo_version |= !gpio_get_value(MOTHERBOARD_BIT0); - - system_rev = 0x27000; - system_rev |= (mo_version << MOTHERBOARD_SHIFT); - system_rev |= (exp_version << EXPBOARD_SHIFT); -} - -static void __init visstrim_m10_board_init(void) -{ - int ret; - - imx27_soc_init(); - visstrim_m10_revision(); - - ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins, - ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10"); - if (ret) - pr_err("Failed to setup pins (%d)\n", ret); - - imx27_add_imx_ssi(0, &visstrim_m10_ssi_pdata); - imx27_add_imx_uart0(&uart_pdata); - - imx27_add_imx_i2c(0, &visstrim_m10_i2c_data); - imx27_add_imx_i2c(1, &visstrim_m10_i2c_data); - i2c_register_board_info(0, visstrim_m10_i2c_devices, - ARRAY_SIZE(visstrim_m10_i2c_devices)); - - imx27_add_mxc_mmc(0, &visstrim_m10_sdhc_pdata); - imx27_add_mxc_ehci_otg(&visstrim_m10_usbotg_pdata); - imx27_add_fec(NULL); - - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); -} - -static void __init visstrim_m10_late_init(void) -{ - int mo_version, ret; - - ret = gpio_request_array(visstrim_m10_gpios, - ARRAY_SIZE(visstrim_m10_gpios)); - if (ret) - pr_err("Failed to request gpios (%d)\n", ret); - - imx_add_gpio_keys(&visstrim_gpio_keys_platform_data); - - imx_add_platform_device("mx27vis", 0, NULL, 0, &snd_mx27vis_pdata, - sizeof(snd_mx27vis_pdata)); - - gpio_led_register_device(0, &visstrim_m10_led_data); - - /* Use mother board version to decide what video devices we shall use */ - mo_version = (system_rev >> MOTHERBOARD_SHIFT) & VERSION_MASK; - if (mo_version & 0x1) { - visstrim_emmaprp_init(); - - /* - * Despite not being used, tvp5150 must be - * powered on to avoid I2C problems. To minimize - * power consupmtion keep reset enabled. - */ - gpio_set_value(TVP5150_PWDN, 1); - ndelay(1); - gpio_set_value(TVP5150_RSTN, 0); - } else { - visstrim_deinterlace_init(); - visstrim_analog_camera_init(); - } - - visstrim_coda_init(); -} - -static void __init visstrim_m10_timer_init(void) -{ - mx27_clocks_init((unsigned long)25000000); -} - -MACHINE_START(IMX27_VISSTRIM_M10, "Vista Silicon Visstrim_M10") - .atag_offset = 0x100, - .reserve = visstrim_reserve, - .map_io = mx27_map_io, - .init_early = imx27_init_early, - .init_irq = mx27_init_irq, - .init_time = visstrim_m10_timer_init, - .init_machine = visstrim_m10_board_init, - .init_late = visstrim_m10_late_init, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/imx31-dt.c b/arch/arm/mach-imx/mach-imx31.c index dc69dfe600df..dc69dfe600df 100644 --- a/arch/arm/mach-imx/imx31-dt.c +++ b/arch/arm/mach-imx/mach-imx31.c diff --git a/arch/arm/mach-imx/imx35-dt.c b/arch/arm/mach-imx/mach-imx35.c index ec5c3068715c..ec5c3068715c 100644 --- a/arch/arm/mach-imx/imx35-dt.c +++ b/arch/arm/mach-imx/mach-imx35.c diff --git a/arch/arm/mach-imx/mach-imx7ulp.c b/arch/arm/mach-imx/mach-imx7ulp.c index 128cf4c92aab..445256e6a4a0 100644 --- a/arch/arm/mach-imx/mach-imx7ulp.c +++ b/arch/arm/mach-imx/mach-imx7ulp.c @@ -67,6 +67,9 @@ static const char *const imx7ulp_dt_compat[] __initconst = { static void __init imx7ulp_init_late(void) { + if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT)) + platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0); + imx7ulp_cpuidle_init(); } diff --git a/arch/arm/mach-imx/mach-kzm_arm11_01.c b/arch/arm/mach-imx/mach-kzm_arm11_01.c deleted file mode 100644 index 63f7f78a77af..000000000000 --- a/arch/arm/mach-imx/mach-kzm_arm11_01.c +++ /dev/null @@ -1,291 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * KZM-ARM11-01 support - * Copyright (C) 2009 Yoichi Yuasa <yuasa@linux-mips.org> - * - * based on code for MX31ADS, - * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright (C) 2002 Shane Nay (shane@minirl.com) - * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/serial_8250.h> -#include <linux/smsc911x.h> -#include <linux/types.h> -#include <linux/regulator/machine.h> -#include <linux/regulator/fixed.h> - -#include <asm/irq.h> -#include <asm/mach-types.h> -#include <asm/memory.h> -#include <asm/setup.h> -#include <asm/mach/arch.h> -#include <asm/mach/irq.h> -#include <asm/mach/map.h> -#include <asm/mach/time.h> - -#include "common.h" -#include "devices-imx31.h" -#include "hardware.h" -#include "iomux-mx3.h" - -#define KZM_ARM11_IO_ADDRESS(x) (IOMEM( \ - IMX_IO_P2V_MODULE(x, MX31_CS4) ?: \ - IMX_IO_P2V_MODULE(x, MX31_CS5)) ?: \ - MX31_IO_ADDRESS(x)) - -/* - * KZM-ARM11-01 Board Control Registers on FPGA - */ -#define KZM_ARM11_CTL1 (MX31_CS4_BASE_ADDR + 0x1000) -#define KZM_ARM11_CTL2 (MX31_CS4_BASE_ADDR + 0x1001) -#define KZM_ARM11_RSW1 (MX31_CS4_BASE_ADDR + 0x1002) -#define KZM_ARM11_BACK_LIGHT (MX31_CS4_BASE_ADDR + 0x1004) -#define KZM_ARM11_FPGA_REV (MX31_CS4_BASE_ADDR + 0x1008) -#define KZM_ARM11_7SEG_LED (MX31_CS4_BASE_ADDR + 0x1010) -#define KZM_ARM11_LEDS (MX31_CS4_BASE_ADDR + 0x1020) -#define KZM_ARM11_DIPSW2 (MX31_CS4_BASE_ADDR + 0x1003) - -/* - * External UART for touch panel on FPGA - */ -#define KZM_ARM11_16550 (MX31_CS4_BASE_ADDR + 0x1050) - -#if IS_ENABLED(CONFIG_SERIAL_8250) -/* - * KZM-ARM11-01 has an external UART on FPGA - */ -static struct plat_serial8250_port serial_platform_data[] = { - { - .membase = KZM_ARM11_IO_ADDRESS(KZM_ARM11_16550), - .mapbase = KZM_ARM11_16550, - /* irq number is run-time assigned */ - .irqflags = IRQ_TYPE_EDGE_RISING, - .uartclk = 14745600, - .regshift = 0, - .iotype = UPIO_MEM, - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | - UPF_BUGGY_UART, - }, - {}, -}; - -static struct resource serial8250_resources[] = { - { - .start = KZM_ARM11_16550, - .end = KZM_ARM11_16550 + 0x10, - .flags = IORESOURCE_MEM, - }, - { - /* irq number is run-time assigned */ - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device serial_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = serial_platform_data, - }, - .num_resources = ARRAY_SIZE(serial8250_resources), - .resource = serial8250_resources, -}; - -static int __init kzm_init_ext_uart(void) -{ - u8 tmp; - - /* - * GPIO 1-1: external UART interrupt line - */ - mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO)); - gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "ext-uart-int"); - gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)); - - /* - * Unmask UART interrupt - */ - tmp = __raw_readb(KZM_ARM11_IO_ADDRESS(KZM_ARM11_CTL1)); - tmp |= 0x2; - __raw_writeb(tmp, KZM_ARM11_IO_ADDRESS(KZM_ARM11_CTL1)); - - serial_platform_data[0].irq = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)); - serial8250_resources[1].start = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)); - serial8250_resources[1].end = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)); - - return platform_device_register(&serial_device); -} -#else -static inline int kzm_init_ext_uart(void) -{ - return 0; -} -#endif - -/* - * SMSC LAN9118 - */ -#if IS_ENABLED(CONFIG_SMSC911X) -static struct smsc911x_platform_config kzm_smsc9118_config = { - .phy_interface = PHY_INTERFACE_MODE_MII, - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, - .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, - .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, -}; - -static struct resource kzm_smsc9118_resources[] = { - { - .start = MX31_CS5_BASE_ADDR, - .end = MX31_CS5_BASE_ADDR + SZ_128K - 1, - .flags = IORESOURCE_MEM, - }, - { - /* irq number is run-time assigned */ - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, - }, -}; - -static struct platform_device kzm_smsc9118_device = { - .name = "smsc911x", - .id = -1, - .num_resources = ARRAY_SIZE(kzm_smsc9118_resources), - .resource = kzm_smsc9118_resources, - .dev = { - .platform_data = &kzm_smsc9118_config, - }, -}; - -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vdd33a", "smsc911x"), - REGULATOR_SUPPLY("vddvario", "smsc911x"), -}; - -static int __init kzm_init_smsc9118(void) -{ - /* - * GPIO 1-2: SMSC9118 interrupt line - */ - mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO)); - gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2), "smsc9118-int"); - gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2)); - - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - - kzm_smsc9118_resources[1].start = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2)); - kzm_smsc9118_resources[1].end = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2)); - - return platform_device_register(&kzm_smsc9118_device); -} -#else -static inline int kzm_init_smsc9118(void) -{ - return 0; -} -#endif - -#if IS_ENABLED(CONFIG_SERIAL_IMX) -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static void __init kzm_init_imx_uart(void) -{ - imx31_add_imx_uart0(&uart_pdata); - imx31_add_imx_uart1(&uart_pdata); -} -#else -static inline void kzm_init_imx_uart(void) -{ -} -#endif - -static int kzm_pins[] __initdata = { - MX31_PIN_CTS1__CTS1, - MX31_PIN_RTS1__RTS1, - MX31_PIN_TXD1__TXD1, - MX31_PIN_RXD1__RXD1, - MX31_PIN_DCD_DCE1__DCD_DCE1, - MX31_PIN_RI_DCE1__RI_DCE1, - MX31_PIN_DSR_DCE1__DSR_DCE1, - MX31_PIN_DTR_DCE1__DTR_DCE1, - MX31_PIN_CTS2__CTS2, - MX31_PIN_RTS2__RTS2, - MX31_PIN_TXD2__TXD2, - MX31_PIN_RXD2__RXD2, - MX31_PIN_DCD_DTE1__DCD_DTE2, - MX31_PIN_RI_DTE1__RI_DTE2, - MX31_PIN_DSR_DTE1__DSR_DTE2, - MX31_PIN_DTR_DTE1__DTR_DTE2, -}; - -/* - * Board specific initialization. - */ -static void __init kzm_board_init(void) -{ - imx31_soc_init(); - - mxc_iomux_setup_multiple_pins(kzm_pins, - ARRAY_SIZE(kzm_pins), "kzm"); - kzm_init_imx_uart(); - - pr_info("Clock input source is 26MHz\n"); -} - -static void __init kzm_late_init(void) -{ - kzm_init_ext_uart(); - kzm_init_smsc9118(); -} - -/* - * This structure defines static mappings for the kzm-arm11-01 board. - */ -static struct map_desc kzm_io_desc[] __initdata = { - { - .virtual = (unsigned long)MX31_CS4_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR), - .length = MX31_CS4_SIZE, - .type = MT_DEVICE - }, - { - .virtual = (unsigned long)MX31_CS5_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR), - .length = MX31_CS5_SIZE, - .type = MT_DEVICE - }, -}; - -/* - * Set up static virtual mappings. - */ -static void __init kzm_map_io(void) -{ - mx31_map_io(); - iotable_init(kzm_io_desc, ARRAY_SIZE(kzm_io_desc)); -} - -static void __init kzm_timer_init(void) -{ - mx31_clocks_init(26000000); -} - -MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01") - .atag_offset = 0x100, - .map_io = kzm_map_io, - .init_early = imx31_init_early, - .init_irq = mx31_init_irq, - .init_time = kzm_timer_init, - .init_machine = kzm_board_init, - .init_late = kzm_late_init, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c deleted file mode 100644 index ec011e89eb9e..000000000000 --- a/arch/arm/mach-imx/mach-mx21ads.c +++ /dev/null @@ -1,338 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright (C) 2002 Shane Nay (shane@minirl.com) - * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -#include <linux/platform_device.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/physmap.h> -#include <linux/gpio/driver.h> -#include <linux/gpio/machine.h> -#include <linux/gpio.h> -#include <linux/regulator/fixed.h> -#include <linux/regulator/machine.h> -#include <asm/mach-types.h> -#include <asm/mach/arch.h> - -#include "common.h" -#include "devices-imx21.h" -#include "hardware.h" -#include "iomux-mx21.h" - -#define MX21ADS_CS8900A_REG (MX21_CS1_BASE_ADDR + 0x000000) -#define MX21ADS_ST16C255_IOBASE_REG (MX21_CS1_BASE_ADDR + 0x200000) -#define MX21ADS_VERSION_REG (MX21_CS1_BASE_ADDR + 0x400000) -#define MX21ADS_IO_REG (MX21_CS1_BASE_ADDR + 0x800000) - -#define MX21ADS_MMC_CD IMX_GPIO_NR(4, 25) -#define MX21ADS_CS8900A_IRQ_GPIO IMX_GPIO_NR(5, 11) -#define MX21ADS_MMGPIO_BASE (6 * 32) - -/* MX21ADS_IO_REG bit definitions */ -#define MX21ADS_IO_SD_WP (MX21ADS_MMGPIO_BASE + 0) -#define MX21ADS_IO_TP6 (MX21ADS_IO_SD_WP) -#define MX21ADS_IO_SW_SEL (MX21ADS_MMGPIO_BASE + 1) -#define MX21ADS_IO_TP7 (MX21ADS_IO_SW_SEL) -#define MX21ADS_IO_RESET_E_UART (MX21ADS_MMGPIO_BASE + 2) -#define MX21ADS_IO_RESET_BASE (MX21ADS_MMGPIO_BASE + 3) -#define MX21ADS_IO_CSI_CTL2 (MX21ADS_MMGPIO_BASE + 4) -#define MX21ADS_IO_CSI_CTL1 (MX21ADS_MMGPIO_BASE + 5) -#define MX21ADS_IO_CSI_CTL0 (MX21ADS_MMGPIO_BASE + 6) -#define MX21ADS_IO_UART1_EN (MX21ADS_MMGPIO_BASE + 7) -#define MX21ADS_IO_UART4_EN (MX21ADS_MMGPIO_BASE + 8) -#define MX21ADS_IO_LCDON (MX21ADS_MMGPIO_BASE + 9) -#define MX21ADS_IO_IRDA_EN (MX21ADS_MMGPIO_BASE + 10) -#define MX21ADS_IO_IRDA_FIR_SEL (MX21ADS_MMGPIO_BASE + 11) -#define MX21ADS_IO_IRDA_MD0_B (MX21ADS_MMGPIO_BASE + 12) -#define MX21ADS_IO_IRDA_MD1 (MX21ADS_MMGPIO_BASE + 13) -#define MX21ADS_IO_LED4_ON (MX21ADS_MMGPIO_BASE + 14) -#define MX21ADS_IO_LED3_ON (MX21ADS_MMGPIO_BASE + 15) - -static const int mx21ads_pins[] __initconst = { - - /* CS8900A */ - (GPIO_PORTE | GPIO_GPIO | GPIO_IN | 11), - - /* UART1 */ - PE12_PF_UART1_TXD, - PE13_PF_UART1_RXD, - PE14_PF_UART1_CTS, - PE15_PF_UART1_RTS, - - /* UART3 (IrDA) - only TXD and RXD */ - PE8_PF_UART3_TXD, - PE9_PF_UART3_RXD, - - /* UART4 */ - PB26_AF_UART4_RTS, - PB28_AF_UART4_TXD, - PB29_AF_UART4_CTS, - PB31_AF_UART4_RXD, - - /* LCDC */ - PA5_PF_LSCLK, - PA6_PF_LD0, - PA7_PF_LD1, - PA8_PF_LD2, - PA9_PF_LD3, - PA10_PF_LD4, - PA11_PF_LD5, - PA12_PF_LD6, - PA13_PF_LD7, - PA14_PF_LD8, - PA15_PF_LD9, - PA16_PF_LD10, - PA17_PF_LD11, - PA18_PF_LD12, - PA19_PF_LD13, - PA20_PF_LD14, - PA21_PF_LD15, - PA22_PF_LD16, - PA24_PF_REV, /* Sharp panel dedicated signal */ - PA25_PF_CLS, /* Sharp panel dedicated signal */ - PA26_PF_PS, /* Sharp panel dedicated signal */ - PA27_PF_SPL_SPR, /* Sharp panel dedicated signal */ - PA28_PF_HSYNC, - PA29_PF_VSYNC, - PA30_PF_CONTRAST, - PA31_PF_OE_ACD, - - /* MMC/SDHC */ - PE18_PF_SD1_D0, - PE19_PF_SD1_D1, - PE20_PF_SD1_D2, - PE21_PF_SD1_D3, - PE22_PF_SD1_CMD, - PE23_PF_SD1_CLK, - - /* NFC */ - PF0_PF_NRFB, - PF1_PF_NFCE, - PF2_PF_NFWP, - PF3_PF_NFCLE, - PF4_PF_NFALE, - PF5_PF_NFRE, - PF6_PF_NFWE, - PF7_PF_NFIO0, - PF8_PF_NFIO1, - PF9_PF_NFIO2, - PF10_PF_NFIO3, - PF11_PF_NFIO4, - PF12_PF_NFIO5, - PF13_PF_NFIO6, - PF14_PF_NFIO7, -}; - -/* ADS's NOR flash: 2x AM29BDS128HE9VKI on 32-bit bus */ -static struct physmap_flash_data mx21ads_flash_data = { - .width = 4, -}; - -static struct resource mx21ads_flash_resource = - DEFINE_RES_MEM(MX21_CS0_BASE_ADDR, SZ_32M); - -static struct platform_device mx21ads_nor_mtd_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &mx21ads_flash_data, - }, - .num_resources = 1, - .resource = &mx21ads_flash_resource, -}; - -static struct resource mx21ads_cs8900_resources[] __initdata = { - DEFINE_RES_MEM(MX21ADS_CS8900A_REG, SZ_1K), - /* irq number is run-time assigned */ - DEFINE_RES_IRQ(-1), -}; - -static const struct platform_device_info mx21ads_cs8900_devinfo __initconst = { - .name = "cs89x0", - .id = 0, - .res = mx21ads_cs8900_resources, - .num_res = ARRAY_SIZE(mx21ads_cs8900_resources), -}; - -static const struct imxuart_platform_data uart_pdata_rts __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static const struct imxuart_platform_data uart_pdata_norts __initconst = { -}; - -static struct resource mx21ads_mmgpio_resource = - DEFINE_RES_MEM_NAMED(MX21ADS_IO_REG, SZ_2, "dat"); - -static struct bgpio_pdata mx21ads_mmgpio_pdata = { - .label = "mx21ads-mmgpio", - .base = MX21ADS_MMGPIO_BASE, - .ngpio = 16, -}; - -static struct platform_device mx21ads_mmgpio = { - .name = "basic-mmio-gpio", - .id = PLATFORM_DEVID_AUTO, - .resource = &mx21ads_mmgpio_resource, - .num_resources = 1, - .dev = { - .platform_data = &mx21ads_mmgpio_pdata, - }, -}; - -static struct regulator_consumer_supply mx21ads_lcd_regulator_consumer = - REGULATOR_SUPPLY("lcd", "imx-fb.0"); - -static struct regulator_init_data mx21ads_lcd_regulator_init_data = { - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .consumer_supplies = &mx21ads_lcd_regulator_consumer, - .num_consumer_supplies = 1, -}; - -static struct fixed_voltage_config mx21ads_lcd_regulator_pdata = { - .supply_name = "LCD", - .microvolts = 3300000, - .init_data = &mx21ads_lcd_regulator_init_data, -}; - -static struct platform_device mx21ads_lcd_regulator = { - .name = "reg-fixed-voltage", - .id = PLATFORM_DEVID_AUTO, - .dev = { - .platform_data = &mx21ads_lcd_regulator_pdata, - }, -}; - -static struct gpiod_lookup_table mx21ads_lcd_regulator_gpiod_table = { - .dev_id = "reg-fixed-voltage.0", /* Let's hope ID 0 is what we get */ - .table = { - GPIO_LOOKUP("mx21ads-mmgpio", 9, NULL, GPIO_ACTIVE_HIGH), - { }, - }, -}; - -/* - * Connected is a portrait Sharp-QVGA display - * of type: LQ035Q7DB02 - */ -static struct imx_fb_videomode mx21ads_modes[] = { - { - .mode = { - .name = "Sharp-LQ035Q7", - .refresh = 60, - .xres = 240, - .yres = 320, - .pixclock = 188679, /* in ps (5.3MHz) */ - .hsync_len = 2, - .left_margin = 6, - .right_margin = 16, - .vsync_len = 1, - .upper_margin = 8, - .lower_margin = 10, - }, - .pcr = 0xfb108bc7, - .bpp = 16, - }, -}; - -static const struct imx_fb_platform_data mx21ads_fb_data __initconst = { - .mode = mx21ads_modes, - .num_modes = ARRAY_SIZE(mx21ads_modes), - - .pwmr = 0x00a903ff, - .lscr1 = 0x00120300, - .dmacr = 0x00020008, -}; - -static int mx21ads_sdhc_get_ro(struct device *dev) -{ - return gpio_get_value(MX21ADS_IO_SD_WP); -} - -static int mx21ads_sdhc_init(struct device *dev, irq_handler_t detect_irq, - void *data) -{ - int ret; - - ret = gpio_request(MX21ADS_IO_SD_WP, "mmc-ro"); - if (ret) - return ret; - - return request_irq(gpio_to_irq(MX21ADS_MMC_CD), detect_irq, - IRQF_TRIGGER_FALLING, "mmc-detect", data); -} - -static void mx21ads_sdhc_exit(struct device *dev, void *data) -{ - free_irq(gpio_to_irq(MX21ADS_MMC_CD), data); - gpio_free(MX21ADS_IO_SD_WP); -} - -static const struct imxmmc_platform_data mx21ads_sdhc_pdata __initconst = { - .ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31, /* 3.0V */ - .get_ro = mx21ads_sdhc_get_ro, - .init = mx21ads_sdhc_init, - .exit = mx21ads_sdhc_exit, -}; - -static const struct mxc_nand_platform_data -mx21ads_nand_board_info __initconst = { - .width = 1, - .hw_ecc = 1, -}; - -static struct platform_device *platform_devices[] __initdata = { - &mx21ads_mmgpio, - &mx21ads_lcd_regulator, - &mx21ads_nor_mtd_device, -}; - -static void __init mx21ads_board_init(void) -{ - imx21_soc_init(); - - mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins), - "mx21ads"); - - imx21_add_imx_uart0(&uart_pdata_rts); - imx21_add_imx_uart2(&uart_pdata_norts); - imx21_add_imx_uart3(&uart_pdata_rts); - imx21_add_mxc_nand(&mx21ads_nand_board_info); - - imx21_add_imx_fb(&mx21ads_fb_data); -} - -static void __init mx21ads_late_init(void) -{ - imx21_add_mxc_mmc(0, &mx21ads_sdhc_pdata); - - gpiod_add_lookup_table(&mx21ads_lcd_regulator_gpiod_table); - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); - - mx21ads_cs8900_resources[1].start = - gpio_to_irq(MX21ADS_CS8900A_IRQ_GPIO); - mx21ads_cs8900_resources[1].end = - gpio_to_irq(MX21ADS_CS8900A_IRQ_GPIO); - platform_device_register_full(&mx21ads_cs8900_devinfo); -} - -static void __init mx21ads_timer_init(void) -{ - mx21_clocks_init(32768, 26000000); -} - -MACHINE_START(MX21ADS, "Freescale i.MX21ADS") - /* maintainer: Freescale Semiconductor, Inc. */ - .atag_offset = 0x100, - .map_io = mx21_map_io, - .init_early = imx21_init_early, - .init_irq = mx21_init_irq, - .init_time = mx21ads_timer_init, - .init_machine = mx21ads_board_init, - .init_late = mx21ads_late_init, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c deleted file mode 100644 index 2db4475b7f85..000000000000 --- a/arch/arm/mach-imx/mach-mx27_3ds.c +++ /dev/null @@ -1,470 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. - * - * Author: Fabio Estevam <fabio.estevam@freescale.com> - */ - -/* - * This machine is known as: - * - i.MX27 3-Stack Development System - * - i.MX27 Platform Development Kit (i.MX27 PDK) - */ - -#include <linux/platform_device.h> -#include <linux/gpio.h> -#include <linux/gpio/machine.h> -#include <linux/irq.h> -#include <linux/usb/otg.h> -#include <linux/usb/ulpi.h> -#include <linux/delay.h> -#include <linux/mfd/mc13783.h> -#include <linux/spi/spi.h> -#include <linux/regulator/machine.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> - -#include "3ds_debugboard.h" -#include "common.h" -#include "devices-imx27.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx27.h" -#include "ulpi.h" - -#define SD1_EN_GPIO IMX_GPIO_NR(2, 25) -#define OTG_PHY_RESET_GPIO IMX_GPIO_NR(2, 23) -#define SPI2_SS0 IMX_GPIO_NR(4, 21) -#define PMIC_INT IMX_GPIO_NR(3, 14) -#define SPI1_SS0 IMX_GPIO_NR(4, 28) -#define SD1_CD IMX_GPIO_NR(2, 26) -#define LCD_RESET IMX_GPIO_NR(1, 3) -#define LCD_ENABLE IMX_GPIO_NR(1, 31) - -static const int mx27pdk_pins[] __initconst = { - /* UART1 */ - PE12_PF_UART1_TXD, - PE13_PF_UART1_RXD, - PE14_PF_UART1_CTS, - PE15_PF_UART1_RTS, - /* FEC */ - PD0_AIN_FEC_TXD0, - PD1_AIN_FEC_TXD1, - PD2_AIN_FEC_TXD2, - PD3_AIN_FEC_TXD3, - PD4_AOUT_FEC_RX_ER, - PD5_AOUT_FEC_RXD1, - PD6_AOUT_FEC_RXD2, - PD7_AOUT_FEC_RXD3, - PD8_AF_FEC_MDIO, - PD9_AIN_FEC_MDC, - PD10_AOUT_FEC_CRS, - PD11_AOUT_FEC_TX_CLK, - PD12_AOUT_FEC_RXD0, - PD13_AOUT_FEC_RX_DV, - PD14_AOUT_FEC_RX_CLK, - PD15_AOUT_FEC_COL, - PD16_AIN_FEC_TX_ER, - PF23_AIN_FEC_TX_EN, - /* SDHC1 */ - PE18_PF_SD1_D0, - PE19_PF_SD1_D1, - PE20_PF_SD1_D2, - PE21_PF_SD1_D3, - PE22_PF_SD1_CMD, - PE23_PF_SD1_CLK, - SD1_EN_GPIO | GPIO_GPIO | GPIO_OUT, - /* OTG */ - OTG_PHY_RESET_GPIO | GPIO_GPIO | GPIO_OUT, - PC7_PF_USBOTG_DATA5, - PC8_PF_USBOTG_DATA6, - PC9_PF_USBOTG_DATA0, - PC10_PF_USBOTG_DATA2, - PC11_PF_USBOTG_DATA1, - PC12_PF_USBOTG_DATA4, - PC13_PF_USBOTG_DATA3, - PE0_PF_USBOTG_NXT, - PE1_PF_USBOTG_STP, - PE2_PF_USBOTG_DIR, - PE24_PF_USBOTG_CLK, - PE25_PF_USBOTG_DATA7, - /* CSPI1 */ - PD31_PF_CSPI1_MOSI, - PD30_PF_CSPI1_MISO, - PD29_PF_CSPI1_SCLK, - PD25_PF_CSPI1_RDY, - SPI1_SS0 | GPIO_GPIO | GPIO_OUT, - /* CSPI2 */ - PD22_PF_CSPI2_SCLK, - PD23_PF_CSPI2_MISO, - PD24_PF_CSPI2_MOSI, - SPI2_SS0 | GPIO_GPIO | GPIO_OUT, - /* I2C1 */ - PD17_PF_I2C_DATA, - PD18_PF_I2C_CLK, - /* PMIC INT */ - PMIC_INT | GPIO_GPIO | GPIO_IN, - /* LCD */ - PA5_PF_LSCLK, - PA6_PF_LD0, - PA7_PF_LD1, - PA8_PF_LD2, - PA9_PF_LD3, - PA10_PF_LD4, - PA11_PF_LD5, - PA12_PF_LD6, - PA13_PF_LD7, - PA14_PF_LD8, - PA15_PF_LD9, - PA16_PF_LD10, - PA17_PF_LD11, - PA18_PF_LD12, - PA19_PF_LD13, - PA20_PF_LD14, - PA21_PF_LD15, - PA22_PF_LD16, - PA23_PF_LD17, - PA28_PF_HSYNC, - PA29_PF_VSYNC, - PA30_PF_CONTRAST, - LCD_ENABLE | GPIO_GPIO | GPIO_OUT, - LCD_RESET | GPIO_GPIO | GPIO_OUT, - /* SSI4 */ - PC16_PF_SSI4_FS, - PC17_PF_SSI4_RXD, - PC18_PF_SSI4_TXD, - PC19_PF_SSI4_CLK, -}; - -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -/* - * Matrix keyboard - */ - -static const uint32_t mx27_3ds_keymap[] = { - KEY(0, 0, KEY_UP), - KEY(0, 1, KEY_DOWN), - KEY(1, 0, KEY_RIGHT), - KEY(1, 1, KEY_LEFT), - KEY(1, 2, KEY_ENTER), - KEY(2, 0, KEY_F6), - KEY(2, 1, KEY_F8), - KEY(2, 2, KEY_F9), - KEY(2, 3, KEY_F10), -}; - -static const struct matrix_keymap_data mx27_3ds_keymap_data __initconst = { - .keymap = mx27_3ds_keymap, - .keymap_size = ARRAY_SIZE(mx27_3ds_keymap), -}; - -static int mx27_3ds_sdhc1_init(struct device *dev, irq_handler_t detect_irq, - void *data) -{ - return request_irq(gpio_to_irq(SD1_CD), detect_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "sdhc1-card-detect", data); -} - -static void mx27_3ds_sdhc1_exit(struct device *dev, void *data) -{ - free_irq(gpio_to_irq(SD1_CD), data); -} - -static const struct imxmmc_platform_data sdhc1_pdata __initconst = { - .init = mx27_3ds_sdhc1_init, - .exit = mx27_3ds_sdhc1_exit, -}; - -static void mx27_3ds_sdhc1_enable_level_translator(void) -{ - /* Turn on TXB0108 OE pin */ - gpio_request(SD1_EN_GPIO, "sd1_enable"); - gpio_direction_output(SD1_EN_GPIO, 1); -} - - -static int otg_phy_init(void) -{ - gpio_request(OTG_PHY_RESET_GPIO, "usb-otg-reset"); - gpio_direction_output(OTG_PHY_RESET_GPIO, 0); - mdelay(1); - gpio_set_value(OTG_PHY_RESET_GPIO, 1); - return 0; -} - -static int mx27_3ds_otg_init(struct platform_device *pdev) -{ - return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI); -} - -static struct mxc_usbh_platform_data otg_pdata __initdata = { - .init = mx27_3ds_otg_init, - .portsc = MXC_EHCI_MODE_ULPI, -}; - -static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_ULPI, -}; - -static bool otg_mode_host __initdata; - -static int __init mx27_3ds_otg_mode(char *options) -{ - if (!strcmp(options, "host")) - otg_mode_host = true; - else if (!strcmp(options, "device")) - otg_mode_host = false; - else - pr_info("otg_mode neither \"host\" nor \"device\". " - "Defaulting to device\n"); - return 1; -} -__setup("otg_mode=", mx27_3ds_otg_mode); - -/* Regulators */ -static struct regulator_init_data gpo_init = { - .constraints = { - .boot_on = 1, - .always_on = 1, - } -}; - -static struct regulator_consumer_supply vmmc1_consumers[] = { - REGULATOR_SUPPLY("vcore", "spi0.0"), -}; - -static struct regulator_init_data vmmc1_init = { - .constraints = { - .min_uV = 2800000, - .max_uV = 2800000, - .apply_uV = 1, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(vmmc1_consumers), - .consumer_supplies = vmmc1_consumers, -}; - -static struct regulator_consumer_supply vgen_consumers[] = { - REGULATOR_SUPPLY("vdd", "spi0.0"), -}; - -static struct regulator_init_data vgen_init = { - .constraints = { - .min_uV = 1800000, - .max_uV = 1800000, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, - }, - .num_consumer_supplies = ARRAY_SIZE(vgen_consumers), - .consumer_supplies = vgen_consumers, -}; - -static struct mc13xxx_regulator_init_data mx27_3ds_regulators[] = { - { - .id = MC13783_REG_VMMC1, - .init_data = &vmmc1_init, - }, { - .id = MC13783_REG_VGEN, - .init_data = &vgen_init, - }, { - .id = MC13783_REG_GPO1, /* Turn on 1.8V */ - .init_data = &gpo_init, - }, { - .id = MC13783_REG_GPO3, /* Turn on 3.3V */ - .init_data = &gpo_init, - }, -}; - -/* MC13783 */ -static struct mc13xxx_codec_platform_data mx27_3ds_codec = { - .dac_ssi_port = MC13783_SSI1_PORT, - .adc_ssi_port = MC13783_SSI1_PORT, -}; - -static struct mc13xxx_platform_data mc13783_pdata = { - .regulators = { - .regulators = mx27_3ds_regulators, - .num_regulators = ARRAY_SIZE(mx27_3ds_regulators), - - }, - .flags = MC13XXX_USE_TOUCHSCREEN | MC13XXX_USE_RTC | - MC13XXX_USE_CODEC, - .codec = &mx27_3ds_codec, -}; - -static struct imx_ssi_platform_data mx27_3ds_ssi_pdata = { - .flags = IMX_SSI_DMA | IMX_SSI_NET, -}; - -/* SPI */ -static struct gpiod_lookup_table mx27_spi1_gpiod_table = { - .dev_id = "imx27-cspi.0", /* Actual device name for spi1 */ - .table = { - /* - * The i.MX27 has the i.MX21 GPIO controller, the SPI1 CS GPIO - * SPI1_SS0 is numbered IMX_GPIO_NR(4, 28). - * - * This is in "bank 4" which is subtracted by one in the macro - * so this is actually bank 3 on "imx21-gpio.3". - */ - GPIO_LOOKUP_IDX("imx21-gpio.3", 28, "cs", 0, GPIO_ACTIVE_LOW), - { }, - }, -}; - -static struct gpiod_lookup_table mx27_spi2_gpiod_table = { - .dev_id = "imx27-cspi.1", /* Actual device name for spi2 */ - .table = { - /* - * The i.MX27 has the i.MX21 GPIO controller, the SPI2 CS GPIO - * SPI2_SS0 is numbered IMX_GPIO_NR(4, 21). - * - * This is in "bank 4" which is subtracted by one in the macro - * so this is actually bank 3 on "imx21-gpio.3". - */ - GPIO_LOOKUP_IDX("imx21-gpio.3", 21, "cs", 0, GPIO_ACTIVE_LOW), - { }, - }, -}; - -static struct imx_fb_videomode mx27_3ds_modes[] = { - { /* 480x640 @ 60 Hz */ - .mode = { - .name = "Epson-VGA", - .refresh = 60, - .xres = 480, - .yres = 640, - .pixclock = 41701, - .left_margin = 20, - .right_margin = 41, - .upper_margin = 10, - .lower_margin = 5, - .hsync_len = 20, - .vsync_len = 10, - .sync = FB_SYNC_OE_ACT_HIGH | - FB_SYNC_CLK_INVERT, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, - .bpp = 16, - .pcr = 0xFAC08B82, - }, -}; - -static const struct imx_fb_platform_data mx27_3ds_fb_data __initconst = { - .mode = mx27_3ds_modes, - .num_modes = ARRAY_SIZE(mx27_3ds_modes), - .pwmr = 0x00A903FF, - .lscr1 = 0x00120300, - .dmacr = 0x00020010, -}; - -/* LCD */ -static struct gpiod_lookup_table mx27_3ds_lcd_gpiod_table = { - .dev_id = "spi0.0", /* Bus 0 chipselect 0 */ - .table = { - /* - * The i.MX27 has the i.MX21 GPIO controller, the GPIOs - * numbered IMX_GPIO_NR(1, 3) and IMX_GPIO_NR(1, 31) - * are in "bank 1" which is subtracted by one in the macro - * so these are actually bank 0 on "imx21-gpio.0". - */ - GPIO_LOOKUP("imx21-gpio.0", 3, "reset", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("imx21-gpio.0", 31, "enable", GPIO_ACTIVE_HIGH), - { }, - }, -}; - -static struct spi_board_info mx27_3ds_spi_devs[] __initdata = { - { - .modalias = "mc13783", - .max_speed_hz = 1000000, - .bus_num = 1, - .chip_select = 0, /* SS0 */ - .platform_data = &mc13783_pdata, - /* irq number is run-time assigned */ - .mode = SPI_CS_HIGH, - }, { - .modalias = "l4f00242t03", - .max_speed_hz = 5000000, - .bus_num = 0, - .chip_select = 0, /* SS0 */ - }, -}; - -static const struct imxi2c_platform_data mx27_3ds_i2c0_data __initconst = { - .bitrate = 100000, -}; - -static void __init mx27pdk_init(void) -{ - imx27_soc_init(); - - mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins), - "mx27pdk"); - imx27_add_imx_uart0(&uart_pdata); - imx27_add_fec(NULL); - imx27_add_imx_keypad(&mx27_3ds_keymap_data); - imx27_add_imx2_wdt(); - - imx27_add_spi_imx1(&mx27_spi2_gpiod_table); - imx27_add_spi_imx0(&mx27_spi1_gpiod_table); - - imx27_add_imx_i2c(0, &mx27_3ds_i2c0_data); - imx27_add_imx_fb(&mx27_3ds_fb_data); - - imx27_add_imx_ssi(0, &mx27_3ds_ssi_pdata); -} - -static void __init mx27pdk_late_init(void) -{ - mx27_3ds_sdhc1_enable_level_translator(); - imx27_add_mxc_mmc(0, &sdhc1_pdata); - - otg_phy_init(); - - if (otg_mode_host) { - otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | - ULPI_OTG_DRVVBUS_EXT); - - if (otg_pdata.otg) - imx27_add_mxc_ehci_otg(&otg_pdata); - } - - if (!otg_mode_host) - imx27_add_fsl_usb2_udc(&otg_device_pdata); - - gpiod_add_lookup_table(&mx27_3ds_lcd_gpiod_table); - mx27_3ds_spi_devs[0].irq = gpio_to_irq(PMIC_INT); - spi_register_board_info(mx27_3ds_spi_devs, - ARRAY_SIZE(mx27_3ds_spi_devs)); - - if (mxc_expio_init(MX27_CS5_BASE_ADDR, IMX_GPIO_NR(3, 28))) - pr_warn("Init of the debugboard failed, all devices on the debugboard are unusable.\n"); - - - imx_add_platform_device("imx_mc13783", 0, NULL, 0, NULL, 0); -} - -static void __init mx27pdk_timer_init(void) -{ - mx27_clocks_init(26000000); -} - -MACHINE_START(MX27_3DS, "Freescale MX27PDK") - /* maintainer: Freescale Semiconductor, Inc. */ - .atag_offset = 0x100, - .map_io = mx27_map_io, - .init_early = imx27_init_early, - .init_irq = mx27_init_irq, - .init_time = mx27pdk_timer_init, - .init_machine = mx27pdk_init, - .init_late = mx27pdk_late_init, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c deleted file mode 100644 index ba202f95bcdf..000000000000 --- a/arch/arm/mach-imx/mach-mx27ads.c +++ /dev/null @@ -1,407 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright (C) 2002 Shane Nay (shane@minirl.com) - * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. - */ -#include <linux/gpio/driver.h> -/* Needed for gpio_to_irq() */ -#include <linux/gpio.h> -#include <linux/gpio/machine.h> -#include <linux/platform_device.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/map.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/physmap.h> -#include <linux/i2c.h> -#include <linux/irq.h> - -#include <linux/regulator/fixed.h> -#include <linux/regulator/machine.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/mach/map.h> - -#include "common.h" -#include "devices-imx27.h" -#include "hardware.h" -#include "iomux-mx27.h" - -/* - * Base address of PBC controller, CS4 - */ -#define PBC_BASE_ADDRESS 0xf4300000 -#define PBC_REG_ADDR(offset) (void __force __iomem *) \ - (PBC_BASE_ADDRESS + (offset)) - -/* When the PBC address connection is fixed in h/w, defined as 1 */ -#define PBC_ADDR_SH 0 - -/* Offsets for the PBC Controller register */ -/* - * PBC Board version register offset - */ -#define PBC_VERSION_REG PBC_REG_ADDR(0x00000 >> PBC_ADDR_SH) -/* - * PBC Board control register 1 set address. - */ -#define PBC_BCTRL1_SET_REG PBC_REG_ADDR(0x00008 >> PBC_ADDR_SH) -/* - * PBC Board control register 1 clear address. - */ -#define PBC_BCTRL1_CLEAR_REG PBC_REG_ADDR(0x0000C >> PBC_ADDR_SH) - -/* PBC Board Control Register 1 bit definitions */ -#define PBC_BCTRL1_LCDON 0x0800 /* Enable the LCD */ - -/* to determine the correct external crystal reference */ -#define CKIH_27MHZ_BIT_SET (1 << 3) - -static const int mx27ads_pins[] __initconst = { - /* UART0 */ - PE12_PF_UART1_TXD, - PE13_PF_UART1_RXD, - PE14_PF_UART1_CTS, - PE15_PF_UART1_RTS, - /* UART1 */ - PE3_PF_UART2_CTS, - PE4_PF_UART2_RTS, - PE6_PF_UART2_TXD, - PE7_PF_UART2_RXD, - /* UART2 */ - PE8_PF_UART3_TXD, - PE9_PF_UART3_RXD, - PE10_PF_UART3_CTS, - PE11_PF_UART3_RTS, - /* UART3 */ - PB26_AF_UART4_RTS, - PB28_AF_UART4_TXD, - PB29_AF_UART4_CTS, - PB31_AF_UART4_RXD, - /* UART4 */ - PB18_AF_UART5_TXD, - PB19_AF_UART5_RXD, - PB20_AF_UART5_CTS, - PB21_AF_UART5_RTS, - /* UART5 */ - PB10_AF_UART6_TXD, - PB12_AF_UART6_CTS, - PB11_AF_UART6_RXD, - PB13_AF_UART6_RTS, - /* FEC */ - PD0_AIN_FEC_TXD0, - PD1_AIN_FEC_TXD1, - PD2_AIN_FEC_TXD2, - PD3_AIN_FEC_TXD3, - PD4_AOUT_FEC_RX_ER, - PD5_AOUT_FEC_RXD1, - PD6_AOUT_FEC_RXD2, - PD7_AOUT_FEC_RXD3, - PD8_AF_FEC_MDIO, - PD9_AIN_FEC_MDC, - PD10_AOUT_FEC_CRS, - PD11_AOUT_FEC_TX_CLK, - PD12_AOUT_FEC_RXD0, - PD13_AOUT_FEC_RX_DV, - PD14_AOUT_FEC_RX_CLK, - PD15_AOUT_FEC_COL, - PD16_AIN_FEC_TX_ER, - PF23_AIN_FEC_TX_EN, - /* I2C2 */ - PC5_PF_I2C2_SDA, - PC6_PF_I2C2_SCL, - /* FB */ - PA5_PF_LSCLK, - PA6_PF_LD0, - PA7_PF_LD1, - PA8_PF_LD2, - PA9_PF_LD3, - PA10_PF_LD4, - PA11_PF_LD5, - PA12_PF_LD6, - PA13_PF_LD7, - PA14_PF_LD8, - PA15_PF_LD9, - PA16_PF_LD10, - PA17_PF_LD11, - PA18_PF_LD12, - PA19_PF_LD13, - PA20_PF_LD14, - PA21_PF_LD15, - PA22_PF_LD16, - PA23_PF_LD17, - PA24_PF_REV, - PA25_PF_CLS, - PA26_PF_PS, - PA27_PF_SPL_SPR, - PA28_PF_HSYNC, - PA29_PF_VSYNC, - PA30_PF_CONTRAST, - PA31_PF_OE_ACD, - /* OWIRE */ - PE16_AF_OWIRE, - /* SDHC1*/ - PE18_PF_SD1_D0, - PE19_PF_SD1_D1, - PE20_PF_SD1_D2, - PE21_PF_SD1_D3, - PE22_PF_SD1_CMD, - PE23_PF_SD1_CLK, - /* SDHC2*/ - PB4_PF_SD2_D0, - PB5_PF_SD2_D1, - PB6_PF_SD2_D2, - PB7_PF_SD2_D3, - PB8_PF_SD2_CMD, - PB9_PF_SD2_CLK, -}; - -static const struct mxc_nand_platform_data -mx27ads_nand_board_info __initconst = { - .width = 1, - .hw_ecc = 1, -}; - -/* ADS's NOR flash */ -static struct physmap_flash_data mx27ads_flash_data = { - .width = 2, -}; - -static struct resource mx27ads_flash_resource = { - .start = 0xc0000000, - .end = 0xc0000000 + 0x02000000 - 1, - .flags = IORESOURCE_MEM, - -}; - -static struct platform_device mx27ads_nor_mtd_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &mx27ads_flash_data, - }, - .num_resources = 1, - .resource = &mx27ads_flash_resource, -}; - -static const struct imxi2c_platform_data mx27ads_i2c1_data __initconst = { - .bitrate = 100000, -}; - -static struct i2c_board_info mx27ads_i2c_devices[] = { -}; - -static void vgpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - if (value) - imx_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG); - else - imx_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); -} - -static int vgpio_dir_out(struct gpio_chip *chip, unsigned offset, int value) -{ - return 0; -} - -#define MX27ADS_LCD_GPIO (6 * 32) - -static struct regulator_consumer_supply mx27ads_lcd_regulator_consumer = - REGULATOR_SUPPLY("lcd", "imx-fb.0"); - -static struct regulator_init_data mx27ads_lcd_regulator_init_data = { - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS, -}, - .consumer_supplies = &mx27ads_lcd_regulator_consumer, - .num_consumer_supplies = 1, -}; - -static struct fixed_voltage_config mx27ads_lcd_regulator_pdata = { - .supply_name = "LCD", - .microvolts = 3300000, - .init_data = &mx27ads_lcd_regulator_init_data, -}; - -static struct gpiod_lookup_table mx27ads_lcd_regulator_gpiod_table = { - .dev_id = "reg-fixed-voltage.0", /* Let's hope ID 0 is what we get */ - .table = { - GPIO_LOOKUP("LCD", 0, NULL, GPIO_ACTIVE_LOW), - { }, - }, -}; - -static void __init mx27ads_regulator_init(void) -{ - struct gpio_chip *vchip; - - vchip = kzalloc(sizeof(*vchip), GFP_KERNEL); - vchip->owner = THIS_MODULE; - vchip->label = "LCD"; - vchip->base = MX27ADS_LCD_GPIO; - vchip->ngpio = 1; - vchip->direction_output = vgpio_dir_out; - vchip->set = vgpio_set; - gpiochip_add_data(vchip, NULL); - - gpiod_add_lookup_table(&mx27ads_lcd_regulator_gpiod_table); - - platform_device_register_data(NULL, "reg-fixed-voltage", - PLATFORM_DEVID_AUTO, - &mx27ads_lcd_regulator_pdata, - sizeof(mx27ads_lcd_regulator_pdata)); -} - -static struct imx_fb_videomode mx27ads_modes[] = { - { - .mode = { - .name = "Sharp-LQ035Q7", - .refresh = 60, - .xres = 240, - .yres = 320, - .pixclock = 188679, /* in ps (5.3MHz) */ - .hsync_len = 1, - .left_margin = 9, - .right_margin = 16, - .vsync_len = 1, - .upper_margin = 7, - .lower_margin = 9, - }, - .bpp = 16, - .pcr = 0xFB008BC0, - }, -}; - -static const struct imx_fb_platform_data mx27ads_fb_data __initconst = { - .mode = mx27ads_modes, - .num_modes = ARRAY_SIZE(mx27ads_modes), - - /* - * - HSYNC active high - * - VSYNC active high - * - clk notenabled while idle - * - clock inverted - * - data not inverted - * - data enable low active - * - enable sharp mode - */ - .pwmr = 0x00A903FF, - .lscr1 = 0x00120300, - .dmacr = 0x00020010, -}; - -static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq, - void *data) -{ - return request_irq(gpio_to_irq(IMX_GPIO_NR(5, 21)), detect_irq, - IRQF_TRIGGER_RISING, "sdhc1-card-detect", data); -} - -static int mx27ads_sdhc2_init(struct device *dev, irq_handler_t detect_irq, - void *data) -{ - return request_irq(gpio_to_irq(IMX_GPIO_NR(2, 7)), detect_irq, - IRQF_TRIGGER_RISING, "sdhc2-card-detect", data); -} - -static void mx27ads_sdhc1_exit(struct device *dev, void *data) -{ - free_irq(gpio_to_irq(IMX_GPIO_NR(5, 21)), data); -} - -static void mx27ads_sdhc2_exit(struct device *dev, void *data) -{ - free_irq(gpio_to_irq(IMX_GPIO_NR(2, 7)), data); -} - -static const struct imxmmc_platform_data sdhc1_pdata __initconst = { - .init = mx27ads_sdhc1_init, - .exit = mx27ads_sdhc1_exit, -}; - -static const struct imxmmc_platform_data sdhc2_pdata __initconst = { - .init = mx27ads_sdhc2_init, - .exit = mx27ads_sdhc2_exit, -}; - -static struct platform_device *platform_devices[] __initdata = { - &mx27ads_nor_mtd_device, -}; - -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static void __init mx27ads_board_init(void) -{ - imx27_soc_init(); - - mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins), - "mx27ads"); - - imx27_add_imx_uart0(&uart_pdata); - imx27_add_imx_uart1(&uart_pdata); - imx27_add_imx_uart2(&uart_pdata); - imx27_add_imx_uart3(&uart_pdata); - imx27_add_imx_uart4(&uart_pdata); - imx27_add_imx_uart5(&uart_pdata); - imx27_add_mxc_nand(&mx27ads_nand_board_info); - - /* only the i2c master 1 is used on this CPU card */ - i2c_register_board_info(1, mx27ads_i2c_devices, - ARRAY_SIZE(mx27ads_i2c_devices)); - imx27_add_imx_i2c(1, &mx27ads_i2c1_data); - imx27_add_imx_fb(&mx27ads_fb_data); - - imx27_add_fec(NULL); - imx27_add_mxc_w1(); -} - -static void __init mx27ads_late_init(void) -{ - mx27ads_regulator_init(); - - imx27_add_mxc_mmc(0, &sdhc1_pdata); - imx27_add_mxc_mmc(1, &sdhc2_pdata); - - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); -} - -static void __init mx27ads_timer_init(void) -{ - unsigned long fref = 26000000; - - if ((imx_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) - fref = 27000000; - - mx27_clocks_init(fref); -} - -static struct map_desc mx27ads_io_desc[] __initdata = { - { - .virtual = PBC_BASE_ADDRESS, - .pfn = __phys_to_pfn(MX27_CS4_BASE_ADDR), - .length = SZ_1M, - .type = MT_DEVICE, - }, -}; - -static void __init mx27ads_map_io(void) -{ - mx27_map_io(); - iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc)); -} - -MACHINE_START(MX27ADS, "Freescale i.MX27ADS") - /* maintainer: Freescale Semiconductor, Inc. */ - .atag_offset = 0x100, - .map_io = mx27ads_map_io, - .init_early = imx27_init_early, - .init_irq = mx27_init_irq, - .init_time = mx27ads_timer_init, - .init_machine = mx27ads_board_init, - .init_late = mx27ads_late_init, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c deleted file mode 100644 index 23e63d3b4c6a..000000000000 --- a/arch/arm/mach-imx/mach-mx31_3ds.c +++ /dev/null @@ -1,615 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -#include <linux/delay.h> -#include <linux/dma-mapping.h> -#include <linux/types.h> -#include <linux/init.h> -#include <linux/clk.h> -#include <linux/irq.h> -#include <linux/gpio.h> -#include <linux/gpio/machine.h> -#include <linux/platform_device.h> -#include <linux/mfd/mc13783.h> -#include <linux/spi/spi.h> -#include <linux/regulator/machine.h> -#include <linux/usb/otg.h> -#include <linux/usb/ulpi.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/memory.h> -#include <asm/mach/map.h> - -#include "3ds_debugboard.h" -#include "common.h" -#include "devices-imx31.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx3.h" -#include "ulpi.h" - -static int mx31_3ds_pins[] = { - /* UART1 */ - MX31_PIN_CTS1__CTS1, - MX31_PIN_RTS1__RTS1, - MX31_PIN_TXD1__TXD1, - MX31_PIN_RXD1__RXD1, - IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO), - /*SPI0*/ - IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_ALT1), - IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_ALT1), - /* SPI 1 */ - MX31_PIN_CSPI2_SCLK__SCLK, - MX31_PIN_CSPI2_MOSI__MOSI, - MX31_PIN_CSPI2_MISO__MISO, - MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, - MX31_PIN_CSPI2_SS0__SS0, - MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */ - /* MC13783 IRQ */ - IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO), - /* USB OTG reset */ - IOMUX_MODE(MX31_PIN_USB_PWR, IOMUX_CONFIG_GPIO), - /* USB OTG */ - MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, - MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, - MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, - MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, - MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, - MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, - MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, - MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, - MX31_PIN_USBOTG_CLK__USBOTG_CLK, - MX31_PIN_USBOTG_DIR__USBOTG_DIR, - MX31_PIN_USBOTG_NXT__USBOTG_NXT, - MX31_PIN_USBOTG_STP__USBOTG_STP, - /*Keyboard*/ - MX31_PIN_KEY_ROW0_KEY_ROW0, - MX31_PIN_KEY_ROW1_KEY_ROW1, - MX31_PIN_KEY_ROW2_KEY_ROW2, - MX31_PIN_KEY_COL0_KEY_COL0, - MX31_PIN_KEY_COL1_KEY_COL1, - MX31_PIN_KEY_COL2_KEY_COL2, - MX31_PIN_KEY_COL3_KEY_COL3, - /* USB Host 2 */ - IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_PC_VS2, IOMUX_CONFIG_ALT1), - IOMUX_MODE(MX31_PIN_PC_BVD1, IOMUX_CONFIG_ALT1), - IOMUX_MODE(MX31_PIN_PC_BVD2, IOMUX_CONFIG_ALT1), - IOMUX_MODE(MX31_PIN_PC_RST, IOMUX_CONFIG_ALT1), - IOMUX_MODE(MX31_PIN_IOIS16, IOMUX_CONFIG_ALT1), - IOMUX_MODE(MX31_PIN_PC_RW_B, IOMUX_CONFIG_ALT1), - /* USB Host2 reset */ - IOMUX_MODE(MX31_PIN_USB_BYP, IOMUX_CONFIG_GPIO), - /* I2C1 */ - MX31_PIN_I2C_CLK__I2C1_SCL, - MX31_PIN_I2C_DAT__I2C1_SDA, - /* SDHC1 */ - MX31_PIN_SD1_DATA3__SD1_DATA3, - MX31_PIN_SD1_DATA2__SD1_DATA2, - MX31_PIN_SD1_DATA1__SD1_DATA1, - MX31_PIN_SD1_DATA0__SD1_DATA0, - MX31_PIN_SD1_CLK__SD1_CLK, - MX31_PIN_SD1_CMD__SD1_CMD, - MX31_PIN_GPIO3_1__GPIO3_1, /* Card detect */ - MX31_PIN_GPIO3_0__GPIO3_0, /* OE */ - /* Framebuffer */ - MX31_PIN_LD0__LD0, - MX31_PIN_LD1__LD1, - MX31_PIN_LD2__LD2, - MX31_PIN_LD3__LD3, - MX31_PIN_LD4__LD4, - MX31_PIN_LD5__LD5, - MX31_PIN_LD6__LD6, - MX31_PIN_LD7__LD7, - MX31_PIN_LD8__LD8, - MX31_PIN_LD9__LD9, - MX31_PIN_LD10__LD10, - MX31_PIN_LD11__LD11, - MX31_PIN_LD12__LD12, - MX31_PIN_LD13__LD13, - MX31_PIN_LD14__LD14, - MX31_PIN_LD15__LD15, - MX31_PIN_LD16__LD16, - MX31_PIN_LD17__LD17, - MX31_PIN_VSYNC3__VSYNC3, - MX31_PIN_HSYNC__HSYNC, - MX31_PIN_FPSHIFT__FPSHIFT, - MX31_PIN_CONTRAST__CONTRAST, - /* SSI */ - MX31_PIN_STXD4__STXD4, - MX31_PIN_SRXD4__SRXD4, - MX31_PIN_SCK4__SCK4, - MX31_PIN_SFS4__SFS4, -}; - -/* - * FB support - */ -static const struct fb_videomode fb_modedb[] = { - { /* 480x640 @ 60 Hz */ - .name = "Epson-VGA", - .refresh = 60, - .xres = 480, - .yres = 640, - .pixclock = 41701, - .left_margin = 20, - .right_margin = 41, - .upper_margin = 10, - .lower_margin = 5, - .hsync_len = 20, - .vsync_len = 10, - .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, -}; - -static struct mx3fb_platform_data mx3fb_pdata __initdata = { - .name = "Epson-VGA", - .mode = fb_modedb, - .num_modes = ARRAY_SIZE(fb_modedb), -}; - -/* LCD */ -static struct gpiod_lookup_table mx31_3ds_lcd_gpiod_table = { - .dev_id = "spi0.2", /* Bus 0 chipselect 2 */ - .table = { - /* - * "reset" has IOMUX_TO_GPIO(IOMUX_PIN(88, 28)). - * The macro only shifts 88 to bits 9..16 and then - * mask it and shift it back. The GPIO number is 88. - * 88 is 2*32+24 - */ - GPIO_LOOKUP("imx31-gpio.2", 24, "reset", GPIO_ACTIVE_HIGH), - /* - * Same reasoning as above for - * IOMUX_TO_GPIO(IOMUX_PIN(89, 27), pin 89 is 2*32+25. - */ - GPIO_LOOKUP("imx31-gpio.2", 25, "enable", GPIO_ACTIVE_HIGH), - { }, - }, -}; - -/* - * Support for SD card slot in personality board - */ -#define MX31_3DS_GPIO_SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_GPIO3_1) -#define MX31_3DS_GPIO_SDHC1_BE IOMUX_TO_GPIO(MX31_PIN_GPIO3_0) - -static struct gpio mx31_3ds_sdhc1_gpios[] = { - { MX31_3DS_GPIO_SDHC1_CD, GPIOF_IN, "sdhc1-card-detect" }, - { MX31_3DS_GPIO_SDHC1_BE, GPIOF_OUT_INIT_LOW, "sdhc1-bus-en" }, -}; - -static int mx31_3ds_sdhc1_init(struct device *dev, - irq_handler_t detect_irq, - void *data) -{ - int ret; - - ret = gpio_request_array(mx31_3ds_sdhc1_gpios, - ARRAY_SIZE(mx31_3ds_sdhc1_gpios)); - if (ret) { - pr_warn("Unable to request the SD/MMC GPIOs.\n"); - return ret; - } - - ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)), - detect_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - "sdhc1-detect", data); - if (ret) { - pr_warn("Unable to request the SD/MMC card-detect IRQ.\n"); - goto gpio_free; - } - - return 0; - -gpio_free: - gpio_free_array(mx31_3ds_sdhc1_gpios, - ARRAY_SIZE(mx31_3ds_sdhc1_gpios)); - return ret; -} - -static void mx31_3ds_sdhc1_exit(struct device *dev, void *data) -{ - free_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)), data); - gpio_free_array(mx31_3ds_sdhc1_gpios, - ARRAY_SIZE(mx31_3ds_sdhc1_gpios)); -} - -static void mx31_3ds_sdhc1_setpower(struct device *dev, unsigned int vdd) -{ - /* - * While the voltage stuff is done by the driver, activate the - * Buffer Enable Pin only if there is a card in slot to fix the card - * voltage issue caused by bi-directional chip TXB0108 on 3Stack. - * Done here because at this stage we have for sure a debounced value - * of the presence of the card, showed by the value of vdd. - * 7 == ilog2(MMC_VDD_165_195) - */ - if (vdd > 7) - gpio_set_value(MX31_3DS_GPIO_SDHC1_BE, 1); - else - gpio_set_value(MX31_3DS_GPIO_SDHC1_BE, 0); -} - -static struct imxmmc_platform_data sdhc1_pdata = { - .init = mx31_3ds_sdhc1_init, - .exit = mx31_3ds_sdhc1_exit, - .setpower = mx31_3ds_sdhc1_setpower, -}; - -/* - * Matrix keyboard - */ - -static const uint32_t mx31_3ds_keymap[] = { - KEY(0, 0, KEY_UP), - KEY(0, 1, KEY_DOWN), - KEY(1, 0, KEY_RIGHT), - KEY(1, 1, KEY_LEFT), - KEY(1, 2, KEY_ENTER), - KEY(2, 0, KEY_F6), - KEY(2, 1, KEY_F8), - KEY(2, 2, KEY_F9), - KEY(2, 3, KEY_F10), -}; - -static const struct matrix_keymap_data mx31_3ds_keymap_data __initconst = { - .keymap = mx31_3ds_keymap, - .keymap_size = ARRAY_SIZE(mx31_3ds_keymap), -}; - -/* Regulators */ -static struct regulator_init_data pwgtx_init = { - .constraints = { - .boot_on = 1, - .always_on = 1, - }, -}; - -static struct regulator_init_data gpo_init = { - .constraints = { - .boot_on = 1, - .always_on = 1, - } -}; - -static struct regulator_consumer_supply vmmc2_consumers[] = { - REGULATOR_SUPPLY("vmmc", "imx31-mmc.0"), -}; - -static struct regulator_init_data vmmc2_init = { - .constraints = { - .min_uV = 3000000, - .max_uV = 3000000, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(vmmc2_consumers), - .consumer_supplies = vmmc2_consumers, -}; - -static struct regulator_consumer_supply vmmc1_consumers[] = { - REGULATOR_SUPPLY("vcore", "spi0.0"), -}; - -static struct regulator_init_data vmmc1_init = { - .constraints = { - .min_uV = 2800000, - .max_uV = 2800000, - .apply_uV = 1, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(vmmc1_consumers), - .consumer_supplies = vmmc1_consumers, -}; - -static struct regulator_consumer_supply vgen_consumers[] = { - REGULATOR_SUPPLY("vdd", "spi0.0"), -}; - -static struct regulator_init_data vgen_init = { - .constraints = { - .min_uV = 1800000, - .max_uV = 1800000, - .apply_uV = 1, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(vgen_consumers), - .consumer_supplies = vgen_consumers, -}; - -static struct mc13xxx_regulator_init_data mx31_3ds_regulators[] = { - { - .id = MC13783_REG_PWGT1SPI, /* Power Gate for ARM core. */ - .init_data = &pwgtx_init, - }, { - .id = MC13783_REG_PWGT2SPI, /* Power Gate for L2 Cache. */ - .init_data = &pwgtx_init, - }, { - - .id = MC13783_REG_GPO1, /* Turn on 1.8V */ - .init_data = &gpo_init, - }, { - .id = MC13783_REG_GPO3, /* Turn on 3.3V */ - .init_data = &gpo_init, - }, { - .id = MC13783_REG_VMMC2, /* Power MMC/SD, WiFi/Bluetooth. */ - .init_data = &vmmc2_init, - }, { - .id = MC13783_REG_VMMC1, /* Power LCD, CMOS, FM, GPS, Accel. */ - .init_data = &vmmc1_init, - }, { - .id = MC13783_REG_VGEN, /* Power LCD */ - .init_data = &vgen_init, - }, -}; - -/* MC13783 */ -static struct mc13xxx_codec_platform_data mx31_3ds_codec = { - .dac_ssi_port = MC13783_SSI1_PORT, - .adc_ssi_port = MC13783_SSI1_PORT, -}; - -static struct mc13xxx_platform_data mc13783_pdata = { - .regulators = { - .regulators = mx31_3ds_regulators, - .num_regulators = ARRAY_SIZE(mx31_3ds_regulators), - }, - .codec = &mx31_3ds_codec, - .flags = MC13XXX_USE_TOUCHSCREEN | MC13XXX_USE_RTC | MC13XXX_USE_CODEC, - -}; - -static struct imx_ssi_platform_data mx31_3ds_ssi_pdata = { - .flags = IMX_SSI_DMA | IMX_SSI_NET, -}; - -static struct spi_board_info mx31_3ds_spi_devs[] __initdata = { - { - .modalias = "mc13783", - .max_speed_hz = 1000000, - .bus_num = 1, - .chip_select = 2, /* SS2 */ - .platform_data = &mc13783_pdata, - /* irq number is run-time assigned */ - .mode = SPI_CS_HIGH, - }, { - .modalias = "l4f00242t03", - .max_speed_hz = 5000000, - .bus_num = 0, - .chip_select = 2, /* SS2 */ - }, -}; - -/* - * NAND Flash - */ -static const struct mxc_nand_platform_data -mx31_3ds_nand_board_info __initconst = { - .width = 1, - .hw_ecc = 1, -#ifdef CONFIG_MACH_MX31_3DS_MXC_NAND_USE_BBT - .flash_bbt = 1, -#endif -}; - -/* - * USB OTG - */ - -#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ - PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) - -#define USBOTG_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_PWR) -#define USBH2_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_BYP) - -static int mx31_3ds_usbotg_init(void) -{ - int err; - - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG); - - err = gpio_request(USBOTG_RST_B, "otgusb-reset"); - if (err) { - pr_err("Failed to request the USB OTG reset gpio\n"); - return err; - } - - err = gpio_direction_output(USBOTG_RST_B, 0); - if (err) { - pr_err("Failed to drive the USB OTG reset gpio\n"); - goto usbotg_free_reset; - } - - mdelay(1); - gpio_set_value(USBOTG_RST_B, 1); - return 0; - -usbotg_free_reset: - gpio_free(USBOTG_RST_B); - return err; -} - -static int mx31_3ds_otg_init(struct platform_device *pdev) -{ - return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); -} - -static int mx31_3ds_host2_init(struct platform_device *pdev) -{ - int err; - - mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_PC_VS2, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_PC_BVD1, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_PC_BVD2, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_PC_RST, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_IOIS16, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_PC_RW_B, USB_PAD_CFG); - - err = gpio_request(USBH2_RST_B, "usbh2-reset"); - if (err) { - pr_err("Failed to request the USB Host 2 reset gpio\n"); - return err; - } - - err = gpio_direction_output(USBH2_RST_B, 0); - if (err) { - pr_err("Failed to drive the USB Host 2 reset gpio\n"); - goto usbotg_free_reset; - } - - mdelay(1); - gpio_set_value(USBH2_RST_B, 1); - - mdelay(10); - - return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); - -usbotg_free_reset: - gpio_free(USBH2_RST_B); - return err; -} - -static struct mxc_usbh_platform_data otg_pdata __initdata = { - .init = mx31_3ds_otg_init, - .portsc = MXC_EHCI_MODE_ULPI, -}; - -static struct mxc_usbh_platform_data usbh2_pdata __initdata = { - .init = mx31_3ds_host2_init, - .portsc = MXC_EHCI_MODE_ULPI, -}; - -static const struct fsl_usb2_platform_data usbotg_pdata __initconst = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_ULPI, -}; - -static bool otg_mode_host __initdata; - -static int __init mx31_3ds_otg_mode(char *options) -{ - if (!strcmp(options, "host")) - otg_mode_host = true; - else if (!strcmp(options, "device")) - otg_mode_host = false; - else - pr_info("otg_mode neither \"host\" nor \"device\". " - "Defaulting to device\n"); - return 1; -} -__setup("otg_mode=", mx31_3ds_otg_mode); - -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static const struct imxi2c_platform_data mx31_3ds_i2c0_data __initconst = { - .bitrate = 100000, -}; - -static void __init mx31_3ds_init(void) -{ - imx31_soc_init(); - - /* Configure SPI1 IOMUX */ - mxc_iomux_set_gpr(MUX_PGP_CSPI_BB, true); - - mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins), - "mx31_3ds"); - - imx31_add_imx_uart0(&uart_pdata); - imx31_add_mxc_nand(&mx31_3ds_nand_board_info); - - imx31_add_spi_imx1(NULL); - - imx31_add_imx_keypad(&mx31_3ds_keymap_data); - - imx31_add_imx2_wdt(); - imx31_add_imx_i2c0(&mx31_3ds_i2c0_data); - - imx31_add_spi_imx0(NULL); - imx31_add_ipu_core(); - imx31_add_mx3_sdc_fb(&mx3fb_pdata); - - imx31_add_imx_ssi(0, &mx31_3ds_ssi_pdata); - - imx_add_platform_device("imx_mc13783", 0, NULL, 0, NULL, 0); -} - -static void __init mx31_3ds_late(void) -{ - gpiod_add_lookup_table(&mx31_3ds_lcd_gpiod_table); - mx31_3ds_spi_devs[0].irq = gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); - spi_register_board_info(mx31_3ds_spi_devs, - ARRAY_SIZE(mx31_3ds_spi_devs)); - - mx31_3ds_usbotg_init(); - if (otg_mode_host) { - otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | - ULPI_OTG_DRVVBUS_EXT); - if (otg_pdata.otg) - imx31_add_mxc_ehci_otg(&otg_pdata); - } - usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | - ULPI_OTG_DRVVBUS_EXT); - if (usbh2_pdata.otg) - imx31_add_mxc_ehci_hs(2, &usbh2_pdata); - - if (!otg_mode_host) - imx31_add_fsl_usb2_udc(&usbotg_pdata); - - if (mxc_expio_init(MX31_CS5_BASE_ADDR, IOMUX_TO_GPIO(MX31_PIN_GPIO1_1))) - printk(KERN_WARNING "Init of the debug board failed, all " - "devices on the debug board are unusable.\n"); - - imx31_add_mxc_mmc(0, &sdhc1_pdata); -} - -static void __init mx31_3ds_timer_init(void) -{ - mx31_clocks_init(26000000); -} - -MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)") - /* Maintainer: Freescale Semiconductor, Inc. */ - .atag_offset = 0x100, - .map_io = mx31_map_io, - .init_early = imx31_init_early, - .init_irq = mx31_init_irq, - .init_time = mx31_3ds_timer_init, - .init_machine = mx31_3ds_init, - .init_late = mx31_3ds_late, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c deleted file mode 100644 index 49783385bccf..000000000000 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ /dev/null @@ -1,579 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright (C) 2002 Shane Nay (shane@minirl.com) - * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -#include <linux/types.h> -#include <linux/init.h> -#include <linux/clk.h> -#include <linux/serial_8250.h> -#include <linux/gpio.h> -#include <linux/i2c.h> -#include <linux/irq.h> -#include <linux/irqdomain.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/memory.h> -#include <asm/mach/map.h> - -#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 -#include <linux/mfd/wm8350/audio.h> -#include <linux/mfd/wm8350/core.h> -#include <linux/mfd/wm8350/pmic.h> -#endif - -#include "common.h" -#include "devices-imx31.h" -#include "hardware.h" -#include "iomux-mx3.h" - -/* Base address of PBC controller */ -#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT - -/* PBC Board interrupt status register */ -#define PBC_INTSTATUS 0x000016 - -/* PBC Board interrupt current status register */ -#define PBC_INTCURR_STATUS 0x000018 - -/* PBC Interrupt mask register set address */ -#define PBC_INTMASK_SET 0x00001A - -/* PBC Interrupt mask register clear address */ -#define PBC_INTMASK_CLEAR 0x00001C - -/* External UART A */ -#define PBC_SC16C652_UARTA 0x010000 - -/* External UART B */ -#define PBC_SC16C652_UARTB 0x010010 - -#define PBC_INTSTATUS_REG (PBC_INTSTATUS + PBC_BASE_ADDRESS) -#define PBC_INTMASK_SET_REG (PBC_INTMASK_SET + PBC_BASE_ADDRESS) -#define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS) - -#define EXPIO_INT_XUART_INTA 10 -#define EXPIO_INT_XUART_INTB 11 - -#define MXC_MAX_EXP_IO_LINES 16 - -/* CS8900 */ -#define EXPIO_INT_ENET_INT 8 -#define CS4_CS8900_MMIO_START 0x20000 - -static struct irq_domain *domain; - -/* - * The serial port definition structure. - */ -static struct plat_serial8250_port serial_platform_data[] = { - { - .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA), - .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTA), - .uartclk = 14745600, - .regshift = 0, - .iotype = UPIO_MEM, - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ, - }, { - .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB), - .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTB), - .uartclk = 14745600, - .regshift = 0, - .iotype = UPIO_MEM, - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ, - }, - {}, -}; - -static struct platform_device serial_device = { - .name = "serial8250", - .id = 0, - .dev = { - .platform_data = serial_platform_data, - }, -}; - -static struct resource mx31ads_cs8900_resources[] __initdata = { - DEFINE_RES_MEM(MX31_CS4_BASE_ADDR + CS4_CS8900_MMIO_START, SZ_64K), - DEFINE_RES_IRQ(-1), -}; - -static const struct platform_device_info mx31ads_cs8900_devinfo __initconst = { - .name = "cs89x0", - .id = 0, - .res = mx31ads_cs8900_resources, - .num_res = ARRAY_SIZE(mx31ads_cs8900_resources), -}; - -static int __init mxc_init_extuart(void) -{ - serial_platform_data[0].irq = irq_find_mapping(domain, - EXPIO_INT_XUART_INTA); - serial_platform_data[1].irq = irq_find_mapping(domain, - EXPIO_INT_XUART_INTB); - return platform_device_register(&serial_device); -} - -static void __init mxc_init_ext_ethernet(void) -{ - mx31ads_cs8900_resources[1].start = - irq_find_mapping(domain, EXPIO_INT_ENET_INT); - mx31ads_cs8900_resources[1].end = - irq_find_mapping(domain, EXPIO_INT_ENET_INT); - platform_device_register_full( - (struct platform_device_info *)&mx31ads_cs8900_devinfo); -} - -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static unsigned int uart_pins[] = { - MX31_PIN_CTS1__CTS1, - MX31_PIN_RTS1__RTS1, - MX31_PIN_TXD1__TXD1, - MX31_PIN_RXD1__RXD1 -}; - -static inline void mxc_init_imx_uart(void) -{ - mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0"); - imx31_add_imx_uart0(&uart_pdata); -} - -static void mx31ads_expio_irq_handler(struct irq_desc *desc) -{ - u32 imr_val; - u32 int_valid; - u32 expio_irq; - - imr_val = imx_readw(PBC_INTMASK_SET_REG); - int_valid = imx_readw(PBC_INTSTATUS_REG) & imr_val; - - expio_irq = 0; - for (; int_valid != 0; int_valid >>= 1, expio_irq++) { - if ((int_valid & 1) == 0) - continue; - - generic_handle_irq(irq_find_mapping(domain, expio_irq)); - } -} - -/* - * Disable an expio pin's interrupt by setting the bit in the imr. - * @param d an expio virtual irq description - */ -static void expio_mask_irq(struct irq_data *d) -{ - u32 expio = d->hwirq; - /* mask the interrupt */ - imx_writew(1 << expio, PBC_INTMASK_CLEAR_REG); - imx_readw(PBC_INTMASK_CLEAR_REG); -} - -/* - * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr. - * @param d an expio virtual irq description - */ -static void expio_ack_irq(struct irq_data *d) -{ - u32 expio = d->hwirq; - /* clear the interrupt status */ - imx_writew(1 << expio, PBC_INTSTATUS_REG); -} - -/* - * Enable a expio pin's interrupt by clearing the bit in the imr. - * @param d an expio virtual irq description - */ -static void expio_unmask_irq(struct irq_data *d) -{ - u32 expio = d->hwirq; - /* unmask the interrupt */ - imx_writew(1 << expio, PBC_INTMASK_SET_REG); -} - -static struct irq_chip expio_irq_chip = { - .name = "EXPIO(CPLD)", - .irq_ack = expio_ack_irq, - .irq_mask = expio_mask_irq, - .irq_unmask = expio_unmask_irq, -}; - -static void __init mx31ads_init_expio(void) -{ - int irq_base; - int i, irq; - - printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n"); - - /* - * Configure INT line as GPIO input - */ - mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio"); - - /* disable the interrupt and clear the status */ - imx_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); - imx_writew(0xFFFF, PBC_INTSTATUS_REG); - - irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id()); - WARN_ON(irq_base < 0); - - domain = irq_domain_add_legacy(NULL, MXC_MAX_EXP_IO_LINES, irq_base, 0, - &irq_domain_simple_ops, NULL); - WARN_ON(!domain); - - for (i = irq_base; i < irq_base + MXC_MAX_EXP_IO_LINES; i++) { - irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq); - irq_clear_status_flags(i, IRQ_NOREQUEST); - } - irq = gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_4)); - irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); - irq_set_chained_handler(irq, mx31ads_expio_irq_handler); -} - -#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 -/* This section defines setup for the Wolfson Microelectronics - * 1133-EV1 PMU/audio board. When other PMU boards are supported the - * regulator definitions may be shared with them, but for now they can - * only be used with this board so would generate warnings about - * unused statics and some of the configuration is specific to this - * module. - */ - -/* CPU */ -static struct regulator_consumer_supply sw1a_consumers[] = { - { - .supply = "cpu_vcc", - } -}; - -static struct regulator_init_data sw1a_data = { - .constraints = { - .name = "SW1A", - .min_uV = 1275000, - .max_uV = 1600000, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_MODE, - .valid_modes_mask = REGULATOR_MODE_NORMAL | - REGULATOR_MODE_FAST, - .state_mem = { - .uV = 1400000, - .mode = REGULATOR_MODE_NORMAL, - .enabled = 1, - }, - .initial_state = PM_SUSPEND_MEM, - .always_on = 1, - .boot_on = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(sw1a_consumers), - .consumer_supplies = sw1a_consumers, -}; - -/* System IO - High */ -static struct regulator_init_data viohi_data = { - .constraints = { - .name = "VIOHO", - .min_uV = 2800000, - .max_uV = 2800000, - .state_mem = { - .uV = 2800000, - .mode = REGULATOR_MODE_NORMAL, - .enabled = 1, - }, - .initial_state = PM_SUSPEND_MEM, - .always_on = 1, - .boot_on = 1, - }, -}; - -/* System IO - Low */ -static struct regulator_init_data violo_data = { - .constraints = { - .name = "VIOLO", - .min_uV = 1800000, - .max_uV = 1800000, - .state_mem = { - .uV = 1800000, - .mode = REGULATOR_MODE_NORMAL, - .enabled = 1, - }, - .initial_state = PM_SUSPEND_MEM, - .always_on = 1, - .boot_on = 1, - }, -}; - -/* DDR RAM */ -static struct regulator_init_data sw2a_data = { - .constraints = { - .name = "SW2A", - .min_uV = 1800000, - .max_uV = 1800000, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .state_mem = { - .uV = 1800000, - .mode = REGULATOR_MODE_NORMAL, - .enabled = 1, - }, - .state_disk = { - .mode = REGULATOR_MODE_NORMAL, - .enabled = 0, - }, - .always_on = 1, - .boot_on = 1, - .initial_state = PM_SUSPEND_MEM, - }, -}; - -static struct regulator_init_data ldo1_data = { - .constraints = { - .name = "VCAM/VMMC1/VMMC2", - .min_uV = 2800000, - .max_uV = 2800000, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - .apply_uV = 1, - }, -}; - -static struct regulator_consumer_supply ldo2_consumers[] = { - { .supply = "AVDD", .dev_name = "1-001a" }, - { .supply = "HPVDD", .dev_name = "1-001a" }, -}; - -/* CODEC and SIM */ -static struct regulator_init_data ldo2_data = { - .constraints = { - .name = "VESIM/VSIM/AVDD", - .min_uV = 3300000, - .max_uV = 3300000, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - .apply_uV = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(ldo2_consumers), - .consumer_supplies = ldo2_consumers, -}; - -/* General */ -static struct regulator_init_data vdig_data = { - .constraints = { - .name = "VDIG", - .min_uV = 1500000, - .max_uV = 1500000, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .apply_uV = 1, - .always_on = 1, - .boot_on = 1, - }, -}; - -/* Tranceivers */ -static struct regulator_init_data ldo4_data = { - .constraints = { - .name = "VRF1/CVDD_2.775", - .min_uV = 2500000, - .max_uV = 2500000, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .apply_uV = 1, - .always_on = 1, - .boot_on = 1, - }, -}; - -static struct wm8350_led_platform_data wm8350_led_data = { - .name = "wm8350:white", - .default_trigger = "heartbeat", - .max_uA = 27899, -}; - -static struct wm8350_audio_platform_data imx32ads_wm8350_setup = { - .vmid_discharge_msecs = 1000, - .drain_msecs = 30, - .cap_discharge_msecs = 700, - .vmid_charge_msecs = 700, - .vmid_s_curve = WM8350_S_CURVE_SLOW, - .dis_out4 = WM8350_DISCHARGE_SLOW, - .dis_out3 = WM8350_DISCHARGE_SLOW, - .dis_out2 = WM8350_DISCHARGE_SLOW, - .dis_out1 = WM8350_DISCHARGE_SLOW, - .vroi_out4 = WM8350_TIE_OFF_500R, - .vroi_out3 = WM8350_TIE_OFF_500R, - .vroi_out2 = WM8350_TIE_OFF_500R, - .vroi_out1 = WM8350_TIE_OFF_500R, - .vroi_enable = 0, - .codec_current_on = WM8350_CODEC_ISEL_1_0, - .codec_current_standby = WM8350_CODEC_ISEL_0_5, - .codec_current_charge = WM8350_CODEC_ISEL_1_5, -}; - -static int mx31_wm8350_init(struct wm8350 *wm8350) -{ - wm8350_gpio_config(wm8350, 0, WM8350_GPIO_DIR_IN, - WM8350_GPIO0_PWR_ON_IN, WM8350_GPIO_ACTIVE_LOW, - WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF, - WM8350_GPIO_DEBOUNCE_ON); - - wm8350_gpio_config(wm8350, 3, WM8350_GPIO_DIR_IN, - WM8350_GPIO3_PWR_OFF_IN, WM8350_GPIO_ACTIVE_HIGH, - WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF, - WM8350_GPIO_DEBOUNCE_ON); - - wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN, - WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH, - WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF, - WM8350_GPIO_DEBOUNCE_OFF); - - wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN, - WM8350_GPIO7_HIBERNATE_IN, WM8350_GPIO_ACTIVE_HIGH, - WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF, - WM8350_GPIO_DEBOUNCE_OFF); - - wm8350_gpio_config(wm8350, 6, WM8350_GPIO_DIR_OUT, - WM8350_GPIO6_SDOUT_OUT, WM8350_GPIO_ACTIVE_HIGH, - WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, - WM8350_GPIO_DEBOUNCE_OFF); - - wm8350_gpio_config(wm8350, 8, WM8350_GPIO_DIR_OUT, - WM8350_GPIO8_VCC_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW, - WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, - WM8350_GPIO_DEBOUNCE_OFF); - - wm8350_gpio_config(wm8350, 9, WM8350_GPIO_DIR_OUT, - WM8350_GPIO9_BATT_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW, - WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, - WM8350_GPIO_DEBOUNCE_OFF); - - wm8350_register_regulator(wm8350, WM8350_DCDC_1, &sw1a_data); - wm8350_register_regulator(wm8350, WM8350_DCDC_3, &viohi_data); - wm8350_register_regulator(wm8350, WM8350_DCDC_4, &violo_data); - wm8350_register_regulator(wm8350, WM8350_DCDC_6, &sw2a_data); - wm8350_register_regulator(wm8350, WM8350_LDO_1, &ldo1_data); - wm8350_register_regulator(wm8350, WM8350_LDO_2, &ldo2_data); - wm8350_register_regulator(wm8350, WM8350_LDO_3, &vdig_data); - wm8350_register_regulator(wm8350, WM8350_LDO_4, &ldo4_data); - - /* LEDs */ - wm8350_dcdc_set_slot(wm8350, WM8350_DCDC_5, 1, 1, - WM8350_DC5_ERRACT_SHUTDOWN_CONV); - wm8350_isink_set_flash(wm8350, WM8350_ISINK_A, - WM8350_ISINK_FLASH_DISABLE, - WM8350_ISINK_FLASH_TRIG_BIT, - WM8350_ISINK_FLASH_DUR_32MS, - WM8350_ISINK_FLASH_ON_INSTANT, - WM8350_ISINK_FLASH_OFF_INSTANT, - WM8350_ISINK_FLASH_MODE_EN); - wm8350_dcdc25_set_mode(wm8350, WM8350_DCDC_5, - WM8350_ISINK_MODE_BOOST, - WM8350_ISINK_ILIM_NORMAL, - WM8350_DC5_RMP_20V, - WM8350_DC5_FBSRC_ISINKA); - wm8350_register_led(wm8350, 0, WM8350_DCDC_5, WM8350_ISINK_A, - &wm8350_led_data); - - wm8350->codec.platform_data = &imx32ads_wm8350_setup; - - regulator_has_full_constraints(); - - return 0; -} - -static struct wm8350_platform_data __initdata mx31_wm8350_pdata = { - .init = mx31_wm8350_init, -}; -#endif - -static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = { -#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 - { - I2C_BOARD_INFO("wm8350", 0x1a), - .platform_data = &mx31_wm8350_pdata, - /* irq number is run-time assigned */ - }, -#endif -}; - -static void __init mxc_init_i2c(void) -{ -#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 - mx31ads_i2c1_devices[0].irq = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); -#endif - i2c_register_board_info(1, mx31ads_i2c1_devices, - ARRAY_SIZE(mx31ads_i2c1_devices)); - - mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1)); - mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1)); - - imx31_add_imx_i2c1(NULL); -} - -static unsigned int ssi_pins[] = { - MX31_PIN_SFS5__SFS5, - MX31_PIN_SCK5__SCK5, - MX31_PIN_SRXD5__SRXD5, - MX31_PIN_STXD5__STXD5, -}; - -static void __init mxc_init_audio(void) -{ - imx31_add_imx_ssi(0, NULL); - mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi"); -} - -/* - * Static mappings, starting from the CS4 start address up to the start address - * of the CS8900. - */ -static struct map_desc mx31ads_io_desc[] __initdata = { - { - .virtual = (unsigned long)MX31_CS4_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR), - .length = CS4_CS8900_MMIO_START, - .type = MT_DEVICE - }, -}; - -static void __init mx31ads_map_io(void) -{ - mx31_map_io(); - iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc)); -} - -static void __init mx31ads_init(void) -{ - imx31_soc_init(); - - mxc_init_imx_uart(); - mxc_init_audio(); -} - -static void __init mx31ads_late(void) -{ - mx31ads_init_expio(); - mxc_init_extuart(); - mxc_init_i2c(); - mxc_init_ext_ethernet(); -} - -static void __init mx31ads_timer_init(void) -{ - mx31_clocks_init(26000000); -} - -MACHINE_START(MX31ADS, "Freescale MX31ADS") - /* Maintainer: Freescale Semiconductor, Inc. */ - .atag_offset = 0x100, - .map_io = mx31ads_map_io, - .init_early = imx31_init_early, - .init_irq = mx31_init_irq, - .init_time = mx31ads_timer_init, - .init_machine = mx31ads_init, - .init_late = mx31ads_late, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx31lilly.c b/arch/arm/mach-imx/mach-mx31lilly.c deleted file mode 100644 index 4b955ccc92cd..000000000000 --- a/arch/arm/mach-imx/mach-mx31lilly.c +++ /dev/null @@ -1,312 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * LILLY-1131 module support - * - * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> - * - * based on code for other MX31 boards, - * - * Copyright 2005-2007 Freescale Semiconductor - * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> - * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group - */ - -#include <linux/types.h> -#include <linux/init.h> -#include <linux/clk.h> -#include <linux/gpio.h> -#include <linux/delay.h> -#include <linux/platform_device.h> -#include <linux/interrupt.h> -#include <linux/moduleparam.h> -#include <linux/smsc911x.h> -#include <linux/mtd/physmap.h> -#include <linux/spi/spi.h> -#include <linux/mfd/mc13783.h> -#include <linux/usb/otg.h> -#include <linux/usb/ulpi.h> -#include <linux/regulator/machine.h> -#include <linux/regulator/fixed.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/mach/map.h> - -#include "board-mx31lilly.h" -#include "common.h" -#include "devices-imx31.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx3.h" -#include "ulpi.h" - -/* - * This file contains module-specific initialization routines for LILLY-1131. - * Initialization of peripherals found on the baseboard is implemented in the - * appropriate baseboard support code. - */ - -static unsigned int mx31lilly_pins[] __initdata = { - MX31_PIN_CTS1__CTS1, - MX31_PIN_RTS1__RTS1, - MX31_PIN_TXD1__TXD1, - MX31_PIN_RXD1__RXD1, - MX31_PIN_CTS2__CTS2, - MX31_PIN_RTS2__RTS2, - MX31_PIN_TXD2__TXD2, - MX31_PIN_RXD2__RXD2, - MX31_PIN_CSPI3_MOSI__RXD3, - MX31_PIN_CSPI3_MISO__TXD3, - MX31_PIN_CSPI3_SCLK__RTS3, - MX31_PIN_CSPI3_SPI_RDY__CTS3, -}; - -/* UART */ -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -/* SMSC ethernet support */ - -static struct resource smsc91x_resources[] = { - { - .start = MX31_CS4_BASE_ADDR, - .end = MX31_CS4_BASE_ADDR + 0xffff, - .flags = IORESOURCE_MEM, - }, - { - /* irq number is run-time assigned */ - .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, - } -}; - -static struct smsc911x_platform_config smsc911x_config = { - .phy_interface = PHY_INTERFACE_MODE_MII, - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, - .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, - .flags = SMSC911X_USE_32BIT | - SMSC911X_SAVE_MAC_ADDRESS | - SMSC911X_FORCE_INTERNAL_PHY, -}; - -static struct platform_device smsc91x_device = { - .name = "smsc911x", - .id = -1, - .num_resources = ARRAY_SIZE(smsc91x_resources), - .resource = smsc91x_resources, - .dev = { - .platform_data = &smsc911x_config, - } -}; - -/* NOR flash */ -static struct physmap_flash_data nor_flash_data = { - .width = 2, -}; - -static struct resource nor_flash_resource = { - .start = 0xa0000000, - .end = 0xa1ffffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device physmap_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &nor_flash_data, - }, - .resource = &nor_flash_resource, - .num_resources = 1, -}; - -/* USB */ - -#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ - PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) - -static int usbh1_init(struct platform_device *pdev) -{ - int pins[] = { - MX31_PIN_CSPI1_MOSI__USBH1_RXDM, - MX31_PIN_CSPI1_MISO__USBH1_RXDP, - MX31_PIN_CSPI1_SS0__USBH1_TXDM, - MX31_PIN_CSPI1_SS1__USBH1_TXDP, - MX31_PIN_CSPI1_SS2__USBH1_RCV, - MX31_PIN_CSPI1_SCLK__USBH1_OEB, - MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, - }; - - mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H1"); - - mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG); - - mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true); - - mdelay(10); - - return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED | - MXC_EHCI_INTERFACE_SINGLE_UNI); -} - -static int usbh2_init(struct platform_device *pdev) -{ - int pins[] = { - MX31_PIN_USBH2_DATA0__USBH2_DATA0, - MX31_PIN_USBH2_DATA1__USBH2_DATA1, - MX31_PIN_USBH2_CLK__USBH2_CLK, - MX31_PIN_USBH2_DIR__USBH2_DIR, - MX31_PIN_USBH2_NXT__USBH2_NXT, - MX31_PIN_USBH2_STP__USBH2_STP, - }; - - mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H2"); - - mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG); - - mxc_iomux_set_gpr(MUX_PGP_UH2, true); - - /* chip select */ - mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO), - "USBH2_CS"); - gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), "USBH2 CS"); - gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), 0); - - mdelay(10); - - return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); -} - -static const struct mxc_usbh_platform_data usbh1_pdata __initconst = { - .init = usbh1_init, - .portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL, -}; - -static struct mxc_usbh_platform_data usbh2_pdata __initdata = { - .init = usbh2_init, - .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, -}; - -static void __init lilly1131_usb_init(void) -{ - imx31_add_mxc_ehci_hs(1, &usbh1_pdata); - - usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | - ULPI_OTG_DRVVBUS_EXT); - if (usbh2_pdata.otg) - imx31_add_mxc_ehci_hs(2, &usbh2_pdata); -} - -static struct mc13xxx_platform_data mc13783_pdata __initdata = { - .flags = MC13XXX_USE_RTC | MC13XXX_USE_TOUCHSCREEN, -}; - -static struct spi_board_info mc13783_dev __initdata = { - .modalias = "mc13783", - .max_speed_hz = 1000000, - .bus_num = 1, - .chip_select = 0, - .platform_data = &mc13783_pdata, - /* irq number is run-time assigned */ -}; - -static struct platform_device *devices[] __initdata = { - &smsc91x_device, - &physmap_flash_device, -}; - -static int mx31lilly_baseboard; -core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444); - -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vdd33a", "smsc911x"), - REGULATOR_SUPPLY("vddvario", "smsc911x"), -}; - -static void __init mx31lilly_board_init(void) -{ - imx31_soc_init(); - - mxc_iomux_setup_multiple_pins(mx31lilly_pins, - ARRAY_SIZE(mx31lilly_pins), "mx31lily"); - - imx31_add_imx_uart0(&uart_pdata); - imx31_add_imx_uart1(&uart_pdata); - imx31_add_imx_uart2(&uart_pdata); - - mxc_iomux_alloc_pin(MX31_PIN_CS4__CS4, "Ethernet CS"); - - /* SPI */ - mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SCLK__SCLK, "SPI1_CLK"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MOSI__MOSI, "SPI1_TX"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MISO__MISO, "SPI1_RX"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, "SPI1_RDY"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS0__SS0, "SPI1_SS0"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS1__SS1, "SPI1_SS1"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS2__SS2, "SPI1_SS2"); - - mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SCLK__SCLK, "SPI2_CLK"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MOSI__MOSI, "SPI2_TX"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MISO__MISO, "SPI2_RX"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, "SPI2_RDY"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS0__SS0, "SPI2_SS0"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS1__SS1, "SPI2_SS1"); - mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS2__SS2, "SPI2_SS2"); - - imx31_add_spi_imx0(NULL); - imx31_add_spi_imx1(NULL); - - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); -} - -static void __init mx31lilly_late_init(void) -{ - if (mx31lilly_baseboard == MX31LILLY_DB) - mx31lilly_db_init(); - - mc13783_dev.irq = gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); - spi_register_board_info(&mc13783_dev, 1); - - smsc91x_resources[1].start = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)); - smsc91x_resources[1].end = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)); - platform_add_devices(devices, ARRAY_SIZE(devices)); - - /* USB */ - lilly1131_usb_init(); -} - -static void __init mx31lilly_timer_init(void) -{ - mx31_clocks_init(26000000); -} - -MACHINE_START(LILLY1131, "INCO startec LILLY-1131") - .atag_offset = 0x100, - .map_io = mx31_map_io, - .init_early = imx31_init_early, - .init_irq = mx31_init_irq, - .init_time = mx31lilly_timer_init, - .init_machine = mx31lilly_board_init, - .init_late = mx31lilly_late_init, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx31lite.c b/arch/arm/mach-imx/mach-mx31lite.c deleted file mode 100644 index aaccf52f7ac1..000000000000 --- a/arch/arm/mach-imx/mach-mx31lite.c +++ /dev/null @@ -1,290 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright (C) 2002 Shane Nay (shane@minirl.com) - * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2009 Daniel Mack <daniel@caiaq.de> - */ - -#include <linux/types.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/memory.h> -#include <linux/platform_device.h> -#include <linux/gpio.h> -#include <linux/moduleparam.h> -#include <linux/smsc911x.h> -#include <linux/mfd/mc13783.h> -#include <linux/spi/spi.h> -#include <linux/usb/otg.h> -#include <linux/usb/ulpi.h> -#include <linux/mtd/physmap.h> -#include <linux/delay.h> -#include <linux/regulator/machine.h> -#include <linux/regulator/fixed.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/mach/map.h> -#include <asm/page.h> -#include <asm/setup.h> - -#include "board-mx31lite.h" -#include "common.h" -#include "devices-imx31.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx3.h" -#include "ulpi.h" - -/* - * This file contains the module-specific initialization routines. - */ - -static unsigned int mx31lite_pins[] = { - /* UART1 */ - MX31_PIN_CTS1__CTS1, - MX31_PIN_RTS1__RTS1, - MX31_PIN_TXD1__TXD1, - MX31_PIN_RXD1__RXD1, - /* SPI 0 */ - MX31_PIN_CSPI1_SCLK__SCLK, - MX31_PIN_CSPI1_MOSI__MOSI, - MX31_PIN_CSPI1_MISO__MISO, - MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, - MX31_PIN_CSPI1_SS0__SS0, - MX31_PIN_CSPI1_SS1__SS1, - MX31_PIN_CSPI1_SS2__SS2, - /* LAN9117 IRQ pin */ - IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO), - /* SPI 1 */ - MX31_PIN_CSPI2_SCLK__SCLK, - MX31_PIN_CSPI2_MOSI__MOSI, - MX31_PIN_CSPI2_MISO__MISO, - MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, - MX31_PIN_CSPI2_SS0__SS0, - MX31_PIN_CSPI2_SS1__SS1, - MX31_PIN_CSPI2_SS2__SS2, -}; - -/* UART */ -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static const struct mxc_nand_platform_data -mx31lite_nand_board_info __initconst = { - .width = 1, - .hw_ecc = 1, -}; - -static struct smsc911x_platform_config smsc911x_config = { - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, - .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, - .flags = SMSC911X_USE_16BIT, -}; - -static struct resource smsc911x_resources[] = { - { - .start = MX31_CS4_BASE_ADDR, - .end = MX31_CS4_BASE_ADDR + 0x100, - .flags = IORESOURCE_MEM, - }, { - /* irq number is run-time assigned */ - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device smsc911x_device = { - .name = "smsc911x", - .id = -1, - .num_resources = ARRAY_SIZE(smsc911x_resources), - .resource = smsc911x_resources, - .dev = { - .platform_data = &smsc911x_config, - }, -}; - -static struct mc13xxx_platform_data mc13783_pdata __initdata = { - .flags = MC13XXX_USE_RTC, -}; - -static struct spi_board_info mc13783_spi_dev __initdata = { - .modalias = "mc13783", - .max_speed_hz = 1000000, - .bus_num = 1, - .chip_select = 0, - .platform_data = &mc13783_pdata, - /* irq number is run-time assigned */ -}; - -/* - * USB - */ - -#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ - PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) - -static int usbh2_init(struct platform_device *pdev) -{ - int pins[] = { - MX31_PIN_USBH2_DATA0__USBH2_DATA0, - MX31_PIN_USBH2_DATA1__USBH2_DATA1, - MX31_PIN_USBH2_CLK__USBH2_CLK, - MX31_PIN_USBH2_DIR__USBH2_DIR, - MX31_PIN_USBH2_NXT__USBH2_NXT, - MX31_PIN_USBH2_STP__USBH2_STP, - }; - - mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H2"); - - mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG); - - mxc_iomux_set_gpr(MUX_PGP_UH2, true); - - /* chip select */ - mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO), - "USBH2_CS"); - gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), "USBH2 CS"); - gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), 0); - - mdelay(10); - - return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); -} - -static struct mxc_usbh_platform_data usbh2_pdata __initdata = { - .init = usbh2_init, - .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, -}; - -/* - * NOR flash - */ - -static struct physmap_flash_data nor_flash_data = { - .width = 2, -}; - -static struct resource nor_flash_resource = { - .start = 0xa0000000, - .end = 0xa1ffffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device physmap_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &nor_flash_data, - }, - .resource = &nor_flash_resource, - .num_resources = 1, -}; - -/* - * This structure defines the MX31 memory map. - */ -static struct map_desc mx31lite_io_desc[] __initdata = { - { - .virtual = (unsigned long)MX31_CS4_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR), - .length = MX31_CS4_SIZE, - .type = MT_DEVICE - } -}; - -/* - * Set up static virtual mappings. - */ -static void __init mx31lite_map_io(void) -{ - mx31_map_io(); - iotable_init(mx31lite_io_desc, ARRAY_SIZE(mx31lite_io_desc)); -} - -static int mx31lite_baseboard; -core_param(mx31lite_baseboard, mx31lite_baseboard, int, 0444); - -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vdd33a", "smsc911x"), - REGULATOR_SUPPLY("vddvario", "smsc911x"), -}; - -static void __init mx31lite_init(void) -{ - imx31_soc_init(); - - mxc_iomux_setup_multiple_pins(mx31lite_pins, ARRAY_SIZE(mx31lite_pins), - "mx31lite"); - - imx31_add_imx_uart0(&uart_pdata); - imx31_add_spi_imx0(NULL); - - /* NOR and NAND flash */ - platform_device_register(&physmap_flash_device); - imx31_add_mxc_nand(&mx31lite_nand_board_info); - - imx31_add_spi_imx1(NULL); - - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); -} - -static void __init mx31lite_late(void) -{ - int ret; - - if (mx31lite_baseboard == MX31LITE_DB) - mx31lite_db_init(); - - mc13783_spi_dev.irq = gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); - spi_register_board_info(&mc13783_spi_dev, 1); - - /* USB */ - usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | - ULPI_OTG_DRVVBUS_EXT); - if (usbh2_pdata.otg) - imx31_add_mxc_ehci_hs(2, &usbh2_pdata); - - /* SMSC9117 IRQ pin */ - ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq"); - if (ret) - pr_warn("could not get LAN irq gpio\n"); - else { - gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_SFS6)); - smsc911x_resources[1].start = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SFS6)); - smsc911x_resources[1].end = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SFS6)); - platform_device_register(&smsc911x_device); - } -} - -static void __init mx31lite_timer_init(void) -{ - mx31_clocks_init(26000000); -} - -MACHINE_START(MX31LITE, "LogicPD i.MX31 SOM") - /* Maintainer: Freescale Semiconductor, Inc. */ - .atag_offset = 0x100, - .map_io = mx31lite_map_io, - .init_early = imx31_init_early, - .init_irq = mx31_init_irq, - .init_time = mx31lite_timer_init, - .init_machine = mx31lite_init, - .init_late = mx31lite_late, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c deleted file mode 100644 index 96845a4eaf57..000000000000 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ /dev/null @@ -1,581 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2008 Valentin Longchamp, EPFL Mobots group - */ - -#include <linux/delay.h> -#include <linux/dma-mapping.h> -#include <linux/gfp.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/moduleparam.h> -#include <linux/leds.h> -#include <linux/memory.h> -#include <linux/mtd/physmap.h> -#include <linux/mtd/partitions.h> -#include <linux/platform_device.h> -#include <linux/regulator/machine.h> -#include <linux/mfd/mc13783.h> -#include <linux/spi/spi.h> -#include <linux/types.h> -#include <linux/memblock.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/err.h> -#include <linux/input.h> - -#include <linux/usb/otg.h> -#include <linux/usb/ulpi.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/mach/map.h> -#include <asm/memblock.h> -#include <linux/platform_data/asoc-imx-ssi.h> - -#include "board-mx31moboard.h" -#include "common.h" -#include "devices-imx31.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx3.h" -#include "ulpi.h" - -static unsigned int moboard_pins[] = { - /* UART0 */ - MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1, - MX31_PIN_CTS1__GPIO2_7, - /* UART4 */ - MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5, - MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5, - /* I2C0 */ - MX31_PIN_I2C_DAT__I2C1_SDA, MX31_PIN_I2C_CLK__I2C1_SCL, - /* I2C1 */ - MX31_PIN_DCD_DTE1__I2C2_SDA, MX31_PIN_RI_DTE1__I2C2_SCL, - /* SDHC1 */ - MX31_PIN_SD1_DATA3__SD1_DATA3, MX31_PIN_SD1_DATA2__SD1_DATA2, - MX31_PIN_SD1_DATA1__SD1_DATA1, MX31_PIN_SD1_DATA0__SD1_DATA0, - MX31_PIN_SD1_CLK__SD1_CLK, MX31_PIN_SD1_CMD__SD1_CMD, - MX31_PIN_ATA_CS0__GPIO3_26, MX31_PIN_ATA_CS1__GPIO3_27, - /* USB reset */ - MX31_PIN_GPIO1_0__GPIO1_0, - /* USB OTG */ - MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, - MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, - MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, - MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, - MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, - MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, - MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, - MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, - MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR, - MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP, - MX31_PIN_USB_OC__GPIO1_30, - /* USB H2 */ - MX31_PIN_USBH2_DATA0__USBH2_DATA0, - MX31_PIN_USBH2_DATA1__USBH2_DATA1, - MX31_PIN_STXD3__USBH2_DATA2, MX31_PIN_SRXD3__USBH2_DATA3, - MX31_PIN_SCK3__USBH2_DATA4, MX31_PIN_SFS3__USBH2_DATA5, - MX31_PIN_STXD6__USBH2_DATA6, MX31_PIN_SRXD6__USBH2_DATA7, - MX31_PIN_USBH2_CLK__USBH2_CLK, MX31_PIN_USBH2_DIR__USBH2_DIR, - MX31_PIN_USBH2_NXT__USBH2_NXT, MX31_PIN_USBH2_STP__USBH2_STP, - MX31_PIN_SCK6__GPIO1_25, - /* LEDs */ - MX31_PIN_SVEN0__GPIO2_0, MX31_PIN_STX0__GPIO2_1, - MX31_PIN_SRX0__GPIO2_2, MX31_PIN_SIMPD0__GPIO2_3, - /* SPI1 */ - MX31_PIN_CSPI2_MOSI__MOSI, MX31_PIN_CSPI2_MISO__MISO, - MX31_PIN_CSPI2_SCLK__SCLK, MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, - MX31_PIN_CSPI2_SS0__SS0, MX31_PIN_CSPI2_SS2__SS2, - /* Atlas IRQ */ - MX31_PIN_GPIO1_3__GPIO1_3, - /* SPI2 */ - MX31_PIN_CSPI3_MOSI__MOSI, MX31_PIN_CSPI3_MISO__MISO, - MX31_PIN_CSPI3_SCLK__SCLK, MX31_PIN_CSPI3_SPI_RDY__SPI_RDY, - MX31_PIN_CSPI2_SS1__CSPI3_SS1, - /* SSI */ - MX31_PIN_STXD4__STXD4, MX31_PIN_SRXD4__SRXD4, - MX31_PIN_SCK4__SCK4, MX31_PIN_SFS4__SFS4, -}; - -static struct physmap_flash_data mx31moboard_flash_data = { - .width = 2, -}; - -static struct resource mx31moboard_flash_resource = { - .start = 0xa0000000, - .end = 0xa1ffffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device mx31moboard_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &mx31moboard_flash_data, - }, - .resource = &mx31moboard_flash_resource, - .num_resources = 1, -}; - -static void __init moboard_uart0_init(void) -{ - if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack")) { - gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0); - gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1)); - } -} - -static const struct imxuart_platform_data uart0_pdata __initconst = { -}; - -static const struct imxuart_platform_data uart4_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static const struct imxi2c_platform_data moboard_i2c0_data __initconst = { - .bitrate = 400000, -}; - -static const struct imxi2c_platform_data moboard_i2c1_data __initconst = { - .bitrate = 100000, -}; - -static struct regulator_consumer_supply sdhc_consumers[] = { - { - .dev_name = "imx31-mmc.0", - .supply = "sdhc0_vcc", - }, - { - .dev_name = "imx31-mmc.1", - .supply = "sdhc1_vcc", - }, -}; - -static struct regulator_init_data sdhc_vreg_data = { - .constraints = { - .min_uV = 2700000, - .max_uV = 3000000, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, - .valid_modes_mask = REGULATOR_MODE_NORMAL | - REGULATOR_MODE_FAST, - .always_on = 0, - .boot_on = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(sdhc_consumers), - .consumer_supplies = sdhc_consumers, -}; - -static struct regulator_consumer_supply cam_consumers[] = { - { - .dev_name = "mx3_camera.0", - .supply = "cam_vcc", - }, -}; - -static struct regulator_init_data cam_vreg_data = { - .constraints = { - .min_uV = 2700000, - .max_uV = 3000000, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, - .valid_modes_mask = REGULATOR_MODE_NORMAL | - REGULATOR_MODE_FAST, - .always_on = 0, - .boot_on = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(cam_consumers), - .consumer_supplies = cam_consumers, -}; - -static struct mc13xxx_regulator_init_data moboard_regulators[] = { - { - .id = MC13783_REG_VMMC1, - .init_data = &sdhc_vreg_data, - }, - { - .id = MC13783_REG_VCAM, - .init_data = &cam_vreg_data, - }, -}; - -static struct mc13xxx_led_platform_data moboard_led[] = { - { - .id = MC13783_LED_R1, - .name = "coreboard-led-4:red", - }, - { - .id = MC13783_LED_G1, - .name = "coreboard-led-4:green", - }, - { - .id = MC13783_LED_B1, - .name = "coreboard-led-4:blue", - }, - { - .id = MC13783_LED_R2, - .name = "coreboard-led-5:red", - }, - { - .id = MC13783_LED_G2, - .name = "coreboard-led-5:green", - }, - { - .id = MC13783_LED_B2, - .name = "coreboard-led-5:blue", - }, -}; - -static struct mc13xxx_leds_platform_data moboard_leds = { - .num_leds = ARRAY_SIZE(moboard_led), - .led = moboard_led, - .led_control[0] = MC13783_LED_C0_ENABLE | MC13783_LED_C0_ABMODE(0), - .led_control[1] = MC13783_LED_C1_SLEWLIM, - .led_control[2] = MC13783_LED_C2_SLEWLIM, - .led_control[3] = MC13783_LED_C3_PERIOD(0) | - MC13783_LED_C3_CURRENT_R1(2) | - MC13783_LED_C3_CURRENT_G1(2) | - MC13783_LED_C3_CURRENT_B1(2), - .led_control[4] = MC13783_LED_C4_PERIOD(0) | - MC13783_LED_C4_CURRENT_R2(3) | - MC13783_LED_C4_CURRENT_G2(3) | - MC13783_LED_C4_CURRENT_B2(3), -}; - -static struct mc13xxx_buttons_platform_data moboard_buttons = { - .b1on_flags = MC13783_BUTTON_DBNC_750MS | MC13783_BUTTON_ENABLE | - MC13783_BUTTON_POL_INVERT, - .b1on_key = KEY_POWER, -}; - -static struct mc13xxx_codec_platform_data moboard_codec = { - .dac_ssi_port = MC13783_SSI1_PORT, - .adc_ssi_port = MC13783_SSI1_PORT, -}; - -static struct mc13xxx_platform_data moboard_pmic = { - .regulators = { - .regulators = moboard_regulators, - .num_regulators = ARRAY_SIZE(moboard_regulators), - }, - .leds = &moboard_leds, - .buttons = &moboard_buttons, - .codec = &moboard_codec, - .flags = MC13XXX_USE_RTC | MC13XXX_USE_ADC | MC13XXX_USE_CODEC, -}; - -static struct imx_ssi_platform_data moboard_ssi_pdata = { - .flags = IMX_SSI_DMA | IMX_SSI_NET, -}; - -static struct spi_board_info moboard_spi_board_info[] __initdata = { - { - .modalias = "mc13783", - /* irq number is run-time assigned */ - .max_speed_hz = 300000, - .bus_num = 1, - .chip_select = 0, - .platform_data = &moboard_pmic, - .mode = SPI_CS_HIGH, - }, -}; - -#define SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_ATA_CS0) -#define SDHC1_WP IOMUX_TO_GPIO(MX31_PIN_ATA_CS1) - -static int moboard_sdhc1_get_ro(struct device *dev) -{ - return !gpio_get_value(SDHC1_WP); -} - -static int moboard_sdhc1_init(struct device *dev, irq_handler_t detect_irq, - void *data) -{ - int ret; - - ret = gpio_request(SDHC1_CD, "sdhc-detect"); - if (ret) - return ret; - - gpio_direction_input(SDHC1_CD); - - ret = gpio_request(SDHC1_WP, "sdhc-wp"); - if (ret) - goto err_gpio_free; - gpio_direction_input(SDHC1_WP); - - ret = request_irq(gpio_to_irq(SDHC1_CD), detect_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "sdhc1-card-detect", data); - if (ret) - goto err_gpio_free_2; - - return 0; - -err_gpio_free_2: - gpio_free(SDHC1_WP); -err_gpio_free: - gpio_free(SDHC1_CD); - - return ret; -} - -static void moboard_sdhc1_exit(struct device *dev, void *data) -{ - free_irq(gpio_to_irq(SDHC1_CD), data); - gpio_free(SDHC1_WP); - gpio_free(SDHC1_CD); -} - -static const struct imxmmc_platform_data sdhc1_pdata __initconst = { - .get_ro = moboard_sdhc1_get_ro, - .init = moboard_sdhc1_init, - .exit = moboard_sdhc1_exit, -}; - -/* - * this pin is dedicated for all mx31moboard systems, so we do it here - */ -#define USB_RESET_B IOMUX_TO_GPIO(MX31_PIN_GPIO1_0) -#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ - PAD_CTL_ODE_CMOS) - -#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC) -#define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6) - -static void usb_xcvr_reset(void) -{ - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG | PAD_CTL_100K_PU); - mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG | PAD_CTL_100K_PU); - mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG | PAD_CTL_100K_PU); - mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG | PAD_CTL_100K_PU); - - mxc_iomux_set_gpr(MUX_PGP_UH2, true); - mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG | PAD_CTL_100K_PU); - mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG | PAD_CTL_100K_PU); - mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG | PAD_CTL_100K_PU); - mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG | PAD_CTL_100K_PU); - mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG | PAD_CTL_100K_PD); - mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG | PAD_CTL_100K_PD); - - gpio_request(OTG_EN_B, "usb-udc-en"); - gpio_direction_output(OTG_EN_B, 0); - gpio_request(USBH2_EN_B, "usbh2-en"); - gpio_direction_output(USBH2_EN_B, 0); - - gpio_request(USB_RESET_B, "usb-reset"); - gpio_direction_output(USB_RESET_B, 0); - mdelay(1); - gpio_set_value(USB_RESET_B, 1); - mdelay(1); -} - -static int moboard_usbh2_init_hw(struct platform_device *pdev) -{ - return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); -} - -static struct mxc_usbh_platform_data usbh2_pdata __initdata = { - .init = moboard_usbh2_init_hw, - .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, -}; - -static int __init moboard_usbh2_init(void) -{ - struct platform_device *pdev; - - usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | - ULPI_OTG_DRVVBUS_EXT); - if (!usbh2_pdata.otg) - return -ENODEV; - - pdev = imx31_add_mxc_ehci_hs(2, &usbh2_pdata); - - return PTR_ERR_OR_ZERO(pdev); -} - -static const struct gpio_led mx31moboard_leds[] __initconst = { - { - .name = "coreboard-led-0:red:running", - .default_trigger = "heartbeat", - .gpio = IOMUX_TO_GPIO(MX31_PIN_SVEN0), - }, { - .name = "coreboard-led-1:red", - .gpio = IOMUX_TO_GPIO(MX31_PIN_STX0), - }, { - .name = "coreboard-led-2:red", - .gpio = IOMUX_TO_GPIO(MX31_PIN_SRX0), - }, { - .name = "coreboard-led-3:red", - .gpio = IOMUX_TO_GPIO(MX31_PIN_SIMPD0), - }, -}; - -static const struct gpio_led_platform_data mx31moboard_led_pdata __initconst = { - .num_leds = ARRAY_SIZE(mx31moboard_leds), - .leds = mx31moboard_leds, -}; - -static struct platform_device *devices[] __initdata = { - &mx31moboard_flash, -}; - -static struct mx3_camera_pdata camera_pdata __initdata = { - .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10, - .mclk_10khz = 4800, -}; - -static phys_addr_t mx3_camera_base __initdata; -#define MX3_CAMERA_BUF_SIZE SZ_4M - -static int __init mx31moboard_init_cam(void) -{ - int ret; - struct platform_device *pdev; - - imx31_add_ipu_core(); - - pdev = imx31_alloc_mx3_camera(&camera_pdata); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - ret = dma_declare_coherent_memory(&pdev->dev, - mx3_camera_base, mx3_camera_base, - MX3_CAMERA_BUF_SIZE); - if (ret) - goto err; - - ret = platform_device_add(pdev); - if (ret) -err: - platform_device_put(pdev); - - return ret; - -} - -static void mx31moboard_poweroff(void) -{ - struct clk *clk = clk_get_sys("imx2-wdt.0", NULL); - - if (!IS_ERR(clk)) - clk_prepare_enable(clk); - - mxc_iomux_mode(MX31_PIN_WATCHDOG_RST__WATCHDOG_RST); - - imx_writew(1 << 6 | 1 << 2, MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); -} - -static int mx31moboard_baseboard; -core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444); - -/* - * Board specific initialization. - */ -static void __init mx31moboard_init(void) -{ - imx31_soc_init(); - - mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins), - "moboard"); - - platform_add_devices(devices, ARRAY_SIZE(devices)); - - imx31_add_imx2_wdt(); - - imx31_add_imx_uart0(&uart0_pdata); - imx31_add_imx_uart4(&uart4_pdata); - - imx31_add_imx_i2c0(&moboard_i2c0_data); - imx31_add_imx_i2c1(&moboard_i2c1_data); - - imx31_add_spi_imx1(NULL); - imx31_add_spi_imx2(NULL); - - mx31moboard_init_cam(); - - imx31_add_imx_ssi(0, &moboard_ssi_pdata); - - pm_power_off = mx31moboard_poweroff; -} - -static void __init mx31moboard_late(void) -{ - gpio_led_register_device(-1, &mx31moboard_led_pdata); - - moboard_uart0_init(); - - gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3), "pmic-irq"); - gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); - moboard_spi_board_info[0].irq = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); - spi_register_board_info(moboard_spi_board_info, - ARRAY_SIZE(moboard_spi_board_info)); - - imx31_add_mxc_mmc(0, &sdhc1_pdata); - - usb_xcvr_reset(); - moboard_usbh2_init(); - - imx_add_platform_device("imx_mc13783", 0, NULL, 0, NULL, 0); - - switch (mx31moboard_baseboard) { - case MX31NOBOARD: - break; - case MX31DEVBOARD: - mx31moboard_devboard_init(); - break; - case MX31MARXBOT: - mx31moboard_marxbot_init(); - break; - case MX31SMARTBOT: - case MX31EYEBOT: - mx31moboard_smartbot_init(mx31moboard_baseboard); - break; - default: - printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n", - mx31moboard_baseboard); - } -} - -static void __init mx31moboard_timer_init(void) -{ - mx31_clocks_init(26000000); -} - -static void __init mx31moboard_reserve(void) -{ - /* reserve 4 MiB for mx3-camera */ - mx3_camera_base = arm_memblock_steal(MX3_CAMERA_BUF_SIZE, - MX3_CAMERA_BUF_SIZE); -} - -MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard") - /* Maintainer: Philippe Retornaz, EPFL Mobots group */ - .atag_offset = 0x100, - .reserve = mx31moboard_reserve, - .map_io = mx31_map_io, - .init_early = imx31_init_early, - .init_irq = mx31_init_irq, - .init_time = mx31moboard_timer_init, - .init_machine = mx31moboard_init, - .init_late = mx31moboard_late, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c deleted file mode 100644 index 802e0abe4568..000000000000 --- a/arch/arm/mach-imx/mach-mx35_3ds.c +++ /dev/null @@ -1,516 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix - * - * Author: Fabio Estevam <fabio.estevam@freescale.com> - * - * Copyright (C) 2011 Meprolight, Ltd. - * Alex Gershgorin <alexg@meprolight.com> - * - * Modified from i.MX31 3-Stack Development System - */ - -/* - * This machine is known as: - * - i.MX35 3-Stack Development System - * - i.MX35 Platform Development Kit (i.MX35 PDK) - */ - -#include <linux/types.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/memory.h> -#include <linux/gpio.h> -#include <linux/usb/otg.h> - -#include <linux/mtd/physmap.h> -#include <linux/mfd/mc13892.h> -#include <linux/regulator/machine.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/mach/map.h> - -#include <video/platform_lcd.h> - -#include "3ds_debugboard.h" -#include "common.h" -#include "devices-imx35.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx35.h" - -#define GPIO_MC9S08DZ60_GPS_ENABLE 0 -#define GPIO_MC9S08DZ60_HDD_ENABLE 4 -#define GPIO_MC9S08DZ60_WIFI_ENABLE 5 -#define GPIO_MC9S08DZ60_LCD_ENABLE 6 -#define GPIO_MC9S08DZ60_SPEAKER_ENABLE 8 - -static const struct fb_videomode fb_modedb[] = { - { - /* 800x480 @ 55 Hz */ - .name = "Ceramate-CLAA070VC01", - .refresh = 55, - .xres = 800, - .yres = 480, - .pixclock = 40000, - .left_margin = 40, - .right_margin = 40, - .upper_margin = 5, - .lower_margin = 5, - .hsync_len = 20, - .vsync_len = 10, - .sync = FB_SYNC_OE_ACT_HIGH, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, -}; - -static struct mx3fb_platform_data mx3fb_pdata __initdata = { - .name = "Ceramate-CLAA070VC01", - .mode = fb_modedb, - .num_modes = ARRAY_SIZE(fb_modedb), -}; - -static struct i2c_board_info __initdata i2c_devices_3ds[] = { - { - I2C_BOARD_INFO("mc9s08dz60", 0x69), - }, -}; - -static int lcd_power_gpio = -ENXIO; - -static int mc9s08dz60_gpiochip_match(struct gpio_chip *chip, void *data) -{ - return !strcmp(chip->label, data); -} - -static void mx35_3ds_lcd_set_power( - struct plat_lcd_data *pd, unsigned int power) -{ - struct gpio_chip *chip; - - if (!gpio_is_valid(lcd_power_gpio)) { - chip = gpiochip_find( - "mc9s08dz60", mc9s08dz60_gpiochip_match); - if (chip) { - lcd_power_gpio = - chip->base + GPIO_MC9S08DZ60_LCD_ENABLE; - if (gpio_request(lcd_power_gpio, "lcd_power") < 0) { - pr_err("error: gpio already requested!\n"); - lcd_power_gpio = -ENXIO; - } - } else { - pr_err("error: didn't find mc9s08dz60 gpio chip\n"); - } - } - - if (gpio_is_valid(lcd_power_gpio)) - gpio_set_value_cansleep(lcd_power_gpio, power); -} - -static struct plat_lcd_data mx35_3ds_lcd_data = { - .set_power = mx35_3ds_lcd_set_power, -}; - -static struct platform_device mx35_3ds_lcd = { - .name = "platform-lcd", - .dev.platform_data = &mx35_3ds_lcd_data, -}; - -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static struct physmap_flash_data mx35pdk_flash_data = { - .width = 2, -}; - -static struct resource mx35pdk_flash_resource = { - .start = MX35_CS0_BASE_ADDR, - .end = MX35_CS0_BASE_ADDR + SZ_64M - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device mx35pdk_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &mx35pdk_flash_data, - }, - .resource = &mx35pdk_flash_resource, - .num_resources = 1, -}; - -static const struct mxc_nand_platform_data mx35pdk_nand_board_info __initconst = { - .width = 1, - .hw_ecc = 1, - .flash_bbt = 1, -}; - -static struct platform_device *devices[] __initdata = { - &mx35pdk_flash, -}; - -static const iomux_v3_cfg_t mx35pdk_pads[] __initconst = { - /* UART1 */ - MX35_PAD_CTS1__UART1_CTS, - MX35_PAD_RTS1__UART1_RTS, - MX35_PAD_TXD1__UART1_TXD_MUX, - MX35_PAD_RXD1__UART1_RXD_MUX, - /* FEC */ - MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, - MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, - MX35_PAD_FEC_RX_DV__FEC_RX_DV, - MX35_PAD_FEC_COL__FEC_COL, - MX35_PAD_FEC_RDATA0__FEC_RDATA_0, - MX35_PAD_FEC_TDATA0__FEC_TDATA_0, - MX35_PAD_FEC_TX_EN__FEC_TX_EN, - MX35_PAD_FEC_MDC__FEC_MDC, - MX35_PAD_FEC_MDIO__FEC_MDIO, - MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, - MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, - MX35_PAD_FEC_CRS__FEC_CRS, - MX35_PAD_FEC_RDATA1__FEC_RDATA_1, - MX35_PAD_FEC_TDATA1__FEC_TDATA_1, - MX35_PAD_FEC_RDATA2__FEC_RDATA_2, - MX35_PAD_FEC_TDATA2__FEC_TDATA_2, - MX35_PAD_FEC_RDATA3__FEC_RDATA_3, - MX35_PAD_FEC_TDATA3__FEC_TDATA_3, - /* USBOTG */ - MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR, - MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC, - /* USBH1 */ - MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR, - MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC, - /* SDCARD */ - MX35_PAD_SD1_CMD__ESDHC1_CMD, - MX35_PAD_SD1_CLK__ESDHC1_CLK, - MX35_PAD_SD1_DATA0__ESDHC1_DAT0, - MX35_PAD_SD1_DATA1__ESDHC1_DAT1, - MX35_PAD_SD1_DATA2__ESDHC1_DAT2, - MX35_PAD_SD1_DATA3__ESDHC1_DAT3, - /* I2C1 */ - MX35_PAD_I2C1_CLK__I2C1_SCL, - MX35_PAD_I2C1_DAT__I2C1_SDA, - /* Display */ - MX35_PAD_LD0__IPU_DISPB_DAT_0, - MX35_PAD_LD1__IPU_DISPB_DAT_1, - MX35_PAD_LD2__IPU_DISPB_DAT_2, - MX35_PAD_LD3__IPU_DISPB_DAT_3, - MX35_PAD_LD4__IPU_DISPB_DAT_4, - MX35_PAD_LD5__IPU_DISPB_DAT_5, - MX35_PAD_LD6__IPU_DISPB_DAT_6, - MX35_PAD_LD7__IPU_DISPB_DAT_7, - MX35_PAD_LD8__IPU_DISPB_DAT_8, - MX35_PAD_LD9__IPU_DISPB_DAT_9, - MX35_PAD_LD10__IPU_DISPB_DAT_10, - MX35_PAD_LD11__IPU_DISPB_DAT_11, - MX35_PAD_LD12__IPU_DISPB_DAT_12, - MX35_PAD_LD13__IPU_DISPB_DAT_13, - MX35_PAD_LD14__IPU_DISPB_DAT_14, - MX35_PAD_LD15__IPU_DISPB_DAT_15, - MX35_PAD_LD16__IPU_DISPB_DAT_16, - MX35_PAD_LD17__IPU_DISPB_DAT_17, - MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC, - MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK, - MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY, - MX35_PAD_CONTRAST__IPU_DISPB_CONTR, - MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC, - MX35_PAD_D3_REV__IPU_DISPB_D3_REV, - MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS, - /*PMIC IRQ*/ - MX35_PAD_GPIO2_0__GPIO2_0, -}; - -static struct regulator_consumer_supply sw1_consumers[] = { - { - .supply = "cpu_vcc", - } -}; - -static struct regulator_consumer_supply vcam_consumers[] = { - /* sgtl5000 */ - REGULATOR_SUPPLY("VDDA", "0-000a"), -}; - -static struct regulator_init_data sw1_init = { - .constraints = { - .name = "SW1", - .min_uV = 600000, - .max_uV = 1375000, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, - .valid_modes_mask = 0, - .always_on = 1, - .boot_on = 1, - }, - .num_consumer_supplies = ARRAY_SIZE(sw1_consumers), - .consumer_supplies = sw1_consumers, -}; - -static struct regulator_init_data sw2_init = { - .constraints = { - .name = "SW2", - .always_on = 1, - .boot_on = 1, - } -}; - -static struct regulator_init_data sw3_init = { - .constraints = { - .name = "SW3", - .always_on = 1, - .boot_on = 1, - } -}; - -static struct regulator_init_data sw4_init = { - .constraints = { - .name = "SW4", - .always_on = 1, - .boot_on = 1, - } -}; - -static struct regulator_init_data viohi_init = { - .constraints = { - .name = "VIOHI", - .boot_on = 1, - } -}; - -static struct regulator_init_data vusb_init = { - .constraints = { - .name = "VUSB", - .boot_on = 1, - } -}; - -static struct regulator_init_data vdig_init = { - .constraints = { - .name = "VDIG", - .boot_on = 1, - } -}; - -static struct regulator_init_data vpll_init = { - .constraints = { - .name = "VPLL", - .boot_on = 1, - } -}; - -static struct regulator_init_data vusb2_init = { - .constraints = { - .name = "VUSB2", - .boot_on = 1, - } -}; - -static struct regulator_init_data vvideo_init = { - .constraints = { - .name = "VVIDEO", - .boot_on = 1 - } -}; - -static struct regulator_init_data vcam_init = { - .constraints = { - .name = "VCAM", - .min_uV = 2500000, - .max_uV = 3000000, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_MODE, - .valid_modes_mask = REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL, - .boot_on = 1 - }, - .num_consumer_supplies = ARRAY_SIZE(vcam_consumers), - .consumer_supplies = vcam_consumers, -}; - -static struct regulator_init_data vgen1_init = { - .constraints = { - .name = "VGEN1", - } -}; - -static struct regulator_init_data vgen2_init = { - .constraints = { - .name = "VGEN2", - .boot_on = 1, - } -}; - -static struct regulator_init_data vgen3_init = { - .constraints = { - .name = "VGEN3", - } -}; - -static struct mc13xxx_regulator_init_data mx35_3ds_regulators[] = { - { .id = MC13892_SW1, .init_data = &sw1_init }, - { .id = MC13892_SW2, .init_data = &sw2_init }, - { .id = MC13892_SW3, .init_data = &sw3_init }, - { .id = MC13892_SW4, .init_data = &sw4_init }, - { .id = MC13892_VIOHI, .init_data = &viohi_init }, - { .id = MC13892_VPLL, .init_data = &vpll_init }, - { .id = MC13892_VDIG, .init_data = &vdig_init }, - { .id = MC13892_VUSB2, .init_data = &vusb2_init }, - { .id = MC13892_VVIDEO, .init_data = &vvideo_init }, - { .id = MC13892_VCAM, .init_data = &vcam_init }, - { .id = MC13892_VGEN1, .init_data = &vgen1_init }, - { .id = MC13892_VGEN2, .init_data = &vgen2_init }, - { .id = MC13892_VGEN3, .init_data = &vgen3_init }, - { .id = MC13892_VUSB, .init_data = &vusb_init }, -}; - -static struct mc13xxx_platform_data mx35_3ds_mc13892_data = { - .flags = MC13XXX_USE_RTC | MC13XXX_USE_TOUCHSCREEN, - .regulators = { - .num_regulators = ARRAY_SIZE(mx35_3ds_regulators), - .regulators = mx35_3ds_regulators, - }, -}; - -#define GPIO_PMIC_INT IMX_GPIO_NR(2, 0) - -static struct i2c_board_info mx35_3ds_i2c_mc13892 = { - - I2C_BOARD_INFO("mc13892", 0x08), - .platform_data = &mx35_3ds_mc13892_data, - /* irq number is run-time assigned */ -}; - -static void __init imx35_3ds_init_mc13892(void) -{ - int ret = gpio_request_one(GPIO_PMIC_INT, GPIOF_DIR_IN, "pmic irq"); - - if (ret) { - pr_err("failed to get pmic irq: %d\n", ret); - return; - } - - mx35_3ds_i2c_mc13892.irq = gpio_to_irq(GPIO_PMIC_INT); - i2c_register_board_info(0, &mx35_3ds_i2c_mc13892, 1); -} - -static int mx35_3ds_otg_init(struct platform_device *pdev) -{ - return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERNAL_PHY); -} - -/* OTG config */ -static const struct fsl_usb2_platform_data usb_otg_pdata __initconst = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_UTMI_WIDE, - .workaround = FLS_USB2_WORKAROUND_ENGCM09152, -/* - * ENGCM09152 also requires a hardware change. - * Please check the MX35 Chip Errata document for details. - */ -}; - -static struct mxc_usbh_platform_data otg_pdata __initdata = { - .init = mx35_3ds_otg_init, - .portsc = MXC_EHCI_MODE_UTMI, -}; - -static int mx35_3ds_usbh_init(struct platform_device *pdev) -{ - return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI | - MXC_EHCI_INTERNAL_PHY); -} - -/* USB HOST config */ -static const struct mxc_usbh_platform_data usb_host_pdata __initconst = { - .init = mx35_3ds_usbh_init, - .portsc = MXC_EHCI_MODE_SERIAL, -}; - -static bool otg_mode_host __initdata; - -static int __init mx35_3ds_otg_mode(char *options) -{ - if (!strcmp(options, "host")) - otg_mode_host = true; - else if (!strcmp(options, "device")) - otg_mode_host = false; - else - pr_info("otg_mode neither \"host\" nor \"device\". " - "Defaulting to device\n"); - return 1; -} -__setup("otg_mode=", mx35_3ds_otg_mode); - -static const struct imxi2c_platform_data mx35_3ds_i2c0_data __initconst = { - .bitrate = 100000, -}; - -/* - * Board specific initialization. - */ -static void __init mx35_3ds_init(void) -{ - imx35_soc_init(); - - mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads)); - - imx35_add_fec(NULL); - imx35_add_imx2_wdt(); - imx35_add_mxc_rtc(); - platform_add_devices(devices, ARRAY_SIZE(devices)); - - imx35_add_imx_uart0(&uart_pdata); - - if (otg_mode_host) - imx35_add_mxc_ehci_otg(&otg_pdata); - - imx35_add_mxc_ehci_hs(&usb_host_pdata); - - if (!otg_mode_host) - imx35_add_fsl_usb2_udc(&usb_otg_pdata); - - imx35_add_mxc_nand(&mx35pdk_nand_board_info); - imx35_add_sdhci_esdhc_imx(0, NULL); - - imx35_add_imx_i2c0(&mx35_3ds_i2c0_data); - - i2c_register_board_info( - 0, i2c_devices_3ds, ARRAY_SIZE(i2c_devices_3ds)); - - imx35_add_ipu_core(); -} - -static void __init mx35_3ds_late_init(void) -{ - struct platform_device *imx35_fb_pdev; - - if (mxc_expio_init(MX35_CS5_BASE_ADDR, IMX_GPIO_NR(1, 1))) - pr_warn("Init of the debugboard failed, all " - "devices on the debugboard are unusable.\n"); - - imx35_fb_pdev = imx35_add_mx3_sdc_fb(&mx3fb_pdata); - mx35_3ds_lcd.dev.parent = &imx35_fb_pdev->dev; - platform_device_register(&mx35_3ds_lcd); - - imx35_3ds_init_mc13892(); -} - -static void __init mx35pdk_timer_init(void) -{ - mx35_clocks_init(); -} - -MACHINE_START(MX35_3DS, "Freescale MX35PDK") - /* Maintainer: Freescale Semiconductor, Inc */ - .atag_offset = 0x100, - .map_io = mx35_map_io, - .init_early = imx35_init_early, - .init_irq = mx35_init_irq, - .init_time = mx35pdk_timer_init, - .init_machine = mx35_3ds_init, - .init_late = mx35_3ds_late_init, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c deleted file mode 100644 index 27a3678e0658..000000000000 --- a/arch/arm/mach-imx/mach-pca100.c +++ /dev/null @@ -1,426 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix - * Copyright (C) 2009 Sascha Hauer (kernel@pengutronix.de) - */ - -#include <linux/platform_device.h> -#include <linux/io.h> -#include <linux/i2c.h> -#include <linux/property.h> -#include <linux/dma-mapping.h> -#include <linux/spi/spi.h> -#include <linux/spi/eeprom.h> -#include <linux/irq.h> -#include <linux/delay.h> -#include <linux/gpio.h> -#include <linux/gpio/machine.h> -#include <linux/usb/otg.h> -#include <linux/usb/ulpi.h> - -#include <asm/mach/arch.h> -#include <asm/mach-types.h> -#include <asm/mach/time.h> - -#include "common.h" -#include "devices-imx27.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx27.h" -#include "ulpi.h" - -#define OTG_PHY_CS_GPIO (GPIO_PORTB + 23) -#define USBH2_PHY_CS_GPIO (GPIO_PORTB + 24) -#define SPI1_SS0 (GPIO_PORTD + 28) -#define SPI1_SS1 (GPIO_PORTD + 27) -#define SD2_CD (GPIO_PORTC + 29) - -static const int pca100_pins[] __initconst = { - /* UART1 */ - PE12_PF_UART1_TXD, - PE13_PF_UART1_RXD, - PE14_PF_UART1_CTS, - PE15_PF_UART1_RTS, - /* SDHC */ - PB4_PF_SD2_D0, - PB5_PF_SD2_D1, - PB6_PF_SD2_D2, - PB7_PF_SD2_D3, - PB8_PF_SD2_CMD, - PB9_PF_SD2_CLK, - SD2_CD | GPIO_GPIO | GPIO_IN, - /* FEC */ - PD0_AIN_FEC_TXD0, - PD1_AIN_FEC_TXD1, - PD2_AIN_FEC_TXD2, - PD3_AIN_FEC_TXD3, - PD4_AOUT_FEC_RX_ER, - PD5_AOUT_FEC_RXD1, - PD6_AOUT_FEC_RXD2, - PD7_AOUT_FEC_RXD3, - PD8_AF_FEC_MDIO, - PD9_AIN_FEC_MDC, - PD10_AOUT_FEC_CRS, - PD11_AOUT_FEC_TX_CLK, - PD12_AOUT_FEC_RXD0, - PD13_AOUT_FEC_RX_DV, - PD14_AOUT_FEC_RX_CLK, - PD15_AOUT_FEC_COL, - PD16_AIN_FEC_TX_ER, - PF23_AIN_FEC_TX_EN, - /* SSI1 */ - PC20_PF_SSI1_FS, - PC21_PF_SSI1_RXD, - PC22_PF_SSI1_TXD, - PC23_PF_SSI1_CLK, - /* onboard I2C */ - PC5_PF_I2C2_SDA, - PC6_PF_I2C2_SCL, - /* external I2C */ - PD17_PF_I2C_DATA, - PD18_PF_I2C_CLK, - /* SPI1 */ - PD25_PF_CSPI1_RDY, - PD29_PF_CSPI1_SCLK, - PD30_PF_CSPI1_MISO, - PD31_PF_CSPI1_MOSI, - /* OTG */ - OTG_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT, - PC7_PF_USBOTG_DATA5, - PC8_PF_USBOTG_DATA6, - PC9_PF_USBOTG_DATA0, - PC10_PF_USBOTG_DATA2, - PC11_PF_USBOTG_DATA1, - PC12_PF_USBOTG_DATA4, - PC13_PF_USBOTG_DATA3, - PE0_PF_USBOTG_NXT, - PE1_PF_USBOTG_STP, - PE2_PF_USBOTG_DIR, - PE24_PF_USBOTG_CLK, - PE25_PF_USBOTG_DATA7, - /* USBH2 */ - USBH2_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT, - PA0_PF_USBH2_CLK, - PA1_PF_USBH2_DIR, - PA2_PF_USBH2_DATA7, - PA3_PF_USBH2_NXT, - PA4_PF_USBH2_STP, - PD19_AF_USBH2_DATA4, - PD20_AF_USBH2_DATA3, - PD21_AF_USBH2_DATA6, - PD22_AF_USBH2_DATA0, - PD23_AF_USBH2_DATA2, - PD24_AF_USBH2_DATA1, - PD26_AF_USBH2_DATA5, - /* display */ - PA5_PF_LSCLK, - PA6_PF_LD0, - PA7_PF_LD1, - PA8_PF_LD2, - PA9_PF_LD3, - PA10_PF_LD4, - PA11_PF_LD5, - PA12_PF_LD6, - PA13_PF_LD7, - PA14_PF_LD8, - PA15_PF_LD9, - PA16_PF_LD10, - PA17_PF_LD11, - PA18_PF_LD12, - PA19_PF_LD13, - PA20_PF_LD14, - PA21_PF_LD15, - PA22_PF_LD16, - PA23_PF_LD17, - PA26_PF_PS, - PA28_PF_HSYNC, - PA29_PF_VSYNC, - PA31_PF_OE_ACD, - /* free GPIO */ - GPIO_PORTC | 31 | GPIO_GPIO | GPIO_IN, /* GPIO0_IRQ */ - GPIO_PORTC | 25 | GPIO_GPIO | GPIO_IN, /* GPIO1_IRQ */ - GPIO_PORTE | 5 | GPIO_GPIO | GPIO_IN, /* GPIO2_IRQ */ -}; - -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static const struct mxc_nand_platform_data -pca100_nand_board_info __initconst = { - .width = 1, - .hw_ecc = 1, -}; - -static const struct imxi2c_platform_data pca100_i2c1_data __initconst = { - .bitrate = 100000, -}; - -static const struct property_entry board_eeprom_properties[] = { - PROPERTY_ENTRY_U32("pagesize", 32), - { } -}; - -static struct i2c_board_info pca100_i2c_devices[] = { - { - I2C_BOARD_INFO("24c32", 0x52), /* E0=0, E1=1, E2=0 */ - .properties = board_eeprom_properties, - }, { - I2C_BOARD_INFO("pcf8563", 0x51), - }, { - I2C_BOARD_INFO("lm75", 0x4a), - } -}; - -static struct spi_eeprom at25320 = { - .name = "at25320an", - .byte_len = 4096, - .page_size = 32, - .flags = EE_ADDR2, -}; - -static struct spi_board_info pca100_spi_board_info[] __initdata = { - { - .modalias = "at25", - .max_speed_hz = 30000, - .bus_num = 0, - .chip_select = 1, - .platform_data = &at25320, - }, -}; - -static struct gpiod_lookup_table pca100_spi0_gpiod_table = { - .dev_id = "imx27-cspi.0", /* Actual device name for spi0 */ - .table = { - /* - * The i.MX27 has the i.MX21 GPIO controller, port D is - * bank 3 and thus named "imx21-gpio.3". - * SPI1_SS0 is GPIO_PORTD + 28 - * SPI1_SS1 is GPIO_PORTD + 27 - */ - GPIO_LOOKUP_IDX("imx21-gpio.3", 28, "cs", 0, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX("imx21-gpio.3", 27, "cs", 1, GPIO_ACTIVE_LOW), - { }, - }, -}; - -static void pca100_ac97_warm_reset(struct snd_ac97 *ac97) -{ - mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT); - gpio_set_value(GPIO_PORTC + 20, 1); - udelay(2); - gpio_set_value(GPIO_PORTC + 20, 0); - mxc_gpio_mode(PC20_PF_SSI1_FS); - msleep(2); -} - -static void pca100_ac97_cold_reset(struct snd_ac97 *ac97) -{ - mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT); /* FS */ - gpio_set_value(GPIO_PORTC + 20, 0); - mxc_gpio_mode(GPIO_PORTC | 22 | GPIO_GPIO | GPIO_OUT); /* TX */ - gpio_set_value(GPIO_PORTC + 22, 0); - mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_OUT); /* reset */ - gpio_set_value(GPIO_PORTC + 28, 0); - udelay(10); - gpio_set_value(GPIO_PORTC + 28, 1); - mxc_gpio_mode(PC20_PF_SSI1_FS); - mxc_gpio_mode(PC22_PF_SSI1_TXD); - msleep(2); -} - -static const struct imx_ssi_platform_data pca100_ssi_pdata __initconst = { - .ac97_reset = pca100_ac97_cold_reset, - .ac97_warm_reset = pca100_ac97_warm_reset, - .flags = IMX_SSI_USE_AC97, -}; - -static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq, - void *data) -{ - int ret; - - ret = request_irq(gpio_to_irq(IMX_GPIO_NR(3, 29)), detect_irq, - IRQF_TRIGGER_FALLING, "imx-mmc-detect", data); - if (ret) - printk(KERN_ERR - "pca100: Failed to request irq for sd/mmc detection\n"); - - return ret; -} - -static void pca100_sdhc2_exit(struct device *dev, void *data) -{ - free_irq(gpio_to_irq(IMX_GPIO_NR(3, 29)), data); -} - -static const struct imxmmc_platform_data sdhc_pdata __initconst = { - .init = pca100_sdhc2_init, - .exit = pca100_sdhc2_exit, -}; - -static int otg_phy_init(struct platform_device *pdev) -{ - gpio_set_value(OTG_PHY_CS_GPIO, 0); - - mdelay(10); - - return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI); -} - -static struct mxc_usbh_platform_data otg_pdata __initdata = { - .init = otg_phy_init, - .portsc = MXC_EHCI_MODE_ULPI, -}; - -static int usbh2_phy_init(struct platform_device *pdev) -{ - gpio_set_value(USBH2_PHY_CS_GPIO, 0); - - mdelay(10); - - return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI); -} - -static struct mxc_usbh_platform_data usbh2_pdata __initdata = { - .init = usbh2_phy_init, - .portsc = MXC_EHCI_MODE_ULPI, -}; - -static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_ULPI, -}; - -static bool otg_mode_host __initdata; - -static int __init pca100_otg_mode(char *options) -{ - if (!strcmp(options, "host")) - otg_mode_host = true; - else if (!strcmp(options, "device")) - otg_mode_host = false; - else - pr_info("otg_mode neither \"host\" nor \"device\". " - "Defaulting to device\n"); - return 1; -} -__setup("otg_mode=", pca100_otg_mode); - -/* framebuffer info */ -static struct imx_fb_videomode pca100_fb_modes[] = { - { - .mode = { - .name = "EMERGING-ETV570G0DHU", - .refresh = 60, - .xres = 640, - .yres = 480, - .pixclock = 39722, /* in ps (25.175 MHz) */ - .hsync_len = 30, - .left_margin = 114, - .right_margin = 16, - .vsync_len = 3, - .upper_margin = 32, - .lower_margin = 0, - }, - /* - * TFT - * Pixel pol active high - * HSYNC active low - * VSYNC active low - * use HSYNC for ACD count - * line clock disable while idle - * always enable line clock even if no data - */ - .pcr = 0xf0c08080, - .bpp = 16, - }, -}; - -static const struct imx_fb_platform_data pca100_fb_data __initconst = { - .mode = pca100_fb_modes, - .num_modes = ARRAY_SIZE(pca100_fb_modes), - - .pwmr = 0x00A903FF, - .lscr1 = 0x00120300, - .dmacr = 0x00020010, -}; - -static void __init pca100_init(void) -{ - int ret; - - imx27_soc_init(); - - ret = mxc_gpio_setup_multiple_pins(pca100_pins, - ARRAY_SIZE(pca100_pins), "PCA100"); - if (ret) - printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret); - - imx27_add_imx_uart0(&uart_pdata); - - imx27_add_mxc_nand(&pca100_nand_board_info); - - /* only the i2c master 1 is used on this CPU card */ - i2c_register_board_info(1, pca100_i2c_devices, - ARRAY_SIZE(pca100_i2c_devices)); - - imx27_add_imx_i2c(1, &pca100_i2c1_data); - - mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_IN); - mxc_gpio_mode(GPIO_PORTD | 27 | GPIO_GPIO | GPIO_IN); - spi_register_board_info(pca100_spi_board_info, - ARRAY_SIZE(pca100_spi_board_info)); - imx27_add_spi_imx0(&pca100_spi0_gpiod_table); - - imx27_add_imx_fb(&pca100_fb_data); - - imx27_add_fec(NULL); - imx27_add_imx2_wdt(); - imx27_add_mxc_w1(); -} - -static void __init pca100_late_init(void) -{ - imx27_add_imx_ssi(0, &pca100_ssi_pdata); - - imx27_add_mxc_mmc(1, &sdhc_pdata); - - gpio_request(OTG_PHY_CS_GPIO, "usb-otg-cs"); - gpio_direction_output(OTG_PHY_CS_GPIO, 1); - gpio_request(USBH2_PHY_CS_GPIO, "usb-host2-cs"); - gpio_direction_output(USBH2_PHY_CS_GPIO, 1); - - if (otg_mode_host) { - otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | - ULPI_OTG_DRVVBUS_EXT); - - if (otg_pdata.otg) - imx27_add_mxc_ehci_otg(&otg_pdata); - } else { - gpio_set_value(OTG_PHY_CS_GPIO, 0); - imx27_add_fsl_usb2_udc(&otg_device_pdata); - } - - usbh2_pdata.otg = imx_otg_ulpi_create( - ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); - - if (usbh2_pdata.otg) - imx27_add_mxc_ehci_hs(2, &usbh2_pdata); -} - -static void __init pca100_timer_init(void) -{ - mx27_clocks_init(26000000); -} - -MACHINE_START(PCA100, "phyCARD-i.MX27") - .atag_offset = 0x100, - .map_io = mx27_map_io, - .init_early = imx27_init_early, - .init_irq = mx27_init_irq, - .init_machine = pca100_init, - .init_late = pca100_late_init, - .init_time = pca100_timer_init, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c deleted file mode 100644 index c7d23e9d4f8b..000000000000 --- a/arch/arm/mach-imx/mach-pcm037.c +++ /dev/null @@ -1,585 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2008 Sascha Hauer, Pengutronix - */ - -#include <linux/types.h> -#include <linux/init.h> -#include <linux/dma-mapping.h> -#include <linux/platform_device.h> -#include <linux/mtd/physmap.h> -#include <linux/mtd/plat-ram.h> -#include <linux/memory.h> -#include <linux/gpio.h> -#include <linux/smsc911x.h> -#include <linux/interrupt.h> -#include <linux/i2c.h> -#include <linux/property.h> -#include <linux/delay.h> -#include <linux/spi/spi.h> -#include <linux/irq.h> -#include <linux/can/platform/sja1000.h> -#include <linux/usb/otg.h> -#include <linux/usb/ulpi.h> -#include <linux/gfp.h> -#include <linux/regulator/machine.h> -#include <linux/regulator/fixed.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/mach/map.h> - -#include "common.h" -#include "devices-imx31.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx3.h" -#include "pcm037.h" -#include "ulpi.h" - -static enum pcm037_board_variant pcm037_instance = PCM037_PCM970; - -static int __init pcm037_variant_setup(char *str) -{ - if (!strcmp("eet", str)) - pcm037_instance = PCM037_EET; - else if (strcmp("pcm970", str)) - pr_warn("Unknown pcm037 baseboard variant %s\n", str); - - return 1; -} - -/* Supported values: "pcm970" (default) and "eet" */ -__setup("pcm037_variant=", pcm037_variant_setup); - -enum pcm037_board_variant pcm037_variant(void) -{ - return pcm037_instance; -} - -/* UART1 with RTS/CTS handshake signals */ -static unsigned int pcm037_uart1_handshake_pins[] = { - MX31_PIN_CTS1__CTS1, - MX31_PIN_RTS1__RTS1, - MX31_PIN_TXD1__TXD1, - MX31_PIN_RXD1__RXD1, -}; - -/* UART1 without RTS/CTS handshake signals */ -static unsigned int pcm037_uart1_pins[] = { - MX31_PIN_TXD1__TXD1, - MX31_PIN_RXD1__RXD1, -}; - -static unsigned int pcm037_pins[] = { - /* I2C */ - MX31_PIN_CSPI2_MOSI__SCL, - MX31_PIN_CSPI2_MISO__SDA, - MX31_PIN_CSPI2_SS2__I2C3_SDA, - MX31_PIN_CSPI2_SCLK__I2C3_SCL, - /* SDHC1 */ - MX31_PIN_SD1_DATA3__SD1_DATA3, - MX31_PIN_SD1_DATA2__SD1_DATA2, - MX31_PIN_SD1_DATA1__SD1_DATA1, - MX31_PIN_SD1_DATA0__SD1_DATA0, - MX31_PIN_SD1_CLK__SD1_CLK, - MX31_PIN_SD1_CMD__SD1_CMD, - IOMUX_MODE(MX31_PIN_SCK6, IOMUX_CONFIG_GPIO), /* card detect */ - IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO), /* write protect */ - /* SPI1 */ - MX31_PIN_CSPI1_MOSI__MOSI, - MX31_PIN_CSPI1_MISO__MISO, - MX31_PIN_CSPI1_SCLK__SCLK, - MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, - MX31_PIN_CSPI1_SS0__SS0, - MX31_PIN_CSPI1_SS1__SS1, - MX31_PIN_CSPI1_SS2__SS2, - /* UART2 */ - MX31_PIN_TXD2__TXD2, - MX31_PIN_RXD2__RXD2, - MX31_PIN_CTS2__CTS2, - MX31_PIN_RTS2__RTS2, - /* UART3 */ - MX31_PIN_CSPI3_MOSI__RXD3, - MX31_PIN_CSPI3_MISO__TXD3, - MX31_PIN_CSPI3_SCLK__RTS3, - MX31_PIN_CSPI3_SPI_RDY__CTS3, - /* LAN9217 irq pin */ - IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO), - /* Onewire */ - MX31_PIN_BATT_LINE__OWIRE, - /* Framebuffer */ - MX31_PIN_LD0__LD0, - MX31_PIN_LD1__LD1, - MX31_PIN_LD2__LD2, - MX31_PIN_LD3__LD3, - MX31_PIN_LD4__LD4, - MX31_PIN_LD5__LD5, - MX31_PIN_LD6__LD6, - MX31_PIN_LD7__LD7, - MX31_PIN_LD8__LD8, - MX31_PIN_LD9__LD9, - MX31_PIN_LD10__LD10, - MX31_PIN_LD11__LD11, - MX31_PIN_LD12__LD12, - MX31_PIN_LD13__LD13, - MX31_PIN_LD14__LD14, - MX31_PIN_LD15__LD15, - MX31_PIN_LD16__LD16, - MX31_PIN_LD17__LD17, - MX31_PIN_VSYNC3__VSYNC3, - MX31_PIN_HSYNC__HSYNC, - MX31_PIN_FPSHIFT__FPSHIFT, - MX31_PIN_DRDY0__DRDY0, - MX31_PIN_D3_REV__D3_REV, - MX31_PIN_CONTRAST__CONTRAST, - MX31_PIN_D3_SPL__D3_SPL, - MX31_PIN_D3_CLS__D3_CLS, - MX31_PIN_LCS0__GPIO3_23, - /* GPIO */ - IOMUX_MODE(MX31_PIN_ATA_DMACK, IOMUX_CONFIG_GPIO), - /* OTG */ - MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, - MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, - MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, - MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, - MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, - MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, - MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, - MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, - MX31_PIN_USBOTG_CLK__USBOTG_CLK, - MX31_PIN_USBOTG_DIR__USBOTG_DIR, - MX31_PIN_USBOTG_NXT__USBOTG_NXT, - MX31_PIN_USBOTG_STP__USBOTG_STP, - /* USB host 2 */ - IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC), - IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC), -}; - -static struct physmap_flash_data pcm037_flash_data = { - .width = 2, -}; - -static struct resource pcm037_flash_resource = { - .start = 0xa0000000, - .end = 0xa1ffffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device pcm037_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &pcm037_flash_data, - }, - .resource = &pcm037_flash_resource, - .num_resources = 1, -}; - -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static struct resource smsc911x_resources[] = { - { - .start = MX31_CS1_BASE_ADDR + 0x300, - .end = MX31_CS1_BASE_ADDR + 0x300 + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, { - /* irq number is run-time assigned */ - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, - }, -}; - -static struct smsc911x_platform_config smsc911x_info = { - .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY | - SMSC911X_SAVE_MAC_ADDRESS, - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, - .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, - .phy_interface = PHY_INTERFACE_MODE_MII, -}; - -static struct platform_device pcm037_eth = { - .name = "smsc911x", - .id = -1, - .num_resources = ARRAY_SIZE(smsc911x_resources), - .resource = smsc911x_resources, - .dev = { - .platform_data = &smsc911x_info, - }, -}; - -static struct platdata_mtd_ram pcm038_sram_data = { - .bankwidth = 2, -}; - -static struct resource pcm038_sram_resource = { - .start = MX31_CS4_BASE_ADDR, - .end = MX31_CS4_BASE_ADDR + 512 * 1024 - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device pcm037_sram_device = { - .name = "mtd-ram", - .id = 0, - .dev = { - .platform_data = &pcm038_sram_data, - }, - .num_resources = 1, - .resource = &pcm038_sram_resource, -}; - -static const struct mxc_nand_platform_data -pcm037_nand_board_info __initconst = { - .width = 1, - .hw_ecc = 1, -}; - -static const struct imxi2c_platform_data pcm037_i2c1_data __initconst = { - .bitrate = 100000, -}; - -static const struct imxi2c_platform_data pcm037_i2c2_data __initconst = { - .bitrate = 20000, -}; - -static const struct property_entry board_eeprom_properties[] = { - PROPERTY_ENTRY_U32("pagesize", 32), - { } -}; - -static struct i2c_board_info pcm037_i2c_devices[] = { - { - I2C_BOARD_INFO("24c32", 0x52), /* E0=0, E1=1, E2=0 */ - .properties = board_eeprom_properties, - }, { - I2C_BOARD_INFO("pcf8563", 0x51), - } -}; - -/* Not connected by default */ -#ifdef PCM970_SDHC_RW_SWITCH -static int pcm970_sdhc1_get_ro(struct device *dev) -{ - return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_SFS6)); -} -#endif - -#define SDHC1_GPIO_WP IOMUX_TO_GPIO(MX31_PIN_SFS6) -#define SDHC1_GPIO_DET IOMUX_TO_GPIO(MX31_PIN_SCK6) - -static int pcm970_sdhc1_init(struct device *dev, irq_handler_t detect_irq, - void *data) -{ - int ret; - - ret = gpio_request(SDHC1_GPIO_DET, "sdhc-detect"); - if (ret) - return ret; - - gpio_direction_input(SDHC1_GPIO_DET); - -#ifdef PCM970_SDHC_RW_SWITCH - ret = gpio_request(SDHC1_GPIO_WP, "sdhc-wp"); - if (ret) - goto err_gpio_free; - gpio_direction_input(SDHC1_GPIO_WP); -#endif - - ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SCK6)), detect_irq, - IRQF_TRIGGER_FALLING, "sdhc-detect", data); - if (ret) - goto err_gpio_free_2; - - return 0; - -err_gpio_free_2: -#ifdef PCM970_SDHC_RW_SWITCH - gpio_free(SDHC1_GPIO_WP); -err_gpio_free: -#endif - gpio_free(SDHC1_GPIO_DET); - - return ret; -} - -static void pcm970_sdhc1_exit(struct device *dev, void *data) -{ - free_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_SCK6)), data); - gpio_free(SDHC1_GPIO_DET); - gpio_free(SDHC1_GPIO_WP); -} - -static const struct imxmmc_platform_data sdhc_pdata __initconst = { -#ifdef PCM970_SDHC_RW_SWITCH - .get_ro = pcm970_sdhc1_get_ro, -#endif - .init = pcm970_sdhc1_init, - .exit = pcm970_sdhc1_exit, -}; - -static struct platform_device *devices[] __initdata = { - &pcm037_flash, - &pcm037_sram_device, -}; - -static const struct fb_videomode fb_modedb[] = { - { - /* 240x320 @ 60 Hz Sharp */ - .name = "Sharp-LQ035Q7DH06-QVGA", - .refresh = 60, - .xres = 240, - .yres = 320, - .pixclock = 185925, - .left_margin = 9, - .right_margin = 16, - .upper_margin = 7, - .lower_margin = 9, - .hsync_len = 1, - .vsync_len = 1, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | - FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* 240x320 @ 60 Hz */ - .name = "TX090", - .refresh = 60, - .xres = 240, - .yres = 320, - .pixclock = 38255, - .left_margin = 144, - .right_margin = 0, - .upper_margin = 7, - .lower_margin = 40, - .hsync_len = 96, - .vsync_len = 1, - .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* 240x320 @ 60 Hz */ - .name = "CMEL-OLED", - .refresh = 60, - .xres = 240, - .yres = 320, - .pixclock = 185925, - .left_margin = 9, - .right_margin = 16, - .upper_margin = 7, - .lower_margin = 9, - .hsync_len = 1, - .vsync_len = 1, - .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, -}; - -static struct mx3fb_platform_data mx3fb_pdata = { - .name = "Sharp-LQ035Q7DH06-QVGA", - .mode = fb_modedb, - .num_modes = ARRAY_SIZE(fb_modedb), -}; - -static struct resource pcm970_sja1000_resources[] = { - { - .start = MX31_CS5_BASE_ADDR, - .end = MX31_CS5_BASE_ADDR + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, { - /* irq number is run-time assigned */ - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, - }, -}; - -static struct sja1000_platform_data pcm970_sja1000_platform_data = { - .osc_freq = 16000000, - .ocr = OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL, - .cdr = CDR_CBP, -}; - -static struct platform_device pcm970_sja1000 = { - .name = "sja1000_platform", - .dev = { - .platform_data = &pcm970_sja1000_platform_data, - }, - .resource = pcm970_sja1000_resources, - .num_resources = ARRAY_SIZE(pcm970_sja1000_resources), -}; - -static int pcm037_otg_init(struct platform_device *pdev) -{ - return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI); -} - -static struct mxc_usbh_platform_data otg_pdata __initdata = { - .init = pcm037_otg_init, - .portsc = MXC_EHCI_MODE_ULPI, -}; - -static int pcm037_usbh2_init(struct platform_device *pdev) -{ - return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI); -} - -static struct mxc_usbh_platform_data usbh2_pdata __initdata = { - .init = pcm037_usbh2_init, - .portsc = MXC_EHCI_MODE_ULPI, -}; - -static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_ULPI, -}; - -static bool otg_mode_host __initdata; - -static int __init pcm037_otg_mode(char *options) -{ - if (!strcmp(options, "host")) - otg_mode_host = true; - else if (!strcmp(options, "device")) - otg_mode_host = false; - else - pr_info("otg_mode neither \"host\" nor \"device\". " - "Defaulting to device\n"); - return 1; -} -__setup("otg_mode=", pcm037_otg_mode); - -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vdd33a", "smsc911x"), - REGULATOR_SUPPLY("vddvario", "smsc911x"), -}; - -/* - * Board specific initialization. - */ -static void __init pcm037_init(void) -{ - imx31_soc_init(); - - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - - mxc_iomux_set_gpr(MUX_PGP_UH2, 1); - - mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins), - "pcm037"); - -#define H2_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS \ - | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) - - mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, H2_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, H2_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, H2_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_STP, H2_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, H2_PAD_CFG); /* USBH2_DATA0 */ - mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, H2_PAD_CFG); /* USBH2_DATA1 */ - mxc_iomux_set_pad(MX31_PIN_SRXD6, H2_PAD_CFG); /* USBH2_DATA2 */ - mxc_iomux_set_pad(MX31_PIN_STXD6, H2_PAD_CFG); /* USBH2_DATA3 */ - mxc_iomux_set_pad(MX31_PIN_SFS3, H2_PAD_CFG); /* USBH2_DATA4 */ - mxc_iomux_set_pad(MX31_PIN_SCK3, H2_PAD_CFG); /* USBH2_DATA5 */ - mxc_iomux_set_pad(MX31_PIN_SRXD3, H2_PAD_CFG); /* USBH2_DATA6 */ - mxc_iomux_set_pad(MX31_PIN_STXD3, H2_PAD_CFG); /* USBH2_DATA7 */ - - if (pcm037_variant() == PCM037_EET) - mxc_iomux_setup_multiple_pins(pcm037_uart1_pins, - ARRAY_SIZE(pcm037_uart1_pins), "pcm037_uart1"); - else - mxc_iomux_setup_multiple_pins(pcm037_uart1_handshake_pins, - ARRAY_SIZE(pcm037_uart1_handshake_pins), - "pcm037_uart1"); - - platform_add_devices(devices, ARRAY_SIZE(devices)); - - imx31_add_imx2_wdt(); - imx31_add_imx_uart0(&uart_pdata); - /* XXX: should't this have .flags = 0 (i.e. no RTSCTS) on PCM037_EET? */ - imx31_add_imx_uart1(&uart_pdata); - imx31_add_imx_uart2(&uart_pdata); - - imx31_add_mxc_w1(); - - /* I2C adapters and devices */ - i2c_register_board_info(1, pcm037_i2c_devices, - ARRAY_SIZE(pcm037_i2c_devices)); - - imx31_add_imx_i2c1(&pcm037_i2c1_data); - imx31_add_imx_i2c2(&pcm037_i2c2_data); - - imx31_add_mxc_nand(&pcm037_nand_board_info); - imx31_add_ipu_core(); - imx31_add_mx3_sdc_fb(&mx3fb_pdata); - - if (otg_mode_host) { - otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | - ULPI_OTG_DRVVBUS_EXT); - if (otg_pdata.otg) - imx31_add_mxc_ehci_otg(&otg_pdata); - } - - usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | - ULPI_OTG_DRVVBUS_EXT); - if (usbh2_pdata.otg) - imx31_add_mxc_ehci_hs(2, &usbh2_pdata); - - if (!otg_mode_host) - imx31_add_fsl_usb2_udc(&otg_device_pdata); -} - -static void __init pcm037_timer_init(void) -{ - mx31_clocks_init(26000000); -} - -static void __init pcm037_init_late(void) -{ - int ret; - - /* LAN9217 IRQ pin */ - ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1), "lan9217-irq"); - if (!ret) { - gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)); - smsc911x_resources[1].start = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)); - smsc911x_resources[1].end = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)); - platform_device_register(&pcm037_eth); - } else { - pr_warn("could not get LAN irq gpio\n"); - } - - imx31_add_mxc_mmc(0, &sdhc_pdata); - - pcm970_sja1000_resources[1].start = - gpio_to_irq(IOMUX_TO_GPIO(IOMUX_PIN(48, 105))); - pcm970_sja1000_resources[1].end = - gpio_to_irq(IOMUX_TO_GPIO(IOMUX_PIN(48, 105))); - platform_device_register(&pcm970_sja1000); - - pcm037_eet_init_devices(); -} - -MACHINE_START(PCM037, "Phytec Phycore pcm037") - /* Maintainer: Pengutronix */ - .atag_offset = 0x100, - .map_io = mx31_map_io, - .init_early = imx31_init_early, - .init_irq = mx31_init_irq, - .init_time = pcm037_timer_init, - .init_machine = pcm037_init, - .init_late = pcm037_init_late, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-pcm037_eet.c b/arch/arm/mach-imx/mach-pcm037_eet.c deleted file mode 100644 index 8b0e03a595c1..000000000000 --- a/arch/arm/mach-imx/mach-pcm037_eet.c +++ /dev/null @@ -1,166 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009 - * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de> - */ -#include <linux/gpio.h> -#include <linux/input.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> - -#include <asm/mach-types.h> - -#include "pcm037.h" -#include "common.h" -#include "devices-imx31.h" -#include "iomux-mx3.h" - -static unsigned int pcm037_eet_pins[] = { - /* Reserve and hardwire GPIO 57 high - S6E63D6 chipselect */ - IOMUX_MODE(MX31_PIN_KEY_COL7, IOMUX_CONFIG_GPIO), - /* GPIO keys */ - IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO), /* 0 */ - IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO), /* 1 */ - IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO), /* 2 */ - IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO), /* 3 */ - IOMUX_MODE(MX31_PIN_SVEN0, IOMUX_CONFIG_GPIO), /* 32 */ - IOMUX_MODE(MX31_PIN_STX0, IOMUX_CONFIG_GPIO), /* 33 */ - IOMUX_MODE(MX31_PIN_SRX0, IOMUX_CONFIG_GPIO), /* 34 */ - IOMUX_MODE(MX31_PIN_SIMPD0, IOMUX_CONFIG_GPIO), /* 35 */ - IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_GPIO), /* 38 */ - IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_GPIO), /* 39 */ - IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_GPIO), /* 50 */ - IOMUX_MODE(MX31_PIN_KEY_ROW5, IOMUX_CONFIG_GPIO), /* 51 */ - IOMUX_MODE(MX31_PIN_KEY_ROW6, IOMUX_CONFIG_GPIO), /* 52 */ - IOMUX_MODE(MX31_PIN_KEY_ROW7, IOMUX_CONFIG_GPIO), /* 53 */ - - /* LEDs */ - IOMUX_MODE(MX31_PIN_DTR_DTE1, IOMUX_CONFIG_GPIO), /* 44 */ - IOMUX_MODE(MX31_PIN_DSR_DTE1, IOMUX_CONFIG_GPIO), /* 45 */ - IOMUX_MODE(MX31_PIN_KEY_COL5, IOMUX_CONFIG_GPIO), /* 55 */ - IOMUX_MODE(MX31_PIN_KEY_COL6, IOMUX_CONFIG_GPIO), /* 56 */ -}; - -/* SPI */ -static struct spi_board_info pcm037_spi_dev[] = { - { - .modalias = "dac124s085", - .max_speed_hz = 400000, - .bus_num = 0, - .chip_select = 1, /* Index in pcm037_spi1_cs[] */ - .mode = SPI_CPHA, - }, -}; - -/* GPIO-keys input device */ -static struct gpio_keys_button pcm037_gpio_keys[] = { - { - .type = EV_KEY, - .code = KEY_L, - .gpio = 0, - .desc = "Wheel Manual", - .wakeup = 0, - }, { - .type = EV_KEY, - .code = KEY_A, - .gpio = 1, - .desc = "Wheel AF", - .wakeup = 0, - }, { - .type = EV_KEY, - .code = KEY_V, - .gpio = 2, - .desc = "Wheel View", - .wakeup = 0, - }, { - .type = EV_KEY, - .code = KEY_M, - .gpio = 3, - .desc = "Wheel Menu", - .wakeup = 0, - }, { - .type = EV_KEY, - .code = KEY_UP, - .gpio = 32, - .desc = "Nav Pad Up", - .wakeup = 0, - }, { - .type = EV_KEY, - .code = KEY_RIGHT, - .gpio = 33, - .desc = "Nav Pad Right", - .wakeup = 0, - }, { - .type = EV_KEY, - .code = KEY_DOWN, - .gpio = 34, - .desc = "Nav Pad Down", - .wakeup = 0, - }, { - .type = EV_KEY, - .code = KEY_LEFT, - .gpio = 35, - .desc = "Nav Pad Left", - .wakeup = 0, - }, { - .type = EV_KEY, - .code = KEY_ENTER, - .gpio = 38, - .desc = "Nav Pad Ok", - .wakeup = 0, - }, { - .type = EV_KEY, - .code = KEY_O, - .gpio = 39, - .desc = "Wheel Off", - .wakeup = 0, - }, { - .type = EV_KEY, - .code = BTN_FORWARD, - .gpio = 50, - .desc = "Focus Forward", - .wakeup = 0, - }, { - .type = EV_KEY, - .code = BTN_BACK, - .gpio = 51, - .desc = "Focus Backward", - .wakeup = 0, - }, { - .type = EV_KEY, - .code = BTN_MIDDLE, - .gpio = 52, - .desc = "Release Half", - .wakeup = 0, - }, { - .type = EV_KEY, - .code = BTN_EXTRA, - .gpio = 53, - .desc = "Release Full", - .wakeup = 0, - }, -}; - -static const struct gpio_keys_platform_data - pcm037_gpio_keys_platform_data __initconst = { - .buttons = pcm037_gpio_keys, - .nbuttons = ARRAY_SIZE(pcm037_gpio_keys), - .rep = 0, /* No auto-repeat */ -}; - -int __init pcm037_eet_init_devices(void) -{ - if (pcm037_variant() != PCM037_EET) - return 0; - - mxc_iomux_setup_multiple_pins(pcm037_eet_pins, - ARRAY_SIZE(pcm037_eet_pins), "pcm037_eet"); - - /* SPI */ - spi_register_board_info(pcm037_spi_dev, ARRAY_SIZE(pcm037_spi_dev)); - imx31_add_spi_imx0(NULL); - - imx_add_gpio_keys(&pcm037_gpio_keys_platform_data); - - return 0; -} diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c deleted file mode 100644 index 017a50113005..000000000000 --- a/arch/arm/mach-imx/mach-pcm043.c +++ /dev/null @@ -1,412 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2009 Sascha Hauer, Pengutronix - */ - -#include <linux/types.h> -#include <linux/init.h> - -#include <linux/platform_device.h> -#include <linux/mtd/physmap.h> -#include <linux/mtd/plat-ram.h> -#include <linux/memory.h> -#include <linux/gpio.h> -#include <linux/gpio/machine.h> -#include <linux/smc911x.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/i2c.h> -#include <linux/property.h> -#include <linux/usb/otg.h> -#include <linux/usb/ulpi.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/mach/map.h> - -#include "common.h" -#include "devices-imx35.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx35.h" -#include "ulpi.h" - -static const struct fb_videomode fb_modedb[] = { - { - /* 240x320 @ 60 Hz */ - .name = "Sharp-LQ035Q7", - .refresh = 60, - .xres = 240, - .yres = 320, - .pixclock = 185925, - .left_margin = 9, - .right_margin = 16, - .upper_margin = 7, - .lower_margin = 9, - .hsync_len = 1, - .vsync_len = 1, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* 240x320 @ 60 Hz */ - .name = "TX090", - .refresh = 60, - .xres = 240, - .yres = 320, - .pixclock = 38255, - .left_margin = 144, - .right_margin = 0, - .upper_margin = 7, - .lower_margin = 40, - .hsync_len = 96, - .vsync_len = 1, - .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, -}; - -static struct mx3fb_platform_data mx3fb_pdata __initdata = { - .name = "Sharp-LQ035Q7", - .mode = fb_modedb, - .num_modes = ARRAY_SIZE(fb_modedb), -}; - -static struct physmap_flash_data pcm043_flash_data = { - .width = 2, -}; - -static struct resource pcm043_flash_resource = { - .start = 0xa0000000, - .end = 0xa1ffffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device pcm043_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &pcm043_flash_data, - }, - .resource = &pcm043_flash_resource, - .num_resources = 1, -}; - -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static const struct imxi2c_platform_data pcm043_i2c0_data __initconst = { - .bitrate = 50000, -}; - -static const struct property_entry board_eeprom_properties[] = { - PROPERTY_ENTRY_U32("pagesize", 32), - { } -}; - -static struct i2c_board_info pcm043_i2c_devices[] = { - { - I2C_BOARD_INFO("24c32", 0x52), /* E0=0, E1=1, E2=0 */ - .properties = board_eeprom_properties, - }, { - I2C_BOARD_INFO("pcf8563", 0x51), - }, -}; - -static struct platform_device *devices[] __initdata = { - &pcm043_flash, -}; - -static const iomux_v3_cfg_t pcm043_pads[] __initconst = { - /* UART1 */ - MX35_PAD_CTS1__UART1_CTS, - MX35_PAD_RTS1__UART1_RTS, - MX35_PAD_TXD1__UART1_TXD_MUX, - MX35_PAD_RXD1__UART1_RXD_MUX, - /* UART2 */ - MX35_PAD_CTS2__UART2_CTS, - MX35_PAD_RTS2__UART2_RTS, - MX35_PAD_TXD2__UART2_TXD_MUX, - MX35_PAD_RXD2__UART2_RXD_MUX, - /* FEC */ - MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, - MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, - MX35_PAD_FEC_RX_DV__FEC_RX_DV, - MX35_PAD_FEC_COL__FEC_COL, - MX35_PAD_FEC_RDATA0__FEC_RDATA_0, - MX35_PAD_FEC_TDATA0__FEC_TDATA_0, - MX35_PAD_FEC_TX_EN__FEC_TX_EN, - MX35_PAD_FEC_MDC__FEC_MDC, - MX35_PAD_FEC_MDIO__FEC_MDIO, - MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, - MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, - MX35_PAD_FEC_CRS__FEC_CRS, - MX35_PAD_FEC_RDATA1__FEC_RDATA_1, - MX35_PAD_FEC_TDATA1__FEC_TDATA_1, - MX35_PAD_FEC_RDATA2__FEC_RDATA_2, - MX35_PAD_FEC_TDATA2__FEC_TDATA_2, - MX35_PAD_FEC_RDATA3__FEC_RDATA_3, - MX35_PAD_FEC_TDATA3__FEC_TDATA_3, - /* I2C1 */ - MX35_PAD_I2C1_CLK__I2C1_SCL, - MX35_PAD_I2C1_DAT__I2C1_SDA, - /* Display */ - MX35_PAD_LD0__IPU_DISPB_DAT_0, - MX35_PAD_LD1__IPU_DISPB_DAT_1, - MX35_PAD_LD2__IPU_DISPB_DAT_2, - MX35_PAD_LD3__IPU_DISPB_DAT_3, - MX35_PAD_LD4__IPU_DISPB_DAT_4, - MX35_PAD_LD5__IPU_DISPB_DAT_5, - MX35_PAD_LD6__IPU_DISPB_DAT_6, - MX35_PAD_LD7__IPU_DISPB_DAT_7, - MX35_PAD_LD8__IPU_DISPB_DAT_8, - MX35_PAD_LD9__IPU_DISPB_DAT_9, - MX35_PAD_LD10__IPU_DISPB_DAT_10, - MX35_PAD_LD11__IPU_DISPB_DAT_11, - MX35_PAD_LD12__IPU_DISPB_DAT_12, - MX35_PAD_LD13__IPU_DISPB_DAT_13, - MX35_PAD_LD14__IPU_DISPB_DAT_14, - MX35_PAD_LD15__IPU_DISPB_DAT_15, - MX35_PAD_LD16__IPU_DISPB_DAT_16, - MX35_PAD_LD17__IPU_DISPB_DAT_17, - MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC, - MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK, - MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY, - MX35_PAD_CONTRAST__IPU_DISPB_CONTR, - MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC, - MX35_PAD_D3_REV__IPU_DISPB_D3_REV, - MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS, - /* gpio */ - MX35_PAD_ATA_CS0__GPIO2_6, - /* USB host */ - MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR, - MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC, - /* SSI */ - MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS, - MX35_PAD_STXD4__AUDMUX_AUD4_TXD, - MX35_PAD_SRXD4__AUDMUX_AUD4_RXD, - MX35_PAD_SCK4__AUDMUX_AUD4_TXC, - /* CAN2 */ - MX35_PAD_TX5_RX0__CAN2_TXCAN, - MX35_PAD_TX4_RX1__CAN2_RXCAN, - /* esdhc */ - MX35_PAD_SD1_CMD__ESDHC1_CMD, - MX35_PAD_SD1_CLK__ESDHC1_CLK, - MX35_PAD_SD1_DATA0__ESDHC1_DAT0, - MX35_PAD_SD1_DATA1__ESDHC1_DAT1, - MX35_PAD_SD1_DATA2__ESDHC1_DAT2, - MX35_PAD_SD1_DATA3__ESDHC1_DAT3, - MX35_PAD_ATA_DATA10__GPIO2_23, /* WriteProtect */ - MX35_PAD_ATA_DATA11__GPIO2_24, /* CardDetect */ -}; - -#define AC97_GPIO_TXFS IMX_GPIO_NR(2, 31) -#define AC97_GPIO_TXD IMX_GPIO_NR(2, 28) -#define AC97_GPIO_RESET IMX_GPIO_NR(2, 0) - -static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97) -{ - iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31; - iomux_v3_cfg_t txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS; - int ret; - - ret = gpio_request(AC97_GPIO_TXFS, "SSI"); - if (ret) { - printk("failed to get GPIO_TXFS: %d\n", ret); - return; - } - - mxc_iomux_v3_setup_pad(txfs_gpio); - - /* warm reset */ - gpio_direction_output(AC97_GPIO_TXFS, 1); - udelay(2); - gpio_set_value(AC97_GPIO_TXFS, 0); - - gpio_free(AC97_GPIO_TXFS); - mxc_iomux_v3_setup_pad(txfs); -} - -static void pcm043_ac97_cold_reset(struct snd_ac97 *ac97) -{ - iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31; - iomux_v3_cfg_t txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS; - iomux_v3_cfg_t txd_gpio = MX35_PAD_STXD4__GPIO2_28; - iomux_v3_cfg_t txd = MX35_PAD_STXD4__AUDMUX_AUD4_TXD; - iomux_v3_cfg_t reset_gpio = MX35_PAD_SD2_CMD__GPIO2_0; - int ret; - - ret = gpio_request(AC97_GPIO_TXFS, "SSI"); - if (ret) - goto err1; - - ret = gpio_request(AC97_GPIO_TXD, "SSI"); - if (ret) - goto err2; - - ret = gpio_request(AC97_GPIO_RESET, "SSI"); - if (ret) - goto err3; - - mxc_iomux_v3_setup_pad(txfs_gpio); - mxc_iomux_v3_setup_pad(txd_gpio); - mxc_iomux_v3_setup_pad(reset_gpio); - - gpio_direction_output(AC97_GPIO_TXFS, 0); - gpio_direction_output(AC97_GPIO_TXD, 0); - - /* cold reset */ - gpio_direction_output(AC97_GPIO_RESET, 0); - udelay(10); - gpio_direction_output(AC97_GPIO_RESET, 1); - - mxc_iomux_v3_setup_pad(txd); - mxc_iomux_v3_setup_pad(txfs); - - gpio_free(AC97_GPIO_RESET); -err3: - gpio_free(AC97_GPIO_TXD); -err2: - gpio_free(AC97_GPIO_TXFS); -err1: - if (ret) - printk("%s failed with %d\n", __func__, ret); - mdelay(1); -} - -static const struct imx_ssi_platform_data pcm043_ssi_pdata __initconst = { - .ac97_reset = pcm043_ac97_cold_reset, - .ac97_warm_reset = pcm043_ac97_warm_reset, - .flags = IMX_SSI_USE_AC97, -}; - -static const struct mxc_nand_platform_data -pcm037_nand_board_info __initconst = { - .width = 1, - .hw_ecc = 1, -}; - -static int pcm043_otg_init(struct platform_device *pdev) -{ - return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI); -} - -static struct mxc_usbh_platform_data otg_pdata __initdata = { - .init = pcm043_otg_init, - .portsc = MXC_EHCI_MODE_UTMI, -}; - -static int pcm043_usbh1_init(struct platform_device *pdev) -{ - return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI | - MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN); -} - -static const struct mxc_usbh_platform_data usbh1_pdata __initconst = { - .init = pcm043_usbh1_init, - .portsc = MXC_EHCI_MODE_SERIAL, -}; - -static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_UTMI, -}; - -static bool otg_mode_host __initdata; - -static int __init pcm043_otg_mode(char *options) -{ - if (!strcmp(options, "host")) - otg_mode_host = true; - else if (!strcmp(options, "device")) - otg_mode_host = false; - else - pr_info("otg_mode neither \"host\" nor \"device\". " - "Defaulting to device\n"); - return 1; -} -__setup("otg_mode=", pcm043_otg_mode); - -static struct esdhc_platform_data sd1_pdata = { - .wp_type = ESDHC_WP_GPIO, - .cd_type = ESDHC_CD_GPIO, -}; - -static struct gpiod_lookup_table sd1_gpio_table = { - .dev_id = "sdhci-esdhc-imx35.0", - .table = { - /* Card detect: bank 2 offset 24 */ - GPIO_LOOKUP("imx35-gpio.2", 24, "cd", GPIO_ACTIVE_LOW), - /* Write protect: bank 2 offset 23 */ - GPIO_LOOKUP("imx35-gpio.2", 23, "wp", GPIO_ACTIVE_LOW), - { }, - }, -}; - -/* - * Board specific initialization. - */ -static void __init pcm043_init(void) -{ - imx35_soc_init(); - - mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads)); - - imx35_add_fec(NULL); - platform_add_devices(devices, ARRAY_SIZE(devices)); - imx35_add_imx2_wdt(); - - imx35_add_imx_uart0(&uart_pdata); - imx35_add_mxc_nand(&pcm037_nand_board_info); - - imx35_add_imx_uart1(&uart_pdata); - - i2c_register_board_info(0, pcm043_i2c_devices, - ARRAY_SIZE(pcm043_i2c_devices)); - - imx35_add_imx_i2c0(&pcm043_i2c0_data); - - imx35_add_ipu_core(); - imx35_add_mx3_sdc_fb(&mx3fb_pdata); - - if (otg_mode_host) { - otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | - ULPI_OTG_DRVVBUS_EXT); - if (otg_pdata.otg) - imx35_add_mxc_ehci_otg(&otg_pdata); - } - imx35_add_mxc_ehci_hs(&usbh1_pdata); - - if (!otg_mode_host) - imx35_add_fsl_usb2_udc(&otg_device_pdata); - - imx35_add_flexcan1(); -} - -static void __init pcm043_late_init(void) -{ - imx35_add_imx_ssi(0, &pcm043_ssi_pdata); - - gpiod_add_lookup_table(&sd1_gpio_table); - imx35_add_sdhci_esdhc_imx(0, &sd1_pdata); -} - -static void __init pcm043_timer_init(void) -{ - mx35_clocks_init(); -} - -MACHINE_START(PCM043, "Phytec Phycore pcm043") - /* Maintainer: Pengutronix */ - .atag_offset = 0x100, - .map_io = mx35_map_io, - .init_early = imx35_init_early, - .init_irq = mx35_init_irq, - .init_time = pcm043_timer_init, - .init_machine = pcm043_init, - .init_late = pcm043_late_init, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c deleted file mode 100644 index 5b362da2dc09..000000000000 --- a/arch/arm/mach-imx/mach-qong.c +++ /dev/null @@ -1,262 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com> - */ - -#include <linux/types.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/memory.h> -#include <linux/platform_device.h> -#include <linux/mtd/physmap.h> -#include <linux/mtd/platnand.h> -#include <linux/gpio.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/mach/map.h> -#include <asm/page.h> -#include <asm/setup.h> - -#include "common.h" -#include "devices-imx31.h" -#include "hardware.h" -#include "iomux-mx3.h" - -/* FPGA defines */ -#define QONG_FPGA_VERSION(major, minor, rev) \ - (((major & 0xF) << 12) | ((minor & 0xF) << 8) | (rev & 0xFF)) - -#define QONG_FPGA_BASEADDR MX31_CS1_BASE_ADDR -#define QONG_FPGA_PERIPH_SIZE (1 << 24) - -#define QONG_FPGA_CTRL_BASEADDR QONG_FPGA_BASEADDR -#define QONG_FPGA_CTRL_SIZE 0x10 -/* FPGA control registers */ -#define QONG_FPGA_CTRL_VERSION 0x00 - -#define QONG_DNET_ID 1 -#define QONG_DNET_BASEADDR \ - (QONG_FPGA_BASEADDR + QONG_DNET_ID * QONG_FPGA_PERIPH_SIZE) -#define QONG_DNET_SIZE 0x00001000 - -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static int uart_pins[] = { - MX31_PIN_CTS1__CTS1, - MX31_PIN_RTS1__RTS1, - MX31_PIN_TXD1__TXD1, - MX31_PIN_RXD1__RXD1 -}; - -static inline void __init mxc_init_imx_uart(void) -{ - mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), - "uart-0"); - imx31_add_imx_uart0(&uart_pdata); -} - -static struct resource dnet_resources[] = { - { - .name = "dnet-memory", - .start = QONG_DNET_BASEADDR, - .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1, - .flags = IORESOURCE_MEM, - }, { - /* irq number is run-time assigned */ - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device dnet_device = { - .name = "dnet", - .id = -1, - .num_resources = ARRAY_SIZE(dnet_resources), - .resource = dnet_resources, -}; - -static int __init qong_init_dnet(void) -{ - int ret; - - dnet_resources[1].start = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)); - dnet_resources[1].end = - gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)); - ret = platform_device_register(&dnet_device); - return ret; -} - -/* MTD NOR flash */ - -static struct physmap_flash_data qong_flash_data = { - .width = 2, -}; - -static struct resource qong_flash_resource = { - .start = MX31_CS0_BASE_ADDR, - .end = MX31_CS0_BASE_ADDR + SZ_128M - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device qong_nor_mtd_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &qong_flash_data, - }, - .resource = &qong_flash_resource, - .num_resources = 1, -}; - -static void qong_init_nor_mtd(void) -{ - (void)platform_device_register(&qong_nor_mtd_device); -} - -/* - * Hardware specific access to control-lines - */ -static void qong_nand_cmd_ctrl(struct nand_chip *nand_chip, int cmd, - unsigned int ctrl) -{ - if (cmd == NAND_CMD_NONE) - return; - - if (ctrl & NAND_CLE) - writeb(cmd, nand_chip->legacy.IO_ADDR_W + (1 << 24)); - else - writeb(cmd, nand_chip->legacy.IO_ADDR_W + (1 << 23)); -} - -/* - * Read the Device Ready pin. - */ -static int qong_nand_device_ready(struct nand_chip *chip) -{ - return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB)); -} - -static void qong_nand_select_chip(struct nand_chip *chip, int cs) -{ - if (cs >= 0) - gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0); - else - gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1); -} - -static struct platform_nand_data qong_nand_data = { - .chip = { - .nr_chips = 1, - .chip_delay = 20, - .options = 0, - }, - .ctrl = { - .cmd_ctrl = qong_nand_cmd_ctrl, - .dev_ready = qong_nand_device_ready, - .select_chip = qong_nand_select_chip, - } -}; - -static struct resource qong_nand_resource = { - .start = MX31_CS3_BASE_ADDR, - .end = MX31_CS3_BASE_ADDR + SZ_32M - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device qong_nand_device = { - .name = "gen_nand", - .id = -1, - .dev = { - .platform_data = &qong_nand_data, - }, - .num_resources = 1, - .resource = &qong_nand_resource, -}; - -static void __init qong_init_nand_mtd(void) -{ - /* init CS */ - imx_writel(0x00004f00, MX31_IO_ADDRESS(MX31_WEIM_CSCRxU(3))); - imx_writel(0x20013b31, MX31_IO_ADDRESS(MX31_WEIM_CSCRxL(3))); - imx_writel(0x00020800, MX31_IO_ADDRESS(MX31_WEIM_CSCRxA(3))); - - mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true); - - /* enable pin */ - mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFCE_B, IOMUX_CONFIG_GPIO)); - if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), "nand_enable")) - gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0); - - /* ready/busy pin */ - mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFRB, IOMUX_CONFIG_GPIO)); - if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFRB), "nand_rdy")) - gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFRB)); - - /* write protect pin */ - mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFWP_B, IOMUX_CONFIG_GPIO)); - if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFWP_B), "nand_wp")) - gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFWP_B)); - - platform_device_register(&qong_nand_device); -} - -static void __init qong_init_fpga(void) -{ - void __iomem *regs; - u32 fpga_ver; - - regs = ioremap(QONG_FPGA_CTRL_BASEADDR, QONG_FPGA_CTRL_SIZE); - if (!regs) { - printk(KERN_ERR "%s: failed to map registers, aborting.\n", - __func__); - return; - } - - fpga_ver = readl(regs + QONG_FPGA_CTRL_VERSION); - iounmap(regs); - printk(KERN_INFO "Qong FPGA version %d.%d.%d\n", - (fpga_ver & 0xF000) >> 12, - (fpga_ver & 0x0F00) >> 8, fpga_ver & 0x00FF); - if (fpga_ver < QONG_FPGA_VERSION(0, 8, 7)) { - printk(KERN_ERR "qong: Unexpected FPGA version, FPGA-based " - "devices won't be registered!\n"); - return; - } - - /* register FPGA-based devices */ - qong_init_nand_mtd(); - qong_init_dnet(); -} - -/* - * Board specific initialization. - */ -static void __init qong_init(void) -{ - imx31_soc_init(); - - mxc_init_imx_uart(); - qong_init_nor_mtd(); - imx31_add_imx2_wdt(); -} - -static void __init qong_timer_init(void) -{ - mx31_clocks_init(26000000); -} - -MACHINE_START(QONG, "Dave/DENX QongEVB-LITE") - /* Maintainer: DENX Software Engineering GmbH */ - .atag_offset = 0x100, - .map_io = mx31_map_io, - .init_early = imx31_init_early, - .init_irq = mx31_init_irq, - .init_time = qong_timer_init, - .init_machine = qong_init, - .init_late = qong_init_fpga, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mach-vpr200.c b/arch/arm/mach-imx/mach-vpr200.c deleted file mode 100644 index fae5a41b5f6c..000000000000 --- a/arch/arm/mach-imx/mach-vpr200.c +++ /dev/null @@ -1,306 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix - * Copyright 2010 Creative Product Design - * - * Derived from mx35 3stack. - * Original author: Fabio Estevam <fabio.estevam@freescale.com> - */ - -#include <linux/types.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/mtd/physmap.h> -#include <linux/memory.h> -#include <linux/gpio.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/time.h> - -#include <linux/i2c.h> -#include <linux/mfd/mc13xxx.h> - -#include "common.h" -#include "devices-imx35.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx35.h" - -#define GPIO_LCDPWR IMX_GPIO_NR(1, 2) -#define GPIO_PMIC_INT IMX_GPIO_NR(2, 0) - -#define GPIO_BUTTON1 IMX_GPIO_NR(1, 4) -#define GPIO_BUTTON2 IMX_GPIO_NR(1, 5) -#define GPIO_BUTTON3 IMX_GPIO_NR(1, 7) -#define GPIO_BUTTON4 IMX_GPIO_NR(1, 8) -#define GPIO_BUTTON5 IMX_GPIO_NR(1, 9) -#define GPIO_BUTTON6 IMX_GPIO_NR(1, 10) -#define GPIO_BUTTON7 IMX_GPIO_NR(1, 11) -#define GPIO_BUTTON8 IMX_GPIO_NR(1, 12) - -static const struct fb_videomode fb_modedb[] = { - { - /* 800x480 @ 60 Hz */ - .name = "PT0708048", - .refresh = 60, - .xres = 800, - .yres = 480, - .pixclock = KHZ2PICOS(33260), - .left_margin = 50, - .right_margin = 156, - .upper_margin = 10, - .lower_margin = 10, - .hsync_len = 1, /* note: DE only display */ - .vsync_len = 1, /* note: DE only display */ - .sync = FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* 800x480 @ 60 Hz */ - .name = "CTP-CLAA070LC0ACW", - .refresh = 60, - .xres = 800, - .yres = 480, - .pixclock = KHZ2PICOS(27000), - .left_margin = 50, - .right_margin = 50, /* whole line should have 900 clocks */ - .upper_margin = 10, - .lower_margin = 10, /* whole frame should have 500 lines */ - .hsync_len = 1, /* note: DE only display */ - .vsync_len = 1, /* note: DE only display */ - .sync = FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - } -}; - -static struct mx3fb_platform_data mx3fb_pdata __initdata = { - .name = "PT0708048", - .mode = fb_modedb, - .num_modes = ARRAY_SIZE(fb_modedb), -}; - -static struct physmap_flash_data vpr200_flash_data = { - .width = 2, -}; - -static struct resource vpr200_flash_resource = { - .start = MX35_CS0_BASE_ADDR, - .end = MX35_CS0_BASE_ADDR + SZ_64M - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device vpr200_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &vpr200_flash_data, - }, - .resource = &vpr200_flash_resource, - .num_resources = 1, -}; - -static const struct mxc_nand_platform_data - vpr200_nand_board_info __initconst = { - .width = 1, - .hw_ecc = 1, - .flash_bbt = 1, -}; - -#define VPR_KEY_DEBOUNCE 500 -static struct gpio_keys_button vpr200_gpio_keys_table[] = { - {KEY_F2, GPIO_BUTTON1, 1, "vpr-keys: F2", 0, VPR_KEY_DEBOUNCE}, - {KEY_F3, GPIO_BUTTON2, 1, "vpr-keys: F3", 0, VPR_KEY_DEBOUNCE}, - {KEY_F4, GPIO_BUTTON3, 1, "vpr-keys: F4", 0, VPR_KEY_DEBOUNCE}, - {KEY_F5, GPIO_BUTTON4, 1, "vpr-keys: F5", 0, VPR_KEY_DEBOUNCE}, - {KEY_F6, GPIO_BUTTON5, 1, "vpr-keys: F6", 0, VPR_KEY_DEBOUNCE}, - {KEY_F7, GPIO_BUTTON6, 1, "vpr-keys: F7", 0, VPR_KEY_DEBOUNCE}, - {KEY_F8, GPIO_BUTTON7, 1, "vpr-keys: F8", 1, VPR_KEY_DEBOUNCE}, - {KEY_F9, GPIO_BUTTON8, 1, "vpr-keys: F9", 1, VPR_KEY_DEBOUNCE}, -}; - -static const struct gpio_keys_platform_data - vpr200_gpio_keys_data __initconst = { - .buttons = vpr200_gpio_keys_table, - .nbuttons = ARRAY_SIZE(vpr200_gpio_keys_table), -}; - -static struct mc13xxx_platform_data vpr200_pmic = { - .flags = MC13XXX_USE_ADC | MC13XXX_USE_TOUCHSCREEN, -}; - -static const struct imxi2c_platform_data vpr200_i2c0_data __initconst = { - .bitrate = 50000, -}; - -static struct i2c_board_info vpr200_i2c_devices[] = { - { - I2C_BOARD_INFO("24c02", 0x50), /* E0=0, E1=0, E2=0 */ - }, { - I2C_BOARD_INFO("mc13892", 0x08), - .platform_data = &vpr200_pmic, - /* irq number is run-time assigned */ - } -}; - -static const iomux_v3_cfg_t vpr200_pads[] __initconst = { - /* UART1 */ - MX35_PAD_TXD1__UART1_TXD_MUX, - MX35_PAD_RXD1__UART1_RXD_MUX, - /* UART3 */ - MX35_PAD_ATA_DATA10__UART3_RXD_MUX, - MX35_PAD_ATA_DATA11__UART3_TXD_MUX, - /* FEC */ - MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, - MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, - MX35_PAD_FEC_RX_DV__FEC_RX_DV, - MX35_PAD_FEC_COL__FEC_COL, - MX35_PAD_FEC_RDATA0__FEC_RDATA_0, - MX35_PAD_FEC_TDATA0__FEC_TDATA_0, - MX35_PAD_FEC_TX_EN__FEC_TX_EN, - MX35_PAD_FEC_MDC__FEC_MDC, - MX35_PAD_FEC_MDIO__FEC_MDIO, - MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, - MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, - MX35_PAD_FEC_CRS__FEC_CRS, - MX35_PAD_FEC_RDATA1__FEC_RDATA_1, - MX35_PAD_FEC_TDATA1__FEC_TDATA_1, - MX35_PAD_FEC_RDATA2__FEC_RDATA_2, - MX35_PAD_FEC_TDATA2__FEC_TDATA_2, - MX35_PAD_FEC_RDATA3__FEC_RDATA_3, - MX35_PAD_FEC_TDATA3__FEC_TDATA_3, - /* Display */ - MX35_PAD_LD0__IPU_DISPB_DAT_0, - MX35_PAD_LD1__IPU_DISPB_DAT_1, - MX35_PAD_LD2__IPU_DISPB_DAT_2, - MX35_PAD_LD3__IPU_DISPB_DAT_3, - MX35_PAD_LD4__IPU_DISPB_DAT_4, - MX35_PAD_LD5__IPU_DISPB_DAT_5, - MX35_PAD_LD6__IPU_DISPB_DAT_6, - MX35_PAD_LD7__IPU_DISPB_DAT_7, - MX35_PAD_LD8__IPU_DISPB_DAT_8, - MX35_PAD_LD9__IPU_DISPB_DAT_9, - MX35_PAD_LD10__IPU_DISPB_DAT_10, - MX35_PAD_LD11__IPU_DISPB_DAT_11, - MX35_PAD_LD12__IPU_DISPB_DAT_12, - MX35_PAD_LD13__IPU_DISPB_DAT_13, - MX35_PAD_LD14__IPU_DISPB_DAT_14, - MX35_PAD_LD15__IPU_DISPB_DAT_15, - MX35_PAD_LD16__IPU_DISPB_DAT_16, - MX35_PAD_LD17__IPU_DISPB_DAT_17, - MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK, - MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY, - MX35_PAD_CONTRAST__IPU_DISPB_CONTR, - /* LCD Enable */ - MX35_PAD_D3_VSYNC__GPIO1_2, - /* USBOTG */ - MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR, - MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC, - /* SDCARD */ - MX35_PAD_SD1_CMD__ESDHC1_CMD, - MX35_PAD_SD1_CLK__ESDHC1_CLK, - MX35_PAD_SD1_DATA0__ESDHC1_DAT0, - MX35_PAD_SD1_DATA1__ESDHC1_DAT1, - MX35_PAD_SD1_DATA2__ESDHC1_DAT2, - MX35_PAD_SD1_DATA3__ESDHC1_DAT3, - /* PMIC */ - MX35_PAD_GPIO2_0__GPIO2_0, - /* GPIO keys */ - MX35_PAD_SCKR__GPIO1_4, - MX35_PAD_COMPARE__GPIO1_5, - MX35_PAD_SCKT__GPIO1_7, - MX35_PAD_FST__GPIO1_8, - MX35_PAD_HCKT__GPIO1_9, - MX35_PAD_TX5_RX0__GPIO1_10, - MX35_PAD_TX4_RX1__GPIO1_11, - MX35_PAD_TX3_RX2__GPIO1_12, -}; - -/* USB Device config */ -static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_UTMI, - .workaround = FLS_USB2_WORKAROUND_ENGCM09152, -}; - -static int vpr200_usbh_init(struct platform_device *pdev) -{ - return mx35_initialize_usb_hw(pdev->id, - MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY); -} - -/* USB HOST config */ -static const struct mxc_usbh_platform_data usb_host_pdata __initconst = { - .init = vpr200_usbh_init, - .portsc = MXC_EHCI_MODE_SERIAL, -}; - -static struct platform_device *devices[] __initdata = { - &vpr200_flash, -}; - -/* - * Board specific initialization. - */ -static void __init vpr200_board_init(void) -{ - imx35_soc_init(); - - mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads)); - - imx35_add_fec(NULL); - imx35_add_imx2_wdt(); - - imx35_add_imx_uart0(NULL); - imx35_add_imx_uart2(NULL); - - imx35_add_ipu_core(); - imx35_add_mx3_sdc_fb(&mx3fb_pdata); - - imx35_add_fsl_usb2_udc(&otg_device_pdata); - imx35_add_mxc_ehci_hs(&usb_host_pdata); - - imx35_add_mxc_nand(&vpr200_nand_board_info); - imx35_add_sdhci_esdhc_imx(0, NULL); -} - -static void __init vpr200_late_init(void) -{ - imx_add_gpio_keys(&vpr200_gpio_keys_data); - - platform_add_devices(devices, ARRAY_SIZE(devices)); - - if (0 != gpio_request(GPIO_LCDPWR, "LCDPWR")) - printk(KERN_WARNING "vpr200: Couldn't get LCDPWR gpio\n"); - else - gpio_direction_output(GPIO_LCDPWR, 0); - - if (0 != gpio_request(GPIO_PMIC_INT, "PMIC_INT")) - printk(KERN_WARNING "vpr200: Couldn't get PMIC_INT gpio\n"); - else - gpio_direction_input(GPIO_PMIC_INT); - - vpr200_i2c_devices[1].irq = gpio_to_irq(GPIO_PMIC_INT); - i2c_register_board_info(0, vpr200_i2c_devices, - ARRAY_SIZE(vpr200_i2c_devices)); - - imx35_add_imx_i2c0(&vpr200_i2c0_data); -} - -static void __init vpr200_timer_init(void) -{ - mx35_clocks_init(); -} - -MACHINE_START(VPR200, "VPR200") - /* Maintainer: Creative Product Design */ - .map_io = mx35_map_io, - .init_early = imx35_init_early, - .init_irq = mx35_init_irq, - .init_time = vpr200_timer_init, - .init_machine = vpr200_board_init, - .init_late = vpr200_late_init, - .restart = mxc_restart, -MACHINE_END diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c deleted file mode 100644 index b834026e4615..000000000000 --- a/arch/arm/mach-imx/mm-imx21.c +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * arch/arm/mach-imx/mm-imx21.c - * - * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) - */ - -#include <linux/mm.h> -#include <linux/init.h> -#include <linux/pinctrl/machine.h> -#include <asm/mach/map.h> - -#include "common.h" -#include "devices/devices-common.h" -#include "hardware.h" -#include "iomux-v1.h" - -/* MX21 memory map definition */ -static struct map_desc imx21_io_desc[] __initdata = { - /* - * this fixed mapping covers: - * - AIPI1 - * - AIPI2 - * - AITC - * - ROM Patch - * - and some reserved space - */ - imx_map_entry(MX21, AIPI, MT_DEVICE), - /* - * this fixed mapping covers: - * - CSI - * - ATA - */ - imx_map_entry(MX21, SAHB1, MT_DEVICE), - /* - * this fixed mapping covers: - * - EMI - */ - imx_map_entry(MX21, X_MEMC, MT_DEVICE), -}; - -/* - * Initialize the memory map. It is called during the - * system startup to create static physical to virtual - * memory map for the IO modules. - */ -void __init mx21_map_io(void) -{ - iotable_init(imx21_io_desc, ARRAY_SIZE(imx21_io_desc)); -} - -void __init imx21_init_early(void) -{ - mxc_set_cpu_type(MXC_CPU_MX21); - imx_iomuxv1_init(MX21_IO_ADDRESS(MX21_GPIO_BASE_ADDR), - MX21_NUM_GPIO_PORT); -} - -void __init mx21_init_irq(void) -{ - mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR)); -} - -static const struct resource imx21_audmux_res[] __initconst = { - DEFINE_RES_MEM(MX21_AUDMUX_BASE_ADDR, SZ_4K), -}; - -void __init imx21_soc_init(void) -{ - mxc_arch_reset_init(MX21_IO_ADDRESS(MX21_WDOG_BASE_ADDR)); - mxc_device_init(); - - mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); - mxc_register_gpio("imx21-gpio", 1, MX21_GPIO2_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); - mxc_register_gpio("imx21-gpio", 2, MX21_GPIO3_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); - mxc_register_gpio("imx21-gpio", 3, MX21_GPIO4_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); - mxc_register_gpio("imx21-gpio", 4, MX21_GPIO5_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); - mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); - - pinctrl_provide_dummies(); - imx_add_imx_dma("imx21-dma", MX21_DMA_BASE_ADDR, MX21_INT_DMACH0); - platform_device_register_simple("imx21-audmux", 0, imx21_audmux_res, - ARRAY_SIZE(imx21_audmux_res)); -} diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c deleted file mode 100644 index 2717614f101d..000000000000 --- a/arch/arm/mach-imx/mm-imx27.c +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * arch/arm/mach-imx/mm-imx27.c - * - * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) - */ - -#include <linux/mm.h> -#include <linux/init.h> -#include <linux/pinctrl/machine.h> -#include <asm/mach/map.h> - -#include "common.h" -#include "devices/devices-common.h" -#include "hardware.h" -#include "iomux-v1.h" - -/* MX27 memory map definition */ -static struct map_desc imx27_io_desc[] __initdata = { - /* - * this fixed mapping covers: - * - AIPI1 - * - AIPI2 - * - AITC - * - ROM Patch - * - and some reserved space - */ - imx_map_entry(MX27, AIPI, MT_DEVICE), - /* - * this fixed mapping covers: - * - CSI - * - ATA - */ - imx_map_entry(MX27, SAHB1, MT_DEVICE), - /* - * this fixed mapping covers: - * - EMI - */ - imx_map_entry(MX27, X_MEMC, MT_DEVICE), -}; - -/* - * Initialize the memory map. It is called during the - * system startup to create static physical to virtual - * memory map for the IO modules. - */ -void __init mx27_map_io(void) -{ - iotable_init(imx27_io_desc, ARRAY_SIZE(imx27_io_desc)); -} - -void __init imx27_init_early(void) -{ - mxc_set_cpu_type(MXC_CPU_MX27); - imx_iomuxv1_init(MX27_IO_ADDRESS(MX27_GPIO_BASE_ADDR), - MX27_NUM_GPIO_PORT); -} - -void __init mx27_init_irq(void) -{ - mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR)); -} - -static const struct resource imx27_audmux_res[] __initconst = { - DEFINE_RES_MEM(MX27_AUDMUX_BASE_ADDR, SZ_4K), -}; - -void __init imx27_soc_init(void) -{ - mxc_arch_reset_init(MX27_IO_ADDRESS(MX27_WDOG_BASE_ADDR)); - mxc_device_init(); - - /* i.mx27 has the i.mx21 type gpio */ - mxc_register_gpio("imx21-gpio", 0, MX27_GPIO1_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); - mxc_register_gpio("imx21-gpio", 1, MX27_GPIO2_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); - mxc_register_gpio("imx21-gpio", 2, MX27_GPIO3_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); - mxc_register_gpio("imx21-gpio", 3, MX27_GPIO4_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); - mxc_register_gpio("imx21-gpio", 4, MX27_GPIO5_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); - mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); - - pinctrl_provide_dummies(); - imx_add_imx_dma("imx27-dma", MX27_DMA_BASE_ADDR, MX27_INT_DMACH0); - /* imx27 has the imx21 type audmux */ - platform_device_register_simple("imx21-audmux", 0, imx27_audmux_res, - ARRAY_SIZE(imx27_audmux_res)); - - imx27_pm_init(); -} diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c index ea2d58a63903..5056438e5b42 100644 --- a/arch/arm/mach-imx/mm-imx3.c +++ b/arch/arm/mach-imx/mm-imx3.c @@ -11,6 +11,7 @@ #include <linux/init.h> #include <linux/err.h> #include <linux/io.h> +#include <linux/of_address.h> #include <linux/pinctrl/machine.h> #include <asm/system_misc.h> @@ -19,9 +20,7 @@ #include "common.h" #include "crmregs-imx3.h" -#include "devices/devices-common.h" #include "hardware.h" -#include "iomux-v3.h" void __iomem *mx3_ccm_base; @@ -71,40 +70,6 @@ static void __iomem *imx3_ioremap_caller(phys_addr_t phys_addr, size_t size, return __arm_ioremap_caller(phys_addr, size, mtype, caller); } -static void __init imx3_init_l2x0(void) -{ -#ifdef CONFIG_CACHE_L2X0 - void __iomem *l2x0_base; - void __iomem *clkctl_base; - -/* - * First of all, we must repair broken chip settings. There are some - * i.MX35 CPUs in the wild, comming with bogus L2 cache settings. These - * misconfigured CPUs will run amok immediately when the L2 cache gets enabled. - * Workaraound is to setup the correct register setting prior enabling the - * L2 cache. This should not hurt already working CPUs, as they are using the - * same value. - */ -#define L2_MEM_VAL 0x10 - - clkctl_base = ioremap(MX35_CLKCTL_BASE_ADDR, 4096); - if (clkctl_base != NULL) { - writel(0x00000515, clkctl_base + L2_MEM_VAL); - iounmap(clkctl_base); - } else { - pr_err("L2 cache: Cannot fix timing. Trying to continue without\n"); - } - - l2x0_base = ioremap(MX3x_L2CC_BASE_ADDR, 4096); - if (!l2x0_base) { - printk(KERN_ERR "remapping L2 cache area failed\n"); - return; - } - - l2x0_init(l2x0_base, 0x00030024, 0x00000000); -#endif -} - #ifdef CONFIG_SOC_IMX31 static struct map_desc mx31_io_desc[] __initdata = { imx_map_entry(MX31, X_MEMC, MT_DEVICE), @@ -135,70 +100,26 @@ static void imx31_idle(void) void __init imx31_init_early(void) { + struct device_node *np; + mxc_set_cpu_type(MXC_CPU_MX31); arch_ioremap_caller = imx3_ioremap_caller; arm_pm_idle = imx31_idle; - mx3_ccm_base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR); + np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm"); + mx3_ccm_base = of_iomap(np, 0); + BUG_ON(!mx3_ccm_base); } void __init mx31_init_irq(void) { - mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR)); -} - -static struct sdma_script_start_addrs imx31_to1_sdma_script __initdata = { - .per_2_per_addr = 1677, -}; - -static struct sdma_script_start_addrs imx31_to2_sdma_script __initdata = { - .ap_2_ap_addr = 423, - .ap_2_bp_addr = 829, - .bp_2_ap_addr = 1029, -}; - -static struct sdma_platform_data imx31_sdma_pdata __initdata = { - .fw_name = "sdma-imx31-to2.bin", - .script_addrs = &imx31_to2_sdma_script, -}; - -static const struct resource imx31_audmux_res[] __initconst = { - DEFINE_RES_MEM(MX31_AUDMUX_BASE_ADDR, SZ_16K), -}; - -static const struct resource imx31_rnga_res[] __initconst = { - DEFINE_RES_MEM(MX31_RNGA_BASE_ADDR, SZ_16K), -}; - -void __init imx31_soc_init(void) -{ - int to_version = mx31_revision() >> 4; + void __iomem *avic_base; + struct device_node *np; - imx3_init_l2x0(); + np = of_find_compatible_node(NULL, NULL, "fsl,imx31-avic"); + avic_base = of_iomap(np, 0); + BUG_ON(!avic_base); - mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); - mxc_device_init(); - - mxc_register_gpio("imx31-gpio", 0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0); - mxc_register_gpio("imx31-gpio", 1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0); - mxc_register_gpio("imx31-gpio", 2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0); - - pinctrl_provide_dummies(); - - if (to_version == 1) { - strncpy(imx31_sdma_pdata.fw_name, "sdma-imx31-to1.bin", - strlen(imx31_sdma_pdata.fw_name)); - imx31_sdma_pdata.script_addrs = &imx31_to1_sdma_script; - } - - imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata); - - imx_set_aips(MX31_IO_ADDRESS(MX31_AIPS1_BASE_ADDR)); - imx_set_aips(MX31_IO_ADDRESS(MX31_AIPS2_BASE_ADDR)); - - platform_device_register_simple("imx31-audmux", 0, imx31_audmux_res, - ARRAY_SIZE(imx31_audmux_res)); - platform_device_register_simple("mxc_rnga", -1, imx31_rnga_res, - ARRAY_SIZE(imx31_rnga_res)); + mxc_init_irq(avic_base); } #endif /* ifdef CONFIG_SOC_IMX31 */ @@ -228,85 +149,25 @@ static void imx35_idle(void) void __init imx35_init_early(void) { + struct device_node *np; + mxc_set_cpu_type(MXC_CPU_MX35); - mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR)); arm_pm_idle = imx35_idle; arch_ioremap_caller = imx3_ioremap_caller; - mx3_ccm_base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR); + np = of_find_compatible_node(NULL, NULL, "fsl,imx35-ccm"); + mx3_ccm_base = of_iomap(np, 0); + BUG_ON(!mx3_ccm_base); } void __init mx35_init_irq(void) { - mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR)); -} - -static struct sdma_script_start_addrs imx35_to1_sdma_script __initdata = { - .ap_2_ap_addr = 642, - .uart_2_mcu_addr = 817, - .mcu_2_app_addr = 747, - .uartsh_2_mcu_addr = 1183, - .per_2_shp_addr = 1033, - .mcu_2_shp_addr = 961, - .ata_2_mcu_addr = 1333, - .mcu_2_ata_addr = 1252, - .app_2_mcu_addr = 683, - .shp_2_per_addr = 1111, - .shp_2_mcu_addr = 892, -}; - -static struct sdma_script_start_addrs imx35_to2_sdma_script __initdata = { - .ap_2_ap_addr = 729, - .uart_2_mcu_addr = 904, - .per_2_app_addr = 1597, - .mcu_2_app_addr = 834, - .uartsh_2_mcu_addr = 1270, - .per_2_shp_addr = 1120, - .mcu_2_shp_addr = 1048, - .ata_2_mcu_addr = 1429, - .mcu_2_ata_addr = 1339, - .app_2_per_addr = 1531, - .app_2_mcu_addr = 770, - .shp_2_per_addr = 1198, - .shp_2_mcu_addr = 979, -}; - -static struct sdma_platform_data imx35_sdma_pdata __initdata = { - .fw_name = "sdma-imx35-to2.bin", - .script_addrs = &imx35_to2_sdma_script, -}; - -static const struct resource imx35_audmux_res[] __initconst = { - DEFINE_RES_MEM(MX35_AUDMUX_BASE_ADDR, SZ_16K), -}; - -void __init imx35_soc_init(void) -{ - int to_version = mx35_revision() >> 4; - - imx3_init_l2x0(); - - mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR)); - mxc_device_init(); - - mxc_register_gpio("imx35-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0); - mxc_register_gpio("imx35-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0); - mxc_register_gpio("imx35-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0); - - pinctrl_provide_dummies(); - if (to_version == 1) { - strncpy(imx35_sdma_pdata.fw_name, "sdma-imx35-to1.bin", - strlen(imx35_sdma_pdata.fw_name)); - imx35_sdma_pdata.script_addrs = &imx35_to1_sdma_script; - } - - imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata); + void __iomem *avic_base; + struct device_node *np; - /* Setup AIPS registers */ - imx_set_aips(MX35_IO_ADDRESS(MX35_AIPS1_BASE_ADDR)); - imx_set_aips(MX35_IO_ADDRESS(MX35_AIPS2_BASE_ADDR)); + np = of_find_compatible_node(NULL, NULL, "fsl,imx35-avic"); + avic_base = of_iomap(np, 0); + BUG_ON(!avic_base); - /* i.mx35 has the i.mx31 type audmux */ - platform_device_register_simple("imx31-audmux", 0, imx35_audmux_res, - ARRAY_SIZE(imx35_audmux_res)); + mxc_init_irq(avic_base); } #endif /* ifdef CONFIG_SOC_IMX35 */ diff --git a/arch/arm/mach-imx/mx21.h b/arch/arm/mach-imx/mx21.h deleted file mode 100644 index 38be12a44bdd..000000000000 --- a/arch/arm/mach-imx/mx21.h +++ /dev/null @@ -1,176 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2008 Juergen Beisert, kernel@pengutronix.de - * Copyright 2009 Holger Schurig, hs4233@mail.mn-solutions.de - * - * This contains i.MX21-specific hardware definitions. For those - * hardware pieces that are common between i.MX21 and i.MX27, have a - * look at mx2x.h. - */ - -#ifndef __MACH_MX21_H__ -#define __MACH_MX21_H__ - -#define MX21_AIPI_BASE_ADDR 0x10000000 -#define MX21_AIPI_SIZE SZ_1M -#define MX21_DMA_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x01000) -#define MX21_WDOG_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x02000) -#define MX21_GPT1_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x03000) -#define MX21_GPT2_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x04000) -#define MX21_GPT3_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x05000) -#define MX21_PWM_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x06000) -#define MX21_RTC_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x07000) -#define MX21_KPP_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x08000) -#define MX21_OWIRE_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x09000) -#define MX21_UART1_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x0a000) -#define MX21_UART2_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x0b000) -#define MX21_UART3_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x0c000) -#define MX21_UART4_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x0d000) -#define MX21_CSPI1_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x0e000) -#define MX21_CSPI2_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x0f000) -#define MX21_SSI1_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x10000) -#define MX21_SSI2_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x11000) -#define MX21_I2C_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x12000) -#define MX21_SDHC1_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x13000) -#define MX21_SDHC2_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x14000) -#define MX21_GPIO_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x15000) -#define MX21_GPIO1_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x000) -#define MX21_GPIO2_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x100) -#define MX21_GPIO3_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x200) -#define MX21_GPIO4_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x300) -#define MX21_GPIO5_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x400) -#define MX21_GPIO6_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x500) -#define MX21_AUDMUX_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x16000) -#define MX21_CSPI3_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x17000) -#define MX21_LCDC_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x21000) -#define MX21_SLCDC_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x22000) -#define MX21_USBOTG_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x24000) -#define MX21_EMMA_PP_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x26000) -#define MX21_EMMA_PRP_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x26400) -#define MX21_CCM_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x27000) -#define MX21_SYSCTRL_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x27800) -#define MX21_JAM_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x3e000) -#define MX21_MAX_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x3f000) - -#define MX21_AVIC_BASE_ADDR 0x10040000 - -#define MX21_SAHB1_BASE_ADDR 0x80000000 -#define MX21_SAHB1_SIZE SZ_1M -#define MX21_CSI_BASE_ADDR (MX2x_SAHB1_BASE_ADDR + 0x0000) - -/* Memory regions and CS */ -#define MX21_SDRAM_BASE_ADDR 0xc0000000 -#define MX21_CSD1_BASE_ADDR 0xc4000000 - -#define MX21_CS0_BASE_ADDR 0xc8000000 -#define MX21_CS1_BASE_ADDR 0xcc000000 -#define MX21_CS2_BASE_ADDR 0xd0000000 -#define MX21_CS3_BASE_ADDR 0xd1000000 -#define MX21_CS4_BASE_ADDR 0xd2000000 -#define MX21_PCMCIA_MEM_BASE_ADDR 0xd4000000 -#define MX21_CS5_BASE_ADDR 0xdd000000 - -/* NAND, SDRAM, WEIM etc controllers */ -#define MX21_X_MEMC_BASE_ADDR 0xdf000000 -#define MX21_X_MEMC_SIZE SZ_256K - -#define MX21_SDRAMC_BASE_ADDR (MX21_X_MEMC_BASE_ADDR + 0x0000) -#define MX21_EIM_BASE_ADDR (MX21_X_MEMC_BASE_ADDR + 0x1000) -#define MX21_PCMCIA_CTL_BASE_ADDR (MX21_X_MEMC_BASE_ADDR + 0x2000) -#define MX21_NFC_BASE_ADDR (MX21_X_MEMC_BASE_ADDR + 0x3000) - -#define MX21_IRAM_BASE_ADDR 0xffffe800 /* internal ram */ - -#define MX21_IO_P2V(x) IMX_IO_P2V(x) -#define MX21_IO_ADDRESS(x) IOMEM(MX21_IO_P2V(x)) - -/* fixed interrupt numbers */ -#include <asm/irq.h> -#define MX21_INT_CSPI3 (NR_IRQS_LEGACY + 6) -#define MX21_INT_GPIO (NR_IRQS_LEGACY + 8) -#define MX21_INT_FIRI (NR_IRQS_LEGACY + 9) -#define MX21_INT_SDHC2 (NR_IRQS_LEGACY + 10) -#define MX21_INT_SDHC1 (NR_IRQS_LEGACY + 11) -#define MX21_INT_I2C (NR_IRQS_LEGACY + 12) -#define MX21_INT_SSI2 (NR_IRQS_LEGACY + 13) -#define MX21_INT_SSI1 (NR_IRQS_LEGACY + 14) -#define MX21_INT_CSPI2 (NR_IRQS_LEGACY + 15) -#define MX21_INT_CSPI1 (NR_IRQS_LEGACY + 16) -#define MX21_INT_UART4 (NR_IRQS_LEGACY + 17) -#define MX21_INT_UART3 (NR_IRQS_LEGACY + 18) -#define MX21_INT_UART2 (NR_IRQS_LEGACY + 19) -#define MX21_INT_UART1 (NR_IRQS_LEGACY + 20) -#define MX21_INT_KPP (NR_IRQS_LEGACY + 21) -#define MX21_INT_RTC (NR_IRQS_LEGACY + 22) -#define MX21_INT_PWM (NR_IRQS_LEGACY + 23) -#define MX21_INT_GPT3 (NR_IRQS_LEGACY + 24) -#define MX21_INT_GPT2 (NR_IRQS_LEGACY + 25) -#define MX21_INT_GPT1 (NR_IRQS_LEGACY + 26) -#define MX21_INT_WDOG (NR_IRQS_LEGACY + 27) -#define MX21_INT_PCMCIA (NR_IRQS_LEGACY + 28) -#define MX21_INT_NFC (NR_IRQS_LEGACY + 29) -#define MX21_INT_BMI (NR_IRQS_LEGACY + 30) -#define MX21_INT_CSI (NR_IRQS_LEGACY + 31) -#define MX21_INT_DMACH0 (NR_IRQS_LEGACY + 32) -#define MX21_INT_DMACH1 (NR_IRQS_LEGACY + 33) -#define MX21_INT_DMACH2 (NR_IRQS_LEGACY + 34) -#define MX21_INT_DMACH3 (NR_IRQS_LEGACY + 35) -#define MX21_INT_DMACH4 (NR_IRQS_LEGACY + 36) -#define MX21_INT_DMACH5 (NR_IRQS_LEGACY + 37) -#define MX21_INT_DMACH6 (NR_IRQS_LEGACY + 38) -#define MX21_INT_DMACH7 (NR_IRQS_LEGACY + 39) -#define MX21_INT_DMACH8 (NR_IRQS_LEGACY + 40) -#define MX21_INT_DMACH9 (NR_IRQS_LEGACY + 41) -#define MX21_INT_DMACH10 (NR_IRQS_LEGACY + 42) -#define MX21_INT_DMACH11 (NR_IRQS_LEGACY + 43) -#define MX21_INT_DMACH12 (NR_IRQS_LEGACY + 44) -#define MX21_INT_DMACH13 (NR_IRQS_LEGACY + 45) -#define MX21_INT_DMACH14 (NR_IRQS_LEGACY + 46) -#define MX21_INT_DMACH15 (NR_IRQS_LEGACY + 47) -#define MX21_INT_EMMAENC (NR_IRQS_LEGACY + 49) -#define MX21_INT_EMMADEC (NR_IRQS_LEGACY + 50) -#define MX21_INT_EMMAPRP (NR_IRQS_LEGACY + 51) -#define MX21_INT_EMMAPP (NR_IRQS_LEGACY + 52) -#define MX21_INT_USBWKUP (NR_IRQS_LEGACY + 53) -#define MX21_INT_USBDMA (NR_IRQS_LEGACY + 54) -#define MX21_INT_USBHOST (NR_IRQS_LEGACY + 55) -#define MX21_INT_USBFUNC (NR_IRQS_LEGACY + 56) -#define MX21_INT_USBMNP (NR_IRQS_LEGACY + 57) -#define MX21_INT_USBCTRL (NR_IRQS_LEGACY + 58) -#define MX21_INT_SLCDC (NR_IRQS_LEGACY + 60) -#define MX21_INT_LCDC (NR_IRQS_LEGACY + 61) - -/* fixed DMA request numbers */ -#define MX21_DMA_REQ_CSPI3_RX 1 -#define MX21_DMA_REQ_CSPI3_TX 2 -#define MX21_DMA_REQ_EXT 3 -#define MX21_DMA_REQ_FIRI_RX 4 -#define MX21_DMA_REQ_SDHC2 6 -#define MX21_DMA_REQ_SDHC1 7 -#define MX21_DMA_REQ_SSI2_RX0 8 -#define MX21_DMA_REQ_SSI2_TX0 9 -#define MX21_DMA_REQ_SSI2_RX1 10 -#define MX21_DMA_REQ_SSI2_TX1 11 -#define MX21_DMA_REQ_SSI1_RX0 12 -#define MX21_DMA_REQ_SSI1_TX0 13 -#define MX21_DMA_REQ_SSI1_RX1 14 -#define MX21_DMA_REQ_SSI1_TX1 15 -#define MX21_DMA_REQ_CSPI2_RX 16 -#define MX21_DMA_REQ_CSPI2_TX 17 -#define MX21_DMA_REQ_CSPI1_RX 18 -#define MX21_DMA_REQ_CSPI1_TX 19 -#define MX21_DMA_REQ_UART4_RX 20 -#define MX21_DMA_REQ_UART4_TX 21 -#define MX21_DMA_REQ_UART3_RX 22 -#define MX21_DMA_REQ_UART3_TX 23 -#define MX21_DMA_REQ_UART2_RX 24 -#define MX21_DMA_REQ_UART2_TX 25 -#define MX21_DMA_REQ_UART1_RX 26 -#define MX21_DMA_REQ_UART1_TX 27 -#define MX21_DMA_REQ_BMI_TX 28 -#define MX21_DMA_REQ_BMI_RX 29 -#define MX21_DMA_REQ_CSI_STAT 30 -#define MX21_DMA_REQ_CSI_RX 31 - -#endif /* ifndef __MACH_MX21_H__ */ diff --git a/arch/arm/mach-imx/mx27.h b/arch/arm/mach-imx/mx27.h index c6f7aae02b67..241c04d706fe 100644 --- a/arch/arm/mach-imx/mx27.h +++ b/arch/arm/mach-imx/mx27.h @@ -13,209 +13,13 @@ #define MX27_AIPI_BASE_ADDR 0x10000000 #define MX27_AIPI_SIZE SZ_1M -#define MX27_DMA_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x01000) -#define MX27_WDOG_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x02000) -#define MX27_GPT1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x03000) -#define MX27_GPT2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x04000) -#define MX27_GPT3_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x05000) -#define MX27_PWM_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x06000) -#define MX27_RTC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x07000) -#define MX27_KPP_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x08000) -#define MX27_OWIRE_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x09000) -#define MX27_UART1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x0a000) -#define MX27_UART2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x0b000) -#define MX27_UART3_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x0c000) -#define MX27_UART4_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x0d000) -#define MX27_CSPI1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x0e000) -#define MX27_CSPI2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x0f000) -#define MX27_SSI1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x10000) -#define MX27_SSI2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x11000) -#define MX27_I2C1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x12000) -#define MX27_SDHC1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x13000) -#define MX27_SDHC2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x14000) -#define MX27_GPIO_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x15000) -#define MX27_GPIO1_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x000) -#define MX27_GPIO2_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x100) -#define MX27_GPIO3_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x200) -#define MX27_GPIO4_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x300) -#define MX27_GPIO5_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x400) -#define MX27_GPIO6_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x500) -#define MX27_AUDMUX_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x16000) -#define MX27_CSPI3_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x17000) -#define MX27_MSHC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x18000) -#define MX27_GPT4_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x19000) -#define MX27_GPT5_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x1a000) -#define MX27_UART5_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x1b000) -#define MX27_UART6_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x1c000) -#define MX27_I2C2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x1d000) -#define MX27_SDHC3_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x1e000) -#define MX27_GPT6_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x1f000) -#define MX27_LCDC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x21000) -#define MX27_SLCDC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x22000) -#define MX27_VPU_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x23000) -#define MX27_USB_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x24000) -#define MX27_USB_OTG_BASE_ADDR (MX27_USB_BASE_ADDR + 0x0000) -#define MX27_USB_HS1_BASE_ADDR (MX27_USB_BASE_ADDR + 0x0200) -#define MX27_USB_HS2_BASE_ADDR (MX27_USB_BASE_ADDR + 0x0400) -#define MX27_SAHARA_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x25000) -#define MX27_EMMAPP_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x26000) -#define MX27_EMMAPRP_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x26400) -#define MX27_CCM_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x27000) -#define MX27_SYSCTRL_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x27800) -#define MX27_IIM_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x28000) -#define MX27_RTIC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x2a000) -#define MX27_FEC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x2b000) -#define MX27_SCC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x2c000) -#define MX27_ETB_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x3b000) -#define MX27_ETB_RAM_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x3c000) -#define MX27_JAM_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x3e000) -#define MX27_MAX_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x3f000) - -#define MX27_AVIC_BASE_ADDR 0x10040000 - -/* ROM patch */ -#define MX27_ROMP_BASE_ADDR 0x10041000 #define MX27_SAHB1_BASE_ADDR 0x80000000 #define MX27_SAHB1_SIZE SZ_1M -#define MX27_CSI_BASE_ADDR (MX27_SAHB1_BASE_ADDR + 0x0000) -#define MX27_ATA_BASE_ADDR (MX27_SAHB1_BASE_ADDR + 0x1000) - -/* Memory regions and CS */ -#define MX27_SDRAM_BASE_ADDR 0xa0000000 -#define MX27_CSD1_BASE_ADDR 0xb0000000 -#define MX27_CS0_BASE_ADDR 0xc0000000 -#define MX27_CS1_BASE_ADDR 0xc8000000 -#define MX27_CS2_BASE_ADDR 0xd0000000 -#define MX27_CS3_BASE_ADDR 0xd2000000 -#define MX27_CS4_BASE_ADDR 0xd4000000 -#define MX27_CS5_BASE_ADDR 0xd6000000 - -/* NAND, SDRAM, WEIM, M3IF, EMI controllers */ #define MX27_X_MEMC_BASE_ADDR 0xd8000000 #define MX27_X_MEMC_SIZE SZ_1M -#define MX27_NFC_BASE_ADDR (MX27_X_MEMC_BASE_ADDR) -#define MX27_SDRAMC_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x1000) -#define MX27_WEIM_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x2000) -#define MX27_M3IF_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x3000) -#define MX27_PCMCIA_CTL_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x4000) - -#define MX27_WEIM_CSCRx_BASE_ADDR(cs) (MX27_WEIM_BASE_ADDR + (cs) * 0x10) -#define MX27_WEIM_CSCRxU(cs) (MX27_WEIM_CSCRx_BASE_ADDR(cs)) -#define MX27_WEIM_CSCRxL(cs) (MX27_WEIM_CSCRx_BASE_ADDR(cs) + 0x4) -#define MX27_WEIM_CSCRxA(cs) (MX27_WEIM_CSCRx_BASE_ADDR(cs) + 0x8) - -#define MX27_PCMCIA_MEM_BASE_ADDR 0xdc000000 - -/* IRAM */ -#define MX27_IRAM_BASE_ADDR 0xffff4c00 /* internal ram */ #define MX27_IO_P2V(x) IMX_IO_P2V(x) -#define MX27_IO_ADDRESS(x) IOMEM(MX27_IO_P2V(x)) - -/* fixed interrupt numbers */ -#include <asm/irq.h> -#define MX27_INT_I2C2 (NR_IRQS_LEGACY + 1) -#define MX27_INT_GPT6 (NR_IRQS_LEGACY + 2) -#define MX27_INT_GPT5 (NR_IRQS_LEGACY + 3) -#define MX27_INT_GPT4 (NR_IRQS_LEGACY + 4) -#define MX27_INT_RTIC (NR_IRQS_LEGACY + 5) -#define MX27_INT_CSPI3 (NR_IRQS_LEGACY + 6) -#define MX27_INT_MSHC (NR_IRQS_LEGACY + 7) -#define MX27_INT_GPIO (NR_IRQS_LEGACY + 8) -#define MX27_INT_SDHC3 (NR_IRQS_LEGACY + 9) -#define MX27_INT_SDHC2 (NR_IRQS_LEGACY + 10) -#define MX27_INT_SDHC1 (NR_IRQS_LEGACY + 11) -#define MX27_INT_I2C1 (NR_IRQS_LEGACY + 12) -#define MX27_INT_SSI2 (NR_IRQS_LEGACY + 13) -#define MX27_INT_SSI1 (NR_IRQS_LEGACY + 14) -#define MX27_INT_CSPI2 (NR_IRQS_LEGACY + 15) -#define MX27_INT_CSPI1 (NR_IRQS_LEGACY + 16) -#define MX27_INT_UART4 (NR_IRQS_LEGACY + 17) -#define MX27_INT_UART3 (NR_IRQS_LEGACY + 18) -#define MX27_INT_UART2 (NR_IRQS_LEGACY + 19) -#define MX27_INT_UART1 (NR_IRQS_LEGACY + 20) -#define MX27_INT_KPP (NR_IRQS_LEGACY + 21) -#define MX27_INT_RTC (NR_IRQS_LEGACY + 22) -#define MX27_INT_PWM (NR_IRQS_LEGACY + 23) -#define MX27_INT_GPT3 (NR_IRQS_LEGACY + 24) -#define MX27_INT_GPT2 (NR_IRQS_LEGACY + 25) -#define MX27_INT_GPT1 (NR_IRQS_LEGACY + 26) -#define MX27_INT_WDOG (NR_IRQS_LEGACY + 27) -#define MX27_INT_PCMCIA (NR_IRQS_LEGACY + 28) -#define MX27_INT_NFC (NR_IRQS_LEGACY + 29) -#define MX27_INT_ATA (NR_IRQS_LEGACY + 30) -#define MX27_INT_CSI (NR_IRQS_LEGACY + 31) -#define MX27_INT_DMACH0 (NR_IRQS_LEGACY + 32) -#define MX27_INT_DMACH1 (NR_IRQS_LEGACY + 33) -#define MX27_INT_DMACH2 (NR_IRQS_LEGACY + 34) -#define MX27_INT_DMACH3 (NR_IRQS_LEGACY + 35) -#define MX27_INT_DMACH4 (NR_IRQS_LEGACY + 36) -#define MX27_INT_DMACH5 (NR_IRQS_LEGACY + 37) -#define MX27_INT_DMACH6 (NR_IRQS_LEGACY + 38) -#define MX27_INT_DMACH7 (NR_IRQS_LEGACY + 39) -#define MX27_INT_DMACH8 (NR_IRQS_LEGACY + 40) -#define MX27_INT_DMACH9 (NR_IRQS_LEGACY + 41) -#define MX27_INT_DMACH10 (NR_IRQS_LEGACY + 42) -#define MX27_INT_DMACH11 (NR_IRQS_LEGACY + 43) -#define MX27_INT_DMACH12 (NR_IRQS_LEGACY + 44) -#define MX27_INT_DMACH13 (NR_IRQS_LEGACY + 45) -#define MX27_INT_DMACH14 (NR_IRQS_LEGACY + 46) -#define MX27_INT_DMACH15 (NR_IRQS_LEGACY + 47) -#define MX27_INT_UART6 (NR_IRQS_LEGACY + 48) -#define MX27_INT_UART5 (NR_IRQS_LEGACY + 49) -#define MX27_INT_FEC (NR_IRQS_LEGACY + 50) -#define MX27_INT_EMMAPRP (NR_IRQS_LEGACY + 51) -#define MX27_INT_EMMAPP (NR_IRQS_LEGACY + 52) -#define MX27_INT_VPU (NR_IRQS_LEGACY + 53) -#define MX27_INT_USB_HS1 (NR_IRQS_LEGACY + 54) -#define MX27_INT_USB_HS2 (NR_IRQS_LEGACY + 55) -#define MX27_INT_USB_OTG (NR_IRQS_LEGACY + 56) -#define MX27_INT_SCC_SMN (NR_IRQS_LEGACY + 57) -#define MX27_INT_SCC_SCM (NR_IRQS_LEGACY + 58) -#define MX27_INT_SAHARA (NR_IRQS_LEGACY + 59) -#define MX27_INT_SLCDC (NR_IRQS_LEGACY + 60) -#define MX27_INT_LCDC (NR_IRQS_LEGACY + 61) -#define MX27_INT_IIM (NR_IRQS_LEGACY + 62) -#define MX27_INT_CCM (NR_IRQS_LEGACY + 63) - -/* fixed DMA request numbers */ -#define MX27_DMA_REQ_CSPI3_RX 1 -#define MX27_DMA_REQ_CSPI3_TX 2 -#define MX27_DMA_REQ_EXT 3 -#define MX27_DMA_REQ_MSHC 4 -#define MX27_DMA_REQ_SDHC2 6 -#define MX27_DMA_REQ_SDHC1 7 -#define MX27_DMA_REQ_SSI2_RX0 8 -#define MX27_DMA_REQ_SSI2_TX0 9 -#define MX27_DMA_REQ_SSI2_RX1 10 -#define MX27_DMA_REQ_SSI2_TX1 11 -#define MX27_DMA_REQ_SSI1_RX0 12 -#define MX27_DMA_REQ_SSI1_TX0 13 -#define MX27_DMA_REQ_SSI1_RX1 14 -#define MX27_DMA_REQ_SSI1_TX1 15 -#define MX27_DMA_REQ_CSPI2_RX 16 -#define MX27_DMA_REQ_CSPI2_TX 17 -#define MX27_DMA_REQ_CSPI1_RX 18 -#define MX27_DMA_REQ_CSPI1_TX 19 -#define MX27_DMA_REQ_UART4_RX 20 -#define MX27_DMA_REQ_UART4_TX 21 -#define MX27_DMA_REQ_UART3_RX 22 -#define MX27_DMA_REQ_UART3_TX 23 -#define MX27_DMA_REQ_UART2_RX 24 -#define MX27_DMA_REQ_UART2_TX 25 -#define MX27_DMA_REQ_UART1_RX 26 -#define MX27_DMA_REQ_UART1_TX 27 -#define MX27_DMA_REQ_ATA_TX 28 -#define MX27_DMA_REQ_ATA_RCV 29 -#define MX27_DMA_REQ_CSI_STAT 30 -#define MX27_DMA_REQ_CSI_RX 31 -#define MX27_DMA_REQ_UART5_TX 32 -#define MX27_DMA_REQ_UART5_RX 33 -#define MX27_DMA_REQ_UART6_TX 34 -#define MX27_DMA_REQ_UART6_RX 35 -#define MX27_DMA_REQ_SDHC3 36 -#define MX27_DMA_REQ_NFC 37 #endif /* ifndef __MACH_MX27_H__ */ diff --git a/arch/arm/mach-imx/mx31.h b/arch/arm/mach-imx/mx31.h index d9574671ca5c..08a72e25c289 100644 --- a/arch/arm/mach-imx/mx31.h +++ b/arch/arm/mach-imx/mx31.h @@ -2,196 +2,17 @@ #ifndef __MACH_MX31_H__ #define __MACH_MX31_H__ -/* - * IRAM - */ -#define MX31_IRAM_BASE_ADDR 0x1ffc0000 /* internal ram */ -#define MX31_IRAM_SIZE SZ_16K - -#define MX31_L2CC_BASE_ADDR 0x30000000 -#define MX31_L2CC_SIZE SZ_1M - #define MX31_AIPS1_BASE_ADDR 0x43f00000 #define MX31_AIPS1_SIZE SZ_1M -#define MX31_MAX_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x04000) -#define MX31_EVTMON_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x08000) -#define MX31_CLKCTL_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x0c000) -#define MX31_ETB_SLOT4_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x10000) -#define MX31_ETB_SLOT5_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x14000) -#define MX31_ECT_CTIO_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x18000) -#define MX31_I2C1_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x80000) -#define MX31_I2C3_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x84000) -#define MX31_USB_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x88000) -#define MX31_USB_OTG_BASE_ADDR (MX31_USB_BASE_ADDR + 0x0000) -#define MX31_USB_HS1_BASE_ADDR (MX31_USB_BASE_ADDR + 0x0200) -#define MX31_USB_HS2_BASE_ADDR (MX31_USB_BASE_ADDR + 0x0400) -#define MX31_ATA_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x8c000) -#define MX31_UART1_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x90000) -#define MX31_UART2_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x94000) -#define MX31_I2C2_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x98000) -#define MX31_OWIRE_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x9c000) -#define MX31_SSI1_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xa0000) -#define MX31_CSPI1_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xa4000) -#define MX31_KPP_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xa8000) -#define MX31_IOMUXC_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xac000) -#define MX31_UART4_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xb0000) -#define MX31_UART5_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xb4000) -#define MX31_ECT_IP1_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xb8000) -#define MX31_ECT_IP2_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xbc000) - #define MX31_SPBA0_BASE_ADDR 0x50000000 #define MX31_SPBA0_SIZE SZ_1M -#define MX31_SDHC1_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x04000) -#define MX31_SDHC2_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x08000) -#define MX31_UART3_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x0c000) -#define MX31_CSPI2_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x10000) -#define MX31_SSI2_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x14000) -#define MX31_SIM1_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x18000) -#define MX31_IIM_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x1c000) -#define MX31_ATA_DMA_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x20000) -#define MX31_MSHC1_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x24000) -#define MX31_SPBA_CTRL_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x3c000) - #define MX31_AIPS2_BASE_ADDR 0x53f00000 #define MX31_AIPS2_SIZE SZ_1M -#define MX31_CCM_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x80000) -#define MX31_CSPI3_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x84000) -#define MX31_FIRI_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x8c000) -#define MX31_GPT1_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x90000) -#define MX31_EPIT1_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x94000) -#define MX31_EPIT2_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x98000) -#define MX31_GPIO3_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xa4000) -#define MX31_SCC_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xac000) -#define MX31_SCM_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xae000) -#define MX31_SMN_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xaf000) -#define MX31_RNGA_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xb0000) -#define MX31_IPU_CTRL_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xc0000) -#define MX31_AUDMUX_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xc4000) -#define MX31_MPEG4_ENC_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xc8000) -#define MX31_GPIO1_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xcc000) -#define MX31_GPIO2_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xd0000) -#define MX31_SDMA_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xd4000) -#define MX31_RTC_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xd8000) -#define MX31_WDOG_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xdc000) -#define MX31_PWM_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xe0000) -#define MX31_RTIC_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xec000) - -#define MX31_ROMP_BASE_ADDR 0x60000000 -#define MX31_ROMP_BASE_ADDR_VIRT IOMEM(0xfc500000) -#define MX31_ROMP_SIZE SZ_1M - #define MX31_AVIC_BASE_ADDR 0x68000000 #define MX31_AVIC_SIZE SZ_1M - -#define MX31_IPU_MEM_BASE_ADDR 0x70000000 -#define MX31_CSD0_BASE_ADDR 0x80000000 -#define MX31_CSD1_BASE_ADDR 0x90000000 - -#define MX31_CS0_BASE_ADDR 0xa0000000 -#define MX31_CS1_BASE_ADDR 0xa8000000 -#define MX31_CS2_BASE_ADDR 0xb0000000 -#define MX31_CS3_BASE_ADDR 0xb2000000 - -#define MX31_CS4_BASE_ADDR 0xb4000000 -#define MX31_CS4_BASE_ADDR_VIRT IOMEM(0xf6000000) -#define MX31_CS4_SIZE SZ_32M - -#define MX31_CS5_BASE_ADDR 0xb6000000 -#define MX31_CS5_BASE_ADDR_VIRT IOMEM(0xf8000000) -#define MX31_CS5_SIZE SZ_32M - #define MX31_X_MEMC_BASE_ADDR 0xb8000000 #define MX31_X_MEMC_SIZE SZ_64K -#define MX31_NFC_BASE_ADDR (MX31_X_MEMC_BASE_ADDR + 0x0000) -#define MX31_ESDCTL_BASE_ADDR (MX31_X_MEMC_BASE_ADDR + 0x1000) -#define MX31_WEIM_BASE_ADDR (MX31_X_MEMC_BASE_ADDR + 0x2000) -#define MX31_M3IF_BASE_ADDR (MX31_X_MEMC_BASE_ADDR + 0x3000) -#define MX31_EMI_CTL_BASE_ADDR (MX31_X_MEMC_BASE_ADDR + 0x4000) -#define MX31_PCMCIA_CTL_BASE_ADDR MX31_EMI_CTL_BASE_ADDR - -#define MX31_WEIM_CSCRx_BASE_ADDR(cs) (MX31_WEIM_BASE_ADDR + (cs) * 0x10) -#define MX31_WEIM_CSCRxU(cs) (MX31_WEIM_CSCRx_BASE_ADDR(cs)) -#define MX31_WEIM_CSCRxL(cs) (MX31_WEIM_CSCRx_BASE_ADDR(cs) + 0x4) -#define MX31_WEIM_CSCRxA(cs) (MX31_WEIM_CSCRx_BASE_ADDR(cs) + 0x8) - -#define MX31_PCMCIA_MEM_BASE_ADDR 0xbc000000 #define MX31_IO_P2V(x) IMX_IO_P2V(x) -#define MX31_IO_ADDRESS(x) IOMEM(MX31_IO_P2V(x)) - -/* - * Interrupt numbers - */ -#include <asm/irq.h> -#define MX31_INT_I2C3 (NR_IRQS_LEGACY + 3) -#define MX31_INT_I2C2 (NR_IRQS_LEGACY + 4) -#define MX31_INT_MPEG4_ENCODER (NR_IRQS_LEGACY + 5) -#define MX31_INT_RTIC (NR_IRQS_LEGACY + 6) -#define MX31_INT_FIRI (NR_IRQS_LEGACY + 7) -#define MX31_INT_SDHC2 (NR_IRQS_LEGACY + 8) -#define MX31_INT_SDHC1 (NR_IRQS_LEGACY + 9) -#define MX31_INT_I2C1 (NR_IRQS_LEGACY + 10) -#define MX31_INT_SSI2 (NR_IRQS_LEGACY + 11) -#define MX31_INT_SSI1 (NR_IRQS_LEGACY + 12) -#define MX31_INT_CSPI2 (NR_IRQS_LEGACY + 13) -#define MX31_INT_CSPI1 (NR_IRQS_LEGACY + 14) -#define MX31_INT_ATA (NR_IRQS_LEGACY + 15) -#define MX31_INT_MBX (NR_IRQS_LEGACY + 16) -#define MX31_INT_CSPI3 (NR_IRQS_LEGACY + 17) -#define MX31_INT_UART3 (NR_IRQS_LEGACY + 18) -#define MX31_INT_IIM (NR_IRQS_LEGACY + 19) -#define MX31_INT_SIM2 (NR_IRQS_LEGACY + 20) -#define MX31_INT_SIM1 (NR_IRQS_LEGACY + 21) -#define MX31_INT_RNGA (NR_IRQS_LEGACY + 22) -#define MX31_INT_EVTMON (NR_IRQS_LEGACY + 23) -#define MX31_INT_KPP (NR_IRQS_LEGACY + 24) -#define MX31_INT_RTC (NR_IRQS_LEGACY + 25) -#define MX31_INT_PWM (NR_IRQS_LEGACY + 26) -#define MX31_INT_EPIT2 (NR_IRQS_LEGACY + 27) -#define MX31_INT_EPIT1 (NR_IRQS_LEGACY + 28) -#define MX31_INT_GPT (NR_IRQS_LEGACY + 29) -#define MX31_INT_POWER_FAIL (NR_IRQS_LEGACY + 30) -#define MX31_INT_CCM_DVFS (NR_IRQS_LEGACY + 31) -#define MX31_INT_UART2 (NR_IRQS_LEGACY + 32) -#define MX31_INT_NFC (NR_IRQS_LEGACY + 33) -#define MX31_INT_SDMA (NR_IRQS_LEGACY + 34) -#define MX31_INT_USB_HS1 (NR_IRQS_LEGACY + 35) -#define MX31_INT_USB_HS2 (NR_IRQS_LEGACY + 36) -#define MX31_INT_USB_OTG (NR_IRQS_LEGACY + 37) -#define MX31_INT_MSHC1 (NR_IRQS_LEGACY + 39) -#define MX31_INT_MSHC2 (NR_IRQS_LEGACY + 40) -#define MX31_INT_IPU_ERR (NR_IRQS_LEGACY + 41) -#define MX31_INT_IPU_SYN (NR_IRQS_LEGACY + 42) -#define MX31_INT_UART1 (NR_IRQS_LEGACY + 45) -#define MX31_INT_UART4 (NR_IRQS_LEGACY + 46) -#define MX31_INT_UART5 (NR_IRQS_LEGACY + 47) -#define MX31_INT_ECT (NR_IRQS_LEGACY + 48) -#define MX31_INT_SCC_SCM (NR_IRQS_LEGACY + 49) -#define MX31_INT_SCC_SMN (NR_IRQS_LEGACY + 50) -#define MX31_INT_GPIO2 (NR_IRQS_LEGACY + 51) -#define MX31_INT_GPIO1 (NR_IRQS_LEGACY + 52) -#define MX31_INT_CCM (NR_IRQS_LEGACY + 53) -#define MX31_INT_PCMCIA (NR_IRQS_LEGACY + 54) -#define MX31_INT_WDOG (NR_IRQS_LEGACY + 55) -#define MX31_INT_GPIO3 (NR_IRQS_LEGACY + 56) -#define MX31_INT_EXT_POWER (NR_IRQS_LEGACY + 58) -#define MX31_INT_EXT_TEMPER (NR_IRQS_LEGACY + 59) -#define MX31_INT_EXT_SENSOR60 (NR_IRQS_LEGACY + 60) -#define MX31_INT_EXT_SENSOR61 (NR_IRQS_LEGACY + 61) -#define MX31_INT_EXT_WDOG (NR_IRQS_LEGACY + 62) -#define MX31_INT_EXT_TV (NR_IRQS_LEGACY + 63) - -#define MX31_DMA_REQ_SDHC1 20 -#define MX31_DMA_REQ_SDHC2 21 -#define MX31_DMA_REQ_SSI2_RX1 22 -#define MX31_DMA_REQ_SSI2_TX1 23 -#define MX31_DMA_REQ_SSI2_RX0 24 -#define MX31_DMA_REQ_SSI2_TX0 25 -#define MX31_DMA_REQ_SSI1_RX1 26 -#define MX31_DMA_REQ_SSI1_TX1 27 -#define MX31_DMA_REQ_SSI1_RX0 28 -#define MX31_DMA_REQ_SSI1_TX0 29 - -#define MX31_PROD_SIGNATURE 0x1 /* For MX31 */ #endif /* ifndef __MACH_MX31_H__ */ diff --git a/arch/arm/mach-imx/mx31lilly-db.c b/arch/arm/mach-imx/mx31lilly-db.c deleted file mode 100644 index 00a5ee30d5dd..000000000000 --- a/arch/arm/mach-imx/mx31lilly-db.c +++ /dev/null @@ -1,182 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * LILLY-1131 development board support - * - * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> - * - * based on code for other MX31 boards, - * - * Copyright 2005-2007 Freescale Semiconductor - * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> - * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/init.h> -#include <linux/gpio.h> -#include <linux/platform_device.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include "board-mx31lilly.h" -#include "common.h" -#include "devices-imx31.h" -#include "hardware.h" -#include "iomux-mx3.h" - -/* - * This file contains board-specific initialization routines for the - * LILLY-1131 development board. If you design an own baseboard for the - * module, use this file as base for support code. - */ - -static unsigned int lilly_db_board_pins[] __initdata = { - MX31_PIN_SD1_DATA3__SD1_DATA3, - MX31_PIN_SD1_DATA2__SD1_DATA2, - MX31_PIN_SD1_DATA1__SD1_DATA1, - MX31_PIN_SD1_DATA0__SD1_DATA0, - MX31_PIN_SD1_CLK__SD1_CLK, - MX31_PIN_SD1_CMD__SD1_CMD, - MX31_PIN_LD0__LD0, - MX31_PIN_LD1__LD1, - MX31_PIN_LD2__LD2, - MX31_PIN_LD3__LD3, - MX31_PIN_LD4__LD4, - MX31_PIN_LD5__LD5, - MX31_PIN_LD6__LD6, - MX31_PIN_LD7__LD7, - MX31_PIN_LD8__LD8, - MX31_PIN_LD9__LD9, - MX31_PIN_LD10__LD10, - MX31_PIN_LD11__LD11, - MX31_PIN_LD12__LD12, - MX31_PIN_LD13__LD13, - MX31_PIN_LD14__LD14, - MX31_PIN_LD15__LD15, - MX31_PIN_LD16__LD16, - MX31_PIN_LD17__LD17, - MX31_PIN_VSYNC3__VSYNC3, - MX31_PIN_HSYNC__HSYNC, - MX31_PIN_FPSHIFT__FPSHIFT, - MX31_PIN_DRDY0__DRDY0, - MX31_PIN_CONTRAST__CONTRAST, -}; - -/* MMC support */ - -static int mxc_mmc1_get_ro(struct device *dev) -{ - return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_LCS0)); -} - -static int gpio_det, gpio_wp; - -#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ - PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) - -static int mxc_mmc1_init(struct device *dev, - irq_handler_t detect_irq, void *data) -{ - int ret; - - gpio_det = IOMUX_TO_GPIO(MX31_PIN_GPIO1_1); - gpio_wp = IOMUX_TO_GPIO(MX31_PIN_LCS0); - - mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, MMC_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, MMC_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, MMC_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, MMC_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SD1_CMD, MMC_PAD_CFG); - - ret = gpio_request(gpio_det, "MMC detect"); - if (ret) - return ret; - - ret = gpio_request(gpio_wp, "MMC w/p"); - if (ret) - goto exit_free_det; - - gpio_direction_input(gpio_det); - gpio_direction_input(gpio_wp); - - ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)), - detect_irq, IRQF_TRIGGER_FALLING, - "MMC detect", data); - if (ret) - goto exit_free_wp; - - return 0; - -exit_free_wp: - gpio_free(gpio_wp); - -exit_free_det: - gpio_free(gpio_det); - - return ret; -} - -static void mxc_mmc1_exit(struct device *dev, void *data) -{ - gpio_free(gpio_det); - gpio_free(gpio_wp); - free_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)), data); -} - -static const struct imxmmc_platform_data mmc_pdata __initconst = { - .get_ro = mxc_mmc1_get_ro, - .init = mxc_mmc1_init, - .exit = mxc_mmc1_exit, -}; - -/* Framebuffer support */ -static const struct fb_videomode fb_modedb = { - /* 640x480 TFT panel (IPS-056T) */ - .name = "CRT-VGA", - .refresh = 64, - .xres = 640, - .yres = 480, - .pixclock = 30000, - .left_margin = 200, - .right_margin = 2, - .upper_margin = 2, - .lower_margin = 2, - .hsync_len = 3, - .vsync_len = 1, - .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, -}; - -static struct mx3fb_platform_data fb_pdata __initdata = { - .name = "CRT-VGA", - .mode = &fb_modedb, - .num_modes = 1, -}; - -#define LCD_VCC_EN_GPIO (7) - -static void __init mx31lilly_init_fb(void) -{ - if (gpio_request(LCD_VCC_EN_GPIO, "LCD enable") != 0) { - printk(KERN_WARNING "unable to request LCD_VCC_EN pin.\n"); - return; - } - - imx31_add_ipu_core(); - imx31_add_mx3_sdc_fb(&fb_pdata); - gpio_direction_output(LCD_VCC_EN_GPIO, 1); -} - -void __init mx31lilly_db_init(void) -{ - mxc_iomux_setup_multiple_pins(lilly_db_board_pins, - ARRAY_SIZE(lilly_db_board_pins), - "development board pins"); - imx31_add_mxc_mmc(0, &mmc_pdata); - mx31lilly_init_fb(); -} diff --git a/arch/arm/mach-imx/mx31lite-db.c b/arch/arm/mach-imx/mx31lite-db.c deleted file mode 100644 index 13da7325c32b..000000000000 --- a/arch/arm/mach-imx/mx31lite-db.c +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * LogicPD i.MX31 SOM-LV development board support - * - * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> - * - * based on code for other MX31 boards, - * - * Copyright 2005-2007 Freescale Semiconductor - * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> - * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/init.h> -#include <linux/gpio.h> -#include <linux/leds.h> -#include <linux/platform_device.h> - -#include <asm/mach-types.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include "board-mx31lite.h" -#include "common.h" -#include "devices-imx31.h" -#include "hardware.h" -#include "iomux-mx3.h" - -/* - * This file contains board-specific initialization routines for the - * LogicPD i.MX31 SOM-LV development board, aka 'LiteKit'. - * If you design an own baseboard for the module, use this file as base - * for support code. - */ - -static unsigned int litekit_db_board_pins[] __initdata = { - /* SDHC1 */ - MX31_PIN_SD1_DATA0__SD1_DATA0, - MX31_PIN_SD1_DATA1__SD1_DATA1, - MX31_PIN_SD1_DATA2__SD1_DATA2, - MX31_PIN_SD1_DATA3__SD1_DATA3, - MX31_PIN_SD1_CLK__SD1_CLK, - MX31_PIN_SD1_CMD__SD1_CMD, -}; - -/* MMC */ - -static int gpio_det, gpio_wp; - -#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ - PAD_CTL_ODE_CMOS) - -static int mxc_mmc1_get_ro(struct device *dev) -{ - return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_GPIO1_6)); -} - -static int mxc_mmc1_init(struct device *dev, - irq_handler_t detect_irq, void *data) -{ - int ret; - - gpio_det = IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1); - gpio_wp = IOMUX_TO_GPIO(MX31_PIN_GPIO1_6); - - mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, - MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); - mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, - MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); - mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, - MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); - mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, - MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); - mxc_iomux_set_pad(MX31_PIN_SD1_CMD, - MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); - mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG); - - ret = gpio_request(gpio_det, "MMC detect"); - if (ret) - return ret; - - ret = gpio_request(gpio_wp, "MMC w/p"); - if (ret) - goto exit_free_det; - - gpio_direction_input(gpio_det); - gpio_direction_input(gpio_wp); - - ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)), - detect_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "MMC detect", data); - if (ret) - goto exit_free_wp; - - return 0; - -exit_free_wp: - gpio_free(gpio_wp); - -exit_free_det: - gpio_free(gpio_det); - - return ret; -} - -static void mxc_mmc1_exit(struct device *dev, void *data) -{ - gpio_free(gpio_det); - gpio_free(gpio_wp); - free_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)), data); -} - -static const struct imxmmc_platform_data mmc_pdata __initconst = { - .get_ro = mxc_mmc1_get_ro, - .init = mxc_mmc1_init, - .exit = mxc_mmc1_exit, -}; - -/* GPIO LEDs */ - -static const struct gpio_led litekit_leds[] __initconst = { - { - .name = "GPIO0", - .gpio = IOMUX_TO_GPIO(MX31_PIN_COMPARE), - .active_low = 1, - .default_state = LEDS_GPIO_DEFSTATE_OFF, - }, - { - .name = "GPIO1", - .gpio = IOMUX_TO_GPIO(MX31_PIN_CAPTURE), - .active_low = 1, - .default_state = LEDS_GPIO_DEFSTATE_OFF, - } -}; - -static const struct gpio_led_platform_data - litekit_led_platform_data __initconst = { - .leds = litekit_leds, - .num_leds = ARRAY_SIZE(litekit_leds), -}; - -void __init mx31lite_db_init(void) -{ - mxc_iomux_setup_multiple_pins(litekit_db_board_pins, - ARRAY_SIZE(litekit_db_board_pins), - "development board pins"); - imx31_add_mxc_mmc(0, &mmc_pdata); - gpio_led_register_device(-1, &litekit_led_platform_data); - imx31_add_imx2_wdt(); - imx31_add_mxc_rtc(); -} diff --git a/arch/arm/mach-imx/mx31moboard-devboard.c b/arch/arm/mach-imx/mx31moboard-devboard.c deleted file mode 100644 index 6a9db0663a80..000000000000 --- a/arch/arm/mach-imx/mx31moboard-devboard.c +++ /dev/null @@ -1,238 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group - */ - -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/types.h> - -#include <linux/usb/otg.h> - -#include "board-mx31moboard.h" -#include "common.h" -#include "devices-imx31.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx3.h" -#include "ulpi.h" - -static unsigned int devboard_pins[] = { - /* UART1 */ - MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2, - MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2, - /* SDHC2 */ - MX31_PIN_PC_PWRON__SD2_DATA3, MX31_PIN_PC_VS1__SD2_DATA2, - MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0, - MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD, - MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29, - /* USB H1 */ - MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM, - MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP, - MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB, - MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND, - MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12, - /* SEL */ - MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9, - MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11, -}; - -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -#define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR) -#define SDHC2_WP IOMUX_TO_GPIO(MX31_PIN_ATA_DIOW) - -static int devboard_sdhc2_get_ro(struct device *dev) -{ - return !gpio_get_value(SDHC2_WP); -} - -static int devboard_sdhc2_init(struct device *dev, irq_handler_t detect_irq, - void *data) -{ - int ret; - - ret = gpio_request(SDHC2_CD, "sdhc-detect"); - if (ret) - return ret; - - gpio_direction_input(SDHC2_CD); - - ret = gpio_request(SDHC2_WP, "sdhc-wp"); - if (ret) - goto err_gpio_free; - gpio_direction_input(SDHC2_WP); - - ret = request_irq(gpio_to_irq(SDHC2_CD), detect_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "sdhc2-card-detect", data); - if (ret) - goto err_gpio_free_2; - - return 0; - -err_gpio_free_2: - gpio_free(SDHC2_WP); -err_gpio_free: - gpio_free(SDHC2_CD); - - return ret; -} - -static void devboard_sdhc2_exit(struct device *dev, void *data) -{ - free_irq(gpio_to_irq(SDHC2_CD), data); - gpio_free(SDHC2_WP); - gpio_free(SDHC2_CD); -} - -static const struct imxmmc_platform_data sdhc2_pdata __initconst = { - .get_ro = devboard_sdhc2_get_ro, - .init = devboard_sdhc2_init, - .exit = devboard_sdhc2_exit, -}; - -#define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1) -#define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1) -#define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1) -#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1) - -static void devboard_init_sel_gpios(void) -{ - if (!gpio_request(SEL0, "sel0")) { - gpio_direction_input(SEL0); - gpio_export(SEL0, true); - } - - if (!gpio_request(SEL1, "sel1")) { - gpio_direction_input(SEL1); - gpio_export(SEL1, true); - } - - if (!gpio_request(SEL2, "sel2")) { - gpio_direction_input(SEL2); - gpio_export(SEL2, true); - } - - if (!gpio_request(SEL3, "sel3")) { - gpio_direction_input(SEL3); - gpio_export(SEL3, true); - } -} -#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ - PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) - -static int devboard_usbh1_hw_init(struct platform_device *pdev) -{ - mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true); - - mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG); - - mdelay(10); - - return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED | - MXC_EHCI_INTERFACE_SINGLE_UNI); -} - -#define USBH1_VBUSEN_B IOMUX_TO_GPIO(MX31_PIN_NFRE_B) -#define USBH1_MODE IOMUX_TO_GPIO(MX31_PIN_NFALE) - -static int devboard_isp1105_init(struct usb_phy *otg) -{ - int ret = gpio_request(USBH1_MODE, "usbh1-mode"); - if (ret) - return ret; - /* single ended */ - gpio_direction_output(USBH1_MODE, 0); - - ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen"); - if (ret) { - gpio_free(USBH1_MODE); - return ret; - } - gpio_direction_output(USBH1_VBUSEN_B, 1); - - return 0; -} - - -static int devboard_isp1105_set_vbus(struct usb_otg *otg, bool on) -{ - if (on) - gpio_set_value(USBH1_VBUSEN_B, 0); - else - gpio_set_value(USBH1_VBUSEN_B, 1); - - return 0; -} - -static struct mxc_usbh_platform_data usbh1_pdata __initdata = { - .init = devboard_usbh1_hw_init, - .portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL, -}; - -static int __init devboard_usbh1_init(void) -{ - struct usb_phy *phy; - struct platform_device *pdev; - - phy = kzalloc(sizeof(*phy), GFP_KERNEL); - if (!phy) - return -ENOMEM; - - phy->otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); - if (!phy->otg) { - kfree(phy); - return -ENOMEM; - } - - phy->label = "ISP1105"; - phy->init = devboard_isp1105_init; - phy->otg->set_vbus = devboard_isp1105_set_vbus; - - usbh1_pdata.otg = phy; - - pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata); - - return PTR_ERR_OR_ZERO(pdev); -} - - -static const struct fsl_usb2_platform_data usb_pdata __initconst = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_ULPI, -}; - -/* - * system init for baseboard usage. Will be called by mx31moboard init. - */ -void __init mx31moboard_devboard_init(void) -{ - printk(KERN_INFO "Initializing mx31devboard peripherals\n"); - - mxc_iomux_setup_multiple_pins(devboard_pins, ARRAY_SIZE(devboard_pins), - "devboard"); - - imx31_add_imx_uart1(&uart_pdata); - - imx31_add_mxc_mmc(1, &sdhc2_pdata); - - devboard_init_sel_gpios(); - - imx31_add_fsl_usb2_udc(&usb_pdata); - - devboard_usbh1_init(); -} diff --git a/arch/arm/mach-imx/mx31moboard-marxbot.c b/arch/arm/mach-imx/mx31moboard-marxbot.c deleted file mode 100644 index c2690008e6fc..000000000000 --- a/arch/arm/mach-imx/mx31moboard-marxbot.c +++ /dev/null @@ -1,270 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group - */ - -#include <linux/delay.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/i2c.h> -#include <linux/spi/spi.h> -#include <linux/slab.h> -#include <linux/platform_device.h> -#include <linux/types.h> - -#include <linux/usb/otg.h> - -#include "board-mx31moboard.h" -#include "common.h" -#include "devices-imx31.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx3.h" -#include "ulpi.h" - -static unsigned int marxbot_pins[] = { - /* SDHC2 */ - MX31_PIN_PC_PWRON__SD2_DATA3, MX31_PIN_PC_VS1__SD2_DATA2, - MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0, - MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD, - MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29, - /* dsPIC resets */ - MX31_PIN_STXD5__GPIO1_21, MX31_PIN_SRXD5__GPIO1_22, - /*battery detection */ - MX31_PIN_LCS0__GPIO3_23, - /* USB H1 */ - MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM, - MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP, - MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB, - MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND, - MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12, - /* SEL */ - MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9, - MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11, -}; - -#define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR) -#define SDHC2_WP IOMUX_TO_GPIO(MX31_PIN_ATA_DIOW) - -static int marxbot_sdhc2_get_ro(struct device *dev) -{ - return !gpio_get_value(SDHC2_WP); -} - -static int marxbot_sdhc2_init(struct device *dev, irq_handler_t detect_irq, - void *data) -{ - int ret; - - ret = gpio_request(SDHC2_CD, "sdhc-detect"); - if (ret) - return ret; - - gpio_direction_input(SDHC2_CD); - - ret = gpio_request(SDHC2_WP, "sdhc-wp"); - if (ret) - goto err_gpio_free; - gpio_direction_input(SDHC2_WP); - - ret = request_irq(gpio_to_irq(SDHC2_CD), detect_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "sdhc2-card-detect", data); - if (ret) - goto err_gpio_free_2; - - return 0; - -err_gpio_free_2: - gpio_free(SDHC2_WP); -err_gpio_free: - gpio_free(SDHC2_CD); - - return ret; -} - -static void marxbot_sdhc2_exit(struct device *dev, void *data) -{ - free_irq(gpio_to_irq(SDHC2_CD), data); - gpio_free(SDHC2_WP); - gpio_free(SDHC2_CD); -} - -static const struct imxmmc_platform_data sdhc2_pdata __initconst = { - .get_ro = marxbot_sdhc2_get_ro, - .init = marxbot_sdhc2_init, - .exit = marxbot_sdhc2_exit, -}; - -#define TRSLAT_RST_B IOMUX_TO_GPIO(MX31_PIN_STXD5) -#define DSPICS_RST_B IOMUX_TO_GPIO(MX31_PIN_SRXD5) - -static void dspics_resets_init(void) -{ - if (!gpio_request(TRSLAT_RST_B, "translator-rst")) { - gpio_direction_output(TRSLAT_RST_B, 0); - gpio_export(TRSLAT_RST_B, false); - } - - if (!gpio_request(DSPICS_RST_B, "dspics-rst")) { - gpio_direction_output(DSPICS_RST_B, 0); - gpio_export(DSPICS_RST_B, false); - } -} - -static struct spi_board_info marxbot_spi_board_info[] __initdata = { - { - .modalias = "spidev", - .max_speed_hz = 300000, - .bus_num = 1, - .chip_select = 1, /* according spi1_cs[] ! */ - }, -}; - -#define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1) -#define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1) -#define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1) -#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1) - -static void marxbot_init_sel_gpios(void) -{ - if (!gpio_request(SEL0, "sel0")) { - gpio_direction_input(SEL0); - gpio_export(SEL0, true); - } - - if (!gpio_request(SEL1, "sel1")) { - gpio_direction_input(SEL1); - gpio_export(SEL1, true); - } - - if (!gpio_request(SEL2, "sel2")) { - gpio_direction_input(SEL2); - gpio_export(SEL2, true); - } - - if (!gpio_request(SEL3, "sel3")) { - gpio_direction_input(SEL3); - gpio_export(SEL3, true); - } -} - -#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ - PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) - -static int marxbot_usbh1_hw_init(struct platform_device *pdev) -{ - mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true); - - mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG); - mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG); - - mdelay(10); - - return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED | - MXC_EHCI_INTERFACE_SINGLE_UNI); -} - -#define USBH1_VBUSEN_B IOMUX_TO_GPIO(MX31_PIN_NFRE_B) -#define USBH1_MODE IOMUX_TO_GPIO(MX31_PIN_NFALE) - -static int marxbot_isp1105_init(struct usb_phy *otg) -{ - int ret = gpio_request(USBH1_MODE, "usbh1-mode"); - if (ret) - return ret; - /* single ended */ - gpio_direction_output(USBH1_MODE, 0); - - ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen"); - if (ret) { - gpio_free(USBH1_MODE); - return ret; - } - gpio_direction_output(USBH1_VBUSEN_B, 1); - - return 0; -} - - -static int marxbot_isp1105_set_vbus(struct usb_otg *otg, bool on) -{ - if (on) - gpio_set_value(USBH1_VBUSEN_B, 0); - else - gpio_set_value(USBH1_VBUSEN_B, 1); - - return 0; -} - -static struct mxc_usbh_platform_data usbh1_pdata __initdata = { - .init = marxbot_usbh1_hw_init, - .portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL, -}; - -static int __init marxbot_usbh1_init(void) -{ - struct usb_phy *phy; - struct platform_device *pdev; - - phy = kzalloc(sizeof(*phy), GFP_KERNEL); - if (!phy) - return -ENOMEM; - - phy->otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); - if (!phy->otg) { - kfree(phy); - return -ENOMEM; - } - - phy->label = "ISP1105"; - phy->init = marxbot_isp1105_init; - phy->otg->set_vbus = marxbot_isp1105_set_vbus; - - usbh1_pdata.otg = phy; - - pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata); - - return PTR_ERR_OR_ZERO(pdev); -} - -static const struct fsl_usb2_platform_data usb_pdata __initconst = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_ULPI, -}; - -/* - * system init for baseboard usage. Will be called by mx31moboard init. - */ -void __init mx31moboard_marxbot_init(void) -{ - printk(KERN_INFO "Initializing mx31marxbot peripherals\n"); - - mxc_iomux_setup_multiple_pins(marxbot_pins, ARRAY_SIZE(marxbot_pins), - "marxbot"); - - marxbot_init_sel_gpios(); - - dspics_resets_init(); - - imx31_add_mxc_mmc(1, &sdhc2_pdata); - - spi_register_board_info(marxbot_spi_board_info, - ARRAY_SIZE(marxbot_spi_board_info)); - - /* battery present pin */ - gpio_request(IOMUX_TO_GPIO(MX31_PIN_LCS0), "bat-present"); - gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_LCS0)); - gpio_export(IOMUX_TO_GPIO(MX31_PIN_LCS0), false); - - imx31_add_fsl_usb2_udc(&usb_pdata); - - marxbot_usbh1_init(); -} diff --git a/arch/arm/mach-imx/mx31moboard-smartbot.c b/arch/arm/mach-imx/mx31moboard-smartbot.c deleted file mode 100644 index d165bd952bad..000000000000 --- a/arch/arm/mach-imx/mx31moboard-smartbot.c +++ /dev/null @@ -1,124 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group - */ - -#include <linux/delay.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/i2c.h> -#include <linux/platform_device.h> -#include <linux/types.h> - -#include <linux/usb/otg.h> -#include <linux/usb/ulpi.h> - -#include "board-mx31moboard.h" -#include "common.h" -#include "devices-imx31.h" -#include "ehci.h" -#include "hardware.h" -#include "iomux-mx3.h" -#include "ulpi.h" - -static unsigned int smartbot_pins[] = { - /* UART1 */ - MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2, - MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2, - /* ENABLES */ - MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9, - MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11, -}; - -static const struct imxuart_platform_data uart_pdata __initconst = { - .flags = IMXUART_HAVE_RTSCTS, -}; - -static const struct fsl_usb2_platform_data usb_pdata __initconst = { - .operating_mode = FSL_USB2_DR_DEVICE, - .phy_mode = FSL_USB2_PHY_ULPI, -}; - -#if defined(CONFIG_USB_ULPI) - -static int smartbot_otg_init(struct platform_device *pdev) -{ - return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); -} - -static struct mxc_usbh_platform_data otg_host_pdata __initdata = { - .init = smartbot_otg_init, - .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, -}; - -static int __init smartbot_otg_host_init(void) -{ - struct platform_device *pdev; - - otg_host_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | - ULPI_OTG_DRVVBUS_EXT); - if (!otg_host_pdata.otg) - return -ENODEV; - - pdev = imx31_add_mxc_ehci_otg(&otg_host_pdata); - - return PTR_ERR_OR_ZERO(pdev); -} -#else -static inline int smartbot_otg_host_init(void) { return 0; } -#endif - -#define POWER_EN IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1) -#define DSPIC_RST_B IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1) -#define TRSLAT_RST_B IOMUX_TO_GPIO(MX31_PIN_RI_DCE1) -#define TRSLAT_SRC_CHOICE IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1) - -static void smartbot_resets_init(void) -{ - if (!gpio_request(POWER_EN, "power-enable")) { - gpio_direction_output(POWER_EN, 0); - gpio_export(POWER_EN, false); - } - - if (!gpio_request(DSPIC_RST_B, "dspic-rst")) { - gpio_direction_output(DSPIC_RST_B, 0); - gpio_export(DSPIC_RST_B, false); - } - - if (!gpio_request(TRSLAT_RST_B, "translator-rst")) { - gpio_direction_output(TRSLAT_RST_B, 0); - gpio_export(TRSLAT_RST_B, false); - } - - if (!gpio_request(TRSLAT_SRC_CHOICE, "translator-src-choice")) { - gpio_direction_output(TRSLAT_SRC_CHOICE, 0); - gpio_export(TRSLAT_SRC_CHOICE, false); - } -} -/* - * system init for baseboard usage. Will be called by mx31moboard init. - */ -void __init mx31moboard_smartbot_init(int board) -{ - printk(KERN_INFO "Initializing mx31smartbot peripherals\n"); - - mxc_iomux_setup_multiple_pins(smartbot_pins, ARRAY_SIZE(smartbot_pins), - "smartbot"); - - imx31_add_imx_uart1(&uart_pdata); - - switch (board) { - case MX31SMARTBOT: - imx31_add_fsl_usb2_udc(&usb_pdata); - break; - case MX31EYEBOT: - smartbot_otg_host_init(); - break; - default: - printk(KERN_WARNING "Unknown board %d, USB OTG not initialized", - board); - } - - smartbot_resets_init(); -} diff --git a/arch/arm/mach-imx/mx35.h b/arch/arm/mach-imx/mx35.h index 760de6a0af7e..5a8a87a85c14 100644 --- a/arch/arm/mach-imx/mx35.h +++ b/arch/arm/mach-imx/mx35.h @@ -2,190 +2,17 @@ #ifndef __MACH_MX35_H__ #define __MACH_MX35_H__ -/* - * IRAM - */ -#define MX35_IRAM_BASE_ADDR 0x10000000 /* internal ram */ -#define MX35_IRAM_SIZE SZ_128K - -#define MX35_L2CC_BASE_ADDR 0x30000000 -#define MX35_L2CC_SIZE SZ_1M - #define MX35_AIPS1_BASE_ADDR 0x43f00000 #define MX35_AIPS1_SIZE SZ_1M -#define MX35_MAX_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x04000) -#define MX35_EVTMON_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x08000) -#define MX35_CLKCTL_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x0c000) -#define MX35_ETB_SLOT4_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x10000) -#define MX35_ETB_SLOT5_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x14000) -#define MX35_ECT_CTIO_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x18000) -#define MX35_I2C1_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x80000) -#define MX35_I2C3_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x84000) -#define MX35_UART1_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x90000) -#define MX35_UART2_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x94000) -#define MX35_I2C2_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x98000) -#define MX35_OWIRE_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x9c000) -#define MX35_SSI1_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0xa0000) -#define MX35_CSPI1_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0xa4000) -#define MX35_KPP_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0xa8000) -#define MX35_IOMUXC_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0xac000) -#define MX35_ECT_IP1_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0xb8000) -#define MX35_ECT_IP2_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0xbc000) - #define MX35_SPBA0_BASE_ADDR 0x50000000 #define MX35_SPBA0_SIZE SZ_1M -#define MX35_UART3_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x0c000) -#define MX35_CSPI2_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x10000) -#define MX35_SSI2_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x14000) -#define MX35_ATA_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x20000) -#define MX35_MSHC1_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x24000) -#define MX35_FEC_BASE_ADDR 0x50038000 -#define MX35_SPBA_CTRL_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x3c000) - #define MX35_AIPS2_BASE_ADDR 0x53f00000 #define MX35_AIPS2_SIZE SZ_1M -#define MX35_CCM_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0x80000) -#define MX35_GPT1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0x90000) -#define MX35_EPIT1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0x94000) -#define MX35_EPIT2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0x98000) -#define MX35_GPIO3_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xa4000) -#define MX35_SCC_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xac000) -#define MX35_RNGA_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb0000) -#define MX35_ESDHC1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb4000) -#define MX35_ESDHC2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb8000) -#define MX35_ESDHC3_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xbc000) -#define MX35_IPU_CTRL_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xc0000) -#define MX35_AUDMUX_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xc4000) -#define MX35_GPIO1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xcc000) -#define MX35_GPIO2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xd0000) -#define MX35_SDMA_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xd4000) -#define MX35_RTC_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xd8000) -#define MX35_WDOG_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xdc000) -#define MX35_PWM_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xe0000) -#define MX35_CAN1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xe4000) -#define MX35_CAN2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xe8000) -#define MX35_RTIC_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xec000) -#define MX35_IIM_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xf0000) -#define MX35_USB_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xf4000) -#define MX35_USB_OTG_BASE_ADDR (MX35_USB_BASE_ADDR + 0x0000) -/* - * The Reference Manual (IMX35RM, Rev. 2, 3/2009) claims an offset of 0x200 for - * HS. When host support was implemented only a preliminary document was - * available, which told 0x400. This works fine. - */ -#define MX35_USB_HS_BASE_ADDR (MX35_USB_BASE_ADDR + 0x0400) - -#define MX35_ROMP_BASE_ADDR 0x60000000 -#define MX35_ROMP_SIZE SZ_1M - #define MX35_AVIC_BASE_ADDR 0x68000000 #define MX35_AVIC_SIZE SZ_1M - -/* - * Memory regions and CS - */ -#define MX35_IPU_MEM_BASE_ADDR 0x70000000 -#define MX35_CSD0_BASE_ADDR 0x80000000 -#define MX35_CSD1_BASE_ADDR 0x90000000 - -#define MX35_CS0_BASE_ADDR 0xa0000000 -#define MX35_CS1_BASE_ADDR 0xa8000000 -#define MX35_CS2_BASE_ADDR 0xb0000000 -#define MX35_CS3_BASE_ADDR 0xb2000000 - -#define MX35_CS4_BASE_ADDR 0xb4000000 -#define MX35_CS4_BASE_ADDR_VIRT 0xf6000000 -#define MX35_CS4_SIZE SZ_32M - -#define MX35_CS5_BASE_ADDR 0xb6000000 -#define MX35_CS5_BASE_ADDR_VIRT 0xf8000000 -#define MX35_CS5_SIZE SZ_32M - -/* - * NAND, SDRAM, WEIM, M3IF, EMI controllers - */ #define MX35_X_MEMC_BASE_ADDR 0xb8000000 #define MX35_X_MEMC_SIZE SZ_64K -#define MX35_ESDCTL_BASE_ADDR (MX35_X_MEMC_BASE_ADDR + 0x1000) -#define MX35_WEIM_BASE_ADDR (MX35_X_MEMC_BASE_ADDR + 0x2000) -#define MX35_M3IF_BASE_ADDR (MX35_X_MEMC_BASE_ADDR + 0x3000) -#define MX35_EMI_CTL_BASE_ADDR (MX35_X_MEMC_BASE_ADDR + 0x4000) -#define MX35_PCMCIA_CTL_BASE_ADDR MX35_EMI_CTL_BASE_ADDR - -#define MX35_NFC_BASE_ADDR 0xbb000000 -#define MX35_PCMCIA_MEM_BASE_ADDR 0xbc000000 #define MX35_IO_P2V(x) IMX_IO_P2V(x) -#define MX35_IO_ADDRESS(x) IOMEM(MX35_IO_P2V(x)) - -/* - * Interrupt numbers - */ -#include <asm/irq.h> -#define MX35_INT_OWIRE (NR_IRQS_LEGACY + 2) -#define MX35_INT_I2C3 (NR_IRQS_LEGACY + 3) -#define MX35_INT_I2C2 (NR_IRQS_LEGACY + 4) -#define MX35_INT_RTIC (NR_IRQS_LEGACY + 6) -#define MX35_INT_ESDHC1 (NR_IRQS_LEGACY + 7) -#define MX35_INT_ESDHC2 (NR_IRQS_LEGACY + 8) -#define MX35_INT_ESDHC3 (NR_IRQS_LEGACY + 9) -#define MX35_INT_I2C1 (NR_IRQS_LEGACY + 10) -#define MX35_INT_SSI1 (NR_IRQS_LEGACY + 11) -#define MX35_INT_SSI2 (NR_IRQS_LEGACY + 12) -#define MX35_INT_CSPI2 (NR_IRQS_LEGACY + 13) -#define MX35_INT_CSPI1 (NR_IRQS_LEGACY + 14) -#define MX35_INT_ATA (NR_IRQS_LEGACY + 15) -#define MX35_INT_GPU2D (NR_IRQS_LEGACY + 16) -#define MX35_INT_ASRC (NR_IRQS_LEGACY + 17) -#define MX35_INT_UART3 (NR_IRQS_LEGACY + 18) -#define MX35_INT_IIM (NR_IRQS_LEGACY + 19) -#define MX35_INT_RNGA (NR_IRQS_LEGACY + 22) -#define MX35_INT_EVTMON (NR_IRQS_LEGACY + 23) -#define MX35_INT_KPP (NR_IRQS_LEGACY + 24) -#define MX35_INT_RTC (NR_IRQS_LEGACY + 25) -#define MX35_INT_PWM (NR_IRQS_LEGACY + 26) -#define MX35_INT_EPIT2 (NR_IRQS_LEGACY + 27) -#define MX35_INT_EPIT1 (NR_IRQS_LEGACY + 28) -#define MX35_INT_GPT (NR_IRQS_LEGACY + 29) -#define MX35_INT_POWER_FAIL (NR_IRQS_LEGACY + 30) -#define MX35_INT_UART2 (NR_IRQS_LEGACY + 32) -#define MX35_INT_NFC (NR_IRQS_LEGACY + 33) -#define MX35_INT_SDMA (NR_IRQS_LEGACY + 34) -#define MX35_INT_USB_HS (NR_IRQS_LEGACY + 35) -#define MX35_INT_USB_OTG (NR_IRQS_LEGACY + 37) -#define MX35_INT_MSHC1 (NR_IRQS_LEGACY + 39) -#define MX35_INT_ESAI (NR_IRQS_LEGACY + 40) -#define MX35_INT_IPU_ERR (NR_IRQS_LEGACY + 41) -#define MX35_INT_IPU_SYN (NR_IRQS_LEGACY + 42) -#define MX35_INT_CAN1 (NR_IRQS_LEGACY + 43) -#define MX35_INT_CAN2 (NR_IRQS_LEGACY + 44) -#define MX35_INT_UART1 (NR_IRQS_LEGACY + 45) -#define MX35_INT_MLB (NR_IRQS_LEGACY + 46) -#define MX35_INT_SPDIF (NR_IRQS_LEGACY + 47) -#define MX35_INT_ECT (NR_IRQS_LEGACY + 48) -#define MX35_INT_SCC_SCM (NR_IRQS_LEGACY + 49) -#define MX35_INT_SCC_SMN (NR_IRQS_LEGACY + 50) -#define MX35_INT_GPIO2 (NR_IRQS_LEGACY + 51) -#define MX35_INT_GPIO1 (NR_IRQS_LEGACY + 52) -#define MX35_INT_WDOG (NR_IRQS_LEGACY + 55) -#define MX35_INT_GPIO3 (NR_IRQS_LEGACY + 56) -#define MX35_INT_FEC (NR_IRQS_LEGACY + 57) -#define MX35_INT_EXT_POWER (NR_IRQS_LEGACY + 58) -#define MX35_INT_EXT_TEMPER (NR_IRQS_LEGACY + 59) -#define MX35_INT_EXT_SENSOR60 (NR_IRQS_LEGACY + 60) -#define MX35_INT_EXT_SENSOR61 (NR_IRQS_LEGACY + 61) -#define MX35_INT_EXT_WDOG (NR_IRQS_LEGACY + 62) -#define MX35_INT_EXT_TV (NR_IRQS_LEGACY + 63) - -#define MX35_DMA_REQ_SSI2_RX1 22 -#define MX35_DMA_REQ_SSI2_TX1 23 -#define MX35_DMA_REQ_SSI2_RX0 24 -#define MX35_DMA_REQ_SSI2_TX0 25 -#define MX35_DMA_REQ_SSI1_RX1 26 -#define MX35_DMA_REQ_SSI1_TX1 27 -#define MX35_DMA_REQ_SSI1_RX0 28 -#define MX35_DMA_REQ_SSI1_TX0 29 - -#define MX35_PROD_SIGNATURE 0x1 /* For MX31 */ #endif /* ifndef __MACH_MX35_H__ */ diff --git a/arch/arm/mach-imx/pcm037.h b/arch/arm/mach-imx/pcm037.h deleted file mode 100644 index 470d3c887e14..000000000000 --- a/arch/arm/mach-imx/pcm037.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __PCM037_H__ -#define __PCM037_H__ - -enum pcm037_board_variant { - PCM037_PCM970, - PCM037_EET, -}; - -extern enum pcm037_board_variant pcm037_variant(void); - -#ifdef CONFIG_MACH_PCM037_EET -int pcm037_eet_init_devices(void); -#else -static inline int pcm037_eet_init_devices(void) { return 0; } -#endif - -#endif diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c index d943535566c8..020e6deb67c8 100644 --- a/arch/arm/mach-imx/pm-imx27.c +++ b/arch/arm/mach-imx/pm-imx27.c @@ -7,6 +7,7 @@ * modify it under the terms of the GNU General Public License. */ +#include <linux/of_address.h> #include <linux/kernel.h> #include <linux/suspend.h> #include <linux/io.h> @@ -15,13 +16,20 @@ static int mx27_suspend_enter(suspend_state_t state) { + void __iomem *ccm_base; + struct device_node *np; u32 cscr; + + np = of_find_compatible_node(NULL, NULL, "fsl,imx27-ccm"); + ccm_base = of_iomap(np, 0); + BUG_ON(!ccm_base); + switch (state) { case PM_SUSPEND_MEM: /* Clear MPEN and SPEN to disable MPLL/SPLL */ - cscr = imx_readl(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); + cscr = imx_readl(ccm_base); cscr &= 0xFFFFFFFC; - imx_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); + imx_writel(cscr, ccm_base); /* Executes WFI */ cpu_do_idle(); break; diff --git a/arch/arm/mach-imx/ulpi.h b/arch/arm/mach-imx/ulpi.h deleted file mode 100644 index b367902c9c32..000000000000 --- a/arch/arm/mach-imx/ulpi.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __MACH_ULPI_H -#define __MACH_ULPI_H - -#include <linux/usb/ulpi.h> - -#ifdef CONFIG_USB_ULPI_VIEWPORT -static inline struct usb_phy *imx_otg_ulpi_create(unsigned int flags) -{ - return otg_ulpi_create(&ulpi_viewport_access_ops, flags); -} -#else -static inline struct usb_phy *imx_otg_ulpi_create(unsigned int flags) -{ - return NULL; -} -#endif - -#endif /* __MACH_ULPI_H */ - diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 184262d660ba..000f672a94c9 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -29,6 +29,7 @@ #include <linux/sched_clock.h> #include <linux/irqchip/irq-ixp4xx.h> #include <linux/platform_data/timer-ixp4xx.h> +#include <linux/dma-map-ops.h> #include <mach/udc.h> #include <mach/hardware.h> #include <mach/io.h> diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c index 638808c4e122..09a65c2dfd73 100644 --- a/arch/arm/mach-keystone/keystone.c +++ b/arch/arm/mach-keystone/keystone.c @@ -8,6 +8,7 @@ */ #include <linux/io.h> #include <linux/of.h> +#include <linux/dma-mapping.h> #include <linux/init.h> #include <linux/of_platform.h> #include <linux/of_address.h> @@ -24,8 +25,7 @@ #include "keystone.h" -static unsigned long keystone_dma_pfn_offset __read_mostly; - +#ifdef CONFIG_ARM_LPAE static int keystone_platform_notifier(struct notifier_block *nb, unsigned long event, void *data) { @@ -38,9 +38,12 @@ static int keystone_platform_notifier(struct notifier_block *nb, return NOTIFY_BAD; if (!dev->of_node) { - dev->dma_pfn_offset = keystone_dma_pfn_offset; - dev_err(dev, "set dma_pfn_offset%08lx\n", - dev->dma_pfn_offset); + int ret = dma_direct_set_offset(dev, KEYSTONE_HIGH_PHYS_START, + KEYSTONE_LOW_PHYS_START, + KEYSTONE_HIGH_PHYS_SIZE); + dev_err(dev, "set dma_offset%08llx%s\n", + KEYSTONE_HIGH_PHYS_START - KEYSTONE_LOW_PHYS_START, + ret ? " failed" : ""); } return NOTIFY_OK; } @@ -48,14 +51,14 @@ static int keystone_platform_notifier(struct notifier_block *nb, static struct notifier_block platform_nb = { .notifier_call = keystone_platform_notifier, }; +#endif /* CONFIG_ARM_LPAE */ static void __init keystone_init(void) { - if (PHYS_OFFSET >= KEYSTONE_HIGH_PHYS_START) { - keystone_dma_pfn_offset = PFN_DOWN(KEYSTONE_HIGH_PHYS_START - - KEYSTONE_LOW_PHYS_START); +#ifdef CONFIG_ARM_LPAE + if (PHYS_OFFSET >= KEYSTONE_HIGH_PHYS_START) bus_register_notifier(&platform_bus_type, &platform_nb); - } +#endif keystone_pm_runtime_init(); } diff --git a/arch/arm/mach-mstar/Kconfig b/arch/arm/mach-mstar/Kconfig index 52744fe32368..576d1ab293c8 100644 --- a/arch/arm/mach-mstar/Kconfig +++ b/arch/arm/mach-mstar/Kconfig @@ -3,6 +3,7 @@ menuconfig ARCH_MSTARV7 depends on ARCH_MULTI_V7 select ARM_GIC select ARM_HEAVY_MB + select MST_IRQ help Support for newer MStar/Sigmastar SoC families that are based on Armv7 cores like the Cortex A7 and share the same diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index 8f8748a0c84f..49e3c8d20c2f 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -25,7 +25,7 @@ #include <linux/of_address.h> #include <linux/io.h> #include <linux/smp.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/mbus.h> diff --git a/arch/arm/mach-omap1/include/mach/memory.h b/arch/arm/mach-omap1/include/mach/memory.h index 1142560e0078..36bc0000cb6a 100644 --- a/arch/arm/mach-omap1/include/mach/memory.h +++ b/arch/arm/mach-omap1/include/mach/memory.h @@ -14,42 +14,11 @@ * OMAP-1510 bus address is translated into a Local Bus address if the * OMAP bus type is lbus. We do the address translation based on the * device overriding the defaults used in the dma-mapping API. - * Note that the is_lbus_device() test is not very efficient on 1510 - * because of the strncmp(). */ -#if defined(CONFIG_ARCH_OMAP15XX) && !defined(__ASSEMBLER__) /* * OMAP-1510 Local Bus address offset */ #define OMAP1510_LB_OFFSET UL(0x30000000) -#define virt_to_lbus(x) ((x) - PAGE_OFFSET + OMAP1510_LB_OFFSET) -#define lbus_to_virt(x) ((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET) -#define is_lbus_device(dev) (cpu_is_omap15xx() && dev && (strncmp(dev_name(dev), "ohci", 4) == 0)) - -#define __arch_pfn_to_dma(dev, pfn) \ - ({ dma_addr_t __dma = __pfn_to_phys(pfn); \ - if (is_lbus_device(dev)) \ - __dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \ - __dma; }) - -#define __arch_dma_to_pfn(dev, addr) \ - ({ dma_addr_t __dma = addr; \ - if (is_lbus_device(dev)) \ - __dma += PHYS_OFFSET - OMAP1510_LB_OFFSET; \ - __phys_to_pfn(__dma); \ - }) - -#define __arch_dma_to_virt(dev, addr) ({ (void *) (is_lbus_device(dev) ? \ - lbus_to_virt(addr) : \ - __phys_to_virt(addr)); }) - -#define __arch_virt_to_dma(dev, addr) ({ unsigned long __addr = (unsigned long)(addr); \ - (dma_addr_t) (is_lbus_device(dev) ? \ - virt_to_lbus(__addr) : \ - __virt_to_phys(__addr)); }) - -#endif /* CONFIG_ARCH_OMAP15XX */ - #endif diff --git a/arch/arm/mach-omap1/include/mach/mux.h b/arch/arm/mach-omap1/include/mach/mux.h index adfe1f6bd0c5..3f6dc55d9898 100644 --- a/arch/arm/mach-omap1/include/mach/mux.h +++ b/arch/arm/mach-omap1/include/mach/mux.h @@ -88,7 +88,7 @@ * OMAP730/850 has a slightly different config for the pin mux. * - config regs are the OMAP7XX_IO_CONF_x regs (see omap7xx.h) regs and * not the FUNC_MUX_CTRL_x regs from hardware.h - * - for pull-up/down, only has one enable bit which is is in the same register + * - for pull-up/down, only has one enable bit which is in the same register * as mux config */ #define MUX_CFG_7XX(desc, mux_reg, mode_offset, mode, \ diff --git a/arch/arm/mach-omap1/usb.c b/arch/arm/mach-omap1/usb.c index d8e9bbda8f7b..ba8566204ea9 100644 --- a/arch/arm/mach-omap1/usb.c +++ b/arch/arm/mach-omap1/usb.c @@ -9,6 +9,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> +#include <linux/dma-mapping.h> #include <linux/io.h> #include <asm/irq.h> @@ -542,6 +543,25 @@ bad: /* ULPD_APLL_CTRL */ #define APLL_NDPLL_SWITCH (1 << 0) +static int omap_1510_usb_ohci_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct device *dev = data; + + if (event != BUS_NOTIFY_ADD_DEVICE) + return NOTIFY_DONE; + + if (strncmp(dev_name(dev), "ohci", 4) == 0 && + dma_direct_set_offset(dev, PHYS_OFFSET, OMAP1510_LB_OFFSET, + (u64)-1)) + WARN_ONCE(1, "failed to set DMA offset\n"); + return NOTIFY_OK; +} + +static struct notifier_block omap_1510_usb_ohci_nb = { + .notifier_call = omap_1510_usb_ohci_notifier, +}; + static void __init omap_1510_usb_init(struct omap_usb_config *config) { unsigned int val; @@ -600,6 +620,8 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config) if (config->register_host) { int status; + bus_register_notifier(&platform_bus_type, + &omap_1510_usb_ohci_nb); ohci_device.dev.platform_data = config; status = platform_device_register(&ohci_device); if (status) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index ea23205bf70f..3ee7bdff86b2 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -7,6 +7,7 @@ config ARCH_OMAP2 depends on ARCH_MULTI_V6 select ARCH_OMAP2PLUS select CPU_V6 + select PM_GENERIC_DOMAINS if PM select SOC_HAS_OMAP2_SDRC config ARCH_OMAP3 diff --git a/arch/arm/mach-omap2/am33xx.h b/arch/arm/mach-omap2/am33xx.h index 5eef093e6738..bf2b5f87e404 100644 --- a/arch/arm/mach-omap2/am33xx.h +++ b/arch/arm/mach-omap2/am33xx.h @@ -1,7 +1,7 @@ /* * This file contains the address info for various AM33XX modules. * - * Copyright (C) 2011 Texas Instruments, Inc. - http://www.ti.com/ + * Copyright (C) 2011 Texas Instruments, Inc. - https://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 334923d7652d..7290f033fd2d 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -3,7 +3,7 @@ * Copyright (C) 2005 Nokia Corporation * Author: Paul Mundt <paul.mundt@nokia.com> * - * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/ * * Modified from the original mach-omap/omap2/board-generic.c did by Paul * to support the OMAP2+ device tree boards with an unique board file. diff --git a/arch/arm/mach-omap2/clockdomains33xx_data.c b/arch/arm/mach-omap2/clockdomains33xx_data.c index 32c90fd9eba2..b4d5144df445 100644 --- a/arch/arm/mach-omap2/clockdomains33xx_data.c +++ b/arch/arm/mach-omap2/clockdomains33xx_data.c @@ -1,7 +1,7 @@ /* * AM33XX Clock Domain data. * - * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2011-2012 Texas Instruments Incorporated - https://www.ti.com/ * Vaibhav Hiremath <hvaibhav@ti.com> * * This program is free software; you can redistribute it and/or diff --git a/arch/arm/mach-omap2/clockdomains81xx_data.c b/arch/arm/mach-omap2/clockdomains81xx_data.c index 65fbd136b20c..127dc7ace71f 100644 --- a/arch/arm/mach-omap2/clockdomains81xx_data.c +++ b/arch/arm/mach-omap2/clockdomains81xx_data.c @@ -1,7 +1,7 @@ /* * TI81XX Clock Domain data. * - * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ + * Copyright (C) 2010 Texas Instruments, Inc. - https://www.ti.com/ * Copyright (C) 2013 SKTB SKiT, http://www.skitlab.ru/ * * This program is free software; you can redistribute it and/or diff --git a/arch/arm/mach-omap2/cm-regbits-33xx.h b/arch/arm/mach-omap2/cm-regbits-33xx.h index c0823fd6d5e0..e7ae2bb515e3 100644 --- a/arch/arm/mach-omap2/cm-regbits-33xx.h +++ b/arch/arm/mach-omap2/cm-regbits-33xx.h @@ -4,7 +4,7 @@ * This file is automatically generated from the AM33XX hardware databases. * Vaibhav Hiremath <hvaibhav@ti.com> * - * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2011-2012 Texas Instruments Incorporated - https://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/arch/arm/mach-omap2/cm-regbits-54xx.h b/arch/arm/mach-omap2/cm-regbits-54xx.h index 44663b575bf4..fc886883866f 100644 --- a/arch/arm/mach-omap2/cm-regbits-54xx.h +++ b/arch/arm/mach-omap2/cm-regbits-54xx.h @@ -2,7 +2,7 @@ /* * OMAP54xx Clock Management register bits * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com * * Paul Walmsley (paul@pwsan.com) * Rajendra Nayak (rnayak@ti.com) diff --git a/arch/arm/mach-omap2/cm-regbits-7xx.h b/arch/arm/mach-omap2/cm-regbits-7xx.h index a78ccbaab1a6..2725af4d1f87 100644 --- a/arch/arm/mach-omap2/cm-regbits-7xx.h +++ b/arch/arm/mach-omap2/cm-regbits-7xx.h @@ -2,7 +2,7 @@ /* * DRA7xx Clock Management register bits * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com * * Generated by code originally written by: * Paul Walmsley (paul@pwsan.com) diff --git a/arch/arm/mach-omap2/cm1_54xx.h b/arch/arm/mach-omap2/cm1_54xx.h index 7be363a27a40..eb86bbd93f35 100644 --- a/arch/arm/mach-omap2/cm1_54xx.h +++ b/arch/arm/mach-omap2/cm1_54xx.h @@ -2,7 +2,7 @@ /* * OMAP54xx CM1 instance offset macros * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com * * Paul Walmsley (paul@pwsan.com) * Rajendra Nayak (rnayak@ti.com) diff --git a/arch/arm/mach-omap2/cm1_7xx.h b/arch/arm/mach-omap2/cm1_7xx.h index 28660edc7f5f..aae3831f5233 100644 --- a/arch/arm/mach-omap2/cm1_7xx.h +++ b/arch/arm/mach-omap2/cm1_7xx.h @@ -2,7 +2,7 @@ /* * DRA7xx CM1 instance offset macros * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com * * Generated by code originally written by: * Paul Walmsley (paul@pwsan.com) diff --git a/arch/arm/mach-omap2/cm2_54xx.h b/arch/arm/mach-omap2/cm2_54xx.h index c5da1f5cae93..8e49765cd441 100644 --- a/arch/arm/mach-omap2/cm2_54xx.h +++ b/arch/arm/mach-omap2/cm2_54xx.h @@ -2,7 +2,7 @@ /* * OMAP54xx CM2 instance offset macros * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com * * Paul Walmsley (paul@pwsan.com) * Rajendra Nayak (rnayak@ti.com) diff --git a/arch/arm/mach-omap2/cm2_7xx.h b/arch/arm/mach-omap2/cm2_7xx.h index e16fc58ef152..f8734605b1e1 100644 --- a/arch/arm/mach-omap2/cm2_7xx.h +++ b/arch/arm/mach-omap2/cm2_7xx.h @@ -2,7 +2,7 @@ /* * DRA7xx CM2 instance offset macros * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com * * Generated by code originally written by: * Paul Walmsley (paul@pwsan.com) diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index 084d454f6074..ac4882ebdca3 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c @@ -1,7 +1,7 @@ /* * AM33XX CM functions * - * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2011-2012 Texas Instruments Incorporated - https://www.ti.com/ * Vaibhav Hiremath <hvaibhav@ti.com> * * Reference taken from from OMAP4 cminst44xx.c diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h index a91f7d282455..63b362bfc4d9 100644 --- a/arch/arm/mach-omap2/cm33xx.h +++ b/arch/arm/mach-omap2/cm33xx.h @@ -1,7 +1,7 @@ /* * AM33XX CM offset macros * - * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2011-2012 Texas Instruments Incorporated - https://www.ti.com/ * Vaibhav Hiremath <hvaibhav@ti.com> * * This program is free software; you can redistribute it and/or diff --git a/arch/arm/mach-omap2/cm81xx.h b/arch/arm/mach-omap2/cm81xx.h index 5d73a1057c82..bd91223e838e 100644 --- a/arch/arm/mach-omap2/cm81xx.h +++ b/arch/arm/mach-omap2/cm81xx.h @@ -1,7 +1,7 @@ /* * Clock domain register offsets for TI81XX. * - * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ + * Copyright (C) 2010 Texas Instruments, Inc. - https://www.ti.com/ * Copyright (C) 2013 SKTB SKiT, http://www.skitlab.ru/ * * This program is free software; you can redistribute it and/or diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index 6f5f89711f25..a92d277f81a0 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -174,8 +174,10 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, */ if (mpuss_can_lose_context) { error = cpu_cluster_pm_enter(); - if (error) + if (error) { + omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON); goto cpu_cluster_pm_out; + } } } diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 46012ca812f4..2000fca6bd4e 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -1,7 +1,7 @@ /* * OMAP2plus display device setup / initialization. * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/ * Senthilvadivu Guruswamy * Sumit Semwal * diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index 8cc109cc242a..dfc9b21ff19b 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c @@ -13,7 +13,7 @@ * Copyright (C) 2009 Texas Instruments * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/ * Converted DMA library into platform driver * - G, Manjunath Kondaiah <manjugk@ti.com> */ diff --git a/arch/arm/mach-omap2/l3_2xxx.h b/arch/arm/mach-omap2/l3_2xxx.h index c2bd8d86202b..6297c62428ac 100644 --- a/arch/arm/mach-omap2/l3_2xxx.h +++ b/arch/arm/mach-omap2/l3_2xxx.h @@ -2,7 +2,7 @@ /* * arch/arm/plat-omap/include/plat/l3_2xxx.h - L3 firewall definitions * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/ * Sumit Semwal */ #ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_2XXX_H diff --git a/arch/arm/mach-omap2/l3_3xxx.h b/arch/arm/mach-omap2/l3_3xxx.h index 995ebccd13e0..60ea7b201fdc 100644 --- a/arch/arm/mach-omap2/l3_3xxx.h +++ b/arch/arm/mach-omap2/l3_3xxx.h @@ -2,7 +2,7 @@ /* * arch/arm/plat-omap/include/plat/l3_3xxx.h - L3 firewall definitions * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/ * Sumit Semwal */ #ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_3XXX_H diff --git a/arch/arm/mach-omap2/l4_2xxx.h b/arch/arm/mach-omap2/l4_2xxx.h index 556e69c2bd00..418e1072d730 100644 --- a/arch/arm/mach-omap2/l4_2xxx.h +++ b/arch/arm/mach-omap2/l4_2xxx.h @@ -2,7 +2,7 @@ /* * arch/arm/plat-omap/include/plat/l4_2xxx.h - L4 firewall definitions * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/ * Sumit Semwal */ #ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L4_2XXX_H diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index 54aff33e55e6..93c20bbd7b7e 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -2,7 +2,7 @@ /* * OMAP IOMMU quirks for various TI SoCs * - * Copyright (C) 2015-2019 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2015-2019 Texas Instruments Incorporated - https://www.ti.com/ * Suman Anna <s-anna@ti.com> */ @@ -74,7 +74,7 @@ static struct powerdomain *_get_pwrdm(struct device *dev) return pwrdm; clk = of_clk_get(dev->of_node->parent, 0); - if (!clk) { + if (IS_ERR(clk)) { dev_err(dev, "no fck found\n"); return 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 index 5f4ab24dd60d..e29841072287 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h @@ -26,7 +26,6 @@ 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_l4_wkup__rtc; 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; @@ -43,7 +42,6 @@ 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 am33xx_rtc_hwmod; extern struct omap_hwmod_class am33xx_emif_hwmod_class; extern struct omap_hwmod_class am33xx_l4_hwmod_class; 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 index b389d6589c32..ab5146bfe941 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c @@ -74,30 +74,6 @@ struct omap_hwmod_ocp_if am33xx_l3_s__l3_main = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* gfx -> l3 main */ -struct omap_hwmod_ocp_if am33xx_gfx__l3_main = { - .master = &am33xx_gfx_hwmod, - .slave = &am33xx_l3_main_hwmod, - .clk = "dpll_core_m4_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l3 main -> gfx */ -struct omap_hwmod_ocp_if am33xx_l3_main__gfx = { - .master = &am33xx_l3_main_hwmod, - .slave = &am33xx_gfx_hwmod, - .clk = "dpll_core_m4_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* l4 wkup -> rtc */ -struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc = { - .master = &am33xx_l4_wkup_hwmod, - .slave = &am33xx_rtc_hwmod, - .clk = "clkdiv32k_ick", - .user = OCP_USER_MPU, -}; - /* l3s cfg -> gpmc */ struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = { .master = &am33xx_l3_s_hwmod, 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 index 4b3cd590fb52..bcc120ed610a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c @@ -26,7 +26,6 @@ #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)) -#define PRCM_FLAGS(oh, flag) ((oh).prcm.omap4.flags = (flag)) /* * 'l3' class @@ -133,30 +132,6 @@ struct omap_hwmod_class am33xx_wkup_m3_hwmod_class = { .name = "wkup_m3", }; -/* gfx */ -/* Pseudo hwmod for reset control purpose only */ -static struct omap_hwmod_class am33xx_gfx_hwmod_class = { - .name = "gfx", -}; - -static struct omap_hwmod_rst_info am33xx_gfx_resets[] = { - { .name = "gfx", .rst_shift = 0, .st_shift = 0}, -}; - -struct omap_hwmod am33xx_gfx_hwmod = { - .name = "gfx", - .class = &am33xx_gfx_hwmod_class, - .clkdm_name = "gfx_l3_clkdm", - .main_clk = "gfx_fck_div_ck", - .prcm = { - .omap4 = { - .modulemode = MODULEMODE_SWCTRL, - }, - }, - .rst_lines = am33xx_gfx_resets, - .rst_lines_cnt = ARRAY_SIZE(am33xx_gfx_resets), -}; - /* * 'prcm' class * power and reset manager (whole prcm infrastructure) @@ -274,67 +249,24 @@ struct omap_hwmod am33xx_gpmc_hwmod = { }, }; - -/* - * 'rtc' class - * rtc subsystem - */ -static struct omap_hwmod_class_sysconfig am33xx_rtc_sysc = { - .rev_offs = 0x0074, - .sysc_offs = 0x0078, - .sysc_flags = SYSC_HAS_SIDLEMODE, - .idlemodes = (SIDLE_FORCE | SIDLE_NO | - SIDLE_SMART | SIDLE_SMART_WKUP), - .sysc_fields = &omap_hwmod_sysc_type3, -}; - -static struct omap_hwmod_class am33xx_rtc_hwmod_class = { - .name = "rtc", - .sysc = &am33xx_rtc_sysc, - .unlock = &omap_hwmod_rtc_unlock, - .lock = &omap_hwmod_rtc_lock, -}; - -struct omap_hwmod am33xx_rtc_hwmod = { - .name = "rtc", - .class = &am33xx_rtc_hwmod_class, - .clkdm_name = "l4_rtc_clkdm", - .main_clk = "clk_32768_ck", - .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_rtc_hwmod, AM33XX_CM_RTC_RTC_CLKCTRL_OFFSET); - PRCM_FLAGS(am33xx_rtc_hwmod, HWMOD_OMAP4_ZERO_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_gfx_hwmod, AM33XX_CM_GFX_GFX_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); } -static void omap_hwmod_am33xx_rst(void) -{ - RSTCTRL(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTCTRL_OFFSET); - RSTST(am33xx_gfx_hwmod, AM33XX_RM_GFX_RSTST_OFFSET); -} - void omap_hwmod_am33xx_reg(void) { omap_hwmod_am33xx_clkctrl(); - omap_hwmod_am33xx_rst(); } static void omap_hwmod_am43xx_clkctrl(void) @@ -343,25 +275,16 @@ static void omap_hwmod_am43xx_clkctrl(void) AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET); CLKCTRL(am33xx_smartreflex1_hwmod, AM43XX_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET); - CLKCTRL(am33xx_rtc_hwmod, AM43XX_CM_RTC_RTC_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_gfx_hwmod, AM43XX_CM_GFX_GFX_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); } -static void omap_hwmod_am43xx_rst(void) -{ - RSTCTRL(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTCTRL_OFFSET); - RSTST(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTST_OFFSET); -} - void omap_hwmod_am43xx_reg(void) { omap_hwmod_am43xx_clkctrl(); - omap_hwmod_am43xx_rst(); } diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 3cf9c4c90b18..b232f6ca6fe3 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -1,7 +1,7 @@ /* * omap_hwmod_33xx_data.c: Hardware modules present on the AM33XX chips * - * Copyright (C) {2012} Texas Instruments Incorporated - http://www.ti.com/ + * 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 @@ -274,16 +274,13 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l3_main__l4_hs, &am33xx_l3_main__l3_s, &am33xx_l3_main__l3_instr, - &am33xx_l3_main__gfx, &am33xx_l3_s__l3_main, &am33xx_wkup_m3__l4_wkup, - &am33xx_gfx__l3_main, &am33xx_l3_main__debugss, &am33xx_l4_wkup__wkup_m3, &am33xx_l4_wkup__control, &am33xx_l4_wkup__smartreflex0, &am33xx_l4_wkup__smartreflex1, - &am33xx_l4_wkup__rtc, &am33xx_l3_s__gpmc, &am33xx_l3_main__ocmc, NULL, diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c index b88d12de68a2..b97cb745bbbc 100644 --- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c @@ -143,11 +143,9 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { &am43xx_l3_main__l4_hs, &am33xx_l3_main__l3_s, &am33xx_l3_main__l3_instr, - &am33xx_l3_main__gfx, &am33xx_l3_s__l3_main, &am43xx_l3_main__emif, &am43xx_wkup_m3__l4_wkup, - &am33xx_gfx__l3_main, &am43xx_l4_wkup__wkup_m3, &am43xx_l4_wkup__control, &am43xx_l4_wkup__smartreflex0, @@ -157,11 +155,6 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { NULL, }; -static struct omap_hwmod_ocp_if *am43xx_rtc_hwmod_ocp_ifs[] __initdata = { - &am33xx_l4_wkup__rtc, - NULL, -}; - int __init am43xx_hwmod_init(void) { int ret; @@ -170,8 +163,5 @@ int __init am43xx_hwmod_init(void) omap_hwmod_init(); ret = omap_hwmod_register_links(am43xx_hwmod_ocp_ifs); - if (!ret && of_machine_is_compatible("ti,am4372")) - ret = omap_hwmod_register_links(am43xx_rtc_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 665ca74a834a..37c59115b353 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -124,21 +124,6 @@ static struct omap_hwmod_class omap44xx_l4_hwmod_class = { .name = "l4", }; -/* l4_abe */ -static struct omap_hwmod omap44xx_l4_abe_hwmod = { - .name = "l4_abe", - .class = &omap44xx_l4_hwmod_class, - .clkdm_name = "abe_clkdm", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET, - .context_offs = OMAP4_RM_ABE_AESS_CONTEXT_OFFSET, - .lostcontext_mask = OMAP4430_LOSTMEM_AESSMEM_MASK, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, - }, - }, -}; - /* l4_cfg */ static struct omap_hwmod omap44xx_l4_cfg_hwmod = { .name = "l4_cfg", @@ -771,22 +756,6 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_3 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* l3_main_1 -> l4_abe */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_abe = { - .master = &omap44xx_l3_main_1_hwmod, - .slave = &omap44xx_l4_abe_hwmod, - .clk = "l3_div_ck", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* mpu -> l4_abe */ -static struct omap_hwmod_ocp_if omap44xx_mpu__l4_abe = { - .master = &omap44xx_mpu_hwmod, - .slave = &omap44xx_l4_abe_hwmod, - .clk = "ocp_abe_iclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l3_main_1 -> l4_cfg */ static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_cfg = { .master = &omap44xx_l3_main_1_hwmod, @@ -988,8 +957,6 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l3_main_1__l3_main_3, &omap44xx_l3_main_2__l3_main_3, &omap44xx_l4_cfg__l3_main_3, - &omap44xx_l3_main_1__l4_abe, - &omap44xx_mpu__l4_abe, &omap44xx_l3_main_1__l4_cfg, &omap44xx_l3_main_2__l4_per, &omap44xx_l4_cfg__l4_wkup, diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c index 7c38c1ba58ac..85b9ab4756ed 100644 --- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c @@ -2,7 +2,7 @@ /* * Hardware modules present on the OMAP54xx chips * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com * * Paul Walmsley * Benoit Cousson @@ -121,19 +121,6 @@ static struct omap_hwmod_class omap54xx_l4_hwmod_class = { .name = "l4", }; -/* l4_abe */ -static struct omap_hwmod omap54xx_l4_abe_hwmod = { - .name = "l4_abe", - .class = &omap54xx_l4_hwmod_class, - .clkdm_name = "abe_clkdm", - .prcm = { - .omap4 = { - .clkctrl_offs = OMAP54XX_CM_ABE_L4_ABE_CLKCTRL_OFFSET, - .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT, - }, - }, -}; - /* l4_cfg */ static struct omap_hwmod omap54xx_l4_cfg_hwmod = { .name = "l4_cfg", @@ -395,22 +382,6 @@ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_3 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* l3_main_1 -> l4_abe */ -static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l4_abe = { - .master = &omap54xx_l3_main_1_hwmod, - .slave = &omap54xx_l4_abe_hwmod, - .clk = "abe_iclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - -/* mpu -> l4_abe */ -static struct omap_hwmod_ocp_if omap54xx_mpu__l4_abe = { - .master = &omap54xx_mpu_hwmod, - .slave = &omap54xx_l4_abe_hwmod, - .clk = "abe_iclk", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l3_main_1 -> l4_cfg */ static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l4_cfg = { .master = &omap54xx_l3_main_1_hwmod, @@ -478,8 +449,6 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = { &omap54xx_l3_main_1__l3_main_3, &omap54xx_l3_main_2__l3_main_3, &omap54xx_l4_cfg__l3_main_3, - &omap54xx_l3_main_1__l4_abe, - &omap54xx_mpu__l4_abe, &omap54xx_l3_main_1__l4_cfg, &omap54xx_l3_main_2__l4_per, &omap54xx_l3_main_1__l4_wkup, diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index adb07848de96..05e163c8337a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -2,7 +2,7 @@ /* * Hardware modules present on the DRA7xx chips * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com * * Paul Walmsley * Benoit Cousson @@ -419,41 +419,6 @@ static struct omap_hwmod dra7xx_qspi_hwmod = { }; /* - * 'rtcss' class - * - */ -static struct omap_hwmod_class_sysconfig dra7xx_rtcss_sysc = { - .rev_offs = 0x0074, - .sysc_offs = 0x0078, - .sysc_flags = SYSC_HAS_SIDLEMODE, - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), - .sysc_fields = &omap_hwmod_sysc_type3, -}; - -static struct omap_hwmod_class dra7xx_rtcss_hwmod_class = { - .name = "rtcss", - .sysc = &dra7xx_rtcss_sysc, - .unlock = &omap_hwmod_rtc_unlock, - .lock = &omap_hwmod_rtc_lock, -}; - -/* rtcss */ -static struct omap_hwmod dra7xx_rtcss_hwmod = { - .name = "rtcss", - .class = &dra7xx_rtcss_hwmod_class, - .clkdm_name = "rtc_clkdm", - .main_clk = "sys_32k_ck", - .prcm = { - .omap4 = { - .clkctrl_offs = DRA7XX_CM_RTC_RTCSS_CLKCTRL_OFFSET, - .context_offs = DRA7XX_RM_RTC_RTCSS_CONTEXT_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - -/* * 'sata' class * */ @@ -702,14 +667,6 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__qspi = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -/* l4_per3 -> rtcss */ -static struct omap_hwmod_ocp_if dra7xx_l4_per3__rtcss = { - .master = &dra7xx_l4_per3_hwmod, - .slave = &dra7xx_rtcss_hwmod, - .clk = "l4_root_clk_div", - .user = OCP_USER_MPU | OCP_USER_SDMA, -}; - /* l4_cfg -> sata */ static struct omap_hwmod_ocp_if dra7xx_l4_cfg__sata = { .master = &dra7xx_l4_cfg_hwmod, @@ -786,7 +743,6 @@ static struct omap_hwmod_ocp_if *dra72x_hwmod_ocp_ifs[] __initdata = { }; static struct omap_hwmod_ocp_if *rtc_hwmod_ocp_ifs[] __initdata = { - &dra7xx_l4_per3__rtcss, NULL, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c index 50fb699b163f..450ab990c66a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c @@ -1,7 +1,7 @@ /* * DM81xx hwmod data. * - * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ + * Copyright (C) 2010 Texas Instruments, Inc. - https://www.ti.com/ * Copyright (C) 2013 SKTB SKiT, http://www.skitlab.ru/ * * This program is free software; you can redistribute it and/or diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-omap2/omap_opp_data.h index 336fdfcf88bb..533dd643069a 100644 --- a/arch/arm/mach-omap2/omap_opp_data.h +++ b/arch/arm/mach-omap2/omap_opp_data.h @@ -1,7 +1,7 @@ /* * OMAP SoC specific OPP Data helpers * - * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2009-2010 Texas Instruments Incorporated - https://www.ti.com/ * Nishanth Menon * Kevin Hilman * Copyright (C) 2010 Nokia Corporation. diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c index d2925e8b2eff..6f6a6a66c981 100644 --- a/arch/arm/mach-omap2/omap_phy_internal.c +++ b/arch/arm/mach-omap2/omap_phy_internal.c @@ -3,7 +3,7 @@ * This file configures the internal USB PHY in OMAP4430. Used * with TWL6030 transceiver and MUSB on OMAP4430. * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com * Author: Hema HK <hemahk@ti.com> */ diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c index c2d459f5b0da..b610c5fb423b 100644 --- a/arch/arm/mach-omap2/opp3xxx_data.c +++ b/arch/arm/mach-omap2/opp3xxx_data.c @@ -1,7 +1,7 @@ /* * OMAP3 OPP table definitions. * - * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2009-2010 Texas Instruments Incorporated - https://www.ti.com/ * Nishanth Menon * Kevin Hilman * Copyright (C) 2010-2011 Nokia Corporation. diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c index 985aeab9bc2a..d937c5ef41c6 100644 --- a/arch/arm/mach-omap2/opp4xxx_data.c +++ b/arch/arm/mach-omap2/opp4xxx_data.c @@ -1,7 +1,7 @@ /* * OMAP4 OPP table definitions. * - * Copyright (C) 2010-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2010-2012 Texas Instruments Incorporated - https://www.ti.com/ * Nishanth Menon * Kevin Hilman * Thara Gopinath diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index fceb1e525d26..919d35d5b325 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -34,8 +34,6 @@ #include "prm2xxx_3xxx.h" #include "pm.h" -u32 enable_off_mode; - #ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> #include <linux/seq_file.h> diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 01ec1ba4878b..da829a90fe8c 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -28,6 +28,8 @@ #include "clockdomain.h" #include "pm.h" +u32 enable_off_mode; + #ifdef CONFIG_SUSPEND /* * omap_pm_suspend: points to a function that does the SoC-specific diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 2a883a0c1fcd..80e84ae66aee 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -49,11 +49,7 @@ static inline int omap4_opp_init(void) extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); -#ifdef CONFIG_PM_DEBUG extern u32 enable_off_mode; -#else -#define enable_off_mode 0 -#endif #if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev); diff --git a/arch/arm/mach-omap2/pm33xx-core.c b/arch/arm/mach-omap2/pm33xx-core.c index 58236c7dc83e..56f2c0bcae5a 100644 --- a/arch/arm/mach-omap2/pm33xx-core.c +++ b/arch/arm/mach-omap2/pm33xx-core.c @@ -2,7 +2,7 @@ /* * AM33XX Arch Power Management Routines * - * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2016-2018 Texas Instruments Incorporated - https://www.ti.com/ * Dave Gerlach */ @@ -25,7 +25,6 @@ #include "control.h" #include "clockdomain.h" #include "iomap.h" -#include "omap_hwmod.h" #include "pm.h" #include "powerdomain.h" #include "prm33xx.h" @@ -36,7 +35,6 @@ static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm; static struct clockdomain *gfx_l4ls_clkdm; static void __iomem *scu_base; -static struct omap_hwmod *rtc_oh; static int (*idle_fn)(u32 wfi_flags); @@ -267,13 +265,6 @@ static struct am33xx_pm_sram_addr *amx3_get_sram_addrs(void) return NULL; } -static void __iomem *am43xx_get_rtc_base_addr(void) -{ - rtc_oh = omap_hwmod_lookup("rtc"); - - return omap_hwmod_get_mpu_rt_va(rtc_oh); -} - static void am43xx_save_context(void) { } @@ -297,16 +288,6 @@ static void am43xx_restore_context(void) writel_relaxed(0x0, AM33XX_L4_WK_IO_ADDRESS(0x44df2e14)); } -static void am43xx_prepare_rtc_suspend(void) -{ - omap_hwmod_enable(rtc_oh); -} - -static void am43xx_prepare_rtc_resume(void) -{ - omap_hwmod_idle(rtc_oh); -} - static struct am33xx_pm_platform_data am33xx_ops = { .init = am33xx_suspend_init, .deinit = amx3_suspend_deinit, @@ -317,10 +298,7 @@ static struct am33xx_pm_platform_data am33xx_ops = { .get_sram_addrs = amx3_get_sram_addrs, .save_context = am33xx_save_context, .restore_context = am33xx_restore_context, - .prepare_rtc_suspend = am43xx_prepare_rtc_suspend, - .prepare_rtc_resume = am43xx_prepare_rtc_resume, .check_off_mode_enable = am33xx_check_off_mode_enable, - .get_rtc_base_addr = am43xx_get_rtc_base_addr, }; static struct am33xx_pm_platform_data am43xx_ops = { @@ -333,10 +311,7 @@ static struct am33xx_pm_platform_data am43xx_ops = { .get_sram_addrs = amx3_get_sram_addrs, .save_context = am43xx_save_context, .restore_context = am43xx_restore_context, - .prepare_rtc_suspend = am43xx_prepare_rtc_suspend, - .prepare_rtc_resume = am43xx_prepare_rtc_resume, .check_off_mode_enable = am43xx_check_off_mode_enable, - .get_rtc_base_addr = am43xx_get_rtc_base_addr, }; static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index f5dfddf492e2..71c1d18aafbc 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -25,6 +25,7 @@ #include <linux/clk.h> #include <linux/delay.h> #include <linux/slab.h> +#include <linux/of.h> #include <linux/omap-gpmc.h> #include <trace/events/power.h> @@ -410,7 +411,12 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) if (!pwrst) return -ENOMEM; pwrst->pwrdm = pwrdm; - pwrst->next_state = PWRDM_POWER_RET; + + if (enable_off_mode) + pwrst->next_state = PWRDM_POWER_OFF; + else + pwrst->next_state = PWRDM_POWER_RET; + list_add(&pwrst->node, &pwrst_list); if (pwrdm_has_hdwr_sar(pwrdm)) @@ -444,6 +450,22 @@ static void __init pm_errata_configure(void) } } +static void __init omap3_pm_check_pmic(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "ti,twl4030-power-idle"); + if (!np) + np = of_find_compatible_node(NULL, NULL, "ti,twl4030-power-idle-osc-off"); + + if (np) { + of_node_put(np); + enable_off_mode = 1; + } else { + enable_off_mode = 0; + } +} + int __init omap3_pm_init(void) { struct power_state *pwrst, *tmp; @@ -477,6 +499,8 @@ int __init omap3_pm_init(void) goto err2; } + omap3_pm_check_pmic(); + ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { pr_err("Failed to setup powerdomains\n"); diff --git a/arch/arm/mach-omap2/powerdomains33xx_data.c b/arch/arm/mach-omap2/powerdomains33xx_data.c index 869adb82569e..626055e59aed 100644 --- a/arch/arm/mach-omap2/powerdomains33xx_data.c +++ b/arch/arm/mach-omap2/powerdomains33xx_data.c @@ -1,7 +1,7 @@ /* * AM33XX Power domain data * - * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2011-2012 Texas Instruments Incorporated - https://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/arch/arm/mach-omap2/prcm43xx.h b/arch/arm/mach-omap2/prcm43xx.h index 7078a61c1d3f..899da0ae9800 100644 --- a/arch/arm/mach-omap2/prcm43xx.h +++ b/arch/arm/mach-omap2/prcm43xx.h @@ -1,7 +1,7 @@ /* * AM43x PRCM defines * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com/ * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any diff --git a/arch/arm/mach-omap2/prcm_mpu54xx.h b/arch/arm/mach-omap2/prcm_mpu54xx.h index 6ef38829c064..bdbfa070b08e 100644 --- a/arch/arm/mach-omap2/prcm_mpu54xx.h +++ b/arch/arm/mach-omap2/prcm_mpu54xx.h @@ -2,7 +2,7 @@ /* * OMAP54xx PRCM MPU instance offset macros * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com * * Paul Walmsley (paul@pwsan.com) * Rajendra Nayak (rnayak@ti.com) diff --git a/arch/arm/mach-omap2/prcm_mpu7xx.h b/arch/arm/mach-omap2/prcm_mpu7xx.h index 33d0013aa1d4..2e3032440ea0 100644 --- a/arch/arm/mach-omap2/prcm_mpu7xx.h +++ b/arch/arm/mach-omap2/prcm_mpu7xx.h @@ -2,7 +2,7 @@ /* * DRA7xx PRCM MPU instance offset macros * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com * * Generated by code originally written by: * Paul Walmsley (paul@pwsan.com) diff --git a/arch/arm/mach-omap2/prm-regbits-33xx.h b/arch/arm/mach-omap2/prm-regbits-33xx.h index 84feecee4fe6..7dfdff09ddeb 100644 --- a/arch/arm/mach-omap2/prm-regbits-33xx.h +++ b/arch/arm/mach-omap2/prm-regbits-33xx.h @@ -1,7 +1,7 @@ /* * AM33XX PRM_XXX register bits * - * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2011-2012 Texas Instruments Incorporated - https://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c index d5141669c28d..9144cc0479af 100644 --- a/arch/arm/mach-omap2/prm33xx.c +++ b/arch/arm/mach-omap2/prm33xx.c @@ -1,7 +1,7 @@ /* * AM33XX PRM functions * - * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2011-2012 Texas Instruments Incorporated - https://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h index 66302c6aba61..d0b7404565f1 100644 --- a/arch/arm/mach-omap2/prm33xx.h +++ b/arch/arm/mach-omap2/prm33xx.h @@ -1,7 +1,7 @@ /* * AM33XX PRM instance offset macros * - * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2011-2012 Texas Instruments Incorporated - https://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/arch/arm/mach-omap2/prm54xx.h b/arch/arm/mach-omap2/prm54xx.h index ee0f1cc92e3a..7329d6fcd78b 100644 --- a/arch/arm/mach-omap2/prm54xx.h +++ b/arch/arm/mach-omap2/prm54xx.h @@ -2,7 +2,7 @@ /* * OMAP54xx PRM instance offset macros * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com * * Paul Walmsley (paul@pwsan.com) * Rajendra Nayak (rnayak@ti.com) diff --git a/arch/arm/mach-omap2/prm7xx.h b/arch/arm/mach-omap2/prm7xx.h index cf99307d1b1f..e5aee0409eae 100644 --- a/arch/arm/mach-omap2/prm7xx.h +++ b/arch/arm/mach-omap2/prm7xx.h @@ -2,7 +2,7 @@ /* * DRA7xx PRM instance offset macros * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com * * Generated by code originally written by: * Paul Walmsley (paul@pwsan.com) diff --git a/arch/arm/mach-omap2/scrm54xx.h b/arch/arm/mach-omap2/scrm54xx.h index 810d2b186337..cb6f3e6a7095 100644 --- a/arch/arm/mach-omap2/scrm54xx.h +++ b/arch/arm/mach-omap2/scrm54xx.h @@ -2,7 +2,7 @@ /* * OMAP54XX SCRM registers and bitfields * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com * * Benoit Cousson (b-cousson@ti.com) * diff --git a/arch/arm/mach-omap2/sleep33xx.S b/arch/arm/mach-omap2/sleep33xx.S index dc221249bc22..ac3d0b363c51 100644 --- a/arch/arm/mach-omap2/sleep33xx.S +++ b/arch/arm/mach-omap2/sleep33xx.S @@ -2,7 +2,7 @@ /* * Low level suspend code for AM33XX SoCs * - * Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2012-2018 Texas Instruments Incorporated - https://www.ti.com/ * Dave Gerlach, Vaibhav Bedia */ diff --git a/arch/arm/mach-omap2/sleep43xx.S b/arch/arm/mach-omap2/sleep43xx.S index 90d2907a2eb2..832c91327945 100644 --- a/arch/arm/mach-omap2/sleep43xx.S +++ b/arch/arm/mach-omap2/sleep43xx.S @@ -2,7 +2,7 @@ /* * Low level suspend code for AM43XX SoCs * - * Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2013-2018 Texas Instruments Incorporated - https://www.ti.com/ * Dave Gerlach, Vaibhav Bedia */ diff --git a/arch/arm/mach-omap2/ti81xx.h b/arch/arm/mach-omap2/ti81xx.h index a1e6caf0dba6..192b0e7d3eb4 100644 --- a/arch/arm/mach-omap2/ti81xx.h +++ b/arch/arm/mach-omap2/ti81xx.h @@ -1,7 +1,7 @@ /* * This file contains the address data for various TI81XX modules. * - * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ + * Copyright (C) 2010 Texas Instruments, Inc. - https://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/arch/arm/mach-omap2/voltagedomains54xx_data.c b/arch/arm/mach-omap2/voltagedomains54xx_data.c index aac274d6a93b..e60d76db0f21 100644 --- a/arch/arm/mach-omap2/voltagedomains54xx_data.c +++ b/arch/arm/mach-omap2/voltagedomains54xx_data.c @@ -4,7 +4,7 @@ * * Based on voltagedomains44xx_data.c * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com */ #include <linux/kernel.h> #include <linux/err.h> diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 3d2c108e911e..431709725d02 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -369,6 +369,15 @@ static struct pxaficp_platform_data tosa_ficp_platform_data = { /* * Tosa AC IN */ +static struct gpiod_lookup_table tosa_power_gpiod_table = { + .dev_id = "gpio-charger", + .table = { + GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_AC_IN, + NULL, GPIO_ACTIVE_LOW), + { }, + }, +}; + static char *tosa_ac_supplied_to[] = { "main-battery", "backup-battery", @@ -378,8 +387,6 @@ static char *tosa_ac_supplied_to[] = { static struct gpio_charger_platform_data tosa_power_data = { .name = "charger", .type = POWER_SUPPLY_TYPE_MAINS, - .gpio = TOSA_GPIO_AC_IN, - .gpio_active_low = 1, .supplied_to = tosa_ac_supplied_to, .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to), }; @@ -951,6 +958,7 @@ static void __init tosa_init(void) clk_add_alias("CLK_CK3P6MI", tc6393xb_device.name, "GPIO11_CLK", NULL); gpiod_add_lookup_table(&tosa_udc_gpiod_table); + gpiod_add_lookup_table(&tosa_power_gpiod_table); platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/mach-s3c/Kconfig index 301e572651c0..25606e668cf9 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/mach-s3c/Kconfig @@ -2,12 +2,16 @@ # # Copyright 2009 Simtec Electronics +source "arch/arm/mach-s3c/Kconfig.s3c24xx" +source "arch/arm/mach-s3c/Kconfig.s3c64xx" + config PLAT_SAMSUNG bool - depends on PLAT_S3C24XX || ARCH_S3C64XX || ARCH_EXYNOS || ARCH_S5PV210 + depends on PLAT_S3C24XX || ARCH_S3C64XX default y select GENERIC_IRQ_CHIP select NO_IOPORT_MAP + select SOC_SAMSUNG help Base platform code for all Samsung SoC based systems @@ -154,7 +158,7 @@ config S3C_DEV_WDT bool default y if ARCH_S3C24XX help - Complie in platform device definition for Watchdog Timer + Compile in platform device definition for Watchdog Timer config S3C_DEV_NAND bool @@ -169,7 +173,7 @@ config S3C_DEV_ONENAND config S3C_DEV_RTC bool help - Complie in platform device definition for RTC + Compile in platform device definition for RTC config SAMSUNG_DEV_ADC bool @@ -234,54 +238,6 @@ config SAMSUNG_PM_GPIO pinctrl-samsung driver. endif -comment "Power management" - -config SAMSUNG_PM_DEBUG - bool "Samsung PM Suspend debug" - depends on PM && DEBUG_KERNEL - depends on PLAT_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210 - depends on DEBUG_EXYNOS_UART || DEBUG_S3C24XX_UART || DEBUG_S3C2410_UART - help - Say Y here if you want verbose debugging from the PM Suspend and - Resume code. See <file:Documentation/arm/samsung-s3c24xx/suspend.rst> - for more information. - -config S3C_PM_DEBUG_LED_SMDK - bool "SMDK LED suspend/resume debugging" - depends on PM && (MACH_SMDK6410) - help - Say Y here to enable the use of the SMDK LEDs on the baseboard - for debugging of the state of the suspend and resume process. - - Note, this currently only works for S3C64XX based SMDK boards. - -config SAMSUNG_PM_CHECK - bool "S3C2410 PM Suspend Memory CRC" - depends on PM && (PLAT_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210) - select CRC32 - help - Enable the PM code's memory area checksum over sleep. This option - will generate CRCs of all blocks of memory, and store them before - going to sleep. The blocks are then checked on resume for any - errors. - - Note, this can take several seconds depending on memory size - and CPU speed. - - See <file:Documentation/arm/samsung-s3c24xx/suspend.rst> - -config SAMSUNG_PM_CHECK_CHUNKSIZE - int "S3C2410 PM Suspend CRC Chunksize (KiB)" - depends on PM && SAMSUNG_PM_CHECK - default 64 - help - Set the chunksize in Kilobytes of the CRC for checking memory - corruption over suspend and resume. A smaller value will mean that - the CRC data block will take more memory, but will identify any - faults with better precision. - - See <file:Documentation/arm/samsung-s3c24xx/suspend.rst> - config SAMSUNG_WAKEMASK bool depends on PM @@ -290,19 +246,5 @@ config SAMSUNG_WAKEMASK and above. This code allows a set of interrupt to wakeup-mask mappings. See <plat/wakeup-mask.h> -config SAMSUNG_WDT_RESET - bool - help - Compile support for system restart by triggering watchdog reset. - Used on SoCs that do not provide dedicated reset control. - -config DEBUG_S3C_UART - depends on PLAT_SAMSUNG - int - default "0" if DEBUG_S3C_UART0 - default "1" if DEBUG_S3C_UART1 - default "2" if DEBUG_S3C_UART2 - default "3" if DEBUG_S3C_UART3 - endmenu endif diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c/Kconfig.s3c24xx index 7673dde9671a..000e3e234f71 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c/Kconfig.s3c24xx @@ -123,11 +123,6 @@ config S3C24XX_PLL This also means that the PLL tables for the selected CPU(s) will be built which may increase the size of the kernel image. -config S3C_SETUP_CAMIF - bool - help - Compile in common setup code for S3C CAMIF devices - # cpu frequency items common between s3c2410 and s3c2440/s3c2442 config S3C2410_IOTIMING @@ -137,13 +132,6 @@ config S3C2410_IOTIMING Internal node to select io timing code that is common to the s3c2410 and s3c2440/s3c2442 cpu frequency support. -config S3C2410_CPUFREQ_UTILS - bool - depends on ARM_S3C24XX_CPUFREQ - help - Internal node to select timing code that is common to the s3c2410 - and s3c2440/s3c244 cpu frequency support. - # cpu frequency support common to s3c2412, s3c2413 and s3c2442 config S3C2412_IOTIMING @@ -468,7 +456,6 @@ config MACH_MINI2440 select NEW_LEDS select S3C_DEV_NAND select S3C_DEV_USB_HOST - select S3C_SETUP_CAMIF help Say Y here to select support for the MINI2440. Is a 10cm x 10cm board available via various sources. It can come with a 3.5" or 7" touch LCD. diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c/Kconfig.s3c64xx index ac3e3563487f..f3fcb570edf5 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c/Kconfig.s3c64xx @@ -13,15 +13,15 @@ menuconfig ARCH_S3C64XX select GPIO_SAMSUNG if ATAGS select GPIOLIB select HAVE_S3C2410_I2C if I2C - select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_TCM select PLAT_SAMSUNG select PM_GENERIC_DOMAINS if PM select S3C_DEV_NAND if ATAGS select S3C_GPIO_TRACK if ATAGS + select S3C2410_WATCHDOG select SAMSUNG_ATAGS if ATAGS select SAMSUNG_WAKEMASK if PM - select SAMSUNG_WDT_RESET + select WATCHDOG help Samsung S3C64XX series based systems @@ -165,7 +165,6 @@ config MACH_SMDK6410 bool "SMDK6410" depends on ATAGS select CPU_S3C6410 - select HAVE_S3C2410_WATCHDOG if WATCHDOG select S3C64XX_SETUP_FB_24BPP select S3C64XX_SETUP_I2C1 select S3C64XX_SETUP_IDE diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/mach-s3c/Makefile index 3db9d2c38258..54188d10ab2e 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/mach-s3c/Makefile @@ -2,9 +2,16 @@ # # Copyright 2009 Simtec Electronics -ccflags-$(CONFIG_ARCH_S3C64XX) := -I$(srctree)/arch/arm/mach-s3c64xx/include ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include +ifdef CONFIG_ARCH_S3C24XX +include $(src)/Makefile.s3c24xx +endif + +ifdef CONFIG_ARCH_S3C64XX +include $(src)/Makefile.s3c64xx +endif + # Objects we always build independent of SoC choice obj-y += init.o cpu.o @@ -24,12 +31,7 @@ obj-$(CONFIG_GPIO_SAMSUNG) += gpio-samsung.o # PM support -obj-$(CONFIG_PM_SLEEP) += pm-common.o -obj-$(CONFIG_EXYNOS_CPU_SUSPEND) += pm-common.o -obj-$(CONFIG_SAMSUNG_PM) += pm.o +obj-$(CONFIG_SAMSUNG_PM) += pm.o pm-common.o obj-$(CONFIG_SAMSUNG_PM_GPIO) += pm-gpio.o -obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o -obj-$(CONFIG_SAMSUNG_PM_DEBUG) += pm-debug.o obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o -obj-$(CONFIG_SAMSUNG_WDT_RESET) += watchdog-reset.o diff --git a/arch/arm/mach-s3c24xx/Makefile.boot b/arch/arm/mach-s3c/Makefile.boot index 7f19e226035e..7f19e226035e 100644 --- a/arch/arm/mach-s3c24xx/Makefile.boot +++ b/arch/arm/mach-s3c/Makefile.boot diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c/Makefile.s3c24xx index 6692f2de71b2..3483ab3a2b81 100644 --- a/arch/arm/mach-s3c24xx/Makefile +++ b/arch/arm/mach-s3c/Makefile.s3c24xx @@ -7,7 +7,10 @@ # core -obj-y += common.o +obj-y += s3c24xx.o +obj-y += irq-s3c24xx.o +obj-$(CONFIG_SPI_S3C24XX_FIQ) += irq-s3c24xx-fiq.o +obj-$(CONFIG_SPI_S3C24XX_FIQ) += irq-s3c24xx-fiq-exports.o obj-$(CONFIG_CPU_S3C2410) += s3c2410.o obj-$(CONFIG_S3C2410_PLL) += pll-s3c2410.o @@ -30,12 +33,12 @@ obj-$(CONFIG_CPU_S3C2443) += s3c2443.o # PM -obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_PM_SLEEP) += irq-pm.o sleep.o +obj-$(CONFIG_PM) += pm-s3c24xx.o +obj-$(CONFIG_PM_SLEEP) += irq-pm-s3c24xx.o sleep-s3c24xx.o # common code -obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += cpufreq-utils.o +obj-$(CONFIG_ARM_S3C24XX_CPUFREQ) += cpufreq-utils-s3c24xx.o obj-$(CONFIG_S3C2410_IOTIMING) += iotiming-s3c2410.o obj-$(CONFIG_S3C2412_IOTIMING) += iotiming-s3c2412.o @@ -80,7 +83,7 @@ obj-$(CONFIG_MACH_SMDK2443) += mach-smdk2443.o # common bits of machine support -obj-$(CONFIG_S3C24XX_SMDK) += common-smdk.o +obj-$(CONFIG_S3C24XX_SMDK) += common-smdk-s3c24xx.o obj-$(CONFIG_S3C24XX_SIMTEC_AUDIO) += simtec-audio.o obj-$(CONFIG_S3C24XX_SIMTEC_NOR) += simtec-nor.o obj-$(CONFIG_S3C24XX_SIMTEC_PM) += simtec-pm.o @@ -93,8 +96,7 @@ obj-$(CONFIG_MACH_OSIRIS_DVS) += mach-osiris-dvs.o # device setup -obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o -obj-$(CONFIG_S3C2443_SETUP_SPI) += setup-spi.o -obj-$(CONFIG_ARCH_S3C24XX) += setup-i2c.o -obj-$(CONFIG_S3C24XX_SETUP_TS) += setup-ts.o -obj-$(CONFIG_S3C_SETUP_CAMIF) += setup-camif.o +obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio-s3c24xx.o +obj-$(CONFIG_S3C2443_SETUP_SPI) += setup-spi-s3c24xx.o +obj-$(CONFIG_ARCH_S3C24XX) += setup-i2c-s3c24xx.o +obj-$(CONFIG_S3C24XX_SETUP_TS) += setup-ts-s3c24xx.o diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c/Makefile.s3c64xx index 8caeb4ad17e9..0c18e31936df 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c/Makefile.s3c64xx @@ -3,22 +3,22 @@ # Copyright 2008 Openmoko, Inc. # Copyright 2008 Simtec Electronics -ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include -I$(srctree)/arch/arm/plat-samsung/include -asflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include -I$(srctree)/arch/arm/plat-samsung/include +ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include +asflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include # PM -obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_PM_SLEEP) += sleep.o -obj-$(CONFIG_CPU_IDLE) += cpuidle.o +obj-$(CONFIG_PM) += pm-s3c64xx.o +obj-$(CONFIG_PM_SLEEP) += sleep-s3c64xx.o +obj-$(CONFIG_CPU_IDLE) += cpuidle-s3c64xx.o ifdef CONFIG_SAMSUNG_ATAGS -obj-$(CONFIG_PM_SLEEP) += irq-pm.o +obj-$(CONFIG_PM_SLEEP) += irq-pm-s3c64xx.o # Core -obj-y += common.o +obj-y += s3c64xx.o obj-$(CONFIG_CPU_S3C6400) += s3c6400.o obj-$(CONFIG_CPU_S3C6410) += s3c6410.o @@ -28,21 +28,21 @@ obj-$(CONFIG_S3C64XX_PL080) += pl080.o # Device support -obj-y += dev-uart.o -obj-y += dev-audio.o +obj-y += dev-uart-s3c64xx.o +obj-y += dev-audio-s3c64xx.o # Device setup -obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o -obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o -obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o -obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o -obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o -obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o -obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o -obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy.o +obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi-s3c64xx.o +obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy-s3c64xx.o -obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o +obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight-s3c64xx.o # Machine support diff --git a/arch/arm/plat-samsung/include/plat/adc-core.h b/arch/arm/mach-s3c/adc-core.h index 039f6862b6a7..039f6862b6a7 100644 --- a/arch/arm/plat-samsung/include/plat/adc-core.h +++ b/arch/arm/mach-s3c/adc-core.h diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/mach-s3c/adc.c index 55b1925f65d7..0232520d3c13 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/mach-s3c/adc.c @@ -19,8 +19,8 @@ #include <linux/io.h> #include <linux/regulator/consumer.h> -#include <plat/regs-adc.h> -#include <plat/adc.h> +#include "regs-adc.h" +#include <linux/soc/samsung/s3c-adc.h> /* This driver is designed to control the usage of the ADC block between * the touchscreen and any other drivers that may need to use it, such as diff --git a/arch/arm/mach-s3c24xx/anubis.h b/arch/arm/mach-s3c/anubis.h index 13847292e6c7..13847292e6c7 100644 --- a/arch/arm/mach-s3c24xx/anubis.h +++ b/arch/arm/mach-s3c/anubis.h diff --git a/arch/arm/mach-s3c64xx/ata-core.h b/arch/arm/mach-s3c/ata-core-s3c64xx.h index 6d9a81f759e6..4863ad9d3a42 100644 --- a/arch/arm/mach-s3c64xx/ata-core.h +++ b/arch/arm/mach-s3c/ata-core-s3c64xx.h @@ -6,8 +6,8 @@ * Samsung CF-ATA Controller core functions */ -#ifndef __ASM_PLAT_ATA_CORE_H -#define __ASM_PLAT_ATA_CORE_H __FILE__ +#ifndef __ASM_PLAT_ATA_CORE_S3C64XX_H +#define __ASM_PLAT_ATA_CORE_S3C64XX_H __FILE__ /* These functions are only for use with the core support code, such as * the cpu specific initialisation code @@ -21,4 +21,4 @@ static inline void s3c_cfcon_setname(char *name) #endif } -#endif /* __ASM_PLAT_ATA_CORE_H */ +#endif /* __ASM_PLAT_ATA_CORE_S3C64XX_H */ diff --git a/arch/arm/mach-s3c64xx/backlight.h b/arch/arm/mach-s3c/backlight-s3c64xx.h index 028663f1cacc..2a2b35821d58 100644 --- a/arch/arm/mach-s3c64xx/backlight.h +++ b/arch/arm/mach-s3c/backlight-s3c64xx.h @@ -4,8 +4,8 @@ * http://www.samsung.com */ -#ifndef __ASM_PLAT_BACKLIGHT_H -#define __ASM_PLAT_BACKLIGHT_H __FILE__ +#ifndef __ASM_PLAT_BACKLIGHT_S3C64XX_H +#define __ASM_PLAT_BACKLIGHT_S3C64XX_H __FILE__ /* samsung_bl_gpio_info - GPIO info for PWM Backlight control * @no: GPIO number for PWM timer out @@ -19,4 +19,4 @@ struct samsung_bl_gpio_info { extern void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, struct platform_pwm_backlight_data *bl_data); -#endif /* __ASM_PLAT_BACKLIGHT_H */ +#endif /* __ASM_PLAT_BACKLIGHT_S3C64XX_H */ diff --git a/arch/arm/mach-s3c24xx/bast-ide.c b/arch/arm/mach-s3c/bast-ide.c index 067944398f46..da64db1811d8 100644 --- a/arch/arm/mach-s3c24xx/bast-ide.c +++ b/arch/arm/mach-s3c/bast-ide.c @@ -19,7 +19,8 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/map.h> +#include "map.h" +#include <mach/irqs.h> #include "bast.h" diff --git a/arch/arm/mach-s3c24xx/bast-irq.c b/arch/arm/mach-s3c/bast-irq.c index 03728058d58d..d299f124e6dc 100644 --- a/arch/arm/mach-s3c24xx/bast-irq.c +++ b/arch/arm/mach-s3c/bast-irq.c @@ -15,8 +15,8 @@ #include <asm/mach-types.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> -#include <mach/regs-irq.h> +#include "regs-irq.h" +#include <mach/irqs.h> #include "bast.h" @@ -62,7 +62,7 @@ bast_pc104_mask(struct irq_data *data) static void bast_pc104_maskack(struct irq_data *data) { - struct irq_desc *desc = irq_desc + BAST_IRQ_ISA; + struct irq_desc *desc = irq_to_desc(BAST_IRQ_ISA); bast_pc104_mask(data); desc->irq_data.chip->irq_ack(&desc->irq_data); @@ -94,8 +94,6 @@ static void bast_irq_pc104_demux(struct irq_desc *desc) if (unlikely(stat == 0)) { /* ack if we get an irq with nothing (ie, startup) */ - - desc = irq_desc + BAST_IRQ_ISA; desc->irq_data.chip->irq_ack(&desc->irq_data); } else { /* handle the IRQ */ diff --git a/arch/arm/mach-s3c24xx/bast.h b/arch/arm/mach-s3c/bast.h index a7726f93f5eb..a7726f93f5eb 100644 --- a/arch/arm/mach-s3c24xx/bast.h +++ b/arch/arm/mach-s3c/bast.h diff --git a/arch/arm/mach-s3c24xx/common-smdk.c b/arch/arm/mach-s3c/common-smdk-s3c24xx.c index 75064dfaceb1..f860d8bcba0e 100644 --- a/arch/arm/mach-s3c24xx/common-smdk.c +++ b/arch/arm/mach-s3c/common-smdk-s3c24xx.c @@ -29,19 +29,18 @@ #include <asm/mach/irq.h> #include <asm/mach-types.h> -#include <mach/hardware.h> #include <asm/irq.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" #include <linux/platform_data/leds-s3c24xx.h> #include <linux/platform_data/mtd-nand-s3c2410.h> -#include <plat/gpio-cfg.h> -#include <plat/devs.h> -#include <plat/pm.h> +#include "gpio-cfg.h" +#include "devs.h" +#include "pm.h" -#include "common-smdk.h" +#include "common-smdk-s3c24xx.h" /* LED devices */ @@ -191,7 +190,7 @@ static struct s3c2410_platform_nand smdk_nand_info = { .twrph1 = 20, .nr_sets = ARRAY_SIZE(smdk_nand_sets), .sets = smdk_nand_sets, - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; /* devices we initialise */ diff --git a/arch/arm/mach-s3c24xx/common-smdk.h b/arch/arm/mach-s3c/common-smdk-s3c24xx.h index c0352b06e435..c0352b06e435 100644 --- a/arch/arm/mach-s3c24xx/common-smdk.h +++ b/arch/arm/mach-s3c/common-smdk-s3c24xx.h diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/mach-s3c/cpu.c index e1ba88ba31d8..6e9772555f0d 100644 --- a/arch/arm/plat-samsung/cpu.c +++ b/arch/arm/mach-s3c/cpu.c @@ -10,17 +10,10 @@ #include <linux/init.h> #include <linux/io.h> -#include <plat/map-base.h> -#include <plat/cpu.h> +#include <mach/map-base.h> +#include "cpu.h" unsigned long samsung_cpu_id; -static unsigned int samsung_cpu_rev; - -unsigned int samsung_rev(void) -{ - return samsung_cpu_rev; -} -EXPORT_SYMBOL(samsung_rev); void __init s3c64xx_init_cpu(void) { @@ -34,15 +27,5 @@ void __init s3c64xx_init_cpu(void) samsung_cpu_id = readl_relaxed(S3C_VA_SYS + 0xA1C); } - samsung_cpu_rev = 0; - - pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id); -} - -void __init s5p_init_cpu(const void __iomem *cpuid_addr) -{ - samsung_cpu_id = readl_relaxed(cpuid_addr); - samsung_cpu_rev = samsung_cpu_id & 0xFF; - pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id); } diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/mach-s3c/cpu.h index fadcddbea064..20ff98d05c53 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/mach-s3c/cpu.h @@ -109,9 +109,6 @@ extern void s3c_init_cpu(unsigned long idcode, extern void s3c24xx_init_io(struct map_desc *mach_desc, int size); extern void s3c64xx_init_cpu(void); -extern void s5p_init_cpu(const void __iomem *cpuid_addr); - -extern unsigned int samsung_rev(void); extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no); @@ -126,15 +123,6 @@ extern struct syscore_ops s3c2412_pm_syscore_ops; extern struct syscore_ops s3c2416_pm_syscore_ops; extern struct syscore_ops s3c244x_pm_syscore_ops; -/* system device subsystems */ - -extern struct bus_type s3c2410_subsys; -extern struct bus_type s3c2410a_subsys; -extern struct bus_type s3c2412_subsys; -extern struct bus_type s3c2416_subsys; -extern struct bus_type s3c2440_subsys; -extern struct bus_type s3c2442_subsys; -extern struct bus_type s3c2443_subsys; extern struct bus_type s3c6410_subsys; #endif diff --git a/arch/arm/mach-s3c24xx/cpufreq-utils.c b/arch/arm/mach-s3c/cpufreq-utils-s3c24xx.c index 1a7f38d085dd..c1784d8facdf 100644 --- a/arch/arm/mach-s3c24xx/cpufreq-utils.c +++ b/arch/arm/mach-s3c/cpufreq-utils-s3c24xx.c @@ -12,12 +12,12 @@ #include <linux/io.h> #include <linux/clk.h> -#include <mach/map.h> -#include <mach/regs-clock.h> +#include "map.h" +#include "regs-clock.h" -#include <plat/cpu-freq-core.h> +#include <linux/soc/samsung/s3c-cpufreq-core.h> -#include "regs-mem.h" +#include "regs-mem-s3c24xx.h" /** * s3c2410_cpufreq_setrefresh - set SDRAM refresh value @@ -60,3 +60,35 @@ void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg) if (!IS_ERR(cfg->mpll)) clk_set_rate(cfg->mpll, cfg->pll.frequency); } + +#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442) +u32 s3c2440_read_camdivn(void) +{ + return __raw_readl(S3C2440_CAMDIVN); +} + +void s3c2440_write_camdivn(u32 camdiv) +{ + __raw_writel(camdiv, S3C2440_CAMDIVN); +} +#endif + +u32 s3c24xx_read_clkdivn(void) +{ + return __raw_readl(S3C2410_CLKDIVN); +} + +void s3c24xx_write_clkdivn(u32 clkdiv) +{ + __raw_writel(clkdiv, S3C2410_CLKDIVN); +} + +u32 s3c24xx_read_mpllcon(void) +{ + return __raw_readl(S3C2410_MPLLCON); +} + +void s3c24xx_write_locktime(u32 locktime) +{ + return __raw_writel(locktime, S3C2410_LOCKTIME); +} diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c/cpuidle-s3c64xx.c index 0bac6f6413b0..b1c5f43d4922 100644 --- a/arch/arm/mach-s3c64xx/cpuidle.c +++ b/arch/arm/mach-s3c/cpuidle-s3c64xx.c @@ -13,11 +13,11 @@ #include <asm/cpuidle.h> -#include <plat/cpu.h> -#include <mach/map.h> +#include "cpu.h" +#include "map.h" -#include "regs-sys.h" -#include "regs-syscon-power.h" +#include "regs-sys-s3c64xx.h" +#include "regs-syscon-power-s3c64xx.h" static int s3c64xx_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, diff --git a/arch/arm/mach-s3c64xx/crag6410.h b/arch/arm/mach-s3c/crag6410.h index 00d9aa114aa7..f39ea2ca7a75 100644 --- a/arch/arm/mach-s3c64xx/crag6410.h +++ b/arch/arm/mach-s3c/crag6410.h @@ -8,7 +8,7 @@ #ifndef MACH_CRAG6410_H #define MACH_CRAG6410_H -#include <mach/gpio-samsung.h> +#include "gpio-samsung.h" #define GLENFARCLAS_PMIC_IRQ_BASE IRQ_BOARD_START #define BANFF_PMIC_IRQ_BASE (IRQ_BOARD_START + 64) diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c/dev-audio-s3c64xx.c index e3c49b5d1355..fc2f077afd24 100644 --- a/arch/arm/mach-s3c64xx/dev-audio.c +++ b/arch/arm/mach-s3c/dev-audio-s3c64xx.c @@ -11,13 +11,12 @@ #include <linux/export.h> #include <mach/irqs.h> -#include <mach/map.h> -#include <mach/dma.h> +#include "map.h" -#include <plat/devs.h> +#include "devs.h" #include <linux/platform_data/asoc-s3c.h> -#include <plat/gpio-cfg.h> -#include <mach/gpio-samsung.h> +#include "gpio-cfg.h" +#include "gpio-samsung.h" static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev) { diff --git a/arch/arm/mach-s3c64xx/dev-backlight.c b/arch/arm/mach-s3c/dev-backlight-s3c64xx.c index 09e6da305f60..65488b61e50c 100644 --- a/arch/arm/mach-s3c64xx/dev-backlight.c +++ b/arch/arm/mach-s3c/dev-backlight-s3c64xx.c @@ -11,10 +11,10 @@ #include <linux/io.h> #include <linux/pwm_backlight.h> -#include <plat/devs.h> -#include <plat/gpio-cfg.h> +#include "devs.h" +#include "gpio-cfg.h" -#include "backlight.h" +#include "backlight-s3c64xx.h" struct samsung_bl_drvdata { struct platform_pwm_backlight_data plat_data; diff --git a/arch/arm/mach-s3c64xx/dev-uart.c b/arch/arm/mach-s3c/dev-uart-s3c64xx.c index 5fb59ad30008..8288e8d6c092 100644 --- a/arch/arm/mach-s3c64xx/dev-uart.c +++ b/arch/arm/mach-s3c/dev-uart-s3c64xx.c @@ -15,11 +15,10 @@ #include <asm/mach/arch.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> -#include <mach/map.h> +#include "map.h" #include <mach/irqs.h> -#include <plat/devs.h> +#include "devs.h" /* Serial port registrations */ diff --git a/arch/arm/plat-samsung/dev-uart.c b/arch/arm/mach-s3c/dev-uart.c index 7476a5dbae77..3d1f7f2fd7c7 100644 --- a/arch/arm/plat-samsung/dev-uart.c +++ b/arch/arm/mach-s3c/dev-uart.c @@ -10,7 +10,7 @@ #include <linux/kernel.h> #include <linux/platform_device.h> -#include <plat/devs.h> +#include "devs.h" /* uart devices */ diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/mach-s3c/devs.c index 089a17687104..06dec64848f9 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/mach-s3c/devs.c @@ -5,6 +5,7 @@ // // Base Samsung platform device definitions +#include <linux/gpio.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/interrupt.h> @@ -37,28 +38,32 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/dma.h> #include <mach/irqs.h> -#include <mach/map.h> +#include "map.h" +#include "gpio-samsung.h" +#include "gpio-cfg.h" -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/adc.h> +#ifdef CONFIG_PLAT_S3C24XX +#include "regs-s3c2443-clock.h" +#endif /* CONFIG_PLAT_S3C24XX */ + +#include "cpu.h" +#include "devs.h" +#include <linux/soc/samsung/s3c-adc.h> #include <linux/platform_data/ata-samsung_cf.h> -#include <plat/fb.h> -#include <plat/fb-s3c2410.h> +#include "fb.h" +#include <linux/platform_data/fb-s3c2410.h> #include <linux/platform_data/hwmon-s3c.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/keypad.h> +#include "keypad.h" #include <linux/platform_data/mmc-s3cmci.h> #include <linux/platform_data/mtd-nand-s3c2410.h> -#include <plat/pwm-core.h> -#include <plat/sdhci.h> +#include "pwm-core.h" +#include "sdhci.h" #include <linux/platform_data/touchscreen-s3c2410.h> #include <linux/platform_data/usb-s3c2410_udc.h> #include <linux/platform_data/usb-ohci-s3c2410.h> -#include <plat/usb-phy.h> -#include <plat/regs-spi.h> +#include "usb-phy.h" #include <linux/platform_data/asoc-s3c.h> #include <linux/platform_data/spi-s3c64xx.h> @@ -833,16 +838,42 @@ struct platform_device s3c_device_rtc = { /* SDI */ #ifdef CONFIG_PLAT_S3C24XX +void s3c24xx_mci_def_set_power(unsigned char power_mode, unsigned short vdd) +{ + switch (power_mode) { + case MMC_POWER_ON: + case MMC_POWER_UP: + /* Configure GPE5...GPE10 pins in SD mode */ + s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2), + S3C_GPIO_PULL_NONE); + break; + + case MMC_POWER_OFF: + default: + gpio_direction_output(S3C2410_GPE(5), 0); + break; + } +} + static struct resource s3c_sdi_resource[] = { [0] = DEFINE_RES_MEM(S3C24XX_PA_SDI, S3C24XX_SZ_SDI), [1] = DEFINE_RES_IRQ(IRQ_SDI), }; +static struct s3c24xx_mci_pdata s3cmci_def_pdata = { + /* This is currently here to avoid a number of if (host->pdata) + * checks. Any zero fields to ensure reasonable defaults are picked. */ + .no_wprotect = 1, + .no_detect = 1, + .set_power = s3c24xx_mci_def_set_power, +}; + struct platform_device s3c_device_sdi = { .name = "s3c2410-sdi", .id = -1, .num_resources = ARRAY_SIZE(s3c_sdi_resource), .resource = s3c_sdi_resource, + .dev.platform_data = &s3cmci_def_pdata, }; void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata) @@ -1038,6 +1069,8 @@ struct platform_device s3c_device_usb_hsudc = { void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd) { s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc); + pd->phy_init = s3c_hsudc_init_phy; + pd->phy_uninit = s3c_hsudc_uninit_phy; } #endif /* CONFIG_PLAT_S3C24XX */ diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/mach-s3c/devs.h index 02b0c5750572..02b0c5750572 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/mach-s3c/devs.h diff --git a/arch/arm/mach-s3c24xx/include/mach/dma.h b/arch/arm/mach-s3c/dma-s3c24xx.h index 25fc9c258fc1..25fc9c258fc1 100644 --- a/arch/arm/mach-s3c24xx/include/mach/dma.h +++ b/arch/arm/mach-s3c/dma-s3c24xx.h diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c/dma-s3c64xx.h index 40ca8de21096..40ca8de21096 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c/dma-s3c64xx.h diff --git a/arch/arm/mach-s3c/dma.h b/arch/arm/mach-s3c/dma.h new file mode 100644 index 000000000000..59a4578c5f00 --- /dev/null +++ b/arch/arm/mach-s3c/dma.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "dma-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "dma-s3c64xx.h" +#endif diff --git a/arch/arm/mach-s3c24xx/fb-core.h b/arch/arm/mach-s3c/fb-core-s3c24xx.h index 1821e820262c..0e07f3ba4aef 100644 --- a/arch/arm/mach-s3c24xx/fb-core.h +++ b/arch/arm/mach-s3c/fb-core-s3c24xx.h @@ -5,8 +5,8 @@ * * Samsung framebuffer driver core functions */ -#ifndef __ASM_PLAT_FB_CORE_H -#define __ASM_PLAT_FB_CORE_H __FILE__ +#ifndef __ASM_PLAT_FB_CORE_S3C24XX_H +#define __ASM_PLAT_FB_CORE_S3C24XX_H __FILE__ /* * These functions are only for use with the core support code, such as @@ -21,4 +21,4 @@ static inline void s3c_fb_setname(char *name) #endif } -#endif /* __ASM_PLAT_FB_CORE_H */ +#endif /* __ASM_PLAT_FB_CORE_S3C24XX_H */ diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/mach-s3c/fb.h index 615d381ae32e..615d381ae32e 100644 --- a/arch/arm/plat-samsung/include/plat/fb.h +++ b/arch/arm/mach-s3c/fb.h diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/mach-s3c/gpio-cfg-helpers.h index db0c56f5ca15..db0c56f5ca15 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h +++ b/arch/arm/mach-s3c/gpio-cfg-helpers.h diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/mach-s3c/gpio-cfg.h index 469c220e092b..469c220e092b 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h +++ b/arch/arm/mach-s3c/gpio-cfg.h diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/mach-s3c/gpio-core.h index c0bfceb88340..b361c8c0d669 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-core.h +++ b/arch/arm/mach-s3c/gpio-core.h @@ -11,7 +11,7 @@ #define __PLAT_SAMSUNG_GPIO_CORE_H /* Bring in machine-local definitions, especially S3C_GPIO_END */ -#include <mach/gpio-samsung.h> +#include "gpio-samsung.h" #include <linux/gpio/driver.h> #define GPIOCON_OFF (0x00) diff --git a/arch/arm/mach-s3c24xx/include/mach/gpio-samsung.h b/arch/arm/mach-s3c/gpio-samsung-s3c24xx.h index 2ad22b2d459b..c29fdc95f883 100644 --- a/arch/arm/mach-s3c24xx/include/mach/gpio-samsung.h +++ b/arch/arm/mach-s3c/gpio-samsung-s3c24xx.h @@ -14,6 +14,8 @@ #ifndef GPIO_SAMSUNG_S3C24XX_H #define GPIO_SAMSUNG_S3C24XX_H +#include "map.h" + /* * GPIO sizes for various SoCs: * diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h b/arch/arm/mach-s3c/gpio-samsung-s3c64xx.h index 8ed144a0d474..8ed144a0d474 100644 --- a/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h +++ b/arch/arm/mach-s3c/gpio-samsung-s3c64xx.h diff --git a/arch/arm/plat-samsung/gpio-samsung.c b/arch/arm/mach-s3c/gpio-samsung.c index 8955fd675265..76ef415789f2 100644 --- a/arch/arm/plat-samsung/gpio-samsung.c +++ b/arch/arm/mach-s3c/gpio-samsung.c @@ -27,15 +27,15 @@ #include <asm/irq.h> #include <mach/irqs.h> -#include <mach/map.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> - -#include <plat/cpu.h> -#include <plat/gpio-core.h> -#include <plat/gpio-cfg.h> -#include <plat/gpio-cfg-helpers.h> -#include <plat/pm.h> +#include "map.h" +#include "regs-gpio.h" +#include "gpio-samsung.h" + +#include "cpu.h" +#include "gpio-core.h" +#include "gpio-cfg.h" +#include "gpio-cfg-helpers.h" +#include "pm.h" int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip, unsigned int off, samsung_gpio_pull_t pull) diff --git a/arch/arm/mach-s3c/gpio-samsung.h b/arch/arm/mach-s3c/gpio-samsung.h new file mode 100644 index 000000000000..02f6f4a96862 --- /dev/null +++ b/arch/arm/mach-s3c/gpio-samsung.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "gpio-samsung-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "gpio-samsung-s3c64xx.h" +#endif diff --git a/arch/arm/mach-s3c24xx/gta02.h b/arch/arm/mach-s3c/gta02.h index d5610ba829a4..043ae382bfc5 100644 --- a/arch/arm/mach-s3c24xx/gta02.h +++ b/arch/arm/mach-s3c/gta02.h @@ -6,7 +6,7 @@ #ifndef __MACH_S3C24XX_GTA02_H #define __MACH_S3C24XX_GTA02_H __FILE__ -#include <mach/regs-gpio.h> +#include "regs-gpio.h" #define GTA02_GPIO_AUX_LED S3C2410_GPB(2) #define GTA02_GPIO_USB_PULLUP S3C2410_GPB(9) diff --git a/arch/arm/mach-s3c24xx/h1940-bluetooth.c b/arch/arm/mach-s3c/h1940-bluetooth.c index 186b5321658e..59edcf8a620d 100644 --- a/arch/arm/mach-s3c24xx/h1940-bluetooth.c +++ b/arch/arm/mach-s3c/h1940-bluetooth.c @@ -13,10 +13,9 @@ #include <linux/gpio.h> #include <linux/rfkill.h> -#include <plat/gpio-cfg.h> -#include <mach/hardware.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> +#include "gpio-cfg.h" +#include "regs-gpio.h" +#include "gpio-samsung.h" #include "h1940.h" diff --git a/arch/arm/mach-s3c24xx/h1940.h b/arch/arm/mach-s3c/h1940.h index 5dfe9d10cd15..5dfe9d10cd15 100644 --- a/arch/arm/mach-s3c24xx/h1940.h +++ b/arch/arm/mach-s3c/h1940.h diff --git a/arch/arm/mach-s3c24xx/include/mach/hardware.h b/arch/arm/mach-s3c/hardware-s3c24xx.h index f28ac6c78d82..33b37467d05f 100644 --- a/arch/arm/mach-s3c24xx/include/mach/hardware.h +++ b/arch/arm/mach-s3c/hardware-s3c24xx.h @@ -6,16 +6,9 @@ * S3C2410 - hardware */ -#ifndef __ASM_ARCH_HARDWARE_H -#define __ASM_ARCH_HARDWARE_H - -#ifndef __ASSEMBLY__ +#ifndef __ASM_ARCH_HARDWARE_S3C24XX_H +#define __ASM_ARCH_HARDWARE_S3C24XX_H extern unsigned int s3c2410_modify_misccr(unsigned int clr, unsigned int chg); -#endif /* __ASSEMBLY__ */ - -#include <linux/sizes.h> -#include <mach/map.h> - -#endif /* __ASM_ARCH_HARDWARE_H */ +#endif /* __ASM_ARCH_HARDWARE_S3C24XX_H */ diff --git a/arch/arm/plat-samsung/include/plat/iic-core.h b/arch/arm/mach-s3c/iic-core.h index c5cfd5af3874..c5cfd5af3874 100644 --- a/arch/arm/plat-samsung/include/plat/iic-core.h +++ b/arch/arm/mach-s3c/iic-core.h diff --git a/arch/arm/mach-s3c/include/mach/io-s3c24xx.h b/arch/arm/mach-s3c/include/mach/io-s3c24xx.h new file mode 100644 index 000000000000..738b775d3336 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/io-s3c24xx.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * arch/arm/mach-s3c2410/include/mach/io.h + * from arch/arm/mach-rpc/include/mach/io.h + * + * Copyright (C) 1997 Russell King + * (C) 2003 Simtec Electronics +*/ + +#ifndef __ASM_ARM_ARCH_IO_S3C24XX_H +#define __ASM_ARM_ARCH_IO_S3C24XX_H + +#include <mach/map-base.h> + +/* + * ISA style IO, for each machine to sort out mappings for, + * if it implements it. We reserve two 16M regions for ISA, + * so the PC/104 can use separate addresses for 8-bit and + * 16-bit port I/O. + */ +#define PCIO_BASE S3C_ADDR(0x02000000) +#define IO_SPACE_LIMIT 0x00ffffff +#define S3C24XX_VA_ISA_WORD (PCIO_BASE) +#define S3C24XX_VA_ISA_BYTE (PCIO_BASE + 0x01000000) + +#ifdef CONFIG_ISA + +#define inb(p) readb(S3C24XX_VA_ISA_BYTE + (p)) +#define inw(p) readw(S3C24XX_VA_ISA_WORD + (p)) +#define inl(p) readl(S3C24XX_VA_ISA_WORD + (p)) + +#define outb(v,p) writeb((v), S3C24XX_VA_ISA_BYTE + (p)) +#define outw(v,p) writew((v), S3C24XX_VA_ISA_WORD + (p)) +#define outl(v,p) writel((v), S3C24XX_VA_ISA_WORD + (p)) + +#define insb(p,d,l) readsb(S3C24XX_VA_ISA_BYTE + (p),d,l) +#define insw(p,d,l) readsw(S3C24XX_VA_ISA_WORD + (p),d,l) +#define insl(p,d,l) readsl(S3C24XX_VA_ISA_WORD + (p),d,l) + +#define outsb(p,d,l) writesb(S3C24XX_VA_ISA_BYTE + (p),d,l) +#define outsw(p,d,l) writesw(S3C24XX_VA_ISA_WORD + (p),d,l) +#define outsl(p,d,l) writesl(S3C24XX_VA_ISA_WORD + (p),d,l) + +#else + +#define __io(x) (PCIO_BASE + (x)) + +#endif + +#endif diff --git a/arch/arm/mach-s3c/include/mach/io.h b/arch/arm/mach-s3c/include/mach/io.h new file mode 100644 index 000000000000..30a0135708dc --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/io.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Krzysztof Kozlowski <krzk@kernel.org> + */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "io-s3c24xx.h" +#endif diff --git a/arch/arm/mach-s3c24xx/include/mach/irqs.h b/arch/arm/mach-s3c/include/mach/irqs-s3c24xx.h index aaf3bae08b52..aaf3bae08b52 100644 --- a/arch/arm/mach-s3c24xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c/include/mach/irqs-s3c24xx.h diff --git a/arch/arm/mach-s3c64xx/include/mach/irqs.h b/arch/arm/mach-s3c/include/mach/irqs-s3c64xx.h index c244e480e6b3..c244e480e6b3 100644 --- a/arch/arm/mach-s3c64xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c/include/mach/irqs-s3c64xx.h diff --git a/arch/arm/mach-s3c/include/mach/irqs.h b/arch/arm/mach-s3c/include/mach/irqs.h new file mode 100644 index 000000000000..0bff1c1c8eb0 --- /dev/null +++ b/arch/arm/mach-s3c/include/mach/irqs.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "irqs-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "irqs-s3c64xx.h" +#endif diff --git a/arch/arm/plat-samsung/include/plat/map-base.h b/arch/arm/mach-s3c/include/mach/map-base.h index 34b39ded0e2e..34b39ded0e2e 100644 --- a/arch/arm/plat-samsung/include/plat/map-base.h +++ b/arch/arm/mach-s3c/include/mach/map-base.h diff --git a/arch/arm/plat-samsung/init.c b/arch/arm/mach-s3c/init.c index e9acf02ef3c3..9d92f03e9bc1 100644 --- a/arch/arm/plat-samsung/init.c +++ b/arch/arm/mach-s3c/init.c @@ -23,8 +23,8 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <plat/cpu.h> -#include <plat/devs.h> +#include "cpu.h" +#include "devs.h" static struct cpu_table *cpu; diff --git a/arch/arm/mach-s3c24xx/iotiming-s3c2410.c b/arch/arm/mach-s3c/iotiming-s3c2410.c index 9f90aaf70bf3..28d9f473e24a 100644 --- a/arch/arm/mach-s3c24xx/iotiming-s3c2410.c +++ b/arch/arm/mach-s3c/iotiming-s3c2410.c @@ -14,12 +14,12 @@ #include <linux/io.h> #include <linux/slab.h> -#include <mach/map.h> -#include <mach/regs-clock.h> +#include "map.h" +#include "regs-clock.h" -#include <plat/cpu-freq-core.h> +#include <linux/soc/samsung/s3c-cpufreq-core.h> -#include "regs-mem.h" +#include "regs-mem-s3c24xx.h" #define print_ns(x) ((x) / 10), ((x) % 10) @@ -129,7 +129,7 @@ static unsigned int calc_0124(unsigned int cyc, unsigned long hclk_tns, return 0; } -int calc_tacp(unsigned int cyc, unsigned long hclk, unsigned long *v) +static int calc_tacp(unsigned int cyc, unsigned long hclk, unsigned long *v) { /* Currently no support for Tacp calculations. */ return 0; @@ -288,8 +288,8 @@ static unsigned int get_0124(unsigned long hclk_tns, * Given the BANKCON setting in @bt and the current frequency settings * in @cfg, update the cycle timing information. */ -void s3c2410_iotiming_getbank(struct s3c_cpufreq_config *cfg, - struct s3c2410_iobank_timing *bt) +static void s3c2410_iotiming_getbank(struct s3c_cpufreq_config *cfg, + struct s3c2410_iobank_timing *bt) { unsigned long bankcon = bt->bankcon; unsigned long hclk = cfg->freq.hclk_tns; diff --git a/arch/arm/mach-s3c24xx/iotiming-s3c2412.c b/arch/arm/mach-s3c/iotiming-s3c2412.c index 59356d10fbcf..003f89c4dc53 100644 --- a/arch/arm/mach-s3c24xx/iotiming-s3c2412.c +++ b/arch/arm/mach-s3c/iotiming-s3c2412.c @@ -23,10 +23,10 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <plat/cpu.h> -#include <plat/cpu-freq-core.h> +#include "cpu.h" +#include <linux/soc/samsung/s3c-cpufreq-core.h> -#include <mach/s3c2412.h> +#include "s3c2412.h" #define print_ns(x) ((x) / 10), ((x) % 10) diff --git a/arch/arm/mach-s3c24xx/irq-pm.c b/arch/arm/mach-s3c/irq-pm-s3c24xx.c index e0131b16a4af..4d5e28312d91 100644 --- a/arch/arm/mach-s3c24xx/irq-pm.c +++ b/arch/arm/mach-s3c/irq-pm-s3c24xx.c @@ -13,14 +13,14 @@ #include <linux/syscore_ops.h> #include <linux/io.h> -#include <plat/cpu.h> -#include <plat/pm.h> -#include <plat/map-base.h> -#include <plat/map-s3c.h> - -#include <mach/regs-irq.h> -#include <mach/regs-gpio.h> -#include <mach/pm-core.h> +#include "cpu.h" +#include "pm.h" +#include <mach/map-base.h> +#include "map-s3c.h" + +#include "regs-irq.h" +#include "regs-gpio.h" +#include "pm-core.h" #include <asm/irq.h> diff --git a/arch/arm/mach-s3c64xx/irq-pm.c b/arch/arm/mach-s3c/irq-pm-s3c64xx.c index 31b221190479..4a1e935bada1 100644 --- a/arch/arm/mach-s3c64xx/irq-pm.c +++ b/arch/arm/mach-s3c/irq-pm-s3c64xx.c @@ -20,11 +20,11 @@ #include <linux/io.h> #include <linux/of.h> -#include <mach/map.h> +#include "map.h" -#include <mach/regs-gpio.h> -#include <plat/cpu.h> -#include <plat/pm.h> +#include "regs-gpio.h" +#include "cpu.h" +#include "pm.h" /* We handled all the IRQ types in this code, to save having to make several * small files to handle each different type separately. Having the EINT_GRP diff --git a/arch/arm/mach-s3c/irq-s3c24xx-fiq-exports.c b/arch/arm/mach-s3c/irq-s3c24xx-fiq-exports.c new file mode 100644 index 000000000000..84cf86376ded --- /dev/null +++ b/arch/arm/mach-s3c/irq-s3c24xx-fiq-exports.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include <linux/stddef.h> +#include <linux/export.h> +#include <linux/spi/s3c24xx-fiq.h> + +EXPORT_SYMBOL(s3c24xx_spi_fiq_rx); +EXPORT_SYMBOL(s3c24xx_spi_fiq_txrx); +EXPORT_SYMBOL(s3c24xx_spi_fiq_tx); diff --git a/arch/arm/mach-s3c/irq-s3c24xx-fiq.S b/arch/arm/mach-s3c/irq-s3c24xx-fiq.S new file mode 100644 index 000000000000..b54cbd012241 --- /dev/null +++ b/arch/arm/mach-s3c/irq-s3c24xx-fiq.S @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* linux/drivers/spi/spi_s3c24xx_fiq.S + * + * Copyright 2009 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * S3C24XX SPI - FIQ pseudo-DMA transfer code +*/ + +#include <linux/linkage.h> +#include <asm/assembler.h> + +#include "map.h" +#include "regs-irq.h" + +#include <linux/spi/s3c24xx-fiq.h> + +#define S3C2410_SPTDAT (0x10) +#define S3C2410_SPRDAT (0x14) + + .text + + @ entry to these routines is as follows, with the register names + @ defined in fiq.h so that they can be shared with the C files which + @ setup the calling registers. + @ + @ fiq_rirq The base of the IRQ registers to find S3C2410_SRCPND + @ fiq_rtmp Temporary register to hold tx/rx data + @ fiq_rspi The base of the SPI register block + @ fiq_rtx The tx buffer pointer + @ fiq_rrx The rx buffer pointer + @ fiq_rcount The number of bytes to move + + @ each entry starts with a word entry of how long it is + @ and an offset to the irq acknowledgment word + +ENTRY(s3c24xx_spi_fiq_rx) +s3c24xx_spi_fix_rx: + .word fiq_rx_end - fiq_rx_start + .word fiq_rx_irq_ack - fiq_rx_start +fiq_rx_start: + ldr fiq_rtmp, fiq_rx_irq_ack + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] + + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] + strb fiq_rtmp, [ fiq_rrx ], #1 + + mov fiq_rtmp, #0xff + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] + + subs fiq_rcount, fiq_rcount, #1 + subnes pc, lr, #4 @@ return, still have work to do + + @@ set IRQ controller so that next op will trigger IRQ + mov fiq_rtmp, #0 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] + subs pc, lr, #4 + +fiq_rx_irq_ack: + .word 0 +fiq_rx_end: + +ENTRY(s3c24xx_spi_fiq_txrx) +s3c24xx_spi_fiq_txrx: + .word fiq_txrx_end - fiq_txrx_start + .word fiq_txrx_irq_ack - fiq_txrx_start +fiq_txrx_start: + + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] + strb fiq_rtmp, [ fiq_rrx ], #1 + + ldr fiq_rtmp, fiq_txrx_irq_ack + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] + + ldrb fiq_rtmp, [ fiq_rtx ], #1 + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] + + subs fiq_rcount, fiq_rcount, #1 + subnes pc, lr, #4 @@ return, still have work to do + + mov fiq_rtmp, #0 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] + subs pc, lr, #4 + +fiq_txrx_irq_ack: + .word 0 + +fiq_txrx_end: + +ENTRY(s3c24xx_spi_fiq_tx) +s3c24xx_spi_fix_tx: + .word fiq_tx_end - fiq_tx_start + .word fiq_tx_irq_ack - fiq_tx_start +fiq_tx_start: + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] + + ldr fiq_rtmp, fiq_tx_irq_ack + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] + + ldrb fiq_rtmp, [ fiq_rtx ], #1 + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] + + subs fiq_rcount, fiq_rcount, #1 + subnes pc, lr, #4 @@ return, still have work to do + + mov fiq_rtmp, #0 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] + subs pc, lr, #4 + +fiq_tx_irq_ack: + .word 0 + +fiq_tx_end: + + .end diff --git a/arch/arm/mach-s3c/irq-s3c24xx.c b/arch/arm/mach-s3c/irq-s3c24xx.c new file mode 100644 index 000000000000..79b5f19af7a5 --- /dev/null +++ b/arch/arm/mach-s3c/irq-s3c24xx.c @@ -0,0 +1,1337 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * S3C24XX IRQ handling + * + * Copyright (c) 2003-2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de> +*/ + +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/device.h> +#include <linux/irqdomain.h> +#include <linux/irqchip.h> +#include <linux/irqchip/chained_irq.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> + +#include <asm/exception.h> +#include <asm/mach/irq.h> + +#include <mach/irqs.h> +#include "regs-irq.h" +#include "regs-gpio.h" + +#include "cpu.h" +#include "regs-irqtype.h" +#include "pm.h" + +#define S3C_IRQTYPE_NONE 0 +#define S3C_IRQTYPE_EINT 1 +#define S3C_IRQTYPE_EDGE 2 +#define S3C_IRQTYPE_LEVEL 3 + +struct s3c_irq_data { + unsigned int type; + unsigned long offset; + unsigned long parent_irq; + + /* data gets filled during init */ + struct s3c_irq_intc *intc; + unsigned long sub_bits; + struct s3c_irq_intc *sub_intc; +}; + +/* + * Structure holding the controller data + * @reg_pending register holding pending irqs + * @reg_intpnd special register intpnd in main intc + * @reg_mask mask register + * @domain irq_domain of the controller + * @parent parent controller for ext and sub irqs + * @irqs irq-data, always s3c_irq_data[32] + */ +struct s3c_irq_intc { + void __iomem *reg_pending; + void __iomem *reg_intpnd; + void __iomem *reg_mask; + struct irq_domain *domain; + struct s3c_irq_intc *parent; + struct s3c_irq_data *irqs; +}; + +/* + * Array holding pointers to the global controller structs + * [0] ... main_intc + * [1] ... sub_intc + * [2] ... main_intc2 on s3c2416 + */ +static struct s3c_irq_intc *s3c_intc[3]; + +static void s3c_irq_mask(struct irq_data *data) +{ + struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data); + struct s3c_irq_intc *intc = irq_data->intc; + struct s3c_irq_intc *parent_intc = intc->parent; + struct s3c_irq_data *parent_data; + unsigned long mask; + unsigned int irqno; + + mask = readl_relaxed(intc->reg_mask); + mask |= (1UL << irq_data->offset); + writel_relaxed(mask, intc->reg_mask); + + if (parent_intc) { + parent_data = &parent_intc->irqs[irq_data->parent_irq]; + + /* check to see if we need to mask the parent IRQ + * The parent_irq is always in main_intc, so the hwirq + * for find_mapping does not need an offset in any case. + */ + if ((mask & parent_data->sub_bits) == parent_data->sub_bits) { + irqno = irq_find_mapping(parent_intc->domain, + irq_data->parent_irq); + s3c_irq_mask(irq_get_irq_data(irqno)); + } + } +} + +static void s3c_irq_unmask(struct irq_data *data) +{ + struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data); + struct s3c_irq_intc *intc = irq_data->intc; + struct s3c_irq_intc *parent_intc = intc->parent; + unsigned long mask; + unsigned int irqno; + + mask = readl_relaxed(intc->reg_mask); + mask &= ~(1UL << irq_data->offset); + writel_relaxed(mask, intc->reg_mask); + + if (parent_intc) { + irqno = irq_find_mapping(parent_intc->domain, + irq_data->parent_irq); + s3c_irq_unmask(irq_get_irq_data(irqno)); + } +} + +static inline void s3c_irq_ack(struct irq_data *data) +{ + struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data); + struct s3c_irq_intc *intc = irq_data->intc; + unsigned long bitval = 1UL << irq_data->offset; + + writel_relaxed(bitval, intc->reg_pending); + if (intc->reg_intpnd) + writel_relaxed(bitval, intc->reg_intpnd); +} + +static int s3c_irq_type(struct irq_data *data, unsigned int type) +{ + switch (type) { + case IRQ_TYPE_NONE: + break; + case IRQ_TYPE_EDGE_RISING: + case IRQ_TYPE_EDGE_FALLING: + case IRQ_TYPE_EDGE_BOTH: + irq_set_handler(data->irq, handle_edge_irq); + break; + case IRQ_TYPE_LEVEL_LOW: + case IRQ_TYPE_LEVEL_HIGH: + irq_set_handler(data->irq, handle_level_irq); + break; + default: + pr_err("No such irq type %d\n", type); + return -EINVAL; + } + + return 0; +} + +static int s3c_irqext_type_set(void __iomem *gpcon_reg, + void __iomem *extint_reg, + unsigned long gpcon_offset, + unsigned long extint_offset, + unsigned int type) +{ + unsigned long newvalue = 0, value; + + /* Set the GPIO to external interrupt mode */ + value = readl_relaxed(gpcon_reg); + value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset); + writel_relaxed(value, gpcon_reg); + + /* Set the external interrupt to pointed trigger type */ + switch (type) + { + case IRQ_TYPE_NONE: + pr_warn("No edge setting!\n"); + break; + + case IRQ_TYPE_EDGE_RISING: + newvalue = S3C2410_EXTINT_RISEEDGE; + break; + + case IRQ_TYPE_EDGE_FALLING: + newvalue = S3C2410_EXTINT_FALLEDGE; + break; + + case IRQ_TYPE_EDGE_BOTH: + newvalue = S3C2410_EXTINT_BOTHEDGE; + break; + + case IRQ_TYPE_LEVEL_LOW: + newvalue = S3C2410_EXTINT_LOWLEV; + break; + + case IRQ_TYPE_LEVEL_HIGH: + newvalue = S3C2410_EXTINT_HILEV; + break; + + default: + pr_err("No such irq type %d\n", type); + return -EINVAL; + } + + value = readl_relaxed(extint_reg); + value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset); + writel_relaxed(value, extint_reg); + + return 0; +} + +static int s3c_irqext_type(struct irq_data *data, unsigned int type) +{ + void __iomem *extint_reg; + void __iomem *gpcon_reg; + unsigned long gpcon_offset, extint_offset; + + if ((data->hwirq >= 4) && (data->hwirq <= 7)) { + gpcon_reg = S3C2410_GPFCON; + extint_reg = S3C24XX_EXTINT0; + gpcon_offset = (data->hwirq) * 2; + extint_offset = (data->hwirq) * 4; + } else if ((data->hwirq >= 8) && (data->hwirq <= 15)) { + gpcon_reg = S3C2410_GPGCON; + extint_reg = S3C24XX_EXTINT1; + gpcon_offset = (data->hwirq - 8) * 2; + extint_offset = (data->hwirq - 8) * 4; + } else if ((data->hwirq >= 16) && (data->hwirq <= 23)) { + gpcon_reg = S3C2410_GPGCON; + extint_reg = S3C24XX_EXTINT2; + gpcon_offset = (data->hwirq - 8) * 2; + extint_offset = (data->hwirq - 16) * 4; + } else { + return -EINVAL; + } + + return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset, + extint_offset, type); +} + +static int s3c_irqext0_type(struct irq_data *data, unsigned int type) +{ + void __iomem *extint_reg; + void __iomem *gpcon_reg; + unsigned long gpcon_offset, extint_offset; + + if (data->hwirq <= 3) { + gpcon_reg = S3C2410_GPFCON; + extint_reg = S3C24XX_EXTINT0; + gpcon_offset = (data->hwirq) * 2; + extint_offset = (data->hwirq) * 4; + } else { + return -EINVAL; + } + + return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset, + extint_offset, type); +} + +static struct irq_chip s3c_irq_chip = { + .name = "s3c", + .irq_ack = s3c_irq_ack, + .irq_mask = s3c_irq_mask, + .irq_unmask = s3c_irq_unmask, + .irq_set_type = s3c_irq_type, + .irq_set_wake = s3c_irq_wake +}; + +static struct irq_chip s3c_irq_level_chip = { + .name = "s3c-level", + .irq_mask = s3c_irq_mask, + .irq_unmask = s3c_irq_unmask, + .irq_ack = s3c_irq_ack, + .irq_set_type = s3c_irq_type, +}; + +static struct irq_chip s3c_irqext_chip = { + .name = "s3c-ext", + .irq_mask = s3c_irq_mask, + .irq_unmask = s3c_irq_unmask, + .irq_ack = s3c_irq_ack, + .irq_set_type = s3c_irqext_type, + .irq_set_wake = s3c_irqext_wake +}; + +static struct irq_chip s3c_irq_eint0t4 = { + .name = "s3c-ext0", + .irq_ack = s3c_irq_ack, + .irq_mask = s3c_irq_mask, + .irq_unmask = s3c_irq_unmask, + .irq_set_wake = s3c_irq_wake, + .irq_set_type = s3c_irqext0_type, +}; + +static void s3c_irq_demux(struct irq_desc *desc) +{ + struct irq_chip *chip = irq_desc_get_chip(desc); + struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc); + struct s3c_irq_intc *intc = irq_data->intc; + struct s3c_irq_intc *sub_intc = irq_data->sub_intc; + unsigned int n, offset, irq; + unsigned long src, msk; + + /* we're using individual domains for the non-dt case + * and one big domain for the dt case where the subintc + * starts at hwirq number 32. + */ + offset = irq_domain_get_of_node(intc->domain) ? 32 : 0; + + chained_irq_enter(chip, desc); + + src = readl_relaxed(sub_intc->reg_pending); + msk = readl_relaxed(sub_intc->reg_mask); + + src &= ~msk; + src &= irq_data->sub_bits; + + while (src) { + n = __ffs(src); + src &= ~(1 << n); + irq = irq_find_mapping(sub_intc->domain, offset + n); + generic_handle_irq(irq); + } + + chained_irq_exit(chip, desc); +} + +static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc, + struct pt_regs *regs, int intc_offset) +{ + int pnd; + int offset; + + pnd = readl_relaxed(intc->reg_intpnd); + if (!pnd) + return false; + + /* non-dt machines use individual domains */ + if (!irq_domain_get_of_node(intc->domain)) + intc_offset = 0; + + /* We have a problem that the INTOFFSET register does not always + * show one interrupt. Occasionally we get two interrupts through + * the prioritiser, and this causes the INTOFFSET register to show + * what looks like the logical-or of the two interrupt numbers. + * + * Thanks to Klaus, Shannon, et al for helping to debug this problem + */ + offset = readl_relaxed(intc->reg_intpnd + 4); + + /* Find the bit manually, when the offset is wrong. + * The pending register only ever contains the one bit of the next + * interrupt to handle. + */ + if (!(pnd & (1 << offset))) + offset = __ffs(pnd); + + handle_domain_irq(intc->domain, intc_offset + offset, regs); + return true; +} + +asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs) +{ + do { + if (likely(s3c_intc[0])) + if (s3c24xx_handle_intc(s3c_intc[0], regs, 0)) + continue; + + if (s3c_intc[2]) + if (s3c24xx_handle_intc(s3c_intc[2], regs, 64)) + continue; + + break; + } while (1); +} + +#ifdef CONFIG_FIQ +/** + * s3c24xx_set_fiq - set the FIQ routing + * @irq: IRQ number to route to FIQ on processor. + * @ack_ptr: pointer to a location for storing the bit mask + * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing. + * + * Change the state of the IRQ to FIQ routing depending on @irq and @on. If + * @on is true, the @irq is checked to see if it can be routed and the + * interrupt controller updated to route the IRQ. If @on is false, the FIQ + * routing is cleared, regardless of which @irq is specified. + * + * returns the mask value for the register. + */ +int s3c24xx_set_fiq(unsigned int irq, u32 *ack_ptr, bool on) +{ + u32 intmod; + unsigned offs; + + if (on) { + offs = irq - FIQ_START; + if (offs > 31) + return 0; + + intmod = 1 << offs; + } else { + intmod = 0; + } + + if (ack_ptr) + *ack_ptr = intmod; + writel_relaxed(intmod, S3C2410_INTMOD); + + return intmod; +} + +EXPORT_SYMBOL_GPL(s3c24xx_set_fiq); +#endif + +static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct s3c_irq_intc *intc = h->host_data; + struct s3c_irq_data *irq_data = &intc->irqs[hw]; + struct s3c_irq_intc *parent_intc; + struct s3c_irq_data *parent_irq_data; + unsigned int irqno; + + /* attach controller pointer to irq_data */ + irq_data->intc = intc; + irq_data->offset = hw; + + parent_intc = intc->parent; + + /* set handler and flags */ + switch (irq_data->type) { + case S3C_IRQTYPE_NONE: + return 0; + case S3C_IRQTYPE_EINT: + /* On the S3C2412, the EINT0to3 have a parent irq + * but need the s3c_irq_eint0t4 chip + */ + if (parent_intc && (!soc_is_s3c2412() || hw >= 4)) + irq_set_chip_and_handler(virq, &s3c_irqext_chip, + handle_edge_irq); + else + irq_set_chip_and_handler(virq, &s3c_irq_eint0t4, + handle_edge_irq); + break; + case S3C_IRQTYPE_EDGE: + if (parent_intc || intc->reg_pending == S3C2416_SRCPND2) + irq_set_chip_and_handler(virq, &s3c_irq_level_chip, + handle_edge_irq); + else + irq_set_chip_and_handler(virq, &s3c_irq_chip, + handle_edge_irq); + break; + case S3C_IRQTYPE_LEVEL: + if (parent_intc) + irq_set_chip_and_handler(virq, &s3c_irq_level_chip, + handle_level_irq); + else + irq_set_chip_and_handler(virq, &s3c_irq_chip, + handle_level_irq); + break; + default: + pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type); + return -EINVAL; + } + + irq_set_chip_data(virq, irq_data); + + if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) { + if (irq_data->parent_irq > 31) { + pr_err("irq-s3c24xx: parent irq %lu is out of range\n", + irq_data->parent_irq); + return -EINVAL; + } + + parent_irq_data = &parent_intc->irqs[irq_data->parent_irq]; + parent_irq_data->sub_intc = intc; + parent_irq_data->sub_bits |= (1UL << hw); + + /* attach the demuxer to the parent irq */ + irqno = irq_find_mapping(parent_intc->domain, + irq_data->parent_irq); + if (!irqno) { + pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n", + irq_data->parent_irq); + return -EINVAL; + } + irq_set_chained_handler(irqno, s3c_irq_demux); + } + + return 0; +} + +static const struct irq_domain_ops s3c24xx_irq_ops = { + .map = s3c24xx_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +static void s3c24xx_clear_intc(struct s3c_irq_intc *intc) +{ + void __iomem *reg_source; + unsigned long pend; + unsigned long last; + int i; + + /* if intpnd is set, read the next pending irq from there */ + reg_source = intc->reg_intpnd ? intc->reg_intpnd : intc->reg_pending; + + last = 0; + for (i = 0; i < 4; i++) { + pend = readl_relaxed(reg_source); + + if (pend == 0 || pend == last) + break; + + writel_relaxed(pend, intc->reg_pending); + if (intc->reg_intpnd) + writel_relaxed(pend, intc->reg_intpnd); + + pr_info("irq: clearing pending status %08x\n", (int)pend); + last = pend; + } +} + +static struct s3c_irq_intc * __init s3c24xx_init_intc(struct device_node *np, + struct s3c_irq_data *irq_data, + struct s3c_irq_intc *parent, + unsigned long address) +{ + struct s3c_irq_intc *intc; + void __iomem *base = (void *)0xf6000000; /* static mapping */ + int irq_num; + int irq_start; + int ret; + + intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL); + if (!intc) + return ERR_PTR(-ENOMEM); + + intc->irqs = irq_data; + + if (parent) + intc->parent = parent; + + /* select the correct data for the controller. + * Need to hard code the irq num start and offset + * to preserve the static mapping for now + */ + switch (address) { + case 0x4a000000: + pr_debug("irq: found main intc\n"); + intc->reg_pending = base; + intc->reg_mask = base + 0x08; + intc->reg_intpnd = base + 0x10; + irq_num = 32; + irq_start = S3C2410_IRQ(0); + break; + case 0x4a000018: + pr_debug("irq: found subintc\n"); + intc->reg_pending = base + 0x18; + intc->reg_mask = base + 0x1c; + irq_num = 29; + irq_start = S3C2410_IRQSUB(0); + break; + case 0x4a000040: + pr_debug("irq: found intc2\n"); + intc->reg_pending = base + 0x40; + intc->reg_mask = base + 0x48; + intc->reg_intpnd = base + 0x50; + irq_num = 8; + irq_start = S3C2416_IRQ(0); + break; + case 0x560000a4: + pr_debug("irq: found eintc\n"); + base = (void *)0xfd000000; + + intc->reg_mask = base + 0xa4; + intc->reg_pending = base + 0xa8; + irq_num = 24; + irq_start = S3C2410_IRQ(32); + break; + default: + pr_err("irq: unsupported controller address\n"); + ret = -EINVAL; + goto err; + } + + /* now that all the data is complete, init the irq-domain */ + s3c24xx_clear_intc(intc); + intc->domain = irq_domain_add_legacy(np, irq_num, irq_start, + 0, &s3c24xx_irq_ops, + intc); + if (!intc->domain) { + pr_err("irq: could not create irq-domain\n"); + ret = -EINVAL; + goto err; + } + + set_handle_irq(s3c24xx_handle_irq); + + return intc; + +err: + kfree(intc); + return ERR_PTR(ret); +} + +static struct s3c_irq_data __maybe_unused init_eint[32] = { + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */ +}; + +#ifdef CONFIG_CPU_S3C2410 +static struct s3c_irq_data init_s3c2410base[32] = { + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */ + { .type = S3C_IRQTYPE_EDGE, }, /* WDT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* LCD */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */ + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ +}; + +static struct s3c_irq_data init_s3c2410subint[32] = { + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */ +}; + +void __init s3c2410_init_irq(void) +{ +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2410base[0], NULL, + 0x4a000000); + if (IS_ERR(s3c_intc[0])) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2410subint[0], + s3c_intc[0], 0x4a000018); + s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4); +} +#endif + +#ifdef CONFIG_CPU_S3C2412 +static struct s3c_irq_data init_s3c2412base[32] = { + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT1 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT2 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */ + { .type = S3C_IRQTYPE_EDGE, }, /* WDT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* LCD */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* SDI/CF */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */ + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ +}; + +static struct s3c_irq_data init_s3c2412eint[32] = { + { .type = S3C_IRQTYPE_EINT, .parent_irq = 0 }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 1 }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 2 }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 3 }, /* EINT3 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */ + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */ +}; + +static struct s3c_irq_data init_s3c2412subint[32] = { + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */ + { .type = S3C_IRQTYPE_NONE, }, + { .type = S3C_IRQTYPE_NONE, }, + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* SDI */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* CF */ +}; + +void __init s3c2412_init_irq(void) +{ + pr_info("S3C2412: IRQ Support\n"); + +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2412base[0], NULL, + 0x4a000000); + if (IS_ERR(s3c_intc[0])) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c24xx_init_intc(NULL, &init_s3c2412eint[0], s3c_intc[0], 0x560000a4); + s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2412subint[0], + s3c_intc[0], 0x4a000018); +} +#endif + +#ifdef CONFIG_CPU_S3C2416 +static struct s3c_irq_data init_s3c2416base[32] = { + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */ + { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */ + { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */ + { .type = S3C_IRQTYPE_NONE, }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* NAND */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */ + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */ + { .type = S3C_IRQTYPE_NONE, }, + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ +}; + +static struct s3c_irq_data init_s3c2416subint[32] = { + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */ +}; + +static struct s3c_irq_data init_s3c2416_second[32] = { + { .type = S3C_IRQTYPE_EDGE }, /* 2D */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE }, /* PCM0 */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_EDGE }, /* I2S0 */ +}; + +void __init s3c2416_init_irq(void) +{ + pr_info("S3C2416: IRQ Support\n"); + +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2416base[0], NULL, + 0x4a000000); + if (IS_ERR(s3c_intc[0])) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4); + s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2416subint[0], + s3c_intc[0], 0x4a000018); + + s3c_intc[2] = s3c24xx_init_intc(NULL, &init_s3c2416_second[0], + NULL, 0x4a000040); +} + +#endif + +#ifdef CONFIG_CPU_S3C2440 +static struct s3c_irq_data init_s3c2440base[32] = { + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */ + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */ + { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* LCD */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */ + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ +}; + +static struct s3c_irq_data init_s3c2440subint[32] = { + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */ +}; + +void __init s3c2440_init_irq(void) +{ + pr_info("S3C2440: IRQ Support\n"); + +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2440base[0], NULL, + 0x4a000000); + if (IS_ERR(s3c_intc[0])) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4); + s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2440subint[0], + s3c_intc[0], 0x4a000018); +} +#endif + +#ifdef CONFIG_CPU_S3C2442 +static struct s3c_irq_data init_s3c2442base[32] = { + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */ + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */ + { .type = S3C_IRQTYPE_EDGE, }, /* WDT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* LCD */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */ + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ +}; + +static struct s3c_irq_data init_s3c2442subint[32] = { + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */ +}; + +void __init s3c2442_init_irq(void) +{ + pr_info("S3C2442: IRQ Support\n"); + +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2442base[0], NULL, + 0x4a000000); + if (IS_ERR(s3c_intc[0])) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4); + s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2442subint[0], + s3c_intc[0], 0x4a000018); +} +#endif + +#ifdef CONFIG_CPU_S3C2443 +static struct s3c_irq_data init_s3c2443base[32] = { + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */ + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */ + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */ + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */ + { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */ + { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */ + { .type = S3C_IRQTYPE_EDGE, }, /* CFON */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* NAND */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */ + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */ + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */ + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */ + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */ + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */ +}; + + +static struct s3c_irq_data init_s3c2443subint[32] = { + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */ + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD1 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */ + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */ +}; + +void __init s3c2443_init_irq(void) +{ + pr_info("S3C2443: IRQ Support\n"); + +#ifdef CONFIG_FIQ + init_FIQ(FIQ_START); +#endif + + s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2443base[0], NULL, + 0x4a000000); + if (IS_ERR(s3c_intc[0])) { + pr_err("irq: could not create main interrupt controller\n"); + return; + } + + s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4); + s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2443subint[0], + s3c_intc[0], 0x4a000018); +} +#endif + +#ifdef CONFIG_OF +static int s3c24xx_irq_map_of(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + unsigned int ctrl_num = hw / 32; + unsigned int intc_hw = hw % 32; + struct s3c_irq_intc *intc = s3c_intc[ctrl_num]; + struct s3c_irq_intc *parent_intc = intc->parent; + struct s3c_irq_data *irq_data = &intc->irqs[intc_hw]; + + /* attach controller pointer to irq_data */ + irq_data->intc = intc; + irq_data->offset = intc_hw; + + if (!parent_intc) + irq_set_chip_and_handler(virq, &s3c_irq_chip, handle_edge_irq); + else + irq_set_chip_and_handler(virq, &s3c_irq_level_chip, + handle_edge_irq); + + irq_set_chip_data(virq, irq_data); + + return 0; +} + +/* Translate our of irq notation + * format: <ctrl_num ctrl_irq parent_irq type> + */ +static int s3c24xx_irq_xlate_of(struct irq_domain *d, struct device_node *n, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_type) +{ + struct s3c_irq_intc *intc; + struct s3c_irq_intc *parent_intc; + struct s3c_irq_data *irq_data; + struct s3c_irq_data *parent_irq_data; + int irqno; + + if (WARN_ON(intsize < 4)) + return -EINVAL; + + if (intspec[0] > 2 || !s3c_intc[intspec[0]]) { + pr_err("controller number %d invalid\n", intspec[0]); + return -EINVAL; + } + intc = s3c_intc[intspec[0]]; + + *out_hwirq = intspec[0] * 32 + intspec[2]; + *out_type = intspec[3] & IRQ_TYPE_SENSE_MASK; + + parent_intc = intc->parent; + if (parent_intc) { + irq_data = &intc->irqs[intspec[2]]; + irq_data->parent_irq = intspec[1]; + parent_irq_data = &parent_intc->irqs[irq_data->parent_irq]; + parent_irq_data->sub_intc = intc; + parent_irq_data->sub_bits |= (1UL << intspec[2]); + + /* parent_intc is always s3c_intc[0], so no offset */ + irqno = irq_create_mapping(parent_intc->domain, intspec[1]); + if (irqno < 0) { + pr_err("irq: could not map parent interrupt\n"); + return irqno; + } + + irq_set_chained_handler(irqno, s3c_irq_demux); + } + + return 0; +} + +static const struct irq_domain_ops s3c24xx_irq_ops_of = { + .map = s3c24xx_irq_map_of, + .xlate = s3c24xx_irq_xlate_of, +}; + +struct s3c24xx_irq_of_ctrl { + char *name; + unsigned long offset; + struct s3c_irq_intc **handle; + struct s3c_irq_intc **parent; + struct irq_domain_ops *ops; +}; + +static int __init s3c_init_intc_of(struct device_node *np, + struct device_node *interrupt_parent, + struct s3c24xx_irq_of_ctrl *s3c_ctrl, int num_ctrl) +{ + struct s3c_irq_intc *intc; + struct s3c24xx_irq_of_ctrl *ctrl; + struct irq_domain *domain; + void __iomem *reg_base; + int i; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + pr_err("irq-s3c24xx: could not map irq registers\n"); + return -EINVAL; + } + + domain = irq_domain_add_linear(np, num_ctrl * 32, + &s3c24xx_irq_ops_of, NULL); + if (!domain) { + pr_err("irq: could not create irq-domain\n"); + return -EINVAL; + } + + for (i = 0; i < num_ctrl; i++) { + ctrl = &s3c_ctrl[i]; + + pr_debug("irq: found controller %s\n", ctrl->name); + + intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL); + if (!intc) + return -ENOMEM; + + intc->domain = domain; + intc->irqs = kcalloc(32, sizeof(struct s3c_irq_data), + GFP_KERNEL); + if (!intc->irqs) { + kfree(intc); + return -ENOMEM; + } + + if (ctrl->parent) { + intc->reg_pending = reg_base + ctrl->offset; + intc->reg_mask = reg_base + ctrl->offset + 0x4; + + if (*(ctrl->parent)) { + intc->parent = *(ctrl->parent); + } else { + pr_warn("irq: parent of %s missing\n", + ctrl->name); + kfree(intc->irqs); + kfree(intc); + continue; + } + } else { + intc->reg_pending = reg_base + ctrl->offset; + intc->reg_mask = reg_base + ctrl->offset + 0x08; + intc->reg_intpnd = reg_base + ctrl->offset + 0x10; + } + + s3c24xx_clear_intc(intc); + s3c_intc[i] = intc; + } + + set_handle_irq(s3c24xx_handle_irq); + + return 0; +} + +static struct s3c24xx_irq_of_ctrl s3c2410_ctrl[] = { + { + .name = "intc", + .offset = 0, + }, { + .name = "subintc", + .offset = 0x18, + .parent = &s3c_intc[0], + } +}; + +int __init s3c2410_init_intc_of(struct device_node *np, + struct device_node *interrupt_parent) +{ + return s3c_init_intc_of(np, interrupt_parent, + s3c2410_ctrl, ARRAY_SIZE(s3c2410_ctrl)); +} +IRQCHIP_DECLARE(s3c2410_irq, "samsung,s3c2410-irq", s3c2410_init_intc_of); + +static struct s3c24xx_irq_of_ctrl s3c2416_ctrl[] = { + { + .name = "intc", + .offset = 0, + }, { + .name = "subintc", + .offset = 0x18, + .parent = &s3c_intc[0], + }, { + .name = "intc2", + .offset = 0x40, + } +}; + +int __init s3c2416_init_intc_of(struct device_node *np, + struct device_node *interrupt_parent) +{ + return s3c_init_intc_of(np, interrupt_parent, + s3c2416_ctrl, ARRAY_SIZE(s3c2416_ctrl)); +} +IRQCHIP_DECLARE(s3c2416_irq, "samsung,s3c2416-irq", s3c2416_init_intc_of); +#endif diff --git a/arch/arm/mach-s3c64xx/irq-uart.h b/arch/arm/mach-s3c/irq-uart-s3c64xx.h index 78eccdce95a7..78eccdce95a7 100644 --- a/arch/arm/mach-s3c64xx/irq-uart.h +++ b/arch/arm/mach-s3c/irq-uart-s3c64xx.h diff --git a/arch/arm/plat-samsung/include/plat/keypad.h b/arch/arm/mach-s3c/keypad.h index 9754b9a29945..9754b9a29945 100644 --- a/arch/arm/plat-samsung/include/plat/keypad.h +++ b/arch/arm/mach-s3c/keypad.h diff --git a/arch/arm/mach-s3c24xx/mach-amlm5900.c b/arch/arm/mach-s3c/mach-amlm5900.c index 9a9daf526d0c..94c4512ace17 100644 --- a/arch/arm/mach-s3c24xx/mach-amlm5900.c +++ b/arch/arm/mach-s3c/mach-amlm5900.c @@ -13,6 +13,7 @@ #include <linux/list.h> #include <linux/timer.h> #include <linux/init.h> +#include <linux/gpio/machine.h> #include <linux/gpio.h> #include <linux/device.h> #include <linux/platform_device.h> @@ -26,28 +27,24 @@ #include <asm/mach/irq.h> #include <asm/mach/flash.h> -#include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach-types.h> -#include <mach/fb.h> +#include <linux/platform_data/fb-s3c2410.h> -#include <mach/regs-lcd.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/gpio-cfg.h> +#include "devs.h" +#include "cpu.h" +#include "gpio-cfg.h" #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/mtd/map.h> #include <linux/mtd/physmap.h> -#include <plat/samsung-time.h> - -#include "common.h" +#include "s3c24xx.h" static struct resource amlm5900_nor_resource = DEFINE_RES_MEM(0x00000000, SZ_16M); @@ -124,6 +121,19 @@ static struct s3c2410_uartcfg amlm5900_uartcfgs[] = { } }; +static struct gpiod_lookup_table amlm5900_mmc_gpio_table = { + .dev_id = "s3c2410-sdi", + .table = { + /* bus pins */ + GPIO_LOOKUP_IDX("GPIOE", 5, "bus", 0, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 6, "bus", 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 7, "bus", 2, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 8, "bus", 3, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 9, "bus", 4, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH), + { }, + }, +}; static struct platform_device *amlm5900_devices[] __initdata = { #ifdef CONFIG_FB_S3C2410 @@ -143,13 +153,13 @@ static void __init amlm5900_map_io(void) { s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc)); s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init amlm5900_init_time(void) { s3c2410_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } #ifdef CONFIG_FB_S3C2410 @@ -180,13 +190,17 @@ static struct s3c2410fb_mach_info __initdata amlm5900_fb_info = { .gpccon = 0xaaaaaaaa, .gpccon_mask = 0xffffffff, + .gpccon_reg = S3C2410_GPCCON, .gpcup = 0x0000ffff, .gpcup_mask = 0xffffffff, + .gpcup_reg = S3C2410_GPCUP, .gpdcon = 0xaaaaaaaa, .gpdcon_mask = 0xffffffff, + .gpdcon_reg = S3C2410_GPDCON, .gpdup = 0x0000ffff, .gpdup_mask = 0xffffffff, + .gpdup_reg = S3C2410_GPDUP, }; #endif @@ -219,6 +233,7 @@ static void __init amlm5900_init(void) s3c24xx_fb_set_platdata(&amlm5900_fb_info); #endif s3c_i2c0_set_platdata(NULL); + gpiod_add_lookup_table(&amlm5900_mmc_gpio_table); platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices)); } diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c/mach-anubis.c index 072966dcad78..90e3fd98a3ac 100644 --- a/arch/arm/mach-s3c24xx/mach-anubis.c +++ b/arch/arm/mach-s3c/mach-anubis.c @@ -24,13 +24,11 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach-types.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> -#include <mach/gpio-samsung.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" #include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h> @@ -41,13 +39,12 @@ #include <net/ax88796.h> -#include <plat/devs.h> -#include <plat/cpu.h> +#include "devs.h" +#include "cpu.h" #include <linux/platform_data/asoc-s3c24xx_simtec.h> -#include <plat/samsung-time.h> #include "anubis.h" -#include "common.h" +#include "s3c24xx.h" #include "simtec.h" #define COPYRIGHT ", Copyright 2005-2009 Simtec Electronics" @@ -218,7 +215,7 @@ static struct s3c2410_platform_nand __initdata anubis_nand_info = { .nr_sets = ARRAY_SIZE(anubis_nand_sets), .sets = anubis_nand_sets, .select_chip = anubis_nand_select, - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; /* IDE channels */ @@ -384,7 +381,7 @@ static void __init anubis_map_io(void) { s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc)); s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); /* check for the newer revision boards with large page nand */ @@ -403,7 +400,7 @@ static void __init anubis_map_io(void) static void __init anubis_init_time(void) { s3c2440_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init anubis_init(void) diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c/mach-anw6410.c index 0d3d5befb806..825714e9ac66 100644 --- a/arch/arm/mach-s3c64xx/mach-anw6410.c +++ b/arch/arm/mach-s3c/mach-anw6410.c @@ -30,24 +30,22 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> -#include <mach/map.h> +#include "map.h" #include <asm/irq.h> #include <asm/mach-types.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/fb.h> +#include "fb.h" -#include <plat/devs.h> -#include <plat/cpu.h> +#include "devs.h" +#include "cpu.h" #include <mach/irqs.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> -#include <plat/samsung-time.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" -#include "common.h" -#include "regs-modem.h" +#include "s3c64xx.h" +#include "regs-modem-s3c64xx.h" /* DM9000 */ #define ANW6410_PA_DM9000 (0x18000000) @@ -204,7 +202,7 @@ static void __init anw6410_map_io(void) s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc)); s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4); anw6410_lcd_mode_set(); } @@ -228,6 +226,5 @@ MACHINE_START(ANW6410, "A&W6410") .init_irq = s3c6410_init_irq, .map_io = anw6410_map_io, .init_machine = anw6410_machine_init, - .init_time = samsung_timer_init, - .restart = s3c64xx_restart, + .init_time = s3c64xx_timer_init, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-at2440evb.c b/arch/arm/mach-s3c/mach-at2440evb.c index 58c5ef3cf1d7..5fa49d4e2650 100644 --- a/arch/arm/mach-s3c24xx/mach-at2440evb.c +++ b/arch/arm/mach-s3c/mach-at2440evb.c @@ -24,14 +24,12 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> -#include <mach/fb.h> +#include <linux/platform_data/fb-s3c2410.h> #include <asm/irq.h> #include <asm/mach-types.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> -#include <mach/gpio-samsung.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" #include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h> @@ -40,12 +38,11 @@ #include <linux/mtd/nand_ecc.h> #include <linux/mtd/partitions.h> -#include <plat/devs.h> -#include <plat/cpu.h> +#include "devs.h" +#include "cpu.h" #include <linux/platform_data/mmc-s3cmci.h> -#include <plat/samsung-time.h> -#include "common.h" +#include "s3c24xx.h" static struct map_desc at2440evb_iodesc[] __initdata = { /* Nothing here */ @@ -109,7 +106,7 @@ static struct s3c2410_platform_nand __initdata at2440evb_nand_info = { .twrph1 = 40, .nr_sets = ARRAY_SIZE(at2440evb_nand_sets), .sets = at2440evb_nand_sets, - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; /* DM9000AEP 10/100 ethernet controller */ @@ -136,18 +133,26 @@ static struct platform_device at2440evb_device_eth = { }; static struct s3c24xx_mci_pdata at2440evb_mci_pdata __initdata = { - /* Intentionally left blank */ + .set_power = s3c24xx_mci_def_set_power, }; static struct gpiod_lookup_table at2440evb_mci_gpio_table = { .dev_id = "s3c2410-sdi", .table = { /* Card detect S3C2410_GPG(10) */ - GPIO_LOOKUP("GPG", 10, "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOG", 10, "cd", GPIO_ACTIVE_LOW), + /* bus pins */ + GPIO_LOOKUP_IDX("GPIOE", 5, "bus", 0, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 6, "bus", 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 7, "bus", 2, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 8, "bus", 3, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 9, "bus", 4, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH), { }, }, }; + /* 7" LCD panel */ static struct s3c2410fb_display at2440evb_lcd_cfg __initdata = { @@ -197,13 +202,13 @@ static void __init at2440evb_map_io(void) { s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc)); s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init at2440evb_init_time(void) { s3c2440_init_clocks(16934400); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init at2440evb_init(void) diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c/mach-bast.c index a7c3955ae8f6..328f5d9ae9f9 100644 --- a/arch/arm/mach-s3c24xx/mach-bast.c +++ b/arch/arm/mach-s3c/mach-bast.c @@ -40,20 +40,17 @@ #include <asm/mach/irq.h> #include <asm/mach-types.h> -#include <mach/fb.h> -#include <mach/hardware.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> -#include <mach/gpio-samsung.h> - -#include <plat/cpu.h> -#include <plat/cpu-freq.h> -#include <plat/devs.h> -#include <plat/gpio-cfg.h> -#include <plat/samsung-time.h> +#include <linux/platform_data/fb-s3c2410.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" + +#include "cpu.h" +#include <linux/soc/samsung/s3c-cpu-freq.h> +#include "devs.h" +#include "gpio-cfg.h" #include "bast.h" -#include "common.h" +#include "s3c24xx.h" #include "simtec.h" #define COPYRIGHT ", Copyright 2004-2008 Simtec Electronics" @@ -294,7 +291,7 @@ static struct s3c2410_platform_nand __initdata bast_nand_info = { .nr_sets = ARRAY_SIZE(bast_nand_sets), .sets = bast_nand_sets, .select_chip = bast_nand_select, - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; /* DM9000 */ @@ -550,13 +547,13 @@ static void __init bast_map_io(void) s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init bast_init_time(void) { s3c2410_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init bast_init(void) diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c/mach-crag6410-module.c index 34f1baa10c54..407ad493493e 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c/mach-crag6410-module.c @@ -27,7 +27,7 @@ #include <linux/platform_data/spi-s3c64xx.h> -#include <plat/cpu.h> +#include "cpu.h" #include <mach/irqs.h> #include "crag6410.h" @@ -378,8 +378,7 @@ static const struct { .i2c_devs = wm2200_i2c, .num_i2c_devs = ARRAY_SIZE(wm2200_i2c) }, }; -static int wlf_gf_module_probe(struct i2c_client *i2c, - const struct i2c_device_id *i2c_id) +static int wlf_gf_module_probe(struct i2c_client *i2c) { int ret, i, j, id, rev; @@ -432,7 +431,7 @@ static struct i2c_driver wlf_gf_module_driver = { .driver = { .name = "wlf-gf-module" }, - .probe = wlf_gf_module_probe, + .probe_new = wlf_gf_module_probe, .id_table = wlf_gf_module_id, }; diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c/mach-crag6410.c index da9654255e3f..4a12c75d407f 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c/mach-crag6410.c @@ -44,30 +44,28 @@ #include <asm/mach-types.h> #include <video/samsung_fimd.h> -#include <mach/hardware.h> -#include <mach/map.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> +#include "map.h" +#include "regs-gpio.h" +#include "gpio-samsung.h" #include <mach/irqs.h> -#include <plat/fb.h> -#include <plat/sdhci.h> -#include <plat/gpio-cfg.h> +#include "fb.h" +#include "sdhci.h" +#include "gpio-cfg.h" #include <linux/platform_data/spi-s3c64xx.h> -#include <plat/keypad.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/adc.h> +#include "keypad.h" +#include "devs.h" +#include "cpu.h" +#include <linux/soc/samsung/s3c-adc.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/pm.h> -#include <plat/samsung-time.h> +#include "pm.h" -#include "common.h" +#include "s3c64xx.h" #include "crag6410.h" -#include "regs-gpio-memport.h" -#include "regs-modem.h" -#include "regs-sys.h" +#include "regs-gpio-memport-s3c64xx.h" +#include "regs-modem-s3c64xx.h" +#include "regs-sys-s3c64xx.h" /* serial port setup */ @@ -750,7 +748,7 @@ static void __init crag6410_map_io(void) s3c64xx_init_io(NULL, 0); s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(crag6410_uartcfgs, ARRAY_SIZE(crag6410_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4); /* LCD type and Bypass set by bootloader */ } @@ -877,6 +875,5 @@ MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410") .init_irq = s3c6410_init_irq, .map_io = crag6410_map_io, .init_machine = crag6410_machine_init, - .init_time = samsung_timer_init, - .restart = s3c64xx_restart, + .init_time = s3c64xx_timer_init, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c/mach-gta02.c index 594901f3b8e5..3c75c7d112ea 100644 --- a/arch/arm/mach-s3c24xx/mach-gta02.c +++ b/arch/arm/mach-s3c/mach-gta02.c @@ -15,6 +15,7 @@ #include <linux/delay.h> #include <linux/timer.h> #include <linux/init.h> +#include <linux/gpio/machine.h> #include <linux/gpio.h> #include <linux/gpio_keys.h> #include <linux/workqueue.h> @@ -56,20 +57,18 @@ #include <linux/platform_data/touchscreen-s3c2410.h> #include <linux/platform_data/usb-ohci-s3c2410.h> #include <linux/platform_data/usb-s3c2410_udc.h> +#include <linux/platform_data/fb-s3c2410.h> -#include <mach/fb.h> -#include <mach/hardware.h> -#include <mach/regs-gpio.h> -#include <mach/regs-irq.h> -#include <mach/gpio-samsung.h> +#include "regs-gpio.h" +#include "regs-irq.h" +#include "gpio-samsung.h" -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/gpio-cfg.h> -#include <plat/pm.h> -#include <plat/samsung-time.h> +#include "cpu.h" +#include "devs.h" +#include "gpio-cfg.h" +#include "pm.h" -#include "common.h" +#include "s3c24xx.h" #include "gta02.h" static struct pcf50633 *gta02_pcf; @@ -416,7 +415,7 @@ static struct s3c2410_platform_nand __initdata gta02_nand_info = { .twrph1 = 15, .nr_sets = ARRAY_SIZE(gta02_nand_sets), .sets = gta02_nand_sets, - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; @@ -474,11 +473,39 @@ static struct platform_device gta02_buttons_device = { }, }; +static struct gpiod_lookup_table gta02_audio_gpio_table = { + .dev_id = "neo1973-audio", + .table = { + GPIO_LOOKUP("GPIOJ", 2, "amp-shut", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("GPIOJ", 1, "hp", GPIO_ACTIVE_HIGH), + { }, + }, +}; + +static struct platform_device gta02_audio = { + .name = "neo1973-audio", + .id = -1, +}; + +static struct gpiod_lookup_table gta02_mmc_gpio_table = { + .dev_id = "s3c2410-sdi", + .table = { + /* bus pins */ + GPIO_LOOKUP_IDX("GPIOE", 5, "bus", 0, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 6, "bus", 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 7, "bus", 2, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 8, "bus", 3, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 9, "bus", 4, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH), + { }, + }, +}; + static void __init gta02_map_io(void) { s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc)); s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } @@ -498,6 +525,7 @@ static struct platform_device *gta02_devices[] __initdata = { >a02_buttons_device, &s3c_device_adc, &s3c_device_ts, + >a02_audio, }; static void gta02_poweroff(void) @@ -524,6 +552,12 @@ static void __init gta02_machine_init(void) i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs)); + /* 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); + + gpiod_add_lookup_table(>a02_audio_gpio_table); + gpiod_add_lookup_table(>a02_mmc_gpio_table); platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices)); pm_power_off = gta02_poweroff; @@ -533,7 +567,7 @@ static void __init gta02_machine_init(void) static void __init gta02_init_time(void) { s3c2442_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } MACHINE_START(NEO1973_GTA02, "GTA02") diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c/mach-h1940.c index f4710052843a..53d51aa83200 100644 --- a/arch/arm/mach-s3c24xx/mach-h1940.c +++ b/arch/arm/mach-s3c/mach-h1940.c @@ -47,20 +47,19 @@ #include <sound/uda1380.h> -#include <mach/fb.h> -#include <mach/hardware.h> -#include <mach/regs-clock.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> -#include <mach/gpio-samsung.h> - -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/gpio-cfg.h> -#include <plat/pm.h> -#include <plat/samsung-time.h> - -#include "common.h" +#include <linux/platform_data/fb-s3c2410.h> +#include "map.h" +#include "hardware-s3c24xx.h" +#include "regs-clock.h" +#include "regs-gpio.h" +#include "gpio-samsung.h" + +#include "cpu.h" +#include "devs.h" +#include "gpio-cfg.h" +#include "pm.h" + +#include "s3c24xx.h" #include "h1940.h" #define H1940_LATCH ((void __force __iomem *)0xF8000000) @@ -180,9 +179,9 @@ static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = { .cfg_gpio = s3c24xx_ts_cfg_gpio, }; -/** +/* * Set lcd on or off - **/ + */ static struct s3c2410fb_display h1940_lcd __initdata = { .lcdcon5= S3C2410_LCDCON5_FRM565 | \ S3C2410_LCDCON5_INVVLINE | \ @@ -211,12 +210,16 @@ static struct s3c2410fb_mach_info h1940_fb_info __initdata = { .lpcsel = 0x02, .gpccon = 0xaa940659, .gpccon_mask = 0xffffc0f0, + .gpccon_reg = S3C2410_GPCCON, .gpcup = 0x0000ffff, .gpcup_mask = 0xffffffff, + .gpcup_reg = S3C2410_GPCUP, .gpdcon = 0xaa84aaa0, .gpdcon_mask = 0xffffffff, + .gpdcon_reg = S3C2410_GPDCON, .gpdup = 0x0000faff, .gpdup_mask = 0xffffffff, + .gpdup_reg = S3C2410_GPDUP, }; static int power_supply_init(struct device *dev) @@ -446,6 +449,8 @@ static struct platform_device h1940_device_bluetooth = { static void h1940_set_mmc_power(unsigned char power_mode, unsigned short vdd) { + s3c24xx_mci_def_set_power(power_mode, vdd); + switch (power_mode) { case MMC_POWER_OFF: gpio_set_value(H1940_LATCH_SD_POWER, 0); @@ -468,13 +473,36 @@ static struct gpiod_lookup_table h1940_mmc_gpio_table = { .dev_id = "s3c2410-sdi", .table = { /* Card detect S3C2410_GPF(5) */ - GPIO_LOOKUP("GPF", 5, "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOF", 5, "cd", GPIO_ACTIVE_LOW), /* Write protect S3C2410_GPH(8) */ - GPIO_LOOKUP("GPH", 8, "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOH", 8, "wp", GPIO_ACTIVE_LOW), + /* bus pins */ + GPIO_LOOKUP_IDX("GPIOE", 5, "bus", 0, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 6, "bus", 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 7, "bus", 2, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 8, "bus", 3, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 9, "bus", 4, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH), { }, }, }; +static struct gpiod_lookup_table h1940_audio_gpio_table = { + .dev_id = "h1940-audio", + .table = { + GPIO_LOOKUP("H1940_LATCH", + H1940_LATCH_AUDIO_POWER - H1940_LATCH_GPIO(0), + "speaker-power", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("GPIOG", 4, "hp", GPIO_ACTIVE_HIGH), + { }, + }, +}; + +static struct platform_device h1940_audio = { + .name = "h1940-audio", + .id = -1, +}; + static struct pwm_lookup h1940_pwm_lookup[] = { PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight", NULL, 36296, PWM_POLARITY_NORMAL), @@ -651,13 +679,14 @@ static struct platform_device *h1940_devices[] __initdata = { &s3c_device_ts, &power_supply, &h1940_battery, + &h1940_audio, }; static void __init h1940_map_io(void) { s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc)); s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); /* setup PM */ @@ -674,7 +703,7 @@ static void __init h1940_map_io(void) static void __init h1940_init_time(void) { s3c2410_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } /* H1940 and RX3715 need to reserve this for suspend */ @@ -690,6 +719,10 @@ 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); + /* 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); s3c24xx_mci_set_platdata(&h1940_mmc_cfg); s3c24xx_udc_set_platdata(&h1940_udc_cfg); s3c24xx_ts_set_platdata(&h1940_ts_cfg); diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c/mach-hmt.c index e7080215c624..b287e9987311 100644 --- a/arch/arm/mach-s3c64xx/mach-hmt.c +++ b/arch/arm/mach-s3c/mach-hmt.c @@ -25,23 +25,21 @@ #include <asm/mach/irq.h> #include <video/samsung_fimd.h> -#include <mach/hardware.h> -#include <mach/map.h> +#include "map.h" #include <mach/irqs.h> #include <asm/irq.h> #include <asm/mach-types.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <mach/gpio-samsung.h> -#include <plat/fb.h> +#include "gpio-samsung.h" +#include "fb.h" #include <linux/platform_data/mtd-nand-s3c2410.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/samsung-time.h> +#include "devs.h" +#include "cpu.h" -#include "common.h" +#include "s3c64xx.h" #define UCON S3C2410_UCON_DEFAULT #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE) @@ -199,7 +197,7 @@ static struct s3c2410_platform_nand hmt_nand_info = { .twrph1 = 40, .nr_sets = ARRAY_SIZE(hmt_nand_sets), .sets = hmt_nand_sets, - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; static struct gpio_led hmt_leds[] = { @@ -251,7 +249,7 @@ static void __init hmt_map_io(void) s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc)); s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4); } static void __init hmt_machine_init(void) @@ -280,6 +278,5 @@ MACHINE_START(HMT, "Airgoo-HMT") .init_irq = s3c6410_init_irq, .map_io = hmt_map_io, .init_machine = hmt_machine_init, - .init_time = samsung_timer_init, - .restart = s3c64xx_restart, + .init_time = s3c64xx_timer_init, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-jive.c b/arch/arm/mach-s3c/mach-jive.c index 885e8f12e4b9..2a29c3eca559 100644 --- a/arch/arm/mach-s3c24xx/mach-jive.c +++ b/arch/arm/mach-s3c/mach-jive.c @@ -31,10 +31,10 @@ #include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> -#include <mach/fb.h> -#include <mach/gpio-samsung.h> +#include "hardware-s3c24xx.h" +#include "regs-gpio.h" +#include <linux/platform_data/fb-s3c2410.h> +#include "gpio-samsung.h" #include <asm/mach-types.h> @@ -43,14 +43,13 @@ #include <linux/mtd/nand_ecc.h> #include <linux/mtd/partitions.h> -#include <plat/gpio-cfg.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/pm.h> +#include "gpio-cfg.h" +#include "devs.h" +#include "cpu.h" +#include "pm.h" #include <linux/platform_data/usb-s3c2410_udc.h> -#include <plat/samsung-time.h> -#include "common.h" +#include "s3c24xx.h" #include "s3c2412-power.h" static struct map_desc jive_iodesc[] __initdata = { @@ -228,7 +227,7 @@ static struct s3c2410_platform_nand __initdata jive_nand_info = { .twrph1 = 40, .sets = jive_nand_sets, .nr_sets = ARRAY_SIZE(jive_nand_sets), - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; static int __init jive_mtdset(char *options) @@ -321,6 +320,7 @@ static struct s3c2410fb_mach_info jive_lcd_config = { * data. */ .gpcup = (0xf << 1) | (0x3f << 10), + .gpcup_reg = S3C2410_GPCUP, .gpccon = (S3C2410_GPC1_VCLK | S3C2410_GPC2_VLINE | S3C2410_GPC3_VFRAME | S3C2410_GPC4_VM | @@ -334,8 +334,12 @@ static struct s3c2410fb_mach_info jive_lcd_config = { S3C2410_GPCCON_MASK(12) | S3C2410_GPCCON_MASK(13) | S3C2410_GPCCON_MASK(14) | S3C2410_GPCCON_MASK(15)), + .gpccon_reg = S3C2410_GPCCON, + .gpdup = (0x3f << 2) | (0x3f << 10), + .gpdup_reg = S3C2410_GPDUP, + .gpdcon = (S3C2410_GPD2_VD10 | S3C2410_GPD3_VD11 | S3C2410_GPD4_VD12 | S3C2410_GPD5_VD13 | S3C2410_GPD6_VD14 | S3C2410_GPD7_VD15 | @@ -349,6 +353,8 @@ static struct s3c2410fb_mach_info jive_lcd_config = { S3C2410_GPDCON_MASK(10) | S3C2410_GPDCON_MASK(11)| S3C2410_GPDCON_MASK(12) | S3C2410_GPDCON_MASK(13)| S3C2410_GPDCON_MASK(14) | S3C2410_GPDCON_MASK(15)), + + .gpdcon_reg = S3C2410_GPDCON, }; /* ILI9320 support. */ @@ -523,13 +529,13 @@ static void __init jive_map_io(void) { s3c24xx_init_io(jive_iodesc, ARRAY_SIZE(jive_iodesc)); s3c24xx_init_uarts(jive_uartcfgs, ARRAY_SIZE(jive_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init jive_init_time(void) { s3c2412_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void jive_power_off(void) diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c/mach-mini2440.c index 235749448311..dc22ab839b95 100644 --- a/arch/arm/mach-s3c24xx/mach-mini2440.c +++ b/arch/arm/mach-s3c/mach-mini2440.c @@ -30,15 +30,13 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/hardware.h> -#include <mach/fb.h> +#include <linux/platform_data/fb-s3c2410.h> #include <asm/mach-types.h> -#include <mach/regs-gpio.h> +#include "regs-gpio.h" #include <linux/platform_data/leds-s3c24xx.h> -#include <mach/regs-lcd.h> #include <mach/irqs.h> -#include <mach/gpio-samsung.h> +#include "gpio-samsung.h" #include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/mmc-s3cmci.h> @@ -49,14 +47,13 @@ #include <linux/mtd/nand_ecc.h> #include <linux/mtd/partitions.h> -#include <plat/gpio-cfg.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/samsung-time.h> +#include "gpio-cfg.h" +#include "devs.h" +#include "cpu.h" #include <sound/s3c24xx_uda134x.h> -#include "common.h" +#include "s3c24xx.h" #define MACH_MINI2440_DM9K_BASE (S3C2410_CS4 + 0x300) @@ -215,6 +212,9 @@ static struct s3c2410fb_mach_info mini2440_fb_info __initdata = { S3C2410_GPCCON_MASK(12) | S3C2410_GPCCON_MASK(13) | S3C2410_GPCCON_MASK(14) | S3C2410_GPCCON_MASK(15)), + .gpccon_reg = S3C2410_GPCCON, + .gpcup_reg = S3C2410_GPCUP, + .gpdup = (0x3f << 2) | (0x3f << 10), .gpdcon = (S3C2410_GPD2_VD10 | S3C2410_GPD3_VD11 | @@ -230,13 +230,16 @@ static struct s3c2410fb_mach_info mini2440_fb_info __initdata = { S3C2410_GPDCON_MASK(10) | S3C2410_GPDCON_MASK(11)| S3C2410_GPDCON_MASK(12) | S3C2410_GPDCON_MASK(13)| S3C2410_GPDCON_MASK(14) | S3C2410_GPDCON_MASK(15)), + + .gpdcon_reg = S3C2410_GPDCON, + .gpdup_reg = S3C2410_GPDUP, }; /* MMC/SD */ static struct s3c24xx_mci_pdata mini2440_mmc_cfg __initdata = { .wprotect_invert = 1, - .set_power = NULL, + .set_power = s3c24xx_mci_def_set_power, .ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34, }; @@ -244,9 +247,16 @@ static struct gpiod_lookup_table mini2440_mmc_gpio_table = { .dev_id = "s3c2410-sdi", .table = { /* Card detect S3C2410_GPG(8) */ - GPIO_LOOKUP("GPG", 8, "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOG", 8, "cd", GPIO_ACTIVE_LOW), /* Write protect S3C2410_GPH(8) */ - GPIO_LOOKUP("GPH", 8, "wp", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("GPIOH", 8, "wp", GPIO_ACTIVE_HIGH), + /* bus pins */ + GPIO_LOOKUP_IDX("GPIOE", 5, "bus", 0, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 6, "bus", 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 7, "bus", 2, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 8, "bus", 3, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 9, "bus", 4, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH), { }, }, }; @@ -296,7 +306,7 @@ static struct s3c2410_platform_nand mini2440_nand_info __initdata = { .nr_sets = ARRAY_SIZE(mini2440_nand_sets), .sets = mini2440_nand_sets, .ignore_unset_ecc = 1, - .ecc_mode = NAND_ECC_HW, + .engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST, }; /* DM9000AEP 10/100 ethernet controller */ @@ -587,13 +597,13 @@ static void __init mini2440_map_io(void) { s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc)); s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init mini2440_init_time(void) { s3c2440_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } /* @@ -716,6 +726,11 @@ static void __init mini2440_init(void) s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP); s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT); } + + /* 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); + if (features.lcd_index != -1) { int li; diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c/mach-mini6410.c index 0dd36ae49e6a..741fa1f09694 100644 --- a/arch/arm/mach-s3c64xx/mach-mini6410.c +++ b/arch/arm/mach-s3c/mach-mini6410.c @@ -23,27 +23,26 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/map.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> - -#include <plat/adc.h> -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/fb.h> +#include "map.h" +#include "regs-gpio.h" +#include "gpio-samsung.h" + +#include <linux/soc/samsung/s3c-adc.h> +#include "cpu.h" +#include "devs.h" +#include "fb.h" #include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/mmc-sdhci-s3c.h> -#include <plat/sdhci.h> +#include "sdhci.h" #include <linux/platform_data/touchscreen-s3c2410.h> #include <mach/irqs.h> #include <video/platform_lcd.h> #include <video/samsung_fimd.h> -#include <plat/samsung-time.h> -#include "common.h" -#include "regs-modem.h" -#include "regs-srom.h" +#include "s3c64xx.h" +#include "regs-modem-s3c64xx.h" +#include "regs-srom-s3c64xx.h" #define UCON S3C2410_UCON_DEFAULT #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) @@ -136,7 +135,7 @@ static struct s3c2410_platform_nand mini6410_nand_info = { .twrph1 = 40, .nr_sets = ARRAY_SIZE(mini6410_nand_sets), .sets = mini6410_nand_sets, - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; static struct s3c_fb_pd_win mini6410_lcd_type0_fb_win = { @@ -238,7 +237,7 @@ static void __init mini6410_map_io(void) s3c64xx_init_io(NULL, 0); s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4); /* set the LCD type */ tmp = __raw_readl(S3C64XX_SPCON); @@ -362,6 +361,5 @@ MACHINE_START(MINI6410, "MINI6410") .init_irq = s3c6410_init_irq, .map_io = mini6410_map_io, .init_machine = mini6410_machine_init, - .init_time = samsung_timer_init, - .restart = s3c64xx_restart, + .init_time = s3c64xx_timer_init, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-n30.c b/arch/arm/mach-s3c/mach-n30.c index 998ccff3c174..e40c1fcf418c 100644 --- a/arch/arm/mach-s3c24xx/mach-n30.c +++ b/arch/arm/mach-s3c/mach-n30.c @@ -27,15 +27,15 @@ #include <linux/io.h> #include <linux/mmc/host.h> -#include <mach/hardware.h> +#include "hardware-s3c24xx.h" #include <asm/irq.h> #include <asm/mach-types.h> -#include <mach/fb.h> +#include <linux/platform_data/fb-s3c2410.h> #include <linux/platform_data/leds-s3c24xx.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> -#include <mach/gpio-samsung.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" +#include "gpio-cfg.h" #include <asm/mach/arch.h> #include <asm/mach/irq.h> @@ -43,14 +43,12 @@ #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/gpio-cfg.h> +#include "cpu.h" +#include "devs.h" #include <linux/platform_data/mmc-s3cmci.h> #include <linux/platform_data/usb-s3c2410_udc.h> -#include <plat/samsung-time.h> -#include "common.h" +#include "s3c24xx.h" static struct map_desc n30_iodesc[] __initdata = { /* nothing here yet */ @@ -368,6 +366,8 @@ static struct s3c2410fb_mach_info n30_fb_info __initdata = { static void n30_sdi_set_power(unsigned char power_mode, unsigned short vdd) { + s3c24xx_mci_def_set_power(power_mode, vdd); + switch (power_mode) { case MMC_POWER_ON: case MMC_POWER_UP: @@ -389,10 +389,17 @@ static struct gpiod_lookup_table n30_mci_gpio_table = { .dev_id = "s3c2410-sdi", .table = { /* Card detect S3C2410_GPF(1) */ - GPIO_LOOKUP("GPF", 1, "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOF", 1, "cd", GPIO_ACTIVE_LOW), /* Write protect S3C2410_GPG(10) */ - GPIO_LOOKUP("GPG", 10, "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOG", 10, "wp", GPIO_ACTIVE_LOW), { }, + /* bus pins */ + GPIO_LOOKUP_IDX("GPIOE", 5, "bus", 0, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 6, "bus", 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 7, "bus", 2, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 8, "bus", 3, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 9, "bus", 4, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH), }, }; @@ -572,13 +579,13 @@ static void __init n30_map_io(void) s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc)); n30_hwinit(); s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init n30_init_time(void) { s3c2410_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } /* GPB3 is the line that controls the pull-up for the USB D+ line */ @@ -600,6 +607,10 @@ static void __init n30_init(void) S3C2410_MISCCR_USBSUSPND0 | S3C2410_MISCCR_USBSUSPND1, 0x0); + /* 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); + if (machine_is_n30()) { /* Turn off suspend on both USB ports, and switch the * selectable USB port to USB device mode. */ diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c/mach-ncp.c index 13fea5c86ca3..1a45bed56622 100644 --- a/arch/arm/mach-s3c64xx/mach-ncp.c +++ b/arch/arm/mach-s3c/mach-ncp.c @@ -25,20 +25,18 @@ #include <asm/mach/irq.h> #include <mach/irqs.h> -#include <mach/hardware.h> -#include <mach/map.h> +#include "map.h" #include <asm/irq.h> #include <asm/mach-types.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/fb.h> +#include "fb.h" -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/samsung-time.h> +#include "devs.h" +#include "cpu.h" -#include "common.h" +#include "s3c64xx.h" #define UCON S3C2410_UCON_DEFAULT #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE @@ -81,7 +79,7 @@ static void __init ncp_map_io(void) s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc)); s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4); } static void __init ncp_machine_init(void) @@ -98,6 +96,5 @@ MACHINE_START(NCP, "NCP") .init_irq = s3c6410_init_irq, .map_io = ncp_map_io, .init_machine = ncp_machine_init, - .init_time = samsung_timer_init, - .restart = s3c64xx_restart, + .init_time = s3c64xx_timer_init, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-nexcoder.c b/arch/arm/mach-s3c/mach-nexcoder.c index c2f34758ccb6..2a454c919658 100644 --- a/arch/arm/mach-s3c24xx/mach-nexcoder.c +++ b/arch/arm/mach-s3c/mach-nexcoder.c @@ -28,21 +28,19 @@ #include <asm/mach/irq.h> #include <asm/setup.h> -#include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach-types.h> //#include <asm/debug-ll.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/gpio-cfg.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/samsung-time.h> +#include "gpio-cfg.h" +#include "devs.h" +#include "cpu.h" -#include "common.h" +#include "s3c24xx.h" static struct map_desc nexcoder_iodesc[] __initdata = { /* nothing here yet */ @@ -131,7 +129,7 @@ static void __init nexcoder_map_io(void) { s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc)); s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); nexcoder_sensorboard_init(); } @@ -139,12 +137,17 @@ static void __init nexcoder_map_io(void) static void __init nexcoder_init_time(void) { s3c2440_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init nexcoder_init(void) { s3c_i2c0_set_platdata(NULL); + + /* 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); + platform_add_devices(nexcoder_devices, ARRAY_SIZE(nexcoder_devices)); }; diff --git a/arch/arm/mach-s3c24xx/mach-osiris-dvs.c b/arch/arm/mach-s3c/mach-osiris-dvs.c index 5d819b6ea428..2e283aedab65 100644 --- a/arch/arm/mach-s3c24xx/mach-osiris-dvs.c +++ b/arch/arm/mach-s3c/mach-osiris-dvs.c @@ -14,8 +14,8 @@ #include <linux/mfd/tps65010.h> -#include <plat/cpu-freq.h> -#include <mach/gpio-samsung.h> +#include <linux/soc/samsung/s3c-cpu-freq.h> +#include "gpio-samsung.h" #define OSIRIS_GPIO_DVS S3C2410_GPB(5) diff --git a/arch/arm/mach-s3c24xx/mach-osiris.c b/arch/arm/mach-s3c/mach-osiris.c index ee3630cb236a..81744ca67d1d 100644 --- a/arch/arm/mach-s3c24xx/mach-osiris.c +++ b/arch/arm/mach-s3c/mach-osiris.c @@ -36,20 +36,17 @@ #include <linux/mtd/nand_ecc.h> #include <linux/mtd/partitions.h> -#include <plat/cpu.h> -#include <plat/cpu-freq.h> -#include <plat/devs.h> -#include <plat/gpio-cfg.h> -#include <plat/samsung-time.h> - -#include <mach/hardware.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> -#include <mach/gpio-samsung.h> - -#include "common.h" +#include "cpu.h" +#include <linux/soc/samsung/s3c-cpu-freq.h> +#include "devs.h" +#include "gpio-cfg.h" + +#include "regs-gpio.h" +#include "gpio-samsung.h" + +#include "s3c24xx.h" #include "osiris.h" -#include "regs-mem.h" +#include "regs-mem-s3c24xx.h" /* onboard perihperal map */ @@ -234,7 +231,7 @@ static struct s3c2410_platform_nand __initdata osiris_nand_info = { .nr_sets = ARRAY_SIZE(osiris_nand_sets), .sets = osiris_nand_sets, .select_chip = osiris_nand_select, - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; /* PCMCIA control and configuration */ @@ -359,7 +356,7 @@ static void __init osiris_map_io(void) s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc)); s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); /* check for the newer revision boards with large page nand */ @@ -384,7 +381,7 @@ static void __init osiris_map_io(void) static void __init osiris_init_time(void) { s3c2440_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init osiris_init(void) diff --git a/arch/arm/mach-s3c24xx/mach-otom.c b/arch/arm/mach-s3c/mach-otom.c index 4e24d89e870b..460ee97766cd 100644 --- a/arch/arm/mach-s3c24xx/mach-otom.c +++ b/arch/arm/mach-s3c/mach-otom.c @@ -22,14 +22,13 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> -#include <mach/regs-gpio.h> +#include "gpio-samsung.h" +#include "gpio-cfg.h" -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/samsung-time.h> +#include "cpu.h" +#include "devs.h" -#include "common.h" +#include "s3c24xx.h" #include "otom.h" static struct map_desc otom11_iodesc[] __initdata = { @@ -95,18 +94,22 @@ static void __init otom11_map_io(void) { s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc)); s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init otom11_init_time(void) { s3c2410_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init otom11_init(void) { s3c_i2c0_set_platdata(NULL); + + /* 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); platform_add_devices(otom11_devices, ARRAY_SIZE(otom11_devices)); } diff --git a/arch/arm/mach-s3c24xx/mach-qt2410.c b/arch/arm/mach-s3c/mach-qt2410.c index ff9e3197309b..151e8e373d40 100644 --- a/arch/arm/mach-s3c24xx/mach-qt2410.c +++ b/arch/arm/mach-s3c/mach-qt2410.c @@ -28,26 +28,23 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach-types.h> #include <linux/platform_data/leds-s3c24xx.h> -#include <mach/regs-lcd.h> -#include <mach/fb.h> +#include <linux/platform_data/fb-s3c2410.h> #include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/usb-s3c2410_udc.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <mach/gpio-samsung.h> +#include "gpio-samsung.h" -#include <plat/gpio-cfg.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/pm.h> -#include <plat/samsung-time.h> +#include "gpio-cfg.h" +#include "devs.h" +#include "cpu.h" +#include "pm.h" -#include "common.h" -#include "common-smdk.h" +#include "s3c24xx.h" +#include "common-smdk-s3c24xx.h" static struct map_desc qt2410_iodesc[] __initdata = { { 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE } @@ -225,6 +222,20 @@ static struct gpiod_lookup_table qt2410_spi_gpiod_table = { }, }; +static struct gpiod_lookup_table qt2410_mmc_gpiod_table = { + .dev_id = "s3c2410-sdi", + .table = { + /* bus pins */ + GPIO_LOOKUP_IDX("GPIOE", 5, "bus", 0, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 6, "bus", 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 7, "bus", 2, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 8, "bus", 3, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 9, "bus", 4, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH), + { }, + }, +}; + /* Board devices */ static struct platform_device *qt2410_devices[] __initdata = { @@ -287,7 +298,7 @@ static struct s3c2410_platform_nand __initdata qt2410_nand_info = { .twrph1 = 20, .nr_sets = ARRAY_SIZE(qt2410_nand_sets), .sets = qt2410_nand_sets, - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; /* UDC */ @@ -309,13 +320,13 @@ static void __init qt2410_map_io(void) { s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc)); s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init qt2410_init_time(void) { s3c2410_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init qt2410_machine_init(void) @@ -343,9 +354,13 @@ static void __init qt2410_machine_init(void) s3c24xx_udc_set_platdata(&qt2410_udc_cfg); s3c_i2c0_set_platdata(NULL); + /* 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); gpiod_add_lookup_table(&qt2410_spi_gpiod_table); s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE); gpiod_add_lookup_table(&qt2410_led_gpio_table); + gpiod_add_lookup_table(&qt2410_mmc_gpiod_table); platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices)); s3c_pm_init(); } diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c/mach-real6410.c index 0ff88b6859c4..9d218a53d631 100644 --- a/arch/arm/mach-s3c64xx/mach-real6410.c +++ b/arch/arm/mach-s3c/mach-real6410.c @@ -24,25 +24,24 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/map.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> +#include "map.h" +#include "regs-gpio.h" +#include "gpio-samsung.h" #include <mach/irqs.h> -#include <plat/adc.h> -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/fb.h> +#include <linux/soc/samsung/s3c-adc.h> +#include "cpu.h" +#include "devs.h" +#include "fb.h" #include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/touchscreen-s3c2410.h> #include <video/platform_lcd.h> #include <video/samsung_fimd.h> -#include <plat/samsung-time.h> -#include "common.h" -#include "regs-modem.h" -#include "regs-srom.h" +#include "s3c64xx.h" +#include "regs-modem-s3c64xx.h" +#include "regs-srom-s3c64xx.h" #define UCON S3C2410_UCON_DEFAULT #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) @@ -188,7 +187,7 @@ static struct s3c2410_platform_nand real6410_nand_info = { .twrph1 = 40, .nr_sets = ARRAY_SIZE(real6410_nand_sets), .sets = real6410_nand_sets, - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; static struct platform_device *real6410_devices[] __initdata = { @@ -208,7 +207,7 @@ static void __init real6410_map_io(void) s3c64xx_init_io(NULL, 0); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4); /* set the LCD type */ tmp = __raw_readl(S3C64XX_SPCON); @@ -330,6 +329,5 @@ MACHINE_START(REAL6410, "REAL6410") .init_irq = s3c6410_init_irq, .map_io = real6410_map_io, .init_machine = real6410_machine_init, - .init_time = samsung_timer_init, - .restart = s3c64xx_restart, + .init_time = s3c64xx_timer_init, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c/mach-rx1950.c index fde98b175c75..b9758f0a9a14 100644 --- a/arch/arm/mach-s3c24xx/mach-rx1950.c +++ b/arch/arm/mach-s3c/mach-rx1950.c @@ -42,21 +42,20 @@ #include <linux/platform_data/mtd-nand-s3c2410.h> #include <linux/platform_data/touchscreen-s3c2410.h> #include <linux/platform_data/usb-s3c2410_udc.h> +#include <linux/platform_data/fb-s3c2410.h> #include <sound/uda1380.h> -#include <mach/fb.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> -#include <mach/gpio-samsung.h> +#include "hardware-s3c24xx.h" +#include "regs-gpio.h" +#include "gpio-samsung.h" -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/pm.h> -#include <plat/samsung-time.h> -#include <plat/gpio-cfg.h> +#include "cpu.h" +#include "devs.h" +#include "pm.h" +#include "gpio-cfg.h" -#include "common.h" +#include "s3c24xx.h" #include "h1940.h" #define LCD_PWM_PERIOD 192960 @@ -361,14 +360,17 @@ static struct s3c2410fb_mach_info rx1950_lcd_cfg = { .lpcsel = 0x02, .gpccon = 0xaa9556a9, .gpccon_mask = 0xffc003fc, + .gpccon_reg = S3C2410_GPCCON, .gpcup = 0x0000ffff, .gpcup_mask = 0xffffffff, + .gpcup_reg = S3C2410_GPCUP, .gpdcon = 0xaa90aaa1, .gpdcon_mask = 0xffc0fff0, + .gpdcon_reg = S3C2410_GPDCON, .gpdup = 0x0000fcfd, .gpdup_mask = 0xffffffff, - + .gpdup_reg = S3C2410_GPDUP, }; static struct pwm_lookup rx1950_pwm_lookup[] = { @@ -549,6 +551,8 @@ static struct platform_device rx1950_backlight = { static void rx1950_set_mmc_power(unsigned char power_mode, unsigned short vdd) { + s3c24xx_mci_def_set_power(power_mode, vdd); + switch (power_mode) { case MMC_POWER_OFF: gpio_direction_output(S3C2410_GPJ(1), 0); @@ -571,9 +575,16 @@ static struct gpiod_lookup_table rx1950_mmc_gpio_table = { .dev_id = "s3c2410-sdi", .table = { /* Card detect S3C2410_GPF(5) */ - GPIO_LOOKUP("GPF", 5, "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOF", 5, "cd", GPIO_ACTIVE_LOW), /* Write protect S3C2410_GPH(8) */ - GPIO_LOOKUP("GPH", 8, "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOH", 8, "wp", GPIO_ACTIVE_LOW), + /* bus pins */ + GPIO_LOOKUP_IDX("GPIOE", 5, "bus", 0, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 6, "bus", 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 7, "bus", 2, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 8, "bus", 3, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 9, "bus", 4, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH), { }, }, }; @@ -620,7 +631,7 @@ static struct s3c2410_platform_nand rx1950_nand_info = { .twrph1 = 15, .nr_sets = ARRAY_SIZE(rx1950_nand_sets), .sets = rx1950_nand_sets, - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = { @@ -728,6 +739,20 @@ static struct i2c_board_info rx1950_i2c_devices[] = { }, }; +static struct gpiod_lookup_table rx1950_audio_gpio_table = { + .dev_id = "rx1950-audio", + .table = { + GPIO_LOOKUP("GPIOG", 12, "hp-gpio", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("GPIOA", 1, "speaker-power", GPIO_ACTIVE_HIGH), + { }, + }, +}; + +static struct platform_device rx1950_audio = { + .name = "rx1950-audio", + .id = -1, +}; + static struct platform_device *rx1950_devices[] __initdata = { &s3c2410_device_dclk, &s3c_device_lcd, @@ -746,13 +771,14 @@ static struct platform_device *rx1950_devices[] __initdata = { &power_supply, &rx1950_battery, &rx1950_leds, + &rx1950_audio, }; static void __init rx1950_map_io(void) { s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc)); s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); /* setup PM */ @@ -766,7 +792,7 @@ static void __init rx1950_map_io(void) static void __init rx1950_init_time(void) { s3c2442_init_clocks(16934000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init rx1950_init_machine(void) @@ -813,6 +839,10 @@ static void __init rx1950_init_machine(void) gpio_direction_output(S3C2410_GPJ(6), 0); pwm_add_table(rx1950_pwm_lookup, ARRAY_SIZE(rx1950_pwm_lookup)); + gpiod_add_lookup_table(&rx1950_audio_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); platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices)); i2c_register_board_info(0, rx1950_i2c_devices, diff --git a/arch/arm/mach-s3c24xx/mach-rx3715.c b/arch/arm/mach-s3c/mach-rx3715.c index 995f1ff34a1b..a03662a47b38 100644 --- a/arch/arm/mach-s3c24xx/mach-rx3715.c +++ b/arch/arm/mach-s3c/mach-rx3715.c @@ -30,22 +30,20 @@ #include <asm/mach/map.h> #include <linux/platform_data/mtd-nand-s3c2410.h> +#include <linux/platform_data/fb-s3c2410.h> #include <asm/irq.h> #include <asm/mach-types.h> -#include <mach/fb.h> -#include <mach/hardware.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> -#include <mach/gpio-samsung.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" +#include "gpio-cfg.h" -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/pm.h> -#include <plat/samsung-time.h> +#include "cpu.h" +#include "devs.h" +#include "pm.h" -#include "common.h" +#include "s3c24xx.h" #include "h1940.h" static struct map_desc rx3715_iodesc[] __initdata = { @@ -125,13 +123,17 @@ static struct s3c2410fb_mach_info rx3715_fb_info __initdata = { .gpccon = 0xaa955699, .gpccon_mask = 0xffc003cc, + .gpccon_reg = S3C2410_GPCCON, .gpcup = 0x0000ffff, .gpcup_mask = 0xffffffff, + .gpcup_reg = S3C2410_GPCUP, .gpdcon = 0xaa95aaa1, .gpdcon_mask = 0xffc0fff0, + .gpdcon_reg = S3C2410_GPDCON, .gpdup = 0x0000faff, .gpdup_mask = 0xffffffff, + .gpdup_reg = S3C2410_GPDUP, }; static struct mtd_partition __initdata rx3715_nand_part[] = { @@ -158,7 +160,7 @@ static struct s3c2410_platform_nand __initdata rx3715_nand_info = { .twrph1 = 15, .nr_sets = ARRAY_SIZE(rx3715_nand_sets), .sets = rx3715_nand_sets, - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; static struct platform_device *rx3715_devices[] __initdata = { @@ -174,13 +176,13 @@ static void __init rx3715_map_io(void) { s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc)); s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init rx3715_init_time(void) { s3c2440_init_clocks(16934000); - samsung_timer_init(); + s3c24xx_timer_init(); } /* H1940 and RX3715 need to reserve this for suspend */ @@ -199,6 +201,9 @@ static void __init rx3715_init_machine(void) s3c_nand_set_platdata(&rx3715_nand_info); s3c24xx_fb_set_platdata(&rx3715_fb_info); + /* 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); platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices)); } diff --git a/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c b/arch/arm/mach-s3c/mach-s3c2416-dt.c index aa7102713b37..418544d3015d 100644 --- a/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c +++ b/arch/arm/mach-s3c/mach-s3c2416-dt.c @@ -16,12 +16,12 @@ #include <linux/serial_s3c.h> #include <asm/mach/arch.h> -#include <mach/map.h> +#include "map.h" -#include <plat/cpu.h> -#include <plat/pm.h> +#include "cpu.h" +#include "pm.h" -#include "common.h" +#include "s3c24xx.h" static void __init s3c2416_dt_map_io(void) { diff --git a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c b/arch/arm/mach-s3c/mach-s3c64xx-dt.c index 1724f5ea5c46..00169c103862 100644 --- a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c +++ b/arch/arm/mach-s3c/mach-s3c64xx-dt.c @@ -8,11 +8,10 @@ #include <asm/mach/map.h> #include <asm/system_misc.h> -#include <plat/cpu.h> -#include <mach/map.h> +#include "cpu.h" +#include "map.h" -#include "common.h" -#include "watchdog-reset.h" +#include "s3c64xx.h" /* * IO mapping for shared system controller IP. @@ -39,20 +38,6 @@ static void __init s3c64xx_dt_map_io(void) panic("SoC is not S3C64xx!"); } -static void __init s3c64xx_dt_init_machine(void) -{ - samsung_wdt_reset_of_init(); -} - -static void s3c64xx_dt_restart(enum reboot_mode mode, const char *cmd) -{ - if (mode != REBOOT_SOFT) - samsung_wdt_reset(); - - /* if all else fails, or mode was for soft, jump to 0 */ - soft_restart(0); -} - static const char *const s3c64xx_dt_compat[] __initconst = { "samsung,s3c6400", "samsung,s3c6410", @@ -63,6 +48,4 @@ DT_MACHINE_START(S3C6400_DT, "Samsung S3C64xx (Flattened Device Tree)") /* Maintainer: Tomasz Figa <tomasz.figa@gmail.com> */ .dt_compat = s3c64xx_dt_compat, .map_io = s3c64xx_dt_map_io, - .init_machine = s3c64xx_dt_init_machine, - .restart = s3c64xx_dt_restart, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c/mach-smartq.c index 5025db607c0f..5b6e7c2a85ef 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.c +++ b/arch/arm/mach-s3c/mach-smartq.c @@ -18,25 +18,24 @@ #include <asm/mach-types.h> #include <asm/mach/map.h> -#include <mach/map.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> +#include "map.h" +#include "regs-gpio.h" +#include "gpio-samsung.h" -#include <plat/cpu.h> -#include <plat/devs.h> +#include "cpu.h" +#include "devs.h" #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/gpio-cfg.h> +#include "gpio-cfg.h" #include <linux/platform_data/hwmon-s3c.h> #include <linux/platform_data/usb-ohci-s3c2410.h> -#include <plat/sdhci.h> +#include "sdhci.h" #include <linux/platform_data/touchscreen-s3c2410.h> #include <video/platform_lcd.h> -#include <plat/samsung-time.h> -#include "common.h" +#include "s3c64xx.h" #include "mach-smartq.h" -#include "regs-modem.h" +#include "regs-modem-s3c64xx.h" #define UCON S3C2410_UCON_DEFAULT #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE) @@ -384,7 +383,7 @@ void __init smartq_map_io(void) s3c64xx_set_xtal_freq(12000000); s3c64xx_set_xusbxti_freq(12000000); s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4); smartq_lcd_mode_set(); } diff --git a/arch/arm/mach-s3c64xx/mach-smartq.h b/arch/arm/mach-s3c/mach-smartq.h index f98132f4f430..f98132f4f430 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.h +++ b/arch/arm/mach-s3c/mach-smartq.h diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c/mach-smartq5.c index 44e9edb144fa..8c940227e810 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq5.c +++ b/arch/arm/mach-s3c/mach-smartq5.c @@ -15,17 +15,16 @@ #include <video/samsung_fimd.h> #include <mach/irqs.h> -#include <mach/map.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> +#include "map.h" +#include "regs-gpio.h" +#include "gpio-samsung.h" -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/fb.h> -#include <plat/gpio-cfg.h> -#include <plat/samsung-time.h> +#include "cpu.h" +#include "devs.h" +#include "fb.h" +#include "gpio-cfg.h" -#include "common.h" +#include "s3c64xx.h" #include "mach-smartq.h" static struct gpio_led smartq5_leds[] = { @@ -151,6 +150,5 @@ MACHINE_START(SMARTQ5, "SmartQ 5") .init_irq = s3c6410_init_irq, .map_io = smartq_map_io, .init_machine = smartq5_machine_init, - .init_time = samsung_timer_init, - .restart = s3c64xx_restart, + .init_time = s3c64xx_timer_init, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c/mach-smartq7.c index 815ee7d0b5e3..ab243969d6d0 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq7.c +++ b/arch/arm/mach-s3c/mach-smartq7.c @@ -15,17 +15,16 @@ #include <video/samsung_fimd.h> #include <mach/irqs.h> -#include <mach/map.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> +#include "map.h" +#include "regs-gpio.h" +#include "gpio-samsung.h" -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/fb.h> -#include <plat/gpio-cfg.h> -#include <plat/samsung-time.h> +#include "cpu.h" +#include "devs.h" +#include "fb.h" +#include "gpio-cfg.h" -#include "common.h" +#include "s3c64xx.h" #include "mach-smartq.h" static struct gpio_led smartq7_leds[] = { @@ -167,6 +166,5 @@ MACHINE_START(SMARTQ7, "SmartQ 7") .init_irq = s3c6410_init_irq, .map_io = smartq_map_io, .init_machine = smartq7_machine_init, - .init_time = samsung_timer_init, - .restart = s3c64xx_restart, + .init_time = s3c64xx_timer_init, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-smdk2410.c b/arch/arm/mach-s3c/mach-smdk2410.c index 18dfef52c8bf..ca83d5a7d101 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2410.c +++ b/arch/arm/mach-s3c/mach-smdk2410.c @@ -19,23 +19,23 @@ #include <linux/serial_s3c.h> #include <linux/platform_device.h> #include <linux/io.h> +#include "gpio-samsung.h" +#include "gpio-cfg.h" #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach-types.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/samsung-time.h> +#include "devs.h" +#include "cpu.h" -#include "common.h" -#include "common-smdk.h" +#include "s3c24xx.h" +#include "common-smdk-s3c24xx.h" static struct map_desc smdk2410_iodesc[] __initdata = { /* nothing here yet */ @@ -81,19 +81,22 @@ static void __init smdk2410_map_io(void) { s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc)); s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init smdk2410_init_time(void) { s3c2410_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init smdk2410_init(void) { s3c_i2c0_set_platdata(NULL); platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices)); + /* 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); smdk_machine_init(); } diff --git a/arch/arm/mach-s3c24xx/mach-smdk2413.c b/arch/arm/mach-s3c/mach-smdk2413.c index ca80167f268d..c43095b321d7 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2413.c +++ b/arch/arm/mach-s3c/mach-smdk2413.c @@ -23,27 +23,26 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> #include <asm/hardware/iomd.h> #include <asm/setup.h> #include <asm/irq.h> #include <asm/mach-types.h> //#include <asm/debug-ll.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> +#include "hardware-s3c24xx.h" +#include "regs-gpio.h" #include <linux/platform_data/usb-s3c2410_udc.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <mach/gpio-samsung.h> -#include <mach/fb.h> +#include <linux/platform_data/fb-s3c2410.h> +#include "gpio-samsung.h" +#include "gpio-cfg.h" -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/samsung-time.h> +#include "devs.h" +#include "cpu.h" -#include "common.h" -#include "common-smdk.h" +#include "s3c24xx.h" +#include "common-smdk-s3c24xx.h" static struct map_desc smdk2413_iodesc[] __initdata = { }; @@ -99,13 +98,13 @@ static void __init smdk2413_map_io(void) { s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc)); s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init smdk2413_init_time(void) { s3c2412_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init smdk2413_machine_init(void) @@ -119,6 +118,9 @@ static void __init smdk2413_machine_init(void) s3c24xx_udc_set_platdata(&smdk2413_udc_cfg); s3c_i2c0_set_platdata(NULL); + /* 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); platform_add_devices(smdk2413_devices, ARRAY_SIZE(smdk2413_devices)); smdk_machine_init(); @@ -132,7 +134,7 @@ MACHINE_START(S3C2413, "S3C2413") .init_irq = s3c2412_init_irq, .map_io = smdk2413_map_io, .init_machine = smdk2413_machine_init, - .init_time = samsung_timer_init, + .init_time = s3c24xx_timer_init, MACHINE_END MACHINE_START(SMDK2412, "SMDK2412") @@ -143,7 +145,7 @@ MACHINE_START(SMDK2412, "SMDK2412") .init_irq = s3c2412_init_irq, .map_io = smdk2413_map_io, .init_machine = smdk2413_machine_init, - .init_time = samsung_timer_init, + .init_time = s3c24xx_timer_init, MACHINE_END MACHINE_START(SMDK2413, "SMDK2413") diff --git a/arch/arm/mach-s3c24xx/mach-smdk2416.c b/arch/arm/mach-s3c/mach-smdk2416.c index 61c3e45898d3..4d883a792cc6 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2416.c +++ b/arch/arm/mach-s3c/mach-smdk2416.c @@ -25,31 +25,29 @@ #include <asm/mach/irq.h> #include <video/samsung_fimd.h> -#include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach-types.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> -#include <mach/regs-s3c2443-clock.h> -#include <mach/gpio-samsung.h> +#include "hardware-s3c24xx.h" +#include "regs-gpio.h" +#include "regs-s3c2443-clock.h" +#include "gpio-samsung.h" #include <linux/platform_data/leds-s3c24xx.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/gpio-cfg.h> -#include <plat/devs.h> -#include <plat/cpu.h> +#include "gpio-cfg.h" +#include "devs.h" +#include "cpu.h" #include <linux/platform_data/mtd-nand-s3c2410.h> -#include <plat/sdhci.h> +#include "sdhci.h" #include <linux/platform_data/usb-s3c2410_udc.h> #include <linux/platform_data/s3c-hsudc.h> -#include <plat/samsung-time.h> -#include <plat/fb.h> +#include "fb.h" -#include "common.h" -#include "common-smdk.h" +#include "s3c24xx.h" +#include "common-smdk-s3c24xx.h" static struct map_desc smdk2416_iodesc[] __initdata = { /* ISA IO Space map (memory space selected by A24) */ @@ -215,14 +213,14 @@ static struct platform_device *smdk2416_devices[] __initdata = { static void __init smdk2416_init_time(void) { s3c2416_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init smdk2416_map_io(void) { s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc)); s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init smdk2416_machine_init(void) diff --git a/arch/arm/mach-s3c24xx/mach-smdk2440.c b/arch/arm/mach-s3c/mach-smdk2440.c index 7bafcd8ea104..7f6fe0db04f3 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2440.c +++ b/arch/arm/mach-s3c/mach-smdk2440.c @@ -23,22 +23,21 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach-types.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" +#include "gpio-cfg.h" -#include <mach/fb.h> +#include <linux/platform_data/fb-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/samsung-time.h> +#include "devs.h" +#include "cpu.h" -#include "common.h" -#include "common-smdk.h" +#include "s3c24xx.h" +#include "common-smdk-s3c24xx.h" static struct map_desc smdk2440_iodesc[] __initdata = { /* ISA IO Space map (memory space selected by A24) */ @@ -137,6 +136,11 @@ static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = { .gpdcon_mask = 0xffffffff, .gpdup = 0x0000faff, .gpdup_mask = 0xffffffff, + + .gpccon_reg = S3C2410_GPCCON, + .gpcup_reg = S3C2410_GPCUP, + .gpdcon_reg = S3C2410_GPDCON, + .gpdup_reg = S3C2410_GPDUP, #endif .lpcsel = ((0xCE6) & ~7) | 1<<4, @@ -154,20 +158,22 @@ static void __init smdk2440_map_io(void) { s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc)); s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init smdk2440_init_time(void) { s3c2440_init_clocks(16934400); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init smdk2440_machine_init(void) { s3c24xx_fb_set_platdata(&smdk2440_fb_info); s3c_i2c0_set_platdata(NULL); - + /* 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); platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices)); smdk_machine_init(); } diff --git a/arch/arm/mach-s3c24xx/mach-smdk2443.c b/arch/arm/mach-s3c/mach-smdk2443.c index 2358ed5ed7be..fc54c91ade56 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2443.c +++ b/arch/arm/mach-s3c/mach-smdk2443.c @@ -22,22 +22,19 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach-types.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> +#include "regs-gpio.h" -#include <mach/fb.h> +#include <linux/platform_data/fb-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/samsung-time.h> +#include "devs.h" +#include "cpu.h" -#include "common.h" -#include "common-smdk.h" +#include "s3c24xx.h" +#include "common-smdk-s3c24xx.h" static struct map_desc smdk2443_iodesc[] __initdata = { /* ISA IO Space map (memory space selected by A24) */ @@ -112,13 +109,13 @@ static void __init smdk2443_map_io(void) { s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc)); s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init smdk2443_init_time(void) { s3c2443_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init smdk2443_machine_init(void) diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c/mach-smdk6400.c index cbd16843c7d1..827221398d6c 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6400.c +++ b/arch/arm/mach-s3c/mach-smdk6400.c @@ -23,16 +23,14 @@ #include <asm/mach/irq.h> #include <mach/irqs.h> -#include <mach/hardware.h> -#include <mach/map.h> +#include "map.h" -#include <plat/devs.h> -#include <plat/cpu.h> +#include "devs.h" +#include "cpu.h" #include <linux/platform_data/i2c-s3c2410.h> -#include <mach/gpio-samsung.h> -#include <plat/samsung-time.h> +#include "gpio-samsung.h" -#include "common.h" +#include "s3c64xx.h" #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB @@ -62,7 +60,7 @@ static void __init smdk6400_map_io(void) s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc)); s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4); } static struct platform_device *smdk6400_devices[] __initdata = { @@ -88,6 +86,5 @@ MACHINE_START(SMDK6400, "SMDK6400") .init_irq = s3c6400_init_irq, .map_io = smdk6400_map_io, .init_machine = smdk6400_machine_init, - .init_time = samsung_timer_init, - .restart = s3c64xx_restart, + .init_time = s3c64xx_timer_init, MACHINE_END diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c/mach-smdk6410.c index 56f406c0c3dd..ae18c1375c9c 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c/mach-smdk6410.c @@ -45,32 +45,30 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> #include <mach/irqs.h> -#include <mach/map.h> +#include "map.h" #include <asm/irq.h> #include <asm/mach-types.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" #include <linux/platform_data/ata-samsung_cf.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/fb.h> -#include <plat/gpio-cfg.h> +#include "fb.h" +#include "gpio-cfg.h" -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/adc.h> +#include "devs.h" +#include "cpu.h" +#include <linux/soc/samsung/s3c-adc.h> #include <linux/platform_data/touchscreen-s3c2410.h> -#include <plat/keypad.h> -#include <plat/samsung-time.h> +#include "keypad.h" -#include "backlight.h" -#include "common.h" -#include "regs-modem.h" -#include "regs-srom.h" -#include "regs-sys.h" +#include "backlight-s3c64xx.h" +#include "s3c64xx.h" +#include "regs-modem-s3c64xx.h" +#include "regs-srom-s3c64xx.h" +#include "regs-sys-s3c64xx.h" #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB @@ -635,7 +633,7 @@ static void __init smdk6410_map_io(void) s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc)); s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4); /* set the LCD type */ @@ -704,6 +702,5 @@ MACHINE_START(SMDK6410, "SMDK6410") .init_irq = s3c6410_init_irq, .map_io = smdk6410_map_io, .init_machine = smdk6410_machine_init, - .init_time = samsung_timer_init, - .restart = s3c64xx_restart, + .init_time = s3c64xx_timer_init, MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-tct_hammer.c b/arch/arm/mach-s3c/mach-tct_hammer.c index 8d8ddd6ea305..2a61df316e8c 100644 --- a/arch/arm/mach-s3c24xx/mach-tct_hammer.c +++ b/arch/arm/mach-s3c/mach-tct_hammer.c @@ -7,6 +7,7 @@ // derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by // Ben Dooks <ben@simtec.co.uk> +#include <linux/gpio/machine.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/interrupt.h> @@ -24,21 +25,19 @@ #include <asm/mach/irq.h> #include <asm/mach/flash.h> -#include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach-types.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/devs.h> -#include <plat/cpu.h> +#include "devs.h" +#include "cpu.h" #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/mtd/map.h> #include <linux/mtd/physmap.h> -#include <plat/samsung-time.h> -#include "common.h" +#include "s3c24xx.h" static struct resource tct_hammer_nor_resource = DEFINE_RES_MEM(0x00000000, SZ_16M); @@ -103,6 +102,19 @@ static struct s3c2410_uartcfg tct_hammer_uartcfgs[] = { } }; +static struct gpiod_lookup_table tct_hammer_mmc_gpio_table = { + .dev_id = "s3c2410-sdi", + .table = { + /* bus pins */ + GPIO_LOOKUP_IDX("GPIOE", 5, "bus", 0, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 6, "bus", 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 7, "bus", 2, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 8, "bus", 3, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 9, "bus", 4, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH), + { }, + }, +}; static struct platform_device *tct_hammer_devices[] __initdata = { &s3c_device_adc, @@ -119,18 +131,19 @@ static void __init tct_hammer_map_io(void) { s3c24xx_init_io(tct_hammer_iodesc, ARRAY_SIZE(tct_hammer_iodesc)); s3c24xx_init_uarts(tct_hammer_uartcfgs, ARRAY_SIZE(tct_hammer_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init tct_hammer_init_time(void) { s3c2410_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init tct_hammer_init(void) { s3c_i2c0_set_platdata(NULL); + gpiod_add_lookup_table(&tct_hammer_mmc_gpio_table); platform_add_devices(tct_hammer_devices, ARRAY_SIZE(tct_hammer_devices)); } diff --git a/arch/arm/mach-s3c24xx/mach-vr1000.c b/arch/arm/mach-s3c/mach-vr1000.c index 6a3fb2becc7c..5c3d07cf2e79 100644 --- a/arch/arm/mach-s3c24xx/mach-vr1000.c +++ b/arch/arm/mach-s3c/mach-vr1000.c @@ -35,17 +35,15 @@ #include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/asoc-s3c24xx_simtec.h> -#include <mach/hardware.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" +#include "gpio-cfg.h" -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/gpio-cfg.h> -#include <plat/samsung-time.h> +#include "cpu.h" +#include "devs.h" #include "bast.h" -#include "common.h" +#include "s3c24xx.h" #include "simtec.h" #include "vr1000.h" @@ -328,13 +326,13 @@ static void __init vr1000_map_io(void) s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc)); s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init vr1000_init_time(void) { s3c2410_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init vr1000_init(void) diff --git a/arch/arm/mach-s3c24xx/mach-vstms.c b/arch/arm/mach-s3c/mach-vstms.c index d76b28b65e65..05f19f5ffabb 100644 --- a/arch/arm/mach-s3c24xx/mach-vstms.c +++ b/arch/arm/mach-s3c/mach-vstms.c @@ -24,24 +24,23 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> #include <asm/setup.h> #include <asm/irq.h> #include <asm/mach-types.h> -#include <mach/regs-gpio.h> -#include <mach/regs-lcd.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" +#include "gpio-cfg.h" -#include <mach/fb.h> +#include <linux/platform_data/fb-s3c2410.h> #include <linux/platform_data/i2c-s3c2410.h> #include <linux/platform_data/mtd-nand-s3c2410.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/samsung-time.h> +#include "devs.h" +#include "cpu.h" -#include "common.h" +#include "s3c24xx.h" static struct map_desc vstms_iodesc[] __initdata = { }; @@ -112,7 +111,7 @@ static struct s3c2410_platform_nand __initdata vstms_nand_info = { .twrph1 = 20, .nr_sets = ARRAY_SIZE(vstms_nand_sets), .sets = vstms_nand_sets, - .ecc_mode = NAND_ECC_SOFT, + .engine_type = NAND_ECC_ENGINE_TYPE_SOFT, }; static struct platform_device *vstms_devices[] __initdata = { @@ -136,20 +135,22 @@ static void __init vstms_map_io(void) { s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc)); s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs)); - samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); + s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); } static void __init vstms_init_time(void) { s3c2412_init_clocks(12000000); - samsung_timer_init(); + s3c24xx_timer_init(); } static void __init vstms_init(void) { s3c_i2c0_set_platdata(NULL); s3c_nand_set_platdata(&vstms_nand_info); - + /* 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); platform_add_devices(vstms_devices, ARRAY_SIZE(vstms_devices)); } diff --git a/arch/arm/plat-samsung/include/plat/map-s3c.h b/arch/arm/mach-s3c/map-s3c.h index 4244acbf4b65..a18fdd3d6ae2 100644 --- a/arch/arm/plat-samsung/include/plat/map-s3c.h +++ b/arch/arm/mach-s3c/map-s3c.h @@ -9,6 +9,8 @@ #ifndef __ASM_PLAT_MAP_S3C_H #define __ASM_PLAT_MAP_S3C_H __FILE__ +#include "map.h" + #define S3C24XX_VA_IRQ S3C_VA_IRQ #define S3C24XX_VA_MEMCTRL S3C_VA_MEM #define S3C24XX_VA_UART S3C_VA_UART @@ -45,16 +47,8 @@ #define S3C_VA_USB_HSPHY S3C64XX_VA_USB_HSPHY -/* - * ISA style IO, for each machine to sort out mappings for, - * if it implements it. We reserve two 16M regions for ISA. - */ - #define S3C2410_ADDR(x) S3C_ADDR(x) -#define S3C24XX_VA_ISA_WORD S3C2410_ADDR(0x02000000) -#define S3C24XX_VA_ISA_BYTE S3C2410_ADDR(0x03000000) - /* deal with the registers that move under the 2412/2413 */ #if defined(CONFIG_CPU_S3C2412) @@ -71,6 +65,6 @@ extern void __iomem *s3c24xx_va_gpio2; #define S3C24XX_VA_GPIO2 S3C24XX_VA_GPIO #endif -#include <plat/map-s5p.h> +#include "map-s5p.h" #endif /* __ASM_PLAT_MAP_S3C_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/map.h b/arch/arm/mach-s3c/map-s3c24xx.h index bca93112f57d..b5dba78a9dd7 100644 --- a/arch/arm/mach-s3c24xx/include/mach/map.h +++ b/arch/arm/mach-s3c/map-s3c24xx.h @@ -9,8 +9,8 @@ #ifndef __ASM_ARCH_MAP_H #define __ASM_ARCH_MAP_H -#include <plat/map-base.h> -#include <plat/map-s3c.h> +#include <mach/map-base.h> +#include "map-s3c.h" /* * interrupt controller is the first thing we put in, to make @@ -86,6 +86,8 @@ #define S3C2410_PA_SPI (0x59000000) #define S3C2443_PA_SPI0 (0x52000000) #define S3C2443_PA_SPI1 S3C2410_PA_SPI +#define S3C2410_SPI1 (0x20) +#define S3C2412_SPI1 (0x100) /* SDI */ #define S3C2410_PA_SDI (0x5A000000) diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c/map-s3c64xx.h index 9372a535b7ba..d7740d2a77c4 100644 --- a/arch/arm/mach-s3c64xx/include/mach/map.h +++ b/arch/arm/mach-s3c/map-s3c64xx.h @@ -11,8 +11,8 @@ #ifndef __ASM_ARCH_MAP_H #define __ASM_ARCH_MAP_H __FILE__ -#include <plat/map-base.h> -#include <plat/map-s3c.h> +#include <mach/map-base.h> +#include "map-s3c.h" /* * Post-mux Chip Select Regions Xm0CSn_ diff --git a/arch/arm/plat-samsung/include/plat/map-s5p.h b/arch/arm/mach-s3c/map-s5p.h index d69a0ca09fb5..cd237924e34d 100644 --- a/arch/arm/plat-samsung/include/plat/map-s5p.h +++ b/arch/arm/mach-s3c/map-s5p.h @@ -9,14 +9,12 @@ #ifndef __ASM_PLAT_MAP_S5P_H #define __ASM_PLAT_MAP_S5P_H __FILE__ -#define S5P_VA_CHIPID S3C_ADDR(0x02000000) - #define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000)) #define VA_VIC0 VA_VIC(0) #define VA_VIC1 VA_VIC(1) #define VA_VIC2 VA_VIC(2) #define VA_VIC3 VA_VIC(3) -#include <plat/map-s3c.h> +#include "map-s3c.h" #endif /* __ASM_PLAT_MAP_S5P_H */ diff --git a/arch/arm/mach-s3c/map.h b/arch/arm/mach-s3c/map.h new file mode 100644 index 000000000000..7cfb517d4886 --- /dev/null +++ b/arch/arm/mach-s3c/map.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "map-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "map-s3c64xx.h" +#endif diff --git a/arch/arm/mach-s3c24xx/nand-core.h b/arch/arm/mach-s3c/nand-core-s3c24xx.h index 8de633d416ae..a14316729c48 100644 --- a/arch/arm/mach-s3c24xx/nand-core.h +++ b/arch/arm/mach-s3c/nand-core-s3c24xx.h @@ -6,8 +6,8 @@ * S3C - Nand Controller core functions */ -#ifndef __ASM_ARCH_NAND_CORE_H -#define __ASM_ARCH_NAND_CORE_H __FILE__ +#ifndef __ASM_ARCH_NAND_CORE_S3C24XX_H +#define __ASM_ARCH_NAND_CORE_S3C24XX_H __FILE__ /* These functions are only for use with the core support code, such as * the cpu specific initialisation code @@ -21,4 +21,4 @@ static inline void s3c_nand_setname(char *name) #endif } -#endif /* __ASM_ARCH_NAND_CORE_H */ +#endif /* __ASM_ARCH_NAND_CORE_S3C24XX_H */ diff --git a/arch/arm/mach-s3c64xx/onenand-core.h b/arch/arm/mach-s3c/onenand-core-s3c64xx.h index 0cf6b5e76b24..e2dfdd1fec93 100644 --- a/arch/arm/mach-s3c64xx/onenand-core.h +++ b/arch/arm/mach-s3c/onenand-core-s3c64xx.h @@ -7,8 +7,8 @@ * Samsung OneNAD Controller core functions */ -#ifndef __ASM_ARCH_ONENAND_CORE_H -#define __ASM_ARCH_ONENAND_CORE_H __FILE__ +#ifndef __ASM_ARCH_ONENAND_CORE_S3C64XX_H +#define __ASM_ARCH_ONENAND_CORE_S3C64XX_H __FILE__ /* These functions are only for use with the core support code, such as * the cpu specific initialisation code @@ -29,4 +29,4 @@ static inline void s3c64xx_onenand1_setname(char *name) #endif } -#endif /* __ASM_ARCH_ONENAND_CORE_H */ +#endif /* __ASM_ARCH_ONENAND_CORE_S3C64XX_H */ diff --git a/arch/arm/mach-s3c24xx/osiris.h b/arch/arm/mach-s3c/osiris.h index b6c9c5ed2ba7..b6c9c5ed2ba7 100644 --- a/arch/arm/mach-s3c24xx/osiris.h +++ b/arch/arm/mach-s3c/osiris.h diff --git a/arch/arm/mach-s3c24xx/otom.h b/arch/arm/mach-s3c/otom.h index c800f67d03d4..c800f67d03d4 100644 --- a/arch/arm/mach-s3c24xx/otom.h +++ b/arch/arm/mach-s3c/otom.h diff --git a/arch/arm/mach-s3c64xx/pl080.c b/arch/arm/mach-s3c/pl080.c index 152edbeea0c7..4730f080c736 100644 --- a/arch/arm/mach-s3c64xx/pl080.c +++ b/arch/arm/mach-s3c/pl080.c @@ -10,11 +10,11 @@ #include <linux/amba/pl08x.h> #include <linux/of.h> -#include <plat/cpu.h> +#include "cpu.h" #include <mach/irqs.h> -#include <mach/map.h> +#include "map.h" -#include "regs-sys.h" +#include "regs-sys-s3c64xx.h" static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd) { diff --git a/arch/arm/plat-samsung/platformdata.c b/arch/arm/mach-s3c/platformdata.c index cbc3b4b45c74..e643c81aef45 100644 --- a/arch/arm/plat-samsung/platformdata.c +++ b/arch/arm/mach-s3c/platformdata.c @@ -9,8 +9,8 @@ #include <linux/string.h> #include <linux/platform_device.h> -#include <plat/devs.h> -#include <plat/sdhci.h> +#include "devs.h" +#include "sdhci.h" void __init *s3c_set_platdata(void *pd, size_t pdsize, struct platform_device *pdev) diff --git a/arch/arm/mach-s3c24xx/pll-s3c2410.c b/arch/arm/mach-s3c/pll-s3c2410.c index 0561f79ddce8..3fbc99eaa4a2 100644 --- a/arch/arm/mach-s3c24xx/pll-s3c2410.c +++ b/arch/arm/mach-s3c/pll-s3c2410.c @@ -15,8 +15,8 @@ #include <linux/clk.h> #include <linux/err.h> -#include <plat/cpu.h> -#include <plat/cpu-freq-core.h> +#include <linux/soc/samsung/s3c-cpufreq-core.h> +#include <linux/soc/samsung/s3c-pm.h> /* This array should be sorted in ascending order of the frequencies */ static struct cpufreq_frequency_table pll_vals_12MHz[] = { diff --git a/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c b/arch/arm/mach-s3c/pll-s3c2440-12000000.c index 2ec3a2f9a6a5..fdb8e8c2fe3b 100644 --- a/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c +++ b/arch/arm/mach-s3c/pll-s3c2440-12000000.c @@ -13,8 +13,8 @@ #include <linux/clk.h> #include <linux/err.h> -#include <plat/cpu.h> -#include <plat/cpu-freq-core.h> +#include <linux/soc/samsung/s3c-cpufreq-core.h> +#include <linux/soc/samsung/s3c-pm.h> /* This array should be sorted in ascending order of the frequencies */ static struct cpufreq_frequency_table s3c2440_plls_12[] = { diff --git a/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c b/arch/arm/mach-s3c/pll-s3c2440-16934400.c index 4b3d9e36c6bb..438b6fc099a4 100644 --- a/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c +++ b/arch/arm/mach-s3c/pll-s3c2440-16934400.c @@ -13,8 +13,8 @@ #include <linux/clk.h> #include <linux/err.h> -#include <plat/cpu.h> -#include <plat/cpu-freq-core.h> +#include <linux/soc/samsung/s3c-cpufreq-core.h> +#include <linux/soc/samsung/s3c-pm.h> /* This array should be sorted in ascending order of the frequencies */ static struct cpufreq_frequency_table s3c2440_plls_169344[] = { diff --git a/arch/arm/plat-samsung/pm-common.c b/arch/arm/mach-s3c/pm-common.c index 59a10c6dcba1..618bd4499cae 100644 --- a/arch/arm/plat-samsung/pm-common.c +++ b/arch/arm/mach-s3c/pm-common.c @@ -12,7 +12,7 @@ #include <linux/io.h> #include <linux/kernel.h> -#include <plat/pm-common.h> +#include "pm-common.h" /* helper functions to save and restore register state */ @@ -55,6 +55,8 @@ void s3c_pm_do_restore(const struct sleep_save *ptr, int count) /** * s3c_pm_do_restore_core() - early restore register values from save list. + * @ptr: Pointer to an array of registers. + * @count: Size of the ptr array. * * This is similar to s3c_pm_do_restore() except we try and minimise the * side effects of the function in case registers that hardware might need diff --git a/arch/arm/mach-s3c/pm-common.h b/arch/arm/mach-s3c/pm-common.h new file mode 100644 index 000000000000..18b9607e1e39 --- /dev/null +++ b/arch/arm/mach-s3c/pm-common.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Tomasz Figa <t.figa@samsung.com> + * Copyright (c) 2004 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Written by Ben Dooks, <ben@simtec.co.uk> + */ + +#ifndef __PLAT_SAMSUNG_PM_COMMON_H +#define __PLAT_SAMSUNG_PM_COMMON_H __FILE__ + +#include <linux/irq.h> +#include <linux/soc/samsung/s3c-pm.h> + +/* sleep save info */ + +/** + * struct sleep_save - save information for shared peripherals. + * @reg: Pointer to the register to save. + * @val: Holder for the value saved from reg. + * + * This describes a list of registers which is used by the pm core and + * other subsystem to save and restore register values over suspend. + */ +struct sleep_save { + void __iomem *reg; + unsigned long val; +}; + +#define SAVE_ITEM(x) \ + { .reg = (x) } + +/* helper functions to save/restore lists of registers. */ + +extern void s3c_pm_do_save(struct sleep_save *ptr, int count); +extern void s3c_pm_do_restore(const struct sleep_save *ptr, int count); +extern void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count); + +#endif diff --git a/arch/arm/mach-s3c24xx/include/mach/pm-core.h b/arch/arm/mach-s3c/pm-core-s3c24xx.h index 5e4ce89d0158..bcb7978a4e85 100644 --- a/arch/arm/mach-s3c24xx/include/mach/pm-core.h +++ b/arch/arm/mach-s3c/pm-core-s3c24xx.h @@ -11,10 +11,12 @@ #include <linux/io.h> #include "regs-clock.h" -#include "regs-irq.h" +#include "regs-irq-s3c24xx.h" +#include <mach/irqs.h> static inline void s3c_pm_debug_init_uart(void) { +#ifdef CONFIG_SAMSUNG_PM_DEBUG unsigned long tmp = __raw_readl(S3C2410_CLKCON); /* re-start uart clocks */ @@ -24,6 +26,7 @@ static inline void s3c_pm_debug_init_uart(void) __raw_writel(tmp, S3C2410_CLKCON); udelay(10); +#endif } static inline void s3c_pm_arch_prepare_irqs(void) @@ -75,11 +78,6 @@ static inline void s3c_pm_arch_show_resume_irqs(void) s3c_irqwake_eintmask); } -static inline void s3c_pm_arch_update_uart(void __iomem *regs, - struct pm_uart_save *save) -{ -} - static inline void s3c_pm_restored_gpios(void) { } static inline void samsung_pm_saved_gpios(void) { } diff --git a/arch/arm/mach-s3c64xx/include/mach/pm-core.h b/arch/arm/mach-s3c/pm-core-s3c64xx.h index bbf79ed28583..06f564e5cf63 100644 --- a/arch/arm/mach-s3c64xx/include/mach/pm-core.h +++ b/arch/arm/mach-s3c/pm-core-s3c64xx.h @@ -14,12 +14,13 @@ #include <linux/serial_s3c.h> #include <linux/delay.h> -#include <mach/regs-gpio.h> -#include <mach/regs-clock.h> -#include <mach/map.h> +#include "regs-gpio.h" +#include "regs-clock.h" +#include "map.h" static inline void s3c_pm_debug_init_uart(void) { +#ifdef CONFIG_SAMSUNG_PM_DEBUG u32 tmp = __raw_readl(S3C_PCLK_GATE); /* As a note, since the S3C64XX UARTs generally have multiple @@ -35,6 +36,7 @@ static inline void s3c_pm_debug_init_uart(void) __raw_writel(tmp, S3C_PCLK_GATE); udelay(10); +#endif } static inline void s3c_pm_arch_prepare_irqs(void) @@ -63,48 +65,6 @@ static inline void s3c_pm_arch_show_resume_irqs(void) #define s3c_irqwake_intallow 0 #endif -static inline void s3c_pm_arch_update_uart(void __iomem *regs, - struct pm_uart_save *save) -{ - u32 ucon = __raw_readl(regs + S3C2410_UCON); - u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK; - u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK; - u32 new_ucon; - u32 delta; - - /* S3C64XX UART blocks only support level interrupts, so ensure that - * when we restore unused UART blocks we force the level interrupt - * settigs. */ - save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL; - - /* We have a constraint on changing the clock type of the UART - * between UCLKx and PCLK, so ensure that when we restore UCON - * that the CLK field is correctly modified if the bootloader - * has changed anything. - */ - if (ucon_clk != save_clk) { - new_ucon = save->ucon; - delta = ucon_clk ^ save_clk; - - /* change from UCLKx => wrong PCLK, - * either UCLK can be tested for by a bit-test - * with UCLK0 */ - if (ucon_clk & S3C6400_UCON_UCLK0 && - !(save_clk & S3C6400_UCON_UCLK0) && - delta & S3C6400_UCON_PCLK2) { - new_ucon &= ~S3C6400_UCON_UCLK0; - } else if (delta == S3C6400_UCON_PCLK2) { - /* as an precaution, don't change from - * PCLK2 => PCLK or vice-versa */ - new_ucon ^= S3C6400_UCON_PCLK2; - } - - S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n", - ucon, new_ucon, save->ucon); - save->ucon = new_ucon; - } -} - static inline void s3c_pm_restored_gpios(void) { /* ensure sleep mode has been cleared from the system */ diff --git a/arch/arm/mach-s3c/pm-core.h b/arch/arm/mach-s3c/pm-core.h new file mode 100644 index 000000000000..b0e1d277f599 --- /dev/null +++ b/arch/arm/mach-s3c/pm-core.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "pm-core-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "pm-core-s3c64xx.h" +#endif diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/mach-s3c/pm-gpio.c index cb2e3bc79336..cfdbc2337998 100644 --- a/arch/arm/plat-samsung/pm-gpio.c +++ b/arch/arm/mach-s3c/pm-gpio.c @@ -13,10 +13,10 @@ #include <linux/io.h> #include <linux/gpio.h> -#include <mach/gpio-samsung.h> +#include "gpio-samsung.h" -#include <plat/gpio-core.h> -#include <plat/pm.h> +#include "gpio-core.h" +#include "pm.h" /* PM GPIO helpers */ diff --git a/arch/arm/mach-s3c24xx/pm-h1940.S b/arch/arm/mach-s3c/pm-h1940.S index a7bbe336ac6b..3bf6685123cb 100644 --- a/arch/arm/mach-s3c24xx/pm-h1940.S +++ b/arch/arm/mach-s3c/pm-h1940.S @@ -7,10 +7,9 @@ #include <linux/linkage.h> #include <asm/assembler.h> -#include <mach/hardware.h> -#include <mach/map.h> +#include "map.h" -#include <mach/regs-gpio.h> +#include "regs-gpio.h" .text .global h1940_pm_return diff --git a/arch/arm/mach-s3c24xx/pm-s3c2410.c b/arch/arm/mach-s3c/pm-s3c2410.c index 2d8ea701380a..a66419883735 100644 --- a/arch/arm/mach-s3c24xx/pm-s3c2410.c +++ b/arch/arm/mach-s3c/pm-s3c2410.c @@ -16,13 +16,12 @@ #include <asm/mach-types.h> -#include <mach/hardware.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" -#include <plat/gpio-cfg.h> -#include <plat/cpu.h> -#include <plat/pm.h> +#include "gpio-cfg.h" +#include "cpu.h" +#include "pm.h" #include "h1940.h" diff --git a/arch/arm/mach-s3c24xx/pm-s3c2412.c b/arch/arm/mach-s3c/pm-s3c2412.c index 2dfdaab0aa1f..6a9604477c9e 100644 --- a/arch/arm/mach-s3c24xx/pm-s3c2412.c +++ b/arch/arm/mach-s3c/pm-s3c2412.c @@ -19,14 +19,14 @@ #include <asm/cacheflush.h> #include <asm/irq.h> -#include <mach/hardware.h> -#include <mach/regs-gpio.h> +#include <mach/irqs.h> +#include "regs-gpio.h" -#include <plat/cpu.h> -#include <plat/pm.h> -#include <plat/wakeup-mask.h> +#include "cpu.h" +#include "pm.h" +#include "wakeup-mask.h" -#include "regs-dsc.h" +#include "regs-dsc-s3c24xx.h" #include "s3c2412-power.h" extern void s3c2412_sleep_enter(void); diff --git a/arch/arm/mach-s3c24xx/pm-s3c2416.c b/arch/arm/mach-s3c/pm-s3c2416.c index 9a2f05e279d4..f69ad84cf4ff 100644 --- a/arch/arm/mach-s3c24xx/pm-s3c2416.c +++ b/arch/arm/mach-s3c/pm-s3c2416.c @@ -11,10 +11,10 @@ #include <asm/cacheflush.h> -#include <mach/regs-s3c2443-clock.h> +#include "regs-s3c2443-clock.h" -#include <plat/cpu.h> -#include <plat/pm.h> +#include "cpu.h" +#include "pm.h" #include "s3c2412-power.h" diff --git a/arch/arm/mach-s3c24xx/pm.c b/arch/arm/mach-s3c/pm-s3c24xx.c index c64988c609ad..3a8f5c38882e 100644 --- a/arch/arm/mach-s3c24xx/pm.c +++ b/arch/arm/mach-s3c/pm-s3c24xx.c @@ -21,17 +21,17 @@ #include <linux/serial_s3c.h> #include <linux/io.h> -#include <mach/regs-clock.h> -#include <mach/regs-gpio.h> -#include <mach/regs-irq.h> -#include <mach/gpio-samsung.h> +#include "regs-clock.h" +#include "regs-gpio.h" +#include "regs-irq.h" +#include "gpio-samsung.h" #include <asm/mach/time.h> -#include <plat/gpio-cfg.h> -#include <plat/pm.h> +#include "gpio-cfg.h" +#include "pm.h" -#include "regs-mem.h" +#include "regs-mem-s3c24xx.h" #define PFX "s3c24xx-pm: " diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c/pm-s3c64xx.c index fd6dbb263ed5..4f1778123dee 100644 --- a/arch/arm/mach-s3c64xx/pm.c +++ b/arch/arm/mach-s3c/pm-s3c64xx.c @@ -14,22 +14,22 @@ #include <linux/gpio.h> #include <linux/pm_domain.h> -#include <mach/map.h> +#include "map.h" #include <mach/irqs.h> -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/pm.h> -#include <plat/wakeup-mask.h> +#include "cpu.h" +#include "devs.h" +#include "pm.h" +#include "wakeup-mask.h" -#include <mach/regs-gpio.h> -#include <mach/regs-clock.h> -#include <mach/gpio-samsung.h> +#include "regs-gpio.h" +#include "regs-clock.h" +#include "gpio-samsung.h" -#include "regs-gpio-memport.h" -#include "regs-modem.h" -#include "regs-sys.h" -#include "regs-syscon-power.h" +#include "regs-gpio-memport-s3c64xx.h" +#include "regs-modem-s3c64xx.h" +#include "regs-sys-s3c64xx.h" +#include "regs-syscon-power-s3c64xx.h" struct s3c64xx_pm_domain { char *const name; @@ -305,6 +305,56 @@ static void s3c64xx_pm_prepare(void) __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT), S3C64XX_WAKEUP_STAT); } +#ifdef CONFIG_SAMSUNG_PM_DEBUG +void s3c_pm_arch_update_uart(void __iomem *regs, struct pm_uart_save *save) +{ + u32 ucon; + u32 ucon_clk + u32 save_clk; + u32 new_ucon; + u32 delta; + + if (!soc_is_s3c64xx()) + return; + + ucon = __raw_readl(regs + S3C2410_UCON); + ucon_clk = ucon & S3C6400_UCON_CLKMASK; + sav_clk = save->ucon & S3C6400_UCON_CLKMASK; + + /* S3C64XX UART blocks only support level interrupts, so ensure that + * when we restore unused UART blocks we force the level interrupt + * settigs. */ + save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL; + + /* We have a constraint on changing the clock type of the UART + * between UCLKx and PCLK, so ensure that when we restore UCON + * that the CLK field is correctly modified if the bootloader + * has changed anything. + */ + if (ucon_clk != save_clk) { + new_ucon = save->ucon; + delta = ucon_clk ^ save_clk; + + /* change from UCLKx => wrong PCLK, + * either UCLK can be tested for by a bit-test + * with UCLK0 */ + if (ucon_clk & S3C6400_UCON_UCLK0 && + !(save_clk & S3C6400_UCON_UCLK0) && + delta & S3C6400_UCON_PCLK2) { + new_ucon &= ~S3C6400_UCON_UCLK0; + } else if (delta == S3C6400_UCON_PCLK2) { + /* as an precaution, don't change from + * PCLK2 => PCLK or vice-versa */ + new_ucon ^= S3C6400_UCON_PCLK2; + } + + S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n", + ucon, new_ucon, save->ucon); + save->ucon = new_ucon; + } +} +#endif + int __init s3c64xx_pm_init(void) { int i; diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/mach-s3c/pm.c index d6bfd66592b0..c563bb9d92be 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/mach-s3c/pm.c @@ -18,15 +18,16 @@ #include <asm/cacheflush.h> #include <asm/suspend.h> -#include <mach/map.h> -#include <mach/regs-clock.h> -#include <mach/regs-irq.h> +#include "map.h" +#include "regs-clock.h" +#include "regs-irq.h" #include <mach/irqs.h> #include <asm/irq.h> -#include <plat/pm.h> -#include <mach/pm-core.h> +#include "cpu.h" +#include "pm.h" +#include "pm-core.h" /* for external use */ @@ -70,8 +71,7 @@ static int s3c_pm_enter(suspend_state_t state) { int ret; /* ensure the debug is initialised (if enabled) */ - - s3c_pm_debug_init(); + s3c_pm_debug_init_uart(); S3C_PMDBG("%s(%d)\n", __func__, state); @@ -100,7 +100,7 @@ static int s3c_pm_enter(suspend_state_t state) samsung_pm_saved_gpios(); } - s3c_pm_save_uarts(); + s3c_pm_save_uarts(soc_is_s3c2410()); s3c_pm_save_core(); /* set the irq configuration for wake */ @@ -137,14 +137,14 @@ static int s3c_pm_enter(suspend_state_t state) /* restore the system state */ s3c_pm_restore_core(); - s3c_pm_restore_uarts(); + s3c_pm_restore_uarts(soc_is_s3c2410()); if (!of_have_populated_dt()) { samsung_pm_restore_gpios(); s3c_pm_restored_gpios(); } - s3c_pm_debug_init(); + s3c_pm_debug_init_uart(); /* check what irq (if any) restored the system */ diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/mach-s3c/pm.h index 2746137f9794..eed61e585457 100644 --- a/arch/arm/plat-samsung/include/plat/pm.h +++ b/arch/arm/mach-s3c/pm.h @@ -11,7 +11,7 @@ * management */ -#include <plat/pm-common.h> +#include "pm-common.h" struct device; diff --git a/arch/arm/plat-samsung/include/plat/pwm-core.h b/arch/arm/mach-s3c/pwm-core.h index 05e3448642a1..05e3448642a1 100644 --- a/arch/arm/plat-samsung/include/plat/pwm-core.h +++ b/arch/arm/mach-s3c/pwm-core.h diff --git a/arch/arm/plat-samsung/include/plat/regs-adc.h b/arch/arm/mach-s3c/regs-adc.h index 58953c7381dd..58953c7381dd 100644 --- a/arch/arm/plat-samsung/include/plat/regs-adc.h +++ b/arch/arm/mach-s3c/regs-adc.h diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-clock.h b/arch/arm/mach-s3c/regs-clock-s3c24xx.h index 7ca3dd4f13c0..933ddb5eedec 100644 --- a/arch/arm/mach-s3c24xx/include/mach/regs-clock.h +++ b/arch/arm/mach-s3c/regs-clock-s3c24xx.h @@ -9,6 +9,8 @@ #ifndef __ASM_ARM_REGS_CLOCK #define __ASM_ARM_REGS_CLOCK +#include "map.h" + #define S3C2410_CLKREG(x) ((x) + S3C24XX_VA_CLKPWR) #define S3C2410_PLLVAL(_m,_p,_s) ((_m) << 12 | ((_p) << 4) | ((_s))) diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h b/arch/arm/mach-s3c/regs-clock-s3c64xx.h index 35a68767b318..35a68767b318 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h +++ b/arch/arm/mach-s3c/regs-clock-s3c64xx.h diff --git a/arch/arm/mach-s3c/regs-clock.h b/arch/arm/mach-s3c/regs-clock.h new file mode 100644 index 000000000000..7df31f203d28 --- /dev/null +++ b/arch/arm/mach-s3c/regs-clock.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "regs-clock-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "regs-clock-s3c64xx.h" +#endif diff --git a/arch/arm/mach-s3c24xx/regs-dsc.h b/arch/arm/mach-s3c/regs-dsc-s3c24xx.h index b500636276f2..8b8b572aef04 100644 --- a/arch/arm/mach-s3c24xx/regs-dsc.h +++ b/arch/arm/mach-s3c/regs-dsc-s3c24xx.h @@ -7,8 +7,8 @@ */ -#ifndef __ASM_ARCH_REGS_DSC_H -#define __ASM_ARCH_REGS_DSC_H __FILE__ +#ifndef __ASM_ARCH_REGS_DSC_S3C24XX_H +#define __ASM_ARCH_REGS_DSC_S3C24XX_H __FILE__ /* S3C2412 */ #define S3C2412_DSC0 S3C2410_GPIOREG(0xdc) @@ -18,5 +18,5 @@ #define S3C2440_DSC0 S3C2410_GPIOREG(0xc4) #define S3C2440_DSC1 S3C2410_GPIOREG(0xc8) -#endif /* __ASM_ARCH_REGS_DSC_H */ +#endif /* __ASM_ARCH_REGS_DSC_S3C24XX_H */ diff --git a/arch/arm/mach-s3c64xx/regs-gpio-memport.h b/arch/arm/mach-s3c/regs-gpio-memport-s3c64xx.h index 589afe1132d6..589afe1132d6 100644 --- a/arch/arm/mach-s3c64xx/regs-gpio-memport.h +++ b/arch/arm/mach-s3c/regs-gpio-memport-s3c64xx.h diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h b/arch/arm/mach-s3c/regs-gpio-s3c24xx.h index 594e967c0673..9a7e262268a7 100644 --- a/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h +++ b/arch/arm/mach-s3c/regs-gpio-s3c24xx.h @@ -10,6 +10,8 @@ #ifndef __ASM_ARCH_REGS_GPIO_H #define __ASM_ARCH_REGS_GPIO_H +#include "map-s3c.h" + #define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80) /* general configuration options */ diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h b/arch/arm/mach-s3c/regs-gpio-s3c64xx.h index 592a2be3d2aa..592a2be3d2aa 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h +++ b/arch/arm/mach-s3c/regs-gpio-s3c64xx.h diff --git a/arch/arm/mach-s3c/regs-gpio.h b/arch/arm/mach-s3c/regs-gpio.h new file mode 100644 index 000000000000..0d41cb76d440 --- /dev/null +++ b/arch/arm/mach-s3c/regs-gpio.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "regs-gpio-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "regs-gpio-s3c64xx.h" +#endif diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-irq.h b/arch/arm/mach-s3c/regs-irq-s3c24xx.h index 8d8e669e3903..c0b97b203415 100644 --- a/arch/arm/mach-s3c24xx/include/mach/regs-irq.h +++ b/arch/arm/mach-s3c/regs-irq-s3c24xx.h @@ -8,6 +8,8 @@ #ifndef ___ASM_ARCH_REGS_IRQ_H #define ___ASM_ARCH_REGS_IRQ_H +#include "map-s3c.h" + /* interrupt controller */ #define S3C2410_IRQREG(x) ((x) + S3C24XX_VA_IRQ) diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-irq.h b/arch/arm/mach-s3c/regs-irq-s3c64xx.h index b18c7bcb61c5..b18c7bcb61c5 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-irq.h +++ b/arch/arm/mach-s3c/regs-irq-s3c64xx.h diff --git a/arch/arm/mach-s3c/regs-irq.h b/arch/arm/mach-s3c/regs-irq.h new file mode 100644 index 000000000000..57f0dda8dbf5 --- /dev/null +++ b/arch/arm/mach-s3c/regs-irq.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CONFIG_ARCH_S3C24XX +#include "regs-irq-s3c24xx.h" +#endif + +#ifdef CONFIG_ARCH_S3C64XX +#include "regs-irq-s3c64xx.h" +#endif diff --git a/arch/arm/plat-samsung/include/plat/regs-irqtype.h b/arch/arm/mach-s3c/regs-irqtype.h index ec5c4c5fdd8f..ec5c4c5fdd8f 100644 --- a/arch/arm/plat-samsung/include/plat/regs-irqtype.h +++ b/arch/arm/mach-s3c/regs-irqtype.h diff --git a/arch/arm/mach-s3c24xx/regs-mem.h b/arch/arm/mach-s3c/regs-mem-s3c24xx.h index 2f3bc48b5890..8fed34a1672a 100644 --- a/arch/arm/mach-s3c24xx/regs-mem.h +++ b/arch/arm/mach-s3c/regs-mem-s3c24xx.h @@ -9,6 +9,8 @@ #ifndef __ARCH_ARM_MACH_S3C24XX_REGS_MEM_H #define __ARCH_ARM_MACH_S3C24XX_REGS_MEM_H __FILE__ +#include "map-s3c.h" + #define S3C2410_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x)) #define S3C2410_BWSCON S3C2410_MEMREG(0x00) diff --git a/arch/arm/mach-s3c64xx/regs-modem.h b/arch/arm/mach-s3c/regs-modem-s3c64xx.h index 136ad44291bf..136ad44291bf 100644 --- a/arch/arm/mach-s3c64xx/regs-modem.h +++ b/arch/arm/mach-s3c/regs-modem-s3c64xx.h diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c/regs-s3c2443-clock.h index 6bf924612b06..b3b670d463db 100644 --- a/arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h +++ b/arch/arm/mach-s3c/regs-s3c2443-clock.h @@ -10,6 +10,9 @@ #ifndef __ASM_ARM_REGS_S3C2443_CLOCK #define __ASM_ARM_REGS_S3C2443_CLOCK +#include <linux/delay.h> +#include "map-s3c.h" + #define S3C2443_CLKREG(x) ((x) + S3C24XX_VA_CLKPWR) #define S3C2443_PLLCON_MDIVSHIFT 16 @@ -184,5 +187,52 @@ s3c2443_get_epll(unsigned int pllval, unsigned int baseclk) return (unsigned int)fvco; } +static inline void s3c_hsudc_init_phy(void) +{ + u32 cfg; + + cfg = readl(S3C2443_PWRCFG) | S3C2443_PWRCFG_USBPHY; + writel(cfg, S3C2443_PWRCFG); + + cfg = readl(S3C2443_URSTCON); + cfg |= (S3C2443_URSTCON_FUNCRST | S3C2443_URSTCON_PHYRST); + writel(cfg, S3C2443_URSTCON); + mdelay(1); + + cfg = readl(S3C2443_URSTCON); + cfg &= ~(S3C2443_URSTCON_FUNCRST | S3C2443_URSTCON_PHYRST); + writel(cfg, S3C2443_URSTCON); + + cfg = readl(S3C2443_PHYCTRL); + cfg &= ~(S3C2443_PHYCTRL_CLKSEL | S3C2443_PHYCTRL_DSPORT); + cfg |= (S3C2443_PHYCTRL_EXTCLK | S3C2443_PHYCTRL_PLLSEL); + writel(cfg, S3C2443_PHYCTRL); + + cfg = readl(S3C2443_PHYPWR); + cfg &= ~(S3C2443_PHYPWR_FSUSPEND | S3C2443_PHYPWR_PLL_PWRDN | + S3C2443_PHYPWR_XO_ON | S3C2443_PHYPWR_PLL_REFCLK | + S3C2443_PHYPWR_ANALOG_PD); + cfg |= S3C2443_PHYPWR_COMMON_ON; + writel(cfg, S3C2443_PHYPWR); + + cfg = readl(S3C2443_UCLKCON); + cfg |= (S3C2443_UCLKCON_DETECT_VBUS | S3C2443_UCLKCON_FUNC_CLKEN | + S3C2443_UCLKCON_TCLKEN); + writel(cfg, S3C2443_UCLKCON); +} + +static inline void s3c_hsudc_uninit_phy(void) +{ + u32 cfg; + + cfg = readl(S3C2443_PWRCFG) & ~S3C2443_PWRCFG_USBPHY; + writel(cfg, S3C2443_PWRCFG); + + writel(S3C2443_PHYPWR_FSUSPEND, S3C2443_PHYPWR); + + cfg = readl(S3C2443_UCLKCON) & ~S3C2443_UCLKCON_FUNC_CLKEN; + writel(cfg, S3C2443_UCLKCON); +} + #endif /* __ASM_ARM_REGS_S3C2443_CLOCK */ diff --git a/arch/arm/mach-s3c64xx/regs-srom.h b/arch/arm/mach-s3c/regs-srom-s3c64xx.h index 2b37988bdf94..2b37988bdf94 100644 --- a/arch/arm/mach-s3c64xx/regs-srom.h +++ b/arch/arm/mach-s3c/regs-srom-s3c64xx.h diff --git a/arch/arm/mach-s3c64xx/regs-sys.h b/arch/arm/mach-s3c/regs-sys-s3c64xx.h index 3687325e2bb4..3687325e2bb4 100644 --- a/arch/arm/mach-s3c64xx/regs-sys.h +++ b/arch/arm/mach-s3c/regs-sys-s3c64xx.h diff --git a/arch/arm/mach-s3c64xx/regs-syscon-power.h b/arch/arm/mach-s3c/regs-syscon-power-s3c64xx.h index a35811cc656e..a35811cc656e 100644 --- a/arch/arm/mach-s3c64xx/regs-syscon-power.h +++ b/arch/arm/mach-s3c/regs-syscon-power-s3c64xx.h diff --git a/arch/arm/mach-s3c64xx/regs-usb-hsotg-phy.h b/arch/arm/mach-s3c/regs-usb-hsotg-phy-s3c64xx.h index deb1dd2d9c83..deb1dd2d9c83 100644 --- a/arch/arm/mach-s3c64xx/regs-usb-hsotg-phy.h +++ b/arch/arm/mach-s3c/regs-usb-hsotg-phy-s3c64xx.h diff --git a/arch/arm/mach-s3c24xx/include/mach/rtc-core.h b/arch/arm/mach-s3c/rtc-core-s3c24xx.h index 88510333b96b..e7258b2423fc 100644 --- a/arch/arm/mach-s3c24xx/include/mach/rtc-core.h +++ b/arch/arm/mach-s3c/rtc-core-s3c24xx.h @@ -5,8 +5,8 @@ * Samsung RTC Controller core functions */ -#ifndef __RTC_CORE_H -#define __RTC_CORE_H __FILE__ +#ifndef __RTC_CORE_S3C24XX_H +#define __RTC_CORE_S3C24XX_H __FILE__ /* These functions are only for use with the core support code, such as * the cpu specific initialisation code @@ -20,4 +20,4 @@ static inline void s3c_rtc_setname(char *name) s3c_device_rtc.name = name; } -#endif /* __RTC_CORE_H */ +#endif /* __RTC_CORE_S3C24XX_H */ diff --git a/arch/arm/mach-s3c24xx/s3c2410.c b/arch/arm/mach-s3c/s3c2410.c index 21fd5404bc98..4d39d9939c2f 100644 --- a/arch/arm/mach-s3c24xx/s3c2410.c +++ b/arch/arm/mach-s3c/s3c2410.c @@ -25,28 +25,27 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> -#include <mach/gpio-samsung.h> +#include "map.h" +#include "gpio-samsung.h" #include <asm/irq.h> #include <asm/system_misc.h> -#include <plat/cpu-freq.h> -#include <mach/regs-clock.h> +#include "regs-clock.h" -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/pm.h> +#include "cpu.h" +#include "devs.h" +#include "pm.h" -#include <plat/gpio-core.h> -#include <plat/gpio-cfg.h> -#include <plat/gpio-cfg-helpers.h> +#include "gpio-core.h" +#include "gpio-cfg.h" +#include "gpio-cfg-helpers.h" -#include "common.h" +#include "s3c24xx.h" /* Initial IO mappings */ -static struct map_desc s3c2410_iodesc[] __initdata = { +static struct map_desc s3c2410_iodesc[] __initdata __maybe_unused = { IODESC_ENT(CLKPWR), IODESC_ENT(TIMER), IODESC_ENT(WATCHDOG), diff --git a/arch/arm/mach-s3c24xx/s3c2412-power.h b/arch/arm/mach-s3c/s3c2412-power.h index 0031cfaa1d76..0031cfaa1d76 100644 --- a/arch/arm/mach-s3c24xx/s3c2412-power.h +++ b/arch/arm/mach-s3c/s3c2412-power.h diff --git a/arch/arm/mach-s3c24xx/s3c2412.c b/arch/arm/mach-s3c/s3c2412.c index 8fe4d4670dcb..0b1ca78c9d2a 100644 --- a/arch/arm/mach-s3c24xx/s3c2412.c +++ b/arch/arm/mach-s3c/s3c2412.c @@ -29,19 +29,17 @@ #include <asm/irq.h> #include <asm/system_misc.h> -#include <mach/hardware.h> -#include <mach/regs-clock.h> -#include <mach/regs-gpio.h> - -#include <plat/cpu.h> -#include <plat/cpu-freq.h> -#include <plat/devs.h> -#include <plat/pm.h> -#include <plat/regs-spi.h> - -#include "common.h" -#include "nand-core.h" -#include "regs-dsc.h" +#include "map.h" +#include "regs-clock.h" +#include "regs-gpio.h" + +#include "cpu.h" +#include "devs.h" +#include "pm.h" + +#include "s3c24xx.h" +#include "nand-core-s3c24xx.h" +#include "regs-dsc-s3c24xx.h" #include "s3c2412-power.h" #ifndef CONFIG_CPU_S3C2412_ONLY @@ -57,7 +55,7 @@ static inline void s3c2412_init_gpio2(void) /* Initial IO mappings */ -static struct map_desc s3c2412_iodesc[] __initdata = { +static struct map_desc s3c2412_iodesc[] __initdata __maybe_unused = { IODESC_ENT(CLKPWR), IODESC_ENT(TIMER), IODESC_ENT(WATCHDOG), diff --git a/arch/arm/mach-s3c24xx/include/mach/s3c2412.h b/arch/arm/mach-s3c/s3c2412.h index 4ff83f956cfb..ed09a0e13bd8 100644 --- a/arch/arm/mach-s3c24xx/include/mach/s3c2412.h +++ b/arch/arm/mach-s3c/s3c2412.h @@ -8,6 +8,8 @@ #ifndef __ARCH_ARM_MACH_S3C24XX_S3C2412_H #define __ARCH_ARM_MACH_S3C24XX_S3C2412_H __FILE__ +#include "map-s3c.h" + #define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x)) #define S3C2412_EBIREG(x) (S3C2412_VA_EBI + (x)) diff --git a/arch/arm/mach-s3c24xx/s3c2416.c b/arch/arm/mach-s3c/s3c2416.c index 9514196cad8c..126e6ed29713 100644 --- a/arch/arm/mach-s3c24xx/s3c2416.c +++ b/arch/arm/mach-s3c/s3c2416.c @@ -26,32 +26,32 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> -#include <mach/gpio-samsung.h> +#include "map.h" +#include "gpio-samsung.h" #include <asm/proc-fns.h> #include <asm/irq.h> #include <asm/system_misc.h> -#include <mach/regs-s3c2443-clock.h> -#include <mach/rtc-core.h> +#include "regs-s3c2443-clock.h" +#include "rtc-core-s3c24xx.h" -#include <plat/gpio-core.h> -#include <plat/gpio-cfg.h> -#include <plat/gpio-cfg-helpers.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/sdhci.h> -#include <plat/pm.h> +#include "gpio-core.h" +#include "gpio-cfg.h" +#include "gpio-cfg-helpers.h" +#include "devs.h" +#include "cpu.h" +#include "sdhci.h" +#include "pm.h" -#include <plat/iic-core.h> -#include <plat/adc-core.h> +#include "iic-core.h" +#include "adc-core.h" -#include "common.h" -#include "fb-core.h" -#include "nand-core.h" -#include "spi-core.h" +#include "s3c24xx.h" +#include "fb-core-s3c24xx.h" +#include "nand-core-s3c24xx.h" +#include "spi-core-s3c24xx.h" -static struct map_desc s3c2416_iodesc[] __initdata = { +static struct map_desc s3c2416_iodesc[] __initdata __maybe_unused = { IODESC_ENT(WATCHDOG), IODESC_ENT(CLKPWR), IODESC_ENT(TIMER), diff --git a/arch/arm/mach-s3c24xx/s3c2440.c b/arch/arm/mach-s3c/s3c2440.c index 451d9851b0a7..c6cdee4987e8 100644 --- a/arch/arm/mach-s3c24xx/s3c2440.c +++ b/arch/arm/mach-s3c/s3c2440.c @@ -23,19 +23,18 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> -#include <mach/gpio-samsung.h> #include <asm/irq.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/pm.h> +#include "devs.h" +#include "cpu.h" +#include "pm.h" -#include <plat/gpio-core.h> -#include <plat/gpio-cfg.h> -#include <plat/gpio-cfg-helpers.h> +#include "gpio-core.h" +#include "gpio-cfg.h" +#include "gpio-cfg-helpers.h" +#include "gpio-samsung.h" -#include "common.h" +#include "s3c24xx.h" static struct device s3c2440_dev = { .bus = &s3c2440_subsys, diff --git a/arch/arm/mach-s3c24xx/s3c2442.c b/arch/arm/mach-s3c/s3c2442.c index 432d68325c9d..0c0e30b6688f 100644 --- a/arch/arm/mach-s3c24xx/s3c2442.c +++ b/arch/arm/mach-s3c/s3c2442.c @@ -21,21 +21,20 @@ #include <linux/clk.h> #include <linux/io.h> -#include <mach/hardware.h> -#include <mach/gpio-samsung.h> #include <linux/atomic.h> #include <asm/irq.h> -#include <mach/regs-clock.h> +#include "regs-clock.h" -#include <plat/cpu.h> -#include <plat/pm.h> +#include "cpu.h" +#include "pm.h" -#include <plat/gpio-core.h> -#include <plat/gpio-cfg.h> -#include <plat/gpio-cfg-helpers.h> +#include "gpio-core.h" +#include "gpio-cfg.h" +#include "gpio-cfg-helpers.h" +#include "gpio-samsung.h" -#include "common.h" +#include "s3c24xx.h" static struct device s3c2442_dev = { .bus = &s3c2442_subsys, diff --git a/arch/arm/mach-s3c24xx/s3c2443.c b/arch/arm/mach-s3c/s3c2443.c index 4cbeb74cf3d6..08f910144246 100644 --- a/arch/arm/mach-s3c24xx/s3c2443.c +++ b/arch/arm/mach-s3c/s3c2443.c @@ -23,26 +23,28 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> -#include <mach/gpio-samsung.h> +#include "map.h" +#include "gpio-samsung.h" +#include <mach/irqs.h> #include <asm/irq.h> #include <asm/system_misc.h> -#include <mach/regs-s3c2443-clock.h> -#include <mach/rtc-core.h> +#include "regs-s3c2443-clock.h" +#include "rtc-core-s3c24xx.h" -#include <plat/gpio-core.h> -#include <plat/gpio-cfg.h> -#include <plat/gpio-cfg-helpers.h> -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/adc-core.h> +#include "gpio-core.h" +#include "gpio-cfg.h" +#include "gpio-cfg-helpers.h" +#include "devs.h" +#include "cpu.h" +#include "adc-core.h" -#include "fb-core.h" -#include "nand-core.h" -#include "spi-core.h" +#include "s3c24xx.h" +#include "fb-core-s3c24xx.h" +#include "nand-core-s3c24xx.h" +#include "spi-core-s3c24xx.h" -static struct map_desc s3c2443_iodesc[] __initdata = { +static struct map_desc s3c2443_iodesc[] __initdata __maybe_unused = { IODESC_ENT(WATCHDOG), IODESC_ENT(CLKPWR), IODESC_ENT(TIMER), diff --git a/arch/arm/mach-s3c24xx/s3c244x.c b/arch/arm/mach-s3c/s3c244x.c index a75f588b9d45..95df3491e650 100644 --- a/arch/arm/mach-s3c24xx/s3c244x.c +++ b/arch/arm/mach-s3c/s3c244x.c @@ -25,23 +25,21 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> +#include "map.h" #include <asm/irq.h> -#include <plat/cpu-freq.h> +#include "regs-clock.h" +#include "regs-gpio.h" -#include <mach/regs-clock.h> -#include <mach/regs-gpio.h> +#include "devs.h" +#include "cpu.h" +#include "pm.h" -#include <plat/devs.h> -#include <plat/cpu.h> -#include <plat/pm.h> +#include "s3c24xx.h" +#include "nand-core-s3c24xx.h" +#include "regs-dsc-s3c24xx.h" -#include "common.h" -#include "nand-core.h" -#include "regs-dsc.h" - -static struct map_desc s3c244x_iodesc[] __initdata = { +static struct map_desc s3c244x_iodesc[] __initdata __maybe_unused = { IODESC_ENT(CLKPWR), IODESC_ENT(TIMER), IODESC_ENT(WATCHDOG), diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c/s3c24xx.c index 3dc029c2d2cb..ccfed48c98aa 100644 --- a/arch/arm/mach-s3c24xx/common.c +++ b/arch/arm/mach-s3c/s3c24xx.c @@ -17,11 +17,14 @@ #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/io.h> +#include <linux/platform_data/clk-s3c2410.h> #include <linux/platform_data/dma-s3c24xx.h> #include <linux/dmaengine.h> +#include <linux/clk/samsung.h> -#include <mach/hardware.h> -#include <mach/regs-clock.h> +#include "hardware-s3c24xx.h" +#include "map.h" +#include "regs-clock.h" #include <asm/irq.h> #include <asm/cacheflush.h> #include <asm/system_info.h> @@ -30,15 +33,14 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/regs-gpio.h> -#include <mach/dma.h> +#include "regs-gpio.h" +#include "dma-s3c24xx.h" -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/cpu-freq.h> -#include <plat/pwm-core.h> +#include "cpu.h" +#include "devs.h" +#include "pwm-core.h" -#include "common.h" +#include "s3c24xx.h" /* table of supported CPUs */ @@ -137,7 +139,7 @@ static struct cpu_table cpu_ids[] __initdata = { /* minimal IO mapping */ -static struct map_desc s3c_iodesc[] __initdata = { +static struct map_desc s3c_iodesc[] __initdata __maybe_unused = { IODESC_ENT(GPIO), IODESC_ENT(IRQ), IODESC_ENT(MEMCTRL), @@ -220,13 +222,13 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) samsung_pwm_set_platdata(&s3c24xx_pwm_variant); } -void __init samsung_set_timer_source(unsigned int event, unsigned int source) +void __init s3c24xx_set_timer_source(unsigned int event, unsigned int source) { s3c24xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1; s3c24xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source)); } -void __init samsung_timer_init(void) +void __init s3c24xx_timer_init(void) { unsigned int timer_irqs[SAMSUNG_PWM_NUM] = { IRQ_TIMER0, IRQ_TIMER1, IRQ_TIMER2, IRQ_TIMER3, IRQ_TIMER4, @@ -662,10 +664,17 @@ static struct resource s3c2410_dclk_resource[] = { [0] = DEFINE_RES_MEM(0x56000084, 0x4), }; +static struct s3c2410_clk_platform_data s3c_clk_platform_data = { + .modify_misccr = s3c2410_modify_misccr, +}; + struct platform_device s3c2410_device_dclk = { .name = "s3c2410-dclk", .id = 0, .num_resources = ARRAY_SIZE(s3c2410_dclk_resource), .resource = s3c2410_dclk_resource, + .dev = { + .platform_data = &s3c_clk_platform_data, + }, }; #endif diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c/s3c24xx.h index d087b20e8857..5848bef5bb49 100644 --- a/arch/arm/mach-s3c24xx/common.h +++ b/arch/arm/mach-s3c/s3c24xx.h @@ -10,6 +10,7 @@ #define __ARCH_ARM_MACH_S3C24XX_COMMON_H __FILE__ #include <linux/reboot.h> +#include <mach/irqs.h> struct s3c2410_uartcfg; @@ -108,19 +109,16 @@ extern struct platform_device s3c2443_device_dma; extern struct platform_device s3c2410_device_dclk; -#ifdef CONFIG_S3C2410_COMMON_CLK -void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f, - int current_soc, - void __iomem *reg_base); -#endif -#ifdef CONFIG_S3C2412_COMMON_CLK -void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f, - unsigned long ext_f, void __iomem *reg_base); -#endif -#ifdef CONFIG_S3C2443_COMMON_CLK -void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f, - int current_soc, - void __iomem *reg_base); -#endif +enum s3c24xx_timer_mode { + S3C24XX_PWM0, + S3C24XX_PWM1, + S3C24XX_PWM2, + S3C24XX_PWM3, + S3C24XX_PWM4, +}; + +extern void __init s3c24xx_set_timer_source(enum s3c24xx_timer_mode event, + enum s3c24xx_timer_mode source); +extern void __init s3c24xx_timer_init(void); #endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */ diff --git a/arch/arm/mach-s3c64xx/s3c6400.c b/arch/arm/mach-s3c/s3c6400.c index 545eea716db8..802f4fb7462d 100644 --- a/arch/arm/mach-s3c64xx/s3c6400.c +++ b/arch/arm/mach-s3c/s3c6400.c @@ -26,19 +26,17 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> #include <asm/irq.h> -#include <plat/cpu-freq.h> -#include <mach/regs-clock.h> +#include "regs-clock.h" -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/sdhci.h> -#include <plat/iic-core.h> +#include "cpu.h" +#include "devs.h" +#include "sdhci.h" +#include "iic-core.h" -#include "common.h" -#include "onenand-core.h" +#include "s3c64xx.h" +#include "onenand-core-s3c64xx.h" void __init s3c6400_map_io(void) { diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c/s3c6410.c index 47e04e019624..dae17d5fd092 100644 --- a/arch/arm/mach-s3c64xx/s3c6410.c +++ b/arch/arm/mach-s3c/s3c6410.c @@ -27,21 +27,20 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> #include <asm/irq.h> -#include <plat/cpu-freq.h> -#include <mach/regs-clock.h> +#include <linux/soc/samsung/s3c-pm.h> +#include "regs-clock.h" -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/sdhci.h> -#include <plat/adc-core.h> -#include <plat/iic-core.h> +#include "cpu.h" +#include "devs.h" +#include "sdhci.h" +#include "adc-core.h" +#include "iic-core.h" -#include "ata-core.h" -#include "common.h" -#include "onenand-core.h" +#include "ata-core-s3c64xx.h" +#include "s3c64xx.h" +#include "onenand-core-s3c64xx.h" void __init s3c6410_map_io(void) { diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c/s3c64xx.c index 13e91074308a..4dfb648142f2 100644 --- a/arch/arm/mach-s3c64xx/common.c +++ b/arch/arm/mach-s3c/s3c64xx.c @@ -24,6 +24,7 @@ #include <linux/platform_device.h> #include <linux/reboot.h> #include <linux/io.h> +#include <linux/clk/samsung.h> #include <linux/dma-mapping.h> #include <linux/irq.h> #include <linux/gpio.h> @@ -34,22 +35,19 @@ #include <asm/mach/map.h> #include <asm/system_misc.h> -#include <mach/map.h> +#include "map.h" #include <mach/irqs.h> -#include <mach/hardware.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> - -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/pm.h> -#include <plat/gpio-cfg.h> -#include <plat/pwm-core.h> -#include <plat/regs-irqtype.h> - -#include "common.h" -#include "irq-uart.h" -#include "watchdog-reset.h" +#include "regs-gpio.h" +#include "gpio-samsung.h" + +#include "cpu.h" +#include "devs.h" +#include "pm.h" +#include "gpio-cfg.h" +#include "pwm-core.h" +#include "regs-irqtype.h" +#include "s3c64xx.h" +#include "irq-uart-s3c64xx.h" /* External clock frequency */ static unsigned long xtal_f __ro_after_init = 12000000; @@ -97,7 +95,12 @@ static struct cpu_table cpu_ids[] __initdata = { /* minimal IO mapping */ -/* see notes on uart map in arch/arm/mach-s3c64xx/include/mach/debug-macro.S */ +/* + * note, for the boot process to work we have to keep the UART + * virtual address aligned to an 1MiB boundary for the L1 + * mapping the head code makes. We keep the UART virtual address + * aligned and add in the offset when we load the value here. + */ #define UART_OFFS (S3C_PA_UART & 0xfffff) static struct map_desc s3c_iodesc[] __initdata = { @@ -170,13 +173,13 @@ static struct samsung_pwm_variant s3c64xx_pwm_variant = { .tclk_mask = (1 << 7) | (1 << 6) | (1 << 5), }; -void __init samsung_set_timer_source(unsigned int event, unsigned int source) +void __init s3c64xx_set_timer_source(unsigned int event, unsigned int source) { s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1; s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source)); } -void __init samsung_timer_init(void) +void __init s3c64xx_timer_init(void) { unsigned int timer_irqs[SAMSUNG_PWM_NUM] = { IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC, @@ -228,13 +231,7 @@ core_initcall(s3c64xx_dev_init); void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) { - /* - * FIXME: there is no better place to put this at the moment - * (s3c64xx_clk_init needs ioremap and must happen before init_time - * samsung_wdt_reset_init needs clocks) - */ s3c64xx_clk_init(NULL, xtal_f, xusbxti_f, soc_is_s3c6400(), S3C_VA_SYS); - samsung_wdt_reset_init(S3C_VA_WATCHDOG); printk(KERN_DEBUG "%s: initialising interrupts\n", __func__); @@ -428,12 +425,3 @@ static int __init s3c64xx_init_irq_eint(void) return 0; } arch_initcall(s3c64xx_init_irq_eint); - -void s3c64xx_restart(enum reboot_mode mode, const char *cmd) -{ - if (mode != REBOOT_SOFT) - samsung_wdt_reset(); - - /* if all else fails, or mode was for soft, jump to 0 */ - soft_restart(0); -} diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c/s3c64xx.h index 03670887a764..92258e4f60f6 100644 --- a/arch/arm/mach-s3c64xx/common.h +++ b/arch/arm/mach-s3c/s3c64xx.h @@ -19,11 +19,7 @@ void s3c64xx_init_irq(u32 vic0, u32 vic1); void s3c64xx_init_io(struct map_desc *mach_desc, int size); -void s3c64xx_restart(enum reboot_mode mode, const char *cmd); - struct device_node; -void s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, - unsigned long xusbxti_f, bool is_s3c6400, void __iomem *reg_base); void s3c64xx_set_xtal_freq(unsigned long freq); void s3c64xx_set_xusbxti_freq(unsigned long freq); @@ -54,4 +50,17 @@ extern struct pl08x_platform_data s3c64xx_dma0_plat_data; extern struct pl08x_platform_data s3c64xx_dma1_plat_data; #endif +/* Samsung HR-Timer Clock mode */ +enum s3c64xx_timer_mode { + S3C64XX_PWM0, + S3C64XX_PWM1, + S3C64XX_PWM2, + S3C64XX_PWM3, + S3C64XX_PWM4, +}; + +extern void __init s3c64xx_set_timer_source(enum s3c64xx_timer_mode event, + enum s3c64xx_timer_mode source); +extern void __init s3c64xx_timer_init(void); + #endif /* __ARCH_ARM_MACH_S3C64XX_COMMON_H */ diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/mach-s3c/sdhci.h index 5731e42ea208..9f9d419e58d7 100644 --- a/arch/arm/plat-samsung/include/plat/sdhci.h +++ b/arch/arm/mach-s3c/sdhci.h @@ -15,7 +15,7 @@ #define __PLAT_S3C_SDHCI_H __FILE__ #include <linux/platform_data/mmc-sdhci-s3c.h> -#include <plat/devs.h> +#include "devs.h" /* s3c_sdhci_set_platdata() - common helper for setting SDHCI platform data * @pd: The default platform data for this device. diff --git a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c b/arch/arm/mach-s3c/setup-fb-24bpp-s3c64xx.c index 2c7178b26ebb..cfa34b55ca21 100644 --- a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c +++ b/arch/arm/mach-s3c/setup-fb-24bpp-s3c64xx.c @@ -12,9 +12,9 @@ #include <linux/fb.h> #include <linux/gpio.h> -#include <plat/fb.h> -#include <plat/gpio-cfg.h> -#include <mach/gpio-samsung.h> +#include "fb.h" +#include "gpio-cfg.h" +#include "gpio-samsung.h" void s3c64xx_fb_gpio_setup_24bpp(void) { diff --git a/arch/arm/mach-s3c24xx/setup-i2c.c b/arch/arm/mach-s3c/setup-i2c-s3c24xx.c index 1a01d44b5910..0d88366b234c 100644 --- a/arch/arm/mach-s3c24xx/setup-i2c.c +++ b/arch/arm/mach-s3c/setup-i2c-s3c24xx.c @@ -10,11 +10,11 @@ struct platform_device; -#include <plat/gpio-cfg.h> #include <linux/platform_data/i2c-s3c2410.h> -#include <mach/hardware.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> + +#include "gpio-cfg.h" +#include "regs-gpio.h" +#include "gpio-samsung.h" void s3c_i2c0_cfg_gpio(struct platform_device *dev) { diff --git a/arch/arm/mach-s3c64xx/setup-i2c0.c b/arch/arm/mach-s3c/setup-i2c0-s3c64xx.c index 552eb50da38c..a6ef8d2bc995 100644 --- a/arch/arm/mach-s3c64xx/setup-i2c0.c +++ b/arch/arm/mach-s3c/setup-i2c0-s3c64xx.c @@ -14,8 +14,8 @@ struct platform_device; /* don't need the contents */ #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/gpio-cfg.h> -#include <mach/gpio-samsung.h> +#include "gpio-cfg.h" +#include "gpio-samsung.h" void s3c_i2c0_cfg_gpio(struct platform_device *dev) { diff --git a/arch/arm/mach-s3c64xx/setup-i2c1.c b/arch/arm/mach-s3c/setup-i2c1-s3c64xx.c index d231f0fc508d..0fe37363d26e 100644 --- a/arch/arm/mach-s3c64xx/setup-i2c1.c +++ b/arch/arm/mach-s3c/setup-i2c1-s3c64xx.c @@ -14,8 +14,8 @@ struct platform_device; /* don't need the contents */ #include <linux/platform_data/i2c-s3c2410.h> -#include <plat/gpio-cfg.h> -#include <mach/gpio-samsung.h> +#include "gpio-cfg.h" +#include "gpio-samsung.h" void s3c_i2c1_cfg_gpio(struct platform_device *dev) { diff --git a/arch/arm/mach-s3c64xx/setup-ide.c b/arch/arm/mach-s3c/setup-ide-s3c64xx.c index 810139a807ce..f11f2b02e49f 100644 --- a/arch/arm/mach-s3c64xx/setup-ide.c +++ b/arch/arm/mach-s3c/setup-ide-s3c64xx.c @@ -9,12 +9,13 @@ #include <linux/gpio.h> #include <linux/io.h> -#include <mach/map.h> -#include <mach/regs-clock.h> -#include <plat/gpio-cfg.h> -#include <mach/gpio-samsung.h> #include <linux/platform_data/ata-samsung_cf.h> +#include "map.h" +#include "regs-clock.h" +#include "gpio-cfg.h" +#include "gpio-samsung.h" + void s3c64xx_ide_setup_gpio(void) { u32 reg; diff --git a/arch/arm/mach-s3c64xx/setup-keypad.c b/arch/arm/mach-s3c/setup-keypad-s3c64xx.c index 351961025273..8463ad37c6ab 100644 --- a/arch/arm/mach-s3c64xx/setup-keypad.c +++ b/arch/arm/mach-s3c/setup-keypad-s3c64xx.c @@ -6,9 +6,9 @@ // GPIO configuration for S3C64XX KeyPad device #include <linux/gpio.h> -#include <plat/gpio-cfg.h> -#include <plat/keypad.h> -#include <mach/gpio-samsung.h> +#include "gpio-cfg.h" +#include "keypad.h" +#include "gpio-samsung.h" void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) { diff --git a/arch/arm/mach-s3c24xx/setup-sdhci-gpio.c b/arch/arm/mach-s3c/setup-sdhci-gpio-s3c24xx.c index 218346a36d1e..02131b3a731d 100644 --- a/arch/arm/mach-s3c24xx/setup-sdhci-gpio.c +++ b/arch/arm/mach-s3c/setup-sdhci-gpio-s3c24xx.c @@ -14,9 +14,10 @@ #include <linux/io.h> #include <linux/gpio.h> -#include <mach/regs-gpio.h> -#include <mach/gpio-samsung.h> -#include <plat/gpio-cfg.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" +#include "gpio-cfg.h" +#include "sdhci.h" void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) { diff --git a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c b/arch/arm/mach-s3c/setup-sdhci-gpio-s3c64xx.c index 138455af4937..646ff949acd5 100644 --- a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c +++ b/arch/arm/mach-s3c/setup-sdhci-gpio-s3c64xx.c @@ -13,9 +13,9 @@ #include <linux/io.h> #include <linux/gpio.h> -#include <plat/gpio-cfg.h> -#include <plat/sdhci.h> -#include <mach/gpio-samsung.h> +#include "gpio-cfg.h" +#include "sdhci.h" +#include "gpio-samsung.h" void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) { diff --git a/arch/arm/mach-s3c24xx/setup-spi.c b/arch/arm/mach-s3c/setup-spi-s3c24xx.c index 6c2b96a82da5..93fa1bbc9d5c 100644 --- a/arch/arm/mach-s3c24xx/setup-spi.c +++ b/arch/arm/mach-s3c/setup-spi-s3c24xx.c @@ -8,10 +8,10 @@ #include <linux/gpio.h> #include <linux/platform_device.h> -#include <plat/gpio-cfg.h> +#include "gpio-cfg.h" -#include <mach/hardware.h> -#include <mach/regs-gpio.h> +#include "hardware-s3c24xx.h" +#include "regs-gpio.h" #ifdef CONFIG_S3C64XX_DEV_SPI0 int s3c64xx_spi0_cfg_gpio(void) diff --git a/arch/arm/mach-s3c64xx/setup-spi.c b/arch/arm/mach-s3c/setup-spi-s3c64xx.c index 39dfae1f46e7..efcf78d41585 100644 --- a/arch/arm/mach-s3c64xx/setup-spi.c +++ b/arch/arm/mach-s3c/setup-spi-s3c64xx.c @@ -4,8 +4,9 @@ // http://www.samsung.com/ #include <linux/gpio.h> -#include <plat/gpio-cfg.h> -#include <mach/gpio-samsung.h> +#include <linux/platform_data/spi-s3c64xx.h> +#include "gpio-cfg.h" +#include "gpio-samsung.h" #ifdef CONFIG_S3C64XX_DEV_SPI0 int s3c64xx_spi0_cfg_gpio(void) diff --git a/arch/arm/mach-s3c24xx/setup-ts.c b/arch/arm/mach-s3c/setup-ts-s3c24xx.c index 53a14d4f4852..57363eaeb7e8 100644 --- a/arch/arm/mach-s3c24xx/setup-ts.c +++ b/arch/arm/mach-s3c/setup-ts-s3c24xx.c @@ -10,12 +10,14 @@ struct platform_device; /* don't need the contents */ -#include <plat/gpio-cfg.h> -#include <mach/hardware.h> -#include <mach/gpio-samsung.h> +#include <linux/platform_data/touchscreen-s3c2410.h> + +#include "gpio-cfg.h" +#include "gpio-samsung.h" /** * s3c24xx_ts_cfg_gpio - configure gpio for s3c2410 systems + * @dev: Device to configure GPIO for (ignored) * * Configure the GPIO for the S3C2410 system, where we have external FETs * connected to the device (later systems such as the S3C2440 integrate diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c/setup-usb-phy-s3c64xx.c index d6b0e3b268af..500d105afd6b 100644 --- a/arch/arm/mach-s3c64xx/setup-usb-phy.c +++ b/arch/arm/mach-s3c/setup-usb-phy-s3c64xx.c @@ -8,12 +8,12 @@ #include <linux/err.h> #include <linux/io.h> #include <linux/platform_device.h> -#include <mach/map.h> -#include <plat/cpu.h> -#include <plat/usb-phy.h> +#include "map.h" +#include "cpu.h" +#include "usb-phy.h" -#include "regs-sys.h" -#include "regs-usb-hsotg-phy.h" +#include "regs-sys-s3c64xx.h" +#include "regs-usb-hsotg-phy-s3c64xx.h" enum samsung_usb_phy_type { USB_PHY_TYPE_DEVICE, @@ -31,7 +31,7 @@ static int s3c_usb_otgphy_init(struct platform_device *pdev) phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK; xusbxti = clk_get(&pdev->dev, "xusbxti"); - if (xusbxti && !IS_ERR(xusbxti)) { + if (!IS_ERR(xusbxti)) { switch (clk_get_rate(xusbxti)) { case 12 * MHZ: phyclk |= S3C_PHYCLK_CLKSEL_12M; diff --git a/arch/arm/mach-s3c24xx/simtec-audio.c b/arch/arm/mach-s3c/simtec-audio.c index 12e17f82dae3..487485bcc2ab 100644 --- a/arch/arm/mach-s3c24xx/simtec-audio.c +++ b/arch/arm/mach-s3c/simtec-audio.c @@ -12,11 +12,12 @@ #include <linux/device.h> #include <linux/io.h> -#include <mach/hardware.h> -#include <mach/regs-gpio.h> +#include "regs-gpio.h" +#include "gpio-samsung.h" +#include "gpio-cfg.h" #include <linux/platform_data/asoc-s3c24xx_simtec.h> -#include <plat/devs.h> +#include "devs.h" #include "bast.h" #include "simtec.h" @@ -65,6 +66,10 @@ int __init simtec_audio_add(const char *name, bool has_lr_routing, if (has_lr_routing) simtec_audio_platdata.startup = simtec_audio_startup_lrroute; + /* 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); + platform_device_register(&s3c_device_iis); platform_device_register(&simtec_audio_dev); return 0; diff --git a/arch/arm/mach-s3c24xx/simtec-nor.c b/arch/arm/mach-s3c/simtec-nor.c index 26b18497e959..a6fba056a747 100644 --- a/arch/arm/mach-s3c24xx/simtec-nor.c +++ b/arch/arm/mach-s3c/simtec-nor.c @@ -21,7 +21,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/map.h> +#include "map.h" #include "bast.h" #include "simtec.h" diff --git a/arch/arm/mach-s3c24xx/simtec-pm.c b/arch/arm/mach-s3c/simtec-pm.c index c19074d81389..490256a766e2 100644 --- a/arch/arm/mach-s3c24xx/simtec-pm.c +++ b/arch/arm/mach-s3c/simtec-pm.c @@ -19,16 +19,14 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/hardware.h> - -#include <mach/map.h> -#include <mach/regs-gpio.h> +#include "map.h" +#include "regs-gpio.h" #include <asm/mach-types.h> -#include <plat/pm.h> +#include "pm.h" -#include "regs-mem.h" +#include "regs-mem-s3c24xx.h" #define COPYRIGHT ", Copyright 2005 Simtec Electronics" diff --git a/arch/arm/mach-s3c24xx/simtec-usb.c b/arch/arm/mach-s3c/simtec-usb.c index dc1016ffed94..18fe0642743a 100644 --- a/arch/arm/mach-s3c24xx/simtec-usb.c +++ b/arch/arm/mach-s3c/simtec-usb.c @@ -23,12 +23,12 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <mach/hardware.h> -#include <mach/gpio-samsung.h> +#include "gpio-samsung.h" +#include <mach/irqs.h> #include <asm/irq.h> #include <linux/platform_data/usb-ohci-s3c2410.h> -#include <plat/devs.h> +#include "devs.h" #include "bast.h" #include "simtec.h" diff --git a/arch/arm/mach-s3c24xx/simtec.h b/arch/arm/mach-s3c/simtec.h index d96bd60872b8..d96bd60872b8 100644 --- a/arch/arm/mach-s3c24xx/simtec.h +++ b/arch/arm/mach-s3c/simtec.h diff --git a/arch/arm/mach-s3c24xx/sleep-s3c2410.S b/arch/arm/mach-s3c/sleep-s3c2410.S index 659f9eff9de2..04aded98782b 100644 --- a/arch/arm/mach-s3c24xx/sleep-s3c2410.S +++ b/arch/arm/mach-s3c/sleep-s3c2410.S @@ -13,13 +13,12 @@ #include <linux/linkage.h> #include <linux/serial_s3c.h> #include <asm/assembler.h> -#include <mach/hardware.h> -#include <mach/map.h> +#include "map.h" -#include <mach/regs-gpio.h> -#include <mach/regs-clock.h> +#include "regs-gpio.h" +#include "regs-clock.h" -#include "regs-mem.h" +#include "regs-mem-s3c24xx.h" /* s3c2410_cpu_suspend * diff --git a/arch/arm/mach-s3c24xx/sleep-s3c2412.S b/arch/arm/mach-s3c/sleep-s3c2412.S index c373f1ca862b..b4b61737fbb2 100644 --- a/arch/arm/mach-s3c24xx/sleep-s3c2412.S +++ b/arch/arm/mach-s3c/sleep-s3c2412.S @@ -8,10 +8,9 @@ #include <linux/linkage.h> #include <asm/assembler.h> -#include <mach/hardware.h> -#include <mach/map.h> +#include "map.h" -#include <mach/regs-irq.h> +#include "regs-irq.h" .text diff --git a/arch/arm/mach-s3c24xx/sleep.S b/arch/arm/mach-s3c/sleep-s3c24xx.S index f0f11ad60c52..4b2af91f3dce 100644 --- a/arch/arm/mach-s3c24xx/sleep.S +++ b/arch/arm/mach-s3c/sleep-s3c24xx.S @@ -13,11 +13,10 @@ #include <linux/linkage.h> #include <linux/serial_s3c.h> #include <asm/assembler.h> -#include <mach/hardware.h> -#include <mach/map.h> +#include "map.h" -#include <mach/regs-gpio.h> -#include <mach/regs-clock.h> +#include "regs-gpio.h" +#include "regs-clock.h" /* * S3C24XX_DEBUG_RESUME is dangerous if your bootloader does not diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c/sleep-s3c64xx.S index 39e16a07a5e4..739e53fbce09 100644 --- a/arch/arm/mach-s3c64xx/sleep.S +++ b/arch/arm/mach-s3c/sleep-s3c64xx.S @@ -11,12 +11,12 @@ #include <linux/linkage.h> #include <asm/assembler.h> -#include <mach/map.h> +#include "map.h" #undef S3C64XX_VA_GPIO #define S3C64XX_VA_GPIO (0x0) -#include <mach/regs-gpio.h> +#include "regs-gpio.h" #define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT)) diff --git a/arch/arm/mach-s3c24xx/spi-core.h b/arch/arm/mach-s3c/spi-core-s3c24xx.h index 1048fac629a2..057667469cc3 100644 --- a/arch/arm/mach-s3c24xx/spi-core.h +++ b/arch/arm/mach-s3c/spi-core-s3c24xx.h @@ -3,8 +3,8 @@ * Copyright (C) 2012 Heiko Stuebner <heiko@sntech.de> */ -#ifndef __PLAT_S3C_SPI_CORE_H -#define __PLAT_S3C_SPI_CORE_H +#ifndef __PLAT_S3C_SPI_CORE_S3C24XX_H +#define __PLAT_S3C_SPI_CORE_S3C24XX_H /* These functions are only for use with the core support code, such as * the cpu specific initialisation code @@ -24,4 +24,4 @@ static inline void s3c24xx_spi_setname(char *name) #endif } -#endif /* __PLAT_S3C_SPI_CORE_H */ +#endif /* __PLAT_S3C_SPI_CORE_S3C24XX_H */ diff --git a/arch/arm/plat-samsung/include/plat/usb-phy.h b/arch/arm/mach-s3c/usb-phy.h index 759d66a0773a..759d66a0773a 100644 --- a/arch/arm/plat-samsung/include/plat/usb-phy.h +++ b/arch/arm/mach-s3c/usb-phy.h diff --git a/arch/arm/mach-s3c24xx/vr1000.h b/arch/arm/mach-s3c/vr1000.h index 3cfa296bec2a..3cfa296bec2a 100644 --- a/arch/arm/mach-s3c24xx/vr1000.h +++ b/arch/arm/mach-s3c/vr1000.h diff --git a/arch/arm/plat-samsung/wakeup-mask.c b/arch/arm/mach-s3c/wakeup-mask.c index 24f96fb80738..b490e7527c66 100644 --- a/arch/arm/plat-samsung/wakeup-mask.c +++ b/arch/arm/mach-s3c/wakeup-mask.c @@ -11,8 +11,8 @@ #include <linux/irq.h> #include <linux/io.h> -#include <plat/wakeup-mask.h> -#include <plat/pm.h> +#include "wakeup-mask.h" +#include "pm.h" void samsung_sync_wakemask(void __iomem *reg, const struct samsung_wakeup_mask *mask, int nr_mask) diff --git a/arch/arm/plat-samsung/include/plat/wakeup-mask.h b/arch/arm/mach-s3c/wakeup-mask.h index 630909e6630b..630909e6630b 100644 --- a/arch/arm/plat-samsung/include/plat/wakeup-mask.h +++ b/arch/arm/mach-s3c/wakeup-mask.h diff --git a/arch/arm/mach-s3c24xx/include/mach/fb.h b/arch/arm/mach-s3c24xx/include/mach/fb.h deleted file mode 100644 index 4e539cb8b884..000000000000 --- a/arch/arm/mach-s3c24xx/include/mach/fb.h +++ /dev/null @@ -1,2 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#include <plat/fb-s3c2410.h> diff --git a/arch/arm/mach-s3c24xx/include/mach/io.h b/arch/arm/mach-s3c24xx/include/mach/io.h deleted file mode 100644 index f960e6d10114..000000000000 --- a/arch/arm/mach-s3c24xx/include/mach/io.h +++ /dev/null @@ -1,212 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * arch/arm/mach-s3c2410/include/mach/io.h - * from arch/arm/mach-rpc/include/mach/io.h - * - * Copyright (C) 1997 Russell King - * (C) 2003 Simtec Electronics -*/ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#include <mach/hardware.h> - -#define IO_SPACE_LIMIT 0xffffffff - -/* - * We use two different types of addressing - PC style addresses, and ARM - * addresses. PC style accesses the PC hardware with the normal PC IO - * addresses, eg 0x3f8 for serial#1. ARM addresses are above A28 - * and are translated to the start of IO. Note that all addresses are - * not shifted left! - */ - -#define __PORT_PCIO(x) ((x) < (1<<28)) - -#define PCIO_BASE (S3C24XX_VA_ISA_WORD) -#define PCIO_BASE_b (S3C24XX_VA_ISA_BYTE) -#define PCIO_BASE_w (S3C24XX_VA_ISA_WORD) -#define PCIO_BASE_l (S3C24XX_VA_ISA_WORD) -/* - * Dynamic IO functions - let the compiler - * optimize the expressions - */ - -#define DECLARE_DYN_OUT(sz,fnsuffix,instr) \ -static inline void __out##fnsuffix (unsigned int val, unsigned int port) \ -{ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "cmp %2, #(1<<28)\n\t" \ - "mov %0, %2\n\t" \ - "addcc %0, %0, %3\n\t" \ - "str" instr " %1, [%0, #0 ] @ out" #fnsuffix \ - : "=&r" (temp) \ - : "r" (val), "r" (port), "Ir" (PCIO_BASE_##fnsuffix) \ - : "cc"); \ -} - - -#define DECLARE_DYN_IN(sz,fnsuffix,instr) \ -static inline unsigned sz __in##fnsuffix (unsigned int port) \ -{ \ - unsigned long temp, value; \ - __asm__ __volatile__( \ - "cmp %2, #(1<<28)\n\t" \ - "mov %0, %2\n\t" \ - "addcc %0, %0, %3\n\t" \ - "ldr" instr " %1, [%0, #0 ] @ in" #fnsuffix \ - : "=&r" (temp), "=r" (value) \ - : "r" (port), "Ir" (PCIO_BASE_##fnsuffix) \ - : "cc"); \ - return (unsigned sz)value; \ -} - -static inline void __iomem *__ioaddr (unsigned long port) -{ - return __PORT_PCIO(port) ? (PCIO_BASE + port) : (void __iomem *)port; -} - -#define DECLARE_IO(sz,fnsuffix,instr) \ - DECLARE_DYN_IN(sz,fnsuffix,instr) \ - DECLARE_DYN_OUT(sz,fnsuffix,instr) - -DECLARE_IO(char,b,"b") -DECLARE_IO(short,w,"h") -DECLARE_IO(int,l,"") - -#undef DECLARE_IO -#undef DECLARE_DYN_IN - -/* - * Constant address IO functions - * - * These have to be macros for the 'J' constraint to work - - * +/-4096 immediate operand. - */ -#define __outbc(value,port) \ -({ \ - if (__PORT_PCIO((port))) \ - __asm__ __volatile__( \ - "strb %0, [%1, %2] @ outbc" \ - : : "r" (value), "r" (PCIO_BASE), "Jr" ((port))); \ - else \ - __asm__ __volatile__( \ - "strb %0, [%1, #0] @ outbc" \ - : : "r" (value), "r" ((port))); \ -}) - -#define __inbc(port) \ -({ \ - unsigned char result; \ - if (__PORT_PCIO((port))) \ - __asm__ __volatile__( \ - "ldrb %0, [%1, %2] @ inbc" \ - : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port))); \ - else \ - __asm__ __volatile__( \ - "ldrb %0, [%1, #0] @ inbc" \ - : "=r" (result) : "r" ((port))); \ - result; \ -}) - -#define __outwc(value,port) \ -({ \ - unsigned long v = value; \ - if (__PORT_PCIO((port))) { \ - if ((port) < 256 && (port) > -256) \ - __asm__ __volatile__( \ - "strh %0, [%1, %2] @ outwc" \ - : : "r" (v), "r" (PCIO_BASE), "Jr" ((port))); \ - else if ((port) > 0) \ - __asm__ __volatile__( \ - "strh %0, [%1, %2] @ outwc" \ - : : "r" (v), \ - "r" (PCIO_BASE + ((port) & ~0xff)), \ - "Jr" (((port) & 0xff))); \ - else \ - __asm__ __volatile__( \ - "strh %0, [%1, #0] @ outwc" \ - : : "r" (v), \ - "r" (PCIO_BASE + (port))); \ - } else \ - __asm__ __volatile__( \ - "strh %0, [%1, #0] @ outwc" \ - : : "r" (v), "r" ((port))); \ -}) - -#define __inwc(port) \ -({ \ - unsigned short result; \ - if (__PORT_PCIO((port))) { \ - if ((port) < 256 && (port) > -256 ) \ - __asm__ __volatile__( \ - "ldrh %0, [%1, %2] @ inwc" \ - : "=r" (result) \ - : "r" (PCIO_BASE), \ - "Jr" ((port))); \ - else if ((port) > 0) \ - __asm__ __volatile__( \ - "ldrh %0, [%1, %2] @ inwc" \ - : "=r" (result) \ - : "r" (PCIO_BASE + ((port) & ~0xff)), \ - "Jr" (((port) & 0xff))); \ - else \ - __asm__ __volatile__( \ - "ldrh %0, [%1, #0] @ inwc" \ - : "=r" (result) \ - : "r" (PCIO_BASE + ((port)))); \ - } else \ - __asm__ __volatile__( \ - "ldrh %0, [%1, #0] @ inwc" \ - : "=r" (result) : "r" ((port))); \ - result; \ -}) - -#define __outlc(value,port) \ -({ \ - unsigned long v = value; \ - if (__PORT_PCIO((port))) \ - __asm__ __volatile__( \ - "str %0, [%1, %2] @ outlc" \ - : : "r" (v), "r" (PCIO_BASE), "Jr" ((port))); \ - else \ - __asm__ __volatile__( \ - "str %0, [%1, #0] @ outlc" \ - : : "r" (v), "r" ((port))); \ -}) - -#define __inlc(port) \ -({ \ - unsigned long result; \ - if (__PORT_PCIO((port))) \ - __asm__ __volatile__( \ - "ldr %0, [%1, %2] @ inlc" \ - : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port))); \ - else \ - __asm__ __volatile__( \ - "ldr %0, [%1, #0] @ inlc" \ - : "=r" (result) : "r" ((port))); \ - result; \ -}) - -#define __ioaddrc(port) ((__PORT_PCIO(port) ? PCIO_BASE + (port) : (void __iomem *)0 + (port))) - -#define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p)) -#define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p)) -#define inl(p) (__builtin_constant_p((p)) ? __inlc(p) : __inl(p)) -#define outb(v,p) (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p)) -#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p)) -#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p)) -#define __ioaddr(p) (__builtin_constant_p((p)) ? __ioaddr(p) : __ioaddrc(p)) - -#define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l) -#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l) -#define insl(p,d,l) __raw_readsl(__ioaddr(p),d,l) - -#define outsb(p,d,l) __raw_writesb(__ioaddr(p),d,l) -#define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l) -#define outsl(p,d,l) __raw_writesl(__ioaddr(p),d,l) - -#endif diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-lcd.h b/arch/arm/mach-s3c24xx/include/mach/regs-lcd.h deleted file mode 100644 index 4c3434f261bb..000000000000 --- a/arch/arm/mach-s3c24xx/include/mach/regs-lcd.h +++ /dev/null @@ -1,157 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk> - * http://www.simtec.co.uk/products/SWLINUX/ - */ - -#ifndef ___ASM_ARCH_REGS_LCD_H -#define ___ASM_ARCH_REGS_LCD_H - -#define S3C2410_LCDREG(x) (x) - -/* LCD control registers */ -#define S3C2410_LCDCON1 S3C2410_LCDREG(0x00) -#define S3C2410_LCDCON2 S3C2410_LCDREG(0x04) -#define S3C2410_LCDCON3 S3C2410_LCDREG(0x08) -#define S3C2410_LCDCON4 S3C2410_LCDREG(0x0C) -#define S3C2410_LCDCON5 S3C2410_LCDREG(0x10) - -#define S3C2410_LCDCON1_CLKVAL(x) ((x) << 8) -#define S3C2410_LCDCON1_MMODE (1<<7) -#define S3C2410_LCDCON1_DSCAN4 (0<<5) -#define S3C2410_LCDCON1_STN4 (1<<5) -#define S3C2410_LCDCON1_STN8 (2<<5) -#define S3C2410_LCDCON1_TFT (3<<5) - -#define S3C2410_LCDCON1_STN1BPP (0<<1) -#define S3C2410_LCDCON1_STN2GREY (1<<1) -#define S3C2410_LCDCON1_STN4GREY (2<<1) -#define S3C2410_LCDCON1_STN8BPP (3<<1) -#define S3C2410_LCDCON1_STN12BPP (4<<1) - -#define S3C2410_LCDCON1_TFT1BPP (8<<1) -#define S3C2410_LCDCON1_TFT2BPP (9<<1) -#define S3C2410_LCDCON1_TFT4BPP (10<<1) -#define S3C2410_LCDCON1_TFT8BPP (11<<1) -#define S3C2410_LCDCON1_TFT16BPP (12<<1) -#define S3C2410_LCDCON1_TFT24BPP (13<<1) - -#define S3C2410_LCDCON1_ENVID (1) - -#define S3C2410_LCDCON1_MODEMASK 0x1E - -#define S3C2410_LCDCON2_VBPD(x) ((x) << 24) -#define S3C2410_LCDCON2_LINEVAL(x) ((x) << 14) -#define S3C2410_LCDCON2_VFPD(x) ((x) << 6) -#define S3C2410_LCDCON2_VSPW(x) ((x) << 0) - -#define S3C2410_LCDCON2_GET_VBPD(x) ( ((x) >> 24) & 0xFF) -#define S3C2410_LCDCON2_GET_VFPD(x) ( ((x) >> 6) & 0xFF) -#define S3C2410_LCDCON2_GET_VSPW(x) ( ((x) >> 0) & 0x3F) - -#define S3C2410_LCDCON3_HBPD(x) ((x) << 19) -#define S3C2410_LCDCON3_WDLY(x) ((x) << 19) -#define S3C2410_LCDCON3_HOZVAL(x) ((x) << 8) -#define S3C2410_LCDCON3_HFPD(x) ((x) << 0) -#define S3C2410_LCDCON3_LINEBLANK(x)((x) << 0) - -#define S3C2410_LCDCON3_GET_HBPD(x) ( ((x) >> 19) & 0x7F) -#define S3C2410_LCDCON3_GET_HFPD(x) ( ((x) >> 0) & 0xFF) - -/* LDCCON4 changes for STN mode on the S3C2412 */ - -#define S3C2410_LCDCON4_MVAL(x) ((x) << 8) -#define S3C2410_LCDCON4_HSPW(x) ((x) << 0) -#define S3C2410_LCDCON4_WLH(x) ((x) << 0) - -#define S3C2410_LCDCON4_GET_HSPW(x) ( ((x) >> 0) & 0xFF) - -#define S3C2410_LCDCON5_BPP24BL (1<<12) -#define S3C2410_LCDCON5_FRM565 (1<<11) -#define S3C2410_LCDCON5_INVVCLK (1<<10) -#define S3C2410_LCDCON5_INVVLINE (1<<9) -#define S3C2410_LCDCON5_INVVFRAME (1<<8) -#define S3C2410_LCDCON5_INVVD (1<<7) -#define S3C2410_LCDCON5_INVVDEN (1<<6) -#define S3C2410_LCDCON5_INVPWREN (1<<5) -#define S3C2410_LCDCON5_INVLEND (1<<4) -#define S3C2410_LCDCON5_PWREN (1<<3) -#define S3C2410_LCDCON5_ENLEND (1<<2) -#define S3C2410_LCDCON5_BSWP (1<<1) -#define S3C2410_LCDCON5_HWSWP (1<<0) - -/* framebuffer start addressed */ -#define S3C2410_LCDSADDR1 S3C2410_LCDREG(0x14) -#define S3C2410_LCDSADDR2 S3C2410_LCDREG(0x18) -#define S3C2410_LCDSADDR3 S3C2410_LCDREG(0x1C) - -#define S3C2410_LCDBANK(x) ((x) << 21) -#define S3C2410_LCDBASEU(x) (x) - -#define S3C2410_OFFSIZE(x) ((x) << 11) -#define S3C2410_PAGEWIDTH(x) (x) - -/* colour lookup and miscellaneous controls */ - -#define S3C2410_REDLUT S3C2410_LCDREG(0x20) -#define S3C2410_GREENLUT S3C2410_LCDREG(0x24) -#define S3C2410_BLUELUT S3C2410_LCDREG(0x28) - -#define S3C2410_DITHMODE S3C2410_LCDREG(0x4C) -#define S3C2410_TPAL S3C2410_LCDREG(0x50) - -#define S3C2410_TPAL_EN (1<<24) - -/* interrupt info */ -#define S3C2410_LCDINTPND S3C2410_LCDREG(0x54) -#define S3C2410_LCDSRCPND S3C2410_LCDREG(0x58) -#define S3C2410_LCDINTMSK S3C2410_LCDREG(0x5C) -#define S3C2410_LCDINT_FIWSEL (1<<2) -#define S3C2410_LCDINT_FRSYNC (1<<1) -#define S3C2410_LCDINT_FICNT (1<<0) - -/* s3c2442 extra stn registers */ - -#define S3C2442_REDLUT S3C2410_LCDREG(0x20) -#define S3C2442_GREENLUT S3C2410_LCDREG(0x24) -#define S3C2442_BLUELUT S3C2410_LCDREG(0x28) -#define S3C2442_DITHMODE S3C2410_LCDREG(0x20) - -#define S3C2410_LPCSEL S3C2410_LCDREG(0x60) - -#define S3C2410_TFTPAL(x) S3C2410_LCDREG((0x400 + (x)*4)) - -/* S3C2412 registers */ - -#define S3C2412_TPAL S3C2410_LCDREG(0x20) - -#define S3C2412_LCDINTPND S3C2410_LCDREG(0x24) -#define S3C2412_LCDSRCPND S3C2410_LCDREG(0x28) -#define S3C2412_LCDINTMSK S3C2410_LCDREG(0x2C) - -#define S3C2412_TCONSEL S3C2410_LCDREG(0x30) - -#define S3C2412_LCDCON6 S3C2410_LCDREG(0x34) -#define S3C2412_LCDCON7 S3C2410_LCDREG(0x38) -#define S3C2412_LCDCON8 S3C2410_LCDREG(0x3C) -#define S3C2412_LCDCON9 S3C2410_LCDREG(0x40) - -#define S3C2412_REDLUT(x) S3C2410_LCDREG(0x44 + ((x)*4)) -#define S3C2412_GREENLUT(x) S3C2410_LCDREG(0x60 + ((x)*4)) -#define S3C2412_BLUELUT(x) S3C2410_LCDREG(0x98 + ((x)*4)) - -#define S3C2412_FRCPAT(x) S3C2410_LCDREG(0xB4 + ((x)*4)) - -/* general registers */ - -/* base of the LCD registers, where INTPND, INTSRC and then INTMSK - * are available. */ - -#define S3C2410_LCDINTBASE S3C2410_LCDREG(0x54) -#define S3C2412_LCDINTBASE S3C2410_LCDREG(0x24) - -#define S3C24XX_LCDINTPND (0x00) -#define S3C24XX_LCDSRCPND (0x04) -#define S3C24XX_LCDINTMSK (0x08) - -#endif /* ___ASM_ARCH_REGS_LCD_H */ diff --git a/arch/arm/mach-s3c24xx/setup-camif.c b/arch/arm/mach-s3c24xx/setup-camif.c deleted file mode 100644 index 2b262fae3f61..000000000000 --- a/arch/arm/mach-s3c24xx/setup-camif.c +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.com> -// -// Helper functions for S3C24XX/S3C64XX SoC series CAMIF driver - -#include <linux/gpio.h> -#include <plat/gpio-cfg.h> -#include <mach/gpio-samsung.h> - -/* Number of camera port pins, without FIELD */ -#define S3C_CAMIF_NUM_GPIOS 13 - -/* Default camera port configuration helpers. */ - -static void camif_get_gpios(int *gpio_start, int *gpio_reset) -{ -#ifdef CONFIG_ARCH_S3C24XX - *gpio_start = S3C2410_GPJ(0); - *gpio_reset = S3C2410_GPJ(12); -#else - /* s3c64xx */ - *gpio_start = S3C64XX_GPF(0); - *gpio_reset = S3C64XX_GPF(3); -#endif -} - -int s3c_camif_gpio_get(void) -{ - int gpio_start, gpio_reset; - int ret, i; - - camif_get_gpios(&gpio_start, &gpio_reset); - - for (i = 0; i < S3C_CAMIF_NUM_GPIOS; i++) { - int gpio = gpio_start + i; - - if (gpio == gpio_reset) - continue; - - ret = gpio_request(gpio, "camif"); - if (!ret) - ret = s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); - if (ret) { - pr_err("failed to configure GPIO %d\n", gpio); - for (--i; i >= 0; i--) - gpio_free(gpio--); - return ret; - } - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); - } - - return 0; -} - -void s3c_camif_gpio_put(void) -{ - int i, gpio_start, gpio_reset; - - camif_get_gpios(&gpio_start, &gpio_reset); - - for (i = 0; i < S3C_CAMIF_NUM_GPIOS; i++) { - int gpio = gpio_start + i; - if (gpio != gpio_reset) - gpio_free(gpio); - } -} diff --git a/arch/arm/mach-s3c64xx/include/mach/hardware.h b/arch/arm/mach-s3c64xx/include/mach/hardware.h deleted file mode 100644 index c4ed359474de..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/hardware.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* linux/arch/arm/mach-s3c6400/include/mach/hardware.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C6400 - Hardware support - */ - -#ifndef __ASM_ARCH_HARDWARE_H -#define __ASM_ARCH_HARDWARE_H __FILE__ - -/* currently nothing here, placeholder */ - -#endif /* __ASM_ARCH_IRQ_H */ diff --git a/arch/arm/mach-s3c64xx/watchdog-reset.h b/arch/arm/mach-s3c64xx/watchdog-reset.h deleted file mode 100644 index 1042d6c463dc..000000000000 --- a/arch/arm/mach-s3c64xx/watchdog-reset.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * S3C2410 - System define for arch_reset() function - */ - -#ifndef __PLAT_SAMSUNG_WATCHDOG_RESET_H -#define __PLAT_SAMSUNG_WATCHDOG_RESET_H - -extern void samsung_wdt_reset(void); -extern void samsung_wdt_reset_of_init(void); -extern void samsung_wdt_reset_init(void __iomem *base); - -#endif /* __PLAT_SAMSUNG_WATCHDOG_RESET_H */ diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 03984a791879..95d4e8284866 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -14,10 +14,10 @@ config ARCH_S5PV210 select COMMON_CLK_SAMSUNG select GPIOLIB select HAVE_S3C2410_I2C if I2C - select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS select PINCTRL select PINCTRL_EXYNOS + select SOC_SAMSUNG help Samsung S5PV210/S5PC110 series based systems diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index e7b551e18e5c..aa0a1f091daf 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -3,12 +3,5 @@ # Copyright (c) 2010 Samsung Electronics Co., Ltd. # http://www.samsung.com/ -ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/arch/arm/plat-samsung/include - -# Core - obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o - -# machine support - obj-y += s5pv210.o diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c index b336df0c57f3..d59c094cdea8 100644 --- a/arch/arm/mach-s5pv210/pm.c +++ b/arch/arm/mach-s5pv210/pm.c @@ -13,15 +13,56 @@ #include <linux/suspend.h> #include <linux/syscore_ops.h> #include <linux/io.h> +#include <linux/soc/samsung/s3c-pm.h> #include <asm/cacheflush.h> #include <asm/suspend.h> -#include <plat/pm-common.h> - #include "common.h" #include "regs-clock.h" +/* helper functions to save and restore register state */ +struct sleep_save { + void __iomem *reg; + unsigned long val; +}; + +#define SAVE_ITEM(x) \ + { .reg = (x) } + +/** + * s3c_pm_do_save() - save a set of registers for restoration on resume. + * @ptr: Pointer to an array of registers. + * @count: Size of the ptr array. + * + * Run through the list of registers given, saving their contents in the + * array for later restoration when we wakeup. + */ +static void s3c_pm_do_save(struct sleep_save *ptr, int count) +{ + for (; count > 0; count--, ptr++) { + ptr->val = readl_relaxed(ptr->reg); + S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val); + } +} + +/** + * s3c_pm_do_restore() - restore register values from the save list. + * @ptr: Pointer to an array of registers. + * @count: Size of the ptr array. + * + * Restore the register values saved from s3c_pm_do_save(). + * + * WARNING: Do not put any debug in here that may effect memory or use + * peripherals, as things may be changing! +*/ + +static void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count) +{ + for (; count > 0; count--, ptr++) + writel_relaxed(ptr->val, ptr->reg); +} + static struct sleep_save s5pv210_core_save[] = { /* Clock ETC */ SAVE_ITEM(S5P_MDNIE_SEL), @@ -99,8 +140,6 @@ static int s5pv210_suspend_enter(suspend_state_t state) u32 eint_wakeup_mask = s5pv210_read_eint_wakeup_mask(); int ret; - s3c_pm_debug_init(); - S3C_PMDBG("%s: suspending the system...\n", __func__); S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__, @@ -113,7 +152,7 @@ static int s5pv210_suspend_enter(suspend_state_t state) return -EINVAL; } - s3c_pm_save_uarts(); + s3c_pm_save_uarts(false); s5pv210_pm_prepare(); flush_cache_all(); s3c_pm_check_store(); @@ -122,7 +161,7 @@ static int s5pv210_suspend_enter(suspend_state_t state) if (ret) return ret; - s3c_pm_restore_uarts(); + s3c_pm_restore_uarts(false); S3C_PMDBG("%s: wakeup stat: %08x\n", __func__, __raw_readl(S5P_WAKEUP_STAT)); diff --git a/arch/arm/mach-s5pv210/regs-clock.h b/arch/arm/mach-s5pv210/regs-clock.h index 2a35c831a9b0..9cad2306e470 100644 --- a/arch/arm/mach-s5pv210/regs-clock.h +++ b/arch/arm/mach-s5pv210/regs-clock.h @@ -9,7 +9,9 @@ #ifndef __ASM_ARCH_REGS_CLOCK_H #define __ASM_ARCH_REGS_CLOCK_H __FILE__ -#include <plat/map-base.h> +#define S3C_ADDR_BASE 0xF6000000 +#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x)) +#define S3C_VA_SYS S3C_ADDR(0x00100000) #define S5P_CLKREG(x) (S3C_VA_SYS + (x)) diff --git a/arch/arm/mach-s5pv210/s5pv210.c b/arch/arm/mach-s5pv210/s5pv210.c index 868f9c20419d..a21ed3bb992a 100644 --- a/arch/arm/mach-s5pv210/s5pv210.c +++ b/arch/arm/mach-s5pv210/s5pv210.c @@ -13,8 +13,6 @@ #include <asm/mach/map.h> #include <asm/system_misc.h> -#include <plat/map-base.h> - #include "common.h" #include "regs-clock.h" diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 3cc2b71e16f0..bd3a52fd09ce 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c @@ -30,6 +30,7 @@ #include <linux/gpio_keys.h> #include <linux/input.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <linux/power/gpio-charger.h> #include <video/sa1100fb.h> @@ -131,16 +132,23 @@ static struct irda_platform_data collie_ir_data = { /* * Collie AC IN */ +static struct gpiod_lookup_table collie_power_gpiod_table = { + .dev_id = "gpio-charger", + .table = { + GPIO_LOOKUP("gpio", COLLIE_GPIO_AC_IN, + NULL, GPIO_ACTIVE_HIGH), + { }, + }, +}; + static char *collie_ac_supplied_to[] = { "main-battery", "backup-battery", }; - static struct gpio_charger_platform_data collie_power_data = { .name = "charger", .type = POWER_SUPPLY_TYPE_MAINS, - .gpio = COLLIE_GPIO_AC_IN, .supplied_to = collie_ac_supplied_to, .num_supplicants = ARRAY_SIZE(collie_ac_supplied_to), }; @@ -386,6 +394,8 @@ static void __init collie_init(void) platform_scoop_config = &collie_pcmcia_config; + gpiod_add_lookup_table(&collie_power_gpiod_table); + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if (ret) { printk(KERN_WARNING "collie: Unable to register LoCoMo device\n"); diff --git a/arch/arm/mach-shmobile/rcar-gen2.h b/arch/arm/mach-shmobile/rcar-gen2.h index 4777fff2de41..af9dbd6aa49e 100644 --- a/arch/arm/mach-shmobile/rcar-gen2.h +++ b/arch/arm/mach-shmobile/rcar-gen2.h @@ -2,8 +2,6 @@ #ifndef __ASM_RCAR_GEN2_H__ #define __ASM_RCAR_GEN2_H__ -void rcar_gen2_timer_init(void); -void rcar_gen2_reserve(void); void rcar_gen2_pm_init(void); #endif /* __ASM_RCAR_GEN2_H__ */ diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index c42ff8c314c8..d42d93443f2f 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -9,7 +9,7 @@ #include <linux/clocksource.h> #include <linux/device.h> -#include <linux/dma-contiguous.h> +#include <linux/dma-map-ops.h> #include <linux/io.h> #include <linux/kernel.h> #include <linux/memblock.h> @@ -59,7 +59,7 @@ static unsigned int __init get_extal_freq(void) #define CNTCR 0 #define CNTFID0 0x20 -void __init rcar_gen2_timer_init(void) +static void __init rcar_gen2_timer_init(void) { bool need_update = true; void __iomem *base; @@ -174,7 +174,7 @@ static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname, return 0; } -void __init rcar_gen2_reserve(void) +static void __init rcar_gen2_reserve(void) { struct memory_reserve_config mrc; diff --git a/arch/arm/mach-stm32/Makefile.boot b/arch/arm/mach-stm32/Makefile.boot index cec195d4fcba..5dde7328a7a9 100644 --- a/arch/arm/mach-stm32/Makefile.boot +++ b/arch/arm/mach-stm32/Makefile.boot @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only # Empty file waiting for deletion once Makefile.boot isn't needed any more. # Patch waits for application at -# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 . +# https://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 . diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 12c26eb88afb..43d91bfd2360 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -1249,20 +1249,28 @@ static void __init l2c310_of_parse(const struct device_node *np, ret = of_property_read_u32(np, "prefetch-data", &val); if (ret == 0) { - if (val) + if (val) { prefetch |= L310_PREFETCH_CTRL_DATA_PREFETCH; - else + *aux_val |= L310_PREFETCH_CTRL_DATA_PREFETCH; + } else { prefetch &= ~L310_PREFETCH_CTRL_DATA_PREFETCH; + *aux_val &= ~L310_PREFETCH_CTRL_DATA_PREFETCH; + } + *aux_mask &= ~L310_PREFETCH_CTRL_DATA_PREFETCH; } else if (ret != -EINVAL) { pr_err("L2C-310 OF prefetch-data property value is missing\n"); } ret = of_property_read_u32(np, "prefetch-instr", &val); if (ret == 0) { - if (val) + if (val) { prefetch |= L310_PREFETCH_CTRL_INSTR_PREFETCH; - else + *aux_val |= L310_PREFETCH_CTRL_INSTR_PREFETCH; + } else { prefetch &= ~L310_PREFETCH_CTRL_INSTR_PREFETCH; + *aux_val &= ~L310_PREFETCH_CTRL_INSTR_PREFETCH; + } + *aux_mask &= ~L310_PREFETCH_CTRL_INSTR_PREFETCH; } else if (ret != -EINVAL) { pr_err("L2C-310 OF prefetch-instr property value is missing\n"); } diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c index 287ef898a55e..6bfd2b884505 100644 --- a/arch/arm/mm/dma-mapping-nommu.c +++ b/arch/arm/mm/dma-mapping-nommu.c @@ -8,6 +8,7 @@ #include <linux/export.h> #include <linux/mm.h> #include <linux/dma-direct.h> +#include <linux/dma-map-ops.h> #include <linux/scatterlist.h> #include <asm/cachetype.h> @@ -176,6 +177,8 @@ static void arm_nommu_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist const struct dma_map_ops arm_nommu_dma_ops = { .alloc = arm_nommu_dma_alloc, .free = arm_nommu_dma_free, + .alloc_pages = dma_direct_alloc_pages, + .free_pages = dma_direct_free_pages, .mmap = arm_nommu_dma_mmap, .map_page = arm_nommu_dma_map_page, .unmap_page = arm_nommu_dma_unmap_page, diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 8a8949174b1c..c4b8df2ad328 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -15,9 +15,7 @@ #include <linux/init.h> #include <linux/device.h> #include <linux/dma-direct.h> -#include <linux/dma-mapping.h> -#include <linux/dma-noncoherent.h> -#include <linux/dma-contiguous.h> +#include <linux/dma-map-ops.h> #include <linux/highmem.h> #include <linux/memblock.h> #include <linux/slab.h> @@ -35,7 +33,6 @@ #include <asm/dma-iommu.h> #include <asm/mach/map.h> #include <asm/system_info.h> -#include <asm/dma-contiguous.h> #include <xen/swiotlb-xen.h> #include "dma.h" @@ -199,6 +196,8 @@ static int arm_dma_supported(struct device *dev, u64 mask) const struct dma_map_ops arm_dma_ops = { .alloc = arm_dma_alloc, .free = arm_dma_free, + .alloc_pages = dma_direct_alloc_pages, + .free_pages = dma_direct_free_pages, .mmap = arm_dma_mmap, .get_sgtable = arm_dma_get_sgtable, .map_page = arm_dma_map_page, @@ -226,6 +225,8 @@ static int arm_coherent_dma_mmap(struct device *dev, struct vm_area_struct *vma, const struct dma_map_ops arm_coherent_dma_ops = { .alloc = arm_coherent_dma_alloc, .free = arm_coherent_dma_free, + .alloc_pages = dma_direct_alloc_pages, + .free_pages = dma_direct_free_pages, .mmap = arm_coherent_dma_mmap, .get_sgtable = arm_dma_get_sgtable, .map_page = arm_coherent_dma_map_page, diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 000c1b48e973..d57112a276f5 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -18,7 +18,7 @@ #include <linux/highmem.h> #include <linux/gfp.h> #include <linux/memblock.h> -#include <linux/dma-contiguous.h> +#include <linux/dma-map-ops.h> #include <linux/sizes.h> #include <linux/stop_machine.h> #include <linux/swiotlb.h> @@ -299,16 +299,14 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn) */ static void __init free_unused_memmap(void) { - unsigned long start, prev_end = 0; - struct memblock_region *reg; + unsigned long start, end, prev_end = 0; + int i; /* * This relies on each bank being in address order. * The banks are sorted previously in bootmem_init(). */ - for_each_memblock(memory, reg) { - start = memblock_region_memory_base_pfn(reg); - + for_each_mem_pfn_range(i, MAX_NUMNODES, &start, &end, NULL) { #ifdef CONFIG_SPARSEMEM /* * Take care not to free memmap entries that don't exist @@ -336,8 +334,7 @@ static void __init free_unused_memmap(void) * memmap entries are valid from the bank end aligned to * MAX_ORDER_NR_PAGES. */ - prev_end = ALIGN(memblock_region_memory_end_pfn(reg), - MAX_ORDER_NR_PAGES); + prev_end = ALIGN(end, MAX_ORDER_NR_PAGES); } #ifdef CONFIG_SPARSEMEM @@ -347,61 +344,29 @@ static void __init free_unused_memmap(void) #endif } -#ifdef CONFIG_HIGHMEM -static inline void free_area_high(unsigned long pfn, unsigned long end) -{ - for (; pfn < end; pfn++) - free_highmem_page(pfn_to_page(pfn)); -} -#endif - static void __init free_highpages(void) { #ifdef CONFIG_HIGHMEM unsigned long max_low = max_low_pfn; - struct memblock_region *mem, *res; + phys_addr_t range_start, range_end; + u64 i; /* set highmem page free */ - for_each_memblock(memory, mem) { - unsigned long start = memblock_region_memory_base_pfn(mem); - unsigned long end = memblock_region_memory_end_pfn(mem); + for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, + &range_start, &range_end, NULL) { + unsigned long start = PHYS_PFN(range_start); + unsigned long end = PHYS_PFN(range_end); /* Ignore complete lowmem entries */ if (end <= max_low) continue; - if (memblock_is_nomap(mem)) - continue; - /* Truncate partial highmem entries */ if (start < max_low) start = max_low; - /* Find and exclude any reserved regions */ - for_each_memblock(reserved, res) { - unsigned long res_start, res_end; - - res_start = memblock_region_reserved_base_pfn(res); - res_end = memblock_region_reserved_end_pfn(res); - - if (res_end < start) - continue; - if (res_start < start) - res_start = start; - if (res_start > end) - res_start = end; - if (res_end > end) - res_end = end; - if (res_start != start) - free_area_high(start, res_start); - start = res_end; - if (start == end) - break; - } - - /* And now free anything which remains */ - if (start < end) - free_area_high(start, end); + for (; start < end; start++) + free_highmem_page(pfn_to_page(start)); } #endif } diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index c36f977b2ccb..ab69250a86bc 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -17,7 +17,6 @@ #include <asm/cp15.h> #include <asm/cputype.h> -#include <asm/sections.h> #include <asm/cachetype.h> #include <asm/fixmap.h> #include <asm/sections.h> @@ -1154,9 +1153,8 @@ phys_addr_t arm_lowmem_limit __initdata = 0; void __init adjust_lowmem_bounds(void) { - phys_addr_t memblock_limit = 0; - u64 vmalloc_limit; - struct memblock_region *reg; + phys_addr_t block_start, block_end, memblock_limit = 0; + u64 vmalloc_limit, i; phys_addr_t lowmem_limit = 0; /* @@ -1172,26 +1170,18 @@ void __init adjust_lowmem_bounds(void) * The first usable region must be PMD aligned. Mark its start * as MEMBLOCK_NOMAP if it isn't */ - for_each_memblock(memory, reg) { - if (!memblock_is_nomap(reg)) { - if (!IS_ALIGNED(reg->base, PMD_SIZE)) { - phys_addr_t len; + for_each_mem_range(i, &block_start, &block_end) { + if (!IS_ALIGNED(block_start, PMD_SIZE)) { + phys_addr_t len; - len = round_up(reg->base, PMD_SIZE) - reg->base; - memblock_mark_nomap(reg->base, len); - } - break; + len = round_up(block_start, PMD_SIZE) - block_start; + memblock_mark_nomap(block_start, len); } + break; } - for_each_memblock(memory, reg) { - phys_addr_t block_start = reg->base; - phys_addr_t block_end = reg->base + reg->size; - - if (memblock_is_nomap(reg)) - continue; - - if (reg->base < vmalloc_limit) { + for_each_mem_range(i, &block_start, &block_end) { + if (block_start < vmalloc_limit) { if (block_end > lowmem_limit) /* * Compare as u64 to ensure vmalloc_limit does @@ -1440,19 +1430,15 @@ static void __init kmap_init(void) static void __init map_lowmem(void) { - struct memblock_region *reg; phys_addr_t kernel_x_start = round_down(__pa(KERNEL_START), SECTION_SIZE); phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE); + phys_addr_t start, end; + u64 i; /* Map all the lowmem memory banks. */ - for_each_memblock(memory, reg) { - phys_addr_t start = reg->base; - phys_addr_t end = start + reg->size; + for_each_mem_range(i, &start, &end) { struct map_desc map; - if (memblock_is_nomap(reg)) - continue; - if (end > arm_lowmem_limit) end = arm_lowmem_limit; if (start >= end) diff --git a/arch/arm/mm/pmsa-v7.c b/arch/arm/mm/pmsa-v7.c index 699fa2e88725..88950e41a3a9 100644 --- a/arch/arm/mm/pmsa-v7.c +++ b/arch/arm/mm/pmsa-v7.c @@ -231,12 +231,12 @@ static int __init allocate_region(phys_addr_t base, phys_addr_t size, void __init pmsav7_adjust_lowmem_bounds(void) { phys_addr_t specified_mem_size = 0, total_mem_size = 0; - struct memblock_region *reg; - bool first = true; phys_addr_t mem_start; phys_addr_t mem_end; + phys_addr_t reg_start, reg_end; unsigned int mem_max_regions; - int num, i; + int num; + u64 i; /* Free-up PMSAv7_PROBE_REGION */ mpu_min_region_order = __mpu_min_region_order(); @@ -262,20 +262,19 @@ void __init pmsav7_adjust_lowmem_bounds(void) mem_max_regions -= num; #endif - for_each_memblock(memory, reg) { - if (first) { + for_each_mem_range(i, ®_start, ®_end) { + if (i == 0) { phys_addr_t phys_offset = PHYS_OFFSET; /* * Initially only use memory continuous from * PHYS_OFFSET */ - if (reg->base != phys_offset) + if (reg_start != phys_offset) panic("First memory bank must be contiguous from PHYS_OFFSET"); - mem_start = reg->base; - mem_end = reg->base + reg->size; - specified_mem_size = reg->size; - first = false; + mem_start = reg_start; + mem_end = reg_end; + specified_mem_size = mem_end - mem_start; } else { /* * memblock auto merges contiguous blocks, remove @@ -283,8 +282,8 @@ void __init pmsav7_adjust_lowmem_bounds(void) * blocks separately while iterating) */ pr_notice("Ignoring RAM after %pa, memory at %pa ignored\n", - &mem_end, ®->base); - memblock_remove(reg->base, 0 - reg->base); + &mem_end, ®_start); + memblock_remove(reg_start, 0 - reg_start); break; } } diff --git a/arch/arm/mm/pmsa-v8.c b/arch/arm/mm/pmsa-v8.c index 0d7d5fb59247..2de019f7503e 100644 --- a/arch/arm/mm/pmsa-v8.c +++ b/arch/arm/mm/pmsa-v8.c @@ -94,20 +94,19 @@ static __init bool is_region_fixed(int number) void __init pmsav8_adjust_lowmem_bounds(void) { phys_addr_t mem_end; - struct memblock_region *reg; - bool first = true; + phys_addr_t reg_start, reg_end; + u64 i; - for_each_memblock(memory, reg) { - if (first) { + for_each_mem_range(i, ®_start, ®_end) { + if (i == 0) { phys_addr_t phys_offset = PHYS_OFFSET; /* * Initially only use memory continuous from * PHYS_OFFSET */ - if (reg->base != phys_offset) + if (reg_start != phys_offset) panic("First memory bank must be contiguous from PHYS_OFFSET"); - mem_end = reg->base + reg->size; - first = false; + mem_end = reg_end; } else { /* * memblock auto merges contiguous blocks, remove @@ -115,8 +114,8 @@ void __init pmsav8_adjust_lowmem_bounds(void) * blocks separately while iterating) */ pr_notice("Ignoring RAM after %pa, memory at %pa ignored\n", - &mem_end, ®->base); - memblock_remove(reg->base, 0 - reg->base); + &mem_end, ®_start); + memblock_remove(reg_start, 0 - reg_start); break; } } diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 93fd7fc537cf..272670ef1e92 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -23,7 +23,7 @@ config OMAP_DEBUG_LEDS config POWER_AVS_OMAP bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2" - depends on POWER_AVS && (ARCH_OMAP3 || ARCH_OMAP4) && PM + depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM select POWER_SUPPLY help Say Y to enable AVS(Adaptive Voltage Scaling) diff --git a/arch/arm/plat-samsung/include/plat/adc.h b/arch/arm/plat-samsung/include/plat/adc.h deleted file mode 100644 index 74d1a46408c1..000000000000 --- a/arch/arm/plat-samsung/include/plat/adc.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * S3C ADC driver information - */ - -#ifndef __ASM_PLAT_ADC_H -#define __ASM_PLAT_ADC_H __FILE__ - -struct s3c_adc_client; -struct platform_device; - -extern int s3c_adc_start(struct s3c_adc_client *client, - unsigned int channel, unsigned int nr_samples); - -extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch); - -extern struct s3c_adc_client * - s3c_adc_register(struct platform_device *pdev, - void (*select)(struct s3c_adc_client *client, - unsigned selected), - void (*conv)(struct s3c_adc_client *client, - unsigned d0, unsigned d1, - unsigned *samples_left), - unsigned int is_ts); - -extern void s3c_adc_release(struct s3c_adc_client *client); - -#endif /* __ASM_PLAT_ADC_H */ diff --git a/arch/arm/plat-samsung/include/plat/cpu-freq-core.h b/arch/arm/plat-samsung/include/plat/cpu-freq-core.h deleted file mode 100644 index 2c7cf2665634..000000000000 --- a/arch/arm/plat-samsung/include/plat/cpu-freq-core.h +++ /dev/null @@ -1,287 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2006-2009 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * S3C CPU frequency scaling support - core support - */ - -#include <plat/cpu-freq.h> - -struct seq_file; - -#define MAX_BANKS (8) -#define S3C2412_MAX_IO (8) - -/** - * struct s3c2410_iobank_timing - IO bank timings for S3C2410 style timings - * @bankcon: The cached version of settings in this structure. - * @tacp: - * @tacs: Time from address valid to nCS asserted. - * @tcos: Time from nCS asserted to nOE or nWE asserted. - * @tacc: Time that nOE or nWE is asserted. - * @tcoh: Time nCS is held after nOE or nWE are released. - * @tcah: Time address is held for after - * @nwait_en: Whether nWAIT is enabled for this bank. - * - * This structure represents the IO timings for a S3C2410 style IO bank - * used by the CPU frequency support if it needs to change the settings - * of the IO. - */ -struct s3c2410_iobank_timing { - unsigned long bankcon; - unsigned int tacp; - unsigned int tacs; - unsigned int tcos; - unsigned int tacc; - unsigned int tcoh; /* nCS hold after nOE/nWE */ - unsigned int tcah; /* Address hold after nCS */ - unsigned char nwait_en; /* nWait enabled for bank. */ -}; - -/** - * struct s3c2412_iobank_timing - io timings for PL092 (S3C2412) style IO - * @idcy: The idle cycle time between transactions. - * @wstrd: nCS release to end of read cycle. - * @wstwr: nCS release to end of write cycle. - * @wstoen: nCS assertion to nOE assertion time. - * @wstwen: nCS assertion to nWE assertion time. - * @wstbrd: Burst ready delay. - * @smbidcyr: Register cache for smbidcyr value. - * @smbwstrd: Register cache for smbwstrd value. - * @smbwstwr: Register cache for smbwstwr value. - * @smbwstoen: Register cache for smbwstoen value. - * @smbwstwen: Register cache for smbwstwen value. - * @smbwstbrd: Register cache for smbwstbrd value. - * - * Timing information for a IO bank on an S3C2412 or similar system which - * uses a PL093 block. - */ -struct s3c2412_iobank_timing { - unsigned int idcy; - unsigned int wstrd; - unsigned int wstwr; - unsigned int wstoen; - unsigned int wstwen; - unsigned int wstbrd; - - /* register cache */ - unsigned char smbidcyr; - unsigned char smbwstrd; - unsigned char smbwstwr; - unsigned char smbwstoen; - unsigned char smbwstwen; - unsigned char smbwstbrd; -}; - -union s3c_iobank { - struct s3c2410_iobank_timing *io_2410; - struct s3c2412_iobank_timing *io_2412; -}; - -/** - * struct s3c_iotimings - Chip IO timings holder - * @bank: The timings for each IO bank. - */ -struct s3c_iotimings { - union s3c_iobank bank[MAX_BANKS]; -}; - -/** - * struct s3c_plltab - PLL table information. - * @vals: List of PLL values. - * @size: Size of the PLL table @vals. - */ -struct s3c_plltab { - struct s3c_pllval *vals; - int size; -}; - -/** - * struct s3c_cpufreq_config - current cpu frequency configuration - * @freq: The current settings for the core clocks. - * @max: Maxium settings, derived from core, board and user settings. - * @pll: The PLL table entry for the current PLL settings. - * @divs: The divisor settings for the core clocks. - * @info: The current core driver information. - * @board: The information for the board we are running on. - * @lock_pll: Set if the PLL settings cannot be changed. - * - * This is for the core drivers that need to know information about - * the current settings and values. It should not be needed by any - * device drivers. -*/ -struct s3c_cpufreq_config { - struct s3c_freq freq; - struct s3c_freq max; - struct clk *mpll; - struct cpufreq_frequency_table pll; - struct s3c_clkdivs divs; - struct s3c_cpufreq_info *info; /* for core, not drivers */ - struct s3c_cpufreq_board *board; - - unsigned int lock_pll:1; -}; - -/** - * struct s3c_cpufreq_info - Information for the CPU frequency driver. - * @name: The name of this implementation. - * @max: The maximum frequencies for the system. - * @latency: Transition latency to give to cpufreq. - * @locktime_m: The lock-time in uS for the MPLL. - * @locktime_u: The lock-time in uS for the UPLL. - * @locttime_bits: The number of bits each LOCKTIME field. - * @need_pll: Set if this driver needs to change the PLL values to achieve - * any frequency changes. This is really only need by devices like the - * S3C2410 where there is no or limited divider between the PLL and the - * ARMCLK. - * @get_iotiming: Get the current IO timing data, mainly for use at start. - * @set_iotiming: Update the IO timings from the cached copies calculated - * from the @calc_iotiming entry when changing the frequency. - * @calc_iotiming: Calculate and update the cached copies of the IO timings - * from the newly calculated frequencies. - * @calc_freqtable: Calculate (fill in) the given frequency table from the - * current frequency configuration. If the table passed in is NULL, - * then the return is the number of elements to be filled for allocation - * of the table. - * @set_refresh: Set the memory refresh configuration. - * @set_fvco: Set the PLL frequencies. - * @set_divs: Update the clock divisors. - * @calc_divs: Calculate the clock divisors. - */ -struct s3c_cpufreq_info { - const char *name; - struct s3c_freq max; - - unsigned int latency; - - unsigned int locktime_m; - unsigned int locktime_u; - unsigned char locktime_bits; - - unsigned int need_pll:1; - - /* driver routines */ - - int (*get_iotiming)(struct s3c_cpufreq_config *cfg, - struct s3c_iotimings *timings); - - void (*set_iotiming)(struct s3c_cpufreq_config *cfg, - struct s3c_iotimings *timings); - - int (*calc_iotiming)(struct s3c_cpufreq_config *cfg, - struct s3c_iotimings *timings); - - int (*calc_freqtable)(struct s3c_cpufreq_config *cfg, - struct cpufreq_frequency_table *t, - size_t table_size); - - void (*debug_io_show)(struct seq_file *seq, - struct s3c_cpufreq_config *cfg, - union s3c_iobank *iob); - - void (*set_refresh)(struct s3c_cpufreq_config *cfg); - void (*set_fvco)(struct s3c_cpufreq_config *cfg); - void (*set_divs)(struct s3c_cpufreq_config *cfg); - int (*calc_divs)(struct s3c_cpufreq_config *cfg); -}; - -extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info); - -extern int s3c_plltab_register(struct cpufreq_frequency_table *plls, - unsigned int plls_no); - -/* exports and utilities for debugfs */ -extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void); -extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void); - -#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS -#define s3c_cpufreq_debugfs_call(x) x -#else -#define s3c_cpufreq_debugfs_call(x) NULL -#endif - -/* Useful utility functions. */ - -extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *); - -/* S3C2410 and compatible exported functions */ - -extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg); -extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg); - -#ifdef CONFIG_S3C2410_IOTIMING -extern void s3c2410_iotiming_debugfs(struct seq_file *seq, - struct s3c_cpufreq_config *cfg, - union s3c_iobank *iob); - -extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg, - struct s3c_iotimings *iot); - -extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg, - struct s3c_iotimings *timings); - -extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg, - struct s3c_iotimings *iot); -#else -#define s3c2410_iotiming_debugfs NULL -#define s3c2410_iotiming_calc NULL -#define s3c2410_iotiming_get NULL -#define s3c2410_iotiming_set NULL -#endif /* CONFIG_S3C2410_IOTIMING */ - -/* S3C2412 compatible routines */ - -#ifdef CONFIG_S3C2412_IOTIMING -extern void s3c2412_iotiming_debugfs(struct seq_file *seq, - struct s3c_cpufreq_config *cfg, - union s3c_iobank *iob); - -extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg, - struct s3c_iotimings *timings); - -extern int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg, - struct s3c_iotimings *iot); - -extern void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg, - struct s3c_iotimings *iot); -#else -#define s3c2412_iotiming_debugfs NULL -#define s3c2412_iotiming_calc NULL -#define s3c2412_iotiming_get NULL -#define s3c2412_iotiming_set NULL -#endif /* CONFIG_S3C2412_IOTIMING */ - -#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG -#define s3c_freq_dbg(x...) printk(KERN_INFO x) -#else -#define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0) -#endif /* CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG */ - -#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG -#define s3c_freq_iodbg(x...) printk(KERN_INFO x) -#else -#define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0) -#endif /* CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG */ - -static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table, - int index, size_t table_size, - unsigned int freq) -{ - if (index < 0) - return index; - - if (table) { - if (index >= table_size) - return -ENOMEM; - - s3c_freq_dbg("%s: { %d = %u kHz }\n", - __func__, index, freq); - - table[index].driver_data = index; - table[index].frequency = freq; - } - - return index + 1; -} diff --git a/arch/arm/plat-samsung/include/plat/cpu-freq.h b/arch/arm/plat-samsung/include/plat/cpu-freq.h deleted file mode 100644 index 558892bcf9b6..000000000000 --- a/arch/arm/plat-samsung/include/plat/cpu-freq.h +++ /dev/null @@ -1,141 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2006-2007 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * S3C CPU frequency scaling support - driver and board - */ - -#include <linux/cpufreq.h> - -struct s3c_cpufreq_info; -struct s3c_cpufreq_board; -struct s3c_iotimings; - -/** - * struct s3c_freq - frequency information (mainly for core drivers) - * @fclk: The FCLK frequency in Hz. - * @armclk: The ARMCLK frequency in Hz. - * @hclk_tns: HCLK cycle time in 10ths of nano-seconds. - * @hclk: The HCLK frequency in Hz. - * @pclk: The PCLK frequency in Hz. - * - * This contains the frequency information about the current configuration - * mainly for the core drivers to ensure we do not end up passing about - * a large number of parameters. - * - * The @hclk_tns field is a useful cache for the parts of the drivers that - * need to calculate IO timings and suchlike. - */ -struct s3c_freq { - unsigned long fclk; - unsigned long armclk; - unsigned long hclk_tns; /* in 10ths of ns */ - unsigned long hclk; - unsigned long pclk; -}; - -/** - * struct s3c_cpufreq_freqs - s3c cpufreq notification information. - * @freqs: The cpufreq setting information. - * @old: The old clock settings. - * @new: The new clock settings. - * @pll_changing: Set if the PLL is changing. - * - * Wrapper 'struct cpufreq_freqs' so that any drivers receiving the - * notification can use this information that is not provided by just - * having the core frequency alone. - * - * The pll_changing flag is used to indicate if the PLL itself is - * being set during this change. This is important as the clocks - * will temporarily be set to the XTAL clock during this time, so - * drivers may want to close down their output during this time. - * - * Note, this is not being used by any current drivers and therefore - * may be removed in the future. - */ -struct s3c_cpufreq_freqs { - struct cpufreq_freqs freqs; - struct s3c_freq old; - struct s3c_freq new; - - unsigned int pll_changing:1; -}; - -#define to_s3c_cpufreq(_cf) container_of(_cf, struct s3c_cpufreq_freqs, freqs) - -/** - * struct s3c_clkdivs - clock divisor information - * @p_divisor: Divisor from FCLK to PCLK. - * @h_divisor: Divisor from FCLK to HCLK. - * @arm_divisor: Divisor from FCLK to ARMCLK (not all CPUs). - * @dvs: Non-zero if using DVS mode for ARMCLK. - * - * Divisor settings for the core clocks. - */ -struct s3c_clkdivs { - int p_divisor; - int h_divisor; - int arm_divisor; - unsigned char dvs; -}; - -#define PLLVAL(_m, _p, _s) (((_m) << 12) | ((_p) << 4) | (_s)) - -/** - * struct s3c_pllval - PLL value entry. - * @freq: The frequency for this entry in Hz. - * @pll_reg: The PLL register setting for this PLL value. - */ -struct s3c_pllval { - unsigned long freq; - unsigned long pll_reg; -}; - -/** - * struct s3c_cpufreq_board - per-board cpu frequency informatin - * @refresh: The SDRAM refresh period in nanoseconds. - * @auto_io: Set if the IO timing settings should be generated from the - * initialisation time hardware registers. - * @need_io: Set if the board has external IO on any of the chipselect - * lines that will require the hardware timing registers to be - * updated on a clock change. - * @max: The maxium frequency limits for the system. Any field that - * is left at zero will use the CPU's settings. - * - * This contains the board specific settings that affect how the CPU - * drivers chose settings. These include the memory refresh and IO - * timing information. - * - * Registration depends on the driver being used, the ARMCLK only - * implementation does not currently need this but the older style - * driver requires this to be available. - */ -struct s3c_cpufreq_board { - unsigned int refresh; - unsigned int auto_io:1; /* automatically init io timings. */ - unsigned int need_io:1; /* set if needs io timing support. */ - - /* any non-zero field in here is taken as an upper limit. */ - struct s3c_freq max; /* frequency limits */ -}; - -/* Things depending on frequency scaling. */ -#ifdef CONFIG_ARM_S3C_CPUFREQ -#define __init_or_cpufreq -#else -#define __init_or_cpufreq __init -#endif - -/* Board functions */ - -#ifdef CONFIG_ARM_S3C_CPUFREQ -extern int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board); -#else - -static inline int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board) -{ - return 0; -} -#endif /* CONFIG_ARM_S3C_CPUFREQ */ diff --git a/arch/arm/plat-samsung/include/plat/fb-s3c2410.h b/arch/arm/plat-samsung/include/plat/fb-s3c2410.h deleted file mode 100644 index 614240d768b4..000000000000 --- a/arch/arm/plat-samsung/include/plat/fb-s3c2410.h +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org> - * - * Inspired by pxafb.h -*/ - -#ifndef __ASM_PLAT_FB_S3C2410_H -#define __ASM_PLAT_FB_S3C2410_H __FILE__ - -struct s3c2410fb_hw { - unsigned long lcdcon1; - unsigned long lcdcon2; - unsigned long lcdcon3; - unsigned long lcdcon4; - unsigned long lcdcon5; -}; - -/* LCD description */ -struct s3c2410fb_display { - /* LCD type */ - unsigned type; - - /* Screen size */ - unsigned short width; - unsigned short height; - - /* Screen info */ - unsigned short xres; - unsigned short yres; - unsigned short bpp; - - unsigned pixclock; /* pixclock in picoseconds */ - unsigned short left_margin; /* value in pixels (TFT) or HCLKs (STN) */ - unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */ - unsigned short hsync_len; /* value in pixels (TFT) or HCLKs (STN) */ - unsigned short upper_margin; /* value in lines (TFT) or 0 (STN) */ - unsigned short lower_margin; /* value in lines (TFT) or 0 (STN) */ - unsigned short vsync_len; /* value in lines (TFT) or 0 (STN) */ - - /* lcd configuration registers */ - unsigned long lcdcon5; -}; - -struct s3c2410fb_mach_info { - - struct s3c2410fb_display *displays; /* attached displays info */ - unsigned num_displays; /* number of defined displays */ - unsigned default_display; - - /* GPIOs */ - - unsigned long gpcup; - unsigned long gpcup_mask; - unsigned long gpccon; - unsigned long gpccon_mask; - unsigned long gpdup; - unsigned long gpdup_mask; - unsigned long gpdcon; - unsigned long gpdcon_mask; - - /* lpc3600 control register */ - unsigned long lpcsel; -}; - -extern void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *); - -#endif /* __ASM_PLAT_FB_S3C2410_H */ diff --git a/arch/arm/plat-samsung/include/plat/pm-common.h b/arch/arm/plat-samsung/include/plat/pm-common.h deleted file mode 100644 index 1268bae04234..000000000000 --- a/arch/arm/plat-samsung/include/plat/pm-common.h +++ /dev/null @@ -1,107 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2013 Samsung Electronics Co., Ltd. - * Tomasz Figa <t.figa@samsung.com> - * Copyright (c) 2004 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Written by Ben Dooks, <ben@simtec.co.uk> - */ - -#ifndef __PLAT_SAMSUNG_PM_COMMON_H -#define __PLAT_SAMSUNG_PM_COMMON_H __FILE__ - -#include <linux/irq.h> - -/* sleep save info */ - -/** - * struct sleep_save - save information for shared peripherals. - * @reg: Pointer to the register to save. - * @val: Holder for the value saved from reg. - * - * This describes a list of registers which is used by the pm core and - * other subsystem to save and restore register values over suspend. - */ -struct sleep_save { - void __iomem *reg; - unsigned long val; -}; - -#define SAVE_ITEM(x) \ - { .reg = (x) } - -/* helper functions to save/restore lists of registers. */ - -extern void s3c_pm_do_save(struct sleep_save *ptr, int count); -extern void s3c_pm_do_restore(const struct sleep_save *ptr, int count); -extern void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count); - -/* PM debug functions */ - -/** - * struct pm_uart_save - save block for core UART - * @ulcon: Save value for S3C2410_ULCON - * @ucon: Save value for S3C2410_UCON - * @ufcon: Save value for S3C2410_UFCON - * @umcon: Save value for S3C2410_UMCON - * @ubrdiv: Save value for S3C2410_UBRDIV - * - * Save block for UART registers to be held over sleep and restored if they - * are needed (say by debug). -*/ -struct pm_uart_save { - u32 ulcon; - u32 ucon; - u32 ufcon; - u32 umcon; - u32 ubrdiv; - u32 udivslot; -}; - -#ifdef CONFIG_SAMSUNG_PM_DEBUG -/** - * s3c_pm_dbg() - low level debug function for use in suspend/resume. - * @msg: The message to print. - * - * This function is used mainly to debug the resume process before the system - * can rely on printk/console output. It uses the low-level debugging output - * routine printascii() to do its work. - */ -extern void s3c_pm_dbg(const char *msg, ...); - -/** - * s3c_pm_debug_init() - suspend/resume low level debug initialization. - * @base: Virtual base of UART to use for suspend/resume debugging. - * - * This function needs to be called before S3C_PMDBG() can be used, to set up - * UART port base address and configuration. - */ -extern void s3c_pm_debug_init(void); - -#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt) - -extern void s3c_pm_save_uarts(void); -extern void s3c_pm_restore_uarts(void); -#else -#define S3C_PMDBG(fmt...) pr_debug(fmt) -#define s3c_pm_debug_init() do { } while (0) - -static inline void s3c_pm_save_uarts(void) { } -static inline void s3c_pm_restore_uarts(void) { } -#endif - -/* suspend memory checking */ - -#ifdef CONFIG_SAMSUNG_PM_CHECK -extern void s3c_pm_check_prepare(void); -extern void s3c_pm_check_restore(void); -extern void s3c_pm_check_cleanup(void); -extern void s3c_pm_check_store(void); -#else -#define s3c_pm_check_prepare() do { } while (0) -#define s3c_pm_check_restore() do { } while (0) -#define s3c_pm_check_cleanup() do { } while (0) -#define s3c_pm_check_store() do { } while (0) -#endif - -#endif diff --git a/arch/arm/plat-samsung/include/plat/regs-spi.h b/arch/arm/plat-samsung/include/plat/regs-spi.h deleted file mode 100644 index 607844311566..000000000000 --- a/arch/arm/plat-samsung/include/plat/regs-spi.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2004 Fetron GmbH - * - * S3C2410 SPI register definition - */ - -#ifndef __ASM_ARCH_REGS_SPI_H -#define __ASM_ARCH_REGS_SPI_H - -#define S3C2410_SPI1 (0x20) -#define S3C2412_SPI1 (0x100) - -#define S3C2410_SPCON (0x00) - -#define S3C2410_SPCON_SMOD_DMA (2 << 5) /* DMA mode */ -#define S3C2410_SPCON_SMOD_INT (1 << 5) /* interrupt mode */ -#define S3C2410_SPCON_SMOD_POLL (0 << 5) /* polling mode */ -#define S3C2410_SPCON_ENSCK (1 << 4) /* Enable SCK */ -#define S3C2410_SPCON_MSTR (1 << 3) /* Master:1, Slave:0 select */ -#define S3C2410_SPCON_CPOL_HIGH (1 << 2) /* Clock polarity select */ -#define S3C2410_SPCON_CPOL_LOW (0 << 2) /* Clock polarity select */ - -#define S3C2410_SPCON_CPHA_FMTB (1 << 1) /* Clock Phase Select */ -#define S3C2410_SPCON_CPHA_FMTA (0 << 1) /* Clock Phase Select */ - -#define S3C2410_SPSTA (0x04) - -#define S3C2410_SPSTA_DCOL (1 << 2) /* Data Collision Error */ -#define S3C2410_SPSTA_MULD (1 << 1) /* Multi Master Error */ -#define S3C2410_SPSTA_READY (1 << 0) /* Data Tx/Rx ready */ -#define S3C2412_SPSTA_READY_ORG (1 << 3) - -#define S3C2410_SPPIN (0x08) - -#define S3C2410_SPPIN_ENMUL (1 << 2) /* Multi Master Error detect */ -#define S3C2410_SPPIN_RESERVED (1 << 1) -#define S3C2410_SPPIN_KEEP (1 << 0) /* Master Out keep */ - -#define S3C2410_SPPRE (0x0C) -#define S3C2410_SPTDAT (0x10) -#define S3C2410_SPRDAT (0x14) - -#endif /* __ASM_ARCH_REGS_SPI_H */ diff --git a/arch/arm/plat-samsung/include/plat/regs-udc.h b/arch/arm/plat-samsung/include/plat/regs-udc.h deleted file mode 100644 index d8d2eeaca088..000000000000 --- a/arch/arm/plat-samsung/include/plat/regs-udc.h +++ /dev/null @@ -1,146 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (C) 2004 Herbert Poetzl <herbert@13thfloor.at> - */ - -#ifndef __ASM_ARCH_REGS_UDC_H -#define __ASM_ARCH_REGS_UDC_H - -#define S3C2410_USBDREG(x) (x) - -#define S3C2410_UDC_FUNC_ADDR_REG S3C2410_USBDREG(0x0140) -#define S3C2410_UDC_PWR_REG S3C2410_USBDREG(0x0144) -#define S3C2410_UDC_EP_INT_REG S3C2410_USBDREG(0x0148) - -#define S3C2410_UDC_USB_INT_REG S3C2410_USBDREG(0x0158) -#define S3C2410_UDC_EP_INT_EN_REG S3C2410_USBDREG(0x015c) - -#define S3C2410_UDC_USB_INT_EN_REG S3C2410_USBDREG(0x016c) - -#define S3C2410_UDC_FRAME_NUM1_REG S3C2410_USBDREG(0x0170) -#define S3C2410_UDC_FRAME_NUM2_REG S3C2410_USBDREG(0x0174) - -#define S3C2410_UDC_EP0_FIFO_REG S3C2410_USBDREG(0x01c0) -#define S3C2410_UDC_EP1_FIFO_REG S3C2410_USBDREG(0x01c4) -#define S3C2410_UDC_EP2_FIFO_REG S3C2410_USBDREG(0x01c8) -#define S3C2410_UDC_EP3_FIFO_REG S3C2410_USBDREG(0x01cc) -#define S3C2410_UDC_EP4_FIFO_REG S3C2410_USBDREG(0x01d0) - -#define S3C2410_UDC_EP1_DMA_CON S3C2410_USBDREG(0x0200) -#define S3C2410_UDC_EP1_DMA_UNIT S3C2410_USBDREG(0x0204) -#define S3C2410_UDC_EP1_DMA_FIFO S3C2410_USBDREG(0x0208) -#define S3C2410_UDC_EP1_DMA_TTC_L S3C2410_USBDREG(0x020c) -#define S3C2410_UDC_EP1_DMA_TTC_M S3C2410_USBDREG(0x0210) -#define S3C2410_UDC_EP1_DMA_TTC_H S3C2410_USBDREG(0x0214) - -#define S3C2410_UDC_EP2_DMA_CON S3C2410_USBDREG(0x0218) -#define S3C2410_UDC_EP2_DMA_UNIT S3C2410_USBDREG(0x021c) -#define S3C2410_UDC_EP2_DMA_FIFO S3C2410_USBDREG(0x0220) -#define S3C2410_UDC_EP2_DMA_TTC_L S3C2410_USBDREG(0x0224) -#define S3C2410_UDC_EP2_DMA_TTC_M S3C2410_USBDREG(0x0228) -#define S3C2410_UDC_EP2_DMA_TTC_H S3C2410_USBDREG(0x022c) - -#define S3C2410_UDC_EP3_DMA_CON S3C2410_USBDREG(0x0240) -#define S3C2410_UDC_EP3_DMA_UNIT S3C2410_USBDREG(0x0244) -#define S3C2410_UDC_EP3_DMA_FIFO S3C2410_USBDREG(0x0248) -#define S3C2410_UDC_EP3_DMA_TTC_L S3C2410_USBDREG(0x024c) -#define S3C2410_UDC_EP3_DMA_TTC_M S3C2410_USBDREG(0x0250) -#define S3C2410_UDC_EP3_DMA_TTC_H S3C2410_USBDREG(0x0254) - -#define S3C2410_UDC_EP4_DMA_CON S3C2410_USBDREG(0x0258) -#define S3C2410_UDC_EP4_DMA_UNIT S3C2410_USBDREG(0x025c) -#define S3C2410_UDC_EP4_DMA_FIFO S3C2410_USBDREG(0x0260) -#define S3C2410_UDC_EP4_DMA_TTC_L S3C2410_USBDREG(0x0264) -#define S3C2410_UDC_EP4_DMA_TTC_M S3C2410_USBDREG(0x0268) -#define S3C2410_UDC_EP4_DMA_TTC_H S3C2410_USBDREG(0x026c) - -#define S3C2410_UDC_INDEX_REG S3C2410_USBDREG(0x0178) - -/* indexed registers */ - -#define S3C2410_UDC_MAXP_REG S3C2410_USBDREG(0x0180) - -#define S3C2410_UDC_EP0_CSR_REG S3C2410_USBDREG(0x0184) - -#define S3C2410_UDC_IN_CSR1_REG S3C2410_USBDREG(0x0184) -#define S3C2410_UDC_IN_CSR2_REG S3C2410_USBDREG(0x0188) - -#define S3C2410_UDC_OUT_CSR1_REG S3C2410_USBDREG(0x0190) -#define S3C2410_UDC_OUT_CSR2_REG S3C2410_USBDREG(0x0194) -#define S3C2410_UDC_OUT_FIFO_CNT1_REG S3C2410_USBDREG(0x0198) -#define S3C2410_UDC_OUT_FIFO_CNT2_REG S3C2410_USBDREG(0x019c) - -#define S3C2410_UDC_FUNCADDR_UPDATE (1 << 7) - -#define S3C2410_UDC_PWR_ISOUP (1 << 7) /* R/W */ -#define S3C2410_UDC_PWR_RESET (1 << 3) /* R */ -#define S3C2410_UDC_PWR_RESUME (1 << 2) /* R/W */ -#define S3C2410_UDC_PWR_SUSPEND (1 << 1) /* R */ -#define S3C2410_UDC_PWR_ENSUSPEND (1 << 0) /* R/W */ - -#define S3C2410_UDC_PWR_DEFAULT (0x00) - -#define S3C2410_UDC_INT_EP4 (1 << 4) /* R/W (clear only) */ -#define S3C2410_UDC_INT_EP3 (1 << 3) /* R/W (clear only) */ -#define S3C2410_UDC_INT_EP2 (1 << 2) /* R/W (clear only) */ -#define S3C2410_UDC_INT_EP1 (1 << 1) /* R/W (clear only) */ -#define S3C2410_UDC_INT_EP0 (1 << 0) /* R/W (clear only) */ - -#define S3C2410_UDC_USBINT_RESET (1 << 2) /* R/W (clear only) */ -#define S3C2410_UDC_USBINT_RESUME (1 << 1) /* R/W (clear only) */ -#define S3C2410_UDC_USBINT_SUSPEND (1 << 0) /* R/W (clear only) */ - -#define S3C2410_UDC_INTE_EP4 (1 << 4) /* R/W */ -#define S3C2410_UDC_INTE_EP3 (1 << 3) /* R/W */ -#define S3C2410_UDC_INTE_EP2 (1 << 2) /* R/W */ -#define S3C2410_UDC_INTE_EP1 (1 << 1) /* R/W */ -#define S3C2410_UDC_INTE_EP0 (1 << 0) /* R/W */ - -#define S3C2410_UDC_USBINTE_RESET (1 << 2) /* R/W */ -#define S3C2410_UDC_USBINTE_SUSPEND (1 << 0) /* R/W */ - -#define S3C2410_UDC_INDEX_EP0 (0x00) -#define S3C2410_UDC_INDEX_EP1 (0x01) -#define S3C2410_UDC_INDEX_EP2 (0x02) -#define S3C2410_UDC_INDEX_EP3 (0x03) -#define S3C2410_UDC_INDEX_EP4 (0x04) - -#define S3C2410_UDC_ICSR1_CLRDT (1 << 6) /* R/W */ -#define S3C2410_UDC_ICSR1_SENTSTL (1 << 5) /* R/W (clear only) */ -#define S3C2410_UDC_ICSR1_SENDSTL (1 << 4) /* R/W */ -#define S3C2410_UDC_ICSR1_FFLUSH (1 << 3) /* W (set only) */ -#define S3C2410_UDC_ICSR1_UNDRUN (1 << 2) /* R/W (clear only) */ -#define S3C2410_UDC_ICSR1_PKTRDY (1 << 0) /* R/W (set only) */ - -#define S3C2410_UDC_ICSR2_AUTOSET (1 << 7) /* R/W */ -#define S3C2410_UDC_ICSR2_ISO (1 << 6) /* R/W */ -#define S3C2410_UDC_ICSR2_MODEIN (1 << 5) /* R/W */ -#define S3C2410_UDC_ICSR2_DMAIEN (1 << 4) /* R/W */ - -#define S3C2410_UDC_OCSR1_CLRDT (1 << 7) /* R/W */ -#define S3C2410_UDC_OCSR1_SENTSTL (1 << 6) /* R/W (clear only) */ -#define S3C2410_UDC_OCSR1_SENDSTL (1 << 5) /* R/W */ -#define S3C2410_UDC_OCSR1_FFLUSH (1 << 4) /* R/W */ -#define S3C2410_UDC_OCSR1_DERROR (1 << 3) /* R */ -#define S3C2410_UDC_OCSR1_OVRRUN (1 << 2) /* R/W (clear only) */ -#define S3C2410_UDC_OCSR1_PKTRDY (1 << 0) /* R/W (clear only) */ - -#define S3C2410_UDC_OCSR2_AUTOCLR (1 << 7) /* R/W */ -#define S3C2410_UDC_OCSR2_ISO (1 << 6) /* R/W */ -#define S3C2410_UDC_OCSR2_DMAIEN (1 << 5) /* R/W */ - -#define S3C2410_UDC_EP0_CSR_OPKRDY (1 << 0) -#define S3C2410_UDC_EP0_CSR_IPKRDY (1 << 1) -#define S3C2410_UDC_EP0_CSR_SENTSTL (1 << 2) -#define S3C2410_UDC_EP0_CSR_DE (1 << 3) -#define S3C2410_UDC_EP0_CSR_SE (1 << 4) -#define S3C2410_UDC_EP0_CSR_SENDSTL (1 << 5) -#define S3C2410_UDC_EP0_CSR_SOPKTRDY (1 << 6) -#define S3C2410_UDC_EP0_CSR_SSE (1 << 7) - -#define S3C2410_UDC_MAXP_8 (1 << 0) -#define S3C2410_UDC_MAXP_16 (1 << 1) -#define S3C2410_UDC_MAXP_32 (1 << 2) -#define S3C2410_UDC_MAXP_64 (1 << 3) - -#endif diff --git a/arch/arm/plat-samsung/include/plat/samsung-time.h b/arch/arm/plat-samsung/include/plat/samsung-time.h deleted file mode 100644 index 32ab0860f631..000000000000 --- a/arch/arm/plat-samsung/include/plat/samsung-time.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Header file for samsung s3c and s5p time support - */ - -#ifndef __ASM_PLAT_SAMSUNG_TIME_H -#define __ASM_PLAT_SAMSUNG_TIME_H __FILE__ - -/* Samsung HR-Timer Clock mode */ -enum samsung_timer_mode { - SAMSUNG_PWM0, - SAMSUNG_PWM1, - SAMSUNG_PWM2, - SAMSUNG_PWM3, - SAMSUNG_PWM4, -}; - -extern void __init samsung_set_timer_source(enum samsung_timer_mode event, - enum samsung_timer_mode source); - -extern void __init samsung_timer_init(void); - -#endif /* __ASM_PLAT_SAMSUNG_TIME_H */ diff --git a/arch/arm/plat-samsung/pm-check.c b/arch/arm/plat-samsung/pm-check.c deleted file mode 100644 index cd2c02c68bc3..000000000000 --- a/arch/arm/plat-samsung/pm-check.c +++ /dev/null @@ -1,233 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// originally in linux/arch/arm/plat-s3c24xx/pm.c -// -// Copyright (c) 2004-2008 Simtec Electronics -// http://armlinux.simtec.co.uk -// Ben Dooks <ben@simtec.co.uk> -// -// S3C Power Mangament - suspend/resume memory corruption check. - -#include <linux/kernel.h> -#include <linux/suspend.h> -#include <linux/init.h> -#include <linux/crc32.h> -#include <linux/ioport.h> -#include <linux/slab.h> - -#include <plat/pm-common.h> - -#if CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE < 1 -#error CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE must be a positive non-zero value -#endif - -/* suspend checking code... - * - * this next area does a set of crc checks over all the installed - * memory, so the system can verify if the resume was ok. - * - * CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE defines the block-size for the CRC, - * increasing it will mean that the area corrupted will be less easy to spot, - * and reducing the size will cause the CRC save area to grow -*/ - -#define CHECK_CHUNKSIZE (CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE * 1024) - -static u32 crc_size; /* size needed for the crc block */ -static u32 *crcs; /* allocated over suspend/resume */ - -typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg); - -/* s3c_pm_run_res - * - * go through the given resource list, and look for system ram -*/ - -static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg) -{ - while (ptr != NULL) { - if (ptr->child != NULL) - s3c_pm_run_res(ptr->child, fn, arg); - - if ((ptr->flags & IORESOURCE_SYSTEM_RAM) - == IORESOURCE_SYSTEM_RAM) { - S3C_PMDBG("Found system RAM at %08lx..%08lx\n", - (unsigned long)ptr->start, - (unsigned long)ptr->end); - arg = (fn)(ptr, arg); - } - - ptr = ptr->sibling; - } -} - -static void s3c_pm_run_sysram(run_fn_t fn, u32 *arg) -{ - s3c_pm_run_res(&iomem_resource, fn, arg); -} - -static u32 *s3c_pm_countram(struct resource *res, u32 *val) -{ - u32 size = (u32)resource_size(res); - - size += CHECK_CHUNKSIZE-1; - size /= CHECK_CHUNKSIZE; - - S3C_PMDBG("Area %08lx..%08lx, %d blocks\n", - (unsigned long)res->start, (unsigned long)res->end, size); - - *val += size * sizeof(u32); - return val; -} - -/* s3c_pm_prepare_check - * - * prepare the necessary information for creating the CRCs. This - * must be done before the final save, as it will require memory - * allocating, and thus touching bits of the kernel we do not - * know about. -*/ - -void s3c_pm_check_prepare(void) -{ - crc_size = 0; - - s3c_pm_run_sysram(s3c_pm_countram, &crc_size); - - S3C_PMDBG("s3c_pm_prepare_check: %u checks needed\n", crc_size); - - crcs = kmalloc(crc_size+4, GFP_KERNEL); - if (crcs == NULL) - printk(KERN_ERR "Cannot allocated CRC save area\n"); -} - -static u32 *s3c_pm_makecheck(struct resource *res, u32 *val) -{ - unsigned long addr, left; - - for (addr = res->start; addr < res->end; - addr += CHECK_CHUNKSIZE) { - left = res->end - addr; - - if (left > CHECK_CHUNKSIZE) - left = CHECK_CHUNKSIZE; - - *val = crc32_le(~0, phys_to_virt(addr), left); - val++; - } - - return val; -} - -/* s3c_pm_check_store - * - * compute the CRC values for the memory blocks before the final - * sleep. -*/ - -void s3c_pm_check_store(void) -{ - if (crcs != NULL) - s3c_pm_run_sysram(s3c_pm_makecheck, crcs); -} - -/* in_region - * - * return TRUE if the area defined by ptr..ptr+size contains the - * what..what+whatsz -*/ - -static inline int in_region(void *ptr, int size, void *what, size_t whatsz) -{ - if ((what+whatsz) < ptr) - return 0; - - if (what > (ptr+size)) - return 0; - - return 1; -} - -/** - * s3c_pm_runcheck() - helper to check a resource on restore. - * @res: The resource to check - * @vak: Pointer to list of CRC32 values to check. - * - * Called from the s3c_pm_check_restore() via s3c_pm_run_sysram(), this - * function runs the given memory resource checking it against the stored - * CRC to ensure that memory is restored. The function tries to skip as - * many of the areas used during the suspend process. - */ -static u32 *s3c_pm_runcheck(struct resource *res, u32 *val) -{ - unsigned long addr; - unsigned long left; - void *stkpage; - void *ptr; - u32 calc; - - stkpage = (void *)((u32)&calc & ~PAGE_MASK); - - for (addr = res->start; addr < res->end; - addr += CHECK_CHUNKSIZE) { - left = res->end - addr; - - if (left > CHECK_CHUNKSIZE) - left = CHECK_CHUNKSIZE; - - ptr = phys_to_virt(addr); - - if (in_region(ptr, left, stkpage, 4096)) { - S3C_PMDBG("skipping %08lx, has stack in\n", addr); - goto skip_check; - } - - if (in_region(ptr, left, crcs, crc_size)) { - S3C_PMDBG("skipping %08lx, has crc block in\n", addr); - goto skip_check; - } - - /* calculate and check the checksum */ - - calc = crc32_le(~0, ptr, left); - if (calc != *val) { - printk(KERN_ERR "Restore CRC error at " - "%08lx (%08x vs %08x)\n", addr, calc, *val); - - S3C_PMDBG("Restore CRC error at %08lx (%08x vs %08x)\n", - addr, calc, *val); - } - - skip_check: - val++; - } - - return val; -} - -/** - * s3c_pm_check_restore() - memory check called on resume - * - * check the CRCs after the restore event and free the memory used - * to hold them -*/ -void s3c_pm_check_restore(void) -{ - if (crcs != NULL) - s3c_pm_run_sysram(s3c_pm_runcheck, crcs); -} - -/** - * s3c_pm_check_cleanup() - free memory resources - * - * Free the resources that where allocated by the suspend - * memory check code. We do this separately from the - * s3c_pm_check_restore() function as we cannot call any - * functions that might sleep during that resume. - */ -void s3c_pm_check_cleanup(void) -{ - kfree(crcs); - crcs = NULL; -} - diff --git a/arch/arm/plat-samsung/pm-debug.c b/arch/arm/plat-samsung/pm-debug.c deleted file mode 100644 index b76b1e9ba4ae..000000000000 --- a/arch/arm/plat-samsung/pm-debug.c +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Copyright (C) 2013 Samsung Electronics Co., Ltd. -// Tomasz Figa <t.figa@samsung.com> -// Copyright (C) 2008 Openmoko, Inc. -// Copyright (C) 2004-2008 Simtec Electronics -// Ben Dooks <ben@simtec.co.uk> -// http://armlinux.simtec.co.uk/ -// -// Samsung common power management (suspend to RAM) debug support - -#include <linux/serial_core.h> -#include <linux/serial_s3c.h> -#include <linux/io.h> - -#include <asm/mach/map.h> - -#include <plat/cpu.h> -#include <plat/pm-common.h> - -#ifdef CONFIG_SAMSUNG_ATAGS -#include <plat/pm.h> -#include <mach/pm-core.h> -#else -static inline void s3c_pm_debug_init_uart(void) {} -static inline void s3c_pm_arch_update_uart(void __iomem *regs, - struct pm_uart_save *save) {} -#endif - -static struct pm_uart_save uart_save; - -extern void printascii(const char *); - -void s3c_pm_dbg(const char *fmt, ...) -{ - va_list va; - char buff[256]; - - va_start(va, fmt); - vsnprintf(buff, sizeof(buff), fmt, va); - va_end(va); - - printascii(buff); -} - -void s3c_pm_debug_init(void) -{ - /* restart uart clocks so we can use them to output */ - s3c_pm_debug_init_uart(); -} - -static inline void __iomem *s3c_pm_uart_base(void) -{ - unsigned long paddr; - unsigned long vaddr; - - debug_ll_addr(&paddr, &vaddr); - - return (void __iomem *)vaddr; -} - -void s3c_pm_save_uarts(void) -{ - void __iomem *regs = s3c_pm_uart_base(); - struct pm_uart_save *save = &uart_save; - - save->ulcon = __raw_readl(regs + S3C2410_ULCON); - save->ucon = __raw_readl(regs + S3C2410_UCON); - save->ufcon = __raw_readl(regs + S3C2410_UFCON); - save->umcon = __raw_readl(regs + S3C2410_UMCON); - save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV); - - if (!soc_is_s3c2410()) - save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT); - - S3C_PMDBG("UART[%p]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n", - regs, save->ulcon, save->ucon, save->ufcon, save->ubrdiv); -} - -void s3c_pm_restore_uarts(void) -{ - void __iomem *regs = s3c_pm_uart_base(); - struct pm_uart_save *save = &uart_save; - - s3c_pm_arch_update_uart(regs, save); - - __raw_writel(save->ulcon, regs + S3C2410_ULCON); - __raw_writel(save->ucon, regs + S3C2410_UCON); - __raw_writel(save->ufcon, regs + S3C2410_UFCON); - __raw_writel(save->umcon, regs + S3C2410_UMCON); - __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV); - - if (!soc_is_s3c2410()) - __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT); -} diff --git a/arch/arm/plat-samsung/watchdog-reset.c b/arch/arm/plat-samsung/watchdog-reset.c deleted file mode 100644 index 71d85ff323f7..000000000000 --- a/arch/arm/plat-samsung/watchdog-reset.c +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Copyright (c) 2008 Simtec Electronics -// Ben Dooks <ben@simtec.co.uk> -// -// Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com> -// -// Watchdog reset support for Samsung SoCs. - -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/delay.h> -#include <linux/of.h> -#include <linux/of_address.h> - -#define S3C2410_WTCON 0x00 -#define S3C2410_WTDAT 0x04 -#define S3C2410_WTCNT 0x08 - -#define S3C2410_WTCON_ENABLE (1 << 5) -#define S3C2410_WTCON_DIV16 (0 << 3) -#define S3C2410_WTCON_RSTEN (1 << 0) -#define S3C2410_WTCON_PRESCALE(x) ((x) << 8) - -static void __iomem *wdt_base; -static struct clk *wdt_clock; - -void samsung_wdt_reset(void) -{ - if (!wdt_base) { - pr_err("%s: wdt reset not initialized\n", __func__); - /* delay to allow the serial port to show the message */ - mdelay(50); - return; - } - - if (!IS_ERR(wdt_clock)) - clk_prepare_enable(wdt_clock); - - /* disable watchdog, to be safe */ - __raw_writel(0, wdt_base + S3C2410_WTCON); - - /* put initial values into count and data */ - __raw_writel(0x80, wdt_base + S3C2410_WTCNT); - __raw_writel(0x80, wdt_base + S3C2410_WTDAT); - - /* set the watchdog to go and reset... */ - __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV16 | - S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x20), - wdt_base + S3C2410_WTCON); - - /* wait for reset to assert... */ - mdelay(500); - - pr_err("Watchdog reset failed to assert reset\n"); - - /* delay to allow the serial port to show the message */ - mdelay(50); -} - -#ifdef CONFIG_OF -static const struct of_device_id s3c2410_wdt_match[] = { - { .compatible = "samsung,s3c2410-wdt" }, - { .compatible = "samsung,s3c6410-wdt" }, - {}, -}; - -void __init samsung_wdt_reset_of_init(void) -{ - struct device_node *np; - - np = of_find_matching_node(NULL, s3c2410_wdt_match); - if (!np) { - pr_err("%s: failed to find watchdog node\n", __func__); - return; - } - - wdt_base = of_iomap(np, 0); - if (!wdt_base) { - pr_err("%s: failed to map watchdog registers\n", __func__); - return; - } - - wdt_clock = of_clk_get(np, 0); -} -#endif - -void __init samsung_wdt_reset_init(void __iomem *base) -{ - wdt_base = base; - wdt_clock = clk_get(NULL, "watchdog"); -} diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c index feefa2055eba..a9653117ca0d 100644 --- a/arch/arm/probes/kprobes/core.c +++ b/arch/arm/probes/kprobes/core.c @@ -413,87 +413,15 @@ void __naked __kprobes kretprobe_trampoline(void) /* Called from kretprobe_trampoline */ static __used __kprobes void *trampoline_handler(struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *tmp; - unsigned long flags, orig_ret_address = 0; - unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; - kprobe_opcode_t *correct_ret_addr = NULL; - - INIT_HLIST_HEAD(&empty_rp); - kretprobe_hash_lock(current, &head, &flags); - - /* - * It is possible to have multiple instances associated with a given - * task either because multiple functions in the call path have - * a return probe installed on them, and/or more than one return - * probe was registered for a target function. - * - * We can handle this because: - * - instances are always inserted at the head of the list - * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the - * real return address, and all the rest will point to - * kretprobe_trampoline - */ - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - orig_ret_address = (unsigned long)ri->ret_addr; - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_assert(ri, orig_ret_address, trampoline_address); - - correct_ret_addr = ri->ret_addr; - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - orig_ret_address = (unsigned long)ri->ret_addr; - if (ri->rp && ri->rp->handler) { - __this_cpu_write(current_kprobe, &ri->rp->kp); - get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; - ri->ret_addr = correct_ret_addr; - ri->rp->handler(ri, regs); - __this_cpu_write(current_kprobe, NULL); - } - - recycle_rp_inst(ri, &empty_rp); - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_hash_unlock(current, &flags); - - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } - - return (void *)orig_ret_address; + return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, + (void *)regs->ARM_fp); } void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) { ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr; + ri->fp = (void *)regs->ARM_fp; /* Replace the return addr with trampoline addr. */ regs->ARM_lr = (unsigned long)&kretprobe_trampoline; diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl index 171077cbf419..d056a548358e 100644 --- a/arch/arm/tools/syscall.tbl +++ b/arch/arm/tools/syscall.tbl @@ -453,3 +453,4 @@ 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 +440 common process_madvise sys_process_madvise diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile index a54f70731d9f..150ce6e6a5d3 100644 --- a/arch/arm/vdso/Makefile +++ b/arch/arm/vdso/Makefile @@ -19,7 +19,7 @@ ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO32 ldflags-$(CONFIG_CPU_ENDIAN_BE8) := --be8 ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \ -z max-page-size=4096 -nostdlib -shared $(ldflags-y) \ - --hash-style=sysv --build-id \ + --hash-style=sysv --build-id=sha1 \ -T obj-$(CONFIG_VDSO) += vdso.o diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index e93145d72c26..60e901cd0de6 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -150,7 +150,7 @@ static int xen_starting_cpu(unsigned int cpu) pr_info("Xen: initializing cpu%d\n", cpu); vcpup = per_cpu_ptr(xen_vcpu_info, cpu); - info.mfn = virt_to_gfn(vcpup); + info.mfn = percpu_to_gfn(vcpup); info.offset = xen_offset_in_page(vcpup); err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, xen_vcpu_nr(cpu), @@ -158,7 +158,8 @@ static int xen_starting_cpu(unsigned int cpu) BUG_ON(err); per_cpu(xen_vcpu, cpu) = vcpup; - xen_setup_runstate_info(cpu); + if (!xen_kernel_unmapped_at_usr()) + xen_setup_runstate_info(cpu); after_register_vcpu_info: enable_percpu_irq(xen_events_irq, 0); @@ -387,7 +388,8 @@ static int __init xen_guest_init(void) return -EINVAL; } - xen_time_setup_guest(); + if (!xen_kernel_unmapped_at_usr()) + xen_time_setup_guest(); if (xen_initial_domain()) pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier); diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c index 396797ffe2b1..467fa225c3d0 100644 --- a/arch/arm/xen/mm.c +++ b/arch/arm/xen/mm.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only #include <linux/cpu.h> #include <linux/dma-direct.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <linux/gfp.h> #include <linux/highmem.h> #include <linux/export.h> @@ -25,11 +25,12 @@ unsigned long xen_get_swiotlb_free_pages(unsigned int order) { - struct memblock_region *reg; + phys_addr_t base; gfp_t flags = __GFP_NOWARN|__GFP_KSWAPD_RECLAIM; + u64 i; - for_each_memblock(memory, reg) { - if (reg->base < (phys_addr_t)0xffffffff) { + for_each_mem_range(i, &base, NULL) { + if (base < (phys_addr_t)0xffffffff) { if (IS_ENABLED(CONFIG_ZONE_DMA32)) flags |= __GFP_DMA32; else diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 51259274a819..f858c352f72a 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -29,6 +29,7 @@ config ARM64 select ARCH_HAS_SETUP_DMA_OPS select ARCH_HAS_SET_DIRECT_MAP select ARCH_HAS_SET_MEMORY + select ARCH_STACKWALK select ARCH_HAS_STRICT_KERNEL_RWX select ARCH_HAS_STRICT_MODULE_RWX select ARCH_HAS_SYNC_DMA_FOR_DEVICE @@ -106,6 +107,7 @@ config ARM64 select GENERIC_CPU_VULNERABILITIES select GENERIC_EARLY_IOREMAP select GENERIC_IDLE_POLL_SETUP + select GENERIC_IRQ_IPI select GENERIC_IRQ_MULTI_HANDLER select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW @@ -121,6 +123,7 @@ config ARM64 select GENERIC_VDSO_TIME_NS select HANDLE_DOMAIN_IRQ select HARDIRQS_SW_RESEND + select HAVE_MOVE_PMD select HAVE_PCI select HAVE_ACPI_APEI if (ACPI && EFI) select HAVE_ALIGNED_STRUCT_PAGE if SLUB @@ -192,6 +195,7 @@ config ARM64 select PCI_SYSCALL if PCI select POWER_RESET select POWER_SUPPLY + select SET_FS select SPARSE_IRQ select SWIOTLB select SYSCTL_EXCEPTION_TRACE @@ -211,12 +215,18 @@ config ARM64_PAGE_SHIFT default 14 if ARM64_16K_PAGES default 12 -config ARM64_CONT_SHIFT +config ARM64_CONT_PTE_SHIFT int default 5 if ARM64_64K_PAGES default 7 if ARM64_16K_PAGES default 4 +config ARM64_CONT_PMD_SHIFT + int + default 5 if ARM64_64K_PAGES + default 5 if ARM64_16K_PAGES + default 4 + config ARCH_MMAP_RND_BITS_MIN default 14 if ARM64_64K_PAGES default 16 if ARM64_16K_PAGES @@ -1033,19 +1043,6 @@ config ARCH_ENABLE_SPLIT_PMD_PTLOCK config CC_HAVE_SHADOW_CALL_STACK def_bool $(cc-option, -fsanitize=shadow-call-stack -ffixed-x18) -config SECCOMP - bool "Enable seccomp to safely compute untrusted bytecode" - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via prctl(PR_SET_SECCOMP), it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - config PARAVIRT bool "Enable paravirtualization code" help @@ -1604,8 +1601,6 @@ config ARM64_BTI_KERNEL depends on CC_HAS_BRANCH_PROT_PAC_RET_BTI # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94697 depends on !CC_IS_GCC || GCC_VERSION >= 100100 - # https://reviews.llvm.org/rGb8ae3fdfa579dbf366b1bb1cbfdbf8c51db7fa55 - depends on !CC_IS_CLANG || CLANG_VERSION >= 100001 depends on !(CC_IS_CLANG && GCOV_KERNEL) depends on (!FUNCTION_GRAPH_TRACER || DYNAMIC_FTRACE_WITH_REGS) help @@ -1638,6 +1633,39 @@ config ARCH_RANDOM provides a high bandwidth, cryptographically secure hardware random number generator. +config ARM64_AS_HAS_MTE + # Initial support for MTE went in binutils 2.32.0, checked with + # ".arch armv8.5-a+memtag" below. However, this was incomplete + # as a late addition to the final architecture spec (LDGM/STGM) + # is only supported in the newer 2.32.x and 2.33 binutils + # versions, hence the extra "stgm" instruction check below. + def_bool $(as-instr,.arch armv8.5-a+memtag\nstgm xzr$(comma)[x0]) + +config ARM64_MTE + bool "Memory Tagging Extension support" + default y + depends on ARM64_AS_HAS_MTE && ARM64_TAGGED_ADDR_ABI + select ARCH_USES_HIGH_VMA_FLAGS + help + Memory Tagging (part of the ARMv8.5 Extensions) provides + architectural support for run-time, always-on detection of + various classes of memory error to aid with software debugging + to eliminate vulnerabilities arising from memory-unsafe + languages. + + This option enables the support for the Memory Tagging + Extension at EL0 (i.e. for userspace). + + Selecting this option allows the feature to be detected at + runtime. Any secondary CPU not implementing this feature will + not be allowed a late bring-up. + + Userspace binaries that want to use this feature must + explicitly opt in. The mechanism for the userspace is + described in: + + Documentation/arm64/memory-tagging-extension.rst. + endmenu config ARM64_SVE @@ -1850,6 +1878,10 @@ config ARCH_ENABLE_HUGEPAGE_MIGRATION def_bool y depends on HUGETLB_PAGE && MIGRATION +config ARCH_ENABLE_THP_MIGRATION + def_bool y + depends on TRANSPARENT_HUGEPAGE + menu "Power management options" source "kernel/power/Kconfig" diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index cd58f8495c45..6f2494dd6d60 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -80,7 +80,6 @@ config ARCH_EXYNOS select EXYNOS_CHIPID select EXYNOS_PM_DOMAINS if PM_GENERIC_DOMAINS select EXYNOS_PMU - select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS select PINCTRL select PINCTRL_EXYNOS @@ -300,6 +299,13 @@ config ARCH_VEXPRESS This enables support for the ARMv8 software model (Versatile Express). +config ARCH_VISCONTI + bool "Toshiba Visconti SoC Family" + select PINCTRL + select PINCTRL_VISCONTI + help + This enables support for Toshiba Visconti SoCs Family. + config ARCH_VULCAN def_bool n diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 130569f90c54..5789c2d18d43 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -10,14 +10,13 @@ # # Copyright (C) 1995-2001 by Russell King -LDFLAGS_vmlinux :=--no-undefined -X -CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET) +LDFLAGS_vmlinux :=--no-undefined -X -z norelro ifeq ($(CONFIG_RELOCATABLE), y) # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour # for relative relocs, since this leads to better Image compression # with the relocation offsets always being zero. -LDFLAGS_vmlinux += -shared -Bsymbolic -z notext -z norelro \ +LDFLAGS_vmlinux += -shared -Bsymbolic -z notext \ $(call ld-option, --no-apply-dynamic-relocs) endif @@ -29,6 +28,10 @@ LDFLAGS_vmlinux += --fix-cortex-a53-843419 endif endif +# We never want expected sections to be placed heuristically by the +# linker. All sections should be explicitly named in the linker script. +LDFLAGS_vmlinux += $(call ld-option, --orphan-handling=warn) + ifeq ($(CONFIG_ARM64_USE_LSE_ATOMICS), y) ifneq ($(CONFIG_ARM64_LSE_ATOMICS), y) $(warning LSE atomics not supported by binutils) @@ -47,13 +50,16 @@ endif KBUILD_CFLAGS += -mgeneral-regs-only \ $(compat_vdso) $(cc_has_k_constraint) -KBUILD_CFLAGS += -fno-asynchronous-unwind-tables KBUILD_CFLAGS += $(call cc-disable-warning, psabi) KBUILD_AFLAGS += $(compat_vdso) KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) KBUILD_AFLAGS += $(call cc-option,-mabi=lp64) +# Avoid generating .eh_frame* sections. +KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables +KBUILD_AFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables + ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) prepare: stack_protector_prepare stack_protector_prepare: prepare0 @@ -120,10 +126,6 @@ endif CHECKFLAGS += -D__aarch64__ -ifeq ($(CONFIG_ARM64_MODULE_PLTS),y) -KBUILD_LDS_MODULE += $(srctree)/arch/arm64/kernel/module.lds -endif - ifeq ($(CONFIG_DYNAMIC_FTRACE_WITH_REGS),y) KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY CC_FLAGS_FTRACE := -fpatchable-function-entry=2 @@ -132,9 +134,6 @@ endif # Default value head-y := arch/arm64/kernel/head.o -# The byte offset of the kernel image in RAM from the start of RAM. -TEXT_OFFSET := 0x0 - ifeq ($(CONFIG_KASAN_SW_TAGS), y) KASAN_SHADOW_SCALE_SHIFT := 4 else @@ -145,8 +144,6 @@ KBUILD_CFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT) KBUILD_CPPFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT) KBUILD_AFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT) -export TEXT_OFFSET - core-y += arch/arm64/ libs-y := arch/arm64/lib/ $(libs-y) libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index 270e8aabbac8..9b1170658d60 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile @@ -27,5 +27,6 @@ subdir-y += socionext subdir-y += sprd subdir-y += synaptics subdir-y += ti +subdir-y += toshiba subdir-y += xilinx subdir-y += zte diff --git a/arch/arm64/boot/dts/actions/s700.dtsi b/arch/arm64/boot/dts/actions/s700.dtsi index 2006ad5424fa..2c78caebf515 100644 --- a/arch/arm64/boot/dts/actions/s700.dtsi +++ b/arch/arm64/boot/dts/actions/s700.dtsi @@ -5,6 +5,7 @@ #include <dt-bindings/clock/actions,s700-cmu.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/power/owl-s700-powergate.h> #include <dt-bindings/reset/actions,s700-reset.h> / { @@ -231,7 +232,7 @@ pinctrl: pinctrl@e01b0000 { compatible = "actions,s700-pinctrl"; - reg = <0x0 0xe01b0000 0x0 0x1000>; + reg = <0x0 0xe01b0000 0x0 0x100>; clocks = <&cmu CLK_GPIO>; gpio-controller; gpio-ranges = <&pinctrl 0 0 136>; @@ -244,5 +245,19 @@ <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; }; + + dma: dma-controller@e0230000 { + compatible = "actions,s700-dma"; + reg = <0x0 0xe0230000 0x0 0x1000>; + interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <1>; + dma-channels = <10>; + dma-requests = <44>; + clocks = <&cmu CLK_DMAC>; + power-domains = <&sps S700_PD_DMA>; + }; }; }; diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile index 916d10d5b87c..211d1e9d4701 100644 --- a/arch/arm64/boot/dts/allwinner/Makefile +++ b/arch/arm64/boot/dts/allwinner/Makefile @@ -15,6 +15,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinephone-1.2.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a100-allwinner-perf1.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-emlid-neutis-n5-devboard.dtb diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a100-allwinner-perf1.dts b/arch/arm64/boot/dts/allwinner/sun50i-a100-allwinner-perf1.dts new file mode 100644 index 000000000000..d34c2bb1079f --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-a100-allwinner-perf1.dts @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: (GPL-2.0+ or MIT) +/* + * Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com> + */ + +/dts-v1/; + +#include "sun50i-a100.dtsi" + +/{ + model = "Allwinner A100 Perf1"; + compatible = "allwinner,a100-perf1", "allwinner,sun50i-a100"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&pio { + vcc-pb-supply = <®_dcdc1>; + vcc-pc-supply = <®_eldo1>; + vcc-pd-supply = <®_dcdc1>; + vcc-pe-supply = <®_dldo2>; + vcc-pf-supply = <®_dcdc1>; + vcc-pg-supply = <®_dldo1>; + vcc-ph-supply = <®_dcdc1>; +}; + +&r_pio { + /* + * FIXME: We can't add that supply for now since it would + * create a circular dependency between pinctrl, the regulator + * and the RSB Bus. + * + * vcc-pl-supply = <®_aldo3>; + */ +}; + +&r_i2c0 { + status = "okay"; + + axp803: pmic@34 { + compatible = "x-powers,axp803"; + reg = <0x34>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */ + }; +}; + +#include "axp803.dtsi" + +&ac_power_supply { + status = "okay"; +}; + +®_aldo1 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-dram-1"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-usb-pl"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-io-usb-pd-emmc-nand-card"; +}; + +®_dcdc2 { + regulator-always-on; + /* + * FIXME: update min and max before support dvfs. + */ + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-cpux"; +}; + +/* DCDC3 is polyphased with DCDC2 */ + +®_dcdc4 { + regulator-always-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <950000>; + regulator-name = "vdd-sys-usb-dram"; +}; + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vcc-dram-2"; +}; + +®_dldo1 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pg-dcxo-wifi"; +}; + +®_dldo2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2800000>; + regulator-name = "vcc-pe-csi"; +}; + +®_dldo3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "ldo-avdd-csi"; +}; + +®_dldo4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2800000>; + regulator-name = "avcc-csi"; +}; + +®_eldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pc-lvds-csi-efuse-emmc-nand"; +}; + +®_eldo2 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1800000>; + regulator-name = "dvdd-csi"; +}; + +®_eldo3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-mipi-lcd"; +}; + +®_fldo1 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdd-cpus-usb"; +}; + +®_ldo_io0 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-ctp"; + status = "okay"; +}; + +®_drivevbus { + regulator-name = "usb0-vbus"; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi new file mode 100644 index 000000000000..cc321c04f121 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi @@ -0,0 +1,364 @@ +// SPDX-License-Identifier: (GPL-2.0+ or MIT) +/* + * Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com> + */ + +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/sun50i-a100-ccu.h> +#include <dt-bindings/clock/sun50i-a100-r-ccu.h> +#include <dt-bindings/reset/sun50i-a100-ccu.h> +#include <dt-bindings/reset/sun50i-a100-r-ccu.h> + +/ { + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + reg = <0x0>; + enable-method = "psci"; + }; + + cpu@1 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + reg = <0x1>; + enable-method = "psci"; + }; + + cpu@2 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + reg = <0x2>; + enable-method = "psci"; + }; + + cpu@3 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + reg = <0x3>; + enable-method = "psci"; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + dcxo24M: dcxo24M-clk { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "dcxo24M"; + #clock-cells = <0>; + }; + + iosc: internal-osc-clk { + compatible = "fixed-clock"; + clock-frequency = <16000000>; + clock-accuracy = <300000000>; + clock-output-names = "iosc"; + #clock-cells = <0>; + }; + + osc32k: osc32k-clk { + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "osc32k"; + #clock-cells = <0>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, + <GIC_PPI 14 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, + <GIC_PPI 11 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, + <GIC_PPI 10 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0x3fffffff>; + + ccu: clock@3001000 { + compatible = "allwinner,sun50i-a100-ccu"; + reg = <0x03001000 0x1000>; + clocks = <&dcxo24M>, <&osc32k>, <&iosc>; + clock-names = "hosc", "losc", "iosc"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + gic: interrupt-controller@3021000 { + compatible = "arm,gic-400"; + reg = <0x03021000 0x1000>, <0x03022000 0x2000>, + <0x03024000 0x2000>, <0x03026000 0x2000>; + interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | + IRQ_TYPE_LEVEL_HIGH)>; + interrupt-controller; + #interrupt-cells = <3>; + }; + + efuse@3006000 { + compatible = "allwinner,sun50i-a100-sid", + "allwinner,sun50i-a64-sid"; + reg = <0x03006000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + ths_calibration: calib@14 { + reg = <0x14 8>; + }; + }; + + pio: pinctrl@300b000 { + compatible = "allwinner,sun50i-a100-pinctrl"; + reg = <0x0300b000 0x400>; + interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_APB1>, <&dcxo24M>, <&osc32k>; + clock-names = "apb", "hosc", "losc"; + gpio-controller; + #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <3>; + + uart0_pb_pins: uart0-pb-pins { + pins = "PB9", "PB10"; + function = "uart0"; + }; + }; + + uart0: serial@5000000 { + compatible = "snps,dw-apb-uart"; + reg = <0x05000000 0x400>; + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART0>; + resets = <&ccu RST_BUS_UART0>; + status = "disabled"; + }; + + uart1: serial@5000400 { + compatible = "snps,dw-apb-uart"; + reg = <0x05000400 0x400>; + interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART1>; + resets = <&ccu RST_BUS_UART1>; + status = "disabled"; + }; + + uart2: serial@5000800 { + compatible = "snps,dw-apb-uart"; + reg = <0x05000800 0x400>; + interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART2>; + resets = <&ccu RST_BUS_UART2>; + status = "disabled"; + }; + + uart3: serial@5000c00 { + compatible = "snps,dw-apb-uart"; + reg = <0x05000c00 0x400>; + interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART3>; + resets = <&ccu RST_BUS_UART3>; + status = "disabled"; + }; + + uart4: serial@5001000 { + compatible = "snps,dw-apb-uart"; + reg = <0x05001000 0x400>; + interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART4>; + resets = <&ccu RST_BUS_UART4>; + status = "disabled"; + }; + + i2c0: i2c@5002000 { + compatible = "allwinner,sun50i-a100-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x05002000 0x400>; + interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2C0>; + resets = <&ccu RST_BUS_I2C0>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c1: i2c@5002400 { + compatible = "allwinner,sun50i-a100-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x05002400 0x400>; + interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2C1>; + resets = <&ccu RST_BUS_I2C1>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c2: i2c@5002800 { + compatible = "allwinner,sun50i-a100-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x05002800 0x400>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2C2>; + resets = <&ccu RST_BUS_I2C2>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c3: i2c@5002c00 { + compatible = "allwinner,sun50i-a100-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x05002c00 0x400>; + interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_I2C3>; + resets = <&ccu RST_BUS_I2C3>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + ths: thermal-sensor@5070400 { + compatible = "allwinner,sun50i-a100-ths"; + reg = <0x05070400 0x100>; + interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_THS>; + clock-names = "bus"; + resets = <&ccu RST_BUS_THS>; + nvmem-cells = <&ths_calibration>; + nvmem-cell-names = "calibration"; + #thermal-sensor-cells = <1>; + }; + + r_ccu: clock@7010000 { + compatible = "allwinner,sun50i-a100-r-ccu"; + reg = <0x07010000 0x300>; + clocks = <&dcxo24M>, <&osc32k>, <&iosc>, + <&ccu CLK_PLL_PERIPH0>; + clock-names = "hosc", "losc", "iosc", "pll-periph"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + r_intc: interrupt-controller@7010320 { + compatible = "allwinner,sun50i-a100-nmi", + "allwinner,sun9i-a80-nmi"; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x07010320 0xc>; + interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; + }; + + r_pio: pinctrl@7022000 { + compatible = "allwinner,sun50i-a100-r-pinctrl"; + reg = <0x07022000 0x400>; + interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&r_ccu CLK_R_APB1>, <&dcxo24M>, <&osc32k>; + clock-names = "apb", "hosc", "losc"; + gpio-controller; + #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <3>; + + r_i2c0_pins: r-i2c0-pins { + pins = "PL0", "PL1"; + function = "s_i2c0"; + }; + + r_i2c1_pins: r-i2c1-pins { + pins = "PL8", "PL9"; + function = "s_i2c1"; + }; + }; + + r_uart: serial@7080000 { + compatible = "snps,dw-apb-uart"; + reg = <0x07080000 0x400>; + interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&r_ccu CLK_R_APB2_UART>; + resets = <&r_ccu RST_R_APB2_UART>; + status = "disabled"; + }; + + r_i2c0: i2c@7081400 { + compatible = "allwinner,sun50i-a100-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x07081400 0x400>; + interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&r_ccu CLK_R_APB2_I2C0>; + resets = <&r_ccu RST_R_APB2_I2C0>; + pinctrl-names = "default"; + pinctrl-0 = <&r_i2c0_pins>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + r_i2c1: i2c@7081800 { + compatible = "allwinner,sun50i-a100-i2c", + "allwinner,sun6i-a31-i2c"; + reg = <0x07081800 0x400>; + interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&r_ccu CLK_R_APB2_I2C1>; + resets = <&r_ccu RST_R_APB2_I2C1>; + pinctrl-names = "default"; + pinctrl-0 = <&r_i2c1_pins>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + thermal-zones { + cpu-thermal-zone { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&ths 0>; + }; + + ddr-thermal-zone { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&ths 2>; + }; + + gpu-thermal-zone { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&ths 1>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts index 883f217efb81..3ea5182ca489 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts @@ -331,10 +331,10 @@ "Microphone", "Microphone Jack", "Microphone", "Onboard Microphone"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "Left DAC", "DACL", + "Right DAC", "DACR", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "Headphone Jack", "HP", "MIC2", "Microphone Jack", "Onboard Microphone", "MBIAS", diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts index fde9c7a99b17..d894ec5fa8a1 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts @@ -330,10 +330,10 @@ "Microphone", "Microphone Jack", "Microphone", "Onboard Microphone"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "Left DAC", "DACL", + "Right DAC", "DACR", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "Headphone Jack", "HP", "MIC2", "Microphone Jack", "Onboard Microphone", "MBIAS", diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts index 2165f238af13..329cf276561e 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts @@ -261,11 +261,11 @@ simple-audio-card,widgets = "Microphone", "Microphone Jack", "Headphone", "Headphone Jack"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", + "Left DAC", "DACL", + "Right DAC", "DACR", "Headphone Jack", "HP", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "MIC2", "Microphone Jack"; status = "okay"; }; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts index 64b1c54f87c0..896f34fd9fc3 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts @@ -374,15 +374,15 @@ "Headphone", "Headphone Jack", "Speaker", "Internal Speaker"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", + "Left DAC", "DACL", + "Right DAC", "DACR", "Speaker Amp INL", "LINEOUT", "Speaker Amp INR", "LINEOUT", "Internal Speaker", "Speaker Amp OUTL", "Internal Speaker", "Speaker Amp OUTR", "Headphone Jack", "HP", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "Internal Microphone Left", "MBIAS", "MIC1", "Internal Microphone Left", "Internal Microphone Right", "HBIAS", diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi index 25150aba749d..5780713b0dba 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi @@ -392,10 +392,10 @@ "Internal Speaker", "Speaker Amp OUTR", "Speaker Amp INL", "LINEOUT", "Speaker Amp INR", "LINEOUT", - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "Left DAC", "DACL", + "Right DAC", "DACR", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "Internal Microphone", "MBIAS", "MIC1", "Internal Microphone", "Headset Microphone", "HBIAS", diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts index dc4ab6b434f9..3ab0f0347bc9 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts @@ -421,15 +421,15 @@ "Headphone", "Headphone Jack", "Speaker", "Internal Speaker"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", + "Left DAC", "DACL", + "Right DAC", "DACR", "Speaker Amp INL", "LINEOUT", "Speaker Amp INR", "LINEOUT", "Internal Speaker", "Speaker Amp OUTL", "Internal Speaker", "Speaker Amp OUTR", "Headphone Jack", "HP", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "Internal Microphone Left", "MBIAS", "MIC1", "Internal Microphone Left", "Internal Microphone Right", "HBIAS", diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts index 2f6ea9f3f6a2..9ebb9e07fae3 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts @@ -159,11 +159,11 @@ simple-audio-card,widgets = "Microphone", "Microphone Jack", "Headphone", "Headphone Jack"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", + "Left DAC", "DACL", + "Right DAC", "DACR", "Headphone Jack", "HP", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "MIC2", "Microphone Jack"; status = "okay"; }; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts index f5df5f705b72..a1864a89fb89 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts @@ -340,10 +340,10 @@ "Microphone", "Internal Microphone", "Speaker", "Internal Speaker"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "Left DAC", "DACL", + "Right DAC", "DACR", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "Headphone Jack", "HP", "Speaker Amp INL", "LINEOUT", "Speaker Amp INR", "LINEOUT", diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index 8dfbcd144072..dc238814013c 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -51,7 +51,7 @@ reg = <0>; enable-method = "psci"; next-level-cache = <&L2>; - clocks = <&ccu 21>; + clocks = <&ccu CLK_CPUX>; clock-names = "cpu"; #cooling-cells = <2>; }; @@ -62,7 +62,7 @@ reg = <1>; enable-method = "psci"; next-level-cache = <&L2>; - clocks = <&ccu 21>; + clocks = <&ccu CLK_CPUX>; clock-names = "cpu"; #cooling-cells = <2>; }; @@ -73,7 +73,7 @@ reg = <2>; enable-method = "psci"; next-level-cache = <&L2>; - clocks = <&ccu 21>; + clocks = <&ccu CLK_CPUX>; clock-names = "cpu"; #cooling-cells = <2>; }; @@ -84,7 +84,7 @@ reg = <3>; enable-method = "psci"; next-level-cache = <&L2>; - clocks = <&ccu 21>; + clocks = <&ccu CLK_CPUX>; clock-names = "cpu"; #cooling-cells = <2>; }; @@ -139,10 +139,10 @@ simple-audio-card,mclk-fs = <128>; simple-audio-card,aux-devs = <&codec_analog>; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC"; + "Left DAC", "DACL", + "Right DAC", "DACR", + "ADCL", "Left ADC", + "ADCR", "Right ADC"; status = "disabled"; cpudai: simple-audio-card,cpu { @@ -157,6 +157,7 @@ timer { compatible = "arm,armv8-timer"; allwinner,erratum-unknown1; + arm,no-tick-in-suspend; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, <GIC_PPI 14 @@ -860,7 +861,8 @@ codec: codec@1c22e00 { #sound-dai-cells = <0>; - compatible = "allwinner,sun8i-a33-codec"; + compatible = "allwinner,sun50i-a64-codec", + "allwinner,sun8i-a33-codec"; reg = <0x01c22e00 0x600>; interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi index 6735e316a39c..10489e508695 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi @@ -67,6 +67,7 @@ timer { compatible = "arm,armv8-timer"; + arm,no-tick-in-suspend; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 14 @@ -139,8 +140,7 @@ <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 98 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "gp", "gpmmu", "pp", @@ -151,8 +151,7 @@ "pp2", "ppmmu2", "pp3", - "ppmmu3", - "pmu"; + "ppmmu3"; clocks = <&ccu CLK_BUS_GPU>, <&ccu CLK_GPU>; clock-names = "bus", "core"; resets = <&ccu RST_BUS_GPU>; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi index 9ce78a7b117d..28c77d6872f6 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi @@ -90,6 +90,7 @@ timer { compatible = "arm,armv8-timer"; + arm,no-tick-in-suspend; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, <GIC_PPI 14 diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi index a6fb01c7ab34..0f893984c256 100644 --- a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi +++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi @@ -145,8 +145,8 @@ mac-address = [00 00 00 00 00 00]; resets = <&rst EMAC0_RESET>, <&rst EMAC0_OCP_RESET>; reset-names = "stmmaceth", "stmmaceth-ocp"; - clocks = <&clkmgr STRATIX10_EMAC0_CLK>; - clock-names = "stmmaceth"; + clocks = <&clkmgr STRATIX10_EMAC0_CLK>, <&clkmgr STRATIX10_EMAC_PTP_CLK>; + clock-names = "stmmaceth", "ptp_ref"; tx-fifo-depth = <16384>; rx-fifo-depth = <16384>; snps,multicast-filter-bins = <256>; @@ -163,8 +163,8 @@ mac-address = [00 00 00 00 00 00]; resets = <&rst EMAC1_RESET>, <&rst EMAC1_OCP_RESET>; reset-names = "stmmaceth", "stmmaceth-ocp"; - clocks = <&clkmgr STRATIX10_EMAC1_CLK>; - clock-names = "stmmaceth"; + clocks = <&clkmgr STRATIX10_EMAC1_CLK>, <&clkmgr STRATIX10_EMAC_PTP_CLK>; + clock-names = "stmmaceth", "ptp_ref"; tx-fifo-depth = <16384>; rx-fifo-depth = <16384>; snps,multicast-filter-bins = <256>; @@ -181,8 +181,8 @@ mac-address = [00 00 00 00 00 00]; resets = <&rst EMAC2_RESET>, <&rst EMAC2_OCP_RESET>; reset-names = "stmmaceth", "stmmaceth-ocp"; - clocks = <&clkmgr STRATIX10_EMAC2_CLK>; - clock-names = "stmmaceth"; + clocks = <&clkmgr STRATIX10_EMAC2_CLK>, <&clkmgr STRATIX10_EMAC_PTP_CLK>; + clock-names = "stmmaceth", "ptp_ref"; tx-fifo-depth = <16384>; rx-fifo-depth = <16384>; snps,multicast-filter-bins = <256>; diff --git a/arch/arm64/boot/dts/amazon/alpine-v2.dtsi b/arch/arm64/boot/dts/amazon/alpine-v2.dtsi index d5e7e2bb4e6c..4eb2cd14e00b 100644 --- a/arch/arm64/boot/dts/amazon/alpine-v2.dtsi +++ b/arch/arm64/boot/dts/amazon/alpine-v2.dtsi @@ -113,7 +113,7 @@ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>; }; - gic: gic@f0100000 { + gic: interrupt-controller@f0200000 { compatible = "arm,gic-v3"; reg = <0x0 0xf0200000 0x0 0x10000>, /* GIC Dist */ <0x0 0xf0280000 0x0 0x200000>, /* GICR */ diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile index 4e2239ffcaa5..ced03946314f 100644 --- a/arch/arm64/boot/dts/amlogic/Makefile +++ b/arch/arm64/boot/dts/amlogic/Makefile @@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gtking-pro.dtb dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-khadas-vim3.dtb dtb-$(CONFIG_ARCH_MESON) += meson-g12b-s922x-khadas-vim3.dtb dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2-plus.dtb dtb-$(CONFIG_ARCH_MESON) += meson-g12b-ugoos-am6.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-kii-pro.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nanopi-k2.dtb @@ -24,6 +25,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s805x-libretech-ac.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-hwacom-amazetv.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-khadas-vim.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-libretech-cc-v2.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-nexbox-a95x.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-p212.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p230.dtb diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi index 224c890d32d3..f42cf4b8af2d 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi @@ -5,8 +5,6 @@ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com> */ -#include <dt-bindings/sound/meson-g12a-tohdmitx.h> - / { model = "Khadas VIM3"; @@ -47,69 +45,6 @@ regulator-boot-on; regulator-always-on; }; - - sound { - compatible = "amlogic,axg-sound-card"; - model = "G12B-KHADAS-VIM3"; - audio-aux-devs = <&tdmout_a>; - audio-routing = "TDMOUT_A IN 0", "FRDDR_A OUT 0", - "TDMOUT_A IN 1", "FRDDR_B OUT 0", - "TDMOUT_A IN 2", "FRDDR_C OUT 0", - "TDM_A Playback", "TDMOUT_A OUT"; - - assigned-clocks = <&clkc CLKID_MPLL2>, - <&clkc CLKID_MPLL0>, - <&clkc CLKID_MPLL1>; - assigned-clock-parents = <0>, <0>, <0>; - assigned-clock-rates = <294912000>, - <270950400>, - <393216000>; - status = "okay"; - - dai-link-0 { - sound-dai = <&frddr_a>; - }; - - dai-link-1 { - sound-dai = <&frddr_b>; - }; - - dai-link-2 { - sound-dai = <&frddr_c>; - }; - - /* 8ch hdmi interface */ - dai-link-3 { - sound-dai = <&tdmif_a>; - dai-format = "i2s"; - dai-tdm-slot-tx-mask-0 = <1 1>; - dai-tdm-slot-tx-mask-1 = <1 1>; - dai-tdm-slot-tx-mask-2 = <1 1>; - dai-tdm-slot-tx-mask-3 = <1 1>; - mclk-fs = <256>; - - codec { - sound-dai = <&tohdmitx TOHDMITX_I2S_IN_A>; - }; - }; - - /* hdmi glue */ - dai-link-4 { - sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; - - codec { - sound-dai = <&hdmi_tx>; - }; - }; - }; -}; - -&arb { - status = "okay"; -}; - -&clkc_audio { - status = "okay"; }; &cpu0 { @@ -154,18 +89,6 @@ clock-latency = <50000>; }; -&frddr_a { - status = "okay"; -}; - -&frddr_b { - status = "okay"; -}; - -&frddr_c { - status = "okay"; -}; - &pwm_ab { pinctrl-0 = <&pwm_a_e_pins>; pinctrl-names = "default"; @@ -182,14 +105,3 @@ status = "okay"; }; -&tdmif_a { - status = "okay"; -}; - -&tdmout_a { - status = "okay"; -}; - -&tohdmitx { - status = "okay"; -}; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2-plus.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2-plus.dts new file mode 100644 index 000000000000..5de2815ba99d --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2-plus.dts @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +/dts-v1/; + +/* The Amlogic S922X Rev. C supports the same OPPs as the A311D variant */ +#include "meson-g12b-a311d.dtsi" +#include "meson-g12b-odroid-n2.dtsi" + +/ { + compatible = "hardkernel,odroid-n2-plus", "amlogic,s922x", "amlogic,g12b"; + model = "Hardkernel ODROID-N2Plus"; +}; + +&vddcpu_a { + regulator-min-microvolt = <680000>; + regulator-max-microvolt = <1040000>; + + pwms = <&pwm_AO_cd 1 1500 0>; +}; + +&vddcpu_b { + regulator-min-microvolt = <680000>; + regulator-max-microvolt = <1040000>; + + pwms = <&pwm_AO_cd 1 1500 0>; +}; + diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts index 34fffa6d859d..a198a91259ec 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts @@ -7,625 +7,9 @@ /dts-v1/; #include "meson-g12b-s922x.dtsi" -#include <dt-bindings/input/input.h> -#include <dt-bindings/gpio/meson-g12a-gpio.h> -#include <dt-bindings/sound/meson-g12a-toacodec.h> -#include <dt-bindings/sound/meson-g12a-tohdmitx.h> +#include "meson-g12b-odroid-n2.dtsi" / { compatible = "hardkernel,odroid-n2", "amlogic,s922x", "amlogic,g12b"; model = "Hardkernel ODROID-N2"; - - aliases { - serial0 = &uart_AO; - ethernet0 = ðmac; - }; - - dioo2133: audio-amplifier-0 { - compatible = "simple-audio-amplifier"; - enable-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>; - VCC-supply = <&vcc_5v>; - sound-name-prefix = "U19"; - status = "okay"; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - memory@0 { - device_type = "memory"; - reg = <0x0 0x0 0x0 0x40000000>; - }; - - emmc_pwrseq: emmc-pwrseq { - compatible = "mmc-pwrseq-emmc"; - reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>; - }; - - leds { - compatible = "gpio-leds"; - - blue { - label = "n2:blue"; - gpios = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; - }; - }; - - tflash_vdd: regulator-tflash_vdd { - compatible = "regulator-fixed"; - - regulator-name = "TFLASH_VDD"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - gpio = <&gpio_ao GPIOAO_8 GPIO_ACTIVE_HIGH>; - enable-active-high; - regulator-always-on; - }; - - tf_io: gpio-regulator-tf_io { - compatible = "regulator-gpio"; - - regulator-name = "TF_IO"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - - gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>; - gpios-states = <0>; - - states = <3300000 0>, - <1800000 1>; - }; - - flash_1v8: regulator-flash_1v8 { - compatible = "regulator-fixed"; - regulator-name = "FLASH_1V8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - vin-supply = <&vcc_3v3>; - regulator-always-on; - }; - - main_12v: regulator-main_12v { - compatible = "regulator-fixed"; - regulator-name = "12V"; - regulator-min-microvolt = <12000000>; - regulator-max-microvolt = <12000000>; - regulator-always-on; - }; - - vcc_5v: regulator-vcc_5v { - compatible = "regulator-fixed"; - regulator-name = "5V"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - regulator-always-on; - vin-supply = <&main_12v>; - }; - - vcc_1v8: regulator-vcc_1v8 { - compatible = "regulator-fixed"; - regulator-name = "VCC_1V8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - vin-supply = <&vcc_3v3>; - regulator-always-on; - }; - - vcc_3v3: regulator-vcc_3v3 { - compatible = "regulator-fixed"; - regulator-name = "VCC_3V3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <&vddao_3v3>; - regulator-always-on; - /* FIXME: actually controlled by VDDCPU_B_EN */ - }; - - vddcpu_a: regulator-vddcpu-a { - /* - * MP8756GD Regulator. - */ - compatible = "pwm-regulator"; - - regulator-name = "VDDCPU_A"; - regulator-min-microvolt = <721000>; - regulator-max-microvolt = <1022000>; - - vin-supply = <&main_12v>; - - pwms = <&pwm_ab 0 1250 0>; - pwm-dutycycle-range = <100 0>; - - regulator-boot-on; - regulator-always-on; - }; - - vddcpu_b: regulator-vddcpu-b { - /* - * Silergy SY8120B1ABC Regulator. - */ - compatible = "pwm-regulator"; - - regulator-name = "VDDCPU_B"; - regulator-min-microvolt = <721000>; - regulator-max-microvolt = <1022000>; - - vin-supply = <&main_12v>; - - pwms = <&pwm_AO_cd 1 1250 0>; - pwm-dutycycle-range = <100 0>; - - regulator-boot-on; - regulator-always-on; - }; - - hub_5v: regulator-hub_5v { - compatible = "regulator-fixed"; - regulator-name = "HUB_5V"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc_5v>; - - /* Connected to the Hub CHIPENABLE, LOW sets low power state */ - gpio = <&gpio GPIOH_5 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - - usb_pwr_en: regulator-usb_pwr_en { - compatible = "regulator-fixed"; - regulator-name = "USB_PWR_EN"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc_5v>; - - /* Connected to the microUSB port power enable */ - gpio = <&gpio GPIOH_6 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - - vddao_1v8: regulator-vddao_1v8 { - compatible = "regulator-fixed"; - regulator-name = "VDDAO_1V8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - vin-supply = <&vddao_3v3>; - regulator-always-on; - }; - - vddao_3v3: regulator-vddao_3v3 { - compatible = "regulator-fixed"; - regulator-name = "VDDAO_3V3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <&main_12v>; - regulator-always-on; - }; - - hdmi-connector { - compatible = "hdmi-connector"; - type = "a"; - - port { - hdmi_connector_in: endpoint { - remote-endpoint = <&hdmi_tx_tmds_out>; - }; - }; - }; - - sound { - compatible = "amlogic,axg-sound-card"; - model = "G12B-ODROID-N2"; - audio-widgets = "Line", "Lineout"; - audio-aux-devs = <&tdmout_b>, <&tdmout_c>, <&tdmin_a>, - <&tdmin_b>, <&tdmin_c>, <&tdmin_lb>, - <&dioo2133>; - audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", - "TDMOUT_B IN 1", "FRDDR_B OUT 1", - "TDMOUT_B IN 2", "FRDDR_C OUT 1", - "TDM_B Playback", "TDMOUT_B OUT", - "TDMOUT_C IN 0", "FRDDR_A OUT 2", - "TDMOUT_C IN 1", "FRDDR_B OUT 2", - "TDMOUT_C IN 2", "FRDDR_C OUT 2", - "TDM_C Playback", "TDMOUT_C OUT", - "TDMIN_A IN 4", "TDM_B Loopback", - "TDMIN_B IN 4", "TDM_B Loopback", - "TDMIN_C IN 4", "TDM_B Loopback", - "TDMIN_LB IN 1", "TDM_B Loopback", - "TDMIN_A IN 5", "TDM_C Loopback", - "TDMIN_B IN 5", "TDM_C Loopback", - "TDMIN_C IN 5", "TDM_C Loopback", - "TDMIN_LB IN 2", "TDM_C Loopback", - "TODDR_A IN 0", "TDMIN_A OUT", - "TODDR_B IN 0", "TDMIN_A OUT", - "TODDR_C IN 0", "TDMIN_A OUT", - "TODDR_A IN 1", "TDMIN_B OUT", - "TODDR_B IN 1", "TDMIN_B OUT", - "TODDR_C IN 1", "TDMIN_B OUT", - "TODDR_A IN 2", "TDMIN_C OUT", - "TODDR_B IN 2", "TDMIN_C OUT", - "TODDR_C IN 2", "TDMIN_C OUT", - "TODDR_A IN 6", "TDMIN_LB OUT", - "TODDR_B IN 6", "TDMIN_LB OUT", - "TODDR_C IN 6", "TDMIN_LB OUT", - "U19 INL", "ACODEC LOLP", - "U19 INR", "ACODEC LORP", - "Lineout", "U19 OUTL", - "Lineout", "U19 OUTR"; - - assigned-clocks = <&clkc CLKID_MPLL2>, - <&clkc CLKID_MPLL0>, - <&clkc CLKID_MPLL1>; - assigned-clock-parents = <0>, <0>, <0>; - assigned-clock-rates = <294912000>, - <270950400>, - <393216000>; - status = "okay"; - - dai-link-0 { - sound-dai = <&frddr_a>; - }; - - dai-link-1 { - sound-dai = <&frddr_b>; - }; - - dai-link-2 { - sound-dai = <&frddr_c>; - }; - - dai-link-3 { - sound-dai = <&toddr_a>; - }; - - dai-link-4 { - sound-dai = <&toddr_b>; - }; - - dai-link-5 { - sound-dai = <&toddr_c>; - }; - - /* 8ch hdmi interface */ - dai-link-6 { - sound-dai = <&tdmif_b>; - dai-format = "i2s"; - dai-tdm-slot-tx-mask-0 = <1 1>; - dai-tdm-slot-tx-mask-1 = <1 1>; - dai-tdm-slot-tx-mask-2 = <1 1>; - dai-tdm-slot-tx-mask-3 = <1 1>; - mclk-fs = <256>; - - codec-0 { - sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>; - }; - - codec-1 { - sound-dai = <&toacodec TOACODEC_IN_B>; - }; - }; - - /* i2s jack output interface */ - dai-link-7 { - sound-dai = <&tdmif_c>; - dai-format = "i2s"; - dai-tdm-slot-tx-mask-0 = <1 1>; - mclk-fs = <256>; - - codec-0 { - sound-dai = <&tohdmitx TOHDMITX_I2S_IN_C>; - }; - - codec-1 { - sound-dai = <&toacodec TOACODEC_IN_C>; - }; - }; - - /* hdmi glue */ - dai-link-8 { - sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; - - codec { - sound-dai = <&hdmi_tx>; - }; - }; - - /* acodec glue */ - dai-link-9 { - sound-dai = <&toacodec TOACODEC_OUT>; - - codec { - sound-dai = <&acodec>; - }; - }; - }; -}; - -&acodec { - AVDD-supply = <&vddao_1v8>; - status = "okay"; -}; - -&arb { - status = "okay"; -}; - -&cec_AO { - pinctrl-0 = <&cec_ao_a_h_pins>; - pinctrl-names = "default"; - status = "disabled"; - hdmi-phandle = <&hdmi_tx>; -}; - -&cecb_AO { - pinctrl-0 = <&cec_ao_b_h_pins>; - pinctrl-names = "default"; - status = "okay"; - hdmi-phandle = <&hdmi_tx>; -}; - -&clkc_audio { - status = "okay"; -}; - -&cpu0 { - cpu-supply = <&vddcpu_b>; - operating-points-v2 = <&cpu_opp_table_0>; - clocks = <&clkc CLKID_CPU_CLK>; - clock-latency = <50000>; -}; - -&cpu1 { - cpu-supply = <&vddcpu_b>; - operating-points-v2 = <&cpu_opp_table_0>; - clocks = <&clkc CLKID_CPU_CLK>; - clock-latency = <50000>; -}; - -&cpu100 { - cpu-supply = <&vddcpu_a>; - operating-points-v2 = <&cpub_opp_table_1>; - clocks = <&clkc CLKID_CPUB_CLK>; - clock-latency = <50000>; -}; - -&cpu101 { - cpu-supply = <&vddcpu_a>; - operating-points-v2 = <&cpub_opp_table_1>; - clocks = <&clkc CLKID_CPUB_CLK>; - clock-latency = <50000>; -}; - -&cpu102 { - cpu-supply = <&vddcpu_a>; - operating-points-v2 = <&cpub_opp_table_1>; - clocks = <&clkc CLKID_CPUB_CLK>; - clock-latency = <50000>; -}; - -&cpu103 { - cpu-supply = <&vddcpu_a>; - operating-points-v2 = <&cpub_opp_table_1>; - clocks = <&clkc CLKID_CPUB_CLK>; - clock-latency = <50000>; -}; - -&ext_mdio { - external_phy: ethernet-phy@0 { - /* Realtek RTL8211F (0x001cc916) */ - reg = <0>; - max-speed = <1000>; - - reset-assert-us = <10000>; - reset-deassert-us = <30000>; - reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; - - interrupt-parent = <&gpio_intc>; - /* MAC_INTR on GPIOZ_14 */ - interrupts = <26 IRQ_TYPE_LEVEL_LOW>; - }; -}; - -ðmac { - pinctrl-0 = <ð_pins>, <ð_rgmii_pins>; - pinctrl-names = "default"; - status = "okay"; - phy-mode = "rgmii"; - phy-handle = <&external_phy>; - amlogic,tx-delay-ns = <2>; -}; - -&frddr_a { - status = "okay"; -}; - -&frddr_b { - status = "okay"; -}; - -&frddr_c { - status = "okay"; -}; - -&gpio { - /* - * WARNING: The USB Hub on the Odroid-N2 needs a reset signal - * to be turned high in order to be detected by the USB Controller - * This signal should be handled by a USB specific power sequence - * in order to reset the Hub when USB bus is powered down. - */ - usb-hub { - gpio-hog; - gpios = <GPIOH_4 GPIO_ACTIVE_HIGH>; - output-high; - line-name = "usb-hub-reset"; - }; -}; - -&hdmi_tx { - status = "okay"; - pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>; - pinctrl-names = "default"; - hdmi-supply = <&vcc_5v>; -}; - -&hdmi_tx_tmds_port { - hdmi_tx_tmds_out: endpoint { - remote-endpoint = <&hdmi_connector_in>; - }; -}; - -&ir { - status = "okay"; - pinctrl-0 = <&remote_input_ao_pins>; - pinctrl-names = "default"; - linux,rc-map-name = "rc-odroid"; -}; - -&pwm_ab { - pinctrl-0 = <&pwm_a_e_pins>; - pinctrl-names = "default"; - clocks = <&xtal>; - clock-names = "clkin0"; - status = "okay"; -}; - -&pwm_AO_cd { - pinctrl-0 = <&pwm_ao_d_e_pins>; - pinctrl-names = "default"; - clocks = <&xtal>; - clock-names = "clkin1"; - status = "okay"; -}; - -/* SD card */ -&sd_emmc_b { - status = "okay"; - pinctrl-0 = <&sdcard_c_pins>; - pinctrl-1 = <&sdcard_clk_gate_c_pins>; - pinctrl-names = "default", "clk-gate"; - - bus-width = <4>; - cap-sd-highspeed; - max-frequency = <50000000>; - disable-wp; - - cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>; - vmmc-supply = <&tflash_vdd>; - vqmmc-supply = <&tf_io>; - -}; - -/* eMMC */ -&sd_emmc_c { - status = "okay"; - pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; - pinctrl-1 = <&emmc_clk_gate_pins>; - pinctrl-names = "default", "clk-gate"; - - bus-width = <8>; - cap-mmc-highspeed; - mmc-ddr-1_8v; - mmc-hs200-1_8v; - max-frequency = <200000000>; - disable-wp; - - mmc-pwrseq = <&emmc_pwrseq>; - vmmc-supply = <&vcc_3v3>; - vqmmc-supply = <&flash_1v8>; -}; - -/* - * EMMC_D4, EMMC_D5, EMMC_D6 and EMMC_D7 pins are shared between SPI NOR pins - * and eMMC Data 4 to 7 pins. - * Replace emmc_data_8b_pins to emmc_data_4b_pins from sd_emmc_c pinctrl-0, - * and change bus-width to 4 then spifc can be enabled. - * The SW1 slide should also be set to the correct position. - */ -&spifc { - status = "disabled"; - pinctrl-0 = <&nor_pins>; - pinctrl-names = "default"; - - mx25u64: spi-flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "mxicy,mx25u6435f", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <104000000>; - }; -}; - -&tdmif_b { - status = "okay"; -}; - -&tdmif_c { - status = "okay"; -}; - -&tdmin_a { - status = "okay"; -}; - -&tdmin_b { - status = "okay"; -}; - -&tdmin_c { - status = "okay"; -}; - -&tdmin_lb { - status = "okay"; -}; - -&tdmout_b { - status = "okay"; -}; - -&tdmout_c { - status = "okay"; -}; - -&toacodec { - status = "okay"; -}; - -&tohdmitx { - status = "okay"; -}; - -&toddr_a { - status = "okay"; -}; - -&toddr_b { - status = "okay"; -}; - -&toddr_c { - status = "okay"; -}; - -&uart_AO { - status = "okay"; - pinctrl-0 = <&uart_ao_a_pins>; - pinctrl-names = "default"; -}; - -&usb { - status = "okay"; - vbus-supply = <&usb_pwr_en>; -}; - -&usb2_phy0 { - phy-supply = <&vcc_5v>; -}; - -&usb2_phy1 { - /* Enable the hub which is connected to this port */ - phy-supply = <&hub_5v>; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi new file mode 100644 index 000000000000..6982632ae646 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi @@ -0,0 +1,625 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +#include <dt-bindings/input/input.h> +#include <dt-bindings/gpio/meson-g12a-gpio.h> +#include <dt-bindings/sound/meson-g12a-toacodec.h> +#include <dt-bindings/sound/meson-g12a-tohdmitx.h> + +/ { + aliases { + serial0 = &uart_AO; + ethernet0 = ðmac; + }; + + dioo2133: audio-amplifier-0 { + compatible = "simple-audio-amplifier"; + enable-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>; + VCC-supply = <&vcc_5v>; + sound-name-prefix = "U19"; + status = "okay"; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x40000000>; + }; + + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>; + }; + + leds { + compatible = "gpio-leds"; + + blue { + label = "n2:blue"; + gpios = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + tflash_vdd: regulator-tflash_vdd { + compatible = "regulator-fixed"; + + regulator-name = "TFLASH_VDD"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&gpio_ao GPIOAO_8 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + tf_io: gpio-regulator-tf_io { + compatible = "regulator-gpio"; + + regulator-name = "TF_IO"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>; + gpios-states = <0>; + + states = <3300000 0>, + <1800000 1>; + }; + + flash_1v8: regulator-flash_1v8 { + compatible = "regulator-fixed"; + regulator-name = "FLASH_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3>; + regulator-always-on; + }; + + main_12v: regulator-main_12v { + compatible = "regulator-fixed"; + regulator-name = "12V"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-always-on; + }; + + vcc_5v: regulator-vcc_5v { + compatible = "regulator-fixed"; + regulator-name = "5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + vin-supply = <&main_12v>; + }; + + vcc_1v8: regulator-vcc_1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3>; + regulator-always-on; + }; + + vcc_3v3: regulator-vcc_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vddao_3v3>; + regulator-always-on; + /* FIXME: actually controlled by VDDCPU_B_EN */ + }; + + vddcpu_a: regulator-vddcpu-a { + /* + * MP8756GD Regulator. + */ + compatible = "pwm-regulator"; + + regulator-name = "VDDCPU_A"; + regulator-min-microvolt = <721000>; + regulator-max-microvolt = <1022000>; + + vin-supply = <&main_12v>; + + pwms = <&pwm_ab 0 1250 0>; + pwm-dutycycle-range = <100 0>; + + regulator-boot-on; + regulator-always-on; + }; + + vddcpu_b: regulator-vddcpu-b { + /* + * Silergy SY8120B1ABC Regulator. + */ + compatible = "pwm-regulator"; + + regulator-name = "VDDCPU_B"; + regulator-min-microvolt = <721000>; + regulator-max-microvolt = <1022000>; + + vin-supply = <&main_12v>; + + pwms = <&pwm_AO_cd 1 1250 0>; + pwm-dutycycle-range = <100 0>; + + regulator-boot-on; + regulator-always-on; + }; + + hub_5v: regulator-hub_5v { + compatible = "regulator-fixed"; + regulator-name = "HUB_5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_5v>; + + /* Connected to the Hub CHIPENABLE, LOW sets low power state */ + gpio = <&gpio GPIOH_5 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + usb_pwr_en: regulator-usb_pwr_en { + compatible = "regulator-fixed"; + regulator-name = "USB_PWR_EN"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_5v>; + + /* Connected to the microUSB port power enable */ + gpio = <&gpio GPIOH_6 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vddao_1v8: regulator-vddao_1v8 { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vddao_3v3>; + regulator-always-on; + }; + + vddao_3v3: regulator-vddao_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&main_12v>; + regulator-always-on; + }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi_tx_tmds_out>; + }; + }; + }; + + sound { + compatible = "amlogic,axg-sound-card"; + model = "G12B-ODROID-N2"; + audio-widgets = "Line", "Lineout"; + audio-aux-devs = <&tdmout_b>, <&tdmout_c>, <&tdmin_a>, + <&tdmin_b>, <&tdmin_c>, <&tdmin_lb>, + <&dioo2133>; + audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", + "TDMOUT_B IN 1", "FRDDR_B OUT 1", + "TDMOUT_B IN 2", "FRDDR_C OUT 1", + "TDM_B Playback", "TDMOUT_B OUT", + "TDMOUT_C IN 0", "FRDDR_A OUT 2", + "TDMOUT_C IN 1", "FRDDR_B OUT 2", + "TDMOUT_C IN 2", "FRDDR_C OUT 2", + "TDM_C Playback", "TDMOUT_C OUT", + "TDMIN_A IN 4", "TDM_B Loopback", + "TDMIN_B IN 4", "TDM_B Loopback", + "TDMIN_C IN 4", "TDM_B Loopback", + "TDMIN_LB IN 1", "TDM_B Loopback", + "TDMIN_A IN 5", "TDM_C Loopback", + "TDMIN_B IN 5", "TDM_C Loopback", + "TDMIN_C IN 5", "TDM_C Loopback", + "TDMIN_LB IN 2", "TDM_C Loopback", + "TODDR_A IN 0", "TDMIN_A OUT", + "TODDR_B IN 0", "TDMIN_A OUT", + "TODDR_C IN 0", "TDMIN_A OUT", + "TODDR_A IN 1", "TDMIN_B OUT", + "TODDR_B IN 1", "TDMIN_B OUT", + "TODDR_C IN 1", "TDMIN_B OUT", + "TODDR_A IN 2", "TDMIN_C OUT", + "TODDR_B IN 2", "TDMIN_C OUT", + "TODDR_C IN 2", "TDMIN_C OUT", + "TODDR_A IN 6", "TDMIN_LB OUT", + "TODDR_B IN 6", "TDMIN_LB OUT", + "TODDR_C IN 6", "TDMIN_LB OUT", + "U19 INL", "ACODEC LOLP", + "U19 INR", "ACODEC LORP", + "Lineout", "U19 OUTL", + "Lineout", "U19 OUTR"; + + assigned-clocks = <&clkc CLKID_MPLL2>, + <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&frddr_a>; + }; + + dai-link-1 { + sound-dai = <&frddr_b>; + }; + + dai-link-2 { + sound-dai = <&frddr_c>; + }; + + dai-link-3 { + sound-dai = <&toddr_a>; + }; + + dai-link-4 { + sound-dai = <&toddr_b>; + }; + + dai-link-5 { + sound-dai = <&toddr_c>; + }; + + /* 8ch hdmi interface */ + dai-link-6 { + sound-dai = <&tdmif_b>; + dai-format = "i2s"; + dai-tdm-slot-tx-mask-0 = <1 1>; + dai-tdm-slot-tx-mask-1 = <1 1>; + dai-tdm-slot-tx-mask-2 = <1 1>; + dai-tdm-slot-tx-mask-3 = <1 1>; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>; + }; + + codec-1 { + sound-dai = <&toacodec TOACODEC_IN_B>; + }; + }; + + /* i2s jack output interface */ + dai-link-7 { + sound-dai = <&tdmif_c>; + dai-format = "i2s"; + dai-tdm-slot-tx-mask-0 = <1 1>; + mclk-fs = <256>; + + codec-0 { + sound-dai = <&tohdmitx TOHDMITX_I2S_IN_C>; + }; + + codec-1 { + sound-dai = <&toacodec TOACODEC_IN_C>; + }; + }; + + /* hdmi glue */ + dai-link-8 { + sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; + + codec { + sound-dai = <&hdmi_tx>; + }; + }; + + /* acodec glue */ + dai-link-9 { + sound-dai = <&toacodec TOACODEC_OUT>; + + codec { + sound-dai = <&acodec>; + }; + }; + }; +}; + +&acodec { + AVDD-supply = <&vddao_1v8>; + status = "okay"; +}; + +&arb { + status = "okay"; +}; + +&cec_AO { + pinctrl-0 = <&cec_ao_a_h_pins>; + pinctrl-names = "default"; + status = "disabled"; + hdmi-phandle = <&hdmi_tx>; +}; + +&cecb_AO { + pinctrl-0 = <&cec_ao_b_h_pins>; + pinctrl-names = "default"; + status = "okay"; + hdmi-phandle = <&hdmi_tx>; +}; + +&clkc_audio { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vddcpu_b>; + operating-points-v2 = <&cpu_opp_table_0>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu1 { + cpu-supply = <&vddcpu_b>; + operating-points-v2 = <&cpu_opp_table_0>; + clocks = <&clkc CLKID_CPU_CLK>; + clock-latency = <50000>; +}; + +&cpu100 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu101 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu102 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&cpu103 { + cpu-supply = <&vddcpu_a>; + operating-points-v2 = <&cpub_opp_table_1>; + clocks = <&clkc CLKID_CPUB_CLK>; + clock-latency = <50000>; +}; + +&ext_mdio { + external_phy: ethernet-phy@0 { + /* Realtek RTL8211F (0x001cc916) */ + reg = <0>; + max-speed = <1000>; + + reset-assert-us = <10000>; + reset-deassert-us = <30000>; + reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; + + interrupt-parent = <&gpio_intc>; + /* MAC_INTR on GPIOZ_14 */ + interrupts = <26 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +ðmac { + pinctrl-0 = <ð_pins>, <ð_rgmii_pins>; + pinctrl-names = "default"; + status = "okay"; + phy-mode = "rgmii"; + phy-handle = <&external_phy>; + amlogic,tx-delay-ns = <2>; +}; + +&frddr_a { + status = "okay"; +}; + +&frddr_b { + status = "okay"; +}; + +&frddr_c { + status = "okay"; +}; + +&gpio { + /* + * WARNING: The USB Hub on the Odroid-N2 needs a reset signal + * to be turned high in order to be detected by the USB Controller + * This signal should be handled by a USB specific power sequence + * in order to reset the Hub when USB bus is powered down. + */ + usb-hub { + gpio-hog; + gpios = <GPIOH_4 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "usb-hub-reset"; + }; +}; + +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>; + pinctrl-names = "default"; + hdmi-supply = <&vcc_5v>; +}; + +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; +}; + +&ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; + linux,rc-map-name = "rc-odroid"; +}; + +&pwm_ab { + pinctrl-0 = <&pwm_a_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin0"; + status = "okay"; +}; + +&pwm_AO_cd { + pinctrl-0 = <&pwm_ao_d_e_pins>; + pinctrl-names = "default"; + clocks = <&xtal>; + clock-names = "clkin1"; + status = "okay"; +}; + +/* SD card */ +&sd_emmc_b { + status = "okay"; + pinctrl-0 = <&sdcard_c_pins>; + pinctrl-1 = <&sdcard_clk_gate_c_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <4>; + cap-sd-highspeed; + max-frequency = <50000000>; + disable-wp; + + cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>; + vmmc-supply = <&tflash_vdd>; + vqmmc-supply = <&tf_io>; + +}; + +/* eMMC */ +&sd_emmc_c { + status = "okay"; + pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <8>; + cap-mmc-highspeed; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + max-frequency = <200000000>; + disable-wp; + + mmc-pwrseq = <&emmc_pwrseq>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&flash_1v8>; +}; + +/* + * EMMC_D4, EMMC_D5, EMMC_D6 and EMMC_D7 pins are shared between SPI NOR pins + * and eMMC Data 4 to 7 pins. + * Replace emmc_data_8b_pins to emmc_data_4b_pins from sd_emmc_c pinctrl-0, + * and change bus-width to 4 then spifc can be enabled. + * The SW1 slide should also be set to the correct position. + */ +&spifc { + status = "disabled"; + pinctrl-0 = <&nor_pins>; + pinctrl-names = "default"; + + mx25u64: spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mxicy,mx25u6435f", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <104000000>; + }; +}; + +&tdmif_b { + status = "okay"; +}; + +&tdmif_c { + status = "okay"; +}; + +&tdmin_a { + status = "okay"; +}; + +&tdmin_b { + status = "okay"; +}; + +&tdmin_c { + status = "okay"; +}; + +&tdmin_lb { + status = "okay"; +}; + +&tdmout_b { + status = "okay"; +}; + +&tdmout_c { + status = "okay"; +}; + +&toacodec { + status = "okay"; +}; + +&tohdmitx { + status = "okay"; +}; + +&toddr_a { + status = "okay"; +}; + +&toddr_b { + status = "okay"; +}; + +&toddr_c { + status = "okay"; +}; + +&uart_AO { + status = "okay"; + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; +}; + +&usb { + status = "okay"; + vbus-supply = <&usb_pwr_en>; +}; + +&usb2_phy0 { + phy-supply = <&vcc_5v>; +}; + +&usb2_phy1 { + /* Enable the hub which is connected to this port */ + phy-supply = <&hub_5v>; +}; 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 new file mode 100644 index 000000000000..675eaa87963e --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts @@ -0,0 +1,318 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 BayLibre, SAS. + * Author: Jerome Brunet <jbrunet@baylibre.com> + */ + +/dts-v1/; + +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/sound/meson-aiu.h> + +#include "meson-gxl-s905x.dtsi" + +/ { + compatible = "libretech,aml-s905x-cc-v2", "amlogic,s905x", + "amlogic,meson-gxl"; + model = "Libre Computer AML-S905X-CC V2"; + + aliases { + serial0 = &uart_AO; + ethernet0 = ðmac; + spi0 = &spifc; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>; + }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi_tx_tmds_out>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + led-blue { + color = <LED_COLOR_ID_BLUE>; + function = LED_FUNCTION_STATUS; + gpios = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + panic-indicator; + }; + + led-green { + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_DISK_ACTIVITY; + gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "disk-activity"; + }; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + ao_5v: regulator-ao_5v { + compatible = "regulator-fixed"; + regulator-name = "AO_5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_in>; + regulator-always-on; + }; + + dc_in: regulator-dc_in { + compatible = "regulator-fixed"; + regulator-name = "DC_IN"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + + vcck: regulator-vcck { + compatible = "regulator-fixed"; + regulator-name = "VCCK"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&ao_5v>; + regulator-always-on; + }; + + vcc_card: regulator-vcc_card { + compatible = "regulator-fixed"; + regulator-name = "VCC_CARD"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vddio_ao3v3>; + + gpio = <&gpio GPIOCLK_1 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vcc5v: regulator-vcc5v { + compatible = "regulator-fixed"; + regulator-name = "VCC5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&ao_5v>; + + gpio = <&gpio GPIOH_3 GPIO_OPEN_DRAIN>; + }; + + vddio_ao3v3: regulator-vddio_ao3v3 { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_AO3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&ao_5v>; + regulator-always-on; + }; + + + vddio_card: regulator-vddio-card { + compatible = "regulator-gpio"; + regulator-name = "VDDIO_CARD"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>; + gpios-states = <0>; + + states = <3300000 0>, + <1800000 1>; + + regulator-settling-time-up-us = <200>; + regulator-settling-time-down-us = <50000>; + }; + + vddio_ao18: regulator-vddio_ao18 { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_AO18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vddio_ao3v3>; + regulator-always-on; + }; + + vcc_1v8: regulator-vcc_1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC 1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vddio_ao3v3>; + regulator-always-on; + }; + + sound { + compatible = "amlogic,gx-sound-card"; + model = "GXL-LIBRETECH-S905X-CC-V2"; + 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 { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + + +ðmac { + status = "okay"; +}; + +&internal_phy { + pinctrl-0 = <ð_link_led_pins>, <ð_act_led_pins>; + pinctrl-names = "default"; +}; + +&ir { + status = "okay"; + pinctrl-0 = <&remote_input_ao_pins>; + pinctrl-names = "default"; +}; + +&hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; + hdmi-supply = <&vcc5v>; + pinctrl-names = "default"; +}; + +&hdmi_tx_tmds_port { + hdmi_tx_tmds_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; +}; + +&saradc { + status = "okay"; + vref-supply = <&vddio_ao18>; +}; + +/* SD card */ +&sd_emmc_b { + pinctrl-0 = <&sdcard_pins>; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <4>; + cap-sd-highspeed; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-ddr50; + max-frequency = <100000000>; + disable-wp; + + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vcc_card>; + vqmmc-supply = <&vddio_card>; + + status = "okay"; +}; + +/* eMMC */ +&sd_emmc_c { + pinctrl-0 = <&emmc_pins>; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + max-frequency = <200000000>; + disable-wp; + + mmc-pwrseq = <&emmc_pwrseq>; + vmmc-supply = <&vddio_ao3v3>; + vqmmc-supply = <&vcc_1v8>; + + status = "okay"; +}; + +&spifc { + status = "okay"; + pinctrl-0 = <&nor_pins>; + pinctrl-names = "default"; + + nor_4u1: spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <3000000>; + }; +}; + +&uart_AO { + status = "okay"; + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; +}; + +&usb { + status = "okay"; + dr_mode = "host"; +}; + +&usb2_phy0 { + pinctrl-names = "default"; + phy-supply = <&vcc5v>; +}; + +&usb2_phy1 { + phy-supply = <&vcc5v>; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi index 94f75b446504..7b46555ac55a 100644 --- a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi @@ -7,6 +7,7 @@ #include <dt-bindings/input/input.h> #include <dt-bindings/gpio/meson-g12a-gpio.h> +#include <dt-bindings/sound/meson-g12a-tohdmitx.h> / { aliases { @@ -41,13 +42,13 @@ led-white { label = "vim3:white:sys"; - gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>; + gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; }; led-red { label = "vim3:red"; - gpios = <&gpio_expander 5 GPIO_ACTIVE_LOW>; + gpios = <&gpio_expander 5 GPIO_ACTIVE_HIGH>; }; }; @@ -161,6 +162,62 @@ }; }; + + sound { + compatible = "amlogic,axg-sound-card"; + model = "G12B-KHADAS-VIM3"; + audio-aux-devs = <&tdmout_a>; + audio-routing = "TDMOUT_A IN 0", "FRDDR_A OUT 0", + "TDMOUT_A IN 1", "FRDDR_B OUT 0", + "TDMOUT_A IN 2", "FRDDR_C OUT 0", + "TDM_A Playback", "TDMOUT_A OUT"; + + assigned-clocks = <&clkc CLKID_MPLL2>, + <&clkc CLKID_MPLL0>, + <&clkc CLKID_MPLL1>; + assigned-clock-parents = <0>, <0>, <0>; + assigned-clock-rates = <294912000>, + <270950400>, + <393216000>; + status = "okay"; + + dai-link-0 { + sound-dai = <&frddr_a>; + }; + + dai-link-1 { + sound-dai = <&frddr_b>; + }; + + dai-link-2 { + sound-dai = <&frddr_c>; + }; + + /* 8ch hdmi interface */ + dai-link-3 { + sound-dai = <&tdmif_a>; + dai-format = "i2s"; + dai-tdm-slot-tx-mask-0 = <1 1>; + dai-tdm-slot-tx-mask-1 = <1 1>; + dai-tdm-slot-tx-mask-2 = <1 1>; + dai-tdm-slot-tx-mask-3 = <1 1>; + mclk-fs = <256>; + + codec { + sound-dai = <&tohdmitx TOHDMITX_I2S_IN_A>; + }; + }; + + /* hdmi glue */ + dai-link-4 { + sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; + + codec { + sound-dai = <&hdmi_tx>; + }; + }; + }; + wifi32k: wifi32k { compatible = "pwm-clock"; #clock-cells = <0>; @@ -169,6 +226,14 @@ }; }; +&arb { + status = "okay"; +}; + +&clkc_audio { + status = "okay"; +}; + &cec_AO { pinctrl-0 = <&cec_ao_a_h_pins>; pinctrl-names = "default"; @@ -221,6 +286,18 @@ amlogic,tx-delay-ns = <2>; }; +&frddr_a { + status = "okay"; +}; + +&frddr_b { + status = "okay"; +}; + +&frddr_c { + status = "okay"; +}; + &hdmi_tx { status = "okay"; pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>; @@ -368,6 +445,19 @@ }; }; + +&tdmif_a { + status = "okay"; +}; + +&tdmout_a { + status = "okay"; +}; + +&tohdmitx { + status = "okay"; +}; + &uart_A { status = "okay"; pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>; diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts index 0da56c051a0e..4b517ca72059 100644 --- a/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts @@ -32,69 +32,6 @@ regulator-boot-on; regulator-always-on; }; - - sound { - compatible = "amlogic,axg-sound-card"; - model = "SM1-KHADAS-VIM3L"; - audio-aux-devs = <&tdmout_a>; - audio-routing = "TDMOUT_A IN 0", "FRDDR_A OUT 0", - "TDMOUT_A IN 1", "FRDDR_B OUT 0", - "TDMOUT_A IN 2", "FRDDR_C OUT 0", - "TDM_A Playback", "TDMOUT_A OUT"; - - assigned-clocks = <&clkc CLKID_MPLL2>, - <&clkc CLKID_MPLL0>, - <&clkc CLKID_MPLL1>; - assigned-clock-parents = <0>, <0>, <0>; - assigned-clock-rates = <294912000>, - <270950400>, - <393216000>; - status = "okay"; - - dai-link-0 { - sound-dai = <&frddr_a>; - }; - - dai-link-1 { - sound-dai = <&frddr_b>; - }; - - dai-link-2 { - sound-dai = <&frddr_c>; - }; - - /* 8ch hdmi interface */ - dai-link-3 { - sound-dai = <&tdmif_a>; - dai-format = "i2s"; - dai-tdm-slot-tx-mask-0 = <1 1>; - dai-tdm-slot-tx-mask-1 = <1 1>; - dai-tdm-slot-tx-mask-2 = <1 1>; - dai-tdm-slot-tx-mask-3 = <1 1>; - mclk-fs = <256>; - - codec { - sound-dai = <&tohdmitx TOHDMITX_I2S_IN_A>; - }; - }; - - /* hdmi glue */ - dai-link-4 { - sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>; - - codec { - sound-dai = <&hdmi_tx>; - }; - }; - }; -}; - -&arb { - status = "okay"; -}; - -&clkc_audio { - status = "okay"; }; &cpu0 { @@ -125,18 +62,6 @@ clock-latency = <50000>; }; -&frddr_a { - status = "okay"; -}; - -&frddr_b { - status = "okay"; -}; - -&frddr_c { - status = "okay"; -}; - &pwm_AO_cd { pinctrl-0 = <&pwm_ao_d_e_pins>; pinctrl-names = "default"; @@ -174,14 +99,3 @@ }; */ -&tdmif_a { - status = "okay"; -}; - -&tdmout_a { - status = "okay"; -}; - -&tohdmitx { - status = "okay"; -}; diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi index 3feb1881bbc2..a83c82c50e29 100644 --- a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi +++ b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi @@ -709,13 +709,13 @@ dwgpio: gpio@1c024000 { compatible = "snps,dw-apb-gpio"; reg = <0x0 0x1c024000 0x0 0x1000>; - reg-io-width = <4>; #address-cells = <1>; #size-cells = <0>; porta: gpio-controller@0 { compatible = "snps,dw-apb-gpio-port"; gpio-controller; + #gpio-cells = <2>; snps,nr-gpios = <32>; reg = <0>; }; diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi index 8c802d87e751..0f37e77f5459 100644 --- a/arch/arm64/boot/dts/apm/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi @@ -825,13 +825,13 @@ dwgpio: gpio@1c024000 { compatible = "snps,dw-apb-gpio"; reg = <0x0 0x1c024000 0x0 0x1000>; - reg-io-width = <4>; #address-cells = <1>; #size-cells = <0>; porta: gpio-controller@0 { compatible = "snps,dw-apb-gpio-port"; gpio-controller; + #gpio-cells = <2>; snps,nr-gpios = <32>; reg = <0>; }; diff --git a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi index eeee51f1251b..40d95c58b55e 100644 --- a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi +++ b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi @@ -251,7 +251,7 @@ reg = <0x0f0000 0x10000>; interrupts = <7>; clocks = <&mb_clk24mhz>, <&soc_smc50mhz>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; }; v2m_timer01: timer@110000 { diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi index 001a0a3c7f66..4c4a381d2c75 100644 --- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi +++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi @@ -195,7 +195,7 @@ reg = <0x0f0000 0x1000>; interrupts = <0>; clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; }; v2m_timer01: timer@110000 { diff --git a/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi index 15f7b0ed3836..2cfeaf3b0a87 100644 --- a/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi +++ b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi @@ -576,7 +576,7 @@ reg = <0x66090000 0x1000>; interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>; clocks = <&iprocslow>, <&iprocslow>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; }; gpio_g: gpio@660a0000 { @@ -745,7 +745,7 @@ }; qspi: spi@66470200 { - compatible = "brcm,spi-bcm-qspi", "brcm,spi-ns2-qspi"; + compatible = "brcm,spi-ns2-qspi", "brcm,spi-bcm-qspi"; reg = <0x66470200 0x184>, <0x66470000 0x124>, <0x67017408 0x004>, diff --git a/arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi b/arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi index a9b92e52d50e..43aa5e9c0020 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi +++ b/arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi @@ -151,7 +151,7 @@ }; &nand { - status = "ok"; + status = "okay"; nandcs@0 { compatible = "brcm,nandcs"; reg = <0>; diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi index 0098dfdef96c..b425b12c3ed2 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi +++ b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi @@ -438,7 +438,7 @@ reg = <0x000c0000 0x1000>; interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>; clocks = <&hsls_25m_div2_clk>, <&hsls_div4_clk>; - clock-names = "wdogclk", "apb_pclk"; + clock-names = "wdog_clk", "apb_pclk"; timeout-sec = <60>; }; diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi index 250fc01de78d..829fea23d4ab 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi @@ -87,8 +87,8 @@ i2c_max98504: i2c-gpio-0 { compatible = "i2c-gpio"; - gpios = <&gpd0 1 GPIO_ACTIVE_HIGH /* SPK_AMP_SDA */ - &gpd0 0 GPIO_ACTIVE_HIGH /* SPK_AMP_SCL */ >; + sda-gpios = <&gpd0 1 GPIO_ACTIVE_HIGH>; + scl-gpios = <&gpd0 0 GPIO_ACTIVE_HIGH>; i2c-gpio,delay-us = <2>; #address-cells = <1>; #size-cells = <0>; @@ -795,8 +795,8 @@ reg = <0x27>; interrupt-parent = <&gpa1>; interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; - s3fwrn5,en-gpios = <&gpf1 4 GPIO_ACTIVE_HIGH>; - s3fwrn5,fw-gpios = <&gpj0 2 GPIO_ACTIVE_HIGH>; + en-gpios = <&gpf1 4 GPIO_ACTIVE_HIGH>; + wake-gpios = <&gpj0 2 GPIO_ACTIVE_HIGH>; }; }; diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index 74ac4ac75865..8eb4576da8f3 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi @@ -1015,17 +1015,17 @@ }; syscon_disp: syscon@13b80000 { - compatible = "syscon"; + compatible = "samsung,exynos5433-sysreg", "syscon"; reg = <0x13b80000 0x1010>; }; syscon_cam0: syscon@120f0000 { - compatible = "syscon"; + compatible = "samsung,exynos5433-sysreg", "syscon"; reg = <0x120f0000 0x1020>; }; syscon_cam1: syscon@145f0000 { - compatible = "syscon"; + compatible = "samsung,exynos5433-sysreg", "syscon"; reg = <0x145f0000 0x1038>; }; @@ -1087,7 +1087,7 @@ operating-points-v2 = <&gpu_opp_table>; status = "disabled"; - gpu_opp_table: opp_table { + gpu_opp_table: opp-table { compatible = "operating-points-v2"; opp-160000000 { @@ -1460,10 +1460,6 @@ <&cmu_peric CLK_SCLK_I2S1>; clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; #clock-cells = <1>; - samsung,supports-6ch; - samsung,supports-rstclr; - samsung,supports-tdm; - samsung,supports-low-rfs; #sound-dai-cells = <1>; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile index a39f0a1723e0..f8d59433af01 100644 --- a/arch/arm64/boot/dts/freescale/Makefile +++ b/arch/arm64/boot/dts/freescale/Makefile @@ -28,13 +28,19 @@ 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_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-var-som-symphony.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mn-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mn-ddr4-evk.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mn-var-som-symphony.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mq-hummingboard-pulse.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mq-librem5-devkit.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mq-librem5-r2.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mq-librem5-r3.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mq-nitrogen.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mq-phanbell.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mq-pico-pi.dtb diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a-oxalis.dts b/arch/arm64/boot/dts/freescale/fsl-ls1012a-oxalis.dts index 9927b096d343..242f4b0cb344 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-oxalis.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-oxalis.dts @@ -87,7 +87,7 @@ status = "okay"; }; -&pcie { +&pcie1 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi index ff19ec415b60..6a2c09199047 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi @@ -1,8 +1,9 @@ // SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* - * Device Tree Include file for Freescale Layerscape-1012A family SoC. + * Device Tree Include file for NXP Layerscape-1012A family SoC. * * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2019-2020 NXP * */ @@ -489,7 +490,7 @@ interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>; }; - pcie: pcie@3400000 { + pcie1: pcie@3400000 { compatible = "fsl,ls1012a-pcie"; reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ 0x40 0x00000000 0x0 0x00002000>; /* configuration space */ diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-kbox-a-230-ls.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-kbox-a-230-ls.dts index 4b4cc6a1573d..d66d8b2c3d1a 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-kbox-a-230-ls.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-kbox-a-230-ls.dts @@ -11,11 +11,29 @@ /dts-v1/; #include "fsl-ls1028a-kontron-sl28-var4.dts" +#include <dt-bindings/leds/common.h> / { model = "Kontron KBox A-230-LS"; compatible = "kontron,kbox-a-230-ls", "kontron,sl28-var4", "kontron,sl28", "fsl,ls1028a"; + + leds { + compatible = "gpio-leds"; + + alarm-led { + function = LED_FUNCTION_ALARM; + color = <LED_COLOR_ID_YELLOW>; + gpios = <&sl28cpld_gpio0 0 GPIO_ACTIVE_HIGH>; + }; + + power-led { + linux,default-trigger = "default-on"; + function = LED_FUNCTION_POWER; + color = <LED_COLOR_ID_GREEN>; + gpios = <&sl28cpld_gpio1 3 GPIO_ACTIVE_HIGH>; + }; + }; }; &enetc_mdio_pf3 { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts index 0973a6a45217..c45d7b40e374 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts @@ -15,6 +15,15 @@ compatible = "kontron,sl28-var3-ads2", "kontron,sl28-var3", "kontron,sl28", "fsl,ls1028a"; + pwm-fan { + compatible = "pwm-fan"; + cooling-min-state = <0>; + cooling-max-state = <3>; + #cooling-cells = <2>; + pwms = <&sl28cpld_pwm0 0 4000000>; + cooling-levels = <1 128 192 255>; + }; + sound { #address-cells = <1>; #size-cells = <0>; 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 852dad8d70ab..f46eb47cfa4d 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts @@ -8,6 +8,9 @@ /dts-v1/; #include "fsl-ls1028a.dtsi" +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> / { model = "Kontron SMARC-sAL28"; @@ -22,6 +25,36 @@ spi1 = &dspi2; }; + buttons0 { + compatible = "gpio-keys"; + + power-button { + interrupts-extended = <&sl28cpld_intc + 4 IRQ_TYPE_EDGE_BOTH>; + linux,code = <KEY_POWER>; + label = "Power"; + }; + + sleep-button { + interrupts-extended = <&sl28cpld_intc + 5 IRQ_TYPE_EDGE_BOTH>; + linux,code = <KEY_SLEEP>; + label = "Sleep"; + }; + }; + + buttons1 { + compatible = "gpio-keys-polled"; + poll-interval = <200>; + + lid-switch { + linux,input-type = <EV_SW>; + linux,code = <SW_LID>; + gpios = <&sl28cpld_gpio3 4 GPIO_ACTIVE_LOW>; + label = "Lid"; + }; + }; + chosen { stdout-path = "serial0:115200n8"; }; @@ -166,6 +199,107 @@ reg = <0x32>; }; + sl28cpld@4a { + compatible = "kontron,sl28cpld"; + reg = <0x4a>; + #address-cells = <1>; + #size-cells = <0>; + + watchdog@4 { + compatible = "kontron,sl28cpld-wdt"; + reg = <0x4>; + kontron,assert-wdt-timeout-pin; + }; + + hwmon@b { + compatible = "kontron,sl28cpld-fan"; + reg = <0xb>; + }; + + sl28cpld_pwm0: pwm@c { + compatible = "kontron,sl28cpld-pwm"; + reg = <0xc>; + #pwm-cells = <2>; + }; + + sl28cpld_pwm1: pwm@e { + compatible = "kontron,sl28cpld-pwm"; + reg = <0xe>; + #pwm-cells = <2>; + }; + + sl28cpld_gpio0: gpio@10 { + compatible = "kontron,sl28cpld-gpio"; + reg = <0x10>; + interrupts-extended = <&gpio2 6 + IRQ_TYPE_EDGE_FALLING>; + + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "GPIO0_CAM0_PWR_N", "GPIO1_CAM1_PWR_N", + "GPIO2_CAM0_RST_N", "GPIO3_CAM1_RST_N", + "GPIO4_HDA_RST_N", "GPIO5_PWM_OUT", + "GPIO6_TACHIN", "GPIO7"; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + sl28cpld_gpio1: gpio@15 { + compatible = "kontron,sl28cpld-gpio"; + reg = <0x15>; + interrupts-extended = <&gpio2 6 + IRQ_TYPE_EDGE_FALLING>; + + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "GPIO8", "GPIO9", "GPIO10", "GPIO11", + "", "", "", ""; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + sl28cpld_gpio2: gpio@1a { + compatible = "kontron,sl28cpld-gpo"; + reg = <0x1a>; + + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "LCD0 voltage enable", + "LCD0 backlight enable", + "eMMC reset", "LVDS bridge reset", + "LVDS bridge power-down", + "SDIO power enable", + "", ""; + }; + + sl28cpld_gpio3: gpio@1b { + compatible = "kontron,sl28cpld-gpi"; + reg = <0x1b>; + + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = + "Power button", "Force recovery", "Sleep", + "Battery low", "Lid state", "Charging", + "Charger present", ""; + }; + + sl28cpld_intc: interrupt-controller@1c { + compatible = "kontron,sl28cpld-intc"; + reg = <0x1c>; + interrupts-extended = <&gpio2 6 + IRQ_TYPE_EDGE_FALLING>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + eeprom@50 { compatible = "atmel,24c32"; reg = <0x50>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts index e4f00c2b6608..13cdc958ba3e 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts @@ -313,6 +313,10 @@ status = "okay"; }; +&lpuart0 { + status = "okay"; +}; + &sai1 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts index c2dc1232f93f..1efb61cff454 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts @@ -199,6 +199,7 @@ &enetc_port0 { phy-handle = <&sgmii_phy0>; phy-connection-type = "sgmii"; + managed = "in-band-status"; status = "okay"; mdio { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi index 0efeb8fa773e..73e4f9466887 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi @@ -2,7 +2,7 @@ /* * Device Tree Include file for NXP Layerscape-1028A family SoC. * - * Copyright 2018 NXP + * Copyright 2018-2020 NXP * * Harninder Rai <harninder.rai@nxp.com> * @@ -553,7 +553,7 @@ status = "disabled"; }; - pcie@3400000 { + pcie1: pcie@3400000 { compatible = "fsl,ls1028a-pcie"; reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ 0x80 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -580,7 +580,7 @@ status = "disabled"; }; - pcie@3500000 { + pcie2: pcie@3500000 { compatible = "fsl,ls1028a-pcie"; reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ 0x88 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -722,14 +722,14 @@ compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc000000 0x0 0x1000>; clocks = <&clockgen 4 15>, <&clockgen 4 15>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster1_core1_watchdog: watchdog@c010000 { compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc010000 0x0 0x1000>; clocks = <&clockgen 4 15>, <&clockgen 4 15>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; sai1: audio-controller@f100000 { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi index 5c2e370f6316..0464b8aa4bc4 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi @@ -1,9 +1,9 @@ // SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* - * Device Tree Include file for Freescale Layerscape-1043A family SoC. + * Device Tree Include file for NXP Layerscape-1043A family SoC. * * Copyright 2014-2015 Freescale Semiconductor, Inc. - * Copyright 2018 NXP + * Copyright 2018, 2020 NXP * * Mingkai Hu <Mingkai.hu@freescale.com> */ @@ -814,7 +814,7 @@ interrupts = <0 160 0x4>; }; - pcie@3400000 { + pcie1: pcie@3400000 { compatible = "fsl,ls1043a-pcie"; reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ 0x40 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -840,7 +840,7 @@ status = "disabled"; }; - pcie@3500000 { + pcie2: pcie@3500000 { compatible = "fsl,ls1043a-pcie"; reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ 0x48 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -866,7 +866,7 @@ status = "disabled"; }; - pcie@3600000 { + pcie3: pcie@3600000 { compatible = "fsl,ls1043a-pcie"; reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */ 0x50 0x00000000 0x0 0x00002000>; /* configuration space */ diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi index 0246d975a206..1fa39bacff4b 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi @@ -1,9 +1,9 @@ // SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* - * Device Tree Include file for Freescale Layerscape-1046A family SoC. + * Device Tree Include file for NXP Layerscape-1046A family SoC. * * Copyright 2016 Freescale Semiconductor, Inc. - * Copyright 2018 NXP + * Copyright 2018, 2020 NXP * * Mingkai Hu <mingkai.hu@nxp.com> */ @@ -718,7 +718,7 @@ <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>; }; - pcie@3400000 { + pcie1: pcie@3400000 { compatible = "fsl,ls1046a-pcie"; reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ 0x40 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -744,7 +744,7 @@ status = "disabled"; }; - pcie_ep@3400000 { + pcie_ep1: pcie_ep@3400000 { compatible = "fsl,ls1046a-pcie-ep","fsl,ls-pcie-ep"; reg = <0x00 0x03400000 0x0 0x00100000 0x40 0x00000000 0x8 0x00000000>; @@ -754,7 +754,7 @@ status = "disabled"; }; - pcie@3500000 { + pcie2: pcie@3500000 { compatible = "fsl,ls1046a-pcie"; reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ 0x48 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -780,7 +780,7 @@ status = "disabled"; }; - pcie_ep@3500000 { + pcie_ep2: pcie_ep@3500000 { compatible = "fsl,ls1046a-pcie-ep","fsl,ls-pcie-ep"; reg = <0x00 0x03500000 0x0 0x00100000 0x48 0x00000000 0x8 0x00000000>; @@ -790,7 +790,7 @@ status = "disabled"; }; - pcie@3600000 { + pcie3: pcie@3600000 { compatible = "fsl,ls1046a-pcie"; reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */ 0x50 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -816,7 +816,7 @@ status = "disabled"; }; - pcie_ep@3600000 { + pcie_ep3: pcie_ep@3600000 { compatible = "fsl,ls1046a-pcie-ep", "fsl,ls-pcie-ep"; reg = <0x00 0x03600000 0x0 0x00100000 0x50 0x00000000 0x8 0x00000000>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi index 169f4742ae3b..ff5805206a28 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi @@ -2,7 +2,7 @@ /* * Device Tree Include file for NXP Layerscape-1088A family SoC. * - * Copyright 2017 NXP + * Copyright 2017-2020 NXP * * Harninder Rai <harninder.rai@nxp.com> * @@ -130,19 +130,19 @@ }; thermal-zones { - cpu_thermal: cpu-thermal { + core-cluster { polling-delay-passive = <1000>; polling-delay = <5000>; thermal-sensors = <&tmu 0>; trips { - cpu_alert: cpu-alert { + core_cluster_alert: core-cluster-alert { temperature = <85000>; hysteresis = <2000>; type = "passive"; }; - cpu_crit: cpu-crit { + core-cluster-crit { temperature = <95000>; hysteresis = <2000>; type = "critical"; @@ -151,7 +151,7 @@ cooling-maps { map0 { - trip = <&cpu_alert>; + trip = <&core_cluster_alert>; cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, @@ -164,6 +164,20 @@ }; }; }; + + soc { + polling-delay-passive = <1000>; + polling-delay = <5000>; + thermal-sensors = <&tmu 1>; + + trips { + soc-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; }; timer { @@ -210,45 +224,49 @@ compatible = "fsl,qoriq-tmu"; reg = <0x0 0x1f80000 0x0 0x10000>; interrupts = <0 23 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 0x0000002a + 0x00000002 0x00000030 + 0x00000003 0x00000037 + 0x00000004 0x0000003d + 0x00000005 0x00000044 + 0x00000006 0x0000004a + 0x00000007 0x00000051 + 0x00000008 0x00000057 + 0x00000009 0x0000005e + 0x0000000a 0x00000064 + 0x0000000b 0x0000006b /* 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 0x00000040 + 0x00020004 0x0000004a + 0x00020005 0x00000054 + 0x00020006 0x0000005e /* Calibration data group 4 */ - 0x00030000 0x00000021 - 0x00030001 0x0000002a - 0x00030002 0x0000003c - 0x00030003 0x0000004e>; + 0x00030000 0x00000010 + 0x00030001 0x0000001c + 0x00030002 0x00000027 + 0x00030003 0x00000032 + 0x00030004 0x0000003e + 0x00030005 0x00000049 + 0x00030006 0x00000054 + 0x00030007 0x00000060>; little-endian; #thermal-sensor-cells = <1>; }; @@ -473,7 +491,7 @@ }; }; - pcie@3400000 { + pcie1: pcie@3400000 { compatible = "fsl,ls1088a-pcie"; reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ 0x20 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -499,7 +517,7 @@ status = "disabled"; }; - pcie@3500000 { + pcie2: pcie@3500000 { compatible = "fsl,ls1088a-pcie"; reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ 0x28 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -525,7 +543,7 @@ status = "disabled"; }; - pcie@3600000 { + pcie3: pcie@3600000 { compatible = "fsl,ls1088a-pcie"; reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */ 0x30 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -657,57 +675,57 @@ cluster1_core0_watchdog: wdt@c000000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc000000 0x0 0x1000>; - clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clocks = <&clockgen 4 15>, <&clockgen 4 15>; + clock-names = "wdog_clk", "apb_pclk"; }; cluster1_core1_watchdog: wdt@c010000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc010000 0x0 0x1000>; - clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clocks = <&clockgen 4 15>, <&clockgen 4 15>; + clock-names = "wdog_clk", "apb_pclk"; }; cluster1_core2_watchdog: wdt@c020000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc020000 0x0 0x1000>; - clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clocks = <&clockgen 4 15>, <&clockgen 4 15>; + clock-names = "wdog_clk", "apb_pclk"; }; cluster1_core3_watchdog: wdt@c030000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc030000 0x0 0x1000>; - clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clocks = <&clockgen 4 15>, <&clockgen 4 15>; + clock-names = "wdog_clk", "apb_pclk"; }; cluster2_core0_watchdog: wdt@c100000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc100000 0x0 0x1000>; - clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clocks = <&clockgen 4 15>, <&clockgen 4 15>; + clock-names = "wdog_clk", "apb_pclk"; }; cluster2_core1_watchdog: wdt@c110000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc110000 0x0 0x1000>; - clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clocks = <&clockgen 4 15>, <&clockgen 4 15>; + clock-names = "wdog_clk", "apb_pclk"; }; cluster2_core2_watchdog: wdt@c120000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc120000 0x0 0x1000>; - clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clocks = <&clockgen 4 15>, <&clockgen 4 15>; + clock-names = "wdog_clk", "apb_pclk"; }; cluster2_core3_watchdog: wdt@c130000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc130000 0x0 0x1000>; - clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clocks = <&clockgen 4 15>, <&clockgen 4 15>; + clock-names = "wdog_clk", "apb_pclk"; }; fsl_mc: fsl-mc@80c000000 { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index 41102dacc2e1..bf72918fe545 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -79,20 +79,62 @@ }; thermal-zones { - cpu_thermal: cpu-thermal { + ddr-controller1 { polling-delay-passive = <1000>; polling-delay = <5000>; + thermal-sensors = <&tmu 1>; + trips { + ddr-ctrler1-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + ddr-controller2 { + polling-delay-passive = <1000>; + polling-delay = <5000>; + thermal-sensors = <&tmu 2>; + + trips { + ddr-ctrler2-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + ddr-controller3 { + polling-delay-passive = <1000>; + polling-delay = <5000>; + thermal-sensors = <&tmu 3>; + + trips { + ddr-ctrler3-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + core-cluster1 { + polling-delay-passive = <1000>; + polling-delay = <5000>; thermal-sensors = <&tmu 4>; trips { - cpu_alert: cpu-alert { - temperature = <75000>; + core_cluster1_alert: core-cluster1-alert { + temperature = <85000>; hysteresis = <2000>; type = "passive"; }; - cpu_crit: cpu-crit { - temperature = <85000>; + + core-cluster1-crit { + temperature = <95000>; hysteresis = <2000>; type = "critical"; }; @@ -100,14 +142,95 @@ cooling-maps { map0 { - trip = <&cpu_alert>; + trip = <&core_cluster1_alert>; cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + core-cluster2 { + polling-delay-passive = <1000>; + polling-delay = <5000>; + thermal-sensors = <&tmu 5>; + + trips { + core_cluster2_alert: core-cluster2-alert { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + + core-cluster2-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&core_cluster2_alert>; + cooling-device = <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + core-cluster3 { + polling-delay-passive = <1000>; + polling-delay = <5000>; + thermal-sensors = <&tmu 6>; + + trips { + core_cluster3_alert: core-cluster3-alert { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + + core-cluster3-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&core_cluster3_alert>; + cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + core-cluster4 { + polling-delay-passive = <1000>; + polling-delay = <5000>; + thermal-sensors = <&tmu 7>; + + trips { + core_cluster4_alert: core-cluster4-alert { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + + core-cluster4-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&core_cluster4_alert>; + cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; }; @@ -231,56 +354,56 @@ compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc000000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster1_core1_watchdog: wdt@c010000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc010000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster2_core0_watchdog: wdt@c100000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc100000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster2_core1_watchdog: wdt@c110000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc110000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster3_core0_watchdog: wdt@c200000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc200000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster3_core1_watchdog: wdt@c210000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc210000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster4_core0_watchdog: wdt@c300000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc300000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster4_core1_watchdog: wdt@c310000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xc310000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; crypto: crypto@8000000 { diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi index d247e4228d60..83072da6f6c6 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi @@ -1011,7 +1011,7 @@ status = "disabled"; }; - pcie@3400000 { + pcie1: pcie@3400000 { compatible = "fsl,lx2160a-pcie"; reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ 0x80 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -1039,7 +1039,7 @@ status = "disabled"; }; - pcie@3500000 { + pcie2: pcie@3500000 { compatible = "fsl,lx2160a-pcie"; reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ 0x88 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -1067,7 +1067,7 @@ status = "disabled"; }; - pcie@3600000 { + pcie3: pcie@3600000 { compatible = "fsl,lx2160a-pcie"; reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */ 0x90 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -1095,7 +1095,7 @@ status = "disabled"; }; - pcie@3700000 { + pcie4: pcie@3700000 { compatible = "fsl,lx2160a-pcie"; reg = <0x00 0x03700000 0x0 0x00100000 /* controller registers */ 0x98 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -1123,7 +1123,7 @@ status = "disabled"; }; - pcie@3800000 { + pcie5: pcie@3800000 { compatible = "fsl,lx2160a-pcie"; reg = <0x00 0x03800000 0x0 0x00100000 /* controller registers */ 0xa0 0x00000000 0x0 0x00002000>; /* configuration space */ @@ -1151,7 +1151,7 @@ status = "disabled"; }; - pcie@3900000 { + pcie6: pcie@3900000 { compatible = "fsl,lx2160a-pcie"; reg = <0x00 0x03900000 0x0 0x00100000 /* controller registers */ 0xa8 0x00000000 0x0 0x00002000>; /* configuration space */ diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi index baa5f997d018..d6b9dedd168f 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi @@ -10,19 +10,19 @@ led0 { label = "gen_led0"; gpios = <&pca6416_1 4 GPIO_ACTIVE_HIGH>; - default-state = "none"; + default-state = "off"; }; led1 { label = "gen_led1"; gpios = <&pca6416_1 5 GPIO_ACTIVE_HIGH>; - default-state = "none"; + default-state = "off"; }; led2 { label = "gen_led2"; gpios = <&pca6416_1 6 GPIO_ACTIVE_HIGH>; - default-state = "none"; + default-state = "off"; }; led3 { @@ -70,7 +70,7 @@ &ecspi2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_espi2>; - cs-gpios = <&gpio5 9 0>; + cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; status = "okay"; eeprom@0 { @@ -210,7 +210,7 @@ >; }; - pinctrl_pcal6414: pcal6414-gpio { + pinctrl_pcal6414: pcal6414-gpiogrp { fsl,pins = < MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x19 >; @@ -240,7 +240,7 @@ >; }; - pinctrl_usdhc2_gpio: usdhc2grpgpio { + pinctrl_usdhc2_gpio: usdhc2gpiogrp { fsl,pins = < MX8MM_IOMUXC_SD2_CD_B_USDHC2_CD_B 0x41 MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 @@ -259,7 +259,7 @@ >; }; - pinctrl_usdhc2_100mhz: usdhc2grp100mhz { + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { fsl,pins = < MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194 MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4 @@ -271,7 +271,7 @@ >; }; - pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { fsl,pins = < MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196 MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6 diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi index 94911b1707ef..6de86a4f0ec4 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi @@ -74,12 +74,12 @@ reg = <0x4b>; pinctrl-0 = <&pinctrl_pmic>; interrupt-parent = <&gpio1>; - interrupts = <3 GPIO_ACTIVE_LOW>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; rohm,reset-snvs-powered; regulators { buck1_reg: BUCK1 { - regulator-name = "BUCK1"; + regulator-name = "buck1"; regulator-min-microvolt = <700000>; regulator-max-microvolt = <1300000>; regulator-boot-on; @@ -88,7 +88,7 @@ }; buck2_reg: BUCK2 { - regulator-name = "BUCK2"; + regulator-name = "buck2"; regulator-min-microvolt = <700000>; regulator-max-microvolt = <1300000>; regulator-boot-on; @@ -100,7 +100,7 @@ buck3_reg: BUCK3 { // BUCK5 in datasheet - regulator-name = "BUCK3"; + regulator-name = "buck3"; regulator-min-microvolt = <700000>; regulator-max-microvolt = <1350000>; regulator-boot-on; @@ -109,7 +109,7 @@ buck4_reg: BUCK4 { // BUCK6 in datasheet - regulator-name = "BUCK4"; + regulator-name = "buck4"; regulator-min-microvolt = <3000000>; regulator-max-microvolt = <3300000>; regulator-boot-on; @@ -118,7 +118,7 @@ buck5_reg: BUCK5 { // BUCK7 in datasheet - regulator-name = "BUCK5"; + regulator-name = "buck5"; regulator-min-microvolt = <1605000>; regulator-max-microvolt = <1995000>; regulator-boot-on; @@ -127,7 +127,7 @@ buck6_reg: BUCK6 { // BUCK8 in datasheet - regulator-name = "BUCK6"; + regulator-name = "buck6"; regulator-min-microvolt = <800000>; regulator-max-microvolt = <1400000>; regulator-boot-on; @@ -135,7 +135,7 @@ }; ldo1_reg: LDO1 { - regulator-name = "LDO1"; + regulator-name = "ldo1"; regulator-min-microvolt = <1600000>; regulator-max-microvolt = <3300000>; regulator-boot-on; @@ -143,7 +143,7 @@ }; ldo2_reg: LDO2 { - regulator-name = "LDO2"; + regulator-name = "ldo2"; regulator-min-microvolt = <800000>; regulator-max-microvolt = <900000>; regulator-boot-on; @@ -151,7 +151,7 @@ }; ldo3_reg: LDO3 { - regulator-name = "LDO3"; + regulator-name = "ldo3"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3300000>; regulator-boot-on; @@ -159,7 +159,7 @@ }; ldo4_reg: LDO4 { - regulator-name = "LDO4"; + regulator-name = "ldo4"; regulator-min-microvolt = <900000>; regulator-max-microvolt = <1800000>; regulator-boot-on; @@ -167,7 +167,7 @@ }; ldo6_reg: LDO6 { - regulator-name = "LDO6"; + regulator-name = "ldo6"; regulator-min-microvolt = <900000>; regulator-max-microvolt = <1800000>; regulator-boot-on; @@ -184,7 +184,7 @@ status = "okay"; eeprom@50 { - compatible = "microchip, at24c64d", "atmel,24c64"; + compatible = "microchip,24c64", "atmel,24c64"; pagesize = <32>; read-only; /* Manufacturing EEPROM programmed at factory */ reg = <0x50>; @@ -290,9 +290,9 @@ >; }; - pinctrl_pmic: pmicirq { + pinctrl_pmic: pmicirqgrp { fsl,pins = < - MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41 + MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x141 >; }; @@ -309,7 +309,7 @@ >; }; - pinctrl_usdhc1_gpio: usdhc1grpgpio { + pinctrl_usdhc1_gpio: usdhc1gpiogrp { fsl,pins = < MX8MM_IOMUXC_SD1_RESET_B_GPIO2_IO10 0x41 >; @@ -326,7 +326,7 @@ >; }; - pinctrl_usdhc1_100mhz: usdhc1grp100mhz { + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { fsl,pins = < MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x194 MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4 @@ -337,7 +337,7 @@ >; }; - pinctrl_usdhc1_200mhz: usdhc1grp200mhz { + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { fsl,pins = < MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x196 MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6 @@ -364,7 +364,7 @@ >; }; - pinctrl_usdhc3_100mhz: usdhc3grp100mhz { + pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp { fsl,pins = < MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194 MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4 @@ -380,7 +380,7 @@ >; }; - pinctrl_usdhc3_200mhz: usdhc3grp200mhz { + pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { fsl,pins = < MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196 MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6 diff --git a/arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dts b/arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dts new file mode 100644 index 000000000000..6c079c0a3a48 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-ddr4-evk.dts @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 NXP + */ + +/dts-v1/; + +#include "imx8mm-evk.dtsi" + +/ { + model = "FSL i.MX8MM DDR4 EVK with CYW43455 WIFI/BT board"; + compatible = "fsl,imx8mm-ddr4-evk", "fsl,imx8mm"; + + leds { + pinctrl-0 = <&pinctrl_gpio_led_2>; + + status { + gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gpmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpmi_nand>; + nand-on-flash-bbt; + status = "okay"; +}; + +&iomuxc { + pinctrl_gpmi_nand: gpmi-nand { + fsl,pins = < + MX8MM_IOMUXC_NAND_ALE_RAWNAND_ALE 0x00000096 + MX8MM_IOMUXC_NAND_CE0_B_RAWNAND_CE0_B 0x00000096 + MX8MM_IOMUXC_NAND_CE1_B_RAWNAND_CE1_B 0x00000096 + MX8MM_IOMUXC_NAND_CLE_RAWNAND_CLE 0x00000096 + MX8MM_IOMUXC_NAND_DATA00_RAWNAND_DATA00 0x00000096 + MX8MM_IOMUXC_NAND_DATA01_RAWNAND_DATA01 0x00000096 + MX8MM_IOMUXC_NAND_DATA02_RAWNAND_DATA02 0x00000096 + MX8MM_IOMUXC_NAND_DATA03_RAWNAND_DATA03 0x00000096 + MX8MM_IOMUXC_NAND_DATA04_RAWNAND_DATA04 0x00000096 + MX8MM_IOMUXC_NAND_DATA05_RAWNAND_DATA05 0x00000096 + MX8MM_IOMUXC_NAND_DATA06_RAWNAND_DATA06 0x00000096 + MX8MM_IOMUXC_NAND_DATA07_RAWNAND_DATA07 0x00000096 + MX8MM_IOMUXC_NAND_RE_B_RAWNAND_RE_B 0x00000096 + MX8MM_IOMUXC_NAND_READY_B_RAWNAND_READY_B 0x00000056 + MX8MM_IOMUXC_NAND_WE_B_RAWNAND_WE_B 0x00000096 + MX8MM_IOMUXC_NAND_WP_B_RAWNAND_WP_B 0x00000096 + >; + }; + + pinctrl_gpio_led_2: gpioled2grp { + fsl,pins = < + MX8MM_IOMUXC_NAND_CE3_B_GPIO3_IO4 0x19 + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts index 0f1d7f8aeac4..4e2820d19244 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts @@ -1,97 +1,20 @@ // SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* - * Copyright 2019 NXP + * Copyright 2019-2020 NXP */ /dts-v1/; #include <dt-bindings/usb/pd.h> -#include "imx8mm.dtsi" +#include "imx8mm-evk.dtsi" / { model = "FSL i.MX8MM EVK board"; compatible = "fsl,imx8mm-evk", "fsl,imx8mm"; - chosen { - stdout-path = &uart2; + aliases { + spi0 = &flexspi; }; - - memory@40000000 { - device_type = "memory"; - reg = <0x0 0x40000000 0 0x80000000>; - }; - - leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_led>; - - status { - label = "status"; - gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - }; - - reg_usdhc2_vmmc: regulator-usdhc2 { - compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; - regulator-name = "VSD_3V3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - - wm8524: audio-codec { - #sound-dai-cells = <0>; - compatible = "wlf,wm8524"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_wlf>; - wlf,mute-gpios = <&gpio5 21 GPIO_ACTIVE_LOW>; - }; - - sound-wm8524 { - compatible = "simple-audio-card"; - simple-audio-card,name = "wm8524-audio"; - simple-audio-card,format = "i2s"; - simple-audio-card,frame-master = <&cpudai>; - simple-audio-card,bitclock-master = <&cpudai>; - simple-audio-card,widgets = - "Line", "Left Line Out Jack", - "Line", "Right Line Out Jack"; - simple-audio-card,routing = - "Left Line Out Jack", "LINEVOUTL", - "Right Line Out Jack", "LINEVOUTR"; - - cpudai: simple-audio-card,cpu { - sound-dai = <&sai3>; - dai-tdm-slot-num = <2>; - dai-tdm-slot-width = <32>; - }; - - simple-audio-card,codec { - sound-dai = <&wm8524>; - clocks = <&clk IMX8MM_CLK_SAI3_ROOT>; - }; - }; -}; - -&A53_0 { - cpu-supply = <&buck2_reg>; -}; - -&A53_1 { - cpu-supply = <&buck2_reg>; -}; - -&A53_2 { - cpu-supply = <&buck2_reg>; -}; - -&A53_3 { - cpu-supply = <&buck2_reg>; }; &ddrc { @@ -114,238 +37,22 @@ }; }; -&fec1 { +&flexspi { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_fec1>; - phy-mode = "rgmii-id"; - phy-handle = <ðphy0>; - phy-reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>; - phy-reset-duration = <10>; - fsl,magic-packet; + pinctrl-0 = <&pinctrl_flexspi>; status = "okay"; - mdio { + flash@0 { + reg = <0>; #address-cells = <1>; - #size-cells = <0>; - - ethphy0: ethernet-phy@0 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0>; - }; - }; -}; - -&i2c1 { - clock-frequency = <400000>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c1>; - status = "okay"; - - pmic@4b { - compatible = "rohm,bd71847"; - reg = <0x4b>; - pinctrl-0 = <&pinctrl_pmic>; - interrupt-parent = <&gpio1>; - interrupts = <3 GPIO_ACTIVE_LOW>; - rohm,reset-snvs-powered; - - regulators { - buck1_reg: BUCK1 { - regulator-name = "BUCK1"; - regulator-min-microvolt = <700000>; - regulator-max-microvolt = <1300000>; - regulator-boot-on; - regulator-always-on; - regulator-ramp-delay = <1250>; - }; - - buck2_reg: BUCK2 { - regulator-name = "BUCK2"; - regulator-min-microvolt = <700000>; - regulator-max-microvolt = <1300000>; - regulator-boot-on; - regulator-always-on; - regulator-ramp-delay = <1250>; - rohm,dvs-run-voltage = <1000000>; - rohm,dvs-idle-voltage = <900000>; - }; - - buck3_reg: BUCK3 { - // BUCK5 in datasheet - regulator-name = "BUCK3"; - regulator-min-microvolt = <700000>; - regulator-max-microvolt = <1350000>; - regulator-boot-on; - regulator-always-on; - }; - - buck4_reg: BUCK4 { - // BUCK6 in datasheet - regulator-name = "BUCK4"; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - regulator-always-on; - }; - - buck5_reg: BUCK5 { - // BUCK7 in datasheet - regulator-name = "BUCK5"; - regulator-min-microvolt = <1605000>; - regulator-max-microvolt = <1995000>; - regulator-boot-on; - regulator-always-on; - }; - - buck6_reg: BUCK6 { - // BUCK8 in datasheet - regulator-name = "BUCK6"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <1400000>; - regulator-boot-on; - regulator-always-on; - }; - - ldo1_reg: LDO1 { - regulator-name = "LDO1"; - regulator-min-microvolt = <1600000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - regulator-always-on; - }; - - ldo2_reg: LDO2 { - regulator-name = "LDO2"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <900000>; - regulator-boot-on; - regulator-always-on; - }; - - ldo3_reg: LDO3 { - regulator-name = "LDO3"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - regulator-always-on; - }; - - ldo4_reg: LDO4 { - regulator-name = "LDO4"; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - regulator-always-on; - }; - - ldo6_reg: LDO6 { - regulator-name = "LDO6"; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - regulator-always-on; - }; - }; - }; -}; - -&i2c2 { - clock-frequency = <400000>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c2>; - status = "okay"; - - ptn5110: tcpc@50 { - compatible = "nxp,ptn5110"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_typec1>; - reg = <0x50>; - interrupt-parent = <&gpio2>; - interrupts = <11 8>; - status = "okay"; - - port { - typec1_dr_sw: endpoint { - remote-endpoint = <&usb1_drd_sw>; - }; - }; - - typec1_con: connector { - compatible = "usb-c-connector"; - label = "USB-C"; - power-role = "dual"; - data-role = "dual"; - try-power-role = "sink"; - source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; - sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM) - PDO_VAR(5000, 20000, 3000)>; - op-sink-microwatt = <15000000>; - self-powered; - }; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + spi-max-frequency = <80000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; }; }; -&i2c3 { - clock-frequency = <400000>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c3>; - status = "okay"; - - pca6416: gpio@20 { - compatible = "ti,tca6416"; - reg = <0x20>; - gpio-controller; - #gpio-cells = <2>; - }; -}; - -&sai3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sai3>; - assigned-clocks = <&clk IMX8MM_CLK_SAI3>; - assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>; - assigned-clock-rates = <24576000>; - status = "okay"; -}; - -&snvs_pwrkey { - status = "okay"; -}; - -&uart2 { /* console */ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart2>; - status = "okay"; -}; - -&usbotg1 { - dr_mode = "otg"; - hnp-disable; - srp-disable; - adp-disable; - usb-role-switch; - status = "okay"; - - port { - usb1_drd_sw: endpoint { - remote-endpoint = <&typec1_dr_sw>; - }; - }; -}; - -&usdhc2 { - assigned-clocks = <&clk IMX8MM_CLK_USDHC2>; - assigned-clock-rates = <200000000>; - pinctrl-names = "default", "state_100mhz", "state_200mhz"; - pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; - pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; - pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; - cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; - bus-width = <4>; - vmmc-supply = <®_usdhc2_vmmc>; - status = "okay"; -}; - &usdhc3 { assigned-clocks = <&clk IMX8MM_CLK_USDHC3_ROOT>; assigned-clock-rates = <400000000>; @@ -358,196 +65,64 @@ status = "okay"; }; -&wdog1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_wdog>; - fsl,ext-reset-output; - status = "okay"; -}; - &iomuxc { - pinctrl-names = "default"; - - 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_gpio_led: gpioledgrp { - fsl,pins = < - MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16 0x19 - >; - }; - - pinctrl_gpio_wlf: gpiowlfgrp { + pinctrl_flexspi: flexspigrp { fsl,pins = < - MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21 0xd6 - >; - }; - - pinctrl_i2c1: i2c1grp { - fsl,pins = < - MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 - MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3 - >; - }; - - pinctrl_i2c2: i2c2grp { - fsl,pins = < - MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3 - MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3 - >; - }; - - pinctrl_i2c3: i2c3grp { - fsl,pins = < - MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3 - MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3 - >; - }; - - pinctrl_pmic: pmicirq { - fsl,pins = < - MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41 - >; - }; - - pinctrl_reg_usdhc2_vmmc: regusdhc2vmmc { - fsl,pins = < - MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 - >; - }; - - pinctrl_sai3: sai3grp { - fsl,pins = < - MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6 - MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6 - MX8MM_IOMUXC_SAI3_MCLK_SAI3_MCLK 0xd6 - MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6 - >; - }; - - pinctrl_typec1: typec1grp { - fsl,pins = < - MX8MM_IOMUXC_SD1_STROBE_GPIO2_IO11 0x159 - >; - }; - - pinctrl_uart2: uart2grp { - fsl,pins = < - MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140 - MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140 - >; - }; - - pinctrl_usdhc2_gpio: usdhc2grpgpio { - fsl,pins = < - MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x1c4 - >; - }; - - 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_GPIO1_IO04_USDHC2_VSELECT 0x1d0 - >; - }; - - pinctrl_usdhc2_100mhz: usdhc2grp100mhz { - fsl,pins = < - MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194 - MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4 - MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4 - MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4 - MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4 - MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4 - MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 - >; - }; - - pinctrl_usdhc2_200mhz: usdhc2grp200mhz { - fsl,pins = < - MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196 - MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6 - MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6 - MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6 - MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6 - MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6 - MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + 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_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_100mhz: usdhc3grp100mhz { - 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_200mhz: usdhc3grp200mhz { - 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_wdog: wdoggrp { - fsl,pins = < - MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 + 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_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_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_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 >; }; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi new file mode 100644 index 000000000000..f305a530ff6f --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi @@ -0,0 +1,474 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2020 NXP + */ + +/dts-v1/; + +#include <dt-bindings/usb/pd.h> +#include "imx8mm.dtsi" + +/ { + chosen { + stdout-path = &uart2; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0x0 0x40000000 0 0x80000000>; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_led>; + + status { + label = "status"; + gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; + + reg_usdhc2_vmmc: regulator-usdhc2 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; + regulator-name = "VSD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + wm8524: audio-codec { + #sound-dai-cells = <0>; + compatible = "wlf,wm8524"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_wlf>; + wlf,mute-gpios = <&gpio5 21 GPIO_ACTIVE_LOW>; + }; + + sound-wm8524 { + compatible = "simple-audio-card"; + simple-audio-card,name = "wm8524-audio"; + simple-audio-card,format = "i2s"; + simple-audio-card,frame-master = <&cpudai>; + simple-audio-card,bitclock-master = <&cpudai>; + simple-audio-card,widgets = + "Line", "Left Line Out Jack", + "Line", "Right Line Out Jack"; + simple-audio-card,routing = + "Left Line Out Jack", "LINEVOUTL", + "Right Line Out Jack", "LINEVOUTR"; + + cpudai: simple-audio-card,cpu { + sound-dai = <&sai3>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + }; + + simple-audio-card,codec { + sound-dai = <&wm8524>; + clocks = <&clk IMX8MM_CLK_SAI3_ROOT>; + }; + }; +}; + +&A53_0 { + cpu-supply = <&buck2_reg>; +}; + +&A53_1 { + cpu-supply = <&buck2_reg>; +}; + +&A53_2 { + cpu-supply = <&buck2_reg>; +}; + +&A53_3 { + cpu-supply = <&buck2_reg>; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1>; + phy-mode = "rgmii-id"; + phy-handle = <ðphy0>; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + }; + }; +}; + +&i2c1 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + pmic@4b { + compatible = "rohm,bd71847"; + reg = <0x4b>; + pinctrl-0 = <&pinctrl_pmic>; + interrupt-parent = <&gpio1>; + 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"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <1250>; + }; + + buck2_reg: BUCK2 { + regulator-name = "buck2"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <1000000>; + rohm,dvs-idle-voltage = <900000>; + }; + + buck3_reg: BUCK3 { + // BUCK5 in datasheet + regulator-name = "buck3"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1350000>; + regulator-boot-on; + regulator-always-on; + }; + + buck4_reg: BUCK4 { + // BUCK6 in datasheet + regulator-name = "buck4"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + buck5_reg: BUCK5 { + // BUCK7 in datasheet + regulator-name = "buck5"; + regulator-min-microvolt = <1605000>; + regulator-max-microvolt = <1995000>; + regulator-boot-on; + regulator-always-on; + }; + + buck6_reg: BUCK6 { + // BUCK8 in datasheet + regulator-name = "buck6"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1_reg: LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <1600000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo2_reg: LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo3_reg: LDO3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo4_reg: LDO4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo6_reg: LDO6 { + regulator-name = "ldo6"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; + +&i2c2 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + ptn5110: tcpc@50 { + compatible = "nxp,ptn5110"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_typec1>; + reg = <0x50>; + interrupt-parent = <&gpio2>; + interrupts = <11 8>; + status = "okay"; + + port { + typec1_dr_sw: endpoint { + remote-endpoint = <&usb1_drd_sw>; + }; + }; + + typec1_con: connector { + compatible = "usb-c-connector"; + label = "USB-C"; + power-role = "dual"; + data-role = "dual"; + try-power-role = "sink"; + source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; + sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM) + PDO_VAR(5000, 20000, 3000)>; + op-sink-microwatt = <15000000>; + self-powered; + }; + }; +}; + +&i2c3 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + pca6416: gpio@20 { + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + }; +}; + +&sai3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai3>; + assigned-clocks = <&clk IMX8MM_CLK_SAI3>; + assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>; + assigned-clock-rates = <24576000>; + status = "okay"; +}; + +&snvs_pwrkey { + status = "okay"; +}; + +&uart2 { /* console */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; +}; + +&usbotg1 { + dr_mode = "otg"; + hnp-disable; + srp-disable; + adp-disable; + usb-role-switch; + samsung,picophy-pre-emp-curr-control = <3>; + samsung,picophy-dc-vol-level-adjust = <7>; + status = "okay"; + + port { + usb1_drd_sw: endpoint { + remote-endpoint = <&typec1_dr_sw>; + }; + }; +}; + +&usdhc2 { + assigned-clocks = <&clk IMX8MM_CLK_USDHC2>; + assigned-clock-rates = <200000000>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; + cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + bus-width = <4>; + vmmc-supply = <®_usdhc2_vmmc>; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; + +&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_gpio_led: gpioledgrp { + fsl,pins = < + MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16 0x19 + >; + }; + + pinctrl_gpio_wlf: gpiowlfgrp { + fsl,pins = < + MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21 0xd6 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 + MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3 + MX8MM_IOMUXC_I2C2_SDA_I2C2_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_reg_usdhc2_vmmc: regusdhc2vmmcgrp { + fsl,pins = < + MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 + >; + }; + + pinctrl_sai3: sai3grp { + fsl,pins = < + MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6 + MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6 + MX8MM_IOMUXC_SAI3_MCLK_SAI3_MCLK 0xd6 + MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6 + >; + }; + + pinctrl_typec1: typec1grp { + fsl,pins = < + MX8MM_IOMUXC_SD1_STROBE_GPIO2_IO11 0x159 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140 + MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140 + >; + }; + + pinctrl_usdhc2_gpio: usdhc2grpgpiogrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x1c4 + >; + }; + + 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_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194 + MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4 + MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4 + MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4 + MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4 + MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196 + MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6 + MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6 + MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6 + MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6 + MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dts b/arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dts new file mode 100644 index 000000000000..ac1fe1530ac7 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dts @@ -0,0 +1,255 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2020 Krzysztof Kozlowski <krzk@kernel.org> + */ + +/dts-v1/; + +#include "imx8mm-var-som.dtsi" + +/ { + model = "Variscite VAR-SOM-MX8MM Symphony evaluation board"; + compatible = "variscite,var-som-mx8mm-symphony", "variscite,var-som-mx8mm", "fsl,imx8mm"; + + reg_usdhc2_vmmc: regulator-usdhc2-vmmc { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; + regulator-name = "VSD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usb_otg2_vbus: regulator-usb-otg2-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_usb_otg2_vbus>; + regulator-name = "usb_otg2_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + gpio-keys { + compatible = "gpio-keys"; + + back { + label = "Back"; + gpios = <&pca9534 1 GPIO_ACTIVE_LOW>; + linux,code = <KEY_BACK>; + }; + + home { + label = "Home"; + gpios = <&pca9534 2 GPIO_ACTIVE_LOW>; + linux,code = <KEY_HOME>; + }; + + menu { + label = "Menu"; + gpios = <&pca9534 3 GPIO_ACTIVE_LOW>; + linux,code = <KEY_MENU>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led { + label = "Heartbeat"; + gpios = <&pca9534 0 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + }; +}; + +ðphy { + reset-gpios = <&pca9534 5 GPIO_ACTIVE_HIGH>; +}; + +&i2c2 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + pca9534: gpio@20 { + compatible = "nxp,pca9534"; + reg = <0x20>; + gpio-controller; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pca9534>; + interrupt-parent = <&gpio1>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + #gpio-cells = <2>; + wakeup-source; + + /* USB 3.0 OTG (usbotg1) / SATA port switch, set to USB 3.0 */ + usb3-sata-sel-hog { + gpio-hog; + gpios = <4 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "usb3_sata_sel"; + }; + + som-vselect-hog { + gpio-hog; + gpios = <6 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "som_vselect"; + }; + + enet-sel-hog { + gpio-hog; + gpios = <7 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "enet_sel"; + }; + }; + + extcon_usbotg1: typec@3d { + compatible = "nxp,ptn5150"; + reg = <0x3d>; + interrupt-parent = <&gpio1>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ptn5150>; + status = "okay"; + }; +}; + +&i2c3 { + /* Capacitive touch controller */ + ft5x06_ts: touchscreen@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_captouch>; + interrupt-parent = <&gpio5>; + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; + + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + touchscreen-inverted-x; + touchscreen-inverted-y; + }; + + rtc@68 { + compatible = "dallas,ds1337"; + reg = <0x68>; + }; +}; + +/* Header */ +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +/* Header */ +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + status = "okay"; +}; + +&usbotg1 { + disable-over-current; + extcon = <&extcon_usbotg1>, <&extcon_usbotg1>; +}; + +&usbotg2 { + dr_mode = "host"; + vbus-supply = <®_usb_otg2_vbus>; + srp-disable; + hnp-disable; + adp-disable; + disable-over-current; + /delete-property/ usb-role-switch; + /* + * FIXME: having USB2 enabled hangs the boot just after: + * [ 1.943365] ci_hdrc ci_hdrc.1: EHCI Host Controller + * [ 1.948287] ci_hdrc ci_hdrc.1: new USB bus registered, assigned bus number 1 + * [ 1.971006] ci_hdrc ci_hdrc.1: USB 2.0 started, EHCI 1.00 + * [ 1.977203] hub 1-0:1.0: USB hub found + * [ 1.980987] hub 1-0:1.0: 1 port detected + */ + status = "disabled"; +}; + +&pinctrl_fec1 { + 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 + /* Remove the MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 as not used */ + >; +}; + +&iomuxc { + pinctrl_captouch: captouchgrp { + fsl,pins = < + MX8MM_IOMUXC_SPDIF_RX_GPIO5_IO4 0x16 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3 + MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3 + >; + }; + + pinctrl_pca9534: pca9534grp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x16 + >; + }; + + pinctrl_ptn5150: ptn5150grp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x16 + >; + }; + + pinctrl_reg_usb_otg2_vbus: regusbotg2vbusgrp { + fsl,pins = < + MX8MM_IOMUXC_SAI3_TXD_GPIO5_IO1 0x16 + >; + }; + + pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { + fsl,pins = < + MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140 + MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX8MM_IOMUXC_UART3_RXD_UART3_DCE_RX 0x140 + MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX 0x140 + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-var-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-var-som.dtsi new file mode 100644 index 000000000000..4107fe914d08 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-var-som.dtsi @@ -0,0 +1,561 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2019 NXP + * Copyright (C) 2020 Krzysztof Kozlowski <krzk@kernel.org> + */ + +#include "imx8mm.dtsi" + +/ { + model = "Variscite VAR-SOM-MX8MM module"; + compatible = "variscite,var-som-mx8mm", "fsl,imx8mm"; + + chosen { + stdout-path = &uart4; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0x0 0x40000000 0 0x80000000>; + }; + + reg_eth_phy: regulator-eth-phy { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_eth_phy>; + regulator-name = "eth_phy_pwr"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 9 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&A53_0 { + 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>; + + 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 = <&gpio1 14 GPIO_ACTIVE_LOW>, + <&gpio1 0 GPIO_ACTIVE_LOW>; + /delete-property/ dmas; + /delete-property/ dma-names; + status = "okay"; + + /* Resistive touch controller */ + touchscreen@0 { + reg = <0>; + compatible = "ti,ads7846"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_restouch>; + interrupt-parent = <&gpio1>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + + spi-max-frequency = <1500000>; + pendown-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>; + + ti,x-min = /bits/ 16 <125>; + touchscreen-size-x = /bits/ 16 <4008>; + ti,y-min = /bits/ 16 <282>; + touchscreen-size-y = /bits/ 16 <3864>; + ti,x-plate-ohms = /bits/ 16 <180>; + touchscreen-max-pressure = /bits/ 16 <255>; + touchscreen-average-samples = /bits/ 16 <10>; + ti,debounce-tol = /bits/ 16 <3>; + ti,debounce-rep = /bits/ 16 <1>; + ti,settle-delay-usec = /bits/ 16 <150>; + ti,keep-vref-on; + wakeup-source; + }; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1>; + phy-mode = "rgmii"; + phy-handle = <ðphy>; + phy-supply = <®_eth_phy>; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <4>; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <10000>; + }; + }; +}; + +&i2c1 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + pmic@4b { + compatible = "rohm,bd71847"; + reg = <0x4b>; + pinctrl-0 = <&pinctrl_pmic>; + interrupt-parent = <&gpio2>; + /* + * The interrupt is not correct. It should be level low, + * however with internal pull up this causes IRQ storm. + */ + interrupts = <8 IRQ_TYPE_EDGE_RISING>; + rohm,reset-snvs-powered; + + #clock-cells = <0>; + clocks = <&osc_32k 0>; + clock-output-names = "clk-32k-out"; + + regulators { + buck1_reg: BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <1250>; + }; + + buck2_reg: BUCK2 { + regulator-name = "buck2"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <1000000>; + rohm,dvs-idle-voltage = <900000>; + }; + + buck3_reg: BUCK3 { + regulator-name = "buck3"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1350000>; + regulator-boot-on; + regulator-always-on; + }; + + buck4_reg: BUCK4 { + regulator-name = "buck4"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + buck5_reg: BUCK5 { + regulator-name = "buck5"; + regulator-min-microvolt = <1605000>; + regulator-max-microvolt = <1995000>; + regulator-boot-on; + regulator-always-on; + }; + + buck6_reg: BUCK6 { + regulator-name = "buck6"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1_reg: LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <1600000>; + regulator-max-microvolt = <1900000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo2_reg: LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo3_reg: LDO3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo4_reg: LDO4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo5_reg: LDO5 { + regulator-compatible = "ldo5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ldo6_reg: LDO6 { + regulator-name = "ldo6"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; + +&i2c3 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + /* TODO: configure audio, as of now just put a placeholder */ + wm8904: codec@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + status = "disabled"; + }; +}; + +&snvs_pwrkey { + status = "okay"; +}; + +/* Bluetooth */ +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + assigned-clocks = <&clk IMX8MM_CLK_UART2>; + assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>; + uart-has-rtscts; + status = "okay"; +}; + +/* Console */ +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +&usbotg1 { + dr_mode = "otg"; + usb-role-switch; + status = "okay"; +}; + +&usbotg2 { + dr_mode = "otg"; + usb-role-switch; + status = "okay"; +}; + +/* WIFI */ +&usdhc1 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + bus-width = <4>; + non-removable; + keep-power-in-suspend; + status = "okay"; + + brcmf: bcrmf@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + }; +}; + +/* SD */ +&usdhc2 { + assigned-clocks = <&clk IMX8MM_CLK_USDHC2>; + assigned-clock-rates = <200000000>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; + cd-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + bus-width = <4>; + vmmc-supply = <®_usdhc2_vmmc>; + status = "okay"; +}; + +/* eMMC */ +&usdhc3 { + assigned-clocks = <&clk IMX8MM_CLK_USDHC3_ROOT>; + assigned-clock-rates = <400000000>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + 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_SCLK_ECSPI1_SCLK 0x13 + MX8MM_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x13 + MX8MM_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x13 + MX8MM_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x13 + MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x13 + >; + }; + + 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_GPIO1_IO09_GPIO1_IO9 0x19 + >; + }; + + 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_pmic: pmicirqgrp { + fsl,pins = < + MX8MM_IOMUXC_SD1_DATA6_GPIO2_IO8 0x41 + >; + }; + + pinctrl_reg_eth_phy: regethphygrp { + fsl,pins = < + MX8MM_IOMUXC_SD1_DATA7_GPIO2_IO9 0x41 + >; + }; + + pinctrl_restouch: restouchgrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x1c0 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x140 + MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x140 + MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x140 + MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x140 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX 0x140 + MX8MM_IOMUXC_UART4_TXD_UART4_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 + >; + }; + + 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_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_usdhc2_gpio: usdhc2gpiogrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0xc1 + >; + }; + + 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_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194 + MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4 + MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4 + MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4 + MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4 + MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196 + MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6 + MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6 + MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6 + MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6 + MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + >; + }; + + 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_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_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_wdog: wdoggrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi index 76f040e4be5e..b83f400def8b 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi @@ -854,7 +854,8 @@ reg = <0x30be0000 0x10000>; interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MM_CLK_ENET1_ROOT>, <&clk IMX8MM_CLK_ENET1_ROOT>, <&clk IMX8MM_CLK_ENET_TIMER>, diff --git a/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts b/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts index a1e5483dbbbe..46e76cf32b2f 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts @@ -55,12 +55,12 @@ reg = <0x4b>; pinctrl-0 = <&pinctrl_pmic>; interrupt-parent = <&gpio1>; - interrupts = <3 GPIO_ACTIVE_LOW>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; rohm,reset-snvs-powered; regulators { buck1_reg: BUCK1 { - regulator-name = "BUCK1"; + regulator-name = "buck1"; regulator-min-microvolt = <700000>; regulator-max-microvolt = <1300000>; regulator-boot-on; @@ -69,7 +69,7 @@ }; buck2_reg: BUCK2 { - regulator-name = "BUCK2"; + regulator-name = "buck2"; regulator-min-microvolt = <700000>; regulator-max-microvolt = <1300000>; regulator-boot-on; @@ -79,14 +79,14 @@ buck3_reg: BUCK3 { // BUCK5 in datasheet - regulator-name = "BUCK3"; + regulator-name = "buck3"; regulator-min-microvolt = <700000>; regulator-max-microvolt = <1350000>; }; buck4_reg: BUCK4 { // BUCK6 in datasheet - regulator-name = "BUCK4"; + regulator-name = "buck4"; regulator-min-microvolt = <3000000>; regulator-max-microvolt = <3300000>; regulator-boot-on; @@ -95,7 +95,7 @@ buck5_reg: BUCK5 { // BUCK7 in datasheet - regulator-name = "BUCK5"; + regulator-name = "buck5"; regulator-min-microvolt = <1605000>; regulator-max-microvolt = <1995000>; regulator-boot-on; @@ -104,7 +104,7 @@ buck6_reg: BUCK6 { // BUCK8 in datasheet - regulator-name = "BUCK6"; + regulator-name = "buck6"; regulator-min-microvolt = <800000>; regulator-max-microvolt = <1400000>; regulator-boot-on; @@ -112,7 +112,7 @@ }; ldo1_reg: LDO1 { - regulator-name = "LDO1"; + regulator-name = "ldo1"; regulator-min-microvolt = <1600000>; regulator-max-microvolt = <3300000>; regulator-boot-on; @@ -120,7 +120,7 @@ }; ldo2_reg: LDO2 { - regulator-name = "LDO2"; + regulator-name = "ldo2"; regulator-min-microvolt = <800000>; regulator-max-microvolt = <900000>; regulator-boot-on; @@ -128,7 +128,7 @@ }; ldo3_reg: LDO3 { - regulator-name = "LDO3"; + regulator-name = "ldo3"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3300000>; regulator-boot-on; @@ -136,7 +136,7 @@ }; ldo4_reg: LDO4 { - regulator-name = "LDO4"; + regulator-name = "ldo4"; regulator-min-microvolt = <900000>; regulator-max-microvolt = <1800000>; regulator-boot-on; @@ -144,7 +144,7 @@ }; ldo6_reg: LDO6 { - regulator-name = "LDO6"; + regulator-name = "ldo6"; regulator-min-microvolt = <900000>; regulator-max-microvolt = <1800000>; regulator-boot-on; @@ -153,11 +153,3 @@ }; }; }; - -&iomuxc { - pinctrl_pmic: pmicirq { - fsl,pins = < - MX8MN_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41 - >; - }; -}; diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dts b/arch/arm64/boot/dts/freescale/imx8mn-evk.dts index b846526a8d8b..707d8486b4d8 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dts @@ -7,6 +7,7 @@ #include "imx8mn.dtsi" #include "imx8mn-evk.dtsi" +#include <dt-bindings/interrupt-controller/irq.h> / { model = "NXP i.MX8MNano EVK board"; @@ -19,7 +20,7 @@ reg = <0x25>; pinctrl-0 = <&pinctrl_pmic>; interrupt-parent = <&gpio1>; - interrupts = <3 GPIO_ACTIVE_LOW>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; regulators { buck1: BUCK1{ diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi index 98f5324b1dbe..4aa0dbd578df 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi @@ -132,6 +132,8 @@ srp-disable; adp-disable; usb-role-switch; + samsung,picophy-pre-emp-curr-control = <3>; + samsung,picophy-dc-vol-level-adjust = <7>; status = "okay"; port { @@ -174,8 +176,6 @@ }; &iomuxc { - pinctrl-names = "default"; - pinctrl_fec1: fec1grp { fsl,pins = < MX8MN_IOMUXC_ENET_MDC_ENET1_MDC 0x3 @@ -223,13 +223,13 @@ >; }; - pinctrl_pmic: pmicirq { + pinctrl_pmic: pmicirqgrp { fsl,pins = < - MX8MN_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41 + MX8MN_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x141 >; }; - pinctrl_reg_usdhc2_vmmc: regusdhc2vmmc { + pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { fsl,pins = < MX8MN_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 >; @@ -248,7 +248,7 @@ >; }; - pinctrl_usdhc2_gpio: usdhc2grpgpio { + pinctrl_usdhc2_gpio: usdhc2gpiogrp { fsl,pins = < MX8MN_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x1c4 >; @@ -266,7 +266,7 @@ >; }; - pinctrl_usdhc2_100mhz: usdhc2grp100mhz { + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { fsl,pins = < MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK 0x194 MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4 @@ -278,7 +278,7 @@ >; }; - pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { fsl,pins = < MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK 0x196 MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6 @@ -306,7 +306,7 @@ >; }; - pinctrl_usdhc3_100mhz: usdhc3grp100mhz { + pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp { fsl,pins = < MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK 0x40000194 MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4 @@ -322,7 +322,7 @@ >; }; - pinctrl_usdhc3_200mhz: usdhc3grp200mhz { + pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { fsl,pins = < MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK 0x40000196 MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6 diff --git a/arch/arm64/boot/dts/freescale/imx8mn-var-som-symphony.dts b/arch/arm64/boot/dts/freescale/imx8mn-var-som-symphony.dts new file mode 100644 index 000000000000..f61c48776cf3 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mn-var-som-symphony.dts @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2019-2020 Variscite Ltd. + * Copyright (C) 2020 Krzysztof Kozlowski <krzk@kernel.org> + */ + +/dts-v1/; + +#include "imx8mn-var-som.dtsi" + +/ { + model = "Variscite VAR-SOM-MX8MN Symphony evaluation board"; + compatible = "variscite,var-som-mx8mn-symphony", "variscite,var-som-mx8mn", "fsl,imx8mn"; + + reg_usdhc2_vmmc: regulator-usdhc2-vmmc { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; + regulator-name = "VSD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio4 22 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + gpio-keys { + compatible = "gpio-keys"; + + back { + label = "Back"; + gpios = <&pca9534 1 GPIO_ACTIVE_LOW>; + linux,code = <KEY_BACK>; + }; + + home { + label = "Home"; + gpios = <&pca9534 2 GPIO_ACTIVE_LOW>; + linux,code = <KEY_HOME>; + }; + + menu { + label = "Menu"; + gpios = <&pca9534 3 GPIO_ACTIVE_LOW>; + linux,code = <KEY_MENU>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led { + label = "Heartbeat"; + gpios = <&pca9534 0 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + }; +}; + +ðphy { + reset-gpios = <&pca9534 5 GPIO_ACTIVE_HIGH>; +}; + +&i2c2 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + pca9534: gpio@20 { + compatible = "nxp,pca9534"; + reg = <0x20>; + gpio-controller; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pca9534>; + interrupt-parent = <&gpio1>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + #gpio-cells = <2>; + wakeup-source; + + /* USB 3.0 OTG (usbotg1) / SATA port switch, set to USB 3.0 */ + usb3-sata-sel-hog { + gpio-hog; + gpios = <4 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "usb3_sata_sel"; + }; + + som-vselect-hog { + gpio-hog; + gpios = <6 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "som_vselect"; + }; + + enet-sel-hog { + gpio-hog; + gpios = <7 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "enet_sel"; + }; + }; + + extcon_usbotg1: typec@3d { + compatible = "nxp,ptn5150"; + reg = <0x3d>; + interrupt-parent = <&gpio1>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ptn5150>; + status = "okay"; + }; +}; + +&i2c3 { + /* Capacitive touch controller */ + ft5x06_ts: touchscreen@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_captouch>; + interrupt-parent = <&gpio5>; + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; + + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + touchscreen-inverted-x; + touchscreen-inverted-y; + }; + + rtc@68 { + compatible = "dallas,ds1337"; + reg = <0x68>; + }; +}; + +/* Header */ +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +/* Header */ +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + status = "okay"; +}; + +&usbotg1 { + disable-over-current; + extcon = <&extcon_usbotg1>, <&extcon_usbotg1>; +}; + +&pinctrl_fec1 { + fsl,pins = < + MX8MN_IOMUXC_ENET_MDC_ENET1_MDC 0x3 + MX8MN_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3 + MX8MN_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f + MX8MN_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f + MX8MN_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f + MX8MN_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f + MX8MN_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91 + MX8MN_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 + MX8MN_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 + MX8MN_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 + MX8MN_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f + MX8MN_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 + MX8MN_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 + MX8MN_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f + /* Remove the MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 as not used */ + >; +}; + +&pinctrl_fec1_sleep { + fsl,pins = < + MX8MN_IOMUXC_ENET_MDC_GPIO1_IO16 0x120 + MX8MN_IOMUXC_ENET_MDIO_GPIO1_IO17 0x120 + MX8MN_IOMUXC_ENET_TD3_GPIO1_IO18 0x120 + MX8MN_IOMUXC_ENET_TD2_GPIO1_IO19 0x120 + MX8MN_IOMUXC_ENET_TD1_GPIO1_IO20 0x120 + MX8MN_IOMUXC_ENET_TD0_GPIO1_IO21 0x120 + MX8MN_IOMUXC_ENET_RD3_GPIO1_IO29 0x120 + MX8MN_IOMUXC_ENET_RD2_GPIO1_IO28 0x120 + MX8MN_IOMUXC_ENET_RD1_GPIO1_IO27 0x120 + MX8MN_IOMUXC_ENET_RD0_GPIO1_IO26 0x120 + MX8MN_IOMUXC_ENET_TXC_GPIO1_IO23 0x120 + MX8MN_IOMUXC_ENET_RXC_GPIO1_IO25 0x120 + MX8MN_IOMUXC_ENET_RX_CTL_GPIO1_IO24 0x120 + MX8MN_IOMUXC_ENET_TX_CTL_GPIO1_IO22 0x120 + /* Remove the MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 as not used */ + >; +}; + +&iomuxc { + pinctrl_captouch: captouchgrp { + fsl,pins = < + MX8MN_IOMUXC_SPDIF_RX_GPIO5_IO4 0x16 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX8MN_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3 + MX8MN_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3 + >; + }; + + pinctrl_pca9534: pca9534grp { + fsl,pins = < + MX8MN_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x16 + >; + }; + + pinctrl_ptn5150: ptn5150grp { + fsl,pins = < + MX8MN_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x16 + >; + }; + + pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { + fsl,pins = < + MX8MN_IOMUXC_SAI2_RXC_GPIO4_IO22 0x41 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX8MN_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140 + MX8MN_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX8MN_IOMUXC_UART3_RXD_UART3_DCE_RX 0x140 + MX8MN_IOMUXC_UART3_TXD_UART3_DCE_TX 0x140 + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi new file mode 100644 index 000000000000..a2d0190921e4 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi @@ -0,0 +1,551 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2019 NXP + * Copyright 2019-2020 Variscite Ltd. + * Copyright (C) 2020 Krzysztof Kozlowski <krzk@kernel.org> + */ + +#include "imx8mn.dtsi" + +/ { + model = "Variscite VAR-SOM-MX8MN module"; + compatible = "variscite,var-som-mx8mn", "fsl,imx8mn"; + + chosen { + stdout-path = &uart4; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0x0 0x40000000 0 0x40000000>; + }; + + reg_eth_phy: regulator-eth-phy { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_eth_phy>; + regulator-name = "eth_phy_pwr"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 9 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&A53_0 { + cpu-supply = <&buck2_reg>; +}; + +&A53_1 { + cpu-supply = <&buck2_reg>; +}; + +&A53_2 { + cpu-supply = <&buck2_reg>; +}; + +&A53_3 { + cpu-supply = <&buck2_reg>; +}; + +&ecspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1>; + cs-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>, + <&gpio1 0 GPIO_ACTIVE_LOW>; + /delete-property/ dmas; + /delete-property/ dma-names; + status = "okay"; + + /* Resistive touch controller */ + touchscreen@0 { + reg = <0>; + compatible = "ti,ads7846"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_restouch>; + interrupt-parent = <&gpio1>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + + spi-max-frequency = <1500000>; + pendown-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>; + + ti,x-min = /bits/ 16 <125>; + touchscreen-size-x = /bits/ 16 <4008>; + ti,y-min = /bits/ 16 <282>; + touchscreen-size-y = /bits/ 16 <3864>; + ti,x-plate-ohms = /bits/ 16 <180>; + touchscreen-max-pressure = /bits/ 16 <255>; + touchscreen-average-samples = /bits/ 16 <10>; + ti,debounce-tol = /bits/ 16 <3>; + ti,debounce-rep = /bits/ 16 <1>; + ti,settle-delay-usec = /bits/ 16 <150>; + ti,keep-vref-on; + wakeup-source; + }; +}; + +&fec1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_fec1>; + pinctrl-1 = <&pinctrl_fec1_sleep>; + phy-mode = "rgmii"; + phy-handle = <ðphy>; + phy-supply = <®_eth_phy>; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <4>; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + }; + }; +}; + +&i2c1 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + pmic@4b { + compatible = "rohm,bd71847"; + reg = <0x4b>; + pinctrl-0 = <&pinctrl_pmic>; + interrupt-parent = <&gpio2>; + /* + * The interrupt is not correct. It should be level low, + * however with internal pull up this causes IRQ storm. + */ + interrupts = <8 IRQ_TYPE_EDGE_RISING>; + rohm,reset-snvs-powered; + + regulators { + buck1_reg: BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <1250>; + }; + + buck2_reg: BUCK2 { + regulator-name = "buck2"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <1000000>; + rohm,dvs-idle-voltage = <900000>; + }; + + buck3_reg: BUCK3 { + regulator-name = "buck3"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1350000>; + regulator-boot-on; + regulator-always-on; + }; + + buck4_reg: BUCK4 { + regulator-name = "buck4"; + regulator-min-microvolt = <2600000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + buck5_reg: BUCK5 { + regulator-name = "buck5"; + regulator-min-microvolt = <1605000>; + regulator-max-microvolt = <1995000>; + regulator-boot-on; + regulator-always-on; + }; + + buck6_reg: BUCK6 { + regulator-name = "buck6"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1_reg: LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <1600000>; + regulator-max-microvolt = <1900000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo2_reg: LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo3_reg: LDO3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo4_reg: LDO4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ldo5_reg: LDO5 { + regulator-compatible = "ldo5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ldo6_reg: LDO6 { + regulator-name = "ldo6"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; + +&i2c3 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + /* TODO: configure audio, as of now just put a placeholder */ + wm8904: codec@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + status = "disabled"; + }; +}; + +&snvs_pwrkey { + status = "okay"; +}; + +/* Bluetooth */ +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + assigned-clocks = <&clk IMX8MN_CLK_UART2>; + assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_80M>; + uart-has-rtscts; + status = "okay"; +}; + +/* Console */ +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +&usbotg1 { + dr_mode = "otg"; + usb-role-switch; + status = "okay"; +}; + +/* WIFI */ +&usdhc1 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + bus-width = <4>; + non-removable; + keep-power-in-suspend; + status = "okay"; + + brcmf: bcrmf@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + }; +}; + +/* SD */ +&usdhc2 { + assigned-clocks = <&clk IMX8MN_CLK_USDHC2>; + assigned-clock-rates = <200000000>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; + cd-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + bus-width = <4>; + vmmc-supply = <®_usdhc2_vmmc>; + status = "okay"; +}; + +/* eMMC */ +&usdhc3 { + assigned-clocks = <&clk IMX8MN_CLK_USDHC3_ROOT>; + assigned-clock-rates = <400000000>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + 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 = < + MX8MN_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK 0x13 + MX8MN_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x13 + MX8MN_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x13 + MX8MN_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x13 + MX8MN_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x13 + >; + }; + + pinctrl_fec1: fec1grp { + fsl,pins = < + MX8MN_IOMUXC_ENET_MDC_ENET1_MDC 0x3 + MX8MN_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3 + MX8MN_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f + MX8MN_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f + MX8MN_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f + MX8MN_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f + MX8MN_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91 + MX8MN_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 + MX8MN_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 + MX8MN_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 + MX8MN_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f + MX8MN_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 + MX8MN_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 + MX8MN_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f + MX8MN_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 + >; + }; + + pinctrl_fec1_sleep: fec1sleepgrp { + fsl,pins = < + MX8MN_IOMUXC_ENET_MDC_GPIO1_IO16 0x120 + MX8MN_IOMUXC_ENET_MDIO_GPIO1_IO17 0x120 + MX8MN_IOMUXC_ENET_TD3_GPIO1_IO18 0x120 + MX8MN_IOMUXC_ENET_TD2_GPIO1_IO19 0x120 + MX8MN_IOMUXC_ENET_TD1_GPIO1_IO20 0x120 + MX8MN_IOMUXC_ENET_TD0_GPIO1_IO21 0x120 + MX8MN_IOMUXC_ENET_RD3_GPIO1_IO29 0x120 + MX8MN_IOMUXC_ENET_RD2_GPIO1_IO28 0x120 + MX8MN_IOMUXC_ENET_RD1_GPIO1_IO27 0x120 + MX8MN_IOMUXC_ENET_RD0_GPIO1_IO26 0x120 + MX8MN_IOMUXC_ENET_TXC_GPIO1_IO23 0x120 + MX8MN_IOMUXC_ENET_RXC_GPIO1_IO25 0x120 + MX8MN_IOMUXC_ENET_RX_CTL_GPIO1_IO24 0x120 + MX8MN_IOMUXC_ENET_TX_CTL_GPIO1_IO22 0x120 + MX8MN_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x120 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX8MN_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 + MX8MN_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX8MN_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3 + MX8MN_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3 + >; + }; + + pinctrl_pmic: pmicirqgrp { + fsl,pins = < + MX8MN_IOMUXC_SD1_DATA6_GPIO2_IO8 0x101 + >; + }; + + pinctrl_reg_eth_phy: regethphygrp { + fsl,pins = < + MX8MN_IOMUXC_SD1_DATA7_GPIO2_IO9 0x41 + >; + }; + + pinctrl_restouch: restouchgrp { + fsl,pins = < + MX8MN_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x1c0 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MN_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x140 + MX8MN_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x140 + MX8MN_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x140 + MX8MN_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x140 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX8MN_IOMUXC_UART4_RXD_UART4_DCE_RX 0x140 + MX8MN_IOMUXC_UART4_TXD_UART4_DCE_TX 0x140 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MN_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 + MX8MN_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 + MX8MN_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 + MX8MN_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 + MX8MN_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 + MX8MN_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 + >; + }; + + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { + fsl,pins = < + MX8MN_IOMUXC_SD1_CLK_USDHC1_CLK 0x194 + MX8MN_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4 + MX8MN_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d4 + MX8MN_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d4 + MX8MN_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d4 + MX8MN_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d4 + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { + fsl,pins = < + MX8MN_IOMUXC_SD1_CLK_USDHC1_CLK 0x196 + MX8MN_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6 + MX8MN_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d6 + MX8MN_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d6 + MX8MN_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d6 + MX8MN_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d6 + >; + }; + + pinctrl_usdhc2_gpio: usdhc2gpiogrp { + fsl,pins = < + MX8MN_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x41 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 + MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0 + MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0 + MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0 + MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0 + MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0 + MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { + fsl,pins = < + MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK 0x194 + MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4 + MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4 + MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4 + MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4 + MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4 + MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { + fsl,pins = < + MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK 0x196 + MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6 + MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6 + MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6 + MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6 + MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6 + MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190 + MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0 + MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0 + MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0 + MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0 + MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0 + MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d0 + MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d0 + MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d0 + MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d0 + MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x190 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp { + fsl,pins = < + MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194 + MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4 + MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d4 + MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d4 + MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d4 + MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d4 + MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d4 + MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d4 + MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d4 + MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d4 + MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x194 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { + fsl,pins = < + MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196 + MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6 + MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d6 + MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d6 + MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d6 + MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d6 + MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d6 + MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d6 + MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d6 + MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d6 + MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x196 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX8MN_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 + >; + }; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi index 9385dd7d1a2f..746faf1cf2fb 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi @@ -741,7 +741,8 @@ reg = <0x30be0000 0x10000>; interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MN_CLK_ENET1_ROOT>, <&clk IMX8MN_CLK_ENET1_ROOT>, <&clk IMX8MN_CLK_ENET_TIMER>, diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts index 3da1fff3d6fd..ad66f1286d95 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -124,8 +124,6 @@ }; &iomuxc { - pinctrl-names = "default"; - pinctrl_fec: fecgrp { fsl,pins = < MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x3 @@ -159,7 +157,7 @@ >; }; - pinctrl_reg_usdhc2_vmmc: regusdhc2vmmc { + pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { fsl,pins = < MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x41 >; @@ -184,7 +182,7 @@ >; }; - pinctrl_usdhc2_100mhz: usdhc2grp-100mhz { + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { fsl,pins = < MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x194 MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d4 @@ -196,7 +194,7 @@ >; }; - pinctrl_usdhc2_200mhz: usdhc2grp-200mhz { + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { fsl,pins = < MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x196 MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d6 @@ -208,7 +206,7 @@ >; }; - pinctrl_usdhc2_gpio: usdhc2grp-gpio { + pinctrl_usdhc2_gpio: usdhc2gpiogrp { fsl,pins = < MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x1c4 >; @@ -230,7 +228,7 @@ >; }; - pinctrl_usdhc3_100mhz: usdhc3grp-100mhz { + pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp { fsl,pins = < MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x194 MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d4 @@ -246,7 +244,7 @@ >; }; - pinctrl_usdhc3_200mhz: usdhc3grp-200mhz { + pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { fsl,pins = < MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x196 MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d6 diff --git a/arch/arm64/boot/dts/freescale/imx8mp-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mp-pinfunc.h index 319ab34cab3e..0fef066471ba 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-pinfunc.h +++ b/arch/arm64/boot/dts/freescale/imx8mp-pinfunc.h @@ -11,384 +11,318 @@ * <mux_reg conf_reg input_reg mux_mode input_val> */ #define MX8MP_IOMUXC_GPIO1_IO00__GPIO1_IO00 0x014 0x274 0x000 0x0 0x0 -#define MX8MP_IOMUXC_GPIO1_IO00__CCMSRCGPCMIX_ENET_PHY_REF_CLK_ROOT 0x014 0x274 0x000 0x1 0x0 -#define MX8MP_IOMUXC_GPIO1_IO00__MEDIAMIX_ISP_FL_TRIG_0 0x014 0x274 0x5D4 0x3 0x0 -#define MX8MP_IOMUXC_GPIO1_IO00__ANAMIX_REF_CLK_32K 0x014 0x274 0x000 0x5 0x0 -#define MX8MP_IOMUXC_GPIO1_IO00__CCMSRCGPCMIX_EXT_CLK1 0x014 0x274 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO00__SJC_FAIL 0x014 0x274 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO00__CCM_ENET_PHY_REF_CLK_ROOT 0x014 0x274 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO00__ISP_FL_TRIG_0 0x014 0x274 0x5D4 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO00__CCM_EXT_CLK1 0x014 0x274 0x000 0x6 0x0 #define MX8MP_IOMUXC_GPIO1_IO01__GPIO1_IO01 0x018 0x278 0x000 0x0 0x0 #define MX8MP_IOMUXC_GPIO1_IO01__PWM1_OUT 0x018 0x278 0x000 0x1 0x0 -#define MX8MP_IOMUXC_GPIO1_IO01__MEDIAMIX_ISP_SHUTTER_TRIG_0 0x018 0x278 0x5DC 0x3 0x0 -#define MX8MP_IOMUXC_GPIO1_IO01__ANAMIX_REF_CLK_24M 0x018 0x278 0x000 0x5 0x0 -#define MX8MP_IOMUXC_GPIO1_IO01__CCMSRCGPCMIX_EXT_CLK2 0x018 0x278 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO01__SJC_ACTIVE 0x018 0x278 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO01__ISP_SHUTTER_TRIG_0 0x018 0x278 0x5DC 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO01__CCM_EXT_CLK2 0x018 0x278 0x000 0x6 0x0 #define MX8MP_IOMUXC_GPIO1_IO02__GPIO1_IO02 0x01C 0x27C 0x000 0x0 0x0 #define MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0x01C 0x27C 0x000 0x1 0x0 -#define MX8MP_IOMUXC_GPIO1_IO02__MEDIAMIX_ISP_FLASH_TRIG_0 0x01C 0x27C 0x000 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO02__ISP_FLASH_TRIG_0 0x01C 0x27C 0x000 0x3 0x0 #define MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_ANY 0x01C 0x27C 0x000 0x5 0x0 #define MX8MP_IOMUXC_GPIO1_IO02__SJC_DE_B 0x01C 0x27C 0x000 0x7 0x0 #define MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03 0x020 0x280 0x000 0x0 0x0 #define MX8MP_IOMUXC_GPIO1_IO03__USDHC1_VSELECT 0x020 0x280 0x000 0x1 0x0 -#define MX8MP_IOMUXC_GPIO1_IO03__MEDIAMIX_ISP_PRELIGHT_TRIG_0 0x020 0x280 0x000 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO03__ISP_PRELIGHT_TRIG_0 0x020 0x280 0x000 0x3 0x0 #define MX8MP_IOMUXC_GPIO1_IO03__SDMA1_EXT_EVENT00 0x020 0x280 0x000 0x5 0x0 -#define MX8MP_IOMUXC_GPIO1_IO03__ANAMIX_XTAL_OK 0x020 0x280 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO03__SJC_DONE 0x020 0x280 0x000 0x7 0x0 #define MX8MP_IOMUXC_GPIO1_IO04__GPIO1_IO04 0x024 0x284 0x000 0x0 0x0 #define MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0x024 0x284 0x000 0x1 0x0 -#define MX8MP_IOMUXC_GPIO1_IO04__MEDIAMIX_ISP_SHUTTER_OPEN_0 0x024 0x284 0x000 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO04__ISP_SHUTTER_OPEN_0 0x024 0x284 0x000 0x3 0x0 #define MX8MP_IOMUXC_GPIO1_IO04__SDMA1_EXT_EVENT01 0x024 0x284 0x000 0x5 0x0 -#define MX8MP_IOMUXC_GPIO1_IO04__ANAMIX_XTAL_OK_LV 0x024 0x284 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO04__USDHC1_TEST_TRIG 0x024 0x284 0x000 0x7 0x0 #define MX8MP_IOMUXC_GPIO1_IO05__GPIO1_IO05 0x028 0x288 0x000 0x0 0x0 #define MX8MP_IOMUXC_GPIO1_IO05__M7_NMI 0x028 0x288 0x000 0x1 0x0 -#define MX8MP_IOMUXC_GPIO1_IO05__MEDIAMIX_ISP_FL_TRIG_1 0x028 0x288 0x5D8 0x3 0x0 -#define MX8MP_IOMUXC_GPIO1_IO05__CCMSRCGPCMIX_PMIC_READY 0x028 0x288 0x554 0x5 0x0 -#define MX8MP_IOMUXC_GPIO1_IO05__CCMSRCGPCMIX_INT_BOOT 0x028 0x288 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO05__USDHC2_TEST_TRIG 0x028 0x288 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO05__ISP_FL_TRIG_1 0x028 0x288 0x5D8 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO05__CCM_PMIC_READY 0x028 0x288 0x554 0x5 0x0 #define MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06 0x02C 0x28C 0x000 0x0 0x0 #define MX8MP_IOMUXC_GPIO1_IO06__ENET_QOS_MDC 0x02C 0x28C 0x000 0x1 0x0 -#define MX8MP_IOMUXC_GPIO1_IO06__MEDIAMIX_ISP_SHUTTER_TRIG_1 0x02C 0x28C 0x5E0 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO06__ISP_SHUTTER_TRIG_1 0x02C 0x28C 0x5E0 0x3 0x0 #define MX8MP_IOMUXC_GPIO1_IO06__USDHC1_CD_B 0x02C 0x28C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_GPIO1_IO06__CCMSRCGPCMIX_EXT_CLK3 0x02C 0x28C 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO06__ECSPI1_TEST_TRIG 0x02C 0x28C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO06__CCM_EXT_CLK3 0x02C 0x28C 0x000 0x6 0x0 #define MX8MP_IOMUXC_GPIO1_IO07__GPIO1_IO07 0x030 0x290 0x000 0x0 0x0 #define MX8MP_IOMUXC_GPIO1_IO07__ENET_QOS_MDIO 0x030 0x290 0x590 0x1 0x0 -#define MX8MP_IOMUXC_GPIO1_IO07__MEDIAMIX_ISP_FLASH_TRIG_1 0x030 0x290 0x000 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO07__ISP_FLASH_TRIG_1 0x030 0x290 0x000 0x3 0x0 #define MX8MP_IOMUXC_GPIO1_IO07__USDHC1_WP 0x030 0x290 0x000 0x5 0x0 -#define MX8MP_IOMUXC_GPIO1_IO07__CCMSRCGPCMIX_EXT_CLK4 0x030 0x290 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO07__ECSPI2_TEST_TRIG 0x030 0x290 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO07__CCM_EXT_CLK4 0x030 0x290 0x000 0x6 0x0 #define MX8MP_IOMUXC_GPIO1_IO08__GPIO1_IO08 0x034 0x294 0x000 0x0 0x0 #define MX8MP_IOMUXC_GPIO1_IO08__ENET_QOS_1588_EVENT0_IN 0x034 0x294 0x000 0x1 0x0 #define MX8MP_IOMUXC_GPIO1_IO08__PWM1_OUT 0x034 0x294 0x000 0x2 0x0 -#define MX8MP_IOMUXC_GPIO1_IO08__MEDIAMIX_ISP_PRELIGHT_TRIG_1 0x034 0x294 0x000 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO08__ISP_PRELIGHT_TRIG_1 0x034 0x294 0x000 0x3 0x0 #define MX8MP_IOMUXC_GPIO1_IO08__ENET_QOS_1588_EVENT0_AUX_IN 0x034 0x294 0x000 0x4 0x0 #define MX8MP_IOMUXC_GPIO1_IO08__USDHC2_RESET_B 0x034 0x294 0x000 0x5 0x0 -#define MX8MP_IOMUXC_GPIO1_IO08__CCMSRCGPCMIX_WAIT 0x034 0x294 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO08__FLEXSPI_TEST_TRIG 0x034 0x294 0x000 0x7 0x0 #define MX8MP_IOMUXC_GPIO1_IO09__GPIO1_IO09 0x038 0x298 0x000 0x0 0x0 #define MX8MP_IOMUXC_GPIO1_IO09__ENET_QOS_1588_EVENT0_OUT 0x038 0x298 0x000 0x1 0x0 #define MX8MP_IOMUXC_GPIO1_IO09__PWM2_OUT 0x038 0x298 0x000 0x2 0x0 -#define MX8MP_IOMUXC_GPIO1_IO09__MEDIAMIX_ISP_SHUTTER_OPEN_1 0x038 0x298 0x000 0x3 0x0 +#define MX8MP_IOMUXC_GPIO1_IO09__ISP_SHUTTER_OPEN_1 0x038 0x298 0x000 0x3 0x0 #define MX8MP_IOMUXC_GPIO1_IO09__USDHC3_RESET_B 0x038 0x298 0x000 0x4 0x0 -#define MX8MP_IOMUXC_GPIO1_IO09__AUDIOMIX_EXT_EVENT00 0x038 0x298 0x000 0x5 0x0 -#define MX8MP_IOMUXC_GPIO1_IO09__CCMSRCGPCMIX_STOP 0x038 0x298 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO09__RAWNAND_TEST_TRIG 0x038 0x298 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO09__SDMA2_EXT_EVENT00 0x038 0x298 0x000 0x5 0x0 #define MX8MP_IOMUXC_GPIO1_IO10__GPIO1_IO10 0x03C 0x29C 0x000 0x0 0x0 -#define MX8MP_IOMUXC_GPIO1_IO10__HSIOMIX_usb1_OTG_ID 0x03C 0x29C 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO10__USB1_OTG_ID 0x03C 0x29C 0x000 0x1 0x0 #define MX8MP_IOMUXC_GPIO1_IO10__PWM3_OUT 0x03C 0x29C 0x000 0x2 0x0 -#define MX8MP_IOMUXC_GPIO1_IO10__OCOTP_FUSE_LATCHED 0x03C 0x29C 0x000 0x7 0x0 #define MX8MP_IOMUXC_GPIO1_IO11__GPIO1_IO11 0x040 0x2A0 0x000 0x0 0x0 -#define MX8MP_IOMUXC_GPIO1_IO11__HSIOMIX_usb2_OTG_ID 0x040 0x2A0 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO11__USB2_OTG_ID 0x040 0x2A0 0x000 0x1 0x0 #define MX8MP_IOMUXC_GPIO1_IO11__PWM2_OUT 0x040 0x2A0 0x000 0x2 0x0 #define MX8MP_IOMUXC_GPIO1_IO11__USDHC3_VSELECT 0x040 0x2A0 0x000 0x4 0x0 -#define MX8MP_IOMUXC_GPIO1_IO11__CCMSRCGPCMIX_PMIC_READY 0x040 0x2A0 0x554 0x5 0x1 -#define MX8MP_IOMUXC_GPIO1_IO11__CCMSRCGPCMIX_OUT0 0x040 0x2A0 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO11__CAAM_RNG_OSC_OBS 0x040 0x2A0 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO11__CCM_PMIC_READY 0x040 0x2A0 0x554 0x5 0x1 #define MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12 0x044 0x2A4 0x000 0x0 0x0 -#define MX8MP_IOMUXC_GPIO1_IO12__HSIOMIX_usb1_OTG_PWR 0x044 0x2A4 0x000 0x1 0x0 -#define MX8MP_IOMUXC_GPIO1_IO12__AUDIOMIX_EXT_EVENT01 0x044 0x2A4 0x000 0x5 0x0 -#define MX8MP_IOMUXC_GPIO1_IO12__CCMSRCGPCMIX_OUT1 0x044 0x2A4 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO12__CSU_CSU_ALARM_AUT00 0x044 0x2A4 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO12__USB1_OTG_PWR 0x044 0x2A4 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO12__SDMA2_EXT_EVENT01 0x044 0x2A4 0x000 0x5 0x0 #define MX8MP_IOMUXC_GPIO1_IO13__GPIO1_IO13 0x048 0x2A8 0x000 0x0 0x0 -#define MX8MP_IOMUXC_GPIO1_IO13__HSIOMIX_usb1_OTG_OC 0x048 0x2A8 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO13__USB1_OTG_OC 0x048 0x2A8 0x000 0x1 0x0 #define MX8MP_IOMUXC_GPIO1_IO13__PWM2_OUT 0x048 0x2A8 0x000 0x5 0x0 -#define MX8MP_IOMUXC_GPIO1_IO13__CCMSRCGPCMIX_OUT2 0x048 0x2A8 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO13__CSU_CSU_ALARM_AUT01 0x048 0x2A8 0x000 0x7 0x0 #define MX8MP_IOMUXC_GPIO1_IO14__GPIO1_IO14 0x04C 0x2AC 0x000 0x0 0x0 -#define MX8MP_IOMUXC_GPIO1_IO14__HSIOMIX_usb2_OTG_PWR 0x04C 0x2AC 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR 0x04C 0x2AC 0x000 0x1 0x0 #define MX8MP_IOMUXC_GPIO1_IO14__USDHC3_CD_B 0x04C 0x2AC 0x608 0x4 0x0 #define MX8MP_IOMUXC_GPIO1_IO14__PWM3_OUT 0x04C 0x2AC 0x000 0x5 0x0 -#define MX8MP_IOMUXC_GPIO1_IO14__CCMSRCGPCMIX_CLKO1 0x04C 0x2AC 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO14__CSU_CSU_ALARM_AUT02 0x04C 0x2AC 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO14__CCM_CLKO1 0x04C 0x2AC 0x000 0x6 0x0 #define MX8MP_IOMUXC_GPIO1_IO15__GPIO1_IO15 0x050 0x2B0 0x000 0x0 0x0 -#define MX8MP_IOMUXC_GPIO1_IO15__HSIOMIX_usb2_OTG_OC 0x050 0x2B0 0x000 0x1 0x0 +#define MX8MP_IOMUXC_GPIO1_IO15__USB2_OTG_OC 0x050 0x2B0 0x000 0x1 0x0 #define MX8MP_IOMUXC_GPIO1_IO15__USDHC3_WP 0x050 0x2B0 0x634 0x4 0x0 #define MX8MP_IOMUXC_GPIO1_IO15__PWM4_OUT 0x050 0x2B0 0x000 0x5 0x0 -#define MX8MP_IOMUXC_GPIO1_IO15__CCMSRCGPCMIX_CLKO2 0x050 0x2B0 0x000 0x6 0x0 -#define MX8MP_IOMUXC_GPIO1_IO15__CSU_CSU_INT_DEB 0x050 0x2B0 0x000 0x7 0x0 +#define MX8MP_IOMUXC_GPIO1_IO15__CCM_CLKO2 0x050 0x2B0 0x000 0x6 0x0 #define MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x054 0x2B4 0x000 0x0 0x0 #define MX8MP_IOMUXC_ENET_MDC__AUDIOMIX_SAI6_TX_DATA00 0x054 0x2B4 0x000 0x2 0x0 #define MX8MP_IOMUXC_ENET_MDC__GPIO1_IO16 0x054 0x2B4 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_MDC__USDHC3_STROBE 0x054 0x2B4 0x630 0x6 0x0 -#define MX8MP_IOMUXC_ENET_MDC__SIM_M_HADDR15 0x054 0x2B4 0x000 0x7 0x0 #define MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x058 0x2B8 0x590 0x0 0x1 #define MX8MP_IOMUXC_ENET_MDIO__AUDIOMIX_SAI6_TX_SYNC 0x058 0x2B8 0x528 0x2 0x0 +#define MX8MP_IOMUXC_ENET_MDIO__AUDIOMIX_PDM_BIT_STREAM03 0x058 0x2B8 0x4CC 0x3 0x0 #define MX8MP_IOMUXC_ENET_MDIO__GPIO1_IO17 0x058 0x2B8 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_MDIO__USDHC3_DATA5 0x058 0x2B8 0x624 0x6 0x0 -#define MX8MP_IOMUXC_ENET_MDIO__SIM_M_HADDR16 0x058 0x2B8 0x000 0x7 0x0 #define MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x05C 0x2BC 0x000 0x0 0x0 #define MX8MP_IOMUXC_ENET_TD3__AUDIOMIX_SAI6_TX_BCLK 0x05C 0x2BC 0x524 0x2 0x0 +#define MX8MP_IOMUXC_ENET_TD3__AUDIOMIX_PDM_BIT_STREAM02 0x05C 0x2BC 0x4C8 0x3 0x0 #define MX8MP_IOMUXC_ENET_TD3__GPIO1_IO18 0x05C 0x2BC 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_TD3__USDHC3_DATA6 0x05C 0x2BC 0x628 0x6 0x0 -#define MX8MP_IOMUXC_ENET_TD3__SIM_M_HADDR17 0x05C 0x2BC 0x000 0x7 0x0 #define MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x060 0x2C0 0x000 0x0 0x0 #define MX8MP_IOMUXC_ENET_TD2__CCM_ENET_QOS_CLOCK_GENERATE_REF_CLK 0x060 0x2C0 0x000 0x1 0x0 #define MX8MP_IOMUXC_ENET_TD2__AUDIOMIX_SAI6_RX_DATA00 0x060 0x2C0 0x51C 0x2 0x0 +#define MX8MP_IOMUXC_ENET_TD2__AUDIOMIX_PDM_BIT_STREAM01 0x060 0x2C0 0x4C4 0x3 0x0 #define MX8MP_IOMUXC_ENET_TD2__GPIO1_IO19 0x060 0x2C0 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_TD2__USDHC3_DATA7 0x060 0x2C0 0x62C 0x6 0x0 -#define MX8MP_IOMUXC_ENET_TD2__SIM_M_HADDR18 0x060 0x2C0 0x000 0x7 0x0 #define MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x064 0x2C4 0x000 0x0 0x0 #define MX8MP_IOMUXC_ENET_TD1__AUDIOMIX_SAI6_RX_SYNC 0x064 0x2C4 0x520 0x2 0x0 +#define MX8MP_IOMUXC_ENET_TD1__AUDIOMIX_PDM_BIT_STREAM00 0x064 0x2C4 0x4C0 0x3 0x0 #define MX8MP_IOMUXC_ENET_TD1__GPIO1_IO20 0x064 0x2C4 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_TD1__USDHC3_CD_B 0x064 0x2C4 0x608 0x6 0x1 -#define MX8MP_IOMUXC_ENET_TD1__SIM_M_HADDR19 0x064 0x2C4 0x000 0x7 0x0 #define MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x068 0x2C8 0x000 0x0 0x0 #define MX8MP_IOMUXC_ENET_TD0__AUDIOMIX_SAI6_RX_BCLK 0x068 0x2C8 0x518 0x2 0x0 +#define MX8MP_IOMUXC_ENET_TD0__AUDIOMIX_PDM_CLK 0x068 0x2C8 0x000 0x3 0x0 #define MX8MP_IOMUXC_ENET_TD0__GPIO1_IO21 0x068 0x2C8 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_TD0__USDHC3_WP 0x068 0x2C8 0x634 0x6 0x1 -#define MX8MP_IOMUXC_ENET_TD0__SIM_M_HADDR20 0x068 0x2C8 0x000 0x7 0x0 #define MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x06C 0x2CC 0x000 0x0 0x0 #define MX8MP_IOMUXC_ENET_TX_CTL__AUDIOMIX_SAI6_MCLK 0x06C 0x2CC 0x514 0x2 0x0 -#define MX8MP_IOMUXC_ENET_TX_CTL__AUDIOMIX_SPDIF_OUT 0x06C 0x2CC 0x000 0x3 0x0 +#define MX8MP_IOMUXC_ENET_TX_CTL__AUDIOMIX_SPDIF1_OUT 0x06C 0x2CC 0x000 0x3 0x0 #define MX8MP_IOMUXC_ENET_TX_CTL__GPIO1_IO22 0x06C 0x2CC 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_TX_CTL__USDHC3_DATA0 0x06C 0x2CC 0x610 0x6 0x0 -#define MX8MP_IOMUXC_ENET_TX_CTL__SIM_M_HADDR21 0x06C 0x2CC 0x000 0x7 0x0 #define MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x070 0x2D0 0x000 0x0 0x0 #define MX8MP_IOMUXC_ENET_TXC__ENET_QOS_TX_ER 0x070 0x2D0 0x000 0x1 0x0 #define MX8MP_IOMUXC_ENET_TXC__AUDIOMIX_SAI7_TX_DATA00 0x070 0x2D0 0x000 0x2 0x0 #define MX8MP_IOMUXC_ENET_TXC__GPIO1_IO23 0x070 0x2D0 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_TXC__USDHC3_DATA1 0x070 0x2D0 0x614 0x6 0x0 -#define MX8MP_IOMUXC_ENET_TXC__SIM_M_HADDR22 0x070 0x2D0 0x000 0x7 0x0 #define MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x074 0x2D4 0x000 0x0 0x0 #define MX8MP_IOMUXC_ENET_RX_CTL__AUDIOMIX_SAI7_TX_SYNC 0x074 0x2D4 0x540 0x2 0x0 -#define MX8MP_IOMUXC_ENET_RX_CTL__AUDIOMIX_BIT_STREAM03 0x074 0x2D4 0x4CC 0x3 0x1 +#define MX8MP_IOMUXC_ENET_RX_CTL__AUDIOMIX_PDM_BIT_STREAM03 0x074 0x2D4 0x4CC 0x3 0x1 #define MX8MP_IOMUXC_ENET_RX_CTL__GPIO1_IO24 0x074 0x2D4 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_RX_CTL__USDHC3_DATA2 0x074 0x2D4 0x618 0x6 0x0 -#define MX8MP_IOMUXC_ENET_RX_CTL__SIM_M_HADDR23 0x074 0x2D4 0x000 0x7 0x0 #define MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x078 0x2D8 0x000 0x0 0x0 #define MX8MP_IOMUXC_ENET_RXC__ENET_QOS_RX_ER 0x078 0x2D8 0x000 0x1 0x0 #define MX8MP_IOMUXC_ENET_RXC__AUDIOMIX_SAI7_TX_BCLK 0x078 0x2D8 0x53C 0x2 0x0 -#define MX8MP_IOMUXC_ENET_RXC__AUDIOMIX_BIT_STREAM02 0x078 0x2D8 0x4C8 0x3 0x1 +#define MX8MP_IOMUXC_ENET_RXC__AUDIOMIX_PDM_BIT_STREAM02 0x078 0x2D8 0x4C8 0x3 0x1 #define MX8MP_IOMUXC_ENET_RXC__GPIO1_IO25 0x078 0x2D8 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_RXC__USDHC3_DATA3 0x078 0x2D8 0x61C 0x6 0x0 -#define MX8MP_IOMUXC_ENET_RXC__SIM_M_HADDR24 0x078 0x2D8 0x000 0x7 0x0 #define MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x07C 0x2DC 0x000 0x0 0x0 #define MX8MP_IOMUXC_ENET_RD0__AUDIOMIX_SAI7_RX_DATA00 0x07C 0x2DC 0x534 0x2 0x0 -#define MX8MP_IOMUXC_ENET_RD0__AUDIOMIX_BIT_STREAM01 0x07C 0x2DC 0x4C4 0x3 0x1 +#define MX8MP_IOMUXC_ENET_RD0__AUDIOMIX_PDM_BIT_STREAM01 0x07C 0x2DC 0x4C4 0x3 0x1 #define MX8MP_IOMUXC_ENET_RD0__GPIO1_IO26 0x07C 0x2DC 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_RD0__USDHC3_DATA4 0x07C 0x2DC 0x620 0x6 0x0 -#define MX8MP_IOMUXC_ENET_RD0__SIM_M_HADDR25 0x07C 0x2DC 0x000 0x7 0x0 #define MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x080 0x2E0 0x000 0x0 0x0 #define MX8MP_IOMUXC_ENET_RD1__AUDIOMIX_SAI7_RX_SYNC 0x080 0x2E0 0x538 0x2 0x0 -#define MX8MP_IOMUXC_ENET_RD1__AUDIOMIX_BIT_STREAM00 0x080 0x2E0 0x4C0 0x3 0x1 +#define MX8MP_IOMUXC_ENET_RD1__AUDIOMIX_PDM_BIT_STREAM00 0x080 0x2E0 0x4C0 0x3 0x1 #define MX8MP_IOMUXC_ENET_RD1__GPIO1_IO27 0x080 0x2E0 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_RD1__USDHC3_RESET_B 0x080 0x2E0 0x000 0x6 0x0 -#define MX8MP_IOMUXC_ENET_RD1__SIM_M_HADDR26 0x080 0x2E0 0x000 0x7 0x0 #define MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x084 0x2E4 0x000 0x0 0x0 #define MX8MP_IOMUXC_ENET_RD2__AUDIOMIX_SAI7_RX_BCLK 0x084 0x2E4 0x530 0x2 0x0 -#define MX8MP_IOMUXC_ENET_RD2__AUDIOMIX_CLK 0x084 0x2E4 0x000 0x3 0x0 +#define MX8MP_IOMUXC_ENET_RD2__AUDIOMIX_PDM_CLK 0x084 0x2E4 0x000 0x3 0x0 #define MX8MP_IOMUXC_ENET_RD2__GPIO1_IO28 0x084 0x2E4 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_RD2__USDHC3_CLK 0x084 0x2E4 0x604 0x6 0x0 -#define MX8MP_IOMUXC_ENET_RD2__SIM_M_HADDR27 0x084 0x2E4 0x000 0x7 0x0 #define MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x088 0x2E8 0x000 0x0 0x0 #define MX8MP_IOMUXC_ENET_RD3__AUDIOMIX_SAI7_MCLK 0x088 0x2E8 0x52C 0x2 0x0 -#define MX8MP_IOMUXC_ENET_RD3__AUDIOMIX_SPDIF_IN 0x088 0x2E8 0x544 0x3 0x0 +#define MX8MP_IOMUXC_ENET_RD3__AUDIOMIX_SPDIF1_IN 0x088 0x2E8 0x544 0x3 0x0 #define MX8MP_IOMUXC_ENET_RD3__GPIO1_IO29 0x088 0x2E8 0x000 0x5 0x0 #define MX8MP_IOMUXC_ENET_RD3__USDHC3_CMD 0x088 0x2E8 0x60C 0x6 0x0 -#define MX8MP_IOMUXC_ENET_RD3__SIM_M_HADDR28 0x088 0x2E8 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x08C 0x2EC 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD1_CLK__ENET1_MDC 0x08C 0x2EC 0x000 0x1 0x0 #define MX8MP_IOMUXC_SD1_CLK__I2C5_SCL 0x08C 0x2EC 0x5C4 0x3 0x0 #define MX8MP_IOMUXC_SD1_CLK__UART1_DCE_TX 0x08C 0x2EC 0x000 0x4 0x0 #define MX8MP_IOMUXC_SD1_CLK__UART1_DTE_RX 0x08C 0x2EC 0x5E8 0x4 0x0 #define MX8MP_IOMUXC_SD1_CLK__GPIO2_IO00 0x08C 0x2EC 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD1_CLK__SIM_M_HADDR29 0x08C 0x2EC 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x090 0x2F0 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD1_CMD__ENET1_MDIO 0x090 0x2F0 0x57C 0x1 0x0 #define MX8MP_IOMUXC_SD1_CMD__I2C5_SDA 0x090 0x2F0 0x5C8 0x3 0x0 #define MX8MP_IOMUXC_SD1_CMD__UART1_DCE_RX 0x090 0x2F0 0x5E8 0x4 0x1 #define MX8MP_IOMUXC_SD1_CMD__UART1_DTE_TX 0x090 0x2F0 0x000 0x4 0x0 #define MX8MP_IOMUXC_SD1_CMD__GPIO2_IO01 0x090 0x2F0 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD1_CMD__SIM_M_HADDR30 0x090 0x2F0 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x094 0x2F4 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD1_DATA0__ENET1_RGMII_TD1 0x094 0x2F4 0x000 0x1 0x0 #define MX8MP_IOMUXC_SD1_DATA0__I2C6_SCL 0x094 0x2F4 0x5CC 0x3 0x0 #define MX8MP_IOMUXC_SD1_DATA0__UART1_DCE_RTS 0x094 0x2F4 0x5E4 0x4 0x0 #define MX8MP_IOMUXC_SD1_DATA0__UART1_DTE_CTS 0x094 0x2F4 0x000 0x4 0x0 #define MX8MP_IOMUXC_SD1_DATA0__GPIO2_IO02 0x094 0x2F4 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD1_DATA0__SIM_M_HADDR31 0x094 0x2F4 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x098 0x2F8 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD1_DATA1__ENET1_RGMII_TD0 0x098 0x2F8 0x000 0x1 0x0 #define MX8MP_IOMUXC_SD1_DATA1__I2C6_SDA 0x098 0x2F8 0x5D0 0x3 0x0 #define MX8MP_IOMUXC_SD1_DATA1__UART1_DCE_CTS 0x098 0x2F8 0x000 0x4 0x0 #define MX8MP_IOMUXC_SD1_DATA1__UART1_DTE_RTS 0x098 0x2F8 0x5E4 0x4 0x1 #define MX8MP_IOMUXC_SD1_DATA1__GPIO2_IO03 0x098 0x2F8 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD1_DATA1__SIM_M_HBURST00 0x098 0x2F8 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x09C 0x2FC 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD1_DATA2__ENET1_RGMII_RD0 0x09C 0x2FC 0x580 0x1 0x0 #define MX8MP_IOMUXC_SD1_DATA2__I2C4_SCL 0x09C 0x2FC 0x5BC 0x3 0x0 #define MX8MP_IOMUXC_SD1_DATA2__UART2_DCE_TX 0x09C 0x2FC 0x000 0x4 0x0 #define MX8MP_IOMUXC_SD1_DATA2__UART2_DTE_RX 0x09C 0x2FC 0x5F0 0x4 0x0 #define MX8MP_IOMUXC_SD1_DATA2__GPIO2_IO04 0x09C 0x2FC 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD1_DATA2__SIM_M_HBURST01 0x09C 0x2FC 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x0A0 0x300 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD1_DATA3__ENET1_RGMII_RD1 0x0A0 0x300 0x584 0x1 0x0 #define MX8MP_IOMUXC_SD1_DATA3__I2C4_SDA 0x0A0 0x300 0x5C0 0x3 0x0 #define MX8MP_IOMUXC_SD1_DATA3__UART2_DCE_RX 0x0A0 0x300 0x5F0 0x4 0x1 #define MX8MP_IOMUXC_SD1_DATA3__UART2_DTE_TX 0x0A0 0x300 0x000 0x4 0x0 #define MX8MP_IOMUXC_SD1_DATA3__GPIO2_IO05 0x0A0 0x300 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD1_DATA3__SIM_M_HBURST02 0x0A0 0x300 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD1_DATA4__USDHC1_DATA4 0x0A4 0x304 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD1_DATA4__ENET1_RGMII_TX_CTL 0x0A4 0x304 0x000 0x1 0x0 #define MX8MP_IOMUXC_SD1_DATA4__I2C1_SCL 0x0A4 0x304 0x5A4 0x3 0x0 #define MX8MP_IOMUXC_SD1_DATA4__UART2_DCE_RTS 0x0A4 0x304 0x5EC 0x4 0x0 #define MX8MP_IOMUXC_SD1_DATA4__UART2_DTE_CTS 0x0A4 0x304 0x000 0x4 0x0 #define MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06 0x0A4 0x304 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD1_DATA4__SIM_M_HRESP 0x0A4 0x304 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD1_DATA5__USDHC1_DATA5 0x0A8 0x308 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD1_DATA5__ENET1_TX_ER 0x0A8 0x308 0x000 0x1 0x0 #define MX8MP_IOMUXC_SD1_DATA5__I2C1_SDA 0x0A8 0x308 0x5A8 0x3 0x0 #define MX8MP_IOMUXC_SD1_DATA5__UART2_DCE_CTS 0x0A8 0x308 0x000 0x4 0x0 #define MX8MP_IOMUXC_SD1_DATA5__UART2_DTE_RTS 0x0A8 0x308 0x5EC 0x4 0x1 #define MX8MP_IOMUXC_SD1_DATA5__GPIO2_IO07 0x0A8 0x308 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD1_DATA5__TPSMP_HDATA05 0x0A8 0x308 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD1_DATA6__USDHC1_DATA6 0x0AC 0x30C 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD1_DATA6__ENET1_RGMII_RX_CTL 0x0AC 0x30C 0x588 0x1 0x0 #define MX8MP_IOMUXC_SD1_DATA6__I2C2_SCL 0x0AC 0x30C 0x5AC 0x3 0x0 #define MX8MP_IOMUXC_SD1_DATA6__UART3_DCE_TX 0x0AC 0x30C 0x000 0x4 0x0 #define MX8MP_IOMUXC_SD1_DATA6__UART3_DTE_RX 0x0AC 0x30C 0x5F8 0x4 0x0 #define MX8MP_IOMUXC_SD1_DATA6__GPIO2_IO08 0x0AC 0x30C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD1_DATA6__TPSMP_HDATA06 0x0AC 0x30C 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD1_DATA7__USDHC1_DATA7 0x0B0 0x310 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD1_DATA7__ENET1_RX_ER 0x0B0 0x310 0x58C 0x1 0x0 #define MX8MP_IOMUXC_SD1_DATA7__I2C2_SDA 0x0B0 0x310 0x5B0 0x3 0x0 #define MX8MP_IOMUXC_SD1_DATA7__UART3_DCE_RX 0x0B0 0x310 0x5F8 0x4 0x1 #define MX8MP_IOMUXC_SD1_DATA7__UART3_DTE_TX 0x0B0 0x310 0x000 0x4 0x0 #define MX8MP_IOMUXC_SD1_DATA7__GPIO2_IO09 0x0B0 0x310 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD1_DATA7__TPSMP_HDATA07 0x0B0 0x310 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD1_RESET_B__USDHC1_RESET_B 0x0B4 0x314 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD1_RESET_B__ENET1_TX_CLK 0x0B4 0x314 0x578 0x1 0x0 #define MX8MP_IOMUXC_SD1_RESET_B__I2C3_SCL 0x0B4 0x314 0x5B4 0x3 0x0 #define MX8MP_IOMUXC_SD1_RESET_B__UART3_DCE_RTS 0x0B4 0x314 0x5F4 0x4 0x0 #define MX8MP_IOMUXC_SD1_RESET_B__UART3_DTE_CTS 0x0B4 0x314 0x000 0x4 0x0 #define MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10 0x0B4 0x314 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD1_RESET_B__ECSPI3_TEST_TRIG 0x0B4 0x314 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD1_STROBE__USDHC1_STROBE 0x0B8 0x318 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD1_STROBE__I2C3_SDA 0x0B8 0x318 0x5B8 0x3 0x0 #define MX8MP_IOMUXC_SD1_STROBE__UART3_DCE_CTS 0x0B8 0x318 0x000 0x4 0x0 #define MX8MP_IOMUXC_SD1_STROBE__UART3_DTE_RTS 0x0B8 0x318 0x5F4 0x4 0x1 #define MX8MP_IOMUXC_SD1_STROBE__GPIO2_IO11 0x0B8 0x318 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD1_STROBE__USDHC3_TEST_TRIG 0x0B8 0x318 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD2_CD_B__USDHC2_CD_B 0x0BC 0x31C 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x0BC 0x31C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD2_CD_B__CCMSRCGPCMIX_TESTER_ACK 0x0BC 0x31C 0x000 0x6 0x0 #define MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x0C0 0x320 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD2_CLK__ECSPI2_SCLK 0x0C0 0x320 0x568 0x2 0x0 #define MX8MP_IOMUXC_SD2_CLK__UART4_DCE_RX 0x0C0 0x320 0x600 0x3 0x0 #define MX8MP_IOMUXC_SD2_CLK__UART4_DTE_TX 0x0C0 0x320 0x000 0x3 0x0 #define MX8MP_IOMUXC_SD2_CLK__GPIO2_IO13 0x0C0 0x320 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD2_CLK__CCMSRCGPCMIX_OBSERVE0 0x0C0 0x320 0x000 0x6 0x0 -#define MX8MP_IOMUXC_SD2_CLK__OBSERVE_MUX_OUT00 0x0C0 0x320 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x0C4 0x324 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD2_CMD__ECSPI2_MOSI 0x0C4 0x324 0x570 0x2 0x0 #define MX8MP_IOMUXC_SD2_CMD__UART4_DCE_TX 0x0C4 0x324 0x000 0x3 0x0 #define MX8MP_IOMUXC_SD2_CMD__UART4_DTE_RX 0x0C4 0x324 0x600 0x3 0x1 -#define MX8MP_IOMUXC_SD2_CMD__AUDIOMIX_CLK 0x0C4 0x324 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SD2_CMD__AUDIOMIX_PDM_CLK 0x0C4 0x324 0x000 0x4 0x0 #define MX8MP_IOMUXC_SD2_CMD__GPIO2_IO14 0x0C4 0x324 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD2_CMD__CCMSRCGPCMIX_OBSERVE1 0x0C4 0x324 0x000 0x6 0x0 -#define MX8MP_IOMUXC_SD2_CMD__OBSERVE_MUX_OUT01 0x0C4 0x324 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x0C8 0x328 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD2_DATA0__I2C4_SDA 0x0C8 0x328 0x5C0 0x2 0x1 #define MX8MP_IOMUXC_SD2_DATA0__UART2_DCE_RX 0x0C8 0x328 0x5F0 0x3 0x2 #define MX8MP_IOMUXC_SD2_DATA0__UART2_DTE_TX 0x0C8 0x328 0x000 0x3 0x0 -#define MX8MP_IOMUXC_SD2_DATA0__AUDIOMIX_BIT_STREAM00 0x0C8 0x328 0x4C0 0x4 0x2 +#define MX8MP_IOMUXC_SD2_DATA0__AUDIOMIX_PDM_BIT_STREAM00 0x0C8 0x328 0x4C0 0x4 0x2 #define MX8MP_IOMUXC_SD2_DATA0__GPIO2_IO15 0x0C8 0x328 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD2_DATA0__CCMSRCGPCMIX_OBSERVE2 0x0C8 0x328 0x000 0x6 0x0 -#define MX8MP_IOMUXC_SD2_DATA0__OBSERVE_MUX_OUT02 0x0C8 0x328 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x0CC 0x32C 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD2_DATA1__I2C4_SCL 0x0CC 0x32C 0x5BC 0x2 0x1 #define MX8MP_IOMUXC_SD2_DATA1__UART2_DCE_TX 0x0CC 0x32C 0x000 0x3 0x0 #define MX8MP_IOMUXC_SD2_DATA1__UART2_DTE_RX 0x0CC 0x32C 0x5F0 0x3 0x3 -#define MX8MP_IOMUXC_SD2_DATA1__AUDIOMIX_BIT_STREAM01 0x0CC 0x32C 0x4C4 0x4 0x1 +#define MX8MP_IOMUXC_SD2_DATA1__AUDIOMIX_PDM_BIT_STREAM01 0x0CC 0x32C 0x4C4 0x4 0x2 #define MX8MP_IOMUXC_SD2_DATA1__GPIO2_IO16 0x0CC 0x32C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD2_DATA1__CCMSRCGPCMIX_WAIT 0x0CC 0x32C 0x000 0x6 0x0 -#define MX8MP_IOMUXC_SD2_DATA1__OBSERVE_MUX_OUT03 0x0CC 0x32C 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x0D0 0x330 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD2_DATA2__ECSPI2_SS0 0x0D0 0x330 0x574 0x2 0x0 -#define MX8MP_IOMUXC_SD2_DATA2__AUDIOMIX_SPDIF_OUT 0x0D0 0x330 0x000 0x3 0x0 -#define MX8MP_IOMUXC_SD2_DATA2__AUDIOMIX_BIT_STREAM02 0x0D0 0x330 0x4C8 0x4 0x1 +#define MX8MP_IOMUXC_SD2_DATA2__AUDIOMIX_SPDIF1_OUT 0x0D0 0x330 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SD2_DATA2__AUDIOMIX_PDM_BIT_STREAM02 0x0D0 0x330 0x4C8 0x4 0x2 #define MX8MP_IOMUXC_SD2_DATA2__GPIO2_IO17 0x0D0 0x330 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD2_DATA2__CCMSRCGPCMIX_STOP 0x0D0 0x330 0x000 0x6 0x0 -#define MX8MP_IOMUXC_SD2_DATA2__OBSERVE_MUX_OUT04 0x0D0 0x330 0x000 0x7 0x0 #define MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x0D4 0x334 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD2_DATA3__ECSPI2_MISO 0x0D4 0x334 0x56C 0x2 0x0 -#define MX8MP_IOMUXC_SD2_DATA3__AUDIOMIX_SPDIF_IN 0x0D4 0x334 0x544 0x3 0x1 -#define MX8MP_IOMUXC_SD2_DATA3__AUDIOMIX_BIT_STREAM03 0x0D4 0x334 0x4CC 0x4 0x2 +#define MX8MP_IOMUXC_SD2_DATA3__AUDIOMIX_SPDIF1_IN 0x0D4 0x334 0x544 0x3 0x1 +#define MX8MP_IOMUXC_SD2_DATA3__AUDIOMIX_PDM_BIT_STREAM03 0x0D4 0x334 0x4CC 0x4 0x2 #define MX8MP_IOMUXC_SD2_DATA3__GPIO2_IO18 0x0D4 0x334 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD2_DATA3__CCMSRCGPCMIX_EARLY_RESET 0x0D4 0x334 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SD2_DATA3__SRC_EARLY_RESET 0x0D4 0x334 0x000 0x6 0x0 #define MX8MP_IOMUXC_SD2_RESET_B__USDHC2_RESET_B 0x0D8 0x338 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x0D8 0x338 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SD2_RESET_B__CCMSRCGPCMIX_SYSTEM_RESET 0x0D8 0x338 0x000 0x6 0x0 +#define MX8MP_IOMUXC_SD2_RESET_B__SRC_SYSTEM_RESET 0x0D8 0x338 0x000 0x6 0x0 #define MX8MP_IOMUXC_SD2_WP__USDHC2_WP 0x0DC 0x33C 0x000 0x0 0x0 #define MX8MP_IOMUXC_SD2_WP__GPIO2_IO20 0x0DC 0x33C 0x000 0x5 0x0 #define MX8MP_IOMUXC_SD2_WP__CORESIGHT_EVENTI 0x0DC 0x33C 0x000 0x6 0x0 -#define MX8MP_IOMUXC_SD2_WP__SIM_M_HMASTLOCK 0x0DC 0x33C 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_ALE__RAWNAND_ALE 0x0E0 0x340 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_ALE__NAND_ALE 0x0E0 0x340 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_ALE__FLEXSPI_A_SCLK 0x0E0 0x340 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_ALE__AUDIOMIX_SAI3_TX_BCLK 0x0E0 0x340 0x4E8 0x2 0x0 -#define MX8MP_IOMUXC_NAND_ALE__MEDIAMIX_ISP_FL_TRIG_0 0x0E0 0x340 0x5D4 0x3 0x1 +#define MX8MP_IOMUXC_NAND_ALE__ISP_FL_TRIG_0 0x0E0 0x340 0x5D4 0x3 0x1 #define MX8MP_IOMUXC_NAND_ALE__UART3_DCE_RX 0x0E0 0x340 0x5F8 0x4 0x2 #define MX8MP_IOMUXC_NAND_ALE__UART3_DTE_TX 0x0E0 0x340 0x000 0x4 0x0 #define MX8MP_IOMUXC_NAND_ALE__GPIO3_IO00 0x0E0 0x340 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_ALE__CORESIGHT_TRACE_CLK 0x0E0 0x340 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_ALE__SIM_M_HPROT00 0x0E0 0x340 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_CE0_B__RAWNAND_CE0_B 0x0E4 0x344 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_CE0_B__NAND_CE0_B 0x0E4 0x344 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_CE0_B__FLEXSPI_A_SS0_B 0x0E4 0x344 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_CE0_B__AUDIOMIX_SAI3_TX_DATA00 0x0E4 0x344 0x000 0x2 0x0 -#define MX8MP_IOMUXC_NAND_CE0_B__MEDIAMIX_ISP_SHUTTER_TRIG_0 0x0E4 0x344 0x5DC 0x3 0x1 +#define MX8MP_IOMUXC_NAND_CE0_B__ISP_SHUTTER_TRIG_0 0x0E4 0x344 0x5DC 0x3 0x1 #define MX8MP_IOMUXC_NAND_CE0_B__UART3_DCE_TX 0x0E4 0x344 0x000 0x4 0x0 #define MX8MP_IOMUXC_NAND_CE0_B__UART3_DTE_RX 0x0E4 0x344 0x5F8 0x4 0x3 #define MX8MP_IOMUXC_NAND_CE0_B__GPIO3_IO01 0x0E4 0x344 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_CE0_B__CORESIGHT_TRACE_CTL 0x0E4 0x344 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_CE0_B__SIM_M_HPROT01 0x0E4 0x344 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_CE1_B__RAWNAND_CE1_B 0x0E8 0x348 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_CE1_B__NAND_CE1_B 0x0E8 0x348 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_CE1_B__FLEXSPI_A_SS1_B 0x0E8 0x348 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x0E8 0x348 0x630 0x2 0x1 #define MX8MP_IOMUXC_NAND_CE1_B__I2C4_SCL 0x0E8 0x348 0x5BC 0x4 0x2 #define MX8MP_IOMUXC_NAND_CE1_B__GPIO3_IO02 0x0E8 0x348 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_CE1_B__CORESIGHT_TRACE00 0x0E8 0x348 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_CE1_B__SIM_M_HPROT02 0x0E8 0x348 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_CE2_B__RAWNAND_CE2_B 0x0EC 0x34C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_CE2_B__NAND_CE2_B 0x0EC 0x34C 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_CE2_B__FLEXSPI_B_SS0_B 0x0EC 0x34C 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x0EC 0x34C 0x624 0x2 0x1 #define MX8MP_IOMUXC_NAND_CE2_B__I2C4_SDA 0x0EC 0x34C 0x5C0 0x4 0x2 #define MX8MP_IOMUXC_NAND_CE2_B__GPIO3_IO03 0x0EC 0x34C 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_CE2_B__CORESIGHT_TRACE01 0x0EC 0x34C 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_CE2_B__SIM_M_HPROT03 0x0EC 0x34C 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_CE3_B__RAWNAND_CE3_B 0x0F0 0x350 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_CE3_B__NAND_CE3_B 0x0F0 0x350 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_CE3_B__FLEXSPI_B_SS1_B 0x0F0 0x350 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x0F0 0x350 0x628 0x2 0x1 #define MX8MP_IOMUXC_NAND_CE3_B__I2C3_SDA 0x0F0 0x350 0x5B8 0x4 0x1 #define MX8MP_IOMUXC_NAND_CE3_B__GPIO3_IO04 0x0F0 0x350 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_CE3_B__CORESIGHT_TRACE02 0x0F0 0x350 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_CE3_B__SIM_M_HADDR00 0x0F0 0x350 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_CLE__RAWNAND_CLE 0x0F4 0x354 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_CLE__NAND_CLE 0x0F4 0x354 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_CLE__FLEXSPI_B_SCLK 0x0F4 0x354 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x0F4 0x354 0x62C 0x2 0x1 #define MX8MP_IOMUXC_NAND_CLE__UART4_DCE_RX 0x0F4 0x354 0x600 0x4 0x2 #define MX8MP_IOMUXC_NAND_CLE__UART4_DTE_TX 0x0F4 0x354 0x000 0x4 0x0 #define MX8MP_IOMUXC_NAND_CLE__GPIO3_IO05 0x0F4 0x354 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_CLE__CORESIGHT_TRACE03 0x0F4 0x354 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_CLE__SIM_M_HADDR01 0x0F4 0x354 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_DATA00__RAWNAND_DATA00 0x0F8 0x358 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA00__NAND_DATA00 0x0F8 0x358 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_DATA00__FLEXSPI_A_DATA00 0x0F8 0x358 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_DATA00__AUDIOMIX_SAI3_RX_DATA00 0x0F8 0x358 0x4E4 0x2 0x0 -#define MX8MP_IOMUXC_NAND_DATA00__MEDIAMIX_ISP_FLASH_TRIG_0 0x0F8 0x358 0x000 0x3 0x0 +#define MX8MP_IOMUXC_NAND_DATA00__ISP_FLASH_TRIG_0 0x0F8 0x358 0x000 0x3 0x0 #define MX8MP_IOMUXC_NAND_DATA00__UART4_DCE_RX 0x0F8 0x358 0x600 0x4 0x3 #define MX8MP_IOMUXC_NAND_DATA00__UART4_DTE_TX 0x0F8 0x358 0x000 0x4 0x0 #define MX8MP_IOMUXC_NAND_DATA00__GPIO3_IO06 0x0F8 0x358 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_DATA00__CORESIGHT_TRACE04 0x0F8 0x358 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_DATA00__SIM_M_HADDR02 0x0F8 0x358 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_DATA01__RAWNAND_DATA01 0x0FC 0x35C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA01__NAND_DATA01 0x0FC 0x35C 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_DATA01__FLEXSPI_A_DATA01 0x0FC 0x35C 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_DATA01__AUDIOMIX_SAI3_TX_SYNC 0x0FC 0x35C 0x4EC 0x2 0x0 -#define MX8MP_IOMUXC_NAND_DATA01__MEDIAMIX_ISP_PRELIGHT_TRIG_0 0x0FC 0x35C 0x000 0x3 0x0 +#define MX8MP_IOMUXC_NAND_DATA01__ISP_PRELIGHT_TRIG_0 0x0FC 0x35C 0x000 0x3 0x0 #define MX8MP_IOMUXC_NAND_DATA01__UART4_DCE_TX 0x0FC 0x35C 0x000 0x4 0x0 #define MX8MP_IOMUXC_NAND_DATA01__UART4_DTE_RX 0x0FC 0x35C 0x600 0x4 0x4 #define MX8MP_IOMUXC_NAND_DATA01__GPIO3_IO07 0x0FC 0x35C 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_DATA01__CORESIGHT_TRACE05 0x0FC 0x35C 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_DATA01__SIM_M_HADDR03 0x0FC 0x35C 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_DATA02__RAWNAND_DATA02 0x100 0x360 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA02__NAND_DATA02 0x100 0x360 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_DATA02__FLEXSPI_A_DATA02 0x100 0x360 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_DATA02__USDHC3_CD_B 0x100 0x360 0x608 0x2 0x2 #define MX8MP_IOMUXC_NAND_DATA02__UART4_DCE_CTS 0x100 0x360 0x000 0x3 0x0 @@ -396,82 +330,71 @@ #define MX8MP_IOMUXC_NAND_DATA02__I2C4_SDA 0x100 0x360 0x5C0 0x4 0x3 #define MX8MP_IOMUXC_NAND_DATA02__GPIO3_IO08 0x100 0x360 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_DATA02__CORESIGHT_TRACE06 0x100 0x360 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_DATA02__SIM_M_HADDR04 0x100 0x360 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_DATA03__RAWNAND_DATA03 0x104 0x364 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA03__NAND_DATA03 0x104 0x364 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_DATA03__FLEXSPI_A_DATA03 0x104 0x364 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_DATA03__USDHC3_WP 0x104 0x364 0x634 0x2 0x2 #define MX8MP_IOMUXC_NAND_DATA03__UART4_DCE_RTS 0x104 0x364 0x5FC 0x3 0x1 #define MX8MP_IOMUXC_NAND_DATA03__UART4_DTE_CTS 0x104 0x364 0x000 0x3 0x0 -#define MX8MP_IOMUXC_NAND_DATA03__MEDIAMIX_ISP_FL_TRIG_1 0x104 0x364 0x5D8 0x4 0x1 +#define MX8MP_IOMUXC_NAND_DATA03__ISP_FL_TRIG_1 0x104 0x364 0x5D8 0x4 0x1 #define MX8MP_IOMUXC_NAND_DATA03__GPIO3_IO09 0x104 0x364 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_DATA03__CORESIGHT_TRACE07 0x104 0x364 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_DATA03__SIM_M_HADDR05 0x104 0x364 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_DATA04__RAWNAND_DATA04 0x108 0x368 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA04__NAND_DATA04 0x108 0x368 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_DATA04__FLEXSPI_B_DATA00 0x108 0x368 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x108 0x368 0x610 0x2 0x1 #define MX8MP_IOMUXC_NAND_DATA04__FLEXSPI_A_DATA04 0x108 0x368 0x000 0x3 0x0 -#define MX8MP_IOMUXC_NAND_DATA04__MEDIAMIX_ISP_SHUTTER_TRIG_1 0x108 0x368 0x5E0 0x4 0x1 +#define MX8MP_IOMUXC_NAND_DATA04__ISP_SHUTTER_TRIG_1 0x108 0x368 0x5E0 0x4 0x1 #define MX8MP_IOMUXC_NAND_DATA04__GPIO3_IO10 0x108 0x368 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_DATA04__CORESIGHT_TRACE08 0x108 0x368 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_DATA04__SIM_M_HADDR06 0x108 0x368 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_DATA05__RAWNAND_DATA05 0x10C 0x36C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA05__NAND_DATA05 0x10C 0x36C 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_DATA05__FLEXSPI_B_DATA01 0x10C 0x36C 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x10C 0x36C 0x614 0x2 0x1 #define MX8MP_IOMUXC_NAND_DATA05__FLEXSPI_A_DATA05 0x10C 0x36C 0x000 0x3 0x0 -#define MX8MP_IOMUXC_NAND_DATA05__MEDIAMIX_ISP_FLASH_TRIG_1 0x10C 0x36C 0x000 0x4 0x0 +#define MX8MP_IOMUXC_NAND_DATA05__ISP_FLASH_TRIG_1 0x10C 0x36C 0x000 0x4 0x0 #define MX8MP_IOMUXC_NAND_DATA05__GPIO3_IO11 0x10C 0x36C 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_DATA05__CORESIGHT_TRACE09 0x10C 0x36C 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_DATA05__SIM_M_HADDR07 0x10C 0x36C 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_DATA06__RAWNAND_DATA06 0x110 0x370 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA06__NAND_DATA06 0x110 0x370 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_DATA06__FLEXSPI_B_DATA02 0x110 0x370 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x110 0x370 0x618 0x2 0x1 #define MX8MP_IOMUXC_NAND_DATA06__FLEXSPI_A_DATA06 0x110 0x370 0x000 0x3 0x0 -#define MX8MP_IOMUXC_NAND_DATA06__MEDIAMIX_ISP_PRELIGHT_TRIG_1 0x110 0x370 0x000 0x4 0x0 +#define MX8MP_IOMUXC_NAND_DATA06__ISP_PRELIGHT_TRIG_1 0x110 0x370 0x000 0x4 0x0 #define MX8MP_IOMUXC_NAND_DATA06__GPIO3_IO12 0x110 0x370 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_DATA06__CORESIGHT_TRACE10 0x110 0x370 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_DATA06__SIM_M_HADDR08 0x110 0x370 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_DATA07__RAWNAND_DATA07 0x114 0x374 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DATA07__NAND_DATA07 0x114 0x374 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_DATA07__FLEXSPI_B_DATA03 0x114 0x374 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x114 0x374 0x61C 0x2 0x1 #define MX8MP_IOMUXC_NAND_DATA07__FLEXSPI_A_DATA07 0x114 0x374 0x000 0x3 0x0 -#define MX8MP_IOMUXC_NAND_DATA07__MEDIAMIX_ISP_SHUTTER_OPEN_1 0x114 0x374 0x000 0x4 0x0 +#define MX8MP_IOMUXC_NAND_DATA07__ISP_SHUTTER_OPEN_1 0x114 0x374 0x000 0x4 0x0 #define MX8MP_IOMUXC_NAND_DATA07__GPIO3_IO13 0x114 0x374 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_DATA07__CORESIGHT_TRACE11 0x114 0x374 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_DATA07__SIM_M_HADDR09 0x114 0x374 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_DQS__RAWNAND_DQS 0x118 0x378 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_DQS__NAND_DQS 0x118 0x378 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_DQS__FLEXSPI_A_DQS 0x118 0x378 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_DQS__AUDIOMIX_SAI3_MCLK 0x118 0x378 0x4E0 0x2 0x0 -#define MX8MP_IOMUXC_NAND_DQS__MEDIAMIX_ISP_SHUTTER_OPEN_0 0x118 0x378 0x000 0x3 0x0 +#define MX8MP_IOMUXC_NAND_DQS__ISP_SHUTTER_OPEN_0 0x118 0x378 0x000 0x3 0x0 #define MX8MP_IOMUXC_NAND_DQS__I2C3_SCL 0x118 0x378 0x5B4 0x4 0x1 #define MX8MP_IOMUXC_NAND_DQS__GPIO3_IO14 0x118 0x378 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_DQS__CORESIGHT_TRACE12 0x118 0x378 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_DQS__SIM_M_HADDR10 0x118 0x378 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_RE_B__RAWNAND_RE_B 0x11C 0x37C 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_RE_B__NAND_RE_B 0x11C 0x37C 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_RE_B__FLEXSPI_B_DQS 0x11C 0x37C 0x000 0x1 0x0 #define MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x11C 0x37C 0x620 0x2 0x1 #define MX8MP_IOMUXC_NAND_RE_B__UART4_DCE_TX 0x11C 0x37C 0x000 0x4 0x0 #define MX8MP_IOMUXC_NAND_RE_B__UART4_DTE_RX 0x11C 0x37C 0x600 0x4 0x5 #define MX8MP_IOMUXC_NAND_RE_B__GPIO3_IO15 0x11C 0x37C 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_RE_B__CORESIGHT_TRACE13 0x11C 0x37C 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_RE_B__SIM_M_HADDR11 0x11C 0x37C 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_READY_B__RAWNAND_READY_B 0x120 0x380 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_READY_B__NAND_READY_B 0x120 0x380 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_READY_B__USDHC3_RESET_B 0x120 0x380 0x000 0x2 0x0 #define MX8MP_IOMUXC_NAND_READY_B__I2C3_SCL 0x120 0x380 0x5B4 0x4 0x2 #define MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x120 0x380 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_READY_B__CORESIGHT_TRACE14 0x120 0x380 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_READY_B__SIM_M_HADDR12 0x120 0x380 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_WE_B__RAWNAND_WE_B 0x124 0x384 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_WE_B__NAND_WE_B 0x124 0x384 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x124 0x384 0x604 0x2 0x1 #define MX8MP_IOMUXC_NAND_WE_B__I2C3_SDA 0x124 0x384 0x5B8 0x4 0x2 #define MX8MP_IOMUXC_NAND_WE_B__GPIO3_IO17 0x124 0x384 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_WE_B__CORESIGHT_TRACE15 0x124 0x384 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_WE_B__SIM_M_HADDR13 0x124 0x384 0x000 0x7 0x0 -#define MX8MP_IOMUXC_NAND_WP_B__RAWNAND_WP_B 0x128 0x388 0x000 0x0 0x0 +#define MX8MP_IOMUXC_NAND_WP_B__NAND_WP_B 0x128 0x388 0x000 0x0 0x0 #define MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x128 0x388 0x60C 0x2 0x1 #define MX8MP_IOMUXC_NAND_WP_B__I2C4_SCL 0x128 0x388 0x5BC 0x4 0x3 #define MX8MP_IOMUXC_NAND_WP_B__GPIO3_IO18 0x128 0x388 0x000 0x5 0x0 #define MX8MP_IOMUXC_NAND_WP_B__CORESIGHT_EVENTO 0x128 0x388 0x000 0x6 0x0 -#define MX8MP_IOMUXC_NAND_WP_B__SIM_M_HADDR14 0x128 0x388 0x000 0x7 0x0 #define MX8MP_IOMUXC_SAI5_RXFS__AUDIOMIX_SAI5_RX_SYNC 0x12C 0x38C 0x508 0x0 0x0 #define MX8MP_IOMUXC_SAI5_RXFS__AUDIOMIX_SAI1_TX_DATA00 0x12C 0x38C 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI5_RXFS__PWM4_OUT 0x12C 0x38C 0x000 0x2 0x0 @@ -481,33 +404,33 @@ #define MX8MP_IOMUXC_SAI5_RXC__AUDIOMIX_SAI1_TX_DATA01 0x130 0x390 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI5_RXC__PWM3_OUT 0x130 0x390 0x000 0x2 0x0 #define MX8MP_IOMUXC_SAI5_RXC__I2C6_SDA 0x130 0x390 0x5D0 0x3 0x1 -#define MX8MP_IOMUXC_SAI5_RXC__AUDIOMIX_CLK 0x130 0x390 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI5_RXC__AUDIOMIX_PDM_CLK 0x130 0x390 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI5_RXC__GPIO3_IO20 0x130 0x390 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_SAI5_RX_DATA00 0x134 0x394 0x4F8 0x0 0x0 #define MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_SAI1_TX_DATA02 0x134 0x394 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI5_RXD0__PWM2_OUT 0x134 0x394 0x000 0x2 0x0 #define MX8MP_IOMUXC_SAI5_RXD0__I2C5_SCL 0x134 0x394 0x5C4 0x3 0x1 -#define MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_BIT_STREAM00 0x134 0x394 0x4C0 0x4 0x3 +#define MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_PDM_BIT_STREAM00 0x134 0x394 0x4C0 0x4 0x3 #define MX8MP_IOMUXC_SAI5_RXD0__GPIO3_IO21 0x134 0x394 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI5_RX_DATA01 0x138 0x398 0x4FC 0x0 0x0 #define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI1_TX_DATA03 0x138 0x398 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI1_TX_SYNC 0x138 0x398 0x4D8 0x2 0x0 #define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_SAI5_TX_SYNC 0x138 0x398 0x510 0x3 0x0 -#define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_BIT_STREAM01 0x138 0x398 0x4C4 0x4 0x3 +#define MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_PDM_BIT_STREAM01 0x138 0x398 0x4C4 0x4 0x3 #define MX8MP_IOMUXC_SAI5_RXD1__GPIO3_IO22 0x138 0x398 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI5_RXD1__CAN1_TX 0x138 0x398 0x000 0x6 0x0 #define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_SAI5_RX_DATA02 0x13C 0x39C 0x500 0x0 0x0 #define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_SAI1_TX_DATA04 0x13C 0x39C 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_SAI1_TX_SYNC 0x13C 0x39C 0x4D8 0x2 0x1 #define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_SAI5_TX_BCLK 0x13C 0x39C 0x50C 0x3 0x0 -#define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_BIT_STREAM02 0x13C 0x39C 0x4C8 0x4 0x3 +#define MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_PDM_BIT_STREAM02 0x13C 0x39C 0x4C8 0x4 0x3 #define MX8MP_IOMUXC_SAI5_RXD2__GPIO3_IO23 0x13C 0x39C 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI5_RXD2__CAN1_RX 0x13C 0x39C 0x54C 0x6 0x0 #define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_SAI5_RX_DATA03 0x140 0x3A0 0x504 0x0 0x0 #define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_SAI1_TX_DATA05 0x140 0x3A0 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_SAI1_TX_SYNC 0x140 0x3A0 0x4D8 0x2 0x2 #define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_SAI5_TX_DATA00 0x140 0x3A0 0x000 0x3 0x0 -#define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_BIT_STREAM03 0x140 0x3A0 0x4CC 0x4 0x3 +#define MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_PDM_BIT_STREAM03 0x140 0x3A0 0x4CC 0x4 0x3 #define MX8MP_IOMUXC_SAI5_RXD3__GPIO3_IO24 0x140 0x3A0 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI5_RXD3__CAN2_TX 0x140 0x3A0 0x000 0x6 0x0 #define MX8MP_IOMUXC_SAI5_MCLK__AUDIOMIX_SAI5_MCLK 0x144 0x3A4 0x4F0 0x0 0x0 @@ -517,33 +440,27 @@ #define MX8MP_IOMUXC_SAI5_MCLK__GPIO3_IO25 0x144 0x3A4 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI5_MCLK__CAN2_RX 0x144 0x3A4 0x550 0x6 0x0 #define MX8MP_IOMUXC_SAI1_RXFS__AUDIOMIX_SAI1_RX_SYNC 0x148 0x3A8 0x4D0 0x0 0x0 -#define MX8MP_IOMUXC_SAI1_RXFS__AUDIOMIX_SAI5_RX_SYNC 0x148 0x3A8 0x508 0x1 0x1 #define MX8MP_IOMUXC_SAI1_RXFS__ENET1_1588_EVENT0_IN 0x148 0x3A8 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI1_RXFS__GPIO4_IO00 0x148 0x3A8 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_RXC__AUDIOMIX_SAI1_RX_BCLK 0x14C 0x3AC 0x000 0x0 0x0 -#define MX8MP_IOMUXC_SAI1_RXC__AUDIOMIX_SAI5_RX_BCLK 0x14C 0x3AC 0x4F4 0x1 0x1 -#define MX8MP_IOMUXC_SAI1_RXC__AUDIOMIX_CLK 0x14C 0x3AC 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SAI1_RXC__AUDIOMIX_PDM_CLK 0x14C 0x3AC 0x000 0x3 0x0 #define MX8MP_IOMUXC_SAI1_RXC__ENET1_1588_EVENT0_OUT 0x14C 0x3AC 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI1_RXC__GPIO4_IO01 0x14C 0x3AC 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_SAI1_RX_DATA00 0x150 0x3B0 0x000 0x0 0x0 -#define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_SAI5_RX_DATA00 0x150 0x3B0 0x4F8 0x1 0x1 #define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_SAI1_TX_DATA01 0x150 0x3B0 0x000 0x2 0x0 -#define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_BIT_STREAM00 0x150 0x3B0 0x4C0 0x3 0x4 +#define MX8MP_IOMUXC_SAI1_RXD0__AUDIOMIX_PDM_BIT_STREAM00 0x150 0x3B0 0x4C0 0x3 0x4 #define MX8MP_IOMUXC_SAI1_RXD0__ENET1_1588_EVENT1_IN 0x150 0x3B0 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02 0x150 0x3B0 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_RXD1__AUDIOMIX_SAI1_RX_DATA01 0x154 0x3B4 0x000 0x0 0x0 -#define MX8MP_IOMUXC_SAI1_RXD1__AUDIOMIX_SAI5_RX_DATA01 0x154 0x3B4 0x4FC 0x1 0x1 -#define MX8MP_IOMUXC_SAI1_RXD1__AUDIOMIX_BIT_STREAM01 0x154 0x3B4 0x4C4 0x3 0x4 +#define MX8MP_IOMUXC_SAI1_RXD1__AUDIOMIX_PDM_BIT_STREAM01 0x154 0x3B4 0x4C4 0x3 0x4 #define MX8MP_IOMUXC_SAI1_RXD1__ENET1_1588_EVENT1_OUT 0x154 0x3B4 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI1_RXD1__GPIO4_IO03 0x154 0x3B4 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_RXD2__AUDIOMIX_SAI1_RX_DATA02 0x158 0x3B8 0x000 0x0 0x0 -#define MX8MP_IOMUXC_SAI1_RXD2__AUDIOMIX_SAI5_RX_DATA02 0x158 0x3B8 0x500 0x1 0x1 -#define MX8MP_IOMUXC_SAI1_RXD2__AUDIOMIX_BIT_STREAM02 0x158 0x3B8 0x4C8 0x3 0x4 +#define MX8MP_IOMUXC_SAI1_RXD2__AUDIOMIX_PDM_BIT_STREAM02 0x158 0x3B8 0x4C8 0x3 0x4 #define MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x158 0x3B8 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI1_RXD2__GPIO4_IO04 0x158 0x3B8 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_RXD3__AUDIOMIX_SAI1_RX_DATA03 0x15C 0x3BC 0x000 0x0 0x0 -#define MX8MP_IOMUXC_SAI1_RXD3__AUDIOMIX_SAI5_RX_DATA03 0x15C 0x3BC 0x504 0x1 0x1 -#define MX8MP_IOMUXC_SAI1_RXD3__AUDIOMIX_BIT_STREAM03 0x15C 0x3BC 0x4CC 0x3 0x4 +#define MX8MP_IOMUXC_SAI1_RXD3__AUDIOMIX_PDM_BIT_STREAM03 0x15C 0x3BC 0x4CC 0x3 0x4 #define MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x15C 0x3BC 0x57C 0x4 0x1 #define MX8MP_IOMUXC_SAI1_RXD3__GPIO4_IO05 0x15C 0x3BC 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_RXD4__AUDIOMIX_SAI1_RX_DATA04 0x160 0x3C0 0x000 0x0 0x0 @@ -569,27 +486,21 @@ #define MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x16C 0x3CC 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI1_RXD7__GPIO4_IO09 0x16C 0x3CC 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_TXFS__AUDIOMIX_SAI1_TX_SYNC 0x170 0x3D0 0x4D8 0x0 0x4 -#define MX8MP_IOMUXC_SAI1_TXFS__AUDIOMIX_SAI5_TX_SYNC 0x170 0x3D0 0x510 0x1 0x1 #define MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x170 0x3D0 0x588 0x4 0x1 #define MX8MP_IOMUXC_SAI1_TXFS__GPIO4_IO10 0x170 0x3D0 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_TXC__AUDIOMIX_SAI1_TX_BCLK 0x174 0x3D4 0x4D4 0x0 0x1 -#define MX8MP_IOMUXC_SAI1_TXC__AUDIOMIX_SAI5_TX_BCLK 0x174 0x3D4 0x50C 0x1 0x1 #define MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x174 0x3D4 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI1_TXC__GPIO4_IO11 0x174 0x3D4 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_TXD0__AUDIOMIX_SAI1_TX_DATA00 0x178 0x3D8 0x000 0x0 0x0 -#define MX8MP_IOMUXC_SAI1_TXD0__AUDIOMIX_SAI5_TX_DATA00 0x178 0x3D8 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x178 0x3D8 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI1_TXD0__GPIO4_IO12 0x178 0x3D8 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_TXD1__AUDIOMIX_SAI1_TX_DATA01 0x17C 0x3DC 0x000 0x0 0x0 -#define MX8MP_IOMUXC_SAI1_TXD1__AUDIOMIX_SAI5_TX_DATA01 0x17C 0x3DC 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x17C 0x3DC 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI1_TXD1__GPIO4_IO13 0x17C 0x3DC 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_TXD2__AUDIOMIX_SAI1_TX_DATA02 0x180 0x3E0 0x000 0x0 0x0 -#define MX8MP_IOMUXC_SAI1_TXD2__AUDIOMIX_SAI5_TX_DATA02 0x180 0x3E0 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x180 0x3E0 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI1_TXD2__GPIO4_IO14 0x180 0x3E0 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_TXD3__AUDIOMIX_SAI1_TX_DATA03 0x184 0x3E4 0x000 0x0 0x0 -#define MX8MP_IOMUXC_SAI1_TXD3__AUDIOMIX_SAI5_TX_DATA03 0x184 0x3E4 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x184 0x3E4 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI1_TXD3__GPIO4_IO15 0x184 0x3E4 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_TXD4__AUDIOMIX_SAI1_TX_DATA04 0x188 0x3E8 0x000 0x0 0x0 @@ -609,11 +520,10 @@ #define MX8MP_IOMUXC_SAI1_TXD6__GPIO4_IO18 0x190 0x3F0 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_TXD7__AUDIOMIX_SAI1_TX_DATA07 0x194 0x3F4 0x000 0x0 0x0 #define MX8MP_IOMUXC_SAI1_TXD7__AUDIOMIX_SAI6_MCLK 0x194 0x3F4 0x514 0x1 0x2 -#define MX8MP_IOMUXC_SAI1_TXD7__AUDIOMIX_CLK 0x194 0x3F4 0x000 0x3 0x0 +#define MX8MP_IOMUXC_SAI1_TXD7__AUDIOMIX_PDM_CLK 0x194 0x3F4 0x000 0x3 0x0 #define MX8MP_IOMUXC_SAI1_TXD7__ENET1_TX_ER 0x194 0x3F4 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19 0x194 0x3F4 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI1_MCLK__AUDIOMIX_SAI1_MCLK 0x198 0x3F8 0x000 0x0 0x0 -#define MX8MP_IOMUXC_SAI1_MCLK__AUDIOMIX_SAI5_MCLK 0x198 0x3F8 0x4F0 0x1 0x1 #define MX8MP_IOMUXC_SAI1_MCLK__AUDIOMIX_SAI1_TX_BCLK 0x198 0x3F8 0x4D4 0x2 0x2 #define MX8MP_IOMUXC_SAI1_MCLK__ENET1_TX_CLK 0x198 0x3F8 0x578 0x4 0x1 #define MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20 0x198 0x3F8 0x000 0x5 0x0 @@ -624,16 +534,14 @@ #define MX8MP_IOMUXC_SAI2_RXFS__UART1_DCE_TX 0x19C 0x3FC 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI2_RXFS__UART1_DTE_RX 0x19C 0x3FC 0x5E8 0x4 0x2 #define MX8MP_IOMUXC_SAI2_RXFS__GPIO4_IO21 0x19C 0x3FC 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SAI2_RXFS__AUDIOMIX_BIT_STREAM02 0x19C 0x3FC 0x4C8 0x6 0x5 -#define MX8MP_IOMUXC_SAI2_RXFS__SIM_M_HSIZE00 0x19C 0x3FC 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI2_RXFS__AUDIOMIX_PDM_BIT_STREAM02 0x19C 0x3FC 0x4C8 0x6 0x5 #define MX8MP_IOMUXC_SAI2_RXC__AUDIOMIX_SAI2_RX_BCLK 0x1A0 0x400 0x000 0x0 0x0 #define MX8MP_IOMUXC_SAI2_RXC__AUDIOMIX_SAI5_TX_BCLK 0x1A0 0x400 0x50C 0x1 0x2 #define MX8MP_IOMUXC_SAI2_RXC__CAN1_TX 0x1A0 0x400 0x000 0x3 0x0 #define MX8MP_IOMUXC_SAI2_RXC__UART1_DCE_RX 0x1A0 0x400 0x5E8 0x4 0x3 #define MX8MP_IOMUXC_SAI2_RXC__UART1_DTE_TX 0x1A0 0x400 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x1A0 0x400 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SAI2_RXC__AUDIOMIX_BIT_STREAM01 0x1A0 0x400 0x4C4 0x6 0x5 -#define MX8MP_IOMUXC_SAI2_RXC__SIM_M_HSIZE01 0x1A0 0x400 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI2_RXC__AUDIOMIX_PDM_BIT_STREAM01 0x1A0 0x400 0x4C4 0x6 0x5 #define MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_SAI2_RX_DATA00 0x1A4 0x404 0x000 0x0 0x0 #define MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_SAI5_TX_DATA00 0x1A4 0x404 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI2_RXD0__ENET_QOS_1588_EVENT2_OUT 0x1A4 0x404 0x000 0x2 0x0 @@ -641,8 +549,7 @@ #define MX8MP_IOMUXC_SAI2_RXD0__UART1_DCE_RTS 0x1A4 0x404 0x5E4 0x4 0x2 #define MX8MP_IOMUXC_SAI2_RXD0__UART1_DTE_CTS 0x1A4 0x404 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI2_RXD0__GPIO4_IO23 0x1A4 0x404 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_BIT_STREAM03 0x1A4 0x404 0x4CC 0x6 0x5 -#define MX8MP_IOMUXC_SAI2_RXD0__SIM_M_HSIZE02 0x1A4 0x404 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_PDM_BIT_STREAM03 0x1A4 0x404 0x4CC 0x6 0x5 #define MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI2_TX_SYNC 0x1A8 0x408 0x000 0x0 0x0 #define MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI5_TX_DATA01 0x1A8 0x408 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI2_TXFS__ENET_QOS_1588_EVENT3_OUT 0x1A8 0x408 0x000 0x2 0x0 @@ -650,22 +557,18 @@ #define MX8MP_IOMUXC_SAI2_TXFS__UART1_DCE_CTS 0x1A8 0x408 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI2_TXFS__UART1_DTE_RTS 0x1A8 0x408 0x5E4 0x4 0x3 #define MX8MP_IOMUXC_SAI2_TXFS__GPIO4_IO24 0x1A8 0x408 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_BIT_STREAM02 0x1A8 0x408 0x4C8 0x6 0x6 -#define MX8MP_IOMUXC_SAI2_TXFS__SIM_M_HWRITE 0x1A8 0x408 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_PDM_BIT_STREAM02 0x1A8 0x408 0x4C8 0x6 0x6 #define MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_SAI2_TX_BCLK 0x1AC 0x40C 0x000 0x0 0x0 #define MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_SAI5_TX_DATA02 0x1AC 0x40C 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI2_TXC__CAN1_RX 0x1AC 0x40C 0x54C 0x3 0x1 #define MX8MP_IOMUXC_SAI2_TXC__GPIO4_IO25 0x1AC 0x40C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_BIT_STREAM01 0x1AC 0x40C 0x4C4 0x6 0x6 -#define MX8MP_IOMUXC_SAI2_TXC__SIM_M_HREADYOUT 0x1AC 0x40C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_PDM_BIT_STREAM01 0x1AC 0x40C 0x4C4 0x6 0x6 #define MX8MP_IOMUXC_SAI2_TXD0__AUDIOMIX_SAI2_TX_DATA00 0x1B0 0x410 0x000 0x0 0x0 #define MX8MP_IOMUXC_SAI2_TXD0__AUDIOMIX_SAI5_TX_DATA03 0x1B0 0x410 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI2_TXD0__ENET_QOS_1588_EVENT2_IN 0x1B0 0x410 0x000 0x2 0x0 #define MX8MP_IOMUXC_SAI2_TXD0__CAN2_TX 0x1B0 0x410 0x000 0x3 0x0 #define MX8MP_IOMUXC_SAI2_TXD0__ENET_QOS_1588_EVENT2_AUX_IN 0x1B0 0x410 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI2_TXD0__GPIO4_IO26 0x1B0 0x410 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SAI2_TXD0__CCMSRCGPCMIX_BOOT_MODE04 0x1B0 0x410 0x000 0x6 0x0 -#define MX8MP_IOMUXC_SAI2_TXD0__TPSMP_CLK 0x1B0 0x410 0x000 0x7 0x0 #define MX8MP_IOMUXC_SAI2_MCLK__AUDIOMIX_SAI2_MCLK 0x1B4 0x414 0x000 0x0 0x0 #define MX8MP_IOMUXC_SAI2_MCLK__AUDIOMIX_SAI5_MCLK 0x1B4 0x414 0x4F0 0x1 0x2 #define MX8MP_IOMUXC_SAI2_MCLK__ENET_QOS_1588_EVENT3_IN 0x1B4 0x414 0x000 0x2 0x0 @@ -673,15 +576,13 @@ #define MX8MP_IOMUXC_SAI2_MCLK__ENET_QOS_1588_EVENT3_AUX_IN 0x1B4 0x414 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27 0x1B4 0x414 0x000 0x5 0x0 #define MX8MP_IOMUXC_SAI2_MCLK__AUDIOMIX_SAI3_MCLK 0x1B4 0x414 0x4E0 0x6 0x1 -#define MX8MP_IOMUXC_SAI2_MCLK__TPSMP_HDATA_DIR 0x1B4 0x414 0x000 0x7 0x0 #define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SAI3_RX_SYNC 0x1B8 0x418 0x000 0x0 0x0 #define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SAI2_RX_DATA01 0x1B8 0x418 0x4DC 0x1 0x1 #define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SAI5_RX_SYNC 0x1B8 0x418 0x508 0x2 0x2 #define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SAI3_RX_DATA01 0x1B8 0x418 0x000 0x3 0x0 -#define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SPDIF_IN 0x1B8 0x418 0x544 0x4 0x2 +#define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SPDIF1_IN 0x1B8 0x418 0x544 0x4 0x2 #define MX8MP_IOMUXC_SAI3_RXFS__GPIO4_IO28 0x1B8 0x418 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_BIT_STREAM00 0x1B8 0x418 0x4C0 0x6 0x5 -#define MX8MP_IOMUXC_SAI3_RXFS__TPSMP_HTRANS00 0x1B8 0x418 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_PDM_BIT_STREAM00 0x1B8 0x418 0x4C0 0x6 0x5 #define MX8MP_IOMUXC_SAI3_RXC__AUDIOMIX_SAI3_RX_BCLK 0x1BC 0x41C 0x000 0x0 0x0 #define MX8MP_IOMUXC_SAI3_RXC__AUDIOMIX_SAI2_RX_DATA02 0x1BC 0x41C 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI3_RXC__AUDIOMIX_SAI5_RX_BCLK 0x1BC 0x41C 0x4F4 0x2 0x2 @@ -689,16 +590,14 @@ #define MX8MP_IOMUXC_SAI3_RXC__UART2_DCE_CTS 0x1BC 0x41C 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI3_RXC__UART2_DTE_RTS 0x1BC 0x41C 0x5EC 0x4 0x2 #define MX8MP_IOMUXC_SAI3_RXC__GPIO4_IO29 0x1BC 0x41C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SAI3_RXC__AUDIOMIX_CLK 0x1BC 0x41C 0x000 0x6 0x0 -#define MX8MP_IOMUXC_SAI3_RXC__TPSMP_HTRANS01 0x1BC 0x41C 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI3_RXC__AUDIOMIX_PDM_CLK 0x1BC 0x41C 0x000 0x6 0x0 #define MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI3_RX_DATA00 0x1C0 0x420 0x4E4 0x0 0x1 #define MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI2_RX_DATA03 0x1C0 0x420 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI5_RX_DATA00 0x1C0 0x420 0x4F8 0x2 0x2 #define MX8MP_IOMUXC_SAI3_RXD__UART2_DCE_RTS 0x1C0 0x420 0x5EC 0x4 0x3 #define MX8MP_IOMUXC_SAI3_RXD__UART2_DTE_CTS 0x1C0 0x420 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI3_RXD__GPIO4_IO30 0x1C0 0x420 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_BIT_STREAM01 0x1C0 0x420 0x4C4 0x6 0x7 -#define MX8MP_IOMUXC_SAI3_RXD__TPSMP_HDATA00 0x1C0 0x420 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_PDM_BIT_STREAM01 0x1C0 0x420 0x4C4 0x6 0x7 #define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_SYNC 0x1C4 0x424 0x4EC 0x0 0x1 #define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI2_TX_DATA01 0x1C4 0x424 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI5_RX_DATA01 0x1C4 0x424 0x4FC 0x2 0x2 @@ -706,8 +605,7 @@ #define MX8MP_IOMUXC_SAI3_TXFS__UART2_DCE_RX 0x1C4 0x424 0x5F0 0x4 0x4 #define MX8MP_IOMUXC_SAI3_TXFS__UART2_DTE_TX 0x1C4 0x424 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI3_TXFS__GPIO4_IO31 0x1C4 0x424 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_BIT_STREAM03 0x1C4 0x424 0x4CC 0x6 0x6 -#define MX8MP_IOMUXC_SAI3_TXFS__TPSMP_HDATA01 0x1C4 0x424 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_PDM_BIT_STREAM03 0x1C4 0x424 0x4CC 0x6 0x6 #define MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI3_TX_BCLK 0x1C8 0x428 0x4E8 0x0 0x1 #define MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI2_TX_DATA02 0x1C8 0x428 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI5_RX_DATA02 0x1C8 0x428 0x500 0x2 0x2 @@ -715,30 +613,26 @@ #define MX8MP_IOMUXC_SAI3_TXC__UART2_DCE_TX 0x1C8 0x428 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI3_TXC__UART2_DTE_RX 0x1C8 0x428 0x5F0 0x4 0x5 #define MX8MP_IOMUXC_SAI3_TXC__GPIO5_IO00 0x1C8 0x428 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_BIT_STREAM02 0x1C8 0x428 0x4C8 0x6 0x7 -#define MX8MP_IOMUXC_SAI3_TXC__TPSMP_HDATA02 0x1C8 0x428 0x000 0x7 0x0 +#define MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_PDM_BIT_STREAM02 0x1C8 0x428 0x4C8 0x6 0x7 #define MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI3_TX_DATA00 0x1CC 0x42C 0x000 0x0 0x0 #define MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI2_TX_DATA03 0x1CC 0x42C 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI5_RX_DATA03 0x1CC 0x42C 0x504 0x2 0x2 #define MX8MP_IOMUXC_SAI3_TXD__GPT1_CAPTURE2 0x1CC 0x42C 0x598 0x3 0x0 -#define MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SPDIF_EXT_CLK 0x1CC 0x42C 0x548 0x4 0x0 +#define MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SPDIF1_EXT_CLK 0x1CC 0x42C 0x548 0x4 0x0 #define MX8MP_IOMUXC_SAI3_TXD__GPIO5_IO01 0x1CC 0x42C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SAI3_TXD__CCMSRCGPCMIX_BOOT_MODE05 0x1CC 0x42C 0x000 0x6 0x0 -#define MX8MP_IOMUXC_SAI3_TXD__TPSMP_HDATA03 0x1CC 0x42C 0x000 0x7 0x0 #define MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SAI3_MCLK 0x1D0 0x430 0x4E0 0x0 0x2 #define MX8MP_IOMUXC_SAI3_MCLK__PWM4_OUT 0x1D0 0x430 0x000 0x1 0x0 #define MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SAI5_MCLK 0x1D0 0x430 0x4F0 0x2 0x3 -#define MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SPDIF_OUT 0x1D0 0x430 0x000 0x4 0x0 +#define MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SPDIF1_OUT 0x1D0 0x430 0x000 0x4 0x0 #define MX8MP_IOMUXC_SAI3_MCLK__GPIO5_IO02 0x1D0 0x430 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SPDIF_IN 0x1D0 0x430 0x544 0x6 0x3 -#define MX8MP_IOMUXC_SAI3_MCLK__TPSMP_HDATA04 0x1D0 0x430 0x000 0x7 0x0 -#define MX8MP_IOMUXC_SPDIF_TX__AUDIOMIX_SPDIF_OUT 0x1D4 0x434 0x000 0x0 0x0 +#define MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SPDIF1_IN 0x1D0 0x430 0x544 0x6 0x3 +#define MX8MP_IOMUXC_SPDIF_TX__AUDIOMIX_SPDIF1_OUT 0x1D4 0x434 0x000 0x0 0x0 #define MX8MP_IOMUXC_SPDIF_TX__PWM3_OUT 0x1D4 0x434 0x000 0x1 0x0 #define MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL 0x1D4 0x434 0x5C4 0x2 0x2 #define MX8MP_IOMUXC_SPDIF_TX__GPT1_COMPARE1 0x1D4 0x434 0x000 0x3 0x0 #define MX8MP_IOMUXC_SPDIF_TX__CAN1_TX 0x1D4 0x434 0x000 0x4 0x0 #define MX8MP_IOMUXC_SPDIF_TX__GPIO5_IO03 0x1D4 0x434 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SPDIF_RX__AUDIOMIX_SPDIF_IN 0x1D8 0x438 0x544 0x0 0x4 +#define MX8MP_IOMUXC_SPDIF_RX__AUDIOMIX_SPDIF1_IN 0x1D8 0x438 0x544 0x0 0x4 #define MX8MP_IOMUXC_SPDIF_RX__PWM2_OUT 0x1D8 0x438 0x000 0x1 0x0 #define MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA 0x1D8 0x438 0x5C8 0x2 0x2 #define MX8MP_IOMUXC_SPDIF_RX__GPT1_COMPARE2 0x1D8 0x438 0x000 0x3 0x0 @@ -746,7 +640,7 @@ #define MX8MP_IOMUXC_SPDIF_RX__GPIO5_IO04 0x1D8 0x438 0x000 0x5 0x0 #define MX8MP_IOMUXC_SPDIF_EXT_CLK__GPT1_COMPARE3 0x1DC 0x43C 0x000 0x3 0x0 #define MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 0x1DC 0x43C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_SPDIF_EXT_CLK__AUDIOMIX_SPDIF_EXT_CLK 0x1DC 0x43C 0x548 0x0 0x1 +#define MX8MP_IOMUXC_SPDIF_EXT_CLK__AUDIOMIX_SPDIF1_EXT_CLK 0x1DC 0x43C 0x548 0x0 0x1 #define MX8MP_IOMUXC_SPDIF_EXT_CLK__PWM1_OUT 0x1DC 0x43C 0x000 0x1 0x0 #define MX8MP_IOMUXC_ECSPI1_SCLK__ECSPI1_SCLK 0x1E0 0x440 0x558 0x0 0x0 #define MX8MP_IOMUXC_ECSPI1_SCLK__UART3_DCE_RX 0x1E0 0x440 0x5F8 0x1 0x4 @@ -754,125 +648,105 @@ #define MX8MP_IOMUXC_ECSPI1_SCLK__I2C1_SCL 0x1E0 0x440 0x5A4 0x2 0x1 #define MX8MP_IOMUXC_ECSPI1_SCLK__AUDIOMIX_SAI7_RX_SYNC 0x1E0 0x440 0x538 0x3 0x1 #define MX8MP_IOMUXC_ECSPI1_SCLK__GPIO5_IO06 0x1E0 0x440 0x000 0x5 0x0 -#define MX8MP_IOMUXC_ECSPI1_SCLK__TPSMP_HDATA08 0x1E0 0x440 0x000 0x7 0x0 #define MX8MP_IOMUXC_ECSPI1_MOSI__ECSPI1_MOSI 0x1E4 0x444 0x560 0x0 0x0 #define MX8MP_IOMUXC_ECSPI1_MOSI__UART3_DCE_TX 0x1E4 0x444 0x000 0x1 0x0 #define MX8MP_IOMUXC_ECSPI1_MOSI__UART3_DTE_RX 0x1E4 0x444 0x5F8 0x1 0x5 #define MX8MP_IOMUXC_ECSPI1_MOSI__I2C1_SDA 0x1E4 0x444 0x5A8 0x2 0x1 #define MX8MP_IOMUXC_ECSPI1_MOSI__AUDIOMIX_SAI7_RX_BCLK 0x1E4 0x444 0x530 0x3 0x1 #define MX8MP_IOMUXC_ECSPI1_MOSI__GPIO5_IO07 0x1E4 0x444 0x000 0x5 0x0 -#define MX8MP_IOMUXC_ECSPI1_MOSI__TPSMP_HDATA09 0x1E4 0x444 0x000 0x7 0x0 #define MX8MP_IOMUXC_ECSPI1_MISO__ECSPI1_MISO 0x1E8 0x448 0x55C 0x0 0x0 #define MX8MP_IOMUXC_ECSPI1_MISO__UART3_DCE_CTS 0x1E8 0x448 0x000 0x1 0x0 #define MX8MP_IOMUXC_ECSPI1_MISO__UART3_DTE_RTS 0x1E8 0x448 0x5F4 0x1 0x2 #define MX8MP_IOMUXC_ECSPI1_MISO__I2C2_SCL 0x1E8 0x448 0x5AC 0x2 0x1 #define MX8MP_IOMUXC_ECSPI1_MISO__AUDIOMIX_SAI7_RX_DATA00 0x1E8 0x448 0x534 0x3 0x1 #define MX8MP_IOMUXC_ECSPI1_MISO__GPIO5_IO08 0x1E8 0x448 0x000 0x5 0x0 -#define MX8MP_IOMUXC_ECSPI1_MISO__TPSMP_HDATA10 0x1E8 0x448 0x000 0x7 0x0 #define MX8MP_IOMUXC_ECSPI1_SS0__ECSPI1_SS0 0x1EC 0x44C 0x564 0x0 0x0 #define MX8MP_IOMUXC_ECSPI1_SS0__UART3_DCE_RTS 0x1EC 0x44C 0x5F4 0x1 0x3 #define MX8MP_IOMUXC_ECSPI1_SS0__UART3_DTE_CTS 0x1EC 0x44C 0x000 0x1 0x0 #define MX8MP_IOMUXC_ECSPI1_SS0__I2C2_SDA 0x1EC 0x44C 0x5B0 0x2 0x1 #define MX8MP_IOMUXC_ECSPI1_SS0__AUDIOMIX_SAI7_TX_SYNC 0x1EC 0x44C 0x540 0x3 0x1 #define MX8MP_IOMUXC_ECSPI1_SS0__GPIO5_IO09 0x1EC 0x44C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_ECSPI1_SS0__TPSMP_HDATA11 0x1EC 0x44C 0x000 0x7 0x0 #define MX8MP_IOMUXC_ECSPI2_SCLK__ECSPI2_SCLK 0x1F0 0x450 0x568 0x0 0x1 #define MX8MP_IOMUXC_ECSPI2_SCLK__UART4_DCE_RX 0x1F0 0x450 0x600 0x1 0x6 #define MX8MP_IOMUXC_ECSPI2_SCLK__UART4_DTE_TX 0x1F0 0x450 0x000 0x1 0x0 #define MX8MP_IOMUXC_ECSPI2_SCLK__I2C3_SCL 0x1F0 0x450 0x5B4 0x2 0x3 #define MX8MP_IOMUXC_ECSPI2_SCLK__AUDIOMIX_SAI7_TX_BCLK 0x1F0 0x450 0x53C 0x3 0x1 #define MX8MP_IOMUXC_ECSPI2_SCLK__GPIO5_IO10 0x1F0 0x450 0x000 0x5 0x0 -#define MX8MP_IOMUXC_ECSPI2_SCLK__TPSMP_HDATA12 0x1F0 0x450 0x000 0x7 0x0 #define MX8MP_IOMUXC_ECSPI2_MOSI__ECSPI2_MOSI 0x1F4 0x454 0x570 0x0 0x1 #define MX8MP_IOMUXC_ECSPI2_MOSI__UART4_DCE_TX 0x1F4 0x454 0x000 0x1 0x0 #define MX8MP_IOMUXC_ECSPI2_MOSI__UART4_DTE_RX 0x1F4 0x454 0x600 0x1 0x7 #define MX8MP_IOMUXC_ECSPI2_MOSI__I2C3_SDA 0x1F4 0x454 0x5B8 0x2 0x3 #define MX8MP_IOMUXC_ECSPI2_MOSI__AUDIOMIX_SAI7_TX_DATA00 0x1F4 0x454 0x000 0x3 0x0 #define MX8MP_IOMUXC_ECSPI2_MOSI__GPIO5_IO11 0x1F4 0x454 0x000 0x5 0x0 -#define MX8MP_IOMUXC_ECSPI2_MOSI__TPSMP_HDATA13 0x1F4 0x454 0x000 0x7 0x0 #define MX8MP_IOMUXC_ECSPI2_MISO__GPIO5_IO12 0x1F8 0x458 0x000 0x5 0x0 -#define MX8MP_IOMUXC_ECSPI2_MISO__TPSMP_HDATA14 0x1F8 0x458 0x000 0x7 0x0 #define MX8MP_IOMUXC_ECSPI2_MISO__ECSPI2_MISO 0x1F8 0x458 0x56C 0x0 0x1 #define MX8MP_IOMUXC_ECSPI2_MISO__UART4_DCE_CTS 0x1F8 0x458 0x000 0x1 0x0 #define MX8MP_IOMUXC_ECSPI2_MISO__UART4_DTE_RTS 0x1F8 0x458 0x5FC 0x1 0x2 #define MX8MP_IOMUXC_ECSPI2_MISO__I2C4_SCL 0x1F8 0x458 0x5BC 0x2 0x4 #define MX8MP_IOMUXC_ECSPI2_MISO__AUDIOMIX_SAI7_MCLK 0x1F8 0x458 0x52C 0x3 0x1 -#define MX8MP_IOMUXC_ECSPI2_MISO__CCMSRCGPCMIX_CLKO1 0x1F8 0x458 0x000 0x4 0x0 +#define MX8MP_IOMUXC_ECSPI2_MISO__CCM_CLKO1 0x1F8 0x458 0x000 0x4 0x0 #define MX8MP_IOMUXC_ECSPI2_SS0__ECSPI2_SS0 0x1FC 0x45C 0x574 0x0 0x1 #define MX8MP_IOMUXC_ECSPI2_SS0__UART4_DCE_RTS 0x1FC 0x45C 0x5FC 0x1 0x3 #define MX8MP_IOMUXC_ECSPI2_SS0__UART4_DTE_CTS 0x1FC 0x45C 0x000 0x1 0x0 #define MX8MP_IOMUXC_ECSPI2_SS0__I2C4_SDA 0x1FC 0x45C 0x5C0 0x2 0x4 -#define MX8MP_IOMUXC_ECSPI2_SS0__CCMSRCGPCMIX_CLKO2 0x1FC 0x45C 0x000 0x4 0x0 +#define MX8MP_IOMUXC_ECSPI2_SS0__CCM_CLKO2 0x1FC 0x45C 0x000 0x4 0x0 #define MX8MP_IOMUXC_ECSPI2_SS0__GPIO5_IO13 0x1FC 0x45C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_ECSPI2_SS0__TPSMP_HDATA15 0x1FC 0x45C 0x000 0x7 0x0 #define MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x200 0x460 0x5A4 0x0 0x2 #define MX8MP_IOMUXC_I2C1_SCL__ENET_QOS_MDC 0x200 0x460 0x000 0x1 0x0 #define MX8MP_IOMUXC_I2C1_SCL__ECSPI1_SCLK 0x200 0x460 0x558 0x3 0x1 #define MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14 0x200 0x460 0x000 0x5 0x0 -#define MX8MP_IOMUXC_I2C1_SCL__TPSMP_HDATA16 0x200 0x460 0x000 0x7 0x0 #define MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x204 0x464 0x5A8 0x0 0x2 #define MX8MP_IOMUXC_I2C1_SDA__ENET_QOS_MDIO 0x204 0x464 0x590 0x1 0x2 #define MX8MP_IOMUXC_I2C1_SDA__ECSPI1_MOSI 0x204 0x464 0x560 0x3 0x1 #define MX8MP_IOMUXC_I2C1_SDA__GPIO5_IO15 0x204 0x464 0x000 0x5 0x0 -#define MX8MP_IOMUXC_I2C1_SDA__TPSMP_HDATA17 0x204 0x464 0x000 0x7 0x0 #define MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x208 0x468 0x5AC 0x0 0x2 #define MX8MP_IOMUXC_I2C2_SCL__ENET_QOS_1588_EVENT1_IN 0x208 0x468 0x000 0x1 0x0 #define MX8MP_IOMUXC_I2C2_SCL__USDHC3_CD_B 0x208 0x468 0x608 0x2 0x3 #define MX8MP_IOMUXC_I2C2_SCL__ECSPI1_MISO 0x208 0x468 0x55C 0x3 0x1 #define MX8MP_IOMUXC_I2C2_SCL__ENET_QOS_1588_EVENT1_AUX_IN 0x208 0x468 0x000 0x4 0x0 #define MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16 0x208 0x468 0x000 0x5 0x0 -#define MX8MP_IOMUXC_I2C2_SCL__TPSMP_HDATA18 0x208 0x468 0x000 0x7 0x0 #define MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x20C 0x46C 0x5B0 0x0 0x2 #define MX8MP_IOMUXC_I2C2_SDA__ENET_QOS_1588_EVENT1_OUT 0x20C 0x46C 0x000 0x1 0x0 #define MX8MP_IOMUXC_I2C2_SDA__USDHC3_WP 0x20C 0x46C 0x634 0x2 0x3 #define MX8MP_IOMUXC_I2C2_SDA__ECSPI1_SS0 0x20C 0x46C 0x564 0x3 0x1 #define MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17 0x20C 0x46C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_I2C2_SDA__TPSMP_HDATA19 0x20C 0x46C 0x000 0x7 0x0 #define MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x210 0x470 0x5B4 0x0 0x4 #define MX8MP_IOMUXC_I2C3_SCL__PWM4_OUT 0x210 0x470 0x000 0x1 0x0 #define MX8MP_IOMUXC_I2C3_SCL__GPT2_CLK 0x210 0x470 0x000 0x2 0x0 #define MX8MP_IOMUXC_I2C3_SCL__ECSPI2_SCLK 0x210 0x470 0x568 0x3 0x2 #define MX8MP_IOMUXC_I2C3_SCL__GPIO5_IO18 0x210 0x470 0x000 0x5 0x0 -#define MX8MP_IOMUXC_I2C3_SCL__TPSMP_HDATA20 0x210 0x470 0x000 0x7 0x0 #define MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x214 0x474 0x5B8 0x0 0x4 #define MX8MP_IOMUXC_I2C3_SDA__PWM3_OUT 0x214 0x474 0x000 0x1 0x0 #define MX8MP_IOMUXC_I2C3_SDA__GPT3_CLK 0x214 0x474 0x000 0x2 0x0 #define MX8MP_IOMUXC_I2C3_SDA__ECSPI2_MOSI 0x214 0x474 0x570 0x3 0x2 #define MX8MP_IOMUXC_I2C3_SDA__GPIO5_IO19 0x214 0x474 0x000 0x5 0x0 -#define MX8MP_IOMUXC_I2C3_SDA__TPSMP_HDATA21 0x214 0x474 0x000 0x7 0x0 #define MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x218 0x478 0x5BC 0x0 0x5 #define MX8MP_IOMUXC_I2C4_SCL__PWM2_OUT 0x218 0x478 0x000 0x1 0x0 -#define MX8MP_IOMUXC_I2C4_SCL__HSIOMIX_PCIE_CLKREQ_B 0x218 0x478 0x5A0 0x2 0x0 +#define MX8MP_IOMUXC_I2C4_SCL__PCIE_CLKREQ_B 0x218 0x478 0x5A0 0x2 0x0 #define MX8MP_IOMUXC_I2C4_SCL__ECSPI2_MISO 0x218 0x478 0x56C 0x3 0x2 #define MX8MP_IOMUXC_I2C4_SCL__GPIO5_IO20 0x218 0x478 0x000 0x5 0x0 -#define MX8MP_IOMUXC_I2C4_SCL__TPSMP_HDATA22 0x218 0x478 0x000 0x7 0x0 #define MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x21C 0x47C 0x5C0 0x0 0x5 #define MX8MP_IOMUXC_I2C4_SDA__PWM1_OUT 0x21C 0x47C 0x000 0x1 0x0 #define MX8MP_IOMUXC_I2C4_SDA__ECSPI2_SS0 0x21C 0x47C 0x574 0x3 0x2 #define MX8MP_IOMUXC_I2C4_SDA__GPIO5_IO21 0x21C 0x47C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_I2C4_SDA__TPSMP_HDATA23 0x21C 0x47C 0x000 0x7 0x0 #define MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x220 0x480 0x5E8 0x0 0x4 #define MX8MP_IOMUXC_UART1_RXD__UART1_DTE_TX 0x220 0x480 0x000 0x0 0x0 #define MX8MP_IOMUXC_UART1_RXD__ECSPI3_SCLK 0x220 0x480 0x000 0x1 0x0 #define MX8MP_IOMUXC_UART1_RXD__GPIO5_IO22 0x220 0x480 0x000 0x5 0x0 -#define MX8MP_IOMUXC_UART1_RXD__TPSMP_HDATA24 0x220 0x480 0x000 0x7 0x0 #define MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x224 0x484 0x000 0x0 0x0 #define MX8MP_IOMUXC_UART1_TXD__UART1_DTE_RX 0x224 0x484 0x5E8 0x0 0x5 #define MX8MP_IOMUXC_UART1_TXD__ECSPI3_MOSI 0x224 0x484 0x000 0x1 0x0 #define MX8MP_IOMUXC_UART1_TXD__GPIO5_IO23 0x224 0x484 0x000 0x5 0x0 -#define MX8MP_IOMUXC_UART1_TXD__TPSMP_HDATA25 0x224 0x484 0x000 0x7 0x0 #define MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x228 0x488 0x5F0 0x0 0x6 #define MX8MP_IOMUXC_UART2_RXD__UART2_DTE_TX 0x228 0x488 0x000 0x0 0x0 #define MX8MP_IOMUXC_UART2_RXD__ECSPI3_MISO 0x228 0x488 0x000 0x1 0x0 #define MX8MP_IOMUXC_UART2_RXD__GPT1_COMPARE3 0x228 0x488 0x000 0x3 0x0 #define MX8MP_IOMUXC_UART2_RXD__GPIO5_IO24 0x228 0x488 0x000 0x5 0x0 -#define MX8MP_IOMUXC_UART2_RXD__TPSMP_HDATA26 0x228 0x488 0x000 0x7 0x0 #define MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x22C 0x48C 0x000 0x0 0x0 #define MX8MP_IOMUXC_UART2_TXD__UART2_DTE_RX 0x22C 0x48C 0x5F0 0x0 0x7 #define MX8MP_IOMUXC_UART2_TXD__ECSPI3_SS0 0x22C 0x48C 0x000 0x1 0x0 #define MX8MP_IOMUXC_UART2_TXD__GPT1_COMPARE2 0x22C 0x48C 0x000 0x3 0x0 #define MX8MP_IOMUXC_UART2_TXD__GPIO5_IO25 0x22C 0x48C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_UART2_TXD__TPSMP_HDATA27 0x22C 0x48C 0x000 0x7 0x0 #define MX8MP_IOMUXC_UART3_RXD__UART3_DCE_RX 0x230 0x490 0x5F8 0x0 0x6 #define MX8MP_IOMUXC_UART3_RXD__UART3_DTE_TX 0x230 0x490 0x000 0x0 0x0 #define MX8MP_IOMUXC_UART3_RXD__UART1_DCE_CTS 0x230 0x490 0x000 0x1 0x0 @@ -881,7 +755,6 @@ #define MX8MP_IOMUXC_UART3_RXD__GPT1_CAPTURE2 0x230 0x490 0x598 0x3 0x1 #define MX8MP_IOMUXC_UART3_RXD__CAN2_TX 0x230 0x490 0x000 0x4 0x0 #define MX8MP_IOMUXC_UART3_RXD__GPIO5_IO26 0x230 0x490 0x000 0x5 0x0 -#define MX8MP_IOMUXC_UART3_RXD__TPSMP_HDATA28 0x230 0x490 0x000 0x7 0x0 #define MX8MP_IOMUXC_UART3_TXD__UART3_DCE_TX 0x234 0x494 0x000 0x0 0x0 #define MX8MP_IOMUXC_UART3_TXD__UART3_DTE_RX 0x234 0x494 0x5F8 0x0 0x7 #define MX8MP_IOMUXC_UART3_TXD__UART1_DCE_RTS 0x234 0x494 0x5E4 0x1 0x5 @@ -890,16 +763,14 @@ #define MX8MP_IOMUXC_UART3_TXD__GPT1_CLK 0x234 0x494 0x59C 0x3 0x1 #define MX8MP_IOMUXC_UART3_TXD__CAN2_RX 0x234 0x494 0x550 0x4 0x2 #define MX8MP_IOMUXC_UART3_TXD__GPIO5_IO27 0x234 0x494 0x000 0x5 0x0 -#define MX8MP_IOMUXC_UART3_TXD__TPSMP_HDATA29 0x234 0x494 0x000 0x7 0x0 #define MX8MP_IOMUXC_UART4_RXD__UART4_DCE_RX 0x238 0x498 0x600 0x0 0x8 #define MX8MP_IOMUXC_UART4_RXD__UART4_DTE_TX 0x238 0x498 0x000 0x0 0x0 #define MX8MP_IOMUXC_UART4_RXD__UART2_DCE_CTS 0x238 0x498 0x000 0x1 0x0 #define MX8MP_IOMUXC_UART4_RXD__UART2_DTE_RTS 0x238 0x498 0x5EC 0x1 0x4 -#define MX8MP_IOMUXC_UART4_RXD__HSIOMIX_PCIE_CLKREQ_B 0x238 0x498 0x5A0 0x2 0x1 +#define MX8MP_IOMUXC_UART4_RXD__PCIE_CLKREQ_B 0x238 0x498 0x5A0 0x2 0x1 #define MX8MP_IOMUXC_UART4_RXD__GPT1_COMPARE1 0x238 0x498 0x000 0x3 0x0 #define MX8MP_IOMUXC_UART4_RXD__I2C6_SCL 0x238 0x498 0x5CC 0x4 0x2 #define MX8MP_IOMUXC_UART4_RXD__GPIO5_IO28 0x238 0x498 0x000 0x5 0x0 -#define MX8MP_IOMUXC_UART4_RXD__TPSMP_HDATA30 0x238 0x498 0x000 0x7 0x0 #define MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x23C 0x49C 0x000 0x0 0x0 #define MX8MP_IOMUXC_UART4_TXD__UART4_DTE_RX 0x23C 0x49C 0x600 0x0 0x9 #define MX8MP_IOMUXC_UART4_TXD__UART2_DCE_RTS 0x23C 0x49C 0x5EC 0x1 0x5 @@ -907,23 +778,20 @@ #define MX8MP_IOMUXC_UART4_TXD__GPT1_CAPTURE1 0x23C 0x49C 0x594 0x3 0x1 #define MX8MP_IOMUXC_UART4_TXD__I2C6_SDA 0x23C 0x49C 0x5D0 0x4 0x2 #define MX8MP_IOMUXC_UART4_TXD__GPIO5_IO29 0x23C 0x49C 0x000 0x5 0x0 -#define MX8MP_IOMUXC_UART4_TXD__TPSMP_HDATA31 0x23C 0x49C 0x000 0x7 0x0 -#define MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_EARC_SCL 0x240 0x4A0 0x000 0x0 0x0 +#define MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x240 0x4A0 0x000 0x0 0x0 #define MX8MP_IOMUXC_HDMI_DDC_SCL__I2C5_SCL 0x240 0x4A0 0x5C4 0x3 0x3 #define MX8MP_IOMUXC_HDMI_DDC_SCL__CAN1_TX 0x240 0x4A0 0x000 0x4 0x0 #define MX8MP_IOMUXC_HDMI_DDC_SCL__GPIO3_IO26 0x240 0x4A0 0x000 0x5 0x0 -#define MX8MP_IOMUXC_HDMI_DDC_SCL__AUDIOMIX_test_out00 0x240 0x4A0 0x000 0x6 0x0 -#define MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_EARC_SDA 0x244 0x4A4 0x000 0x0 0x0 +#define MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x244 0x4A4 0x000 0x0 0x0 #define MX8MP_IOMUXC_HDMI_DDC_SDA__I2C5_SDA 0x244 0x4A4 0x5C8 0x3 0x3 #define MX8MP_IOMUXC_HDMI_DDC_SDA__CAN1_RX 0x244 0x4A4 0x54C 0x4 0x3 #define MX8MP_IOMUXC_HDMI_DDC_SDA__GPIO3_IO27 0x244 0x4A4 0x000 0x5 0x0 -#define MX8MP_IOMUXC_HDMI_DDC_SDA__AUDIOMIX_test_out01 0x244 0x4A4 0x000 0x6 0x0 -#define MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_EARC_CEC 0x248 0x4A8 0x000 0x0 0x0 +#define MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x248 0x4A8 0x000 0x0 0x0 #define MX8MP_IOMUXC_HDMI_CEC__I2C6_SCL 0x248 0x4A8 0x5CC 0x3 0x3 #define MX8MP_IOMUXC_HDMI_CEC__CAN2_TX 0x248 0x4A8 0x000 0x4 0x0 #define MX8MP_IOMUXC_HDMI_CEC__GPIO3_IO28 0x248 0x4A8 0x000 0x5 0x0 -#define MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_EARC_DC_HPD 0x24C 0x4AC 0x000 0x0 0x0 -#define MX8MP_IOMUXC_HDMI_HPD__AUDIOMIX_EARC_HDMI_HPD_O 0x24C 0x4AC 0x000 0x1 0x0 +#define MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x24C 0x4AC 0x000 0x0 0x0 +#define MX8MP_IOMUXC_HDMI_HPD__AUDIOMIX_HDMI_HPD_O 0x24C 0x4AC 0x000 0x1 0x0 #define MX8MP_IOMUXC_HDMI_HPD__I2C6_SDA 0x24C 0x4AC 0x5D0 0x3 0x3 #define MX8MP_IOMUXC_HDMI_HPD__CAN2_RX 0x24C 0x4AC 0x550 0x4 0x3 #define MX8MP_IOMUXC_HDMI_HPD__GPIO3_IO29 0x24C 0x4AC 0x000 0x5 0x0 diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index 9de2aa1c573c..6038f66aefc1 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi @@ -702,7 +702,7 @@ reg = <0x30bd0000 0x10000>; interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MP_CLK_SDMA1_ROOT>, - <&clk IMX8MP_CLK_SDMA1_ROOT>; + <&clk IMX8MP_CLK_AHB>; clock-names = "ipg", "ahb"; #dma-cells = <3>; fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin"; @@ -713,7 +713,8 @@ reg = <0x30be0000 0x10000>; interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MP_CLK_ENET1_ROOT>, <&clk IMX8MP_CLK_SIM_ENET_ROOT>, <&clk IMX8MP_CLK_ENET_TIMER>, diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts index c9241abf0df3..2418cca00bc5 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts @@ -132,13 +132,15 @@ }; }; +&dphy { + status = "okay"; +}; + &fec1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec1>; phy-mode = "rgmii-id"; phy-handle = <ðphy0>; - phy-reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; - phy-reset-duration = <10>; fsl,magic-packet; status = "okay"; @@ -149,6 +151,8 @@ ethphy0: ethernet-phy@0 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <0>; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; }; }; }; @@ -157,7 +161,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_wifi_reset>; - wl-reg-on { + wl-reg-on-hog { gpio-hog; gpios = <29 GPIO_ACTIVE_HIGH>; output-high; @@ -255,6 +259,40 @@ }; }; +&lcdif { + status = "okay"; +}; + +&mipi_dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + panel@0 { + pinctrl-0 = <&pinctrl_mipi_dsi>; + pinctrl-names = "default"; + compatible = "raydium,rm67191"; + reg = <0>; + reset-gpios = <&gpio5 6 GPIO_ACTIVE_LOW>; + dsi-lanes = <4>; + + port { + panel_in: endpoint { + remote-endpoint = <&mipi_dsi_out>; + }; + }; + }; + + ports { + port@1 { + reg = <1>; + mipi_dsi_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; +}; + &pcie0 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcie0>; @@ -388,6 +426,12 @@ >; }; + pinctrl_mipi_dsi: mipidsigrp { + fsl,pins = < + MX8MQ_IOMUXC_ECSPI1_SCLK_GPIO5_IO6 0x16 + >; + }; + pinctrl_pcie0: pcie0grp { fsl,pins = < MX8MQ_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B 0x76 @@ -407,7 +451,7 @@ >; }; - pinctrl_reg_usdhc2: regusdhc2grpgpio { + pinctrl_reg_usdhc2: regusdhc2gpiogrp { fsl,pins = < MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 >; diff --git a/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts b/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts index bfd91c1ed6a5..366693f31992 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts @@ -214,13 +214,13 @@ >; }; - pinctrl_usdhc2_gpio: usdhc2grpgpio { + pinctrl_usdhc2_gpio: usdhc2gpiogrp { fsl,pins = < MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x41 >; }; - pinctrl_usdhc2_vmmc: usdhc2vmmcgpio { + pinctrl_usdhc2_vmmc: usdhc2vmmcgpiogrp { fsl,pins = < MX8MQ_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x41 >; @@ -238,7 +238,7 @@ >; }; - pinctrl_usdhc2_100mhz: usdhc2grp100mhz { + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x8d MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xcd @@ -250,7 +250,7 @@ >; }; - pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x9f MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xdf diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts b/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts index 6900ac274f5b..af139b283daf 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts @@ -6,6 +6,7 @@ /dts-v1/; #include "dt-bindings/input/input.h" +#include <dt-bindings/interrupt-controller/irq.h> #include "dt-bindings/pwm/pwm.h" #include "dt-bindings/usb/pd.h" #include "imx8mq.dtsi" @@ -60,7 +61,7 @@ label = "WWAN_WAKE"; gpios = <&gpio3 8 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio3>; - interrupts = <8 GPIO_ACTIVE_LOW>; + interrupts = <8 IRQ_TYPE_LEVEL_LOW>; wakeup-source; linux,code = <KEY_PHONE>; }; @@ -285,10 +286,10 @@ pinctrl-0 = <&pinctrl_pmic>; clocks = <&pmic_osc>; clock-names = "osc"; + #clock-cells = <0>; clock-output-names = "pmic_clk"; interrupt-parent = <&gpio1>; - interrupts = <3 GPIO_ACTIVE_LOW>; - interrupt-names = "irq"; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; rohm,reset-snvs-powered; regulators { @@ -734,7 +735,7 @@ >; }; - pinctrl_usdhc1_100mhz: usdhc1grp100mhz { + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x8d MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xcd @@ -751,7 +752,7 @@ >; }; - pinctrl_usdhc1_200mhz: usdhc1grp200mhz { + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x9f MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xdf @@ -768,13 +769,13 @@ >; }; - pinctrl_usdhc2_pwr: usdhc2grppwr { + pinctrl_usdhc2_pwr: usdhc2pwrgrp { fsl,pins = < MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 >; }; - pinctrl_usdhc2_gpio: usdhc2grpgpio { + pinctrl_usdhc2_gpio: usdhc2gpiogrp { fsl,pins = < MX8MQ_IOMUXC_SD2_WP_GPIO2_IO20 0x80 /* WIFI_WAKE */ >; @@ -791,7 +792,7 @@ >; }; - pinctrl_usdhc2_100mhz: usdhc2grp100mhz { + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x8d MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xcd @@ -802,7 +803,7 @@ >; }; - pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x9f MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xcf @@ -834,6 +835,39 @@ }; }; +&lcdif { + status = "okay"; +}; + +&mipi_dsi { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "rocktech,jh057n00900"; + reg = <0>; + backlight = <&backlight_dsi>; + reset-gpios = <&gpio3 13 GPIO_ACTIVE_LOW>; + iovcc-supply = <®_1v8_p>; + vcc-supply = <®_2v8_p>; + port { + panel_in: endpoint { + remote-endpoint = <&mipi_dsi_out>; + }; + }; + }; + + ports { + port@1 { + reg = <1>; + mipi_dsi_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; +}; + &pgc_gpu { power-supply = <&buck3_reg>; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5-r2.dts b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r2.dts new file mode 100644 index 000000000000..d77fc5df3f06 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r2.dts @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +// Copyright (C) 2020 Purism SPC <kernel@puri.sm> +// +// Librem 5 Chestnut + +/dts-v1/; + +#include "imx8mq-librem5.dtsi" + +/ { + model = "Purism Librem 5r2"; + compatible = "purism,librem5r2", "purism,librem5", "fsl,imx8mq"; +}; + +&bq25895 { + ti,battery-regulation-voltage = <4192000>; /* uV */ + ti,charge-current = <1600000>; /* uA */ + ti,termination-current = <66000>; /* uA */ +}; + +&accel_gyro { + mount-matrix = "1", "0", "0", + "0", "-1", "0", + "0", "0", "1"; +}; + +&proximity { + proximity-near-level = <220>; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts new file mode 100644 index 000000000000..6704ea2c72a3 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +// Copyright (C) 2020 Purism SPC <kernel@puri.sm> + +/dts-v1/; + +#include "imx8mq-librem5.dtsi" + +/ { + model = "Purism Librem 5r3"; + compatible = "purism,librem5r3", "purism,librem5", "fsl,imx8mq"; +}; + +&accel_gyro { + mount-matrix = "1", "0", "0", + "0", "1", "0", + "0", "0", "-1"; +}; + +&bq25895 { + ti,battery-regulation-voltage = <4200000>; /* uV */ + ti,charge-current = <1500000>; /* uA */ + ti,termination-current = <144000>; /* uA */ +}; + +&proximity { + proximity-near-level = <25>; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi new file mode 100644 index 000000000000..e3c6d1272198 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi @@ -0,0 +1,1106 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018-2020 Purism SPC + */ + +/dts-v1/; + +#include "dt-bindings/input/input.h" +#include <dt-bindings/interrupt-controller/irq.h> +#include "dt-bindings/pwm/pwm.h" +#include "dt-bindings/usb/pd.h" +#include "imx8mq.dtsi" + +/ { + model = "Purism Librem 5"; + compatible = "purism,librem5", "fsl,imx8mq"; + + backlight_dsi: backlight-dsi { + compatible = "led-backlight"; + leds = <&led_backlight>; + }; + + pmic_osc: clock-pmic { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "pmic_osc"; + }; + + chosen { + stdout-path = &uart1; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_keys>; + + vol-down { + label = "VOL_DOWN"; + gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEDOWN>; + }; + + vol-up { + label = "VOL_UP"; + gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEUP>; + }; + }; + + reg_aud_1v8: regulator-audio-1v8 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audiopwr>; + regulator-name = "AUDIO_PWR_EN"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio1 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_gnss: regulator-gnss { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gnsspwr>; + regulator-name = "GNSS"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio3 12 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_hub: regulator-hub { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hub_pwr>; + regulator-name = "HUB"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_lcd_3v4: regulator-lcd-3v4 { + compatible = "regulator-fixed"; + regulator-name = "LCD_3V4"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_dsibiasen>; + vin-supply = <®_vsys_3v4>; + gpio = <&gpio1 20 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_vdd_sen: regulator-vdd-sen { + compatible = "regulator-fixed"; + regulator-name = "VDD_SEN"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_vdd_3v3: regulator-vdd-3v3 { + compatible = "regulator-fixed"; + regulator-name = "VDD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_vdd_1v8: regulator-vdd-1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + reg_vsys_3v4: regulator-vsys-3v4 { + compatible = "regulator-fixed"; + regulator-name = "VSYS_3V4"; + regulator-min-microvolt = <3400000>; + regulator-max-microvolt = <3400000>; + regulator-always-on; + }; + + reg_wifi_3v3: regulator-wifi-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3V3_WIFI"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + sound { + compatible = "simple-audio-card"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hp>; + simple-audio-card,name = "Librem 5"; + simple-audio-card,format = "i2s"; + simple-audio-card,widgets = + "Headphone", "Headphones", + "Microphone", "Headset Mic", + "Microphone", "Digital Mic", + "Speaker", "Speaker"; + simple-audio-card,routing = + "Headphones", "HPOUTL", + "Headphones", "HPOUTR", + "Speaker", "SPKOUTL", + "Speaker", "SPKOUTR", + "Headset Mic", "MICBIAS", + "IN3R", "Headset Mic", + "DMICDAT", "Digital Mic"; + simple-audio-card,hp-det-gpio = <&gpio3 9 GPIO_ACTIVE_HIGH>; + + simple-audio-card,cpu { + sound-dai = <&sai2>; + }; + + simple-audio-card,codec { + sound-dai = <&codec>; + clocks = <&clk IMX8MQ_CLK_SAI2_ROOT>; + frame-master; + bitclock-master; + }; + }; + + sound-wwan { + compatible = "simple-audio-card"; + simple-audio-card,name = "Modem"; + simple-audio-card,format = "i2s"; + + simple-audio-card,cpu { + sound-dai = <&sai6>; + frame-inversion; + }; + + simple-audio-card,codec { + sound-dai = <&bm818_codec>; + frame-master; + bitclock-master; + }; + }; + + bm818_codec: sound-wwan-codec { + compatible = "broadmobi,bm818", "option,gtm601"; + #sound-dai-cells = <0>; + }; + + vibrator { + compatible = "pwm-vibrator"; + pwms = <&pwm1 0 1000000000 0>; + pwm-names = "enable"; + vcc-supply = <®_vdd_3v3>; + }; +}; + +&A53_0 { + 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>; + + ddrc_opp_table: ddrc-opp-table { + compatible = "operating-points-v2"; + + opp-25M { + opp-hz = /bits/ 64 <25000000>; + }; + + opp-100M { + opp-hz = /bits/ 64 <100000000>; + }; + + opp-800M { + opp-hz = /bits/ 64 <800000000>; + }; + }; +}; + +&dphy { + status = "okay"; +}; + +&ecspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1>; + cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + nor_flash: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; + }; +}; + +&gpio1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic_5v>; + + pmic-5v { + gpio-hog; + gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; + input; + }; +}; + +&iomuxc { + pinctrl_audiopwr: audiopwrgrp { + fsl,pins = < + /* AUDIO_POWER_EN_3V3 */ + MX8MQ_IOMUXC_GPIO1_IO04_GPIO1_IO4 0x83 + >; + }; + + pinctrl_bl: blgrp { + fsl,pins = < + /* BACKLINGE_EN */ + MX8MQ_IOMUXC_NAND_DQS_GPIO3_IO14 0x83 + >; + }; + + pinctrl_charger_in: chargeringrp { + fsl,pins = < + /* CHRG_INT */ + MX8MQ_IOMUXC_NAND_CE2_B_GPIO3_IO3 0x00 + /* CHG_STATUS_B */ + MX8MQ_IOMUXC_NAND_ALE_GPIO3_IO0 0x80 + >; + }; + + pinctrl_dsibiasen: dsibiasengrp { + fsl,pins = < + /* DSI_BIAS_EN */ + MX8MQ_IOMUXC_ENET_TD1_GPIO1_IO20 0x83 + >; + }; + + pinctrl_dsien: dsiengrp { + fsl,pins = < + /* DSI_EN_3V3 */ + MX8MQ_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x83 + >; + }; + + pinctrl_ecspi1: ecspigrp { + fsl,pins = < + MX8MQ_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x83 + MX8MQ_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x83 + MX8MQ_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x19 + MX8MQ_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK 0x83 + >; + }; + + pinctrl_gauge: gaugegrp { + fsl,pins = < + /* BAT_LOW */ + MX8MQ_IOMUXC_SAI5_RXC_GPIO3_IO20 0x80 + >; + }; + + pinctrl_gnsspwr: gnsspwrgrp { + fsl,pins = < + /* GPS3V3_EN */ + MX8MQ_IOMUXC_NAND_DATA06_GPIO3_IO12 0x83 + >; + }; + + pinctrl_haptic: hapticgrp { + fsl,pins = < + /* MOTO */ + MX8MQ_IOMUXC_SPDIF_EXT_CLK_PWM1_OUT 0x83 + >; + }; + + pinctrl_hp: hpgrp { + fsl,pins = < + /* HEADPHONE_DET_1V8 */ + MX8MQ_IOMUXC_NAND_DATA03_GPIO3_IO9 0x180 + >; + }; + + pinctrl_hub_pwr: hubpwrgrp { + fsl,pins = < + /* HUB_PWR_3V3_EN */ + MX8MQ_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x83 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x40000026 + MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x40000026 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x40000026 + MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x40000026 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL 0x40000026 + MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA 0x40000026 + >; + }; + + pinctrl_i2c4: i2c4grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000026 + MX8MQ_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000026 + >; + }; + + pinctrl_keys: keysgrp { + fsl,pins = < + /* VOL- */ + MX8MQ_IOMUXC_ENET_MDIO_GPIO1_IO17 0x01C0 + /* VOL+ */ + MX8MQ_IOMUXC_ENET_MDC_GPIO1_IO16 0x01C0 + >; + }; + + pinctrl_led_b: ledbgrp { + fsl,pins = < + /* LED_B */ + MX8MQ_IOMUXC_GPIO1_IO13_PWM2_OUT 0x06 + >; + }; + + pinctrl_led_g: ledggrp { + fsl,pins = < + /* LED_G */ + MX8MQ_IOMUXC_SAI3_MCLK_PWM4_OUT 0x06 + >; + }; + + pinctrl_led_r: ledrgrp { + fsl,pins = < + /* LED_R */ + MX8MQ_IOMUXC_SPDIF_TX_PWM3_OUT 0x06 + >; + }; + + pinctrl_mag: maggrp { + fsl,pins = < + /* INT_MAG */ + MX8MQ_IOMUXC_SAI5_RXD1_GPIO3_IO22 0x80 + >; + }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + /* PMIC_NINT */ + MX8MQ_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x80 + >; + }; + + pinctrl_pmic_5v: pmic5vgrp { + fsl,pins = < + /* PMIC_5V */ + MX8MQ_IOMUXC_GPIO1_IO01_GPIO1_IO1 0x80 + >; + }; + + pinctrl_prox: proxgrp { + fsl,pins = < + /* INT_LIGHT */ + MX8MQ_IOMUXC_NAND_DATA01_GPIO3_IO7 0x80 + >; + }; + + pinctrl_rtc: rtcgrp { + fsl,pins = < + /* RTC_INT */ + MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x80 + >; + }; + + pinctrl_sai2: sai2grp { + fsl,pins = < + MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6 + MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6 + MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6 + MX8MQ_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0xd6 + MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6 + >; + }; + + pinctrl_sai6: sai6grp { + fsl,pins = < + MX8MQ_IOMUXC_SAI1_RXD5_SAI6_RX_DATA0 0xd6 + MX8MQ_IOMUXC_SAI1_RXD6_SAI6_RX_SYNC 0xd6 + MX8MQ_IOMUXC_SAI1_TXD4_SAI6_RX_BCLK 0xd6 + MX8MQ_IOMUXC_SAI1_TXD5_SAI6_TX_DATA0 0xd6 + >; + }; + + pinctrl_tcpc: tcpcgrp { + fsl,pins = < + /* TCPC_INT */ + MX8MQ_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x01C0 + >; + }; + + pinctrl_typec: typecgrp { + fsl,pins = < + /* TYPEC_MUX_EN */ + MX8MQ_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x83 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x49 + MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x49 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX 0x49 + MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX 0x49 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX8MQ_IOMUXC_UART3_RXD_UART3_DCE_RX 0x49 + MX8MQ_IOMUXC_UART3_TXD_UART3_DCE_TX 0x49 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX8MQ_IOMUXC_ECSPI2_SCLK_UART4_DCE_RX 0x49 + MX8MQ_IOMUXC_ECSPI2_MOSI_UART4_DCE_TX 0x49 + MX8MQ_IOMUXC_ECSPI2_MISO_UART4_DCE_CTS_B 0x49 + MX8MQ_IOMUXC_ECSPI2_SS0_UART4_DCE_RTS_B 0x49 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x83 + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc3 + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc3 + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc3 + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc3 + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc3 + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc3 + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc3 + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc3 + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc3 + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x83 + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc1_100mhz: usdhc1grp100mhz { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x8d + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xcd + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xcd + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xcd + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xcd + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xcd + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xcd + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xcd + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xcd + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xcd + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x8d + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1grp200mhz { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x9f + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xdf + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xdf + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xdf + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xdf + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xdf + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xdf + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xdf + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xdf + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xdf + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x9f + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x80 + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x83 + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc3 + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc3 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc3 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc3 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc3 + MX8MQ_IOMUXC_SD2_RESET_B_USDHC2_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2grp100mhz { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x80 + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x8d + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xcd + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xcd + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xcd + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xcd + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xcd + MX8MQ_IOMUXC_SD2_RESET_B_USDHC2_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x80 + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x9f + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xcf + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xcf + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xcf + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xcf + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xcf + MX8MQ_IOMUXC_SD2_RESET_B_USDHC2_RESET_B 0xc1 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + /* nWDOG */ + MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0x1f + >; + }; +}; + +&i2c1 { + clock-frequency = <387000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + typec_pd: usb-pd@3f { + compatible = "ti,tps6598x"; + reg = <0x3f>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_typec>, <&pinctrl_tcpc>; + interrupt-parent = <&gpio1>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "irq"; + + connector { + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_con_hs: endpoint { + remote-endpoint = <&typec_hs>; + }; + }; + + port@1 { + reg = <1>; + + usb_con_ss: endpoint { + remote-endpoint = <&typec_ss>; + }; + }; + }; + }; + }; + + pmic: pmic@4b { + compatible = "rohm,bd71837"; + reg = <0x4b>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic>; + clocks = <&pmic_osc>; + clock-names = "osc"; + clock-output-names = "pmic_clk"; + interrupt-parent = <&gpio1>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + rohm,reset-snvs-powered; + + regulators { + buck1_reg: BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <900000>; + rohm,dvs-idle-voltage = <850000>; + rohm,dvs-suspend-voltage = <800000>; + regulator-always-on; + }; + + buck2_reg: BUCK2 { + regulator-name = "buck2"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <1000000>; + rohm,dvs-idle-voltage = <900000>; + regulator-always-on; + }; + + buck3_reg: BUCK3 { + regulator-name = "buck3"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + rohm,dvs-run-voltage = <900000>; + regulator-always-on; + }; + + buck4_reg: BUCK4 { + regulator-name = "buck4"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + rohm,dvs-run-voltage = <1000000>; + }; + + buck5_reg: BUCK5 { + regulator-name = "buck5"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + }; + + buck6_reg: BUCK6 { + regulator-name = "buck6"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + buck7_reg: BUCK7 { + regulator-name = "buck7"; + regulator-min-microvolt = <1605000>; + regulator-max-microvolt = <1995000>; + regulator-always-on; + }; + + buck8_reg: BUCK8 { + regulator-name = "buck8"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-always-on; + }; + + ldo1_reg: LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + /* leave on for snvs power button */ + regulator-always-on; + }; + + ldo2_reg: LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + /* leave on for snvs power button */ + regulator-always-on; + }; + + ldo3_reg: LDO3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + ldo4_reg: LDO4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ldo5_reg: LDO5 { + /* VDD_PHY_0V9 - MIPI and HDMI domains */ + regulator-name = "ldo5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + ldo6_reg: LDO6 { + /* VDD_PHY_0V9 - MIPI, HDMI and USB domains */ + regulator-name = "ldo6"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ldo7_reg: LDO7 { + /* VDD_PHY_3V3 - USB domain */ + regulator-name = "ldo7"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + }; + + rtc@68 { + compatible = "microcrystal,rv4162"; + reg = <0x68>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rtc>; + interrupt-parent = <&gpio1>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&i2c2 { + clock-frequency = <387000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + magnetometer@1e { + compatible = "st,lsm9ds1-magn"; + reg = <0x1e>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mag>; + interrupt-parent = <&gpio3>; + interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; + vdd-supply = <®_vdd_sen>; + vddio-supply = <®_vdd_1v8>; + }; + + regulator@3e { + compatible = "tps65132"; + reg = <0x3e>; + + outp { + regulator-name = "LCD_AVDD"; + vin-supply = <®_lcd_3v4>; + }; + + outn { + regulator-name = "LCD_AVEE"; + vin-supply = <®_lcd_3v4>; + }; + }; + + proximity: prox@60 { + compatible = "vishay,vcnl4040"; + reg = <0x60>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_prox>; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + }; + + accel_gyro: accel-gyro@6a { + compatible = "st,lsm9ds1-imu"; + reg = <0x6a>; + vdd-supply = <®_vdd_sen>; + vddio-supply = <®_vdd_1v8>; + }; +}; + +&i2c3 { + clock-frequency = <387000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + codec: audio-codec@1a { + compatible = "wlf,wm8962"; + reg = <0x1a>; + clocks = <&clk IMX8MQ_CLK_SAI2_ROOT>; + assigned-clocks = <&clk IMX8MQ_CLK_SAI2>; + assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>; + assigned-clock-rates = <24576000>; + #sound-dai-cells = <0>; + mic-cfg = <0x200>; + DCVDD-supply = <®_aud_1v8>; + DBVDD-supply = <®_aud_1v8>; + AVDD-supply = <®_aud_1v8>; + CPVDD-supply = <®_aud_1v8>; + MICVDD-supply = <®_aud_1v8>; + PLLVDD-supply = <®_aud_1v8>; + SPKVDD1-supply = <®_vsys_3v4>; + SPKVDD2-supply = <®_vsys_3v4>; + gpio-cfg = < + 0x0000 /* n/c */ + 0x0001 /* gpio2, 1: default */ + 0x0013 /* gpio3, 2: dmicclk */ + 0x0000 /* n/c, 3: default */ + 0x8014 /* gpio5, 4: dmic_dat */ + 0x0000 /* gpio6, 5: default */ + >; + }; + + backlight@36 { + compatible = "ti,lm36922"; + reg = <0x36>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_bl>; + #address-cells = <1>; + #size-cells = <0>; + enable-gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>; + vled-supply = <®_vsys_3v4>; + ti,ovp-microvolt = <25000000>; + + led_backlight: led@0 { + reg = <0>; + label = ":backlight"; + linux,default-trigger = "backlight"; + led-max-microamp = <20000>; + }; + }; + + touchscreen@38 { + compatible = "edt,edt-ft5506"; + reg = <0x38>; + interrupt-parent = <&gpio1>; + interrupts = <27 IRQ_TYPE_EDGE_FALLING>; + touchscreen-size-x = <720>; + touchscreen-size-y = <1440>; + }; +}; + +&i2c4 { + clock-frequency = <387000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4>; + status = "okay"; + + bat: fuel-gauge@36 { + compatible = "maxim,max17055"; + reg = <0x36>; + interrupt-parent = <&gpio3>; + interrupts = <20 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gauge>; + maxim,over-heat-temp = <700>; + maxim,over-volt = <4500>; + maxim,rsns-microohm = <5000>; + }; + + bq25895: charger@6a { + compatible = "ti,bq25895", "ti,bq25890"; + reg = <0x6a>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_charger_in>; + interrupt-parent = <&gpio3>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + phys = <&usb3_phy0>; + ti,precharge-current = <130000>; /* uA */ + ti,minimum-sys-voltage = <3700000>; /* uV */ + ti,boost-voltage = <5000000>; /* uV */ + ti,boost-max-current = <500000>; /* uA */ + ti,use-vinmin-threshold = <1>; /* enable VINDPM */ + ti,vinmin-threshold = <3900000>; /* uV */ + monitored-battery = <&bat>; + }; +}; + +&pgc_gpu { + power-supply = <&buck3_reg>; +}; + +&pgc_mipi { + power-supply = <&ldo5_reg>; +}; + +&pgc_vpu { + power-supply = <&buck4_reg>; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_haptic>; + status = "okay"; +}; + +&pwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_led_b>; + status = "okay"; +}; + +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_led_g>; + status = "okay"; +}; + +&pwm4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_led_r>; + status = "okay"; +}; + +&sai2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai2>; + assigned-clocks = <&clk IMX8MQ_CLK_SAI2>; + assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>; + assigned-clock-rates = <24576000>; + assigned-clocks = <&clk IMX8MQ_AUDIO_PLL1>, <&clk IMX8MQ_AUDIO_PLL2>; + assigned-clock-rates = <786432000>, <722534400>; + status = "okay"; +}; + +&sai6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai6>; + assigned-clocks = <&clk IMX8MQ_CLK_SAI6>; + assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>; + assigned-clock-rates = <24576000>; + fsl,sai-synchronous-rx; + status = "okay"; +}; + +&snvs_pwrkey { + status = "okay"; +}; + +&snvs_rtc { + status = "disabled"; +}; + +&uart1 { /* console */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&uart2 { /* TPS - GPS - DEBUG */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; + + gnss { + compatible = "globaltop,pa6h"; + vcc-supply = <®_gnss>; + current-speed = <9600>; + }; +}; + +&uart3 { /* SMC */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + status = "okay"; +}; + +&uart4 { /* BT */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + uart-has-rtscts; + status = "okay"; +}; + +&usb3_phy0 { + status = "okay"; +}; + +&usb3_phy1 { + vbus-supply = <®_hub>; + status = "okay"; +}; + +&usb_dwc3_0 { + #address-cells = <1>; + #size-cells = <0>; + dr_mode = "otg"; + snps,dis_u3_susphy_quirk; + status = "okay"; + + port@0 { + reg = <0>; + + typec_hs: endpoint { + remote-endpoint = <&usb_con_hs>; + }; + }; + + port@1 { + reg = <1>; + + typec_ss: endpoint { + remote-endpoint = <&usb_con_ss>; + }; + }; +}; + +&usb_dwc3_1 { + dr_mode = "host"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + /* Microchip USB2642 */ + hub@1 { + compatible = "usb424,2640"; + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + mass-storage@1 { + compatible = "usb424,4041"; + reg = <1>; + }; + }; +}; + +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + bus-width = <8>; + vmmc-supply = <®_vdd_3v3>; + power-supply = <®_vdd_1v8>; + non-removable; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>; + bus-width = <4>; + vmmc-supply = <®_wifi_3v3>; + cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; + disable-wp; + cap-sdio-irq; + keep-power-in-suspend; + wakeup-source; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/freescale/imx8mq-phanbell.dts b/arch/arm64/boot/dts/freescale/imx8mq-phanbell.dts index 77ab568fae67..a3b9d615a3b4 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-phanbell.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-phanbell.dts @@ -6,6 +6,7 @@ /dts-v1/; #include "imx8mq.dtsi" +#include <dt-bindings/interrupt-controller/irq.h> / { model = "Google i.MX8MQ Phanbell"; @@ -125,7 +126,7 @@ clocks = <&pmic_osc>; clock-output-names = "pmic_clk"; interrupt-parent = <&gpio1>; - interrupts = <3 GPIO_ACTIVE_LOW>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; regulators { buck1: BUCK1 { @@ -262,9 +263,6 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec1>; phy-mode = "rgmii-id"; - phy-reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; - phy-reset-duration = <10>; - phy-reset-post-delay = <50>; phy-handle = <ðphy0>; fsl,magic-packet; status = "okay"; @@ -275,6 +273,9 @@ ethphy0: ethernet-phy@0 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <0>; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <50000>; }; }; }; @@ -365,7 +366,7 @@ >; }; - pinctrl_pmic: pmicirq { + pinctrl_pmic: pmicirqgrp { fsl,pins = < MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41 >; @@ -395,7 +396,7 @@ >; }; - pinctrl_usdhc1_100mhz: usdhc1grp100mhz { + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x85 MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc5 @@ -412,7 +413,7 @@ >; }; - pinctrl_usdhc1_200mhz: usdhc1grp200mhz { + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x87 MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc7 @@ -429,7 +430,7 @@ >; }; - pinctrl_usdhc2_gpio: usdhc2grpgpio { + pinctrl_usdhc2_gpio: usdhc2gpiogrp { fsl,pins = < MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x41 MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 @@ -448,7 +449,7 @@ >; }; - pinctrl_usdhc2_100mhz: usdhc2grp100mhz { + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x85 MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc5 @@ -460,7 +461,7 @@ >; }; - pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x87 MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc7 diff --git a/arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts b/arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts index 59da96b7143f..89cbec5c41b2 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts @@ -9,6 +9,7 @@ /dts-v1/; #include "imx8mq.dtsi" +#include <dt-bindings/interrupt-controller/irq.h> / { model = "TechNexion PICO-PI-8M"; @@ -70,7 +71,7 @@ clock-names = "osc"; clock-output-names = "pmic_clk"; interrupt-parent = <&gpio1>; - interrupts = <3 GPIO_ACTIVE_LOW>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; interrupt-names = "irq"; regulators { @@ -297,7 +298,7 @@ >; }; - pinctrl_pmic: pmicirq { + pinctrl_pmic: pmicirqgrp { fsl,pins = < MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41 >; @@ -335,7 +336,7 @@ >; }; - pinctrl_usdhc1_100mhz: usdhc1grp100mhz { + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x85 MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc5 @@ -351,7 +352,7 @@ >; }; - pinctrl_usdhc1_200mhz: usdhc1grp200mhz { + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x87 MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc7 @@ -367,7 +368,7 @@ >; }; - pinctrl_usdhc2_gpio: usdhc2grpgpio { + pinctrl_usdhc2_gpio: usdhc2gpiogrp { fsl,pins = < MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x41 >; @@ -385,7 +386,7 @@ >; }; - pinctrl_usdhc2_100mhz: usdhc2grp100mhz { + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x85 MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc5 @@ -397,7 +398,7 @@ >; }; - pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x87 MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc7 diff --git a/arch/arm64/boot/dts/freescale/imx8mq-sr-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-sr-som.dtsi index 602c870a7ccb..0187890a90c5 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-sr-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mq-sr-som.dtsi @@ -20,8 +20,6 @@ pinctrl-0 = <&pinctrl_fec1>; phy-mode = "rgmii-id"; phy-handle = <ðphy0>; - phy-reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; - phy-reset-duration = <2>; fsl,magic-packet; status = "okay"; @@ -32,6 +30,8 @@ ethphy0: ethernet-phy@4 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <4>; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + reset-assert-us = <2000>; }; }; }; @@ -275,7 +275,7 @@ >; }; - pinctrl_usdhc1_100mhz: usdhc1grp100mhz { + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x8d MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xcd @@ -292,7 +292,7 @@ >; }; - pinctrl_usdhc1_200mhz: usdhc1grp200mhz { + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { fsl,pins = < MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x9f MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xdf diff --git a/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts b/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts index b4795a032fa2..5d5aa6537225 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts @@ -122,7 +122,6 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec1>; phy-mode = "rgmii-id"; - phy-reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; phy-handle = <ðphy>; fsl,magic-packet; status = "okay"; @@ -134,6 +133,7 @@ ethphy: ethernet-phy@3 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <3>; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dts b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dts index 6b3581366d67..bfad4b885905 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dts @@ -15,7 +15,7 @@ &ecspi1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1>; - cs-gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; status = "okay"; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi index 0d1088dcaa02..fa7a041ffcfd 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi @@ -229,28 +229,28 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpio3_hog>; - usb-emulation { + usb-emulation-hog { gpio-hog; gpios = <10 GPIO_ACTIVE_HIGH>; output-low; line-name = "usb-emulation"; }; - usb-mode1 { + usb-mode1-hog { gpio-hog; gpios = <11 GPIO_ACTIVE_HIGH>; output-high; line-name = "usb-mode1"; }; - usb-pwr { + usb-pwr-hog { gpio-hog; gpios = <12 GPIO_ACTIVE_LOW>; output-high; line-name = "usb-pwr-ctrl-en-n"; }; - usb-mode2 { + usb-mode2-hog { gpio-hog; gpios = <13 GPIO_ACTIVE_HIGH>; output-high; diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi index f70435cf9ad5..5e0e7d0f1bc4 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi @@ -423,7 +423,7 @@ tmu: tmu@30260000 { compatible = "fsl,imx8mq-tmu"; reg = <0x30260000 0x10000>; - interrupt = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_TMU_ROOT>; little-endian; fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x70061>; @@ -523,6 +523,12 @@ <&clk IMX8MQ_VIDEO_PLL1_OUT>; assigned-clock-rates = <0>, <0>, <0>, <594000000>; status = "disabled"; + + port@0 { + lcdif_mipi_dsi: endpoint { + remote-endpoint = <&mipi_dsi_lcdif_in>; + }; + }; }; iomuxc: pinctrl@30330000 { @@ -617,6 +623,7 @@ gpc: gpc@303a0000 { compatible = "fsl,imx8mq-gpc"; reg = <0x303a0000 0x10000>; + interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; interrupt-parent = <&gic>; interrupt-controller; #interrupt-cells = <3>; @@ -899,6 +906,49 @@ }; }; + mipi_dsi: mipi-dsi@30a00000 { + compatible = "fsl,imx8mq-nwl-dsi"; + reg = <0x30a00000 0x300>; + clocks = <&clk IMX8MQ_CLK_DSI_CORE>, + <&clk IMX8MQ_CLK_DSI_AHB>, + <&clk IMX8MQ_CLK_DSI_IPG_DIV>, + <&clk IMX8MQ_CLK_DSI_PHY_REF>, + <&clk IMX8MQ_CLK_LCDIF_PIXEL>; + clock-names = "core", "rx_esc", "tx_esc", "phy_ref", "lcdif"; + assigned-clocks = <&clk IMX8MQ_CLK_DSI_AHB>, + <&clk IMX8MQ_CLK_DSI_CORE>, + <&clk IMX8MQ_CLK_DSI_IPG_DIV>; + assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>, + <&clk IMX8MQ_SYS1_PLL_266M>; + assigned-clock-rates = <80000000>, <266000000>, <20000000>; + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; + mux-controls = <&mux 0>; + power-domains = <&pgc_mipi>; + phys = <&dphy>; + phy-names = "dphy"; + resets = <&src IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N>, + <&src IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N>, + <&src IMX8MQ_RESET_MIPI_DSI_ESC_RESET_N>, + <&src IMX8MQ_RESET_MIPI_DSI_PCLK_RESET_N>; + reset-names = "byte", "dpi", "esc", "pclk"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mipi_dsi_lcdif_in: endpoint@0 { + reg = <0>; + remote-endpoint = <&lcdif_mipi_dsi>; + }; + }; + }; + }; + dphy: dphy@30a00300 { compatible = "fsl,imx8mq-mipi-dphy"; reg = <0x30a00300 0x100>; @@ -1031,7 +1081,8 @@ reg = <0x30be0000 0x10000>; interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_ENET1_ROOT>, <&clk IMX8MQ_CLK_ENET1_ROOT>, <&clk IMX8MQ_CLK_ENET_TIMER>, diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-colibri.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-colibri.dtsi index 75f17a29f81e..f38acff0d25c 100644 --- a/arch/arm64/boot/dts/freescale/imx8qxp-colibri.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8qxp-colibri.dtsi @@ -494,7 +494,7 @@ >; }; - pinctrl_usdhc1_100mhz: usdhc1grp100mhz { + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { fsl,pins = < IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041 IMX8QXP_EMMC0_CMD_CONN_EMMC0_CMD 0x21 @@ -511,7 +511,7 @@ >; }; - pinctrl_usdhc1_200mhz: usdhc1grp200mhz { + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { fsl,pins = < IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041 IMX8QXP_EMMC0_CMD_CONN_EMMC0_CMD 0x21 @@ -554,7 +554,7 @@ >; }; - pinctrl_usdhc2_100mhz: usdhc2grp100mhz { + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { fsl,pins = < IMX8QXP_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041 /* SODIMM 47 */ IMX8QXP_USDHC1_CMD_CONN_USDHC1_CMD 0x21 /* SODIMM 190 */ @@ -566,7 +566,7 @@ >; }; - pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { fsl,pins = < IMX8QXP_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041 /* SODIMM 47 */ IMX8QXP_USDHC1_CMD_CONN_USDHC1_CMD 0x21 /* SODIMM 190 */ diff --git a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts index c1b614dabb8e..963300eede17 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts +++ b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts @@ -530,7 +530,7 @@ rt1711h: rt1711h@4e { compatible = "richtek,rt1711h"; reg = <0x4e>; - status = "ok"; + status = "okay"; interrupt-parent = <&gpio27>; interrupts = <3 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; @@ -570,7 +570,7 @@ }; adv7533: adv7533@39 { - status = "ok"; + status = "okay"; compatible = "adi,adv7533"; reg = <0x39>; adi,dsi-lanes = <4>; @@ -656,7 +656,7 @@ &sdio_cfg_func>; /* WL_EN */ vmmc-supply = <&wlan_en>; - status = "ok"; + status = "okay"; wlcore: wlcore@2 { compatible = "ti,wl1837"; diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index d25aac5e0bf8..994140fbc916 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -1089,16 +1089,18 @@ compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xe8a06000 0x0 0x1000>; interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg_ctrl HI3660_OSC32K>; - clock-names = "apb_pclk"; + clocks = <&crg_ctrl HI3660_OSC32K>, + <&crg_ctrl HI3660_OSC32K>; + clock-names = "wdog_clk", "apb_pclk"; }; watchdog1: watchdog@e8a07000 { compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xe8a07000 0x0 0x1000>; interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg_ctrl HI3660_OSC32K>; - clock-names = "apb_pclk"; + clocks = <&crg_ctrl HI3660_OSC32K>, + <&crg_ctrl HI3660_OSC32K>; + clock-names = "wdog_clk", "apb_pclk"; }; tsensor: tsensor@fff30000 { diff --git a/arch/arm64/boot/dts/hisilicon/hi3670-hikey970.dts b/arch/arm64/boot/dts/hisilicon/hi3670-hikey970.dts index 7dac33d4fd5c..7f9f9886c349 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3670-hikey970.dts +++ b/arch/arm64/boot/dts/hisilicon/hi3670-hikey970.dts @@ -418,7 +418,7 @@ &sdio_cfg_func>; /* WL_EN */ vmmc-supply = <&wlan_en>; - status = "ok"; + status = "okay"; wlcore: wlcore@2 { compatible = "ti,wl1837"; diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts index 533ed523888d..91d08673c02e 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts @@ -267,7 +267,7 @@ &uart1 { assigned-clocks = <&sys_ctrl HI6220_UART1_SRC>; assigned-clock-rates = <150000000>; - status = "ok"; + status = "okay"; bluetooth { compatible = "ti,wl1835-st"; @@ -278,21 +278,21 @@ }; &uart2 { - status = "ok"; + status = "okay"; label = "LS-UART0"; }; &uart3 { - status = "ok"; + status = "okay"; label = "LS-UART1"; }; &ade { - status = "ok"; + status = "okay"; }; &dsi { - status = "ok"; + status = "okay"; ports { /* 1 for output port */ @@ -489,17 +489,17 @@ &i2c0 { - status = "ok"; + status = "okay"; }; &i2c1 { - status = "ok"; + status = "okay"; }; &i2c2 { #address-cells = <1>; #size-cells = <0>; - status = "ok"; + status = "okay"; adv7533: adv7533@39 { compatible = "adi,adv7533"; @@ -541,5 +541,5 @@ }; &spi0 { - status = "ok"; + status = "okay"; }; diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi index 3d189d9f0d24..014735a9bc73 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi @@ -371,7 +371,7 @@ clocks = <&sys_ctrl HI6220_EDMAC_ACLK>; dma-no-cci; dma-type = "hi6220_dma"; - status = "ok"; + status = "okay"; }; dual_timer0: timer@f8008000 { @@ -843,8 +843,9 @@ compatible = "arm,sp805-wdt", "arm,primecell"; reg = <0x0 0xf8005000 0x0 0x1000>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&ao_ctrl HI6220_WDT0_PCLK>; - clock-names = "apb_pclk"; + clocks = <&ao_ctrl HI6220_WDT0_PCLK>, + <&ao_ctrl HI6220_WDT0_PCLK>; + clock-names = "wdog_clk", "apb_pclk"; }; tsensor: tsensor@0,f7030700 { diff --git a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts index e93c65ede06c..369b69b17b91 100644 --- a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts +++ b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts @@ -42,15 +42,15 @@ }; &uart0 { - status = "ok"; + status = "okay"; }; &peri_gpio0 { - status = "ok"; + status = "okay"; }; &lbc { - status = "ok"; + status = "okay"; #address-cells = <2>; #size-cells = <1>; ranges = <0 0 0x0 0x90000000 0x08000000>, diff --git a/arch/arm64/boot/dts/hisilicon/hip06-d03.dts b/arch/arm64/boot/dts/hisilicon/hip06-d03.dts index 677862beebef..9f4a930e734d 100644 --- a/arch/arm64/boot/dts/hisilicon/hip06-d03.dts +++ b/arch/arm64/boot/dts/hisilicon/hip06-d03.dts @@ -22,37 +22,37 @@ }; &ipmi0 { - status = "ok"; + status = "okay"; }; &uart0 { - status = "ok"; + status = "okay"; }; ð0 { - status = "ok"; + status = "okay"; }; ð1 { - status = "ok"; + status = "okay"; }; ð2 { - status = "ok"; + status = "okay"; }; ð3 { - status = "ok"; + status = "okay"; }; &sas1 { - status = "ok"; + status = "okay"; }; &usb_ohci { - status = "ok"; + status = "okay"; }; &usb_ehci { - status = "ok"; + status = "okay"; }; diff --git a/arch/arm64/boot/dts/hisilicon/hip07-d05.dts b/arch/arm64/boot/dts/hisilicon/hip07-d05.dts index fcbdffe0868b..81a2312c8a26 100644 --- a/arch/arm64/boot/dts/hisilicon/hip07-d05.dts +++ b/arch/arm64/boot/dts/hisilicon/hip07-d05.dts @@ -50,41 +50,41 @@ }; &uart0 { - status = "ok"; + status = "okay"; }; &ipmi0 { - status = "ok"; + status = "okay"; }; &usb_ohci { - status = "ok"; + status = "okay"; }; &usb_ehci { - status = "ok"; + status = "okay"; }; ð0 { - status = "ok"; + status = "okay"; }; ð1 { - status = "ok"; + status = "okay"; }; ð2 { - status = "ok"; + status = "okay"; }; ð3 { - status = "ok"; + status = "okay"; }; &sas1 { - status = "ok"; + status = "okay"; }; &p0_pcie2_a { - status = "ok"; + status = "okay"; }; diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi index 9d7f19e97df7..e1c0fcba5c20 100644 --- a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi +++ b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi @@ -20,7 +20,7 @@ service_reserved: svcbuffer@0 { compatible = "shared-dma-pool"; - reg = <0x0 0x0 0x0 0x1000000>; + reg = <0x0 0x0 0x0 0x2000000>; alignment = <0x1000>; no-map; }; @@ -149,8 +149,8 @@ snps,multicast-filter-bins = <256>; iommus = <&smmu 1>; altr,sysmgr-syscon = <&sysmgr 0x44 0>; - clocks = <&clkmgr AGILEX_EMAC0_CLK>; - clock-names = "stmmaceth"; + clocks = <&clkmgr AGILEX_EMAC0_CLK>, <&clkmgr AGILEX_EMAC_PTP_CLK>; + clock-names = "stmmaceth", "ptp_ref"; status = "disabled"; }; @@ -167,8 +167,8 @@ snps,multicast-filter-bins = <256>; iommus = <&smmu 2>; altr,sysmgr-syscon = <&sysmgr 0x48 8>; - clocks = <&clkmgr AGILEX_EMAC1_CLK>; - clock-names = "stmmaceth"; + clocks = <&clkmgr AGILEX_EMAC1_CLK>, <&clkmgr AGILEX_EMAC_PTP_CLK>; + clock-names = "stmmaceth", "ptp_ref"; status = "disabled"; }; @@ -185,8 +185,8 @@ snps,multicast-filter-bins = <256>; iommus = <&smmu 3>; altr,sysmgr-syscon = <&sysmgr 0x4c 16>; - clocks = <&clkmgr AGILEX_EMAC2_CLK>; - clock-names = "stmmaceth"; + clocks = <&clkmgr AGILEX_EMAC2_CLK>, <&clkmgr AGILEX_EMAC_PTP_CLK>; + clock-names = "stmmaceth", "ptp_ref"; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/lg/lg1312.dtsi b/arch/arm64/boot/dts/lg/lg1312.dtsi index 64f3b135068d..081fe7a9f605 100644 --- a/arch/arm64/boot/dts/lg/lg1312.dtsi +++ b/arch/arm64/boot/dts/lg/lg1312.dtsi @@ -131,18 +131,18 @@ ranges; timers: timer@fd100000 { - compatible = "arm,sp804"; + compatible = "arm,sp804", "arm,primecell"; reg = <0x0 0xfd100000 0x1000>; interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_bus>; - clock-names = "apb_pclk"; + clocks = <&clk_bus>, <&clk_bus>, <&clk_bus>; + clock-names = "timer0clk", "timer1clk", "apb_pclk"; }; wdog: watchdog@fd200000 { compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xfd200000 0x1000>; interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_bus>; - clock-names = "apb_pclk"; + clocks = <&clk_bus>, <&clk_bus>; + clock-names = "wdog_clk", "apb_pclk"; }; uart0: serial@fe000000 { compatible = "arm,pl011", "arm,primecell"; diff --git a/arch/arm64/boot/dts/lg/lg1313.dtsi b/arch/arm64/boot/dts/lg/lg1313.dtsi index ac23592ab011..604bb6975337 100644 --- a/arch/arm64/boot/dts/lg/lg1313.dtsi +++ b/arch/arm64/boot/dts/lg/lg1313.dtsi @@ -131,18 +131,18 @@ ranges; timers: timer@fd100000 { - compatible = "arm,sp804"; + compatible = "arm,sp804", "arm,primecell"; reg = <0x0 0xfd100000 0x1000>; interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_bus>; - clock-names = "apb_pclk"; + clocks = <&clk_bus>, <&clk_bus>, <&clk_bus>; + clock-names = "timer0clk", "timer1clk", "apb_pclk"; }; wdog: watchdog@fd200000 { compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xfd200000 0x1000>; interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk_bus>; - clock-names = "apb_pclk"; + clocks = <&clk_bus>, <&clk_bus>; + clock-names = "wdog_clk", "apb_pclk"; }; uart0: serial@fe000000 { compatible = "arm,pl011", "arm,primecell"; diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi index 2bbc69b4dc99..d5b6c0a1c54a 100644 --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi @@ -316,7 +316,7 @@ }; pcie_reset_pins: pcie-reset-pins { - groups = "pcie1"; + groups = "pcie1"; /* this actually controls "pcie1_reset" */ function = "gpio"; }; 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 d174ad214857..9a11e5c60c26 100644 --- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts @@ -143,6 +143,56 @@ mdio: mdio-bus { #address-cells = <1>; #size-cells = <0>; + + switch@0 { + compatible = "mediatek,mt7531"; + reg = <0>; + reset-gpios = <&pio 54 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "wan"; + }; + + port@1 { + reg = <1>; + label = "lan0"; + }; + + port@2 { + reg = <2>; + label = "lan1"; + }; + + port@3 { + reg = <3>; + label = "lan2"; + }; + + port@4 { + reg = <4>; + label = "lan3"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts index 0b4de627f96e..08ad0ffb24df 100644 --- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts @@ -105,20 +105,71 @@ pinctrl-0 = <ð_pins>; status = "okay"; - gmac1: mac@1 { + gmac0: mac@0 { compatible = "mediatek,eth-mac"; - reg = <1>; - phy-handle = <&phy5>; + reg = <0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; }; mdio-bus { #address-cells = <1>; #size-cells = <0>; - phy5: ethernet-phy@5 { - reg = <5>; - phy-mode = "sgmii"; + switch@0 { + compatible = "mediatek,mt7531"; + reg = <0>; + reset-gpios = <&pio 54 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "lan0"; + }; + + port@1 { + reg = <1>; + label = "lan1"; + }; + + port@2 { + reg = <2>; + label = "lan2"; + }; + + port@3 { + reg = <3>; + label = "lan3"; + }; + + port@4 { + reg = <4>; + label = "wan"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; }; + }; }; diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi index a5a12b2599a4..44a0346133cd 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi @@ -5,6 +5,7 @@ #include <dt-bindings/input/input.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/regulator/dlg,da9211-regulator.h> #include <dt-bindings/gpio/gpio.h> #include "mt8173.dtsi" @@ -294,7 +295,8 @@ regulator-max-microamp = <4400000>; regulator-ramp-delay = <10000>; regulator-always-on; - regulator-allowed-modes = <0 1>; + regulator-allowed-modes = <DA9211_BUCK_MODE_SYNC + DA9211_BUCK_MODE_AUTO>; }; da9211_vgpu_reg: BUCKB { @@ -431,12 +433,11 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&nor_gpio1_pins>; - bus-width = <8>; - max-frequency = <50000000>; - non-removable; + flash@0 { compatible = "jedec,spi-nor"; reg = <0>; + spi-max-frequency = <50000000>; }; }; diff --git a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts index ae405bd8f06b..cba2d8933e79 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts +++ b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts @@ -25,6 +25,17 @@ chosen { stdout-path = "serial0:921600n8"; }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + scp_mem_reserved: scp_mem_region { + compatible = "shared-dma-pool"; + reg = <0 0x50000000 0 0x2900000>; + no-map; + }; + }; }; &auxadc { diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi index f0a070535b34..85f7c33ba446 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi @@ -90,6 +90,18 @@ regulator-max-microvolt = <3300000>; }; + reserved_memory: reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + scp_mem_reserved: scp_mem_region { + compatible = "shared-dma-pool"; + reg = <0 0x50000000 0 0x2900000>; + no-map; + }; + }; + max98357a: codec0 { compatible = "maxim,max98357a"; sdmode-gpios = <&pio 175 0>; @@ -524,6 +536,13 @@ }; }; + scp_pins: scp { + pins_scp_uart { + pinmux = <PINMUX_GPIO110__FUNC_TP_URXD1_AO>, + <PINMUX_GPIO112__FUNC_TP_UTXD1_AO>; + }; + }; + spi0_pins: spi0 { pins_spi{ pinmux = <PINMUX_GPIO85__FUNC_SPI0_MI>, @@ -651,6 +670,17 @@ }; }; +&scp { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&scp_pins>; + + cros_ec { + compatible = "google,cros-ec-rpmsg"; + mtk,rpmsg-name = "cros-ec-rpmsg"; + }; +}; + &soc_data { status = "okay"; }; diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi index 102105871db2..9cfd961c45eb 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi @@ -317,8 +317,7 @@ }; watchdog: watchdog@10007000 { - compatible = "mediatek,mt8183-wdt", - "mediatek,mt6589-wdt"; + compatible = "mediatek,mt8183-wdt"; reg = <0 0x10007000 0 0x100>; #reset-cells = <1>; }; @@ -339,6 +338,18 @@ clock-names = "spi", "wrap"; }; + scp: scp@10500000 { + compatible = "mediatek,mt8183-scp"; + reg = <0 0x10500000 0 0x80000>, + <0 0x105c0000 0 0x19080>; + reg-names = "sram", "cfg"; + interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&infracfg CLK_INFRA_SCPSYS>; + clock-names = "main"; + memory-region = <&scp_mem_reserved>; + status = "disabled"; + }; + systimer: timer@10017000 { compatible = "mediatek,mt8183-timer", "mediatek,mt6765-timer"; diff --git a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi index dfceffe6950a..29d8cf6df46b 100644 --- a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi +++ b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi @@ -56,7 +56,7 @@ tca6416: gpio@20 { compatible = "ti,tca6416"; reg = <0x20>; - rst-gpio = <&pio 65 GPIO_ACTIVE_HIGH>; + reset-gpios = <&pio 65 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&tca6416_pins>; diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi b/arch/arm64/boot/dts/microchip/sparx5.dtsi index cf712e80615d..3cb01c39c3c8 100644 --- a/arch/arm64/boot/dts/microchip/sparx5.dtsi +++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi @@ -5,6 +5,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/clock/microchip,sparx5.h> / { compatible = "microchip,sparx5"; @@ -13,6 +14,7 @@ #size-cells = <1>; aliases { + spi0 = &spi0; serial0 = &uart0; serial1 = &uart1; }; @@ -117,6 +119,22 @@ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; }; + cpu_ctrl: syscon@600000000 { + compatible = "microchip,sparx5-cpu-syscon", "syscon", + "simple-mfd"; + reg = <0x6 0x00000000 0xd0>; + mux: mux-controller { + compatible = "mmio-mux"; + #mux-control-cells = <0>; + /* + * SI_OWNER and SI2_OWNER in GENERAL_CTRL + * SPI: value 9 - (SIMC,SIBM) = 0b1001 + * SPI2: value 6 - (SIBM,SIMC) = 0b0110 + */ + mux-reg-masks = <0x88 0xf0>; + }; + }; + uart0: serial@600100000 { pinctrl-0 = <&uart_pins>; pinctrl-names = "default"; @@ -143,6 +161,19 @@ status = "disabled"; }; + spi0: spi@600104000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "microchip,sparx5-spi"; + reg = <0x6 0x00104000 0x40>; + num-cs = <16>; + reg-io-width = <4>; + reg-shift = <2>; + clocks = <&ahb_clk>; + interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + timer1: timer@600105000 { compatible = "snps,dw-apb-timer"; reg = <0x6 0x00105000 0x1000>; @@ -151,6 +182,20 @@ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; }; + sdhci0: mmc@600800000 { + compatible = "microchip,dw-sparx5-sdhci"; + status = "disabled"; + reg = <0x6 0x00800000 0x1000>; + pinctrl-0 = <&emmc_pins>; + pinctrl-names = "default"; + clocks = <&clks CLK_ID_AUX1>; + clock-names = "core"; + assigned-clocks = <&clks CLK_ID_AUX1>; + assigned-clock-rates = <800000000>; + interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; + bus-width = <8>; + }; + gpio: pinctrl@6110101e0 { compatible = "microchip,sparx5-pinctrl"; reg = <0x6 0x110101e0 0x90>, <0x6 0x10508010 0x100>; @@ -161,6 +206,26 @@ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; #interrupt-cells = <2>; + cs1_pins: cs1-pins { + pins = "GPIO_16"; + function = "si"; + }; + + cs2_pins: cs2-pins { + pins = "GPIO_17"; + function = "si"; + }; + + cs3_pins: cs3-pins { + pins = "GPIO_18"; + function = "si"; + }; + + si2_pins: si2-pins { + pins = "GPIO_39", "GPIO_40", "GPIO_41"; + function = "si2"; + }; + uart_pins: uart-pins { pins = "GPIO_10", "GPIO_11"; function = "uart"; @@ -180,6 +245,15 @@ pins = "GPIO_28", "GPIO_29"; function = "twi2"; }; + + emmc_pins: emmc-pins { + pins = "GPIO_34", "GPIO_35", "GPIO_36", + "GPIO_37", "GPIO_38", "GPIO_39", + "GPIO_40", "GPIO_41", "GPIO_42", + "GPIO_43", "GPIO_44", "GPIO_45", + "GPIO_46", "GPIO_47"; + function = "emmc"; + }; }; i2c0: i2c@600101000 { @@ -209,5 +283,12 @@ clock-frequency = <100000>; clocks = <&ahb_clk>; }; + + tmon0: tmon@610508110 { + compatible = "microchip,sparx5-temp"; + reg = <0x6 0x10508110 0xc>; + #thermal-sensor-cells = <0>; + clocks = <&ahb_clk>; + }; }; }; diff --git a/arch/arm64/boot/dts/microchip/sparx5_nand.dtsi b/arch/arm64/boot/dts/microchip/sparx5_nand.dtsi new file mode 100644 index 000000000000..03f107e427d7 --- /dev/null +++ b/arch/arm64/boot/dts/microchip/sparx5_nand.dtsi @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries. + */ + +&gpio { + cs14_pins: cs14-pins { + pins = "GPIO_44"; + function = "si"; + }; +}; + +&spi0 { + pinctrl-0 = <&si2_pins>; + pinctrl-names = "default"; + spi@e { + compatible = "spi-mux"; + mux-controls = <&mux>; + #address-cells = <1>; + #size-cells = <0>; + reg = <14>; /* CS14 */ + spi-flash@6 { + compatible = "spi-nand"; + pinctrl-0 = <&cs14_pins>; + pinctrl-names = "default"; + reg = <0x6>; /* SPI2 */ + spi-max-frequency = <42000000>; + rx-sample-delay-ns = <7>; /* Tune for speed */ + }; + }; +}; diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts b/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts index 91ee5b6cfc37..6b2da7c7520c 100644 --- a/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts +++ b/arch/arm64/boot/dts/microchip/sparx5_pcb125.dts @@ -16,6 +16,59 @@ }; }; +&gpio { + emmc_pins: emmc-pins { + /* NB: No "GPIO_35", "GPIO_36", "GPIO_37" + * (N/A: CARD_nDETECT, CARD_WP, CARD_LED) + */ + pins = "GPIO_34", "GPIO_38", "GPIO_39", + "GPIO_40", "GPIO_41", "GPIO_42", + "GPIO_43", "GPIO_44", "GPIO_45", + "GPIO_46", "GPIO_47"; + drive-strength = <3>; + function = "emmc"; + }; +}; + +&sdhci0 { + status = "okay"; + bus-width = <8>; + non-removable; + pinctrl-0 = <&emmc_pins>; + max-frequency = <8000000>; + microchip,clock-delay = <10>; +}; + +&spi0 { + status = "okay"; + spi@0 { + compatible = "spi-mux"; + mux-controls = <&mux>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; /* CS0 */ + spi-flash@9 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <8000000>; + reg = <0x9>; /* SPI */ + }; + }; + spi@1 { + compatible = "spi-mux"; + mux-controls = <&mux 0>; + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; /* CS1 */ + spi-flash@9 { + compatible = "spi-nand"; + pinctrl-0 = <&cs1_pins>; + pinctrl-names = "default"; + spi-max-frequency = <8000000>; + reg = <0x9>; /* SPI */ + }; + }; +}; + &i2c1 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb134.dts b/arch/arm64/boot/dts/microchip/sparx5_pcb134.dts index feee4e99ff57..45ca1af7e850 100644 --- a/arch/arm64/boot/dts/microchip/sparx5_pcb134.dts +++ b/arch/arm64/boot/dts/microchip/sparx5_pcb134.dts @@ -5,6 +5,7 @@ /dts-v1/; #include "sparx5_pcb134_board.dtsi" +#include "sparx5_nand.dtsi" / { model = "Sparx5 PCB134 Reference Board (NAND)"; diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi index 18a535a04368..f37b478d6534 100644 --- a/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi +++ b/arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi @@ -38,6 +38,38 @@ }; }; +&spi0 { + status = "okay"; + spi@0 { + compatible = "spi-mux"; + mux-controls = <&mux>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; /* CS0 */ + spi-flash@9 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <8000000>; + reg = <0x9>; /* SPI */ + }; + }; +}; + +&spi0 { + status = "okay"; + spi@0 { + compatible = "spi-mux"; + mux-controls = <&mux>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; /* CS0 */ + spi-flash@9 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <8000000>; + reg = <0x9>; /* SPI */ + }; + }; +}; + &gpio { i2cmux_pins_i: i2cmux-pins-i { pins = "GPIO_16", "GPIO_17", "GPIO_18", "GPIO_19", diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb134_emmc.dts b/arch/arm64/boot/dts/microchip/sparx5_pcb134_emmc.dts index 10081a66961b..bbb9852c1f15 100644 --- a/arch/arm64/boot/dts/microchip/sparx5_pcb134_emmc.dts +++ b/arch/arm64/boot/dts/microchip/sparx5_pcb134_emmc.dts @@ -15,3 +15,26 @@ reg = <0x00000000 0x00000000 0x10000000>; }; }; + +&gpio { + emmc_pins: emmc-pins { + /* NB: No "GPIO_35", "GPIO_36", "GPIO_37" + * (N/A: CARD_nDETECT, CARD_WP, CARD_LED) + */ + pins = "GPIO_34", "GPIO_38", "GPIO_39", + "GPIO_40", "GPIO_41", "GPIO_42", + "GPIO_43", "GPIO_44", "GPIO_45", + "GPIO_46", "GPIO_47"; + drive-strength = <3>; + function = "emmc"; + }; +}; + +&sdhci0 { + status = "okay"; + pinctrl-0 = <&emmc_pins>; + non-removable; + max-frequency = <52000000>; + bus-width = <8>; + microchip,clock-delay = <10>; +}; diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb135.dts b/arch/arm64/boot/dts/microchip/sparx5_pcb135.dts index 20e409a9be19..647cdb38b113 100644 --- a/arch/arm64/boot/dts/microchip/sparx5_pcb135.dts +++ b/arch/arm64/boot/dts/microchip/sparx5_pcb135.dts @@ -5,6 +5,7 @@ /dts-v1/; #include "sparx5_pcb135_board.dtsi" +#include "sparx5_nand.dtsi" / { model = "Sparx5 PCB135 Reference Board (NAND)"; diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi b/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi index d71f11a10b3d..b02b8c8ce44d 100644 --- a/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi +++ b/arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi @@ -51,6 +51,38 @@ }; }; +&spi0 { + status = "okay"; + spi@0 { + compatible = "spi-mux"; + mux-controls = <&mux>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; /* CS0 */ + spi-flash@9 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <8000000>; + reg = <0x9>; /* SPI */ + }; + }; +}; + +&spi0 { + status = "okay"; + spi@0 { + compatible = "spi-mux"; + mux-controls = <&mux>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; /* CS0 */ + spi-flash@9 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <8000000>; + reg = <0x9>; /* SPI */ + }; + }; +}; + &axi { i2c0_imux: i2c0-imux@0 { compatible = "i2c-mux-pinctrl"; diff --git a/arch/arm64/boot/dts/microchip/sparx5_pcb135_emmc.dts b/arch/arm64/boot/dts/microchip/sparx5_pcb135_emmc.dts index 741f0e12260e..f82266fe2ad4 100644 --- a/arch/arm64/boot/dts/microchip/sparx5_pcb135_emmc.dts +++ b/arch/arm64/boot/dts/microchip/sparx5_pcb135_emmc.dts @@ -15,3 +15,26 @@ reg = <0x00000000 0x00000000 0x10000000>; }; }; + +&gpio { + emmc_pins: emmc-pins { + /* NB: No "GPIO_35", "GPIO_36", "GPIO_37" + * (N/A: CARD_nDETECT, CARD_WP, CARD_LED) + */ + pins = "GPIO_34", "GPIO_38", "GPIO_39", + "GPIO_40", "GPIO_41", "GPIO_42", + "GPIO_43", "GPIO_44", "GPIO_45", + "GPIO_46", "GPIO_47"; + drive-strength = <3>; + function = "emmc"; + }; +}; + +&sdhci0 { + status = "okay"; + pinctrl-0 = <&emmc_pins>; + non-removable; + max-frequency = <52000000>; + bus-width = <8>; + microchip,clock-delay = <10>; +}; diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile index 2273fc5db19c..9296d12d11e9 100644 --- a/arch/arm64/boot/dts/nvidia/Makefile +++ b/arch/arm64/boot/dts/nvidia/Makefile @@ -9,3 +9,4 @@ dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2894-0050-a08.dtb dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p2771-0000.dtb dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-p2972-0000.dtb dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-p3509-0000+p3668-0000.dtb +dtb-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra234-sim-vdk.dtb diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts index 802b8c52489a..381a84912ba8 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts @@ -222,6 +222,7 @@ compatible = "atmel,24c02"; reg = <0x57>; + label = "system"; vcc-supply = <&vdd_1v8>; address-width = <8>; pagesize = <8>; diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi index 53d92fdd7f06..fd9177447711 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi @@ -173,6 +173,7 @@ compatible = "atmel,24c02"; reg = <0x50>; + label = "module"; vcc-supply = <&vdd_1v8>; address-width = <8>; pagesize = <8>; diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 8eb61dd9921e..0c46ab7bbbf3 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -85,7 +85,7 @@ ranges = <0x02900000 0x0 0x02900000 0x200000>; status = "disabled"; - dma-controller@2930000 { + adma: dma-controller@2930000 { compatible = "nvidia,tegra186-adma"; reg = <0x02930000 0x20000>; interrupt-parent = <&agic>; @@ -140,6 +140,221 @@ clock-names = "clk"; status = "disabled"; }; + + tegra_ahub: ahub@2900800 { + compatible = "nvidia,tegra186-ahub"; + reg = <0x02900800 0x800>; + clocks = <&bpmp TEGRA186_CLK_AHUB>; + clock-names = "ahub"; + assigned-clocks = <&bpmp TEGRA186_CLK_AHUB>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x02900800 0x02900800 0x11800>; + status = "disabled"; + + tegra_admaif: admaif@290f000 { + compatible = "nvidia,tegra186-admaif"; + reg = <0x0290f000 0x1000>; + dmas = <&adma 1>, <&adma 1>, + <&adma 2>, <&adma 2>, + <&adma 3>, <&adma 3>, + <&adma 4>, <&adma 4>, + <&adma 5>, <&adma 5>, + <&adma 6>, <&adma 6>, + <&adma 7>, <&adma 7>, + <&adma 8>, <&adma 8>, + <&adma 9>, <&adma 9>, + <&adma 10>, <&adma 10>, + <&adma 11>, <&adma 11>, + <&adma 12>, <&adma 12>, + <&adma 13>, <&adma 13>, + <&adma 14>, <&adma 14>, + <&adma 15>, <&adma 15>, + <&adma 16>, <&adma 16>, + <&adma 17>, <&adma 17>, + <&adma 18>, <&adma 18>, + <&adma 19>, <&adma 19>, + <&adma 20>, <&adma 20>; + dma-names = "rx1", "tx1", + "rx2", "tx2", + "rx3", "tx3", + "rx4", "tx4", + "rx5", "tx5", + "rx6", "tx6", + "rx7", "tx7", + "rx8", "tx8", + "rx9", "tx9", + "rx10", "tx10", + "rx11", "tx11", + "rx12", "tx12", + "rx13", "tx13", + "rx14", "tx14", + "rx15", "tx15", + "rx16", "tx16", + "rx17", "tx17", + "rx18", "tx18", + "rx19", "tx19", + "rx20", "tx20"; + status = "disabled"; + }; + + tegra_i2s1: i2s@2901000 { + compatible = "nvidia,tegra186-i2s", + "nvidia,tegra210-i2s"; + reg = <0x2901000 0x100>; + clocks = <&bpmp TEGRA186_CLK_I2S1>, + <&bpmp TEGRA186_CLK_I2S1_SYNC_INPUT>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA186_CLK_I2S1>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S1"; + status = "disabled"; + }; + + tegra_i2s2: i2s@2901100 { + compatible = "nvidia,tegra186-i2s", + "nvidia,tegra210-i2s"; + reg = <0x2901100 0x100>; + clocks = <&bpmp TEGRA186_CLK_I2S2>, + <&bpmp TEGRA186_CLK_I2S2_SYNC_INPUT>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA186_CLK_I2S2>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S2"; + status = "disabled"; + }; + + tegra_i2s3: i2s@2901200 { + compatible = "nvidia,tegra186-i2s", + "nvidia,tegra210-i2s"; + reg = <0x2901200 0x100>; + clocks = <&bpmp TEGRA186_CLK_I2S3>, + <&bpmp TEGRA186_CLK_I2S3_SYNC_INPUT>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA186_CLK_I2S3>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S3"; + status = "disabled"; + }; + + tegra_i2s4: i2s@2901300 { + compatible = "nvidia,tegra186-i2s", + "nvidia,tegra210-i2s"; + reg = <0x2901300 0x100>; + clocks = <&bpmp TEGRA186_CLK_I2S4>, + <&bpmp TEGRA186_CLK_I2S4_SYNC_INPUT>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA186_CLK_I2S4>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S4"; + status = "disabled"; + }; + + tegra_i2s5: i2s@2901400 { + compatible = "nvidia,tegra186-i2s", + "nvidia,tegra210-i2s"; + reg = <0x2901400 0x100>; + clocks = <&bpmp TEGRA186_CLK_I2S5>, + <&bpmp TEGRA186_CLK_I2S5_SYNC_INPUT>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA186_CLK_I2S5>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S5"; + status = "disabled"; + }; + + tegra_i2s6: i2s@2901500 { + compatible = "nvidia,tegra186-i2s", + "nvidia,tegra210-i2s"; + reg = <0x2901500 0x100>; + clocks = <&bpmp TEGRA186_CLK_I2S6>, + <&bpmp TEGRA186_CLK_I2S6_SYNC_INPUT>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA186_CLK_I2S6>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S6"; + status = "disabled"; + }; + + tegra_dmic1: dmic@2904000 { + compatible = "nvidia,tegra210-dmic"; + reg = <0x2904000 0x100>; + clocks = <&bpmp TEGRA186_CLK_DMIC1>; + clock-names = "dmic"; + assigned-clocks = <&bpmp TEGRA186_CLK_DMIC1>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + assigned-clock-rates = <3072000>; + sound-name-prefix = "DMIC1"; + status = "disabled"; + }; + + tegra_dmic2: dmic@2904100 { + compatible = "nvidia,tegra210-dmic"; + reg = <0x2904100 0x100>; + clocks = <&bpmp TEGRA186_CLK_DMIC2>; + clock-names = "dmic"; + assigned-clocks = <&bpmp TEGRA186_CLK_DMIC2>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + assigned-clock-rates = <3072000>; + sound-name-prefix = "DMIC2"; + status = "disabled"; + }; + + tegra_dmic3: dmic@2904200 { + compatible = "nvidia,tegra210-dmic"; + reg = <0x2904200 0x100>; + clocks = <&bpmp TEGRA186_CLK_DMIC3>; + clock-names = "dmic"; + assigned-clocks = <&bpmp TEGRA186_CLK_DMIC3>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + assigned-clock-rates = <3072000>; + sound-name-prefix = "DMIC3"; + status = "disabled"; + }; + + tegra_dmic4: dmic@2904300 { + compatible = "nvidia,tegra210-dmic"; + reg = <0x2904300 0x100>; + clocks = <&bpmp TEGRA186_CLK_DMIC4>; + clock-names = "dmic"; + assigned-clocks = <&bpmp TEGRA186_CLK_DMIC4>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + assigned-clock-rates = <3072000>; + sound-name-prefix = "DMIC4"; + status = "disabled"; + }; + + tegra_dspk1: dspk@2905000 { + compatible = "nvidia,tegra186-dspk"; + reg = <0x2905000 0x100>; + clocks = <&bpmp TEGRA186_CLK_DSPK1>; + clock-names = "dspk"; + assigned-clocks = <&bpmp TEGRA186_CLK_DSPK1>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + assigned-clock-rates = <12288000>; + sound-name-prefix = "DSPK1"; + status = "disabled"; + }; + + tegra_dspk2: dspk@2905100 { + compatible = "nvidia,tegra186-dspk"; + reg = <0x2905100 0x100>; + clocks = <&bpmp TEGRA186_CLK_DSPK2>; + clock-names = "dspk"; + assigned-clocks = <&bpmp TEGRA186_CLK_DSPK2>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + assigned-clock-rates = <12288000>; + sound-name-prefix = "DSPK2"; + status = "disabled"; + }; + }; }; mc: memory-controller@2c00000 { diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi index 4c005b811233..d71b7a1140fe 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi @@ -57,6 +57,22 @@ status = "okay"; }; + i2c@3160000 { + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + + label = "module"; + vcc-supply = <&vdd_1v8ls>; + address-width = <8>; + pagesize = <8>; + size = <256>; + read-only; + }; + }; + /* SDMMC1 (SD/MMC) */ mmc@3400000 { cd-gpios = <&gpio TEGRA194_MAIN_GPIO(A, 0) GPIO_ACTIVE_LOW>; diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts index 90b6ea5467fa..54d057beec59 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts @@ -23,6 +23,20 @@ }; }; + i2c@3160000 { + eeprom@56 { + compatible = "atmel,24c02"; + reg = <0x56>; + + label = "system"; + vcc-supply = <&vdd_1v8ls>; + address-width = <8>; + pagesize = <8>; + size = <256>; + read-only; + }; + }; + ddc: i2c@31c0000 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p3509-0000+p3668-0000.dts b/arch/arm64/boot/dts/nvidia/tegra194-p3509-0000+p3668-0000.dts index c1c589805d6b..7f97b34216a0 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194-p3509-0000+p3668-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra194-p3509-0000+p3668-0000.dts @@ -27,6 +27,20 @@ status = "okay"; }; + i2c@3160000 { + eeprom@57 { + compatible = "atmel,24c02"; + reg = <0x57>; + + label = "system"; + vcc-supply = <&vdd_1v8>; + address-width = <8>; + pagesize = <8>; + size = <256>; + read-only; + }; + }; + hda@3510000 { nvidia,model = "jetson-xavier-nx-hda"; status = "okay"; diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p3668-0000.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p3668-0000.dtsi index 10cb836aea7e..a2893be80507 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194-p3668-0000.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194-p3668-0000.dtsi @@ -58,6 +58,22 @@ status = "okay"; }; + i2c@3160000 { + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + + label = "module"; + vcc-supply = <&vdd_1v8ls>; + address-width = <8>; + pagesize = <8>; + size = <256>; + read-only; + }; + }; + /* SDMMC1 (SD/MMC) */ mmc@3400000 { status = "okay"; diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi index ca5cb6aef5ee..e9c90f0f44ff 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi @@ -83,7 +83,7 @@ ranges = <0x02900000 0x02900000 0x200000>; status = "disabled"; - dma-controller@2930000 { + adma: dma-controller@2930000 { compatible = "nvidia,tegra194-adma", "nvidia,tegra186-adma"; reg = <0x02930000 0x20000>; @@ -140,6 +140,229 @@ clock-names = "clk"; status = "disabled"; }; + + tegra_ahub: ahub@2900800 { + compatible = "nvidia,tegra194-ahub", + "nvidia,tegra186-ahub"; + reg = <0x02900800 0x800>; + clocks = <&bpmp TEGRA194_CLK_AHUB>; + clock-names = "ahub"; + assigned-clocks = <&bpmp TEGRA194_CLK_AHUB>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x02900800 0x02900800 0x11800>; + status = "disabled"; + + tegra_admaif: admaif@290f000 { + compatible = "nvidia,tegra194-admaif", + "nvidia,tegra186-admaif"; + reg = <0x0290f000 0x1000>; + dmas = <&adma 1>, <&adma 1>, + <&adma 2>, <&adma 2>, + <&adma 3>, <&adma 3>, + <&adma 4>, <&adma 4>, + <&adma 5>, <&adma 5>, + <&adma 6>, <&adma 6>, + <&adma 7>, <&adma 7>, + <&adma 8>, <&adma 8>, + <&adma 9>, <&adma 9>, + <&adma 10>, <&adma 10>, + <&adma 11>, <&adma 11>, + <&adma 12>, <&adma 12>, + <&adma 13>, <&adma 13>, + <&adma 14>, <&adma 14>, + <&adma 15>, <&adma 15>, + <&adma 16>, <&adma 16>, + <&adma 17>, <&adma 17>, + <&adma 18>, <&adma 18>, + <&adma 19>, <&adma 19>, + <&adma 20>, <&adma 20>; + dma-names = "rx1", "tx1", + "rx2", "tx2", + "rx3", "tx3", + "rx4", "tx4", + "rx5", "tx5", + "rx6", "tx6", + "rx7", "tx7", + "rx8", "tx8", + "rx9", "tx9", + "rx10", "tx10", + "rx11", "tx11", + "rx12", "tx12", + "rx13", "tx13", + "rx14", "tx14", + "rx15", "tx15", + "rx16", "tx16", + "rx17", "tx17", + "rx18", "tx18", + "rx19", "tx19", + "rx20", "tx20"; + status = "disabled"; + }; + + tegra_i2s1: i2s@2901000 { + compatible = "nvidia,tegra194-i2s", + "nvidia,tegra210-i2s"; + reg = <0x2901000 0x100>; + clocks = <&bpmp TEGRA194_CLK_I2S1>, + <&bpmp TEGRA194_CLK_I2S1_SYNC_INPUT>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA194_CLK_I2S1>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S1"; + status = "disabled"; + }; + + tegra_i2s2: i2s@2901100 { + compatible = "nvidia,tegra194-i2s", + "nvidia,tegra210-i2s"; + reg = <0x2901100 0x100>; + clocks = <&bpmp TEGRA194_CLK_I2S2>, + <&bpmp TEGRA194_CLK_I2S2_SYNC_INPUT>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA194_CLK_I2S2>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S2"; + status = "disabled"; + }; + + tegra_i2s3: i2s@2901200 { + compatible = "nvidia,tegra194-i2s", + "nvidia,tegra210-i2s"; + reg = <0x2901200 0x100>; + clocks = <&bpmp TEGRA194_CLK_I2S3>, + <&bpmp TEGRA194_CLK_I2S3_SYNC_INPUT>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA194_CLK_I2S3>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S3"; + status = "disabled"; + }; + + tegra_i2s4: i2s@2901300 { + compatible = "nvidia,tegra194-i2s", + "nvidia,tegra210-i2s"; + reg = <0x2901300 0x100>; + clocks = <&bpmp TEGRA194_CLK_I2S4>, + <&bpmp TEGRA194_CLK_I2S4_SYNC_INPUT>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA194_CLK_I2S4>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S4"; + status = "disabled"; + }; + + tegra_i2s5: i2s@2901400 { + compatible = "nvidia,tegra194-i2s", + "nvidia,tegra210-i2s"; + reg = <0x2901400 0x100>; + clocks = <&bpmp TEGRA194_CLK_I2S5>, + <&bpmp TEGRA194_CLK_I2S5_SYNC_INPUT>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA194_CLK_I2S5>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S5"; + status = "disabled"; + }; + + tegra_i2s6: i2s@2901500 { + compatible = "nvidia,tegra194-i2s", + "nvidia,tegra210-i2s"; + reg = <0x2901500 0x100>; + clocks = <&bpmp TEGRA194_CLK_I2S6>, + <&bpmp TEGRA194_CLK_I2S6_SYNC_INPUT>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&bpmp TEGRA194_CLK_I2S6>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S6"; + status = "disabled"; + }; + + tegra_dmic1: dmic@2904000 { + compatible = "nvidia,tegra194-dmic", + "nvidia,tegra210-dmic"; + reg = <0x2904000 0x100>; + clocks = <&bpmp TEGRA194_CLK_DMIC1>; + clock-names = "dmic"; + assigned-clocks = <&bpmp TEGRA194_CLK_DMIC1>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + assigned-clock-rates = <3072000>; + sound-name-prefix = "DMIC1"; + status = "disabled"; + }; + + tegra_dmic2: dmic@2904100 { + compatible = "nvidia,tegra194-dmic", + "nvidia,tegra210-dmic"; + reg = <0x2904100 0x100>; + clocks = <&bpmp TEGRA194_CLK_DMIC2>; + clock-names = "dmic"; + assigned-clocks = <&bpmp TEGRA194_CLK_DMIC2>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + assigned-clock-rates = <3072000>; + sound-name-prefix = "DMIC2"; + status = "disabled"; + }; + + tegra_dmic3: dmic@2904200 { + compatible = "nvidia,tegra194-dmic", + "nvidia,tegra210-dmic"; + reg = <0x2904200 0x100>; + clocks = <&bpmp TEGRA194_CLK_DMIC3>; + clock-names = "dmic"; + assigned-clocks = <&bpmp TEGRA194_CLK_DMIC3>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + assigned-clock-rates = <3072000>; + sound-name-prefix = "DMIC3"; + status = "disabled"; + }; + + tegra_dmic4: dmic@2904300 { + compatible = "nvidia,tegra194-dmic", + "nvidia,tegra210-dmic"; + reg = <0x2904300 0x100>; + clocks = <&bpmp TEGRA194_CLK_DMIC4>; + clock-names = "dmic"; + assigned-clocks = <&bpmp TEGRA194_CLK_DMIC4>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + assigned-clock-rates = <3072000>; + sound-name-prefix = "DMIC4"; + status = "disabled"; + }; + + tegra_dspk1: dspk@2905000 { + compatible = "nvidia,tegra194-dspk", + "nvidia,tegra186-dspk"; + reg = <0x2905000 0x100>; + clocks = <&bpmp TEGRA194_CLK_DSPK1>; + clock-names = "dspk"; + assigned-clocks = <&bpmp TEGRA194_CLK_DSPK1>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + assigned-clock-rates = <12288000>; + sound-name-prefix = "DSPK1"; + status = "disabled"; + }; + + tegra_dspk2: dspk@2905100 { + compatible = "nvidia,tegra194-dspk", + "nvidia,tegra186-dspk"; + reg = <0x2905100 0x100>; + clocks = <&bpmp TEGRA194_CLK_DSPK2>; + clock-names = "dspk"; + assigned-clocks = <&bpmp TEGRA194_CLK_DSPK2>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + assigned-clock-rates = <12288000>; + sound-name-prefix = "DSPK2"; + status = "disabled"; + }; + }; }; pinmux: pinmux@2430000 { @@ -329,6 +552,9 @@ clock-names = "div-clk"; resets = <&bpmp TEGRA194_RESET_I2C4>; reset-names = "i2c"; + pinctrl-0 = <&state_dpaux1_i2c>; + pinctrl-1 = <&state_dpaux1_off>; + pinctrl-names = "default", "idle"; status = "disabled"; }; @@ -343,10 +569,14 @@ clock-names = "div-clk"; resets = <&bpmp TEGRA194_RESET_I2C6>; reset-names = "i2c"; + pinctrl-0 = <&state_dpaux0_i2c>; + pinctrl-1 = <&state_dpaux0_off>; + pinctrl-names = "default", "idle"; status = "disabled"; }; - gen7_i2c: i2c@31c0000 { + /* shares pads with dpaux2 */ + dp_aux_ch2_i2c: i2c@31c0000 { compatible = "nvidia,tegra194-i2c"; reg = <0x031c0000 0x10000>; interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; @@ -356,10 +586,14 @@ clock-names = "div-clk"; resets = <&bpmp TEGRA194_RESET_I2C7>; reset-names = "i2c"; + pinctrl-0 = <&state_dpaux2_i2c>; + pinctrl-1 = <&state_dpaux2_off>; + pinctrl-names = "default", "idle"; status = "disabled"; }; - gen9_i2c: i2c@31e0000 { + /* shares pads with dpaux3 */ + dp_aux_ch3_i2c: i2c@31e0000 { compatible = "nvidia,tegra194-i2c"; reg = <0x031e0000 0x10000>; interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; @@ -369,6 +603,9 @@ clock-names = "div-clk"; resets = <&bpmp TEGRA194_RESET_I2C9>; reset-names = "i2c"; + pinctrl-0 = <&state_dpaux3_i2c>; + pinctrl-1 = <&state_dpaux3_off>; + pinctrl-names = "default", "idle"; status = "disabled"; }; @@ -1401,8 +1638,8 @@ gpu@17000000 { compatible = "nvidia,gv11b"; - reg = <0x17000000 0x10000000>, - <0x18000000 0x10000000>; + reg = <0x17000000 0x1000000>, + <0x18000000 0x1000000>; interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "stall", "nonstall"; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi index 6a4b50aaa25d..6077d572d828 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi @@ -273,6 +273,7 @@ compatible = "atmel,24c02"; reg = <0x50>; + label = "module"; vcc-supply = <&vdd_1v8>; address-width = <8>; pagesize = <8>; @@ -337,7 +338,7 @@ vdd_gpu: regulator@100 { compatible = "pwm-regulator"; - pwms = <&pwm 1 4880>; + pwms = <&pwm 1 8000>; regulator-name = "VDD_GPU"; regulator-min-microvolt = <710000>; regulator-max-microvolt = <1320000>; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts index 56adf287a82c..4c9c2a054642 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts @@ -86,6 +86,7 @@ compatible = "atmel,24c02"; reg = <0x57>; + label = "system"; vcc-supply = <&vdd_1v8>; address-width = <8>; pagesize = <8>; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts b/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts index 2282ea1c6279..859241db4b4d 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts @@ -144,6 +144,7 @@ compatible = "atmel,24c02"; reg = <0x50>; + label = "module"; vcc-supply = <&vdd_1v8>; address-width = <8>; pagesize = <8>; @@ -155,6 +156,7 @@ compatible = "atmel,24c02"; reg = <0x57>; + label = "system"; vcc-supply = <&vdd_1v8>; address-width = <8>; pagesize = <8>; @@ -541,6 +543,8 @@ mode = "peripheral"; usb-role-switch; + vbus-supply = <&vdd_5v0_usb>; + connector { compatible = "gpio-usb-b-connector", "usb-b-connector"; @@ -574,6 +578,7 @@ bus-width = <4>; cd-gpios = <&gpio TEGRA_GPIO(Z, 1) GPIO_ACTIVE_LOW>; + disable-wp; vqmmc-supply = <&vddio_sdmmc>; vmmc-supply = <&vdd_3v3_sd>; @@ -621,6 +626,18 @@ pinctrl-1 = <&dvfs_pwm_inactive_state>; }; + aconnect@702c0000 { + status = "okay"; + + dma@702e2000 { + status = "okay"; + }; + + interrupt-controller@702f9000 { + status = "okay"; + }; + }; + clk32k_in: clock@0 { compatible = "fixed-clock"; clock-frequency = <32768>; @@ -818,7 +835,7 @@ vdd_gpu: regulator@6 { compatible = "pwm-regulator"; - pwms = <&pwm 1 4880>; + pwms = <&pwm 1 8000>; regulator-name = "VDD_GPU"; regulator-min-microvolt = <710000>; @@ -843,4 +860,14 @@ vin-supply = <&avdd_1v05_pll>; }; + + vdd_5v0_usb: regulator@8 { + compatible = "regulator-fixed"; + + regulator-name = "VDD_5V_USB"; + regulator-min-microvolt = <50000000>; + regulator-max-microvolt = <50000000>; + + vin-supply = <&vdd_5v0_sys>; + }; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index 8cca2166a446..d47c88950d38 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -194,6 +194,7 @@ iommus = <&mc TEGRA_SWGROUP_DC>; + nvidia,outputs = <&dsia &dsib &sor0 &sor1>; nvidia,head = <0>; }; @@ -208,10 +209,11 @@ iommus = <&mc TEGRA_SWGROUP_DCB>; + nvidia,outputs = <&dsia &dsib &sor0 &sor1>; nvidia,head = <1>; }; - dsi@54300000 { + dsia: dsi@54300000 { compatible = "nvidia,tegra210-dsi"; reg = <0x0 0x54300000 0x0 0x00040000>; clocks = <&tegra_car TEGRA210_CLK_DSIA>, @@ -248,7 +250,7 @@ status = "disabled"; }; - dsi@54400000 { + dsib: dsi@54400000 { compatible = "nvidia,tegra210-dsi"; reg = <0x0 0x54400000 0x0 0x00040000>; clocks = <&tegra_car TEGRA210_CLK_DSIB>, @@ -284,7 +286,7 @@ status = "disabled"; }; - sor@54540000 { + sor0: sor@54540000 { compatible = "nvidia,tegra210-sor"; reg = <0x0 0x54540000 0x0 0x00040000>; interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; @@ -304,7 +306,7 @@ status = "disabled"; }; - sor@54580000 { + sor1: sor@54580000 { compatible = "nvidia,tegra210-sor1"; reg = <0x0 0x54580000 0x0 0x00040000>; interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; @@ -1385,6 +1387,146 @@ clock-names = "clk"; status = "disabled"; }; + + tegra_ahub: ahub@702d0800 { + compatible = "nvidia,tegra210-ahub"; + reg = <0x702d0800 0x800>; + clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>; + clock-names = "ahub"; + assigned-clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x702d0000 0x702d0000 0x0000e400>; + status = "disabled"; + + tegra_admaif: admaif@702d0000 { + compatible = "nvidia,tegra210-admaif"; + reg = <0x702d0000 0x800>; + dmas = <&adma 1>, <&adma 1>, + <&adma 2>, <&adma 2>, + <&adma 3>, <&adma 3>, + <&adma 4>, <&adma 4>, + <&adma 5>, <&adma 5>, + <&adma 6>, <&adma 6>, + <&adma 7>, <&adma 7>, + <&adma 8>, <&adma 8>, + <&adma 9>, <&adma 9>, + <&adma 10>, <&adma 10>; + dma-names = "rx1", "tx1", + "rx2", "tx2", + "rx3", "tx3", + "rx4", "tx4", + "rx5", "tx5", + "rx6", "tx6", + "rx7", "tx7", + "rx8", "tx8", + "rx9", "tx9", + "rx10", "tx10"; + status = "disabled"; + }; + + tegra_i2s1: i2s@702d1000 { + compatible = "nvidia,tegra210-i2s"; + reg = <0x702d1000 0x100>; + clocks = <&tegra_car TEGRA210_CLK_I2S0>, + <&tegra_car TEGRA210_CLK_I2S0_SYNC>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&tegra_car TEGRA210_CLK_I2S0>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S1"; + status = "disabled"; + }; + + tegra_i2s2: i2s@702d1100 { + compatible = "nvidia,tegra210-i2s"; + reg = <0x702d1100 0x100>; + clocks = <&tegra_car TEGRA210_CLK_I2S1>, + <&tegra_car TEGRA210_CLK_I2S1_SYNC>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&tegra_car TEGRA210_CLK_I2S1>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S2"; + status = "disabled"; + }; + + tegra_i2s3: i2s@702d1200 { + compatible = "nvidia,tegra210-i2s"; + reg = <0x702d1200 0x100>; + clocks = <&tegra_car TEGRA210_CLK_I2S2>, + <&tegra_car TEGRA210_CLK_I2S2_SYNC>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&tegra_car TEGRA210_CLK_I2S2>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S3"; + status = "disabled"; + }; + + tegra_i2s4: i2s@702d1300 { + compatible = "nvidia,tegra210-i2s"; + reg = <0x702d1300 0x100>; + clocks = <&tegra_car TEGRA210_CLK_I2S3>, + <&tegra_car TEGRA210_CLK_I2S3_SYNC>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&tegra_car TEGRA210_CLK_I2S3>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S4"; + status = "disabled"; + }; + + tegra_i2s5: i2s@702d1400 { + compatible = "nvidia,tegra210-i2s"; + reg = <0x702d1400 0x100>; + clocks = <&tegra_car TEGRA210_CLK_I2S4>, + <&tegra_car TEGRA210_CLK_I2S4_SYNC>; + clock-names = "i2s", "sync_input"; + assigned-clocks = <&tegra_car TEGRA210_CLK_I2S4>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + assigned-clock-rates = <1536000>; + sound-name-prefix = "I2S5"; + status = "disabled"; + }; + + tegra_dmic1: dmic@702d4000 { + compatible = "nvidia,tegra210-dmic"; + reg = <0x702d4000 0x100>; + clocks = <&tegra_car TEGRA210_CLK_DMIC1>; + clock-names = "dmic"; + assigned-clocks = <&tegra_car TEGRA210_CLK_DMIC1>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + assigned-clock-rates = <3072000>; + sound-name-prefix = "DMIC1"; + status = "disabled"; + }; + + tegra_dmic2: dmic@702d4100 { + compatible = "nvidia,tegra210-dmic"; + reg = <0x702d4100 0x100>; + clocks = <&tegra_car TEGRA210_CLK_DMIC2>; + clock-names = "dmic"; + assigned-clocks = <&tegra_car TEGRA210_CLK_DMIC2>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + assigned-clock-rates = <3072000>; + sound-name-prefix = "DMIC2"; + status = "disabled"; + }; + + tegra_dmic3: dmic@702d4200 { + compatible = "nvidia,tegra210-dmic"; + reg = <0x702d4200 0x100>; + clocks = <&tegra_car TEGRA210_CLK_DMIC3>; + clock-names = "dmic"; + assigned-clocks = <&tegra_car TEGRA210_CLK_DMIC3>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + assigned-clock-rates = <3072000>; + sound-name-prefix = "DMIC3"; + status = "disabled"; + }; + }; }; spi@70410000 { diff --git a/arch/arm64/boot/dts/nvidia/tegra234-sim-vdk.dts b/arch/arm64/boot/dts/nvidia/tegra234-sim-vdk.dts new file mode 100644 index 000000000000..f6e6a24829af --- /dev/null +++ b/arch/arm64/boot/dts/nvidia/tegra234-sim-vdk.dts @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "tegra234.dtsi" + +/ { + model = "NVIDIA Tegra234 VDK"; + compatible = "nvidia,tegra234-vdk", "nvidia,tegra234"; + + aliases { + sdhci3 = "/cbb@0/sdhci@3460000"; + serial0 = &uarta; + }; + + chosen { + bootargs = "console=ttyS0,115200n8 earlycon=uart8250,mmio32,0x03100000"; + stdout-path = "serial0:115200n8"; + }; + + cbb@0 { + serial@3100000 { + status = "okay"; + }; + + sdhci@3460000 { + status = "okay"; + bus-width = <8>; + non-removable; + only-1-8-v; + }; + + rtc@c2a0000 { + status = "okay"; + }; + + pmc@c360000 { + nvidia,invert-interrupt; + }; + }; +}; diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi new file mode 100644 index 000000000000..f0efb3a62804 --- /dev/null +++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <dt-bindings/clock/tegra234-clock.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/mailbox/tegra186-hsp.h> +#include <dt-bindings/reset/tegra234-reset.h> + +/ { + compatible = "nvidia,tegra234"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + bus@0 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + + ranges = <0x0 0x0 0x0 0x40000000>; + + misc@100000 { + compatible = "nvidia,tegra234-misc"; + reg = <0x00100000 0xf000>, + <0x0010f000 0x1000>; + status = "okay"; + }; + + uarta: serial@3100000 { + compatible = "nvidia,tegra234-uart", "nvidia,tegra20-uart"; + reg = <0x03100000 0x10000>; + interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&bpmp TEGRA234_CLK_UARTA>; + clock-names = "serial"; + resets = <&bpmp TEGRA234_RESET_UARTA>; + reset-names = "serial"; + status = "disabled"; + }; + + mmc@3460000 { + compatible = "nvidia,tegra234-sdhci", "nvidia,tegra186-sdhci"; + reg = <0x03460000 0x20000>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&bpmp TEGRA234_CLK_SDMMC4>; + clock-names = "sdhci"; + resets = <&bpmp TEGRA234_RESET_SDMMC4>; + reset-names = "sdhci"; + dma-coherent; + status = "disabled"; + }; + + fuse@3810000 { + compatible = "nvidia,tegra234-efuse"; + reg = <0x03810000 0x10000>; + clocks = <&bpmp TEGRA234_CLK_FUSE>; + clock-names = "fuse"; + }; + + hsp_top0: hsp@3c00000 { + compatible = "nvidia,tegra234-hsp", "nvidia,tegra194-hsp"; + reg = <0x03c00000 0xa0000>; + interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "doorbell", "shared0", "shared1", "shared2", + "shared3", "shared4", "shared5", "shared6", + "shared7"; + #mbox-cells = <2>; + }; + + hsp_aon: hsp@c150000 { + compatible = "nvidia,tegra234-hsp", "nvidia,tegra194-hsp"; + reg = <0x0c150000 0x90000>; + interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; + /* + * Shared interrupt 0 is routed only to AON/SPE, so + * we only have 4 shared interrupts for the CCPLEX. + */ + interrupt-names = "shared1", "shared2", "shared3", "shared4"; + #mbox-cells = <2>; + }; + + rtc@c2a0000 { + compatible = "nvidia,tegra234-rtc", "nvidia,tegra20-rtc"; + reg = <0x0c2a0000 0x10000>; + interrupt-parent = <&pmc>; + interrupts = <73 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + pmc: pmc@c360000 { + compatible = "nvidia,tegra234-pmc"; + reg = <0x0c360000 0x10000>, + <0x0c370000 0x10000>, + <0x0c380000 0x10000>, + <0x0c390000 0x10000>, + <0x0c3a0000 0x10000>; + reg-names = "pmc", "wake", "aotag", "scratch", "misc"; + + #interrupt-cells = <2>; + interrupt-controller; + }; + + gic: interrupt-controller@f400000 { + compatible = "arm,gic-v3"; + reg = <0x0f400000 0x010000>, /* GICD */ + <0x0f440000 0x200000>; /* GICR */ + interrupt-parent = <&gic>; + interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + + #redistributor-regions = <1>; + #interrupt-cells = <3>; + interrupt-controller; + }; + }; + + sysram@40000000 { + compatible = "nvidia,tegra234-sysram", "mmio-sram"; + reg = <0x0 0x40000000 0x0 0x50000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x40000000 0x50000>; + + cpu_bpmp_tx: shmem@4e000 { + reg = <0x4e000 0x1000>; + label = "cpu-bpmp-tx"; + pool; + }; + + cpu_bpmp_rx: shmem@4f000 { + reg = <0x4f000 0x1000>; + label = "cpu-bpmp-rx"; + pool; + }; + }; + + bpmp: bpmp { + compatible = "nvidia,tegra234-bpmp", "nvidia,tegra186-bpmp"; + mboxes = <&hsp_top0 TEGRA_HSP_MBOX_TYPE_DB + TEGRA_HSP_DB_MASTER_BPMP>; + shmem = <&cpu_bpmp_tx &cpu_bpmp_rx>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + + bpmp_i2c: i2c { + compatible = "nvidia,tegra186-bpmp-i2c"; + nvidia,bpmp-bus-id = <5>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + reg = <0x000>; + + enable-method = "psci"; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + status = "okay"; + method = "smc"; + }; + + 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)>; + interrupt-parent = <&gic>; + always-on; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index d8f1466e6758..fb4631f898fd 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -1,11 +1,11 @@ # SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc.dtb dtb-$(CONFIG_ARCH_QCOM) += apq8096-db820c.dtb -dtb-$(CONFIG_ARCH_QCOM) += apq8096-ifc6640.dtb +dtb-$(CONFIG_ARCH_QCOM) += apq8096-ifc6640.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq6018-cp01-c1.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq8074-hk01.dtb -dtb-$(CONFIG_ARCH_QCOM) += msm8916-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-longcheer-l8150.dtb +dtb-$(CONFIG_ARCH_QCOM) += msm8916-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-a3u-eur.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-a5u-eur.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8992-bullhead-rev-101.dtb @@ -18,7 +18,16 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8998-asus-novago-tp370ql.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8998-hp-envy-x2.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8998-lenovo-miix-630.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8998-mtp.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-1000.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-4000.dtb +dtb-$(CONFIG_ARCH_QCOM) += qrb5165-rb5.dtb dtb-$(CONFIG_ARCH_QCOM) += sc7180-idp.dtb +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-r1.dtb +dtb-$(CONFIG_ARCH_QCOM) += sc7180-trogdor-r1-lte.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm630-sony-xperia-ganges-kirin.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm630-sony-xperia-nile-discovery.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm630-sony-xperia-nile-pioneer.dtb @@ -30,8 +39,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r2.dtb dtb-$(CONFIG_ARCH_QCOM) += sdm845-cheza-r3.dtb 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-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8250-mtp.dtb -dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-1000.dtb -dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-4000.dtb diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 194343510dcb..3c7f97539390 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -3,38 +3,13 @@ * Copyright (c) 2015, The Linux Foundation. All rights reserved. */ -#include "msm8916.dtsi" -#include "pm8916.dtsi" +#include "msm8916-pm8916.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> #include <dt-bindings/pinctrl/qcom,pmic-mpp.h> #include <dt-bindings/sound/apq8016-lpass.h> -/* - * GPIO name legend: proper name = the GPIO line is used as GPIO - * NC = not connected (pin out but not routed from the chip to - * anything the board) - * "[PER]" = pin is muxed for [peripheral] (not GPIO) - * LSEC = Low Speed External Connector - * HSEC = High Speed External Connector - * - * Line names are taken from the schematic "DragonBoard410c" - * dated monday, august 31, 2015. Page 5 in particular. - * - * For the lines routed to the external connectors the - * lines are named after the 96Boards CE Specification 1.0, - * Appendix "Expansion Connector Signal Description". - * - * When the 96Board naming of a line and the schematic name of - * the same line are in conflict, the 96Board specification - * takes precedence, which means that the external UART on the - * LSEC is named UART0 while the schematic and SoC names this - * UART3. This is only for the informational lines i.e. "[FOO]", - * the GPIO named lines "GPIO-A" thru "GPIO-L" are the only - * ones actually used for GPIO. - */ - / { aliases { serial0 = &blsp1_uart2; @@ -76,7 +51,7 @@ }; reserved-memory { - ramoops@bff00000{ + ramoops@bff00000 { compatible = "ramoops"; reg = <0x0 0xbff00000 0x0 0x100000>; @@ -86,509 +61,190 @@ }; }; - soc { - pinctrl@1000000 { - gpio-line-names = - "[UART0_TX]", /* GPIO_0, LSEC pin 5 */ - "[UART0_RX]", /* GPIO_1, LSEC pin 7 */ - "[UART0_CTS_N]", /* GPIO_2, LSEC pin 3 */ - "[UART0_RTS_N]", /* GPIO_3, LSEC pin 9 */ - "[UART1_TX]", /* GPIO_4, LSEC pin 11 */ - "[UART1_RX]", /* GPIO_5, LSEC pin 13 */ - "[I2C0_SDA]", /* GPIO_8, LSEC pin 17 */ - "[I2C0_SCL]", /* GPIO_7, LSEC pin 15 */ - "[SPI1_DOUT]", /* SPI1_MOSI, HSEC pin 1 */ - "[SPI1_DIN]", /* SPI1_MISO, HSEC pin 11 */ - "[SPI1_CS]", /* SPI1_CS_N, HSEC pin 7 */ - "[SPI1_SCLK]", /* SPI1_CLK, HSEC pin 9 */ - "GPIO-B", /* LS_EXP_GPIO_B, LSEC pin 24 */ - "GPIO-C", /* LS_EXP_GPIO_C, LSEC pin 25 */ - "[I2C3_SDA]", /* HSEC pin 38 */ - "[I2C3_SCL]", /* HSEC pin 36 */ - "[SPI0_MOSI]", /* LSEC pin 14 */ - "[SPI0_MISO]", /* LSEC pin 10 */ - "[SPI0_CS_N]", /* LSEC pin 12 */ - "[SPI0_CLK]", /* LSEC pin 8 */ - "HDMI_HPD_N", /* GPIO 20 */ - "USR_LED_1_CTRL", - "[I2C1_SDA]", /* GPIO_22, LSEC pin 21 */ - "[I2C1_SCL]", /* GPIO_23, LSEC pin 19 */ - "GPIO-G", /* LS_EXP_GPIO_G, LSEC pin 29 */ - "GPIO-H", /* LS_EXP_GPIO_H, LSEC pin 30 */ - "[CSI0_MCLK]", /* HSEC pin 15 */ - "[CSI1_MCLK]", /* HSEC pin 17 */ - "GPIO-K", /* LS_EXP_GPIO_K, LSEC pin 33 */ - "[I2C2_SDA]", /* HSEC pin 34 */ - "[I2C2_SCL]", /* HSEC pin 32 */ - "DSI2HDMI_INT_N", - "DSI_SW_SEL_APQ", - "GPIO-L", /* LS_EXP_GPIO_L, LSEC pin 34 */ - "GPIO-J", /* LS_EXP_GPIO_J, LSEC pin 32 */ - "GPIO-I", /* LS_EXP_GPIO_I, LSEC pin 31 */ - "GPIO-A", /* LS_EXP_GPIO_A, LSEC pin 23 */ - "FORCED_USB_BOOT", - "SD_CARD_DET_N", - "[WCSS_BT_SSBI]", - "[WCSS_WLAN_DATA_2]", /* GPIO 40 */ - "[WCSS_WLAN_DATA_1]", - "[WCSS_WLAN_DATA_0]", - "[WCSS_WLAN_SET]", - "[WCSS_WLAN_CLK]", - "[WCSS_FM_SSBI]", - "[WCSS_FM_SDI]", - "[WCSS_BT_DAT_CTL]", - "[WCSS_BT_DAT_STB]", - "NC", - "NC", /* GPIO 50 */ - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", /* GPIO 60 */ - "NC", - "NC", - "[CDC_PDM0_CLK]", - "[CDC_PDM0_SYNC]", - "[CDC_PDM0_TX0]", - "[CDC_PDM0_RX0]", - "[CDC_PDM0_RX1]", - "[CDC_PDM0_RX2]", - "GPIO-D", /* LS_EXP_GPIO_D, LSEC pin 26 */ - "NC", /* GPIO 70 */ - "NC", - "NC", - "NC", - "NC", /* GPIO 74 */ - "NC", - "NC", - "NC", - "NC", - "NC", - "BOOT_CONFIG_0", /* GPIO 80 */ - "BOOT_CONFIG_1", - "BOOT_CONFIG_2", - "BOOT_CONFIG_3", - "NC", - "NC", - "BOOT_CONFIG_5", - "NC", - "NC", - "NC", - "NC", /* GPIO 90 */ - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", /* GPIO 100 */ - "NC", - "NC", - "NC", - "SSBI_GPS", - "NC", - "NC", - "KEY_VOLP_N", - "NC", - "NC", - "[LS_EXP_MI2S_WS]", /* GPIO 110 */ - "NC", - "NC", - "[LS_EXP_MI2S_SCK]", - "[LS_EXP_MI2S_DATA0]", - "GPIO-E", /* LS_EXP_GPIO_E, LSEC pin 27 */ - "NC", - "[DSI2HDMI_MI2S_WS]", - "[DSI2HDMI_MI2S_SCK]", - "[DSI2HDMI_MI2S_DATA0]", - "USR_LED_2_CTRL", /* GPIO 120 */ - "SB_HS_ID"; - }; - - dma@7884000 { - status = "okay"; - }; - - serial@78af000 { - label = "LS-UART0"; - status = "okay"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&blsp1_uart1_default>; - pinctrl-1 = <&blsp1_uart1_sleep>; - }; - - serial@78b0000 { - label = "LS-UART1"; - status = "okay"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&blsp1_uart2_default>; - pinctrl-1 = <&blsp1_uart2_sleep>; - }; - - i2c@78b6000 { - /* On Low speed expansion */ - label = "LS-I2C0"; - status = "okay"; - }; - - i2c@78b8000 { - /* On High speed expansion */ - label = "HS-I2C2"; - status = "okay"; - - adv_bridge: bridge@39 { - status = "okay"; - - compatible = "adi,adv7533"; - reg = <0x39>; - - interrupt-parent = <&msmgpio>; - interrupts = <31 2>; - - adi,dsi-lanes = <4>; - clocks = <&rpmcc RPM_SMD_BB_CLK2>; - clock-names = "cec"; - - pd-gpios = <&msmgpio 32 0>; - - avdd-supply = <&pm8916_l6>; - v1p2-supply = <&pm8916_l6>; - v3p3-supply = <&pm8916_l17>; - - pinctrl-names = "default","sleep"; - pinctrl-0 = <&adv7533_int_active &adv7533_switch_active>; - pinctrl-1 = <&adv7533_int_suspend &adv7533_switch_suspend>; - #sound-dai-cells = <1>; + usb2513 { + compatible = "smsc,usb3503"; + reset-gpios = <&pm8916_gpios 3 GPIO_ACTIVE_LOW>; + initial-mode = <1>; + }; - ports { - #address-cells = <1>; - #size-cells = <0>; + usb_id: usb-id { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_id_default>; + }; - port@0 { - reg = <0>; - adv7533_in: endpoint { - remote-endpoint = <&dsi0_out>; - }; - }; + hdmi-out { + compatible = "hdmi-connector"; + type = "a"; - port@1 { - reg = <1>; - adv7533_out: endpoint { - remote-endpoint = <&hdmi_con>; - }; - }; - }; + port { + hdmi_con: endpoint { + remote-endpoint = <&adv7533_out>; }; }; + }; - i2c@78ba000 { - /* On Low speed expansion */ - label = "LS-I2C1"; - status = "okay"; - }; + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + autorepeat; - spi@78b7000 { - /* On High speed expansion */ - label = "HS-SPI1"; - status = "okay"; - }; + pinctrl-names = "default"; + pinctrl-0 = <&msm_key_volp_n_default>; - spi@78b9000 { - /* On Low speed expansion */ - label = "LS-SPI0"; - status = "okay"; + button@0 { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>; }; + }; - leds { - pinctrl-names = "default"; - pinctrl-0 = <&msmgpio_leds>, - <&pm8916_gpios_leds>, - <&pm8916_mpps_leds>; - - compatible = "gpio-leds"; - - led@1 { - label = "apq8016-sbc:green:user1"; - gpios = <&msmgpio 21 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; - default-state = "off"; - }; - - led@2 { - label = "apq8016-sbc:green:user2"; - gpios = <&msmgpio 120 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "mmc0"; - default-state = "off"; - }; - - led@3 { - label = "apq8016-sbc:green:user3"; - gpios = <&pm8916_gpios 1 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "mmc1"; - default-state = "off"; - }; - - led@4 { - label = "apq8016-sbc:green:user4"; - gpios = <&pm8916_gpios 2 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "none"; - panic-indicator; - default-state = "off"; - }; + leds { + pinctrl-names = "default"; + pinctrl-0 = <&msmgpio_leds>, + <&pm8916_gpios_leds>, + <&pm8916_mpps_leds>; - led@5 { - label = "apq8016-sbc:yellow:wlan"; - gpios = <&pm8916_mpps 2 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "phy0tx"; - default-state = "off"; - }; + compatible = "gpio-leds"; - led@6 { - label = "apq8016-sbc:blue:bt"; - gpios = <&pm8916_mpps 3 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "bluetooth-power"; - default-state = "off"; - }; + led@1 { + label = "apq8016-sbc:green:user1"; + gpios = <&msmgpio 21 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + default-state = "off"; }; - sdhci@7824000 { - vmmc-supply = <&pm8916_l8>; - vqmmc-supply = <&pm8916_l5>; - - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; - pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; - status = "okay"; + led@2 { + label = "apq8016-sbc:green:user2"; + gpios = <&msmgpio 120 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc0"; + default-state = "off"; }; - sdhci@7864000 { - vmmc-supply = <&pm8916_l11>; - vqmmc-supply = <&pm8916_l12>; - - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; - pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; + led@3 { + label = "apq8016-sbc:green:user3"; + gpios = <&pm8916_gpios 1 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc1"; + default-state = "off"; + }; - cd-gpios = <&msmgpio 38 0x1>; - status = "okay"; + led@4 { + label = "apq8016-sbc:green:user4"; + gpios = <&pm8916_gpios 2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "none"; + panic-indicator; + default-state = "off"; }; - usb@78d9000 { - extcon = <&usb_id>, <&usb_id>; - status = "okay"; - adp-disable; - hnp-disable; - srp-disable; - dr_mode = "otg"; - pinctrl-names = "default", "device"; - pinctrl-0 = <&usb_sw_sel_pm &usb_hub_reset_pm>; - pinctrl-1 = <&usb_sw_sel_pm_device &usb_hub_reset_pm_device>; - ulpi { - phy { - v1p8-supply = <&pm8916_l7>; - v3p3-supply = <&pm8916_l13>; - extcon = <&usb_id>; - }; - }; + led@5 { + label = "apq8016-sbc:yellow:wlan"; + gpios = <&pm8916_mpps 2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "phy0tx"; + default-state = "off"; }; - lpass@7708000 { - status = "okay"; + led@6 { + label = "apq8016-sbc:blue:bt"; + gpios = <&pm8916_mpps 3 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "bluetooth-power"; + default-state = "off"; }; + }; +}; - mdss@1a00000 { - status = "okay"; +&blsp_dma { + status = "okay"; +}; - mdp@1a01000 { - status = "okay"; - }; +&blsp_i2c2 { + /* On Low speed expansion */ + status = "okay"; + label = "LS-I2C0"; +}; - dsi@1a98000 { - status = "okay"; +&blsp_i2c4 { + /* On High speed expansion */ + status = "okay"; + label = "HS-I2C2"; - vdda-supply = <&pm8916_l2>; - vddio-supply = <&pm8916_l6>; + adv_bridge: bridge@39 { + status = "okay"; - ports { - port@1 { - endpoint { - remote-endpoint = <&adv7533_in>; - data-lanes = <0 1 2 3>; - }; - }; - }; - }; + compatible = "adi,adv7533"; + reg = <0x39>; - dsi-phy@1a98300 { - status = "okay"; + interrupt-parent = <&msmgpio>; + interrupts = <31 IRQ_TYPE_EDGE_FALLING>; - vddio-supply = <&pm8916_l6>; - }; - }; + adi,dsi-lanes = <4>; + clocks = <&rpmcc RPM_SMD_BB_CLK2>; + clock-names = "cec"; - lpass_codec: codec{ - status = "okay"; - }; + pd-gpios = <&msmgpio 32 GPIO_ACTIVE_HIGH>; - /* - Internal Codec - playback - Primary MI2S - capture - Ter MI2S - - External Primary: - playback - secondary MI2S - capture - Quat MI2S - - External Secondary: - playback - Quat MI2S - capture - Quat MI2S - - */ - - sound: sound { - compatible = "qcom,apq8016-sbc-sndcard"; - reg = <0x07702000 0x4>, <0x07702004 0x4>; - reg-names = "mic-iomux", "spkr-iomux"; - - status = "okay"; - pinctrl-0 = <&cdc_pdm_lines_act &ext_sec_tlmm_lines_act &ext_mclk_tlmm_lines_act>; - pinctrl-1 = <&cdc_pdm_lines_sus &ext_sec_tlmm_lines_sus &ext_mclk_tlmm_lines_sus>; - pinctrl-names = "default", "sleep"; - qcom,model = "DB410c"; - qcom,audio-routing = - "AMIC2", "MIC BIAS Internal2", - "AMIC3", "MIC BIAS External1"; - - external-dai-link@0 { - link-name = "ADV7533"; - cpu { - sound-dai = <&lpass MI2S_QUATERNARY>; - }; - codec { - sound-dai = <&adv_bridge 0>; - }; - }; + avdd-supply = <&pm8916_l6>; + v1p2-supply = <&pm8916_l6>; + v3p3-supply = <&pm8916_l17>; - internal-codec-playback-dai-link@0 { - link-name = "WCD"; - cpu { - sound-dai = <&lpass MI2S_PRIMARY>; - }; - codec { - sound-dai = <&lpass_codec 0>, <&wcd_codec 0>; - }; - }; + pinctrl-names = "default","sleep"; + pinctrl-0 = <&adv7533_int_active &adv7533_switch_active>; + pinctrl-1 = <&adv7533_int_suspend &adv7533_switch_suspend>; + #sound-dai-cells = <1>; - internal-codec-capture-dai-link@0 { - link-name = "WCD-Capture"; - cpu { - sound-dai = <&lpass MI2S_TERTIARY>; - }; - codec { - sound-dai = <&lpass_codec 1>, <&wcd_codec 1>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7533_in: endpoint { + remote-endpoint = <&dsi0_out>; }; }; - }; - spmi@200f000 { - pm8916@0 { - gpios@c000 { - gpio-line-names = - "USR_LED_3_CTRL", - "USR_LED_4_CTRL", - "USB_HUB_RESET_N_PM", - "USB_SW_SEL_PM"; - }; - mpps@a000 { - gpio-line-names = - "VDD_PX_BIAS", - "WLAN_LED_CTRL", - "BT_LED_CTRL", - "GPIO-F"; /* LS_EXP_GPIO_F, LSEC pin 28 */ + port@1 { + reg = <1>; + adv7533_out: endpoint { + remote-endpoint = <&hdmi_con>; }; }; }; - - wcnss@a21b000 { - status = "okay"; - }; - - tpiu@820000 { status = "okay"; }; - funnel@821000 { status = "okay"; }; - replicator@824000 { status = "okay"; }; - etf@825000 { status = "okay"; }; - etr@826000 { status = "okay"; }; - funnel@841000 { status = "okay"; }; - debug@850000 { status = "okay"; }; - debug@852000 { status = "okay"; }; - debug@854000 { status = "okay"; }; - debug@856000 { status = "okay"; }; - etm@85c000 { status = "okay"; }; - etm@85d000 { status = "okay"; }; - etm@85e000 { status = "okay"; }; - etm@85f000 { status = "okay"; }; - cti@810000 { status = "okay"; }; - cti@811000 { status = "okay"; }; - cti@858000 { status = "okay"; }; - cti@859000 { status = "okay"; }; - cti@85a000 { status = "okay"; }; - cti@85b000 { status = "okay"; }; - }; - - usb2513 { - compatible = "smsc,usb3503"; - reset-gpios = <&pm8916_gpios 3 GPIO_ACTIVE_LOW>; - initial-mode = <1>; - }; - - usb_id: usb-id { - compatible = "linux,extcon-usb-gpio"; - id-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&usb_id_default>; }; +}; - hdmi-out { - compatible = "hdmi-connector"; - type = "a"; +&blsp_i2c6 { + /* On Low speed expansion */ + status = "okay"; + label = "LS-I2C1"; +}; - port { - hdmi_con: endpoint { - remote-endpoint = <&adv7533_out>; - }; - }; - }; +&blsp_spi3 { + /* On High speed expansion */ + status = "okay"; + label = "HS-SPI1"; +}; - gpio-keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - autorepeat; +&blsp_spi5 { + /* On Low speed expansion */ + status = "okay"; + label = "LS-SPI0"; +}; - pinctrl-names = "default"; - pinctrl-0 = <&msm_key_volp_n_default>; +&blsp1_uart1 { + status = "okay"; + label = "LS-UART0"; +}; - button@0 { - label = "Volume Up"; - linux,code = <KEY_VOLUMEUP>; - gpios = <&msmgpio 107 GPIO_ACTIVE_LOW>; - }; - }; +&blsp1_uart2 { + status = "okay"; + label = "LS-UART1"; }; &camss { - status = "ok"; + status = "okay"; ports { - #address-cells = <1>; - #size-cells = <0>; port@0 { reg = <0>; csiphy0_ep: endpoint { @@ -602,7 +258,7 @@ }; &cci { - status = "ok"; + status = "okay"; }; &cci_i2c0 { @@ -636,28 +292,126 @@ }; }; -&spmi_bus { - pm8916_0: pm8916@0 { - pon@800 { - resin { - compatible = "qcom,pm8941-resin"; - interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; - debounce = <15625>; - bias-pull-up; - linux,code = <KEY_VOLUMEDOWN>; - }; +&dsi0_out { + data-lanes = <0 1 2 3>; + remote-endpoint = <&adv7533_in>; +}; + +&lpass { + status = "okay"; +}; + +&pm8916_resin { + status = "okay"; + linux,code = <KEY_VOLUMEDOWN>; +}; + +&pronto { + status = "okay"; +}; + +&sdhc_1 { + status = "okay"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; +}; + +&sdhc_2 { + status = "okay"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; + + cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>; +}; + +&sound { + status = "okay"; + + pinctrl-0 = <&cdc_pdm_lines_act &ext_sec_tlmm_lines_act &ext_mclk_tlmm_lines_act>; + pinctrl-1 = <&cdc_pdm_lines_sus &ext_sec_tlmm_lines_sus &ext_mclk_tlmm_lines_sus>; + pinctrl-names = "default", "sleep"; + qcom,model = "DB410c"; + qcom,audio-routing = + "AMIC2", "MIC BIAS Internal2", + "AMIC3", "MIC BIAS External1"; + + external-dai-link@0 { + link-name = "ADV7533"; + cpu { + sound-dai = <&lpass MI2S_QUATERNARY>; + }; + codec { + sound-dai = <&adv_bridge 0>; + }; + }; + + internal-codec-playback-dai-link@0 { + link-name = "WCD"; + cpu { + sound-dai = <&lpass MI2S_PRIMARY>; + }; + codec { + sound-dai = <&lpass_codec 0>, <&wcd_codec 0>; + }; + }; + + internal-codec-capture-dai-link@0 { + link-name = "WCD-Capture"; + cpu { + sound-dai = <&lpass MI2S_TERTIARY>; + }; + codec { + sound-dai = <&lpass_codec 1>, <&wcd_codec 1>; }; }; }; -&wcd_codec { +&usb { status = "okay"; + extcon = <&usb_id>, <&usb_id>; + + pinctrl-names = "default", "device"; + pinctrl-0 = <&usb_sw_sel_pm &usb_hub_reset_pm>; + pinctrl-1 = <&usb_sw_sel_pm_device &usb_hub_reset_pm_device>; +}; + +&usb_hs_phy { + extcon = <&usb_id>; +}; + +&wcd_codec { clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>; clock-names = "mclk"; qcom,mbhc-vthreshold-low = <75 150 237 450 500>; qcom,mbhc-vthreshold-high = <75 150 237 450 500>; }; +/* Enable CoreSight */ +&cti0 { status = "okay"; }; +&cti1 { status = "okay"; }; +&cti12 { status = "okay"; }; +&cti13 { status = "okay"; }; +&cti14 { status = "okay"; }; +&cti15 { status = "okay"; }; +&debug0 { status = "okay"; }; +&debug1 { status = "okay"; }; +&debug2 { status = "okay"; }; +&debug3 { status = "okay"; }; +&etf { status = "okay"; }; +&etm0 { status = "okay"; }; +&etm1 { status = "okay"; }; +&etm2 { status = "okay"; }; +&etm3 { status = "okay"; }; +&etr { status = "okay"; }; +&funnel0 { status = "okay"; }; +&funnel1 { status = "okay"; }; +&replicator { status = "okay"; }; +&tpiu { status = "okay"; }; + &smd_rpm_regulators { vdd_l1_l2_l3-supply = <&pm8916_s3>; vdd_l4_l5_l6-supply = <&pm8916_s4>; @@ -795,7 +549,155 @@ drive-strength = <16>; }; +/* + * GPIO name legend: proper name = the GPIO line is used as GPIO + * NC = not connected (pin out but not routed from the chip to + * anything the board) + * "[PER]" = pin is muxed for [peripheral] (not GPIO) + * LSEC = Low Speed External Connector + * HSEC = High Speed External Connector + * + * Line names are taken from the schematic "DragonBoard410c" + * dated monday, august 31, 2015. Page 5 in particular. + * + * For the lines routed to the external connectors the + * lines are named after the 96Boards CE Specification 1.0, + * Appendix "Expansion Connector Signal Description". + * + * When the 96Board naming of a line and the schematic name of + * the same line are in conflict, the 96Board specification + * takes precedence, which means that the external UART on the + * LSEC is named UART0 while the schematic and SoC names this + * UART3. This is only for the informational lines i.e. "[FOO]", + * the GPIO named lines "GPIO-A" thru "GPIO-L" are the only + * ones actually used for GPIO. + */ + &msmgpio { + gpio-line-names = + "[UART0_TX]", /* GPIO_0, LSEC pin 5 */ + "[UART0_RX]", /* GPIO_1, LSEC pin 7 */ + "[UART0_CTS_N]", /* GPIO_2, LSEC pin 3 */ + "[UART0_RTS_N]", /* GPIO_3, LSEC pin 9 */ + "[UART1_TX]", /* GPIO_4, LSEC pin 11 */ + "[UART1_RX]", /* GPIO_5, LSEC pin 13 */ + "[I2C0_SDA]", /* GPIO_8, LSEC pin 17 */ + "[I2C0_SCL]", /* GPIO_7, LSEC pin 15 */ + "[SPI1_DOUT]", /* SPI1_MOSI, HSEC pin 1 */ + "[SPI1_DIN]", /* SPI1_MISO, HSEC pin 11 */ + "[SPI1_CS]", /* SPI1_CS_N, HSEC pin 7 */ + "[SPI1_SCLK]", /* SPI1_CLK, HSEC pin 9 */ + "GPIO-B", /* LS_EXP_GPIO_B, LSEC pin 24 */ + "GPIO-C", /* LS_EXP_GPIO_C, LSEC pin 25 */ + "[I2C3_SDA]", /* HSEC pin 38 */ + "[I2C3_SCL]", /* HSEC pin 36 */ + "[SPI0_MOSI]", /* LSEC pin 14 */ + "[SPI0_MISO]", /* LSEC pin 10 */ + "[SPI0_CS_N]", /* LSEC pin 12 */ + "[SPI0_CLK]", /* LSEC pin 8 */ + "HDMI_HPD_N", /* GPIO 20 */ + "USR_LED_1_CTRL", + "[I2C1_SDA]", /* GPIO_22, LSEC pin 21 */ + "[I2C1_SCL]", /* GPIO_23, LSEC pin 19 */ + "GPIO-G", /* LS_EXP_GPIO_G, LSEC pin 29 */ + "GPIO-H", /* LS_EXP_GPIO_H, LSEC pin 30 */ + "[CSI0_MCLK]", /* HSEC pin 15 */ + "[CSI1_MCLK]", /* HSEC pin 17 */ + "GPIO-K", /* LS_EXP_GPIO_K, LSEC pin 33 */ + "[I2C2_SDA]", /* HSEC pin 34 */ + "[I2C2_SCL]", /* HSEC pin 32 */ + "DSI2HDMI_INT_N", + "DSI_SW_SEL_APQ", + "GPIO-L", /* LS_EXP_GPIO_L, LSEC pin 34 */ + "GPIO-J", /* LS_EXP_GPIO_J, LSEC pin 32 */ + "GPIO-I", /* LS_EXP_GPIO_I, LSEC pin 31 */ + "GPIO-A", /* LS_EXP_GPIO_A, LSEC pin 23 */ + "FORCED_USB_BOOT", + "SD_CARD_DET_N", + "[WCSS_BT_SSBI]", + "[WCSS_WLAN_DATA_2]", /* GPIO 40 */ + "[WCSS_WLAN_DATA_1]", + "[WCSS_WLAN_DATA_0]", + "[WCSS_WLAN_SET]", + "[WCSS_WLAN_CLK]", + "[WCSS_FM_SSBI]", + "[WCSS_FM_SDI]", + "[WCSS_BT_DAT_CTL]", + "[WCSS_BT_DAT_STB]", + "NC", + "NC", /* GPIO 50 */ + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", /* GPIO 60 */ + "NC", + "NC", + "[CDC_PDM0_CLK]", + "[CDC_PDM0_SYNC]", + "[CDC_PDM0_TX0]", + "[CDC_PDM0_RX0]", + "[CDC_PDM0_RX1]", + "[CDC_PDM0_RX2]", + "GPIO-D", /* LS_EXP_GPIO_D, LSEC pin 26 */ + "NC", /* GPIO 70 */ + "NC", + "NC", + "NC", + "NC", /* GPIO 74 */ + "NC", + "NC", + "NC", + "NC", + "NC", + "BOOT_CONFIG_0", /* GPIO 80 */ + "BOOT_CONFIG_1", + "BOOT_CONFIG_2", + "BOOT_CONFIG_3", + "NC", + "NC", + "BOOT_CONFIG_5", + "NC", + "NC", + "NC", + "NC", /* GPIO 90 */ + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", /* GPIO 100 */ + "NC", + "NC", + "NC", + "SSBI_GPS", + "NC", + "NC", + "KEY_VOLP_N", + "NC", + "NC", + "[LS_EXP_MI2S_WS]", /* GPIO 110 */ + "NC", + "NC", + "[LS_EXP_MI2S_SCK]", + "[LS_EXP_MI2S_DATA0]", + "GPIO-E", /* LS_EXP_GPIO_E, LSEC pin 27 */ + "NC", + "[DSI2HDMI_MI2S_WS]", + "[DSI2HDMI_MI2S_SCK]", + "[DSI2HDMI_MI2S_DATA0]", + "USR_LED_2_CTRL", /* GPIO 120 */ + "SB_HS_ID"; + msmgpio_leds: msmgpio-leds { pins = "gpio21", "gpio120"; function = "gpio"; @@ -855,6 +757,12 @@ }; &pm8916_gpios { + gpio-line-names = + "USR_LED_3_CTRL", + "USR_LED_4_CTRL", + "USB_HUB_RESET_N_PM", + "USB_SW_SEL_PM"; + usb_hub_reset_pm: usb-hub-reset-pm { pins = "gpio3"; function = PMIC_GPIO_FUNC_NORMAL; @@ -897,6 +805,12 @@ }; &pm8916_mpps { + gpio-line-names = + "VDD_PX_BIAS", + "WLAN_LED_CTRL", + "BT_LED_CTRL", + "GPIO-F"; /* LS_EXP_GPIO_F, LSEC pin 28 */ + pinctrl-names = "default"; pinctrl-0 = <&ls_exp_gpio_f>; diff --git a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts index b31117a93995..e8eaa958c199 100644 --- a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts +++ b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts @@ -26,18 +26,18 @@ &blsp1_uart3 { pinctrl-0 = <&serial_3_pins>; pinctrl-names = "default"; - status = "ok"; + status = "okay"; }; &i2c_1 { pinctrl-0 = <&i2c_1_pins>; pinctrl-names = "default"; - status = "ok"; + status = "okay"; }; &spi_0 { cs-select = <0>; - status = "ok"; + status = "okay"; m25p80@0 { #address-cells = <1>; diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi index 1aa8d8579463..a94dac76bf3f 100644 --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi @@ -8,6 +8,7 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/clock/qcom,gcc-ipq6018.h> #include <dt-bindings/reset/qcom,gcc-ipq6018.h> +#include <dt-bindings/clock/qcom,apss-ipq.h> / { #address-cells = <2>; @@ -38,6 +39,10 @@ reg = <0x0>; enable-method = "psci"; next-level-cache = <&L2_0>; + clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>; + clock-names = "cpu"; + operating-points-v2 = <&cpu_opp_table>; + cpu-supply = <&ipq6018_s2>; }; CPU1: cpu@1 { @@ -46,6 +51,10 @@ enable-method = "psci"; reg = <0x1>; next-level-cache = <&L2_0>; + clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>; + clock-names = "cpu"; + operating-points-v2 = <&cpu_opp_table>; + cpu-supply = <&ipq6018_s2>; }; CPU2: cpu@2 { @@ -54,6 +63,10 @@ enable-method = "psci"; reg = <0x2>; next-level-cache = <&L2_0>; + clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>; + clock-names = "cpu"; + operating-points-v2 = <&cpu_opp_table>; + cpu-supply = <&ipq6018_s2>; }; CPU3: cpu@3 { @@ -62,6 +75,10 @@ enable-method = "psci"; reg = <0x3>; next-level-cache = <&L2_0>; + clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>; + clock-names = "cpu"; + operating-points-v2 = <&cpu_opp_table>; + cpu-supply = <&ipq6018_s2>; }; L2_0: l2-cache { @@ -70,6 +87,42 @@ }; }; + cpu_opp_table: cpu_opp_table { + compatible = "operating-points-v2"; + opp-shared; + + opp-864000000 { + opp-hz = /bits/ 64 <864000000>; + opp-microvolt = <725000>; + clock-latency-ns = <200000>; + }; + opp-1056000000 { + opp-hz = /bits/ 64 <1056000000>; + opp-microvolt = <787500>; + clock-latency-ns = <200000>; + }; + opp-1320000000 { + opp-hz = /bits/ 64 <1320000000>; + opp-microvolt = <862500>; + clock-latency-ns = <200000>; + }; + opp-1440000000 { + opp-hz = /bits/ 64 <1440000000>; + opp-microvolt = <925000>; + clock-latency-ns = <200000>; + }; + opp-1608000000 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <987500>; + clock-latency-ns = <200000>; + }; + opp-1800000000 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1062500>; + clock-latency-ns = <200000>; + }; + }; + firmware { scm { compatible = "qcom,scm"; @@ -98,6 +151,11 @@ #size-cells = <2>; ranges; + rpm_msg_ram: memory@0x60000 { + reg = <0x0 0x60000 0x0 0x6000>; + no-map; + }; + tz: tz@48500000 { reg = <0x0 0x48500000 0x0 0x00200000>; no-map; @@ -294,12 +352,22 @@ }; apcs_glb: mailbox@b111000 { - compatible = "qcom,ipq8074-apcs-apps-global"; - reg = <0x0b111000 0xc>; - + compatible = "qcom,ipq6018-apcs-apps-global"; + reg = <0x0b111000 0x1000>; + #clock-cells = <1>; + clocks = <&a53pll>, <&xo>; + clock-names = "pll", "xo"; #mbox-cells = <1>; }; + a53pll: clock@b116000 { + compatible = "qcom,ipq6018-a53pll"; + reg = <0x0b116000 0x40>; + #clock-cells = <0>; + clocks = <&xo>; + clock-names = "xo"; + }; + timer { compatible = "arm,armv8-timer"; interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, @@ -440,4 +508,26 @@ #interrupt-cells = <2>; }; }; + + rpm-glink { + compatible = "qcom,glink-rpm"; + interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>; + qcom,rpm-msg-ram = <&rpm_msg_ram>; + mboxes = <&apcs_glb 0>; + + rpm_requests: glink-channel { + compatible = "qcom,rpm-ipq6018"; + qcom,glink-channels = "rpm_requests"; + + regulators { + compatible = "qcom,rpm-mp5496-regulators"; + + ipq6018_s2: s2 { + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1062500>; + regulator-always-on; + }; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts index f4a76162ab5f..e8c37a1693d3 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts +++ b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts @@ -27,11 +27,11 @@ }; &blsp1_i2c2 { - status = "ok"; + status = "okay"; }; &blsp1_spi1 { - status = "ok"; + status = "okay"; m25p80@0 { #address-cells = <1>; @@ -43,37 +43,37 @@ }; &blsp1_uart3 { - status = "ok"; + status = "okay"; }; &blsp1_uart5 { - status = "ok"; + status = "okay"; }; &pcie0 { - status = "ok"; + status = "okay"; perst-gpio = <&tlmm 61 0x1>; }; &pcie1 { - status = "ok"; + status = "okay"; perst-gpio = <&tlmm 58 0x1>; }; &pcie_phy0 { - status = "ok"; + status = "okay"; }; &pcie_phy1 { - status = "ok"; + status = "okay"; }; &qpic_bam { - status = "ok"; + status = "okay"; }; &qpic_nand { - status = "ok"; + status = "okay"; nand@0 { reg = <0>; @@ -84,29 +84,29 @@ }; &sdhc_1 { - status = "ok"; + status = "okay"; }; &qusb_phy_0 { - status = "ok"; + status = "okay"; }; &qusb_phy_1 { - status = "ok"; + status = "okay"; }; &ssphy_0 { - status = "ok"; + status = "okay"; }; &ssphy_1 { - status = "ok"; + status = "okay"; }; &usb_0 { - status = "ok"; + status = "okay"; }; &usb_1 { - status = "ok"; + status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index 96a5ec89b5f0..829e37ac82f6 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -67,7 +67,7 @@ }; pmu { - compatible = "arm,armv8-pmuv3"; + compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; }; @@ -498,6 +498,14 @@ <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; }; + watchdog: watchdog@b017000 { + compatible = "qcom,kpss-wdt"; + reg = <0xb017000 0x1000>; + interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>; + clocks = <&sleep_clk>; + timeout-sec = <30>; + }; + timer@b120000 { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts index 9f2c8e94fd26..b9d3c5d98dd0 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts @@ -2,8 +2,7 @@ /dts-v1/; -#include "msm8916.dtsi" -#include "pm8916.dtsi" +#include "msm8916-pm8916.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> @@ -29,61 +28,6 @@ }; }; - soc { - sdhci@7824000 { - status = "okay"; - - vmmc-supply = <&pm8916_l8>; - vqmmc-supply = <&pm8916_l5>; - - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; - pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; - }; - - sdhci@7864000 { - status = "okay"; - - vmmc-supply = <&pm8916_l11>; - vqmmc-supply = <&pm8916_l12>; - - 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>; - - non-removable; - }; - - serial@78b0000 { - status = "okay"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&blsp1_uart2_default>; - pinctrl-1 = <&blsp1_uart2_sleep>; - }; - - usb@78d9000 { - status = "okay"; - dr_mode = "peripheral"; - extcon = <&usb_vbus>; - - hnp-disable; - srp-disable; - adp-disable; - - ulpi { - phy { - extcon = <&usb_vbus>; - v1p8-supply = <&pm8916_l7>; - v3p3-supply = <&pm8916_l13>; - }; - }; - }; - - wcnss@a21b000 { - status = "okay"; - }; - }; - // FIXME: Use extcon device provided by charger driver when available usb_vbus: usb-vbus { compatible = "linux,extcon-usb-gpio"; @@ -108,17 +52,45 @@ }; }; -&spmi_bus { - pm8916@0 { - pon@800 { - volume-down { - compatible = "qcom,pm8941-resin"; - interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; - bias-pull-up; - linux,code = <KEY_VOLUMEDOWN>; - }; - }; - }; +&blsp1_uart2 { + status = "okay"; +}; + +&pm8916_resin { + status = "okay"; + linux,code = <KEY_VOLUMEDOWN>; +}; + +&pronto { + status = "okay"; +}; + +&sdhc_1 { + status = "okay"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; +}; + +&sdhc_2 { + status = "okay"; + + 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>; + + non-removable; +}; + +&usb { + status = "okay"; + dr_mode = "peripheral"; + extcon = <&usb_vbus>; +}; + +&usb_hs_phy { + extcon = <&usb_vbus>; }; &smd_rpm_regulators { diff --git a/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi index 0c6e81fb8c01..1bd05046cdeb 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi @@ -3,8 +3,7 @@ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. */ -#include "msm8916.dtsi" -#include "pm8916.dtsi" +#include "msm8916-pm8916.dtsi" / { aliases { @@ -15,13 +14,8 @@ chosen { stdout-path = "serial0"; }; +}; - soc { - serial@78b0000 { - status = "okay"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&blsp1_uart2_default>; - pinctrl-1 = <&blsp1_uart2_sleep>; - }; - }; +&blsp1_uart2 { + status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi new file mode 100644 index 000000000000..cd626e7db599 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8916-pm8916.dtsi @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include "msm8916.dtsi" +#include "pm8916.dtsi" + +&camss { + vdda-supply = <&pm8916_l2>; +}; + +&dsi0 { + vdda-supply = <&pm8916_l2>; + vddio-supply = <&pm8916_l6>; +}; + +&dsi_phy0 { + vddio-supply = <&pm8916_l6>; +}; + +&mpss { + cx-supply = <&pm8916_s1>; + mx-supply = <&pm8916_l3>; + pll-supply = <&pm8916_l7>; +}; + +&pronto { + vddmx-supply = <&pm8916_l3>; + vddpx-supply = <&pm8916_l7>; + + iris { + vddxo-supply = <&pm8916_l7>; + vddrfa-supply = <&pm8916_s3>; + vddpa-supply = <&pm8916_l9>; + vdddig-supply = <&pm8916_l5>; + }; +}; + +&sdhc_1 { + vmmc-supply = <&pm8916_l8>; + vqmmc-supply = <&pm8916_l5>; +}; + +&sdhc_2 { + vmmc-supply = <&pm8916_l11>; + vqmmc-supply = <&pm8916_l12>; +}; + +&usb_hs_phy { + v1p8-supply = <&pm8916_l7>; + v3p3-supply = <&pm8916_l13>; +}; + +&rpm_requests { + smd_rpm_regulators: pm8916-regulators { + compatible = "qcom,rpm-pm8916-regulators"; + + pm8916_s1: s1 {}; + pm8916_s3: s3 {}; + pm8916_s4: s4 {}; + + pm8916_l1: l1 {}; + pm8916_l2: l2 {}; + pm8916_l3: l3 {}; + pm8916_l4: l4 {}; + pm8916_l5: l5 {}; + pm8916_l6: l6 {}; + pm8916_l7: l7 {}; + pm8916_l8: l8 {}; + pm8916_l9: l9 {}; + pm8916_l10: l10 {}; + pm8916_l11: l11 {}; + pm8916_l12: l12 {}; + pm8916_l13: l13 {}; + pm8916_l14: l14 {}; + pm8916_l15: l15 {}; + pm8916_l16: l16 {}; + pm8916_l17: l17 {}; + pm8916_l18: l18 {}; + }; +}; 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 a0c00d9d62c4..b18d21e42f59 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only -#include "msm8916.dtsi" -#include "pm8916.dtsi" +#include "msm8916-pm8916.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> #include <dt-bindings/interrupt-controller/irq.h> @@ -23,78 +22,6 @@ }; }; - soc { - sdhci@7824000 { - status = "okay"; - - vmmc-supply = <&pm8916_l8>; - vqmmc-supply = <&pm8916_l5>; - - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; - pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; - }; - - sdhci@7864000 { - status = "okay"; - - vmmc-supply = <&pm8916_l11>; - vqmmc-supply = <&pm8916_l12>; - - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; - pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; - - cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>; - }; - - serial@78b0000 { - status = "okay"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&blsp1_uart2_default>; - pinctrl-1 = <&blsp1_uart2_sleep>; - }; - - usb@78d9000 { - status = "okay"; - extcon = <&muic>, <&muic>; - - hnp-disable; - srp-disable; - adp-disable; - - ulpi { - phy { - extcon = <&muic>; - v1p8-supply = <&pm8916_l7>; - v3p3-supply = <&pm8916_l13>; - }; - }; - }; - - mdss@1a00000 { - dsi@1a98000 { - #address-cells = <1>; - #size-cells = <0>; - - vdda-supply = <&pm8916_l2>; - vddio-supply = <&pm8916_l6>; - - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&mdss_default>; - pinctrl-1 = <&mdss_sleep>; - }; - - dsi-phy@1a98300 { - vddio-supply = <&pm8916_l6>; - }; - }; - - wcnss@a21b000 { - status = "okay"; - }; - }; - gpio-keys { compatible = "gpio-keys"; @@ -154,7 +81,7 @@ #address-cells = <1>; #size-cells = <0>; - muic: sm5502@25 { + muic: extcon@25 { compatible = "siliconmitus,sm5502-muic"; reg = <0x25>; @@ -186,17 +113,50 @@ }; }; -&spmi_bus { - pm8916@0 { - pon@800 { - volume-down { - compatible = "qcom,pm8941-resin"; - interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; - bias-pull-up; - linux,code = <KEY_VOLUMEDOWN>; - }; - }; - }; +&blsp1_uart2 { + status = "okay"; +}; + +&dsi0 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&mdss_default>; + pinctrl-1 = <&mdss_sleep>; +}; + +&pm8916_resin { + status = "okay"; + linux,code = <KEY_VOLUMEDOWN>; +}; + +&pronto { + status = "okay"; +}; + +&sdhc_1 { + status = "okay"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; +}; + +&sdhc_2 { + status = "okay"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; + + cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>; +}; + +&usb { + status = "okay"; + extcon = <&muic>, <&muic>; +}; + +&usb_hs_phy { + extcon = <&muic>; }; &smd_rpm_regulators { 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 410c7d199f96..086f07ead5cb 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts @@ -44,15 +44,11 @@ }; }; }; +}; - ports { - port@1 { - dsi0_out: endpoint { - remote-endpoint = <&panel_in>; - data-lanes = <0 1>; - }; - }; - }; +&dsi0_out { + data-lanes = <0 1>; + remote-endpoint = <&panel_in>; }; &msmgpio { diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 67cae5f9e47e..aaa21899f1a6 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -4,11 +4,11 @@ */ #include <dt-bindings/arm/coresight-cti-dt.h> +#include <dt-bindings/clock/qcom,gcc-msm8916.h> +#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/clock/qcom,gcc-msm8916.h> #include <dt-bindings/reset/qcom,gcc-msm8916.h> -#include <dt-bindings/clock/qcom,rpmcc.h> #include <dt-bindings/thermal/thermal.h> / { @@ -94,6 +94,20 @@ }; }; + clocks { + xo_board: xo-board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -151,8 +165,8 @@ }; L2_0: l2-cache { - compatible = "cache"; - cache-level = <2>; + compatible = "cache"; + cache-level = <2>; }; idle-states { @@ -189,6 +203,42 @@ }; }; + cpu_opp_table: cpu-opp-table { + compatible = "operating-points-v2"; + opp-shared; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + }; + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + }; + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + }; + opp-998400000 { + opp-hz = /bits/ 64 <998400000>; + }; + }; + + firmware { + scm: scm { + compatible = "qcom,scm-msm8916", "qcom,scm"; + clocks = <&gcc GCC_CRYPTO_CLK>, + <&gcc GCC_CRYPTO_AXI_CLK>, + <&gcc GCC_CRYPTO_AHB_CLK>; + clock-names = "core", "bus", "iface"; + #reset-cells = <1>; + + qcom,dload-mode = <&tcsr 0x6100>; + }; + }; + + pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + }; + psci { compatible = "arm,psci-1.0"; method = "smc"; @@ -223,162 +273,24 @@ }; }; - pmu { - compatible = "arm,cortex-a53-pmu"; - interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4)| IRQ_TYPE_LEVEL_HIGH)>; - }; - - thermal-zones { - cpu0_1-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - - thermal-sensors = <&tsens 5>; - - trips { - cpu0_1_alert0: trip-point@0 { - temperature = <75000>; - hysteresis = <2000>; - type = "passive"; - }; - cpu0_1_crit: cpu_crit { - temperature = <110000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { - map0 { - trip = <&cpu0_1_alert0>; - cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; - }; - - cpu2_3-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - - thermal-sensors = <&tsens 4>; - - trips { - cpu2_3_alert0: trip-point0 { - temperature = <75000>; - hysteresis = <2000>; - type = "passive"; - }; - cpu2_3_crit: cpu_crit { - temperature = <110000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { - map0 { - trip = <&cpu2_3_alert0>; - cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; - }; - - gpu-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - - thermal-sensors = <&tsens 2>; - - trips { - gpu_alert0: trip-point0 { - temperature = <75000>; - hysteresis = <2000>; - type = "passive"; - }; - gpu_crit: gpu_crit { - temperature = <95000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - }; - - camera-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; - - thermal-sensors = <&tsens 1>; - - trips { - cam_alert0: trip-point0 { - temperature = <75000>; - hysteresis = <2000>; - type = "hot"; - }; - }; - }; + smd { + compatible = "qcom,smd"; - modem-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + rpm { + interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>; + qcom,ipc = <&apcs 8 0>; + qcom,smd-edge = <15>; - thermal-sensors = <&tsens 0>; + rpm_requests: rpm-requests { + compatible = "qcom,rpm-msm8916"; + qcom,smd-channels = "rpm_requests"; - trips { - modem_alert0: trip-point0 { - temperature = <85000>; - hysteresis = <2000>; - type = "hot"; + rpmcc: clock-controller { + compatible = "qcom,rpmcc-msm8916"; + #clock-cells = <1>; }; }; }; - - }; - - cpu_opp_table: cpu-opp-table { - compatible = "operating-points-v2"; - opp-shared; - - opp-200000000 { - opp-hz = /bits/ 64 <200000000>; - }; - opp-400000000 { - opp-hz = /bits/ 64 <400000000>; - }; - opp-800000000 { - opp-hz = /bits/ 64 <800000000>; - }; - opp-998400000 { - opp-hz = /bits/ 64 <998400000>; - }; - }; - - timer { - compatible = "arm,armv8-timer"; - interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; - }; - - clocks { - xo_board: xo-board { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <19200000>; - }; - - sleep_clk: sleep-clk { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <32768>; - }; }; smem { @@ -390,509 +302,93 @@ hwlocks = <&tcsr_mutex 3>; }; - firmware { - scm: scm { - compatible = "qcom,scm"; - clocks = <&gcc GCC_CRYPTO_CLK>, <&gcc GCC_CRYPTO_AXI_CLK>, <&gcc GCC_CRYPTO_AHB_CLK>; - clock-names = "core", "bus", "iface"; - #reset-cells = <1>; + smp2p-hexagon { + compatible = "qcom,smp2p"; + qcom,smem = <435>, <428>; - qcom,dload-mode = <&tcsr 0x6100>; - }; - }; + interrupts = <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>; - soc: soc { - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0 0 0xffffffff>; - compatible = "simple-bus"; + qcom,ipc = <&apcs 8 14>; - bimc: interconnect@400000 { - compatible = "qcom,msm8916-bimc"; - reg = <0x00400000 0x62000>; - #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_BIMC_CLK>, - <&rpmcc RPM_SMD_BIMC_A_CLK>; - }; + qcom,local-pid = <0>; + qcom,remote-pid = <1>; - restart@4ab000 { - compatible = "qcom,pshold"; - reg = <0x4ab000 0x4>; - }; + hexagon_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; - pcnoc: interconnect@500000 { - compatible = "qcom,msm8916-pcnoc"; - reg = <0x00500000 0x11000>; - #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_PCNOC_CLK>, - <&rpmcc RPM_SMD_PCNOC_A_CLK>; + #qcom,smem-state-cells = <1>; }; - snoc: interconnect@580000 { - compatible = "qcom,msm8916-snoc"; - reg = <0x00580000 0x14000>; - #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_SNOC_CLK>, - <&rpmcc RPM_SMD_SNOC_A_CLK>; - }; + hexagon_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; - msmgpio: pinctrl@1000000 { - compatible = "qcom,msm8916-pinctrl"; - reg = <0x1000000 0x300000>; - interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; - gpio-controller; - gpio-ranges = <&msmgpio 0 0 122>; - #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; + }; - gcc: clock-controller@1800000 { - compatible = "qcom,gcc-msm8916"; - #clock-cells = <1>; - #reset-cells = <1>; - #power-domain-cells = <1>; - reg = <0x1800000 0x80000>; - }; - - tcsr_mutex_regs: syscon@1905000 { - compatible = "syscon"; - reg = <0x1905000 0x20000>; - }; - - tcsr: syscon@1937000 { - compatible = "qcom,tcsr-msm8916", "syscon"; - reg = <0x1937000 0x30000>; - }; - - tcsr_mutex: hwlock { - compatible = "qcom,tcsr-mutex"; - syscon = <&tcsr_mutex_regs 0 0x1000>; - #hwlock-cells = <1>; - }; - - rpm_msg_ram: memory@60000 { - compatible = "qcom,rpm-msg-ram"; - reg = <0x60000 0x8000>; - }; - - blsp1_uart1: serial@78af000 { - compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; - reg = <0x78af000 0x200>; - interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_BLSP1_UART1_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>; - clock-names = "core", "iface"; - dmas = <&blsp_dma 1>, <&blsp_dma 0>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - - a53pll: clock@b016000 { - compatible = "qcom,msm8916-a53pll"; - reg = <0xb016000 0x40>; - #clock-cells = <0>; - }; - - apcs: mailbox@b011000 { - compatible = "qcom,msm8916-apcs-kpss-global", "syscon"; - reg = <0xb011000 0x1000>; - #mbox-cells = <1>; - clocks = <&a53pll>, <&gcc GPLL0_VOTE>; - clock-names = "pll", "aux"; - #clock-cells = <0>; - }; - - blsp1_uart2: serial@78b0000 { - compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; - reg = <0x78b0000 0x200>; - interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>; - clock-names = "core", "iface"; - dmas = <&blsp_dma 3>, <&blsp_dma 2>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - - blsp_dma: dma@7884000 { - compatible = "qcom,bam-v1.7.0"; - reg = <0x07884000 0x23000>; - interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_BLSP1_AHB_CLK>; - clock-names = "bam_clk"; - #dma-cells = <1>; - qcom,ee = <0>; - status = "disabled"; - }; - - blsp_spi1: spi@78b5000 { - compatible = "qcom,spi-qup-v2.2.1"; - reg = <0x078b5000 0x500>; - interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_BLSP1_QUP1_SPI_APPS_CLK>, - <&gcc GCC_BLSP1_AHB_CLK>; - clock-names = "core", "iface"; - dmas = <&blsp_dma 5>, <&blsp_dma 4>; - dma-names = "rx", "tx"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&spi1_default>; - pinctrl-1 = <&spi1_sleep>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - blsp_spi2: spi@78b6000 { - compatible = "qcom,spi-qup-v2.2.1"; - reg = <0x078b6000 0x500>; - interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_BLSP1_QUP2_SPI_APPS_CLK>, - <&gcc GCC_BLSP1_AHB_CLK>; - clock-names = "core", "iface"; - dmas = <&blsp_dma 7>, <&blsp_dma 6>; - dma-names = "rx", "tx"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&spi2_default>; - pinctrl-1 = <&spi2_sleep>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - blsp_spi3: spi@78b7000 { - compatible = "qcom,spi-qup-v2.2.1"; - reg = <0x078b7000 0x500>; - interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_BLSP1_QUP3_SPI_APPS_CLK>, - <&gcc GCC_BLSP1_AHB_CLK>; - clock-names = "core", "iface"; - dmas = <&blsp_dma 9>, <&blsp_dma 8>; - dma-names = "rx", "tx"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&spi3_default>; - pinctrl-1 = <&spi3_sleep>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - blsp_spi4: spi@78b8000 { - compatible = "qcom,spi-qup-v2.2.1"; - reg = <0x078b8000 0x500>; - interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_BLSP1_QUP4_SPI_APPS_CLK>, - <&gcc GCC_BLSP1_AHB_CLK>; - clock-names = "core", "iface"; - dmas = <&blsp_dma 11>, <&blsp_dma 10>; - dma-names = "rx", "tx"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&spi4_default>; - pinctrl-1 = <&spi4_sleep>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - blsp_spi5: spi@78b9000 { - compatible = "qcom,spi-qup-v2.2.1"; - reg = <0x078b9000 0x500>; - interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_BLSP1_QUP5_SPI_APPS_CLK>, - <&gcc GCC_BLSP1_AHB_CLK>; - clock-names = "core", "iface"; - dmas = <&blsp_dma 13>, <&blsp_dma 12>; - dma-names = "rx", "tx"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&spi5_default>; - pinctrl-1 = <&spi5_sleep>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; + smp2p-wcnss { + compatible = "qcom,smp2p"; + qcom,smem = <451>, <431>; - blsp_spi6: spi@78ba000 { - compatible = "qcom,spi-qup-v2.2.1"; - reg = <0x078ba000 0x500>; - interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_BLSP1_QUP6_SPI_APPS_CLK>, - <&gcc GCC_BLSP1_AHB_CLK>; - clock-names = "core", "iface"; - dmas = <&blsp_dma 15>, <&blsp_dma 14>; - dma-names = "rx", "tx"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&spi6_default>; - pinctrl-1 = <&spi6_sleep>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; + interrupts = <GIC_SPI 143 IRQ_TYPE_EDGE_RISING>; - blsp_i2c1: i2c@78b5000 { - compatible = "qcom,i2c-qup-v2.2.1"; - reg = <0x078b5000 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"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&i2c1_default>; - pinctrl-1 = <&i2c1_sleep>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - blsp_i2c2: i2c@78b6000 { - compatible = "qcom,i2c-qup-v2.2.1"; - reg = <0x078b6000 0x500>; - interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_BLSP1_AHB_CLK>, - <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>; - clock-names = "iface", "core"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&i2c2_default>; - pinctrl-1 = <&i2c2_sleep>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; + qcom,ipc = <&apcs 8 18>; - blsp_i2c4: i2c@78b8000 { - compatible = "qcom,i2c-qup-v2.2.1"; - reg = <0x078b8000 0x500>; - interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_BLSP1_AHB_CLK>, - <&gcc GCC_BLSP1_QUP4_I2C_APPS_CLK>; - clock-names = "iface", "core"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&i2c4_default>; - pinctrl-1 = <&i2c4_sleep>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; + qcom,local-pid = <0>; + qcom,remote-pid = <4>; - blsp_i2c5: i2c@78b9000 { - compatible = "qcom,i2c-qup-v2.2.1"; - reg = <0x078b9000 0x500>; - interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_BLSP1_AHB_CLK>, - <&gcc GCC_BLSP1_QUP5_I2C_APPS_CLK>; - clock-names = "iface", "core"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&i2c5_default>; - pinctrl-1 = <&i2c5_sleep>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; + wcnss_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; - blsp_i2c6: i2c@78ba000 { - compatible = "qcom,i2c-qup-v2.2.1"; - reg = <0x078ba000 0x500>; - interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_BLSP1_AHB_CLK>, - <&gcc GCC_BLSP1_QUP6_I2C_APPS_CLK>; - clock-names = "iface", "core"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&i2c6_default>; - pinctrl-1 = <&i2c6_sleep>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; + #qcom,smem-state-cells = <1>; }; - lpass: lpass@7708000 { - status = "disabled"; - compatible = "qcom,lpass-cpu-apq8016"; - clocks = <&gcc GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK>, - <&gcc GCC_ULTAUDIO_PCNOC_MPORT_CLK>, - <&gcc GCC_ULTAUDIO_PCNOC_SWAY_CLK>, - <&gcc GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK>, - <&gcc GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK>, - <&gcc GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK>, - <&gcc GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK>; - - clock-names = "ahbix-clk", - "pcnoc-mport-clk", - "pcnoc-sway-clk", - "mi2s-bit-clk0", - "mi2s-bit-clk1", - "mi2s-bit-clk2", - "mi2s-bit-clk3"; - #sound-dai-cells = <1>; - - interrupts = <0 160 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "lpass-irq-lpaif"; - reg = <0x07708000 0x10000>; - reg-names = "lpass-lpaif"; + wcnss_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; - #address-cells = <1>; - #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <2>; }; + }; - lpass_codec: codec{ - compatible = "qcom,msm8916-wcd-digital-codec"; - reg = <0x0771c000 0x400>; - clocks = <&gcc GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK>, - <&gcc GCC_CODEC_DIGCODEC_CLK>; - clock-names = "ahbix-clk", "mclk"; - #sound-dai-cells = <1>; - }; + smsm { + compatible = "qcom,smsm"; - sdhc_1: sdhci@7824000 { - compatible = "qcom,sdhci-msm-v4"; - reg = <0x07824900 0x11c>, <0x07824000 0x800>; - reg-names = "hc_mem", "core_mem"; + #address-cells = <1>; + #size-cells = <0>; - interrupts = <0 123 IRQ_TYPE_LEVEL_HIGH>, <0 138 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "hc_irq", "pwr_irq"; - clocks = <&gcc GCC_SDCC1_APPS_CLK>, - <&gcc GCC_SDCC1_AHB_CLK>, - <&xo_board>; - clock-names = "core", "iface", "xo"; - mmc-ddr-1_8v; - bus-width = <8>; - non-removable; - status = "disabled"; - }; + qcom,ipc-1 = <&apcs 8 13>; + qcom,ipc-3 = <&apcs 8 19>; - sdhc_2: sdhci@7864000 { - compatible = "qcom,sdhci-msm-v4"; - reg = <0x07864900 0x11c>, <0x07864000 0x800>; - reg-names = "hc_mem", "core_mem"; + apps_smsm: apps@0 { + reg = <0>; - interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>, <0 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"; - bus-width = <4>; - status = "disabled"; + #qcom,smem-state-cells = <1>; }; - otg: usb@78d9000 { - compatible = "qcom,ci-hdrc"; - reg = <0x78d9000 0x200>, - <0x78d9200 0x200>; - interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc GCC_USB_HS_AHB_CLK>, - <&gcc GCC_USB_HS_SYSTEM_CLK>; - clock-names = "iface", "core"; - assigned-clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>; - assigned-clock-rates = <80000000>; - resets = <&gcc GCC_USB_HS_BCR>; - reset-names = "core"; - phy_type = "ulpi"; - dr_mode = "otg"; - ahb-burst-config = <0>; - phy-names = "usb-phy"; - phys = <&usb_hs_phy>; - status = "disabled"; - #reset-cells = <1>; - - ulpi { - usb_hs_phy: phy { - compatible = "qcom,usb-hs-phy-msm8916", - "qcom,usb-hs-phy"; - #phy-cells = <0>; - clocks = <&xo_board>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>; - clock-names = "ref", "sleep"; - resets = <&gcc GCC_USB2A_PHY_BCR>, <&otg 0>; - reset-names = "phy", "por"; - qcom,init-seq = /bits/ 8 <0x0 0x44 - 0x1 0x6b 0x2 0x24 0x3 0x13>; - }; - }; - }; + hexagon_smsm: hexagon@1 { + reg = <1>; + interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>; - intc: interrupt-controller@b000000 { - compatible = "qcom,msm-qgic2"; interrupt-controller; - #interrupt-cells = <3>; - reg = <0x0b000000 0x1000>, <0x0b002000 0x1000>; + #interrupt-cells = <2>; }; - timer@b020000 { - #address-cells = <1>; - #size-cells = <1>; - ranges; - compatible = "arm,armv7-timer-mem"; - reg = <0xb020000 0x1000>; - clock-frequency = <19200000>; - - frame@b021000 { - frame-number = <0>; - interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; - reg = <0xb021000 0x1000>, - <0xb022000 0x1000>; - }; - - frame@b023000 { - frame-number = <1>; - interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; - reg = <0xb023000 0x1000>; - status = "disabled"; - }; - - frame@b024000 { - frame-number = <2>; - interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; - reg = <0xb024000 0x1000>; - status = "disabled"; - }; - - frame@b025000 { - frame-number = <3>; - interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; - reg = <0xb025000 0x1000>; - status = "disabled"; - }; - - frame@b026000 { - frame-number = <4>; - interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; - reg = <0xb026000 0x1000>; - status = "disabled"; - }; - - frame@b027000 { - frame-number = <5>; - interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; - reg = <0xb027000 0x1000>; - status = "disabled"; - }; - - frame@b028000 { - frame-number = <6>; - interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; - reg = <0xb028000 0x1000>; - status = "disabled"; - }; - }; + wcnss_smsm: wcnss@6 { + reg = <6>; + interrupts = <GIC_SPI 144 IRQ_TYPE_EDGE_RISING>; - spmi_bus: spmi@200f000 { - compatible = "qcom,spmi-pmic-arb"; - reg = <0x200f000 0x001000>, - <0x2400000 0x400000>, - <0x2c00000 0x400000>, - <0x3800000 0x200000>, - <0x200a000 0x002100>; - reg-names = "core", "chnls", "obsrvr", "intr", "cnfg"; - interrupt-names = "periph_irq"; - interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>; - qcom,ee = <0>; - qcom,channel = <0>; - #address-cells = <2>; - #size-cells = <0>; interrupt-controller; - #interrupt-cells = <4>; + #interrupt-cells = <2>; }; + }; + + soc: soc { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0xffffffff>; + compatible = "simple-bus"; rng@22000 { compatible = "qcom,prng"; @@ -901,9 +397,14 @@ clock-names = "core"; }; + restart@4ab000 { + compatible = "qcom,pshold"; + reg = <0x004ab000 0x4>; + }; + qfprom: qfprom@5c000 { compatible = "qcom,qfprom"; - reg = <0x5c000 0x1000>; + reg = <0x0005c000 0x1000>; #address-cells = <1>; #size-cells = <1>; tsens_caldata: caldata@d0 { @@ -914,10 +415,24 @@ }; }; + rpm_msg_ram: memory@60000 { + compatible = "qcom,rpm-msg-ram"; + reg = <0x00060000 0x8000>; + }; + + bimc: interconnect@400000 { + compatible = "qcom,msm8916-bimc"; + reg = <0x00400000 0x62000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_BIMC_CLK>, + <&rpmcc RPM_SMD_BIMC_A_CLK>; + }; + tsens: thermal-sensor@4a9000 { compatible = "qcom,msm8916-tsens", "qcom,tsens-v0_1"; - reg = <0x4a9000 0x1000>, /* TM */ - <0x4a8000 0x1000>; /* SROT */ + reg = <0x004a9000 0x1000>, /* TM */ + <0x004a8000 0x1000>; /* SROT */ nvmem-cells = <&tsens_caldata>, <&tsens_calsel>; nvmem-cell-names = "calib", "calib_sel"; #qcom,sensors = <5>; @@ -926,365 +441,52 @@ #thermal-sensor-cells = <1>; }; - apps_iommu: iommu@1ef0000 { - #address-cells = <1>; - #size-cells = <1>; - #iommu-cells = <1>; - compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; - ranges = <0 0x1e20000 0x40000>; - reg = <0x1ef0000 0x3000>; - clocks = <&gcc GCC_SMMU_CFG_CLK>, - <&gcc GCC_APSS_TCU_CLK>; - clock-names = "iface", "bus"; - qcom,iommu-secure-id = <17>; - - // vfe: - iommu-ctx@3000 { - compatible = "qcom,msm-iommu-v1-sec"; - reg = <0x3000 0x1000>; - interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; - }; - - // mdp_0: - iommu-ctx@4000 { - compatible = "qcom,msm-iommu-v1-ns"; - reg = <0x4000 0x1000>; - interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; - }; - - // venus_ns: - iommu-ctx@5000 { - compatible = "qcom,msm-iommu-v1-sec"; - reg = <0x5000 0x1000>; - interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; - }; - }; - - gpu_iommu: iommu@1f08000 { - #address-cells = <1>; - #size-cells = <1>; - #iommu-cells = <1>; - compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; - ranges = <0 0x1f08000 0x10000>; - clocks = <&gcc GCC_SMMU_CFG_CLK>, - <&gcc GCC_GFX_TCU_CLK>; - clock-names = "iface", "bus"; - qcom,iommu-secure-id = <18>; - - // gfx3d_user: - iommu-ctx@1000 { - compatible = "qcom,msm-iommu-v1-ns"; - reg = <0x1000 0x1000>; - interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>; - }; - - // gfx3d_priv: - iommu-ctx@2000 { - compatible = "qcom,msm-iommu-v1-ns"; - reg = <0x2000 0x1000>; - interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>; - }; - }; - - gpu@1c00000 { - compatible = "qcom,adreno-306.0", "qcom,adreno"; - reg = <0x01c00000 0x20000>; - reg-names = "kgsl_3d0_reg_memory"; - interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "kgsl_3d0_irq"; - clock-names = - "core", - "iface", - "mem", - "mem_iface", - "alt_mem_iface", - "gfx3d"; - clocks = - <&gcc GCC_OXILI_GFX3D_CLK>, - <&gcc GCC_OXILI_AHB_CLK>, - <&gcc GCC_OXILI_GMEM_CLK>, - <&gcc GCC_BIMC_GFX_CLK>, - <&gcc GCC_BIMC_GPU_CLK>, - <&gcc GFX3D_CLK_SRC>; - power-domains = <&gcc OXILI_GDSC>; - operating-points-v2 = <&gpu_opp_table>; - iommus = <&gpu_iommu 1>, <&gpu_iommu 2>; - - gpu_opp_table: opp-table { - compatible = "operating-points-v2"; - - opp-400000000 { - opp-hz = /bits/ 64 <400000000>; - }; - opp-19200000 { - opp-hz = /bits/ 64 <19200000>; - }; - }; + pcnoc: interconnect@500000 { + compatible = "qcom,msm8916-pcnoc"; + reg = <0x00500000 0x11000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_PCNOC_CLK>, + <&rpmcc RPM_SMD_PCNOC_A_CLK>; }; - mdss: mdss@1a00000 { - compatible = "qcom,mdss"; - reg = <0x1a00000 0x1000>, - <0x1ac8000 0x3000>; - reg-names = "mdss_phys", "vbif_phys"; - - power-domains = <&gcc MDSS_GDSC>; - - clocks = <&gcc GCC_MDSS_AHB_CLK>, - <&gcc GCC_MDSS_AXI_CLK>, - <&gcc GCC_MDSS_VSYNC_CLK>; - clock-names = "iface", - "bus", - "vsync"; - - interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>; - - interrupt-controller; - #interrupt-cells = <1>; - - #address-cells = <1>; - #size-cells = <1>; - ranges; - - mdp: mdp@1a01000 { - compatible = "qcom,mdp5"; - reg = <0x1a01000 0x89000>; - reg-names = "mdp_phys"; - - interrupt-parent = <&mdss>; - interrupts = <0 0>; - - clocks = <&gcc GCC_MDSS_AHB_CLK>, - <&gcc GCC_MDSS_AXI_CLK>, - <&gcc GCC_MDSS_MDP_CLK>, - <&gcc GCC_MDSS_VSYNC_CLK>; - clock-names = "iface", - "bus", - "core", - "vsync"; - - iommus = <&apps_iommu 4>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - mdp5_intf1_out: endpoint { - remote-endpoint = <&dsi0_in>; - }; - }; - }; - }; - - dsi0: dsi@1a98000 { - compatible = "qcom,mdss-dsi-ctrl"; - reg = <0x1a98000 0x25c>; - reg-names = "dsi_ctrl"; - - interrupt-parent = <&mdss>; - interrupts = <4 0>; - - assigned-clocks = <&gcc BYTE0_CLK_SRC>, - <&gcc PCLK0_CLK_SRC>; - assigned-clock-parents = <&dsi_phy0 0>, - <&dsi_phy0 1>; - - clocks = <&gcc GCC_MDSS_MDP_CLK>, - <&gcc GCC_MDSS_AHB_CLK>, - <&gcc GCC_MDSS_AXI_CLK>, - <&gcc GCC_MDSS_BYTE0_CLK>, - <&gcc GCC_MDSS_PCLK0_CLK>, - <&gcc GCC_MDSS_ESC0_CLK>; - clock-names = "mdp_core", - "iface", - "bus", - "byte", - "pixel", - "core"; - phys = <&dsi_phy0>; - phy-names = "dsi-phy"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - dsi0_in: endpoint { - remote-endpoint = <&mdp5_intf1_out>; - }; - }; - - port@1 { - reg = <1>; - dsi0_out: endpoint { - }; - }; - }; - }; - - dsi_phy0: dsi-phy@1a98300 { - compatible = "qcom,dsi-phy-28nm-lp"; - reg = <0x1a98300 0xd4>, - <0x1a98500 0x280>, - <0x1a98780 0x30>; - reg-names = "dsi_pll", - "dsi_phy", - "dsi_phy_regulator"; - - #clock-cells = <1>; - #phy-cells = <0>; - - clocks = <&gcc GCC_MDSS_AHB_CLK>, - <&xo_board>; - clock-names = "iface", "ref"; - }; + snoc: interconnect@580000 { + compatible = "qcom,msm8916-snoc"; + reg = <0x00580000 0x14000>; + #interconnect-cells = <1>; + clock-names = "bus", "bus_a"; + clocks = <&rpmcc RPM_SMD_SNOC_CLK>, + <&rpmcc RPM_SMD_SNOC_A_CLK>; }; + /* System CTIs */ + /* CTI 0 - TMC connections */ + cti0: cti@810000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x00810000 0x1000>; - hexagon@4080000 { - compatible = "qcom,q6v5-pil"; - reg = <0x04080000 0x100>, - <0x04020000 0x040>; - - reg-names = "qdsp6", "rmb"; - - interrupts-extended = <&intc 0 24 1>, - <&hexagon_smp2p_in 0 0>, - <&hexagon_smp2p_in 1 0>, - <&hexagon_smp2p_in 2 0>, - <&hexagon_smp2p_in 3 0>; - interrupt-names = "wdog", "fatal", "ready", - "handover", "stop-ack"; - - clocks = <&gcc GCC_MSS_CFG_AHB_CLK>, - <&gcc GCC_MSS_Q6_BIMC_AXI_CLK>, - <&gcc GCC_BOOT_ROM_AHB_CLK>, - <&xo_board>; - clock-names = "iface", "bus", "mem", "xo"; - - qcom,smem-states = <&hexagon_smp2p_out 0>; - qcom,smem-state-names = "stop"; - - resets = <&scm 0>; - reset-names = "mss_restart"; - - cx-supply = <&pm8916_s1>; - mx-supply = <&pm8916_l3>; - pll-supply = <&pm8916_l7>; - - qcom,halt-regs = <&tcsr 0x18000 0x19000 0x1a000>; + clocks = <&rpmcc RPM_QDSS_CLK>; + clock-names = "apb_pclk"; status = "disabled"; - - mba { - memory-region = <&mba_mem>; - }; - - mpss { - memory-region = <&mpss_mem>; - }; - - smd-edge { - interrupts = <0 25 IRQ_TYPE_EDGE_RISING>; - - qcom,smd-edge = <0>; - qcom,ipc = <&apcs 8 12>; - qcom,remote-pid = <1>; - - label = "hexagon"; - - fastrpc { - compatible = "qcom,fastrpc"; - qcom,smd-channels = "fastrpcsmd-apps-dsp"; - label = "adsp"; - - #address-cells = <1>; - #size-cells = <0>; - - cb@1{ - compatible = "qcom,fastrpc-compute-cb"; - reg = <1>; - }; - }; - }; }; - pronto: wcnss@a21b000 { - compatible = "qcom,pronto-v2-pil", "qcom,pronto"; - reg = <0x0a204000 0x2000>, <0x0a202000 0x1000>, <0x0a21b000 0x3000>; - reg-names = "ccu", "dxe", "pmu"; - - memory-region = <&wcnss_mem>; - - interrupts-extended = <&intc 0 149 IRQ_TYPE_EDGE_RISING>, - <&wcnss_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, - <&wcnss_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, - <&wcnss_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, - <&wcnss_smp2p_in 3 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack"; - - vddmx-supply = <&pm8916_l3>; - vddpx-supply = <&pm8916_l7>; - - qcom,state = <&wcnss_smp2p_out 0>; - qcom,state-names = "stop"; + /* CTI 1 - TPIU connections */ + cti1: cti@811000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x00811000 0x1000>; - pinctrl-names = "default"; - pinctrl-0 = <&wcnss_pin_a>; + clocks = <&rpmcc RPM_QDSS_CLK>; + clock-names = "apb_pclk"; status = "disabled"; - - iris { - compatible = "qcom,wcn3620"; - - clocks = <&rpmcc RPM_SMD_RF_CLK2>; - clock-names = "xo"; - - vddxo-supply = <&pm8916_l7>; - vddrfa-supply = <&pm8916_s3>; - vddpa-supply = <&pm8916_l9>; - vdddig-supply = <&pm8916_l5>; - }; - - smd-edge { - interrupts = <0 142 1>; - - qcom,ipc = <&apcs 8 17>; - qcom,smd-edge = <6>; - qcom,remote-pid = <4>; - - label = "pronto"; - - wcnss { - compatible = "qcom,wcnss"; - qcom,smd-channels = "WCNSS_CTRL"; - - qcom,mmio = <&pronto>; - - bt { - compatible = "qcom,wcnss-bt"; - }; - - wifi { - compatible = "qcom,wcnss-wlan"; - - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>, - <0 146 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "tx", "rx"; - - qcom,smem-states = <&apps_smsm 10>, <&apps_smsm 9>; - qcom,smem-state-names = "tx-enable", "tx-rings-empty"; - }; - }; - }; }; - tpiu@820000 { + /* CTIs 2-11 - no information - not instantiated */ + + tpiu: tpiu@820000 { compatible = "arm,coresight-tpiu", "arm,primecell"; - reg = <0x820000 0x1000>; + reg = <0x00820000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1300,9 +502,9 @@ }; }; - funnel@821000 { + funnel0: funnel@821000 { compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; - reg = <0x821000 0x1000>; + reg = <0x00821000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1341,9 +543,9 @@ }; }; - replicator@824000 { + replicator: replicator@824000 { compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; - reg = <0x824000 0x1000>; + reg = <0x00824000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1377,9 +579,9 @@ }; }; - etf@825000 { + etf: etf@825000 { compatible = "arm,coresight-tmc", "arm,primecell"; - reg = <0x825000 0x1000>; + reg = <0x00825000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1403,9 +605,9 @@ }; }; - etr@826000 { + etr: etr@826000 { compatible = "arm,coresight-tmc", "arm,primecell"; - reg = <0x826000 0x1000>; + reg = <0x00826000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1421,9 +623,9 @@ }; }; - funnel@841000 { /* APSS funnel only 4 inputs are used */ + funnel1: funnel@841000 { /* APSS funnel only 4 inputs are used */ compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; - reg = <0x841000 0x1000>; + reg = <0x00841000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1469,45 +671,106 @@ }; }; - debug@850000 { - compatible = "arm,coresight-cpu-debug","arm,primecell"; - reg = <0x850000 0x1000>; + debug0: debug@850000 { + compatible = "arm,coresight-cpu-debug", "arm,primecell"; + reg = <0x00850000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>; clock-names = "apb_pclk"; cpu = <&CPU0>; status = "disabled"; }; - debug@852000 { - compatible = "arm,coresight-cpu-debug","arm,primecell"; - reg = <0x852000 0x1000>; + debug1: debug@852000 { + compatible = "arm,coresight-cpu-debug", "arm,primecell"; + reg = <0x00852000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>; clock-names = "apb_pclk"; cpu = <&CPU1>; status = "disabled"; }; - debug@854000 { - compatible = "arm,coresight-cpu-debug","arm,primecell"; - reg = <0x854000 0x1000>; + debug2: debug@854000 { + compatible = "arm,coresight-cpu-debug", "arm,primecell"; + reg = <0x00854000 0x1000>; + clocks = <&rpmcc RPM_QDSS_CLK>; + clock-names = "apb_pclk"; + cpu = <&CPU2>; + status = "disabled"; + }; + + debug3: debug@856000 { + compatible = "arm,coresight-cpu-debug", "arm,primecell"; + reg = <0x00856000 0x1000>; + clocks = <&rpmcc RPM_QDSS_CLK>; + clock-names = "apb_pclk"; + cpu = <&CPU3>; + status = "disabled"; + }; + + /* Core CTIs; CTIs 12-15 */ + /* CTI - CPU-0 */ + cti12: cti@858000 { + compatible = "arm,coresight-cti-v8-arch", "arm,coresight-cti", + "arm,primecell"; + reg = <0x00858000 0x1000>; + + clocks = <&rpmcc RPM_QDSS_CLK>; + clock-names = "apb_pclk"; + + cpu = <&CPU0>; + arm,cs-dev-assoc = <&etm0>; + + status = "disabled"; + }; + + /* CTI - CPU-1 */ + cti13: cti@859000 { + compatible = "arm,coresight-cti-v8-arch", "arm,coresight-cti", + "arm,primecell"; + reg = <0x00859000 0x1000>; + + clocks = <&rpmcc RPM_QDSS_CLK>; + clock-names = "apb_pclk"; + + cpu = <&CPU1>; + arm,cs-dev-assoc = <&etm1>; + + status = "disabled"; + }; + + /* CTI - CPU-2 */ + cti14: cti@85a000 { + compatible = "arm,coresight-cti-v8-arch", "arm,coresight-cti", + "arm,primecell"; + reg = <0x0085a000 0x1000>; + clocks = <&rpmcc RPM_QDSS_CLK>; clock-names = "apb_pclk"; + cpu = <&CPU2>; + arm,cs-dev-assoc = <&etm2>; + status = "disabled"; }; - debug@856000 { - compatible = "arm,coresight-cpu-debug","arm,primecell"; - reg = <0x856000 0x1000>; + /* CTI - CPU-3 */ + cti15: cti@85b000 { + compatible = "arm,coresight-cti-v8-arch", "arm,coresight-cti", + "arm,primecell"; + reg = <0x0085b000 0x1000>; + clocks = <&rpmcc RPM_QDSS_CLK>; clock-names = "apb_pclk"; + cpu = <&CPU3>; + arm,cs-dev-assoc = <&etm3>; + status = "disabled"; }; etm0: etm@85c000 { compatible = "arm,coresight-etm4x", "arm,primecell"; - reg = <0x85c000 0x1000>; + reg = <0x0085c000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1528,7 +791,7 @@ etm1: etm@85d000 { compatible = "arm,coresight-etm4x", "arm,primecell"; - reg = <0x85d000 0x1000>; + reg = <0x0085d000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1549,7 +812,7 @@ etm2: etm@85e000 { compatible = "arm,coresight-etm4x", "arm,primecell"; - reg = <0x85e000 0x1000>; + reg = <0x0085e000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1570,7 +833,7 @@ etm3: etm@85f000 { compatible = "arm,coresight-etm4x", "arm,primecell"; - reg = <0x85f000 0x1000>; + reg = <0x0085f000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1589,126 +852,171 @@ }; }; - /* System CTIs */ - /* CTI 0 - TMC connections */ - cti@810000 { - compatible = "arm,coresight-cti", "arm,primecell"; - reg = <0x810000 0x1000>; - - clocks = <&rpmcc RPM_QDSS_CLK>; - clock-names = "apb_pclk"; - - status = "disabled"; + msmgpio: pinctrl@1000000 { + compatible = "qcom,msm8916-pinctrl"; + reg = <0x01000000 0x300000>; + interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + gpio-ranges = <&msmgpio 0 0 122>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; }; - /* CTI 1 - TPIU connections */ - cti@811000 { - compatible = "arm,coresight-cti", "arm,primecell"; - reg = <0x811000 0x1000>; + gcc: clock-controller@1800000 { + compatible = "qcom,gcc-msm8916"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + reg = <0x01800000 0x80000>; + }; - clocks = <&rpmcc RPM_QDSS_CLK>; - clock-names = "apb_pclk"; + tcsr_mutex: hwlock@1905000 { + compatible = "qcom,tcsr-mutex"; + reg = <0x01905000 0x20000>; + #hwlock-cells = <1>; + }; - status = "disabled"; + tcsr: syscon@1937000 { + compatible = "qcom,tcsr-msm8916", "syscon"; + reg = <0x01937000 0x30000>; }; - /* CTIs 2-11 - no information - not instantiated */ + mdss: mdss@1a00000 { + compatible = "qcom,mdss"; + reg = <0x01a00000 0x1000>, + <0x01ac8000 0x3000>; + reg-names = "mdss_phys", "vbif_phys"; - /* Core CTIs; CTIs 12-15 */ - /* CTI - CPU-0 */ - cti@858000 { - compatible = "arm,coresight-cti-v8-arch", "arm,coresight-cti", - "arm,primecell"; - reg = <0x858000 0x1000>; + power-domains = <&gcc MDSS_GDSC>; - clocks = <&rpmcc RPM_QDSS_CLK>; - clock-names = "apb_pclk"; + clocks = <&gcc GCC_MDSS_AHB_CLK>, + <&gcc GCC_MDSS_AXI_CLK>, + <&gcc GCC_MDSS_VSYNC_CLK>; + clock-names = "iface", + "bus", + "vsync"; - cpu = <&CPU0>; - arm,cs-dev-assoc = <&etm0>; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; - }; + interrupt-controller; + #interrupt-cells = <1>; - /* CTI - CPU-1 */ - cti@859000 { - compatible = "arm,coresight-cti-v8-arch", "arm,coresight-cti", - "arm,primecell"; - reg = <0x859000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges; - clocks = <&rpmcc RPM_QDSS_CLK>; - clock-names = "apb_pclk"; + mdp: mdp@1a01000 { + compatible = "qcom,mdp5"; + reg = <0x01a01000 0x89000>; + reg-names = "mdp_phys"; - cpu = <&CPU1>; - arm,cs-dev-assoc = <&etm1>; + interrupt-parent = <&mdss>; + interrupts = <0>; - status = "disabled"; - }; + clocks = <&gcc GCC_MDSS_AHB_CLK>, + <&gcc GCC_MDSS_AXI_CLK>, + <&gcc GCC_MDSS_MDP_CLK>, + <&gcc GCC_MDSS_VSYNC_CLK>; + clock-names = "iface", + "bus", + "core", + "vsync"; - /* CTI - CPU-2 */ - cti@85a000 { - compatible = "arm,coresight-cti-v8-arch", "arm,coresight-cti", - "arm,primecell"; - reg = <0x85a000 0x1000>; + iommus = <&apps_iommu 4>; - clocks = <&rpmcc RPM_QDSS_CLK>; - clock-names = "apb_pclk"; + ports { + #address-cells = <1>; + #size-cells = <0>; - cpu = <&CPU2>; - arm,cs-dev-assoc = <&etm2>; + port@0 { + reg = <0>; + mdp5_intf1_out: endpoint { + remote-endpoint = <&dsi0_in>; + }; + }; + }; + }; - status = "disabled"; - }; + dsi0: dsi@1a98000 { + compatible = "qcom,mdss-dsi-ctrl"; + reg = <0x01a98000 0x25c>; + reg-names = "dsi_ctrl"; - /* CTI - CPU-3 */ - cti@85b000 { - compatible = "arm,coresight-cti-v8-arch", "arm,coresight-cti", - "arm,primecell"; - reg = <0x85b000 0x1000>; + interrupt-parent = <&mdss>; + interrupts = <4>; - clocks = <&rpmcc RPM_QDSS_CLK>; - clock-names = "apb_pclk"; + assigned-clocks = <&gcc BYTE0_CLK_SRC>, + <&gcc PCLK0_CLK_SRC>; + assigned-clock-parents = <&dsi_phy0 0>, + <&dsi_phy0 1>; - cpu = <&CPU3>; - arm,cs-dev-assoc = <&etm3>; + clocks = <&gcc GCC_MDSS_MDP_CLK>, + <&gcc GCC_MDSS_AHB_CLK>, + <&gcc GCC_MDSS_AXI_CLK>, + <&gcc GCC_MDSS_BYTE0_CLK>, + <&gcc GCC_MDSS_PCLK0_CLK>, + <&gcc GCC_MDSS_ESC0_CLK>; + clock-names = "mdp_core", + "iface", + "bus", + "byte", + "pixel", + "core"; + phys = <&dsi_phy0>; + phy-names = "dsi-phy"; - status = "disabled"; - }; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; - venus: video-codec@1d00000 { - compatible = "qcom,msm8916-venus"; - reg = <0x01d00000 0xff000>; - interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; - power-domains = <&gcc VENUS_GDSC>; - clocks = <&gcc GCC_VENUS0_VCODEC0_CLK>, - <&gcc GCC_VENUS0_AHB_CLK>, - <&gcc GCC_VENUS0_AXI_CLK>; - clock-names = "core", "iface", "bus"; - iommus = <&apps_iommu 5>; - memory-region = <&venus_mem>; - status = "okay"; + port@0 { + reg = <0>; + dsi0_in: endpoint { + remote-endpoint = <&mdp5_intf1_out>; + }; + }; - video-decoder { - compatible = "venus-decoder"; + port@1 { + reg = <1>; + dsi0_out: endpoint { + }; + }; + }; }; - video-encoder { - compatible = "venus-encoder"; + dsi_phy0: dsi-phy@1a98300 { + compatible = "qcom,dsi-phy-28nm-lp"; + reg = <0x01a98300 0xd4>, + <0x01a98500 0x280>, + <0x01a98780 0x30>; + reg-names = "dsi_pll", + "dsi_phy", + "dsi_phy_regulator"; + + #clock-cells = <1>; + #phy-cells = <0>; + + clocks = <&gcc GCC_MDSS_AHB_CLK>, + <&xo_board>; + clock-names = "iface", "ref"; }; }; camss: camss@1b00000 { compatible = "qcom,msm8916-camss"; - reg = <0x1b0ac00 0x200>, - <0x1b00030 0x4>, - <0x1b0b000 0x200>, - <0x1b00038 0x4>, - <0x1b08000 0x100>, - <0x1b08400 0x100>, - <0x1b0a000 0x500>, - <0x1b00020 0x10>, - <0x1b10000 0x1000>; + reg = <0x01b0ac00 0x200>, + <0x01b00030 0x4>, + <0x01b0b000 0x200>, + <0x01b00038 0x4>, + <0x01b08000 0x100>, + <0x01b08400 0x100>, + <0x01b0a000 0x500>, + <0x01b00020 0x10>, + <0x01b10000 0x1000>; reg-names = "csiphy0", "csiphy0_clk_mux", "csiphy1", @@ -1769,7 +1077,6 @@ "csi_vfe0", "vfe_ahb", "vfe_axi"; - vdda-supply = <&pm8916_l2>; iommus = <&apps_iommu 3>; status = "disabled"; ports { @@ -1782,7 +1089,7 @@ compatible = "qcom,msm8916-cci"; #address-cells = <1>; #size-cells = <0>; - reg = <0x1b0c000 0x1000>; + reg = <0x01b0c000 0x1000>; interrupts = <GIC_SPI 50 IRQ_TYPE_EDGE_RISING>; clocks = <&gcc GCC_CAMSS_TOP_AHB_CLK>, <&gcc GCC_CAMSS_CCI_AHB_CLK>, @@ -1804,135 +1111,804 @@ #size-cells = <0>; }; }; - }; - - smd { - compatible = "qcom,smd"; - rpm { - interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>; - qcom,ipc = <&apcs 8 0>; - qcom,smd-edge = <15>; + gpu@1c00000 { + compatible = "qcom,adreno-306.0", "qcom,adreno"; + reg = <0x01c00000 0x20000>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "kgsl_3d0_irq"; + clock-names = + "core", + "iface", + "mem", + "mem_iface", + "alt_mem_iface", + "gfx3d"; + clocks = + <&gcc GCC_OXILI_GFX3D_CLK>, + <&gcc GCC_OXILI_AHB_CLK>, + <&gcc GCC_OXILI_GMEM_CLK>, + <&gcc GCC_BIMC_GFX_CLK>, + <&gcc GCC_BIMC_GPU_CLK>, + <&gcc GFX3D_CLK_SRC>; + power-domains = <&gcc OXILI_GDSC>; + operating-points-v2 = <&gpu_opp_table>; + iommus = <&gpu_iommu 1>, <&gpu_iommu 2>; - rpm-requests { - compatible = "qcom,rpm-msm8916"; - qcom,smd-channels = "rpm_requests"; + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; - rpmcc: qcom,rpmcc { - compatible = "qcom,rpmcc-msm8916"; - #clock-cells = <1>; + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; }; - - smd_rpm_regulators: pm8916-regulators { - compatible = "qcom,rpm-pm8916-regulators"; - - pm8916_s1: s1 {}; - pm8916_s3: s3 {}; - pm8916_s4: s4 {}; - - pm8916_l1: l1 {}; - pm8916_l2: l2 {}; - pm8916_l3: l3 {}; - pm8916_l4: l4 {}; - pm8916_l5: l5 {}; - pm8916_l6: l6 {}; - pm8916_l7: l7 {}; - pm8916_l8: l8 {}; - pm8916_l9: l9 {}; - pm8916_l10: l10 {}; - pm8916_l11: l11 {}; - pm8916_l12: l12 {}; - pm8916_l13: l13 {}; - pm8916_l14: l14 {}; - pm8916_l15: l15 {}; - pm8916_l16: l16 {}; - pm8916_l17: l17 {}; - pm8916_l18: l18 {}; + opp-19200000 { + opp-hz = /bits/ 64 <19200000>; }; }; }; - }; - hexagon-smp2p { - compatible = "qcom,smp2p"; - qcom,smem = <435>, <428>; + venus: video-codec@1d00000 { + compatible = "qcom,msm8916-venus"; + reg = <0x01d00000 0xff000>; + interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&gcc VENUS_GDSC>; + clocks = <&gcc GCC_VENUS0_VCODEC0_CLK>, + <&gcc GCC_VENUS0_AHB_CLK>, + <&gcc GCC_VENUS0_AXI_CLK>; + clock-names = "core", "iface", "bus"; + iommus = <&apps_iommu 5>; + memory-region = <&venus_mem>; + status = "okay"; - interrupts = <0 27 IRQ_TYPE_EDGE_RISING>; + video-decoder { + compatible = "venus-decoder"; + }; - qcom,ipc = <&apcs 8 14>; + video-encoder { + compatible = "venus-encoder"; + }; + }; - qcom,local-pid = <0>; - qcom,remote-pid = <1>; + apps_iommu: iommu@1ef0000 { + #address-cells = <1>; + #size-cells = <1>; + #iommu-cells = <1>; + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; + ranges = <0 0x01e20000 0x40000>; + reg = <0x01ef0000 0x3000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_APSS_TCU_CLK>; + clock-names = "iface", "bus"; + qcom,iommu-secure-id = <17>; - hexagon_smp2p_out: master-kernel { - qcom,entry-name = "master-kernel"; + // vfe: + iommu-ctx@3000 { + compatible = "qcom,msm-iommu-v1-sec"; + reg = <0x3000 0x1000>; + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; + }; - #qcom,smem-state-cells = <1>; + // mdp_0: + iommu-ctx@4000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x4000 0x1000>; + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; + }; + + // venus_ns: + iommu-ctx@5000 { + compatible = "qcom,msm-iommu-v1-sec"; + reg = <0x5000 0x1000>; + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; + }; }; - hexagon_smp2p_in: slave-kernel { - qcom,entry-name = "slave-kernel"; + gpu_iommu: iommu@1f08000 { + #address-cells = <1>; + #size-cells = <1>; + #iommu-cells = <1>; + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; + ranges = <0 0x01f08000 0x10000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_GFX_TCU_CLK>; + clock-names = "iface", "bus"; + qcom,iommu-secure-id = <18>; + + // gfx3d_user: + iommu-ctx@1000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x1000 0x1000>; + interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>; + }; + + // gfx3d_priv: + iommu-ctx@2000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x2000 0x1000>; + interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + spmi_bus: spmi@200f000 { + compatible = "qcom,spmi-pmic-arb"; + reg = <0x0200f000 0x001000>, + <0x02400000 0x400000>, + <0x02c00000 0x400000>, + <0x03800000 0x200000>, + <0x0200a000 0x002100>; + reg-names = "core", "chnls", "obsrvr", "intr", "cnfg"; + interrupt-names = "periph_irq"; + interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>; + qcom,ee = <0>; + qcom,channel = <0>; + #address-cells = <2>; + #size-cells = <0>; interrupt-controller; - #interrupt-cells = <2>; + #interrupt-cells = <4>; }; - }; - wcnss-smp2p { - compatible = "qcom,smp2p"; - qcom,smem = <451>, <431>; + mpss: remoteproc@4080000 { + compatible = "qcom,msm8916-mss-pil", "qcom,q6v5-pil"; + reg = <0x04080000 0x100>, + <0x04020000 0x040>; - interrupts = <0 143 IRQ_TYPE_EDGE_RISING>; + reg-names = "qdsp6", "rmb"; - qcom,ipc = <&apcs 8 18>; + interrupts-extended = <&intc GIC_SPI 24 IRQ_TYPE_EDGE_RISING>, + <&hexagon_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&hexagon_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, + <&hexagon_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, + <&hexagon_smp2p_in 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", "fatal", "ready", + "handover", "stop-ack"; - qcom,local-pid = <0>; - qcom,remote-pid = <4>; + clocks = <&gcc GCC_MSS_CFG_AHB_CLK>, + <&gcc GCC_MSS_Q6_BIMC_AXI_CLK>, + <&gcc GCC_BOOT_ROM_AHB_CLK>, + <&xo_board>; + clock-names = "iface", "bus", "mem", "xo"; - wcnss_smp2p_out: master-kernel { - qcom,entry-name = "master-kernel"; + qcom,smem-states = <&hexagon_smp2p_out 0>; + qcom,smem-state-names = "stop"; - #qcom,smem-state-cells = <1>; + resets = <&scm 0>; + reset-names = "mss_restart"; + + qcom,halt-regs = <&tcsr 0x18000 0x19000 0x1a000>; + + status = "disabled"; + + mba { + memory-region = <&mba_mem>; + }; + + mpss { + memory-region = <&mpss_mem>; + }; + + smd-edge { + interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>; + + qcom,smd-edge = <0>; + qcom,ipc = <&apcs 8 12>; + qcom,remote-pid = <1>; + + label = "hexagon"; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,smd-channels = "fastrpcsmd-apps-dsp"; + label = "adsp"; + + #address-cells = <1>; + #size-cells = <0>; + + cb@1 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <1>; + }; + }; + }; }; - wcnss_smp2p_in: slave-kernel { - qcom,entry-name = "slave-kernel"; + sound: sound@7702000 { + status = "disabled"; + compatible = "qcom,apq8016-sbc-sndcard"; + reg = <0x07702000 0x4>, <0x07702004 0x4>; + reg-names = "mic-iomux", "spkr-iomux"; + }; + + lpass: audio-controller@7708000 { + status = "disabled"; + compatible = "qcom,lpass-cpu-apq8016"; + clocks = <&gcc GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK>, + <&gcc GCC_ULTAUDIO_PCNOC_MPORT_CLK>, + <&gcc GCC_ULTAUDIO_PCNOC_SWAY_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK>; + + clock-names = "ahbix-clk", + "pcnoc-mport-clk", + "pcnoc-sway-clk", + "mi2s-bit-clk0", + "mi2s-bit-clk1", + "mi2s-bit-clk2", + "mi2s-bit-clk3"; + #sound-dai-cells = <1>; + + interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "lpass-irq-lpaif"; + reg = <0x07708000 0x10000>; + reg-names = "lpass-lpaif"; + + #address-cells = <1>; + #size-cells = <0>; + }; + + lpass_codec: audio-codec@771c000 { + compatible = "qcom,msm8916-wcd-digital-codec"; + reg = <0x0771c000 0x400>; + clocks = <&gcc GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK>, + <&gcc GCC_CODEC_DIGCODEC_CLK>; + clock-names = "ahbix-clk", "mclk"; + #sound-dai-cells = <1>; + }; + sdhc_1: sdhci@7824000 { + compatible = "qcom,sdhci-msm-v4"; + reg = <0x07824900 0x11c>, <0x07824000 0x800>; + reg-names = "hc_mem", "core_mem"; + + interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hc_irq", "pwr_irq"; + clocks = <&gcc GCC_SDCC1_APPS_CLK>, + <&gcc GCC_SDCC1_AHB_CLK>, + <&xo_board>; + clock-names = "core", "iface", "xo"; + mmc-ddr-1_8v; + bus-width = <8>; + non-removable; + status = "disabled"; + }; + + sdhc_2: sdhci@7864000 { + compatible = "qcom,sdhci-msm-v4"; + reg = <0x07864900 0x11c>, <0x07864000 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"; + bus-width = <4>; + status = "disabled"; + }; + + blsp_dma: dma@7884000 { + compatible = "qcom,bam-v1.7.0"; + reg = <0x07884000 0x23000>; + interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "bam_clk"; + #dma-cells = <1>; + qcom,ee = <0>; + status = "disabled"; + }; + + blsp1_uart1: serial@78af000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0x078af000 0x200>; + interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_UART1_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp_dma 1>, <&blsp_dma 0>; + dma-names = "rx", "tx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&blsp1_uart1_default>; + pinctrl-1 = <&blsp1_uart1_sleep>; + status = "disabled"; + }; + + blsp1_uart2: serial@78b0000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0x078b0000 0x200>; + interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp_dma 3>, <&blsp_dma 2>; + dma-names = "rx", "tx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&blsp1_uart2_default>; + pinctrl-1 = <&blsp1_uart2_sleep>; + status = "disabled"; + }; + + blsp_i2c1: i2c@78b5000 { + compatible = "qcom,i2c-qup-v2.2.1"; + reg = <0x078b5000 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"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c1_default>; + pinctrl-1 = <&i2c1_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp_spi1: spi@78b5000 { + compatible = "qcom,spi-qup-v2.2.1"; + reg = <0x078b5000 0x500>; + interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_QUP1_SPI_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp_dma 5>, <&blsp_dma 4>; + dma-names = "rx", "tx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&spi1_default>; + pinctrl-1 = <&spi1_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp_i2c2: i2c@78b6000 { + compatible = "qcom,i2c-qup-v2.2.1"; + reg = <0x078b6000 0x500>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_AHB_CLK>, + <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>; + clock-names = "iface", "core"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c2_default>; + pinctrl-1 = <&i2c2_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp_spi2: spi@78b6000 { + compatible = "qcom,spi-qup-v2.2.1"; + reg = <0x078b6000 0x500>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_QUP2_SPI_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp_dma 7>, <&blsp_dma 6>; + dma-names = "rx", "tx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&spi2_default>; + pinctrl-1 = <&spi2_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp_spi3: spi@78b7000 { + compatible = "qcom,spi-qup-v2.2.1"; + reg = <0x078b7000 0x500>; + interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_QUP3_SPI_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp_dma 9>, <&blsp_dma 8>; + dma-names = "rx", "tx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&spi3_default>; + pinctrl-1 = <&spi3_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp_i2c4: i2c@78b8000 { + compatible = "qcom,i2c-qup-v2.2.1"; + reg = <0x078b8000 0x500>; + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_AHB_CLK>, + <&gcc GCC_BLSP1_QUP4_I2C_APPS_CLK>; + clock-names = "iface", "core"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c4_default>; + pinctrl-1 = <&i2c4_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp_spi4: spi@78b8000 { + compatible = "qcom,spi-qup-v2.2.1"; + reg = <0x078b8000 0x500>; + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_QUP4_SPI_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp_dma 11>, <&blsp_dma 10>; + dma-names = "rx", "tx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&spi4_default>; + pinctrl-1 = <&spi4_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp_i2c5: i2c@78b9000 { + compatible = "qcom,i2c-qup-v2.2.1"; + reg = <0x078b9000 0x500>; + interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_AHB_CLK>, + <&gcc GCC_BLSP1_QUP5_I2C_APPS_CLK>; + clock-names = "iface", "core"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c5_default>; + pinctrl-1 = <&i2c5_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp_spi5: spi@78b9000 { + compatible = "qcom,spi-qup-v2.2.1"; + reg = <0x078b9000 0x500>; + interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_QUP5_SPI_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp_dma 13>, <&blsp_dma 12>; + dma-names = "rx", "tx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&spi5_default>; + pinctrl-1 = <&spi5_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp_i2c6: i2c@78ba000 { + compatible = "qcom,i2c-qup-v2.2.1"; + reg = <0x078ba000 0x500>; + interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_AHB_CLK>, + <&gcc GCC_BLSP1_QUP6_I2C_APPS_CLK>; + clock-names = "iface", "core"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c6_default>; + pinctrl-1 = <&i2c6_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + blsp_spi6: spi@78ba000 { + compatible = "qcom,spi-qup-v2.2.1"; + reg = <0x078ba000 0x500>; + interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_BLSP1_QUP6_SPI_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp_dma 15>, <&blsp_dma 14>; + dma-names = "rx", "tx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&spi6_default>; + pinctrl-1 = <&spi6_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + usb: usb@78d9000 { + compatible = "qcom,ci-hdrc"; + reg = <0x078d9000 0x200>, + <0x078d9200 0x200>; + interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_USB_HS_AHB_CLK>, + <&gcc GCC_USB_HS_SYSTEM_CLK>; + clock-names = "iface", "core"; + assigned-clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>; + assigned-clock-rates = <80000000>; + resets = <&gcc GCC_USB_HS_BCR>; + reset-names = "core"; + phy_type = "ulpi"; + dr_mode = "otg"; + hnp-disable; + srp-disable; + adp-disable; + ahb-burst-config = <0>; + phy-names = "usb-phy"; + phys = <&usb_hs_phy>; + status = "disabled"; + #reset-cells = <1>; + + ulpi { + usb_hs_phy: phy { + compatible = "qcom,usb-hs-phy-msm8916", + "qcom,usb-hs-phy"; + #phy-cells = <0>; + clocks = <&xo_board>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>; + clock-names = "ref", "sleep"; + resets = <&gcc GCC_USB2A_PHY_BCR>, <&usb 0>; + reset-names = "phy", "por"; + qcom,init-seq = /bits/ 8 <0x0 0x44 + 0x1 0x6b 0x2 0x24 0x3 0x13>; + }; + }; + }; + + pronto: remoteproc@a21b000 { + compatible = "qcom,pronto-v2-pil", "qcom,pronto"; + reg = <0x0a204000 0x2000>, <0x0a202000 0x1000>, <0x0a21b000 0x3000>; + reg-names = "ccu", "dxe", "pmu"; + + memory-region = <&wcnss_mem>; + + interrupts-extended = <&intc GIC_SPI 149 IRQ_TYPE_EDGE_RISING>, + <&wcnss_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&wcnss_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, + <&wcnss_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, + <&wcnss_smp2p_in 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack"; + + qcom,state = <&wcnss_smp2p_out 0>; + qcom,state-names = "stop"; + + pinctrl-names = "default"; + pinctrl-0 = <&wcnss_pin_a>; + + status = "disabled"; + + iris { + compatible = "qcom,wcn3620"; + + clocks = <&rpmcc RPM_SMD_RF_CLK2>; + clock-names = "xo"; + }; + + smd-edge { + interrupts = <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>; + + qcom,ipc = <&apcs 8 17>; + qcom,smd-edge = <6>; + qcom,remote-pid = <4>; + + label = "pronto"; + + wcnss { + compatible = "qcom,wcnss"; + qcom,smd-channels = "WCNSS_CTRL"; + + qcom,mmio = <&pronto>; + + bt { + compatible = "qcom,wcnss-bt"; + }; + + wifi { + compatible = "qcom,wcnss-wlan"; + + interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "tx", "rx"; + + qcom,smem-states = <&apps_smsm 10>, <&apps_smsm 9>; + qcom,smem-state-names = "tx-enable", "tx-rings-empty"; + }; + }; + }; + }; + + intc: interrupt-controller@b000000 { + compatible = "qcom,msm-qgic2"; interrupt-controller; - #interrupt-cells = <2>; + #interrupt-cells = <3>; + reg = <0x0b000000 0x1000>, <0x0b002000 0x1000>; + }; + + apcs: mailbox@b011000 { + compatible = "qcom,msm8916-apcs-kpss-global", "syscon"; + reg = <0x0b011000 0x1000>; + #mbox-cells = <1>; + clocks = <&a53pll>, <&gcc GPLL0_VOTE>; + clock-names = "pll", "aux"; + #clock-cells = <0>; + }; + + a53pll: clock@b016000 { + compatible = "qcom,msm8916-a53pll"; + reg = <0x0b016000 0x40>; + #clock-cells = <0>; + }; + + timer@b020000 { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "arm,armv7-timer-mem"; + reg = <0x0b020000 0x1000>; + clock-frequency = <19200000>; + + frame@b021000 { + frame-number = <0>; + interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0b021000 0x1000>, + <0x0b022000 0x1000>; + }; + + frame@b023000 { + frame-number = <1>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0b023000 0x1000>; + status = "disabled"; + }; + + frame@b024000 { + frame-number = <2>; + interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0b024000 0x1000>; + status = "disabled"; + }; + + frame@b025000 { + frame-number = <3>; + interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0b025000 0x1000>; + status = "disabled"; + }; + + frame@b026000 { + frame-number = <4>; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0b026000 0x1000>; + status = "disabled"; + }; + + frame@b027000 { + frame-number = <5>; + interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0b027000 0x1000>; + status = "disabled"; + }; + + frame@b028000 { + frame-number = <6>; + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; + reg = <0x0b028000 0x1000>; + status = "disabled"; + }; }; }; - smsm { - compatible = "qcom,smsm"; + thermal-zones { + cpu0-1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; - #address-cells = <1>; - #size-cells = <0>; + thermal-sensors = <&tsens 5>; - qcom,ipc-1 = <&apcs 8 13>; - qcom,ipc-3 = <&apcs 8 19>; + trips { + cpu0_1_alert0: trip-point0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu0_1_crit: cpu_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; + }; - apps_smsm: apps@0 { - reg = <0>; + cooling-maps { + map0 { + trip = <&cpu0_1_alert0>; + cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; - #qcom,smem-state-cells = <1>; + cpu2-3-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 4>; + + trips { + cpu2_3_alert0: trip-point0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu2_3_crit: cpu_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu2_3_alert0>; + cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; - hexagon_smsm: hexagon@1 { - reg = <1>; - interrupts = <0 26 IRQ_TYPE_EDGE_RISING>; + gpu-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; - interrupt-controller; - #interrupt-cells = <2>; + thermal-sensors = <&tsens 2>; + + trips { + gpu_alert0: trip-point0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + gpu_crit: gpu_crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; - wcnss_smsm: wcnss@6 { - reg = <6>; - interrupts = <0 144 IRQ_TYPE_EDGE_RISING>; + camera-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; - interrupt-controller; - #interrupt-cells = <2>; + thermal-sensors = <&tsens 1>; + + trips { + cam_alert0: trip-point0 { + temperature = <75000>; + hysteresis = <2000>; + type = "hot"; + }; + }; }; + + modem-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 0>; + + trips { + modem_alert0: trip-point0 { + temperature = <85000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8992.dtsi b/arch/arm64/boot/dts/qcom/msm8992.dtsi index 188fff2095f1..8626b3a50eda 100644 --- a/arch/arm64/boot/dts/qcom/msm8992.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8992.dtsi @@ -335,7 +335,7 @@ blsp2_uart2: serial@f995e000 { compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; reg = <0xf995e000 0x1000>; - interrupt = <GIC_SPI 146 IRQ_TYPE_LEVEL_LOW>; + interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_LOW>; clock-names = "core", "iface"; clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>; diff --git a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi index 4032b7478f04..791f254ac3f8 100644 --- a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi @@ -221,7 +221,12 @@ }; &sdhc1 { - status = "okay"; + /* There is an issue with the eMMC causing permanent + * damage to the card if a quirk isn't addressed. + * Until it's fixed, disable the MMC so as not to brick + * devices. + */ + status = "disabled"; /* Downstream pushes 2.95V to the sdhci device, * but upstream driver REALLY wants to make vmmc 1.8v diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 9951286db775..fd6ae5464dea 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -1009,7 +1009,8 @@ "ispif", "vfe0", "vfe1"; - power-domains = <&mmcc VFE0_GDSC>; + power-domains = <&mmcc VFE0_GDSC>, + <&mmcc VFE1_GDSC>; clocks = <&mmcc CAMSS_TOP_AHB_CLK>, <&mmcc CAMSS_ISPIF_AHB_CLK>, <&mmcc CAMSS_CSI0PHYTIMER_CLK>, diff --git a/arch/arm64/boot/dts/qcom/pm660.dtsi b/arch/arm64/boot/dts/qcom/pm660.dtsi index ea0e9558d0f2..2e6a6f6c3b66 100644 --- a/arch/arm64/boot/dts/qcom/pm660.dtsi +++ b/arch/arm64/boot/dts/qcom/pm660.dtsi @@ -44,7 +44,7 @@ gpio-ranges = <&pm660_gpios 0 0 13>; #gpio-cells = <2>; interrupt-controller; - interrupt-cells =<2>; + #interrupt-cells = <2>; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi index 0bcdf0471107..f931cb0de231 100644 --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi @@ -1,24 +1,17 @@ // SPDX-License-Identifier: GPL-2.0 #include <dt-bindings/iio/qcom,spmi-vadc.h> -#include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/spmi/spmi.h> &spmi_bus { - pm8916_0: pm8916@0 { + pm8916_0: pmic@0 { compatible = "qcom,pm8916", "qcom,spmi-pmic"; reg = <0x0 SPMI_USID>; #address-cells = <1>; #size-cells = <0>; - rtc@6000 { - compatible = "qcom,pm8941-rtc"; - reg = <0x6000>; - reg-names = "rtc", "alarm"; - interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; - }; - pon@800 { compatible = "qcom,pm8916-pon"; reg = <0x800>; @@ -33,6 +26,14 @@ linux,code = <KEY_POWER>; }; + pm8916_resin: resin { + compatible = "qcom,pm8941-resin"; + interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; + debounce = <15625>; + bias-pull-up; + status = "disabled"; + }; + watchdog { compatible = "qcom,pm8916-wdt"; interrupts = <0x0 0x8 6 IRQ_TYPE_EDGE_RISING>; @@ -40,28 +41,6 @@ }; }; - pm8916_gpios: gpios@c000 { - compatible = "qcom,pm8916-gpio"; - reg = <0xc000>; - gpio-controller; - #gpio-cells = <2>; - interrupts = <0 0xc0 0 IRQ_TYPE_NONE>, - <0 0xc1 0 IRQ_TYPE_NONE>, - <0 0xc2 0 IRQ_TYPE_NONE>, - <0 0xc3 0 IRQ_TYPE_NONE>; - }; - - pm8916_mpps: mpps@a000 { - compatible = "qcom,pm8916-mpp"; - reg = <0xa000>; - gpio-controller; - #gpio-cells = <2>; - interrupts = <0 0xa0 0 IRQ_TYPE_NONE>, - <0 0xa1 0 IRQ_TYPE_NONE>, - <0 0xa2 0 IRQ_TYPE_NONE>, - <0 0xa3 0 IRQ_TYPE_NONE>; - }; - pm8916_temp: temp-alarm@2400 { compatible = "qcom,spmi-temp-alarm"; reg = <0x2400>; @@ -71,7 +50,7 @@ #thermal-sensor-cells = <0>; }; - pm8916_vadc: vadc@3100 { + pm8916_vadc: adc@3100 { compatible = "qcom,spmi-vadc"; reg = <0x3100>; interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; @@ -79,33 +58,62 @@ #size-cells = <0>; #io-channel-cells = <1>; - usb_in { + adc-chan@0 { reg = <VADC_USBIN>; qcom,pre-scaling = <1 10>; }; - vph_pwr { + adc-chan@7 { reg = <VADC_VSYS>; qcom,pre-scaling = <1 3>; }; - die_temp { + adc-chan@8 { reg = <VADC_DIE_TEMP>; }; - ref_625mv { + adc-chan@9 { reg = <VADC_REF_625MV>; }; - ref_1250v { + adc-chan@a { reg = <VADC_REF_1250MV>; }; - ref_gnd { + adc-chan@e { reg = <VADC_GND_REF>; }; - ref_vdd { + adc-chan@f { reg = <VADC_VDD_VADC>; }; }; + + rtc@6000 { + compatible = "qcom,pm8941-rtc"; + reg = <0x6000>; + reg-names = "rtc", "alarm"; + interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; + }; + + pm8916_mpps: mpps@a000 { + compatible = "qcom,pm8916-mpp"; + reg = <0xa000>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <0 0xa0 0 IRQ_TYPE_NONE>, + <0 0xa1 0 IRQ_TYPE_NONE>, + <0 0xa2 0 IRQ_TYPE_NONE>, + <0 0xa3 0 IRQ_TYPE_NONE>; + }; + + pm8916_gpios: gpios@c000 { + compatible = "qcom,pm8916-gpio"; + reg = <0xc000>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <0 0xc0 0 IRQ_TYPE_NONE>, + <0 0xc1 0 IRQ_TYPE_NONE>, + <0 0xc2 0 IRQ_TYPE_NONE>, + <0 0xc3 0 IRQ_TYPE_NONE>; + }; }; - pm8916_1: pm8916@1 { + pm8916_1: pmic@1 { compatible = "qcom,pm8916", "qcom,spmi-pmic"; reg = <0x1 SPMI_USID>; #address-cells = <1>; @@ -117,9 +125,9 @@ status = "disabled"; }; - wcd_codec: codec@f000 { + wcd_codec: audio-codec@f000 { compatible = "qcom,pm8916-wcd-analog-codec"; - reg = <0xf000 0x200>; + reg = <0xf000>; reg-names = "pmic-codec-core"; clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>; clock-names = "mclk"; diff --git a/arch/arm64/boot/dts/qcom/qcs404-evb-4000.dts b/arch/arm64/boot/dts/qcom/qcs404-evb-4000.dts index 479ad3ac6c28..08d5d51221cf 100644 --- a/arch/arm64/boot/dts/qcom/qcs404-evb-4000.dts +++ b/arch/arm64/boot/dts/qcom/qcs404-evb-4000.dts @@ -13,7 +13,7 @@ }; ðernet { - status = "ok"; + status = "okay"; snps,reset-gpio = <&tlmm 60 GPIO_ACTIVE_LOW>; snps,reset-active-low; diff --git a/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi b/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi index 6422cf9d5855..a80c578484ba 100644 --- a/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi @@ -97,7 +97,7 @@ }; &pcie { - status = "ok"; + status = "okay"; perst-gpio = <&tlmm 43 GPIO_ACTIVE_LOW>; @@ -106,22 +106,22 @@ }; &pcie_phy { - status = "ok"; + status = "okay"; vdda-vp-supply = <&vreg_l3_1p05>; vdda-vph-supply = <&vreg_l5_1p8>; }; &remoteproc_adsp { - status = "ok"; + status = "okay"; }; &remoteproc_cdsp { - status = "ok"; + status = "okay"; }; &remoteproc_wcss { - status = "ok"; + status = "okay"; }; &rpm_requests { @@ -215,7 +215,7 @@ }; &sdcc1 { - status = "ok"; + status = "okay"; supports-cqe; mmc-ddr-1_8v; diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts new file mode 100644 index 000000000000..1528a865f1f8 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts @@ -0,0 +1,686 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2020, Linaro Ltd. + */ + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> +#include "sm8250.dtsi" +#include "pm8150.dtsi" +#include "pm8150b.dtsi" +#include "pm8150l.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. Robotics RB5"; + compatible = "qcom,qrb5165-rb5", "qcom,sm8250"; + + aliases { + serial0 = &uart12; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + dc12v: dc12v-regulator { + compatible = "regulator-fixed"; + regulator-name = "DC12V"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-always-on; + }; + + leds { + compatible = "gpio-leds"; + + user4 { + label = "green:user4"; + gpios = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "panic-indicator"; + default-state = "off"; + }; + + wlan { + label = "yellow:wlan"; + gpios = <&pm8150_gpios 9 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "phy0tx"; + default-state = "off"; + }; + + bt { + label = "blue:bt"; + gpios = <&pm8150_gpios 7 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "bluetooth-power"; + default-state = "off"; + }; + + }; + + vbat: vbat-regulator { + compatible = "regulator-fixed"; + regulator-name = "VBAT"; + vin-supply = <&vreg_l11c_3p3>; + regulator-min-microvolt = <4200000>; + regulator-max-microvolt = <4200000>; + regulator-always-on; + }; + + vbat_som: vbat-som-regulator { + compatible = "regulator-fixed"; + regulator-name = "VBAT_SOM"; + vin-supply = <&dc12v>; + regulator-min-microvolt = <4200000>; + regulator-max-microvolt = <4200000>; + regulator-always-on; + }; + + vdc_3v3: vdc-3v3-regulator { + compatible = "regulator-fixed"; + regulator-name = "VDC_3V3"; + vin-supply = <&dc12v>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdc_5v: vdc-5v-regulator { + compatible = "regulator-fixed"; + regulator-name = "VDC_5V"; + + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + vin-supply = <&vreg_l11c_3p3>; + }; + + vph_pwr: vph-pwr-regulator { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + regulator-always-on; + }; + + vreg_s4a_1p8: vreg-s4a-1p8 { + compatible = "regulator-fixed"; + regulator-name = "vreg_s4a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; +}; + +&apps_rsc { + pm8009-rpmh-regulators { + compatible = "qcom,pm8009-rpmh-regulators"; + qcom,pmic-id = "f"; + + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-l2-supply = <&vreg_s8c_1p3>; + vdd-l5-l6-supply = <&vreg_bob>; + vdd-l7-supply = <&vreg_s4a_1p8>; + + vreg_l1f_1p1: ldo1 { + regulator-name = "vreg_l1f_1p1"; + regulator-min-microvolt = <1104000>; + regulator-max-microvolt = <1104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f_1p2: ldo2 { + regulator-name = "vreg_l2f_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6f_2p8: ldo6 { + regulator-name = "vreg_l6f_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + 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>; + }; + }; + + 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-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_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 = <1800000>; + 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_2p7: ldo16 { + regulator-name = "vreg_l16a_2p7"; + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l17a_3p0: ldo17 { + regulator-name = "vreg_l17a_3p0"; + regulator-min-microvolt = <2856000>; + 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 = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s5a_1p9: smps5 { + regulator-name = "vreg_s5a_1p9"; + regulator-min-microvolt = <1904000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s6a_0p95: smps6 { + regulator-name = "vreg_s6a_0p95"; + regulator-min-microvolt = <920000>; + regulator-max-microvolt = <1128000>; + 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 = <4000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + }; + + 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 = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3c_0p8: ldo3 { + regulator-name = "vreg_l3c_0p8"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4c_1p7: ldo4 { + regulator-name = "vreg_l4c_1p7"; + regulator-min-microvolt = <1704000>; + regulator-max-microvolt = <2928000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5c_1p8: ldo5 { + regulator-name = "vreg_l5c_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2928000>; + 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 = <3000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l11c_3p3: ldo11 { + regulator-name = "vreg_l11c_3p3"; + regulator-min-microvolt = <3296000>; + regulator-max-microvolt = <3296000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + }; + + vreg_s8c_1p3: smps8 { + regulator-name = "vreg_s8c_1p3"; + regulator-min-microvolt = <1352000>; + regulator-max-microvolt = <1352000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +/* LS-I2C0 */ +&i2c4 { + status = "okay"; +}; + +&i2c5 { + status = "okay"; +}; + +/* LS-I2C1 */ +&i2c15 { + status = "okay"; +}; + +&pm8150_gpios { + gpio-reserved-ranges = <1 1>, <3 2>, <7 1>; + gpio-line-names = + "NC", + "OPTION2", + "PM_GPIO-F", + "PM_SLP_CLK_IN", + "OPTION1", + "VOL_UP_N", + "PM8250_GPIO7", /* Blue LED */ + "SP_ARI_PWR_ALARM", + "GPIO_9_P", /* Yellow LED */ + "GPIO_10_P"; /* Green LED */ +}; + +&pm8150b_gpios { + gpio-line-names = + "NC", + "NC", + "NC", + "NC", + "HAP_BOOST_EN", /* SOM */ + "SMB_STAT", /* SOM */ + "NC", + "NC", + "SDM_FORCE_USB_BOOT", + "NC", + "NC", + "NC"; +}; + +&pm8150l_gpios { + gpio-line-names = + "NC", + "PM3003A_EN", + "NC", + "NC", + "PM_GPIO5", /* HDMI RST_N */ + "PM_GPIO-A", /* PWM */ + "PM_GPIO7", + "NC", + "NC", + "PM_GPIO-B", + "NC", + "PM3003A_MODE"; +}; + +&qupv3_id_0 { + status = "okay"; +}; + +&qupv3_id_1 { + status = "okay"; +}; + +&qupv3_id_2 { + status = "okay"; +}; + +/* CAN */ +&spi0 { + status = "okay"; +}; + +&tlmm { + gpio-reserved-ranges = <40 4>; + gpio-line-names = + "GPIO-MM", + "GPIO-NN", + "GPIO-OO", + "GPIO-PP", + "GPIO-A", + "GPIO-C", + "GPIO-E", + "GPIO-D", + "I2C0-SDA", + "I2C0-SCL", + "GPIO-TT", /* GPIO_10 */ + "NC", + "GPIO_12_I2C_SDA", + "GPIO_13_I2C_SCL", + "GPIO-X", + "GPIO_15_RGMII_INT", + "HST_BT_UART_CTS", + "HST_BT_UART_RFR", + "HST_BT_UART_TX", + "HST_BT_UART_RX", + "HST_WLAN_EN", /* GPIO_20 */ + "HST_BT_EN", + "GPIO-AAA", + "GPIO-BBB", + "GPIO-CCC", + "GPIO-Z", + "GPIO-DDD", + "GPIO-BB", + "GPIO_28_CAN_SPI_MISO", + "GPIO_29_CAN_SPI_MOSI", + "GPIO_30_CAN_SPI_CLK", /* GPIO_30 */ + "GPIO_31_CAN_SPI_CS", + "GPIO-UU", + "NC", + "UART1_TXD_SOM", + "UART1_RXD_SOM", + "UART0_CTS", + "UART0_RTS", + "UART0_TXD", + "UART0_RXD", + "SPI1_MISO", /* GPIO_40 */ + "SPI1_MOSI", + "SPI1_CLK", + "SPI1_CS", + "I2C1_SDA", + "I2C1_SCL", + "GPIO-F", + "GPIO-JJ", + "Board_ID1", + "Board_ID2", + "NC", /* GPIO_50 */ + "NC", + "SPI0_MISO", + "SPI0_MOSI", + "SPI0_SCLK", + "SPI0_CS", + "GPIO-QQ", + "GPIO-RR", + "USB2LAN_RESET", + "USB2LAN_EXTWAKE", + "NC", /* GPIO_60 */ + "NC", + "NC", + "LT9611_INT", + "GPIO-AA", + "USB_CC_DIR", + "GPIO-G", + "GPIO-LL", + "USB_DP_HPD_1P8", + "NC", + "NC", /* GPIO_70 */ + "SD_CMD", + "SD_DAT3", + "SD_SCLK", + "SD_DAT2", + "SD_DAT1", + "SD_DAT0", /* BOOT_CFG3 */ + "SD_UFS_CARD_DET_N", + "GPIO-II", + "PCIE0_RST_N", + "PCIE0_CLK_REQ_N", /* GPIO_80 */ + "PCIE0_WAKE_N", + "GPIO-CC", + "GPIO-DD", + "GPIO-EE", + "GPIO-FF", + "GPIO-GG", + "GPIO-HH", + "GPIO-VV", + "GPIO-WW", + "NC", /* GPIO_90 */ + "NC", + "GPIO-K", + "GPIO-I", + "CSI0_MCLK", + "CSI1_MCLK", + "CSI2_MCLK", + "CSI3_MCLK", + "GPIO-AA", /* CSI4_MCLK */ + "GPIO-BB", /* CSI5_MCLK */ + "GPIO-KK", /* GPIO_100 */ + "CCI_I2C_SDA0", + "CCI_I2C_SCL0", + "CCI_I2C_SDA1", + "CCI_I2C_SCL1", + "CCI_I2C_SDA2", + "CCI_I2C_SCL2", + "CCI_I2C_SDA3", + "CCI_I2C_SCL3", + "GPIO-L", + "NC", /* GPIO_110 */ + "NC", + "ACCEL_INT", + "GYRO_INT", + "GPIO-J", + "GPIO-YY", + "GPIO-H", + "GPIO-ZZ", + "NC", + "NC", + "NC", /* GPIO_120 */ + "NC", + "MAG_INT", + "MAG_DRDY_INT", + "HST_SW_CTRL", + "GPIO-M", + "GPIO-N", + "GPIO-O", + "GPIO-P", + "PS_INT", + "WSA1_EN", /* GPIO_130 */ + "USB_HUB_RESET", + "SDM_FORCE_USB_BOOT", + "I2S1_CLK_HDMI", + "I2S1_DATA0_HDMI", + "I2S1_WS_HDMI", + "GPIO-B", + "GPIO_137", /* To LT9611_I2S_MCLK_3V3 */ + "PCM_CLK", + "PCM_DI", + "PCM_DO", /* GPIO_140 */ + "PCM_FS", + "HST_SLIM_CLK", + "HST_SLIM_DATA", + "GPIO-U", + "GPIO-Y", + "GPIO-R", + "GPIO-Q", + "GPIO-S", + "GPIO-T", + "GPIO-V", /* GPIO_150 */ + "GPIO-W", + "DMIC_CLK1", + "DMIC_DATA1", + "DMIC_CLK2", + "DMIC_DATA2", + "WSA_SWR_CLK", + "WSA_SWR_DATA", + "DMIC_CLK3", + "DMIC_DATA3", + "I2C4_SDA", /* GPIO_160 */ + "I2C4_SCL", + "SPI3_CS1", + "SPI3_CS2", + "SPI2_MISO_LS3", + "SPI2_MOSI_LS3", + "SPI2_CLK_LS3", + "SPI2_ACCEL_CS_LS3", + "SPI2_CS1", + "NC", + "GPIO-SS", /* GPIO_170 */ + "GPIO-XX", + "SPI3_MISO", + "SPI3_MOSI", + "SPI3_CLK", + "SPI3_CS", + "HST_BLE_SNS_UART_TX", + "HST_BLE_SNS_UART_RX", + "HST_WLAN_UART_TX", + "HST_WLAN_UART_RX"; +}; + +&uart12 { + status = "okay"; +}; + +&ufs_mem_hc { + status = "okay"; + + vcc-supply = <&vreg_l17a_3p0>; + 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>; +}; diff --git a/arch/arm64/boot/dts/qcom/sc7180-idp.dts b/arch/arm64/boot/dts/qcom/sc7180-idp.dts index d8b550723b32..e77a7926034a 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-idp.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-idp.dts @@ -346,6 +346,13 @@ &uart3 { status = "okay"; + /delete-property/interrupts; + interrupts-extended = <&intc GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>, + <&tlmm 41 IRQ_TYPE_EDGE_FALLING>; + + pinctrl-names = "default", "sleep"; + pinctrl-1 = <&qup_uart3_sleep>; + bluetooth: wcn3990-bt { compatible = "qcom,wcn3990-bt"; vddio-supply = <&vreg_l10a_1p8>; @@ -353,7 +360,6 @@ vddrf-supply = <&vreg_l2c_1p3>; vddch0-supply = <&vreg_l10c_3p3>; max-speed = <3200000>; - clocks = <&rpmhcc RPMH_RF_CLK2>; }; }; @@ -474,32 +480,30 @@ &qup_uart3_default { pinconf-cts { /* - * Configure a pull-down on 38 (CTS) to match the pull of + * Configure a pull-down on CTS to match the pull of * the Bluetooth module. */ pins = "gpio38"; bias-pull-down; - output-high; }; pinconf-rts { - /* We'll drive 39 (RTS), so no pull */ + /* We'll drive RTS, so no pull */ pins = "gpio39"; drive-strength = <2>; bias-disable; }; pinconf-tx { - /* We'll drive 40 (TX), so no pull */ + /* We'll drive TX, so no pull */ pins = "gpio40"; drive-strength = <2>; bias-disable; - output-high; }; pinconf-rx { /* - * Configure a pull-up on 41 (RX). This is needed to avoid + * Configure a pull-up on RX. This is needed to avoid * garbage data when the TX pin of the Bluetooth module is * in tri-state (module powered off or not driving the * signal yet). @@ -547,3 +551,51 @@ }; }; +&tlmm { + qup_uart3_sleep: qup-uart3-sleep { + pinmux { + pins = "gpio38", "gpio39", + "gpio40", "gpio41"; + function = "gpio"; + }; + + pinconf-cts { + /* + * Configure a pull-down on CTS to match the pull of + * the Bluetooth module. + */ + pins = "gpio38"; + bias-pull-down; + }; + + pinconf-rts { + /* + * Configure pull-down on RTS. As RTS is active low + * signal, pull it low to indicate the BT SoC that it + * can wakeup the system anytime from suspend state by + * pulling RX low (by sending wakeup bytes). + */ + pins = "gpio39"; + bias-pull-down; + }; + + pinconf-tx { + /* + * Configure pull-up on TX when it isn't actively driven + * to prevent BT SoC from receiving garbage during sleep. + */ + pins = "gpio40"; + bias-pull-up; + }; + + pinconf-rx { + /* + * Configure a pull-up on RX. This is needed to avoid + * garbage data when the TX pin of the Bluetooth module + * is floating which may cause spurious wakeups. + */ + pins = "gpio41"; + bias-pull-up; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r0.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r0.dts new file mode 100644 index 000000000000..ae4c23a4fe65 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r0.dts @@ -0,0 +1,24 @@ +// 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 (rev0)"; + compatible = "google,lazor-rev0", "qcom,sc7180"; +}; + +&sn65dsi86_out { + /* + * Lane 0 was incorrectly mapped on the cable, but we've now decided + * that the cable is canon and in -rev1+ we'll make a board change + * that means we no longer need the swizzle. + */ + lane-polarities = <1 0>; +}; 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 new file mode 100644 index 000000000000..c3f426c3c30a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-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-r1.dts" + +/ { + model = "Google Lazor (rev1+) with KB Backlight"; + compatible = "google,lazor-sku2", "qcom,sc7180"; +}; + +&keyboard_backlight { + status = "okay"; +}; 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 new file mode 100644 index 000000000000..73e59cf7752a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-lte.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Google Lazor board device tree source + * + * Copyright 2020 Google LLC. + */ + +#include "sc7180-trogdor-lazor-r1.dts" +#include "sc7180-trogdor-lte-sku.dtsi" + +/ { + model = "Google Lazor (rev1+) with LTE"; + compatible = "google,lazor-sku0", "qcom,sc7180"; +}; + +&keyboard_backlight { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts new file mode 100644 index 000000000000..3151ae31c1cc --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.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 (rev1+)"; + 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 new file mode 100644 index 000000000000..180ef9e04306 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Google Lazor board device tree source + * + * Copyright 2020 Google LLC. + */ + +#include "sc7180.dtsi" + +ap_ec_spi: &spi6 {}; +ap_h1_spi: &spi0 {}; + +#include "sc7180-trogdor.dtsi" + +/ { + panel: panel { + compatible = "boe,nv133fhm-n62"; + power-supply = <&pp3300_dx_edp>; + backlight = <&backlight>; + hpd-gpios = <&sn65dsi86_bridge 2 GPIO_ACTIVE_HIGH>; + + ports { + port { + panel_in_edp: endpoint { + remote-endpoint = <&sn65dsi86_out>; + }; + }; + }; + }; +}; + +&ap_sar_sensor { + status = "okay"; +}; + +ap_ts_pen_1v8: &i2c4 { + status = "okay"; + clock-frequency = <400000>; + + ap_ts: touchscreen@10 { + compatible = "hid-over-i2c"; + reg = <0x10>; + pinctrl-names = "default"; + pinctrl-0 = <&ts_int_l>, <&ts_reset_l>; + + interrupt-parent = <&tlmm>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; + + post-power-on-delay-ms = <20>; + hid-descr-addr = <0x0001>; + + vdd-supply = <&pp3300_ts>; + }; +}; + +/* PINCTRL - modifications to sc7180-trogdor.dtsi */ + +&ts_reset_l { + pinconf { + /* This pin is not connected on -rev0, pull up to park. */ + /delete-property/bias-disable; + bias-pull-up; + }; +}; + +/* PINCTRL - board-specific pinctrl */ + +&tlmm { + gpio-line-names = "ESIM_MISO", + "ESIM_MOSI", + "ESIM_CLK", + "ESIM_CS_L", + "", + "", + "AP_TP_I2C_SDA", + "AP_TP_I2C_SCL", + "TS_RESET_L", + "TS_INT_L", + "", + "EDP_BRIJ_IRQ", + "AP_EDP_BKLTEN", + "AP_RAM_ID2", + "", + "EDP_BRIJ_I2C_SDA", + "EDP_BRIJ_I2C_SCL", + "HUB_RST_L", + "", + "AP_RAM_ID1", + "AP_SKU_ID2", + "", + "", + "AMP_EN", + "P_SENSOR_INT_L", + "AP_SAR_SENSOR_SDA", + "AP_SAR_SENSOR_SCL", + "", + "HP_IRQ", + "AP_RAM_ID0", + "EN_PP3300_DX_EDP", + "AP_BRD_ID2", + "BRIJ_SUSPEND", + "AP_BRD_ID0", + "AP_H1_SPI_MISO", + "AP_H1_SPI_MOSI", + "AP_H1_SPI_CLK", + "AP_H1_SPI_CS_L", + "", + "", + "", + "", + "H1_AP_INT_ODL", + "", + "UART_AP_TX_DBG_RX", + "UART_DBG_TX_AP_RX", + "HP_I2C_SDA", + "HP_I2C_SCL", + "FORCED_USB_BOOT", + "", + "", + "AMP_DIN", + "", + "HP_BCLK", + "HP_LRCLK", + "HP_DOUT", + "HP_DIN", + "HP_MCLK", + "TRACKPAD_INT_1V8_ODL", + "AP_EC_SPI_MISO", + "AP_EC_SPI_MOSI", + "AP_EC_SPI_CLK", + "AP_EC_SPI_CS_L", + "AP_SPI_CLK", + "AP_SPI_MOSI", + "AP_SPI_MISO", + /* + * AP_FLASH_WP_L is crossystem ABI. Schematics + * call it BIOS_FLASH_WP_L. + */ + "AP_FLASH_WP_L", + "DBG_SPI_HOLD_L", + "AP_SPI_CS0_L", + "", + "", + "", + "", + "", + "", + "UIM2_DATA", + "UIM2_CLK", + "UIM2_RST", + "UIM2_PRESENT", + "UIM1_DATA", + "UIM1_CLK", + "UIM1_RST", + "", + "EN_PP3300_CODEC", + "EN_PP3300_HUB", + "", + "", + "", + "", + "", + "AP_SKU_ID1", + "AP_RST_REQ", + "", + "AP_BRD_ID1", + "AP_EC_INT_L", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "EDP_BRIJ_EN", + "AP_SKU_ID0", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "AP_TS_PEN_I2C_SDA", + "AP_TS_PEN_I2C_SCL", + "DP_HOT_PLUG_DET", + "EC_IN_RW_ODL"; +}; diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lte-sku.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lte-sku.dtsi new file mode 100644 index 000000000000..44956e3165a1 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lte-sku.dtsi @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Google Trogdor dts fragment for LTE SKUs + * + * Copyright 2020 Google LLC. + */ + +&ap_sar_sensor { + label = "proximity-wifi-lte"; +}; + +&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-lte.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1-lte.dts new file mode 100644 index 000000000000..1123c02bd539 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1-lte.dts @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Google Trogdor board device tree source + * + * Copyright 2020 Google LLC. + */ + +#include "sc7180-trogdor-r1.dts" +#include "sc7180-trogdor-lte-sku.dtsi" + +/ { + model = "Google Trogdor (rev1+) with LTE"; + compatible = "google,trogdor-sku0", "qcom,sc7180"; +}; diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts new file mode 100644 index 000000000000..0a281c24841c --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Google Trogdor board device tree source + * + * Copyright 2020 Google LLC. + */ + +/dts-v1/; + +#include "sc7180.dtsi" + +ap_ec_spi: &spi6 {}; +ap_h1_spi: &spi0 {}; + +#include "sc7180-trogdor.dtsi" + +/ { + model = "Google Trogdor (rev1+)"; + compatible = "google,trogdor", "qcom,sc7180"; + + panel: panel { + compatible = "auo,b116xa01"; + power-supply = <&pp3300_dx_edp>; + backlight = <&backlight>; + hpd-gpios = <&sn65dsi86_bridge 2 GPIO_ACTIVE_HIGH>; + + ports { + port { + panel_in_edp: endpoint { + remote-endpoint = <&sn65dsi86_out>; + }; + }; + }; + }; +}; + +&ap_sar_sensor_i2c { + /* Not hooked up */ + status = "disabled"; +}; + +ap_ts_pen_1v8: &i2c4 { + status = "okay"; + clock-frequency = <400000>; + + ap_ts: touchscreen@10 { + compatible = "elan,ekth3500"; + reg = <0x10>; + pinctrl-names = "default"; + pinctrl-0 = <&ts_int_l>, <&ts_reset_l>; + + interrupt-parent = <&tlmm>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; + + vcc33-supply = <&pp3300_ts>; + + reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>; + }; +}; + +&sdhc_2 { + status = "okay"; +}; + +/* PINCTRL - board-specific pinctrl */ + +&tlmm { + gpio-line-names = "ESIM_MISO", + "ESIM_MOSI", + "ESIM_CLK", + "ESIM_CS_L", + "FP_TO_AP_IRQ_L", + "FP_RST_L", + "AP_TP_I2C_SDA", + "AP_TP_I2C_SCL", + "TS_RESET_L", + "TS_INT_L", + "FPMCU_BOOT0", + "EDP_BRIJ_IRQ", + "AP_EDP_BKLTEN", + "", + "", + "EDP_BRIJ_I2C_SDA", + "EDP_BRIJ_I2C_SCL", + "HUB_RST_L", + "PEN_RST_ODL", + "AP_RAM_ID1", + "AP_RAM_ID2", + "PEN_IRQ_L", + "FPMCU_SEL", + "AMP_EN", + "P_SENSOR_INT_L", + "AP_SAR_SENSOR_SDA", + "AP_SAR_SENSOR_SCL", + "", + "HP_IRQ", + "AP_RAM_ID0", + "EN_PP3300_DX_EDP", + "AP_BRD_ID2", + "BRIJ_SUSPEND", + "AP_BRD_ID0", + "AP_H1_SPI_MISO", + "AP_H1_SPI_MOSI", + "AP_H1_SPI_CLK", + "AP_H1_SPI_CS_L", + "", + "", + "", + "", + "H1_AP_INT_ODL", + "", + "UART_AP_TX_DBG_RX", + "UART_DBG_TX_AP_RX", + "HP_I2C_SDA", + "HP_I2C_SCL", + "FORCED_USB_BOOT", + "", + "", + "AMP_DIN", + "PEN_PDCT_L", + "HP_BCLK", + "HP_LRCLK", + "HP_DOUT", + "HP_DIN", + "HP_MCLK", + "TRACKPAD_INT_1V8_ODL", + "AP_EC_SPI_MISO", + "AP_EC_SPI_MOSI", + "AP_EC_SPI_CLK", + "AP_EC_SPI_CS_L", + "AP_SPI_CLK", + "AP_SPI_MOSI", + "AP_SPI_MISO", + /* + * AP_FLASH_WP_L is crossystem ABI. Schematics + * call it BIOS_FLASH_WP_L. + */ + "AP_FLASH_WP_L", + "DBG_SPI_HOLD_L", + "AP_SPI_CS0_L", + "SD_CD_ODL", + "", + "", + "", + "", + "", + "UIM2_DATA", + "UIM2_CLK", + "UIM2_RST", + "UIM2_PRESENT", + "UIM1_DATA", + "UIM1_CLK", + "UIM1_RST", + "", + "EN_PP3300_CODEC", + "EN_PP3300_HUB", + "", + "AP_SPI_FP_MISO", + "AP_SPI_FP_MOSI", + "AP_SPI_FP_CLK", + "AP_SPI_FP_CS_L", + "AP_SKU_ID1", + "AP_RST_REQ", + "", + "AP_BRD_ID1", + "AP_EC_INT_L", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "EDP_BRIJ_EN", + "AP_SKU_ID0", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "AP_TS_PEN_I2C_SDA", + "AP_TS_PEN_I2C_SCL", + "DP_HOT_PLUG_DET", + "EC_IN_RW_ODL"; +}; diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi new file mode 100644 index 000000000000..bf875589d364 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi @@ -0,0 +1,1402 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Google Trogdor device tree source (common between revisions) + * + * Copyright 2019 Google LLC. + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> + +/* PMICs depend on spmi_bus label and so must come after SoC */ +#include "pm6150.dtsi" +#include "pm6150l.dtsi" + +/* + * Reserved memory changes + * + * Delete all unused memory nodes and define the peripheral memory regions + * required by the board dts. + */ + +/delete-node/ &hyp_mem; +/delete-node/ &xbl_mem; +/delete-node/ &aop_mem; +/delete-node/ &sec_apps_mem; +/delete-node/ &tz_mem; + +/* Increase the size from 2MB to 8MB */ +&rmtfs_mem { + reg = <0x0 0x84400000 0x0 0x800000>; +}; + +/ { + reserved-memory { + atf_mem: memory@80b00000 { + reg = <0x0 0x80b00000 0x0 0x100000>; + no-map; + }; + + mpss_mem: memory@86000000 { + reg = <0x0 0x86000000 0x0 0x8c00000>; + no-map; + }; + + camera_mem: memory@8ec00000 { + reg = <0x0 0x8ec00000 0x0 0x500000>; + no-map; + }; + + venus_mem: memory@8f600000 { + reg = <0 0x8f600000 0 0x500000>; + no-map; + }; + + wlan_mem: memory@94100000 { + reg = <0x0 0x94100000 0x0 0x200000>; + no-map; + }; + + mba_mem: memory@94400000 { + reg = <0x0 0x94400000 0x0 0x200000>; + no-map; + }; + }; + + aliases { + bluetooth0 = &bluetooth; + hsuart0 = &uart3; + serial0 = &uart8; + wifi0 = &wifi; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + /* FIXED REGULATORS - parents above children */ + + /* This is the top level supply and variable voltage */ + ppvar_sys: ppvar-sys-regulator { + compatible = "regulator-fixed"; + regulator-name = "ppvar_sys"; + regulator-always-on; + regulator-boot-on; + }; + + /* This divides ppvar_sys by 2, so voltage is variable */ + src_vph_pwr: src-vph-pwr-regulator { + compatible = "regulator-fixed"; + regulator-name = "src_vph_pwr"; + + /* EC turns on with switchcap_on; always on for AP */ + regulator-always-on; + regulator-boot-on; + + vin-supply = <&ppvar_sys>; + }; + + pp5000_a: pp5000-a-regulator { + compatible = "regulator-fixed"; + regulator-name = "pp5000_a"; + + /* EC turns on with en_pp5000_a; always on for AP */ + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + + vin-supply = <&ppvar_sys>; + }; + + pp3300_a: pp3300-a-regulator { + compatible = "regulator-fixed"; + regulator-name = "pp3300_a"; + + /* EC turns on with en_pp3300_a; always on for AP */ + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + /* + * Actually should be pp3300 but that's practically an alias for + * pp3300_a so we use pp3300's vin-supply here to avoid one more + * node. + */ + vin-supply = <&ppvar_sys>; + }; + + pp3300_audio: + pp3300_codec: pp3300-codec-regulator { + compatible = "regulator-fixed"; + regulator-name = "pp3300_codec"; + + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 83 GPIO_ACTIVE_HIGH>; + enable-active-high; + pinctrl-names = "default"; + pinctrl-0 = <&en_pp3300_codec>; + + vin-supply = <&pp3300_a>; + }; + + pp3300_dx_edp: + pp3300_ts: pp3300-dx-edp-regulator { + compatible = "regulator-fixed"; + regulator-name = "pp3300_dx_edp"; + + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 30 GPIO_ACTIVE_HIGH>; + enable-active-high; + pinctrl-names = "default"; + pinctrl-0 = <&en_pp3300_dx_edp>; + + vin-supply = <&pp3300_a>; + }; + + pp3300_fp_tp: pp3300-fp-tp-regulator { + compatible = "regulator-fixed"; + regulator-name = "pp3300_fp_tp"; + + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + /* AP turns on with PP1800_VIO_OUT; always on for AP */ + regulator-always-on; + regulator-boot-on; + + vin-supply = <&pp3300_a>; + }; + + /* BOARD-SPECIFIC TOP LEVEL NODES */ + + backlight: backlight { + compatible = "pwm-backlight"; + + pwms = <&cros_ec_pwm 1>; + enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>; + power-supply = <&ppvar_sys>; + pinctrl-names = "default"; + pinctrl-0 = <&ap_edp_bklten>; + }; + + gpio_keys: gpio-keys { + compatible = "gpio-keys"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pen_pdct_l>; + + pen-insert { + label = "Pen Insert"; + + /* Insert = low, eject = high */ + gpios = <&tlmm 52 GPIO_ACTIVE_LOW>; + linux,code = <SW_PEN_INSERTED>; + linux,input-type = <EV_SW>; + wakeup-source; + }; + }; + + max98357a: audio-codec-0 { + compatible = "maxim,max98357a"; + pinctrl-names = "default"; + pinctrl-0 = <&_en>; + sdmode-gpios = <&tlmm 23 GPIO_ACTIVE_HIGH>; + #sound-dai-cells = <0>; + }; + + pwmleds { + compatible = "pwm-leds"; + keyboard_backlight: keyboard-backlight { + status = "disabled"; + label = "cros_ec::kbd_backlight"; + pwms = <&cros_ec_pwm 0>; + max-brightness = <1023>; + }; + }; +}; + +&qfprom { + vcc-supply = <&pp1800_l11a>; +}; + +&qspi { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&qspi_clk>, <&qspi_cs0>, <&qspi_data01>; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + + /* TODO: Increase frequency after testing */ + spi-max-frequency = <25000000>; + spi-tx-bus-width = <2>; + spi-rx-bus-width = <2>; + }; +}; + +&apps_rsc { + pm6150-rpmh-regulators { + compatible = "qcom,pm6150-rpmh-regulators"; + qcom,pmic-id = "a"; + + vddpx_1: + vdd2: + pp1125_s1a: smps1 { + regulator-min-microvolt = <1128000>; + regulator-max-microvolt = <1128000>; + }; + + /* + * pp2040_s5a (smps5) and pp1056_s4a (smps4) are just + * inputs to other rails on AOP-managed PMICs on trogdor. + * The system is already configured to manage these rails + * automatically (enable when needed, adjust voltage for + * headroom) so we won't specify anything here. + * + * NOTE: though the rails have a voltage implied by their + * name, the automatic headroom calculation might not result + * in them being that voltage. ...and that's OK. + * Specifically the only point of these rails is to provide + * an input source for other rails and if we can satisify the + * needs of those other rails with a lower source voltage then + * we save power. + */ + + pp1200_l1a: ldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + pp1000_l2a: ldo2 { + regulator-min-microvolt = <944000>; + regulator-max-microvolt = <1056000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + pp1000_l3a: ldo3 { + regulator-min-microvolt = <968000>; + regulator-max-microvolt = <1064000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdd_qlink_lv: + vdd_qlink_lv_ck: + vdd_qusb_hs0_core: + vdd_ufs1_core: + vdda_mipi_csi0_0p9: + vdda_mipi_csi1_0p9: + vdda_mipi_csi2_0p9: + vdda_mipi_csi3_0p9: + vdda_mipi_dsi0_pll: + vdda_pll_cc_ebi01: + vdda_qrefs_0p9: + vdda_usb_ss_dp_core: + pp900_l4a: ldo4 { + regulator-min-microvolt = <824000>; + regulator-max-microvolt = <928000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + pp2700_l5a: ldo5 { + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <2704000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + ebi0_cal: + ebi1_cal: + vddio_ck_ebi0: + vddio_ck_ebi1: + vddio_ebi0: + vddq: + pp600_l6a: ldo6 { + regulator-min-microvolt = <568000>; + regulator-max-microvolt = <648000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdd_cx_wlan: + pp800_l9a: ldo9 { + regulator-min-microvolt = <488000>; + regulator-max-microvolt = <800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdd1: + vddpx_3: + vddpx_7: + vio_in: + pp1800_l10a: ldo10 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdd_qfprom: + vdda_apc1_cs_1p8: + vdda_qrefs_1p8: + vdda_qusb_hs0_1p8: + vddpx_11: + vreg_bb_clk: + pp1800_l11a: ldo11 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + mcp_vccq: + pp1800_l12a_r: ldo12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + pp1800_l13a: ldo13 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + pp1800_prox: + pp1800_l14a: ldo14 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + pp1800_alc5682: + pp1800_l15a: ldo15 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + pp2700_l16a: ldo16 { + regulator-min-microvolt = <2496000>; + regulator-max-microvolt = <3304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdda_qusb_hs0_3p1: + vdd_pdphy: + pp3100_l17a: ldo17 { + regulator-min-microvolt = <2920000>; + regulator-max-microvolt = <3232000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + pp1800_pen: + pp1800_l18a: ldo18 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + mcp_vcc: + pp2850_l19a: ldo19 { + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + pm6150l-rpmh-regulators { + compatible = "qcom,pm6150l-rpmh-regulators"; + qcom,pmic-id = "c"; + + pp1300_s8c: smps8 { + regulator-min-microvolt = <1120000>; + regulator-max-microvolt = <1408000>; + }; + + pp1800_l1c: ldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdd_wcss_adc_dac: + pp1300_l2c: ldo2 { + regulator-min-microvolt = <1168000>; + regulator-max-microvolt = <1304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + pp1200_brij: + vdd_ufs1_1p2: + vdda_csi0_1p25: + vdda_csi1_1p25: + vdda_csi2_1p25: + vdda_csi3_1p25: + vdda_hv_ebi0: + vdda_mipi_dsi0_1p2: + vdda_usb_ss_dp_1p2: + vddpx_10: + pp1200_l3c: ldo3 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + ld_pp1800_esim_l4c: + vddpx_5: + pp1800_l4c: ldo4 { + regulator-min-microvolt = <1648000>; + regulator-max-microvolt = <3304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vddpx_6: + pp1800_l5c: ldo5 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vddpx_2: + ppvar_l6c: ldo6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3304000>; + 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: + pp1800_edp_vpll: + pp1800_l8c: ldo8 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + pp2950_l9c: ldo9 { + regulator-min-microvolt = <2952000>; + regulator-max-microvolt = <2952000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + pp3300_l10c: ldo10 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3400000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + pp3300_l11c: ldo11 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3400000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + src_vreg_bob: bob { + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + }; + }; +}; + +&ap_ec_spi { + status = "okay"; + cros_ec: ec@0 { + compatible = "google,cros-ec-spi"; + reg = <0>; + interrupt-parent = <&tlmm>; + interrupts = <94 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&ap_ec_int_l>; + spi-max-frequency = <3000000>; + + cros_ec_pwm: ec-pwm { + compatible = "google,cros-ec-pwm"; + #pwm-cells = <1>; + }; + + i2c_tunnel: i2c-tunnel { + compatible = "google,cros-ec-i2c-tunnel"; + google,remote-bus = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + pdupdate { + compatible = "google,cros-ec-pd-update"; + }; + + typec { + compatible = "google,cros-ec-typec"; + #address-cells = <1>; + #size-cells = <0>; + + usb_c0: connector@0 { + compatible = "usb-c-connector"; + reg = <0>; + label = "left"; + power-role = "dual"; + data-role = "host"; + try-power-role = "source"; + }; + + usb_c1: connector@1 { + compatible = "usb-c-connector"; + reg = <1>; + label = "right"; + power-role = "dual"; + data-role = "host"; + try-power-role = "source"; + }; + }; + }; +}; + +&ap_h1_spi { + status = "okay"; + cr50: tpm@0 { + compatible = "google,cr50"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&h1_ap_int_odl>; + spi-max-frequency = <800000>; + interrupt-parent = <&tlmm>; + interrupts = <42 IRQ_TYPE_EDGE_RISING>; + }; +}; + +&dsi0 { + status = "okay"; + vdda-supply = <&vdda_mipi_dsi0_1p2>; + + ports { + port@1 { + endpoint { + remote-endpoint = <&sn65dsi86_in>; + data-lanes = <0 1 2 3>; + }; + }; + }; +}; + +&dsi_phy { + status = "okay"; + vdds-supply = <&vdda_mipi_dsi0_pll>; +}; + +edp_brij_i2c: &i2c2 { + status = "okay"; + clock-frequency = <400000>; + + sn65dsi86_bridge: bridge@2d { + compatible = "ti,sn65dsi86"; + reg = <0x2d>; + pinctrl-names = "default"; + pinctrl-0 = <&edp_brij_en>, <&edp_brij_irq>; + gpio-controller; + #gpio-cells = <2>; + + interrupt-parent = <&tlmm>; + interrupts = <11 IRQ_TYPE_LEVEL_HIGH>; + + enable-gpios = <&tlmm 104 GPIO_ACTIVE_HIGH>; + + vpll-supply = <&pp1800_edp_vpll>; + vccio-supply = <&pp1800_brij_vccio>; + vcca-supply = <&pp1200_brij>; + vcc-supply = <&pp1200_brij>; + + clocks = <&rpmhcc RPMH_LN_BB_CLK3>; + clock-names = "refclk"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + sn65dsi86_in: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + + port@1 { + reg = <1>; + sn65dsi86_out: endpoint { + data-lanes = <0 1>; + remote-endpoint = <&panel_in_edp>; + }; + }; + }; + }; +}; + +ap_sar_sensor_i2c: &i2c5 { + status = "okay"; + clock-frequency = <400000>; + + ap_sar_sensor: proximity@28 { + compatible = "semtech,sx9310"; + reg = <0x28>; + #io-channel-cells = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&p_sensor_int_l>; + + interrupt-parent = <&tlmm>; + interrupts = <24 IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&pp3300_a>; + svdd-supply = <&pp1800_prox>; + + status = "disabled"; + label = "proximity-wifi"; + }; +}; + +ap_tp_i2c: &i2c7 { + status = "okay"; + clock-frequency = <400000>; + + trackpad@15 { + compatible = "elan,ekth3000"; + reg = <0x15>; + pinctrl-names = "default"; + pinctrl-0 = <&trackpad_int_1v8_odl>; + + interrupt-parent = <&tlmm>; + interrupts = <58 IRQ_TYPE_EDGE_FALLING>; + + vcc-supply = <&pp3300_fp_tp>; + + wakeup-source; + }; +}; + +hp_i2c: &i2c9 { + status = "okay"; + clock-frequency = <400000>; + + alc5682: codec@1a { + compatible = "realtek,rt5682i"; + reg = <0x1a>; + pinctrl-names = "default"; + pinctrl-0 = <&hp_irq>; + + #sound-dai-cells = <1>; + + interrupt-parent = <&tlmm>; + /* + * This will get ignored because the interrupt type + * is set in rt5682.c. + */ + interrupts = <28 IRQ_TYPE_EDGE_BOTH>; + + AVDD-supply = <&pp1800_alc5682>; + MICVDD-supply = <&pp3300_codec>; + VBAT-supply = <&pp3300_audio>; + + realtek,dmic1-data-pin = <1>; + realtek,dmic1-clk-pin = <1>; + realtek,jd-src = <1>; + }; +}; + +&ipa { + status = "okay"; + + /* + * Trogdor doesn't have QHEE (Qualcomm's EL2 blob), so the + * modem needs to cover certain init steps (GSI init), and + * the AP needs to wait for it. + */ + modem-init; +}; + +&mdp { + status = "okay"; +}; + +&mdss { + status = "okay"; +}; + +&pm6150_pwrkey { + status = "disabled"; +}; + +&qupv3_id_0 { + status = "okay"; +}; + +&qupv3_id_1 { + status = "okay"; +}; + +&remoteproc_mpss { + status = "okay"; + compatible = "qcom,sc7180-mss-pil"; + iommus = <&apps_smmu 0x461 0x0>, <&apps_smmu 0x444 0x3>; + memory-region = <&mba_mem &mpss_mem>; + + /* This gets overridden for SKUs with LTE support. */ + firmware-name = "qcom/sc7180-trogdor/modem-nolte/mba.mbn", + "qcom/sc7180-trogdor/modem-nolte/qdsp6sw.mbn"; +}; + +&sdhc_1 { + status = "okay"; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc1_on>; + pinctrl-1 = <&sdc1_off>; + vmmc-supply = <&mcp_vcc>; + vqmmc-supply = <&mcp_vccq>; +}; + +&sdhc_2 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc2_on>; + pinctrl-1 = <&sdc2_off>; + vmmc-supply = <&pp2950_l9c>; + vqmmc-supply = <&ppvar_l6c>; + + cd-gpios = <&tlmm 69 GPIO_ACTIVE_LOW>; +}; + +ap_spi_fp: &spi10 { + cros_ec_fp: ec@0 { + compatible = "google,cros-ec-spi"; + reg = <0>; + interrupt-parent = <&tlmm>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&fp_to_ap_irq_l>, <&fp_rst_l>, <&fpmcu_boot0>, <&fpmcu_sel>; + spi-max-frequency = <3000000>; + }; +}; + +#include <arm/cros-ec-keyboard.dtsi> +#include <arm/cros-ec-sbs.dtsi> + +&uart3 { + status = "okay"; + + /delete-property/interrupts; + interrupts-extended = <&intc GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>, + <&tlmm 41 IRQ_TYPE_EDGE_FALLING>; + + pinctrl-names = "default", "sleep"; + pinctrl-1 = <&qup_uart3_sleep>; + + bluetooth: bluetooth { + compatible = "qcom,wcn3991-bt"; + vddio-supply = <&pp1800_l10a>; + vddxo-supply = <&pp1800_l1c>; + vddrf-supply = <&pp1300_l2c>; + vddch0-supply = <&pp3300_l10c>; + max-speed = <3200000>; + clocks = <&rpmhcc RPMH_RF_CLK2>; + }; +}; + +&uart8 { + status = "okay"; +}; + +&usb_1 { + status = "okay"; +}; + +&usb_1_dwc3 { + dr_mode = "host"; +}; + +&usb_1_hsphy { + status = "okay"; + vdd-supply = <&vdd_qusb_hs0_core>; + vdda-pll-supply = <&vdda_qusb_hs0_1p8>; + vdda-phy-dpdm-supply = <&vdda_qusb_hs0_3p1>; + qcom,imp-res-offset-value = <8>; + qcom,preemphasis-level = <QUSB2_V2_PREEMPHASIS_15_PERCENT>; + qcom,preemphasis-width = <QUSB2_V2_PREEMPHASIS_WIDTH_HALF_BIT>; + qcom,bias-ctrl-value = <0x22>; + qcom,charge-ctrl-value = <3>; + qcom,hsdisc-trim-value = <0>; +}; + +&usb_1_qmpphy { + status = "okay"; + vdda-phy-supply = <&vdda_usb_ss_dp_1p2>; + vdda-pll-supply = <&vdda_usb_ss_dp_core>; +}; + +&venus { + video-firmware { + iommus = <&apps_smmu 0x0c42 0x0>; + }; +}; + +&wifi { + status = "okay"; + vdd-0.8-cx-mx-supply = <&vdd_cx_wlan>; + vdd-1.8-xo-supply = <&pp1800_l1c>; + vdd-1.3-rfa-supply = <&pp1300_l2c>; + vdd-3.3-ch0-supply = <&pp3300_l10c>; + vdd-3.3-ch1-supply = <&pp3300_l11c>; + + wifi-firmware { + iommus = <&apps_smmu 0xc2 0x1>; + }; +}; + +/* PINCTRL - additions to nodes defined in sc7180.dtsi */ + +&qspi_cs0 { + pinconf { + pins = "gpio68"; + bias-disable; + }; +}; + +&qspi_clk { + pinconf { + pins = "gpio63"; + bias-disable; + }; +}; + +&qspi_data01 { + pinconf { + pins = "gpio64", "gpio65"; + + /* High-Z when no transfers; nice to park the lines */ + bias-pull-up; + }; +}; + +&qup_i2c2_default { + pinconf { + pins = "gpio15", "gpio16"; + drive-strength = <2>; + + /* Has external pullup */ + bias-disable; + }; +}; + +&qup_i2c4_default { + pinconf { + pins = "gpio115", "gpio116"; + drive-strength = <2>; + + /* Has external pullup */ + bias-disable; + }; +}; + +&qup_i2c5_default { + pinconf { + pins = "gpio25", "gpio26"; + drive-strength = <2>; + + /* Has external pullup */ + bias-disable; + }; +}; + +&qup_i2c7_default { + pinconf { + pins = "gpio6", "gpio7"; + drive-strength = <2>; + + /* Has external pullup */ + bias-disable; + }; +}; + +&qup_i2c9_default { + pinconf { + pins = "gpio46", "gpio47"; + drive-strength = <2>; + + /* Has external pullup */ + bias-disable; + }; +}; + +&qup_spi0_default { + pinconf { + pins = "gpio34", "gpio35", "gpio36", "gpio37"; + drive-strength = <2>; + bias-disable; + }; +}; + +&qup_spi6_default { + pinconf { + pins = "gpio59", "gpio60", "gpio61", "gpio62"; + drive-strength = <2>; + bias-disable; + }; +}; + +&qup_spi10_default { + pinconf { + pins = "gpio86", "gpio87", "gpio88", "gpio89"; + drive-strength = <2>; + bias-disable; + }; +}; + +&qup_uart3_default { + pinconf-cts { + /* + * Configure a pull-down on CTS to match the pull of + * the Bluetooth module. + */ + pins = "gpio38"; + bias-pull-down; + }; + + pinconf-rts-tx { + /* We'll drive RTS and TX, so no pull */ + pins = "gpio39", "gpio40"; + drive-strength = <2>; + bias-disable; + }; + + pinconf-rx { + /* + * Configure a pull-up on RX. This is needed to avoid + * garbage data when the TX pin of the Bluetooth module is + * in tri-state (module powered off or not driving the + * signal yet). + */ + pins = "gpio41"; + bias-pull-up; + }; +}; + +&qup_uart8_default { + pinconf-tx { + pins = "gpio44"; + drive-strength = <2>; + bias-disable; + }; + + pinconf-rx { + pins = "gpio45"; + drive-strength = <2>; + bias-pull-up; + }; +}; + +/* PINCTRL - board-specific pinctrl */ + +&pm6150_gpio { + status = "disabled"; /* No GPIOs are connected */ +}; + +&pm6150l_gpio { + gpio-line-names = "AP_SUSPEND", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + ""; +}; + +&tlmm { + /* + * pinctrl settings for pins that have no real owners. + */ + pinctrl-names = "default"; + pinctrl-0 = <&bios_flash_wp_l>, <&ap_suspend_l_neuter>; + + amp_en: amp-en { + pinmux { + pins = "gpio23"; + function = "gpio"; + }; + + pinconf { + pins = "gpio23"; + bias-pull-down; + }; + }; + + ap_ec_int_l: ap-ec-int-l { + pinmux { + pins = "gpio94"; + function = "gpio"; + input-enable; + }; + + pinconf { + pins = "gpio94"; + bias-pull-up; + }; + }; + + ap_edp_bklten: ap-edp-bklten { + pinmux { + pins = "gpio12"; + function = "gpio"; + }; + + pinconf { + pins = "gpio12"; + drive-strength = <2>; + bias-disable; + + /* Force backlight to be disabled to match state at boot. */ + output-low; + }; + }; + + ap_suspend_l_neuter: ap-suspend-l-neuter { + pinmux { + pins = "gpio27"; + function = "gpio"; + }; + + pinconf { + pins = "gpio27"; + bias-disable; + }; + }; + + bios_flash_wp_l: bios-flash-wp-l { + pinmux { + pins = "gpio66"; + function = "gpio"; + input-enable; + }; + + pinconf { + pins = "gpio66"; + bias-disable; + }; + }; + + dp_hot_plug_det: dp-hot-plug-det { + pinmux { + pins = "gpio117"; + function = "dp_hot"; + }; + + config { + pins = "gpio117"; + bias-disable; + input-enable; + drive-strength = <2>; + }; + }; + + edp_brij_en: edp-brij-en { + pinmux { + pins = "gpio104"; + function = "gpio"; + }; + + pinconf { + pins = "gpio104"; + drive-strength = <2>; + bias-disable; + }; + }; + + edp_brij_irq: edp-brij-irq { + pinmux { + pins = "gpio11"; + function = "gpio"; + }; + + pinconf { + pins = "gpio11"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + en_pp3300_codec: en-pp3300-codec { + pinmux { + pins = "gpio83"; + function = "gpio"; + }; + + pinconf { + pins = "gpio83"; + drive-strength = <2>; + bias-disable; + }; + }; + + en_pp3300_dx_edp: en-pp3300-dx-edp { + pinmux { + pins = "gpio30"; + function = "gpio"; + }; + + pinconf { + pins = "gpio30"; + drive-strength = <2>; + bias-disable; + }; + }; + + fpmcu_boot0: fpmcu-boot0 { + pinmux { + pins = "gpio10"; + function = "gpio"; + }; + + pinconf { + pins = "gpio10"; + bias-disable; + drive-strength = <2>; + output-low; + }; + }; + + fpmcu_sel: fpmcu-sel { + pinmux { + pins = "gpio22"; + function = "gpio"; + }; + + pinconf { + pins = "gpio22"; + bias-disable; + drive-strength = <2>; + output-high; + }; + }; + + fp_rst_l: fp-rst-l { + pinmux { + pins = "gpio5"; + function = "gpio"; + }; + + pinconf { + pins = "gpio5"; + bias-disable; + drive-strength = <2>; + output-high; + }; + }; + + fp_to_ap_irq_l: fp-to-ap-irq-l { + pinmux { + pins = "gpio4"; + function = "gpio"; + input-enable; + }; + + pinconf { + pins = "gpio4"; + + /* Has external pullup */ + bias-disable; + }; + }; + + + h1_ap_int_odl: h1-ap-int-odl { + pinmux { + pins = "gpio42"; + function = "gpio"; + input-enable; + }; + + pinconf { + pins = "gpio42"; + bias-pull-up; + }; + }; + + hp_irq: hp-irq { + pinmux { + pins = "gpio28"; + function = "gpio"; + }; + + pinconf { + pins = "gpio28"; + bias-pull-up; + }; + }; + + pen_irq_l: pen-irq-l { + pinmux { + pins = "gpio21"; + function = "gpio"; + }; + + pinconf { + pins = "gpio21"; + + /* Has external pullup */ + bias-disable; + }; + }; + + pen_pdct_l: pen-pdct-l { + pinmux { + pins = "gpio52"; + function = "gpio"; + }; + + pinconf { + pins = "gpio52"; + + /* Has external pullup */ + bias-disable; + }; + }; + + pen_rst_odl: pen-rst-odl { + pinmux { + pins = "gpio18"; + function = "gpio"; + }; + + pinconf { + pins = "gpio18"; + bias-disable; + drive-strength = <2>; + + /* + * The pen driver doesn't currently support + * driving this reset line. By specifying + * output-high here we're relying on the fact + * that this pin has a default pulldown at boot + * (which makes sure the pen was in reset if it + * was powered) and then we set it high here to + * take it out of reset. Better would be if the + * pen driver could control this and we could + * remove "output-high" here. + */ + output-high; /* TODO: Remove this? */ + }; + }; + + p_sensor_int_l: p-sensor-int-l { + pinmux { + pins = "gpio24"; + function = "gpio"; + input-enable; + }; + + pinconf { + pins = "gpio24"; + bias-pull-up; + }; + }; + + qup_uart3_sleep: qup-uart3-sleep { + pinmux { + pins = "gpio38", "gpio39", + "gpio40", "gpio41"; + function = "gpio"; + }; + + pinconf-cts { + /* + * Configure a pull-down on CTS to match the pull of + * the Bluetooth module. + */ + pins = "gpio38"; + bias-pull-down; + }; + + pinconf-rts { + /* + * Configure pull-down on RTS. As RTS is active low + * signal, pull it low to indicate the BT SoC that it + * can wakeup the system anytime from suspend state by + * pulling RX low (by sending wakeup bytes). + */ + pins = "gpio39"; + bias-pull-down; + }; + + pinconf-tx { + /* + * Configure pull-up on TX when it isn't actively driven + * to prevent BT SoC from receiving garbage during sleep. + */ + pins = "gpio40"; + bias-pull-up; + }; + + pinconf-rx { + /* + * Configure a pull-up on RX. This is needed to avoid + * garbage data when the TX pin of the Bluetooth module + * is floating which may cause spurious wakeups. + */ + pins = "gpio41"; + bias-pull-up; + }; + }; + + trackpad_int_1v8_odl: trackpad-int-1v8-odl { + pinmux { + pins = "gpio58"; + function = "gpio"; + }; + + pinconf { + pins = "gpio58"; + + /* Has external pullup */ + bias-disable; + }; + }; + + ts_int_l: ts-int-l { + pinmux { + pins = "gpio9"; + function = "gpio"; + }; + + pinconf { + pins = "gpio9"; + bias-pull-up; + }; + }; + + ts_reset_l: ts-reset-l { + pinmux { + pins = "gpio8"; + function = "gpio"; + }; + + pinconf { + pins = "gpio8"; + bias-disable; + drive-strength = <2>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index d46b3833e52f..6678f1e8e395 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -8,6 +8,7 @@ #include <dt-bindings/clock/qcom,dispcc-sc7180.h> #include <dt-bindings/clock/qcom,gcc-sc7180.h> #include <dt-bindings/clock/qcom,gpucc-sc7180.h> +#include <dt-bindings/clock/qcom,lpasscorecc-sc7180.h> #include <dt-bindings/clock/qcom,rpmh.h> #include <dt-bindings/clock/qcom,videocc-sc7180.h> #include <dt-bindings/interconnect/qcom,osm-l3.h> @@ -132,7 +133,7 @@ capacity-dmips-mhz = <1024>; dynamic-power-coefficient = <100>; operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>, + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; next-level-cache = <&L2_0>; #cooling-cells = <2>; @@ -158,7 +159,7 @@ dynamic-power-coefficient = <100>; next-level-cache = <&L2_100>; operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>, + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 0>; @@ -180,7 +181,7 @@ dynamic-power-coefficient = <100>; next-level-cache = <&L2_200>; operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>, + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 0>; @@ -202,7 +203,7 @@ dynamic-power-coefficient = <100>; next-level-cache = <&L2_300>; operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>, + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 0>; @@ -224,7 +225,7 @@ dynamic-power-coefficient = <100>; next-level-cache = <&L2_400>; operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>, + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 0>; @@ -246,7 +247,7 @@ dynamic-power-coefficient = <100>; next-level-cache = <&L2_500>; operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>, + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 0>; @@ -268,7 +269,7 @@ dynamic-power-coefficient = <405>; next-level-cache = <&L2_600>; operating-points-v2 = <&cpu6_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>, + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 1>; @@ -290,7 +291,7 @@ dynamic-power-coefficient = <405>; next-level-cache = <&L2_700>; operating-points-v2 = <&cpu6_opp_table>; - interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>, + interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; qcom,freq-domain = <&cpufreq_hw 1>; @@ -690,6 +691,9 @@ clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>; clock-names = "core", "iface"; + interconnects = <&aggre1_noc MASTER_EMMC 0 &mc_virt SLAVE_EBI1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_EMMC_CFG 0>; + interconnect-names = "sdhc-ddr","cpu-sdhc"; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&sdhc1_opp_table>; @@ -710,11 +714,15 @@ opp-100000000 { opp-hz = /bits/ 64 <100000000>; required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <100000 100000>; + opp-avg-kBps = <100000 50000>; }; opp-384000000 { opp-hz = /bits/ 64 <384000000>; required-opps = <&rpmhpd_opp_svs_l1>; + opp-peak-kBps = <600000 900000>; + opp-avg-kBps = <261438 300000>; }; }; }; @@ -748,7 +756,7 @@ #size-cells = <2>; ranges; iommus = <&apps_smmu 0x43 0x0>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>; interconnect-names = "qup-core"; status = "disabled"; @@ -762,9 +770,9 @@ interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>, - <&aggre1_noc MASTER_QUP_0 &mc_virt SLAVE_EBI1>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>, + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; @@ -782,8 +790,8 @@ #size-cells = <0>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -798,8 +806,8 @@ interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -814,9 +822,9 @@ interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>, - <&aggre1_noc MASTER_QUP_0 &mc_virt SLAVE_EBI1>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>, + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; @@ -834,8 +842,8 @@ #size-cells = <0>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -850,8 +858,8 @@ interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -866,9 +874,9 @@ interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>, - <&aggre1_noc MASTER_QUP_0 &mc_virt SLAVE_EBI1>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>, + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; @@ -884,8 +892,8 @@ interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -900,9 +908,9 @@ interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>, - <&aggre1_noc MASTER_QUP_0 &mc_virt SLAVE_EBI1>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>, + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; @@ -920,8 +928,8 @@ #size-cells = <0>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -936,8 +944,8 @@ interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -952,9 +960,9 @@ interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>, - <&aggre1_noc MASTER_QUP_0 &mc_virt SLAVE_EBI1>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>, + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; @@ -970,8 +978,8 @@ interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -986,9 +994,9 @@ interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>, - <&aggre1_noc MASTER_QUP_0 &mc_virt SLAVE_EBI1>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>, + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; @@ -1006,8 +1014,8 @@ #size-cells = <0>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1022,8 +1030,8 @@ interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>; + interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1039,7 +1047,7 @@ #size-cells = <2>; ranges; iommus = <&apps_smmu 0x4c3 0x0>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>; interconnect-names = "qup-core"; status = "disabled"; @@ -1053,9 +1061,9 @@ interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>, - <&aggre2_noc MASTER_QUP_1 &mc_virt SLAVE_EBI1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; @@ -1073,8 +1081,8 @@ #size-cells = <0>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1089,8 +1097,8 @@ interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1105,9 +1113,9 @@ interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>, - <&aggre2_noc MASTER_QUP_1 &mc_virt SLAVE_EBI1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; @@ -1123,8 +1131,8 @@ interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1139,9 +1147,9 @@ interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>, - <&aggre2_noc MASTER_QUP_1 &mc_virt SLAVE_EBI1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; @@ -1159,8 +1167,8 @@ #size-cells = <0>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1175,8 +1183,8 @@ interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1191,9 +1199,9 @@ interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>, - <&aggre2_noc MASTER_QUP_1 &mc_virt SLAVE_EBI1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; @@ -1209,8 +1217,8 @@ interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1225,9 +1233,9 @@ interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>, - <&aggre2_noc MASTER_QUP_1 &mc_virt SLAVE_EBI1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; @@ -1245,8 +1253,8 @@ #size-cells = <0>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1261,8 +1269,8 @@ interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1277,9 +1285,9 @@ interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>, - <&aggre2_noc MASTER_QUP_1 &mc_virt SLAVE_EBI1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; status = "disabled"; @@ -1297,8 +1305,8 @@ #size-cells = <0>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1313,8 +1321,8 @@ interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qup_opp_table>; - interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>; + interconnects = <&qup_virt MASTER_QUP_CORE_1 0 &qup_virt SLAVE_QUP_CORE_1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; }; @@ -1323,63 +1331,63 @@ config_noc: interconnect@1500000 { compatible = "qcom,sc7180-config-noc"; reg = <0 0x01500000 0 0x28000>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; system_noc: interconnect@1620000 { compatible = "qcom,sc7180-system-noc"; reg = <0 0x01620000 0 0x17080>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; mc_virt: interconnect@1638000 { compatible = "qcom,sc7180-mc-virt"; reg = <0 0x01638000 0 0x1000>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; qup_virt: interconnect@1650000 { compatible = "qcom,sc7180-qup-virt"; reg = <0 0x01650000 0 0x1000>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; aggre1_noc: interconnect@16e0000 { compatible = "qcom,sc7180-aggre1-noc"; reg = <0 0x016e0000 0 0x15080>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; aggre2_noc: interconnect@1705000 { compatible = "qcom,sc7180-aggre2-noc"; reg = <0 0x01705000 0 0x9000>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; compute_noc: interconnect@170e000 { compatible = "qcom,sc7180-compute-noc"; reg = <0 0x0170e000 0 0x6000>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; mmss_noc: interconnect@1740000 { compatible = "qcom,sc7180-mmss-noc"; reg = <0 0x01740000 0 0x1c100>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; ipa_virt: interconnect@1e00000 { compatible = "qcom,sc7180-ipa-virt"; reg = <0 0x01e00000 0 0x1000>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; @@ -1406,9 +1414,9 @@ clocks = <&rpmhcc RPMH_IPA_CLK>; clock-names = "core"; - interconnects = <&aggre2_noc MASTER_IPA &mc_virt SLAVE_EBI1>, - <&aggre2_noc MASTER_IPA &system_noc SLAVE_IMEM>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_IPA_CFG>; + interconnects = <&aggre2_noc MASTER_IPA 0 &mc_virt SLAVE_EBI1 0>, + <&aggre2_noc MASTER_IPA 0 &system_noc SLAVE_IMEM 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_IPA_CFG 0>; interconnect-names = "memory", "imem", "config"; @@ -1447,6 +1455,19 @@ gpio-ranges = <&tlmm 0 0 120>; wakeup-parent = <&pdc>; + dp_hot_plug_det: dp-hot-plug-det { + pinmux { + pins = "gpio117"; + function = "dp_hot"; + }; + + pinconf { + pins = "gpio117"; + bias-disable; + input-enable; + }; + }; + qspi_clk: qspi-clk { pinmux { pins = "gpio63"; @@ -1886,7 +1907,7 @@ operating-points-v2 = <&gpu_opp_table>; qcom,gmu = <&gmu>; - interconnects = <&gem_noc MASTER_GFX3D &mc_virt SLAVE_EBI1>; + interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "gfx-mem"; gpu_opp_table: opp-table { @@ -2502,6 +2523,10 @@ clocks = <&gcc GCC_SDCC2_APPS_CLK>, <&gcc GCC_SDCC2_AHB_CLK>; clock-names = "core", "iface"; + + interconnects = <&aggre1_noc MASTER_SDCC_2 0 &mc_virt SLAVE_EBI1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_SDCC_2 0>; + interconnect-names = "sdhc-ddr","cpu-sdhc"; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&sdhc2_opp_table>; @@ -2515,11 +2540,15 @@ opp-100000000 { opp-hz = /bits/ 64 <100000000>; required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <160000 100000>; + opp-avg-kBps = <80000 50000>; }; opp-202000000 { opp-hz = /bits/ 64 <202000000>; required-opps = <&rpmhpd_opp_svs_l1>; + opp-peak-kBps = <200000 120000>; + opp-avg-kBps = <100000 60000>; }; }; }; @@ -2552,8 +2581,8 @@ clocks = <&gcc GCC_QSPI_CNOC_PERIPH_AHB_CLK>, <&gcc GCC_QSPI_CORE_CLK>; clock-names = "iface", "core"; - interconnects = <&gem_noc MASTER_APPSS_PROC - &config_noc SLAVE_QSPI_0>; + interconnects = <&gem_noc MASTER_APPSS_PROC 0 + &config_noc SLAVE_QSPI_0 0>; interconnect-names = "qspi-config"; power-domains = <&rpmhpd SC7180_CX>; operating-points-v2 = <&qspi_opp_table>; @@ -2612,13 +2641,13 @@ dc_noc: interconnect@9160000 { compatible = "qcom,sc7180-dc-noc"; reg = <0 0x09160000 0 0x03200>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; system-cache-controller@9200000 { compatible = "qcom,sc7180-llcc"; - reg = <0 0x09200000 0 0x200000>, <0 0x09600000 0 0x50000>; + reg = <0 0x09200000 0 0x50000>, <0 0x09600000 0 0x50000>; reg-names = "llcc_base", "llcc_broadcast_base"; interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>; }; @@ -2626,14 +2655,14 @@ gem_noc: interconnect@9680000 { compatible = "qcom,sc7180-gem-noc"; reg = <0 0x09680000 0 0x3e200>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; npu_noc: interconnect@9990000 { compatible = "qcom,sc7180-npu-noc"; reg = <0 0x09990000 0 0x1600>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; @@ -2669,8 +2698,8 @@ resets = <&gcc GCC_USB30_PRIM_BCR>; - interconnects = <&aggre2_noc MASTER_USB3 &mc_virt SLAVE_EBI1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_USB3>; + interconnects = <&aggre2_noc MASTER_USB3 0 &mc_virt SLAVE_EBI1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3 0>; interconnect-names = "usb-ddr", "apps-usb"; usb_1_dwc3: dwc3@a600000 { @@ -2691,8 +2720,10 @@ reg = <0 0x0aa00000 0 0xff000>; interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&videocc VENUS_GDSC>, - <&videocc VCODEC0_GDSC>; - power-domain-names = "venus", "vcodec0"; + <&videocc VCODEC0_GDSC>, + <&rpmhpd SC7180_CX>; + power-domain-names = "venus", "vcodec0", "cx"; + operating-points-v2 = <&venus_opp_table>; clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>, <&videocc VIDEO_CC_VENUS_AHB_CLK>, <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>, @@ -2702,8 +2733,8 @@ "vcodec0_core", "vcodec0_bus"; iommus = <&apps_smmu 0x0c00 0x60>; memory-region = <&venus_mem>; - interconnects = <&mmss_noc MASTER_VIDEO_P0 &mc_virt SLAVE_EBI1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_VENUS_CFG>; + interconnects = <&mmss_noc MASTER_VIDEO_P0 0 &mc_virt SLAVE_EBI1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_VENUS_CFG 0>; interconnect-names = "video-mem", "cpu-cfg"; video-decoder { @@ -2713,6 +2744,35 @@ video-encoder { compatible = "venus-encoder"; }; + + venus_opp_table: venus-opp-table { + compatible = "operating-points-v2"; + + opp-150000000 { + opp-hz = /bits/ 64 <150000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-270000000 { + opp-hz = /bits/ 64 <270000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-340000000 { + opp-hz = /bits/ 64 <340000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-434000000 { + opp-hz = /bits/ 64 <434000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-500000097 { + opp-hz = /bits/ 64 <500000097>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; }; videocc: clock-controller@ab00000 { @@ -2728,7 +2788,7 @@ camnoc_virt: interconnect@ac00000 { compatible = "qcom,sc7180-camnoc-virt"; reg = <0 0x0ac00000 0 0x1000>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; @@ -2740,10 +2800,9 @@ power-domains = <&dispcc MDSS_GDSC>; clocks = <&gcc GCC_DISP_AHB_CLK>, - <&gcc GCC_DISP_HF_AXI_CLK>, <&dispcc DISP_CC_MDSS_AHB_CLK>, <&dispcc DISP_CC_MDSS_MDP_CLK>; - clock-names = "iface", "bus", "ahb", "core"; + clock-names = "iface", "ahb", "core"; assigned-clocks = <&dispcc DISP_CC_MDSS_MDP_CLK>; assigned-clock-rates = <300000000>; @@ -2752,6 +2811,9 @@ interrupt-controller; #interrupt-cells = <1>; + interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>; + interconnect-names = "mdp0-mem"; + iommus = <&apps_smmu 0x800 0x2>; #address-cells = <2>; @@ -2766,12 +2828,13 @@ <0 0x0aeb0000 0 0x2008>; reg-names = "mdp", "vbif"; - clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, + clocks = <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc DISP_CC_MDSS_AHB_CLK>, <&dispcc DISP_CC_MDSS_ROT_CLK>, <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>, <&dispcc DISP_CC_MDSS_MDP_CLK>, <&dispcc DISP_CC_MDSS_VSYNC_CLK>; - clock-names = "iface", "rot", "lut", "core", + clock-names = "bus", "iface", "rot", "lut", "core", "vsync"; assigned-clocks = <&dispcc DISP_CC_MDSS_MDP_CLK>, <&dispcc DISP_CC_MDSS_VSYNC_CLK>, @@ -2785,7 +2848,7 @@ power-domains = <&rpmhpd SC7180_CX>; interrupt-parent = <&mdss>; - interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <0>; status = "disabled"; @@ -2833,7 +2896,7 @@ reg-names = "dsi_ctrl"; interrupt-parent = <&mdss>; - interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <4>; clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>, <&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>, @@ -3312,6 +3375,29 @@ qcom,msa-fixed-perm; status = "disabled"; }; + + lpasscc: clock-controller@62d00000 { + compatible = "qcom,sc7180-lpasscorecc"; + reg = <0 0x62d00000 0 0x50000>, + <0 0x62780000 0 0x30000>; + reg-names = "lpass_core_cc", "lpass_audio_cc"; + clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>, + <&rpmhcc RPMH_CXO_CLK>; + clock-names = "iface", "bi_tcxo"; + power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>; + #clock-cells = <1>; + #power-domain-cells = <1>; + }; + + lpass_hm: clock-controller@63000000 { + compatible = "qcom,sc7180-lpasshm"; + reg = <0 0x63000000 0 0x28>; + clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>, + <&rpmhcc RPMH_CXO_CLK>; + clock-names = "iface", "bi_tcxo"; + #clock-cells = <1>; + #power-domain-cells = <1>; + }; }; thermal-zones { @@ -3320,6 +3406,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 1>; + sustainable-power = <768>; trips { cpu0_alert0: trip-point0 { @@ -3368,6 +3455,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 2>; + sustainable-power = <768>; trips { cpu1_alert0: trip-point0 { @@ -3416,6 +3504,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 3>; + sustainable-power = <768>; trips { cpu2_alert0: trip-point0 { @@ -3464,6 +3553,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 4>; + sustainable-power = <768>; trips { cpu3_alert0: trip-point0 { @@ -3512,6 +3602,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 5>; + sustainable-power = <768>; trips { cpu4_alert0: trip-point0 { @@ -3560,6 +3651,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 6>; + sustainable-power = <768>; trips { cpu5_alert0: trip-point0 { @@ -3608,6 +3700,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 9>; + sustainable-power = <1202>; trips { cpu6_alert0: trip-point0 { @@ -3648,6 +3741,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 10>; + sustainable-power = <1202>; trips { cpu7_alert0: trip-point0 { @@ -3688,6 +3782,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 11>; + sustainable-power = <1202>; trips { cpu8_alert0: trip-point0 { @@ -3728,6 +3823,7 @@ polling-delay = <0>; thermal-sensors = <&tsens0 12>; + sustainable-power = <1202>; trips { cpu9_alert0: trip-point0 { diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi index 88efe8200c80..deb928d303c2 100644 --- a/arch/arm64/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi @@ -518,6 +518,8 @@ <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; }; tcsr_mutex_regs: syscon@1f40000 { @@ -749,6 +751,8 @@ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; }; lpass_smmu: iommu@5100000 { @@ -778,6 +782,8 @@ <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; }; spmi_bus: spmi@800f000 { @@ -1074,6 +1080,8 @@ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; }; apcs_glb: mailbox@17911000 { diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts index a2a98680ccf5..7cc236575ee2 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -451,16 +451,16 @@ port@0 { reg = <0>; - lt9611_out: endpoint { - remote-endpoint = <&hdmi_con>; + lt9611_a: endpoint { + remote-endpoint = <&dsi0_out>; }; }; - port@1 { - reg = <1>; + port@2 { + reg = <2>; - lt9611_a: endpoint { - remote-endpoint = <&dsi0_out>; + lt9611_out: endpoint { + remote-endpoint = <&hdmi_con>; }; }; }; @@ -1103,7 +1103,7 @@ }; &cci { - status = "ok"; + status = "okay"; }; &cci_i2c0 { diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts new file mode 100644 index 000000000000..86cbae63eaf7 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts @@ -0,0 +1,380 @@ +// SPDX-License-Identifier: GPL-2.0 + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> +#include "sdm845.dtsi" +#include "pm8998.dtsi" +#include "pmi8998.dtsi" + +/* + * Delete following upstream (sdm845.dtsi) reserved + * memory mappings which are different in this device. + */ +/delete-node/ &tz_mem; +/delete-node/ &adsp_mem; +/delete-node/ &wlan_msa_mem; +/delete-node/ &mpss_region; +/delete-node/ &venus_mem; +/delete-node/ &cdsp_mem; +/delete-node/ &mba_region; +/delete-node/ &slpi_mem; +/delete-node/ &spss_mem; +/delete-node/ &rmtfs_mem; + +/ { + model = "Xiaomi Pocophone F1"; + compatible = "xiaomi,beryllium", "qcom,sdm845"; + + /* required for bootloader to select correct board */ + qcom,board-id = <69 0>; + qcom,msm-id = <321 0x20001>; + + aliases { + hsuart0 = &uart6; + }; + + gpio-keys { + compatible = "gpio-keys"; + autorepeat; + + pinctrl-names = "default"; + pinctrl-0 = <&vol_up_pin_a>; + + vol-up { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + gpios = <&pm8998_gpio 6 GPIO_ACTIVE_LOW>; + }; + }; + + /* Reserved memory changes from downstream */ + reserved-memory { + tz_mem: memory@86200000 { + reg = <0 0x86200000 0 0x4900000>; + no-map; + }; + + adsp_mem: memory@8c500000 { + reg = <0 0x8c500000 0 0x1e00000>; + no-map; + }; + + wlan_msa_mem: memory@8e300000 { + reg = <0 0x8e300000 0 0x100000>; + no-map; + }; + + mpss_region: memory@8e400000 { + reg = <0 0x8e400000 0 0x7800000>; + no-map; + }; + + venus_mem: memory@95c00000 { + reg = <0 0x95c00000 0 0x500000>; + no-map; + }; + + cdsp_mem: memory@96100000 { + reg = <0 0x96100000 0 0x800000>; + no-map; + }; + + mba_region: memory@96900000 { + reg = <0 0x96900000 0 0x200000>; + no-map; + }; + + slpi_mem: memory@96b00000 { + reg = <0 0x96b00000 0 0x1400000>; + no-map; + }; + + spss_mem: memory@97f00000 { + reg = <0 0x97f00000 0 0x100000>; + no-map; + }; + + rmtfs_mem: memory@f6301000 { + compatible = "qcom,rmtfs-mem"; + reg = <0 0xf6301000 0 0x200000>; + no-map; + + qcom,client-id = <1>; + qcom,vmid = <15>; + }; + }; + + vreg_s4a_1p8: vreg-s4a-1p8 { + compatible = "regulator-fixed"; + regulator-name = "vreg_s4a_1p8"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; +}; + +&adsp_pas { + status = "okay"; + firmware-name = "qcom/sdm845/adsp.mdt"; +}; + +&apps_rsc { + pm8998-rpmh-regulators { + compatible = "qcom,pm8998-rpmh-regulators"; + qcom,pmic-id = "a"; + + vreg_l1a_0p875: ldo1 { + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5a_0p8: ldo5 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <800000>; + 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>; + }; + + vreg_l12a_1p8: ldo12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l13a_2p95: ldo13 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l17a_1p3: ldo17 { + regulator-min-microvolt = <1304000>; + regulator-max-microvolt = <1304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l20a_2p95: ldo20 { + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2968000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l21a_2p95: ldo21 { + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2968000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l24a_3p075: ldo24 { + regulator-min-microvolt = <3088000>; + regulator-max-microvolt = <3088000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l25a_3p3: ldo25 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3312000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l26a_1p2: ldo26 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +&cdsp_pas { + status = "okay"; + firmware-name = "qcom/sdm845/cdsp.mdt"; +}; + +&gcc { + protected-clocks = <GCC_QSPI_CORE_CLK>, + <GCC_QSPI_CORE_CLK_SRC>, + <GCC_QSPI_CNOC_PERIPH_AHB_CLK>, + <GCC_LPASS_Q6_AXI_CLK>, + <GCC_LPASS_SWAY_CLK>; +}; + +&gpu { + zap-shader { + memory-region = <&gpu_mem>; + firmware-name = "qcom/sdm845/a630_zap.mbn"; + }; +}; + +&mss_pil { + status = "okay"; + firmware-name = "qcom/sdm845/mba.mbn", "qcom/sdm845/modem.mdt"; +}; + +&pm8998_gpio { + vol_up_pin_a: vol-up-active { + pins = "gpio6"; + function = "normal"; + input-enable; + bias-pull-up; + qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>; + }; +}; + +&pm8998_pon { + resin { + compatible = "qcom,pm8941-resin"; + interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; + debounce = <15625>; + bias-pull-up; + linux,code = <KEY_VOLUMEDOWN>; + }; +}; + +&qupv3_id_0 { + status = "okay"; +}; + +&sdhc_2 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&sdc2_default_state &sdc2_card_det_n>; + + vmmc-supply = <&vreg_l21a_2p95>; + vqmmc-supply = <&vreg_l13a_2p95>; + + bus-width = <4>; + cd-gpios = <&tlmm 126 GPIO_ACTIVE_HIGH>; +}; + +&tlmm { + gpio-reserved-ranges = <0 4>, <81 4>; + + sdc2_default_state: sdc2-default { + clk { + pins = "sdc2_clk"; + bias-disable; + drive-strength = <16>; + }; + + cmd { + pins = "sdc2_cmd"; + bias-pull-up; + drive-strength = <10>; + }; + + data { + pins = "sdc2_data"; + bias-pull-up; + drive-strength = <10>; + }; + }; + + sdc2_card_det_n: sd-card-det-n { + pins = "gpio126"; + function = "gpio"; + bias-pull-up; + }; +}; + +&uart6 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn3990-bt"; + + vddio-supply = <&vreg_s4a_1p8>; + vddxo-supply = <&vreg_l7a_1p8>; + vddrf-supply = <&vreg_l17a_1p3>; + vddch0-supply = <&vreg_l25a_3p3>; + max-speed = <3200000>; + }; +}; + +&ufs_mem_hc { + status = "okay"; + + reset-gpios = <&tlmm 150 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l20a_2p95>; + vcc-max-microamp = <800000>; +}; + +&ufs_mem_phy { + status = "okay"; + + vdda-phy-supply = <&vreg_l1a_0p875>; + vdda-pll-supply = <&vreg_l26a_1p2>; +}; + +&usb_1 { + status = "okay"; +}; + +&usb_1_dwc3 { + dr_mode = "peripheral"; +}; + +&usb_1_hsphy { + status = "okay"; + + vdd-supply = <&vreg_l1a_0p875>; + vdda-pll-supply = <&vreg_l12a_1p8>; + vdda-phy-dpdm-supply = <&vreg_l24a_3p075>; + + qcom,imp-res-offset-value = <8>; + qcom,hstx-trim-value = <QUSB2_V2_HSTX_TRIM_21_6_MA>; + qcom,preemphasis-level = <QUSB2_V2_PREEMPHASIS_5_PERCENT>; + qcom,preemphasis-width = <QUSB2_V2_PREEMPHASIS_WIDTH_HALF_BIT>; +}; + +&usb_1_qmpphy { + status = "okay"; + + vdda-phy-supply = <&vreg_l26a_1p2>; + vdda-pll-supply = <&vreg_l1a_0p875>; +}; + +&wifi { + status = "okay"; + + vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>; + vdd-1.8-xo-supply = <&vreg_l7a_1p8>; + vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; + vdd-3.3-ch0-supply = <&vreg_l25a_3p3>; +}; + +/* PINCTRL - additions to nodes defined in sdm845.dtsi */ + +&qup_uart6_default { + pinmux { + pins = "gpio45", "gpio46", "gpio47", "gpio48"; + function = "qup6"; + }; + + cts { + pins = "gpio45"; + bias-disable; + }; + + rts-tx { + pins = "gpio46", "gpio47"; + drive-strength = <2>; + bias-disable; + }; + + rx { + pins = "gpio48"; + bias-pull-up; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index 2884577dcb77..40e8c11f23ab 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -200,7 +200,7 @@ dynamic-power-coefficient = <100>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>, + interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; next-level-cache = <&L2_0>; @@ -225,7 +225,7 @@ dynamic-power-coefficient = <100>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>, + interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; next-level-cache = <&L2_100>; @@ -247,7 +247,7 @@ dynamic-power-coefficient = <100>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>, + interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; next-level-cache = <&L2_200>; @@ -269,7 +269,7 @@ dynamic-power-coefficient = <100>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; - interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>, + interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; next-level-cache = <&L2_300>; @@ -291,7 +291,7 @@ dynamic-power-coefficient = <396>; qcom,freq-domain = <&cpufreq_hw 1>; operating-points-v2 = <&cpu4_opp_table>; - interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>, + interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; next-level-cache = <&L2_400>; @@ -313,7 +313,7 @@ dynamic-power-coefficient = <396>; qcom,freq-domain = <&cpufreq_hw 1>; operating-points-v2 = <&cpu4_opp_table>; - interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>, + interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; next-level-cache = <&L2_500>; @@ -335,7 +335,7 @@ dynamic-power-coefficient = <396>; qcom,freq-domain = <&cpufreq_hw 1>; operating-points-v2 = <&cpu4_opp_table>; - interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>, + interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; next-level-cache = <&L2_600>; @@ -357,7 +357,7 @@ dynamic-power-coefficient = <396>; qcom,freq-domain = <&cpufreq_hw 1>; operating-points-v2 = <&cpu4_opp_table>; - interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>, + interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; #cooling-cells = <2>; next-level-cache = <&L2_700>; @@ -1093,8 +1093,8 @@ qup_opp_table: qup-opp-table { compatible = "operating-points-v2"; - opp-19200000 { - opp-hz = /bits/ 64 <19200000>; + opp-50000000 { + opp-hz = /bits/ 64 <50000000>; required-opps = <&rpmhpd_opp_min_svs>; }; @@ -1107,6 +1107,11 @@ opp-hz = /bits/ 64 <100000000>; required-opps = <&rpmhpd_opp_svs>; }; + + opp-128000000 { + opp-hz = /bits/ 64 <128000000>; + required-opps = <&rpmhpd_opp_nom>; + }; }; qupv3_id_0: geniqup@8c0000 { @@ -2011,49 +2016,49 @@ mem_noc: interconnect@1380000 { compatible = "qcom,sdm845-mem-noc"; reg = <0 0x01380000 0 0x27200>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; dc_noc: interconnect@14e0000 { compatible = "qcom,sdm845-dc-noc"; reg = <0 0x014e0000 0 0x400>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; config_noc: interconnect@1500000 { compatible = "qcom,sdm845-config-noc"; reg = <0 0x01500000 0 0x5080>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; system_noc: interconnect@1620000 { compatible = "qcom,sdm845-system-noc"; reg = <0 0x01620000 0 0x18080>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; aggre1_noc: interconnect@16e0000 { compatible = "qcom,sdm845-aggre1-noc"; reg = <0 0x016e0000 0 0x15080>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; aggre2_noc: interconnect@1700000 { compatible = "qcom,sdm845-aggre2-noc"; reg = <0 0x01700000 0 0x1f300>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; mmss_noc: interconnect@1740000 { compatible = "qcom,sdm845-mmss-noc"; reg = <0 0x01740000 0 0x1c100>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; @@ -2156,9 +2161,9 @@ clocks = <&rpmhcc RPMH_IPA_CLK>; clock-names = "core"; - interconnects = <&aggre2_noc MASTER_IPA &mem_noc SLAVE_EBI1>, - <&aggre2_noc MASTER_IPA &system_noc SLAVE_IMEM>, - <&gladiator_noc MASTER_APPSS_PROC &config_noc SLAVE_IPA_CFG>; + interconnects = <&aggre2_noc MASTER_IPA 0 &mem_noc SLAVE_EBI1 0>, + <&aggre2_noc MASTER_IPA 0 &system_noc SLAVE_IMEM 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_IPA_CFG 0>; interconnect-names = "memory", "imem", "config"; @@ -3569,8 +3574,8 @@ resets = <&gcc GCC_USB30_PRIM_BCR>; - interconnects = <&aggre2_noc MASTER_USB3_0 &mem_noc SLAVE_EBI1>, - <&gladiator_noc MASTER_APPSS_PROC &config_noc SLAVE_USB3_0>; + interconnects = <&aggre2_noc MASTER_USB3_0 0 &mem_noc SLAVE_EBI1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_0 0>; interconnect-names = "usb-ddr", "apps-usb"; usb_1_dwc3: dwc3@a600000 { @@ -3617,8 +3622,8 @@ resets = <&gcc GCC_USB30_SEC_BCR>; - interconnects = <&aggre2_noc MASTER_USB3_1 &mem_noc SLAVE_EBI1>, - <&gladiator_noc MASTER_APPSS_PROC &config_noc SLAVE_USB3_1>; + interconnects = <&aggre2_noc MASTER_USB3_1 0 &mem_noc SLAVE_EBI1 0>, + <&gladiator_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_1 0>; interconnect-names = "usb-ddr", "apps-usb"; usb_2_dwc3: dwc3@a800000 { @@ -3639,8 +3644,10 @@ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&videocc VENUS_GDSC>, <&videocc VCODEC0_GDSC>, - <&videocc VCODEC1_GDSC>; - power-domain-names = "venus", "vcodec0", "vcodec1"; + <&videocc VCODEC1_GDSC>, + <&rpmhpd SDM845_CX>; + power-domain-names = "venus", "vcodec0", "vcodec1", "cx"; + operating-points-v2 = <&venus_opp_table>; clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>, <&videocc VIDEO_CC_VENUS_AHB_CLK>, <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>, @@ -3662,6 +3669,40 @@ video-core1 { compatible = "venus-encoder"; }; + + venus_opp_table: venus-opp-table { + compatible = "operating-points-v2"; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + required-opps = <&rpmhpd_opp_min_svs>; + }; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-320000000 { + opp-hz = /bits/ 64 <320000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-380000000 { + opp-hz = /bits/ 64 <380000000>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + + opp-444000000 { + opp-hz = /bits/ 64 <444000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + + opp-533000097 { + opp-hz = /bits/ 64 <533000097>; + required-opps = <&rpmhpd_opp_turbo>; + }; + }; }; videocc: clock-controller@ab00000 { @@ -3777,6 +3818,10 @@ interrupt-controller; #interrupt-cells = <1>; + interconnects = <&mmss_noc MASTER_MDP0 0 &mem_noc SLAVE_EBI1 0>, + <&mmss_noc MASTER_MDP1 0 &mem_noc SLAVE_EBI1 0>; + interconnect-names = "mdp0-mem", "mdp1-mem"; + iommus = <&apps_smmu 0x880 0x8>, <&apps_smmu 0xc80 0x8>; @@ -4007,7 +4052,7 @@ qcom,gmu = <&gmu>; - interconnects = <&mem_noc MASTER_GFX3D &mem_noc SLAVE_EBI1>; + interconnects = <&mem_noc MASTER_GFX3D 0 &mem_noc SLAVE_EBI1 0>; interconnect-names = "gfx-mem"; gpu_opp_table: opp-table { @@ -4324,7 +4369,7 @@ gladiator_noc: interconnect@17900000 { compatible = "qcom,sdm845-gladiator-noc"; reg = <0 0x17900000 0 0xd080>; - #interconnect-cells = <1>; + #interconnect-cells = <2>; qcom,bcm-voters = <&apps_bcm_voter>; }; diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi index b86a7ead3006..f0a872e02686 100644 --- a/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi @@ -10,6 +10,8 @@ #include <dt-bindings/soc/qcom,rpmh-rsc.h> #include <dt-bindings/clock/qcom,rpmh.h> #include <dt-bindings/clock/qcom,gcc-sm8150.h> +#include <dt-bindings/clock/qcom,gpucc-sm8150.h> +#include <dt-bindings/interconnect/qcom,osm-l3.h> #include <dt-bindings/thermal/thermal.h> / { @@ -439,6 +441,55 @@ }; }; + config_noc: interconnect@1500000 { + compatible = "qcom,sm8150-config-noc"; + reg = <0 0x01500000 0 0x7400>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + system_noc: interconnect@1620000 { + compatible = "qcom,sm8150-system-noc"; + reg = <0 0x01620000 0 0x19400>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + mc_virt: interconnect@163a000 { + compatible = "qcom,sm8150-mc-virt"; + reg = <0 0x0163a000 0 0x1000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre1_noc: interconnect@16e0000 { + compatible = "qcom,sm8150-aggre1-noc"; + reg = <0 0x016e0000 0 0xd080>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre2_noc: interconnect@1700000 { + compatible = "qcom,sm8150-aggre2-noc"; + reg = <0 0x01700000 0 0x20000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + compute_noc: interconnect@1720000 { + compatible = "qcom,sm8150-compute-noc"; + reg = <0 0x01720000 0 0x7000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + mmss_noc: interconnect@1740000 { + compatible = "qcom,sm8150-mmss-noc"; + reg = <0 0x01740000 0 0x1c100>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + ufs_mem_hc: ufshc@1d84000 { compatible = "qcom,sm8150-ufshc", "qcom,ufshc", "jedec,ufs-2.0"; @@ -507,6 +558,13 @@ }; }; + ipa_virt: interconnect@1e00000 { + compatible = "qcom,sm8150-ipa-virt"; + reg = <0 0x01e00000 0 0x1000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + tcsr_mutex_regs: syscon@1f40000 { compatible = "syscon"; reg = <0x0 0x01f40000 0x0 0x40000>; @@ -621,15 +679,15 @@ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "hfi", "gmu"; - clocks = <&gpucc 0>, - <&gpucc 3>, - <&gpucc 6>, + clocks = <&gpucc GPU_CC_AHB_CLK>, + <&gpucc GPU_CC_CX_GMU_CLK>, + <&gpucc GPU_CC_CXO_CLK>, <&gcc GCC_DDRSS_GPU_AXI_CLK>, <&gcc GCC_GPU_MEMNOC_GFX_CLK>; clock-names = "ahb", "gmu", "cxo", "axi", "memnoc"; - power-domains = <&gpucc 0>, - <&gpucc 1>; + power-domains = <&gpucc GPU_CX_GDSC>, + <&gpucc GPU_GX_GDSC>; power-domain-names = "cx", "gx"; iommus = <&adreno_smmu 5 0x400>; @@ -674,12 +732,12 @@ <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 688 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gpucc 0>, + clocks = <&gpucc GPU_CC_AHB_CLK>, <&gcc GCC_GPU_MEMNOC_GFX_CLK>, <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>; clock-names = "ahb", "bus", "iface"; - power-domains = <&gpucc 0>; + power-domains = <&gpucc GPU_CX_GDSC>; }; tlmm: pinctrl@3100000 { @@ -767,7 +825,7 @@ usb_1_hsphy: phy@88e2000 { compatible = "qcom,sm8150-usb-hs-phy", - "qcom,usb-snps-hs-7nm-phy"; + "qcom,usb-snps-hs-7nm-phy"; reg = <0 0x088e2000 0 0x400>; status = "disabled"; #phy-cells = <0>; @@ -813,6 +871,20 @@ }; }; + dc_noc: interconnect@9160000 { + compatible = "qcom,sm8150-dc-noc"; + reg = <0 0x09160000 0 0x3200>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + gem_noc: interconnect@9680000 { + compatible = "qcom,sm8150-gem-noc"; + reg = <0 0x09680000 0 0x3e200>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + usb_1: usb@a6f8800 { compatible = "qcom,sm8150-dwc3", "qcom,dwc3"; reg = <0 0x0a6f8800 0 0x400>; @@ -833,7 +905,7 @@ assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>, <&gcc GCC_USB30_PRIM_MASTER_CLK>; - assigned-clock-rates = <19200000>, <150000000>; + assigned-clock-rates = <19200000>, <200000000>; interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>, @@ -857,6 +929,13 @@ }; }; + camnoc_virt: interconnect@ac00000 { + compatible = "qcom,sm8150-camnoc-virt"; + reg = <0 0x0ac00000 0 0x1000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + aoss_qmp: power-controller@c300000 { compatible = "qcom,sm8150-aoss-qmp"; reg = <0x0 0x0c300000 0x0 0x100000>; @@ -1099,6 +1178,20 @@ }; }; }; + + apps_bcm_voter: bcm_voter { + compatible = "qcom,bcm-voter"; + }; + }; + + osm_l3: interconnect@18321000 { + compatible = "qcom,sm8150-osm-l3"; + reg = <0 0x18321000 0 0x1400>; + + clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>; + clock-names = "xo", "alternate"; + + #interconnect-cells = <1>; }; cpufreq_hw: cpufreq@18323000 { diff --git a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts index 6894f8490dae..fd194ed7fbc8 100644 --- a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts @@ -17,7 +17,7 @@ compatible = "qcom,sm8250-mtp"; aliases { - serial0 = &uart2; + serial0 = &uart12; }; chosen { @@ -358,10 +358,38 @@ firmware-name = "qcom/sm8250/cdsp.mbn"; }; +&i2c1 { + status = "okay"; + clock-frequency = <1000000>; + + /* NQ NFC chip @28 */ +}; + +&i2c13 { + status = "okay"; + + /* st,stmfts @ 49 */ +}; + +&i2c15 { + status = "okay"; + + /* smb1390 @ 10 */ + /* rtc6226 @ 64 */ +}; + +&qupv3_id_0 { + status = "okay"; +}; + &qupv3_id_1 { status = "okay"; }; +&qupv3_id_2 { + status = "okay"; +}; + &slpi { status = "okay"; firmware-name = "qcom/sm8250/slpi.mbn"; @@ -371,7 +399,7 @@ gpio-reserved-ranges = <28 4>, <40 4>; }; -&uart2 { +&uart12 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi index 377172e8967b..d057d85a19fb 100644 --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -5,11 +5,14 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/clock/qcom,gcc-sm8250.h> +#include <dt-bindings/clock/qcom,gpucc-sm8250.h> #include <dt-bindings/clock/qcom,rpmh.h> +#include <dt-bindings/interconnect/qcom,osm-l3.h> #include <dt-bindings/mailbox/qcom-ipcc.h> #include <dt-bindings/power/qcom-aoss-qmp.h> #include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> +#include <dt-bindings/thermal/thermal.h> / { interrupt-parent = <&intc>; @@ -72,7 +75,7 @@ sleep_clk: sleep-clk { compatible = "fixed-clock"; - clock-frequency = <32000>; + clock-frequency = <32768>; #clock-cells = <0>; }; }; @@ -87,6 +90,8 @@ reg = <0x0 0x0>; enable-method = "psci"; next-level-cache = <&L2_0>; + qcom,freq-domain = <&cpufreq_hw 0>; + #cooling-cells = <2>; L2_0: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -102,6 +107,8 @@ reg = <0x0 0x100>; enable-method = "psci"; next-level-cache = <&L2_100>; + qcom,freq-domain = <&cpufreq_hw 0>; + #cooling-cells = <2>; L2_100: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -114,6 +121,8 @@ reg = <0x0 0x200>; enable-method = "psci"; next-level-cache = <&L2_200>; + qcom,freq-domain = <&cpufreq_hw 0>; + #cooling-cells = <2>; L2_200: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -126,6 +135,8 @@ reg = <0x0 0x300>; enable-method = "psci"; next-level-cache = <&L2_300>; + qcom,freq-domain = <&cpufreq_hw 0>; + #cooling-cells = <2>; L2_300: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -138,6 +149,8 @@ reg = <0x0 0x400>; enable-method = "psci"; next-level-cache = <&L2_400>; + qcom,freq-domain = <&cpufreq_hw 1>; + #cooling-cells = <2>; L2_400: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -150,6 +163,8 @@ reg = <0x0 0x500>; enable-method = "psci"; next-level-cache = <&L2_500>; + qcom,freq-domain = <&cpufreq_hw 1>; + #cooling-cells = <2>; L2_500: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -163,6 +178,8 @@ reg = <0x0 0x600>; enable-method = "psci"; next-level-cache = <&L2_600>; + qcom,freq-domain = <&cpufreq_hw 1>; + #cooling-cells = <2>; L2_600: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -175,6 +192,8 @@ reg = <0x0 0x700>; enable-method = "psci"; next-level-cache = <&L2_700>; + qcom,freq-domain = <&cpufreq_hw 2>; + #cooling-cells = <2>; L2_700: l2-cache { compatible = "cache"; next-level-cache = <&L3_0>; @@ -393,8 +412,12 @@ #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; - clock-names = "bi_tcxo", "sleep_clk"; - clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>; + clock-names = "bi_tcxo", + "bi_tcxo_ao", + "sleep_clk"; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&rpmhcc RPMH_CXO_CLK_A>, + <&sleep_clk>; }; ipcc: mailbox@408000 { @@ -406,6 +429,25 @@ #mbox-cells = <2>; }; + qup_opp_table: qup-opp-table { + compatible = "operating-points-v2"; + + opp-50000000 { + opp-hz = /bits/ 64 <50000000>; + required-opps = <&rpmhpd_opp_min_svs>; + }; + + opp-75000000 { + opp-hz = /bits/ 64 <75000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-120000000 { + opp-hz = /bits/ 64 <120000000>; + required-opps = <&rpmhpd_opp_svs>; + }; + }; + qupv3_id_2: geniqup@8c0000 { compatible = "qcom,geni-se-qup"; reg = <0x0 0x008c0000 0x0 0x6000>; @@ -440,6 +482,8 @@ interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -466,6 +510,8 @@ interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -492,6 +538,8 @@ interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -518,6 +566,21 @@ interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; + status = "disabled"; + }; + + uart17: serial@88c000 { + compatible = "qcom,geni-uart"; + reg = <0 0x0088c000 0 0x4000>; + clock-names = "se"; + clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>; + pinctrl-names = "default"; + pinctrl-0 = <&qup_uart17_default>; + interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -544,6 +607,21 @@ interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; + status = "disabled"; + }; + + uart18: serial@890000 { + compatible = "qcom,geni-uart"; + reg = <0 0x00890000 0 0x4000>; + clock-names = "se"; + clocks = <&gcc GCC_QUPV3_WRAP2_S4_CLK>; + pinctrl-names = "default"; + pinctrl-0 = <&qup_uart18_default>; + interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -570,6 +648,8 @@ interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; }; @@ -608,6 +688,8 @@ interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -634,6 +716,8 @@ interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -660,6 +744,21 @@ interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; + status = "disabled"; + }; + + uart2: serial@988000 { + compatible = "qcom,geni-debug-uart"; + reg = <0 0x00988000 0 0x4000>; + clock-names = "se"; + clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>; + pinctrl-names = "default"; + pinctrl-0 = <&qup_uart2_default>; + interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -686,6 +785,8 @@ interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -712,6 +813,8 @@ interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -738,6 +841,8 @@ interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -764,6 +869,21 @@ interrupts = <GIC_SPI 607 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; + status = "disabled"; + }; + + uart6: serial@998000 { + compatible = "qcom,geni-uart"; + reg = <0 0x00998000 0 0x4000>; + clock-names = "se"; + clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>; + pinctrl-names = "default"; + pinctrl-0 = <&qup_uart6_default>; + interrupts = <GIC_SPI 607 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -790,6 +910,8 @@ interrupts = <GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; }; @@ -828,6 +950,8 @@ interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -854,6 +978,8 @@ interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -880,6 +1006,8 @@ interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -906,6 +1034,8 @@ interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -932,15 +1062,21 @@ interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; - uart2: serial@a90000 { + uart12: serial@a90000 { compatible = "qcom,geni-debug-uart"; reg = <0x0 0x00a90000 0x0 0x4000>; clock-names = "se"; clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>; + pinctrl-names = "default"; + pinctrl-0 = <&qup_uart12_default>; interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; @@ -967,10 +1103,61 @@ interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&rpmhpd SM8250_CX>; + operating-points-v2 = <&qup_opp_table>; status = "disabled"; }; }; + config_noc: interconnect@1500000 { + compatible = "qcom,sm8250-config-noc"; + reg = <0 0x01500000 0 0xa580>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + system_noc: interconnect@1620000 { + compatible = "qcom,sm8250-system-noc"; + reg = <0 0x01620000 0 0x1c200>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + mc_virt: interconnect@163d000 { + compatible = "qcom,sm8250-mc-virt"; + reg = <0 0x0163d000 0 0x1000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre1_noc: interconnect@16e0000 { + compatible = "qcom,sm8250-aggre1-noc"; + reg = <0 0x016e0000 0 0x1f180>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre2_noc: interconnect@1700000 { + compatible = "qcom,sm8250-aggre2-noc"; + reg = <0 0x01700000 0 0x33000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + compute_noc: interconnect@1733000 { + compatible = "qcom,sm8250-compute-noc"; + reg = <0 0x01733000 0 0xa180>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + mmss_noc: interconnect@1740000 { + compatible = "qcom,sm8250-mmss-noc"; + reg = <0 0x01740000 0 0x1f080>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + ufs_mem_hc: ufshc@1d84000 { compatible = "qcom,sm8250-ufshc", "qcom,ufshc", "jedec,ufs-2.0"; @@ -1041,6 +1228,13 @@ }; }; + ipa_virt: interconnect@1e00000 { + compatible = "qcom,sm8250-ipa-virt"; + reg = <0 0x01e00000 0 0x1000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + tcsr_mutex: hwlock@1f40000 { compatible = "qcom,tcsr-mutex"; reg = <0x0 0x01f40000 0x0 0x40000>; @@ -1127,15 +1321,15 @@ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "hfi", "gmu"; - clocks = <&gpucc 0>, - <&gpucc 3>, - <&gpucc 6>, + clocks = <&gpucc GPU_CC_AHB_CLK>, + <&gpucc GPU_CC_CX_GMU_CLK>, + <&gpucc GPU_CC_CXO_CLK>, <&gcc GCC_DDRSS_GPU_AXI_CLK>, <&gcc GCC_GPU_MEMNOC_GFX_CLK>; clock-names = "ahb", "gmu", "cxo", "axi", "memnoc"; - power-domains = <&gpucc 0>, - <&gpucc 1>; + power-domains = <&gpucc GPU_CX_GDSC>, + <&gpucc GPU_GX_GDSC>; power-domain-names = "cx", "gx"; iommus = <&adreno_smmu 5 0x400>; @@ -1181,12 +1375,12 @@ <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gpucc 0>, + clocks = <&gpucc GPU_CC_AHB_CLK>, <&gcc GCC_GPU_MEMNOC_GFX_CLK>, <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>; clock-names = "ahb", "bus", "iface"; - power-domains = <&gpucc 0>; + power-domains = <&gpucc GPU_CX_GDSC>; }; slpi: remoteproc@5c00000 { @@ -1266,6 +1460,27 @@ }; }; + dc_noc: interconnect@90c0000 { + compatible = "qcom,sm8250-dc-noc"; + reg = <0 0x090c0000 0 0x4200>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + gem_noc: interconnect@9100000 { + compatible = "qcom,sm8250-gem-noc"; + reg = <0 0x09100000 0 0xb4000>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + npu_noc: interconnect@9990000 { + compatible = "qcom,sm8250-npu-noc"; + reg = <0 0x09990000 0 0x1600>; + #interconnect-cells = <1>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + pdc: interrupt-controller@b220000 { compatible = "qcom,sm8250-pdc", "qcom,pdc"; reg = <0 0x0b220000 0 0x30000>, <0 0x17c000f0 0 0x60>; @@ -1276,6 +1491,28 @@ interrupt-controller; }; + tsens0: thermal-sensor@c263000 { + compatible = "qcom,sm8250-tsens", "qcom,tsens-v2"; + reg = <0 0x0c263000 0 0x1ff>, /* TM */ + <0 0x0c222000 0 0x1ff>; /* SROT */ + #qcom,sensors = <16>; + interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", "critical"; + #thermal-sensor-cells = <1>; + }; + + tsens1: thermal-sensor@c265000 { + compatible = "qcom,sm8250-tsens", "qcom,tsens-v2"; + reg = <0 0x0c265000 0 0x1ff>, /* TM */ + <0 0x0c223000 0 0x1ff>; /* SROT */ + #qcom,sensors = <9>; + interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 509 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", "critical"; + #thermal-sensor-cells = <1>; + }; + aoss_qmp: qmp@c300000 { compatible = "qcom,sm8250-aoss-qmp"; reg = <0 0x0c300000 0 0x100000>; @@ -1880,6 +2117,43 @@ bias-disable; }; }; + + qup_uart2_default: qup-uart2-default { + mux { + pins = "gpio117", "gpio118"; + function = "qup2"; + }; + }; + + qup_uart6_default: qup-uart6-default { + mux { + pins = "gpio16", "gpio17", + "gpio18", "gpio19"; + function = "qup6"; + }; + }; + + qup_uart12_default: qup-uart12-default { + mux { + pins = "gpio34", "gpio35"; + function = "qup12"; + }; + }; + + qup_uart17_default: qup-uart17-default { + mux { + pins = "gpio52", "gpio53", + "gpio54", "gpio55"; + function = "qup17"; + }; + }; + + qup_uart18_default: qup-uart18-default { + mux { + pins = "gpio58", "gpio59"; + function = "qup18"; + }; + }; }; adsp: remoteproc@17300000 { @@ -2066,6 +2340,34 @@ }; }; }; + + apps_bcm_voter: bcm_voter { + compatible = "qcom,bcm-voter"; + }; + }; + + epss_l3: interconnect@18591000 { + compatible = "qcom,sm8250-epss-l3"; + reg = <0 0x18590000 0 0x1000>; + + clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>; + clock-names = "xo", "alternate"; + + #interconnect-cells = <1>; + }; + + cpufreq_hw: cpufreq@18591000 { + compatible = "qcom,sm8250-cpufreq-epss", "qcom,cpufreq-epss"; + reg = <0 0x18591000 0 0x1000>, + <0 0x18592000 0 0x1000>, + <0 0x18593000 0 0x1000>; + reg-names = "freq-domain0", "freq-domain1", + "freq-domain2"; + + clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>; + clock-names = "xo", "alternate"; + + #freq-domain-cells = <1>; }; }; @@ -2080,4 +2382,739 @@ <GIC_PPI 12 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>; }; + + thermal-zones { + cpu0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 1>; + + trips { + cpu0_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu0_alert1: trip-point1 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu0_crit: cpu_crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu0_alert0>; + cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu0_alert1>; + cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 2>; + + trips { + cpu1_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu1_alert1: trip-point1 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu1_crit: cpu_crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu1_alert0>; + cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu1_alert1>; + cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu2-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 3>; + + trips { + cpu2_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu2_alert1: trip-point1 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu2_crit: cpu_crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu2_alert0>; + cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu2_alert1>; + cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu3-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 4>; + + trips { + cpu3_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu3_alert1: trip-point1 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu3_crit: cpu_crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu3_alert0>; + cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu3_alert1>; + cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu4-top-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 7>; + + trips { + cpu4_top_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu4_top_alert1: trip-point1 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu4_top_crit: cpu_crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu4_top_alert0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu4_top_alert1>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu5-top-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 8>; + + trips { + cpu5_top_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu5_top_alert1: trip-point1 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu5_top_crit: cpu_crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu5_top_alert0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu5_top_alert1>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu6-top-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 9>; + + trips { + cpu6_top_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu6_top_alert1: trip-point1 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu6_top_crit: cpu_crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu6_top_alert0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu6_top_alert1>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu7-top-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 10>; + + trips { + cpu7_top_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu7_top_alert1: trip-point1 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu7_top_crit: cpu_crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu7_top_alert0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu7_top_alert1>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu4-bottom-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 11>; + + trips { + cpu4_bottom_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu4_bottom_alert1: trip-point1 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu4_bottom_crit: cpu_crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu4_bottom_alert0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu4_bottom_alert1>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu5-bottom-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 12>; + + trips { + cpu5_bottom_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu5_bottom_alert1: trip-point1 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu5_bottom_crit: cpu_crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu5_bottom_alert0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu5_bottom_alert1>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu6-bottom-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 13>; + + trips { + cpu6_bottom_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu6_bottom_alert1: trip-point1 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu6_bottom_crit: cpu_crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu6_bottom_alert0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu6_bottom_alert1>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu7-bottom-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 14>; + + trips { + cpu7_bottom_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu7_bottom_alert1: trip-point1 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu7_bottom_crit: cpu_crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu7_bottom_alert0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&cpu7_bottom_alert1>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + aoss0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 0>; + + trips { + aoss0_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + cluster0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 5>; + + trips { + cluster0_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + cluster0_crit: cluster0_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cluster1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 6>; + + trips { + cluster1_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + cluster1_crit: cluster1_crit { + temperature = <110000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + gpu-thermal-top { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens0 15>; + + trips { + gpu1_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + aoss1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens1 0>; + + trips { + aoss1_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + wlan-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens1 1>; + + trips { + wlan_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + video-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens1 2>; + + trips { + video_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + mem-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens1 3>; + + trips { + mem_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + q6-hvx-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens1 4>; + + trips { + q6_hvx_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + camera-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens1 5>; + + trips { + camera_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + compute-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens1 6>; + + trips { + compute_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + npu-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens1 7>; + + trips { + npu_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + gpu-thermal-bottom { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens1 8>; + + trips { + gpu2_alert0: trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile index d7902294faf3..dffefe030a76 100644 --- a/arch/arm64/boot/dts/renesas/Makefile +++ b/arch/arm64/boot/dts/renesas/Makefile @@ -21,6 +21,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_R8A77950) += r8a77950-salvator-x.dtb dtb-$(CONFIG_ARCH_R8A77950) += r8a77950-ulcb.dtb @@ -53,3 +54,5 @@ dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk.dtb dtb-$(CONFIG_ARCH_R8A77990) += r8a77990-ebisu.dtb dtb-$(CONFIG_ARCH_R8A77995) += r8a77995-draak.dtb + +dtb-$(CONFIG_ARCH_R8A779A0) += r8a779a0-falcon.dtb diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi index 8e80f50132ad..c15f1c571eb0 100644 --- a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi @@ -408,7 +408,7 @@ resets = <&cpg 905>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a774a1"; reg = <0 0xe6060000 0 0x50c>; }; @@ -2371,6 +2371,44 @@ status = "disabled"; }; + pciec0_ep: pcie-ep@fe000000 { + compatible = "renesas,r8a774a1-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 R8A774A1_PD_ALWAYS_ON>; + status = "disabled"; + }; + + pciec1_ep: pcie-ep@ee800000 { + compatible = "renesas,r8a774a1-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 R8A774A1_PD_ALWAYS_ON>; + status = "disabled"; + }; + fdp1@fe940000 { compatible = "renesas,fdp1"; reg = <0 0xfe940000 0 0x2400>; diff --git a/arch/arm64/boot/dts/renesas/r8a774b1-hihope-rzg2n-ex.dts b/arch/arm64/boot/dts/renesas/r8a774b1-hihope-rzg2n-ex.dts index a3edd55113df..60d7c8adea02 100644 --- a/arch/arm64/boot/dts/renesas/r8a774b1-hihope-rzg2n-ex.dts +++ b/arch/arm64/boot/dts/renesas/r8a774b1-hihope-rzg2n-ex.dts @@ -14,3 +14,8 @@ compatible = "hoperun,hihope-rzg2-ex", "hoperun,hihope-rzg2n", "renesas,r8a774b1"; }; + +/* Set SW43 = ON and SW1001[7] = OFF for SATA port to be activated */ +&sata { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi index 49e5addcfd97..39a1a26ffb54 100644 --- a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi @@ -282,7 +282,7 @@ resets = <&cpg 905>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a774b1"; reg = <0 0xe6060000 0 0x50c>; }; @@ -2240,6 +2240,44 @@ status = "disabled"; }; + pciec0_ep: pcie-ep@fe000000 { + compatible = "renesas,r8a774b1-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 R8A774B1_PD_ALWAYS_ON>; + status = "disabled"; + }; + + pciec1_ep: pcie-ep@ee800000 { + compatible = "renesas,r8a774b1-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 R8A774B1_PD_ALWAYS_ON>; + status = "disabled"; + }; + fdp1@fe940000 { compatible = "renesas,fdp1"; reg = <0 0xfe940000 0 0x2400>; diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi index 42171190cce4..f27d9b2eb996 100644 --- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi @@ -256,7 +256,7 @@ resets = <&cpg 906>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a774c0"; reg = <0 0xe6060000 0 0x508>; }; @@ -1214,9 +1214,8 @@ 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"; + dmas = <&dmac0 0x43>, <&dmac0 0x42>; + dma-names = "tx", "rx"; power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>; resets = <&cpg 210>; #address-cells = <1>; @@ -1698,6 +1697,25 @@ status = "disabled"; }; + pciec0_ep: pcie-ep@fe000000 { + compatible = "renesas,r8a774c0-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 R8A774C0_PD_ALWAYS_ON>; + status = "disabled"; + }; + vspb0: vsp@fe960000 { compatible = "renesas,vsp2"; reg = <0 0xfe960000 0 0x8000>; diff --git a/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h-ex-idk-1110wr.dts b/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h-ex-idk-1110wr.dts new file mode 100644 index 000000000000..3b7339127bc0 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h-ex-idk-1110wr.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for the HiHope RZ/G2H sub board connected + * to an Advantech IDK-1110WR 10.1" LVDS panel + * + * Copyright (C) 2020 Renesas Electronics Corp. + */ + +#include "r8a774e1-hihope-rzg2h-ex.dts" +#include "hihope-rzg2-ex-lvds.dtsi" +#include "rzg2-advantech-idk-1110wr-panel.dtsi" + +&lvds0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h-ex.dts b/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h-ex.dts index 265355e0de5f..812995939841 100644 --- a/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h-ex.dts +++ b/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h-ex.dts @@ -13,3 +13,8 @@ compatible = "hoperun,hihope-rzg2-ex", "hoperun,hihope-rzg2h", "renesas,r8a774e1"; }; + +/* Set SW43 = ON and SW1001[7] = OFF for SATA port to be activated */ +&sata { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h.dts b/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h.dts index cdbe527e9340..9525d5ed6fce 100644 --- a/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h.dts +++ b/arch/arm64/boot/dts/renesas/r8a774e1-hihope-rzg2h.dts @@ -24,3 +24,18 @@ reg = <0x5 0x00000000 0x0 0x80000000>; }; }; + +&du { + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 721>, + <&versaclock5 1>, + <&x302_clk>, + <&versaclock5 2>; + clock-names = "du.0", "du.1", "du.3", + "dclkin.0", "dclkin.1", "dclkin.3"; +}; + +&sdhi3 { + mmc-hs400-1_8v; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi index 0f86cfd52425..9cbf963aa068 100644 --- a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi @@ -127,6 +127,7 @@ power-domains = <&sysc R8A774E1_PD_CA57_CPU0>; next-level-cache = <&L2_CA57>; enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; dynamic-power-coefficient = <854>; clocks = <&cpg CPG_CORE R8A774E1_CLK_Z>; operating-points-v2 = <&cluster0_opp>; @@ -141,6 +142,7 @@ power-domains = <&sysc R8A774E1_PD_CA57_CPU1>; next-level-cache = <&L2_CA57>; enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; clocks = <&cpg CPG_CORE R8A774E1_CLK_Z>; operating-points-v2 = <&cluster0_opp>; capacity-dmips-mhz = <1024>; @@ -154,6 +156,7 @@ power-domains = <&sysc R8A774E1_PD_CA57_CPU2>; next-level-cache = <&L2_CA57>; enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; clocks = <&cpg CPG_CORE R8A774E1_CLK_Z>; operating-points-v2 = <&cluster0_opp>; capacity-dmips-mhz = <1024>; @@ -167,6 +170,7 @@ power-domains = <&sysc R8A774E1_PD_CA57_CPU3>; next-level-cache = <&L2_CA57>; enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; clocks = <&cpg CPG_CORE R8A774E1_CLK_Z>; operating-points-v2 = <&cluster0_opp>; capacity-dmips-mhz = <1024>; @@ -180,6 +184,7 @@ power-domains = <&sysc R8A774E1_PD_CA53_CPU0>; next-level-cache = <&L2_CA53>; enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_1>; #cooling-cells = <2>; dynamic-power-coefficient = <277>; clocks = <&cpg CPG_CORE R8A774E1_CLK_Z2>; @@ -194,6 +199,7 @@ power-domains = <&sysc R8A774E1_PD_CA53_CPU1>; next-level-cache = <&L2_CA53>; enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_1>; clocks = <&cpg CPG_CORE R8A774E1_CLK_Z2>; operating-points-v2 = <&cluster1_opp>; capacity-dmips-mhz = <535>; @@ -206,6 +212,7 @@ power-domains = <&sysc R8A774E1_PD_CA53_CPU2>; next-level-cache = <&L2_CA53>; enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_1>; clocks = <&cpg CPG_CORE R8A774E1_CLK_Z2>; operating-points-v2 = <&cluster1_opp>; capacity-dmips-mhz = <535>; @@ -218,6 +225,7 @@ power-domains = <&sysc R8A774E1_PD_CA53_CPU3>; next-level-cache = <&L2_CA53>; enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_1>; clocks = <&cpg CPG_CORE R8A774E1_CLK_Z2>; operating-points-v2 = <&cluster1_opp>; capacity-dmips-mhz = <535>; @@ -236,6 +244,28 @@ cache-unified; cache-level = <2>; }; + + idle-states { + entry-method = "psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010000>; + local-timer-stop; + entry-latency-us = <400>; + exit-latency-us = <500>; + min-residency-us = <4000>; + }; + + CPU_SLEEP_1: cpu-sleep-1 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010000>; + local-timer-stop; + entry-latency-us = <700>; + exit-latency-us = <700>; + min-residency-us = <5000>; + }; + }; }; extal_clk: extal { @@ -427,7 +457,7 @@ resets = <&cpg 905>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a774e1"; reg = <0 0xe6060000 0 0x50c>; }; @@ -838,18 +868,61 @@ }; hsusb: usb@e6590000 { + compatible = "renesas,usbhs-r8a774e1", + "renesas,rcar-gen3-usbhs"; reg = <0 0xe6590000 0 0x200>; + interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 704>, <&cpg CPG_MOD 703>; + dmas = <&usb_dmac0 0>, <&usb_dmac0 1>, + <&usb_dmac1 0>, <&usb_dmac1 1>; + dma-names = "ch0", "ch1", "ch2", "ch3"; + renesas,buswait = <11>; + phys = <&usb2_phy0 3>; + phy-names = "usb"; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 704>, <&cpg 703>; status = "disabled"; + }; - /* placeholder */ + usb_dmac0: dma-controller@e65a0000 { + compatible = "renesas,r8a774e1-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65a0000 0 0x100>; + interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 330>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 330>; + #dma-cells = <1>; + dma-channels = <2>; + }; + + usb_dmac1: dma-controller@e65b0000 { + compatible = "renesas,r8a774e1-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65b0000 0 0x100>; + interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 331>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 331>; + #dma-cells = <1>; + dma-channels = <2>; }; usb3_phy0: usb-phy@e65ee000 { + compatible = "renesas,r8a774e1-usb3-phy", + "renesas,rcar-gen3-usb3-phy"; reg = <0 0xe65ee000 0 0x90>; + clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>, + <&usb_extal_clk>; + clock-names = "usb3-if", "usb3s_clk", "usb_extal"; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 328>; #phy-cells = <0>; status = "disabled"; - - /* placeholder */ }; dmac0: dma-controller@e6700000 { @@ -1203,11 +1276,73 @@ }; pwm0: pwm@e6e30000 { + compatible = "renesas,pwm-r8a774e1", "renesas,pwm-rcar"; reg = <0 0xe6e30000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 523>; #pwm-cells = <2>; status = "disabled"; + }; - /* placeholder */ + pwm1: pwm@e6e31000 { + compatible = "renesas,pwm-r8a774e1", "renesas,pwm-rcar"; + reg = <0 0xe6e31000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 523>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm2: pwm@e6e32000 { + compatible = "renesas,pwm-r8a774e1", "renesas,pwm-rcar"; + reg = <0 0xe6e32000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 523>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm3: pwm@e6e33000 { + compatible = "renesas,pwm-r8a774e1", "renesas,pwm-rcar"; + reg = <0 0xe6e33000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 523>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm4: pwm@e6e34000 { + compatible = "renesas,pwm-r8a774e1", "renesas,pwm-rcar"; + reg = <0 0xe6e34000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 523>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm5: pwm@e6e35000 { + compatible = "renesas,pwm-r8a774e1", "renesas,pwm-rcar"; + reg = <0 0xe6e35000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 523>; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm6: pwm@e6e36000 { + compatible = "renesas,pwm-r8a774e1", "renesas,pwm-rcar"; + reg = <0 0xe6e36000 0 0x8>; + clocks = <&cpg CPG_MOD 523>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 523>; + #pwm-cells = <2>; + status = "disabled"; }; scif0: serial@e6e60000 { @@ -1372,7 +1507,260 @@ status = "disabled"; }; + vin0: video@e6ef0000 { + compatible = "renesas,vin-r8a774e1"; + reg = <0 0xe6ef0000 0 0x1000>; + interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 811>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 811>; + renesas,id = <0>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + + vin0csi20: endpoint@0 { + reg = <0>; + remote-endpoint = <&csi20vin0>; + }; + vin0csi40: endpoint@2 { + reg = <2>; + remote-endpoint = <&csi40vin0>; + }; + }; + }; + }; + + vin1: video@e6ef1000 { + compatible = "renesas,vin-r8a774e1"; + reg = <0 0xe6ef1000 0 0x1000>; + interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 810>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 810>; + renesas,id = <1>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + + vin1csi20: endpoint@0 { + reg = <0>; + remote-endpoint = <&csi20vin1>; + }; + vin1csi40: endpoint@2 { + reg = <2>; + remote-endpoint = <&csi40vin1>; + }; + }; + }; + }; + + vin2: video@e6ef2000 { + compatible = "renesas,vin-r8a774e1"; + reg = <0 0xe6ef2000 0 0x1000>; + interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 809>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 809>; + renesas,id = <2>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + + vin2csi20: endpoint@0 { + reg = <0>; + remote-endpoint = <&csi20vin2>; + }; + vin2csi40: endpoint@2 { + reg = <2>; + remote-endpoint = <&csi40vin2>; + }; + }; + }; + }; + + vin3: video@e6ef3000 { + compatible = "renesas,vin-r8a774e1"; + reg = <0 0xe6ef3000 0 0x1000>; + interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 808>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 808>; + renesas,id = <3>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + + vin3csi20: endpoint@0 { + reg = <0>; + remote-endpoint = <&csi20vin3>; + }; + vin3csi40: endpoint@2 { + reg = <2>; + remote-endpoint = <&csi40vin3>; + }; + }; + }; + }; + + vin4: video@e6ef4000 { + compatible = "renesas,vin-r8a774e1"; + reg = <0 0xe6ef4000 0 0x1000>; + interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 807>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 807>; + renesas,id = <4>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + + vin4csi20: endpoint@0 { + reg = <0>; + remote-endpoint = <&csi20vin4>; + }; + }; + }; + }; + + vin5: video@e6ef5000 { + compatible = "renesas,vin-r8a774e1"; + reg = <0 0xe6ef5000 0 0x1000>; + interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 806>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 806>; + renesas,id = <5>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + + vin5csi20: endpoint@0 { + reg = <0>; + remote-endpoint = <&csi20vin5>; + }; + }; + }; + }; + + vin6: video@e6ef6000 { + compatible = "renesas,vin-r8a774e1"; + reg = <0 0xe6ef6000 0 0x1000>; + interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 805>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 805>; + renesas,id = <6>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + + vin6csi20: endpoint@0 { + reg = <0>; + remote-endpoint = <&csi20vin6>; + }; + }; + }; + }; + + vin7: video@e6ef7000 { + compatible = "renesas,vin-r8a774e1"; + reg = <0 0xe6ef7000 0 0x1000>; + interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 804>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 804>; + renesas,id = <7>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + + vin7csi20: endpoint@0 { + reg = <0>; + remote-endpoint = <&csi20vin7>; + }; + }; + }; + }; + rcar_sound: sound@ec500000 { + /* + * #sound-dai-cells is required + * + * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>; + * Multi DAI : #sound-dai-cells = <1>; <&rcar_sound N>; + */ + /* + * #clock-cells is required for audio_clkout0/1/2/3 + * + * clkout : #clock-cells = <0>; <&rcar_sound>; + * clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>; + */ + compatible = "renesas,rcar_sound-r8a774e1", "renesas,rcar_sound-gen3"; reg = <0 0xec500000 0 0x1000>, /* SCU */ <0 0xec5a0000 0 0x100>, /* ADG */ <0 0xec540000 0 0x1000>, /* SSIU */ @@ -1380,71 +1768,569 @@ <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/ reg-names = "scu", "adg", "ssiu", "ssi", "audmapp"; + clocks = <&cpg CPG_MOD 1005>, + <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>, + <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>, + <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>, + <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>, + <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>, + <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>, + <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>, + <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>, + <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>, + <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>, + <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, + <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, + <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>, + <&audio_clk_a>, <&audio_clk_b>, + <&audio_clk_c>, + <&cpg CPG_CORE R8A774E1_CLK_S0D4>; + clock-names = "ssi-all", + "ssi.9", "ssi.8", "ssi.7", "ssi.6", + "ssi.5", "ssi.4", "ssi.3", "ssi.2", + "ssi.1", "ssi.0", + "src.9", "src.8", "src.7", "src.6", + "src.5", "src.4", "src.3", "src.2", + "src.1", "src.0", + "mix.1", "mix.0", + "ctu.1", "ctu.0", + "dvc.0", "dvc.1", + "clk_a", "clk_b", "clk_c", "clk_i"; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 1005>, + <&cpg 1006>, <&cpg 1007>, + <&cpg 1008>, <&cpg 1009>, + <&cpg 1010>, <&cpg 1011>, + <&cpg 1012>, <&cpg 1013>, + <&cpg 1014>, <&cpg 1015>; + reset-names = "ssi-all", + "ssi.9", "ssi.8", "ssi.7", "ssi.6", + "ssi.5", "ssi.4", "ssi.3", "ssi.2", + "ssi.1", "ssi.0"; status = "disabled"; - /* placeholder */ + rcar_sound,dvc { + dvc0: dvc-0 { + dmas = <&audma1 0xbc>; + dma-names = "tx"; + }; + dvc1: dvc-1 { + dmas = <&audma1 0xbe>; + dma-names = "tx"; + }; + }; + + rcar_sound,mix { + mix0: mix-0 { }; + mix1: mix-1 { }; + }; + + rcar_sound,ctu { + ctu00: ctu-0 { }; + ctu01: ctu-1 { }; + ctu02: ctu-2 { }; + ctu03: ctu-3 { }; + ctu10: ctu-4 { }; + ctu11: ctu-5 { }; + ctu12: ctu-6 { }; + ctu13: ctu-7 { }; + }; + + rcar_sound,src { + src0: src-0 { + interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x85>, <&audma1 0x9a>; + dma-names = "rx", "tx"; + }; + src1: src-1 { + interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x87>, <&audma1 0x9c>; + dma-names = "rx", "tx"; + }; + src2: src-2 { + interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x89>, <&audma1 0x9e>; + dma-names = "rx", "tx"; + }; + src3: src-3 { + interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8b>, <&audma1 0xa0>; + dma-names = "rx", "tx"; + }; + src4: src-4 { + interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8d>, <&audma1 0xb0>; + dma-names = "rx", "tx"; + }; + src5: src-5 { + interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8f>, <&audma1 0xb2>; + dma-names = "rx", "tx"; + }; + src6: src-6 { + interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x91>, <&audma1 0xb4>; + dma-names = "rx", "tx"; + }; + src7: src-7 { + interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x93>, <&audma1 0xb6>; + dma-names = "rx", "tx"; + }; + src8: src-8 { + interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x95>, <&audma1 0xb8>; + dma-names = "rx", "tx"; + }; + src9: src-9 { + interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x97>, <&audma1 0xba>; + dma-names = "rx", "tx"; + }; + }; + + rcar_sound,ssiu { + ssiu00: ssiu-0 { + dmas = <&audma0 0x15>, <&audma1 0x16>; + dma-names = "rx", "tx"; + }; + ssiu01: ssiu-1 { + dmas = <&audma0 0x35>, <&audma1 0x36>; + dma-names = "rx", "tx"; + }; + ssiu02: ssiu-2 { + dmas = <&audma0 0x37>, <&audma1 0x38>; + dma-names = "rx", "tx"; + }; + ssiu03: ssiu-3 { + dmas = <&audma0 0x47>, <&audma1 0x48>; + dma-names = "rx", "tx"; + }; + ssiu04: ssiu-4 { + dmas = <&audma0 0x3F>, <&audma1 0x40>; + dma-names = "rx", "tx"; + }; + ssiu05: ssiu-5 { + dmas = <&audma0 0x43>, <&audma1 0x44>; + dma-names = "rx", "tx"; + }; + ssiu06: ssiu-6 { + dmas = <&audma0 0x4F>, <&audma1 0x50>; + dma-names = "rx", "tx"; + }; + ssiu07: ssiu-7 { + dmas = <&audma0 0x53>, <&audma1 0x54>; + dma-names = "rx", "tx"; + }; + ssiu10: ssiu-8 { + dmas = <&audma0 0x49>, <&audma1 0x4a>; + dma-names = "rx", "tx"; + }; + ssiu11: ssiu-9 { + dmas = <&audma0 0x4B>, <&audma1 0x4C>; + dma-names = "rx", "tx"; + }; + ssiu12: ssiu-10 { + dmas = <&audma0 0x57>, <&audma1 0x58>; + dma-names = "rx", "tx"; + }; + ssiu13: ssiu-11 { + dmas = <&audma0 0x59>, <&audma1 0x5A>; + dma-names = "rx", "tx"; + }; + ssiu14: ssiu-12 { + dmas = <&audma0 0x5F>, <&audma1 0x60>; + dma-names = "rx", "tx"; + }; + ssiu15: ssiu-13 { + dmas = <&audma0 0xC3>, <&audma1 0xC4>; + dma-names = "rx", "tx"; + }; + ssiu16: ssiu-14 { + dmas = <&audma0 0xC7>, <&audma1 0xC8>; + dma-names = "rx", "tx"; + }; + ssiu17: ssiu-15 { + dmas = <&audma0 0xCB>, <&audma1 0xCC>; + dma-names = "rx", "tx"; + }; + ssiu20: ssiu-16 { + dmas = <&audma0 0x63>, <&audma1 0x64>; + dma-names = "rx", "tx"; + }; + ssiu21: ssiu-17 { + dmas = <&audma0 0x67>, <&audma1 0x68>; + dma-names = "rx", "tx"; + }; + ssiu22: ssiu-18 { + dmas = <&audma0 0x6B>, <&audma1 0x6C>; + dma-names = "rx", "tx"; + }; + ssiu23: ssiu-19 { + dmas = <&audma0 0x6D>, <&audma1 0x6E>; + dma-names = "rx", "tx"; + }; + ssiu24: ssiu-20 { + dmas = <&audma0 0xCF>, <&audma1 0xCE>; + dma-names = "rx", "tx"; + }; + ssiu25: ssiu-21 { + dmas = <&audma0 0xEB>, <&audma1 0xEC>; + dma-names = "rx", "tx"; + }; + ssiu26: ssiu-22 { + dmas = <&audma0 0xED>, <&audma1 0xEE>; + dma-names = "rx", "tx"; + }; + ssiu27: ssiu-23 { + dmas = <&audma0 0xEF>, <&audma1 0xF0>; + dma-names = "rx", "tx"; + }; + ssiu30: ssiu-24 { + dmas = <&audma0 0x6f>, <&audma1 0x70>; + dma-names = "rx", "tx"; + }; + ssiu31: ssiu-25 { + dmas = <&audma0 0x21>, <&audma1 0x22>; + dma-names = "rx", "tx"; + }; + ssiu32: ssiu-26 { + dmas = <&audma0 0x23>, <&audma1 0x24>; + dma-names = "rx", "tx"; + }; + ssiu33: ssiu-27 { + dmas = <&audma0 0x25>, <&audma1 0x26>; + dma-names = "rx", "tx"; + }; + ssiu34: ssiu-28 { + dmas = <&audma0 0x27>, <&audma1 0x28>; + dma-names = "rx", "tx"; + }; + ssiu35: ssiu-29 { + dmas = <&audma0 0x29>, <&audma1 0x2A>; + dma-names = "rx", "tx"; + }; + ssiu36: ssiu-30 { + dmas = <&audma0 0x2B>, <&audma1 0x2C>; + dma-names = "rx", "tx"; + }; + ssiu37: ssiu-31 { + dmas = <&audma0 0x2D>, <&audma1 0x2E>; + dma-names = "rx", "tx"; + }; + ssiu40: ssiu-32 { + dmas = <&audma0 0x71>, <&audma1 0x72>; + dma-names = "rx", "tx"; + }; + ssiu41: ssiu-33 { + dmas = <&audma0 0x17>, <&audma1 0x18>; + dma-names = "rx", "tx"; + }; + ssiu42: ssiu-34 { + dmas = <&audma0 0x19>, <&audma1 0x1A>; + dma-names = "rx", "tx"; + }; + ssiu43: ssiu-35 { + dmas = <&audma0 0x1B>, <&audma1 0x1C>; + dma-names = "rx", "tx"; + }; + ssiu44: ssiu-36 { + dmas = <&audma0 0x1D>, <&audma1 0x1E>; + dma-names = "rx", "tx"; + }; + ssiu45: ssiu-37 { + dmas = <&audma0 0x1F>, <&audma1 0x20>; + dma-names = "rx", "tx"; + }; + ssiu46: ssiu-38 { + dmas = <&audma0 0x31>, <&audma1 0x32>; + dma-names = "rx", "tx"; + }; + ssiu47: ssiu-39 { + dmas = <&audma0 0x33>, <&audma1 0x34>; + dma-names = "rx", "tx"; + }; + ssiu50: ssiu-40 { + dmas = <&audma0 0x73>, <&audma1 0x74>; + dma-names = "rx", "tx"; + }; + ssiu60: ssiu-41 { + dmas = <&audma0 0x75>, <&audma1 0x76>; + dma-names = "rx", "tx"; + }; + ssiu70: ssiu-42 { + dmas = <&audma0 0x79>, <&audma1 0x7a>; + dma-names = "rx", "tx"; + }; + ssiu80: ssiu-43 { + dmas = <&audma0 0x7b>, <&audma1 0x7c>; + dma-names = "rx", "tx"; + }; + ssiu90: ssiu-44 { + dmas = <&audma0 0x7d>, <&audma1 0x7e>; + dma-names = "rx", "tx"; + }; + ssiu91: ssiu-45 { + dmas = <&audma0 0x7F>, <&audma1 0x80>; + dma-names = "rx", "tx"; + }; + ssiu92: ssiu-46 { + dmas = <&audma0 0x81>, <&audma1 0x82>; + dma-names = "rx", "tx"; + }; + ssiu93: ssiu-47 { + dmas = <&audma0 0x83>, <&audma1 0x84>; + dma-names = "rx", "tx"; + }; + ssiu94: ssiu-48 { + dmas = <&audma0 0xA3>, <&audma1 0xA4>; + dma-names = "rx", "tx"; + }; + ssiu95: ssiu-49 { + dmas = <&audma0 0xA5>, <&audma1 0xA6>; + dma-names = "rx", "tx"; + }; + ssiu96: ssiu-50 { + dmas = <&audma0 0xA7>, <&audma1 0xA8>; + dma-names = "rx", "tx"; + }; + ssiu97: ssiu-51 { + dmas = <&audma0 0xA9>, <&audma1 0xAA>; + dma-names = "rx", "tx"; + }; + }; rcar_sound,ssi { + ssi0: ssi-0 { + interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x01>, <&audma1 0x02>; + dma-names = "rx", "tx"; + }; + ssi1: ssi-1 { + interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x03>, <&audma1 0x04>; + dma-names = "rx", "tx"; + }; ssi2: ssi-2 { - /* placeholder */ + interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x05>, <&audma1 0x06>; + dma-names = "rx", "tx"; + }; + ssi3: ssi-3 { + interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x07>, <&audma1 0x08>; + dma-names = "rx", "tx"; + }; + ssi4: ssi-4 { + interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x09>, <&audma1 0x0a>; + dma-names = "rx", "tx"; + }; + ssi5: ssi-5 { + interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0b>, <&audma1 0x0c>; + dma-names = "rx", "tx"; + }; + ssi6: ssi-6 { + interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0d>, <&audma1 0x0e>; + dma-names = "rx", "tx"; + }; + ssi7: ssi-7 { + interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0f>, <&audma1 0x10>; + dma-names = "rx", "tx"; + }; + ssi8: ssi-8 { + interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x11>, <&audma1 0x12>; + dma-names = "rx", "tx"; + }; + ssi9: ssi-9 { + interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x13>, <&audma1 0x14>; + dma-names = "rx", "tx"; }; }; }; + audma0: dma-controller@ec700000 { + compatible = "renesas,dmac-r8a774e1", + "renesas,rcar-dmac"; + reg = <0 0xec700000 0 0x10000>; + interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 502>; + clock-names = "fck"; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 502>; + #dma-cells = <1>; + dma-channels = <16>; + iommus = <&ipmmu_mp0 0>, <&ipmmu_mp0 1>, + <&ipmmu_mp0 2>, <&ipmmu_mp0 3>, + <&ipmmu_mp0 4>, <&ipmmu_mp0 5>, + <&ipmmu_mp0 6>, <&ipmmu_mp0 7>, + <&ipmmu_mp0 8>, <&ipmmu_mp0 9>, + <&ipmmu_mp0 10>, <&ipmmu_mp0 11>, + <&ipmmu_mp0 12>, <&ipmmu_mp0 13>, + <&ipmmu_mp0 14>, <&ipmmu_mp0 15>; + }; + + audma1: dma-controller@ec720000 { + compatible = "renesas,dmac-r8a774e1", + "renesas,rcar-dmac"; + reg = <0 0xec720000 0 0x10000>; + interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 501>; + clock-names = "fck"; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 501>; + #dma-cells = <1>; + dma-channels = <16>; + iommus = <&ipmmu_mp0 16>, <&ipmmu_mp0 17>, + <&ipmmu_mp0 18>, <&ipmmu_mp0 19>, + <&ipmmu_mp0 20>, <&ipmmu_mp0 21>, + <&ipmmu_mp0 22>, <&ipmmu_mp0 23>, + <&ipmmu_mp0 24>, <&ipmmu_mp0 25>, + <&ipmmu_mp0 26>, <&ipmmu_mp0 27>, + <&ipmmu_mp0 28>, <&ipmmu_mp0 29>, + <&ipmmu_mp0 30>, <&ipmmu_mp0 31>; + }; + xhci0: usb@ee000000 { + compatible = "renesas,xhci-r8a774e1", + "renesas,rcar-gen3-xhci"; reg = <0 0xee000000 0 0xc00>; + interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 328>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 328>; status = "disabled"; - - /* placeholder */ }; usb3_peri0: usb@ee020000 { + compatible = "renesas,r8a774e1-usb3-peri", + "renesas,rcar-gen3-usb3-peri"; reg = <0 0xee020000 0 0x400>; + interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 328>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 328>; status = "disabled"; - - /* placeholder */ }; ohci0: usb@ee080000 { + compatible = "generic-ohci"; reg = <0 0xee080000 0 0x100>; + interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>; + phys = <&usb2_phy0 1>; + phy-names = "usb"; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 703>, <&cpg 704>; status = "disabled"; - - /* placeholder */ }; ohci1: usb@ee0a0000 { + compatible = "generic-ohci"; reg = <0 0xee0a0000 0 0x100>; + interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 702>; + phys = <&usb2_phy1 1>; + phy-names = "usb"; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 702>; status = "disabled"; - - /* placeholder */ }; ehci0: usb@ee080100 { + compatible = "generic-ehci"; reg = <0 0xee080100 0 0x100>; + interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>; + phys = <&usb2_phy0 2>; + phy-names = "usb"; + companion = <&ohci0>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 703>, <&cpg 704>; status = "disabled"; - - /* placeholder */ }; ehci1: usb@ee0a0100 { + compatible = "generic-ehci"; reg = <0 0xee0a0100 0 0x100>; + interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 702>; + phys = <&usb2_phy1 2>; + phy-names = "usb"; + companion = <&ohci1>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 702>; status = "disabled"; - - /* placeholder */ }; usb2_phy0: usb-phy@ee080200 { + compatible = "renesas,usb2-phy-r8a774e1", + "renesas,rcar-gen3-usb2-phy"; reg = <0 0xee080200 0 0x700>; + interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 703>, <&cpg 704>; + #phy-cells = <1>; status = "disabled"; - - /* placeholder */ }; usb2_phy1: usb-phy@ee0a0200 { + compatible = "renesas,usb2-phy-r8a774e1", + "renesas,rcar-gen3-usb2-phy"; reg = <0 0xee0a0200 0 0x700>; + clocks = <&cpg CPG_MOD 702>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 702>; + #phy-cells = <1>; status = "disabled"; - - /* placeholder */ }; sdhi0: mmc@ee100000 { @@ -1499,6 +2385,18 @@ status = "disabled"; }; + sata: sata@ee300000 { + compatible = "renesas,sata-r8a774e1", + "renesas,rcar-gen3-sata"; + reg = <0 0xee300000 0 0x200000>; + interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 815>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 815>; + iommus = <&ipmmu_hc 2>; + status = "disabled"; + }; + gic: interrupt-controller@f1010000 { compatible = "arm,gic-400"; #interrupt-cells = <3>; @@ -1517,53 +2415,435 @@ }; pciec0: pcie@fe000000 { + compatible = "renesas,pcie-r8a774e1", + "renesas,pcie-rcar-gen3"; reg = <0 0xfe000000 0 0x80000>; #address-cells = <3>; #size-cells = <2>; + bus-range = <0x00 0xff>; + device_type = "pci"; + ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000>, + <0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000>, + <0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>, + <0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>; + /* Map all possible DDR as inbound ranges */ + dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>; + interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>; + clock-names = "pcie", "pcie_bus"; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 319>; + status = "disabled"; + }; + + pciec1: pcie@ee800000 { + compatible = "renesas,pcie-r8a774e1", + "renesas,pcie-rcar-gen3"; + reg = <0 0xee800000 0 0x80000>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x00 0xff>; + device_type = "pci"; + ranges = <0x01000000 0 0x00000000 0 0xee900000 0 0x00100000>, + <0x02000000 0 0xeea00000 0 0xeea00000 0 0x00200000>, + <0x02000000 0 0xc0000000 0 0xc0000000 0 0x08000000>, + <0x42000000 0 0xc8000000 0 0xc8000000 0 0x08000000>; + /* Map all possible DDR as inbound ranges */ + dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>; + interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 318>, <&pcie_bus_clk>; + clock-names = "pcie", "pcie_bus"; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 318>; + status = "disabled"; + }; + + pciec0_ep: pcie-ep@fe000000 { + compatible = "renesas,r8a774e1-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 R8A774E1_PD_ALWAYS_ON>; + status = "disabled"; + }; + + pciec1_ep: pcie-ep@ee800000 { + compatible = "renesas,r8a774e1-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 R8A774E1_PD_ALWAYS_ON>; status = "disabled"; + }; + + vspbc: vsp@fe920000 { + compatible = "renesas,vsp2"; + reg = <0 0xfe920000 0 0x8000>; + interrupts = <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 624>; + power-domains = <&sysc R8A774E1_PD_A3VP>; + resets = <&cpg 624>; + + renesas,fcp = <&fcpvb1>; + }; + + vspbd: vsp@fe960000 { + compatible = "renesas,vsp2"; + reg = <0 0xfe960000 0 0x8000>; + interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 626>; + power-domains = <&sysc R8A774E1_PD_A3VP>; + resets = <&cpg 626>; + + renesas,fcp = <&fcpvb0>; + }; + + vspd0: vsp@fea20000 { + compatible = "renesas,vsp2"; + reg = <0 0xfea20000 0 0x5000>; + interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 623>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 623>; + + renesas,fcp = <&fcpvd0>; + }; + + vspd1: vsp@fea28000 { + compatible = "renesas,vsp2"; + reg = <0 0xfea28000 0 0x5000>; + interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 622>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 622>; + + renesas,fcp = <&fcpvd1>; + }; + + vspi0: vsp@fe9a0000 { + compatible = "renesas,vsp2"; + reg = <0 0xfe9a0000 0 0x8000>; + interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 631>; + power-domains = <&sysc R8A774E1_PD_A3VP>; + resets = <&cpg 631>; + + renesas,fcp = <&fcpvi0>; + }; + + vspi1: vsp@fe9b0000 { + compatible = "renesas,vsp2"; + reg = <0 0xfe9b0000 0 0x8000>; + interrupts = <GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 630>; + power-domains = <&sysc R8A774E1_PD_A3VP>; + resets = <&cpg 630>; + + renesas,fcp = <&fcpvi1>; + }; + + fdp1@fe940000 { + compatible = "renesas,fdp1"; + reg = <0 0xfe940000 0 0x2400>; + interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 119>; + power-domains = <&sysc R8A774E1_PD_A3VP>; + resets = <&cpg 119>; + renesas,fcp = <&fcpf0>; + }; + + fdp1@fe944000 { + compatible = "renesas,fdp1"; + reg = <0 0xfe944000 0 0x2400>; + interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 118>; + power-domains = <&sysc R8A774E1_PD_A3VP>; + resets = <&cpg 118>; + renesas,fcp = <&fcpf1>; + }; + + fcpf0: fcp@fe950000 { + compatible = "renesas,fcpf"; + reg = <0 0xfe950000 0 0x200>; + clocks = <&cpg CPG_MOD 615>; + power-domains = <&sysc R8A774E1_PD_A3VP>; + resets = <&cpg 615>; + }; + + fcpf1: fcp@fe951000 { + compatible = "renesas,fcpf"; + reg = <0 0xfe951000 0 0x200>; + clocks = <&cpg CPG_MOD 614>; + power-domains = <&sysc R8A774E1_PD_A3VP>; + resets = <&cpg 614>; + }; + + fcpvb0: fcp@fe96f000 { + compatible = "renesas,fcpv"; + reg = <0 0xfe96f000 0 0x200>; + clocks = <&cpg CPG_MOD 607>; + power-domains = <&sysc R8A774E1_PD_A3VP>; + resets = <&cpg 607>; + }; + + fcpvb1: fcp@fe92f000 { + compatible = "renesas,fcpv"; + reg = <0 0xfe92f000 0 0x200>; + clocks = <&cpg CPG_MOD 606>; + power-domains = <&sysc R8A774E1_PD_A3VP>; + resets = <&cpg 606>; + }; + + fcpvi0: fcp@fe9af000 { + compatible = "renesas,fcpv"; + reg = <0 0xfe9af000 0 0x200>; + clocks = <&cpg CPG_MOD 611>; + power-domains = <&sysc R8A774E1_PD_A3VP>; + resets = <&cpg 611>; + }; + + fcpvi1: fcp@fe9bf000 { + compatible = "renesas,fcpv"; + reg = <0 0xfe9bf000 0 0x200>; + clocks = <&cpg CPG_MOD 610>; + power-domains = <&sysc R8A774E1_PD_A3VP>; + resets = <&cpg 610>; + }; + + fcpvd0: fcp@fea27000 { + compatible = "renesas,fcpv"; + reg = <0 0xfea27000 0 0x200>; + clocks = <&cpg CPG_MOD 603>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 603>; + }; + + fcpvd1: fcp@fea2f000 { + compatible = "renesas,fcpv"; + reg = <0 0xfea2f000 0 0x200>; + clocks = <&cpg CPG_MOD 602>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 602>; + }; + + csi20: csi2@fea80000 { + compatible = "renesas,r8a774e1-csi2"; + reg = <0 0xfea80000 0 0x10000>; + interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 714>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 714>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; - /* placeholder */ + reg = <1>; + + csi20vin0: endpoint@0 { + reg = <0>; + remote-endpoint = <&vin0csi20>; + }; + csi20vin1: endpoint@1 { + reg = <1>; + remote-endpoint = <&vin1csi20>; + }; + csi20vin2: endpoint@2 { + reg = <2>; + remote-endpoint = <&vin2csi20>; + }; + csi20vin3: endpoint@3 { + reg = <3>; + remote-endpoint = <&vin3csi20>; + }; + csi20vin4: endpoint@4 { + reg = <4>; + remote-endpoint = <&vin4csi20>; + }; + csi20vin5: endpoint@5 { + reg = <5>; + remote-endpoint = <&vin5csi20>; + }; + csi20vin6: endpoint@6 { + reg = <6>; + remote-endpoint = <&vin6csi20>; + }; + csi20vin7: endpoint@7 { + reg = <7>; + remote-endpoint = <&vin7csi20>; + }; + }; + }; + }; + + csi40: csi2@feaa0000 { + compatible = "renesas,r8a774e1-csi2"; + reg = <0 0xfeaa0000 0 0x10000>; + interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 716>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 716>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <1>; + + csi40vin0: endpoint@0 { + reg = <0>; + remote-endpoint = <&vin0csi40>; + }; + csi40vin1: endpoint@1 { + reg = <1>; + remote-endpoint = <&vin1csi40>; + }; + csi40vin2: endpoint@2 { + reg = <2>; + remote-endpoint = <&vin2csi40>; + }; + csi40vin3: endpoint@3 { + reg = <3>; + remote-endpoint = <&vin3csi40>; + }; + }; + }; }; hdmi0: hdmi@fead0000 { + compatible = "renesas,r8a774e1-hdmi", + "renesas,rcar-gen3-hdmi"; reg = <0 0xfead0000 0 0x10000>; + interrupts = <GIC_SPI 389 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 729>, + <&cpg CPG_CORE R8A774E1_CLK_HDMI>; + clock-names = "iahb", "isfr"; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 729>; status = "disabled"; - /* placeholder */ - ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; + dw_hdmi0_in: endpoint { + remote-endpoint = <&du_out_hdmi0>; + }; }; port@1 { reg = <1>; }; port@2 { + /* HDMI sound */ reg = <2>; }; }; }; du: display@feb00000 { + compatible = "renesas,du-r8a774e1"; reg = <0 0xfeb00000 0 0x80000>; + interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 721>; + clock-names = "du.0", "du.1", "du.3"; + resets = <&cpg 724>, <&cpg 722>; + reset-names = "du.0", "du.3"; status = "disabled"; - /* placeholder */ + renesas,vsps = <&vspd0 0>, <&vspd1 0>, <&vspd0 1>; + ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; + du_out_rgb: endpoint { + }; }; port@1 { reg = <1>; + du_out_hdmi0: endpoint { + remote-endpoint = <&dw_hdmi0_in>; + }; }; port@2 { reg = <2>; + du_out_lvds0: endpoint { + remote-endpoint = <&lvds0_in>; + }; + }; + }; + }; + + lvds0: lvds@feb90000 { + compatible = "renesas,r8a774e1-lvds"; + reg = <0 0xfeb90000 0 0x14>; + clocks = <&cpg CPG_MOD 727>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 727>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + lvds0_in: endpoint { + remote-endpoint = <&du_out_lvds0>; + }; + }; + port@1 { + reg = <1>; + lvds0_out: endpoint { + }; }; }; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77951.dtsi b/arch/arm64/boot/dts/renesas/r8a77951.dtsi index 9beb8e76d923..18ce0face72b 100644 --- a/arch/arm64/boot/dts/renesas/r8a77951.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77951.dtsi @@ -490,7 +490,7 @@ resets = <&cpg 905>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a7795"; reg = <0 0xe6060000 0 0x50c>; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77960.dtsi b/arch/arm64/boot/dts/renesas/r8a77960.dtsi index 4dfb7f076787..f379c8d1511d 100644 --- a/arch/arm64/boot/dts/renesas/r8a77960.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77960.dtsi @@ -459,7 +459,7 @@ resets = <&cpg 905>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a7796"; reg = <0 0xe6060000 0 0x50c>; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77961-salvator-xs.dts b/arch/arm64/boot/dts/renesas/r8a77961-salvator-xs.dts index 2ffc7e31dd58..1e7603365106 100644 --- a/arch/arm64/boot/dts/renesas/r8a77961-salvator-xs.dts +++ b/arch/arm64/boot/dts/renesas/r8a77961-salvator-xs.dts @@ -29,3 +29,60 @@ reg = <0x6 0x00000000 0x1 0x00000000>; }; }; + +&du { + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, + <&versaclock6 1>, + <&x21_clk>, + <&versaclock6 2>; + clock-names = "du.0", "du.1", "du.2", + "dclkin.0", "dclkin.1", "dclkin.2"; +}; + +&hdmi0 { + status = "okay"; + + ports { + port@1 { + reg = <1>; + rcar_dw_hdmi0_out: endpoint { + remote-endpoint = <&hdmi0_con>; + }; + }; + port@2 { + reg = <2>; + dw_hdmi0_snd_in: endpoint { + remote-endpoint = <&rsnd_endpoint1>; + }; + }; + }; +}; + +&hdmi0_con { + remote-endpoint = <&rcar_dw_hdmi0_out>; +}; + +&rcar_sound { + ports { + /* rsnd_port0 is on salvator-common */ + rsnd_port1: port@1 { + reg = <1>; + rsnd_endpoint1: endpoint { + remote-endpoint = <&dw_hdmi0_snd_in>; + + dai-format = "i2s"; + bitclock-master = <&rsnd_endpoint1>; + frame-master = <&rsnd_endpoint1>; + + playback = <&ssi2>; + }; + }; + }; +}; + +&sound_card { + dais = <&rsnd_port0 /* ak4613 */ + &rsnd_port1>; /* HDMI0 */ +}; diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi index 542c44c7dbca..1ba30313c8b8 100644 --- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi @@ -448,7 +448,7 @@ resets = <&cpg 905>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a77961"; reg = <0 0xe6060000 0 0x50c>; }; @@ -1228,27 +1228,494 @@ }; rcar_sound: sound@ec500000 { + /* + * #sound-dai-cells is required + * + * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>; + * Multi DAI : #sound-dai-cells = <1>; <&rcar_sound N>; + */ + /* + * #clock-cells is required for audio_clkout0/1/2/3 + * + * clkout : #clock-cells = <0>; <&rcar_sound>; + * clkout0/1/2/3: #clock-cells = <1>; <&rcar_sound N>; + */ + compatible = "renesas,rcar_sound-r8a77961", "renesas,rcar_sound-gen3"; reg = <0 0xec500000 0 0x1000>, /* SCU */ <0 0xec5a0000 0 0x100>, /* ADG */ <0 0xec540000 0 0x1000>, /* SSIU */ <0 0xec541000 0 0x280>, /* SSI */ <0 0xec760000 0 0x200>; /* Audio DMAC peri peri*/ - /* placeholder */ + reg-names = "scu", "adg", "ssiu", "ssi", "audmapp"; + + clocks = <&cpg CPG_MOD 1005>, + <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>, + <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>, + <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>, + <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>, + <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>, + <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>, + <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>, + <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>, + <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>, + <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>, + <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, + <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, + <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>, + <&audio_clk_a>, <&audio_clk_b>, + <&audio_clk_c>, + <&cpg CPG_CORE R8A77961_CLK_S0D4>; + clock-names = "ssi-all", + "ssi.9", "ssi.8", "ssi.7", "ssi.6", + "ssi.5", "ssi.4", "ssi.3", "ssi.2", + "ssi.1", "ssi.0", + "src.9", "src.8", "src.7", "src.6", + "src.5", "src.4", "src.3", "src.2", + "src.1", "src.0", + "mix.1", "mix.0", + "ctu.1", "ctu.0", + "dvc.0", "dvc.1", + "clk_a", "clk_b", "clk_c", "clk_i"; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 1005>, + <&cpg 1006>, <&cpg 1007>, + <&cpg 1008>, <&cpg 1009>, + <&cpg 1010>, <&cpg 1011>, + <&cpg 1012>, <&cpg 1013>, + <&cpg 1014>, <&cpg 1015>; + reset-names = "ssi-all", + "ssi.9", "ssi.8", "ssi.7", "ssi.6", + "ssi.5", "ssi.4", "ssi.3", "ssi.2", + "ssi.1", "ssi.0"; + status = "disabled"; + + rcar_sound,ctu { + ctu00: ctu-0 { }; + ctu01: ctu-1 { }; + ctu02: ctu-2 { }; + ctu03: ctu-3 { }; + ctu10: ctu-4 { }; + ctu11: ctu-5 { }; + ctu12: ctu-6 { }; + ctu13: ctu-7 { }; + }; + rcar_sound,dvc { - dvc0: dvc-0 { }; - dvc1: dvc-1 { }; + dvc0: dvc-0 { + dmas = <&audma1 0xbc>; + dma-names = "tx"; + }; + dvc1: dvc-1 { + dmas = <&audma1 0xbe>; + dma-names = "tx"; + }; + }; + + rcar_sound,mix { + mix0: mix-0 { }; + mix1: mix-1 { }; }; rcar_sound,src { - src0: src-0 { }; - src1: src-1 { }; + src0: src-0 { + interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x85>, <&audma1 0x9a>; + dma-names = "rx", "tx"; + }; + src1: src-1 { + interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x87>, <&audma1 0x9c>; + dma-names = "rx", "tx"; + }; + src2: src-2 { + interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x89>, <&audma1 0x9e>; + dma-names = "rx", "tx"; + }; + src3: src-3 { + interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8b>, <&audma1 0xa0>; + dma-names = "rx", "tx"; + }; + src4: src-4 { + interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8d>, <&audma1 0xb0>; + dma-names = "rx", "tx"; + }; + src5: src-5 { + interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x8f>, <&audma1 0xb2>; + dma-names = "rx", "tx"; + }; + src6: src-6 { + interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x91>, <&audma1 0xb4>; + dma-names = "rx", "tx"; + }; + src7: src-7 { + interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x93>, <&audma1 0xb6>; + dma-names = "rx", "tx"; + }; + src8: src-8 { + interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x95>, <&audma1 0xb8>; + dma-names = "rx", "tx"; + }; + src9: src-9 { + interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x97>, <&audma1 0xba>; + dma-names = "rx", "tx"; + }; }; rcar_sound,ssi { - ssi0: ssi-0 { }; - ssi1: ssi-1 { }; - ssi2: ssi-2 { }; + ssi0: ssi-0 { + interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x01>, <&audma1 0x02>; + dma-names = "rx", "tx"; + }; + ssi1: ssi-1 { + interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x03>, <&audma1 0x04>; + dma-names = "rx", "tx"; + }; + ssi2: ssi-2 { + interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x05>, <&audma1 0x06>; + dma-names = "rx", "tx"; + }; + ssi3: ssi-3 { + interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x07>, <&audma1 0x08>; + dma-names = "rx", "tx"; + }; + ssi4: ssi-4 { + interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x09>, <&audma1 0x0a>; + dma-names = "rx", "tx"; + }; + ssi5: ssi-5 { + interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0b>, <&audma1 0x0c>; + dma-names = "rx", "tx"; + }; + ssi6: ssi-6 { + interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0d>, <&audma1 0x0e>; + dma-names = "rx", "tx"; + }; + ssi7: ssi-7 { + interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x0f>, <&audma1 0x10>; + dma-names = "rx", "tx"; + }; + ssi8: ssi-8 { + interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x11>, <&audma1 0x12>; + dma-names = "rx", "tx"; + }; + ssi9: ssi-9 { + interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&audma0 0x13>, <&audma1 0x14>; + dma-names = "rx", "tx"; + }; }; + + rcar_sound,ssiu { + ssiu00: ssiu-0 { + dmas = <&audma0 0x15>, <&audma1 0x16>; + dma-names = "rx", "tx"; + }; + ssiu01: ssiu-1 { + dmas = <&audma0 0x35>, <&audma1 0x36>; + dma-names = "rx", "tx"; + }; + ssiu02: ssiu-2 { + dmas = <&audma0 0x37>, <&audma1 0x38>; + dma-names = "rx", "tx"; + }; + ssiu03: ssiu-3 { + dmas = <&audma0 0x47>, <&audma1 0x48>; + dma-names = "rx", "tx"; + }; + ssiu04: ssiu-4 { + dmas = <&audma0 0x3F>, <&audma1 0x40>; + dma-names = "rx", "tx"; + }; + ssiu05: ssiu-5 { + dmas = <&audma0 0x43>, <&audma1 0x44>; + dma-names = "rx", "tx"; + }; + ssiu06: ssiu-6 { + dmas = <&audma0 0x4F>, <&audma1 0x50>; + dma-names = "rx", "tx"; + }; + ssiu07: ssiu-7 { + dmas = <&audma0 0x53>, <&audma1 0x54>; + dma-names = "rx", "tx"; + }; + ssiu10: ssiu-8 { + dmas = <&audma0 0x49>, <&audma1 0x4a>; + dma-names = "rx", "tx"; + }; + ssiu11: ssiu-9 { + dmas = <&audma0 0x4B>, <&audma1 0x4C>; + dma-names = "rx", "tx"; + }; + ssiu12: ssiu-10 { + dmas = <&audma0 0x57>, <&audma1 0x58>; + dma-names = "rx", "tx"; + }; + ssiu13: ssiu-11 { + dmas = <&audma0 0x59>, <&audma1 0x5A>; + dma-names = "rx", "tx"; + }; + ssiu14: ssiu-12 { + dmas = <&audma0 0x5F>, <&audma1 0x60>; + dma-names = "rx", "tx"; + }; + ssiu15: ssiu-13 { + dmas = <&audma0 0xC3>, <&audma1 0xC4>; + dma-names = "rx", "tx"; + }; + ssiu16: ssiu-14 { + dmas = <&audma0 0xC7>, <&audma1 0xC8>; + dma-names = "rx", "tx"; + }; + ssiu17: ssiu-15 { + dmas = <&audma0 0xCB>, <&audma1 0xCC>; + dma-names = "rx", "tx"; + }; + ssiu20: ssiu-16 { + dmas = <&audma0 0x63>, <&audma1 0x64>; + dma-names = "rx", "tx"; + }; + ssiu21: ssiu-17 { + dmas = <&audma0 0x67>, <&audma1 0x68>; + dma-names = "rx", "tx"; + }; + ssiu22: ssiu-18 { + dmas = <&audma0 0x6B>, <&audma1 0x6C>; + dma-names = "rx", "tx"; + }; + ssiu23: ssiu-19 { + dmas = <&audma0 0x6D>, <&audma1 0x6E>; + dma-names = "rx", "tx"; + }; + ssiu24: ssiu-20 { + dmas = <&audma0 0xCF>, <&audma1 0xCE>; + dma-names = "rx", "tx"; + }; + ssiu25: ssiu-21 { + dmas = <&audma0 0xEB>, <&audma1 0xEC>; + dma-names = "rx", "tx"; + }; + ssiu26: ssiu-22 { + dmas = <&audma0 0xED>, <&audma1 0xEE>; + dma-names = "rx", "tx"; + }; + ssiu27: ssiu-23 { + dmas = <&audma0 0xEF>, <&audma1 0xF0>; + dma-names = "rx", "tx"; + }; + ssiu30: ssiu-24 { + dmas = <&audma0 0x6f>, <&audma1 0x70>; + dma-names = "rx", "tx"; + }; + ssiu31: ssiu-25 { + dmas = <&audma0 0x21>, <&audma1 0x22>; + dma-names = "rx", "tx"; + }; + ssiu32: ssiu-26 { + dmas = <&audma0 0x23>, <&audma1 0x24>; + dma-names = "rx", "tx"; + }; + ssiu33: ssiu-27 { + dmas = <&audma0 0x25>, <&audma1 0x26>; + dma-names = "rx", "tx"; + }; + ssiu34: ssiu-28 { + dmas = <&audma0 0x27>, <&audma1 0x28>; + dma-names = "rx", "tx"; + }; + ssiu35: ssiu-29 { + dmas = <&audma0 0x29>, <&audma1 0x2A>; + dma-names = "rx", "tx"; + }; + ssiu36: ssiu-30 { + dmas = <&audma0 0x2B>, <&audma1 0x2C>; + dma-names = "rx", "tx"; + }; + ssiu37: ssiu-31 { + dmas = <&audma0 0x2D>, <&audma1 0x2E>; + dma-names = "rx", "tx"; + }; + ssiu40: ssiu-32 { + dmas = <&audma0 0x71>, <&audma1 0x72>; + dma-names = "rx", "tx"; + }; + ssiu41: ssiu-33 { + dmas = <&audma0 0x17>, <&audma1 0x18>; + dma-names = "rx", "tx"; + }; + ssiu42: ssiu-34 { + dmas = <&audma0 0x19>, <&audma1 0x1A>; + dma-names = "rx", "tx"; + }; + ssiu43: ssiu-35 { + dmas = <&audma0 0x1B>, <&audma1 0x1C>; + dma-names = "rx", "tx"; + }; + ssiu44: ssiu-36 { + dmas = <&audma0 0x1D>, <&audma1 0x1E>; + dma-names = "rx", "tx"; + }; + ssiu45: ssiu-37 { + dmas = <&audma0 0x1F>, <&audma1 0x20>; + dma-names = "rx", "tx"; + }; + ssiu46: ssiu-38 { + dmas = <&audma0 0x31>, <&audma1 0x32>; + dma-names = "rx", "tx"; + }; + ssiu47: ssiu-39 { + dmas = <&audma0 0x33>, <&audma1 0x34>; + dma-names = "rx", "tx"; + }; + ssiu50: ssiu-40 { + dmas = <&audma0 0x73>, <&audma1 0x74>; + dma-names = "rx", "tx"; + }; + ssiu60: ssiu-41 { + dmas = <&audma0 0x75>, <&audma1 0x76>; + dma-names = "rx", "tx"; + }; + ssiu70: ssiu-42 { + dmas = <&audma0 0x79>, <&audma1 0x7a>; + dma-names = "rx", "tx"; + }; + ssiu80: ssiu-43 { + dmas = <&audma0 0x7b>, <&audma1 0x7c>; + dma-names = "rx", "tx"; + }; + ssiu90: ssiu-44 { + dmas = <&audma0 0x7d>, <&audma1 0x7e>; + dma-names = "rx", "tx"; + }; + ssiu91: ssiu-45 { + dmas = <&audma0 0x7F>, <&audma1 0x80>; + dma-names = "rx", "tx"; + }; + ssiu92: ssiu-46 { + dmas = <&audma0 0x81>, <&audma1 0x82>; + dma-names = "rx", "tx"; + }; + ssiu93: ssiu-47 { + dmas = <&audma0 0x83>, <&audma1 0x84>; + dma-names = "rx", "tx"; + }; + ssiu94: ssiu-48 { + dmas = <&audma0 0xA3>, <&audma1 0xA4>; + dma-names = "rx", "tx"; + }; + ssiu95: ssiu-49 { + dmas = <&audma0 0xA5>, <&audma1 0xA6>; + dma-names = "rx", "tx"; + }; + ssiu96: ssiu-50 { + dmas = <&audma0 0xA7>, <&audma1 0xA8>; + dma-names = "rx", "tx"; + }; + ssiu97: ssiu-51 { + dmas = <&audma0 0xA9>, <&audma1 0xAA>; + dma-names = "rx", "tx"; + }; + }; + }; + + audma0: dma-controller@ec700000 { + compatible = "renesas,dmac-r8a77961", + "renesas,rcar-dmac"; + reg = <0 0xec700000 0 0x10000>; + interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 502>; + clock-names = "fck"; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 502>; + #dma-cells = <1>; + dma-channels = <16>; + iommus = <&ipmmu_mp 0>, <&ipmmu_mp 1>, + <&ipmmu_mp 2>, <&ipmmu_mp 3>, + <&ipmmu_mp 4>, <&ipmmu_mp 5>, + <&ipmmu_mp 6>, <&ipmmu_mp 7>, + <&ipmmu_mp 8>, <&ipmmu_mp 9>, + <&ipmmu_mp 10>, <&ipmmu_mp 11>, + <&ipmmu_mp 12>, <&ipmmu_mp 13>, + <&ipmmu_mp 14>, <&ipmmu_mp 15>; + }; + + audma1: dma-controller@ec720000 { + compatible = "renesas,dmac-r8a77961", + "renesas,rcar-dmac"; + reg = <0 0xec720000 0 0x10000>; + interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 501>; + clock-names = "fck"; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 501>; + #dma-cells = <1>; + dma-channels = <16>; + iommus = <&ipmmu_mp 16>, <&ipmmu_mp 17>, + <&ipmmu_mp 18>, <&ipmmu_mp 19>, + <&ipmmu_mp 20>, <&ipmmu_mp 21>, + <&ipmmu_mp 22>, <&ipmmu_mp 23>, + <&ipmmu_mp 24>, <&ipmmu_mp 25>, + <&ipmmu_mp 26>, <&ipmmu_mp 27>, + <&ipmmu_mp 28>, <&ipmmu_mp 29>, + <&ipmmu_mp 30>, <&ipmmu_mp 31>; }; xhci0: usb@ee000000 { @@ -1465,6 +1932,113 @@ status = "disabled"; }; + fcpf0: fcp@fe950000 { + compatible = "renesas,fcpf"; + reg = <0 0xfe950000 0 0x200>; + clocks = <&cpg CPG_MOD 615>; + power-domains = <&sysc R8A77961_PD_A3VC>; + resets = <&cpg 615>; + }; + + fcpvb0: fcp@fe96f000 { + compatible = "renesas,fcpv"; + reg = <0 0xfe96f000 0 0x200>; + clocks = <&cpg CPG_MOD 607>; + power-domains = <&sysc R8A77961_PD_A3VC>; + resets = <&cpg 607>; + }; + + fcpvi0: fcp@fe9af000 { + compatible = "renesas,fcpv"; + reg = <0 0xfe9af000 0 0x200>; + clocks = <&cpg CPG_MOD 611>; + power-domains = <&sysc R8A77961_PD_A3VC>; + resets = <&cpg 611>; + iommus = <&ipmmu_vc0 19>; + }; + + fcpvd0: fcp@fea27000 { + compatible = "renesas,fcpv"; + reg = <0 0xfea27000 0 0x200>; + clocks = <&cpg CPG_MOD 603>; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 603>; + iommus = <&ipmmu_vi0 8>; + }; + + fcpvd1: fcp@fea2f000 { + compatible = "renesas,fcpv"; + reg = <0 0xfea2f000 0 0x200>; + clocks = <&cpg CPG_MOD 602>; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 602>; + iommus = <&ipmmu_vi0 9>; + }; + + fcpvd2: fcp@fea37000 { + compatible = "renesas,fcpv"; + reg = <0 0xfea37000 0 0x200>; + clocks = <&cpg CPG_MOD 601>; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 601>; + iommus = <&ipmmu_vi0 10>; + }; + + vspb: vsp@fe960000 { + compatible = "renesas,vsp2"; + reg = <0 0xfe960000 0 0x8000>; + interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 626>; + power-domains = <&sysc R8A77961_PD_A3VC>; + resets = <&cpg 626>; + + renesas,fcp = <&fcpvb0>; + }; + + vspd0: vsp@fea20000 { + compatible = "renesas,vsp2"; + reg = <0 0xfea20000 0 0x5000>; + interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 623>; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 623>; + + renesas,fcp = <&fcpvd0>; + }; + + vspd1: vsp@fea28000 { + compatible = "renesas,vsp2"; + reg = <0 0xfea28000 0 0x5000>; + interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 622>; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 622>; + + renesas,fcp = <&fcpvd1>; + }; + + vspd2: vsp@fea30000 { + compatible = "renesas,vsp2"; + reg = <0 0xfea30000 0 0x5000>; + interrupts = <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 621>; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 621>; + + renesas,fcp = <&fcpvd2>; + }; + + vspi0: vsp@fe9a0000 { + compatible = "renesas,vsp2"; + reg = <0 0xfe9a0000 0 0x8000>; + interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 631>; + power-domains = <&sysc R8A77961_PD_A3VC>; + resets = <&cpg 631>; + + renesas,fcp = <&fcpvi0>; + }; + csi20: csi2@fea80000 { reg = <0 0xfea80000 0 0x10000>; /* placeholder */ @@ -1499,14 +2073,23 @@ }; hdmi0: hdmi@fead0000 { + compatible = "renesas,r8a77961-hdmi", "renesas,rcar-gen3-hdmi"; reg = <0 0xfead0000 0 0x10000>; - /* placeholder */ + interrupts = <GIC_SPI 389 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 729>, <&cpg CPG_CORE R8A77961_CLK_HDMI>; + clock-names = "iahb", "isfr"; + power-domains = <&sysc R8A77961_PD_ALWAYS_ON>; + resets = <&cpg 729>; + status = "disabled"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; + dw_hdmi0_in: endpoint { + remote-endpoint = <&du_out_hdmi0>; + }; }; port@1 { reg = <1>; @@ -1519,8 +2102,19 @@ }; du: display@feb00000 { + compatible = "renesas,du-r8a77961"; reg = <0 0xfeb00000 0 0x70000>; - /* placeholder */ + interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>; + clock-names = "du.0", "du.1", "du.2"; + resets = <&cpg 724>, <&cpg 722>; + reset-names = "du.0", "du.2"; + + renesas,vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>; + status = "disabled"; ports { #address-cells = <1>; @@ -1534,6 +2128,7 @@ port@1 { reg = <1>; du_out_hdmi0: endpoint { + remote-endpoint = <&dw_hdmi0_in>; }; }; port@2 { diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi index fe4dc12e2bdf..c355460e5f7f 100644 --- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi @@ -329,7 +329,7 @@ resets = <&cpg 905>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a77965"; reg = <0 0xe6060000 0 0x50c>; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi index 2b9124a5ca86..baf8cc821564 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi @@ -204,7 +204,7 @@ resets = <&cpg 907>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a77970"; reg = <0 0xe6060000 0 0x504>; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi index 59f5bbd72161..d6cae90d7fd9 100644 --- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi @@ -234,7 +234,7 @@ resets = <&cpg 907>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a77980"; reg = <0 0xe6060000 0 0x50c>; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts index 7402cfa8d4e4..e0ccca2222d2 100644 --- a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts +++ b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts @@ -520,10 +520,8 @@ &pfc { avb_pins: avb { - mux { - groups = "avb_link", "avb_mii"; - function = "avb"; - }; + groups = "avb_link", "avb_mii"; + function = "avb"; }; canfd0_pins: canfd0 { diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index 1991bdc36792..33d7e657bd9c 100644 --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi @@ -282,7 +282,7 @@ resets = <&cpg 906>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a77990"; reg = <0 0xe6060000 0 0x508>; }; @@ -1192,9 +1192,8 @@ 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"; + dmas = <&dmac0 0x43>, <&dmac0 0x42>; + dma-names = "tx", "rx"; power-domains = <&sysc R8A77990_PD_ALWAYS_ON>; resets = <&cpg 210>; #address-cells = <1>; @@ -1288,6 +1287,126 @@ }; }; + drif00: rif@e6f40000 { + compatible = "renesas,r8a77990-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 R8A77990_PD_ALWAYS_ON>; + resets = <&cpg 515>; + renesas,bonding = <&drif01>; + status = "disabled"; + }; + + drif01: rif@e6f50000 { + compatible = "renesas,r8a77990-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 R8A77990_PD_ALWAYS_ON>; + resets = <&cpg 514>; + renesas,bonding = <&drif00>; + status = "disabled"; + }; + + drif10: rif@e6f60000 { + compatible = "renesas,r8a77990-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 R8A77990_PD_ALWAYS_ON>; + resets = <&cpg 513>; + renesas,bonding = <&drif11>; + status = "disabled"; + }; + + drif11: rif@e6f70000 { + compatible = "renesas,r8a77990-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 R8A77990_PD_ALWAYS_ON>; + resets = <&cpg 512>; + renesas,bonding = <&drif10>; + status = "disabled"; + }; + + drif20: rif@e6f80000 { + compatible = "renesas,r8a77990-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 = <&dmac0 0x28>; + dma-names = "rx"; + power-domains = <&sysc R8A77990_PD_ALWAYS_ON>; + resets = <&cpg 511>; + renesas,bonding = <&drif21>; + status = "disabled"; + }; + + drif21: rif@e6f90000 { + compatible = "renesas,r8a77990-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 = <&dmac0 0x2a>; + dma-names = "rx"; + power-domains = <&sysc R8A77990_PD_ALWAYS_ON>; + resets = <&cpg 510>; + renesas,bonding = <&drif20>; + status = "disabled"; + }; + + drif30: rif@e6fa0000 { + compatible = "renesas,r8a77990-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 = <&dmac0 0x2c>; + dma-names = "rx"; + power-domains = <&sysc R8A77990_PD_ALWAYS_ON>; + resets = <&cpg 509>; + renesas,bonding = <&drif31>; + status = "disabled"; + }; + + drif31: rif@e6fb0000 { + compatible = "renesas,r8a77990-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 = <&dmac0 0x2e>; + dma-names = "rx"; + power-domains = <&sysc R8A77990_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/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts index 79c73a99d2fe..8f471881b7a3 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts +++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts @@ -393,10 +393,8 @@ &pfc { avb0_pins: avb { - mux { - groups = "avb0_link", "avb0_mdio", "avb0_mii"; - function = "avb0"; - }; + groups = "avb0_link", "avb0_mdio", "avb0_mii"; + function = "avb0"; }; can0_pins: can0 { diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi index 2c2272f5f5b5..cd7ca9774196 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi @@ -188,7 +188,7 @@ resets = <&cpg 906>; }; - pfc: pin-controller@e6060000 { + pfc: pinctrl@e6060000 { compatible = "renesas,pfc-r8a77995"; reg = <0 0xe6060000 0 0x508>; }; diff --git a/arch/arm64/boot/dts/renesas/r8a779a0-falcon-cpu.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0-falcon-cpu.dtsi new file mode 100644 index 000000000000..4ba269a4cec8 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a779a0-falcon-cpu.dtsi @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for the Falcon CPU board + * + * Copyright (C) 2020 Renesas Electronics Corp. + */ + +#include "r8a779a0.dtsi" + +/ { + model = "Renesas Falcon CPU board"; + compatible = "renesas,falcon-cpu", "renesas,r8a779a0"; + + memory@48000000 { + device_type = "memory"; + /* first 128MB is reserved for secure area. */ + reg = <0x0 0x48000000 0x0 0x78000000>; + }; + + memory@500000000 { + device_type = "memory"; + reg = <0x5 0x00000000 0x0 0x80000000>; + }; + + memory@600000000 { + device_type = "memory"; + reg = <0x6 0x00000000 0x0 0x80000000>; + }; + + memory@700000000 { + device_type = "memory"; + reg = <0x7 0x00000000 0x0 0x80000000>; + }; +}; + +&extal_clk { + clock-frequency = <16666666>; +}; + +&extalr_clk { + clock-frequency = <32768>; +}; + +&scif0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a779a0-falcon.dts b/arch/arm64/boot/dts/renesas/r8a779a0-falcon.dts new file mode 100644 index 000000000000..8eda70e5a82b --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a779a0-falcon.dts @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for the Falcon CPU and BreakOut boards + * + * Copyright (C) 2020 Renesas Electronics Corp. + */ + +/dts-v1/; +#include "r8a779a0-falcon-cpu.dtsi" + +/ { + model = "Renesas Falcon CPU and Breakout boards based on r8a779a0"; + compatible = "renesas,falcon-breakout", "renesas,falcon-cpu", "renesas,r8a779a0"; + + aliases { + serial0 = &scif0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi new file mode 100644 index 000000000000..6cf77ce9aa93 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for the R-Car V3U (R8A779A0) SoC + * + * Copyright (C) 2020 Renesas Electronics Corp. + */ + +#include <dt-bindings/clock/r8a779a0-cpg-mssr.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/power/r8a779a0-sysc.h> + +/ { + compatible = "renesas,r8a779a0"; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + a76_0: cpu@0 { + compatible = "arm,cortex-a76"; + reg = <0>; + device_type = "cpu"; + power-domains = <&sysc R8A779A0_PD_A1E0D0C0>; + next-level-cache = <&L3_CA76_0>; + }; + + L3_CA76_0: cache-controller-0 { + compatible = "cache"; + power-domains = <&sysc R8A779A0_PD_A2E0D0>; + cache-unified; + cache-level = <3>; + }; + }; + + extal_clk: extal { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board */ + clock-frequency = <0>; + }; + + extalr_clk: extalr { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board */ + clock-frequency = <0>; + }; + + pmu_a76 { + compatible = "arm,cortex-a76-pmu"; + interrupts-extended = <&gic GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>, + <&gic GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>, + <&gic GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>, + <&gic GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>; + }; + + /* External SCIF clock - to be overridden by boards that provide it */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + }; + + soc: soc { + compatible = "simple-bus"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + cpg: clock-controller@e6150000 { + compatible = "renesas,r8a779a0-cpg-mssr"; + reg = <0 0xe6150000 0 0x4000>; + clocks = <&extal_clk>, <&extalr_clk>; + clock-names = "extal", "extalr"; + #clock-cells = <2>; + #power-domain-cells = <0>; + #reset-cells = <1>; + }; + + rst: reset-controller@e6160000 { + compatible = "renesas,r8a779a0-rst"; + reg = <0 0xe6160000 0 0x4000>; + }; + + sysc: system-controller@e6180000 { + compatible = "renesas,r8a779a0-sysc"; + reg = <0 0xe6180000 0 0x4000>; + #power-domain-cells = <1>; + }; + + scif0: serial@e6e60000 { + compatible = "renesas,scif-r8a779a0", + "renesas,rcar-gen3-scif", "renesas,scif"; + reg = <0 0xe6e60000 0 64>; + interrupts = <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 702>, + <&cpg CPG_CORE R8A779A0_CLK_S1D2>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>; + resets = <&cpg 702>; + status = "disabled"; + }; + + gic: interrupt-controller@f1000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x0 0xf1000000 0 0x20000>, + <0x0 0xf1060000 0 0x110000>; + interrupts = <GIC_PPI 9 + (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>; + power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>; + }; + + prr: chipid@fff00044 { + compatible = "renesas,prr"; + reg = <0 0xfff00044 0 4>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, + <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, + <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>, + <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/ulcb.dtsi b/arch/arm64/boot/dts/renesas/ulcb.dtsi index ff88af8e39d3..a2e085db87c5 100644 --- a/arch/arm64/boot/dts/renesas/ulcb.dtsi +++ b/arch/arm64/boot/dts/renesas/ulcb.dtsi @@ -469,6 +469,7 @@ mmc-hs200-1_8v; mmc-hs400-1_8v; non-removable; + full-pwr-cycle-in-suspend; status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index b87b1f773083..26661c7b736b 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -2,9 +2,11 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-roc-cc.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a95x-z2.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb @@ -33,7 +35,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-pinebook-pro.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc-mezzanine.dtb -dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4a.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4b.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4c.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock960.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64-v2.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi index e8b754d415d8..2560b98771ca 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi @@ -574,7 +574,7 @@ }; spdif_tx: spdif-tx@ff3a0000 { - compatible = "rockchip,rk3308-spdif", "rockchip,rk3328-spdif"; + compatible = "rockchip,rk3308-spdif", "rockchip,rk3066-spdif"; reg = <0x0 0xff3a0000 0x0 0x1000>; interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru SCLK_SPDIF_TX>, <&cru HCLK_SPDIFTX>; diff --git a/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts new file mode 100644 index 000000000000..30c73ef25370 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts @@ -0,0 +1,374 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; +#include <dt-bindings/input/input.h> +#include "rk3328.dtsi" + +/ { + model = "A95X Z2"; + compatible = "zkmagic,a95x-z2", "rockchip,rk3318"; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + recovery { + label = "recovery"; + linux,code = <KEY_VENDOR>; + press-threshold-microvolt = <17000>; + }; + }; + + ir-receiver { + compatible = "gpio-ir-receiver"; + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&ir_int>; + pinctrl-names = "default"; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-0 = <&cyx_led_pin>; + pinctrl-names = "default"; + + cyx_led: led-0 { + default-state = "on"; + gpios = <&gpio2 RK_PC7 GPIO_ACTIVE_LOW>; + label = "CYX_LED"; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-0 = <&wifi_enable_h>; + pinctrl-names = "default"; + reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + }; + + spdif-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "SPDIF"; + + simple-audio-card,cpu { + sound-dai = <&spdif>; + }; + + simple-audio-card,codec { + sound-dai = <&spdif_out>; + }; + }; + + spdif_out: spdif-out { + compatible = "linux,spdif-dit"; + #sound-dai-cells = <0>; + }; + + /* Power tree */ + vccio_1v8: vccio-1v8-regulator { + compatible = "regulator-fixed"; + regulator-name = "vccio_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + vccio_3v3: vccio-3v3-regulator { + compatible = "regulator-fixed"; + regulator-name = "vccio_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vcc_otg_vbus: otg-vbus-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&otg_vbus_drv>; + pinctrl-names = "default"; + regulator-name = "vcc_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + }; + + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&sdmmc0m1_pin>; + pinctrl-names = "default"; + regulator-name = "vcc_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vccio_3v3>; + }; + + vdd_arm: vdd-arm { + compatible = "pwm-regulator"; + pwms = <&pwm0 0 5000 1>; + regulator-name = "vdd_arm"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1400000>; + regulator-settling-time-up-us = <250>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm1 0 5000 1>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1300000>; + regulator-settling-time-up-us = <250>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&analog_sound { + status = "okay"; +}; + +&codec { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&cpu0_opp_table { + opp-1200000000 { + status = "disabled"; + }; + + opp-1296000000 { + status = "disabled"; + }; +}; + +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + non-removable; + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; + pinctrl-names = "default"; + status = "okay"; +}; + +&gmac2phy { + assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; + assigned-clock-rate = <50000000>; + assigned-clocks = <&cru SCLK_MAC2PHY>; + clock_in_out = "output"; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_log>; +}; + +&hdmi { + ddc-i2c-scl-high-time-ns = <9625>; + ddc-i2c-scl-low-time-ns = <10000>; + status = "okay"; +}; + +&hdmiphy { + status = "okay"; +}; + +&hdmi_sound { + status = "okay"; +}; + +&i2s0 { + status = "okay"; +}; + +&i2s1 { + status = "okay"; +}; + +&io_domains { + pmuio-supply = <&vccio_3v3>; + vccio1-supply = <&vccio_3v3>; + vccio2-supply = <&vccio_1v8>; + vccio3-supply = <&vccio_3v3>; + vccio4-supply = <&vccio_1v8>; + vccio5-supply = <&vccio_3v3>; + vccio6-supply = <&vccio_3v3>; + status = "okay"; +}; + +&pinctrl { + ir { + ir_int: ir-int { + rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + leds { + cyx_led_pin: cyx-led-pin { + rockchip,pins = <2 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pwm0 { + pwm0_pin_pull_up: pwm0-pin-pull-up { + rockchip,pins = <2 RK_PA4 1 &pcfg_pull_up>; + }; + }; + + pwm1 { + pwm1_pin_pull_up: pwm1-pin-pull-up { + rockchip,pins = <2 RK_PA5 1 &pcfg_pull_up>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sdmmc1 { + clk_32k_out: clk-32k-out { + rockchip,pins = <1 RK_PD4 1 &pcfg_pull_none>; + }; + }; + + usb { + host_vbus_drv: host-vbus-drv { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + otg_vbus_drv: otg-vbus-drv { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pwm0 { + pinctrl-0 = <&pwm0_pin_pull_up>; + pinctrl-names = "active"; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_pin_pull_up>; + pinctrl-names = "active"; + status = "okay"; +}; + +&saradc { + vref-supply = <&vccio_1v8>; + status = "okay"; +}; + +&sdio { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + max-frequency = <125000000>; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk &clk_32k_out>; + pinctrl-names = "default"; + sd-uhs-sdr104; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; + pinctrl-names = "default"; + vmmc-supply = <&vcc_sd>; + status = "okay"; +}; + +&spdif { + pinctrl-0 = <&spdifm0_tx>; + status = "okay"; +}; + +&soc_crit { + temperature = <115000>; /* millicelsius */ +}; + +&target { + temperature = <105000>; /* millicelsius */ +}; + +&threshold { + temperature = <90000>; /* millicelsius */ +}; + +&tsadc { + rockchip,hw-tshut-temp = <120000>; + status = "okay"; +}; + +&u2phy { + status = "okay"; +}; + +&u2phy_host { + status = "okay"; +}; + +&u2phy_otg { + phy-supply = <&vcc_otg_vbus>; + status = "okay"; +}; + +&uart0 { + pinctrl-0 = <&uart0_xfer &uart0_cts>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb20_otg { + dr_mode = "host"; + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&vop { + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts index 1969dab84138..a48767931af6 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts @@ -70,6 +70,18 @@ cpu-supply = <&vdd_arm>; }; +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + &emmc { bus-width = <8>; cap-mmc-highspeed; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts new file mode 100644 index 000000000000..be7a31d81632 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts @@ -0,0 +1,368 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 David Bauer <mail@david-bauer.net> + */ + +/dts-v1/; + +#include <dt-bindings/input/input.h> +#include <dt-bindings/gpio/gpio.h> +#include "rk3328.dtsi" + +/ { + model = "FriendlyElec NanoPi R2S"; + compatible = "friendlyarm,nanopi-r2s", "rockchip,rk3328"; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + gmac_clk: gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "gmac_clk"; + #clock-cells = <0>; + }; + + keys { + compatible = "gpio-keys"; + pinctrl-0 = <&reset_button_pin>; + pinctrl-names = "default"; + + reset { + label = "reset"; + gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; + linux,code = <KEY_RESTART>; + debounce-interval = <50>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-0 = <&lan_led_pin>, <&sys_led_pin>, <&wan_led_pin>; + pinctrl-names = "default"; + + lan_led: led-0 { + gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; + label = "nanopi-r2s:green:lan"; + }; + + sys_led: led-1 { + gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + label = "nanopi-r2s:red:sys"; + }; + + wan_led: led-2 { + gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>; + label = "nanopi-r2s:green:wan"; + }; + }; + + vcc_io_sdio: sdmmcio-regulator { + compatible = "regulator-gpio"; + enable-active-high; + gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&sdio_vcc_pin>; + pinctrl-names = "default"; + regulator-name = "vcc_io_sdio"; + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-settling-time-us = <5000>; + regulator-type = "voltage"; + startup-delay-us = <2000>; + states = <1800000 0x1 + 3300000 0x0>; + vin-supply = <&vcc_io_33>; + }; + + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&sdmmc0m1_pin>; + pinctrl-names = "default"; + regulator-name = "vcc_sd"; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_io_33>; + }; + + vdd_5v: vdd-5v { + compatible = "regulator-fixed"; + regulator-name = "vdd_5v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&gmac2io { + assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; + assigned-clock-parents = <&gmac_clk>, <&gmac_clk>; + clock_in_out = "input"; + phy-handle = <&rtl8211e>; + phy-mode = "rgmii"; + phy-supply = <&vcc_io_33>; + pinctrl-0 = <&rgmiim1_pins>; + pinctrl-names = "default"; + rx_delay = <0x18>; + snps,aal; + tx_delay = <0x24>; + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + rtl8211e: ethernet-phy@1 { + reg = <1>; + pinctrl-0 = <ð_phy_reset_pin>; + pinctrl-names = "default"; + reset-assert-us = <10000>; + reset-deassert-us = <50000>; + reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&i2c1 { + status = "okay"; + + rk805: pmic@18 { + compatible = "rockchip,rk805"; + reg = <0x18>; + interrupt-parent = <&gpio1>; + interrupts = <24 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk805-clkout2"; + gpio-controller; + #gpio-cells = <2>; + pinctrl-0 = <&pmic_int_l>; + pinctrl-names = "default"; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vdd_5v>; + vcc2-supply = <&vdd_5v>; + vcc3-supply = <&vdd_5v>; + vcc4-supply = <&vdd_5v>; + vcc5-supply = <&vcc_io_33>; + vcc6-supply = <&vdd_5v>; + + regulators { + vdd_log: DCDC_REG1 { + regulator-name = "vdd_log"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-on-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_io_33: DCDC_REG4 { + regulator-name = "vcc_io_33"; + 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_18: LDO_REG1 { + regulator-name = "vcc_18"; + 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>; + }; + }; + + vcc18_emmc: LDO_REG2 { + regulator-name = "vcc18_emmc"; + 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_10: LDO_REG3 { + regulator-name = "vdd_10"; + 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>; + }; + }; + }; + }; +}; + +&io_domains { + pmuio-supply = <&vcc_io_33>; + vccio1-supply = <&vcc_io_33>; + vccio2-supply = <&vcc18_emmc>; + vccio3-supply = <&vcc_io_sdio>; + vccio4-supply = <&vcc_18>; + vccio5-supply = <&vcc_io_33>; + vccio6-supply = <&vcc_io_33>; + status = "okay"; +}; + +&pinctrl { + button { + reset_button_pin: reset-button-pin { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + ethernet-phy { + eth_phy_reset_pin: eth-phy-reset-pin { + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + leds { + lan_led_pin: lan-led-pin { + rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + sys_led_pin: sys-led-pin { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + wan_led_pin: wan-led-pin { + rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sd { + sdio_vcc_pin: sdio-vcc-pin { + rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pwm2 { + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + disable-wp; + pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>; + pinctrl-names = "default"; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vcc_io_sdio>; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +&u2phy { + status = "okay"; +}; + +&u2phy_host { + status = "okay"; +}; + +&u2phy_otg { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb20_otg { + status = "okay"; + dr_mode = "host"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi index 1c52f47c43a6..87fabc64cc39 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi @@ -134,7 +134,7 @@ pinctrl-0 = <&rmii_pins>; tx_delay = <0x30>; rx_delay = <0x10>; - status = "ok"; + status = "okay"; }; &i2c0 { diff --git a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts index b058ce999e3b..ecce16ecc9c3 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts @@ -183,7 +183,7 @@ snps,reset-delays-us = <0 10000 1000000>; tx_delay = <0x30>; rx_delay = <0x10>; - status = "ok"; + status = "okay"; }; &i2c0 { diff --git a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts index 236ab0f1b206..2582fa4b90e2 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts @@ -167,7 +167,7 @@ pinctrl-0 = <&rmii_pins>; tx_delay = <0x30>; rx_delay = <0x10>; - status = "ok"; + status = "okay"; }; &i2c0 { @@ -198,7 +198,7 @@ }; &io_domains { - status = "ok"; + status = "okay"; audio-supply = <&vcc_io>; gpio30-supply = <&vcc_io>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi index e36837c04dc7..635afdd99122 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi @@ -138,6 +138,14 @@ }; }; + ir-receiver { + compatible = "gpio-ir-receiver"; + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + linux,rc-map-name = "rc-khadas"; + pinctrl-names = "default"; + pinctrl-0 = <&ir_rx>; + }; + leds { compatible = "gpio-leds"; pinctrl-names = "default"; @@ -585,6 +593,12 @@ }; }; + ir { + ir_rx: ir-rx { + rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + leds { sys_led_pin: sys-led-pin { rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; @@ -690,6 +704,16 @@ status = "okay"; }; +&spi1 { + status = "okay"; + + spiflash: flash@0 { + compatible = "winbond,w25q128fw", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <104000000>; + }; +}; + &tcphy0 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts index 2acb3d500fb9..754627d97144 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts @@ -11,6 +11,16 @@ model = "Firefly ROC-RK3399-PC Mezzanine Board"; compatible = "firefly,roc-rk3399-pc-mezzanine", "rockchip,rk3399"; + /* MP8009 PoE PD */ + poe_12v: poe-12v { + compatible = "regulator-fixed"; + regulator-name = "poe_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + vcc3v3_ngff: vcc3v3-ngff { compatible = "regulator-fixed"; regulator-name = "vcc3v3_ngff"; @@ -22,7 +32,7 @@ regulator-boot-on; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - vin-supply = <&dc_12v>; + vin-supply = <&sys_12v>; }; vcc3v3_pcie: vcc3v3-pcie { @@ -34,10 +44,14 @@ pinctrl-0 = <&vcc3v3_pcie_en>; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - vin-supply = <&dc_12v>; + vin-supply = <&sys_12v>; }; }; +&sys_12v { + vin-supply = <&poe_12v>; +}; + &pcie_phy { status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi index b85ec31cd283..e7a459fa4322 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi @@ -110,6 +110,14 @@ regulator-max-microvolt = <5000000>; }; + sys_12v: sys-12v { + compatible = "regulator-fixed"; + regulator-name = "sys_12v"; + regulator-always-on; + regulator-boot-on; + vin-supply = <&dc_12v>; + }; + /* switched by pmic_sleep */ vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 { compatible = "regulator-fixed"; @@ -141,7 +149,7 @@ regulator-boot-on; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - vin-supply = <&dc_12v>; + vin-supply = <&sys_12v>; }; vcca_0v9: vcca-0v9 { @@ -186,7 +194,7 @@ regulator-boot-on; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - vin-supply = <&dc_12v>; + vin-supply = <&sys_12v>; }; vdd_log: vdd-log { diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi index 60f98a3e19d8..678a336010bf 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi @@ -11,9 +11,6 @@ #include "rk3399-opp.dtsi" / { - model = "Radxa ROCK Pi 4"; - compatible = "radxa,rockpi4", "rockchip,rk3399"; - chosen { stdout-path = "serial2:1500000n8"; }; @@ -587,17 +584,6 @@ pinctrl-names = "default"; pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; sd-uhs-sdr104; - status = "okay"; - - brcmf: wifi@1 { - compatible = "brcm,bcm4329-fmac"; - reg = <1>; - interrupt-parent = <&gpio0>; - interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>; - interrupt-names = "host-wake"; - pinctrl-names = "default"; - pinctrl-0 = <&wifi_host_wake_l>; - }; }; &sdmmc { @@ -666,18 +652,6 @@ &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; - status = "okay"; - - bluetooth { - compatible = "brcm,bcm43438-bt"; - clocks = <&rk808 1>; - clock-names = "ext_clock"; - device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; - host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; - shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; - }; }; &uart2 { diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts new file mode 100644 index 000000000000..89f2af5e111d --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Akash Gajjar <Akash_Gajjar@mentor.com> + * Copyright (c) 2019 Pragnesh Patel <Pragnesh_Patel@mentor.com> + */ + +/dts-v1/; +#include "rk3399-rock-pi-4.dtsi" + +/ { + model = "Radxa ROCK Pi 4A"; + compatible = "radxa,rockpi4a", "radxa,rockpi4", "rockchip,rk3399"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts new file mode 100644 index 000000000000..f0055ce2fda0 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Akash Gajjar <Akash_Gajjar@mentor.com> + * Copyright (c) 2019 Pragnesh Patel <Pragnesh_Patel@mentor.com> + */ + +/dts-v1/; +#include "rk3399-rock-pi-4.dtsi" + +/ { + model = "Radxa ROCK Pi 4B"; + compatible = "radxa,rockpi4b", "radxa,rockpi4", "rockchip,rk3399"; +}; + +&sdio0 { + status = "okay"; + + brcmf: wifi@1 { + compatible = "brcm,bcm4329-fmac"; + reg = <1>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>; + interrupt-names = "host-wake"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_host_wake_l>; + }; +}; + +&uart0 { + status = "okay"; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + clocks = <&rk808 1>; + clock-names = "ext_clock"; + device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; + shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts new file mode 100644 index 000000000000..4c7ebb1c5d2d --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd + * Copyright (c) 2019 Radxa Limited + * Copyright (c) 2019 Amarula Solutions(India) + */ + +/dts-v1/; +#include "rk3399-rock-pi-4.dtsi" + +/ { + model = "Radxa ROCK Pi 4C"; + compatible = "radxa,rockpi4c", "radxa,rockpi4", "rockchip,rk3399"; +}; + +&sdio0 { + status = "okay"; + + brcmf: wifi@1 { + compatible = "brcm,bcm4329-fmac"; + reg = <1>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>; + interrupt-names = "host-wake"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_host_wake_l>; + }; +}; + +&uart0 { + status = "okay"; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + clocks = <&rk808 1>; + clock-names = "ext_clock"; + device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; + shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; + }; +}; + +&vcc5v0_host { + gpio = <&gpio3 RK_PD6 GPIO_ACTIVE_HIGH>; +}; + +&vcc5v0_host_en { + rockchip,pins = <3 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; +}; diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile index 05c0bebf65d4..65506f21ba30 100644 --- a/arch/arm64/boot/dts/ti/Makefile +++ b/arch/arm64/boot/dts/ti/Makefile @@ -3,9 +3,11 @@ # Make file to build device tree binaries for boards based on # Texas Instruments Inc processors # -# Copyright (C) 2016-2018 Texas Instruments Incorporated - https://www.ti.com/ +# Copyright (C) 2016-2020 Texas Instruments Incorporated - https://www.ti.com/ # -dtb-$(CONFIG_ARCH_K3_AM6_SOC) += k3-am654-base-board.dtb +dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board.dtb -dtb-$(CONFIG_ARCH_K3_J721E_SOC) += k3-j721e-common-proc-board.dtb +dtb-$(CONFIG_ARCH_K3) += k3-j721e-common-proc-board.dtb + +dtb-$(CONFIG_ARCH_K3) += k3-j7200-common-proc-board.dtb diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi index 24ef18fe77df..533525229a8d 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi @@ -112,7 +112,29 @@ power-domains = <&k3_pds 148 TI_SCI_PD_EXCLUSIVE>; }; - main_pmx0: pinmux@11c000 { + crypto: crypto@4e00000 { + compatible = "ti,am654-sa2ul"; + reg = <0x0 0x4e00000 0x0 0x1200>; + power-domains = <&k3_pds 136 TI_SCI_PD_EXCLUSIVE>; + #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>; + dma-names = "tx", "rx1", "rx2"; + dma-coherent; + + rng: rng@4e10000 { + compatible = "inside-secure,safexcel-eip76"; + reg = <0x0 0x4e10000 0x0 0x7d>; + interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&k3_clks 136 1>; + }; + }; + + main_pmx0: pinctrl@11c000 { compatible = "pinctrl-single"; reg = <0x0 0x11c000 0x0 0x2e4>; #pinctrl-cells = <1>; @@ -120,7 +142,7 @@ pinctrl-single,function-mask = <0xffffffff>; }; - main_pmx1: pinmux@11c2e8 { + main_pmx1: pinctrl@11c2e8 { compatible = "pinctrl-single"; reg = <0x0 0x11c2e8 0x0 0x24>; #pinctrl-cells = <1>; @@ -283,7 +305,7 @@ no-1-8-v; }; - scm_conf: scm_conf@100000 { + scm_conf: scm-conf@100000 { compatible = "syscon", "simple-mfd"; reg = <0 0x00100000 0 0x1c000>; #address-cells = <1>; @@ -305,12 +327,12 @@ reg = <0x00000210 0x4>; }; - serdes0_clk: serdes_clk@4080 { + serdes0_clk: clock@4080 { compatible = "syscon"; reg = <0x00004080 0x4>; }; - serdes1_clk: serdes_clk@4090 { + serdes1_clk: clock@4090 { compatible = "syscon"; reg = <0x00004090 0x4>; }; @@ -322,12 +344,12 @@ <0x4090 0x3>; /* SERDES1 lane select */ }; - dss_oldi_io_ctrl: dss_oldi_io_ctrl@41E0 { + dss_oldi_io_ctrl: dss-oldi-io-ctrl@41e0 { compatible = "syscon"; - reg = <0x0000041E0 0x14>; + reg = <0x0000041e0 0x14>; }; - ehrpwm_tbclk: syscon@4140 { + ehrpwm_tbclk: clock@4140 { compatible = "ti,am654-ehrpwm-tbclk", "syscon"; reg = <0x4140 0x18>; #clock-cells = <1>; @@ -423,7 +445,7 @@ ti,interrupt-ranges = <0 392 32>; }; - main_navss { + main-navss { compatible = "simple-mfd"; #address-cells = <2>; #size-cells = <2>; @@ -639,7 +661,7 @@ }; }; - main_gpio0: main_gpio0@600000 { + main_gpio0: gpio@600000 { compatible = "ti,am654-gpio", "ti,keystone-gpio"; reg = <0x0 0x600000 0x0 0x100>; gpio-controller; @@ -654,7 +676,7 @@ clock-names = "gpio"; }; - main_gpio1: main_gpio1@601000 { + main_gpio1: gpio@601000 { compatible = "ti,am654-gpio", "ti,keystone-gpio"; reg = <0x0 0x601000 0x0 0x100>; gpio-controller; @@ -682,7 +704,7 @@ ti,syscon-pcie-mode = <&pcie0_mode>; bus-range = <0x0 0xff>; num-viewport = <16>; - max-link-speed = <3>; + max-link-speed = <2>; dma-coherent; interrupts = <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>; msi-map = <0x0 &gic_its 0x0 0x10000>; @@ -696,7 +718,7 @@ ti,syscon-pcie-mode = <&pcie0_mode>; num-ib-windows = <16>; num-ob-windows = <16>; - max-link-speed = <3>; + max-link-speed = <2>; dma-coherent; interrupts = <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>; }; @@ -714,7 +736,7 @@ ti,syscon-pcie-mode = <&pcie1_mode>; bus-range = <0x0 0xff>; num-viewport = <16>; - max-link-speed = <3>; + max-link-speed = <2>; dma-coherent; interrupts = <GIC_SPI 355 IRQ_TYPE_EDGE_RISING>; msi-map = <0x0 &gic_its 0x10000 0x10000>; @@ -728,7 +750,7 @@ ti,syscon-pcie-mode = <&pcie1_mode>; num-ib-windows = <16>; num-ob-windows = <16>; - max-link-speed = <3>; + max-link-speed = <2>; dma-coherent; interrupts = <GIC_SPI 355 IRQ_TYPE_EDGE_RISING>; }; diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi index 51ca4b4d4c21..29aaf8dca6f6 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi @@ -6,7 +6,7 @@ */ &cbass_mcu { - mcu_conf: scm_conf@40f00000 { + mcu_conf: scm-conf@40f00000 { compatible = "syscon", "simple-mfd"; reg = <0x0 0x40f00000 0x0 0x20000>; #address-cells = <1>; @@ -116,7 +116,7 @@ }; }; - mcu_navss { + mcu-navss { compatible = "simple-mfd"; #address-cells = <2>; #size-cells = <2>; diff --git a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi index a1ffe88d9664..ed42f13e7663 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi @@ -39,7 +39,7 @@ reg = <0x43000014 0x4>; }; - wkup_pmx0: pinmux@4301c000 { + wkup_pmx0: pinctrl@4301c000 { compatible = "pinctrl-single"; reg = <0x4301c000 0x118>; #pinctrl-cells = <1>; @@ -80,7 +80,7 @@ ti,interrupt-ranges = <0 712 16>; }; - wkup_gpio0: wkup_gpio0@42110000 { + wkup_gpio0: gpio@42110000 { compatible = "ti,am654-gpio", "ti,keystone-gpio"; reg = <0x42110000 0x100>; gpio-controller; @@ -95,7 +95,7 @@ clock-names = "gpio"; }; - wkup_vtm0: thermal@42050000 { + wkup_vtm0: temperature-sensor@42050000 { compatible = "ti,am654-vtm"; reg = <0x42050000 0x25c>; power-domains = <&k3_pds 80 TI_SCI_PD_EXCLUSIVE>; diff --git a/arch/arm64/boot/dts/ti/k3-am65.dtsi b/arch/arm64/boot/dts/ti/k3-am65.dtsi index 27c0406b10ba..d84c0bc05023 100644 --- a/arch/arm64/boot/dts/ti/k3-am65.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65.dtsi @@ -61,7 +61,7 @@ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>; }; - cbass_main: interconnect@100000 { + cbass_main: bus@100000 { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; @@ -88,7 +88,7 @@ <0x05 0x00000000 0x05 0x00000000 0x01 0x0000000>, <0x07 0x00000000 0x07 0x00000000 0x01 0x0000000>; - cbass_mcu: interconnect@28380000 { + cbass_mcu: bus@28380000 { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; @@ -106,7 +106,7 @@ <0x05 0x00000000 0x05 0x00000000 0x01 0x0000000>, /* FSS OSPI0 data region 3*/ <0x07 0x00000000 0x07 0x00000000 0x01 0x0000000>; /* FSS OSPI1 data region 3*/ - cbass_wakeup: interconnect@42040000 { + cbass_wakeup: bus@42040000 { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <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 b8a8a0fcb8af..d12dd89f3405 100644 --- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts +++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts @@ -29,7 +29,7 @@ #address-cells = <2>; #size-cells = <2>; ranges; - secure_ddr: secure_ddr@9e800000 { + secure_ddr: secure-ddr@9e800000 { reg = <0 0x9e800000 0 0x01800000>; /* for OP-TEE */ alignment = <0x1000>; no-map; @@ -70,14 +70,14 @@ >; }; - push_button_pins_default: push_button__pins_default { + push_button_pins_default: push-button-pins-default { pinctrl-single,pins = < AM65X_WKUP_IOPAD(0x0030, PIN_INPUT, 7) /* (R5) WKUP_GPIO0_24 */ AM65X_WKUP_IOPAD(0x003c, PIN_INPUT, 7) /* (P2) WKUP_GPIO0_27 */ >; }; - mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins_default { + mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins-default { pinctrl-single,pins = < AM65X_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* (V1) MCU_OSPI0_CLK */ AM65X_WKUP_IOPAD(0x0008, PIN_INPUT, 0) /* (U2) MCU_OSPI0_DQS */ @@ -93,13 +93,13 @@ >; }; - wkup_pca554_default: wkup_pca554_default { + wkup_pca554_default: wkup-pca554-default { pinctrl-single,pins = < AM65X_WKUP_IOPAD(0x0034, PIN_INPUT, 7) /* (T1) MCU_OSPI1_CLK.WKUP_GPIO0_25 */ >; }; - mcu_cpsw_pins_default: mcu_cpsw_pins_default { + mcu_cpsw_pins_default: mcu-cpsw-pins-default { pinctrl-single,pins = < AM65X_WKUP_IOPAD(0x0058, PIN_OUTPUT, 0) /* (N4) MCU_RGMII1_TX_CTL */ AM65X_WKUP_IOPAD(0x005c, PIN_INPUT, 0) /* (N5) MCU_RGMII1_RX_CTL */ @@ -116,7 +116,7 @@ >; }; - mcu_mdio_pins_default: mcu_mdio1_pins_default { + mcu_mdio_pins_default: mcu-mdio1-pins-default { pinctrl-single,pins = < AM65X_WKUP_IOPAD(0x008c, PIN_OUTPUT, 0) /* (L1) MCU_MDIO0_MDC */ AM65X_WKUP_IOPAD(0x0088, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */ @@ -167,7 +167,7 @@ >; }; - main_mmc1_pins_default: main_mmc1_pins_default { + main_mmc1_pins_default: main-mmc1-pins-default { pinctrl-single,pins = < AM65X_IOPAD(0x02d4, PIN_INPUT_PULLDOWN, 0) /* (C27) MMC1_CLK */ AM65X_IOPAD(0x02d8, PIN_INPUT_PULLUP, 0) /* (C28) MMC1_CMD */ @@ -180,7 +180,7 @@ >; }; - usb1_pins_default: usb1_pins_default { + usb1_pins_default: usb1-pins-default { pinctrl-single,pins = < AM65X_IOPAD(0x02c0, PIN_OUTPUT, 0) /* (AC8) USB1_DRVVBUS */ >; @@ -257,7 +257,7 @@ pinctrl-0 = <&main_i2c1_pins_default>; clock-frequency = <400000>; - ov5640@3c { + ov5640: camera@3c { compatible = "ovti,ov5640"; reg = <0x3c>; diff --git a/arch/arm64/boot/dts/ti/k3-am654-industrial-thermal.dtsi b/arch/arm64/boot/dts/ti/k3-am654-industrial-thermal.dtsi index cdc3d40c3f60..9021c738056b 100644 --- a/arch/arm64/boot/dts/ti/k3-am654-industrial-thermal.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am654-industrial-thermal.dtsi @@ -2,13 +2,13 @@ #include <dt-bindings/thermal/thermal.h> -mpu0_thermal: mpu0_thermal { +mpu0_thermal: mpu0-thermal { polling-delay-passive = <250>; /* milliseconds */ polling-delay = <500>; /* milliseconds */ thermal-sensors = <&wkup_vtm0 0>; trips { - mpu0_crit: mpu0_crit { + mpu0_crit: mpu0-crit { temperature = <125000>; /* milliCelsius */ hysteresis = <2000>; /* milliCelsius */ type = "critical"; @@ -16,13 +16,13 @@ mpu0_thermal: mpu0_thermal { }; }; -mpu1_thermal: mpu1_thermal { +mpu1_thermal: mpu1-thermal { polling-delay-passive = <250>; /* milliseconds */ polling-delay = <500>; /* milliseconds */ thermal-sensors = <&wkup_vtm0 1>; trips { - mpu1_crit: mpu1_crit { + mpu1_crit: mpu1-crit { temperature = <125000>; /* milliCelsius */ hysteresis = <2000>; /* milliCelsius */ type = "critical"; @@ -30,13 +30,13 @@ mpu1_thermal: mpu1_thermal { }; }; -mcu_thermal: mcu_thermal { +mcu_thermal: mcu-thermal { polling-delay-passive = <250>; /* milliseconds */ polling-delay = <500>; /* milliseconds */ thermal-sensors = <&wkup_vtm0 2>; trips { - mcu_crit: mcu_crit { + mcu_crit: mcu-crit { temperature = <125000>; /* milliCelsius */ hysteresis = <2000>; /* milliCelsius */ type = "critical"; 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 new file mode 100644 index 000000000000..ef03e7636b66 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com/ + */ + +/dts-v1/; + +#include "k3-j7200-som-p0.dtsi" +#include <dt-bindings/net/ti-dp83867.h> +#include <dt-bindings/mux/ti-serdes.h> + +/ { + chosen { + stdout-path = "serial2:115200n8"; + bootargs = "console=ttyS2,115200n8 earlycon=ns16550a,mmio32,0x02800000"; + }; +}; + +&wkup_pmx0 { + mcu_cpsw_pins_default: mcu-cpsw-pins-default { + pinctrl-single,pins = < + J721E_WKUP_IOPAD(0x0068, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */ + J721E_WKUP_IOPAD(0x006c, PIN_INPUT, 0) /* MCU_RGMII1_RX_CTL */ + J721E_WKUP_IOPAD(0x0070, PIN_OUTPUT, 0) /* MCU_RGMII1_TD3 */ + J721E_WKUP_IOPAD(0x0074, PIN_OUTPUT, 0) /* MCU_RGMII1_TD2 */ + J721E_WKUP_IOPAD(0x0078, PIN_OUTPUT, 0) /* MCU_RGMII1_TD1 */ + J721E_WKUP_IOPAD(0x007c, PIN_OUTPUT, 0) /* MCU_RGMII1_TD0 */ + J721E_WKUP_IOPAD(0x0088, PIN_INPUT, 0) /* MCU_RGMII1_RD3 */ + J721E_WKUP_IOPAD(0x008c, PIN_INPUT, 0) /* MCU_RGMII1_RD2 */ + J721E_WKUP_IOPAD(0x0090, PIN_INPUT, 0) /* MCU_RGMII1_RD1 */ + J721E_WKUP_IOPAD(0x0094, PIN_INPUT, 0) /* MCU_RGMII1_RD0 */ + J721E_WKUP_IOPAD(0x0080, PIN_INPUT, 0) /* MCU_RGMII1_TXC */ + J721E_WKUP_IOPAD(0x0084, PIN_INPUT, 0) /* MCU_RGMII1_RXC */ + >; + }; + + mcu_mdio_pins_default: mcu-mdio1-pins-default { + pinctrl-single,pins = < + J721E_WKUP_IOPAD(0x009c, PIN_OUTPUT, 0) /* (L1) MCU_MDIO0_MDC */ + J721E_WKUP_IOPAD(0x0098, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */ + >; + }; +}; + +&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 */ + J721E_IOPAD(0xe0, PIN_INPUT_PULLUP, 3) /* (T3) EXT_REFCLK1.I2C1_SDA */ + >; + }; + + main_mmc1_pins_default: main-mmc1-pins-default { + pinctrl-single,pins = < + J721E_IOPAD(0x104, PIN_INPUT, 0) /* (M20) MMC1_CMD */ + J721E_IOPAD(0x100, PIN_INPUT, 0) /* (P21) MMC1_CLK */ + J721E_IOPAD(0xfc, PIN_INPUT, 0) /* (P25) MMC1_CLKLB */ + J721E_IOPAD(0xf8, PIN_INPUT, 0) /* (M19) MMC1_DAT0 */ + J721E_IOPAD(0xf4, PIN_INPUT, 0) /* (N21) MMC1_DAT1 */ + J721E_IOPAD(0xf0, PIN_INPUT, 0) /* (N20) MMC1_DAT2 */ + J721E_IOPAD(0xec, PIN_INPUT, 0) /* (N19) MMC1_DAT3 */ + J721E_IOPAD(0xe4, PIN_INPUT, 8) /* (V1) TIMER_IO0.MMC1_SDCD */ + >; + }; + + main_usbss0_pins_default: main-usbss0-pins-default { + pinctrl-single,pins = < + J721E_IOPAD(0x120, PIN_OUTPUT, 0) /* (T4) USB0_DRVVBUS */ + >; + }; +}; + +&wkup_uart0 { + /* Wakeup UART is used by System firmware */ + status = "disabled"; +}; + +&main_uart0 { + /* Shared with ATF on this platform */ + power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>; +}; + +&main_uart2 { + /* MAIN UART 2 is used by R5F firmware */ + status = "disabled"; +}; + +&main_uart3 { + /* UART not brought out */ + status = "disabled"; +}; + +&main_uart4 { + /* UART not brought out */ + status = "disabled"; +}; + +&main_uart5 { + /* UART not brought out */ + status = "disabled"; +}; + +&main_uart6 { + /* UART not brought out */ + status = "disabled"; +}; + +&main_uart7 { + /* UART not brought out */ + status = "disabled"; +}; + +&main_uart8 { + /* UART not brought out */ + status = "disabled"; +}; + +&main_uart9 { + /* UART not brought out */ + status = "disabled"; +}; + +&mcu_cpsw { + pinctrl-names = "default"; + pinctrl-0 = <&mcu_cpsw_pins_default &mcu_mdio_pins_default>; +}; + +&davinci_mdio { + phy0: ethernet-phy@0 { + reg = <0>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; + ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; + }; +}; + +&cpsw_port1 { + phy-mode = "rgmii-rxid"; + phy-handle = <&phy0>; +}; + +&main_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&main_i2c0_pins_default>; + clock-frequency = <400000>; + + exp1: gpio@20 { + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + }; + + exp2: gpio@22 { + compatible = "ti,tca6424"; + reg = <0x22>; + gpio-controller; + #gpio-cells = <2>; + }; +}; + +&main_i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&main_i2c1_pins_default>; + clock-frequency = <400000>; + + exp4: gpio@20 { + compatible = "ti,tca6408"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + }; +}; + +&main_sdhci0 { + /* eMMC */ + non-removable; + ti,driver-strength-ohm = <50>; + disable-wp; +}; + +&main_sdhci1 { + /* SD card */ + pinctrl-0 = <&main_mmc1_pins_default>; + pinctrl-names = "default"; + ti,driver-strength-ohm = <50>; + disable-wp; +}; + +&serdes_ln_ctrl { + idle-states = <J7200_SERDES0_LANE0_PCIE1_LANE0>, <J7200_SERDES0_LANE1_PCIE1_LANE1>, + <J7200_SERDES0_LANE2_QSGMII_LANE1>, <J7200_SERDES0_LANE3_IP4_UNUSED>; +}; + +&usb_serdes_mux { + idle-states = <1>; /* USB0 to SERDES lane 3 */ +}; + +&usbss0 { + pinctrl-names = "default"; + pinctrl-0 = <&main_usbss0_pins_default>; + ti,vbus-divider; + ti,usb2-only; +}; + +&usb0 { + dr_mode = "otg"; + maximum-speed = "high-speed"; +}; diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi new file mode 100644 index 000000000000..72d6496e88dd --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi @@ -0,0 +1,449 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for J7200 SoC Family Main Domain peripherals + * + * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com/ + */ + +&cbass_main { + msmc_ram: sram@70000000 { + compatible = "mmio-sram"; + reg = <0x00 0x70000000 0x00 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x00 0x00 0x70000000 0x100000>; + + atf-sram@0 { + reg = <0x00 0x20000>; + }; + }; + + scm_conf: scm-conf@100000 { + compatible = "ti,j721e-system-controller", "syscon", "simple-mfd"; + reg = <0x00 0x00100000 0x00 0x1c000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x00 0x00 0x00100000 0x1c000>; + + serdes_ln_ctrl: serdes-ln-ctrl@4080 { + compatible = "mmio-mux"; + #mux-control-cells = <1>; + mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */ + <0x4088 0x3>, <0x408c 0x3>; /* SERDES0 lane2/3 select */ + }; + + usb_serdes_mux: mux-controller@4000 { + compatible = "mmio-mux"; + #mux-control-cells = <1>; + mux-reg-masks = <0x4000 0x8000000>; /* USB0 to SERDES0 lane 1/3 mux */ + }; + }; + + gic500: interrupt-controller@1800000 { + compatible = "arm,gic-v3"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x00 0x01800000 0x00 0x10000>, /* GICD */ + <0x00 0x01900000 0x00 0x100000>; /* GICR */ + + /* vcpumntirq: virtual CPU interface maintenance interrupt */ + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + + gic_its: msi-controller@1820000 { + compatible = "arm,gic-v3-its"; + reg = <0x00 0x01820000 0x00 0x10000>; + socionext,synquacer-pre-its = <0x1000000 0x400000>; + msi-controller; + #msi-cells = <1>; + }; + }; + + main_gpio_intr: interrupt-controller0 { + compatible = "ti,sci-intr"; + ti,intr-trigger-type = <1>; + interrupt-controller; + interrupt-parent = <&gic500>; + #interrupt-cells = <1>; + ti,sci = <&dmsc>; + ti,sci-dev-id = <131>; + ti,interrupt-ranges = <8 392 56>; + }; + + main_navss: bus@30000000 { + compatible = "simple-mfd"; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>; + ti,sci-dev-id = <199>; + + main_navss_intr: interrupt-controller1 { + compatible = "ti,sci-intr"; + ti,intr-trigger-type = <4>; + interrupt-controller; + interrupt-parent = <&gic500>; + #interrupt-cells = <1>; + ti,sci = <&dmsc>; + ti,sci-dev-id = <213>; + ti,interrupt-ranges = <0 64 64>, + <64 448 64>, + <128 672 64>; + }; + + main_udmass_inta: msi-controller@33d00000 { + compatible = "ti,sci-inta"; + reg = <0x00 0x33d00000 0x00 0x100000>; + interrupt-controller; + #interrupt-cells = <0>; + interrupt-parent = <&main_navss_intr>; + msi-controller; + ti,sci = <&dmsc>; + ti,sci-dev-id = <209>; + ti,interrupt-ranges = <0 0 256>; + }; + + secure_proxy_main: mailbox@32c00000 { + compatible = "ti,am654-secure-proxy"; + #mbox-cells = <1>; + reg-names = "target_data", "rt", "scfg"; + reg = <0x00 0x32c00000 0x00 0x100000>, + <0x00 0x32400000 0x00 0x100000>, + <0x00 0x32800000 0x00 0x100000>; + interrupt-names = "rx_011"; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + }; + + main_ringacc: ringacc@3c000000 { + compatible = "ti,am654-navss-ringacc"; + reg = <0x00 0x3c000000 0x00 0x400000>, + <0x00 0x38000000 0x00 0x400000>, + <0x00 0x31120000 0x00 0x100>, + <0x00 0x33000000 0x00 0x40000>; + reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target"; + ti,num-rings = <1024>; + ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */ + ti,sci = <&dmsc>; + ti,sci-dev-id = <211>; + msi-parent = <&main_udmass_inta>; + }; + + main_udmap: dma-controller@31150000 { + compatible = "ti,j721e-navss-main-udmap"; + reg = <0x00 0x31150000 0x00 0x100>, + <0x00 0x34000000 0x00 0x100000>, + <0x00 0x35000000 0x00 0x100000>; + reg-names = "gcfg", "rchanrt", "tchanrt"; + msi-parent = <&main_udmass_inta>; + #dma-cells = <1>; + + ti,sci = <&dmsc>; + ti,sci-dev-id = <212>; + ti,ringacc = <&main_ringacc>; + + ti,sci-rm-range-tchan = <0x0d>, /* TX_CHAN */ + <0x0f>, /* TX_HCHAN */ + <0x10>; /* TX_UHCHAN */ + ti,sci-rm-range-rchan = <0x0a>, /* RX_CHAN */ + <0x0b>, /* RX_HCHAN */ + <0x0c>; /* RX_UHCHAN */ + ti,sci-rm-range-rflow = <0x00>; /* GP RFLOW */ + }; + + cpts@310d0000 { + compatible = "ti,j721e-cpts"; + reg = <0x00 0x310d0000 0x00 0x400>; + reg-names = "cpts"; + clocks = <&k3_clks 201 1>; + clock-names = "cpts"; + interrupts-extended = <&main_navss_intr 391>; + interrupt-names = "cpts"; + ti,cpts-periodic-outputs = <6>; + ti,cpts-ext-ts-inputs = <8>; + }; + }; + + main_pmx0: pinctrl@11c000 { + compatible = "pinctrl-single"; + /* Proxy 0 addressing */ + reg = <0x00 0x11c000 0x00 0x2b4>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; + + main_uart0: serial@2800000 { + compatible = "ti,j721e-uart", "ti,am654-uart"; + reg = <0x00 0x02800000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 146 2>; + clock-names = "fclk"; + }; + + main_uart1: serial@2810000 { + compatible = "ti,j721e-uart", "ti,am654-uart"; + reg = <0x00 0x02810000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + power-domains = <&k3_pds 278 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 278 2>; + clock-names = "fclk"; + }; + + main_uart2: serial@2820000 { + compatible = "ti,j721e-uart", "ti,am654-uart"; + reg = <0x00 0x02820000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + power-domains = <&k3_pds 279 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 279 2>; + clock-names = "fclk"; + }; + + main_uart3: serial@2830000 { + compatible = "ti,j721e-uart", "ti,am654-uart"; + reg = <0x00 0x02830000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + power-domains = <&k3_pds 280 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 280 2>; + clock-names = "fclk"; + }; + + main_uart4: serial@2840000 { + compatible = "ti,j721e-uart", "ti,am654-uart"; + reg = <0x00 0x02840000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + power-domains = <&k3_pds 281 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 281 2>; + clock-names = "fclk"; + }; + + main_uart5: serial@2850000 { + compatible = "ti,j721e-uart", "ti,am654-uart"; + reg = <0x00 0x02850000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + power-domains = <&k3_pds 282 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 282 2>; + clock-names = "fclk"; + }; + + main_uart6: serial@2860000 { + compatible = "ti,j721e-uart", "ti,am654-uart"; + reg = <0x00 0x02860000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + power-domains = <&k3_pds 283 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 283 2>; + clock-names = "fclk"; + }; + + main_uart7: serial@2870000 { + compatible = "ti,j721e-uart", "ti,am654-uart"; + reg = <0x00 0x02870000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + power-domains = <&k3_pds 284 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 284 2>; + clock-names = "fclk"; + }; + + main_uart8: serial@2880000 { + compatible = "ti,j721e-uart", "ti,am654-uart"; + reg = <0x00 0x02880000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + power-domains = <&k3_pds 285 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 285 2>; + clock-names = "fclk"; + }; + + main_uart9: serial@2890000 { + compatible = "ti,j721e-uart", "ti,am654-uart"; + reg = <0x00 0x02890000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + power-domains = <&k3_pds 286 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 286 2>; + clock-names = "fclk"; + }; + + main_i2c0: i2c@2000000 { + compatible = "ti,j721e-i2c", "ti,omap4-i2c"; + reg = <0x00 0x2000000 0x00 0x100>; + interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "fck"; + clocks = <&k3_clks 187 1>; + power-domains = <&k3_pds 187 TI_SCI_PD_SHARED>; + }; + + main_i2c1: i2c@2010000 { + compatible = "ti,j721e-i2c", "ti,omap4-i2c"; + reg = <0x00 0x2010000 0x00 0x100>; + interrupts = <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "fck"; + clocks = <&k3_clks 188 1>; + power-domains = <&k3_pds 188 TI_SCI_PD_EXCLUSIVE>; + }; + + main_i2c2: i2c@2020000 { + compatible = "ti,j721e-i2c", "ti,omap4-i2c"; + reg = <0x00 0x2020000 0x00 0x100>; + interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "fck"; + clocks = <&k3_clks 189 1>; + power-domains = <&k3_pds 189 TI_SCI_PD_EXCLUSIVE>; + }; + + main_i2c3: i2c@2030000 { + compatible = "ti,j721e-i2c", "ti,omap4-i2c"; + reg = <0x00 0x2030000 0x00 0x100>; + interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "fck"; + clocks = <&k3_clks 190 1>; + power-domains = <&k3_pds 190 TI_SCI_PD_EXCLUSIVE>; + }; + + main_i2c4: i2c@2040000 { + compatible = "ti,j721e-i2c", "ti,omap4-i2c"; + reg = <0x00 0x2040000 0x00 0x100>; + interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "fck"; + clocks = <&k3_clks 191 1>; + power-domains = <&k3_pds 191 TI_SCI_PD_EXCLUSIVE>; + }; + + main_i2c5: i2c@2050000 { + compatible = "ti,j721e-i2c", "ti,omap4-i2c"; + reg = <0x00 0x2050000 0x00 0x100>; + interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "fck"; + clocks = <&k3_clks 192 1>; + power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>; + }; + + main_i2c6: i2c@2060000 { + compatible = "ti,j721e-i2c", "ti,omap4-i2c"; + reg = <0x00 0x2060000 0x00 0x100>; + interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "fck"; + clocks = <&k3_clks 193 1>; + power-domains = <&k3_pds 193 TI_SCI_PD_EXCLUSIVE>; + }; + + main_sdhci0: mmc@4f80000 { + compatible = "ti,j7200-sdhci-8bit", "ti,j721e-sdhci-8bit"; + reg = <0x00 0x04f80000 0x00 0x260>, <0x00 0x4f88000 0x00 0x134>; + interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&k3_pds 91 TI_SCI_PD_EXCLUSIVE>; + clock-names = "clk_xin", "clk_ahb"; + clocks = <&k3_clks 91 3>, <&k3_clks 91 0>; + ti,otap-del-sel-legacy = <0x0>; + ti,otap-del-sel-mmc-hs = <0x0>; + ti,otap-del-sel-ddr52 = <0x6>; + ti,otap-del-sel-hs200 = <0x8>; + ti,otap-del-sel-hs400 = <0x0>; + ti,strobe-sel = <0x77>; + ti,trm-icp = <0x8>; + bus-width = <8>; + mmc-ddr-1_8v; + dma-coherent; + }; + + main_sdhci1: mmc@4fb0000 { + compatible = "ti,j7200-sdhci-4bit", "ti,j721e-sdhci-4bit"; + reg = <0x00 0x04fb0000 0x00 0x260>, <0x00 0x4fb8000 0x00 0x134>; + interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&k3_pds 92 TI_SCI_PD_EXCLUSIVE>; + clock-names = "clk_xin", "clk_ahb"; + clocks = <&k3_clks 92 2>, <&k3_clks 92 1>; + ti,otap-del-sel-legacy = <0x0>; + ti,otap-del-sel-sd-hs = <0x0>; + ti,otap-del-sel-sdr12 = <0xf>; + ti,otap-del-sel-sdr25 = <0xf>; + ti,otap-del-sel-sdr50 = <0xc>; + ti,otap-del-sel-sdr104 = <0x5>; + ti,otap-del-sel-ddr50 = <0xc>; + no-1-8-v; + dma-coherent; + }; + + usbss0: cdns-usb@4104000 { + compatible = "ti,j721e-usb"; + reg = <0x00 0x4104000 0x00 0x100>; + dma-coherent; + power-domains = <&k3_pds 288 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 288 12>, <&k3_clks 288 3>; + clock-names = "ref", "lpm"; + assigned-clocks = <&k3_clks 288 12>; /* USB2_REFCLK */ + assigned-clock-parents = <&k3_clks 288 13>; /* HFOSC0 */ + #address-cells = <2>; + #size-cells = <2>; + ranges; + + usb0: usb@6000000 { + compatible = "cdns,usb3"; + reg = <0x00 0x6000000 0x00 0x10000>, + <0x00 0x6010000 0x00 0x10000>, + <0x00 0x6020000 0x00 0x10000>; + reg-names = "otg", "xhci", "dev"; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */ + <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>, /* irq.6 */ + <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; /* otgirq.0 */ + interrupt-names = "host", + "peripheral", + "otg"; + maximum-speed = "super-speed"; + dr_mode = "otg"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi new file mode 100644 index 000000000000..eb2a78a53512 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for J7200 SoC Family MCU/WAKEUP Domain peripherals + * + * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com/ + */ + +&cbass_mcu_wakeup { + dmsc: dmsc@44083000 { + compatible = "ti,k2g-sci"; + ti,host-id = <12>; + + mbox-names = "rx", "tx"; + + mboxes= <&secure_proxy_main 11>, + <&secure_proxy_main 13>; + + reg-names = "debug_messages"; + reg = <0x00 0x44083000 0x00 0x1000>; + + k3_pds: power-controller { + compatible = "ti,sci-pm-domain"; + #power-domain-cells = <2>; + }; + + k3_clks: clocks { + compatible = "ti,k2g-sci-clk"; + #clock-cells = <2>; + }; + + k3_reset: reset-controller { + compatible = "ti,sci-reset"; + #reset-cells = <2>; + }; + }; + + mcu_conf: syscon@40f00000 { + compatible = "syscon", "simple-mfd"; + reg = <0x00 0x40f00000 0x00 0x20000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x00 0x00 0x40f00000 0x20000>; + + phy_gmii_sel: phy@4040 { + compatible = "ti,am654-phy-gmii-sel"; + reg = <0x4040 0x4>; + #phy-cells = <1>; + }; + }; + + chipid@43000014 { + compatible = "ti,am654-chipid"; + reg = <0x00 0x43000014 0x00 0x4>; + }; + + wkup_pmx0: pinctrl@4301c000 { + compatible = "pinctrl-single"; + /* Proxy 0 addressing */ + reg = <0x00 0x4301c000 0x00 0x178>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; + + mcu_ram: sram@41c00000 { + compatible = "mmio-sram"; + reg = <0x00 0x41c00000 0x00 0x100000>; + ranges = <0x00 0x00 0x41c00000 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + }; + + wkup_uart0: serial@42300000 { + compatible = "ti,j721e-uart", "ti,am654-uart"; + reg = <0x00 0x42300000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 897 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + power-domains = <&k3_pds 287 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 287 2>; + clock-names = "fclk"; + }; + + mcu_uart0: serial@40a00000 { + compatible = "ti,j721e-uart", "ti,am654-uart"; + reg = <0x00 0x40a00000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 846 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <96000000>; + current-speed = <115200>; + power-domains = <&k3_pds 149 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 149 2>; + clock-names = "fclk"; + }; + + wkup_gpio_intr: interrupt-controller2 { + compatible = "ti,sci-intr"; + ti,intr-trigger-type = <1>; + interrupt-controller; + interrupt-parent = <&gic500>; + #interrupt-cells = <1>; + ti,sci = <&dmsc>; + ti,sci-dev-id = <137>; + ti,interrupt-ranges = <16 960 16>; + }; + + mcu_navss: bus@28380000 { + compatible = "simple-mfd"; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>; + dma-coherent; + dma-ranges; + ti,sci-dev-id = <232>; + + mcu_ringacc: ringacc@2b800000 { + compatible = "ti,am654-navss-ringacc"; + reg = <0x00 0x2b800000 0x00 0x400000>, + <0x00 0x2b000000 0x00 0x400000>, + <0x00 0x28590000 0x00 0x100>, + <0x00 0x2a500000 0x00 0x40000>; + reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target"; + ti,num-rings = <286>; + ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */ + ti,sci = <&dmsc>; + ti,sci-dev-id = <235>; + msi-parent = <&main_udmass_inta>; + }; + + mcu_udmap: dma-controller@285c0000 { + compatible = "ti,j721e-navss-mcu-udmap"; + reg = <0x00 0x285c0000 0x00 0x100>, + <0x00 0x2a800000 0x00 0x40000>, + <0x00 0x2aa00000 0x00 0x40000>; + reg-names = "gcfg", "rchanrt", "tchanrt"; + msi-parent = <&main_udmass_inta>; + #dma-cells = <1>; + + ti,sci = <&dmsc>; + ti,sci-dev-id = <236>; + ti,ringacc = <&mcu_ringacc>; + + ti,sci-rm-range-tchan = <0x0d>, /* TX_CHAN */ + <0x0f>; /* TX_HCHAN */ + ti,sci-rm-range-rchan = <0x0a>, /* RX_CHAN */ + <0x0b>; /* RX_HCHAN */ + ti,sci-rm-range-rflow = <0x00>; /* GP RFLOW */ + }; + }; + + mcu_cpsw: ethernet@46000000 { + compatible = "ti,j721e-cpsw-nuss"; + #address-cells = <2>; + #size-cells = <2>; + reg = <0x00 0x46000000 0x00 0x200000>; + reg-names = "cpsw_nuss"; + ranges = <0x00 0x00 0x00 0x46000000 0x00 0x200000>; + dma-coherent; + clocks = <&k3_clks 18 21>; + clock-names = "fck"; + power-domains = <&k3_pds 18 TI_SCI_PD_EXCLUSIVE>; + + dmas = <&mcu_udmap 0xf000>, + <&mcu_udmap 0xf001>, + <&mcu_udmap 0xf002>, + <&mcu_udmap 0xf003>, + <&mcu_udmap 0xf004>, + <&mcu_udmap 0xf005>, + <&mcu_udmap 0xf006>, + <&mcu_udmap 0xf007>, + <&mcu_udmap 0x7000>; + dma-names = "tx0", "tx1", "tx2", "tx3", + "tx4", "tx5", "tx6", "tx7", + "rx"; + + ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + + cpsw_port1: port@1 { + reg = <1>; + ti,mac-only; + label = "port1"; + ti,syscon-efuse = <&mcu_conf 0x200>; + phys = <&phy_gmii_sel 1>; + }; + }; + + davinci_mdio: mdio@f00 { + compatible = "ti,cpsw-mdio","ti,davinci_mdio"; + reg = <0x00 0xf00 0x00 0x100>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&k3_clks 18 21>; + clock-names = "fck"; + bus_freq = <1000000>; + }; + + cpts@3d000 { + compatible = "ti,am65-cpts"; + reg = <0x00 0x3d000 0x00 0x400>; + clocks = <&k3_clks 18 2>; + clock-names = "cpts"; + interrupts-extended = <&gic500 GIC_SPI 858 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "cpts"; + ti,cpts-ext-ts-inputs = <4>; + ti,cpts-periodic-outputs = <2>; + }; + }; + + mcu_i2c0: i2c@40b00000 { + compatible = "ti,j721e-i2c", "ti,omap4-i2c"; + reg = <0x00 0x40b00000 0x00 0x100>; + interrupts = <GIC_SPI 852 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "fck"; + clocks = <&k3_clks 194 1>; + power-domains = <&k3_pds 194 TI_SCI_PD_EXCLUSIVE>; + }; + + mcu_i2c1: i2c@40b10000 { + compatible = "ti,j721e-i2c", "ti,omap4-i2c"; + reg = <0x00 0x40b10000 0x00 0x100>; + interrupts = <GIC_SPI 853 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "fck"; + clocks = <&k3_clks 195 1>; + power-domains = <&k3_pds 195 TI_SCI_PD_EXCLUSIVE>; + }; + + wkup_i2c0: i2c@42120000 { + compatible = "ti,j721e-i2c", "ti,omap4-i2c"; + reg = <0x00 0x42120000 0x00 0x100>; + interrupts = <GIC_SPI 896 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "fck"; + clocks = <&k3_clks 197 1>; + power-domains = <&k3_pds 197 TI_SCI_PD_SHARED>; + }; + + fss: syscon@47000000 { + compatible = "syscon", "simple-mfd"; + reg = <0x00 0x47000000 0x00 0x100>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + hbmc_mux: hbmc-mux { + compatible = "mmio-mux"; + #mux-control-cells = <1>; + mux-reg-masks = <0x4 0x2>; /* HBMC select */ + }; + + hbmc: hyperbus@47034000 { + compatible = "ti,am654-hbmc"; + reg = <0x00 0x47034000 0x00 0x100>, + <0x05 0x00000000 0x01 0x0000000>; + power-domains = <&k3_pds 102 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 102 0>; + assigned-clocks = <&k3_clks 102 5>; + assigned-clock-rates = <333333333>; + #address-cells = <2>; + #size-cells = <1>; + mux-controls = <&hbmc_mux 0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi new file mode 100644 index 000000000000..6a98ba499bc2 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com/ + */ + +/dts-v1/; + +#include "k3-j7200.dtsi" + +/ { + memory@80000000 { + device_type = "memory"; + /* 4G RAM */ + reg = <0x00 0x80000000 0x00 0x80000000>, + <0x08 0x80000000 0x00 0x80000000>; + }; + + reserved_memory: reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + secure_ddr: optee@9e800000 { + reg = <0x00 0x9e800000 0x00 0x01800000>; + alignment = <0x1000>; + no-map; + }; + }; +}; + +&wkup_pmx0 { + mcu_fss0_hpb0_pins_default: mcu-fss0-hpb0-pins-default { + pinctrl-single,pins = < + J721E_WKUP_IOPAD(0x0, PIN_OUTPUT, 1) /* (B6) MCU_OSPI0_CLK.MCU_HYPERBUS0_CK */ + J721E_WKUP_IOPAD(0x4, PIN_OUTPUT, 1) /* (C8) MCU_OSPI0_LBCLKO.MCU_HYPERBUS0_CKn */ + J721E_WKUP_IOPAD(0x2c, PIN_OUTPUT, 1) /* (D6) MCU_OSPI0_CSn0.MCU_HYPERBUS0_CSn0 */ + J721E_WKUP_IOPAD(0x30, PIN_OUTPUT, 1) /* (D7) MCU_OSPI0_CSn1.MCU_HYPERBUS0_RESETn */ + J721E_WKUP_IOPAD(0x8, PIN_INPUT, 1) /* (B7) MCU_OSPI0_DQS.MCU_HYPERBUS0_RWDS */ + J721E_WKUP_IOPAD(0xc, PIN_INPUT, 1) /* (D8) MCU_OSPI0_D0.MCU_HYPERBUS0_DQ0 */ + J721E_WKUP_IOPAD(0x10, PIN_INPUT, 1) /* (C7) MCU_OSPI0_D1.MCU_HYPERBUS0_DQ1 */ + J721E_WKUP_IOPAD(0x14, PIN_INPUT, 1) /* (C5) MCU_OSPI0_D2.MCU_HYPERBUS0_DQ2 */ + J721E_WKUP_IOPAD(0x18, PIN_INPUT, 1) /* (A5) MCU_OSPI0_D3.MCU_HYPERBUS0_DQ3 */ + J721E_WKUP_IOPAD(0x1c, PIN_INPUT, 1) /* (A6) MCU_OSPI0_D4.MCU_HYPERBUS0_DQ4 */ + J721E_WKUP_IOPAD(0x20, PIN_INPUT, 1) /* (B8) MCU_OSPI0_D5.MCU_HYPERBUS0_DQ5 */ + J721E_WKUP_IOPAD(0x24, PIN_INPUT, 1) /* (A8) MCU_OSPI0_D6.MCU_HYPERBUS0_DQ6 */ + J721E_WKUP_IOPAD(0x28, PIN_INPUT, 1) /* (A7) MCU_OSPI0_D7.MCU_HYPERBUS0_DQ7 */ + >; + }; +}; + +&hbmc { + /* OSPI and HBMC are muxed inside FSS, Bootloader will enable + * appropriate node based on board detection + */ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&mcu_fss0_hpb0_pins_default>; + ranges = <0x00 0x00 0x05 0x00000000 0x4000000>, /* 64MB Flash on CS0 */ + <0x01 0x00 0x05 0x04000000 0x800000>; /* 8MB RAM on CS1 */ + + flash@0,0 { + compatible = "cypress,hyperflash", "cfi-flash"; + reg = <0x00 0x00 0x4000000>; + }; +}; diff --git a/arch/arm64/boot/dts/ti/k3-j7200.dtsi b/arch/arm64/boot/dts/ti/k3-j7200.dtsi new file mode 100644 index 000000000000..66169bcf7c9a --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-j7200.dtsi @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for J7200 SoC Family + * + * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com/ + */ + +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/pinctrl/k3.h> +#include <dt-bindings/soc/ti,sci_pm_domain.h> + +/ { + model = "Texas Instruments K3 J7200 SoC"; + compatible = "ti,j7200"; + interrupt-parent = <&gic500>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &wkup_uart0; + serial1 = &mcu_uart0; + serial2 = &main_uart0; + serial3 = &main_uart1; + serial4 = &main_uart2; + serial5 = &main_uart3; + serial6 = &main_uart4; + serial7 = &main_uart5; + serial8 = &main_uart6; + serial9 = &main_uart7; + serial10 = &main_uart8; + serial11 = &main_uart9; + }; + + chosen { }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu-map { + cluster0: cluster0 { + core0 { + cpu = <&cpu0>; + }; + + core1 { + cpu = <&cpu1>; + }; + }; + + }; + + cpu0: cpu@0 { + compatible = "arm,cortex-a72"; + reg = <0x000>; + device_type = "cpu"; + enable-method = "psci"; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; + next-level-cache = <&L2_0>; + }; + + cpu1: cpu@1 { + compatible = "arm,cortex-a72"; + reg = <0x001>; + device_type = "cpu"; + enable-method = "psci"; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; + next-level-cache = <&L2_0>; + }; + }; + + L2_0: l2-cache0 { + compatible = "cache"; + cache-level = <2>; + cache-size = <0x100000>; + cache-line-size = <64>; + cache-sets = <2048>; + next-level-cache = <&msmc_l3>; + }; + + msmc_l3: l3-cache0 { + compatible = "cache"; + cache-level = <3>; + }; + + firmware { + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + + psci: psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + }; + + a72_timer0: timer-cl0-cpu0 { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* cntpsirq */ + <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* cntpnsirq */ + <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* cntvirq */ + <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* cnthpirq */ + }; + + pmu: pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>; + }; + + cbass_main: bus@100000 { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */ + <0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */ + <0x00 0x00a40000 0x00 0x00a40000 0x00 0x00000800>, /* timesync router */ + <0x00 0x01000000 0x00 0x01000000 0x00 0x0d000000>, /* Most peripherals */ + <0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>, /* MAIN NAVSS */ + <0x00 0x70000000 0x00 0x70000000 0x00 0x00800000>, /* MSMC RAM */ + <0x00 0x18000000 0x00 0x18000000 0x00 0x08000000>, /* PCIe1 DAT0 */ + <0x41 0x00000000 0x41 0x00000000 0x01 0x00000000>, /* PCIe1 DAT1 */ + + /* MCUSS_WKUP Range */ + <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>, + <0x00 0x40200000 0x00 0x40200000 0x00 0x00998400>, + <0x00 0x40f00000 0x00 0x40f00000 0x00 0x00020000>, + <0x00 0x41000000 0x00 0x41000000 0x00 0x00020000>, + <0x00 0x41400000 0x00 0x41400000 0x00 0x00020000>, + <0x00 0x41c00000 0x00 0x41c00000 0x00 0x00100000>, + <0x00 0x42040000 0x00 0x42040000 0x00 0x03ac2400>, + <0x00 0x45100000 0x00 0x45100000 0x00 0x00c24000>, + <0x00 0x46000000 0x00 0x46000000 0x00 0x00200000>, + <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>, + <0x00 0x50000000 0x00 0x50000000 0x00 0x10000000>, + <0x05 0x00000000 0x05 0x00000000 0x01 0x00000000>, + <0x07 0x00000000 0x07 0x00000000 0x01 0x00000000>; + + cbass_mcu_wakeup: bus@28380000 { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>, /* MCU NAVSS*/ + <0x00 0x40200000 0x00 0x40200000 0x00 0x00998400>, /* First peripheral window */ + <0x00 0x40f00000 0x00 0x40f00000 0x00 0x00020000>, /* CTRL_MMR0 */ + <0x00 0x41000000 0x00 0x41000000 0x00 0x00020000>, /* MCU R5F Core0 */ + <0x00 0x41400000 0x00 0x41400000 0x00 0x00020000>, /* MCU R5F Core1 */ + <0x00 0x41c00000 0x00 0x41c00000 0x00 0x00100000>, /* MCU SRAM */ + <0x00 0x42040000 0x00 0x42040000 0x00 0x03ac2400>, /* WKUP peripheral window */ + <0x00 0x45100000 0x00 0x45100000 0x00 0x00c24000>, /* MMRs, remaining NAVSS */ + <0x00 0x46000000 0x00 0x46000000 0x00 0x00200000>, /* CPSW */ + <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>, /* OSPI register space */ + <0x00 0x50000000 0x00 0x50000000 0x00 0x10000000>, /* FSS OSPI0/1 data region 0 */ + <0x05 0x00000000 0x05 0x00000000 0x01 0x00000000>, /* FSS OSPI0 data region 3 */ + <0x07 0x00000000 0x07 0x00000000 0x01 0x00000000>; /* FSS OSPI1 data region 3 */ + }; + }; +}; + +/* Now include the peripherals for each bus segments */ +#include "k3-j7200-main.dtsi" +#include "k3-j7200-mcu-wakeup.dtsi" 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 e8fc01d97ada..52e121155563 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 @@ -86,13 +86,13 @@ }; &main_pmx0 { - sw10_button_pins_default: sw10_button_pins_default { + sw10_button_pins_default: sw10-button-pins-default { pinctrl-single,pins = < J721E_IOPAD(0x0, PIN_INPUT, 7) /* (AC18) EXTINTn.GPIO0_0 */ >; }; - main_mmc1_pins_default: main_mmc1_pins_default { + main_mmc1_pins_default: main-mmc1-pins-default { pinctrl-single,pins = < J721E_IOPAD(0x254, PIN_INPUT, 0) /* (R29) MMC1_CMD */ J721E_IOPAD(0x250, PIN_INPUT, 0) /* (P25) MMC1_CLK */ @@ -106,14 +106,14 @@ >; }; - main_usbss0_pins_default: main_usbss0_pins_default { + main_usbss0_pins_default: main-usbss0-pins-default { pinctrl-single,pins = < J721E_IOPAD(0x290, PIN_OUTPUT, 0) /* (U6) USB0_DRVVBUS */ J721E_IOPAD(0x210, PIN_INPUT, 7) /* (W3) MCAN1_RX.GPIO1_3 */ >; }; - main_usbss1_pins_default: main_usbss1_pins_default { + main_usbss1_pins_default: main-usbss1-pins-default { pinctrl-single,pins = < J721E_IOPAD(0x214, PIN_OUTPUT, 4) /* (V4) MCAN1_TX.USB1_DRVVBUS */ >; @@ -153,7 +153,7 @@ >; }; - mcasp10_pins_default: mcasp10_pins_default { + mcasp10_pins_default: mcasp10-pins-default { pinctrl-single,pins = < J721E_IOPAD(0x158, PIN_OUTPUT_PULLDOWN, 12) /* (U23) RGMII5_TX_CTL.MCASP10_ACLKX */ J721E_IOPAD(0x15c, PIN_OUTPUT_PULLDOWN, 12) /* (U26) RGMII5_RX_CTL.MCASP10_AFSX */ @@ -167,7 +167,7 @@ >; }; - audi_ext_refclk2_pins_default: audi_ext_refclk2_pins_default { + audi_ext_refclk2_pins_default: audi-ext-refclk2-pins-default { pinctrl-single,pins = < J721E_IOPAD(0x1a4, PIN_OUTPUT, 3) /* (W26) RGMII6_RXC.AUDIO_EXT_REFCLK2 */ >; @@ -175,7 +175,7 @@ }; &wkup_pmx0 { - sw11_button_pins_default: sw11_button_pins_default { + sw11_button_pins_default: sw11-button-pins-default { pinctrl-single,pins = < J721E_WKUP_IOPAD(0xcc, PIN_INPUT, 7) /* (G28) WKUP_GPIO0_7 */ >; @@ -194,7 +194,7 @@ >; }; - mcu_cpsw_pins_default: mcu_cpsw_pins_default { + mcu_cpsw_pins_default: mcu-cpsw-pins-default { pinctrl-single,pins = < J721E_WKUP_IOPAD(0x0058, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */ J721E_WKUP_IOPAD(0x005c, PIN_INPUT, 0) /* MCU_RGMII1_RX_CTL */ @@ -211,7 +211,7 @@ >; }; - mcu_mdio_pins_default: mcu_mdio1_pins_default { + mcu_mdio_pins_default: mcu-mdio1-pins-default { pinctrl-single,pins = < J721E_WKUP_IOPAD(0x008c, PIN_OUTPUT, 0) /* MCU_MDIO0_MDC */ J721E_WKUP_IOPAD(0x0088, PIN_INPUT, 0) /* MCU_MDIO0_MDIO */ @@ -286,99 +286,6 @@ status = "disabled"; }; -&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 { - interrupts = <428>; - - mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 { - ti,mbox-rx = <0 0 0>; - ti,mbox-tx = <1 0 0>; - }; - - mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 { - ti,mbox-rx = <2 0 0>; - ti,mbox-tx = <3 0 0>; - }; -}; - -&mailbox0_cluster3 { - interrupts = <424>; - - mbox_c66_0: mbox-c66-0 { - ti,mbox-rx = <0 0 0>; - ti,mbox-tx = <1 0 0>; - }; - - mbox_c66_1: mbox-c66-1 { - ti,mbox-rx = <2 0 0>; - ti,mbox-tx = <3 0 0>; - }; -}; - -&mailbox0_cluster4 { - interrupts = <420>; - - mbox_c71_0: mbox-c71-0 { - ti,mbox-rx = <0 0 0>; - ti,mbox-tx = <1 0 0>; - }; -}; - -&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_sdhci0 { /* eMMC */ non-removable; @@ -404,11 +311,12 @@ }; &serdes_ln_ctrl { - idle-states = <SERDES0_LANE0_PCIE0_LANE0>, <SERDES0_LANE1_PCIE0_LANE1>, - <SERDES1_LANE0_PCIE1_LANE0>, <SERDES1_LANE1_PCIE1_LANE1>, - <SERDES2_LANE0_PCIE2_LANE0>, <SERDES2_LANE1_PCIE2_LANE1>, - <SERDES3_LANE0_USB3_0_SWAP>, <SERDES3_LANE1_USB3_0>, - <SERDES4_LANE0_EDP_LANE0>, <SERDES4_LANE1_EDP_LANE1>, <SERDES4_LANE2_EDP_LANE2>, <SERDES4_LANE3_EDP_LANE3>; + idle-states = <J721E_SERDES0_LANE0_PCIE0_LANE0>, <J721E_SERDES0_LANE1_PCIE0_LANE1>, + <J721E_SERDES1_LANE0_PCIE1_LANE0>, <J721E_SERDES1_LANE1_PCIE1_LANE1>, + <J721E_SERDES2_LANE0_PCIE2_LANE0>, <J721E_SERDES2_LANE1_PCIE2_LANE1>, + <J721E_SERDES3_LANE0_USB3_0_SWAP>, <J721E_SERDES3_LANE1_USB3_0>, + <J721E_SERDES4_LANE0_EDP_LANE0>, <J721E_SERDES4_LANE1_EDP_LANE1>, + <J721E_SERDES4_LANE2_EDP_LANE2>, <J721E_SERDES4_LANE3_EDP_LANE3>; }; &serdes_wiz3 { @@ -500,7 +408,7 @@ gpio-controller; #gpio-cells = <2>; - p09 { + p09-hog { /* P11 - MCASP/TRACE_MUX_S0 */ gpio-hog; gpios = <9 GPIO_ACTIVE_HIGH>; @@ -508,7 +416,7 @@ line-name = "MCASP/TRACE_MUX_S0"; }; - p10 { + p10-hog { /* P12 - MCASP/TRACE_MUX_S1 */ gpio-hog; gpios = <10 GPIO_ACTIVE_HIGH>; @@ -651,3 +559,83 @@ status = "okay"; }; + +&serdes0 { + serdes0_pcie_link: link@0 { + reg = <0>; + cdns,num-lanes = <1>; + #phy-cells = <0>; + cdns,phy-type = <PHY_TYPE_PCIE>; + resets = <&serdes_wiz0 1>; + }; +}; + +&serdes1 { + serdes1_pcie_link: link@0 { + reg = <0>; + cdns,num-lanes = <2>; + #phy-cells = <0>; + cdns,phy-type = <PHY_TYPE_PCIE>; + resets = <&serdes_wiz1 1>, <&serdes_wiz1 2>; + }; +}; + +&serdes2 { + serdes2_pcie_link: link@0 { + reg = <0>; + cdns,num-lanes = <2>; + #phy-cells = <0>; + cdns,phy-type = <PHY_TYPE_PCIE>; + resets = <&serdes_wiz2 1>, <&serdes_wiz2 2>; + }; +}; + +&pcie0_rc { + reset-gpios = <&exp1 6 GPIO_ACTIVE_HIGH>; + phys = <&serdes0_pcie_link>; + phy-names = "pcie-phy"; + num-lanes = <1>; +}; + +&pcie1_rc { + reset-gpios = <&exp1 2 GPIO_ACTIVE_HIGH>; + phys = <&serdes1_pcie_link>; + phy-names = "pcie-phy"; + num-lanes = <2>; +}; + +&pcie2_rc { + reset-gpios = <&exp2 20 GPIO_ACTIVE_HIGH>; + phys = <&serdes2_pcie_link>; + phy-names = "pcie-phy"; + num-lanes = <2>; +}; + +&pcie0_ep { + phys = <&serdes0_pcie_link>; + phy-names = "pcie-phy"; + num-lanes = <1>; + status = "disabled"; +}; + +&pcie1_ep { + phys = <&serdes1_pcie_link>; + phy-names = "pcie-phy"; + num-lanes = <2>; + status = "disabled"; +}; + +&pcie2_ep { + phys = <&serdes2_pcie_link>; + phy-names = "pcie-phy"; + num-lanes = <2>; + status = "disabled"; +}; + +&pcie3_rc { + status = "disabled"; +}; + +&pcie3_ep { + 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 12ceea9b3c9a..e2a96b2c423c 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi @@ -6,7 +6,7 @@ */ #include <dt-bindings/phy/phy.h> #include <dt-bindings/mux/mux.h> -#include <dt-bindings/mux/mux-j721e-wiz.h> +#include <dt-bindings/mux/ti-serdes.h> &cbass_main { msmc_ram: sram@70000000 { @@ -28,7 +28,39 @@ #size-cells = <1>; ranges = <0x0 0x0 0x00100000 0x1c000>; - serdes_ln_ctrl: serdes-ln-ctrl@4080 { + pcie0_ctrl: syscon@4070 { + compatible = "ti,j721e-system-controller", "syscon", "simple-mfd"; + reg = <0x00004070 0x4>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x4070 0x4070 0x4>; + }; + + pcie1_ctrl: syscon@4074 { + compatible = "ti,j721e-system-controller", "syscon", "simple-mfd"; + reg = <0x00004074 0x4>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x4074 0x4074 0x4>; + }; + + pcie2_ctrl: syscon@4078 { + compatible = "ti,j721e-system-controller", "syscon", "simple-mfd"; + reg = <0x00004078 0x4>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x4078 0x4078 0x4>; + }; + + pcie3_ctrl: syscon@407c { + compatible = "ti,j721e-system-controller", "syscon", "simple-mfd"; + reg = <0x0000407c 0x4>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x407c 0x407c 0x4>; + }; + + serdes_ln_ctrl: mux@4080 { compatible = "mmio-mux"; reg = <0x00004080 0x50>; #mux-control-cells = <1>; @@ -38,11 +70,12 @@ <0x40b0 0x3>, <0x40b4 0x3>, /* SERDES3 lane0/1 select */ <0x40c0 0x3>, <0x40c4 0x3>, <0x40c8 0x3>, <0x40cc 0x3>; /* SERDES4 lane0/1/2/3 select */ - idle-states = <SERDES0_LANE0_PCIE0_LANE0>, <SERDES0_LANE1_PCIE0_LANE1>, - <SERDES1_LANE0_PCIE1_LANE0>, <SERDES1_LANE1_PCIE1_LANE1>, - <SERDES2_LANE0_PCIE2_LANE0>, <SERDES2_LANE1_PCIE2_LANE1>, - <MUX_IDLE_AS_IS>, <SERDES3_LANE1_USB3_0>, - <SERDES4_LANE0_EDP_LANE0>, <SERDES4_LANE1_EDP_LANE1>, <SERDES4_LANE2_EDP_LANE2>, <SERDES4_LANE3_EDP_LANE3>; + idle-states = <J721E_SERDES0_LANE0_PCIE0_LANE0>, <J721E_SERDES0_LANE1_PCIE0_LANE1>, + <J721E_SERDES1_LANE0_PCIE1_LANE0>, <J721E_SERDES1_LANE1_PCIE1_LANE1>, + <J721E_SERDES2_LANE0_PCIE2_LANE0>, <J721E_SERDES2_LANE1_PCIE2_LANE1>, + <MUX_IDLE_AS_IS>, <J721E_SERDES3_LANE1_USB3_0>, + <J721E_SERDES4_LANE0_EDP_LANE0>, <J721E_SERDES4_LANE1_EDP_LANE1>, + <J721E_SERDES4_LANE2_EDP_LANE2>, <J721E_SERDES4_LANE3_EDP_LANE3>; }; usb_serdes_mux: mux-controller@4000 { @@ -86,7 +119,7 @@ ti,interrupt-ranges = <8 392 56>; }; - main_navss { + main-navss { compatible = "simple-mfd"; #address-cells = <2>; #size-cells = <2>; @@ -304,7 +337,30 @@ }; }; - main_pmx0: pinmux@11c000 { + main_crypto: crypto@4e00000 { + compatible = "ti,j721e-sa2ul"; + reg = <0x0 0x4e00000 0x0 0x1200>; + power-domains = <&k3_pds 264 TI_SCI_PD_EXCLUSIVE>; + #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>; + dma-names = "tx", "rx1", "rx2"; + dma-coherent; + + rng: rng@4e10000 { + compatible = "inside-secure,safexcel-eip76"; + reg = <0x0 0x4e10000 0x0 0x7d>; + interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&k3_clks 264 1>; + }; + }; + + main_pmx0: pinctrl@11c000 { compatible = "pinctrl-single"; /* Proxy 0 addressing */ reg = <0x0 0x11c000 0x0 0x2b4>; @@ -553,6 +609,204 @@ }; }; + pcie0_rc: pcie@2900000 { + compatible = "ti,j721e-pcie-host"; + reg = <0x00 0x02900000 0x00 0x1000>, + <0x00 0x02907000 0x00 0x400>, + <0x00 0x0d000000 0x00 0x00800000>, + <0x00 0x10000000 0x00 0x00001000>; + reg-names = "intd_cfg", "user_cfg", "reg", "cfg"; + interrupt-names = "link_state"; + interrupts = <GIC_SPI 318 IRQ_TYPE_EDGE_RISING>; + device_type = "pci"; + ti,syscon-pcie-ctrl = <&pcie0_ctrl>; + max-link-speed = <3>; + num-lanes = <2>; + power-domains = <&k3_pds 239 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 239 1>; + clock-names = "fck"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0xf>; + vendor-id = <0x104c>; + device-id = <0xb00d>; + msi-map = <0x0 &gic_its 0x0 0x10000>; + dma-coherent; + ranges = <0x01000000 0x0 0x10001000 0x0 0x10001000 0x0 0x0010000>, + <0x02000000 0x0 0x10011000 0x0 0x10011000 0x0 0x7fef000>; + dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>; + }; + + pcie0_ep: pcie-ep@2900000 { + compatible = "ti,j721e-pcie-ep"; + reg = <0x00 0x02900000 0x00 0x1000>, + <0x00 0x02907000 0x00 0x400>, + <0x00 0x0d000000 0x00 0x00800000>, + <0x00 0x10000000 0x00 0x08000000>; + reg-names = "intd_cfg", "user_cfg", "reg", "mem"; + interrupt-names = "link_state"; + interrupts = <GIC_SPI 318 IRQ_TYPE_EDGE_RISING>; + ti,syscon-pcie-ctrl = <&pcie0_ctrl>; + max-link-speed = <3>; + num-lanes = <2>; + power-domains = <&k3_pds 239 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 239 1>; + clock-names = "fck"; + cdns,max-outbound-regions = <16>; + max-functions = /bits/ 8 <6>; + max-virtual-functions = /bits/ 16 <4 4 4 4 0 0>; + dma-coherent; + }; + + pcie1_rc: pcie@2910000 { + compatible = "ti,j721e-pcie-host"; + reg = <0x00 0x02910000 0x00 0x1000>, + <0x00 0x02917000 0x00 0x400>, + <0x00 0x0d800000 0x00 0x00800000>, + <0x00 0x18000000 0x00 0x00001000>; + reg-names = "intd_cfg", "user_cfg", "reg", "cfg"; + interrupt-names = "link_state"; + interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>; + device_type = "pci"; + ti,syscon-pcie-ctrl = <&pcie1_ctrl>; + max-link-speed = <3>; + num-lanes = <2>; + power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 240 1>; + clock-names = "fck"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0xf>; + vendor-id = <0x104c>; + device-id = <0xb00d>; + msi-map = <0x0 &gic_its 0x10000 0x10000>; + dma-coherent; + ranges = <0x01000000 0x0 0x18001000 0x0 0x18001000 0x0 0x0010000>, + <0x02000000 0x0 0x18011000 0x0 0x18011000 0x0 0x7fef000>; + dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>; + }; + + pcie1_ep: pcie-ep@2910000 { + compatible = "ti,j721e-pcie-ep"; + reg = <0x00 0x02910000 0x00 0x1000>, + <0x00 0x02917000 0x00 0x400>, + <0x00 0x0d800000 0x00 0x00800000>, + <0x00 0x18000000 0x00 0x08000000>; + reg-names = "intd_cfg", "user_cfg", "reg", "mem"; + interrupt-names = "link_state"; + interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>; + ti,syscon-pcie-ctrl = <&pcie1_ctrl>; + max-link-speed = <3>; + num-lanes = <2>; + power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 240 1>; + clock-names = "fck"; + cdns,max-outbound-regions = <16>; + max-functions = /bits/ 8 <6>; + max-virtual-functions = /bits/ 16 <4 4 4 4 0 0>; + dma-coherent; + }; + + pcie2_rc: pcie@2920000 { + compatible = "ti,j721e-pcie-host"; + reg = <0x00 0x02920000 0x00 0x1000>, + <0x00 0x02927000 0x00 0x400>, + <0x00 0x0e000000 0x00 0x00800000>, + <0x44 0x00000000 0x00 0x00001000>; + reg-names = "intd_cfg", "user_cfg", "reg", "cfg"; + interrupt-names = "link_state"; + interrupts = <GIC_SPI 342 IRQ_TYPE_EDGE_RISING>; + device_type = "pci"; + ti,syscon-pcie-ctrl = <&pcie2_ctrl>; + max-link-speed = <3>; + num-lanes = <2>; + power-domains = <&k3_pds 241 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 241 1>; + clock-names = "fck"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0xf>; + vendor-id = <0x104c>; + device-id = <0xb00d>; + msi-map = <0x0 &gic_its 0x20000 0x10000>; + dma-coherent; + ranges = <0x01000000 0x0 0x00001000 0x44 0x00001000 0x0 0x0010000>, + <0x02000000 0x0 0x00011000 0x44 0x00011000 0x0 0x7fef000>; + dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>; + }; + + pcie2_ep: pcie-ep@2920000 { + compatible = "ti,j721e-pcie-ep"; + reg = <0x00 0x02920000 0x00 0x1000>, + <0x00 0x02927000 0x00 0x400>, + <0x00 0x0e000000 0x00 0x00800000>, + <0x44 0x00000000 0x00 0x08000000>; + reg-names = "intd_cfg", "user_cfg", "reg", "mem"; + interrupt-names = "link_state"; + interrupts = <GIC_SPI 342 IRQ_TYPE_EDGE_RISING>; + ti,syscon-pcie-ctrl = <&pcie2_ctrl>; + max-link-speed = <3>; + num-lanes = <2>; + power-domains = <&k3_pds 241 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 241 1>; + clock-names = "fck"; + cdns,max-outbound-regions = <16>; + max-functions = /bits/ 8 <6>; + max-virtual-functions = /bits/ 16 <4 4 4 4 0 0>; + dma-coherent; + }; + + pcie3_rc: pcie@2930000 { + compatible = "ti,j721e-pcie-host"; + reg = <0x00 0x02930000 0x00 0x1000>, + <0x00 0x02937000 0x00 0x400>, + <0x00 0x0e800000 0x00 0x00800000>, + <0x44 0x10000000 0x00 0x00001000>; + reg-names = "intd_cfg", "user_cfg", "reg", "cfg"; + interrupt-names = "link_state"; + interrupts = <GIC_SPI 354 IRQ_TYPE_EDGE_RISING>; + device_type = "pci"; + ti,syscon-pcie-ctrl = <&pcie3_ctrl>; + max-link-speed = <3>; + num-lanes = <2>; + power-domains = <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 242 1>; + clock-names = "fck"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0xf>; + vendor-id = <0x104c>; + device-id = <0xb00d>; + msi-map = <0x0 &gic_its 0x30000 0x10000>; + dma-coherent; + ranges = <0x01000000 0x0 0x00001000 0x44 0x10001000 0x0 0x0010000>, + <0x02000000 0x0 0x00011000 0x44 0x10011000 0x0 0x7fef000>; + dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>; + }; + + pcie3_ep: pcie-ep@2930000 { + compatible = "ti,j721e-pcie-ep"; + reg = <0x00 0x02930000 0x00 0x1000>, + <0x00 0x02937000 0x00 0x400>, + <0x00 0x0e800000 0x00 0x00800000>, + <0x44 0x10000000 0x00 0x08000000>; + reg-names = "intd_cfg", "user_cfg", "reg", "mem"; + interrupt-names = "link_state"; + interrupts = <GIC_SPI 354 IRQ_TYPE_EDGE_RISING>; + ti,syscon-pcie-ctrl = <&pcie3_ctrl>; + max-link-speed = <3>; + num-lanes = <2>; + power-domains = <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 242 1>; + clock-names = "fck"; + cdns,max-outbound-regions = <16>; + max-functions = /bits/ 8 <6>; + max-virtual-functions = /bits/ 16 <4 4 4 4 0 0>; + dma-coherent; + #address-cells = <2>; + #size-cells = <2>; + }; + main_uart0: serial@2800000 { compatible = "ti,j721e-uart", "ti,am654-uart"; reg = <0x00 0x02800000 0x00 0x100>; @@ -865,7 +1119,7 @@ no-1-8-v; }; - usbss0: cdns_usb@4104000 { + usbss0: cdns-usb@4104000 { compatible = "ti,j721e-usb"; reg = <0x00 0x4104000 0x00 0x100>; dma-coherent; @@ -895,7 +1149,7 @@ }; }; - usbss1: cdns_usb@4114000 { + usbss1: cdns-usb@4114000 { compatible = "ti,j721e-usb"; reg = <0x00 0x4114000 0x00 0x100>; dma-coherent; @@ -1326,4 +1580,42 @@ assigned-clocks = <&k3_clks 253 1>; assigned-clock-parents = <&k3_clks 253 5>; }; + + c66_0: dsp@4d80800000 { + compatible = "ti,j721e-c66-dsp"; + reg = <0x4d 0x80800000 0x00 0x00048000>, + <0x4d 0x80e00000 0x00 0x00008000>, + <0x4d 0x80f00000 0x00 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + ti,sci = <&dmsc>; + ti,sci-dev-id = <142>; + ti,sci-proc-ids = <0x03 0xff>; + resets = <&k3_reset 142 1>; + firmware-name = "j7-c66_0-fw"; + }; + + c66_1: dsp@4d81800000 { + compatible = "ti,j721e-c66-dsp"; + reg = <0x4d 0x81800000 0x00 0x00048000>, + <0x4d 0x81e00000 0x00 0x00008000>, + <0x4d 0x81f00000 0x00 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + ti,sci = <&dmsc>; + ti,sci-dev-id = <143>; + ti,sci-proc-ids = <0x04 0xff>; + resets = <&k3_reset 143 1>; + firmware-name = "j7-c66_1-fw"; + }; + + c71_0: dsp@64800000 { + compatible = "ti,j721e-c71-dsp"; + reg = <0x00 0x64800000 0x00 0x00080000>, + <0x00 0x64e00000 0x00 0x0000c000>; + reg-names = "l2sram", "l1dram"; + ti,sci = <&dmsc>; + ti,sci-dev-id = <15>; + ti,sci-proc-ids = <0x30 0xff>; + resets = <&k3_reset 15 1>; + firmware-name = "j7-c71_0-fw"; + }; }; 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 c4a48e8d420a..e581cb1d87ee 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi @@ -53,7 +53,7 @@ reg = <0x0 0x43000014 0x0 0x4>; }; - wkup_pmx0: pinmux@4301c000 { + wkup_pmx0: pinctrl@4301c000 { compatible = "pinctrl-single"; /* Proxy 0 addressing */ reg = <0x00 0x4301c000 0x00 0x178>; @@ -249,7 +249,7 @@ }; }; - mcu_navss { + mcu-navss { compatible = "simple-mfd"; #address-cells = <2>; #size-cells = <2>; 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 8fa3361e5e45..5dc3ba739131 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi @@ -25,11 +25,53 @@ alignment = <0x1000>; no-map; }; + + c66_1_dma_memory_region: c66-dma-memory@a6000000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa6000000 0x00 0x100000>; + no-map; + }; + + c66_0_memory_region: c66-memory@a6100000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa6100000 0x00 0xf00000>; + no-map; + }; + + c66_0_dma_memory_region: c66-dma-memory@a7000000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa7000000 0x00 0x100000>; + no-map; + }; + + c66_1_memory_region: c66-memory@a7100000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa7100000 0x00 0xf00000>; + no-map; + }; + + c71_0_dma_memory_region: c71-dma-memory@a8000000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa8000000 0x00 0x100000>; + no-map; + }; + + c71_0_memory_region: c71-memory@a8100000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa8100000 0x00 0xf00000>; + no-map; + }; + + rtos_ipc_memory_region: ipc-memories@aa000000 { + reg = <0x00 0xaa000000 0x00 0x01c00000>; + alignment = <0x1000>; + no-map; + }; }; }; &wkup_pmx0 { - wkup_i2c0_pins_default: wkup_i2c0_pins_default { + wkup_i2c0_pins_default: wkup-i2c0-pins-default { pinctrl-single,pins = < J721E_WKUP_IOPAD(0xf8, PIN_INPUT_PULLUP, 0) /* (J25) WKUP_I2C0_SCL */ J721E_WKUP_IOPAD(0xfc, PIN_INPUT_PULLUP, 0) /* (H24) WKUP_I2C0_SDA */ @@ -72,3 +114,114 @@ #size-cells = <1>; }; }; + +&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 { + interrupts = <428>; + + mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 { + ti,mbox-rx = <0 0 0>; + ti,mbox-tx = <1 0 0>; + }; + + mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 { + ti,mbox-rx = <2 0 0>; + ti,mbox-tx = <3 0 0>; + }; +}; + +&mailbox0_cluster3 { + interrupts = <424>; + + mbox_c66_0: mbox-c66-0 { + ti,mbox-rx = <0 0 0>; + ti,mbox-tx = <1 0 0>; + }; + + mbox_c66_1: mbox-c66-1 { + ti,mbox-rx = <2 0 0>; + ti,mbox-tx = <3 0 0>; + }; +}; + +&mailbox0_cluster4 { + interrupts = <420>; + + mbox_c71_0: mbox-c71-0 { + ti,mbox-rx = <0 0 0>; + ti,mbox-tx = <1 0 0>; + }; +}; + +&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"; +}; + +&c66_0 { + mboxes = <&mailbox0_cluster3 &mbox_c66_0>; + memory-region = <&c66_0_dma_memory_region>, + <&c66_0_memory_region>; +}; + +&c66_1 { + mboxes = <&mailbox0_cluster3 &mbox_c66_1>; + memory-region = <&c66_1_dma_memory_region>, + <&c66_1_memory_region>; +}; + +&c71_0 { + mboxes = <&mailbox0_cluster4 &mbox_c71_0>; + memory-region = <&c71_0_dma_memory_region>, + <&c71_0_memory_region>; +}; diff --git a/arch/arm64/boot/dts/ti/k3-j721e.dtsi b/arch/arm64/boot/dts/ti/k3-j721e.dtsi index d035b61e0e16..cc483f7344af 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721e.dtsi @@ -120,21 +120,24 @@ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>; }; - cbass_main: interconnect@100000 { + cbass_main: bus@100000 { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */ <0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */ <0x00 0x00900000 0x00 0x00900000 0x00 0x00012000>, /* serdes */ - <0x00 0x00A40000 0x00 0x00A40000 0x00 0x00000800>, /* timesync router */ + <0x00 0x00a40000 0x00 0x00a40000 0x00 0x00000800>, /* timesync router */ <0x00 0x06000000 0x00 0x06000000 0x00 0x00400000>, /* USBSS0 */ <0x00 0x06400000 0x00 0x06400000 0x00 0x00400000>, /* USBSS1 */ <0x00 0x01000000 0x00 0x01000000 0x00 0x0af02400>, /* Most peripherals */ <0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>, /* MAIN NAVSS */ - <0x00 0x0d000000 0x00 0x0d000000 0x00 0x01000000>, /* PCIe Core*/ + <0x00 0x0d000000 0x00 0x0d000000 0x00 0x01800000>, /* PCIe Core*/ + <0x00 0x0e000000 0x00 0x0e000000 0x00 0x01800000>, /* PCIe Core*/ <0x00 0x10000000 0x00 0x10000000 0x00 0x10000000>, /* PCIe DAT */ <0x00 0x64800000 0x00 0x64800000 0x00 0x00800000>, /* C71 */ + <0x44 0x00000000 0x44 0x00000000 0x00 0x08000000>, /* PCIe2 DAT */ + <0x44 0x10000000 0x44 0x10000000 0x00 0x08000000>, /* PCIe3 DAT */ <0x4d 0x80800000 0x4d 0x80800000 0x00 0x00800000>, /* C66_0 */ <0x4d 0x81800000 0x4d 0x81800000 0x00 0x00800000>, /* C66_1 */ <0x4e 0x20000000 0x4e 0x20000000 0x00 0x00080000>, /* GPU */ @@ -155,7 +158,7 @@ <0x05 0x00000000 0x05 0x00000000 0x01 0x00000000>, <0x07 0x00000000 0x07 0x00000000 0x01 0x00000000>; - cbass_mcu_wakeup: interconnect@28380000 { + cbass_mcu_wakeup: bus@28380000 { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; diff --git a/arch/arm64/boot/dts/toshiba/Makefile b/arch/arm64/boot/dts/toshiba/Makefile new file mode 100644 index 000000000000..8cd460d5b68e --- /dev/null +++ b/arch/arm64/boot/dts/toshiba/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +dtb-$(CONFIG_ARCH_VISCONTI) += tmpv7708-rm-mbrc.dtb diff --git a/arch/arm64/boot/dts/toshiba/tmpv7708-rm-mbrc.dts b/arch/arm64/boot/dts/toshiba/tmpv7708-rm-mbrc.dts new file mode 100644 index 000000000000..ed0bf7f13f54 --- /dev/null +++ b/arch/arm64/boot/dts/toshiba/tmpv7708-rm-mbrc.dts @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree File for TMPV7708 RM main board + * + * (C) Copyright 2020, Toshiba Corporation. + * (C) Copyright 2020, Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp> + */ + +/dts-v1/; + +#include "tmpv7708.dtsi" + +/ { + model = "Toshiba TMPV7708 RM main board"; + compatible = "toshiba,tmpv7708-rm-mbrc", "toshiba,tmpv7708"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + /* 768MB memory */ + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x30000000>; + }; +}; + +&uart0 { + status = "okay"; + clocks = <&uart_clk>; + clock-names = "apb_pclk"; +}; + +&uart1 { + status = "okay"; + clocks = <&uart_clk>; + clock-names = "apb_pclk"; +}; diff --git a/arch/arm64/boot/dts/toshiba/tmpv7708.dtsi b/arch/arm64/boot/dts/toshiba/tmpv7708.dtsi new file mode 100644 index 000000000000..242f25f4e12a --- /dev/null +++ b/arch/arm64/boot/dts/toshiba/tmpv7708.dtsi @@ -0,0 +1,390 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree Source for the TMPV7708 + * + * (C) Copyright 2018 - 2020, Toshiba Corporation. + * (C) Copyright 2020, Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp> + * + */ + +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> + +/memreserve/ 0x81000000 0x00300000; /* cpu-release-addr */ + +/ { + compatible = "toshiba,tmpv7708"; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + 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>; + }; + }; + }; + + cpu0: cpu@0 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x81100000>; + reg = <0x00>; + }; + + cpu1: cpu@1 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x81100000>; + reg = <0x01>; + }; + + cpu2: cpu@2 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x81100000>; + reg = <0x02>; + }; + + cpu3: cpu@3 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x81100000>; + reg = <0x03>; + }; + + cpu4: cpu@100 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x81100000>; + reg = <0x100>; + }; + + cpu5: cpu@101 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x81100000>; + reg = <0x101>; + }; + + cpu6: cpu@102 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x81100000>; + reg = <0x102>; + }; + + cpu7: cpu@103 { + compatible = "arm,cortex-a53"; + device_type = "cpu"; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x81100000>; + reg = <0x103>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = + <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>; + }; + + uart_clk: uart-clk { + compatible = "fixed-clock"; + clock-frequency = <150000000>; + #clock-cells = <0>; + }; + + soc { + #address-cells = <2>; + #size-cells = <2>; + compatible = "simple-bus"; + interrupt-parent = <&gic>; + ranges; + + gic: interrupt-controller@24001000 { + compatible = "arm,gic-400"; + interrupt-controller; + #interrupt-cells = <3>; + interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>; + reg = <0 0x24001000 0 0x1000>, + <0 0x24002000 0 0x2000>, + <0 0x24004000 0 0x2000>, + <0 0x24006000 0 0x2000>; + }; + + pmux: pmux@24190000 { + compatible = "toshiba,tmpv7708-pinctrl"; + reg = <0 0x24190000 0 0x10000>; + }; + + uart0: serial@28200000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0 0x28200000 0 0x1000>; + interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "disabled"; + }; + + uart1: serial@28201000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0 0x28201000 0 0x1000>; + interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; + }; + + uart2: serial@28202000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0 0x28202000 0 0x1000>; + interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + status = "disabled"; + }; + + uart3: serial@28203000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0 0x28203000 0 0x1000>; + interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; + status = "disabled"; + }; + + i2c0: i2c@28030000 { + compatible = "snps,designware-i2c"; + reg = <0 0x28030000 0 0x1000>; + interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c@28031000 { + compatible = "snps,designware-i2c"; + reg = <0 0x28031000 0 0x1000>; + interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c@28032000 { + compatible = "snps,designware-i2c"; + reg = <0 0x28032000 0 0x1000>; + interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c3: i2c@28033000 { + compatible = "snps,designware-i2c"; + reg = <0 0x28033000 0 0x1000>; + interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_pins>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c4: i2c@28034000 { + compatible = "snps,designware-i2c"; + reg = <0 0x28034000 0 0x1000>; + interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_pins>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c5: i2c@28035000 { + compatible = "snps,designware-i2c"; + reg = <0 0x28035000 0 0x1000>; + interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c5_pins>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c6: i2c@28036000 { + compatible = "snps,designware-i2c"; + reg = <0 0x28036000 0 0x1000>; + interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6_pins>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c7: i2c@28037000 { + compatible = "snps,designware-i2c"; + reg = <0 0x28037000 0 0x1000>; + interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c7_pins>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c8: i2c@28038000 { + compatible = "snps,designware-i2c"; + reg = <0 0x28038000 0 0x1000>; + interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c8_pins>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi0: spi@28140000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0 0x28140000 0 0x1000>; + interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + num-cs = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi1: spi@28141000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0 0x28141000 0 0x1000>; + interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_pins>; + num-cs = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi2: spi@28142000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0 0x28142000 0 0x1000>; + interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&spi2_pins>; + num-cs = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi3: spi@28143000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0 0x28143000 0 0x1000>; + interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&spi3_pins>; + num-cs = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi4: spi@28144000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0 0x28144000 0 0x1000>; + interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&spi4_pins>; + num-cs = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi5: spi@28145000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0 0x28145000 0 0x1000>; + interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&spi5_pins>; + num-cs = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi6: spi@28146000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0 0x28146000 0 0x1000>; + interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&spi6_pins>; + num-cs = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; +}; + +#include "tmpv7708_pins.dtsi" diff --git a/arch/arm64/boot/dts/toshiba/tmpv7708_pins.dtsi b/arch/arm64/boot/dts/toshiba/tmpv7708_pins.dtsi new file mode 100644 index 000000000000..34de00015a7f --- /dev/null +++ b/arch/arm64/boot/dts/toshiba/tmpv7708_pins.dtsi @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +&pmux { + spi0_pins: spi0-pins { + function = "spi0"; + groups = "spi0_grp"; + }; + spi1_pins: spi1-pins { + function = "spi1"; + groups = "spi1_grp"; + }; + spi2_pins: spi2-pins { + function = "spi2"; + groups = "spi2_grp"; + }; + spi3_pins: spi3-pins { + function = "spi3"; + groups = "spi3_grp"; + }; + spi4_pins: spi4-pins { + function = "spi4"; + groups = "spi4_grp"; + }; + spi5_pins: spi5-pins { + function = "spi5"; + groups = "spi5_grp"; + }; + spi6_pins: spi6-pins { + function = "spi6"; + groups = "spi6_grp"; + }; + uart0_pins: uart0-pins { + function = "uart0"; + groups = "uart0_grp"; + }; + uart1_pins: uart1-pins { + function = "uart1"; + groups = "uart1_grp"; + }; + uart2_pins: uart2-pins { + function = "uart2"; + groups = "uart2_grp"; + }; + uart3_pins: uart3-pins { + function = "uart3"; + groups = "uart3_grp"; + }; + i2c0_pins: i2c0-pins { + function = "i2c0"; + groups = "i2c0_grp"; + bias-pull-up; + }; + i2c1_pins: i2c1-pins { + function = "i2c1"; + groups = "i2c1_grp"; + bias-pull-up; + }; + i2c2_pins: i2c2-pins { + function = "i2c2"; + groups = "i2c2_grp"; + bias-pull-up; + }; + i2c3_pins: i2c3-pins { + function = "i2c3"; + groups = "i2c3_grp"; + bias-pull-up; + }; + i2c4_pins: i2c4-pins { + function = "i2c4"; + groups = "i2c4_grp"; + bias-pull-up; + }; + i2c5_pins: i2c5-pins { + function = "i2c5"; + groups = "i2c5_grp"; + bias-pull-up; + }; + i2c6_pins: i2c6-pins { + function = "i2c6"; + groups = "i2c6_grp"; + bias-pull-up; + }; + i2c7_pins: i2c7-pins { + function = "i2c7"; + groups = "i2c7_grp"; + bias-pull-up; + }; + i2c8_pins: i2c8-pins { + function = "i2c8"; + groups = "i2c8_grp"; + bias-pull-up; + }; +}; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi index 9868ca15dfc5..c94c3bb67edc 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi @@ -10,35 +10,30 @@ #include <dt-bindings/clock/xlnx-zynqmp-clk.h> / { pss_ref_clk: pss_ref_clk { - u-boot,dm-pre-reloc; compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <33333333>; }; video_clk: video_clk { - u-boot,dm-pre-reloc; compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <27000000>; }; pss_alt_ref_clk: pss_alt_ref_clk { - u-boot,dm-pre-reloc; compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; gt_crx_ref_clk: gt_crx_ref_clk { - u-boot,dm-pre-reloc; compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <108000000>; }; aux_ref_clk: aux_ref_clk { - u-boot,dm-pre-reloc; compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <27000000>; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts index d60110ad8367..68ecd0f7b2f2 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts @@ -56,27 +56,27 @@ leds { compatible = "gpio-leds"; - ds2 { + led-ds2 { label = "ds2"; gpios = <&gpio 20 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; }; - ds3 { + led-ds3 { label = "ds3"; gpios = <&gpio 19 GPIO_ACTIVE_HIGH>; linux,default-trigger = "phy0tx"; /* WLAN tx */ default-state = "off"; }; - ds4 { + led-ds4 { label = "ds4"; gpios = <&gpio 18 GPIO_ACTIVE_HIGH>; linux,default-trigger = "phy0rx"; /* WLAN rx */ default-state = "off"; }; - ds5 { + led-ds5 { label = "ds5"; gpios = <&gpio 17 GPIO_ACTIVE_HIGH>; linux,default-trigger = "bluetooth-power"; @@ -186,7 +186,7 @@ compatible = "ti,tps65086"; reg = <0x5e>; interrupt-parent = <&gpio>; - interrupts = <77 GPIO_ACTIVE_LOW>; + interrupts = <77 IRQ_TYPE_LEVEL_LOW>; #gpio-cells = <2>; gpio-controller; }; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts index 4f801721564f..f1255f635dfd 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts @@ -203,25 +203,25 @@ gpio-line-names = "PS_GTR_LAN_SEL0", "PS_GTR_LAN_SEL1", "PS_GTR_LAN_SEL2", "PS_GTR_LAN_SEL3", "PCI_CLK_DIR_SEL", "IIC_MUX_RESET_B", "GEM3_EXP_RESET_B", "", "", "", "", "", "", "", "", ""; - gtr-sel0 { + gtr-sel0-hog { gpio-hog; gpios = <0 0>; output-low; /* PCIE = 0, DP = 1 */ line-name = "sel0"; }; - gtr-sel1 { + gtr-sel1-hog { gpio-hog; gpios = <1 0>; output-high; /* PCIE = 0, DP = 1 */ line-name = "sel1"; }; - gtr-sel2 { + gtr-sel2-hog { gpio-hog; gpios = <2 0>; output-high; /* PCIE = 0, USB0 = 1 */ line-name = "sel2"; }; - gtr-sel3 { + gtr-sel3-hog { gpio-hog; gpios = <3 0>; output-high; /* PCIE = 0, SATA = 1 */ diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index 9174ddc76bdc..771f60e0346d 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -13,6 +13,7 @@ */ #include <dt-bindings/power/xlnx-zynqmp-power.h> +#include <dt-bindings/reset/xlnx-zynqmp-resets.h> / { compatible = "xlnx,zynqmp"; @@ -130,7 +131,6 @@ }; zynqmp_clk: clock-controller { - u-boot,dm-pre-reloc; #clock-cells = <1>; compatible = "xlnx,zynqmp-clk"; clocks = <&pss_ref_clk>, @@ -182,7 +182,7 @@ ranges; }; - amba_apu: amba-apu@0 { + amba_apu: axi@0 { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <1>; @@ -201,7 +201,7 @@ }; }; - amba: amba { + amba: axi { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; @@ -500,7 +500,7 @@ }; i2c0: i2c@ff020000 { - compatible = "cdns,i2c-r1p14", "cdns,i2c-r1p10"; + compatible = "cdns,i2c-r1p14"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 17 4>; @@ -511,7 +511,7 @@ }; i2c1: i2c@ff030000 { - compatible = "cdns,i2c-r1p14", "cdns,i2c-r1p10"; + compatible = "cdns,i2c-r1p14"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 18 4>; @@ -558,6 +558,15 @@ }; }; + psgtr: phy@fd400000 { + compatible = "xlnx,zynqmp-psgtr-v1.1"; + status = "disabled"; + reg = <0x0 0xfd400000 0x0 0x40000>, + <0x0 0xfd3d0000 0x0 0x1000>; + reg-names = "serdes", "siou"; + #phy-cells = <4>; + }; + rtc: rtc@ffa60000 { compatible = "xlnx,zynqmp-rtc"; status = "disabled"; @@ -601,7 +610,7 @@ power-domains = <&zynqmp_firmware PD_SD_1>; }; - smmu: smmu@fd800000 { + smmu: iommu@fd800000 { compatible = "arm,mmu-500"; reg = <0x0 0xfd800000 0x0 0x20000>; status = "disabled"; diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index e0f33826819f..17a2df6a263e 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -57,6 +57,7 @@ CONFIG_ARCH_THUNDER=y CONFIG_ARCH_THUNDER2=y CONFIG_ARCH_UNIPHIER=y CONFIG_ARCH_VEXPRESS=y +CONFIG_ARCH_VISCONTI=y CONFIG_ARCH_XGENE=y CONFIG_ARCH_ZX=y CONFIG_ARCH_ZYNQMP=y @@ -199,6 +200,9 @@ CONFIG_MAC80211_LEDS=y CONFIG_RFKILL=m CONFIG_NET_9P=y CONFIG_NET_9P_VIRTIO=y +CONFIG_NFC=m +CONFIG_NFC_NCI=m +CONFIG_NFC_S3FWRN5_I2C=m CONFIG_PCI=y CONFIG_PCIEPORTBUS=y CONFIG_PCI_IOV=y @@ -208,6 +212,7 @@ CONFIG_HOTPLUG_PCI_ACPI=y CONFIG_PCI_AARDVARK=y CONFIG_PCI_TEGRA=y CONFIG_PCIE_RCAR_HOST=y +CONFIG_PCIE_RCAR_EP=y CONFIG_PCI_HOST_GENERIC=y CONFIG_PCI_XGENE=y CONFIG_PCIE_ALTERA=y @@ -224,6 +229,9 @@ CONFIG_PCIE_ARMADA_8K=y CONFIG_PCIE_KIRIN=y CONFIG_PCIE_HISI_STB=y CONFIG_PCIE_TEGRA194_HOST=m +CONFIG_PCI_ENDPOINT=y +CONFIG_PCI_ENDPOINT_CONFIGFS=y +CONFIG_PCI_EPF_TEST=m CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_FW_LOADER_USER_HELPER=y @@ -231,6 +239,7 @@ CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y CONFIG_HISILICON_LPC=y CONFIG_SIMPLE_PM_BUS=y CONFIG_FSL_MC_BUS=y +CONFIG_TEGRA_ACONNECT=m CONFIG_MTD=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y @@ -254,6 +263,7 @@ CONFIG_BLK_DEV_NBD=m CONFIG_VIRTIO_BLK=y CONFIG_BLK_DEV_NVME=m CONFIG_SRAM=y +CONFIG_PCI_ENDPOINT_TEST=m CONFIG_EEPROM_AT24=m CONFIG_EEPROM_AT25=m CONFIG_UACCE=m @@ -453,6 +463,7 @@ CONFIG_SPI_MESON_SPIFC=m CONFIG_SPI_ORION=y CONFIG_SPI_PL022=y CONFIG_SPI_ROCKCHIP=y +CONFIG_SPI_RPCIF=m CONFIG_SPI_QCOM_QSPI=m CONFIG_SPI_QUP=y CONFIG_SPI_QCOM_GENI=m @@ -500,6 +511,7 @@ CONFIG_GPIO_PCA953X=y CONFIG_GPIO_PCA953X_IRQ=y CONFIG_GPIO_BD9571MWV=m CONFIG_GPIO_MAX77620=y +CONFIG_GPIO_SL28CPLD=m CONFIG_POWER_AVS=y CONFIG_QCOM_CPR=y CONFIG_ROCKCHIP_IODOMAIN=y @@ -513,6 +525,7 @@ CONFIG_SENSORS_ARM_SCPI=y CONFIG_SENSORS_LM90=m CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_RASPBERRYPI_HWMON=m +CONFIG_SENSORS_SL28CPLD=m CONFIG_SENSORS_INA2XX=m CONFIG_SENSORS_INA3221=m CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y @@ -535,6 +548,7 @@ CONFIG_QCOM_TSENS=y CONFIG_QCOM_SPMI_TEMP_ALARM=m CONFIG_UNIPHIER_THERMAL=y CONFIG_WATCHDOG=y +CONFIG_SL28CPLD_WATCHDOG=m CONFIG_ARM_SP805_WATCHDOG=y CONFIG_ARM_SBSA_WATCHDOG=y CONFIG_ARM_SMC_WATCHDOG=y @@ -560,6 +574,7 @@ CONFIG_MFD_MAX77620=y CONFIG_MFD_SPMI_PMIC=y CONFIG_MFD_RK808=y CONFIG_MFD_SEC_CORE=y +CONFIG_MFD_SL28CPLD=y CONFIG_MFD_ROHM_BD718XX=y CONFIG_MFD_WCD934X=m CONFIG_REGULATOR_FIXED_VOLTAGE=y @@ -640,10 +655,14 @@ CONFIG_DRM_MSM=m CONFIG_DRM_TEGRA=m CONFIG_DRM_PANEL_LVDS=m CONFIG_DRM_PANEL_SIMPLE=m -CONFIG_DRM_SIMPLE_BRIDGE=m +CONFIG_DRM_PANEL_RAYDIUM_RM67191=m +CONFIG_DRM_PANEL_SITRONIX_ST7703=m CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m CONFIG_DRM_DISPLAY_CONNECTOR=m +CONFIG_DRM_NWL_MIPI_DSI=m +CONFIG_DRM_LONTIUM_LT9611=m CONFIG_DRM_SII902X=m +CONFIG_DRM_SIMPLE_BRIDGE=m CONFIG_DRM_THINE_THC63LVD1024=m CONFIG_DRM_TI_SN65DSI86=m CONFIG_DRM_I2C_ADV7511=m @@ -654,6 +673,7 @@ CONFIG_DRM_VC4=m CONFIG_DRM_ETNAVIV=m CONFIG_DRM_HISI_HIBMC=m CONFIG_DRM_HISI_KIRIN=m +CONFIG_DRM_MXSFB=m CONFIG_DRM_MESON=m CONFIG_DRM_PL111=m CONFIG_DRM_LIMA=m @@ -676,6 +696,9 @@ CONFIG_SND_BCM2835_SOC_I2S=m CONFIG_SND_SOC_FSL_SAI=m CONFIG_SND_MESON_AXG_SOUND_CARD=m CONFIG_SND_MESON_GX_SOUND_CARD=m +CONFIG_SND_SOC_QCOM=m +CONFIG_SND_SOC_APQ8016_SBC=m +CONFIG_SND_SOC_MSM8996=m CONFIG_SND_SOC_SDM845=m CONFIG_SND_SOC_ROCKCHIP=m CONFIG_SND_SOC_ROCKCHIP_SPDIF=m @@ -684,6 +707,12 @@ CONFIG_SND_SOC_RK3399_GRU_SOUND=m CONFIG_SND_SOC_SAMSUNG=y CONFIG_SND_SOC_RCAR=m CONFIG_SND_SUN4I_SPDIF=m +CONFIG_SND_SOC_TEGRA=m +CONFIG_SND_SOC_TEGRA210_AHUB=m +CONFIG_SND_SOC_TEGRA210_DMIC=m +CONFIG_SND_SOC_TEGRA210_I2S=m +CONFIG_SND_SOC_TEGRA186_DSPK=m +CONFIG_SND_SOC_TEGRA210_ADMAIF=m CONFIG_SND_SOC_AK4613=m CONFIG_SND_SOC_ES7134=m CONFIG_SND_SOC_ES7241=m @@ -709,6 +738,7 @@ CONFIG_USB_OHCI_EXYNOS=y CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_RENESAS_USBHS_HCD=m CONFIG_USB_RENESAS_USBHS=m +CONFIG_USB_ACM=m CONFIG_USB_STORAGE=y CONFIG_USB_MUSB_HDRC=y CONFIG_USB_MUSB_SUNXI=y @@ -718,12 +748,25 @@ CONFIG_USB_CHIPIDEA=y CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y CONFIG_USB_ISP1760=y +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_HSIC_USB3503=y CONFIG_NOP_USB_XCEIV=y CONFIG_USB_GADGET=y CONFIG_USB_RENESAS_USBHS_UDC=m CONFIG_USB_RENESAS_USB3=m CONFIG_USB_TEGRA_XUDC=m +CONFIG_USB_CONFIGFS=m +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_OBEX=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_FS=y CONFIG_TYPEC=m CONFIG_TYPEC_TCPM=m CONFIG_TYPEC_FUSB302=m @@ -800,6 +843,7 @@ CONFIG_MV_XOR_V2=y CONFIG_OWL_DMA=y CONFIG_PL330_DMA=y CONFIG_TEGRA20_APB_DMA=y +CONFIG_TEGRA210_ADMA=m CONFIG_QCOM_BAM_DMA=y CONFIG_QCOM_HIDMA_MGMT=y CONFIG_QCOM_HIDMA=y @@ -827,6 +871,7 @@ CONFIG_COMMON_CLK_FSL_SAI=y CONFIG_COMMON_CLK_S2MPS11=y CONFIG_COMMON_CLK_PWM=y CONFIG_COMMON_CLK_VC5=y +CONFIG_COMMON_CLK_BD718XX=m CONFIG_CLK_RASPBERRYPI=m CONFIG_CLK_IMX8MM=y CONFIG_CLK_IMX8MN=y @@ -854,6 +899,8 @@ CONFIG_SDM_VIDEOCC_845=y CONFIG_SDM_DISPCC_845=y CONFIG_SM_GCC_8150=y CONFIG_SM_GCC_8250=y +CONFIG_SM_GPUCC_8150=y +CONFIG_SM_GPUCC_8250=y CONFIG_QCOM_HFPLL=y CONFIG_HWSPINLOCK=y CONFIG_HWSPINLOCK_QCOM=y @@ -914,8 +961,10 @@ CONFIG_ARCH_TEGRA_194_SOC=y CONFIG_ARCH_K3_AM6_SOC=y CONFIG_ARCH_K3_J721E_SOC=y CONFIG_TI_SCI_PM_DOMAINS=y +CONFIG_EXTCON_PTN5150=m CONFIG_EXTCON_USB_GPIO=y CONFIG_EXTCON_USBC_CROS_EC=y +CONFIG_RENESAS_RPCIF=m CONFIG_IIO=y CONFIG_EXYNOS_ADC=y CONFIG_MAX9611=m @@ -934,14 +983,18 @@ CONFIG_PWM_MESON=m CONFIG_PWM_RCAR=m CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_SAMSUNG=y +CONFIG_PWM_SL28CPLD=m CONFIG_PWM_SUN4I=m CONFIG_PWM_TEGRA=m +CONFIG_SL28CPLD_INTC=y CONFIG_QCOM_PDC=y +CONFIG_RESET_IMX7=y CONFIG_RESET_QCOM_AOSS=y CONFIG_RESET_QCOM_PDC=m CONFIG_RESET_TI_SCI=y CONFIG_PHY_XGENE=y CONFIG_PHY_SUN4I_USB=y +CONFIG_PHY_MIXEL_MIPI_DPHY=m CONFIG_PHY_HI6220_USB=y CONFIG_PHY_HISTB_COMBPHY=y CONFIG_PHY_HISI_INNO_USB2=y @@ -949,6 +1002,7 @@ CONFIG_PHY_MVEBU_CP110_COMPHY=y CONFIG_PHY_QCOM_QMP=m CONFIG_PHY_QCOM_QUSB2=m CONFIG_PHY_QCOM_USB_HS=y +CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y CONFIG_PHY_RCAR_GEN3_PCIE=y CONFIG_PHY_RCAR_GEN3_USB2=y CONFIG_PHY_RCAR_GEN3_USB3=m @@ -984,6 +1038,12 @@ CONFIG_SLIMBUS=m CONFIG_SLIM_QCOM_CTRL=m CONFIG_SLIM_QCOM_NGD_CTRL=m CONFIG_MUX_MMIO=y +CONFIG_INTERCONNECT=y +CONFIG_INTERCONNECT_QCOM=y +CONFIG_INTERCONNECT_QCOM_MSM8916=m +CONFIG_INTERCONNECT_QCOM_SDM845=m +CONFIG_INTERCONNECT_QCOM_SM8150=m +CONFIG_INTERCONNECT_QCOM_SM8250=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_EXT4_FS_POSIX_ACL=y diff --git a/arch/arm64/crypto/aes-neonbs-core.S b/arch/arm64/crypto/aes-neonbs-core.S index b357164379f6..63a52ad9a75c 100644 --- a/arch/arm64/crypto/aes-neonbs-core.S +++ b/arch/arm64/crypto/aes-neonbs-core.S @@ -788,7 +788,7 @@ SYM_FUNC_START_LOCAL(__xts_crypt8) 0: mov bskey, x21 mov rounds, x22 - br x7 + br x16 SYM_FUNC_END(__xts_crypt8) .macro __xts_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7 @@ -806,7 +806,7 @@ SYM_FUNC_END(__xts_crypt8) uzp1 v30.4s, v30.4s, v25.4s ld1 {v25.16b}, [x24] -99: adr x7, \do8 +99: adr x16, \do8 bl __xts_crypt8 ldp q16, q17, [sp, #.Lframe_local_offset] diff --git a/arch/arm64/crypto/ghash-ce-glue.c b/arch/arm64/crypto/ghash-ce-glue.c index da1034867aaa..8536008e3e35 100644 --- a/arch/arm64/crypto/ghash-ce-glue.c +++ b/arch/arm64/crypto/ghash-ce-glue.c @@ -347,7 +347,7 @@ static int gcm_encrypt(struct aead_request *req) u8 buf[AES_BLOCK_SIZE]; u8 iv[AES_BLOCK_SIZE]; u64 dg[2] = {}; - u128 lengths; + be128 lengths; u8 *tag; int err; @@ -461,7 +461,7 @@ static int gcm_decrypt(struct aead_request *req) u8 buf[AES_BLOCK_SIZE]; u8 iv[AES_BLOCK_SIZE]; u64 dg[2] = {}; - u128 lengths; + be128 lengths; u8 *tag; int err; diff --git a/arch/arm64/crypto/sha1-ce-glue.c b/arch/arm64/crypto/sha1-ce-glue.c index 565ef604ca04..c63b99211db3 100644 --- a/arch/arm64/crypto/sha1-ce-glue.c +++ b/arch/arm64/crypto/sha1-ce-glue.c @@ -25,6 +25,9 @@ struct sha1_ce_state { u32 finalize; }; +extern const u32 sha1_ce_offsetof_count; +extern const u32 sha1_ce_offsetof_finalize; + asmlinkage void sha1_ce_transform(struct sha1_ce_state *sst, u8 const *src, int blocks); diff --git a/arch/arm64/crypto/sha2-ce-glue.c b/arch/arm64/crypto/sha2-ce-glue.c index 9450d19b9e6e..5e956d7582a5 100644 --- a/arch/arm64/crypto/sha2-ce-glue.c +++ b/arch/arm64/crypto/sha2-ce-glue.c @@ -25,6 +25,9 @@ struct sha256_ce_state { u32 finalize; }; +extern const u32 sha256_ce_offsetof_count; +extern const u32 sha256_ce_offsetof_finalize; + asmlinkage void sha2_ce_transform(struct sha256_ce_state *sst, u8 const *src, int blocks); diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h index 6647ae4f0231..880b9054d75c 100644 --- a/arch/arm64/include/asm/arch_gicv3.h +++ b/arch/arm64/include/asm/arch_gicv3.h @@ -153,7 +153,7 @@ static inline bool gic_prio_masking_enabled(void) static inline void gic_pmr_mask_irqs(void) { - BUILD_BUG_ON(GICD_INT_DEF_PRI < (GIC_PRIO_IRQOFF | + BUILD_BUG_ON(GICD_INT_DEF_PRI < (__GIC_PRIO_IRQOFF | GIC_PRIO_PSR_I_SET)); BUILD_BUG_ON(GICD_INT_DEF_PRI >= GIC_PRIO_IRQON); /* @@ -162,6 +162,12 @@ static inline void gic_pmr_mask_irqs(void) * are applied to IRQ priorities */ BUILD_BUG_ON((0x80 | (GICD_INT_DEF_PRI >> 1)) >= GIC_PRIO_IRQON); + /* + * Same situation as above, but now we make sure that we can mask + * regular interrupts. + */ + BUILD_BUG_ON((0x80 | (GICD_INT_DEF_PRI >> 1)) < (__GIC_PRIO_IRQOFF_NS | + GIC_PRIO_PSR_I_SET)); gic_write_pmr(GIC_PRIO_IRQOFF); } diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h index 44209f6146aa..ffb1a40d5475 100644 --- a/arch/arm64/include/asm/archrandom.h +++ b/arch/arm64/include/asm/archrandom.h @@ -79,10 +79,5 @@ arch_get_random_seed_long_early(unsigned long *v) } #define arch_get_random_seed_long_early arch_get_random_seed_long_early -#else - -static inline bool __arm64_rndr(unsigned long *v) { return false; } -static inline bool __init __early_cpu_has_rndr(void) { return false; } - #endif /* CONFIG_ARCH_RANDOM */ #endif /* _ASM_ARCHRANDOM_H */ diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h index fb4c27506ef4..c3009b0e5239 100644 --- a/arch/arm64/include/asm/barrier.h +++ b/arch/arm64/include/asm/barrier.h @@ -45,6 +45,7 @@ #define rmb() dsb(ld) #define wmb() dsb(st) +#define dma_mb() dmb(osh) #define dma_rmb() dmb(oshld) #define dma_wmb() dmb(oshst) diff --git a/arch/arm64/include/asm/boot.h b/arch/arm64/include/asm/boot.h index c7f67da13cd9..3e7943fd17a4 100644 --- a/arch/arm64/include/asm/boot.h +++ b/arch/arm64/include/asm/boot.h @@ -13,8 +13,7 @@ #define MAX_FDT_SIZE SZ_2M /* - * arm64 requires the kernel image to placed - * TEXT_OFFSET bytes beyond a 2 MB aligned base + * arm64 requires the kernel image to placed at a 2 MB aligned base address */ #define MIN_KIMG_ALIGN SZ_2M diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h index a4d1b5f771f6..0ac3e06a2118 100644 --- a/arch/arm64/include/asm/cache.h +++ b/arch/arm64/include/asm/cache.h @@ -79,7 +79,7 @@ static inline u32 cache_type_cwg(void) return (read_cpuid_cachetype() >> CTR_CWG_SHIFT) & CTR_CWG_MASK; } -#define __read_mostly __section(.data..read_mostly) +#define __read_mostly __section(".data..read_mostly") static inline int cache_line_size_of_cpu(void) { diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h index 935d2aa231bf..23a9fb73c04f 100644 --- a/arch/arm64/include/asm/compat.h +++ b/arch/arm64/include/asm/compat.h @@ -35,8 +35,6 @@ typedef s32 compat_nlink_t; typedef u16 compat_ipc_pid_t; typedef u32 compat_caddr_t; typedef __kernel_fsid_t compat_fsid_t; -typedef s64 compat_s64; -typedef u64 compat_u64; struct compat_stat { #ifdef __AARCH64EB__ diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h index d28e8f37d3b4..e95c4df83911 100644 --- a/arch/arm64/include/asm/cpu_ops.h +++ b/arch/arm64/include/asm/cpu_ops.h @@ -21,7 +21,7 @@ * mechanism for doing so, tests whether it is possible to boot * the given CPU. * @cpu_boot: Boots a cpu into the kernel. - * @cpu_postboot: Optionally, perform any post-boot cleanup or necesary + * @cpu_postboot: Optionally, perform any post-boot cleanup or necessary * synchronisation. Called from the cpu being booted. * @cpu_can_disable: Determines whether a CPU can be disabled based on * mechanism-specific information. diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index c4ac9a13ad5f..42868dbd29fd 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -64,7 +64,8 @@ #define ARM64_BTI 54 #define ARM64_HAS_ARMv8_4_TTL 55 #define ARM64_HAS_TLB_RANGE 56 +#define ARM64_MTE 57 -#define ARM64_NCAPS 57 +#define ARM64_NCAPS 58 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 79d6a0371c78..97244d4feca9 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -358,7 +358,7 @@ static inline int cpucap_default_scope(const struct arm64_cpu_capabilities *cap) } /* - * Generic helper for handling capabilties with multiple (match,enable) pairs + * Generic helper for handling capabilities with multiple (match,enable) pairs * of call backs, sharing the same capability bit. * Iterate over each entry to see if at least one matches. */ @@ -703,6 +703,12 @@ static __always_inline bool system_uses_irq_prio_masking(void) cpus_have_const_cap(ARM64_HAS_IRQ_PRIO_MASKING); } +static inline bool system_supports_mte(void) +{ + return IS_ENABLED(CONFIG_ARM64_MTE) && + cpus_have_const_cap(ARM64_MTE); +} + static inline bool system_has_prio_mask_debugging(void) { return IS_ENABLED(CONFIG_ARM64_DEBUG_PRIORITY_MASKING) && diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index d4ab3f73e7a3..973b14415271 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -65,7 +65,7 @@ efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...); (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 dram_base) +static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr) { return ULONG_MAX; } @@ -80,8 +80,7 @@ static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base) * apply to other bootloaders, and are required for some kernel * configurations. */ -static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, - unsigned long image_addr) +static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr) { return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1)); } diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index 035003acfa87..22c81f1edda2 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -35,7 +35,9 @@ #define ESR_ELx_EC_SYS64 (0x18) #define ESR_ELx_EC_SVE (0x19) #define ESR_ELx_EC_ERET (0x1a) /* EL2 only */ -/* Unallocated EC: 0x1b - 0x1E */ +/* Unallocated EC: 0x1B */ +#define ESR_ELx_EC_FPAC (0x1C) /* EL1 and above */ +/* Unallocated EC: 0x1D - 0x1E */ #define ESR_ELx_EC_IMP_DEF (0x1f) /* EL3 only */ #define ESR_ELx_EC_IABT_LOW (0x20) #define ESR_ELx_EC_IABT_CUR (0x21) diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h index 7577a754d443..99b9383cd036 100644 --- a/arch/arm64/include/asm/exception.h +++ b/arch/arm64/include/asm/exception.h @@ -47,4 +47,5 @@ void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr); void do_cp15instr(unsigned int esr, struct pt_regs *regs); void do_el0_svc(struct pt_regs *regs); void do_el0_svc_compat(struct pt_regs *regs); +void do_ptrauth_fault(struct pt_regs *regs, unsigned int esr); #endif /* __ASM_EXCEPTION_H */ diff --git a/arch/arm64/include/asm/extable.h b/arch/arm64/include/asm/extable.h index 840a35ed92ec..b15eb4a3e6b2 100644 --- a/arch/arm64/include/asm/extable.h +++ b/arch/arm64/include/asm/extable.h @@ -22,6 +22,15 @@ struct exception_table_entry #define ARCH_HAS_RELATIVE_EXTABLE +static inline bool in_bpf_jit(struct pt_regs *regs) +{ + if (!IS_ENABLED(CONFIG_BPF_JIT)) + return false; + + return regs->pc >= BPF_JIT_REGION_START && + regs->pc < BPF_JIT_REGION_END; +} + #ifdef CONFIG_BPF_JIT int arm64_bpf_fixup_exception(const struct exception_table_entry *ex, struct pt_regs *regs); diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index 59f10dd13f12..bec5f14b622a 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -69,6 +69,9 @@ static inline void *sve_pffr(struct thread_struct *thread) extern void sve_save_state(void *state, u32 *pfpsr); extern void sve_load_state(void const *state, u32 const *pfpsr, unsigned long vq_minus_1); +extern void sve_flush_live(void); +extern void sve_load_from_fpsimd_state(struct user_fpsimd_state const *state, + unsigned long vq_minus_1); extern unsigned int sve_get_vl(void); struct arm64_cpu_capabilities; diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h index 636e9d9c7929..af43367534c7 100644 --- a/arch/arm64/include/asm/fpsimdmacros.h +++ b/arch/arm64/include/asm/fpsimdmacros.h @@ -164,25 +164,59 @@ | ((\np) << 5) .endm +/* PFALSE P\np.B */ +.macro _sve_pfalse np + _sve_check_preg \np + .inst 0x2518e400 \ + | (\np) +.endm + .macro __for from:req, to:req .if (\from) == (\to) - _for__body \from + _for__body %\from .else - __for \from, (\from) + ((\to) - (\from)) / 2 - __for (\from) + ((\to) - (\from)) / 2 + 1, \to + __for %\from, %((\from) + ((\to) - (\from)) / 2) + __for %((\from) + ((\to) - (\from)) / 2 + 1), %\to .endif .endm .macro _for var:req, from:req, to:req, insn:vararg .macro _for__body \var:req + .noaltmacro \insn + .altmacro .endm + .altmacro __for \from, \to + .noaltmacro .purgem _for__body .endm +/* Update ZCR_EL1.LEN with the new VQ */ +.macro sve_load_vq xvqminus1, xtmp, xtmp2 + mrs_s \xtmp, SYS_ZCR_EL1 + bic \xtmp2, \xtmp, ZCR_ELx_LEN_MASK + orr \xtmp2, \xtmp2, \xvqminus1 + cmp \xtmp2, \xtmp + b.eq 921f + msr_s SYS_ZCR_EL1, \xtmp2 //self-synchronising +921: +.endm + +/* Preserve the first 128-bits of Znz and zero the rest. */ +.macro _sve_flush_z nz + _sve_check_zreg \nz + mov v\nz\().16b, v\nz\().16b +.endm + +.macro sve_flush + _for n, 0, 31, _sve_flush_z \n + _for n, 0, 15, _sve_pfalse \n + _sve_wrffr 0 +.endm + .macro sve_save nxbase, xpfpsr, nxtmp _for n, 0, 31, _sve_str_v \n, \nxbase, \n - 34 _for n, 0, 15, _sve_str_p \n, \nxbase, \n - 16 @@ -197,13 +231,7 @@ .endm .macro sve_load nxbase, xpfpsr, xvqminus1, nxtmp, xtmp2 - mrs_s x\nxtmp, SYS_ZCR_EL1 - bic \xtmp2, x\nxtmp, ZCR_ELx_LEN_MASK - orr \xtmp2, \xtmp2, \xvqminus1 - cmp \xtmp2, x\nxtmp - b.eq 921f - msr_s SYS_ZCR_EL1, \xtmp2 // self-synchronising -921: + sve_load_vq \xvqminus1, x\nxtmp, \xtmp2 _for n, 0, 31, _sve_ldr_v \n, \nxbase, \n - 34 _sve_ldr_p 0, \nxbase _sve_wrffr 0 diff --git a/arch/arm64/include/asm/hardirq.h b/arch/arm64/include/asm/hardirq.h index 985493af704b..5ffa4bacdad3 100644 --- a/arch/arm64/include/asm/hardirq.h +++ b/arch/arm64/include/asm/hardirq.h @@ -13,21 +13,12 @@ #include <asm/kvm_arm.h> #include <asm/sysreg.h> -#define NR_IPI 7 - typedef struct { unsigned int __softirq_pending; - unsigned int ipi_irqs[NR_IPI]; } ____cacheline_aligned irq_cpustat_t; #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -#define __inc_irq_stat(cpu, member) __IRQ_STAT(cpu, member)++ -#define __get_irq_stat(cpu, member) __IRQ_STAT(cpu, member) - -u64 smp_irq_stat_cpu(unsigned int cpu); -#define arch_irq_stat_cpu smp_irq_stat_cpu - #define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 struct nmi_ctx { diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h index 22f73fe09030..9a5498c2c8ee 100644 --- a/arch/arm64/include/asm/hwcap.h +++ b/arch/arm64/include/asm/hwcap.h @@ -8,18 +8,27 @@ #include <uapi/asm/hwcap.h> #include <asm/cpufeature.h> +#define COMPAT_HWCAP_SWP (1 << 0) #define COMPAT_HWCAP_HALF (1 << 1) #define COMPAT_HWCAP_THUMB (1 << 2) +#define COMPAT_HWCAP_26BIT (1 << 3) #define COMPAT_HWCAP_FAST_MULT (1 << 4) +#define COMPAT_HWCAP_FPA (1 << 5) #define COMPAT_HWCAP_VFP (1 << 6) #define COMPAT_HWCAP_EDSP (1 << 7) +#define COMPAT_HWCAP_JAVA (1 << 8) +#define COMPAT_HWCAP_IWMMXT (1 << 9) +#define COMPAT_HWCAP_CRUNCH (1 << 10) +#define COMPAT_HWCAP_THUMBEE (1 << 11) #define COMPAT_HWCAP_NEON (1 << 12) #define COMPAT_HWCAP_VFPv3 (1 << 13) +#define COMPAT_HWCAP_VFPV3D16 (1 << 14) #define COMPAT_HWCAP_TLS (1 << 15) #define COMPAT_HWCAP_VFPv4 (1 << 16) #define COMPAT_HWCAP_IDIVA (1 << 17) #define COMPAT_HWCAP_IDIVT (1 << 18) #define COMPAT_HWCAP_IDIV (COMPAT_HWCAP_IDIVA|COMPAT_HWCAP_IDIVT) +#define COMPAT_HWCAP_VFPD32 (1 << 19) #define COMPAT_HWCAP_LPAE (1 << 20) #define COMPAT_HWCAP_EVTSTRM (1 << 21) @@ -95,7 +104,7 @@ #define KERNEL_HWCAP_DGH __khwcap2_feature(DGH) #define KERNEL_HWCAP_RNG __khwcap2_feature(RNG) #define KERNEL_HWCAP_BTI __khwcap2_feature(BTI) -/* reserved for KERNEL_HWCAP_MTE __khwcap2_feature(MTE) */ +#define KERNEL_HWCAP_MTE __khwcap2_feature(MTE) /* * This yields a mask that user programs can use to figure out what diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h index 0bc46149e491..4b39293d0f72 100644 --- a/arch/arm64/include/asm/insn.h +++ b/arch/arm64/include/asm/insn.h @@ -359,9 +359,13 @@ __AARCH64_INSN_FUNCS(brk, 0xFFE0001F, 0xD4200000) __AARCH64_INSN_FUNCS(exception, 0xFF000000, 0xD4000000) __AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F) __AARCH64_INSN_FUNCS(br, 0xFFFFFC1F, 0xD61F0000) +__AARCH64_INSN_FUNCS(br_auth, 0xFEFFF800, 0xD61F0800) __AARCH64_INSN_FUNCS(blr, 0xFFFFFC1F, 0xD63F0000) +__AARCH64_INSN_FUNCS(blr_auth, 0xFEFFF800, 0xD63F0800) __AARCH64_INSN_FUNCS(ret, 0xFFFFFC1F, 0xD65F0000) +__AARCH64_INSN_FUNCS(ret_auth, 0xFFFFFBFF, 0xD65F0BFF) __AARCH64_INSN_FUNCS(eret, 0xFFFFFFFF, 0xD69F03E0) +__AARCH64_INSN_FUNCS(eret_auth, 0xFFFFFBFF, 0xD69F0BFF) __AARCH64_INSN_FUNCS(mrs, 0xFFF00000, 0xD5300000) __AARCH64_INSN_FUNCS(msr_imm, 0xFFF8F01F, 0xD500401F) __AARCH64_INSN_FUNCS(msr_reg, 0xFFF00000, 0xD5100000) diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index ff50dd731852..fd172c41df90 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h @@ -110,6 +110,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) #define __io_par(v) __iormb(v) #define __iowmb() dma_wmb() +#define __iomb() dma_mb() /* * Relaxed I/O memory access primitives. These follow the Device memory diff --git a/arch/arm64/include/asm/irq_work.h b/arch/arm64/include/asm/irq_work.h index 8a1ef1907760..a1020285ea75 100644 --- a/arch/arm64/include/asm/irq_work.h +++ b/arch/arm64/include/asm/irq_work.h @@ -2,11 +2,9 @@ #ifndef __ASM_IRQ_WORK_H #define __ASM_IRQ_WORK_H -#include <asm/smp.h> - static inline bool arch_irq_work_has_interrupt(void) { - return !!__smp_cross_call; + return true; } #endif /* __ASM_IRQ_WORK_H */ diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h index 329fb15f6bac..19ca76ea60d9 100644 --- a/arch/arm64/include/asm/kernel-pgtable.h +++ b/arch/arm64/include/asm/kernel-pgtable.h @@ -86,7 +86,7 @@ + EARLY_PGDS((vstart), (vend)) /* each PGDIR needs a next level page table */ \ + EARLY_PUDS((vstart), (vend)) /* each PUD needs a next level page table */ \ + EARLY_PMDS((vstart), (vend))) /* each PMD needs a next level page table */ -#define INIT_DIR_SIZE (PAGE_SIZE * EARLY_PAGES(KIMAGE_VADDR + TEXT_OFFSET, _end)) +#define INIT_DIR_SIZE (PAGE_SIZE * EARLY_PAGES(KIMAGE_VADDR, _end)) #define IDMAP_DIR_SIZE (IDMAP_PGTABLE_LEVELS * PAGE_SIZE) #ifdef CONFIG_ARM64_SW_TTBR0_PAN diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 1da8e3dc4455..64ce29378467 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -12,6 +12,7 @@ #include <asm/types.h> /* Hyp Configuration Register (HCR) bits */ +#define HCR_ATA (UL(1) << 56) #define HCR_FWB (UL(1) << 46) #define HCR_API (UL(1) << 41) #define HCR_APK (UL(1) << 40) @@ -66,7 +67,7 @@ * TWI: Trap WFI * TIDCP: Trap L2CTLR/L2ECTLR * BSU_IS: Upgrade barriers to the inner shareable domain - * FB: Force broadcast of all maintainance operations + * FB: Force broadcast of all maintenance operations * AMO: Override CPSR.A and enable signaling with VA * IMO: Override CPSR.I and enable signaling with VI * FMO: Override CPSR.F and enable signaling with VF @@ -78,7 +79,7 @@ HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \ 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) +#define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_ATA) #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H) /* TCR_EL2 Registers bits */ diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 96eccb107ec2..5ef2669ccd6c 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -298,15 +298,15 @@ static __always_inline int kvm_vcpu_dabt_get_rd(const struct kvm_vcpu *vcpu) return (kvm_vcpu_get_esr(vcpu) & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT; } -static __always_inline bool kvm_vcpu_dabt_iss1tw(const struct kvm_vcpu *vcpu) +static __always_inline bool kvm_vcpu_abt_iss1tw(const struct kvm_vcpu *vcpu) { return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_S1PTW); } +/* Always check for S1PTW *before* using this. */ static __always_inline bool kvm_vcpu_dabt_iswrite(const struct kvm_vcpu *vcpu) { - return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_WNR) || - kvm_vcpu_dabt_iss1tw(vcpu); /* AF/DBM update */ + return kvm_vcpu_get_esr(vcpu) & ESR_ELx_WNR; } static inline bool kvm_vcpu_dabt_is_cm(const struct kvm_vcpu *vcpu) @@ -335,6 +335,11 @@ static inline bool kvm_vcpu_trap_is_iabt(const struct kvm_vcpu *vcpu) return kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_IABT_LOW; } +static inline bool kvm_vcpu_trap_is_exec_fault(const struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_trap_is_iabt(vcpu) && !kvm_vcpu_abt_iss1tw(vcpu); +} + static __always_inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu) { return kvm_vcpu_get_esr(vcpu) & ESR_ELx_FSC; @@ -372,6 +377,9 @@ static __always_inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu) static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu) { + if (kvm_vcpu_abt_iss1tw(vcpu)) + return true; + if (kvm_vcpu_trap_is_iabt(vcpu)) return false; diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index afa722504bfd..cd61239bae8c 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -126,13 +126,18 @@ /* * Memory types available. + * + * IMPORTANT: MT_NORMAL must be index 0 since vm_get_page_prot() may 'or' in + * the MT_NORMAL_TAGGED memory type for PROT_MTE mappings. Note + * that protection_map[] only contains MT_NORMAL attributes. */ -#define MT_DEVICE_nGnRnE 0 -#define MT_DEVICE_nGnRE 1 -#define MT_DEVICE_GRE 2 -#define MT_NORMAL_NC 3 -#define MT_NORMAL 4 -#define MT_NORMAL_WT 5 +#define MT_NORMAL 0 +#define MT_NORMAL_TAGGED 1 +#define MT_NORMAL_NC 2 +#define MT_NORMAL_WT 3 +#define MT_DEVICE_nGnRnE 4 +#define MT_DEVICE_nGnRE 5 +#define MT_DEVICE_GRE 6 /* * Memory types for Stage-2 translation @@ -164,12 +169,11 @@ extern u64 vabits_actual; #define PAGE_END (_PAGE_END(vabits_actual)) -extern s64 physvirt_offset; extern s64 memstart_addr; /* PHYS_OFFSET - the physical address of the start of memory. */ #define PHYS_OFFSET ({ VM_BUG_ON(memstart_addr & 1); memstart_addr; }) -/* the virtual base of the kernel image (minus TEXT_OFFSET) */ +/* the virtual base of the kernel image */ extern u64 kimage_vaddr; /* the offset between the kernel virtual and physical mappings */ @@ -240,7 +244,7 @@ static inline const void *__tag_set(const void *addr, u8 tag) */ #define __is_lm_address(addr) (!(((u64)addr) & BIT(vabits_actual - 1))) -#define __lm_to_phys(addr) (((addr) + physvirt_offset)) +#define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET) #define __kimg_to_phys(addr) ((addr) - kimage_voffset) #define __virt_to_phys_nodebug(x) ({ \ @@ -258,7 +262,7 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x); #define __phys_addr_symbol(x) __pa_symbol_nodebug(x) #endif /* CONFIG_DEBUG_VIRTUAL */ -#define __phys_to_virt(x) ((unsigned long)((x) - physvirt_offset)) +#define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET) #define __phys_to_kimg(x) ((unsigned long)((x) + kimage_voffset)) /* diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h index 081ec8de9ea6..e3e28f7daf62 100644 --- a/arch/arm64/include/asm/mman.h +++ b/arch/arm64/include/asm/mman.h @@ -9,16 +9,53 @@ static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, unsigned long pkey __always_unused) { + unsigned long ret = 0; + if (system_supports_bti() && (prot & PROT_BTI)) - return VM_ARM64_BTI; + ret |= VM_ARM64_BTI; - return 0; + if (system_supports_mte() && (prot & PROT_MTE)) + ret |= VM_MTE; + + return ret; } #define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey) +static inline unsigned long arch_calc_vm_flag_bits(unsigned long flags) +{ + /* + * Only allow MTE on anonymous mappings as these are guaranteed to be + * backed by tags-capable memory. The vm_flags may be overridden by a + * filesystem supporting MTE (RAM-based). + */ + if (system_supports_mte() && (flags & MAP_ANONYMOUS)) + return VM_MTE_ALLOWED; + + return 0; +} +#define arch_calc_vm_flag_bits(flags) arch_calc_vm_flag_bits(flags) + static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags) { - return (vm_flags & VM_ARM64_BTI) ? __pgprot(PTE_GP) : __pgprot(0); + pteval_t prot = 0; + + if (vm_flags & VM_ARM64_BTI) + prot |= PTE_GP; + + /* + * There are two conditions required for returning a Normal Tagged + * memory type: (1) the user requested it via PROT_MTE passed to + * mmap() or mprotect() and (2) the corresponding vma supports MTE. We + * register (1) as VM_MTE in the vma->vm_flags and (2) as + * VM_MTE_ALLOWED. Note that the latter can only be set during the + * mmap() call since mprotect() does not accept MAP_* flags. + * Checking for VM_MTE only is sufficient since arch_validate_flags() + * does not permit (VM_MTE & !VM_MTE_ALLOWED). + */ + if (vm_flags & VM_MTE) + prot |= PTE_ATTRINDX(MT_NORMAL_TAGGED); + + return __pgprot(prot); } #define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags) @@ -30,8 +67,21 @@ static inline bool arch_validate_prot(unsigned long prot, if (system_supports_bti()) supported |= PROT_BTI; + if (system_supports_mte()) + supported |= PROT_MTE; + return (prot & ~supported) == 0; } #define arch_validate_prot(prot, addr) arch_validate_prot(prot, addr) +static inline bool arch_validate_flags(unsigned long vm_flags) +{ + if (!system_supports_mte()) + return true; + + /* only allow VM_MTE if VM_MTE_ALLOWED has been set previously */ + return !(vm_flags & VM_MTE) || (vm_flags & VM_MTE_ALLOWED); +} +#define arch_validate_flags(vm_flags) arch_validate_flags(vm_flags) + #endif /* ! __ASM_MMAN_H__ */ diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index cbff2d42c1d8..b2e91c187e2a 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -17,11 +17,14 @@ #ifndef __ASSEMBLY__ +#include <linux/refcount.h> + typedef struct { atomic64_t id; #ifdef CONFIG_COMPAT void *sigpage; #endif + refcount_t pinned; void *vdso; unsigned long flags; } mm_context_t; diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h index f2d7537d6f83..0672236e1aea 100644 --- a/arch/arm64/include/asm/mmu_context.h +++ b/arch/arm64/include/asm/mmu_context.h @@ -177,7 +177,13 @@ static inline void cpu_replace_ttbr1(pgd_t *pgdp) #define destroy_context(mm) do { } while(0) void check_and_switch_context(struct mm_struct *mm); -#define init_new_context(tsk,mm) ({ atomic64_set(&(mm)->context.id, 0); 0; }) +static inline int +init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + atomic64_set(&mm->context.id, 0); + refcount_set(&mm->context.pinned, 0); + return 0; +} #ifdef CONFIG_ARM64_SW_TTBR0_PAN static inline void update_saved_ttbr0(struct task_struct *tsk, @@ -248,6 +254,9 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, void verify_cpu_asid_bits(void); void post_ttbr_update_workaround(void); +unsigned long arm64_mm_context_get(struct mm_struct *mm); +void arm64_mm_context_put(struct mm_struct *mm); + #endif /* !__ASSEMBLY__ */ #endif /* !__ASM_MMU_CONTEXT_H */ diff --git a/arch/arm64/kernel/module.lds b/arch/arm64/include/asm/module.lds.h index 22e36a21c113..691f15af788e 100644 --- a/arch/arm64/kernel/module.lds +++ b/arch/arm64/include/asm/module.lds.h @@ -1,5 +1,7 @@ +#ifdef CONFIG_ARM64_MODULE_PLTS SECTIONS { .plt (NOLOAD) : { BYTE(0) } .init.plt (NOLOAD) : { BYTE(0) } .text.ftrace_trampoline (NOLOAD) : { BYTE(0) } } +#endif diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h new file mode 100644 index 000000000000..1c99fcadb58c --- /dev/null +++ b/arch/arm64/include/asm/mte.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 ARM Ltd. + */ +#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 + +#ifndef __ASSEMBLY__ + +#include <linux/page-flags.h> + +#include <asm/pgtable-types.h> + +void mte_clear_page_tags(void *addr); +unsigned long mte_copy_tags_from_user(void *to, const void __user *from, + unsigned long n); +unsigned long mte_copy_tags_to_user(void __user *to, void *from, + unsigned long n); +int mte_save_tags(struct page *page); +void mte_save_page_tags(const void *page_addr, void *tag_storage); +bool mte_restore_tags(swp_entry_t entry, struct page *page); +void mte_restore_page_tags(void *page_addr, const void *tag_storage); +void mte_invalidate_tags(int type, pgoff_t offset); +void mte_invalidate_tags_area(int type); +void *mte_allocate_tag_storage(void); +void mte_free_tag_storage(char *storage); + +#ifdef CONFIG_ARM64_MTE + +/* track which pages have valid allocation tags */ +#define PG_mte_tagged PG_arch_2 + +void mte_sync_tags(pte_t *ptep, pte_t pte); +void mte_copy_page_tags(void *kto, const void *kfrom); +void flush_mte_state(void); +void mte_thread_switch(struct task_struct *next); +void mte_suspend_exit(void); +long set_mte_ctrl(struct task_struct *task, unsigned long arg); +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 + +/* unused if !CONFIG_ARM64_MTE, silence the compiler */ +#define PG_mte_tagged 0 + +static inline void mte_sync_tags(pte_t *ptep, pte_t pte) +{ +} +static inline void mte_copy_page_tags(void *kto, const void *kfrom) +{ +} +static inline void flush_mte_state(void) +{ +} +static inline void mte_thread_switch(struct task_struct *next) +{ +} +static inline void mte_suspend_exit(void) +{ +} +static inline long set_mte_ctrl(struct task_struct *task, unsigned long arg) +{ + return 0; +} +static inline long get_mte_ctrl(struct task_struct *task) +{ + return 0; +} +static inline int mte_ptrace_copy_tags(struct task_struct *child, + long request, unsigned long addr, + unsigned long data) +{ + return -EIO; +} + +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_MTE_H */ diff --git a/arch/arm64/include/asm/numa.h b/arch/arm64/include/asm/numa.h index 626ad01e83bf..dd870390d639 100644 --- a/arch/arm64/include/asm/numa.h +++ b/arch/arm64/include/asm/numa.h @@ -25,6 +25,9 @@ const struct cpumask *cpumask_of_node(int node); /* Returns a pointer to the cpumask of CPUs on Node 'node'. */ static inline const struct cpumask *cpumask_of_node(int node) { + if (node == NUMA_NO_NODE) + return cpu_all_mask; + return node_to_cpumask_map[node]; } #endif diff --git a/arch/arm64/include/asm/page-def.h b/arch/arm64/include/asm/page-def.h index f99d48ecbeef..2403f7b4cdbf 100644 --- a/arch/arm64/include/asm/page-def.h +++ b/arch/arm64/include/asm/page-def.h @@ -11,13 +11,8 @@ #include <linux/const.h> /* PAGE_SHIFT determines the page size */ -/* CONT_SHIFT determines the number of pages which can be tracked together */ #define PAGE_SHIFT CONFIG_ARM64_PAGE_SHIFT -#define CONT_SHIFT CONFIG_ARM64_CONT_SHIFT #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) -#define CONT_SIZE (_AC(1, UL) << (CONT_SHIFT + PAGE_SHIFT)) -#define CONT_MASK (~(CONT_SIZE-1)) - #endif /* __ASM_PAGE_DEF_H */ diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h index c01b52add377..012cffc574e8 100644 --- a/arch/arm64/include/asm/page.h +++ b/arch/arm64/include/asm/page.h @@ -15,18 +15,25 @@ #include <linux/personality.h> /* for READ_IMPLIES_EXEC */ #include <asm/pgtable-types.h> -extern void __cpu_clear_user_page(void *p, unsigned long user); -extern void __cpu_copy_user_page(void *to, const void *from, - unsigned long user); +struct page; +struct vm_area_struct; + extern void copy_page(void *to, const void *from); extern void clear_page(void *to); +void copy_user_highpage(struct page *to, struct page *from, + unsigned long vaddr, struct vm_area_struct *vma); +#define __HAVE_ARCH_COPY_USER_HIGHPAGE + +void copy_highpage(struct page *to, struct page *from); +#define __HAVE_ARCH_COPY_HIGHPAGE + #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE -#define clear_user_page(addr,vaddr,pg) __cpu_clear_user_page(addr, vaddr) -#define copy_user_page(to,from,vaddr,pg) __cpu_copy_user_page(to, from, vaddr) +#define clear_user_page(page, vaddr, pg) clear_page(page) +#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) typedef struct page *pgtable_t; @@ -36,7 +43,7 @@ extern int pfn_valid(unsigned long); #endif /* !__ASSEMBLY__ */ -#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_TSK_EXEC +#define VM_DATA_DEFAULT_FLAGS (VM_DATA_FLAGS_TSK_EXEC | VM_MTE_ALLOWED) #include <asm-generic/getorder.h> diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h index 70b323cf8300..b33ca260e3c9 100644 --- a/arch/arm64/include/asm/pci.h +++ b/arch/arm64/include/asm/pci.h @@ -17,6 +17,7 @@ #define pcibios_assign_all_busses() \ (pci_has_flag(PCI_REASSIGN_ALL_BUS)) +#define arch_can_pci_mmap_wc() 1 #define ARCH_GENERIC_PCI_MMAP_RESOURCE 1 extern int isa_dma_bridge_buggy; diff --git a/arch/arm64/include/asm/perf_event.h b/arch/arm64/include/asm/perf_event.h index 2c2d7dbe8a02..60731f602d3e 100644 --- a/arch/arm64/include/asm/perf_event.h +++ b/arch/arm64/include/asm/perf_event.h @@ -236,6 +236,9 @@ #define ARMV8_PMU_USERENR_CR (1 << 2) /* Cycle counter can be read at EL0 */ #define ARMV8_PMU_USERENR_ER (1 << 3) /* Event counter can be read at EL0 */ +/* PMMIR_EL1.SLOTS mask */ +#define ARMV8_PMU_SLOTS_MASK 0xff + #ifdef CONFIG_PERF_EVENTS struct pt_regs; extern unsigned long perf_instruction_pointer(struct pt_regs *regs); diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index 2b5f822fb033..01a96d07ae74 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h @@ -81,25 +81,15 @@ /* * Contiguous page definitions. */ -#ifdef CONFIG_ARM64_64K_PAGES -#define CONT_PTE_SHIFT (5 + PAGE_SHIFT) -#define CONT_PMD_SHIFT (5 + PMD_SHIFT) -#elif defined(CONFIG_ARM64_16K_PAGES) -#define CONT_PTE_SHIFT (7 + PAGE_SHIFT) -#define CONT_PMD_SHIFT (5 + PMD_SHIFT) -#else -#define CONT_PTE_SHIFT (4 + PAGE_SHIFT) -#define CONT_PMD_SHIFT (4 + PMD_SHIFT) -#endif - +#define CONT_PTE_SHIFT (CONFIG_ARM64_CONT_PTE_SHIFT + PAGE_SHIFT) #define CONT_PTES (1 << (CONT_PTE_SHIFT - PAGE_SHIFT)) #define CONT_PTE_SIZE (CONT_PTES * PAGE_SIZE) #define CONT_PTE_MASK (~(CONT_PTE_SIZE - 1)) + +#define CONT_PMD_SHIFT (CONFIG_ARM64_CONT_PMD_SHIFT + PMD_SHIFT) #define CONT_PMDS (1 << (CONT_PMD_SHIFT - PMD_SHIFT)) #define CONT_PMD_SIZE (CONT_PMDS * PMD_SIZE) #define CONT_PMD_MASK (~(CONT_PMD_SIZE - 1)) -/* the numerical offset of the PTE within a range of CONT_PTES */ -#define CONT_RANGE_OFFSET(addr) (((addr)>>PAGE_SHIFT)&(CONT_PTES-1)) /* * Hardware page table definitions. diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h index 8f094c43072a..046be789fbb4 100644 --- a/arch/arm64/include/asm/pgtable-prot.h +++ b/arch/arm64/include/asm/pgtable-prot.h @@ -19,6 +19,13 @@ #define PTE_DEVMAP (_AT(pteval_t, 1) << 57) #define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */ +/* + * This bit indicates that the entry is present i.e. pmd_page() + * still points to a valid huge page in memory even if the pmd + * has been invalidated. + */ +#define PMD_PRESENT_INVALID (_AT(pteval_t, 1) << 59) /* only when !PMD_SECT_VALID */ + #ifndef __ASSEMBLY__ #include <asm/cpufeature.h> @@ -50,6 +57,7 @@ extern bool arm64_use_ng_mappings; #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC)) #define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT)) #define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL)) +#define PROT_NORMAL_TAGGED (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_TAGGED)) #define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE)) #define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL)) @@ -58,6 +66,7 @@ extern bool arm64_use_ng_mappings; #define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL)) #define PAGE_KERNEL __pgprot(PROT_NORMAL) +#define PAGE_KERNEL_TAGGED __pgprot(PROT_NORMAL_TAGGED) #define PAGE_KERNEL_RO __pgprot((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY) #define PAGE_KERNEL_ROX __pgprot((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY) #define PAGE_KERNEL_EXEC __pgprot(PROT_NORMAL & ~PTE_PXN) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index d5d3fbe73953..4ff12a7adcfd 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -9,6 +9,7 @@ #include <asm/proc-fns.h> #include <asm/memory.h> +#include <asm/mte.h> #include <asm/pgtable-hwdef.h> #include <asm/pgtable-prot.h> #include <asm/tlbflush.h> @@ -23,6 +24,8 @@ #define VMALLOC_START (MODULES_END) #define VMALLOC_END (- PUD_SIZE - VMEMMAP_SIZE - SZ_64K) +#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT)) + #define FIRST_USER_ADDRESS 0UL #ifndef __ASSEMBLY__ @@ -33,13 +36,6 @@ #include <linux/mm_types.h> #include <linux/sched.h> -extern struct page *vmemmap; - -extern void __pte_error(const char *file, int line, unsigned long val); -extern void __pmd_error(const char *file, int line, unsigned long val); -extern void __pud_error(const char *file, int line, unsigned long val); -extern void __pgd_error(const char *file, int line, unsigned long val); - #ifdef CONFIG_TRANSPARENT_HUGEPAGE #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE @@ -51,13 +47,22 @@ extern void __pgd_error(const char *file, int line, unsigned long val); #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ /* + * Outside of a few very special situations (e.g. hibernation), we always + * use broadcast TLB invalidation instructions, therefore a spurious page + * fault on one CPU which has been handled concurrently by another CPU + * does not need to perform additional invalidation. + */ +#define flush_tlb_fix_spurious_fault(vma, address) do { } while (0) + +/* * ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. */ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #define ZERO_PAGE(vaddr) phys_to_page(__pa_symbol(empty_zero_page)) -#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte)) +#define pte_ERROR(e) \ + pr_err("%s:%d: bad pte %016llx.\n", __FILE__, __LINE__, pte_val(e)) /* * Macros to convert between a physical address and its placement in a @@ -90,6 +95,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #define pte_user_exec(pte) (!(pte_val(pte) & PTE_UXN)) #define pte_cont(pte) (!!(pte_val(pte) & PTE_CONT)) #define pte_devmap(pte) (!!(pte_val(pte) & PTE_DEVMAP)) +#define pte_tagged(pte) ((pte_val(pte) & PTE_ATTRINDX_MASK) == \ + PTE_ATTRINDX(MT_NORMAL_TAGGED)) #define pte_cont_addr_end(addr, end) \ ({ unsigned long __boundary = ((addr) + CONT_PTE_SIZE) & CONT_PTE_MASK; \ @@ -145,6 +152,18 @@ static inline pte_t set_pte_bit(pte_t pte, pgprot_t prot) return pte; } +static inline pmd_t clear_pmd_bit(pmd_t pmd, pgprot_t prot) +{ + pmd_val(pmd) &= ~pgprot_val(prot); + return pmd; +} + +static inline pmd_t set_pmd_bit(pmd_t pmd, pgprot_t prot) +{ + pmd_val(pmd) |= pgprot_val(prot); + return pmd; +} + static inline pte_t pte_wrprotect(pte_t pte) { pte = clear_pte_bit(pte, __pgprot(PTE_WRITE)); @@ -284,6 +303,10 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte)) __sync_icache_dcache(pte); + if (system_supports_mte() && + pte_present(pte) && pte_tagged(pte) && !pte_special(pte)) + mte_sync_tags(ptep, pte); + __check_racy_pte_update(mm, ptep, pte); set_pte(ptep, pte); @@ -363,15 +386,24 @@ static inline int pmd_protnone(pmd_t pmd) } #endif +#define pmd_present_invalid(pmd) (!!(pmd_val(pmd) & PMD_PRESENT_INVALID)) + +static inline int pmd_present(pmd_t pmd) +{ + return pte_present(pmd_pte(pmd)) || pmd_present_invalid(pmd); +} + /* * THP definitions. */ #ifdef CONFIG_TRANSPARENT_HUGEPAGE -#define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT)) +static inline int pmd_trans_huge(pmd_t pmd) +{ + return pmd_val(pmd) && pmd_present(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT); +} #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -#define pmd_present(pmd) pte_present(pmd_pte(pmd)) #define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd)) #define pmd_young(pmd) pte_young(pmd_pte(pmd)) #define pmd_valid(pmd) pte_valid(pmd_pte(pmd)) @@ -381,7 +413,14 @@ static inline int pmd_protnone(pmd_t pmd) #define pmd_mkclean(pmd) pte_pmd(pte_mkclean(pmd_pte(pmd))) #define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd))) #define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd))) -#define pmd_mkinvalid(pmd) (__pmd(pmd_val(pmd) & ~PMD_SECT_VALID)) + +static inline pmd_t pmd_mkinvalid(pmd_t pmd) +{ + pmd = set_pmd_bit(pmd, __pgprot(PMD_PRESENT_INVALID)); + pmd = clear_pmd_bit(pmd, __pgprot(PMD_SECT_VALID)); + + return pmd; +} #define pmd_thp_or_huge(pmd) (pmd_huge(pmd) || pmd_trans_huge(pmd)) @@ -541,7 +580,8 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd) #if CONFIG_PGTABLE_LEVELS > 2 -#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd)) +#define pmd_ERROR(e) \ + pr_err("%s:%d: bad pmd %016llx.\n", __FILE__, __LINE__, pmd_val(e)) #define pud_none(pud) (!pud_val(pud)) #define pud_bad(pud) (!(pud_val(pud) & PUD_TABLE_BIT)) @@ -608,7 +648,8 @@ static inline unsigned long pud_page_vaddr(pud_t pud) #if CONFIG_PGTABLE_LEVELS > 3 -#define pud_ERROR(pud) __pud_error(__FILE__, __LINE__, pud_val(pud)) +#define pud_ERROR(e) \ + pr_err("%s:%d: bad pud %016llx.\n", __FILE__, __LINE__, pud_val(e)) #define p4d_none(p4d) (!p4d_val(p4d)) #define p4d_bad(p4d) (!(p4d_val(p4d) & 2)) @@ -667,15 +708,21 @@ static inline unsigned long p4d_page_vaddr(p4d_t p4d) #endif /* CONFIG_PGTABLE_LEVELS > 3 */ -#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd)) +#define pgd_ERROR(e) \ + pr_err("%s:%d: bad pgd %016llx.\n", __FILE__, __LINE__, pgd_val(e)) #define pgd_set_fixmap(addr) ((pgd_t *)set_fixmap_offset(FIX_PGD, addr)) #define pgd_clear_fixmap() clear_fixmap(FIX_PGD) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { + /* + * Normal and Normal-Tagged are two different memory types and indices + * in MAIR_EL1. The mask below has to include PTE_ATTRINDX_MASK. + */ const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | - PTE_PROT_NONE | PTE_VALID | PTE_WRITE | PTE_GP; + PTE_PROT_NONE | PTE_VALID | PTE_WRITE | PTE_GP | + PTE_ATTRINDX_MASK; /* preserve the hardware dirty information */ if (pte_hw_dirty(pte)) pte = pte_mkdirty(pte); @@ -847,6 +894,11 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(swp) ((pte_t) { (swp).val }) +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION +#define __pmd_to_swp_entry(pmd) ((swp_entry_t) { pmd_val(pmd) }) +#define __swp_entry_to_pmd(swp) __pmd((swp).val) +#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */ + /* * Ensure that there are not more swap files than can be encoded in the kernel * PTEs. @@ -855,6 +907,38 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, extern int kern_addr_valid(unsigned long addr); +#ifdef CONFIG_ARM64_MTE + +#define __HAVE_ARCH_PREPARE_TO_SWAP +static inline int arch_prepare_to_swap(struct page *page) +{ + if (system_supports_mte()) + return mte_save_tags(page); + return 0; +} + +#define __HAVE_ARCH_SWAP_INVALIDATE +static inline void arch_swap_invalidate_page(int type, pgoff_t offset) +{ + if (system_supports_mte()) + mte_invalidate_tags(type, offset); +} + +static inline void arch_swap_invalidate_area(int type) +{ + if (system_supports_mte()) + mte_invalidate_tags_area(type); +} + +#define __HAVE_ARCH_SWAP_RESTORE +static inline void arch_swap_restore(swp_entry_t entry, struct page *page) +{ + if (system_supports_mte() && mte_restore_tags(entry, page)) + set_bit(PG_mte_tagged, &page->flags); +} + +#endif /* CONFIG_ARM64_MTE */ + /* * On AArch64, the cache coherency is handled via the set_pte_at() function. */ diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 7d90ea2e2063..fce8cbecd6bc 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -152,6 +152,10 @@ struct thread_struct { struct ptrauth_keys_user keys_user; struct ptrauth_keys_kernel keys_kernel; #endif +#ifdef CONFIG_ARM64_MTE + u64 sctlr_tcf0; + u64 gcr_user_incl; +#endif }; static inline void arch_thread_struct_whitelist(unsigned long *offset, @@ -301,10 +305,10 @@ extern void __init minsigstksz_setup(void); #ifdef CONFIG_ARM64_TAGGED_ADDR_ABI /* PR_{SET,GET}_TAGGED_ADDR_CTRL prctl */ -long set_tagged_addr_ctrl(unsigned long arg); -long get_tagged_addr_ctrl(void); -#define SET_TAGGED_ADDR_CTRL(arg) set_tagged_addr_ctrl(arg) -#define GET_TAGGED_ADDR_CTRL() get_tagged_addr_ctrl() +long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg); +long get_tagged_addr_ctrl(struct task_struct *task); +#define SET_TAGGED_ADDR_CTRL(arg) set_tagged_addr_ctrl(current, arg) +#define GET_TAGGED_ADDR_CTRL() get_tagged_addr_ctrl(current) #endif /* diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 966ed30ed5f7..997cf8c8cd52 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -31,9 +31,21 @@ * interrupt disabling temporarily does not rely on IRQ priorities. */ #define GIC_PRIO_IRQON 0xe0 -#define GIC_PRIO_IRQOFF (GIC_PRIO_IRQON & ~0x80) +#define __GIC_PRIO_IRQOFF (GIC_PRIO_IRQON & ~0x80) +#define __GIC_PRIO_IRQOFF_NS 0xa0 #define GIC_PRIO_PSR_I_SET (1 << 4) +#define GIC_PRIO_IRQOFF \ + ({ \ + extern struct static_key_false gic_nonsecure_priorities;\ + u8 __prio = __GIC_PRIO_IRQOFF; \ + \ + if (static_branch_unlikely(&gic_nonsecure_priorities)) \ + __prio = __GIC_PRIO_IRQOFF_NS; \ + \ + __prio; \ + }) + /* Additional SPSR bits not exposed in the UABI */ #define PSR_MODE_THREAD_BIT (1 << 0) #define PSR_IL_BIT (1 << 20) diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index 0eadbf933e35..2e7f529ec5a6 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -56,27 +56,15 @@ static inline void set_cpu_logical_map(int cpu, u64 hwid) struct seq_file; /* - * generate IPI list text - */ -extern void show_ipi_list(struct seq_file *p, int prec); - -/* - * Called from C code, this handles an IPI. - */ -extern void handle_IPI(int ipinr, struct pt_regs *regs); - -/* * Discover the set of possible CPUs and determine their * SMP operations. */ extern void smp_init_cpus(void); /* - * Provide a function to raise an IPI cross call on CPUs in callmap. + * Register IPI interrupts with the arch SMP code */ -extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int)); - -extern void (*__smp_cross_call)(const struct cpumask *, unsigned int); +extern void set_smp_ipi_range(int ipi_base, int nr_ipi); /* * Called from the secondary holding pen, this is the secondary CPU entry point. diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h index fc7613023c19..eb29b1fe8255 100644 --- a/arch/arm64/include/asm/stacktrace.h +++ b/arch/arm64/include/asm/stacktrace.h @@ -63,7 +63,7 @@ struct stackframe { extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame); extern void walk_stackframe(struct task_struct *tsk, struct stackframe *frame, - int (*fn)(struct stackframe *, void *), void *data); + bool (*fn)(void *, unsigned long), void *data); extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk, const char *loglvl); diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 554a7e8ecb07..d52c1b3ce589 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -91,10 +91,12 @@ #define PSTATE_PAN pstate_field(0, 4) #define PSTATE_UAO pstate_field(0, 3) #define PSTATE_SSBS pstate_field(3, 1) +#define PSTATE_TCO pstate_field(3, 4) #define SET_PSTATE_PAN(x) __emit_inst(0xd500401f | PSTATE_PAN | ((!!x) << PSTATE_Imm_shift)) #define SET_PSTATE_UAO(x) __emit_inst(0xd500401f | PSTATE_UAO | ((!!x) << PSTATE_Imm_shift)) #define SET_PSTATE_SSBS(x) __emit_inst(0xd500401f | PSTATE_SSBS | ((!!x) << PSTATE_Imm_shift)) +#define SET_PSTATE_TCO(x) __emit_inst(0xd500401f | PSTATE_TCO | ((!!x) << PSTATE_Imm_shift)) #define __SYS_BARRIER_INSN(CRm, op2, Rt) \ __emit_inst(0xd5000000 | sys_insn(0, 3, 3, (CRm), (op2)) | ((Rt) & 0x1f)) @@ -181,6 +183,8 @@ #define SYS_SCTLR_EL1 sys_reg(3, 0, 1, 0, 0) #define SYS_ACTLR_EL1 sys_reg(3, 0, 1, 0, 1) #define SYS_CPACR_EL1 sys_reg(3, 0, 1, 0, 2) +#define SYS_RGSR_EL1 sys_reg(3, 0, 1, 0, 5) +#define SYS_GCR_EL1 sys_reg(3, 0, 1, 0, 6) #define SYS_ZCR_EL1 sys_reg(3, 0, 1, 2, 0) @@ -218,6 +222,8 @@ #define SYS_ERXADDR_EL1 sys_reg(3, 0, 5, 4, 3) #define SYS_ERXMISC0_EL1 sys_reg(3, 0, 5, 5, 0) #define SYS_ERXMISC1_EL1 sys_reg(3, 0, 5, 5, 1) +#define SYS_TFSR_EL1 sys_reg(3, 0, 5, 6, 0) +#define SYS_TFSRE0_EL1 sys_reg(3, 0, 5, 6, 1) #define SYS_FAR_EL1 sys_reg(3, 0, 6, 0, 0) #define SYS_PAR_EL1 sys_reg(3, 0, 7, 4, 0) @@ -321,6 +327,8 @@ #define SYS_PMINTENSET_EL1 sys_reg(3, 0, 9, 14, 1) #define SYS_PMINTENCLR_EL1 sys_reg(3, 0, 9, 14, 2) +#define SYS_PMMIR_EL1 sys_reg(3, 0, 9, 14, 6) + #define SYS_MAIR_EL1 sys_reg(3, 0, 10, 2, 0) #define SYS_AMAIR_EL1 sys_reg(3, 0, 10, 3, 0) @@ -368,6 +376,7 @@ #define SYS_CCSIDR_EL1 sys_reg(3, 1, 0, 0, 0) #define SYS_CLIDR_EL1 sys_reg(3, 1, 0, 0, 1) +#define SYS_GMID_EL1 sys_reg(3, 1, 0, 0, 4) #define SYS_AIDR_EL1 sys_reg(3, 1, 0, 0, 7) #define SYS_CSSELR_EL1 sys_reg(3, 2, 0, 0, 0) @@ -460,6 +469,7 @@ #define SYS_ESR_EL2 sys_reg(3, 4, 5, 2, 0) #define SYS_VSESR_EL2 sys_reg(3, 4, 5, 2, 3) #define SYS_FPEXC32_EL2 sys_reg(3, 4, 5, 3, 0) +#define SYS_TFSR_EL2 sys_reg(3, 4, 5, 6, 0) #define SYS_FAR_EL2 sys_reg(3, 4, 6, 0, 0) #define SYS_VDISR_EL2 sys_reg(3, 4, 12, 1, 1) @@ -516,6 +526,7 @@ #define SYS_AFSR0_EL12 sys_reg(3, 5, 5, 1, 0) #define SYS_AFSR1_EL12 sys_reg(3, 5, 5, 1, 1) #define SYS_ESR_EL12 sys_reg(3, 5, 5, 2, 0) +#define SYS_TFSR_EL12 sys_reg(3, 5, 5, 6, 0) #define SYS_FAR_EL12 sys_reg(3, 5, 6, 0, 0) #define SYS_MAIR_EL12 sys_reg(3, 5, 10, 2, 0) #define SYS_AMAIR_EL12 sys_reg(3, 5, 10, 3, 0) @@ -531,6 +542,15 @@ /* Common SCTLR_ELx flags. */ #define SCTLR_ELx_DSSBS (BIT(44)) +#define SCTLR_ELx_ATA (BIT(43)) + +#define SCTLR_ELx_TCF_SHIFT 40 +#define SCTLR_ELx_TCF_NONE (UL(0x0) << SCTLR_ELx_TCF_SHIFT) +#define SCTLR_ELx_TCF_SYNC (UL(0x1) << SCTLR_ELx_TCF_SHIFT) +#define SCTLR_ELx_TCF_ASYNC (UL(0x2) << SCTLR_ELx_TCF_SHIFT) +#define SCTLR_ELx_TCF_MASK (UL(0x3) << SCTLR_ELx_TCF_SHIFT) + +#define SCTLR_ELx_ITFSB (BIT(37)) #define SCTLR_ELx_ENIA (BIT(31)) #define SCTLR_ELx_ENIB (BIT(30)) #define SCTLR_ELx_ENDA (BIT(27)) @@ -559,6 +579,14 @@ #endif /* SCTLR_EL1 specific flags. */ +#define SCTLR_EL1_ATA0 (BIT(42)) + +#define SCTLR_EL1_TCF0_SHIFT 38 +#define SCTLR_EL1_TCF0_NONE (UL(0x0) << SCTLR_EL1_TCF0_SHIFT) +#define SCTLR_EL1_TCF0_SYNC (UL(0x1) << SCTLR_EL1_TCF0_SHIFT) +#define SCTLR_EL1_TCF0_ASYNC (UL(0x2) << SCTLR_EL1_TCF0_SHIFT) +#define SCTLR_EL1_TCF0_MASK (UL(0x3) << SCTLR_EL1_TCF0_SHIFT) + #define SCTLR_EL1_BT1 (BIT(36)) #define SCTLR_EL1_BT0 (BIT(35)) #define SCTLR_EL1_UCI (BIT(26)) @@ -587,6 +615,7 @@ SCTLR_EL1_SA0 | SCTLR_EL1_SED | SCTLR_ELx_I |\ SCTLR_EL1_DZE | SCTLR_EL1_UCT |\ SCTLR_EL1_NTWE | SCTLR_ELx_IESB | SCTLR_EL1_SPAN |\ + SCTLR_ELx_ITFSB| SCTLR_ELx_ATA | SCTLR_EL1_ATA0 |\ ENDIAN_SET_EL1 | SCTLR_EL1_UCI | SCTLR_EL1_RES1) /* MAIR_ELx memory attributes (used by Linux) */ @@ -595,6 +624,7 @@ #define MAIR_ATTR_DEVICE_GRE UL(0x0c) #define MAIR_ATTR_NORMAL_NC UL(0x44) #define MAIR_ATTR_NORMAL_WT UL(0xbb) +#define MAIR_ATTR_NORMAL_TAGGED UL(0xf0) #define MAIR_ATTR_NORMAL UL(0xff) #define MAIR_ATTR_MASK UL(0xff) @@ -636,14 +666,22 @@ #define ID_AA64ISAR1_APA_SHIFT 4 #define ID_AA64ISAR1_DPB_SHIFT 0 -#define ID_AA64ISAR1_APA_NI 0x0 -#define ID_AA64ISAR1_APA_ARCHITECTED 0x1 -#define ID_AA64ISAR1_API_NI 0x0 -#define ID_AA64ISAR1_API_IMP_DEF 0x1 -#define ID_AA64ISAR1_GPA_NI 0x0 -#define ID_AA64ISAR1_GPA_ARCHITECTED 0x1 -#define ID_AA64ISAR1_GPI_NI 0x0 -#define ID_AA64ISAR1_GPI_IMP_DEF 0x1 +#define ID_AA64ISAR1_APA_NI 0x0 +#define ID_AA64ISAR1_APA_ARCHITECTED 0x1 +#define ID_AA64ISAR1_APA_ARCH_EPAC 0x2 +#define ID_AA64ISAR1_APA_ARCH_EPAC2 0x3 +#define ID_AA64ISAR1_APA_ARCH_EPAC2_FPAC 0x4 +#define ID_AA64ISAR1_APA_ARCH_EPAC2_FPAC_CMB 0x5 +#define ID_AA64ISAR1_API_NI 0x0 +#define ID_AA64ISAR1_API_IMP_DEF 0x1 +#define ID_AA64ISAR1_API_IMP_DEF_EPAC 0x2 +#define ID_AA64ISAR1_API_IMP_DEF_EPAC2 0x3 +#define ID_AA64ISAR1_API_IMP_DEF_EPAC2_FPAC 0x4 +#define ID_AA64ISAR1_API_IMP_DEF_EPAC2_FPAC_CMB 0x5 +#define ID_AA64ISAR1_GPA_NI 0x0 +#define ID_AA64ISAR1_GPA_ARCHITECTED 0x1 +#define ID_AA64ISAR1_GPI_NI 0x0 +#define ID_AA64ISAR1_GPI_IMP_DEF 0x1 /* id_aa64pfr0 */ #define ID_AA64PFR0_CSV3_SHIFT 60 @@ -686,6 +724,10 @@ #define ID_AA64PFR1_SSBS_PSTATE_INSNS 2 #define ID_AA64PFR1_BT_BTI 0x1 +#define ID_AA64PFR1_MTE_NI 0x0 +#define ID_AA64PFR1_MTE_EL0 0x1 +#define ID_AA64PFR1_MTE 0x2 + /* id_aa64zfr0 */ #define ID_AA64ZFR0_F64MM_SHIFT 56 #define ID_AA64ZFR0_F32MM_SHIFT 52 @@ -920,6 +962,28 @@ #define CPACR_EL1_ZEN_EL0EN (BIT(17)) /* enable EL0 access, if EL1EN set */ #define CPACR_EL1_ZEN (CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN) +/* TCR EL1 Bit Definitions */ +#define SYS_TCR_EL1_TCMA1 (BIT(58)) +#define SYS_TCR_EL1_TCMA0 (BIT(57)) + +/* GCR_EL1 Definitions */ +#define SYS_GCR_EL1_RRND (BIT(16)) +#define SYS_GCR_EL1_EXCL_MASK 0xffffUL + +/* RGSR_EL1 Definitions */ +#define SYS_RGSR_EL1_TAG_MASK 0xfUL +#define SYS_RGSR_EL1_SEED_SHIFT 8 +#define SYS_RGSR_EL1_SEED_MASK 0xffffUL + +/* GMID_EL1 field definitions */ +#define SYS_GMID_EL1_BS_SHIFT 0 +#define SYS_GMID_EL1_BS_SIZE 4 + +/* TFSR{,E0}_EL1 bit definitions */ +#define SYS_TFSR_EL1_TF0_SHIFT 0 +#define SYS_TFSR_EL1_TF1_SHIFT 1 +#define SYS_TFSR_EL1_TF0 (UL(1) << SYS_TFSR_EL1_TF0_SHIFT) +#define SYS_TFSR_EL1_TF1 (UK(2) << SYS_TFSR_EL1_TF1_SHIFT) /* Safe value for MPIDR_EL1: Bit31:RES1, Bit30:U:0, Bit24:MT:0 */ #define SYS_MPIDR_SAFE_VAL (BIT(31)) @@ -1024,6 +1088,13 @@ write_sysreg(__scs_new, sysreg); \ } while (0) +#define sysreg_clear_set_s(sysreg, clear, set) do { \ + u64 __scs_val = read_sysreg_s(sysreg); \ + u64 __scs_new = (__scs_val & ~(u64)(clear)) | (set); \ + if (__scs_new != __scs_val) \ + write_sysreg_s(__scs_new, sysreg); \ +} while (0) + #endif #endif /* __ASM_SYSREG_H */ diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h index 5e784e16ee89..1fbab854a51b 100644 --- a/arch/arm64/include/asm/thread_info.h +++ b/arch/arm64/include/asm/thread_info.h @@ -67,6 +67,7 @@ void arch_release_task_struct(struct task_struct *tsk); #define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */ #define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */ #define TIF_FSCHECK 5 /* Check FS is USER_DS on return */ +#define TIF_MTE_ASYNC_FAULT 6 /* MTE Asynchronous Tag Check Fault */ #define TIF_SYSCALL_TRACE 8 /* syscall trace active */ #define TIF_SYSCALL_AUDIT 9 /* syscall auditing */ #define TIF_SYSCALL_TRACEPOINT 10 /* syscall tracepoint for ftrace */ @@ -96,10 +97,11 @@ void arch_release_task_struct(struct task_struct *tsk); #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_32BIT (1 << TIF_32BIT) #define _TIF_SVE (1 << TIF_SVE) +#define _TIF_MTE_ASYNC_FAULT (1 << TIF_MTE_ASYNC_FAULT) #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \ - _TIF_UPROBE | _TIF_FSCHECK) + _TIF_UPROBE | _TIF_FSCHECK | _TIF_MTE_ASYNC_FAULT) #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \ diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h index e042f6527981..11a465243f66 100644 --- a/arch/arm64/include/asm/topology.h +++ b/arch/arm64/include/asm/topology.h @@ -26,7 +26,9 @@ void topology_scale_freq_tick(void); #endif /* CONFIG_ARM64_AMU_EXTN */ /* Replace task scheduler's default frequency-invariant accounting */ +#define arch_set_freq_scale topology_set_freq_scale #define arch_scale_freq_capacity topology_get_freq_scale +#define arch_scale_freq_invariant topology_scale_freq_invariant /* Replace task scheduler's default cpu-invariant accounting */ #define arch_scale_cpu_capacity topology_get_cpu_scale diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h index cee5928e1b7d..d96dc2c7c09d 100644 --- a/arch/arm64/include/asm/traps.h +++ b/arch/arm64/include/asm/traps.h @@ -24,7 +24,7 @@ struct undef_hook { void register_undef_hook(struct undef_hook *hook); void unregister_undef_hook(struct undef_hook *hook); -void force_signal_inject(int signal, int code, unsigned long address); +void force_signal_inject(int signal, int code, unsigned long address, unsigned int err); void arm64_notify_segfault(unsigned long addr); void arm64_force_sig_fault(int signo, int code, void __user *addr, const char *str); void arm64_force_sig_mceerr(int code, void __user *addr, short lsb, const char *str); diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h index 3b859596840d..b3b2019f8d16 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 440 +#define __NR_compat_syscalls 441 #endif #define __ARCH_WANT_SYS_CLONE diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h index 734860ac7cf9..107f08e03b9f 100644 --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h @@ -53,7 +53,7 @@ __SYSCALL(__NR_lseek, compat_sys_lseek) #define __NR_getpid 20 __SYSCALL(__NR_getpid, sys_getpid) #define __NR_mount 21 -__SYSCALL(__NR_mount, compat_sys_mount) +__SYSCALL(__NR_mount, sys_mount) /* 22 was sys_umount */ __SYSCALL(22, sys_ni_syscall) #define __NR_setuid 23 @@ -301,9 +301,9 @@ __SYSCALL(__NR_flock, sys_flock) #define __NR_msync 144 __SYSCALL(__NR_msync, sys_msync) #define __NR_readv 145 -__SYSCALL(__NR_readv, compat_sys_readv) +__SYSCALL(__NR_readv, sys_readv) #define __NR_writev 146 -__SYSCALL(__NR_writev, compat_sys_writev) +__SYSCALL(__NR_writev, sys_writev) #define __NR_getsid 147 __SYSCALL(__NR_getsid, sys_getsid) #define __NR_fdatasync 148 @@ -697,7 +697,7 @@ __SYSCALL(__NR_sync_file_range2, compat_sys_aarch32_sync_file_range2) #define __NR_tee 342 __SYSCALL(__NR_tee, sys_tee) #define __NR_vmsplice 343 -__SYSCALL(__NR_vmsplice, compat_sys_vmsplice) +__SYSCALL(__NR_vmsplice, sys_vmsplice) #define __NR_move_pages 344 __SYSCALL(__NR_move_pages, compat_sys_move_pages) #define __NR_getcpu 345 @@ -763,9 +763,9 @@ __SYSCALL(__NR_sendmmsg, compat_sys_sendmmsg) #define __NR_setns 375 __SYSCALL(__NR_setns, sys_setns) #define __NR_process_vm_readv 376 -__SYSCALL(__NR_process_vm_readv, compat_sys_process_vm_readv) +__SYSCALL(__NR_process_vm_readv, sys_process_vm_readv) #define __NR_process_vm_writev 377 -__SYSCALL(__NR_process_vm_writev, compat_sys_process_vm_writev) +__SYSCALL(__NR_process_vm_writev, sys_process_vm_writev) #define __NR_kcmp 378 __SYSCALL(__NR_kcmp, sys_kcmp) #define __NR_finit_module 379 @@ -887,6 +887,8 @@ __SYSCALL(__NR_openat2, sys_openat2) __SYSCALL(__NR_pidfd_getfd, sys_pidfd_getfd) #define __NR_faccessat2 439 __SYSCALL(__NR_faccessat2, sys_faccessat2) +#define __NR_process_madvise 440 +__SYSCALL(__NR_process_madvise, sys_process_madvise) /* * Please add new compat syscalls above this comment and update diff --git a/arch/arm64/include/asm/xen/page.h b/arch/arm64/include/asm/xen/page.h index 31bbc803cecb..dffdc773221b 100644 --- a/arch/arm64/include/asm/xen/page.h +++ b/arch/arm64/include/asm/xen/page.h @@ -1 +1,7 @@ #include <xen/arm/page.h> +#include <asm/mmu.h> + +static inline bool xen_kernel_unmapped_at_usr(void) +{ + return arm64_kernel_unmapped_at_el0(); +} diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h index 912162f73529..b8f41aa234ee 100644 --- a/arch/arm64/include/uapi/asm/hwcap.h +++ b/arch/arm64/include/uapi/asm/hwcap.h @@ -74,6 +74,6 @@ #define HWCAP2_DGH (1 << 15) #define HWCAP2_RNG (1 << 16) #define HWCAP2_BTI (1 << 17) -/* reserved for HWCAP2_MTE (1 << 18) */ +#define HWCAP2_MTE (1 << 18) #endif /* _UAPI__ASM_HWCAP_H */ diff --git a/arch/arm64/include/uapi/asm/mman.h b/arch/arm64/include/uapi/asm/mman.h index 6fdd71eb644f..1e6482a838e1 100644 --- a/arch/arm64/include/uapi/asm/mman.h +++ b/arch/arm64/include/uapi/asm/mman.h @@ -5,5 +5,6 @@ #include <asm-generic/mman.h> #define PROT_BTI 0x10 /* BTI guarded page */ +#define PROT_MTE 0x20 /* Normal Tagged mapping */ #endif /* ! _UAPI__ASM_MMAN_H */ diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h index 42cbe34d95ce..758ae984ff97 100644 --- a/arch/arm64/include/uapi/asm/ptrace.h +++ b/arch/arm64/include/uapi/asm/ptrace.h @@ -51,6 +51,7 @@ #define PSR_PAN_BIT 0x00400000 #define PSR_UAO_BIT 0x00800000 #define PSR_DIT_BIT 0x01000000 +#define PSR_TCO_BIT 0x02000000 #define PSR_V_BIT 0x10000000 #define PSR_C_BIT 0x20000000 #define PSR_Z_BIT 0x40000000 @@ -75,6 +76,9 @@ /* syscall emulation path in ptrace */ #define PTRACE_SYSEMU 31 #define PTRACE_SYSEMU_SINGLESTEP 32 +/* MTE allocation tag access */ +#define PTRACE_PEEKMTETAGS 33 +#define PTRACE_POKEMTETAGS 34 #ifndef __ASSEMBLY__ diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index bd12b9a2ab4a..bbaf0bc4ad60 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -3,8 +3,6 @@ # Makefile for the linux kernel. # -CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET) -AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) CFLAGS_armv8_deprecated.o := -I$(src) CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) @@ -61,6 +59,7 @@ obj-$(CONFIG_CRASH_CORE) += crash_core.o obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o obj-$(CONFIG_SHADOW_CALL_STACK) += scs.o +obj-$(CONFIG_ARM64_MTE) += mte.o obj-y += vdso/ probes/ obj-$(CONFIG_COMPAT_VDSO) += vdso32/ diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index a85174d05473..cada0b816c8a 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -298,8 +298,21 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size) case EFI_BOOT_SERVICES_DATA: case EFI_CONVENTIONAL_MEMORY: case EFI_PERSISTENT_MEMORY: - pr_warn(FW_BUG "requested region covers kernel memory @ %pa\n", &phys); - return NULL; + if (memblock_is_map_memory(phys) || + !memblock_is_region_memory(phys, size)) { + pr_warn(FW_BUG "requested region covers kernel memory @ %pa\n", &phys); + return NULL; + } + /* + * Mapping kernel memory is permitted if the region in + * question is covered by a single memblock with the + * NOMAP attribute set: this enables the use of ACPI + * table overrides passed via initramfs, which are + * reserved in memory using arch_reserve_mem_area() + * below. As this particular use case only requires + * read access, fall through to the R/O mapping case. + */ + fallthrough; case EFI_RUNTIME_SERVICES_CODE: /* @@ -388,3 +401,8 @@ int apei_claim_sea(struct pt_regs *regs) return err; } + +void arch_reserve_mem_area(acpi_physical_address addr, size_t size) +{ + memblock_mark_nomap(addr, size); +} diff --git a/arch/arm64/kernel/cpu-reset.S b/arch/arm64/kernel/cpu-reset.S index 4a18055b2ff9..37721eb6f9a1 100644 --- a/arch/arm64/kernel/cpu-reset.S +++ b/arch/arm64/kernel/cpu-reset.S @@ -35,6 +35,10 @@ SYM_CODE_START(__cpu_soft_restart) mov_q x13, SCTLR_ELx_FLAGS bic x12, x12, x13 pre_disable_mmu_workaround + /* + * either disable EL1&0 translation regime or disable EL2&0 translation + * regime if HCR_EL2.E2H == 1 + */ msr sctlr_el1, x12 isb diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 6c8303559beb..24d75af344b1 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -476,8 +476,12 @@ const struct arm64_cpu_capabilities arm64_errata[] = { .desc = "ARM erratum 1418040", .capability = ARM64_WORKAROUND_1418040, ERRATA_MIDR_RANGE_LIST(erratum_1418040_list), - .type = (ARM64_CPUCAP_SCOPE_LOCAL_CPU | - ARM64_CPUCAP_PERMITTED_FOR_LATE_CPU), + /* + * We need to allow affected CPUs to come in late, but + * also need the non-affected CPUs to be able to come + * in at any point in time. Wonderful. + */ + .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE, }, #endif #ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index a4debb63ebfb..dcc165b3fc04 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -75,6 +75,7 @@ #include <asm/cpu_ops.h> #include <asm/fpsimd.h> #include <asm/mmu_context.h> +#include <asm/mte.h> #include <asm/processor.h> #include <asm/sysreg.h> #include <asm/traps.h> @@ -197,9 +198,9 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = { ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_FCMA_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_JSCVT_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), - FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_API_SHIFT, 4, 0), + FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_API_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), - FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_APA_SHIFT, 4, 0), + FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_APA_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_DPB_SHIFT, 4, 0), ARM64_FTR_END, }; @@ -227,6 +228,8 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = { ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_MPAMFRAC_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_RASFRAC_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_MTE), + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_MTE_SHIFT, 4, ID_AA64PFR1_MTE_NI), ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR1_SSBS_SHIFT, 4, ID_AA64PFR1_SSBS_PSTATE_NI), ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_BTI), FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_BT_SHIFT, 4, 0), @@ -1111,6 +1114,7 @@ u64 read_sanitised_ftr_reg(u32 id) return 0; return regp->sys_val; } +EXPORT_SYMBOL_GPL(read_sanitised_ftr_reg); #define read_sysreg_case(r) \ case r: return read_sysreg_s(r) @@ -1443,6 +1447,7 @@ static inline void __cpu_enable_hw_dbm(void) write_sysreg(tcr, tcr_el1); isb(); + local_flush_tlb_all(); } static bool cpu_has_broken_dbm(void) @@ -1606,11 +1611,37 @@ static void cpu_clear_disr(const struct arm64_cpu_capabilities *__unused) #endif /* CONFIG_ARM64_RAS_EXTN */ #ifdef CONFIG_ARM64_PTR_AUTH -static bool has_address_auth(const struct arm64_cpu_capabilities *entry, - int __unused) +static bool has_address_auth_cpucap(const struct arm64_cpu_capabilities *entry, int scope) { - return __system_matches_cap(ARM64_HAS_ADDRESS_AUTH_ARCH) || - __system_matches_cap(ARM64_HAS_ADDRESS_AUTH_IMP_DEF); + int boot_val, sec_val; + + /* We don't expect to be called with SCOPE_SYSTEM */ + WARN_ON(scope == SCOPE_SYSTEM); + /* + * The ptr-auth feature levels are not intercompatible with lower + * levels. Hence we must match ptr-auth feature level of the secondary + * CPUs with that of the boot CPU. The level of boot cpu is fetched + * from the sanitised register whereas direct register read is done for + * the secondary CPUs. + * The sanitised feature state is guaranteed to match that of the + * boot CPU as a mismatched secondary CPU is parked before it gets + * a chance to update the state, with the capability. + */ + boot_val = cpuid_feature_extract_field(read_sanitised_ftr_reg(entry->sys_reg), + entry->field_pos, entry->sign); + if (scope & SCOPE_BOOT_CPU) + return boot_val >= entry->min_field_value; + /* Now check for the secondary CPUs with SCOPE_LOCAL_CPU scope */ + sec_val = cpuid_feature_extract_field(__read_sysreg_by_encoding(entry->sys_reg), + entry->field_pos, entry->sign); + return sec_val == boot_val; +} + +static bool has_address_auth_metacap(const struct arm64_cpu_capabilities *entry, + int scope) +{ + return has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH], scope) || + has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_IMP_DEF], scope); } static bool has_generic_auth(const struct arm64_cpu_capabilities *entry, @@ -1660,6 +1691,22 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused) } #endif /* CONFIG_ARM64_BTI */ +#ifdef CONFIG_ARM64_MTE +static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) +{ + static bool cleared_zero_page = false; + + /* + * Clear the tags in the zero page. This needs to be done via the + * linear map which has the Tagged attribute. + */ + if (!cleared_zero_page) { + cleared_zero_page = true; + mte_clear_page_tags(lm_alias(empty_zero_page)); + } +} +#endif /* CONFIG_ARM64_MTE */ + /* Internal helper functions to match cpu capability type */ static bool cpucap_late_cpu_optional(const struct arm64_cpu_capabilities *cap) @@ -1976,7 +2023,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .sign = FTR_UNSIGNED, .field_pos = ID_AA64ISAR1_APA_SHIFT, .min_field_value = ID_AA64ISAR1_APA_ARCHITECTED, - .matches = has_cpuid_feature, + .matches = has_address_auth_cpucap, }, { .desc = "Address authentication (IMP DEF algorithm)", @@ -1986,12 +2033,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .sign = FTR_UNSIGNED, .field_pos = ID_AA64ISAR1_API_SHIFT, .min_field_value = ID_AA64ISAR1_API_IMP_DEF, - .matches = has_cpuid_feature, + .matches = has_address_auth_cpucap, }, { .capability = ARM64_HAS_ADDRESS_AUTH, .type = ARM64_CPUCAP_BOOT_CPU_FEATURE, - .matches = has_address_auth, + .matches = has_address_auth_metacap, }, { .desc = "Generic authentication (architected algorithm)", @@ -2076,6 +2123,19 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .sign = FTR_UNSIGNED, }, #endif +#ifdef CONFIG_ARM64_MTE + { + .desc = "Memory Tagging Extension", + .capability = ARM64_MTE, + .type = ARM64_CPUCAP_STRICT_BOOT_CPU_FEATURE, + .matches = has_cpuid_feature, + .sys_reg = SYS_ID_AA64PFR1_EL1, + .field_pos = ID_AA64PFR1_MTE_SHIFT, + .min_field_value = ID_AA64PFR1_MTE, + .sign = FTR_UNSIGNED, + .cpu_enable = cpu_enable_mte, + }, +#endif /* CONFIG_ARM64_MTE */ {}, }; @@ -2192,6 +2252,9 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { HWCAP_MULTI_CAP(ptr_auth_hwcap_addr_matches, CAP_HWCAP, KERNEL_HWCAP_PACA), HWCAP_MULTI_CAP(ptr_auth_hwcap_gen_matches, CAP_HWCAP, KERNEL_HWCAP_PACG), #endif +#ifdef CONFIG_ARM64_MTE + HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE), +#endif /* CONFIG_ARM64_MTE */ {}, }; diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index d0076c2159e6..6a7bb3729d60 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -43,94 +43,93 @@ static const char *icache_policy_str[] = { unsigned long __icache_flags; static const char *const hwcap_str[] = { - "fp", - "asimd", - "evtstrm", - "aes", - "pmull", - "sha1", - "sha2", - "crc32", - "atomics", - "fphp", - "asimdhp", - "cpuid", - "asimdrdm", - "jscvt", - "fcma", - "lrcpc", - "dcpop", - "sha3", - "sm3", - "sm4", - "asimddp", - "sha512", - "sve", - "asimdfhm", - "dit", - "uscat", - "ilrcpc", - "flagm", - "ssbs", - "sb", - "paca", - "pacg", - "dcpodp", - "sve2", - "sveaes", - "svepmull", - "svebitperm", - "svesha3", - "svesm4", - "flagm2", - "frint", - "svei8mm", - "svef32mm", - "svef64mm", - "svebf16", - "i8mm", - "bf16", - "dgh", - "rng", - "bti", - /* reserved for "mte" */ - NULL + [KERNEL_HWCAP_FP] = "fp", + [KERNEL_HWCAP_ASIMD] = "asimd", + [KERNEL_HWCAP_EVTSTRM] = "evtstrm", + [KERNEL_HWCAP_AES] = "aes", + [KERNEL_HWCAP_PMULL] = "pmull", + [KERNEL_HWCAP_SHA1] = "sha1", + [KERNEL_HWCAP_SHA2] = "sha2", + [KERNEL_HWCAP_CRC32] = "crc32", + [KERNEL_HWCAP_ATOMICS] = "atomics", + [KERNEL_HWCAP_FPHP] = "fphp", + [KERNEL_HWCAP_ASIMDHP] = "asimdhp", + [KERNEL_HWCAP_CPUID] = "cpuid", + [KERNEL_HWCAP_ASIMDRDM] = "asimdrdm", + [KERNEL_HWCAP_JSCVT] = "jscvt", + [KERNEL_HWCAP_FCMA] = "fcma", + [KERNEL_HWCAP_LRCPC] = "lrcpc", + [KERNEL_HWCAP_DCPOP] = "dcpop", + [KERNEL_HWCAP_SHA3] = "sha3", + [KERNEL_HWCAP_SM3] = "sm3", + [KERNEL_HWCAP_SM4] = "sm4", + [KERNEL_HWCAP_ASIMDDP] = "asimddp", + [KERNEL_HWCAP_SHA512] = "sha512", + [KERNEL_HWCAP_SVE] = "sve", + [KERNEL_HWCAP_ASIMDFHM] = "asimdfhm", + [KERNEL_HWCAP_DIT] = "dit", + [KERNEL_HWCAP_USCAT] = "uscat", + [KERNEL_HWCAP_ILRCPC] = "ilrcpc", + [KERNEL_HWCAP_FLAGM] = "flagm", + [KERNEL_HWCAP_SSBS] = "ssbs", + [KERNEL_HWCAP_SB] = "sb", + [KERNEL_HWCAP_PACA] = "paca", + [KERNEL_HWCAP_PACG] = "pacg", + [KERNEL_HWCAP_DCPODP] = "dcpodp", + [KERNEL_HWCAP_SVE2] = "sve2", + [KERNEL_HWCAP_SVEAES] = "sveaes", + [KERNEL_HWCAP_SVEPMULL] = "svepmull", + [KERNEL_HWCAP_SVEBITPERM] = "svebitperm", + [KERNEL_HWCAP_SVESHA3] = "svesha3", + [KERNEL_HWCAP_SVESM4] = "svesm4", + [KERNEL_HWCAP_FLAGM2] = "flagm2", + [KERNEL_HWCAP_FRINT] = "frint", + [KERNEL_HWCAP_SVEI8MM] = "svei8mm", + [KERNEL_HWCAP_SVEF32MM] = "svef32mm", + [KERNEL_HWCAP_SVEF64MM] = "svef64mm", + [KERNEL_HWCAP_SVEBF16] = "svebf16", + [KERNEL_HWCAP_I8MM] = "i8mm", + [KERNEL_HWCAP_BF16] = "bf16", + [KERNEL_HWCAP_DGH] = "dgh", + [KERNEL_HWCAP_RNG] = "rng", + [KERNEL_HWCAP_BTI] = "bti", + [KERNEL_HWCAP_MTE] = "mte", }; #ifdef CONFIG_COMPAT +#define COMPAT_KERNEL_HWCAP(x) const_ilog2(COMPAT_HWCAP_ ## x) static const char *const compat_hwcap_str[] = { - "swp", - "half", - "thumb", - "26bit", - "fastmult", - "fpa", - "vfp", - "edsp", - "java", - "iwmmxt", - "crunch", - "thumbee", - "neon", - "vfpv3", - "vfpv3d16", - "tls", - "vfpv4", - "idiva", - "idivt", - "vfpd32", - "lpae", - "evtstrm", - NULL + [COMPAT_KERNEL_HWCAP(SWP)] = "swp", + [COMPAT_KERNEL_HWCAP(HALF)] = "half", + [COMPAT_KERNEL_HWCAP(THUMB)] = "thumb", + [COMPAT_KERNEL_HWCAP(26BIT)] = NULL, /* Not possible on arm64 */ + [COMPAT_KERNEL_HWCAP(FAST_MULT)] = "fastmult", + [COMPAT_KERNEL_HWCAP(FPA)] = NULL, /* Not possible on arm64 */ + [COMPAT_KERNEL_HWCAP(VFP)] = "vfp", + [COMPAT_KERNEL_HWCAP(EDSP)] = "edsp", + [COMPAT_KERNEL_HWCAP(JAVA)] = NULL, /* Not possible on arm64 */ + [COMPAT_KERNEL_HWCAP(IWMMXT)] = NULL, /* Not possible on arm64 */ + [COMPAT_KERNEL_HWCAP(CRUNCH)] = NULL, /* Not possible on arm64 */ + [COMPAT_KERNEL_HWCAP(THUMBEE)] = NULL, /* Not possible on arm64 */ + [COMPAT_KERNEL_HWCAP(NEON)] = "neon", + [COMPAT_KERNEL_HWCAP(VFPv3)] = "vfpv3", + [COMPAT_KERNEL_HWCAP(VFPV3D16)] = NULL, /* Not possible on arm64 */ + [COMPAT_KERNEL_HWCAP(TLS)] = "tls", + [COMPAT_KERNEL_HWCAP(VFPv4)] = "vfpv4", + [COMPAT_KERNEL_HWCAP(IDIVA)] = "idiva", + [COMPAT_KERNEL_HWCAP(IDIVT)] = "idivt", + [COMPAT_KERNEL_HWCAP(VFPD32)] = NULL, /* Not possible on arm64 */ + [COMPAT_KERNEL_HWCAP(LPAE)] = "lpae", + [COMPAT_KERNEL_HWCAP(EVTSTRM)] = "evtstrm", }; +#define COMPAT_KERNEL_HWCAP2(x) const_ilog2(COMPAT_HWCAP2_ ## x) static const char *const compat_hwcap2_str[] = { - "aes", - "pmull", - "sha1", - "sha2", - "crc32", - NULL + [COMPAT_KERNEL_HWCAP2(AES)] = "aes", + [COMPAT_KERNEL_HWCAP2(PMULL)] = "pmull", + [COMPAT_KERNEL_HWCAP2(SHA1)] = "sha1", + [COMPAT_KERNEL_HWCAP2(SHA2)] = "sha2", + [COMPAT_KERNEL_HWCAP2(CRC32)] = "crc32", }; #endif /* CONFIG_COMPAT */ @@ -166,16 +165,25 @@ static int c_show(struct seq_file *m, void *v) seq_puts(m, "Features\t:"); if (compat) { #ifdef CONFIG_COMPAT - for (j = 0; compat_hwcap_str[j]; j++) - if (compat_elf_hwcap & (1 << j)) + for (j = 0; j < ARRAY_SIZE(compat_hwcap_str); j++) { + if (compat_elf_hwcap & (1 << j)) { + /* + * Warn once if any feature should not + * have been present on arm64 platform. + */ + if (WARN_ON_ONCE(!compat_hwcap_str[j])) + continue; + seq_printf(m, " %s", compat_hwcap_str[j]); + } + } - for (j = 0; compat_hwcap2_str[j]; j++) + for (j = 0; j < ARRAY_SIZE(compat_hwcap2_str); j++) if (compat_elf_hwcap2 & (1 << j)) seq_printf(m, " %s", compat_hwcap2_str[j]); #endif /* CONFIG_COMPAT */ } else { - for (j = 0; hwcap_str[j]; j++) + for (j = 0; j < ARRAY_SIZE(hwcap_str); j++) if (cpu_have_feature(j)) seq_printf(m, " %s", hwcap_str[j]); } diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index 7310a4f7f993..fa76151de6ff 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -384,7 +384,7 @@ void __init debug_traps_init(void) hook_debug_fault_code(DBG_ESR_EVT_HWSS, single_step_handler, SIGTRAP, TRAP_TRACE, "single-step handler"); hook_debug_fault_code(DBG_ESR_EVT_BRK, brk_handler, SIGTRAP, - TRAP_BRKPT, "ptrace BRK handler"); + TRAP_BRKPT, "BRK handler"); } /* Re-enable single step for syscall restarting. */ diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index d0cf596db82c..fa02efb28e88 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -54,7 +54,7 @@ static __init pteval_t create_mapping_protection(efi_memory_desc_t *md) } /* we will fill this structure from the stub, so don't put it in .bss */ -struct screen_info screen_info __section(.data); +struct screen_info screen_info __section(".data"); int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) { diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c index d3be9dbf5490..43d4c329775f 100644 --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c @@ -66,6 +66,13 @@ static void notrace el1_dbg(struct pt_regs *regs, unsigned long esr) } NOKPROBE_SYMBOL(el1_dbg); +static void notrace el1_fpac(struct pt_regs *regs, unsigned long esr) +{ + local_daif_inherit(regs); + do_ptrauth_fault(regs, esr); +} +NOKPROBE_SYMBOL(el1_fpac); + asmlinkage void notrace el1_sync_handler(struct pt_regs *regs) { unsigned long esr = read_sysreg(esr_el1); @@ -92,6 +99,9 @@ asmlinkage void notrace el1_sync_handler(struct pt_regs *regs) case ESR_ELx_EC_BRK64: el1_dbg(regs, esr); break; + case ESR_ELx_EC_FPAC: + el1_fpac(regs, esr); + break; default: el1_inv(regs, esr); } @@ -227,6 +237,14 @@ static void notrace el0_svc(struct pt_regs *regs) } NOKPROBE_SYMBOL(el0_svc); +static void notrace el0_fpac(struct pt_regs *regs, unsigned long esr) +{ + user_exit_irqoff(); + local_daif_restore(DAIF_PROCCTX); + do_ptrauth_fault(regs, esr); +} +NOKPROBE_SYMBOL(el0_fpac); + asmlinkage void notrace el0_sync_handler(struct pt_regs *regs) { unsigned long esr = read_sysreg(esr_el1); @@ -272,6 +290,9 @@ asmlinkage void notrace el0_sync_handler(struct pt_regs *regs) case ESR_ELx_EC_BRK64: el0_dbg(regs, esr); break; + case ESR_ELx_EC_FPAC: + el0_fpac(regs, esr); + break; default: el0_inv(regs, esr); } diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S index f880dd63ddc3..2ca395c25448 100644 --- a/arch/arm64/kernel/entry-fpsimd.S +++ b/arch/arm64/kernel/entry-fpsimd.S @@ -32,6 +32,7 @@ SYM_FUNC_START(fpsimd_load_state) SYM_FUNC_END(fpsimd_load_state) #ifdef CONFIG_ARM64_SVE + SYM_FUNC_START(sve_save_state) sve_save 0, x1, 2 ret @@ -46,4 +47,28 @@ SYM_FUNC_START(sve_get_vl) _sve_rdvl 0, 1 ret SYM_FUNC_END(sve_get_vl) + +/* + * Load SVE state from FPSIMD state. + * + * x0 = pointer to struct fpsimd_state + * x1 = VQ - 1 + * + * Each SVE vector will be loaded with the first 128-bits taken from FPSIMD + * and the rest zeroed. All the other SVE registers will be zeroed. + */ +SYM_FUNC_START(sve_load_from_fpsimd_state) + sve_load_vq x1, x2, x3 + fpsimd_restore x0, 8 + _for n, 0, 15, _sve_pfalse \n + _sve_wrffr 0 + ret +SYM_FUNC_END(sve_load_from_fpsimd_state) + +/* Zero all SVE registers but the first 128-bits of each vector */ +SYM_FUNC_START(sve_flush_live) + sve_flush + ret +SYM_FUNC_END(sve_flush_live) + #endif /* CONFIG_ARM64_SVE */ diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index aeb337029d56..f30007dff35f 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -147,6 +147,32 @@ alternative_cb_end .L__asm_ssbd_skip\@: .endm + /* Check for MTE asynchronous tag check faults */ + .macro check_mte_async_tcf, flgs, tmp +#ifdef CONFIG_ARM64_MTE +alternative_if_not ARM64_MTE + b 1f +alternative_else_nop_endif + mrs_s \tmp, SYS_TFSRE0_EL1 + tbz \tmp, #SYS_TFSR_EL1_TF0_SHIFT, 1f + /* Asynchronous TCF occurred for TTBR0 access, set the TI flag */ + orr \flgs, \flgs, #_TIF_MTE_ASYNC_FAULT + str \flgs, [tsk, #TSK_TI_FLAGS] + msr_s SYS_TFSRE0_EL1, xzr +1: +#endif + .endm + + /* Clear the MTE asynchronous tag check faults */ + .macro clear_mte_async_tcf +#ifdef CONFIG_ARM64_MTE +alternative_if ARM64_MTE + dsb ish + msr_s SYS_TFSRE0_EL1, xzr +alternative_else_nop_endif +#endif + .endm + .macro kernel_entry, el, regsize = 64 .if \regsize == 32 mov w0, w0 // zero upper 32 bits of x0 @@ -180,6 +206,8 @@ alternative_cb_end ldr x19, [tsk, #TSK_TI_FLAGS] disable_step_tsk x19, x20 + /* Check for asynchronous tag check faults in user space */ + check_mte_async_tcf x19, x22 apply_ssbd 1, x22, x23 ptrauth_keys_install_kernel tsk, x20, x22, x23 @@ -231,6 +259,13 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING str x20, [sp, #S_PMR_SAVE] alternative_else_nop_endif + /* Re-enable tag checking (TCO set on exception entry) */ +#ifdef CONFIG_ARM64_MTE +alternative_if ARM64_MTE + SET_PSTATE_TCO(0) +alternative_else_nop_endif +#endif + /* * Registers that may be useful after this macro is invoked: * @@ -740,6 +775,8 @@ SYM_CODE_START_LOCAL(ret_to_user) and x2, x1, #_TIF_WORK_MASK cbnz x2, work_pending finish_ret_to_user: + /* Ignore asynchronous tag check faults in the uaccess routines */ + clear_mte_async_tcf enable_step_tsk x1, x2 #ifdef CONFIG_GCC_PLUGIN_STACKLEAK bl stackleak_erase diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 55c8f3ec6705..062b21f30f94 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -32,9 +32,11 @@ #include <linux/swab.h> #include <asm/esr.h> +#include <asm/exception.h> #include <asm/fpsimd.h> #include <asm/cpufeature.h> #include <asm/cputype.h> +#include <asm/neon.h> #include <asm/processor.h> #include <asm/simd.h> #include <asm/sigcontext.h> @@ -312,7 +314,7 @@ static void fpsimd_save(void) * re-enter user with corrupt state. * There's no way to recover, so kill it: */ - force_signal_inject(SIGKILL, SI_KERNEL, 0); + force_signal_inject(SIGKILL, SI_KERNEL, 0, 0); return; } @@ -676,7 +678,7 @@ int sve_set_current_vl(unsigned long arg) vl = arg & PR_SVE_VL_LEN_MASK; flags = arg & ~vl; - if (!system_supports_sve()) + if (!system_supports_sve() || is_compat_task()) return -EINVAL; ret = sve_set_vector_length(current, vl, flags); @@ -689,7 +691,7 @@ int sve_set_current_vl(unsigned long arg) /* PR_SVE_GET_VL */ int sve_get_current_vl(void) { - if (!system_supports_sve()) + if (!system_supports_sve() || is_compat_task()) return -EINVAL; return sve_prctl_status(0); @@ -928,7 +930,7 @@ void fpsimd_release_task(struct task_struct *dead_task) * the SVE access trap will be disabled the next time this task * reaches ret_to_user. * - * TIF_SVE should be clear on entry: otherwise, task_fpsimd_load() + * TIF_SVE should be clear on entry: otherwise, fpsimd_restore_current_state() * would have disabled the SVE access trap for userspace during * ret_to_user, making an SVE access trap impossible in that case. */ @@ -936,7 +938,7 @@ void do_sve_acc(unsigned int esr, struct pt_regs *regs) { /* Even if we chose not to use SVE, the hardware could still trap: */ if (unlikely(!system_supports_sve()) || WARN_ON(is_compat_task())) { - force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc); + force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0); return; } diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 037421c66b14..d8d9caf02834 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -36,14 +36,10 @@ #include "efi-header.S" -#define __PHYS_OFFSET (KERNEL_START - TEXT_OFFSET) +#define __PHYS_OFFSET KERNEL_START -#if (TEXT_OFFSET & 0xfff) != 0 -#error TEXT_OFFSET must be at least 4KB aligned -#elif (PAGE_OFFSET & 0x1fffff) != 0 +#if (PAGE_OFFSET & 0x1fffff) != 0 #error PAGE_OFFSET must be at least 2MB aligned -#elif TEXT_OFFSET > 0x1fffff -#error TEXT_OFFSET must be less than 2MB #endif /* @@ -55,7 +51,7 @@ * x0 = physical address to the FDT blob. * * This code is mostly position independent so you call this at - * __pa(PAGE_OFFSET + TEXT_OFFSET). + * __pa(PAGE_OFFSET). * * Note that the callee-saved registers are used for storing variables * that are useful before the MMU is enabled. The allocations are described @@ -77,7 +73,7 @@ _head: b primary_entry // branch to kernel start, magic .long 0 // reserved #endif - le64sym _kernel_offset_le // Image load offset from start of RAM, little-endian + .quad 0 // Image load offset from start of RAM, little-endian le64sym _kernel_size_le // Effective size of kernel image, little-endian le64sym _kernel_flags_le // Informative flags, little-endian .quad 0 // reserved @@ -382,7 +378,7 @@ SYM_FUNC_START_LOCAL(__create_page_tables) * Map the kernel image (starting with PHYS_OFFSET). */ adrp x0, init_pg_dir - mov_q x5, KIMAGE_VADDR + TEXT_OFFSET // compile time __va(_text) + mov_q x5, KIMAGE_VADDR // compile time __va(_text) add x5, x5, x23 // add KASLR displacement mov x4, PTRS_PER_PGD adrp x6, _end // runtime __pa(_end) @@ -474,7 +470,7 @@ SYM_FUNC_END(__primary_switched) .pushsection ".rodata", "a" SYM_DATA_START(kimage_vaddr) - .quad _text - TEXT_OFFSET + .quad _text SYM_DATA_END(kimage_vaddr) EXPORT_SYMBOL(kimage_vaddr) .popsection diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c index c7b00120dc3e..42003774d261 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c @@ -21,7 +21,6 @@ #include <linux/sched.h> #include <linux/suspend.h> #include <linux/utsname.h> -#include <linux/version.h> #include <asm/barrier.h> #include <asm/cacheflush.h> @@ -31,6 +30,7 @@ #include <asm/kexec.h> #include <asm/memory.h> #include <asm/mmu_context.h> +#include <asm/mte.h> #include <asm/pgalloc.h> #include <asm/pgtable-hwdef.h> #include <asm/sections.h> @@ -285,6 +285,117 @@ static int create_safe_exec_page(void *src_start, size_t length, #define dcache_clean_range(start, end) __flush_dcache_area(start, (end - start)) +#ifdef CONFIG_ARM64_MTE + +static DEFINE_XARRAY(mte_pages); + +static int save_tags(struct page *page, unsigned long pfn) +{ + void *tag_storage, *ret; + + tag_storage = mte_allocate_tag_storage(); + if (!tag_storage) + return -ENOMEM; + + mte_save_page_tags(page_address(page), tag_storage); + + ret = xa_store(&mte_pages, pfn, tag_storage, GFP_KERNEL); + if (WARN(xa_is_err(ret), "Failed to store MTE tags")) { + mte_free_tag_storage(tag_storage); + return xa_err(ret); + } else if (WARN(ret, "swsusp: %s: Duplicate entry", __func__)) { + mte_free_tag_storage(ret); + } + + return 0; +} + +static void swsusp_mte_free_storage(void) +{ + XA_STATE(xa_state, &mte_pages, 0); + void *tags; + + xa_lock(&mte_pages); + xas_for_each(&xa_state, tags, ULONG_MAX) { + mte_free_tag_storage(tags); + } + xa_unlock(&mte_pages); + + xa_destroy(&mte_pages); +} + +static int swsusp_mte_save_tags(void) +{ + struct zone *zone; + unsigned long pfn, max_zone_pfn; + int ret = 0; + int n = 0; + + if (!system_supports_mte()) + return 0; + + for_each_populated_zone(zone) { + max_zone_pfn = zone_end_pfn(zone); + for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) { + struct page *page = pfn_to_online_page(pfn); + + if (!page) + continue; + + if (!test_bit(PG_mte_tagged, &page->flags)) + continue; + + ret = save_tags(page, pfn); + if (ret) { + swsusp_mte_free_storage(); + goto out; + } + + n++; + } + } + pr_info("Saved %d MTE pages\n", n); + +out: + return ret; +} + +static void swsusp_mte_restore_tags(void) +{ + XA_STATE(xa_state, &mte_pages, 0); + int n = 0; + void *tags; + + xa_lock(&mte_pages); + xas_for_each(&xa_state, tags, ULONG_MAX) { + unsigned long pfn = xa_state.xa_index; + struct page *page = pfn_to_online_page(pfn); + + mte_restore_page_tags(page_address(page), tags); + + mte_free_tag_storage(tags); + n++; + } + xa_unlock(&mte_pages); + + pr_info("Restored %d MTE pages\n", n); + + xa_destroy(&mte_pages); +} + +#else /* CONFIG_ARM64_MTE */ + +static int swsusp_mte_save_tags(void) +{ + return 0; +} + +static void swsusp_mte_restore_tags(void) +{ +} + +#endif /* CONFIG_ARM64_MTE */ + int swsusp_arch_suspend(void) { int ret = 0; @@ -302,6 +413,10 @@ int swsusp_arch_suspend(void) /* make the crash dump kernel image visible/saveable */ crash_prepare_suspend(); + ret = swsusp_mte_save_tags(); + if (ret) + return ret; + sleep_cpu = smp_processor_id(); ret = swsusp_save(); } else { @@ -315,6 +430,8 @@ int swsusp_arch_suspend(void) dcache_clean_range(__hyp_text_start, __hyp_text_end); } + swsusp_mte_restore_tags(); + /* make the crash dump kernel image protected again */ crash_post_resume(); diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h index ad8432251733..c615b285ff5b 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -95,6 +95,8 @@ KVM_NVHE_ALIAS(vgic_v3_cpuif_trap); /* Static key checked in pmr_sync(). */ #ifdef CONFIG_ARM64_PSEUDO_NMI KVM_NVHE_ALIAS(gic_pmr_sync); +/* Static key checked in GIC_PRIO_IRQOFF. */ +KVM_NVHE_ALIAS(gic_nonsecure_priorities); #endif /* EL2 exception handling */ diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h index c7d38c660372..7bc3ba897901 100644 --- a/arch/arm64/kernel/image.h +++ b/arch/arm64/kernel/image.h @@ -62,7 +62,6 @@ */ #define HEAD_SYMBOLS \ DEFINE_IMAGE_LE64(_kernel_size_le, _end - _text); \ - DEFINE_IMAGE_LE64(_kernel_offset_le, TEXT_OFFSET); \ DEFINE_IMAGE_LE64(_kernel_flags_le, __HEAD_FLAGS); #endif /* __ARM64_KERNEL_IMAGE_H */ diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c index a107375005bc..6c0de2f60ea9 100644 --- a/arch/arm64/kernel/insn.c +++ b/arch/arm64/kernel/insn.c @@ -60,16 +60,10 @@ bool __kprobes aarch64_insn_is_steppable_hint(u32 insn) case AARCH64_INSN_HINT_XPACLRI: case AARCH64_INSN_HINT_PACIA_1716: case AARCH64_INSN_HINT_PACIB_1716: - case AARCH64_INSN_HINT_AUTIA_1716: - case AARCH64_INSN_HINT_AUTIB_1716: case AARCH64_INSN_HINT_PACIAZ: case AARCH64_INSN_HINT_PACIASP: case AARCH64_INSN_HINT_PACIBZ: case AARCH64_INSN_HINT_PACIBSP: - case AARCH64_INSN_HINT_AUTIAZ: - case AARCH64_INSN_HINT_AUTIASP: - case AARCH64_INSN_HINT_AUTIBZ: - case AARCH64_INSN_HINT_AUTIBSP: case AARCH64_INSN_HINT_BTI: case AARCH64_INSN_HINT_BTIC: case AARCH64_INSN_HINT_BTIJ: @@ -176,7 +170,7 @@ bool __kprobes aarch64_insn_uses_literal(u32 insn) bool __kprobes aarch64_insn_is_branch(u32 insn) { - /* b, bl, cb*, tb*, b.cond, br, blr */ + /* b, bl, cb*, tb*, ret*, b.cond, br*, blr* */ return aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn) || @@ -185,8 +179,11 @@ bool __kprobes aarch64_insn_is_branch(u32 insn) aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn) || aarch64_insn_is_ret(insn) || + aarch64_insn_is_ret_auth(insn) || aarch64_insn_is_br(insn) || + aarch64_insn_is_br_auth(insn) || aarch64_insn_is_blr(insn) || + aarch64_insn_is_blr_auth(insn) || aarch64_insn_is_bcond(insn); } diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c index 04a327ccf84d..9cf2fb87584a 100644 --- a/arch/arm64/kernel/irq.c +++ b/arch/arm64/kernel/irq.c @@ -10,10 +10,10 @@ * Copyright (C) 2012 ARM Ltd. */ -#include <linux/kernel_stat.h> #include <linux/irq.h> #include <linux/memory.h> #include <linux/smp.h> +#include <linux/hardirq.h> #include <linux/init.h> #include <linux/irqchip.h> #include <linux/kprobes.h> @@ -22,20 +22,11 @@ #include <asm/daifflags.h> #include <asm/vmap_stack.h> -unsigned long irq_err_count; - /* Only access this in an NMI enter/exit */ DEFINE_PER_CPU(struct nmi_ctx, nmi_contexts); DEFINE_PER_CPU(unsigned long *, irq_stack_ptr); -int arch_show_interrupts(struct seq_file *p, int prec) -{ - show_ipi_list(p, prec); - seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); - return 0; -} - #ifdef CONFIG_VMAP_STACK static void init_irq_stacks(void) { diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c index 361a1143e09e..5b0e67b93cdc 100644 --- a/arch/arm64/kernel/machine_kexec_file.c +++ b/arch/arm64/kernel/machine_kexec_file.c @@ -215,8 +215,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz) phys_addr_t start, end; nr_ranges = 1; /* for exclusion of crashkernel region */ - for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE, - MEMBLOCK_NONE, &start, &end, NULL) + for_each_mem_range(i, &start, &end) nr_ranges++; cmem = kmalloc(struct_size(cmem, ranges, nr_ranges), GFP_KERNEL); @@ -225,8 +224,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz) cmem->max_nr_ranges = nr_ranges; cmem->nr_ranges = 0; - for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE, - MEMBLOCK_NONE, &start, &end, NULL) { + for_each_mem_range(i, &start, &end) { cmem->ranges[cmem->nr_ranges].start = start; cmem->ranges[cmem->nr_ranges].end = end - 1; cmem->nr_ranges++; diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c new file mode 100644 index 000000000000..52a0638ed967 --- /dev/null +++ b/arch/arm64/kernel/mte.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 ARM Ltd. + */ + +#include <linux/bitops.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/prctl.h> +#include <linux/sched.h> +#include <linux/sched/mm.h> +#include <linux/string.h> +#include <linux/swap.h> +#include <linux/swapops.h> +#include <linux/thread_info.h> +#include <linux/uio.h> + +#include <asm/cpufeature.h> +#include <asm/mte.h> +#include <asm/ptrace.h> +#include <asm/sysreg.h> + +static void mte_sync_page_tags(struct page *page, pte_t *ptep, bool check_swap) +{ + pte_t old_pte = READ_ONCE(*ptep); + + if (check_swap && is_swap_pte(old_pte)) { + swp_entry_t entry = pte_to_swp_entry(old_pte); + + if (!non_swap_entry(entry) && mte_restore_tags(entry, page)) + return; + } + + mte_clear_page_tags(page_address(page)); +} + +void mte_sync_tags(pte_t *ptep, pte_t pte) +{ + struct page *page = pte_page(pte); + long i, nr_pages = compound_nr(page); + bool check_swap = nr_pages == 1; + + /* if PG_mte_tagged is set, tags have already been initialised */ + for (i = 0; i < nr_pages; i++, page++) { + if (!test_and_set_bit(PG_mte_tagged, &page->flags)) + mte_sync_page_tags(page, ptep, check_swap); + } +} + +int memcmp_pages(struct page *page1, struct page *page2) +{ + char *addr1, *addr2; + int ret; + + addr1 = page_address(page1); + addr2 = page_address(page2); + ret = memcmp(addr1, addr2, PAGE_SIZE); + + if (!system_supports_mte() || ret) + return ret; + + /* + * If the page content is identical but at least one of the pages is + * tagged, return non-zero to avoid KSM merging. If only one of the + * pages is tagged, set_pte_at() may zero or change the tags of the + * other page via mte_sync_tags(). + */ + if (test_bit(PG_mte_tagged, &page1->flags) || + test_bit(PG_mte_tagged, &page2->flags)) + return addr1 != addr2; + + return ret; +} + +static void update_sctlr_el1_tcf0(u64 tcf0) +{ + /* ISB required for the kernel uaccess routines */ + sysreg_clear_set(sctlr_el1, SCTLR_EL1_TCF0_MASK, tcf0); + isb(); +} + +static void set_sctlr_el1_tcf0(u64 tcf0) +{ + /* + * mte_thread_switch() checks current->thread.sctlr_tcf0 as an + * optimisation. Disable preemption so that it does not see + * the variable update before the SCTLR_EL1.TCF0 one. + */ + preempt_disable(); + current->thread.sctlr_tcf0 = tcf0; + update_sctlr_el1_tcf0(tcf0); + preempt_enable(); +} + +static void update_gcr_el1_excl(u64 incl) +{ + 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. + * 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) +{ + current->thread.gcr_user_incl = incl; + update_gcr_el1_excl(incl); +} + +void flush_mte_state(void) +{ + if (!system_supports_mte()) + return; + + /* clear any pending asynchronous tag fault */ + dsb(ish); + write_sysreg_s(0, SYS_TFSRE0_EL1); + clear_thread_flag(TIF_MTE_ASYNC_FAULT); + /* disable tag checking */ + set_sctlr_el1_tcf0(SCTLR_EL1_TCF0_NONE); + /* reset tag generation mask */ + set_gcr_el1_excl(0); +} + +void mte_thread_switch(struct task_struct *next) +{ + if (!system_supports_mte()) + return; + + /* 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) +{ + if (!system_supports_mte()) + return; + + update_gcr_el1_excl(current->thread.gcr_user_incl); +} + +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; + + if (!system_supports_mte()) + return 0; + + switch (arg & PR_MTE_TCF_MASK) { + case PR_MTE_TCF_NONE: + tcf0 = SCTLR_EL1_TCF0_NONE; + break; + case PR_MTE_TCF_SYNC: + tcf0 = SCTLR_EL1_TCF0_SYNC; + break; + case PR_MTE_TCF_ASYNC: + tcf0 = SCTLR_EL1_TCF0_ASYNC; + break; + default: + return -EINVAL; + } + + if (task != current) { + task->thread.sctlr_tcf0 = tcf0; + task->thread.gcr_user_incl = gcr_incl; + } else { + set_sctlr_el1_tcf0(tcf0); + set_gcr_el1_excl(gcr_incl); + } + + return 0; +} + +long get_mte_ctrl(struct task_struct *task) +{ + unsigned long ret; + + if (!system_supports_mte()) + return 0; + + ret = task->thread.gcr_user_incl << PR_MTE_TAG_SHIFT; + + switch (task->thread.sctlr_tcf0) { + case SCTLR_EL1_TCF0_NONE: + return PR_MTE_TCF_NONE; + case SCTLR_EL1_TCF0_SYNC: + ret |= PR_MTE_TCF_SYNC; + break; + case SCTLR_EL1_TCF0_ASYNC: + ret |= PR_MTE_TCF_ASYNC; + break; + } + + return ret; +} + +/* + * Access MTE tags in another process' address space as given in mm. Update + * the number of tags copied. Return 0 if any tags copied, error otherwise. + * Inspired by __access_remote_vm(). + */ +static int __access_remote_tags(struct mm_struct *mm, unsigned long addr, + struct iovec *kiov, unsigned int gup_flags) +{ + struct vm_area_struct *vma; + void __user *buf = kiov->iov_base; + size_t len = kiov->iov_len; + int ret; + int write = gup_flags & FOLL_WRITE; + + if (!access_ok(buf, len)) + return -EFAULT; + + if (mmap_read_lock_killable(mm)) + return -EIO; + + while (len) { + unsigned long tags, offset; + void *maddr; + struct page *page = NULL; + + ret = get_user_pages_remote(mm, addr, 1, gup_flags, &page, + &vma, NULL); + if (ret <= 0) + break; + + /* + * Only copy tags if the page has been mapped as PROT_MTE + * (PG_mte_tagged set). Otherwise the tags are not valid and + * not accessible to user. Moreover, an mprotect(PROT_MTE) + * would cause the existing tags to be cleared if the page + * was never mapped with PROT_MTE. + */ + if (!test_bit(PG_mte_tagged, &page->flags)) { + ret = -EOPNOTSUPP; + put_page(page); + break; + } + + /* limit access to the end of the page */ + offset = offset_in_page(addr); + tags = min(len, (PAGE_SIZE - offset) / MTE_GRANULE_SIZE); + + maddr = page_address(page); + if (write) { + tags = mte_copy_tags_from_user(maddr + offset, buf, tags); + set_page_dirty_lock(page); + } else { + tags = mte_copy_tags_to_user(buf, maddr + offset, tags); + } + put_page(page); + + /* error accessing the tracer's buffer */ + if (!tags) + break; + + len -= tags; + buf += tags; + addr += tags * MTE_GRANULE_SIZE; + } + mmap_read_unlock(mm); + + /* return an error if no tags copied */ + kiov->iov_len = buf - kiov->iov_base; + if (!kiov->iov_len) { + /* check for error accessing the tracee's address space */ + if (ret <= 0) + return -EIO; + else + return -EFAULT; + } + + return 0; +} + +/* + * Copy MTE tags in another process' address space at 'addr' to/from tracer's + * iovec buffer. Return 0 on success. Inspired by ptrace_access_vm(). + */ +static int access_remote_tags(struct task_struct *tsk, unsigned long addr, + struct iovec *kiov, unsigned int gup_flags) +{ + struct mm_struct *mm; + int ret; + + mm = get_task_mm(tsk); + if (!mm) + return -EPERM; + + if (!tsk->ptrace || (current != tsk->parent) || + ((get_dumpable(mm) != SUID_DUMP_USER) && + !ptracer_capable(tsk, mm->user_ns))) { + mmput(mm); + return -EPERM; + } + + ret = __access_remote_tags(mm, addr, kiov, gup_flags); + mmput(mm); + + return ret; +} + +int mte_ptrace_copy_tags(struct task_struct *child, long request, + unsigned long addr, unsigned long data) +{ + int ret; + struct iovec kiov; + struct iovec __user *uiov = (void __user *)data; + unsigned int gup_flags = FOLL_FORCE; + + if (!system_supports_mte()) + return -EIO; + + if (get_user(kiov.iov_base, &uiov->iov_base) || + get_user(kiov.iov_len, &uiov->iov_len)) + return -EFAULT; + + if (request == PTRACE_POKEMTETAGS) + gup_flags |= FOLL_WRITE; + + /* align addr to the MTE tag granule */ + addr &= MTE_GRANULE_MASK; + + ret = access_remote_tags(child, addr, &kiov, gup_flags); + if (!ret) + ret = put_user(kiov.iov_len, &uiov->iov_len); + + return ret; +} diff --git a/arch/arm64/kernel/paravirt.c b/arch/arm64/kernel/paravirt.c index 295d66490584..c07d7a034941 100644 --- a/arch/arm64/kernel/paravirt.c +++ b/arch/arm64/kernel/paravirt.c @@ -50,16 +50,19 @@ static u64 pv_steal_clock(int cpu) struct pv_time_stolen_time_region *reg; reg = per_cpu_ptr(&stolen_time_region, cpu); - if (!reg->kaddr) { - pr_warn_once("stolen time enabled but not configured for cpu %d\n", - cpu); + + /* + * paravirt_steal_clock() may be called before the CPU + * online notification callback runs. Until the callback + * has run we just return zero. + */ + if (!reg->kaddr) return 0; - } return le64_to_cpu(READ_ONCE(reg->kaddr->stolen_time)); } -static int stolen_time_dying_cpu(unsigned int cpu) +static int stolen_time_cpu_down_prepare(unsigned int cpu) { struct pv_time_stolen_time_region *reg; @@ -73,7 +76,7 @@ static int stolen_time_dying_cpu(unsigned int cpu) return 0; } -static int init_stolen_time_cpu(unsigned int cpu) +static int stolen_time_cpu_online(unsigned int cpu) { struct pv_time_stolen_time_region *reg; struct arm_smccc_res res; @@ -103,19 +106,20 @@ static int init_stolen_time_cpu(unsigned int cpu) return 0; } -static int pv_time_init_stolen_time(void) +static int __init pv_time_init_stolen_time(void) { int ret; - ret = cpuhp_setup_state(CPUHP_AP_ARM_KVMPV_STARTING, - "hypervisor/arm/pvtime:starting", - init_stolen_time_cpu, stolen_time_dying_cpu); + ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, + "hypervisor/arm/pvtime:online", + stolen_time_cpu_online, + stolen_time_cpu_down_prepare); if (ret < 0) return ret; return 0; } -static bool has_pv_steal_clock(void) +static bool __init has_pv_steal_clock(void) { struct arm_smccc_res res; diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c index b0e03e052dd1..88ff471b0bce 100644 --- a/arch/arm64/kernel/perf_callchain.c +++ b/arch/arm64/kernel/perf_callchain.c @@ -137,11 +137,11 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry, * whist unwinding the stackframe and is like a subroutine return so we use * the PC. */ -static int callchain_trace(struct stackframe *frame, void *data) +static bool callchain_trace(void *data, unsigned long pc) { struct perf_callchain_entry_ctx *entry = data; - perf_callchain_store(entry, frame->pc); - return 0; + perf_callchain_store(entry, pc); + return true; } void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 462f9a9cc44b..3605f77ad4df 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -69,6 +69,9 @@ static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL, [C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB, + [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS_RD, + [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_LL_CACHE_RD, + [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, }; @@ -302,13 +305,33 @@ static struct attribute_group armv8_pmuv3_format_attr_group = { .attrs = armv8_pmuv3_format_attrs, }; +static ssize_t slots_show(struct device *dev, struct device_attribute *attr, + char *page) +{ + struct pmu *pmu = dev_get_drvdata(dev); + struct arm_pmu *cpu_pmu = container_of(pmu, struct arm_pmu, pmu); + u32 slots = cpu_pmu->reg_pmmir & ARMV8_PMU_SLOTS_MASK; + + return snprintf(page, PAGE_SIZE, "0x%08x\n", slots); +} + +static DEVICE_ATTR_RO(slots); + +static struct attribute *armv8_pmuv3_caps_attrs[] = { + &dev_attr_slots.attr, + NULL, +}; + +static struct attribute_group armv8_pmuv3_caps_attr_group = { + .name = "caps", + .attrs = armv8_pmuv3_caps_attrs, +}; + /* * Perf Events' indices */ #define ARMV8_IDX_CYCLE_COUNTER 0 #define ARMV8_IDX_COUNTER0 1 -#define ARMV8_IDX_COUNTER_LAST(cpu_pmu) \ - (ARMV8_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1) /* @@ -348,6 +371,73 @@ static inline bool armv8pmu_event_is_chained(struct perf_event *event) #define ARMV8_IDX_TO_COUNTER(x) \ (((x) - ARMV8_IDX_COUNTER0) & ARMV8_PMU_COUNTER_MASK) +/* + * This code is really good + */ + +#define PMEVN_CASE(n, case_macro) \ + case n: case_macro(n); break + +#define PMEVN_SWITCH(x, case_macro) \ + do { \ + switch (x) { \ + PMEVN_CASE(0, case_macro); \ + PMEVN_CASE(1, case_macro); \ + PMEVN_CASE(2, case_macro); \ + PMEVN_CASE(3, case_macro); \ + PMEVN_CASE(4, case_macro); \ + PMEVN_CASE(5, case_macro); \ + PMEVN_CASE(6, case_macro); \ + PMEVN_CASE(7, case_macro); \ + PMEVN_CASE(8, case_macro); \ + PMEVN_CASE(9, case_macro); \ + PMEVN_CASE(10, case_macro); \ + PMEVN_CASE(11, case_macro); \ + PMEVN_CASE(12, case_macro); \ + PMEVN_CASE(13, case_macro); \ + PMEVN_CASE(14, case_macro); \ + PMEVN_CASE(15, case_macro); \ + PMEVN_CASE(16, case_macro); \ + PMEVN_CASE(17, case_macro); \ + PMEVN_CASE(18, case_macro); \ + PMEVN_CASE(19, case_macro); \ + PMEVN_CASE(20, case_macro); \ + PMEVN_CASE(21, case_macro); \ + PMEVN_CASE(22, case_macro); \ + PMEVN_CASE(23, case_macro); \ + PMEVN_CASE(24, case_macro); \ + PMEVN_CASE(25, case_macro); \ + PMEVN_CASE(26, case_macro); \ + PMEVN_CASE(27, case_macro); \ + PMEVN_CASE(28, case_macro); \ + PMEVN_CASE(29, case_macro); \ + PMEVN_CASE(30, case_macro); \ + default: WARN(1, "Invalid PMEV* index\n"); \ + } \ + } while (0) + +#define RETURN_READ_PMEVCNTRN(n) \ + return read_sysreg(pmevcntr##n##_el0) +static unsigned long read_pmevcntrn(int n) +{ + PMEVN_SWITCH(n, RETURN_READ_PMEVCNTRN); + return 0; +} + +#define WRITE_PMEVCNTRN(n) \ + write_sysreg(val, pmevcntr##n##_el0) +static void write_pmevcntrn(int n, unsigned long val) +{ + PMEVN_SWITCH(n, WRITE_PMEVCNTRN); +} + +#define WRITE_PMEVTYPERN(n) \ + write_sysreg(val, pmevtyper##n##_el0) +static void write_pmevtypern(int n, unsigned long val) +{ + PMEVN_SWITCH(n, WRITE_PMEVTYPERN); +} + static inline u32 armv8pmu_pmcr_read(void) { return read_sysreg(pmcr_el0); @@ -365,28 +455,16 @@ static inline int armv8pmu_has_overflowed(u32 pmovsr) return pmovsr & ARMV8_PMU_OVERFLOWED_MASK; } -static inline int armv8pmu_counter_valid(struct arm_pmu *cpu_pmu, int idx) -{ - return idx >= ARMV8_IDX_CYCLE_COUNTER && - idx <= ARMV8_IDX_COUNTER_LAST(cpu_pmu); -} - static inline int armv8pmu_counter_has_overflowed(u32 pmnc, int idx) { return pmnc & BIT(ARMV8_IDX_TO_COUNTER(idx)); } -static inline void armv8pmu_select_counter(int idx) +static inline u32 armv8pmu_read_evcntr(int idx) { u32 counter = ARMV8_IDX_TO_COUNTER(idx); - write_sysreg(counter, pmselr_el0); - isb(); -} -static inline u64 armv8pmu_read_evcntr(int idx) -{ - armv8pmu_select_counter(idx); - return read_sysreg(pmxevcntr_el0); + return read_pmevcntrn(counter); } static inline u64 armv8pmu_read_hw_counter(struct perf_event *event) @@ -440,15 +518,11 @@ static u64 armv8pmu_unbias_long_counter(struct perf_event *event, u64 value) static u64 armv8pmu_read_counter(struct perf_event *event) { - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); struct hw_perf_event *hwc = &event->hw; int idx = hwc->idx; u64 value = 0; - if (!armv8pmu_counter_valid(cpu_pmu, idx)) - pr_err("CPU%u reading wrong counter %d\n", - smp_processor_id(), idx); - else if (idx == ARMV8_IDX_CYCLE_COUNTER) + if (idx == ARMV8_IDX_CYCLE_COUNTER) value = read_sysreg(pmccntr_el0); else value = armv8pmu_read_hw_counter(event); @@ -458,8 +532,9 @@ static u64 armv8pmu_read_counter(struct perf_event *event) static inline void armv8pmu_write_evcntr(int idx, u64 value) { - armv8pmu_select_counter(idx); - write_sysreg(value, pmxevcntr_el0); + u32 counter = ARMV8_IDX_TO_COUNTER(idx); + + write_pmevcntrn(counter, value); } static inline void armv8pmu_write_hw_counter(struct perf_event *event, @@ -477,16 +552,12 @@ static inline void armv8pmu_write_hw_counter(struct perf_event *event, static void armv8pmu_write_counter(struct perf_event *event, u64 value) { - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); struct hw_perf_event *hwc = &event->hw; int idx = hwc->idx; value = armv8pmu_bias_long_counter(event, value); - if (!armv8pmu_counter_valid(cpu_pmu, idx)) - pr_err("CPU%u writing wrong counter %d\n", - smp_processor_id(), idx); - else if (idx == ARMV8_IDX_CYCLE_COUNTER) + if (idx == ARMV8_IDX_CYCLE_COUNTER) write_sysreg(value, pmccntr_el0); else armv8pmu_write_hw_counter(event, value); @@ -494,9 +565,10 @@ static void armv8pmu_write_counter(struct perf_event *event, u64 value) static inline void armv8pmu_write_evtype(int idx, u32 val) { - armv8pmu_select_counter(idx); + u32 counter = ARMV8_IDX_TO_COUNTER(idx); + val &= ARMV8_PMU_EVTYPE_MASK; - write_sysreg(val, pmxevtyper_el0); + write_pmevtypern(counter, val); } static inline void armv8pmu_write_event_type(struct perf_event *event) @@ -516,7 +588,10 @@ static inline void armv8pmu_write_event_type(struct perf_event *event) armv8pmu_write_evtype(idx - 1, hwc->config_base); armv8pmu_write_evtype(idx, chain_evt); } else { - armv8pmu_write_evtype(idx, hwc->config_base); + if (idx == ARMV8_IDX_CYCLE_COUNTER) + write_sysreg(hwc->config_base, pmccfiltr_el0); + else + armv8pmu_write_evtype(idx, hwc->config_base); } } @@ -532,6 +607,11 @@ static u32 armv8pmu_event_cnten_mask(struct perf_event *event) static inline void armv8pmu_enable_counter(u32 mask) { + /* + * Make sure event configuration register writes are visible before we + * enable the counter. + * */ + isb(); write_sysreg(mask, pmcntenset_el0); } @@ -550,6 +630,11 @@ static inline void armv8pmu_enable_event_counter(struct perf_event *event) static inline void armv8pmu_disable_counter(u32 mask) { write_sysreg(mask, pmcntenclr_el0); + /* + * Make sure the effects of disabling the counter are visible before we + * start configuring the event. + */ + isb(); } static inline void armv8pmu_disable_event_counter(struct perf_event *event) @@ -606,15 +691,10 @@ static inline u32 armv8pmu_getreset_flags(void) static void armv8pmu_enable_event(struct perf_event *event) { - unsigned long flags; - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); - /* * Enable counter and interrupt, and set the counter to count * the event that we're interested in. */ - raw_spin_lock_irqsave(&events->pmu_lock, flags); /* * Disable counter @@ -622,7 +702,7 @@ static void armv8pmu_enable_event(struct perf_event *event) armv8pmu_disable_event_counter(event); /* - * Set event (if destined for PMNx counters). + * Set event. */ armv8pmu_write_event_type(event); @@ -635,21 +715,10 @@ static void armv8pmu_enable_event(struct perf_event *event) * Enable counter */ armv8pmu_enable_event_counter(event); - - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); } static void armv8pmu_disable_event(struct perf_event *event) { - unsigned long flags; - struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); - - /* - * Disable counter and interrupt - */ - raw_spin_lock_irqsave(&events->pmu_lock, flags); - /* * Disable counter */ @@ -659,30 +728,18 @@ static void armv8pmu_disable_event(struct perf_event *event) * Disable interrupt for this counter */ armv8pmu_disable_event_irq(event); - - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); } static void armv8pmu_start(struct arm_pmu *cpu_pmu) { - unsigned long flags; - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); - - raw_spin_lock_irqsave(&events->pmu_lock, flags); /* Enable all counters */ armv8pmu_pmcr_write(armv8pmu_pmcr_read() | ARMV8_PMU_PMCR_E); - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); } static void armv8pmu_stop(struct arm_pmu *cpu_pmu) { - unsigned long flags; - struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events); - - raw_spin_lock_irqsave(&events->pmu_lock, flags); /* Disable all counters */ armv8pmu_pmcr_write(armv8pmu_pmcr_read() & ~ARMV8_PMU_PMCR_E); - raw_spin_unlock_irqrestore(&events->pmu_lock, flags); } static irqreturn_t armv8pmu_handle_irq(struct arm_pmu *cpu_pmu) @@ -735,20 +792,16 @@ static irqreturn_t armv8pmu_handle_irq(struct arm_pmu *cpu_pmu) if (!armpmu_event_set_period(event)) continue; + /* + * Perf event overflow will queue the processing of the event as + * an irq_work which will be taken care of in the handling of + * IPI_IRQ_WORK. + */ if (perf_event_overflow(event, &data, regs)) cpu_pmu->disable(event); } armv8pmu_start(cpu_pmu); - /* - * Handle the pending perf events. - * - * Note: this call *must* be run with interrupts disabled. For - * platforms that can have the PMU interrupts raised as an NMI, this - * will not work. - */ - irq_work_run(); - return IRQ_HANDLED; } @@ -997,6 +1050,12 @@ static void __armv8pmu_probe_pmu(void *info) bitmap_from_arr32(cpu_pmu->pmceid_ext_bitmap, pmceid, ARMV8_PMUV3_MAX_COMMON_EVENTS); + + /* store PMMIR_EL1 register for sysfs */ + if (pmuver >= ID_AA64DFR0_PMUVER_8_4 && (pmceid_raw[1] & BIT(31))) + cpu_pmu->reg_pmmir = read_cpuid(PMMIR_EL1); + else + cpu_pmu->reg_pmmir = 0; } static int armv8pmu_probe_pmu(struct arm_pmu *cpu_pmu) @@ -1019,7 +1078,8 @@ static int armv8pmu_probe_pmu(struct arm_pmu *cpu_pmu) static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name, int (*map_event)(struct perf_event *event), const struct attribute_group *events, - const struct attribute_group *format) + const struct attribute_group *format, + const struct attribute_group *caps) { int ret = armv8pmu_probe_pmu(cpu_pmu); if (ret) @@ -1044,104 +1104,112 @@ static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name, events : &armv8_pmuv3_events_attr_group; cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = format ? format : &armv8_pmuv3_format_attr_group; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_CAPS] = caps ? + caps : &armv8_pmuv3_caps_attr_group; return 0; } +static int armv8_pmu_init_nogroups(struct arm_pmu *cpu_pmu, char *name, + int (*map_event)(struct perf_event *event)) +{ + return armv8_pmu_init(cpu_pmu, name, map_event, NULL, NULL, NULL); +} + static int armv8_pmuv3_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_pmuv3", - armv8_pmuv3_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_pmuv3", + armv8_pmuv3_map_event); } static int armv8_a34_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_cortex_a34", - armv8_pmuv3_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a34", + armv8_pmuv3_map_event); } static int armv8_a35_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_cortex_a35", - armv8_a53_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a35", + armv8_a53_map_event); } static int armv8_a53_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_cortex_a53", - armv8_a53_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a53", + armv8_a53_map_event); } static int armv8_a55_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_cortex_a55", - armv8_pmuv3_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a55", + armv8_pmuv3_map_event); } static int armv8_a57_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_cortex_a57", - armv8_a57_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a57", + armv8_a57_map_event); } static int armv8_a65_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_cortex_a65", - armv8_pmuv3_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a65", + armv8_pmuv3_map_event); } static int armv8_a72_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_cortex_a72", - armv8_a57_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a72", + armv8_a57_map_event); } static int armv8_a73_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_cortex_a73", - armv8_a73_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a73", + armv8_a73_map_event); } static int armv8_a75_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_cortex_a75", - armv8_pmuv3_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a75", + armv8_pmuv3_map_event); } static int armv8_a76_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_cortex_a76", - armv8_pmuv3_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a76", + armv8_pmuv3_map_event); } static int armv8_a77_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_cortex_a77", - armv8_pmuv3_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a77", + armv8_pmuv3_map_event); } static int armv8_e1_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_neoverse_e1", - armv8_pmuv3_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_neoverse_e1", + armv8_pmuv3_map_event); } static int armv8_n1_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_neoverse_n1", - armv8_pmuv3_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_neoverse_n1", + armv8_pmuv3_map_event); } static int armv8_thunder_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_cavium_thunder", - armv8_thunder_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cavium_thunder", + armv8_thunder_map_event); } static int armv8_vulcan_pmu_init(struct arm_pmu *cpu_pmu) { - return armv8_pmu_init(cpu_pmu, "armv8_brcm_vulcan", - armv8_vulcan_map_event, NULL, NULL); + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_brcm_vulcan", + armv8_vulcan_map_event); } static const struct of_device_id armv8_pmu_of_device_ids[] = { diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c index 666b225aeb3a..94e8718e7229 100644 --- a/arch/arm64/kernel/perf_regs.c +++ b/arch/arm64/kernel/perf_regs.c @@ -16,7 +16,7 @@ u64 perf_reg_value(struct pt_regs *regs, int idx) /* * Our handling of compat tasks (PERF_SAMPLE_REGS_ABI_32) is weird, but - * we're stuck with it for ABI compatability reasons. + * we're stuck with it for ABI compatibility reasons. * * For a 32-bit consumer inspecting a 32-bit task, then it will look at * the first 16 registers (see arch/arm/include/uapi/asm/perf_regs.h). diff --git a/arch/arm64/kernel/pointer_auth.c b/arch/arm64/kernel/pointer_auth.c index 1e77736a4f66..adb955fd9bdd 100644 --- a/arch/arm64/kernel/pointer_auth.c +++ b/arch/arm64/kernel/pointer_auth.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 +#include <linux/compat.h> #include <linux/errno.h> #include <linux/prctl.h> #include <linux/random.h> @@ -17,6 +18,9 @@ int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg) if (!system_supports_address_auth() && !system_supports_generic_auth()) return -EINVAL; + if (is_compat_thread(task_thread_info(tsk))) + return -EINVAL; + if (!arg) { ptrauth_keys_init_user(keys); return 0; diff --git a/arch/arm64/kernel/probes/decode-insn.c b/arch/arm64/kernel/probes/decode-insn.c index 263d5fba4c8a..104101f633b1 100644 --- a/arch/arm64/kernel/probes/decode-insn.c +++ b/arch/arm64/kernel/probes/decode-insn.c @@ -29,7 +29,8 @@ static bool __kprobes aarch64_insn_is_steppable(u32 insn) aarch64_insn_is_msr_imm(insn) || aarch64_insn_is_msr_reg(insn) || aarch64_insn_is_exception(insn) || - aarch64_insn_is_eret(insn)) + aarch64_insn_is_eret(insn) || + aarch64_insn_is_eret_auth(insn)) return false; /* @@ -42,8 +43,10 @@ static bool __kprobes aarch64_insn_is_steppable(u32 insn) != AARCH64_INSN_SPCLREG_DAIF; /* - * The HINT instruction is is problematic when single-stepping, - * except for the NOP case. + * The HINT instruction is steppable only if it is in whitelist + * and the rest of other such instructions are blocked for + * single stepping as they may cause exception or other + * unintended behaviour. */ if (aarch64_insn_is_hint(insn)) return aarch64_insn_is_steppable_hint(insn); diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index 5290f17a4d80..deba738142ed 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c @@ -464,87 +464,15 @@ int __init arch_populate_kprobe_blacklist(void) void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *tmp; - unsigned long flags, orig_ret_address = 0; - unsigned long trampoline_address = - (unsigned long)&kretprobe_trampoline; - kprobe_opcode_t *correct_ret_addr = NULL; - - INIT_HLIST_HEAD(&empty_rp); - kretprobe_hash_lock(current, &head, &flags); - - /* - * It is possible to have multiple instances associated with a given - * task either because multiple functions in the call path have - * return probes installed on them, and/or more than one - * return probe was registered for a target function. - * - * We can handle this because: - * - instances are always pushed into the head of the list - * - when multiple return probes are registered for the same - * function, the (chronologically) first instance's ret_addr - * will be the real return address, and all the rest will - * point to kretprobe_trampoline. - */ - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - orig_ret_address = (unsigned long)ri->ret_addr; - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_assert(ri, orig_ret_address, trampoline_address); - - correct_ret_addr = ri->ret_addr; - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - orig_ret_address = (unsigned long)ri->ret_addr; - if (ri->rp && ri->rp->handler) { - __this_cpu_write(current_kprobe, &ri->rp->kp); - get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; - ri->ret_addr = correct_ret_addr; - ri->rp->handler(ri, regs); - __this_cpu_write(current_kprobe, NULL); - } - - recycle_rp_inst(ri, &empty_rp); - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_hash_unlock(current, &flags); - - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } - return (void *)orig_ret_address; + return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, + (void *)kernel_stack_pointer(regs)); } void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) { ri->ret_addr = (kprobe_opcode_t *)regs->regs[30]; + ri->fp = (void *)kernel_stack_pointer(regs); /* replace return addr (x30) with trampoline */ regs->regs[30] = (long)&kretprobe_trampoline; diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 085d8ca39e47..4784011cecac 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -53,6 +53,7 @@ #include <asm/exec.h> #include <asm/fpsimd.h> #include <asm/mmu_context.h> +#include <asm/mte.h> #include <asm/processor.h> #include <asm/pointer_auth.h> #include <asm/stacktrace.h> @@ -240,7 +241,7 @@ static void print_pstate(struct pt_regs *regs) const char *btype_str = btypes[(pstate & PSR_BTYPE_MASK) >> PSR_BTYPE_SHIFT]; - printk("pstate: %08llx (%c%c%c%c %c%c%c%c %cPAN %cUAO BTYPE=%s)\n", + printk("pstate: %08llx (%c%c%c%c %c%c%c%c %cPAN %cUAO %cTCO BTYPE=%s)\n", pstate, pstate & PSR_N_BIT ? 'N' : 'n', pstate & PSR_Z_BIT ? 'Z' : 'z', @@ -252,6 +253,7 @@ static void print_pstate(struct pt_regs *regs) pstate & PSR_F_BIT ? 'F' : 'f', pstate & PSR_PAN_BIT ? '+' : '-', pstate & PSR_UAO_BIT ? '+' : '-', + pstate & PSR_TCO_BIT ? '+' : '-', btype_str); } } @@ -337,6 +339,7 @@ void flush_thread(void) tls_thread_flush(); flush_ptrace_hw_breakpoint(current); flush_tagged_addr_state(); + flush_mte_state(); } void release_thread(struct task_struct *dead_task) @@ -369,6 +372,9 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) dst->thread.sve_state = NULL; clear_tsk_thread_flag(dst, TIF_SVE); + /* clear any pending asynchronous tag fault raised by the parent */ + clear_tsk_thread_flag(dst, TIF_MTE_ASYNC_FAULT); + return 0; } @@ -561,6 +567,13 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev, */ dsb(ish); + /* + * MTE thread switching must happen after the DSB above to ensure that + * any asynchronous tag check faults have been logged in the TFSR*_EL1 + * registers. + */ + mte_thread_switch(next); + /* the actual thread switch */ last = cpu_switch_to(prev, next); @@ -623,11 +636,18 @@ void arch_setup_new_exec(void) */ static unsigned int tagged_addr_disabled; -long set_tagged_addr_ctrl(unsigned long arg) +long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg) { - if (is_compat_task()) + unsigned long valid_mask = PR_TAGGED_ADDR_ENABLE; + struct thread_info *ti = task_thread_info(task); + + if (is_compat_thread(ti)) return -EINVAL; - if (arg & ~PR_TAGGED_ADDR_ENABLE) + + if (system_supports_mte()) + valid_mask |= PR_MTE_TCF_MASK | PR_MTE_TAG_MASK; + + if (arg & ~valid_mask) return -EINVAL; /* @@ -637,20 +657,28 @@ long set_tagged_addr_ctrl(unsigned long arg) if (arg & PR_TAGGED_ADDR_ENABLE && tagged_addr_disabled) return -EINVAL; - update_thread_flag(TIF_TAGGED_ADDR, arg & PR_TAGGED_ADDR_ENABLE); + if (set_mte_ctrl(task, arg) != 0) + return -EINVAL; + + update_ti_thread_flag(ti, TIF_TAGGED_ADDR, arg & PR_TAGGED_ADDR_ENABLE); return 0; } -long get_tagged_addr_ctrl(void) +long get_tagged_addr_ctrl(struct task_struct *task) { - if (is_compat_task()) + long ret = 0; + struct thread_info *ti = task_thread_info(task); + + if (is_compat_thread(ti)) return -EINVAL; - if (test_thread_flag(TIF_TAGGED_ADDR)) - return PR_TAGGED_ADDR_ENABLE; + if (test_ti_thread_flag(ti, TIF_TAGGED_ADDR)) + ret = PR_TAGGED_ADDR_ENABLE; - return 0; + ret |= get_mte_ctrl(task); + + return ret; } /* diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c index 68b710f1b43f..25f3c80b5ffe 100644 --- a/arch/arm64/kernel/proton-pack.c +++ b/arch/arm64/kernel/proton-pack.c @@ -67,7 +67,8 @@ ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, * - Mitigated in hardware and advertised by ID_AA64PFR0_EL1.CSV2. * - Mitigated in hardware and listed in our "safe list". * - Mitigated in software by firmware. - * - Mitigated in software by a CPU-specific dance in the kernel. + * - Mitigated in software by a CPU-specific dance in the kernel and a + * firmware call at EL2. * - Vulnerable. * * It's not unlikely for different CPUs in a big.LITTLE system to fall into @@ -204,8 +205,8 @@ static void install_bp_hardening_cb(bp_hardening_cb_t fn) __SMCCC_WORKAROUND_1_SMC_SZ; /* - * detect_harden_bp_fw() passes NULL for the hyp_vecs start/end if - * we're a guest. Skip the hyp-vectors work. + * 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); @@ -259,6 +260,16 @@ static void qcom_link_stack_sanitisation(void) : "=&r" (tmp)); } +static bp_hardening_cb_t spectre_v2_get_sw_mitigation_cb(void) +{ + u32 midr = read_cpuid_id(); + if (((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR) && + ((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR_V1)) + return NULL; + + return qcom_link_stack_sanitisation; +} + static enum mitigation_state spectre_v2_enable_fw_mitigation(void) { bp_hardening_cb_t cb; @@ -284,26 +295,15 @@ static enum mitigation_state spectre_v2_enable_fw_mitigation(void) return SPECTRE_VULNERABLE; } + /* + * Prefer a CPU-specific workaround if it exists. Note that we + * still rely on firmware for the mitigation at EL2. + */ + cb = spectre_v2_get_sw_mitigation_cb() ?: cb; install_bp_hardening_cb(cb); return SPECTRE_MITIGATED; } -static enum mitigation_state spectre_v2_enable_sw_mitigation(void) -{ - u32 midr; - - if (spectre_v2_mitigations_off()) - return SPECTRE_VULNERABLE; - - midr = read_cpuid_id(); - if (((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR) && - ((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR_V1)) - return SPECTRE_VULNERABLE; - - install_bp_hardening_cb(qcom_link_stack_sanitisation); - return SPECTRE_MITIGATED; -} - void spectre_v2_enable_mitigation(const struct arm64_cpu_capabilities *__unused) { enum mitigation_state state; @@ -313,8 +313,6 @@ void spectre_v2_enable_mitigation(const struct arm64_cpu_capabilities *__unused) state = spectre_v2_get_cpu_hw_mitigation_state(); if (state == SPECTRE_VULNERABLE) state = spectre_v2_enable_fw_mitigation(); - if (state == SPECTRE_VULNERABLE) - state = spectre_v2_enable_sw_mitigation(); update_mitigation_state(&spectre_v2_state, state); } diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index d8ebfd813e28..f49b349e16a3 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -34,6 +34,7 @@ #include <asm/cpufeature.h> #include <asm/debug-monitors.h> #include <asm/fpsimd.h> +#include <asm/mte.h> #include <asm/pointer_auth.h> #include <asm/stacktrace.h> #include <asm/syscall.h> @@ -1032,6 +1033,35 @@ static int pac_generic_keys_set(struct task_struct *target, #endif /* CONFIG_CHECKPOINT_RESTORE */ #endif /* CONFIG_ARM64_PTR_AUTH */ +#ifdef CONFIG_ARM64_TAGGED_ADDR_ABI +static int tagged_addr_ctrl_get(struct task_struct *target, + const struct user_regset *regset, + struct membuf to) +{ + long ctrl = get_tagged_addr_ctrl(target); + + if (IS_ERR_VALUE(ctrl)) + return ctrl; + + return membuf_write(&to, &ctrl, sizeof(ctrl)); +} + +static int tagged_addr_ctrl_set(struct task_struct *target, const struct + user_regset *regset, unsigned int pos, + unsigned int count, const void *kbuf, const + void __user *ubuf) +{ + int ret; + long ctrl; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl, 0, -1); + if (ret) + return ret; + + return set_tagged_addr_ctrl(target, ctrl); +} +#endif + enum aarch64_regset { REGSET_GPR, REGSET_FPR, @@ -1051,6 +1081,9 @@ enum aarch64_regset { REGSET_PACG_KEYS, #endif #endif +#ifdef CONFIG_ARM64_TAGGED_ADDR_ABI + REGSET_TAGGED_ADDR_CTRL, +#endif }; static const struct user_regset aarch64_regsets[] = { @@ -1148,6 +1181,16 @@ static const struct user_regset aarch64_regsets[] = { }, #endif #endif +#ifdef CONFIG_ARM64_TAGGED_ADDR_ABI + [REGSET_TAGGED_ADDR_CTRL] = { + .core_note_type = NT_ARM_TAGGED_ADDR_CTRL, + .n = 1, + .size = sizeof(long), + .align = sizeof(long), + .regset_get = tagged_addr_ctrl_get, + .set = tagged_addr_ctrl_set, + }, +#endif }; static const struct user_regset_view user_aarch64_view = { @@ -1691,6 +1734,12 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task) long arch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data) { + switch (request) { + case PTRACE_PEEKMTETAGS: + case PTRACE_POKEMTETAGS: + return mte_ptrace_copy_tags(child, request, addr, data); + } + return ptrace_request(child, request, addr, data); } @@ -1793,7 +1842,7 @@ void syscall_trace_exit(struct pt_regs *regs) * We also reserve IL for the kernel; SS is handled dynamically. */ #define SPSR_EL1_AARCH64_RES0_BITS \ - (GENMASK_ULL(63, 32) | GENMASK_ULL(27, 25) | GENMASK_ULL(23, 22) | \ + (GENMASK_ULL(63, 32) | GENMASK_ULL(27, 26) | GENMASK_ULL(23, 22) | \ GENMASK_ULL(20, 13) | GENMASK_ULL(5, 5)) #define SPSR_EL1_AARCH32_RES0_BITS \ (GENMASK_ULL(63, 32) | GENMASK_ULL(22, 22) | GENMASK_ULL(20, 20)) diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S index 542d6edc6806..84eec95ec06c 100644 --- a/arch/arm64/kernel/relocate_kernel.S +++ b/arch/arm64/kernel/relocate_kernel.S @@ -36,18 +36,6 @@ SYM_CODE_START(arm64_relocate_new_kernel) mov x14, xzr /* x14 = entry ptr */ mov x13, xzr /* x13 = copy dest */ - /* Clear the sctlr_el2 flags. */ - mrs x0, CurrentEL - cmp x0, #CurrentEL_EL2 - b.ne 1f - mrs x0, sctlr_el2 - mov_q x1, SCTLR_ELx_FLAGS - bic x0, x0, x1 - pre_disable_mmu_workaround - msr sctlr_el2, x0 - isb -1: - /* Check if the new image needs relocation. */ tbnz x16, IND_DONE_BIT, .Ldone diff --git a/arch/arm64/kernel/return_address.c b/arch/arm64/kernel/return_address.c index a5e8b3b9d798..a6d18755652f 100644 --- a/arch/arm64/kernel/return_address.c +++ b/arch/arm64/kernel/return_address.c @@ -18,16 +18,16 @@ struct return_address_data { void *addr; }; -static int save_return_addr(struct stackframe *frame, void *d) +static bool save_return_addr(void *d, unsigned long pc) { struct return_address_data *data = d; if (!data->level) { - data->addr = (void *)frame->pc; - return 1; + data->addr = (void *)pc; + return false; } else { --data->level; - return 0; + return true; } } NOKPROBE_SYMBOL(save_return_addr); diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 53acbeca4f57..133257ffd859 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -217,7 +217,7 @@ static void __init request_standard_resources(void) if (!standard_resources) panic("%s: Failed to allocate %zu bytes\n", __func__, res_size); - for_each_memblock(memory, region) { + for_each_mem_region(region) { res = &standard_resources[i++]; if (memblock_is_nomap(region)) { res->name = "reserved"; @@ -257,7 +257,7 @@ static int __init reserve_memblock_reserved_regions(void) if (!memblock_is_region_reserved(mem->start, mem_size)) continue; - for_each_reserved_mem_region(j, &r_start, &r_end) { + for_each_reserved_mem_range(j, &r_start, &r_end) { resource_size_t start, end; start = max(PFN_PHYS(PFN_DOWN(r_start)), mem->start); diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 3b4f31f35e45..a8184cad8890 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -244,7 +244,8 @@ static int preserve_sve_context(struct sve_context __user *ctx) if (vq) { /* * This assumes that the SVE state has already been saved to - * the task struct by calling preserve_fpsimd_context(). + * the task struct by calling the function + * fpsimd_signal_preserve_current_state(). */ err |= __copy_to_user((char __user *)ctx + SVE_SIG_REGS_OFFSET, current->thread.sve_state, @@ -748,6 +749,9 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, regs->pstate |= PSR_BTYPE_C; } + /* TCO (Tag Check Override) always cleared for signal handlers */ + regs->pstate &= ~PSR_TCO_BIT; + if (ka->sa.sa_flags & SA_RESTORER) sigtramp = ka->sa.sa_restorer; else @@ -932,11 +936,16 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, if (thread_flags & _TIF_UPROBE) uprobe_notify_resume(regs); + if (thread_flags & _TIF_MTE_ASYNC_FAULT) { + clear_thread_flag(TIF_MTE_ASYNC_FAULT); + send_sig_fault(SIGSEGV, SEGV_MTEAERR, + (void __user *)NULL, current); + } + if (thread_flags & _TIF_SIGPENDING) do_signal(regs); if (thread_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); rseq_handle_notify_resume(NULL, regs); } diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S index 1f93809528a4..d62447964ed9 100644 --- a/arch/arm64/kernel/smccc-call.S +++ b/arch/arm64/kernel/smccc-call.S @@ -9,7 +9,6 @@ #include <asm/assembler.h> .macro SMCCC instr - .cfi_startproc \instr #0 ldr x4, [sp] stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] @@ -21,7 +20,6 @@ b.ne 1f str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS] 1: ret - .cfi_endproc .endm /* diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 355ee9eed4dd..82e75fc2c903 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -30,6 +30,7 @@ #include <linux/completion.h> #include <linux/of.h> #include <linux/irq_work.h> +#include <linux/kernel_stat.h> #include <linux/kexec.h> #include <linux/kvm_host.h> @@ -72,10 +73,18 @@ enum ipi_msg_type { IPI_CPU_CRASH_STOP, IPI_TIMER, IPI_IRQ_WORK, - IPI_WAKEUP + IPI_WAKEUP, + NR_IPI }; +static int ipi_irq_base __read_mostly; +static int nr_ipi __read_mostly = NR_IPI; +static struct irq_desc *ipi_desc[NR_IPI] __read_mostly; + +static void ipi_setup(int cpu); + #ifdef CONFIG_HOTPLUG_CPU +static void ipi_teardown(int cpu); static int op_cpu_kill(unsigned int cpu); #else static inline int op_cpu_kill(unsigned int cpu) @@ -237,6 +246,8 @@ asmlinkage notrace void secondary_start_kernel(void) */ notify_cpu_starting(cpu); + ipi_setup(cpu); + store_cpu_topology(cpu); numa_add_cpu(cpu); @@ -302,6 +313,7 @@ int __cpu_disable(void) * and we must not schedule until we're ready to give up the cpu. */ set_cpu_online(cpu, false); + ipi_teardown(cpu); /* * OK - migrate IRQs away from this CPU @@ -772,13 +784,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } } -void (*__smp_cross_call)(const struct cpumask *, unsigned int); - -void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) -{ - __smp_cross_call = fn; -} - static const char *ipi_types[NR_IPI] __tracepoint_string = { #define S(x,s) [x] = s S(IPI_RESCHEDULE, "Rescheduling interrupts"), @@ -790,35 +795,25 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = { S(IPI_WAKEUP, "CPU wake-up interrupts"), }; -static void smp_cross_call(const struct cpumask *target, unsigned int ipinr) -{ - trace_ipi_raise(target, ipi_types[ipinr]); - __smp_cross_call(target, ipinr); -} +static void smp_cross_call(const struct cpumask *target, unsigned int ipinr); -void show_ipi_list(struct seq_file *p, int prec) +unsigned long irq_err_count; + +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 ", - __get_irq_stat(cpu, ipi_irqs[i])); + seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu)); seq_printf(p, " %s\n", ipi_types[i]); } -} - -u64 smp_irq_stat_cpu(unsigned int cpu) -{ - u64 sum = 0; - int i; - for (i = 0; i < NR_IPI; i++) - sum += __get_irq_stat(cpu, ipi_irqs[i]); - - return sum; + seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); + return 0; } void arch_send_call_function_ipi_mask(const struct cpumask *mask) @@ -841,8 +836,7 @@ void arch_send_wakeup_ipi_mask(const struct cpumask *mask) #ifdef CONFIG_IRQ_WORK void arch_irq_work_raise(void) { - if (__smp_cross_call) - smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); + smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); } #endif @@ -890,15 +884,12 @@ static void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs) /* * Main handler for inter-processor interrupts */ -void handle_IPI(int ipinr, struct pt_regs *regs) +static void do_handle_IPI(int ipinr) { unsigned int cpu = smp_processor_id(); - struct pt_regs *old_regs = set_irq_regs(regs); - if ((unsigned)ipinr < NR_IPI) { + if ((unsigned)ipinr < NR_IPI) trace_ipi_entry_rcuidle(ipi_types[ipinr]); - __inc_irq_stat(cpu, ipi_irqs[ipinr]); - } switch (ipinr) { case IPI_RESCHEDULE: @@ -906,21 +897,16 @@ void handle_IPI(int ipinr, struct pt_regs *regs) break; case IPI_CALL_FUNC: - irq_enter(); generic_smp_call_function_interrupt(); - irq_exit(); break; case IPI_CPU_STOP: - irq_enter(); local_cpu_stop(); - irq_exit(); break; case IPI_CPU_CRASH_STOP: if (IS_ENABLED(CONFIG_KEXEC_CORE)) { - irq_enter(); - ipi_cpu_crash_stop(cpu, regs); + ipi_cpu_crash_stop(cpu, get_irq_regs()); unreachable(); } @@ -928,17 +914,13 @@ void handle_IPI(int ipinr, struct pt_regs *regs) #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST case IPI_TIMER: - irq_enter(); tick_receive_broadcast(); - irq_exit(); break; #endif #ifdef CONFIG_IRQ_WORK case IPI_IRQ_WORK: - irq_enter(); irq_work_run(); - irq_exit(); break; #endif @@ -957,7 +939,66 @@ void handle_IPI(int ipinr, struct pt_regs *regs) if ((unsigned)ipinr < NR_IPI) trace_ipi_exit_rcuidle(ipi_types[ipinr]); - set_irq_regs(old_regs); +} + +static irqreturn_t ipi_handler(int irq, void *data) +{ + do_handle_IPI(irq - ipi_irq_base); + return IRQ_HANDLED; +} + +static void smp_cross_call(const struct cpumask *target, unsigned int ipinr) +{ + trace_ipi_raise(target, ipi_types[ipinr]); + __ipi_send_mask(ipi_desc[ipinr], target); +} + +static void ipi_setup(int cpu) +{ + int i; + + if (WARN_ON_ONCE(!ipi_irq_base)) + return; + + for (i = 0; i < nr_ipi; i++) + enable_percpu_irq(ipi_irq_base + i, 0); +} + +#ifdef CONFIG_HOTPLUG_CPU +static void ipi_teardown(int cpu) +{ + int i; + + if (WARN_ON_ONCE(!ipi_irq_base)) + return; + + for (i = 0; i < nr_ipi; i++) + disable_percpu_irq(ipi_irq_base + i); +} +#endif + +void __init set_smp_ipi_range(int ipi_base, int n) +{ + int i; + + WARN_ON(n < NR_IPI); + nr_ipi = min(n, NR_IPI); + + for (i = 0; i < nr_ipi; i++) { + int err; + + err = request_percpu_irq(ipi_base + i, ipi_handler, + "IPI", &cpu_number); + WARN_ON(err); + + ipi_desc[i] = irq_to_desc(ipi_base + i); + irq_set_status_flags(ipi_base + i, IRQ_HIDDEN); + } + + ipi_irq_base = ipi_base; + + /* Setup the boot CPU immediately */ + ipi_setup(smp_processor_id()); } void smp_send_reschedule(int cpu) diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c index c8a3fee00c11..056772c26098 100644 --- a/arch/arm64/kernel/smp_spin_table.c +++ b/arch/arm64/kernel/smp_spin_table.c @@ -19,7 +19,7 @@ #include <asm/smp_plat.h> extern void secondary_holding_pen(void); -volatile unsigned long __section(.mmuoff.data.read) +volatile unsigned long __section(".mmuoff.data.read") secondary_holding_pen_release = INVALID_HWID; static phys_addr_t cpu_release_addr[NR_CPUS]; @@ -83,9 +83,9 @@ static int smp_spin_table_cpu_prepare(unsigned int cpu) /* * We write the release address as LE regardless of the native - * endianess of the kernel. Therefore, any boot-loaders that + * endianness of the kernel. Therefore, any boot-loaders that * read this address need to convert this address to the - * boot-loader's endianess before jumping. This is mandated by + * boot-loader's endianness before jumping. This is mandated by * the boot protocol. */ writeq_relaxed(__pa_symbol(secondary_holding_pen), release_addr); diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 2dd8e3b8b94b..fa56af1a59c3 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -118,12 +118,12 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) NOKPROBE_SYMBOL(unwind_frame); void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame, - int (*fn)(struct stackframe *, void *), void *data) + bool (*fn)(void *, unsigned long), void *data) { while (1) { int ret; - if (fn(frame, data)) + if (!fn(data, frame->pc)) break; ret = unwind_frame(tsk, frame); if (ret < 0) @@ -132,84 +132,89 @@ void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame, } NOKPROBE_SYMBOL(walk_stackframe); -#ifdef CONFIG_STACKTRACE -struct stack_trace_data { - struct stack_trace *trace; - unsigned int no_sched_functions; - unsigned int skip; -}; - -static int save_trace(struct stackframe *frame, void *d) +static void dump_backtrace_entry(unsigned long where, const char *loglvl) { - struct stack_trace_data *data = d; - struct stack_trace *trace = data->trace; - unsigned long addr = frame->pc; - - if (data->no_sched_functions && in_sched_functions(addr)) - return 0; - if (data->skip) { - data->skip--; - return 0; - } - - trace->entries[trace->nr_entries++] = addr; - - return trace->nr_entries >= trace->max_entries; + printk("%s %pS\n", loglvl, (void *)where); } -void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) +void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk, + const char *loglvl) { - struct stack_trace_data data; struct stackframe frame; + int skip = 0; - data.trace = trace; - data.skip = trace->skip; - data.no_sched_functions = 0; + pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); - start_backtrace(&frame, regs->regs[29], regs->pc); - walk_stackframe(current, &frame, save_trace, &data); -} -EXPORT_SYMBOL_GPL(save_stack_trace_regs); + if (regs) { + if (user_mode(regs)) + return; + skip = 1; + } -static noinline void __save_stack_trace(struct task_struct *tsk, - struct stack_trace *trace, unsigned int nosched) -{ - struct stack_trace_data data; - struct stackframe frame; + if (!tsk) + tsk = current; if (!try_get_task_stack(tsk)) return; - data.trace = trace; - data.skip = trace->skip; - data.no_sched_functions = nosched; - - if (tsk != current) { - start_backtrace(&frame, thread_saved_fp(tsk), - thread_saved_pc(tsk)); - } else { - /* We don't want this function nor the caller */ - data.skip += 2; + if (tsk == current) { start_backtrace(&frame, (unsigned long)__builtin_frame_address(0), - (unsigned long)__save_stack_trace); + (unsigned long)dump_backtrace); + } else { + /* + * task blocked in __switch_to + */ + start_backtrace(&frame, + thread_saved_fp(tsk), + thread_saved_pc(tsk)); } - walk_stackframe(tsk, &frame, save_trace, &data); + printk("%sCall trace:\n", loglvl); + do { + /* skip until specified stack frame */ + if (!skip) { + dump_backtrace_entry(frame.pc, loglvl); + } else if (frame.fp == regs->regs[29]) { + skip = 0; + /* + * Mostly, this is the case where this function is + * called in panic/abort. As exception handler's + * stack frame does not contain the corresponding pc + * at which an exception has taken place, use regs->pc + * instead. + */ + dump_backtrace_entry(regs->pc, loglvl); + } + } while (!unwind_frame(tsk, &frame)); put_task_stack(tsk); } -void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) +void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl) { - __save_stack_trace(tsk, trace, 1); + dump_backtrace(NULL, tsk, loglvl); + barrier(); } -EXPORT_SYMBOL_GPL(save_stack_trace_tsk); -void save_stack_trace(struct stack_trace *trace) +#ifdef CONFIG_STACKTRACE + +void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, + struct task_struct *task, struct pt_regs *regs) { - __save_stack_trace(current, trace, 0); + struct stackframe frame; + + if (regs) + start_backtrace(&frame, regs->regs[29], regs->pc); + else if (task == current) + start_backtrace(&frame, + (unsigned long)__builtin_frame_address(0), + (unsigned long)arch_stack_walk); + else + start_backtrace(&frame, thread_saved_fp(task), + thread_saved_pc(task)); + + walk_stackframe(task, &frame, consume_entry, cookie); } -EXPORT_SYMBOL_GPL(save_stack_trace); #endif diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c index 584c14ce3c86..96cd347c7a46 100644 --- a/arch/arm64/kernel/suspend.c +++ b/arch/arm64/kernel/suspend.c @@ -10,6 +10,7 @@ #include <asm/daifflags.h> #include <asm/debug-monitors.h> #include <asm/exec.h> +#include <asm/mte.h> #include <asm/memory.h> #include <asm/mmu_context.h> #include <asm/smp_plat.h> @@ -73,6 +74,9 @@ void notrace __cpu_suspend_exit(void) * disabled it, make sure their wishes are obeyed. */ spectre_v4_enable_mitigation(NULL); + + /* Restore additional MTE-specific configuration */ + mte_suspend_exit(); } /* diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index 5f0c04863d2c..e4c0dadf0d92 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -123,6 +123,16 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, local_daif_restore(DAIF_PROCCTX); user_exit(); + if (system_supports_mte() && (flags & _TIF_MTE_ASYNC_FAULT)) { + /* + * Process the asynchronous tag check fault before the actual + * syscall. do_notify_resume() will send a signal to userspace + * before the syscall is restarted. + */ + regs->regs[0] = -ERESTARTNOINTR; + return; + } + if (has_syscall_work(flags)) { /* * The de-facto standard way to skip a system call using ptrace diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index 0801a0f3c156..543c67cae02f 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -36,21 +36,23 @@ void store_cpu_topology(unsigned int cpuid) if (mpidr & MPIDR_UP_BITMASK) return; - /* Create cpu topology mapping based on MPIDR. */ - if (mpidr & MPIDR_MT_BITMASK) { - /* Multiprocessor system : Multi-threads per core */ - cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); - cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1); - cpuid_topo->package_id = MPIDR_AFFINITY_LEVEL(mpidr, 2) | - MPIDR_AFFINITY_LEVEL(mpidr, 3) << 8; - } else { - /* Multiprocessor system : Single-thread per core */ - cpuid_topo->thread_id = -1; - cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); - cpuid_topo->package_id = MPIDR_AFFINITY_LEVEL(mpidr, 1) | - MPIDR_AFFINITY_LEVEL(mpidr, 2) << 8 | - MPIDR_AFFINITY_LEVEL(mpidr, 3) << 16; - } + /* + * This would be the place to create cpu topology based on MPIDR. + * + * However, it cannot be trusted to depict the actual topology; some + * pieces of the architecture enforce an artificial cap on Aff0 values + * (e.g. GICv3's ICC_SGI1R_EL1 limits it to 15), leading to an + * artificial cycling of Aff1, Aff2 and Aff3 values. IOW, these end up + * having absolutely no relationship to the actual underlying system + * topology, and cannot be reasonably used as core / package ID. + * + * If the MT bit is set, Aff0 *could* be used to define a thread ID, but + * we still wouldn't be able to obtain a sane core ID. This means we + * need to entirely ignore MPIDR for any topology deduction. + */ + cpuid_topo->thread_id = -1; + cpuid_topo->core_id = cpuid; + cpuid_topo->package_id = cpu_to_node(cpuid); pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n", cpuid, cpuid_topo->package_id, cpuid_topo->core_id, @@ -246,6 +248,13 @@ static int __init init_amu_fie(void) static_branch_enable(&amu_fie_key); } + /* + * If the system is not fully invariant after AMU init, disable + * partial use of counters for frequency invariance. + */ + if (!topology_scale_freq_invariant()) + static_branch_disable(&amu_fie_key); + free_valid_mask: free_cpumask_var(valid_cpus); @@ -253,7 +262,7 @@ free_valid_mask: } late_initcall_sync(init_amu_fie); -bool arch_freq_counters_available(struct cpumask *cpus) +bool arch_freq_counters_available(const struct cpumask *cpus) { return amu_freq_invariant() && cpumask_subset(cpus, amu_fie_cpus); diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 13ebd5ca2070..8af4e0e85736 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -34,6 +34,7 @@ #include <asm/daifflags.h> #include <asm/debug-monitors.h> #include <asm/esr.h> +#include <asm/extable.h> #include <asm/insn.h> #include <asm/kprobes.h> #include <asm/traps.h> @@ -53,11 +54,6 @@ static const char *handler[]= { int show_unhandled_signals = 0; -static void dump_backtrace_entry(unsigned long where, const char *loglvl) -{ - printk("%s %pS\n", loglvl, (void *)where); -} - static void dump_kernel_instr(const char *lvl, struct pt_regs *regs) { unsigned long addr = instruction_pointer(regs); @@ -83,66 +79,6 @@ static void dump_kernel_instr(const char *lvl, struct pt_regs *regs) printk("%sCode: %s\n", lvl, str); } -void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk, - const char *loglvl) -{ - struct stackframe frame; - int skip = 0; - - pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); - - if (regs) { - if (user_mode(regs)) - return; - skip = 1; - } - - if (!tsk) - tsk = current; - - if (!try_get_task_stack(tsk)) - return; - - if (tsk == current) { - start_backtrace(&frame, - (unsigned long)__builtin_frame_address(0), - (unsigned long)dump_backtrace); - } else { - /* - * task blocked in __switch_to - */ - start_backtrace(&frame, - thread_saved_fp(tsk), - thread_saved_pc(tsk)); - } - - printk("%sCall trace:\n", loglvl); - do { - /* skip until specified stack frame */ - if (!skip) { - dump_backtrace_entry(frame.pc, loglvl); - } else if (frame.fp == regs->regs[29]) { - skip = 0; - /* - * Mostly, this is the case where this function is - * called in panic/abort. As exception handler's - * stack frame does not contain the corresponding pc - * at which an exception has taken place, use regs->pc - * instead. - */ - dump_backtrace_entry(regs->pc, loglvl); - } - } while (!unwind_frame(tsk, &frame)); - - put_task_stack(tsk); -} - -void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl) -{ - dump_backtrace(NULL, tsk, loglvl); - barrier(); -} - #ifdef CONFIG_PREEMPT #define S_PREEMPT " PREEMPT" #elif defined(CONFIG_PREEMPT_RT) @@ -200,9 +136,9 @@ void die(const char *str, struct pt_regs *regs, int err) oops_exit(); if (in_interrupt()) - panic("Fatal exception in interrupt"); + panic("%s: Fatal exception in interrupt", str); if (panic_on_oops) - panic("Fatal exception"); + panic("%s: Fatal exception", str); raw_spin_unlock_irqrestore(&die_lock, flags); @@ -412,7 +348,7 @@ exit: return fn ? fn(regs, instr) : 1; } -void force_signal_inject(int signal, int code, unsigned long address) +void force_signal_inject(int signal, int code, unsigned long address, unsigned int err) { const char *desc; struct pt_regs *regs = current_pt_regs(); @@ -438,7 +374,7 @@ void force_signal_inject(int signal, int code, unsigned long address) signal = SIGKILL; } - arm64_notify_die(desc, regs, signal, code, (void __user *)address, 0); + arm64_notify_die(desc, regs, signal, code, (void __user *)address, err); } /* @@ -455,7 +391,7 @@ void arm64_notify_segfault(unsigned long addr) code = SEGV_ACCERR; mmap_read_unlock(current->mm); - force_signal_inject(SIGSEGV, code, addr); + force_signal_inject(SIGSEGV, code, addr, 0); } void do_undefinstr(struct pt_regs *regs) @@ -468,17 +404,28 @@ void do_undefinstr(struct pt_regs *regs) return; BUG_ON(!user_mode(regs)); - force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc); + force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0); } NOKPROBE_SYMBOL(do_undefinstr); void do_bti(struct pt_regs *regs) { BUG_ON(!user_mode(regs)); - force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc); + force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0); } NOKPROBE_SYMBOL(do_bti); +void do_ptrauth_fault(struct pt_regs *regs, unsigned int esr) +{ + /* + * Unexpected FPAC exception or pointer authentication failure in + * the kernel: kill the task before it does any more harm. + */ + BUG_ON(!user_mode(regs)); + force_signal_inject(SIGILL, ILL_ILLOPN, regs->pc, esr); +} +NOKPROBE_SYMBOL(do_ptrauth_fault); + #define __user_cache_maint(insn, address, res) \ if (address >= user_addr_max()) { \ res = -EFAULT; \ @@ -528,7 +475,7 @@ static void user_cache_maint_handler(unsigned int esr, struct pt_regs *regs) __user_cache_maint("ic ivau", address, ret); break; default: - force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc); + force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0); return; } @@ -581,7 +528,7 @@ static void mrs_handler(unsigned int esr, struct pt_regs *regs) sysreg = esr_sys64_to_sysreg(esr); if (do_emulate_mrs(regs, sysreg, rt) != 0) - force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc); + force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0); } static void wfi_handler(unsigned int esr, struct pt_regs *regs) @@ -775,6 +722,7 @@ static const char *esr_class_str[] = { [ESR_ELx_EC_SYS64] = "MSR/MRS (AArch64)", [ESR_ELx_EC_SVE] = "SVE", [ESR_ELx_EC_ERET] = "ERET/ERETAA/ERETAB", + [ESR_ELx_EC_FPAC] = "FPAC", [ESR_ELx_EC_IMP_DEF] = "EL3 IMP DEF", [ESR_ELx_EC_IABT_LOW] = "IABT (lower EL)", [ESR_ELx_EC_IABT_CUR] = "IABT (current EL)", @@ -935,26 +883,6 @@ asmlinkage void enter_from_user_mode(void) } NOKPROBE_SYMBOL(enter_from_user_mode); -void __pte_error(const char *file, int line, unsigned long val) -{ - pr_err("%s:%d: bad pte %016lx.\n", file, line, val); -} - -void __pmd_error(const char *file, int line, unsigned long val) -{ - pr_err("%s:%d: bad pmd %016lx.\n", file, line, val); -} - -void __pud_error(const char *file, int line, unsigned long val) -{ - pr_err("%s:%d: bad pud %016lx.\n", file, line, val); -} - -void __pgd_error(const char *file, int line, unsigned long val) -{ - pr_err("%s:%d: bad pgd %016lx.\n", file, line, val); -} - /* GENERIC_BUG traps */ int is_valid_bugaddr(unsigned long addr) @@ -994,6 +922,21 @@ static struct break_hook bug_break_hook = { .imm = BUG_BRK_IMM, }; +static int reserved_fault_handler(struct pt_regs *regs, unsigned int esr) +{ + pr_err("%s generated an invalid instruction at %pS!\n", + in_bpf_jit(regs) ? "BPF JIT" : "Kernel text patching", + (void *)instruction_pointer(regs)); + + /* We cannot handle this */ + return DBG_HOOK_ERROR; +} + +static struct break_hook fault_break_hook = { + .fn = reserved_fault_handler, + .imm = FAULT_BRK_IMM, +}; + #ifdef CONFIG_KASAN_SW_TAGS #define KASAN_ESR_RECOVER 0x20 @@ -1059,6 +1002,7 @@ int __init early_brk64(unsigned long addr, unsigned int esr, void __init trap_init(void) { register_kernel_break_hook(&bug_break_hook); + register_kernel_break_hook(&fault_break_hook); #ifdef CONFIG_KASAN_SW_TAGS register_kernel_break_hook(&kasan_break_hook); #endif diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index d4202a32abc9..debb8995d57f 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -30,15 +30,11 @@ #include <asm/vdso.h> extern char vdso_start[], vdso_end[]; -#ifdef CONFIG_COMPAT_VDSO extern char vdso32_start[], vdso32_end[]; -#endif /* CONFIG_COMPAT_VDSO */ enum vdso_abi { VDSO_ABI_AA64, -#ifdef CONFIG_COMPAT_VDSO VDSO_ABI_AA32, -#endif /* CONFIG_COMPAT_VDSO */ }; enum vvar_pages { @@ -284,21 +280,17 @@ up_fail: /* * Create and map the vectors page for AArch32 tasks. */ -#ifdef CONFIG_COMPAT_VDSO static int aarch32_vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *new_vma) { return __vdso_remap(VDSO_ABI_AA32, sm, new_vma); } -#endif /* CONFIG_COMPAT_VDSO */ enum aarch32_map { AA32_MAP_VECTORS, /* kuser helpers */ -#ifdef CONFIG_COMPAT_VDSO + AA32_MAP_SIGPAGE, AA32_MAP_VVAR, AA32_MAP_VDSO, -#endif - AA32_MAP_SIGPAGE }; static struct page *aarch32_vectors_page __ro_after_init; @@ -309,7 +301,10 @@ static struct vm_special_mapping aarch32_vdso_maps[] = { .name = "[vectors]", /* ABI */ .pages = &aarch32_vectors_page, }, -#ifdef CONFIG_COMPAT_VDSO + [AA32_MAP_SIGPAGE] = { + .name = "[sigpage]", /* ABI */ + .pages = &aarch32_sig_page, + }, [AA32_MAP_VVAR] = { .name = "[vvar]", .fault = vvar_fault, @@ -319,11 +314,6 @@ static struct vm_special_mapping aarch32_vdso_maps[] = { .name = "[vdso]", .mremap = aarch32_vdso_mremap, }, -#endif /* CONFIG_COMPAT_VDSO */ - [AA32_MAP_SIGPAGE] = { - .name = "[sigpage]", /* ABI */ - .pages = &aarch32_sig_page, - }, }; static int aarch32_alloc_kuser_vdso_page(void) @@ -362,25 +352,25 @@ static int aarch32_alloc_sigpage(void) return 0; } -#ifdef CONFIG_COMPAT_VDSO static int __aarch32_alloc_vdso_pages(void) { + + if (!IS_ENABLED(CONFIG_COMPAT_VDSO)) + return 0; + vdso_info[VDSO_ABI_AA32].dm = &aarch32_vdso_maps[AA32_MAP_VVAR]; vdso_info[VDSO_ABI_AA32].cm = &aarch32_vdso_maps[AA32_MAP_VDSO]; return __vdso_init(VDSO_ABI_AA32); } -#endif /* CONFIG_COMPAT_VDSO */ static int __init aarch32_alloc_vdso_pages(void) { int ret; -#ifdef CONFIG_COMPAT_VDSO ret = __aarch32_alloc_vdso_pages(); if (ret) return ret; -#endif ret = aarch32_alloc_sigpage(); if (ret) @@ -449,14 +439,12 @@ int aarch32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) if (ret) goto out; -#ifdef CONFIG_COMPAT_VDSO - ret = __setup_additional_pages(VDSO_ABI_AA32, - mm, - bprm, - uses_interp); - if (ret) - goto out; -#endif /* CONFIG_COMPAT_VDSO */ + if (IS_ENABLED(CONFIG_COMPAT_VDSO)) { + ret = __setup_additional_pages(VDSO_ABI_AA32, mm, bprm, + uses_interp); + if (ret) + goto out; + } ret = aarch32_sigreturn_setup(mm); out: @@ -497,8 +485,7 @@ static int __init vdso_init(void) } arch_initcall(vdso_init); -int arch_setup_additional_pages(struct linux_binprm *bprm, - int uses_interp) +int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) { struct mm_struct *mm = current->mm; int ret; @@ -506,11 +493,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, if (mmap_write_lock_killable(mm)) return -EINTR; - ret = __setup_additional_pages(VDSO_ABI_AA64, - mm, - bprm, - uses_interp); - + ret = __setup_additional_pages(VDSO_ABI_AA64, mm, bprm, uses_interp); mmap_write_unlock(mm); return ret; diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile index 45d5cfe46429..d65f52264aba 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile @@ -24,14 +24,13 @@ 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 -n \ + -Bsymbolic $(call ld-option, --no-eh-frame-hdr) --build-id=sha1 -n \ $(btildflags-y) -T ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18 ccflags-y += -DDISABLE_BRANCH_PROFILING CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) -KBUILD_CFLAGS += $(DISABLE_LTO) KASAN_SANITIZE := n UBSAN_SANITIZE := n OBJECT_FILES_NON_STANDARD := y @@ -43,18 +42,11 @@ ifneq ($(c-gettimeofday-y),) CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y) endif -# Clang versions less than 8 do not support -mcmodel=tiny -ifeq ($(CONFIG_CC_IS_CLANG), y) - ifeq ($(shell test $(CONFIG_CLANG_VERSION) -lt 80000; echo $$?),0) - CFLAGS_REMOVE_vgettimeofday.o += -mcmodel=tiny - endif -endif - # Disable gcov profiling for VDSO code GCOV_PROFILE := n obj-y += vdso.o -extra-y += vdso.lds +targets += vdso.lds CPPFLAGS_vdso.lds += -P -C -U$(ARCH) # Force dependency (incbin is bad) diff --git a/arch/arm64/kernel/vdso/gen_vdso_offsets.sh b/arch/arm64/kernel/vdso/gen_vdso_offsets.sh index 0664acaf61ff..8b806eacd0a6 100755 --- a/arch/arm64/kernel/vdso/gen_vdso_offsets.sh +++ b/arch/arm64/kernel/vdso/gen_vdso_offsets.sh @@ -8,7 +8,7 @@ # 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 +# Author: Will Deacon <will.deacon@arm.com> # LC_ALL=C diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile index d6adb4677c25..7f96a1a9f68c 100644 --- a/arch/arm64/kernel/vdso32/Makefile +++ b/arch/arm64/kernel/vdso32/Makefile @@ -90,9 +90,9 @@ VDSO_CFLAGS += -O2 # Some useful compiler-dependent flags from top-level Makefile VDSO_CFLAGS += $(call cc32-option,-Wdeclaration-after-statement,) VDSO_CFLAGS += $(call cc32-option,-Wno-pointer-sign) -VDSO_CFLAGS += $(call cc32-option,-fno-strict-overflow) +VDSO_CFLAGS += -fno-strict-overflow VDSO_CFLAGS += $(call cc32-option,-Werror=strict-prototypes) -VDSO_CFLAGS += $(call cc32-option,-Werror=date-time) +VDSO_CFLAGS += -Werror=date-time VDSO_CFLAGS += $(call cc32-option,-Werror=incompatible-pointer-types) # The 32-bit compiler does not provide 128-bit integers, which are used in @@ -128,7 +128,7 @@ VDSO_LDFLAGS += -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1 VDSO_LDFLAGS += -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 VDSO_LDFLAGS += -nostdlib -shared -mfloat-abi=soft VDSO_LDFLAGS += -Wl,--hash-style=sysv -VDSO_LDFLAGS += -Wl,--build-id +VDSO_LDFLAGS += -Wl,--build-id=sha1 VDSO_LDFLAGS += $(call cc32-ldoption,-fuse-ld=bfd) @@ -155,7 +155,7 @@ asm-obj-vdso := $(addprefix $(obj)/, $(asm-obj-vdso)) obj-vdso := $(c-obj-vdso) $(c-obj-vdso-gettimeofday) $(asm-obj-vdso) obj-y += vdso.o -extra-y += vdso.lds +targets += vdso.lds CPPFLAGS_vdso.lds += -P -C -U$(ARCH) # Force dependency (vdso.s includes vdso.so through incbin) diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index d52e6b5dbfd3..6d78c041fdf6 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -6,6 +6,7 @@ */ #define RO_EXCEPTION_TABLE_ALIGN 8 +#define RUNTIME_DISCARD_EXIT #include <asm-generic/vmlinux.lds.h> #include <asm/cache.h> @@ -108,16 +109,13 @@ SECTIONS * matching the same input section name. There is no documented * order of matching. */ + DISCARDS /DISCARD/ : { - EXIT_CALL - *(.discard) - *(.discard.*) *(.interp .dynamic) *(.dynsym .dynstr .hash .gnu.hash) - *(.eh_frame) } - . = KIMAGE_VADDR + TEXT_OFFSET; + . = KIMAGE_VADDR; .head.text : { _text = .; @@ -143,6 +141,14 @@ SECTIONS *(.got) /* Global offset table */ } + /* + * Make sure that the .got.plt is either completely empty or it + * contains only the lazy dispatch entries. + */ + .got.plt : { *(.got.plt) } + ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0x18, + "Unexpected GOT/PLT entries detected!") + . = ALIGN(SEGMENT_ALIGN); _etext = .; /* End of text section */ @@ -262,8 +268,22 @@ SECTIONS _end = .; STABS_DEBUG + DWARF_DEBUG + ELF_DETAILS HEAD_SYMBOLS + + /* + * Sections that should stay zero sized, which is safer to + * explicitly check instead of blindly discarding. + */ + .plt : { + *(.plt) *(.plt.*) *(.iplt) *(.igot) + } + ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!") + + .data.rel.ro : { *(.data.rel.ro) } + ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!") } #include "image-vars.h" @@ -287,4 +307,4 @@ ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) == PAGE_SIZE, /* * If padding is applied before .head.text, virt<->phys conversions will fail. */ -ASSERT(_text == (KIMAGE_VADDR + TEXT_OFFSET), "HEAD is misaligned") +ASSERT(_text == KIMAGE_VADDR, "HEAD is misaligned") diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h index eeac62b685a9..313a8fa3c721 100644 --- a/arch/arm64/kvm/hyp/include/hyp/switch.h +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h @@ -446,7 +446,7 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) kvm_vcpu_trap_get_fault_type(vcpu) == FSC_FAULT && kvm_vcpu_dabt_isvalid(vcpu) && !kvm_vcpu_abt_issea(vcpu) && - !kvm_vcpu_dabt_iss1tw(vcpu); + !kvm_vcpu_abt_iss1tw(vcpu); if (valid) { int ret = __vgic_v2_perform_cpuif_access(vcpu); diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c index ad212d8fa417..fbde89a2c6e8 100644 --- a/arch/arm64/kvm/hyp/nvhe/tlb.c +++ b/arch/arm64/kvm/hyp/nvhe/tlb.c @@ -31,7 +31,14 @@ static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu, isb(); } + /* + * __load_guest_stage2() includes an ISB only when the AT + * workaround is applied. Take care of the opposite condition, + * ensuring that we always have an ISB, but not two ISBs back + * to back. + */ __load_guest_stage2(mmu); + asm(ALTERNATIVE("isb", "nop", ARM64_WORKAROUND_SPECULATIVE_AT)); } static void __tlb_switch_to_host(struct tlb_inv_context *cxt) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index a109c5001827..1a01da9fdc99 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -759,7 +759,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, struct kvm_pgtable *pgt; write_fault = kvm_is_write_fault(vcpu); - exec_fault = kvm_vcpu_trap_is_iabt(vcpu); + exec_fault = kvm_vcpu_trap_is_exec_fault(vcpu); VM_BUG_ON(write_fault && exec_fault); if (fault_status == FSC_PERM && !write_fault && !exec_fault) { @@ -999,7 +999,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) goto out; } - if (kvm_vcpu_dabt_iss1tw(vcpu)) { + if (kvm_vcpu_abt_iss1tw(vcpu)) { kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu)); ret = 1; goto out_unlock; diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index ee13c5eecd3d..2ed5ef8f274b 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -284,6 +284,7 @@ void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu) for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) kvm_pmu_release_perf_event(&pmu->pmc[i]); + irq_work_sync(&vcpu->arch.pmu.overflow_work); } u64 kvm_pmu_valid_counter_mask(struct kvm_vcpu *vcpu) @@ -449,6 +450,22 @@ void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu) } /** + * When perf interrupt is an NMI, we cannot safely notify the vcpu corresponding + * to the event. + * This is why we need a callback to do it once outside of the NMI context. + */ +static void kvm_pmu_perf_overflow_notify_vcpu(struct irq_work *work) +{ + struct kvm_vcpu *vcpu; + struct kvm_pmu *pmu; + + pmu = container_of(work, struct kvm_pmu, overflow_work); + vcpu = kvm_pmc_to_vcpu(pmu->pmc); + + kvm_vcpu_kick(vcpu); +} + +/** * When the perf event overflows, set the overflow status and inform the vcpu. */ static void kvm_pmu_perf_overflow(struct perf_event *perf_event, @@ -480,7 +497,11 @@ static void kvm_pmu_perf_overflow(struct perf_event *perf_event, if (kvm_pmu_overflow_status(vcpu)) { kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu); - kvm_vcpu_kick(vcpu); + + if (!in_nmi()) + kvm_vcpu_kick(vcpu); + else + irq_work_queue(&vcpu->arch.pmu.overflow_work); } cpu_pmu->pmu.start(perf_event, PERF_EF_RELOAD); @@ -857,6 +878,9 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu) return ret; } + init_irq_work(&vcpu->arch.pmu.overflow_work, + kvm_pmu_perf_overflow_notify_vcpu); + vcpu->arch.pmu.created = true; return 0; } diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 436043cd327e..6d287eefd9f1 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1131,6 +1131,8 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, if (!(val & (0xfUL << ID_AA64PFR0_CSV2_SHIFT)) && arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED) val |= (1UL << ID_AA64PFR0_CSV2_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)) { val &= ~((0xfUL << ID_AA64ISAR1_APA_SHIFT) | (0xfUL << ID_AA64ISAR1_API_SHIFT) | @@ -1339,6 +1341,13 @@ static bool access_ccsidr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, return true; } +static bool access_mte_regs(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + kvm_inject_undefined(vcpu); + return false; +} + /* sys_reg_desc initialiser for known cpufeature ID registers */ #define ID_SANITISED(name) { \ SYS_DESC(SYS_##name), \ @@ -1505,6 +1514,10 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_SCTLR_EL1), access_vm_reg, reset_val, SCTLR_EL1, 0x00C50078 }, { SYS_DESC(SYS_ACTLR_EL1), access_actlr, reset_actlr, ACTLR_EL1 }, { SYS_DESC(SYS_CPACR_EL1), NULL, reset_val, CPACR_EL1, 0 }, + + { SYS_DESC(SYS_RGSR_EL1), access_mte_regs }, + { SYS_DESC(SYS_GCR_EL1), access_mte_regs }, + { SYS_DESC(SYS_ZCR_EL1), NULL, reset_val, ZCR_EL1, 0, .visibility = sve_visibility }, { SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 }, { SYS_DESC(SYS_TTBR1_EL1), access_vm_reg, reset_unknown, TTBR1_EL1 }, @@ -1529,6 +1542,9 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_ERXMISC0_EL1), trap_raz_wi }, { SYS_DESC(SYS_ERXMISC1_EL1), trap_raz_wi }, + { SYS_DESC(SYS_TFSR_EL1), access_mte_regs }, + { SYS_DESC(SYS_TFSRE0_EL1), access_mte_regs }, + { SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 }, { SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 }, diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c index 5c786b915cd3..52d6f24f65dc 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c @@ -1001,8 +1001,8 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg, bool allow_group1) raw_spin_lock_irqsave(&irq->irq_lock, flags); /* - * An access targetting Group0 SGIs can only generate - * those, while an access targetting Group1 SGIs can + * An access targeting Group0 SGIs can only generate + * those, while an access targeting Group1 SGIs can * generate interrupts of either group. */ if (!irq->group || allow_group1) { diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile index 2fc253466dbf..d31e1169d9b8 100644 --- a/arch/arm64/lib/Makefile +++ b/arch/arm64/lib/Makefile @@ -16,3 +16,5 @@ lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o obj-$(CONFIG_CRC32) += crc32.o obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o + +obj-$(CONFIG_ARM64_MTE) += mte.o diff --git a/arch/arm64/lib/mte.S b/arch/arm64/lib/mte.S new file mode 100644 index 000000000000..03ca6d8b8670 --- /dev/null +++ b/arch/arm64/lib/mte.S @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 ARM Ltd. + */ +#include <linux/linkage.h> + +#include <asm/alternative.h> +#include <asm/assembler.h> +#include <asm/mte.h> +#include <asm/page.h> +#include <asm/sysreg.h> + + .arch armv8.5-a+memtag + +/* + * multitag_transfer_size - set \reg to the block size that is accessed by the + * LDGM/STGM instructions. + */ + .macro multitag_transfer_size, reg, tmp + mrs_s \reg, SYS_GMID_EL1 + ubfx \reg, \reg, #SYS_GMID_EL1_BS_SHIFT, #SYS_GMID_EL1_BS_SIZE + mov \tmp, #4 + lsl \reg, \tmp, \reg + .endm + +/* + * Clear the tags in a page + * x0 - address of the page to be cleared + */ +SYM_FUNC_START(mte_clear_page_tags) + multitag_transfer_size x1, x2 +1: stgm xzr, [x0] + add x0, x0, x1 + tst x0, #(PAGE_SIZE - 1) + b.ne 1b + ret +SYM_FUNC_END(mte_clear_page_tags) + +/* + * Copy the tags from the source page to the destination one + * x0 - address of the destination page + * x1 - address of the source page + */ +SYM_FUNC_START(mte_copy_page_tags) + mov x2, x0 + mov x3, x1 + multitag_transfer_size x5, x6 +1: ldgm x4, [x3] + stgm x4, [x2] + add x2, x2, x5 + add x3, x3, x5 + tst x2, #(PAGE_SIZE - 1) + b.ne 1b + ret +SYM_FUNC_END(mte_copy_page_tags) + +/* + * Read tags from a user buffer (one tag per byte) and set the corresponding + * tags at the given kernel address. Used by PTRACE_POKEMTETAGS. + * x0 - kernel address (to) + * x1 - user buffer (from) + * x2 - number of tags/bytes (n) + * Returns: + * x0 - number of tags read/set + */ +SYM_FUNC_START(mte_copy_tags_from_user) + mov x3, x1 + cbz x2, 2f +1: + uao_user_alternative 2f, ldrb, ldtrb, w4, x1, 0 + lsl x4, x4, #MTE_TAG_SHIFT + stg x4, [x0], #MTE_GRANULE_SIZE + add x1, x1, #1 + subs x2, x2, #1 + b.ne 1b + + // exception handling and function return +2: sub x0, x1, x3 // update the number of tags set + ret +SYM_FUNC_END(mte_copy_tags_from_user) + +/* + * Get the tags from a kernel address range and write the tag values to the + * given user buffer (one tag per byte). Used by PTRACE_PEEKMTETAGS. + * x0 - user buffer (to) + * x1 - kernel address (from) + * x2 - number of tags/bytes (n) + * Returns: + * x0 - number of tags read/set + */ +SYM_FUNC_START(mte_copy_tags_to_user) + mov x3, x0 + cbz x2, 2f +1: + ldg x4, [x1] + ubfx x4, x4, #MTE_TAG_SHIFT, #MTE_TAG_SIZE + uao_user_alternative 2f, strb, sttrb, w4, x0, 0 + add x0, x0, #1 + add x1, x1, #MTE_GRANULE_SIZE + subs x2, x2, #1 + b.ne 1b + + // exception handling and function return +2: sub x0, x0, x3 // update the number of tags copied + ret +SYM_FUNC_END(mte_copy_tags_to_user) + +/* + * Save the tags in a page + * x0 - page address + * x1 - tag storage + */ +SYM_FUNC_START(mte_save_page_tags) + multitag_transfer_size x7, x5 +1: + mov x2, #0 +2: + ldgm x5, [x0] + orr x2, x2, x5 + add x0, x0, x7 + tst x0, #0xFF // 16 tag values fit in a register, + b.ne 2b // which is 16*16=256 bytes + + str x2, [x1], #8 + + tst x0, #(PAGE_SIZE - 1) + b.ne 1b + + ret +SYM_FUNC_END(mte_save_page_tags) + +/* + * Restore the tags in a page + * x0 - page address + * x1 - tag storage + */ +SYM_FUNC_START(mte_restore_page_tags) + multitag_transfer_size x7, x5 +1: + ldr x2, [x1], #8 +2: + stgm x2, [x0] + add x0, x0, x7 + tst x0, #0xFF + b.ne 2b + + tst x0, #(PAGE_SIZE - 1) + b.ne 1b + + ret +SYM_FUNC_END(mte_restore_page_tags) diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile index d91030f0ffee..5ead3c3de3b6 100644 --- a/arch/arm64/mm/Makefile +++ b/arch/arm64/mm/Makefile @@ -4,10 +4,11 @@ obj-y := dma-mapping.o extable.o fault.o init.o \ ioremap.o mmap.o pgd.o mmu.o \ context.o proc.o pageattr.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o -obj-$(CONFIG_PTDUMP_CORE) += dump.o +obj-$(CONFIG_PTDUMP_CORE) += ptdump.o obj-$(CONFIG_PTDUMP_DEBUGFS) += ptdump_debugfs.o obj-$(CONFIG_NUMA) += numa.o obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o +obj-$(CONFIG_ARM64_MTE) += mteswap.o KASAN_SANITIZE_physaddr.o += n obj-$(CONFIG_KASAN) += kasan_init.o diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c index 9b11c096a042..001737a8f309 100644 --- a/arch/arm64/mm/context.c +++ b/arch/arm64/mm/context.c @@ -27,6 +27,10 @@ static DEFINE_PER_CPU(atomic64_t, active_asids); static DEFINE_PER_CPU(u64, reserved_asids); static cpumask_t tlb_flush_pending; +static unsigned long max_pinned_asids; +static unsigned long nr_pinned_asids; +static unsigned long *pinned_asid_map; + #define ASID_MASK (~GENMASK(asid_bits - 1, 0)) #define ASID_FIRST_VERSION (1UL << asid_bits) @@ -72,7 +76,7 @@ void verify_cpu_asid_bits(void) } } -static void set_kpti_asid_bits(void) +static void set_kpti_asid_bits(unsigned long *map) { unsigned int len = BITS_TO_LONGS(NUM_USER_ASIDS) * sizeof(unsigned long); /* @@ -81,13 +85,15 @@ static void set_kpti_asid_bits(void) * is set, then the ASID will map only userspace. Thus * mark even as reserved for kernel. */ - memset(asid_map, 0xaa, len); + memset(map, 0xaa, len); } static void set_reserved_asid_bits(void) { - if (arm64_kernel_unmapped_at_el0()) - set_kpti_asid_bits(); + if (pinned_asid_map) + bitmap_copy(asid_map, pinned_asid_map, NUM_USER_ASIDS); + else if (arm64_kernel_unmapped_at_el0()) + set_kpti_asid_bits(asid_map); else bitmap_clear(asid_map, 0, NUM_USER_ASIDS); } @@ -166,6 +172,14 @@ static u64 new_context(struct mm_struct *mm) return newasid; /* + * If it is pinned, we can keep using it. Note that reserved + * takes priority, because even if it is also pinned, we need to + * update the generation into the reserved_asids. + */ + if (refcount_read(&mm->context.pinned)) + return newasid; + + /* * We had a valid ASID in a previous life, so try to re-use * it if possible. */ @@ -256,6 +270,71 @@ switch_mm_fastpath: cpu_switch_mm(mm->pgd, mm); } +unsigned long arm64_mm_context_get(struct mm_struct *mm) +{ + unsigned long flags; + u64 asid; + + if (!pinned_asid_map) + return 0; + + raw_spin_lock_irqsave(&cpu_asid_lock, flags); + + asid = atomic64_read(&mm->context.id); + + if (refcount_inc_not_zero(&mm->context.pinned)) + goto out_unlock; + + if (nr_pinned_asids >= max_pinned_asids) { + asid = 0; + goto out_unlock; + } + + if (!asid_gen_match(asid)) { + /* + * We went through one or more rollover since that ASID was + * used. Ensure that it is still valid, or generate a new one. + */ + asid = new_context(mm); + atomic64_set(&mm->context.id, asid); + } + + nr_pinned_asids++; + __set_bit(asid2idx(asid), pinned_asid_map); + refcount_set(&mm->context.pinned, 1); + +out_unlock: + raw_spin_unlock_irqrestore(&cpu_asid_lock, flags); + + asid &= ~ASID_MASK; + + /* Set the equivalent of USER_ASID_BIT */ + if (asid && arm64_kernel_unmapped_at_el0()) + asid |= 1; + + return asid; +} +EXPORT_SYMBOL_GPL(arm64_mm_context_get); + +void arm64_mm_context_put(struct mm_struct *mm) +{ + unsigned long flags; + u64 asid = atomic64_read(&mm->context.id); + + if (!pinned_asid_map) + return; + + raw_spin_lock_irqsave(&cpu_asid_lock, flags); + + if (refcount_dec_and_test(&mm->context.pinned)) { + __clear_bit(asid2idx(asid), pinned_asid_map); + nr_pinned_asids--; + } + + raw_spin_unlock_irqrestore(&cpu_asid_lock, flags); +} +EXPORT_SYMBOL_GPL(arm64_mm_context_put); + /* Errata workaround post TTBRx_EL1 update. */ asmlinkage void post_ttbr_update_workaround(void) { @@ -296,8 +375,11 @@ static int asids_update_limit(void) { unsigned long num_available_asids = NUM_USER_ASIDS; - if (arm64_kernel_unmapped_at_el0()) + if (arm64_kernel_unmapped_at_el0()) { num_available_asids /= 2; + if (pinned_asid_map) + set_kpti_asid_bits(pinned_asid_map); + } /* * Expect allocation after rollover to fail if we don't have at least * one more ASID than CPUs. ASID #0 is reserved for init_mm. @@ -305,6 +387,13 @@ static int asids_update_limit(void) WARN_ON(num_available_asids - 1 <= num_possible_cpus()); pr_info("ASID allocator initialised with %lu entries\n", num_available_asids); + + /* + * There must always be an ASID available after rollover. Ensure that, + * even if all CPUs have a reserved ASID and the maximum number of ASIDs + * are pinned, there still is at least one empty slot in the ASID map. + */ + max_pinned_asids = num_available_asids - num_possible_cpus() - 2; return 0; } arch_initcall(asids_update_limit); @@ -319,13 +408,17 @@ static int asids_init(void) panic("Failed to allocate bitmap for %lu ASIDs\n", NUM_USER_ASIDS); + pinned_asid_map = kcalloc(BITS_TO_LONGS(NUM_USER_ASIDS), + sizeof(*pinned_asid_map), GFP_KERNEL); + nr_pinned_asids = 0; + /* * We cannot call set_reserved_asid_bits() here because CPU * caps are not finalized yet, so it is safer to assume KPTI * and reserve kernel ASID's from beginning. */ if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) - set_kpti_asid_bits(); + set_kpti_asid_bits(asid_map); return 0; } early_initcall(asids_init); diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c index 2ee7b73433a5..70a71f38b6a9 100644 --- a/arch/arm64/mm/copypage.c +++ b/arch/arm64/mm/copypage.c @@ -6,21 +6,32 @@ * Copyright (C) 2012 ARM Ltd. */ +#include <linux/bitops.h> #include <linux/mm.h> #include <asm/page.h> #include <asm/cacheflush.h> +#include <asm/cpufeature.h> +#include <asm/mte.h> -void __cpu_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr) +void copy_highpage(struct page *to, struct page *from) { - struct page *page = virt_to_page(kto); + struct page *kto = page_address(to); + struct page *kfrom = page_address(from); + copy_page(kto, kfrom); - flush_dcache_page(page); + + if (system_supports_mte() && test_bit(PG_mte_tagged, &from->flags)) { + set_bit(PG_mte_tagged, &to->flags); + mte_copy_page_tags(kto, kfrom); + } } -EXPORT_SYMBOL_GPL(__cpu_copy_user_page); +EXPORT_SYMBOL(copy_highpage); -void __cpu_clear_user_page(void *kaddr, unsigned long vaddr) +void copy_user_highpage(struct page *to, struct page *from, + unsigned long vaddr, struct vm_area_struct *vma) { - clear_page(kaddr); + copy_highpage(to, from); + flush_dcache_page(to); } -EXPORT_SYMBOL_GPL(__cpu_clear_user_page); +EXPORT_SYMBOL_GPL(copy_user_highpage); diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 6c45350e33aa..93e87b287556 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -6,7 +6,7 @@ #include <linux/gfp.h> #include <linux/cache.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <linux/dma-iommu.h> #include <xen/xen.h> #include <xen/swiotlb-xen.h> diff --git a/arch/arm64/mm/extable.c b/arch/arm64/mm/extable.c index eee1732ab6cd..aa0060178343 100644 --- a/arch/arm64/mm/extable.c +++ b/arch/arm64/mm/extable.c @@ -14,9 +14,7 @@ int fixup_exception(struct pt_regs *regs) if (!fixup) return 0; - if (IS_ENABLED(CONFIG_BPF_JIT) && - regs->pc >= BPF_JIT_REGION_START && - regs->pc < BPF_JIT_REGION_END) + if (in_bpf_jit(regs)) return arm64_bpf_fixup_exception(fixup, regs); regs->pc = (unsigned long)&fixup->fixup + fixup->fixup; diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index f07333e86c2f..94c99c1c19e3 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -218,7 +218,9 @@ int ptep_set_access_flags(struct vm_area_struct *vma, pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval, pteval); } while (pteval != old_pteval); - flush_tlb_fix_spurious_fault(vma, address); + /* Invalidate a stale read-only entry */ + if (dirty) + flush_tlb_page(vma, address); return 1; } @@ -641,6 +643,13 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) return 0; } +static int do_tag_check_fault(unsigned long addr, unsigned int esr, + struct pt_regs *regs) +{ + do_bad_area(addr, esr, regs); + return 0; +} + static const struct fault_info fault_info[] = { { do_bad, SIGKILL, SI_KERNEL, "ttbr address size fault" }, { do_bad, SIGKILL, SI_KERNEL, "level 1 address size fault" }, @@ -659,7 +668,7 @@ static const struct fault_info fault_info[] = { { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" }, { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" }, { do_sea, SIGBUS, BUS_OBJERR, "synchronous external abort" }, - { do_bad, SIGKILL, SI_KERNEL, "unknown 17" }, + { do_tag_check_fault, SIGSEGV, SEGV_MTESERR, "synchronous tag check fault" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 18" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 19" }, { do_sea, SIGKILL, SI_KERNEL, "level 0 (translation table walk)" }, diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 481d22c32a2e..095540667f0f 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -21,8 +21,7 @@ #include <linux/of.h> #include <linux/of_fdt.h> #include <linux/dma-direct.h> -#include <linux/dma-mapping.h> -#include <linux/dma-contiguous.h> +#include <linux/dma-map-ops.h> #include <linux/efi.h> #include <linux/swiotlb.h> #include <linux/vmalloc.h> @@ -54,12 +53,6 @@ s64 memstart_addr __ro_after_init = -1; EXPORT_SYMBOL(memstart_addr); -s64 physvirt_offset __ro_after_init; -EXPORT_SYMBOL(physvirt_offset); - -struct page *vmemmap __ro_after_init; -EXPORT_SYMBOL(vmemmap); - /* * 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 @@ -290,20 +283,6 @@ void __init arm64_memblock_init(void) memstart_addr = round_down(memblock_start_of_DRAM(), ARM64_MEMSTART_ALIGN); - physvirt_offset = PHYS_OFFSET - PAGE_OFFSET; - - vmemmap = ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT)); - - /* - * If we are running with a 52-bit kernel VA config on a system that - * does not support it, we have to offset our vmemmap and physvirt_offset - * s.t. we avoid the 52-bit portion of the direct linear map - */ - if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52)) { - vmemmap += (_PAGE_OFFSET(48) - _PAGE_OFFSET(52)) >> PAGE_SHIFT; - physvirt_offset = PHYS_OFFSET - _PAGE_OFFSET(48); - } - /* * 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 @@ -319,6 +298,16 @@ void __init arm64_memblock_init(void) } /* + * If we are running with a 52-bit kernel VA config on a system that + * does not support it, we have to place the available physical + * memory in the 48-bit addressable part of the linear region, i.e., + * we have to move it upward. Since memstart_addr represents the + * physical address of PAGE_OFFSET, we have to *subtract* from it. + */ + if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52)) + memstart_addr -= _PAGE_OFFSET(48) - _PAGE_OFFSET(52); + + /* * Apply the memory limit if it was set. Since the kernel may be loaded * high up in memory, add back the kernel region that must be accessible * via the linear mapping. @@ -429,6 +418,8 @@ void __init bootmem_init(void) arm64_hugetlb_cma_reserve(); #endif + dma_pernuma_cma_reserve(); + /* * sparse_init() tries to allocate memory from memblock, so must be * done after the fixed reservations @@ -471,12 +462,10 @@ static inline void free_memmap(unsigned long start_pfn, unsigned long end_pfn) */ static void __init free_unused_memmap(void) { - unsigned long start, prev_end = 0; - struct memblock_region *reg; - - for_each_memblock(memory, reg) { - start = __phys_to_pfn(reg->base); + unsigned long start, end, prev_end = 0; + int i; + for_each_mem_pfn_range(i, MAX_NUMNODES, &start, &end, NULL) { #ifdef CONFIG_SPARSEMEM /* * Take care not to free memmap entries that don't exist due @@ -496,8 +485,7 @@ static void __init free_unused_memmap(void) * memmap entries are valid from the bank end aligned to * MAX_ORDER_NR_PAGES. */ - prev_end = ALIGN(__phys_to_pfn(reg->base + reg->size), - MAX_ORDER_NR_PAGES); + prev_end = ALIGN(end, MAX_ORDER_NR_PAGES); } #ifdef CONFIG_SPARSEMEM diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c index 7291b26ce788..b24e43d20667 100644 --- a/arch/arm64/mm/kasan_init.c +++ b/arch/arm64/mm/kasan_init.c @@ -212,8 +212,8 @@ void __init kasan_init(void) { u64 kimg_shadow_start, kimg_shadow_end; u64 mod_shadow_start, mod_shadow_end; - struct memblock_region *reg; - int i; + phys_addr_t pa_start, pa_end; + u64 i; kimg_shadow_start = (u64)kasan_mem_to_shadow(_text) & PAGE_MASK; kimg_shadow_end = PAGE_ALIGN((u64)kasan_mem_to_shadow(_end)); @@ -246,9 +246,9 @@ void __init kasan_init(void) kasan_populate_early_shadow((void *)mod_shadow_end, (void *)kimg_shadow_start); - for_each_memblock(memory, reg) { - void *start = (void *)__phys_to_virt(reg->base); - void *end = (void *)__phys_to_virt(reg->base + reg->size); + for_each_mem_range(i, &pa_start, &pa_end) { + void *start = (void *)__phys_to_virt(pa_start); + void *end = (void *)__phys_to_virt(pa_end); if (start >= end) break; diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 75df62fea1b6..1c0f3e02f731 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -122,7 +122,7 @@ static bool pgattr_change_is_safe(u64 old, u64 new) * The following mapping attributes may be updated in live * kernel mappings without the need for break-before-make. */ - static const pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG; + pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG; /* creating or taking down mappings is always safe */ if (old == 0 || new == 0) @@ -136,6 +136,17 @@ static bool pgattr_change_is_safe(u64 old, u64 new) if (old & ~new & PTE_NG) return false; + /* + * Changing the memory type between Normal and Normal-Tagged is safe + * since Tagged is considered a permission attribute from the + * mismatched attribute aliases perspective. + */ + if (((old & PTE_ATTRINDX_MASK) == PTE_ATTRINDX(MT_NORMAL) || + (old & PTE_ATTRINDX_MASK) == PTE_ATTRINDX(MT_NORMAL_TAGGED)) && + ((new & PTE_ATTRINDX_MASK) == PTE_ATTRINDX(MT_NORMAL) || + (new & PTE_ATTRINDX_MASK) == PTE_ATTRINDX(MT_NORMAL_TAGGED))) + mask |= PTE_ATTRINDX_MASK; + return ((old ^ new) & ~mask) == 0; } @@ -462,8 +473,9 @@ static void __init map_mem(pgd_t *pgdp) { phys_addr_t kernel_start = __pa_symbol(_text); phys_addr_t kernel_end = __pa_symbol(__init_begin); - struct memblock_region *reg; + phys_addr_t start, end; int flags = 0; + u64 i; if (rodata_full || debug_pagealloc_enabled()) flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; @@ -482,16 +494,15 @@ static void __init map_mem(pgd_t *pgdp) #endif /* map all the memory banks */ - for_each_memblock(memory, reg) { - phys_addr_t start = reg->base; - phys_addr_t end = start + reg->size; - + for_each_mem_range(i, &start, &end) { if (start >= end) break; - if (memblock_is_nomap(reg)) - continue; - - __map_memblock(pgdp, start, end, PAGE_KERNEL, flags); + /* + * The linear map must allow allocation tags reading/writing + * if MTE is present. Otherwise, it has the same attributes as + * PAGE_KERNEL. + */ + __map_memblock(pgdp, start, end, PAGE_KERNEL_TAGGED, flags); } /* diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c new file mode 100644 index 000000000000..c52c1847079c --- /dev/null +++ b/arch/arm64/mm/mteswap.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include <linux/pagemap.h> +#include <linux/xarray.h> +#include <linux/slab.h> +#include <linux/swap.h> +#include <linux/swapops.h> +#include <asm/mte.h> + +static DEFINE_XARRAY(mte_pages); + +void *mte_allocate_tag_storage(void) +{ + /* tags granule is 16 bytes, 2 tags stored per byte */ + return kmalloc(PAGE_SIZE / 16 / 2, GFP_KERNEL); +} + +void mte_free_tag_storage(char *storage) +{ + kfree(storage); +} + +int mte_save_tags(struct page *page) +{ + void *tag_storage, *ret; + + if (!test_bit(PG_mte_tagged, &page->flags)) + return 0; + + tag_storage = mte_allocate_tag_storage(); + if (!tag_storage) + return -ENOMEM; + + mte_save_page_tags(page_address(page), tag_storage); + + /* page_private contains the swap entry.val set in do_swap_page */ + ret = xa_store(&mte_pages, page_private(page), tag_storage, GFP_KERNEL); + if (WARN(xa_is_err(ret), "Failed to store MTE tags")) { + mte_free_tag_storage(tag_storage); + return xa_err(ret); + } else if (ret) { + /* Entry is being replaced, free the old entry */ + mte_free_tag_storage(ret); + } + + return 0; +} + +bool mte_restore_tags(swp_entry_t entry, struct page *page) +{ + void *tags = xa_load(&mte_pages, entry.val); + + if (!tags) + return false; + + mte_restore_page_tags(page_address(page), tags); + + return true; +} + +void mte_invalidate_tags(int type, pgoff_t offset) +{ + swp_entry_t entry = swp_entry(type, offset); + void *tags = xa_erase(&mte_pages, entry.val); + + mte_free_tag_storage(tags); +} + +void mte_invalidate_tags_area(int type) +{ + swp_entry_t entry = swp_entry(type, 0); + swp_entry_t last_entry = swp_entry(type + 1, 0); + void *tags; + + XA_STATE(xa_state, &mte_pages, entry.val); + + xa_lock(&mte_pages); + xas_for_each(&xa_state, tags, last_entry.val - 1) { + __xa_erase(&mte_pages, xa_state.xa_index); + mte_free_tag_storage(tags); + } + xa_unlock(&mte_pages); +} diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c index 73f8b49d485c..a8303bc6b62a 100644 --- a/arch/arm64/mm/numa.c +++ b/arch/arm64/mm/numa.c @@ -46,7 +46,11 @@ EXPORT_SYMBOL(node_to_cpumask_map); */ const struct cpumask *cpumask_of_node(int node) { - if (WARN_ON(node >= nr_node_ids)) + + if (node == NUMA_NO_NODE) + return cpu_all_mask; + + if (WARN_ON(node < 0 || node >= nr_node_ids)) return cpu_none_mask; if (WARN_ON(node_to_cpumask_map[node] == NULL)) @@ -350,7 +354,7 @@ static int __init numa_register_nodes(void) struct memblock_region *mblk; /* Check that valid nid is set to memblks */ - for_each_memblock(memory, mblk) { + for_each_mem_region(mblk) { int mblk_nid = memblock_get_region_node(mblk); if (mblk_nid == NUMA_NO_NODE || mblk_nid >= MAX_NUMNODES) { @@ -423,19 +427,16 @@ out_free_distance: */ static int __init dummy_numa_init(void) { + phys_addr_t start = memblock_start_of_DRAM(); + phys_addr_t end = memblock_end_of_DRAM(); int ret; - struct memblock_region *mblk; if (numa_off) pr_info("NUMA disabled\n"); /* Forced off on command line. */ - pr_info("Faking a node at [mem %#018Lx-%#018Lx]\n", - memblock_start_of_DRAM(), memblock_end_of_DRAM() - 1); - - for_each_memblock(memory, mblk) { - ret = numa_add_memblk(0, mblk->base, mblk->base + mblk->size); - if (!ret) - continue; + pr_info("Faking a node at [mem %#018Lx-%#018Lx]\n", start, end - 1); + ret = numa_add_memblk(0, start, end); + if (ret) { pr_err("NUMA init failed\n"); return ret; } @@ -448,7 +449,7 @@ static int __init dummy_numa_init(void) * arm64_numa_init() - Initialize NUMA * * Try each configured NUMA initialization method until one succeeds. The - * last fallback is dummy single node config encomapssing whole memory. + * last fallback is dummy single node config encompassing whole memory. */ void __init arm64_numa_init(void) { diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c index 23f648c2a199..1b94f5b82654 100644 --- a/arch/arm64/mm/pageattr.c +++ b/arch/arm64/mm/pageattr.c @@ -8,6 +8,7 @@ #include <linux/sched.h> #include <linux/vmalloc.h> +#include <asm/cacheflush.h> #include <asm/set_memory.h> #include <asm/tlbflush.h> diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 796e47a571e6..23c326a06b2d 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -18,6 +18,7 @@ #include <asm/cpufeature.h> #include <asm/alternative.h> #include <asm/smp.h> +#include <asm/sysreg.h> #ifdef CONFIG_ARM64_64K_PAGES #define TCR_TG_FLAGS TCR_TG0_64K | TCR_TG1_64K @@ -44,14 +45,18 @@ #define TCR_KASAN_FLAGS 0 #endif -/* Default MAIR_EL1 */ +/* + * Default MAIR_EL1. MT_NORMAL_TAGGED is initially mapped as Normal memory and + * changed during __cpu_setup to Normal Tagged if the system supports MTE. + */ #define MAIR_EL1_SET \ (MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRnE, MT_DEVICE_nGnRnE) | \ MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRE, MT_DEVICE_nGnRE) | \ MAIR_ATTRIDX(MAIR_ATTR_DEVICE_GRE, MT_DEVICE_GRE) | \ MAIR_ATTRIDX(MAIR_ATTR_NORMAL_NC, MT_NORMAL_NC) | \ MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL) | \ - MAIR_ATTRIDX(MAIR_ATTR_NORMAL_WT, MT_NORMAL_WT)) + MAIR_ATTRIDX(MAIR_ATTR_NORMAL_WT, MT_NORMAL_WT) | \ + MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL_TAGGED)) #ifdef CONFIG_CPU_PM /** @@ -421,6 +426,29 @@ SYM_FUNC_START(__cpu_setup) * Memory region attributes */ mov_q x5, MAIR_EL1_SET +#ifdef CONFIG_ARM64_MTE + /* + * Update MAIR_EL1, GCR_EL1 and TFSR*_EL1 if MTE is supported + * (ID_AA64PFR1_EL1[11:8] > 1). + */ + mrs x10, ID_AA64PFR1_EL1 + ubfx x10, x10, #ID_AA64PFR1_MTE_SHIFT, #4 + cmp x10, #ID_AA64PFR1_MTE + b.lt 1f + + /* Normal Tagged memory type at the corresponding MAIR index */ + mov x10, #MAIR_ATTR_NORMAL_TAGGED + bfi x5, x10, #(8 * MT_NORMAL_TAGGED), #8 + + /* initialize GCR_EL1: all non-zero tags excluded by default */ + mov x10, #(SYS_GCR_EL1_RRND | SYS_GCR_EL1_EXCL_MASK) + msr_s SYS_GCR_EL1, x10 + + /* clear any pending tag check faults in TFSR*_EL1 */ + msr_s SYS_TFSR_EL1, xzr + msr_s SYS_TFSRE0_EL1, xzr +1: +#endif msr mair_el1, x5 /* * Set/prepare TCR and TTBR. We use 512GB (39-bit) address range for diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/ptdump.c index 0b8da1cc1c07..807dc634bbd2 100644 --- a/arch/arm64/mm/dump.c +++ b/arch/arm64/mm/ptdump.c @@ -41,6 +41,8 @@ static struct addr_marker address_markers[] = { { 0 /* KASAN_SHADOW_START */, "Kasan shadow start" }, { KASAN_SHADOW_END, "Kasan shadow end" }, #endif + { BPF_JIT_REGION_START, "BPF start" }, + { BPF_JIT_REGION_END, "BPF end" }, { MODULES_VADDR, "Modules start" }, { MODULES_END, "Modules end" }, { VMALLOC_START, "vmalloc() area" }, @@ -169,6 +171,10 @@ static const struct prot_bits pte_bits[] = { .mask = PTE_ATTRINDX_MASK, .val = PTE_ATTRINDX(MT_NORMAL), .set = "MEM/NORMAL", + }, { + .mask = PTE_ATTRINDX_MASK, + .val = PTE_ATTRINDX(MT_NORMAL_TAGGED), + .set = "MEM/NORMAL-TAGGED", } }; diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index f8912e45be7a..ef9f1d5e989d 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -143,14 +143,17 @@ static inline void emit_addr_mov_i64(const int reg, const u64 val, } } -static inline int bpf2a64_offset(int bpf_to, int bpf_from, +static inline int bpf2a64_offset(int bpf_insn, int off, const struct jit_ctx *ctx) { - int to = ctx->offset[bpf_to]; - /* -1 to account for the Branch instruction */ - int from = ctx->offset[bpf_from] - 1; - - return to - from; + /* BPF JMP offset is relative to the next instruction */ + bpf_insn++; + /* + * Whereas arm64 branch instructions encode the offset + * from the branch itself, so we must subtract 1 from the + * instruction offset. + */ + return ctx->offset[bpf_insn + off] - (ctx->offset[bpf_insn] - 1); } static void jit_fill_hole(void *area, unsigned int size) @@ -642,7 +645,7 @@ emit_bswap_uxt: /* JUMP off */ case BPF_JMP | BPF_JA: - jmp_offset = bpf2a64_offset(i + off, i, ctx); + jmp_offset = bpf2a64_offset(i, off, ctx); check_imm26(jmp_offset); emit(A64_B(jmp_offset), ctx); break; @@ -669,7 +672,7 @@ emit_bswap_uxt: case BPF_JMP32 | BPF_JSLE | BPF_X: emit(A64_CMP(is64, dst, src), ctx); emit_cond_jmp: - jmp_offset = bpf2a64_offset(i + off, i, ctx); + jmp_offset = bpf2a64_offset(i, off, ctx); check_imm19(jmp_offset); switch (BPF_OP(code)) { case BPF_JEQ: @@ -908,10 +911,21 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass) const struct bpf_prog *prog = ctx->prog; int i; + /* + * - offset[0] offset of the end of prologue, + * start of the 1st instruction. + * - offset[1] - offset of the end of 1st instruction, + * start of the 2nd instruction + * [....] + * - offset[3] - offset of the end of 3rd instruction, + * start of 4th instruction + */ for (i = 0; i < prog->len; i++) { const struct bpf_insn *insn = &prog->insnsi[i]; int ret; + if (ctx->image == NULL) + ctx->offset[i] = ctx->idx; ret = build_insn(insn, ctx, extra_pass); if (ret > 0) { i++; @@ -919,11 +933,16 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass) ctx->offset[i] = ctx->idx; continue; } - if (ctx->image == NULL) - ctx->offset[i] = ctx->idx; if (ret) return ret; } + /* + * offset is allocated with prog->len + 1 so fill in + * the last element with the offset after the last + * instruction (end of program) + */ + if (ctx->image == NULL) + ctx->offset[i] = ctx->idx; return 0; } @@ -1002,7 +1021,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) memset(&ctx, 0, sizeof(ctx)); ctx.prog = prog; - ctx.offset = kcalloc(prog->len, sizeof(int), GFP_KERNEL); + ctx.offset = kcalloc(prog->len + 1, sizeof(int), GFP_KERNEL); if (ctx.offset == NULL) { prog = orig_prog; goto out_off; @@ -1089,7 +1108,7 @@ skip_init_ctx: prog->jited_len = prog_size; if (!prog->is_func || extra_pass) { - bpf_prog_fill_jited_linfo(prog, ctx.offset); + bpf_prog_fill_jited_linfo(prog, ctx.offset + 1); out_off: kfree(ctx.offset); kfree(jit_data); diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig index 6444ebfd06a6..48d66bf0465d 100644 --- a/arch/c6x/Kconfig +++ b/arch/c6x/Kconfig @@ -22,6 +22,7 @@ config C6X select GENERIC_CLOCKEVENTS select MODULES_USE_ELF_RELA select MMU_GATHER_NO_RANGE if MMU + select SET_FS config MMU def_bool n diff --git a/arch/c6x/include/asm/checksum.h b/arch/c6x/include/asm/checksum.h index 36770b8308d9..934918def632 100644 --- a/arch/c6x/include/asm/checksum.h +++ b/arch/c6x/include/asm/checksum.h @@ -26,6 +26,9 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, } #define csum_tcpudp_nofold csum_tcpudp_nofold +#define _HAVE_ARCH_CSUM_AND_COPY +extern __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len); + #include <asm-generic/checksum.h> #endif /* _ASM_C6X_CHECKSUM_H */ diff --git a/arch/c6x/kernel/setup.c b/arch/c6x/kernel/setup.c index 8ef35131f999..9254c3b794a5 100644 --- a/arch/c6x/kernel/setup.c +++ b/arch/c6x/kernel/setup.c @@ -287,7 +287,8 @@ notrace void __init machine_init(unsigned long dt_ptr) void __init setup_arch(char **cmdline_p) { - struct memblock_region *reg; + phys_addr_t start, end; + u64 i; printk(KERN_INFO "Initializing kernel\n"); @@ -351,9 +352,9 @@ void __init setup_arch(char **cmdline_p) disable_caching(ram_start, ram_end - 1); /* Set caching of external RAM used by Linux */ - for_each_memblock(memory, reg) - enable_caching(CACHE_REGION_START(reg->base), - CACHE_REGION_START(reg->base + reg->size - 1)); + for_each_mem_range(i, &start, &end) + enable_caching(CACHE_REGION_START(start), + CACHE_REGION_START(end - 1)); #ifdef CONFIG_BLK_DEV_INITRD /* diff --git a/arch/c6x/kernel/signal.c b/arch/c6x/kernel/signal.c index d05c78eace1b..a3f15b9a79da 100644 --- a/arch/c6x/kernel/signal.c +++ b/arch/c6x/kernel/signal.c @@ -316,8 +316,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags, if (thread_info_flags & (1 << TIF_SIGPENDING)) do_signal(regs, syscall); - if (thread_info_flags & (1 << TIF_NOTIFY_RESUME)) { - clear_thread_flag(TIF_NOTIFY_RESUME); + if (thread_info_flags & (1 << TIF_NOTIFY_RESUME)) tracehook_notify_resume(regs); - } } diff --git a/arch/c6x/lib/csum_64plus.S b/arch/c6x/lib/csum_64plus.S index 9c07127485d1..57148866d8d3 100644 --- a/arch/c6x/lib/csum_64plus.S +++ b/arch/c6x/lib/csum_64plus.S @@ -24,7 +24,6 @@ ENTRY(csum_partial_copy_nocheck) MVC .S2 ILC,B30 - MV .D1X B6,A31 ; given csum ZERO .D1 A9 ; csum (a side) || ZERO .D2 B9 ; csum (b side) || SHRU .S2X A6,2,B5 ; len / 4 @@ -144,8 +143,7 @@ L91: SHRU .S2X A9,16,B4 SHRU .S1 A9,16,A0 [A0] BNOP .S1 L91,5 -L10: ADD .D1 A31,A9,A9 - MV .D1 A9,A4 +L10: MV .D1 A9,A4 BNOP .S2 B3,4 MVC .S2 B30,ILC diff --git a/arch/c6x/mm/dma-coherent.c b/arch/c6x/mm/dma-coherent.c index a5909091cb14..03df07a831fc 100644 --- a/arch/c6x/mm/dma-coherent.c +++ b/arch/c6x/mm/dma-coherent.c @@ -15,7 +15,7 @@ #include <linux/bitops.h> #include <linux/module.h> #include <linux/interrupt.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <linux/memblock.h> #include <asm/cacheflush.h> diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index 3d5afb5f5685..268fad5f51cf 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -78,6 +78,7 @@ config CSKY select PCI_DOMAINS_GENERIC if PCI select PCI_SYSCALL if PCI select PCI_MSI if PCI + select SET_FS config LOCKDEP_SUPPORT def_bool y @@ -309,16 +310,3 @@ endmenu source "arch/csky/Kconfig.platforms" source "kernel/Kconfig.hz" - -config SECCOMP - bool "Enable seccomp to safely compute untrusted bytecode" - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via prctl(PR_SET_SECCOMP), it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. diff --git a/arch/csky/include/asm/tcm.h b/arch/csky/include/asm/tcm.h index 2b135cefb73f..bd1e662ecdfa 100644 --- a/arch/csky/include/asm/tcm.h +++ b/arch/csky/include/asm/tcm.h @@ -10,13 +10,13 @@ #include <linux/compiler.h> /* Tag variables with this */ -#define __tcmdata __section(.tcm.data) +#define __tcmdata __section(".tcm.data") /* Tag constants with this */ -#define __tcmconst __section(.tcm.rodata) +#define __tcmconst __section(".tcm.rodata") /* Tag functions inside TCM called from outside TCM with this */ -#define __tcmfunc __section(.tcm.text) noinline +#define __tcmfunc __section(".tcm.text") noinline /* Tag function inside TCM called from inside TCM with this */ -#define __tcmlocalfunc __section(.tcm.text) +#define __tcmlocalfunc __section(".tcm.text") void *tcm_alloc(size_t len); void tcm_free(void *addr, size_t len); diff --git a/arch/csky/kernel/probes/kprobes.c b/arch/csky/kernel/probes/kprobes.c index f0f733b7ac5a..589f090f48b9 100644 --- a/arch/csky/kernel/probes/kprobes.c +++ b/arch/csky/kernel/probes/kprobes.c @@ -404,87 +404,14 @@ int __init arch_populate_kprobe_blacklist(void) void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *tmp; - unsigned long flags, orig_ret_address = 0; - unsigned long trampoline_address = - (unsigned long)&kretprobe_trampoline; - kprobe_opcode_t *correct_ret_addr = NULL; - - INIT_HLIST_HEAD(&empty_rp); - kretprobe_hash_lock(current, &head, &flags); - - /* - * It is possible to have multiple instances associated with a given - * task either because multiple functions in the call path have - * return probes installed on them, and/or more than one - * return probe was registered for a target function. - * - * We can handle this because: - * - instances are always pushed into the head of the list - * - when multiple return probes are registered for the same - * function, the (chronologically) first instance's ret_addr - * will be the real return address, and all the rest will - * point to kretprobe_trampoline. - */ - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - orig_ret_address = (unsigned long)ri->ret_addr; - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_assert(ri, orig_ret_address, trampoline_address); - - correct_ret_addr = ri->ret_addr; - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - orig_ret_address = (unsigned long)ri->ret_addr; - if (ri->rp && ri->rp->handler) { - __this_cpu_write(current_kprobe, &ri->rp->kp); - get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; - ri->ret_addr = correct_ret_addr; - ri->rp->handler(ri, regs); - __this_cpu_write(current_kprobe, NULL); - } - - recycle_rp_inst(ri, &empty_rp); - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_hash_unlock(current, &flags); - - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } - return (void *)orig_ret_address; + return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); } void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) { ri->ret_addr = (kprobe_opcode_t *)regs->lr; + ri->fp = NULL; regs->lr = (unsigned long) &kretprobe_trampoline; } diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c index 0481f4e34538..e4cab16056d6 100644 --- a/arch/csky/kernel/setup.c +++ b/arch/csky/kernel/setup.c @@ -7,7 +7,7 @@ #include <linux/of.h> #include <linux/of_fdt.h> #include <linux/start_kernel.h> -#include <linux/dma-contiguous.h> +#include <linux/dma-map-ops.h> #include <linux/screen_info.h> #include <asm/sections.h> #include <asm/mmu_context.h> diff --git a/arch/csky/kernel/signal.c b/arch/csky/kernel/signal.c index 970895df75ec..8b068cf37447 100644 --- a/arch/csky/kernel/signal.c +++ b/arch/csky/kernel/signal.c @@ -261,7 +261,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, do_signal(regs); if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); rseq_handle_notify_resume(NULL, regs); } diff --git a/arch/csky/kernel/vmlinux.lds.S b/arch/csky/kernel/vmlinux.lds.S index f05b413df328..f03033e17c29 100644 --- a/arch/csky/kernel/vmlinux.lds.S +++ b/arch/csky/kernel/vmlinux.lds.S @@ -109,6 +109,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + ELF_DETAILS DISCARDS } diff --git a/arch/csky/mm/dma-mapping.c b/arch/csky/mm/dma-mapping.c index 8f6571ae27c8..c3a775a7e8f9 100644 --- a/arch/csky/mm/dma-mapping.c +++ b/arch/csky/mm/dma-mapping.c @@ -2,9 +2,7 @@ // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. #include <linux/cache.h> -#include <linux/dma-mapping.h> -#include <linux/dma-contiguous.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <linux/genalloc.h> #include <linux/highmem.h> #include <linux/io.h> diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index d11666d538fe..7945de067e9f 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -25,6 +25,7 @@ config H8300 select HAVE_ARCH_KGDB select HAVE_ARCH_HASH select CPU_NO_EFFICIENT_FFS + select SET_FS select UACCESS_MEMCPY config CPU_BIG_ENDIAN diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index 83ce3caf7313..aea0a40b77a9 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c @@ -172,5 +172,5 @@ asmlinkage int sys_clone(unsigned long __user *args) kargs.exit_signal = (lower_32_bits(clone_flags) & CSIGNAL); kargs.stack = newsp; - return _do_fork(&kargs); + return kernel_clone(&kargs); } diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c index 28ac88358a89..0281f92eea3d 100644 --- a/arch/h8300/kernel/setup.c +++ b/arch/h8300/kernel/setup.c @@ -74,17 +74,15 @@ static void __init bootmem_init(void) memory_end = memory_start = 0; /* Find main memory where is the kernel */ - for_each_memblock(memory, region) { - memory_start = region->base; - memory_end = region->base + region->size; - } + memory_start = memblock_start_of_DRAM(); + memory_end = memblock_end_of_DRAM(); if (!memory_end) panic("No memory!"); /* setup bootmem globals (we use no_bootmem, but mm still depends on this) */ min_low_pfn = PFN_UP(memory_start); - max_low_pfn = PFN_DOWN(memblock_end_of_DRAM()); + max_low_pfn = PFN_DOWN(memory_end); max_pfn = max_low_pfn; memblock_reserve(__pa(_stext), _end - _stext); diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c index 69e68949787f..75d9b7e626b2 100644 --- a/arch/h8300/kernel/signal.c +++ b/arch/h8300/kernel/signal.c @@ -282,8 +282,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs); - if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); + if (thread_info_flags & _TIF_NOTIFY_RESUME) tracehook_notify_resume(regs); - } } diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index 667cfc511cf9..f2afabbadd43 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -31,6 +31,7 @@ config HEXAGON select GENERIC_CLOCKEVENTS_BROADCAST select MODULES_USE_ELF_RELA select GENERIC_CPU_DEVICES + select SET_FS help Qualcomm Hexagon is a processor architecture designed for high performance and low power across a wide variety of applications. diff --git a/arch/hexagon/include/asm/checksum.h b/arch/hexagon/include/asm/checksum.h index a5c42f4614c1..4bc6ad96c4c5 100644 --- a/arch/hexagon/include/asm/checksum.h +++ b/arch/hexagon/include/asm/checksum.h @@ -10,17 +10,6 @@ unsigned int do_csum(const void *voidptr, int len); /* - * the same as csum_partial, but copies from src while it - * checksums - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ -#define csum_partial_copy_nocheck csum_partial_copy_nocheck -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum); - -/* * computes the checksum of the TCP/UDP pseudo-header * returns a 16-bit checksum, already complemented */ diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c index 25f388d9cfcc..00b9a81075dd 100644 --- a/arch/hexagon/kernel/dma.c +++ b/arch/hexagon/kernel/dma.c @@ -5,7 +5,7 @@ * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. */ -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <linux/memblock.h> #include <linux/genalloc.h> #include <linux/module.h> diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c index dfd322c5ce83..5a0a95d93ddb 100644 --- a/arch/hexagon/kernel/process.c +++ b/arch/hexagon/kernel/process.c @@ -180,7 +180,6 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) } if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); return 1; } diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S index 0ca2471ddb9f..35b18e55eae8 100644 --- a/arch/hexagon/kernel/vmlinux.lds.S +++ b/arch/hexagon/kernel/vmlinux.lds.S @@ -67,5 +67,6 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + ELF_DETAILS } diff --git a/arch/hexagon/lib/checksum.c b/arch/hexagon/lib/checksum.c index c4a6b72d97de..ba50822a0800 100644 --- a/arch/hexagon/lib/checksum.c +++ b/arch/hexagon/lib/checksum.c @@ -176,14 +176,3 @@ unsigned int do_csum(const void *voidptr, int len) return 0xFFFF & sum0; } - -/* - * copy from ds while checksumming, otherwise like csum_partial - */ -__wsum -csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) -{ - memcpy(dst, src, len); - return csum_partial(dst, len, sum); -} -EXPORT_SYMBOL(csum_partial_copy_nocheck); diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 5b4ec80bf586..39b25a5a591b 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -8,6 +8,7 @@ menu "Processor type and features" config IA64 bool + select ARCH_HAS_DMA_MARK_CLEAN select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO select ACPI @@ -32,8 +33,6 @@ config IA64 select TTY select HAVE_ARCH_TRACEHOOK select HAVE_VIRT_CPU_ACCOUNTING - select DMA_NONCOHERENT_MMAP - select ARCH_HAS_SYNC_DMA_FOR_CPU select VIRT_TO_BUS select GENERIC_IRQ_PROBE select GENERIC_PENDING_IRQ if SMP @@ -56,6 +55,8 @@ config IA64 select NEED_DMA_MAP_STATE select NEED_SG_DMA_LENGTH select NUMA if !FLATMEM + select PCI_MSI_ARCH_FALLBACKS if PCI_MSI + select SET_FS default y help The Itanium Processor Family is Intel's 64-bit successor to @@ -362,15 +363,6 @@ config ARCH_PROC_KCORE_TEXT config IA64_MCA_RECOVERY tristate "MCA recovery from errors other than TLB." -config PERFMON - bool "Performance monitor support" - depends on BROKEN - help - Selects whether support for the IA-64 performance monitor hardware - is included in the kernel. This makes some kernel data-structures a - little bigger and slows down execution a bit, but it is generally - a good idea to turn this on. If you're unsure, say Y. - config IA64_PALINFO tristate "/proc/pal support" help diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 2876a7df1b0a..703b1c4f6d12 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -20,7 +20,6 @@ CHECKFLAGS += -D__ia64=1 -D__ia64__=1 -D_LP64 -D__LP64__ OBJCOPYFLAGS := --strip-all LDFLAGS_vmlinux := -static -KBUILD_LDS_MODULE += $(srctree)/arch/ia64/module.lds KBUILD_AFLAGS_KERNEL := -mconstant-gp EXTRA := diff --git a/arch/ia64/configs/bigsur_defconfig b/arch/ia64/configs/bigsur_defconfig index f3ba813a5b80..cfed5ed89301 100644 --- a/arch/ia64/configs/bigsur_defconfig +++ b/arch/ia64/configs/bigsur_defconfig @@ -11,7 +11,6 @@ CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_PREEMPT=y # CONFIG_VIRTUAL_MEM_MAP is not set -CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y CONFIG_EFI_VARS=y CONFIG_BINFMT_MISC=m @@ -27,10 +26,9 @@ CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=m -CONFIG_IDE=m -CONFIG_BLK_DEV_IDECD=m -CONFIG_BLK_DEV_GENERIC=m -CONFIG_BLK_DEV_PIIX=m +CONFIG_ATA=m +CONFIG_ATA_GENERIC=m +CONFIG_ATA_PIIX=m CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SCSI_CONSTANTS=y diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig index cb267a07c57f..ca0d596c800d 100644 --- a/arch/ia64/configs/generic_defconfig +++ b/arch/ia64/configs/generic_defconfig @@ -18,7 +18,6 @@ CONFIG_IA64_CYCLONE=y CONFIG_SMP=y CONFIG_HOTPLUG_CPU=y CONFIG_IA64_MCA_RECOVERY=y -CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y CONFIG_KEXEC=y CONFIG_CRASH_DUMP=y @@ -45,11 +44,10 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_SGI_XP=m -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_CMD64X=y -CONFIG_BLK_DEV_PIIX=y +CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_CMD64X=y +CONFIG_ATA_PIIX=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=m diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig index 7e25f2f031b6..281eb9c544f9 100644 --- a/arch/ia64/configs/gensparse_defconfig +++ b/arch/ia64/configs/gensparse_defconfig @@ -17,7 +17,6 @@ CONFIG_NR_CPUS=512 CONFIG_HOTPLUG_CPU=y CONFIG_SPARSEMEM_MANUAL=y CONFIG_IA64_MCA_RECOVERY=y -CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y CONFIG_EFI_VARS=y CONFIG_BINFMT_MISC=m @@ -36,12 +35,11 @@ CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y +CONFIG_ATA=y CONFIG_BLK_DEV_IDECD=y -CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_CMD64X=y -CONFIG_BLK_DEV_PIIX=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_CMD64X=y +CONFIG_ATA_PIIX=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig index 3f486d5bdc2d..b4f9819a1a45 100644 --- a/arch/ia64/configs/tiger_defconfig +++ b/arch/ia64/configs/tiger_defconfig @@ -21,7 +21,6 @@ CONFIG_HOTPLUG_CPU=y CONFIG_PERMIT_BSP_REMOVE=y CONFIG_FORCE_CPEI_RETARGET=y CONFIG_IA64_MCA_RECOVERY=y -CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y CONFIG_KEXEC=y CONFIG_EFI_VARS=y @@ -41,11 +40,10 @@ CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_CMD64X=y -CONFIG_BLK_DEV_PIIX=y +CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_CMD64X=y +CONFIG_ATA_PIIX=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig index 261e98e1f5fe..629cb9cdf723 100644 --- a/arch/ia64/configs/zx1_defconfig +++ b/arch/ia64/configs/zx1_defconfig @@ -10,7 +10,6 @@ CONFIG_NR_CPUS=16 CONFIG_HOTPLUG_CPU=y CONFIG_FLATMEM_MANUAL=y CONFIG_IA64_MCA_RECOVERY=y -CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y CONFIG_CRASH_DUMP=y CONFIG_EFI_VARS=y @@ -26,10 +25,9 @@ CONFIG_IP_MULTICAST=y CONFIG_NETFILTER=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_CMD64X=y +CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_CMD64X=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 656a4888c300..9148ddbf02e5 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -33,7 +33,7 @@ #include <linux/bitops.h> /* hweight64() */ #include <linux/crash_dump.h> #include <linux/iommu-helper.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/prefetch.h> #include <linux/swiotlb.h> @@ -485,8 +485,7 @@ sba_search_bitmap(struct ioc *ioc, struct device *dev, ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0); ASSERT(res_ptr < res_end); - boundary_size = (unsigned long long)dma_get_seg_boundary(dev) + 1; - boundary_size = ALIGN(boundary_size, 1ULL << iovp_shift) >> iovp_shift; + boundary_size = dma_get_seg_boundary_nr_pages(dev, iovp_shift); BUG_ON(ioc->ibase & ~iovp_mask); shift = ioc->ibase >> iovp_shift; @@ -2071,6 +2070,8 @@ static const struct dma_map_ops sba_dma_ops = { .dma_supported = sba_dma_supported, .mmap = dma_common_mmap, .get_sgtable = dma_common_get_sgtable, + .alloc_pages = dma_common_alloc_pages, + .free_pages = dma_common_free_pages, }; static int __init diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index b66ba907019c..87927eb824cc 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h @@ -74,8 +74,6 @@ static inline void arch_acpi_set_pdc_bits(u32 *buf) buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; } -#define acpi_unlazy_tlb(x) - #ifdef CONFIG_ACPI_NUMA extern cpumask_t early_cpu_possible_map; #define for_each_possible_early_cpu(cpu) \ diff --git a/arch/ia64/include/asm/cache.h b/arch/ia64/include/asm/cache.h index 4eb6f742d14f..2f1c70647068 100644 --- a/arch/ia64/include/asm/cache.h +++ b/arch/ia64/include/asm/cache.h @@ -25,6 +25,6 @@ # define SMP_CACHE_BYTES (1 << 3) #endif -#define __read_mostly __attribute__((__section__(".data..read_mostly"))) +#define __read_mostly __section(".data..read_mostly") #endif /* _ASM_IA64_CACHE_H */ diff --git a/arch/ia64/include/asm/checksum.h b/arch/ia64/include/asm/checksum.h index 2a1c64629cdc..f3026213aa32 100644 --- a/arch/ia64/include/asm/checksum.h +++ b/arch/ia64/include/asm/checksum.h @@ -37,9 +37,6 @@ extern __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, */ extern __wsum csum_partial(const void *buff, int len, __wsum sum); -extern __wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum); - /* * This routine is used for miscellaneous IP-like checksums, mainly in * icmp.c diff --git a/arch/ia64/module.lds b/arch/ia64/include/asm/module.lds.h index eff68f362793..eff68f362793 100644 --- a/arch/ia64/module.lds +++ b/arch/ia64/include/asm/module.lds.h diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h index 95a2ec37400f..2d8bcdc27d7f 100644 --- a/arch/ia64/include/asm/processor.h +++ b/arch/ia64/include/asm/processor.h @@ -280,15 +280,6 @@ struct thread_struct { __u64 map_base; /* base address for get_unmapped_area() */ __u64 rbs_bot; /* the base address for the RBS */ int last_fph_cpu; /* CPU that may hold the contents of f32-f127 */ - -#ifdef CONFIG_PERFMON - void *pfm_context; /* pointer to detailed PMU context */ - unsigned long pfm_needs_checking; /* when >0, pending perfmon work on kernel exit */ -# define INIT_THREAD_PM .pfm_context = NULL, \ - .pfm_needs_checking = 0UL, -#else -# define INIT_THREAD_PM -#endif unsigned long dbr[IA64_NUM_DBG_REGS]; unsigned long ibr[IA64_NUM_DBG_REGS]; struct ia64_fpreg fph[96]; /* saved/loaded on demand */ @@ -301,7 +292,6 @@ struct thread_struct { .map_base = DEFAULT_MAP_BASE, \ .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \ .last_fph_cpu = -1, \ - INIT_THREAD_PM \ .dbr = {0, }, \ .ibr = {0, }, \ .fph = {{{{0}}}, } \ diff --git a/arch/ia64/include/asm/switch_to.h b/arch/ia64/include/asm/switch_to.h index 9011e90a6b97..a5a4e09468fa 100644 --- a/arch/ia64/include/asm/switch_to.h +++ b/arch/ia64/include/asm/switch_to.h @@ -31,16 +31,8 @@ extern struct task_struct *ia64_switch_to (void *next_task); extern void ia64_save_extra (struct task_struct *task); extern void ia64_load_extra (struct task_struct *task); -#ifdef CONFIG_PERFMON - DECLARE_PER_CPU(unsigned long, pfm_syst_info); -# define PERFMON_IS_SYSWIDE() (__this_cpu_read(pfm_syst_info) & 0x1) -#else -# define PERFMON_IS_SYSWIDE() (0) -#endif - #define IA64_HAS_EXTRA_STATE(t) \ - ((t)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID) \ - || PERFMON_IS_SYSWIDE()) + ((t)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID)) #define __switch_to(prev,next,last) do { \ if (IA64_HAS_EXTRA_STATE(prev)) \ diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 1a8df6669eee..c89bd5f8cbf8 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -10,7 +10,7 @@ endif extra-y := head.o vmlinux.lds obj-y := entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ - irq_lsapic.o ivt.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ + irq_lsapic.o ivt.o pal.o patch.o process.o ptrace.o sal.o \ salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ unwind.o mca.o mca_asm.o topology.o dma-mapping.o iosapic.o acpi.o \ acpi-ext.o @@ -21,7 +21,6 @@ obj-$(CONFIG_IA64_PALINFO) += palinfo.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_SMP) += smp.o smpboot.o obj-$(CONFIG_NUMA) += numa.o -obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o obj-$(CONFIG_IA64_CYCLONE) += cyclone.o obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o obj-$(CONFIG_KPROBES) += kprobes.o @@ -41,7 +40,7 @@ obj-y += esi_stub.o # must be in kernel proper endif obj-$(CONFIG_INTEL_IOMMU) += pci-dma.o -obj-$(CONFIG_BINFMT_ELF) += elfcore.o +obj-$(CONFIG_ELF_CORE) += elfcore.o # fp_emulate() expects f2-f5,f16-f31 to contain the user-level state. CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31 diff --git a/arch/ia64/kernel/dma-mapping.c b/arch/ia64/kernel/dma-mapping.c index 09ef9ce9988d..cd0c166bfbc2 100644 --- a/arch/ia64/kernel/dma-mapping.c +++ b/arch/ia64/kernel/dma-mapping.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -#include <linux/dma-direct.h> +#include <linux/dma-map-ops.h> #include <linux/export.h> /* Set this to 1 if there is a HW IOMMU in the system */ @@ -7,15 +7,3 @@ int iommu_detected __read_mostly; const struct dma_map_ops *dma_ops; EXPORT_SYMBOL(dma_ops); - -void *arch_dma_alloc(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) -{ - return dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs); -} - -void arch_dma_free(struct device *dev, size_t size, void *cpu_addr, - dma_addr_t dma_addr, unsigned long attrs) -{ - dma_direct_free_pages(dev, size, cpu_addr, dma_addr, attrs); -} diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 6fff934150eb..46e33c5cb53d 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -40,10 +40,6 @@ #include <asm/hw_irq.h> #include <asm/tlbflush.h> -#ifdef CONFIG_PERFMON -# include <asm/perfmon.h> -#endif - #define IRQ_DEBUG 0 #define IRQ_VECTOR_UNASSIGNED (0) @@ -627,9 +623,6 @@ init_IRQ (void) "irq_move"); } #endif -#ifdef CONFIG_PERFMON - pfm_init_percpu(); -#endif } void diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 7a7df944d798..fc1ff8a4d7de 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -396,83 +396,9 @@ static void kretprobe_trampoline(void) { } -/* - * At this point the target function has been tricked into - * returning into our trampoline. Lookup the associated instance - * and then: - * - call the handler function - * - cleanup by marking the instance as unused - * - long jump back to the original return address - */ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *tmp; - unsigned long flags, orig_ret_address = 0; - unsigned long trampoline_address = - ((struct fnptr *)kretprobe_trampoline)->ip; - - INIT_HLIST_HEAD(&empty_rp); - kretprobe_hash_lock(current, &head, &flags); - - /* - * It is possible to have multiple instances associated with a given - * task either because an multiple functions in the call path - * have a return probe installed on them, and/or more than one return - * return probe was registered for a target function. - * - * We can handle this because: - * - instances are always inserted at the head of the list - * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the - * real return address, and all the rest will point to - * kretprobe_trampoline - */ - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - orig_ret_address = (unsigned long)ri->ret_addr; - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - regs->cr_iip = orig_ret_address; - - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - if (ri->rp && ri->rp->handler) - ri->rp->handler(ri, regs); - - orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - kretprobe_assert(ri, orig_ret_address, trampoline_address); - - kretprobe_hash_unlock(current, &flags); - - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } + regs->cr_iip = __kretprobe_trampoline_handler(regs, kretprobe_trampoline, NULL); /* * By returning a non-zero value, we are telling * kprobe_handler() that we don't want the post_handler @@ -485,6 +411,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) { ri->ret_addr = (kprobe_opcode_t *)regs->b0; + ri->fp = NULL; /* Replace the return addr with trampoline addr */ regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip; diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c deleted file mode 100644 index 0dc3611e7971..000000000000 --- a/arch/ia64/kernel/perfmon.c +++ /dev/null @@ -1,6703 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * This file implements the perfmon-2 subsystem which is used - * to program the IA-64 Performance Monitoring Unit (PMU). - * - * The initial version of perfmon.c was written by - * Ganesh Venkitachalam, IBM Corp. - * - * Then it was modified for perfmon-1.x by Stephane Eranian and - * David Mosberger, Hewlett Packard Co. - * - * Version Perfmon-2.x is a rewrite of perfmon-1.x - * by Stephane Eranian, Hewlett Packard Co. - * - * Copyright (C) 1999-2005 Hewlett Packard Co - * Stephane Eranian <eranian@hpl.hp.com> - * David Mosberger-Tang <davidm@hpl.hp.com> - * - * More information about perfmon available at: - * http://www.hpl.hp.com/research/linux/perfmon - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/sched/task.h> -#include <linux/sched/task_stack.h> -#include <linux/interrupt.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> -#include <linux/init.h> -#include <linux/vmalloc.h> -#include <linux/mm.h> -#include <linux/sysctl.h> -#include <linux/list.h> -#include <linux/file.h> -#include <linux/poll.h> -#include <linux/vfs.h> -#include <linux/smp.h> -#include <linux/pagemap.h> -#include <linux/mount.h> -#include <linux/pseudo_fs.h> -#include <linux/bitops.h> -#include <linux/capability.h> -#include <linux/rcupdate.h> -#include <linux/completion.h> -#include <linux/tracehook.h> -#include <linux/slab.h> -#include <linux/cpu.h> - -#include <asm/errno.h> -#include <asm/intrinsics.h> -#include <asm/page.h> -#include <asm/perfmon.h> -#include <asm/processor.h> -#include <asm/signal.h> -#include <linux/uaccess.h> -#include <asm/delay.h> - -#include "irq.h" - -#ifdef CONFIG_PERFMON -/* - * perfmon context state - */ -#define PFM_CTX_UNLOADED 1 /* context is not loaded onto any task */ -#define PFM_CTX_LOADED 2 /* context is loaded onto a task */ -#define PFM_CTX_MASKED 3 /* context is loaded but monitoring is masked due to overflow */ -#define PFM_CTX_ZOMBIE 4 /* owner of the context is closing it */ - -#define PFM_INVALID_ACTIVATION (~0UL) - -#define PFM_NUM_PMC_REGS 64 /* PMC save area for ctxsw */ -#define PFM_NUM_PMD_REGS 64 /* PMD save area for ctxsw */ - -/* - * depth of message queue - */ -#define PFM_MAX_MSGS 32 -#define PFM_CTXQ_EMPTY(g) ((g)->ctx_msgq_head == (g)->ctx_msgq_tail) - -/* - * type of a PMU register (bitmask). - * bitmask structure: - * bit0 : register implemented - * bit1 : end marker - * bit2-3 : reserved - * bit4 : pmc has pmc.pm - * bit5 : pmc controls a counter (has pmc.oi), pmd is used as counter - * bit6-7 : register type - * bit8-31: reserved - */ -#define PFM_REG_NOTIMPL 0x0 /* not implemented at all */ -#define PFM_REG_IMPL 0x1 /* register implemented */ -#define PFM_REG_END 0x2 /* end marker */ -#define PFM_REG_MONITOR (0x1<<4|PFM_REG_IMPL) /* a PMC with a pmc.pm field only */ -#define PFM_REG_COUNTING (0x2<<4|PFM_REG_MONITOR) /* a monitor + pmc.oi+ PMD used as a counter */ -#define PFM_REG_CONTROL (0x4<<4|PFM_REG_IMPL) /* PMU control register */ -#define PFM_REG_CONFIG (0x8<<4|PFM_REG_IMPL) /* configuration register */ -#define PFM_REG_BUFFER (0xc<<4|PFM_REG_IMPL) /* PMD used as buffer */ - -#define PMC_IS_LAST(i) (pmu_conf->pmc_desc[i].type & PFM_REG_END) -#define PMD_IS_LAST(i) (pmu_conf->pmd_desc[i].type & PFM_REG_END) - -#define PMC_OVFL_NOTIFY(ctx, i) ((ctx)->ctx_pmds[i].flags & PFM_REGFL_OVFL_NOTIFY) - -/* i assumed unsigned */ -#define PMC_IS_IMPL(i) (i< PMU_MAX_PMCS && (pmu_conf->pmc_desc[i].type & PFM_REG_IMPL)) -#define PMD_IS_IMPL(i) (i< PMU_MAX_PMDS && (pmu_conf->pmd_desc[i].type & PFM_REG_IMPL)) - -/* XXX: these assume that register i is implemented */ -#define PMD_IS_COUNTING(i) ((pmu_conf->pmd_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING) -#define PMC_IS_COUNTING(i) ((pmu_conf->pmc_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING) -#define PMC_IS_MONITOR(i) ((pmu_conf->pmc_desc[i].type & PFM_REG_MONITOR) == PFM_REG_MONITOR) -#define PMC_IS_CONTROL(i) ((pmu_conf->pmc_desc[i].type & PFM_REG_CONTROL) == PFM_REG_CONTROL) - -#define PMC_DFL_VAL(i) pmu_conf->pmc_desc[i].default_value -#define PMC_RSVD_MASK(i) pmu_conf->pmc_desc[i].reserved_mask -#define PMD_PMD_DEP(i) pmu_conf->pmd_desc[i].dep_pmd[0] -#define PMC_PMD_DEP(i) pmu_conf->pmc_desc[i].dep_pmd[0] - -#define PFM_NUM_IBRS IA64_NUM_DBG_REGS -#define PFM_NUM_DBRS IA64_NUM_DBG_REGS - -#define CTX_OVFL_NOBLOCK(c) ((c)->ctx_fl_block == 0) -#define CTX_HAS_SMPL(c) ((c)->ctx_fl_is_sampling) -#define PFM_CTX_TASK(h) (h)->ctx_task - -#define PMU_PMC_OI 5 /* position of pmc.oi bit */ - -/* XXX: does not support more than 64 PMDs */ -#define CTX_USED_PMD(ctx, mask) (ctx)->ctx_used_pmds[0] |= (mask) -#define CTX_IS_USED_PMD(ctx, c) (((ctx)->ctx_used_pmds[0] & (1UL << (c))) != 0UL) - -#define CTX_USED_MONITOR(ctx, mask) (ctx)->ctx_used_monitors[0] |= (mask) - -#define CTX_USED_IBR(ctx,n) (ctx)->ctx_used_ibrs[(n)>>6] |= 1UL<< ((n) % 64) -#define CTX_USED_DBR(ctx,n) (ctx)->ctx_used_dbrs[(n)>>6] |= 1UL<< ((n) % 64) -#define CTX_USES_DBREGS(ctx) (((pfm_context_t *)(ctx))->ctx_fl_using_dbreg==1) -#define PFM_CODE_RR 0 /* requesting code range restriction */ -#define PFM_DATA_RR 1 /* requestion data range restriction */ - -#define PFM_CPUINFO_CLEAR(v) pfm_get_cpu_var(pfm_syst_info) &= ~(v) -#define PFM_CPUINFO_SET(v) pfm_get_cpu_var(pfm_syst_info) |= (v) -#define PFM_CPUINFO_GET() pfm_get_cpu_var(pfm_syst_info) - -#define RDEP(x) (1UL<<(x)) - -/* - * context protection macros - * in SMP: - * - we need to protect against CPU concurrency (spin_lock) - * - we need to protect against PMU overflow interrupts (local_irq_disable) - * in UP: - * - we need to protect against PMU overflow interrupts (local_irq_disable) - * - * spin_lock_irqsave()/spin_unlock_irqrestore(): - * in SMP: local_irq_disable + spin_lock - * in UP : local_irq_disable - * - * spin_lock()/spin_lock(): - * in UP : removed automatically - * in SMP: protect against context accesses from other CPU. interrupts - * are not masked. This is useful for the PMU interrupt handler - * because we know we will not get PMU concurrency in that code. - */ -#define PROTECT_CTX(c, f) \ - do { \ - DPRINT(("spinlock_irq_save ctx %p by [%d]\n", c, task_pid_nr(current))); \ - spin_lock_irqsave(&(c)->ctx_lock, f); \ - DPRINT(("spinlocked ctx %p by [%d]\n", c, task_pid_nr(current))); \ - } while(0) - -#define UNPROTECT_CTX(c, f) \ - do { \ - DPRINT(("spinlock_irq_restore ctx %p by [%d]\n", c, task_pid_nr(current))); \ - spin_unlock_irqrestore(&(c)->ctx_lock, f); \ - } while(0) - -#define PROTECT_CTX_NOPRINT(c, f) \ - do { \ - spin_lock_irqsave(&(c)->ctx_lock, f); \ - } while(0) - - -#define UNPROTECT_CTX_NOPRINT(c, f) \ - do { \ - spin_unlock_irqrestore(&(c)->ctx_lock, f); \ - } while(0) - - -#define PROTECT_CTX_NOIRQ(c) \ - do { \ - spin_lock(&(c)->ctx_lock); \ - } while(0) - -#define UNPROTECT_CTX_NOIRQ(c) \ - do { \ - spin_unlock(&(c)->ctx_lock); \ - } while(0) - - -#ifdef CONFIG_SMP - -#define GET_ACTIVATION() pfm_get_cpu_var(pmu_activation_number) -#define INC_ACTIVATION() pfm_get_cpu_var(pmu_activation_number)++ -#define SET_ACTIVATION(c) (c)->ctx_last_activation = GET_ACTIVATION() - -#else /* !CONFIG_SMP */ -#define SET_ACTIVATION(t) do {} while(0) -#define GET_ACTIVATION(t) do {} while(0) -#define INC_ACTIVATION(t) do {} while(0) -#endif /* CONFIG_SMP */ - -#define SET_PMU_OWNER(t, c) do { pfm_get_cpu_var(pmu_owner) = (t); pfm_get_cpu_var(pmu_ctx) = (c); } while(0) -#define GET_PMU_OWNER() pfm_get_cpu_var(pmu_owner) -#define GET_PMU_CTX() pfm_get_cpu_var(pmu_ctx) - -#define LOCK_PFS(g) spin_lock_irqsave(&pfm_sessions.pfs_lock, g) -#define UNLOCK_PFS(g) spin_unlock_irqrestore(&pfm_sessions.pfs_lock, g) - -#define PFM_REG_RETFLAG_SET(flags, val) do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0) - -/* - * cmp0 must be the value of pmc0 - */ -#define PMC0_HAS_OVFL(cmp0) (cmp0 & ~0x1UL) - -#define PFMFS_MAGIC 0xa0b4d889 - -/* - * debugging - */ -#define PFM_DEBUGGING 1 -#ifdef PFM_DEBUGGING -#define DPRINT(a) \ - do { \ - if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __func__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \ - } while (0) - -#define DPRINT_ovfl(a) \ - do { \ - if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __func__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \ - } while (0) -#endif - -/* - * 64-bit software counter structure - * - * the next_reset_type is applied to the next call to pfm_reset_regs() - */ -typedef struct { - unsigned long val; /* virtual 64bit counter value */ - unsigned long lval; /* last reset value */ - unsigned long long_reset; /* reset value on sampling overflow */ - unsigned long short_reset; /* reset value on overflow */ - unsigned long reset_pmds[4]; /* which other pmds to reset when this counter overflows */ - unsigned long smpl_pmds[4]; /* which pmds are accessed when counter overflow */ - unsigned long seed; /* seed for random-number generator */ - unsigned long mask; /* mask for random-number generator */ - unsigned int flags; /* notify/do not notify */ - unsigned long eventid; /* overflow event identifier */ -} pfm_counter_t; - -/* - * context flags - */ -typedef struct { - unsigned int block:1; /* when 1, task will blocked on user notifications */ - unsigned int system:1; /* do system wide monitoring */ - unsigned int using_dbreg:1; /* using range restrictions (debug registers) */ - unsigned int is_sampling:1; /* true if using a custom format */ - unsigned int excl_idle:1; /* exclude idle task in system wide session */ - unsigned int going_zombie:1; /* context is zombie (MASKED+blocking) */ - unsigned int trap_reason:2; /* reason for going into pfm_handle_work() */ - unsigned int no_msg:1; /* no message sent on overflow */ - unsigned int can_restart:1; /* allowed to issue a PFM_RESTART */ - unsigned int reserved:22; -} pfm_context_flags_t; - -#define PFM_TRAP_REASON_NONE 0x0 /* default value */ -#define PFM_TRAP_REASON_BLOCK 0x1 /* we need to block on overflow */ -#define PFM_TRAP_REASON_RESET 0x2 /* we need to reset PMDs */ - - -/* - * perfmon context: encapsulates all the state of a monitoring session - */ - -typedef struct pfm_context { - spinlock_t ctx_lock; /* context protection */ - - pfm_context_flags_t ctx_flags; /* bitmask of flags (block reason incl.) */ - unsigned int ctx_state; /* state: active/inactive (no bitfield) */ - - struct task_struct *ctx_task; /* task to which context is attached */ - - unsigned long ctx_ovfl_regs[4]; /* which registers overflowed (notification) */ - - struct completion ctx_restart_done; /* use for blocking notification mode */ - - unsigned long ctx_used_pmds[4]; /* bitmask of PMD used */ - unsigned long ctx_all_pmds[4]; /* bitmask of all accessible PMDs */ - unsigned long ctx_reload_pmds[4]; /* bitmask of force reload PMD on ctxsw in */ - - unsigned long ctx_all_pmcs[4]; /* bitmask of all accessible PMCs */ - unsigned long ctx_reload_pmcs[4]; /* bitmask of force reload PMC on ctxsw in */ - unsigned long ctx_used_monitors[4]; /* bitmask of monitor PMC being used */ - - unsigned long ctx_pmcs[PFM_NUM_PMC_REGS]; /* saved copies of PMC values */ - - unsigned int ctx_used_ibrs[1]; /* bitmask of used IBR (speedup ctxsw in) */ - unsigned int ctx_used_dbrs[1]; /* bitmask of used DBR (speedup ctxsw in) */ - unsigned long ctx_dbrs[IA64_NUM_DBG_REGS]; /* DBR values (cache) when not loaded */ - unsigned long ctx_ibrs[IA64_NUM_DBG_REGS]; /* IBR values (cache) when not loaded */ - - pfm_counter_t ctx_pmds[PFM_NUM_PMD_REGS]; /* software state for PMDS */ - - unsigned long th_pmcs[PFM_NUM_PMC_REGS]; /* PMC thread save state */ - unsigned long th_pmds[PFM_NUM_PMD_REGS]; /* PMD thread save state */ - - unsigned long ctx_saved_psr_up; /* only contains psr.up value */ - - unsigned long ctx_last_activation; /* context last activation number for last_cpu */ - unsigned int ctx_last_cpu; /* CPU id of current or last CPU used (SMP only) */ - unsigned int ctx_cpu; /* cpu to which perfmon is applied (system wide) */ - - int ctx_fd; /* file descriptor used my this context */ - pfm_ovfl_arg_t ctx_ovfl_arg; /* argument to custom buffer format handler */ - - pfm_buffer_fmt_t *ctx_buf_fmt; /* buffer format callbacks */ - void *ctx_smpl_hdr; /* points to sampling buffer header kernel vaddr */ - unsigned long ctx_smpl_size; /* size of sampling buffer */ - void *ctx_smpl_vaddr; /* user level virtual address of smpl buffer */ - - wait_queue_head_t ctx_msgq_wait; - pfm_msg_t ctx_msgq[PFM_MAX_MSGS]; - int ctx_msgq_head; - int ctx_msgq_tail; - struct fasync_struct *ctx_async_queue; - - wait_queue_head_t ctx_zombieq; /* termination cleanup wait queue */ -} pfm_context_t; - -/* - * magic number used to verify that structure is really - * a perfmon context - */ -#define PFM_IS_FILE(f) ((f)->f_op == &pfm_file_ops) - -#define PFM_GET_CTX(t) ((pfm_context_t *)(t)->thread.pfm_context) - -#ifdef CONFIG_SMP -#define SET_LAST_CPU(ctx, v) (ctx)->ctx_last_cpu = (v) -#define GET_LAST_CPU(ctx) (ctx)->ctx_last_cpu -#else -#define SET_LAST_CPU(ctx, v) do {} while(0) -#define GET_LAST_CPU(ctx) do {} while(0) -#endif - - -#define ctx_fl_block ctx_flags.block -#define ctx_fl_system ctx_flags.system -#define ctx_fl_using_dbreg ctx_flags.using_dbreg -#define ctx_fl_is_sampling ctx_flags.is_sampling -#define ctx_fl_excl_idle ctx_flags.excl_idle -#define ctx_fl_going_zombie ctx_flags.going_zombie -#define ctx_fl_trap_reason ctx_flags.trap_reason -#define ctx_fl_no_msg ctx_flags.no_msg -#define ctx_fl_can_restart ctx_flags.can_restart - -#define PFM_SET_WORK_PENDING(t, v) do { (t)->thread.pfm_needs_checking = v; } while(0); -#define PFM_GET_WORK_PENDING(t) (t)->thread.pfm_needs_checking - -/* - * global information about all sessions - * mostly used to synchronize between system wide and per-process - */ -typedef struct { - spinlock_t pfs_lock; /* lock the structure */ - - unsigned int pfs_task_sessions; /* number of per task sessions */ - unsigned int pfs_sys_sessions; /* number of per system wide sessions */ - unsigned int pfs_sys_use_dbregs; /* incremented when a system wide session uses debug regs */ - unsigned int pfs_ptrace_use_dbregs; /* incremented when a process uses debug regs */ - struct task_struct *pfs_sys_session[NR_CPUS]; /* point to task owning a system-wide session */ -} pfm_session_t; - -/* - * information about a PMC or PMD. - * dep_pmd[]: a bitmask of dependent PMD registers - * dep_pmc[]: a bitmask of dependent PMC registers - */ -typedef int (*pfm_reg_check_t)(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs); -typedef struct { - unsigned int type; - int pm_pos; - unsigned long default_value; /* power-on default value */ - unsigned long reserved_mask; /* bitmask of reserved bits */ - pfm_reg_check_t read_check; - pfm_reg_check_t write_check; - unsigned long dep_pmd[4]; - unsigned long dep_pmc[4]; -} pfm_reg_desc_t; - -/* assume cnum is a valid monitor */ -#define PMC_PM(cnum, val) (((val) >> (pmu_conf->pmc_desc[cnum].pm_pos)) & 0x1) - -/* - * This structure is initialized at boot time and contains - * a description of the PMU main characteristics. - * - * If the probe function is defined, detection is based - * on its return value: - * - 0 means recognized PMU - * - anything else means not supported - * When the probe function is not defined, then the pmu_family field - * is used and it must match the host CPU family such that: - * - cpu->family & config->pmu_family != 0 - */ -typedef struct { - unsigned long ovfl_val; /* overflow value for counters */ - - pfm_reg_desc_t *pmc_desc; /* detailed PMC register dependencies descriptions */ - pfm_reg_desc_t *pmd_desc; /* detailed PMD register dependencies descriptions */ - - unsigned int num_pmcs; /* number of PMCS: computed at init time */ - unsigned int num_pmds; /* number of PMDS: computed at init time */ - unsigned long impl_pmcs[4]; /* bitmask of implemented PMCS */ - unsigned long impl_pmds[4]; /* bitmask of implemented PMDS */ - - char *pmu_name; /* PMU family name */ - unsigned int pmu_family; /* cpuid family pattern used to identify pmu */ - unsigned int flags; /* pmu specific flags */ - unsigned int num_ibrs; /* number of IBRS: computed at init time */ - unsigned int num_dbrs; /* number of DBRS: computed at init time */ - unsigned int num_counters; /* PMC/PMD counting pairs : computed at init time */ - int (*probe)(void); /* customized probe routine */ - unsigned int use_rr_dbregs:1; /* set if debug registers used for range restriction */ -} pmu_config_t; -/* - * PMU specific flags - */ -#define PFM_PMU_IRQ_RESEND 1 /* PMU needs explicit IRQ resend */ - -/* - * debug register related type definitions - */ -typedef struct { - unsigned long ibr_mask:56; - unsigned long ibr_plm:4; - unsigned long ibr_ig:3; - unsigned long ibr_x:1; -} ibr_mask_reg_t; - -typedef struct { - unsigned long dbr_mask:56; - unsigned long dbr_plm:4; - unsigned long dbr_ig:2; - unsigned long dbr_w:1; - unsigned long dbr_r:1; -} dbr_mask_reg_t; - -typedef union { - unsigned long val; - ibr_mask_reg_t ibr; - dbr_mask_reg_t dbr; -} dbreg_t; - - -/* - * perfmon command descriptions - */ -typedef struct { - int (*cmd_func)(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs); - char *cmd_name; - int cmd_flags; - unsigned int cmd_narg; - size_t cmd_argsize; - int (*cmd_getsize)(void *arg, size_t *sz); -} pfm_cmd_desc_t; - -#define PFM_CMD_FD 0x01 /* command requires a file descriptor */ -#define PFM_CMD_ARG_READ 0x02 /* command must read argument(s) */ -#define PFM_CMD_ARG_RW 0x04 /* command must read/write argument(s) */ -#define PFM_CMD_STOP 0x08 /* command does not work on zombie context */ - - -#define PFM_CMD_NAME(cmd) pfm_cmd_tab[(cmd)].cmd_name -#define PFM_CMD_READ_ARG(cmd) (pfm_cmd_tab[(cmd)].cmd_flags & PFM_CMD_ARG_READ) -#define PFM_CMD_RW_ARG(cmd) (pfm_cmd_tab[(cmd)].cmd_flags & PFM_CMD_ARG_RW) -#define PFM_CMD_USE_FD(cmd) (pfm_cmd_tab[(cmd)].cmd_flags & PFM_CMD_FD) -#define PFM_CMD_STOPPED(cmd) (pfm_cmd_tab[(cmd)].cmd_flags & PFM_CMD_STOP) - -#define PFM_CMD_ARG_MANY -1 /* cannot be zero */ - -typedef struct { - unsigned long pfm_spurious_ovfl_intr_count; /* keep track of spurious ovfl interrupts */ - unsigned long pfm_replay_ovfl_intr_count; /* keep track of replayed ovfl interrupts */ - unsigned long pfm_ovfl_intr_count; /* keep track of ovfl interrupts */ - unsigned long pfm_ovfl_intr_cycles; /* cycles spent processing ovfl interrupts */ - unsigned long pfm_ovfl_intr_cycles_min; /* min cycles spent processing ovfl interrupts */ - unsigned long pfm_ovfl_intr_cycles_max; /* max cycles spent processing ovfl interrupts */ - unsigned long pfm_smpl_handler_calls; - unsigned long pfm_smpl_handler_cycles; - char pad[SMP_CACHE_BYTES] ____cacheline_aligned; -} pfm_stats_t; - -/* - * perfmon internal variables - */ -static pfm_stats_t pfm_stats[NR_CPUS]; -static pfm_session_t pfm_sessions; /* global sessions information */ - -static DEFINE_SPINLOCK(pfm_alt_install_check); -static pfm_intr_handler_desc_t *pfm_alt_intr_handler; - -static struct proc_dir_entry *perfmon_dir; -static pfm_uuid_t pfm_null_uuid = {0,}; - -static spinlock_t pfm_buffer_fmt_lock; -static LIST_HEAD(pfm_buffer_fmt_list); - -static pmu_config_t *pmu_conf; - -/* sysctl() controls */ -pfm_sysctl_t pfm_sysctl; -EXPORT_SYMBOL(pfm_sysctl); - -static struct ctl_table pfm_ctl_table[] = { - { - .procname = "debug", - .data = &pfm_sysctl.debug, - .maxlen = sizeof(int), - .mode = 0666, - .proc_handler = proc_dointvec, - }, - { - .procname = "debug_ovfl", - .data = &pfm_sysctl.debug_ovfl, - .maxlen = sizeof(int), - .mode = 0666, - .proc_handler = proc_dointvec, - }, - { - .procname = "fastctxsw", - .data = &pfm_sysctl.fastctxsw, - .maxlen = sizeof(int), - .mode = 0600, - .proc_handler = proc_dointvec, - }, - { - .procname = "expert_mode", - .data = &pfm_sysctl.expert_mode, - .maxlen = sizeof(int), - .mode = 0600, - .proc_handler = proc_dointvec, - }, - {} -}; -static struct ctl_table pfm_sysctl_dir[] = { - { - .procname = "perfmon", - .mode = 0555, - .child = pfm_ctl_table, - }, - {} -}; -static struct ctl_table pfm_sysctl_root[] = { - { - .procname = "kernel", - .mode = 0555, - .child = pfm_sysctl_dir, - }, - {} -}; -static struct ctl_table_header *pfm_sysctl_header; - -static int pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs); - -#define pfm_get_cpu_var(v) __ia64_per_cpu_var(v) -#define pfm_get_cpu_data(a,b) per_cpu(a, b) - -static inline void -pfm_put_task(struct task_struct *task) -{ - if (task != current) put_task_struct(task); -} - -static inline unsigned long -pfm_protect_ctx_ctxsw(pfm_context_t *x) -{ - spin_lock(&(x)->ctx_lock); - return 0UL; -} - -static inline void -pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f) -{ - spin_unlock(&(x)->ctx_lock); -} - -/* forward declaration */ -static const struct dentry_operations pfmfs_dentry_operations; - -static int pfmfs_init_fs_context(struct fs_context *fc) -{ - struct pseudo_fs_context *ctx = init_pseudo(fc, PFMFS_MAGIC); - if (!ctx) - return -ENOMEM; - ctx->dops = &pfmfs_dentry_operations; - return 0; -} - -static struct file_system_type pfm_fs_type = { - .name = "pfmfs", - .init_fs_context = pfmfs_init_fs_context, - .kill_sb = kill_anon_super, -}; -MODULE_ALIAS_FS("pfmfs"); - -DEFINE_PER_CPU(unsigned long, pfm_syst_info); -DEFINE_PER_CPU(struct task_struct *, pmu_owner); -DEFINE_PER_CPU(pfm_context_t *, pmu_ctx); -DEFINE_PER_CPU(unsigned long, pmu_activation_number); -EXPORT_PER_CPU_SYMBOL_GPL(pfm_syst_info); - - -/* forward declaration */ -static const struct file_operations pfm_file_ops; - -/* - * forward declarations - */ -#ifndef CONFIG_SMP -static void pfm_lazy_save_regs (struct task_struct *ta); -#endif - -void dump_pmu_state(const char *); -static int pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs); - -#include "perfmon_itanium.h" -#include "perfmon_mckinley.h" -#include "perfmon_montecito.h" -#include "perfmon_generic.h" - -static pmu_config_t *pmu_confs[]={ - &pmu_conf_mont, - &pmu_conf_mck, - &pmu_conf_ita, - &pmu_conf_gen, /* must be last */ - NULL -}; - - -static int pfm_end_notify_user(pfm_context_t *ctx); - -static inline void -pfm_clear_psr_pp(void) -{ - ia64_rsm(IA64_PSR_PP); - ia64_srlz_i(); -} - -static inline void -pfm_set_psr_pp(void) -{ - ia64_ssm(IA64_PSR_PP); - ia64_srlz_i(); -} - -static inline void -pfm_clear_psr_up(void) -{ - ia64_rsm(IA64_PSR_UP); - ia64_srlz_i(); -} - -static inline void -pfm_set_psr_up(void) -{ - ia64_ssm(IA64_PSR_UP); - ia64_srlz_i(); -} - -static inline unsigned long -pfm_get_psr(void) -{ - unsigned long tmp; - tmp = ia64_getreg(_IA64_REG_PSR); - ia64_srlz_i(); - return tmp; -} - -static inline void -pfm_set_psr_l(unsigned long val) -{ - ia64_setreg(_IA64_REG_PSR_L, val); - ia64_srlz_i(); -} - -static inline void -pfm_freeze_pmu(void) -{ - ia64_set_pmc(0,1UL); - ia64_srlz_d(); -} - -static inline void -pfm_unfreeze_pmu(void) -{ - ia64_set_pmc(0,0UL); - ia64_srlz_d(); -} - -static inline void -pfm_restore_ibrs(unsigned long *ibrs, unsigned int nibrs) -{ - int i; - - for (i=0; i < nibrs; i++) { - ia64_set_ibr(i, ibrs[i]); - ia64_dv_serialize_instruction(); - } - ia64_srlz_i(); -} - -static inline void -pfm_restore_dbrs(unsigned long *dbrs, unsigned int ndbrs) -{ - int i; - - for (i=0; i < ndbrs; i++) { - ia64_set_dbr(i, dbrs[i]); - ia64_dv_serialize_data(); - } - ia64_srlz_d(); -} - -/* - * PMD[i] must be a counter. no check is made - */ -static inline unsigned long -pfm_read_soft_counter(pfm_context_t *ctx, int i) -{ - return ctx->ctx_pmds[i].val + (ia64_get_pmd(i) & pmu_conf->ovfl_val); -} - -/* - * PMD[i] must be a counter. no check is made - */ -static inline void -pfm_write_soft_counter(pfm_context_t *ctx, int i, unsigned long val) -{ - unsigned long ovfl_val = pmu_conf->ovfl_val; - - ctx->ctx_pmds[i].val = val & ~ovfl_val; - /* - * writing to unimplemented part is ignore, so we do not need to - * mask off top part - */ - ia64_set_pmd(i, val & ovfl_val); -} - -static pfm_msg_t * -pfm_get_new_msg(pfm_context_t *ctx) -{ - int idx, next; - - next = (ctx->ctx_msgq_tail+1) % PFM_MAX_MSGS; - - DPRINT(("ctx_fd=%p head=%d tail=%d\n", ctx, ctx->ctx_msgq_head, ctx->ctx_msgq_tail)); - if (next == ctx->ctx_msgq_head) return NULL; - - idx = ctx->ctx_msgq_tail; - ctx->ctx_msgq_tail = next; - - DPRINT(("ctx=%p head=%d tail=%d msg=%d\n", ctx, ctx->ctx_msgq_head, ctx->ctx_msgq_tail, idx)); - - return ctx->ctx_msgq+idx; -} - -static pfm_msg_t * -pfm_get_next_msg(pfm_context_t *ctx) -{ - pfm_msg_t *msg; - - DPRINT(("ctx=%p head=%d tail=%d\n", ctx, ctx->ctx_msgq_head, ctx->ctx_msgq_tail)); - - if (PFM_CTXQ_EMPTY(ctx)) return NULL; - - /* - * get oldest message - */ - msg = ctx->ctx_msgq+ctx->ctx_msgq_head; - - /* - * and move forward - */ - ctx->ctx_msgq_head = (ctx->ctx_msgq_head+1) % PFM_MAX_MSGS; - - DPRINT(("ctx=%p head=%d tail=%d type=%d\n", ctx, ctx->ctx_msgq_head, ctx->ctx_msgq_tail, msg->pfm_gen_msg.msg_type)); - - return msg; -} - -static void -pfm_reset_msgq(pfm_context_t *ctx) -{ - ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0; - DPRINT(("ctx=%p msgq reset\n", ctx)); -} - -static pfm_context_t * -pfm_context_alloc(int ctx_flags) -{ - pfm_context_t *ctx; - - /* - * allocate context descriptor - * must be able to free with interrupts disabled - */ - ctx = kzalloc(sizeof(pfm_context_t), GFP_KERNEL); - if (ctx) { - DPRINT(("alloc ctx @%p\n", ctx)); - - /* - * init context protection lock - */ - spin_lock_init(&ctx->ctx_lock); - - /* - * context is unloaded - */ - ctx->ctx_state = PFM_CTX_UNLOADED; - - /* - * initialization of context's flags - */ - ctx->ctx_fl_block = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0; - ctx->ctx_fl_system = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0; - ctx->ctx_fl_no_msg = (ctx_flags & PFM_FL_OVFL_NO_MSG) ? 1: 0; - /* - * will move to set properties - * ctx->ctx_fl_excl_idle = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0; - */ - - /* - * init restart semaphore to locked - */ - init_completion(&ctx->ctx_restart_done); - - /* - * activation is used in SMP only - */ - ctx->ctx_last_activation = PFM_INVALID_ACTIVATION; - SET_LAST_CPU(ctx, -1); - - /* - * initialize notification message queue - */ - ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0; - init_waitqueue_head(&ctx->ctx_msgq_wait); - init_waitqueue_head(&ctx->ctx_zombieq); - - } - return ctx; -} - -static void -pfm_context_free(pfm_context_t *ctx) -{ - if (ctx) { - DPRINT(("free ctx @%p\n", ctx)); - kfree(ctx); - } -} - -static void -pfm_mask_monitoring(struct task_struct *task) -{ - pfm_context_t *ctx = PFM_GET_CTX(task); - unsigned long mask, val, ovfl_mask; - int i; - - DPRINT_ovfl(("masking monitoring for [%d]\n", task_pid_nr(task))); - - ovfl_mask = pmu_conf->ovfl_val; - /* - * monitoring can only be masked as a result of a valid - * counter overflow. In UP, it means that the PMU still - * has an owner. Note that the owner can be different - * from the current task. However the PMU state belongs - * to the owner. - * In SMP, a valid overflow only happens when task is - * current. Therefore if we come here, we know that - * the PMU state belongs to the current task, therefore - * we can access the live registers. - * - * So in both cases, the live register contains the owner's - * state. We can ONLY touch the PMU registers and NOT the PSR. - * - * As a consequence to this call, the ctx->th_pmds[] array - * contains stale information which must be ignored - * when context is reloaded AND monitoring is active (see - * pfm_restart). - */ - mask = ctx->ctx_used_pmds[0]; - for (i = 0; mask; i++, mask>>=1) { - /* skip non used pmds */ - if ((mask & 0x1) == 0) continue; - val = ia64_get_pmd(i); - - if (PMD_IS_COUNTING(i)) { - /* - * we rebuild the full 64 bit value of the counter - */ - ctx->ctx_pmds[i].val += (val & ovfl_mask); - } else { - ctx->ctx_pmds[i].val = val; - } - DPRINT_ovfl(("pmd[%d]=0x%lx hw_pmd=0x%lx\n", - i, - ctx->ctx_pmds[i].val, - val & ovfl_mask)); - } - /* - * mask monitoring by setting the privilege level to 0 - * we cannot use psr.pp/psr.up for this, it is controlled by - * the user - * - * if task is current, modify actual registers, otherwise modify - * thread save state, i.e., what will be restored in pfm_load_regs() - */ - mask = ctx->ctx_used_monitors[0] >> PMU_FIRST_COUNTER; - for(i= PMU_FIRST_COUNTER; mask; i++, mask>>=1) { - if ((mask & 0x1) == 0UL) continue; - ia64_set_pmc(i, ctx->th_pmcs[i] & ~0xfUL); - ctx->th_pmcs[i] &= ~0xfUL; - DPRINT_ovfl(("pmc[%d]=0x%lx\n", i, ctx->th_pmcs[i])); - } - /* - * make all of this visible - */ - ia64_srlz_d(); -} - -/* - * must always be done with task == current - * - * context must be in MASKED state when calling - */ -static void -pfm_restore_monitoring(struct task_struct *task) -{ - pfm_context_t *ctx = PFM_GET_CTX(task); - unsigned long mask, ovfl_mask; - unsigned long psr, val; - int i, is_system; - - is_system = ctx->ctx_fl_system; - ovfl_mask = pmu_conf->ovfl_val; - - if (task != current) { - printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task_pid_nr(task), task_pid_nr(current)); - return; - } - if (ctx->ctx_state != PFM_CTX_MASKED) { - printk(KERN_ERR "perfmon.%d: task[%d] current[%d] invalid state=%d\n", __LINE__, - task_pid_nr(task), task_pid_nr(current), ctx->ctx_state); - return; - } - psr = pfm_get_psr(); - /* - * monitoring is masked via the PMC. - * As we restore their value, we do not want each counter to - * restart right away. We stop monitoring using the PSR, - * restore the PMC (and PMD) and then re-establish the psr - * as it was. Note that there can be no pending overflow at - * this point, because monitoring was MASKED. - * - * system-wide session are pinned and self-monitoring - */ - if (is_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) { - /* disable dcr pp */ - ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) & ~IA64_DCR_PP); - pfm_clear_psr_pp(); - } else { - pfm_clear_psr_up(); - } - /* - * first, we restore the PMD - */ - mask = ctx->ctx_used_pmds[0]; - for (i = 0; mask; i++, mask>>=1) { - /* skip non used pmds */ - if ((mask & 0x1) == 0) continue; - - if (PMD_IS_COUNTING(i)) { - /* - * we split the 64bit value according to - * counter width - */ - val = ctx->ctx_pmds[i].val & ovfl_mask; - ctx->ctx_pmds[i].val &= ~ovfl_mask; - } else { - val = ctx->ctx_pmds[i].val; - } - ia64_set_pmd(i, val); - - DPRINT(("pmd[%d]=0x%lx hw_pmd=0x%lx\n", - i, - ctx->ctx_pmds[i].val, - val)); - } - /* - * restore the PMCs - */ - mask = ctx->ctx_used_monitors[0] >> PMU_FIRST_COUNTER; - for(i= PMU_FIRST_COUNTER; mask; i++, mask>>=1) { - if ((mask & 0x1) == 0UL) continue; - ctx->th_pmcs[i] = ctx->ctx_pmcs[i]; - ia64_set_pmc(i, ctx->th_pmcs[i]); - DPRINT(("[%d] pmc[%d]=0x%lx\n", - task_pid_nr(task), i, ctx->th_pmcs[i])); - } - ia64_srlz_d(); - - /* - * must restore DBR/IBR because could be modified while masked - * XXX: need to optimize - */ - if (ctx->ctx_fl_using_dbreg) { - pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf->num_ibrs); - pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf->num_dbrs); - } - - /* - * now restore PSR - */ - if (is_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) { - /* enable dcr pp */ - ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) | IA64_DCR_PP); - ia64_srlz_i(); - } - pfm_set_psr_l(psr); -} - -static inline void -pfm_save_pmds(unsigned long *pmds, unsigned long mask) -{ - int i; - - ia64_srlz_d(); - - for (i=0; mask; i++, mask>>=1) { - if (mask & 0x1) pmds[i] = ia64_get_pmd(i); - } -} - -/* - * reload from thread state (used for ctxw only) - */ -static inline void -pfm_restore_pmds(unsigned long *pmds, unsigned long mask) -{ - int i; - unsigned long val, ovfl_val = pmu_conf->ovfl_val; - - for (i=0; mask; i++, mask>>=1) { - if ((mask & 0x1) == 0) continue; - val = PMD_IS_COUNTING(i) ? pmds[i] & ovfl_val : pmds[i]; - ia64_set_pmd(i, val); - } - ia64_srlz_d(); -} - -/* - * propagate PMD from context to thread-state - */ -static inline void -pfm_copy_pmds(struct task_struct *task, pfm_context_t *ctx) -{ - unsigned long ovfl_val = pmu_conf->ovfl_val; - unsigned long mask = ctx->ctx_all_pmds[0]; - unsigned long val; - int i; - - DPRINT(("mask=0x%lx\n", mask)); - - for (i=0; mask; i++, mask>>=1) { - - val = ctx->ctx_pmds[i].val; - - /* - * We break up the 64 bit value into 2 pieces - * the lower bits go to the machine state in the - * thread (will be reloaded on ctxsw in). - * The upper part stays in the soft-counter. - */ - if (PMD_IS_COUNTING(i)) { - ctx->ctx_pmds[i].val = val & ~ovfl_val; - val &= ovfl_val; - } - ctx->th_pmds[i] = val; - - DPRINT(("pmd[%d]=0x%lx soft_val=0x%lx\n", - i, - ctx->th_pmds[i], - ctx->ctx_pmds[i].val)); - } -} - -/* - * propagate PMC from context to thread-state - */ -static inline void -pfm_copy_pmcs(struct task_struct *task, pfm_context_t *ctx) -{ - unsigned long mask = ctx->ctx_all_pmcs[0]; - int i; - - DPRINT(("mask=0x%lx\n", mask)); - - for (i=0; mask; i++, mask>>=1) { - /* masking 0 with ovfl_val yields 0 */ - ctx->th_pmcs[i] = ctx->ctx_pmcs[i]; - DPRINT(("pmc[%d]=0x%lx\n", i, ctx->th_pmcs[i])); - } -} - - - -static inline void -pfm_restore_pmcs(unsigned long *pmcs, unsigned long mask) -{ - int i; - - for (i=0; mask; i++, mask>>=1) { - if ((mask & 0x1) == 0) continue; - ia64_set_pmc(i, pmcs[i]); - } - ia64_srlz_d(); -} - -static inline int -pfm_uuid_cmp(pfm_uuid_t a, pfm_uuid_t b) -{ - return memcmp(a, b, sizeof(pfm_uuid_t)); -} - -static inline int -pfm_buf_fmt_exit(pfm_buffer_fmt_t *fmt, struct task_struct *task, void *buf, struct pt_regs *regs) -{ - int ret = 0; - if (fmt->fmt_exit) ret = (*fmt->fmt_exit)(task, buf, regs); - return ret; -} - -static inline int -pfm_buf_fmt_getsize(pfm_buffer_fmt_t *fmt, struct task_struct *task, unsigned int flags, int cpu, void *arg, unsigned long *size) -{ - int ret = 0; - if (fmt->fmt_getsize) ret = (*fmt->fmt_getsize)(task, flags, cpu, arg, size); - return ret; -} - - -static inline int -pfm_buf_fmt_validate(pfm_buffer_fmt_t *fmt, struct task_struct *task, unsigned int flags, - int cpu, void *arg) -{ - int ret = 0; - if (fmt->fmt_validate) ret = (*fmt->fmt_validate)(task, flags, cpu, arg); - return ret; -} - -static inline int -pfm_buf_fmt_init(pfm_buffer_fmt_t *fmt, struct task_struct *task, void *buf, unsigned int flags, - int cpu, void *arg) -{ - int ret = 0; - if (fmt->fmt_init) ret = (*fmt->fmt_init)(task, buf, flags, cpu, arg); - return ret; -} - -static inline int -pfm_buf_fmt_restart(pfm_buffer_fmt_t *fmt, struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs) -{ - int ret = 0; - if (fmt->fmt_restart) ret = (*fmt->fmt_restart)(task, ctrl, buf, regs); - return ret; -} - -static inline int -pfm_buf_fmt_restart_active(pfm_buffer_fmt_t *fmt, struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs) -{ - int ret = 0; - if (fmt->fmt_restart_active) ret = (*fmt->fmt_restart_active)(task, ctrl, buf, regs); - return ret; -} - -static pfm_buffer_fmt_t * -__pfm_find_buffer_fmt(pfm_uuid_t uuid) -{ - struct list_head * pos; - pfm_buffer_fmt_t * entry; - - list_for_each(pos, &pfm_buffer_fmt_list) { - entry = list_entry(pos, pfm_buffer_fmt_t, fmt_list); - if (pfm_uuid_cmp(uuid, entry->fmt_uuid) == 0) - return entry; - } - return NULL; -} - -/* - * find a buffer format based on its uuid - */ -static pfm_buffer_fmt_t * -pfm_find_buffer_fmt(pfm_uuid_t uuid) -{ - pfm_buffer_fmt_t * fmt; - spin_lock(&pfm_buffer_fmt_lock); - fmt = __pfm_find_buffer_fmt(uuid); - spin_unlock(&pfm_buffer_fmt_lock); - return fmt; -} - -int -pfm_register_buffer_fmt(pfm_buffer_fmt_t *fmt) -{ - int ret = 0; - - /* some sanity checks */ - if (fmt == NULL || fmt->fmt_name == NULL) return -EINVAL; - - /* we need at least a handler */ - if (fmt->fmt_handler == NULL) return -EINVAL; - - /* - * XXX: need check validity of fmt_arg_size - */ - - spin_lock(&pfm_buffer_fmt_lock); - - if (__pfm_find_buffer_fmt(fmt->fmt_uuid)) { - printk(KERN_ERR "perfmon: duplicate sampling format: %s\n", fmt->fmt_name); - ret = -EBUSY; - goto out; - } - list_add(&fmt->fmt_list, &pfm_buffer_fmt_list); - printk(KERN_INFO "perfmon: added sampling format %s\n", fmt->fmt_name); - -out: - spin_unlock(&pfm_buffer_fmt_lock); - return ret; -} -EXPORT_SYMBOL(pfm_register_buffer_fmt); - -int -pfm_unregister_buffer_fmt(pfm_uuid_t uuid) -{ - pfm_buffer_fmt_t *fmt; - int ret = 0; - - spin_lock(&pfm_buffer_fmt_lock); - - fmt = __pfm_find_buffer_fmt(uuid); - if (!fmt) { - printk(KERN_ERR "perfmon: cannot unregister format, not found\n"); - ret = -EINVAL; - goto out; - } - list_del_init(&fmt->fmt_list); - printk(KERN_INFO "perfmon: removed sampling format: %s\n", fmt->fmt_name); - -out: - spin_unlock(&pfm_buffer_fmt_lock); - return ret; - -} -EXPORT_SYMBOL(pfm_unregister_buffer_fmt); - -static int -pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) -{ - unsigned long flags; - /* - * validity checks on cpu_mask have been done upstream - */ - LOCK_PFS(flags); - - DPRINT(("in sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu=%u\n", - pfm_sessions.pfs_sys_sessions, - pfm_sessions.pfs_task_sessions, - pfm_sessions.pfs_sys_use_dbregs, - is_syswide, - cpu)); - - if (is_syswide) { - /* - * cannot mix system wide and per-task sessions - */ - if (pfm_sessions.pfs_task_sessions > 0UL) { - DPRINT(("system wide not possible, %u conflicting task_sessions\n", - pfm_sessions.pfs_task_sessions)); - goto abort; - } - - if (pfm_sessions.pfs_sys_session[cpu]) goto error_conflict; - - DPRINT(("reserving system wide session on CPU%u currently on CPU%u\n", cpu, smp_processor_id())); - - pfm_sessions.pfs_sys_session[cpu] = task; - - pfm_sessions.pfs_sys_sessions++ ; - - } else { - if (pfm_sessions.pfs_sys_sessions) goto abort; - pfm_sessions.pfs_task_sessions++; - } - - DPRINT(("out sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu=%u\n", - pfm_sessions.pfs_sys_sessions, - pfm_sessions.pfs_task_sessions, - pfm_sessions.pfs_sys_use_dbregs, - is_syswide, - cpu)); - - /* - * Force idle() into poll mode - */ - cpu_idle_poll_ctrl(true); - - UNLOCK_PFS(flags); - - return 0; - -error_conflict: - DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n", - task_pid_nr(pfm_sessions.pfs_sys_session[cpu]), - cpu)); -abort: - UNLOCK_PFS(flags); - - return -EBUSY; - -} - -static int -pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu) -{ - unsigned long flags; - /* - * validity checks on cpu_mask have been done upstream - */ - LOCK_PFS(flags); - - DPRINT(("in sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu=%u\n", - pfm_sessions.pfs_sys_sessions, - pfm_sessions.pfs_task_sessions, - pfm_sessions.pfs_sys_use_dbregs, - is_syswide, - cpu)); - - - if (is_syswide) { - pfm_sessions.pfs_sys_session[cpu] = NULL; - /* - * would not work with perfmon+more than one bit in cpu_mask - */ - if (ctx && ctx->ctx_fl_using_dbreg) { - if (pfm_sessions.pfs_sys_use_dbregs == 0) { - printk(KERN_ERR "perfmon: invalid release for ctx %p sys_use_dbregs=0\n", ctx); - } else { - pfm_sessions.pfs_sys_use_dbregs--; - } - } - pfm_sessions.pfs_sys_sessions--; - } else { - pfm_sessions.pfs_task_sessions--; - } - DPRINT(("out sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu=%u\n", - pfm_sessions.pfs_sys_sessions, - pfm_sessions.pfs_task_sessions, - pfm_sessions.pfs_sys_use_dbregs, - is_syswide, - cpu)); - - /* Undo forced polling. Last session reenables pal_halt */ - cpu_idle_poll_ctrl(false); - - UNLOCK_PFS(flags); - - return 0; -} - -/* - * removes virtual mapping of the sampling buffer. - * IMPORTANT: cannot be called with interrupts disable, e.g. inside - * a PROTECT_CTX() section. - */ -static int -pfm_remove_smpl_mapping(void *vaddr, unsigned long size) -{ - struct task_struct *task = current; - int r; - - /* sanity checks */ - if (task->mm == NULL || size == 0UL || vaddr == NULL) { - printk(KERN_ERR "perfmon: pfm_remove_smpl_mapping [%d] invalid context mm=%p\n", task_pid_nr(task), task->mm); - return -EINVAL; - } - - DPRINT(("smpl_vaddr=%p size=%lu\n", vaddr, size)); - - /* - * does the actual unmapping - */ - r = vm_munmap((unsigned long)vaddr, size); - - if (r !=0) { - printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size); - } - - DPRINT(("do_unmap(%p, %lu)=%d\n", vaddr, size, r)); - - return 0; -} - -/* - * free actual physical storage used by sampling buffer - */ -#if 0 -static int -pfm_free_smpl_buffer(pfm_context_t *ctx) -{ - pfm_buffer_fmt_t *fmt; - - if (ctx->ctx_smpl_hdr == NULL) goto invalid_free; - - /* - * we won't use the buffer format anymore - */ - fmt = ctx->ctx_buf_fmt; - - DPRINT(("sampling buffer @%p size %lu vaddr=%p\n", - ctx->ctx_smpl_hdr, - ctx->ctx_smpl_size, - ctx->ctx_smpl_vaddr)); - - pfm_buf_fmt_exit(fmt, current, NULL, NULL); - - /* - * free the buffer - */ - vfree(ctx->ctx_smpl_hdr); - - ctx->ctx_smpl_hdr = NULL; - ctx->ctx_smpl_size = 0UL; - - return 0; - -invalid_free: - printk(KERN_ERR "perfmon: pfm_free_smpl_buffer [%d] no buffer\n", task_pid_nr(current)); - return -EINVAL; -} -#endif - -static inline void -pfm_exit_smpl_buffer(pfm_buffer_fmt_t *fmt) -{ - if (fmt == NULL) return; - - pfm_buf_fmt_exit(fmt, current, NULL, NULL); - -} - -/* - * pfmfs should _never_ be mounted by userland - too much of security hassle, - * no real gain from having the whole whorehouse mounted. So we don't need - * any operations on the root directory. However, we need a non-trivial - * d_name - pfm: will go nicely and kill the special-casing in procfs. - */ -static struct vfsmount *pfmfs_mnt __read_mostly; - -static int __init -init_pfm_fs(void) -{ - int err = register_filesystem(&pfm_fs_type); - if (!err) { - pfmfs_mnt = kern_mount(&pfm_fs_type); - err = PTR_ERR(pfmfs_mnt); - if (IS_ERR(pfmfs_mnt)) - unregister_filesystem(&pfm_fs_type); - else - err = 0; - } - return err; -} - -static ssize_t -pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos) -{ - pfm_context_t *ctx; - pfm_msg_t *msg; - ssize_t ret; - unsigned long flags; - DECLARE_WAITQUEUE(wait, current); - if (PFM_IS_FILE(filp) == 0) { - printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current)); - return -EINVAL; - } - - ctx = filp->private_data; - if (ctx == NULL) { - printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", task_pid_nr(current)); - return -EINVAL; - } - - /* - * check even when there is no message - */ - if (size < sizeof(pfm_msg_t)) { - DPRINT(("message is too small ctx=%p (>=%ld)\n", ctx, sizeof(pfm_msg_t))); - return -EINVAL; - } - - PROTECT_CTX(ctx, flags); - - /* - * put ourselves on the wait queue - */ - add_wait_queue(&ctx->ctx_msgq_wait, &wait); - - - for(;;) { - /* - * check wait queue - */ - - set_current_state(TASK_INTERRUPTIBLE); - - DPRINT(("head=%d tail=%d\n", ctx->ctx_msgq_head, ctx->ctx_msgq_tail)); - - ret = 0; - if(PFM_CTXQ_EMPTY(ctx) == 0) break; - - UNPROTECT_CTX(ctx, flags); - - /* - * check non-blocking read - */ - ret = -EAGAIN; - if(filp->f_flags & O_NONBLOCK) break; - - /* - * check pending signals - */ - if(signal_pending(current)) { - ret = -EINTR; - break; - } - /* - * no message, so wait - */ - schedule(); - - PROTECT_CTX(ctx, flags); - } - DPRINT(("[%d] back to running ret=%ld\n", task_pid_nr(current), ret)); - set_current_state(TASK_RUNNING); - remove_wait_queue(&ctx->ctx_msgq_wait, &wait); - - if (ret < 0) goto abort; - - ret = -EINVAL; - msg = pfm_get_next_msg(ctx); - if (msg == NULL) { - printk(KERN_ERR "perfmon: pfm_read no msg for ctx=%p [%d]\n", ctx, task_pid_nr(current)); - goto abort_locked; - } - - DPRINT(("fd=%d type=%d\n", msg->pfm_gen_msg.msg_ctx_fd, msg->pfm_gen_msg.msg_type)); - - ret = -EFAULT; - if(copy_to_user(buf, msg, sizeof(pfm_msg_t)) == 0) ret = sizeof(pfm_msg_t); - -abort_locked: - UNPROTECT_CTX(ctx, flags); -abort: - return ret; -} - -static ssize_t -pfm_write(struct file *file, const char __user *ubuf, - size_t size, loff_t *ppos) -{ - DPRINT(("pfm_write called\n")); - return -EINVAL; -} - -static __poll_t -pfm_poll(struct file *filp, poll_table * wait) -{ - pfm_context_t *ctx; - unsigned long flags; - __poll_t mask = 0; - - if (PFM_IS_FILE(filp) == 0) { - printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current)); - return 0; - } - - ctx = filp->private_data; - if (ctx == NULL) { - printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", task_pid_nr(current)); - return 0; - } - - - DPRINT(("pfm_poll ctx_fd=%d before poll_wait\n", ctx->ctx_fd)); - - poll_wait(filp, &ctx->ctx_msgq_wait, wait); - - PROTECT_CTX(ctx, flags); - - if (PFM_CTXQ_EMPTY(ctx) == 0) - mask = EPOLLIN | EPOLLRDNORM; - - UNPROTECT_CTX(ctx, flags); - - DPRINT(("pfm_poll ctx_fd=%d mask=0x%x\n", ctx->ctx_fd, mask)); - - return mask; -} - -static long -pfm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - DPRINT(("pfm_ioctl called\n")); - return -EINVAL; -} - -/* - * interrupt cannot be masked when coming here - */ -static inline int -pfm_do_fasync(int fd, struct file *filp, pfm_context_t *ctx, int on) -{ - int ret; - - ret = fasync_helper (fd, filp, on, &ctx->ctx_async_queue); - - DPRINT(("pfm_fasync called by [%d] on ctx_fd=%d on=%d async_queue=%p ret=%d\n", - task_pid_nr(current), - fd, - on, - ctx->ctx_async_queue, ret)); - - return ret; -} - -static int -pfm_fasync(int fd, struct file *filp, int on) -{ - pfm_context_t *ctx; - int ret; - - if (PFM_IS_FILE(filp) == 0) { - printk(KERN_ERR "perfmon: pfm_fasync bad magic [%d]\n", task_pid_nr(current)); - return -EBADF; - } - - ctx = filp->private_data; - if (ctx == NULL) { - printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", task_pid_nr(current)); - return -EBADF; - } - /* - * we cannot mask interrupts during this call because this may - * may go to sleep if memory is not readily avalaible. - * - * We are protected from the conetxt disappearing by the get_fd()/put_fd() - * done in caller. Serialization of this function is ensured by caller. - */ - ret = pfm_do_fasync(fd, filp, ctx, on); - - - DPRINT(("pfm_fasync called on ctx_fd=%d on=%d async_queue=%p ret=%d\n", - fd, - on, - ctx->ctx_async_queue, ret)); - - return ret; -} - -#ifdef CONFIG_SMP -/* - * this function is exclusively called from pfm_close(). - * The context is not protected at that time, nor are interrupts - * on the remote CPU. That's necessary to avoid deadlocks. - */ -static void -pfm_syswide_force_stop(void *info) -{ - pfm_context_t *ctx = (pfm_context_t *)info; - struct pt_regs *regs = task_pt_regs(current); - struct task_struct *owner; - unsigned long flags; - int ret; - - if (ctx->ctx_cpu != smp_processor_id()) { - printk(KERN_ERR "perfmon: pfm_syswide_force_stop for CPU%d but on CPU%d\n", - ctx->ctx_cpu, - smp_processor_id()); - return; - } - owner = GET_PMU_OWNER(); - if (owner != ctx->ctx_task) { - printk(KERN_ERR "perfmon: pfm_syswide_force_stop CPU%d unexpected owner [%d] instead of [%d]\n", - smp_processor_id(), - task_pid_nr(owner), task_pid_nr(ctx->ctx_task)); - return; - } - if (GET_PMU_CTX() != ctx) { - printk(KERN_ERR "perfmon: pfm_syswide_force_stop CPU%d unexpected ctx %p instead of %p\n", - smp_processor_id(), - GET_PMU_CTX(), ctx); - return; - } - - DPRINT(("on CPU%d forcing system wide stop for [%d]\n", smp_processor_id(), task_pid_nr(ctx->ctx_task))); - /* - * the context is already protected in pfm_close(), we simply - * need to mask interrupts to avoid a PMU interrupt race on - * this CPU - */ - local_irq_save(flags); - - ret = pfm_context_unload(ctx, NULL, 0, regs); - if (ret) { - DPRINT(("context_unload returned %d\n", ret)); - } - - /* - * unmask interrupts, PMU interrupts are now spurious here - */ - local_irq_restore(flags); -} - -static void -pfm_syswide_cleanup_other_cpu(pfm_context_t *ctx) -{ - int ret; - - DPRINT(("calling CPU%d for cleanup\n", ctx->ctx_cpu)); - ret = smp_call_function_single(ctx->ctx_cpu, pfm_syswide_force_stop, ctx, 1); - DPRINT(("called CPU%d for cleanup ret=%d\n", ctx->ctx_cpu, ret)); -} -#endif /* CONFIG_SMP */ - -/* - * called for each close(). Partially free resources. - * When caller is self-monitoring, the context is unloaded. - */ -static int -pfm_flush(struct file *filp, fl_owner_t id) -{ - pfm_context_t *ctx; - struct task_struct *task; - struct pt_regs *regs; - unsigned long flags; - unsigned long smpl_buf_size = 0UL; - void *smpl_buf_vaddr = NULL; - int state, is_system; - - if (PFM_IS_FILE(filp) == 0) { - DPRINT(("bad magic for\n")); - return -EBADF; - } - - ctx = filp->private_data; - if (ctx == NULL) { - printk(KERN_ERR "perfmon: pfm_flush: NULL ctx [%d]\n", task_pid_nr(current)); - return -EBADF; - } - - /* - * remove our file from the async queue, if we use this mode. - * This can be done without the context being protected. We come - * here when the context has become unreachable by other tasks. - * - * We may still have active monitoring at this point and we may - * end up in pfm_overflow_handler(). However, fasync_helper() - * operates with interrupts disabled and it cleans up the - * queue. If the PMU handler is called prior to entering - * fasync_helper() then it will send a signal. If it is - * invoked after, it will find an empty queue and no - * signal will be sent. In both case, we are safe - */ - PROTECT_CTX(ctx, flags); - - state = ctx->ctx_state; - is_system = ctx->ctx_fl_system; - - task = PFM_CTX_TASK(ctx); - regs = task_pt_regs(task); - - DPRINT(("ctx_state=%d is_current=%d\n", - state, - task == current ? 1 : 0)); - - /* - * if state == UNLOADED, then task is NULL - */ - - /* - * we must stop and unload because we are losing access to the context. - */ - if (task == current) { -#ifdef CONFIG_SMP - /* - * the task IS the owner but it migrated to another CPU: that's bad - * but we must handle this cleanly. Unfortunately, the kernel does - * not provide a mechanism to block migration (while the context is loaded). - * - * We need to release the resource on the ORIGINAL cpu. - */ - if (is_system && ctx->ctx_cpu != smp_processor_id()) { - - DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu)); - /* - * keep context protected but unmask interrupt for IPI - */ - local_irq_restore(flags); - - pfm_syswide_cleanup_other_cpu(ctx); - - /* - * restore interrupt masking - */ - local_irq_save(flags); - - /* - * context is unloaded at this point - */ - } else -#endif /* CONFIG_SMP */ - { - - DPRINT(("forcing unload\n")); - /* - * stop and unload, returning with state UNLOADED - * and session unreserved. - */ - pfm_context_unload(ctx, NULL, 0, regs); - - DPRINT(("ctx_state=%d\n", ctx->ctx_state)); - } - } - - /* - * remove virtual mapping, if any, for the calling task. - * cannot reset ctx field until last user is calling close(). - * - * ctx_smpl_vaddr must never be cleared because it is needed - * by every task with access to the context - * - * When called from do_exit(), the mm context is gone already, therefore - * mm is NULL, i.e., the VMA is already gone and we do not have to - * do anything here - */ - if (ctx->ctx_smpl_vaddr && current->mm) { - smpl_buf_vaddr = ctx->ctx_smpl_vaddr; - smpl_buf_size = ctx->ctx_smpl_size; - } - - UNPROTECT_CTX(ctx, flags); - - /* - * if there was a mapping, then we systematically remove it - * at this point. Cannot be done inside critical section - * because some VM function reenables interrupts. - * - */ - if (smpl_buf_vaddr) pfm_remove_smpl_mapping(smpl_buf_vaddr, smpl_buf_size); - - return 0; -} -/* - * called either on explicit close() or from exit_files(). - * Only the LAST user of the file gets to this point, i.e., it is - * called only ONCE. - * - * IMPORTANT: we get called ONLY when the refcnt on the file gets to zero - * (fput()),i.e, last task to access the file. Nobody else can access the - * file at this point. - * - * When called from exit_files(), the VMA has been freed because exit_mm() - * is executed before exit_files(). - * - * When called from exit_files(), the current task is not yet ZOMBIE but we - * flush the PMU state to the context. - */ -static int -pfm_close(struct inode *inode, struct file *filp) -{ - pfm_context_t *ctx; - struct task_struct *task; - struct pt_regs *regs; - DECLARE_WAITQUEUE(wait, current); - unsigned long flags; - unsigned long smpl_buf_size = 0UL; - void *smpl_buf_addr = NULL; - int free_possible = 1; - int state, is_system; - - DPRINT(("pfm_close called private=%p\n", filp->private_data)); - - if (PFM_IS_FILE(filp) == 0) { - DPRINT(("bad magic\n")); - return -EBADF; - } - - ctx = filp->private_data; - if (ctx == NULL) { - printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", task_pid_nr(current)); - return -EBADF; - } - - PROTECT_CTX(ctx, flags); - - state = ctx->ctx_state; - is_system = ctx->ctx_fl_system; - - task = PFM_CTX_TASK(ctx); - regs = task_pt_regs(task); - - DPRINT(("ctx_state=%d is_current=%d\n", - state, - task == current ? 1 : 0)); - - /* - * if task == current, then pfm_flush() unloaded the context - */ - if (state == PFM_CTX_UNLOADED) goto doit; - - /* - * context is loaded/masked and task != current, we need to - * either force an unload or go zombie - */ - - /* - * The task is currently blocked or will block after an overflow. - * we must force it to wakeup to get out of the - * MASKED state and transition to the unloaded state by itself. - * - * This situation is only possible for per-task mode - */ - if (state == PFM_CTX_MASKED && CTX_OVFL_NOBLOCK(ctx) == 0) { - - /* - * set a "partial" zombie state to be checked - * upon return from down() in pfm_handle_work(). - * - * We cannot use the ZOMBIE state, because it is checked - * by pfm_load_regs() which is called upon wakeup from down(). - * In such case, it would free the context and then we would - * return to pfm_handle_work() which would access the - * stale context. Instead, we set a flag invisible to pfm_load_regs() - * but visible to pfm_handle_work(). - * - * For some window of time, we have a zombie context with - * ctx_state = MASKED and not ZOMBIE - */ - ctx->ctx_fl_going_zombie = 1; - - /* - * force task to wake up from MASKED state - */ - complete(&ctx->ctx_restart_done); - - DPRINT(("waking up ctx_state=%d\n", state)); - - /* - * put ourself to sleep waiting for the other - * task to report completion - * - * the context is protected by mutex, therefore there - * is no risk of being notified of completion before - * begin actually on the waitq. - */ - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&ctx->ctx_zombieq, &wait); - - UNPROTECT_CTX(ctx, flags); - - /* - * XXX: check for signals : - * - ok for explicit close - * - not ok when coming from exit_files() - */ - schedule(); - - - PROTECT_CTX(ctx, flags); - - - remove_wait_queue(&ctx->ctx_zombieq, &wait); - set_current_state(TASK_RUNNING); - - /* - * context is unloaded at this point - */ - DPRINT(("after zombie wakeup ctx_state=%d for\n", state)); - } - else if (task != current) { -#ifdef CONFIG_SMP - /* - * switch context to zombie state - */ - ctx->ctx_state = PFM_CTX_ZOMBIE; - - DPRINT(("zombie ctx for [%d]\n", task_pid_nr(task))); - /* - * cannot free the context on the spot. deferred until - * the task notices the ZOMBIE state - */ - free_possible = 0; -#else - pfm_context_unload(ctx, NULL, 0, regs); -#endif - } - -doit: - /* reload state, may have changed during opening of critical section */ - state = ctx->ctx_state; - - /* - * the context is still attached to a task (possibly current) - * we cannot destroy it right now - */ - - /* - * we must free the sampling buffer right here because - * we cannot rely on it being cleaned up later by the - * monitored task. It is not possible to free vmalloc'ed - * memory in pfm_load_regs(). Instead, we remove the buffer - * now. should there be subsequent PMU overflow originally - * meant for sampling, the will be converted to spurious - * and that's fine because the monitoring tools is gone anyway. - */ - if (ctx->ctx_smpl_hdr) { - smpl_buf_addr = ctx->ctx_smpl_hdr; - smpl_buf_size = ctx->ctx_smpl_size; - /* no more sampling */ - ctx->ctx_smpl_hdr = NULL; - ctx->ctx_fl_is_sampling = 0; - } - - DPRINT(("ctx_state=%d free_possible=%d addr=%p size=%lu\n", - state, - free_possible, - smpl_buf_addr, - smpl_buf_size)); - - if (smpl_buf_addr) pfm_exit_smpl_buffer(ctx->ctx_buf_fmt); - - /* - * UNLOADED that the session has already been unreserved. - */ - if (state == PFM_CTX_ZOMBIE) { - pfm_unreserve_session(ctx, ctx->ctx_fl_system , ctx->ctx_cpu); - } - - /* - * disconnect file descriptor from context must be done - * before we unlock. - */ - filp->private_data = NULL; - - /* - * if we free on the spot, the context is now completely unreachable - * from the callers side. The monitored task side is also cut, so we - * can freely cut. - * - * If we have a deferred free, only the caller side is disconnected. - */ - UNPROTECT_CTX(ctx, flags); - - /* - * All memory free operations (especially for vmalloc'ed memory) - * MUST be done with interrupts ENABLED. - */ - vfree(smpl_buf_addr); - - /* - * return the memory used by the context - */ - if (free_possible) pfm_context_free(ctx); - - return 0; -} - -static const struct file_operations pfm_file_ops = { - .llseek = no_llseek, - .read = pfm_read, - .write = pfm_write, - .poll = pfm_poll, - .unlocked_ioctl = pfm_ioctl, - .fasync = pfm_fasync, - .release = pfm_close, - .flush = pfm_flush -}; - -static char *pfmfs_dname(struct dentry *dentry, char *buffer, int buflen) -{ - return dynamic_dname(dentry, buffer, buflen, "pfm:[%lu]", - d_inode(dentry)->i_ino); -} - -static const struct dentry_operations pfmfs_dentry_operations = { - .d_delete = always_delete_dentry, - .d_dname = pfmfs_dname, -}; - - -static struct file * -pfm_alloc_file(pfm_context_t *ctx) -{ - struct file *file; - struct inode *inode; - struct path path; - struct qstr this = { .name = "" }; - - /* - * allocate a new inode - */ - inode = new_inode(pfmfs_mnt->mnt_sb); - if (!inode) - return ERR_PTR(-ENOMEM); - - DPRINT(("new inode ino=%ld @%p\n", inode->i_ino, inode)); - - inode->i_mode = S_IFCHR|S_IRUGO; - inode->i_uid = current_fsuid(); - inode->i_gid = current_fsgid(); - - /* - * allocate a new dcache entry - */ - path.dentry = d_alloc(pfmfs_mnt->mnt_root, &this); - if (!path.dentry) { - iput(inode); - return ERR_PTR(-ENOMEM); - } - path.mnt = mntget(pfmfs_mnt); - - d_add(path.dentry, inode); - - file = alloc_file(&path, FMODE_READ, &pfm_file_ops); - if (IS_ERR(file)) { - path_put(&path); - return file; - } - - file->f_flags = O_RDONLY; - file->private_data = ctx; - - return file; -} - -static int -pfm_remap_buffer(struct vm_area_struct *vma, unsigned long buf, unsigned long addr, unsigned long size) -{ - DPRINT(("CPU%d buf=0x%lx addr=0x%lx size=%ld\n", smp_processor_id(), buf, addr, size)); - - while (size > 0) { - unsigned long pfn = ia64_tpa(buf) >> PAGE_SHIFT; - - - if (remap_pfn_range(vma, addr, pfn, PAGE_SIZE, PAGE_READONLY)) - return -ENOMEM; - - addr += PAGE_SIZE; - buf += PAGE_SIZE; - size -= PAGE_SIZE; - } - return 0; -} - -/* - * allocate a sampling buffer and remaps it into the user address space of the task - */ -static int -pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t *ctx, unsigned long rsize, void **user_vaddr) -{ - struct mm_struct *mm = task->mm; - struct vm_area_struct *vma = NULL; - unsigned long size; - void *smpl_buf; - - - /* - * the fixed header + requested size and align to page boundary - */ - size = PAGE_ALIGN(rsize); - - DPRINT(("sampling buffer rsize=%lu size=%lu bytes\n", rsize, size)); - - /* - * check requested size to avoid Denial-of-service attacks - * XXX: may have to refine this test - * Check against address space limit. - * - * if ((mm->total_vm << PAGE_SHIFT) + len> task->rlim[RLIMIT_AS].rlim_cur) - * return -ENOMEM; - */ - if (size > task_rlimit(task, RLIMIT_MEMLOCK)) - return -ENOMEM; - - /* - * We do the easy to undo allocations first. - */ - smpl_buf = vzalloc(size); - if (smpl_buf == NULL) { - DPRINT(("Can't allocate sampling buffer\n")); - return -ENOMEM; - } - - DPRINT(("smpl_buf @%p\n", smpl_buf)); - - /* allocate vma */ - vma = vm_area_alloc(mm); - if (!vma) { - DPRINT(("Cannot allocate vma\n")); - goto error_kmem; - } - - /* - * partially initialize the vma for the sampling buffer - */ - vma->vm_file = get_file(filp); - vma->vm_flags = VM_READ|VM_MAYREAD|VM_DONTEXPAND|VM_DONTDUMP; - vma->vm_page_prot = PAGE_READONLY; /* XXX may need to change */ - - /* - * Now we have everything we need and we can initialize - * and connect all the data structures - */ - - ctx->ctx_smpl_hdr = smpl_buf; - ctx->ctx_smpl_size = size; /* aligned size */ - - /* - * Let's do the difficult operations next. - * - * now we atomically find some area in the address space and - * remap the buffer in it. - */ - mmap_write_lock(task->mm); - - /* find some free area in address space, must have mmap sem held */ - vma->vm_start = get_unmapped_area(NULL, 0, size, 0, MAP_PRIVATE|MAP_ANONYMOUS); - if (IS_ERR_VALUE(vma->vm_start)) { - DPRINT(("Cannot find unmapped area for size %ld\n", size)); - mmap_write_unlock(task->mm); - goto error; - } - vma->vm_end = vma->vm_start + size; - vma->vm_pgoff = vma->vm_start >> PAGE_SHIFT; - - DPRINT(("aligned size=%ld, hdr=%p mapped @0x%lx\n", size, ctx->ctx_smpl_hdr, vma->vm_start)); - - /* can only be applied to current task, need to have the mm semaphore held when called */ - if (pfm_remap_buffer(vma, (unsigned long)smpl_buf, vma->vm_start, size)) { - DPRINT(("Can't remap buffer\n")); - mmap_write_unlock(task->mm); - goto error; - } - - /* - * now insert the vma in the vm list for the process, must be - * done with mmap lock held - */ - insert_vm_struct(mm, vma); - - vm_stat_account(vma->vm_mm, vma->vm_flags, vma_pages(vma)); - mmap_write_unlock(task->mm); - - /* - * keep track of user level virtual address - */ - ctx->ctx_smpl_vaddr = (void *)vma->vm_start; - *(unsigned long *)user_vaddr = vma->vm_start; - - return 0; - -error: - vm_area_free(vma); -error_kmem: - vfree(smpl_buf); - - return -ENOMEM; -} - -/* - * XXX: do something better here - */ -static int -pfm_bad_permissions(struct task_struct *task) -{ - const struct cred *tcred; - kuid_t uid = current_uid(); - kgid_t gid = current_gid(); - int ret; - - rcu_read_lock(); - tcred = __task_cred(task); - - /* inspired by ptrace_attach() */ - DPRINT(("cur: uid=%d gid=%d task: euid=%d suid=%d uid=%d egid=%d sgid=%d\n", - from_kuid(&init_user_ns, uid), - from_kgid(&init_user_ns, gid), - from_kuid(&init_user_ns, tcred->euid), - from_kuid(&init_user_ns, tcred->suid), - from_kuid(&init_user_ns, tcred->uid), - from_kgid(&init_user_ns, tcred->egid), - from_kgid(&init_user_ns, tcred->sgid))); - - ret = ((!uid_eq(uid, tcred->euid)) - || (!uid_eq(uid, tcred->suid)) - || (!uid_eq(uid, tcred->uid)) - || (!gid_eq(gid, tcred->egid)) - || (!gid_eq(gid, tcred->sgid)) - || (!gid_eq(gid, tcred->gid))) && !capable(CAP_SYS_PTRACE); - - rcu_read_unlock(); - return ret; -} - -static int -pfarg_is_sane(struct task_struct *task, pfarg_context_t *pfx) -{ - int ctx_flags; - - /* valid signal */ - - ctx_flags = pfx->ctx_flags; - - if (ctx_flags & PFM_FL_SYSTEM_WIDE) { - - /* - * cannot block in this mode - */ - if (ctx_flags & PFM_FL_NOTIFY_BLOCK) { - DPRINT(("cannot use blocking mode when in system wide monitoring\n")); - return -EINVAL; - } - } else { - } - /* probably more to add here */ - - return 0; -} - -static int -pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t *ctx, unsigned int ctx_flags, - unsigned int cpu, pfarg_context_t *arg) -{ - pfm_buffer_fmt_t *fmt = NULL; - unsigned long size = 0UL; - void *uaddr = NULL; - void *fmt_arg = NULL; - int ret = 0; -#define PFM_CTXARG_BUF_ARG(a) (pfm_buffer_fmt_t *)(a+1) - - /* invoke and lock buffer format, if found */ - fmt = pfm_find_buffer_fmt(arg->ctx_smpl_buf_id); - if (fmt == NULL) { - DPRINT(("[%d] cannot find buffer format\n", task_pid_nr(task))); - return -EINVAL; - } - - /* - * buffer argument MUST be contiguous to pfarg_context_t - */ - if (fmt->fmt_arg_size) fmt_arg = PFM_CTXARG_BUF_ARG(arg); - - ret = pfm_buf_fmt_validate(fmt, task, ctx_flags, cpu, fmt_arg); - - DPRINT(("[%d] after validate(0x%x,%d,%p)=%d\n", task_pid_nr(task), ctx_flags, cpu, fmt_arg, ret)); - - if (ret) goto error; - - /* link buffer format and context */ - ctx->ctx_buf_fmt = fmt; - ctx->ctx_fl_is_sampling = 1; /* assume record() is defined */ - - /* - * check if buffer format wants to use perfmon buffer allocation/mapping service - */ - ret = pfm_buf_fmt_getsize(fmt, task, ctx_flags, cpu, fmt_arg, &size); - if (ret) goto error; - - if (size) { - /* - * buffer is always remapped into the caller's address space - */ - ret = pfm_smpl_buffer_alloc(current, filp, ctx, size, &uaddr); - if (ret) goto error; - - /* keep track of user address of buffer */ - arg->ctx_smpl_vaddr = uaddr; - } - ret = pfm_buf_fmt_init(fmt, task, ctx->ctx_smpl_hdr, ctx_flags, cpu, fmt_arg); - -error: - return ret; -} - -static void -pfm_reset_pmu_state(pfm_context_t *ctx) -{ - int i; - - /* - * install reset values for PMC. - */ - for (i=1; PMC_IS_LAST(i) == 0; i++) { - if (PMC_IS_IMPL(i) == 0) continue; - ctx->ctx_pmcs[i] = PMC_DFL_VAL(i); - DPRINT(("pmc[%d]=0x%lx\n", i, ctx->ctx_pmcs[i])); - } - /* - * PMD registers are set to 0UL when the context in memset() - */ - - /* - * On context switched restore, we must restore ALL pmc and ALL pmd even - * when they are not actively used by the task. In UP, the incoming process - * may otherwise pick up left over PMC, PMD state from the previous process. - * As opposed to PMD, stale PMC can cause harm to the incoming - * process because they may change what is being measured. - * Therefore, we must systematically reinstall the entire - * PMC state. In SMP, the same thing is possible on the - * same CPU but also on between 2 CPUs. - * - * The problem with PMD is information leaking especially - * to user level when psr.sp=0 - * - * There is unfortunately no easy way to avoid this problem - * on either UP or SMP. This definitively slows down the - * pfm_load_regs() function. - */ - - /* - * bitmask of all PMCs accessible to this context - * - * PMC0 is treated differently. - */ - ctx->ctx_all_pmcs[0] = pmu_conf->impl_pmcs[0] & ~0x1; - - /* - * bitmask of all PMDs that are accessible to this context - */ - ctx->ctx_all_pmds[0] = pmu_conf->impl_pmds[0]; - - DPRINT(("<%d> all_pmcs=0x%lx all_pmds=0x%lx\n", ctx->ctx_fd, ctx->ctx_all_pmcs[0],ctx->ctx_all_pmds[0])); - - /* - * useful in case of re-enable after disable - */ - ctx->ctx_used_ibrs[0] = 0UL; - ctx->ctx_used_dbrs[0] = 0UL; -} - -static int -pfm_ctx_getsize(void *arg, size_t *sz) -{ - pfarg_context_t *req = (pfarg_context_t *)arg; - pfm_buffer_fmt_t *fmt; - - *sz = 0; - - if (!pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) return 0; - - fmt = pfm_find_buffer_fmt(req->ctx_smpl_buf_id); - if (fmt == NULL) { - DPRINT(("cannot find buffer format\n")); - return -EINVAL; - } - /* get just enough to copy in user parameters */ - *sz = fmt->fmt_arg_size; - DPRINT(("arg_size=%lu\n", *sz)); - - return 0; -} - - - -/* - * cannot attach if : - * - kernel task - * - task not owned by caller - * - task incompatible with context mode - */ -static int -pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task) -{ - /* - * no kernel task or task not owner by caller - */ - if (task->mm == NULL) { - DPRINT(("task [%d] has not memory context (kernel thread)\n", task_pid_nr(task))); - return -EPERM; - } - if (pfm_bad_permissions(task)) { - DPRINT(("no permission to attach to [%d]\n", task_pid_nr(task))); - return -EPERM; - } - /* - * cannot block in self-monitoring mode - */ - if (CTX_OVFL_NOBLOCK(ctx) == 0 && task == current) { - DPRINT(("cannot load a blocking context on self for [%d]\n", task_pid_nr(task))); - return -EINVAL; - } - - if (task->exit_state == EXIT_ZOMBIE) { - DPRINT(("cannot attach to zombie task [%d]\n", task_pid_nr(task))); - return -EBUSY; - } - - /* - * always ok for self - */ - if (task == current) return 0; - - if (!task_is_stopped_or_traced(task)) { - DPRINT(("cannot attach to non-stopped task [%d] state=%ld\n", task_pid_nr(task), task->state)); - return -EBUSY; - } - /* - * make sure the task is off any CPU - */ - wait_task_inactive(task, 0); - - /* more to come... */ - - return 0; -} - -static int -pfm_get_task(pfm_context_t *ctx, pid_t pid, struct task_struct **task) -{ - struct task_struct *p = current; - int ret; - - /* XXX: need to add more checks here */ - if (pid < 2) return -EPERM; - - if (pid != task_pid_vnr(current)) { - /* make sure task cannot go away while we operate on it */ - p = find_get_task_by_vpid(pid); - if (!p) - return -ESRCH; - } - - ret = pfm_task_incompatible(ctx, p); - if (ret == 0) { - *task = p; - } else if (p != current) { - pfm_put_task(p); - } - return ret; -} - - - -static int -pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - pfarg_context_t *req = (pfarg_context_t *)arg; - struct file *filp; - struct path path; - int ctx_flags; - int fd; - int ret; - - /* let's check the arguments first */ - ret = pfarg_is_sane(current, req); - if (ret < 0) - return ret; - - ctx_flags = req->ctx_flags; - - ret = -ENOMEM; - - fd = get_unused_fd_flags(0); - if (fd < 0) - return fd; - - ctx = pfm_context_alloc(ctx_flags); - if (!ctx) - goto error; - - filp = pfm_alloc_file(ctx); - if (IS_ERR(filp)) { - ret = PTR_ERR(filp); - goto error_file; - } - - req->ctx_fd = ctx->ctx_fd = fd; - - /* - * does the user want to sample? - */ - if (pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) { - ret = pfm_setup_buffer_fmt(current, filp, ctx, ctx_flags, 0, req); - if (ret) - goto buffer_error; - } - - DPRINT(("ctx=%p flags=0x%x system=%d notify_block=%d excl_idle=%d no_msg=%d ctx_fd=%d\n", - ctx, - ctx_flags, - ctx->ctx_fl_system, - ctx->ctx_fl_block, - ctx->ctx_fl_excl_idle, - ctx->ctx_fl_no_msg, - ctx->ctx_fd)); - - /* - * initialize soft PMU state - */ - pfm_reset_pmu_state(ctx); - - fd_install(fd, filp); - - return 0; - -buffer_error: - path = filp->f_path; - put_filp(filp); - path_put(&path); - - if (ctx->ctx_buf_fmt) { - pfm_buf_fmt_exit(ctx->ctx_buf_fmt, current, NULL, regs); - } -error_file: - pfm_context_free(ctx); - -error: - put_unused_fd(fd); - return ret; -} - -static inline unsigned long -pfm_new_counter_value (pfm_counter_t *reg, int is_long_reset) -{ - unsigned long val = is_long_reset ? reg->long_reset : reg->short_reset; - unsigned long new_seed, old_seed = reg->seed, mask = reg->mask; - extern unsigned long carta_random32 (unsigned long seed); - - if (reg->flags & PFM_REGFL_RANDOM) { - new_seed = carta_random32(old_seed); - val -= (old_seed & mask); /* counter values are negative numbers! */ - if ((mask >> 32) != 0) - /* construct a full 64-bit random value: */ - new_seed |= carta_random32(old_seed >> 32) << 32; - reg->seed = new_seed; - } - reg->lval = val; - return val; -} - -static void -pfm_reset_regs_masked(pfm_context_t *ctx, unsigned long *ovfl_regs, int is_long_reset) -{ - unsigned long mask = ovfl_regs[0]; - unsigned long reset_others = 0UL; - unsigned long val; - int i; - - /* - * now restore reset value on sampling overflowed counters - */ - mask >>= PMU_FIRST_COUNTER; - for(i = PMU_FIRST_COUNTER; mask; i++, mask >>= 1) { - - if ((mask & 0x1UL) == 0UL) continue; - - ctx->ctx_pmds[i].val = val = pfm_new_counter_value(ctx->ctx_pmds+ i, is_long_reset); - reset_others |= ctx->ctx_pmds[i].reset_pmds[0]; - - DPRINT_ovfl((" %s reset ctx_pmds[%d]=%lx\n", is_long_reset ? "long" : "short", i, val)); - } - - /* - * Now take care of resetting the other registers - */ - for(i = 0; reset_others; i++, reset_others >>= 1) { - - if ((reset_others & 0x1) == 0) continue; - - ctx->ctx_pmds[i].val = val = pfm_new_counter_value(ctx->ctx_pmds + i, is_long_reset); - - DPRINT_ovfl(("%s reset_others pmd[%d]=%lx\n", - is_long_reset ? "long" : "short", i, val)); - } -} - -static void -pfm_reset_regs(pfm_context_t *ctx, unsigned long *ovfl_regs, int is_long_reset) -{ - unsigned long mask = ovfl_regs[0]; - unsigned long reset_others = 0UL; - unsigned long val; - int i; - - DPRINT_ovfl(("ovfl_regs=0x%lx is_long_reset=%d\n", ovfl_regs[0], is_long_reset)); - - if (ctx->ctx_state == PFM_CTX_MASKED) { - pfm_reset_regs_masked(ctx, ovfl_regs, is_long_reset); - return; - } - - /* - * now restore reset value on sampling overflowed counters - */ - mask >>= PMU_FIRST_COUNTER; - for(i = PMU_FIRST_COUNTER; mask; i++, mask >>= 1) { - - if ((mask & 0x1UL) == 0UL) continue; - - val = pfm_new_counter_value(ctx->ctx_pmds+ i, is_long_reset); - reset_others |= ctx->ctx_pmds[i].reset_pmds[0]; - - DPRINT_ovfl((" %s reset ctx_pmds[%d]=%lx\n", is_long_reset ? "long" : "short", i, val)); - - pfm_write_soft_counter(ctx, i, val); - } - - /* - * Now take care of resetting the other registers - */ - for(i = 0; reset_others; i++, reset_others >>= 1) { - - if ((reset_others & 0x1) == 0) continue; - - val = pfm_new_counter_value(ctx->ctx_pmds + i, is_long_reset); - - if (PMD_IS_COUNTING(i)) { - pfm_write_soft_counter(ctx, i, val); - } else { - ia64_set_pmd(i, val); - } - DPRINT_ovfl(("%s reset_others pmd[%d]=%lx\n", - is_long_reset ? "long" : "short", i, val)); - } - ia64_srlz_d(); -} - -static int -pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - struct task_struct *task; - pfarg_reg_t *req = (pfarg_reg_t *)arg; - unsigned long value, pmc_pm; - unsigned long smpl_pmds, reset_pmds, impl_pmds; - unsigned int cnum, reg_flags, flags, pmc_type; - int i, can_access_pmu = 0, is_loaded, is_system, expert_mode; - int is_monitor, is_counting, state; - int ret = -EINVAL; - pfm_reg_check_t wr_func; -#define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z)) - - state = ctx->ctx_state; - is_loaded = state == PFM_CTX_LOADED ? 1 : 0; - is_system = ctx->ctx_fl_system; - task = ctx->ctx_task; - impl_pmds = pmu_conf->impl_pmds[0]; - - if (state == PFM_CTX_ZOMBIE) return -EINVAL; - - if (is_loaded) { - /* - * In system wide and when the context is loaded, access can only happen - * when the caller is running on the CPU being monitored by the session. - * It does not have to be the owner (ctx_task) of the context per se. - */ - if (is_system && ctx->ctx_cpu != smp_processor_id()) { - DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu)); - return -EBUSY; - } - can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0; - } - expert_mode = pfm_sysctl.expert_mode; - - for (i = 0; i < count; i++, req++) { - - cnum = req->reg_num; - reg_flags = req->reg_flags; - value = req->reg_value; - smpl_pmds = req->reg_smpl_pmds[0]; - reset_pmds = req->reg_reset_pmds[0]; - flags = 0; - - - if (cnum >= PMU_MAX_PMCS) { - DPRINT(("pmc%u is invalid\n", cnum)); - goto error; - } - - pmc_type = pmu_conf->pmc_desc[cnum].type; - pmc_pm = (value >> pmu_conf->pmc_desc[cnum].pm_pos) & 0x1; - is_counting = (pmc_type & PFM_REG_COUNTING) == PFM_REG_COUNTING ? 1 : 0; - is_monitor = (pmc_type & PFM_REG_MONITOR) == PFM_REG_MONITOR ? 1 : 0; - - /* - * we reject all non implemented PMC as well - * as attempts to modify PMC[0-3] which are used - * as status registers by the PMU - */ - if ((pmc_type & PFM_REG_IMPL) == 0 || (pmc_type & PFM_REG_CONTROL) == PFM_REG_CONTROL) { - DPRINT(("pmc%u is unimplemented or no-access pmc_type=%x\n", cnum, pmc_type)); - goto error; - } - wr_func = pmu_conf->pmc_desc[cnum].write_check; - /* - * If the PMC is a monitor, then if the value is not the default: - * - system-wide session: PMCx.pm=1 (privileged monitor) - * - per-task : PMCx.pm=0 (user monitor) - */ - if (is_monitor && value != PMC_DFL_VAL(cnum) && is_system ^ pmc_pm) { - DPRINT(("pmc%u pmc_pm=%lu is_system=%d\n", - cnum, - pmc_pm, - is_system)); - goto error; - } - - if (is_counting) { - /* - * enforce generation of overflow interrupt. Necessary on all - * CPUs. - */ - value |= 1 << PMU_PMC_OI; - - if (reg_flags & PFM_REGFL_OVFL_NOTIFY) { - flags |= PFM_REGFL_OVFL_NOTIFY; - } - - if (reg_flags & PFM_REGFL_RANDOM) flags |= PFM_REGFL_RANDOM; - - /* verify validity of smpl_pmds */ - if ((smpl_pmds & impl_pmds) != smpl_pmds) { - DPRINT(("invalid smpl_pmds 0x%lx for pmc%u\n", smpl_pmds, cnum)); - goto error; - } - - /* verify validity of reset_pmds */ - if ((reset_pmds & impl_pmds) != reset_pmds) { - DPRINT(("invalid reset_pmds 0x%lx for pmc%u\n", reset_pmds, cnum)); - goto error; - } - } else { - if (reg_flags & (PFM_REGFL_OVFL_NOTIFY|PFM_REGFL_RANDOM)) { - DPRINT(("cannot set ovfl_notify or random on pmc%u\n", cnum)); - goto error; - } - /* eventid on non-counting monitors are ignored */ - } - - /* - * execute write checker, if any - */ - if (likely(expert_mode == 0 && wr_func)) { - ret = (*wr_func)(task, ctx, cnum, &value, regs); - if (ret) goto error; - ret = -EINVAL; - } - - /* - * no error on this register - */ - PFM_REG_RETFLAG_SET(req->reg_flags, 0); - - /* - * Now we commit the changes to the software state - */ - - /* - * update overflow information - */ - if (is_counting) { - /* - * full flag update each time a register is programmed - */ - ctx->ctx_pmds[cnum].flags = flags; - - ctx->ctx_pmds[cnum].reset_pmds[0] = reset_pmds; - ctx->ctx_pmds[cnum].smpl_pmds[0] = smpl_pmds; - ctx->ctx_pmds[cnum].eventid = req->reg_smpl_eventid; - - /* - * Mark all PMDS to be accessed as used. - * - * We do not keep track of PMC because we have to - * systematically restore ALL of them. - * - * We do not update the used_monitors mask, because - * if we have not programmed them, then will be in - * a quiescent state, therefore we will not need to - * mask/restore then when context is MASKED. - */ - CTX_USED_PMD(ctx, reset_pmds); - CTX_USED_PMD(ctx, smpl_pmds); - /* - * make sure we do not try to reset on - * restart because we have established new values - */ - if (state == PFM_CTX_MASKED) ctx->ctx_ovfl_regs[0] &= ~1UL << cnum; - } - /* - * Needed in case the user does not initialize the equivalent - * PMD. Clearing is done indirectly via pfm_reset_pmu_state() so there is no - * possible leak here. - */ - CTX_USED_PMD(ctx, pmu_conf->pmc_desc[cnum].dep_pmd[0]); - - /* - * keep track of the monitor PMC that we are using. - * we save the value of the pmc in ctx_pmcs[] and if - * the monitoring is not stopped for the context we also - * place it in the saved state area so that it will be - * picked up later by the context switch code. - * - * The value in ctx_pmcs[] can only be changed in pfm_write_pmcs(). - * - * The value in th_pmcs[] may be modified on overflow, i.e., when - * monitoring needs to be stopped. - */ - if (is_monitor) CTX_USED_MONITOR(ctx, 1UL << cnum); - - /* - * update context state - */ - ctx->ctx_pmcs[cnum] = value; - - if (is_loaded) { - /* - * write thread state - */ - if (is_system == 0) ctx->th_pmcs[cnum] = value; - - /* - * write hardware register if we can - */ - if (can_access_pmu) { - ia64_set_pmc(cnum, value); - } -#ifdef CONFIG_SMP - else { - /* - * per-task SMP only here - * - * we are guaranteed that the task is not running on the other CPU, - * we indicate that this PMD will need to be reloaded if the task - * is rescheduled on the CPU it ran last on. - */ - ctx->ctx_reload_pmcs[0] |= 1UL << cnum; - } -#endif - } - - DPRINT(("pmc[%u]=0x%lx ld=%d apmu=%d flags=0x%x all_pmcs=0x%lx used_pmds=0x%lx eventid=%ld smpl_pmds=0x%lx reset_pmds=0x%lx reloads_pmcs=0x%lx used_monitors=0x%lx ovfl_regs=0x%lx\n", - cnum, - value, - is_loaded, - can_access_pmu, - flags, - ctx->ctx_all_pmcs[0], - ctx->ctx_used_pmds[0], - ctx->ctx_pmds[cnum].eventid, - smpl_pmds, - reset_pmds, - ctx->ctx_reload_pmcs[0], - ctx->ctx_used_monitors[0], - ctx->ctx_ovfl_regs[0])); - } - - /* - * make sure the changes are visible - */ - if (can_access_pmu) ia64_srlz_d(); - - return 0; -error: - PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL); - return ret; -} - -static int -pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - struct task_struct *task; - pfarg_reg_t *req = (pfarg_reg_t *)arg; - unsigned long value, hw_value, ovfl_mask; - unsigned int cnum; - int i, can_access_pmu = 0, state; - int is_counting, is_loaded, is_system, expert_mode; - int ret = -EINVAL; - pfm_reg_check_t wr_func; - - - state = ctx->ctx_state; - is_loaded = state == PFM_CTX_LOADED ? 1 : 0; - is_system = ctx->ctx_fl_system; - ovfl_mask = pmu_conf->ovfl_val; - task = ctx->ctx_task; - - if (unlikely(state == PFM_CTX_ZOMBIE)) return -EINVAL; - - /* - * on both UP and SMP, we can only write to the PMC when the task is - * the owner of the local PMU. - */ - if (likely(is_loaded)) { - /* - * In system wide and when the context is loaded, access can only happen - * when the caller is running on the CPU being monitored by the session. - * It does not have to be the owner (ctx_task) of the context per se. - */ - if (unlikely(is_system && ctx->ctx_cpu != smp_processor_id())) { - DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu)); - return -EBUSY; - } - can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0; - } - expert_mode = pfm_sysctl.expert_mode; - - for (i = 0; i < count; i++, req++) { - - cnum = req->reg_num; - value = req->reg_value; - - if (!PMD_IS_IMPL(cnum)) { - DPRINT(("pmd[%u] is unimplemented or invalid\n", cnum)); - goto abort_mission; - } - is_counting = PMD_IS_COUNTING(cnum); - wr_func = pmu_conf->pmd_desc[cnum].write_check; - - /* - * execute write checker, if any - */ - if (unlikely(expert_mode == 0 && wr_func)) { - unsigned long v = value; - - ret = (*wr_func)(task, ctx, cnum, &v, regs); - if (ret) goto abort_mission; - - value = v; - ret = -EINVAL; - } - - /* - * no error on this register - */ - PFM_REG_RETFLAG_SET(req->reg_flags, 0); - - /* - * now commit changes to software state - */ - hw_value = value; - - /* - * update virtualized (64bits) counter - */ - if (is_counting) { - /* - * write context state - */ - ctx->ctx_pmds[cnum].lval = value; - - /* - * when context is load we use the split value - */ - if (is_loaded) { - hw_value = value & ovfl_mask; - value = value & ~ovfl_mask; - } - } - /* - * update reset values (not just for counters) - */ - ctx->ctx_pmds[cnum].long_reset = req->reg_long_reset; - ctx->ctx_pmds[cnum].short_reset = req->reg_short_reset; - - /* - * update randomization parameters (not just for counters) - */ - ctx->ctx_pmds[cnum].seed = req->reg_random_seed; - ctx->ctx_pmds[cnum].mask = req->reg_random_mask; - - /* - * update context value - */ - ctx->ctx_pmds[cnum].val = value; - - /* - * Keep track of what we use - * - * We do not keep track of PMC because we have to - * systematically restore ALL of them. - */ - CTX_USED_PMD(ctx, PMD_PMD_DEP(cnum)); - - /* - * mark this PMD register used as well - */ - CTX_USED_PMD(ctx, RDEP(cnum)); - - /* - * make sure we do not try to reset on - * restart because we have established new values - */ - if (is_counting && state == PFM_CTX_MASKED) { - ctx->ctx_ovfl_regs[0] &= ~1UL << cnum; - } - - if (is_loaded) { - /* - * write thread state - */ - if (is_system == 0) ctx->th_pmds[cnum] = hw_value; - - /* - * write hardware register if we can - */ - if (can_access_pmu) { - ia64_set_pmd(cnum, hw_value); - } else { -#ifdef CONFIG_SMP - /* - * we are guaranteed that the task is not running on the other CPU, - * we indicate that this PMD will need to be reloaded if the task - * is rescheduled on the CPU it ran last on. - */ - ctx->ctx_reload_pmds[0] |= 1UL << cnum; -#endif - } - } - - DPRINT(("pmd[%u]=0x%lx ld=%d apmu=%d, hw_value=0x%lx ctx_pmd=0x%lx short_reset=0x%lx " - "long_reset=0x%lx notify=%c seed=0x%lx mask=0x%lx used_pmds=0x%lx reset_pmds=0x%lx reload_pmds=0x%lx all_pmds=0x%lx ovfl_regs=0x%lx\n", - cnum, - value, - is_loaded, - can_access_pmu, - hw_value, - ctx->ctx_pmds[cnum].val, - ctx->ctx_pmds[cnum].short_reset, - ctx->ctx_pmds[cnum].long_reset, - PMC_OVFL_NOTIFY(ctx, cnum) ? 'Y':'N', - ctx->ctx_pmds[cnum].seed, - ctx->ctx_pmds[cnum].mask, - ctx->ctx_used_pmds[0], - ctx->ctx_pmds[cnum].reset_pmds[0], - ctx->ctx_reload_pmds[0], - ctx->ctx_all_pmds[0], - ctx->ctx_ovfl_regs[0])); - } - - /* - * make changes visible - */ - if (can_access_pmu) ia64_srlz_d(); - - return 0; - -abort_mission: - /* - * for now, we have only one possibility for error - */ - PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL); - return ret; -} - -/* - * By the way of PROTECT_CONTEXT(), interrupts are masked while we are in this function. - * Therefore we know, we do not have to worry about the PMU overflow interrupt. If an - * interrupt is delivered during the call, it will be kept pending until we leave, making - * it appears as if it had been generated at the UNPROTECT_CONTEXT(). At least we are - * guaranteed to return consistent data to the user, it may simply be old. It is not - * trivial to treat the overflow while inside the call because you may end up in - * some module sampling buffer code causing deadlocks. - */ -static int -pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - struct task_struct *task; - unsigned long val = 0UL, lval, ovfl_mask, sval; - pfarg_reg_t *req = (pfarg_reg_t *)arg; - unsigned int cnum, reg_flags = 0; - int i, can_access_pmu = 0, state; - int is_loaded, is_system, is_counting, expert_mode; - int ret = -EINVAL; - pfm_reg_check_t rd_func; - - /* - * access is possible when loaded only for - * self-monitoring tasks or in UP mode - */ - - state = ctx->ctx_state; - is_loaded = state == PFM_CTX_LOADED ? 1 : 0; - is_system = ctx->ctx_fl_system; - ovfl_mask = pmu_conf->ovfl_val; - task = ctx->ctx_task; - - if (state == PFM_CTX_ZOMBIE) return -EINVAL; - - if (likely(is_loaded)) { - /* - * In system wide and when the context is loaded, access can only happen - * when the caller is running on the CPU being monitored by the session. - * It does not have to be the owner (ctx_task) of the context per se. - */ - if (unlikely(is_system && ctx->ctx_cpu != smp_processor_id())) { - DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu)); - return -EBUSY; - } - /* - * this can be true when not self-monitoring only in UP - */ - can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0; - - if (can_access_pmu) ia64_srlz_d(); - } - expert_mode = pfm_sysctl.expert_mode; - - DPRINT(("ld=%d apmu=%d ctx_state=%d\n", - is_loaded, - can_access_pmu, - state)); - - /* - * on both UP and SMP, we can only read the PMD from the hardware register when - * the task is the owner of the local PMU. - */ - - for (i = 0; i < count; i++, req++) { - - cnum = req->reg_num; - reg_flags = req->reg_flags; - - if (unlikely(!PMD_IS_IMPL(cnum))) goto error; - /* - * we can only read the register that we use. That includes - * the one we explicitly initialize AND the one we want included - * in the sampling buffer (smpl_regs). - * - * Having this restriction allows optimization in the ctxsw routine - * without compromising security (leaks) - */ - if (unlikely(!CTX_IS_USED_PMD(ctx, cnum))) goto error; - - sval = ctx->ctx_pmds[cnum].val; - lval = ctx->ctx_pmds[cnum].lval; - is_counting = PMD_IS_COUNTING(cnum); - - /* - * If the task is not the current one, then we check if the - * PMU state is still in the local live register due to lazy ctxsw. - * If true, then we read directly from the registers. - */ - if (can_access_pmu){ - val = ia64_get_pmd(cnum); - } else { - /* - * context has been saved - * if context is zombie, then task does not exist anymore. - * In this case, we use the full value saved in the context (pfm_flush_regs()). - */ - val = is_loaded ? ctx->th_pmds[cnum] : 0UL; - } - rd_func = pmu_conf->pmd_desc[cnum].read_check; - - if (is_counting) { - /* - * XXX: need to check for overflow when loaded - */ - val &= ovfl_mask; - val += sval; - } - - /* - * execute read checker, if any - */ - if (unlikely(expert_mode == 0 && rd_func)) { - unsigned long v = val; - ret = (*rd_func)(ctx->ctx_task, ctx, cnum, &v, regs); - if (ret) goto error; - val = v; - ret = -EINVAL; - } - - PFM_REG_RETFLAG_SET(reg_flags, 0); - - DPRINT(("pmd[%u]=0x%lx\n", cnum, val)); - - /* - * update register return value, abort all if problem during copy. - * we only modify the reg_flags field. no check mode is fine because - * access has been verified upfront in sys_perfmonctl(). - */ - req->reg_value = val; - req->reg_flags = reg_flags; - req->reg_last_reset_val = lval; - } - - return 0; - -error: - PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL); - return ret; -} - -int -pfm_mod_write_pmcs(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs) -{ - pfm_context_t *ctx; - - if (req == NULL) return -EINVAL; - - ctx = GET_PMU_CTX(); - - if (ctx == NULL) return -EINVAL; - - /* - * for now limit to current task, which is enough when calling - * from overflow handler - */ - if (task != current && ctx->ctx_fl_system == 0) return -EBUSY; - - return pfm_write_pmcs(ctx, req, nreq, regs); -} -EXPORT_SYMBOL(pfm_mod_write_pmcs); - -int -pfm_mod_read_pmds(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs) -{ - pfm_context_t *ctx; - - if (req == NULL) return -EINVAL; - - ctx = GET_PMU_CTX(); - - if (ctx == NULL) return -EINVAL; - - /* - * for now limit to current task, which is enough when calling - * from overflow handler - */ - if (task != current && ctx->ctx_fl_system == 0) return -EBUSY; - - return pfm_read_pmds(ctx, req, nreq, regs); -} -EXPORT_SYMBOL(pfm_mod_read_pmds); - -/* - * Only call this function when a process it trying to - * write the debug registers (reading is always allowed) - */ -int -pfm_use_debug_registers(struct task_struct *task) -{ - pfm_context_t *ctx = task->thread.pfm_context; - unsigned long flags; - int ret = 0; - - if (pmu_conf->use_rr_dbregs == 0) return 0; - - DPRINT(("called for [%d]\n", task_pid_nr(task))); - - /* - * do it only once - */ - if (task->thread.flags & IA64_THREAD_DBG_VALID) return 0; - - /* - * Even on SMP, we do not need to use an atomic here because - * the only way in is via ptrace() and this is possible only when the - * process is stopped. Even in the case where the ctxsw out is not totally - * completed by the time we come here, there is no way the 'stopped' process - * could be in the middle of fiddling with the pfm_write_ibr_dbr() routine. - * So this is always safe. - */ - if (ctx && ctx->ctx_fl_using_dbreg == 1) return -1; - - LOCK_PFS(flags); - - /* - * We cannot allow setting breakpoints when system wide monitoring - * sessions are using the debug registers. - */ - if (pfm_sessions.pfs_sys_use_dbregs> 0) - ret = -1; - else - pfm_sessions.pfs_ptrace_use_dbregs++; - - DPRINT(("ptrace_use_dbregs=%u sys_use_dbregs=%u by [%d] ret = %d\n", - pfm_sessions.pfs_ptrace_use_dbregs, - pfm_sessions.pfs_sys_use_dbregs, - task_pid_nr(task), ret)); - - UNLOCK_PFS(flags); - - return ret; -} - -/* - * This function is called for every task that exits with the - * IA64_THREAD_DBG_VALID set. This indicates a task which was - * able to use the debug registers for debugging purposes via - * ptrace(). Therefore we know it was not using them for - * performance monitoring, so we only decrement the number - * of "ptraced" debug register users to keep the count up to date - */ -int -pfm_release_debug_registers(struct task_struct *task) -{ - unsigned long flags; - int ret; - - if (pmu_conf->use_rr_dbregs == 0) return 0; - - LOCK_PFS(flags); - if (pfm_sessions.pfs_ptrace_use_dbregs == 0) { - printk(KERN_ERR "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task_pid_nr(task)); - ret = -1; - } else { - pfm_sessions.pfs_ptrace_use_dbregs--; - ret = 0; - } - UNLOCK_PFS(flags); - - return ret; -} - -static int -pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - struct task_struct *task; - pfm_buffer_fmt_t *fmt; - pfm_ovfl_ctrl_t rst_ctrl; - int state, is_system; - int ret = 0; - - state = ctx->ctx_state; - fmt = ctx->ctx_buf_fmt; - is_system = ctx->ctx_fl_system; - task = PFM_CTX_TASK(ctx); - - switch(state) { - case PFM_CTX_MASKED: - break; - case PFM_CTX_LOADED: - if (CTX_HAS_SMPL(ctx) && fmt->fmt_restart_active) break; - fallthrough; - case PFM_CTX_UNLOADED: - case PFM_CTX_ZOMBIE: - DPRINT(("invalid state=%d\n", state)); - return -EBUSY; - default: - DPRINT(("state=%d, cannot operate (no active_restart handler)\n", state)); - return -EINVAL; - } - - /* - * In system wide and when the context is loaded, access can only happen - * when the caller is running on the CPU being monitored by the session. - * It does not have to be the owner (ctx_task) of the context per se. - */ - if (is_system && ctx->ctx_cpu != smp_processor_id()) { - DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu)); - return -EBUSY; - } - - /* sanity check */ - if (unlikely(task == NULL)) { - printk(KERN_ERR "perfmon: [%d] pfm_restart no task\n", task_pid_nr(current)); - return -EINVAL; - } - - if (task == current || is_system) { - - fmt = ctx->ctx_buf_fmt; - - DPRINT(("restarting self %d ovfl=0x%lx\n", - task_pid_nr(task), - ctx->ctx_ovfl_regs[0])); - - if (CTX_HAS_SMPL(ctx)) { - - prefetch(ctx->ctx_smpl_hdr); - - rst_ctrl.bits.mask_monitoring = 0; - rst_ctrl.bits.reset_ovfl_pmds = 0; - - if (state == PFM_CTX_LOADED) - ret = pfm_buf_fmt_restart_active(fmt, task, &rst_ctrl, ctx->ctx_smpl_hdr, regs); - else - ret = pfm_buf_fmt_restart(fmt, task, &rst_ctrl, ctx->ctx_smpl_hdr, regs); - } else { - rst_ctrl.bits.mask_monitoring = 0; - rst_ctrl.bits.reset_ovfl_pmds = 1; - } - - if (ret == 0) { - if (rst_ctrl.bits.reset_ovfl_pmds) - pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_PMD_LONG_RESET); - - if (rst_ctrl.bits.mask_monitoring == 0) { - DPRINT(("resuming monitoring for [%d]\n", task_pid_nr(task))); - - if (state == PFM_CTX_MASKED) pfm_restore_monitoring(task); - } else { - DPRINT(("keeping monitoring stopped for [%d]\n", task_pid_nr(task))); - - // cannot use pfm_stop_monitoring(task, regs); - } - } - /* - * clear overflowed PMD mask to remove any stale information - */ - ctx->ctx_ovfl_regs[0] = 0UL; - - /* - * back to LOADED state - */ - ctx->ctx_state = PFM_CTX_LOADED; - - /* - * XXX: not really useful for self monitoring - */ - ctx->ctx_fl_can_restart = 0; - - return 0; - } - - /* - * restart another task - */ - - /* - * When PFM_CTX_MASKED, we cannot issue a restart before the previous - * one is seen by the task. - */ - if (state == PFM_CTX_MASKED) { - if (ctx->ctx_fl_can_restart == 0) return -EINVAL; - /* - * will prevent subsequent restart before this one is - * seen by other task - */ - ctx->ctx_fl_can_restart = 0; - } - - /* - * if blocking, then post the semaphore is PFM_CTX_MASKED, i.e. - * the task is blocked or on its way to block. That's the normal - * restart path. If the monitoring is not masked, then the task - * can be actively monitoring and we cannot directly intervene. - * Therefore we use the trap mechanism to catch the task and - * force it to reset the buffer/reset PMDs. - * - * if non-blocking, then we ensure that the task will go into - * pfm_handle_work() before returning to user mode. - * - * We cannot explicitly reset another task, it MUST always - * be done by the task itself. This works for system wide because - * the tool that is controlling the session is logically doing - * "self-monitoring". - */ - if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) { - DPRINT(("unblocking [%d]\n", task_pid_nr(task))); - complete(&ctx->ctx_restart_done); - } else { - DPRINT(("[%d] armed exit trap\n", task_pid_nr(task))); - - ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_RESET; - - PFM_SET_WORK_PENDING(task, 1); - - set_notify_resume(task); - - /* - * XXX: send reschedule if task runs on another CPU - */ - } - return 0; -} - -static int -pfm_debug(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - unsigned int m = *(unsigned int *)arg; - - pfm_sysctl.debug = m == 0 ? 0 : 1; - - printk(KERN_INFO "perfmon debugging %s (timing reset)\n", pfm_sysctl.debug ? "on" : "off"); - - if (m == 0) { - memset(pfm_stats, 0, sizeof(pfm_stats)); - for(m=0; m < NR_CPUS; m++) pfm_stats[m].pfm_ovfl_intr_cycles_min = ~0UL; - } - return 0; -} - -/* - * arg can be NULL and count can be zero for this function - */ -static int -pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - struct thread_struct *thread = NULL; - struct task_struct *task; - pfarg_dbreg_t *req = (pfarg_dbreg_t *)arg; - unsigned long flags; - dbreg_t dbreg; - unsigned int rnum; - int first_time; - int ret = 0, state; - int i, can_access_pmu = 0; - int is_system, is_loaded; - - if (pmu_conf->use_rr_dbregs == 0) return -EINVAL; - - state = ctx->ctx_state; - is_loaded = state == PFM_CTX_LOADED ? 1 : 0; - is_system = ctx->ctx_fl_system; - task = ctx->ctx_task; - - if (state == PFM_CTX_ZOMBIE) return -EINVAL; - - /* - * on both UP and SMP, we can only write to the PMC when the task is - * the owner of the local PMU. - */ - if (is_loaded) { - thread = &task->thread; - /* - * In system wide and when the context is loaded, access can only happen - * when the caller is running on the CPU being monitored by the session. - * It does not have to be the owner (ctx_task) of the context per se. - */ - if (unlikely(is_system && ctx->ctx_cpu != smp_processor_id())) { - DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu)); - return -EBUSY; - } - can_access_pmu = GET_PMU_OWNER() == task || is_system ? 1 : 0; - } - - /* - * we do not need to check for ipsr.db because we do clear ibr.x, dbr.r, and dbr.w - * ensuring that no real breakpoint can be installed via this call. - * - * IMPORTANT: regs can be NULL in this function - */ - - first_time = ctx->ctx_fl_using_dbreg == 0; - - /* - * don't bother if we are loaded and task is being debugged - */ - if (is_loaded && (thread->flags & IA64_THREAD_DBG_VALID) != 0) { - DPRINT(("debug registers already in use for [%d]\n", task_pid_nr(task))); - return -EBUSY; - } - - /* - * check for debug registers in system wide mode - * - * If though a check is done in pfm_context_load(), - * we must repeat it here, in case the registers are - * written after the context is loaded - */ - if (is_loaded) { - LOCK_PFS(flags); - - if (first_time && is_system) { - if (pfm_sessions.pfs_ptrace_use_dbregs) - ret = -EBUSY; - else - pfm_sessions.pfs_sys_use_dbregs++; - } - UNLOCK_PFS(flags); - } - - if (ret != 0) return ret; - - /* - * mark ourself as user of the debug registers for - * perfmon purposes. - */ - ctx->ctx_fl_using_dbreg = 1; - - /* - * clear hardware registers to make sure we don't - * pick up stale state. - * - * for a system wide session, we do not use - * thread.dbr, thread.ibr because this process - * never leaves the current CPU and the state - * is shared by all processes running on it - */ - if (first_time && can_access_pmu) { - DPRINT(("[%d] clearing ibrs, dbrs\n", task_pid_nr(task))); - for (i=0; i < pmu_conf->num_ibrs; i++) { - ia64_set_ibr(i, 0UL); - ia64_dv_serialize_instruction(); - } - ia64_srlz_i(); - for (i=0; i < pmu_conf->num_dbrs; i++) { - ia64_set_dbr(i, 0UL); - ia64_dv_serialize_data(); - } - ia64_srlz_d(); - } - - /* - * Now install the values into the registers - */ - for (i = 0; i < count; i++, req++) { - - rnum = req->dbreg_num; - dbreg.val = req->dbreg_value; - - ret = -EINVAL; - - if ((mode == PFM_CODE_RR && rnum >= PFM_NUM_IBRS) || ((mode == PFM_DATA_RR) && rnum >= PFM_NUM_DBRS)) { - DPRINT(("invalid register %u val=0x%lx mode=%d i=%d count=%d\n", - rnum, dbreg.val, mode, i, count)); - - goto abort_mission; - } - - /* - * make sure we do not install enabled breakpoint - */ - if (rnum & 0x1) { - if (mode == PFM_CODE_RR) - dbreg.ibr.ibr_x = 0; - else - dbreg.dbr.dbr_r = dbreg.dbr.dbr_w = 0; - } - - PFM_REG_RETFLAG_SET(req->dbreg_flags, 0); - - /* - * Debug registers, just like PMC, can only be modified - * by a kernel call. Moreover, perfmon() access to those - * registers are centralized in this routine. The hardware - * does not modify the value of these registers, therefore, - * if we save them as they are written, we can avoid having - * to save them on context switch out. This is made possible - * by the fact that when perfmon uses debug registers, ptrace() - * won't be able to modify them concurrently. - */ - if (mode == PFM_CODE_RR) { - CTX_USED_IBR(ctx, rnum); - - if (can_access_pmu) { - ia64_set_ibr(rnum, dbreg.val); - ia64_dv_serialize_instruction(); - } - - ctx->ctx_ibrs[rnum] = dbreg.val; - - DPRINT(("write ibr%u=0x%lx used_ibrs=0x%x ld=%d apmu=%d\n", - rnum, dbreg.val, ctx->ctx_used_ibrs[0], is_loaded, can_access_pmu)); - } else { - CTX_USED_DBR(ctx, rnum); - - if (can_access_pmu) { - ia64_set_dbr(rnum, dbreg.val); - ia64_dv_serialize_data(); - } - ctx->ctx_dbrs[rnum] = dbreg.val; - - DPRINT(("write dbr%u=0x%lx used_dbrs=0x%x ld=%d apmu=%d\n", - rnum, dbreg.val, ctx->ctx_used_dbrs[0], is_loaded, can_access_pmu)); - } - } - - return 0; - -abort_mission: - /* - * in case it was our first attempt, we undo the global modifications - */ - if (first_time) { - LOCK_PFS(flags); - if (ctx->ctx_fl_system) { - pfm_sessions.pfs_sys_use_dbregs--; - } - UNLOCK_PFS(flags); - ctx->ctx_fl_using_dbreg = 0; - } - /* - * install error return flag - */ - PFM_REG_RETFLAG_SET(req->dbreg_flags, PFM_REG_RETFL_EINVAL); - - return ret; -} - -static int -pfm_write_ibrs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - return pfm_write_ibr_dbr(PFM_CODE_RR, ctx, arg, count, regs); -} - -static int -pfm_write_dbrs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - return pfm_write_ibr_dbr(PFM_DATA_RR, ctx, arg, count, regs); -} - -int -pfm_mod_write_ibrs(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs) -{ - pfm_context_t *ctx; - - if (req == NULL) return -EINVAL; - - ctx = GET_PMU_CTX(); - - if (ctx == NULL) return -EINVAL; - - /* - * for now limit to current task, which is enough when calling - * from overflow handler - */ - if (task != current && ctx->ctx_fl_system == 0) return -EBUSY; - - return pfm_write_ibrs(ctx, req, nreq, regs); -} -EXPORT_SYMBOL(pfm_mod_write_ibrs); - -int -pfm_mod_write_dbrs(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs) -{ - pfm_context_t *ctx; - - if (req == NULL) return -EINVAL; - - ctx = GET_PMU_CTX(); - - if (ctx == NULL) return -EINVAL; - - /* - * for now limit to current task, which is enough when calling - * from overflow handler - */ - if (task != current && ctx->ctx_fl_system == 0) return -EBUSY; - - return pfm_write_dbrs(ctx, req, nreq, regs); -} -EXPORT_SYMBOL(pfm_mod_write_dbrs); - - -static int -pfm_get_features(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - pfarg_features_t *req = (pfarg_features_t *)arg; - - req->ft_version = PFM_VERSION; - return 0; -} - -static int -pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - struct pt_regs *tregs; - struct task_struct *task = PFM_CTX_TASK(ctx); - int state, is_system; - - state = ctx->ctx_state; - is_system = ctx->ctx_fl_system; - - /* - * context must be attached to issue the stop command (includes LOADED,MASKED,ZOMBIE) - */ - if (state == PFM_CTX_UNLOADED) return -EINVAL; - - /* - * In system wide and when the context is loaded, access can only happen - * when the caller is running on the CPU being monitored by the session. - * It does not have to be the owner (ctx_task) of the context per se. - */ - if (is_system && ctx->ctx_cpu != smp_processor_id()) { - DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu)); - return -EBUSY; - } - DPRINT(("task [%d] ctx_state=%d is_system=%d\n", - task_pid_nr(PFM_CTX_TASK(ctx)), - state, - is_system)); - /* - * in system mode, we need to update the PMU directly - * and the user level state of the caller, which may not - * necessarily be the creator of the context. - */ - if (is_system) { - /* - * Update local PMU first - * - * disable dcr pp - */ - ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) & ~IA64_DCR_PP); - ia64_srlz_i(); - - /* - * update local cpuinfo - */ - PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP); - - /* - * stop monitoring, does srlz.i - */ - pfm_clear_psr_pp(); - - /* - * stop monitoring in the caller - */ - ia64_psr(regs)->pp = 0; - - return 0; - } - /* - * per-task mode - */ - - if (task == current) { - /* stop monitoring at kernel level */ - pfm_clear_psr_up(); - - /* - * stop monitoring at the user level - */ - ia64_psr(regs)->up = 0; - } else { - tregs = task_pt_regs(task); - - /* - * stop monitoring at the user level - */ - ia64_psr(tregs)->up = 0; - - /* - * monitoring disabled in kernel at next reschedule - */ - ctx->ctx_saved_psr_up = 0; - DPRINT(("task=[%d]\n", task_pid_nr(task))); - } - return 0; -} - - -static int -pfm_start(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - struct pt_regs *tregs; - int state, is_system; - - state = ctx->ctx_state; - is_system = ctx->ctx_fl_system; - - if (state != PFM_CTX_LOADED) return -EINVAL; - - /* - * In system wide and when the context is loaded, access can only happen - * when the caller is running on the CPU being monitored by the session. - * It does not have to be the owner (ctx_task) of the context per se. - */ - if (is_system && ctx->ctx_cpu != smp_processor_id()) { - DPRINT(("should be running on CPU%d\n", ctx->ctx_cpu)); - return -EBUSY; - } - - /* - * in system mode, we need to update the PMU directly - * and the user level state of the caller, which may not - * necessarily be the creator of the context. - */ - if (is_system) { - - /* - * set user level psr.pp for the caller - */ - ia64_psr(regs)->pp = 1; - - /* - * now update the local PMU and cpuinfo - */ - PFM_CPUINFO_SET(PFM_CPUINFO_DCR_PP); - - /* - * start monitoring at kernel level - */ - pfm_set_psr_pp(); - - /* enable dcr pp */ - ia64_setreg(_IA64_REG_CR_DCR, ia64_getreg(_IA64_REG_CR_DCR) | IA64_DCR_PP); - ia64_srlz_i(); - - return 0; - } - - /* - * per-process mode - */ - - if (ctx->ctx_task == current) { - - /* start monitoring at kernel level */ - pfm_set_psr_up(); - - /* - * activate monitoring at user level - */ - ia64_psr(regs)->up = 1; - - } else { - tregs = task_pt_regs(ctx->ctx_task); - - /* - * start monitoring at the kernel level the next - * time the task is scheduled - */ - ctx->ctx_saved_psr_up = IA64_PSR_UP; - - /* - * activate monitoring at user level - */ - ia64_psr(tregs)->up = 1; - } - return 0; -} - -static int -pfm_get_pmc_reset(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - pfarg_reg_t *req = (pfarg_reg_t *)arg; - unsigned int cnum; - int i; - int ret = -EINVAL; - - for (i = 0; i < count; i++, req++) { - - cnum = req->reg_num; - - if (!PMC_IS_IMPL(cnum)) goto abort_mission; - - req->reg_value = PMC_DFL_VAL(cnum); - - PFM_REG_RETFLAG_SET(req->reg_flags, 0); - - DPRINT(("pmc_reset_val pmc[%u]=0x%lx\n", cnum, req->reg_value)); - } - return 0; - -abort_mission: - PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL); - return ret; -} - -static int -pfm_check_task_exist(pfm_context_t *ctx) -{ - struct task_struct *g, *t; - int ret = -ESRCH; - - read_lock(&tasklist_lock); - - do_each_thread (g, t) { - if (t->thread.pfm_context == ctx) { - ret = 0; - goto out; - } - } while_each_thread (g, t); -out: - read_unlock(&tasklist_lock); - - DPRINT(("pfm_check_task_exist: ret=%d ctx=%p\n", ret, ctx)); - - return ret; -} - -static int -pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - struct task_struct *task; - struct thread_struct *thread; - struct pfm_context_t *old; - unsigned long flags; -#ifndef CONFIG_SMP - struct task_struct *owner_task = NULL; -#endif - pfarg_load_t *req = (pfarg_load_t *)arg; - unsigned long *pmcs_source, *pmds_source; - int the_cpu; - int ret = 0; - int state, is_system, set_dbregs = 0; - - state = ctx->ctx_state; - is_system = ctx->ctx_fl_system; - /* - * can only load from unloaded or terminated state - */ - if (state != PFM_CTX_UNLOADED) { - DPRINT(("cannot load to [%d], invalid ctx_state=%d\n", - req->load_pid, - ctx->ctx_state)); - return -EBUSY; - } - - DPRINT(("load_pid [%d] using_dbreg=%d\n", req->load_pid, ctx->ctx_fl_using_dbreg)); - - if (CTX_OVFL_NOBLOCK(ctx) == 0 && req->load_pid == current->pid) { - DPRINT(("cannot use blocking mode on self\n")); - return -EINVAL; - } - - ret = pfm_get_task(ctx, req->load_pid, &task); - if (ret) { - DPRINT(("load_pid [%d] get_task=%d\n", req->load_pid, ret)); - return ret; - } - - ret = -EINVAL; - - /* - * system wide is self monitoring only - */ - if (is_system && task != current) { - DPRINT(("system wide is self monitoring only load_pid=%d\n", - req->load_pid)); - goto error; - } - - thread = &task->thread; - - ret = 0; - /* - * cannot load a context which is using range restrictions, - * into a task that is being debugged. - */ - if (ctx->ctx_fl_using_dbreg) { - if (thread->flags & IA64_THREAD_DBG_VALID) { - ret = -EBUSY; - DPRINT(("load_pid [%d] task is debugged, cannot load range restrictions\n", req->load_pid)); - goto error; - } - LOCK_PFS(flags); - - if (is_system) { - if (pfm_sessions.pfs_ptrace_use_dbregs) { - DPRINT(("cannot load [%d] dbregs in use\n", - task_pid_nr(task))); - ret = -EBUSY; - } else { - pfm_sessions.pfs_sys_use_dbregs++; - DPRINT(("load [%d] increased sys_use_dbreg=%u\n", task_pid_nr(task), pfm_sessions.pfs_sys_use_dbregs)); - set_dbregs = 1; - } - } - - UNLOCK_PFS(flags); - - if (ret) goto error; - } - - /* - * SMP system-wide monitoring implies self-monitoring. - * - * The programming model expects the task to - * be pinned on a CPU throughout the session. - * Here we take note of the current CPU at the - * time the context is loaded. No call from - * another CPU will be allowed. - * - * The pinning via shed_setaffinity() - * must be done by the calling task prior - * to this call. - * - * systemwide: keep track of CPU this session is supposed to run on - */ - the_cpu = ctx->ctx_cpu = smp_processor_id(); - - ret = -EBUSY; - /* - * now reserve the session - */ - ret = pfm_reserve_session(current, is_system, the_cpu); - if (ret) goto error; - - /* - * task is necessarily stopped at this point. - * - * If the previous context was zombie, then it got removed in - * pfm_save_regs(). Therefore we should not see it here. - * If we see a context, then this is an active context - * - * XXX: needs to be atomic - */ - DPRINT(("before cmpxchg() old_ctx=%p new_ctx=%p\n", - thread->pfm_context, ctx)); - - ret = -EBUSY; - old = ia64_cmpxchg(acq, &thread->pfm_context, NULL, ctx, sizeof(pfm_context_t *)); - if (old != NULL) { - DPRINT(("load_pid [%d] already has a context\n", req->load_pid)); - goto error_unres; - } - - pfm_reset_msgq(ctx); - - ctx->ctx_state = PFM_CTX_LOADED; - - /* - * link context to task - */ - ctx->ctx_task = task; - - if (is_system) { - /* - * we load as stopped - */ - PFM_CPUINFO_SET(PFM_CPUINFO_SYST_WIDE); - PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP); - - if (ctx->ctx_fl_excl_idle) PFM_CPUINFO_SET(PFM_CPUINFO_EXCL_IDLE); - } else { - thread->flags |= IA64_THREAD_PM_VALID; - } - - /* - * propagate into thread-state - */ - pfm_copy_pmds(task, ctx); - pfm_copy_pmcs(task, ctx); - - pmcs_source = ctx->th_pmcs; - pmds_source = ctx->th_pmds; - - /* - * always the case for system-wide - */ - if (task == current) { - - if (is_system == 0) { - - /* allow user level control */ - ia64_psr(regs)->sp = 0; - DPRINT(("clearing psr.sp for [%d]\n", task_pid_nr(task))); - - SET_LAST_CPU(ctx, smp_processor_id()); - INC_ACTIVATION(); - SET_ACTIVATION(ctx); -#ifndef CONFIG_SMP - /* - * push the other task out, if any - */ - owner_task = GET_PMU_OWNER(); - if (owner_task) pfm_lazy_save_regs(owner_task); -#endif - } - /* - * load all PMD from ctx to PMU (as opposed to thread state) - * restore all PMC from ctx to PMU - */ - pfm_restore_pmds(pmds_source, ctx->ctx_all_pmds[0]); - pfm_restore_pmcs(pmcs_source, ctx->ctx_all_pmcs[0]); - - ctx->ctx_reload_pmcs[0] = 0UL; - ctx->ctx_reload_pmds[0] = 0UL; - - /* - * guaranteed safe by earlier check against DBG_VALID - */ - if (ctx->ctx_fl_using_dbreg) { - pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf->num_ibrs); - pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf->num_dbrs); - } - /* - * set new ownership - */ - SET_PMU_OWNER(task, ctx); - - DPRINT(("context loaded on PMU for [%d]\n", task_pid_nr(task))); - } else { - /* - * when not current, task MUST be stopped, so this is safe - */ - regs = task_pt_regs(task); - - /* force a full reload */ - ctx->ctx_last_activation = PFM_INVALID_ACTIVATION; - SET_LAST_CPU(ctx, -1); - - /* initial saved psr (stopped) */ - ctx->ctx_saved_psr_up = 0UL; - ia64_psr(regs)->up = ia64_psr(regs)->pp = 0; - } - - ret = 0; - -error_unres: - if (ret) pfm_unreserve_session(ctx, ctx->ctx_fl_system, the_cpu); -error: - /* - * we must undo the dbregs setting (for system-wide) - */ - if (ret && set_dbregs) { - LOCK_PFS(flags); - pfm_sessions.pfs_sys_use_dbregs--; - UNLOCK_PFS(flags); - } - /* - * release task, there is now a link with the context - */ - if (is_system == 0 && task != current) { - pfm_put_task(task); - - if (ret == 0) { - ret = pfm_check_task_exist(ctx); - if (ret) { - ctx->ctx_state = PFM_CTX_UNLOADED; - ctx->ctx_task = NULL; - } - } - } - return ret; -} - -/* - * in this function, we do not need to increase the use count - * for the task via get_task_struct(), because we hold the - * context lock. If the task were to disappear while having - * a context attached, it would go through pfm_exit_thread() - * which also grabs the context lock and would therefore be blocked - * until we are here. - */ -static void pfm_flush_pmds(struct task_struct *, pfm_context_t *ctx); - -static int -pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) -{ - struct task_struct *task = PFM_CTX_TASK(ctx); - struct pt_regs *tregs; - int prev_state, is_system; - int ret; - - DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task_pid_nr(task) : -1)); - - prev_state = ctx->ctx_state; - is_system = ctx->ctx_fl_system; - - /* - * unload only when necessary - */ - if (prev_state == PFM_CTX_UNLOADED) { - DPRINT(("ctx_state=%d, nothing to do\n", prev_state)); - return 0; - } - - /* - * clear psr and dcr bits - */ - ret = pfm_stop(ctx, NULL, 0, regs); - if (ret) return ret; - - ctx->ctx_state = PFM_CTX_UNLOADED; - - /* - * in system mode, we need to update the PMU directly - * and the user level state of the caller, which may not - * necessarily be the creator of the context. - */ - if (is_system) { - - /* - * Update cpuinfo - * - * local PMU is taken care of in pfm_stop() - */ - PFM_CPUINFO_CLEAR(PFM_CPUINFO_SYST_WIDE); - PFM_CPUINFO_CLEAR(PFM_CPUINFO_EXCL_IDLE); - - /* - * save PMDs in context - * release ownership - */ - pfm_flush_pmds(current, ctx); - - /* - * at this point we are done with the PMU - * so we can unreserve the resource. - */ - if (prev_state != PFM_CTX_ZOMBIE) - pfm_unreserve_session(ctx, 1 , ctx->ctx_cpu); - - /* - * disconnect context from task - */ - task->thread.pfm_context = NULL; - /* - * disconnect task from context - */ - ctx->ctx_task = NULL; - - /* - * There is nothing more to cleanup here. - */ - return 0; - } - - /* - * per-task mode - */ - tregs = task == current ? regs : task_pt_regs(task); - - if (task == current) { - /* - * cancel user level control - */ - ia64_psr(regs)->sp = 1; - - DPRINT(("setting psr.sp for [%d]\n", task_pid_nr(task))); - } - /* - * save PMDs to context - * release ownership - */ - pfm_flush_pmds(task, ctx); - - /* - * at this point we are done with the PMU - * so we can unreserve the resource. - * - * when state was ZOMBIE, we have already unreserved. - */ - if (prev_state != PFM_CTX_ZOMBIE) - pfm_unreserve_session(ctx, 0 , ctx->ctx_cpu); - - /* - * reset activation counter and psr - */ - ctx->ctx_last_activation = PFM_INVALID_ACTIVATION; - SET_LAST_CPU(ctx, -1); - - /* - * PMU state will not be restored - */ - task->thread.flags &= ~IA64_THREAD_PM_VALID; - - /* - * break links between context and task - */ - task->thread.pfm_context = NULL; - ctx->ctx_task = NULL; - - PFM_SET_WORK_PENDING(task, 0); - - ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_NONE; - ctx->ctx_fl_can_restart = 0; - ctx->ctx_fl_going_zombie = 0; - - DPRINT(("disconnected [%d] from context\n", task_pid_nr(task))); - - return 0; -} - - -/* - * called only from exit_thread() - * we come here only if the task has a context attached (loaded or masked) - */ -void -pfm_exit_thread(struct task_struct *task) -{ - pfm_context_t *ctx; - unsigned long flags; - struct pt_regs *regs = task_pt_regs(task); - int ret, state; - int free_ok = 0; - - ctx = PFM_GET_CTX(task); - - PROTECT_CTX(ctx, flags); - - DPRINT(("state=%d task [%d]\n", ctx->ctx_state, task_pid_nr(task))); - - state = ctx->ctx_state; - switch(state) { - case PFM_CTX_UNLOADED: - /* - * only comes to this function if pfm_context is not NULL, i.e., cannot - * be in unloaded state - */ - printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task_pid_nr(task)); - break; - case PFM_CTX_LOADED: - case PFM_CTX_MASKED: - ret = pfm_context_unload(ctx, NULL, 0, regs); - if (ret) { - printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret); - } - DPRINT(("ctx unloaded for current state was %d\n", state)); - - pfm_end_notify_user(ctx); - break; - case PFM_CTX_ZOMBIE: - ret = pfm_context_unload(ctx, NULL, 0, regs); - if (ret) { - printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret); - } - free_ok = 1; - break; - default: - printk(KERN_ERR "perfmon: pfm_exit_thread [%d] unexpected state=%d\n", task_pid_nr(task), state); - break; - } - UNPROTECT_CTX(ctx, flags); - - { u64 psr = pfm_get_psr(); - BUG_ON(psr & (IA64_PSR_UP|IA64_PSR_PP)); - BUG_ON(GET_PMU_OWNER()); - BUG_ON(ia64_psr(regs)->up); - BUG_ON(ia64_psr(regs)->pp); - } - - /* - * All memory free operations (especially for vmalloc'ed memory) - * MUST be done with interrupts ENABLED. - */ - if (free_ok) pfm_context_free(ctx); -} - -/* - * functions MUST be listed in the increasing order of their index (see permfon.h) - */ -#define PFM_CMD(name, flags, arg_count, arg_type, getsz) { name, #name, flags, arg_count, sizeof(arg_type), getsz } -#define PFM_CMD_S(name, flags) { name, #name, flags, 0, 0, NULL } -#define PFM_CMD_PCLRWS (PFM_CMD_FD|PFM_CMD_ARG_RW|PFM_CMD_STOP) -#define PFM_CMD_PCLRW (PFM_CMD_FD|PFM_CMD_ARG_RW) -#define PFM_CMD_NONE { NULL, "no-cmd", 0, 0, 0, NULL} - -static pfm_cmd_desc_t pfm_cmd_tab[]={ -/* 0 */PFM_CMD_NONE, -/* 1 */PFM_CMD(pfm_write_pmcs, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_reg_t, NULL), -/* 2 */PFM_CMD(pfm_write_pmds, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_reg_t, NULL), -/* 3 */PFM_CMD(pfm_read_pmds, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_reg_t, NULL), -/* 4 */PFM_CMD_S(pfm_stop, PFM_CMD_PCLRWS), -/* 5 */PFM_CMD_S(pfm_start, PFM_CMD_PCLRWS), -/* 6 */PFM_CMD_NONE, -/* 7 */PFM_CMD_NONE, -/* 8 */PFM_CMD(pfm_context_create, PFM_CMD_ARG_RW, 1, pfarg_context_t, pfm_ctx_getsize), -/* 9 */PFM_CMD_NONE, -/* 10 */PFM_CMD_S(pfm_restart, PFM_CMD_PCLRW), -/* 11 */PFM_CMD_NONE, -/* 12 */PFM_CMD(pfm_get_features, PFM_CMD_ARG_RW, 1, pfarg_features_t, NULL), -/* 13 */PFM_CMD(pfm_debug, 0, 1, unsigned int, NULL), -/* 14 */PFM_CMD_NONE, -/* 15 */PFM_CMD(pfm_get_pmc_reset, PFM_CMD_ARG_RW, PFM_CMD_ARG_MANY, pfarg_reg_t, NULL), -/* 16 */PFM_CMD(pfm_context_load, PFM_CMD_PCLRWS, 1, pfarg_load_t, NULL), -/* 17 */PFM_CMD_S(pfm_context_unload, PFM_CMD_PCLRWS), -/* 18 */PFM_CMD_NONE, -/* 19 */PFM_CMD_NONE, -/* 20 */PFM_CMD_NONE, -/* 21 */PFM_CMD_NONE, -/* 22 */PFM_CMD_NONE, -/* 23 */PFM_CMD_NONE, -/* 24 */PFM_CMD_NONE, -/* 25 */PFM_CMD_NONE, -/* 26 */PFM_CMD_NONE, -/* 27 */PFM_CMD_NONE, -/* 28 */PFM_CMD_NONE, -/* 29 */PFM_CMD_NONE, -/* 30 */PFM_CMD_NONE, -/* 31 */PFM_CMD_NONE, -/* 32 */PFM_CMD(pfm_write_ibrs, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_dbreg_t, NULL), -/* 33 */PFM_CMD(pfm_write_dbrs, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_dbreg_t, NULL) -}; -#define PFM_CMD_COUNT (sizeof(pfm_cmd_tab)/sizeof(pfm_cmd_desc_t)) - -static int -pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags) -{ - struct task_struct *task; - int state, old_state; - -recheck: - state = ctx->ctx_state; - task = ctx->ctx_task; - - if (task == NULL) { - DPRINT(("context %d no task, state=%d\n", ctx->ctx_fd, state)); - return 0; - } - - DPRINT(("context %d state=%d [%d] task_state=%ld must_stop=%d\n", - ctx->ctx_fd, - state, - task_pid_nr(task), - task->state, PFM_CMD_STOPPED(cmd))); - - /* - * self-monitoring always ok. - * - * for system-wide the caller can either be the creator of the - * context (to one to which the context is attached to) OR - * a task running on the same CPU as the session. - */ - if (task == current || ctx->ctx_fl_system) return 0; - - /* - * we are monitoring another thread - */ - switch(state) { - case PFM_CTX_UNLOADED: - /* - * if context is UNLOADED we are safe to go - */ - return 0; - case PFM_CTX_ZOMBIE: - /* - * no command can operate on a zombie context - */ - DPRINT(("cmd %d state zombie cannot operate on context\n", cmd)); - return -EINVAL; - case PFM_CTX_MASKED: - /* - * PMU state has been saved to software even though - * the thread may still be running. - */ - if (cmd != PFM_UNLOAD_CONTEXT) return 0; - } - - /* - * context is LOADED or MASKED. Some commands may need to have - * the task stopped. - * - * We could lift this restriction for UP but it would mean that - * the user has no guarantee the task would not run between - * two successive calls to perfmonctl(). That's probably OK. - * If this user wants to ensure the task does not run, then - * the task must be stopped. - */ - if (PFM_CMD_STOPPED(cmd)) { - if (!task_is_stopped_or_traced(task)) { - DPRINT(("[%d] task not in stopped state\n", task_pid_nr(task))); - return -EBUSY; - } - /* - * task is now stopped, wait for ctxsw out - * - * This is an interesting point in the code. - * We need to unprotect the context because - * the pfm_save_regs() routines needs to grab - * the same lock. There are danger in doing - * this because it leaves a window open for - * another task to get access to the context - * and possibly change its state. The one thing - * that is not possible is for the context to disappear - * because we are protected by the VFS layer, i.e., - * get_fd()/put_fd(). - */ - old_state = state; - - UNPROTECT_CTX(ctx, flags); - - wait_task_inactive(task, 0); - - PROTECT_CTX(ctx, flags); - - /* - * we must recheck to verify if state has changed - */ - if (ctx->ctx_state != old_state) { - DPRINT(("old_state=%d new_state=%d\n", old_state, ctx->ctx_state)); - goto recheck; - } - } - return 0; -} - -/* - * system-call entry point (must return long) - */ -asmlinkage long -sys_perfmonctl (int fd, int cmd, void __user *arg, int count) -{ - struct fd f = {NULL, 0}; - pfm_context_t *ctx = NULL; - unsigned long flags = 0UL; - void *args_k = NULL; - long ret; /* will expand int return types */ - size_t base_sz, sz, xtra_sz = 0; - int narg, completed_args = 0, call_made = 0, cmd_flags; - int (*func)(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs); - int (*getsize)(void *arg, size_t *sz); -#define PFM_MAX_ARGSIZE 4096 - - /* - * reject any call if perfmon was disabled at initialization - */ - if (unlikely(pmu_conf == NULL)) return -ENOSYS; - - if (unlikely(cmd < 0 || cmd >= PFM_CMD_COUNT)) { - DPRINT(("invalid cmd=%d\n", cmd)); - return -EINVAL; - } - - func = pfm_cmd_tab[cmd].cmd_func; - narg = pfm_cmd_tab[cmd].cmd_narg; - base_sz = pfm_cmd_tab[cmd].cmd_argsize; - getsize = pfm_cmd_tab[cmd].cmd_getsize; - cmd_flags = pfm_cmd_tab[cmd].cmd_flags; - - if (unlikely(func == NULL)) { - DPRINT(("invalid cmd=%d\n", cmd)); - return -EINVAL; - } - - DPRINT(("cmd=%s idx=%d narg=0x%x argsz=%lu count=%d\n", - PFM_CMD_NAME(cmd), - cmd, - narg, - base_sz, - count)); - - /* - * check if number of arguments matches what the command expects - */ - if (unlikely((narg == PFM_CMD_ARG_MANY && count <= 0) || (narg > 0 && narg != count))) - return -EINVAL; - -restart_args: - sz = xtra_sz + base_sz*count; - /* - * limit abuse to min page size - */ - if (unlikely(sz > PFM_MAX_ARGSIZE)) { - printk(KERN_ERR "perfmon: [%d] argument too big %lu\n", task_pid_nr(current), sz); - return -E2BIG; - } - - /* - * allocate default-sized argument buffer - */ - if (likely(count && args_k == NULL)) { - args_k = kmalloc(PFM_MAX_ARGSIZE, GFP_KERNEL); - if (args_k == NULL) return -ENOMEM; - } - - ret = -EFAULT; - - /* - * copy arguments - * - * assume sz = 0 for command without parameters - */ - if (sz && copy_from_user(args_k, arg, sz)) { - DPRINT(("cannot copy_from_user %lu bytes @%p\n", sz, arg)); - goto error_args; - } - - /* - * check if command supports extra parameters - */ - if (completed_args == 0 && getsize) { - /* - * get extra parameters size (based on main argument) - */ - ret = (*getsize)(args_k, &xtra_sz); - if (ret) goto error_args; - - completed_args = 1; - - DPRINT(("restart_args sz=%lu xtra_sz=%lu\n", sz, xtra_sz)); - - /* retry if necessary */ - if (likely(xtra_sz)) goto restart_args; - } - - if (unlikely((cmd_flags & PFM_CMD_FD) == 0)) goto skip_fd; - - ret = -EBADF; - - f = fdget(fd); - if (unlikely(f.file == NULL)) { - DPRINT(("invalid fd %d\n", fd)); - goto error_args; - } - if (unlikely(PFM_IS_FILE(f.file) == 0)) { - DPRINT(("fd %d not related to perfmon\n", fd)); - goto error_args; - } - - ctx = f.file->private_data; - if (unlikely(ctx == NULL)) { - DPRINT(("no context for fd %d\n", fd)); - goto error_args; - } - prefetch(&ctx->ctx_state); - - PROTECT_CTX(ctx, flags); - - /* - * check task is stopped - */ - ret = pfm_check_task_state(ctx, cmd, flags); - if (unlikely(ret)) goto abort_locked; - -skip_fd: - ret = (*func)(ctx, args_k, count, task_pt_regs(current)); - - call_made = 1; - -abort_locked: - if (likely(ctx)) { - DPRINT(("context unlocked\n")); - UNPROTECT_CTX(ctx, flags); - } - - /* copy argument back to user, if needed */ - if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT; - -error_args: - if (f.file) - fdput(f); - - kfree(args_k); - - DPRINT(("cmd=%s ret=%ld\n", PFM_CMD_NAME(cmd), ret)); - - return ret; -} - -static void -pfm_resume_after_ovfl(pfm_context_t *ctx, unsigned long ovfl_regs, struct pt_regs *regs) -{ - pfm_buffer_fmt_t *fmt = ctx->ctx_buf_fmt; - pfm_ovfl_ctrl_t rst_ctrl; - int state; - int ret = 0; - - state = ctx->ctx_state; - /* - * Unlock sampling buffer and reset index atomically - * XXX: not really needed when blocking - */ - if (CTX_HAS_SMPL(ctx)) { - - rst_ctrl.bits.mask_monitoring = 0; - rst_ctrl.bits.reset_ovfl_pmds = 0; - - if (state == PFM_CTX_LOADED) - ret = pfm_buf_fmt_restart_active(fmt, current, &rst_ctrl, ctx->ctx_smpl_hdr, regs); - else - ret = pfm_buf_fmt_restart(fmt, current, &rst_ctrl, ctx->ctx_smpl_hdr, regs); - } else { - rst_ctrl.bits.mask_monitoring = 0; - rst_ctrl.bits.reset_ovfl_pmds = 1; - } - - if (ret == 0) { - if (rst_ctrl.bits.reset_ovfl_pmds) { - pfm_reset_regs(ctx, &ovfl_regs, PFM_PMD_LONG_RESET); - } - if (rst_ctrl.bits.mask_monitoring == 0) { - DPRINT(("resuming monitoring\n")); - if (ctx->ctx_state == PFM_CTX_MASKED) pfm_restore_monitoring(current); - } else { - DPRINT(("stopping monitoring\n")); - //pfm_stop_monitoring(current, regs); - } - ctx->ctx_state = PFM_CTX_LOADED; - } -} - -/* - * context MUST BE LOCKED when calling - * can only be called for current - */ -static void -pfm_context_force_terminate(pfm_context_t *ctx, struct pt_regs *regs) -{ - int ret; - - DPRINT(("entering for [%d]\n", task_pid_nr(current))); - - ret = pfm_context_unload(ctx, NULL, 0, regs); - if (ret) { - printk(KERN_ERR "pfm_context_force_terminate: [%d] unloaded failed with %d\n", task_pid_nr(current), ret); - } - - /* - * and wakeup controlling task, indicating we are now disconnected - */ - wake_up_interruptible(&ctx->ctx_zombieq); - - /* - * given that context is still locked, the controlling - * task will only get access when we return from - * pfm_handle_work(). - */ -} - -static int pfm_ovfl_notify_user(pfm_context_t *ctx, unsigned long ovfl_pmds); - - /* - * pfm_handle_work() can be called with interrupts enabled - * (TIF_NEED_RESCHED) or disabled. The down_interruptible - * call may sleep, therefore we must re-enable interrupts - * to avoid deadlocks. It is safe to do so because this function - * is called ONLY when returning to user level (pUStk=1), in which case - * there is no risk of kernel stack overflow due to deep - * interrupt nesting. - */ -void -pfm_handle_work(void) -{ - pfm_context_t *ctx; - struct pt_regs *regs; - unsigned long flags, dummy_flags; - unsigned long ovfl_regs; - unsigned int reason; - int ret; - - ctx = PFM_GET_CTX(current); - if (ctx == NULL) { - printk(KERN_ERR "perfmon: [%d] has no PFM context\n", - task_pid_nr(current)); - return; - } - - PROTECT_CTX(ctx, flags); - - PFM_SET_WORK_PENDING(current, 0); - - regs = task_pt_regs(current); - - /* - * extract reason for being here and clear - */ - reason = ctx->ctx_fl_trap_reason; - ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_NONE; - ovfl_regs = ctx->ctx_ovfl_regs[0]; - - DPRINT(("reason=%d state=%d\n", reason, ctx->ctx_state)); - - /* - * must be done before we check for simple-reset mode - */ - if (ctx->ctx_fl_going_zombie || ctx->ctx_state == PFM_CTX_ZOMBIE) - goto do_zombie; - - //if (CTX_OVFL_NOBLOCK(ctx)) goto skip_blocking; - if (reason == PFM_TRAP_REASON_RESET) - goto skip_blocking; - - /* - * restore interrupt mask to what it was on entry. - * Could be enabled/diasbled. - */ - UNPROTECT_CTX(ctx, flags); - - /* - * force interrupt enable because of down_interruptible() - */ - local_irq_enable(); - - DPRINT(("before block sleeping\n")); - - /* - * may go through without blocking on SMP systems - * if restart has been received already by the time we call down() - */ - ret = wait_for_completion_interruptible(&ctx->ctx_restart_done); - - DPRINT(("after block sleeping ret=%d\n", ret)); - - /* - * lock context and mask interrupts again - * We save flags into a dummy because we may have - * altered interrupts mask compared to entry in this - * function. - */ - PROTECT_CTX(ctx, dummy_flags); - - /* - * we need to read the ovfl_regs only after wake-up - * because we may have had pfm_write_pmds() in between - * and that can changed PMD values and therefore - * ovfl_regs is reset for these new PMD values. - */ - ovfl_regs = ctx->ctx_ovfl_regs[0]; - - if (ctx->ctx_fl_going_zombie) { -do_zombie: - DPRINT(("context is zombie, bailing out\n")); - pfm_context_force_terminate(ctx, regs); - goto nothing_to_do; - } - /* - * in case of interruption of down() we don't restart anything - */ - if (ret < 0) - goto nothing_to_do; - -skip_blocking: - pfm_resume_after_ovfl(ctx, ovfl_regs, regs); - ctx->ctx_ovfl_regs[0] = 0UL; - -nothing_to_do: - /* - * restore flags as they were upon entry - */ - UNPROTECT_CTX(ctx, flags); -} - -static int -pfm_notify_user(pfm_context_t *ctx, pfm_msg_t *msg) -{ - if (ctx->ctx_state == PFM_CTX_ZOMBIE) { - DPRINT(("ignoring overflow notification, owner is zombie\n")); - return 0; - } - - DPRINT(("waking up somebody\n")); - - if (msg) wake_up_interruptible(&ctx->ctx_msgq_wait); - - /* - * safe, we are not in intr handler, nor in ctxsw when - * we come here - */ - kill_fasync (&ctx->ctx_async_queue, SIGIO, POLL_IN); - - return 0; -} - -static int -pfm_ovfl_notify_user(pfm_context_t *ctx, unsigned long ovfl_pmds) -{ - pfm_msg_t *msg = NULL; - - if (ctx->ctx_fl_no_msg == 0) { - msg = pfm_get_new_msg(ctx); - if (msg == NULL) { - printk(KERN_ERR "perfmon: pfm_ovfl_notify_user no more notification msgs\n"); - return -1; - } - - msg->pfm_ovfl_msg.msg_type = PFM_MSG_OVFL; - msg->pfm_ovfl_msg.msg_ctx_fd = ctx->ctx_fd; - msg->pfm_ovfl_msg.msg_active_set = 0; - msg->pfm_ovfl_msg.msg_ovfl_pmds[0] = ovfl_pmds; - msg->pfm_ovfl_msg.msg_ovfl_pmds[1] = 0UL; - msg->pfm_ovfl_msg.msg_ovfl_pmds[2] = 0UL; - msg->pfm_ovfl_msg.msg_ovfl_pmds[3] = 0UL; - msg->pfm_ovfl_msg.msg_tstamp = 0UL; - } - - DPRINT(("ovfl msg: msg=%p no_msg=%d fd=%d ovfl_pmds=0x%lx\n", - msg, - ctx->ctx_fl_no_msg, - ctx->ctx_fd, - ovfl_pmds)); - - return pfm_notify_user(ctx, msg); -} - -static int -pfm_end_notify_user(pfm_context_t *ctx) -{ - pfm_msg_t *msg; - - msg = pfm_get_new_msg(ctx); - if (msg == NULL) { - printk(KERN_ERR "perfmon: pfm_end_notify_user no more notification msgs\n"); - return -1; - } - /* no leak */ - memset(msg, 0, sizeof(*msg)); - - msg->pfm_end_msg.msg_type = PFM_MSG_END; - msg->pfm_end_msg.msg_ctx_fd = ctx->ctx_fd; - msg->pfm_ovfl_msg.msg_tstamp = 0UL; - - DPRINT(("end msg: msg=%p no_msg=%d ctx_fd=%d\n", - msg, - ctx->ctx_fl_no_msg, - ctx->ctx_fd)); - - return pfm_notify_user(ctx, msg); -} - -/* - * main overflow processing routine. - * it can be called from the interrupt path or explicitly during the context switch code - */ -static void pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, - unsigned long pmc0, struct pt_regs *regs) -{ - pfm_ovfl_arg_t *ovfl_arg; - unsigned long mask; - unsigned long old_val, ovfl_val, new_val; - unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL, smpl_pmds = 0UL, reset_pmds; - unsigned long tstamp; - pfm_ovfl_ctrl_t ovfl_ctrl; - unsigned int i, has_smpl; - int must_notify = 0; - - if (unlikely(ctx->ctx_state == PFM_CTX_ZOMBIE)) goto stop_monitoring; - - /* - * sanity test. Should never happen - */ - if (unlikely((pmc0 & 0x1) == 0)) goto sanity_check; - - tstamp = ia64_get_itc(); - mask = pmc0 >> PMU_FIRST_COUNTER; - ovfl_val = pmu_conf->ovfl_val; - has_smpl = CTX_HAS_SMPL(ctx); - - DPRINT_ovfl(("pmc0=0x%lx pid=%d iip=0x%lx, %s " - "used_pmds=0x%lx\n", - pmc0, - task ? task_pid_nr(task): -1, - (regs ? regs->cr_iip : 0), - CTX_OVFL_NOBLOCK(ctx) ? "nonblocking" : "blocking", - ctx->ctx_used_pmds[0])); - - - /* - * first we update the virtual counters - * assume there was a prior ia64_srlz_d() issued - */ - for (i = PMU_FIRST_COUNTER; mask ; i++, mask >>= 1) { - - /* skip pmd which did not overflow */ - if ((mask & 0x1) == 0) continue; - - /* - * Note that the pmd is not necessarily 0 at this point as qualified events - * may have happened before the PMU was frozen. The residual count is not - * taken into consideration here but will be with any read of the pmd via - * pfm_read_pmds(). - */ - old_val = new_val = ctx->ctx_pmds[i].val; - new_val += 1 + ovfl_val; - ctx->ctx_pmds[i].val = new_val; - - /* - * check for overflow condition - */ - if (likely(old_val > new_val)) { - ovfl_pmds |= 1UL << i; - if (PMC_OVFL_NOTIFY(ctx, i)) ovfl_notify |= 1UL << i; - } - - DPRINT_ovfl(("ctx_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx\n", - i, - new_val, - old_val, - ia64_get_pmd(i) & ovfl_val, - ovfl_pmds, - ovfl_notify)); - } - - /* - * there was no 64-bit overflow, nothing else to do - */ - if (ovfl_pmds == 0UL) return; - - /* - * reset all control bits - */ - ovfl_ctrl.val = 0; - reset_pmds = 0UL; - - /* - * if a sampling format module exists, then we "cache" the overflow by - * calling the module's handler() routine. - */ - if (has_smpl) { - unsigned long start_cycles, end_cycles; - unsigned long pmd_mask; - int j, k, ret = 0; - int this_cpu = smp_processor_id(); - - pmd_mask = ovfl_pmds >> PMU_FIRST_COUNTER; - ovfl_arg = &ctx->ctx_ovfl_arg; - - prefetch(ctx->ctx_smpl_hdr); - - for(i=PMU_FIRST_COUNTER; pmd_mask && ret == 0; i++, pmd_mask >>=1) { - - mask = 1UL << i; - - if ((pmd_mask & 0x1) == 0) continue; - - ovfl_arg->ovfl_pmd = (unsigned char )i; - ovfl_arg->ovfl_notify = ovfl_notify & mask ? 1 : 0; - ovfl_arg->active_set = 0; - ovfl_arg->ovfl_ctrl.val = 0; /* module must fill in all fields */ - ovfl_arg->smpl_pmds[0] = smpl_pmds = ctx->ctx_pmds[i].smpl_pmds[0]; - - ovfl_arg->pmd_value = ctx->ctx_pmds[i].val; - ovfl_arg->pmd_last_reset = ctx->ctx_pmds[i].lval; - ovfl_arg->pmd_eventid = ctx->ctx_pmds[i].eventid; - - /* - * copy values of pmds of interest. Sampling format may copy them - * into sampling buffer. - */ - if (smpl_pmds) { - for(j=0, k=0; smpl_pmds; j++, smpl_pmds >>=1) { - if ((smpl_pmds & 0x1) == 0) continue; - ovfl_arg->smpl_pmds_values[k++] = PMD_IS_COUNTING(j) ? pfm_read_soft_counter(ctx, j) : ia64_get_pmd(j); - DPRINT_ovfl(("smpl_pmd[%d]=pmd%u=0x%lx\n", k-1, j, ovfl_arg->smpl_pmds_values[k-1])); - } - } - - pfm_stats[this_cpu].pfm_smpl_handler_calls++; - - start_cycles = ia64_get_itc(); - - /* - * call custom buffer format record (handler) routine - */ - ret = (*ctx->ctx_buf_fmt->fmt_handler)(task, ctx->ctx_smpl_hdr, ovfl_arg, regs, tstamp); - - end_cycles = ia64_get_itc(); - - /* - * For those controls, we take the union because they have - * an all or nothing behavior. - */ - ovfl_ctrl.bits.notify_user |= ovfl_arg->ovfl_ctrl.bits.notify_user; - ovfl_ctrl.bits.block_task |= ovfl_arg->ovfl_ctrl.bits.block_task; - ovfl_ctrl.bits.mask_monitoring |= ovfl_arg->ovfl_ctrl.bits.mask_monitoring; - /* - * build the bitmask of pmds to reset now - */ - if (ovfl_arg->ovfl_ctrl.bits.reset_ovfl_pmds) reset_pmds |= mask; - - pfm_stats[this_cpu].pfm_smpl_handler_cycles += end_cycles - start_cycles; - } - /* - * when the module cannot handle the rest of the overflows, we abort right here - */ - if (ret && pmd_mask) { - DPRINT(("handler aborts leftover ovfl_pmds=0x%lx\n", - pmd_mask<<PMU_FIRST_COUNTER)); - } - /* - * remove the pmds we reset now from the set of pmds to reset in pfm_restart() - */ - ovfl_pmds &= ~reset_pmds; - } else { - /* - * when no sampling module is used, then the default - * is to notify on overflow if requested by user - */ - ovfl_ctrl.bits.notify_user = ovfl_notify ? 1 : 0; - ovfl_ctrl.bits.block_task = ovfl_notify ? 1 : 0; - ovfl_ctrl.bits.mask_monitoring = ovfl_notify ? 1 : 0; /* XXX: change for saturation */ - ovfl_ctrl.bits.reset_ovfl_pmds = ovfl_notify ? 0 : 1; - /* - * if needed, we reset all overflowed pmds - */ - if (ovfl_notify == 0) reset_pmds = ovfl_pmds; - } - - DPRINT_ovfl(("ovfl_pmds=0x%lx reset_pmds=0x%lx\n", ovfl_pmds, reset_pmds)); - - /* - * reset the requested PMD registers using the short reset values - */ - if (reset_pmds) { - unsigned long bm = reset_pmds; - pfm_reset_regs(ctx, &bm, PFM_PMD_SHORT_RESET); - } - - if (ovfl_notify && ovfl_ctrl.bits.notify_user) { - /* - * keep track of what to reset when unblocking - */ - ctx->ctx_ovfl_regs[0] = ovfl_pmds; - - /* - * check for blocking context - */ - if (CTX_OVFL_NOBLOCK(ctx) == 0 && ovfl_ctrl.bits.block_task) { - - ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_BLOCK; - - /* - * set the perfmon specific checking pending work for the task - */ - PFM_SET_WORK_PENDING(task, 1); - - /* - * when coming from ctxsw, current still points to the - * previous task, therefore we must work with task and not current. - */ - set_notify_resume(task); - } - /* - * defer until state is changed (shorten spin window). the context is locked - * anyway, so the signal receiver would come spin for nothing. - */ - must_notify = 1; - } - - DPRINT_ovfl(("owner [%d] pending=%ld reason=%u ovfl_pmds=0x%lx ovfl_notify=0x%lx masked=%d\n", - GET_PMU_OWNER() ? task_pid_nr(GET_PMU_OWNER()) : -1, - PFM_GET_WORK_PENDING(task), - ctx->ctx_fl_trap_reason, - ovfl_pmds, - ovfl_notify, - ovfl_ctrl.bits.mask_monitoring ? 1 : 0)); - /* - * in case monitoring must be stopped, we toggle the psr bits - */ - if (ovfl_ctrl.bits.mask_monitoring) { - pfm_mask_monitoring(task); - ctx->ctx_state = PFM_CTX_MASKED; - ctx->ctx_fl_can_restart = 1; - } - - /* - * send notification now - */ - if (must_notify) pfm_ovfl_notify_user(ctx, ovfl_notify); - - return; - -sanity_check: - printk(KERN_ERR "perfmon: CPU%d overflow handler [%d] pmc0=0x%lx\n", - smp_processor_id(), - task ? task_pid_nr(task) : -1, - pmc0); - return; - -stop_monitoring: - /* - * in SMP, zombie context is never restored but reclaimed in pfm_load_regs(). - * Moreover, zombies are also reclaimed in pfm_save_regs(). Therefore we can - * come here as zombie only if the task is the current task. In which case, we - * can access the PMU hardware directly. - * - * Note that zombies do have PM_VALID set. So here we do the minimal. - * - * In case the context was zombified it could not be reclaimed at the time - * the monitoring program exited. At this point, the PMU reservation has been - * returned, the sampiing buffer has been freed. We must convert this call - * into a spurious interrupt. However, we must also avoid infinite overflows - * by stopping monitoring for this task. We can only come here for a per-task - * context. All we need to do is to stop monitoring using the psr bits which - * are always task private. By re-enabling secure montioring, we ensure that - * the monitored task will not be able to re-activate monitoring. - * The task will eventually be context switched out, at which point the context - * will be reclaimed (that includes releasing ownership of the PMU). - * - * So there might be a window of time where the number of per-task session is zero - * yet one PMU might have a owner and get at most one overflow interrupt for a zombie - * context. This is safe because if a per-task session comes in, it will push this one - * out and by the virtue on pfm_save_regs(), this one will disappear. If a system wide - * session is force on that CPU, given that we use task pinning, pfm_save_regs() will - * also push our zombie context out. - * - * Overall pretty hairy stuff.... - */ - DPRINT(("ctx is zombie for [%d], converted to spurious\n", task ? task_pid_nr(task): -1)); - pfm_clear_psr_up(); - ia64_psr(regs)->up = 0; - ia64_psr(regs)->sp = 1; - return; -} - -static int -pfm_do_interrupt_handler(void *arg, struct pt_regs *regs) -{ - struct task_struct *task; - pfm_context_t *ctx; - unsigned long flags; - u64 pmc0; - int this_cpu = smp_processor_id(); - int retval = 0; - - pfm_stats[this_cpu].pfm_ovfl_intr_count++; - - /* - * srlz.d done before arriving here - */ - pmc0 = ia64_get_pmc(0); - - task = GET_PMU_OWNER(); - ctx = GET_PMU_CTX(); - - /* - * if we have some pending bits set - * assumes : if any PMC0.bit[63-1] is set, then PMC0.fr = 1 - */ - if (PMC0_HAS_OVFL(pmc0) && task) { - /* - * we assume that pmc0.fr is always set here - */ - - /* sanity check */ - if (!ctx) goto report_spurious1; - - if (ctx->ctx_fl_system == 0 && (task->thread.flags & IA64_THREAD_PM_VALID) == 0) - goto report_spurious2; - - PROTECT_CTX_NOPRINT(ctx, flags); - - pfm_overflow_handler(task, ctx, pmc0, regs); - - UNPROTECT_CTX_NOPRINT(ctx, flags); - - } else { - pfm_stats[this_cpu].pfm_spurious_ovfl_intr_count++; - retval = -1; - } - /* - * keep it unfrozen at all times - */ - pfm_unfreeze_pmu(); - - return retval; - -report_spurious1: - printk(KERN_INFO "perfmon: spurious overflow interrupt on CPU%d: process %d has no PFM context\n", - this_cpu, task_pid_nr(task)); - pfm_unfreeze_pmu(); - return -1; -report_spurious2: - printk(KERN_INFO "perfmon: spurious overflow interrupt on CPU%d: process %d, invalid flag\n", - this_cpu, - task_pid_nr(task)); - pfm_unfreeze_pmu(); - return -1; -} - -static irqreturn_t -pfm_interrupt_handler(int irq, void *arg) -{ - unsigned long start_cycles, total_cycles; - unsigned long min, max; - int this_cpu; - int ret; - struct pt_regs *regs = get_irq_regs(); - - this_cpu = get_cpu(); - if (likely(!pfm_alt_intr_handler)) { - min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min; - max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max; - - start_cycles = ia64_get_itc(); - - ret = pfm_do_interrupt_handler(arg, regs); - - total_cycles = ia64_get_itc(); - - /* - * don't measure spurious interrupts - */ - if (likely(ret == 0)) { - total_cycles -= start_cycles; - - if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles; - if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles; - - pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles; - } - } - else { - (*pfm_alt_intr_handler->handler)(irq, arg, regs); - } - - put_cpu(); - return IRQ_HANDLED; -} - -/* - * /proc/perfmon interface, for debug only - */ - -#define PFM_PROC_SHOW_HEADER ((void *)(long)nr_cpu_ids+1) - -static void * -pfm_proc_start(struct seq_file *m, loff_t *pos) -{ - if (*pos == 0) { - return PFM_PROC_SHOW_HEADER; - } - - while (*pos <= nr_cpu_ids) { - if (cpu_online(*pos - 1)) { - return (void *)*pos; - } - ++*pos; - } - return NULL; -} - -static void * -pfm_proc_next(struct seq_file *m, void *v, loff_t *pos) -{ - ++*pos; - return pfm_proc_start(m, pos); -} - -static void -pfm_proc_stop(struct seq_file *m, void *v) -{ -} - -static void -pfm_proc_show_header(struct seq_file *m) -{ - struct list_head * pos; - pfm_buffer_fmt_t * entry; - unsigned long flags; - - seq_printf(m, - "perfmon version : %u.%u\n" - "model : %s\n" - "fastctxsw : %s\n" - "expert mode : %s\n" - "ovfl_mask : 0x%lx\n" - "PMU flags : 0x%x\n", - PFM_VERSION_MAJ, PFM_VERSION_MIN, - pmu_conf->pmu_name, - pfm_sysctl.fastctxsw > 0 ? "Yes": "No", - pfm_sysctl.expert_mode > 0 ? "Yes": "No", - pmu_conf->ovfl_val, - pmu_conf->flags); - - LOCK_PFS(flags); - - seq_printf(m, - "proc_sessions : %u\n" - "sys_sessions : %u\n" - "sys_use_dbregs : %u\n" - "ptrace_use_dbregs : %u\n", - pfm_sessions.pfs_task_sessions, - pfm_sessions.pfs_sys_sessions, - pfm_sessions.pfs_sys_use_dbregs, - pfm_sessions.pfs_ptrace_use_dbregs); - - UNLOCK_PFS(flags); - - spin_lock(&pfm_buffer_fmt_lock); - - list_for_each(pos, &pfm_buffer_fmt_list) { - entry = list_entry(pos, pfm_buffer_fmt_t, fmt_list); - seq_printf(m, "format : %16phD %s\n", - entry->fmt_uuid, entry->fmt_name); - } - spin_unlock(&pfm_buffer_fmt_lock); - -} - -static int -pfm_proc_show(struct seq_file *m, void *v) -{ - unsigned long psr; - unsigned int i; - int cpu; - - if (v == PFM_PROC_SHOW_HEADER) { - pfm_proc_show_header(m); - return 0; - } - - /* show info for CPU (v - 1) */ - - cpu = (long)v - 1; - seq_printf(m, - "CPU%-2d overflow intrs : %lu\n" - "CPU%-2d overflow cycles : %lu\n" - "CPU%-2d overflow min : %lu\n" - "CPU%-2d overflow max : %lu\n" - "CPU%-2d smpl handler calls : %lu\n" - "CPU%-2d smpl handler cycles : %lu\n" - "CPU%-2d spurious intrs : %lu\n" - "CPU%-2d replay intrs : %lu\n" - "CPU%-2d syst_wide : %d\n" - "CPU%-2d dcr_pp : %d\n" - "CPU%-2d exclude idle : %d\n" - "CPU%-2d owner : %d\n" - "CPU%-2d context : %p\n" - "CPU%-2d activations : %lu\n", - cpu, pfm_stats[cpu].pfm_ovfl_intr_count, - cpu, pfm_stats[cpu].pfm_ovfl_intr_cycles, - cpu, pfm_stats[cpu].pfm_ovfl_intr_cycles_min, - cpu, pfm_stats[cpu].pfm_ovfl_intr_cycles_max, - cpu, pfm_stats[cpu].pfm_smpl_handler_calls, - cpu, pfm_stats[cpu].pfm_smpl_handler_cycles, - cpu, pfm_stats[cpu].pfm_spurious_ovfl_intr_count, - cpu, pfm_stats[cpu].pfm_replay_ovfl_intr_count, - cpu, pfm_get_cpu_data(pfm_syst_info, cpu) & PFM_CPUINFO_SYST_WIDE ? 1 : 0, - cpu, pfm_get_cpu_data(pfm_syst_info, cpu) & PFM_CPUINFO_DCR_PP ? 1 : 0, - cpu, pfm_get_cpu_data(pfm_syst_info, cpu) & PFM_CPUINFO_EXCL_IDLE ? 1 : 0, - cpu, pfm_get_cpu_data(pmu_owner, cpu) ? pfm_get_cpu_data(pmu_owner, cpu)->pid: -1, - cpu, pfm_get_cpu_data(pmu_ctx, cpu), - cpu, pfm_get_cpu_data(pmu_activation_number, cpu)); - - if (num_online_cpus() == 1 && pfm_sysctl.debug > 0) { - - psr = pfm_get_psr(); - - ia64_srlz_d(); - - seq_printf(m, - "CPU%-2d psr : 0x%lx\n" - "CPU%-2d pmc0 : 0x%lx\n", - cpu, psr, - cpu, ia64_get_pmc(0)); - - for (i=0; PMC_IS_LAST(i) == 0; i++) { - if (PMC_IS_COUNTING(i) == 0) continue; - seq_printf(m, - "CPU%-2d pmc%u : 0x%lx\n" - "CPU%-2d pmd%u : 0x%lx\n", - cpu, i, ia64_get_pmc(i), - cpu, i, ia64_get_pmd(i)); - } - } - return 0; -} - -const struct seq_operations pfm_seq_ops = { - .start = pfm_proc_start, - .next = pfm_proc_next, - .stop = pfm_proc_stop, - .show = pfm_proc_show -}; - -/* - * we come here as soon as local_cpu_data->pfm_syst_wide is set. this happens - * during pfm_enable() hence before pfm_start(). We cannot assume monitoring - * is active or inactive based on mode. We must rely on the value in - * local_cpu_data->pfm_syst_info - */ -void -pfm_syst_wide_update_task(struct task_struct *task, unsigned long info, int is_ctxswin) -{ - struct pt_regs *regs; - unsigned long dcr; - unsigned long dcr_pp; - - dcr_pp = info & PFM_CPUINFO_DCR_PP ? 1 : 0; - - /* - * pid 0 is guaranteed to be the idle task. There is one such task with pid 0 - * on every CPU, so we can rely on the pid to identify the idle task. - */ - if ((info & PFM_CPUINFO_EXCL_IDLE) == 0 || task->pid) { - regs = task_pt_regs(task); - ia64_psr(regs)->pp = is_ctxswin ? dcr_pp : 0; - return; - } - /* - * if monitoring has started - */ - if (dcr_pp) { - dcr = ia64_getreg(_IA64_REG_CR_DCR); - /* - * context switching in? - */ - if (is_ctxswin) { - /* mask monitoring for the idle task */ - ia64_setreg(_IA64_REG_CR_DCR, dcr & ~IA64_DCR_PP); - pfm_clear_psr_pp(); - ia64_srlz_i(); - return; - } - /* - * context switching out - * restore monitoring for next task - * - * Due to inlining this odd if-then-else construction generates - * better code. - */ - ia64_setreg(_IA64_REG_CR_DCR, dcr |IA64_DCR_PP); - pfm_set_psr_pp(); - ia64_srlz_i(); - } -} - -#ifdef CONFIG_SMP - -static void -pfm_force_cleanup(pfm_context_t *ctx, struct pt_regs *regs) -{ - struct task_struct *task = ctx->ctx_task; - - ia64_psr(regs)->up = 0; - ia64_psr(regs)->sp = 1; - - if (GET_PMU_OWNER() == task) { - DPRINT(("cleared ownership for [%d]\n", - task_pid_nr(ctx->ctx_task))); - SET_PMU_OWNER(NULL, NULL); - } - - /* - * disconnect the task from the context and vice-versa - */ - PFM_SET_WORK_PENDING(task, 0); - - task->thread.pfm_context = NULL; - task->thread.flags &= ~IA64_THREAD_PM_VALID; - - DPRINT(("force cleanup for [%d]\n", task_pid_nr(task))); -} - - -/* - * in 2.6, interrupts are masked when we come here and the runqueue lock is held - */ -void -pfm_save_regs(struct task_struct *task) -{ - pfm_context_t *ctx; - unsigned long flags; - u64 psr; - - - ctx = PFM_GET_CTX(task); - if (ctx == NULL) return; - - /* - * we always come here with interrupts ALREADY disabled by - * the scheduler. So we simply need to protect against concurrent - * access, not CPU concurrency. - */ - flags = pfm_protect_ctx_ctxsw(ctx); - - if (ctx->ctx_state == PFM_CTX_ZOMBIE) { - struct pt_regs *regs = task_pt_regs(task); - - pfm_clear_psr_up(); - - pfm_force_cleanup(ctx, regs); - - BUG_ON(ctx->ctx_smpl_hdr); - - pfm_unprotect_ctx_ctxsw(ctx, flags); - - pfm_context_free(ctx); - return; - } - - /* - * save current PSR: needed because we modify it - */ - ia64_srlz_d(); - psr = pfm_get_psr(); - - BUG_ON(psr & (IA64_PSR_I)); - - /* - * stop monitoring: - * This is the last instruction which may generate an overflow - * - * We do not need to set psr.sp because, it is irrelevant in kernel. - * It will be restored from ipsr when going back to user level - */ - pfm_clear_psr_up(); - - /* - * keep a copy of psr.up (for reload) - */ - ctx->ctx_saved_psr_up = psr & IA64_PSR_UP; - - /* - * release ownership of this PMU. - * PM interrupts are masked, so nothing - * can happen. - */ - SET_PMU_OWNER(NULL, NULL); - - /* - * we systematically save the PMD as we have no - * guarantee we will be schedule at that same - * CPU again. - */ - pfm_save_pmds(ctx->th_pmds, ctx->ctx_used_pmds[0]); - - /* - * save pmc0 ia64_srlz_d() done in pfm_save_pmds() - * we will need it on the restore path to check - * for pending overflow. - */ - ctx->th_pmcs[0] = ia64_get_pmc(0); - - /* - * unfreeze PMU if had pending overflows - */ - if (ctx->th_pmcs[0] & ~0x1UL) pfm_unfreeze_pmu(); - - /* - * finally, allow context access. - * interrupts will still be masked after this call. - */ - pfm_unprotect_ctx_ctxsw(ctx, flags); -} - -#else /* !CONFIG_SMP */ -void -pfm_save_regs(struct task_struct *task) -{ - pfm_context_t *ctx; - u64 psr; - - ctx = PFM_GET_CTX(task); - if (ctx == NULL) return; - - /* - * save current PSR: needed because we modify it - */ - psr = pfm_get_psr(); - - BUG_ON(psr & (IA64_PSR_I)); - - /* - * stop monitoring: - * This is the last instruction which may generate an overflow - * - * We do not need to set psr.sp because, it is irrelevant in kernel. - * It will be restored from ipsr when going back to user level - */ - pfm_clear_psr_up(); - - /* - * keep a copy of psr.up (for reload) - */ - ctx->ctx_saved_psr_up = psr & IA64_PSR_UP; -} - -static void -pfm_lazy_save_regs (struct task_struct *task) -{ - pfm_context_t *ctx; - unsigned long flags; - - { u64 psr = pfm_get_psr(); - BUG_ON(psr & IA64_PSR_UP); - } - - ctx = PFM_GET_CTX(task); - - /* - * we need to mask PMU overflow here to - * make sure that we maintain pmc0 until - * we save it. overflow interrupts are - * treated as spurious if there is no - * owner. - * - * XXX: I don't think this is necessary - */ - PROTECT_CTX(ctx,flags); - - /* - * release ownership of this PMU. - * must be done before we save the registers. - * - * after this call any PMU interrupt is treated - * as spurious. - */ - SET_PMU_OWNER(NULL, NULL); - - /* - * save all the pmds we use - */ - pfm_save_pmds(ctx->th_pmds, ctx->ctx_used_pmds[0]); - - /* - * save pmc0 ia64_srlz_d() done in pfm_save_pmds() - * it is needed to check for pended overflow - * on the restore path - */ - ctx->th_pmcs[0] = ia64_get_pmc(0); - - /* - * unfreeze PMU if had pending overflows - */ - if (ctx->th_pmcs[0] & ~0x1UL) pfm_unfreeze_pmu(); - - /* - * now get can unmask PMU interrupts, they will - * be treated as purely spurious and we will not - * lose any information - */ - UNPROTECT_CTX(ctx,flags); -} -#endif /* CONFIG_SMP */ - -#ifdef CONFIG_SMP -/* - * in 2.6, interrupts are masked when we come here and the runqueue lock is held - */ -void -pfm_load_regs (struct task_struct *task) -{ - pfm_context_t *ctx; - unsigned long pmc_mask = 0UL, pmd_mask = 0UL; - unsigned long flags; - u64 psr, psr_up; - int need_irq_resend; - - ctx = PFM_GET_CTX(task); - if (unlikely(ctx == NULL)) return; - - BUG_ON(GET_PMU_OWNER()); - - /* - * possible on unload - */ - if (unlikely((task->thread.flags & IA64_THREAD_PM_VALID) == 0)) return; - - /* - * we always come here with interrupts ALREADY disabled by - * the scheduler. So we simply need to protect against concurrent - * access, not CPU concurrency. - */ - flags = pfm_protect_ctx_ctxsw(ctx); - psr = pfm_get_psr(); - - need_irq_resend = pmu_conf->flags & PFM_PMU_IRQ_RESEND; - - BUG_ON(psr & (IA64_PSR_UP|IA64_PSR_PP)); - BUG_ON(psr & IA64_PSR_I); - - if (unlikely(ctx->ctx_state == PFM_CTX_ZOMBIE)) { - struct pt_regs *regs = task_pt_regs(task); - - BUG_ON(ctx->ctx_smpl_hdr); - - pfm_force_cleanup(ctx, regs); - - pfm_unprotect_ctx_ctxsw(ctx, flags); - - /* - * this one (kmalloc'ed) is fine with interrupts disabled - */ - pfm_context_free(ctx); - - return; - } - - /* - * we restore ALL the debug registers to avoid picking up - * stale state. - */ - if (ctx->ctx_fl_using_dbreg) { - pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf->num_ibrs); - pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf->num_dbrs); - } - /* - * retrieve saved psr.up - */ - psr_up = ctx->ctx_saved_psr_up; - - /* - * if we were the last user of the PMU on that CPU, - * then nothing to do except restore psr - */ - if (GET_LAST_CPU(ctx) == smp_processor_id() && ctx->ctx_last_activation == GET_ACTIVATION()) { - - /* - * retrieve partial reload masks (due to user modifications) - */ - pmc_mask = ctx->ctx_reload_pmcs[0]; - pmd_mask = ctx->ctx_reload_pmds[0]; - - } else { - /* - * To avoid leaking information to the user level when psr.sp=0, - * we must reload ALL implemented pmds (even the ones we don't use). - * In the kernel we only allow PFM_READ_PMDS on registers which - * we initialized or requested (sampling) so there is no risk there. - */ - pmd_mask = pfm_sysctl.fastctxsw ? ctx->ctx_used_pmds[0] : ctx->ctx_all_pmds[0]; - - /* - * ALL accessible PMCs are systematically reloaded, unused registers - * get their default (from pfm_reset_pmu_state()) values to avoid picking - * up stale configuration. - * - * PMC0 is never in the mask. It is always restored separately. - */ - pmc_mask = ctx->ctx_all_pmcs[0]; - } - /* - * when context is MASKED, we will restore PMC with plm=0 - * and PMD with stale information, but that's ok, nothing - * will be captured. - * - * XXX: optimize here - */ - if (pmd_mask) pfm_restore_pmds(ctx->th_pmds, pmd_mask); - if (pmc_mask) pfm_restore_pmcs(ctx->th_pmcs, pmc_mask); - - /* - * check for pending overflow at the time the state - * was saved. - */ - if (unlikely(PMC0_HAS_OVFL(ctx->th_pmcs[0]))) { - /* - * reload pmc0 with the overflow information - * On McKinley PMU, this will trigger a PMU interrupt - */ - ia64_set_pmc(0, ctx->th_pmcs[0]); - ia64_srlz_d(); - ctx->th_pmcs[0] = 0UL; - - /* - * will replay the PMU interrupt - */ - if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR); - - pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; - } - - /* - * we just did a reload, so we reset the partial reload fields - */ - ctx->ctx_reload_pmcs[0] = 0UL; - ctx->ctx_reload_pmds[0] = 0UL; - - SET_LAST_CPU(ctx, smp_processor_id()); - - /* - * dump activation value for this PMU - */ - INC_ACTIVATION(); - /* - * record current activation for this context - */ - SET_ACTIVATION(ctx); - - /* - * establish new ownership. - */ - SET_PMU_OWNER(task, ctx); - - /* - * restore the psr.up bit. measurement - * is active again. - * no PMU interrupt can happen at this point - * because we still have interrupts disabled. - */ - if (likely(psr_up)) pfm_set_psr_up(); - - /* - * allow concurrent access to context - */ - pfm_unprotect_ctx_ctxsw(ctx, flags); -} -#else /* !CONFIG_SMP */ -/* - * reload PMU state for UP kernels - * in 2.5 we come here with interrupts disabled - */ -void -pfm_load_regs (struct task_struct *task) -{ - pfm_context_t *ctx; - struct task_struct *owner; - unsigned long pmd_mask, pmc_mask; - u64 psr, psr_up; - int need_irq_resend; - - owner = GET_PMU_OWNER(); - ctx = PFM_GET_CTX(task); - psr = pfm_get_psr(); - - BUG_ON(psr & (IA64_PSR_UP|IA64_PSR_PP)); - BUG_ON(psr & IA64_PSR_I); - - /* - * we restore ALL the debug registers to avoid picking up - * stale state. - * - * This must be done even when the task is still the owner - * as the registers may have been modified via ptrace() - * (not perfmon) by the previous task. - */ - if (ctx->ctx_fl_using_dbreg) { - pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf->num_ibrs); - pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf->num_dbrs); - } - - /* - * retrieved saved psr.up - */ - psr_up = ctx->ctx_saved_psr_up; - need_irq_resend = pmu_conf->flags & PFM_PMU_IRQ_RESEND; - - /* - * short path, our state is still there, just - * need to restore psr and we go - * - * we do not touch either PMC nor PMD. the psr is not touched - * by the overflow_handler. So we are safe w.r.t. to interrupt - * concurrency even without interrupt masking. - */ - if (likely(owner == task)) { - if (likely(psr_up)) pfm_set_psr_up(); - return; - } - - /* - * someone else is still using the PMU, first push it out and - * then we'll be able to install our stuff ! - * - * Upon return, there will be no owner for the current PMU - */ - if (owner) pfm_lazy_save_regs(owner); - - /* - * To avoid leaking information to the user level when psr.sp=0, - * we must reload ALL implemented pmds (even the ones we don't use). - * In the kernel we only allow PFM_READ_PMDS on registers which - * we initialized or requested (sampling) so there is no risk there. - */ - pmd_mask = pfm_sysctl.fastctxsw ? ctx->ctx_used_pmds[0] : ctx->ctx_all_pmds[0]; - - /* - * ALL accessible PMCs are systematically reloaded, unused registers - * get their default (from pfm_reset_pmu_state()) values to avoid picking - * up stale configuration. - * - * PMC0 is never in the mask. It is always restored separately - */ - pmc_mask = ctx->ctx_all_pmcs[0]; - - pfm_restore_pmds(ctx->th_pmds, pmd_mask); - pfm_restore_pmcs(ctx->th_pmcs, pmc_mask); - - /* - * check for pending overflow at the time the state - * was saved. - */ - if (unlikely(PMC0_HAS_OVFL(ctx->th_pmcs[0]))) { - /* - * reload pmc0 with the overflow information - * On McKinley PMU, this will trigger a PMU interrupt - */ - ia64_set_pmc(0, ctx->th_pmcs[0]); - ia64_srlz_d(); - - ctx->th_pmcs[0] = 0UL; - - /* - * will replay the PMU interrupt - */ - if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR); - - pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; - } - - /* - * establish new ownership. - */ - SET_PMU_OWNER(task, ctx); - - /* - * restore the psr.up bit. measurement - * is active again. - * no PMU interrupt can happen at this point - * because we still have interrupts disabled. - */ - if (likely(psr_up)) pfm_set_psr_up(); -} -#endif /* CONFIG_SMP */ - -/* - * this function assumes monitoring is stopped - */ -static void -pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx) -{ - u64 pmc0; - unsigned long mask2, val, pmd_val, ovfl_val; - int i, can_access_pmu = 0; - int is_self; - - /* - * is the caller the task being monitored (or which initiated the - * session for system wide measurements) - */ - is_self = ctx->ctx_task == task ? 1 : 0; - - /* - * can access PMU is task is the owner of the PMU state on the current CPU - * or if we are running on the CPU bound to the context in system-wide mode - * (that is not necessarily the task the context is attached to in this mode). - * In system-wide we always have can_access_pmu true because a task running on an - * invalid processor is flagged earlier in the call stack (see pfm_stop). - */ - can_access_pmu = (GET_PMU_OWNER() == task) || (ctx->ctx_fl_system && ctx->ctx_cpu == smp_processor_id()); - if (can_access_pmu) { - /* - * Mark the PMU as not owned - * This will cause the interrupt handler to do nothing in case an overflow - * interrupt was in-flight - * This also guarantees that pmc0 will contain the final state - * It virtually gives us full control on overflow processing from that point - * on. - */ - SET_PMU_OWNER(NULL, NULL); - DPRINT(("releasing ownership\n")); - - /* - * read current overflow status: - * - * we are guaranteed to read the final stable state - */ - ia64_srlz_d(); - pmc0 = ia64_get_pmc(0); /* slow */ - - /* - * reset freeze bit, overflow status information destroyed - */ - pfm_unfreeze_pmu(); - } else { - pmc0 = ctx->th_pmcs[0]; - /* - * clear whatever overflow status bits there were - */ - ctx->th_pmcs[0] = 0; - } - ovfl_val = pmu_conf->ovfl_val; - /* - * we save all the used pmds - * we take care of overflows for counting PMDs - * - * XXX: sampling situation is not taken into account here - */ - mask2 = ctx->ctx_used_pmds[0]; - - DPRINT(("is_self=%d ovfl_val=0x%lx mask2=0x%lx\n", is_self, ovfl_val, mask2)); - - for (i = 0; mask2; i++, mask2>>=1) { - - /* skip non used pmds */ - if ((mask2 & 0x1) == 0) continue; - - /* - * can access PMU always true in system wide mode - */ - val = pmd_val = can_access_pmu ? ia64_get_pmd(i) : ctx->th_pmds[i]; - - if (PMD_IS_COUNTING(i)) { - DPRINT(("[%d] pmd[%d] ctx_pmd=0x%lx hw_pmd=0x%lx\n", - task_pid_nr(task), - i, - ctx->ctx_pmds[i].val, - val & ovfl_val)); - - /* - * we rebuild the full 64 bit value of the counter - */ - val = ctx->ctx_pmds[i].val + (val & ovfl_val); - - /* - * now everything is in ctx_pmds[] and we need - * to clear the saved context from save_regs() such that - * pfm_read_pmds() gets the correct value - */ - pmd_val = 0UL; - - /* - * take care of overflow inline - */ - if (pmc0 & (1UL << i)) { - val += 1 + ovfl_val; - DPRINT(("[%d] pmd[%d] overflowed\n", task_pid_nr(task), i)); - } - } - - DPRINT(("[%d] ctx_pmd[%d]=0x%lx pmd_val=0x%lx\n", task_pid_nr(task), i, val, pmd_val)); - - if (is_self) ctx->th_pmds[i] = pmd_val; - - ctx->ctx_pmds[i].val = val; - } -} - -static void -pfm_alt_save_pmu_state(void *data) -{ - struct pt_regs *regs; - - regs = task_pt_regs(current); - - DPRINT(("called\n")); - - /* - * should not be necessary but - * let's take not risk - */ - pfm_clear_psr_up(); - pfm_clear_psr_pp(); - ia64_psr(regs)->pp = 0; - - /* - * This call is required - * May cause a spurious interrupt on some processors - */ - pfm_freeze_pmu(); - - ia64_srlz_d(); -} - -void -pfm_alt_restore_pmu_state(void *data) -{ - struct pt_regs *regs; - - regs = task_pt_regs(current); - - DPRINT(("called\n")); - - /* - * put PMU back in state expected - * by perfmon - */ - pfm_clear_psr_up(); - pfm_clear_psr_pp(); - ia64_psr(regs)->pp = 0; - - /* - * perfmon runs with PMU unfrozen at all times - */ - pfm_unfreeze_pmu(); - - ia64_srlz_d(); -} - -int -pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl) -{ - int ret, i; - int reserve_cpu; - - /* some sanity checks */ - if (hdl == NULL || hdl->handler == NULL) return -EINVAL; - - /* do the easy test first */ - if (pfm_alt_intr_handler) return -EBUSY; - - /* one at a time in the install or remove, just fail the others */ - if (!spin_trylock(&pfm_alt_install_check)) { - return -EBUSY; - } - - /* reserve our session */ - for_each_online_cpu(reserve_cpu) { - ret = pfm_reserve_session(NULL, 1, reserve_cpu); - if (ret) goto cleanup_reserve; - } - - /* save the current system wide pmu states */ - on_each_cpu(pfm_alt_save_pmu_state, NULL, 1); - - /* officially change to the alternate interrupt handler */ - pfm_alt_intr_handler = hdl; - - spin_unlock(&pfm_alt_install_check); - - return 0; - -cleanup_reserve: - for_each_online_cpu(i) { - /* don't unreserve more than we reserved */ - if (i >= reserve_cpu) break; - - pfm_unreserve_session(NULL, 1, i); - } - - spin_unlock(&pfm_alt_install_check); - - return ret; -} -EXPORT_SYMBOL_GPL(pfm_install_alt_pmu_interrupt); - -int -pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl) -{ - int i; - - if (hdl == NULL) return -EINVAL; - - /* cannot remove someone else's handler! */ - if (pfm_alt_intr_handler != hdl) return -EINVAL; - - /* one at a time in the install or remove, just fail the others */ - if (!spin_trylock(&pfm_alt_install_check)) { - return -EBUSY; - } - - pfm_alt_intr_handler = NULL; - - on_each_cpu(pfm_alt_restore_pmu_state, NULL, 1); - - for_each_online_cpu(i) { - pfm_unreserve_session(NULL, 1, i); - } - - spin_unlock(&pfm_alt_install_check); - - return 0; -} -EXPORT_SYMBOL_GPL(pfm_remove_alt_pmu_interrupt); - -/* - * perfmon initialization routine, called from the initcall() table - */ -static int init_pfm_fs(void); - -static int __init -pfm_probe_pmu(void) -{ - pmu_config_t **p; - int family; - - family = local_cpu_data->family; - p = pmu_confs; - - while(*p) { - if ((*p)->probe) { - if ((*p)->probe() == 0) goto found; - } else if ((*p)->pmu_family == family || (*p)->pmu_family == 0xff) { - goto found; - } - p++; - } - return -1; -found: - pmu_conf = *p; - return 0; -} - -int __init -pfm_init(void) -{ - unsigned int n, n_counters, i; - - printk("perfmon: version %u.%u IRQ %u\n", - PFM_VERSION_MAJ, - PFM_VERSION_MIN, - IA64_PERFMON_VECTOR); - - if (pfm_probe_pmu()) { - printk(KERN_INFO "perfmon: disabled, there is no support for processor family %d\n", - local_cpu_data->family); - return -ENODEV; - } - - /* - * compute the number of implemented PMD/PMC from the - * description tables - */ - n = 0; - for (i=0; PMC_IS_LAST(i) == 0; i++) { - if (PMC_IS_IMPL(i) == 0) continue; - pmu_conf->impl_pmcs[i>>6] |= 1UL << (i&63); - n++; - } - pmu_conf->num_pmcs = n; - - n = 0; n_counters = 0; - for (i=0; PMD_IS_LAST(i) == 0; i++) { - if (PMD_IS_IMPL(i) == 0) continue; - pmu_conf->impl_pmds[i>>6] |= 1UL << (i&63); - n++; - if (PMD_IS_COUNTING(i)) n_counters++; - } - pmu_conf->num_pmds = n; - pmu_conf->num_counters = n_counters; - - /* - * sanity checks on the number of debug registers - */ - if (pmu_conf->use_rr_dbregs) { - if (pmu_conf->num_ibrs > IA64_NUM_DBG_REGS) { - printk(KERN_INFO "perfmon: unsupported number of code debug registers (%u)\n", pmu_conf->num_ibrs); - pmu_conf = NULL; - return -1; - } - if (pmu_conf->num_dbrs > IA64_NUM_DBG_REGS) { - printk(KERN_INFO "perfmon: unsupported number of data debug registers (%u)\n", pmu_conf->num_ibrs); - pmu_conf = NULL; - return -1; - } - } - - printk("perfmon: %s PMU detected, %u PMCs, %u PMDs, %u counters (%lu bits)\n", - pmu_conf->pmu_name, - pmu_conf->num_pmcs, - pmu_conf->num_pmds, - pmu_conf->num_counters, - ffz(pmu_conf->ovfl_val)); - - /* sanity check */ - if (pmu_conf->num_pmds >= PFM_NUM_PMD_REGS || pmu_conf->num_pmcs >= PFM_NUM_PMC_REGS) { - printk(KERN_ERR "perfmon: not enough pmc/pmd, perfmon disabled\n"); - pmu_conf = NULL; - return -1; - } - - /* - * create /proc/perfmon (mostly for debugging purposes) - */ - perfmon_dir = proc_create_seq("perfmon", S_IRUGO, NULL, &pfm_seq_ops); - if (perfmon_dir == NULL) { - printk(KERN_ERR "perfmon: cannot create /proc entry, perfmon disabled\n"); - pmu_conf = NULL; - return -1; - } - - /* - * create /proc/sys/kernel/perfmon (for debugging purposes) - */ - pfm_sysctl_header = register_sysctl_table(pfm_sysctl_root); - - /* - * initialize all our spinlocks - */ - spin_lock_init(&pfm_sessions.pfs_lock); - spin_lock_init(&pfm_buffer_fmt_lock); - - init_pfm_fs(); - - for(i=0; i < NR_CPUS; i++) pfm_stats[i].pfm_ovfl_intr_cycles_min = ~0UL; - - return 0; -} - -__initcall(pfm_init); - -/* - * this function is called before pfm_init() - */ -void -pfm_init_percpu (void) -{ - static int first_time=1; - /* - * make sure no measurement is active - * (may inherit programmed PMCs from EFI). - */ - pfm_clear_psr_pp(); - pfm_clear_psr_up(); - - /* - * we run with the PMU not frozen at all times - */ - pfm_unfreeze_pmu(); - - if (first_time) { - register_percpu_irq(IA64_PERFMON_VECTOR, pfm_interrupt_handler, - 0, "perfmon"); - first_time=0; - } - - ia64_setreg(_IA64_REG_CR_PMV, IA64_PERFMON_VECTOR); - ia64_srlz_d(); -} - -/* - * used for debug purposes only - */ -void -dump_pmu_state(const char *from) -{ - struct task_struct *task; - struct pt_regs *regs; - pfm_context_t *ctx; - unsigned long psr, dcr, info, flags; - int i, this_cpu; - - local_irq_save(flags); - - this_cpu = smp_processor_id(); - regs = task_pt_regs(current); - info = PFM_CPUINFO_GET(); - dcr = ia64_getreg(_IA64_REG_CR_DCR); - - if (info == 0 && ia64_psr(regs)->pp == 0 && (dcr & IA64_DCR_PP) == 0) { - local_irq_restore(flags); - return; - } - - printk("CPU%d from %s() current [%d] iip=0x%lx %s\n", - this_cpu, - from, - task_pid_nr(current), - regs->cr_iip, - current->comm); - - task = GET_PMU_OWNER(); - ctx = GET_PMU_CTX(); - - printk("->CPU%d owner [%d] ctx=%p\n", this_cpu, task ? task_pid_nr(task) : -1, ctx); - - psr = pfm_get_psr(); - - printk("->CPU%d pmc0=0x%lx psr.pp=%d psr.up=%d dcr.pp=%d syst_info=0x%lx user_psr.up=%d user_psr.pp=%d\n", - this_cpu, - ia64_get_pmc(0), - psr & IA64_PSR_PP ? 1 : 0, - psr & IA64_PSR_UP ? 1 : 0, - dcr & IA64_DCR_PP ? 1 : 0, - info, - ia64_psr(regs)->up, - ia64_psr(regs)->pp); - - ia64_psr(regs)->up = 0; - ia64_psr(regs)->pp = 0; - - for (i=1; PMC_IS_LAST(i) == 0; i++) { - if (PMC_IS_IMPL(i) == 0) continue; - printk("->CPU%d pmc[%d]=0x%lx thread_pmc[%d]=0x%lx\n", this_cpu, i, ia64_get_pmc(i), i, ctx->th_pmcs[i]); - } - - for (i=1; PMD_IS_LAST(i) == 0; i++) { - if (PMD_IS_IMPL(i) == 0) continue; - printk("->CPU%d pmd[%d]=0x%lx thread_pmd[%d]=0x%lx\n", this_cpu, i, ia64_get_pmd(i), i, ctx->th_pmds[i]); - } - - if (ctx) { - printk("->CPU%d ctx_state=%d vaddr=%p addr=%p fd=%d ctx_task=[%d] saved_psr_up=0x%lx\n", - this_cpu, - ctx->ctx_state, - ctx->ctx_smpl_vaddr, - ctx->ctx_smpl_hdr, - ctx->ctx_msgq_head, - ctx->ctx_msgq_tail, - ctx->ctx_saved_psr_up); - } - local_irq_restore(flags); -} - -/* - * called from process.c:copy_thread(). task is new child. - */ -void -pfm_inherit(struct task_struct *task, struct pt_regs *regs) -{ - struct thread_struct *thread; - - DPRINT(("perfmon: pfm_inherit clearing state for [%d]\n", task_pid_nr(task))); - - thread = &task->thread; - - /* - * cut links inherited from parent (current) - */ - thread->pfm_context = NULL; - - PFM_SET_WORK_PENDING(task, 0); - - /* - * the psr bits are already set properly in copy_threads() - */ -} -#else /* !CONFIG_PERFMON */ -asmlinkage long -sys_perfmonctl (int fd, int cmd, void *arg, int count) -{ - return -ENOSYS; -} -#endif /* CONFIG_PERFMON */ diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index f19cb97c0098..6b61a703bcf5 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -51,10 +51,6 @@ #include "entry.h" -#ifdef CONFIG_PERFMON -# include <asm/perfmon.h> -#endif - #include "sigframe.h" void (*ia64_mark_idle)(int); @@ -174,22 +170,13 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall) return; } -#ifdef CONFIG_PERFMON - if (current->thread.pfm_needs_checking) - /* - * Note: pfm_handle_work() allow us to call it with interrupts - * disabled, and may enable interrupts within the function. - */ - pfm_handle_work(); -#endif - /* deal with pending signal delivery */ if (test_thread_flag(TIF_SIGPENDING)) { local_irq_enable(); /* force interrupt enable */ ia64_do_signal(scr, in_syscall); } - if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) { + if (test_thread_flag(TIF_NOTIFY_RESUME)) { local_irq_enable(); /* force interrupt enable */ tracehook_notify_resume(&scr->pt); } @@ -264,41 +251,15 @@ void arch_cpu_idle(void) void ia64_save_extra (struct task_struct *task) { -#ifdef CONFIG_PERFMON - unsigned long info; -#endif - if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) ia64_save_debug_regs(&task->thread.dbr[0]); - -#ifdef CONFIG_PERFMON - if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0) - pfm_save_regs(task); - - info = __this_cpu_read(pfm_syst_info); - if (info & PFM_CPUINFO_SYST_WIDE) - pfm_syst_wide_update_task(task, info, 0); -#endif } void ia64_load_extra (struct task_struct *task) { -#ifdef CONFIG_PERFMON - unsigned long info; -#endif - if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) ia64_load_debug_regs(&task->thread.dbr[0]); - -#ifdef CONFIG_PERFMON - if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0) - pfm_load_regs(task); - - info = __this_cpu_read(pfm_syst_info); - if (info & PFM_CPUINFO_SYST_WIDE) - pfm_syst_wide_update_task(task, info, 1); -#endif } /* @@ -310,7 +271,7 @@ ia64_load_extra (struct task_struct *task) * * <clone syscall> <some kernel call frames> * sys_clone : - * _do_fork _do_fork + * kernel_clone kernel_clone * copy_thread copy_thread * * This means that the stack layout is as follows: @@ -432,11 +393,6 @@ copy_thread(unsigned long clone_flags, unsigned long user_stack_base, */ child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET) & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP)); - -#ifdef CONFIG_PERFMON - if (current->thread.pfm_context) - pfm_inherit(p, child_ptregs); -#endif return retval; } @@ -455,7 +411,7 @@ asmlinkage long ia64_clone(unsigned long clone_flags, unsigned long stack_start, .tls = tls, }; - return _do_fork(&args); + return kernel_clone(&args); } static void @@ -563,15 +519,6 @@ exit_thread (struct task_struct *tsk) { ia64_drop_fpu(tsk); -#ifdef CONFIG_PERFMON - /* if needed, stop monitoring and flush state to perfmon context */ - if (tsk->thread.pfm_context) - pfm_exit_thread(tsk); - - /* free debug register resources */ - if (tsk->thread.flags & IA64_THREAD_DBG_VALID) - pfm_release_debug_registers(tsk); -#endif } unsigned long diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 33ca9fa0fbf5..75c070aed81e 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -30,9 +30,6 @@ #include <asm/rse.h> #include <linux/uaccess.h> #include <asm/unwind.h> -#ifdef CONFIG_PERFMON -#include <asm/perfmon.h> -#endif #include "entry.h" @@ -1951,27 +1948,6 @@ access_uarea(struct task_struct *child, unsigned long addr, "address 0x%lx\n", addr); return -1; } -#ifdef CONFIG_PERFMON - /* - * Check if debug registers are used by perfmon. This - * test must be done once we know that we can do the - * operation, i.e. the arguments are all valid, but - * before we start modifying the state. - * - * Perfmon needs to keep a count of how many processes - * are trying to modify the debug registers for system - * wide monitoring sessions. - * - * We also include read access here, because they may - * cause the PMU-installed debug register state - * (dbr[], ibr[]) to be reset. The two arrays are also - * used by perfmon, but we do not use - * IA64_THREAD_DBG_VALID. The registers are restored - * by the PMU context switch code. - */ - if (pfm_use_debug_registers(child)) - return -1; -#endif if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) { child->thread.flags |= IA64_THREAD_DBG_VALID; diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index c29c600d7967..093040f7e626 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -355,10 +355,6 @@ smp_callin (void) extern void ia64_init_itm(void); extern volatile int time_keeper_id; -#ifdef CONFIG_PERFMON - extern void pfm_init_percpu(void); -#endif - cpuid = smp_processor_id(); phys_id = hard_smp_processor_id(); itc_master = time_keeper_id; @@ -389,10 +385,6 @@ smp_callin (void) ia64_mca_cmc_vector_setup(); /* Setup vector on AP */ -#ifdef CONFIG_PERFMON - pfm_init_percpu(); -#endif - local_irq_enable(); if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) { diff --git a/arch/ia64/kernel/syscalls/syscall.tbl b/arch/ia64/kernel/syscalls/syscall.tbl index f52a41f4c340..b96ed8b8a508 100644 --- a/arch/ia64/kernel/syscalls/syscall.tbl +++ b/arch/ia64/kernel/syscalls/syscall.tbl @@ -160,7 +160,7 @@ 148 common mmap2 sys_mmap2 149 common pciconfig_read sys_pciconfig_read 150 common pciconfig_write sys_pciconfig_write -151 common perfmonctl sys_perfmonctl +151 common perfmonctl sys_ni_syscall 152 common sigaltstack sys_sigaltstack 153 common rt_sigaction sys_rt_sigaction 154 common rt_sigpending sys_rt_sigpending @@ -360,3 +360,4 @@ 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 +440 common process_madvise sys_process_madvise diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index d259690eb91a..9b265783be6a 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -218,6 +218,7 @@ SECTIONS { STABS_DEBUG DWARF_DEBUG + ELF_DETAILS /* Default discards */ DISCARDS diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile index 82118b38532f..081fcba01dc0 100644 --- a/arch/ia64/lib/Makefile +++ b/arch/ia64/lib/Makefile @@ -12,7 +12,6 @@ lib-y := io.o __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o -lib-$(CONFIG_PERFMON) += carta_random.o AFLAGS___divdi3.o = AFLAGS___udivdi3.o = -DUNSIGNED diff --git a/arch/ia64/lib/carta_random.S b/arch/ia64/lib/carta_random.S deleted file mode 100644 index 1a4a639dc42f..000000000000 --- a/arch/ia64/lib/carta_random.S +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Fast, simple, yet decent quality random number generator based on - * a paper by David G. Carta ("Two Fast Implementations of the - * `Minimal Standard' Random Number Generator," Communications of the - * ACM, January, 1990). - * - * Copyright (C) 2002 Hewlett-Packard Co - * David Mosberger-Tang <davidm@hpl.hp.com> - */ - -#include <asm/asmmacro.h> - -#define a r2 -#define m r3 -#define lo r8 -#define hi r9 -#define t0 r16 -#define t1 r17 -#define seed r32 - -GLOBAL_ENTRY(carta_random32) - movl a = (16807 << 16) | 16807 - ;; - pmpyshr2.u t0 = a, seed, 0 - pmpyshr2.u t1 = a, seed, 16 - ;; - unpack2.l t0 = t1, t0 - dep m = -1, r0, 0, 31 - ;; - zxt4 lo = t0 - shr.u hi = t0, 32 - ;; - dep t0 = 0, hi, 15, 49 // t0 = (hi & 0x7fff) - ;; - shl t0 = t0, 16 // t0 = (hi & 0x7fff) << 16 - shr t1 = hi, 15 // t1 = (hi >> 15) - ;; - add lo = lo, t0 - ;; - cmp.gtu p6, p0 = lo, m - ;; -(p6) and lo = lo, m - ;; -(p6) add lo = 1, lo - ;; - add lo = lo, t1 - ;; - cmp.gtu p6, p0 = lo, m - ;; -(p6) and lo = lo, m - ;; -(p6) add lo = 1, lo - br.ret.sptk.many rp -END(carta_random32) diff --git a/arch/ia64/lib/csum_partial_copy.c b/arch/ia64/lib/csum_partial_copy.c index 6e82e0be8040..917e3138b277 100644 --- a/arch/ia64/lib/csum_partial_copy.c +++ b/arch/ia64/lib/csum_partial_copy.c @@ -96,18 +96,3 @@ unsigned long do_csum_c(const unsigned char * buff, int len, unsigned int psum) out: return result; } - -/* - * XXX Fixme - * - * This is very ugly but temporary. THIS NEEDS SERIOUS ENHANCEMENTS. - * But it's very tricky to get right even in C. - */ -__wsum -csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) -{ - memcpy(dst, src, len); - return csum_partial(dst, len, sum); -} - -EXPORT_SYMBOL(csum_partial_copy_nocheck); diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 0b3fb4c7af29..ef12e097f318 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -8,7 +8,7 @@ #include <linux/kernel.h> #include <linux/init.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <linux/dmar.h> #include <linux/efi.h> #include <linux/elf.h> @@ -73,8 +73,7 @@ __ia64_sync_icache_dcache (pte_t pte) * DMA can be marked as "clean" so that lazy_mmu_prot_update() doesn't have to * flush them when they get mapped into an executable vm-area. */ -void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, - enum dma_data_direction dir) +void arch_dma_mark_clean(phys_addr_t paddr, size_t size) { unsigned long pfn = PHYS_PFN(paddr); @@ -538,7 +537,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), - MEMMAP_EARLY, NULL); + MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); return 0; } @@ -547,8 +546,8 @@ 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_EARLY, - NULL); + memmap_init_zone(size, nid, zone, start_pfn, + MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); } else { struct page *start; struct memmap_init_callback_data args; diff --git a/arch/ia64/oprofile/Makefile b/arch/ia64/oprofile/Makefile index cd134d6643bf..fc7944d462f4 100644 --- a/arch/ia64/oprofile/Makefile +++ b/arch/ia64/oprofile/Makefile @@ -8,4 +8,3 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ timer_int.o ) oprofile-y := $(DRIVER_OBJS) init.o backtrace.o -oprofile-$(CONFIG_PERFMON) += perfmon.o diff --git a/arch/ia64/oprofile/init.c b/arch/ia64/oprofile/init.c index 31b545c35460..a692ba16a07b 100644 --- a/arch/ia64/oprofile/init.c +++ b/arch/ia64/oprofile/init.c @@ -18,21 +18,11 @@ extern void ia64_backtrace(struct pt_regs * const regs, unsigned int depth); int __init oprofile_arch_init(struct oprofile_operations *ops) { - int ret = -ENODEV; - -#ifdef CONFIG_PERFMON - /* perfmon_init() can fail, but we have no way to report it */ - ret = perfmon_init(ops); -#endif ops->backtrace = ia64_backtrace; - - return ret; + return -ENODEV; } void oprofile_arch_exit(void) { -#ifdef CONFIG_PERFMON - perfmon_exit(); -#endif } diff --git a/arch/ia64/oprofile/perfmon.c b/arch/ia64/oprofile/perfmon.c deleted file mode 100644 index 192d3e8e1f65..000000000000 --- a/arch/ia64/oprofile/perfmon.c +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file perfmon.c - * - * @remark Copyright 2003 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon <levon@movementarian.org> - */ - -#include <linux/kernel.h> -#include <linux/oprofile.h> -#include <linux/sched.h> -#include <asm/perfmon.h> -#include <asm/ptrace.h> -#include <asm/errno.h> - -static int allow_ints; - -static int -perfmon_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, - struct pt_regs *regs, unsigned long stamp) -{ - int event = arg->pmd_eventid; - - arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1; - - /* the owner of the oprofile event buffer may have exited - * without perfmon being shutdown (e.g. SIGSEGV) - */ - if (allow_ints) - oprofile_add_sample(regs, event); - return 0; -} - - -static int perfmon_start(void) -{ - allow_ints = 1; - return 0; -} - - -static void perfmon_stop(void) -{ - allow_ints = 0; -} - - -#define OPROFILE_FMT_UUID { \ - 0x77, 0x7a, 0x6e, 0x61, 0x20, 0x65, 0x73, 0x69, 0x74, 0x6e, 0x72, 0x20, 0x61, 0x65, 0x0a, 0x6c } - -static pfm_buffer_fmt_t oprofile_fmt = { - .fmt_name = "oprofile_format", - .fmt_uuid = OPROFILE_FMT_UUID, - .fmt_handler = perfmon_handler, -}; - - -static char *get_cpu_type(void) -{ - __u8 family = local_cpu_data->family; - - switch (family) { - case 0x07: - return "ia64/itanium"; - case 0x1f: - return "ia64/itanium2"; - default: - return "ia64/ia64"; - } -} - - -/* all the ops are handled via userspace for IA64 perfmon */ - -static int using_perfmon; - -int perfmon_init(struct oprofile_operations *ops) -{ - int ret = pfm_register_buffer_fmt(&oprofile_fmt); - if (ret) - return -ENODEV; - - ops->cpu_type = get_cpu_type(); - ops->start = perfmon_start; - ops->stop = perfmon_stop; - using_perfmon = 1; - printk(KERN_INFO "oprofile: using perfmon.\n"); - return 0; -} - - -void perfmon_exit(void) -{ - if (!using_perfmon) - return; - - pfm_unregister_buffer_fmt(oprofile_fmt.fmt_uuid); -} diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 6f2f38d05772..372e4e69c43a 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -6,32 +6,34 @@ config M68K select ARCH_HAS_BINFMT_FLAT select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA + select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS select ARCH_MIGHT_HAVE_PC_PARPORT if ISA select ARCH_NO_PREEMPT if !COLDFIRE + select ARCH_WANT_IPC_PARSE_VERSION select BINFMT_FLAT_ARGVP_ENVP_ON_STACK select DMA_DIRECT_REMAP if HAS_DMA && MMU && !COLDFIRE - select HAVE_IDE - select HAVE_AOUT if MMU - select HAVE_ASM_MODVERSIONS - select HAVE_DEBUG_BUGVERBOSE - select GENERIC_IRQ_SHOW select GENERIC_ATOMIC64 - select NO_DMA if !MMU && !COLDFIRE - select HAVE_UID16 - select VIRT_TO_BUS - select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS select GENERIC_CPU_DEVICES select GENERIC_IOMAP + select GENERIC_IRQ_SHOW select GENERIC_STRNCPY_FROM_USER if MMU select GENERIC_STRNLEN_USER if MMU - select ARCH_WANT_IPC_PARSE_VERSION + select HAVE_AOUT if MMU + select HAVE_ASM_MODVERSIONS + select HAVE_DEBUG_BUGVERBOSE select HAVE_FUTEX_CMPXCHG if MMU && FUTEX + select HAVE_IDE select HAVE_MOD_ARCH_SPECIFIC + select HAVE_UID16 + select MMU_GATHER_NO_RANGE if MMU select MODULES_USE_ELF_REL select MODULES_USE_ELF_RELA - select OLD_SIGSUSPEND3 + select NO_DMA if !MMU && !COLDFIRE select OLD_SIGACTION - select MMU_GATHER_NO_RANGE if MMU + select OLD_SIGSUSPEND3 + select SET_FS + select UACCESS_MEMCPY if !MMU + select VIRT_TO_BUS config CPU_BIG_ENDIAN def_bool y diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index 4438ffb4bbe1..ea14f2046fb4 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile @@ -75,7 +75,6 @@ KBUILD_CPPFLAGS += -D__uClinux__ endif KBUILD_LDFLAGS := -m m68kelf -KBUILD_LDS_MODULE += $(srctree)/arch/m68k/kernel/module.lds ifdef CONFIG_SUN3 LDFLAGS_vmlinux = -N diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index 8f23b2fab64c..bee9f240f35d 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c @@ -214,7 +214,7 @@ static void __init amiga_identify(void) switch (amiga_model) { case AMI_UNKNOWN: - goto Generic; + break; case AMI_600: case AMI_1200: @@ -227,7 +227,7 @@ static void __init amiga_identify(void) case AMI_2000: case AMI_2500: AMIGAHW_SET(A2000_CLK); /* Is this correct for all models? */ - goto Generic; + break; case AMI_3000: case AMI_3000T: @@ -238,7 +238,7 @@ static void __init amiga_identify(void) AMIGAHW_SET(A3000_SCSI); AMIGAHW_SET(A3000_CLK); AMIGAHW_SET(ZORRO3); - goto Generic; + break; case AMI_4000T: AMIGAHW_SET(A4000_SCSI); @@ -247,68 +247,12 @@ static void __init amiga_identify(void) AMIGAHW_SET(A4000_IDE); AMIGAHW_SET(A3000_CLK); AMIGAHW_SET(ZORRO3); - goto Generic; + break; case AMI_CDTV: case AMI_CD32: AMIGAHW_SET(CD_ROM); AMIGAHW_SET(A2000_CLK); /* Is this correct? */ - goto Generic; - - Generic: - AMIGAHW_SET(AMI_VIDEO); - AMIGAHW_SET(AMI_BLITTER); - AMIGAHW_SET(AMI_AUDIO); - AMIGAHW_SET(AMI_FLOPPY); - AMIGAHW_SET(AMI_KEYBOARD); - AMIGAHW_SET(AMI_MOUSE); - AMIGAHW_SET(AMI_SERIAL); - AMIGAHW_SET(AMI_PARALLEL); - AMIGAHW_SET(CHIP_RAM); - AMIGAHW_SET(PAULA); - - switch (amiga_chipset) { - case CS_OCS: - case CS_ECS: - case CS_AGA: - switch (amiga_custom.deniseid & 0xf) { - case 0x0c: - AMIGAHW_SET(DENISE_HR); - break; - case 0x08: - AMIGAHW_SET(LISA); - break; - } - break; - default: - AMIGAHW_SET(DENISE); - break; - } - switch ((amiga_custom.vposr>>8) & 0x7f) { - case 0x00: - AMIGAHW_SET(AGNUS_PAL); - break; - case 0x10: - AMIGAHW_SET(AGNUS_NTSC); - break; - case 0x20: - case 0x21: - AMIGAHW_SET(AGNUS_HR_PAL); - break; - case 0x30: - case 0x31: - AMIGAHW_SET(AGNUS_HR_NTSC); - break; - case 0x22: - case 0x23: - AMIGAHW_SET(ALICE_PAL); - break; - case 0x32: - case 0x33: - AMIGAHW_SET(ALICE_NTSC); - break; - } - AMIGAHW_SET(ZORRO); break; case AMI_DRACO: @@ -318,6 +262,60 @@ static void __init amiga_identify(void) panic("Unknown Amiga Model"); } + AMIGAHW_SET(AMI_VIDEO); + AMIGAHW_SET(AMI_BLITTER); + AMIGAHW_SET(AMI_AUDIO); + AMIGAHW_SET(AMI_FLOPPY); + AMIGAHW_SET(AMI_KEYBOARD); + AMIGAHW_SET(AMI_MOUSE); + AMIGAHW_SET(AMI_SERIAL); + AMIGAHW_SET(AMI_PARALLEL); + AMIGAHW_SET(CHIP_RAM); + AMIGAHW_SET(PAULA); + + switch (amiga_chipset) { + case CS_OCS: + case CS_ECS: + case CS_AGA: + switch (amiga_custom.deniseid & 0xf) { + case 0x0c: + AMIGAHW_SET(DENISE_HR); + break; + case 0x08: + AMIGAHW_SET(LISA); + break; + default: + AMIGAHW_SET(DENISE); + break; + } + break; + } + switch ((amiga_custom.vposr>>8) & 0x7f) { + case 0x00: + AMIGAHW_SET(AGNUS_PAL); + break; + case 0x10: + AMIGAHW_SET(AGNUS_NTSC); + break; + case 0x20: + case 0x21: + AMIGAHW_SET(AGNUS_HR_PAL); + break; + case 0x30: + case 0x31: + AMIGAHW_SET(AGNUS_HR_NTSC); + break; + case 0x22: + case 0x23: + AMIGAHW_SET(ALICE_PAL); + break; + case 0x32: + case 0x33: + AMIGAHW_SET(ALICE_NTSC); + break; + } + AMIGAHW_SET(ZORRO); + #define AMIGAHW_ANNOUNCE(name, str) \ if (AMIGAHW_PRESENT(name)) \ pr_cont(str) diff --git a/arch/m68k/coldfire/device.c b/arch/m68k/coldfire/device.c index 9ef4ec0aea00..59f7dfe50a4d 100644 --- a/arch/m68k/coldfire/device.c +++ b/arch/m68k/coldfire/device.c @@ -554,7 +554,7 @@ static struct platform_device mcf_edma = { }; #endif /* IS_ENABLED(CONFIG_MCF_EDMA) */ -#if IS_ENABLED(CONFIG_MMC) +#ifdef MCFSDHC_BASE static struct mcf_esdhc_platform_data mcf_esdhc_data = { .max_bus_width = 4, .cd_type = ESDHC_CD_NONE, @@ -579,7 +579,7 @@ static struct platform_device mcf_esdhc = { .resource = mcf_esdhc_resources, .dev.platform_data = &mcf_esdhc_data, }; -#endif /* IS_ENABLED(CONFIG_MMC) */ +#endif /* MCFSDHC_BASE */ static struct platform_device *mcf_devices[] __initdata = { &mcf_uart, @@ -613,7 +613,7 @@ static struct platform_device *mcf_devices[] __initdata = { #if IS_ENABLED(CONFIG_MCF_EDMA) &mcf_edma, #endif -#if IS_ENABLED(CONFIG_MMC) +#ifdef MCFSDHC_BASE &mcf_esdhc, #endif }; diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 522dcf624aa5..3cd76bfaee03 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -317,6 +317,7 @@ CONFIG_DUMMY_IRQ=m CONFIG_IDE=y CONFIG_IDE_GD_ATAPI=y CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_PLATFORM=y CONFIG_BLK_DEV_MAC_IDE=y CONFIG_RAID_ATTRS=m CONFIG_SCSI=y diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig index 2433409f4369..c3d6faa7894f 100644 --- a/arch/m68k/configs/multi_defconfig +++ b/arch/m68k/configs/multi_defconfig @@ -346,6 +346,7 @@ CONFIG_DUMMY_IRQ=m CONFIG_IDE=y CONFIG_IDE_GD_ATAPI=y CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_PLATFORM=y CONFIG_BLK_DEV_GAYLE=y CONFIG_BLK_DEV_BUDDHA=y CONFIG_BLK_DEV_FALCON_IDE=y diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h index 3f2c15d6f18c..692e7b6cc042 100644 --- a/arch/m68k/include/asm/checksum.h +++ b/arch/m68k/include/asm/checksum.h @@ -31,14 +31,13 @@ __wsum csum_partial(const void *buff, int len, __wsum sum); */ #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER +#define _HAVE_ARCH_CSUM_AND_COPY extern __wsum csum_and_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, - int *csum_err); + int len); extern __wsum csum_partial_copy_nocheck(const void *src, - void *dst, int len, - __wsum sum); + void *dst, int len); /* * This is a version of ip_fast_csum() optimized for IP headers, diff --git a/arch/m68k/kernel/module.lds b/arch/m68k/include/asm/module.lds.h index fda94fa38243..fda94fa38243 100644 --- a/arch/m68k/kernel/module.lds +++ b/arch/m68k/include/asm/module.lds.h diff --git a/arch/m68k/include/asm/thread_info.h b/arch/m68k/include/asm/thread_info.h index 015f1ca38305..3689c6718c88 100644 --- a/arch/m68k/include/asm/thread_info.h +++ b/arch/m68k/include/asm/thread_info.h @@ -68,4 +68,12 @@ static inline struct thread_info *current_thread_info(void) #define TIF_MEMDIE 16 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 18 /* restore signal mask in do_signal */ +#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) +#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) +#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) +#define _TIF_DELAYED_TRACE (1 << TIF_DELAYED_TRACE) +#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) +#define _TIF_MEMDIE (1 << TIF_MEMDIE) +#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) + #endif /* _ASM_M68K_THREAD_INFO_H */ diff --git a/arch/m68k/include/asm/uaccess.h b/arch/m68k/include/asm/uaccess.h index e896466a41a4..f98208ccbbcd 100644 --- a/arch/m68k/include/asm/uaccess.h +++ b/arch/m68k/include/asm/uaccess.h @@ -1,7 +1,397 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifdef __uClinux__ -#include <asm/uaccess_no.h> +#ifndef __M68K_UACCESS_H +#define __M68K_UACCESS_H + +#ifdef CONFIG_MMU + +/* + * User space memory access functions + */ +#include <linux/compiler.h> +#include <linux/types.h> +#include <asm/segment.h> +#include <asm/extable.h> + +/* We let the MMU do all checking */ +static inline int access_ok(const void __user *addr, + unsigned long size) +{ + return 1; +} + +/* + * Not all varients of the 68k family support the notion of address spaces. + * The traditional 680x0 parts do, and they use the sfc/dfc registers and + * the "moves" instruction to access user space from kernel space. Other + * family members like ColdFire don't support this, and only have a single + * address space, and use the usual "move" instruction for user space access. + * + * Outside of this difference the user space access functions are the same. + * So lets keep the code simple and just define in what we need to use. + */ +#ifdef CONFIG_CPU_HAS_ADDRESS_SPACES +#define MOVES "moves" #else -#include <asm/uaccess_mm.h> +#define MOVES "move" #endif -#include <asm/extable.h> + +extern int __put_user_bad(void); +extern int __get_user_bad(void); + +#define __put_user_asm(res, x, ptr, bwl, reg, err) \ +asm volatile ("\n" \ + "1: "MOVES"."#bwl" %2,%1\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .even\n" \ + "10: moveq.l %3,%0\n" \ + " jra 2b\n" \ + " .previous\n" \ + "\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,10b\n" \ + " .long 2b,10b\n" \ + " .previous" \ + : "+d" (res), "=m" (*(ptr)) \ + : #reg (x), "i" (err)) + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + */ + +#define __put_user(x, ptr) \ +({ \ + typeof(*(ptr)) __pu_val = (x); \ + int __pu_err = 0; \ + __chk_user_ptr(ptr); \ + switch (sizeof (*(ptr))) { \ + case 1: \ + __put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT); \ + break; \ + case 2: \ + __put_user_asm(__pu_err, __pu_val, ptr, w, r, -EFAULT); \ + break; \ + case 4: \ + __put_user_asm(__pu_err, __pu_val, ptr, l, r, -EFAULT); \ + break; \ + case 8: \ + { \ + const void __user *__pu_ptr = (ptr); \ + asm volatile ("\n" \ + "1: "MOVES".l %2,(%1)+\n" \ + "2: "MOVES".l %R2,(%1)\n" \ + "3:\n" \ + " .section .fixup,\"ax\"\n" \ + " .even\n" \ + "10: movel %3,%0\n" \ + " jra 3b\n" \ + " .previous\n" \ + "\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,10b\n" \ + " .long 2b,10b\n" \ + " .long 3b,10b\n" \ + " .previous" \ + : "+d" (__pu_err), "+a" (__pu_ptr) \ + : "r" (__pu_val), "i" (-EFAULT) \ + : "memory"); \ + break; \ + } \ + default: \ + __pu_err = __put_user_bad(); \ + break; \ + } \ + __pu_err; \ +}) +#define put_user(x, ptr) __put_user(x, ptr) + + +#define __get_user_asm(res, x, ptr, type, bwl, reg, err) ({ \ + type __gu_val; \ + asm volatile ("\n" \ + "1: "MOVES"."#bwl" %2,%1\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .even\n" \ + "10: move.l %3,%0\n" \ + " sub.l %1,%1\n" \ + " jra 2b\n" \ + " .previous\n" \ + "\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,10b\n" \ + " .previous" \ + : "+d" (res), "=&" #reg (__gu_val) \ + : "m" (*(ptr)), "i" (err)); \ + (x) = (__force typeof(*(ptr)))(__force unsigned long)__gu_val; \ +}) + +#define __get_user(x, ptr) \ +({ \ + int __gu_err = 0; \ + __chk_user_ptr(ptr); \ + switch (sizeof(*(ptr))) { \ + case 1: \ + __get_user_asm(__gu_err, x, ptr, u8, b, d, -EFAULT); \ + break; \ + case 2: \ + __get_user_asm(__gu_err, x, ptr, u16, w, r, -EFAULT); \ + break; \ + case 4: \ + __get_user_asm(__gu_err, x, ptr, u32, l, r, -EFAULT); \ + break; \ + case 8: { \ + const void __user *__gu_ptr = (ptr); \ + union { \ + u64 l; \ + __typeof__(*(ptr)) t; \ + } __gu_val; \ + asm volatile ("\n" \ + "1: "MOVES".l (%2)+,%1\n" \ + "2: "MOVES".l (%2),%R1\n" \ + "3:\n" \ + " .section .fixup,\"ax\"\n" \ + " .even\n" \ + "10: move.l %3,%0\n" \ + " sub.l %1,%1\n" \ + " sub.l %R1,%R1\n" \ + " jra 3b\n" \ + " .previous\n" \ + "\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,10b\n" \ + " .long 2b,10b\n" \ + " .previous" \ + : "+d" (__gu_err), "=&r" (__gu_val.l), \ + "+a" (__gu_ptr) \ + : "i" (-EFAULT) \ + : "memory"); \ + (x) = __gu_val.t; \ + break; \ + } \ + default: \ + __gu_err = __get_user_bad(); \ + break; \ + } \ + __gu_err; \ +}) +#define get_user(x, ptr) __get_user(x, ptr) + +unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n); +unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned long n); + +#define __suffix0 +#define __suffix1 b +#define __suffix2 w +#define __suffix4 l + +#define ____constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3)\ + asm volatile ("\n" \ + "1: "MOVES"."#s1" (%2)+,%3\n" \ + " move."#s1" %3,(%1)+\n" \ + " .ifnc \""#s2"\",\"\"\n" \ + "2: "MOVES"."#s2" (%2)+,%3\n" \ + " move."#s2" %3,(%1)+\n" \ + " .ifnc \""#s3"\",\"\"\n" \ + "3: "MOVES"."#s3" (%2)+,%3\n" \ + " move."#s3" %3,(%1)+\n" \ + " .endif\n" \ + " .endif\n" \ + "4:\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,10f\n" \ + " .ifnc \""#s2"\",\"\"\n" \ + " .long 2b,20f\n" \ + " .ifnc \""#s3"\",\"\"\n" \ + " .long 3b,30f\n" \ + " .endif\n" \ + " .endif\n" \ + " .previous\n" \ + "\n" \ + " .section .fixup,\"ax\"\n" \ + " .even\n" \ + "10: addq.l #"#n1",%0\n" \ + " .ifnc \""#s2"\",\"\"\n" \ + "20: addq.l #"#n2",%0\n" \ + " .ifnc \""#s3"\",\"\"\n" \ + "30: addq.l #"#n3",%0\n" \ + " .endif\n" \ + " .endif\n" \ + " jra 4b\n" \ + " .previous\n" \ + : "+d" (res), "+&a" (to), "+a" (from), "=&d" (tmp) \ + : : "memory") + +#define ___constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3)\ + ____constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3) +#define __constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3) \ + ___constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, \ + __suffix##n1, __suffix##n2, __suffix##n3) + +static __always_inline unsigned long +__constant_copy_from_user(void *to, const void __user *from, unsigned long n) +{ + unsigned long res = 0, tmp; + + switch (n) { + case 1: + __constant_copy_from_user_asm(res, to, from, tmp, 1, 0, 0); + break; + case 2: + __constant_copy_from_user_asm(res, to, from, tmp, 2, 0, 0); + break; + case 3: + __constant_copy_from_user_asm(res, to, from, tmp, 2, 1, 0); + break; + case 4: + __constant_copy_from_user_asm(res, to, from, tmp, 4, 0, 0); + break; + case 5: + __constant_copy_from_user_asm(res, to, from, tmp, 4, 1, 0); + break; + case 6: + __constant_copy_from_user_asm(res, to, from, tmp, 4, 2, 0); + break; + case 7: + __constant_copy_from_user_asm(res, to, from, tmp, 4, 2, 1); + break; + case 8: + __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 0); + break; + case 9: + __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 1); + break; + case 10: + __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 2); + break; + case 12: + __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 4); + break; + default: + /* we limit the inlined version to 3 moves */ + return __generic_copy_from_user(to, from, n); + } + + return res; +} + +#define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3) \ + asm volatile ("\n" \ + " move."#s1" (%2)+,%3\n" \ + "11: "MOVES"."#s1" %3,(%1)+\n" \ + "12: move."#s2" (%2)+,%3\n" \ + "21: "MOVES"."#s2" %3,(%1)+\n" \ + "22:\n" \ + " .ifnc \""#s3"\",\"\"\n" \ + " move."#s3" (%2)+,%3\n" \ + "31: "MOVES"."#s3" %3,(%1)+\n" \ + "32:\n" \ + " .endif\n" \ + "4:\n" \ + "\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 11b,5f\n" \ + " .long 12b,5f\n" \ + " .long 21b,5f\n" \ + " .long 22b,5f\n" \ + " .ifnc \""#s3"\",\"\"\n" \ + " .long 31b,5f\n" \ + " .long 32b,5f\n" \ + " .endif\n" \ + " .previous\n" \ + "\n" \ + " .section .fixup,\"ax\"\n" \ + " .even\n" \ + "5: moveq.l #"#n",%0\n" \ + " jra 4b\n" \ + " .previous\n" \ + : "+d" (res), "+a" (to), "+a" (from), "=&d" (tmp) \ + : : "memory") + +static __always_inline unsigned long +__constant_copy_to_user(void __user *to, const void *from, unsigned long n) +{ + unsigned long res = 0, tmp; + + switch (n) { + case 1: + __put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1); + break; + case 2: + __put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, r, 2); + break; + case 3: + __constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,); + break; + case 4: + __put_user_asm(res, *(u32 *)from, (u32 __user *)to, l, r, 4); + break; + case 5: + __constant_copy_to_user_asm(res, to, from, tmp, 5, l, b,); + break; + case 6: + __constant_copy_to_user_asm(res, to, from, tmp, 6, l, w,); + break; + case 7: + __constant_copy_to_user_asm(res, to, from, tmp, 7, l, w, b); + break; + case 8: + __constant_copy_to_user_asm(res, to, from, tmp, 8, l, l,); + break; + case 9: + __constant_copy_to_user_asm(res, to, from, tmp, 9, l, l, b); + break; + case 10: + __constant_copy_to_user_asm(res, to, from, tmp, 10, l, l, w); + break; + case 12: + __constant_copy_to_user_asm(res, to, from, tmp, 12, l, l, l); + break; + default: + /* limit the inlined version to 3 moves */ + return __generic_copy_to_user(to, from, n); + } + + return res; +} + +static inline unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long n) +{ + if (__builtin_constant_p(n)) + return __constant_copy_from_user(to, from, n); + return __generic_copy_from_user(to, from, n); +} + +static inline unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) +{ + if (__builtin_constant_p(n)) + return __constant_copy_to_user(to, from, n); + return __generic_copy_to_user(to, from, n); +} +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER + +#define user_addr_max() \ + (uaccess_kernel() ? ~0UL : TASK_SIZE) + +extern long strncpy_from_user(char *dst, const char __user *src, long count); +extern __must_check long strnlen_user(const char __user *str, long n); + +unsigned long __clear_user(void __user *to, unsigned long n); + +#define clear_user __clear_user + +#else /* !CONFIG_MMU */ +#include <asm-generic/uaccess.h> +#endif + +#endif /* _M68K_UACCESS_H */ diff --git a/arch/m68k/include/asm/uaccess_mm.h b/arch/m68k/include/asm/uaccess_mm.h deleted file mode 100644 index 9ae9f8d05925..000000000000 --- a/arch/m68k/include/asm/uaccess_mm.h +++ /dev/null @@ -1,390 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __M68K_UACCESS_H -#define __M68K_UACCESS_H - -/* - * User space memory access functions - */ -#include <linux/compiler.h> -#include <linux/types.h> -#include <asm/segment.h> - -/* We let the MMU do all checking */ -static inline int access_ok(const void __user *addr, - unsigned long size) -{ - return 1; -} - -/* - * Not all varients of the 68k family support the notion of address spaces. - * The traditional 680x0 parts do, and they use the sfc/dfc registers and - * the "moves" instruction to access user space from kernel space. Other - * family members like ColdFire don't support this, and only have a single - * address space, and use the usual "move" instruction for user space access. - * - * Outside of this difference the user space access functions are the same. - * So lets keep the code simple and just define in what we need to use. - */ -#ifdef CONFIG_CPU_HAS_ADDRESS_SPACES -#define MOVES "moves" -#else -#define MOVES "move" -#endif - -extern int __put_user_bad(void); -extern int __get_user_bad(void); - -#define __put_user_asm(res, x, ptr, bwl, reg, err) \ -asm volatile ("\n" \ - "1: "MOVES"."#bwl" %2,%1\n" \ - "2:\n" \ - " .section .fixup,\"ax\"\n" \ - " .even\n" \ - "10: moveq.l %3,%0\n" \ - " jra 2b\n" \ - " .previous\n" \ - "\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 4\n" \ - " .long 1b,10b\n" \ - " .long 2b,10b\n" \ - " .previous" \ - : "+d" (res), "=m" (*(ptr)) \ - : #reg (x), "i" (err)) - -/* - * These are the main single-value transfer routines. They automatically - * use the right size if we just have the right pointer type. - */ - -#define __put_user(x, ptr) \ -({ \ - typeof(*(ptr)) __pu_val = (x); \ - int __pu_err = 0; \ - __chk_user_ptr(ptr); \ - switch (sizeof (*(ptr))) { \ - case 1: \ - __put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT); \ - break; \ - case 2: \ - __put_user_asm(__pu_err, __pu_val, ptr, w, r, -EFAULT); \ - break; \ - case 4: \ - __put_user_asm(__pu_err, __pu_val, ptr, l, r, -EFAULT); \ - break; \ - case 8: \ - { \ - const void __user *__pu_ptr = (ptr); \ - asm volatile ("\n" \ - "1: "MOVES".l %2,(%1)+\n" \ - "2: "MOVES".l %R2,(%1)\n" \ - "3:\n" \ - " .section .fixup,\"ax\"\n" \ - " .even\n" \ - "10: movel %3,%0\n" \ - " jra 3b\n" \ - " .previous\n" \ - "\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 4\n" \ - " .long 1b,10b\n" \ - " .long 2b,10b\n" \ - " .long 3b,10b\n" \ - " .previous" \ - : "+d" (__pu_err), "+a" (__pu_ptr) \ - : "r" (__pu_val), "i" (-EFAULT) \ - : "memory"); \ - break; \ - } \ - default: \ - __pu_err = __put_user_bad(); \ - break; \ - } \ - __pu_err; \ -}) -#define put_user(x, ptr) __put_user(x, ptr) - - -#define __get_user_asm(res, x, ptr, type, bwl, reg, err) ({ \ - type __gu_val; \ - asm volatile ("\n" \ - "1: "MOVES"."#bwl" %2,%1\n" \ - "2:\n" \ - " .section .fixup,\"ax\"\n" \ - " .even\n" \ - "10: move.l %3,%0\n" \ - " sub.l %1,%1\n" \ - " jra 2b\n" \ - " .previous\n" \ - "\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 4\n" \ - " .long 1b,10b\n" \ - " .previous" \ - : "+d" (res), "=&" #reg (__gu_val) \ - : "m" (*(ptr)), "i" (err)); \ - (x) = (__force typeof(*(ptr)))(__force unsigned long)__gu_val; \ -}) - -#define __get_user(x, ptr) \ -({ \ - int __gu_err = 0; \ - __chk_user_ptr(ptr); \ - switch (sizeof(*(ptr))) { \ - case 1: \ - __get_user_asm(__gu_err, x, ptr, u8, b, d, -EFAULT); \ - break; \ - case 2: \ - __get_user_asm(__gu_err, x, ptr, u16, w, r, -EFAULT); \ - break; \ - case 4: \ - __get_user_asm(__gu_err, x, ptr, u32, l, r, -EFAULT); \ - break; \ - case 8: { \ - const void __user *__gu_ptr = (ptr); \ - union { \ - u64 l; \ - __typeof__(*(ptr)) t; \ - } __gu_val; \ - asm volatile ("\n" \ - "1: "MOVES".l (%2)+,%1\n" \ - "2: "MOVES".l (%2),%R1\n" \ - "3:\n" \ - " .section .fixup,\"ax\"\n" \ - " .even\n" \ - "10: move.l %3,%0\n" \ - " sub.l %1,%1\n" \ - " sub.l %R1,%R1\n" \ - " jra 3b\n" \ - " .previous\n" \ - "\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 4\n" \ - " .long 1b,10b\n" \ - " .long 2b,10b\n" \ - " .previous" \ - : "+d" (__gu_err), "=&r" (__gu_val.l), \ - "+a" (__gu_ptr) \ - : "i" (-EFAULT) \ - : "memory"); \ - (x) = __gu_val.t; \ - break; \ - } \ - default: \ - __gu_err = __get_user_bad(); \ - break; \ - } \ - __gu_err; \ -}) -#define get_user(x, ptr) __get_user(x, ptr) - -unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n); -unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned long n); - -#define __suffix0 -#define __suffix1 b -#define __suffix2 w -#define __suffix4 l - -#define ____constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3)\ - asm volatile ("\n" \ - "1: "MOVES"."#s1" (%2)+,%3\n" \ - " move."#s1" %3,(%1)+\n" \ - " .ifnc \""#s2"\",\"\"\n" \ - "2: "MOVES"."#s2" (%2)+,%3\n" \ - " move."#s2" %3,(%1)+\n" \ - " .ifnc \""#s3"\",\"\"\n" \ - "3: "MOVES"."#s3" (%2)+,%3\n" \ - " move."#s3" %3,(%1)+\n" \ - " .endif\n" \ - " .endif\n" \ - "4:\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 4\n" \ - " .long 1b,10f\n" \ - " .ifnc \""#s2"\",\"\"\n" \ - " .long 2b,20f\n" \ - " .ifnc \""#s3"\",\"\"\n" \ - " .long 3b,30f\n" \ - " .endif\n" \ - " .endif\n" \ - " .previous\n" \ - "\n" \ - " .section .fixup,\"ax\"\n" \ - " .even\n" \ - "10: addq.l #"#n1",%0\n" \ - " .ifnc \""#s2"\",\"\"\n" \ - "20: addq.l #"#n2",%0\n" \ - " .ifnc \""#s3"\",\"\"\n" \ - "30: addq.l #"#n3",%0\n" \ - " .endif\n" \ - " .endif\n" \ - " jra 4b\n" \ - " .previous\n" \ - : "+d" (res), "+&a" (to), "+a" (from), "=&d" (tmp) \ - : : "memory") - -#define ___constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3)\ - ____constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3) -#define __constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3) \ - ___constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, \ - __suffix##n1, __suffix##n2, __suffix##n3) - -static __always_inline unsigned long -__constant_copy_from_user(void *to, const void __user *from, unsigned long n) -{ - unsigned long res = 0, tmp; - - switch (n) { - case 1: - __constant_copy_from_user_asm(res, to, from, tmp, 1, 0, 0); - break; - case 2: - __constant_copy_from_user_asm(res, to, from, tmp, 2, 0, 0); - break; - case 3: - __constant_copy_from_user_asm(res, to, from, tmp, 2, 1, 0); - break; - case 4: - __constant_copy_from_user_asm(res, to, from, tmp, 4, 0, 0); - break; - case 5: - __constant_copy_from_user_asm(res, to, from, tmp, 4, 1, 0); - break; - case 6: - __constant_copy_from_user_asm(res, to, from, tmp, 4, 2, 0); - break; - case 7: - __constant_copy_from_user_asm(res, to, from, tmp, 4, 2, 1); - break; - case 8: - __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 0); - break; - case 9: - __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 1); - break; - case 10: - __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 2); - break; - case 12: - __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 4); - break; - default: - /* we limit the inlined version to 3 moves */ - return __generic_copy_from_user(to, from, n); - } - - return res; -} - -#define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3) \ - asm volatile ("\n" \ - " move."#s1" (%2)+,%3\n" \ - "11: "MOVES"."#s1" %3,(%1)+\n" \ - "12: move."#s2" (%2)+,%3\n" \ - "21: "MOVES"."#s2" %3,(%1)+\n" \ - "22:\n" \ - " .ifnc \""#s3"\",\"\"\n" \ - " move."#s3" (%2)+,%3\n" \ - "31: "MOVES"."#s3" %3,(%1)+\n" \ - "32:\n" \ - " .endif\n" \ - "4:\n" \ - "\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 4\n" \ - " .long 11b,5f\n" \ - " .long 12b,5f\n" \ - " .long 21b,5f\n" \ - " .long 22b,5f\n" \ - " .ifnc \""#s3"\",\"\"\n" \ - " .long 31b,5f\n" \ - " .long 32b,5f\n" \ - " .endif\n" \ - " .previous\n" \ - "\n" \ - " .section .fixup,\"ax\"\n" \ - " .even\n" \ - "5: moveq.l #"#n",%0\n" \ - " jra 4b\n" \ - " .previous\n" \ - : "+d" (res), "+a" (to), "+a" (from), "=&d" (tmp) \ - : : "memory") - -static __always_inline unsigned long -__constant_copy_to_user(void __user *to, const void *from, unsigned long n) -{ - unsigned long res = 0, tmp; - - switch (n) { - case 1: - __put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1); - break; - case 2: - __put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, r, 2); - break; - case 3: - __constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,); - break; - case 4: - __put_user_asm(res, *(u32 *)from, (u32 __user *)to, l, r, 4); - break; - case 5: - __constant_copy_to_user_asm(res, to, from, tmp, 5, l, b,); - break; - case 6: - __constant_copy_to_user_asm(res, to, from, tmp, 6, l, w,); - break; - case 7: - __constant_copy_to_user_asm(res, to, from, tmp, 7, l, w, b); - break; - case 8: - __constant_copy_to_user_asm(res, to, from, tmp, 8, l, l,); - break; - case 9: - __constant_copy_to_user_asm(res, to, from, tmp, 9, l, l, b); - break; - case 10: - __constant_copy_to_user_asm(res, to, from, tmp, 10, l, l, w); - break; - case 12: - __constant_copy_to_user_asm(res, to, from, tmp, 12, l, l, l); - break; - default: - /* limit the inlined version to 3 moves */ - return __generic_copy_to_user(to, from, n); - } - - return res; -} - -static inline unsigned long -raw_copy_from_user(void *to, const void __user *from, unsigned long n) -{ - if (__builtin_constant_p(n)) - return __constant_copy_from_user(to, from, n); - return __generic_copy_from_user(to, from, n); -} - -static inline unsigned long -raw_copy_to_user(void __user *to, const void *from, unsigned long n) -{ - if (__builtin_constant_p(n)) - return __constant_copy_to_user(to, from, n); - return __generic_copy_to_user(to, from, n); -} -#define INLINE_COPY_FROM_USER -#define INLINE_COPY_TO_USER - -#define user_addr_max() \ - (uaccess_kernel() ? ~0UL : TASK_SIZE) - -extern long strncpy_from_user(char *dst, const char __user *src, long count); -extern __must_check long strnlen_user(const char __user *str, long n); - -unsigned long __clear_user(void __user *to, unsigned long n); - -#define clear_user __clear_user - -#endif /* _M68K_UACCESS_H */ diff --git a/arch/m68k/include/asm/uaccess_no.h b/arch/m68k/include/asm/uaccess_no.h deleted file mode 100644 index dcfb69361408..000000000000 --- a/arch/m68k/include/asm/uaccess_no.h +++ /dev/null @@ -1,160 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __M68KNOMMU_UACCESS_H -#define __M68KNOMMU_UACCESS_H - -/* - * User space memory access functions - */ -#include <linux/string.h> - -#include <asm/segment.h> - -#define access_ok(addr,size) _access_ok((unsigned long)(addr),(size)) - -/* - * It is not enough to just have access_ok check for a real RAM address. - * This would disallow the case of code/ro-data running XIP in flash/rom. - * Ideally we would check the possible flash ranges too, but that is - * currently not so easy. - */ -static inline int _access_ok(unsigned long addr, unsigned long size) -{ - return 1; -} - -/* - * These are the main single-value transfer routines. They automatically - * use the right size if we just have the right pointer type. - */ - -#define put_user(x, ptr) \ -({ \ - int __pu_err = 0; \ - typeof(*(ptr)) __pu_val = (x); \ - switch (sizeof (*(ptr))) { \ - case 1: \ - __put_user_asm(__pu_err, __pu_val, ptr, b); \ - break; \ - case 2: \ - __put_user_asm(__pu_err, __pu_val, ptr, w); \ - break; \ - case 4: \ - __put_user_asm(__pu_err, __pu_val, ptr, l); \ - break; \ - case 8: \ - memcpy((void __force *)ptr, &__pu_val, sizeof(*(ptr))); \ - break; \ - default: \ - __pu_err = __put_user_bad(); \ - break; \ - } \ - __pu_err; \ -}) -#define __put_user(x, ptr) put_user(x, ptr) - -extern int __put_user_bad(void); - -/* - * Tell gcc we read from memory instead of writing: this is because - * we do not write to any memory gcc knows about, so there are no - * aliasing issues. - */ - -#define __ptr(x) ((unsigned long __user *)(x)) - -#define __put_user_asm(err,x,ptr,bwl) \ - __asm__ ("move" #bwl " %0,%1" \ - : /* no outputs */ \ - :"d" (x),"m" (*__ptr(ptr)) : "memory") - -#define get_user(x, ptr) \ -({ \ - int __gu_err = 0; \ - switch (sizeof(*(ptr))) { \ - case 1: \ - __get_user_asm(__gu_err, x, ptr, b, "=d"); \ - break; \ - case 2: \ - __get_user_asm(__gu_err, x, ptr, w, "=r"); \ - break; \ - case 4: \ - __get_user_asm(__gu_err, x, ptr, l, "=r"); \ - break; \ - case 8: { \ - union { \ - u64 l; \ - __typeof__(*(ptr)) t; \ - } __gu_val; \ - memcpy(&__gu_val.l, (const void __force *)ptr, sizeof(__gu_val.l)); \ - (x) = __gu_val.t; \ - break; \ - } \ - default: \ - __gu_err = __get_user_bad(); \ - break; \ - } \ - __gu_err; \ -}) -#define __get_user(x, ptr) get_user(x, ptr) - -extern int __get_user_bad(void); - -#define __get_user_asm(err,x,ptr,bwl,reg) \ - __asm__ ("move" #bwl " %1,%0" \ - : "=d" (x) \ - : "m" (*__ptr(ptr))) - -static inline unsigned long -raw_copy_from_user(void *to, const void __user *from, unsigned long n) -{ - memcpy(to, (__force const void *)from, n); - return 0; -} - -static inline unsigned long -raw_copy_to_user(void __user *to, const void *from, unsigned long n) -{ - memcpy((__force void *)to, from, n); - return 0; -} -#define INLINE_COPY_FROM_USER -#define INLINE_COPY_TO_USER - -/* - * Copy a null terminated string from userspace. - */ - -static inline long -strncpy_from_user(char *dst, const char *src, long count) -{ - char *tmp; - strncpy(dst, src, count); - for (tmp = dst; *tmp && count > 0; tmp++, count--) - ; - return(tmp - dst); /* DAVIDM should we count a NUL ? check getname */ -} - -/* - * Return the size of a string (including the ending 0) - * - * Return 0 on exception, a value greater than N if too long - */ -static inline long strnlen_user(const char *src, long n) -{ - return(strlen(src) + 1); /* DAVIDM make safer */ -} - -/* - * Zero Userspace - */ - -static inline unsigned long -__clear_user(void *to, unsigned long n) -{ - memset(to, 0, n); - return 0; -} - -#define clear_user(to,n) __clear_user(to,n) - -#endif /* _M68KNOMMU_UACCESS_H */ diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c index b1ca3522eccc..1c1b875fadc1 100644 --- a/arch/m68k/kernel/dma.c +++ b/arch/m68k/kernel/dma.c @@ -6,7 +6,7 @@ #undef DEBUG -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <linux/device.h> #include <linux/kernel.h> #include <linux/platform_device.h> diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index 29de2b3108ea..493c95db0e51 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -57,7 +57,7 @@ * Of course, readability is a subjective issue, so it will never be * argued that that goal was accomplished. It was merely a goal. * A key way to help make code more readable is to give good - * documentation. So, the first thing you will find is exaustive + * documentation. So, the first thing you will find is exhaustive * write-ups on the structure of the file, and the features of the * functional subroutines. * @@ -1304,7 +1304,7 @@ L(mmu_fixup_done): * mmu_engage * * This chunk of code performs the gruesome task of engaging the MMU. - * The reason its gruesome is because when the MMU becomes engaged it + * The reason it's gruesome is because when the MMU becomes engaged it * maps logical addresses to physical addresses. The Program Counter * register is then passed through the MMU before the next instruction * is fetched (the instruction following the engage MMU instruction). @@ -1369,7 +1369,7 @@ L(mmu_fixup_done): /* * After this point no new memory is allocated and * the start of available memory is stored in availmem. - * (The bootmem allocator requires now the physicall address.) + * (The bootmem allocator requires now the physical address.) */ movel L(memory_start),availmem @@ -1547,7 +1547,7 @@ func_return get_bi_record * seven bits of the logical address (LA) are used as an * index into the "root table." Each entry in the root * table has a bit which specifies if it's a valid pointer to a - * pointer table. Each entry defines a 32KMeg range of memory. + * pointer table. Each entry defines a 32Meg range of memory. * If an entry is invalid then that logical range of 32M is * invalid and references to that range of memory (when the MMU * is enabled) will fault. If the entry is valid, then it does @@ -1584,7 +1584,7 @@ func_return get_bi_record * bits 17..12 - index into the Page Table * bits 11..0 - offset into a particular 4K page * - * The algorithms which follows do one thing: they abstract + * The algorithms which follow do one thing: they abstract * the MMU hardware. For example, there are three kinds of * cache settings that are relevant. Either, memory is * being mapped in which case it is either Kernel Code (or @@ -2082,7 +2082,7 @@ func_return mmu_map_tt * mmu_map * * This routine will map a range of memory using a pointer - * table and allocating the pages on the fly from the kernel. + * table and allocate the pages on the fly from the kernel. * The pointer table does not have to be already linked into * the root table, this routine will do that if necessary. * @@ -2528,7 +2528,7 @@ func_start mmu_get_root_table_entry,%d0/%a1 /* Find the start of free memory, get_bi_record does this for us, * as the bootinfo structure is located directly behind the kernel - * and and we simply search for the last entry. + * we simply search for the last entry. */ get_bi_record BI_LAST addw #PAGESIZE-1,%a0 @@ -2654,7 +2654,7 @@ func_start mmu_get_page_table_entry,%d0/%a1 jne 2f /* If the page table entry doesn't exist, we allocate a complete new - * page and use it as one continues big page table which can cover + * page and use it as one continuous big page table which can cover * 4MB of memory, nearly almost all mappings have that alignment. */ get_new_page diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index 6492a2c54dbc..08359a6e058f 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c @@ -107,10 +107,10 @@ void flush_thread(void) * on top of pt_regs, which means that sys_clone() arguments would be * buried. We could, of course, copy them, but it's too costly for no * good reason - generic clone() would have to copy them *again* for - * _do_fork() anyway. So in this case it's actually better to pass pt_regs * - * and extract arguments for _do_fork() from there. Eventually we might - * go for calling _do_fork() directly from the wrapper, but only after we - * are finished with _do_fork() prototype conversion. + * kernel_clone() anyway. So in this case it's actually better to pass pt_regs * + * and extract arguments for kernel_clone() from there. Eventually we might + * go for calling kernel_clone() directly from the wrapper, but only after we + * are finished with kernel_clone() prototype conversion. */ asmlinkage int m68k_clone(struct pt_regs *regs) { @@ -125,7 +125,7 @@ asmlinkage int m68k_clone(struct pt_regs *regs) .tls = regs->d5, }; - return _do_fork(&args); + return kernel_clone(&args); } /* diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index a98fca977073..46f91e0f6a08 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -920,7 +920,8 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set, err |= __put_user(0x70004e40 + (__NR_sigreturn << 16), (long __user *)(frame->retcode)); #else - err |= __put_user((void *) ret_from_user_signal, &frame->pretcode); + err |= __put_user((long) ret_from_user_signal, + (long __user *) &frame->pretcode); #endif if (err) @@ -1004,7 +1005,8 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); #endif #else - err |= __put_user((void *) ret_from_user_rt_signal, &frame->pretcode); + err |= __put_user((long) ret_from_user_rt_signal, + (long __user *) &frame->pretcode); #endif /* CONFIG_MMU */ if (err) @@ -1134,6 +1136,6 @@ void do_notify_resume(struct pt_regs *regs) if (test_thread_flag(TIF_SIGPENDING)) do_signal(regs); - if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) + if (test_thread_flag(TIF_NOTIFY_RESUME)) tracehook_notify_resume(regs); } diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl index 81fc799d8392..625fb6d32842 100644 --- a/arch/m68k/kernel/syscalls/syscall.tbl +++ b/arch/m68k/kernel/syscalls/syscall.tbl @@ -439,3 +439,4 @@ 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 +440 common process_madvise sys_process_madvise diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index 546e81935fe8..9e1261462bcc 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -845,7 +845,6 @@ static void show_trace(unsigned long *stack, const char *loglvl) void show_registers(struct pt_regs *regs) { struct frame *fp = (struct frame *)regs; - mm_segment_t old_fs = get_fs(); u16 c, *cp; unsigned long addr; int i; @@ -918,10 +917,9 @@ void show_registers(struct pt_regs *regs) show_stack(NULL, (unsigned long *)addr, KERN_INFO); pr_info("Code:"); - set_fs(KERNEL_DS); cp = (u16 *)regs->pc; for (i = -8; i < 16; i++) { - if (get_user(c, cp + i) && i >= 0) { + if (get_kernel_nofault(c, cp + i) && i >= 0) { pr_cont(" Bad PC value."); break; } @@ -930,7 +928,6 @@ void show_registers(struct pt_regs *regs) else pr_cont(" <%04x>", c); } - set_fs(old_fs); pr_cont("\n"); } diff --git a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c index 31797be9a3dc..7e6afeae6217 100644 --- a/arch/m68k/lib/checksum.c +++ b/arch/m68k/lib/checksum.c @@ -129,8 +129,7 @@ EXPORT_SYMBOL(csum_partial); */ __wsum -csum_and_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *csum_err) +csum_and_copy_from_user(const void __user *src, void *dst, int len) { /* * GCC doesn't like more than 10 operands for the asm @@ -138,6 +137,7 @@ csum_and_copy_from_user(const void __user *src, void *dst, * code. */ unsigned long tmp1, tmp2; + __wsum sum = ~0U; __asm__("movel %2,%4\n\t" "btst #1,%4\n\t" /* Check alignment */ @@ -236,84 +236,33 @@ csum_and_copy_from_user(const void __user *src, void *dst, "clrl %5\n\t" "addxl %5,%0\n\t" /* add X bit */ "7:\t" - "clrl %5\n" /* no error - clear return value */ - "8:\n" ".section .fixup,\"ax\"\n" ".even\n" - /* If any exception occurs zero out the rest. - Similarities with the code above are intentional :-) */ + /* If any exception occurs, return 0 */ "90:\t" - "clrw %3@+\n\t" - "movel %1,%4\n\t" - "lsrl #5,%1\n\t" - "jeq 1f\n\t" - "subql #1,%1\n" - "91:\t" - "clrl %3@+\n" - "92:\t" - "clrl %3@+\n" - "93:\t" - "clrl %3@+\n" - "94:\t" - "clrl %3@+\n" - "95:\t" - "clrl %3@+\n" - "96:\t" - "clrl %3@+\n" - "97:\t" - "clrl %3@+\n" - "98:\t" - "clrl %3@+\n\t" - "dbra %1,91b\n\t" - "clrw %1\n\t" - "subql #1,%1\n\t" - "jcc 91b\n" - "1:\t" - "movel %4,%1\n\t" - "andw #0x1c,%4\n\t" - "jeq 1f\n\t" - "lsrw #2,%4\n\t" - "subqw #1,%4\n" - "99:\t" - "clrl %3@+\n\t" - "dbra %4,99b\n\t" - "1:\t" - "andw #3,%1\n\t" - "jeq 9f\n" - "100:\t" - "clrw %3@+\n\t" - "tstw %1\n\t" - "jeq 9f\n" - "101:\t" - "clrb %3@+\n" - "9:\t" -#define STR(X) STR1(X) -#define STR1(X) #X - "moveq #-" STR(EFAULT) ",%5\n\t" - "jra 8b\n" + "clrl %0\n" + "jra 7b\n" ".previous\n" ".section __ex_table,\"a\"\n" ".long 10b,90b\n" - ".long 11b,91b\n" - ".long 12b,92b\n" - ".long 13b,93b\n" - ".long 14b,94b\n" - ".long 15b,95b\n" - ".long 16b,96b\n" - ".long 17b,97b\n" - ".long 18b,98b\n" - ".long 19b,99b\n" - ".long 20b,100b\n" - ".long 21b,101b\n" + ".long 11b,90b\n" + ".long 12b,90b\n" + ".long 13b,90b\n" + ".long 14b,90b\n" + ".long 15b,90b\n" + ".long 16b,90b\n" + ".long 17b,90b\n" + ".long 18b,90b\n" + ".long 19b,90b\n" + ".long 20b,90b\n" + ".long 21b,90b\n" ".previous" : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), "=&d" (tmp1), "=d" (tmp2) : "0" (sum), "1" (len), "2" (src), "3" (dst) ); - *csum_err = tmp2; - - return(sum); + return sum; } EXPORT_SYMBOL(csum_and_copy_from_user); @@ -324,9 +273,10 @@ EXPORT_SYMBOL(csum_and_copy_from_user); */ __wsum -csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) +csum_partial_copy_nocheck(const void *src, void *dst, int len) { unsigned long tmp1, tmp2; + __wsum sum = 0; __asm__("movel %2,%4\n\t" "btst #1,%4\n\t" /* Check alignment */ "jeq 2f\n\t" diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index a621fcc1a576..0ac53d87493c 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c @@ -24,6 +24,7 @@ #include <linux/init.h> #include <linux/vt_kern.h> #include <linux/platform_device.h> +#include <linux/ata_platform.h> #include <linux/adb.h> #include <linux/cuda.h> #include <linux/pmu.h> @@ -940,6 +941,26 @@ static const struct resource mac_scsi_ccl_rsrc[] __initconst = { }, }; +static const struct resource mac_ide_quadra_rsrc[] __initconst = { + DEFINE_RES_MEM(0x50F1A000, 0x104), + DEFINE_RES_IRQ(IRQ_NUBUS_F), +}; + +static const struct resource mac_ide_pb_rsrc[] __initconst = { + DEFINE_RES_MEM(0x50F1A000, 0x104), + DEFINE_RES_IRQ(IRQ_NUBUS_C), +}; + +static const struct resource mac_pata_baboon_rsrc[] __initconst = { + DEFINE_RES_MEM(0x50F1A000, 0x38), + DEFINE_RES_MEM(0x50F1A038, 0x04), + DEFINE_RES_IRQ(IRQ_BABOON_1), +}; + +static const struct pata_platform_info mac_pata_baboon_data __initconst = { + .ioport_shift = 2, +}; + int __init mac_platform_init(void) { phys_addr_t swim_base = 0; @@ -1049,6 +1070,26 @@ int __init mac_platform_init(void) } /* + * IDE device + */ + + switch (macintosh_config->ide_type) { + case MAC_IDE_QUADRA: + platform_device_register_simple("mac_ide", -1, + mac_ide_quadra_rsrc, ARRAY_SIZE(mac_ide_quadra_rsrc)); + break; + case MAC_IDE_PB: + platform_device_register_simple("mac_ide", -1, + mac_ide_pb_rsrc, ARRAY_SIZE(mac_ide_pb_rsrc)); + break; + case MAC_IDE_BABOON: + platform_device_register_resndata(NULL, "pata_platform", -1, + mac_pata_baboon_rsrc, ARRAY_SIZE(mac_pata_baboon_rsrc), + &mac_pata_baboon_data, sizeof(mac_pata_baboon_data)); + break; + } + + /* * Ethernet device */ diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c index 388780797f7d..4de6229c7bfd 100644 --- a/arch/m68k/mac/macboing.c +++ b/arch/m68k/mac/macboing.c @@ -116,7 +116,7 @@ static void mac_init_asc( void ) * support 16-bit stereo output, but only mono input." * * Technical Information Library (TIL) article number 16405. - * http://support.apple.com/kb/TA32601 + * https://support.apple.com/kb/TA32601 * * --David Kilzer */ diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c index 2b9cb4a62281..eac9dde65193 100644 --- a/arch/m68k/mm/mcfmmu.c +++ b/arch/m68k/mm/mcfmmu.c @@ -42,7 +42,7 @@ void __init paging_init(void) unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; int i; - empty_zero_page = (void *) memblock_alloc(PAGE_SIZE, PAGE_SIZE); + empty_zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE); if (!empty_zero_page) panic("%s: Failed to allocate %lu bytes align=0x%lx\n", __func__, PAGE_SIZE, PAGE_SIZE); diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c index 2bb006bdc31c..3a653f0a4188 100644 --- a/arch/m68k/mm/motorola.c +++ b/arch/m68k/mm/motorola.c @@ -226,8 +226,8 @@ static pte_t * __init kernel_page_table(void) { pte_t *pte_table = last_pte_table; - if (((unsigned long)last_pte_table & ~PAGE_MASK) == 0) { - pte_table = (pte_t *)memblock_alloc_low(PAGE_SIZE, PAGE_SIZE); + if (PAGE_ALIGNED(last_pte_table)) { + pte_table = memblock_alloc_low(PAGE_SIZE, PAGE_SIZE); if (!pte_table) { panic("%s: Failed to allocate %lu bytes align=%lx\n", __func__, PAGE_SIZE, PAGE_SIZE); @@ -274,9 +274,8 @@ static pmd_t * __init kernel_ptr_table(void) } last_pmd_table += PTRS_PER_PMD; - if (((unsigned long)last_pmd_table & ~PAGE_MASK) == 0) { - last_pmd_table = (pmd_t *)memblock_alloc_low(PAGE_SIZE, - PAGE_SIZE); + if (PAGE_ALIGNED(last_pmd_table)) { + last_pmd_table = memblock_alloc_low(PAGE_SIZE, PAGE_SIZE); if (!last_pmd_table) panic("%s: Failed to allocate %lu bytes align=%lx\n", __func__, PAGE_SIZE, PAGE_SIZE); diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index d262ac0c8714..33925ffed68f 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -26,6 +26,7 @@ config MICROBLAZE select GENERIC_SCHED_CLOCK select HAVE_ARCH_HASH select HAVE_ARCH_KGDB + select HAVE_ARCH_SECCOMP select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_CONTIGUOUS select HAVE_DYNAMIC_FTRACE @@ -46,6 +47,7 @@ config MICROBLAZE select CPU_NO_EFFICIENT_FFS select MMU_GATHER_NO_RANGE if MMU select SPARSE_IRQ + select SET_FS # Endianness selection choice @@ -120,23 +122,6 @@ config CMDLINE_FORCE Set this to have arguments from the default kernel command string override those passed by the boot loader. -config SECCOMP - bool "Enable seccomp to safely compute untrusted bytecode" - depends on PROC_FS - default y - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via /proc/<pid>/seccomp, it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - - If unsure, say Y. Only embedded should say N here. - endmenu menu "Kernel features" diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild index 2e87a9b6d312..63bce836b9f1 100644 --- a/arch/microblaze/include/asm/Kbuild +++ b/arch/microblaze/include/asm/Kbuild @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 generated-y += syscall_table.h generic-y += extable.h -generic-y += hw_irq.h generic-y += kvm_para.h generic-y += local64.h generic-y += mcs_spinlock.h diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index d7bebd04247b..04d091ade417 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c @@ -8,9 +8,8 @@ */ #include <linux/device.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <linux/gfp.h> -#include <linux/dma-debug.h> #include <linux/export.h> #include <linux/bug.h> #include <asm/cacheflush.h> diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 2310daff1f8a..333b09658ca8 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -46,7 +46,7 @@ DEFINE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */ * ASM code. Default position is BSS section which is cleared * in machine_early_init(). */ -char cmd_line[COMMAND_LINE_SIZE] __attribute__ ((section(".data"))); +char cmd_line[COMMAND_LINE_SIZE] __section(".data"); void __init setup_arch(char **cmdline_p) { diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c index 4a96b59f0bee..f11a0ccccabc 100644 --- a/arch/microblaze/kernel/signal.c +++ b/arch/microblaze/kernel/signal.c @@ -316,6 +316,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, int in_syscall) if (test_thread_flag(TIF_SIGPENDING)) do_signal(regs, in_syscall); - if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) + if (test_thread_flag(TIF_NOTIFY_RESUME)) tracehook_notify_resume(regs); } diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl index b4e263916f41..aae729c95cf9 100644 --- a/arch/microblaze/kernel/syscalls/syscall.tbl +++ b/arch/microblaze/kernel/syscalls/syscall.tbl @@ -445,3 +445,4 @@ 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 +440 common process_madvise sys_process_madvise diff --git a/arch/microblaze/mm/consistent.c b/arch/microblaze/mm/consistent.c index e09b66e43cb6..81dffe43b18c 100644 --- a/arch/microblaze/mm/consistent.c +++ b/arch/microblaze/mm/consistent.c @@ -11,7 +11,7 @@ #include <linux/types.h> #include <linux/mm.h> #include <linux/init.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <asm/cpuinfo.h> #include <asm/cacheflush.h> diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c index 3344d4a1fe89..45da639bd22c 100644 --- a/arch/microblaze/mm/init.c +++ b/arch/microblaze/mm/init.c @@ -7,7 +7,7 @@ * for more details. */ -#include <linux/dma-contiguous.h> +#include <linux/dma-map-ops.h> #include <linux/memblock.h> #include <linux/init.h> #include <linux/kernel.h> @@ -108,15 +108,15 @@ static void __init paging_init(void) void __init setup_memory(void) { - struct memblock_region *reg; - #ifndef CONFIG_MMU u32 kernel_align_start, kernel_align_size; + phys_addr_t start, end; + u64 i; /* Find main memory where is the kernel */ - for_each_memblock(memory, reg) { - memory_start = (u32)reg->base; - lowmem_size = reg->size; + for_each_mem_range(i, &start, &end) { + memory_start = start; + lowmem_size = end - start; if ((memory_start <= (u32)_text) && ((u32)_text <= (memory_start + lowmem_size - 1))) { memory_size = lowmem_size; @@ -164,17 +164,6 @@ void __init setup_memory(void) pr_info("%s: max_low_pfn: %#lx\n", __func__, max_low_pfn); pr_info("%s: max_pfn: %#lx\n", __func__, max_pfn); - /* Add active regions with valid PFNs */ - for_each_memblock(memory, reg) { - unsigned long start_pfn, end_pfn; - - start_pfn = memblock_region_memory_base_pfn(reg); - end_pfn = memblock_region_memory_end_pfn(reg); - memblock_set_node(start_pfn << PAGE_SHIFT, - (end_pfn - start_pfn) << PAGE_SHIFT, - &memblock.memory, 0); - } - paging_init(); } diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index a13c4cf6e608..5483e38b5dc7 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -13,7 +13,6 @@ platform-$(CONFIG_MIPS_COBALT) += cobalt/ platform-$(CONFIG_MACH_DECSTATION) += dec/ platform-$(CONFIG_MIPS_GENERIC) += generic/ platform-$(CONFIG_MACH_JAZZ) += jazz/ -platform-$(CONFIG_MACH_INGENIC) += jz4740/ platform-$(CONFIG_LANTIQ) += lantiq/ platform-$(CONFIG_MACH_LOONGSON2EF) += loongson2ef/ platform-$(CONFIG_MACH_LOONGSON32) += loongson32/ @@ -22,7 +21,6 @@ platform-$(CONFIG_MIPS_MALTA) += mti-malta/ platform-$(CONFIG_NLM_COMMON) += netlogic/ platform-$(CONFIG_PIC32MZDA) += pic32/ platform-$(CONFIG_MACH_PISTACHIO) += pistachio/ -platform-$(CONFIG_SOC_PNX833X) += pnx833x/ platform-$(CONFIG_RALINK) += ralink/ platform-$(CONFIG_MIKROTIK_RB532) += rb532/ platform-$(CONFIG_SGI_IP22) += sgi-ip22/ diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c95fa3a2484c..2000bb2b0220 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -86,21 +86,43 @@ config MIPS select MODULES_USE_ELF_REL if MODULES select MODULES_USE_ELF_RELA if MODULES && 64BIT select PERF_USE_VMALLOC + select PCI_MSI_ARCH_FALLBACKS if PCI_MSI select RTC_LIB + select SET_FS select SYSCTL_EXCEPTION_TRACE select VIRT_TO_BUS config MIPS_FIXUP_BIGPHYS_ADDR bool +config MIPS_GENERIC + bool + +config MACH_INGENIC + bool + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_ZBOOT + select DMA_NONCOHERENT + select IRQ_MIPS_CPU + select PINCTRL + select GPIOLIB + select COMMON_CLK + select GENERIC_IRQ_CHIP + select BUILTIN_DTB if MIPS_NO_APPENDED_DTB + select USE_OF + select CPU_SUPPORTS_CPUFREQ + select MIPS_EXTERNAL_TIMER + menu "Machine selection" choice prompt "System type" - default MIPS_GENERIC + default MIPS_GENERIC_KERNEL -config MIPS_GENERIC +config MIPS_GENERIC_KERNEL bool "Generic board-agnostic MIPS kernel" + select MIPS_GENERIC select BOOT_RAW select BUILTIN_DTB select CEVT_R4K @@ -137,6 +159,7 @@ config MIPS_GENERIC select SYS_SUPPORTS_MULTITHREADING select SYS_SUPPORTS_RELOCATABLE select SYS_SUPPORTS_SMARTMIPS + select SYS_SUPPORTS_ZBOOT select UHI_BOOT select USB_EHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN @@ -389,20 +412,11 @@ config MACH_JAZZ Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and Olivetti M700-10 workstations. -config MACH_INGENIC +config MACH_INGENIC_SOC bool "Ingenic SoC based machines" - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN + select MIPS_GENERIC + select MACH_INGENIC select SYS_SUPPORTS_ZBOOT_UART16550 - select CPU_SUPPORTS_HUGEPAGES - select DMA_NONCOHERENT - select IRQ_MIPS_CPU - select PINCTRL - select GPIOLIB - select COMMON_CLK - select GENERIC_IRQ_CHIP - select BUILTIN_DTB if MIPS_NO_APPENDED_DTB - select USE_OF config LANTIQ bool "Lantiq based platforms" @@ -475,6 +489,7 @@ config MACH_LOONGSON64 select SYS_SUPPORTS_ZBOOT select ZONE_DMA32 select NUMA + select SMP select COMMON_CLK select USE_OF select BUILTIN_DTB @@ -568,6 +583,7 @@ config MIPS_MALTA select SYS_SUPPORTS_VPE_LOADER select SYS_SUPPORTS_ZBOOT select USE_OF + select WAR_ICACHE_REFILLS select ZONE_DMA32 if 64BIT help This enables support for the MIPS Technologies Malta evaluation @@ -589,19 +605,6 @@ config MACH_VR41XX select SYS_SUPPORTS_MIPS16 select GPIOLIB -config NXP_STB220 - bool "NXP STB220 board" - select SOC_PNX833X - help - Support for NXP Semiconductors STB220 Development Board. - -config NXP_STB225 - bool "NXP 225 board" - select SOC_PNX833X - select SOC_PNX8335 - help - Support for NXP Semiconductors STB225 Development Board. - config RALINK bool "Ralink based machines" select CEVT_R4K @@ -615,6 +618,7 @@ config RALINK select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_MIPS16 + select SYS_SUPPORTS_ZBOOT select SYS_HAS_EARLY_PRINTK select CLKDEV_LOOKUP select ARCH_HAS_RESET_CONTROLLER @@ -651,6 +655,9 @@ config SGI_IP22 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select WAR_R4600_V1_INDEX_ICACHEOP + select WAR_R4600_V1_HIT_CACHEOP + select WAR_R4600_V2_HIT_CACHEOP select MIPS_L1_CACHE_SHIFT_7 help This are the SGI Indy, Challenge S and Indigo2, as well as certain @@ -678,6 +685,7 @@ config SGI_IP27 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_NUMA select SYS_SUPPORTS_SMP + select WAR_R10000_LLSC select MIPS_L1_CACHE_SHIFT_7 select NUMA help @@ -713,6 +721,7 @@ config SGI_IP28 select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select WAR_R10000_LLSC select MIPS_L1_CACHE_SHIFT_7 help This is the SGI Indigo2 with R10000 processor. To compile a Linux @@ -739,6 +748,7 @@ config SGI_IP30 select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_SMP + select WAR_R10000_LLSC select MIPS_L1_CACHE_SHIFT_7 select ARC_MEMORY help @@ -766,6 +776,7 @@ config SGI_IP32 select SYS_HAS_CPU_NEVADA select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select WAR_ICACHE_REFILLS help If you want this kernel to run on SGI O2 workstation, say Y here. @@ -877,6 +888,7 @@ config SNI_RM select I8253 select I8259 select ISA + select MIPS_L1_CACHE_SHIFT_6 select SWAP_IO_SPACE if CPU_BIG_ENDIAN select SYS_HAS_CPU_R4X00 select SYS_HAS_CPU_R5000 @@ -888,6 +900,7 @@ config SNI_RM select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_HIGHMEM select SYS_SUPPORTS_LITTLE_ENDIAN + select WAR_R4600_V2_HIT_CACHEOP help The SNI RM200/300/400 are MIPS-based machines manufactured by Siemens Nixdorf Informationssysteme (SNI), parent company of Pyramid @@ -899,6 +912,7 @@ config MACH_TX39XX config MACH_TX49XX bool "Toshiba TX49 series based machines" + select WAR_TX49XX_ICACHE_INDEX_INV config MIKROTIK_RB532 bool "Mikrotik RB532 boards" @@ -1024,8 +1038,8 @@ source "arch/mips/bcm47xx/Kconfig" source "arch/mips/bcm63xx/Kconfig" source "arch/mips/bmips/Kconfig" source "arch/mips/generic/Kconfig" +source "arch/mips/ingenic/Kconfig" source "arch/mips/jazz/Kconfig" -source "arch/mips/jz4740/Kconfig" source "arch/mips/lantiq/Kconfig" source "arch/mips/pic32/Kconfig" source "arch/mips/pistachio/Kconfig" @@ -1134,7 +1148,6 @@ config DMA_NONCOHERENT select ARCH_HAS_SYNC_DMA_FOR_DEVICE select ARCH_HAS_DMA_SET_UNCACHED select DMA_NONCOHERENT_MMAP - select DMA_NONCOHERENT_CACHE_SYNC select NEED_DMA_MAP_STATE config SYS_HAS_EARLY_PRINTK @@ -1266,23 +1279,6 @@ config PCI_XTALK_BRIDGE config NO_EXCEPT_FILL bool -config SOC_PNX833X - bool - select CEVT_R4K - select CSRC_R4K - select IRQ_MIPS_CPU - select DMA_NONCOHERENT - select SYS_HAS_CPU_MIPS32_R2 - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_MIPS16 - select CPU_MIPSR2_IRQ_VI - -config SOC_PNX8335 - bool - select SOC_PNX833X - config MIPS_SPRAM bool @@ -1619,7 +1615,6 @@ config CPU_P5600 select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_HIGHMEM select CPU_SUPPORTS_MSA - select CPU_SUPPORTS_UNCACHED_ACCELERATED select CPU_SUPPORTS_CPUFREQ select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_IRQ_EI @@ -1890,6 +1885,7 @@ config SYS_SUPPORTS_ZBOOT select HAVE_KERNEL_LZMA select HAVE_KERNEL_LZO select HAVE_KERNEL_XZ + select HAVE_KERNEL_ZSTD config SYS_SUPPORTS_ZBOOT_UART16550 bool @@ -2271,7 +2267,7 @@ config FORCE_MAX_ZONEORDER default "13" if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_32KB range 12 64 if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_16KB default "12" if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_16KB - range 11 64 + range 0 64 default "11" help The kernel memory allocator divides physically contiguous memory @@ -2637,6 +2633,76 @@ config MIPS_ASID_BITS_VARIABLE config MIPS_CRC_SUPPORT bool +# R4600 erratum. Due to the lack of errata information the exact +# technical details aren't known. I've experimentally found that disabling +# interrupts during indexed I-cache flushes seems to be sufficient to deal +# with the issue. +config WAR_R4600_V1_INDEX_ICACHEOP + bool + +# Pleasures of the R4600 V1.x. Cite from the IDT R4600 V1.7 errata: +# +# 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, +# Hit_Invalidate_D and Create_Dirty_Excl_D should only be +# executed if there is no other dcache activity. If the dcache is +# accessed for another instruction immeidately preceding when these +# cache instructions are executing, it is possible that the dcache +# tag match outputs used by these cache instructions will be +# incorrect. These cache instructions should be preceded by at least +# four instructions that are not any kind of load or store +# instruction. +# +# This is not allowed: lw +# nop +# nop +# nop +# cache Hit_Writeback_Invalidate_D +# +# This is allowed: lw +# nop +# nop +# nop +# nop +# cache Hit_Writeback_Invalidate_D +config WAR_R4600_V1_HIT_CACHEOP + bool + +# Writeback and invalidate the primary cache dcache before DMA. +# +# R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D, +# Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only +# operate correctly if the internal data cache refill buffer is empty. These +# CACHE instructions should be separated from any potential data cache miss +# by a load instruction to an uncached address to empty the response buffer." +# (Revision 2.0 device errata from IDT available on https://www.idt.com/ +# in .pdf format.) +config WAR_R4600_V2_HIT_CACHEOP + bool + +# From TX49/H2 manual: "If the instruction (i.e. CACHE) is issued for +# the line which this instruction itself exists, the following +# operation is not guaranteed." +# +# Workaround: do two phase flushing for Index_Invalidate_I +config WAR_TX49XX_ICACHE_INDEX_INV + bool + +# The RM7000 processors and the E9000 cores have a bug (though PMC-Sierra +# opposes it being called that) where invalid instructions in the same +# I-cache line worth of instructions being fetched may case spurious +# exceptions. +config WAR_ICACHE_REFILLS + bool + +# On the R10000 up to version 2.6 (not sure about 2.7) there is a bug that +# may cause ll / sc and lld / scd sequences to execute non-atomically. +config WAR_R10000_LLSC + bool + +# 34K core erratum: "Problems Executing the TLBR Instruction" +config WAR_MIPS34K_MISSED_ITLB + bool + # # - Highmem only makes sense for the 32-bit kernel. # - The current highmem code will only work properly on physically indexed @@ -3004,23 +3070,6 @@ config PHYSICAL_START specified in the "crashkernel=YM@XM" command line boot parameter passed to the panic-ed kernel). -config SECCOMP - bool "Enable seccomp to safely compute untrusted bytecode" - depends on PROC_FS - default y - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via /proc/<pid>/seccomp, it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - - If unsure, say Y. Only embedded should say N here. - config MIPS_O32_FP64_SUPPORT bool "Support for O32 binaries using 64-bit FP" if !CPU_MIPSR6 depends on 32BIT || MIPS32_O32 diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig index 83b288b95b16..69734120ada1 100644 --- a/arch/mips/alchemy/Kconfig +++ b/arch/mips/alchemy/Kconfig @@ -1,12 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -# au1000-style gpio and interrupt controllers -config ALCHEMY_GPIOINT_AU1000 - bool - -# au1300-style GPIO/INT controller -config ALCHEMY_GPIOINT_AU1300 - bool - choice prompt "Machine type" depends on MIPS_ALCHEMY @@ -15,7 +7,6 @@ choice config MIPS_MTX1 bool "4G Systems MTX-1 board" select HAVE_PCI - select ALCHEMY_GPIOINT_AU1000 select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_HAS_EARLY_PRINTK @@ -33,13 +24,11 @@ config MIPS_DB1XXX config MIPS_XXS1500 bool "MyCable XXS1500 board" - select ALCHEMY_GPIOINT_AU1000 select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_HAS_EARLY_PRINTK config MIPS_GPR bool "Trapeze ITS GPR board" - select ALCHEMY_GPIOINT_AU1000 select HAVE_PCI select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_HAS_EARLY_PRINTK diff --git a/arch/mips/alchemy/board-gpr.c b/arch/mips/alchemy/board-gpr.c index 6c47318946e4..f587c40b6d00 100644 --- a/arch/mips/alchemy/board-gpr.c +++ b/arch/mips/alchemy/board-gpr.c @@ -31,23 +31,6 @@ const char *get_system_type(void) return "GPR"; } -void __init prom_init(void) -{ - unsigned char *memsize_str; - unsigned long memsize; - - prom_argc = fw_arg0; - prom_argv = (char **)fw_arg1; - prom_envp = (char **)fw_arg2; - - prom_init_cmdline(); - - memsize_str = prom_getenv("memsize"); - if (!memsize_str || kstrtoul(memsize_str, 0, &memsize)) - memsize = 0x04000000; - add_memory_region(0, memsize, BOOT_MEM_RAM); -} - void prom_putchar(char c) { alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c index 23093535399f..68ea57511629 100644 --- a/arch/mips/alchemy/board-mtx1.c +++ b/arch/mips/alchemy/board-mtx1.c @@ -30,23 +30,6 @@ const char *get_system_type(void) return "MTX-1"; } -void __init prom_init(void) -{ - unsigned char *memsize_str; - unsigned long memsize; - - prom_argc = fw_arg0; - prom_argv = (char **)fw_arg1; - prom_envp = (char **)fw_arg2; - - prom_init_cmdline(); - - memsize_str = prom_getenv("memsize"); - if (!memsize_str || kstrtoul(memsize_str, 0, &memsize)) - memsize = 0x04000000; - add_memory_region(0, memsize, BOOT_MEM_RAM); -} - void prom_putchar(char c) { alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); diff --git a/arch/mips/alchemy/board-xxs1500.c b/arch/mips/alchemy/board-xxs1500.c index c67dfe1f4997..b184baa4e56a 100644 --- a/arch/mips/alchemy/board-xxs1500.c +++ b/arch/mips/alchemy/board-xxs1500.c @@ -25,24 +25,6 @@ const char *get_system_type(void) return "XXS1500"; } -void __init prom_init(void) -{ - unsigned char *memsize_str; - unsigned long memsize; - - prom_argc = fw_arg0; - prom_argv = (char **)fw_arg1; - prom_envp = (char **)fw_arg2; - - prom_init_cmdline(); - - memsize_str = prom_getenv("memsize"); - if (!memsize_str || kstrtoul(memsize_str, 0, &memsize)) - memsize = 0x04000000; - - add_memory_region(0, memsize, BOOT_MEM_RAM); -} - void prom_putchar(char c) { alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); diff --git a/arch/mips/alchemy/common/prom.c b/arch/mips/alchemy/common/prom.c index af312b5e33f6..d910c0a64de9 100644 --- a/arch/mips/alchemy/common/prom.c +++ b/arch/mips/alchemy/common/prom.c @@ -34,6 +34,9 @@ */ #include <linux/init.h> +#include <linux/kernel.h> +#include <linux/memblock.h> +#include <linux/sizes.h> #include <linux/string.h> #include <asm/bootinfo.h> @@ -76,6 +79,24 @@ char *prom_getenv(char *envname) return NULL; } +void __init prom_init(void) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = (int)fw_arg0; + prom_argv = (char **)fw_arg1; + prom_envp = (char **)fw_arg2; + + prom_init_cmdline(); + + memsize_str = prom_getenv("memsize"); + if (!memsize_str || kstrtoul(memsize_str, 0, &memsize)) + memsize = SZ_64M; /* minimum memsize is 64MB RAM */ + + memblock_add(0, memsize); +} + static inline unsigned char str2hexnum(unsigned char c) { if (c >= '0' && c <= '9') diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c index 8ac1f56ee57d..cd72eaa1168f 100644 --- a/arch/mips/alchemy/devboards/db1300.c +++ b/arch/mips/alchemy/devboards/db1300.c @@ -731,6 +731,7 @@ static struct platform_device db1300_lcd_dev = { /**********************************************************************/ +#if IS_ENABLED(CONFIG_TOUCHSCREEN_WM97XX) static void db1300_wm97xx_irqen(struct wm97xx *wm, int enable) { if (enable) @@ -762,6 +763,12 @@ static int db1300_wm97xx_probe(struct platform_device *pdev) return wm97xx_register_mach_ops(wm, &db1300_wm97xx_ops); } +#else +static int db1300_wm97xx_probe(struct platform_device *pdev) +{ + return -ENODEV; +} +#endif static struct platform_driver db1300_wm97xx_driver = { .driver.name = "wm97xx-touch", diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c index 8d4b65c3268a..754bdd2ca630 100644 --- a/arch/mips/alchemy/devboards/platform.c +++ b/arch/mips/alchemy/devboards/platform.c @@ -20,23 +20,6 @@ #include <prom.h> -void __init prom_init(void) -{ - unsigned char *memsize_str; - unsigned long memsize; - - prom_argc = (int)fw_arg0; - prom_argv = (char **)fw_arg1; - prom_envp = (char **)fw_arg2; - - prom_init_cmdline(); - memsize_str = prom_getenv("memsize"); - if (!memsize_str || kstrtoul(memsize_str, 0, &memsize)) - memsize = 64 << 20; /* all devboards have at least 64MB RAM */ - - add_memory_region(0, memsize, BOOT_MEM_RAM); -} - void prom_putchar(char c) { if (alchemy_get_cputype() == ALCHEMY_CPU_AU1300) diff --git a/arch/mips/ar7/memory.c b/arch/mips/ar7/memory.c index ad6efb36ebfe..787716c5e946 100644 --- a/arch/mips/ar7/memory.c +++ b/arch/mips/ar7/memory.c @@ -47,7 +47,7 @@ void __init prom_meminit(void) unsigned long pages; pages = memsize() >> PAGE_SHIFT; - add_memory_region(PHYS_OFFSET, pages << PAGE_SHIFT, BOOT_MEM_RAM); + memblock_add(PHYS_OFFSET, pages << PAGE_SHIFT); } void __init prom_free_prom_memory(void) diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c index e7b53e3960c8..9dbed7b5ea76 100644 --- a/arch/mips/ath25/ar2315.c +++ b/arch/mips/ath25/ar2315.c @@ -19,6 +19,7 @@ #include <linux/bitops.h> #include <linux/irqdomain.h> #include <linux/interrupt.h> +#include <linux/memblock.h> #include <linux/platform_device.h> #include <linux/reboot.h> #include <asm/bootinfo.h> @@ -266,7 +267,7 @@ void __init ar2315_plat_mem_setup(void) memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_COL_WIDTH); memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_ROW_WIDTH); memsize <<= 3; - add_memory_region(0, memsize, BOOT_MEM_RAM); + memblock_add(0, memsize); iounmap(sdram_base); ar2315_rst_base = ioremap(AR2315_RST_BASE, AR2315_RST_SIZE); diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c index 42bf2afb4765..23c879f4b734 100644 --- a/arch/mips/ath25/ar5312.c +++ b/arch/mips/ath25/ar5312.c @@ -19,6 +19,7 @@ #include <linux/bitops.h> #include <linux/irqdomain.h> #include <linux/interrupt.h> +#include <linux/memblock.h> #include <linux/platform_device.h> #include <linux/mtd/physmap.h> #include <linux/reboot.h> @@ -363,7 +364,7 @@ void __init ar5312_plat_mem_setup(void) memsize = (bank0_ac ? (1 << (bank0_ac + 1)) : 0) + (bank1_ac ? (1 << (bank1_ac + 1)) : 0); memsize <<= 20; - add_memory_region(0, memsize, BOOT_MEM_RAM); + memblock_add(0, memsize); iounmap(sdram_base); ar5312_rst_base = ioremap(AR5312_RST_BASE, AR5312_RST_SIZE); diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c index 135a5407f015..3e2a8166377f 100644 --- a/arch/mips/bcm47xx/prom.c +++ b/arch/mips/bcm47xx/prom.c @@ -27,6 +27,7 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/kernel.h> +#include <linux/memblock.h> #include <linux/spinlock.h> #include <linux/ssb/ssb_driver_chipcommon.h> #include <linux/ssb/ssb_regs.h> @@ -97,7 +98,7 @@ static __init void prom_init_mem(void) */ if (c->cputype == CPU_74K && (mem == (128 << 20))) mem -= 0x1000; - add_memory_region(0, mem, BOOT_MEM_RAM); + memblock_add(0, mem); } /* diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 82627c264964..94bf839576c1 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -141,14 +141,14 @@ static void __init bcm47xx_register_bcma(void) /* * Memory setup is done in the early part of MIPS's arch_mem_init. It's supposed - * to detect memory and record it with add_memory_region. + * to detect memory and record it with memblock_add. * Any extra initializaion performed here must not use kmalloc or bootmem. */ void __init plat_mem_setup(void) { struct cpuinfo_mips *c = ¤t_cpu_data; - if ((c->cputype == CPU_74K) || (c->cputype == CPU_1074K)) { + if (c->cputype == CPU_74K) { pr_info("Using bcma bus\n"); #ifdef CONFIG_BCM47XX_BCMA bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index 230bf27c1fb8..01aff80a5967 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -1,8 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only /* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> */ @@ -32,7 +29,6 @@ #include <uapi/linux/bcm933xx_hcs.h> - #define HCS_OFFSET_128K 0x20000 static struct board_info board; @@ -42,30 +38,28 @@ static struct board_info board; */ #ifdef CONFIG_BCM63XX_CPU_3368 static struct board_info __initdata board_cvg834g = { - .name = "CVG834G_E15R3921", - .expected_cpu_id = 0x3368, - - .has_uart0 = 1, - .has_uart1 = 1, + .name = "CVG834G_E15R3921", + .expected_cpu_id = 0x3368, - .has_enet0 = 1, - .has_pci = 1, + .ephy_reset_gpio = 36, + .ephy_reset_gpio_flags = GPIOF_INIT_HIGH, + .has_pci = 1, + .has_uart0 = 1, + .has_uart1 = 1, + .has_enet0 = 1, .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, + .has_phy = 1, + .use_internal_phy = 1, }, .leds = { { - .name = "CVG834G:green:power", - .gpio = 37, + .name = "CVG834G:green:power", + .gpio = 37, .default_trigger= "default-on", }, }, - - .ephy_reset_gpio = 36, - .ephy_reset_gpio_flags = GPIOF_INIT_HIGH, }; #endif /* CONFIG_BCM63XX_CPU_3368 */ @@ -74,44 +68,44 @@ static struct board_info __initdata board_cvg834g = { */ #ifdef CONFIG_BCM63XX_CPU_6328 static struct board_info __initdata board_96328avng = { - .name = "96328avng", - .expected_cpu_id = 0x6328, + .name = "96328avng", + .expected_cpu_id = 0x6328, - .has_uart0 = 1, - .has_pci = 1, - .has_usbd = 0, + .has_pci = 1, + .has_uart0 = 1, + .has_usbd = 0, .usbd = { - .use_fullspeed = 0, - .port_no = 0, + .use_fullspeed = 0, + .port_no = 0, }, .leds = { { - .name = "96328avng::ppp-fail", - .gpio = 2, - .active_low = 1, + .name = "96328avng::ppp-fail", + .gpio = 2, + .active_low = 1, }, { - .name = "96328avng::power", - .gpio = 4, - .active_low = 1, + .name = "96328avng::power", + .gpio = 4, + .active_low = 1, .default_trigger = "default-on", }, { - .name = "96328avng::power-fail", - .gpio = 8, - .active_low = 1, + .name = "96328avng::power-fail", + .gpio = 8, + .active_low = 1, }, { - .name = "96328avng::wps", - .gpio = 9, - .active_low = 1, + .name = "96328avng::wps", + .gpio = 9, + .active_low = 1, }, { - .name = "96328avng::ppp", - .gpio = 11, - .active_low = 1, + .name = "96328avng::ppp", + .gpio = 11, + .active_low = 1, }, }, }; @@ -122,85 +116,86 @@ static struct board_info __initdata board_96328avng = { */ #ifdef CONFIG_BCM63XX_CPU_6338 static struct board_info __initdata board_96338gw = { - .name = "96338GW", - .expected_cpu_id = 0x6338, + .name = "96338GW", + .expected_cpu_id = 0x6338, - .has_uart0 = 1, - .has_enet0 = 1, + .has_ohci0 = 1, + .has_uart0 = 1, + + .has_enet0 = 1, .enet0 = { - .force_speed_100 = 1, - .force_duplex_full = 1, + .force_speed_100 = 1, + .force_duplex_full = 1, }, - .has_ohci0 = 1, - .leds = { { - .name = "adsl", - .gpio = 3, - .active_low = 1, + .name = "adsl", + .gpio = 3, + .active_low = 1, }, { - .name = "ses", - .gpio = 5, - .active_low = 1, + .name = "ses", + .gpio = 5, + .active_low = 1, }, { - .name = "ppp-fail", - .gpio = 4, - .active_low = 1, + .name = "ppp-fail", + .gpio = 4, + .active_low = 1, }, { - .name = "power", - .gpio = 0, - .active_low = 1, + .name = "power", + .gpio = 0, + .active_low = 1, .default_trigger = "default-on", }, { - .name = "stop", - .gpio = 1, - .active_low = 1, + .name = "stop", + .gpio = 1, + .active_low = 1, } }, }; static struct board_info __initdata board_96338w = { - .name = "96338W", - .expected_cpu_id = 0x6338, + .name = "96338W", + .expected_cpu_id = 0x6338, + + .has_uart0 = 1, - .has_uart0 = 1, - .has_enet0 = 1, + .has_enet0 = 1, .enet0 = { - .force_speed_100 = 1, - .force_duplex_full = 1, + .force_speed_100 = 1, + .force_duplex_full = 1, }, .leds = { { - .name = "adsl", - .gpio = 3, - .active_low = 1, + .name = "adsl", + .gpio = 3, + .active_low = 1, }, { - .name = "ses", - .gpio = 5, - .active_low = 1, + .name = "ses", + .gpio = 5, + .active_low = 1, }, { - .name = "ppp-fail", - .gpio = 4, - .active_low = 1, + .name = "ppp-fail", + .gpio = 4, + .active_low = 1, }, { - .name = "power", - .gpio = 0, - .active_low = 1, + .name = "power", + .gpio = 0, + .active_low = 1, .default_trigger = "default-on", }, { - .name = "stop", - .gpio = 1, - .active_low = 1, + .name = "stop", + .gpio = 1, + .active_low = 1, }, }, }; @@ -211,10 +206,10 @@ static struct board_info __initdata board_96338w = { */ #ifdef CONFIG_BCM63XX_CPU_6345 static struct board_info __initdata board_96345gw2 = { - .name = "96345GW2", - .expected_cpu_id = 0x6345, + .name = "96345GW2", + .expected_cpu_id = 0x6345, - .has_uart0 = 1, + .has_uart0 = 1, }; #endif /* CONFIG_BCM63XX_CPU_6345 */ @@ -223,286 +218,282 @@ static struct board_info __initdata board_96345gw2 = { */ #ifdef CONFIG_BCM63XX_CPU_6348 static struct board_info __initdata board_96348r = { - .name = "96348R", - .expected_cpu_id = 0x6348, + .name = "96348R", + .expected_cpu_id = 0x6348, - .has_uart0 = 1, - .has_enet0 = 1, - .has_pci = 1, + .has_pci = 1, + .has_uart0 = 1, + .has_enet0 = 1, .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, + .has_phy = 1, + .use_internal_phy = 1, }, .leds = { { - .name = "adsl-fail", - .gpio = 2, - .active_low = 1, + .name = "adsl-fail", + .gpio = 2, + .active_low = 1, }, { - .name = "ppp", - .gpio = 3, - .active_low = 1, + .name = "ppp", + .gpio = 3, + .active_low = 1, }, { - .name = "ppp-fail", - .gpio = 4, - .active_low = 1, + .name = "ppp-fail", + .gpio = 4, + .active_low = 1, }, { - .name = "power", - .gpio = 0, - .active_low = 1, + .name = "power", + .gpio = 0, + .active_low = 1, .default_trigger = "default-on", }, { - .name = "stop", - .gpio = 1, - .active_low = 1, + .name = "stop", + .gpio = 1, + .active_low = 1, }, }, }; static struct board_info __initdata board_96348gw_10 = { - .name = "96348GW-10", - .expected_cpu_id = 0x6348, + .name = "96348GW-10", + .expected_cpu_id = 0x6348, - .has_uart0 = 1, - .has_enet0 = 1, - .has_enet1 = 1, - .has_pci = 1, + .has_ohci0 = 1, + .has_pccard = 1, + .has_pci = 1, + .has_uart0 = 1, + .has_enet0 = 1, .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, + .has_phy = 1, + .use_internal_phy = 1, }, + + .has_enet1 = 1, .enet1 = { - .force_speed_100 = 1, - .force_duplex_full = 1, + .force_speed_100 = 1, + .force_duplex_full = 1, }, - .has_ohci0 = 1, - .has_pccard = 1, - .has_ehci0 = 1, - .leds = { { - .name = "adsl-fail", - .gpio = 2, - .active_low = 1, + .name = "adsl-fail", + .gpio = 2, + .active_low = 1, }, { - .name = "ppp", - .gpio = 3, - .active_low = 1, + .name = "ppp", + .gpio = 3, + .active_low = 1, }, { - .name = "ppp-fail", - .gpio = 4, - .active_low = 1, + .name = "ppp-fail", + .gpio = 4, + .active_low = 1, }, { - .name = "power", - .gpio = 0, - .active_low = 1, + .name = "power", + .gpio = 0, + .active_low = 1, .default_trigger = "default-on", }, { - .name = "stop", - .gpio = 1, - .active_low = 1, + .name = "stop", + .gpio = 1, + .active_low = 1, }, }, }; static struct board_info __initdata board_96348gw_11 = { - .name = "96348GW-11", - .expected_cpu_id = 0x6348, + .name = "96348GW-11", + .expected_cpu_id = 0x6348, - .has_uart0 = 1, - .has_enet0 = 1, - .has_enet1 = 1, - .has_pci = 1, + .has_ohci0 = 1, + .has_pccard = 1, + .has_pci = 1, + .has_uart0 = 1, + .has_enet0 = 1, .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, + .has_phy = 1, + .use_internal_phy = 1, }, + .has_enet1 = 1, .enet1 = { - .force_speed_100 = 1, - .force_duplex_full = 1, + .force_speed_100 = 1, + .force_duplex_full = 1, }, - - .has_ohci0 = 1, - .has_pccard = 1, - .has_ehci0 = 1, - .leds = { { - .name = "adsl-fail", - .gpio = 2, - .active_low = 1, + .name = "adsl-fail", + .gpio = 2, + .active_low = 1, }, { - .name = "ppp", - .gpio = 3, - .active_low = 1, + .name = "ppp", + .gpio = 3, + .active_low = 1, }, { - .name = "ppp-fail", - .gpio = 4, - .active_low = 1, + .name = "ppp-fail", + .gpio = 4, + .active_low = 1, }, { - .name = "power", - .gpio = 0, - .active_low = 1, + .name = "power", + .gpio = 0, + .active_low = 1, .default_trigger = "default-on", }, { - .name = "stop", - .gpio = 1, - .active_low = 1, + .name = "stop", + .gpio = 1, + .active_low = 1, }, }, }; static struct board_info __initdata board_96348gw = { - .name = "96348GW", - .expected_cpu_id = 0x6348, + .name = "96348GW", + .expected_cpu_id = 0x6348, - .has_uart0 = 1, - .has_enet0 = 1, - .has_enet1 = 1, - .has_pci = 1, + .has_ohci0 = 1, + .has_pci = 1, + .has_uart0 = 1, + .has_enet0 = 1, .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, + .has_phy = 1, + .use_internal_phy = 1, }, + + .has_enet1 = 1, .enet1 = { - .force_speed_100 = 1, - .force_duplex_full = 1, + .force_speed_100 = 1, + .force_duplex_full = 1, }, - .has_ohci0 = 1, - .leds = { { - .name = "adsl-fail", - .gpio = 2, - .active_low = 1, + .name = "adsl-fail", + .gpio = 2, + .active_low = 1, }, { - .name = "ppp", - .gpio = 3, - .active_low = 1, + .name = "ppp", + .gpio = 3, + .active_low = 1, }, { - .name = "ppp-fail", - .gpio = 4, - .active_low = 1, + .name = "ppp-fail", + .gpio = 4, + .active_low = 1, }, { - .name = "power", - .gpio = 0, - .active_low = 1, + .name = "power", + .gpio = 0, + .active_low = 1, .default_trigger = "default-on", }, { - .name = "stop", - .gpio = 1, - .active_low = 1, + .name = "stop", + .gpio = 1, + .active_low = 1, }, }, }; static struct board_info __initdata board_FAST2404 = { - .name = "F@ST2404", - .expected_cpu_id = 0x6348, + .name = "F@ST2404", + .expected_cpu_id = 0x6348, - .has_uart0 = 1, - .has_enet0 = 1, - .has_enet1 = 1, - .has_pci = 1, + .has_ohci0 = 1, + .has_pccard = 1, + .has_pci = 1, + .has_uart0 = 1, + .has_enet0 = 1, .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, + .has_phy = 1, + .use_internal_phy = 1, }, + .has_enet1 = 1, .enet1 = { - .force_speed_100 = 1, - .force_duplex_full = 1, + .force_speed_100 = 1, + .force_duplex_full = 1, }, - - .has_ohci0 = 1, - .has_pccard = 1, - .has_ehci0 = 1, }; static struct board_info __initdata board_rta1025w_16 = { - .name = "RTA1025W_16", - .expected_cpu_id = 0x6348, + .name = "RTA1025W_16", + .expected_cpu_id = 0x6348, - .has_enet0 = 1, - .has_enet1 = 1, - .has_pci = 1, + .has_pci = 1, + .has_enet0 = 1, .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, + .has_phy = 1, + .use_internal_phy = 1, }, + + .has_enet1 = 1, .enet1 = { - .force_speed_100 = 1, - .force_duplex_full = 1, + .force_speed_100 = 1, + .force_duplex_full = 1, }, }; static struct board_info __initdata board_DV201AMR = { - .name = "DV201AMR", - .expected_cpu_id = 0x6348, + .name = "DV201AMR", + .expected_cpu_id = 0x6348, - .has_uart0 = 1, - .has_pci = 1, - .has_ohci0 = 1, + .has_ohci0 = 1, + .has_pci = 1, + .has_uart0 = 1, - .has_enet0 = 1, - .has_enet1 = 1, + .has_enet0 = 1, .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, + .has_phy = 1, + .use_internal_phy = 1, }, + + .has_enet1 = 1, .enet1 = { - .force_speed_100 = 1, - .force_duplex_full = 1, + .force_speed_100 = 1, + .force_duplex_full = 1, }, }; static struct board_info __initdata board_96348gw_a = { - .name = "96348GW-A", - .expected_cpu_id = 0x6348, + .name = "96348GW-A", + .expected_cpu_id = 0x6348, - .has_uart0 = 1, - .has_enet0 = 1, - .has_enet1 = 1, - .has_pci = 1, + .has_ohci0 = 1, + .has_pci = 1, + .has_uart0 = 1, + .has_enet0 = 1, .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, + .has_phy = 1, + .use_internal_phy = 1, }, + + .has_enet1 = 1, .enet1 = { - .force_speed_100 = 1, - .force_duplex_full = 1, + .force_speed_100 = 1, + .force_duplex_full = 1, }, - - .has_ohci0 = 1, }; #endif /* CONFIG_BCM63XX_CPU_6348 */ @@ -511,146 +502,142 @@ static struct board_info __initdata board_96348gw_a = { */ #ifdef CONFIG_BCM63XX_CPU_6358 static struct board_info __initdata board_96358vw = { - .name = "96358VW", - .expected_cpu_id = 0x6358, + .name = "96358VW", + .expected_cpu_id = 0x6358, - .has_uart0 = 1, - .has_enet0 = 1, - .has_enet1 = 1, - .has_pci = 1, + .has_ehci0 = 1, + .has_ohci0 = 1, + .has_pccard = 1, + .has_pci = 1, + .has_uart0 = 1, + .has_enet0 = 1, .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, + .has_phy = 1, + .use_internal_phy = 1, }, + .has_enet1 = 1, .enet1 = { - .force_speed_100 = 1, - .force_duplex_full = 1, + .force_speed_100 = 1, + .force_duplex_full = 1, }, - .has_ohci0 = 1, - .has_pccard = 1, - .has_ehci0 = 1, - .leds = { { - .name = "adsl-fail", - .gpio = 15, - .active_low = 1, + .name = "adsl-fail", + .gpio = 15, + .active_low = 1, }, { - .name = "ppp", - .gpio = 22, - .active_low = 1, + .name = "ppp", + .gpio = 22, + .active_low = 1, }, { - .name = "ppp-fail", - .gpio = 23, - .active_low = 1, + .name = "ppp-fail", + .gpio = 23, + .active_low = 1, }, { - .name = "power", - .gpio = 4, + .name = "power", + .gpio = 4, .default_trigger = "default-on", }, { - .name = "stop", - .gpio = 5, + .name = "stop", + .gpio = 5, }, }, }; static struct board_info __initdata board_96358vw2 = { - .name = "96358VW2", - .expected_cpu_id = 0x6358, + .name = "96358VW2", + .expected_cpu_id = 0x6358, - .has_uart0 = 1, - .has_enet0 = 1, - .has_enet1 = 1, - .has_pci = 1, + .has_ehci0 = 1, + .has_ohci0 = 1, + .has_pccard = 1, + .has_pci = 1, + .has_uart0 = 1, + .has_enet0 = 1, .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, + .has_phy = 1, + .use_internal_phy = 1, }, + .has_enet1 = 1, .enet1 = { - .force_speed_100 = 1, - .force_duplex_full = 1, + .force_speed_100 = 1, + .force_duplex_full = 1, }, - - .has_ohci0 = 1, - .has_pccard = 1, - .has_ehci0 = 1, - .leds = { { - .name = "adsl", - .gpio = 22, - .active_low = 1, + .name = "adsl", + .gpio = 22, + .active_low = 1, }, { - .name = "ppp-fail", - .gpio = 23, + .name = "ppp-fail", + .gpio = 23, }, { - .name = "power", - .gpio = 5, - .active_low = 1, + .name = "power", + .gpio = 5, + .active_low = 1, .default_trigger = "default-on", }, { - .name = "stop", - .gpio = 4, - .active_low = 1, + .name = "stop", + .gpio = 4, + .active_low = 1, }, }, }; static struct board_info __initdata board_AGPFS0 = { - .name = "AGPF-S0", - .expected_cpu_id = 0x6358, + .name = "AGPF-S0", + .expected_cpu_id = 0x6358, - .has_uart0 = 1, - .has_enet0 = 1, - .has_enet1 = 1, - .has_pci = 1, + .has_ehci0 = 1, + .has_ohci0 = 1, + .has_pci = 1, + .has_uart0 = 1, + .has_enet0 = 1, .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, + .has_phy = 1, + .use_internal_phy = 1, }, + .has_enet1 = 1, .enet1 = { - .force_speed_100 = 1, - .force_duplex_full = 1, + .force_speed_100 = 1, + .force_duplex_full = 1, }, - - .has_ohci0 = 1, - .has_ehci0 = 1, }; static struct board_info __initdata board_DWVS0 = { - .name = "DWV-S0", - .expected_cpu_id = 0x6358, + .name = "DWV-S0", + .expected_cpu_id = 0x6358, - .has_enet0 = 1, - .has_enet1 = 1, - .has_pci = 1, + .has_ehci0 = 1, + .has_ohci0 = 1, + .has_pci = 1, + .has_enet0 = 1, .enet0 = { - .has_phy = 1, - .use_internal_phy = 1, + .has_phy = 1, + .use_internal_phy = 1, }, + .has_enet1 = 1, .enet1 = { - .force_speed_100 = 1, - .force_duplex_full = 1, + .force_speed_100 = 1, + .force_duplex_full = 1, }, - - .has_ohci0 = 1, }; #endif /* CONFIG_BCM63XX_CPU_6358 */ diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c index e28ee9a7cc7e..d811e3e03f81 100644 --- a/arch/mips/bcm63xx/setup.c +++ b/arch/mips/bcm63xx/setup.c @@ -146,7 +146,7 @@ void __init plat_time_init(void) void __init plat_mem_setup(void) { - add_memory_region(0, bcm63xx_get_memory_size(), BOOT_MEM_RAM); + memblock_add(0, bcm63xx_get_memory_size()); _machine_halt = bcm63xx_machine_halt; _machine_restart = __bcm63xx_machine_reboot; diff --git a/arch/mips/bmips/dma.c b/arch/mips/bmips/dma.c index df56bf4179e3..49061b870680 100644 --- a/arch/mips/bmips/dma.c +++ b/arch/mips/bmips/dma.c @@ -40,7 +40,7 @@ static struct bmips_dma_range *bmips_dma_ranges; #define FLUSH_RAC 0x100 -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t pa) +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t pa) { struct bmips_dma_range *r; @@ -52,7 +52,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t pa) return pa; } -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr) { struct bmips_dma_range *r; diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index 6e56caef69f0..d66511825fe1 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -22,7 +22,12 @@ KBUILD_CFLAGS := $(filter-out -pg, $(KBUILD_CFLAGS)) KBUILD_CFLAGS := $(filter-out -fstack-protector, $(KBUILD_CFLAGS)) -KBUILD_CFLAGS := $(KBUILD_CFLAGS) -D__KERNEL__ \ +# Disable lq/sq in zboot +ifdef CONFIG_CPU_LOONGSON64 +KBUILD_CFLAGS := $(filter-out -march=loongson3a, $(KBUILD_CFLAGS)) -march=mips64r2 +endif + +KBUILD_CFLAGS := $(KBUILD_CFLAGS) -D__KERNEL__ -D__DISABLE_EXPORTS \ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" KBUILD_AFLAGS := $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ @@ -70,6 +75,7 @@ tool_$(CONFIG_KERNEL_LZ4) = lz4 tool_$(CONFIG_KERNEL_LZMA) = lzma tool_$(CONFIG_KERNEL_LZO) = lzo tool_$(CONFIG_KERNEL_XZ) = xzkern +tool_$(CONFIG_KERNEL_ZSTD) = zstd22 targets += vmlinux.bin.z $(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c index 88f5d637b1c4..c61c641674e6 100644 --- a/arch/mips/boot/compressed/decompress.c +++ b/arch/mips/boot/compressed/decompress.c @@ -72,6 +72,10 @@ void error(char *x) #include "../../../../lib/decompress_unxz.c" #endif +#ifdef CONFIG_KERNEL_ZSTD +#include "../../../../lib/decompress_unzstd.c" +#endif + const unsigned long __stack_chk_guard = 0x000a0dff; void __stack_chk_fail(void) diff --git a/arch/mips/boot/compressed/string.c b/arch/mips/boot/compressed/string.c index 43beecc3587c..0b593b709228 100644 --- a/arch/mips/boot/compressed/string.c +++ b/arch/mips/boot/compressed/string.c @@ -5,6 +5,7 @@ * Very small subset of simple string routines */ +#include <linux/compiler_attributes.h> #include <linux/types.h> void *memcpy(void *dest, const void *src, size_t n) @@ -27,3 +28,19 @@ void *memset(void *s, int c, size_t n) ss[i] = c; return s; } + +void * __weak memmove(void *dest, const void *src, size_t n) +{ + unsigned int i; + const char *s = src; + char *d = dest; + + if ((uintptr_t)dest < (uintptr_t)src) { + for (i = 0; i < n; i++) + d[i] = s[i]; + } else { + for (i = n; i > 0; i--) + d[i - 1] = s[i - 1]; + } + return dest; +} diff --git a/arch/mips/boot/dts/brcm/bcm63268.dtsi b/arch/mips/boot/dts/brcm/bcm63268.dtsi index beec24145af7..5acb49b61867 100644 --- a/arch/mips/boot/dts/brcm/bcm63268.dtsi +++ b/arch/mips/boot/dts/brcm/bcm63268.dtsi @@ -117,6 +117,12 @@ status = "disabled"; }; + periph_pwr: power-controller@1000184c { + compatible = "brcm,bcm6328-power-controller"; + reg = <0x1000184c 0x4>; + #power-domain-cells = <1>; + }; + ehci: usb@10002500 { compatible = "brcm,bcm63268-ehci", "generic-ehci"; reg = <0x10002500 0x100>; diff --git a/arch/mips/boot/dts/brcm/bcm6328.dtsi b/arch/mips/boot/dts/brcm/bcm6328.dtsi index af860d06def6..1f9edd710392 100644 --- a/arch/mips/boot/dts/brcm/bcm6328.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6328.dtsi @@ -110,6 +110,12 @@ status = "disabled"; }; + periph_pwr: power-controller@10001848 { + compatible = "brcm,bcm6328-power-controller"; + reg = <0x10001848 0x4>; + #power-domain-cells = <1>; + }; + ehci: usb@10002500 { compatible = "brcm,bcm6328-ehci", "generic-ehci"; reg = <0x10002500 0x100>; diff --git a/arch/mips/boot/dts/brcm/bcm6362.dtsi b/arch/mips/boot/dts/brcm/bcm6362.dtsi index 8ae6981735b8..c98f9111e3c8 100644 --- a/arch/mips/boot/dts/brcm/bcm6362.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6362.dtsi @@ -108,6 +108,12 @@ status = "disabled"; }; + periph_pwr: power-controller@10001848 { + compatible = "brcm,bcm6362-power-controller"; + reg = <0x10001848 0x4>; + #power-domain-cells = <1>; + }; + leds0: led-controller@10001900 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/mips/boot/dts/ingenic/jz4725b.dtsi b/arch/mips/boot/dts/ingenic/jz4725b.dtsi index a8fca560878d..a1f0b71c9223 100644 --- a/arch/mips/boot/dts/ingenic/jz4725b.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4725b.dtsi @@ -7,6 +7,20 @@ #size-cells = <1>; compatible = "ingenic,jz4725b"; + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "ingenic,xburst-mxu1.0"; + reg = <0>; + + clocks = <&cgu JZ4725B_CLK_CCLK>; + clock-names = "cpu"; + }; + }; + cpuintc: interrupt-controller { #address-cells = <0>; #interrupt-cells = <1>; diff --git a/arch/mips/boot/dts/ingenic/jz4740.dtsi b/arch/mips/boot/dts/ingenic/jz4740.dtsi index 1520585c235c..eee523678ce5 100644 --- a/arch/mips/boot/dts/ingenic/jz4740.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4740.dtsi @@ -7,6 +7,20 @@ #size-cells = <1>; compatible = "ingenic,jz4740"; + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "ingenic,xburst-mxu1.0"; + reg = <0>; + + clocks = <&cgu JZ4740_CLK_CCLK>; + clock-names = "cpu"; + }; + }; + cpuintc: interrupt-controller { #address-cells = <0>; #interrupt-cells = <1>; diff --git a/arch/mips/boot/dts/ingenic/jz4770.dtsi b/arch/mips/boot/dts/ingenic/jz4770.dtsi index fa11ac950499..018721a9eea9 100644 --- a/arch/mips/boot/dts/ingenic/jz4770.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4770.dtsi @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 - #include <dt-bindings/clock/jz4770-cgu.h> #include <dt-bindings/clock/ingenic,tcu.h> @@ -8,6 +7,20 @@ #size-cells = <1>; compatible = "ingenic,jz4770"; + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "ingenic,xburst-fpu1.0-mxu1.1"; + reg = <0>; + + clocks = <&cgu JZ4770_CLK_CCLK>; + clock-names = "cpu"; + }; + }; + cpuintc: interrupt-controller { #address-cells = <0>; #interrupt-cells = <1>; diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi index b7f409a7cf5d..dfb5a7e1bb21 100644 --- a/arch/mips/boot/dts/ingenic/jz4780.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi @@ -8,6 +8,29 @@ #size-cells = <1>; compatible = "ingenic,jz4780"; + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "ingenic,xburst-fpu1.0-mxu1.1"; + reg = <0>; + + clocks = <&cgu JZ4780_CLK_CPU>; + clock-names = "cpu"; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "ingenic,xburst-fpu1.0-mxu1.1"; + reg = <1>; + + clocks = <&cgu JZ4780_CLK_CORE1>; + clock-names = "cpu"; + }; + }; + cpuintc: interrupt-controller { #address-cells = <0>; #interrupt-cells = <1>; diff --git a/arch/mips/boot/dts/ingenic/qi_lb60.dts b/arch/mips/boot/dts/ingenic/qi_lb60.dts index bf298268f1a1..ba0218971572 100644 --- a/arch/mips/boot/dts/ingenic/qi_lb60.dts +++ b/arch/mips/boot/dts/ingenic/qi_lb60.dts @@ -109,74 +109,73 @@ debounce-delay-ms = <10>; wakeup-source; - row-gpios = <&gpd 18 0 &gpd 19 0 &gpd 20 0 &gpd 21 0 - &gpd 22 0 &gpd 23 0 &gpd 24 0 &gpd 26 0>; - col-gpios = <&gpc 10 0 &gpc 11 0 &gpc 12 0 &gpc 13 0 - &gpc 14 0 &gpc 15 0 &gpc 16 0 &gpc 17 0>; + row-gpios = <&gpd 18 0>, <&gpd 19 0>, <&gpd 20 0>, <&gpd 21 0>, + <&gpd 22 0>, <&gpd 23 0>, <&gpd 24 0>, <&gpd 26 0>; + col-gpios = <&gpc 10 0>, <&gpc 11 0>, <&gpc 12 0>, <&gpc 13 0>, + <&gpc 14 0>, <&gpc 15 0>, <&gpc 16 0>, <&gpc 17 0>; gpio-activelow; - linux,keymap = < - MATRIX_KEY(0, 0, KEY_F1) /* S2 */ - MATRIX_KEY(0, 1, KEY_F2) /* S3 */ - MATRIX_KEY(0, 2, KEY_F3) /* S4 */ - MATRIX_KEY(0, 3, KEY_F4) /* S5 */ - MATRIX_KEY(0, 4, KEY_F5) /* S6 */ - MATRIX_KEY(0, 5, KEY_F6) /* S7 */ - MATRIX_KEY(0, 6, KEY_F7) /* S8 */ - - MATRIX_KEY(1, 0, KEY_Q) /* S10 */ - MATRIX_KEY(1, 1, KEY_W) /* S11 */ - MATRIX_KEY(1, 2, KEY_E) /* S12 */ - MATRIX_KEY(1, 3, KEY_R) /* S13 */ - MATRIX_KEY(1, 4, KEY_T) /* S14 */ - MATRIX_KEY(1, 5, KEY_Y) /* S15 */ - MATRIX_KEY(1, 6, KEY_U) /* S16 */ - MATRIX_KEY(1, 7, KEY_I) /* S17 */ - MATRIX_KEY(2, 0, KEY_A) /* S18 */ - MATRIX_KEY(2, 1, KEY_S) /* S19 */ - MATRIX_KEY(2, 2, KEY_D) /* S20 */ - MATRIX_KEY(2, 3, KEY_F) /* S21 */ - MATRIX_KEY(2, 4, KEY_G) /* S22 */ - MATRIX_KEY(2, 5, KEY_H) /* S23 */ - MATRIX_KEY(2, 6, KEY_J) /* S24 */ - MATRIX_KEY(2, 7, KEY_K) /* S25 */ - MATRIX_KEY(3, 0, KEY_ESC) /* S26 */ - MATRIX_KEY(3, 1, KEY_Z) /* S27 */ - MATRIX_KEY(3, 2, KEY_X) /* S28 */ - MATRIX_KEY(3, 3, KEY_C) /* S29 */ - MATRIX_KEY(3, 4, KEY_V) /* S30 */ - MATRIX_KEY(3, 5, KEY_B) /* S31 */ - MATRIX_KEY(3, 6, KEY_N) /* S32 */ - MATRIX_KEY(3, 7, KEY_M) /* S33 */ - MATRIX_KEY(4, 0, KEY_TAB) /* S34 */ - MATRIX_KEY(4, 1, KEY_CAPSLOCK) /* S35 */ - MATRIX_KEY(4, 2, KEY_BACKSLASH) /* S36 */ - MATRIX_KEY(4, 3, KEY_APOSTROPHE) /* S37 */ - MATRIX_KEY(4, 4, KEY_COMMA) /* S38 */ - MATRIX_KEY(4, 5, KEY_DOT) /* S39 */ - MATRIX_KEY(4, 6, KEY_SLASH) /* S40 */ - MATRIX_KEY(4, 7, KEY_UP) /* S41 */ - MATRIX_KEY(5, 0, KEY_O) /* S42 */ - MATRIX_KEY(5, 1, KEY_L) /* S43 */ - MATRIX_KEY(5, 2, KEY_EQUAL) /* S44 */ - MATRIX_KEY(5, 3, KEY_QI_UPRED) /* S45 */ - MATRIX_KEY(5, 4, KEY_SPACE) /* S46 */ - MATRIX_KEY(5, 5, KEY_QI_QI) /* S47 */ - MATRIX_KEY(5, 6, KEY_RIGHTCTRL) /* S48 */ - MATRIX_KEY(5, 7, KEY_LEFT) /* S49 */ - MATRIX_KEY(6, 0, KEY_F8) /* S50 */ - MATRIX_KEY(6, 1, KEY_P) /* S51 */ - MATRIX_KEY(6, 2, KEY_BACKSPACE)/* S52 */ - MATRIX_KEY(6, 3, KEY_ENTER) /* S53 */ - MATRIX_KEY(6, 4, KEY_QI_VOLUP) /* S54 */ - MATRIX_KEY(6, 5, KEY_QI_VOLDOWN) /* S55 */ - MATRIX_KEY(6, 6, KEY_DOWN) /* S56 */ - MATRIX_KEY(6, 7, KEY_RIGHT) /* S57 */ - - MATRIX_KEY(7, 0, KEY_LEFTSHIFT) /* S58 */ - MATRIX_KEY(7, 1, KEY_LEFTALT) /* S59 */ - MATRIX_KEY(7, 2, KEY_QI_FN) /* S60 */ - >; + linux,keymap = + <MATRIX_KEY(0, 0, KEY_F1)>, /* S2 */ + <MATRIX_KEY(0, 1, KEY_F2)>, /* S3 */ + <MATRIX_KEY(0, 2, KEY_F3)>, /* S4 */ + <MATRIX_KEY(0, 3, KEY_F4)>, /* S5 */ + <MATRIX_KEY(0, 4, KEY_F5)>, /* S6 */ + <MATRIX_KEY(0, 5, KEY_F6)>, /* S7 */ + <MATRIX_KEY(0, 6, KEY_F7)>, /* S8 */ + + <MATRIX_KEY(1, 0, KEY_Q)>, /* S10 */ + <MATRIX_KEY(1, 1, KEY_W)>, /* S11 */ + <MATRIX_KEY(1, 2, KEY_E)>, /* S12 */ + <MATRIX_KEY(1, 3, KEY_R)>, /* S13 */ + <MATRIX_KEY(1, 4, KEY_T)>, /* S14 */ + <MATRIX_KEY(1, 5, KEY_Y)>, /* S15 */ + <MATRIX_KEY(1, 6, KEY_U)>, /* S16 */ + <MATRIX_KEY(1, 7, KEY_I)>, /* S17 */ + <MATRIX_KEY(2, 0, KEY_A)>, /* S18 */ + <MATRIX_KEY(2, 1, KEY_S)>, /* S19 */ + <MATRIX_KEY(2, 2, KEY_D)>, /* S20 */ + <MATRIX_KEY(2, 3, KEY_F)>, /* S21 */ + <MATRIX_KEY(2, 4, KEY_G)>, /* S22 */ + <MATRIX_KEY(2, 5, KEY_H)>, /* S23 */ + <MATRIX_KEY(2, 6, KEY_J)>, /* S24 */ + <MATRIX_KEY(2, 7, KEY_K)>, /* S25 */ + <MATRIX_KEY(3, 0, KEY_ESC)>, /* S26 */ + <MATRIX_KEY(3, 1, KEY_Z)>, /* S27 */ + <MATRIX_KEY(3, 2, KEY_X)>, /* S28 */ + <MATRIX_KEY(3, 3, KEY_C)>, /* S29 */ + <MATRIX_KEY(3, 4, KEY_V)>, /* S30 */ + <MATRIX_KEY(3, 5, KEY_B)>, /* S31 */ + <MATRIX_KEY(3, 6, KEY_N)>, /* S32 */ + <MATRIX_KEY(3, 7, KEY_M)>, /* S33 */ + <MATRIX_KEY(4, 0, KEY_TAB)>, /* S34 */ + <MATRIX_KEY(4, 1, KEY_CAPSLOCK)>, /* S35 */ + <MATRIX_KEY(4, 2, KEY_BACKSLASH)>, /* S36 */ + <MATRIX_KEY(4, 3, KEY_APOSTROPHE)>, /* S37 */ + <MATRIX_KEY(4, 4, KEY_COMMA)>, /* S38 */ + <MATRIX_KEY(4, 5, KEY_DOT)>, /* S39 */ + <MATRIX_KEY(4, 6, KEY_SLASH)>, /* S40 */ + <MATRIX_KEY(4, 7, KEY_UP)>, /* S41 */ + <MATRIX_KEY(5, 0, KEY_O)>, /* S42 */ + <MATRIX_KEY(5, 1, KEY_L)>, /* S43 */ + <MATRIX_KEY(5, 2, KEY_EQUAL)>, /* S44 */ + <MATRIX_KEY(5, 3, KEY_QI_UPRED)>, /* S45 */ + <MATRIX_KEY(5, 4, KEY_SPACE)>, /* S46 */ + <MATRIX_KEY(5, 5, KEY_QI_QI)>, /* S47 */ + <MATRIX_KEY(5, 6, KEY_RIGHTCTRL)>, /* S48 */ + <MATRIX_KEY(5, 7, KEY_LEFT)>, /* S49 */ + <MATRIX_KEY(6, 0, KEY_F8)>, /* S50 */ + <MATRIX_KEY(6, 1, KEY_P)>, /* S51 */ + <MATRIX_KEY(6, 2, KEY_BACKSPACE)>,/* S52 */ + <MATRIX_KEY(6, 3, KEY_ENTER)>, /* S53 */ + <MATRIX_KEY(6, 4, KEY_QI_VOLUP)>, /* S54 */ + <MATRIX_KEY(6, 5, KEY_QI_VOLDOWN)>, /* S55 */ + <MATRIX_KEY(6, 6, KEY_DOWN)>, /* S56 */ + <MATRIX_KEY(6, 7, KEY_RIGHT)>, /* S57 */ + + <MATRIX_KEY(7, 0, KEY_LEFTSHIFT)>, /* S58 */ + <MATRIX_KEY(7, 1, KEY_LEFTALT)>, /* S59 */ + <MATRIX_KEY(7, 2, KEY_QI_FN)>; /* S60 */ }; spi { @@ -261,12 +260,12 @@ #address-cells = <1>; #size-cells = <0>; - ingenic,bch-controller = <&ecc>; + ecc-engine = <&ecc>; pinctrl-names = "default"; pinctrl-0 = <&pins_nemc>; - rb-gpios = <&gpc 30 GPIO_ACTIVE_LOW>; + rb-gpios = <&gpc 30 GPIO_ACTIVE_HIGH>; nand@1 { reg = <1>; @@ -324,7 +323,7 @@ pins_nemc: nemc { function = "nand"; - groups = "nand-cs1"; + groups = "nand-fre-fwe", "nand-cs1"; }; pins_uart0: uart0 { diff --git a/arch/mips/boot/dts/ingenic/x1000.dtsi b/arch/mips/boot/dts/ingenic/x1000.dtsi index 9de9e7c2d523..1f1f896dd1f7 100644 --- a/arch/mips/boot/dts/ingenic/x1000.dtsi +++ b/arch/mips/boot/dts/ingenic/x1000.dtsi @@ -8,6 +8,20 @@ #size-cells = <1>; compatible = "ingenic,x1000", "ingenic,x1000e"; + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "ingenic,xburst-fpu1.0-mxu1.1"; + reg = <0>; + + clocks = <&cgu X1000_CLK_CPU>; + clock-names = "cpu"; + }; + }; + cpuintc: interrupt-controller { #address-cells = <0>; #interrupt-cells = <1>; diff --git a/arch/mips/boot/dts/ingenic/x1830.dtsi b/arch/mips/boot/dts/ingenic/x1830.dtsi index eb1214481a33..b05dac3ae308 100644 --- a/arch/mips/boot/dts/ingenic/x1830.dtsi +++ b/arch/mips/boot/dts/ingenic/x1830.dtsi @@ -8,6 +8,20 @@ #size-cells = <1>; compatible = "ingenic,x1830"; + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "ingenic,xburst-fpu2.0-mxu2.0"; + reg = <0>; + + clocks = <&cgu X1830_CLK_CPU>; + clock-names = "cpu"; + }; + }; + cpuintc: interrupt-controller { #address-cells = <0>; #interrupt-cells = <1>; diff --git a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi index e574a062dfae..f99a7a11fded 100644 --- a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi +++ b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi @@ -19,6 +19,45 @@ #interrupt-cells = <2>; }; + ls7a_uart0: serial@10080000 { + compatible = "ns16550a"; + reg = <0 0x10080000 0 0x100>; + clock-frequency = <50000000>; + interrupt-parent = <&pic>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + no-loopback-test; + }; + + ls7a_uart1: serial@10080100 { + status = "disabled"; + compatible = "ns16550a"; + reg = <0 0x10080100 0 0x100>; + clock-frequency = <50000000>; + interrupt-parent = <&pic>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + no-loopback-test; + }; + + ls7a_uart2: serial@10080200 { + status = "disabled"; + compatible = "ns16550a"; + reg = <0 0x10080200 0 0x100>; + clock-frequency = <50000000>; + interrupt-parent = <&pic>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + no-loopback-test; + }; + + ls7a_uart3: serial@10080300 { + status = "disabled"; + compatible = "ns16550a"; + reg = <0 0x10080300 0 0x100>; + clock-frequency = <50000000>; + interrupt-parent = <&pic>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + no-loopback-test; + }; + pci@1a000000 { compatible = "loongson,ls7a-pci"; device_type = "pci"; diff --git a/arch/mips/boot/dts/mscc/ocelot.dtsi b/arch/mips/boot/dts/mscc/ocelot.dtsi index f94e8a02ed06..535a98284dcb 100644 --- a/arch/mips/boot/dts/mscc/ocelot.dtsi +++ b/arch/mips/boot/dts/mscc/ocelot.dtsi @@ -134,11 +134,13 @@ <0x1280000 0x100>, <0x1800000 0x80000>, <0x1880000 0x10000>, + <0x1040000 0x10000>, + <0x1050000 0x10000>, <0x1060000 0x10000>; reg-names = "sys", "rew", "qs", "ptp", "port0", "port1", "port2", "port3", "port4", "port5", "port6", "port7", "port8", "port9", "port10", "qsys", - "ana", "s2"; + "ana", "s0", "s1", "s2"; interrupts = <18 21 22>; interrupt-names = "ptp_rdy", "xtr", "inj"; diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c index 14ea680d180e..df70308db0e6 100644 --- a/arch/mips/cavium-octeon/dma-octeon.c +++ b/arch/mips/cavium-octeon/dma-octeon.c @@ -168,7 +168,7 @@ void __init octeon_pci_dma_init(void) } #endif /* CONFIG_PCI */ -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { #ifdef CONFIG_PCI if (dev && dev_is_pci(dev)) @@ -177,7 +177,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) return paddr; } -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr) +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) { #ifdef CONFIG_PCI if (dev && dev_is_pci(dev)) @@ -190,25 +190,25 @@ char *octeon_swiotlb; void __init plat_swiotlb_setup(void) { - struct memblock_region *mem; + phys_addr_t start, end; phys_addr_t max_addr; phys_addr_t addr_size; size_t swiotlbsize; unsigned long swiotlb_nslabs; + u64 i; max_addr = 0; addr_size = 0; - for_each_memblock(memory, mem) { + for_each_mem_range(i, &start, &end) { /* These addresses map low for PCI. */ - if (mem->base > 0x410000000ull && !OCTEON_IS_OCTEON2()) + if (start > 0x410000000ull && !OCTEON_IS_OCTEON2()) continue; - addr_size += mem->size; - - if (max_addr < mem->base + mem->size) - max_addr = mem->base + mem->size; + addr_size += (end - start); + if (max_addr < end) + max_addr = end; } swiotlbsize = PAGE_SIZE; diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 4f34d92b52f9..561389d3fadb 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -16,6 +16,7 @@ #include <linux/export.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/memblock.h> #include <linux/serial.h> #include <linux/smp.h> #include <linux/types.h> @@ -930,7 +931,7 @@ static __init void memory_exclude_page(u64 addr, u64 *mem, u64 *size) { if (addr > *mem && addr < *mem + *size) { u64 inc = addr - *mem; - add_memory_region(*mem, inc, BOOT_MEM_RAM); + memblock_add(*mem, inc); *mem += inc; *size -= inc; } @@ -992,19 +993,18 @@ void __init plat_mem_setup(void) /* Crashkernel ignores bootmem list. It relies on mem=X@Y option */ #ifdef CONFIG_CRASH_DUMP - add_memory_region(reserve_low_mem, max_memory, BOOT_MEM_RAM); + memblock_add(reserve_low_mem, max_memory); total += max_memory; #else #ifdef CONFIG_KEXEC if (crashk_size > 0) { - add_memory_region(crashk_base, crashk_size, BOOT_MEM_RAM); + memblock_add(crashk_base, crashk_size); crashk_end = crashk_base + crashk_size; } #endif /* - * When allocating memory, we want incrementing addresses from - * bootmem_alloc so the code in add_memory_region can merge - * regions next to each other. + * When allocating memory, we want incrementing addresses, + * which is handled by memblock */ cvmx_bootmem_lock(); while (total < max_memory) { @@ -1039,13 +1039,9 @@ void __init plat_mem_setup(void) */ if (memory < crashk_base && end > crashk_end) { /* region is fully in */ - add_memory_region(memory, - crashk_base - memory, - BOOT_MEM_RAM); + memblock_add(memory, crashk_base - memory); total += crashk_base - memory; - add_memory_region(crashk_end, - end - crashk_end, - BOOT_MEM_RAM); + memblock_add(crashk_end, end - crashk_end); total += end - crashk_end; continue; } @@ -1073,7 +1069,7 @@ void __init plat_mem_setup(void) */ mem_alloc_size -= end - crashk_base; #endif - add_memory_region(memory, mem_alloc_size, BOOT_MEM_RAM); + memblock_add(memory, mem_alloc_size); total += mem_alloc_size; /* Recovering mem_alloc_size */ mem_alloc_size = 4 << 20; @@ -1088,7 +1084,7 @@ void __init plat_mem_setup(void) /* Adjust for physical offset. */ kernel_start &= ~0xffffffff80000000ULL; - add_memory_region(kernel_start, kernel_size, BOOT_MEM_RAM); + memblock_add(kernel_start, kernel_size); #endif /* CONFIG_CRASH_DUMP */ #ifdef CONFIG_CAVIUM_RESERVE32 @@ -1126,7 +1122,7 @@ EXPORT_SYMBOL(prom_putchar); void __init prom_free_prom_memory(void) { - if (CAVIUM_OCTEON_DCACHE_PREFETCH_WAR) { + if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { /* Check for presence of Core-14449 fix. */ u32 insn; u32 *foo; diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c index c136a18c7221..46581e686882 100644 --- a/arch/mips/cobalt/setup.c +++ b/arch/mips/cobalt/setup.c @@ -13,6 +13,7 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/ioport.h> +#include <linux/memblock.h> #include <linux/pm.h> #include <asm/bootinfo.h> @@ -112,7 +113,7 @@ void __init prom_init(void) strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE); } - add_memory_region(0x0, memsz, BOOT_MEM_RAM); + memblock_add(0, memsz); setup_8250_early_printk_port(CKSEG1ADDR(0x1c800000), 0, 0); } diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig index 0a46199fdc3f..052c5ad0f2b1 100644 --- a/arch/mips/configs/ci20_defconfig +++ b/arch/mips/configs/ci20_defconfig @@ -22,7 +22,7 @@ CONFIG_EMBEDDED=y # CONFIG_VM_EVENT_COUNTERS is not set # CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y -CONFIG_MACH_INGENIC=y +CONFIG_MACH_INGENIC_SOC=y CONFIG_JZ4780_CI20=y CONFIG_HIGHMEM=y CONFIG_HZ_100=y @@ -42,7 +42,7 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_DEVTMPFS=y -# CONFIG_FW_LOADER is not set +CONFIG_FW_LOADER=m # CONFIG_ALLOW_DEV_COREDUMP is not set CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y diff --git a/arch/mips/configs/cu1000-neo_defconfig b/arch/mips/configs/cu1000-neo_defconfig index e924c817f73d..55d0690a3ffe 100644 --- a/arch/mips/configs/cu1000-neo_defconfig +++ b/arch/mips/configs/cu1000-neo_defconfig @@ -1,5 +1,3 @@ -CONFIG_LOCALVERSION_AUTO=y -CONFIG_KERNEL_GZIP=y CONFIG_SYSVIPC=y CONFIG_NO_HZ_IDLE=y CONFIG_HIGH_RES_TIMERS=y @@ -9,7 +7,6 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_CGROUPS=y CONFIG_MEMCG=y -CONFIG_MEMCG_KMEM=y CONFIG_CGROUP_SCHED=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_DEVICE=y @@ -22,7 +19,7 @@ CONFIG_EMBEDDED=y # CONFIG_VM_EVENT_COUNTERS is not set # CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y -CONFIG_MACH_INGENIC=y +CONFIG_MACH_INGENIC_SOC=y CONFIG_X1000_CU1000_NEO=y CONFIG_HIGHMEM=y CONFIG_HZ_100=y @@ -31,7 +28,6 @@ CONFIG_HZ_100=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_COMPACTION is not set CONFIG_CMA=y -CONFIG_CMA_AREAS=7 CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -40,19 +36,16 @@ CONFIG_CFG80211=y CONFIG_UEVENT_HELPER=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y -# CONFIG_FW_LOADER is not set # CONFIG_ALLOW_DEV_COREDUMP is not set CONFIG_NETDEVICES=y CONFIG_STMMAC_ETH=y CONFIG_SMSC_PHY=y CONFIG_BRCMFMAC=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_LEGACY_PTY_COUNT=2 -CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=3 @@ -66,8 +59,6 @@ CONFIG_GPIO_SYSFS=y CONFIG_SENSORS_ADS7828=y CONFIG_WATCHDOG=y CONFIG_JZ4740_WDT=y -# CONFIG_LCD_CLASS_DEVICE is not set -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set # CONFIG_VGA_CONSOLE is not set # CONFIG_HID is not set # CONFIG_USB_SUPPORT is not set @@ -82,8 +73,6 @@ CONFIG_RTC_DRV_JZ4740=y CONFIG_DMADEVICES=y CONFIG_DMA_JZ4780=y # CONFIG_IOMMU_SUPPORT is not set -CONFIG_NVMEM=y -CONFIG_NVMEM_SYSFS=y CONFIG_EXT4_FS=y # CONFIG_DNOTIFY is not set CONFIG_AUTOFS_FS=y @@ -108,8 +97,8 @@ CONFIG_CONSOLE_LOGLEVEL_QUIET=15 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 CONFIG_DEBUG_INFO=y CONFIG_STRIP_ASM_SYMS=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y CONFIG_PANIC_ON_OOPS=y CONFIG_PANIC_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set diff --git a/arch/mips/configs/cu1830-neo_defconfig b/arch/mips/configs/cu1830-neo_defconfig index cbfb62900273..e7064851a47a 100644 --- a/arch/mips/configs/cu1830-neo_defconfig +++ b/arch/mips/configs/cu1830-neo_defconfig @@ -1,5 +1,3 @@ -CONFIG_LOCALVERSION_AUTO=y -CONFIG_KERNEL_GZIP=y CONFIG_SYSVIPC=y CONFIG_NO_HZ_IDLE=y CONFIG_HIGH_RES_TIMERS=y @@ -9,7 +7,6 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_CGROUPS=y CONFIG_MEMCG=y -CONFIG_MEMCG_KMEM=y CONFIG_CGROUP_SCHED=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_DEVICE=y @@ -22,7 +19,7 @@ CONFIG_EMBEDDED=y # CONFIG_VM_EVENT_COUNTERS is not set # CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y -CONFIG_MACH_INGENIC=y +CONFIG_MACH_INGENIC_SOC=y CONFIG_X1830_CU1830_NEO=y CONFIG_HIGHMEM=y CONFIG_HZ_100=y @@ -31,7 +28,6 @@ CONFIG_HZ_100=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_COMPACTION is not set CONFIG_CMA=y -CONFIG_CMA_AREAS=7 CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -40,7 +36,6 @@ CONFIG_CFG80211=y CONFIG_UEVENT_HELPER=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y -# CONFIG_FW_LOADER is not set # CONFIG_ALLOW_DEV_COREDUMP is not set CONFIG_MD=y CONFIG_BLK_DEV_MD=y @@ -49,13 +44,11 @@ CONFIG_NETDEVICES=y CONFIG_STMMAC_ETH=y CONFIG_ICPLUS_PHY=y CONFIG_BRCMFMAC=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_LEGACY_PTY_COUNT=2 -CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=2 @@ -69,8 +62,6 @@ CONFIG_GPIO_SYSFS=y CONFIG_SENSORS_ADS7828=y CONFIG_WATCHDOG=y CONFIG_JZ4740_WDT=y -# CONFIG_LCD_CLASS_DEVICE is not set -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set # CONFIG_VGA_CONSOLE is not set # CONFIG_HID is not set # CONFIG_USB_SUPPORT is not set @@ -85,8 +76,6 @@ CONFIG_RTC_DRV_JZ4740=y CONFIG_DMADEVICES=y CONFIG_DMA_JZ4780=y # CONFIG_IOMMU_SUPPORT is not set -CONFIG_NVMEM=y -CONFIG_NVMEM_SYSFS=y CONFIG_EXT4_FS=y # CONFIG_DNOTIFY is not set CONFIG_AUTOFS_FS=y @@ -111,8 +100,8 @@ CONFIG_CONSOLE_LOGLEVEL_QUIET=15 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 CONFIG_DEBUG_INFO=y CONFIG_STRIP_ASM_SYMS=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y CONFIG_PANIC_ON_OOPS=y CONFIG_PANIC_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set diff --git a/arch/mips/configs/gcw0_defconfig b/arch/mips/configs/gcw0_defconfig index 4994749b9eaa..7e28a4fe9d84 100644 --- a/arch/mips/configs/gcw0_defconfig +++ b/arch/mips/configs/gcw0_defconfig @@ -4,7 +4,7 @@ CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT_VOLUNTARY=y CONFIG_EMBEDDED=y CONFIG_PROFILING=y -CONFIG_MACH_INGENIC=y +CONFIG_MACH_INGENIC_SOC=y CONFIG_JZ4770_GCW0=y CONFIG_HIGHMEM=y # CONFIG_SECCOMP is not set diff --git a/arch/mips/configs/loongson3_defconfig b/arch/mips/configs/loongson3_defconfig index a65b08de4098..38a817ead8e7 100644 --- a/arch/mips/configs/loongson3_defconfig +++ b/arch/mips/configs/loongson3_defconfig @@ -30,7 +30,6 @@ CONFIG_EMBEDDED=y CONFIG_PERF_EVENTS=y CONFIG_MACH_LOONGSON64=y CONFIG_CPU_HAS_MSA=y -CONFIG_SMP=y CONFIG_NR_CPUS=16 CONFIG_HZ_256=y CONFIG_KEXEC=y @@ -403,7 +402,6 @@ CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_DEFLATE=m CONFIG_PRINTK_TIME=y -CONFIG_FRAME_WARN=1024 CONFIG_STRIP_ASM_SYMS=y CONFIG_MAGIC_SYSRQ=y # CONFIG_SCHED_DEBUG is not set diff --git a/arch/mips/configs/pnx8335_stb225_defconfig b/arch/mips/configs/pnx8335_stb225_defconfig deleted file mode 100644 index d06db6b87959..000000000000 --- a/arch/mips/configs/pnx8335_stb225_defconfig +++ /dev/null @@ -1,77 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_PREEMPT_VOLUNTARY=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_EXPERT=y -CONFIG_SLAB=y -CONFIG_NXP_STB225=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_HZ_128=y -# CONFIG_SECCOMP is not set -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_INET_AH=y -# CONFIG_IPV6 is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_LE_BYTE_SWAP=y -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_SD=y -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_ATA=y -CONFIG_NETDEVICES=y -CONFIG_INPUT_EVDEV=m -CONFIG_INPUT_EVBUG=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_VT_CONSOLE is not set -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_PNX8XXX=y -CONFIG_SERIAL_PNX8XXX_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -# CONFIG_HWMON is not set -CONFIG_FB=y -# CONFIG_VGA_CONSOLE is not set -CONFIG_SOUND=m -CONFIG_SND=m -CONFIG_SND_VERBOSE_PRINTK=y -CONFIG_SND_DEBUG=y -CONFIG_SND_SEQUENCER=m -CONFIG_EXT2_FS=m -# CONFIG_DNOTIFY is not set -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_CRAMFS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -CONFIG_NLS=y -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_UTF8=m diff --git a/arch/mips/configs/qi_lb60_defconfig b/arch/mips/configs/qi_lb60_defconfig index 81bfbee72b0c..b4448d0876d5 100644 --- a/arch/mips/configs/qi_lb60_defconfig +++ b/arch/mips/configs/qi_lb60_defconfig @@ -7,7 +7,8 @@ CONFIG_EMBEDDED=y # CONFIG_VM_EVENT_COUNTERS is not set # CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y -CONFIG_MACH_INGENIC=y +CONFIG_MACH_INGENIC_SOC=y +CONFIG_JZ4740_QI_LB60=y CONFIG_HZ_100=y # CONFIG_SECCOMP is not set CONFIG_MODULES=y @@ -72,9 +73,7 @@ CONFIG_DRM=y CONFIG_DRM_FBDEV_OVERALLOC=200 CONFIG_DRM_PANEL_SIMPLE=y CONFIG_DRM_INGENIC=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 @@ -170,9 +169,9 @@ CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_STRIP_ASM_SYMS=y CONFIG_READABLE_ASM=y +CONFIG_KGDB=y CONFIG_DEBUG_KMEMLEAK=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_PANIC_ON_OOPS=y # CONFIG_FTRACE is not set -CONFIG_KGDB=y diff --git a/arch/mips/configs/rs90_defconfig b/arch/mips/configs/rs90_defconfig index de6752051ecc..dfbb9fed9a42 100644 --- a/arch/mips/configs/rs90_defconfig +++ b/arch/mips/configs/rs90_defconfig @@ -19,7 +19,7 @@ CONFIG_EMBEDDED=y # CONFIG_PERF_EVENTS is not set CONFIG_SLAB=y CONFIG_PROFILING=y -CONFIG_MACH_INGENIC=y +CONFIG_MACH_INGENIC_SOC=y CONFIG_JZ4740_RS90=y CONFIG_PAGE_SIZE_16KB=y CONFIG_HZ_100=y @@ -80,8 +80,8 @@ CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set CONFIG_LEGACY_PTY_COUNT=2 -# CONFIG_DEVMEM is not set # CONFIG_HW_RANDOM is not set +# CONFIG_DEVMEM is not set # CONFIG_I2C_COMPAT is not set # CONFIG_I2C_HELPER_AUTO is not set CONFIG_POWER_SUPPLY=y diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c index 5073d2ed78bb..44490c30d63b 100644 --- a/arch/mips/dec/prom/memory.c +++ b/arch/mips/dec/prom/memory.c @@ -12,7 +12,6 @@ #include <linux/types.h> #include <asm/addrspace.h> -#include <asm/bootinfo.h> #include <asm/dec/machtype.h> #include <asm/dec/prom.h> #include <asm/page.h> @@ -28,7 +27,7 @@ volatile unsigned long mem_err; /* So we know an error occurred */ #define CHUNK_SIZE 0x400000 -static inline void pmax_setup_memory_region(void) +static __init void pmax_setup_memory_region(void) { volatile unsigned char *memory_page, dummy; char old_handler[0x80]; @@ -50,15 +49,14 @@ static inline void pmax_setup_memory_region(void) } memcpy((void *)(CKSEG0 + 0x80), &old_handler, 0x80); - add_memory_region(0, (unsigned long)memory_page - CKSEG1 - CHUNK_SIZE, - BOOT_MEM_RAM); + memblock_add(0, (unsigned long)memory_page - CKSEG1 - CHUNK_SIZE); } /* * Use the REX prom calls to get hold of the memory bitmap, and thence * determine memory size. */ -static inline void rex_setup_memory_region(void) +static __init void rex_setup_memory_region(void) { int i, bitmap_size; unsigned long mem_start = 0, mem_size = 0; @@ -76,13 +74,13 @@ static inline void rex_setup_memory_region(void) else if (!mem_size) mem_start += (8 * bm->pagesize); else { - add_memory_region(mem_start, mem_size, BOOT_MEM_RAM); + memblock_add(mem_start, mem_size); mem_start += mem_size + (8 * bm->pagesize); mem_size = 0; } } if (mem_size) - add_memory_region(mem_start, mem_size, BOOT_MEM_RAM); + memblock_add(mem_start, mem_size); } void __init prom_meminit(u32 magic) diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c index d4e868b828e5..eaad0ed4b523 100644 --- a/arch/mips/dec/setup.c +++ b/arch/mips/dec/setup.c @@ -6,7 +6,7 @@ * for more details. * * Copyright (C) 1998 Harald Koerfgen - * Copyright (C) 2000, 2001, 2002, 2003, 2005 Maciej W. Rozycki + * Copyright (C) 2000, 2001, 2002, 2003, 2005, 2020 Maciej W. Rozycki */ #include <linux/console.h> #include <linux/export.h> @@ -15,6 +15,7 @@ #include <linux/ioport.h> #include <linux/irq.h> #include <linux/irqnr.h> +#include <linux/memblock.h> #include <linux/param.h> #include <linux/percpu-defs.h> #include <linux/sched.h> @@ -22,6 +23,7 @@ #include <linux/types.h> #include <linux/pm.h> +#include <asm/addrspace.h> #include <asm/bootinfo.h> #include <asm/cpu.h> #include <asm/cpu-features.h> @@ -29,7 +31,9 @@ #include <asm/irq.h> #include <asm/irq_cpu.h> #include <asm/mipsregs.h> +#include <asm/page.h> #include <asm/reboot.h> +#include <asm/sections.h> #include <asm/time.h> #include <asm/traps.h> #include <asm/wbflush.h> @@ -146,6 +150,9 @@ void __init plat_mem_setup(void) ioport_resource.start = ~0UL; ioport_resource.end = 0UL; + + /* Stay away from the firmware working memory area for now. */ + memblock_reserve(PHYS_OFFSET, __pa_symbol(&_text) - PHYS_OFFSET); } /* diff --git a/arch/mips/fw/arc/memory.c b/arch/mips/fw/arc/memory.c index da0712ad85f5..37625ae5e35d 100644 --- a/arch/mips/fw/arc/memory.c +++ b/arch/mips/fw/arc/memory.c @@ -68,20 +68,24 @@ static char *arc_mtypes[8] = { : arc_mtypes[a.arc] #endif +enum { + mem_free, mem_prom_used, mem_reserved +}; + static inline int memtype_classify_arcs(union linux_memtypes type) { switch (type.arcs) { case arcs_fcontig: case arcs_free: - return BOOT_MEM_RAM; + return mem_free; case arcs_atmp: - return BOOT_MEM_ROM_DATA; + return mem_prom_used; case arcs_eblock: case arcs_rvpage: case arcs_bmem: case arcs_prog: case arcs_aperm: - return BOOT_MEM_RESERVED; + return mem_reserved; default: BUG(); } @@ -93,15 +97,15 @@ static inline int memtype_classify_arc(union linux_memtypes type) switch (type.arc) { case arc_free: case arc_fcontig: - return BOOT_MEM_RAM; + return mem_free; case arc_atmp: - return BOOT_MEM_ROM_DATA; + return mem_prom_used; case arc_eblock: case arc_rvpage: case arc_bmem: case arc_prog: case arc_aperm: - return BOOT_MEM_RESERVED; + return mem_reserved; default: BUG(); } @@ -143,9 +147,17 @@ void __weak __init prom_meminit(void) size = p->pages << ARC_PAGE_SHIFT; type = prom_memtype_classify(p->type); - add_memory_region(base, size, type); + /* ignore mirrored RAM on IP28/IP30 */ + if (base < PHYS_OFFSET) + continue; + + memblock_add(base, size); + + if (type == mem_reserved) + memblock_reserve(base, size); - if (type == BOOT_MEM_ROM_DATA) { + if (type == mem_prom_used) { + memblock_reserve(base, size); if (nr_prom_mem >= 5) { pr_err("Too many ROM DATA regions"); continue; diff --git a/arch/mips/fw/sni/sniprom.c b/arch/mips/fw/sni/sniprom.c index 80112f2298b6..8f6730376a42 100644 --- a/arch/mips/fw/sni/sniprom.c +++ b/arch/mips/fw/sni/sniprom.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/init.h> +#include <linux/memblock.h> #include <linux/string.h> #include <linux/console.h> @@ -131,8 +132,7 @@ static void __init sni_mem_init(void) } pr_debug("Bank%d: %08x @ %08x\n", i, memconf[i].size, memconf[i].base); - add_memory_region(memconf[i].base, memconf[i].size, - BOOT_MEM_RAM); + memblock_add(memconf[i].base, memconf[i].size); } } diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig index fd6019802657..55d9aed7ced9 100644 --- a/arch/mips/generic/Kconfig +++ b/arch/mips/generic/Kconfig @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -if MIPS_GENERIC +if MIPS_GENERIC_KERNEL config LEGACY_BOARDS bool @@ -73,6 +73,12 @@ config FIT_IMAGE_FDT_OCELOT from Microsemi in the FIT kernel image. This requires u-boot on the platform. +config BOARD_INGENIC + bool "Support boards based on Ingenic SoCs" + select MACH_INGENIC_GENERIC + help + Enable support for boards based on Ingenic SoCs. + config VIRT_BOARD_RANCHU bool "Support Ranchu platform for Android emulator" help diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile index 2384a6b09e4c..e37a59bae0a6 100644 --- a/arch/mips/generic/Makefile +++ b/arch/mips/generic/Makefile @@ -11,4 +11,5 @@ obj-y += proc.o obj-$(CONFIG_YAMON_DT_SHIM) += yamon-dt.o obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o obj-$(CONFIG_LEGACY_BOARD_OCELOT) += board-ocelot.o +obj-$(CONFIG_MACH_INGENIC) += board-ingenic.o obj-$(CONFIG_VIRT_BOARD_RANCHU) += board-ranchu.o diff --git a/arch/mips/generic/Platform b/arch/mips/generic/Platform index 53c33cb72974..f8ef2f9d107e 100644 --- a/arch/mips/generic/Platform +++ b/arch/mips/generic/Platform @@ -8,8 +8,12 @@ # option) any later version. # +# Note: order matters, keep the asm/mach-generic include last. +cflags-$(CONFIG_MACH_INGENIC_SOC) += -I$(srctree)/arch/mips/include/asm/mach-ingenic cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic + load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000 +zload-$(CONFIG_MIPS_GENERIC) += 0xffffffff81000000 all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb its-y := vmlinux.its.S diff --git a/arch/mips/generic/board-ingenic.c b/arch/mips/generic/board-ingenic.c new file mode 100644 index 000000000000..0cec0bea13d6 --- /dev/null +++ b/arch/mips/generic/board-ingenic.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Support for Ingenic SoCs + * + * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> + * Copyright (C) 2011, Maarten ter Huurne <maarten@treewalker.org> + * Copyright (C) 2020 Paul Cercueil <paul@crapouillou.net> + */ + +#include <linux/of_address.h> +#include <linux/of_fdt.h> +#include <linux/pm.h> +#include <linux/sizes.h> +#include <linux/suspend.h> +#include <linux/types.h> + +#include <asm/bootinfo.h> +#include <asm/machine.h> +#include <asm/reboot.h> + +static __init char *ingenic_get_system_type(unsigned long machtype) +{ + switch (machtype) { + case MACH_INGENIC_X2000E: + return "X2000E"; + case MACH_INGENIC_X2000: + return "X2000"; + case MACH_INGENIC_X1830: + return "X1830"; + case MACH_INGENIC_X1000E: + return "X1000E"; + case MACH_INGENIC_X1000: + return "X1000"; + case MACH_INGENIC_JZ4780: + return "JZ4780"; + case MACH_INGENIC_JZ4775: + return "JZ4775"; + case MACH_INGENIC_JZ4770: + return "JZ4770"; + case MACH_INGENIC_JZ4725B: + return "JZ4725B"; + default: + return "JZ4740"; + } +} + +static __init const void *ingenic_fixup_fdt(const void *fdt, const void *match_data) +{ + /* + * Old devicetree files for the qi,lb60 board did not have a /memory + * node. Hardcode the memory info here. + */ + if (!fdt_node_check_compatible(fdt, 0, "qi,lb60") && + fdt_path_offset(fdt, "/memory") < 0) + early_init_dt_add_memory_arch(0, SZ_32M); + + mips_machtype = (unsigned long)match_data; + system_type = ingenic_get_system_type(mips_machtype); + + return fdt; +} + +static const struct of_device_id ingenic_of_match[] __initconst = { + { .compatible = "ingenic,jz4740", .data = (void *)MACH_INGENIC_JZ4740 }, + { .compatible = "ingenic,jz4725b", .data = (void *)MACH_INGENIC_JZ4725B }, + { .compatible = "ingenic,jz4770", .data = (void *)MACH_INGENIC_JZ4770 }, + { .compatible = "ingenic,jz4775", .data = (void *)MACH_INGENIC_JZ4775 }, + { .compatible = "ingenic,jz4780", .data = (void *)MACH_INGENIC_JZ4780 }, + { .compatible = "ingenic,x1000", .data = (void *)MACH_INGENIC_X1000 }, + { .compatible = "ingenic,x1000e", .data = (void *)MACH_INGENIC_X1000E }, + { .compatible = "ingenic,x1830", .data = (void *)MACH_INGENIC_X1830 }, + { .compatible = "ingenic,x2000", .data = (void *)MACH_INGENIC_X2000 }, + { .compatible = "ingenic,x2000e", .data = (void *)MACH_INGENIC_X2000E }, + {} +}; + +MIPS_MACHINE(ingenic) = { + .matches = ingenic_of_match, + .fixup_fdt = ingenic_fixup_fdt, +}; + +static void ingenic_wait_instr(void) +{ + __asm__(".set push;\n" + ".set mips3;\n" + "wait;\n" + ".set pop;\n" + ); +} + +static void ingenic_halt(void) +{ + for (;;) + ingenic_wait_instr(); +} + +static int __maybe_unused ingenic_pm_enter(suspend_state_t state) +{ + ingenic_wait_instr(); + + return 0; +} + +static const struct platform_suspend_ops ingenic_pm_ops __maybe_unused = { + .valid = suspend_valid_only_mem, + .enter = ingenic_pm_enter, +}; + +static int __init ingenic_pm_init(void) +{ + if (boot_cpu_type() == CPU_XBURST) { + if (IS_ENABLED(CONFIG_PM_SLEEP)) + suspend_set_ops(&ingenic_pm_ops); + _machine_halt = ingenic_halt; + } + + return 0; + +} +late_initcall(ingenic_pm_init); diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c index 805d0135a9f4..66a19337d2ab 100644 --- a/arch/mips/generic/init.c +++ b/arch/mips/generic/init.c @@ -39,12 +39,11 @@ void __init *plat_get_fdt(void) /* Already set up */ return (void *)fdt; - if ((fw_arg0 == -2) && !fdt_check_header((void *)fw_passed_dtb)) { + if (fw_passed_dtb && !fdt_check_header((void *)fw_passed_dtb)) { /* - * We booted using the UHI boot protocol, so we have been - * provided with the appropriate device tree for the board. - * Make use of it & search for any machine struct based upon - * the root compatible string. + * We have been provided with the appropriate device tree for + * the board. Make use of it & search for any machine struct + * based upon the root compatible string. */ fdt = (void *)fw_passed_dtb; @@ -106,7 +105,7 @@ void __init plat_mem_setup(void) if (mach && mach->fixup_fdt) fdt = mach->fixup_fdt(fdt, mach_match_data); - strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); + fw_init_cmdline(); __dt_setup_arch((void *)fdt); } diff --git a/arch/mips/generic/proc.c b/arch/mips/generic/proc.c index 4c992809cc3f..cce2fde219a3 100644 --- a/arch/mips/generic/proc.c +++ b/arch/mips/generic/proc.c @@ -8,11 +8,16 @@ #include <asm/bootinfo.h> +char *system_type; + const char *get_system_type(void) { const char *str; int err; + if (system_type) + return system_type; + err = of_property_read_string(of_root, "model", &str); if (!err) return str; diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index 147c9327ce04..aa03b1237155 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h @@ -79,8 +79,10 @@ enum ingenic_machine_type { MACH_INGENIC_JZ4775, MACH_INGENIC_JZ4780, MACH_INGENIC_X1000, + MACH_INGENIC_X1000E, MACH_INGENIC_X1830, MACH_INGENIC_X2000, + MACH_INGENIC_X2000E, }; extern char *system_type; @@ -88,13 +90,6 @@ const char *get_system_type(void); extern unsigned long mips_machtype; -#define BOOT_MEM_RAM 1 -#define BOOT_MEM_ROM_DATA 2 -#define BOOT_MEM_RESERVED 3 -#define BOOT_MEM_INIT_RAM 4 -#define BOOT_MEM_NOMAP 5 - -extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type); extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max); extern void prom_init(void); diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h index 8b14c2706aa5..29187e12b861 100644 --- a/arch/mips/include/asm/cache.h +++ b/arch/mips/include/asm/cache.h @@ -14,6 +14,6 @@ #define L1_CACHE_SHIFT CONFIG_MIPS_L1_CACHE_SHIFT #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) -#define __read_mostly __attribute__((__section__(".data..read_mostly"))) +#define __read_mostly __section(".data..read_mostly") #endif /* _ASM_CACHE_H */ diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h index 181f7d14efb9..5f80c28f5253 100644 --- a/arch/mips/include/asm/checksum.h +++ b/arch/mips/include/asm/checksum.h @@ -34,42 +34,17 @@ */ __wsum csum_partial(const void *buff, int len, __wsum sum); -__wsum __csum_partial_copy_kernel(const void *src, void *dst, - int len, __wsum sum, int *err_ptr); - -__wsum __csum_partial_copy_from_user(const void *src, void *dst, - int len, __wsum sum, int *err_ptr); -__wsum __csum_partial_copy_to_user(const void *src, void *dst, - int len, __wsum sum, int *err_ptr); -/* - * this is a new version of the above that records errors it finds in *errp, - * but continues and zeros the rest of the buffer. - */ -static inline -__wsum csum_partial_copy_from_user(const void __user *src, void *dst, int len, - __wsum sum, int *err_ptr) -{ - might_fault(); - if (uaccess_kernel()) - return __csum_partial_copy_kernel((__force void *)src, dst, - len, sum, err_ptr); - else - return __csum_partial_copy_from_user((__force void *)src, dst, - len, sum, err_ptr); -} +__wsum __csum_partial_copy_from_user(const void __user *src, void *dst, int len); +__wsum __csum_partial_copy_to_user(const void *src, void __user *dst, int len); #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER static inline -__wsum csum_and_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) +__wsum csum_and_copy_from_user(const void __user *src, void *dst, int len) { - if (access_ok(src, len)) - return csum_partial_copy_from_user(src, dst, len, sum, - err_ptr); - if (len) - *err_ptr = -EFAULT; - - return sum; + might_fault(); + if (!access_ok(src, len)) + return 0; + return __csum_partial_copy_from_user(src, dst, len); } /* @@ -77,33 +52,24 @@ __wsum csum_and_copy_from_user(const void __user *src, void *dst, */ #define HAVE_CSUM_COPY_USER static inline -__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len, - __wsum sum, int *err_ptr) +__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len) { might_fault(); - if (access_ok(dst, len)) { - if (uaccess_kernel()) - return __csum_partial_copy_kernel(src, - (__force void *)dst, - len, sum, err_ptr); - else - return __csum_partial_copy_to_user(src, - (__force void *)dst, - len, sum, err_ptr); - } - if (len) - *err_ptr = -EFAULT; - - return (__force __wsum)-1; /* invalid checksum */ + if (!access_ok(dst, len)) + return 0; + return __csum_partial_copy_to_user(src, dst, len); } /* * the same as csum_partial, but copies from user space (but on MIPS * we have just one address space, so this is identical to the above) */ -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum); -#define csum_partial_copy_nocheck csum_partial_copy_nocheck +#define _HAVE_ARCH_CSUM_AND_COPY +__wsum __csum_partial_copy_nocheck(const void *src, void *dst, int len); +static inline __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len) +{ + return __csum_partial_copy_nocheck(src, dst, len); +} /* * Fold a partial checksum without adding pseudo headers diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h index 255afcdd79c9..65975712a22d 100644 --- a/arch/mips/include/asm/compat.h +++ b/arch/mips/include/asm/compat.h @@ -26,8 +26,6 @@ typedef s32 compat_caddr_t; typedef struct { s32 val[2]; } compat_fsid_t; -typedef s64 compat_s64; -typedef u64 compat_u64; struct compat_stat { compat_dev_t st_dev; diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 78cf7e300f12..f2e216eef7da 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -171,9 +171,6 @@ #ifndef cpu_has_llsc #define cpu_has_llsc __isa_ge_or_opt(1, MIPS_CPU_LLSC) #endif -#ifndef cpu_has_bp_ghist -#define cpu_has_bp_ghist __opt(MIPS_CPU_BP_GHIST) -#endif #ifndef kernel_uses_llsc #define kernel_uses_llsc cpu_has_llsc #endif diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h index 75a7a382da09..3288cef4b168 100644 --- a/arch/mips/include/asm/cpu-type.h +++ b/arch/mips/include/asm/cpu-type.h @@ -47,6 +47,7 @@ static inline int __pure __get_cpu_type(const int cpu_type) case CPU_34K: case CPU_1004K: case CPU_74K: + case CPU_1074K: case CPU_M14KC: case CPU_M14KEC: case CPU_INTERAPTIV: diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 388a82f28a87..c9222cc2244f 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -398,7 +398,6 @@ enum cpu_type_enum { #define MIPS_CPU_RW_LLB BIT_ULL(32) /* LLADDR/LLB writes are allowed */ #define MIPS_CPU_LPA BIT_ULL(33) /* CPU supports Large Physical Addressing */ #define MIPS_CPU_CDMM BIT_ULL(34) /* CPU has Common Device Memory Map */ -#define MIPS_CPU_BP_GHIST BIT_ULL(35) /* R12K+ Branch Prediction Global History */ #define MIPS_CPU_SP BIT_ULL(36) /* Small (1KB) page support */ #define MIPS_CPU_FTLB BIT_ULL(37) /* CPU has Fixed-page-size TLB */ #define MIPS_CPU_NAN_LEGACY BIT_ULL(38) /* Legacy NaN implemented */ diff --git a/arch/mips/include/asm/dma-direct.h b/arch/mips/include/asm/dma-direct.h index 14e352651ce9..9a640118316c 100644 --- a/arch/mips/include/asm/dma-direct.h +++ b/arch/mips/include/asm/dma-direct.h @@ -2,7 +2,7 @@ #ifndef _MIPS_DMA_DIRECT_H #define _MIPS_DMA_DIRECT_H 1 -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr); -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr); +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr); +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr); #endif /* _MIPS_DMA_DIRECT_H */ diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h index 2bf8f6014579..d85248404c52 100644 --- a/arch/mips/include/asm/futex.h +++ b/arch/mips/include/asm/futex.h @@ -21,7 +21,7 @@ #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ { \ - if (cpu_has_llsc && R10000_LLSC_WAR) { \ + if (cpu_has_llsc && IS_ENABLED(CONFIG_WAR_R10000_LLSC)) { \ __asm__ __volatile__( \ " .set push \n" \ " .set noat \n" \ @@ -133,7 +133,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, if (!access_ok(uaddr, sizeof(u32))) return -EFAULT; - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (cpu_has_llsc && IS_ENABLED(CONFIG_WAR_R10000_LLSC)) { __asm__ __volatile__( "# futex_atomic_cmpxchg_inatomic \n" " .set push \n" diff --git a/arch/mips/include/asm/idle.h b/arch/mips/include/asm/idle.h index 655a6dbc861a..0992cad9c632 100644 --- a/arch/mips/include/asm/idle.h +++ b/arch/mips/include/asm/idle.h @@ -15,6 +15,8 @@ static inline int using_rollback_handler(void) return cpu_wait == r4k_wait; } +extern void __init check_wait(void); + extern int mips_cpuidle_wait_enter(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); diff --git a/arch/mips/include/asm/jazzdma.h b/arch/mips/include/asm/jazzdma.h index d13f940022d5..c831da7fa898 100644 --- a/arch/mips/include/asm/jazzdma.h +++ b/arch/mips/include/asm/jazzdma.h @@ -10,8 +10,6 @@ */ extern unsigned long vdma_alloc(unsigned long paddr, unsigned long size); extern int vdma_free(unsigned long laddr); -extern int vdma_remap(unsigned long laddr, unsigned long paddr, - unsigned long size); extern unsigned long vdma_phys2log(unsigned long paddr); extern unsigned long vdma_log2phys(unsigned long laddr); extern void vdma_stats(void); /* for debugging only */ diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index 825d337a505a..24f3d0f9996b 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -341,7 +341,7 @@ struct kvm_mips_tlb { #define KVM_MIPS_GUEST_TLB_SIZE 64 struct kvm_vcpu_arch { void *guest_ebase; - int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu); + int (*vcpu_run)(struct kvm_vcpu *vcpu); /* Host registers preserved across guest mode execution */ unsigned long host_stack; @@ -852,7 +852,7 @@ int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks); /* Debug: dump vcpu state */ int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu); -extern int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu); +extern int kvm_mips_handle_exit(struct kvm_vcpu *vcpu); /* Building of entry/exception code */ int kvm_mips_entry_setup(void); diff --git a/arch/mips/include/asm/llsc.h b/arch/mips/include/asm/llsc.h index c49738bc3bda..ec09fe5d6d6c 100644 --- a/arch/mips/include/asm/llsc.h +++ b/arch/mips/include/asm/llsc.h @@ -28,7 +28,7 @@ * works around a bug present in R10000 CPUs prior to revision 3.0 that could * cause ll-sc sequences to execute non-atomically. */ -#if R10000_LLSC_WAR +#ifdef CONFIG_WAR_R10000_LLSC # define __SC_BEQZ "beqzl " #elif MIPS_ISA_REV >= 6 # define __SC_BEQZ "beqzc " diff --git a/arch/mips/include/asm/local.h b/arch/mips/include/asm/local.h index fef0fda8f82f..ecda7295ddcd 100644 --- a/arch/mips/include/asm/local.h +++ b/arch/mips/include/asm/local.h @@ -31,7 +31,7 @@ static __inline__ long local_add_return(long i, local_t * l) { unsigned long result; - if (kernel_uses_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && IS_ENABLED(CONFIG_WAR_R10000_LLSC)) { unsigned long temp; __asm__ __volatile__( @@ -80,7 +80,7 @@ static __inline__ long local_sub_return(long i, local_t * l) { unsigned long result; - if (kernel_uses_llsc && R10000_LLSC_WAR) { + if (kernel_uses_llsc && IS_ENABLED(CONFIG_WAR_R10000_LLSC)) { unsigned long temp; __asm__ __volatile__( diff --git a/arch/mips/include/asm/m48t37.h b/arch/mips/include/asm/m48t37.h deleted file mode 100644 index 3687a02e692b..000000000000 --- a/arch/mips/include/asm/m48t37.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Registers for the SGS-Thomson M48T37 Timekeeper RAM chip - */ -#ifndef _ASM_M48T37_H -#define _ASM_M48T37_H - -#include <linux/spinlock.h> - -extern spinlock_t rtc_lock; - -struct m48t37_rtc { - volatile u8 pad[0x7ff0]; /* NVRAM */ - volatile u8 flags; - volatile u8 century; - volatile u8 alarm_sec; - volatile u8 alarm_min; - volatile u8 alarm_hour; - volatile u8 alarm_data; - volatile u8 interrupts; - volatile u8 watchdog; - volatile u8 control; - volatile u8 sec; - volatile u8 min; - volatile u8 hour; - volatile u8 day; - volatile u8 date; - volatile u8 month; - volatile u8 year; -}; - -#define M48T37_RTC_SET 0x80 -#define M48T37_RTC_STOPPED 0x80 -#define M48T37_RTC_READ 0x40 - -#endif /* _ASM_M48T37_H */ diff --git a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h index ecfbb5aeada3..e6e527224a15 100644 --- a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h @@ -39,7 +39,6 @@ #define cpu_has_guestctl2 0 #define cpu_has_guestid 0 #define cpu_has_drg 0 -#define cpu_has_bp_ghist 0 #define cpu_has_mips16 0 #define cpu_has_mips16e2 0 #define cpu_has_mdmx 0 diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1300.h b/arch/mips/include/asm/mach-au1x00/gpio-au1300.h index d25846a1291f..d16add7ba49d 100644 --- a/arch/mips/include/asm/mach-au1x00/gpio-au1300.h +++ b/arch/mips/include/asm/mach-au1x00/gpio-au1300.h @@ -120,141 +120,4 @@ static inline int au1300_gpio_getinitlvl(unsigned int gpio) return (v >> gpio) & 1; } -/**********************************************************************/ - -/* Linux gpio framework integration. -* -* 4 use cases of Alchemy GPIOS: -*(1) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=y: -* Board must register gpiochips. -*(2) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=n: -* A gpiochip for the 75 GPIOs is registered. -* -*(3) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=y: -* the boards' gpio.h must provide the linux gpio wrapper functions, -* -*(4) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=n: -* inlinable gpio functions are provided which enable access to the -* Au1300 gpios only by using the numbers straight out of the data- -* sheets. - -* Cases 1 and 3 are intended for boards which want to provide their own -* GPIO namespace and -operations (i.e. for example you have 8 GPIOs -* which are in part provided by spare Au1300 GPIO pins and in part by -* an external FPGA but you still want them to be accessible in linux -* as gpio0-7. The board can of course use the alchemy_gpioX_* functions -* as required). -*/ - -#ifndef CONFIG_GPIOLIB - -#ifdef CONFIG_ALCHEMY_GPIOINT_AU1300 - -#ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (4) */ - -static inline int gpio_direction_input(unsigned int gpio) -{ - return au1300_gpio_direction_input(gpio); -} - -static inline int gpio_direction_output(unsigned int gpio, int v) -{ - return au1300_gpio_direction_output(gpio, v); -} - -static inline int gpio_get_value(unsigned int gpio) -{ - return au1300_gpio_get_value(gpio); -} - -static inline void gpio_set_value(unsigned int gpio, int v) -{ - au1300_gpio_set_value(gpio, v); -} - -static inline int gpio_get_value_cansleep(unsigned gpio) -{ - return gpio_get_value(gpio); -} - -static inline void gpio_set_value_cansleep(unsigned gpio, int value) -{ - gpio_set_value(gpio, value); -} - -static inline int gpio_is_valid(unsigned int gpio) -{ - return au1300_gpio_is_valid(gpio); -} - -static inline int gpio_cansleep(unsigned int gpio) -{ - return au1300_gpio_cansleep(gpio); -} - -static inline int gpio_to_irq(unsigned int gpio) -{ - return au1300_gpio_to_irq(gpio); -} - -static inline int irq_to_gpio(unsigned int irq) -{ - return au1300_irq_to_gpio(irq); -} - -static inline int gpio_request(unsigned int gpio, const char *label) -{ - return 0; -} - -static inline int gpio_request_one(unsigned gpio, - unsigned long flags, const char *label) -{ - return 0; -} - -static inline int gpio_request_array(struct gpio *array, size_t num) -{ - return 0; -} - -static inline void gpio_free(unsigned gpio) -{ -} - -static inline void gpio_free_array(struct gpio *array, size_t num) -{ -} - -static inline int gpio_set_debounce(unsigned gpio, unsigned debounce) -{ - return -ENOSYS; -} - -static inline void gpio_unexport(unsigned gpio) -{ -} - -static inline int gpio_export(unsigned gpio, bool direction_may_change) -{ - return -ENOSYS; -} - -static inline int gpio_sysfs_set_active_low(unsigned gpio, int value) -{ - return -ENOSYS; -} - -static inline int gpio_export_link(struct device *dev, const char *name, - unsigned gpio) -{ - return -ENOSYS; -} - -#endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */ - -#endif /* CONFIG_ALCHEMY_GPIOINT_AU1300 */ - -#endif /* CONFIG GPIOLIB */ - #endif /* _GPIO_AU1300_H_ */ diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h index d7f1ef246d5c..93817bfb7fb2 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h @@ -10,6 +10,7 @@ #include <linux/bcma/bcma.h> #include <linux/bcma/bcma_soc.h> #include <linux/bcm47xx_nvram.h> +#include <linux/bcm47xx_sprom.h> enum bcm47xx_bus_type { #ifdef CONFIG_BCM47XX_SSB @@ -32,9 +33,6 @@ union bcm47xx_bus { extern union bcm47xx_bus bcm47xx_bus; extern enum bcm47xx_bus_type bcm47xx_bus_type; -void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix, - bool fallback); - void bcm47xx_set_system_type(u16 chip_id); #endif /* __ASM_BCM47XX_H */ diff --git a/arch/mips/include/asm/mach-cavium-octeon/war.h b/arch/mips/include/asm/mach-cavium-octeon/war.h deleted file mode 100644 index 2421411b7636..000000000000 --- a/arch/mips/include/asm/mach-cavium-octeon/war.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - * Copyright (C) 2008 Cavium Networks <support@caviumnetworks.com> - */ -#ifndef __ASM_MIPS_MACH_CAVIUM_OCTEON_WAR_H -#define __ASM_MIPS_MACH_CAVIUM_OCTEON_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 0 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#define CAVIUM_OCTEON_DCACHE_PREFETCH_WAR \ - OCTEON_IS_MODEL(OCTEON_CN6XXX) - -#endif /* __ASM_MIPS_MACH_CAVIUM_OCTEON_WAR_H */ diff --git a/arch/mips/include/asm/mach-generic/irq.h b/arch/mips/include/asm/mach-generic/irq.h index 72ac2c202c55..079889ced4f3 100644 --- a/arch/mips/include/asm/mach-generic/irq.h +++ b/arch/mips/include/asm/mach-generic/irq.h @@ -9,7 +9,7 @@ #define __ASM_MACH_GENERIC_IRQ_H #ifndef NR_IRQS -#define NR_IRQS 128 +#define NR_IRQS 256 #endif #ifdef CONFIG_I8259 diff --git a/arch/mips/include/asm/mach-generic/war.h b/arch/mips/include/asm/mach-generic/war.h deleted file mode 100644 index f0f4a35d0870..000000000000 --- a/arch/mips/include/asm/mach-generic/war.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MACH_GENERIC_WAR_H -#define __ASM_MACH_GENERIC_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 0 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MACH_GENERIC_WAR_H */ diff --git a/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ingenic/cpu-feature-overrides.h index 7c5e576f9d96..7c5e576f9d96 100644 --- a/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-ingenic/cpu-feature-overrides.h diff --git a/arch/mips/include/asm/mach-ip22/war.h b/arch/mips/include/asm/mach-ip22/war.h deleted file mode 100644 index b48eb4ac362d..000000000000 --- a/arch/mips/include/asm/mach-ip22/war.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MIPS_MACH_IP22_WAR_H -#define __ASM_MIPS_MACH_IP22_WAR_H - -/* - * R4600 CPU modules for the Indy come with both V1.7 and V2.0 processors. - */ - -#define R4600_V1_INDEX_ICACHEOP_WAR 1 -#define R4600_V1_HIT_CACHEOP_WAR 1 -#define R4600_V2_HIT_CACHEOP_WAR 1 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 0 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_IP22_WAR_H */ diff --git a/arch/mips/include/asm/mach-ip27/kmalloc.h b/arch/mips/include/asm/mach-ip27/kmalloc.h deleted file mode 100644 index 82c23ce2afa7..000000000000 --- a/arch/mips/include/asm/mach-ip27/kmalloc.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __ASM_MACH_IP27_KMALLOC_H -#define __ASM_MACH_IP27_KMALLOC_H - -/* - * All happy, no need to define ARCH_DMA_MINALIGN - */ - -#endif /* __ASM_MACH_IP27_KMALLOC_H */ diff --git a/arch/mips/include/asm/mach-ip27/war.h b/arch/mips/include/asm/mach-ip27/war.h deleted file mode 100644 index ef3efce0094a..000000000000 --- a/arch/mips/include/asm/mach-ip27/war.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MIPS_MACH_IP27_WAR_H -#define __ASM_MIPS_MACH_IP27_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 0 -#define R10000_LLSC_WAR 1 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_IP27_WAR_H */ diff --git a/arch/mips/include/asm/mach-ip28/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ip28/cpu-feature-overrides.h index ba8b4e30b3e2..613bbc10c1f2 100644 --- a/arch/mips/include/asm/mach-ip28/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-ip28/cpu-feature-overrides.h @@ -25,7 +25,7 @@ #define cpu_has_mcheck 0 #define cpu_has_ejtag 0 -#define cpu_has_llsc 1 +#define cpu_has_llsc 0 #define cpu_has_vtag_icache 0 #define cpu_has_dc_aliases 0 /* see probe_pcache() */ #define cpu_has_ic_fills_f_dc 0 diff --git a/arch/mips/include/asm/mach-ip28/war.h b/arch/mips/include/asm/mach-ip28/war.h deleted file mode 100644 index 61cd67354829..000000000000 --- a/arch/mips/include/asm/mach-ip28/war.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MIPS_MACH_IP28_WAR_H -#define __ASM_MIPS_MACH_IP28_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 0 -#define R10000_LLSC_WAR 1 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_IP28_WAR_H */ diff --git a/arch/mips/include/asm/mach-ip30/irq.h b/arch/mips/include/asm/mach-ip30/irq.h deleted file mode 100644 index 27ba899c95be..000000000000 --- a/arch/mips/include/asm/mach-ip30/irq.h +++ /dev/null @@ -1,87 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * HEART IRQ defines - * - * Copyright (C) 2009 Johannes Dickgreber <tanzy@gmx.de> - * 2014-2016 Joshua Kinard <kumba@gentoo.org> - * - */ - -#ifndef __ASM_MACH_IP30_IRQ_H -#define __ASM_MACH_IP30_IRQ_H - -/* - * HEART has 64 hardware interrupts, but use 128 to leave room for a few - * software interrupts as well (such as the CPU timer interrupt. - */ -#define NR_IRQS 128 - -extern void __init ip30_install_ipi(void); - -/* - * HEART has 64 interrupt vectors available to it, subdivided into five - * priority levels. They are numbered 0 to 63. - */ -#define HEART_NUM_IRQS 64 - -/* - * These are the five interrupt priority levels and their corresponding - * CPU IPx interrupt pins. - * - * Level 4 - Error Interrupts. - * Level 3 - HEART timer interrupt. - * Level 2 - CPU IPI, CPU debug, power putton, general device interrupts. - * Level 1 - General device interrupts. - * Level 0 - General device GFX flow control interrupts. - */ -#define HEART_L4_INT_MASK 0xfff8000000000000ULL /* IP6 */ -#define HEART_L3_INT_MASK 0x0004000000000000ULL /* IP5 */ -#define HEART_L2_INT_MASK 0x0003ffff00000000ULL /* IP4 */ -#define HEART_L1_INT_MASK 0x00000000ffff0000ULL /* IP3 */ -#define HEART_L0_INT_MASK 0x000000000000ffffULL /* IP2 */ - -/* HEART L0 Interrupts (Low Priority) */ -#define HEART_L0_INT_GENERIC 0 -#define HEART_L0_INT_FLOW_CTRL_HWTR_0 1 -#define HEART_L0_INT_FLOW_CTRL_HWTR_1 2 - -/* HEART L2 Interrupts (High Priority) */ -#define HEART_L2_INT_RESCHED_CPU_0 46 -#define HEART_L2_INT_RESCHED_CPU_1 47 -#define HEART_L2_INT_CALL_CPU_0 48 -#define HEART_L2_INT_CALL_CPU_1 49 - -/* HEART L3 Interrupts (Compare/Counter Timer) */ -#define HEART_L3_INT_TIMER 50 - -/* HEART L4 Interrupts (Errors) */ -#define HEART_L4_INT_XWID_ERR_9 51 -#define HEART_L4_INT_XWID_ERR_A 52 -#define HEART_L4_INT_XWID_ERR_B 53 -#define HEART_L4_INT_XWID_ERR_C 54 -#define HEART_L4_INT_XWID_ERR_D 55 -#define HEART_L4_INT_XWID_ERR_E 56 -#define HEART_L4_INT_XWID_ERR_F 57 -#define HEART_L4_INT_XWID_ERR_XBOW 58 -#define HEART_L4_INT_CPU_BUS_ERR_0 59 -#define HEART_L4_INT_CPU_BUS_ERR_1 60 -#define HEART_L4_INT_CPU_BUS_ERR_2 61 -#define HEART_L4_INT_CPU_BUS_ERR_3 62 -#define HEART_L4_INT_HEART_EXCP 63 - -/* - * Power Switch is wired via BaseIO BRIDGE slot #6. - * - * ACFail is wired via BaseIO BRIDGE slot #7. - */ -#define IP30_POWER_IRQ HEART_L2_INT_POWER_BTN - -#include <asm/mach-generic/irq.h> - -#define IP30_HEART_L0_IRQ (MIPS_CPU_IRQ_BASE + 2) -#define IP30_HEART_L1_IRQ (MIPS_CPU_IRQ_BASE + 3) -#define IP30_HEART_L2_IRQ (MIPS_CPU_IRQ_BASE + 4) -#define IP30_HEART_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 5) -#define IP30_HEART_ERR_IRQ (MIPS_CPU_IRQ_BASE + 6) - -#endif /* __ASM_MACH_IP30_IRQ_H */ diff --git a/arch/mips/include/asm/mach-ip30/war.h b/arch/mips/include/asm/mach-ip30/war.h deleted file mode 100644 index a1fa0c1f5300..000000000000 --- a/arch/mips/include/asm/mach-ip30/war.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MIPS_MACH_IP30_WAR_H -#define __ASM_MIPS_MACH_IP30_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 0 -#ifdef CONFIG_CPU_R10000 -#define R10000_LLSC_WAR 1 -#else -#define R10000_LLSC_WAR 0 -#endif -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_IP30_WAR_H */ diff --git a/arch/mips/include/asm/mach-ip32/war.h b/arch/mips/include/asm/mach-ip32/war.h deleted file mode 100644 index e77b9d1b6c96..000000000000 --- a/arch/mips/include/asm/mach-ip32/war.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MIPS_MACH_IP32_WAR_H -#define __ASM_MIPS_MACH_IP32_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 1 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_IP32_WAR_H */ diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h deleted file mode 100644 index 27c543bd340f..000000000000 --- a/arch/mips/include/asm/mach-jz4740/irq.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> - * JZ4740 IRQ definitions - */ - -#ifndef __ASM_MACH_JZ4740_IRQ_H__ -#define __ASM_MACH_JZ4740_IRQ_H__ - -#define MIPS_CPU_IRQ_BASE 0 -#define NR_IRQS 256 - -#endif diff --git a/arch/mips/include/asm/mach-loongson2ef/mc146818rtc.h b/arch/mips/include/asm/mach-loongson2ef/mc146818rtc.h deleted file mode 100644 index 00d602629a55..000000000000 --- a/arch/mips/include/asm/mach-loongson2ef/mc146818rtc.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org) - * - * RTC routines for PC style attached Dallas chip. - */ -#ifndef __ASM_MACH_LOONGSON2EF_MC146818RTC_H -#define __ASM_MACH_LOONGSON2EF_MC146818RTC_H - -#include <linux/io.h> - -#define RTC_PORT(x) (0x70 + (x)) -#define RTC_IRQ 8 - -static inline unsigned char CMOS_READ(unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - return inb_p(RTC_PORT(1)); -} - -static inline void CMOS_WRITE(unsigned char data, unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - outb_p(data, RTC_PORT(1)); -} - -#define RTC_ALWAYS_BCD 0 - -#ifndef mc146818_decode_year -#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970) -#endif - -#endif /* __ASM_MACH_LOONGSON2EF_MC146818RTC_H */ diff --git a/arch/mips/include/asm/mach-loongson64/irq.h b/arch/mips/include/asm/mach-loongson64/irq.h index bf2480923154..98ea977cf0b8 100644 --- a/arch/mips/include/asm/mach-loongson64/irq.h +++ b/arch/mips/include/asm/mach-loongson64/irq.h @@ -5,7 +5,8 @@ /* cpu core interrupt numbers */ #define NR_IRQS_LEGACY 16 #define NR_MIPS_CPU_IRQS 8 -#define NR_IRQS (NR_IRQS_LEGACY + NR_MIPS_CPU_IRQS + 256) +#define NR_MAX_CHAINED_IRQS 40 /* Chained IRQs means those not directly used by devices */ +#define NR_IRQS (NR_IRQS_LEGACY + NR_MIPS_CPU_IRQS + NR_MAX_CHAINED_IRQS + 256) #define MIPS_CPU_IRQ_BASE NR_IRQS_LEGACY diff --git a/arch/mips/include/asm/mach-loongson64/mmzone.h b/arch/mips/include/asm/mach-loongson64/mmzone.h index 5eaca4fe3f92..ebb1deaa77b9 100644 --- a/arch/mips/include/asm/mach-loongson64/mmzone.h +++ b/arch/mips/include/asm/mach-loongson64/mmzone.h @@ -10,13 +10,9 @@ #define _ASM_MACH_LOONGSON64_MMZONE_H #define NODE_ADDRSPACE_SHIFT 44 -#define NODE0_ADDRSPACE_OFFSET 0x000000000000UL -#define NODE1_ADDRSPACE_OFFSET 0x100000000000UL -#define NODE2_ADDRSPACE_OFFSET 0x200000000000UL -#define NODE3_ADDRSPACE_OFFSET 0x300000000000UL #define pa_to_nid(addr) (((addr) & 0xf00000000000) >> NODE_ADDRSPACE_SHIFT) -#define nid_to_addrbase(nid) ((nid) << NODE_ADDRSPACE_SHIFT) +#define nid_to_addrbase(nid) ((unsigned long)(nid) << NODE_ADDRSPACE_SHIFT) extern struct pglist_data *__node_data[]; diff --git a/arch/mips/include/asm/mach-malta/malta-dtshim.h b/arch/mips/include/asm/mach-malta/malta-dtshim.h deleted file mode 100644 index 7c97b710121d..000000000000 --- a/arch/mips/include/asm/mach-malta/malta-dtshim.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2015 Imagination Technologies - * Author: Paul Burton <paul.burton@mips.com> - */ - -#ifndef __MIPS_MALTA_DTSHIM_H__ -#define __MIPS_MALTA_DTSHIM_H__ - -#include <linux/init.h> - -#ifdef CONFIG_MIPS_MALTA - -extern void __init *malta_dt_shim(void *fdt); - -#else /* !CONFIG_MIPS_MALTA */ - -static inline void *malta_dt_shim(void *fdt) -{ - return fdt; -} - -#endif /* !CONFIG_MIPS_MALTA */ - -#endif /* __MIPS_MALTA_DTSHIM_H__ */ diff --git a/arch/mips/include/asm/mach-malta/malta-pm.h b/arch/mips/include/asm/mach-malta/malta-pm.h deleted file mode 100644 index 2a5146d79313..000000000000 --- a/arch/mips/include/asm/mach-malta/malta-pm.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2014 Imagination Technologies - * Author: Paul Burton <paul.burton@mips.com> - */ - -#ifndef __ASM_MIPS_MACH_MALTA_PM_H__ -#define __ASM_MIPS_MACH_MALTA_PM_H__ - -#include <asm/mips-boards/piix4.h> - -#ifdef CONFIG_MIPS_MALTA_PM - -/** - * mips_pm_suspend - enter a suspend state - * @state: the state to enter, one of PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_* - * - * Enters a suspend state via the Malta's PIIX4. If the state to be entered - * is one which loses context (eg. SOFF) then this function will never - * return. - */ -extern int mips_pm_suspend(unsigned state); - -#else /* !CONFIG_MIPS_MALTA_PM */ - -static inline int mips_pm_suspend(unsigned state) -{ - return -EINVAL; -} - -#endif /* !CONFIG_MIPS_MALTA_PM */ - -#endif /* __ASM_MIPS_MACH_MALTA_PM_H__ */ diff --git a/arch/mips/include/asm/mach-malta/war.h b/arch/mips/include/asm/mach-malta/war.h deleted file mode 100644 index d62d2ffe515e..000000000000 --- a/arch/mips/include/asm/mach-malta/war.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MIPS_MACH_MIPS_WAR_H -#define __ASM_MIPS_MACH_MIPS_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 1 -#define MIPS_CACHE_SYNC_WAR 1 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 1 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_MIPS_WAR_H */ diff --git a/arch/mips/include/asm/mach-paravirt/cpu-feature-overrides.h b/arch/mips/include/asm/mach-paravirt/cpu-feature-overrides.h deleted file mode 100644 index 23ecf816daa7..000000000000 --- a/arch/mips/include/asm/mach-paravirt/cpu-feature-overrides.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2013 Cavium, Inc. - */ -#ifndef __ASM_MACH_PARAVIRT_CPU_FEATURE_OVERRIDES_H -#define __ASM_MACH_PARAVIRT_CPU_FEATURE_OVERRIDES_H - -#define cpu_has_4kex 1 -#define cpu_has_3k_cache 0 -#define cpu_has_tx39_cache 0 -#define cpu_has_counter 1 -#define cpu_has_llsc 1 -/* - * We Disable LL/SC on non SMP systems as it is faster to disable - * interrupts for atomic access than a LL/SC. - */ -#ifdef CONFIG_SMP -# define kernel_uses_llsc 1 -#else -# define kernel_uses_llsc 0 -#endif - -#ifdef CONFIG_CPU_CAVIUM_OCTEON -#define cpu_dcache_line_size() 128 -#define cpu_icache_line_size() 128 -#define cpu_has_octeon_cache 1 -#define cpu_has_4k_cache 0 -#else -#define cpu_has_4k_cache 1 -#endif - -#endif /* __ASM_MACH_PARAVIRT_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-paravirt/irq.h b/arch/mips/include/asm/mach-paravirt/irq.h deleted file mode 100644 index 9b4d35eca977..000000000000 --- a/arch/mips/include/asm/mach-paravirt/irq.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2013 Cavium, Inc. - */ -#ifndef __ASM_MACH_PARAVIRT_IRQ_H__ -#define __ASM_MACH_PARAVIRT_IRQ_H__ - -#define NR_IRQS 64 -#define MIPS_CPU_IRQ_BASE 1 - -#define MIPS_IRQ_PCIA (MIPS_CPU_IRQ_BASE + 8) - -#define MIPS_IRQ_MBOX0 (MIPS_CPU_IRQ_BASE + 32) -#define MIPS_IRQ_MBOX1 (MIPS_CPU_IRQ_BASE + 33) - -#endif /* __ASM_MACH_PARAVIRT_IRQ_H__ */ diff --git a/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h b/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h deleted file mode 100644 index c9f5769dfc8f..000000000000 --- a/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2013 Cavium, Inc - */ -#ifndef __ASM_MACH_PARAVIRT_KERNEL_ENTRY_H -#define __ASM_MACH_PARAVIRT_KERNEL_ENTRY_H - -#define CP0_EBASE $15, 1 - - .macro kernel_entry_setup -#ifdef CONFIG_SMP - mfc0 t0, CP0_EBASE - andi t0, t0, 0x3ff # CPUNum - beqz t0, 1f - # CPUs other than zero goto smp_bootstrap - j smp_bootstrap -#endif /* CONFIG_SMP */ - -1: - .endm - -/* - * Do SMP slave processor setup necessary before we can safely execute - * C code. - */ - .macro smp_slave_setup - mfc0 t0, CP0_EBASE - andi t0, t0, 0x3ff # CPUNum - slti t1, t0, NR_CPUS - bnez t1, 1f -2: - di - wait - b 2b # Unknown CPU, loop forever. -1: - PTR_LA t1, paravirt_smp_sp - PTR_SLL t0, PTR_SCALESHIFT - PTR_ADDU t1, t1, t0 -3: - PTR_L sp, 0(t1) - beqz sp, 3b # Spin until told to proceed. - - PTR_LA t1, paravirt_smp_gp - PTR_ADDU t1, t1, t0 - sync - PTR_L gp, 0(t1) - .endm - -#endif /* __ASM_MACH_PARAVIRT_KERNEL_ENTRY_H */ diff --git a/arch/mips/include/asm/mach-pnx833x/gpio.h b/arch/mips/include/asm/mach-pnx833x/gpio.h deleted file mode 100644 index 85b5b8e26118..000000000000 --- a/arch/mips/include/asm/mach-pnx833x/gpio.h +++ /dev/null @@ -1,159 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * gpio.h: GPIO Support for PNX833X. - * - * Copyright 2008 NXP Semiconductors - * Chris Steel <chris.steel@nxp.com> - * Daniel Laird <daniel.j.laird@nxp.com> - */ -#ifndef __ASM_MIPS_MACH_PNX833X_GPIO_H -#define __ASM_MIPS_MACH_PNX833X_GPIO_H - -/* BIG FAT WARNING: races danger! - No protections exist here. Current users are only early init code, - when locking is not needed because no concurrency yet exists there, - and GPIO IRQ dispatcher, which does locking. - However, if many uses will ever happen, proper locking will be needed - - including locking between different uses -*/ - -#include <asm/mach-pnx833x/pnx833x.h> - -#define SET_REG_BIT(reg, bit) do { (reg |= (1 << (bit))); } while (0) -#define CLEAR_REG_BIT(reg, bit) do { (reg &= ~(1 << (bit))); } while (0) - -/* Initialize GPIO to a known state */ -static inline void pnx833x_gpio_init(void) -{ - PNX833X_PIO_DIR = 0; - PNX833X_PIO_DIR2 = 0; - PNX833X_PIO_SEL = 0; - PNX833X_PIO_SEL2 = 0; - PNX833X_PIO_INT_EDGE = 0; - PNX833X_PIO_INT_HI = 0; - PNX833X_PIO_INT_LO = 0; - - /* clear any GPIO interrupt requests */ - PNX833X_PIO_INT_CLEAR = 0xffff; - PNX833X_PIO_INT_CLEAR = 0; - PNX833X_PIO_INT_ENABLE = 0; -} - -/* Select GPIO direction for a pin */ -static inline void pnx833x_gpio_select_input(unsigned int pin) -{ - if (pin < 32) - CLEAR_REG_BIT(PNX833X_PIO_DIR, pin); - else - CLEAR_REG_BIT(PNX833X_PIO_DIR2, pin & 31); -} -static inline void pnx833x_gpio_select_output(unsigned int pin) -{ - if (pin < 32) - SET_REG_BIT(PNX833X_PIO_DIR, pin); - else - SET_REG_BIT(PNX833X_PIO_DIR2, pin & 31); -} - -/* Select GPIO or alternate function for a pin */ -static inline void pnx833x_gpio_select_function_io(unsigned int pin) -{ - if (pin < 32) - CLEAR_REG_BIT(PNX833X_PIO_SEL, pin); - else - CLEAR_REG_BIT(PNX833X_PIO_SEL2, pin & 31); -} -static inline void pnx833x_gpio_select_function_alt(unsigned int pin) -{ - if (pin < 32) - SET_REG_BIT(PNX833X_PIO_SEL, pin); - else - SET_REG_BIT(PNX833X_PIO_SEL2, pin & 31); -} - -/* Read GPIO pin */ -static inline int pnx833x_gpio_read(unsigned int pin) -{ - if (pin < 32) - return (PNX833X_PIO_IN >> pin) & 1; - else - return (PNX833X_PIO_IN2 >> (pin & 31)) & 1; -} - -/* Write GPIO pin */ -static inline void pnx833x_gpio_write(unsigned int val, unsigned int pin) -{ - if (pin < 32) { - if (val) - SET_REG_BIT(PNX833X_PIO_OUT, pin); - else - CLEAR_REG_BIT(PNX833X_PIO_OUT, pin); - } else { - if (val) - SET_REG_BIT(PNX833X_PIO_OUT2, pin & 31); - else - CLEAR_REG_BIT(PNX833X_PIO_OUT2, pin & 31); - } -} - -/* Configure GPIO interrupt */ -#define GPIO_INT_NONE 0 -#define GPIO_INT_LEVEL_LOW 1 -#define GPIO_INT_LEVEL_HIGH 2 -#define GPIO_INT_EDGE_RISING 3 -#define GPIO_INT_EDGE_FALLING 4 -#define GPIO_INT_EDGE_BOTH 5 -static inline void pnx833x_gpio_setup_irq(int when, unsigned int pin) -{ - switch (when) { - case GPIO_INT_LEVEL_LOW: - CLEAR_REG_BIT(PNX833X_PIO_INT_EDGE, pin); - CLEAR_REG_BIT(PNX833X_PIO_INT_HI, pin); - SET_REG_BIT(PNX833X_PIO_INT_LO, pin); - break; - case GPIO_INT_LEVEL_HIGH: - CLEAR_REG_BIT(PNX833X_PIO_INT_EDGE, pin); - SET_REG_BIT(PNX833X_PIO_INT_HI, pin); - CLEAR_REG_BIT(PNX833X_PIO_INT_LO, pin); - break; - case GPIO_INT_EDGE_RISING: - SET_REG_BIT(PNX833X_PIO_INT_EDGE, pin); - SET_REG_BIT(PNX833X_PIO_INT_HI, pin); - CLEAR_REG_BIT(PNX833X_PIO_INT_LO, pin); - break; - case GPIO_INT_EDGE_FALLING: - SET_REG_BIT(PNX833X_PIO_INT_EDGE, pin); - CLEAR_REG_BIT(PNX833X_PIO_INT_HI, pin); - SET_REG_BIT(PNX833X_PIO_INT_LO, pin); - break; - case GPIO_INT_EDGE_BOTH: - SET_REG_BIT(PNX833X_PIO_INT_EDGE, pin); - SET_REG_BIT(PNX833X_PIO_INT_HI, pin); - SET_REG_BIT(PNX833X_PIO_INT_LO, pin); - break; - default: - CLEAR_REG_BIT(PNX833X_PIO_INT_EDGE, pin); - CLEAR_REG_BIT(PNX833X_PIO_INT_HI, pin); - CLEAR_REG_BIT(PNX833X_PIO_INT_LO, pin); - break; - } -} - -/* Enable/disable GPIO interrupt */ -static inline void pnx833x_gpio_enable_irq(unsigned int pin) -{ - SET_REG_BIT(PNX833X_PIO_INT_ENABLE, pin); -} -static inline void pnx833x_gpio_disable_irq(unsigned int pin) -{ - CLEAR_REG_BIT(PNX833X_PIO_INT_ENABLE, pin); -} - -/* Clear GPIO interrupt request */ -static inline void pnx833x_gpio_clear_irq(unsigned int pin) -{ - SET_REG_BIT(PNX833X_PIO_INT_CLEAR, pin); - CLEAR_REG_BIT(PNX833X_PIO_INT_CLEAR, pin); -} - -#endif diff --git a/arch/mips/include/asm/mach-pnx833x/irq-mapping.h b/arch/mips/include/asm/mach-pnx833x/irq-mapping.h deleted file mode 100644 index 32d8063c1bbc..000000000000 --- a/arch/mips/include/asm/mach-pnx833x/irq-mapping.h +++ /dev/null @@ -1,112 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/* - * irq.h: IRQ mappings for PNX833X. - * - * Copyright 2008 NXP Semiconductors - * Chris Steel <chris.steel@nxp.com> - * Daniel Laird <daniel.j.laird@nxp.com> - */ - -#ifndef __ASM_MIPS_MACH_PNX833X_IRQ_MAPPING_H -#define __ASM_MIPS_MACH_PNX833X_IRQ_MAPPING_H -/* - * The "IRQ numbers" are completely virtual. - * - * In PNX8330/1, we have 48 interrupt lines, numbered from 1 to 48. - * Let's use numbers 1..48 for PIC interrupts, number 0 for timer interrupt, - * numbers 49..64 for (virtual) GPIO interrupts. - * - * In PNX8335, we have 57 interrupt lines, numbered from 1 to 57, - * connected to PIC, which uses core hardware interrupt 2, and also - * a timer interrupt through hardware interrupt 5. - * Let's use numbers 1..64 for PIC interrupts, number 0 for timer interrupt, - * numbers 65..80 for (virtual) GPIO interrupts. - * - */ -#include <irq.h> - -#define PNX833X_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) - -/* Interrupts supported by PIC */ -#define PNX833X_PIC_I2C0_INT (PNX833X_PIC_IRQ_BASE + 1) -#define PNX833X_PIC_I2C1_INT (PNX833X_PIC_IRQ_BASE + 2) -#define PNX833X_PIC_UART0_INT (PNX833X_PIC_IRQ_BASE + 3) -#define PNX833X_PIC_UART1_INT (PNX833X_PIC_IRQ_BASE + 4) -#define PNX833X_PIC_TS_IN0_DV_INT (PNX833X_PIC_IRQ_BASE + 5) -#define PNX833X_PIC_TS_IN0_DMA_INT (PNX833X_PIC_IRQ_BASE + 6) -#define PNX833X_PIC_GPIO_INT (PNX833X_PIC_IRQ_BASE + 7) -#define PNX833X_PIC_AUDIO_DEC_INT (PNX833X_PIC_IRQ_BASE + 8) -#define PNX833X_PIC_VIDEO_DEC_INT (PNX833X_PIC_IRQ_BASE + 9) -#define PNX833X_PIC_CONFIG_INT (PNX833X_PIC_IRQ_BASE + 10) -#define PNX833X_PIC_AOI_INT (PNX833X_PIC_IRQ_BASE + 11) -#define PNX833X_PIC_SYNC_INT (PNX833X_PIC_IRQ_BASE + 12) -#define PNX8330_PIC_SPU_INT (PNX833X_PIC_IRQ_BASE + 13) -#define PNX8335_PIC_SATA_INT (PNX833X_PIC_IRQ_BASE + 13) -#define PNX833X_PIC_OSD_INT (PNX833X_PIC_IRQ_BASE + 14) -#define PNX833X_PIC_DISP1_INT (PNX833X_PIC_IRQ_BASE + 15) -#define PNX833X_PIC_DEINTERLACER_INT (PNX833X_PIC_IRQ_BASE + 16) -#define PNX833X_PIC_DISPLAY2_INT (PNX833X_PIC_IRQ_BASE + 17) -#define PNX833X_PIC_VC_INT (PNX833X_PIC_IRQ_BASE + 18) -#define PNX833X_PIC_SC_INT (PNX833X_PIC_IRQ_BASE + 19) -#define PNX833X_PIC_IDE_INT (PNX833X_PIC_IRQ_BASE + 20) -#define PNX833X_PIC_IDE_DMA_INT (PNX833X_PIC_IRQ_BASE + 21) -#define PNX833X_PIC_TS_IN1_DV_INT (PNX833X_PIC_IRQ_BASE + 22) -#define PNX833X_PIC_TS_IN1_DMA_INT (PNX833X_PIC_IRQ_BASE + 23) -#define PNX833X_PIC_SGDX_DMA_INT (PNX833X_PIC_IRQ_BASE + 24) -#define PNX833X_PIC_TS_OUT_INT (PNX833X_PIC_IRQ_BASE + 25) -#define PNX833X_PIC_IR_INT (PNX833X_PIC_IRQ_BASE + 26) -#define PNX833X_PIC_VMSP1_INT (PNX833X_PIC_IRQ_BASE + 27) -#define PNX833X_PIC_VMSP2_INT (PNX833X_PIC_IRQ_BASE + 28) -#define PNX833X_PIC_PIBC_INT (PNX833X_PIC_IRQ_BASE + 29) -#define PNX833X_PIC_TS_IN0_TRD_INT (PNX833X_PIC_IRQ_BASE + 30) -#define PNX833X_PIC_SGDX_TPD_INT (PNX833X_PIC_IRQ_BASE + 31) -#define PNX833X_PIC_USB_INT (PNX833X_PIC_IRQ_BASE + 32) -#define PNX833X_PIC_TS_IN1_TRD_INT (PNX833X_PIC_IRQ_BASE + 33) -#define PNX833X_PIC_CLOCK_INT (PNX833X_PIC_IRQ_BASE + 34) -#define PNX833X_PIC_SGDX_PARSER_INT (PNX833X_PIC_IRQ_BASE + 35) -#define PNX833X_PIC_VMSP_DMA_INT (PNX833X_PIC_IRQ_BASE + 36) - -#if defined(CONFIG_SOC_PNX8335) -#define PNX8335_PIC_MIU_INT (PNX833X_PIC_IRQ_BASE + 37) -#define PNX8335_PIC_AVCHIP_IRQ_INT (PNX833X_PIC_IRQ_BASE + 38) -#define PNX8335_PIC_SYNC_HD_INT (PNX833X_PIC_IRQ_BASE + 39) -#define PNX8335_PIC_DISP_HD_INT (PNX833X_PIC_IRQ_BASE + 40) -#define PNX8335_PIC_DISP_SCALER_INT (PNX833X_PIC_IRQ_BASE + 41) -#define PNX8335_PIC_OSD_HD1_INT (PNX833X_PIC_IRQ_BASE + 42) -#define PNX8335_PIC_DTL_WRITER_Y_INT (PNX833X_PIC_IRQ_BASE + 43) -#define PNX8335_PIC_DTL_WRITER_C_INT (PNX833X_PIC_IRQ_BASE + 44) -#define PNX8335_PIC_DTL_EMULATOR_Y_IR_INT (PNX833X_PIC_IRQ_BASE + 45) -#define PNX8335_PIC_DTL_EMULATOR_C_IR_INT (PNX833X_PIC_IRQ_BASE + 46) -#define PNX8335_PIC_DENC_TTX_INT (PNX833X_PIC_IRQ_BASE + 47) -#define PNX8335_PIC_MMI_SIF0_INT (PNX833X_PIC_IRQ_BASE + 48) -#define PNX8335_PIC_MMI_SIF1_INT (PNX833X_PIC_IRQ_BASE + 49) -#define PNX8335_PIC_MMI_CDMMU_INT (PNX833X_PIC_IRQ_BASE + 50) -#define PNX8335_PIC_PIBCS_INT (PNX833X_PIC_IRQ_BASE + 51) -#define PNX8335_PIC_ETHERNET_INT (PNX833X_PIC_IRQ_BASE + 52) -#define PNX8335_PIC_VMSP1_0_INT (PNX833X_PIC_IRQ_BASE + 53) -#define PNX8335_PIC_VMSP1_1_INT (PNX833X_PIC_IRQ_BASE + 54) -#define PNX8335_PIC_VMSP1_DMA_INT (PNX833X_PIC_IRQ_BASE + 55) -#define PNX8335_PIC_TDGR_DE_INT (PNX833X_PIC_IRQ_BASE + 56) -#define PNX8335_PIC_IR1_IRQ_INT (PNX833X_PIC_IRQ_BASE + 57) -#endif - -/* GPIO interrupts */ -#define PNX833X_GPIO_0_INT (PNX833X_GPIO_IRQ_BASE + 0) -#define PNX833X_GPIO_1_INT (PNX833X_GPIO_IRQ_BASE + 1) -#define PNX833X_GPIO_2_INT (PNX833X_GPIO_IRQ_BASE + 2) -#define PNX833X_GPIO_3_INT (PNX833X_GPIO_IRQ_BASE + 3) -#define PNX833X_GPIO_4_INT (PNX833X_GPIO_IRQ_BASE + 4) -#define PNX833X_GPIO_5_INT (PNX833X_GPIO_IRQ_BASE + 5) -#define PNX833X_GPIO_6_INT (PNX833X_GPIO_IRQ_BASE + 6) -#define PNX833X_GPIO_7_INT (PNX833X_GPIO_IRQ_BASE + 7) -#define PNX833X_GPIO_8_INT (PNX833X_GPIO_IRQ_BASE + 8) -#define PNX833X_GPIO_9_INT (PNX833X_GPIO_IRQ_BASE + 9) -#define PNX833X_GPIO_10_INT (PNX833X_GPIO_IRQ_BASE + 10) -#define PNX833X_GPIO_11_INT (PNX833X_GPIO_IRQ_BASE + 11) -#define PNX833X_GPIO_12_INT (PNX833X_GPIO_IRQ_BASE + 12) -#define PNX833X_GPIO_13_INT (PNX833X_GPIO_IRQ_BASE + 13) -#define PNX833X_GPIO_14_INT (PNX833X_GPIO_IRQ_BASE + 14) -#define PNX833X_GPIO_15_INT (PNX833X_GPIO_IRQ_BASE + 15) - -#endif diff --git a/arch/mips/include/asm/mach-pnx833x/irq.h b/arch/mips/include/asm/mach-pnx833x/irq.h deleted file mode 100644 index b7a6dab5b9f7..000000000000 --- a/arch/mips/include/asm/mach-pnx833x/irq.h +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * irq.h: IRQ mappings for PNX833X. - * - * Copyright 2008 NXP Semiconductors - * Chris Steel <chris.steel@nxp.com> - * Daniel Laird <daniel.j.laird@nxp.com> - */ - -#ifndef __ASM_MIPS_MACH_PNX833X_IRQ_H -#define __ASM_MIPS_MACH_PNX833X_IRQ_H -/* - * The "IRQ numbers" are completely virtual. - * - * In PNX8330/1, we have 48 interrupt lines, numbered from 1 to 48. - * Let's use numbers 1..48 for PIC interrupts, number 0 for timer interrupt, - * numbers 49..64 for (virtual) GPIO interrupts. - * - * In PNX8335, we have 57 interrupt lines, numbered from 1 to 57, - * connected to PIC, which uses core hardware interrupt 2, and also - * a timer interrupt through hardware interrupt 5. - * Let's use numbers 1..64 for PIC interrupts, number 0 for timer interrupt, - * numbers 65..80 for (virtual) GPIO interrupts. - * - */ -#if defined(CONFIG_SOC_PNX8335) - #define PNX833X_PIC_NUM_IRQ 58 -#else - #define PNX833X_PIC_NUM_IRQ 37 -#endif - -#define MIPS_CPU_NUM_IRQ 8 -#define PNX833X_GPIO_NUM_IRQ 16 - -#define MIPS_CPU_IRQ_BASE 0 -#define PNX833X_PIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + MIPS_CPU_NUM_IRQ) -#define PNX833X_GPIO_IRQ_BASE (PNX833X_PIC_IRQ_BASE + PNX833X_PIC_NUM_IRQ) -#define NR_IRQS (MIPS_CPU_NUM_IRQ + PNX833X_PIC_NUM_IRQ + PNX833X_GPIO_NUM_IRQ) - -#endif diff --git a/arch/mips/include/asm/mach-pnx833x/pnx833x.h b/arch/mips/include/asm/mach-pnx833x/pnx833x.h deleted file mode 100644 index 00bb67a36386..000000000000 --- a/arch/mips/include/asm/mach-pnx833x/pnx833x.h +++ /dev/null @@ -1,189 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * pnx833x.h: Register mappings for PNX833X. - * - * Copyright 2008 NXP Semiconductors - * Chris Steel <chris.steel@nxp.com> - * Daniel Laird <daniel.j.laird@nxp.com> - */ -#ifndef __ASM_MIPS_MACH_PNX833X_PNX833X_H -#define __ASM_MIPS_MACH_PNX833X_PNX833X_H - -/* All regs are accessed in KSEG1 */ -#define PNX833X_BASE (0xa0000000ul + 0x17E00000ul) - -#define PNX833X_REG(offs) (*((volatile unsigned long *)(PNX833X_BASE + offs))) - -/* Registers are named exactly as in PNX833X docs, just with PNX833X_ prefix */ - -/* Read access to multibit fields */ -#define PNX833X_BIT(val, reg, field) ((val) & PNX833X_##reg##_##field) -#define PNX833X_REGBIT(reg, field) PNX833X_BIT(PNX833X_##reg, reg, field) - -/* Use PNX833X_FIELD to extract a field from val */ -#define PNX_FIELD(cpu, val, reg, field) \ - (((val) & PNX##cpu##_##reg##_##field##_MASK) >> \ - PNX##cpu##_##reg##_##field##_SHIFT) -#define PNX833X_FIELD(val, reg, field) PNX_FIELD(833X, val, reg, field) -#define PNX8330_FIELD(val, reg, field) PNX_FIELD(8330, val, reg, field) -#define PNX8335_FIELD(val, reg, field) PNX_FIELD(8335, val, reg, field) - -/* Use PNX833X_REGFIELD to extract a field from a register */ -#define PNX833X_REGFIELD(reg, field) PNX833X_FIELD(PNX833X_##reg, reg, field) -#define PNX8330_REGFIELD(reg, field) PNX8330_FIELD(PNX8330_##reg, reg, field) -#define PNX8335_REGFIELD(reg, field) PNX8335_FIELD(PNX8335_##reg, reg, field) - - -#define PNX_WRITEFIELD(cpu, val, reg, field) \ - (PNX##cpu##_##reg = (PNX##cpu##_##reg & ~(PNX##cpu##_##reg##_##field##_MASK)) | \ - ((val) << PNX##cpu##_##reg##_##field##_SHIFT)) -#define PNX833X_WRITEFIELD(val, reg, field) \ - PNX_WRITEFIELD(833X, val, reg, field) -#define PNX8330_WRITEFIELD(val, reg, field) \ - PNX_WRITEFIELD(8330, val, reg, field) -#define PNX8335_WRITEFIELD(val, reg, field) \ - PNX_WRITEFIELD(8335, val, reg, field) - - -/* Macros to detect CPU type */ - -#define PNX833X_CONFIG_MODULE_ID PNX833X_REG(0x7FFC) -#define PNX833X_CONFIG_MODULE_ID_MAJREV_MASK 0x0000f000 -#define PNX833X_CONFIG_MODULE_ID_MAJREV_SHIFT 12 -#define PNX8330_CONFIG_MODULE_MAJREV 4 -#define PNX8335_CONFIG_MODULE_MAJREV 5 -#define CPU_IS_PNX8330 (PNX833X_REGFIELD(CONFIG_MODULE_ID, MAJREV) == \ - PNX8330_CONFIG_MODULE_MAJREV) -#define CPU_IS_PNX8335 (PNX833X_REGFIELD(CONFIG_MODULE_ID, MAJREV) == \ - PNX8335_CONFIG_MODULE_MAJREV) - - - -#define PNX833X_RESET_CONTROL PNX833X_REG(0x8004) -#define PNX833X_RESET_CONTROL_2 PNX833X_REG(0x8014) - -#define PNX833X_PIC_REG(offs) PNX833X_REG(0x01000 + (offs)) -#define PNX833X_PIC_INT_PRIORITY PNX833X_PIC_REG(0x0) -#define PNX833X_PIC_INT_SRC PNX833X_PIC_REG(0x4) -#define PNX833X_PIC_INT_SRC_INT_SRC_MASK 0x00000FF8ul /* bits 11:3 */ -#define PNX833X_PIC_INT_SRC_INT_SRC_SHIFT 3 -#define PNX833X_PIC_INT_REG(irq) PNX833X_PIC_REG(0x10 + 4*(irq)) - -#define PNX833X_CLOCK_CPUCP_CTL PNX833X_REG(0x9228) -#define PNX833X_CLOCK_CPUCP_CTL_EXIT_RESET 0x00000002ul /* bit 1 */ -#define PNX833X_CLOCK_CPUCP_CTL_DIV_CLOCK_MASK 0x00000018ul /* bits 4:3 */ -#define PNX833X_CLOCK_CPUCP_CTL_DIV_CLOCK_SHIFT 3 - -#define PNX8335_CLOCK_PLL_CPU_CTL PNX833X_REG(0x9020) -#define PNX8335_CLOCK_PLL_CPU_CTL_FREQ_MASK 0x1f -#define PNX8335_CLOCK_PLL_CPU_CTL_FREQ_SHIFT 0 - -#define PNX833X_CONFIG_MUX PNX833X_REG(0x7004) -#define PNX833X_CONFIG_MUX_IDE_MUX 0x00000080 /* bit 7 */ - -#define PNX8330_CONFIG_POLYFUSE_7 PNX833X_REG(0x7040) -#define PNX8330_CONFIG_POLYFUSE_7_BOOT_MODE_MASK 0x00180000 -#define PNX8330_CONFIG_POLYFUSE_7_BOOT_MODE_SHIFT 19 - -#define PNX833X_PIO_IN PNX833X_REG(0xF000) -#define PNX833X_PIO_OUT PNX833X_REG(0xF004) -#define PNX833X_PIO_DIR PNX833X_REG(0xF008) -#define PNX833X_PIO_SEL PNX833X_REG(0xF014) -#define PNX833X_PIO_INT_EDGE PNX833X_REG(0xF020) -#define PNX833X_PIO_INT_HI PNX833X_REG(0xF024) -#define PNX833X_PIO_INT_LO PNX833X_REG(0xF028) -#define PNX833X_PIO_INT_STATUS PNX833X_REG(0xFFE0) -#define PNX833X_PIO_INT_ENABLE PNX833X_REG(0xFFE4) -#define PNX833X_PIO_INT_CLEAR PNX833X_REG(0xFFE8) -#define PNX833X_PIO_IN2 PNX833X_REG(0xF05C) -#define PNX833X_PIO_OUT2 PNX833X_REG(0xF060) -#define PNX833X_PIO_DIR2 PNX833X_REG(0xF064) -#define PNX833X_PIO_SEL2 PNX833X_REG(0xF068) - -#define PNX833X_UART0_PORTS_START (PNX833X_BASE + 0xB000) -#define PNX833X_UART0_PORTS_END (PNX833X_BASE + 0xBFFF) -#define PNX833X_UART1_PORTS_START (PNX833X_BASE + 0xC000) -#define PNX833X_UART1_PORTS_END (PNX833X_BASE + 0xCFFF) - -#define PNX833X_USB_PORTS_START (PNX833X_BASE + 0x19000) -#define PNX833X_USB_PORTS_END (PNX833X_BASE + 0x19FFF) - -#define PNX833X_CONFIG_USB PNX833X_REG(0x7008) - -#define PNX833X_I2C0_PORTS_START (PNX833X_BASE + 0xD000) -#define PNX833X_I2C0_PORTS_END (PNX833X_BASE + 0xDFFF) -#define PNX833X_I2C1_PORTS_START (PNX833X_BASE + 0xE000) -#define PNX833X_I2C1_PORTS_END (PNX833X_BASE + 0xEFFF) - -#define PNX833X_IDE_PORTS_START (PNX833X_BASE + 0x1A000) -#define PNX833X_IDE_PORTS_END (PNX833X_BASE + 0x1AFFF) -#define PNX833X_IDE_MODULE_ID PNX833X_REG(0x1AFFC) - -#define PNX833X_IDE_MODULE_ID_MODULE_ID_MASK 0xFFFF0000 -#define PNX833X_IDE_MODULE_ID_MODULE_ID_SHIFT 16 -#define PNX833X_IDE_MODULE_ID_VALUE 0xA009 - - -#define PNX833X_MIU_SEL0 PNX833X_REG(0x2004) -#define PNX833X_MIU_SEL0_TIMING PNX833X_REG(0x2008) -#define PNX833X_MIU_SEL1 PNX833X_REG(0x200C) -#define PNX833X_MIU_SEL1_TIMING PNX833X_REG(0x2010) -#define PNX833X_MIU_SEL2 PNX833X_REG(0x2014) -#define PNX833X_MIU_SEL2_TIMING PNX833X_REG(0x2018) -#define PNX833X_MIU_SEL3 PNX833X_REG(0x201C) -#define PNX833X_MIU_SEL3_TIMING PNX833X_REG(0x2020) - -#define PNX833X_MIU_SEL0_SPI_MODE_ENABLE_MASK (1 << 14) -#define PNX833X_MIU_SEL0_SPI_MODE_ENABLE_SHIFT 14 - -#define PNX833X_MIU_SEL0_BURST_MODE_ENABLE_MASK (1 << 7) -#define PNX833X_MIU_SEL0_BURST_MODE_ENABLE_SHIFT 7 - -#define PNX833X_MIU_SEL0_BURST_PAGE_LEN_MASK (0xF << 9) -#define PNX833X_MIU_SEL0_BURST_PAGE_LEN_SHIFT 9 - -#define PNX833X_MIU_CONFIG_SPI PNX833X_REG(0x2000) - -#define PNX833X_MIU_CONFIG_SPI_OPCODE_MASK (0xFF << 3) -#define PNX833X_MIU_CONFIG_SPI_OPCODE_SHIFT 3 - -#define PNX833X_MIU_CONFIG_SPI_DATA_ENABLE_MASK (1 << 2) -#define PNX833X_MIU_CONFIG_SPI_DATA_ENABLE_SHIFT 2 - -#define PNX833X_MIU_CONFIG_SPI_ADDR_ENABLE_MASK (1 << 1) -#define PNX833X_MIU_CONFIG_SPI_ADDR_ENABLE_SHIFT 1 - -#define PNX833X_MIU_CONFIG_SPI_SYNC_MASK (1 << 0) -#define PNX833X_MIU_CONFIG_SPI_SYNC_SHIFT 0 - -#define PNX833X_WRITE_CONFIG_SPI(opcode, data_enable, addr_enable, sync) \ - (PNX833X_MIU_CONFIG_SPI = \ - ((opcode) << PNX833X_MIU_CONFIG_SPI_OPCODE_SHIFT) | \ - ((data_enable) << PNX833X_MIU_CONFIG_SPI_DATA_ENABLE_SHIFT) | \ - ((addr_enable) << PNX833X_MIU_CONFIG_SPI_ADDR_ENABLE_SHIFT) | \ - ((sync) << PNX833X_MIU_CONFIG_SPI_SYNC_SHIFT)) - -#define PNX8335_IP3902_PORTS_START (PNX833X_BASE + 0x2F000) -#define PNX8335_IP3902_PORTS_END (PNX833X_BASE + 0x2FFFF) -#define PNX8335_IP3902_MODULE_ID PNX833X_REG(0x2FFFC) - -#define PNX8335_IP3902_MODULE_ID_MODULE_ID_MASK 0xFFFF0000 -#define PNX8335_IP3902_MODULE_ID_MODULE_ID_SHIFT 16 -#define PNX8335_IP3902_MODULE_ID_VALUE 0x3902 - - /* I/O location(gets remapped)*/ -#define PNX8335_NAND_BASE 0x18000000 -/* I/O location with CLE high */ -#define PNX8335_NAND_CLE_MASK 0x00100000 -/* I/O location with ALE high */ -#define PNX8335_NAND_ALE_MASK 0x00010000 - -#define PNX8335_SATA_PORTS_START (PNX833X_BASE + 0x2E000) -#define PNX8335_SATA_PORTS_END (PNX833X_BASE + 0x2EFFF) -#define PNX8335_SATA_MODULE_ID PNX833X_REG(0x2EFFC) - -#define PNX8335_SATA_MODULE_ID_MODULE_ID_MASK 0xFFFF0000 -#define PNX8335_SATA_MODULE_ID_MODULE_ID_SHIFT 16 -#define PNX8335_SATA_MODULE_ID_VALUE 0xA099 - -#endif diff --git a/arch/mips/include/asm/mach-rc32434/war.h b/arch/mips/include/asm/mach-rc32434/war.h deleted file mode 100644 index af430d26f713..000000000000 --- a/arch/mips/include/asm/mach-rc32434/war.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MIPS_MACH_MIPS_WAR_H -#define __ASM_MIPS_MACH_MIPS_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 1 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 0 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_MIPS_WAR_H */ diff --git a/arch/mips/include/asm/mach-rm/war.h b/arch/mips/include/asm/mach-rm/war.h deleted file mode 100644 index eca16d167c2f..000000000000 --- a/arch/mips/include/asm/mach-rm/war.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MIPS_MACH_RM_WAR_H -#define __ASM_MIPS_MACH_RM_WAR_H - -/* - * The RM200C seems to have been shipped only with V2.0 R4600s - */ - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 1 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 0 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_RM_WAR_H */ diff --git a/arch/mips/include/asm/mach-sibyte/war.h b/arch/mips/include/asm/mach-sibyte/war.h deleted file mode 100644 index 4755b6116807..000000000000 --- a/arch/mips/include/asm/mach-sibyte/war.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MIPS_MACH_SIBYTE_WAR_H -#define __ASM_MIPS_MACH_SIBYTE_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 - -#if defined(CONFIG_SB1_PASS_2_WORKAROUNDS) - -#ifndef __ASSEMBLY__ -extern int sb1250_m3_workaround_needed(void); -#endif - -#define BCM1250_M3_WAR sb1250_m3_workaround_needed() -#define SIBYTE_1956_WAR 1 - -#else - -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 - -#endif - -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 0 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_SIBYTE_WAR_H */ diff --git a/arch/mips/include/asm/mach-tx49xx/war.h b/arch/mips/include/asm/mach-tx49xx/war.h deleted file mode 100644 index 445abb4eb769..000000000000 --- a/arch/mips/include/asm/mach-tx49xx/war.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MIPS_MACH_TX49XX_WAR_H -#define __ASM_MIPS_MACH_TX49XX_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 1 -#define ICACHE_REFILLS_WORKAROUND_WAR 0 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_TX49XX_WAR_H */ diff --git a/arch/mips/include/asm/machine.h b/arch/mips/include/asm/machine.h index 29ca344a8cab..fc64cce270f0 100644 --- a/arch/mips/include/asm/machine.h +++ b/arch/mips/include/asm/machine.h @@ -23,7 +23,7 @@ extern long __mips_machines_end; #define MIPS_MACHINE(name) \ static const struct mips_machine __mips_mach_##name \ - __used __section(.mips.machines.init) + __used __section(".mips.machines.init") #define for_each_mips_machine(mach) \ for ((mach) = (struct mips_machine *)&__mips_machines_start; \ diff --git a/arch/mips/include/asm/mips-boards/malta.h b/arch/mips/include/asm/mips-boards/malta.h index 65de4fb06096..254be3d62519 100644 --- a/arch/mips/include/asm/mips-boards/malta.h +++ b/arch/mips/include/asm/mips-boards/malta.h @@ -92,4 +92,6 @@ static inline unsigned long get_msc_port_base(unsigned long reg) #define MALTA_JMPRS_REG 0x1f000210 +extern void __init *malta_dt_shim(void *fdt); + #endif /* __ASM_MIPS_BOARDS_MALTA_H */ diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 4ddc12e4444a..a0e8ae5497b6 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -389,6 +389,13 @@ #define ST0_CU3 0x80000000 #define ST0_XX 0x80000000 /* MIPS IV naming */ +/* in-kernel enabled CUs */ +#ifdef CONFIG_CPU_LOONGSON64 +#define ST0_KERNEL_CUMASK (ST0_CU0 | ST0_CU2) +#else +#define ST0_KERNEL_CUMASK ST0_CU0 +#endif + /* * Bitfields and bit numbers in the coprocessor 0 IntCtl register. (MIPSR2) */ @@ -1706,12 +1713,6 @@ do { \ #define read_c0_count() __read_32bit_c0_register($9, 0) #define write_c0_count(val) __write_32bit_c0_register($9, 0, val) -#define read_c0_count2() __read_32bit_c0_register($9, 6) /* pnx8550 */ -#define write_c0_count2(val) __write_32bit_c0_register($9, 6, val) - -#define read_c0_count3() __read_32bit_c0_register($9, 7) /* pnx8550 */ -#define write_c0_count3(val) __write_32bit_c0_register($9, 7, val) - #define read_c0_entryhi() __read_ulong_c0_register($10, 0) #define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) @@ -1730,12 +1731,6 @@ do { \ #define read_c0_guestctl0ext() __read_32bit_c0_register($11, 4) #define write_c0_guestctl0ext(val) __write_32bit_c0_register($11, 4, val) -#define read_c0_compare2() __read_32bit_c0_register($11, 6) /* pnx8550 */ -#define write_c0_compare2(val) __write_32bit_c0_register($11, 6, val) - -#define read_c0_compare3() __read_32bit_c0_register($11, 7) /* pnx8550 */ -#define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val) - #define read_c0_status() __read_32bit_c0_register($12, 0) #define write_c0_status(val) __write_32bit_c0_register($12, 0, val) @@ -2728,7 +2723,7 @@ static inline void tlb_probe(void) static inline void tlb_read(void) { -#if MIPS34K_MISSED_ITLB_WAR +#ifdef CONFIG_WAR_MIPS34K_MISSED_ITLB int res = 0; __asm__ __volatile__( @@ -2750,7 +2745,7 @@ static inline void tlb_read(void) "tlbr\n\t" ".set reorder"); -#if MIPS34K_MISSED_ITLB_WAR +#ifdef CONFIG_WAR_MIPS34K_MISSED_ITLB if ((res & _ULCAST_(1))) __asm__ __volatile__( " .set push \n" diff --git a/arch/mips/include/asm/netlogic/psb-bootinfo.h b/arch/mips/include/asm/netlogic/psb-bootinfo.h index 6878307f0ee6..c716e9397113 100644 --- a/arch/mips/include/asm/netlogic/psb-bootinfo.h +++ b/arch/mips/include/asm/netlogic/psb-bootinfo.h @@ -77,21 +77,6 @@ struct psb_info { uint64_t avail_mem_map; }; -enum { - NETLOGIC_IO_SPACE = 0x10, - PCIX_IO_SPACE, - PCIX_CFG_SPACE, - PCIX_MEMORY_SPACE, - HT_IO_SPACE, - HT_CFG_SPACE, - HT_MEMORY_SPACE, - SRAM_SPACE, - FLASH_CONTROLLER_SPACE -}; - -#define NLM_MAX_ARGS 64 -#define NLM_MAX_ENVS 32 - /* This is what netlboot passes and linux boot_mem_map is subtly different */ #define NLM_BOOT_MEM_MAP_MAX 32 struct nlm_boot_mem_map { @@ -102,6 +87,7 @@ struct nlm_boot_mem_map { uint32_t type; /* type of memory segment */ } map[NLM_BOOT_MEM_MAP_MAX]; }; +#define NLM_BOOT_MEM_RAM 1 /* Pointer to saved boot loader info */ extern struct psb_info nlm_prom_info; diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h index 62787765575e..c114a7ba0bad 100644 --- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h +++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h @@ -295,6 +295,8 @@ enum cvmx_board_types_enum { */ CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001, CVMX_BOARD_TYPE_UBNT_E100 = 20002, + CVMX_BOARD_TYPE_UBNT_E200 = 20003, + CVMX_BOARD_TYPE_UBNT_E220 = 20005, CVMX_BOARD_TYPE_CUST_DSR1000N = 20006, CVMX_BOARD_TYPE_KONTRON_S1901 = 21901, CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000, @@ -396,6 +398,8 @@ static inline const char *cvmx_board_type_to_string(enum /* Customer private range */ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN) ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100) + ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E200) + ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E220) ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DSR1000N) ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KONTRON_S1901) ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX) diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index e26dc41a8a68..2362842ee2b5 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h @@ -249,11 +249,6 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val) #define _CACHE_CACHABLE_NONCOHERENT (5<<_CACHE_SHIFT) -#elif defined(CONFIG_MACH_INGENIC) - -/* Ingenic uses the WA bit to achieve write-combine memory writes */ -#define _CACHE_UNCACHED_ACCELERATED (1<<_CACHE_SHIFT) - #endif #ifndef _CACHE_CACHABLE_NO_WA diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index dd7a0f552cac..e5ef0fdd4838 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -37,8 +37,6 @@ struct vm_area_struct; _PAGE_GLOBAL | _page_cachable_default) #define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT) -#define PAGE_USERIO __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \ - _page_cachable_default) #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \ __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED) diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 856e12f6063d..7834e7c0c78a 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -29,6 +29,7 @@ */ extern unsigned int vced_count, vcei_count; +extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); #ifdef CONFIG_32BIT #ifdef CONFIG_KVM_GUEST diff --git a/arch/mips/include/asm/r4k-timer.h b/arch/mips/include/asm/r4k-timer.h index afe9e0e03fe9..6e7361629348 100644 --- a/arch/mips/include/asm/r4k-timer.h +++ b/arch/mips/include/asm/r4k-timer.h @@ -5,8 +5,8 @@ * * Copyright (C) 2008 by Ralf Baechle (ralf@linux-mips.org) */ -#ifndef __ASM_R4K_TYPES_H -#define __ASM_R4K_TYPES_H +#ifndef __ASM_R4K_TIMER_H +#define __ASM_R4K_TIMER_H #include <linux/compiler.h> @@ -27,4 +27,4 @@ static inline void synchronise_count_slave(int cpu) #endif -#endif /* __ASM_R4K_TYPES_H */ +#endif /* __ASM_R4K_TIMER_H */ diff --git a/arch/mips/include/asm/sgi/heart.h b/arch/mips/include/asm/sgi/heart.h index c423221b4792..0d03751955c4 100644 --- a/arch/mips/include/asm/sgi/heart.h +++ b/arch/mips/include/asm/sgi/heart.h @@ -264,6 +264,57 @@ struct ip30_heart_regs { /* 0x0ff00000 */ #define HC_NCOR_MEM_ERR BIT(1) #define HC_COR_MEM_ERR BIT(0) +/* + * HEART has 64 interrupt vectors available to it, subdivided into five + * priority levels. They are numbered 0 to 63. + */ +#define HEART_NUM_IRQS 64 + +/* + * These are the five interrupt priority levels and their corresponding + * CPU IPx interrupt pins. + * + * Level 4 - Error Interrupts. + * Level 3 - HEART timer interrupt. + * Level 2 - CPU IPI, CPU debug, power putton, general device interrupts. + * Level 1 - General device interrupts. + * Level 0 - General device GFX flow control interrupts. + */ +#define HEART_L4_INT_MASK 0xfff8000000000000ULL /* IP6 */ +#define HEART_L3_INT_MASK 0x0004000000000000ULL /* IP5 */ +#define HEART_L2_INT_MASK 0x0003ffff00000000ULL /* IP4 */ +#define HEART_L1_INT_MASK 0x00000000ffff0000ULL /* IP3 */ +#define HEART_L0_INT_MASK 0x000000000000ffffULL /* IP2 */ + +/* HEART L0 Interrupts (Low Priority) */ +#define HEART_L0_INT_GENERIC 0 +#define HEART_L0_INT_FLOW_CTRL_HWTR_0 1 +#define HEART_L0_INT_FLOW_CTRL_HWTR_1 2 + +/* HEART L2 Interrupts (High Priority) */ +#define HEART_L2_INT_RESCHED_CPU_0 46 +#define HEART_L2_INT_RESCHED_CPU_1 47 +#define HEART_L2_INT_CALL_CPU_0 48 +#define HEART_L2_INT_CALL_CPU_1 49 + +/* HEART L3 Interrupts (Compare/Counter Timer) */ +#define HEART_L3_INT_TIMER 50 + +/* HEART L4 Interrupts (Errors) */ +#define HEART_L4_INT_XWID_ERR_9 51 +#define HEART_L4_INT_XWID_ERR_A 52 +#define HEART_L4_INT_XWID_ERR_B 53 +#define HEART_L4_INT_XWID_ERR_C 54 +#define HEART_L4_INT_XWID_ERR_D 55 +#define HEART_L4_INT_XWID_ERR_E 56 +#define HEART_L4_INT_XWID_ERR_F 57 +#define HEART_L4_INT_XWID_ERR_XBOW 58 +#define HEART_L4_INT_CPU_BUS_ERR_0 59 +#define HEART_L4_INT_CPU_BUS_ERR_1 60 +#define HEART_L4_INT_CPU_BUS_ERR_2 61 +#define HEART_L4_INT_CPU_BUS_ERR_3 62 +#define HEART_L4_INT_HEART_EXCP 63 + extern struct ip30_heart_regs __iomem *heart_regs; #define heart_read ____raw_readq diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index 3e8d2aaf96af..aa430a6c68b2 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -450,7 +450,7 @@ */ .macro CLI mfc0 t0, CP0_STATUS - li t1, ST0_CU0 | STATMASK + li t1, ST0_KERNEL_CUMASK | STATMASK or t0, t1 xori t0, STATMASK mtc0 t0, CP0_STATUS @@ -463,7 +463,7 @@ */ .macro STI mfc0 t0, CP0_STATUS - li t1, ST0_CU0 | STATMASK + li t1, ST0_KERNEL_CUMASK | STATMASK or t0, t1 xori t0, STATMASK & ~1 mtc0 t0, CP0_STATUS @@ -477,7 +477,7 @@ */ .macro KMODE mfc0 t0, CP0_STATUS - li t1, ST0_CU0 | (STATMASK & ~1) + li t1, ST0_KERNEL_CUMASK | (STATMASK & ~1) #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) andi t2, t0, ST0_IEP srl t2, 2 diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h index 0b0a93bf83cd..a4374b4cb88f 100644 --- a/arch/mips/include/asm/switch_to.h +++ b/arch/mips/include/asm/switch_to.h @@ -117,6 +117,8 @@ do { \ __restore_dsp(next); \ } \ if (cop2_present) { \ + u32 status = read_c0_status(); \ + \ set_c0_status(ST0_CU2); \ if ((KSTK_STATUS(prev) & ST0_CU2)) { \ if (cop2_lazy_restore) \ @@ -127,7 +129,7 @@ do { \ !cop2_lazy_restore) { \ cop2_restore(next); \ } \ - clear_c0_status(ST0_CU2); \ + write_c0_status(status); \ } \ __clear_r5_hw_ll_bit(); \ __clear_software_ll_bit(); \ diff --git a/arch/mips/include/asm/txx9/tx4939.h b/arch/mips/include/asm/txx9/tx4939.h index 00805ac6e9fc..abf980af9ef4 100644 --- a/arch/mips/include/asm/txx9/tx4939.h +++ b/arch/mips/include/asm/txx9/tx4939.h @@ -498,7 +498,6 @@ struct tx4939_vpc_desc { ((((mst) + 245/2) / 245UL * 429 * 16 + 19) / 19 / 2) void tx4939_wdt_init(void); -void tx4939_add_memory_regions(void); void tx4939_setup(void); void tx4939_time_init(unsigned int tmrnr); void tx4939_sio_init(unsigned int sclk, unsigned int cts_mask); diff --git a/arch/mips/include/asm/war.h b/arch/mips/include/asm/war.h index e43f800e662d..21443f096238 100644 --- a/arch/mips/include/asm/war.h +++ b/arch/mips/include/asm/war.h @@ -9,8 +9,6 @@ #ifndef _ASM_WAR_H #define _ASM_WAR_H -#include <war.h> - /* * Work around certain R4000 CPU errata (as implemented by GCC): * @@ -72,152 +70,4 @@ #define DADDI_WAR 0 #endif -/* - * Another R4600 erratum. Due to the lack of errata information the exact - * technical details aren't known. I've experimentally found that disabling - * interrupts during indexed I-cache flushes seems to be sufficient to deal - * with the issue. - */ -#ifndef R4600_V1_INDEX_ICACHEOP_WAR -#error Check setting of R4600_V1_INDEX_ICACHEOP_WAR for your platform -#endif - -/* - * Pleasures of the R4600 V1.x. Cite from the IDT R4600 V1.7 errata: - * - * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, - * Hit_Invalidate_D and Create_Dirty_Excl_D should only be - * executed if there is no other dcache activity. If the dcache is - * accessed for another instruction immeidately preceding when these - * cache instructions are executing, it is possible that the dcache - * tag match outputs used by these cache instructions will be - * incorrect. These cache instructions should be preceded by at least - * four instructions that are not any kind of load or store - * instruction. - * - * This is not allowed: lw - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - * - * This is allowed: lw - * nop - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - */ -#ifndef R4600_V1_HIT_CACHEOP_WAR -#error Check setting of R4600_V1_HIT_CACHEOP_WAR for your platform -#endif - - -/* - * Writeback and invalidate the primary cache dcache before DMA. - * - * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D, - * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only - * operate correctly if the internal data cache refill buffer is empty. These - * CACHE instructions should be separated from any potential data cache miss - * by a load instruction to an uncached address to empty the response buffer." - * (Revision 2.0 device errata from IDT available on https://www.idt.com/ - * in .pdf format.) - */ -#ifndef R4600_V2_HIT_CACHEOP_WAR -#error Check setting of R4600_V2_HIT_CACHEOP_WAR for your platform -#endif - -/* - * Workaround for the Sibyte M3 errata the text of which can be found at - * - * http://sibyte.broadcom.com/hw/bcm1250/docs/pass2errata.txt - * - * This will enable the use of a special TLB refill handler which does a - * consistency check on the information in c0_badvaddr and c0_entryhi and - * will just return and take the exception again if the information was - * found to be inconsistent. - */ -#ifndef BCM1250_M3_WAR -#error Check setting of BCM1250_M3_WAR for your platform -#endif - -/* - * This is a DUART workaround related to glitches around register accesses - */ -#ifndef SIBYTE_1956_WAR -#error Check setting of SIBYTE_1956_WAR for your platform -#endif - -/* - * Fill buffers not flushed on CACHE instructions - * - * Hit_Invalidate_I cacheops invalidate an icache line but the refill - * for that line can get stale data from the fill buffer instead of - * accessing memory if the previous icache miss was also to that line. - * - * Workaround: generate an icache refill from a different line - * - * Affects: - * MIPS 4K RTL revision <3.0, PRID revision <4 - */ -#ifndef MIPS4K_ICACHE_REFILL_WAR -#error Check setting of MIPS4K_ICACHE_REFILL_WAR for your platform -#endif - -/* - * Missing implicit forced flush of evictions caused by CACHE - * instruction - * - * Evictions caused by a CACHE instructions are not forced on to the - * bus. The BIU gives higher priority to fetches than to the data from - * the eviction buffer and no collision detection is performed between - * fetches and pending data from the eviction buffer. - * - * Workaround: Execute a SYNC instruction after the cache instruction - * - * Affects: - * MIPS 5Kc,5Kf RTL revision <2.3, PRID revision <8 - * MIPS 20Kc RTL revision <4.0, PRID revision <? - */ -#ifndef MIPS_CACHE_SYNC_WAR -#error Check setting of MIPS_CACHE_SYNC_WAR for your platform -#endif - -/* - * From TX49/H2 manual: "If the instruction (i.e. CACHE) is issued for - * the line which this instruction itself exists, the following - * operation is not guaranteed." - * - * Workaround: do two phase flushing for Index_Invalidate_I - */ -#ifndef TX49XX_ICACHE_INDEX_INV_WAR -#error Check setting of TX49XX_ICACHE_INDEX_INV_WAR for your platform -#endif - -/* - * The RM7000 processors and the E9000 cores have a bug (though PMC-Sierra - * opposes it being called that) where invalid instructions in the same - * I-cache line worth of instructions being fetched may case spurious - * exceptions. - */ -#ifndef ICACHE_REFILLS_WORKAROUND_WAR -#error Check setting of ICACHE_REFILLS_WORKAROUND_WAR for your platform -#endif - -/* - * On the R10000 up to version 2.6 (not sure about 2.7) there is a bug that - * may cause ll / sc and lld / scd sequences to execute non-atomically. - */ -#ifndef R10000_LLSC_WAR -#error Check setting of R10000_LLSC_WAR for your platform -#endif - -/* - * 34K core erratum: "Problems Executing the TLBR Instruction" - */ -#ifndef MIPS34K_MISSED_ITLB_WAR -#error Check setting of MIPS34K_MISSED_ITLB_WAR for your platform -#endif - #endif /* _ASM_WAR_H */ diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/ingenic/Kconfig index c2a6fbf8e411..3238e16febd5 100644 --- a/arch/mips/jz4740/Kconfig +++ b/arch/mips/ingenic/Kconfig @@ -1,15 +1,21 @@ # SPDX-License-Identifier: GPL-2.0 + +config MACH_INGENIC_GENERIC + bool + select MACH_INGENIC + select MACH_JZ4740 + select MACH_JZ4770 + select MACH_JZ4780 + select MACH_X1000 + choice prompt "Machine type" - depends on MACH_INGENIC + depends on MACH_INGENIC_SOC default INGENIC_GENERIC_BOARD config INGENIC_GENERIC_BOARD bool "Generic board" - select MACH_JZ4740 - select MACH_JZ4770 - select MACH_JZ4780 - select MACH_X1000 + select MACH_INGENIC_GENERIC config JZ4740_QI_LB60 bool "Qi Hardware Ben NanoNote" diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c index 014773f0bfcd..461457b28982 100644 --- a/arch/mips/jazz/jazzdma.c +++ b/arch/mips/jazz/jazzdma.c @@ -16,8 +16,7 @@ #include <linux/memblock.h> #include <linux/spinlock.h> #include <linux/gfp.h> -#include <linux/dma-direct.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <asm/mipsregs.h> #include <asm/jazz.h> #include <asm/io.h> @@ -210,76 +209,6 @@ int vdma_free(unsigned long laddr) EXPORT_SYMBOL(vdma_free); /* - * Map certain page(s) to another physical address. - * Caller must have allocated the page(s) before. - */ -int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size) -{ - int first, pages; - - if (laddr > 0xffffff) { - if (vdma_debug) - printk - ("vdma_map: Invalid logical address: %08lx\n", - laddr); - return -EINVAL; /* invalid logical address */ - } - if (paddr > 0x1fffffff) { - if (vdma_debug) - printk - ("vdma_map: Invalid physical address: %08lx\n", - paddr); - return -EINVAL; /* invalid physical address */ - } - - pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1; - first = laddr >> 12; - if (vdma_debug) - printk("vdma_remap: first=%x, pages=%x\n", first, pages); - if (first + pages > VDMA_PGTBL_ENTRIES) { - if (vdma_debug) - printk("vdma_alloc: Invalid size: %08lx\n", size); - return -EINVAL; - } - - paddr &= ~(VDMA_PAGESIZE - 1); - while (pages > 0 && first < VDMA_PGTBL_ENTRIES) { - if (pgtbl[first].owner != laddr) { - if (vdma_debug) - printk("Trying to remap other's pages.\n"); - return -EPERM; /* not owner */ - } - pgtbl[first].frame = paddr; - paddr += VDMA_PAGESIZE; - first++; - pages--; - } - - /* - * Update translation table - */ - r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0); - - if (vdma_debug > 2) { - int i; - pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1; - first = laddr >> 12; - printk("LADDR: "); - for (i = first; i < first + pages; i++) - printk("%08x ", i << 12); - printk("\nPADDR: "); - for (i = first; i < first + pages; i++) - printk("%08x ", pgtbl[i].frame); - printk("\nOWNER: "); - for (i = first; i < first + pages; i++) - printk("%08x ", pgtbl[i].owner); - printk("\n"); - } - - return 0; -} - -/* * Translate a physical address to a logical address. * This will return the logical address of the first * match. @@ -562,26 +491,34 @@ int vdma_get_enable(int channel) static void *jazz_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) { + struct page *page; void *ret; - ret = dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs); - if (!ret) - return NULL; + if (attrs & DMA_ATTR_NO_WARN) + gfp |= __GFP_NOWARN; - *dma_handle = vdma_alloc(virt_to_phys(ret), size); - if (*dma_handle == DMA_MAPPING_ERROR) { - dma_direct_free_pages(dev, size, ret, *dma_handle, attrs); + size = PAGE_ALIGN(size); + page = alloc_pages(gfp, get_order(size)); + if (!page) return NULL; - } - - return ret; + ret = page_address(page); + memset(ret, 0, size); + *dma_handle = vdma_alloc(virt_to_phys(ret), size); + if (*dma_handle == DMA_MAPPING_ERROR) + goto out_free_pages; + arch_dma_prep_coherent(page, size); + return (void *)(UNCAC_BASE + __pa(ret)); + +out_free_pages: + __free_pages(page, get_order(size)); + return NULL; } static void jazz_dma_free(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle, unsigned long attrs) { vdma_free(dma_handle); - dma_direct_free_pages(dev, size, vaddr, dma_handle, attrs); + __free_pages(virt_to_page(vaddr), get_order(size)); } static dma_addr_t jazz_dma_map_page(struct device *dev, struct page *page, @@ -678,9 +615,9 @@ const struct dma_map_ops jazz_dma_ops = { .sync_single_for_device = jazz_dma_sync_single_for_device, .sync_sg_for_cpu = jazz_dma_sync_sg_for_cpu, .sync_sg_for_device = jazz_dma_sync_sg_for_device, - .dma_supported = dma_direct_supported, - .cache_sync = arch_dma_cache_sync, .mmap = dma_common_mmap, .get_sgtable = dma_common_get_sgtable, + .alloc_pages = dma_common_alloc_pages, + .free_pages = dma_common_free_pages, }; EXPORT_SYMBOL(jazz_dma_ops); diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile deleted file mode 100644 index f96c0f5eca44..000000000000 --- a/arch/mips/jz4740/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for the Ingenic JZ4740. -# - -# Object file lists. -obj-y += setup.o - -CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt diff --git a/arch/mips/jz4740/Platform b/arch/mips/jz4740/Platform deleted file mode 100644 index bd35d0621b13..000000000000 --- a/arch/mips/jz4740/Platform +++ /dev/null @@ -1,3 +0,0 @@ -cflags-$(CONFIG_MACH_INGENIC) += -I$(srctree)/arch/mips/include/asm/mach-jz4740 -load-$(CONFIG_MACH_INGENIC) += 0xffffffff80010000 -zload-$(CONFIG_MACH_INGENIC) += 0xffffffff81000000 diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c deleted file mode 100644 index 51d906325ce6..000000000000 --- a/arch/mips/jz4740/setup.c +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> - * Copyright (C) 2011, Maarten ter Huurne <maarten@treewalker.org> - * JZ4740 setup code - */ - -#include <linux/clocksource.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/irqchip.h> -#include <linux/kernel.h> -#include <linux/libfdt.h> -#include <linux/of_clk.h> -#include <linux/of_fdt.h> -#include <linux/pm.h> -#include <linux/sizes.h> -#include <linux/suspend.h> - -#include <asm/bootinfo.h> -#include <asm/fw/fw.h> -#include <asm/prom.h> -#include <asm/reboot.h> -#include <asm/time.h> - -static unsigned long __init get_board_mach_type(const void *fdt) -{ - if (!fdt_node_check_compatible(fdt, 0, "ingenic,x2000")) - return MACH_INGENIC_X2000; - if (!fdt_node_check_compatible(fdt, 0, "ingenic,x1830")) - return MACH_INGENIC_X1830; - if (!fdt_node_check_compatible(fdt, 0, "ingenic,x1000")) - return MACH_INGENIC_X1000; - if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4780")) - return MACH_INGENIC_JZ4780; - if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4770")) - return MACH_INGENIC_JZ4770; - if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4725b")) - return MACH_INGENIC_JZ4725B; - - return MACH_INGENIC_JZ4740; -} - -void __init plat_mem_setup(void) -{ - void *dtb = (void *)fw_passed_dtb; - - __dt_setup_arch(dtb); - - /* - * Old devicetree files for the qi,lb60 board did not have a /memory - * node. Hardcode the memory info here. - */ - if (!fdt_node_check_compatible(dtb, 0, "qi,lb60") && - fdt_path_offset(dtb, "/memory") < 0) - early_init_dt_add_memory_arch(0, SZ_32M); - - mips_machtype = get_board_mach_type(dtb); -} - -void __init device_tree_init(void) -{ - if (!initial_boot_params) - return; - - unflatten_and_copy_device_tree(); -} - -const char *get_system_type(void) -{ - switch (mips_machtype) { - case MACH_INGENIC_X2000: - return "X2000"; - case MACH_INGENIC_X1830: - return "X1830"; - case MACH_INGENIC_X1000: - return "X1000"; - case MACH_INGENIC_JZ4780: - return "JZ4780"; - case MACH_INGENIC_JZ4770: - return "JZ4770"; - case MACH_INGENIC_JZ4725B: - return "JZ4725B"; - default: - return "JZ4740"; - } -} - -void __init arch_init_irq(void) -{ - irqchip_init(); -} - -void __init plat_time_init(void) -{ - of_clk_init(NULL); - timer_probe(); -} - -void __init prom_init(void) -{ - fw_init_cmdline(); -} - -void __init prom_free_prom_memory(void) -{ -} - -static void jz4740_wait_instr(void) -{ - __asm__(".set push;\n" - ".set mips3;\n" - "wait;\n" - ".set pop;\n" - ); -} - -static void jz4740_halt(void) -{ - for (;;) - jz4740_wait_instr(); -} - -static int __maybe_unused jz4740_pm_enter(suspend_state_t state) -{ - jz4740_wait_instr(); - - return 0; -} - -static const struct platform_suspend_ops jz4740_pm_ops __maybe_unused = { - .valid = suspend_valid_only_mem, - .enter = jz4740_pm_enter, -}; - -static int __init jz4740_pm_init(void) -{ - if (IS_ENABLED(CONFIG_PM_SLEEP)) - suspend_set_ops(&jz4740_pm_ops); - _machine_halt = jz4740_halt; - - return 0; - -} -late_initcall(jz4740_pm_init); diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 13a26d254829..2a05b923f579 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -5,11 +5,17 @@ extra-y := head.o vmlinux.lds -obj-y += cmpxchg.o cpu-probe.o branch.o elf.o entry.o genex.o idle.o irq.o \ +obj-y += branch.o cmpxchg.o elf.o entry.o genex.o idle.o irq.o \ process.o prom.o ptrace.o reset.o setup.o signal.o \ syscall.o time.o topology.o traps.o unaligned.o watch.o \ vdso.o cacheinfo.o +ifdef CONFIG_CPU_R3K_TLB +obj-y += cpu-r3k-probe.o +else +obj-y += cpu-probe.o +endif + ifdef CONFIG_FUNCTION_TRACER CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_early_printk.o = -pg @@ -42,6 +48,7 @@ sw-$(CONFIG_CPU_TX39XX) := r2300_switch.o sw-$(CONFIG_CPU_CAVIUM_OCTEON) := octeon_switch.o obj-y += $(sw-y) +obj-$(CONFIG_MIPS_FP_SUPPORT) += fpu-probe.o obj-$(CONFIG_CPU_R2300_FPU) += r2300_fpu.o obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index fb3e203698ea..0216ff24c392 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -20,6 +20,8 @@ #include <asm/ptrace.h> #include <linux/uaccess.h> +#include "probes-common.h" + /* * Calculate and return exception PC in case of branch delay slot * for microMIPS and MIPS16e. It does not clear the ISA mode bit. diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index e2955f1f6316..e6853697a056 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -28,336 +28,14 @@ #include <asm/spram.h> #include <linux/uaccess.h> +#include "fpu-probe.h" + #include <asm/mach-loongson64/cpucfg-emul.h> /* Hardware capabilities */ unsigned int elf_hwcap __read_mostly; EXPORT_SYMBOL_GPL(elf_hwcap); -#ifdef CONFIG_MIPS_FP_SUPPORT - -/* - * Get the FPU Implementation/Revision. - */ -static inline unsigned long cpu_get_fpu_id(void) -{ - unsigned long tmp, fpu_id; - - tmp = read_c0_status(); - __enable_fpu(FPU_AS_IS); - fpu_id = read_32bit_cp1_register(CP1_REVISION); - write_c0_status(tmp); - return fpu_id; -} - -/* - * Check if the CPU has an external FPU. - */ -static inline int __cpu_has_fpu(void) -{ - return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE; -} - -/* - * Determine the FCSR mask for FPU hardware. - */ -static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c) -{ - unsigned long sr, mask, fcsr, fcsr0, fcsr1; - - fcsr = c->fpu_csr31; - mask = FPU_CSR_ALL_X | FPU_CSR_ALL_E | FPU_CSR_ALL_S | FPU_CSR_RM; - - sr = read_c0_status(); - __enable_fpu(FPU_AS_IS); - - fcsr0 = fcsr & mask; - write_32bit_cp1_register(CP1_STATUS, fcsr0); - fcsr0 = read_32bit_cp1_register(CP1_STATUS); - - fcsr1 = fcsr | ~mask; - write_32bit_cp1_register(CP1_STATUS, fcsr1); - fcsr1 = read_32bit_cp1_register(CP1_STATUS); - - write_32bit_cp1_register(CP1_STATUS, fcsr); - - write_c0_status(sr); - - c->fpu_msk31 = ~(fcsr0 ^ fcsr1) & ~mask; -} - -/* - * Determine the IEEE 754 NaN encodings and ABS.fmt/NEG.fmt execution modes - * supported by FPU hardware. - */ -static void cpu_set_fpu_2008(struct cpuinfo_mips *c) -{ - if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 | - MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | - MIPS_CPU_ISA_M32R5 | MIPS_CPU_ISA_M64R5 | - MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) { - unsigned long sr, fir, fcsr, fcsr0, fcsr1; - - sr = read_c0_status(); - __enable_fpu(FPU_AS_IS); - - fir = read_32bit_cp1_register(CP1_REVISION); - if (fir & MIPS_FPIR_HAS2008) { - fcsr = read_32bit_cp1_register(CP1_STATUS); - - /* - * MAC2008 toolchain never landed in real world, so we're only - * testing wether it can be disabled and don't try to enabled - * it. - */ - fcsr0 = fcsr & ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008 | FPU_CSR_MAC2008); - write_32bit_cp1_register(CP1_STATUS, fcsr0); - fcsr0 = read_32bit_cp1_register(CP1_STATUS); - - fcsr1 = fcsr | FPU_CSR_ABS2008 | FPU_CSR_NAN2008; - write_32bit_cp1_register(CP1_STATUS, fcsr1); - fcsr1 = read_32bit_cp1_register(CP1_STATUS); - - write_32bit_cp1_register(CP1_STATUS, fcsr); - - if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2)) { - /* - * The bit for MAC2008 might be reused by R6 in future, - * so we only test for R2-R5. - */ - if (fcsr0 & FPU_CSR_MAC2008) - c->options |= MIPS_CPU_MAC_2008_ONLY; - } - - if (!(fcsr0 & FPU_CSR_NAN2008)) - c->options |= MIPS_CPU_NAN_LEGACY; - if (fcsr1 & FPU_CSR_NAN2008) - c->options |= MIPS_CPU_NAN_2008; - - if ((fcsr0 ^ fcsr1) & FPU_CSR_ABS2008) - c->fpu_msk31 &= ~FPU_CSR_ABS2008; - else - c->fpu_csr31 |= fcsr & FPU_CSR_ABS2008; - - if ((fcsr0 ^ fcsr1) & FPU_CSR_NAN2008) - c->fpu_msk31 &= ~FPU_CSR_NAN2008; - else - c->fpu_csr31 |= fcsr & FPU_CSR_NAN2008; - } else { - c->options |= MIPS_CPU_NAN_LEGACY; - } - - write_c0_status(sr); - } else { - c->options |= MIPS_CPU_NAN_LEGACY; - } -} - -/* - * IEEE 754 conformance mode to use. Affects the NaN encoding and the - * ABS.fmt/NEG.fmt execution mode. - */ -static enum { STRICT, LEGACY, STD2008, RELAXED } ieee754 = STRICT; - -/* - * Set the IEEE 754 NaN encodings and the ABS.fmt/NEG.fmt execution modes - * to support by the FPU emulator according to the IEEE 754 conformance - * mode selected. Note that "relaxed" straps the emulator so that it - * allows 2008-NaN binaries even for legacy processors. - */ -static void cpu_set_nofpu_2008(struct cpuinfo_mips *c) -{ - c->options &= ~(MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY); - c->fpu_csr31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008); - c->fpu_msk31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008); - - switch (ieee754) { - case STRICT: - if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 | - MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | - MIPS_CPU_ISA_M32R5 | MIPS_CPU_ISA_M64R5 | - MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) { - c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY; - } else { - c->options |= MIPS_CPU_NAN_LEGACY; - c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008; - } - break; - case LEGACY: - c->options |= MIPS_CPU_NAN_LEGACY; - c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008; - break; - case STD2008: - c->options |= MIPS_CPU_NAN_2008; - c->fpu_csr31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008; - c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008; - break; - case RELAXED: - c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY; - break; - } -} - -/* - * Override the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode - * according to the "ieee754=" parameter. - */ -static void cpu_set_nan_2008(struct cpuinfo_mips *c) -{ - switch (ieee754) { - case STRICT: - mips_use_nan_legacy = !!cpu_has_nan_legacy; - mips_use_nan_2008 = !!cpu_has_nan_2008; - break; - case LEGACY: - mips_use_nan_legacy = !!cpu_has_nan_legacy; - mips_use_nan_2008 = !cpu_has_nan_legacy; - break; - case STD2008: - mips_use_nan_legacy = !cpu_has_nan_2008; - mips_use_nan_2008 = !!cpu_has_nan_2008; - break; - case RELAXED: - mips_use_nan_legacy = true; - mips_use_nan_2008 = true; - break; - } -} - -/* - * IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode override - * settings: - * - * strict: accept binaries that request a NaN encoding supported by the FPU - * legacy: only accept legacy-NaN binaries - * 2008: only accept 2008-NaN binaries - * relaxed: accept any binaries regardless of whether supported by the FPU - */ -static int __init ieee754_setup(char *s) -{ - if (!s) - return -1; - else if (!strcmp(s, "strict")) - ieee754 = STRICT; - else if (!strcmp(s, "legacy")) - ieee754 = LEGACY; - else if (!strcmp(s, "2008")) - ieee754 = STD2008; - else if (!strcmp(s, "relaxed")) - ieee754 = RELAXED; - else - return -1; - - if (!(boot_cpu_data.options & MIPS_CPU_FPU)) - cpu_set_nofpu_2008(&boot_cpu_data); - cpu_set_nan_2008(&boot_cpu_data); - - return 0; -} - -early_param("ieee754", ieee754_setup); - -/* - * Set the FIR feature flags for the FPU emulator. - */ -static void cpu_set_nofpu_id(struct cpuinfo_mips *c) -{ - u32 value; - - value = 0; - if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 | - MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | - MIPS_CPU_ISA_M32R5 | MIPS_CPU_ISA_M64R5 | - MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) - value |= MIPS_FPIR_D | MIPS_FPIR_S; - if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | - MIPS_CPU_ISA_M32R5 | MIPS_CPU_ISA_M64R5 | - MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) - value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W; - if (c->options & MIPS_CPU_NAN_2008) - value |= MIPS_FPIR_HAS2008; - c->fpu_id = value; -} - -/* Determined FPU emulator mask to use for the boot CPU with "nofpu". */ -static unsigned int mips_nofpu_msk31; - -/* - * Set options for FPU hardware. - */ -static void cpu_set_fpu_opts(struct cpuinfo_mips *c) -{ - c->fpu_id = cpu_get_fpu_id(); - mips_nofpu_msk31 = c->fpu_msk31; - - if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 | - MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | - MIPS_CPU_ISA_M32R5 | MIPS_CPU_ISA_M64R5 | - MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) { - if (c->fpu_id & MIPS_FPIR_3D) - c->ases |= MIPS_ASE_MIPS3D; - if (c->fpu_id & MIPS_FPIR_UFRP) - c->options |= MIPS_CPU_UFR; - if (c->fpu_id & MIPS_FPIR_FREP) - c->options |= MIPS_CPU_FRE; - } - - cpu_set_fpu_fcsr_mask(c); - cpu_set_fpu_2008(c); - cpu_set_nan_2008(c); -} - -/* - * Set options for the FPU emulator. - */ -static void cpu_set_nofpu_opts(struct cpuinfo_mips *c) -{ - c->options &= ~MIPS_CPU_FPU; - c->fpu_msk31 = mips_nofpu_msk31; - - cpu_set_nofpu_2008(c); - cpu_set_nan_2008(c); - cpu_set_nofpu_id(c); -} - -static int mips_fpu_disabled; - -static int __init fpu_disable(char *s) -{ - cpu_set_nofpu_opts(&boot_cpu_data); - mips_fpu_disabled = 1; - - return 1; -} - -__setup("nofpu", fpu_disable); - -#else /* !CONFIG_MIPS_FP_SUPPORT */ - -#define mips_fpu_disabled 1 - -static inline unsigned long cpu_get_fpu_id(void) -{ - return FPIR_IMP_NONE; -} - -static inline int __cpu_has_fpu(void) -{ - return 0; -} - -static void cpu_set_fpu_opts(struct cpuinfo_mips *c) -{ - /* no-op */ -} - -static void cpu_set_nofpu_opts(struct cpuinfo_mips *c) -{ - /* no-op */ -} - -#endif /* CONFIG_MIPS_FP_SUPPORT */ - static inline unsigned long cpu_get_msa_id(void) { unsigned long status, msa_id; @@ -1600,8 +1278,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | - MIPS_CPU_LLSC | MIPS_CPU_BP_GHIST; + MIPS_CPU_LLSC; c->tlbsize = 64; + write_c0_r10k_diag(read_c0_r10k_diag() | R10K_DIAG_E_GHIST); break; case PRID_IMP_R14000: if (((c->processor_id >> 4) & 0x0f) > 2) { @@ -1615,8 +1294,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | - MIPS_CPU_LLSC | MIPS_CPU_BP_GHIST; + MIPS_CPU_LLSC; c->tlbsize = 64; + write_c0_r10k_diag(read_c0_r10k_diag() | R10K_DIAG_E_GHIST); break; case PRID_IMP_LOONGSON_64C: /* Loongson-2/3 */ switch (c->processor_id & PRID_REV_MASK) { @@ -2123,7 +1803,10 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) /* XBurst does not implement the CP0 counter. */ c->options &= ~MIPS_CPU_COUNTER; - BUG_ON(!__builtin_constant_p(cpu_has_counter) || cpu_has_counter); + BUG_ON(__builtin_constant_p(cpu_has_counter) && cpu_has_counter); + + /* XBurst has virtually tagged icache */ + c->icache.flags |= MIPS_CACHE_VTAG; switch (c->processor_id & PRID_IMP_MASK) { @@ -2169,8 +1852,9 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) /* XBurst®1 with MXU2.0 SIMD ISA */ case PRID_IMP_XBURST_REV2: + /* Ingenic uses the WA bit to achieve write-combine memory writes */ + c->writecombine = _CACHE_CACHABLE_WA; c->cputype = CPU_XBURST; - c->writecombine = _CACHE_UNCACHED_ACCELERATED; __cpu_name[cpu] = "Ingenic XBurst"; break; @@ -2372,10 +2056,6 @@ void cpu_probe(void) else cpu_set_nofpu_opts(c); - if (cpu_has_bp_ghist) - write_c0_r10k_diag(read_c0_r10k_diag() | - R10K_DIAG_E_GHIST); - if (cpu_has_mips_r2_r6) { c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1; /* R2 has Performance Counter Interrupt indicator */ diff --git a/arch/mips/kernel/cpu-r3k-probe.c b/arch/mips/kernel/cpu-r3k-probe.c new file mode 100644 index 000000000000..abdbbe8c5a43 --- /dev/null +++ b/arch/mips/kernel/cpu-r3k-probe.c @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Processor capabilities determination functions. + * + * Copyright (C) xxxx the Anonymous + * Copyright (C) 1994 - 2006 Ralf Baechle + * Copyright (C) 2003, 2004 Maciej W. Rozycki + * Copyright (C) 2001, 2004, 2011, 2012 MIPS Technologies, Inc. + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/ptrace.h> +#include <linux/smp.h> +#include <linux/stddef.h> +#include <linux/export.h> + +#include <asm/bugs.h> +#include <asm/cpu.h> +#include <asm/cpu-features.h> +#include <asm/cpu-type.h> +#include <asm/fpu.h> +#include <asm/mipsregs.h> +#include <asm/elf.h> + +#include "fpu-probe.h" + +/* Hardware capabilities */ +unsigned int elf_hwcap __read_mostly; +EXPORT_SYMBOL_GPL(elf_hwcap); + +void __init check_bugs32(void) +{ + +} + +/* + * Probe whether cpu has config register by trying to play with + * alternate cache bit and see whether it matters. + * It's used by cpu_probe to distinguish between R3000A and R3081. + */ +static inline int cpu_has_confreg(void) +{ +#ifdef CONFIG_CPU_R3000 + extern unsigned long r3k_cache_size(unsigned long); + unsigned long size1, size2; + unsigned long cfg = read_c0_conf(); + + size1 = r3k_cache_size(ST0_ISC); + write_c0_conf(cfg ^ R30XX_CONF_AC); + size2 = r3k_cache_size(ST0_ISC); + write_c0_conf(cfg); + return size1 != size2; +#else + return 0; +#endif +} + +static inline void set_elf_platform(int cpu, const char *plat) +{ + if (cpu == 0) + __elf_platform = plat; +} + +const char *__cpu_name[NR_CPUS]; +const char *__elf_platform; +const char *__elf_base_platform; + +void cpu_probe(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int cpu = smp_processor_id(); + + /* + * Set a default elf platform, cpu probe may later + * overwrite it with a more precise value + */ + set_elf_platform(cpu, "mips"); + + c->processor_id = PRID_IMP_UNKNOWN; + c->fpu_id = FPIR_IMP_NONE; + c->cputype = CPU_UNKNOWN; + c->writecombine = _CACHE_UNCACHED; + + c->fpu_csr31 = FPU_CSR_RN; + c->fpu_msk31 = FPU_CSR_RSVD | FPU_CSR_ABS2008 | FPU_CSR_NAN2008 | + FPU_CSR_CONDX | FPU_CSR_FS; + + c->srsets = 1; + + c->processor_id = read_c0_prid(); + switch (c->processor_id & (PRID_COMP_MASK | PRID_IMP_MASK)) { + case PRID_COMP_LEGACY | PRID_IMP_R2000: + c->cputype = CPU_R2000; + __cpu_name[cpu] = "R2000"; + c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | + MIPS_CPU_NOFPUEX; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; + break; + case PRID_COMP_LEGACY | PRID_IMP_R3000: + if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A) { + if (cpu_has_confreg()) { + c->cputype = CPU_R3081E; + __cpu_name[cpu] = "R3081"; + } else { + c->cputype = CPU_R3000A; + __cpu_name[cpu] = "R3000A"; + } + } else { + c->cputype = CPU_R3000; + __cpu_name[cpu] = "R3000"; + } + c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | + MIPS_CPU_NOFPUEX; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; + break; + case PRID_COMP_LEGACY | PRID_IMP_TX39: + c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE; + + if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { + c->cputype = CPU_TX3927; + __cpu_name[cpu] = "TX3927"; + c->tlbsize = 64; + } else { + switch (c->processor_id & PRID_REV_MASK) { + case PRID_REV_TX3912: + c->cputype = CPU_TX3912; + __cpu_name[cpu] = "TX3912"; + c->tlbsize = 32; + break; + case PRID_REV_TX3922: + c->cputype = CPU_TX3922; + __cpu_name[cpu] = "TX3922"; + c->tlbsize = 64; + break; + } + } + break; + } + + BUG_ON(!__cpu_name[cpu]); + BUG_ON(c->cputype == CPU_UNKNOWN); + + /* + * Platform code can force the cpu type to optimize code + * generation. In that case be sure the cpu type is correctly + * manually setup otherwise it could trigger some nasty bugs. + */ + BUG_ON(current_cpu_type() != c->cputype); + + if (mips_fpu_disabled) + c->options &= ~MIPS_CPU_FPU; + + if (c->options & MIPS_CPU_FPU) + cpu_set_fpu_opts(c); + else + cpu_set_nofpu_opts(c); +} + +void cpu_report(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + pr_info("CPU%d revision is: %08x (%s)\n", + smp_processor_id(), c->processor_id, cpu_name_string()); + if (c->options & MIPS_CPU_FPU) + pr_info("FPU revision is: %08x\n", c->fpu_id); +} diff --git a/arch/mips/kernel/fpu-probe.c b/arch/mips/kernel/fpu-probe.c new file mode 100644 index 000000000000..e689d6a83234 --- /dev/null +++ b/arch/mips/kernel/fpu-probe.c @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Processor capabilities determination functions. + * + * Copyright (C) xxxx the Anonymous + * Copyright (C) 1994 - 2006 Ralf Baechle + * Copyright (C) 2003, 2004 Maciej W. Rozycki + * Copyright (C) 2001, 2004, 2011, 2012 MIPS Technologies, Inc. + */ + +#include <linux/init.h> +#include <linux/kernel.h> + +#include <asm/bugs.h> +#include <asm/cpu.h> +#include <asm/cpu-features.h> +#include <asm/cpu-type.h> +#include <asm/elf.h> +#include <asm/fpu.h> +#include <asm/mipsregs.h> + +#include "fpu-probe.h" + +/* + * Get the FPU Implementation/Revision. + */ +static inline unsigned long cpu_get_fpu_id(void) +{ + unsigned long tmp, fpu_id; + + tmp = read_c0_status(); + __enable_fpu(FPU_AS_IS); + fpu_id = read_32bit_cp1_register(CP1_REVISION); + write_c0_status(tmp); + return fpu_id; +} + +/* + * Check if the CPU has an external FPU. + */ +int __cpu_has_fpu(void) +{ + return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE; +} + +/* + * Determine the FCSR mask for FPU hardware. + */ +static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c) +{ + unsigned long sr, mask, fcsr, fcsr0, fcsr1; + + fcsr = c->fpu_csr31; + mask = FPU_CSR_ALL_X | FPU_CSR_ALL_E | FPU_CSR_ALL_S | FPU_CSR_RM; + + sr = read_c0_status(); + __enable_fpu(FPU_AS_IS); + + fcsr0 = fcsr & mask; + write_32bit_cp1_register(CP1_STATUS, fcsr0); + fcsr0 = read_32bit_cp1_register(CP1_STATUS); + + fcsr1 = fcsr | ~mask; + write_32bit_cp1_register(CP1_STATUS, fcsr1); + fcsr1 = read_32bit_cp1_register(CP1_STATUS); + + write_32bit_cp1_register(CP1_STATUS, fcsr); + + write_c0_status(sr); + + c->fpu_msk31 = ~(fcsr0 ^ fcsr1) & ~mask; +} + +/* + * Determine the IEEE 754 NaN encodings and ABS.fmt/NEG.fmt execution modes + * supported by FPU hardware. + */ +static void cpu_set_fpu_2008(struct cpuinfo_mips *c) +{ + if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 | + MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | + MIPS_CPU_ISA_M32R5 | MIPS_CPU_ISA_M64R5 | + MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) { + unsigned long sr, fir, fcsr, fcsr0, fcsr1; + + sr = read_c0_status(); + __enable_fpu(FPU_AS_IS); + + fir = read_32bit_cp1_register(CP1_REVISION); + if (fir & MIPS_FPIR_HAS2008) { + fcsr = read_32bit_cp1_register(CP1_STATUS); + + /* + * MAC2008 toolchain never landed in real world, so + * we're only testing whether it can be disabled and + * don't try to enabled it. + */ + fcsr0 = fcsr & ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008 | + FPU_CSR_MAC2008); + write_32bit_cp1_register(CP1_STATUS, fcsr0); + fcsr0 = read_32bit_cp1_register(CP1_STATUS); + + fcsr1 = fcsr | FPU_CSR_ABS2008 | FPU_CSR_NAN2008; + write_32bit_cp1_register(CP1_STATUS, fcsr1); + fcsr1 = read_32bit_cp1_register(CP1_STATUS); + + write_32bit_cp1_register(CP1_STATUS, fcsr); + + if (c->isa_level & (MIPS_CPU_ISA_M32R2 | + MIPS_CPU_ISA_M64R2)) { + /* + * The bit for MAC2008 might be reused by R6 + * in future, so we only test for R2-R5. + */ + if (fcsr0 & FPU_CSR_MAC2008) + c->options |= MIPS_CPU_MAC_2008_ONLY; + } + + if (!(fcsr0 & FPU_CSR_NAN2008)) + c->options |= MIPS_CPU_NAN_LEGACY; + if (fcsr1 & FPU_CSR_NAN2008) + c->options |= MIPS_CPU_NAN_2008; + + if ((fcsr0 ^ fcsr1) & FPU_CSR_ABS2008) + c->fpu_msk31 &= ~FPU_CSR_ABS2008; + else + c->fpu_csr31 |= fcsr & FPU_CSR_ABS2008; + + if ((fcsr0 ^ fcsr1) & FPU_CSR_NAN2008) + c->fpu_msk31 &= ~FPU_CSR_NAN2008; + else + c->fpu_csr31 |= fcsr & FPU_CSR_NAN2008; + } else { + c->options |= MIPS_CPU_NAN_LEGACY; + } + + write_c0_status(sr); + } else { + c->options |= MIPS_CPU_NAN_LEGACY; + } +} + +/* + * IEEE 754 conformance mode to use. Affects the NaN encoding and the + * ABS.fmt/NEG.fmt execution mode. + */ +static enum { STRICT, LEGACY, STD2008, RELAXED } ieee754 = STRICT; + +/* + * Set the IEEE 754 NaN encodings and the ABS.fmt/NEG.fmt execution modes + * to support by the FPU emulator according to the IEEE 754 conformance + * mode selected. Note that "relaxed" straps the emulator so that it + * allows 2008-NaN binaries even for legacy processors. + */ +static void cpu_set_nofpu_2008(struct cpuinfo_mips *c) +{ + c->options &= ~(MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY); + c->fpu_csr31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008); + c->fpu_msk31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008); + + switch (ieee754) { + case STRICT: + if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 | + MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | + MIPS_CPU_ISA_M32R5 | MIPS_CPU_ISA_M64R5 | + MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) { + c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY; + } else { + c->options |= MIPS_CPU_NAN_LEGACY; + c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008; + } + break; + case LEGACY: + c->options |= MIPS_CPU_NAN_LEGACY; + c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008; + break; + case STD2008: + c->options |= MIPS_CPU_NAN_2008; + c->fpu_csr31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008; + c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008; + break; + case RELAXED: + c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY; + break; + } +} + +/* + * Override the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode + * according to the "ieee754=" parameter. + */ +static void cpu_set_nan_2008(struct cpuinfo_mips *c) +{ + switch (ieee754) { + case STRICT: + mips_use_nan_legacy = !!cpu_has_nan_legacy; + mips_use_nan_2008 = !!cpu_has_nan_2008; + break; + case LEGACY: + mips_use_nan_legacy = !!cpu_has_nan_legacy; + mips_use_nan_2008 = !cpu_has_nan_legacy; + break; + case STD2008: + mips_use_nan_legacy = !cpu_has_nan_2008; + mips_use_nan_2008 = !!cpu_has_nan_2008; + break; + case RELAXED: + mips_use_nan_legacy = true; + mips_use_nan_2008 = true; + break; + } +} + +/* + * IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode override + * settings: + * + * strict: accept binaries that request a NaN encoding supported by the FPU + * legacy: only accept legacy-NaN binaries + * 2008: only accept 2008-NaN binaries + * relaxed: accept any binaries regardless of whether supported by the FPU + */ +static int __init ieee754_setup(char *s) +{ + if (!s) + return -1; + else if (!strcmp(s, "strict")) + ieee754 = STRICT; + else if (!strcmp(s, "legacy")) + ieee754 = LEGACY; + else if (!strcmp(s, "2008")) + ieee754 = STD2008; + else if (!strcmp(s, "relaxed")) + ieee754 = RELAXED; + else + return -1; + + if (!(boot_cpu_data.options & MIPS_CPU_FPU)) + cpu_set_nofpu_2008(&boot_cpu_data); + cpu_set_nan_2008(&boot_cpu_data); + + return 0; +} + +early_param("ieee754", ieee754_setup); + +/* + * Set the FIR feature flags for the FPU emulator. + */ +static void cpu_set_nofpu_id(struct cpuinfo_mips *c) +{ + u32 value; + + value = 0; + if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 | + MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | + MIPS_CPU_ISA_M32R5 | MIPS_CPU_ISA_M64R5 | + MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) + value |= MIPS_FPIR_D | MIPS_FPIR_S; + if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | + MIPS_CPU_ISA_M32R5 | MIPS_CPU_ISA_M64R5 | + MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) + value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W; + if (c->options & MIPS_CPU_NAN_2008) + value |= MIPS_FPIR_HAS2008; + c->fpu_id = value; +} + +/* Determined FPU emulator mask to use for the boot CPU with "nofpu". */ +static unsigned int mips_nofpu_msk31; + +/* + * Set options for FPU hardware. + */ +void cpu_set_fpu_opts(struct cpuinfo_mips *c) +{ + c->fpu_id = cpu_get_fpu_id(); + mips_nofpu_msk31 = c->fpu_msk31; + + if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 | + MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 | + MIPS_CPU_ISA_M32R5 | MIPS_CPU_ISA_M64R5 | + MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) { + if (c->fpu_id & MIPS_FPIR_3D) + c->ases |= MIPS_ASE_MIPS3D; + if (c->fpu_id & MIPS_FPIR_UFRP) + c->options |= MIPS_CPU_UFR; + if (c->fpu_id & MIPS_FPIR_FREP) + c->options |= MIPS_CPU_FRE; + } + + cpu_set_fpu_fcsr_mask(c); + cpu_set_fpu_2008(c); + cpu_set_nan_2008(c); +} + +/* + * Set options for the FPU emulator. + */ +void cpu_set_nofpu_opts(struct cpuinfo_mips *c) +{ + c->options &= ~MIPS_CPU_FPU; + c->fpu_msk31 = mips_nofpu_msk31; + + cpu_set_nofpu_2008(c); + cpu_set_nan_2008(c); + cpu_set_nofpu_id(c); +} + +int mips_fpu_disabled; + +static int __init fpu_disable(char *s) +{ + cpu_set_nofpu_opts(&boot_cpu_data); + mips_fpu_disabled = 1; + + return 1; +} + +__setup("nofpu", fpu_disable); + diff --git a/arch/mips/kernel/fpu-probe.h b/arch/mips/kernel/fpu-probe.h new file mode 100644 index 000000000000..951ce50890d0 --- /dev/null +++ b/arch/mips/kernel/fpu-probe.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <linux/kernel.h> + +#include <asm/cpu.h> +#include <asm/cpu-info.h> + +#ifdef CONFIG_MIPS_FP_SUPPORT + +extern int mips_fpu_disabled; + +int __cpu_has_fpu(void); +void cpu_set_fpu_opts(struct cpuinfo_mips *c); +void cpu_set_nofpu_opts(struct cpuinfo_mips *c); + +#else /* !CONFIG_MIPS_FP_SUPPORT */ + +#define mips_fpu_disabled 1 + +static inline unsigned long cpu_get_fpu_id(void) +{ + return FPIR_IMP_NONE; +} + +static inline int __cpu_has_fpu(void) +{ + return 0; +} + +static inline void cpu_set_fpu_opts(struct cpuinfo_mips *c) +{ + /* no-op */ +} + +static inline void cpu_set_nofpu_opts(struct cpuinfo_mips *c) +{ + /* no-op */ +} + +#endif /* CONFIG_MIPS_FP_SUPPORT */ diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 2625232bfe52..f57e68f40a34 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -37,10 +37,6 @@ void arch_ftrace_update_code(int command) ftrace_modify_all_code(command); } -#endif - -#ifdef CONFIG_DYNAMIC_FTRACE - #define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */ #define ADDR_MASK 0x03ffffff /* op_code|addr : 31...26|25 ....0 */ #define JUMP_RANGE_MASK ((1UL << 28) - 1) diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 7dd234e788e6..61b73580b877 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -35,7 +35,7 @@ .macro setup_c0_status set clr .set push mfc0 t0, CP0_STATUS - or t0, ST0_CU0|\set|0x1f|\clr + or t0, ST0_KERNEL_CUMASK|\set|0x1f|\clr xor t0, 0x1f|\clr mtc0 t0, CP0_STATUS .set noreorder diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c index d043c2f897fc..54dfba8fa77c 100644 --- a/arch/mips/kernel/kprobes.c +++ b/arch/mips/kernel/kprobes.c @@ -477,6 +477,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) { ri->ret_addr = (kprobe_opcode_t *) regs->regs[31]; + ri->fp = NULL; /* Replace the return addr with trampoline addr */ regs->regs[31] = (unsigned long)kretprobe_trampoline; @@ -488,57 +489,8 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, static int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *tmp; - unsigned long flags, orig_ret_address = 0; - unsigned long trampoline_address = (unsigned long)kretprobe_trampoline; - - INIT_HLIST_HEAD(&empty_rp); - kretprobe_hash_lock(current, &head, &flags); - - /* - * It is possible to have multiple instances associated with a given - * task either because an multiple functions in the call path - * have a return probe installed on them, and/or more than one return - * return probe was registered for a target function. - * - * We can handle this because: - * - instances are always inserted at the head of the list - * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the - * real return address, and all the rest will point to - * kretprobe_trampoline - */ - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - if (ri->rp && ri->rp->handler) - ri->rp->handler(ri, regs); - - orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_assert(ri, orig_ret_address, trampoline_address); - instruction_pointer(regs) = orig_ret_address; - - kretprobe_hash_unlock(current, &flags); - - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } + instruction_pointer(regs) = __kretprobe_trampoline_handler(regs, + kretprobe_trampoline, NULL); /* * By returning a non-zero value, we are telling * kprobe_handler() that we don't want the post_handler diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c index 1a08428eedcf..6c590ef27648 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -167,7 +167,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len, return -EINVAL; get_online_cpus(); - read_lock(&tasklist_lock); + rcu_read_lock(); retval = -ESRCH; p = find_process_by_pid(pid); @@ -181,7 +181,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len, cpumask_and(&mask, &allowed, cpu_active_mask); out_unlock: - read_unlock(&tasklist_lock); + rcu_read_unlock(); put_online_cpus(); if (retval) return retval; diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index f5dc316a826a..75ebd8d7bd5d 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -52,6 +52,7 @@ #include <asm/inst.h> #include <asm/stacktrace.h> #include <asm/irq_regs.h> +#include <asm/exec.h> #ifdef CONFIG_HOTPLUG_CPU void arch_cpu_idle_dead(void) @@ -68,7 +69,7 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) unsigned long status; /* New thread loses kernel privileges. */ - status = regs->cp0_status & ~(ST0_CU0|ST0_CU1|ST0_FR|KU_MASK); + status = regs->cp0_status & ~(ST0_CU0|ST0_CU1|ST0_CU2|ST0_FR|KU_MASK); status |= KU_USER; regs->cp0_status = status; lose_fpu(0); @@ -133,7 +134,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, childregs = (struct pt_regs *) childksp - 1; /* Put the stack after the struct pt_regs. */ childksp = (unsigned long) childregs; - p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1); + p->thread.cp0_status = (read_c0_status() & ~(ST0_CU2|ST0_CU1)) | ST0_KERNEL_CUMASK; if (unlikely(p->flags & PF_KTHREAD)) { /* kernel thread */ unsigned long status = p->thread.cp0_status; @@ -279,7 +280,21 @@ static inline int is_ra_save_ins(union mips_instruction *ip, int *poff) *poff = ip->i_format.simmediate / sizeof(ulong); return 1; } - +#ifdef CONFIG_CPU_LOONGSON64 + if ((ip->loongson3_lswc2_format.opcode == swc2_op) && + (ip->loongson3_lswc2_format.ls == 1) && + (ip->loongson3_lswc2_format.fr == 0) && + (ip->loongson3_lswc2_format.base == 29)) { + if (ip->loongson3_lswc2_format.rt == 31) { + *poff = ip->loongson3_lswc2_format.offset << 1; + return 1; + } + if (ip->loongson3_lswc2_format.rq == 31) { + *poff = (ip->loongson3_lswc2_format.offset << 1) + 1; + return 1; + } + } +#endif return 0; #endif } diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index 9e50dc8df2f6..6abebd57b218 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c @@ -36,31 +36,6 @@ char *mips_get_machine_name(void) } #ifdef CONFIG_USE_OF -void __init early_init_dt_add_memory_arch(u64 base, u64 size) -{ - if (base >= PHYS_ADDR_MAX) { - pr_warn("Trying to add an invalid memory region, skipped\n"); - return; - } - - /* Truncate the passed memory region instead of type casting */ - if (base + size - 1 >= PHYS_ADDR_MAX || base + size < base) { - pr_warn("Truncate memory region %llx @ %llx to size %llx\n", - size, base, PHYS_ADDR_MAX - base); - size = PHYS_ADDR_MAX - base; - } - - add_memory_region(base, size, BOOT_MEM_RAM); -} - -int __init early_init_dt_reserve_memory_arch(phys_addr_t base, - phys_addr_t size, bool nomap) -{ - add_memory_region(base, size, - nomap ? BOOT_MEM_NOMAP : BOOT_MEM_RESERVED); - - return 0; -} void __init __dt_setup_arch(void *bph) { diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index bf5f5acab0a8..0d4253208bde 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -24,7 +24,7 @@ #include <linux/kexec.h> #include <linux/sizes.h> #include <linux/device.h> -#include <linux/dma-contiguous.h> +#include <linux/dma-map-ops.h> #include <linux/decompress/generic.h> #include <linux/of_fdt.h> #include <linux/of_reserved_mem.h> @@ -44,7 +44,7 @@ #include <asm/prom.h> #ifdef CONFIG_MIPS_ELF_APPENDED_DTB -const char __section(.appended_dtb) __appended_dtb[0x100000]; +const char __section(".appended_dtb") __appended_dtb[0x100000]; #endif /* CONFIG_MIPS_ELF_APPENDED_DTB */ struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly; @@ -91,45 +91,6 @@ unsigned long ARCH_PFN_OFFSET; EXPORT_SYMBOL(ARCH_PFN_OFFSET); #endif -void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type) -{ - /* - * Note: This function only exists for historical reason, - * new code should use memblock_add or memblock_add_node instead. - */ - - /* - * If the region reaches the top of the physical address space, adjust - * the size slightly so that (start + size) doesn't overflow - */ - if (start + size - 1 == PHYS_ADDR_MAX) - --size; - - /* Sanity check */ - if (start + size < start) { - pr_warn("Trying to add an invalid memory region, skipped\n"); - return; - } - - if (start < PHYS_OFFSET) - return; - - memblock_add(start, size); - /* Reserve any memory except the ordinary RAM ranges. */ - switch (type) { - case BOOT_MEM_RAM: - break; - - case BOOT_MEM_NOMAP: /* Discard the range from the system. */ - memblock_remove(start, size); - break; - - default: /* Reserve the rest of the memory types at boot time */ - memblock_reserve(start, size); - break; - } -} - void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max) { void *dm = &detect_magic; @@ -146,7 +107,7 @@ void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_add ((unsigned long long) sz_min) / SZ_1M, ((unsigned long long) sz_max) / SZ_1M); - add_memory_region(start, size, BOOT_MEM_RAM); + memblock_add(start, size); } /* @@ -300,8 +261,9 @@ static void __init bootmem_init(void) static void __init bootmem_init(void) { - struct memblock_region *mem; phys_addr_t ramstart, ramend; + phys_addr_t start, end; + u64 i; ramstart = memblock_start_of_DRAM(); ramend = memblock_end_of_DRAM(); @@ -338,18 +300,13 @@ static void __init bootmem_init(void) min_low_pfn = ARCH_PFN_OFFSET; max_pfn = PFN_DOWN(ramend); - for_each_memblock(memory, mem) { - unsigned long start = memblock_region_memory_base_pfn(mem); - unsigned long end = memblock_region_memory_end_pfn(mem); - + for_each_mem_range(i, &start, &end) { /* * Skip highmem here so we get an accurate max_low_pfn if low * memory stops short of high memory. * If the region overlaps HIGHMEM_START, end is clipped so * max_pfn excludes the highmem portion. */ - if (memblock_is_nomap(mem)) - continue; if (start >= PFN_DOWN(HIGHMEM_START)) continue; if (end > PFN_DOWN(HIGHMEM_START)) @@ -400,7 +357,7 @@ static int __init early_parse_mem(char *p) if (*p == '@') start = memparse(p + 1, &p); - add_memory_region(start, size, BOOT_MEM_RAM); + memblock_add(start, size); return 0; } @@ -426,13 +383,14 @@ static int __init early_parse_memmap(char *p) if (*p == '@') { start_at = memparse(p+1, &p); - add_memory_region(start_at, mem_size, BOOT_MEM_RAM); + memblock_add(start_at, mem_size); } else if (*p == '#') { pr_err("\"memmap=nn#ss\" (force ACPI data) invalid on MIPS\n"); return -EINVAL; } else if (*p == '$') { start_at = memparse(p+1, &p); - add_memory_region(start_at, mem_size, BOOT_MEM_RESERVED); + memblock_add(start_at, mem_size); + memblock_reserve(start_at, mem_size); } else { pr_err("\"memmap\" invalid format!\n"); return -EINVAL; @@ -447,16 +405,15 @@ static int __init early_parse_memmap(char *p) early_param("memmap", early_parse_memmap); #ifdef CONFIG_PROC_VMCORE -unsigned long setup_elfcorehdr, setup_elfcorehdr_size; +static unsigned long setup_elfcorehdr, setup_elfcorehdr_size; static int __init early_parse_elfcorehdr(char *p) { - struct memblock_region *mem; + phys_addr_t start, end; + u64 i; setup_elfcorehdr = memparse(p, &p); - for_each_memblock(memory, mem) { - unsigned long start = mem->base; - unsigned long end = start + mem->size; + for_each_mem_range(i, &start, &end) { if (setup_elfcorehdr >= start && setup_elfcorehdr < end) { /* * Reserve from the elf core header to the end of @@ -477,6 +434,11 @@ early_param("elfcorehdr", early_parse_elfcorehdr); #endif #ifdef CONFIG_KEXEC + +/* 64M alignment for crash kernel regions */ +#define CRASH_ALIGN SZ_64M +#define CRASH_ADDR_MAX SZ_512M + static void __init mips_parse_crashkernel(void) { unsigned long long total_mem; @@ -489,9 +451,22 @@ static void __init mips_parse_crashkernel(void) if (ret != 0 || crash_size <= 0) return; - if (!memblock_find_in_range(crash_base, crash_base + crash_size, crash_size, 1)) { - pr_warn("Invalid memory region reserved for crash kernel\n"); - return; + if (crash_base <= 0) { + crash_base = memblock_find_in_range(CRASH_ALIGN, CRASH_ADDR_MAX, + crash_size, CRASH_ALIGN); + if (!crash_base) { + pr_warn("crashkernel reservation failed - No suitable area found.\n"); + return; + } + } else { + unsigned long long start; + + start = memblock_find_in_range(crash_base, crash_base + crash_size, + crash_size, 1); + if (start != crash_base) { + pr_warn("Invalid memory region reserved for crash kernel\n"); + return; + } } crashk_res.start = crash_base; @@ -626,7 +601,7 @@ static void __init bootcmdline_init(void) * arch_mem_init - initialize memory management subsystem * * o plat_mem_setup() detects the memory configuration and will record detected - * memory areas using add_memory_region. + * memory areas using memblock_add. * * At this stage the memory configuration of the system is known to the * kernel but generic memory management system is still entirely uninitialized. @@ -720,7 +695,8 @@ static void __init arch_mem_init(char **cmdline_p) static void __init resource_init(void) { - struct memblock_region *region; + phys_addr_t start, end; + u64 i; if (UNCAC_BASE != IO_BASE) return; @@ -732,9 +708,7 @@ static void __init resource_init(void) bss_resource.start = __pa_symbol(&__bss_start); bss_resource.end = __pa_symbol(&__bss_stop) - 1; - for_each_memblock(memory, region) { - phys_addr_t start = PFN_PHYS(memblock_region_memory_base_pfn(region)); - phys_addr_t end = PFN_PHYS(memblock_region_memory_end_pfn(region)) - 1; + for_each_mem_range(i, &start, &end) { struct resource *res; res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES); @@ -743,7 +717,12 @@ static void __init resource_init(void) sizeof(struct resource)); res->start = start; - res->end = end; + /* + * In memblock, end points to the first byte after the + * range while in resourses, end points to the last byte in + * the range. + */ + res->end = end - 1; res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; res->name = "System RAM"; diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index a0262729cd4c..50d0515bea21 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -545,6 +545,12 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) return err ?: protected_restore_fp_context(sc); } +#ifdef CONFIG_WAR_ICACHE_REFILLS +#define SIGMASK ~(cpu_icache_line_size()-1) +#else +#define SIGMASK ALMASK +#endif + void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size) { @@ -565,7 +571,7 @@ void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, sp = sigsp(sp, ksig); - return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK)); + return (void __user *)((sp - frame_size) & SIGMASK); } /* @@ -901,7 +907,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, do_signal(regs); if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); rseq_handle_notify_resume(NULL, regs); } diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index c333e5788664..2afa3eef486a 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -106,7 +106,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) if (unlikely(!access_ok((const void __user *)addr, 4))) return -EINVAL; - if (cpu_has_llsc && R10000_LLSC_WAR) { + if (cpu_has_llsc && IS_ENABLED(CONFIG_WAR_R10000_LLSC)) { __asm__ __volatile__ ( " .set push \n" " .set arch=r4000 \n" diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl index f9df9edb67a4..32817c954435 100644 --- a/arch/mips/kernel/syscalls/syscall_n32.tbl +++ b/arch/mips/kernel/syscalls/syscall_n32.tbl @@ -25,8 +25,8 @@ 15 n32 ioctl compat_sys_ioctl 16 n32 pread64 sys_pread64 17 n32 pwrite64 sys_pwrite64 -18 n32 readv compat_sys_readv -19 n32 writev compat_sys_writev +18 n32 readv sys_readv +19 n32 writev sys_writev 20 n32 access sys_access 21 n32 pipe sysm_pipe 22 n32 _newselect compat_sys_select @@ -167,7 +167,7 @@ 157 n32 sync sys_sync 158 n32 acct sys_acct 159 n32 settimeofday compat_sys_settimeofday -160 n32 mount compat_sys_mount +160 n32 mount sys_mount 161 n32 umount2 sys_umount 162 n32 swapon sys_swapon 163 n32 swapoff sys_swapoff @@ -278,7 +278,7 @@ 267 n32 splice sys_splice 268 n32 sync_file_range sys_sync_file_range 269 n32 tee sys_tee -270 n32 vmsplice compat_sys_vmsplice +270 n32 vmsplice sys_vmsplice 271 n32 move_pages compat_sys_move_pages 272 n32 set_robust_list compat_sys_set_robust_list 273 n32 get_robust_list compat_sys_get_robust_list @@ -317,8 +317,8 @@ 306 n32 syncfs sys_syncfs 307 n32 sendmmsg compat_sys_sendmmsg 308 n32 setns sys_setns -309 n32 process_vm_readv compat_sys_process_vm_readv -310 n32 process_vm_writev compat_sys_process_vm_writev +309 n32 process_vm_readv sys_process_vm_readv +310 n32 process_vm_writev sys_process_vm_writev 311 n32 kcmp sys_kcmp 312 n32 finit_module sys_finit_module 313 n32 sched_setattr sys_sched_setattr @@ -378,3 +378,4 @@ 437 n32 openat2 sys_openat2 438 n32 pidfd_getfd sys_pidfd_getfd 439 n32 faccessat2 sys_faccessat2 +440 n32 process_madvise sys_process_madvise diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl index 557f9954a2b9..9e4ea3c31b1c 100644 --- a/arch/mips/kernel/syscalls/syscall_n64.tbl +++ b/arch/mips/kernel/syscalls/syscall_n64.tbl @@ -354,3 +354,4 @@ 437 n64 openat2 sys_openat2 438 n64 pidfd_getfd sys_pidfd_getfd 439 n64 faccessat2 sys_faccessat2 +440 n64 process_madvise sys_process_madvise diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl index 195b43cf27c8..29f5f28cf5ce 100644 --- a/arch/mips/kernel/syscalls/syscall_o32.tbl +++ b/arch/mips/kernel/syscalls/syscall_o32.tbl @@ -29,7 +29,7 @@ 18 o32 unused18 sys_ni_syscall 19 o32 lseek sys_lseek 20 o32 getpid sys_getpid -21 o32 mount sys_mount compat_sys_mount +21 o32 mount sys_mount 22 o32 umount sys_oldumount 23 o32 setuid sys_setuid 24 o32 getuid sys_getuid @@ -156,8 +156,8 @@ 142 o32 _newselect sys_select compat_sys_select 143 o32 flock sys_flock 144 o32 msync sys_msync -145 o32 readv sys_readv compat_sys_readv -146 o32 writev sys_writev compat_sys_writev +145 o32 readv sys_readv +146 o32 writev sys_writev 147 o32 cacheflush sys_cacheflush 148 o32 cachectl sys_cachectl 149 o32 sysmips __sys_sysmips @@ -318,7 +318,7 @@ 304 o32 splice sys_splice 305 o32 sync_file_range sys_sync_file_range sys32_sync_file_range 306 o32 tee sys_tee -307 o32 vmsplice sys_vmsplice compat_sys_vmsplice +307 o32 vmsplice sys_vmsplice 308 o32 move_pages sys_move_pages compat_sys_move_pages 309 o32 set_robust_list sys_set_robust_list compat_sys_set_robust_list 310 o32 get_robust_list sys_get_robust_list compat_sys_get_robust_list @@ -356,8 +356,8 @@ 342 o32 syncfs sys_syncfs 343 o32 sendmmsg sys_sendmmsg compat_sys_sendmmsg 344 o32 setns sys_setns -345 o32 process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv -346 o32 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev +345 o32 process_vm_readv sys_process_vm_readv +346 o32 process_vm_writev sys_process_vm_writev 347 o32 kcmp sys_kcmp 348 o32 finit_module sys_finit_module 349 o32 sched_setattr sys_sched_setattr @@ -427,3 +427,4 @@ 437 o32 openat2 sys_openat2 438 o32 pidfd_getfd sys_pidfd_getfd 439 o32 faccessat2 sys_faccessat2 +440 o32 process_madvise sys_process_madvise diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index cf788591f091..e0352958e2f7 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -2204,7 +2204,7 @@ static void configure_status(void) * flag that some firmware may have left set and the TS bit (for * IP27). Set XX for ISA IV code to work. */ - unsigned int status_set = ST0_CU0; + unsigned int status_set = ST0_KERNEL_CUMASK; #ifdef CONFIG_64BIT status_set |= ST0_FR|ST0_KX|ST0_SX|ST0_UX; #endif diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index f185a85a27c1..5e97e9d02f98 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -202,6 +202,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + ELF_DETAILS /* These must appear regardless of . */ .gptab.sdata : { diff --git a/arch/mips/kvm/entry.c b/arch/mips/kvm/entry.c index fd716942e302..832475bf2055 100644 --- a/arch/mips/kvm/entry.c +++ b/arch/mips/kvm/entry.c @@ -205,7 +205,7 @@ static inline void build_set_exc_base(u32 **p, unsigned int reg) * Assemble the start of the vcpu_run function to run a guest VCPU. The function * conforms to the following prototype: * - * int vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu); + * int vcpu_run(struct kvm_vcpu *vcpu); * * The exit from the guest and return to the caller is handled by the code * generated by kvm_mips_build_ret_to_host(). @@ -218,8 +218,7 @@ void *kvm_mips_build_vcpu_run(void *addr) unsigned int i; /* - * A0: run - * A1: vcpu + * A0: vcpu */ /* k0/k1 not being used in host kernel context */ @@ -238,10 +237,10 @@ void *kvm_mips_build_vcpu_run(void *addr) kvm_mips_build_save_scratch(&p, V1, K1); /* VCPU scratch register has pointer to vcpu */ - UASM_i_MTC0(&p, A1, scratch_vcpu[0], scratch_vcpu[1]); + UASM_i_MTC0(&p, A0, scratch_vcpu[0], scratch_vcpu[1]); /* Offset into vcpu->arch */ - UASM_i_ADDIU(&p, K1, A1, offsetof(struct kvm_vcpu, arch)); + UASM_i_ADDIU(&p, K1, A0, offsetof(struct kvm_vcpu, arch)); /* * Save the host stack to VCPU, used for exception processing @@ -645,10 +644,7 @@ void *kvm_mips_build_exit(void *addr) /* Now that context has been saved, we can use other registers */ /* Restore vcpu */ - UASM_i_MFC0(&p, S1, scratch_vcpu[0], scratch_vcpu[1]); - - /* Restore run (vcpu->run) */ - UASM_i_LW(&p, S0, offsetof(struct kvm_vcpu, run), S1); + UASM_i_MFC0(&p, S0, scratch_vcpu[0], scratch_vcpu[1]); /* * Save Host level EPC, BadVaddr and Cause to VCPU, useful to process @@ -810,7 +806,6 @@ void *kvm_mips_build_exit(void *addr) * with this in the kernel */ uasm_i_move(&p, A0, S0); - uasm_i_move(&p, A1, S1); UASM_i_LA(&p, T9, (unsigned long)kvm_mips_handle_exit); uasm_i_jalr(&p, RA, T9); UASM_i_ADDIU(&p, SP, SP, -CALLFRAME_SIZ); @@ -852,7 +847,7 @@ static void *kvm_mips_build_ret_from_exit(void *addr) * guest, reload k1 */ - uasm_i_move(&p, K1, S1); + uasm_i_move(&p, K1, S0); UASM_i_ADDIU(&p, K1, K1, offsetof(struct kvm_vcpu, arch)); /* @@ -886,8 +881,8 @@ static void *kvm_mips_build_ret_to_guest(void *addr) { u32 *p = addr; - /* Put the saved pointer to vcpu (s1) back into the scratch register */ - UASM_i_MTC0(&p, S1, scratch_vcpu[0], scratch_vcpu[1]); + /* Put the saved pointer to vcpu (s0) back into the scratch register */ + UASM_i_MTC0(&p, S0, scratch_vcpu[0], scratch_vcpu[1]); /* Load up the Guest EBASE to minimize the window where BEV is set */ UASM_i_LW(&p, T0, offsetof(struct kvm_vcpu_arch, guest_ebase), K1); diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index 7de85d2253ff..3d6a7f5827b1 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -137,6 +137,8 @@ extern void kvm_init_loongson_ipi(struct kvm *kvm); int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) { switch (type) { + case KVM_VM_MIPS_AUTO: + break; #ifdef CONFIG_KVM_MIPS_VZ case KVM_VM_MIPS_VZ: #else @@ -1197,8 +1199,9 @@ static void kvm_mips_set_c0_status(void) /* * Return value is in the form (errcode<<2 | RESUME_FLAG_HOST | RESUME_FLAG_NV) */ -int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu) +int kvm_mips_handle_exit(struct kvm_vcpu *vcpu) { + struct kvm_run *run = vcpu->run; u32 cause = vcpu->arch.host_cp0_cause; u32 exccode = (cause >> CAUSEB_EXCCODE) & 0x1f; u32 __user *opc = (u32 __user *) vcpu->arch.pc; diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c index f8cba51e1054..0788c00d7e94 100644 --- a/arch/mips/kvm/trap_emul.c +++ b/arch/mips/kvm/trap_emul.c @@ -1241,7 +1241,7 @@ static int kvm_trap_emul_vcpu_run(struct kvm_vcpu *vcpu) */ kvm_mips_suspend_mm(cpu); - r = vcpu->arch.vcpu_run(vcpu->run, vcpu); + r = vcpu->arch.vcpu_run(vcpu); /* We may have migrated while handling guest exits */ cpu = smp_processor_id(); diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c index c299e5d6d69c..2ffbe9264a31 100644 --- a/arch/mips/kvm/vz.c +++ b/arch/mips/kvm/vz.c @@ -3266,7 +3266,7 @@ static int kvm_vz_vcpu_run(struct kvm_vcpu *vcpu) kvm_vz_vcpu_load_tlb(vcpu, cpu); kvm_vz_vcpu_load_wired(vcpu); - r = vcpu->arch.vcpu_run(vcpu->run, vcpu); + r = vcpu->arch.vcpu_run(vcpu); kvm_vz_vcpu_save_wired(vcpu); diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index b10342018d19..917fac1636b7 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c @@ -112,11 +112,15 @@ static u32 pmu_clk_cr_b[] = { #define PMU_PPE_DP BIT(23) #define PMU_PPE_DPLUS BIT(24) #define PMU_USB1_P BIT(26) +#define PMU_GPHY3 BIT(26) /* grx390 */ #define PMU_USB1 BIT(27) #define PMU_SWITCH BIT(28) #define PMU_PPE_TOP BIT(29) +#define PMU_GPHY0 BIT(29) /* ar10, xrx390 */ #define PMU_GPHY BIT(30) +#define PMU_GPHY1 BIT(30) /* ar10, xrx390 */ #define PMU_PCIE_CLK BIT(31) +#define PMU_GPHY2 BIT(31) /* ar10, xrx390 */ #define PMU1_PCIE_PHY BIT(0) /* vr9-specific,moved in ar10/grx390 */ #define PMU1_PCIE_CTL BIT(1) @@ -465,6 +469,9 @@ void __init ltq_soc_init(void) if (of_machine_is_compatible("lantiq,grx390") || of_machine_is_compatible("lantiq,ar10")) { + clkdev_add_pmu("1e108000.switch", "gphy0", 0, 0, PMU_GPHY0); + clkdev_add_pmu("1e108000.switch", "gphy1", 0, 0, PMU_GPHY1); + clkdev_add_pmu("1e108000.switch", "gphy2", 0, 0, PMU_GPHY2); clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB0_P); clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB1_P); /* rc 0 */ @@ -496,6 +503,7 @@ void __init ltq_soc_init(void) } else if (of_machine_is_compatible("lantiq,grx390")) { clkdev_add_static(ltq_grx390_cpu_hz(), ltq_grx390_fpi_hz(), ltq_grx390_fpi_hz(), ltq_grx390_pp32_hz()); + clkdev_add_pmu("1e108000.switch", "gphy3", 0, 0, PMU_GPHY3); clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1); /* rc 2 */ @@ -514,8 +522,6 @@ void __init ltq_soc_init(void) clkdev_add_pmu("1e10b308.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP | PMU_PPE_TC); clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); - clkdev_add_pmu("1e108000.switch", "gphy0", 0, 0, PMU_GPHY); - clkdev_add_pmu("1e108000.switch", "gphy1", 0, 0, PMU_GPHY); clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); clkdev_add_pmu("1e116000.mei", "afe", 1, 2, PMU_ANALOG_DSL_AFE); clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S index 87fda0713b84..a46db0807195 100644 --- a/arch/mips/lib/csum_partial.S +++ b/arch/mips/lib/csum_partial.S @@ -308,8 +308,8 @@ EXPORT_SYMBOL(csum_partial) /* * checksum and copy routines based on memcpy.S * - * csum_partial_copy_nocheck(src, dst, len, sum) - * __csum_partial_copy_kernel(src, dst, len, sum, errp) + * csum_partial_copy_nocheck(src, dst, len) + * __csum_partial_copy_kernel(src, dst, len) * * See "Spec" in memcpy.S for details. Unlike __copy_user, all * function in this file use the standard calling convention. @@ -318,26 +318,11 @@ EXPORT_SYMBOL(csum_partial) #define src a0 #define dst a1 #define len a2 -#define psum a3 #define sum v0 #define odd t8 -#define errptr t9 /* - * The exception handler for loads requires that: - * 1- AT contain the address of the byte just past the end of the source - * of the copy, - * 2- src_entry <= src < AT, and - * 3- (dst - src) == (dst_entry - src_entry), - * The _entry suffix denotes values when __copy_user was called. - * - * (1) is set up up by __csum_partial_copy_from_user and maintained by - * not writing AT in __csum_partial_copy - * (2) is met by incrementing src by the number of bytes copied - * (3) is met by not doing loads between a pair of increments of dst and src - * - * The exception handlers for stores stores -EFAULT to errptr and return. - * These handlers do not need to overwrite any data. + * All exception handlers simply return 0. */ /* Instruction type */ @@ -358,11 +343,11 @@ EXPORT_SYMBOL(csum_partial) * addr : Address * handler : Exception handler */ -#define EXC(insn, type, reg, addr, handler) \ +#define EXC(insn, type, reg, addr) \ .if \mode == LEGACY_MODE; \ 9: insn reg, addr; \ .section __ex_table,"a"; \ - PTR 9b, handler; \ + PTR 9b, .L_exc; \ .previous; \ /* This is enabled in EVA mode */ \ .else; \ @@ -371,7 +356,7 @@ EXPORT_SYMBOL(csum_partial) ((\to == USEROP) && (type == ST_INSN)); \ 9: __BUILD_EVA_INSN(insn##e, reg, addr); \ .section __ex_table,"a"; \ - PTR 9b, handler; \ + PTR 9b, .L_exc; \ .previous; \ .else; \ /* EVA without exception */ \ @@ -384,14 +369,14 @@ EXPORT_SYMBOL(csum_partial) #ifdef USE_DOUBLE #define LOADK ld /* No exception */ -#define LOAD(reg, addr, handler) EXC(ld, LD_INSN, reg, addr, handler) -#define LOADBU(reg, addr, handler) EXC(lbu, LD_INSN, reg, addr, handler) -#define LOADL(reg, addr, handler) EXC(ldl, LD_INSN, reg, addr, handler) -#define LOADR(reg, addr, handler) EXC(ldr, LD_INSN, reg, addr, handler) -#define STOREB(reg, addr, handler) EXC(sb, ST_INSN, reg, addr, handler) -#define STOREL(reg, addr, handler) EXC(sdl, ST_INSN, reg, addr, handler) -#define STORER(reg, addr, handler) EXC(sdr, ST_INSN, reg, addr, handler) -#define STORE(reg, addr, handler) EXC(sd, ST_INSN, reg, addr, handler) +#define LOAD(reg, addr) EXC(ld, LD_INSN, reg, addr) +#define LOADBU(reg, addr) EXC(lbu, LD_INSN, reg, addr) +#define LOADL(reg, addr) EXC(ldl, LD_INSN, reg, addr) +#define LOADR(reg, addr) EXC(ldr, LD_INSN, reg, addr) +#define STOREB(reg, addr) EXC(sb, ST_INSN, reg, addr) +#define STOREL(reg, addr) EXC(sdl, ST_INSN, reg, addr) +#define STORER(reg, addr) EXC(sdr, ST_INSN, reg, addr) +#define STORE(reg, addr) EXC(sd, ST_INSN, reg, addr) #define ADD daddu #define SUB dsubu #define SRL dsrl @@ -404,14 +389,14 @@ EXPORT_SYMBOL(csum_partial) #else #define LOADK lw /* No exception */ -#define LOAD(reg, addr, handler) EXC(lw, LD_INSN, reg, addr, handler) -#define LOADBU(reg, addr, handler) EXC(lbu, LD_INSN, reg, addr, handler) -#define LOADL(reg, addr, handler) EXC(lwl, LD_INSN, reg, addr, handler) -#define LOADR(reg, addr, handler) EXC(lwr, LD_INSN, reg, addr, handler) -#define STOREB(reg, addr, handler) EXC(sb, ST_INSN, reg, addr, handler) -#define STOREL(reg, addr, handler) EXC(swl, ST_INSN, reg, addr, handler) -#define STORER(reg, addr, handler) EXC(swr, ST_INSN, reg, addr, handler) -#define STORE(reg, addr, handler) EXC(sw, ST_INSN, reg, addr, handler) +#define LOAD(reg, addr) EXC(lw, LD_INSN, reg, addr) +#define LOADBU(reg, addr) EXC(lbu, LD_INSN, reg, addr) +#define LOADL(reg, addr) EXC(lwl, LD_INSN, reg, addr) +#define LOADR(reg, addr) EXC(lwr, LD_INSN, reg, addr) +#define STOREB(reg, addr) EXC(sb, ST_INSN, reg, addr) +#define STOREL(reg, addr) EXC(swl, ST_INSN, reg, addr) +#define STORER(reg, addr) EXC(swr, ST_INSN, reg, addr) +#define STORE(reg, addr) EXC(sw, ST_INSN, reg, addr) #define ADD addu #define SUB subu #define SRL srl @@ -450,22 +435,9 @@ EXPORT_SYMBOL(csum_partial) .set at=v1 #endif - .macro __BUILD_CSUM_PARTIAL_COPY_USER mode, from, to, __nocheck + .macro __BUILD_CSUM_PARTIAL_COPY_USER mode, from, to - PTR_ADDU AT, src, len /* See (1) above. */ - /* initialize __nocheck if this the first time we execute this - * macro - */ -#ifdef CONFIG_64BIT - move errptr, a4 -#else - lw errptr, 16(sp) -#endif - .if \__nocheck == 1 - FEXPORT(csum_partial_copy_nocheck) - EXPORT_SYMBOL(csum_partial_copy_nocheck) - .endif - move sum, zero + li sum, -1 move odd, zero /* * Note: dst & src may be unaligned, len may be 0 @@ -497,31 +469,31 @@ EXPORT_SYMBOL(csum_partial) SUB len, 8*NBYTES # subtract here for bgez loop .align 4 1: - LOAD(t0, UNIT(0)(src), .Ll_exc\@) - LOAD(t1, UNIT(1)(src), .Ll_exc_copy\@) - LOAD(t2, UNIT(2)(src), .Ll_exc_copy\@) - LOAD(t3, UNIT(3)(src), .Ll_exc_copy\@) - LOAD(t4, UNIT(4)(src), .Ll_exc_copy\@) - LOAD(t5, UNIT(5)(src), .Ll_exc_copy\@) - LOAD(t6, UNIT(6)(src), .Ll_exc_copy\@) - LOAD(t7, UNIT(7)(src), .Ll_exc_copy\@) + LOAD(t0, UNIT(0)(src)) + LOAD(t1, UNIT(1)(src)) + LOAD(t2, UNIT(2)(src)) + LOAD(t3, UNIT(3)(src)) + LOAD(t4, UNIT(4)(src)) + LOAD(t5, UNIT(5)(src)) + LOAD(t6, UNIT(6)(src)) + LOAD(t7, UNIT(7)(src)) SUB len, len, 8*NBYTES ADD src, src, 8*NBYTES - STORE(t0, UNIT(0)(dst), .Ls_exc\@) + STORE(t0, UNIT(0)(dst)) ADDC(t0, t1) - STORE(t1, UNIT(1)(dst), .Ls_exc\@) + STORE(t1, UNIT(1)(dst)) ADDC(sum, t0) - STORE(t2, UNIT(2)(dst), .Ls_exc\@) + STORE(t2, UNIT(2)(dst)) ADDC(t2, t3) - STORE(t3, UNIT(3)(dst), .Ls_exc\@) + STORE(t3, UNIT(3)(dst)) ADDC(sum, t2) - STORE(t4, UNIT(4)(dst), .Ls_exc\@) + STORE(t4, UNIT(4)(dst)) ADDC(t4, t5) - STORE(t5, UNIT(5)(dst), .Ls_exc\@) + STORE(t5, UNIT(5)(dst)) ADDC(sum, t4) - STORE(t6, UNIT(6)(dst), .Ls_exc\@) + STORE(t6, UNIT(6)(dst)) ADDC(t6, t7) - STORE(t7, UNIT(7)(dst), .Ls_exc\@) + STORE(t7, UNIT(7)(dst)) ADDC(sum, t6) .set reorder /* DADDI_WAR */ ADD dst, dst, 8*NBYTES @@ -541,19 +513,19 @@ EXPORT_SYMBOL(csum_partial) /* * len >= 4*NBYTES */ - LOAD(t0, UNIT(0)(src), .Ll_exc\@) - LOAD(t1, UNIT(1)(src), .Ll_exc_copy\@) - LOAD(t2, UNIT(2)(src), .Ll_exc_copy\@) - LOAD(t3, UNIT(3)(src), .Ll_exc_copy\@) + LOAD(t0, UNIT(0)(src)) + LOAD(t1, UNIT(1)(src)) + LOAD(t2, UNIT(2)(src)) + LOAD(t3, UNIT(3)(src)) SUB len, len, 4*NBYTES ADD src, src, 4*NBYTES - STORE(t0, UNIT(0)(dst), .Ls_exc\@) + STORE(t0, UNIT(0)(dst)) ADDC(t0, t1) - STORE(t1, UNIT(1)(dst), .Ls_exc\@) + STORE(t1, UNIT(1)(dst)) ADDC(sum, t0) - STORE(t2, UNIT(2)(dst), .Ls_exc\@) + STORE(t2, UNIT(2)(dst)) ADDC(t2, t3) - STORE(t3, UNIT(3)(dst), .Ls_exc\@) + STORE(t3, UNIT(3)(dst)) ADDC(sum, t2) .set reorder /* DADDI_WAR */ ADD dst, dst, 4*NBYTES @@ -566,10 +538,10 @@ EXPORT_SYMBOL(csum_partial) beq rem, len, .Lcopy_bytes\@ nop 1: - LOAD(t0, 0(src), .Ll_exc\@) + LOAD(t0, 0(src)) ADD src, src, NBYTES SUB len, len, NBYTES - STORE(t0, 0(dst), .Ls_exc\@) + STORE(t0, 0(dst)) ADDC(sum, t0) .set reorder /* DADDI_WAR */ ADD dst, dst, NBYTES @@ -592,10 +564,10 @@ EXPORT_SYMBOL(csum_partial) ADD t1, dst, len # t1 is just past last byte of dst li bits, 8*NBYTES SLL rem, len, 3 # rem = number of bits to keep - LOAD(t0, 0(src), .Ll_exc\@) + LOAD(t0, 0(src)) SUB bits, bits, rem # bits = number of bits to discard SHIFT_DISCARD t0, t0, bits - STREST(t0, -1(t1), .Ls_exc\@) + STREST(t0, -1(t1)) SHIFT_DISCARD_REVERT t0, t0, bits .set reorder ADDC(sum, t0) @@ -612,12 +584,12 @@ EXPORT_SYMBOL(csum_partial) * Set match = (src and dst have same alignment) */ #define match rem - LDFIRST(t3, FIRST(0)(src), .Ll_exc\@) + LDFIRST(t3, FIRST(0)(src)) ADD t2, zero, NBYTES - LDREST(t3, REST(0)(src), .Ll_exc_copy\@) + LDREST(t3, REST(0)(src)) SUB t2, t2, t1 # t2 = number of bytes copied xor match, t0, t1 - STFIRST(t3, FIRST(0)(dst), .Ls_exc\@) + STFIRST(t3, FIRST(0)(dst)) SLL t4, t1, 3 # t4 = number of bits to discard SHIFT_DISCARD t3, t3, t4 /* no SHIFT_DISCARD_REVERT to handle odd buffer properly */ @@ -639,26 +611,26 @@ EXPORT_SYMBOL(csum_partial) * It's OK to load FIRST(N+1) before REST(N) because the two addresses * are to the same unit (unless src is aligned, but it's not). */ - LDFIRST(t0, FIRST(0)(src), .Ll_exc\@) - LDFIRST(t1, FIRST(1)(src), .Ll_exc_copy\@) + LDFIRST(t0, FIRST(0)(src)) + LDFIRST(t1, FIRST(1)(src)) SUB len, len, 4*NBYTES - LDREST(t0, REST(0)(src), .Ll_exc_copy\@) - LDREST(t1, REST(1)(src), .Ll_exc_copy\@) - LDFIRST(t2, FIRST(2)(src), .Ll_exc_copy\@) - LDFIRST(t3, FIRST(3)(src), .Ll_exc_copy\@) - LDREST(t2, REST(2)(src), .Ll_exc_copy\@) - LDREST(t3, REST(3)(src), .Ll_exc_copy\@) + LDREST(t0, REST(0)(src)) + LDREST(t1, REST(1)(src)) + LDFIRST(t2, FIRST(2)(src)) + LDFIRST(t3, FIRST(3)(src)) + LDREST(t2, REST(2)(src)) + LDREST(t3, REST(3)(src)) ADD src, src, 4*NBYTES #ifdef CONFIG_CPU_SB1 nop # improves slotting #endif - STORE(t0, UNIT(0)(dst), .Ls_exc\@) + STORE(t0, UNIT(0)(dst)) ADDC(t0, t1) - STORE(t1, UNIT(1)(dst), .Ls_exc\@) + STORE(t1, UNIT(1)(dst)) ADDC(sum, t0) - STORE(t2, UNIT(2)(dst), .Ls_exc\@) + STORE(t2, UNIT(2)(dst)) ADDC(t2, t3) - STORE(t3, UNIT(3)(dst), .Ls_exc\@) + STORE(t3, UNIT(3)(dst)) ADDC(sum, t2) .set reorder /* DADDI_WAR */ ADD dst, dst, 4*NBYTES @@ -671,11 +643,11 @@ EXPORT_SYMBOL(csum_partial) beq rem, len, .Lcopy_bytes\@ nop 1: - LDFIRST(t0, FIRST(0)(src), .Ll_exc\@) - LDREST(t0, REST(0)(src), .Ll_exc_copy\@) + LDFIRST(t0, FIRST(0)(src)) + LDREST(t0, REST(0)(src)) ADD src, src, NBYTES SUB len, len, NBYTES - STORE(t0, 0(dst), .Ls_exc\@) + STORE(t0, 0(dst)) ADDC(sum, t0) .set reorder /* DADDI_WAR */ ADD dst, dst, NBYTES @@ -696,11 +668,10 @@ EXPORT_SYMBOL(csum_partial) #endif move t2, zero # partial word li t3, SHIFT_START # shift -/* use .Ll_exc_copy here to return correct sum on fault */ #define COPY_BYTE(N) \ - LOADBU(t0, N(src), .Ll_exc_copy\@); \ + LOADBU(t0, N(src)); \ SUB len, len, 1; \ - STOREB(t0, N(dst), .Ls_exc\@); \ + STOREB(t0, N(dst)); \ SLLV t0, t0, t3; \ addu t3, SHIFT_INC; \ beqz len, .Lcopy_bytes_done\@; \ @@ -714,9 +685,9 @@ EXPORT_SYMBOL(csum_partial) COPY_BYTE(4) COPY_BYTE(5) #endif - LOADBU(t0, NBYTES-2(src), .Ll_exc_copy\@) + LOADBU(t0, NBYTES-2(src)) SUB len, len, 1 - STOREB(t0, NBYTES-2(dst), .Ls_exc\@) + STOREB(t0, NBYTES-2(dst)) SLLV t0, t0, t3 or t2, t0 .Lcopy_bytes_done\@: @@ -753,97 +724,31 @@ EXPORT_SYMBOL(csum_partial) #endif .set pop .set reorder - ADDC32(sum, psum) jr ra .set noreorder + .endm -.Ll_exc_copy\@: - /* - * Copy bytes from src until faulting load address (or until a - * lb faults) - * - * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28) - * may be more than a byte beyond the last address. - * Hence, the lb below may get an exception. - * - * Assumes src < THREAD_BUADDR($28) - */ - LOADK t0, TI_TASK($28) - li t2, SHIFT_START - LOADK t0, THREAD_BUADDR(t0) -1: - LOADBU(t1, 0(src), .Ll_exc\@) - ADD src, src, 1 - sb t1, 0(dst) # can't fault -- we're copy_from_user - SLLV t1, t1, t2 - addu t2, SHIFT_INC - ADDC(sum, t1) - .set reorder /* DADDI_WAR */ - ADD dst, dst, 1 - bne src, t0, 1b - .set noreorder -.Ll_exc\@: - LOADK t0, TI_TASK($28) - nop - LOADK t0, THREAD_BUADDR(t0) # t0 is just past last good address - nop - SUB len, AT, t0 # len number of uncopied bytes - /* - * Here's where we rely on src and dst being incremented in tandem, - * See (3) above. - * dst += (fault addr - src) to put dst at first byte to clear - */ - ADD dst, t0 # compute start address in a1 - SUB dst, src - /* - * Clear len bytes starting at dst. Can't call __bzero because it - * might modify len. An inefficient loop for these rare times... - */ - .set reorder /* DADDI_WAR */ - SUB src, len, 1 - beqz len, .Ldone\@ - .set noreorder -1: sb zero, 0(dst) - ADD dst, dst, 1 - .set push - .set noat -#ifndef CONFIG_CPU_DADDI_WORKAROUNDS - bnez src, 1b - SUB src, src, 1 -#else - li v1, 1 - bnez src, 1b - SUB src, src, v1 -#endif - li v1, -EFAULT - b .Ldone\@ - sw v1, (errptr) - -.Ls_exc\@: - li v0, -1 /* invalid checksum */ - li v1, -EFAULT + .set noreorder +.L_exc: jr ra - sw v1, (errptr) - .set pop - .endm + li v0, 0 -LEAF(__csum_partial_copy_kernel) -EXPORT_SYMBOL(__csum_partial_copy_kernel) +FEXPORT(__csum_partial_copy_nocheck) +EXPORT_SYMBOL(__csum_partial_copy_nocheck) #ifndef CONFIG_EVA FEXPORT(__csum_partial_copy_to_user) EXPORT_SYMBOL(__csum_partial_copy_to_user) FEXPORT(__csum_partial_copy_from_user) EXPORT_SYMBOL(__csum_partial_copy_from_user) #endif -__BUILD_CSUM_PARTIAL_COPY_USER LEGACY_MODE USEROP USEROP 1 -END(__csum_partial_copy_kernel) +__BUILD_CSUM_PARTIAL_COPY_USER LEGACY_MODE USEROP USEROP #ifdef CONFIG_EVA LEAF(__csum_partial_copy_to_user) -__BUILD_CSUM_PARTIAL_COPY_USER EVA_MODE KERNELOP USEROP 0 +__BUILD_CSUM_PARTIAL_COPY_USER EVA_MODE KERNELOP USEROP END(__csum_partial_copy_to_user) LEAF(__csum_partial_copy_from_user) -__BUILD_CSUM_PARTIAL_COPY_USER EVA_MODE USEROP KERNELOP 0 +__BUILD_CSUM_PARTIAL_COPY_USER EVA_MODE USEROP KERNELOP END(__csum_partial_copy_from_user) #endif diff --git a/arch/mips/loongson2ef/Platform b/arch/mips/loongson2ef/Platform index 4ab55f1123a0..ae023b9a1c51 100644 --- a/arch/mips/loongson2ef/Platform +++ b/arch/mips/loongson2ef/Platform @@ -44,6 +44,10 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS endif endif +# Some -march= flags enable MMI instructions, and GCC complains about that +# support being enabled alongside -msoft-float. Thus explicitly disable MMI. +cflags-y += $(call cc-option,-mno-loongson-mmi) + # # Loongson Machines' Support # diff --git a/arch/mips/loongson2ef/common/mem.c b/arch/mips/loongson2ef/common/mem.c index ae21f1c62baa..057d58bb470e 100644 --- a/arch/mips/loongson2ef/common/mem.c +++ b/arch/mips/loongson2ef/common/mem.c @@ -17,10 +17,7 @@ u32 memsize, highmemsize; void __init prom_init_memory(void) { - add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); - - add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize << - 20), BOOT_MEM_RESERVED); + memblock_add(0x0, (memsize << 20)); #ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG { @@ -41,12 +38,7 @@ void __init prom_init_memory(void) #ifdef CONFIG_64BIT if (highmemsize > 0) - add_memory_region(LOONGSON_HIGHMEM_START, - highmemsize << 20, BOOT_MEM_RAM); - - add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START - - LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED); - + memblock_add(LOONGSON_HIGHMEM_START, highmemsize << 20); #endif /* !CONFIG_64BIT */ } diff --git a/arch/mips/loongson2ef/fuloong-2e/dma.c b/arch/mips/loongson2ef/fuloong-2e/dma.c index e122292bf666..cea167d8aba8 100644 --- a/arch/mips/loongson2ef/fuloong-2e/dma.c +++ b/arch/mips/loongson2ef/fuloong-2e/dma.c @@ -1,12 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/dma-direct.h> -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { return paddr | 0x80000000; } -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr) { return dma_addr & 0x7fffffff; } diff --git a/arch/mips/loongson2ef/lemote-2f/dma.c b/arch/mips/loongson2ef/lemote-2f/dma.c index abf0e39d7e46..3c9e99456357 100644 --- a/arch/mips/loongson2ef/lemote-2f/dma.c +++ b/arch/mips/loongson2ef/lemote-2f/dma.c @@ -1,12 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/dma-direct.h> -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { return paddr | 0x80000000; } -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr) { if (dma_addr > 0x8fffffff) return dma_addr; diff --git a/arch/mips/loongson32/common/prom.c b/arch/mips/loongson32/common/prom.c index fd76114fa3b0..c133b5adf34e 100644 --- a/arch/mips/loongson32/common/prom.c +++ b/arch/mips/loongson32/common/prom.c @@ -7,8 +7,8 @@ #include <linux/io.h> #include <linux/init.h> +#include <linux/memblock.h> #include <linux/serial_reg.h> -#include <asm/bootinfo.h> #include <asm/fw/fw.h> #include <loongson1.h> @@ -42,5 +42,5 @@ void __init prom_free_prom_memory(void) void __init plat_mem_setup(void) { - add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); + memblock_add(0x0, (memsize << 20)); } diff --git a/arch/mips/loongson64/cop2-ex.c b/arch/mips/loongson64/cop2-ex.c index f130f62129b8..00055d4b6042 100644 --- a/arch/mips/loongson64/cop2-ex.c +++ b/arch/mips/loongson64/cop2-ex.c @@ -95,10 +95,8 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, if (res) goto fault; - set_fpr64(current->thread.fpu.fpr, - insn.loongson3_lswc2_format.rt, value); - set_fpr64(current->thread.fpu.fpr, - insn.loongson3_lswc2_format.rq, value_next); + set_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lswc2_format.rt], 0, value); + set_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lswc2_format.rq], 0, value_next); compute_return_epc(regs); own_fpu(1); } @@ -130,15 +128,13 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, goto sigbus; lose_fpu(1); - value_next = get_fpr64(current->thread.fpu.fpr, - insn.loongson3_lswc2_format.rq); + value_next = get_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lswc2_format.rq], 0); StoreDW(addr + 8, value_next, res); if (res) goto fault; - value = get_fpr64(current->thread.fpu.fpr, - insn.loongson3_lswc2_format.rt); + value = get_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lswc2_format.rt], 0); StoreDW(addr, value, res); if (res) @@ -204,8 +200,7 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, if (res) goto fault; - set_fpr64(current->thread.fpu.fpr, - insn.loongson3_lsdc2_format.rt, value); + set_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0, value); compute_return_epc(regs); own_fpu(1); @@ -221,8 +216,7 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, if (res) goto fault; - set_fpr64(current->thread.fpu.fpr, - insn.loongson3_lsdc2_format.rt, value); + set_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0, value); compute_return_epc(regs); own_fpu(1); break; @@ -286,8 +280,7 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, goto sigbus; lose_fpu(1); - value = get_fpr64(current->thread.fpu.fpr, - insn.loongson3_lsdc2_format.rt); + value = get_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0); StoreW(addr, value, res); if (res) @@ -305,8 +298,7 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, goto sigbus; lose_fpu(1); - value = get_fpr64(current->thread.fpu.fpr, - insn.loongson3_lsdc2_format.rt); + value = get_fpr64(¤t->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0); StoreDW(addr, value, res); if (res) diff --git a/arch/mips/loongson64/dma.c b/arch/mips/loongson64/dma.c index dbfe6e82fddd..364f2f27c872 100644 --- a/arch/mips/loongson64/dma.c +++ b/arch/mips/loongson64/dma.c @@ -4,7 +4,7 @@ #include <linux/swiotlb.h> #include <boot_param.h> -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from * Loongson-3's 48bit address space and embed it into 40bit */ @@ -13,7 +13,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) return ((nid << 44) ^ paddr) | (nid << node_id_offset); } -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr) +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) { /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from * Loongson-3's 48bit address space and embed it into 40bit */ diff --git a/arch/mips/loongson64/numa.c b/arch/mips/loongson64/numa.c index ea8bb1bc667e..cf9459f79f9b 100644 --- a/arch/mips/loongson64/numa.c +++ b/arch/mips/loongson64/numa.c @@ -98,27 +98,6 @@ static void __init init_topology_matrix(void) } } -static unsigned long nid_to_addroffset(unsigned int nid) -{ - unsigned long result; - switch (nid) { - case 0: - default: - result = NODE0_ADDRSPACE_OFFSET; - break; - case 1: - result = NODE1_ADDRSPACE_OFFSET; - break; - case 2: - result = NODE2_ADDRSPACE_OFFSET; - break; - case 3: - result = NODE3_ADDRSPACE_OFFSET; - break; - } - return result; -} - static void __init szmem(unsigned int node) { u32 i, mem_type; @@ -146,7 +125,7 @@ static void __init szmem(unsigned int node) pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", start_pfn, end_pfn, num_physpages); memblock_add_node(PFN_PHYS(start_pfn), - PFN_PHYS(end_pfn - start_pfn), node); + PFN_PHYS(node_psize), node); break; case SYSTEM_RAM_HIGH: start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; @@ -158,7 +137,7 @@ static void __init szmem(unsigned int node) pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", start_pfn, end_pfn, num_physpages); memblock_add_node(PFN_PHYS(start_pfn), - PFN_PHYS(end_pfn - start_pfn), node); + PFN_PHYS(node_psize), node); break; case SYSTEM_RAM_RESERVED: pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", @@ -175,7 +154,7 @@ static void __init node_mem_init(unsigned int node) unsigned long node_addrspace_offset; unsigned long start_pfn, end_pfn; - node_addrspace_offset = nid_to_addroffset(node); + node_addrspace_offset = nid_to_addrbase(node); pr_info("Node%d's addrspace_offset is 0x%lx\n", node, node_addrspace_offset); @@ -242,9 +221,7 @@ void __init paging_init(void) unsigned long zones_size[MAX_NR_ZONES] = {0, }; pagetable_init(); -#ifdef CONFIG_ZONE_DMA32 zones_size[ZONE_DMA32] = MAX_DMA32_PFN; -#endif zones_size[ZONE_NORMAL] = max_low_pfn; free_area_init(zones_size); } diff --git a/arch/mips/loongson64/reset.c b/arch/mips/loongson64/reset.c index bc7671079f0c..3bb8a1ed9348 100644 --- a/arch/mips/loongson64/reset.c +++ b/arch/mips/loongson64/reset.c @@ -15,11 +15,6 @@ #include <loongson.h> #include <boot_param.h> -static inline void loongson_reboot(void) -{ - ((void (*)(void))ioremap(LOONGSON_BOOT_BASE, 4)) (); -} - static void loongson_restart(char *command) { diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 0ef717093262..9cede7ce37e6 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -130,9 +130,10 @@ struct bcache_ops *bcops = &no_sc_ops; #define R4600_HIT_CACHEOP_WAR_IMPL \ do { \ - if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) \ + if (IS_ENABLED(CONFIG_WAR_R4600_V2_HIT_CACHEOP) && \ + cpu_is_r4600_v2_x()) \ *(volatile unsigned long *)CKSEG1; \ - if (R4600_V1_HIT_CACHEOP_WAR) \ + if (IS_ENABLED(CONFIG_WAR_R4600_V1_HIT_CACHEOP)) \ __asm__ __volatile__("nop;nop;nop;nop"); \ } while (0) @@ -238,7 +239,7 @@ static void r4k_blast_dcache_setup(void) r4k_blast_dcache = blast_dcache128; } -/* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */ +/* force code alignment (used for CONFIG_WAR_TX49XX_ICACHE_INDEX_INV) */ #define JUMP_TO_ALIGN(order) \ __asm__ __volatile__( \ "b\t1f\n\t" \ @@ -366,10 +367,11 @@ static void r4k_blast_icache_page_indexed_setup(void) else if (ic_lsize == 16) r4k_blast_icache_page_indexed = blast_icache16_page_indexed; else if (ic_lsize == 32) { - if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x()) + if (IS_ENABLED(CONFIG_WAR_R4600_V1_INDEX_ICACHEOP) && + cpu_is_r4600_v1_x()) r4k_blast_icache_page_indexed = blast_icache32_r4600_v1_page_indexed; - else if (TX49XX_ICACHE_INDEX_INV_WAR) + else if (IS_ENABLED(CONFIG_WAR_TX49XX_ICACHE_INDEX_INV)) r4k_blast_icache_page_indexed = tx49_blast_icache32_page_indexed; else if (current_cpu_type() == CPU_LOONGSON2EF) @@ -394,9 +396,10 @@ static void r4k_blast_icache_setup(void) else if (ic_lsize == 16) r4k_blast_icache = blast_icache16; else if (ic_lsize == 32) { - if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x()) + if (IS_ENABLED(CONFIG_WAR_R4600_V1_INDEX_ICACHEOP) && + cpu_is_r4600_v1_x()) r4k_blast_icache = blast_r4600_v1_icache32; - else if (TX49XX_ICACHE_INDEX_INV_WAR) + else if (IS_ENABLED(CONFIG_WAR_TX49XX_ICACHE_INDEX_INV)) r4k_blast_icache = tx49_blast_icache32; else if (current_cpu_type() == CPU_LOONGSON2EF) r4k_blast_icache = loongson2_blast_icache32; diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c index 563c2c0d0c81..38d3d9143b47 100644 --- a/arch/mips/mm/dma-noncoherent.c +++ b/arch/mips/mm/dma-noncoherent.c @@ -5,8 +5,7 @@ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf. */ #include <linux/dma-direct.h> -#include <linux/dma-noncoherent.h> -#include <linux/dma-contiguous.h> +#include <linux/dma-map-ops.h> #include <linux/highmem.h> #include <asm/cache.h> @@ -55,22 +54,34 @@ void *arch_dma_set_uncached(void *addr, size_t size) return (void *)(__pa(addr) + UNCAC_BASE); } -static inline void dma_sync_virt(void *addr, size_t size, +static inline void dma_sync_virt_for_device(void *addr, size_t size, enum dma_data_direction dir) { switch (dir) { case DMA_TO_DEVICE: dma_cache_wback((unsigned long)addr, size); break; - case DMA_FROM_DEVICE: dma_cache_inv((unsigned long)addr, size); break; - case DMA_BIDIRECTIONAL: dma_cache_wback_inv((unsigned long)addr, size); break; + default: + BUG(); + } +} +static inline void dma_sync_virt_for_cpu(void *addr, size_t size, + enum dma_data_direction dir) +{ + switch (dir) { + case DMA_TO_DEVICE: + break; + case DMA_FROM_DEVICE: + case DMA_BIDIRECTIONAL: + dma_cache_inv((unsigned long)addr, size); + break; default: BUG(); } @@ -82,7 +93,7 @@ static inline void dma_sync_virt(void *addr, size_t size, * configured then the bulk of this loop gets optimized out. */ static inline void dma_sync_phys(phys_addr_t paddr, size_t size, - enum dma_data_direction dir) + enum dma_data_direction dir, bool for_device) { struct page *page = pfn_to_page(paddr >> PAGE_SHIFT); unsigned long offset = paddr & ~PAGE_MASK; @@ -90,18 +101,20 @@ static inline void dma_sync_phys(phys_addr_t paddr, size_t size, do { size_t len = left; + void *addr; if (PageHighMem(page)) { - void *addr; - if (offset + len > PAGE_SIZE) len = PAGE_SIZE - offset; + } + + addr = kmap_atomic(page); + if (for_device) + dma_sync_virt_for_device(addr + offset, len, dir); + else + dma_sync_virt_for_cpu(addr + offset, len, dir); + kunmap_atomic(addr); - addr = kmap_atomic(page); - dma_sync_virt(addr + offset, len, dir); - kunmap_atomic(addr); - } else - dma_sync_virt(page_address(page) + offset, size, dir); offset = 0; page++; left -= len; @@ -111,7 +124,7 @@ static inline void dma_sync_phys(phys_addr_t paddr, size_t size, void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, enum dma_data_direction dir) { - dma_sync_phys(paddr, size, dir); + dma_sync_phys(paddr, size, dir, true); } #ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU @@ -119,18 +132,10 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, enum dma_data_direction dir) { if (cpu_needs_post_dma_flush()) - dma_sync_phys(paddr, size, dir); + dma_sync_phys(paddr, size, dir, false); } #endif -void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size, - enum dma_data_direction direction) -{ - BUG_ON(direction == DMA_NONE); - - dma_sync_virt(vaddr, size, direction); -} - #ifdef CONFIG_DMA_PERDEV_COHERENT void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, const struct iommu_ops *iommu, bool coherent) diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 6c7bbfe35ba3..07e84a774938 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -569,7 +569,7 @@ unsigned long pgd_current[NR_CPUS]; * size, and waste space. So we place it in its own section and align * it in the linker script. */ -pgd_t swapper_pg_dir[PTRS_PER_PGD] __section(.bss..swapper_pg_dir); +pgd_t swapper_pg_dir[PTRS_PER_PGD] __section(".bss..swapper_pg_dir"); #ifndef __PAGETABLE_PUD_FOLDED pud_t invalid_pud_table[PTRS_PER_PUD] __page_aligned_bss; #endif diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c index cd805b005509..504bc4047c4c 100644 --- a/arch/mips/mm/page.c +++ b/arch/mips/mm/page.c @@ -250,14 +250,16 @@ static inline void build_clear_pref(u32 **buf, int off) if (cpu_has_cache_cdex_s) { uasm_i_cache(buf, Create_Dirty_Excl_SD, off, A0); } else if (cpu_has_cache_cdex_p) { - if (R4600_V1_HIT_CACHEOP_WAR && cpu_is_r4600_v1_x()) { + if (IS_ENABLED(CONFIG_WAR_R4600_V1_HIT_CACHEOP) && + cpu_is_r4600_v1_x()) { uasm_i_nop(buf); uasm_i_nop(buf); uasm_i_nop(buf); uasm_i_nop(buf); } - if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) + if (IS_ENABLED(CONFIG_WAR_R4600_V2_HIT_CACHEOP) && + cpu_is_r4600_v2_x()) uasm_i_lw(buf, ZERO, ZERO, AT); uasm_i_cache(buf, Create_Dirty_Excl_D, off, A0); @@ -302,7 +304,7 @@ void build_clear_page(void) else uasm_i_ori(&buf, A2, A0, off); - if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) + if (IS_ENABLED(CONFIG_WAR_R4600_V2_HIT_CACHEOP) && cpu_is_r4600_v2_x()) uasm_i_lui(&buf, AT, uasm_rel_hi(0xa0000000)); off = cache_line_size ? min(8, pref_bias_clear_store / cache_line_size) @@ -402,14 +404,16 @@ static inline void build_copy_store_pref(u32 **buf, int off) if (cpu_has_cache_cdex_s) { uasm_i_cache(buf, Create_Dirty_Excl_SD, off, A0); } else if (cpu_has_cache_cdex_p) { - if (R4600_V1_HIT_CACHEOP_WAR && cpu_is_r4600_v1_x()) { + if (IS_ENABLED(CONFIG_WAR_R4600_V1_HIT_CACHEOP) && + cpu_is_r4600_v1_x()) { uasm_i_nop(buf); uasm_i_nop(buf); uasm_i_nop(buf); uasm_i_nop(buf); } - if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) + if (IS_ENABLED(CONFIG_WAR_R4600_V2_HIT_CACHEOP) && + cpu_is_r4600_v2_x()) uasm_i_lw(buf, ZERO, ZERO, AT); uasm_i_cache(buf, Create_Dirty_Excl_D, off, A0); @@ -453,7 +457,7 @@ void build_copy_page(void) else uasm_i_ori(&buf, A2, A0, off); - if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) + if (IS_ENABLED(CONFIG_WAR_R4600_V2_HIT_CACHEOP) && cpu_is_r4600_v2_x()) uasm_i_lui(&buf, AT, uasm_rel_hi(0xa0000000)); off = cache_line_size ? min(8, pref_bias_copy_load / cache_line_size) * diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c index 97dc0511e63f..dd0a5becaabd 100644 --- a/arch/mips/mm/sc-mips.c +++ b/arch/mips/mm/sc-mips.c @@ -228,6 +228,7 @@ static inline int __init mips_sc_probe(void) * contradicted by all documentation. */ case MACH_INGENIC_JZ4770: + case MACH_INGENIC_JZ4775: c->scache.ways = 4; break; @@ -236,6 +237,7 @@ static inline int __init mips_sc_probe(void) * but that is contradicted by all documentation. */ case MACH_INGENIC_X1000: + case MACH_INGENIC_X1000E: c->scache.sets = 256; c->scache.ways = 4; break; diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 14f8ba93367f..a7521b8f7658 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -83,14 +83,18 @@ static inline int r4k_250MHZhwbug(void) return 0; } +extern int sb1250_m3_workaround_needed(void); + static inline int __maybe_unused bcm1250_m3_war(void) { - return BCM1250_M3_WAR; + if (IS_ENABLED(CONFIG_SB1_PASS_2_WORKAROUNDS)) + return sb1250_m3_workaround_needed(); + return 0; } static inline int __maybe_unused r10000_llsc_war(void) { - return R10000_LLSC_WAR; + return IS_ENABLED(CONFIG_WAR_R10000_LLSC); } static int use_bbit_insns(void) diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index c56f129c9a4b..81dd226d6b6b 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c @@ -394,7 +394,7 @@ I_u2u1u3(_lddir) void uasm_i_pref(u32 **buf, unsigned int a, signed int b, unsigned int c) { - if (CAVIUM_OCTEON_DCACHE_PREFETCH_WAR && a <= 24 && a != 5) + if (OCTEON_IS_MODEL(OCTEON_CN6XXX) && a <= 24 && a != 5) /* * As per erratum Core-14449, replace prefetches 0-4, * 6-24 with 'pref 28'. diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index c4ad5a9b4bc1..e1fb8b534944 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c @@ -16,7 +16,6 @@ #include <asm/dma-coherence.h> #include <asm/fw/fw.h> -#include <asm/mach-malta/malta-dtshim.h> #include <asm/mips-cps.h> #include <asm/mips-boards/generic.h> #include <asm/mips-boards/malta.h> diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c index 1a0fc5b62ba4..9adc0c1b4ffc 100644 --- a/arch/mips/netlogic/xlp/setup.c +++ b/arch/mips/netlogic/xlp/setup.c @@ -70,7 +70,7 @@ static void nlm_fixup_mem(void) const int pref_backup = 512; struct memblock_region *mem; - for_each_memblock(memory, mem) { + for_each_mem_region(mem) { memblock_remove(mem->base + mem->size - pref_backup, pref_backup); } @@ -89,7 +89,7 @@ static void __init xlp_init_mem_from_bars(void) if (map[i] > 0x10000000 && map[i] < 0x20000000) map[i] = 0x20000000; - add_memory_region(map[i], map[i+1] - map[i], BOOT_MEM_RAM); + memblock_add(map[i], map[i+1] - map[i]); } } diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c index 72ceddc9a03f..627e88101316 100644 --- a/arch/mips/netlogic/xlr/setup.c +++ b/arch/mips/netlogic/xlr/setup.c @@ -34,6 +34,7 @@ #include <linux/kernel.h> #include <linux/serial_8250.h> +#include <linux/memblock.h> #include <linux/pm.h> #include <asm/idle.h> @@ -149,7 +150,7 @@ static void prom_add_memory(void) bootm = (void *)(long)nlm_prom_info.psb_mem_map; for (i = 0; i < bootm->nr_map; i++) { - if (bootm->map[i].type != BOOT_MEM_RAM) + if (bootm->map[i].type != NLM_BOOT_MEM_RAM) continue; start = bootm->map[i].addr; size = bootm->map[i].size; @@ -158,7 +159,7 @@ static void prom_add_memory(void) if (i == 0 && start == 0 && size == 0x0c000000) size = 0x0ff00000; - add_memory_region(start, size - pref_backup, BOOT_MEM_RAM); + memblock_add(start, size - pref_backup); } } diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c index 490953f51528..0b15730cef88 100644 --- a/arch/mips/pci/pci-ar2315.c +++ b/arch/mips/pci/pci-ar2315.c @@ -170,12 +170,12 @@ static inline dma_addr_t ar2315_dev_offset(struct device *dev) return 0; } -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { return paddr + ar2315_dev_offset(dev); } -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr) { return dma_addr - ar2315_dev_offset(dev); } @@ -423,9 +423,8 @@ static int ar2315_pci_probe(struct platform_device *pdev) return -EINVAL; apc->irq = irq; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "ar2315-pci-ctrl"); - apc->mmr_mem = devm_ioremap_resource(dev, res); + apc->mmr_mem = devm_platform_ioremap_resource_byname(pdev, + "ar2315-pci-ctrl"); if (IS_ERR(apc->mmr_mem)) return PTR_ERR(apc->mmr_mem); diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c index a9f8e7c881bd..118760b3fa82 100644 --- a/arch/mips/pci/pci-ar71xx.c +++ b/arch/mips/pci/pci-ar71xx.c @@ -336,8 +336,8 @@ static int ar71xx_pci_probe(struct platform_device *pdev) if (!apc) return -ENOMEM; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); - apc->cfg_base = devm_ioremap_resource(&pdev->dev, res); + apc->cfg_base = devm_platform_ioremap_resource_byname(pdev, + "cfg_base"); if (IS_ERR(apc->cfg_base)) return PTR_ERR(apc->cfg_base); diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 869d5c9a2f8d..807558b251ef 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c @@ -372,18 +372,15 @@ static int ar724x_pci_probe(struct platform_device *pdev) if (!apc) return -ENOMEM; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base"); - apc->ctrl_base = devm_ioremap_resource(&pdev->dev, res); + apc->ctrl_base = devm_platform_ioremap_resource_byname(pdev, "ctrl_base"); if (IS_ERR(apc->ctrl_base)) return PTR_ERR(apc->ctrl_base); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); - apc->devcfg_base = devm_ioremap_resource(&pdev->dev, res); + apc->devcfg_base = devm_platform_ioremap_resource_byname(pdev, "cfg_base"); if (IS_ERR(apc->devcfg_base)) return PTR_ERR(apc->devcfg_base); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "crp_base"); - apc->crp_base = devm_ioremap_resource(&pdev->dev, res); + apc->crp_base = devm_platform_ioremap_resource_byname(pdev, "crp_base"); if (IS_ERR(apc->crp_base)) return PTR_ERR(apc->crp_base); diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c index 9b3cc775c55e..50f7d42cca5a 100644 --- a/arch/mips/pci/pci-xtalk-bridge.c +++ b/arch/mips/pci/pci-xtalk-bridge.c @@ -25,7 +25,7 @@ /* * Common phys<->dma mapping for platforms using pci xtalk bridge */ -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { struct pci_dev *pdev = to_pci_dev(dev); struct bridge_controller *bc = BRIDGE_CONTROLLER(pdev->bus); @@ -33,7 +33,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) return bc->baddr + paddr; } -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr) { return dma_addr & ~(0xffUL << 56); } diff --git a/arch/mips/pnx833x/Makefile b/arch/mips/pnx833x/Makefile deleted file mode 100644 index 927268a58237..000000000000 --- a/arch/mips/pnx833x/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_SOC_PNX833X) += common/ -obj-$(CONFIG_NXP_STB220) += stb22x/ -obj-$(CONFIG_NXP_STB225) += stb22x/ diff --git a/arch/mips/pnx833x/Platform b/arch/mips/pnx833x/Platform deleted file mode 100644 index e5286a49fc3e..000000000000 --- a/arch/mips/pnx833x/Platform +++ /dev/null @@ -1,4 +0,0 @@ -# NXP STB225 -cflags-$(CONFIG_SOC_PNX833X) += -I$(srctree)/arch/mips/include/asm/mach-pnx833x -load-$(CONFIG_NXP_STB220) += 0xffffffff80001000 -load-$(CONFIG_NXP_STB225) += 0xffffffff80001000 diff --git a/arch/mips/pnx833x/common/Makefile b/arch/mips/pnx833x/common/Makefile deleted file mode 100644 index 9b4d394112b0..000000000000 --- a/arch/mips/pnx833x/common/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-y := interrupts.o platform.o prom.o setup.o reset.o diff --git a/arch/mips/pnx833x/common/interrupts.c b/arch/mips/pnx833x/common/interrupts.c deleted file mode 100644 index 2fbbabcac386..000000000000 --- a/arch/mips/pnx833x/common/interrupts.c +++ /dev/null @@ -1,303 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * interrupts.c: Interrupt mappings for PNX833X. - * - * Copyright 2008 NXP Semiconductors - * Chris Steel <chris.steel@nxp.com> - * Daniel Laird <daniel.j.laird@nxp.com> - */ -#include <linux/kernel.h> -#include <linux/irq.h> -#include <linux/hardirq.h> -#include <linux/interrupt.h> -#include <asm/mipsregs.h> -#include <asm/irq_cpu.h> -#include <asm/setup.h> -#include <irq.h> -#include <irq-mapping.h> -#include <gpio.h> - -static int mips_cpu_timer_irq; - -static const unsigned int irq_prio[PNX833X_PIC_NUM_IRQ] = -{ - 0, /* unused */ - 4, /* PNX833X_PIC_I2C0_INT 1 */ - 4, /* PNX833X_PIC_I2C1_INT 2 */ - 1, /* PNX833X_PIC_UART0_INT 3 */ - 1, /* PNX833X_PIC_UART1_INT 4 */ - 6, /* PNX833X_PIC_TS_IN0_DV_INT 5 */ - 6, /* PNX833X_PIC_TS_IN0_DMA_INT 6 */ - 7, /* PNX833X_PIC_GPIO_INT 7 */ - 4, /* PNX833X_PIC_AUDIO_DEC_INT 8 */ - 5, /* PNX833X_PIC_VIDEO_DEC_INT 9 */ - 4, /* PNX833X_PIC_CONFIG_INT 10 */ - 4, /* PNX833X_PIC_AOI_INT 11 */ - 9, /* PNX833X_PIC_SYNC_INT 12 */ - 9, /* PNX8335_PIC_SATA_INT 13 */ - 4, /* PNX833X_PIC_OSD_INT 14 */ - 9, /* PNX833X_PIC_DISP1_INT 15 */ - 4, /* PNX833X_PIC_DEINTERLACER_INT 16 */ - 9, /* PNX833X_PIC_DISPLAY2_INT 17 */ - 4, /* PNX833X_PIC_VC_INT 18 */ - 4, /* PNX833X_PIC_SC_INT 19 */ - 9, /* PNX833X_PIC_IDE_INT 20 */ - 9, /* PNX833X_PIC_IDE_DMA_INT 21 */ - 6, /* PNX833X_PIC_TS_IN1_DV_INT 22 */ - 6, /* PNX833X_PIC_TS_IN1_DMA_INT 23 */ - 4, /* PNX833X_PIC_SGDX_DMA_INT 24 */ - 4, /* PNX833X_PIC_TS_OUT_INT 25 */ - 4, /* PNX833X_PIC_IR_INT 26 */ - 3, /* PNX833X_PIC_VMSP1_INT 27 */ - 3, /* PNX833X_PIC_VMSP2_INT 28 */ - 4, /* PNX833X_PIC_PIBC_INT 29 */ - 4, /* PNX833X_PIC_TS_IN0_TRD_INT 30 */ - 4, /* PNX833X_PIC_SGDX_TPD_INT 31 */ - 5, /* PNX833X_PIC_USB_INT 32 */ - 4, /* PNX833X_PIC_TS_IN1_TRD_INT 33 */ - 4, /* PNX833X_PIC_CLOCK_INT 34 */ - 4, /* PNX833X_PIC_SGDX_PARSER_INT 35 */ - 4, /* PNX833X_PIC_VMSP_DMA_INT 36 */ -#if defined(CONFIG_SOC_PNX8335) - 4, /* PNX8335_PIC_MIU_INT 37 */ - 4, /* PNX8335_PIC_AVCHIP_IRQ_INT 38 */ - 9, /* PNX8335_PIC_SYNC_HD_INT 39 */ - 9, /* PNX8335_PIC_DISP_HD_INT 40 */ - 9, /* PNX8335_PIC_DISP_SCALER_INT 41 */ - 4, /* PNX8335_PIC_OSD_HD1_INT 42 */ - 4, /* PNX8335_PIC_DTL_WRITER_Y_INT 43 */ - 4, /* PNX8335_PIC_DTL_WRITER_C_INT 44 */ - 4, /* PNX8335_PIC_DTL_EMULATOR_Y_IR_INT 45 */ - 4, /* PNX8335_PIC_DTL_EMULATOR_C_IR_INT 46 */ - 4, /* PNX8335_PIC_DENC_TTX_INT 47 */ - 4, /* PNX8335_PIC_MMI_SIF0_INT 48 */ - 4, /* PNX8335_PIC_MMI_SIF1_INT 49 */ - 4, /* PNX8335_PIC_MMI_CDMMU_INT 50 */ - 4, /* PNX8335_PIC_PIBCS_INT 51 */ - 12, /* PNX8335_PIC_ETHERNET_INT 52 */ - 3, /* PNX8335_PIC_VMSP1_0_INT 53 */ - 3, /* PNX8335_PIC_VMSP1_1_INT 54 */ - 4, /* PNX8335_PIC_VMSP1_DMA_INT 55 */ - 4, /* PNX8335_PIC_TDGR_DE_INT 56 */ - 4, /* PNX8335_PIC_IR1_IRQ_INT 57 */ -#endif -}; - -static void pnx833x_timer_dispatch(void) -{ - do_IRQ(mips_cpu_timer_irq); -} - -static void pic_dispatch(void) -{ - unsigned int irq = PNX833X_REGFIELD(PIC_INT_SRC, INT_SRC); - - if ((irq >= 1) && (irq < (PNX833X_PIC_NUM_IRQ))) { - unsigned long priority = PNX833X_PIC_INT_PRIORITY; - PNX833X_PIC_INT_PRIORITY = irq_prio[irq]; - - if (irq == PNX833X_PIC_GPIO_INT) { - unsigned long mask = PNX833X_PIO_INT_STATUS & PNX833X_PIO_INT_ENABLE; - int pin; - while ((pin = ffs(mask & 0xffff))) { - pin -= 1; - do_IRQ(PNX833X_GPIO_IRQ_BASE + pin); - mask &= ~(1 << pin); - } - } else { - do_IRQ(irq + PNX833X_PIC_IRQ_BASE); - } - - PNX833X_PIC_INT_PRIORITY = priority; - } else { - printk(KERN_ERR "plat_irq_dispatch: unexpected irq %u\n", irq); - } -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_status() & read_c0_cause(); - - if (pending & STATUSF_IP4) - pic_dispatch(); - else if (pending & STATUSF_IP7) - do_IRQ(PNX833X_TIMER_IRQ); - else - spurious_interrupt(); -} - -static inline void pnx833x_hard_enable_pic_irq(unsigned int irq) -{ - /* Currently we do this by setting IRQ priority to 1. - If priority support is being implemented, 1 should be repalced - by a better value. */ - PNX833X_PIC_INT_REG(irq) = irq_prio[irq]; -} - -static inline void pnx833x_hard_disable_pic_irq(unsigned int irq) -{ - /* Disable IRQ by writing setting it's priority to 0 */ - PNX833X_PIC_INT_REG(irq) = 0; -} - -static DEFINE_RAW_SPINLOCK(pnx833x_irq_lock); - -static unsigned int pnx833x_startup_pic_irq(unsigned int irq) -{ - unsigned long flags; - unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; - - raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); - pnx833x_hard_enable_pic_irq(pic_irq); - raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); - return 0; -} - -static void pnx833x_enable_pic_irq(struct irq_data *d) -{ - unsigned long flags; - unsigned int pic_irq = d->irq - PNX833X_PIC_IRQ_BASE; - - raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); - pnx833x_hard_enable_pic_irq(pic_irq); - raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); -} - -static void pnx833x_disable_pic_irq(struct irq_data *d) -{ - unsigned long flags; - unsigned int pic_irq = d->irq - PNX833X_PIC_IRQ_BASE; - - raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); - pnx833x_hard_disable_pic_irq(pic_irq); - raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); -} - -static DEFINE_RAW_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock); - -static void pnx833x_enable_gpio_irq(struct irq_data *d) -{ - int pin = d->irq - PNX833X_GPIO_IRQ_BASE; - unsigned long flags; - raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); - pnx833x_gpio_enable_irq(pin); - raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); -} - -static void pnx833x_disable_gpio_irq(struct irq_data *d) -{ - int pin = d->irq - PNX833X_GPIO_IRQ_BASE; - unsigned long flags; - raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); - pnx833x_gpio_disable_irq(pin); - raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); -} - -static int pnx833x_set_type_gpio_irq(struct irq_data *d, unsigned int flow_type) -{ - int pin = d->irq - PNX833X_GPIO_IRQ_BASE; - int gpio_mode; - - switch (flow_type) { - case IRQ_TYPE_EDGE_RISING: - gpio_mode = GPIO_INT_EDGE_RISING; - break; - case IRQ_TYPE_EDGE_FALLING: - gpio_mode = GPIO_INT_EDGE_FALLING; - break; - case IRQ_TYPE_EDGE_BOTH: - gpio_mode = GPIO_INT_EDGE_BOTH; - break; - case IRQ_TYPE_LEVEL_HIGH: - gpio_mode = GPIO_INT_LEVEL_HIGH; - break; - case IRQ_TYPE_LEVEL_LOW: - gpio_mode = GPIO_INT_LEVEL_LOW; - break; - default: - gpio_mode = GPIO_INT_NONE; - break; - } - - pnx833x_gpio_setup_irq(gpio_mode, pin); - - return 0; -} - -static struct irq_chip pnx833x_pic_irq_type = { - .name = "PNX-PIC", - .irq_enable = pnx833x_enable_pic_irq, - .irq_disable = pnx833x_disable_pic_irq, -}; - -static struct irq_chip pnx833x_gpio_irq_type = { - .name = "PNX-GPIO", - .irq_enable = pnx833x_enable_gpio_irq, - .irq_disable = pnx833x_disable_gpio_irq, - .irq_set_type = pnx833x_set_type_gpio_irq, -}; - -void __init arch_init_irq(void) -{ - unsigned int irq; - - /* setup standard internal cpu irqs */ - mips_cpu_irq_init(); - - /* Set IRQ information in irq_desc */ - for (irq = PNX833X_PIC_IRQ_BASE; irq < (PNX833X_PIC_IRQ_BASE + PNX833X_PIC_NUM_IRQ); irq++) { - pnx833x_hard_disable_pic_irq(irq); - irq_set_chip_and_handler(irq, &pnx833x_pic_irq_type, - handle_simple_irq); - } - - for (irq = PNX833X_GPIO_IRQ_BASE; irq < (PNX833X_GPIO_IRQ_BASE + PNX833X_GPIO_NUM_IRQ); irq++) - irq_set_chip_and_handler(irq, &pnx833x_gpio_irq_type, - handle_simple_irq); - - /* Set PIC priority limiter register to 0 */ - PNX833X_PIC_INT_PRIORITY = 0; - - /* Setup GPIO IRQ dispatching */ - pnx833x_startup_pic_irq(PNX833X_PIC_GPIO_INT); - - /* Enable PIC IRQs (HWIRQ2) */ - if (cpu_has_vint) - set_vi_handler(4, pic_dispatch); - - write_c0_status(read_c0_status() | IE_IRQ2); -} - -unsigned int get_c0_compare_int(void) -{ - if (cpu_has_vint) - set_vi_handler(cp0_compare_irq, pnx833x_timer_dispatch); - - mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; - return mips_cpu_timer_irq; -} - -void __init plat_time_init(void) -{ - /* calculate mips_hpt_frequency based on PNX833X_CLOCK_CPUCP_CTL reg */ - - extern unsigned long mips_hpt_frequency; - unsigned long reg = PNX833X_CLOCK_CPUCP_CTL; - - if (!(PNX833X_BIT(reg, CLOCK_CPUCP_CTL, EXIT_RESET))) { - /* Functional clock is disabled so use crystal frequency */ - mips_hpt_frequency = 25; - } else { -#if defined(CONFIG_SOC_PNX8335) - /* Functional clock is enabled, so get clock multiplier */ - mips_hpt_frequency = 90 + (10 * PNX8335_REGFIELD(CLOCK_PLL_CPU_CTL, FREQ)); -#else - static const unsigned long int freq[4] = {240, 160, 120, 80}; - mips_hpt_frequency = freq[PNX833X_FIELD(reg, CLOCK_CPUCP_CTL, DIV_CLOCK)]; -#endif - } - - printk(KERN_INFO "CPU clock is %ld MHz\n", mips_hpt_frequency); - - mips_hpt_frequency *= 500000; -} diff --git a/arch/mips/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c deleted file mode 100644 index 5fa0373f1c9e..000000000000 --- a/arch/mips/pnx833x/common/platform.c +++ /dev/null @@ -1,224 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * platform.c: platform support for PNX833X. - * - * Copyright 2008 NXP Semiconductors - * Chris Steel <chris.steel@nxp.com> - * Daniel Laird <daniel.j.laird@nxp.com> - * - * Based on software written by: - * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code. - */ -#include <linux/device.h> -#include <linux/dma-mapping.h> -#include <linux/platform_device.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/resource.h> -#include <linux/serial.h> -#include <linux/serial_pnx8xxx.h> -#include <linux/mtd/platnand.h> - -#include <irq.h> -#include <irq-mapping.h> -#include <pnx833x.h> - -static u64 uart_dmamask = DMA_BIT_MASK(32); - -static struct resource pnx833x_uart_resources[] = { - [0] = { - .start = PNX833X_UART0_PORTS_START, - .end = PNX833X_UART0_PORTS_END, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = PNX833X_PIC_UART0_INT, - .end = PNX833X_PIC_UART0_INT, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = PNX833X_UART1_PORTS_START, - .end = PNX833X_UART1_PORTS_END, - .flags = IORESOURCE_MEM, - }, - [3] = { - .start = PNX833X_PIC_UART1_INT, - .end = PNX833X_PIC_UART1_INT, - .flags = IORESOURCE_IRQ, - }, -}; - -struct pnx8xxx_port pnx8xxx_ports[] = { - [0] = { - .port = { - .type = PORT_PNX8XXX, - .iotype = UPIO_MEM, - .membase = (void __iomem *)PNX833X_UART0_PORTS_START, - .mapbase = PNX833X_UART0_PORTS_START, - .irq = PNX833X_PIC_UART0_INT, - .uartclk = 3692300, - .fifosize = 16, - .flags = UPF_BOOT_AUTOCONF, - .line = 0, - }, - }, - [1] = { - .port = { - .type = PORT_PNX8XXX, - .iotype = UPIO_MEM, - .membase = (void __iomem *)PNX833X_UART1_PORTS_START, - .mapbase = PNX833X_UART1_PORTS_START, - .irq = PNX833X_PIC_UART1_INT, - .uartclk = 3692300, - .fifosize = 16, - .flags = UPF_BOOT_AUTOCONF, - .line = 1, - }, - }, -}; - -static struct platform_device pnx833x_uart_device = { - .name = "pnx8xxx-uart", - .id = -1, - .dev = { - .dma_mask = &uart_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = pnx8xxx_ports, - }, - .num_resources = ARRAY_SIZE(pnx833x_uart_resources), - .resource = pnx833x_uart_resources, -}; - -static u64 ehci_dmamask = DMA_BIT_MASK(32); - -static struct resource pnx833x_usb_ehci_resources[] = { - [0] = { - .start = PNX833X_USB_PORTS_START, - .end = PNX833X_USB_PORTS_END, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = PNX833X_PIC_USB_INT, - .end = PNX833X_PIC_USB_INT, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device pnx833x_usb_ehci_device = { - .name = "pnx833x-ehci", - .id = -1, - .dev = { - .dma_mask = &ehci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .num_resources = ARRAY_SIZE(pnx833x_usb_ehci_resources), - .resource = pnx833x_usb_ehci_resources, -}; - -static u64 ethernet_dmamask = DMA_BIT_MASK(32); - -static struct resource pnx833x_ethernet_resources[] = { - [0] = { - .start = PNX8335_IP3902_PORTS_START, - .end = PNX8335_IP3902_PORTS_END, - .flags = IORESOURCE_MEM, - }, -#ifdef CONFIG_SOC_PNX8335 - [1] = { - .start = PNX8335_PIC_ETHERNET_INT, - .end = PNX8335_PIC_ETHERNET_INT, - .flags = IORESOURCE_IRQ, - }, -#endif -}; - -static struct platform_device pnx833x_ethernet_device = { - .name = "ip3902-eth", - .id = -1, - .dev = { - .dma_mask = ðernet_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .num_resources = ARRAY_SIZE(pnx833x_ethernet_resources), - .resource = pnx833x_ethernet_resources, -}; - -static struct resource pnx833x_sata_resources[] = { - [0] = { - .start = PNX8335_SATA_PORTS_START, - .end = PNX8335_SATA_PORTS_END, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = PNX8335_PIC_SATA_INT, - .end = PNX8335_PIC_SATA_INT, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device pnx833x_sata_device = { - .name = "pnx833x-sata", - .id = -1, - .num_resources = ARRAY_SIZE(pnx833x_sata_resources), - .resource = pnx833x_sata_resources, -}; - -static void -pnx833x_flash_nand_cmd_ctrl(struct nand_chip *this, int cmd, unsigned int ctrl) -{ - unsigned long nandaddr = (unsigned long)this->legacy.IO_ADDR_W; - - if (cmd == NAND_CMD_NONE) - return; - - if (ctrl & NAND_CLE) - writeb(cmd, (void __iomem *)(nandaddr + PNX8335_NAND_CLE_MASK)); - else - writeb(cmd, (void __iomem *)(nandaddr + PNX8335_NAND_ALE_MASK)); -} - -static struct platform_nand_data pnx833x_flash_nand_data = { - .chip = { - .nr_chips = 1, - .chip_delay = 25, - }, - .ctrl = { - .cmd_ctrl = pnx833x_flash_nand_cmd_ctrl - } -}; - -/* - * Set start to be the correct address (PNX8335_NAND_BASE with no 0xb!!), - * 12 bytes more seems to be the standard that allows for NAND access. - */ -static struct resource pnx833x_flash_nand_resource = { - .start = PNX8335_NAND_BASE, - .end = PNX8335_NAND_BASE + 12, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device pnx833x_flash_nand = { - .name = "gen_nand", - .id = -1, - .num_resources = 1, - .resource = &pnx833x_flash_nand_resource, - .dev = { - .platform_data = &pnx833x_flash_nand_data, - }, -}; - -static struct platform_device *pnx833x_platform_devices[] __initdata = { - &pnx833x_uart_device, - &pnx833x_usb_ehci_device, - &pnx833x_ethernet_device, - &pnx833x_sata_device, - &pnx833x_flash_nand, -}; - -static int __init pnx833x_platform_init(void) -{ - return platform_add_devices(pnx833x_platform_devices, - ARRAY_SIZE(pnx833x_platform_devices)); -} - -arch_initcall(pnx833x_platform_init); diff --git a/arch/mips/pnx833x/common/prom.c b/arch/mips/pnx833x/common/prom.c deleted file mode 100644 index 12733ef25782..000000000000 --- a/arch/mips/pnx833x/common/prom.c +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * prom.c: - * - * Copyright 2008 NXP Semiconductors - * Chris Steel <chris.steel@nxp.com> - * Daniel Laird <daniel.j.laird@nxp.com> - * - * Based on software written by: - * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code. - */ -#include <linux/init.h> -#include <asm/bootinfo.h> -#include <linux/string.h> - -void __init prom_init_cmdline(void) -{ - int argc = fw_arg0; - char **argv = (char **)fw_arg1; - char *c = &(arcs_cmdline[0]); - int i; - - for (i = 1; i < argc; i++) { - strcpy(c, argv[i]); - c += strlen(argv[i]); - if (i < argc-1) - *c++ = ' '; - } - *c = 0; -} - -char __init *prom_getenv(char *envname) -{ - extern char **prom_envp; - char **env = prom_envp; - int i; - - i = strlen(envname); - - while (*env) { - if (strncmp(envname, *env, i) == 0 && *(*env+i) == '=') - return *env + i + 1; - env++; - } - - return 0; -} - -void __init prom_free_prom_memory(void) -{ -} diff --git a/arch/mips/pnx833x/common/reset.c b/arch/mips/pnx833x/common/reset.c deleted file mode 100644 index b48e83bf912b..000000000000 --- a/arch/mips/pnx833x/common/reset.c +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * reset.c: reset support for PNX833X. - * - * Copyright 2008 NXP Semiconductors - * Chris Steel <chris.steel@nxp.com> - * Daniel Laird <daniel.j.laird@nxp.com> - * - * Based on software written by: - * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code. - */ -#include <linux/reboot.h> -#include <pnx833x.h> - -void pnx833x_machine_restart(char *command) -{ - PNX833X_RESET_CONTROL_2 = 0; - PNX833X_RESET_CONTROL = 0; -} - -void pnx833x_machine_halt(void) -{ - while (1) - __asm__ __volatile__ ("wait"); - -} - -void pnx833x_machine_power_off(void) -{ - pnx833x_machine_halt(); -} diff --git a/arch/mips/pnx833x/common/setup.c b/arch/mips/pnx833x/common/setup.c deleted file mode 100644 index abf68d92ce4a..000000000000 --- a/arch/mips/pnx833x/common/setup.c +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * setup.c: Setup PNX833X Soc. - * - * Copyright 2008 NXP Semiconductors - * Chris Steel <chris.steel@nxp.com> - * Daniel Laird <daniel.j.laird@nxp.com> - * - * Based on software written by: - * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code. - */ -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/io.h> -#include <linux/pci.h> -#include <asm/reboot.h> -#include <pnx833x.h> -#include <gpio.h> - -extern void pnx833x_board_setup(void); -extern void pnx833x_machine_restart(char *); -extern void pnx833x_machine_halt(void); -extern void pnx833x_machine_power_off(void); - -int __init plat_mem_setup(void) -{ - /* set mips clock to 320MHz */ -#if defined(CONFIG_SOC_PNX8335) - PNX8335_WRITEFIELD(0x17, CLOCK_PLL_CPU_CTL, FREQ); -#endif - pnx833x_gpio_init(); /* so it will be ready in board_setup() */ - - pnx833x_board_setup(); - - _machine_restart = pnx833x_machine_restart; - _machine_halt = pnx833x_machine_halt; - pm_power_off = pnx833x_machine_power_off; - - /* IO/MEM resources. */ - set_io_port_base(KSEG1); - ioport_resource.start = 0; - ioport_resource.end = ~0; - iomem_resource.start = 0; - iomem_resource.end = ~0; - - return 0; -} diff --git a/arch/mips/pnx833x/stb22x/Makefile b/arch/mips/pnx833x/stb22x/Makefile deleted file mode 100644 index 7c5ddf36b735..000000000000 --- a/arch/mips/pnx833x/stb22x/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-y := board.o diff --git a/arch/mips/pnx833x/stb22x/board.c b/arch/mips/pnx833x/stb22x/board.c deleted file mode 100644 index 93d8e7b73427..000000000000 --- a/arch/mips/pnx833x/stb22x/board.c +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * board.c: STB225 board support. - * - * Copyright 2008 NXP Semiconductors - * Chris Steel <chris.steel@nxp.com> - * Daniel Laird <daniel.j.laird@nxp.com> - * - * Based on software written by: - * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code. - */ -#include <linux/init.h> -#include <asm/bootinfo.h> -#include <linux/mm.h> -#include <pnx833x.h> -#include <gpio.h> - -/* endianess twiddlers */ -#define PNX8335_DEBUG0 0x4400 -#define PNX8335_DEBUG1 0x4404 -#define PNX8335_DEBUG2 0x4408 -#define PNX8335_DEBUG3 0x440c -#define PNX8335_DEBUG4 0x4410 -#define PNX8335_DEBUG5 0x4414 -#define PNX8335_DEBUG6 0x4418 -#define PNX8335_DEBUG7 0x441c - -int prom_argc; -char **prom_argv, **prom_envp; - -extern void prom_init_cmdline(void); -extern char *prom_getenv(char *envname); - -const char *get_system_type(void) -{ - return "NXP STB22x"; -} - -static inline unsigned long env_or_default(char *env, unsigned long dfl) -{ - char *str = prom_getenv(env); - return str ? simple_strtol(str, 0, 0) : dfl; -} - -void __init prom_init(void) -{ - unsigned long memsize; - - prom_argc = fw_arg0; - prom_argv = (char **)fw_arg1; - prom_envp = (char **)fw_arg2; - - prom_init_cmdline(); - - memsize = env_or_default("memsize", 0x02000000); - add_memory_region(0, memsize, BOOT_MEM_RAM); -} - -void __init pnx833x_board_setup(void) -{ - pnx833x_gpio_select_function_alt(4); - pnx833x_gpio_select_output(4); - pnx833x_gpio_select_function_alt(5); - pnx833x_gpio_select_input(5); - pnx833x_gpio_select_function_alt(6); - pnx833x_gpio_select_input(6); - pnx833x_gpio_select_function_alt(7); - pnx833x_gpio_select_output(7); - - pnx833x_gpio_select_function_alt(25); - pnx833x_gpio_select_function_alt(26); - - pnx833x_gpio_select_function_alt(27); - pnx833x_gpio_select_function_alt(28); - pnx833x_gpio_select_function_alt(29); - pnx833x_gpio_select_function_alt(30); - pnx833x_gpio_select_function_alt(31); - pnx833x_gpio_select_function_alt(32); - pnx833x_gpio_select_function_alt(33); - -#if IS_ENABLED(CONFIG_MTD_NAND_PLATFORM) - /* Setup MIU for NAND access on CS0... - * - * (it seems that we must also configure CS1 for reliable operation, - * otherwise the first read ID command will fail if it's read as 4 bytes - * but pass if it's read as 1 word.) - */ - - /* Setup MIU CS0 & CS1 timing */ - PNX833X_MIU_SEL0 = 0; - PNX833X_MIU_SEL1 = 0; - PNX833X_MIU_SEL0_TIMING = 0x50003081; - PNX833X_MIU_SEL1_TIMING = 0x50003081; - - /* Setup GPIO 00 for use as MIU CS1 (CS0 is not multiplexed, so does not need this) */ - pnx833x_gpio_select_function_alt(0); - - /* Setup GPIO 04 to input NAND read/busy signal */ - pnx833x_gpio_select_function_io(4); - pnx833x_gpio_select_input(4); - - /* Setup GPIO 05 to disable NAND write protect */ - pnx833x_gpio_select_function_io(5); - pnx833x_gpio_select_output(5); - pnx833x_gpio_write(1, 5); - -#elif IS_ENABLED(CONFIG_MTD_CFI) - - /* Set up MIU for 16-bit NOR access on CS0 and CS1... */ - - /* Setup MIU CS0 & CS1 timing */ - PNX833X_MIU_SEL0 = 1; - PNX833X_MIU_SEL1 = 1; - PNX833X_MIU_SEL0_TIMING = 0x6A08D082; - PNX833X_MIU_SEL1_TIMING = 0x6A08D082; - - /* Setup GPIO 00 for use as MIU CS1 (CS0 is not multiplexed, so does not need this) */ - pnx833x_gpio_select_function_alt(0); -#endif -} diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index 90c6d4a11c5d..cbae9d23ab7f 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c @@ -84,8 +84,7 @@ void __init plat_mem_setup(void) if (memory_dtb) of_scan_flat_dt(early_init_dt_scan_memory, NULL); else if (soc_info.mem_size) - add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M, - BOOT_MEM_RAM); + memblock_add(soc_info.mem_base, soc_info.mem_size * SZ_1M); else detect_memory_region(soc_info.mem_base, soc_info.mem_size_min * SZ_1M, diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c index 303cc3dc1749..a9d1f2019dc3 100644 --- a/arch/mips/rb532/prom.c +++ b/arch/mips/rb532/prom.c @@ -126,5 +126,5 @@ void __init prom_init(void) /* give all RAM to boot allocator, * except for the first 0x400 and the last 0x200 bytes */ - add_memory_region(ddrbase + 0x400, memsize - 0x600, BOOT_MEM_RAM); + memblock_add(ddrbase + 0x400, memsize - 0x600); } diff --git a/arch/mips/sgi-ip30/ip30-common.h b/arch/mips/sgi-ip30/ip30-common.h index d2bcaee712f3..7b5db24b6279 100644 --- a/arch/mips/sgi-ip30/ip30-common.h +++ b/arch/mips/sgi-ip30/ip30-common.h @@ -3,6 +3,20 @@ #ifndef __IP30_COMMON_H #define __IP30_COMMON_H +/* + * Power Switch is wired via BaseIO BRIDGE slot #6. + * + * ACFail is wired via BaseIO BRIDGE slot #7. + */ +#define IP30_POWER_IRQ HEART_L2_INT_POWER_BTN + +#define IP30_HEART_L0_IRQ (MIPS_CPU_IRQ_BASE + 2) +#define IP30_HEART_L1_IRQ (MIPS_CPU_IRQ_BASE + 3) +#define IP30_HEART_L2_IRQ (MIPS_CPU_IRQ_BASE + 4) +#define IP30_HEART_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 5) +#define IP30_HEART_ERR_IRQ (MIPS_CPU_IRQ_BASE + 6) + +extern void __init ip30_install_ipi(void); extern struct plat_smp_ops ip30_smp_ops; extern void __init ip30_per_cpu_init(void); diff --git a/arch/mips/sgi-ip30/ip30-irq.c b/arch/mips/sgi-ip30/ip30-irq.c index c2ffcb920250..e8374e4c705b 100644 --- a/arch/mips/sgi-ip30/ip30-irq.c +++ b/arch/mips/sgi-ip30/ip30-irq.c @@ -14,6 +14,8 @@ #include <asm/irq_cpu.h> #include <asm/sgi/heart.h> +#include "ip30-common.h" + struct heart_irq_data { u64 *irq_mask; int cpu; diff --git a/arch/mips/sgi-ip32/ip32-dma.c b/arch/mips/sgi-ip32/ip32-dma.c index fa7b17cb5385..20c6da9d76bc 100644 --- a/arch/mips/sgi-ip32/ip32-dma.c +++ b/arch/mips/sgi-ip32/ip32-dma.c @@ -18,7 +18,7 @@ #define RAM_OFFSET_MASK 0x3fffffffUL -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { dma_addr_t dma_addr = paddr & RAM_OFFSET_MASK; @@ -27,7 +27,7 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) return dma_addr; } -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr) { phys_addr_t paddr = dma_addr & RAM_OFFSET_MASK; diff --git a/arch/mips/sgi-ip32/ip32-memory.c b/arch/mips/sgi-ip32/ip32-memory.c index 62b956cc2d1d..0f53fed39da6 100644 --- a/arch/mips/sgi-ip32/ip32-memory.c +++ b/arch/mips/sgi-ip32/ip32-memory.c @@ -9,6 +9,7 @@ #include <linux/types.h> #include <linux/init.h> #include <linux/kernel.h> +#include <linux/memblock.h> #include <linux/mm.h> #include <asm/ip32/crime.h> @@ -36,7 +37,7 @@ void __init prom_meminit(void) printk("CRIME MC: bank %u base 0x%016Lx size %LuMiB\n", bank, base, size >> 20); - add_memory_region(base, size, BOOT_MEM_RAM); + memblock_add(base, size); } } diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c index 3abd1465ec02..8019dae1721a 100644 --- a/arch/mips/sgi-ip32/ip32-setup.c +++ b/arch/mips/sgi-ip32/ip32-setup.c @@ -12,12 +12,10 @@ #include <linux/console.h> #include <linux/init.h> #include <linux/interrupt.h> -#include <linux/mc146818rtc.h> #include <linux/param.h> #include <linux/sched.h> #include <asm/bootinfo.h> -#include <asm/mc146818-time.h> #include <asm/mipsregs.h> #include <asm/mmu_context.h> #include <asm/sgialib.h> diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c index cbf5939ed53a..89f7fca45152 100644 --- a/arch/mips/sibyte/common/cfe.c +++ b/arch/mips/sibyte/common/cfe.c @@ -114,16 +114,14 @@ static __init void prom_meminit(void) if (initrd_start) { if ((initrd_pstart > addr) && (initrd_pstart < (addr + size))) { - add_memory_region(addr, - initrd_pstart - addr, - BOOT_MEM_RAM); + memblock_add(addr, + initrd_pstart - addr); rd_flag = 1; } if ((initrd_pend > addr) && (initrd_pend < (addr + size))) { - add_memory_region(initrd_pend, - (addr + size) - initrd_pend, - BOOT_MEM_RAM); + memblock_add(initrd_pend, + (addr + size) - initrd_pend); rd_flag = 1; } } @@ -142,7 +140,7 @@ static __init void prom_meminit(void) */ if (size > 512) size -= 512; - add_memory_region(addr, size, BOOT_MEM_RAM); + memblock_add(addr, size); } board_mem_region_addrs[board_mem_region_count] = addr; board_mem_region_sizes[board_mem_region_count] = size; @@ -158,8 +156,8 @@ static __init void prom_meminit(void) } #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) { - add_memory_region(initrd_pstart, initrd_pend - initrd_pstart, - BOOT_MEM_RESERVED); + memblock_add(initrd_pstart, initrd_pend - initrd_pstart); + memblock_reserve(initrd_pstart, initrd_pend - initrd_pstart); } #endif } diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c index b09dc844985a..eeeec18c420a 100644 --- a/arch/mips/sni/a20r.c +++ b/arch/mips/sni/a20r.c @@ -143,7 +143,10 @@ static struct platform_device sc26xx_pdev = { }, }; -static u32 a20r_ack_hwint(void) +/* + * Trigger chipset to update CPU's CAUSE IP field + */ +static u32 a20r_update_cause_ip(void) { u32 status = read_c0_status(); @@ -205,12 +208,14 @@ static void a20r_hwint(void) int irq; clear_c0_status(IE_IRQ0); - status = a20r_ack_hwint(); + status = a20r_update_cause_ip(); cause = read_c0_cause(); irq = ffs(((cause & status) >> 8) & 0xf8); if (likely(irq > 0)) do_IRQ(SNI_A20R_IRQ_BASE + irq - 1); + + a20r_update_cause_ip(); set_c0_status(IE_IRQ0); } diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c index 360c388f4c82..bf8a3cdababf 100644 --- a/arch/mips/txx9/generic/setup_tx4939.c +++ b/arch/mips/txx9/generic/setup_tx4939.c @@ -22,7 +22,6 @@ #include <linux/mtd/physmap.h> #include <linux/platform_device.h> #include <linux/platform_data/txx9/ndfmc.h> -#include <asm/bootinfo.h> #include <asm/reboot.h> #include <asm/traps.h> #include <asm/txx9irq.h> @@ -94,22 +93,6 @@ static struct resource tx4939_sdram_resource[4]; static struct resource tx4939_sram_resource; #define TX4939_SRAM_SIZE 0x800 -void __init tx4939_add_memory_regions(void) -{ - int i; - unsigned long start, size; - u64 win; - - for (i = 0; i < 4; i++) { - if (!((__u32)____raw_readq(&tx4939_ddrcptr->winen) & (1 << i))) - continue; - win = ____raw_readq(&tx4939_ddrcptr->win[i]); - start = (unsigned long)(win >> 48); - size = (((unsigned long)(win >> 32) & 0xffff) + 1) - start; - add_memory_region(start << 20, size << 20, BOOT_MEM_RAM); - } -} - void __init tx4939_setup(void) { int i; diff --git a/arch/mips/txx9/jmr3927/prom.c b/arch/mips/txx9/jmr3927/prom.c index 68a96473c134..53c68de54d30 100644 --- a/arch/mips/txx9/jmr3927/prom.c +++ b/arch/mips/txx9/jmr3927/prom.c @@ -37,7 +37,7 @@ */ #include <linux/init.h> #include <linux/kernel.h> -#include <asm/bootinfo.h> +#include <linux/memblock.h> #include <asm/txx9/generic.h> #include <asm/txx9/jmr3927.h> @@ -47,6 +47,6 @@ void __init jmr3927_prom_init(void) if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0) pr_err("TX3927 TLB off\n"); - add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM); + memblock_add(0, JMR3927_SDRAM_SIZE); txx9_sio_putchar_init(TX3927_SIO_REG(1)); } diff --git a/arch/mips/txx9/rbtx4927/prom.c b/arch/mips/txx9/rbtx4927/prom.c index fe6d0b54763f..9b4acff826eb 100644 --- a/arch/mips/txx9/rbtx4927/prom.c +++ b/arch/mips/txx9/rbtx4927/prom.c @@ -29,13 +29,14 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include <linux/init.h> -#include <asm/bootinfo.h> +#include <linux/memblock.h> #include <asm/txx9/generic.h> #include <asm/txx9/rbtx4927.h> void __init rbtx4927_prom_init(void) { - add_memory_region(0, tx4927_get_mem_size(), BOOT_MEM_RAM); + memblock_add(0, tx4927_get_mem_size()); txx9_sio_putchar_init(TX4927_SIO_REG(0) & 0xfffffffffULL); } diff --git a/arch/mips/txx9/rbtx4938/prom.c b/arch/mips/txx9/rbtx4938/prom.c index 2b36a2ee744c..0de84716a428 100644 --- a/arch/mips/txx9/rbtx4938/prom.c +++ b/arch/mips/txx9/rbtx4938/prom.c @@ -12,12 +12,11 @@ #include <linux/init.h> #include <linux/memblock.h> -#include <asm/bootinfo.h> #include <asm/txx9/generic.h> #include <asm/txx9/rbtx4938.h> void __init rbtx4938_prom_init(void) { - add_memory_region(0, tx4938_get_mem_size(), BOOT_MEM_RAM); + memblock_add(0, tx4938_get_mem_size()); txx9_sio_putchar_init(TX4938_SIO_REG(0) & 0xfffffffffULL); } diff --git a/arch/mips/txx9/rbtx4939/prom.c b/arch/mips/txx9/rbtx4939/prom.c index bd277ecb4ad6..ba25ba1bd2ec 100644 --- a/arch/mips/txx9/rbtx4939/prom.c +++ b/arch/mips/txx9/rbtx4939/prom.c @@ -7,11 +7,23 @@ */ #include <linux/init.h> +#include <linux/memblock.h> #include <asm/txx9/generic.h> #include <asm/txx9/rbtx4939.h> void __init rbtx4939_prom_init(void) { - tx4939_add_memory_regions(); + unsigned long start, size; + u64 win; + int i; + + for (i = 0; i < 4; i++) { + if (!((__u32)____raw_readq(&tx4939_ddrcptr->winen) & (1 << i))) + continue; + win = ____raw_readq(&tx4939_ddrcptr->win[i]); + start = (unsigned long)(win >> 48); + size = (((unsigned long)(win >> 32) & 0xffff) + 1) - start; + memblock_add(start << 20, size << 20); + } txx9_sio_putchar_init(TX4939_SIO_REG(0) & 0xfffffffffULL); } diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile index 57fe83235281..5810cc12bc1d 100644 --- a/arch/mips/vdso/Makefile +++ b/arch/mips/vdso/Makefile @@ -61,7 +61,7 @@ endif # VDSO linker flags. ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \ $(filter -E%,$(KBUILD_CFLAGS)) -nostdlib -shared \ - -G 0 --eh-frame-hdr --hash-style=sysv --build-id -T + -G 0 --eh-frame-hdr --hash-style=sysv --build-id=sha1 -T CFLAGS_REMOVE_vdso.o = -pg diff --git a/arch/nds32/Kconfig b/arch/nds32/Kconfig index e30298e99e1b..e8e541fd2267 100644 --- a/arch/nds32/Kconfig +++ b/arch/nds32/Kconfig @@ -48,6 +48,7 @@ config NDS32 select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE + select SET_FS help Andes(nds32) Linux support. diff --git a/arch/nds32/kernel/dma.c b/arch/nds32/kernel/dma.c index 69d762182d49..2ac8e6c82a61 100644 --- a/arch/nds32/kernel/dma.c +++ b/arch/nds32/kernel/dma.c @@ -3,7 +3,7 @@ #include <linux/types.h> #include <linux/mm.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <linux/cache.h> #include <linux/highmem.h> #include <asm/cacheflush.h> diff --git a/arch/nds32/kernel/setup.c b/arch/nds32/kernel/setup.c index a066efbe53c0..c356e484dcab 100644 --- a/arch/nds32/kernel/setup.c +++ b/arch/nds32/kernel/setup.c @@ -249,12 +249,8 @@ static void __init setup_memory(void) memory_end = memory_start = 0; /* Find main memory where is the kernel */ - for_each_memblock(memory, region) { - memory_start = region->base; - memory_end = region->base + region->size; - pr_info("%s: Memory: 0x%x-0x%x\n", __func__, - memory_start, memory_end); - } + memory_start = memblock_start_of_DRAM(); + memory_end = memblock_end_of_DRAM(); if (!memory_end) { panic("No memory!"); diff --git a/arch/nds32/kernel/signal.c b/arch/nds32/kernel/signal.c index 36e25a410bb0..2acb94812af9 100644 --- a/arch/nds32/kernel/signal.c +++ b/arch/nds32/kernel/signal.c @@ -379,8 +379,6 @@ do_notify_resume(struct pt_regs *regs, unsigned int thread_flags) if (thread_flags & _TIF_SIGPENDING) do_signal(regs); - if (thread_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); + if (thread_flags & _TIF_NOTIFY_RESUME) tracehook_notify_resume(regs); - } } diff --git a/arch/nds32/kernel/vdso/Makefile b/arch/nds32/kernel/vdso/Makefile index 7c3c1ccb196e..55df25ef0057 100644 --- a/arch/nds32/kernel/vdso/Makefile +++ b/arch/nds32/kernel/vdso/Makefile @@ -20,7 +20,7 @@ GCOV_PROFILE := n obj-y += vdso.o -extra-y += vdso.lds +targets += vdso.lds CPPFLAGS_vdso.lds += -P -C -U$(ARCH) # Force dependency diff --git a/arch/nds32/kernel/vmlinux.lds.S b/arch/nds32/kernel/vmlinux.lds.S index 7a6c1cefe3fe..6a91b965fb1e 100644 --- a/arch/nds32/kernel/vmlinux.lds.S +++ b/arch/nds32/kernel/vmlinux.lds.S @@ -64,6 +64,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + ELF_DETAILS DISCARDS } diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig index c6645141bb2a..c7c6ba6bec9d 100644 --- a/arch/nios2/Kconfig +++ b/arch/nios2/Kconfig @@ -27,6 +27,7 @@ config NIOS2 select USB_ARCH_HAS_HCD if USB_SUPPORT select CPU_NO_EFFICIENT_FFS select MMU_GATHER_NO_RANGE if MMU + select SET_FS config GENERIC_CSUM def_bool y diff --git a/arch/nios2/include/asm/checksum.h b/arch/nios2/include/asm/checksum.h index b4316c361729..69004e07a1ba 100644 --- a/arch/nios2/include/asm/checksum.h +++ b/arch/nios2/include/asm/checksum.h @@ -12,10 +12,6 @@ /* Take these from lib/checksum.c */ extern __wsum csum_partial(const void *buff, int len, __wsum sum); -__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, - __wsum sum); -#define csum_partial_copy_nocheck csum_partial_copy_nocheck - extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl); extern __sum16 ip_compute_csum(const void *buff, int len); diff --git a/arch/nios2/kernel/process.c b/arch/nios2/kernel/process.c index 88a4ec03edab..4ffe857e6ada 100644 --- a/arch/nios2/kernel/process.c +++ b/arch/nios2/kernel/process.c @@ -266,5 +266,5 @@ asmlinkage int nios2_clone(unsigned long clone_flags, unsigned long newsp, .tls = tls, }; - return _do_fork(&args); + return kernel_clone(&args); } diff --git a/arch/nios2/kernel/signal.c b/arch/nios2/kernel/signal.c index d8a087cf2b42..cf2dca2ac7c3 100644 --- a/arch/nios2/kernel/signal.c +++ b/arch/nios2/kernel/signal.c @@ -317,7 +317,7 @@ asmlinkage int do_notify_resume(struct pt_regs *regs) */ return restart; } - } else if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) + } else if (test_thread_flag(TIF_NOTIFY_RESUME)) tracehook_notify_resume(regs); return 0; diff --git a/arch/nios2/kernel/vmlinux.lds.S b/arch/nios2/kernel/vmlinux.lds.S index c55a7cfa1075..126e114744cb 100644 --- a/arch/nios2/kernel/vmlinux.lds.S +++ b/arch/nios2/kernel/vmlinux.lds.S @@ -58,6 +58,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + ELF_DETAILS DISCARDS } diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index 7e94fe37cb2f..6233c6293180 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig @@ -39,6 +39,7 @@ config OPENRISC select ARCH_WANT_FRAME_POINTERS select GENERIC_IRQ_MULTI_HANDLER select MMU_GATHER_NO_RANGE if MMU + select SET_FS config CPU_BIG_ENDIAN def_bool y diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h index f0390211236b..120f5005461b 100644 --- a/arch/openrisc/include/asm/uaccess.h +++ b/arch/openrisc/include/asm/uaccess.h @@ -165,19 +165,19 @@ struct __large_struct { #define __get_user_nocheck(x, ptr, size) \ ({ \ - long __gu_err, __gu_val; \ - __get_user_size(__gu_val, (ptr), (size), __gu_err); \ - (x) = (__force __typeof__(*(ptr)))__gu_val; \ + long __gu_err; \ + __get_user_size((x), (ptr), (size), __gu_err); \ __gu_err; \ }) #define __get_user_check(x, ptr, size) \ ({ \ - long __gu_err = -EFAULT, __gu_val = 0; \ + long __gu_err = -EFAULT; \ const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ - if (access_ok(__gu_addr, size)) \ - __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ - (x) = (__force __typeof__(*(ptr)))__gu_val; \ + if (access_ok(__gu_addr, size)) \ + __get_user_size((x), __gu_addr, (size), __gu_err); \ + else \ + (x) = (__typeof__(*(ptr))) 0; \ __gu_err; \ }) @@ -191,11 +191,13 @@ do { \ case 2: __get_user_asm(x, ptr, retval, "l.lhz"); break; \ case 4: __get_user_asm(x, ptr, retval, "l.lwz"); break; \ case 8: __get_user_asm2(x, ptr, retval); break; \ - default: (x) = __get_user_bad(); \ + default: (x) = (__typeof__(*(ptr)))__get_user_bad(); \ } \ } while (0) #define __get_user_asm(x, addr, err, op) \ +{ \ + unsigned long __gu_tmp; \ __asm__ __volatile__( \ "1: "op" %1,0(%2)\n" \ "2:\n" \ @@ -209,10 +211,14 @@ do { \ " .align 2\n" \ " .long 1b,3b\n" \ ".previous" \ - : "=r"(err), "=r"(x) \ - : "r"(addr), "i"(-EFAULT), "0"(err)) + : "=r"(err), "=r"(__gu_tmp) \ + : "r"(addr), "i"(-EFAULT), "0"(err)); \ + (x) = (__typeof__(*(addr)))__gu_tmp; \ +} #define __get_user_asm2(x, addr, err) \ +{ \ + unsigned long long __gu_tmp; \ __asm__ __volatile__( \ "1: l.lwz %1,0(%2)\n" \ "2: l.lwz %H1,4(%2)\n" \ @@ -229,8 +235,11 @@ do { \ " .long 1b,4b\n" \ " .long 2b,4b\n" \ ".previous" \ - : "=r"(err), "=&r"(x) \ - : "r"(addr), "i"(-EFAULT), "0"(err)) + : "=r"(err), "=&r"(__gu_tmp) \ + : "r"(addr), "i"(-EFAULT), "0"(err)); \ + (x) = (__typeof__(*(addr)))( \ + (__typeof__((x)-(x)))__gu_tmp); \ +} /* more complex routines */ diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c index 345727638d52..1b16d97e7da7 100644 --- a/arch/openrisc/kernel/dma.c +++ b/arch/openrisc/kernel/dma.c @@ -13,7 +13,7 @@ * DMA mapping callbacks... */ -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <linux/pagewalk.h> #include <asm/cpuinfo.h> diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c index b18e775f8be3..2416a9f91533 100644 --- a/arch/openrisc/kernel/setup.c +++ b/arch/openrisc/kernel/setup.c @@ -48,17 +48,12 @@ static void __init setup_memory(void) unsigned long ram_start_pfn; unsigned long ram_end_pfn; phys_addr_t memory_start, memory_end; - struct memblock_region *region; memory_end = memory_start = 0; /* Find main memory where is the kernel, we assume its the only one */ - for_each_memblock(memory, region) { - memory_start = region->base; - memory_end = region->base + region->size; - printk(KERN_INFO "%s: Memory: 0x%x-0x%x\n", __func__, - memory_start, memory_end); - } + memory_start = memblock_start_of_DRAM(); + memory_end = memblock_end_of_DRAM(); if (!memory_end) { panic("No memory!"); @@ -80,6 +75,16 @@ static void __init setup_memory(void) */ memblock_reserve(__pa(_stext), _end - _stext); +#ifdef CONFIG_BLK_DEV_INITRD + /* Then reserve the initrd, if any */ + if (initrd_start && (initrd_end > initrd_start)) { + unsigned long aligned_start = ALIGN_DOWN(initrd_start, PAGE_SIZE); + unsigned long aligned_end = ALIGN(initrd_end, PAGE_SIZE); + + memblock_reserve(__pa(aligned_start), aligned_end - aligned_start); + } +#endif /* CONFIG_BLK_DEV_INITRD */ + early_init_fdt_reserve_self(); early_init_fdt_scan_reserved_mem(); diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c index c779364f0cd0..af66f968dd45 100644 --- a/arch/openrisc/kernel/signal.c +++ b/arch/openrisc/kernel/signal.c @@ -311,7 +311,6 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) } syscall = 0; } else { - clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); } } diff --git a/arch/openrisc/kernel/vmlinux.lds.S b/arch/openrisc/kernel/vmlinux.lds.S index 22fbc5fb24b3..d5c7bb0fae57 100644 --- a/arch/openrisc/kernel/vmlinux.lds.S +++ b/arch/openrisc/kernel/vmlinux.lds.S @@ -103,6 +103,7 @@ SECTIONS /* Throw in the debugging sections */ STABS_DEBUG DWARF_DEBUG + ELF_DETAILS /* Sections to be discarded -- must be last */ DISCARDS diff --git a/arch/openrisc/mm/cache.c b/arch/openrisc/mm/cache.c index 08f56af387ac..534a52ec5e66 100644 --- a/arch/openrisc/mm/cache.c +++ b/arch/openrisc/mm/cache.c @@ -16,7 +16,7 @@ #include <asm/cacheflush.h> #include <asm/tlbflush.h> -static void cache_loop(struct page *page, const unsigned int reg) +static __always_inline void cache_loop(struct page *page, const unsigned int reg) { unsigned long paddr = page_to_pfn(page) << PAGE_SHIFT; unsigned long line = paddr & ~(L1_CACHE_BYTES - 1); diff --git a/arch/openrisc/mm/init.c b/arch/openrisc/mm/init.c index 3d7c79c7745d..8348feaaf46e 100644 --- a/arch/openrisc/mm/init.c +++ b/arch/openrisc/mm/init.c @@ -64,6 +64,7 @@ extern const char _s_kernel_ro[], _e_kernel_ro[]; */ static void __init map_ram(void) { + phys_addr_t start, end; unsigned long v, p, e; pgprot_t prot; pgd_t *pge; @@ -71,6 +72,7 @@ static void __init map_ram(void) pud_t *pue; pmd_t *pme; pte_t *pte; + u64 i; /* These mark extents of read-only kernel pages... * ...from vmlinux.lds.S */ @@ -78,9 +80,9 @@ static void __init map_ram(void) v = PAGE_OFFSET; - for_each_memblock(memory, region) { - p = (u32) region->base & PAGE_MASK; - e = p + (u32) region->size; + for_each_mem_range(i, &start, &end) { + p = (u32) start & PAGE_MASK; + e = (u32) end; v = (u32) __va(p); pge = pgd_offset_k(v); diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 3b0f53dd70bc..b234e8154cbd 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -63,6 +63,7 @@ config PARISC select HAVE_FTRACE_MCOUNT_RECORD if HAVE_DYNAMIC_FTRACE select HAVE_KPROBES_ON_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS + select SET_FS help The PA-RISC microprocessor is designed by Hewlett-Packard and used @@ -195,7 +196,6 @@ config PA11 depends on PA7000 || PA7100LC || PA7200 || PA7300LC select ARCH_HAS_SYNC_DMA_FOR_CPU select ARCH_HAS_SYNC_DMA_FOR_DEVICE - select DMA_NONCOHERENT_CACHE_SYNC config PREFETCH def_bool y @@ -376,21 +376,6 @@ config KEXEC_FILE endmenu +source "drivers/firmware/Kconfig" source "drivers/parisc/Kconfig" - -config SECCOMP - def_bool y - prompt "Enable seccomp to safely compute untrusted bytecode" - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via prctl(PR_SET_SECCOMP), it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - - If unsure, say Y. Only embedded should say N here. diff --git a/arch/parisc/boot/compressed/vmlinux.lds.S b/arch/parisc/boot/compressed/vmlinux.lds.S index 2ac3a643f2eb..ab7b43990857 100644 --- a/arch/parisc/boot/compressed/vmlinux.lds.S +++ b/arch/parisc/boot/compressed/vmlinux.lds.S @@ -84,6 +84,7 @@ SECTIONS } STABS_DEBUG + ELF_DETAILS .note 0 : { *(.note) } /* Sections to be discarded */ diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig index 61bac8ff8f22..3cbcfad5f724 100644 --- a/arch/parisc/configs/generic-32bit_defconfig +++ b/arch/parisc/configs/generic-32bit_defconfig @@ -52,10 +52,6 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=6144 -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_NS87415=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y @@ -65,6 +61,8 @@ CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_ZALON=y CONFIG_SCSI_DH=y CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_NS87415=y CONFIG_MD=y CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig index 59561e04e659..7e2d7026285e 100644 --- a/arch/parisc/configs/generic-64bit_defconfig +++ b/arch/parisc/configs/generic-64bit_defconfig @@ -58,11 +58,6 @@ CONFIG_PCI_IOV=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_BLK_DEV_LOOP=y -CONFIG_IDE=y -CONFIG_IDE_GD=m -CONFIG_IDE_GD_ATAPI=y -CONFIG_BLK_DEV_IDECD=m -CONFIG_BLK_DEV_NS87415=y # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y @@ -76,6 +71,7 @@ CONFIG_SCSI_ZALON=y CONFIG_SCSI_QLA_ISCSI=m CONFIG_SCSI_DH=y CONFIG_ATA=y +CONFIG_PATA_NS87415=y CONFIG_PATA_SIL680=y CONFIG_ATA_GENERIC=y CONFIG_MD=y diff --git a/arch/parisc/include/asm/barrier.h b/arch/parisc/include/asm/barrier.h index 640d46edf32e..c705decf2bed 100644 --- a/arch/parisc/include/asm/barrier.h +++ b/arch/parisc/include/asm/barrier.h @@ -2,11 +2,15 @@ #ifndef __ASM_BARRIER_H #define __ASM_BARRIER_H +#include <asm/alternative.h> + #ifndef __ASSEMBLY__ /* The synchronize caches instruction executes as a nop on systems in which all memory references are performed in order. */ -#define synchronize_caches() __asm__ __volatile__ ("sync" : : : "memory") +#define synchronize_caches() asm volatile("sync" \ + ALTERNATIVE(ALT_COND_NO_SMP, INSN_NOP) \ + : : : "memory") #if defined(CONFIG_SMP) #define mb() do { synchronize_caches(); } while (0) diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h index e5de3f897633..d53e9e27dba0 100644 --- a/arch/parisc/include/asm/cache.h +++ b/arch/parisc/include/asm/cache.h @@ -22,7 +22,7 @@ #define ARCH_DMA_MINALIGN L1_CACHE_BYTES -#define __read_mostly __section(.data..read_mostly) +#define __read_mostly __section(".data..read_mostly") void parisc_cache_init(void); /* initializes cache-flushing */ void disable_sr_hashing_asm(int); /* low level support for above */ diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h index fe8c63b2d2c3..3c43baca7b39 100644 --- a/arch/parisc/include/asm/checksum.h +++ b/arch/parisc/include/asm/checksum.h @@ -19,14 +19,6 @@ extern __wsum csum_partial(const void *, int, __wsum); /* - * The same as csum_partial, but copies from src while it checksums. - * - * Here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ -extern __wsum csum_partial_copy_nocheck(const void *, void *, int, __wsum); - -/* * Optimized for IP headers, which always checksum on 4 octet boundaries. * * Written by Randolph Chung <tausq@debian.org>, and then mucked with by @@ -181,25 +173,5 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, return csum_fold(sum); } -/* - * Copy and checksum to user - */ -#define HAVE_CSUM_COPY_USER -static __inline__ __wsum csum_and_copy_to_user(const void *src, - void __user *dst, - int len, __wsum sum, - int *err_ptr) -{ - /* code stolen from include/asm-mips64 */ - sum = csum_partial(src, len, sum); - - if (copy_to_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - - return sum; -} - #endif diff --git a/arch/parisc/include/asm/cmpxchg.h b/arch/parisc/include/asm/cmpxchg.h index 068958575871..cf5ee9b0b393 100644 --- a/arch/parisc/include/asm/cmpxchg.h +++ b/arch/parisc/include/asm/cmpxchg.h @@ -14,22 +14,22 @@ extern void __xchg_called_with_bad_pointer(void); /* __xchg32/64 defined in arch/parisc/lib/bitops.c */ -extern unsigned long __xchg8(char, char *); -extern unsigned long __xchg32(int, int *); +extern unsigned long __xchg8(char, volatile char *); +extern unsigned long __xchg32(int, volatile int *); #ifdef CONFIG_64BIT -extern unsigned long __xchg64(unsigned long, unsigned long *); +extern unsigned long __xchg64(unsigned long, volatile unsigned long *); #endif /* optimizer better get rid of switch since size is a constant */ static inline unsigned long -__xchg(unsigned long x, __volatile__ void *ptr, int size) +__xchg(unsigned long x, volatile void *ptr, int size) { switch (size) { #ifdef CONFIG_64BIT - case 8: return __xchg64(x, (unsigned long *) ptr); + case 8: return __xchg64(x, (volatile unsigned long *) ptr); #endif - case 4: return __xchg32((int) x, (int *) ptr); - case 1: return __xchg8((char) x, (char *) ptr); + case 4: return __xchg32((int) x, (volatile int *) ptr); + case 1: return __xchg8((char) x, (volatile char *) ptr); } __xchg_called_with_bad_pointer(); return x; diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h index 2f4f66a3bac0..8f33085ff1bd 100644 --- a/arch/parisc/include/asm/compat.h +++ b/arch/parisc/include/asm/compat.h @@ -22,8 +22,6 @@ typedef u32 compat_dev_t; typedef u16 compat_nlink_t; typedef u16 compat_ipc_pid_t; typedef u32 compat_caddr_t; -typedef s64 compat_s64; -typedef u64 compat_u64; struct compat_stat { compat_dev_t st_dev; /* dev_t is 32 bits on parisc */ diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h index c459f656c8c3..fceb9cf02fb3 100644 --- a/arch/parisc/include/asm/futex.h +++ b/arch/parisc/include/asm/futex.h @@ -16,7 +16,7 @@ static inline void _futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags) { extern u32 lws_lock_start[]; - long index = ((long)uaddr & 0xf0) >> 2; + long index = ((long)uaddr & 0x3f8) >> 1; arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; local_irq_save(*flags); arch_spin_lock(s); @@ -26,7 +26,7 @@ static inline void _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) { extern u32 lws_lock_start[]; - long index = ((long)uaddr & 0xf0) >> 2; + long index = ((long)uaddr & 0x3f8) >> 1; arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; arch_spin_unlock(s); local_irq_restore(*flags); diff --git a/arch/parisc/include/asm/ldcw.h b/arch/parisc/include/asm/ldcw.h index e080143e79a3..6d28b5514699 100644 --- a/arch/parisc/include/asm/ldcw.h +++ b/arch/parisc/include/asm/ldcw.h @@ -52,7 +52,7 @@ }) #ifdef CONFIG_SMP -# define __lock_aligned __section(.data..lock_aligned) +# define __lock_aligned __section(".data..lock_aligned") #endif #endif /* __PARISC_LDCW_H */ diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h index 79feff1b0721..33500c9f6e5e 100644 --- a/arch/parisc/include/asm/socket.h +++ b/arch/parisc/include/asm/socket.h @@ -4,8 +4,8 @@ #include <uapi/asm/socket.h> -/* O_NONBLOCK clashes with the bits used for socket types. Therefore we - * have to define SOCK_NONBLOCK to a different value here. +/* O_NONBLOCK clashed with the bits used for socket types. Therefore we + * had to define SOCK_NONBLOCK to a different value here. */ #define SOCK_NONBLOCK 0x40000000 diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h index 51b6c47f802f..fa5ee8a45dbd 100644 --- a/arch/parisc/include/asm/spinlock.h +++ b/arch/parisc/include/asm/spinlock.h @@ -10,13 +10,21 @@ static inline int arch_spin_is_locked(arch_spinlock_t *x) { volatile unsigned int *a = __ldcw_align(x); - return *a == 0; + return READ_ONCE(*a) == 0; } -#define arch_spin_lock(lock) arch_spin_lock_flags(lock, 0) +static inline void arch_spin_lock(arch_spinlock_t *x) +{ + volatile unsigned int *a; + + a = __ldcw_align(x); + while (__ldcw(a) == 0) + while (*a == 0) + continue; +} static inline void arch_spin_lock_flags(arch_spinlock_t *x, - unsigned long flags) + unsigned long flags) { volatile unsigned int *a; @@ -25,10 +33,8 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *x, while (*a == 0) if (flags & PSW_SM_I) { local_irq_enable(); - cpu_relax(); local_irq_disable(); - } else - cpu_relax(); + } } #define arch_spin_lock_flags arch_spin_lock_flags @@ -44,12 +50,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *x) static inline int arch_spin_trylock(arch_spinlock_t *x) { volatile unsigned int *a; - int ret; a = __ldcw_align(x); - ret = __ldcw(a) != 0; - - return ret; + return __ldcw(a) != 0; } /* diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h index 03ce20e5ad7d..03dee816cb13 100644 --- a/arch/parisc/include/uapi/asm/fcntl.h +++ b/arch/parisc/include/uapi/asm/fcntl.h @@ -3,22 +3,19 @@ #define _PARISC_FCNTL_H #define O_APPEND 000000010 -#define O_BLKSEEK 000000100 /* HPUX only */ #define O_CREAT 000000400 /* not fcntl */ #define O_EXCL 000002000 /* not fcntl */ #define O_LARGEFILE 000004000 #define __O_SYNC 000100000 #define O_SYNC (__O_SYNC|O_DSYNC) -#define O_NONBLOCK 000200004 /* HPUX has separate NDELAY & NONBLOCK */ +#define O_NONBLOCK 000200000 #define O_NOCTTY 000400000 /* not fcntl */ -#define O_DSYNC 001000000 /* HPUX only */ -#define O_RSYNC 002000000 /* HPUX only */ +#define O_DSYNC 001000000 #define O_NOATIME 004000000 #define O_CLOEXEC 010000000 /* set close_on_exec */ #define O_DIRECTORY 000010000 /* must be a directory */ #define O_NOFOLLOW 000000200 /* don't follow links */ -#define O_INVISIBLE 004000000 /* invisible I/O, for DMAPI/XDSM */ #define O_PATH 020000000 #define __O_TMPFILE 040000000 diff --git a/arch/parisc/include/uapi/asm/mman.h b/arch/parisc/include/uapi/asm/mman.h index 6fd8871e4081..ab78cba446ed 100644 --- a/arch/parisc/include/uapi/asm/mman.h +++ b/arch/parisc/include/uapi/asm/mman.h @@ -25,6 +25,7 @@ #define MAP_STACK 0x40000 /* give out an address that is best suited for process/thread stacks */ #define MAP_HUGETLB 0x80000 /* create a huge page mapping */ #define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED which doesn't unmap underlying mapping */ +#define MAP_UNINITIALIZED 0 /* uninitialized anonymous mmap */ #define MS_SYNC 1 /* synchronous memory sync */ #define MS_ASYNC 2 /* sync memory asynchronously */ diff --git a/arch/parisc/include/uapi/asm/signal.h b/arch/parisc/include/uapi/asm/signal.h index d38563a394f2..e605197b462c 100644 --- a/arch/parisc/include/uapi/asm/signal.h +++ b/arch/parisc/include/uapi/asm/signal.h @@ -35,11 +35,11 @@ #define SIGURG 29 #define SIGXFSZ 30 #define SIGUNUSED 31 -#define SIGSYS 31 /* Linux doesn't use this */ +#define SIGSYS 31 /* These should not be considered constants from userland. */ #define SIGRTMIN 32 -#define SIGRTMAX _NSIG /* it's 44 under HP/UX */ +#define SIGRTMAX _NSIG /* * SA_FLAGS values: @@ -61,7 +61,6 @@ #define SA_NODEFER 0x00000020 #define SA_RESTART 0x00000040 #define SA_NOCLDWAIT 0x00000080 -#define _SA_SIGGFAULT 0x00000100 /* HPUX */ #define SA_NOMASK SA_NODEFER #define SA_ONESHOT SA_RESETHAND diff --git a/arch/parisc/install.sh b/arch/parisc/install.sh index 6f68784fea25..056d588befdd 100644 --- a/arch/parisc/install.sh +++ b/arch/parisc/install.sh @@ -43,7 +43,7 @@ fi # Default install -if [ "$(basename $2)" = "zImage" ]; then +if [ "$(basename $2)" = "vmlinuz" ]; then # Compressed install echo "Installing compressed kernel" base=vmlinuz diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index b5e1d9f1b440..86a1a63563fd 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -383,12 +383,12 @@ EXPORT_SYMBOL(flush_kernel_icache_range_asm); static unsigned long parisc_cache_flush_threshold __ro_after_init = FLUSH_THRESHOLD; #define FLUSH_TLB_THRESHOLD (16*1024) /* 16 KiB minimum TLB threshold */ -static unsigned long parisc_tlb_flush_threshold __ro_after_init = FLUSH_TLB_THRESHOLD; +static unsigned long parisc_tlb_flush_threshold __ro_after_init = ~0UL; void __init parisc_setup_cache_timing(void) { unsigned long rangetime, alltime; - unsigned long size, start; + unsigned long size; unsigned long threshold; alltime = mfctl(16); @@ -422,14 +422,9 @@ void __init parisc_setup_cache_timing(void) goto set_tlb_threshold; } - size = 0; - start = (unsigned long) _text; + size = (unsigned long)_end - (unsigned long)_text; rangetime = mfctl(16); - while (start < (unsigned long) _end) { - flush_tlb_kernel_range(start, start + PAGE_SIZE); - start += PAGE_SIZE; - size += PAGE_SIZE; - } + flush_tlb_kernel_range((unsigned long)_text, (unsigned long)_end); rangetime = mfctl(16) - rangetime; alltime = mfctl(16); @@ -444,8 +439,11 @@ void __init parisc_setup_cache_timing(void) threshold/1024); set_tlb_threshold: - if (threshold > parisc_tlb_flush_threshold) + if (threshold > FLUSH_TLB_THRESHOLD) parisc_tlb_flush_threshold = threshold; + else + parisc_tlb_flush_threshold = FLUSH_TLB_THRESHOLD; + printk(KERN_INFO "TLB flush threshold set to %lu KiB\n", parisc_tlb_flush_threshold/1024); } diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index a5f3e50fe976..80fa0650736b 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -30,6 +30,7 @@ #include <linux/spinlock.h> #include <linux/string.h> #include <linux/export.h> +#include <linux/dma-map-ops.h> #include <asm/hardware.h> #include <asm/io.h> #include <asm/pdc.h> diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 519f9056fd00..f6f28e41bb5e 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -899,20 +899,20 @@ intr_check_sig: * Only do signals if we are returning to user space */ LDREG PT_IASQ0(%r16), %r20 - cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */ + cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* forward */ LDREG PT_IASQ1(%r16), %r20 - cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */ - - /* NOTE: We need to enable interrupts if we have to deliver - * signals. We used to do this earlier but it caused kernel - * stack overflows. */ - ssm PSW_SM_I, %r0 + cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* forward */ copy %r0, %r25 /* long in_syscall = 0 */ #ifdef CONFIG_64BIT ldo -16(%r30),%r29 /* Reference param save area */ #endif + /* NOTE: We need to enable interrupts if we have to deliver + * signals. We used to do this earlier but it caused kernel + * stack overflows. */ + ssm PSW_SM_I, %r0 + BL do_notify_resume,%r2 copy %r16, %r26 /* struct pt_regs *regs */ diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c index 4bab21c71055..63e3ecb9da81 100644 --- a/arch/parisc/kernel/ftrace.c +++ b/arch/parisc/kernel/ftrace.c @@ -21,7 +21,7 @@ #include <asm/ftrace.h> #include <asm/patch.h> -#define __hot __attribute__ ((__section__ (".text.hot"))) +#define __hot __section(".text.hot") #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c index 9298f2285510..7ab2f2a54400 100644 --- a/arch/parisc/kernel/inventory.c +++ b/arch/parisc/kernel/inventory.c @@ -19,6 +19,7 @@ #include <linux/init.h> #include <linux/slab.h> #include <linux/mm.h> +#include <linux/platform_device.h> #include <asm/hardware.h> #include <asm/io.h> #include <asm/mmzone.h> @@ -641,4 +642,33 @@ void __init do_device_inventory(void) if (pa_serialize_tlb_flushes) pr_info("Merced bus found: Enable PxTLB serialization.\n"); #endif + +#if defined(CONFIG_FW_CFG_SYSFS) + if (running_on_qemu) { + struct resource res[3] = {0,}; + unsigned int base; + + base = ((unsigned long long) PAGE0->pad0[2] << 32) + | PAGE0->pad0[3]; /* SeaBIOS stored it here */ + + res[0].name = "fw_cfg"; + res[0].start = base; + res[0].end = base + 8 - 1; + res[0].flags = IORESOURCE_MEM; + + res[1].name = "ctrl"; + res[1].start = 0; + res[1].flags = IORESOURCE_REG; + + res[2].name = "data"; + res[2].start = 4; + res[2].flags = IORESOURCE_REG; + + if (base) { + pr_info("Found qemu fw_cfg interface at %#08x\n", base); + platform_device_register_simple("fw_cfg", + PLATFORM_DEVID_NONE, res, 3); + } + } +#endif } diff --git a/arch/parisc/kernel/kprobes.c b/arch/parisc/kernel/kprobes.c index 77ec51818916..6d21a515eea5 100644 --- a/arch/parisc/kernel/kprobes.c +++ b/arch/parisc/kernel/kprobes.c @@ -191,80 +191,11 @@ static struct kprobe trampoline_p = { static int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *tmp; - unsigned long flags, orig_ret_address = 0; - unsigned long trampoline_address = (unsigned long)trampoline_p.addr; - kprobe_opcode_t *correct_ret_addr = NULL; - - INIT_HLIST_HEAD(&empty_rp); - kretprobe_hash_lock(current, &head, &flags); - - /* - * It is possible to have multiple instances associated with a given - * task either because multiple functions in the call path have - * a return probe installed on them, and/or more than one return - * probe was registered for a target function. - * - * We can handle this because: - * - instances are always inserted at the head of the list - * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the - * real return address, and all the rest will point to - * kretprobe_trampoline - */ - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - orig_ret_address = (unsigned long)ri->ret_addr; - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_assert(ri, orig_ret_address, trampoline_address); - - correct_ret_addr = ri->ret_addr; - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - orig_ret_address = (unsigned long)ri->ret_addr; - if (ri->rp && ri->rp->handler) { - __this_cpu_write(current_kprobe, &ri->rp->kp); - get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; - ri->ret_addr = correct_ret_addr; - ri->rp->handler(ri, regs); - __this_cpu_write(current_kprobe, NULL); - } - - recycle_rp_inst(ri, &empty_rp); - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } + unsigned long orig_ret_address; - kretprobe_hash_unlock(current, &flags); - - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } + orig_ret_address = __kretprobe_trampoline_handler(regs, trampoline_p.addr, NULL); instruction_pointer_set(regs, orig_ret_address); + return 1; } @@ -272,6 +203,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) { ri->ret_addr = (kprobe_opcode_t *)regs->gr[2]; + ri->fp = NULL; /* Replace the return addr with trampoline addr. */ regs->gr[2] = (unsigned long)trampoline_p.addr; diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c index 38c68e131bbe..36610a5c029f 100644 --- a/arch/parisc/kernel/pci-dma.c +++ b/arch/parisc/kernel/pci-dma.c @@ -26,7 +26,7 @@ #include <linux/string.h> #include <linux/types.h> #include <linux/dma-direct.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <asm/cacheflush.h> #include <asm/dma.h> /* for DMA_CHUNK_SIZE */ @@ -454,9 +454,3 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, { flush_kernel_dcache_range((unsigned long)phys_to_virt(paddr), size); } - -void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size, - enum dma_data_direction direction) -{ - flush_kernel_dcache_range((unsigned long)vaddr, size); -} diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 3c037fc96038..9f43eaeb0b0a 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -606,8 +606,6 @@ void do_notify_resume(struct pt_regs *regs, long in_syscall) if (test_thread_flag(TIF_SIGPENDING)) do_signal(regs, in_syscall); - if (test_thread_flag(TIF_NOTIFY_RESUME)) { - clear_thread_flag(TIF_NOTIFY_RESUME); + if (test_thread_flag(TIF_NOTIFY_RESUME)) tracehook_notify_resume(regs); - } } diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 6271139d2213..10227f667c8a 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -173,9 +173,12 @@ ipi_interrupt(int irq, void *dev_id) this_cpu, which); return IRQ_NONE; } /* Switch */ - /* let in any pending interrupts */ - local_irq_enable(); - local_irq_disable(); + + /* before doing more, let in any pending interrupts */ + if (ops) { + local_irq_enable(); + local_irq_disable(); + } } /* while (ops) */ } return IRQ_HANDLED; diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 5d458a44b09c..9549496f5523 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -6,7 +6,7 @@ * Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org> * Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org> * Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org> - * Copyright (C) 1999-2014 Helge Deller <deller@gmx.de> + * Copyright (C) 1999-2020 Helge Deller <deller@gmx.de> */ #include <linux/uaccess.h> @@ -23,6 +23,7 @@ #include <linux/utsname.h> #include <linux/personality.h> #include <linux/random.h> +#include <linux/compat.h> /* we construct an artificial offset for the mapping based on the physical * address of the kernel mapping variable */ @@ -373,3 +374,73 @@ long parisc_personality(unsigned long personality) return err; } + +/* + * Up to kernel v5.9 we defined O_NONBLOCK as 000200004, + * since then O_NONBLOCK is defined as 000200000. + * + * The following wrapper functions mask out the old + * O_NDELAY bit from calls which use O_NONBLOCK. + * + * XXX: Remove those in year 2022 (or later)? + */ + +#define O_NONBLOCK_OLD 000200004 +#define O_NONBLOCK_MASK_OUT (O_NONBLOCK_OLD & ~O_NONBLOCK) + +static int FIX_O_NONBLOCK(int flags) +{ + if (flags & O_NONBLOCK_MASK_OUT) { + struct task_struct *tsk = current; + pr_warn_once("%s(%d) uses a deprecated O_NONBLOCK value.\n", + tsk->comm, tsk->pid); + } + return flags & ~O_NONBLOCK_MASK_OUT; +} + +asmlinkage long parisc_timerfd_create(int clockid, int flags) +{ + flags = FIX_O_NONBLOCK(flags); + return sys_timerfd_create(clockid, flags); +} + +asmlinkage long parisc_signalfd4(int ufd, sigset_t __user *user_mask, + size_t sizemask, int flags) +{ + flags = FIX_O_NONBLOCK(flags); + return sys_signalfd4(ufd, user_mask, sizemask, flags); +} + +#ifdef CONFIG_COMPAT +asmlinkage long parisc_compat_signalfd4(int ufd, + compat_sigset_t __user *user_mask, + compat_size_t sizemask, int flags) +{ + flags = FIX_O_NONBLOCK(flags); + return compat_sys_signalfd4(ufd, user_mask, sizemask, flags); +} +#endif + +asmlinkage long parisc_eventfd2(unsigned int count, int flags) +{ + flags = FIX_O_NONBLOCK(flags); + return sys_eventfd2(count, flags); +} + +asmlinkage long parisc_userfaultfd(int flags) +{ + flags = FIX_O_NONBLOCK(flags); + return sys_userfaultfd(flags); +} + +asmlinkage long parisc_pipe2(int __user *fildes, int flags) +{ + flags = FIX_O_NONBLOCK(flags); + return sys_pipe2(fildes, flags); +} + +asmlinkage long parisc_inotify_init1(int flags) +{ + flags = FIX_O_NONBLOCK(flags); + return sys_inotify_init1(flags); +} diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 3ad61a177f5b..322503780db6 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -571,8 +571,8 @@ lws_compare_and_swap: ldil L%lws_lock_start, %r20 ldo R%lws_lock_start(%r20), %r28 - /* Extract four bits from r26 and hash lock (Bits 4-7) */ - extru %r26, 27, 4, %r20 + /* Extract eight bits from r26 and hash lock (Bits 3-11) */ + extru %r26, 28, 8, %r20 /* Find lock to use, the hash is either one of 0 to 15, multiplied by 16 (keep it 16-byte aligned) @@ -761,8 +761,8 @@ cas2_lock_start: ldil L%lws_lock_start, %r20 ldo R%lws_lock_start(%r20), %r28 - /* Extract four bits from r26 and hash lock (Bits 4-7) */ - extru %r26, 27, 4, %r20 + /* Extract eight bits from r26 and hash lock (Bits 3-11) */ + extru %r26, 28, 8, %r20 /* Find lock to use, the hash is either one of 0 to 15, multiplied by 16 (keep it 16-byte aligned) @@ -950,7 +950,7 @@ END(sys_call_table64) .align L1_CACHE_BYTES ENTRY(lws_lock_start) /* lws locks */ - .rept 16 + .rept 256 /* Keep locks aligned at 16-bytes */ .word 1 .word 0 diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl index def64d221cd4..f375ea528e59 100644 --- a/arch/parisc/kernel/syscalls/syscall.tbl +++ b/arch/parisc/kernel/syscalls/syscall.tbl @@ -29,7 +29,7 @@ 18 common stat sys_newstat compat_sys_newstat 19 common lseek sys_lseek compat_sys_lseek 20 common getpid sys_getpid -21 common mount sys_mount compat_sys_mount +21 common mount sys_mount 22 common bind sys_bind 23 common setuid sys_setuid 24 common getuid sys_getuid @@ -159,8 +159,8 @@ 142 common _newselect sys_select compat_sys_select 143 common flock sys_flock 144 common msync sys_msync -145 common readv sys_readv compat_sys_readv -146 common writev sys_writev compat_sys_writev +145 common readv sys_readv +146 common writev sys_writev 147 common getsid sys_getsid 148 common fdatasync sys_fdatasync 149 common _sysctl sys_ni_syscall @@ -330,7 +330,7 @@ 292 32 sync_file_range parisc_sync_file_range 292 64 sync_file_range sys_sync_file_range 293 common tee sys_tee -294 common vmsplice sys_vmsplice compat_sys_vmsplice +294 common vmsplice sys_vmsplice 295 common move_pages sys_move_pages compat_sys_move_pages 296 common getcpu sys_getcpu 297 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait @@ -344,17 +344,17 @@ 304 common eventfd sys_eventfd 305 32 fallocate parisc_fallocate 305 64 fallocate sys_fallocate -306 common timerfd_create sys_timerfd_create +306 common timerfd_create parisc_timerfd_create 307 32 timerfd_settime sys_timerfd_settime32 307 64 timerfd_settime sys_timerfd_settime 308 32 timerfd_gettime sys_timerfd_gettime32 308 64 timerfd_gettime sys_timerfd_gettime -309 common signalfd4 sys_signalfd4 compat_sys_signalfd4 -310 common eventfd2 sys_eventfd2 +309 common signalfd4 parisc_signalfd4 parisc_compat_signalfd4 +310 common eventfd2 parisc_eventfd2 311 common epoll_create1 sys_epoll_create1 312 common dup3 sys_dup3 -313 common pipe2 sys_pipe2 -314 common inotify_init1 sys_inotify_init1 +313 common pipe2 parisc_pipe2 +314 common inotify_init1 parisc_inotify_init1 315 common preadv sys_preadv compat_sys_preadv 316 common pwritev sys_pwritev compat_sys_pwritev 317 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo @@ -372,8 +372,8 @@ 327 common syncfs sys_syncfs 328 common setns sys_setns 329 common sendmmsg sys_sendmmsg compat_sys_sendmmsg -330 common process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv -331 common process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev +330 common process_vm_readv sys_process_vm_readv +331 common process_vm_writev sys_process_vm_writev 332 common kcmp sys_kcmp 333 common finit_module sys_finit_module 334 common sched_setattr sys_sched_setattr @@ -387,7 +387,7 @@ 341 common bpf sys_bpf 342 common execveat sys_execveat compat_sys_execveat 343 common membarrier sys_membarrier -344 common userfaultfd sys_userfaultfd +344 common userfaultfd parisc_userfaultfd 345 common mlock2 sys_mlock2 346 common copy_file_range sys_copy_file_range 347 common preadv2 sys_preadv2 compat_sys_preadv2 @@ -437,3 +437,4 @@ 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 +440 common process_madvise sys_process_madvise diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 04508158815c..13d94f0f94a0 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -180,9 +180,16 @@ static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm) static int rtc_generic_set_time(struct device *dev, struct rtc_time *tm) { time64_t secs = rtc_tm_to_time64(tm); - - if (pdc_tod_set(secs, 0) < 0) + int ret; + + /* hppa has Y2K38 problem: pdc_tod_set() takes an u32 value! */ + ret = pdc_tod_set(secs, 0); + if (ret != 0) { + pr_warn("pdc_tod_set(%lld) returned error %d\n", secs, ret); + if (ret == PDC_INVALID_ARG) + return -EINVAL; return -EOPNOTSUPP; + } return 0; } diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index 53e29d88f99c..2769eb991f58 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -164,6 +164,7 @@ SECTIONS _end = . ; STABS_DEBUG + ELF_DETAILS .note 0 : { *(.note) } /* Sections to be discarded */ diff --git a/arch/parisc/lib/bitops.c b/arch/parisc/lib/bitops.c index 2e4d1f05a926..9ac683bf6ae7 100644 --- a/arch/parisc/lib/bitops.c +++ b/arch/parisc/lib/bitops.c @@ -18,7 +18,7 @@ arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = { #endif #ifdef CONFIG_64BIT -unsigned long __xchg64(unsigned long x, unsigned long *ptr) +unsigned long __xchg64(unsigned long x, volatile unsigned long *ptr) { unsigned long temp, flags; @@ -30,7 +30,7 @@ unsigned long __xchg64(unsigned long x, unsigned long *ptr) } #endif -unsigned long __xchg32(int x, int *ptr) +unsigned long __xchg32(int x, volatile int *ptr) { unsigned long flags; long temp; @@ -43,7 +43,7 @@ unsigned long __xchg32(int x, int *ptr) } -unsigned long __xchg8(char x, char *ptr) +unsigned long __xchg8(char x, volatile char *ptr) { unsigned long flags; long temp; diff --git a/arch/parisc/lib/checksum.c b/arch/parisc/lib/checksum.c index c6f161583549..4818f3db84a5 100644 --- a/arch/parisc/lib/checksum.c +++ b/arch/parisc/lib/checksum.c @@ -106,20 +106,3 @@ __wsum csum_partial(const void *buff, int len, __wsum sum) } EXPORT_SYMBOL(csum_partial); - -/* - * copy while checksumming, otherwise like csum_partial - */ -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) -{ - /* - * It's 2:30 am and I don't feel like doing it real ... - * This is lots slower than the real thing (tm) - */ - sum = csum_partial(src, len, sum); - memcpy(dst, src, len); - - return sum; -} -EXPORT_SYMBOL(csum_partial_copy_nocheck); diff --git a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c index ce400417d54e..f03adb1999e7 100644 --- a/arch/parisc/lib/iomap.c +++ b/arch/parisc/lib/iomap.c @@ -346,6 +346,16 @@ u64 ioread64be(const void __iomem *addr) return *((u64 *)addr); } +u64 ioread64_hi_lo(const void __iomem *addr) +{ + u32 low, high; + + high = ioread32(addr + sizeof(u32)); + low = ioread32(addr); + + return low + ((u64)high << 32); +} + void iowrite8(u8 datum, void __iomem *addr) { if (unlikely(INDIRECT_ADDR(addr))) { @@ -409,6 +419,12 @@ void iowrite64be(u64 datum, void __iomem *addr) } } +void iowrite64_hi_lo(u64 val, void __iomem *addr) +{ + iowrite32(val >> 32, addr + sizeof(u32)); + iowrite32(val, addr); +} + /* Repeating interfaces */ void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count) @@ -511,6 +527,7 @@ EXPORT_SYMBOL(ioread32); EXPORT_SYMBOL(ioread32be); EXPORT_SYMBOL(ioread64); EXPORT_SYMBOL(ioread64be); +EXPORT_SYMBOL(ioread64_hi_lo); EXPORT_SYMBOL(iowrite8); EXPORT_SYMBOL(iowrite16); EXPORT_SYMBOL(iowrite16be); @@ -518,6 +535,7 @@ EXPORT_SYMBOL(iowrite32); EXPORT_SYMBOL(iowrite32be); EXPORT_SYMBOL(iowrite64); EXPORT_SYMBOL(iowrite64be); +EXPORT_SYMBOL(iowrite64_hi_lo); EXPORT_SYMBOL(ioread8_rep); EXPORT_SYMBOL(ioread16_rep); EXPORT_SYMBOL(ioread32_rep); diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 4381b65ae1e0..3ec633b11b54 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -42,11 +42,11 @@ extern void parisc_kernel_start(void); /* Kernel entry point in head.S */ * guarantee that global objects will be laid out in memory in the same order * as the order of declaration, so put these in different sections and use * the linker script to order them. */ -pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data..vm0.pmd"), aligned(PAGE_SIZE))); +pmd_t pmd0[PTRS_PER_PMD] __section(".data..vm0.pmd") __attribute__ ((aligned(PAGE_SIZE))); #endif -pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data..vm0.pgd"), aligned(PAGE_SIZE))); -pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data..vm0.pte"), aligned(PAGE_SIZE))); +pgd_t swapper_pg_dir[PTRS_PER_PGD] __section(".data..vm0.pgd") __attribute__ ((aligned(PAGE_SIZE))); +pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __section(".data..vm0.pte") __attribute__ ((aligned(PAGE_SIZE))); static struct resource data_resource = { .name = "Kernel data", diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 65bed1fdeaad..e9f13fe08492 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -59,7 +59,10 @@ config HAVE_SETUP_PER_CPU_AREA def_bool PPC64 config NEED_PER_CPU_EMBED_FIRST_CHUNK - def_bool PPC64 + def_bool y if PPC64 + +config NEED_PER_CPU_PAGE_FIRST_CHUNK + def_bool y if PPC64 config NR_IRQS int "Number of virtual interrupt numbers" @@ -116,7 +119,6 @@ config PPC # select ARCH_32BIT_OFF_T if PPC32 select ARCH_HAS_DEBUG_VIRTUAL - select ARCH_HAS_DEBUG_VM_PGTABLE select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_FORTIFY_SOURCE @@ -136,7 +138,7 @@ config PPC select ARCH_HAS_STRICT_KERNEL_RWX if (PPC32 && !HIBERNATION) select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UACCESS_FLUSHCACHE - select ARCH_HAS_UACCESS_MCSAFE if PPC64 + select ARCH_HAS_COPY_MC if PPC64 select ARCH_HAS_UBSAN_SANITIZE_ALL select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_KEEP_MEMBLOCK @@ -149,6 +151,7 @@ config PPC select ARCH_USE_QUEUED_RWLOCKS if PPC_QUEUED_SPINLOCKS select ARCH_USE_QUEUED_SPINLOCKS if PPC_QUEUED_SPINLOCKS select ARCH_WANT_IPC_PARSE_VERSION + select ARCH_WANT_IRQS_OFF_ACTIVATE_MM select ARCH_WEAK_RELEASE_ACQUIRE select BINFMT_ELF select BUILDTIME_TABLE_SORT @@ -246,6 +249,7 @@ config PPC select OLD_SIGACTION if PPC32 select OLD_SIGSUSPEND select PCI_DOMAINS if PCI + select PCI_MSI_ARCH_FALLBACKS if PCI_MSI select PCI_SYSCALL if PCI select PPC_DAWR if PPC64 select RTC_LIB @@ -946,23 +950,6 @@ config ARCH_WANTS_FREEZER_CONTROL source "kernel/power/Kconfig" -config SECCOMP - bool "Enable seccomp to safely compute untrusted bytecode" - depends on PROC_FS - default y - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via /proc/<pid>/seccomp, it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - - If unsure, say Y. Only embedded should say N here. - config PPC_MEM_KEYS prompt "PowerPC Memory Protection Keys" def_bool y @@ -981,7 +968,7 @@ config PPC_MEM_KEYS config PPC_SECURE_BOOT prompt "Enable secure boot support" bool - depends on PPC_POWERNV + depends on PPC_POWERNV || PPC_PSERIES depends on IMA_ARCH_POLICY imply IMA_SECURE_AND_OR_TRUSTED_BOOT help @@ -1001,6 +988,19 @@ config PPC_SECVAR_SYSFS read/write operations on these variables. Say Y if you have secure boot enabled and want to expose variables to userspace. +config PPC_RTAS_FILTER + bool "Enable filtering of RTAS syscalls" + default y + depends on PPC_RTAS + help + The RTAS syscall API has security issues that could be used to + compromise system integrity. This option enforces restrictions on the + RTAS calls and arguments passed by userspace programs to mitigate + these issues. + + Say Y unless you know what you are doing and the filter is causing + problems for you. + endmenu config ISA_DMA_API diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 3e8da9cf2eb9..a4d56f0a41d9 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -65,7 +65,6 @@ UTS_MACHINE := $(subst $(space),,$(machine-y)) ifdef CONFIG_PPC32 KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o else -KBUILD_LDS_MODULE += $(srctree)/arch/powerpc/kernel/module.lds ifeq ($(call ld-ifversion, -ge, 225000000, y),y) # Have the linker provide sfpr if possible. # There is a corresponding test in arch/powerpc/lib/Makefile @@ -264,7 +263,8 @@ KBUILD_CFLAGS += $(cpu-as-y) KBUILD_AFLAGS += $(aflags-y) KBUILD_CFLAGS += $(cflags-y) -head-y := arch/powerpc/kernel/head_$(BITS).o +head-$(CONFIG_PPC64) := arch/powerpc/kernel/head_64.o +head-$(CONFIG_PPC_BOOK3S_32) := arch/powerpc/kernel/head_book3s_32.o head-$(CONFIG_PPC_8xx) := arch/powerpc/kernel/head_8xx.o head-$(CONFIG_40x) := arch/powerpc/kernel/head_40x.o head-$(CONFIG_44x) := arch/powerpc/kernel/head_44x.o diff --git a/arch/powerpc/Makefile.postlink b/arch/powerpc/Makefile.postlink index 2268396ff4bb..a6c77f4d32b2 100644 --- a/arch/powerpc/Makefile.postlink +++ b/arch/powerpc/Makefile.postlink @@ -18,7 +18,7 @@ quiet_cmd_relocs_check = CHKREL $@ ifdef CONFIG_PPC_BOOK3S_64 cmd_relocs_check = \ $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@" ; \ - $(BASH) $(srctree)/arch/powerpc/tools/unrel_branch_check.sh "$(OBJDUMP)" "$@" + $(BASH) $(srctree)/arch/powerpc/tools/unrel_branch_check.sh "$(OBJDUMP)" "$(NM)" "$@" else cmd_relocs_check = \ $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@" diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index b88fd27a45f0..f8ce6d2dde7b 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -7,7 +7,7 @@ # Based on coffboot by Paul Mackerras # Simplified for ppc64 by Todd Inglett # -# NOTE: this code is built for 32 bit in ELF32 format even though +# NOTE: this code may be built for 32 bit in ELF32 format even though # it packages a 64 bit kernel. We do this to simplify the # bootloader and increase compatibility with OpenFirmware. # diff --git a/arch/powerpc/boot/dts/fsl/t1024rdb.dts b/arch/powerpc/boot/dts/fsl/t1024rdb.dts index 73a645324bc1..dbcd31cc35dc 100644 --- a/arch/powerpc/boot/dts/fsl/t1024rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1024rdb.dts @@ -161,7 +161,6 @@ rtc@68 { compatible = "dallas,ds1339"; reg = <0x68>; - interrupts = <0x1 0x1 0 0>; }; }; diff --git a/arch/powerpc/boot/dts/fsl/t1040rdb.dts b/arch/powerpc/boot/dts/fsl/t1040rdb.dts index 65ff34c49025..af0c8a6f5613 100644 --- a/arch/powerpc/boot/dts/fsl/t1040rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1040rdb.dts @@ -64,6 +64,40 @@ phy_sgmii_2: ethernet-phy@3 { reg = <0x03>; }; + + /* VSC8514 QSGMII PHY */ + phy_qsgmii_0: ethernet-phy@4 { + reg = <0x4>; + }; + + phy_qsgmii_1: ethernet-phy@5 { + reg = <0x5>; + }; + + phy_qsgmii_2: ethernet-phy@6 { + reg = <0x6>; + }; + + phy_qsgmii_3: ethernet-phy@7 { + reg = <0x7>; + }; + + /* VSC8514 QSGMII PHY */ + phy_qsgmii_4: ethernet-phy@8 { + reg = <0x8>; + }; + + phy_qsgmii_5: ethernet-phy@9 { + reg = <0x9>; + }; + + phy_qsgmii_6: ethernet-phy@a { + reg = <0xa>; + }; + + phy_qsgmii_7: ethernet-phy@b { + reg = <0xb>; + }; }; }; }; @@ -76,3 +110,76 @@ }; #include "t1040si-post.dtsi" + +&seville_switch { + status = "okay"; +}; + +&seville_port0 { + managed = "in-band-status"; + phy-handle = <&phy_qsgmii_0>; + phy-mode = "qsgmii"; + label = "ETH5"; + status = "okay"; +}; + +&seville_port1 { + managed = "in-band-status"; + phy-handle = <&phy_qsgmii_1>; + phy-mode = "qsgmii"; + label = "ETH4"; + status = "okay"; +}; + +&seville_port2 { + managed = "in-band-status"; + phy-handle = <&phy_qsgmii_2>; + phy-mode = "qsgmii"; + label = "ETH7"; + status = "okay"; +}; + +&seville_port3 { + managed = "in-band-status"; + phy-handle = <&phy_qsgmii_3>; + phy-mode = "qsgmii"; + label = "ETH6"; + status = "okay"; +}; + +&seville_port4 { + managed = "in-band-status"; + phy-handle = <&phy_qsgmii_4>; + phy-mode = "qsgmii"; + label = "ETH9"; + status = "okay"; +}; + +&seville_port5 { + managed = "in-band-status"; + phy-handle = <&phy_qsgmii_5>; + phy-mode = "qsgmii"; + label = "ETH8"; + status = "okay"; +}; + +&seville_port6 { + managed = "in-band-status"; + phy-handle = <&phy_qsgmii_6>; + phy-mode = "qsgmii"; + label = "ETH11"; + status = "okay"; +}; + +&seville_port7 { + managed = "in-band-status"; + phy-handle = <&phy_qsgmii_7>; + phy-mode = "qsgmii"; + label = "ETH10"; + status = "okay"; +}; + +&seville_port8 { + ethernet = <&enet0>; + status = "okay"; +}; diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi index 315d0557eefc..f58eb820eb5e 100644 --- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi @@ -628,6 +628,84 @@ status = "disabled"; }; }; + + seville_switch: ethernet-switch@800000 { + compatible = "mscc,vsc9953-switch"; + reg = <0x800000 0x290000>; + interrupts = <26 2 0 0>; + interrupt-names = "xtr"; + little-endian; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + seville_port0: port@0 { + reg = <0>; + status = "disabled"; + }; + + seville_port1: port@1 { + reg = <1>; + status = "disabled"; + }; + + seville_port2: port@2 { + reg = <2>; + status = "disabled"; + }; + + seville_port3: port@3 { + reg = <3>; + status = "disabled"; + }; + + seville_port4: port@4 { + reg = <4>; + status = "disabled"; + }; + + seville_port5: port@5 { + reg = <5>; + status = "disabled"; + }; + + seville_port6: port@6 { + reg = <6>; + status = "disabled"; + }; + + seville_port7: port@7 { + reg = <7>; + status = "disabled"; + }; + + seville_port8: port@8 { + reg = <8>; + phy-mode = "internal"; + status = "disabled"; + + fixed-link { + speed = <2500>; + full-duplex; + }; + }; + + seville_port9: port@9 { + reg = <9>; + phy-mode = "internal"; + status = "disabled"; + + fixed-link { + speed = <2500>; + full-duplex; + }; + }; + }; + }; }; &qe { diff --git a/arch/powerpc/boot/dts/fsl/t4240rdb.dts b/arch/powerpc/boot/dts/fsl/t4240rdb.dts index a56a705d41f7..145896f2eef6 100644 --- a/arch/powerpc/boot/dts/fsl/t4240rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t4240rdb.dts @@ -144,7 +144,6 @@ rtc@68 { compatible = "dallas,ds1374"; reg = <0x68>; - interrupts = <0x1 0x1 0 0>; }; }; diff --git a/arch/powerpc/boot/util.S b/arch/powerpc/boot/util.S index f11f0589a669..d03cdb7606dc 100644 --- a/arch/powerpc/boot/util.S +++ b/arch/powerpc/boot/util.S @@ -18,7 +18,7 @@ .text -/* udelay (on non-601 processors) needs to know the period of the +/* udelay needs to know the period of the * timebase in nanoseconds. This used to be hardcoded to be 60ns * (period of 66MHz/4). Now a variable is used that is initialized to * 60 for backward compatibility, but it can be overridden as necessary @@ -37,19 +37,6 @@ timebase_period_ns: */ .globl udelay udelay: - mfspr r4,SPRN_PVR - srwi r4,r4,16 - cmpwi 0,r4,1 /* 601 ? */ - bne .Ludelay_not_601 -00: li r0,86 /* Instructions / microsecond? */ - mtctr r0 -10: addi r0,r0,0 /* NOP */ - bdnz 10b - subic. r3,r3,1 - bne 00b - blr - -.Ludelay_not_601: mulli r4,r3,1000 /* nanoseconds */ /* Change r4 to be the number of ticks using: * (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns diff --git a/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig b/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig index 0683d8c292a8..cea72e85ed26 100644 --- a/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig +++ b/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig @@ -29,9 +29,9 @@ CONFIG_SYN_COOKIES=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_IDE=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_VIA82CXXX=y +CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_VIA=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E1000=y diff --git a/arch/powerpc/configs/85xx/tqm8540_defconfig b/arch/powerpc/configs/85xx/tqm8540_defconfig index 98982a0e82d8..bbf040aa1f9a 100644 --- a/arch/powerpc/configs/85xx/tqm8540_defconfig +++ b/arch/powerpc/configs/85xx/tqm8540_defconfig @@ -30,9 +30,9 @@ CONFIG_MTD_CFI_AMDSTD=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_IDE=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_VIA82CXXX=y +CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_VIA=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y diff --git a/arch/powerpc/configs/85xx/tqm8541_defconfig b/arch/powerpc/configs/85xx/tqm8541_defconfig index a6e21db1dafe..523ad8dcfd9d 100644 --- a/arch/powerpc/configs/85xx/tqm8541_defconfig +++ b/arch/powerpc/configs/85xx/tqm8541_defconfig @@ -30,9 +30,9 @@ CONFIG_MTD_CFI_AMDSTD=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_IDE=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_VIA82CXXX=y +CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_VIA=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y diff --git a/arch/powerpc/configs/85xx/tqm8555_defconfig b/arch/powerpc/configs/85xx/tqm8555_defconfig index ca1de3979474..0032ce1e8c9c 100644 --- a/arch/powerpc/configs/85xx/tqm8555_defconfig +++ b/arch/powerpc/configs/85xx/tqm8555_defconfig @@ -30,9 +30,9 @@ CONFIG_MTD_CFI_AMDSTD=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_IDE=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_VIA82CXXX=y +CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_VIA=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y diff --git a/arch/powerpc/configs/85xx/tqm8560_defconfig b/arch/powerpc/configs/85xx/tqm8560_defconfig index ca3b8c8ef30f..a80b971f7d6e 100644 --- a/arch/powerpc/configs/85xx/tqm8560_defconfig +++ b/arch/powerpc/configs/85xx/tqm8560_defconfig @@ -30,9 +30,9 @@ CONFIG_MTD_CFI_AMDSTD=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_IDE=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_BLK_DEV_VIA82CXXX=y +CONFIG_ATA=y +CONFIG_ATA_GENERIC=y +CONFIG_PATA_VIA=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig index af9af03059e4..15ed8d0aa014 100644 --- a/arch/powerpc/configs/pasemi_defconfig +++ b/arch/powerpc/configs/pasemi_defconfig @@ -108,7 +108,6 @@ CONFIG_FB_NVIDIA=y CONFIG_FB_NVIDIA_I2C=y CONFIG_FB_RADEON=y # CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_LOGO=y CONFIG_SOUND=y CONFIG_SND=y diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index 5e6f92ba3210..66e9a0fd64ff 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -743,7 +743,6 @@ CONFIG_FB_TRIDENT=m CONFIG_FB_SM501=m CONFIG_FB_IBM_GXT4500=y CONFIG_LCD_PLATFORM=m -CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_LOGO=y diff --git a/arch/powerpc/crypto/crc-vpmsum_test.c b/arch/powerpc/crypto/crc-vpmsum_test.c index dce86e75f1a8..c1c1ef9457fb 100644 --- a/arch/powerpc/crypto/crc-vpmsum_test.c +++ b/arch/powerpc/crypto/crc-vpmsum_test.c @@ -9,6 +9,7 @@ #include <crypto/internal/hash.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/random.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/cpufeature.h> @@ -22,10 +23,11 @@ static unsigned long iterations = 10000; static int __init crc_test_init(void) { u16 crc16 = 0, verify16 = 0; - u32 crc32 = 0, verify32 = 0; __le32 verify32le = 0; unsigned char *data; + u32 verify32 = 0; unsigned long i; + __le32 crc32; int ret; struct crypto_shash *crct10dif_tfm; @@ -98,7 +100,7 @@ static int __init crc_test_init(void) crypto_shash_final(crc32c_shash, (u8 *)(&crc32)); verify32 = le32_to_cpu(verify32le); verify32le = ~cpu_to_le32(__crc32c_le(~verify32, data+offset, len)); - if (crc32 != (u32)verify32le) { + if (crc32 != verify32le) { pr_err("FAILURE in CRC32: got 0x%08x expected 0x%08x (len %lu)\n", crc32, verify32, len); break; diff --git a/arch/powerpc/include/asm/asm-const.h b/arch/powerpc/include/asm/asm-const.h index 082c1538c562..0ce2368bd20f 100644 --- a/arch/powerpc/include/asm/asm-const.h +++ b/arch/powerpc/include/asm/asm-const.h @@ -11,4 +11,17 @@ # define __ASM_CONST(x) x##UL # define ASM_CONST(x) __ASM_CONST(x) #endif + +/* + * Inline assembly memory constraint + * + * GCC 4.9 doesn't properly handle pre update memory constraint "m<>" + * + */ +#if defined(GCC_VERSION) && GCC_VERSION < 50000 +#define UPD_CONSTR "" +#else +#define UPD_CONSTR "<>" +#endif + #endif /* _ASM_POWERPC_ASM_CONST_H */ diff --git a/arch/powerpc/include/asm/asm-prototypes.h b/arch/powerpc/include/asm/asm-prototypes.h index de14b1a34d56..d0b832cbbec8 100644 --- a/arch/powerpc/include/asm/asm-prototypes.h +++ b/arch/powerpc/include/asm/asm-prototypes.h @@ -67,6 +67,7 @@ void single_step_exception(struct pt_regs *regs); void program_check_exception(struct pt_regs *regs); void alignment_exception(struct pt_regs *regs); void StackOverflow(struct pt_regs *regs); +void stack_overflow_exception(struct pt_regs *regs); void kernel_fp_unavailable_exception(struct pt_regs *regs); void altivec_unavailable_exception(struct pt_regs *regs); void vsx_unavailable_exception(struct pt_regs *regs); @@ -144,7 +145,9 @@ void _kvmppc_restore_tm_pr(struct kvm_vcpu *vcpu, u64 guest_msr); void _kvmppc_save_tm_pr(struct kvm_vcpu *vcpu, u64 guest_msr); /* Patch sites */ -extern s32 patch__call_flush_branch_caches; +extern s32 patch__call_flush_branch_caches1; +extern s32 patch__call_flush_branch_caches2; +extern s32 patch__call_flush_branch_caches3; extern s32 patch__flush_count_cache_return; extern s32 patch__flush_link_stack_return; extern s32 patch__call_kvm_flush_link_stack; diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h index 082b98808701..b6ac4f86c87b 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h @@ -13,20 +13,24 @@ */ #define MAX_EA_BITS_PER_CONTEXT 46 -#define REGION_SHIFT (MAX_EA_BITS_PER_CONTEXT - 2) /* - * Our page table limit us to 64TB. Hence for the kernel mapping, - * each MAP area is limited to 16 TB. - * The four map areas are: linear mapping, vmap, IO and vmemmap + * Our page table limit us to 64TB. For 64TB physical memory, we only need 64GB + * of vmemmap space. To better support sparse memory layout, we use 61TB + * linear map range, 1TB of vmalloc, 1TB of I/O and 1TB of vmememmap. */ +#define REGION_SHIFT (40) #define H_KERN_MAP_SIZE (ASM_CONST(1) << REGION_SHIFT) /* - * Define the address range of the kernel non-linear virtual area - * 16TB + * Limits the linear mapping range */ -#define H_KERN_VIRT_START ASM_CONST(0xc000100000000000) +#define H_MAX_PHYSMEM_BITS 46 + +/* + * Define the address range of the kernel non-linear virtual area (61TB) + */ +#define H_KERN_VIRT_START ASM_CONST(0xc0003d0000000000) #ifndef __ASSEMBLY__ #define H_PTE_TABLE_SIZE (sizeof(pte_t) << H_PTE_INDEX_SIZE) diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index f20de1149ebe..338e62fbea0b 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -7,6 +7,19 @@ #define H_PUD_INDEX_SIZE 10 // size: 8B << 10 = 8KB, maps 2^10 x 16GB = 16TB #define H_PGD_INDEX_SIZE 8 // size: 8B << 8 = 2KB, maps 2^8 x 16TB = 4PB +/* + * If we store section details in page->flags we can't increase the MAX_PHYSMEM_BITS + * if we increase SECTIONS_WIDTH we will not store node details in page->flags and + * page_to_nid does a page->section->node lookup + * Hence only increase for VMEMMAP. Further depending on SPARSEMEM_EXTREME reduce + * memory requirements with large number of sections. + * 51 bits is the max physical real address on POWER9 + */ +#if defined(CONFIG_SPARSEMEM_VMEMMAP) && defined(CONFIG_SPARSEMEM_EXTREME) +#define H_MAX_PHYSMEM_BITS 51 +#else +#define H_MAX_PHYSMEM_BITS 46 +#endif /* * Each context is 512TB size. SLB miss for first context/default context diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h index 93d18da5e7ec..683a9c7d1b03 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h +++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h @@ -577,8 +577,8 @@ extern void slb_set_size(u16 size); * For vmalloc and memmap, we use just one context with 512TB. With 64 byte * struct page size, we need ony 32 TB in memmap for 2PB (51 bits (MAX_PHYSMEM_BITS)). */ -#if (MAX_PHYSMEM_BITS > MAX_EA_BITS_PER_CONTEXT) -#define MAX_KERNEL_CTX_CNT (1UL << (MAX_PHYSMEM_BITS - MAX_EA_BITS_PER_CONTEXT)) +#if (H_MAX_PHYSMEM_BITS > MAX_EA_BITS_PER_CONTEXT) +#define MAX_KERNEL_CTX_CNT (1UL << (H_MAX_PHYSMEM_BITS - MAX_EA_BITS_PER_CONTEXT)) #else #define MAX_KERNEL_CTX_CNT 1 #endif diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h index 55442d45c597..e0b52940e43c 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu.h +++ b/arch/powerpc/include/asm/book3s/64/mmu.h @@ -27,21 +27,6 @@ struct mmu_psize_def { extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; #endif /* __ASSEMBLY__ */ -/* - * If we store section details in page->flags we can't increase the MAX_PHYSMEM_BITS - * if we increase SECTIONS_WIDTH we will not store node details in page->flags and - * page_to_nid does a page->section->node lookup - * Hence only increase for VMEMMAP. Further depending on SPARSEMEM_EXTREME reduce - * memory requirements with large number of sections. - * 51 bits is the max physical real address on POWER9 - */ -#if defined(CONFIG_SPARSEMEM_VMEMMAP) && defined(CONFIG_SPARSEMEM_EXTREME) && \ - defined(CONFIG_PPC_64K_PAGES) -#define MAX_PHYSMEM_BITS 51 -#else -#define MAX_PHYSMEM_BITS 46 -#endif - /* 64-bit classic hash table MMU */ #include <asm/book3s/64/mmu-hash.h> @@ -85,7 +70,7 @@ extern unsigned int mmu_base_pid; /* * memory block size used with radix translation. */ -extern unsigned int __ro_after_init radix_mem_block_size; +extern unsigned long __ro_after_init radix_mem_block_size; #define PRTB_SIZE_SHIFT (mmu_pid_bits + 4) #define PRTB_ENTRIES (1ul << mmu_pid_bits) @@ -239,14 +224,14 @@ static inline void early_init_mmu_secondary(void) extern void hash__setup_initial_memory_limit(phys_addr_t first_memblock_base, phys_addr_t first_memblock_size); -extern void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base, - phys_addr_t first_memblock_size); static inline void setup_initial_memory_limit(phys_addr_t first_memblock_base, phys_addr_t first_memblock_size) { - if (early_radix_enabled()) - return radix__setup_initial_memory_limit(first_memblock_base, - first_memblock_size); + /* + * Hash has more strict restrictions. At this point we don't + * know which translations we will pick. Hence go with hash + * restrictions. + */ return hash__setup_initial_memory_limit(first_memblock_base, first_memblock_size); } diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 495fc0ccb453..cd3feeac6e87 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -294,6 +294,13 @@ extern unsigned long pci_io_base; #include <asm/book3s/64/hash.h> #include <asm/book3s/64/radix.h> +#if H_MAX_PHYSMEM_BITS > R_MAX_PHYSMEM_BITS +#define MAX_PHYSMEM_BITS H_MAX_PHYSMEM_BITS +#else +#define MAX_PHYSMEM_BITS R_MAX_PHYSMEM_BITS +#endif + + #ifdef CONFIG_PPC_64K_PAGES #include <asm/book3s/64/pgtable-64k.h> #else @@ -615,7 +622,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) VM_BUG_ON(pfn >> (64 - PAGE_SHIFT)); VM_BUG_ON((pfn << PAGE_SHIFT) & ~PTE_RPN_MASK); - return __pte(((pte_basic_t)pfn << PAGE_SHIFT) | pgprot_val(pgprot)); + return __pte(((pte_basic_t)pfn << PAGE_SHIFT) | pgprot_val(pgprot) | _PAGE_PTE); } static inline unsigned long pte_pfn(pte_t pte) @@ -651,11 +658,6 @@ static inline pte_t pte_mkexec(pte_t pte) return __pte_raw(pte_raw(pte) | cpu_to_be64(_PAGE_EXEC)); } -static inline pte_t pte_mkpte(pte_t pte) -{ - return __pte_raw(pte_raw(pte) | cpu_to_be64(_PAGE_PTE)); -} - static inline pte_t pte_mkwrite(pte_t pte) { /* @@ -819,6 +821,14 @@ static inline int pte_none(pte_t pte) static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte, int percpu) { + + VM_WARN_ON(!(pte_raw(pte) & cpu_to_be64(_PAGE_PTE))); + /* + * Keep the _PAGE_PTE added till we are sure we handle _PAGE_PTE + * in all the callers. + */ + pte = __pte_raw(pte_raw(pte) | cpu_to_be64(_PAGE_PTE)); + if (radix_enabled()) return radix__set_pte_at(mm, addr, ptep, pte, percpu); return hash__set_pte_at(mm, addr, ptep, pte, percpu); @@ -866,6 +876,13 @@ static inline bool pte_ci(pte_t pte) static inline void pmd_clear(pmd_t *pmdp) { + if (IS_ENABLED(CONFIG_DEBUG_VM) && !radix_enabled()) { + /* + * Don't use this if we can possibly have a hash page table + * entry mapping this. + */ + WARN_ON((pmd_val(*pmdp) & (H_PAGE_HASHPTE | _PAGE_PTE)) == (H_PAGE_HASHPTE | _PAGE_PTE)); + } *pmdp = __pmd(0); } @@ -914,6 +931,13 @@ static inline int pmd_bad(pmd_t pmd) static inline void pud_clear(pud_t *pudp) { + if (IS_ENABLED(CONFIG_DEBUG_VM) && !radix_enabled()) { + /* + * Don't use this if we can possibly have a hash page table + * entry mapping this. + */ + WARN_ON((pud_val(*pudp) & (H_PAGE_HASHPTE | _PAGE_PTE)) == (H_PAGE_HASHPTE | _PAGE_PTE)); + } *pudp = __pud(0); } diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h index 0cba794c4fb8..c7813dc628fc 100644 --- a/arch/powerpc/include/asm/book3s/64/radix.h +++ b/arch/powerpc/include/asm/book3s/64/radix.h @@ -91,6 +91,22 @@ * +------------------------------+ Kernel linear (0xc.....) */ + +/* + * If we store section details in page->flags we can't increase the MAX_PHYSMEM_BITS + * if we increase SECTIONS_WIDTH we will not store node details in page->flags and + * page_to_nid does a page->section->node lookup + * Hence only increase for VMEMMAP. Further depending on SPARSEMEM_EXTREME reduce + * memory requirements with large number of sections. + * 51 bits is the max physical real address on POWER9 + */ + +#if defined(CONFIG_SPARSEMEM_VMEMMAP) && defined(CONFIG_SPARSEMEM_EXTREME) +#define R_MAX_PHYSMEM_BITS 51 +#else +#define R_MAX_PHYSMEM_BITS 46 +#endif + #define RADIX_KERN_VIRT_START ASM_CONST(0xc008000000000000) /* * 49 = MAX_EA_BITS_PER_CONTEXT (hash specific). To make sure we pick diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index 2124b7090db9..ae0a68a838e8 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h @@ -97,7 +97,7 @@ static inline u32 l1_icache_bytes(void) #endif -#define __read_mostly __section(.data..read_mostly) +#define __read_mostly __section(".data..read_mostly") #ifdef CONFIG_PPC_BOOK3S_32 extern long _get_L2CR(void); diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 54764c6e922d..138e46d8c04e 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -98,6 +98,16 @@ static inline void invalidate_dcache_range(unsigned long start, mb(); /* sync */ } +#ifdef CONFIG_4xx +static inline void flush_instruction_cache(void) +{ + iccci((void *)KERNELBASE); + isync(); +} +#else +void flush_instruction_cache(void); +#endif + #include <asm-generic/cacheflush.h> #endif /* _ASM_POWERPC_CACHEFLUSH_H */ diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h index 9cce06194dcc..82f099ba2411 100644 --- a/arch/powerpc/include/asm/checksum.h +++ b/arch/powerpc/include/asm/checksum.h @@ -18,19 +18,18 @@ * Like csum_partial, this must be called with even lengths, * except for the last fragment. */ -extern __wsum csum_partial_copy_generic(const void *src, void *dst, - int len, __wsum sum, - int *src_err, int *dst_err); +extern __wsum csum_partial_copy_generic(const void *src, void *dst, int len); #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER extern __wsum csum_and_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr); + int len); #define HAVE_CSUM_COPY_USER extern __wsum csum_and_copy_to_user(const void *src, void __user *dst, - int len, __wsum sum, int *err_ptr); + int len); -#define csum_partial_copy_nocheck(src, dst, len, sum) \ - csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL) +#define _HAVE_ARCH_CSUM_AND_COPY +#define csum_partial_copy_nocheck(src, dst, len) \ + csum_partial_copy_generic((src), (dst), (len)) /* diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h index 3e3cdfaa76c6..9191fc29e6ed 100644 --- a/arch/powerpc/include/asm/compat.h +++ b/arch/powerpc/include/asm/compat.h @@ -27,8 +27,6 @@ typedef s16 compat_nlink_t; typedef u16 compat_ipc_pid_t; typedef u32 compat_caddr_t; typedef __kernel_fsid_t compat_fsid_t; -typedef s64 compat_s64; -typedef u64 compat_u64; struct compat_stat { compat_dev_t st_dev; diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 32a15dc49e8c..3d2f94afc13a 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -9,11 +9,6 @@ #ifndef __ASSEMBLY__ -/* - * Added to include __machine_check_early_realmode_* functions - */ -#include <asm/mce.h> - /* This structure can grow, it's real size is used by head.S code * via the mkdefs mechanism. */ @@ -170,6 +165,7 @@ static inline void cpu_feature_keys_init(void) { } #else /* CONFIG_PPC32 */ /* Define these to 0 for the sake of tests in common code */ #define CPU_FTR_PPC_LE (0) +#define CPU_FTR_SPE (0) #endif /* @@ -299,8 +295,6 @@ static inline void cpu_feature_keys_init(void) { } #define CPU_FTR_MAYBE_CAN_NAP 0 #endif -#define CPU_FTRS_PPC601 (CPU_FTR_COMMON | \ - CPU_FTR_COHERENT_ICACHE) #define CPU_FTRS_603 (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE | CPU_FTR_NOEXECUTE) #define CPU_FTRS_604 (CPU_FTR_COMMON | CPU_FTR_PPC_LE) @@ -483,7 +477,7 @@ static inline void cpu_feature_keys_init(void) { } CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \ - CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_ARCH_31 | \ + CPU_FTR_ARCH_300 | CPU_FTR_ARCH_31 | \ CPU_FTR_DAWR | CPU_FTR_DAWR1) #define CPU_FTRS_CELL (CPU_FTR_LWSYNC | \ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ @@ -516,10 +510,8 @@ static inline void cpu_feature_keys_init(void) { } #else enum { CPU_FTRS_POSSIBLE = -#ifdef CONFIG_PPC_BOOK3S_601 - CPU_FTRS_PPC601 | -#elif defined(CONFIG_PPC_BOOK3S_32) - CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU | +#ifdef CONFIG_PPC_BOOK3S_32 + CPU_FTRS_603 | 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 | @@ -594,9 +586,7 @@ enum { #else enum { CPU_FTRS_ALWAYS = -#ifdef CONFIG_PPC_BOOK3S_601 - CPU_FTRS_PPC601 & -#elif defined(CONFIG_PPC_BOOK3S_32) +#ifdef CONFIG_PPC_BOOK3S_32 CPU_FTRS_603 & 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 & diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index deb99fd6e060..98c8bd155bf9 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h @@ -23,7 +23,6 @@ extern int threads_per_core; extern int threads_per_subcore; extern int threads_shift; -extern bool has_big_cores; extern cpumask_t threads_core_mask; #else #define threads_per_core 1 diff --git a/arch/powerpc/include/asm/delay.h b/arch/powerpc/include/asm/delay.h index 66963f7d3e64..51bb8c1476c7 100644 --- a/arch/powerpc/include/asm/delay.h +++ b/arch/powerpc/include/asm/delay.h @@ -54,7 +54,7 @@ extern void udelay(unsigned long usecs); ({ \ typeof(condition) __ret; \ unsigned long __loops = tb_ticks_per_usec * timeout; \ - unsigned long __start = get_tbl(); \ + unsigned long __start = mftb(); \ \ if (delay) { \ while (!(__ret = (condition)) && \ diff --git a/arch/powerpc/include/asm/dma-direct.h b/arch/powerpc/include/asm/dma-direct.h index abc154d784b0..128304cbee1d 100644 --- a/arch/powerpc/include/asm/dma-direct.h +++ b/arch/powerpc/include/asm/dma-direct.h @@ -2,12 +2,12 @@ #ifndef ASM_POWERPC_DMA_DIRECT_H #define ASM_POWERPC_DMA_DIRECT_H 1 -static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { return paddr + dev->archdata.dma_offset; } -static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr) +static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) { return daddr - dev->archdata.dma_offset; } diff --git a/arch/powerpc/include/asm/drmem.h b/arch/powerpc/include/asm/drmem.h index 17ccc6474ab6..bf2402fed3e0 100644 --- a/arch/powerpc/include/asm/drmem.h +++ b/arch/powerpc/include/asm/drmem.h @@ -8,26 +8,39 @@ #ifndef _ASM_POWERPC_LMB_H #define _ASM_POWERPC_LMB_H +#include <linux/sched.h> + struct drmem_lmb { u64 base_addr; u32 drc_index; u32 aa_index; u32 flags; -#ifdef CONFIG_MEMORY_HOTPLUG - int nid; -#endif }; struct drmem_lmb_info { struct drmem_lmb *lmbs; int n_lmbs; - u32 lmb_size; + u64 lmb_size; }; extern struct drmem_lmb_info *drmem_info; +static inline struct drmem_lmb *drmem_lmb_next(struct drmem_lmb *lmb, + const struct drmem_lmb *start) +{ + /* + * DLPAR code paths can take several milliseconds per element + * when interacting with firmware. Ensure that we don't + * unfairly monopolize the CPU. + */ + if (((++lmb - start) % 16) == 0) + cond_resched(); + + return lmb; +} + #define for_each_drmem_lmb_in_range(lmb, start, end) \ - for ((lmb) = (start); (lmb) < (end); (lmb)++) + for ((lmb) = (start); (lmb) < (end); lmb = drmem_lmb_next(lmb, start)) #define for_each_drmem_lmb(lmb) \ for_each_drmem_lmb_in_range((lmb), \ @@ -67,7 +80,7 @@ struct of_drconf_cell_v2 { #define DRCONF_MEM_RESERVED 0x00000080 #define DRCONF_MEM_HOTREMOVABLE 0x00000100 -static inline u32 drmem_lmb_size(void) +static inline u64 drmem_lmb_size(void) { return drmem_info->lmb_size; } @@ -105,22 +118,4 @@ static inline void invalidate_lmb_associativity_index(struct drmem_lmb *lmb) lmb->aa_index = 0xffffffff; } -#ifdef CONFIG_MEMORY_HOTPLUG -static inline void lmb_set_nid(struct drmem_lmb *lmb) -{ - lmb->nid = memory_add_physaddr_to_nid(lmb->base_addr); -} -static inline void lmb_clear_nid(struct drmem_lmb *lmb) -{ - lmb->nid = -1; -} -#else -static inline void lmb_set_nid(struct drmem_lmb *lmb) -{ -} -static inline void lmb_clear_nid(struct drmem_lmb *lmb) -{ -} -#endif - #endif /* _ASM_POWERPC_LMB_H */ diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index d5f369bcd130..b1a5bba2e0b9 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -27,7 +27,6 @@ struct pci_dn; #define EEH_FORCE_DISABLED 0x02 /* EEH disabled */ #define EEH_PROBE_MODE_DEV 0x04 /* From PCI device */ #define EEH_PROBE_MODE_DEVTREE 0x08 /* From device tree */ -#define EEH_VALID_PE_ZERO 0x10 /* PE#0 is valid */ #define EEH_ENABLE_IO_FOR_LOG 0x20 /* Enable IO for log */ #define EEH_EARLY_DUMP_LOG 0x40 /* Dump log immediately */ @@ -74,7 +73,6 @@ struct pci_dn; struct eeh_pe { int type; /* PE type: PHB/Bus/Device */ int state; /* PE EEH dependent mode */ - int config_addr; /* Traditional PCI address */ int addr; /* PE configuration address */ struct pci_controller *phb; /* Associated PHB */ struct pci_bus *bus; /* Top PCI bus for bus PE */ @@ -216,7 +214,6 @@ enum { struct eeh_ops { char *name; - int (*init)(void); struct eeh_dev *(*probe)(struct pci_dev *pdev); int (*set_option)(struct eeh_pe *pe, int option); int (*get_state)(struct eeh_pe *pe, int *delay); @@ -281,8 +278,7 @@ int eeh_phb_pe_create(struct pci_controller *phb); int eeh_wait_state(struct eeh_pe *pe, int max_wait); struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb); struct eeh_pe *eeh_pe_next(struct eeh_pe *pe, struct eeh_pe *root); -struct eeh_pe *eeh_pe_get(struct pci_controller *phb, - int pe_no, int config_addr); +struct eeh_pe *eeh_pe_get(struct pci_controller *phb, int pe_no); int eeh_pe_tree_insert(struct eeh_dev *edev, struct eeh_pe *new_pe_parent); int eeh_pe_tree_remove(struct eeh_dev *edev); void eeh_pe_update_time_stamp(struct eeh_pe *pe); @@ -295,8 +291,7 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe); struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe); void eeh_show_enabled(void); -int __init eeh_ops_register(struct eeh_ops *ops); -int __exit eeh_ops_unregister(const char *name); +int __init eeh_init(struct eeh_ops *ops); int eeh_check_failure(const volatile void __iomem *token); int eeh_dev_check_failure(struct eeh_dev *edev); void eeh_addr_cache_init(void); diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index fbb377055471..c1fbccb04390 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -375,11 +375,13 @@ #define H_CPU_CHAR_THREAD_RECONFIG_CTRL (1ull << 57) // IBM bit 6 #define H_CPU_CHAR_COUNT_CACHE_DISABLED (1ull << 56) // IBM bit 7 #define H_CPU_CHAR_BCCTR_FLUSH_ASSIST (1ull << 54) // IBM bit 9 +#define H_CPU_CHAR_BCCTR_LINK_FLUSH_ASSIST (1ull << 52) // IBM bit 11 #define H_CPU_BEHAV_FAVOUR_SECURITY (1ull << 63) // IBM bit 0 #define H_CPU_BEHAV_L1D_FLUSH_PR (1ull << 62) // IBM bit 1 #define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ull << 61) // IBM bit 2 #define H_CPU_BEHAV_FLUSH_COUNT_CACHE (1ull << 58) // IBM bit 5 +#define H_CPU_BEHAV_FLUSH_LINK_STACK (1ull << 57) // IBM bit 6 /* Flag values used in H_REGISTER_PROC_TBL hcall */ #define PROC_TABLE_OP_MASK 0x18 @@ -560,6 +562,42 @@ struct hv_guest_state { /* Latest version of hv_guest_state structure */ #define HV_GUEST_STATE_VERSION 1 +/* + * From the document "H_GetPerformanceCounterInfo Interface" v1.07 + * + * H_GET_PERF_COUNTER_INFO argument + */ +struct hv_get_perf_counter_info_params { + __be32 counter_request; /* I */ + __be32 starting_index; /* IO */ + __be16 secondary_index; /* IO */ + __be16 returned_values; /* O */ + __be32 detail_rc; /* O, only needed when called via *_norets() */ + + /* + * O, size each of counter_value element in bytes, only set for version + * >= 0x3 + */ + __be16 cv_element_size; + + /* I, 0 (zero) for versions < 0x3 */ + __u8 counter_info_version_in; + + /* O, 0 (zero) if version < 0x3. Must be set to 0 when making hcall */ + __u8 counter_info_version_out; + __u8 reserved[0xC]; + __u8 counter_value[]; +} __packed; + +#define HGPCI_REQ_BUFFER_SIZE 4096 +#define HGPCI_MAX_DATA_BYTES \ + (HGPCI_REQ_BUFFER_SIZE - sizeof(struct hv_get_perf_counter_info_params)) + +struct hv_gpci_request_buffer { + struct hv_get_perf_counter_info_params params; + uint8_t bytes[HGPCI_MAX_DATA_BYTES]; +} __packed; + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_HVCALL_H */ diff --git a/arch/powerpc/include/asm/hw_breakpoint.h b/arch/powerpc/include/asm/hw_breakpoint.h index db206a7f38e2..abebfbee5b1c 100644 --- a/arch/powerpc/include/asm/hw_breakpoint.h +++ b/arch/powerpc/include/asm/hw_breakpoint.h @@ -10,6 +10,7 @@ #define _PPC_BOOK3S_64_HW_BREAKPOINT_H #include <asm/cpu_has_feature.h> +#include <asm/inst.h> #ifdef __KERNEL__ struct arch_hw_breakpoint { @@ -17,6 +18,7 @@ struct arch_hw_breakpoint { u16 type; u16 len; /* length of the target data symbol */ u16 hw_len; /* length programmed in hw */ + u8 flags; }; /* Note: Don't change the first 6 bits below as they are in the same order @@ -36,12 +38,15 @@ struct arch_hw_breakpoint { #define HW_BRK_TYPE_PRIV_ALL (HW_BRK_TYPE_USER | HW_BRK_TYPE_KERNEL | \ HW_BRK_TYPE_HYP) +#define HW_BRK_FLAG_DISABLED 0x1 + /* Minimum granularity */ #ifdef CONFIG_PPC_8xx #define HW_BREAKPOINT_SIZE 0x4 #else #define HW_BREAKPOINT_SIZE 0x8 #endif +#define HW_BREAKPOINT_SIZE_QUADWORD 0x10 #define DABR_MAX_LEN 8 #define DAWR_MAX_LEN 512 @@ -51,6 +56,13 @@ static inline int nr_wp_slots(void) return cpu_has_feature(CPU_FTR_DAWR1) ? 2 : 1; } +bool wp_check_constraints(struct pt_regs *regs, struct ppc_inst instr, + unsigned long ea, int type, int size, + struct arch_hw_breakpoint *info); + +void wp_get_instr_detail(struct pt_regs *regs, struct ppc_inst *instr, + int *type, int *size, unsigned long *ea); + #ifdef CONFIG_HAVE_HW_BREAKPOINT #include <linux/kdebug.h> #include <asm/reg.h> diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index 35060be09073..0363734ff56e 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -25,9 +25,8 @@ #define PACA_IRQ_DBELL 0x02 #define PACA_IRQ_EE 0x04 #define PACA_IRQ_DEC 0x08 /* Or FIT */ -#define PACA_IRQ_EE_EDGE 0x10 /* BookE only */ -#define PACA_IRQ_HMI 0x20 -#define PACA_IRQ_PMI 0x40 +#define PACA_IRQ_HMI 0x10 +#define PACA_IRQ_PMI 0x20 /* * Some soft-masked interrupts must be hard masked until they are replayed @@ -369,12 +368,6 @@ static inline void may_hard_irq_enable(void) { } #define ARCH_IRQ_INIT_FLAGS IRQ_NOREQUEST -/* - * interrupt-retrigger: should we handle this via lost interrupts and IPIs - * or should we not care like we do now ? --BenH. - */ -struct irq_chip; - #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_HW_IRQ_H */ diff --git a/arch/powerpc/include/asm/icswx.h b/arch/powerpc/include/asm/icswx.h index b0c70a35fd0e..f6599ccb3012 100644 --- a/arch/powerpc/include/asm/icswx.h +++ b/arch/powerpc/include/asm/icswx.h @@ -156,8 +156,7 @@ struct coprocessor_request_block { u8 reserved[32]; struct coprocessor_status_block csb; -} __packed; - +} __aligned(128); /* RFC02167 Initiate Coprocessor Instructions document * Chapter 8.2.1.1.1 RS @@ -188,6 +187,9 @@ static inline int icswx(__be32 ccw, struct coprocessor_request_block *crb) __be64 ccw_reg = ccw; u32 cr; + /* NB: the same structures are used by VAS-NX */ + BUILD_BUG_ON(sizeof(*crb) != 128); + __asm__ __volatile__( PPC_ICSWX(%1,0,%2) "\n" "mfcr %0\n" diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index 5032f1593299..deef7c94d7b6 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -12,7 +12,7 @@ #include <linux/compiler.h> #include <linux/spinlock.h> #include <linux/device.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/bitops.h> #include <asm/machdep.h> #include <asm/types.h> diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index 814dfab7e392..4f983ca4030a 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h @@ -35,7 +35,6 @@ static __inline__ int irq_canonicalize(int irq) extern int distribute_irqs; -struct irqaction; struct pt_regs; #define __ARCH_HAS_DO_SOFTIRQ diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 10ded83414de..d67a470e95a3 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -326,6 +326,7 @@ struct kvm_arch { #endif #ifdef CONFIG_KVM_XICS struct kvmppc_xics *xics; + struct kvmppc_xics *xics_device; struct kvmppc_xive *xive; /* Current XIVE device in use */ struct { struct kvmppc_xive *native; diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index a90b892f0bfe..475687f24f4a 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -65,7 +65,6 @@ struct machdep_calls { void __noreturn (*restart)(char *cmd); void __noreturn (*halt)(void); void (*panic)(char *str); - void (*cpu_die)(void); long (*time_init)(void); /* Optional, may be NULL */ @@ -222,8 +221,6 @@ struct machdep_calls { extern void e500_idle(void); extern void power4_idle(void); -extern void power7_idle(void); -extern void power9_idle(void); extern void ppc6xx_idle(void); extern void book3e_idle(void); @@ -235,7 +232,7 @@ extern void book3e_idle(void); extern struct machdep_calls ppc_md; extern struct machdep_calls *machine_id; -#define __machine_desc __attribute__ ((__section__ (".machine.desc"))) +#define __machine_desc __section(".machine.desc") #define define_machine(name) \ extern struct machdep_calls mach_##name; \ diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 7f3658a97384..e02aa793420b 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -244,7 +244,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, */ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) { - switch_mm(prev, next, current); + switch_mm_irqs_off(prev, next, current); } /* We don't currently use enter_lazy_tlb() for anything */ diff --git a/arch/powerpc/kernel/module.lds b/arch/powerpc/include/asm/module.lds.h index cea5dc124be4..cea5dc124be4 100644 --- a/arch/powerpc/kernel/module.lds +++ b/arch/powerpc/include/asm/module.lds.h diff --git a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h index e752a5807a59..39be9aea86db 100644 --- a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h +++ b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h @@ -65,4 +65,18 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, pte_update(mm, addr, ptep, clr, set, 1); } +#ifdef CONFIG_PPC_4K_PAGES +static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma, + struct page *page, int writable) +{ + size_t size = huge_page_size(hstate_vma(vma)); + + if (size == SZ_16K) + return __pte(pte_val(entry) & ~_PAGE_HUGE); + else + return entry; +} +#define arch_make_huge_pte arch_make_huge_pte +#endif + #endif /* _ASM_POWERPC_NOHASH_32_HUGETLB_8XX_H */ diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h index b9e134d0f03a..ee2243ba96cf 100644 --- a/arch/powerpc/include/asm/nohash/32/pgtable.h +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h @@ -227,6 +227,19 @@ static inline void pmd_clear(pmd_t *pmdp) */ #ifdef CONFIG_PPC_8xx static pmd_t *pmd_off(struct mm_struct *mm, unsigned long addr); +static int hugepd_ok(hugepd_t hpd); + +static int number_of_cells_per_pte(pmd_t *pmd, pte_basic_t val, int huge) +{ + if (!huge) + return PAGE_SIZE / SZ_4K; + else if (hugepd_ok(*((hugepd_t *)pmd))) + return 1; + else if (IS_ENABLED(CONFIG_PPC_4K_PAGES) && !(val & _PAGE_HUGE)) + return SZ_16K / SZ_4K; + else + return SZ_512K / SZ_4K; +} static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p, unsigned long clr, unsigned long set, int huge) @@ -237,12 +250,7 @@ static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, p int num, i; pmd_t *pmd = pmd_off(mm, addr); - if (!huge) - num = PAGE_SIZE / SZ_4K; - else if ((pmd_val(*pmd) & _PMD_PAGE_MASK) != _PMD_PAGE_8M) - num = SZ_512K / SZ_4K; - else - num = 1; + num = number_of_cells_per_pte(pmd, new, huge); for (i = 0; i < num; i++, entry++, new += SZ_4K) *entry = new; diff --git a/arch/powerpc/include/asm/nohash/pgtable.h b/arch/powerpc/include/asm/nohash/pgtable.h index 4b7c3472eab1..6277e7596ae5 100644 --- a/arch/powerpc/include/asm/nohash/pgtable.h +++ b/arch/powerpc/include/asm/nohash/pgtable.h @@ -140,11 +140,6 @@ static inline pte_t pte_mkold(pte_t pte) return __pte(pte_val(pte) & ~_PAGE_ACCESSED); } -static inline pte_t pte_mkpte(pte_t pte) -{ - return pte; -} - static inline pte_t pte_mkspecial(pte_t pte) { return __pte(pte_val(pte) | _PAGE_SPECIAL); diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index 63ed7e3b0ba3..6436f0b41539 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h @@ -9,7 +9,7 @@ #include <linux/types.h> #include <linux/slab.h> #include <linux/string.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/scatterlist.h> #include <asm/machdep.h> diff --git a/arch/powerpc/include/asm/pnv-ocxl.h b/arch/powerpc/include/asm/pnv-ocxl.h index ee79d2cd9fb6..d37ededca3ee 100644 --- a/arch/powerpc/include/asm/pnv-ocxl.h +++ b/arch/powerpc/include/asm/pnv-ocxl.h @@ -28,7 +28,4 @@ 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_alloc_xive_irq(u32 *irq, u64 *trigger_addr); -void pnv_ocxl_free_xive_irq(u32 irq); - #endif /* _ASM_PNV_OCXL_H */ diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index b4cc6608131c..511786f0e40d 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -382,16 +382,6 @@ n: #endif /* various errata or part fixups */ -#ifdef CONFIG_PPC601_SYNC_FIX -#define SYNC sync; isync -#define SYNC_601 sync -#define ISYNC_601 isync -#else -#define SYNC -#define SYNC_601 -#define ISYNC_601 -#endif - #if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) #define MFTB(dest) \ 90: mfspr dest, SPRN_TBRL; \ @@ -411,8 +401,7 @@ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96) #define MFTBU(dest) mfspr dest, SPRN_TBRU #endif -/* tlbsync is not implemented on 601 */ -#if !defined(CONFIG_SMP) || defined(CONFIG_PPC_BOOK3S_601) +#ifndef CONFIG_SMP #define TLBSYNC #else #define TLBSYNC tlbsync; sync diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index ed0d633ab5aa..c61c859b51a8 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -83,10 +83,6 @@ struct task_struct; void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp); void release_thread(struct task_struct *); -typedef struct { - unsigned long seg; -} mm_segment_t; - #define TS_FPR(i) fp_state.fpr[i][TS_FPROFFSET] #define TS_CKFPR(i) ckfp_state.fpr[i][TS_FPROFFSET] @@ -148,7 +144,6 @@ struct thread_struct { unsigned long ksp_vsid; #endif struct pt_regs *regs; /* Pointer to saved register state */ - mm_segment_t addr_limit; /* for get_fs() validation */ #ifdef CONFIG_BOOKE /* BookE base exception scratch space; align on cacheline */ unsigned long normsave[8] ____cacheline_aligned; @@ -220,6 +215,7 @@ struct thread_struct { unsigned long tm_tar; unsigned long tm_ppr; unsigned long tm_dscr; + unsigned long tm_amr; /* * Checkpointed FP and VSX 0-31 register set. @@ -295,7 +291,6 @@ struct thread_struct { #define INIT_THREAD { \ .ksp = INIT_SP, \ .ksp_limit = INIT_SP_LIMIT, \ - .addr_limit = KERNEL_DS, \ .pgdir = swapper_pg_dir, \ .fpexc_mode = MSR_FE0 | MSR_FE1, \ SPEFSCR_INIT \ @@ -303,7 +298,6 @@ struct thread_struct { #else #define INIT_THREAD { \ .ksp = INIT_SP, \ - .addr_limit = KERNEL_DS, \ .fpexc_mode = 0, \ } #endif @@ -432,16 +426,10 @@ enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF}; extern int powersave_nap; /* set if nap mode can be used in idle loop */ extern void power7_idle_type(unsigned long type); -extern void power9_idle_type(unsigned long stop_psscr_val, +extern void arch300_idle_type(unsigned long stop_psscr_val, unsigned long stop_psscr_mask); -extern void flush_instruction_cache(void); -extern void hard_reset_now(void); -extern void poweroff_now(void); extern int fix_alignment(struct pt_regs *); -extern void cvt_fd(float *from, double *to); -extern void cvt_df(double *from, float *to); -extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); #ifdef CONFIG_PPC64 /* diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index 155a197c0aa1..e2c778c176a3 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h @@ -243,11 +243,7 @@ static inline void set_trap_norestart(struct pt_regs *regs) } #define arch_has_single_step() (1) -#ifndef CONFIG_PPC_BOOK3S_601 #define arch_has_block_step() (true) -#else -#define arch_has_block_step() (false) -#endif #define ARCH_HAS_USER_SINGLE_STEP_REPORT /* diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 88fb88491fe9..f877a576b338 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -521,6 +521,8 @@ #define SPRN_TSCR 0x399 /* Thread Switch Control Register */ #define SPRN_DEC 0x016 /* Decrement Register */ +#define SPRN_PIT 0x3DB /* Programmable Interval Timer (40x/BOOKE) */ + #define SPRN_DER 0x095 /* Debug Enable Register */ #define DER_RSTE 0x40000000 /* Reset Interrupt */ #define DER_CHSTPE 0x20000000 /* Check Stop */ @@ -817,7 +819,7 @@ #define THRM1_TIN (1 << 31) #define THRM1_TIV (1 << 30) #define THRM1_THRES(x) ((x&0x7f)<<23) -#define THRM3_SITV(x) ((x&0x3fff)<<1) +#define THRM3_SITV(x) ((x & 0x1fff) << 1) #define THRM1_TID (1<<2) #define THRM1_TIE (1<<1) #define THRM1_V (1<<0) @@ -1353,6 +1355,7 @@ #define PVR_POWER8NVL 0x004C #define PVR_POWER8 0x004D #define PVR_POWER9 0x004E +#define PVR_POWER10 0x0080 #define PVR_BE 0x0070 #define PVR_PA6T 0x0090 @@ -1416,8 +1419,7 @@ static inline void msr_check_and_clear(unsigned long bits) __msr_check_and_clear(bits); } -#ifdef __powerpc64__ -#if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) +#if defined(CONFIG_PPC_CELL) || defined(CONFIG_E500) #define mftb() ({unsigned long rval; \ asm volatile( \ "90: mfspr %0, %2;\n" \ @@ -1427,29 +1429,23 @@ static inline void msr_check_and_clear(unsigned long bits) : "=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 */ -#else /* __powerpc64__ */ - #if defined(CONFIG_PPC_8xx) -#define mftbl() ({unsigned long rval; \ - asm volatile("mftbl %0" : "=r" (rval)); rval;}) #define mftbu() ({unsigned long rval; \ asm volatile("mftbu %0" : "=r" (rval)); rval;}) #else -#define mftbl() ({unsigned long rval; \ - asm volatile("mfspr %0, %1" : "=r" (rval) : \ - "i" (SPRN_TBRL)); rval;}) #define mftbu() ({unsigned long rval; \ asm volatile("mfspr %0, %1" : "=r" (rval) : \ "i" (SPRN_TBRU)); rval;}) #endif -#define mftb() mftbl() -#endif /* !__powerpc64__ */ #define mttbl(v) asm volatile("mttbl %0":: "r"(v)) #define mttbu(v) asm volatile("mttbu %0":: "r"(v)) diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index ff30f1076162..29a948e0c0f2 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -174,7 +174,6 @@ #define SPRN_L1CSR1 0x3F3 /* L1 Cache Control and Status Register 1 */ #define SPRN_MMUCSR0 0x3F4 /* MMU Control and Status Register 0 */ #define SPRN_MMUCFG 0x3F7 /* MMU Configuration Register */ -#define SPRN_PIT 0x3DB /* Programmable Interval Timer */ #define SPRN_BUCSR 0x3F5 /* Branch Unit Control and Status */ #define SPRN_L2CSR0 0x3F9 /* L2 Data Cache Control and Status Register 0 */ #define SPRN_L2CSR1 0x3FA /* L2 Data Cache Control and Status Register 1 */ diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 49a25e2400f2..b2035b2f57ce 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -28,8 +28,8 @@ extern int boot_cpuid; extern int spinning_secondaries; extern u32 *cpu_to_phys_id; +extern bool coregroup_enabled; -extern void cpu_die(void); extern int cpu_to_chip_id(int cpu); #ifdef CONFIG_SMP @@ -50,6 +50,9 @@ struct smp_ops_t { int (*cpu_disable)(void); void (*cpu_die)(unsigned int nr); int (*cpu_bootable)(unsigned int nr); +#ifdef CONFIG_HOTPLUG_CPU + void (*cpu_offline_self)(void); +#endif }; extern int smp_send_nmi_ipi(int cpu, void (*fn)(struct pt_regs *), u64 delay_us); @@ -118,11 +121,6 @@ static inline struct cpumask *cpu_sibling_mask(int cpu) return per_cpu(cpu_sibling_map, cpu); } -static inline struct cpumask *cpu_core_mask(int cpu) -{ - return per_cpu(cpu_core_map, cpu); -} - static inline struct cpumask *cpu_l2_cache_mask(int cpu) { return per_cpu(cpu_l2_cache_map, cpu); @@ -135,6 +133,19 @@ static inline struct cpumask *cpu_smallcore_mask(int cpu) extern int cpu_to_core_id(int cpu); +extern bool has_big_cores; + +#define cpu_smt_mask cpu_smt_mask +#ifdef CONFIG_SCHED_SMT +static inline const struct cpumask *cpu_smt_mask(int cpu) +{ + if (has_big_cores) + return per_cpu(cpu_smallcore_map, cpu); + + return per_cpu(cpu_sibling_map, cpu); +} +#endif /* CONFIG_SCHED_SMT */ + /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. * * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up @@ -243,7 +254,6 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); * 64-bit but defining them all here doesn't harm */ extern void generic_secondary_smp_init(void); -extern void generic_secondary_thread_init(void); extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_acknowledge; extern char __secondary_hold; diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h index 283552cd0e58..2aa0e31e6884 100644 --- a/arch/powerpc/include/asm/string.h +++ b/arch/powerpc/include/asm/string.h @@ -53,9 +53,7 @@ void *__memmove(void *to, const void *from, __kernel_size_t n); #ifndef CONFIG_KASAN #define __HAVE_ARCH_MEMSET32 #define __HAVE_ARCH_MEMSET64 -#define __HAVE_ARCH_MEMCPY_MCSAFE -extern int memcpy_mcsafe(void *dst, const void *src, __kernel_size_t sz); extern void *__memset16(uint16_t *, uint16_t v, __kernel_size_t); extern void *__memset32(uint32_t *, uint32_t v, __kernel_size_t); extern void *__memset64(uint64_t *, uint64_t v, __kernel_size_t); diff --git a/arch/powerpc/include/asm/svm.h b/arch/powerpc/include/asm/svm.h index 85580b30aba4..7546402d796a 100644 --- a/arch/powerpc/include/asm/svm.h +++ b/arch/powerpc/include/asm/svm.h @@ -15,6 +15,8 @@ static inline bool is_secure_guest(void) return mfmsr() & MSR_S; } +void __init svm_swiotlb_init(void); + void dtl_cache_ctor(void *addr); #define get_dtl_cache_ctor() (is_secure_guest() ? dtl_cache_ctor : NULL) @@ -25,6 +27,8 @@ static inline bool is_secure_guest(void) return false; } +static inline void svm_swiotlb_init(void) {} + #define get_dtl_cache_ctor() NULL #endif /* CONFIG_PPC_SVM */ diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h index aca70fb43147..1d67bc8d7bc6 100644 --- a/arch/powerpc/include/asm/synch.h +++ b/arch/powerpc/include/asm/synch.h @@ -3,8 +3,9 @@ #define _ASM_POWERPC_SYNCH_H #ifdef __KERNEL__ +#include <asm/cputable.h> #include <asm/feature-fixups.h> -#include <asm/asm-const.h> +#include <asm/ppc-opcode.h> #ifndef __ASSEMBLY__ extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup; @@ -20,6 +21,22 @@ static inline void isync(void) { __asm__ __volatile__ ("isync" : : : "memory"); } + +static inline void ppc_after_tlbiel_barrier(void) +{ + asm volatile("ptesync": : :"memory"); + /* + * POWER9, POWER10 need a cp_abort after tlbiel to ensure the copy is + * invalidated correctly. If this is not done, the paste can take data + * from the physical address that was translated at copy time. + * + * POWER9 in practice does not need this, because address spaces with + * accelerators mapped will use tlbie (which does invalidate the copy) + * to invalidate translations. It's not possible to limit POWER10 this + * way due to local copy-paste. + */ + asm volatile(ASM_FTR_IFSET(PPC_CP_ABORT, "", %0) : : "i" (CPU_FTR_ARCH_31) : "memory"); +} #endif /* __ASSEMBLY__ */ #if defined(__powerpc64__) diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index ca6c97025704..46a210b03d2b 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h @@ -90,7 +90,6 @@ void arch_setup_new_exec(void); #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_SIGPENDING 1 /* signal pending */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ -#define TIF_FSCHECK 3 /* Check FS is USER_DS on return */ #define TIF_SYSCALL_EMU 4 /* syscall emulation active */ #define TIF_RESTORE_TM 5 /* need to restore TM FP/VEC/VSX */ #define TIF_PATCH_PENDING 6 /* pending live patching update */ @@ -130,7 +129,6 @@ void arch_setup_new_exec(void); #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) #define _TIF_EMULATE_STACK_STORE (1<<TIF_EMULATE_STACK_STORE) #define _TIF_NOHZ (1<<TIF_NOHZ) -#define _TIF_FSCHECK (1<<TIF_FSCHECK) #define _TIF_SYSCALL_EMU (1<<TIF_SYSCALL_EMU) #define _TIF_SYSCALL_DOTRACE (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT | \ @@ -138,8 +136,7 @@ void arch_setup_new_exec(void); #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ - _TIF_RESTORE_TM | _TIF_PATCH_PENDING | \ - _TIF_FSCHECK) + _TIF_RESTORE_TM | _TIF_PATCH_PENDING) #define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR) /* Bits in local_flags */ diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index cb326720a8a1..2f566c1a754c 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h @@ -38,44 +38,10 @@ struct div_result { u64 result_low; }; -/* Accessor functions for the timebase (RTC on 601) registers. */ -#define __USE_RTC() (IS_ENABLED(CONFIG_PPC_BOOK3S_601)) - -#ifdef CONFIG_PPC64 - /* For compatibility, get_tbl() is defined as get_tb() on ppc64 */ -#define get_tbl get_tb - -#else - static inline unsigned long get_tbl(void) { - return mftbl(); -} - -static inline unsigned int get_tbu(void) -{ - return mftbu(); -} -#endif /* !CONFIG_PPC64 */ - -static inline unsigned int get_rtcl(void) -{ - unsigned int rtcl; - - asm volatile("mfrtcl %0" : "=r" (rtcl)); - return rtcl; -} - -static inline u64 get_rtc(void) -{ - unsigned int hi, lo, hi2; - - do { - asm volatile("mfrtcu %0; mfrtcl %1; mfrtcu %2" - : "=r" (hi), "=r" (lo), "=r" (hi2)); - } while (hi2 != hi); - return (u64)hi * 1000000000 + lo; + return mftb(); } static inline u64 get_vtb(void) @@ -87,30 +53,21 @@ static inline u64 get_vtb(void) return 0; } -#ifdef CONFIG_PPC64 -static inline u64 get_tb(void) -{ - return mftb(); -} -#else /* CONFIG_PPC64 */ static inline u64 get_tb(void) { unsigned int tbhi, tblo, tbhi2; + if (IS_ENABLED(CONFIG_PPC64)) + return mftb(); + do { - tbhi = get_tbu(); - tblo = get_tbl(); - tbhi2 = get_tbu(); + tbhi = mftbu(); + tblo = mftb(); + tbhi2 = mftbu(); } while (tbhi != tbhi2); return ((u64)tbhi << 32) | tblo; } -#endif /* !CONFIG_PPC64 */ - -static inline u64 get_tb_or_rtc(void) -{ - return __USE_RTC() ? get_rtc() : get_tb(); -} static inline void set_tb(unsigned int upper, unsigned int lower) { @@ -127,11 +84,10 @@ static inline void set_tb(unsigned int upper, unsigned int lower) */ static inline u64 get_dec(void) { -#if defined(CONFIG_40x) - return (mfspr(SPRN_PIT)); -#else - return (mfspr(SPRN_DEC)); -#endif + if (IS_ENABLED(CONFIG_40x)) + return mfspr(SPRN_PIT); + + return mfspr(SPRN_DEC); } /* @@ -141,23 +97,17 @@ static inline u64 get_dec(void) */ static inline void set_dec(u64 val) { -#if defined(CONFIG_40x) - mtspr(SPRN_PIT, (u32) val); -#else -#ifndef CONFIG_BOOKE - --val; -#endif - mtspr(SPRN_DEC, val); -#endif /* not 40x */ + if (IS_ENABLED(CONFIG_40x)) + mtspr(SPRN_PIT, (u32)val); + else if (IS_ENABLED(CONFIG_BOOKE)) + mtspr(SPRN_DEC, val); + else + mtspr(SPRN_DEC, val - 1); } static inline unsigned long tb_ticks_since(unsigned long tstamp) { - if (__USE_RTC()) { - int delta = get_rtcl() - (unsigned int) tstamp; - return delta < 0 ? delta + 1000000000 : delta; - } - return get_tbl() - tstamp; + return mftb() - tstamp; } #define mulhwu(x,y) \ diff --git a/arch/powerpc/include/asm/timex.h b/arch/powerpc/include/asm/timex.h index 6047402b0a4d..95988870a57b 100644 --- a/arch/powerpc/include/asm/timex.h +++ b/arch/powerpc/include/asm/timex.h @@ -17,9 +17,6 @@ typedef unsigned long cycles_t; static inline cycles_t get_cycles(void) { - if (IS_ENABLED(CONFIG_PPC_BOOK3S_601)) - return 0; - return mftb(); } diff --git a/arch/powerpc/include/asm/tlb.h b/arch/powerpc/include/asm/tlb.h index fbc6f3002f23..d97f061fecac 100644 --- a/arch/powerpc/include/asm/tlb.h +++ b/arch/powerpc/include/asm/tlb.h @@ -66,19 +66,6 @@ static inline int mm_is_thread_local(struct mm_struct *mm) return false; return cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)); } -static inline void mm_reset_thread_local(struct mm_struct *mm) -{ - WARN_ON(atomic_read(&mm->context.copros) > 0); - /* - * It's possible for mm_access to take a reference on mm_users to - * access the remote mm from another thread, but it's not allowed - * to set mm_cpumask, so mm_users may be > 1 here. - */ - WARN_ON(current->mm != mm); - atomic_set(&mm->context.active_cpus, 1); - cpumask_clear(mm_cpumask(mm)); - cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); -} #else /* CONFIG_PPC_BOOK3S_64 */ static inline int mm_is_thread_local(struct mm_struct *mm) { diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index f0b6300e7dd3..8728590f514a 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -86,14 +86,27 @@ static inline int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc) #endif /* CONFIG_NUMA */ +struct drmem_lmb; +int of_drconf_to_nid_single(struct drmem_lmb *lmb); + #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR) extern int find_and_online_cpu_nid(int cpu); +extern int cpu_to_coregroup_id(int cpu); #else static inline int find_and_online_cpu_nid(int cpu) { return 0; } +static inline int cpu_to_coregroup_id(int cpu) +{ +#ifdef CONFIG_SMP + return cpu_to_core_id(cpu); +#else + return 0; +#endif +} + #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */ #include <asm-generic/topology.h> @@ -104,15 +117,10 @@ static inline int find_and_online_cpu_nid(int cpu) #ifdef CONFIG_PPC64 #include <asm/smp.h> -#ifdef CONFIG_PPC_SPLPAR -int get_physical_package_id(int cpu); -#define topology_physical_package_id(cpu) (get_physical_package_id(cpu)) -#else #define topology_physical_package_id(cpu) (cpu_to_chip_id(cpu)) -#endif #define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) -#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) +#define topology_core_cpumask(cpu) (cpu_cpu_mask(cpu)) #define topology_core_id(cpu) (cpu_to_core_id(cpu)) #endif diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h index 00699903f1ef..ef5bbb705c08 100644 --- a/arch/powerpc/include/asm/uaccess.h +++ b/arch/powerpc/include/asm/uaccess.h @@ -8,62 +8,21 @@ #include <asm/extable.h> #include <asm/kup.h> -/* - * The fs value determines whether argument validity checking should be - * performed or not. If get_fs() == USER_DS, checking is performed, with - * get_fs() == KERNEL_DS, checking is bypassed. - * - * For historical reasons, these macros are grossly misnamed. - * - * The fs/ds values are now the highest legal address in the "segment". - * This simplifies the checking in the routines below. - */ - -#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) - -#define KERNEL_DS MAKE_MM_SEG(~0UL) #ifdef __powerpc64__ /* We use TASK_SIZE_USER64 as TASK_SIZE is not constant */ -#define USER_DS MAKE_MM_SEG(TASK_SIZE_USER64 - 1) +#define TASK_SIZE_MAX TASK_SIZE_USER64 #else -#define USER_DS MAKE_MM_SEG(TASK_SIZE - 1) +#define TASK_SIZE_MAX TASK_SIZE #endif -#define get_fs() (current->thread.addr_limit) - -static inline void set_fs(mm_segment_t fs) -{ - current->thread.addr_limit = fs; - /* On user-mode return check addr_limit (fs) is correct */ - set_thread_flag(TIF_FSCHECK); -} - -#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg) -#define user_addr_max() (get_fs().seg) - -#ifdef __powerpc64__ -/* - * This check is sufficient because there is a large enough - * gap between user addresses and the kernel addresses - */ -#define __access_ok(addr, size, segment) \ - (((addr) <= (segment).seg) && ((size) <= (segment).seg)) - -#else - -static inline int __access_ok(unsigned long addr, unsigned long size, - mm_segment_t seg) +static inline bool __access_ok(unsigned long addr, unsigned long size) { - if (addr > seg.seg) - return 0; - return (size == 0 || size - 1 <= seg.seg - addr); + return addr < TASK_SIZE_MAX && size <= TASK_SIZE_MAX - addr; } -#endif - #define access_ok(addr, size) \ (__chk_user_ptr(addr), \ - __access_ok((__force unsigned long)(addr), (size), get_fs())) + __access_ok((unsigned long)(addr), (size))) /* * These are the main single-value transfer routines. They automatically @@ -151,52 +110,16 @@ static inline int __access_ok(unsigned long addr, unsigned long size, extern long __put_user_bad(void); -/* - * We don't tell gcc that we are accessing memory, but this is OK - * because we do not write to any memory gcc knows about, so there - * are no aliasing issues. - */ -#define __put_user_asm(x, addr, err, op) \ - __asm__ __volatile__( \ - "1: " op " %1,0(%2) # put_user\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: li %0,%3\n" \ - " b 2b\n" \ - ".previous\n" \ - EX_TABLE(1b, 3b) \ - : "=r" (err) \ - : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err)) - -#ifdef __powerpc64__ -#define __put_user_asm2(x, ptr, retval) \ - __put_user_asm(x, ptr, retval, "std") -#else /* __powerpc64__ */ -#define __put_user_asm2(x, addr, err) \ - __asm__ __volatile__( \ - "1: stw %1,0(%2)\n" \ - "2: stw %1+1,4(%2)\n" \ - "3:\n" \ - ".section .fixup,\"ax\"\n" \ - "4: li %0,%3\n" \ - " b 3b\n" \ - ".previous\n" \ - EX_TABLE(1b, 4b) \ - EX_TABLE(2b, 4b) \ - : "=r" (err) \ - : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err)) -#endif /* __powerpc64__ */ - #define __put_user_size_allowed(x, ptr, size, retval) \ do { \ + __label__ __pu_failed; \ + \ retval = 0; \ - switch (size) { \ - case 1: __put_user_asm(x, ptr, retval, "stb"); break; \ - case 2: __put_user_asm(x, ptr, retval, "sth"); break; \ - case 4: __put_user_asm(x, ptr, retval, "stw"); break; \ - case 8: __put_user_asm2(x, ptr, retval); break; \ - default: __put_user_bad(); \ - } \ + __put_user_size_goto(x, ptr, size, __pu_failed); \ + break; \ + \ +__pu_failed: \ + retval = -EFAULT; \ } while (0) #define __put_user_size(x, ptr, size, retval) \ @@ -249,12 +172,17 @@ do { \ }) +/* + * We don't tell gcc that we are accessing memory, but this is OK + * because we do not write to any memory gcc knows about, so there + * are no aliasing issues. + */ #define __put_user_asm_goto(x, addr, label, op) \ asm volatile goto( \ "1: " op "%U1%X1 %0,%1 # put_user\n" \ EX_TABLE(1b, %l2) \ : \ - : "r" (x), "m" (*addr) \ + : "r" (x), "m"UPD_CONSTR (*addr) \ : \ : label) @@ -316,7 +244,7 @@ extern long __get_user_bad(void); #define __get_user_asm(x, addr, err, op) \ __asm__ __volatile__( \ - "1: "op" %1,0(%2) # get_user\n" \ + "1: "op"%U2%X2 %1, %2 # get_user\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ "3: li %0,%3\n" \ @@ -325,7 +253,7 @@ extern long __get_user_bad(void); ".previous\n" \ EX_TABLE(1b, 3b) \ : "=r" (err), "=r" (x) \ - : "b" (addr), "i" (-EFAULT), "0" (err)) + : "m"UPD_CONSTR (*addr), "i" (-EFAULT), "0" (err)) #ifdef __powerpc64__ #define __get_user_asm2(x, addr, err) \ @@ -333,8 +261,8 @@ extern long __get_user_bad(void); #else /* __powerpc64__ */ #define __get_user_asm2(x, addr, err) \ __asm__ __volatile__( \ - "1: lwz %1,0(%2)\n" \ - "2: lwz %1+1,4(%2)\n" \ + "1: lwz%X2 %1, %2\n" \ + "2: lwz%X2 %L1, %L2\n" \ "3:\n" \ ".section .fixup,\"ax\"\n" \ "4: li %0,%3\n" \ @@ -345,7 +273,7 @@ extern long __get_user_bad(void); EX_TABLE(1b, 4b) \ EX_TABLE(2b, 4b) \ : "=r" (err), "=&r" (x) \ - : "b" (addr), "i" (-EFAULT), "0" (err)) + : "m" (*addr), "i" (-EFAULT), "0" (err)) #endif /* __powerpc64__ */ #define __get_user_size_allowed(x, ptr, size, retval) \ @@ -355,10 +283,10 @@ do { \ if (size > sizeof(x)) \ (x) = __get_user_bad(); \ switch (size) { \ - case 1: __get_user_asm(x, ptr, retval, "lbz"); break; \ - case 2: __get_user_asm(x, ptr, retval, "lhz"); break; \ - case 4: __get_user_asm(x, ptr, retval, "lwz"); break; \ - case 8: __get_user_asm2(x, ptr, retval); break; \ + case 1: __get_user_asm(x, (u8 __user *)ptr, retval, "lbz"); break; \ + case 2: __get_user_asm(x, (u16 __user *)ptr, retval, "lhz"); break; \ + case 4: __get_user_asm(x, (u32 __user *)ptr, retval, "lwz"); break; \ + case 8: __get_user_asm2(x, (u64 __user *)ptr, retval); break; \ default: (x) = __get_user_bad(); \ } \ } while (0) @@ -435,6 +363,32 @@ do { \ extern unsigned long __copy_tofrom_user(void __user *to, const void __user *from, unsigned long size); +#ifdef CONFIG_ARCH_HAS_COPY_MC +unsigned long __must_check +copy_mc_generic(void *to, const void *from, unsigned long size); + +static inline unsigned long __must_check +copy_mc_to_kernel(void *to, const void *from, unsigned long size) +{ + return copy_mc_generic(to, from, size); +} +#define copy_mc_to_kernel copy_mc_to_kernel + +static inline unsigned long __must_check +copy_mc_to_user(void __user *to, const void *from, unsigned long n) +{ + if (likely(check_copy_size(from, n, true))) { + if (access_ok(to, n)) { + allow_write_to_user(to, n); + n = copy_mc_generic((void *)to, from, n); + prevent_write_to_user(to, n); + } + } + + return n; +} +#endif + #ifdef __powerpc64__ static inline unsigned long raw_copy_in_user(void __user *to, const void __user *from, unsigned long n) @@ -523,20 +477,6 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n) return ret; } -static __always_inline unsigned long __must_check -copy_to_user_mcsafe(void __user *to, const void *from, unsigned long n) -{ - if (likely(check_copy_size(from, n, true))) { - if (access_ok(to, n)) { - allow_write_to_user(to, n); - n = memcpy_mcsafe((void *)to, from, n); - prevent_write_to_user(to, n); - } - } - - return n; -} - unsigned long __arch_clear_user(void __user *addr, unsigned long size); static inline unsigned long clear_user(void __user *addr, unsigned long size) @@ -623,4 +563,20 @@ do { \ __put_user_goto(*(u8*)(_src + _i), (u8 __user *)(_dst + _i), e);\ } while (0) +#define HAVE_GET_KERNEL_NOFAULT + +#define __get_kernel_nofault(dst, src, type, err_label) \ +do { \ + int __kr_err; \ + \ + __get_user_size_allowed(*((type *)(dst)), (__force type __user *)(src),\ + sizeof(type), __kr_err); \ + if (unlikely(__kr_err)) \ + goto err_label; \ +} while (0) + +#define __put_kernel_nofault(dst, src, type, err_label) \ + __put_user_size_goto(*((type *)(src)), \ + (__force type __user *)(dst), sizeof(type), err_label) + #endif /* _ARCH_POWERPC_UACCESS_H */ diff --git a/arch/powerpc/include/uapi/asm/ptrace.h b/arch/powerpc/include/uapi/asm/ptrace.h index f5f1ccc740fc..7004cfea3f5f 100644 --- a/arch/powerpc/include/uapi/asm/ptrace.h +++ b/arch/powerpc/include/uapi/asm/ptrace.h @@ -222,6 +222,7 @@ struct ppc_debug_info { #define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x0000000000000004 #define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x0000000000000008 #define PPC_DEBUG_FEATURE_DATA_BP_DAWR 0x0000000000000010 +#define PPC_DEBUG_FEATURE_DATA_BP_ARCH_31 0x0000000000000020 #ifndef __ASSEMBLY__ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index cbf41fb4ee89..bf0bf1b900d2 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -45,7 +45,8 @@ obj-y := cputable.o syscalls.o \ signal.o sysfs.o cacheinfo.o time.o \ prom.o traps.o setup-common.o \ udbg.o misc.o io.o misc_$(BITS).o \ - of_platform.o prom_parse.o firmware.o + of_platform.o prom_parse.o firmware.o \ + hw_breakpoint_constraints.o obj-y += ptrace/ obj-$(CONFIG_PPC64) += setup_64.o \ paca.o nvram_64.o note.o syscall_64.o @@ -94,7 +95,8 @@ obj-$(CONFIG_PPC_FSL_BOOK3E) += cpu_setup_fsl_booke.o obj-$(CONFIG_PPC_DOORBELL) += dbell.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o -extra-y := head_$(BITS).o +extra-$(CONFIG_PPC64) := head_64.o +extra-$(CONFIG_PPC_BOOK3S_32) := head_book3s_32.o extra-$(CONFIG_40x) := head_40x.o extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 8711c2164b45..c2722ff36e98 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -176,6 +176,7 @@ int main(void) OFFSET(THREAD_TM_TAR, thread_struct, tm_tar); OFFSET(THREAD_TM_PPR, thread_struct, tm_ppr); OFFSET(THREAD_TM_DSCR, thread_struct, tm_dscr); + OFFSET(THREAD_TM_AMR, thread_struct, tm_amr); OFFSET(PT_CKPT_REGS, thread_struct, ckpt_regs); OFFSET(THREAD_CKVRSTATE, thread_struct, ckvr_state.vr); OFFSET(THREAD_CKVRSAVE, thread_struct, ckvrsave); diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 02300edc6989..803c2a45b22a 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c @@ -26,7 +26,7 @@ static void scrollscreen(void); #endif -#define __force_data __section(.data) +#define __force_data __section(".data") static int g_loc_X __force_data; static int g_loc_Y __force_data; @@ -95,19 +95,10 @@ void __init btext_prepare_BAT(void) boot_text_mapped = 0; return; } - if (PVR_VER(mfspr(SPRN_PVR)) != 1) { - /* 603, 604, G3, G4, ... */ - lowbits = addr & ~0xFF000000UL; - addr &= 0xFF000000UL; - disp_BAT[0] = vaddr | (BL_16M<<2) | 2; - disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW); - } else { - /* 601 */ - lowbits = addr & ~0xFF800000UL; - addr &= 0xFF800000UL; - disp_BAT[0] = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4; - disp_BAT[1] = addr | BL_8M | 0x40; - } + lowbits = addr & ~0xFF000000UL; + addr &= 0xFF000000UL; + disp_BAT[0] = vaddr | (BL_16M<<2) | 2; + disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW); logicalDisplayBase = (void *) (vaddr + lowbits); } #endif diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 2aa89c6b2896..29de58d4dfb7 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -16,6 +16,7 @@ #include <asm/oprofile_impl.h> #include <asm/cputable.h> #include <asm/prom.h> /* for PTRRELOC on ARCH=ppc */ +#include <asm/mce.h> #include <asm/mmu.h> #include <asm/setup.h> @@ -120,9 +121,16 @@ extern void __restore_cpu_e6500(void); PPC_FEATURE2_DARN | \ PPC_FEATURE2_SCV) #define COMMON_USER_POWER10 COMMON_USER_POWER9 -#define COMMON_USER2_POWER10 (COMMON_USER2_POWER9 | \ - PPC_FEATURE2_ARCH_3_1 | \ - PPC_FEATURE2_MMA) +#define COMMON_USER2_POWER10 (PPC_FEATURE2_ARCH_3_1 | \ + PPC_FEATURE2_MMA | \ + PPC_FEATURE2_ARCH_3_00 | \ + PPC_FEATURE2_HAS_IEEE128 | \ + PPC_FEATURE2_DARN | \ + PPC_FEATURE2_SCV | \ + PPC_FEATURE2_ARCH_2_07 | \ + PPC_FEATURE2_DSCR | \ + PPC_FEATURE2_ISEL | PPC_FEATURE2_TAR | \ + PPC_FEATURE2_VEC_CRYPTO) #ifdef CONFIG_PPC_BOOK3E_64 #define COMMON_USER_BOOKE (COMMON_USER_PPC64 | PPC_FEATURE_BOOKE) @@ -608,21 +616,6 @@ static struct cpu_spec __initdata cpu_specs[] = { #endif /* CONFIG_PPC_BOOK3S_64 */ #ifdef CONFIG_PPC32 -#ifdef CONFIG_PPC_BOOK3S_601 - { /* 601 */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x00010000, - .cpu_name = "601", - .cpu_features = CPU_FTRS_PPC601, - .cpu_user_features = COMMON_USER | PPC_FEATURE_601_INSTR | - PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB, - .mmu_features = MMU_FTR_HPTE_TABLE, - .icache_bsize = 32, - .dcache_bsize = 32, - .machine_check = machine_check_generic, - .platform = "ppc601", - }, -#endif /* CONFIG_PPC_BOOK3S_601 */ #ifdef CONFIG_PPC_BOOK3S_6xx { /* 603 */ .pvr_mask = 0xffff0000, diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 569fecd7b5b2..a1c744194018 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -120,7 +120,8 @@ u64 dma_iommu_get_required_mask(struct device *dev) if (!tbl) return 0; - mask = 1ULL < (fls_long(tbl->it_offset + tbl->it_size) - 1); + mask = 1ULL << (fls_long(tbl->it_offset + tbl->it_size) + + tbl->it_page_shift - 1); mask += mask - 1; return mask; @@ -137,4 +138,6 @@ const struct dma_map_ops dma_iommu_ops = { .get_required_mask = dma_iommu_get_required_mask, .mmap = dma_common_mmap, .get_sgtable = dma_common_get_sgtable, + .alloc_pages = dma_common_alloc_pages, + .free_pages = dma_common_free_pages, }; diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c index f204ad79b6b5..1098863e17ee 100644 --- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c @@ -17,6 +17,7 @@ #include <asm/cputable.h> #include <asm/dt_cpu_ftrs.h> +#include <asm/mce.h> #include <asm/mmu.h> #include <asm/oprofile_impl.h> #include <asm/prom.h> diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 94682382fc8c..813713c9120c 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -466,11 +466,6 @@ int eeh_dev_check_failure(struct eeh_dev *edev) return 0; } - if (!pe->addr && !pe->config_addr) { - eeh_stats.no_cfg_addr++; - return 0; - } - /* * On PowerNV platform, we might already have fenced PHB * there and we need take care of that firstly. @@ -929,56 +924,6 @@ void eeh_save_bars(struct eeh_dev *edev) edev->config_space[1] |= PCI_COMMAND_MASTER; } -/** - * eeh_ops_register - Register platform dependent EEH operations - * @ops: platform dependent EEH operations - * - * Register the platform dependent EEH operation callback - * functions. The platform should call this function before - * any other EEH operations. - */ -int __init eeh_ops_register(struct eeh_ops *ops) -{ - if (!ops->name) { - pr_warn("%s: Invalid EEH ops name for %p\n", - __func__, ops); - return -EINVAL; - } - - if (eeh_ops && eeh_ops != ops) { - pr_warn("%s: EEH ops of platform %s already existing (%s)\n", - __func__, eeh_ops->name, ops->name); - return -EEXIST; - } - - eeh_ops = ops; - - return 0; -} - -/** - * eeh_ops_unregister - Unreigster platform dependent EEH operations - * @name: name of EEH platform operations - * - * Unregister the platform dependent EEH operation callback - * functions. - */ -int __exit eeh_ops_unregister(const char *name) -{ - if (!name || !strlen(name)) { - pr_warn("%s: Invalid EEH ops name\n", - __func__); - return -EINVAL; - } - - if (eeh_ops && !strcmp(eeh_ops->name, name)) { - eeh_ops = NULL; - return 0; - } - - return -EEXIST; -} - static int eeh_reboot_notifier(struct notifier_block *nb, unsigned long action, void *unused) { @@ -990,54 +935,6 @@ static struct notifier_block eeh_reboot_nb = { .notifier_call = eeh_reboot_notifier, }; -/** - * eeh_init - EEH initialization - * - * Initialize EEH by trying to enable it for all of the adapters in the system. - * As a side effect we can determine here if eeh is supported at all. - * Note that we leave EEH on so failed config cycles won't cause a machine - * check. If a user turns off EEH for a particular adapter they are really - * telling Linux to ignore errors. Some hardware (e.g. POWER5) won't - * grant access to a slot if EEH isn't enabled, and so we always enable - * EEH for all slots/all devices. - * - * The eeh-force-off option disables EEH checking globally, for all slots. - * Even if force-off is set, the EEH hardware is still enabled, so that - * newer systems can boot. - */ -static int eeh_init(void) -{ - struct pci_controller *hose, *tmp; - int ret = 0; - - /* Register reboot notifier */ - ret = register_reboot_notifier(&eeh_reboot_nb); - if (ret) { - pr_warn("%s: Failed to register notifier (%d)\n", - __func__, ret); - return ret; - } - - /* call platform initialization function */ - if (!eeh_ops) { - pr_warn("%s: Platform EEH operation not found\n", - __func__); - return -EEXIST; - } else if ((ret = eeh_ops->init())) - return ret; - - /* Initialize PHB PEs */ - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) - eeh_phb_pe_create(hose); - - eeh_addr_cache_init(); - - /* Initialize EEH event */ - return eeh_event_init(); -} - -core_initcall_sync(eeh_init); - static int eeh_device_notifier(struct notifier_block *nb, unsigned long action, void *data) { @@ -1062,12 +959,47 @@ static struct notifier_block eeh_device_nb = { .notifier_call = eeh_device_notifier, }; -static __init int eeh_set_bus_notifier(void) +/** + * eeh_init - System wide EEH initialization + * + * It's the platform's job to call this from an arch_initcall(). + */ +int eeh_init(struct eeh_ops *ops) { - bus_register_notifier(&pci_bus_type, &eeh_device_nb); - return 0; + struct pci_controller *hose, *tmp; + int ret = 0; + + /* the platform should only initialise EEH once */ + if (WARN_ON(eeh_ops)) + return -EEXIST; + if (WARN_ON(!ops)) + return -ENOENT; + eeh_ops = ops; + + /* Register reboot notifier */ + ret = register_reboot_notifier(&eeh_reboot_nb); + if (ret) { + pr_warn("%s: Failed to register reboot notifier (%d)\n", + __func__, ret); + return ret; + } + + ret = bus_register_notifier(&pci_bus_type, &eeh_device_nb); + if (ret) { + pr_warn("%s: Failed to register bus notifier (%d)\n", + __func__, ret); + return ret; + } + + /* Initialize PHB PEs */ + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) + eeh_phb_pe_create(hose); + + eeh_addr_cache_init(); + + /* Initialize EEH event */ + return eeh_event_init(); } -arch_initcall(eeh_set_bus_notifier); /** * eeh_probe_device() - Perform EEH initialization for the indicated pci device @@ -1720,7 +1652,7 @@ static ssize_t eeh_force_recover_write(struct file *filp, return -ENODEV; /* Retrieve PE */ - pe = eeh_pe_get(hose, pe_no, 0); + pe = eeh_pe_get(hose, pe_no); if (!pe) return -ENODEV; diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index d2aaaa73fdd5..845e024321d4 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -251,43 +251,21 @@ void eeh_pe_dev_traverse(struct eeh_pe *root, /** * __eeh_pe_get - Check the PE address - * @data: EEH PE - * @flag: EEH device * * For one particular PE, it can be identified by PE address * or tranditional BDF address. BDF address is composed of * Bus/Device/Function number. The extra data referred by flag * indicates which type of address should be used. */ -struct eeh_pe_get_flag { - int pe_no; - int config_addr; -}; - static void *__eeh_pe_get(struct eeh_pe *pe, void *flag) { - struct eeh_pe_get_flag *tmp = (struct eeh_pe_get_flag *) flag; + int *target_pe = flag; - /* Unexpected PHB PE */ + /* PHB PEs are special and should be ignored */ if (pe->type & EEH_PE_PHB) return NULL; - /* - * We prefer PE address. For most cases, we should - * have non-zero PE address - */ - if (eeh_has_flag(EEH_VALID_PE_ZERO)) { - if (tmp->pe_no == pe->addr) - return pe; - } else { - if (tmp->pe_no && - (tmp->pe_no == pe->addr)) - return pe; - } - - /* Try BDF address */ - if (tmp->config_addr && - (tmp->config_addr == pe->config_addr)) + if (*target_pe == pe->addr) return pe; return NULL; @@ -297,7 +275,6 @@ static void *__eeh_pe_get(struct eeh_pe *pe, void *flag) * eeh_pe_get - Search PE based on the given address * @phb: PCI controller * @pe_no: PE number - * @config_addr: Config address * * Search the corresponding PE based on the specified address which * is included in the eeh device. The function is used to check if @@ -306,16 +283,11 @@ static void *__eeh_pe_get(struct eeh_pe *pe, void *flag) * which is composed of PCI bus/device/function number, or unified * PE address. */ -struct eeh_pe *eeh_pe_get(struct pci_controller *phb, - int pe_no, int config_addr) +struct eeh_pe *eeh_pe_get(struct pci_controller *phb, int pe_no) { struct eeh_pe *root = eeh_phb_pe_get(phb); - struct eeh_pe_get_flag tmp = { pe_no, config_addr }; - struct eeh_pe *pe; - pe = eeh_pe_traverse(root, __eeh_pe_get, &tmp); - - return pe; + return eeh_pe_traverse(root, __eeh_pe_get, &pe_no); } /** @@ -336,19 +308,13 @@ int eeh_pe_tree_insert(struct eeh_dev *edev, struct eeh_pe *new_pe_parent) struct pci_controller *hose = edev->controller; struct eeh_pe *pe, *parent; - /* Check if the PE number is valid */ - if (!eeh_has_flag(EEH_VALID_PE_ZERO) && !edev->pe_config_addr) { - eeh_edev_err(edev, "PE#0 is invalid for this PHB!\n"); - return -EINVAL; - } - /* * Search the PE has been existing or not according * to the PE address. If that has been existing, the * PE should be composed of PCI bus and its subordinate * components. */ - pe = eeh_pe_get(hose, edev->pe_config_addr, edev->bdfn); + pe = eeh_pe_get(hose, edev->pe_config_addr); if (pe) { if (pe->type & EEH_PE_INVALID) { list_add_tail(&edev->entry, &pe->edevs); @@ -388,8 +354,8 @@ int eeh_pe_tree_insert(struct eeh_dev *edev, struct eeh_pe *new_pe_parent) pr_err("%s: out of memory!\n", __func__); return -ENOMEM; } - pe->addr = edev->pe_config_addr; - pe->config_addr = edev->bdfn; + + pe->addr = edev->pe_config_addr; /* * Put the new EEH PE into hierarchy tree. If the parent diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index f4d0af8e1136..8cdc8bcde703 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -234,7 +234,6 @@ transfer_to_handler_cont: mtspr SPRN_SRR0,r11 mtspr SPRN_SRR1,r10 mtlr r9 - SYNC RFI /* jump to handler, enable MMU */ #if defined (CONFIG_PPC_BOOK3S_32) || defined(CONFIG_E500) @@ -264,7 +263,6 @@ _ASM_NOKPROBE_SYMBOL(transfer_to_handler_cont) LOAD_REG_IMMEDIATE(r0, MSR_KERNEL) mtspr SPRN_SRR0,r12 mtspr SPRN_SRR1,r0 - SYNC RFI reenable_mmu: @@ -323,7 +321,6 @@ stack_ovf: #endif mtspr SPRN_SRR0,r9 mtspr SPRN_SRR1,r10 - SYNC RFI _ASM_NOKPROBE_SYMBOL(stack_ovf) #endif @@ -411,7 +408,6 @@ ret_from_syscall: /* disable interrupts so current_thread_info()->flags can't change */ LOAD_REG_IMMEDIATE(r10,MSR_KERNEL) /* doesn't include MSR_EE */ /* Note: We don't bother telling lockdep about it */ - SYNC mtmsr r10 lwz r9,TI_FLAGS(r2) li r8,-MAX_ERRNO @@ -474,7 +470,6 @@ syscall_exit_finish: #endif mtspr SPRN_SRR0,r7 mtspr SPRN_SRR1,r8 - SYNC RFI _ASM_NOKPROBE_SYMBOL(syscall_exit_finish) #ifdef CONFIG_44x @@ -567,7 +562,6 @@ syscall_exit_work: * lockdep as we are supposed to have IRQs on at this point */ ori r10,r10,MSR_EE - SYNC mtmsr r10 /* Save NVGPRS if they're not saved already */ @@ -606,7 +600,6 @@ ret_from_kernel_syscall: #endif mtspr SPRN_SRR0, r9 mtspr SPRN_SRR1, r10 - SYNC RFI _ASM_NOKPROBE_SYMBOL(ret_from_kernel_syscall) @@ -810,7 +803,6 @@ fast_exception_return: REST_GPR(9, r11) REST_GPR(12, r11) lwz r11,GPR11(r11) - SYNC RFI _ASM_NOKPROBE_SYMBOL(fast_exception_return) @@ -819,19 +811,11 @@ _ASM_NOKPROBE_SYMBOL(fast_exception_return) 1: lis r3,exc_exit_restart_end@ha addi r3,r3,exc_exit_restart_end@l cmplw r12,r3 -#ifdef CONFIG_PPC_BOOK3S_601 - bge 2b -#else bge 3f -#endif lis r4,exc_exit_restart@ha addi r4,r4,exc_exit_restart@l cmplw r12,r4 -#ifdef CONFIG_PPC_BOOK3S_601 - blt 2b -#else blt 3f -#endif lis r3,fee_restarts@ha tophys(r3,r3) lwz r5,fee_restarts@l(r3) @@ -848,7 +832,6 @@ fee_restarts: /* aargh, a nonrecoverable interrupt, panic */ /* aargh, we don't know which trap this is */ -/* but the 601 doesn't implement the RI bit, so assume it's OK */ 3: li r10,-1 stw r10,_TRAP(r11) @@ -872,7 +855,6 @@ ret_from_except: * from the interrupt. */ /* Note: We don't bother telling lockdep about it */ LOAD_REG_IMMEDIATE(r10,MSR_KERNEL) - SYNC /* Some chip revs have problems here... */ mtmsr r10 /* disable interrupts */ lwz r3,_MSR(r1) /* Returning to user mode? */ @@ -1035,7 +1017,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) * exc_exit_restart below. -- paulus */ LOAD_REG_IMMEDIATE(r10,MSR_KERNEL & ~MSR_RI) - SYNC mtmsr r10 /* clear the RI bit */ .globl exc_exit_restart exc_exit_restart: @@ -1046,7 +1027,6 @@ exc_exit_restart: lwz r1,GPR1(r1) .globl exc_exit_restart_end exc_exit_restart_end: - SYNC RFI _ASM_NOKPROBE_SYMBOL(exc_exit_restart) _ASM_NOKPROBE_SYMBOL(exc_exit_restart_end) @@ -1274,7 +1254,6 @@ do_resched: /* r10 contains MSR_KERNEL here */ mfmsr r10 #endif ori r10,r10,MSR_EE - SYNC mtmsr r10 /* hard-enable interrupts */ bl schedule recheck: @@ -1283,7 +1262,6 @@ recheck: * TI_FLAGS aren't advertised. */ LOAD_REG_IMMEDIATE(r10,MSR_KERNEL) - SYNC mtmsr r10 /* disable interrupts */ lwz r9,TI_FLAGS(r2) andi. r0,r9,_TIF_NEED_RESCHED @@ -1292,7 +1270,6 @@ recheck: beq restore_user do_user_signal: /* r10 contains MSR_KERNEL here */ ori r10,r10,MSR_EE - SYNC mtmsr r10 /* hard-enable interrupts */ /* save r13-r31 in the exception frame, if not already done */ lwz r3,_TRAP(r1) @@ -1316,19 +1293,11 @@ nonrecoverable: lis r10,exc_exit_restart_end@ha addi r10,r10,exc_exit_restart_end@l cmplw r12,r10 -#ifdef CONFIG_PPC_BOOK3S_601 - bgelr -#else bge 3f -#endif lis r11,exc_exit_restart@ha addi r11,r11,exc_exit_restart@l cmplw r12,r11 -#ifdef CONFIG_PPC_BOOK3S_601 - bltlr -#else blt 3f -#endif lis r10,ee_restarts@ha lwz r12,ee_restarts@l(r10) addi r12,r12,1 @@ -1336,7 +1305,6 @@ nonrecoverable: mr r12,r11 /* restart at exc_exit_restart */ blr 3: /* OK, we can't recover, kill this process */ - /* but the 601 doesn't implement the RI bit, so assume it's OK */ lwz r3,_TRAP(r1) andi. r0,r3,1 beq 5f @@ -1382,8 +1350,7 @@ _GLOBAL(enter_rtas) mfmsr r9 stw r9,8(r1) LOAD_REG_IMMEDIATE(r0,MSR_KERNEL) - SYNC /* disable interrupts so SRR0/1 */ - mtmsr r0 /* don't get trashed */ + mtmsr r0 /* disable interrupts so SRR0/1 don't get trashed */ li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR) mtlr r6 stw r7, THREAD + RTAS_SP(r2) diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 733e40eba4eb..2f3846192ec7 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -430,7 +430,11 @@ _ASM_NOKPROBE_SYMBOL(save_nvgprs); #define FLUSH_COUNT_CACHE \ 1: nop; \ - patch_site 1b, patch__call_flush_branch_caches + patch_site 1b, patch__call_flush_branch_caches1; \ +1: nop; \ + patch_site 1b, patch__call_flush_branch_caches2; \ +1: nop; \ + patch_site 1b, patch__call_flush_branch_caches3 .macro nops number .rept \number @@ -512,7 +516,7 @@ _GLOBAL(_switch) kuap_check_amr r9, r10 - FLUSH_COUNT_CACHE + FLUSH_COUNT_CACHE /* Clobbers r9, ctr */ /* * On SMP kernels, care must be taken because a task may be diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index d9ed79415100..f579ce46eef2 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S @@ -988,7 +988,6 @@ kernel_dbg_exc: .endm masked_interrupt_book3e_0x500: - // XXX When adding support for EPR, use PACA_IRQ_EE_EDGE masked_interrupt_book3e PACA_IRQ_EE 1 masked_interrupt_book3e_0x900: @@ -1303,16 +1302,6 @@ fast_exception_return: addi r3,r1,STACK_FRAME_OVERHEAD; bl do_IRQ b ret_from_except -1: cmpwi cr0,r3,0xf00 - bne 1f - addi r3,r1,STACK_FRAME_OVERHEAD; - bl performance_monitor_exception - b ret_from_except -1: cmpwi cr0,r3,0xe60 - bne 1f - addi r3,r1,STACK_FRAME_OVERHEAD; - bl handle_hmi_exception - b ret_from_except 1: cmpwi cr0,r3,0x900 bne 1f addi r3,r1,STACK_FRAME_OVERHEAD; diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index 10ebb4bf71ad..8482739d42f3 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c @@ -191,13 +191,13 @@ int is_fadump_active(void) */ static bool is_fadump_mem_area_contiguous(u64 d_start, u64 d_end) { - struct memblock_region *reg; + phys_addr_t reg_start, reg_end; bool ret = false; - u64 start, end; + u64 i, start, end; - for_each_memblock(memory, reg) { - start = max_t(u64, d_start, reg->base); - end = min_t(u64, d_end, (reg->base + reg->size)); + for_each_mem_range(i, ®_start, ®_end) { + start = max_t(u64, d_start, reg_start); + end = min_t(u64, d_end, reg_end); if (d_start < end) { /* Memory hole from d_start to start */ if (start > d_start) @@ -422,34 +422,34 @@ static int __init add_boot_mem_regions(unsigned long mstart, static int __init fadump_get_boot_mem_regions(void) { - unsigned long base, size, cur_size, hole_size, last_end; + unsigned long size, cur_size, hole_size, last_end; unsigned long mem_size = fw_dump.boot_memory_size; - struct memblock_region *reg; + phys_addr_t reg_start, reg_end; int ret = 1; + u64 i; fw_dump.boot_mem_regs_cnt = 0; last_end = 0; hole_size = 0; cur_size = 0; - for_each_memblock(memory, reg) { - base = reg->base; - size = reg->size; - hole_size += (base - last_end); + for_each_mem_range(i, ®_start, ®_end) { + size = reg_end - reg_start; + hole_size += (reg_start - last_end); if ((cur_size + size) >= mem_size) { size = (mem_size - cur_size); - ret = add_boot_mem_regions(base, size); + ret = add_boot_mem_regions(reg_start, size); break; } mem_size -= size; cur_size += size; - ret = add_boot_mem_regions(base, size); + ret = add_boot_mem_regions(reg_start, size); if (!ret) break; - last_end = base + size; + last_end = reg_end; } fw_dump.boot_mem_top = PAGE_ALIGN(fw_dump.boot_memory_size + hole_size); @@ -754,10 +754,8 @@ u32 *fadump_regs_to_elf_notes(u32 *buf, struct pt_regs *regs) void fadump_update_elfcore_header(char *bufp) { - struct elfhdr *elf; struct elf_phdr *phdr; - elf = (struct elfhdr *)bufp; bufp += sizeof(struct elfhdr); /* First note is a place holder for cpu notes info. */ @@ -985,9 +983,8 @@ static int fadump_init_elfcore_header(char *bufp) */ static int fadump_setup_crash_memory_ranges(void) { - struct memblock_region *reg; - u64 start, end; - int i, ret; + u64 i, start, end; + int ret; pr_debug("Setup crash memory ranges.\n"); crash_mrange_info.mem_range_cnt = 0; @@ -1005,10 +1002,7 @@ static int fadump_setup_crash_memory_ranges(void) return ret; } - for_each_memblock(memory, reg) { - start = (u64)reg->base; - end = start + (u64)reg->size; - + for_each_mem_range(i, &start, &end) { /* * skip the memory chunk that is already added * (0 through boot_memory_top). @@ -1242,14 +1236,17 @@ static void fadump_free_reserved_memory(unsigned long start_pfn, */ static void fadump_release_reserved_area(u64 start, u64 end) { + unsigned long reg_spfn, reg_epfn; u64 tstart, tend, spfn, epfn; - struct memblock_region *reg; + int i; spfn = PHYS_PFN(start); epfn = PHYS_PFN(end); - for_each_memblock(memory, reg) { - tstart = max_t(u64, spfn, memblock_region_memory_base_pfn(reg)); - tend = min_t(u64, epfn, memblock_region_memory_end_pfn(reg)); + + for_each_mem_pfn_range(i, MAX_NUMNODES, ®_spfn, ®_epfn, NULL) { + tstart = max_t(u64, spfn, reg_spfn); + tend = min_t(u64, epfn, reg_epfn); + if (tstart < tend) { fadump_free_reserved_memory(tstart, tend); @@ -1684,12 +1681,10 @@ int __init fadump_reserve_mem(void) /* Preserve everything above the base address */ static void __init fadump_reserve_crash_area(u64 base) { - struct memblock_region *reg; - u64 mstart, msize; + u64 i, mstart, mend, msize; - for_each_memblock(memory, reg) { - mstart = reg->base; - msize = reg->size; + for_each_mem_range(i, &mstart, &mend) { + msize = mend - mstart; if ((mstart + msize) < base) continue; diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 4ae39db70044..3ff9a8fafa46 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -87,7 +87,6 @@ BEGIN_FTR_SECTION oris r5,r5,MSR_VSX@h END_FTR_SECTION_IFSET(CPU_FTR_VSX) #endif - SYNC MTMSRD(r5) /* enable use of fpu now */ isync /* enable use of FP after return */ @@ -134,18 +133,3 @@ _GLOBAL(save_fpu) mffs fr0 stfd fr0,FPSTATE_FPSCR(r6) blr - -/* - * These are used in the alignment trap handler when emulating - * single-precision loads and stores. - */ - -_GLOBAL(cvt_fd) - lfs 0,0(r3) - stfd 0,0(r4) - blr - -_GLOBAL(cvt_df) - lfd 0,0(r3) - stfs 0,0(r4) - blr diff --git a/arch/powerpc/kernel/head_32.h b/arch/powerpc/kernel/head_32.h index 9abec6cd099c..7c767765071d 100644 --- a/arch/powerpc/kernel/head_32.h +++ b/arch/powerpc/kernel/head_32.h @@ -40,48 +40,52 @@ .macro EXCEPTION_PROLOG_1 for_rtas=0 #ifdef CONFIG_VMAP_STACK - .ifeq \for_rtas - li r11, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */ - mtmsr r11 - isync - .endif - subi r11, r1, INT_FRAME_SIZE /* use r1 if kernel */ + mr r11, 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 #else - tophys(r11,r1) /* use tophys(r1) if kernel */ - subi r11, r11, INT_FRAME_SIZE /* alloc exc. frame */ -#endif + subi r11, r1, INT_FRAME_SIZE /* use r1 if kernel */ beq 1f mfspr r11,SPRN_SPRG_THREAD - tovirt_vmstack r11, r11 lwz r11,TASK_STACK-THREAD(r11) addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE - tophys_novmstack r11, r11 +#endif 1: + tophys_novmstack r11, r11 #ifdef CONFIG_VMAP_STACK - mtcrf 0x7f, r11 + mtcrf 0x7f, r1 bt 32 - THREAD_ALIGN_SHIFT, stack_overflow #endif .endm .macro EXCEPTION_PROLOG_2 handle_dar_dsisr=0 -#if defined(CONFIG_VMAP_STACK) && defined(CONFIG_PPC_BOOK3S) -BEGIN_MMU_FTR_SECTION +#ifdef CONFIG_VMAP_STACK mtcr r10 -FTR_SECTION_ELSE - stw r10, _CCR(r11) -ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE) + li r10, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */ + mtmsr r10 + isync #else stw r10,_CCR(r11) /* save registers */ #endif mfspr r10, SPRN_SPRG_SCRATCH0 +#ifdef CONFIG_VMAP_STACK + stw r11,GPR1(r1) + stw r11,0(r1) + mr r11, r1 +#else + stw r1,GPR1(r11) + stw r1,0(r11) + tovirt(r1, r11) /* set new kernel sp */ +#endif stw r12,GPR12(r11) stw r9,GPR9(r11) stw r10,GPR10(r11) -#if defined(CONFIG_VMAP_STACK) && defined(CONFIG_PPC_BOOK3S) -BEGIN_MMU_FTR_SECTION +#ifdef CONFIG_VMAP_STACK mfcr r10 stw r10, _CCR(r11) -END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) #endif mfspr r12,SPRN_SPRG_SCRATCH1 stw r12,GPR11(r11) @@ -97,19 +101,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) stw r10, _DSISR(r11) .endif lwz r9, SRR1(r12) -#if defined(CONFIG_VMAP_STACK) && defined(CONFIG_PPC_BOOK3S) -BEGIN_MMU_FTR_SECTION andi. r10, r9, MSR_PR -END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) -#endif lwz r12, SRR0(r12) #else mfspr r12,SPRN_SRR0 mfspr r9,SPRN_SRR1 #endif - stw r1,GPR1(r11) - stw r1,0(r11) - tovirt_novmstack r1, r11 /* set new kernel sp */ #ifdef CONFIG_40x rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */ #else @@ -225,7 +222,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) #endif mtspr SPRN_SRR1,r10 mtspr SPRN_SRR0,r11 - SYNC RFI /* jump to handler, enable MMU */ 99: b ret_from_kernel_syscall .endm @@ -327,20 +323,19 @@ label: .macro vmap_stack_overflow_exception #ifdef CONFIG_VMAP_STACK #ifdef CONFIG_SMP - mfspr r11, SPRN_SPRG_THREAD - tovirt(r11, r11) - lwz r11, TASK_CPU - THREAD(r11) - slwi r11, r11, 3 - addis r11, r11, emergency_ctx@ha + mfspr r1, SPRN_SPRG_THREAD + lwz r1, TASK_CPU - THREAD(r1) + slwi r1, r1, 3 + addis r1, r1, emergency_ctx@ha #else - lis r11, emergency_ctx@ha + lis r1, emergency_ctx@ha #endif - lwz r11, emergency_ctx@l(r11) - cmpwi cr1, r11, 0 + lwz r1, emergency_ctx@l(r1) + cmpwi cr1, r1, 0 bne cr1, 1f - lis r11, init_thread_union@ha - addi r11, r11, init_thread_union@l -1: addi r11, r11, THREAD_SIZE - INT_FRAME_SIZE + lis r1, init_thread_union@ha + addi r1, r1, init_thread_union@l +1: addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE EXCEPTION_PROLOG_2 SAVE_NVGPRS(r11) addi r3, r1, STACK_FRAME_OVERHEAD diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S index 5b282d9965a5..44c9018aed1b 100644 --- a/arch/powerpc/kernel/head_40x.S +++ b/arch/powerpc/kernel/head_40x.S @@ -72,7 +72,6 @@ turn_on_mmu: lis r0,start_here@h ori r0,r0,start_here@l mtspr SPRN_SRR0,r0 - SYNC rfi /* enables MMU */ b . /* prevent prefetch past rfi */ diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 0e05a9a47a4b..1510b2a56669 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -300,9 +300,6 @@ _GLOBAL(fsl_secondary_thread_init) rlwimi r3, r3, 30, 2, 30 mtspr SPRN_PIR, r3 1: -#endif - -_GLOBAL(generic_secondary_thread_init) mr r24,r3 /* turn on 64-bit mode */ @@ -312,13 +309,13 @@ _GLOBAL(generic_secondary_thread_init) bl relative_toc tovirt(r2,r2) -#ifdef CONFIG_PPC_BOOK3E /* Book3E initialization */ mr r3,r24 bl book3e_secondary_thread_init -#endif b generic_secondary_common_init +#endif /* CONFIG_PPC_BOOK3E */ + /* * On pSeries and most other platforms, secondary processors spin * in the following code. diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_book3s_32.S index f3ab94d73936..5eb9eedac920 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_book3s_32.S @@ -34,16 +34,6 @@ #include "head_32.h" -/* 601 only have IBAT */ -#ifdef CONFIG_PPC_BOOK3S_601 -#define LOAD_BAT(n, reg, RA, RB) \ - li RA,0; \ - mtspr SPRN_IBAT##n##U,RA; \ - lwz RA,(n*16)+0(reg); \ - lwz RB,(n*16)+4(reg); \ - mtspr SPRN_IBAT##n##U,RA; \ - mtspr SPRN_IBAT##n##L,RB -#else #define LOAD_BAT(n, reg, RA, RB) \ /* see the comment for clear_bats() -- Cort */ \ li RA,0; \ @@ -57,11 +47,10 @@ lwz RB,(n*16)+12(reg); \ mtspr SPRN_DBAT##n##U,RA; \ mtspr SPRN_DBAT##n##L,RB -#endif __HEAD .stabs "arch/powerpc/kernel/",N_SO,0,0,0f - .stabs "head_32.S",N_SO,0,0,0f + .stabs "head_book3s_32.S",N_SO,0,0,0f 0: _ENTRY(_stext); @@ -166,9 +155,9 @@ __after_mmu_off: bl initial_bats bl load_segment_registers -#ifdef CONFIG_KASAN +BEGIN_MMU_FTR_SECTION bl early_hash_table -#endif +END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) #if defined(CONFIG_BOOTX_TEXT) bl setup_disp_bat #endif @@ -185,10 +174,8 @@ __after_mmu_off: bl reloc_offset li r24,0 /* cpu# */ bl call_setup_cpu /* Call setup_cpu for this CPU */ -#ifdef CONFIG_PPC_BOOK3S_32 bl reloc_offset bl init_idle_6xx -#endif /* CONFIG_PPC_BOOK3S_32 */ /* @@ -219,7 +206,6 @@ turn_on_mmu: lis r0,start_here@h ori r0,r0,start_here@l mtspr SPRN_SRR0,r0 - SYNC RFI /* enables MMU */ /* @@ -274,14 +260,8 @@ __secondary_hold_acknowledge: DO_KVM 0x200 MachineCheck: EXCEPTION_PROLOG_0 -#ifdef CONFIG_VMAP_STACK - li r11, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */ - mtmsr r11 - isync -#endif #ifdef CONFIG_PPC_CHRP mfspr r11, SPRN_SPRG_THREAD - tovirt_vmstack r11, r11 lwz r11, RTAS_SP(r11) cmpwi cr1, r11, 0 bne cr1, 7f @@ -439,7 +419,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE) SystemCall: SYSCALL_ENTRY 0xc00 -/* Single step - not used on 601 */ EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD) EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_STD) @@ -790,14 +769,12 @@ fast_hash_page_return: mtcr r11 lwz r11, THR11(r10) mfspr r10, SPRN_SPRG_SCRATCH0 - SYNC RFI 1: /* ISI */ mtcr r11 mfspr r11, SPRN_SPRG_SCRATCH1 mfspr r10, SPRN_SPRG_SCRATCH0 - SYNC RFI stack_overflow: @@ -888,7 +865,6 @@ __secondary_start_pmac_0: set to map the 0xf0000000 - 0xffffffff region */ mfmsr r0 rlwinm r0,r0,0,28,26 /* clear DR (0x10) */ - SYNC mtmsr r0 isync @@ -900,10 +876,8 @@ __secondary_start: lis r3,-KERNELBASE@h mr r4,r24 bl call_setup_cpu /* Call setup_cpu for this CPU */ -#ifdef CONFIG_PPC_BOOK3S_32 lis r3,-KERNELBASE@h bl init_idle_6xx -#endif /* CONFIG_PPC_BOOK3S_32 */ /* get current's stack and current */ lis r2,secondary_current@ha @@ -936,7 +910,6 @@ __secondary_start: ori r3,r3,start_secondary@l mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 - SYNC RFI #endif /* CONFIG_SMP */ @@ -945,21 +918,9 @@ __secondary_start: #endif /* - * Those generic dummy functions are kept for CPUs not - * included in CONFIG_PPC_BOOK3S_32 - */ -#if !defined(CONFIG_PPC_BOOK3S_32) -_ENTRY(__save_cpu_setup) - blr -_ENTRY(__restore_cpu_setup) - blr -#endif /* !defined(CONFIG_PPC_BOOK3S_32) */ - -/* * Load stuff into the MMU. Intended to be called with * IR=0 and DR=0. */ -#ifdef CONFIG_KASAN early_hash_table: sync /* Force all PTE updates to finish */ isync @@ -970,8 +931,10 @@ 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 + lis r3, Hash@ha + stw r6, Hash@l(r3) blr -#endif load_up_mmu: sync /* Force all PTE updates to finish */ @@ -985,8 +948,7 @@ load_up_mmu: lwz r6,_SDR1@l(r6) mtspr SPRN_SDR1,r6 -/* Load the BAT registers with the values set up by MMU_init. - MMU_init takes care of whether we're on a 601 or not. */ +/* Load the BAT registers with the values set up by MMU_init. */ lis r3,BATS@ha addi r3,r3,BATS@l tophys(r3,r3) @@ -1002,7 +964,7 @@ BEGIN_MMU_FTR_SECTION END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) blr -load_segment_registers: +_GLOBAL(load_segment_registers) li r0, NUM_USER_SEGMENTS /* load up user segment register values */ mtctr r0 /* for context 0 */ li r3, 0 /* Kp = 0, Ks = 0, VSID = 0 */ @@ -1061,11 +1023,7 @@ start_here: bl machine_init bl __save_cpu_setup bl MMU_init -#ifdef CONFIG_KASAN -BEGIN_MMU_FTR_SECTION bl MMU_init_hw_patch -END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) -#endif /* * Go back to running unmapped so we can load up new values @@ -1080,7 +1038,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) .align 4 mtspr SPRN_SRR0,r4 mtspr SPRN_SRR1,r3 - SYNC RFI /* Load up the kernel context */ 2: bl load_up_mmu @@ -1092,7 +1049,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) */ lis r5, abatron_pteptrs@h ori r5, r5, abatron_pteptrs@l - stw r5, 0xf0(r0) /* This much match your Abatron config */ + stw r5, 0xf0(0) /* This much match your Abatron config */ lis r6, swapper_pg_dir@h ori r6, r6, swapper_pg_dir@l tophys(r5, r5) @@ -1105,7 +1062,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) ori r3,r3,start_kernel@l mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 - SYNC RFI /* @@ -1165,7 +1121,6 @@ EXPORT_SYMBOL(switch_mmu_context) clear_bats: li r10,0 -#ifndef CONFIG_PPC_BOOK3S_601 mtspr SPRN_DBAT0U,r10 mtspr SPRN_DBAT0L,r10 mtspr SPRN_DBAT1U,r10 @@ -1174,7 +1129,6 @@ clear_bats: mtspr SPRN_DBAT2L,r10 mtspr SPRN_DBAT3U,r10 mtspr SPRN_DBAT3L,r10 -#endif mtspr SPRN_IBAT0U,r10 mtspr SPRN_IBAT0L,r10 mtspr SPRN_IBAT1U,r10 @@ -1223,7 +1177,6 @@ _ENTRY(update_bats) .align 4 mtspr SPRN_SRR0, r4 mtspr SPRN_SRR1, r3 - SYNC RFI 1: bl clear_bats lis r3, BATS@ha @@ -1243,7 +1196,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) mtmsr r3 mtspr SPRN_SRR0, r7 mtspr SPRN_SRR1, r6 - SYNC RFI flush_tlbs: @@ -1267,26 +1219,9 @@ mmu_off: sync RFI -/* - * On 601, we use 3 BATs to map up to 24M of RAM at _PAGE_OFFSET - * (we keep one for debugging) and on others, we use one 256M BAT. - */ +/* We use one BAT to map up to 256M of RAM at _PAGE_OFFSET */ initial_bats: lis r11,PAGE_OFFSET@h -#ifdef CONFIG_PPC_BOOK3S_601 - ori r11,r11,4 /* set up BAT registers for 601 */ - li r8,0x7f /* valid, block length = 8MB */ - mtspr SPRN_IBAT0U,r11 /* N.B. 601 has valid bit in */ - mtspr SPRN_IBAT0L,r8 /* lower BAT register */ - addis r11,r11,0x800000@h - addis r8,r8,0x800000@h - mtspr SPRN_IBAT1U,r11 - mtspr SPRN_IBAT1L,r8 - addis r11,r11,0x800000@h - addis r8,r8,0x800000@h - mtspr SPRN_IBAT2U,r11 - mtspr SPRN_IBAT2L,r8 -#else tophys(r8,r11) #ifdef CONFIG_SMP ori r8,r8,0x12 /* R/W access, M=1 */ @@ -1295,11 +1230,10 @@ initial_bats: #endif /* CONFIG_SMP */ ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */ - mtspr SPRN_DBAT0L,r8 /* N.B. 6xx (not 601) have valid */ + mtspr SPRN_DBAT0L,r8 /* N.B. 6xx have valid */ mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */ mtspr SPRN_IBAT0L,r8 mtspr SPRN_IBAT0U,r11 -#endif isync blr @@ -1317,13 +1251,8 @@ setup_disp_bat: beqlr lwz r11,0(r8) lwz r8,4(r8) -#ifndef CONFIG_PPC_BOOK3S_601 mtspr SPRN_DBAT3L,r8 mtspr SPRN_DBAT3U,r11 -#else - mtspr SPRN_IBAT3L,r8 - mtspr SPRN_IBAT3U,r11 -#endif blr #endif /* CONFIG_BOOTX_TEXT */ diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index 18f87bf9e32b..71c359d438b5 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -176,7 +176,6 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV) #endif mtspr SPRN_SRR1,r10 mtspr SPRN_SRR0,r11 - SYNC RFI /* jump to handler, enable MMU */ 99: b ret_from_kernel_syscall .endm diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index 1f4a1efa0074..f4e8f21046f5 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c @@ -494,151 +494,6 @@ reset: } } -static bool dar_in_user_range(unsigned long dar, struct arch_hw_breakpoint *info) -{ - return ((info->address <= dar) && (dar - info->address < info->len)); -} - -static bool ea_user_range_overlaps(unsigned long ea, int size, - struct arch_hw_breakpoint *info) -{ - return ((ea < info->address + info->len) && - (ea + size > info->address)); -} - -static bool dar_in_hw_range(unsigned long dar, struct arch_hw_breakpoint *info) -{ - unsigned long hw_start_addr, hw_end_addr; - - hw_start_addr = ALIGN_DOWN(info->address, HW_BREAKPOINT_SIZE); - hw_end_addr = ALIGN(info->address + info->len, HW_BREAKPOINT_SIZE); - - return ((hw_start_addr <= dar) && (hw_end_addr > dar)); -} - -static bool ea_hw_range_overlaps(unsigned long ea, int size, - struct arch_hw_breakpoint *info) -{ - unsigned long hw_start_addr, hw_end_addr; - - hw_start_addr = ALIGN_DOWN(info->address, HW_BREAKPOINT_SIZE); - hw_end_addr = ALIGN(info->address + info->len, HW_BREAKPOINT_SIZE); - - return ((ea < hw_end_addr) && (ea + size > hw_start_addr)); -} - -/* - * If hw has multiple DAWR registers, we also need to check all - * dawrx constraint bits to confirm this is _really_ a valid event. - * If type is UNKNOWN, but privilege level matches, consider it as - * a positive match. - */ -static bool check_dawrx_constraints(struct pt_regs *regs, int type, - struct arch_hw_breakpoint *info) -{ - if (OP_IS_LOAD(type) && !(info->type & HW_BRK_TYPE_READ)) - return false; - - /* - * The Cache Management instructions other than dcbz never - * cause a match. i.e. if type is CACHEOP, the instruction - * is dcbz, and dcbz is treated as Store. - */ - if ((OP_IS_STORE(type) || type == CACHEOP) && !(info->type & HW_BRK_TYPE_WRITE)) - return false; - - if (is_kernel_addr(regs->nip) && !(info->type & HW_BRK_TYPE_KERNEL)) - return false; - - if (user_mode(regs) && !(info->type & HW_BRK_TYPE_USER)) - return false; - - return true; -} - -/* - * Return true if the event is valid wrt dawr configuration, - * including extraneous exception. Otherwise return false. - */ -static bool check_constraints(struct pt_regs *regs, struct ppc_inst instr, - unsigned long ea, int type, int size, - struct arch_hw_breakpoint *info) -{ - bool in_user_range = dar_in_user_range(regs->dar, info); - bool dawrx_constraints; - - /* - * 8xx supports only one breakpoint and thus we can - * unconditionally return true. - */ - if (IS_ENABLED(CONFIG_PPC_8xx)) { - if (!in_user_range) - info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ; - return true; - } - - if (unlikely(ppc_inst_equal(instr, ppc_inst(0)))) { - if (cpu_has_feature(CPU_FTR_ARCH_31) && - !dar_in_hw_range(regs->dar, info)) - return false; - - return true; - } - - dawrx_constraints = check_dawrx_constraints(regs, type, info); - - if (type == UNKNOWN) { - if (cpu_has_feature(CPU_FTR_ARCH_31) && - !dar_in_hw_range(regs->dar, info)) - return false; - - return dawrx_constraints; - } - - if (ea_user_range_overlaps(ea, size, info)) - return dawrx_constraints; - - if (ea_hw_range_overlaps(ea, size, info)) { - if (dawrx_constraints) { - info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ; - return true; - } - } - return false; -} - -static int cache_op_size(void) -{ -#ifdef __powerpc64__ - return ppc64_caches.l1d.block_size; -#else - return L1_CACHE_BYTES; -#endif -} - -static void get_instr_detail(struct pt_regs *regs, struct ppc_inst *instr, - int *type, int *size, unsigned long *ea) -{ - struct instruction_op op; - - if (__get_user_instr_inatomic(*instr, (void __user *)regs->nip)) - return; - - analyse_instr(&op, regs, *instr); - *type = GETTYPE(op.type); - *ea = op.ea; -#ifdef __powerpc64__ - if (!(regs->msr & MSR_64BIT)) - *ea &= 0xffffffffUL; -#endif - - *size = GETSIZE(op.type); - if (*type == CACHEOP) { - *size = cache_op_size(); - *ea &= ~(*size - 1); - } -} - static bool is_larx_stcx_instr(int type) { return type == LARX || type == STCX; @@ -722,7 +577,7 @@ int hw_breakpoint_handler(struct die_args *args) rcu_read_lock(); if (!IS_ENABLED(CONFIG_PPC_8xx)) - get_instr_detail(regs, &instr, &type, &size, &ea); + wp_get_instr_detail(regs, &instr, &type, &size, &ea); for (i = 0; i < nr_wp_slots(); i++) { bp[i] = __this_cpu_read(bp_per_reg[i]); @@ -732,7 +587,7 @@ int hw_breakpoint_handler(struct die_args *args) info[i] = counter_arch_bp(bp[i]); info[i]->type &= ~HW_BRK_TYPE_EXTRANEOUS_IRQ; - if (check_constraints(regs, instr, ea, type, size, info[i])) { + if (wp_check_constraints(regs, instr, ea, type, size, info[i])) { if (!IS_ENABLED(CONFIG_PPC_8xx) && ppc_inst_equal(instr, ppc_inst(0))) { handler_error(bp[i], info[i]); diff --git a/arch/powerpc/kernel/hw_breakpoint_constraints.c b/arch/powerpc/kernel/hw_breakpoint_constraints.c new file mode 100644 index 000000000000..867ee4aa026a --- /dev/null +++ b/arch/powerpc/kernel/hw_breakpoint_constraints.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include <linux/kernel.h> +#include <linux/uaccess.h> +#include <linux/sched.h> +#include <asm/hw_breakpoint.h> +#include <asm/sstep.h> +#include <asm/cache.h> + +static bool dar_in_user_range(unsigned long dar, struct arch_hw_breakpoint *info) +{ + return ((info->address <= dar) && (dar - info->address < info->len)); +} + +static bool ea_user_range_overlaps(unsigned long ea, int size, + struct arch_hw_breakpoint *info) +{ + return ((ea < info->address + info->len) && + (ea + size > info->address)); +} + +static bool dar_in_hw_range(unsigned long dar, struct arch_hw_breakpoint *info) +{ + unsigned long hw_start_addr, hw_end_addr; + + hw_start_addr = ALIGN_DOWN(info->address, HW_BREAKPOINT_SIZE); + hw_end_addr = ALIGN(info->address + info->len, HW_BREAKPOINT_SIZE); + + return ((hw_start_addr <= dar) && (hw_end_addr > dar)); +} + +static bool ea_hw_range_overlaps(unsigned long ea, int size, + struct arch_hw_breakpoint *info) +{ + unsigned long hw_start_addr, hw_end_addr; + unsigned long align_size = HW_BREAKPOINT_SIZE; + + /* + * On p10 predecessors, quadword is handle differently then + * other instructions. + */ + if (!cpu_has_feature(CPU_FTR_ARCH_31) && size == 16) + align_size = HW_BREAKPOINT_SIZE_QUADWORD; + + hw_start_addr = ALIGN_DOWN(info->address, align_size); + hw_end_addr = ALIGN(info->address + info->len, align_size); + + return ((ea < hw_end_addr) && (ea + size > hw_start_addr)); +} + +/* + * If hw has multiple DAWR registers, we also need to check all + * dawrx constraint bits to confirm this is _really_ a valid event. + * If type is UNKNOWN, but privilege level matches, consider it as + * a positive match. + */ +static bool check_dawrx_constraints(struct pt_regs *regs, int type, + struct arch_hw_breakpoint *info) +{ + if (OP_IS_LOAD(type) && !(info->type & HW_BRK_TYPE_READ)) + return false; + + /* + * The Cache Management instructions other than dcbz never + * cause a match. i.e. if type is CACHEOP, the instruction + * is dcbz, and dcbz is treated as Store. + */ + if ((OP_IS_STORE(type) || type == CACHEOP) && !(info->type & HW_BRK_TYPE_WRITE)) + return false; + + if (is_kernel_addr(regs->nip) && !(info->type & HW_BRK_TYPE_KERNEL)) + return false; + + if (user_mode(regs) && !(info->type & HW_BRK_TYPE_USER)) + return false; + + return true; +} + +/* + * Return true if the event is valid wrt dawr configuration, + * including extraneous exception. Otherwise return false. + */ +bool wp_check_constraints(struct pt_regs *regs, struct ppc_inst instr, + unsigned long ea, int type, int size, + struct arch_hw_breakpoint *info) +{ + bool in_user_range = dar_in_user_range(regs->dar, info); + bool dawrx_constraints; + + /* + * 8xx supports only one breakpoint and thus we can + * unconditionally return true. + */ + if (IS_ENABLED(CONFIG_PPC_8xx)) { + if (!in_user_range) + info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ; + return true; + } + + if (unlikely(ppc_inst_equal(instr, ppc_inst(0)))) { + if (cpu_has_feature(CPU_FTR_ARCH_31) && + !dar_in_hw_range(regs->dar, info)) + return false; + + return true; + } + + dawrx_constraints = check_dawrx_constraints(regs, type, info); + + if (type == UNKNOWN) { + if (cpu_has_feature(CPU_FTR_ARCH_31) && + !dar_in_hw_range(regs->dar, info)) + return false; + + return dawrx_constraints; + } + + if (ea_user_range_overlaps(ea, size, info)) + return dawrx_constraints; + + if (ea_hw_range_overlaps(ea, size, info)) { + if (dawrx_constraints) { + info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ; + return true; + } + } + return false; +} + +static int cache_op_size(void) +{ +#ifdef __powerpc64__ + return ppc64_caches.l1d.block_size; +#else + return L1_CACHE_BYTES; +#endif +} + +void wp_get_instr_detail(struct pt_regs *regs, struct ppc_inst *instr, + int *type, int *size, unsigned long *ea) +{ + struct instruction_op op; + + if (__get_user_instr_inatomic(*instr, (void __user *)regs->nip)) + return; + + analyse_instr(&op, regs, *instr); + *type = GETTYPE(op.type); + *ea = op.ea; +#ifdef __powerpc64__ + if (!(regs->msr & MSR_64BIT)) + *ea &= 0xffffffffUL; +#endif + + *size = GETSIZE(op.type); + if (*type == CACHEOP) { + *size = cache_op_size(); + *ea &= ~(*size - 1); + } else if (*type == LOAD_VMX || *type == STORE_VMX) { + *ea &= ~(*size - 1); + } +} diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index 422e31d2f5a2..ae0e2632393d 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c @@ -41,14 +41,6 @@ static int __init powersave_off(char *arg) } __setup("powersave=off", powersave_off); -#ifdef CONFIG_HOTPLUG_CPU -void arch_cpu_idle_dead(void) -{ - sched_preempt_enable_no_resched(); - cpu_die(); -} -#endif - void arch_cpu_idle(void) { ppc64_runlatch_off(); diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 9704f3f76e63..5b69a6a72a0e 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -172,7 +172,6 @@ static unsigned long iommu_range_alloc(struct device *dev, int largealloc = npages > 15; int pass = 0; unsigned long align_mask; - unsigned long boundary_size; unsigned long flags; unsigned int pool_nr; struct iommu_pool *pool; @@ -236,15 +235,9 @@ again: } } - if (dev) - boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, - 1 << tbl->it_page_shift); - else - boundary_size = ALIGN(1UL << 32, 1 << tbl->it_page_shift); - /* 4GB boundary for iseries_hv_alloc and iseries_hv_map */ - n = iommu_area_alloc(tbl->it_map, limit, start, npages, tbl->it_offset, - boundary_size >> tbl->it_page_shift, align_mask); + dma_get_seg_boundary_nr_pages(dev, tbl->it_page_shift), + align_mask); if (n == -1) { if (likely(pass == 0)) { /* First try the pool from the start */ diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index bf21ebd36190..7d0f7682d01d 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -104,7 +104,7 @@ static inline notrace unsigned long get_irq_happened(void) static inline notrace int decrementer_check_overflow(void) { - u64 now = get_tb_or_rtc(); + u64 now = get_tb(); u64 *next_tb = this_cpu_ptr(&decrementers_next_tb); return now >= *next_tb; @@ -113,7 +113,7 @@ static inline notrace int decrementer_check_overflow(void) #ifdef CONFIG_PPC_BOOK3E /* This is called whenever we are re-enabling interrupts - * and returns either 0 (nothing to do) or 500/900/280/a00/e80 if + * and returns either 0 (nothing to do) or 500/900/280 if * there's an EE, DEC or DBELL to generate. * * This is called in two contexts: From arch_local_irq_restore() @@ -181,16 +181,6 @@ notrace unsigned int __check_irq_replay(void) return 0x500; } - /* - * Check if an EPR external interrupt happened this bit is typically - * set if we need to handle another "edge" interrupt from within the - * MPIC "EPR" handler. - */ - if (happened & PACA_IRQ_EE_EDGE) { - local_paca->irq_happened &= ~PACA_IRQ_EE_EDGE; - return 0x500; - } - if (happened & PACA_IRQ_DBELL) { local_paca->irq_happened &= ~PACA_IRQ_DBELL; return 0x280; @@ -201,6 +191,25 @@ notrace unsigned int __check_irq_replay(void) return 0; } + +/* + * This is specifically called by assembly code to re-enable interrupts + * if they are currently disabled. This is typically called before + * schedule() or do_signal() when returning to userspace. We do it + * in C to avoid the burden of dealing with lockdep etc... + * + * NOTE: This is called with interrupts hard disabled but not marked + * as such in paca->irq_happened, so we need to resync this. + */ +void notrace restore_interrupts(void) +{ + if (irqs_disabled()) { + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; + local_irq_enable(); + } else + __hard_irq_enable(); +} + #endif /* CONFIG_PPC_BOOK3E */ void replay_soft_interrupts(void) @@ -214,7 +223,7 @@ void replay_soft_interrupts(void) struct pt_regs regs; ppc_save_regs(®s); - regs.softe = IRQS_ALL_DISABLED; + regs.softe = IRQS_ENABLED; again: if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) @@ -270,19 +279,6 @@ again: hard_irq_disable(); } - /* - * Check if an EPR external interrupt happened this bit is typically - * set if we need to handle another "edge" interrupt from within the - * MPIC "EPR" handler. - */ - if (IS_ENABLED(CONFIG_PPC_BOOK3E) && (happened & PACA_IRQ_EE_EDGE)) { - local_paca->irq_happened &= ~PACA_IRQ_EE_EDGE; - regs.trap = 0x500; - do_IRQ(®s); - if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) - hard_irq_disable(); - } - if (IS_ENABLED(CONFIG_PPC_DOORBELL) && (happened & PACA_IRQ_DBELL)) { local_paca->irq_happened &= ~PACA_IRQ_DBELL; if (IS_ENABLED(CONFIG_PPC_BOOK3E)) @@ -368,6 +364,12 @@ notrace void arch_local_irq_restore(unsigned long mask) } } + /* + * Disable preempt here, so that the below preempt_enable will + * perform resched if required (a replayed interrupt may set + * need_resched). + */ + preempt_disable(); irq_soft_mask_set(IRQS_ALL_DISABLED); trace_hardirqs_off(); @@ -377,28 +379,11 @@ notrace void arch_local_irq_restore(unsigned long mask) trace_hardirqs_on(); irq_soft_mask_set(IRQS_ENABLED); __hard_irq_enable(); + preempt_enable(); } EXPORT_SYMBOL(arch_local_irq_restore); /* - * This is specifically called by assembly code to re-enable interrupts - * if they are currently disabled. This is typically called before - * schedule() or do_signal() when returning to userspace. We do it - * in C to avoid the burden of dealing with lockdep etc... - * - * NOTE: This is called with interrupts hard disabled but not marked - * as such in paca->irq_happened, so we need to resync this. - */ -void notrace restore_interrupts(void) -{ - if (irqs_disabled()) { - local_paca->irq_happened |= PACA_IRQ_HARD_DIS; - local_irq_enable(); - } else - __hard_irq_enable(); -} - -/* * This is a helper to use when about to go into idle low-power * when the latter has the side effect of re-enabling interrupts * (such as calling H_CEDE under pHyp). diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 6ab9b4d037c3..01ab2163659e 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -218,6 +218,7 @@ bool arch_kprobe_on_func_entry(unsigned long offset) void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) { ri->ret_addr = (kprobe_opcode_t *)regs->link; + ri->fp = NULL; /* Replace the return addr with trampoline addr */ regs->link = (unsigned long)kretprobe_trampoline; @@ -396,50 +397,9 @@ asm(".global kretprobe_trampoline\n" */ static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *tmp; - unsigned long flags, orig_ret_address = 0; - unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; - - INIT_HLIST_HEAD(&empty_rp); - kretprobe_hash_lock(current, &head, &flags); - - /* - * It is possible to have multiple instances associated with a given - * task either because an multiple functions in the call path - * have a return probe installed on them, and/or more than one return - * return probe was registered for a target function. - * - * We can handle this because: - * - instances are always inserted at the head of the list - * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the - * real return address, and all the rest will point to - * kretprobe_trampoline - */ - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - if (ri->rp && ri->rp->handler) - ri->rp->handler(ri, regs); - - orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_assert(ri, orig_ret_address, trampoline_address); + unsigned long orig_ret_address; + orig_ret_address = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); /* * We get here through one of two paths: * 1. by taking a trap -> kprobe_handler() -> here @@ -458,13 +418,6 @@ static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) regs->nip = orig_ret_address - 4; regs->link = orig_ret_address; - kretprobe_hash_unlock(current, &flags); - - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } - return 0; } NOKPROBE_SYMBOL(trampoline_probe_handler); diff --git a/arch/powerpc/kernel/l2cr_6xx.S b/arch/powerpc/kernel/l2cr_6xx.S index 5f07aa5e9851..225511d73bef 100644 --- a/arch/powerpc/kernel/l2cr_6xx.S +++ b/arch/powerpc/kernel/l2cr_6xx.S @@ -256,7 +256,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450) sync /* Restore MSR (restores EE and DR bits to original state) */ - SYNC mtmsr r7 isync @@ -377,7 +376,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_L3CR) 1: bdnz 1b /* Restore MSR (restores EE and DR bits to original state) */ -4: SYNC +4: mtmsr r7 isync blr diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c index ada59f6c4298..63702c0badb9 100644 --- a/arch/powerpc/kernel/mce.c +++ b/arch/powerpc/kernel/mce.c @@ -591,12 +591,11 @@ EXPORT_SYMBOL_GPL(machine_check_print_event_info); long notrace machine_check_early(struct pt_regs *regs) { long handled = 0; - bool nested = in_nmi(); u8 ftrace_enabled = this_cpu_get_ftrace_enabled(); this_cpu_set_ftrace_enabled(0); - - if (!nested) + /* Do not use nmi_enter/exit for pseries hpte guest */ + if (radix_enabled() || !firmware_has_feature(FW_FEATURE_LPAR)) nmi_enter(); hv_nmi_check_nonrecoverable(regs); @@ -607,7 +606,7 @@ long notrace machine_check_early(struct pt_regs *regs) if (ppc_md.machine_check_early) handled = ppc_md.machine_check_early(regs); - if (!nested) + if (radix_enabled() || !firmware_has_feature(FW_FEATURE_LPAR)) nmi_exit(); this_cpu_set_ftrace_enabled(ftrace_enabled); diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index b24f866fef81..717e658b90fd 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -215,19 +215,6 @@ _GLOBAL(low_choose_7447a_dfs) #endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_PPC_BOOK3S_32 */ -/* - * complement mask on the msr then "or" some values on. - * _nmask_and_or_msr(nmask, value_to_or) - */ -_GLOBAL(_nmask_and_or_msr) - mfmsr r0 /* Get current msr */ - andc r0,r0,r3 /* And off the bits set in r3 (first parm) */ - or r0,r0,r4 /* Or on the bits in r4 (second parm) */ - SYNC /* Some chip revs have problems here... */ - mtmsr r0 /* Update machine state */ - isync - blr /* Done */ - #ifdef CONFIG_40x /* @@ -268,41 +255,6 @@ _ASM_NOKPROBE_SYMBOL(real_writeb) #endif /* CONFIG_40x */ - -/* - * Flush instruction cache. - * This is a no-op on the 601. - */ -#ifndef CONFIG_PPC_8xx -_GLOBAL(flush_instruction_cache) -#if defined(CONFIG_4xx) - lis r3, KERNELBASE@h - iccci 0,r3 -#elif defined(CONFIG_FSL_BOOKE) -#ifdef CONFIG_E200 - mfspr r3,SPRN_L1CSR0 - ori r3,r3,L1CSR0_CFI|L1CSR0_CLFC - /* msync; isync recommended here */ - mtspr SPRN_L1CSR0,r3 - isync - blr -#endif - mfspr r3,SPRN_L1CSR1 - ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR - mtspr SPRN_L1CSR1,r3 -#elif defined(CONFIG_PPC_BOOK3S_601) - blr /* for 601, do nothing */ -#else - /* 603/604 processor - use invalidate-all bit in HID0 */ - mfspr r3,SPRN_HID0 - ori r3,r3,HID0_ICFI - mtspr SPRN_HID0,r3 -#endif /* CONFIG_4xx */ - isync - blr -EXPORT_SYMBOL(flush_instruction_cache) -#endif /* CONFIG_PPC_8xx */ - /* * Copy a whole page. We use the dcbz instruction on the destination * to reduce memory traffic (it eliminates the unnecessary reads of diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 7bb46ad98207..070465825c21 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -365,7 +365,6 @@ _GLOBAL(kexec_smp_wait) li r4,KEXEC_STATE_REAL_MODE stb r4,PACAKEXECSTATE(r13) - SYNC b kexec_wait diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 73a57043ee66..d421a2c7f822 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -124,10 +124,8 @@ unsigned long notrace msr_check_and_set(unsigned long bits) newmsr = oldmsr | bits; -#ifdef CONFIG_VSX if (cpu_has_feature(CPU_FTR_VSX) && (bits & MSR_FP)) newmsr |= MSR_VSX; -#endif if (oldmsr != newmsr) mtmsr_isync(newmsr); @@ -144,10 +142,8 @@ void notrace __msr_check_and_clear(unsigned long bits) newmsr = oldmsr & ~bits; -#ifdef CONFIG_VSX if (cpu_has_feature(CPU_FTR_VSX) && (bits & MSR_FP)) newmsr &= ~MSR_VSX; -#endif if (oldmsr != newmsr) mtmsr_isync(newmsr); @@ -162,10 +158,8 @@ static void __giveup_fpu(struct task_struct *tsk) save_fpu(tsk); msr = tsk->thread.regs->msr; msr &= ~(MSR_FP|MSR_FE0|MSR_FE1); -#ifdef CONFIG_VSX if (cpu_has_feature(CPU_FTR_VSX)) msr &= ~MSR_VSX; -#endif tsk->thread.regs->msr = msr; } @@ -235,6 +229,8 @@ void enable_kernel_fp(void) } } EXPORT_SYMBOL(enable_kernel_fp); +#else +static inline void __giveup_fpu(struct task_struct *tsk) { } #endif /* CONFIG_PPC_FPU */ #ifdef CONFIG_ALTIVEC @@ -245,10 +241,8 @@ static void __giveup_altivec(struct task_struct *tsk) save_altivec(tsk); msr = tsk->thread.regs->msr; msr &= ~MSR_VEC; -#ifdef CONFIG_VSX if (cpu_has_feature(CPU_FTR_VSX)) msr &= ~MSR_VSX; -#endif tsk->thread.regs->msr = msr; } @@ -414,21 +408,14 @@ static unsigned long msr_all_available; static int __init init_msr_all_available(void) { -#ifdef CONFIG_PPC_FPU - msr_all_available |= MSR_FP; -#endif -#ifdef CONFIG_ALTIVEC + if (IS_ENABLED(CONFIG_PPC_FPU)) + msr_all_available |= MSR_FP; if (cpu_has_feature(CPU_FTR_ALTIVEC)) msr_all_available |= MSR_VEC; -#endif -#ifdef CONFIG_VSX if (cpu_has_feature(CPU_FTR_VSX)) msr_all_available |= MSR_VSX; -#endif -#ifdef CONFIG_SPE if (cpu_has_feature(CPU_FTR_SPE)) msr_all_available |= MSR_SPE; -#endif return 0; } @@ -452,18 +439,12 @@ void giveup_all(struct task_struct *tsk) WARN_ON((usermsr & MSR_VSX) && !((usermsr & MSR_FP) && (usermsr & MSR_VEC))); -#ifdef CONFIG_PPC_FPU if (usermsr & MSR_FP) __giveup_fpu(tsk); -#endif -#ifdef CONFIG_ALTIVEC if (usermsr & MSR_VEC) __giveup_altivec(tsk); -#endif -#ifdef CONFIG_SPE if (usermsr & MSR_SPE) __giveup_spe(tsk); -#endif msr_check_and_clear(msr_all_available); } @@ -509,19 +490,18 @@ static bool should_restore_altivec(void) { return false; } static void do_restore_altivec(void) { } #endif /* CONFIG_ALTIVEC */ -#ifdef CONFIG_VSX static bool should_restore_vsx(void) { if (cpu_has_feature(CPU_FTR_VSX)) return true; return false; } +#ifdef CONFIG_VSX static void do_restore_vsx(void) { current->thread.used_vsr = 1; } #else -static bool should_restore_vsx(void) { return false; } static void do_restore_vsx(void) { } #endif /* CONFIG_VSX */ @@ -581,7 +561,7 @@ void notrace restore_math(struct pt_regs *regs) regs->msr |= new_msr | fpexc_mode; } } -#endif +#endif /* CONFIG_PPC_BOOK3S_64 */ static void save_all(struct task_struct *tsk) { @@ -642,6 +622,44 @@ void do_send_trap(struct pt_regs *regs, unsigned long address, (void __user *)address); } #else /* !CONFIG_PPC_ADV_DEBUG_REGS */ + +static void do_break_handler(struct pt_regs *regs) +{ + struct arch_hw_breakpoint null_brk = {0}; + struct arch_hw_breakpoint *info; + struct ppc_inst instr = ppc_inst(0); + int type = 0; + int size = 0; + unsigned long ea; + int i; + + /* + * If underneath hw supports only one watchpoint, we know it + * caused exception. 8xx also falls into this category. + */ + if (nr_wp_slots() == 1) { + __set_breakpoint(0, &null_brk); + current->thread.hw_brk[0] = null_brk; + current->thread.hw_brk[0].flags |= HW_BRK_FLAG_DISABLED; + return; + } + + /* Otherwise findout which DAWR caused exception and disable it. */ + wp_get_instr_detail(regs, &instr, &type, &size, &ea); + + for (i = 0; i < nr_wp_slots(); i++) { + info = ¤t->thread.hw_brk[i]; + if (!info->address) + continue; + + if (wp_check_constraints(regs, instr, ea, type, size, info)) { + __set_breakpoint(i, &null_brk); + current->thread.hw_brk[i] = null_brk; + current->thread.hw_brk[i].flags |= HW_BRK_FLAG_DISABLED; + } + } +} + void do_break (struct pt_regs *regs, unsigned long address, unsigned long error_code) { @@ -653,6 +671,16 @@ void do_break (struct pt_regs *regs, unsigned long address, if (debugger_break_match(regs)) return; + /* + * We reach here only when watchpoint exception is generated by ptrace + * event (or hw is buggy!). Now if CONFIG_HAVE_HW_BREAKPOINT is set, + * watchpoint is already handled by hw_breakpoint_handler() so we don't + * have to do anything. But when CONFIG_HAVE_HW_BREAKPOINT is not set, + * we need to manually handle the watchpoint here. + */ + if (!IS_ENABLED(CONFIG_HAVE_HW_BREAKPOINT)) + do_break_handler(regs); + /* Deliver the signal to userspace */ force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)address); } @@ -783,9 +811,8 @@ static void switch_hw_breakpoint(struct task_struct *new) static inline int __set_dabr(unsigned long dabr, unsigned long dabrx) { mtspr(SPRN_DAC1, dabr); -#ifdef CONFIG_PPC_47x - isync(); -#endif + if (IS_ENABLED(CONFIG_PPC_47x)) + isync(); return 0; } #elif defined(CONFIG_PPC_BOOK3S) @@ -1256,15 +1283,17 @@ struct task_struct *__switch_to(struct task_struct *prev, restore_math(current->thread.regs); /* - * The copy-paste buffer can only store into foreign real - * addresses, so unprivileged processes can not see the - * data or use it in any way unless they have foreign real - * mappings. If the new process has the foreign real address - * mappings, we must issue a cp_abort to clear any state and - * prevent snooping, corruption or a covert channel. + * On POWER9 the copy-paste buffer can only paste into + * foreign real addresses, so unprivileged processes can not + * see the data or use it in any way unless they have + * foreign real mappings. If the new process has the foreign + * real address mappings, we must issue a cp_abort to clear + * any state and prevent snooping, corruption or a covert + * channel. ISA v3.1 supports paste into local memory. */ if (current->mm && - atomic_read(¤t->mm->context.vas_windows)) + (cpu_has_feature(CPU_FTR_ARCH_31) || + atomic_read(¤t->mm->context.vas_windows))) asm volatile(PPC_CP_ABORT); } #endif /* CONFIG_PPC_BOOK3S_64 */ @@ -1453,12 +1482,13 @@ void show_regs(struct pt_regs * regs) trap = TRAP(regs); if (!trap_is_syscall(regs) && cpu_has_feature(CPU_FTR_CFAR)) pr_cont("CFAR: "REG" ", regs->orig_gpr3); - if (trap == 0x200 || trap == 0x300 || trap == 0x600) -#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) - pr_cont("DEAR: "REG" ESR: "REG" ", regs->dar, regs->dsisr); -#else - pr_cont("DAR: "REG" DSISR: %08lx ", regs->dar, regs->dsisr); -#endif + if (trap == 0x200 || trap == 0x300 || trap == 0x600) { + if (IS_ENABLED(CONFIG_4xx) || IS_ENABLED(CONFIG_BOOKE)) + pr_cont("DEAR: "REG" ESR: "REG" ", regs->dar, regs->dsisr); + else + pr_cont("DAR: "REG" DSISR: %08lx ", regs->dar, regs->dsisr); + } + #ifdef CONFIG_PPC64 pr_cont("IRQMASK: %lx ", regs->softe); #endif @@ -1475,14 +1505,14 @@ void show_regs(struct pt_regs * regs) break; } pr_cont("\n"); -#ifdef CONFIG_KALLSYMS /* * Lookup NIP late so we have the best change of getting the * above info out without failing */ - printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip); - printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link); -#endif + if (IS_ENABLED(CONFIG_KALLSYMS)) { + printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip); + printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link); + } show_stack(current, (unsigned long *) regs->gpr[1], KERN_DEFAULT); if (!user_mode(regs)) show_instructions(regs); @@ -1731,11 +1761,9 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) #ifdef CONFIG_PPC64 unsigned long load_addr = regs->gpr[2]; /* saved by ELF_PLAT_INIT */ -#ifdef CONFIG_PPC_BOOK3S_64 - if (!radix_enabled()) + if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !radix_enabled()) preload_new_slb_context(start, sp); #endif -#endif /* * If we exec out of a kernel thread then thread.regs will not be @@ -1866,7 +1894,6 @@ int set_fpexc_mode(struct task_struct *tsk, unsigned int val) * fpexc_mode. fpexc_mode is also used for setting FP exception * mode (asyn, precise, disabled) for 'Classic' FP. */ if (val & PR_FP_EXC_SW_ENABLE) { -#ifdef CONFIG_SPE if (cpu_has_feature(CPU_FTR_SPE)) { /* * When the sticky exception bits are set @@ -1880,16 +1907,15 @@ int set_fpexc_mode(struct task_struct *tsk, unsigned int val) * anyway to restore the prctl settings from * the saved environment. */ +#ifdef CONFIG_SPE tsk->thread.spefscr_last = mfspr(SPRN_SPEFSCR); tsk->thread.fpexc_mode = val & (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT); +#endif return 0; } else { return -EINVAL; } -#else - return -EINVAL; -#endif } /* on a CONFIG_SPE this does not hurt us. The bits that @@ -1908,10 +1934,9 @@ int set_fpexc_mode(struct task_struct *tsk, unsigned int val) int get_fpexc_mode(struct task_struct *tsk, unsigned long adr) { - unsigned int val; + unsigned int val = 0; - if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE) -#ifdef CONFIG_SPE + if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE) { if (cpu_has_feature(CPU_FTR_SPE)) { /* * When the sticky exception bits are set @@ -1925,15 +1950,15 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr) * anyway to restore the prctl settings from * the saved environment. */ +#ifdef CONFIG_SPE tsk->thread.spefscr_last = mfspr(SPRN_SPEFSCR); val = tsk->thread.fpexc_mode; +#endif } else return -EINVAL; -#else - return -EINVAL; -#endif - else + } else { val = __unpack_fe01(tsk->thread.fpexc_mode); + } return put_user(val, (unsigned int __user *) adr); } @@ -2102,10 +2127,8 @@ void show_stack(struct task_struct *tsk, unsigned long *stack, unsigned long sp, ip, lr, newsp; int count = 0; int firstframe = 1; -#ifdef CONFIG_FUNCTION_GRAPH_TRACER unsigned long ret_addr; int ftrace_idx = 0; -#endif if (tsk == NULL) tsk = current; @@ -2133,12 +2156,10 @@ void show_stack(struct task_struct *tsk, unsigned long *stack, if (!firstframe || ip != lr) { printk("%s["REG"] ["REG"] %pS", loglvl, sp, ip, (void *)ip); -#ifdef CONFIG_FUNCTION_GRAPH_TRACER ret_addr = ftrace_graph_ret_addr(current, &ftrace_idx, ip, stack); if (ret_addr != ip) pr_cont(" (%pS)", (void *)ret_addr); -#endif if (firstframe) pr_cont(" (unreliable)"); pr_cont("\n"); diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index d8a2fb87ba0c..c1545f22c077 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -776,6 +776,11 @@ void __init early_init_devtree(void *params) limit = ALIGN(memory_limit ?: memblock_phys_mem_size(), PAGE_SIZE); memblock_enforce_memory_limit(limit); +#if defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_PPC_4K_PAGES) + if (!early_radix_enabled()) + memblock_cap_memory_range(0, 1UL << (H_MAX_PHYSMEM_BITS)); +#endif + memblock_allow_resize(); memblock_dump_all(); diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index ae7ec9903191..38ae5933d917 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -45,7 +45,7 @@ #include <linux/linux_logo.h> /* All of prom_init bss lives here */ -#define __prombss __section(.bss.prominit) +#define __prombss __section(".bss.prominit") /* * Eventually bump that one up @@ -2422,10 +2422,19 @@ static void __init prom_check_displays(void) u32 width, height, pitch, addr; prom_printf("Setting btext !\n"); - prom_getprop(node, "width", &width, 4); - prom_getprop(node, "height", &height, 4); - prom_getprop(node, "linebytes", &pitch, 4); - prom_getprop(node, "address", &addr, 4); + + if (prom_getprop(node, "width", &width, 4) == PROM_ERROR) + return; + + if (prom_getprop(node, "height", &height, 4) == PROM_ERROR) + return; + + if (prom_getprop(node, "linebytes", &pitch, 4) == PROM_ERROR) + return; + + if (prom_getprop(node, "address", &addr, 4) == PROM_ERROR) + return; + prom_printf("W=%d H=%d LB=%d addr=0x%x\n", width, height, pitch, addr); btext_setup_display(width, height, 8, pitch, addr); diff --git a/arch/powerpc/kernel/ptrace/ptrace-noadv.c b/arch/powerpc/kernel/ptrace/ptrace-noadv.c index 697c7e4b5877..aa36fcad36cd 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-noadv.c +++ b/arch/powerpc/kernel/ptrace/ptrace-noadv.c @@ -57,6 +57,8 @@ void ppc_gethwdinfo(struct ppc_debug_info *dbginfo) } else { dbginfo->features = 0; } + if (cpu_has_feature(CPU_FTR_ARCH_31)) + dbginfo->features |= PPC_DEBUG_FEATURE_DATA_BP_ARCH_31; } int ptrace_get_debugreg(struct task_struct *child, unsigned long addr, @@ -217,8 +219,9 @@ long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_inf return -EIO; brk.address = ALIGN_DOWN(bp_info->addr, HW_BREAKPOINT_SIZE); - brk.type = HW_BRK_TYPE_TRANSLATE; + brk.type = HW_BRK_TYPE_TRANSLATE | HW_BRK_TYPE_PRIV_ALL; brk.len = DABR_MAX_LEN; + brk.hw_len = DABR_MAX_LEN; if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) brk.type |= HW_BRK_TYPE_READ; if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) @@ -286,11 +289,13 @@ long ppc_del_hwdebug(struct task_struct *child, long data) } return ret; #else /* CONFIG_HAVE_HW_BREAKPOINT */ - if (child->thread.hw_brk[data - 1].address == 0) + if (!(child->thread.hw_brk[data - 1].flags & HW_BRK_FLAG_DISABLED) && + child->thread.hw_brk[data - 1].address == 0) return -ENOENT; child->thread.hw_brk[data - 1].address = 0; child->thread.hw_brk[data - 1].type = 0; + child->thread.hw_brk[data - 1].flags = 0; #endif /* CONFIG_HAVE_HW_BREAKPOINT */ return 0; diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 806d554ce357..954f41676f69 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -992,6 +992,147 @@ struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log, return NULL; } +#ifdef CONFIG_PPC_RTAS_FILTER + +/* + * The sys_rtas syscall, as originally designed, allows root to pass + * arbitrary physical addresses to RTAS calls. A number of RTAS calls + * can be abused to write to arbitrary memory and do other things that + * are potentially harmful to system integrity, and thus should only + * be used inside the kernel and not exposed to userspace. + * + * All known legitimate users of the sys_rtas syscall will only ever + * pass addresses that fall within the RMO buffer, and use a known + * subset of RTAS calls. + * + * Accordingly, we filter RTAS requests to check that the call is + * permitted, and that provided pointers fall within the RMO buffer. + * The rtas_filters list contains an entry for each permitted call, + * with the indexes of the parameters which are expected to contain + * addresses and sizes of buffers allocated inside the RMO buffer. + */ +struct rtas_filter { + const char *name; + int token; + /* Indexes into the args buffer, -1 if not used */ + int buf_idx1; + int size_idx1; + int buf_idx2; + int size_idx2; + + int fixed_size; +}; + +static struct rtas_filter rtas_filters[] __ro_after_init = { + { "ibm,activate-firmware", -1, -1, -1, -1, -1 }, + { "ibm,configure-connector", -1, 0, -1, 1, -1, 4096 }, /* Special cased */ + { "display-character", -1, -1, -1, -1, -1 }, + { "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,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 }, + { "get-power-level", -1, -1, -1, -1, -1 }, + { "get-sensor-state", -1, -1, -1, -1, -1 }, + { "ibm,get-system-parameter", -1, 1, 2, -1, -1 }, + { "get-time-of-day", -1, -1, -1, -1, -1 }, + { "ibm,get-vpd", -1, 0, -1, 1, 2 }, + { "ibm,lpar-perftools", -1, 2, 3, -1, -1 }, + { "ibm,platform-dump", -1, 4, 5, -1, -1 }, + { "ibm,read-slot-reset-state", -1, -1, -1, -1, -1 }, + { "ibm,scan-log-dump", -1, 0, 1, -1, -1 }, + { "ibm,set-dynamic-indicator", -1, 2, -1, -1, -1 }, + { "ibm,set-eeh-option", -1, -1, -1, -1, -1 }, + { "set-indicator", -1, -1, -1, -1, -1 }, + { "set-power-level", -1, -1, -1, -1, -1 }, + { "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 }, + { "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 }, + { "ibm,physical-attestation", -1, 0, 1, -1, -1 }, +}; + +static bool in_rmo_buf(u32 base, u32 end) +{ + return base >= rtas_rmo_buf && + base < (rtas_rmo_buf + RTAS_RMOBUF_MAX) && + base <= end && + end >= rtas_rmo_buf && + end < (rtas_rmo_buf + RTAS_RMOBUF_MAX); +} + +static bool block_rtas_call(int token, int nargs, + struct rtas_args *args) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(rtas_filters); i++) { + struct rtas_filter *f = &rtas_filters[i]; + u32 base, size, end; + + if (token != f->token) + continue; + + if (f->buf_idx1 != -1) { + base = be32_to_cpu(args->args[f->buf_idx1]); + if (f->size_idx1 != -1) + size = be32_to_cpu(args->args[f->size_idx1]); + else if (f->fixed_size) + size = f->fixed_size; + else + size = 1; + + end = base + size - 1; + if (!in_rmo_buf(base, end)) + goto err; + } + + if (f->buf_idx2 != -1) { + base = be32_to_cpu(args->args[f->buf_idx2]); + if (f->size_idx2 != -1) + size = be32_to_cpu(args->args[f->size_idx2]); + else if (f->fixed_size) + size = f->fixed_size; + else + size = 1; + end = base + size - 1; + + /* + * Special case for ibm,configure-connector where the + * address can be 0 + */ + if (!strcmp(f->name, "ibm,configure-connector") && + base == 0) + return false; + + if (!in_rmo_buf(base, end)) + goto err; + } + + return false; + } + +err: + pr_err_ratelimited("sys_rtas: RTAS call blocked - exploit attempt?\n"); + pr_err_ratelimited("sys_rtas: token=0x%x, nargs=%d (called by %s)\n", + token, nargs, current->comm); + return true; +} + +#else + +static bool block_rtas_call(int token, int nargs, + struct rtas_args *args) +{ + return false; +} + +#endif /* CONFIG_PPC_RTAS_FILTER */ + /* We assume to be passed big endian arguments */ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs) { @@ -1029,6 +1170,9 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs) args.rets = &args.args[nargs]; memset(args.rets, 0, nret * sizeof(rtas_arg_t)); + if (block_rtas_call(token, nargs, &args)) + return -EINVAL; + /* Need to handle ibm,suspend_me call specially */ if (token == ibm_suspend_me_token) { @@ -1090,6 +1234,9 @@ void __init rtas_initialize(void) unsigned long rtas_region = RTAS_INSTANTIATE_MAX; u32 base, size, entry; int no_base, no_size, no_entry; +#ifdef CONFIG_PPC_RTAS_FILTER + int i; +#endif /* Get RTAS dev node and fill up our "rtas" structure with infos * about it. @@ -1129,6 +1276,12 @@ void __init rtas_initialize(void) #ifdef CONFIG_RTAS_ERROR_LOGGING rtas_last_error_token = rtas_token("rtas-last-error"); #endif + +#ifdef CONFIG_PPC_RTAS_FILTER + for (i = 0; i < ARRAY_SIZE(rtas_filters); i++) { + rtas_filters[i].token = rtas_token(rtas_filters[i].name); + } +#endif } int __init early_init_dt_scan_rtas(unsigned long node, diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c index c9876aab3142..e4e1a94ccf6a 100644 --- a/arch/powerpc/kernel/security.c +++ b/arch/powerpc/kernel/security.c @@ -430,30 +430,44 @@ device_initcall(stf_barrier_debugfs_init); static void update_branch_cache_flush(void) { + u32 *site; + #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE + site = &patch__call_kvm_flush_link_stack; // This controls the branch from guest_exit_cont to kvm_flush_link_stack if (link_stack_flush_type == BRANCH_CACHE_FLUSH_NONE) { - patch_instruction_site(&patch__call_kvm_flush_link_stack, - ppc_inst(PPC_INST_NOP)); + patch_instruction_site(site, ppc_inst(PPC_INST_NOP)); } else { // Could use HW flush, but that could also flush count cache - patch_branch_site(&patch__call_kvm_flush_link_stack, - (u64)&kvm_flush_link_stack, BRANCH_SET_LINK); + patch_branch_site(site, (u64)&kvm_flush_link_stack, BRANCH_SET_LINK); } #endif + // Patch out the bcctr first, then nop the rest + site = &patch__call_flush_branch_caches3; + patch_instruction_site(site, ppc_inst(PPC_INST_NOP)); + site = &patch__call_flush_branch_caches2; + patch_instruction_site(site, ppc_inst(PPC_INST_NOP)); + site = &patch__call_flush_branch_caches1; + patch_instruction_site(site, ppc_inst(PPC_INST_NOP)); + // This controls the branch from _switch to flush_branch_caches if (count_cache_flush_type == BRANCH_CACHE_FLUSH_NONE && link_stack_flush_type == BRANCH_CACHE_FLUSH_NONE) { - patch_instruction_site(&patch__call_flush_branch_caches, - ppc_inst(PPC_INST_NOP)); + // Nothing to be done + } else if (count_cache_flush_type == BRANCH_CACHE_FLUSH_HW && link_stack_flush_type == BRANCH_CACHE_FLUSH_HW) { - patch_instruction_site(&patch__call_flush_branch_caches, - ppc_inst(PPC_INST_BCCTR_FLUSH)); + // Patch in the bcctr last + site = &patch__call_flush_branch_caches1; + patch_instruction_site(site, ppc_inst(0x39207fff)); // li r9,0x7fff + site = &patch__call_flush_branch_caches2; + patch_instruction_site(site, ppc_inst(0x7d2903a6)); // mtctr r9 + site = &patch__call_flush_branch_caches3; + patch_instruction_site(site, ppc_inst(PPC_INST_BCCTR_FLUSH)); + } else { - patch_branch_site(&patch__call_flush_branch_caches, - (u64)&flush_branch_caches, BRANCH_SET_LINK); + patch_branch_site(site, (u64)&flush_branch_caches, BRANCH_SET_LINK); // If we just need to flush the link stack, early return if (count_cache_flush_type == BRANCH_CACHE_FLUSH_NONE) { diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 1823706ae076..057d6b8e9bb0 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -223,6 +223,6 @@ __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_PPC_BOOK3S_601) || IS_ENABLED(CONFIG_E200)) + 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 6be430107c6f..bb9cab3641d7 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -66,6 +66,7 @@ #include <asm/feature-fixups.h> #include <asm/kup.h> #include <asm/early_ioremap.h> +#include <asm/pgalloc.h> #include "setup.h" @@ -756,17 +757,46 @@ void __init emergency_stack_init(void) } #ifdef CONFIG_SMP -#define PCPU_DYN_SIZE () - -static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align) +/** + * pcpu_alloc_bootmem - NUMA friendly alloc_bootmem wrapper for percpu + * @cpu: cpu to allocate for + * @size: size allocation in bytes + * @align: alignment + * + * Allocate @size bytes aligned at @align for cpu @cpu. This wrapper + * does the right thing for NUMA regardless of the current + * configuration. + * + * RETURNS: + * Pointer to the allocated area on success, NULL on failure. + */ +static void * __init pcpu_alloc_bootmem(unsigned int cpu, size_t size, + size_t align) { - return memblock_alloc_try_nid(size, align, __pa(MAX_DMA_ADDRESS), - MEMBLOCK_ALLOC_ACCESSIBLE, - early_cpu_to_node(cpu)); + const unsigned long goal = __pa(MAX_DMA_ADDRESS); +#ifdef CONFIG_NEED_MULTIPLE_NODES + int node = early_cpu_to_node(cpu); + void *ptr; + if (!node_online(node) || !NODE_DATA(node)) { + ptr = memblock_alloc_from(size, align, goal); + pr_info("cpu %d has no node %d or node-local memory\n", + cpu, node); + pr_debug("per cpu data for cpu%d %lu bytes at %016lx\n", + cpu, size, __pa(ptr)); + } else { + ptr = memblock_alloc_try_nid(size, align, goal, + MEMBLOCK_ALLOC_ACCESSIBLE, node); + pr_debug("per cpu data for cpu%d %lu bytes on node%d at " + "%016lx\n", cpu, size, node, __pa(ptr)); + } + return ptr; +#else + return memblock_alloc_from(size, align, goal); +#endif } -static void __init pcpu_fc_free(void *ptr, size_t size) +static void __init pcpu_free_bootmem(void *ptr, size_t size) { memblock_free(__pa(ptr), size); } @@ -782,13 +812,58 @@ static int pcpu_cpu_distance(unsigned int from, unsigned int to) unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; EXPORT_SYMBOL(__per_cpu_offset); +static void __init pcpu_populate_pte(unsigned long addr) +{ + pgd_t *pgd = pgd_offset_k(addr); + p4d_t *p4d; + pud_t *pud; + pmd_t *pmd; + + p4d = p4d_offset(pgd, addr); + if (p4d_none(*p4d)) { + pud_t *new; + + new = memblock_alloc(PUD_TABLE_SIZE, PUD_TABLE_SIZE); + if (!new) + goto err_alloc; + p4d_populate(&init_mm, p4d, new); + } + + pud = pud_offset(p4d, addr); + if (pud_none(*pud)) { + pmd_t *new; + + new = memblock_alloc(PMD_TABLE_SIZE, PMD_TABLE_SIZE); + if (!new) + goto err_alloc; + pud_populate(&init_mm, pud, new); + } + + pmd = pmd_offset(pud, addr); + if (!pmd_present(*pmd)) { + pte_t *new; + + new = memblock_alloc(PTE_TABLE_SIZE, PTE_TABLE_SIZE); + if (!new) + goto err_alloc; + pmd_populate_kernel(&init_mm, pmd, new); + } + + return; + +err_alloc: + panic("%s: Failed to allocate %lu bytes align=%lx from=%lx\n", + __func__, PAGE_SIZE, PAGE_SIZE, PAGE_SIZE); +} + + void __init setup_per_cpu_areas(void) { const size_t dyn_size = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE; size_t atom_size; unsigned long delta; unsigned int cpu; - int rc; + int rc = -EINVAL; /* * Linear mapping is one of 4K, 1M and 16M. For 4K, no need @@ -800,8 +875,18 @@ void __init setup_per_cpu_areas(void) else atom_size = 1 << 20; - rc = pcpu_embed_first_chunk(0, dyn_size, atom_size, pcpu_cpu_distance, - pcpu_fc_alloc, pcpu_fc_free); + if (pcpu_chosen_fc != PCPU_FC_PAGE) { + rc = pcpu_embed_first_chunk(0, dyn_size, atom_size, pcpu_cpu_distance, + pcpu_alloc_bootmem, pcpu_free_bootmem); + if (rc) + pr_warn("PERCPU: %s allocator failed (%d), " + "falling back to page size\n", + pcpu_fc_names[pcpu_chosen_fc], rc); + } + + if (rc < 0) + rc = pcpu_page_first_chunk(0, pcpu_alloc_bootmem, pcpu_free_bootmem, + pcpu_populate_pte); if (rc < 0) panic("cannot initialize percpu area (err=%d)", rc); diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index d15a98c758b8..d2c356f37077 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -312,9 +312,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) { user_exit(); - /* Check valid addr_limit, TIF check is done there */ - addr_limit_user_check(); - if (thread_info_flags & _TIF_UPROBE) uprobe_notify_resume(regs); @@ -327,7 +324,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) } if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); rseq_handle_notify_resume(NULL, regs); } diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 8261999c7d52..3c6b9822f978 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -75,17 +75,28 @@ static DEFINE_PER_CPU(int, cpu_state) = { 0 }; struct task_struct *secondary_current; bool has_big_cores; +bool coregroup_enabled; DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); DEFINE_PER_CPU(cpumask_var_t, cpu_smallcore_map); DEFINE_PER_CPU(cpumask_var_t, cpu_l2_cache_map); DEFINE_PER_CPU(cpumask_var_t, cpu_core_map); +DEFINE_PER_CPU(cpumask_var_t, cpu_coregroup_map); EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); EXPORT_PER_CPU_SYMBOL(cpu_l2_cache_map); EXPORT_PER_CPU_SYMBOL(cpu_core_map); EXPORT_SYMBOL_GPL(has_big_cores); +enum { +#ifdef CONFIG_SCHED_SMT + smt_idx, +#endif + cache_idx, + mc_idx, + die_idx, +}; + #define MAX_THREAD_LIST_SIZE 8 #define THREAD_GROUP_SHARE_L1 1 struct thread_groups { @@ -660,6 +671,28 @@ static void set_cpus_unrelated(int i, int j, #endif /* + * Extends set_cpus_related. Instead of setting one CPU at a time in + * dstmask, set srcmask at oneshot. dstmask should be super set of srcmask. + */ +static void or_cpumasks_related(int i, int j, struct cpumask *(*srcmask)(int), + struct cpumask *(*dstmask)(int)) +{ + struct cpumask *mask; + int k; + + mask = srcmask(j); + for_each_cpu(k, srcmask(i)) + cpumask_or(dstmask(k), dstmask(k), mask); + + if (i == j) + return; + + mask = srcmask(i); + for_each_cpu(k, srcmask(j)) + cpumask_or(dstmask(k), dstmask(k), mask); +} + +/* * 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 @@ -789,10 +822,6 @@ static int init_cpu_l1_cache_map(int cpu) if (err) goto out; - zalloc_cpumask_var_node(&per_cpu(cpu_l1_cache_map, cpu), - GFP_KERNEL, - cpu_to_node(cpu)); - cpu_group_start = get_cpu_thread_group_start(cpu, &tg); if (unlikely(cpu_group_start == -1)) { @@ -801,6 +830,9 @@ static int init_cpu_l1_cache_map(int cpu) goto out; } + zalloc_cpumask_var_node(&per_cpu(cpu_l1_cache_map, cpu), + 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); @@ -819,6 +851,74 @@ out: return err; } +static bool shared_caches; + +#ifdef CONFIG_SCHED_SMT +/* cpumask of CPUs with asymmetric SMT dependency */ +static int powerpc_smt_flags(void) +{ + int flags = SD_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES; + + if (cpu_has_feature(CPU_FTR_ASYM_SMT)) { + printk_once(KERN_INFO "Enabling Asymmetric SMT scheduling\n"); + flags |= SD_ASYM_PACKING; + } + return flags; +} +#endif + +/* + * P9 has a slightly odd architecture where pairs of cores share an L2 cache. + * This topology makes it *much* cheaper to migrate tasks between adjacent cores + * since the migrated task remains cache hot. We want to take advantage of this + * at the scheduler level so an extra topology level is required. + */ +static int powerpc_shared_cache_flags(void) +{ + return SD_SHARE_PKG_RESOURCES; +} + +/* + * We can't just pass cpu_l2_cache_mask() directly because + * returns a non-const pointer and the compiler barfs on that. + */ +static const struct cpumask *shared_cache_mask(int cpu) +{ + return per_cpu(cpu_l2_cache_map, cpu); +} + +#ifdef CONFIG_SCHED_SMT +static const struct cpumask *smallcore_smt_mask(int cpu) +{ + return cpu_smallcore_mask(cpu); +} +#endif + +static struct cpumask *cpu_coregroup_mask(int cpu) +{ + return per_cpu(cpu_coregroup_map, cpu); +} + +static bool has_coregroup_support(void) +{ + return coregroup_enabled; +} + +static const struct cpumask *cpu_mc_mask(int cpu) +{ + return cpu_coregroup_mask(cpu); +} + +static struct sched_domain_topology_level powerpc_topology[] = { +#ifdef CONFIG_SCHED_SMT + { cpu_smt_mask, powerpc_smt_flags, SD_INIT_NAME(SMT) }, +#endif + { shared_cache_mask, powerpc_shared_cache_flags, SD_INIT_NAME(CACHE) }, + { cpu_mc_mask, SD_INIT_NAME(MC) }, + { cpu_cpu_mask, SD_INIT_NAME(DIE) }, + { NULL, }, +}; + static int init_big_cores(void) { int cpu; @@ -861,6 +961,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) GFP_KERNEL, cpu_to_node(cpu)); zalloc_cpumask_var_node(&per_cpu(cpu_core_map, cpu), GFP_KERNEL, cpu_to_node(cpu)); + if (has_coregroup_support()) + zalloc_cpumask_var_node(&per_cpu(cpu_coregroup_map, cpu), + GFP_KERNEL, cpu_to_node(cpu)); + +#ifdef CONFIG_NEED_MULTIPLE_NODES /* * numa_node_id() works after this. */ @@ -869,12 +974,21 @@ void __init smp_prepare_cpus(unsigned int max_cpus) set_cpu_numa_mem(cpu, local_memory_node(numa_cpu_lookup_table[cpu])); } +#endif + /* + * cpu_core_map is now more updated and exists only since + * its been exported for long. It only will have a snapshot + * of cpu_cpu_mask. + */ + cpumask_copy(per_cpu(cpu_core_map, cpu), cpu_cpu_mask(cpu)); } /* Init the cpumasks so the boot CPU is related to itself */ cpumask_set_cpu(boot_cpuid, cpu_sibling_mask(boot_cpuid)); cpumask_set_cpu(boot_cpuid, cpu_l2_cache_mask(boot_cpuid)); - cpumask_set_cpu(boot_cpuid, cpu_core_mask(boot_cpuid)); + + if (has_coregroup_support()) + cpumask_set_cpu(boot_cpuid, cpu_coregroup_mask(boot_cpuid)); init_big_cores(); if (has_big_cores) { @@ -1126,26 +1240,46 @@ static struct device_node *cpu_to_l2cache(int cpu) return cache; } -static bool update_mask_by_l2(int cpu, struct cpumask *(*mask_fn)(int)) +static bool update_mask_by_l2(int cpu, cpumask_var_t *mask) { + struct cpumask *(*submask_fn)(int) = cpu_sibling_mask; struct device_node *l2_cache, *np; int i; + if (has_big_cores) + submask_fn = cpu_smallcore_mask; + l2_cache = cpu_to_l2cache(cpu); - if (!l2_cache) + if (!l2_cache || !*mask) { + /* Assume only core siblings share cache with this CPU */ + for_each_cpu(i, submask_fn(cpu)) + set_cpus_related(cpu, i, cpu_l2_cache_mask); + return false; + } + + cpumask_and(*mask, cpu_online_mask, cpu_cpu_mask(cpu)); + + /* Update l2-cache mask with all the CPUs that are part of submask */ + or_cpumasks_related(cpu, cpu, submask_fn, cpu_l2_cache_mask); - for_each_cpu(i, cpu_online_mask) { + /* Skip all CPUs already part of current CPU l2-cache mask */ + cpumask_andnot(*mask, *mask, cpu_l2_cache_mask(cpu)); + + for_each_cpu(i, *mask) { /* * when updating the marks the current CPU has not been marked * online, but we need to update the cache masks */ np = cpu_to_l2cache(i); - if (!np) - continue; - if (np == l2_cache) - set_cpus_related(cpu, i, mask_fn); + /* Skip all CPUs already part of current CPU l2-cache */ + if (np == l2_cache) { + or_cpumasks_related(cpu, i, submask_fn, cpu_l2_cache_mask); + cpumask_andnot(*mask, *mask, submask_fn(i)); + } else { + cpumask_andnot(*mask, *mask, cpu_l2_cache_mask(i)); + } of_node_put(np); } @@ -1157,59 +1291,81 @@ static bool update_mask_by_l2(int cpu, struct cpumask *(*mask_fn)(int)) #ifdef CONFIG_HOTPLUG_CPU static void remove_cpu_from_masks(int cpu) { + struct cpumask *(*mask_fn)(int) = cpu_sibling_mask; int i; - /* NB: cpu_core_mask is a superset of the others */ - for_each_cpu(i, cpu_core_mask(cpu)) { - set_cpus_unrelated(cpu, i, cpu_core_mask); + if (shared_caches) + mask_fn = cpu_l2_cache_mask; + + for_each_cpu(i, mask_fn(cpu)) { set_cpus_unrelated(cpu, i, cpu_l2_cache_mask); set_cpus_unrelated(cpu, i, cpu_sibling_mask); if (has_big_cores) set_cpus_unrelated(cpu, i, cpu_smallcore_mask); } + + if (has_coregroup_support()) { + for_each_cpu(i, cpu_coregroup_mask(cpu)) + set_cpus_unrelated(cpu, i, cpu_coregroup_mask); + } } #endif static inline void add_cpu_to_smallcore_masks(int cpu) { - struct cpumask *this_l1_cache_map = per_cpu(cpu_l1_cache_map, cpu); - int i, first_thread = cpu_first_thread_sibling(cpu); + int i; if (!has_big_cores) return; cpumask_set_cpu(cpu, cpu_smallcore_mask(cpu)); - for (i = first_thread; i < first_thread + threads_per_core; i++) { - if (cpu_online(i) && cpumask_test_cpu(i, this_l1_cache_map)) + for_each_cpu(i, per_cpu(cpu_l1_cache_map, cpu)) { + if (cpu_online(i)) set_cpus_related(i, cpu, cpu_smallcore_mask); } } -int get_physical_package_id(int cpu) +static void update_coregroup_mask(int cpu, cpumask_var_t *mask) { - int pkg_id = cpu_to_chip_id(cpu); + struct cpumask *(*submask_fn)(int) = cpu_sibling_mask; + int coregroup_id = cpu_to_coregroup_id(cpu); + int i; - /* - * If the platform is PowerNV or Guest on KVM, ibm,chip-id is - * defined. Hence we would return the chip-id as the result of - * get_physical_package_id. - */ - if (pkg_id == -1 && firmware_has_feature(FW_FEATURE_LPAR) && - IS_ENABLED(CONFIG_PPC_SPLPAR)) { - struct device_node *np = of_get_cpu_node(cpu, NULL); - pkg_id = of_node_to_nid(np); - of_node_put(np); + if (shared_caches) + submask_fn = cpu_l2_cache_mask; + + if (!*mask) { + /* Assume only siblings are part of this CPU's coregroup */ + for_each_cpu(i, submask_fn(cpu)) + set_cpus_related(cpu, i, cpu_coregroup_mask); + + return; } - return pkg_id; + cpumask_and(*mask, cpu_online_mask, cpu_cpu_mask(cpu)); + + /* Update coregroup mask with all the CPUs that are part of submask */ + or_cpumasks_related(cpu, cpu, submask_fn, cpu_coregroup_mask); + + /* Skip all CPUs already part of coregroup mask */ + cpumask_andnot(*mask, *mask, cpu_coregroup_mask(cpu)); + + for_each_cpu(i, *mask) { + /* Skip all CPUs not part of this coregroup */ + if (coregroup_id == cpu_to_coregroup_id(i)) { + or_cpumasks_related(cpu, i, submask_fn, cpu_coregroup_mask); + cpumask_andnot(*mask, *mask, submask_fn(i)); + } else { + cpumask_andnot(*mask, *mask, cpu_coregroup_mask(i)); + } + } } -EXPORT_SYMBOL_GPL(get_physical_package_id); static void add_cpu_to_masks(int cpu) { int first_thread = cpu_first_thread_sibling(cpu); - int pkg_id = get_physical_package_id(cpu); + cpumask_var_t mask; int i; /* @@ -1223,36 +1379,21 @@ static void add_cpu_to_masks(int cpu) set_cpus_related(i, cpu, cpu_sibling_mask); add_cpu_to_smallcore_masks(cpu); - /* - * Copy the thread sibling mask into the cache sibling mask - * and mark any CPUs that share an L2 with this CPU. - */ - for_each_cpu(i, cpu_sibling_mask(cpu)) - set_cpus_related(cpu, i, cpu_l2_cache_mask); - update_mask_by_l2(cpu, cpu_l2_cache_mask); - /* - * Copy the cache sibling mask into core sibling mask and mark - * any CPUs on the same chip as this CPU. - */ - for_each_cpu(i, cpu_l2_cache_mask(cpu)) - set_cpus_related(cpu, i, cpu_core_mask); + /* In CPU-hotplug path, hence use GFP_ATOMIC */ + alloc_cpumask_var_node(&mask, GFP_ATOMIC, cpu_to_node(cpu)); + update_mask_by_l2(cpu, &mask); - if (pkg_id == -1) - return; + if (has_coregroup_support()) + update_coregroup_mask(cpu, &mask); - for_each_cpu(i, cpu_online_mask) - if (get_physical_package_id(i) == pkg_id) - set_cpus_related(cpu, i, cpu_core_mask); + free_cpumask_var(mask); } -static bool shared_caches; - /* Activate a secondary processor. */ void start_secondary(void *unused) { unsigned int cpu = smp_processor_id(); - struct cpumask *(*sibling_mask)(int) = cpu_sibling_mask; mmgrab(&init_mm); current->active_mm = &init_mm; @@ -1278,14 +1419,20 @@ void start_secondary(void *unused) /* Update topology CPU masks */ add_cpu_to_masks(cpu); - if (has_big_cores) - sibling_mask = cpu_smallcore_mask; /* * Check for any shared caches. Note that this must be done on a * per-core basis because one core in the pair might be disabled. */ - if (!cpumask_equal(cpu_l2_cache_mask(cpu), sibling_mask(cpu))) - shared_caches = true; + if (!shared_caches) { + struct cpumask *(*sibling_mask)(int) = cpu_sibling_mask; + struct cpumask *mask = cpu_l2_cache_mask(cpu); + + if (has_big_cores) + sibling_mask = cpu_smallcore_mask; + + if (cpumask_weight(mask) > cpumask_weight(sibling_mask(cpu))) + shared_caches = true; + } set_numa_node(numa_cpu_lookup_table[cpu]); set_numa_mem(local_memory_node(numa_cpu_lookup_table[cpu])); @@ -1311,63 +1458,44 @@ int setup_profiling_timer(unsigned int multiplier) return 0; } -#ifdef CONFIG_SCHED_SMT -/* cpumask of CPUs with asymetric SMT dependancy */ -static int powerpc_smt_flags(void) +static void fixup_topology(void) { - int flags = SD_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES; + int i; - if (cpu_has_feature(CPU_FTR_ASYM_SMT)) { - printk_once(KERN_INFO "Enabling Asymmetric SMT scheduling\n"); - flags |= SD_ASYM_PACKING; +#ifdef CONFIG_SCHED_SMT + if (has_big_cores) { + pr_info("Big cores detected but using small core scheduling\n"); + powerpc_topology[smt_idx].mask = smallcore_smt_mask; } - return flags; -} #endif -static struct sched_domain_topology_level powerpc_topology[] = { -#ifdef CONFIG_SCHED_SMT - { cpu_smt_mask, powerpc_smt_flags, SD_INIT_NAME(SMT) }, -#endif - { cpu_cpu_mask, SD_INIT_NAME(DIE) }, - { NULL, }, -}; + if (!has_coregroup_support()) + powerpc_topology[mc_idx].mask = powerpc_topology[cache_idx].mask; -/* - * P9 has a slightly odd architecture where pairs of cores share an L2 cache. - * This topology makes it *much* cheaper to migrate tasks between adjacent cores - * since the migrated task remains cache hot. We want to take advantage of this - * at the scheduler level so an extra topology level is required. - */ -static int powerpc_shared_cache_flags(void) -{ - return SD_SHARE_PKG_RESOURCES; -} + /* + * Try to consolidate topology levels here instead of + * allowing scheduler to degenerate. + * - Dont consolidate if masks are different. + * - Dont consolidate if sd_flags exists and are different. + */ + for (i = 1; i <= die_idx; i++) { + if (powerpc_topology[i].mask != powerpc_topology[i - 1].mask) + continue; -/* - * We can't just pass cpu_l2_cache_mask() directly because - * returns a non-const pointer and the compiler barfs on that. - */ -static const struct cpumask *shared_cache_mask(int cpu) -{ - return cpu_l2_cache_mask(cpu); -} + if (powerpc_topology[i].sd_flags && powerpc_topology[i - 1].sd_flags && + powerpc_topology[i].sd_flags != powerpc_topology[i - 1].sd_flags) + continue; -#ifdef CONFIG_SCHED_SMT -static const struct cpumask *smallcore_smt_mask(int cpu) -{ - return cpu_smallcore_mask(cpu); -} -#endif + if (!powerpc_topology[i - 1].sd_flags) + powerpc_topology[i - 1].sd_flags = powerpc_topology[i].sd_flags; -static struct sched_domain_topology_level power9_topology[] = { -#ifdef CONFIG_SCHED_SMT - { cpu_smt_mask, powerpc_smt_flags, SD_INIT_NAME(SMT) }, + powerpc_topology[i].mask = powerpc_topology[i + 1].mask; + powerpc_topology[i].sd_flags = powerpc_topology[i + 1].sd_flags; +#ifdef CONFIG_SCHED_DEBUG + powerpc_topology[i].name = powerpc_topology[i + 1].name; #endif - { shared_cache_mask, powerpc_shared_cache_flags, SD_INIT_NAME(CACHE) }, - { cpu_cpu_mask, SD_INIT_NAME(DIE) }, - { NULL, }, -}; + } +} void __init smp_cpus_done(unsigned int max_cpus) { @@ -1382,24 +1510,8 @@ void __init smp_cpus_done(unsigned int max_cpus) dump_numa_cpu_topology(); -#ifdef CONFIG_SCHED_SMT - if (has_big_cores) { - pr_info("Big cores detected but using small core scheduling\n"); - power9_topology[0].mask = smallcore_smt_mask; - powerpc_topology[0].mask = smallcore_smt_mask; - } -#endif - /* - * If any CPU detects that it's sharing a cache with another CPU then - * use the deeper topology that is aware of this sharing. - */ - if (shared_caches) { - pr_info("Using shared cache scheduler topology\n"); - set_sched_topology(power9_topology); - } else { - pr_info("Using standard scheduler topology\n"); - set_sched_topology(powerpc_topology); - } + fixup_topology(); + set_sched_topology(powerpc_topology); } #ifdef CONFIG_HOTPLUG_CPU @@ -1429,16 +1541,18 @@ void __cpu_die(unsigned int cpu) smp_ops->cpu_die(cpu); } -void cpu_die(void) +void arch_cpu_idle_dead(void) { + sched_preempt_enable_no_resched(); + /* * Disable on the down path. This will be re-enabled by * start_secondary() via start_secondary_resume() below */ this_cpu_disable_ftrace(); - if (ppc_md.cpu_die) - ppc_md.cpu_die(); + if (smp_ops->cpu_offline_self) + smp_ops->cpu_offline_self(); /* If we return, we re-enter start_secondary */ start_secondary_resume(); diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl index c2d737ff2e7b..1275daec7fec 100644 --- a/arch/powerpc/kernel/syscalls/syscall.tbl +++ b/arch/powerpc/kernel/syscalls/syscall.tbl @@ -34,7 +34,7 @@ 18 spu oldstat sys_ni_syscall 19 common lseek sys_lseek compat_sys_lseek 20 common getpid sys_getpid -21 nospu mount sys_mount compat_sys_mount +21 nospu mount sys_mount 22 32 umount sys_oldumount 22 64 umount sys_ni_syscall 22 spu umount sys_ni_syscall @@ -193,8 +193,8 @@ 142 common _newselect sys_select compat_sys_select 143 common flock sys_flock 144 common msync sys_msync -145 common readv sys_readv compat_sys_readv -146 common writev sys_writev compat_sys_writev +145 common readv sys_readv +146 common writev sys_writev 147 common getsid sys_getsid 148 common fdatasync sys_fdatasync 149 nospu _sysctl sys_ni_syscall @@ -369,7 +369,7 @@ 282 common unshare sys_unshare 283 common splice sys_splice 284 common tee sys_tee -285 common vmsplice sys_vmsplice compat_sys_vmsplice +285 common vmsplice sys_vmsplice 286 common openat sys_openat compat_sys_openat 287 common mkdirat sys_mkdirat 288 common mknodat sys_mknodat @@ -449,8 +449,8 @@ 348 common syncfs sys_syncfs 349 common sendmmsg sys_sendmmsg compat_sys_sendmmsg 350 common setns sys_setns -351 nospu process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv -352 nospu process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev +351 nospu process_vm_readv sys_process_vm_readv +352 nospu process_vm_writev sys_process_vm_writev 353 nospu finit_module sys_finit_module 354 nospu kcmp sys_kcmp 355 common sched_setattr sys_sched_setattr @@ -529,3 +529,4 @@ 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 +440 common process_madvise sys_process_madvise diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 46b4ebc33db7..2e08640bb3b4 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -32,29 +32,27 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); -/* - * SMT snooze delay stuff, 64-bit only for now - */ - #ifdef CONFIG_PPC64 -/* Time in microseconds we delay before sleeping in the idle loop */ -static DEFINE_PER_CPU(long, smt_snooze_delay) = { 100 }; +/* + * Snooze delay has not been hooked up since 3fa8cad82b94 ("powerpc/pseries/cpuidle: + * smt-snooze-delay cleanup.") and has been broken even longer. As was foretold in + * 2014: + * + * "ppc64_util currently utilises it. Once we fix ppc64_util, propose to clean + * up the kernel code." + * + * powerpc-utils stopped using it as of 1.3.8. At some point in the future this + * code should be removed. + */ static ssize_t store_smt_snooze_delay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct cpu *cpu = container_of(dev, struct cpu, dev); - ssize_t ret; - long snooze; - - ret = sscanf(buf, "%ld", &snooze); - if (ret != 1) - return -EINVAL; - - per_cpu(smt_snooze_delay, cpu->dev.id) = snooze; + pr_warn_once("%s (%d) stored to unsupported smt_snooze_delay, which has no effect.\n", + current->comm, current->pid); return count; } @@ -62,9 +60,9 @@ static ssize_t show_smt_snooze_delay(struct device *dev, struct device_attribute *attr, char *buf) { - struct cpu *cpu = container_of(dev, struct cpu, dev); - - return sprintf(buf, "%ld\n", per_cpu(smt_snooze_delay, cpu->dev.id)); + pr_warn_once("%s (%d) read from unsupported smt_snooze_delay\n", + current->comm, current->pid); + return sprintf(buf, "100\n"); } static DEVICE_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay, @@ -72,16 +70,10 @@ static DEVICE_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay, static int __init setup_smt_snooze_delay(char *str) { - unsigned int cpu; - long snooze; - if (!cpu_has_feature(CPU_FTR_SMT)) return 1; - snooze = simple_strtol(str, NULL, 10); - for_each_possible_cpu(cpu) - per_cpu(smt_snooze_delay, cpu) = snooze; - + pr_warn("smt-snooze-delay command line option has no effect\n"); return 1; } __setup("smt-snooze-delay=", setup_smt_snooze_delay); @@ -225,14 +217,13 @@ static DEVICE_ATTR(dscr_default, 0600, static void sysfs_create_dscr_default(void) { if (cpu_has_feature(CPU_FTR_DSCR)) { - int err = 0; int cpu; dscr_default = spr_default_dscr; for_each_possible_cpu(cpu) paca_ptrs[cpu]->dscr_default = dscr_default; - err = device_create_file(cpu_subsys.dev_root, &dev_attr_dscr_default); + device_create_file(cpu_subsys.dev_root, &dev_attr_dscr_default); } } #endif /* CONFIG_PPC64 */ @@ -1168,6 +1159,7 @@ static int __init topology_init(void) for_each_possible_cpu(cpu) { struct cpu *c = &per_cpu(cpu_devices, cpu); +#ifdef CONFIG_HOTPLUG_CPU /* * For now, we just see if the system supports making * the RTAS calls for CPU hotplug. But, there may be a @@ -1175,8 +1167,9 @@ static int __init topology_init(void) * CPU. For instance, the boot cpu might never be valid * for hotplugging. */ - if (ppc_md.cpu_die) + if (smp_ops->cpu_offline_self) c->hotpluggable = 1; +#endif if (cpu_online(cpu) || c->hotpluggable) { register_cpu(c, cpu); diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c index e2ab8a111b69..0b4694b8d248 100644 --- a/arch/powerpc/kernel/tau_6xx.c +++ b/arch/powerpc/kernel/tau_6xx.c @@ -13,13 +13,14 @@ */ #include <linux/errno.h> -#include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/string.h> #include <linux/mm.h> #include <linux/interrupt.h> #include <linux/init.h> +#include <linux/delay.h> +#include <linux/workqueue.h> #include <asm/io.h> #include <asm/reg.h> @@ -39,9 +40,7 @@ static struct tau_temp unsigned char grew; } tau[NR_CPUS]; -struct timer_list tau_timer; - -#undef DEBUG +static bool tau_int_enable; /* TODO: put these in a /proc interface, with some sanity checks, and maybe * dynamic adjustment to minimize # of interrupts */ @@ -50,72 +49,49 @@ struct timer_list tau_timer; #define step_size 2 /* step size when temp goes out of range */ #define window_expand 1 /* expand the window by this much */ /* configurable values for shrinking the window */ -#define shrink_timer 2*HZ /* period between shrinking the window */ +#define shrink_timer 2000 /* period between shrinking the window */ #define min_window 2 /* minimum window size, degrees C */ static void set_thresholds(unsigned long cpu) { -#ifdef CONFIG_TAU_INT - /* - * setup THRM1, - * threshold, valid bit, enable interrupts, interrupt when below threshold - */ - mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TIE | THRM1_TID); + u32 maybe_tie = tau_int_enable ? THRM1_TIE : 0; - /* setup THRM2, - * threshold, valid bit, enable interrupts, interrupt when above threshold - */ - mtspr (SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V | THRM1_TIE); -#else - /* same thing but don't enable interrupts */ - mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TID); - mtspr(SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V); -#endif + /* setup THRM1, threshold, valid bit, interrupt when below threshold */ + mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | maybe_tie | THRM1_TID); + + /* setup THRM2, threshold, valid bit, interrupt when above threshold */ + mtspr(SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V | maybe_tie); } static void TAUupdate(int cpu) { - unsigned thrm; - -#ifdef DEBUG - printk("TAUupdate "); -#endif + u32 thrm; + u32 bits = THRM1_TIV | THRM1_TIN | THRM1_V; /* if both thresholds are crossed, the step_sizes cancel out * and the window winds up getting expanded twice. */ - if((thrm = mfspr(SPRN_THRM1)) & THRM1_TIV){ /* is valid? */ - if(thrm & THRM1_TIN){ /* crossed low threshold */ - if (tau[cpu].low >= step_size){ - tau[cpu].low -= step_size; - tau[cpu].high -= (step_size - window_expand); - } - tau[cpu].grew = 1; -#ifdef DEBUG - printk("low threshold crossed "); -#endif + thrm = mfspr(SPRN_THRM1); + if ((thrm & bits) == bits) { + mtspr(SPRN_THRM1, 0); + + if (tau[cpu].low >= step_size) { + tau[cpu].low -= step_size; + tau[cpu].high -= (step_size - window_expand); } + tau[cpu].grew = 1; + pr_debug("%s: low threshold crossed\n", __func__); } - if((thrm = mfspr(SPRN_THRM2)) & THRM1_TIV){ /* is valid? */ - if(thrm & THRM1_TIN){ /* crossed high threshold */ - if (tau[cpu].high <= 127-step_size){ - tau[cpu].low += (step_size - window_expand); - tau[cpu].high += step_size; - } - tau[cpu].grew = 1; -#ifdef DEBUG - printk("high threshold crossed "); -#endif + thrm = mfspr(SPRN_THRM2); + if ((thrm & bits) == bits) { + mtspr(SPRN_THRM2, 0); + + if (tau[cpu].high <= 127 - step_size) { + tau[cpu].low += (step_size - window_expand); + tau[cpu].high += step_size; } + tau[cpu].grew = 1; + pr_debug("%s: high threshold crossed\n", __func__); } - -#ifdef DEBUG - printk("grew = %d\n", tau[cpu].grew); -#endif - -#ifndef CONFIG_TAU_INT /* tau_timeout will do this if not using interrupts */ - set_thresholds(cpu); -#endif - } #ifdef CONFIG_TAU_INT @@ -140,17 +116,16 @@ void TAUException(struct pt_regs * regs) static void tau_timeout(void * info) { int cpu; - unsigned long flags; int size; int shrink; - /* disabling interrupts *should* be okay */ - local_irq_save(flags); cpu = smp_processor_id(); -#ifndef CONFIG_TAU_INT - TAUupdate(cpu); -#endif + if (!tau_int_enable) + TAUupdate(cpu); + + /* Stop thermal sensor comparisons and interrupts */ + mtspr(SPRN_THRM3, 0); size = tau[cpu].high - tau[cpu].low; if (size > min_window && ! tau[cpu].grew) { @@ -173,32 +148,26 @@ static void tau_timeout(void * info) set_thresholds(cpu); - /* - * Do the enable every time, since otherwise a bunch of (relatively) - * complex sleep code needs to be added. One mtspr every time - * tau_timeout is called is probably not a big deal. - * - * Enable thermal sensor and set up sample interval timer - * need 20 us to do the compare.. until a nice 'cpu_speed' function - * call is implemented, just assume a 500 mhz clock. It doesn't really - * matter if we take too long for a compare since it's all interrupt - * driven anyway. - * - * use a extra long time.. (60 us @ 500 mhz) + /* Restart thermal sensor comparisons and interrupts. + * The "PowerPC 740 and PowerPC 750 Microprocessor Datasheet" + * recommends that "the maximum value be set in THRM3 under all + * conditions." */ - mtspr(SPRN_THRM3, THRM3_SITV(500*60) | THRM3_E); - - local_irq_restore(flags); + mtspr(SPRN_THRM3, THRM3_SITV(0x1fff) | THRM3_E); } -static void tau_timeout_smp(struct timer_list *unused) -{ +static struct workqueue_struct *tau_workq; - /* schedule ourselves to be run again */ - mod_timer(&tau_timer, jiffies + shrink_timer) ; +static void tau_work_func(struct work_struct *work) +{ + msleep(shrink_timer); on_each_cpu(tau_timeout, NULL, 0); + /* schedule ourselves to be run again */ + queue_work(tau_workq, work); } +DECLARE_WORK(tau_work, tau_work_func); + /* * setup the TAU * @@ -231,21 +200,19 @@ static int __init TAU_init(void) return 1; } + tau_int_enable = IS_ENABLED(CONFIG_TAU_INT) && + !strcmp(cur_cpu_spec->platform, "ppc750"); - /* first, set up the window shrinking timer */ - timer_setup(&tau_timer, tau_timeout_smp, 0); - tau_timer.expires = jiffies + shrink_timer; - add_timer(&tau_timer); + tau_workq = alloc_workqueue("tau", WQ_UNBOUND, 1, 0); + if (!tau_workq) + return -ENOMEM; on_each_cpu(TAU_init_smp, NULL, 0); - printk("Thermal assist unit "); -#ifdef CONFIG_TAU_INT - printk("using interrupts, "); -#else - printk("using timers, "); -#endif - printk("shrink_timer: %d jiffies\n", shrink_timer); + queue_work(tau_workq, &tau_work); + + pr_info("Thermal assist unit using %s, shrink_timer: %d ms\n", + tau_int_enable ? "interrupts" : "workqueue", shrink_timer); tau_initialized = 1; return 0; diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index f85539ebb513..74efe46f5532 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -75,15 +75,6 @@ #include <linux/clockchips.h> #include <linux/timekeeper_internal.h> -static u64 rtc_read(struct clocksource *); -static struct clocksource clocksource_rtc = { - .name = "rtc", - .rating = 400, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, - .mask = CLOCKSOURCE_MASK(64), - .read = rtc_read, -}; - static u64 timebase_read(struct clocksource *); static struct clocksource clocksource_timebase = { .name = "timebase", @@ -447,19 +438,9 @@ void vtime_flush(struct task_struct *tsk) void __delay(unsigned long loops) { unsigned long start; - int diff; spin_begin(); - if (__USE_RTC()) { - start = get_rtcl(); - do { - /* the RTCL register wraps at 1000000000 */ - diff = get_rtcl() - start; - if (diff < 0) - diff += 1000000000; - spin_cpu_relax(); - } while (diff < loops); - } else if (tb_invalid) { + if (tb_invalid) { /* * TB is in error state and isn't ticking anymore. * HMI handler was unable to recover from TB error. @@ -467,8 +448,8 @@ void __delay(unsigned long loops) */ spin_cpu_relax(); } else { - start = get_tbl(); - while (get_tbl() - start < loops) + start = mftb(); + while (mftb() - start < loops) spin_cpu_relax(); } spin_end(); @@ -614,7 +595,7 @@ void timer_interrupt(struct pt_regs *regs) irq_work_run(); } - now = get_tb_or_rtc(); + now = get_tb(); if (now >= *next_tb) { *next_tb = ~(u64)0; if (evt->event_handler) @@ -696,8 +677,6 @@ EXPORT_SYMBOL_GPL(tb_to_ns); */ notrace unsigned long long sched_clock(void) { - if (__USE_RTC()) - return get_rtc(); return mulhdu(get_tb() - boot_tb, tb_to_ns_scale) << tb_to_ns_shift; } @@ -847,11 +826,6 @@ void read_persistent_clock64(struct timespec64 *ts) } /* clocksource code */ -static notrace u64 rtc_read(struct clocksource *cs) -{ - return (u64)get_rtc(); -} - static notrace u64 timebase_read(struct clocksource *cs) { return (u64)get_tb(); @@ -948,12 +922,7 @@ void update_vsyscall_tz(void) static void __init clocksource_init(void) { - struct clocksource *clock; - - if (__USE_RTC()) - clock = &clocksource_rtc; - else - clock = &clocksource_timebase; + struct clocksource *clock = &clocksource_timebase; if (clocksource_register_hz(clock, tb_ticks_per_sec)) { printk(KERN_ERR "clocksource: %s is already registered\n", @@ -968,7 +937,7 @@ static void __init clocksource_init(void) static int decrementer_set_next_event(unsigned long evt, struct clock_event_device *dev) { - __this_cpu_write(decrementers_next_tb, get_tb_or_rtc() + evt); + __this_cpu_write(decrementers_next_tb, get_tb() + evt); set_dec(evt); /* We may have raced with new irq work */ @@ -1071,17 +1040,12 @@ void __init time_init(void) u64 scale; unsigned shift; - if (__USE_RTC()) { - /* 601 processor: dec counts down by 128 every 128ns */ - ppc_tb_freq = 1000000000; - } else { - /* Normal PowerPC with timebase register */ - ppc_md.calibrate_decr(); - printk(KERN_DEBUG "time_init: decrementer frequency = %lu.%.6lu MHz\n", - ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); - printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n", - ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); - } + /* Normal PowerPC with timebase register */ + ppc_md.calibrate_decr(); + printk(KERN_DEBUG "time_init: decrementer frequency = %lu.%.6lu MHz\n", + ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); + printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n", + ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); tb_ticks_per_jiffy = ppc_tb_freq / HZ; tb_ticks_per_sec = ppc_tb_freq; @@ -1107,7 +1071,7 @@ void __init time_init(void) tb_to_ns_scale = scale; tb_to_ns_shift = shift; /* Save the current timebase to pretty up CONFIG_PRINTK_TIME */ - boot_tb = get_tb_or_rtc(); + boot_tb = get_tb(); /* If platform provided a timezone (pmac), we correct the time */ if (timezone_offset) { diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S index 6ba0fdd1e7f8..2b91f233b05d 100644 --- a/arch/powerpc/kernel/tm.S +++ b/arch/powerpc/kernel/tm.S @@ -122,6 +122,13 @@ _GLOBAL(tm_reclaim) std r3, STK_PARAM(R3)(r1) SAVE_NVGPRS(r1) + /* + * Save kernel live AMR since it will be clobbered by treclaim + * but can be used elsewhere later in kernel space. + */ + mfspr r3, SPRN_AMR + std r3, TM_FRAME_L1(r1) + /* We need to setup MSR for VSX register save instructions. */ mfmsr r14 mr r15, r14 @@ -245,7 +252,7 @@ _GLOBAL(tm_reclaim) * but is used in signal return to 'wind back' to the abort handler. */ - /* ******************** CR,LR,CCR,MSR ********** */ + /* ***************** CTR, LR, CR, XER ********** */ mfctr r3 mflr r4 mfcr r5 @@ -256,7 +263,6 @@ _GLOBAL(tm_reclaim) std r5, _CCR(r7) std r6, _XER(r7) - /* ******************** TAR, DSCR ********** */ mfspr r3, SPRN_TAR mfspr r4, SPRN_DSCR @@ -264,6 +270,10 @@ _GLOBAL(tm_reclaim) std r3, THREAD_TM_TAR(r12) std r4, THREAD_TM_DSCR(r12) + /* ******************** AMR **************** */ + mfspr r3, SPRN_AMR + std r3, THREAD_TM_AMR(r12) + /* * MSR and flags: We don't change CRs, and we don't need to alter MSR. */ @@ -308,7 +318,9 @@ _GLOBAL(tm_reclaim) std r3, THREAD_TM_TFHAR(r12) std r4, THREAD_TM_TFIAR(r12) - /* AMR is checkpointed too, but is unsupported by Linux. */ + /* Restore kernel live AMR */ + ld r8, TM_FRAME_L1(r1) + mtspr SPRN_AMR, r8 /* Restore original MSR/IRQ state & clear TM mode */ ld r14, TM_FRAME_L0(r1) /* Orig MSR */ @@ -355,6 +367,13 @@ _GLOBAL(__tm_recheckpoint) */ SAVE_NVGPRS(r1) + /* + * Save kernel live AMR since it will be clobbered for trechkpt + * but can be used elsewhere later in kernel space. + */ + mfspr r8, SPRN_AMR + std r8, TM_FRAME_L0(r1) + /* Load complete register state from ts_ckpt* registers */ addi r7, r3, PT_CKPT_REGS /* Thread's ckpt_regs */ @@ -404,7 +423,7 @@ _GLOBAL(__tm_recheckpoint) restore_gprs: - /* ******************** CR,LR,CCR,MSR ********** */ + /* ****************** CTR, LR, XER ************* */ ld r4, _CTR(r7) ld r5, _LINK(r7) ld r8, _XER(r7) @@ -417,6 +436,10 @@ restore_gprs: ld r4, THREAD_TM_TAR(r3) mtspr SPRN_TAR, r4 + /* ******************** AMR ******************** */ + ld r4, THREAD_TM_AMR(r3) + mtspr SPRN_AMR, r4 + /* Load up the PPR and DSCR in GPRs only at this stage */ ld r5, THREAD_TM_DSCR(r3) ld r6, THREAD_TM_PPR(r3) @@ -509,6 +532,10 @@ restore_gprs: li r4, MSR_RI mtmsrd r4, 1 + /* Restore kernel live AMR */ + ld r8, TM_FRAME_L0(r1) + mtspr SPRN_AMR, r8 + REST_NVGPRS(r1) addi r1, r1, TM_FRAME_SIZE diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index d1ebe152f210..5006dcbe1d9f 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -529,9 +529,6 @@ out: * Check if the NIP corresponds to the address of a sync * instruction for which there is an entry in the exception * table. - * Note that the 601 only takes a machine check on TEA - * (transfer error ack) signal assertion, and does not - * set any of the top 16 bits of SRR1. * -- paulus. */ static inline int check_io_access(struct pt_regs *regs) @@ -796,7 +793,6 @@ int machine_check_generic(struct pt_regs *regs) case 0x80000: pr_cont("Machine check signal\n"); break; - case 0: /* for 601 */ case 0x40000: case 0x140000: /* 7450 MSS error and TEA */ pr_cont("Transfer error ack signal\n"); @@ -889,7 +885,7 @@ static void p9_hmi_special_emu(struct pt_regs *regs) { unsigned int ra, rb, t, i, sel, instr, rc; const void __user *addr; - u8 vbuf[16], *vdst; + u8 vbuf[16] __aligned(16), *vdst; unsigned long ea, msr, msr_mask; bool swap; diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile index 87ab1152d5ce..73eada6bc8cd 100644 --- a/arch/powerpc/kernel/vdso32/Makefile +++ b/arch/powerpc/kernel/vdso32/Makefile @@ -29,7 +29,7 @@ ccflags-y := -shared -fno-common -fno-builtin -nostdlib \ asflags-y := -D__VDSO32__ -s obj-y += vdso32_wrapper.o -extra-y += vdso32.lds +targets += vdso32.lds CPPFLAGS_vdso32.lds += -P -C -Upowerpc # Force dependency (incbin is bad) @@ -50,7 +50,7 @@ $(obj-vdso32): %.o: %.S FORCE # actual build commands quiet_cmd_vdso32ld = VDSO32L $@ - cmd_vdso32ld = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ $(call cc-ldoption, -Wl$(comma)--orphan-handling=warn) -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) + cmd_vdso32ld = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) quiet_cmd_vdso32as = VDSO32A $@ cmd_vdso32as = $(VDSOCC) $(a_flags) $(CC32FLAGS) -c -o $@ $< diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S index 217bb630f8f9..1d23e2771dba 100644 --- a/arch/powerpc/kernel/vdso32/datapage.S +++ b/arch/powerpc/kernel/vdso32/datapage.S @@ -47,7 +47,6 @@ V_FUNCTION_END(__kernel_get_syscall_map) * * returns the timebase frequency in HZ */ -#ifndef CONFIG_PPC_BOOK3S_601 V_FUNCTION_BEGIN(__kernel_get_tbfreq) .cfi_startproc mflr r12 @@ -60,4 +59,3 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq) blr .cfi_endproc V_FUNCTION_END(__kernel_get_tbfreq) -#endif diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S index 4c985467a668..7eadac74c7f9 100644 --- a/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S @@ -111,7 +111,6 @@ SECTIONS *(.note.GNU-stack) *(.data .data.* .gnu.linkonce.d.* .sdata*) *(.bss .sbss .dynbss .dynsbss) - *(.glink .iplt .plt .rela*) } } @@ -145,13 +144,11 @@ VERSION __kernel_datapage_offset; __kernel_get_syscall_map; -#ifndef CONFIG_PPC_BOOK3S_601 __kernel_gettimeofday; __kernel_clock_gettime; __kernel_clock_getres; __kernel_time; __kernel_get_tbfreq; -#endif __kernel_sync_dicache; __kernel_sync_dicache_p5; __kernel_sigtramp32; diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile index 38c317f25141..dfd34f68bfa1 100644 --- a/arch/powerpc/kernel/vdso64/Makefile +++ b/arch/powerpc/kernel/vdso64/Makefile @@ -17,7 +17,7 @@ ccflags-y := -shared -fno-common -fno-builtin -nostdlib \ asflags-y := -D__VDSO64__ -s obj-y += vdso64_wrapper.o -extra-y += vdso64.lds +targets += vdso64.lds CPPFLAGS_vdso64.lds += -P -C -U$(ARCH) # Force dependency (incbin is bad) @@ -34,7 +34,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE # actual build commands quiet_cmd_vdso64ld = VDSO64L $@ - cmd_vdso64ld = $(CC) $(c_flags) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) $(call cc-ldoption, -Wl$(comma)--orphan-handling=warn) + cmd_vdso64ld = $(CC) $(c_flags) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) # install commands for the unstripped file quiet_cmd_vdso_install = INSTALL $@ diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index 4e3a8d4ee614..256fb9720298 100644 --- a/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S @@ -30,7 +30,7 @@ SECTIONS . = ALIGN(16); .text : { *(.text .stub .text.* .gnu.linkonce.t.* __ftr_alt_*) - *(.sfpr) + *(.sfpr .glink) } :text PROVIDE(__etext = .); PROVIDE(_etext = .); @@ -111,7 +111,6 @@ SECTIONS *(.branch_lt) *(.data .data.* .gnu.linkonce.d.* .sdata*) *(.bss .sbss .dynbss .dynsbss) - *(.glink .iplt .plt .rela*) } } diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 326e113d2e45..e0548b4950de 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -360,8 +360,8 @@ SECTIONS PROVIDE32 (end = .); STABS_DEBUG - DWARF_DEBUG + ELF_DETAILS DISCARDS /DISCARD/ : { diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c index 53bb71e3a2e1..c69bcf9b547a 100644 --- a/arch/powerpc/kexec/file_load_64.c +++ b/arch/powerpc/kexec/file_load_64.c @@ -138,15 +138,13 @@ out: */ static int get_crash_memory_ranges(struct crash_mem **mem_ranges) { - struct memblock_region *reg; + phys_addr_t base, end; struct crash_mem *tmem; + u64 i; int ret; - for_each_memblock(memory, reg) { - u64 base, size; - - base = (u64)reg->base; - size = (u64)reg->size; + for_each_mem_range(i, &base, &end) { + u64 size = end - base; /* Skip backup memory region, which needs a separate entry */ if (base == BACKUP_SRC_START) { @@ -250,8 +248,7 @@ static int __locate_mem_hole_top_down(struct kexec_buf *kbuf, phys_addr_t start, end; u64 i; - for_each_mem_range_rev(i, &memblock.memory, NULL, NUMA_NO_NODE, - MEMBLOCK_NONE, &start, &end, NULL) { + for_each_mem_range_rev(i, &start, &end) { /* * memblock uses [start, end) convention while it is * [start, end] here. Fix the off-by-one to have the @@ -350,8 +347,7 @@ static int __locate_mem_hole_bottom_up(struct kexec_buf *kbuf, phys_addr_t start, end; u64 i; - for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE, - MEMBLOCK_NONE, &start, &end, NULL) { + for_each_mem_range(i, &start, &end) { /* * memblock uses [start, end) convention while it is * [start, end] here. Fix the off-by-one to have the diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 49db50d1db04..44bf567b6589 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -558,12 +558,12 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { - return -ENOTSUPP; + return -EOPNOTSUPP; } int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { - return -ENOTSUPP; + return -EOPNOTSUPP; } int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, @@ -879,13 +879,15 @@ void kvmppc_core_destroy_vm(struct kvm *kvm) #ifdef CONFIG_KVM_XICS /* - * Free the XIVE devices which are not directly freed by the + * Free the XIVE and XICS devices which are not directly freed by the * device 'release' method */ kfree(kvm->arch.xive_devices.native); kvm->arch.xive_devices.native = NULL; kfree(kvm->arch.xive_devices.xics_on_xive); kvm->arch.xive_devices.xics_on_xive = NULL; + kfree(kvm->arch.xics_device); + kvm->arch.xics_device = NULL; #endif /* CONFIG_KVM_XICS */ } diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index 22a677b18695..bb35490400e9 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -347,7 +347,7 @@ static unsigned long kvmppc_radix_update_pte(struct kvm *kvm, pte_t *ptep, return __radix_pte_update(ptep, clr, set); } -void kvmppc_radix_set_pte_at(struct kvm *kvm, unsigned long addr, +static void kvmppc_radix_set_pte_at(struct kvm *kvm, unsigned long addr, pte_t *ptep, pte_t pte) { radix__set_pte_at(kvm->mm, addr, ptep, pte, 0); diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index 1a529df0ab44..8da93fdfa59e 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c @@ -283,7 +283,7 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, struct kvmppc_spapr_tce_table *siter; struct mm_struct *mm = kvm->mm; unsigned long npages, size = args->size; - int ret = -ENOMEM; + int ret; if (!args->size || args->page_shift < 12 || args->page_shift > 34 || (args->offset + args->size > (ULLONG_MAX >> args->page_shift))) @@ -489,7 +489,7 @@ static long kvmppc_tce_iommu_unmap(struct kvm *kvm, return ret; } -long kvmppc_tce_iommu_do_map(struct kvm *kvm, struct iommu_table *tbl, +static long kvmppc_tce_iommu_do_map(struct kvm *kvm, struct iommu_table *tbl, unsigned long entry, unsigned long ua, enum dma_data_direction dir) { diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c index ac6ac192b8bb..083a4e037718 100644 --- a/arch/powerpc/kvm/book3s_64_vio_hv.c +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c @@ -32,7 +32,7 @@ #ifdef CONFIG_BUG #define WARN_ON_ONCE_RM(condition) ({ \ - static bool __section(.data.unlikely) __warned; \ + static bool __section(".data.unlikely") __warned; \ int __ret_warn_once = !!(condition); \ \ if (unlikely(__ret_warn_once && !__warned)) { \ @@ -237,7 +237,7 @@ static long iommu_tce_xchg_no_kill_rm(struct mm_struct *mm, return ret; } -extern void iommu_tce_kill_rm(struct iommu_table *tbl, +static void iommu_tce_kill_rm(struct iommu_table *tbl, unsigned long entry, unsigned long pages) { if (tbl->it_ops->tce_kill) diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 4ba06a2a306c..e3b1839fc251 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -111,7 +111,7 @@ module_param(one_vm_per_core, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(one_vm_per_core, "Only run vCPUs from the same VM on a core (requires indep_threads_mode=N)"); #ifdef CONFIG_KVM_XICS -static struct kernel_param_ops module_param_ops = { +static const struct kernel_param_ops module_param_ops = { .set = param_set_int, .get = param_get_int, }; @@ -3442,9 +3442,19 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long host_psscr = mfspr(SPRN_PSSCR); unsigned long host_pidr = mfspr(SPRN_PID); + /* + * P8 and P9 suppress the HDEC exception when LPCR[HDICE] = 0, + * so set HDICE before writing HDEC. + */ + mtspr(SPRN_LPCR, vcpu->kvm->arch.host_lpcr | LPCR_HDICE); + isync(); + hdec = time_limit - mftb(); - if (hdec < 0) + if (hdec < 0) { + mtspr(SPRN_LPCR, vcpu->kvm->arch.host_lpcr); + isync(); return BOOK3S_INTERRUPT_HV_DECREMENTER; + } mtspr(SPRN_HDEC, hdec); if (vc->tb_offset) { @@ -3530,6 +3540,13 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit, */ asm volatile("eieio; tlbsync; ptesync"); + /* + * cp_abort is required if the processor supports local copy-paste + * to clear the copy buffer that was under control of the guest. + */ + if (cpu_has_feature(CPU_FTR_ARCH_31)) + asm volatile(PPC_CP_ABORT); + mtspr(SPRN_LPID, vcpu->kvm->arch.host_lpid); /* restore host LPID */ isync(); @@ -3558,7 +3575,7 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit, * Virtual-mode guest entry for POWER9 and later when the host and * guest are both using the radix MMU. The LPIDR has already been set. */ -int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, +static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpcr) { struct kvmppc_vcore *vc = vcpu->arch.vcore; @@ -3572,7 +3589,7 @@ int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, dec = mfspr(SPRN_DEC); tb = mftb(); - if (dec < 512) + if (dec < 0) return BOOK3S_INTERRUPT_HV_DECREMENTER; local_paca->kvm_hstate.dec_expires = dec + tb; if (local_paca->kvm_hstate.dec_expires < time_limit) @@ -5250,6 +5267,12 @@ static long kvm_arch_vm_ioctl_hv(struct file *filp, case KVM_PPC_ALLOCATE_HTAB: { u32 htab_order; + /* If we're a nested hypervisor, we currently only support radix */ + if (kvmhv_on_pseries()) { + r = -EOPNOTSUPP; + break; + } + r = -EFAULT; if (get_user(htab_order, (u32 __user *)argp)) break; diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 073617ce83e0..8f58dd20b362 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -95,23 +95,15 @@ EXPORT_SYMBOL_GPL(kvm_free_hpt_cma); void __init kvm_cma_reserve(void) { unsigned long align_size; - struct memblock_region *reg; - phys_addr_t selected_size = 0; + phys_addr_t selected_size; /* * We need CMA reservation only when we are in HV mode */ if (!cpu_has_feature(CPU_FTR_HVMODE)) return; - /* - * We cannot use memblock_phys_mem_size() here, because - * memblock_analyze() has not been called yet. - */ - for_each_memblock(memory, reg) - selected_size += memblock_region_memory_end_pfn(reg) - - memblock_region_memory_base_pfn(reg); - selected_size = (selected_size * kvm_cma_resv_ratio / 100) << PAGE_SHIFT; + selected_size = PAGE_ALIGN(memblock_phys_mem_size() * kvm_cma_resv_ratio / 100); if (selected_size) { pr_info("%s: reserving %ld MiB for global area\n", __func__, (unsigned long)selected_size / SZ_1M); diff --git a/arch/powerpc/kvm/book3s_hv_interrupts.S b/arch/powerpc/kvm/book3s_hv_interrupts.S index 59822cba454d..327417d79eac 100644 --- a/arch/powerpc/kvm/book3s_hv_interrupts.S +++ b/arch/powerpc/kvm/book3s_hv_interrupts.S @@ -58,13 +58,16 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) /* * Put whatever is in the decrementer into the * hypervisor decrementer. + * Because of a hardware deviation in P8 and P9, + * we need to set LPCR[HDICE] before writing HDEC. */ -BEGIN_FTR_SECTION ld r5, HSTATE_KVM_VCORE(r13) ld r6, VCORE_KVM(r5) ld r9, KVM_HOST_LPCR(r6) - andis. r9, r9, LPCR_LD@h -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) + ori r8, r9, LPCR_HDICE + mtspr SPRN_LPCR, r8 + isync + andis. r0, r9, LPCR_LD@h mfspr r8,SPRN_DEC mftb r7 BEGIN_FTR_SECTION diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c index 6822d23a2da4..33b58549a9aa 100644 --- a/arch/powerpc/kvm/book3s_hv_nested.c +++ b/arch/powerpc/kvm/book3s_hv_nested.c @@ -569,7 +569,7 @@ static void kvmhv_update_ptbl_cache(struct kvm_nested_guest *gp) kvmhv_set_nested_ptbl(gp); } -struct kvm_nested_guest *kvmhv_alloc_nested(struct kvm *kvm, unsigned int lpid) +static struct kvm_nested_guest *kvmhv_alloc_nested(struct kvm *kvm, unsigned int lpid) { struct kvm_nested_guest *gp; long shadow_lpid; diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c index 4d7e5610731a..c2c9c733f359 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_xics.c +++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c @@ -764,7 +764,7 @@ int xics_rm_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr) return ics_rm_eoi(vcpu, irq); } -unsigned long eoi_rc; +static unsigned long eoi_rc; static void icp_eoi(struct irq_chip *c, u32 hwirq, __be32 xirr, bool *again) { diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 799d6d0f4ead..cd9995ee8441 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -1831,6 +1831,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_P9_RADIX_PREFETCH_BUG) #endif /* CONFIG_PPC_RADIX_MMU */ /* + * cp_abort is required if the processor supports local copy-paste + * to clear the copy buffer that was under control of the guest. + */ +BEGIN_FTR_SECTION + PPC_CP_ABORT +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_31) + + /* * POWER7/POWER8 guest -> host partition switch code. * We don't have to lock against tlbies but we do * have to coordinate the hardware threads. diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c b/arch/powerpc/kvm/book3s_hv_uvmem.c index 7705d5557239..84e5a2dc8be5 100644 --- a/arch/powerpc/kvm/book3s_hv_uvmem.c +++ b/arch/powerpc/kvm/book3s_hv_uvmem.c @@ -687,9 +687,9 @@ static struct page *kvmppc_uvmem_get_page(unsigned long gpa, struct kvm *kvm) struct kvmppc_uvmem_page_pvt *pvt; unsigned long pfn_last, pfn_first; - pfn_first = kvmppc_uvmem_pgmap.res.start >> PAGE_SHIFT; + pfn_first = kvmppc_uvmem_pgmap.range.start >> PAGE_SHIFT; pfn_last = pfn_first + - (resource_size(&kvmppc_uvmem_pgmap.res) >> PAGE_SHIFT); + (range_len(&kvmppc_uvmem_pgmap.range) >> PAGE_SHIFT); spin_lock(&kvmppc_uvmem_bitmap_lock); bit = find_first_zero_bit(kvmppc_uvmem_bitmap, @@ -1007,7 +1007,7 @@ static vm_fault_t kvmppc_uvmem_migrate_to_ram(struct vm_fault *vmf) static void kvmppc_uvmem_page_free(struct page *page) { unsigned long pfn = page_to_pfn(page) - - (kvmppc_uvmem_pgmap.res.start >> PAGE_SHIFT); + (kvmppc_uvmem_pgmap.range.start >> PAGE_SHIFT); struct kvmppc_uvmem_page_pvt *pvt; spin_lock(&kvmppc_uvmem_bitmap_lock); @@ -1170,7 +1170,9 @@ int kvmppc_uvmem_init(void) } kvmppc_uvmem_pgmap.type = MEMORY_DEVICE_PRIVATE; - kvmppc_uvmem_pgmap.res = *res; + kvmppc_uvmem_pgmap.range.start = res->start; + kvmppc_uvmem_pgmap.range.end = res->end; + kvmppc_uvmem_pgmap.nr_range = 1; kvmppc_uvmem_pgmap.ops = &kvmppc_uvmem_ops; /* just one global instance: */ kvmppc_uvmem_pgmap.owner = &kvmppc_uvmem_pgmap; @@ -1205,7 +1207,7 @@ void kvmppc_uvmem_free(void) return; memunmap_pages(&kvmppc_uvmem_pgmap); - release_mem_region(kvmppc_uvmem_pgmap.res.start, - resource_size(&kvmppc_uvmem_pgmap.res)); + release_mem_region(kvmppc_uvmem_pgmap.range.start, + range_len(&kvmppc_uvmem_pgmap.range)); kfree(kvmppc_uvmem_bitmap); } diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 88fac22fbf09..b1fefa63e125 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -569,7 +569,7 @@ static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 msr) #endif } -void kvmppc_set_pvr_pr(struct kvm_vcpu *vcpu, u32 pvr) +static void kvmppc_set_pvr_pr(struct kvm_vcpu *vcpu, u32 pvr) { u32 host_pvr; diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index 381bf8dea193..5fee5a11550d 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c @@ -1334,47 +1334,97 @@ static int xics_has_attr(struct kvm_device *dev, struct kvm_device_attr *attr) return -ENXIO; } -static void kvmppc_xics_free(struct kvm_device *dev) +/* + * Called when device fd is closed. kvm->lock is held. + */ +static void kvmppc_xics_release(struct kvm_device *dev) { struct kvmppc_xics *xics = dev->private; int i; struct kvm *kvm = xics->kvm; + struct kvm_vcpu *vcpu; + + pr_devel("Releasing xics device\n"); + + /* + * Since this is the device release function, we know that + * userspace does not have any open fd referring to the + * device. Therefore there can not be any of the device + * attribute set/get functions being executed concurrently, + * and similarly, the connect_vcpu and set/clr_mapped + * functions also cannot be being executed. + */ debugfs_remove(xics->dentry); + /* + * We should clean up the vCPU interrupt presenters first. + */ + kvm_for_each_vcpu(i, vcpu, kvm) { + /* + * Take vcpu->mutex to ensure that no one_reg get/set ioctl + * (i.e. kvmppc_xics_[gs]et_icp) can be done concurrently. + * Holding the vcpu->mutex also means that execution is + * excluded for the vcpu until the ICP was freed. When the vcpu + * can execute again, vcpu->arch.icp and vcpu->arch.irq_type + * have been cleared and the vcpu will not be going into the + * XICS code anymore. + */ + mutex_lock(&vcpu->mutex); + kvmppc_xics_free_icp(vcpu); + mutex_unlock(&vcpu->mutex); + } + if (kvm) kvm->arch.xics = NULL; - for (i = 0; i <= xics->max_icsid; i++) + for (i = 0; i <= xics->max_icsid; i++) { kfree(xics->ics[i]); - kfree(xics); + xics->ics[i] = NULL; + } + /* + * A reference of the kvmppc_xics pointer is now kept under + * the xics_device pointer of the machine for reuse. It is + * freed when the VM is destroyed for now until we fix all the + * execution paths. + */ kfree(dev); } +static struct kvmppc_xics *kvmppc_xics_get_device(struct kvm *kvm) +{ + struct kvmppc_xics **kvm_xics_device = &kvm->arch.xics_device; + struct kvmppc_xics *xics = *kvm_xics_device; + + if (!xics) { + xics = kzalloc(sizeof(*xics), GFP_KERNEL); + *kvm_xics_device = xics; + } else { + memset(xics, 0, sizeof(*xics)); + } + + return xics; +} + static int kvmppc_xics_create(struct kvm_device *dev, u32 type) { struct kvmppc_xics *xics; struct kvm *kvm = dev->kvm; - int ret = 0; - xics = kzalloc(sizeof(*xics), GFP_KERNEL); + pr_devel("Creating xics for partition\n"); + + /* Already there ? */ + if (kvm->arch.xics) + return -EEXIST; + + xics = kvmppc_xics_get_device(kvm); if (!xics) return -ENOMEM; dev->private = xics; xics->dev = dev; xics->kvm = kvm; - - /* Already there ? */ - if (kvm->arch.xics) - ret = -EEXIST; - else - kvm->arch.xics = xics; - - if (ret) { - kfree(xics); - return ret; - } + kvm->arch.xics = xics; #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE if (cpu_has_feature(CPU_FTR_ARCH_206) && @@ -1399,7 +1449,7 @@ struct kvm_device_ops kvm_xics_ops = { .name = "kvm-xics", .create = kvmppc_xics_create, .init = kvmppc_xics_init, - .destroy = kvmppc_xics_free, + .release = kvmppc_xics_release, .set_attr = xics_set_attr, .get_attr = xics_get_attr, .has_attr = xics_has_attr, @@ -1415,7 +1465,7 @@ int kvmppc_xics_connect_vcpu(struct kvm_device *dev, struct kvm_vcpu *vcpu, return -EPERM; if (xics->kvm != vcpu->kvm) return -EPERM; - if (vcpu->arch.irq_type) + if (vcpu->arch.irq_type != KVMPPC_IRQ_DEFAULT) return -EBUSY; r = kvmppc_xics_create_icp(vcpu, xcpu); diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index bdea91df1497..d0c2db0e07fa 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -1227,17 +1227,7 @@ static int xive_native_debug_show(struct seq_file *m, void *private) return 0; } -static int xive_native_debug_open(struct inode *inode, struct file *file) -{ - return single_open(file, xive_native_debug_show, inode->i_private); -} - -static const struct file_operations xive_native_debug_fops = { - .open = xive_native_debug_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(xive_native_debug); static void xive_native_debugfs_init(struct kvmppc_xive *xive) { diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 3e1c9f08e302..b1abcb816439 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -1747,12 +1747,12 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { - return -ENOTSUPP; + return -EOPNOTSUPP; } int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) { - return -ENOTSUPP; + return -EOPNOTSUPP; } int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, @@ -1773,7 +1773,7 @@ void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot) int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) { - return -ENOTSUPP; + return -EOPNOTSUPP; } void kvmppc_core_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index d66a645503eb..69a91b571845 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -39,7 +39,7 @@ obj-$(CONFIG_PPC_BOOK3S_64) += copyuser_power7.o copypage_power7.o \ memcpy_power7.o obj64-y += copypage_64.o copyuser_64.o mem_64.o hweight_64.o \ - memcpy_64.o memcpy_mcsafe_64.o + memcpy_64.o copy_mc_64.o ifndef CONFIG_PPC_QUEUED_SPINLOCKS obj64-$(CONFIG_SMP) += locks.o diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S index ecd150dc3ed9..27d9070617df 100644 --- a/arch/powerpc/lib/checksum_32.S +++ b/arch/powerpc/lib/checksum_32.S @@ -78,12 +78,10 @@ EXPORT_SYMBOL(__csum_partial) /* * Computes the checksum of a memory block at src, length len, - * and adds in "sum" (32-bit), while copying the block to dst. - * If an access exception occurs on src or dst, it stores -EFAULT - * to *src_err or *dst_err respectively, and (for an error on - * src) zeroes the rest of dst. + * and adds in 0xffffffff, while copying the block to dst. + * If an access exception occurs it returns zero. * - * csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err) + * csum_partial_copy_generic(src, dst, len) */ #define CSUM_COPY_16_BYTES_WITHEX(n) \ 8 ## n ## 0: \ @@ -108,14 +106,14 @@ EXPORT_SYMBOL(__csum_partial) adde r12,r12,r10 #define CSUM_COPY_16_BYTES_EXCODE(n) \ - EX_TABLE(8 ## n ## 0b, src_error); \ - EX_TABLE(8 ## n ## 1b, src_error); \ - EX_TABLE(8 ## n ## 2b, src_error); \ - EX_TABLE(8 ## n ## 3b, src_error); \ - EX_TABLE(8 ## n ## 4b, dst_error); \ - EX_TABLE(8 ## n ## 5b, dst_error); \ - EX_TABLE(8 ## n ## 6b, dst_error); \ - EX_TABLE(8 ## n ## 7b, dst_error); + EX_TABLE(8 ## n ## 0b, fault); \ + EX_TABLE(8 ## n ## 1b, fault); \ + EX_TABLE(8 ## n ## 2b, fault); \ + EX_TABLE(8 ## n ## 3b, fault); \ + EX_TABLE(8 ## n ## 4b, fault); \ + EX_TABLE(8 ## n ## 5b, fault); \ + EX_TABLE(8 ## n ## 6b, fault); \ + EX_TABLE(8 ## n ## 7b, fault); .text .stabs "arch/powerpc/lib/",N_SO,0,0,0f @@ -127,11 +125,8 @@ LG_CACHELINE_BYTES = L1_CACHE_SHIFT CACHELINE_MASK = (L1_CACHE_BYTES-1) _GLOBAL(csum_partial_copy_generic) - stwu r1,-16(r1) - stw r7,12(r1) - stw r8,8(r1) - - addic r12,r6,0 + li r12,-1 + addic r0,r0,0 /* clear carry */ addi r6,r4,-4 neg r0,r4 addi r4,r3,-4 @@ -241,39 +236,23 @@ _GLOBAL(csum_partial_copy_generic) slwi r0,r0,8 adde r12,r12,r0 66: addze r3,r12 - addi r1,r1,16 beqlr+ cr7 rlwinm r3,r3,8,0,31 /* odd destination address: rotate one byte */ blr -/* read fault */ -src_error: - lwz r7,12(r1) - addi r1,r1,16 - cmpwi cr0,r7,0 - beqlr - li r0,-EFAULT - stw r0,0(r7) - blr -/* write fault */ -dst_error: - lwz r8,8(r1) - addi r1,r1,16 - cmpwi cr0,r8,0 - beqlr - li r0,-EFAULT - stw r0,0(r8) +fault: + li r3,0 blr - EX_TABLE(70b, src_error); - EX_TABLE(71b, dst_error); - EX_TABLE(72b, src_error); - EX_TABLE(73b, dst_error); - EX_TABLE(54b, dst_error); + EX_TABLE(70b, fault); + EX_TABLE(71b, fault); + EX_TABLE(72b, fault); + EX_TABLE(73b, fault); + EX_TABLE(54b, fault); /* * this stuff handles faults in the cacheline loop and branches to either - * src_error (if in read part) or dst_error (if in write part) + * fault (if in read part) or fault (if in write part) */ CSUM_COPY_16_BYTES_EXCODE(0) #if L1_CACHE_BYTES >= 32 @@ -290,12 +269,12 @@ dst_error: #endif #endif - EX_TABLE(30b, src_error); - EX_TABLE(31b, dst_error); - EX_TABLE(40b, src_error); - EX_TABLE(41b, dst_error); - EX_TABLE(50b, src_error); - EX_TABLE(51b, dst_error); + EX_TABLE(30b, fault); + EX_TABLE(31b, fault); + EX_TABLE(40b, fault); + EX_TABLE(41b, fault); + EX_TABLE(50b, fault); + EX_TABLE(51b, fault); EXPORT_SYMBOL(csum_partial_copy_generic) diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S index 514978f908d4..98ff51bd2f7d 100644 --- a/arch/powerpc/lib/checksum_64.S +++ b/arch/powerpc/lib/checksum_64.S @@ -182,34 +182,33 @@ EXPORT_SYMBOL(__csum_partial) .macro srcnr 100: - EX_TABLE(100b,.Lsrc_error_nr) + EX_TABLE(100b,.Lerror_nr) .endm .macro source 150: - EX_TABLE(150b,.Lsrc_error) + EX_TABLE(150b,.Lerror) .endm .macro dstnr 200: - EX_TABLE(200b,.Ldest_error_nr) + EX_TABLE(200b,.Lerror_nr) .endm .macro dest 250: - EX_TABLE(250b,.Ldest_error) + EX_TABLE(250b,.Lerror) .endm /* * Computes the checksum of a memory block at src, length len, - * and adds in "sum" (32-bit), while copying the block to dst. - * If an access exception occurs on src or dst, it stores -EFAULT - * to *src_err or *dst_err respectively. The caller must take any action - * required in this case (zeroing memory, recalculating partial checksum etc). + * and adds in 0xffffffff (32-bit), while copying the block to dst. + * If an access exception occurs, it returns 0. * - * csum_partial_copy_generic(r3=src, r4=dst, r5=len, r6=sum, r7=src_err, r8=dst_err) + * csum_partial_copy_generic(r3=src, r4=dst, r5=len) */ _GLOBAL(csum_partial_copy_generic) + li r6,-1 addic r0,r6,0 /* clear carry */ srdi. r6,r5,3 /* less than 8 bytes? */ @@ -401,29 +400,15 @@ dstnr; stb r6,0(r4) srdi r3,r3,32 blr -.Lsrc_error: +.Lerror: ld r14,STK_REG(R14)(r1) ld r15,STK_REG(R15)(r1) ld r16,STK_REG(R16)(r1) addi r1,r1,STACKFRAMESIZE -.Lsrc_error_nr: - cmpdi 0,r7,0 - beqlr - li r6,-EFAULT - stw r6,0(r7) +.Lerror_nr: + li r3,0 blr -.Ldest_error: - ld r14,STK_REG(R14)(r1) - ld r15,STK_REG(R15)(r1) - ld r16,STK_REG(R16)(r1) - addi r1,r1,STACKFRAMESIZE -.Ldest_error_nr: - cmpdi 0,r8,0 - beqlr - li r6,-EFAULT - stw r6,0(r8) - blr EXPORT_SYMBOL(csum_partial_copy_generic) /* diff --git a/arch/powerpc/lib/checksum_wrappers.c b/arch/powerpc/lib/checksum_wrappers.c index fabe4db28726..b895166afc82 100644 --- a/arch/powerpc/lib/checksum_wrappers.c +++ b/arch/powerpc/lib/checksum_wrappers.c @@ -12,83 +12,37 @@ #include <linux/uaccess.h> __wsum csum_and_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) + int len) { - unsigned int csum; + __wsum csum; might_sleep(); - allow_read_from_user(src, len); - - *err_ptr = 0; - - if (!len) { - csum = 0; - goto out; - } - if (unlikely((len < 0) || !access_ok(src, len))) { - *err_ptr = -EFAULT; - csum = (__force unsigned int)sum; - goto out; - } + if (unlikely(!access_ok(src, len))) + return 0; - csum = csum_partial_copy_generic((void __force *)src, dst, - len, sum, err_ptr, NULL); - - if (unlikely(*err_ptr)) { - int missing = __copy_from_user(dst, src, len); - - if (missing) { - memset(dst + len - missing, 0, missing); - *err_ptr = -EFAULT; - } else { - *err_ptr = 0; - } + allow_read_from_user(src, len); - csum = csum_partial(dst, len, sum); - } + csum = csum_partial_copy_generic((void __force *)src, dst, len); -out: prevent_read_from_user(src, len); - return (__force __wsum)csum; + return csum; } EXPORT_SYMBOL(csum_and_copy_from_user); -__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len, - __wsum sum, int *err_ptr) +__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len) { - unsigned int csum; + __wsum csum; might_sleep(); - allow_write_to_user(dst, len); - - *err_ptr = 0; - - if (!len) { - csum = 0; - goto out; - } + if (unlikely(!access_ok(dst, len))) + return 0; - if (unlikely((len < 0) || !access_ok(dst, len))) { - *err_ptr = -EFAULT; - csum = -1; /* invalid checksum */ - goto out; - } - - csum = csum_partial_copy_generic(src, (void __force *)dst, - len, sum, NULL, err_ptr); - - if (unlikely(*err_ptr)) { - csum = csum_partial(src, len, sum); + allow_write_to_user(dst, len); - if (copy_to_user(dst, src, len)) { - *err_ptr = -EFAULT; - csum = -1; /* invalid checksum */ - } - } + csum = csum_partial_copy_generic(src, (void __force *)dst, len); -out: prevent_write_to_user(dst, len); - return (__force __wsum)csum; + return csum; } EXPORT_SYMBOL(csum_and_copy_to_user); diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 8c3934ea6220..2333625b5e31 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -21,21 +21,18 @@ static int __patch_instruction(struct ppc_inst *exec_addr, struct ppc_inst instr, struct ppc_inst *patch_addr) { - int err = 0; - - if (!ppc_inst_prefixed(instr)) { - __put_user_asm(ppc_inst_val(instr), patch_addr, err, "stw"); - } else { - __put_user_asm(ppc_inst_as_u64(instr), patch_addr, err, "std"); - } - - if (err) - return err; + if (!ppc_inst_prefixed(instr)) + __put_user_asm_goto(ppc_inst_val(instr), patch_addr, failed, "stw"); + else + __put_user_asm_goto(ppc_inst_as_u64(instr), patch_addr, failed, "std"); asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr), "r" (exec_addr)); return 0; + +failed: + return -EFAULT; } int raw_patch_instruction(struct ppc_inst *addr, struct ppc_inst instr) diff --git a/arch/powerpc/lib/memcpy_mcsafe_64.S b/arch/powerpc/lib/copy_mc_64.S index cb882d9a6d8a..88d46c471493 100644 --- a/arch/powerpc/lib/memcpy_mcsafe_64.S +++ b/arch/powerpc/lib/copy_mc_64.S @@ -50,7 +50,7 @@ err3; stb r0,0(r3) blr -_GLOBAL(memcpy_mcsafe) +_GLOBAL(copy_mc_generic) mr r7,r5 cmpldi r5,16 blt .Lshort_copy @@ -239,4 +239,4 @@ err1; stb r0,0(r3) 15: li r3,0 blr -EXPORT_SYMBOL_GPL(memcpy_mcsafe); +EXPORT_SYMBOL_GPL(copy_mc_generic); diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index caee8cc77e19..855457ed09b5 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -108,11 +108,11 @@ static nokprobe_inline long address_ok(struct pt_regs *regs, { if (!user_mode(regs)) return 1; - if (__access_ok(ea, nb, USER_DS)) + if (__access_ok(ea, nb)) return 1; - if (__access_ok(ea, 1, USER_DS)) + if (__access_ok(ea, 1)) /* Access overlaps the end of the user region */ - regs->dar = USER_DS.seg; + regs->dar = TASK_SIZE_MAX - 1; else regs->dar = ea; return 0; @@ -219,10 +219,13 @@ static nokprobe_inline unsigned long mlsd_8lsd_ea(unsigned int instr, ea += regs->gpr[ra]; else if (!prefix_r && !ra) ; /* Leave ea as is */ - else if (prefix_r && !ra) + else if (prefix_r) ea += regs->nip; - else if (prefix_r && ra) - ; /* Invalid form. Should already be checked for by caller! */ + + /* + * (prefix_r && ra) is an invalid form. Should already be + * checked for by caller! + */ return ea; } diff --git a/arch/powerpc/mm/book3s32/hash_low.S b/arch/powerpc/mm/book3s32/hash_low.S index 1690d369688b..b2c912e517b9 100644 --- a/arch/powerpc/mm/book3s32/hash_low.S +++ b/arch/powerpc/mm/book3s32/hash_low.S @@ -15,6 +15,7 @@ */ #include <linux/pgtable.h> +#include <linux/init.h> #include <asm/reg.h> #include <asm/page.h> #include <asm/cputable.h> @@ -199,11 +200,9 @@ _GLOBAL(add_hash_page) * covered by a BAT). -- paulus */ mfmsr r9 - SYNC rlwinm r0,r9,0,17,15 /* clear bit 16 (MSR_EE) */ rlwinm r0,r0,0,28,26 /* clear MSR_DR */ mtmsr r0 - SYNC_601 isync #ifdef CONFIG_SMP @@ -262,7 +261,6 @@ _GLOBAL(add_hash_page) /* reenable interrupts and DR */ mtmsr r9 - SYNC_601 isync lwz r0,4(r1) @@ -287,9 +285,9 @@ _ASM_NOKPROBE_SYMBOL(add_hash_page) * * For speed, 4 of the instructions get patched once the size and * physical address of the hash table are known. These definitions - * of Hash_base and Hash_bits below are just an example. + * of Hash_base and Hash_bits below are for the early hash table. */ -Hash_base = 0xc0180000 +Hash_base = early_hash Hash_bits = 12 /* e.g. 256kB hash table */ Hash_msk = (((1 << Hash_bits) - 1) * 64) @@ -310,6 +308,7 @@ Hash_msk = (((1 << Hash_bits) - 1) * 64) #define HASH_LEFT 31-(LG_PTEG_SIZE+Hash_bits-1) #define HASH_RIGHT 31-LG_PTEG_SIZE +__REF _GLOBAL(create_hpte) /* Convert linux-style PTE (r5) to low word of PPC-style PTE (r8) */ rlwinm r8,r5,32-9,30,30 /* _PAGE_RW -> PP msb */ @@ -476,6 +475,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) sync /* make sure pte updates get to memory */ blr + .previous _ASM_NOKPROBE_SYMBOL(create_hpte) .section .bss @@ -496,6 +496,7 @@ htab_hash_searches: * * We assume that there is a hash table in use (Hash != 0). */ +__REF _GLOBAL(flush_hash_pages) /* * We disable interrupts here, even on UP, because we want @@ -506,11 +507,9 @@ _GLOBAL(flush_hash_pages) * covered by a BAT). -- paulus */ mfmsr r10 - SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ rlwinm r0,r0,0,28,26 /* clear MSR_DR */ mtmsr r0 - SYNC_601 isync /* First find a PTE in the range that has _PAGE_HASHPTE set */ @@ -629,9 +628,9 @@ _GLOBAL(flush_hash_pages) #endif 19: mtmsr r10 - SYNC_601 isync blr + .previous EXPORT_SYMBOL(flush_hash_pages) _ASM_NOKPROBE_SYMBOL(flush_hash_pages) @@ -643,11 +642,9 @@ _GLOBAL(_tlbie) lwz r8,TASK_CPU(r2) oris r8,r8,11 mfmsr r10 - SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ rlwinm r0,r0,0,28,26 /* clear DR */ mtmsr r0 - SYNC_601 isync lis r9,mmu_hash_lock@h ori r9,r9,mmu_hash_lock@l @@ -664,7 +661,6 @@ _GLOBAL(_tlbie) li r0,0 stw r0,0(r9) /* clear mmu_hash_lock */ mtmsr r10 - SYNC_601 isync #else /* CONFIG_SMP */ tlbie r3 @@ -681,11 +677,9 @@ _GLOBAL(_tlbia) lwz r8,TASK_CPU(r2) oris r8,r8,10 mfmsr r10 - SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ rlwinm r0,r0,0,28,26 /* clear DR */ mtmsr r0 - SYNC_601 isync lis r9,mmu_hash_lock@h ori r9,r9,mmu_hash_lock@l @@ -709,7 +703,6 @@ _GLOBAL(_tlbia) li r0,0 stw r0,0(r9) /* clear mmu_hash_lock */ mtmsr r10 - SYNC_601 isync #endif /* CONFIG_SMP */ blr diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c index d426eaf76bb0..a59e7ec98180 100644 --- a/arch/powerpc/mm/book3s32/mmu.c +++ b/arch/powerpc/mm/book3s32/mmu.c @@ -31,6 +31,8 @@ #include <mm/mmu_decl.h> +u8 __initdata early_hash[SZ_256K] __aligned(SZ_256K) = {0}; + struct hash_pte *Hash; static unsigned long Hash_size, Hash_mask; unsigned long _SDR1; @@ -73,23 +75,13 @@ unsigned long p_block_mapped(phys_addr_t pa) static int find_free_bat(void) { int b; + int n = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4; - if (IS_ENABLED(CONFIG_PPC_BOOK3S_601)) { - for (b = 0; b < 4; b++) { - struct ppc_bat *bat = BATS[b]; - - if (!(bat[0].batl & 0x40)) - return b; - } - } else { - int n = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4; + for (b = 0; b < n; b++) { + struct ppc_bat *bat = BATS[b]; - for (b = 0; b < n; b++) { - struct ppc_bat *bat = BATS[b]; - - if (!(bat[1].batu & 3)) - return b; - } + if (!(bat[1].batu & 3)) + return b; } return -1; } @@ -97,7 +89,7 @@ static int find_free_bat(void) /* * This function calculates the size of the larger block usable to map the * beginning of an area based on the start address and size of that area: - * - max block size is 8M on 601 and 256 on other 6xx. + * - max block size is 256 on 6xx. * - base address must be aligned to the block size. So the maximum block size * is identified by the lowest bit set to 1 in the base address (for instance * if base is 0x16000000, max size is 0x02000000). @@ -106,7 +98,7 @@ static int find_free_bat(void) */ static unsigned int block_size(unsigned long base, unsigned long top) { - unsigned int max_size = IS_ENABLED(CONFIG_PPC_BOOK3S_601) ? SZ_8M : SZ_256M; + unsigned int max_size = SZ_256M; unsigned int base_shift = (ffs(base) - 1) & 31; unsigned int block_shift = (fls(top - base) - 1) & 31; @@ -117,7 +109,6 @@ static unsigned int block_size(unsigned long base, unsigned long top) * Set up one of the IBAT (block address translation) register pairs. * The parameters are not checked; in particular size must be a power * of 2 between 128k and 256M. - * Only for 603+ ... */ static void setibat(int index, unsigned long virt, phys_addr_t phys, unsigned int size, pgprot_t prot) @@ -214,9 +205,6 @@ void mmu_mark_initmem_nx(void) unsigned long border = (unsigned long)__init_begin - PAGE_OFFSET; unsigned long size; - if (IS_ENABLED(CONFIG_PPC_BOOK3S_601)) - return; - for (i = 0; i < nb - 1 && base < top && top - base > (128 << 10);) { size = block_size(base, top); setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT); @@ -253,9 +241,6 @@ void mmu_mark_rodata_ro(void) int nb = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4; int i; - if (IS_ENABLED(CONFIG_PPC_BOOK3S_601)) - return; - for (i = 0; i < nb; i++) { struct ppc_bat *bat = BATS[i]; @@ -294,35 +279,22 @@ void __init setbat(int index, unsigned long virt, phys_addr_t phys, flags &= ~_PAGE_COHERENT; bl = (size >> 17) - 1; - if (!IS_ENABLED(CONFIG_PPC_BOOK3S_601)) { - /* 603, 604, etc. */ - /* Do DBAT first */ - wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE - | _PAGE_COHERENT | _PAGE_GUARDED); - wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX; - bat[1].batu = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */ - bat[1].batl = BAT_PHYS_ADDR(phys) | wimgxpp; - if (flags & _PAGE_USER) - bat[1].batu |= 1; /* Vp = 1 */ - if (flags & _PAGE_GUARDED) { - /* G bit must be zero in IBATs */ - flags &= ~_PAGE_EXEC; - } - if (flags & _PAGE_EXEC) - bat[0] = bat[1]; - else - bat[0].batu = bat[0].batl = 0; - } else { - /* 601 cpu */ - if (bl > BL_8M) - bl = BL_8M; - wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE - | _PAGE_COHERENT); - wimgxpp |= (flags & _PAGE_RW)? - ((flags & _PAGE_USER)? PP_RWRW: PP_RWXX): PP_RXRX; - bat->batu = virt | wimgxpp | 4; /* Ks=0, Ku=1 */ - bat->batl = phys | bl | 0x40; /* V=1 */ + /* Do DBAT first */ + wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE + | _PAGE_COHERENT | _PAGE_GUARDED); + wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX; + bat[1].batu = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */ + bat[1].batl = BAT_PHYS_ADDR(phys) | wimgxpp; + if (flags & _PAGE_USER) + bat[1].batu |= 1; /* Vp = 1 */ + if (flags & _PAGE_GUARDED) { + /* G bit must be zero in IBATs */ + flags &= ~_PAGE_EXEC; } + if (flags & _PAGE_EXEC) + bat[0] = bat[1]; + else + bat[0].batu = bat[0].batl = 0; bat_addrs[index].start = virt; bat_addrs[index].limit = virt + ((bl + 1) << 17) - 1; @@ -425,15 +397,6 @@ void __init MMU_init_hw(void) hash_mb2 = hash_mb = 32 - LG_HPTEG_SIZE - lg_n_hpteg; if (lg_n_hpteg > 16) hash_mb2 = 16 - LG_HPTEG_SIZE; - - /* - * When KASAN is selected, there is already an early temporary hash - * table and the switch to the final hash table is done later. - */ - if (IS_ENABLED(CONFIG_KASAN)) - return; - - MMU_init_hw_patch(); } void __init MMU_init_hw_patch(void) @@ -441,6 +404,9 @@ void __init MMU_init_hw_patch(void) unsigned int hmask = Hash_mask >> (16 - LG_HPTEG_SIZE); unsigned int hash = (unsigned int)Hash - PAGE_OFFSET; + if (!mmu_has_feature(MMU_FTR_HPTE_TABLE)) + return; + if (ppc_md.progress) ppc_md.progress("hash:patch", 0x345); if (ppc_md.progress) @@ -474,11 +440,7 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base, */ BUG_ON(first_memblock_base != 0); - /* 601 can only access 16MB at the moment */ - if (IS_ENABLED(CONFIG_PPC_BOOK3S_601)) - memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01000000)); - else /* Anything else has 256M mapped */ - memblock_set_current_limit(min_t(u64, first_memblock_size, 0x10000000)); + memblock_set_current_limit(min_t(u64, first_memblock_size, SZ_256M)); } void __init print_system_hash_info(void) diff --git a/arch/powerpc/mm/book3s64/hash_native.c b/arch/powerpc/mm/book3s64/hash_native.c index cf20e5229ce1..0203cdf48c54 100644 --- a/arch/powerpc/mm/book3s64/hash_native.c +++ b/arch/powerpc/mm/book3s64/hash_native.c @@ -82,7 +82,7 @@ static void tlbiel_all_isa206(unsigned int num_sets, unsigned int is) for (set = 0; set < num_sets; set++) tlbiel_hash_set_isa206(set, is); - asm volatile("ptesync": : :"memory"); + ppc_after_tlbiel_barrier(); } static void tlbiel_all_isa300(unsigned int num_sets, unsigned int is) @@ -110,7 +110,7 @@ static void tlbiel_all_isa300(unsigned int num_sets, unsigned int is) */ tlbiel_hash_set_isa300(0, is, 0, 2, 1); - asm volatile("ptesync": : :"memory"); + ppc_after_tlbiel_barrier(); asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT "; isync" : : :"memory"); } @@ -303,7 +303,7 @@ static inline void tlbie(unsigned long vpn, int psize, int apsize, asm volatile("ptesync": : :"memory"); if (use_local) { __tlbiel(vpn, psize, apsize, ssize); - asm volatile("ptesync": : :"memory"); + ppc_after_tlbiel_barrier(); } else { __tlbie(vpn, psize, apsize, ssize); fixup_tlbie_vpn(vpn, psize, apsize, ssize); @@ -879,7 +879,7 @@ static void native_flush_hash_range(unsigned long number, int local) __tlbiel(vpn, psize, psize, ssize); } pte_iterate_hashed_end(); } - asm volatile("ptesync":::"memory"); + ppc_after_tlbiel_barrier(); } else { int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c index c663e7ba801f..24702c0a92e0 100644 --- a/arch/powerpc/mm/book3s64/hash_utils.c +++ b/arch/powerpc/mm/book3s64/hash_utils.c @@ -7,7 +7,7 @@ * * SMP scalability work: * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM - * + * * Module name: htab.c * * Description: @@ -260,8 +260,12 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, DBG("htab_bolt_mapping(%lx..%lx -> %lx (%lx,%d,%d)\n", vstart, vend, pstart, prot, psize, ssize); - for (vaddr = vstart, paddr = pstart; vaddr < vend; - vaddr += step, paddr += step) { + /* Carefully map only the possible range */ + vaddr = ALIGN(vstart, step); + paddr = ALIGN(pstart, step); + vend = ALIGN_DOWN(vend, step); + + for (; vaddr < vend; vaddr += step, paddr += step) { unsigned long hash, hpteg; unsigned long vsid = get_kernel_vsid(vaddr, ssize); unsigned long vpn = hpt_vpn(vaddr, vsid, ssize); @@ -343,7 +347,9 @@ int htab_remove_mapping(unsigned long vstart, unsigned long vend, if (!mmu_hash_ops.hpte_removebolted) return -ENODEV; - for (vaddr = vstart; vaddr < vend; vaddr += step) { + /* Unmap the full range specificied */ + vaddr = ALIGN_DOWN(vstart, step); + for (;vaddr < vend; vaddr += step) { rc = mmu_hash_ops.hpte_removebolted(vaddr, psize, ssize); if (rc == -ENOENT) { ret = -ENOENT; @@ -867,8 +873,8 @@ static void __init htab_initialize(void) unsigned long table; unsigned long pteg_count; unsigned long prot; - unsigned long base = 0, size = 0; - struct memblock_region *reg; + phys_addr_t base = 0, size = 0, end; + u64 i; DBG(" -> htab_initialize()\n"); @@ -884,7 +890,7 @@ static void __init htab_initialize(void) /* * Calculate the required size of the htab. We want the number of * PTEGs to equal one half the number of real pages. - */ + */ htab_size_bytes = htab_get_table_size(); pteg_count = htab_size_bytes >> 7; @@ -894,7 +900,7 @@ static void __init htab_initialize(void) firmware_has_feature(FW_FEATURE_PS3_LV1)) { /* Using a hypervisor which owns the htab */ htab_address = NULL; - _SDR1 = 0; + _SDR1 = 0; #ifdef CONFIG_FA_DUMP /* * If firmware assisted dump is active firmware preserves @@ -960,9 +966,9 @@ static void __init htab_initialize(void) #endif /* CONFIG_DEBUG_PAGEALLOC */ /* create bolted the linear mapping in the hash table */ - for_each_memblock(memory, reg) { - base = (unsigned long)__va(reg->base); - size = reg->size; + for_each_mem_range(i, &base, &end) { + size = end - base; + base = (unsigned long)__va(base); DBG("creating mapping for region: %lx..%lx (prot: %lx)\n", base, size, prot); diff --git a/arch/powerpc/mm/book3s64/internal.h b/arch/powerpc/mm/book3s64/internal.h index 7eda0d30d765..c12d78ee42f5 100644 --- a/arch/powerpc/mm/book3s64/internal.h +++ b/arch/powerpc/mm/book3s64/internal.h @@ -13,4 +13,6 @@ static inline bool stress_slb(void) return static_branch_unlikely(&stress_slb_key); } +void slb_setup_new_exec(void); + #endif /* ARCH_POWERPC_MM_BOOK3S64_INTERNAL_H */ diff --git a/arch/powerpc/mm/book3s64/mmu_context.c b/arch/powerpc/mm/book3s64/mmu_context.c index 0ba30b8b935b..1c54821de7bf 100644 --- a/arch/powerpc/mm/book3s64/mmu_context.c +++ b/arch/powerpc/mm/book3s64/mmu_context.c @@ -21,6 +21,8 @@ #include <asm/mmu_context.h> #include <asm/pgalloc.h> +#include "internal.h" + static DEFINE_IDA(mmu_context_ida); static int alloc_context_id(int min_id, int max_id) @@ -48,8 +50,6 @@ int hash__alloc_context_id(void) } EXPORT_SYMBOL_GPL(hash__alloc_context_id); -void slb_setup_new_exec(void); - static int realloc_context_ids(mm_context_t *ctx) { int i, id; diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c index 28c784976bed..3adcf730f478 100644 --- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -34,7 +34,7 @@ unsigned int mmu_pid_bits; unsigned int mmu_base_pid; -unsigned int radix_mem_block_size __ro_after_init; +unsigned long radix_mem_block_size __ro_after_init; static __ref void *early_alloc_pgtable(unsigned long size, int nid, unsigned long region_start, unsigned long region_end) @@ -276,6 +276,7 @@ static int __meminit create_physical_mapping(unsigned long start, int psize; start = ALIGN(start, PAGE_SIZE); + end = ALIGN_DOWN(end, PAGE_SIZE); for (addr = start; addr < end; addr += mapping_size) { unsigned long gap, previous_size; int rc; @@ -329,7 +330,8 @@ static int __meminit create_physical_mapping(unsigned long start, static void __init radix_init_pgtable(void) { unsigned long rts_field; - struct memblock_region *reg; + phys_addr_t start, end; + u64 i; /* We don't support slb for radix */ mmu_slb_size = 0; @@ -337,20 +339,19 @@ static void __init radix_init_pgtable(void) /* * Create the linear mapping */ - for_each_memblock(memory, reg) { + for_each_mem_range(i, &start, &end) { /* * The memblock allocator is up at this point, so the * page tables will be allocated within the range. No * need or a node (which we don't have yet). */ - if ((reg->base + reg->size) >= RADIX_VMALLOC_START) { + if (end >= RADIX_VMALLOC_START) { pr_warn("Outside the supported range\n"); continue; } - WARN_ON(create_physical_mapping(reg->base, - reg->base + reg->size, + WARN_ON(create_physical_mapping(start, end, radix_mem_block_size, -1, PAGE_KERNEL)); } @@ -497,7 +498,7 @@ static int __init probe_memory_block_size(unsigned long node, const char *uname, depth, void *data) { unsigned long *mem_block_size = (unsigned long *)data; - const __be64 *prop; + const __be32 *prop; int len; if (depth != 1) @@ -507,13 +508,14 @@ static int __init probe_memory_block_size(unsigned long node, const char *uname, return 0; prop = of_get_flat_dt_prop(node, "ibm,lmb-size", &len); - if (!prop || len < sizeof(__be64)) + + if (!prop || len < dt_root_size_cells * sizeof(__be32)) /* * Nothing in the device tree */ *mem_block_size = MIN_MEMORY_BLOCK_SIZE; else - *mem_block_size = be64_to_cpup(prop); + *mem_block_size = of_read_number(prop, dt_root_size_cells); return 1; } @@ -734,21 +736,6 @@ void radix__mmu_cleanup_all(void) } } -void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base, - phys_addr_t first_memblock_size) -{ - /* - * We don't currently support the first MEMBLOCK not mapping 0 - * physical on those processors - */ - BUG_ON(first_memblock_base != 0); - - /* - * Radix mode is not limited by RMA / VRMA addressing. - */ - ppc64_rma_size = ULONG_MAX; -} - #ifdef CONFIG_MEMORY_HOTPLUG static void free_pte_table(pte_t *pte_start, pmd_t *pmd) { diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c index 0d233763441f..b487b489d4b6 100644 --- a/arch/powerpc/mm/book3s64/radix_tlb.c +++ b/arch/powerpc/mm/book3s64/radix_tlb.c @@ -65,7 +65,7 @@ static void tlbiel_all_isa300(unsigned int num_sets, unsigned int is) for (set = 1; set < num_sets; set++) tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 1); - asm volatile("ptesync": : :"memory"); + ppc_after_tlbiel_barrier(); } void radix__tlbiel_all(unsigned int action) @@ -296,7 +296,7 @@ static __always_inline void _tlbiel_pid(unsigned long pid, unsigned long ric) /* For PWC, only one flush is needed */ if (ric == RIC_FLUSH_PWC) { - asm volatile("ptesync": : :"memory"); + ppc_after_tlbiel_barrier(); return; } @@ -304,7 +304,7 @@ static __always_inline void _tlbiel_pid(unsigned long pid, unsigned long ric) for (set = 1; set < POWER9_TLB_SETS_RADIX ; set++) __tlbiel_pid(pid, set, RIC_FLUSH_TLB); - asm volatile("ptesync": : :"memory"); + ppc_after_tlbiel_barrier(); asm volatile(PPC_RADIX_INVALIDATE_ERAT_USER "; isync" : : :"memory"); } @@ -431,7 +431,7 @@ static __always_inline void _tlbiel_va(unsigned long va, unsigned long pid, asm volatile("ptesync": : :"memory"); __tlbiel_va(va, pid, ap, ric); - asm volatile("ptesync": : :"memory"); + ppc_after_tlbiel_barrier(); } static inline void _tlbiel_va_range(unsigned long start, unsigned long end, @@ -442,7 +442,7 @@ static inline void _tlbiel_va_range(unsigned long start, unsigned long end, if (also_pwc) __tlbiel_pid(pid, 0, RIC_FLUSH_PWC); __tlbiel_va_range(start, end, pid, page_size, psize); - asm volatile("ptesync": : :"memory"); + ppc_after_tlbiel_barrier(); } static inline void __tlbie_va_range(unsigned long start, unsigned long end, @@ -645,19 +645,29 @@ static void do_exit_flush_lazy_tlb(void *arg) struct mm_struct *mm = arg; unsigned long pid = mm->context.id; + /* + * A kthread could have done a mmget_not_zero() after the flushing CPU + * checked mm_is_singlethreaded, and be in the process of + * kthread_use_mm when interrupted here. In that case, current->mm will + * be set to mm, because kthread_use_mm() setting ->mm and switching to + * the mm is done with interrupts off. + */ if (current->mm == mm) - return; /* Local CPU */ + goto out_flush; if (current->active_mm == mm) { - /* - * Must be a kernel thread because sender is single-threaded. - */ - BUG_ON(current->mm); + WARN_ON_ONCE(current->mm != NULL); + /* Is a kernel thread and is using mm as the lazy tlb */ mmgrab(&init_mm); - switch_mm(mm, &init_mm, current); current->active_mm = &init_mm; + switch_mm_irqs_off(mm, &init_mm, current); mmdrop(mm); } + + atomic_dec(&mm->context.active_cpus); + cpumask_clear_cpu(smp_processor_id(), mm_cpumask(mm)); + +out_flush: _tlbiel_pid(pid, RIC_FLUSH_ALL); } @@ -672,7 +682,6 @@ static void exit_flush_lazy_tlbs(struct mm_struct *mm) */ smp_call_function_many(mm_cpumask(mm), do_exit_flush_lazy_tlb, (void *)mm, 1); - mm_reset_thread_local(mm); } void radix__flush_tlb_mm(struct mm_struct *mm) @@ -940,7 +949,7 @@ is_local: if (hflush) __tlbiel_va_range(hstart, hend, pid, PMD_SIZE, MMU_PAGE_2M); - asm volatile("ptesync": : :"memory"); + ppc_after_tlbiel_barrier(); } else if (cputlb_use_tlbie()) { asm volatile("ptesync": : :"memory"); __tlbie_va_range(start, end, pid, page_size, mmu_virtual_psize); diff --git a/arch/powerpc/mm/book3s64/slb.c b/arch/powerpc/mm/book3s64/slb.c index 156c38f89511..c30fcbfa0e32 100644 --- a/arch/powerpc/mm/book3s64/slb.c +++ b/arch/powerpc/mm/book3s64/slb.c @@ -765,8 +765,8 @@ static long slb_allocate_kernel(unsigned long ea, unsigned long id) if (id == LINEAR_MAP_REGION_ID) { - /* We only support upto MAX_PHYSMEM_BITS */ - if ((ea & EA_MASK) > (1UL << MAX_PHYSMEM_BITS)) + /* We only support upto H_MAX_PHYSMEM_BITS */ + if ((ea & EA_MASK) > (1UL << H_MAX_PHYSMEM_BITS)) return -EFAULT; flags = SLB_VSID_KERNEL | mmu_psize_defs[mmu_linear_psize].sllp; diff --git a/arch/powerpc/mm/dma-noncoherent.c b/arch/powerpc/mm/dma-noncoherent.c index 5ab4f868e919..30260b5d146d 100644 --- a/arch/powerpc/mm/dma-noncoherent.c +++ b/arch/powerpc/mm/dma-noncoherent.c @@ -11,7 +11,7 @@ #include <linux/types.h> #include <linux/highmem.h> #include <linux/dma-direct.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <asm/tlbflush.h> #include <asm/dma.h> diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c index b2eeea39684c..9af3832c9d8d 100644 --- a/arch/powerpc/mm/drmem.c +++ b/arch/powerpc/mm/drmem.c @@ -389,10 +389,8 @@ static void __init init_drmem_v1_lmbs(const __be32 *prop) if (!drmem_info->lmbs) return; - for_each_drmem_lmb(lmb) { + for_each_drmem_lmb(lmb) read_drconf_v1_cell(lmb, &prop); - lmb_set_nid(lmb); - } } static void __init init_drmem_v2_lmbs(const __be32 *prop) @@ -437,8 +435,6 @@ static void __init init_drmem_v2_lmbs(const __be32 *prop) lmb->aa_index = dr_cell.aa_index; lmb->flags = dr_cell.flags; - - lmb_set_nid(lmb); } } } diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 26292544630f..36c3800769fb 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -180,7 +180,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz if (!hpdp) return NULL; - if (IS_ENABLED(CONFIG_PPC_8xx) && sz == SZ_512K) + if (IS_ENABLED(CONFIG_PPC_8xx) && pshift < PMD_SHIFT) return pte_alloc_map(mm, (pmd_t *)hpdp, addr); BUG_ON(!hugepd_none(*hpdp) && !hugepd_ok(*hpdp)); @@ -330,10 +330,24 @@ static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshif get_hugepd_cache_index(pdshift - shift)); } -static void hugetlb_free_pte_range(struct mmu_gather *tlb, pmd_t *pmd, unsigned long addr) +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) + return; + pmd_clear(pmd); pte_free_tlb(tlb, token, addr); mm_dec_nr_ptes(tlb->mm); @@ -363,7 +377,7 @@ static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, */ WARN_ON(!IS_ENABLED(CONFIG_PPC_8xx)); - hugetlb_free_pte_range(tlb, pmd, addr); + hugetlb_free_pte_range(tlb, pmd, addr, end, floor, ceiling); continue; } diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 02e127fa5777..386be136026e 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -162,16 +162,16 @@ static __meminit struct vmemmap_backing * vmemmap_list_alloc(int node) return next++; } -static __meminit void vmemmap_list_populate(unsigned long phys, - unsigned long start, - int node) +static __meminit int vmemmap_list_populate(unsigned long phys, + unsigned long start, + int node) { struct vmemmap_backing *vmem_back; vmem_back = vmemmap_list_alloc(node); if (unlikely(!vmem_back)) { - WARN_ON(1); - return; + pr_debug("vmemap list allocation failed\n"); + return -ENOMEM; } vmem_back->phys = phys; @@ -179,6 +179,7 @@ static __meminit void vmemmap_list_populate(unsigned long phys, vmem_back->list = vmemmap_list; vmemmap_list = vmem_back; + return 0; } static bool altmap_cross_boundary(struct vmem_altmap *altmap, unsigned long start, @@ -199,6 +200,7 @@ static bool altmap_cross_boundary(struct vmem_altmap *altmap, unsigned long star int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, struct vmem_altmap *altmap) { + bool altmap_alloc; unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift; /* Align to the page size of the linear mapping. */ @@ -228,13 +230,32 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, p = vmemmap_alloc_block_buf(page_size, node, altmap); if (!p) pr_debug("altmap block allocation failed, falling back to system memory"); + else + altmap_alloc = true; } - if (!p) + if (!p) { p = vmemmap_alloc_block_buf(page_size, node, NULL); + altmap_alloc = false; + } if (!p) return -ENOMEM; - vmemmap_list_populate(__pa(p), start, node); + if (vmemmap_list_populate(__pa(p), start, node)) { + /* + * If we don't populate vmemap list, we don't have + * the ability to free the allocated vmemmap + * pages in section_deactivate. Hence free them + * here. + */ + int nr_pfns = page_size >> PAGE_SHIFT; + unsigned long page_order = get_order(page_size); + + if (altmap_alloc) + vmem_altmap_free(altmap, nr_pfns); + else + free_pages((unsigned long)p, page_order); + return -ENOMEM; + } pr_debug(" * %016lx..%016lx allocated at %p\n", start, start + page_size, p); @@ -264,10 +285,8 @@ static unsigned long vmemmap_list_free(unsigned long start) vmem_back_prev = vmem_back; } - if (unlikely(!vmem_back)) { - WARN_ON(1); + if (unlikely(!vmem_back)) return 0; - } /* remove it from vmemmap_list */ if (vmem_back == vmemmap_list) /* remove head */ @@ -433,9 +452,16 @@ void __init mmu_early_init_devtree(void) if (!(mfmsr() & MSR_HV)) early_check_vec5(); - if (early_radix_enabled()) + if (early_radix_enabled()) { radix__early_init_devtree(); - else + /* + * We have finalized the translation we are going to use by now. + * Radix mode is not limited by RMA / VRMA addressing. + * Hence don't limit memblock allocations. + */ + ppc64_rma_size = ULONG_MAX; + memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE); + } else hash__early_init_devtree(); } #endif /* CONFIG_PPC_BOOK3S_64 */ diff --git a/arch/powerpc/mm/kasan/kasan_init_32.c b/arch/powerpc/mm/kasan/kasan_init_32.c index fb294046e00e..cf8770b1a692 100644 --- a/arch/powerpc/mm/kasan/kasan_init_32.c +++ b/arch/powerpc/mm/kasan/kasan_init_32.c @@ -127,8 +127,7 @@ void __init kasan_mmu_init(void) { int ret; - if (early_mmu_has_feature(MMU_FTR_HPTE_TABLE) || - IS_ENABLED(CONFIG_KASAN_VMALLOC)) { + if (early_mmu_has_feature(MMU_FTR_HPTE_TABLE)) { ret = kasan_init_shadow_page_tables(KASAN_SHADOW_START, KASAN_SHADOW_END); if (ret) @@ -138,12 +137,12 @@ void __init kasan_mmu_init(void) void __init kasan_init(void) { - struct memblock_region *reg; + phys_addr_t base, end; + u64 i; + int ret; - for_each_memblock(memory, reg) { - phys_addr_t base = reg->base; - phys_addr_t top = min(base + reg->size, total_lowmem); - int ret; + for_each_mem_range(i, &base, &end) { + phys_addr_t top = min(end, total_lowmem); if (base >= top) continue; @@ -153,6 +152,13 @@ void __init kasan_init(void) panic("kasan: kasan_init_region() failed"); } + if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) { + ret = kasan_init_shadow_page_tables(KASAN_SHADOW_START, KASAN_SHADOW_END); + + if (ret) + panic("kasan: kasan_init_shadow_page_tables() failed"); + } + kasan_remap_early_shadow_ro(); clear_page(kasan_early_shadow_page); @@ -168,22 +174,6 @@ void __init kasan_late_init(void) kasan_unmap_early_shadow_vmalloc(); } -#ifdef CONFIG_PPC_BOOK3S_32 -u8 __initdata early_hash[256 << 10] __aligned(256 << 10) = {0}; - -static void __init kasan_early_hash_table(void) -{ - unsigned int hash = __pa(early_hash); - - modify_instruction_site(&patch__hash_page_A0, 0xffff, hash >> 16); - modify_instruction_site(&patch__flush_hash_A0, 0xffff, hash >> 16); - - Hash = (struct hash_pte *)early_hash; -} -#else -static void __init kasan_early_hash_table(void) {} -#endif - void __init kasan_early_init(void) { unsigned long addr = KASAN_SHADOW_START; @@ -199,7 +189,4 @@ void __init kasan_early_init(void) next = pgd_addr_end(addr, end); pmd_populate_kernel(&init_mm, pmd, kasan_early_shadow_pte); } while (pmd++, addr = next, addr != end); - - if (early_mmu_has_feature(MMU_FTR_HPTE_TABLE)) - kasan_early_hash_table(); } diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 42e25874f5a8..01ec2a252f09 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -49,6 +49,7 @@ #include <asm/swiotlb.h> #include <asm/rtas.h> #include <asm/kasan.h> +#include <asm/svm.h> #include <mm/mmu_decl.h> @@ -184,15 +185,16 @@ void __init initmem_init(void) /* mark pages that don't exist as nosave */ static int __init mark_nonram_nosave(void) { - struct memblock_region *reg, *prev = NULL; - - for_each_memblock(memory, reg) { - if (prev && - memblock_region_memory_end_pfn(prev) < memblock_region_memory_base_pfn(reg)) - register_nosave_region(memblock_region_memory_end_pfn(prev), - memblock_region_memory_base_pfn(reg)); - prev = reg; + unsigned long spfn, epfn, prev = 0; + int i; + + for_each_mem_pfn_range(i, MAX_NUMNODES, &spfn, &epfn, NULL) { + if (prev && prev < spfn) + register_nosave_region(prev, spfn); + + prev = epfn; } + return 0; } #else /* CONFIG_NEED_MULTIPLE_NODES */ @@ -282,7 +284,10 @@ void __init mem_init(void) * back to to-down. */ memblock_set_bottom_up(true); - swiotlb_init(0); + if (is_secure_guest()) + svm_swiotlb_init(); + else + swiotlb_init(0); #endif high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); @@ -584,20 +589,24 @@ void flush_icache_user_page(struct vm_area_struct *vma, struct page *page, */ static int __init add_system_ram_resources(void) { - struct memblock_region *reg; + phys_addr_t start, end; + u64 i; - for_each_memblock(memory, reg) { + for_each_mem_range(i, &start, &end) { struct resource *res; - unsigned long base = reg->base; - unsigned long size = reg->size; res = kzalloc(sizeof(struct resource), GFP_KERNEL); WARN_ON(!res); if (res) { res->name = "System RAM"; - res->start = base; - res->end = base + size - 1; + res->start = start; + /* + * In memblock, end points to the first byte after + * the range while in resourses, end points to the + * last byte in the range. + */ + res->end = end - 1; res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; WARN_ON(request_resource(&iomem_resource, res) < 0); } diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c index d2b37146ae6c..231ca95f9ffb 100644 --- a/arch/powerpc/mm/nohash/8xx.c +++ b/arch/powerpc/mm/nohash/8xx.c @@ -244,13 +244,6 @@ void set_context(unsigned long id, pgd_t *pgd) mb(); } -void flush_instruction_cache(void) -{ - isync(); - mtspr(SPRN_IC_CST, IDC_INVALL); - isync(); -} - #ifdef CONFIG_PPC_KUEP void __init setup_kuep(bool disabled) { diff --git a/arch/powerpc/mm/nohash/fsl_booke.c b/arch/powerpc/mm/nohash/fsl_booke.c index 0c294827d6e5..36bda962d3b3 100644 --- a/arch/powerpc/mm/nohash/fsl_booke.c +++ b/arch/powerpc/mm/nohash/fsl_booke.c @@ -219,6 +219,22 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top) return tlbcam_addrs[tlbcam_index - 1].limit - PAGE_OFFSET + 1; } +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); + } + isync(); +} + /* * MMU_init_hw does the chip-specific initialization of the MMU hardware. */ diff --git a/arch/powerpc/mm/nohash/tlb.c b/arch/powerpc/mm/nohash/tlb.c index 14514585db98..5872f69141d5 100644 --- a/arch/powerpc/mm/nohash/tlb.c +++ b/arch/powerpc/mm/nohash/tlb.c @@ -83,16 +83,12 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { }; #elif defined(CONFIG_PPC_8xx) struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { - /* we only manage 4k and 16k pages as normal pages */ -#ifdef CONFIG_PPC_4K_PAGES [MMU_PAGE_4K] = { .shift = 12, }, -#else [MMU_PAGE_16K] = { .shift = 14, }, -#endif [MMU_PAGE_512K] = { .shift = 19, }, diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 1f61fa2148b5..63f61d8b55e5 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -430,7 +430,7 @@ static int of_get_assoc_arrays(struct assoc_arrays *aa) * This is like of_node_to_nid_single() for memory represented in the * ibm,dynamic-reconfiguration-memory node. */ -static int of_drconf_to_nid_single(struct drmem_lmb *lmb) +int of_drconf_to_nid_single(struct drmem_lmb *lmb) { struct assoc_arrays aa = { .arrays = NULL }; int default_nid = NUMA_NO_NODE; @@ -507,6 +507,11 @@ static int numa_setup_cpu(unsigned long lcpu) int fcpu = cpu_first_thread_sibling(lcpu); int nid = NUMA_NO_NODE; + if (!cpu_present(lcpu)) { + set_cpu_numa_node(lcpu, first_online_node); + return first_online_node; + } + /* * If a valid cpu-to-node mapping is already available, use it * directly instead of querying the firmware, since it represents @@ -723,21 +728,22 @@ static int __init parse_numa_properties(void) */ for_each_present_cpu(i) { struct device_node *cpu; - int nid; - - cpu = of_get_cpu_node(i, NULL); - BUG_ON(!cpu); - nid = of_node_to_nid_single(cpu); - of_node_put(cpu); + int nid = vphn_get_nid(i); /* * Don't fall back to default_nid yet -- we will plug * cpus into nodes once the memory scan has discovered * the topology. */ - if (nid < 0) - continue; - node_set_online(nid); + if (nid == NUMA_NO_NODE) { + cpu = of_get_cpu_node(i, NULL); + BUG_ON(!cpu); + nid = of_node_to_nid_single(cpu); + of_node_put(cpu); + } + + if (likely(nid > 0)) + node_set_online(nid); } get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells); @@ -804,17 +810,14 @@ static void __init setup_nonnuma(void) unsigned long total_ram = memblock_phys_mem_size(); unsigned long start_pfn, end_pfn; unsigned int nid = 0; - struct memblock_region *reg; + int i; printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", top_of_ram, total_ram); printk(KERN_DEBUG "Memory hole size: %ldMB\n", (top_of_ram - total_ram) >> 20); - for_each_memblock(memory, reg) { - start_pfn = memblock_region_memory_base_pfn(reg); - end_pfn = memblock_region_memory_end_pfn(reg); - + for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, NULL) { fake_numa_create_new_node(end_pfn, &nid); memblock_set_node(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn - start_pfn), @@ -891,7 +894,9 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn) static void __init find_possible_nodes(void) { struct device_node *rtas; - u32 numnodes, i; + const __be32 *domains; + int prop_length, max_nodes; + u32 i; if (!numa_enabled) return; @@ -900,16 +905,31 @@ static void __init find_possible_nodes(void) if (!rtas) return; - if (of_property_read_u32_index(rtas, - "ibm,max-associativity-domains", - min_common_depth, &numnodes)) - goto out; + /* + * ibm,current-associativity-domains is a fairly recent property. If + * it doesn't exist, then fallback on ibm,max-associativity-domains. + * Current denotes what the platform can support compared to max + * which denotes what the Hypervisor can support. + */ + domains = of_get_property(rtas, "ibm,current-associativity-domains", + &prop_length); + if (!domains) { + domains = of_get_property(rtas, "ibm,max-associativity-domains", + &prop_length); + if (!domains) + goto out; + } - for (i = 0; i < numnodes; i++) { + max_nodes = of_read_number(&domains[min_common_depth], 1); + for (i = 0; i < max_nodes; i++) { if (!node_possible(i)) node_set(i, node_possible_map); } + prop_length /= sizeof(int); + if (prop_length > min_common_depth + 2) + coregroup_enabled = 1; + out: of_node_put(rtas); } @@ -918,6 +938,16 @@ void __init mem_topology_setup(void) { int cpu; + /* + * Linux/mm assumes node 0 to be online at boot. However this is not + * true on PowerPC, where node 0 is similar to any other node, it + * could be cpuless, memoryless node. So force node 0 to be offline + * for now. This will prevent cpuless, memoryless node 0 showing up + * unnecessarily as online. If a node has cpus or memory that need + * to be online, then node will anyway be marked online. + */ + node_set_offline(0); + if (parse_numa_properties()) setup_nonnuma(); @@ -935,8 +965,17 @@ void __init mem_topology_setup(void) reset_numa_cpu_lookup_table(); - for_each_present_cpu(cpu) + for_each_possible_cpu(cpu) { + /* + * Powerpc with CONFIG_NUMA always used to have a node 0, + * even if it was memoryless or cpuless. For all cpus that + * are possible but not present, cpu_to_node() would point + * to node 0. To remove a cpuless, memoryless dummy node, + * powerpc need to make sure all possible but not present + * cpu_to_node are set to a proper node. + */ numa_setup_cpu(cpu); + } } void __init initmem_init(void) @@ -1203,6 +1242,31 @@ int find_and_online_cpu_nid(int cpu) return new_nid; } +int cpu_to_coregroup_id(int cpu) +{ + __be32 associativity[VPHN_ASSOC_BUFSIZE] = {0}; + int index; + + if (cpu < 0 || cpu > nr_cpu_ids) + return -1; + + if (!coregroup_enabled) + goto out; + + if (!firmware_has_feature(FW_FEATURE_VPHN)) + goto out; + + if (vphn_get_associativity(cpu, associativity)) + goto out; + + index = of_read_number(associativity, 1); + if (index > min_common_depth + 1) + return of_read_number(&associativity[index - 1], 1); + +out: + return cpu_to_core_id(cpu); +} + static int topology_update_init(void) { topology_inited = 1; diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c index 9c0547d77af3..15555c95cebc 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c @@ -184,9 +184,6 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, */ VM_WARN_ON(pte_hw_valid(*ptep) && !pte_protnone(*ptep)); - /* Add the pte bit when trying to set a pte */ - pte = pte_mkpte(pte); - /* Note: mm->context.id might not yet have been assigned as * this context might not have been activated yet when this * is called. @@ -266,8 +263,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_ pmd_t *pmd = pmd_off(mm, addr); pte_basic_t val; pte_basic_t *entry = &ptep->pte; - int num = is_hugepd(*((hugepd_t *)pmd)) ? 1 : SZ_512K / SZ_4K; - int i; + int num, i; /* * Make sure hardware valid bit is not set. We don't do @@ -275,11 +271,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_ */ VM_WARN_ON(pte_hw_valid(*ptep) && !pte_protnone(*ptep)); - pte = pte_mkpte(pte); - pte = set_pte_filter(pte); val = pte_val(pte); + + num = number_of_cells_per_pte(pmd, val, 1); + for (i = 0; i < num; i++, entry++, val += SZ_4K) *entry = val; } diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 6eb4eab79385..079159e97bca 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -123,11 +123,11 @@ static void __init __mapin_ram_chunk(unsigned long offset, unsigned long top) void __init mapin_ram(void) { - struct memblock_region *reg; + phys_addr_t base, end; + u64 i; - for_each_memblock(memory, reg) { - phys_addr_t base = reg->base; - phys_addr_t top = min(base + reg->size, total_lowmem); + for_each_mem_range(i, &base, &end) { + phys_addr_t top = min(end, total_lowmem); if (base >= top) continue; diff --git a/arch/powerpc/mm/ptdump/8xx.c b/arch/powerpc/mm/ptdump/8xx.c index 8a797dcbf475..86da2a669680 100644 --- a/arch/powerpc/mm/ptdump/8xx.c +++ b/arch/powerpc/mm/ptdump/8xx.c @@ -11,8 +11,13 @@ static const struct flag_info flag_array[] = { { +#ifdef CONFIG_PPC_16K_PAGES .mask = _PAGE_HUGE, .val = _PAGE_HUGE, +#else + .mask = _PAGE_SPS, + .val = _PAGE_SPS, +#endif .set = "huge", .clear = " ", }, { diff --git a/arch/powerpc/mm/ptdump/bats.c b/arch/powerpc/mm/ptdump/bats.c index e29b338d499f..c4c628b03cf8 100644 --- a/arch/powerpc/mm/ptdump/bats.c +++ b/arch/powerpc/mm/ptdump/bats.c @@ -12,62 +12,6 @@ #include "ptdump.h" -static char *pp_601(int k, int pp) -{ - if (pp == 0) - return k ? " " : "rwx"; - if (pp == 1) - return k ? "r x" : "rwx"; - if (pp == 2) - return "rwx"; - return "r x"; -} - -static void bat_show_601(struct seq_file *m, int idx, u32 lower, u32 upper) -{ - u32 blpi = upper & 0xfffe0000; - u32 k = (upper >> 2) & 3; - u32 pp = upper & 3; - phys_addr_t pbn = PHYS_BAT_ADDR(lower); - u32 bsm = lower & 0x3ff; - u32 size = (bsm + 1) << 17; - - seq_printf(m, "%d: ", idx); - if (!(lower & 0x40)) { - seq_puts(m, " -\n"); - return; - } - - seq_printf(m, "0x%08x-0x%08x ", blpi, blpi + size - 1); -#ifdef CONFIG_PHYS_64BIT - seq_printf(m, "0x%016llx ", pbn); -#else - seq_printf(m, "0x%08x ", pbn); -#endif - pt_dump_size(m, size); - - seq_printf(m, "Kernel %s User %s", pp_601(k & 2, pp), pp_601(k & 1, pp)); - - seq_puts(m, lower & _PAGE_WRITETHRU ? "w " : " "); - seq_puts(m, lower & _PAGE_NO_CACHE ? "i " : " "); - seq_puts(m, lower & _PAGE_COHERENT ? "m " : " "); - seq_puts(m, "\n"); -} - -#define BAT_SHOW_601(_m, _n, _l, _u) bat_show_601(_m, _n, mfspr(_l), mfspr(_u)) - -static int bats_show_601(struct seq_file *m, void *v) -{ - seq_puts(m, "---[ Block Address Translation ]---\n"); - - BAT_SHOW_601(m, 0, SPRN_IBAT0L, SPRN_IBAT0U); - BAT_SHOW_601(m, 1, SPRN_IBAT1L, SPRN_IBAT1U); - BAT_SHOW_601(m, 2, SPRN_IBAT2L, SPRN_IBAT2U); - BAT_SHOW_601(m, 3, SPRN_IBAT3L, SPRN_IBAT3U); - - return 0; -} - static void bat_show_603(struct seq_file *m, int idx, u32 lower, u32 upper, bool is_d) { u32 bepi = upper & 0xfffe0000; @@ -146,9 +90,6 @@ static int bats_show_603(struct seq_file *m, void *v) static int bats_open(struct inode *inode, struct file *file) { - if (IS_ENABLED(CONFIG_PPC_BOOK3S_601)) - return single_open(file, bats_show_601, NULL); - return single_open(file, bats_show_603, NULL); } diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 78d61f97371e..e809cb5a1631 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -475,7 +475,6 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, case BPF_JMP | BPF_JSET | BPF_K: case BPF_JMP | BPF_JSET | BPF_X: true_cond = COND_NE; - fallthrough; cond_branch: /* same targets, can avoid doing the test :) */ if (filter[i].jt == filter[i].jf) { diff --git a/arch/powerpc/oprofile/cell/spu_task_sync.c b/arch/powerpc/oprofile/cell/spu_task_sync.c index df59d0bb121f..489f993100d5 100644 --- a/arch/powerpc/oprofile/cell/spu_task_sync.c +++ b/arch/powerpc/oprofile/cell/spu_task_sync.c @@ -572,7 +572,7 @@ void spu_sync_buffer(int spu_num, unsigned int *samples, * samples are recorded. * No big deal -- so we just drop a few samples. */ - pr_debug("SPU_PROF: No cached SPU contex " + pr_debug("SPU_PROF: No cached SPU context " "for SPU #%d. Dropping samples.\n", spu_num); goto out; } diff --git a/arch/powerpc/perf/hv-gpci-requests.h b/arch/powerpc/perf/hv-gpci-requests.h index e608f9db12dd..8965b4463d43 100644 --- a/arch/powerpc/perf/hv-gpci-requests.h +++ b/arch/powerpc/perf/hv-gpci-requests.h @@ -95,7 +95,7 @@ REQUEST(__field(0, 8, partition_id) #define REQUEST_NAME system_performance_capabilities #define REQUEST_NUM 0x40 -#define REQUEST_IDX_KIND "starting_index=0xffffffffffffffff" +#define REQUEST_IDX_KIND "starting_index=0xffffffff" #include I(REQUEST_BEGIN) REQUEST(__field(0, 1, perf_collect_privileged) __field(0x1, 1, capability_mask) @@ -223,7 +223,7 @@ REQUEST(__field(0, 2, partition_id) #define REQUEST_NAME system_hypervisor_times #define REQUEST_NUM 0xF0 -#define REQUEST_IDX_KIND "starting_index=0xffffffffffffffff" +#define REQUEST_IDX_KIND "starting_index=0xffffffff" #include I(REQUEST_BEGIN) REQUEST(__count(0, 8, time_spent_to_dispatch_virtual_processors) __count(0x8, 8, time_spent_processing_virtual_processor_timers) @@ -234,7 +234,7 @@ REQUEST(__count(0, 8, time_spent_to_dispatch_virtual_processors) #define REQUEST_NAME system_tlbie_count_and_time #define REQUEST_NUM 0xF4 -#define REQUEST_IDX_KIND "starting_index=0xffffffffffffffff" +#define REQUEST_IDX_KIND "starting_index=0xffffffff" #include I(REQUEST_BEGIN) REQUEST(__count(0, 8, tlbie_instructions_issued) /* diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c index 6884d16ec19b..d48413e28c39 100644 --- a/arch/powerpc/perf/hv-gpci.c +++ b/arch/powerpc/perf/hv-gpci.c @@ -48,6 +48,8 @@ EVENT_DEFINE_RANGE_FORMAT(length, config1, 24, 31); /* u32, byte offset */ EVENT_DEFINE_RANGE_FORMAT(offset, config1, 32, 63); +static cpumask_t hv_gpci_cpumask; + static struct attribute *format_attrs[] = { &format_attr_request.attr, &format_attr_starting_index.attr, @@ -94,7 +96,15 @@ static ssize_t kernel_version_show(struct device *dev, return sprintf(page, "0x%x\n", COUNTER_INFO_VERSION_CURRENT); } +static ssize_t cpumask_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return cpumap_print_to_pagebuf(true, buf, &hv_gpci_cpumask); +} + static DEVICE_ATTR_RO(kernel_version); +static DEVICE_ATTR_RO(cpumask); + HV_CAPS_ATTR(version, "0x%x\n"); HV_CAPS_ATTR(ga, "%d\n"); HV_CAPS_ATTR(expanded, "%d\n"); @@ -111,6 +121,15 @@ static struct attribute *interface_attrs[] = { NULL, }; +static struct attribute *cpumask_attrs[] = { + &dev_attr_cpumask.attr, + NULL, +}; + +static struct attribute_group cpumask_attr_group = { + .attrs = cpumask_attrs, +}; + static struct attribute_group interface_group = { .name = "interface", .attrs = interface_attrs, @@ -120,20 +139,12 @@ static const struct attribute_group *attr_groups[] = { &format_group, &event_group, &interface_group, + &cpumask_attr_group, NULL, }; -#define HGPCI_REQ_BUFFER_SIZE 4096 -#define HGPCI_MAX_DATA_BYTES \ - (HGPCI_REQ_BUFFER_SIZE - sizeof(struct hv_get_perf_counter_info_params)) - static DEFINE_PER_CPU(char, hv_gpci_reqb[HGPCI_REQ_BUFFER_SIZE]) __aligned(sizeof(uint64_t)); -struct hv_gpci_request_buffer { - struct hv_get_perf_counter_info_params params; - uint8_t bytes[HGPCI_MAX_DATA_BYTES]; -} __packed; - static unsigned long single_gpci_request(u32 req, u32 starting_index, u16 secondary_index, u8 version_in, u32 offset, u8 length, u64 *value) @@ -275,6 +286,45 @@ static struct pmu h_gpci_pmu = { .capabilities = PERF_PMU_CAP_NO_EXCLUDE, }; +static int ppc_hv_gpci_cpu_online(unsigned int cpu) +{ + if (cpumask_empty(&hv_gpci_cpumask)) + cpumask_set_cpu(cpu, &hv_gpci_cpumask); + + return 0; +} + +static int ppc_hv_gpci_cpu_offline(unsigned int cpu) +{ + int target; + + /* Check if exiting cpu is used for collecting gpci events */ + if (!cpumask_test_and_clear_cpu(cpu, &hv_gpci_cpumask)) + return 0; + + /* Find a new cpu to collect gpci events */ + target = cpumask_last(cpu_active_mask); + + if (target < 0 || target >= nr_cpu_ids) { + pr_err("hv_gpci: CPU hotplug init failed\n"); + return -1; + } + + /* Migrate gpci events to the new target */ + cpumask_set_cpu(target, &hv_gpci_cpumask); + perf_pmu_migrate_context(&h_gpci_pmu, cpu, target); + + return 0; +} + +static int hv_gpci_cpu_hotplug_init(void) +{ + return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_HV_GPCI_ONLINE, + "perf/powerpc/hv_gcpi:online", + ppc_hv_gpci_cpu_online, + ppc_hv_gpci_cpu_offline); +} + static int hv_gpci_init(void) { int r; @@ -295,6 +345,11 @@ static int hv_gpci_init(void) return -ENODEV; } + /* init cpuhotplug */ + r = hv_gpci_cpu_hotplug_init(); + if (r) + return r; + /* sampling not supported */ h_gpci_pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT; diff --git a/arch/powerpc/perf/hv-gpci.h b/arch/powerpc/perf/hv-gpci.h index a3053eda5dcc..4d108262bed7 100644 --- a/arch/powerpc/perf/hv-gpci.h +++ b/arch/powerpc/perf/hv-gpci.h @@ -2,33 +2,6 @@ #ifndef LINUX_POWERPC_PERF_HV_GPCI_H_ #define LINUX_POWERPC_PERF_HV_GPCI_H_ -#include <linux/types.h> - -/* From the document "H_GetPerformanceCounterInfo Interface" v1.07 */ - -/* H_GET_PERF_COUNTER_INFO argument */ -struct hv_get_perf_counter_info_params { - __be32 counter_request; /* I */ - __be32 starting_index; /* IO */ - __be16 secondary_index; /* IO */ - __be16 returned_values; /* O */ - __be32 detail_rc; /* O, only needed when called via *_norets() */ - - /* - * O, size each of counter_value element in bytes, only set for version - * >= 0x3 - */ - __be16 cv_element_size; - - /* I, 0 (zero) for versions < 0x3 */ - __u8 counter_info_version_in; - - /* O, 0 (zero) if version < 0x3. Must be set to 0 when making hcall */ - __u8 counter_info_version_out; - __u8 reserved[0xC]; - __u8 counter_value[]; -} __packed; - /* * counter info version => fw version/reference (spec version) * diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 62d0b54086f8..9ed4fcccf8a9 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -1426,8 +1426,6 @@ static void trace_imc_event_del(struct perf_event *event, int flags) static int trace_imc_event_init(struct perf_event *event) { - struct task_struct *target; - if (event->attr.type != event->pmu->type) return -ENOENT; @@ -1458,7 +1456,6 @@ static int trace_imc_event_init(struct perf_event *event) mutex_unlock(&imc_global_refc.lock); event->hw.idx = -1; - target = event->hw.target; event->pmu->task_ctx_nr = perf_hw_context; event->destroy = reset_global_refc; diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c index 964437adec18..2848904df638 100644 --- a/arch/powerpc/perf/isa207-common.c +++ b/arch/powerpc/perf/isa207-common.c @@ -288,6 +288,15 @@ int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp) mask |= CNST_PMC_MASK(pmc); value |= CNST_PMC_VAL(pmc); + + /* + * PMC5 and PMC6 are used to count cycles and instructions and + * they do not support most of the constraint bits. Add a check + * to exclude PMC5/6 from most of the constraints except for + * EBB/BHRB. + */ + if (pmc >= 5) + goto ebb_bhrb; } if (pmc <= 4) { @@ -357,6 +366,7 @@ int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp) } } +ebb_bhrb: if (!pmc && ebb) /* EBB events must specify the PMC */ return -1; diff --git a/arch/powerpc/perf/isa207-common.h b/arch/powerpc/perf/isa207-common.h index 044de65e96b9..7025de5e60e7 100644 --- a/arch/powerpc/perf/isa207-common.h +++ b/arch/powerpc/perf/isa207-common.h @@ -13,6 +13,8 @@ #include <asm/firmware.h> #include <asm/cputable.h> +#include "internal.h" + #define EVENT_EBB_MASK 1ull #define EVENT_EBB_SHIFT PERF_EVENT_CONFIG_EBB_SHIFT #define EVENT_BHRB_MASK 1ull diff --git a/arch/powerpc/perf/power10-pmu.c b/arch/powerpc/perf/power10-pmu.c index 83148656b524..9dbe8f9b89b4 100644 --- a/arch/powerpc/perf/power10-pmu.c +++ b/arch/powerpc/perf/power10-pmu.c @@ -9,7 +9,6 @@ #define pr_fmt(fmt) "power10-pmu: " fmt #include "isa207-common.h" -#include "internal.h" /* * Raw event encoding for Power10: diff --git a/arch/powerpc/perf/power5+-pmu.c b/arch/powerpc/perf/power5+-pmu.c index a62b2cd7914f..3e64b4a1511f 100644 --- a/arch/powerpc/perf/power5+-pmu.c +++ b/arch/powerpc/perf/power5+-pmu.c @@ -10,6 +10,8 @@ #include <asm/reg.h> #include <asm/cputable.h> +#include "internal.h" + /* * Bits in event code for POWER5+ (POWER5 GS) and POWER5++ (POWER5 GS DD3) */ diff --git a/arch/powerpc/perf/power5-pmu.c b/arch/powerpc/perf/power5-pmu.c index 8732b587cf71..017bb19b73fb 100644 --- a/arch/powerpc/perf/power5-pmu.c +++ b/arch/powerpc/perf/power5-pmu.c @@ -10,6 +10,8 @@ #include <asm/reg.h> #include <asm/cputable.h> +#include "internal.h" + /* * Bits in event code for POWER5 (not POWER5++) */ diff --git a/arch/powerpc/perf/power6-pmu.c b/arch/powerpc/perf/power6-pmu.c index 0e318cf87129..189974478e9f 100644 --- a/arch/powerpc/perf/power6-pmu.c +++ b/arch/powerpc/perf/power6-pmu.c @@ -10,6 +10,8 @@ #include <asm/reg.h> #include <asm/cputable.h> +#include "internal.h" + /* * Bits in event code for POWER6 */ diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c index 5e0bf09cf077..bacfab104a1a 100644 --- a/arch/powerpc/perf/power7-pmu.c +++ b/arch/powerpc/perf/power7-pmu.c @@ -10,6 +10,8 @@ #include <asm/reg.h> #include <asm/cputable.h> +#include "internal.h" + /* * Bits in event code for POWER7 */ diff --git a/arch/powerpc/perf/ppc970-pmu.c b/arch/powerpc/perf/ppc970-pmu.c index d35223fb112c..7d78df97f272 100644 --- a/arch/powerpc/perf/ppc970-pmu.c +++ b/arch/powerpc/perf/ppc970-pmu.c @@ -9,6 +9,8 @@ #include <asm/reg.h> #include <asm/cputable.h> +#include "internal.h" + /* * Bits in event code for PPC970 */ diff --git a/arch/powerpc/platforms/44x/machine_check.c b/arch/powerpc/platforms/44x/machine_check.c index 90ad6ac529d2..a5c898bb9bab 100644 --- a/arch/powerpc/platforms/44x/machine_check.c +++ b/arch/powerpc/platforms/44x/machine_check.c @@ -7,6 +7,7 @@ #include <linux/ptrace.h> #include <asm/reg.h> +#include <asm/cacheflush.h> int machine_check_440A(struct pt_regs *regs) { diff --git a/arch/powerpc/platforms/44x/ppc476.c b/arch/powerpc/platforms/44x/ppc476.c index cba83eee685c..07f7e3ce67b5 100644 --- a/arch/powerpc/platforms/44x/ppc476.c +++ b/arch/powerpc/platforms/44x/ppc476.c @@ -86,8 +86,7 @@ static void __noreturn avr_reset_system(char *cmd) avr_halt_system(AVR_PWRCTL_RESET); } -static int avr_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int avr_probe(struct i2c_client *client) { avr_i2c_client = client; ppc_md.restart = avr_reset_system; @@ -104,7 +103,7 @@ static struct i2c_driver avr_driver = { .driver = { .name = "akebono-avr", }, - .probe = avr_probe, + .probe_new = avr_probe, .id_table = avr_id, }; diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index 0967bdfb1691..409481016928 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -142,7 +142,7 @@ static int mcu_gpiochip_remove(struct mcu *mcu) return 0; } -static int mcu_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int mcu_probe(struct i2c_client *client) { struct mcu *mcu; int ret; @@ -221,7 +221,7 @@ static struct i2c_driver mcu_driver = { .name = "mcu-mpc8349emitx", .of_match_table = mcu_of_match_table, }, - .probe = mcu_probe, + .probe_new = mcu_probe, .remove = mcu_remove, .id_table = mcu_ids, }; diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index fda108bae95f..c6df294054fe 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -112,7 +112,7 @@ static void mpc85xx_take_timebase(void) local_irq_restore(flags); } -static void smp_85xx_mach_cpu_die(void) +static void smp_85xx_cpu_offline_self(void) { unsigned int cpu = smp_processor_id(); @@ -506,7 +506,7 @@ void __init mpc85xx_smp_init(void) if (qoriq_pm_ops) { smp_85xx_ops.give_timebase = mpc85xx_give_timebase; smp_85xx_ops.take_timebase = mpc85xx_take_timebase; - ppc_md.cpu_die = smp_85xx_mach_cpu_die; + smp_85xx_ops.cpu_offline_self = smp_85xx_cpu_offline_self; smp_85xx_ops.cpu_die = qoriq_cpu_kill; } #endif diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index fb7515b4fa9c..7a5e8f4541e3 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -199,21 +199,6 @@ source "drivers/cpuidle/Kconfig" endmenu -config PPC601_SYNC_FIX - bool "Workarounds for PPC601 bugs" - depends on PPC_BOOK3S_601 && PPC_PMAC - default y - help - Some versions of the PPC601 (the first PowerPC chip) have bugs which - mean that extra synchronization instructions are required near - certain instructions, typically those that make major changes to the - CPU state. These extra instructions reduce performance slightly. - If you say N here, these extra instructions will not be included, - resulting in a kernel which will run faster but may not run at all - on some systems with the PPC601 chip. - - If in doubt, say Y here. - config TAU bool "On-chip CPU temperature sensor support" depends on PPC_BOOK3S_32 @@ -223,12 +208,11 @@ config TAU temperature within 2-4 degrees Celsius. This option shows the current on-die temperature in /proc/cpuinfo if the cpu supports it. - Unfortunately, on some chip revisions, this sensor is very inaccurate - and in many cases, does not work at all, so don't assume the cpu - temp is actually what /proc/cpuinfo says it is. + Unfortunately, this sensor is very inaccurate when uncalibrated, so + don't assume the cpu temp is actually what /proc/cpuinfo says it is. config TAU_INT - bool "Interrupt driven TAU driver (DANGEROUS)" + bool "Interrupt driven TAU driver (EXPERIMENTAL)" depends on TAU help The TAU supports an interrupt driven mode which causes an interrupt @@ -236,12 +220,7 @@ config TAU_INT to get notified the temp has exceeded a range. With this option off, a timer is used to re-check the temperature periodically. - However, on some cpus it appears that the TAU interrupt hardware - is buggy and can cause a situation which would lead unexplained hard - lockups. - - Unless you are extending the TAU driver, or enjoy kernel/hardware - debugging, leave this option off. + If in doubt, say N here. config TAU_AVERAGE bool "Average high and low temp" diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 1dc9d3c81872..c194c4ae8bc7 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -20,7 +20,7 @@ choice depends on PPC32 help There are five families of 32 bit PowerPC chips supported. - The most common ones are the desktop and server CPUs (601, 603, + 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 @@ -30,7 +30,7 @@ choice If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx. config PPC_BOOK3S_6xx - bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx except 601" + bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx" select PPC_BOOK3S_32 select PPC_FPU select PPC_HAVE_PMU_SUPPORT @@ -38,13 +38,6 @@ config PPC_BOOK3S_6xx select PPC_HAVE_KUAP select HAVE_ARCH_VMAP_STACK if !ADB_PMU -config PPC_BOOK3S_601 - bool "PowerPC 601" - select PPC_BOOK3S_32 - select PPC_FPU - select PPC_HAVE_KUAP - select HAVE_ARCH_VMAP_STACK - config PPC_85xx bool "Freescale 85xx" select E500 @@ -490,13 +483,12 @@ endmenu config VDSO32 def_bool y - depends on PPC32 || CPU_BIG_ENDIAN + depends on PPC32 || COMPAT help This symbol controls whether we build the 32-bit VDSO. We obviously want to do that if we're building a 32-bit kernel. If we're building - a 64-bit kernel then we only want a 32-bit VDSO if we're building for - big endian. That is because the only little endian configuration we - support is ppc64le which is 64-bit only. + a 64-bit kernel then we only want a 32-bit VDSO if we're also enabling + COMPAT. choice prompt "Endianness selection" diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index 15437abe1f6d..b95c3380d2b5 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -147,7 +147,8 @@ static void __noreturn mpc7448_hpc2_restart(char *cmd) local_irq_disable(); /* Set exception prefix high - to the firmware */ - _nmask_and_or_msr(0, MSR_IP); + mtmsr(mfmsr() | MSR_IP); + isync(); for (;;) ; /* Spin until reset happens */ } diff --git a/arch/powerpc/platforms/embedded6xx/storcenter.c b/arch/powerpc/platforms/embedded6xx/storcenter.c index ed1914dd34bb..e346ddcef45e 100644 --- a/arch/powerpc/platforms/embedded6xx/storcenter.c +++ b/arch/powerpc/platforms/embedded6xx/storcenter.c @@ -101,7 +101,8 @@ static void __noreturn storcenter_restart(char *cmd) local_irq_disable(); /* Set exception prefix high - to the firmware */ - _nmask_and_or_msr(0, MSR_IP); + mtmsr(mfmsr() | MSR_IP); + isync(); /* Wait for reset to happen */ for (;;) ; diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index 16a52afdb76e..0d715db434dc 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h @@ -34,7 +34,7 @@ extern void pmac_check_ht_link(void); extern void pmac_setup_smp(void); extern int psurge_secondary_virq; -extern void low_cpu_die(void) __attribute__((noreturn)); +extern void low_cpu_offline_self(void) __attribute__((noreturn)); extern int pmac_nvram_init(void); extern void pmac_pic_init(void); diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index f002b0fa69b8..2e2cc0c75d87 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -284,7 +284,7 @@ static void __init pmac_setup_arch(void) /* 604, G3, G4 etc. */ loops_per_jiffy = *fp / HZ; else - /* 601, 603, etc. */ + /* 603, etc. */ loops_per_jiffy = *fp / (2 * HZ); of_node_put(cpu); break; diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S index f9a680fdd9c4..7e0f8ba6e54a 100644 --- a/arch/powerpc/platforms/powermac/sleep.S +++ b/arch/powerpc/platforms/powermac/sleep.S @@ -201,8 +201,8 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) addi r3,r3,sleep_storage@l stw r5,0(r3) - .globl low_cpu_die -low_cpu_die: + .globl low_cpu_offline_self +low_cpu_offline_self: /* Flush & disable all caches */ bl flush_disable_caches @@ -244,7 +244,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450) mtmsr r2 isync b 1b -_ASM_NOKPROBE_SYMBOL(low_cpu_die) +_ASM_NOKPROBE_SYMBOL(low_cpu_offline_self) /* * Here is the resume code. */ @@ -294,14 +294,7 @@ grackle_wake_up: * we do any r1 memory access as we are not sure they * are in a sane state above the first 256Mb region */ - li r0,16 /* load up segment register values */ - mtctr r0 /* for context 0 */ - lis r3,0x2000 /* Ku = 1, VSID = 0 */ - li r4,0 -3: mtsrin r3,r4 - addi r3,r3,0x111 /* increment VSID */ - addis r4,r4,0x1000 /* address of next segment */ - bdnz 3b + bl load_segment_registers sync isync diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index eb23264910e1..74ebe664b016 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -270,10 +270,6 @@ static void __init smp_psurge_probe(void) int i, ncpus; struct device_node *dn; - /* We don't do SMP on the PPC601 -- paulus */ - if (PVR_VER(mfspr(SPRN_PVR)) == 1) - return; - /* * The powersurge cpu board can be used in the generation * of powermacs that have a socket for an upgradeable cpu card, @@ -920,7 +916,7 @@ static int smp_core99_cpu_disable(void) #ifdef CONFIG_PPC32 -static void pmac_cpu_die(void) +static void pmac_cpu_offline_self(void) { int cpu = smp_processor_id(); @@ -930,12 +926,12 @@ static void pmac_cpu_die(void) generic_set_cpu_dead(cpu); smp_wmb(); mb(); - low_cpu_die(); + low_cpu_offline_self(); } #else /* CONFIG_PPC32 */ -static void pmac_cpu_die(void) +static void pmac_cpu_offline_self(void) { int cpu = smp_processor_id(); @@ -1020,7 +1016,7 @@ void __init pmac_setup_smp(void) #endif /* CONFIG_PPC_PMAC32_PSURGE */ #ifdef CONFIG_HOTPLUG_CPU - ppc_md.cpu_die = pmac_cpu_die; + smp_ops->cpu_offline_self = pmac_cpu_offline_self; #endif } diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 9af8c3b98853..89e22c460ebf 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -38,60 +38,12 @@ static int eeh_event_irq = -EINVAL; -void pnv_pcibios_bus_add_device(struct pci_dev *pdev) +static void pnv_pcibios_bus_add_device(struct pci_dev *pdev) { dev_dbg(&pdev->dev, "EEH: Setting up device\n"); eeh_probe_device(pdev); } -static int pnv_eeh_init(void) -{ - struct pci_controller *hose; - struct pnv_phb *phb; - int max_diag_size = PNV_PCI_DIAG_BUF_SIZE; - - if (!firmware_has_feature(FW_FEATURE_OPAL)) { - pr_warn("%s: OPAL is required !\n", - __func__); - return -EINVAL; - } - - /* Set probe mode */ - eeh_add_flag(EEH_PROBE_MODE_DEV); - - /* - * P7IOC blocks PCI config access to frozen PE, but PHB3 - * doesn't do that. So we have to selectively enable I/O - * prior to collecting error log. - */ - list_for_each_entry(hose, &hose_list, list_node) { - phb = hose->private_data; - - if (phb->model == PNV_PHB_MODEL_P7IOC) - eeh_add_flag(EEH_ENABLE_IO_FOR_LOG); - - if (phb->diag_data_size > max_diag_size) - max_diag_size = phb->diag_data_size; - - /* - * PE#0 should be regarded as valid by EEH core - * if it's not the reserved one. Currently, we - * have the reserved PE#255 and PE#127 for PHB3 - * and P7IOC separately. So we should regard - * PE#0 as valid for PHB3 and P7IOC. - */ - if (phb->ioda.reserved_pe_idx != 0) - eeh_add_flag(EEH_VALID_PE_ZERO); - - break; - } - - eeh_set_pe_aux_size(max_diag_size); - ppc_md.pcibios_bus_add_device = pnv_pcibios_bus_add_device; - - return 0; -} - static irqreturn_t pnv_eeh_event(int irq, void *data) { /* @@ -135,7 +87,7 @@ static ssize_t pnv_eeh_ei_write(struct file *filp, return -EINVAL; /* Retrieve PE */ - pe = eeh_pe_get(hose, pe_no, 0); + pe = eeh_pe_get(hose, pe_no); if (!pe) return -ENODEV; @@ -190,7 +142,7 @@ PNV_EEH_DBGFS_ENTRY(inbB, 0xE10); #endif /* CONFIG_DEBUG_FS */ -void pnv_eeh_enable_phbs(void) +static void pnv_eeh_enable_phbs(void) { struct pci_controller *hose; struct pnv_phb *phb; @@ -354,7 +306,7 @@ static struct eeh_pe *pnv_eeh_get_upstream_pe(struct pci_dev *pdev) if (parent) { struct pnv_ioda_pe *ioda_pe = pnv_ioda_get_pe(parent); - return eeh_pe_get(phb->hose, ioda_pe->pe_number, 0); + return eeh_pe_get(phb->hose, ioda_pe->pe_number); } return NULL; @@ -1406,7 +1358,7 @@ static int pnv_eeh_get_pe(struct pci_controller *hose, } /* Find the PE according to PE# */ - dev_pe = eeh_pe_get(hose, pe_no, 0); + dev_pe = eeh_pe_get(hose, pe_no); if (!dev_pe) return -EEXIST; @@ -1674,7 +1626,6 @@ static int pnv_eeh_restore_config(struct eeh_dev *edev) static struct eeh_ops pnv_eeh_ops = { .name = "powernv", - .init = pnv_eeh_init, .probe = pnv_eeh_probe, .set_option = pnv_eeh_set_option, .get_state = pnv_eeh_get_state, @@ -1715,9 +1666,44 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pnv_pci_fixup_vf_mps); */ static int __init eeh_powernv_init(void) { + int max_diag_size = PNV_PCI_DIAG_BUF_SIZE; + struct pci_controller *hose; + struct pnv_phb *phb; int ret = -EINVAL; - ret = eeh_ops_register(&pnv_eeh_ops); + if (!firmware_has_feature(FW_FEATURE_OPAL)) { + pr_warn("%s: OPAL is required !\n", __func__); + return -EINVAL; + } + + /* Set probe mode */ + eeh_add_flag(EEH_PROBE_MODE_DEV); + + /* + * P7IOC blocks PCI config access to frozen PE, but PHB3 + * doesn't do that. So we have to selectively enable I/O + * prior to collecting error log. + */ + list_for_each_entry(hose, &hose_list, list_node) { + phb = hose->private_data; + + if (phb->model == PNV_PHB_MODEL_P7IOC) + eeh_add_flag(EEH_ENABLE_IO_FOR_LOG); + + if (phb->diag_data_size > max_diag_size) + max_diag_size = phb->diag_data_size; + + break; + } + + /* + * eeh_init() allocates the eeh_pe and its aux data buf so the + * size needs to be set before calling eeh_init(). + */ + eeh_set_pe_aux_size(max_diag_size); + ppc_md.pcibios_bus_add_device = pnv_pcibios_bus_add_device; + + ret = eeh_init(&pnv_eeh_ops); if (!ret) pr_info("EEH: PowerNV platform initialized\n"); else @@ -1725,4 +1711,4 @@ static int __init eeh_powernv_init(void) return ret; } -machine_early_initcall(powernv, eeh_powernv_init); +machine_arch_initcall(powernv, eeh_powernv_init); diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index 345ab062b21a..1ed7c5286487 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -565,7 +565,7 @@ void power7_idle_type(unsigned long type) irq_set_pending_from_srr1(srr1); } -void power7_idle(void) +static void power7_idle(void) { if (!powersave_nap) return; @@ -659,20 +659,6 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on) mmcr0 = mfspr(SPRN_MMCR0); } - if (cpu_has_feature(CPU_FTR_ARCH_31)) { - /* - * POWER10 uses MMCRA (BHRBRD) as BHRB disable bit. - * If the user hasn't asked for the BHRB to be - * written, the value of MMCRA[BHRBRD] is 1. - * On wakeup from stop, MMCRA[BHRBD] will be 0, - * since it is previleged resource and will be lost. - * Thus, if we do not save and restore the MMCRA[BHRBD], - * hardware will be needlessly writing to the BHRB - * in problem mode. - */ - mmcra = mfspr(SPRN_MMCRA); - } - if ((psscr & PSSCR_RL_MASK) >= deep_spr_loss_state) { sprs.lpcr = mfspr(SPRN_LPCR); sprs.hfscr = mfspr(SPRN_HFSCR); @@ -735,10 +721,6 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on) mtspr(SPRN_MMCR0, mmcr0); } - /* Reload MMCRA to restore BHRB disable bit for POWER10 */ - if (cpu_has_feature(CPU_FTR_ARCH_31)) - mtspr(SPRN_MMCRA, mmcra); - /* * DD2.2 and earlier need to set then clear bit 60 in MMCRA * to ensure the PMU starts running. @@ -823,73 +805,6 @@ out: return srr1; } -#ifdef CONFIG_HOTPLUG_CPU -static unsigned long power9_offline_stop(unsigned long psscr) -{ - unsigned long srr1; - -#ifndef CONFIG_KVM_BOOK3S_HV_POSSIBLE - __ppc64_runlatch_off(); - srr1 = power9_idle_stop(psscr, true); - __ppc64_runlatch_on(); -#else - /* - * Tell KVM we're entering idle. - * This does not have to be done in real mode because the P9 MMU - * is independent per-thread. Some steppings share radix/hash mode - * between threads, but in that case KVM has a barrier sync in real - * mode before and after switching between radix and hash. - * - * kvm_start_guest must still be called in real mode though, hence - * the false argument. - */ - local_paca->kvm_hstate.hwthread_state = KVM_HWTHREAD_IN_IDLE; - - __ppc64_runlatch_off(); - srr1 = power9_idle_stop(psscr, false); - __ppc64_runlatch_on(); - - local_paca->kvm_hstate.hwthread_state = KVM_HWTHREAD_IN_KERNEL; - /* Order setting hwthread_state vs. testing hwthread_req */ - smp_mb(); - if (local_paca->kvm_hstate.hwthread_req) - srr1 = idle_kvm_start_guest(srr1); - mtmsr(MSR_KERNEL); -#endif - - return srr1; -} -#endif - -void power9_idle_type(unsigned long stop_psscr_val, - unsigned long stop_psscr_mask) -{ - unsigned long psscr; - unsigned long srr1; - - if (!prep_irq_for_idle_irqsoff()) - return; - - psscr = mfspr(SPRN_PSSCR); - psscr = (psscr & ~stop_psscr_mask) | stop_psscr_val; - - __ppc64_runlatch_off(); - srr1 = power9_idle_stop(psscr, true); - __ppc64_runlatch_on(); - - fini_irq_for_idle_irqsoff(); - - irq_set_pending_from_srr1(srr1); -} - -/* - * Used for ppc_md.power_save which needs a function with no parameters - */ -void power9_idle(void) -{ - power9_idle_type(pnv_default_stop_val, pnv_default_stop_mask); -} - #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE /* * This is used in working around bugs in thread reconfiguration @@ -962,6 +877,198 @@ void pnv_power9_force_smt4_release(void) EXPORT_SYMBOL_GPL(pnv_power9_force_smt4_release); #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ +struct p10_sprs { + /* + * SPRs that get lost in shallow states: + * + * P10 loses CR, LR, CTR, FPSCR, VSCR, XER, TAR, SPRG2, and HSPRG1 + * isa300 idle routines restore CR, LR. + * CTR is volatile + * idle thread doesn't use FP or VEC + * kernel doesn't use TAR + * HSPRG1 is only live in HV interrupt entry + * SPRG2 is only live in KVM guests, KVM handles it. + */ +}; + +static unsigned long power10_idle_stop(unsigned long psscr, bool mmu_on) +{ + int cpu = raw_smp_processor_id(); + int first = cpu_first_thread_sibling(cpu); + unsigned long *state = &paca_ptrs[first]->idle_state; + unsigned long core_thread_mask = (1UL << threads_per_core) - 1; + unsigned long srr1; + unsigned long pls; +// struct p10_sprs sprs = {}; /* avoid false used-uninitialised */ + bool sprs_saved = false; + + if (!(psscr & (PSSCR_EC|PSSCR_ESL))) { + /* EC=ESL=0 case */ + + BUG_ON(!mmu_on); + + /* + * Wake synchronously. SRESET via xscom may still cause + * a 0x100 powersave wakeup with SRR1 reason! + */ + srr1 = isa300_idle_stop_noloss(psscr); /* go idle */ + if (likely(!srr1)) + return 0; + + /* + * Registers not saved, can't recover! + * This would be a hardware bug + */ + BUG_ON((srr1 & SRR1_WAKESTATE) != SRR1_WS_NOLOSS); + + goto out; + } + + /* EC=ESL=1 case */ + if ((psscr & PSSCR_RL_MASK) >= deep_spr_loss_state) { + /* XXX: save SPRs for deep state loss here. */ + + sprs_saved = true; + + atomic_start_thread_idle(); + } + + srr1 = isa300_idle_stop_mayloss(psscr); /* go idle */ + + psscr = mfspr(SPRN_PSSCR); + + WARN_ON_ONCE(!srr1); + WARN_ON_ONCE(mfmsr() & (MSR_IR|MSR_DR)); + + if (unlikely((srr1 & SRR1_WAKEMASK_P8) == SRR1_WAKEHMI)) + hmi_exception_realmode(NULL); + + /* + * On POWER10, SRR1 bits do not match exactly as expected. + * SRR1_WS_GPRLOSS (10b) can also result in SPR loss, so + * just always test PSSCR for SPR/TB state loss. + */ + pls = (psscr & PSSCR_PLS) >> PSSCR_PLS_SHIFT; + if (likely(pls < deep_spr_loss_state)) { + if (sprs_saved) + atomic_stop_thread_idle(); + goto out; + } + + /* HV state loss */ + BUG_ON(!sprs_saved); + + atomic_lock_thread_idle(); + + if ((*state & core_thread_mask) != 0) + goto core_woken; + + /* XXX: restore per-core SPRs here */ + + if (pls >= pnv_first_tb_loss_level) { + /* TB loss */ + if (opal_resync_timebase() != OPAL_SUCCESS) + BUG(); + } + + /* + * isync after restoring shared SPRs and before unlocking. Unlock + * only contains hwsync which does not necessarily do the right + * thing for SPRs. + */ + isync(); + +core_woken: + atomic_unlock_and_stop_thread_idle(); + + /* XXX: restore per-thread SPRs here */ + + if (!radix_enabled()) + __slb_restore_bolted_realmode(); + +out: + if (mmu_on) + mtmsr(MSR_KERNEL); + + return srr1; +} + +#ifdef CONFIG_HOTPLUG_CPU +static unsigned long arch300_offline_stop(unsigned long psscr) +{ + unsigned long srr1; + +#ifndef CONFIG_KVM_BOOK3S_HV_POSSIBLE + __ppc64_runlatch_off(); + if (cpu_has_feature(CPU_FTR_ARCH_31)) + srr1 = power10_idle_stop(psscr, true); + else + srr1 = power9_idle_stop(psscr, true); + __ppc64_runlatch_on(); +#else + /* + * Tell KVM we're entering idle. + * This does not have to be done in real mode because the P9 MMU + * is independent per-thread. Some steppings share radix/hash mode + * between threads, but in that case KVM has a barrier sync in real + * mode before and after switching between radix and hash. + * + * kvm_start_guest must still be called in real mode though, hence + * the false argument. + */ + local_paca->kvm_hstate.hwthread_state = KVM_HWTHREAD_IN_IDLE; + + __ppc64_runlatch_off(); + if (cpu_has_feature(CPU_FTR_ARCH_31)) + srr1 = power10_idle_stop(psscr, false); + else + srr1 = power9_idle_stop(psscr, false); + __ppc64_runlatch_on(); + + local_paca->kvm_hstate.hwthread_state = KVM_HWTHREAD_IN_KERNEL; + /* Order setting hwthread_state vs. testing hwthread_req */ + smp_mb(); + if (local_paca->kvm_hstate.hwthread_req) + srr1 = idle_kvm_start_guest(srr1); + mtmsr(MSR_KERNEL); +#endif + + return srr1; +} +#endif + +void arch300_idle_type(unsigned long stop_psscr_val, + unsigned long stop_psscr_mask) +{ + unsigned long psscr; + unsigned long srr1; + + if (!prep_irq_for_idle_irqsoff()) + return; + + psscr = mfspr(SPRN_PSSCR); + psscr = (psscr & ~stop_psscr_mask) | stop_psscr_val; + + __ppc64_runlatch_off(); + if (cpu_has_feature(CPU_FTR_ARCH_31)) + srr1 = power10_idle_stop(psscr, true); + else + srr1 = power9_idle_stop(psscr, true); + __ppc64_runlatch_on(); + + fini_irq_for_idle_irqsoff(); + + irq_set_pending_from_srr1(srr1); +} + +/* + * Used for ppc_md.power_save which needs a function with no parameters + */ +static void arch300_idle(void) +{ + arch300_idle_type(pnv_default_stop_val, pnv_default_stop_mask); +} + #ifdef CONFIG_HOTPLUG_CPU void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 lpcr_val) @@ -995,7 +1102,7 @@ unsigned long pnv_cpu_offline(unsigned int cpu) psscr = mfspr(SPRN_PSSCR); psscr = (psscr & ~pnv_deepest_stop_psscr_mask) | pnv_deepest_stop_psscr_val; - srr1 = power9_offline_stop(psscr); + srr1 = arch300_offline_stop(psscr); } else if (cpu_has_feature(CPU_FTR_ARCH_206) && power7_offline_type) { srr1 = power7_offline(); } else { @@ -1093,11 +1200,15 @@ int validate_psscr_val_mask(u64 *psscr_val, u64 *psscr_mask, u32 flags) * @dt_idle_states: Number of idle state entries * Returns 0 on success */ -static void __init pnv_power9_idle_init(void) +static void __init pnv_arch300_idle_init(void) { u64 max_residency_ns = 0; int i; + /* stop is not really architected, we only have p9,p10 drivers */ + if (!pvr_version_is(PVR_POWER10) && !pvr_version_is(PVR_POWER9)) + return; + /* * pnv_deepest_stop_{val,mask} should be set to values corresponding to * the deepest stop state. @@ -1112,6 +1223,11 @@ static void __init pnv_power9_idle_init(void) struct pnv_idle_states_t *state = &pnv_idle_states[i]; u64 psscr_rl = state->psscr_val & PSSCR_RL_MASK; + /* No deep loss driver implemented for POWER10 yet */ + if (pvr_version_is(PVR_POWER10) && + state->flags & (OPAL_PM_TIMEBASE_STOP|OPAL_PM_LOSE_FULL_CONTEXT)) + continue; + if ((state->flags & OPAL_PM_TIMEBASE_STOP) && (pnv_first_tb_loss_level > psscr_rl)) pnv_first_tb_loss_level = psscr_rl; @@ -1162,7 +1278,7 @@ static void __init pnv_power9_idle_init(void) if (unlikely(!default_stop_found)) { pr_warn("cpuidle-powernv: No suitable default stop state found. Disabling platform idle.\n"); } else { - ppc_md.power_save = power9_idle; + ppc_md.power_save = arch300_idle; pr_info("cpuidle-powernv: Default stop: psscr = 0x%016llx,mask=0x%016llx\n", pnv_default_stop_val, pnv_default_stop_mask); } @@ -1224,7 +1340,7 @@ static void __init pnv_probe_idle_states(void) } if (cpu_has_feature(CPU_FTR_ARCH_300)) - pnv_power9_idle_init(); + pnv_arch300_idle_init(); for (i = 0; i < nr_pnv_idle_states; i++) supported_cpuidle_states |= pnv_idle_states[i].flags; @@ -1295,7 +1411,7 @@ static int pnv_parse_cpuidle_dt(void) for (i = 0; i < nr_idle_states; i++) pnv_idle_states[i].residency_ns = temp_u32[i]; - /* For power9 */ + /* For power9 and later */ if (cpu_has_feature(CPU_FTR_ARCH_300)) { /* Read pm_crtl_val */ if (of_property_read_u64_array(np, "ibm,cpu-idle-state-psscr", @@ -1358,8 +1474,8 @@ static int __init pnv_init_idle_states(void) if (!cpu_has_feature(CPU_FTR_ARCH_300)) { /* P7/P8 nap */ p->thread_idle_state = PNV_THREAD_RUNNING; - } else { - /* P9 stop */ + } else if (pvr_version_is(PVR_POWER9)) { + /* P9 stop workarounds */ #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE p->requested_psscr = 0; atomic_set(&p->dont_stop, 0); diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c index 13b369d2cc45..6828108486f8 100644 --- a/arch/powerpc/platforms/powernv/memtrace.c +++ b/arch/powerpc/platforms/powernv/memtrace.c @@ -224,7 +224,7 @@ static int memtrace_online(void) ent->mem = 0; } - if (add_memory(ent->nid, ent->start, ent->size)) { + if (add_memory(ent->nid, ent->start, ent->size, MHP_NONE)) { pr_err("Failed to add trace memory to node %d\n", ent->nid); ret += 1; diff --git a/arch/powerpc/platforms/powernv/ocxl.c b/arch/powerpc/platforms/powernv/ocxl.c index 8c65aacda9c8..ecdad219d704 100644 --- a/arch/powerpc/platforms/powernv/ocxl.c +++ b/arch/powerpc/platforms/powernv/ocxl.c @@ -2,7 +2,6 @@ // Copyright 2017 IBM Corp. #include <asm/pnv-ocxl.h> #include <asm/opal.h> -#include <asm/xive.h> #include <misc/ocxl-config.h> #include "pci.h" @@ -484,32 +483,3 @@ 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_alloc_xive_irq(u32 *irq, u64 *trigger_addr) -{ - __be64 flags, trigger_page; - s64 rc; - u32 hwirq; - - hwirq = xive_native_alloc_irq(); - if (!hwirq) - return -ENOENT; - - rc = opal_xive_get_irq_info(hwirq, &flags, NULL, &trigger_page, NULL, - NULL); - if (rc || !trigger_page) { - xive_native_free_irq(hwirq); - return -ENOENT; - } - *irq = hwirq; - *trigger_addr = be64_to_cpu(trigger_page); - return 0; - -} -EXPORT_SYMBOL_GPL(pnv_ocxl_alloc_xive_irq); - -void pnv_ocxl_free_xive_irq(u32 irq) -{ - xive_native_free_irq(irq); -} -EXPORT_SYMBOL_GPL(pnv_ocxl_free_xive_irq); diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c index 6dba3b62269f..23571f0b555a 100644 --- a/arch/powerpc/platforms/powernv/opal-core.c +++ b/arch/powerpc/platforms/powernv/opal-core.c @@ -510,7 +510,7 @@ static void __init opalcore_config_init(void) idx = be32_to_cpu(opalc_metadata->region_cnt); if (idx > MAX_PT_LOAD_CNT) { pr_warn("WARNING: OPAL regions count (%d) adjusted to limit (%d)", - MAX_PT_LOAD_CNT, idx); + idx, MAX_PT_LOAD_CNT); idx = MAX_PT_LOAD_CNT; } for (i = 0; i < idx; i++) { diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c index 543c816fa99e..00c5a59d82d9 100644 --- a/arch/powerpc/platforms/powernv/opal-dump.c +++ b/arch/powerpc/platforms/powernv/opal-dump.c @@ -88,9 +88,14 @@ static ssize_t dump_ack_store(struct dump_obj *dump_obj, const char *buf, size_t count) { - dump_send_ack(dump_obj->id); - sysfs_remove_file_self(&dump_obj->kobj, &attr->attr); - kobject_put(&dump_obj->kobj); + /* + * Try to self remove this attribute. If we are successful, + * delete the kobject itself. + */ + if (sysfs_remove_file_self(&dump_obj->kobj, &attr->attr)) { + dump_send_ack(dump_obj->id); + kobject_put(&dump_obj->kobj); + } return count; } @@ -318,15 +323,14 @@ static ssize_t dump_attr_read(struct file *filep, struct kobject *kobj, return count; } -static struct dump_obj *create_dump_obj(uint32_t id, size_t size, - uint32_t type) +static void create_dump_obj(uint32_t id, size_t size, uint32_t type) { struct dump_obj *dump; int rc; dump = kzalloc(sizeof(*dump), GFP_KERNEL); if (!dump) - return NULL; + return; dump->kobj.kset = dump_kset; @@ -346,21 +350,39 @@ static struct dump_obj *create_dump_obj(uint32_t id, size_t size, rc = kobject_add(&dump->kobj, NULL, "0x%x-0x%x", type, id); if (rc) { kobject_put(&dump->kobj); - return NULL; + return; } + /* + * As soon as the sysfs file for this dump is created/activated there is + * a chance the opal_errd daemon (or any userspace) might read and + * acknowledge the dump before kobject_uevent() is called. If that + * happens then there is a potential race between + * dump_ack_store->kobject_put() and kobject_uevent() which leads to a + * use-after-free of a kernfs object resulting in a kernel crash. + * + * To avoid that, we need to take a reference on behalf of the bin file, + * so that our reference remains valid while we call kobject_uevent(). + * We then drop our reference before exiting the function, leaving the + * bin file to drop the last reference (if it hasn't already). + */ + + /* Take a reference for the bin file */ + kobject_get(&dump->kobj); rc = sysfs_create_bin_file(&dump->kobj, &dump->dump_attr); - if (rc) { + if (rc == 0) { + kobject_uevent(&dump->kobj, KOBJ_ADD); + + pr_info("%s: New platform dump. ID = 0x%x Size %u\n", + __func__, dump->id, dump->size); + } else { + /* Drop reference count taken for bin file */ kobject_put(&dump->kobj); - return NULL; } - pr_info("%s: New platform dump. ID = 0x%x Size %u\n", - __func__, dump->id, dump->size); - - kobject_uevent(&dump->kobj, KOBJ_ADD); - - return dump; + /* Drop our reference */ + kobject_put(&dump->kobj); + return; } static irqreturn_t process_dump(int irq, void *data) diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c index 62ef7ad995da..37b380eef41a 100644 --- a/arch/powerpc/platforms/powernv/opal-elog.c +++ b/arch/powerpc/platforms/powernv/opal-elog.c @@ -72,9 +72,14 @@ static ssize_t elog_ack_store(struct elog_obj *elog_obj, const char *buf, size_t count) { - opal_send_ack_elog(elog_obj->id); - sysfs_remove_file_self(&elog_obj->kobj, &attr->attr); - kobject_put(&elog_obj->kobj); + /* + * Try to self remove this attribute. If we are successful, + * delete the kobject itself. + */ + if (sysfs_remove_file_self(&elog_obj->kobj, &attr->attr)) { + opal_send_ack_elog(elog_obj->id); + kobject_put(&elog_obj->kobj); + } return count; } @@ -179,14 +184,14 @@ static ssize_t raw_attr_read(struct file *filep, struct kobject *kobj, return count; } -static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type) +static void create_elog_obj(uint64_t id, size_t size, uint64_t type) { struct elog_obj *elog; int rc; elog = kzalloc(sizeof(*elog), GFP_KERNEL); if (!elog) - return NULL; + return; elog->kobj.kset = elog_kset; @@ -219,18 +224,37 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type) rc = kobject_add(&elog->kobj, NULL, "0x%llx", id); if (rc) { kobject_put(&elog->kobj); - return NULL; + return; } + /* + * As soon as the sysfs file for this elog is created/activated there is + * a chance the opal_errd daemon (or any userspace) might read and + * acknowledge the elog before kobject_uevent() is called. If that + * happens then there is a potential race between + * elog_ack_store->kobject_put() and kobject_uevent() which leads to a + * use-after-free of a kernfs object resulting in a kernel crash. + * + * To avoid that, we need to take a reference on behalf of the bin file, + * so that our reference remains valid while we call kobject_uevent(). + * We then drop our reference before exiting the function, leaving the + * bin file to drop the last reference (if it hasn't already). + */ + + /* Take a reference for the bin file */ + kobject_get(&elog->kobj); rc = sysfs_create_bin_file(&elog->kobj, &elog->raw_attr); - if (rc) { + if (rc == 0) { + kobject_uevent(&elog->kobj, KOBJ_ADD); + } else { + /* Drop the reference taken for the bin file */ kobject_put(&elog->kobj); - return NULL; } - kobject_uevent(&elog->kobj, KOBJ_ADD); + /* Drop our reference */ + kobject_put(&elog->kobj); - return elog; + return; } static irqreturn_t elog_event(int irq, void *data) diff --git a/arch/powerpc/platforms/powernv/opal-msglog.c b/arch/powerpc/platforms/powernv/opal-msglog.c index d26da19a611f..d3b6e135c18b 100644 --- a/arch/powerpc/platforms/powernv/opal-msglog.c +++ b/arch/powerpc/platforms/powernv/opal-msglog.c @@ -12,6 +12,8 @@ #include <linux/types.h> #include <asm/barrier.h> +#include "powernv.h" + /* OPAL in-memory console. Defined in OPAL source at core/console.c */ struct memcons { __be64 magic; diff --git a/arch/powerpc/platforms/powernv/opal-prd.c b/arch/powerpc/platforms/powernv/opal-prd.c index 45f4223a790f..deddaebf8c14 100644 --- a/arch/powerpc/platforms/powernv/opal-prd.c +++ b/arch/powerpc/platforms/powernv/opal-prd.c @@ -24,7 +24,7 @@ #include <linux/uaccess.h> -/** +/* * The msg member must be at the end of the struct, as it's followed by the * message data. */ diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 023a4f987bb2..2b4ceb5e6ce4 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -894,7 +894,6 @@ int pnv_ioda_deconfigure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) { - struct pci_dev *parent; uint8_t bcomp, dcomp, fcomp; long rc, rid_end, rid; @@ -904,7 +903,6 @@ int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) dcomp = OPAL_IGNORE_RID_DEVICE_NUMBER; fcomp = OPAL_IGNORE_RID_FUNCTION_NUMBER; - parent = pe->pbus->self; if (pe->flags & PNV_IODA_PE_BUS_ALL) count = resource_size(&pe->pbus->busn_res); else @@ -925,12 +923,6 @@ int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) } rid_end = pe->rid + (count << 8); } else { -#ifdef CONFIG_PCI_IOV - if (pe->flags & PNV_IODA_PE_VF) - parent = pe->parent_dev; - else -#endif /* CONFIG_PCI_IOV */ - parent = pe->pdev->bus->self; bcomp = OpalPciBusAll; dcomp = OPAL_COMPARE_RID_DEVICE_NUMBER; fcomp = OPAL_COMPARE_RID_FUNCTION_NUMBER; diff --git a/arch/powerpc/platforms/powernv/powernv.h b/arch/powerpc/platforms/powernv/powernv.h index 1aa51c4fa904..11df4e16a1cc 100644 --- a/arch/powerpc/platforms/powernv/powernv.h +++ b/arch/powerpc/platforms/powernv/powernv.h @@ -2,6 +2,13 @@ #ifndef _POWERNV_H #define _POWERNV_H +/* + * There's various hacks scattered throughout the generic powerpc arch code + * that needs to call into powernv platform stuff. The prototypes for those + * functions are in asm/powernv.h + */ +#include <asm/powernv.h> + #ifdef CONFIG_SMP extern void pnv_smp_init(void); #else diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c index 8035caf6e297..72c25295c1c2 100644 --- a/arch/powerpc/platforms/powernv/rng.c +++ b/arch/powerpc/platforms/powernv/rng.c @@ -65,7 +65,7 @@ int powernv_get_random_real_mode(unsigned long *v) return 1; } -int powernv_get_random_darn(unsigned long *v) +static int powernv_get_random_darn(unsigned long *v) { unsigned long val; diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 7fcb88623081..9acaa0f131b9 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -130,6 +130,28 @@ static void pnv_setup_rfi_flush(void) setup_count_cache_flush(); } +static void __init pnv_check_guarded_cores(void) +{ + struct device_node *dn; + int bad_count = 0; + + for_each_node_by_type(dn, "cpu") { + if (of_property_match_string(dn, "status", "bad") >= 0) + bad_count++; + }; + + if (bad_count) { + printk(" _ _______________\n"); + pr_cont(" | | / \\\n"); + pr_cont(" | | | WARNING! |\n"); + pr_cont(" | | | |\n"); + pr_cont(" | | | It looks like |\n"); + pr_cont(" |_| | you have %*d |\n", 3, bad_count); + pr_cont(" _ | guarded cores |\n"); + pr_cont(" (_) \\_______________/\n"); + } +} + static void __init pnv_setup_arch(void) { set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT); @@ -150,6 +172,8 @@ static void __init pnv_setup_arch(void) /* Enable NAP mode */ powersave_nap = 1; + pnv_check_guarded_cores(); + /* XXX PMCS */ } diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index b2ba3e95bda7..54c4ba45c7ce 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -43,7 +43,7 @@ #include <asm/udbg.h> #define DBG(fmt...) udbg_printf(fmt) #else -#define DBG(fmt...) +#define DBG(fmt...) do { } while (0) #endif static void pnv_smp_setup_cpu(int cpu) @@ -158,7 +158,7 @@ static void pnv_flush_interrupts(void) } } -static void pnv_smp_cpu_kill_self(void) +static void pnv_cpu_offline_self(void) { unsigned long srr1, unexpected_mask, wmask; unsigned int cpu; @@ -417,6 +417,7 @@ static struct smp_ops_t pnv_smp_ops = { #ifdef CONFIG_HOTPLUG_CPU .cpu_disable = pnv_smp_cpu_disable, .cpu_die = generic_cpu_die, + .cpu_offline_self = pnv_cpu_offline_self, #endif /* CONFIG_HOTPLUG_CPU */ }; @@ -430,7 +431,6 @@ void __init pnv_smp_init(void) smp_ops = &pnv_smp_ops; #ifdef CONFIG_HOTPLUG_CPU - ppc_md.cpu_die = pnv_smp_cpu_kill_self; #ifdef CONFIG_KEXEC_CORE crash_wake_offline = 1; #endif diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 6434f9cb5aed..5f5fe63a3d1c 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -186,7 +186,7 @@ static void unmap_winctx_mmio_bars(struct vas_window *window) * OS/User Window Context (UWC) MMIO Base Address Region for the given window. * Map these bus addresses and save the mapped kernel addresses in @window. */ -int map_winctx_mmio_bars(struct vas_window *window) +static int map_winctx_mmio_bars(struct vas_window *window) { int len; u64 start; @@ -214,7 +214,7 @@ int map_winctx_mmio_bars(struct vas_window *window) * registers are not sequential. And, we can only write to offsets * with valid registers. */ -void reset_window_regs(struct vas_window *window) +static void reset_window_regs(struct vas_window *window) { write_hvwc_reg(window, VREG(LPID), 0ULL); write_hvwc_reg(window, VREG(PID), 0ULL); @@ -357,7 +357,8 @@ static void init_rsvd_tx_buf_count(struct vas_window *txwin, * as a one-time task? That could work for NX but what about other * receivers? Let the receivers tell us the rx-fifo buffers for now. */ -int init_winctx_regs(struct vas_window *window, struct vas_winctx *winctx) +static void init_winctx_regs(struct vas_window *window, + struct vas_winctx *winctx) { u64 val; int fifo_size; @@ -499,8 +500,6 @@ int init_winctx_regs(struct vas_window *window, struct vas_winctx *winctx) val = SET_FIELD(VAS_WINCTL_NX_WIN, val, winctx->nx_win); val = SET_FIELD(VAS_WINCTL_OPEN, val, 1); write_hvwc_reg(window, VREG(WINCTL), val); - - return 0; } static void vas_release_window_id(struct ida *ida, int winid) diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c index 1193c294b8d0..0c252478e556 100644 --- a/arch/powerpc/platforms/ps3/spu.c +++ b/arch/powerpc/platforms/ps3/spu.c @@ -448,7 +448,7 @@ static void ps3_disable_spu(struct spu_context *ctx) ctx->ops->runcntl_stop(ctx); } -const struct spu_management_ops spu_management_ps3_ops = { +static const struct spu_management_ops spu_management_ps3_ops = { .enumerate_spus = ps3_enumerate_spus, .create_spu = ps3_create_spu, .destroy_spu = ps3_destroy_spu, @@ -589,7 +589,7 @@ static u64 resource_allocation_enable_get(struct spu *spu) return 0; /* No support. */ } -const struct spu_priv1_ops spu_priv1_ps3_ops = { +static const struct spu_priv1_ops spu_priv1_ps3_ops = { .int_mask_and = int_mask_and, .int_mask_or = int_mask_or, .int_mask_set = int_mask_set, diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 3542b7bd6a46..c62aaa29a9d5 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -9,7 +9,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/export.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/err.h> #include <linux/slab.h> @@ -696,6 +696,8 @@ static const struct dma_map_ops ps3_sb_dma_ops = { .unmap_page = ps3_unmap_page, .mmap = dma_common_mmap, .get_sgtable = dma_common_get_sgtable, + .alloc_pages = dma_common_alloc_pages, + .free_pages = dma_common_free_pages, }; static const struct dma_map_ops ps3_ioc0_dma_ops = { @@ -708,6 +710,8 @@ static const struct dma_map_ops ps3_ioc0_dma_ops = { .unmap_page = ps3_unmap_page, .mmap = dma_common_mmap, .get_sgtable = dma_common_get_sgtable, + .alloc_pages = dma_common_alloc_pages, + .free_pages = dma_common_free_pages, }; /** diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index cb2d9a970b7b..cf024fa37bda 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c @@ -33,8 +33,6 @@ #include <asm/ppc-pci.h> #include <asm/rtas.h> -static int pseries_eeh_get_pe_addr(struct pci_dn *pdn); - /* RTAS tokens */ static int ibm_set_eeh_option; static int ibm_set_slot_reset; @@ -86,42 +84,43 @@ void pseries_pcibios_bus_add_device(struct pci_dev *pdev) /** - * pseries_eeh_get_config_addr - Retrieve config address + * pseries_eeh_get_pe_config_addr - Find the pe_config_addr for a device + * @pdn: pci_dn of the input device + * + * The EEH RTAS calls use a tuple consisting of: (buid_hi, buid_lo, + * pe_config_addr) as a handle to a given PE. This function finds the + * pe_config_addr based on the device's config addr. * - * Retrieve the assocated config address. Actually, there're 2 RTAS - * function calls dedicated for the purpose. We need implement - * it through the new function and then the old one. Besides, - * you should make sure the config address is figured out from - * FDT node before calling the function. + * Keep in mind that the pe_config_addr *might* be numerically identical to the + * device's config addr, but the two are conceptually distinct. * - * It's notable that zero'ed return value means invalid PE config - * address. + * Returns the pe_config_addr, or a negative error code. */ -static int pseries_eeh_get_config_addr(struct pci_controller *phb, int config_addr) +static int pseries_eeh_get_pe_config_addr(struct pci_dn *pdn) { - int ret = 0; - int rets[3]; + int config_addr = rtas_config_addr(pdn->busno, pdn->devfn, 0); + struct pci_controller *phb = pdn->phb; + int ret, rets[3]; if (ibm_get_config_addr_info2 != RTAS_UNKNOWN_SERVICE) { /* - * First of all, we need to make sure there has one PE - * associated with the device. Otherwise, PE address is - * meaningless. + * First of all, use function 1 to determine if this device is + * part of a PE or not. ret[0] being zero indicates it's not. */ ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets, config_addr, BUID_HI(phb->buid), BUID_LO(phb->buid), 1); if (ret || (rets[0] == 0)) - return 0; + return -ENOENT; - /* Retrieve the associated PE config address */ + /* Retrieve the associated PE config address with function 0 */ ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets, config_addr, BUID_HI(phb->buid), BUID_LO(phb->buid), 0); if (ret) { pr_warn("%s: Failed to get address for PHB#%x-PE#%x\n", __func__, phb->global_number, config_addr); - return 0; + return -ENXIO; } return rets[0]; @@ -134,13 +133,20 @@ static int pseries_eeh_get_config_addr(struct pci_controller *phb, int config_ad if (ret) { pr_warn("%s: Failed to get address for PHB#%x-PE#%x\n", __func__, phb->global_number, config_addr); - return 0; + return -ENXIO; } return rets[0]; } - return ret; + /* + * PAPR does describe a process for finding the pe_config_addr that was + * used before the ibm,get-config-addr-info calls were added. However, + * I haven't found *any* systems that don't have that RTAS call + * implemented. If you happen to find one that needs the old DT based + * process, patches are welcome! + */ + return -ENOENT; } /** @@ -161,8 +167,7 @@ static int pseries_eeh_phb_reset(struct pci_controller *phb, int config_addr, in BUID_LO(phb->buid), option); /* If fundamental-reset not supported, try hot-reset */ - if (option == EEH_RESET_FUNDAMENTAL && - ret == -8) { + if (option == EEH_RESET_FUNDAMENTAL && ret == -8) { option = EEH_RESET_HOT; ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL, config_addr, BUID_HI(phb->buid), @@ -170,8 +175,7 @@ static int pseries_eeh_phb_reset(struct pci_controller *phb, int config_addr, in } /* We need reset hold or settlement delay */ - if (option == EEH_RESET_FUNDAMENTAL || - option == EEH_RESET_HOT) + if (option == EEH_RESET_FUNDAMENTAL || option == EEH_RESET_HOT) msleep(EEH_PE_RST_HOLD_TIME); else msleep(EEH_PE_RST_SETTLE_TIME); @@ -239,88 +243,6 @@ static unsigned char slot_errbuf[RTAS_ERROR_LOG_MAX]; static DEFINE_SPINLOCK(slot_errbuf_lock); static int eeh_error_buf_size; -/** - * pseries_eeh_init - EEH platform dependent initialization - * - * EEH platform dependent initialization on pseries. - */ -static int pseries_eeh_init(void) -{ - struct pci_controller *phb; - struct pci_dn *pdn; - int addr, config_addr; - - /* figure out EEH RTAS function call tokens */ - ibm_set_eeh_option = rtas_token("ibm,set-eeh-option"); - ibm_set_slot_reset = rtas_token("ibm,set-slot-reset"); - ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2"); - ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state"); - ibm_slot_error_detail = rtas_token("ibm,slot-error-detail"); - ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2"); - ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info"); - ibm_configure_pe = rtas_token("ibm,configure-pe"); - - /* - * ibm,configure-pe and ibm,configure-bridge have the same semantics, - * however ibm,configure-pe can be faster. If we can't find - * ibm,configure-pe then fall back to using ibm,configure-bridge. - */ - if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE) - ibm_configure_pe = rtas_token("ibm,configure-bridge"); - - /* - * Necessary sanity check. We needn't check "get-config-addr-info" - * and its variant since the old firmware probably support address - * of domain/bus/slot/function for EEH RTAS operations. - */ - if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE || - ibm_set_slot_reset == RTAS_UNKNOWN_SERVICE || - (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE && - ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE) || - ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE || - ibm_configure_pe == RTAS_UNKNOWN_SERVICE) { - pr_info("EEH functionality not supported\n"); - return -EINVAL; - } - - /* Initialize error log lock and size */ - spin_lock_init(&slot_errbuf_lock); - eeh_error_buf_size = rtas_token("rtas-error-log-max"); - if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) { - pr_info("%s: unknown EEH error log size\n", - __func__); - eeh_error_buf_size = 1024; - } else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) { - pr_info("%s: EEH error log size %d exceeds the maximal %d\n", - __func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX); - eeh_error_buf_size = RTAS_ERROR_LOG_MAX; - } - - /* Set EEH probe mode */ - eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG); - - /* Set EEH machine dependent code */ - ppc_md.pcibios_bus_add_device = pseries_pcibios_bus_add_device; - - if (is_kdump_kernel() || reset_devices) { - pr_info("Issue PHB reset ...\n"); - list_for_each_entry(phb, &hose_list, list_node) { - pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list); - addr = (pdn->busno << 16) | (pdn->devfn << 8); - config_addr = pseries_eeh_get_config_addr(phb, addr); - /* invalid PE config addr */ - if (config_addr == 0) - continue; - - pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_FUNDAMENTAL); - pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_DEACTIVATE); - pseries_eeh_phb_configure_bridge(phb, config_addr); - } - } - - return 0; -} - static int pseries_eeh_cap_start(struct pci_dn *pdn) { u32 status; @@ -439,10 +361,9 @@ static struct eeh_pe *pseries_eeh_pe_get_parent(struct eeh_dev *edev) */ void pseries_eeh_init_edev(struct pci_dn *pdn) { + struct eeh_pe pe, *parent; struct eeh_dev *edev; - struct eeh_pe pe; u32 pcie_flags; - int enable = 0; int ret; if (WARN_ON_ONCE(!eeh_has_flag(EEH_PROBE_MODE_DEVTREE))) @@ -499,51 +420,38 @@ void pseries_eeh_init_edev(struct pci_dn *pdn) } } - /* Initialize the fake PE */ + /* first up, find the pe_config_addr for the PE containing the device */ + ret = pseries_eeh_get_pe_config_addr(pdn); + if (ret < 0) { + eeh_edev_dbg(edev, "Unable to find pe_config_addr\n"); + goto err; + } + + /* Try enable EEH on the fake PE */ memset(&pe, 0, sizeof(struct eeh_pe)); pe.phb = pdn->phb; - pe.config_addr = (pdn->busno << 16) | (pdn->devfn << 8); + pe.addr = ret; - /* Enable EEH on the device */ eeh_edev_dbg(edev, "Enabling EEH on device\n"); ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE); if (ret) { eeh_edev_dbg(edev, "EEH failed to enable on device (code %d)\n", ret); - } else { - struct eeh_pe *parent; + goto err; + } - /* Retrieve PE address */ - edev->pe_config_addr = pseries_eeh_get_pe_addr(pdn); - pe.addr = edev->pe_config_addr; + edev->pe_config_addr = pe.addr; - /* Some older systems (Power4) allow the ibm,set-eeh-option - * call to succeed even on nodes where EEH is not supported. - * Verify support explicitly. - */ - ret = eeh_ops->get_state(&pe, NULL); - if (ret > 0 && ret != EEH_STATE_NOT_SUPPORT) - enable = 1; + eeh_add_flag(EEH_ENABLED); - /* - * This device doesn't support EEH, but it may have an - * EEH parent. In this case any error on the device will - * freeze the PE of it's upstream bridge, so added it to - * the upstream PE. - */ - parent = pseries_eeh_pe_get_parent(edev); - if (parent && !enable) - edev->pe_config_addr = parent->addr; + parent = pseries_eeh_pe_get_parent(edev); + eeh_pe_tree_insert(edev, parent); + eeh_save_bars(edev); + eeh_edev_dbg(edev, "EEH enabled for device"); - if (enable || parent) { - eeh_add_flag(EEH_ENABLED); - eeh_pe_tree_insert(edev, parent); - } - eeh_edev_dbg(edev, "EEH is %s on device (code %d)\n", - (enable ? "enabled" : "unsupported"), ret); - } + return; - /* Save memory bars */ - eeh_save_bars(edev); +err: + eeh_edev_dbg(edev, "EEH is unsupported on device (code = %d)\n", ret); } static struct eeh_dev *pseries_eeh_probe(struct pci_dev *pdev) @@ -600,7 +508,6 @@ EXPORT_SYMBOL_GPL(pseries_eeh_init_edev_recursive); static int pseries_eeh_set_option(struct eeh_pe *pe, int option) { int ret = 0; - int config_addr; /* * When we're enabling or disabling EEH functioality on @@ -613,85 +520,23 @@ static int pseries_eeh_set_option(struct eeh_pe *pe, int option) case EEH_OPT_ENABLE: case EEH_OPT_THAW_MMIO: case EEH_OPT_THAW_DMA: - config_addr = pe->config_addr; - if (pe->addr) - config_addr = pe->addr; break; case EEH_OPT_FREEZE_PE: /* Not support */ return 0; default: - pr_err("%s: Invalid option %d\n", - __func__, option); + pr_err("%s: Invalid option %d\n", __func__, option); return -EINVAL; } ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL, - config_addr, BUID_HI(pe->phb->buid), + pe->addr, BUID_HI(pe->phb->buid), BUID_LO(pe->phb->buid), option); return ret; } /** - * pseries_eeh_get_pe_addr - Retrieve PE address - * @pe: EEH PE - * - * Retrieve the assocated PE address. Actually, there're 2 RTAS - * function calls dedicated for the purpose. We need implement - * it through the new function and then the old one. Besides, - * you should make sure the config address is figured out from - * FDT node before calling the function. - * - * It's notable that zero'ed return value means invalid PE config - * address. - */ -static int pseries_eeh_get_pe_addr(struct pci_dn *pdn) -{ - int config_addr = rtas_config_addr(pdn->busno, pdn->devfn, 0); - unsigned long buid = pdn->phb->buid; - int ret = 0; - int rets[3]; - - if (ibm_get_config_addr_info2 != RTAS_UNKNOWN_SERVICE) { - /* - * First of all, we need to make sure there has one PE - * associated with the device. Otherwise, PE address is - * meaningless. - */ - ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets, - config_addr, BUID_HI(buid), BUID_LO(buid), 1); - if (ret || (rets[0] == 0)) - return 0; - - /* Retrieve the associated PE config address */ - ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets, - config_addr, BUID_HI(buid), BUID_LO(buid), 0); - if (ret) { - pr_warn("%s: Failed to get address for PHB#%x-PE#%x\n", - __func__, pdn->phb->global_number, config_addr); - return 0; - } - - return rets[0]; - } - - if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) { - ret = rtas_call(ibm_get_config_addr_info, 4, 2, rets, - config_addr, BUID_HI(buid), BUID_LO(buid), 0); - if (ret) { - pr_warn("%s: Failed to get address for PHB#%x-PE#%x\n", - __func__, pdn->phb->global_number, config_addr); - return 0; - } - - return rets[0]; - } - - return ret; -} - -/** * pseries_eeh_get_state - Retrieve PE state * @pe: EEH PE * @delay: suggested time to wait if state is unavailable @@ -706,25 +551,19 @@ static int pseries_eeh_get_pe_addr(struct pci_dn *pdn) */ static int pseries_eeh_get_state(struct eeh_pe *pe, int *delay) { - int config_addr; int ret; int rets[4]; int result; - /* Figure out PE config address if possible */ - config_addr = pe->config_addr; - if (pe->addr) - config_addr = pe->addr; - if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) { ret = rtas_call(ibm_read_slot_reset_state2, 3, 4, rets, - config_addr, BUID_HI(pe->phb->buid), + pe->addr, BUID_HI(pe->phb->buid), BUID_LO(pe->phb->buid)); } else if (ibm_read_slot_reset_state != RTAS_UNKNOWN_SERVICE) { /* Fake PE unavailable info */ rets[2] = 0; ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets, - config_addr, BUID_HI(pe->phb->buid), + pe->addr, BUID_HI(pe->phb->buid), BUID_LO(pe->phb->buid)); } else { return EEH_STATE_NOT_SUPPORT; @@ -778,14 +617,7 @@ static int pseries_eeh_get_state(struct eeh_pe *pe, int *delay) */ static int pseries_eeh_reset(struct eeh_pe *pe, int option) { - int config_addr; - - /* Figure out PE address */ - config_addr = pe->config_addr; - if (pe->addr) - config_addr = pe->addr; - - return pseries_eeh_phb_reset(pe->phb, config_addr, option); + return pseries_eeh_phb_reset(pe->phb, pe->addr, option); } /** @@ -801,19 +633,13 @@ static int pseries_eeh_reset(struct eeh_pe *pe, int option) */ static int pseries_eeh_get_log(struct eeh_pe *pe, int severity, char *drv_log, unsigned long len) { - int config_addr; unsigned long flags; int ret; spin_lock_irqsave(&slot_errbuf_lock, flags); memset(slot_errbuf, 0, eeh_error_buf_size); - /* Figure out the PE address */ - config_addr = pe->config_addr; - if (pe->addr) - config_addr = pe->addr; - - ret = rtas_call(ibm_slot_error_detail, 8, 1, NULL, config_addr, + ret = rtas_call(ibm_slot_error_detail, 8, 1, NULL, pe->addr, BUID_HI(pe->phb->buid), BUID_LO(pe->phb->buid), virt_to_phys(drv_log), len, virt_to_phys(slot_errbuf), eeh_error_buf_size, @@ -832,14 +658,7 @@ static int pseries_eeh_get_log(struct eeh_pe *pe, int severity, char *drv_log, u */ static int pseries_eeh_configure_bridge(struct eeh_pe *pe) { - int config_addr; - - /* Figure out the PE address */ - config_addr = pe->config_addr; - if (pe->addr) - config_addr = pe->addr; - - return pseries_eeh_phb_configure_bridge(pe->phb, config_addr); + return pseries_eeh_phb_configure_bridge(pe->phb, pe->addr); } /** @@ -954,8 +773,7 @@ static int pseries_notify_resume(struct eeh_dev *edev) if (!edev) return -EEXIST; - if (rtas_token("ibm,open-sriov-allow-unfreeze") - == RTAS_UNKNOWN_SERVICE) + if (rtas_token("ibm,open-sriov-allow-unfreeze") == RTAS_UNKNOWN_SERVICE) return -EINVAL; if (edev->pdev->is_physfn || edev->pdev->is_virtfn) @@ -967,7 +785,6 @@ static int pseries_notify_resume(struct eeh_dev *edev) static struct eeh_ops pseries_eeh_ops = { .name = "pseries", - .init = pseries_eeh_init, .probe = pseries_eeh_probe, .set_option = pseries_eeh_set_option, .get_state = pseries_eeh_get_state, @@ -992,15 +809,84 @@ static struct eeh_ops pseries_eeh_ops = { */ static int __init eeh_pseries_init(void) { - int ret; + struct pci_controller *phb; + struct pci_dn *pdn; + int ret, config_addr; - ret = eeh_ops_register(&pseries_eeh_ops); + /* figure out EEH RTAS function call tokens */ + ibm_set_eeh_option = rtas_token("ibm,set-eeh-option"); + ibm_set_slot_reset = rtas_token("ibm,set-slot-reset"); + ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2"); + ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state"); + ibm_slot_error_detail = rtas_token("ibm,slot-error-detail"); + ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2"); + ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info"); + ibm_configure_pe = rtas_token("ibm,configure-pe"); + + /* + * ibm,configure-pe and ibm,configure-bridge have the same semantics, + * however ibm,configure-pe can be faster. If we can't find + * ibm,configure-pe then fall back to using ibm,configure-bridge. + */ + if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE) + ibm_configure_pe = rtas_token("ibm,configure-bridge"); + + /* + * Necessary sanity check. We needn't check "get-config-addr-info" + * and its variant since the old firmware probably support address + * of domain/bus/slot/function for EEH RTAS operations. + */ + if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE || + ibm_set_slot_reset == RTAS_UNKNOWN_SERVICE || + (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE && + ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE) || + ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE || + ibm_configure_pe == RTAS_UNKNOWN_SERVICE) { + pr_info("EEH functionality not supported\n"); + return -EINVAL; + } + + /* Initialize error log lock and size */ + spin_lock_init(&slot_errbuf_lock); + eeh_error_buf_size = rtas_token("rtas-error-log-max"); + if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) { + pr_info("%s: unknown EEH error log size\n", + __func__); + eeh_error_buf_size = 1024; + } else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) { + pr_info("%s: EEH error log size %d exceeds the maximal %d\n", + __func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX); + eeh_error_buf_size = RTAS_ERROR_LOG_MAX; + } + + /* Set EEH probe mode */ + eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG); + + /* Set EEH machine dependent code */ + ppc_md.pcibios_bus_add_device = pseries_pcibios_bus_add_device; + + if (is_kdump_kernel() || reset_devices) { + pr_info("Issue PHB reset ...\n"); + list_for_each_entry(phb, &hose_list, list_node) { + pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list); + config_addr = pseries_eeh_get_pe_config_addr(pdn); + + /* invalid PE config addr */ + if (config_addr < 0) + continue; + + pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_FUNDAMENTAL); + pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_DEACTIVATE); + pseries_eeh_phb_configure_bridge(phb, config_addr); + } + } + + ret = eeh_init(&pseries_eeh_ops); if (!ret) pr_info("EEH: pSeries platform initialized\n"); else pr_info("EEH: pSeries platform initialization failure (%d)\n", ret); - return ret; } -machine_early_initcall(pseries, eeh_pseries_init); +machine_arch_initcall(pseries, eeh_pseries_init); diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 7a974ed6b240..f2837e33bf5d 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -55,7 +55,7 @@ static void rtas_stop_self(void) panic("Alas, I survived.\n"); } -static void pseries_mach_cpu_die(void) +static void pseries_cpu_offline_self(void) { unsigned int hwcpu = hard_smp_processor_id(); @@ -102,7 +102,7 @@ static int pseries_cpu_disable(void) * to self-destroy so that the cpu-offline thread can send the CPU_DEAD * notifications. * - * OTOH, pseries_mach_cpu_die() is called by the @cpu when it wants to + * OTOH, pseries_cpu_offline_self() is called by the @cpu when it wants to * self-destruct. */ static void pseries_cpu_die(unsigned int cpu) @@ -901,7 +901,7 @@ static int __init pseries_cpu_hotplug_init(void) return 0; } - ppc_md.cpu_die = pseries_mach_cpu_die; + smp_ops->cpu_offline_self = pseries_cpu_offline_self; smp_ops->cpu_disable = pseries_cpu_disable; smp_ops->cpu_die = pseries_cpu_die; diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 5d545b78111f..7efe6ec5d14a 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -30,12 +30,17 @@ unsigned long pseries_memory_block_size(void) np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); if (np) { - const __be64 *size; + int len; + int size_cells; + const __be32 *prop; - size = of_get_property(np, "ibm,lmb-size", NULL); - if (size) - memblock_size = be64_to_cpup(size); + size_cells = of_n_size_cells(np); + + prop = of_get_property(np, "ibm,lmb-size", &len); + if (prop && len >= size_cells * sizeof(__be32)) + memblock_size = of_read_number(prop, size_cells); of_node_put(np); + } else if (machine_is(pseries)) { /* This fallback really only applies to pseries */ unsigned int memzero_size = 0; @@ -277,7 +282,7 @@ static int dlpar_offline_lmb(struct drmem_lmb *lmb) return dlpar_change_lmb_state(lmb, false); } -static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) +static int pseries_remove_memblock(unsigned long base, unsigned long memblock_size) { unsigned long block_sz, start_pfn; int sections_per_block; @@ -308,10 +313,11 @@ out: static int pseries_remove_mem_node(struct device_node *np) { - const __be32 *regs; + const __be32 *prop; unsigned long base; - unsigned int lmb_size; + unsigned long lmb_size; int ret = -EINVAL; + int addr_cells, size_cells; /* * Check to see if we are actually removing memory @@ -322,12 +328,19 @@ static int pseries_remove_mem_node(struct device_node *np) /* * Find the base address and size of the memblock */ - regs = of_get_property(np, "reg", NULL); - if (!regs) + prop = of_get_property(np, "reg", NULL); + if (!prop) return ret; - base = be64_to_cpu(*(unsigned long *)regs); - lmb_size = be32_to_cpu(regs[3]); + addr_cells = of_n_addr_cells(np); + size_cells = of_n_size_cells(np); + + /* + * "reg" property represents (addr,size) tuple. + */ + base = of_read_number(prop, addr_cells); + prop += addr_cells; + lmb_size = of_read_number(prop, size_cells); pseries_remove_memblock(base, lmb_size); return 0; @@ -354,25 +367,32 @@ static int dlpar_add_lmb(struct drmem_lmb *); static int dlpar_remove_lmb(struct drmem_lmb *lmb) { + struct memory_block *mem_block; unsigned long block_sz; int rc; if (!lmb_is_removable(lmb)) return -EINVAL; + mem_block = lmb_to_memblock(lmb); + if (mem_block == NULL) + return -EINVAL; + rc = dlpar_offline_lmb(lmb); - if (rc) + if (rc) { + put_device(&mem_block->dev); return rc; + } block_sz = pseries_memory_block_size(); - __remove_memory(lmb->nid, lmb->base_addr, block_sz); + __remove_memory(mem_block->nid, lmb->base_addr, block_sz); + put_device(&mem_block->dev); /* Update memory regions for memory remove */ memblock_remove(lmb->base_addr, block_sz); invalidate_lmb_associativity_index(lmb); - lmb_clear_nid(lmb); lmb->flags &= ~DRCONF_MEM_ASSIGNED; return 0; @@ -557,7 +577,7 @@ static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index) #else static inline int pseries_remove_memblock(unsigned long base, - unsigned int memblock_size) + unsigned long memblock_size) { return -EOPNOTSUPP; } @@ -591,7 +611,7 @@ static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index) static int dlpar_add_lmb(struct drmem_lmb *lmb) { unsigned long block_sz; - int rc; + int nid, rc; if (lmb->flags & DRCONF_MEM_ASSIGNED) return -EINVAL; @@ -602,11 +622,15 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb) return rc; } - lmb_set_nid(lmb); block_sz = memory_block_size_bytes(); + /* Find the node id for this LMB. Fake one if necessary. */ + nid = of_drconf_to_nid_single(lmb); + if (nid < 0 || !node_possible(nid)) + nid = first_online_node; + /* Add the memory */ - rc = __add_memory(lmb->nid, lmb->base_addr, block_sz); + rc = __add_memory(nid, lmb->base_addr, block_sz, MHP_NONE); if (rc) { invalidate_lmb_associativity_index(lmb); return rc; @@ -614,9 +638,8 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb) rc = dlpar_online_lmb(lmb); if (rc) { - __remove_memory(lmb->nid, lmb->base_addr, block_sz); + __remove_memory(nid, lmb->base_addr, block_sz); invalidate_lmb_associativity_index(lmb); - lmb_clear_nid(lmb); } else { lmb->flags |= DRCONF_MEM_ASSIGNED; } @@ -878,10 +901,11 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog) static int pseries_add_mem_node(struct device_node *np) { - const __be32 *regs; + const __be32 *prop; unsigned long base; - unsigned int lmb_size; + unsigned long lmb_size; int ret = -EINVAL; + int addr_cells, size_cells; /* * Check to see if we are actually adding memory @@ -892,12 +916,18 @@ static int pseries_add_mem_node(struct device_node *np) /* * Find the base and size of the memblock */ - regs = of_get_property(np, "reg", NULL); - if (!regs) + prop = of_get_property(np, "reg", NULL); + if (!prop) return ret; - base = be64_to_cpu(*(unsigned long *)regs); - lmb_size = be32_to_cpu(regs[3]); + addr_cells = of_n_addr_cells(np); + size_cells = of_n_size_cells(np); + /* + * "reg" property represents (addr,size) tuple. + */ + base = of_read_number(prop, addr_cells); + prop += addr_cells; + lmb_size = of_read_number(prop, size_cells); /* * Update memory region to represent the memory add diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c index c40c62ec432e..2c59b4986ea5 100644 --- a/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c @@ -70,31 +70,14 @@ static int hc_show(struct seq_file *m, void *p) return 0; } -static const struct seq_operations hcall_inst_seq_ops = { +static const struct seq_operations hcall_inst_sops = { .start = hc_start, .next = hc_next, .stop = hc_stop, .show = hc_show }; -static int hcall_inst_seq_open(struct inode *inode, struct file *file) -{ - int rc; - struct seq_file *seq; - - rc = seq_open(file, &hcall_inst_seq_ops); - seq = file->private_data; - seq->private = file_inode(file)->i_private; - - return rc; -} - -static const struct file_operations hcall_inst_seq_fops = { - .open = hcall_inst_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; +DEFINE_SEQ_ATTRIBUTE(hcall_inst); #define HCALL_ROOT_DIR "hcall_inst" #define CPU_NAME_BUF_SIZE 32 @@ -149,7 +132,7 @@ static int __init hcall_inst_init(void) snprintf(cpu_name_buf, CPU_NAME_BUF_SIZE, "cpu%d", cpu); debugfs_create_file(cpu_name_buf, 0444, hcall_root, per_cpu(hcall_stats, cpu), - &hcall_inst_seq_fops); + &hcall_inst_fops); } return 0; diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c index a6f101c958e8..8c6e509f6967 100644 --- a/arch/powerpc/platforms/pseries/ibmebus.c +++ b/arch/powerpc/platforms/pseries/ibmebus.c @@ -40,7 +40,7 @@ #include <linux/export.h> #include <linux/console.h> #include <linux/kobject.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/interrupt.h> #include <linux/of.h> #include <linux/slab.h> diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 6d47b4a3ce39..e4198700ed1a 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -39,6 +39,20 @@ #include "pseries.h" +enum { + DDW_QUERY_PE_DMA_WIN = 0, + DDW_CREATE_PE_DMA_WIN = 1, + DDW_REMOVE_PE_DMA_WIN = 2, + + DDW_APPLICABLE_SIZE +}; + +enum { + DDW_EXT_SIZE = 0, + DDW_EXT_RESET_DMA_WIN = 1, + DDW_EXT_QUERY_OUT_SIZE = 2 +}; + static struct iommu_table_group *iommu_pseries_alloc_group(int node) { struct iommu_table_group *table_group; @@ -334,7 +348,7 @@ struct direct_window { /* Dynamic DMA Window support */ struct ddw_query_response { u32 windows_available; - u32 largest_available_block; + u64 largest_available_block; u32 page_size; u32 migration_capable; }; @@ -767,25 +781,14 @@ static int __init disable_ddw_setup(char *str) early_param("disable_ddw", disable_ddw_setup); -static void remove_ddw(struct device_node *np, bool remove_prop) +static void remove_dma_window(struct device_node *np, u32 *ddw_avail, + struct property *win) { struct dynamic_dma_window_prop *dwp; - struct property *win64; - u32 ddw_avail[3]; u64 liobn; - int ret = 0; - - ret = of_property_read_u32_array(np, "ibm,ddw-applicable", - &ddw_avail[0], 3); - - win64 = of_find_property(np, DIRECT64_PROPNAME, NULL); - if (!win64) - return; - - if (ret || win64->length < sizeof(*dwp)) - goto delprop; + int ret; - dwp = win64->value; + dwp = win->value; liobn = (u64)be32_to_cpu(dwp->liobn); /* clear the whole window, note the arg is in kernel pages */ @@ -798,19 +801,39 @@ static void remove_ddw(struct device_node *np, bool remove_prop) pr_debug("%pOF successfully cleared tces in window.\n", np); - ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn); + ret = rtas_call(ddw_avail[DDW_REMOVE_PE_DMA_WIN], 1, 1, NULL, liobn); if (ret) pr_warn("%pOF: failed to remove direct window: rtas returned " "%d to ibm,remove-pe-dma-window(%x) %llx\n", - np, ret, ddw_avail[2], liobn); + np, ret, ddw_avail[DDW_REMOVE_PE_DMA_WIN], liobn); else pr_debug("%pOF: successfully removed direct window: rtas returned " "%d to ibm,remove-pe-dma-window(%x) %llx\n", - np, ret, ddw_avail[2], liobn); + np, ret, ddw_avail[DDW_REMOVE_PE_DMA_WIN], liobn); +} + +static void remove_ddw(struct device_node *np, bool remove_prop) +{ + struct property *win; + u32 ddw_avail[DDW_APPLICABLE_SIZE]; + int ret = 0; -delprop: - if (remove_prop) - ret = of_remove_property(np, win64); + ret = of_property_read_u32_array(np, "ibm,ddw-applicable", + &ddw_avail[0], DDW_APPLICABLE_SIZE); + if (ret) + return; + + win = of_find_property(np, DIRECT64_PROPNAME, NULL); + if (!win) + return; + + if (win->length >= sizeof(struct dynamic_dma_window_prop)) + remove_dma_window(np, ddw_avail, win); + + if (!remove_prop) + return; + + ret = of_remove_property(np, win); if (ret) pr_warn("%pOF: failed to remove direct window property: %d\n", np, ret); @@ -869,14 +892,62 @@ static int find_existing_ddw_windows(void) } machine_arch_initcall(pseries, find_existing_ddw_windows); +/** + * ddw_read_ext - Get the value of an DDW extension + * @np: device node from which the extension value is to be read. + * @extnum: index number of the extension. + * @value: pointer to return value, modified when extension is available. + * + * Checks if "ibm,ddw-extensions" exists for this node, and get the value + * on index 'extnum'. + * It can be used only to check if a property exists, passing value == NULL. + * + * Returns: + * 0 if extension successfully read + * -EINVAL if the "ibm,ddw-extensions" does not exist, + * -ENODATA if "ibm,ddw-extensions" does not have a value, and + * -EOVERFLOW if "ibm,ddw-extensions" does not contain this extension. + */ +static inline int ddw_read_ext(const struct device_node *np, int extnum, + u32 *value) +{ + static const char propname[] = "ibm,ddw-extensions"; + u32 count; + int ret; + + ret = of_property_read_u32_index(np, propname, DDW_EXT_SIZE, &count); + if (ret) + return ret; + + if (count < extnum) + return -EOVERFLOW; + + if (!value) + value = &count; + + return of_property_read_u32_index(np, propname, extnum, value); +} + static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail, - struct ddw_query_response *query) + struct ddw_query_response *query, + struct device_node *parent) { struct device_node *dn; struct pci_dn *pdn; - u32 cfg_addr; + u32 cfg_addr, ext_query, query_out[5]; u64 buid; - int ret; + int ret, out_sz; + + /* + * From LoPAR level 2.8, "ibm,ddw-extensions" index 3 can rule how many + * output parameters ibm,query-pe-dma-windows will have, ranging from + * 5 to 6. + */ + ret = ddw_read_ext(parent, DDW_EXT_QUERY_OUT_SIZE, &ext_query); + if (!ret && ext_query == 1) + out_sz = 6; + else + out_sz = 5; /* * Get the config address and phb buid of the PE window. @@ -889,11 +960,28 @@ static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail, buid = pdn->phb->buid; cfg_addr = ((pdn->busno << 16) | (pdn->devfn << 8)); - ret = rtas_call(ddw_avail[0], 3, 5, (u32 *)query, - cfg_addr, BUID_HI(buid), BUID_LO(buid)); - dev_info(&dev->dev, "ibm,query-pe-dma-windows(%x) %x %x %x" - " returned %d\n", ddw_avail[0], cfg_addr, BUID_HI(buid), - BUID_LO(buid), ret); + ret = rtas_call(ddw_avail[DDW_QUERY_PE_DMA_WIN], 3, out_sz, query_out, + cfg_addr, BUID_HI(buid), BUID_LO(buid)); + dev_info(&dev->dev, "ibm,query-pe-dma-windows(%x) %x %x %x returned %d\n", + ddw_avail[DDW_QUERY_PE_DMA_WIN], cfg_addr, BUID_HI(buid), + BUID_LO(buid), ret); + + switch (out_sz) { + case 5: + query->windows_available = query_out[0]; + query->largest_available_block = query_out[1]; + query->page_size = query_out[2]; + query->migration_capable = query_out[3]; + break; + case 6: + query->windows_available = query_out[0]; + query->largest_available_block = ((u64)query_out[1] << 32) | + query_out[2]; + query->page_size = query_out[3]; + query->migration_capable = query_out[4]; + break; + } + return ret; } @@ -920,15 +1008,16 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddw_avail, do { /* extra outputs are LIOBN and dma-addr (hi, lo) */ - ret = rtas_call(ddw_avail[1], 5, 4, (u32 *)create, - cfg_addr, BUID_HI(buid), BUID_LO(buid), - page_shift, window_shift); + ret = rtas_call(ddw_avail[DDW_CREATE_PE_DMA_WIN], 5, 4, + (u32 *)create, cfg_addr, BUID_HI(buid), + BUID_LO(buid), page_shift, window_shift); } while (rtas_busy_delay(ret)); dev_info(&dev->dev, "ibm,create-pe-dma-window(%x) %x %x %x %x %x returned %d " - "(liobn = 0x%x starting addr = %x %x)\n", ddw_avail[1], - cfg_addr, BUID_HI(buid), BUID_LO(buid), page_shift, - window_shift, ret, create->liobn, create->addr_hi, create->addr_lo); + "(liobn = 0x%x starting addr = %x %x)\n", + ddw_avail[DDW_CREATE_PE_DMA_WIN], cfg_addr, BUID_HI(buid), + BUID_LO(buid), page_shift, window_shift, ret, create->liobn, + create->addr_hi, create->addr_lo); return ret; } @@ -978,6 +1067,38 @@ static phys_addr_t ddw_memory_hotplug_max(void) } /* + * Platforms supporting the DDW option starting with LoPAR level 2.7 implement + * ibm,ddw-extensions, which carries the rtas token for + * ibm,reset-pe-dma-windows. + * That rtas-call can be used to restore the default DMA window for the device. + */ +static void reset_dma_window(struct pci_dev *dev, struct device_node *par_dn) +{ + int ret; + u32 cfg_addr, reset_dma_win; + u64 buid; + struct device_node *dn; + struct pci_dn *pdn; + + ret = ddw_read_ext(par_dn, DDW_EXT_RESET_DMA_WIN, &reset_dma_win); + if (ret) + return; + + dn = pci_device_to_OF_node(dev); + pdn = PCI_DN(dn); + buid = pdn->phb->buid; + cfg_addr = (pdn->busno << 16) | (pdn->devfn << 8); + + ret = rtas_call(reset_dma_win, 3, 1, NULL, cfg_addr, BUID_HI(buid), + BUID_LO(buid)); + if (ret) + dev_info(&dev->dev, + "ibm,reset-pe-dma-windows(%x) %x %x %x returned %d ", + reset_dma_win, cfg_addr, BUID_HI(buid), BUID_LO(buid), + ret); +} + +/* * If the PE supports dynamic dma windows, and there is space for a table * that can map all pages in a linear offset, then setup such a table, * and record the dma-offset in the struct device. @@ -996,11 +1117,12 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) int page_shift; u64 dma_addr, max_addr; struct device_node *dn; - u32 ddw_avail[3]; + u32 ddw_avail[DDW_APPLICABLE_SIZE]; struct direct_window *window; struct property *win64; struct dynamic_dma_window_prop *ddwprop; struct failed_ddw_pdn *fpdn; + bool default_win_removed = false; mutex_lock(&direct_window_init_mutex); @@ -1029,7 +1151,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) * the property is actually in the parent, not the PE */ ret = of_property_read_u32_array(pdn, "ibm,ddw-applicable", - &ddw_avail[0], 3); + &ddw_avail[0], DDW_APPLICABLE_SIZE); if (ret) goto out_failed; @@ -1040,18 +1162,42 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) * of page sizes: supported and supported for migrate-dma. */ dn = pci_device_to_OF_node(dev); - ret = query_ddw(dev, ddw_avail, &query); + ret = query_ddw(dev, ddw_avail, &query, pdn); if (ret != 0) goto out_failed; + /* + * If there is no window available, remove the default DMA window, + * if it's present. This will make all the resources available to the + * new DDW window. + * If anything fails after this, we need to restore it, so also check + * for extensions presence. + */ if (query.windows_available == 0) { - /* - * no additional windows are available for this device. - * We might be able to reallocate the existing window, - * trading in for a larger page size. - */ - dev_dbg(&dev->dev, "no free dynamic windows"); - goto out_failed; + struct property *default_win; + int reset_win_ext; + + default_win = of_find_property(pdn, "ibm,dma-window", NULL); + if (!default_win) + goto out_failed; + + reset_win_ext = ddw_read_ext(pdn, DDW_EXT_RESET_DMA_WIN, NULL); + if (reset_win_ext) + goto out_failed; + + remove_dma_window(pdn, ddw_avail, default_win); + default_win_removed = true; + + /* Query again, to check if the window is available */ + ret = query_ddw(dev, ddw_avail, &query, pdn); + if (ret != 0) + goto out_failed; + + if (query.windows_available == 0) { + /* no windows are available for this device. */ + dev_dbg(&dev->dev, "no free dynamic windows"); + goto out_failed; + } } if (query.page_size & 4) { page_shift = 24; /* 16MB */ @@ -1068,7 +1214,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) /* 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 %u " + 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); goto out_failed; @@ -1142,6 +1288,8 @@ out_free_prop: kfree(win64); out_failed: + if (default_win_removed) + reset_dma_window(dev, pdn); fpdn = kzalloc(sizeof(*fpdn), GFP_KERNEL); if (!fpdn) diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index baf24eacd268..764170fdb0f7 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -1724,6 +1724,7 @@ void __init hpte_init_pseries(void) pseries_lpar_register_process_table(0, 0, 0); } +#ifdef CONFIG_PPC_RADIX_MMU void radix_init_pseries(void) { pr_info("Using radix MMU under hypervisor\n"); @@ -1731,6 +1732,7 @@ void radix_init_pseries(void) pseries_lpar_register_process_table(__pa(process_tb), 0, PRTB_SIZE_SHIFT - 12); } +#endif #ifdef CONFIG_PPC_SMLPAR #define CMO_FREE_HINT_DEFAULT 1 diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c index b8d28ab88178..e278390ab28d 100644 --- a/arch/powerpc/platforms/pseries/lparcfg.c +++ b/arch/powerpc/platforms/pseries/lparcfg.c @@ -136,6 +136,39 @@ static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data) return rc; } +static void show_gpci_data(struct seq_file *m) +{ + struct hv_gpci_request_buffer *buf; + unsigned int affinity_score; + long ret; + + buf = kmalloc(sizeof(*buf), GFP_KERNEL); + if (buf == NULL) + return; + + /* + * Show the local LPAR's affinity score. + * + * 0xB1 selects the Affinity_Domain_Info_By_Partition subcall. + * The score is at byte 0xB in the output buffer. + */ + memset(&buf->params, 0, sizeof(buf->params)); + buf->params.counter_request = cpu_to_be32(0xB1); + buf->params.starting_index = cpu_to_be32(-1); /* local LPAR */ + buf->params.counter_info_version_in = 0x5; /* v5+ for score */ + ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO, virt_to_phys(buf), + sizeof(*buf)); + if (ret != H_SUCCESS) { + pr_debug("hcall failed: H_GET_PERF_COUNTER_INFO: %ld, %x\n", + ret, be32_to_cpu(buf->params.detail_rc)); + goto out; + } + affinity_score = buf->bytes[0xB]; + seq_printf(m, "partition_affinity_score=%u\n", affinity_score); +out: + kfree(buf); +} + static unsigned h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) { @@ -487,6 +520,8 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v) partition_active_processors * 100); } + show_gpci_data(m); + seq_printf(m, "partition_active_processors=%d\n", partition_active_processors); diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index f439f0dfea7d..835163f54244 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -785,7 +785,8 @@ static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc, static ssize_t perf_stats_show(struct device *dev, struct device_attribute *attr, char *buf) { - int index, rc; + int index; + ssize_t rc; struct seq_buf s; struct papr_scm_perf_stat *stat; struct papr_scm_perf_stats *stats; @@ -820,9 +821,9 @@ static ssize_t perf_stats_show(struct device *dev, free_stats: kfree(stats); - return rc ? rc : seq_buf_used(&s); + return rc ? rc : (ssize_t)seq_buf_used(&s); } -DEVICE_ATTR_RO(perf_stats); +static DEVICE_ATTR_ADMIN_RO(perf_stats); static ssize_t flags_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -897,6 +898,9 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p) p->bus_desc.of_node = p->pdev->dev.of_node; p->bus_desc.provider_name = kstrdup(p->pdev->name, GFP_KERNEL); + /* Set the dimm command family mask to accept PDSMs */ + set_bit(NVDIMM_FAMILY_PAPR, &p->bus_desc.dimm_family_mask); + if (!p->bus_desc.provider_name) return -ENOMEM; diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 13c86a292c6d..b2b245b25edb 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -521,18 +521,55 @@ int pSeries_system_reset_exception(struct pt_regs *regs) return 0; /* need to perform reset */ } +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: + /* + * Store the old slb content in paca before flushing. + * Print this when we go to virtual mode. + * There are chances that we may hit MCE again if there + * is a parity error on the SLB entry we trying to read + * for saving. Hence limit the slb saving to single + * level of recursion. + */ + if (local_paca->in_mce == 1) + slb_save_contents(local_paca->mce_faulty_slbs); + flush_and_reload_slb(); + disposition = RTAS_DISP_FULLY_RECOVERED; + break; + default: + break; + } + } else if (disposition == RTAS_DISP_LIMITED_RECOVERY) { + /* Platform corrected itself but could be degraded */ + pr_err("MCE: limited recovery, system may be degraded\n"); + disposition = RTAS_DISP_FULLY_RECOVERED; + } +#endif + return disposition; +} -static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp) +static int mce_handle_err_virtmode(struct pt_regs *regs, + struct rtas_error_log *errp, + struct pseries_mc_errorlog *mce_log, + int disposition) { struct mce_error_info mce_err = { 0 }; - unsigned long eaddr = 0, paddr = 0; - struct pseries_errorlog *pseries_log; - struct pseries_mc_errorlog *mce_log; - int disposition = rtas_error_disposition(errp); int initiator = rtas_error_initiator(errp); int severity = rtas_error_severity(errp); + unsigned long eaddr = 0, paddr = 0; u8 error_type, err_sub_type; + if (!mce_log) + goto out; + + error_type = mce_log->error_type; + err_sub_type = rtas_mc_error_sub_type(mce_log); + if (initiator == RTAS_INITIATOR_UNKNOWN) mce_err.initiator = MCE_INITIATOR_UNKNOWN; else if (initiator == RTAS_INITIATOR_CPU) @@ -571,18 +608,7 @@ static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp) mce_err.error_type = MCE_ERROR_TYPE_UNKNOWN; mce_err.error_class = MCE_ECLASS_UNKNOWN; - if (!rtas_error_extended(errp)) - goto out; - - pseries_log = get_pseries_errorlog(errp, PSERIES_ELOG_SECT_ID_MCE); - if (pseries_log == NULL) - goto out; - - mce_log = (struct pseries_mc_errorlog *)pseries_log->data; - error_type = mce_log->error_type; - err_sub_type = rtas_mc_error_sub_type(mce_log); - - switch (mce_log->error_type) { + switch (error_type) { case MC_ERROR_TYPE_UE: mce_err.error_type = MCE_ERROR_TYPE_UE; mce_common_process_ue(regs, &mce_err); @@ -682,37 +708,31 @@ static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp) mce_err.error_type = MCE_ERROR_TYPE_UNKNOWN; break; } +out: + save_mce_event(regs, disposition == RTAS_DISP_FULLY_RECOVERED, + &mce_err, regs->nip, eaddr, paddr); + return disposition; +} -#ifdef CONFIG_PPC_BOOK3S_64 - if (disposition == RTAS_DISP_NOT_RECOVERED) { - switch (error_type) { - case MC_ERROR_TYPE_SLB: - case MC_ERROR_TYPE_ERAT: - /* - * Store the old slb content in paca before flushing. - * Print this when we go to virtual mode. - * There are chances that we may hit MCE again if there - * is a parity error on the SLB entry we trying to read - * for saving. Hence limit the slb saving to single - * level of recursion. - */ - if (local_paca->in_mce == 1) - slb_save_contents(local_paca->mce_faulty_slbs); - flush_and_reload_slb(); - disposition = RTAS_DISP_FULLY_RECOVERED; - break; - default: - break; - } - } else if (disposition == RTAS_DISP_LIMITED_RECOVERY) { - /* Platform corrected itself but could be degraded */ - printk(KERN_ERR "MCE: limited recovery, system may " - "be degraded\n"); - disposition = RTAS_DISP_FULLY_RECOVERED; - } -#endif +static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp) +{ + struct pseries_errorlog *pseries_log; + struct pseries_mc_errorlog *mce_log = NULL; + int disposition = rtas_error_disposition(errp); + u8 error_type; + + if (!rtas_error_extended(errp)) + goto out; + + pseries_log = get_pseries_errorlog(errp, PSERIES_ELOG_SECT_ID_MCE); + if (!pseries_log) + goto out; + + mce_log = (struct pseries_mc_errorlog *)pseries_log->data; + error_type = mce_log->error_type; + + disposition = mce_handle_err_realmode(disposition, error_type); -out: /* * Enable translation as we will be accessing per-cpu variables * in save_mce_event() which may fall outside RMO region, also @@ -723,10 +743,10 @@ out: * Note: All the realmode handling like flushing SLB entries for * SLB multihit is done by now. */ +out: mtmsr(mfmsr() | MSR_IR | MSR_DR); - save_mce_event(regs, disposition == RTAS_DISP_FULLY_RECOVERED, - &mce_err, regs->nip, eaddr, paddr); - + disposition = mce_handle_err_virtmode(regs, errp, mce_log, + disposition); return disposition; } diff --git a/arch/powerpc/platforms/pseries/rng.c b/arch/powerpc/platforms/pseries/rng.c index bbb97169bf63..6268545947b8 100644 --- a/arch/powerpc/platforms/pseries/rng.c +++ b/arch/powerpc/platforms/pseries/rng.c @@ -36,6 +36,7 @@ static __init int rng_init(void) ppc_md.get_random_seed = pseries_get_random_long; + of_node_put(dn); return 0; } machine_subsys_initcall(pseries, rng_init); diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 2f4ee0a90284..633c45ec406d 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -519,9 +519,15 @@ static void init_cpu_char_feature_flags(struct h_cpu_char_result *result) if (result->character & H_CPU_CHAR_BCCTR_FLUSH_ASSIST) security_ftr_set(SEC_FTR_BCCTR_FLUSH_ASSIST); + if (result->character & H_CPU_CHAR_BCCTR_LINK_FLUSH_ASSIST) + security_ftr_set(SEC_FTR_BCCTR_LINK_FLUSH_ASSIST); + if (result->behaviour & H_CPU_BEHAV_FLUSH_COUNT_CACHE) security_ftr_set(SEC_FTR_FLUSH_COUNT_CACHE); + if (result->behaviour & H_CPU_BEHAV_FLUSH_LINK_STACK) + security_ftr_set(SEC_FTR_FLUSH_LINK_STACK); + /* * The features below are enabled by default, so we instead look to see * if firmware has *disabled* them, and clear them if so. diff --git a/arch/powerpc/platforms/pseries/svm.c b/arch/powerpc/platforms/pseries/svm.c index e6d7a344d9f2..7b739cc7a8a9 100644 --- a/arch/powerpc/platforms/pseries/svm.c +++ b/arch/powerpc/platforms/pseries/svm.c @@ -7,6 +7,7 @@ */ #include <linux/mm.h> +#include <linux/memblock.h> #include <asm/machdep.h> #include <asm/svm.h> #include <asm/swiotlb.h> @@ -35,6 +36,31 @@ static int __init init_svm(void) } machine_early_initcall(pseries, init_svm); +/* + * Initialize SWIOTLB. Essentially the same as swiotlb_init(), except that it + * can allocate the buffer anywhere in memory. Since the hypervisor doesn't have + * any addressing limitation, we don't need to allocate it in low addresses. + */ +void __init svm_swiotlb_init(void) +{ + unsigned char *vstart; + unsigned long bytes, io_tlb_nslabs; + + io_tlb_nslabs = (swiotlb_size_or_default() >> IO_TLB_SHIFT); + io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE); + + bytes = io_tlb_nslabs << IO_TLB_SHIFT; + + vstart = memblock_alloc(PAGE_ALIGN(bytes), PAGE_SIZE); + if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, false)) + return; + + if (io_tlb_start) + memblock_free_early(io_tlb_start, + PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); + panic("SVM: Cannot allocate SWIOTLB buffer"); +} + int set_memory_encrypted(unsigned long addr, int numpages) { if (!PAGE_ALIGNED(addr)) diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c index 0487b26f6f1a..b2797cfe4e2b 100644 --- a/arch/powerpc/platforms/pseries/vio.c +++ b/arch/powerpc/platforms/pseries/vio.c @@ -20,7 +20,7 @@ #include <linux/console.h> #include <linux/export.h> #include <linux/mm.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/kobject.h> #include <asm/iommu.h> @@ -608,6 +608,8 @@ static const struct dma_map_ops vio_dma_mapping_ops = { .get_required_mask = dma_iommu_get_required_mask, .mmap = dma_common_mmap, .get_sgtable = dma_common_get_sgtable, + .alloc_pages = dma_common_alloc_pages, + .free_pages = dma_common_free_pages, }; /** diff --git a/arch/powerpc/sysdev/xics/icp-hv.c b/arch/powerpc/sysdev/xics/icp-hv.c index ad8117148ea3..21b9d1bf39ff 100644 --- a/arch/powerpc/sysdev/xics/icp-hv.c +++ b/arch/powerpc/sysdev/xics/icp-hv.c @@ -174,6 +174,7 @@ int icp_hv_init(void) icp_ops = &icp_hv_ops; + of_node_put(np); return 0; } diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index f591be9f01f4..a80440af491a 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -1565,7 +1565,7 @@ static int __init xive_off(char *arg) } __setup("xive=off", xive_off); -void xive_debug_show_cpu(struct seq_file *m, int cpu) +static void xive_debug_show_cpu(struct seq_file *m, int cpu) { struct xive_cpu *xc = per_cpu(xive_cpu, cpu); @@ -1599,7 +1599,7 @@ void xive_debug_show_cpu(struct seq_file *m, int cpu) seq_puts(m, "\n"); } -void xive_debug_show_irq(struct seq_file *m, u32 hw_irq, struct irq_data *d) +static void xive_debug_show_irq(struct seq_file *m, u32 hw_irq, struct irq_data *d) { struct irq_chip *chip = irq_data_get_irq_chip(d); int rc; diff --git a/arch/powerpc/tools/checkpatch.sh b/arch/powerpc/tools/checkpatch.sh index 3ce5c093b19d..91c04802ec31 100755 --- a/arch/powerpc/tools/checkpatch.sh +++ b/arch/powerpc/tools/checkpatch.sh @@ -9,7 +9,6 @@ script_base=$(realpath $(dirname $0)) exec $script_base/../../../scripts/checkpatch.pl \ --subjective \ --no-summary \ - --max-line-length=90 \ --show-types \ --ignore ARCH_INCLUDE_LINUX \ --ignore BIT_MACRO \ diff --git a/arch/powerpc/tools/unrel_branch_check.sh b/arch/powerpc/tools/unrel_branch_check.sh index 6e6a30aea3ed..8301efee1e6c 100755 --- a/arch/powerpc/tools/unrel_branch_check.sh +++ b/arch/powerpc/tools/unrel_branch_check.sh @@ -1,60 +1,79 @@ -# Copyright © 2016 IBM Corporation +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0+ +# Copyright © 2016,2020 IBM Corporation # -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version -# 2 of the License, or (at your option) any later version. -# -# This script checks the relocations of a vmlinux for "suspicious" -# branches from unrelocated code (head_64.S code). - -# Turn this on if you want more debug output: -# set -x +# This script checks the unrelocated code of a vmlinux for "suspicious" +# branches to relocated code (head_64.S code). -# Have Kbuild supply the path to objdump so we handle cross compilation. +# Have Kbuild supply the path to objdump and nm so we handle cross compilation. objdump="$1" -vmlinux="$2" - -#__end_interrupts should be located within the first 64K - -end_intr=0x$( -$objdump -R "$vmlinux" -d --start-address=0xc000000000000000 \ - --stop-address=0xc000000000010000 | -grep '\<__end_interrupts>:' | -awk '{print $1}' -) - -BRANCHES=$( -$objdump -R "$vmlinux" -D --start-address=0xc000000000000000 \ - --stop-address=${end_intr} | -grep -e "^c[0-9a-f]*:[[:space:]]*\([0-9a-f][0-9a-f][[:space:]]\)\{4\}[[:space:]]*b" | -grep -v '\<__start_initialization_multiplatform>' | -grep -v -e 'b.\?.\?ctr' | -grep -v -e 'b.\?.\?lr' | -sed -e 's/\bbt.\?[[:space:]]*[[:digit:]][[:digit:]]*,/beq/' \ - -e 's/\bbf.\?[[:space:]]*[[:digit:]][[:digit:]]*,/bne/' \ - -e 's/[[:space:]]0x/ /' \ - -e 's/://' | -awk '{ print $1 ":" $6 ":0x" $7 ":" $8 " "}' -) - -for tuple in $BRANCHES -do - from=`echo $tuple | cut -d':' -f1` - branch=`echo $tuple | cut -d':' -f2` - to=`echo $tuple | cut -d':' -f3 | sed 's/cr[0-7],//'` - sym=`echo $tuple | cut -d':' -f4` - - if (( $to > $end_intr )) - then - if [ -z "$bad_branches" ]; then - echo "WARNING: Unrelocated relative branches" - bad_branches="yes" +nm="$2" +vmlinux="$3" + +kstart=0xc000000000000000 + +end_intr=0x$($nm -p "$vmlinux" | + sed -E -n '/\s+[[:alpha:]]\s+__end_interrupts\s*$/{s///p;q}') +if [ "$end_intr" = "0x" ]; then + exit 0 +fi + +# we know that there is a correct branch to +# __start_initialization_multiplatform, so find its address +# so we can exclude it. +sim=0x$($nm -p "$vmlinux" | + sed -E -n '/\s+[[:alpha:]]\s+__start_initialization_multiplatform\s*$/{s///p;q}') + +$objdump -D --no-show-raw-insn --start-address="$kstart" --stop-address="$end_intr" "$vmlinux" | +sed -E -n ' +# match lines that start with a kernel address +/^c[0-9a-f]*:\s*b/ { + # drop branches via ctr or lr + /\<b.?.?(ct|l)r/d + # cope with some differences between Clang and GNU objdumps + s/\<bt.?\s*[[:digit:]]+,/beq/ + s/\<bf.?\s*[[:digit:]]+,/bne/ + # tidy up + s/\s0x/ / + s/:// + # format for the loop below + s/^(\S+)\s+(\S+)\s+(\S+)\s*(\S*).*$/\1:\2:\3:\4/ + # strip out condition registers + s/:cr[0-7],/:/ + p +}' | { + +all_good=true +while IFS=: read -r from branch to sym; do + case "$to" in + c*) to="0x$to" + ;; + .+*) + to=${to#.+} + if [ "$branch" = 'b' ]; then + if (( to >= 0x2000000 )); then + to=$(( to - 0x4000000 )) + fi + elif (( to >= 0x8000 )); then + to=$(( to - 0x10000 )) + fi + printf -v to '0x%x' $(( "0x$from" + to )) + ;; + *) printf 'Unkown branch format\n' + ;; + esac + if [ "$to" = "$sim" ]; then + continue + fi + if (( to > end_intr )); then + if $all_good; then + printf '%s\n' 'WARNING: Unrelocated relative branches' + all_good=false fi - echo "$from $branch-> $to $sym" + printf '%s %s-> %s %s\n' "$from" "$branch" "$to" "$sym" fi done -if [ -z "$bad_branches" ]; then - exit 0 -fi +$all_good + +} diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index df7bca00f5ec..55c43a6c9111 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -969,6 +969,7 @@ static void insert_cpu_bpts(void) brk.address = dabr[i].address; brk.type = (dabr[i].enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL; brk.len = 8; + brk.hw_len = 8; __set_breakpoint(i, &brk); } } diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index df18372861d8..44377fd7860e 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -32,11 +32,13 @@ config RISCV select ARCH_WANT_FRAME_POINTERS select ARCH_WANT_HUGE_PMD_SHARE if 64BIT select CLONE_BACKWARDS + select CLINT_TIMER if !MMU select COMMON_CLK select EDAC_SUPPORT select GENERIC_ARCH_TOPOLOGY if SMP select GENERIC_ATOMIC64 if !64BIT select GENERIC_CLOCKEVENTS + select GENERIC_EARLY_IOREMAP select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO select GENERIC_IOREMAP select GENERIC_IRQ_MULTI_HANDLER @@ -86,6 +88,7 @@ config RISCV select SPARSE_IRQ select SYSCTL_EXCEPTION_TRACE select THREAD_INFO_IN_TASK + select UACCESS_MEMCPY if !MMU config ARCH_MMAP_RND_BITS_MIN default 18 if 64BIT @@ -333,19 +336,6 @@ menu "Kernel features" source "kernel/Kconfig.hz" -config SECCOMP - bool "Enable seccomp to safely compute untrusted bytecode" - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via prctl(PR_SET_SECCOMP), it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - config RISCV_SBI_V01 bool "SBI v0.1 support" default y @@ -400,6 +390,28 @@ config CMDLINE_FORCE endchoice +config EFI_STUB + bool + +config EFI + bool "UEFI runtime support" + depends on OF + select LIBFDT + select UCS2_STRING + select EFI_PARAMS_FROM_FDT + select EFI_STUB + select EFI_GENERIC_STUB + select EFI_RUNTIME_WRAPPERS + select RISCV_ISA_C + depends on MMU + default y + help + This option provides support for runtime services provided + by UEFI firmware (such as non-volatile variables, realtime + clock, and platform reset). A UEFI stub is also provided to + allow the kernel to be booted as an EFI application. This + is only useful on systems that have UEFI firmware. + endmenu config BUILTIN_DTB @@ -412,3 +424,5 @@ menu "Power management options" source "kernel/power/Kconfig" endmenu + +source "drivers/firmware/Kconfig" diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index fb6e37db836d..0289a97325d1 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -53,9 +53,6 @@ endif ifeq ($(CONFIG_CMODEL_MEDANY),y) KBUILD_CFLAGS += -mcmodel=medany endif -ifeq ($(CONFIG_MODULE_SECTIONS),y) - KBUILD_LDS_MODULE += $(srctree)/arch/riscv/kernel/module.lds -endif ifeq ($(CONFIG_PERF_EVENTS),y) KBUILD_CFLAGS += -fno-omit-frame-pointer endif @@ -80,6 +77,7 @@ head-y := arch/riscv/kernel/head.o core-y += arch/riscv/ libs-y += arch/riscv/lib/ +libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a PHONY += vdso_install vdso_install: diff --git a/arch/riscv/boot/dts/kendryte/k210.dtsi b/arch/riscv/boot/dts/kendryte/k210.dtsi index c1df56ccb8d5..d2d0ff645632 100644 --- a/arch/riscv/boot/dts/kendryte/k210.dtsi +++ b/arch/riscv/boot/dts/kendryte/k210.dtsi @@ -95,10 +95,12 @@ #clock-cells = <1>; }; - clint0: interrupt-controller@2000000 { + clint0: clint@2000000 { + #interrupt-cells = <1>; compatible = "riscv,clint0"; reg = <0x2000000 0xC000>; - interrupts-extended = <&cpu0_intc 3>, <&cpu1_intc 3>; + interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7 + &cpu1_intc 3 &cpu1_intc 7>; clocks = <&sysctl K210_CLK_ACLK>; }; diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig index d58c93efb603..d222d353d86d 100644 --- a/arch/riscv/configs/defconfig +++ b/arch/riscv/configs/defconfig @@ -130,3 +130,4 @@ CONFIG_DEBUG_BLOCK_EXT_DEVT=y # CONFIG_RUNTIME_TESTING_MENU is not set CONFIG_MEMTEST=y # CONFIG_SYSFS_SYSCALL is not set +CONFIG_EFI=y diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild index 3d9410bb4de0..59dd7be55005 100644 --- a/arch/riscv/include/asm/Kbuild +++ b/arch/riscv/include/asm/Kbuild @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +generic-y += early_ioremap.h generic-y += extable.h generic-y += flat.h generic-y += kvm_para.h diff --git a/arch/riscv/include/asm/cacheinfo.h b/arch/riscv/include/asm/cacheinfo.h index 5d9662e9aba8..d1a365215ec0 100644 --- a/arch/riscv/include/asm/cacheinfo.h +++ b/arch/riscv/include/asm/cacheinfo.h @@ -1,4 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 SiFive + */ #ifndef _ASM_RISCV_CACHEINFO_H #define _ASM_RISCV_CACHEINFO_H @@ -11,5 +14,7 @@ struct riscv_cacheinfo_ops { }; void riscv_set_cacheinfo_ops(struct riscv_cacheinfo_ops *ops); +uintptr_t get_cache_size(u32 level, enum cache_type type); +uintptr_t get_cache_geometry(u32 level, enum cache_type type); #endif /* _ASM_RISCV_CACHEINFO_H */ diff --git a/arch/riscv/include/asm/clint.h b/arch/riscv/include/asm/clint.h new file mode 100644 index 000000000000..0789fd37b40a --- /dev/null +++ b/arch/riscv/include/asm/clint.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Google, Inc + */ + +#ifndef _ASM_RISCV_CLINT_H +#define _ASM_RISCV_CLINT_H + +#include <linux/types.h> +#include <asm/mmio.h> + +#ifdef CONFIG_RISCV_M_MODE +/* + * This lives in the CLINT driver, but is accessed directly by timex.h to avoid + * any overhead when accessing the MMIO timer. + * + * The ISA defines mtime as a 64-bit memory-mapped register that increments at + * a constant frequency, but it doesn't define some other constraints we depend + * on (most notably ordering constraints, but also some simpler stuff like the + * memory layout). Thus, this is called "clint_time_val" instead of something + * like "riscv_mtime", to signify that these non-ISA assumptions must hold. + */ +extern u64 __iomem *clint_time_val; +#endif + +#endif diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h new file mode 100644 index 000000000000..7542282f1141 --- /dev/null +++ b/arch/riscv/include/asm/efi.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + */ +#ifndef _ASM_EFI_H +#define _ASM_EFI_H + +#include <asm/csr.h> +#include <asm/io.h> +#include <asm/mmu_context.h> +#include <asm/ptrace.h> +#include <asm/tlbflush.h> + +#ifdef CONFIG_EFI +extern void efi_init(void); +#else +#define efi_init() +#endif + +int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); +int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); + +#define arch_efi_call_virt_setup() efi_virtmap_load() +#define arch_efi_call_virt_teardown() efi_virtmap_unload() + +#define arch_efi_call_virt(p, f, args...) p->f(args) + +#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) +{ + return image_addr + SZ_256M; +} + +#define alloc_screen_info(x...) (&screen_info) + +static inline void free_screen_info(struct screen_info *si) +{ +} + +static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) +{ +} + +void efi_virtmap_load(void); +void efi_virtmap_unload(void); + +#endif /* _ASM_EFI_H */ diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h index d83a4efd052b..5c725e1df58b 100644 --- a/arch/riscv/include/asm/elf.h +++ b/arch/riscv/include/asm/elf.h @@ -11,6 +11,7 @@ #include <uapi/asm/elf.h> #include <asm/auxvec.h> #include <asm/byteorder.h> +#include <asm/cacheinfo.h> /* * These are used to set parameters in the core dumps. @@ -61,6 +62,18 @@ extern unsigned long elf_hwcap; do { \ NEW_AUX_ENT(AT_SYSINFO_EHDR, \ (elf_addr_t)current->mm->context.vdso); \ + NEW_AUX_ENT(AT_L1I_CACHESIZE, \ + get_cache_size(1, CACHE_TYPE_INST)); \ + NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY, \ + get_cache_geometry(1, CACHE_TYPE_INST)); \ + NEW_AUX_ENT(AT_L1D_CACHESIZE, \ + get_cache_size(1, CACHE_TYPE_DATA)); \ + NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY, \ + get_cache_geometry(1, CACHE_TYPE_DATA)); \ + NEW_AUX_ENT(AT_L2_CACHESIZE, \ + get_cache_size(2, CACHE_TYPE_UNIFIED)); \ + NEW_AUX_ENT(AT_L2_CACHEGEOMETRY, \ + get_cache_geometry(2, CACHE_TYPE_UNIFIED)); \ } while (0) #define ARCH_HAS_SETUP_ADDITIONAL_PAGES struct linux_binprm; diff --git a/arch/riscv/include/asm/fixmap.h b/arch/riscv/include/asm/fixmap.h index 1ff075a8dfc7..54cbf07fb4e9 100644 --- a/arch/riscv/include/asm/fixmap.h +++ b/arch/riscv/include/asm/fixmap.h @@ -22,14 +22,24 @@ */ enum fixed_addresses { FIX_HOLE, -#define FIX_FDT_SIZE SZ_1M - FIX_FDT_END, - FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1, FIX_PTE, FIX_PMD, FIX_TEXT_POKE1, FIX_TEXT_POKE0, FIX_EARLYCON_MEM_BASE, + + __end_of_permanent_fixed_addresses, + /* + * Temporary boot-time mappings, used by early_ioremap(), + * before ioremap() is functional. + */ +#define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE) +#define FIX_BTMAPS_SLOTS 7 +#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS) + + FIX_BTMAP_END = __end_of_permanent_fixed_addresses, + FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1, + __end_of_fixed_addresses }; diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h index ace8a6e2d11d..845002cc2e57 100644 --- a/arch/riscv/include/asm/ftrace.h +++ b/arch/riscv/include/asm/ftrace.h @@ -66,6 +66,13 @@ do { \ * Let auipc+jalr be the basic *mcount unit*, so we make it 8 bytes here. */ #define MCOUNT_INSN_SIZE 8 + +#ifndef __ASSEMBLY__ +struct dyn_ftrace; +int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec); +#define ftrace_init_nop ftrace_init_nop +#endif + #endif #endif /* _ASM_RISCV_FTRACE_H */ diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h index 3835c3295dc5..c025a746a148 100644 --- a/arch/riscv/include/asm/io.h +++ b/arch/riscv/include/asm/io.h @@ -14,6 +14,7 @@ #include <linux/types.h> #include <linux/pgtable.h> #include <asm/mmiowb.h> +#include <asm/early_ioremap.h> /* * MMIO access functions are separated out to break dependency cycles diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h index 967eacb01ab5..dabcf2cfb3dc 100644 --- a/arch/riscv/include/asm/mmu.h +++ b/arch/riscv/include/asm/mmu.h @@ -20,6 +20,8 @@ typedef struct { #endif } mm_context_t; +void __init create_pgd_mapping(pgd_t *pgdp, uintptr_t va, phys_addr_t pa, + phys_addr_t sz, pgprot_t prot); #endif /* __ASSEMBLY__ */ #endif /* _ASM_RISCV_MMU_H */ diff --git a/arch/riscv/kernel/module.lds b/arch/riscv/include/asm/module.lds.h index 295ecfb341a2..4254ff2ff049 100644 --- a/arch/riscv/kernel/module.lds +++ b/arch/riscv/include/asm/module.lds.h @@ -1,8 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2017 Andes Technology Corporation */ - +#ifdef CONFIG_MODULE_SECTIONS SECTIONS { .plt (NOLOAD) : { BYTE(0) } .got (NOLOAD) : { BYTE(0) } .got.plt (NOLOAD) : { BYTE(0) } } +#endif diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index eaea1f717010..183f1f4b2ae6 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -100,6 +100,10 @@ #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) \ + | _PAGE_EXEC) #define PAGE_TABLE __pgprot(_PAGE_TABLE) @@ -464,6 +468,7 @@ static inline void __kernel_map_pages(struct page *page, int numpages, int enabl #define kern_addr_valid(addr) (1) /* FIXME */ extern void *dtb_early_va; +extern uintptr_t dtb_early_pa; void setup_bootmem(void); void paging_init(void); diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h new file mode 100644 index 000000000000..3a9971b1210f --- /dev/null +++ b/arch/riscv/include/asm/sections.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + */ +#ifndef __ASM_SECTIONS_H +#define __ASM_SECTIONS_H + +#include <asm-generic/sections.h> + +extern char _start[]; +extern char _start_kernel[]; + +#endif /* __ASM_SECTIONS_H */ diff --git a/arch/riscv/include/asm/soc.h b/arch/riscv/include/asm/soc.h index 136a442ef876..6c8363b1f327 100644 --- a/arch/riscv/include/asm/soc.h +++ b/arch/riscv/include/asm/soc.h @@ -13,7 +13,7 @@ #define SOC_EARLY_INIT_DECLARE(name, compat, fn) \ static const struct of_device_id __soc_early_init__##name \ - __used __section(__soc_early_init_table) \ + __used __section("__soc_early_init_table") \ = { .compatible = compat, .data = fn } void soc_early_init(void); @@ -46,7 +46,7 @@ struct soc_builtin_dtb { } \ \ static const struct soc_builtin_dtb __soc_builtin_dtb__##name \ - __used __section(__soc_builtin_dtb_table) = \ + __used __section("__soc_builtin_dtb_table") = \ { \ .vendor_id = vendor, \ .arch_id = arch, \ diff --git a/arch/riscv/include/asm/stackprotector.h b/arch/riscv/include/asm/stackprotector.h index d95f7b2a7f37..5962f8891f06 100644 --- a/arch/riscv/include/asm/stackprotector.h +++ b/arch/riscv/include/asm/stackprotector.h @@ -5,7 +5,6 @@ #include <linux/random.h> #include <linux/version.h> -#include <asm/timex.h> extern unsigned long __stack_chk_guard; @@ -18,12 +17,9 @@ extern unsigned long __stack_chk_guard; static __always_inline void boot_init_stack_canary(void) { unsigned long canary; - unsigned long tsc; /* Try to get a semi random initial value. */ get_random_bytes(&canary, sizeof(canary)); - tsc = get_cycles(); - canary += tsc + (tsc << BITS_PER_LONG/2); canary ^= LINUX_VERSION_CODE; canary &= CANARY_MASK; diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h index 464a2bbc97ea..a390711129de 100644 --- a/arch/riscv/include/asm/thread_info.h +++ b/arch/riscv/include/asm/thread_info.h @@ -24,10 +24,6 @@ #include <asm/processor.h> #include <asm/csr.h> -typedef struct { - unsigned long seg; -} mm_segment_t; - /* * low level task data that entry.S needs immediate access to * - this struct should fit entirely inside of one cache line @@ -39,7 +35,6 @@ typedef struct { struct thread_info { unsigned long flags; /* low level flags */ int preempt_count; /* 0=>preemptible, <0=>BUG */ - mm_segment_t addr_limit; /* * These stack pointers are overwritten on every system call or * exception. SP is also saved to the stack it can be recovered when @@ -59,7 +54,6 @@ struct thread_info { { \ .flags = 0, \ .preempt_count = INIT_PREEMPT_COUNT, \ - .addr_limit = KERNEL_DS, \ } #endif /* !__ASSEMBLY__ */ diff --git a/arch/riscv/include/asm/timex.h b/arch/riscv/include/asm/timex.h index a3fb85d505d4..ab104905d4db 100644 --- a/arch/riscv/include/asm/timex.h +++ b/arch/riscv/include/asm/timex.h @@ -10,6 +10,44 @@ typedef unsigned long cycles_t; +#ifdef CONFIG_RISCV_M_MODE + +#include <asm/clint.h> + +#ifdef CONFIG_64BIT +static inline cycles_t get_cycles(void) +{ + return readq_relaxed(clint_time_val); +} +#else /* !CONFIG_64BIT */ +static inline u32 get_cycles(void) +{ + return readl_relaxed(((u32 *)clint_time_val)); +} +#define get_cycles get_cycles + +static inline u32 get_cycles_hi(void) +{ + return readl_relaxed(((u32 *)clint_time_val) + 1); +} +#define get_cycles_hi get_cycles_hi +#endif /* CONFIG_64BIT */ + +/* + * Much like MIPS, we may not have a viable counter to use at an early point + * in the boot process. Unfortunately we don't have a fallback, so instead + * we just return 0. + */ +static inline unsigned long random_get_entropy(void) +{ + if (unlikely(clint_time_val == NULL)) + return 0; + return get_cycles(); +} +#define random_get_entropy() random_get_entropy() + +#else /* CONFIG_RISCV_M_MODE */ + static inline cycles_t get_cycles(void) { return csr_read(CSR_TIME); @@ -41,6 +79,8 @@ static inline u64 get_cycles64(void) } #endif /* CONFIG_64BIT */ +#endif /* !CONFIG_RISCV_M_MODE */ + #define ARCH_HAS_READ_CURRENT_TIMER static inline int read_current_timer(unsigned long *timer_val) { diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h index f56c66b3f5fe..c47e6b35c551 100644 --- a/arch/riscv/include/asm/uaccess.h +++ b/arch/riscv/include/asm/uaccess.h @@ -13,24 +13,6 @@ /* * User space memory access functions */ - -extern unsigned long __must_check __asm_copy_to_user(void __user *to, - const void *from, unsigned long n); -extern unsigned long __must_check __asm_copy_from_user(void *to, - const void __user *from, unsigned long n); - -static inline unsigned long -raw_copy_from_user(void *to, const void __user *from, unsigned long n) -{ - return __asm_copy_from_user(to, from, n); -} - -static inline unsigned long -raw_copy_to_user(void __user *to, const void *from, unsigned long n) -{ - return __asm_copy_to_user(to, from, n); -} - #ifdef CONFIG_MMU #include <linux/errno.h> #include <linux/compiler.h> @@ -44,29 +26,6 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n) #define __disable_user_access() \ __asm__ __volatile__ ("csrc sstatus, %0" : : "r" (SR_SUM) : "memory") -/* - * The fs value determines whether argument validity checking should be - * performed or not. If get_fs() == USER_DS, checking is performed, with - * get_fs() == KERNEL_DS, checking is bypassed. - * - * For historical reasons, these macros are grossly misnamed. - */ - -#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) - -#define KERNEL_DS MAKE_MM_SEG(~0UL) -#define USER_DS MAKE_MM_SEG(TASK_SIZE) - -#define get_fs() (current_thread_info()->addr_limit) - -static inline void set_fs(mm_segment_t fs) -{ - current_thread_info()->addr_limit = fs; -} - -#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg) -#define user_addr_max() (get_fs().seg) - /** * access_ok: - Checks if a user space pointer is valid * @addr: User space pointer to start of block to check @@ -94,9 +53,7 @@ static inline void set_fs(mm_segment_t fs) */ static inline int __access_ok(unsigned long addr, unsigned long size) { - const mm_segment_t fs = get_fs(); - - return size <= fs.seg && addr <= fs.seg - size; + return size <= TASK_SIZE && addr <= TASK_SIZE - size; } /* @@ -125,7 +82,6 @@ static inline int __access_ok(unsigned long addr, unsigned long size) do { \ uintptr_t __tmp; \ __typeof__(x) __x; \ - __enable_user_access(); \ __asm__ __volatile__ ( \ "1:\n" \ " " insn " %1, %3\n" \ @@ -143,7 +99,6 @@ do { \ " .previous" \ : "+r" (err), "=&r" (__x), "=r" (__tmp) \ : "m" (*(ptr)), "i" (-EFAULT)); \ - __disable_user_access(); \ (x) = __x; \ } while (0) @@ -156,7 +111,6 @@ do { \ u32 __user *__ptr = (u32 __user *)(ptr); \ u32 __lo, __hi; \ uintptr_t __tmp; \ - __enable_user_access(); \ __asm__ __volatile__ ( \ "1:\n" \ " lw %1, %4\n" \ @@ -180,12 +134,30 @@ do { \ "=r" (__tmp) \ : "m" (__ptr[__LSW]), "m" (__ptr[__MSW]), \ "i" (-EFAULT)); \ - __disable_user_access(); \ (x) = (__typeof__(x))((__typeof__((x)-(x)))( \ (((u64)__hi << 32) | __lo))); \ } while (0) #endif /* CONFIG_64BIT */ +#define __get_user_nocheck(x, __gu_ptr, __gu_err) \ +do { \ + switch (sizeof(*__gu_ptr)) { \ + case 1: \ + __get_user_asm("lb", (x), __gu_ptr, __gu_err); \ + break; \ + case 2: \ + __get_user_asm("lh", (x), __gu_ptr, __gu_err); \ + break; \ + case 4: \ + __get_user_asm("lw", (x), __gu_ptr, __gu_err); \ + break; \ + case 8: \ + __get_user_8((x), __gu_ptr, __gu_err); \ + break; \ + default: \ + BUILD_BUG(); \ + } \ +} while (0) /** * __get_user: - Get a simple variable from user space, with less checking. @@ -209,25 +181,15 @@ do { \ */ #define __get_user(x, ptr) \ ({ \ - register long __gu_err = 0; \ const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ + long __gu_err = 0; \ + \ __chk_user_ptr(__gu_ptr); \ - switch (sizeof(*__gu_ptr)) { \ - case 1: \ - __get_user_asm("lb", (x), __gu_ptr, __gu_err); \ - break; \ - case 2: \ - __get_user_asm("lh", (x), __gu_ptr, __gu_err); \ - break; \ - case 4: \ - __get_user_asm("lw", (x), __gu_ptr, __gu_err); \ - break; \ - case 8: \ - __get_user_8((x), __gu_ptr, __gu_err); \ - break; \ - default: \ - BUILD_BUG(); \ - } \ + \ + __enable_user_access(); \ + __get_user_nocheck(x, __gu_ptr, __gu_err); \ + __disable_user_access(); \ + \ __gu_err; \ }) @@ -261,7 +223,6 @@ do { \ do { \ uintptr_t __tmp; \ __typeof__(*(ptr)) __x = x; \ - __enable_user_access(); \ __asm__ __volatile__ ( \ "1:\n" \ " " insn " %z3, %2\n" \ @@ -278,7 +239,6 @@ do { \ " .previous" \ : "+r" (err), "=r" (__tmp), "=m" (*(ptr)) \ : "rJ" (__x), "i" (-EFAULT)); \ - __disable_user_access(); \ } while (0) #ifdef CONFIG_64BIT @@ -290,7 +250,6 @@ do { \ u32 __user *__ptr = (u32 __user *)(ptr); \ u64 __x = (__typeof__((x)-(x)))(x); \ uintptr_t __tmp; \ - __enable_user_access(); \ __asm__ __volatile__ ( \ "1:\n" \ " sw %z4, %2\n" \ @@ -312,10 +271,28 @@ do { \ "=m" (__ptr[__LSW]), \ "=m" (__ptr[__MSW]) \ : "rJ" (__x), "rJ" (__x >> 32), "i" (-EFAULT)); \ - __disable_user_access(); \ } while (0) #endif /* CONFIG_64BIT */ +#define __put_user_nocheck(x, __gu_ptr, __pu_err) \ +do { \ + switch (sizeof(*__gu_ptr)) { \ + case 1: \ + __put_user_asm("sb", (x), __gu_ptr, __pu_err); \ + break; \ + case 2: \ + __put_user_asm("sh", (x), __gu_ptr, __pu_err); \ + break; \ + case 4: \ + __put_user_asm("sw", (x), __gu_ptr, __pu_err); \ + break; \ + case 8: \ + __put_user_8((x), __gu_ptr, __pu_err); \ + break; \ + default: \ + BUILD_BUG(); \ + } \ +} while (0) /** * __put_user: - Write a simple value into user space, with less checking. @@ -338,25 +315,15 @@ do { \ */ #define __put_user(x, ptr) \ ({ \ - register long __pu_err = 0; \ __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ + long __pu_err = 0; \ + \ __chk_user_ptr(__gu_ptr); \ - switch (sizeof(*__gu_ptr)) { \ - case 1: \ - __put_user_asm("sb", (x), __gu_ptr, __pu_err); \ - break; \ - case 2: \ - __put_user_asm("sh", (x), __gu_ptr, __pu_err); \ - break; \ - case 4: \ - __put_user_asm("sw", (x), __gu_ptr, __pu_err); \ - break; \ - case 8: \ - __put_user_8((x), __gu_ptr, __pu_err); \ - break; \ - default: \ - BUILD_BUG(); \ - } \ + \ + __enable_user_access(); \ + __put_user_nocheck(x, __gu_ptr, __pu_err); \ + __disable_user_access(); \ + \ __pu_err; \ }) @@ -385,6 +352,24 @@ do { \ -EFAULT; \ }) + +unsigned long __must_check __asm_copy_to_user(void __user *to, + const void *from, unsigned long n); +unsigned long __must_check __asm_copy_from_user(void *to, + const void __user *from, unsigned long n); + +static inline unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long n) +{ + return __asm_copy_from_user(to, from, n); +} + +static inline unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) +{ + return __asm_copy_to_user(to, from, n); +} + extern long strncpy_from_user(char *dest, const char __user *src, long count); extern long __must_check strlen_user(const char __user *str); @@ -476,6 +461,26 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n) __ret; \ }) +#define HAVE_GET_KERNEL_NOFAULT + +#define __get_kernel_nofault(dst, src, type, err_label) \ +do { \ + long __kr_err; \ + \ + __get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \ + if (unlikely(__kr_err)) \ + goto err_label; \ +} while (0) + +#define __put_kernel_nofault(dst, src, type, err_label) \ +do { \ + long __kr_err; \ + \ + __put_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \ + if (unlikely(__kr_err)) \ + goto err_label; \ +} while (0) + #else /* CONFIG_MMU */ #include <asm-generic/uaccess.h> #endif /* CONFIG_MMU */ diff --git a/arch/riscv/include/uapi/asm/auxvec.h b/arch/riscv/include/uapi/asm/auxvec.h index d86cb17bbabe..32c73ba1d531 100644 --- a/arch/riscv/include/uapi/asm/auxvec.h +++ b/arch/riscv/include/uapi/asm/auxvec.h @@ -10,4 +10,28 @@ /* vDSO location */ #define AT_SYSINFO_EHDR 33 +/* + * The set of entries below represent more extensive information + * about the caches, in the form of two entry per cache type, + * one entry containing the cache size in bytes, and the other + * containing the cache line size in bytes in the bottom 16 bits + * and the cache associativity in the next 16 bits. + * + * The associativity is such that if N is the 16-bit value, the + * cache is N way set associative. A value if 0xffff means fully + * associative, a value of 1 means directly mapped. + * + * For all these fields, a value of 0 means that the information + * is not known. + */ +#define AT_L1I_CACHESIZE 40 +#define AT_L1I_CACHEGEOMETRY 41 +#define AT_L1D_CACHESIZE 42 +#define AT_L1D_CACHEGEOMETRY 43 +#define AT_L2_CACHESIZE 44 +#define AT_L2_CACHEGEOMETRY 45 + +/* entries in ARCH_DLINFO */ +#define AT_VECTOR_SIZE_ARCH 7 + #endif /* _UAPI_ASM_RISCV_AUXVEC_H */ diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index dc93710f0b2f..fa896c5f7ccb 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -55,4 +55,6 @@ obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o +obj-$(CONFIG_EFI) += efi.o + clean: diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c index bd0f122965c3..de59dd457b41 100644 --- a/arch/riscv/kernel/cacheinfo.c +++ b/arch/riscv/kernel/cacheinfo.c @@ -3,7 +3,6 @@ * Copyright (C) 2017 SiFive */ -#include <linux/cacheinfo.h> #include <linux/cpu.h> #include <linux/of.h> #include <linux/of_device.h> @@ -25,12 +24,84 @@ cache_get_priv_group(struct cacheinfo *this_leaf) return NULL; } -static void ci_leaf_init(struct cacheinfo *this_leaf, - struct device_node *node, - enum cache_type type, unsigned int level) +static struct cacheinfo *get_cacheinfo(u32 level, enum cache_type type) +{ + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(smp_processor_id()); + struct cacheinfo *this_leaf; + int index; + + for (index = 0; index < this_cpu_ci->num_leaves; index++) { + this_leaf = this_cpu_ci->info_list + index; + if (this_leaf->level == level && this_leaf->type == type) + return this_leaf; + } + + return NULL; +} + +uintptr_t get_cache_size(u32 level, enum cache_type type) +{ + struct cacheinfo *this_leaf = get_cacheinfo(level, type); + + return this_leaf ? this_leaf->size : 0; +} + +uintptr_t get_cache_geometry(u32 level, enum cache_type type) +{ + struct cacheinfo *this_leaf = get_cacheinfo(level, type); + + return this_leaf ? (this_leaf->ways_of_associativity << 16 | + this_leaf->coherency_line_size) : + 0; +} + +static void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type, + unsigned int level, unsigned int size, + unsigned int sets, unsigned int line_size) { this_leaf->level = level; this_leaf->type = type; + this_leaf->size = size; + this_leaf->number_of_sets = sets; + this_leaf->coherency_line_size = line_size; + + /* + * If the cache is fully associative, there is no need to + * check the other properties. + */ + if (sets == 1) + return; + + /* + * Set the ways number for n-ways associative, make sure + * all properties are big than zero. + */ + if (sets > 0 && size > 0 && line_size > 0) + this_leaf->ways_of_associativity = (size / sets) / line_size; +} + +static void fill_cacheinfo(struct cacheinfo **this_leaf, + struct device_node *node, unsigned int level) +{ + unsigned int size, sets, line_size; + + if (!of_property_read_u32(node, "cache-size", &size) && + !of_property_read_u32(node, "cache-block-size", &line_size) && + !of_property_read_u32(node, "cache-sets", &sets)) { + ci_leaf_init((*this_leaf)++, CACHE_TYPE_UNIFIED, level, size, sets, line_size); + } + + if (!of_property_read_u32(node, "i-cache-size", &size) && + !of_property_read_u32(node, "i-cache-sets", &sets) && + !of_property_read_u32(node, "i-cache-block-size", &line_size)) { + ci_leaf_init((*this_leaf)++, CACHE_TYPE_INST, level, size, sets, line_size); + } + + if (!of_property_read_u32(node, "d-cache-size", &size) && + !of_property_read_u32(node, "d-cache-sets", &sets) && + !of_property_read_u32(node, "d-cache-block-size", &line_size)) { + ci_leaf_init((*this_leaf)++, CACHE_TYPE_DATA, level, size, sets, line_size); + } } static int __init_cache_level(unsigned int cpu) @@ -83,29 +154,24 @@ static int __populate_cache_leaves(unsigned int cpu) struct device_node *prev = NULL; int levels = 1, level = 1; - if (of_property_read_bool(np, "cache-size")) - ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level); - if (of_property_read_bool(np, "i-cache-size")) - ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level); - if (of_property_read_bool(np, "d-cache-size")) - ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level); + /* Level 1 caches in cpu node */ + fill_cacheinfo(&this_leaf, np, level); + /* Next level caches in cache nodes */ prev = np; while ((np = of_find_next_cache_node(np))) { of_node_put(prev); prev = np; + if (!of_device_is_compatible(np, "cache")) break; if (of_property_read_u32(np, "cache-level", &level)) break; if (level <= levels) break; - if (of_property_read_bool(np, "cache-size")) - ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level); - if (of_property_read_bool(np, "i-cache-size")) - ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level); - if (of_property_read_bool(np, "d-cache-size")) - ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level); + + fill_cacheinfo(&this_leaf, np, level); + levels = level; } of_node_put(np); diff --git a/arch/riscv/kernel/cpu_ops.c b/arch/riscv/kernel/cpu_ops.c index 0ec22354018c..1985884fe829 100644 --- a/arch/riscv/kernel/cpu_ops.c +++ b/arch/riscv/kernel/cpu_ops.c @@ -15,8 +15,8 @@ const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init; -void *__cpu_up_stack_pointer[NR_CPUS] __section(.data); -void *__cpu_up_task_pointer[NR_CPUS] __section(.data); +void *__cpu_up_stack_pointer[NR_CPUS] __section(".data"); +void *__cpu_up_task_pointer[NR_CPUS] __section(".data"); extern const struct cpu_operations cpu_ops_sbi; extern const struct cpu_operations cpu_ops_spinwait; diff --git a/arch/riscv/kernel/efi-header.S b/arch/riscv/kernel/efi-header.S new file mode 100644 index 000000000000..8e733aa48ba6 --- /dev/null +++ b/arch/riscv/kernel/efi-header.S @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + * Adapted from arch/arm64/kernel/efi-header.S + */ + +#include <linux/pe.h> +#include <linux/sizes.h> + + .macro __EFI_PE_HEADER + .long PE_MAGIC +coff_header: +#ifdef CONFIG_64BIT + .short IMAGE_FILE_MACHINE_RISCV64 // Machine +#else + .short IMAGE_FILE_MACHINE_RISCV32 // Machine +#endif + .short section_count // NumberOfSections + .long 0 // TimeDateStamp + .long 0 // PointerToSymbolTable + .long 0 // NumberOfSymbols + .short section_table - optional_header // SizeOfOptionalHeader + .short IMAGE_FILE_DEBUG_STRIPPED | \ + IMAGE_FILE_EXECUTABLE_IMAGE | \ + IMAGE_FILE_LINE_NUMS_STRIPPED // Characteristics + +optional_header: +#ifdef CONFIG_64BIT + .short PE_OPT_MAGIC_PE32PLUS // PE32+ format +#else + .short PE_OPT_MAGIC_PE32 // PE32 format +#endif + .byte 0x02 // MajorLinkerVersion + .byte 0x14 // MinorLinkerVersion + .long __pecoff_text_end - efi_header_end // SizeOfCode + .long __pecoff_data_virt_size // SizeOfInitializedData + .long 0 // SizeOfUninitializedData + .long __efistub_efi_pe_entry - _start // AddressOfEntryPoint + .long efi_header_end - _start // BaseOfCode +#ifdef CONFIG_32BIT + .long __pecoff_text_end - _start // BaseOfData +#endif + +extra_header_fields: + .quad 0 // ImageBase + .long PECOFF_SECTION_ALIGNMENT // SectionAlignment + .long PECOFF_FILE_ALIGNMENT // FileAlignment + .short 0 // MajorOperatingSystemVersion + .short 0 // MinorOperatingSystemVersion + .short LINUX_EFISTUB_MAJOR_VERSION // MajorImageVersion + .short LINUX_EFISTUB_MINOR_VERSION // MinorImageVersion + .short 0 // MajorSubsystemVersion + .short 0 // MinorSubsystemVersion + .long 0 // Win32VersionValue + + .long _end - _start // SizeOfImage + + // Everything before the kernel image is considered part of the header + .long efi_header_end - _start // SizeOfHeaders + .long 0 // CheckSum + .short IMAGE_SUBSYSTEM_EFI_APPLICATION // Subsystem + .short 0 // DllCharacteristics + .quad 0 // SizeOfStackReserve + .quad 0 // SizeOfStackCommit + .quad 0 // SizeOfHeapReserve + .quad 0 // SizeOfHeapCommit + .long 0 // LoaderFlags + .long (section_table - .) / 8 // NumberOfRvaAndSizes + + .quad 0 // ExportTable + .quad 0 // ImportTable + .quad 0 // ResourceTable + .quad 0 // ExceptionTable + .quad 0 // CertificationTable + .quad 0 // BaseRelocationTable + + // Section table +section_table: + .ascii ".text\0\0\0" + .long __pecoff_text_end - efi_header_end // VirtualSize + .long efi_header_end - _start // VirtualAddress + .long __pecoff_text_end - efi_header_end // SizeOfRawData + .long efi_header_end - _start // PointerToRawData + + .long 0 // PointerToRelocations + .long 0 // PointerToLineNumbers + .short 0 // NumberOfRelocations + .short 0 // NumberOfLineNumbers + .long IMAGE_SCN_CNT_CODE | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_EXECUTE // Characteristics + + .ascii ".data\0\0\0" + .long __pecoff_data_virt_size // VirtualSize + .long __pecoff_text_end - _start // VirtualAddress + .long __pecoff_data_raw_size // SizeOfRawData + .long __pecoff_text_end - _start // PointerToRawData + + .long 0 // PointerToRelocations + .long 0 // PointerToLineNumbers + .short 0 // NumberOfRelocations + .short 0 // NumberOfLineNumbers + .long IMAGE_SCN_CNT_INITIALIZED_DATA | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_WRITE // Characteristics + + .set section_count, (. - section_table) / 40 + + .balign 0x1000 +efi_header_end: + .endm diff --git a/arch/riscv/kernel/efi.c b/arch/riscv/kernel/efi.c new file mode 100644 index 000000000000..024159298231 --- /dev/null +++ b/arch/riscv/kernel/efi.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + * Adapted from arch/arm64/kernel/efi.c + */ + +#include <linux/efi.h> +#include <linux/init.h> + +#include <asm/efi.h> +#include <asm/pgtable.h> +#include <asm/pgtable-bits.h> + +/* + * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be + * executable, everything else can be mapped with the XN bits + * set. Also take the new (optional) RO/XP bits into account. + */ +static __init pgprot_t efimem_to_pgprot_map(efi_memory_desc_t *md) +{ + u64 attr = md->attribute; + u32 type = md->type; + + if (type == EFI_MEMORY_MAPPED_IO) + return PAGE_KERNEL; + + /* R-- */ + if ((attr & (EFI_MEMORY_XP | EFI_MEMORY_RO)) == + (EFI_MEMORY_XP | EFI_MEMORY_RO)) + return PAGE_KERNEL_READ; + + /* R-X */ + if (attr & EFI_MEMORY_RO) + return PAGE_KERNEL_READ_EXEC; + + /* RW- */ + if (((attr & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP)) == + EFI_MEMORY_XP) || + type != EFI_RUNTIME_SERVICES_CODE) + return PAGE_KERNEL; + + /* RWX */ + return PAGE_KERNEL_EXEC; +} + +int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) +{ + pgprot_t prot = __pgprot(pgprot_val(efimem_to_pgprot_map(md)) & + ~(_PAGE_GLOBAL)); + int i; + + /* RISC-V maps one page at a time */ + for (i = 0; i < md->num_pages; i++) + create_pgd_mapping(mm->pgd, md->virt_addr + i * PAGE_SIZE, + md->phys_addr + i * PAGE_SIZE, + PAGE_SIZE, prot); + return 0; +} + +static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data) +{ + efi_memory_desc_t *md = data; + pte_t pte = READ_ONCE(*ptep); + unsigned long val; + + if (md->attribute & EFI_MEMORY_RO) { + val = pte_val(pte) & ~_PAGE_WRITE; + val = pte_val(pte) | _PAGE_READ; + pte = __pte(val); + } + if (md->attribute & EFI_MEMORY_XP) { + val = pte_val(pte) & ~_PAGE_EXEC; + pte = __pte(val); + } + set_pte(ptep, pte); + + return 0; +} + +int __init efi_set_mapping_permissions(struct mm_struct *mm, + efi_memory_desc_t *md) +{ + BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE && + md->type != EFI_RUNTIME_SERVICES_DATA); + + /* + * Calling apply_to_page_range() is only safe on regions that are + * guaranteed to be mapped down to pages. Since we are only called + * for regions that have been mapped using efi_create_mapping() above + * (and this is checked by the generic Memory Attributes table parsing + * routines), there is no need to check that again here. + */ + return apply_to_page_range(mm, md->virt_addr, + md->num_pages << EFI_PAGE_SHIFT, + set_permissions, md); +} diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c index 2ff63d0cbb50..99e12faa5498 100644 --- a/arch/riscv/kernel/ftrace.c +++ b/arch/riscv/kernel/ftrace.c @@ -97,6 +97,25 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, return __ftrace_modify_call(rec->ip, addr, false); } + +/* + * This is called early on, and isn't wrapped by + * ftrace_arch_code_modify_{prepare,post_process}() and therefor doesn't hold + * text_mutex, which triggers a lockdep failure. SMP isn't running so we could + * just directly poke the text, but it's simpler to just take the lock + * ourselves. + */ +int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec) +{ + int out; + + ftrace_arch_code_modify_prepare(); + out = ftrace_make_nop(mod, rec, MCOUNT_ADDR); + ftrace_arch_code_modify_post_process(); + + return out; +} + int ftrace_update_ftrace_func(ftrace_func_t func) { int ret = __ftrace_modify_call((unsigned long)&ftrace_call, diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S index 0a4e81b8dc79..11e2a4fe66e0 100644 --- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S @@ -3,7 +3,6 @@ * Copyright (C) 2012 Regents of the University of California */ -#include <asm/thread_info.h> #include <asm/asm-offsets.h> #include <asm/asm.h> #include <linux/init.h> @@ -13,6 +12,7 @@ #include <asm/csr.h> #include <asm/hwcap.h> #include <asm/image.h> +#include "efi-header.S" __HEAD ENTRY(_start) @@ -22,10 +22,18 @@ ENTRY(_start) * Do not modify it without modifying the structure and all bootloaders * that expects this header format!! */ +#ifdef CONFIG_EFI + /* + * This instruction decodes to "MZ" ASCII required by UEFI. + */ + c.li s4,-13 + j _start_kernel +#else /* jump to start kernel */ j _start_kernel /* reserved */ .word 0 +#endif .balign 8 #if __riscv_xlen == 64 /* Image load offset(2MB) from start of RAM */ @@ -43,7 +51,14 @@ ENTRY(_start) .ascii RISCV_IMAGE_MAGIC .balign 4 .ascii RISCV_IMAGE_MAGIC2 +#ifdef CONFIG_EFI + .word pe_head_start - _start +pe_head_start: + + __EFI_PE_HEADER +#else .word 0 +#endif .align 2 #ifdef CONFIG_MMU @@ -259,7 +274,6 @@ clear_bss_done: #endif /* Start the kernel */ call soc_early_init - call parse_dtb tail start_kernel .Lsecondary_start: diff --git a/arch/riscv/kernel/head.h b/arch/riscv/kernel/head.h index 105fb0496b24..b48dda3d04f6 100644 --- a/arch/riscv/kernel/head.h +++ b/arch/riscv/kernel/head.h @@ -16,6 +16,4 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa); extern void *__cpu_up_stack_pointer[]; extern void *__cpu_up_task_pointer[]; -void __init parse_dtb(void); - #endif /* __ASM_HEAD_H */ diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h new file mode 100644 index 000000000000..8c212efb37a6 --- /dev/null +++ b/arch/riscv/kernel/image-vars.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020 Western Digital Corporation or its affiliates. + * Linker script variables to be set after section resolution, as + * ld.lld does not like variables assigned before SECTIONS is processed. + * Based on arch/arm64/kerne/image-vars.h + */ +#ifndef __RISCV_KERNEL_IMAGE_VARS_H +#define __RISCV_KERNEL_IMAGE_VARS_H + +#ifndef LINKER_SCRIPT +#error This file should only be included in vmlinux.lds.S +#endif + +#ifdef CONFIG_EFI + +/* + * The EFI stub has its own symbol namespace prefixed by __efistub_, to + * isolate it from the kernel proper. The following symbols are legally + * accessed by the stub, so provide some aliases to make them accessible. + * Only include data symbols here, or text symbols of functions that are + * guaranteed to be safe when executed at another offset than they were + * linked at. The routines below are all implemented in assembler in a + * position independent manner + */ +__efistub_memcmp = memcmp; +__efistub_memchr = memchr; +__efistub_memcpy = memcpy; +__efistub_memmove = memmove; +__efistub_memset = memset; +__efistub_strlen = strlen; +__efistub_strnlen = strnlen; +__efistub_strcmp = strcmp; +__efistub_strncmp = strncmp; +__efistub_strrchr = strrchr; + +#ifdef CONFIG_KASAN +__efistub___memcpy = memcpy; +__efistub___memmove = memmove; +__efistub___memset = memset; +#endif + +__efistub__start = _start; +__efistub__start_kernel = _start_kernel; +__efistub__end = _end; +__efistub__edata = _edata; +__efistub_screen_info = screen_info; + +#endif + +#endif /* __RISCV_KERNEL_IMAGE_VARS_H */ diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c index 2b97c493427c..19225ec65db6 100644 --- a/arch/riscv/kernel/process.c +++ b/arch/riscv/kernel/process.c @@ -84,7 +84,6 @@ void start_thread(struct pt_regs *regs, unsigned long pc, } regs->epc = pc; regs->sp = sp; - set_fs(USER_DS); } void flush_thread(void) diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 2c6dd329312b..c424cc6dd833 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -17,19 +17,22 @@ #include <linux/sched/task.h> #include <linux/swiotlb.h> #include <linux/smp.h> +#include <linux/efi.h> #include <asm/cpu_ops.h> +#include <asm/early_ioremap.h> #include <asm/setup.h> #include <asm/sections.h> #include <asm/sbi.h> #include <asm/tlbflush.h> #include <asm/thread_info.h> #include <asm/kasan.h> +#include <asm/efi.h> #include "head.h" -#ifdef CONFIG_DUMMY_CONSOLE -struct screen_info screen_info = { +#if defined(CONFIG_DUMMY_CONSOLE) || defined(CONFIG_EFI) +struct screen_info screen_info __section(".data") = { .orig_video_lines = 30, .orig_video_cols = 80, .orig_video_mode = 0, @@ -44,12 +47,13 @@ struct screen_info screen_info = { * This is used before the kernel initializes the BSS so it can't be in the * BSS. */ -atomic_t hart_lottery __section(.sdata); +atomic_t hart_lottery __section(".sdata"); unsigned long boot_cpu_hartid; static DEFINE_PER_CPU(struct cpu, cpu_devices); -void __init parse_dtb(void) +static void __init parse_dtb(void) { + /* Early scan of device tree from init memory */ if (early_init_dt_scan(dtb_early_va)) return; @@ -62,6 +66,7 @@ void __init parse_dtb(void) void __init setup_arch(char **cmdline_p) { + parse_dtb(); init_mm.start_code = (unsigned long) _stext; init_mm.end_code = (unsigned long) _etext; init_mm.end_data = (unsigned long) _edata; @@ -69,14 +74,19 @@ void __init setup_arch(char **cmdline_p) *cmdline_p = boot_command_line; + early_ioremap_setup(); parse_early_param(); + efi_init(); setup_bootmem(); paging_init(); #if IS_ENABLED(CONFIG_BUILTIN_DTB) unflatten_and_copy_device_tree(); #else - unflatten_device_tree(); + if (early_init_dt_verify(__va(dtb_early_pa))) + unflatten_device_tree(); + else + pr_err("No DTB found in kernel mappings\n"); #endif #ifdef CONFIG_SWIOTLB diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c index e996e08f1061..bc6841867b51 100644 --- a/arch/riscv/kernel/signal.c +++ b/arch/riscv/kernel/signal.c @@ -313,8 +313,6 @@ asmlinkage __visible void do_notify_resume(struct pt_regs *regs, if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs); - if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); + if (thread_info_flags & _TIF_NOTIFY_RESUME) tracehook_notify_resume(regs); - } } diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile index 478e7338ddc1..7d6a94d45ec9 100644 --- a/arch/riscv/kernel/vdso/Makefile +++ b/arch/riscv/kernel/vdso/Makefile @@ -49,7 +49,7 @@ $(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso) FORCE # refer to these symbols in the kernel code rather than hand-coded addresses. SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \ - -Wl,--build-id -Wl,--hash-style=both + -Wl,--build-id=sha1 -Wl,--hash-style=both $(obj)/vdso-dummy.o: $(src)/vdso.lds $(obj)/rt_sigreturn.o FORCE $(call if_changed,vdsold) diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S index f3586e31ed1e..3ffbd6cbdb86 100644 --- a/arch/riscv/kernel/vmlinux.lds.S +++ b/arch/riscv/kernel/vmlinux.lds.S @@ -10,6 +10,7 @@ #include <asm/cache.h> #include <asm/thread_info.h> #include <asm/set_memory.h> +#include "image-vars.h" #include <linux/sizes.h> OUTPUT_ARCH(riscv) @@ -17,18 +18,19 @@ ENTRY(_start) jiffies = jiffies_64; +PECOFF_SECTION_ALIGNMENT = 0x1000; +PECOFF_FILE_ALIGNMENT = 0x200; + SECTIONS { /* Beginning of code and text segment */ . = LOAD_OFFSET; _start = .; - _stext = .; HEAD_TEXT_SECTION . = ALIGN(PAGE_SIZE); __init_begin = .; INIT_TEXT_SECTION(PAGE_SIZE) - INIT_DATA_SECTION(16) . = ALIGN(8); __soc_early_init_table : { __soc_early_init_table_start = .; @@ -55,6 +57,7 @@ SECTIONS . = ALIGN(SECTION_ALIGN); .text : { _text = .; + _stext = .; TEXT_TEXT SCHED_TEXT CPUIDLE_TEXT @@ -67,6 +70,13 @@ SECTIONS _etext = .; } +#ifdef CONFIG_EFI + . = ALIGN(PECOFF_SECTION_ALIGNMENT); + __pecoff_text_end = .; +#endif + + INIT_DATA_SECTION(16) + /* Start of data section */ _sdata = .; RO_DATA(SECTION_ALIGN) @@ -83,20 +93,31 @@ SECTIONS .sdata : { __global_pointer$ = . + 0x800; *(.sdata*) - /* End of data section */ - _edata = .; } +#ifdef CONFIG_EFI + .pecoff_edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGNMENT); } + __pecoff_data_raw_size = ABSOLUTE(. - __pecoff_text_end); +#endif + + /* End of data section */ + _edata = .; + 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); +#endif _end = .; STABS_DEBUG DWARF_DEBUG + ELF_DETAILS DISCARDS } diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index 0d0db80800c4..47e7a8204460 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -2,5 +2,5 @@ lib-y += delay.o lib-y += memcpy.o lib-y += memset.o -lib-y += uaccess.o +lib-$(CONFIG_MMU) += uaccess.o lib-$(CONFIG_64BIT) += tishift.o diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c index 716d64e36f83..1359e21c0c62 100644 --- a/arch/riscv/mm/fault.c +++ b/arch/riscv/mm/fault.c @@ -19,6 +19,167 @@ #include "../kernel/head.h" +static inline void no_context(struct pt_regs *regs, unsigned long addr) +{ + /* Are we prepared to handle this kernel fault? */ + if (fixup_exception(regs)) + return; + + /* + * Oops. The kernel tried to access some bad page. We'll have to + * terminate things with extreme prejudice. + */ + bust_spinlocks(1); + pr_alert("Unable to handle kernel %s at virtual address " REG_FMT "\n", + (addr < PAGE_SIZE) ? "NULL pointer dereference" : + "paging request", addr); + die(regs, "Oops"); + do_exit(SIGKILL); +} + +static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_fault_t fault) +{ + if (fault & VM_FAULT_OOM) { + /* + * We ran out of memory, call the OOM killer, and return the userspace + * (which will retry the fault, or kill us if we got oom-killed). + */ + if (!user_mode(regs)) { + no_context(regs, addr); + return; + } + pagefault_out_of_memory(); + return; + } else if (fault & VM_FAULT_SIGBUS) { + /* Kernel mode? Handle exceptions or die */ + if (!user_mode(regs)) { + no_context(regs, addr); + return; + } + do_trap(regs, SIGBUS, BUS_ADRERR, addr); + return; + } + BUG(); +} + +static inline void bad_area(struct pt_regs *regs, struct mm_struct *mm, int code, unsigned long addr) +{ + /* + * Something tried to access memory that isn't in our memory map. + * Fix it, but check if it's kernel or user first. + */ + mmap_read_unlock(mm); + /* User mode accesses just cause a SIGSEGV */ + if (user_mode(regs)) { + do_trap(regs, SIGSEGV, code, addr); + return; + } + + no_context(regs, addr); +} + +static inline void vmalloc_fault(struct pt_regs *regs, int code, unsigned long addr) +{ + pgd_t *pgd, *pgd_k; + pud_t *pud, *pud_k; + p4d_t *p4d, *p4d_k; + pmd_t *pmd, *pmd_k; + pte_t *pte_k; + int index; + + /* User mode accesses just cause a SIGSEGV */ + if (user_mode(regs)) + return do_trap(regs, SIGSEGV, code, addr); + + /* + * Synchronize this task's top level page-table + * with the 'reference' page table. + * + * Do _not_ use "tsk->active_mm->pgd" here. + * We might be inside an interrupt in the middle + * of a task switch. + */ + index = pgd_index(addr); + pgd = (pgd_t *)pfn_to_virt(csr_read(CSR_SATP)) + index; + pgd_k = init_mm.pgd + index; + + if (!pgd_present(*pgd_k)) { + no_context(regs, addr); + return; + } + set_pgd(pgd, *pgd_k); + + p4d = p4d_offset(pgd, addr); + p4d_k = p4d_offset(pgd_k, addr); + if (!p4d_present(*p4d_k)) { + no_context(regs, addr); + return; + } + + pud = pud_offset(p4d, addr); + pud_k = pud_offset(p4d_k, addr); + if (!pud_present(*pud_k)) { + no_context(regs, addr); + return; + } + + /* + * Since the vmalloc area is global, it is unnecessary + * to copy individual PTEs + */ + pmd = pmd_offset(pud, addr); + pmd_k = pmd_offset(pud_k, addr); + if (!pmd_present(*pmd_k)) { + no_context(regs, addr); + return; + } + set_pmd(pmd, *pmd_k); + + /* + * Make sure the actual PTE exists as well to + * catch kernel vmalloc-area accesses to non-mapped + * addresses. If we don't do this, this will just + * silently loop forever. + */ + pte_k = pte_offset_kernel(pmd_k, addr); + if (!pte_present(*pte_k)) { + no_context(regs, addr); + return; + } + + /* + * The kernel assumes that TLBs don't cache invalid + * entries, but in RISC-V, SFENCE.VMA specifies an + * ordering constraint, not a cache flush; it is + * necessary even after writing invalid entries. + */ + local_flush_tlb_page(addr); +} + +static inline bool access_error(unsigned long cause, struct vm_area_struct *vma) +{ + switch (cause) { + case EXC_INST_PAGE_FAULT: + if (!(vma->vm_flags & VM_EXEC)) { + return true; + } + break; + case EXC_LOAD_PAGE_FAULT: + if (!(vma->vm_flags & VM_READ)) { + return true; + } + break; + case EXC_STORE_PAGE_FAULT: + if (!(vma->vm_flags & VM_WRITE)) { + return true; + } + break; + default: + panic("%s: unhandled cause %lu", __func__, cause); + } + return false; +} + /* * This routine handles page faults. It determines the address and the * problem, and then passes it off to one of the appropriate routines. @@ -48,8 +209,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs) * only copy the information from the master page table, * nothing more. */ - if (unlikely((addr >= VMALLOC_START) && (addr <= VMALLOC_END))) - goto vmalloc_fault; + if (unlikely((addr >= VMALLOC_START) && (addr <= VMALLOC_END))) { + vmalloc_fault(regs, code, addr); + return; + } /* Enable interrupts if they were enabled in the parent context. */ if (likely(regs->status & SR_PIE)) @@ -59,25 +222,37 @@ asmlinkage void do_page_fault(struct pt_regs *regs) * If we're in an interrupt, have no user context, or are running * in an atomic region, then we must not take the fault. */ - if (unlikely(faulthandler_disabled() || !mm)) - goto no_context; + if (unlikely(faulthandler_disabled() || !mm)) { + no_context(regs, addr); + return; + } if (user_mode(regs)) flags |= FAULT_FLAG_USER; perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr); + if (cause == EXC_STORE_PAGE_FAULT) + flags |= FAULT_FLAG_WRITE; + else if (cause == EXC_INST_PAGE_FAULT) + flags |= FAULT_FLAG_INSTRUCTION; retry: mmap_read_lock(mm); vma = find_vma(mm, addr); - if (unlikely(!vma)) - goto bad_area; + if (unlikely(!vma)) { + bad_area(regs, mm, code, addr); + return; + } if (likely(vma->vm_start <= addr)) goto good_area; - if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) - goto bad_area; - if (unlikely(expand_stack(vma, addr))) - goto bad_area; + if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) { + bad_area(regs, mm, code, addr); + return; + } + if (unlikely(expand_stack(vma, addr))) { + bad_area(regs, mm, code, addr); + return; + } /* * Ok, we have a good vm_area for this memory access, so @@ -86,22 +261,9 @@ retry: good_area: code = SEGV_ACCERR; - switch (cause) { - case EXC_INST_PAGE_FAULT: - if (!(vma->vm_flags & VM_EXEC)) - goto bad_area; - break; - case EXC_LOAD_PAGE_FAULT: - if (!(vma->vm_flags & VM_READ)) - goto bad_area; - break; - case EXC_STORE_PAGE_FAULT: - if (!(vma->vm_flags & VM_WRITE)) - goto bad_area; - flags |= FAULT_FLAG_WRITE; - break; - default: - panic("%s: unhandled cause %lu", __func__, cause); + if (unlikely(access_error(cause, vma))) { + bad_area(regs, mm, code, addr); + return; } /* @@ -119,144 +281,22 @@ good_area: if (fault_signal_pending(fault, regs)) return; - if (unlikely(fault & VM_FAULT_ERROR)) { - if (fault & VM_FAULT_OOM) - goto out_of_memory; - else if (fault & VM_FAULT_SIGBUS) - goto do_sigbus; - BUG(); - } - - if (flags & FAULT_FLAG_ALLOW_RETRY) { - if (fault & VM_FAULT_RETRY) { - flags |= FAULT_FLAG_TRIED; + if (unlikely((fault & VM_FAULT_RETRY) && (flags & FAULT_FLAG_ALLOW_RETRY))) { + flags |= FAULT_FLAG_TRIED; - /* - * No need to mmap_read_unlock(mm) as we would - * have already released it in __lock_page_or_retry - * in mm/filemap.c. - */ - goto retry; - } + /* + * No need to mmap_read_unlock(mm) as we would + * have already released it in __lock_page_or_retry + * in mm/filemap.c. + */ + goto retry; } mmap_read_unlock(mm); - return; - /* - * Something tried to access memory that isn't in our memory map. - * Fix it, but check if it's kernel or user first. - */ -bad_area: - mmap_read_unlock(mm); - /* User mode accesses just cause a SIGSEGV */ - if (user_mode(regs)) { - do_trap(regs, SIGSEGV, code, addr); + if (unlikely(fault & VM_FAULT_ERROR)) { + mm_fault_error(regs, addr, fault); return; } - -no_context: - /* Are we prepared to handle this kernel fault? */ - if (fixup_exception(regs)) - return; - - /* - * Oops. The kernel tried to access some bad page. We'll have to - * terminate things with extreme prejudice. - */ - bust_spinlocks(1); - pr_alert("Unable to handle kernel %s at virtual address " REG_FMT "\n", - (addr < PAGE_SIZE) ? "NULL pointer dereference" : - "paging request", addr); - die(regs, "Oops"); - do_exit(SIGKILL); - - /* - * We ran out of memory, call the OOM killer, and return the userspace - * (which will retry the fault, or kill us if we got oom-killed). - */ -out_of_memory: - mmap_read_unlock(mm); - if (!user_mode(regs)) - goto no_context; - pagefault_out_of_memory(); - return; - -do_sigbus: - mmap_read_unlock(mm); - /* Kernel mode? Handle exceptions or die */ - if (!user_mode(regs)) - goto no_context; - do_trap(regs, SIGBUS, BUS_ADRERR, addr); return; - -vmalloc_fault: - { - pgd_t *pgd, *pgd_k; - pud_t *pud, *pud_k; - p4d_t *p4d, *p4d_k; - pmd_t *pmd, *pmd_k; - pte_t *pte_k; - int index; - - /* User mode accesses just cause a SIGSEGV */ - if (user_mode(regs)) - return do_trap(regs, SIGSEGV, code, addr); - - /* - * Synchronize this task's top level page-table - * with the 'reference' page table. - * - * Do _not_ use "tsk->active_mm->pgd" here. - * We might be inside an interrupt in the middle - * of a task switch. - */ - index = pgd_index(addr); - pgd = (pgd_t *)pfn_to_virt(csr_read(CSR_SATP)) + index; - pgd_k = init_mm.pgd + index; - - if (!pgd_present(*pgd_k)) - goto no_context; - set_pgd(pgd, *pgd_k); - - p4d = p4d_offset(pgd, addr); - p4d_k = p4d_offset(pgd_k, addr); - if (!p4d_present(*p4d_k)) - goto no_context; - - pud = pud_offset(p4d, addr); - pud_k = pud_offset(p4d_k, addr); - if (!pud_present(*pud_k)) - goto no_context; - - /* - * Since the vmalloc area is global, it is unnecessary - * to copy individual PTEs - */ - pmd = pmd_offset(pud, addr); - pmd_k = pmd_offset(pud_k, addr); - if (!pmd_present(*pmd_k)) - goto no_context; - set_pmd(pmd, *pmd_k); - - /* - * Make sure the actual PTE exists as well to - * catch kernel vmalloc-area accesses to non-mapped - * addresses. If we don't do this, this will just - * silently loop forever. - */ - pte_k = pte_offset_kernel(pmd_k, addr); - if (!pte_present(*pte_k)) - goto no_context; - - /* - * The kernel assumes that TLBs don't cache invalid - * entries, but in RISC-V, SFENCE.VMA specifies an - * ordering constraint, not a cache flush; it is - * necessary even after writing invalid entries. - */ - local_flush_tlb_page(addr); - - return; - } } diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 787c75f751a5..ea933b789a88 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -28,7 +28,18 @@ unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] EXPORT_SYMBOL(empty_zero_page); extern char _start[]; -void *dtb_early_va; +#define DTB_EARLY_BASE_VA PGDIR_SIZE +void *dtb_early_va __initdata; +uintptr_t dtb_early_pa __initdata; + +struct pt_alloc_ops { + pte_t *(*get_pte_virt)(phys_addr_t pa); + phys_addr_t (*alloc_pte)(uintptr_t va); +#ifndef __PAGETABLE_PMD_FOLDED + pmd_t *(*get_pmd_virt)(phys_addr_t pa); + phys_addr_t (*alloc_pmd)(uintptr_t va); +#endif +}; static void __init zone_sizes_init(void) { @@ -141,25 +152,23 @@ disable: } #endif /* CONFIG_BLK_DEV_INITRD */ -static phys_addr_t dtb_early_pa __initdata; - void __init setup_bootmem(void) { - struct memblock_region *reg; phys_addr_t mem_size = 0; phys_addr_t total_mem = 0; - phys_addr_t mem_start, end = 0; + phys_addr_t mem_start, start, end = 0; phys_addr_t vmlinux_end = __pa_symbol(&_end); phys_addr_t vmlinux_start = __pa_symbol(&_start); + u64 i; /* Find the memory region containing the kernel */ - for_each_memblock(memory, reg) { - end = reg->base + reg->size; + for_each_mem_range(i, &start, &end) { + phys_addr_t size = end - start; if (!total_mem) - mem_start = reg->base; - if (reg->base <= vmlinux_start && vmlinux_end <= end) - BUG_ON(reg->size == 0); - total_mem = total_mem + reg->size; + mem_start = start; + if (start <= vmlinux_start && vmlinux_end <= end) + BUG_ON(size == 0); + total_mem = total_mem + size; } /* @@ -191,18 +200,11 @@ void __init setup_bootmem(void) early_init_fdt_scan_reserved_mem(); memblock_allow_resize(); memblock_dump_all(); - - for_each_memblock(memory, reg) { - unsigned long start_pfn = memblock_region_memory_base_pfn(reg); - unsigned long end_pfn = memblock_region_memory_end_pfn(reg); - - memblock_set_node(PFN_PHYS(start_pfn), - PFN_PHYS(end_pfn - start_pfn), - &memblock.memory, 0); - } } #ifdef CONFIG_MMU +static struct pt_alloc_ops pt_ops; + unsigned long va_pa_offset; EXPORT_SYMBOL(va_pa_offset); unsigned long pfn_base; @@ -211,7 +213,6 @@ EXPORT_SYMBOL(pfn_base); pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss; pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss; pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss; -static bool mmu_enabled; #define MAX_EARLY_MAPPING_SIZE SZ_128M @@ -226,35 +227,53 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot) ptep = &fixmap_pte[pte_index(addr)]; - if (pgprot_val(prot)) { + if (pgprot_val(prot)) set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); - } else { + else pte_clear(&init_mm, addr, ptep); - local_flush_tlb_page(addr); - } + local_flush_tlb_page(addr); } -static pte_t *__init get_pte_virt(phys_addr_t pa) +static inline pte_t *__init get_pte_virt_early(phys_addr_t pa) { - if (mmu_enabled) { - clear_fixmap(FIX_PTE); - return (pte_t *)set_fixmap_offset(FIX_PTE, pa); - } else { - return (pte_t *)((uintptr_t)pa); - } + return (pte_t *)((uintptr_t)pa); +} + +static inline pte_t *__init get_pte_virt_fixmap(phys_addr_t pa) +{ + clear_fixmap(FIX_PTE); + return (pte_t *)set_fixmap_offset(FIX_PTE, pa); } -static phys_addr_t __init alloc_pte(uintptr_t va) +static inline pte_t *get_pte_virt_late(phys_addr_t pa) +{ + return (pte_t *) __va(pa); +} + +static inline phys_addr_t __init alloc_pte_early(uintptr_t va) { /* * We only create PMD or PGD early mappings so we * should never reach here with MMU disabled. */ - BUG_ON(!mmu_enabled); + BUG(); +} +static inline phys_addr_t __init alloc_pte_fixmap(uintptr_t va) +{ return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE); } +static phys_addr_t alloc_pte_late(uintptr_t va) +{ + unsigned long vaddr; + + vaddr = __get_free_page(GFP_KERNEL); + if (!vaddr || !pgtable_pte_page_ctor(virt_to_page(vaddr))) + BUG(); + return __pa(vaddr); +} + static void __init create_pte_mapping(pte_t *ptep, uintptr_t va, phys_addr_t pa, phys_addr_t sz, pgprot_t prot) @@ -279,28 +298,46 @@ pmd_t fixmap_pmd[PTRS_PER_PMD] __page_aligned_bss; #endif pmd_t early_pmd[PTRS_PER_PMD * NUM_EARLY_PMDS] __initdata __aligned(PAGE_SIZE); -static pmd_t *__init get_pmd_virt(phys_addr_t pa) +static pmd_t *__init get_pmd_virt_early(phys_addr_t pa) { - if (mmu_enabled) { - clear_fixmap(FIX_PMD); - return (pmd_t *)set_fixmap_offset(FIX_PMD, pa); - } else { - return (pmd_t *)((uintptr_t)pa); - } + /* Before MMU is enabled */ + return (pmd_t *)((uintptr_t)pa); } -static phys_addr_t __init alloc_pmd(uintptr_t va) +static pmd_t *__init get_pmd_virt_fixmap(phys_addr_t pa) { - uintptr_t pmd_num; + clear_fixmap(FIX_PMD); + return (pmd_t *)set_fixmap_offset(FIX_PMD, pa); +} + +static pmd_t *get_pmd_virt_late(phys_addr_t pa) +{ + return (pmd_t *) __va(pa); +} - if (mmu_enabled) - return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE); +static phys_addr_t __init alloc_pmd_early(uintptr_t va) +{ + uintptr_t pmd_num; pmd_num = (va - PAGE_OFFSET) >> PGDIR_SHIFT; BUG_ON(pmd_num >= NUM_EARLY_PMDS); return (uintptr_t)&early_pmd[pmd_num * PTRS_PER_PMD]; } +static phys_addr_t __init alloc_pmd_fixmap(uintptr_t va) +{ + return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE); +} + +static phys_addr_t alloc_pmd_late(uintptr_t va) +{ + unsigned long vaddr; + + vaddr = __get_free_page(GFP_KERNEL); + BUG_ON(!vaddr); + return __pa(vaddr); +} + static void __init create_pmd_mapping(pmd_t *pmdp, uintptr_t va, phys_addr_t pa, phys_addr_t sz, pgprot_t prot) @@ -316,34 +353,34 @@ static void __init create_pmd_mapping(pmd_t *pmdp, } if (pmd_none(pmdp[pmd_idx])) { - pte_phys = alloc_pte(va); + pte_phys = pt_ops.alloc_pte(va); pmdp[pmd_idx] = pfn_pmd(PFN_DOWN(pte_phys), PAGE_TABLE); - ptep = get_pte_virt(pte_phys); + ptep = pt_ops.get_pte_virt(pte_phys); memset(ptep, 0, PAGE_SIZE); } else { pte_phys = PFN_PHYS(_pmd_pfn(pmdp[pmd_idx])); - ptep = get_pte_virt(pte_phys); + ptep = pt_ops.get_pte_virt(pte_phys); } create_pte_mapping(ptep, va, pa, sz, prot); } #define pgd_next_t pmd_t -#define alloc_pgd_next(__va) alloc_pmd(__va) -#define get_pgd_next_virt(__pa) get_pmd_virt(__pa) +#define alloc_pgd_next(__va) pt_ops.alloc_pmd(__va) +#define get_pgd_next_virt(__pa) pt_ops.get_pmd_virt(__pa) #define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot) \ create_pmd_mapping(__nextp, __va, __pa, __sz, __prot) #define fixmap_pgd_next fixmap_pmd #else #define pgd_next_t pte_t -#define alloc_pgd_next(__va) alloc_pte(__va) -#define get_pgd_next_virt(__pa) get_pte_virt(__pa) +#define alloc_pgd_next(__va) pt_ops.alloc_pte(__va) +#define get_pgd_next_virt(__pa) pt_ops.get_pte_virt(__pa) #define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot) \ create_pte_mapping(__nextp, __va, __pa, __sz, __prot) #define fixmap_pgd_next fixmap_pte #endif -static void __init create_pgd_mapping(pgd_t *pgdp, +void __init create_pgd_mapping(pgd_t *pgdp, uintptr_t va, phys_addr_t pa, phys_addr_t sz, pgprot_t prot) { @@ -399,10 +436,13 @@ static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size) asmlinkage void __init setup_vm(uintptr_t dtb_pa) { - uintptr_t va, end_va; + uintptr_t va, pa, end_va; uintptr_t load_pa = (uintptr_t)(&_start); uintptr_t load_sz = (uintptr_t)(&_end) - load_pa; uintptr_t map_size = best_map_size(load_pa, MAX_EARLY_MAPPING_SIZE); +#ifndef __PAGETABLE_PMD_FOLDED + pmd_t fix_bmap_spmd, fix_bmap_epmd; +#endif va_pa_offset = PAGE_OFFSET - load_pa; pfn_base = PFN_DOWN(load_pa); @@ -418,6 +458,12 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) BUG_ON((load_pa % map_size) != 0); BUG_ON(load_sz > MAX_EARLY_MAPPING_SIZE); + pt_ops.alloc_pte = alloc_pte_early; + pt_ops.get_pte_virt = get_pte_virt_early; +#ifndef __PAGETABLE_PMD_FOLDED + pt_ops.alloc_pmd = alloc_pmd_early; + pt_ops.get_pmd_virt = get_pmd_virt_early; +#endif /* Setup early PGD for fixmap */ create_pgd_mapping(early_pg_dir, FIXADDR_START, (uintptr_t)fixmap_pgd_next, PGDIR_SIZE, PAGE_TABLE); @@ -448,42 +494,71 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) load_pa + (va - PAGE_OFFSET), map_size, PAGE_KERNEL_EXEC); - /* Create fixed mapping for early FDT parsing */ - end_va = __fix_to_virt(FIX_FDT) + FIX_FDT_SIZE; - for (va = __fix_to_virt(FIX_FDT); va < end_va; va += PAGE_SIZE) - create_pte_mapping(fixmap_pte, va, - dtb_pa + (va - __fix_to_virt(FIX_FDT)), - PAGE_SIZE, PAGE_KERNEL); - - /* Save pointer to DTB for early FDT parsing */ - dtb_early_va = (void *)fix_to_virt(FIX_FDT) + (dtb_pa & ~PAGE_MASK); - /* Save physical address for memblock reservation */ + /* Create two consecutive PGD mappings for FDT early scan */ + pa = dtb_pa & ~(PGDIR_SIZE - 1); + create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA, + pa, PGDIR_SIZE, PAGE_KERNEL); + create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA + PGDIR_SIZE, + pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL); + dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PGDIR_SIZE - 1)); dtb_early_pa = dtb_pa; + + /* + * Bootime fixmap only can handle PMD_SIZE mapping. Thus, boot-ioremap + * range can not span multiple pmds. + */ + BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT) + != (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT)); + +#ifndef __PAGETABLE_PMD_FOLDED + /* + * Early ioremap fixmap is already created as it lies within first 2MB + * of fixmap region. We always map PMD_SIZE. Thus, both FIX_BTMAP_END + * FIX_BTMAP_BEGIN should lie in the same pmd. Verify that and warn + * the user if not. + */ + fix_bmap_spmd = fixmap_pmd[pmd_index(__fix_to_virt(FIX_BTMAP_BEGIN))]; + fix_bmap_epmd = fixmap_pmd[pmd_index(__fix_to_virt(FIX_BTMAP_END))]; + if (pmd_val(fix_bmap_spmd) != pmd_val(fix_bmap_epmd)) { + WARN_ON(1); + pr_warn("fixmap btmap start [%08lx] != end [%08lx]\n", + pmd_val(fix_bmap_spmd), pmd_val(fix_bmap_epmd)); + pr_warn("fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n", + fix_to_virt(FIX_BTMAP_BEGIN)); + pr_warn("fix_to_virt(FIX_BTMAP_END): %08lx\n", + fix_to_virt(FIX_BTMAP_END)); + + pr_warn("FIX_BTMAP_END: %d\n", FIX_BTMAP_END); + pr_warn("FIX_BTMAP_BEGIN: %d\n", FIX_BTMAP_BEGIN); + } +#endif } static void __init setup_vm_final(void) { uintptr_t va, map_size; phys_addr_t pa, start, end; - struct memblock_region *reg; - - /* Set mmu_enabled flag */ - mmu_enabled = true; + u64 i; + /** + * MMU is enabled at this point. But page table setup is not complete yet. + * fixmap page table alloc functions should be used at this point + */ + pt_ops.alloc_pte = alloc_pte_fixmap; + pt_ops.get_pte_virt = get_pte_virt_fixmap; +#ifndef __PAGETABLE_PMD_FOLDED + pt_ops.alloc_pmd = alloc_pmd_fixmap; + pt_ops.get_pmd_virt = get_pmd_virt_fixmap; +#endif /* Setup swapper PGD for fixmap */ create_pgd_mapping(swapper_pg_dir, FIXADDR_START, __pa_symbol(fixmap_pgd_next), PGDIR_SIZE, PAGE_TABLE); /* Map all memory banks */ - for_each_memblock(memory, reg) { - start = reg->base; - end = start + reg->size; - + for_each_mem_range(i, &start, &end) { if (start >= end) break; - if (memblock_is_nomap(reg)) - continue; if (start <= __pa(PAGE_OFFSET) && __pa(PAGE_OFFSET) < end) start = __pa(PAGE_OFFSET); @@ -503,6 +578,14 @@ static void __init setup_vm_final(void) /* Move to swapper page table */ csr_write(CSR_SATP, PFN_DOWN(__pa_symbol(swapper_pg_dir)) | SATP_MODE); local_flush_tlb_all(); + + /* generic page allocation functions must be used to setup page table */ + pt_ops.alloc_pte = alloc_pte_late; + pt_ops.get_pte_virt = get_pte_virt_late; +#ifndef __PAGETABLE_PMD_FOLDED + pt_ops.alloc_pmd = alloc_pmd_late; + pt_ops.get_pmd_virt = get_pmd_virt_late; +#endif } #else asmlinkage void __init setup_vm(uintptr_t dtb_pa) @@ -516,6 +599,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) #else dtb_early_va = (void *)dtb_pa; #endif + dtb_early_pa = dtb_pa; } static inline void setup_vm_final(void) @@ -545,7 +629,7 @@ static void __init resource_init(void) { struct memblock_region *region; - for_each_memblock(memory, region) { + for_each_mem_region(region) { struct resource *res; res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES); diff --git a/arch/riscv/mm/kasan_init.c b/arch/riscv/mm/kasan_init.c index 87b4ab3d3c77..12ddd1f6bf70 100644 --- a/arch/riscv/mm/kasan_init.c +++ b/arch/riscv/mm/kasan_init.c @@ -85,16 +85,16 @@ static void __init populate(void *start, void *end) void __init kasan_init(void) { - struct memblock_region *reg; - unsigned long i; + phys_addr_t _start, _end; + u64 i; kasan_populate_early_shadow((void *)KASAN_SHADOW_START, (void *)kasan_mem_to_shadow((void *) VMALLOC_END)); - for_each_memblock(memory, reg) { - void *start = (void *)__va(reg->base); - void *end = (void *)__va(reg->base + reg->size); + for_each_mem_range(i, &_start, &_end) { + void *start = (void *)_start; + void *end = (void *)_end; if (start >= end) break; diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c index 0831c2e61a8f..ace74dec7492 100644 --- a/arch/riscv/mm/ptdump.c +++ b/arch/riscv/mm/ptdump.c @@ -3,6 +3,7 @@ * Copyright (C) 2019 SiFive */ +#include <linux/efi.h> #include <linux/init.h> #include <linux/debugfs.h> #include <linux/seq_file.h> @@ -49,6 +50,14 @@ struct addr_marker { const char *name; }; +/* Private information for debugfs */ +struct ptd_mm_info { + struct mm_struct *mm; + const struct addr_marker *markers; + unsigned long base_addr; + unsigned long end; +}; + static struct addr_marker address_markers[] = { #ifdef CONFIG_KASAN {KASAN_SHADOW_START, "Kasan shadow start"}, @@ -68,6 +77,28 @@ static struct addr_marker address_markers[] = { {-1, NULL}, }; +static struct ptd_mm_info kernel_ptd_info = { + .mm = &init_mm, + .markers = address_markers, + .base_addr = KERN_VIRT_START, + .end = ULONG_MAX, +}; + +#ifdef CONFIG_EFI +static struct addr_marker efi_addr_markers[] = { + { 0, "UEFI runtime start" }, + { SZ_1G, "UEFI runtime end" }, + { -1, NULL } +}; + +static struct ptd_mm_info efi_ptd_info = { + .mm = &efi_mm, + .markers = efi_addr_markers, + .base_addr = 0, + .end = SZ_2G, +}; +#endif + /* Page Table Entry */ struct prot_bits { u64 mask; @@ -245,22 +276,22 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, } } -static void ptdump_walk(struct seq_file *s) +static void ptdump_walk(struct seq_file *s, struct ptd_mm_info *pinfo) { struct pg_state st = { .seq = s, - .marker = address_markers, + .marker = pinfo->markers, .level = -1, .ptdump = { .note_page = note_page, .range = (struct ptdump_range[]) { - {KERN_VIRT_START, ULONG_MAX}, + {pinfo->base_addr, pinfo->end}, {0, 0} } } }; - ptdump_walk_pgd(&st.ptdump, &init_mm, NULL); + ptdump_walk_pgd(&st.ptdump, pinfo->mm, NULL); } void ptdump_check_wx(void) @@ -293,7 +324,7 @@ void ptdump_check_wx(void) static int ptdump_show(struct seq_file *m, void *v) { - ptdump_walk(m); + ptdump_walk(m, m->private); return 0; } @@ -308,8 +339,13 @@ static int ptdump_init(void) for (j = 0; j < ARRAY_SIZE(pte_bits); j++) pg_level[i].mask |= pte_bits[j].mask; - debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, + debugfs_create_file("kernel_page_tables", 0400, NULL, &kernel_ptd_info, &ptdump_fops); +#ifdef CONFIG_EFI + if (efi_enabled(EFI_RUNTIME_SERVICES)) + debugfs_create_file("efi_page_tables", 0400, NULL, &efi_ptd_info, + &ptdump_fops); +#endif return 0; } diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index b29fcc66ec39..4a2a12be04c9 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -60,6 +60,7 @@ config S390 def_bool y 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_FORTIFY_SOURCE @@ -73,6 +74,7 @@ config S390 select ARCH_HAS_STRICT_MODULE_RWX select ARCH_HAS_SYSCALL_WRAPPER select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_HAS_VDSO_DATA select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_INLINE_READ_LOCK select ARCH_INLINE_READ_LOCK_BH @@ -118,6 +120,8 @@ config S390 select GENERIC_CPU_AUTOPROBE select GENERIC_CPU_VULNERABILITIES select GENERIC_FIND_FIRST_BIT + select GENERIC_GETTIMEOFDAY + select GENERIC_PTDUMP select GENERIC_SMP_IDLE_THREAD select GENERIC_TIME_VSYSCALL select HAVE_ALIGNED_STRUCT_PAGE if SLUB @@ -149,6 +153,7 @@ config S390 select HAVE_FUNCTION_TRACER select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_GCC_PLUGINS + select HAVE_GENERIC_VDSO select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZ4 @@ -185,6 +190,8 @@ config S390 select OLD_SIGSUSPEND3 select PCI_DOMAINS if PCI select PCI_MSI if PCI + select PCI_MSI_ARCH_FALLBACKS if PCI_MSI + select SET_FS select SPARSE_IRQ select SYSCTL_EXCEPTION_TRACE select THREAD_INFO_IN_TASK @@ -791,23 +798,6 @@ config CRASH_DUMP endmenu -config SECCOMP - def_bool y - prompt "Enable seccomp to safely compute untrusted bytecode" - depends on PROC_FS - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via /proc/<pid>/seccomp, it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - - If unsure, say Y. - config CCW def_bool y @@ -820,6 +810,7 @@ menu "Virtualization" config PROTECTED_VIRTUALIZATION_GUEST def_bool n prompt "Protected virtualization guest support" + select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS help Select this option, if you want to be able to run this kernel as a protected virtualization KVM guest. diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug index 761fe2b0b2f6..ab48b694ade8 100644 --- a/arch/s390/Kconfig.debug +++ b/arch/s390/Kconfig.debug @@ -3,17 +3,5 @@ config TRACE_IRQFLAGS_SUPPORT def_bool y -config S390_PTDUMP - bool "Export kernel pagetable layout to userspace via debugfs" - depends on DEBUG_KERNEL - select DEBUG_FS - help - Say Y here if you want to show the kernel pagetable layout in a - debugfs file. This information is only useful for kernel developers - who are working in architecture specific areas of the kernel. - It is probably not a good idea to enable this feature in a production - kernel. - If in doubt, say "N" - config EARLY_PRINTK def_bool y diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile index 45b33b83de08..41a64b8dce25 100644 --- a/arch/s390/boot/Makefile +++ b/arch/s390/boot/Makefile @@ -73,7 +73,3 @@ $(obj)/startup.a: $(OBJECTS) FORCE install: sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/bzImage \ System.map "$(INSTALL_PATH)" - -chkbss := $(obj-y) -chkbss-target := startup.a -include $(srctree)/arch/s390/scripts/Makefile.chkbss diff --git a/arch/s390/boot/compressed/Makefile b/arch/s390/boot/compressed/Makefile index fa529c5b4486..b235ed95a3d8 100644 --- a/arch/s390/boot/compressed/Makefile +++ b/arch/s390/boot/compressed/Makefile @@ -62,7 +62,3 @@ $(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE OBJCOPYFLAGS_piggy.o := -I binary -O elf64-s390 -B s390:64-bit --rename-section .data=.vmlinux.bin.compressed $(obj)/piggy.o: $(obj)/vmlinux.bin$(suffix-y) FORCE $(call if_changed,objcopy) - -chkbss := $(filter-out piggy.o info.o, $(obj-y)) -chkbss-target := vmlinux.bin -include $(srctree)/arch/s390/scripts/Makefile.chkbss diff --git a/arch/s390/boot/compressed/decompressor.c b/arch/s390/boot/compressed/decompressor.c index 368fd372c875..3061b11c4d27 100644 --- a/arch/s390/boot/compressed/decompressor.c +++ b/arch/s390/boot/compressed/decompressor.c @@ -16,7 +16,6 @@ * gzip declarations */ #define STATIC static -#define STATIC_RW_DATA static __section(.data) #undef memset #undef memcpy diff --git a/arch/s390/boot/compressed/vmlinux.lds.S b/arch/s390/boot/compressed/vmlinux.lds.S index 44561b2c3712..9427e2cd0c15 100644 --- a/arch/s390/boot/compressed/vmlinux.lds.S +++ b/arch/s390/boot/compressed/vmlinux.lds.S @@ -59,6 +59,19 @@ SECTIONS BOOT_DATA_PRESERVED /* + * This is the BSS section of the decompressor and not of the decompressed Linux kernel. + * It will consume place in the decompressor's image. + */ + . = ALIGN(8); + .bss : { + _bss = . ; + *(.bss) + *(.bss.*) + *(COMMON) + _ebss = .; + } + + /* * uncompressed image info used by the decompressor it should match * struct vmlinux_info. It comes from .vmlinux.info section of * uncompressed vmlinux in a form of info.o @@ -81,15 +94,6 @@ SECTIONS FILL(0xff); . = ALIGN(4096); } - . = ALIGN(256); - .bss : { - _bss = . ; - *(.bss) - *(.bss.*) - *(COMMON) - . = ALIGN(8); /* For convenience during zeroing */ - _ebss = .; - } _end = .; /* Sections to be discarded */ diff --git a/arch/s390/boot/head.S b/arch/s390/boot/head.S index dae10961d072..1a2c2b1ed964 100644 --- a/arch/s390/boot/head.S +++ b/arch/s390/boot/head.S @@ -360,22 +360,23 @@ ENTRY(startup_kdump) # the save area and does disabled wait with a faulty address. # ENTRY(startup_pgm_check_handler) - stmg %r0,%r15,__LC_SAVE_AREA_SYNC - la %r1,4095 - stctg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r1) - mvc __LC_GPREGS_SAVE_AREA-4095(128,%r1),__LC_SAVE_AREA_SYNC - mvc __LC_PSW_SAVE_AREA-4095(16,%r1),__LC_PGM_OLD_PSW + stmg %r8,%r15,__LC_SAVE_AREA_SYNC + la %r8,4095 + stctg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r8) + stmg %r0,%r7,__LC_GPREGS_SAVE_AREA-4095(%r8) + mvc __LC_GPREGS_SAVE_AREA-4095+64(64,%r8),__LC_SAVE_AREA_SYNC + mvc __LC_PSW_SAVE_AREA-4095(16,%r8),__LC_PGM_OLD_PSW mvc __LC_RETURN_PSW(16),__LC_PGM_OLD_PSW ni __LC_RETURN_PSW,0xfc # remove IO and EX bits ni __LC_RETURN_PSW+1,0xfb # remove MCHK bit oi __LC_RETURN_PSW+1,0x2 # set wait state bit - larl %r2,.Lold_psw_disabled_wait - stg %r2,__LC_PGM_NEW_PSW+8 - l %r15,.Ldump_info_stack-.Lold_psw_disabled_wait(%r2) + larl %r9,.Lold_psw_disabled_wait + stg %r9,__LC_PGM_NEW_PSW+8 + l %r15,.Ldump_info_stack-.Lold_psw_disabled_wait(%r9) brasl %r14,print_pgm_check_info .Lold_psw_disabled_wait: - la %r1,4095 - lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1) + la %r8,4095 + lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r8) lpswe __LC_RETURN_PSW # disabled wait .Ldump_info_stack: .long 0x5000 + PAGE_SIZE - STACK_FRAME_OVERHEAD diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c index 8e222a666025..f94b91d72620 100644 --- a/arch/s390/boot/ipl_parm.c +++ b/arch/s390/boot/ipl_parm.c @@ -21,7 +21,7 @@ unsigned long __bootdata(memory_end); int __bootdata(memory_end_set); int __bootdata(noexec_disabled); -int kaslr_enabled __section(.data); +int kaslr_enabled; static inline int __diag308(unsigned long subcode, void *addr) { @@ -70,30 +70,44 @@ static size_t scpdata_length(const u8 *buf, size_t count) static size_t ipl_block_get_ascii_scpdata(char *dest, size_t size, const struct ipl_parameter_block *ipb) { - size_t count; - size_t i; + const __u8 *scp_data; + __u32 scp_data_len; int has_lowercase; + size_t count = 0; + size_t i; + + switch (ipb->pb0_hdr.pbt) { + case IPL_PBT_FCP: + scp_data_len = ipb->fcp.scp_data_len; + scp_data = ipb->fcp.scp_data; + break; + case IPL_PBT_NVME: + scp_data_len = ipb->nvme.scp_data_len; + scp_data = ipb->nvme.scp_data; + break; + default: + goto out; + } - count = min(size - 1, scpdata_length(ipb->fcp.scp_data, - ipb->fcp.scp_data_len)); + count = min(size - 1, scpdata_length(scp_data, scp_data_len)); if (!count) goto out; has_lowercase = 0; for (i = 0; i < count; i++) { - if (!isascii(ipb->fcp.scp_data[i])) { + if (!isascii(scp_data[i])) { count = 0; goto out; } - if (!has_lowercase && islower(ipb->fcp.scp_data[i])) + if (!has_lowercase && islower(scp_data[i])) has_lowercase = 1; } if (has_lowercase) - memcpy(dest, ipb->fcp.scp_data, count); + memcpy(dest, scp_data, count); else for (i = 0; i < count; i++) - dest[i] = tolower(ipb->fcp.scp_data[i]); + dest[i] = tolower(scp_data[i]); out: dest[count] = '\0'; return count; @@ -115,6 +129,7 @@ static void append_ipl_block_parm(void) parm, COMMAND_LINE_SIZE - len - 1, &ipl_block); break; case IPL_PBT_FCP: + case IPL_PBT_NVME: rc = ipl_block_get_ascii_scpdata( parm, COMMAND_LINE_SIZE - len - 1, &ipl_block); break; @@ -209,7 +224,7 @@ static void modify_fac_list(char *str) check_cleared_facilities(); } -static char command_line_buf[COMMAND_LINE_SIZE] __section(.data); +static char command_line_buf[COMMAND_LINE_SIZE]; void parse_boot_command_line(void) { char *param, *val; @@ -230,7 +245,7 @@ void parse_boot_command_line(void) if (!strcmp(param, "vmalloc") && val) vmalloc_size = round_up(memparse(val, NULL), PAGE_SIZE); - if (!strcmp(param, "dfltcc")) { + if (!strcmp(param, "dfltcc") && val) { if (!strcmp(val, "off")) zlib_dfltcc_support = ZLIB_DFLTCC_DISABLED; else if (!strcmp(val, "on")) @@ -254,17 +269,34 @@ void parse_boot_command_line(void) if (!strcmp(param, "nokaslr")) kaslr_enabled = 0; + +#if IS_ENABLED(CONFIG_KVM) + if (!strcmp(param, "prot_virt")) { + rc = kstrtobool(val, &enabled); + if (!rc && enabled) + prot_virt_host = 1; + } +#endif } } +static inline bool is_ipl_block_dump(void) +{ + if (ipl_block.pb0_hdr.pbt == IPL_PBT_FCP && + ipl_block.fcp.opt == IPL_PB0_FCP_OPT_DUMP) + return true; + if (ipl_block.pb0_hdr.pbt == IPL_PBT_NVME && + ipl_block.nvme.opt == IPL_PB0_NVME_OPT_DUMP) + return true; + return false; +} + void setup_memory_end(void) { #ifdef CONFIG_CRASH_DUMP if (OLDMEM_BASE) { kaslr_enabled = 0; - } else if (ipl_block_valid && - ipl_block.pb0_hdr.pbt == IPL_PBT_FCP && - ipl_block.fcp.opt == IPL_PB0_FCP_OPT_DUMP) { + } else if (ipl_block_valid && is_ipl_block_dump()) { kaslr_enabled = 0; if (!sclp_early_get_hsa_size(&memory_end) && memory_end) memory_end_set = 1; diff --git a/arch/s390/boot/kaslr.c b/arch/s390/boot/kaslr.c index d4442163ffa9..d844a5ef9089 100644 --- a/arch/s390/boot/kaslr.c +++ b/arch/s390/boot/kaslr.c @@ -42,7 +42,7 @@ static int check_prng(void) return PRNG_MODE_TDES; } -static unsigned long get_random(unsigned long limit) +static int get_random(unsigned long limit, unsigned long *value) { struct prng_parm prng = { /* initial parameter block for tdes mode, copied from libica */ @@ -84,19 +84,101 @@ static unsigned long get_random(unsigned long limit) (u8 *) &random, sizeof(random)); break; default: - random = 0; + return -1; } - return random % limit; + *value = random % limit; + return 0; +} + +/* + * To randomize kernel base address we have to consider several facts: + * 1. physical online memory might not be continuous and have holes. mem_detect + * info contains list of online memory ranges we should consider. + * 2. we have several memory regions which are occupied and we should not + * overlap and destroy them. Currently safe_addr tells us the border below + * which all those occupied regions are. We are safe to use anything above + * safe_addr. + * 3. the upper limit might apply as well, even if memory above that limit is + * online. Currently those limitations are: + * 3.1. Limit set by "mem=" kernel command line option + * 3.2. memory reserved at the end for kasan initialization. + * 4. kernel base address must be aligned to THREAD_SIZE (kernel stack size). + * Which is required for CONFIG_CHECK_STACK. Currently THREAD_SIZE is 4 pages + * (16 pages when the kernel is built with kasan enabled) + * Assumptions: + * 1. kernel size (including .bss size) and upper memory limit are page aligned. + * 2. mem_detect memory region start is THREAD_SIZE aligned / end is PAGE_SIZE + * aligned (in practice memory configurations granularity on z/VM and LPAR + * is 1mb). + * + * To guarantee uniform distribution of kernel base address among all suitable + * addresses we generate random value just once. For that we need to build a + * continuous range in which every value would be suitable. We can build this + * range by simply counting all suitable addresses (let's call them positions) + * which would be valid as kernel base address. To count positions we iterate + * over online memory ranges. For each range which is big enough for the + * kernel image we count all suitable addresses we can put the kernel image at + * that is + * (end - start - kernel_size) / THREAD_SIZE + 1 + * Two functions count_valid_kernel_positions and position_to_address help + * to count positions in memory range given and then convert position back + * to address. + */ +static unsigned long count_valid_kernel_positions(unsigned long kernel_size, + unsigned long _min, + unsigned long _max) +{ + unsigned long start, end, pos = 0; + int i; + + for_each_mem_detect_block(i, &start, &end) { + if (_min >= end) + continue; + if (start >= _max) + break; + start = max(_min, start); + end = min(_max, end); + if (end - start < kernel_size) + continue; + pos += (end - start - kernel_size) / THREAD_SIZE + 1; + } + + return pos; +} + +static unsigned long position_to_address(unsigned long pos, unsigned long kernel_size, + unsigned long _min, unsigned long _max) +{ + unsigned long start, end; + int i; + + for_each_mem_detect_block(i, &start, &end) { + if (_min >= end) + continue; + if (start >= _max) + break; + start = max(_min, start); + end = min(_max, end); + if (end - start < kernel_size) + continue; + if ((end - start - kernel_size) / THREAD_SIZE + 1 >= pos) + return start + (pos - 1) * THREAD_SIZE; + pos -= (end - start - kernel_size) / THREAD_SIZE + 1; + } + + return 0; } unsigned long get_random_base(unsigned long safe_addr) { - unsigned long memory_limit = memory_end_set ? memory_end : 0; - unsigned long base, start, end, kernel_size; - unsigned long block_sum, offset; + unsigned long memory_limit = get_mem_detect_end(); + unsigned long base_pos, max_pos, kernel_size; unsigned long kasan_needs; int i; + if (memory_end_set) + memory_limit = min(memory_limit, memory_end); + if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && INITRD_START && INITRD_SIZE) { if (safe_addr < INITRD_START + INITRD_SIZE) safe_addr = INITRD_START + INITRD_SIZE; @@ -126,45 +208,17 @@ unsigned long get_random_base(unsigned long safe_addr) } kernel_size = vmlinux.image_size + vmlinux.bss_size; - block_sum = 0; - for_each_mem_detect_block(i, &start, &end) { - if (memory_limit) { - if (start >= memory_limit) - break; - if (end > memory_limit) - end = memory_limit; - } - if (end - start < kernel_size) - continue; - block_sum += end - start - kernel_size; - } - if (!block_sum) { + if (safe_addr + kernel_size > memory_limit) + return 0; + + max_pos = count_valid_kernel_positions(kernel_size, safe_addr, memory_limit); + if (!max_pos) { sclp_early_printk("KASLR disabled: not enough memory\n"); return 0; } - base = get_random(block_sum); - if (base == 0) + /* we need a value in the range [1, base_pos] inclusive */ + if (get_random(max_pos, &base_pos)) return 0; - if (base < safe_addr) - base = safe_addr; - block_sum = offset = 0; - for_each_mem_detect_block(i, &start, &end) { - if (memory_limit) { - if (start >= memory_limit) - break; - if (end > memory_limit) - end = memory_limit; - } - if (end - start < kernel_size) - continue; - block_sum += end - start - kernel_size; - if (base <= block_sum) { - base = start + base - offset; - base = ALIGN_DOWN(base, THREAD_SIZE); - break; - } - offset = block_sum; - } - return base; + return position_to_address(base_pos + 1, kernel_size, safe_addr, memory_limit); } diff --git a/arch/s390/boot/pgm_check_info.c b/arch/s390/boot/pgm_check_info.c index 83b5b7915c32..a3c9862bcede 100644 --- a/arch/s390/boot/pgm_check_info.c +++ b/arch/s390/boot/pgm_check_info.c @@ -2,6 +2,7 @@ #include <linux/kernel.h> #include <linux/string.h> #include <asm/lowcore.h> +#include <asm/setup.h> #include <asm/sclp.h> #include "boot.h" @@ -32,7 +33,8 @@ void print_pgm_check_info(void) char *p; add_str(buf, "Linux version "); - strlcat(buf, kernel_version, sizeof(buf)); + strlcat(buf, kernel_version, sizeof(buf) - 1); + strlcat(buf, "\n", sizeof(buf)); sclp_early_printk(buf); p = add_str(buf, "Kernel fault: interruption code "); @@ -42,6 +44,13 @@ void print_pgm_check_info(void) add_str(p, "\n"); sclp_early_printk(buf); + if (kaslr_enabled) { + p = add_str(buf, "Kernel random base: "); + p = add_val_as_hex(p, __kaslr_offset); + add_str(p, "\n"); + sclp_early_printk(buf); + } + p = add_str(buf, "PSW : "); p = add_val_as_hex(p, S390_lowcore.psw_save_area.mask); p = add_str(p, " "); diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c index 3b3a11f95269..cc96b04cc0ba 100644 --- a/arch/s390/boot/startup.c +++ b/arch/s390/boot/startup.c @@ -46,10 +46,8 @@ struct diag_ops __bootdata_preserved(diag_dma_ops) = { .diag0c = _diag0c_dma, .diag308_reset = _diag308_reset_dma }; -static struct diag210 _diag210_tmp_dma __section(.dma.data); +static struct diag210 _diag210_tmp_dma __section(".dma.data"); struct diag210 *__bootdata_preserved(__diag210_tmp_dma) = &_diag210_tmp_dma; -void _swsusp_reset_dma(void); -unsigned long __bootdata_preserved(__swsusp_reset_dma) = __pa(_swsusp_reset_dma); void error(char *x) { @@ -120,6 +118,9 @@ static void handle_relocs(unsigned long offset) } } +/* + * This function clears the BSS section of the decompressed Linux kernel and NOT the decompressor's. + */ static void clear_bss_section(void) { memset((void *)vmlinux.default_lma + vmlinux.image_size, 0, vmlinux.bss_size); diff --git a/arch/s390/boot/text_dma.S b/arch/s390/boot/text_dma.S index 9715715c4c28..f7c77cd518f2 100644 --- a/arch/s390/boot/text_dma.S +++ b/arch/s390/boot/text_dma.S @@ -97,23 +97,6 @@ ENTRY(_diag0c_dma) ENDPROC(_diag0c_dma) /* - * void _swsusp_reset_dma(void) - */ -ENTRY(_swsusp_reset_dma) - larl %r1,restart_entry - larl %r2,.Lrestart_diag308_psw - og %r1,0(%r2) - stg %r1,0(%r0) - lghi %r0,0 - diag %r0,%r0,0x308 -restart_entry: - lhi %r1,1 - sigp %r1,%r0,SIGP_SET_ARCHITECTURE - sam64 - BR_EX_DMA_r14 -ENDPROC(_swsusp_reset_dma) - -/* * void _diag308_reset_dma(void) * * Calls diag 308 subcode 1 and continues execution diff --git a/arch/s390/boot/uv.c b/arch/s390/boot/uv.c index f887a479cdc7..a15c033f53ca 100644 --- a/arch/s390/boot/uv.c +++ b/arch/s390/boot/uv.c @@ -7,6 +7,9 @@ #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST int __bootdata_preserved(prot_virt_guest); #endif +#if IS_ENABLED(CONFIG_KVM) +int __bootdata_preserved(prot_virt_host); +#endif struct uv_info __bootdata_preserved(uv_info); void uv_query_info(void) diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig index 7228aabe9da6..0784bf3caf43 100644 --- a/arch/s390/configs/debug_defconfig +++ b/arch/s390/configs/debug_defconfig @@ -775,6 +775,8 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_PAGEALLOC=y CONFIG_PAGE_OWNER=y CONFIG_DEBUG_RODATA_TEST=y +CONFIG_DEBUG_WX=y +CONFIG_PTDUMP_DEBUGFS=y CONFIG_DEBUG_OBJECTS=y CONFIG_DEBUG_OBJECTS_SELFTEST=y CONFIG_DEBUG_OBJECTS_FREE=y @@ -822,7 +824,6 @@ CONFIG_FTRACE_SYSCALLS=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_BPF_KPROBE_OVERRIDE=y CONFIG_HIST_TRIGGERS=y -CONFIG_S390_PTDUMP=y CONFIG_NOTIFIER_ERROR_INJECTION=m CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m CONFIG_FAULT_INJECTION=y diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig index fab03b7a6932..905bc8c4cfaf 100644 --- a/arch/s390/configs/defconfig +++ b/arch/s390/configs/defconfig @@ -759,6 +759,8 @@ CONFIG_GDB_SCRIPTS=y CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_WX=y +CONFIG_PTDUMP_DEBUGFS=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_PANIC_ON_OOPS=y CONFIG_TEST_LOCKUP=m @@ -775,7 +777,6 @@ CONFIG_FTRACE_SYSCALLS=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_BPF_KPROBE_OVERRIDE=y CONFIG_HIST_TRIGGERS=y -CONFIG_S390_PTDUMP=y CONFIG_LKDTM=m CONFIG_PERCPU_TEST=m CONFIG_ATOMIC64_SELFTEST=y diff --git a/arch/s390/include/asm/cache.h b/arch/s390/include/asm/cache.h index d5e22e837416..00128174c025 100644 --- a/arch/s390/include/asm/cache.h +++ b/arch/s390/include/asm/cache.h @@ -14,6 +14,6 @@ #define L1_CACHE_SHIFT 8 #define NET_SKB_PAD 32 -#define __read_mostly __section(.data..read_mostly) +#define __read_mostly __section(".data..read_mostly") #endif diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h index 3cfe1eb89838..c0be5fe1ddba 100644 --- a/arch/s390/include/asm/ccwdev.h +++ b/arch/s390/include/asm/ccwdev.h @@ -238,7 +238,10 @@ extern void ccw_device_get_schid(struct ccw_device *, struct subchannel_id *); struct channel_path_desc_fmt0 *ccw_device_get_chp_desc(struct ccw_device *, int); u8 *ccw_device_get_util_str(struct ccw_device *cdev, int chp_idx); int ccw_device_pnso(struct ccw_device *cdev, - struct chsc_pnso_area *pnso_area, - struct chsc_pnso_resume_token resume_token, - int cnc); + struct chsc_pnso_area *pnso_area, u8 oc, + struct chsc_pnso_resume_token resume_token, int cnc); +int ccw_device_get_cssid(struct ccw_device *cdev, u8 *cssid); +int ccw_device_get_iid(struct ccw_device *cdev, u8 *iid); +int ccw_device_get_chpid(struct ccw_device *cdev, int chp_idx, u8 *chpid); +int ccw_device_get_chid(struct ccw_device *cdev, int chp_idx, u16 *chid); #endif /* _S390_CCWDEV_H_ */ diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h index 6d01c96aeb5c..a8c02cfbc712 100644 --- a/arch/s390/include/asm/checksum.h +++ b/arch/s390/include/asm/checksum.h @@ -13,21 +13,21 @@ #define _S390_CHECKSUM_H #include <linux/uaccess.h> +#include <linux/in6.h> /* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) + * Computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit). * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic + * Returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic. * - * this function must be called with even lengths, except - * for the last fragment, which may be odd + * This function must be called with even lengths, except + * for the last fragment, which may be odd. * - * it's best to have buff aligned on a 32-bit boundary + * It's best to have buff aligned on a 32-bit boundary. */ -static inline __wsum -csum_partial(const void *buff, int len, __wsum sum) +static inline __wsum csum_partial(const void *buff, int len, __wsum sum) { register unsigned long reg2 asm("2") = (unsigned long) buff; register unsigned long reg3 asm("3") = (unsigned long) len; @@ -39,82 +39,92 @@ csum_partial(const void *buff, int len, __wsum sum) return sum; } -static inline __wsum -csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum) -{ - memcpy(dst,src,len); - return csum_partial(dst, len, sum); -} - /* - * Fold a partial checksum without adding pseudo headers + * Fold a partial checksum without adding pseudo headers. */ static inline __sum16 csum_fold(__wsum sum) { u32 csum = (__force u32) sum; - csum += (csum >> 16) + (csum << 16); + csum += (csum >> 16) | (csum << 16); csum >>= 16; return (__force __sum16) ~csum; } /* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - * + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksums on 4 octet boundaries. */ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) { - return csum_fold(csum_partial(iph, ihl*4, 0)); + __u64 csum = 0; + __u32 *ptr = (u32 *)iph; + + csum += *ptr++; + csum += *ptr++; + csum += *ptr++; + csum += *ptr++; + ihl -= 4; + while (ihl--) + csum += *ptr++; + csum += (csum >> 32) | (csum << 32); + return csum_fold((__force __wsum)(csum >> 32)); } /* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 32-bit checksum + * Computes the checksum of the TCP/UDP pseudo-header. + * Returns a 32-bit checksum. */ -static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, __u8 proto, - __wsum sum) +static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { - __u32 csum = (__force __u32)sum; + __u64 csum = (__force __u64)sum; csum += (__force __u32)saddr; - if (csum < (__force __u32)saddr) - csum++; - csum += (__force __u32)daddr; - if (csum < (__force __u32)daddr) - csum++; - - csum += len + proto; - if (csum < len + proto) - csum++; - - return (__force __wsum)csum; + csum += len; + csum += proto; + csum += (csum >> 32) | (csum << 32); + return (__force __wsum)(csum >> 32); } /* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented + * Computes the checksum of the TCP/UDP pseudo-header. + * Returns a 16-bit checksum, already complemented. */ - -static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, __u8 proto, - __wsum sum) +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); } /* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c + * Used for miscellaneous IP-like checksums, mainly icmp. */ - static inline __sum16 ip_compute_csum(const void *buff, int len) { return csum_fold(csum_partial(buff, len, 0)); } -#endif /* _S390_CHECKSUM_H */ - +#define _HAVE_ARCH_IPV6_CSUM +static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, + const struct in6_addr *daddr, + __u32 len, __u8 proto, __wsum csum) +{ + __u64 sum = (__force __u64)csum; + + sum += (__force __u32)saddr->s6_addr32[0]; + sum += (__force __u32)saddr->s6_addr32[1]; + sum += (__force __u32)saddr->s6_addr32[2]; + sum += (__force __u32)saddr->s6_addr32[3]; + sum += (__force __u32)daddr->s6_addr32[0]; + sum += (__force __u32)daddr->s6_addr32[1]; + sum += (__force __u32)daddr->s6_addr32[2]; + sum += (__force __u32)daddr->s6_addr32[3]; + sum += len; + sum += proto; + sum += (sum >> 32) | (sum << 32); + return csum_fold((__force __wsum)(sum >> 32)); +} +#endif /* _S390_CHECKSUM_H */ diff --git a/arch/s390/include/asm/chsc.h b/arch/s390/include/asm/chsc.h index 36ce2d25a5fc..ae4d2549cd67 100644 --- a/arch/s390/include/asm/chsc.h +++ b/arch/s390/include/asm/chsc.h @@ -12,6 +12,13 @@ #include <uapi/asm/chsc.h> /** + * Operation codes for CHSC PNSO: + * PNSO_OC_NET_BRIDGE_INFO - only addresses that are visible to a bridgeport + * PNSO_OC_NET_ADDR_INFO - all addresses + */ +#define PNSO_OC_NET_BRIDGE_INFO 0 +#define PNSO_OC_NET_ADDR_INFO 3 +/** * struct chsc_pnso_naid_l2 - network address information descriptor * @nit: Network interface token * @addr_lnid: network address and logical network id (VLAN ID) diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index b5bfb3123cb1..5c58756d6476 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h @@ -356,7 +356,6 @@ static inline u8 pathmask_to_pos(u8 mask) return 8 - ffs(mask); } -void channel_subsystem_reinit(void); extern void css_schedule_reprobe(void); extern void *cio_dma_zalloc(size_t size); @@ -372,6 +371,7 @@ struct gen_pool *cio_gp_dma_create(struct device *dma_dev, int nr_pages); /* Function from drivers/s390/cio/chsc.c */ int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta); int chsc_sstpi(void *page, void *result, size_t size); +int chsc_stzi(void *page, void *result, size_t size); int chsc_sgib(u32 origin); #endif diff --git a/arch/s390/include/asm/clocksource.h b/arch/s390/include/asm/clocksource.h new file mode 100644 index 000000000000..03434369fce4 --- /dev/null +++ b/arch/s390/include/asm/clocksource.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* s390-specific clocksource additions */ + +#ifndef _ASM_S390_CLOCKSOURCE_H +#define _ASM_S390_CLOCKSOURCE_H + +#endif /* _ASM_S390_CLOCKSOURCE_H */ diff --git a/arch/s390/include/asm/clp.h b/arch/s390/include/asm/clp.h index 3925b0f085b7..10919eeb7533 100644 --- a/arch/s390/include/asm/clp.h +++ b/arch/s390/include/asm/clp.h @@ -5,6 +5,9 @@ /* CLP common request & response block size */ #define CLP_BLK_SIZE PAGE_SIZE +/* Call Logical Processor - Command Code */ +#define CLP_SLPC 0x0001 + #define CLP_LPS_BASE 0 #define CLP_LPS_PCI 2 diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index 9547cd5d6cdc..ea5b9c34b7be 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -63,8 +63,6 @@ typedef u16 compat_nlink_t; typedef u16 compat_ipc_pid_t; typedef u32 compat_caddr_t; typedef __kernel_fsid_t compat_fsid_t; -typedef s64 compat_s64; -typedef u64 compat_u64; typedef struct { u32 mask; diff --git a/arch/s390/include/asm/css_chars.h b/arch/s390/include/asm/css_chars.h index 480bb02ccacd..638137d46c85 100644 --- a/arch/s390/include/asm/css_chars.h +++ b/arch/s390/include/asm/css_chars.h @@ -36,7 +36,9 @@ struct css_general_char { u64 alt_ssi : 1; /* bit 108 */ u64 : 1; u64 narf : 1; /* bit 110 */ - u64 : 12; + u64 : 5; + u64 enarf: 1; /* bit 116 */ + u64 : 6; u64 util_str : 1;/* bit 123 */ } __packed; diff --git a/arch/s390/include/asm/gmap.h b/arch/s390/include/asm/gmap.h index a816fb4734b8..40264f60b0da 100644 --- a/arch/s390/include/asm/gmap.h +++ b/arch/s390/include/asm/gmap.h @@ -140,8 +140,6 @@ int gmap_shadow_page(struct gmap *sg, unsigned long saddr, pte_t pte); void gmap_register_pte_notifier(struct gmap_notifier *); void gmap_unregister_pte_notifier(struct gmap_notifier *); -void gmap_pte_notify(struct mm_struct *, unsigned long addr, pte_t *, - unsigned long bits); int gmap_mprotect_notify(struct gmap *, unsigned long start, unsigned long len, int prot); diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h index da014e4f8113..28664ee0abc1 100644 --- a/arch/s390/include/asm/io.h +++ b/arch/s390/include/asm/io.h @@ -12,6 +12,7 @@ #include <linux/kernel.h> #include <asm/page.h> +#include <asm/pgtable.h> #include <asm/pci_io.h> #define xlate_dev_mem_ptr xlate_dev_mem_ptr @@ -26,7 +27,10 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr); #define IO_SPACE_LIMIT 0 +void __iomem *ioremap_prot(phys_addr_t addr, size_t size, unsigned long prot); void __iomem *ioremap(phys_addr_t addr, size_t size); +void __iomem *ioremap_wc(phys_addr_t addr, size_t size); +void __iomem *ioremap_wt(phys_addr_t addr, size_t size); void iounmap(volatile void __iomem *addr); static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) @@ -52,6 +56,10 @@ static inline void ioport_unmap(void __iomem *p) #define pci_iomap_wc pci_iomap_wc #define pci_iomap_wc_range pci_iomap_wc_range +#define ioremap ioremap +#define ioremap_wt ioremap_wt +#define ioremap_wc ioremap_wc + #define memcpy_fromio(dst, src, count) zpci_memcpy_fromio(dst, src, count) #define memcpy_toio(dst, src, count) zpci_memcpy_toio(dst, src, count) #define memset_io(dst, val, count) zpci_memset_io(dst, val, count) diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 7d5cfdda5277..a9e2c7295b35 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h @@ -66,6 +66,7 @@ enum ipl_type { IPL_TYPE_FCP_DUMP = 8, IPL_TYPE_NSS = 16, IPL_TYPE_NVME = 32, + IPL_TYPE_NVME_DUMP = 64, }; struct ipl_info @@ -94,6 +95,12 @@ extern struct ipl_info ipl_info; extern void setup_ipl(void); extern void set_os_info_reipl_block(void); +static inline bool is_ipl_type_dump(void) +{ + return (ipl_info.type == IPL_TYPE_FCP_DUMP) || + (ipl_info.type == IPL_TYPE_NVME_DUMP); +} + struct ipl_report { struct ipl_parameter_block *ipib; struct list_head components; diff --git a/arch/s390/include/asm/kasan.h b/arch/s390/include/asm/kasan.h index 89d6886040c8..e9bf486de136 100644 --- a/arch/s390/include/asm/kasan.h +++ b/arch/s390/include/asm/kasan.h @@ -19,6 +19,7 @@ extern void kasan_early_init(void); extern void kasan_copy_shadow(pgd_t *dst); extern void kasan_free_early_identity(void); +extern unsigned long kasan_vmax; #else static inline void kasan_early_init(void) { } static inline void kasan_copy_shadow(pgd_t *dst) { } diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index 99b92c3e46b0..212628932ddc 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h @@ -132,7 +132,8 @@ struct zpci_dev { u8 rid_available : 1; u8 has_hp_slot : 1; u8 is_physfn : 1; - u8 reserved : 5; + u8 util_str_avail : 1; + u8 reserved : 4; unsigned int devfn; /* DEVFN part of the RID*/ struct mutex lock; @@ -179,6 +180,7 @@ struct zpci_dev { atomic64_t mapped_pages; atomic64_t unmapped_pages; + u8 version; enum pci_bus_speed max_bus_speed; struct dentry *debugfs_dev; @@ -208,9 +210,8 @@ int zpci_unregister_ioat(struct zpci_dev *, u8); void zpci_remove_reserved_devices(void); /* CLP */ +int clp_setup_writeback_mio(void); int clp_scan_pci_devices(void); -int clp_rescan_pci_devices(void); -int clp_rescan_pci_devices_simple(u32 *fid); int clp_add_pci_device(u32, u32, int); int clp_enable_fh(struct zpci_dev *, u8); int clp_disable_fh(struct zpci_dev *); @@ -232,12 +233,10 @@ static inline bool zpci_use_mio(struct zpci_dev *zdev) /* Error handling and recovery */ void zpci_event_error(void *); void zpci_event_availability(void *); -void zpci_rescan(void); bool zpci_is_enabled(void); #else /* CONFIG_PCI */ static inline void zpci_event_error(void *e) {} static inline void zpci_event_availability(void *e) {} -static inline void zpci_rescan(void) {} #endif /* CONFIG_PCI */ #ifdef CONFIG_HOTPLUG_PCI_S390 @@ -282,7 +281,6 @@ int zpci_debug_init(void); void zpci_debug_exit(void); void zpci_debug_init_device(struct zpci_dev *, const char *); void zpci_debug_exit_device(struct zpci_dev *); -void zpci_debug_info(struct zpci_dev *, struct seq_file *); /* Error reporting */ int zpci_report_error(struct pci_dev *, struct zpci_report_error_header *); diff --git a/arch/s390/include/asm/pci_clp.h b/arch/s390/include/asm/pci_clp.h index eb51272dd2cc..1f4b666e85ee 100644 --- a/arch/s390/include/asm/pci_clp.h +++ b/arch/s390/include/asm/pci_clp.h @@ -7,6 +7,7 @@ /* * Call Logical Processor - Command Codes */ +#define CLP_SLPC 0x0001 #define CLP_LIST_PCI 0x0002 #define CLP_QUERY_PCI_FN 0x0003 #define CLP_QUERY_PCI_FNGRP 0x0004 @@ -51,6 +52,19 @@ struct clp_fh_list_entry { extern bool zpci_unique_uid; +struct clp_rsp_slpc_pci { + struct clp_rsp_hdr hdr; + u32 reserved2[4]; + u32 lpif[8]; + u32 reserved3[4]; + u32 vwb : 1; + u32 : 1; + u32 mio_wb : 6; + u32 : 24; + u32 reserved5[3]; + u32 lpic[8]; +} __packed; + /* List PCI functions request */ struct clp_req_list_pci { struct clp_req_hdr hdr; @@ -172,6 +186,11 @@ struct clp_rsp_set_pci { } __packed; /* Combined request/response block structures used by clp insn */ +struct clp_req_rsp_slpc_pci { + struct clp_req_slpc request; + struct clp_rsp_slpc_pci response; +} __packed; + struct clp_req_rsp_list_pci { struct clp_req_list_pci request; struct clp_rsp_list_pci response; diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index 74a352f8c0d1..d1297d6bbdcf 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -146,8 +146,6 @@ static inline void pmd_populate(struct mm_struct *mm, #define pte_free_kernel(mm, pte) page_table_free(mm, (unsigned long *) pte) #define pte_free(mm, pte) page_table_free(mm, (unsigned long *) pte) -extern void rcu_table_freelist_finish(void); - void vmem_map_init(void); void *vmem_crst_alloc(unsigned long val); pte_t *vmem_pte_alloc(void); diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 7eb01a5459cd..6b8d8c69b1a1 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -89,6 +89,7 @@ extern unsigned long VMALLOC_START; extern unsigned long VMALLOC_END; #define VMALLOC_DEFAULT_SIZE ((128UL << 30) - MODULES_LEN) extern struct page *vmemmap; +extern unsigned long vmemmap_size; #define VMEM_MAX_PHYS ((unsigned long) vmemmap) @@ -1186,6 +1187,12 @@ void gmap_pmdp_invalidate(struct mm_struct *mm, unsigned long vmaddr); void gmap_pmdp_idte_local(struct mm_struct *mm, unsigned long vmaddr); void gmap_pmdp_idte_global(struct mm_struct *mm, unsigned long vmaddr); +#define pgprot_writecombine pgprot_writecombine +pgprot_t pgprot_writecombine(pgprot_t prot); + +#define pgprot_writethrough pgprot_writethrough +pgprot_t pgprot_writethrough(pgprot_t prot); + /* * Certain architectures need to do special things when PTEs * within a page table are directly modified. Thus, the following @@ -1209,7 +1216,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) { pte_t __pte; - pte_val(__pte) = physpage + pgprot_val(pgprot); + + pte_val(__pte) = physpage | pgprot_val(pgprot); if (!MACHINE_HAS_NX) pte_val(__pte) &= ~_PAGE_NOEXEC; return pte_mkyoung(__pte); @@ -1260,26 +1268,44 @@ static inline pgd_t *pgd_offset_raw(pgd_t *pgd, unsigned long address) #define pgd_offset(mm, address) pgd_offset_raw(READ_ONCE((mm)->pgd), address) -static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) +static inline p4d_t *p4d_offset_lockless(pgd_t *pgdp, pgd_t pgd, unsigned long address) +{ + if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R1) + return (p4d_t *) pgd_deref(pgd) + p4d_index(address); + return (p4d_t *) pgdp; +} +#define p4d_offset_lockless p4d_offset_lockless + +static inline p4d_t *p4d_offset(pgd_t *pgdp, unsigned long address) { - if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R1) - return (p4d_t *) pgd_deref(*pgd) + p4d_index(address); - return (p4d_t *) pgd; + return p4d_offset_lockless(pgdp, *pgdp, address); } -static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address) +static inline pud_t *pud_offset_lockless(p4d_t *p4dp, p4d_t p4d, unsigned long address) { - if ((p4d_val(*p4d) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R2) - return (pud_t *) p4d_deref(*p4d) + pud_index(address); - return (pud_t *) p4d; + if ((p4d_val(p4d) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R2) + return (pud_t *) p4d_deref(p4d) + pud_index(address); + return (pud_t *) p4dp; +} +#define pud_offset_lockless pud_offset_lockless + +static inline pud_t *pud_offset(p4d_t *p4dp, unsigned long address) +{ + return pud_offset_lockless(p4dp, *p4dp, address); } #define pud_offset pud_offset -static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) +static inline pmd_t *pmd_offset_lockless(pud_t *pudp, pud_t pud, unsigned long address) +{ + if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R3) + return (pmd_t *) pud_deref(pud) + pmd_index(address); + return (pmd_t *) pudp; +} +#define pmd_offset_lockless pmd_offset_lockless + +static inline pmd_t *pmd_offset(pud_t *pudp, unsigned long address) { - if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R3) - return (pmd_t *) pud_deref(*pud) + pmd_index(address); - return (pmd_t *) pud; + return pmd_offset_lockless(pudp, *pudp, address); } #define pmd_offset pmd_offset diff --git a/arch/s390/include/asm/ptdump.h b/arch/s390/include/asm/ptdump.h new file mode 100644 index 000000000000..f960b2896606 --- /dev/null +++ b/arch/s390/include/asm/ptdump.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _ASM_S390_PTDUMP_H +#define _ASM_S390_PTDUMP_H + +void ptdump_check_wx(void); + +static inline void debug_checkwx(void) +{ + if (IS_ENABLED(CONFIG_DEBUG_WX)) + ptdump_check_wx(); +} + +#endif /* _ASM_S390_PTDUMP_H */ diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index e69dbf438f99..19e84c95d1e7 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h @@ -26,9 +26,9 @@ /** * struct qdesfmt0 - queue descriptor, format 0 - * @sliba: storage list information block address - * @sla: storage list address - * @slsba: storage list state block address + * @sliba: absolute address of storage list information block + * @sla: absolute address of storage list + * @slsba: absolute address of storage list state block * @akey: access key for SLIB * @bkey: access key for SL * @ckey: access key for SBALs @@ -56,7 +56,7 @@ struct qdesfmt0 { * @oqdcnt: output queue descriptor count * @iqdsz: input queue descriptor size * @oqdsz: output queue descriptor size - * @qiba: queue information block address + * @qiba: absolute address of queue information block * @qkey: queue information block key * @qdf0: queue descriptions */ @@ -327,7 +327,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int, * struct qdio_initialize - qdio initialization data * @q_format: queue format * @qdr_ac: feature flags to set - * @adapter_name: name for the adapter * @qib_param_field_format: format for qib_parm_field * @qib_param_field: pointer to 128 bytes or NULL, if no param field * @qib_rflags: rflags to set @@ -347,7 +346,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int, struct qdio_initialize { unsigned char q_format; unsigned char qdr_ac; - unsigned char adapter_name[8]; unsigned int qib_param_field_format; unsigned char *qib_param_field; unsigned char qib_rflags; diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index c563f8368b19..a7bdd128d85b 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -114,8 +114,7 @@ int sclp_early_get_core_info(struct sclp_core_info *info); void sclp_early_get_ipl_info(struct sclp_ipl_info *info); void sclp_early_detect(void); void sclp_early_printk(const char *s); -void sclp_early_printk_force(const char *s); -void __sclp_early_printk(const char *s, unsigned int len, unsigned int force); +void __sclp_early_printk(const char *s, unsigned int len); int sclp_early_get_memsize(unsigned long *mem); int sclp_early_get_hsa_size(unsigned long *hsa_size); @@ -129,6 +128,8 @@ int sclp_chp_deconfigure(struct chp_id chpid); int sclp_chp_read_info(struct sclp_chp_info *info); int sclp_pci_configure(u32 fid); int sclp_pci_deconfigure(u32 fid); +int sclp_ap_configure(u32 apid); +int sclp_ap_deconfigure(u32 apid); int sclp_pci_report(struct zpci_report_error_header *report, u32 fh, u32 fid); int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count); int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count); diff --git a/arch/s390/include/asm/sections.h b/arch/s390/include/asm/sections.h index 42de04ad9c07..a996d3990a02 100644 --- a/arch/s390/include/asm/sections.h +++ b/arch/s390/include/asm/sections.h @@ -26,14 +26,14 @@ static inline int arch_is_kernel_initmem_freed(unsigned long addr) * final .boot.data section, which should be identical in the decompressor and * the decompressed kernel (that is checked during the build). */ -#define __bootdata(var) __section(.boot.data.var) var +#define __bootdata(var) __section(".boot.data.var") var /* * .boot.preserved.data is similar to .boot.data, but it is not part of the * .init section and thus will be preserved for later use in the decompressed * kernel. */ -#define __bootdata_preserved(var) __section(.boot.preserved.data.var) var +#define __bootdata_preserved(var) __section(".boot.preserved.data.var") var extern unsigned long __sdma, __edma; extern unsigned long __stext_dma, __etext_dma; diff --git a/arch/s390/include/asm/set_memory.h b/arch/s390/include/asm/set_memory.h index c59a83536c70..a22a5a81811c 100644 --- a/arch/s390/include/asm/set_memory.h +++ b/arch/s390/include/asm/set_memory.h @@ -2,6 +2,10 @@ #ifndef _ASMS390_SET_MEMORY_H #define _ASMS390_SET_MEMORY_H +#include <linux/mutex.h> + +extern struct mutex cpa_mutex; + #define SET_MEMORY_RO 1UL #define SET_MEMORY_RW 2UL #define SET_MEMORY_NX 4UL diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 534f212753d6..bdb242a1544e 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -92,7 +92,9 @@ extern int memory_end_set; extern unsigned long memory_end; extern unsigned long vmalloc_size; extern unsigned long max_physmem_end; -extern unsigned long __swsusp_reset_dma; + +/* The Write Back bit position in the physaddr is given by the SLPC PCI */ +extern unsigned long mio_wb_bit_mask; #define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) #define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) @@ -119,9 +121,6 @@ extern unsigned int console_mode; extern unsigned int console_devno; extern unsigned int console_irq; -extern char vmhalt_cmd[]; -extern char vmpoff_cmd[]; - #define CONSOLE_IS_UNDEFINED (console_mode == 0) #define CONSOLE_IS_SCLP (console_mode == 1) #define CONSOLE_IS_3215 (console_mode == 2) diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index 7e155fb6c254..01e360004481 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h @@ -31,7 +31,6 @@ extern void smp_emergency_stop(void); extern int smp_find_processor_id(u16 address); extern int smp_store_status(int cpu); extern void smp_save_dump_cpus(void); -extern int smp_vcpu_scheduled(int cpu); extern void smp_yield_cpu(int cpu); extern void smp_cpu_set_polarization(int cpu, int val); extern int smp_cpu_get_polarization(int cpu); diff --git a/arch/s390/include/asm/stp.h b/arch/s390/include/asm/stp.h index f0ddefb06ec8..ba07463897c1 100644 --- a/arch/s390/include/asm/stp.h +++ b/arch/s390/include/asm/stp.h @@ -6,43 +6,89 @@ #ifndef __S390_STP_H #define __S390_STP_H +#include <linux/compiler.h> + /* notifier for syncs */ extern struct atomic_notifier_head s390_epoch_delta_notifier; /* STP interruption parameter */ struct stp_irq_parm { - unsigned int _pad0 : 14; - unsigned int tsc : 1; /* Timing status change */ - unsigned int lac : 1; /* Link availability change */ - unsigned int tcpc : 1; /* Time control parameter change */ - unsigned int _pad2 : 15; -} __attribute__ ((packed)); + u32 : 14; + u32 tsc : 1; /* Timing status change */ + u32 lac : 1; /* Link availability change */ + u32 tcpc : 1; /* Time control parameter change */ + u32 : 15; +} __packed; #define STP_OP_SYNC 1 #define STP_OP_CTRL 3 struct stp_sstpi { - unsigned int rsvd0; - unsigned int rsvd1 : 8; - unsigned int stratum : 8; - unsigned int vbits : 16; - unsigned int leaps : 16; - unsigned int tmd : 4; - unsigned int ctn : 4; - unsigned int rsvd2 : 3; - unsigned int c : 1; - unsigned int tst : 4; - unsigned int tzo : 16; - unsigned int dsto : 16; - unsigned int ctrl : 16; - unsigned int rsvd3 : 16; - unsigned int tto; - unsigned int rsvd4; - unsigned int ctnid[3]; - unsigned int rsvd5; - unsigned int todoff[4]; - unsigned int rsvd6[48]; -} __attribute__ ((packed)); + u32 : 32; + u32 tu : 1; + u32 lu : 1; + u32 : 6; + u32 stratum : 8; + u32 vbits : 16; + u32 leaps : 16; + u32 tmd : 4; + u32 ctn : 4; + u32 : 3; + u32 c : 1; + u32 tst : 4; + u32 tzo : 16; + u32 dsto : 16; + u32 ctrl : 16; + u32 : 16; + u32 tto; + u32 : 32; + u32 ctnid[3]; + u32 : 32; + u32 todoff[4]; + u32 rsvd[48]; +} __packed; + +struct stp_tzib { + u32 tzan : 16; + u32 : 16; + u32 tzo : 16; + u32 dsto : 16; + u32 stn; + u32 dstn; + u64 dst_on_alg; + u64 dst_off_alg; +} __packed; + +struct stp_tcpib { + u32 atcode : 4; + u32 ntcode : 4; + u32 d : 1; + u32 : 23; + s32 tto; + struct stp_tzib atzib; + struct stp_tzib ntzib; + s32 adst_offset : 16; + s32 ndst_offset : 16; + u32 rsvd1; + u64 ntzib_update; + u64 ndsto_update; +} __packed; + +struct stp_lsoib { + u32 p : 1; + u32 : 31; + s32 also : 16; + s32 nlso : 16; + u64 nlsout; +} __packed; + +struct stp_stzi { + u32 rsvd0[3]; + u64 data_ts; + u32 rsvd1[22]; + struct stp_tcpib tcpib; + struct stp_lsoib lsoib; +} __packed; /* Functions needed by the machine check handler */ int stp_sync_check(void); diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h index acce6a08a1fa..6448bb5be10c 100644 --- a/arch/s390/include/asm/tlbflush.h +++ b/arch/s390/include/asm/tlbflush.h @@ -30,8 +30,6 @@ static inline void __tlb_flush_idte(unsigned long asce) : : "a" (opt), "a" (asce) : "cc"); } -void smp_ptlb_all(void); - /* * Flush all TLB entries on all CPUs. */ diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index f09444d6aeab..c868e7ee49b3 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h @@ -60,6 +60,9 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n); #define INLINE_COPY_TO_USER #endif +int __put_user_bad(void) __attribute__((noreturn)); +int __get_user_bad(void) __attribute__((noreturn)); + #ifdef CONFIG_HAVE_MARCH_Z10_FEATURES #define __put_get_user_asm(to, from, size, spec) \ @@ -109,6 +112,9 @@ static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned lon (unsigned long *)x, size, spec); break; + default: + __put_user_bad(); + break; } return rc; } @@ -139,6 +145,9 @@ static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsign (unsigned long __user *)ptr, size, spec); break; + default: + __get_user_bad(); + break; } return rc; } @@ -179,7 +188,7 @@ static inline int __get_user_fn(void *x, const void __user *ptr, unsigned long s default: \ __put_user_bad(); \ break; \ - } \ + } \ __builtin_expect(__pu_err, 0); \ }) @@ -190,8 +199,6 @@ static inline int __get_user_fn(void *x, const void __user *ptr, unsigned long s }) -int __put_user_bad(void) __attribute__((noreturn)); - #define __get_user(x, ptr) \ ({ \ int __gu_err = -EFAULT; \ @@ -238,8 +245,6 @@ int __put_user_bad(void) __attribute__((noreturn)); __get_user(x, ptr); \ }) -int __get_user_bad(void) __attribute__((noreturn)); - unsigned long __must_check raw_copy_in_user(void __user *to, const void __user *from, unsigned long n); @@ -278,4 +283,115 @@ static inline unsigned long __must_check clear_user(void __user *to, unsigned lo int copy_to_user_real(void __user *dest, void *src, unsigned long count); void *s390_kernel_write(void *dst, const void *src, size_t size); +#define HAVE_GET_KERNEL_NOFAULT + +int __noreturn __put_kernel_bad(void); + +#define __put_kernel_asm(val, to, insn) \ +({ \ + int __rc; \ + \ + asm volatile( \ + "0: " insn " %2,%1\n" \ + "1: xr %0,%0\n" \ + "2:\n" \ + ".pushsection .fixup, \"ax\"\n" \ + "3: lhi %0,%3\n" \ + " jg 2b\n" \ + ".popsection\n" \ + EX_TABLE(0b,3b) EX_TABLE(1b,3b) \ + : "=d" (__rc), "+Q" (*(to)) \ + : "d" (val), "K" (-EFAULT) \ + : "cc"); \ + __rc; \ +}) + +#define __put_kernel_nofault(dst, src, type, err_label) \ +do { \ + u64 __x = (u64)(*((type *)(src))); \ + int __pk_err; \ + \ + switch (sizeof(type)) { \ + case 1: \ + __pk_err = __put_kernel_asm(__x, (type *)(dst), "stc"); \ + break; \ + case 2: \ + __pk_err = __put_kernel_asm(__x, (type *)(dst), "sth"); \ + break; \ + case 4: \ + __pk_err = __put_kernel_asm(__x, (type *)(dst), "st"); \ + break; \ + case 8: \ + __pk_err = __put_kernel_asm(__x, (type *)(dst), "stg"); \ + break; \ + default: \ + __pk_err = __put_kernel_bad(); \ + break; \ + } \ + if (unlikely(__pk_err)) \ + goto err_label; \ +} while (0) + +int __noreturn __get_kernel_bad(void); + +#define __get_kernel_asm(val, from, insn) \ +({ \ + int __rc; \ + \ + asm volatile( \ + "0: " insn " %1,%2\n" \ + "1: xr %0,%0\n" \ + "2:\n" \ + ".pushsection .fixup, \"ax\"\n" \ + "3: lhi %0,%3\n" \ + " jg 2b\n" \ + ".popsection\n" \ + EX_TABLE(0b,3b) EX_TABLE(1b,3b) \ + : "=d" (__rc), "+d" (val) \ + : "Q" (*(from)), "K" (-EFAULT) \ + : "cc"); \ + __rc; \ +}) + +#define __get_kernel_nofault(dst, src, type, err_label) \ +do { \ + int __gk_err; \ + \ + switch (sizeof(type)) { \ + case 1: { \ + u8 __x = 0; \ + \ + __gk_err = __get_kernel_asm(__x, (type *)(src), "ic"); \ + *((type *)(dst)) = (type)__x; \ + break; \ + }; \ + case 2: { \ + u16 __x = 0; \ + \ + __gk_err = __get_kernel_asm(__x, (type *)(src), "lh"); \ + *((type *)(dst)) = (type)__x; \ + break; \ + }; \ + case 4: { \ + u32 __x = 0; \ + \ + __gk_err = __get_kernel_asm(__x, (type *)(src), "l"); \ + *((type *)(dst)) = (type)__x; \ + break; \ + }; \ + case 8: { \ + u64 __x = 0; \ + \ + __gk_err = __get_kernel_asm(__x, (type *)(src), "lg"); \ + *((type *)(dst)) = (type)__x; \ + break; \ + }; \ + default: \ + __gk_err = __get_kernel_bad(); \ + break; \ + } \ + if (unlikely(__gk_err)) \ + goto err_label; \ +} while (0) + #endif /* __S390_UACCESS_H */ diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h index cff4b4c99b75..0325fc0469b7 100644 --- a/arch/s390/include/asm/uv.h +++ b/arch/s390/include/asm/uv.h @@ -33,6 +33,7 @@ #define UVC_CMD_DESTROY_SEC_CPU 0x0121 #define UVC_CMD_CONV_TO_SEC_STOR 0x0200 #define UVC_CMD_CONV_FROM_SEC_STOR 0x0201 +#define UVC_CMD_DESTR_SEC_STOR 0x0202 #define UVC_CMD_SET_SEC_CONF_PARAMS 0x0300 #define UVC_CMD_UNPACK_IMG 0x0301 #define UVC_CMD_VERIFY_IMG 0x0302 @@ -344,6 +345,7 @@ static inline int is_prot_virt_host(void) } int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb); +int uv_destroy_page(unsigned long paddr); int uv_convert_from_secure(unsigned long paddr); int gmap_convert_to_secure(struct gmap *gmap, unsigned long gaddr); @@ -354,6 +356,11 @@ void adjust_to_uv_max(unsigned long *vmax); static inline void setup_uv(void) {} static inline void adjust_to_uv_max(unsigned long *vmax) {} +static inline int uv_destroy_page(unsigned long paddr) +{ + return 0; +} + static inline int uv_convert_from_secure(unsigned long paddr) { return 0; diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h index 0cd085cdeb4f..29b44a930e71 100644 --- a/arch/s390/include/asm/vdso.h +++ b/arch/s390/include/asm/vdso.h @@ -2,6 +2,8 @@ #ifndef __S390_VDSO_H__ #define __S390_VDSO_H__ +#include <vdso/datapage.h> + /* Default link addresses for the vDSOs */ #define VDSO32_LBASE 0 #define VDSO64_LBASE 0 @@ -18,30 +20,7 @@ * itself and may change without notice. */ -struct vdso_data { - __u64 tb_update_count; /* Timebase atomicity ctr 0x00 */ - __u64 xtime_tod_stamp; /* TOD clock for xtime 0x08 */ - __u64 xtime_clock_sec; /* Kernel time 0x10 */ - __u64 xtime_clock_nsec; /* 0x18 */ - __u64 xtime_coarse_sec; /* Coarse kernel time 0x20 */ - __u64 xtime_coarse_nsec; /* 0x28 */ - __u64 wtom_clock_sec; /* Wall to monotonic clock 0x30 */ - __u64 wtom_clock_nsec; /* 0x38 */ - __u64 wtom_coarse_sec; /* Coarse wall to monotonic 0x40 */ - __u64 wtom_coarse_nsec; /* 0x48 */ - __u32 tz_minuteswest; /* Minutes west of Greenwich 0x50 */ - __u32 tz_dsttime; /* Type of dst correction 0x54 */ - __u32 ectg_available; /* ECTG instruction present 0x58 */ - __u32 tk_mult; /* Mult. used for xtime_nsec 0x5c */ - __u32 tk_shift; /* Shift used for xtime_nsec 0x60 */ - __u32 ts_dir; /* TOD steering direction 0x64 */ - __u64 ts_end; /* TOD steering end 0x68 */ - __u32 hrtimer_res; /* hrtimer resolution 0x70 */ -}; - struct vdso_per_cpu_data { - __u64 ectg_timer_base; - __u64 ectg_user_time; /* * Note: node_id and cpu_nr must be at adjacent memory locations. * VDSO userspace must read both values with a single instruction. @@ -56,9 +35,7 @@ struct vdso_per_cpu_data { }; extern struct vdso_data *vdso_data; -extern struct vdso_data boot_vdso_data; -void vdso_alloc_boot_cpu(struct lowcore *lowcore); int vdso_alloc_per_cpu(struct lowcore *lowcore); void vdso_free_per_cpu(struct lowcore *lowcore); diff --git a/arch/s390/include/asm/vdso/clocksource.h b/arch/s390/include/asm/vdso/clocksource.h new file mode 100644 index 000000000000..a93eda0ce7bb --- /dev/null +++ b/arch/s390/include/asm/vdso/clocksource.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_VDSO_CLOCKSOURCE_H +#define __ASM_VDSO_CLOCKSOURCE_H + +#define VDSO_ARCH_CLOCKMODES \ + VDSO_CLOCKMODE_TOD + +#endif /* __ASM_VDSO_CLOCKSOURCE_H */ diff --git a/arch/s390/include/asm/vdso/data.h b/arch/s390/include/asm/vdso/data.h new file mode 100644 index 000000000000..7b3cdb4a5f48 --- /dev/null +++ b/arch/s390/include/asm/vdso/data.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __S390_ASM_VDSO_DATA_H +#define __S390_ASM_VDSO_DATA_H + +#include <linux/types.h> +#include <vdso/datapage.h> + +struct arch_vdso_data { + __u64 tod_steering_delta; + __u64 tod_steering_end; +}; + +#endif /* __S390_ASM_VDSO_DATA_H */ diff --git a/arch/s390/include/asm/vdso/gettimeofday.h b/arch/s390/include/asm/vdso/gettimeofday.h new file mode 100644 index 000000000000..bf123065ad3b --- /dev/null +++ b/arch/s390/include/asm/vdso/gettimeofday.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef ASM_VDSO_GETTIMEOFDAY_H +#define ASM_VDSO_GETTIMEOFDAY_H + +#define VDSO_HAS_TIME 1 + +#define VDSO_HAS_CLOCK_GETRES 1 + +#include <asm/timex.h> +#include <asm/unistd.h> +#include <asm/vdso.h> +#include <linux/compiler.h> + +#define vdso_calc_delta __arch_vdso_calc_delta +static __always_inline u64 __arch_vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 mult) +{ + return (cycles - last) * mult; +} + +static __always_inline const struct vdso_data *__arch_get_vdso_data(void) +{ + return _vdso_data; +} + +static inline u64 __arch_get_hw_counter(s32 clock_mode, const struct vdso_data *vd) +{ + const struct vdso_data *vdso = __arch_get_vdso_data(); + u64 adj, now; + + now = get_tod_clock(); + adj = vdso->arch_data.tod_steering_end - now; + if (unlikely((s64) adj > 0)) + now += (vdso->arch_data.tod_steering_delta < 0) ? (adj >> 15) : -(adj >> 15); + return now; +} + +static __always_inline +long clock_gettime_fallback(clockid_t clkid, struct __kernel_timespec *ts) +{ + register unsigned long r1 __asm__("r1") = __NR_clock_gettime; + register unsigned long r2 __asm__("r2") = (unsigned long)clkid; + register void *r3 __asm__("r3") = ts; + + asm ("svc 0\n" : "+d" (r2) : "d" (r1), "d" (r3) : "cc", "memory"); + return r2; +} + +static __always_inline +long gettimeofday_fallback(register struct __kernel_old_timeval *tv, + register struct timezone *tz) +{ + register unsigned long r1 __asm__("r1") = __NR_gettimeofday; + register unsigned long r2 __asm__("r2") = (unsigned long)tv; + register void *r3 __asm__("r3") = tz; + + asm ("svc 0\n" : "+d" (r2) : "d" (r1), "d" (r3) : "cc", "memory"); + return r2; +} + +static __always_inline +long clock_getres_fallback(clockid_t clkid, struct __kernel_timespec *ts) +{ + register unsigned long r1 __asm__("r1") = __NR_clock_getres; + register unsigned long r2 __asm__("r2") = (unsigned long)clkid; + register void *r3 __asm__("r3") = ts; + + asm ("svc 0\n" : "+d" (r2) : "d" (r1), "d" (r3) : "cc", "memory"); + return r2; +} + +#endif diff --git a/arch/s390/include/asm/vdso/processor.h b/arch/s390/include/asm/vdso/processor.h new file mode 100644 index 000000000000..cfcc3e117c4c --- /dev/null +++ b/arch/s390/include/asm/vdso/processor.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ASM_VDSO_PROCESSOR_H +#define __ASM_VDSO_PROCESSOR_H + +#define cpu_relax() barrier() + +#endif /* __ASM_VDSO_PROCESSOR_H */ diff --git a/arch/s390/include/asm/vdso/vdso.h b/arch/s390/include/asm/vdso/vdso.h new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/arch/s390/include/asm/vdso/vdso.h diff --git a/arch/s390/include/asm/vdso/vsyscall.h b/arch/s390/include/asm/vdso/vsyscall.h new file mode 100644 index 000000000000..6c67c08cefdd --- /dev/null +++ b/arch/s390/include/asm/vdso/vsyscall.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_VDSO_VSYSCALL_H +#define __ASM_VDSO_VSYSCALL_H + +#ifndef __ASSEMBLY__ + +#include <linux/hrtimer.h> +#include <linux/timekeeper_internal.h> +#include <vdso/datapage.h> +#include <asm/vdso.h> +/* + * Update the vDSO data page to keep in sync with kernel timekeeping. + */ + +static __always_inline struct vdso_data *__s390_get_k_vdso_data(void) +{ + return vdso_data; +} +#define __arch_get_k_vdso_data __s390_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_VDSO_VSYSCALL_H */ diff --git a/arch/s390/include/asm/vtimer.h b/arch/s390/include/asm/vtimer.h index 42f707d1c1e8..e601adaa6320 100644 --- a/arch/s390/include/asm/vtimer.h +++ b/arch/s390/include/asm/vtimer.h @@ -25,8 +25,6 @@ extern void add_virt_timer_periodic(struct vtimer_list *timer); extern int mod_virt_timer(struct vtimer_list *timer, u64 expires); extern int mod_virt_timer_periodic(struct vtimer_list *timer, u64 expires); extern int del_virt_timer(struct vtimer_list *timer); - -extern void init_cpu_vtimer(void); extern void vtime_init(void); #endif /* _ASM_S390_TIMER_H */ diff --git a/arch/s390/include/uapi/asm/pkey.h b/arch/s390/include/uapi/asm/pkey.h index d27d7d329263..7349e96d28a0 100644 --- a/arch/s390/include/uapi/asm/pkey.h +++ b/arch/s390/include/uapi/asm/pkey.h @@ -35,12 +35,16 @@ #define PKEY_KEYTYPE_AES_128 1 #define PKEY_KEYTYPE_AES_192 2 #define PKEY_KEYTYPE_AES_256 3 +#define PKEY_KEYTYPE_ECC 4 /* the newer ioctls use a pkey_key_type enum for type information */ enum pkey_key_type { PKEY_TYPE_CCA_DATA = (__u32) 1, PKEY_TYPE_CCA_CIPHER = (__u32) 2, PKEY_TYPE_EP11 = (__u32) 3, + PKEY_TYPE_CCA_ECC = (__u32) 0x1f, + PKEY_TYPE_EP11_AES = (__u32) 6, + PKEY_TYPE_EP11_ECC = (__u32) 7, }; /* the newer ioctls use a pkey_key_size enum for key size information */ @@ -89,6 +93,20 @@ struct pkey_clrkey { }; /* + * EP11 key blobs of type PKEY_TYPE_EP11_AES and PKEY_TYPE_EP11_ECC + * are ep11 blobs prepended by this header: + */ +struct ep11kblob_header { + __u8 type; /* always 0x00 */ + __u8 hver; /* header version, currently needs to be 0x00 */ + __u16 len; /* total length in bytes (including this header) */ + __u8 version; /* PKEY_TYPE_EP11_AES or PKEY_TYPE_EP11_ECC */ + __u8 res0; /* unused */ + __u16 bitlen; /* clear key bit len, 0 for unknown */ + __u8 res1[8]; /* unused */ +} __packed; + +/* * Generate CCA AES secure key. */ struct pkey_genseck { @@ -304,7 +322,7 @@ struct pkey_verifykey2 { #define PKEY_VERIFYKEY2 _IOWR(PKEY_IOCTL_MAGIC, 0x17, struct pkey_verifykey2) /* - * Transform a key blob (of any type) into a protected key, version 2. + * Transform a key blob into a protected key, version 2. * There needs to be a list of apqns given with at least one entry in there. * All apqns in the list need to be exact apqns, 0xFFFF as ANY card or domain * is not supported. The implementation walks through the list of apqns and @@ -313,6 +331,8 @@ struct pkey_verifykey2 { * list is tried until success (return 0) or the end of the list is reached * (return -1 with errno ENODEV). You may use the PKEY_APQNS4K ioctl to * generate a list of apqns based on the key. + * Deriving ECC protected keys from ECC secure keys is not supported with + * this ioctl, use PKEY_KBLOB2PROTK3 for this purpose. */ struct pkey_kblob2pkey2 { __u8 __user *key; /* in: pointer to key blob */ @@ -326,17 +346,17 @@ struct pkey_kblob2pkey2 { /* * Build a list of APQNs based on a key blob given. * Is able to find out which type of secure key is given (CCA AES secure - * key, CCA AES cipher key or EP11 AES key) and tries to find all matching - * crypto cards based on the MKVP and maybe other criterias (like CCA AES - * cipher keys need a CEX5C or higher, EP11 keys with BLOB_PKEY_EXTRACTABLE - * need a CEX7 and EP11 api version 4). The list of APQNs is further filtered - * by the key's mkvp which needs to match to either the current mkvp (CCA and - * EP11) or the alternate mkvp (old mkvp, CCA adapters only) of the apqns. The - * flags argument may be used to limit the matching apqns. If the - * PKEY_FLAGS_MATCH_CUR_MKVP is given, only the current mkvp of each apqn is - * compared. Likewise with the PKEY_FLAGS_MATCH_ALT_MKVP. If both are given, it - * is assumed to return apqns where either the current or the alternate mkvp - * matches. At least one of the matching flags needs to be given. + * key, CCA AES cipher key, CCA ECC private key, EP11 AES key, EP11 ECC private + * key) and tries to find all matching crypto cards based on the MKVP and maybe + * other criterias (like CCA AES cipher keys need a CEX5C or higher, EP11 keys + * with BLOB_PKEY_EXTRACTABLE need a CEX7 and EP11 api version 4). The list of + * APQNs is further filtered by the key's mkvp which needs to match to either + * the current mkvp (CCA and EP11) or the alternate mkvp (old mkvp, CCA adapters + * only) of the apqns. The flags argument may be used to limit the matching + * apqns. If the PKEY_FLAGS_MATCH_CUR_MKVP is given, only the current mkvp of + * each apqn is compared. Likewise with the PKEY_FLAGS_MATCH_ALT_MKVP. If both + * are given, it is assumed to return apqns where either the current or the + * alternate mkvp matches. At least one of the matching flags needs to be given. * The flags argument for EP11 keys has no further action and is currently * ignored (but needs to be given as PKEY_FLAGS_MATCH_CUR_MKVP) as there is only * the wkvp from the key to match against the apqn's wkvp. @@ -365,9 +385,10 @@ struct pkey_apqns4key { * restrict the list by given master key verification patterns. * For different key types there may be different ways to match the * master key verification patterns. For CCA keys (CCA data key and CCA - * cipher key) the first 8 bytes of cur_mkvp refer to the current mkvp value - * of the apqn and the first 8 bytes of the alt_mkvp refer to the old mkvp. - * The flags argument controls if the apqns current and/or alternate mkvp + * cipher key) the first 8 bytes of cur_mkvp refer to the current AES mkvp value + * of the apqn and the first 8 bytes of the alt_mkvp refer to the old AES mkvp. + * For CCA ECC keys it is similar but the match is against the APKA current/old + * mkvp. The flags argument controls if the apqns current and/or alternate mkvp * should match. If the PKEY_FLAGS_MATCH_CUR_MKVP is given, only the current * mkvp of each apqn is compared. Likewise with the PKEY_FLAGS_MATCH_ALT_MKVP. * If both are given, it is assumed to return apqns where either the @@ -397,4 +418,30 @@ struct pkey_apqns4keytype { }; #define PKEY_APQNS4KT _IOWR(PKEY_IOCTL_MAGIC, 0x1C, struct pkey_apqns4keytype) +/* + * Transform a key blob into a protected key, version 3. + * The difference to version 2 of this ioctl is that the protected key + * buffer is now explicitly and not within a struct pkey_protkey any more. + * So this ioctl is also able to handle EP11 and CCA ECC secure keys and + * provide ECC protected keys. + * There needs to be a list of apqns given with at least one entry in there. + * All apqns in the list need to be exact apqns, 0xFFFF as ANY card or domain + * is not supported. The implementation walks through the list of apqns and + * tries to send the request to each apqn without any further checking (like + * card type or online state). If the apqn fails, simple the next one in the + * list is tried until success (return 0) or the end of the list is reached + * (return -1 with errno ENODEV). You may use the PKEY_APQNS4K ioctl to + * generate a list of apqns based on the key. + */ +struct pkey_kblob2pkey3 { + __u8 __user *key; /* in: pointer to key blob */ + __u32 keylen; /* in: key blob size */ + struct pkey_apqn __user *apqns; /* in: ptr to list of apqn targets */ + __u32 apqn_entries; /* in: # of apqn target list entries */ + __u32 pkeytype; /* out: prot key type (enum pkey_key_type) */ + __u32 pkeylen; /* in/out: size of pkey buffer/actual len of pkey */ + __u8 __user *pkey; /* in: pkey blob buffer space ptr */ +}; +#define PKEY_KBLOB2PROTK3 _IOWR(PKEY_IOCTL_MAGIC, 0x1D, struct pkey_kblob2pkey3) + #endif /* _UAPI_PKEY_H */ diff --git a/arch/s390/include/uapi/asm/sie.h b/arch/s390/include/uapi/asm/sie.h index 6ca1e68d7103..ede318653c87 100644 --- a/arch/s390/include/uapi/asm/sie.h +++ b/arch/s390/include/uapi/asm/sie.h @@ -29,7 +29,7 @@ { 0x13, "SIGP conditional emergency signal" }, \ { 0x15, "SIGP sense running" }, \ { 0x16, "SIGP set multithreading"}, \ - { 0x17, "SIGP store additional status ait address"} + { 0x17, "SIGP store additional status at address"} #define icpt_prog_codes \ { 0x0001, "Prog Operation" }, \ diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index efca70970761..dd73b7f07423 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_COMPAT) += $(compat-obj-y) obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_KPROBES) += kprobes.o +obj-$(CONFIG_KPROBES) += kprobes_insn_page.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_UPROBES) += uprobes.o diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 5d8cc1864566..ece58f2217cb 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -59,26 +59,6 @@ int main(void) OFFSET(__SF_SIE_REASON, stack_frame, empty1[2]); OFFSET(__SF_SIE_FLAGS, stack_frame, empty1[3]); BLANK(); - /* timeval/timezone offsets for use by vdso */ - OFFSET(__VDSO_UPD_COUNT, vdso_data, tb_update_count); - OFFSET(__VDSO_XTIME_STAMP, vdso_data, xtime_tod_stamp); - OFFSET(__VDSO_XTIME_SEC, vdso_data, xtime_clock_sec); - OFFSET(__VDSO_XTIME_NSEC, vdso_data, xtime_clock_nsec); - OFFSET(__VDSO_XTIME_CRS_SEC, vdso_data, xtime_coarse_sec); - OFFSET(__VDSO_XTIME_CRS_NSEC, vdso_data, xtime_coarse_nsec); - OFFSET(__VDSO_WTOM_SEC, vdso_data, wtom_clock_sec); - OFFSET(__VDSO_WTOM_NSEC, vdso_data, wtom_clock_nsec); - OFFSET(__VDSO_WTOM_CRS_SEC, vdso_data, wtom_coarse_sec); - OFFSET(__VDSO_WTOM_CRS_NSEC, vdso_data, wtom_coarse_nsec); - OFFSET(__VDSO_TIMEZONE, vdso_data, tz_minuteswest); - OFFSET(__VDSO_ECTG_OK, vdso_data, ectg_available); - OFFSET(__VDSO_TK_MULT, vdso_data, tk_mult); - OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift); - OFFSET(__VDSO_TS_DIR, vdso_data, ts_dir); - OFFSET(__VDSO_TS_END, vdso_data, ts_end); - OFFSET(__VDSO_CLOCK_REALTIME_RES, vdso_data, hrtimer_res); - OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base); - OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time); OFFSET(__VDSO_GETCPU_VAL, vdso_per_cpu_data, getcpu_val); BLANK(); /* constants used by the vdso */ diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index c42ce348103c..205b2e2648aa 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -141,7 +141,7 @@ int copy_oldmem_kernel(void *dst, void *src, size_t count) while (count) { from = __pa(src); if (!OLDMEM_BASE && from < sclp.hsa_size) { - /* Copy from zfcpdump HSA area */ + /* Copy from zfcp/nvme dump HSA area */ len = min(count, sclp.hsa_size - from); rc = memcpy_hsa_kernel(dst, from, len); if (rc) @@ -184,7 +184,7 @@ static int copy_oldmem_user(void __user *dst, void *src, size_t count) while (count) { from = __pa(src); if (!OLDMEM_BASE && from < sclp.hsa_size) { - /* Copy from zfcpdump HSA area */ + /* Copy from zfcp/nvme dump HSA area */ len = min(count, sclp.hsa_size - from); rc = memcpy_hsa_user(dst, from, len); if (rc) @@ -258,7 +258,7 @@ static int remap_oldmem_pfn_range_kdump(struct vm_area_struct *vma, } /* - * Remap "oldmem" for zfcpdump + * Remap "oldmem" for zfcp/nvme dump * * We only map available memory above HSA size. Memory below HSA size * is read on demand using the copy_oldmem_page() function. @@ -283,7 +283,7 @@ static int remap_oldmem_pfn_range_zfcpdump(struct vm_area_struct *vma, } /* - * Remap "oldmem" for kdump or zfcpdump + * Remap "oldmem" for kdump or zfcp/nvme dump */ int remap_oldmem_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot) @@ -632,11 +632,11 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size) u32 alloc_size; u64 hdr_off; - /* If we are not in kdump or zfcpdump mode return */ - if (!OLDMEM_BASE && ipl_info.type != IPL_TYPE_FCP_DUMP) + /* If we are not in kdump or zfcp/nvme dump mode return */ + if (!OLDMEM_BASE && !is_ipl_type_dump()) return 0; - /* If we cannot get HSA size for zfcpdump return error */ - if (ipl_info.type == IPL_TYPE_FCP_DUMP && !sclp.hsa_size) + /* If we cannot get HSA size for zfcp/nvme dump return error */ + if (is_ipl_type_dump() && !sclp.hsa_size) return -ENODEV; /* For kdump, exclude previous crashkernel memory */ diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c index ccba63aaeb47..b8b0cd7b008f 100644 --- a/arch/s390/kernel/diag.c +++ b/arch/s390/kernel/diag.c @@ -104,18 +104,7 @@ static const struct seq_operations show_diag_stat_sops = { .show = show_diag_stat, }; -static int show_diag_stat_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &show_diag_stat_sops); -} - -static const struct file_operations show_diag_stat_fops = { - .open = show_diag_stat_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - +DEFINE_SEQ_ATTRIBUTE(show_diag_stat); static int __init show_diag_stat_init(void) { diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index f304802ecf7b..a7eab7be4db0 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c @@ -482,31 +482,37 @@ static int print_insn(char *buffer, unsigned char *code, unsigned long addr) return (int) (ptr - buffer); } +static int copy_from_regs(struct pt_regs *regs, void *dst, void *src, int len) +{ + if (user_mode(regs)) { + if (copy_from_user(dst, (char __user *)src, len)) + return -EFAULT; + } else { + if (copy_from_kernel_nofault(dst, src, len)) + return -EFAULT; + } + return 0; +} + void show_code(struct pt_regs *regs) { char *mode = user_mode(regs) ? "User" : "Krnl"; unsigned char code[64]; char buffer[128], *ptr; - mm_segment_t old_fs; unsigned long addr; int start, end, opsize, hops, i; /* Get a snapshot of the 64 bytes surrounding the fault address. */ - old_fs = get_fs(); - set_fs(user_mode(regs) ? USER_DS : KERNEL_DS); for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) { addr = regs->psw.addr - 34 + start; - if (__copy_from_user(code + start - 2, - (char __user *) addr, 2)) + if (copy_from_regs(regs, code + start - 2, (void *)addr, 2)) break; } for (end = 32; end < 64; end += 2) { addr = regs->psw.addr + end - 32; - if (__copy_from_user(code + end, - (char __user *) addr, 2)) + if (copy_from_regs(regs, code + end, (void *)addr, 2)) break; } - set_fs(old_fs); /* Code snapshot useable ? */ if ((regs->psw.addr & 1) || start >= end) { printk("%s Code: Bad PSW.\n", mode); diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 078277231858..705844f73934 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -274,19 +274,6 @@ static int __init disable_vector_extension(char *str) } early_param("novx", disable_vector_extension); -static int __init cad_setup(char *str) -{ - bool enabled; - int rc; - - rc = kstrtobool(str, &enabled); - if (!rc && enabled && test_facility(128)) - /* Enable problem state CAD. */ - __ctl_set_bit(2, 3); - return rc; -} -early_param("cad", cad_setup); - char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; static void __init setup_boot_command_line(void) { diff --git a/arch/s390/kernel/early_printk.c b/arch/s390/kernel/early_printk.c index 6f24d83bc5dc..d9d53f44008a 100644 --- a/arch/s390/kernel/early_printk.c +++ b/arch/s390/kernel/early_printk.c @@ -10,7 +10,7 @@ static void sclp_early_write(struct console *con, const char *s, unsigned int len) { - __sclp_early_printk(s, len, 0); + __sclp_early_printk(s, len); } static struct console sclp_early_console = { diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 23edf196d3dc..86235919c2d1 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -435,10 +435,8 @@ ENTRY(system_call) jz .Lsysc_skip_fpu brasl %r14,load_fpu_regs .Lsysc_skip_fpu: - lg %r14,__LC_VDSO_PER_CPU mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) stpt __LC_EXIT_TIMER - mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER lmg %r0,%r15,__PT_R0(%r11) b __LC_RETURN_LPSWE @@ -797,13 +795,11 @@ ENTRY(io_int_handler) TRACE_IRQS_ON 0: #endif - lg %r14,__LC_VDSO_PER_CPU mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) tm __PT_PSW+1(%r11),0x01 # returning to user ? jno .Lio_exit_kernel BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP stpt __LC_EXIT_TIMER - mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER .Lio_exit_kernel: lmg %r0,%r15,__PT_R0(%r11) b __LC_RETURN_LPSWE @@ -1213,14 +1209,12 @@ ENTRY(mcck_int_handler) brasl %r14,s390_handle_mcck TRACE_IRQS_ON .Lmcck_return: - lg %r14,__LC_VDSO_PER_CPU lmg %r0,%r10,__PT_R0(%r11) mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? jno 0f BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP stpt __LC_EXIT_TIMER - mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 0: lmg %r11,%r15,__PT_R11(%r11) b __LC_RETURN_MCCK_LPSWE diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index faca269d5f27..d2ca3fe51f8e 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -9,7 +9,6 @@ #include <asm/idle.h> extern void *restart_stack; -extern unsigned long suspend_zero_pages; void system_call(void); void pgm_check_handler(void); @@ -17,7 +16,6 @@ void ext_int_handler(void); void io_int_handler(void); void mcck_int_handler(void); void restart_int_handler(void); -void restart_call_handler(void); asmlinkage long do_syscall_trace_enter(struct pt_regs *regs); asmlinkage void do_syscall_trace_exit(struct pt_regs *regs); @@ -26,6 +24,7 @@ void do_protection_exception(struct pt_regs *regs); void do_dat_exception(struct pt_regs *regs); void do_secure_storage_access(struct pt_regs *regs); void do_non_secure_storage_access(struct pt_regs *regs); +void do_secure_storage_violation(struct pt_regs *regs); void addressing_exception(struct pt_regs *regs); void data_exception(struct pt_regs *regs); @@ -61,12 +60,10 @@ void do_notify_resume(struct pt_regs *regs); void __init init_IRQ(void); void do_IRQ(struct pt_regs *regs, int irq); void do_restart(void); -void __init startup_init_nobss(void); void __init startup_init(void); void die(struct pt_regs *regs, const char *str); int setup_profiling_timer(unsigned int multiplier); void __init time_init(void); -void s390_early_resume(void); unsigned long prepare_ftrace_return(unsigned long parent, unsigned long sp, unsigned long ip); struct s390_mmap_arg_struct; @@ -91,4 +88,6 @@ void set_fs_fixup(void); unsigned long stack_alloc(void); void stack_free(unsigned long stack); +extern char kprobes_insn_page[]; + #endif /* _ENTRY_H */ diff --git a/arch/s390/kernel/idle.c b/arch/s390/kernel/idle.c index c73f50649e7e..f7f1e64e0d98 100644 --- a/arch/s390/kernel/idle.c +++ b/arch/s390/kernel/idle.c @@ -39,14 +39,13 @@ void enabled_wait(void) local_irq_restore(flags); /* Account time spent with enabled wait psw loaded as idle time. */ - /* XXX seqcount has tracepoints that require RCU */ - write_seqcount_begin(&idle->seqcount); + raw_write_seqcount_begin(&idle->seqcount); idle_time = idle->clock_idle_exit - idle->clock_idle_enter; idle->clock_idle_enter = idle->clock_idle_exit = 0ULL; idle->idle_time += idle_time; idle->idle_count++; account_idle_time(cputime_to_nsecs(idle_time)); - write_seqcount_end(&idle->seqcount); + raw_write_seqcount_end(&idle->seqcount); } NOKPROBE_SYMBOL(enabled_wait); diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 90a2a17239b0..98b3aca1de8e 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -40,10 +40,12 @@ #define IPL_FCP_STR "fcp" #define IPL_FCP_DUMP_STR "fcp_dump" #define IPL_NVME_STR "nvme" +#define IPL_NVME_DUMP_STR "nvme_dump" #define IPL_NSS_STR "nss" #define DUMP_CCW_STR "ccw" #define DUMP_FCP_STR "fcp" +#define DUMP_NVME_STR "nvme" #define DUMP_NONE_STR "none" /* @@ -96,6 +98,8 @@ static char *ipl_type_str(enum ipl_type type) return IPL_NSS_STR; case IPL_TYPE_NVME: return IPL_NVME_STR; + case IPL_TYPE_NVME_DUMP: + return IPL_NVME_DUMP_STR; case IPL_TYPE_UNKNOWN: default: return IPL_UNKNOWN_STR; @@ -106,6 +110,7 @@ enum dump_type { DUMP_TYPE_NONE = 1, DUMP_TYPE_CCW = 2, DUMP_TYPE_FCP = 4, + DUMP_TYPE_NVME = 8, }; static char *dump_type_str(enum dump_type type) @@ -117,6 +122,8 @@ static char *dump_type_str(enum dump_type type) return DUMP_CCW_STR; case DUMP_TYPE_FCP: return DUMP_FCP_STR; + case DUMP_TYPE_NVME: + return DUMP_NVME_STR; default: return NULL; } @@ -144,10 +151,12 @@ static struct ipl_parameter_block *reipl_block_actual; static int dump_capabilities = DUMP_TYPE_NONE; static enum dump_type dump_type = DUMP_TYPE_NONE; static struct ipl_parameter_block *dump_block_fcp; +static struct ipl_parameter_block *dump_block_nvme; static struct ipl_parameter_block *dump_block_ccw; static struct sclp_ipl_info sclp_ipl_info; +static bool reipl_nvme_clear; static bool reipl_fcp_clear; static bool reipl_ccw_clear; @@ -266,7 +275,10 @@ static __init enum ipl_type get_ipl_type(void) else return IPL_TYPE_FCP; case IPL_PBT_NVME: - return IPL_TYPE_NVME; + if (ipl_block.nvme.opt == IPL_PB0_NVME_OPT_DUMP) + return IPL_TYPE_NVME_DUMP; + else + return IPL_TYPE_NVME; } return IPL_TYPE_UNKNOWN; } @@ -324,6 +336,7 @@ static ssize_t sys_ipl_device_show(struct kobject *kobj, case IPL_TYPE_FCP_DUMP: return sprintf(page, "0.0.%04x\n", ipl_block.fcp.devno); case IPL_TYPE_NVME: + case IPL_TYPE_NVME_DUMP: return sprintf(page, "%08ux\n", ipl_block.nvme.fid); default: return 0; @@ -531,6 +544,7 @@ static int __init ipl_init(void) rc = sysfs_create_group(&ipl_kset->kobj, &ipl_fcp_attr_group); break; case IPL_TYPE_NVME: + case IPL_TYPE_NVME_DUMP: rc = sysfs_create_group(&ipl_kset->kobj, &ipl_nvme_attr_group); break; default: @@ -873,6 +887,24 @@ static struct attribute_group reipl_nvme_attr_group = { .bin_attrs = reipl_nvme_bin_attrs }; +static ssize_t reipl_nvme_clear_show(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + return sprintf(page, "%u\n", reipl_nvme_clear); +} + +static ssize_t reipl_nvme_clear_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t len) +{ + if (strtobool(buf, &reipl_nvme_clear) < 0) + return -EINVAL; + return len; +} + +static struct kobj_attribute sys_reipl_nvme_clear_attr = + __ATTR(clear, 0644, reipl_nvme_clear_show, reipl_nvme_clear_store); + /* CCW reipl device attributes */ DEFINE_IPL_CCW_ATTR_RW(reipl_ccw, device, reipl_block_ccw->ccw); @@ -1099,7 +1131,10 @@ static void __reipl_run(void *unused) break; case IPL_TYPE_NVME: diag308(DIAG308_SET, reipl_block_nvme); - diag308(DIAG308_LOAD_CLEAR, NULL); + if (reipl_nvme_clear) + diag308(DIAG308_LOAD_CLEAR, NULL); + else + diag308(DIAG308_LOAD_NORMAL, NULL); break; case IPL_TYPE_NSS: diag308(DIAG308_SET, reipl_block_nss); @@ -1109,6 +1144,7 @@ static void __reipl_run(void *unused) diag308(DIAG308_LOAD_CLEAR, NULL); break; case IPL_TYPE_FCP_DUMP: + case IPL_TYPE_NVME_DUMP: break; } disabled_wait(); @@ -1219,8 +1255,9 @@ static int __init reipl_fcp_init(void) &sys_reipl_fcp_clear_attr.attr); if (rc) goto out2; - } else + } else { reipl_fcp_clear = true; + } if (ipl_info.type == IPL_TYPE_FCP) { memcpy(reipl_block_fcp, &ipl_block, sizeof(ipl_block)); @@ -1266,10 +1303,16 @@ static int __init reipl_nvme_init(void) } rc = sysfs_create_group(&reipl_nvme_kset->kobj, &reipl_nvme_attr_group); - if (rc) { - kset_unregister(reipl_nvme_kset); - free_page((unsigned long) reipl_block_nvme); - return rc; + if (rc) + goto out1; + + if (test_facility(141)) { + rc = sysfs_create_file(&reipl_nvme_kset->kobj, + &sys_reipl_nvme_clear_attr.attr); + if (rc) + goto out2; + } else { + reipl_nvme_clear = true; } if (ipl_info.type == IPL_TYPE_NVME) { @@ -1290,6 +1333,13 @@ static int __init reipl_nvme_init(void) } reipl_capabilities |= IPL_TYPE_NVME; return 0; + +out2: + sysfs_remove_group(&reipl_nvme_kset->kobj, &reipl_nvme_attr_group); +out1: + kset_unregister(reipl_nvme_kset); + free_page((unsigned long) reipl_block_nvme); + return rc; } static int __init reipl_type_init(void) @@ -1382,6 +1432,29 @@ static struct attribute_group dump_fcp_attr_group = { .attrs = dump_fcp_attrs, }; +/* NVME dump device attributes */ +DEFINE_IPL_ATTR_RW(dump_nvme, fid, "0x%08llx\n", "%llx\n", + dump_block_nvme->nvme.fid); +DEFINE_IPL_ATTR_RW(dump_nvme, nsid, "0x%08llx\n", "%llx\n", + dump_block_nvme->nvme.nsid); +DEFINE_IPL_ATTR_RW(dump_nvme, bootprog, "%lld\n", "%llx\n", + dump_block_nvme->nvme.bootprog); +DEFINE_IPL_ATTR_RW(dump_nvme, br_lba, "%lld\n", "%llx\n", + dump_block_nvme->nvme.br_lba); + +static struct attribute *dump_nvme_attrs[] = { + &sys_dump_nvme_fid_attr.attr, + &sys_dump_nvme_nsid_attr.attr, + &sys_dump_nvme_bootprog_attr.attr, + &sys_dump_nvme_br_lba_attr.attr, + NULL, +}; + +static struct attribute_group dump_nvme_attr_group = { + .name = IPL_NVME_STR, + .attrs = dump_nvme_attrs, +}; + /* CCW dump device attributes */ DEFINE_IPL_CCW_ATTR_RW(dump_ccw, device, dump_block_ccw->ccw); @@ -1423,6 +1496,8 @@ static ssize_t dump_type_store(struct kobject *kobj, rc = dump_set_type(DUMP_TYPE_CCW); else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0) rc = dump_set_type(DUMP_TYPE_FCP); + else if (strncmp(buf, DUMP_NVME_STR, strlen(DUMP_NVME_STR)) == 0) + rc = dump_set_type(DUMP_TYPE_NVME); return (rc != 0) ? rc : len; } @@ -1450,6 +1525,9 @@ static void __dump_run(void *unused) case DUMP_TYPE_FCP: diag308_dump(dump_block_fcp); break; + case DUMP_TYPE_NVME: + diag308_dump(dump_block_nvme); + break; default: break; } @@ -1506,6 +1584,29 @@ static int __init dump_fcp_init(void) return 0; } +static int __init dump_nvme_init(void) +{ + int rc; + + if (!sclp_ipl_info.has_dump) + return 0; /* LDIPL DUMP is not installed */ + dump_block_nvme = (void *) get_zeroed_page(GFP_KERNEL); + if (!dump_block_nvme) + return -ENOMEM; + rc = sysfs_create_group(&dump_kset->kobj, &dump_nvme_attr_group); + if (rc) { + free_page((unsigned long)dump_block_nvme); + return rc; + } + dump_block_nvme->hdr.len = IPL_BP_NVME_LEN; + dump_block_nvme->hdr.version = IPL_PARM_BLOCK_VERSION; + dump_block_nvme->fcp.len = IPL_BP0_NVME_LEN; + dump_block_nvme->fcp.pbt = IPL_PBT_NVME; + dump_block_nvme->fcp.opt = IPL_PB0_NVME_OPT_DUMP; + dump_capabilities |= DUMP_TYPE_NVME; + return 0; +} + static int __init dump_init(void) { int rc; @@ -1524,6 +1625,9 @@ static int __init dump_init(void) rc = dump_fcp_init(); if (rc) return rc; + rc = dump_nvme_init(); + if (rc) + return rc; dump_set_type(DUMP_TYPE_NONE); return 0; } @@ -1956,6 +2060,7 @@ void __init setup_ipl(void) ipl_info.data.fcp.lun = ipl_block.fcp.lun; break; case IPL_TYPE_NVME: + case IPL_TYPE_NVME_DUMP: ipl_info.data.nvme.fid = ipl_block.nvme.fid; ipl_info.data.nvme.nsid = ipl_block.nvme.nsid; break; diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index d2a71d872638..aae24dc75df6 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -7,6 +7,7 @@ * s390 port, used ppc64 as template. Mike Grundy <grundym@us.ibm.com> */ +#include <linux/moduleloader.h> #include <linux/kprobes.h> #include <linux/ptrace.h> #include <linux/preempt.h> @@ -21,6 +22,7 @@ #include <asm/set_memory.h> #include <asm/sections.h> #include <asm/dis.h> +#include "entry.h" DEFINE_PER_CPU(struct kprobe *, current_kprobe); DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); @@ -30,19 +32,32 @@ struct kretprobe_blackpoint kretprobe_blacklist[] = { }; DEFINE_INSN_CACHE_OPS(s390_insn); static int insn_page_in_use; -static char insn_page[PAGE_SIZE] __aligned(PAGE_SIZE); + +void *alloc_insn_page(void) +{ + void *page; + + page = module_alloc(PAGE_SIZE); + if (!page) + return NULL; + __set_memory((unsigned long) page, 1, SET_MEMORY_RO | SET_MEMORY_X); + return page; +} + +void free_insn_page(void *page) +{ + module_memfree(page); +} static void *alloc_s390_insn_page(void) { if (xchg(&insn_page_in_use, 1) == 1) return NULL; - set_memory_x((unsigned long) &insn_page, 1); - return &insn_page; + return &kprobes_insn_page; } static void free_s390_insn_page(void *page) { - set_memory_nx((unsigned long) page, 1); xchg(&insn_page_in_use, 0); } @@ -56,25 +71,29 @@ struct kprobe_insn_cache kprobe_s390_insn_slots = { static void copy_instruction(struct kprobe *p) { + kprobe_opcode_t insn[MAX_INSN_SIZE]; s64 disp, new_disp; u64 addr, new_addr; + unsigned int len; - memcpy(p->ainsn.insn, p->addr, insn_length(*p->addr >> 8)); - p->opcode = p->ainsn.insn[0]; - if (!probe_is_insn_relative_long(p->ainsn.insn)) - return; - /* - * For pc-relative instructions in RIL-b or RIL-c format patch the - * RI2 displacement field. We have already made sure that the insn - * slot for the patched instruction is within the same 2GB area - * as the original instruction (either kernel image or module area). - * Therefore the new displacement will always fit. - */ - disp = *(s32 *)&p->ainsn.insn[1]; - addr = (u64)(unsigned long)p->addr; - new_addr = (u64)(unsigned long)p->ainsn.insn; - new_disp = ((addr + (disp * 2)) - new_addr) / 2; - *(s32 *)&p->ainsn.insn[1] = new_disp; + len = insn_length(*p->addr >> 8); + memcpy(&insn, p->addr, len); + p->opcode = insn[0]; + if (probe_is_insn_relative_long(&insn[0])) { + /* + * For pc-relative instructions in RIL-b or RIL-c format patch + * the RI2 displacement field. We have already made sure that + * the insn slot for the patched instruction is within the same + * 2GB area as the original instruction (either kernel image or + * module area). Therefore the new displacement will always fit. + */ + disp = *(s32 *)&insn[1]; + addr = (u64)(unsigned long)p->addr; + new_addr = (u64)(unsigned long)p->ainsn.insn; + new_disp = ((addr + (disp * 2)) - new_addr) / 2; + *(s32 *)&insn[1] = new_disp; + } + s390_kernel_write(p->ainsn.insn, &insn, len); } NOKPROBE_SYMBOL(copy_instruction); @@ -228,6 +247,7 @@ NOKPROBE_SYMBOL(pop_kprobe); void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) { ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14]; + ri->fp = NULL; /* Replace the return addr with trampoline addr */ regs->gprs[14] = (unsigned long) &kretprobe_trampoline; @@ -331,83 +351,7 @@ static void __used kretprobe_trampoline_holder(void) */ static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri; - struct hlist_head *head, empty_rp; - struct hlist_node *tmp; - unsigned long flags, orig_ret_address; - unsigned long trampoline_address; - kprobe_opcode_t *correct_ret_addr; - - INIT_HLIST_HEAD(&empty_rp); - kretprobe_hash_lock(current, &head, &flags); - - /* - * It is possible to have multiple instances associated with a given - * task either because an multiple functions in the call path - * have a return probe installed on them, and/or more than one return - * return probe was registered for a target function. - * - * We can handle this because: - * - instances are always inserted at the head of the list - * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the - * real return address, and all the rest will point to - * kretprobe_trampoline - */ - ri = NULL; - orig_ret_address = 0; - correct_ret_addr = NULL; - trampoline_address = (unsigned long) &kretprobe_trampoline; - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - orig_ret_address = (unsigned long) ri->ret_addr; - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_assert(ri, orig_ret_address, trampoline_address); - - correct_ret_addr = ri->ret_addr; - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - orig_ret_address = (unsigned long) ri->ret_addr; - - if (ri->rp && ri->rp->handler) { - ri->ret_addr = correct_ret_addr; - ri->rp->handler(ri, regs); - } - - recycle_rp_inst(ri, &empty_rp); - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - regs->psw.addr = orig_ret_address; - - kretprobe_hash_unlock(current, &flags); - - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } + regs->psw.addr = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); /* * By returning a non-zero value, we are telling * kprobe_handler() that we don't want the post_handler diff --git a/arch/s390/kernel/kprobes_insn_page.S b/arch/s390/kernel/kprobes_insn_page.S new file mode 100644 index 000000000000..f6cb022ef8c8 --- /dev/null +++ b/arch/s390/kernel/kprobes_insn_page.S @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include <linux/linkage.h> + +/* + * insn_page is a special 4k aligned dummy function for kprobes. + * It will contain all kprobed instructions that are out-of-line executed. + * The page must be within the kernel image to guarantee that the + * out-of-line instructions are within 2GB distance of their original + * location. Using a dummy function ensures that the insn_page is within + * the text section of the kernel and mapped read-only/executable from + * the beginning on, thus avoiding to split large mappings if the page + * would be in the data section instead. + */ + .section .kprobes.text, "ax" + .align 4096 +ENTRY(kprobes_insn_page) + .rept 2048 + .word 0x07fe + .endr +ENDPROC(kprobes_insn_page) + .previous diff --git a/arch/s390/kernel/pgm_check.S b/arch/s390/kernel/pgm_check.S index 2c27907a5ffc..9a92638360ee 100644 --- a/arch/s390/kernel/pgm_check.S +++ b/arch/s390/kernel/pgm_check.S @@ -80,7 +80,7 @@ PGM_CHECK(do_dat_exception) /* 3b */ PGM_CHECK_DEFAULT /* 3c */ PGM_CHECK(do_secure_storage_access) /* 3d */ PGM_CHECK(do_non_secure_storage_access) /* 3e */ -PGM_CHECK_DEFAULT /* 3f */ +PGM_CHECK(do_secure_storage_violation) /* 3f */ PGM_CHECK(monitor_event_exception) /* 40 */ PGM_CHECK_DEFAULT /* 41 */ PGM_CHECK_DEFAULT /* 42 */ diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index e600f6953d7c..4d843e64496f 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -37,7 +37,7 @@ #include <linux/root_dev.h> #include <linux/console.h> #include <linux/kernel_stat.h> -#include <linux/dma-contiguous.h> +#include <linux/dma-map-ops.h> #include <linux/device.h> #include <linux/notifier.h> #include <linux/pfn.h> @@ -102,7 +102,6 @@ struct mem_detect_info __bootdata(mem_detect); struct exception_table_entry *__bootdata_preserved(__start_dma_ex_table); struct exception_table_entry *__bootdata_preserved(__stop_dma_ex_table); -unsigned long __bootdata_preserved(__swsusp_reset_dma); unsigned long __bootdata_preserved(__stext_dma); unsigned long __bootdata_preserved(__etext_dma); unsigned long __bootdata_preserved(__sdma); @@ -119,6 +118,7 @@ EXPORT_SYMBOL(VMALLOC_END); struct page *vmemmap; EXPORT_SYMBOL(vmemmap); +unsigned long vmemmap_size; unsigned long MODULES_VADDR; unsigned long MODULES_END; @@ -128,6 +128,12 @@ struct lowcore *lowcore_ptr[NR_CPUS]; EXPORT_SYMBOL(lowcore_ptr); /* + * The Write Back bit position in the physaddr is given by the SLPC PCI. + * Leaving the mask zero always uses write through which is safe + */ +unsigned long mio_wb_bit_mask __ro_after_init; + +/* * This is set up by the setup-routine at boot-time * for S390 need to find out, what we have to setup * using address 0x10400 ... @@ -245,7 +251,7 @@ static void __init conmode_default(void) #ifdef CONFIG_CRASH_DUMP static void __init setup_zfcpdump(void) { - if (ipl_info.type != IPL_TYPE_FCP_DUMP) + if (!is_ipl_type_dump()) return; if (OLDMEM_BASE) return; @@ -300,7 +306,7 @@ void machine_power_off(void) void (*pm_power_off)(void) = machine_power_off; EXPORT_SYMBOL_GPL(pm_power_off); -void *restart_stack __section(.data); +void *restart_stack; unsigned long stack_alloc(void) { @@ -366,8 +372,12 @@ void __init arch_call_rest_init(void) static void __init setup_lowcore_dat_off(void) { + unsigned long int_psw_mask = PSW_KERNEL_BITS; struct lowcore *lc; + if (IS_ENABLED(CONFIG_KASAN)) + int_psw_mask |= PSW_MASK_DAT; + /* * Setup lowcore for boot cpu */ @@ -379,15 +389,15 @@ static void __init setup_lowcore_dat_off(void) lc->restart_psw.mask = PSW_KERNEL_BITS; lc->restart_psw.addr = (unsigned long) restart_int_handler; - lc->external_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; + lc->external_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK; lc->external_new_psw.addr = (unsigned long) ext_int_handler; - lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; + lc->svc_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK; lc->svc_new_psw.addr = (unsigned long) system_call; - lc->program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; + lc->program_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK; lc->program_new_psw.addr = (unsigned long) pgm_check_handler; lc->mcck_new_psw.mask = PSW_KERNEL_BITS; lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler; - lc->io_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; + lc->io_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK; lc->io_new_psw.addr = (unsigned long) io_int_handler; lc->clock_comparator = clock_comparator_max; lc->nodat_stack = ((unsigned long) &init_thread_union) @@ -402,7 +412,6 @@ static void __init setup_lowcore_dat_off(void) memcpy(lc->alt_stfle_fac_list, S390_lowcore.alt_stfle_fac_list, sizeof(lc->alt_stfle_fac_list)); nmi_alloc_boot_cpu(lc); - vdso_alloc_boot_cpu(lc); lc->sync_enter_timer = S390_lowcore.sync_enter_timer; lc->async_enter_timer = S390_lowcore.async_enter_timer; lc->exit_timer = S390_lowcore.exit_timer; @@ -484,8 +493,9 @@ static struct resource __initdata *standard_resources[] = { static void __init setup_resources(void) { struct resource *res, *std_res, *sub_res; - struct memblock_region *reg; + phys_addr_t start, end; int j; + u64 i; code_resource.start = (unsigned long) _text; code_resource.end = (unsigned long) _etext - 1; @@ -494,7 +504,7 @@ static void __init setup_resources(void) bss_resource.start = (unsigned long) __bss_start; bss_resource.end = (unsigned long) __bss_stop - 1; - for_each_memblock(memory, reg) { + for_each_mem_range(i, &start, &end) { res = memblock_alloc(sizeof(*res), 8); if (!res) panic("%s: Failed to allocate %zu bytes align=0x%x\n", @@ -502,8 +512,13 @@ static void __init setup_resources(void) res->flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM; res->name = "System RAM"; - res->start = reg->base; - res->end = reg->base + reg->size - 1; + res->start = start; + /* + * In memblock, end points to the first byte after the + * range while in resourses, end points to the last byte in + * the range. + */ + res->end = end - 1; request_resource(&iomem_resource, res); for (j = 0; j < ARRAY_SIZE(standard_resources); j++) { @@ -546,22 +561,17 @@ static void __init setup_memory_end(void) unsigned long vmax, tmp; /* Choose kernel address space layout: 3 or 4 levels. */ - if (IS_ENABLED(CONFIG_KASAN)) { - vmax = IS_ENABLED(CONFIG_KASAN_S390_4_LEVEL_PAGING) - ? _REGION1_SIZE - : _REGION2_SIZE; - } else { - tmp = (memory_end ?: max_physmem_end) / PAGE_SIZE; - tmp = tmp * (sizeof(struct page) + PAGE_SIZE); - if (tmp + vmalloc_size + MODULES_LEN <= _REGION2_SIZE) - vmax = _REGION2_SIZE; /* 3-level kernel page table */ - else - vmax = _REGION1_SIZE; /* 4-level kernel page table */ - } - + tmp = (memory_end ?: max_physmem_end) / PAGE_SIZE; + tmp = tmp * (sizeof(struct page) + PAGE_SIZE); + if (tmp + vmalloc_size + MODULES_LEN <= _REGION2_SIZE) + vmax = _REGION2_SIZE; /* 3-level kernel page table */ + else + vmax = _REGION1_SIZE; /* 4-level kernel page table */ if (is_prot_virt_host()) adjust_to_uv_max(&vmax); - +#ifdef CONFIG_KASAN + vmax = kasan_vmax; +#endif /* module area is at the end of the kernel address space. */ MODULES_END = vmax; MODULES_VADDR = MODULES_END - MODULES_LEN; @@ -580,9 +590,14 @@ static void __init setup_memory_end(void) /* Take care that memory_end is set and <= vmemmap */ memory_end = min(memory_end ?: max_physmem_end, (unsigned long)vmemmap); #ifdef CONFIG_KASAN - /* fit in kasan shadow memory region between 1:1 and vmemmap */ memory_end = min(memory_end, KASAN_SHADOW_START); - vmemmap = max(vmemmap, (struct page *)KASAN_SHADOW_END); +#endif + vmemmap_size = SECTION_ALIGN_UP(memory_end / PAGE_SIZE) * sizeof(struct page); +#ifdef CONFIG_KASAN + /* move vmemmap above kasan shadow only if stands in a way */ + if (KASAN_SHADOW_END > (unsigned long)vmemmap && + (unsigned long)vmemmap + vmemmap_size > KASAN_SHADOW_START) + vmemmap = max(vmemmap, (struct page *)KASAN_SHADOW_END); #endif max_pfn = max_low_pfn = PFN_DOWN(memory_end); memblock_remove(memory_end, ULONG_MAX); @@ -619,7 +634,7 @@ static struct notifier_block kdump_mem_nb = { /* * Make sure that the area behind memory_end is protected */ -static void reserve_memory_end(void) +static void __init reserve_memory_end(void) { if (memory_end_set) memblock_reserve(memory_end, ULONG_MAX); @@ -628,7 +643,7 @@ static void reserve_memory_end(void) /* * Make sure that oldmem, where the dump is stored, is protected */ -static void reserve_oldmem(void) +static void __init reserve_oldmem(void) { #ifdef CONFIG_CRASH_DUMP if (OLDMEM_BASE) @@ -640,7 +655,7 @@ static void reserve_oldmem(void) /* * Make sure that oldmem, where the dump is stored, is protected */ -static void remove_oldmem(void) +static void __init remove_oldmem(void) { #ifdef CONFIG_CRASH_DUMP if (OLDMEM_BASE) @@ -776,8 +791,8 @@ static void __init memblock_add_mem_detect_info(void) unsigned long start, end; int i; - memblock_dbg("physmem info source: %s (%hhd)\n", - get_mem_info_source(), mem_detect.info_source); + pr_debug("physmem info source: %s (%hhd)\n", + get_mem_info_source(), mem_detect.info_source); /* keep memblock lists close to the kernel */ memblock_set_bottom_up(true); for_each_mem_detect_block(i, &start, &end) { @@ -819,14 +834,15 @@ static void __init reserve_kernel(void) static void __init setup_memory(void) { - struct memblock_region *reg; + phys_addr_t start, end; + u64 i; /* * Init storage key for present memory */ - for_each_memblock(memory, reg) { - storage_key_init_range(reg->base, reg->base + reg->size); - } + for_each_mem_range(i, &start, &end) + storage_key_init_range(start, end); + psw_set_key(PAGE_DEFAULT_KEY); /* Only cosmetics */ @@ -1126,8 +1142,7 @@ void __init setup_arch(char **cmdline_p) free_mem_detect_info(); remove_oldmem(); - if (is_prot_virt_host()) - setup_uv(); + setup_uv(); setup_memory_end(); setup_memory(); dma_contiguous_reserve(memory_end); @@ -1171,7 +1186,7 @@ void __init setup_arch(char **cmdline_p) if (IS_ENABLED(CONFIG_EXPOLINE)) nospec_init_branches(); - /* Setup zfcpdump support */ + /* Setup zfcp/nvme dump support */ setup_zfcpdump(); /* Add system specific data to the random pool */ diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index b295090e2ce6..9e900a8977bd 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -535,7 +535,6 @@ void do_signal(struct pt_regs *regs) void do_notify_resume(struct pt_regs *regs) { - clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); rseq_handle_notify_resume(NULL, regs); } diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 85700bd85f98..ebfe86d097f0 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -606,14 +606,14 @@ int smp_store_status(int cpu) /* * Collect CPU state of the previous, crashed system. * There are four cases: - * 1) standard zfcp dump - * condition: OLDMEM_BASE == NULL && ipl_info.type == IPL_TYPE_FCP_DUMP + * 1) standard zfcp/nvme dump + * condition: OLDMEM_BASE == NULL && is_ipl_type_dump() == true * The state for all CPUs except the boot CPU needs to be collected * with sigp stop-and-store-status. The boot CPU state is located in * the absolute lowcore of the memory stored in the HSA. The zcore code * will copy the boot CPU state from the HSA. - * 2) stand-alone kdump for SCSI (zfcp dump with swapped memory) - * condition: OLDMEM_BASE != NULL && ipl_info.type == IPL_TYPE_FCP_DUMP + * 2) stand-alone kdump for SCSI/NVMe (zfcp/nvme dump with swapped memory) + * condition: OLDMEM_BASE != NULL && is_ipl_type_dump() == true * The state for all CPUs except the boot CPU needs to be collected * with sigp stop-and-store-status. The firmware or the boot-loader * stored the registers of the boot CPU in the absolute lowcore in the @@ -660,7 +660,7 @@ void __init smp_save_dump_cpus(void) unsigned long page; bool is_boot_cpu; - if (!(OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP)) + if (!(OLDMEM_BASE || is_ipl_type_dump())) /* No previous system present, normal boot. */ return; /* Allocate a page as dumping area for the store status sigps */ @@ -686,7 +686,7 @@ void __init smp_save_dump_cpus(void) /* Get the vector registers */ smp_save_cpu_vxrs(sa, addr, is_boot_cpu, page); /* - * For a zfcp dump OLDMEM_BASE == NULL and the registers + * For a zfcp/nvme dump OLDMEM_BASE == NULL and the registers * of the boot CPU are stored in the HSA. To retrieve * these registers an SCLP request is required which is * done by drivers/s390/char/zcore.c:init_cpu_info() diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c index fc5419ac64c8..7f1266c24f6b 100644 --- a/arch/s390/kernel/stacktrace.c +++ b/arch/s390/kernel/stacktrace.c @@ -19,7 +19,7 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, unwind_for_each_frame(&state, task, regs, 0) { addr = unwind_get_return_address(&state); - if (!addr || !consume_entry(cookie, addr, false)) + if (!addr || !consume_entry(cookie, addr)) break; } } @@ -56,7 +56,7 @@ int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, return -EINVAL; #endif - if (!consume_entry(cookie, addr, false)) + if (!consume_entry(cookie, addr)) return -EINVAL; } diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl index 10456bc936fb..28c168000483 100644 --- a/arch/s390/kernel/syscalls/syscall.tbl +++ b/arch/s390/kernel/syscalls/syscall.tbl @@ -26,7 +26,7 @@ 16 32 lchown - sys_lchown16 19 common lseek sys_lseek compat_sys_lseek 20 common getpid sys_getpid sys_getpid -21 common mount sys_mount compat_sys_mount +21 common mount sys_mount sys_mount 22 common umount sys_oldumount sys_oldumount 23 32 setuid - sys_setuid16 24 32 getuid - sys_getuid16 @@ -134,8 +134,8 @@ 142 64 select sys_select - 143 common flock sys_flock sys_flock 144 common msync sys_msync sys_msync -145 common readv sys_readv compat_sys_readv -146 common writev sys_writev compat_sys_writev +145 common readv sys_readv sys_readv +146 common writev sys_writev sys_writev 147 common getsid sys_getsid sys_getsid 148 common fdatasync sys_fdatasync sys_fdatasync 149 common _sysctl - - @@ -316,7 +316,7 @@ 306 common splice sys_splice sys_splice 307 common sync_file_range sys_sync_file_range compat_sys_s390_sync_file_range 308 common tee sys_tee sys_tee -309 common vmsplice sys_vmsplice compat_sys_vmsplice +309 common vmsplice sys_vmsplice sys_vmsplice 310 common move_pages sys_move_pages compat_sys_move_pages 311 common getcpu sys_getcpu sys_getcpu 312 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait @@ -347,8 +347,8 @@ 337 common clock_adjtime sys_clock_adjtime sys_clock_adjtime32 338 common syncfs sys_syncfs sys_syncfs 339 common setns sys_setns sys_setns -340 common process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv -341 common process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev +340 common process_vm_readv sys_process_vm_readv sys_process_vm_readv +341 common process_vm_writev sys_process_vm_writev sys_process_vm_writev 342 common s390_runtime_instr sys_s390_runtime_instr sys_s390_runtime_instr 343 common kcmp sys_kcmp sys_kcmp 344 common finit_module sys_finit_module sys_finit_module @@ -442,3 +442,4 @@ 437 common openat2 sys_openat2 sys_openat2 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 diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 513e59d08a55..0ac30ee2c633 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -41,6 +41,9 @@ #include <linux/gfp.h> #include <linux/kprobes.h> #include <linux/uaccess.h> +#include <vdso/vsyscall.h> +#include <vdso/clocksource.h> +#include <vdso/helpers.h> #include <asm/facility.h> #include <asm/delay.h> #include <asm/div64.h> @@ -84,7 +87,7 @@ void __init time_early_init(void) /* Initialize TOD steering parameters */ tod_steering_end = *(unsigned long long *) &tod_clock_base[1]; - vdso_data->ts_end = tod_steering_end; + vdso_data->arch_data.tod_steering_end = tod_steering_end; if (!test_facility(28)) return; @@ -257,6 +260,7 @@ static struct clocksource clocksource_tod = { .mult = 1000, .shift = 12, .flags = CLOCK_SOURCE_IS_CONTINUOUS, + .vdso_clock_mode = VDSO_CLOCKMODE_TOD, }; struct clocksource * __init clocksource_default_clock(void) @@ -264,56 +268,6 @@ struct clocksource * __init clocksource_default_clock(void) return &clocksource_tod; } -void update_vsyscall(struct timekeeper *tk) -{ - u64 nsecps; - - if (tk->tkr_mono.clock != &clocksource_tod) - return; - - /* Make userspace gettimeofday spin until we're done. */ - ++vdso_data->tb_update_count; - smp_wmb(); - vdso_data->xtime_tod_stamp = tk->tkr_mono.cycle_last; - vdso_data->xtime_clock_sec = tk->xtime_sec; - vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; - vdso_data->wtom_clock_sec = - tk->xtime_sec + tk->wall_to_monotonic.tv_sec; - vdso_data->wtom_clock_nsec = tk->tkr_mono.xtime_nsec + - + ((u64) tk->wall_to_monotonic.tv_nsec << tk->tkr_mono.shift); - nsecps = (u64) NSEC_PER_SEC << tk->tkr_mono.shift; - while (vdso_data->wtom_clock_nsec >= nsecps) { - vdso_data->wtom_clock_nsec -= nsecps; - vdso_data->wtom_clock_sec++; - } - - vdso_data->xtime_coarse_sec = tk->xtime_sec; - vdso_data->xtime_coarse_nsec = - (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift); - vdso_data->wtom_coarse_sec = - vdso_data->xtime_coarse_sec + tk->wall_to_monotonic.tv_sec; - vdso_data->wtom_coarse_nsec = - vdso_data->xtime_coarse_nsec + tk->wall_to_monotonic.tv_nsec; - while (vdso_data->wtom_coarse_nsec >= NSEC_PER_SEC) { - vdso_data->wtom_coarse_nsec -= NSEC_PER_SEC; - vdso_data->wtom_coarse_sec++; - } - - vdso_data->tk_mult = tk->tkr_mono.mult; - vdso_data->tk_shift = tk->tkr_mono.shift; - vdso_data->hrtimer_res = hrtimer_resolution; - smp_wmb(); - ++vdso_data->tb_update_count; -} - -extern struct timezone sys_tz; - -void update_vsyscall_tz(void) -{ - vdso_data->tz_minuteswest = sys_tz.tz_minuteswest; - vdso_data->tz_dsttime = sys_tz.tz_dsttime; -} - /* * Initialize the TOD clock and the CPU timer of * the boot cpu. @@ -342,11 +296,12 @@ void __init time_init(void) } static DEFINE_PER_CPU(atomic_t, clock_sync_word); -static DEFINE_MUTEX(clock_sync_mutex); +static DEFINE_MUTEX(stp_mutex); static unsigned long clock_sync_flags; -#define CLOCK_SYNC_HAS_STP 0 -#define CLOCK_SYNC_STP 1 +#define CLOCK_SYNC_HAS_STP 0 +#define CLOCK_SYNC_STP 1 +#define CLOCK_SYNC_STPINFO_VALID 2 /* * The get_clock function for the physical clock. It will get the current @@ -431,7 +386,6 @@ static void clock_sync_global(unsigned long long delta) /* Epoch overflow */ tod_clock_base[0]++; /* Adjust TOD steering parameters. */ - vdso_data->tb_update_count++; now = get_tod_clock(); adj = tod_steering_end - now; if (unlikely((s64) adj >= 0)) @@ -443,9 +397,8 @@ static void clock_sync_global(unsigned long long delta) panic("TOD clock sync offset %lli is too large to drift\n", tod_steering_delta); tod_steering_end = now + (abs(tod_steering_delta) << 15); - vdso_data->ts_dir = (tod_steering_delta < 0) ? 0 : 1; - vdso_data->ts_end = tod_steering_end; - vdso_data->tb_update_count++; + vdso_data->arch_data.tod_steering_end = tod_steering_end; + /* Update LPAR offset. */ if (ptff_query(PTFF_QTO) && ptff(&qto, sizeof(qto), PTFF_QTO) == 0) lpar_offset = qto.tod_epoch_difference; @@ -492,7 +445,6 @@ static struct stp_sstpi stp_info; static void *stp_page; static void stp_work_fn(struct work_struct *work); -static DEFINE_MUTEX(stp_work_mutex); static DECLARE_WORK(stp_work, stp_work_fn); static struct timer_list stp_timer; @@ -583,10 +535,26 @@ void stp_queue_work(void) queue_work(time_sync_wq, &stp_work); } +static int __store_stpinfo(void) +{ + int rc = chsc_sstpi(stp_page, &stp_info, sizeof(struct stp_sstpi)); + + if (rc) + clear_bit(CLOCK_SYNC_STPINFO_VALID, &clock_sync_flags); + else + set_bit(CLOCK_SYNC_STPINFO_VALID, &clock_sync_flags); + return rc; +} + +static int stpinfo_valid(void) +{ + return stp_online && test_bit(CLOCK_SYNC_STPINFO_VALID, &clock_sync_flags); +} + static int stp_sync_clock(void *data) { struct clock_sync_data *sync = data; - unsigned long long clock_delta; + unsigned long long clock_delta, flags; static int first; int rc; @@ -599,16 +567,17 @@ static int stp_sync_clock(void *data) if (stp_info.todoff[0] || stp_info.todoff[1] || stp_info.todoff[2] || stp_info.todoff[3] || stp_info.tmd != 2) { + flags = vdso_update_begin(); rc = chsc_sstpc(stp_page, STP_OP_SYNC, 0, &clock_delta); if (rc == 0) { sync->clock_delta = clock_delta; clock_sync_global(clock_delta); - rc = chsc_sstpi(stp_page, &stp_info, - sizeof(struct stp_sstpi)); + rc = __store_stpinfo(); if (rc == 0 && stp_info.tmd != 2) rc = -EAGAIN; } + vdso_update_end(flags); } sync->in_sync = rc ? -EAGAIN : 1; xchg(&first, 0); @@ -628,6 +597,81 @@ static int stp_sync_clock(void *data) return 0; } +static int stp_clear_leap(void) +{ + struct __kernel_timex txc; + int ret; + + memset(&txc, 0, sizeof(txc)); + + ret = do_adjtimex(&txc); + if (ret < 0) + return ret; + + txc.modes = ADJ_STATUS; + txc.status &= ~(STA_INS|STA_DEL); + return do_adjtimex(&txc); +} + +static void stp_check_leap(void) +{ + struct stp_stzi stzi; + struct stp_lsoib *lsoib = &stzi.lsoib; + struct __kernel_timex txc; + int64_t timediff; + int leapdiff, ret; + + if (!stp_info.lu || !check_sync_clock()) { + /* + * Either a scheduled leap second was removed by the operator, + * or STP is out of sync. In both cases, clear the leap second + * kernel flags. + */ + if (stp_clear_leap() < 0) + pr_err("failed to clear leap second flags\n"); + return; + } + + if (chsc_stzi(stp_page, &stzi, sizeof(stzi))) { + pr_err("stzi failed\n"); + return; + } + + timediff = tod_to_ns(lsoib->nlsout - get_tod_clock()) / NSEC_PER_SEC; + leapdiff = lsoib->nlso - lsoib->also; + + if (leapdiff != 1 && leapdiff != -1) { + pr_err("Cannot schedule %d leap seconds\n", leapdiff); + return; + } + + if (timediff < 0) { + if (stp_clear_leap() < 0) + pr_err("failed to clear leap second flags\n"); + } else if (timediff < 7200) { + memset(&txc, 0, sizeof(txc)); + ret = do_adjtimex(&txc); + if (ret < 0) + return; + + txc.modes = ADJ_STATUS; + if (leapdiff > 0) + txc.status |= STA_INS; + else + txc.status |= STA_DEL; + ret = do_adjtimex(&txc); + if (ret < 0) + pr_err("failed to set leap second flags\n"); + /* arm Timer to clear leap second flags */ + mod_timer(&stp_timer, jiffies + msecs_to_jiffies(14400 * MSEC_PER_SEC)); + } else { + /* The day the leap second is scheduled for hasn't been reached. Retry + * in one hour. + */ + mod_timer(&stp_timer, jiffies + msecs_to_jiffies(3600 * MSEC_PER_SEC)); + } +} + /* * STP work. Check for the STP state and take over the clock * synchronization if the STP clock source is usable. @@ -638,7 +682,7 @@ static void stp_work_fn(struct work_struct *work) int rc; /* prevent multiple execution. */ - mutex_lock(&stp_work_mutex); + mutex_lock(&stp_mutex); if (!stp_online) { chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000, NULL); @@ -646,23 +690,22 @@ static void stp_work_fn(struct work_struct *work) goto out_unlock; } - rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0xb0e0, NULL); + rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0xf0e0, NULL); if (rc) goto out_unlock; - rc = chsc_sstpi(stp_page, &stp_info, sizeof(struct stp_sstpi)); + rc = __store_stpinfo(); if (rc || stp_info.c == 0) goto out_unlock; /* Skip synchronization if the clock is already in sync. */ - if (check_sync_clock()) - goto out_unlock; - - memset(&stp_sync, 0, sizeof(stp_sync)); - cpus_read_lock(); - atomic_set(&stp_sync.cpus, num_online_cpus() - 1); - stop_machine_cpuslocked(stp_sync_clock, &stp_sync, cpu_online_mask); - cpus_read_unlock(); + if (!check_sync_clock()) { + memset(&stp_sync, 0, sizeof(stp_sync)); + cpus_read_lock(); + atomic_set(&stp_sync.cpus, num_online_cpus() - 1); + stop_machine_cpuslocked(stp_sync_clock, &stp_sync, cpu_online_mask); + cpus_read_unlock(); + } if (!check_sync_clock()) /* @@ -670,9 +713,11 @@ static void stp_work_fn(struct work_struct *work) * Retry after a second. */ mod_timer(&stp_timer, jiffies + msecs_to_jiffies(MSEC_PER_SEC)); + else if (stp_info.lu) + stp_check_leap(); out_unlock: - mutex_unlock(&stp_work_mutex); + mutex_unlock(&stp_mutex); } /* @@ -687,10 +732,14 @@ static ssize_t ctn_id_show(struct device *dev, struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%016llx\n", - *(unsigned long long *) stp_info.ctnid); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%016llx\n", + *(unsigned long long *) stp_info.ctnid); + mutex_unlock(&stp_mutex); + return ret; } static DEVICE_ATTR_RO(ctn_id); @@ -699,9 +748,13 @@ static ssize_t ctn_type_show(struct device *dev, struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%i\n", stp_info.ctn); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%i\n", stp_info.ctn); + mutex_unlock(&stp_mutex); + return ret; } static DEVICE_ATTR_RO(ctn_type); @@ -710,9 +763,13 @@ static ssize_t dst_offset_show(struct device *dev, struct device_attribute *attr, char *buf) { - if (!stp_online || !(stp_info.vbits & 0x2000)) - return -ENODATA; - return sprintf(buf, "%i\n", (int)(s16) stp_info.dsto); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_mutex); + if (stpinfo_valid() && (stp_info.vbits & 0x2000)) + ret = sprintf(buf, "%i\n", (int)(s16) stp_info.dsto); + mutex_unlock(&stp_mutex); + return ret; } static DEVICE_ATTR_RO(dst_offset); @@ -721,20 +778,56 @@ static ssize_t leap_seconds_show(struct device *dev, struct device_attribute *attr, char *buf) { - if (!stp_online || !(stp_info.vbits & 0x8000)) - return -ENODATA; - return sprintf(buf, "%i\n", (int)(s16) stp_info.leaps); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_mutex); + if (stpinfo_valid() && (stp_info.vbits & 0x8000)) + ret = sprintf(buf, "%i\n", (int)(s16) stp_info.leaps); + mutex_unlock(&stp_mutex); + return ret; } static DEVICE_ATTR_RO(leap_seconds); +static ssize_t leap_seconds_scheduled_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct stp_stzi stzi; + ssize_t ret; + + mutex_lock(&stp_mutex); + if (!stpinfo_valid() || !(stp_info.vbits & 0x8000) || !stp_info.lu) { + mutex_unlock(&stp_mutex); + return -ENODATA; + } + + ret = chsc_stzi(stp_page, &stzi, sizeof(stzi)); + mutex_unlock(&stp_mutex); + if (ret < 0) + return ret; + + if (!stzi.lsoib.p) + return sprintf(buf, "0,0\n"); + + return sprintf(buf, "%llu,%d\n", + tod_to_ns(stzi.lsoib.nlsout - TOD_UNIX_EPOCH) / NSEC_PER_SEC, + stzi.lsoib.nlso - stzi.lsoib.also); +} + +static DEVICE_ATTR_RO(leap_seconds_scheduled); + static ssize_t stratum_show(struct device *dev, struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%i\n", (int)(s16) stp_info.stratum); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%i\n", (int)(s16) stp_info.stratum); + mutex_unlock(&stp_mutex); + return ret; } static DEVICE_ATTR_RO(stratum); @@ -743,9 +836,13 @@ static ssize_t time_offset_show(struct device *dev, struct device_attribute *attr, char *buf) { - if (!stp_online || !(stp_info.vbits & 0x0800)) - return -ENODATA; - return sprintf(buf, "%i\n", (int) stp_info.tto); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_mutex); + if (stpinfo_valid() && (stp_info.vbits & 0x0800)) + ret = sprintf(buf, "%i\n", (int) stp_info.tto); + mutex_unlock(&stp_mutex); + return ret; } static DEVICE_ATTR_RO(time_offset); @@ -754,9 +851,13 @@ static ssize_t time_zone_offset_show(struct device *dev, struct device_attribute *attr, char *buf) { - if (!stp_online || !(stp_info.vbits & 0x4000)) - return -ENODATA; - return sprintf(buf, "%i\n", (int)(s16) stp_info.tzo); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_mutex); + if (stpinfo_valid() && (stp_info.vbits & 0x4000)) + ret = sprintf(buf, "%i\n", (int)(s16) stp_info.tzo); + mutex_unlock(&stp_mutex); + return ret; } static DEVICE_ATTR_RO(time_zone_offset); @@ -765,9 +866,13 @@ static ssize_t timing_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%i\n", stp_info.tmd); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%i\n", stp_info.tmd); + mutex_unlock(&stp_mutex); + return ret; } static DEVICE_ATTR_RO(timing_mode); @@ -776,9 +881,13 @@ static ssize_t timing_state_show(struct device *dev, struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%i\n", stp_info.tst); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%i\n", stp_info.tst); + mutex_unlock(&stp_mutex); + return ret; } static DEVICE_ATTR_RO(timing_state); @@ -801,14 +910,14 @@ static ssize_t online_store(struct device *dev, return -EINVAL; if (!test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags)) return -EOPNOTSUPP; - mutex_lock(&clock_sync_mutex); + mutex_lock(&stp_mutex); stp_online = value; if (stp_online) set_bit(CLOCK_SYNC_STP, &clock_sync_flags); else clear_bit(CLOCK_SYNC_STP, &clock_sync_flags); queue_work(time_sync_wq, &stp_work); - mutex_unlock(&clock_sync_mutex); + mutex_unlock(&stp_mutex); return count; } @@ -824,6 +933,7 @@ static struct device_attribute *stp_attributes[] = { &dev_attr_dst_offset, &dev_attr_leap_seconds, &dev_attr_online, + &dev_attr_leap_seconds_scheduled, &dev_attr_stratum, &dev_attr_time_offset, &dev_attr_time_zone_offset, diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c index c296e5c8dbf9..14bd9d58edc9 100644 --- a/arch/s390/kernel/uv.c +++ b/arch/s390/kernel/uv.c @@ -26,33 +26,10 @@ int __bootdata_preserved(prot_virt_guest); struct uv_info __bootdata_preserved(uv_info); #if IS_ENABLED(CONFIG_KVM) -int prot_virt_host; +int __bootdata_preserved(prot_virt_host); EXPORT_SYMBOL(prot_virt_host); EXPORT_SYMBOL(uv_info); -static int __init prot_virt_setup(char *val) -{ - bool enabled; - int rc; - - rc = kstrtobool(val, &enabled); - if (!rc && enabled) - prot_virt_host = 1; - - if (is_prot_virt_guest() && prot_virt_host) { - prot_virt_host = 0; - pr_warn("Protected virtualization not available in protected guests."); - } - - if (prot_virt_host && !test_facility(158)) { - prot_virt_host = 0; - pr_warn("Protected virtualization not supported by the hardware."); - } - - return rc; -} -early_param("prot_virt", prot_virt_setup); - static int __init uv_init(unsigned long stor_base, unsigned long stor_len) { struct uv_cb_init uvcb = { @@ -74,6 +51,24 @@ void __init setup_uv(void) { unsigned long uv_stor_base; + /* + * keep these conditions in line with kasan init code has_uv_sec_stor_limit() + */ + if (!is_prot_virt_host()) + return; + + if (is_prot_virt_guest()) { + prot_virt_host = 0; + pr_warn("Protected virtualization not available in protected guests."); + return; + } + + if (!test_facility(158)) { + prot_virt_host = 0; + pr_warn("Protected virtualization not supported by the hardware."); + return; + } + uv_stor_base = (unsigned long)memblock_alloc_try_nid( uv_info.uv_base_stor_len, SZ_1M, SZ_2G, MEMBLOCK_ALLOC_ACCESSIBLE, NUMA_NO_NODE); @@ -98,7 +93,8 @@ fail: void adjust_to_uv_max(unsigned long *vmax) { - *vmax = min_t(unsigned long, *vmax, uv_info.max_sec_stor_addr); + if (uv_info.max_sec_stor_addr) + *vmax = min_t(unsigned long, *vmax, uv_info.max_sec_stor_addr); } /* @@ -119,6 +115,26 @@ static int uv_pin_shared(unsigned long paddr) } /* + * Requests the Ultravisor to destroy a guest page and make it + * accessible to the host. The destroy clears the page instead of + * exporting. + * + * @paddr: Absolute host address of page to be destroyed + */ +int uv_destroy_page(unsigned long paddr) +{ + struct uv_cb_cfs uvcb = { + .header.cmd = UVC_CMD_DESTR_SEC_STOR, + .header.len = sizeof(uvcb), + .paddr = paddr + }; + + if (uv_call(0, (u64)&uvcb)) + return -EINVAL; + return 0; +} + +/* * Requests the Ultravisor to encrypt a guest page and make it * accessible to the host for paging (export). * diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index c4baefaa6e34..f9da5b149141 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -20,6 +20,8 @@ #include <linux/security.h> #include <linux/memblock.h> #include <linux/compat.h> +#include <linux/binfmts.h> +#include <vdso/datapage.h> #include <asm/asm-offsets.h> #include <asm/processor.h> #include <asm/mmu.h> @@ -96,35 +98,12 @@ static union { struct vdso_data data; u8 page[PAGE_SIZE]; } vdso_data_store __page_aligned_data; -struct vdso_data *vdso_data = &vdso_data_store.data; - -/* - * Setup vdso data page. - */ -static void __init vdso_init_data(struct vdso_data *vd) -{ - vd->ectg_available = test_facility(31); -} - +struct vdso_data *vdso_data = (struct vdso_data *)&vdso_data_store.data; /* * Allocate/free per cpu vdso data. */ #define SEGMENT_ORDER 2 -/* - * The initial vdso_data structure for the boot CPU. Eventually - * it is replaced with a properly allocated structure in vdso_init. - * This is necessary because a valid S390_lowcore.vdso_per_cpu_data - * pointer is required to be able to return from an interrupt or - * program check. See the exit paths in entry.S. - */ -struct vdso_data boot_vdso_data __initdata; - -void __init vdso_alloc_boot_cpu(struct lowcore *lowcore) -{ - lowcore->vdso_per_cpu_data = (unsigned long) &boot_vdso_data; -} - int vdso_alloc_per_cpu(struct lowcore *lowcore) { unsigned long segment_table, page_table, page_frame; @@ -246,8 +225,6 @@ static int __init vdso_init(void) { int i; - vdso_init_data(vdso_data); - /* Calculate the size of the 64 bit vDSO */ vdso64_pages = ((&vdso64_end - &vdso64_start + PAGE_SIZE - 1) >> PAGE_SHIFT) + 1; diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile index 4a66a1cb919b..13cc5a3f9abf 100644 --- a/arch/s390/kernel/vdso64/Makefile +++ b/arch/s390/kernel/vdso64/Makefile @@ -1,17 +1,23 @@ # SPDX-License-Identifier: GPL-2.0 -# List of files in the vdso, has to be asm only for now +# List of files in the vdso KCOV_INSTRUMENT := n +ARCH_REL_TYPE_ABS := R_390_COPY|R_390_GLOB_DAT|R_390_JMP_SLOT|R_390_RELATIVE +ARCH_REL_TYPE_ABS += R_390_GOT|R_390_PLT -obj-vdso64 = gettimeofday.o clock_getres.o clock_gettime.o note.o getcpu.o +include $(srctree)/lib/vdso/Makefile +obj-vdso64 = vdso_user_wrapper.o note.o getcpu.o +obj-cvdso64 = vdso64_generic.o +CFLAGS_REMOVE_vdso64_generic.o = -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) # Build rules -targets := $(obj-vdso64) vdso64.so vdso64.so.dbg +targets := $(obj-vdso64) $(obj-cvdso64) vdso64.so vdso64.so.dbg obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64)) +obj-cvdso64 := $(addprefix $(obj)/, $(obj-cvdso64)) KBUILD_AFLAGS += -DBUILD_VDSO -KBUILD_CFLAGS += -DBUILD_VDSO +KBUILD_CFLAGS += -DBUILD_VDSO -DDISABLE_BRANCH_PROFILING KBUILD_AFLAGS_64 := $(filter-out -m64,$(KBUILD_AFLAGS)) KBUILD_AFLAGS_64 += -m64 -s @@ -19,13 +25,13 @@ KBUILD_AFLAGS_64 += -m64 -s KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS)) KBUILD_CFLAGS_64 += -m64 -fPIC -shared -fno-common -fno-builtin ldflags-y := -fPIC -shared -nostdlib -soname=linux-vdso64.so.1 \ - --hash-style=both --build-id -T + --hash-style=both --build-id=sha1 -T $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64) $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_64) obj-y += vdso64_wrapper.o -extra-y += vdso64.lds +targets += vdso64.lds CPPFLAGS_vdso64.lds += -P -C -U$(ARCH) # Disable gcov profiling, ubsan and kasan for VDSO code @@ -37,7 +43,7 @@ KASAN_SANITIZE := n $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so # link rule for the .so file, .lds has to be first -$(obj)/vdso64.so.dbg: $(obj)/vdso64.lds $(obj-vdso64) FORCE +$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) $(obj-cvdso64) FORCE $(call if_changed,ld) # strip rule for the .so file @@ -49,9 +55,14 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE $(obj-vdso64): %.o: %.S FORCE $(call if_changed_dep,vdso64as) +$(obj-cvdso64): %.o: %.c FORCE + $(call if_changed_dep,vdso64cc) + # actual build commands quiet_cmd_vdso64as = VDSO64A $@ cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $< +quiet_cmd_vdso64cc = VDSO64C $@ + cmd_vdso64cc = $(CC) $(c_flags) -c -o $@ $< # install commands for the unstripped file quiet_cmd_vdso_install = INSTALL $@ diff --git a/arch/s390/kernel/vdso64/clock_getres.S b/arch/s390/kernel/vdso64/clock_getres.S deleted file mode 100644 index 0c79caa32b59..000000000000 --- a/arch/s390/kernel/vdso64/clock_getres.S +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Userland implementation of clock_getres() for 64 bits processes in a - * s390 kernel for use in the vDSO - * - * Copyright IBM Corp. 2008 - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) - */ -#include <asm/vdso.h> -#include <asm/asm-offsets.h> -#include <asm/unistd.h> -#include <asm/dwarf.h> - - .text - .align 4 - .globl __kernel_clock_getres - .type __kernel_clock_getres,@function -__kernel_clock_getres: - CFI_STARTPROC - larl %r1,3f - lg %r0,0(%r1) - cghi %r2,__CLOCK_REALTIME_COARSE - je 0f - cghi %r2,__CLOCK_MONOTONIC_COARSE - je 0f - larl %r1,_vdso_data - llgf %r0,__VDSO_CLOCK_REALTIME_RES(%r1) - cghi %r2,__CLOCK_REALTIME - je 0f - cghi %r2,__CLOCK_MONOTONIC - je 0f - cghi %r2,__CLOCK_THREAD_CPUTIME_ID - je 0f - cghi %r2,-2 /* Per-thread CPUCLOCK with PID=0, VIRT=1 */ - jne 2f - larl %r5,_vdso_data - icm %r0,15,__LC_ECTG_OK(%r5) - jz 2f -0: ltgr %r3,%r3 - jz 1f /* res == NULL */ - xc 0(8,%r3),0(%r3) /* set tp->tv_sec to zero */ - stg %r0,8(%r3) /* store tp->tv_usec */ -1: lghi %r2,0 - br %r14 -2: lghi %r1,__NR_clock_getres /* fallback to svc */ - svc 0 - br %r14 - CFI_ENDPROC -3: .quad __CLOCK_COARSE_RES - .size __kernel_clock_getres,.-__kernel_clock_getres diff --git a/arch/s390/kernel/vdso64/clock_gettime.S b/arch/s390/kernel/vdso64/clock_gettime.S deleted file mode 100644 index 9d2ee79b90f2..000000000000 --- a/arch/s390/kernel/vdso64/clock_gettime.S +++ /dev/null @@ -1,163 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Userland implementation of clock_gettime() for 64 bits processes in a - * s390 kernel for use in the vDSO - * - * Copyright IBM Corp. 2008 - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) - */ -#include <asm/vdso.h> -#include <asm/asm-offsets.h> -#include <asm/unistd.h> -#include <asm/dwarf.h> -#include <asm/ptrace.h> - - .text - .align 4 - .globl __kernel_clock_gettime - .type __kernel_clock_gettime,@function -__kernel_clock_gettime: - CFI_STARTPROC - aghi %r15,-16 - CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16 - CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD - larl %r5,_vdso_data - cghi %r2,__CLOCK_REALTIME_COARSE - je 4f - cghi %r2,__CLOCK_REALTIME - je 5f - cghi %r2,-3 /* Per-thread CPUCLOCK with PID=0, VIRT=1 */ - je 9f - cghi %r2,__CLOCK_MONOTONIC_COARSE - je 3f - cghi %r2,__CLOCK_MONOTONIC - jne 12f - - /* CLOCK_MONOTONIC */ -0: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ - tmll %r4,0x0001 /* pending update ? loop */ - jnz 0b - stcke 0(%r15) /* Store TOD clock */ - lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ - lg %r0,__VDSO_WTOM_SEC(%r5) - lg %r1,1(%r15) - sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ - msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ - alg %r1,__VDSO_WTOM_NSEC(%r5) - srlg %r1,%r1,0(%r2) /* >> tk->shift */ - clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ - jne 0b - larl %r5,13f -1: clg %r1,0(%r5) - jl 2f - slg %r1,0(%r5) - aghi %r0,1 - j 1b -2: stg %r0,0(%r3) /* store tp->tv_sec */ - stg %r1,8(%r3) /* store tp->tv_nsec */ - lghi %r2,0 - aghi %r15,16 - CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD - CFI_RESTORE 15 - br %r14 - - /* CLOCK_MONOTONIC_COARSE */ - CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16 - CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD -3: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ - tmll %r4,0x0001 /* pending update ? loop */ - jnz 3b - lg %r0,__VDSO_WTOM_CRS_SEC(%r5) - lg %r1,__VDSO_WTOM_CRS_NSEC(%r5) - clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ - jne 3b - j 2b - - /* CLOCK_REALTIME_COARSE */ -4: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ - tmll %r4,0x0001 /* pending update ? loop */ - jnz 4b - lg %r0,__VDSO_XTIME_CRS_SEC(%r5) - lg %r1,__VDSO_XTIME_CRS_NSEC(%r5) - clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ - jne 4b - j 7f - - /* CLOCK_REALTIME */ -5: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ - tmll %r4,0x0001 /* pending update ? loop */ - jnz 5b - stcke 0(%r15) /* Store TOD clock */ - lg %r1,1(%r15) - lg %r0,__VDSO_TS_END(%r5) /* TOD steering end time */ - slgr %r0,%r1 /* now - ts_steering_end */ - ltgr %r0,%r0 /* past end of steering ? */ - jm 17f - srlg %r0,%r0,15 /* 1 per 2^16 */ - tm __VDSO_TS_DIR+3(%r5),0x01 /* steering direction? */ - jz 18f - lcgr %r0,%r0 /* negative TOD offset */ -18: algr %r1,%r0 /* add steering offset */ -17: lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ - sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ - msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ - alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ - srlg %r1,%r1,0(%r2) /* >> tk->shift */ - lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */ - clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ - jne 5b - larl %r5,13f -6: clg %r1,0(%r5) - jl 7f - slg %r1,0(%r5) - aghi %r0,1 - j 6b -7: stg %r0,0(%r3) /* store tp->tv_sec */ - stg %r1,8(%r3) /* store tp->tv_nsec */ - lghi %r2,0 - aghi %r15,16 - CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD - CFI_RESTORE 15 - br %r14 - - /* CPUCLOCK_VIRT for this thread */ - CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16 - CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD -9: lghi %r4,0 - icm %r0,15,__VDSO_ECTG_OK(%r5) - jz 12f - sacf 256 /* Magic ectg instruction */ - .insn ssf,0xc80100000000,__VDSO_ECTG_BASE(4),__VDSO_ECTG_USER(4),4 - sacf 0 - algr %r1,%r0 /* r1 = cputime as TOD value */ - mghi %r1,1000 /* convert to nanoseconds */ - srlg %r1,%r1,12 /* r1 = cputime in nanosec */ - lgr %r4,%r1 - larl %r5,13f - srlg %r1,%r1,9 /* divide by 1000000000 */ - mlg %r0,8(%r5) - srlg %r0,%r0,11 /* r0 = tv_sec */ - stg %r0,0(%r3) - msg %r0,0(%r5) /* calculate tv_nsec */ - slgr %r4,%r0 /* r4 = tv_nsec */ - stg %r4,8(%r3) - lghi %r2,0 - aghi %r15,16 - CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD - CFI_RESTORE 15 - br %r14 - - /* Fallback to system call */ - CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16 - CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD -12: lghi %r1,__NR_clock_gettime - svc 0 - aghi %r15,16 - CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD - CFI_RESTORE 15 - br %r14 - CFI_ENDPROC - -13: .quad 1000000000 -14: .quad 19342813113834067 - .size __kernel_clock_gettime,.-__kernel_clock_gettime diff --git a/arch/s390/kernel/vdso64/gettimeofday.S b/arch/s390/kernel/vdso64/gettimeofday.S deleted file mode 100644 index aebe10dc7c99..000000000000 --- a/arch/s390/kernel/vdso64/gettimeofday.S +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Userland implementation of gettimeofday() for 64 bits processes in a - * s390 kernel for use in the vDSO - * - * Copyright IBM Corp. 2008 - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) - */ -#include <asm/vdso.h> -#include <asm/asm-offsets.h> -#include <asm/unistd.h> -#include <asm/dwarf.h> -#include <asm/ptrace.h> - - .text - .align 4 - .globl __kernel_gettimeofday - .type __kernel_gettimeofday,@function -__kernel_gettimeofday: - CFI_STARTPROC - aghi %r15,-16 - CFI_ADJUST_CFA_OFFSET 16 - CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD - larl %r5,_vdso_data -0: ltgr %r3,%r3 /* check if tz is NULL */ - je 1f - mvc 0(8,%r3),__VDSO_TIMEZONE(%r5) -1: ltgr %r2,%r2 /* check if tv is NULL */ - je 4f - lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ - tmll %r4,0x0001 /* pending update ? loop */ - jnz 0b - stcke 0(%r15) /* Store TOD clock */ - lg %r1,1(%r15) - lg %r0,__VDSO_TS_END(%r5) /* TOD steering end time */ - slgr %r0,%r1 /* now - ts_steering_end */ - ltgr %r0,%r0 /* past end of steering ? */ - jm 6f - srlg %r0,%r0,15 /* 1 per 2^16 */ - tm __VDSO_TS_DIR+3(%r5),0x01 /* steering direction? */ - jz 7f - lcgr %r0,%r0 /* negative TOD offset */ -7: algr %r1,%r0 /* add steering offset */ -6: sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ - msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ - alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ - lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */ - clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ - jne 0b - lgf %r5,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ - srlg %r1,%r1,0(%r5) /* >> tk->shift */ - larl %r5,5f -2: clg %r1,0(%r5) - jl 3f - slg %r1,0(%r5) - aghi %r0,1 - j 2b -3: stg %r0,0(%r2) /* store tv->tv_sec */ - slgr %r0,%r0 /* tv_nsec -> tv_usec */ - ml %r0,8(%r5) - srlg %r0,%r0,6 - stg %r0,8(%r2) /* store tv->tv_usec */ -4: lghi %r2,0 - aghi %r15,16 - CFI_ADJUST_CFA_OFFSET -16 - CFI_RESTORE 15 - br %r14 - CFI_ENDPROC -5: .quad 1000000000 - .long 274877907 - .size __kernel_gettimeofday,.-__kernel_gettimeofday diff --git a/arch/s390/kernel/vdso64/vdso64_generic.c b/arch/s390/kernel/vdso64/vdso64_generic.c new file mode 100644 index 000000000000..a8cef7e4d137 --- /dev/null +++ b/arch/s390/kernel/vdso64/vdso64_generic.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "../../../../lib/vdso/gettimeofday.c" + +int __s390_vdso_gettimeofday(struct __kernel_old_timeval *tv, + struct timezone *tz) +{ + return __cvdso_gettimeofday(tv, tz); +} + +int __s390_vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts) +{ + return __cvdso_clock_gettime(clock, ts); +} + +int __s390_vdso_clock_getres(clockid_t clock, struct __kernel_timespec *ts) +{ + return __cvdso_clock_getres(clock, ts); +} diff --git a/arch/s390/kernel/vdso64/vdso_user_wrapper.S b/arch/s390/kernel/vdso64/vdso_user_wrapper.S new file mode 100644 index 000000000000..a775d7e52872 --- /dev/null +++ b/arch/s390/kernel/vdso64/vdso_user_wrapper.S @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include <asm/vdso.h> +#include <asm/unistd.h> +#include <asm/asm-offsets.h> +#include <asm/dwarf.h> +#include <asm/ptrace.h> + +#define WRAPPER_FRAME_SIZE (STACK_FRAME_OVERHEAD+8) + +/* + * Older glibc version called vdso without allocating a stackframe. This wrapper + * is just used to allocate a stackframe. See + * https://sourceware.org/git/?p=glibc.git;a=commit;h=478593e6374f3818da39332260dc453cb19cfa1e + * for details. + */ +.macro vdso_func func + .globl __kernel_\func + .type __kernel_\func,@function + .align 8 +__kernel_\func: + CFI_STARTPROC + aghi %r15,-WRAPPER_FRAME_SIZE + CFI_DEF_CFA_OFFSET (STACK_FRAME_OVERHEAD + WRAPPER_FRAME_SIZE) + CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD + stg %r14,STACK_FRAME_OVERHEAD(%r15) + brasl %r14,__s390_vdso_\func + lg %r14,STACK_FRAME_OVERHEAD(%r15) + aghi %r15,WRAPPER_FRAME_SIZE + CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD + CFI_RESTORE 15 + br %r14 + CFI_ENDPROC + .size __kernel_\func,.-__kernel_\func +.endm + +vdso_func gettimeofday +vdso_func clock_getres +vdso_func clock_gettime diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 37695499717d..177ccfbda40a 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -181,6 +181,7 @@ SECTIONS /* Debugging sections. */ STABS_DEBUG DWARF_DEBUG + ELF_DETAILS /* Sections to be discarded */ DISCARDS diff --git a/arch/s390/lib/string.c b/arch/s390/lib/string.c index 0e30e6e43b0c..93b3209b94a2 100644 --- a/arch/s390/lib/string.c +++ b/arch/s390/lib/string.c @@ -333,7 +333,7 @@ EXPORT_SYMBOL(memchr); * memcmp - Compare two areas of memory * @s1: One area of memory * @s2: Another area of memory - * @count: The size of the area. + * @n: The size of the area. */ #ifdef __HAVE_ARCH_MEMCMP int memcmp(const void *s1, const void *s2, size_t n) diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile index 3175413186b9..cd67e94c16aa 100644 --- a/arch/s390/mm/Makefile +++ b/arch/s390/mm/Makefile @@ -8,7 +8,7 @@ obj-y += page-states.o pageattr.o pgtable.o pgalloc.o obj-$(CONFIG_CMM) += cmm.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o -obj-$(CONFIG_S390_PTDUMP) += dump_pagetables.o +obj-$(CONFIG_PTDUMP_CORE) += dump_pagetables.o obj-$(CONFIG_PGSTE) += gmap.o KASAN_SANITIZE_kasan_init.o := n diff --git a/arch/s390/mm/dump_pagetables.c b/arch/s390/mm/dump_pagetables.c index c2ac9b8ae612..8f9ff7e7187d 100644 --- a/arch/s390/mm/dump_pagetables.c +++ b/arch/s390/mm/dump_pagetables.c @@ -1,9 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 +#include <linux/set_memory.h> +#include <linux/ptdump.h> #include <linux/seq_file.h> #include <linux/debugfs.h> -#include <linux/sched.h> #include <linux/mm.h> #include <linux/kasan.h> +#include <asm/ptdump.h> #include <asm/kasan.h> #include <asm/sections.h> @@ -15,264 +17,235 @@ struct addr_marker { }; enum address_markers_idx { - IDENTITY_NR = 0, + IDENTITY_BEFORE_NR = 0, + IDENTITY_BEFORE_END_NR, KERNEL_START_NR, KERNEL_END_NR, + IDENTITY_AFTER_NR, + IDENTITY_AFTER_END_NR, #ifdef CONFIG_KASAN KASAN_SHADOW_START_NR, KASAN_SHADOW_END_NR, #endif VMEMMAP_NR, + VMEMMAP_END_NR, VMALLOC_NR, + VMALLOC_END_NR, MODULES_NR, + MODULES_END_NR, }; static struct addr_marker address_markers[] = { - [IDENTITY_NR] = {0, "Identity Mapping"}, + [IDENTITY_BEFORE_NR] = {0, "Identity Mapping Start"}, + [IDENTITY_BEFORE_END_NR] = {(unsigned long)_stext, "Identity Mapping End"}, [KERNEL_START_NR] = {(unsigned long)_stext, "Kernel Image Start"}, [KERNEL_END_NR] = {(unsigned long)_end, "Kernel Image End"}, + [IDENTITY_AFTER_NR] = {(unsigned long)_end, "Identity Mapping Start"}, + [IDENTITY_AFTER_END_NR] = {0, "Identity Mapping End"}, #ifdef CONFIG_KASAN [KASAN_SHADOW_START_NR] = {KASAN_SHADOW_START, "Kasan Shadow Start"}, [KASAN_SHADOW_END_NR] = {KASAN_SHADOW_END, "Kasan Shadow End"}, #endif - [VMEMMAP_NR] = {0, "vmemmap Area"}, - [VMALLOC_NR] = {0, "vmalloc Area"}, - [MODULES_NR] = {0, "Modules Area"}, + [VMEMMAP_NR] = {0, "vmemmap Area Start"}, + [VMEMMAP_END_NR] = {0, "vmemmap Area End"}, + [VMALLOC_NR] = {0, "vmalloc Area Start"}, + [VMALLOC_END_NR] = {0, "vmalloc Area End"}, + [MODULES_NR] = {0, "Modules Area Start"}, + [MODULES_END_NR] = {0, "Modules Area End"}, { -1, NULL } }; struct pg_state { + struct ptdump_state ptdump; + struct seq_file *seq; int level; unsigned int current_prot; + bool check_wx; + unsigned long wx_pages; unsigned long start_address; - unsigned long current_address; const struct addr_marker *marker; }; +#define pt_dump_seq_printf(m, fmt, args...) \ +({ \ + struct seq_file *__m = (m); \ + \ + if (__m) \ + seq_printf(__m, fmt, ##args); \ +}) + +#define pt_dump_seq_puts(m, fmt) \ +({ \ + struct seq_file *__m = (m); \ + \ + if (__m) \ + seq_printf(__m, fmt); \ +}) + static void print_prot(struct seq_file *m, unsigned int pr, int level) { static const char * const level_name[] = { "ASCE", "PGD", "PUD", "PMD", "PTE" }; - seq_printf(m, "%s ", level_name[level]); + pt_dump_seq_printf(m, "%s ", level_name[level]); if (pr & _PAGE_INVALID) { - seq_printf(m, "I\n"); + pt_dump_seq_printf(m, "I\n"); return; } - seq_puts(m, (pr & _PAGE_PROTECT) ? "RO " : "RW "); - seq_puts(m, (pr & _PAGE_NOEXEC) ? "NX\n" : "X\n"); + pt_dump_seq_puts(m, (pr & _PAGE_PROTECT) ? "RO " : "RW "); + pt_dump_seq_puts(m, (pr & _PAGE_NOEXEC) ? "NX\n" : "X\n"); } -static void note_page(struct seq_file *m, struct pg_state *st, - unsigned int new_prot, int level) +static void note_prot_wx(struct pg_state *st, unsigned long addr) +{ +#ifdef CONFIG_DEBUG_WX + if (!st->check_wx) + return; + if (st->current_prot & _PAGE_INVALID) + return; + if (st->current_prot & _PAGE_PROTECT) + return; + if (st->current_prot & _PAGE_NOEXEC) + return; + /* The first lowcore page is currently still W+X. */ + if (addr == PAGE_SIZE) + return; + WARN_ONCE(1, "s390/mm: Found insecure W+X mapping at address %pS\n", + (void *)st->start_address); + st->wx_pages += (addr - st->start_address) / PAGE_SIZE; +#endif /* CONFIG_DEBUG_WX */ +} + +static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level, u64 val) { - static const char units[] = "KMGTPE"; int width = sizeof(unsigned long) * 2; + static const char units[] = "KMGTPE"; const char *unit = units; - unsigned int prot, cur; unsigned long delta; + struct pg_state *st; + struct seq_file *m; + unsigned int prot; - /* - * If we have a "break" in the series, we need to flush the state - * that we have now. "break" is either changing perms, levels or - * address space marker. - */ - prot = new_prot; - cur = st->current_prot; - - if (!st->level) { - /* First entry */ - st->current_prot = new_prot; + st = container_of(pt_st, struct pg_state, ptdump); + m = st->seq; + prot = val & (_PAGE_PROTECT | _PAGE_NOEXEC); + if (level == 4 && (val & _PAGE_INVALID)) + prot = _PAGE_INVALID; + /* For pmd_none() & friends val gets passed as zero. */ + if (level != 4 && !val) + prot = _PAGE_INVALID; + /* Final flush from generic code. */ + if (level == -1) + addr = max_addr; + if (st->level == -1) { + pt_dump_seq_printf(m, "---[ %s ]---\n", st->marker->name); + st->start_address = addr; + st->current_prot = prot; st->level = level; - st->marker = address_markers; - seq_printf(m, "---[ %s ]---\n", st->marker->name); - } else if (prot != cur || level != st->level || - st->current_address >= st->marker[1].start_address) { - /* Print the actual finished series */ - seq_printf(m, "0x%0*lx-0x%0*lx ", - width, st->start_address, - width, st->current_address); - delta = (st->current_address - st->start_address) >> 10; + } else if (prot != st->current_prot || level != st->level || + addr >= st->marker[1].start_address) { + note_prot_wx(st, addr); + pt_dump_seq_printf(m, "0x%0*lx-0x%0*lx ", + width, st->start_address, + width, addr); + delta = (addr - st->start_address) >> 10; while (!(delta & 0x3ff) && unit[1]) { delta >>= 10; unit++; } - seq_printf(m, "%9lu%c ", delta, *unit); + pt_dump_seq_printf(m, "%9lu%c ", delta, *unit); print_prot(m, st->current_prot, st->level); - while (st->current_address >= st->marker[1].start_address) { + while (addr >= st->marker[1].start_address) { st->marker++; - seq_printf(m, "---[ %s ]---\n", st->marker->name); + pt_dump_seq_printf(m, "---[ %s ]---\n", st->marker->name); } - st->start_address = st->current_address; - st->current_prot = new_prot; + st->start_address = addr; + st->current_prot = prot; st->level = level; } } -#ifdef CONFIG_KASAN -static void note_kasan_early_shadow_page(struct seq_file *m, - struct pg_state *st) -{ - unsigned int prot; - - prot = pte_val(*kasan_early_shadow_pte) & - (_PAGE_PROTECT | _PAGE_INVALID | _PAGE_NOEXEC); - note_page(m, st, prot, 4); -} -#endif - -/* - * The actual page table walker functions. In order to keep the - * implementation of print_prot() short, we only check and pass - * _PAGE_INVALID and _PAGE_PROTECT flags to note_page() if a region, - * segment or page table entry is invalid or read-only. - * After all it's just a hint that the current level being walked - * contains an invalid or read-only entry. - */ -static void walk_pte_level(struct seq_file *m, struct pg_state *st, - pmd_t *pmd, unsigned long addr) -{ - unsigned int prot; - pte_t *pte; - int i; - - for (i = 0; i < PTRS_PER_PTE && addr < max_addr; i++) { - st->current_address = addr; - pte = pte_offset_kernel(pmd, addr); - prot = pte_val(*pte) & - (_PAGE_PROTECT | _PAGE_INVALID | _PAGE_NOEXEC); - note_page(m, st, prot, 4); - addr += PAGE_SIZE; - } -} - -static void walk_pmd_level(struct seq_file *m, struct pg_state *st, - pud_t *pud, unsigned long addr) -{ - unsigned int prot; - pmd_t *pmd; - int i; - -#ifdef CONFIG_KASAN - if ((pud_val(*pud) & PAGE_MASK) == __pa(kasan_early_shadow_pmd)) { - note_kasan_early_shadow_page(m, st); - return; - } -#endif - - pmd = pmd_offset(pud, addr); - for (i = 0; i < PTRS_PER_PMD && addr < max_addr; i++, pmd++) { - st->current_address = addr; - if (!pmd_none(*pmd)) { - if (pmd_large(*pmd)) { - prot = pmd_val(*pmd) & - (_SEGMENT_ENTRY_PROTECT | - _SEGMENT_ENTRY_NOEXEC); - note_page(m, st, prot, 3); - } else - walk_pte_level(m, st, pmd, addr); - } else - note_page(m, st, _PAGE_INVALID, 3); - addr += PMD_SIZE; - } -} - -static void walk_pud_level(struct seq_file *m, struct pg_state *st, - p4d_t *p4d, unsigned long addr) +#ifdef CONFIG_DEBUG_WX +void ptdump_check_wx(void) { - unsigned int prot; - pud_t *pud; - int i; + struct pg_state st = { + .ptdump = { + .note_page = note_page, + .range = (struct ptdump_range[]) { + {.start = 0, .end = max_addr}, + {.start = 0, .end = 0}, + } + }, + .seq = NULL, + .level = -1, + .current_prot = 0, + .check_wx = true, + .wx_pages = 0, + .start_address = 0, + .marker = (struct addr_marker[]) { + { .start_address = 0, .name = NULL}, + { .start_address = -1, .name = NULL}, + }, + }; -#ifdef CONFIG_KASAN - if ((p4d_val(*p4d) & PAGE_MASK) == __pa(kasan_early_shadow_pud)) { - note_kasan_early_shadow_page(m, st); + if (!MACHINE_HAS_NX) return; - } -#endif - - pud = pud_offset(p4d, addr); - for (i = 0; i < PTRS_PER_PUD && addr < max_addr; i++, pud++) { - st->current_address = addr; - if (!pud_none(*pud)) - if (pud_large(*pud)) { - prot = pud_val(*pud) & - (_REGION_ENTRY_PROTECT | - _REGION_ENTRY_NOEXEC); - note_page(m, st, prot, 2); - } else - walk_pmd_level(m, st, pud, addr); - else - note_page(m, st, _PAGE_INVALID, 2); - addr += PUD_SIZE; - } + ptdump_walk_pgd(&st.ptdump, &init_mm, NULL); + if (st.wx_pages) + pr_warn("Checked W+X mappings: FAILED, %lu W+X pages found\n", st.wx_pages); + else + pr_info("Checked W+X mappings: passed, no unexpected W+X pages found\n"); } +#endif /* CONFIG_DEBUG_WX */ -static void walk_p4d_level(struct seq_file *m, struct pg_state *st, - pgd_t *pgd, unsigned long addr) +#ifdef CONFIG_PTDUMP_DEBUGFS +static int ptdump_show(struct seq_file *m, void *v) { - p4d_t *p4d; - int i; - -#ifdef CONFIG_KASAN - if ((pgd_val(*pgd) & PAGE_MASK) == __pa(kasan_early_shadow_p4d)) { - note_kasan_early_shadow_page(m, st); - return; - } -#endif + struct pg_state st = { + .ptdump = { + .note_page = note_page, + .range = (struct ptdump_range[]) { + {.start = 0, .end = max_addr}, + {.start = 0, .end = 0}, + } + }, + .seq = m, + .level = -1, + .current_prot = 0, + .check_wx = false, + .wx_pages = 0, + .start_address = 0, + .marker = address_markers, + }; - p4d = p4d_offset(pgd, addr); - for (i = 0; i < PTRS_PER_P4D && addr < max_addr; i++, p4d++) { - st->current_address = addr; - if (!p4d_none(*p4d)) - walk_pud_level(m, st, p4d, addr); - else - note_page(m, st, _PAGE_INVALID, 2); - addr += P4D_SIZE; - } + get_online_mems(); + mutex_lock(&cpa_mutex); + ptdump_walk_pgd(&st.ptdump, &init_mm, NULL); + mutex_unlock(&cpa_mutex); + put_online_mems(); + return 0; } +DEFINE_SHOW_ATTRIBUTE(ptdump); +#endif /* CONFIG_PTDUMP_DEBUGFS */ -static void walk_pgd_level(struct seq_file *m) +/* + * Heapsort from lib/sort.c is not a stable sorting algorithm, do a simple + * insertion sort to preserve the original order of markers with the same + * start address. + */ +static void sort_address_markers(void) { - unsigned long addr = 0; - struct pg_state st; - pgd_t *pgd; - int i; + struct addr_marker tmp; + int i, j; - memset(&st, 0, sizeof(st)); - for (i = 0; i < PTRS_PER_PGD && addr < max_addr; i++) { - st.current_address = addr; - pgd = pgd_offset_k(addr); - if (!pgd_none(*pgd)) - walk_p4d_level(m, &st, pgd, addr); - else - note_page(m, &st, _PAGE_INVALID, 1); - addr += PGDIR_SIZE; - cond_resched(); + for (i = 1; i < ARRAY_SIZE(address_markers) - 1; i++) { + tmp = address_markers[i]; + for (j = i - 1; j >= 0 && address_markers[j].start_address > tmp.start_address; j--) + address_markers[j + 1] = address_markers[j]; + address_markers[j + 1] = tmp; } - /* Flush out the last page */ - st.current_address = max_addr; - note_page(m, &st, 0, 0); } -static int ptdump_show(struct seq_file *m, void *v) -{ - walk_pgd_level(m); - return 0; -} - -static int ptdump_open(struct inode *inode, struct file *filp) -{ - return single_open(filp, ptdump_show, NULL); -} - -static const struct file_operations ptdump_fops = { - .open = ptdump_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static int pt_dump_init(void) { /* @@ -282,10 +255,17 @@ static int pt_dump_init(void) */ max_addr = (S390_lowcore.kernel_asce & _REGION_ENTRY_TYPE_MASK) >> 2; max_addr = 1UL << (max_addr * 11 + 31); + address_markers[IDENTITY_AFTER_END_NR].start_address = memory_end; address_markers[MODULES_NR].start_address = MODULES_VADDR; + address_markers[MODULES_END_NR].start_address = MODULES_END; address_markers[VMEMMAP_NR].start_address = (unsigned long) vmemmap; + address_markers[VMEMMAP_END_NR].start_address = (unsigned long)vmemmap + vmemmap_size; address_markers[VMALLOC_NR].start_address = VMALLOC_START; + address_markers[VMALLOC_END_NR].start_address = VMALLOC_END; + sort_address_markers(); +#ifdef CONFIG_PTDUMP_DEBUGFS debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, &ptdump_fops); +#endif /* CONFIG_PTDUMP_DEBUGFS */ return 0; } device_initcall(pt_dump_init); diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 4c8c063bce5b..996884dcc9fd 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -859,6 +859,21 @@ void do_non_secure_storage_access(struct pt_regs *regs) } NOKPROBE_SYMBOL(do_non_secure_storage_access); +void do_secure_storage_violation(struct pt_regs *regs) +{ + /* + * Either KVM messed up the secure guest mapping or the same + * page is mapped into multiple secure guests. + * + * This exception is only triggered when a guest 2 is running + * and can therefore never occur in kernel context. + */ + printk_ratelimited(KERN_WARNING + "Secure storage violation in task: %s, pid %d\n", + current->comm, current->pid); + send_sig(SIGSEGV, current, 0); +} + #else void do_secure_storage_access(struct pt_regs *regs) { @@ -869,4 +884,9 @@ void do_non_secure_storage_access(struct pt_regs *regs) { default_trap_handler(regs); } + +void do_secure_storage_violation(struct pt_regs *regs) +{ + default_trap_handler(regs); +} #endif diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 373542ca1113..cfb0017f33a7 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -2679,7 +2679,7 @@ static int __s390_reset_acc(pte_t *ptep, unsigned long addr, pte_t pte = READ_ONCE(*ptep); if (pte_present(pte)) - WARN_ON_ONCE(uv_convert_from_secure(pte_val(pte) & PAGE_MASK)); + WARN_ON_ONCE(uv_destroy_page(pte_val(pte) & PAGE_MASK)); return 0; } diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 0d282081dc1f..77767850d0d0 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -34,6 +34,7 @@ #include <asm/processor.h> #include <linux/uaccess.h> #include <asm/pgalloc.h> +#include <asm/ptdump.h> #include <asm/dma.h> #include <asm/lowcore.h> #include <asm/tlb.h> @@ -45,8 +46,9 @@ #include <asm/kasan.h> #include <asm/dma-mapping.h> #include <asm/uv.h> +#include <linux/virtio_config.h> -pgd_t swapper_pg_dir[PTRS_PER_PGD] __section(.bss..swapper_pg_dir); +pgd_t swapper_pg_dir[PTRS_PER_PGD] __section(".bss..swapper_pg_dir"); unsigned long empty_zero_page, zero_page_mask; EXPORT_SYMBOL(empty_zero_page); @@ -129,6 +131,7 @@ void mark_rodata_ro(void) set_memory_ro((unsigned long)__start_ro_after_init, size >> PAGE_SHIFT); pr_info("Write protected read-only-after-init data: %luk\n", size >> 10); + debug_checkwx(); } int set_memory_encrypted(unsigned long addr, int numpages) @@ -160,6 +163,16 @@ bool force_dma_unencrypted(struct device *dev) return is_prot_virt_guest(); } +#ifdef CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS + +int arch_has_restricted_virtio_memory_access(void) +{ + return is_prot_virt_guest(); +} +EXPORT_SYMBOL(arch_has_restricted_virtio_memory_access); + +#endif + /* protected virtualization */ static void pv_init(void) { diff --git a/arch/s390/mm/kasan_init.c b/arch/s390/mm/kasan_init.c index 99dd1c63a065..5646b39c728a 100644 --- a/arch/s390/mm/kasan_init.c +++ b/arch/s390/mm/kasan_init.c @@ -11,7 +11,9 @@ #include <asm/facility.h> #include <asm/sections.h> #include <asm/setup.h> +#include <asm/uv.h> +unsigned long kasan_vmax; static unsigned long segment_pos __initdata; static unsigned long segment_low __initdata; static unsigned long pgalloc_pos __initdata; @@ -99,8 +101,12 @@ static void __init kasan_early_vmemmap_populate(unsigned long address, pgt_prot_zero = pgprot_val(PAGE_KERNEL_RO); if (!has_nx) pgt_prot_zero &= ~_PAGE_NOEXEC; - pgt_prot = pgprot_val(PAGE_KERNEL_EXEC); - sgt_prot = pgprot_val(SEGMENT_KERNEL_EXEC); + pgt_prot = pgprot_val(PAGE_KERNEL); + sgt_prot = pgprot_val(SEGMENT_KERNEL); + if (!has_nx || mode == POPULATE_ONE2ONE) { + pgt_prot &= ~_PAGE_NOEXEC; + sgt_prot &= ~_SEGMENT_ENTRY_NOEXEC; + } while (address < end) { pg_dir = pgd_offset_k(address); @@ -252,14 +258,31 @@ static void __init kasan_early_detect_facilities(void) } } +static bool __init has_uv_sec_stor_limit(void) +{ + /* + * keep these conditions in line with setup_uv() + */ + if (!is_prot_virt_host()) + return false; + + if (is_prot_virt_guest()) + return false; + + if (!test_facility(158)) + return false; + + return !!uv_info.max_sec_stor_addr; +} + void __init kasan_early_init(void) { unsigned long untracked_mem_end; unsigned long shadow_alloc_size; + unsigned long vmax_unlimited; unsigned long initrd_end; unsigned long asce_type; unsigned long memsize; - unsigned long vmax; unsigned long pgt_prot = pgprot_val(PAGE_KERNEL_RO); pte_t pte_z; pmd_t pmd_z = __pmd(__pa(kasan_early_shadow_pte) | _SEGMENT_ENTRY); @@ -287,7 +310,9 @@ void __init kasan_early_init(void) BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, P4D_SIZE)); crst_table_init((unsigned long *)early_pg_dir, _REGION2_ENTRY_EMPTY); - untracked_mem_end = vmax = _REGION1_SIZE; + untracked_mem_end = kasan_vmax = vmax_unlimited = _REGION1_SIZE; + if (has_uv_sec_stor_limit()) + kasan_vmax = min(vmax_unlimited, uv_info.max_sec_stor_addr); asce_type = _ASCE_TYPE_REGION2; } else { /* 3 level paging */ @@ -295,7 +320,7 @@ void __init kasan_early_init(void) BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PUD_SIZE)); crst_table_init((unsigned long *)early_pg_dir, _REGION3_ENTRY_EMPTY); - untracked_mem_end = vmax = _REGION2_SIZE; + untracked_mem_end = kasan_vmax = vmax_unlimited = _REGION2_SIZE; asce_type = _ASCE_TYPE_REGION3; } @@ -365,17 +390,20 @@ void __init kasan_early_init(void) /* populate kasan shadow (for identity mapping and zero page mapping) */ kasan_early_vmemmap_populate(__sha(0), __sha(memsize), POPULATE_MAP); if (IS_ENABLED(CONFIG_MODULES)) - untracked_mem_end = vmax - MODULES_LEN; + untracked_mem_end = kasan_vmax - MODULES_LEN; if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) { - untracked_mem_end = vmax - vmalloc_size - MODULES_LEN; + untracked_mem_end = kasan_vmax - vmalloc_size - MODULES_LEN; /* shallowly populate kasan shadow for vmalloc and modules */ kasan_early_vmemmap_populate(__sha(untracked_mem_end), - __sha(vmax), POPULATE_SHALLOW); + __sha(kasan_vmax), POPULATE_SHALLOW); } /* populate kasan shadow for untracked memory */ kasan_early_vmemmap_populate(__sha(max_physmem_end), __sha(untracked_mem_end), POPULATE_ZERO_SHADOW); + kasan_early_vmemmap_populate(__sha(kasan_vmax), + __sha(vmax_unlimited), + POPULATE_ZERO_SHADOW); /* memory allocated for identity mapping structs will be freed later */ pgalloc_freeable = pgalloc_pos; /* populate identity mapping */ diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c index fc141893d028..567c69f3069e 100644 --- a/arch/s390/mm/page-states.c +++ b/arch/s390/mm/page-states.c @@ -183,9 +183,9 @@ static void mark_kernel_pgd(void) void __init cmma_init_nodat(void) { - struct memblock_region *reg; struct page *page; unsigned long start, end, ix; + int i; if (cmma_flag < 2) return; @@ -193,9 +193,7 @@ void __init cmma_init_nodat(void) mark_kernel_pgd(); /* Set all kernel pages not used for page tables to stable/no-dat */ - for_each_memblock(memory, reg) { - start = memblock_region_memory_base_pfn(reg); - end = memblock_region_memory_end_pfn(reg); + for_each_mem_pfn_range(i, MAX_NUMNODES, &start, &end, NULL) { page = pfn_to_page(start); for (ix = start; ix < end; ix++, page++) { if (__test_and_clear_bit(PG_arch_1, &page->flags)) diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c index c5c52ec2b46f..ed8e5b3575d5 100644 --- a/arch/s390/mm/pageattr.c +++ b/arch/s390/mm/pageattr.c @@ -278,7 +278,7 @@ static int walk_p4d_level(pgd_t *pgd, unsigned long addr, unsigned long end, return rc; } -static DEFINE_MUTEX(cpa_mutex); +DEFINE_MUTEX(cpa_mutex); static int change_page_attr(unsigned long addr, unsigned long end, unsigned long flags) diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 0d25f743b270..18205f851c24 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -24,6 +24,26 @@ #include <asm/mmu_context.h> #include <asm/page-states.h> +pgprot_t pgprot_writecombine(pgprot_t prot) +{ + /* + * mio_wb_bit_mask may be set on a different CPU, but it is only set + * once at init and only read afterwards. + */ + return __pgprot(pgprot_val(prot) | mio_wb_bit_mask); +} +EXPORT_SYMBOL_GPL(pgprot_writecombine); + +pgprot_t pgprot_writethrough(pgprot_t prot) +{ + /* + * mio_wb_bit_mask may be set on a different CPU, but it is only set + * once at init and only read afterwards. + */ + return __pgprot(pgprot_val(prot) & ~mio_wb_bit_mask); +} +EXPORT_SYMBOL_GPL(pgprot_writethrough); + static inline void ptep_ipte_local(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int nodat) { diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index eddf71c22875..b239f2ba93b0 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -555,10 +555,11 @@ int vmem_add_mapping(unsigned long start, unsigned long size) */ void __init vmem_map_init(void) { - struct memblock_region *reg; + phys_addr_t base, end; + u64 i; - for_each_memblock(memory, reg) - vmem_add_range(reg->base, reg->size); + for_each_mem_range(i, &base, &end) + vmem_add_range(base, end - base); __set_memory((unsigned long)_stext, (unsigned long)(_etext - _stext) >> PAGE_SHIFT, SET_MEMORY_RO | SET_MEMORY_X); diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index be4b8532dd3c..0a4182792876 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -50,7 +50,6 @@ struct bpf_jit { int r14_thunk_ip; /* Address of expoline thunk for 'br %r14' */ int tail_call_start; /* Tail call start offset */ int excnt; /* Number of exception table entries */ - int labels[1]; /* Labels for local jumps */ }; #define SEEN_MEM BIT(0) /* use mem[] for temporary storage */ @@ -229,18 +228,18 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1) REG_SET_SEEN(b3); \ }) -#define EMIT6_PCREL_LABEL(op1, op2, b1, b2, label, mask) \ +#define EMIT6_PCREL_RIEB(op1, op2, b1, b2, mask, target) \ ({ \ - int rel = (jit->labels[label] - jit->prg) >> 1; \ + unsigned int rel = (int)((target) - jit->prg) / 2; \ _EMIT6((op1) | reg(b1, b2) << 16 | (rel & 0xffff), \ (op2) | (mask) << 12); \ REG_SET_SEEN(b1); \ REG_SET_SEEN(b2); \ }) -#define EMIT6_PCREL_IMM_LABEL(op1, op2, b1, imm, label, mask) \ +#define EMIT6_PCREL_RIEC(op1, op2, b1, imm, mask, target) \ ({ \ - int rel = (jit->labels[label] - jit->prg) >> 1; \ + unsigned int rel = (int)((target) - jit->prg) / 2; \ _EMIT6((op1) | (reg_high(b1) | (mask)) << 16 | \ (rel & 0xffff), (op2) | ((imm) & 0xff) << 8); \ REG_SET_SEEN(b1); \ @@ -1282,7 +1281,9 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, EMIT4(0xb9040000, BPF_REG_0, REG_2); break; } - case BPF_JMP | BPF_TAIL_CALL: + case BPF_JMP | BPF_TAIL_CALL: { + int patch_1_clrj, patch_2_clij, patch_3_brc; + /* * Implicit input: * B1: pointer to ctx @@ -1300,16 +1301,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, EMIT6_DISP_LH(0xe3000000, 0x0016, REG_W1, REG_0, BPF_REG_2, offsetof(struct bpf_array, map.max_entries)); /* if ((u32)%b3 >= (u32)%w1) goto out; */ - if (!is_first_pass(jit) && can_use_rel(jit, jit->labels[0])) { - /* clrj %b3,%w1,0xa,label0 */ - EMIT6_PCREL_LABEL(0xec000000, 0x0077, BPF_REG_3, - REG_W1, 0, 0xa); - } else { - /* clr %b3,%w1 */ - EMIT2(0x1500, BPF_REG_3, REG_W1); - /* brcl 0xa,label0 */ - EMIT6_PCREL_RILC(0xc0040000, 0xa, jit->labels[0]); - } + /* clrj %b3,%w1,0xa,out */ + patch_1_clrj = jit->prg; + EMIT6_PCREL_RIEB(0xec000000, 0x0077, BPF_REG_3, REG_W1, 0xa, + jit->prg); /* * if (tail_call_cnt++ > MAX_TAIL_CALL_CNT) @@ -1324,16 +1319,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, EMIT4_IMM(0xa7080000, REG_W0, 1); /* laal %w1,%w0,off(%r15) */ EMIT6_DISP_LH(0xeb000000, 0x00fa, REG_W1, REG_W0, REG_15, off); - if (!is_first_pass(jit) && can_use_rel(jit, jit->labels[0])) { - /* clij %w1,MAX_TAIL_CALL_CNT,0x2,label0 */ - EMIT6_PCREL_IMM_LABEL(0xec000000, 0x007f, REG_W1, - MAX_TAIL_CALL_CNT, 0, 0x2); - } else { - /* clfi %w1,MAX_TAIL_CALL_CNT */ - EMIT6_IMM(0xc20f0000, REG_W1, MAX_TAIL_CALL_CNT); - /* brcl 0x2,label0 */ - EMIT6_PCREL_RILC(0xc0040000, 0x2, jit->labels[0]); - } + /* clij %w1,MAX_TAIL_CALL_CNT,0x2,out */ + patch_2_clij = jit->prg; + EMIT6_PCREL_RIEC(0xec000000, 0x007f, REG_W1, MAX_TAIL_CALL_CNT, + 2, jit->prg); /* * prog = array->ptrs[index]; @@ -1348,13 +1337,9 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, /* ltg %r1,prog(%b2,%r1) */ EMIT6_DISP_LH(0xe3000000, 0x0002, REG_1, BPF_REG_2, REG_1, offsetof(struct bpf_array, ptrs)); - if (!is_first_pass(jit) && can_use_rel(jit, jit->labels[0])) { - /* brc 0x8,label0 */ - EMIT4_PCREL_RIC(0xa7040000, 0x8, jit->labels[0]); - } else { - /* brcl 0x8,label0 */ - EMIT6_PCREL_RILC(0xc0040000, 0x8, jit->labels[0]); - } + /* brc 0x8,out */ + patch_3_brc = jit->prg; + EMIT4_PCREL_RIC(0xa7040000, 8, jit->prg); /* * Restore registers before calling function @@ -1371,8 +1356,16 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, /* bc 0xf,tail_call_start(%r1) */ _EMIT4(0x47f01000 + jit->tail_call_start); /* out: */ - jit->labels[0] = jit->prg; + if (jit->prg_buf) { + *(u16 *)(jit->prg_buf + patch_1_clrj + 2) = + (jit->prg - patch_1_clrj) >> 1; + *(u16 *)(jit->prg_buf + patch_2_clij + 2) = + (jit->prg - patch_2_clij) >> 1; + *(u16 *)(jit->prg_buf + patch_3_brc + 2) = + (jit->prg - patch_3_brc) >> 1; + } break; + } case BPF_JMP | BPF_EXIT: /* return b0 */ last = (i == fp->len - 1) ? 1 : 0; if (last) diff --git a/arch/s390/pci/Makefile b/arch/s390/pci/Makefile index b4e3c84772a1..bf557a1b789c 100644 --- a/arch/s390/pci/Makefile +++ b/arch/s390/pci/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_PCI) += pci.o pci_irq.o pci_dma.o pci_clp.o pci_sysfs.o \ pci_event.o pci_debug.o pci_insn.o pci_mmio.o \ pci_bus.o +obj-$(CONFIG_PCI_IOV) += pci_iov.o diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 4b62d6b55024..570016ae8bcd 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -37,6 +37,7 @@ #include <asm/pci_dma.h> #include "pci_bus.h" +#include "pci_iov.h" /* list of all detected zpci devices */ static LIST_HEAD(zpci_list); @@ -226,7 +227,7 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count) zpci_memcpy_toio(to, from, count); } -void __iomem *ioremap(phys_addr_t addr, size_t size) +static void __iomem *__ioremap(phys_addr_t addr, size_t size, pgprot_t prot) { unsigned long offset, vaddr; struct vm_struct *area; @@ -247,14 +248,37 @@ void __iomem *ioremap(phys_addr_t addr, size_t size) return NULL; vaddr = (unsigned long) area->addr; - if (ioremap_page_range(vaddr, vaddr + size, addr, PAGE_KERNEL)) { + if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) { free_vm_area(area); return NULL; } return (void __iomem *) ((unsigned long) area->addr + offset); } + +void __iomem *ioremap_prot(phys_addr_t addr, size_t size, unsigned long prot) +{ + return __ioremap(addr, size, __pgprot(prot)); +} +EXPORT_SYMBOL(ioremap_prot); + +void __iomem *ioremap(phys_addr_t addr, size_t size) +{ + return __ioremap(addr, size, PAGE_KERNEL); +} EXPORT_SYMBOL(ioremap); +void __iomem *ioremap_wc(phys_addr_t addr, size_t size) +{ + return __ioremap(addr, size, pgprot_writecombine(PAGE_KERNEL)); +} +EXPORT_SYMBOL(ioremap_wc); + +void __iomem *ioremap_wt(phys_addr_t addr, size_t size) +{ + return __ioremap(addr, size, pgprot_writethrough(PAGE_KERNEL)); +} +EXPORT_SYMBOL(ioremap_wt); + void iounmap(volatile void __iomem *addr) { if (static_branch_likely(&have_mio)) @@ -390,15 +414,6 @@ static struct pci_ops pci_root_ops = { .write = pci_write, }; -#ifdef CONFIG_PCI_IOV -static struct resource iov_res = { - .name = "PCI IOV res", - .start = 0, - .end = -1, - .flags = IORESOURCE_MEM, -}; -#endif - static void zpci_map_resources(struct pci_dev *pdev) { struct zpci_dev *zdev = to_zpci(pdev); @@ -419,16 +434,7 @@ static void zpci_map_resources(struct pci_dev *pdev) pdev->resource[i].end = pdev->resource[i].start + len - 1; } -#ifdef CONFIG_PCI_IOV - for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { - int bar = i + PCI_IOV_RESOURCES; - - len = pci_resource_len(pdev, bar); - if (!len) - continue; - pdev->resource[bar].parent = &iov_res; - } -#endif + zpci_iov_map_resources(pdev); } static void zpci_unmap_resources(struct pci_dev *pdev) @@ -668,6 +674,10 @@ EXPORT_SYMBOL_GPL(zpci_enable_device); int zpci_disable_device(struct zpci_dev *zdev) { zpci_dma_exit_device(zdev); + /* + * The zPCI function may already be disabled by the platform, this is + * detected in clp_disable_fh() which becomes a no-op. + */ return clp_disable_fh(zdev); } EXPORT_SYMBOL_GPL(zpci_disable_device); @@ -680,7 +690,7 @@ void zpci_remove_device(struct zpci_dev *zdev) pdev = pci_get_slot(zbus->bus, zdev->devfn); if (pdev) { if (pdev->is_virtfn) - return zpci_remove_virtfn(pdev, zdev->vfn); + return zpci_iov_remove_virtfn(pdev, zdev->vfn); pci_stop_and_remove_bus_device_locked(pdev); } } @@ -784,6 +794,9 @@ static int zpci_mem_init(void) if (!zpci_iomap_bitmap) goto error_iomap_bitmap; + if (static_branch_likely(&have_mio)) + clp_setup_writeback_mio(); + return 0; error_iomap_bitmap: kfree(zpci_iomap_start); @@ -881,9 +894,3 @@ out: return rc; } subsys_initcall_sync(pci_base_init); - -void zpci_rescan(void) -{ - if (zpci_is_enabled()) - clp_rescan_pci_devices_simple(NULL); -} diff --git a/arch/s390/pci/pci_bus.c b/arch/s390/pci/pci_bus.c index 5967f3014156..755b46f4c595 100644 --- a/arch/s390/pci/pci_bus.c +++ b/arch/s390/pci/pci_bus.c @@ -24,6 +24,7 @@ #include <asm/pci_dma.h> #include "pci_bus.h" +#include "pci_iov.h" static LIST_HEAD(zbus_list); static DEFINE_SPINLOCK(zbus_list_lock); @@ -126,69 +127,6 @@ static struct zpci_bus *zpci_bus_alloc(int pchid) return zbus; } -#ifdef CONFIG_PCI_IOV -static int zpci_bus_link_virtfn(struct pci_dev *pdev, - struct pci_dev *virtfn, int vfid) -{ - int rc; - - rc = pci_iov_sysfs_link(pdev, virtfn, vfid); - if (rc) - return rc; - - virtfn->is_virtfn = 1; - virtfn->multifunction = 0; - virtfn->physfn = pci_dev_get(pdev); - - return 0; -} - -static int zpci_bus_setup_virtfn(struct zpci_bus *zbus, - struct pci_dev *virtfn, int vfn) -{ - int i, cand_devfn; - struct zpci_dev *zdev; - struct pci_dev *pdev; - int vfid = vfn - 1; /* Linux' vfid's start at 0 vfn at 1*/ - int rc = 0; - - if (!zbus->multifunction) - return 0; - - /* If the parent PF for the given VF is also configured in the - * instance, it must be on the same zbus. - * We can then identify the parent PF by checking what - * devfn the VF would have if it belonged to that PF using the PF's - * stride and offset. Only if this candidate devfn matches the - * actual devfn will we link both functions. - */ - for (i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) { - zdev = zbus->function[i]; - if (zdev && zdev->is_physfn) { - pdev = pci_get_slot(zbus->bus, zdev->devfn); - if (!pdev) - continue; - cand_devfn = pci_iov_virtfn_devfn(pdev, vfid); - if (cand_devfn == virtfn->devfn) { - rc = zpci_bus_link_virtfn(pdev, virtfn, vfid); - /* balance pci_get_slot() */ - pci_dev_put(pdev); - break; - } - /* balance pci_get_slot() */ - pci_dev_put(pdev); - } - } - return rc; -} -#else -static inline int zpci_bus_setup_virtfn(struct zpci_bus *zbus, - struct pci_dev *virtfn, int vfn) -{ - return 0; -} -#endif - void pcibios_bus_add_device(struct pci_dev *pdev) { struct zpci_dev *zdev = to_zpci(pdev); @@ -197,9 +135,10 @@ void pcibios_bus_add_device(struct pci_dev *pdev) * With pdev->no_vf_scan the common PCI probing code does not * perform PF/VF linking. */ - if (zdev->vfn) - zpci_bus_setup_virtfn(zdev->zbus, pdev, zdev->vfn); - + if (zdev->vfn) { + zpci_iov_setup_virtfn(zdev->zbus, pdev, zdev->vfn); + pdev->no_command_memory = 1; + } } static int zpci_bus_add_device(struct zpci_bus *zbus, struct zpci_dev *zdev) diff --git a/arch/s390/pci/pci_bus.h b/arch/s390/pci/pci_bus.h index 4972433df458..f8dfac0b5b71 100644 --- a/arch/s390/pci/pci_bus.h +++ b/arch/s390/pci/pci_bus.h @@ -9,7 +9,6 @@ int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops); void zpci_bus_device_unregister(struct zpci_dev *zdev); -int zpci_bus_init(void); void zpci_release_device(struct kref *kref); static inline void zpci_zdev_put(struct zpci_dev *zdev) @@ -30,15 +29,3 @@ static inline struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus, return (devfn >= ZPCI_FUNCTIONS_PER_BUS) ? NULL : zbus->function[devfn]; } -#ifdef CONFIG_PCI_IOV -static inline void zpci_remove_virtfn(struct pci_dev *pdev, int vfn) -{ - - pci_lock_rescan_remove(); - /* Linux' vfid's start at 0 vfn at 1 */ - pci_iov_remove_virtfn(pdev->physfn, vfn - 1); - pci_unlock_rescan_remove(); -} -#else /* CONFIG_PCI_IOV */ -static inline void zpci_remove_virtfn(struct pci_dev *pdev, int vfn) {} -#endif /* CONFIG_PCI_IOV */ diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index 7e735f41a0a6..153720d21ae7 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c @@ -102,6 +102,7 @@ static void clp_store_query_pci_fngrp(struct zpci_dev *zdev, zdev->msi_addr = response->msia; zdev->max_msi = response->noi; zdev->fmb_update = response->mui; + zdev->version = response->version; switch (response->version) { case 1: @@ -167,6 +168,7 @@ static int clp_store_query_pci_fn(struct zpci_dev *zdev, if (response->util_str_avail) { memcpy(zdev->util_str, response->util_str, sizeof(zdev->util_str)); + zdev->util_str_avail = 1; } zdev->mio_capable = response->mio_addr_avail; for (i = 0; i < PCI_STD_NUM_BARS; i++) { @@ -244,6 +246,7 @@ error: return rc; } +static int clp_refresh_fh(u32 fid); /* * Enable/Disable a given PCI function and update its function handle if * necessary @@ -286,7 +289,41 @@ static int clp_set_pci_fn(struct zpci_dev *zdev, u8 nr_dma_as, u8 command) } else if (!rc && rrb->response.hdr.rsp == CLP_RC_SETPCIFN_ALRDY && rrb->response.fh == 0) { /* Function is already in desired state - update handle */ - rc = clp_rescan_pci_devices_simple(&fid); + rc = clp_refresh_fh(fid); + } + clp_free_block(rrb); + return rc; +} + +int clp_setup_writeback_mio(void) +{ + struct clp_req_rsp_slpc_pci *rrb; + u8 wb_bit_pos; + int rc; + + rrb = clp_alloc_block(GFP_KERNEL); + if (!rrb) + return -ENOMEM; + + memset(rrb, 0, sizeof(*rrb)); + rrb->request.hdr.len = sizeof(rrb->request); + rrb->request.hdr.cmd = CLP_SLPC; + rrb->response.hdr.len = sizeof(rrb->response); + + rc = clp_req(rrb, CLP_LPS_PCI); + if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) { + if (rrb->response.vwb) { + wb_bit_pos = rrb->response.mio_wb; + set_bit_inv(wb_bit_pos, &mio_wb_bit_mask); + zpci_dbg(3, "wb bit: %d\n", wb_bit_pos); + } else { + zpci_dbg(3, "wb bit: n.a.\n"); + } + + } else { + zpci_err("SLPC PCI:\n"); + zpci_err_clp(rrb->response.hdr.rsp, rc); + rc = -EIO; } clp_free_block(rrb); return rc; @@ -374,24 +411,6 @@ static void __clp_add(struct clp_fh_list_entry *entry, void *data) clp_add_pci_device(entry->fid, entry->fh, entry->config_state); } -static void __clp_update(struct clp_fh_list_entry *entry, void *data) -{ - struct zpci_dev *zdev; - u32 *fid = data; - - if (!entry->vendor_id) - return; - - if (fid && *fid != entry->fid) - return; - - zdev = get_zdev_by_fid(entry->fid); - if (!zdev) - return; - - zdev->fh = entry->fh; -} - int clp_scan_pci_devices(void) { struct clp_req_rsp_list_pci *rrb; @@ -407,27 +426,25 @@ int clp_scan_pci_devices(void) return rc; } -int clp_rescan_pci_devices(void) +static void __clp_refresh_fh(struct clp_fh_list_entry *entry, void *data) { - struct clp_req_rsp_list_pci *rrb; - int rc; - - zpci_remove_reserved_devices(); + struct zpci_dev *zdev; + u32 fid = *((u32 *)data); - rrb = clp_alloc_block(GFP_KERNEL); - if (!rrb) - return -ENOMEM; + if (!entry->vendor_id || fid != entry->fid) + return; - rc = clp_list_pci(rrb, NULL, __clp_add); + zdev = get_zdev_by_fid(fid); + if (!zdev) + return; - clp_free_block(rrb); - return rc; + zdev->fh = entry->fh; } -/* Rescan PCI functions and refresh function handles. If fid is non-NULL only - * refresh the handle of the function matching @fid +/* + * Refresh the function handle of the function matching @fid */ -int clp_rescan_pci_devices_simple(u32 *fid) +static int clp_refresh_fh(u32 fid) { struct clp_req_rsp_list_pci *rrb; int rc; @@ -436,7 +453,7 @@ int clp_rescan_pci_devices_simple(u32 *fid) if (!rrb) return -ENOMEM; - rc = clp_list_pci(rrb, fid, __clp_update); + rc = clp_list_pci(rrb, &fid, __clp_refresh_fh); clp_free_block(rrb); return rc; @@ -495,7 +512,7 @@ static int clp_base_command(struct clp_req *req, struct clp_req_hdr *lpcb) } } -static int clp_pci_slpc(struct clp_req *req, struct clp_req_rsp_slpc *lpcb) +static int clp_pci_slpc(struct clp_req *req, struct clp_req_rsp_slpc_pci *lpcb) { unsigned long limit = PAGE_SIZE - sizeof(lpcb->request); diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index 64b1399a73f0..ebc9a49523aa 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c @@ -10,7 +10,7 @@ #include <linux/slab.h> #include <linux/export.h> #include <linux/iommu-helper.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/vmalloc.h> #include <linux/pci.h> #include <asm/pci_dma.h> @@ -261,13 +261,11 @@ static unsigned long __dma_alloc_iommu(struct device *dev, unsigned long start, int size) { struct zpci_dev *zdev = to_zpci(to_pci_dev(dev)); - unsigned long boundary_size; - boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, - PAGE_SIZE) >> PAGE_SHIFT; return iommu_area_alloc(zdev->iommu_bitmap, zdev->iommu_pages, start, size, zdev->start_dma >> PAGE_SHIFT, - boundary_size, 0); + dma_get_seg_boundary_nr_pages(dev, PAGE_SHIFT), + 0); } static dma_addr_t dma_alloc_address(struct device *dev, int size) @@ -670,6 +668,8 @@ const struct dma_map_ops s390_pci_dma_ops = { .unmap_page = s390_dma_unmap_pages, .mmap = dma_common_mmap, .get_sgtable = dma_common_get_sgtable, + .alloc_pages = dma_common_alloc_pages, + .free_pages = dma_common_free_pages, /* dma_supported is unconditionally true without a callback */ }; EXPORT_SYMBOL_GPL(s390_pci_dma_ops); diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c index 9a3a291cad43..d33f21545dfd 100644 --- a/arch/s390/pci/pci_event.c +++ b/arch/s390/pci/pci_event.c @@ -143,6 +143,8 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) zpci_remove_device(zdev); } + zdev->fh = ccdf->fh; + zpci_disable_device(zdev); zdev->state = ZPCI_FN_STATE_STANDBY; if (!clp_get_state(ccdf->fid, &state) && state == ZPCI_FN_STATE_RESERVED) { @@ -150,7 +152,8 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) } break; case 0x0306: /* 0x308 or 0x302 for multiple devices */ - clp_rescan_pci_devices(); + zpci_remove_reserved_devices(); + clp_scan_pci_devices(); break; case 0x0308: /* Standby -> Reserved */ if (!zdev) diff --git a/arch/s390/pci/pci_iov.c b/arch/s390/pci/pci_iov.c new file mode 100644 index 000000000000..ead062bf2b41 --- /dev/null +++ b/arch/s390/pci/pci_iov.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright IBM Corp. 2020 + * + * Author(s): + * Niklas Schnelle <schnelle@linux.ibm.com> + * + */ + +#define KMSG_COMPONENT "zpci" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + +#include <linux/kernel.h> +#include <linux/pci.h> + +#include "pci_iov.h" + +static struct resource iov_res = { + .name = "PCI IOV res", + .start = 0, + .end = -1, + .flags = IORESOURCE_MEM, +}; + +void zpci_iov_map_resources(struct pci_dev *pdev) +{ + resource_size_t len; + int i; + + for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { + int bar = i + PCI_IOV_RESOURCES; + + len = pci_resource_len(pdev, bar); + if (!len) + continue; + pdev->resource[bar].parent = &iov_res; + } +} + +void zpci_iov_remove_virtfn(struct pci_dev *pdev, int vfn) +{ + pci_lock_rescan_remove(); + /* Linux' vfid's start at 0 vfn at 1 */ + pci_iov_remove_virtfn(pdev->physfn, vfn - 1); + pci_unlock_rescan_remove(); +} + +static int zpci_iov_link_virtfn(struct pci_dev *pdev, struct pci_dev *virtfn, int vfid) +{ + int rc; + + rc = pci_iov_sysfs_link(pdev, virtfn, vfid); + if (rc) + return rc; + + virtfn->is_virtfn = 1; + virtfn->multifunction = 0; + virtfn->physfn = pci_dev_get(pdev); + + return 0; +} + +int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn) +{ + int i, cand_devfn; + struct zpci_dev *zdev; + struct pci_dev *pdev; + int vfid = vfn - 1; /* Linux' vfid's start at 0 vfn at 1*/ + int rc = 0; + + if (!zbus->multifunction) + return 0; + + /* If the parent PF for the given VF is also configured in the + * instance, it must be on the same zbus. + * We can then identify the parent PF by checking what + * devfn the VF would have if it belonged to that PF using the PF's + * stride and offset. Only if this candidate devfn matches the + * actual devfn will we link both functions. + */ + for (i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) { + zdev = zbus->function[i]; + if (zdev && zdev->is_physfn) { + pdev = pci_get_slot(zbus->bus, zdev->devfn); + if (!pdev) + continue; + cand_devfn = pci_iov_virtfn_devfn(pdev, vfid); + if (cand_devfn == virtfn->devfn) { + rc = zpci_iov_link_virtfn(pdev, virtfn, vfid); + /* balance pci_get_slot() */ + pci_dev_put(pdev); + break; + } + /* balance pci_get_slot() */ + pci_dev_put(pdev); + } + } + return rc; +} diff --git a/arch/s390/pci/pci_iov.h b/arch/s390/pci/pci_iov.h new file mode 100644 index 000000000000..b2c828003bad --- /dev/null +++ b/arch/s390/pci/pci_iov.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright IBM Corp. 2020 + * + * Author(s): + * Niklas Schnelle <schnelle@linux.ibm.com> + * + */ + +#ifndef __S390_PCI_IOV_H +#define __S390_PCI_IOV_H + +#ifdef CONFIG_PCI_IOV +void zpci_iov_remove_virtfn(struct pci_dev *pdev, int vfn); + +void zpci_iov_map_resources(struct pci_dev *pdev); + +int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn); + +#else /* CONFIG_PCI_IOV */ +static inline void zpci_iov_remove_virtfn(struct pci_dev *pdev, int vfn) {} + +static inline void zpci_iov_map_resources(struct pci_dev *pdev) {} + +static inline int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn) +{ + return 0; +} +#endif /* CONFIG_PCI_IOV */ +#endif /* __S390_PCI_IOV_h */ diff --git a/arch/s390/scripts/Makefile.chkbss b/arch/s390/scripts/Makefile.chkbss deleted file mode 100644 index f4f4c2c6dee9..000000000000 --- a/arch/s390/scripts/Makefile.chkbss +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -chkbss-target ?= built-in.a -$(obj)/$(chkbss-target): chkbss - -chkbss-files := $(addsuffix .chkbss, $(chkbss)) -clean-files += $(chkbss-files) - -PHONY += chkbss -chkbss: $(addprefix $(obj)/, $(chkbss-files)) - -quiet_cmd_chkbss = CHKBSS $< - cmd_chkbss = \ - if ! $(OBJSIZE) --common $< | $(AWK) 'END { if ($$3) exit 1 }'; then \ - echo "error: $< .bss section is not empty" >&2; exit 1; \ - fi; \ - touch $@; - -$(obj)/%.o.chkbss: $(obj)/%.o - $(call cmd,chkbss) diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index d20927128fce..159da4ed578f 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -71,6 +71,7 @@ config SUPERH select PERF_EVENTS select PERF_USE_VMALLOC select RTC_LIB + select SET_FS select SPARSE_IRQ help The SuperH is a RISC processor targeted for use in embedded systems @@ -600,22 +601,6 @@ config PHYSICAL_START where the fail safe kernel needs to run at a different address than the panic-ed kernel. -config SECCOMP - bool "Enable seccomp to safely compute untrusted bytecode" - depends on PROC_FS - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via prctl, it cannot be disabled and the task is only - allowed to execute a few safe syscalls defined by each seccomp - mode. - - If unsure, say N. - config SMP bool "Symmetric multi-processing support" depends on SYS_SUPPORTS_SMP diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index 665cad452798..bac8a058ebd7 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -13,6 +13,7 @@ #include <cpu/sh7723.h> +#include <linux/dma-map-ops.h> #include <linux/clkdev.h> #include <linux/delay.h> #include <linux/device.h> diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index dd427bac5cde..bab91a99124e 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -36,6 +36,7 @@ #include <linux/usb/r8a66597.h> #include <linux/usb/renesas_usbhs.h> #include <linux/videodev2.h> +#include <linux/dma-map-ops.h> #include <media/drv-intf/renesas-ceu.h> #include <media/i2c/mt9t112.h> diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 96538ba3aa32..eeb5ce341efd 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -14,7 +14,6 @@ #include <linux/clkdev.h> #include <linux/delay.h> -#include <linux/dma-mapping.h> #include <linux/gpio.h> #include <linux/gpio/machine.h> #include <linux/i2c.h> @@ -33,6 +32,7 @@ #include <linux/sh_intc.h> #include <linux/usb/r8a66597.h> #include <linux/videodev2.h> +#include <linux/dma-map-ops.h> #include <mach/kfr2r09.h> diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 9ed369dad62d..6703a2122c0d 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -5,7 +5,7 @@ * Copyright (C) 2008 Magnus Damm */ #include <linux/clkdev.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/init.h> #include <linux/platform_device.h> #include <linux/interrupt.h> diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 32f5dd944889..8d6541ba0186 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -32,6 +32,7 @@ #include <linux/smc91x.h> #include <linux/usb/r8a66597.h> #include <linux/videodev2.h> +#include <linux/dma-map-ops.h> #include <mach-se/mach/se7724.h> #include <media/drv-intf/renesas-ceu.h> diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c index d91065e81a4e..bffbe69b2236 100644 --- a/arch/sh/boards/of-generic.c +++ b/arch/sh/boards/of-generic.c @@ -49,7 +49,7 @@ static struct plat_smp_ops dummy_smp_ops = { extern const struct of_cpu_method __cpu_method_of_table[]; const struct of_cpu_method __cpu_method_of_table_sentinel - __section(__cpu_method_of_table_end); + __section("__cpu_method_of_table_end"); static void sh_of_smp_probe(void) { diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index 7be8694c0d13..41e4daee8f04 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c @@ -19,7 +19,7 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/pci.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <asm/io.h> #include <asm/irq.h> diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 6ab0b7377f66..a3903304f33f 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -13,7 +13,6 @@ #include <linux/pci.h> #include <linux/init.h> #include <linux/types.h> -#include <linux/dma-debug.h> #include <linux/io.h> #include <linux/mutex.h> #include <linux/spinlock.h> diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index e0b568aaa701..4468289ab2ca 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -12,6 +12,7 @@ #include <linux/io.h> #include <linux/async.h> #include <linux/delay.h> +#include <linux/dma-mapping.h> #include <linux/slab.h> #include <linux/clk.h> #include <linux/sh_clk.h> @@ -31,6 +32,8 @@ struct sh7786_pcie_port { static struct sh7786_pcie_port *sh7786_pcie_ports; static unsigned int nr_ports; static unsigned long dma_pfn_offset; +size_t memsize; +u64 memstart; static struct sh7786_pcie_hwops { int (*core_init)(void); @@ -301,7 +304,6 @@ static int __init pcie_init(struct sh7786_pcie_port *port) struct pci_channel *chan = port->hose; unsigned int data; phys_addr_t memstart, memend; - size_t memsize; int ret, i, win; /* Begin initialization */ @@ -368,8 +370,6 @@ static int __init pcie_init(struct sh7786_pcie_port *port) memstart = ALIGN_DOWN(memstart, memsize); memsize = roundup_pow_of_two(memend - memstart); - dma_pfn_offset = memstart >> PAGE_SHIFT; - /* * If there's more than 512MB of memory, we need to roll over to * LAR1/LAMR1. @@ -487,7 +487,8 @@ int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) void pcibios_bus_add_device(struct pci_dev *pdev) { - pdev->dev.dma_pfn_offset = dma_pfn_offset; + dma_direct_set_offset(&pdev->dev, __pa(memory_start), + __pa(memory_start) - memstart, memsize); } static int __init sh7786_pcie_core_init(void) diff --git a/arch/sh/include/asm/cache.h b/arch/sh/include/asm/cache.h index a293343456af..32dfa6b82ec6 100644 --- a/arch/sh/include/asm/cache.h +++ b/arch/sh/include/asm/cache.h @@ -14,7 +14,7 @@ #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) -#define __read_mostly __attribute__((__section__(".data..read_mostly"))) +#define __read_mostly __section(".data..read_mostly") #ifndef __ASSEMBLY__ struct cache_info { diff --git a/arch/sh/include/asm/checksum_32.h b/arch/sh/include/asm/checksum_32.h index 91571a42e44e..1a391e3a7659 100644 --- a/arch/sh/include/asm/checksum_32.h +++ b/arch/sh/include/asm/checksum_32.h @@ -30,10 +30,9 @@ asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum); * better 64-bit) boundary */ -asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, - int len, __wsum sum, - int *src_err_ptr, int *dst_err_ptr); +asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, int len); +#define _HAVE_ARCH_CSUM_AND_COPY /* * Note: when you get a NULL pointer exception here this means someone * passed in an incorrect kernel address to one of these functions. @@ -42,23 +41,18 @@ asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, * access_ok(). */ static inline -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) +__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len) { - return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL); + return csum_partial_copy_generic(src, dst, len); } #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER static inline -__wsum csum_and_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) +__wsum csum_and_copy_from_user(const void __user *src, void *dst, int len) { - if (access_ok(src, len)) - return csum_partial_copy_generic((__force const void *)src, dst, - len, sum, err_ptr, NULL); - if (len) - *err_ptr = -EFAULT; - return sum; + if (!access_ok(src, len)) + return 0; + return csum_partial_copy_generic((__force const void *)src, dst, len); } /* @@ -199,16 +193,10 @@ static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, #define HAVE_CSUM_COPY_USER static inline __wsum csum_and_copy_to_user(const void *src, void __user *dst, - int len, __wsum sum, - int *err_ptr) + int len) { - if (access_ok(dst, len)) - return csum_partial_copy_generic((__force const void *)src, - dst, len, sum, NULL, err_ptr); - - if (len) - *err_ptr = -EFAULT; - - return (__force __wsum)-1; /* invalid checksum */ + if (!access_ok(dst, len)) + return 0; + return csum_partial_copy_generic((__force const void *)src, dst, len); } #endif /* __ASM_SH_CHECKSUM_H */ diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h index f7d05546beca..2b4b085e8f21 100644 --- a/arch/sh/include/asm/machvec.h +++ b/arch/sh/include/asm/machvec.h @@ -36,6 +36,6 @@ extern struct sh_machine_vector sh_mv; #define get_system_type() sh_mv.mv_name #define __initmv \ - __used __section(.machvec.init) + __used __section(".machvec.init") #endif /* _ASM_SH_MACHVEC_H */ diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h index 1a0d7cf71c10..199381f77293 100644 --- a/arch/sh/include/asm/smp.h +++ b/arch/sh/include/asm/smp.h @@ -8,7 +8,6 @@ #ifdef CONFIG_SMP -#include <linux/spinlock.h> #include <linux/atomic.h> #include <asm/current.h> #include <asm/percpu.h> @@ -72,7 +71,7 @@ struct of_cpu_method { #define CPU_METHOD_OF_DECLARE(name, _method, _ops) \ static const struct of_cpu_method __cpu_method_of_table_##name \ - __used __section(__cpu_method_of_table) \ + __used __section("__cpu_method_of_table") \ = { .method = _method, .ops = _ops } #else diff --git a/arch/sh/kernel/dma-coherent.c b/arch/sh/kernel/dma-coherent.c index cd46a9825e3c..6a44c0e7ba40 100644 --- a/arch/sh/kernel/dma-coherent.c +++ b/arch/sh/kernel/dma-coherent.c @@ -3,7 +3,7 @@ * Copyright (C) 2004 - 2007 Paul Mundt */ #include <linux/mm.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <asm/cacheflush.h> #include <asm/addrspace.h> diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index ad963104d22d..91ab2607a1ff 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -370,7 +370,6 @@ syscall_trace_entry: nop cmp/eq #-1, r0 bt syscall_exit - mov.l r0, @(OFF_R0,r15) ! Save return value ! Reload R0-R4 from kernel stack, where the ! parent may have modified them using ! ptrace(POKEUSR). (Note that R0-R2 are diff --git a/arch/sh/kernel/kprobes.c b/arch/sh/kernel/kprobes.c index 318296f48f1a..756100b01e84 100644 --- a/arch/sh/kernel/kprobes.c +++ b/arch/sh/kernel/kprobes.c @@ -204,6 +204,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) { ri->ret_addr = (kprobe_opcode_t *) regs->pr; + ri->fp = NULL; /* Replace the return addr with trampoline addr */ regs->pr = (unsigned long)kretprobe_trampoline; @@ -302,62 +303,9 @@ static void __used kretprobe_trampoline_holder(void) */ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *tmp; - unsigned long flags, orig_ret_address = 0; - unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; + regs->pc = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); - INIT_HLIST_HEAD(&empty_rp); - kretprobe_hash_lock(current, &head, &flags); - - /* - * It is possible to have multiple instances associated with a given - * task either because an multiple functions in the call path - * have a return probe installed on them, and/or more then one return - * return probe was registered for a target function. - * - * We can handle this because: - * - instances are always inserted at the head of the list - * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the - * real return address, and all the rest will point to - * kretprobe_trampoline - */ - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - if (ri->rp && ri->rp->handler) { - __this_cpu_write(current_kprobe, &ri->rp->kp); - ri->rp->handler(ri, regs); - __this_cpu_write(current_kprobe, NULL); - } - - orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_assert(ri, orig_ret_address, trampoline_address); - - regs->pc = orig_ret_address; - kretprobe_hash_unlock(current, &flags); - - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } - - return orig_ret_address; + return 1; } static int __kprobes post_kprobe_handler(struct pt_regs *regs) diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index b05bf92f9c32..5281685f6ad1 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -455,16 +455,11 @@ long arch_ptrace(struct task_struct *child, long request, asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { - long ret = 0; - if (test_thread_flag(TIF_SYSCALL_TRACE) && - tracehook_report_syscall_entry(regs)) - /* - * Tracing decided this syscall should not happen. - * We'll return a bogus call number to get an ENOSYS - * error, but leave the original number in regs->regs[0]. - */ - ret = -1L; + tracehook_report_syscall_entry(regs)) { + regs->regs[0] = -ENOSYS; + return -1; + } if (secure_computing() == -1) return -1; @@ -475,7 +470,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) audit_syscall_entry(regs->regs[3], regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); - return ret ?: regs->regs[0]; + return 0; } asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index 4fe3f00137bc..1add47fd31f6 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c @@ -502,8 +502,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0, if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs, save_r0); - if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); + if (thread_info_flags & _TIF_NOTIFY_RESUME) tracehook_notify_resume(regs); - } } diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl index ae0a00beea5f..783738448ff5 100644 --- a/arch/sh/kernel/syscalls/syscall.tbl +++ b/arch/sh/kernel/syscalls/syscall.tbl @@ -442,3 +442,4 @@ 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 +440 common process_madvise sys_process_madvise diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index bde7a6c01aaf..3161b9ccd2a5 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -76,6 +76,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + ELF_DETAILS DISCARDS } diff --git a/arch/sh/lib/checksum.S b/arch/sh/lib/checksum.S index 97b5c2d9fec4..3e07074e0098 100644 --- a/arch/sh/lib/checksum.S +++ b/arch/sh/lib/checksum.S @@ -173,47 +173,27 @@ ENTRY(csum_partial) mov r6, r0 /* -unsigned int csum_partial_copy_generic (const char *src, char *dst, int len, - int sum, int *src_err_ptr, int *dst_err_ptr) +unsigned int csum_partial_copy_generic (const char *src, char *dst, int len) */ /* - * Copy from ds while checksumming, otherwise like csum_partial - * - * The macros SRC and DST specify the type of access for the instruction. - * thus we can call a custom exception handler for all access types. - * - * FIXME: could someone double-check whether I haven't mixed up some SRC and - * DST definitions? It's damn hard to trigger all cases. I hope I got - * them all but there's no guarantee. + * Copy from ds while checksumming, otherwise like csum_partial with initial + * sum being ~0U */ -#define SRC(...) \ +#define EXC(...) \ 9999: __VA_ARGS__ ; \ .section __ex_table, "a"; \ .long 9999b, 6001f ; \ .previous -#define DST(...) \ - 9999: __VA_ARGS__ ; \ - .section __ex_table, "a"; \ - .long 9999b, 6002f ; \ - .previous - ! ! r4: const char *SRC ! r5: char *DST ! r6: int LEN -! r7: int SUM -! -! on stack: -! int *SRC_ERR_PTR -! int *DST_ERR_PTR ! ENTRY(csum_partial_copy_generic) - mov.l r5,@-r15 - mov.l r6,@-r15 - + mov #-1,r7 mov #3,r0 ! Check src and dest are equally aligned mov r4,r1 and r0,r1 @@ -243,11 +223,11 @@ ENTRY(csum_partial_copy_generic) clrt .align 2 5: -SRC( mov.b @r4+,r1 ) -SRC( mov.b @r4+,r0 ) +EXC( mov.b @r4+,r1 ) +EXC( mov.b @r4+,r0 ) extu.b r1,r1 -DST( mov.b r1,@r5 ) -DST( mov.b r0,@(1,r5) ) +EXC( mov.b r1,@r5 ) +EXC( mov.b r0,@(1,r5) ) extu.b r0,r0 add #2,r5 @@ -276,8 +256,8 @@ DST( mov.b r0,@(1,r5) ) ! Handle first two bytes as a special case .align 2 1: -SRC( mov.w @r4+,r0 ) -DST( mov.w r0,@r5 ) +EXC( mov.w @r4+,r0 ) +EXC( mov.w r0,@r5 ) add #2,r5 extu.w r0,r0 addc r0,r7 @@ -292,32 +272,32 @@ DST( mov.w r0,@r5 ) clrt .align 2 1: -SRC( mov.l @r4+,r0 ) -SRC( mov.l @r4+,r1 ) +EXC( mov.l @r4+,r0 ) +EXC( mov.l @r4+,r1 ) addc r0,r7 -DST( mov.l r0,@r5 ) -DST( mov.l r1,@(4,r5) ) +EXC( mov.l r0,@r5 ) +EXC( mov.l r1,@(4,r5) ) addc r1,r7 -SRC( mov.l @r4+,r0 ) -SRC( mov.l @r4+,r1 ) +EXC( mov.l @r4+,r0 ) +EXC( mov.l @r4+,r1 ) addc r0,r7 -DST( mov.l r0,@(8,r5) ) -DST( mov.l r1,@(12,r5) ) +EXC( mov.l r0,@(8,r5) ) +EXC( mov.l r1,@(12,r5) ) addc r1,r7 -SRC( mov.l @r4+,r0 ) -SRC( mov.l @r4+,r1 ) +EXC( mov.l @r4+,r0 ) +EXC( mov.l @r4+,r1 ) addc r0,r7 -DST( mov.l r0,@(16,r5) ) -DST( mov.l r1,@(20,r5) ) +EXC( mov.l r0,@(16,r5) ) +EXC( mov.l r1,@(20,r5) ) addc r1,r7 -SRC( mov.l @r4+,r0 ) -SRC( mov.l @r4+,r1 ) +EXC( mov.l @r4+,r0 ) +EXC( mov.l @r4+,r1 ) addc r0,r7 -DST( mov.l r0,@(24,r5) ) -DST( mov.l r1,@(28,r5) ) +EXC( mov.l r0,@(24,r5) ) +EXC( mov.l r1,@(28,r5) ) addc r1,r7 add #32,r5 movt r0 @@ -335,9 +315,9 @@ DST( mov.l r1,@(28,r5) ) clrt shlr2 r6 3: -SRC( mov.l @r4+,r0 ) +EXC( mov.l @r4+,r0 ) addc r0,r7 -DST( mov.l r0,@r5 ) +EXC( mov.l r0,@r5 ) add #4,r5 movt r0 dt r6 @@ -353,8 +333,8 @@ DST( mov.l r0,@r5 ) mov #2,r1 cmp/hs r1,r6 bf 5f -SRC( mov.w @r4+,r0 ) -DST( mov.w r0,@r5 ) +EXC( mov.w @r4+,r0 ) +EXC( mov.w r0,@r5 ) extu.w r0,r0 add #2,r5 cmp/eq r1,r6 @@ -363,8 +343,8 @@ DST( mov.w r0,@r5 ) shll16 r0 addc r0,r7 5: -SRC( mov.b @r4+,r0 ) -DST( mov.b r0,@r5 ) +EXC( mov.b @r4+,r0 ) +EXC( mov.b r0,@r5 ) extu.b r0,r0 #ifndef __LITTLE_ENDIAN__ shll8 r0 @@ -373,42 +353,13 @@ DST( mov.b r0,@r5 ) mov #0,r0 addc r0,r7 7: -5000: # Exception handler: .section .fixup, "ax" 6001: - mov.l @(8,r15),r0 ! src_err_ptr - mov #-EFAULT,r1 - mov.l r1,@r0 - - ! zero the complete destination - computing the rest - ! is too much work - mov.l @(4,r15),r5 ! dst - mov.l @r15,r6 ! len - mov #0,r7 -1: mov.b r7,@r5 - dt r6 - bf/s 1b - add #1,r5 - mov.l 8000f,r0 - jmp @r0 - nop - .align 2 -8000: .long 5000b - -6002: - mov.l @(12,r15),r0 ! dst_err_ptr - mov #-EFAULT,r1 - mov.l r1,@r0 - mov.l 8001f,r0 - jmp @r0 - nop - .align 2 -8001: .long 5000b - + rts + mov #0,r0 .previous - add #8,r15 rts mov r7,r0 diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 4735176ab811..3348e0c4d769 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -226,15 +226,12 @@ void __init allocate_pgdat(unsigned int nid) static void __init do_init_bootmem(void) { - struct memblock_region *reg; + unsigned long start_pfn, end_pfn; + int i; /* Add active regions with valid PFNs. */ - for_each_memblock(memory, reg) { - unsigned long start_pfn, end_pfn; - start_pfn = memblock_region_memory_base_pfn(reg); - end_pfn = memblock_region_memory_end_pfn(reg); + for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, NULL) __add_active_range(0, start_pfn, end_pfn); - } /* All of system RAM sits in node 0 for the non-NUMA case */ allocate_pgdat(0); diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index efeff2c896a5..a6ca135442f9 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -23,6 +23,7 @@ config SPARC select HAVE_OPROFILE select HAVE_ARCH_KGDB if !SMP || SPARC64 select HAVE_ARCH_TRACEHOOK + select HAVE_ARCH_SECCOMP if SPARC64 select HAVE_EXIT_THREAD select HAVE_PCI select SYSCTL_EXCEPTION_TRACE @@ -43,12 +44,14 @@ config SPARC select GENERIC_STRNLEN_USER select MODULES_USE_ELF_RELA select PCI_SYSCALL if PCI + select PCI_MSI_ARCH_FALLBACKS if PCI_MSI select ODD_RT_SIGACTION select OLD_SIGSUSPEND select CPU_NO_EFFICIENT_FFS select LOCKDEP_SMALL if LOCKDEP select NEED_DMA_MAP_STATE select NEED_SG_DMA_LENGTH + select SET_FS config SPARC32 def_bool !64BIT @@ -226,23 +229,6 @@ config EARLYFB help Say Y here to enable a faster early framebuffer boot console. -config SECCOMP - bool "Enable seccomp to safely compute untrusted bytecode" - depends on SPARC64 && PROC_FS - default y - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via /proc/<pid>/seccomp, it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - - If unsure, say Y. Only embedded should say N here. - config HOTPLUG_CPU bool "Support for hot-pluggable CPUs" depends on SPARC64 && SMP diff --git a/arch/sparc/include/asm/cache.h b/arch/sparc/include/asm/cache.h index dcfd58118c11..e62fd0e72606 100644 --- a/arch/sparc/include/asm/cache.h +++ b/arch/sparc/include/asm/cache.h @@ -21,6 +21,6 @@ #define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT) -#define __read_mostly __attribute__((__section__(".data..read_mostly"))) +#define __read_mostly __section(".data..read_mostly") #endif /* !(_SPARC_CACHE_H) */ diff --git a/arch/sparc/include/asm/checksum.h b/arch/sparc/include/asm/checksum.h index a6256cb6fc5c..f2ac13323b6d 100644 --- a/arch/sparc/include/asm/checksum.h +++ b/arch/sparc/include/asm/checksum.h @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_CHECKSUM_H #define ___ASM_SPARC_CHECKSUM_H +#define _HAVE_ARCH_CSUM_AND_COPY #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER +#define HAVE_CSUM_COPY_USER #if defined(__sparc__) && defined(__arch64__) #include <asm/checksum_64.h> #else diff --git a/arch/sparc/include/asm/checksum_32.h b/arch/sparc/include/asm/checksum_32.h index 479a0b812af5..ce11e0ad80c7 100644 --- a/arch/sparc/include/asm/checksum_32.h +++ b/arch/sparc/include/asm/checksum_32.h @@ -42,7 +42,7 @@ __wsum csum_partial(const void *buff, int len, __wsum sum); unsigned int __csum_partial_copy_sparc_generic (const unsigned char *, unsigned char *); static inline __wsum -csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) +csum_partial_copy_nocheck(const void *src, void *dst, int len) { register unsigned int ret asm("o0") = (unsigned int)src; register char *d asm("o1") = dst; @@ -50,9 +50,9 @@ csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) __asm__ __volatile__ ( "call __csum_partial_copy_sparc_generic\n\t" - " mov %6, %%g7\n" + " mov -1, %%g7\n" : "=&r" (ret), "=&r" (d), "=&r" (l) - : "0" (ret), "1" (d), "2" (l), "r" (sum) + : "0" (ret), "1" (d), "2" (l) : "o2", "o3", "o4", "o5", "o7", "g2", "g3", "g4", "g5", "g7", "memory", "cc"); @@ -60,65 +60,19 @@ csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) } static inline __wsum -csum_and_copy_from_user(const void __user *src, void *dst, int len, - __wsum sum, int *err) - { - register unsigned long ret asm("o0") = (unsigned long)src; - register char *d asm("o1") = dst; - register int l asm("g1") = len; - register __wsum s asm("g7") = sum; - - if (unlikely(!access_ok(src, len))) { - if (len) - *err = -EFAULT; - return sum; - } - - __asm__ __volatile__ ( - ".section __ex_table,#alloc\n\t" - ".align 4\n\t" - ".word 1f,2\n\t" - ".previous\n" - "1:\n\t" - "call __csum_partial_copy_sparc_generic\n\t" - " st %8, [%%sp + 64]\n" - : "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s) - : "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err) - : "o2", "o3", "o4", "o5", "o7", "g2", "g3", "g4", "g5", - "cc", "memory"); - return (__force __wsum)ret; +csum_and_copy_from_user(const void __user *src, void *dst, int len) +{ + if (unlikely(!access_ok(src, len))) + return 0; + return csum_partial_copy_nocheck((__force void *)src, dst, len); } -#define HAVE_CSUM_COPY_USER - static inline __wsum -csum_and_copy_to_user(const void *src, void __user *dst, int len, - __wsum sum, int *err) +csum_and_copy_to_user(const void *src, void __user *dst, int len) { - if (!access_ok(dst, len)) { - *err = -EFAULT; - return sum; - } else { - register unsigned long ret asm("o0") = (unsigned long)src; - register char __user *d asm("o1") = dst; - register int l asm("g1") = len; - register __wsum s asm("g7") = sum; - - __asm__ __volatile__ ( - ".section __ex_table,#alloc\n\t" - ".align 4\n\t" - ".word 1f,1\n\t" - ".previous\n" - "1:\n\t" - "call __csum_partial_copy_sparc_generic\n\t" - " st %8, [%%sp + 64]\n" - : "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s) - : "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err) - : "o2", "o3", "o4", "o5", "o7", - "g2", "g3", "g4", "g5", - "cc", "memory"); - return (__force __wsum)ret; - } + if (!access_ok(dst, len)) + return 0; + return csum_partial_copy_nocheck(src, (__force void *)dst, len); } /* ihl is always 5 or greater, almost always is 5, and iph is word aligned diff --git a/arch/sparc/include/asm/checksum_64.h b/arch/sparc/include/asm/checksum_64.h index 0fa4433f5662..d6b59461e064 100644 --- a/arch/sparc/include/asm/checksum_64.h +++ b/arch/sparc/include/asm/checksum_64.h @@ -38,42 +38,9 @@ __wsum csum_partial(const void * buff, int len, __wsum sum); * here even more important to align src and dst on a 32-bit (or even * better 64-bit) boundary */ -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum); - -long __csum_partial_copy_from_user(const void __user *src, - void *dst, int len, - __wsum sum); - -static inline __wsum -csum_and_copy_from_user(const void __user *src, - void *dst, int len, - __wsum sum, int *err) -{ - long ret = __csum_partial_copy_from_user(src, dst, len, sum); - if (ret < 0) - *err = -EFAULT; - return (__force __wsum) ret; -} - -/* - * Copy and checksum to user - */ -#define HAVE_CSUM_COPY_USER -long __csum_partial_copy_to_user(const void *src, - void __user *dst, int len, - __wsum sum); - -static inline __wsum -csum_and_copy_to_user(const void *src, - void __user *dst, int len, - __wsum sum, int *err) -{ - long ret = __csum_partial_copy_to_user(src, dst, len, sum); - if (ret < 0) - *err = -EFAULT; - return (__force __wsum) ret; -} +__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len); +__wsum csum_and_copy_from_user(const void __user *src, void *dst, int len); +__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len); /* ihl is always 5 or greater, almost always is 5, and iph is word aligned * the majority of the time. diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h index 40a267b3bd52..b85842cda99f 100644 --- a/arch/sparc/include/asm/compat.h +++ b/arch/sparc/include/asm/compat.h @@ -21,8 +21,7 @@ typedef s16 compat_nlink_t; typedef u16 compat_ipc_pid_t; typedef u32 compat_caddr_t; typedef __kernel_fsid_t compat_fsid_t; -typedef s64 compat_s64; -typedef u64 compat_u64; + struct compat_stat { compat_dev_t st_dev; compat_ino_t st_ino; diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h index 9a52d9506f80..549f0a72280d 100644 --- a/arch/sparc/include/asm/io_32.h +++ b/arch/sparc/include/asm/io_32.h @@ -11,6 +11,13 @@ #define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz) #define memcpy_toio(d,s,sz) _memcpy_toio(d,s,sz) +/* + * Bus number may be embedded in the higher bits of the physical address. + * This is why we have no bus number argument to ioremap(). + */ +void __iomem *ioremap(phys_addr_t offset, size_t size); +void iounmap(volatile void __iomem *addr); + #include <asm-generic/io.h> static inline void _memset_io(volatile void __iomem *dst, @@ -121,14 +128,6 @@ static inline void sbus_memcpy_toio(volatile void __iomem *dst, } } -#ifdef __KERNEL__ - -/* - * Bus number may be embedded in the higher bits of the physical address. - * This is why we have no bus number argument to ioremap(). - */ -void __iomem *ioremap(phys_addr_t offset, size_t size); -void iounmap(volatile void __iomem *addr); /* Create a virtual mapping cookie for an IO port range */ void __iomem *ioport_map(unsigned long port, unsigned int nr); void ioport_unmap(void __iomem *); @@ -148,8 +147,6 @@ static inline int sbus_can_burst64(void) struct device; void sbus_set_sbus64(struct device *, int); -#endif - #define __ARCH_HAS_NO_PAGE_ZERO_MAPPED 1 diff --git a/arch/sparc/kernel/btext.c b/arch/sparc/kernel/btext.c index 5869773f3dc4..e2d3f0d2971f 100644 --- a/arch/sparc/kernel/btext.c +++ b/arch/sparc/kernel/btext.c @@ -24,7 +24,7 @@ static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb); static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb); static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb); -#define __force_data __attribute__((__section__(".data"))) +#define __force_data __section(".data") static int g_loc_X __force_data; static int g_loc_Y __force_data; diff --git a/arch/sparc/kernel/iommu-common.c b/arch/sparc/kernel/iommu-common.c index 59cb16691322..23ca75f09277 100644 --- a/arch/sparc/kernel/iommu-common.c +++ b/arch/sparc/kernel/iommu-common.c @@ -166,13 +166,6 @@ unsigned long iommu_tbl_range_alloc(struct device *dev, } } - if (dev) - boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, - 1 << iommu->table_shift); - else - boundary_size = ALIGN(1ULL << 32, 1 << iommu->table_shift); - - boundary_size = boundary_size >> iommu->table_shift; /* * if the skip_span_boundary_check had been set during init, we set * things up so that iommu_is_span_boundary() merely checks if the @@ -181,6 +174,9 @@ unsigned long iommu_tbl_range_alloc(struct device *dev, if ((iommu->flags & IOMMU_NO_SPAN_BOUND) != 0) { shift = 0; boundary_size = iommu->poolsize * iommu->nr_pools; + } else { + boundary_size = dma_get_seg_boundary_nr_pages(dev, + iommu->table_shift); } n = iommu_area_alloc(iommu->map, limit, start, npages, shift, boundary_size, align_mask); diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index 4ae7388b1bff..a034f571d869 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c @@ -10,7 +10,7 @@ #include <linux/slab.h> #include <linux/delay.h> #include <linux/device.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/errno.h> #include <linux/iommu-helper.h> #include <linux/bitmap.h> @@ -472,8 +472,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, outs->dma_length = 0; max_seg_size = dma_get_max_seg_size(dev); - seg_boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, - IO_PAGE_SIZE) >> IO_PAGE_SHIFT; + seg_boundary_size = dma_get_seg_boundary_nr_pages(dev, IO_PAGE_SHIFT); base_shift = iommu->tbl.table_map_base >> IO_PAGE_SHIFT; for_each_sg(sglist, s, nelems, i) { unsigned long paddr, npages, entry, out_entry = 0, slen; diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index d6874c9b639f..8e1d72a16759 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -38,7 +38,7 @@ #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/scatterlist.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <linux/of_device.h> #include <asm/io.h> diff --git a/arch/sparc/kernel/kprobes.c b/arch/sparc/kernel/kprobes.c index dfbca2470536..217c21a6986a 100644 --- a/arch/sparc/kernel/kprobes.c +++ b/arch/sparc/kernel/kprobes.c @@ -453,6 +453,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) { ri->ret_addr = (kprobe_opcode_t *)(regs->u_regs[UREG_RETPC] + 8); + ri->fp = NULL; /* Replace the return addr with trampoline addr */ regs->u_regs[UREG_RETPC] = @@ -465,58 +466,12 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, static int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *tmp; - unsigned long flags, orig_ret_address = 0; - unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; + unsigned long orig_ret_address = 0; - INIT_HLIST_HEAD(&empty_rp); - kretprobe_hash_lock(current, &head, &flags); - - /* - * It is possible to have multiple instances associated with a given - * task either because an multiple functions in the call path - * have a return probe installed on them, and/or more than one return - * return probe was registered for a target function. - * - * We can handle this because: - * - instances are always inserted at the head of the list - * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the - * real return address, and all the rest will point to - * kretprobe_trampoline - */ - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - if (ri->rp && ri->rp->handler) - ri->rp->handler(ri, regs); - - orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_assert(ri, orig_ret_address, trampoline_address); + orig_ret_address = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); regs->tpc = orig_ret_address; regs->tnpc = orig_ret_address + 4; - kretprobe_hash_unlock(current, &flags); - - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } /* * By returning a non-zero value, we are telling * kprobe_handler() that we don't want the post_handler diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 14b93c5564e3..9de57e88f7a1 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -16,6 +16,7 @@ #include <linux/export.h> #include <linux/log2.h> #include <linux/of_device.h> +#include <linux/dma-map-ops.h> #include <asm/iommu-common.h> #include <asm/iommu.h> @@ -508,8 +509,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, iommu_batch_start(dev, prot, ~0UL); max_seg_size = dma_get_max_seg_size(dev); - seg_boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, - IO_PAGE_SIZE) >> IO_PAGE_SHIFT; + seg_boundary_size = dma_get_seg_boundary_nr_pages(dev, IO_PAGE_SHIFT); mask = *dev->dma_mask; if (!iommu_use_atu(iommu, mask)) diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 5234b5ccc0b9..0442ab00518d 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -25,7 +25,7 @@ asmlinkage long sparc_fork(struct pt_regs *regs) .stack = regs->u_regs[UREG_FP], }; - ret = _do_fork(&args); + ret = kernel_clone(&args); /* If we get an error and potentially restart the system * call, we're screwed because copy_thread() clobbered @@ -50,7 +50,7 @@ asmlinkage long sparc_vfork(struct pt_regs *regs) .stack = regs->u_regs[UREG_FP], }; - ret = _do_fork(&args); + ret = kernel_clone(&args); /* If we get an error and potentially restart the system * call, we're screwed because copy_thread() clobbered @@ -96,7 +96,7 @@ asmlinkage long sparc_clone(struct pt_regs *regs) else args.stack = regs->u_regs[UREG_FP]; - ret = _do_fork(&args); + ret = kernel_clone(&args); /* If we get an error and potentially restart the system * call, we're screwed because copy_thread() clobbered diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index d0e0025ee3ba..741d0701003a 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -523,10 +523,8 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, { if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs, orig_i0); - if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); + if (thread_info_flags & _TIF_NOTIFY_RESUME) tracehook_notify_resume(regs); - } } asmlinkage int do_sys_sigstack(struct sigstack __user *ssptr, diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 255264bcb46a..f7ef7edcd5c1 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -551,10 +551,8 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long uprobe_notify_resume(regs); if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs, orig_i0); - if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); + if (thread_info_flags & _TIF_NOTIFY_RESUME) tracehook_notify_resume(regs); - } user_enter(); } diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index e286e2badc8a..e38d8bf454e8 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -1039,38 +1039,9 @@ void smp_fetch_global_pmu(void) * are flush_tlb_*() routines, and these run after flush_cache_*() * which performs the flushw. * - * The SMP TLB coherency scheme we use works as follows: - * - * 1) mm->cpu_vm_mask is a bit mask of which cpus an address - * space has (potentially) executed on, this is the heuristic - * we use to avoid doing cross calls. - * - * Also, for flushing from kswapd and also for clones, we - * use cpu_vm_mask as the list of cpus to make run the TLB. - * - * 2) TLB context numbers are shared globally across all processors - * in the system, this allows us to play several games to avoid - * cross calls. - * - * One invariant is that when a cpu switches to a process, and - * that processes tsk->active_mm->cpu_vm_mask does not have the - * current cpu's bit set, that tlb context is flushed locally. - * - * If the address space is non-shared (ie. mm->count == 1) we avoid - * cross calls when we want to flush the currently running process's - * tlb state. This is done by clearing all cpu bits except the current - * processor's in current->mm->cpu_vm_mask and performing the - * flush locally only. This will force any subsequent cpus which run - * this task to flush the context from the local tlb if the process - * migrates to another cpu (again). - * - * 3) For shared address spaces (threads) and swapping we bite the - * bullet for most cases and perform the cross call (but only to - * the cpus listed in cpu_vm_mask). - * - * The performance gain from "optimizing" away the cross call for threads is - * questionable (in theory the big win for threads is the massive sharing of - * address space state across processors). + * mm->cpu_vm_mask is a bit mask of which cpus an address + * space has (potentially) executed on, this is the heuristic + * we use to limit cross calls. */ /* This currently is only used by the hugetlb arch pre-fault @@ -1080,18 +1051,13 @@ void smp_fetch_global_pmu(void) void smp_flush_tlb_mm(struct mm_struct *mm) { u32 ctx = CTX_HWBITS(mm->context); - int cpu = get_cpu(); - if (atomic_read(&mm->mm_users) == 1) { - cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); - goto local_flush_and_out; - } + get_cpu(); smp_cross_call_masked(&xcall_flush_tlb_mm, ctx, 0, 0, mm_cpumask(mm)); -local_flush_and_out: __flush_tlb_mm(ctx, SECONDARY_CONTEXT); put_cpu(); @@ -1114,17 +1080,15 @@ void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long { u32 ctx = CTX_HWBITS(mm->context); struct tlb_pending_info info; - int cpu = get_cpu(); + + get_cpu(); info.ctx = ctx; info.nr = nr; info.vaddrs = vaddrs; - if (mm == current->mm && atomic_read(&mm->mm_users) == 1) - cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); - else - smp_call_function_many(mm_cpumask(mm), tlb_pending_func, - &info, 1); + smp_call_function_many(mm_cpumask(mm), tlb_pending_func, + &info, 1); __flush_tlb_pending(ctx, nr, vaddrs); @@ -1134,14 +1098,13 @@ void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr) { unsigned long context = CTX_HWBITS(mm->context); - int cpu = get_cpu(); - if (mm == current->mm && atomic_read(&mm->mm_users) == 1) - cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); - else - smp_cross_call_masked(&xcall_flush_tlb_page, - context, vaddr, 0, - mm_cpumask(mm)); + get_cpu(); + + smp_cross_call_masked(&xcall_flush_tlb_page, + context, vaddr, 0, + mm_cpumask(mm)); + __flush_tlb_page(context, vaddr); put_cpu(); diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl index 4af114e84f20..78160260991b 100644 --- a/arch/sparc/kernel/syscalls/syscall.tbl +++ b/arch/sparc/kernel/syscalls/syscall.tbl @@ -38,7 +38,7 @@ 23 64 setuid sys_setuid 24 32 getuid sys_getuid16 24 64 getuid sys_getuid -25 common vmsplice sys_vmsplice compat_sys_vmsplice +25 common vmsplice sys_vmsplice 26 common ptrace sys_ptrace compat_sys_ptrace 27 common alarm sys_alarm 28 common sigaltstack sys_sigaltstack compat_sys_sigaltstack @@ -149,8 +149,8 @@ 117 common getrusage sys_getrusage compat_sys_getrusage 118 common getsockopt sys_getsockopt sys_getsockopt 119 common getcwd sys_getcwd -120 common readv sys_readv compat_sys_readv -121 common writev sys_writev compat_sys_writev +120 common readv sys_readv +121 common writev sys_writev 122 common settimeofday sys_settimeofday compat_sys_settimeofday 123 32 fchown sys_fchown16 123 64 fchown sys_fchown @@ -201,7 +201,7 @@ 164 64 utrap_install sys_utrap_install 165 common quotactl sys_quotactl 166 common set_tid_address sys_set_tid_address -167 common mount sys_mount compat_sys_mount +167 common mount sys_mount 168 common ustat sys_ustat compat_sys_ustat 169 common setxattr sys_setxattr 170 common lsetxattr sys_lsetxattr @@ -406,8 +406,8 @@ 335 common syncfs sys_syncfs 336 common sendmmsg sys_sendmmsg compat_sys_sendmmsg 337 common setns sys_setns -338 common process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv -339 common process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev +338 common process_vm_readv sys_process_vm_readv +339 common process_vm_writev sys_process_vm_writev 340 32 kern_features sys_ni_syscall sys_kern_features 340 64 kern_features sys_kern_features 341 common kcmp sys_kcmp @@ -485,3 +485,4 @@ 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 +440 common process_madvise sys_process_madvise diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index f99e99e58075..d55ae65a07ad 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -187,6 +187,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + ELF_DETAILS DISCARDS } diff --git a/arch/sparc/lib/checksum_32.S b/arch/sparc/lib/checksum_32.S index 6a5469c97246..7488d130faf7 100644 --- a/arch/sparc/lib/checksum_32.S +++ b/arch/sparc/lib/checksum_32.S @@ -144,44 +144,21 @@ cpte: bne csum_partial_end_cruft ! yep, handle it cpout: retl ! get outta here mov %o2, %o0 ! return computed csum - .globl __csum_partial_copy_start, __csum_partial_copy_end -__csum_partial_copy_start: - /* Work around cpp -rob */ #define ALLOC #alloc #define EXECINSTR #execinstr -#define EX(x,y,a,b) \ -98: x,y; \ - .section .fixup,ALLOC,EXECINSTR; \ - .align 4; \ -99: ba 30f; \ - a, b, %o3; \ - .section __ex_table,ALLOC; \ - .align 4; \ - .word 98b, 99b; \ - .text; \ - .align 4 - -#define EX2(x,y) \ -98: x,y; \ - .section __ex_table,ALLOC; \ - .align 4; \ - .word 98b, 30f; \ - .text; \ - .align 4 - -#define EX3(x,y) \ +#define EX(x,y) \ 98: x,y; \ .section __ex_table,ALLOC; \ .align 4; \ - .word 98b, 96f; \ + .word 98b, cc_fault; \ .text; \ .align 4 -#define EXT(start,end,handler) \ +#define EXT(start,end) \ .section __ex_table,ALLOC; \ .align 4; \ - .word start, 0, end, handler; \ + .word start, 0, end, cc_fault; \ .text; \ .align 4 @@ -252,21 +229,21 @@ __csum_partial_copy_start: cc_end_cruft: be 1f andcc %o3, 4, %g0 - EX(ldd [%o0 + 0x00], %g2, and %o3, 0xf) + EX(ldd [%o0 + 0x00], %g2) add %o1, 8, %o1 addcc %g2, %g7, %g7 add %o0, 8, %o0 addxcc %g3, %g7, %g7 - EX2(st %g2, [%o1 - 0x08]) + EX(st %g2, [%o1 - 0x08]) addx %g0, %g7, %g7 andcc %o3, 4, %g0 - EX2(st %g3, [%o1 - 0x04]) + EX(st %g3, [%o1 - 0x04]) 1: be 1f andcc %o3, 3, %o3 - EX(ld [%o0 + 0x00], %g2, add %o3, 4) + EX(ld [%o0 + 0x00], %g2) add %o1, 4, %o1 addcc %g2, %g7, %g7 - EX2(st %g2, [%o1 - 0x04]) + EX(st %g2, [%o1 - 0x04]) addx %g0, %g7, %g7 andcc %o3, 3, %g0 add %o0, 4, %o0 @@ -276,14 +253,14 @@ cc_end_cruft: subcc %o3, 2, %o3 b 4f or %g0, %g0, %o4 -2: EX(lduh [%o0 + 0x00], %o4, add %o3, 2) +2: EX(lduh [%o0 + 0x00], %o4) add %o0, 2, %o0 - EX2(sth %o4, [%o1 + 0x00]) + EX(sth %o4, [%o1 + 0x00]) be 6f add %o1, 2, %o1 sll %o4, 16, %o4 -4: EX(ldub [%o0 + 0x00], %o5, add %g0, 1) - EX2(stb %o5, [%o1 + 0x00]) +4: EX(ldub [%o0 + 0x00], %o5) + EX(stb %o5, [%o1 + 0x00]) sll %o5, 8, %o5 or %o5, %o4, %o4 6: addcc %o4, %g7, %g7 @@ -306,9 +283,9 @@ cc_dword_align: andcc %o0, 0x2, %g0 be 1f andcc %o0, 0x4, %g0 - EX(lduh [%o0 + 0x00], %g4, add %g1, 0) + EX(lduh [%o0 + 0x00], %g4) sub %g1, 2, %g1 - EX2(sth %g4, [%o1 + 0x00]) + EX(sth %g4, [%o1 + 0x00]) add %o0, 2, %o0 sll %g4, 16, %g4 addcc %g4, %g7, %g7 @@ -322,9 +299,9 @@ cc_dword_align: or %g3, %g7, %g7 1: be 3f andcc %g1, 0xffffff80, %g0 - EX(ld [%o0 + 0x00], %g4, add %g1, 0) + EX(ld [%o0 + 0x00], %g4) sub %g1, 4, %g1 - EX2(st %g4, [%o1 + 0x00]) + EX(st %g4, [%o1 + 0x00]) add %o0, 4, %o0 addcc %g4, %g7, %g7 add %o1, 4, %o1 @@ -354,7 +331,7 @@ __csum_partial_copy_sparc_generic: CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x20,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3) CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x40,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3) CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x60,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3) -10: EXT(5b, 10b, 20f) ! note for exception handling +10: EXT(5b, 10b) ! note for exception handling sub %g1, 128, %g1 ! detract from length addx %g0, %g7, %g7 ! add in last carry bit andcc %g1, 0xffffff80, %g0 ! more to csum? @@ -379,7 +356,7 @@ cctbl: CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x68,%g2,%g3,%g4,%g5) CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x28,%g2,%g3,%g4,%g5) CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x18,%g2,%g3,%g4,%g5) CSUMCOPY_LASTCHUNK(%o0,%o1,%g7,0x08,%g2,%g3,%g4,%g5) -12: EXT(cctbl, 12b, 22f) ! note for exception table handling +12: EXT(cctbl, 12b) ! note for exception table handling addx %g0, %g7, %g7 andcc %o3, 0xf, %g0 ! check for low bits set ccte: bne cc_end_cruft ! something left, handle it out of band @@ -390,7 +367,7 @@ ccdbl: CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x00,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x20,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3) CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x40,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3) CSUMCOPY_BIGCHUNK_ALIGNED(%o0,%o1,%g7,0x60,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3) -11: EXT(ccdbl, 11b, 21f) ! note for exception table handling +11: EXT(ccdbl, 11b) ! note for exception table handling sub %g1, 128, %g1 ! detract from length addx %g0, %g7, %g7 ! add in last carry bit andcc %g1, 0xffffff80, %g0 ! more to csum? @@ -407,9 +384,9 @@ ccslow: cmp %g1, 0 be,a 1f srl %g1, 1, %g4 sub %g1, 1, %g1 - EX(ldub [%o0], %g5, add %g1, 1) + EX(ldub [%o0], %g5) add %o0, 1, %o0 - EX2(stb %g5, [%o1]) + EX(stb %g5, [%o1]) srl %g1, 1, %g4 add %o1, 1, %o1 1: cmp %g4, 0 @@ -418,34 +395,34 @@ ccslow: cmp %g1, 0 andcc %o0, 2, %g0 be,a 1f srl %g4, 1, %g4 - EX(lduh [%o0], %o4, add %g1, 0) + EX(lduh [%o0], %o4) sub %g1, 2, %g1 srl %o4, 8, %g2 sub %g4, 1, %g4 - EX2(stb %g2, [%o1]) + EX(stb %g2, [%o1]) add %o4, %g5, %g5 - EX2(stb %o4, [%o1 + 1]) + EX(stb %o4, [%o1 + 1]) add %o0, 2, %o0 srl %g4, 1, %g4 add %o1, 2, %o1 1: cmp %g4, 0 be,a 2f andcc %g1, 2, %g0 - EX3(ld [%o0], %o4) + EX(ld [%o0], %o4) 5: srl %o4, 24, %g2 srl %o4, 16, %g3 - EX2(stb %g2, [%o1]) + EX(stb %g2, [%o1]) srl %o4, 8, %g2 - EX2(stb %g3, [%o1 + 1]) + EX(stb %g3, [%o1 + 1]) add %o0, 4, %o0 - EX2(stb %g2, [%o1 + 2]) + EX(stb %g2, [%o1 + 2]) addcc %o4, %g5, %g5 - EX2(stb %o4, [%o1 + 3]) + EX(stb %o4, [%o1 + 3]) addx %g5, %g0, %g5 ! I am now to lazy to optimize this (question it add %o1, 4, %o1 ! is worthy). Maybe some day - with the sll/srl subcc %g4, 1, %g4 ! tricks bne,a 5b - EX3(ld [%o0], %o4) + EX(ld [%o0], %o4) sll %g5, 16, %g2 srl %g5, 16, %g5 srl %g2, 16, %g2 @@ -453,19 +430,19 @@ ccslow: cmp %g1, 0 add %g2, %g5, %g5 2: be,a 3f andcc %g1, 1, %g0 - EX(lduh [%o0], %o4, and %g1, 3) + EX(lduh [%o0], %o4) andcc %g1, 1, %g0 srl %o4, 8, %g2 add %o0, 2, %o0 - EX2(stb %g2, [%o1]) + EX(stb %g2, [%o1]) add %g5, %o4, %g5 - EX2(stb %o4, [%o1 + 1]) + EX(stb %o4, [%o1 + 1]) add %o1, 2, %o1 3: be,a 1f sll %g5, 16, %o4 - EX(ldub [%o0], %g2, add %g0, 1) + EX(ldub [%o0], %g2) sll %g2, 8, %o4 - EX2(stb %g2, [%o1]) + EX(stb %g2, [%o1]) add %g5, %o4, %g5 sll %g5, 16, %o4 1: addcc %o4, %g5, %g5 @@ -481,113 +458,10 @@ ccslow: cmp %g1, 0 4: addcc %g7, %g5, %g7 retl addx %g0, %g7, %o0 -__csum_partial_copy_end: /* We do these strange calculations for the csum_*_from_user case only, ie. * we only bother with faults on loads... */ -/* o2 = ((g2%20)&3)*8 - * o3 = g1 - (g2/20)*32 - o2 */ -20: - cmp %g2, 20 - blu,a 1f - and %g2, 3, %o2 - sub %g1, 32, %g1 - b 20b - sub %g2, 20, %g2 -1: - sll %o2, 3, %o2 - b 31f - sub %g1, %o2, %o3 - -/* o2 = (!(g2 & 15) ? 0 : (((g2 & 15) + 1) & ~1)*8) - * o3 = g1 - (g2/16)*32 - o2 */ -21: - andcc %g2, 15, %o3 - srl %g2, 4, %g2 - be,a 1f - clr %o2 - add %o3, 1, %o3 - and %o3, 14, %o3 - sll %o3, 3, %o2 -1: - sll %g2, 5, %g2 - sub %g1, %g2, %o3 - b 31f - sub %o3, %o2, %o3 - -/* o0 += (g2/10)*16 - 0x70 - * 01 += (g2/10)*16 - 0x70 - * o2 = (g2 % 10) ? 8 : 0 - * o3 += 0x70 - (g2/10)*16 - o2 */ -22: - cmp %g2, 10 - blu,a 1f - sub %o0, 0x70, %o0 - add %o0, 16, %o0 - add %o1, 16, %o1 - sub %o3, 16, %o3 - b 22b - sub %g2, 10, %g2 -1: - sub %o1, 0x70, %o1 - add %o3, 0x70, %o3 - clr %o2 - tst %g2 - bne,a 1f - mov 8, %o2 -1: - b 31f - sub %o3, %o2, %o3 -96: - and %g1, 3, %g1 - sll %g4, 2, %g4 - add %g1, %g4, %o3 -30: -/* %o1 is dst - * %o3 is # bytes to zero out - * %o4 is faulting address - * %o5 is %pc where fault occurred */ - clr %o2 -31: -/* %o0 is src - * %o1 is dst - * %o2 is # of bytes to copy from src to dst - * %o3 is # bytes to zero out - * %o4 is faulting address - * %o5 is %pc where fault occurred */ - save %sp, -104, %sp - mov %i5, %o0 - mov %i7, %o1 - mov %i4, %o2 - call lookup_fault - mov %g7, %i4 - cmp %o0, 2 - bne 1f - add %g0, -EFAULT, %i5 - tst %i2 - be 2f - mov %i0, %o1 - mov %i1, %o0 -5: - call memcpy - mov %i2, %o2 - tst %o0 - bne,a 2f - add %i3, %i2, %i3 - add %i1, %i2, %i1 -2: - mov %i1, %o0 -6: - call __bzero - mov %i3, %o1 -1: - ld [%sp + 168], %o2 ! struct_ptr of parent - st %i5, [%o2] +cc_fault: ret - restore - - .section __ex_table,#alloc - .align 4 - .word 5b,2 - .word 6b,2 + clr %o0 diff --git a/arch/sparc/lib/csum_copy.S b/arch/sparc/lib/csum_copy.S index 26c644ba3ecb..0c0268e77155 100644 --- a/arch/sparc/lib/csum_copy.S +++ b/arch/sparc/lib/csum_copy.S @@ -68,9 +68,10 @@ .globl FUNC_NAME .type FUNC_NAME,#function EXPORT_SYMBOL(FUNC_NAME) -FUNC_NAME: /* %o0=src, %o1=dst, %o2=len, %o3=sum */ +FUNC_NAME: /* %o0=src, %o1=dst, %o2=len */ LOAD(prefetch, %o0 + 0x000, #n_reads) xor %o0, %o1, %g1 + mov 1, %o3 clr %o4 andcc %g1, 0x3, %g0 bne,pn %icc, 95f diff --git a/arch/sparc/lib/csum_copy_from_user.S b/arch/sparc/lib/csum_copy_from_user.S index d20b9594f0c7..b0ba8d4dd439 100644 --- a/arch/sparc/lib/csum_copy_from_user.S +++ b/arch/sparc/lib/csum_copy_from_user.S @@ -9,14 +9,14 @@ .section .fixup, "ax"; \ .align 4; \ 99: retl; \ - mov -1, %o0; \ + mov 0, %o0; \ .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ .align 4; -#define FUNC_NAME __csum_partial_copy_from_user +#define FUNC_NAME csum_and_copy_from_user #define LOAD(type,addr,dest) type##a [addr] %asi, dest #include "csum_copy.S" diff --git a/arch/sparc/lib/csum_copy_to_user.S b/arch/sparc/lib/csum_copy_to_user.S index d71c0c81e8ab..91ba36dbf7d2 100644 --- a/arch/sparc/lib/csum_copy_to_user.S +++ b/arch/sparc/lib/csum_copy_to_user.S @@ -9,14 +9,14 @@ .section .fixup,"ax"; \ .align 4; \ 99: retl; \ - mov -1, %o0; \ + mov 0, %o0; \ .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ .align 4; -#define FUNC_NAME __csum_partial_copy_to_user +#define FUNC_NAME csum_and_copy_to_user #define STORE(type,src,addr) type##a src, [addr] %asi #include "csum_copy.S" diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c index 8071bfd72349..40ce087dfecf 100644 --- a/arch/sparc/mm/fault_32.c +++ b/arch/sparc/mm/fault_32.c @@ -288,8 +288,6 @@ no_context: if (fixup > 10) { extern const unsigned int __memset_start[]; extern const unsigned int __memset_end[]; - extern const unsigned int __csum_partial_copy_start[]; - extern const unsigned int __csum_partial_copy_end[]; #ifdef DEBUG_EXCEPTIONS printk("Exception: PC<%08lx> faddr<%08lx>\n", @@ -298,9 +296,7 @@ no_context: regs->pc, fixup, g2); #endif if ((regs->pc >= (unsigned long)__memset_start && - regs->pc < (unsigned long)__memset_end) || - (regs->pc >= (unsigned long)__csum_partial_copy_start && - regs->pc < (unsigned long)__csum_partial_copy_end)) { + regs->pc < (unsigned long)__memset_end)) { regs->u_regs[UREG_I4] = address; regs->u_regs[UREG_I5] = regs->pc; } diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index fad6d3129904..96edf64d4fb3 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -1192,18 +1192,14 @@ int of_node_to_nid(struct device_node *dp) static void __init add_node_ranges(void) { - struct memblock_region *reg; + phys_addr_t start, end; unsigned long prev_max; + u64 i; memblock_resized: prev_max = memblock.memory.max; - for_each_memblock(memory, reg) { - unsigned long size = reg->size; - unsigned long start, end; - - start = reg->base; - end = start + size; + for_each_mem_range(i, &start, &end) { while (start < end) { unsigned long this_end; int nid; @@ -1211,7 +1207,7 @@ memblock_resized: this_end = memblock_nid_range(start, end, &nid); numadbg("Setting memblock NUMA node nid[%d] " - "start[%lx] end[%lx]\n", + "start[%llx] end[%lx]\n", nid, start, this_end); memblock_set_node(start, this_end - start, diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 430a47a1b6ae..bf3e6d2fe5d9 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -11,7 +11,7 @@ #include <linux/spinlock.h> #include <linux/mm.h> #include <linux/bitops.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/of.h> #include <linux/of_device.h> diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 3a388b1c5d4b..0c0342e5b10d 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c @@ -12,7 +12,7 @@ #include <linux/init.h> #include <linux/mm.h> #include <linux/slab.h> -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/of.h> #include <linux/of_device.h> diff --git a/arch/sparc/vdso/Makefile b/arch/sparc/vdso/Makefile index f44355e46f31..c5e1545bc5cf 100644 --- a/arch/sparc/vdso/Makefile +++ b/arch/sparc/vdso/Makefile @@ -3,8 +3,6 @@ # Building vDSO images for sparc. # -KBUILD_CFLAGS += $(DISABLE_LTO) - VDSO64-$(CONFIG_SPARC64) := y VDSOCOMPAT-$(CONFIG_COMPAT) := y @@ -115,7 +113,7 @@ quiet_cmd_vdso = VDSO $@ -T $(filter %.lds,$^) $(filter %.o,$^) && \ sh $(srctree)/$(src)/checkundef.sh '$(OBJDUMP)' '$@' -VDSO_LDFLAGS = -shared --hash-style=both --build-id -Bsymbolic +VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 -Bsymbolic GCOV_PROFILE := n # diff --git a/arch/um/Kconfig b/arch/um/Kconfig index eb51fec75948..4b799fad8b48 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -19,6 +19,7 @@ config UML select GENERIC_CPU_DEVICES select GENERIC_CLOCKEVENTS select HAVE_GCC_PLUGINS + select SET_FS select TTY # Needed for line.c config MMU @@ -62,12 +63,12 @@ config NR_CPUS source "arch/$(HEADER_ARCH)/um/Kconfig" -config FORBID_STATIC_LINK - bool +config MAY_HAVE_RUNTIME_DEPS + bool config STATIC_LINK bool "Force a static link" - depends on !FORBID_STATIC_LINK + depends on CC_CAN_LINK_STATIC_NO_RUNTIME_DEPS || !MAY_HAVE_RUNTIME_DEPS help This option gives you the ability to force a static link of UML. Normally, UML is linked as a shared binary. This is inconvenient for @@ -173,22 +174,6 @@ config PGTABLE_LEVELS default 3 if 3_LEVEL_PGTABLES default 2 -config SECCOMP - def_bool y - prompt "Enable seccomp to safely compute untrusted bytecode" - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via prctl(PR_SET_SECCOMP), it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - - If unsure, say Y. - config UML_TIME_TRAVEL_SUPPORT bool prompt "Support time-travel mode (e.g. for test execution)" diff --git a/arch/um/drivers/Kconfig b/arch/um/drivers/Kconfig index 9160ead56e33..2e7b8e0e7194 100644 --- a/arch/um/drivers/Kconfig +++ b/arch/um/drivers/Kconfig @@ -234,7 +234,7 @@ config UML_NET_DAEMON config UML_NET_VECTOR bool "Vector I/O high performance network devices" depends on UML_NET - select FORBID_STATIC_LINK + select MAY_HAVE_RUNTIME_DEPS help This User-Mode Linux network driver uses multi-message send and receive functions. The host running the UML guest must have @@ -246,7 +246,7 @@ config UML_NET_VECTOR config UML_NET_VDE bool "VDE transport (obsolete)" depends on UML_NET - select FORBID_STATIC_LINK + select MAY_HAVE_RUNTIME_DEPS help This User-Mode Linux network transport allows one or more running UMLs on a single host to communicate with each other and also @@ -294,7 +294,7 @@ config UML_NET_MCAST config UML_NET_PCAP bool "pcap transport (obsolete)" depends on UML_NET - select FORBID_STATIC_LINK + select MAY_HAVE_RUNTIME_DEPS help The pcap transport makes a pcap packet stream on the host look like an ethernet device inside UML. This is useful for making diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index 3695821d06a2..785baedc3555 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -7,6 +7,7 @@ */ #include <stdint.h> +#include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c index bbd20638788a..52ddda3e3b10 100644 --- a/arch/um/drivers/pcap_user.c +++ b/arch/um/drivers/pcap_user.c @@ -32,7 +32,7 @@ static int pcap_user_init(void *data, void *dev) return 0; } -static int pcap_open(void *data) +static int pcap_user_open(void *data) { struct pcap_data *pri = data; __u32 netmask; @@ -44,14 +44,14 @@ static int pcap_open(void *data) if (pri->filter != NULL) { err = dev_netmask(pri->dev, &netmask); if (err < 0) { - printk(UM_KERN_ERR "pcap_open : dev_netmask failed\n"); + printk(UM_KERN_ERR "pcap_user_open : dev_netmask failed\n"); return -EIO; } pri->compiled = uml_kmalloc(sizeof(struct bpf_program), UM_GFP_KERNEL); if (pri->compiled == NULL) { - printk(UM_KERN_ERR "pcap_open : kmalloc failed\n"); + printk(UM_KERN_ERR "pcap_user_open : kmalloc failed\n"); return -ENOMEM; } @@ -59,14 +59,14 @@ static int pcap_open(void *data) (struct bpf_program *) pri->compiled, pri->filter, pri->optimize, netmask); if (err < 0) { - printk(UM_KERN_ERR "pcap_open : pcap_compile failed - " + printk(UM_KERN_ERR "pcap_user_open : pcap_compile failed - " "'%s'\n", pcap_geterr(pri->pcap)); goto out; } err = pcap_setfilter(pri->pcap, pri->compiled); if (err < 0) { - printk(UM_KERN_ERR "pcap_open : pcap_setfilter " + printk(UM_KERN_ERR "pcap_user_open : pcap_setfilter " "failed - '%s'\n", pcap_geterr(pri->pcap)); goto out; } @@ -127,7 +127,7 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri) const struct net_user_info pcap_user_info = { .init = pcap_user_init, - .open = pcap_open, + .open = pcap_user_open, .close = NULL, .remove = pcap_remove, .add_address = NULL, diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 8016d32b6809..482a19c5105c 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -9,7 +9,7 @@ #include <errno.h> #include <fcntl.h> #include <string.h> -#include <sys/termios.h> +#include <termios.h> #include <sys/wait.h> #include <net_user.h> #include <os.h> diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c index 8735c468230a..555203e3e7b4 100644 --- a/arch/um/drivers/vector_kern.c +++ b/arch/um/drivers/vector_kern.c @@ -1403,7 +1403,7 @@ static int vector_net_load_bpf_flash(struct net_device *dev, kfree(vp->bpf->filter); vp->bpf->filter = NULL; } else { - vp->bpf = kmalloc(sizeof(struct sock_fprog), GFP_KERNEL); + vp->bpf = kmalloc(sizeof(struct sock_fprog), GFP_ATOMIC); if (vp->bpf == NULL) { netdev_err(dev, "failed to allocate memory for firmware\n"); goto flash_fail; @@ -1415,7 +1415,7 @@ static int vector_net_load_bpf_flash(struct net_device *dev, if (request_firmware(&fw, efl->data, &vdevice->pdev.dev)) goto flash_fail; - vp->bpf->filter = kmemdup(fw->data, fw->size, GFP_KERNEL); + vp->bpf->filter = kmemdup(fw->data, fw->size, GFP_ATOMIC); if (!vp->bpf->filter) goto free_buffer; diff --git a/arch/um/drivers/vector_user.c b/arch/um/drivers/vector_user.c index c4a0f26b2824..bae53220ce26 100644 --- a/arch/um/drivers/vector_user.c +++ b/arch/um/drivers/vector_user.c @@ -18,9 +18,7 @@ #include <fcntl.h> #include <sys/socket.h> #include <sys/un.h> -#include <net/ethernet.h> #include <netinet/ip.h> -#include <netinet/ether.h> #include <linux/if_ether.h> #include <linux/if_packet.h> #include <sys/wait.h> @@ -39,6 +37,7 @@ #define ID_MAX 2 #define TOKEN_IFNAME "ifname" +#define TOKEN_SCRIPT "ifup" #define TRANS_RAW "raw" #define TRANS_RAW_LEN strlen(TRANS_RAW) @@ -55,6 +54,9 @@ #define MAX_UN_LEN 107 +static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +static const char *template = "tapXXXXXX"; + /* This is very ugly and brute force lookup, but it is done * only once at initialization so not worth doing hashes or * anything more intelligent @@ -191,16 +193,21 @@ raw_fd_cleanup: return err; } + static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) { - int fd = -1; + int fd = -1, i; char *iface; struct vector_fds *result = NULL; + bool dynamic = false; + char dynamic_ifname[IFNAMSIZ]; + char *argv[] = {NULL, NULL, NULL, NULL}; iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); if (iface == NULL) { - printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n"); - goto tap_cleanup; + dynamic = true; + iface = dynamic_ifname; + srand(getpid()); } result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); @@ -214,14 +221,30 @@ static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) result->remote_addr_size = 0; /* TAP */ + do { + if (dynamic) { + strcpy(iface, template); + for (i = 0; i < strlen(iface); i++) { + if (iface[i] == 'X') { + iface[i] = padchar[rand() % strlen(padchar)]; + } + } + } + fd = create_tap_fd(iface); + if ((fd < 0) && (!dynamic)) { + printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n"); + goto tap_cleanup; + } + result->tx_fd = fd; + result->rx_fd = fd; + } while (fd < 0); - fd = create_tap_fd(iface); - if (fd < 0) { - printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n"); - goto tap_cleanup; + argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT); + if (argv[0]) { + argv[1] = iface; + run_helper(NULL, NULL, argv); } - result->tx_fd = fd; - result->rx_fd = fd; + return result; tap_cleanup: printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd); @@ -233,6 +256,7 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec) { char *iface; struct vector_fds *result = NULL; + char *argv[] = {NULL, NULL, NULL, NULL}; iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); if (iface == NULL) { @@ -266,6 +290,12 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec) "uml_tap: failed to create paired raw socket: %i\n", result->rx_fd); goto hybrid_cleanup; } + + argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT); + if (argv[0]) { + argv[1] = iface; + run_helper(NULL, NULL, argv); + } return result; hybrid_cleanup: printk(UM_KERN_ERR "user_init_hybrid: init failed"); @@ -332,7 +362,7 @@ static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id) } switch (id) { case ID_BESS: - if (connect(fd, remote_addr, sizeof(struct sockaddr_un)) < 0) { + if (connect(fd, (const struct sockaddr *) remote_addr, sizeof(struct sockaddr_un)) < 0) { printk(UM_KERN_ERR "bess open:cannot connect to %s %i", remote_addr->sun_path, -errno); goto unix_cleanup; } @@ -399,8 +429,7 @@ static struct vector_fds *user_init_fd_fds(struct arglist *ifspec) fd_cleanup: if (fd >= 0) os_close_file(fd); - if (result != NULL) - kfree(result); + kfree(result); return NULL; } @@ -410,6 +439,7 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec) int err = -ENOMEM; char *iface; struct vector_fds *result = NULL; + char *argv[] = {NULL, NULL, NULL, NULL}; iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); if (iface == NULL) @@ -432,6 +462,11 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec) result->remote_addr = NULL; result->remote_addr_size = 0; } + argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT); + if (argv[0]) { + argv[1] = iface; + run_helper(NULL, NULL, argv); + } return result; raw_cleanup: printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err); @@ -789,10 +824,12 @@ void *uml_vector_user_bpf(char *filename) return false; } bpf_prog = uml_kmalloc(sizeof(struct sock_fprog), UM_GFP_KERNEL); - if (bpf_prog != NULL) { - bpf_prog->len = statbuf.st_size / sizeof(struct sock_filter); - bpf_prog->filter = NULL; + if (bpf_prog == NULL) { + printk(KERN_ERR "Failed to allocate bpf prog buffer"); + return NULL; } + bpf_prog->len = statbuf.st_size / sizeof(struct sock_filter); + bpf_prog->filter = NULL; ffd = os_open_file(filename, of_read(OPENFLAGS()), 0); if (ffd < 0) { printk(KERN_ERR "Error %d opening bpf file", -errno); diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index 8d435f8a6dec..1c63b260ecc4 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -16,6 +16,7 @@ generic-y += kdebug.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h generic-y += mmiowb.h +generic-y += module.lds.h generic-y += param.h generic-y += pci.h generic-y += percpu.h diff --git a/arch/um/include/shared/init.h b/arch/um/include/shared/init.h index c66de434a983..1a659e2e8cc3 100644 --- a/arch/um/include/shared/init.h +++ b/arch/um/include/shared/init.h @@ -45,15 +45,15 @@ typedef void (*exitcall_t)(void); /* These are for everybody (although not all archs will actually discard it in modules) */ -#define __init __section(.init.text) -#define __initdata __section(.init.data) -#define __exitdata __section(.exit.data) -#define __exit_call __used __section(.exitcall.exit) +#define __init __section(".init.text") +#define __initdata __section(".init.data") +#define __exitdata __section(".exit.data") +#define __exit_call __used __section(".exitcall.exit") #ifdef MODULE -#define __exit __section(.exit.text) +#define __exit __section(".exit.text") #else -#define __exit __used __section(.exit.text) +#define __exit __used __section(".exit.text") #endif #endif @@ -102,10 +102,10 @@ extern struct uml_param __uml_setup_start, __uml_setup_end; * Mark functions and data as being only used at initialization * or exit time. */ -#define __uml_init_setup __used __section(.uml.setup.init) -#define __uml_setup_help __used __section(.uml.help.init) -#define __uml_postsetup_call __used __section(.uml.postsetup.init) -#define __uml_exit_call __used __section(.uml.exitcall.exit) +#define __uml_init_setup __used __section(".uml.setup.init") +#define __uml_setup_help __used __section(".uml.help.init") +#define __uml_postsetup_call __used __section(".uml.postsetup.init") +#define __uml_exit_call __used __section(".uml.exitcall.exit") #ifdef __UM_HOST__ @@ -120,7 +120,7 @@ extern struct uml_param __uml_setup_start, __uml_setup_end; #define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn -#define __init_call __used __section(.initcall.init) +#define __init_call __used __section(".initcall.init") #endif diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S index f5001481010c..dacbfabf66d8 100644 --- a/arch/um/kernel/dyn.lds.S +++ b/arch/um/kernel/dyn.lds.S @@ -164,8 +164,8 @@ SECTIONS PROVIDE (end = .); STABS_DEBUG - DWARF_DEBUG + ELF_DETAILS DISCARDS } diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 26b5e243d3fc..3bed09538dd9 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -101,7 +101,7 @@ void interrupt_end(void) schedule(); if (test_thread_flag(TIF_SIGPENDING)) do_signal(regs); - if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) + if (test_thread_flag(TIF_NOTIFY_RESUME)) tracehook_notify_resume(regs); } diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c index 10c99e058fca..d1cffc2a7f21 100644 --- a/arch/um/kernel/sigio.c +++ b/arch/um/kernel/sigio.c @@ -35,14 +35,14 @@ int write_sigio_irq(int fd) } /* These are called from os-Linux/sigio.c to protect its pollfds arrays. */ -static DEFINE_SPINLOCK(sigio_spinlock); +static DEFINE_MUTEX(sigio_mutex); void sigio_lock(void) { - spin_lock(&sigio_spinlock); + mutex_lock(&sigio_mutex); } void sigio_unlock(void) { - spin_unlock(&sigio_spinlock); + mutex_unlock(&sigio_mutex); } diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c index bfb70c456b30..95c355181dcd 100644 --- a/arch/um/kernel/skas/clone.c +++ b/arch/um/kernel/skas/clone.c @@ -21,7 +21,7 @@ * on some systems. */ -void __attribute__ ((__section__ (".__syscall_stub"))) +void __section(".__syscall_stub") stub_clone_handler(void) { struct stub_data *data = (struct stub_data *) STUB_DATA; diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c index acbc879d2773..7452f70d50d0 100644 --- a/arch/um/kernel/sysrq.c +++ b/arch/um/kernel/sysrq.c @@ -47,12 +47,10 @@ void show_stack(struct task_struct *task, unsigned long *stack, if (kstack_end(stack)) break; if (i && ((i % STACKSLOTS_PER_LINE) == 0)) - printk("%s\n", loglvl); + pr_cont("\n"); pr_cont(" %08lx", *stack++); } - printk("%s\n", loglvl); printk("%sCall Trace:\n", loglvl); dump_trace(current, &stackops, (void *)loglvl); - printk("%s\n", loglvl); } diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 25eaa6a0c658..3d109ff3309b 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -70,13 +70,17 @@ static void time_travel_handle_message(struct um_timetravel_msg *msg, * read of the message and write of the ACK. */ if (mode != TTMH_READ) { + bool disabled = irqs_disabled(); + + BUG_ON(mode == TTMH_IDLE && !disabled); + + if (disabled) + local_irq_enable(); while (os_poll(1, &time_travel_ext_fd) != 0) { - if (mode == TTMH_IDLE) { - BUG_ON(!irqs_disabled()); - local_irq_enable(); - local_irq_disable(); - } + /* nothing */ } + if (disabled) + local_irq_disable(); } ret = os_read_file(time_travel_ext_fd, msg, sizeof(*msg)); @@ -102,6 +106,7 @@ static void time_travel_handle_message(struct um_timetravel_msg *msg, break; } + resp.seq = msg->seq; os_write_file(time_travel_ext_fd, &resp, sizeof(resp)); } diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 00141e70de56..76b37297b7d4 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -52,7 +52,7 @@ struct cpuinfo_um boot_cpu_data = { }; union thread_union cpu0_irqstack - __attribute__((__section__(".data..init_irqstack"))) = + __section(".data..init_irqstack") = { .thread_info = INIT_THREAD_INFO(init_task) }; /* Changed in setup_arch, which is called in early boot */ diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 3b6dab3d4501..45d957d7004c 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -108,8 +108,8 @@ SECTIONS PROVIDE (end = .); STABS_DEBUG - DWARF_DEBUG + ELF_DETAILS DISCARDS } diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index 9e16078a4bf8..1d7558dac75f 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c @@ -97,7 +97,7 @@ static int remove_files_and_dir(char *dir) while ((ent = readdir(directory)) != NULL) { if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) continue; - len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1; + len = strlen(dir) + strlen("/") + strlen(ent->d_name) + 1; if (len > sizeof(file)) { ret = -E2BIG; goto out; @@ -135,7 +135,7 @@ out: */ static inline int is_umdir_used(char *dir) { - char pid[sizeof("nnnnn\0")], *end, *file; + char pid[sizeof("nnnnnnnnn")], *end, *file; int dead, fd, p, n, err; size_t filelen; @@ -217,10 +217,10 @@ static int umdir_take_if_dead(char *dir) static void __init create_pid_file(void) { - char pid[sizeof("nnnnn\0")], *file; + char pid[sizeof("nnnnnnnnn")], *file; int fd, n; - n = strlen(uml_dir) + UMID_LEN + sizeof("/pid\0"); + n = strlen(uml_dir) + UMID_LEN + sizeof("/pid"); file = malloc(n); if (!file) return; diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index ecf2f390fad2..07327425d06e 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -10,7 +10,7 @@ #include <signal.h> #include <string.h> #include <termios.h> -#include <wait.h> +#include <sys/wait.h> #include <sys/mman.h> #include <sys/utsname.h> #include <init.h> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 7101ac64bb20..f6946b81f74a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -75,7 +75,7 @@ config X86 select ARCH_HAS_PTE_DEVMAP if X86_64 select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 - select ARCH_HAS_UACCESS_MCSAFE if X86_64 && X86_MCE + select ARCH_HAS_COPY_MC if X86_64 select ARCH_HAS_SET_MEMORY select ARCH_HAS_SET_DIRECT_MAP select ARCH_HAS_STRICT_KERNEL_RWX @@ -215,6 +215,8 @@ config X86 select HAVE_FUNCTION_ARG_ACCESS_API select HAVE_STACKPROTECTOR if CC_HAS_SANE_STACKPROTECTOR select HAVE_STACK_VALIDATION if X86_64 + select HAVE_STATIC_CALL + select HAVE_STATIC_CALL_INLINE if HAVE_STACK_VALIDATION select HAVE_RSEQ select HAVE_SYSCALL_TRACEPOINTS select HAVE_UNSTABLE_SCHED_CLOCK @@ -230,6 +232,7 @@ config X86 select RTC_MC146818_LIB select SPARSE_IRQ select SRCU + select STACK_VALIDATION if HAVE_STACK_VALIDATION && (HAVE_STATIC_CALL_INLINE || RETPOLINE) select SYSCTL_EXCEPTION_TRACE select THREAD_INFO_IN_TASK select USER_STACKTRACE_SUPPORT @@ -451,7 +454,6 @@ config GOLDFISH config RETPOLINE bool "Avoid speculative indirect branches in kernel" default y - select STACK_VALIDATION if HAVE_STACK_VALIDATION help Compile kernel with the retpoline compiler options to guard against kernel-to-user data leaks by avoiding speculative indirect @@ -1521,6 +1523,7 @@ config AMD_MEM_ENCRYPT select DYNAMIC_PHYSICAL_MASK select ARCH_USE_MEMREMAP_PROT select ARCH_HAS_FORCE_DMA_UNENCRYPTED + select INSTRUCTION_DECODER help Say yes to enable support for the encryption of system memory. This requires an AMD processor that supports Secure Memory @@ -1968,22 +1971,6 @@ config EFI_MIXED If unsure, say N. -config SECCOMP - def_bool y - prompt "Enable seccomp to safely compute untrusted bytecode" - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via prctl(PR_SET_SECCOMP), it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - - If unsure, say Y. Only embedded should say N here. - source "kernel/Kconfig.hz" config KEXEC diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index ee1d3c5834c6..27b5e2bc6a01 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -62,7 +62,7 @@ config EARLY_PRINTK_USB_XDBC You should normally say N here, unless you want to debug early crashes or need a very simple printk logging facility. -config MCSAFE_TEST +config COPY_MC_TEST def_bool n config EFI_PGT_DUMP diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 4346ffb2e39f..154259f18b8b 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -209,6 +209,10 @@ ifdef CONFIG_X86_64 LDFLAGS_vmlinux += -z max-page-size=0x200000 endif +# We never want expected sections to be placed heuristically by the +# linker. All sections should be explicitly named in the linker script. +LDFLAGS_vmlinux += $(call ld-option, --orphan-handling=warn) + archscripts: scripts_basic $(Q)$(MAKE) $(build)=arch/x86/tools relocs diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 3962f592633d..ee249088cbfe 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -29,10 +29,10 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4 vmlinux.bin.zst KBUILD_CFLAGS := -m$(BITS) -O2 -KBUILD_CFLAGS += -fno-strict-aliasing $(call cc-option, -fPIE, -fPIC) +KBUILD_CFLAGS += -fno-strict-aliasing -fPIE KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING cflags-$(CONFIG_X86_32) := -march=i386 -cflags-$(CONFIG_X86_64) := -mcmodel=small +cflags-$(CONFIG_X86_64) := -mcmodel=small -mno-red-zone KBUILD_CFLAGS += $(cflags-y) KBUILD_CFLAGS += -mno-mmx -mno-sse KBUILD_CFLAGS += -ffreestanding @@ -43,24 +43,26 @@ KBUILD_CFLAGS += -Wno-pointer-sign KBUILD_CFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=) KBUILD_CFLAGS += -fno-asynchronous-unwind-tables KBUILD_CFLAGS += -D__DISABLE_EXPORTS +# Disable relocation relaxation in case the link is not PIE. +KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mrelax-relocations=no) +KBUILD_CFLAGS += -include $(srctree)/include/linux/hidden.h + +# sev-es.c indirectly inludes inat-table.h which is generated during +# compilation and stored in $(objtree). Add the directory to the includes so +# that the compiler finds it even with out-of-tree builds (make O=/some/path). +CFLAGS_sev-es.o += -I$(objtree)/arch/x86/lib/ KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ GCOV_PROFILE := n UBSAN_SANITIZE :=n KBUILD_LDFLAGS := -m elf_$(UTS_MACHINE) +KBUILD_LDFLAGS += $(call ld-option,--no-ld-generated-unwind-info) # Compressed kernel should be built as PIE since it may be loaded at any # address by the bootloader. -ifeq ($(CONFIG_X86_32),y) -KBUILD_LDFLAGS += $(call ld-option, -pie) $(call ld-option, --no-dynamic-linker) -else -# To build 64-bit compressed kernel as PIE, we disable relocation -# overflow check to avoid relocation overflow error with a new linker -# command-line option, -z noreloc-overflow. -KBUILD_LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \ - && echo "-z noreloc-overflow -pie --no-dynamic-linker") -endif -LDFLAGS_vmlinux := -T +LDFLAGS_vmlinux := -pie $(call ld-option, --no-dynamic-linker) +LDFLAGS_vmlinux += $(call ld-option, --orphan-handling=warn) +LDFLAGS_vmlinux += -T hostprogs := mkpiggy HOST_EXTRACFLAGS += -I$(srctree)/tools/include @@ -84,9 +86,11 @@ vmlinux-objs-y := $(obj)/vmlinux.lds $(obj)/kernel_info.o $(obj)/head_$(BITS).o vmlinux-objs-$(CONFIG_EARLY_PRINTK) += $(obj)/early_serial_console.o vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/kaslr.o ifdef CONFIG_X86_64 - vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/kaslr_64.o + vmlinux-objs-y += $(obj)/ident_map_64.o + vmlinux-objs-y += $(obj)/idt_64.o $(obj)/idt_handlers_64.o vmlinux-objs-y += $(obj)/mem_encrypt.o vmlinux-objs-y += $(obj)/pgtable_64.o + vmlinux-objs-$(CONFIG_AMD_MEM_ENCRYPT) += $(obj)/sev-es.o endif vmlinux-objs-$(CONFIG_ACPI) += $(obj)/acpi.o @@ -94,30 +98,8 @@ vmlinux-objs-$(CONFIG_ACPI) += $(obj)/acpi.o vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_thunk_$(BITS).o efi-obj-$(CONFIG_EFI_STUB) = $(objtree)/drivers/firmware/efi/libstub/lib.a -# The compressed kernel is built with -fPIC/-fPIE so that a boot loader -# can place it anywhere in memory and it will still run. However, since -# it is executed as-is without any ELF relocation processing performed -# (and has already had all relocation sections stripped from the binary), -# none of the code can use data relocations (e.g. static assignments of -# pointer values), since they will be meaningless at runtime. This check -# will refuse to link the vmlinux if any of these relocations are found. -quiet_cmd_check_data_rel = DATAREL $@ -define cmd_check_data_rel - for obj in $(filter %.o,$^); do \ - $(READELF) -S $$obj | grep -qF .rel.local && { \ - echo "error: $$obj has data relocations!" >&2; \ - exit 1; \ - } || true; \ - done -endef - -# We need to run two commands under "if_changed", so merge them into a -# single invocation. -quiet_cmd_check-and-link-vmlinux = LD $@ - cmd_check-and-link-vmlinux = $(cmd_check_data_rel); $(cmd_ld) - $(obj)/vmlinux: $(vmlinux-objs-y) $(efi-obj-y) FORCE - $(call if_changed,check-and-link-vmlinux) + $(call if_changed,ld) OBJCOPYFLAGS_vmlinux.bin := -R .comment -S $(obj)/vmlinux.bin: vmlinux FORCE diff --git a/arch/x86/boot/compressed/cpuflags.c b/arch/x86/boot/compressed/cpuflags.c index 6448a8196d32..0cc1323896d1 100644 --- a/arch/x86/boot/compressed/cpuflags.c +++ b/arch/x86/boot/compressed/cpuflags.c @@ -1,6 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#ifdef CONFIG_RANDOMIZE_BASE - #include "../cpuflags.c" bool has_cpuflag(int flag) @@ -9,5 +7,3 @@ bool has_cpuflag(int flag) return test_bit(flag, cpu.flags); } - -#endif diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index 03557f2174bf..659fad53ca82 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -33,32 +33,13 @@ #include <asm/bootparam.h> /* - * The 32-bit x86 assembler in binutils 2.26 will generate R_386_GOT32X - * relocation to get the symbol address in PIC. When the compressed x86 - * kernel isn't built as PIC, the linker optimizes R_386_GOT32X - * relocations to their fixed symbol addresses. However, when the - * compressed x86 kernel is loaded at a different address, it leads - * to the following load failure: - * - * Failed to allocate space for phdrs - * - * during the decompression stage. - * - * If the compressed x86 kernel is relocatable at run-time, it should be - * compiled with -fPIE, instead of -fPIC, if possible and should be built as - * Position Independent Executable (PIE) so that linker won't optimize - * R_386_GOT32X relocation to its fixed symbol address. Older - * linkers generate R_386_32 relocations against locally defined symbols, - * _bss, _ebss, _got, _egot and _end, in PIE. It isn't wrong, just less - * optimal than R_386_RELATIVE. But the x86 kernel fails to properly handle - * R_386_32 relocations when relocating the kernel. To generate - * R_386_RELATIVE relocations, we mark _bss, _ebss, _got, _egot and _end as - * hidden: + * These symbols needed to be marked as .hidden to prevent the BFD linker from + * generating R_386_32 (rather than R_386_RELATIVE) relocations for them when + * the 32-bit compressed kernel is linked as PIE. This is no longer necessary, + * but it doesn't hurt to keep them .hidden. */ .hidden _bss .hidden _ebss - .hidden _got - .hidden _egot .hidden _end __HEAD @@ -77,10 +58,10 @@ SYM_FUNC_START(startup_32) leal (BP_scratch+4)(%esi), %esp call 1f 1: popl %edx - subl $1b, %edx + addl $_GLOBAL_OFFSET_TABLE_+(.-1b), %edx /* Load new GDT */ - leal gdt(%edx), %eax + leal gdt@GOTOFF(%edx), %eax movl %eax, 2(%eax) lgdt (%eax) @@ -93,14 +74,16 @@ SYM_FUNC_START(startup_32) movl %eax, %ss /* - * %edx contains the address we are loaded at by the boot loader and %ebx - * contains the address where we should move the kernel image temporarily - * for safe in-place decompression. %ebp contains the address that the kernel - * will be decompressed to. + * %edx contains the address we are loaded at by the boot loader (plus the + * offset to the GOT). The below code calculates %ebx to be the address where + * we should move the kernel image temporarily for safe in-place decompression + * (again, plus the offset to the GOT). + * + * %ebp is calculated to be the address that the kernel will be decompressed to. */ #ifdef CONFIG_RELOCATABLE - movl %edx, %ebx + leal startup_32@GOTOFF(%edx), %ebx #ifdef CONFIG_EFI_STUB /* @@ -111,7 +94,7 @@ SYM_FUNC_START(startup_32) * image_offset = startup_32 - image_base * Otherwise image_offset will be zero and has no effect on the calculations. */ - subl image_offset(%edx), %ebx + subl image_offset@GOTOFF(%edx), %ebx #endif movl BP_kernel_alignment(%esi), %eax @@ -128,10 +111,10 @@ SYM_FUNC_START(startup_32) movl %ebx, %ebp // Save the output address for later /* Target address to relocate to for decompression */ addl BP_init_size(%esi), %ebx - subl $_end, %ebx + subl $_end@GOTOFF, %ebx /* Set up the stack */ - leal boot_stack_end(%ebx), %esp + leal boot_stack_end@GOTOFF(%ebx), %esp /* Zero EFLAGS */ pushl $0 @@ -142,8 +125,8 @@ SYM_FUNC_START(startup_32) * where decompression in place becomes safe. */ pushl %esi - leal (_bss-4)(%edx), %esi - leal (_bss-4)(%ebx), %edi + leal (_bss@GOTOFF-4)(%edx), %esi + leal (_bss@GOTOFF-4)(%ebx), %edi movl $(_bss - startup_32), %ecx shrl $2, %ecx std @@ -156,14 +139,14 @@ SYM_FUNC_START(startup_32) * during extract_kernel below. To avoid any issues, repoint the GDTR * to the new copy of the GDT. */ - leal gdt(%ebx), %eax + leal gdt@GOTOFF(%ebx), %eax movl %eax, 2(%eax) lgdt (%eax) /* * Jump to the relocated address. */ - leal .Lrelocated(%ebx), %eax + leal .Lrelocated@GOTOFF(%ebx), %eax jmp *%eax SYM_FUNC_END(startup_32) @@ -173,7 +156,7 @@ SYM_FUNC_START_ALIAS(efi_stub_entry) add $0x4, %esp movl 8(%esp), %esi /* save boot_params pointer */ call efi_main - leal startup_32(%eax), %eax + /* efi_main returns the possibly relocated address of startup_32 */ jmp *%eax SYM_FUNC_END(efi32_stub_entry) SYM_FUNC_END_ALIAS(efi_stub_entry) @@ -186,40 +169,26 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) * Clear BSS (stack is currently empty) */ xorl %eax, %eax - leal _bss(%ebx), %edi - leal _ebss(%ebx), %ecx + leal _bss@GOTOFF(%ebx), %edi + leal _ebss@GOTOFF(%ebx), %ecx subl %edi, %ecx shrl $2, %ecx rep stosl /* - * Adjust our own GOT - */ - leal _got(%ebx), %edx - leal _egot(%ebx), %ecx -1: - cmpl %ecx, %edx - jae 2f - addl %ebx, (%edx) - addl $4, %edx - jmp 1b -2: - -/* * Do the extraction, and jump to the new kernel.. */ - /* push arguments for extract_kernel: */ - pushl $z_output_len /* decompressed length, end of relocs */ - - pushl %ebp /* output address */ - - pushl $z_input_len /* input_len */ - leal input_data(%ebx), %eax - pushl %eax /* input_data */ - leal boot_heap(%ebx), %eax - pushl %eax /* heap area */ - pushl %esi /* real mode pointer */ - call extract_kernel /* returns kernel location in %eax */ + /* push arguments for extract_kernel: */ + + pushl output_len@GOTOFF(%ebx) /* decompressed length, end of relocs */ + pushl %ebp /* output address */ + pushl input_len@GOTOFF(%ebx) /* input_len */ + leal input_data@GOTOFF(%ebx), %eax + pushl %eax /* input_data */ + leal boot_heap@GOTOFF(%ebx), %eax + pushl %eax /* heap area */ + pushl %esi /* real mode pointer */ + call extract_kernel /* returns kernel location in %eax */ addl $24, %esp /* diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 97d37f0a34f5..017de6cc87dc 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -33,6 +33,7 @@ #include <asm/processor-flags.h> #include <asm/asm-offsets.h> #include <asm/bootparam.h> +#include <asm/desc_defs.h> #include "pgtable.h" /* @@ -40,11 +41,35 @@ */ .hidden _bss .hidden _ebss - .hidden _got - .hidden _egot .hidden _end __HEAD + +/* + * This macro gives the relative virtual address of X, i.e. the offset of X + * from startup_32. This is the same as the link-time virtual address of X, + * since startup_32 is at 0, but defining it this way tells the + * assembler/linker that we do not want the actual run-time address of X. This + * prevents the linker from trying to create unwanted run-time relocation + * entries for the reference when the compressed kernel is linked as PIE. + * + * A reference X(%reg) will result in the link-time VA of X being stored with + * the instruction, and a run-time R_X86_64_RELATIVE relocation entry that + * adds the 64-bit base address where the kernel is loaded. + * + * Replacing it with (X-startup_32)(%reg) results in the offset being stored, + * and no run-time relocation. + * + * The macro should be used as a displacement with a base register containing + * the run-time address of startup_32 [i.e. rva(X)(%reg)], or as an immediate + * [$ rva(X)]. + * + * This macro can only be used from within the .head.text section, since the + * expression requires startup_32 to be in the same section as the code being + * assembled. + */ +#define rva(X) ((X) - startup_32) + .code32 SYM_FUNC_START(startup_32) /* @@ -67,10 +92,10 @@ SYM_FUNC_START(startup_32) leal (BP_scratch+4)(%esi), %esp call 1f 1: popl %ebp - subl $1b, %ebp + subl $ rva(1b), %ebp /* Load new GDT with the 64bit segments using 32bit descriptor */ - leal gdt(%ebp), %eax + leal rva(gdt)(%ebp), %eax movl %eax, 2(%eax) lgdt (%eax) @@ -83,7 +108,7 @@ SYM_FUNC_START(startup_32) movl %eax, %ss /* setup a stack and make sure cpu supports long mode. */ - leal boot_stack_end(%ebp), %esp + leal rva(boot_stack_end)(%ebp), %esp call verify_cpu testl %eax, %eax @@ -110,7 +135,7 @@ SYM_FUNC_START(startup_32) * image_offset = startup_32 - image_base * Otherwise image_offset will be zero and has no effect on the calculations. */ - subl image_offset(%ebp), %ebx + subl rva(image_offset)(%ebp), %ebx #endif movl BP_kernel_alignment(%esi), %eax @@ -126,7 +151,7 @@ SYM_FUNC_START(startup_32) /* Target address to relocate to for decompression */ addl BP_init_size(%esi), %ebx - subl $_end, %ebx + subl $ rva(_end), %ebx /* * Prepare for entering 64 bit mode @@ -154,19 +179,19 @@ SYM_FUNC_START(startup_32) 1: /* Initialize Page tables to 0 */ - leal pgtable(%ebx), %edi + leal rva(pgtable)(%ebx), %edi xorl %eax, %eax movl $(BOOT_INIT_PGT_SIZE/4), %ecx rep stosl /* Build Level 4 */ - leal pgtable + 0(%ebx), %edi + leal rva(pgtable + 0)(%ebx), %edi leal 0x1007 (%edi), %eax movl %eax, 0(%edi) addl %edx, 4(%edi) /* Build Level 3 */ - leal pgtable + 0x1000(%ebx), %edi + leal rva(pgtable + 0x1000)(%ebx), %edi leal 0x1007(%edi), %eax movl $4, %ecx 1: movl %eax, 0x00(%edi) @@ -177,7 +202,7 @@ SYM_FUNC_START(startup_32) jnz 1b /* Build Level 2 */ - leal pgtable + 0x2000(%ebx), %edi + leal rva(pgtable + 0x2000)(%ebx), %edi movl $0x00000183, %eax movl $2048, %ecx 1: movl %eax, 0(%edi) @@ -188,7 +213,7 @@ SYM_FUNC_START(startup_32) jnz 1b /* Enable the boot page tables */ - leal pgtable(%ebx), %eax + leal rva(pgtable)(%ebx), %eax movl %eax, %cr3 /* Enable Long mode in EFER (Extended Feature Enable Register) */ @@ -213,14 +238,14 @@ SYM_FUNC_START(startup_32) * We place all of the values on our mini stack so lret can * used to perform that far jump. */ - leal startup_64(%ebp), %eax + leal rva(startup_64)(%ebp), %eax #ifdef CONFIG_EFI_MIXED - movl efi32_boot_args(%ebp), %edi + movl rva(efi32_boot_args)(%ebp), %edi cmp $0, %edi jz 1f - leal efi64_stub_entry(%ebp), %eax - movl efi32_boot_args+4(%ebp), %esi - movl efi32_boot_args+8(%ebp), %edx // saved bootparams pointer + leal rva(efi64_stub_entry)(%ebp), %eax + movl rva(efi32_boot_args+4)(%ebp), %esi + movl rva(efi32_boot_args+8)(%ebp), %edx // saved bootparams pointer cmpl $0, %edx jnz 1f /* @@ -231,7 +256,7 @@ SYM_FUNC_START(startup_32) * the correct stack alignment for entry. */ subl $40, %esp - leal efi_pe_entry(%ebp), %eax + leal rva(efi_pe_entry)(%ebp), %eax movl %edi, %ecx // MS calling convention movl %esi, %edx 1: @@ -257,18 +282,18 @@ SYM_FUNC_START(efi32_stub_entry) call 1f 1: pop %ebp - subl $1b, %ebp + subl $ rva(1b), %ebp - movl %esi, efi32_boot_args+8(%ebp) + movl %esi, rva(efi32_boot_args+8)(%ebp) SYM_INNER_LABEL(efi32_pe_stub_entry, SYM_L_LOCAL) - movl %ecx, efi32_boot_args(%ebp) - movl %edx, efi32_boot_args+4(%ebp) - movb $0, efi_is64(%ebp) + movl %ecx, rva(efi32_boot_args)(%ebp) + movl %edx, rva(efi32_boot_args+4)(%ebp) + movb $0, rva(efi_is64)(%ebp) /* Save firmware GDTR and code/data selectors */ - sgdtl efi32_boot_gdt(%ebp) - movw %cs, efi32_boot_cs(%ebp) - movw %ds, efi32_boot_ds(%ebp) + sgdtl rva(efi32_boot_gdt)(%ebp) + movw %cs, rva(efi32_boot_cs)(%ebp) + movw %ds, rva(efi32_boot_ds)(%ebp) /* Disable paging */ movl %cr0, %eax @@ -347,30 +372,11 @@ SYM_CODE_START(startup_64) /* Target address to relocate to for decompression */ movl BP_init_size(%rsi), %ebx - subl $_end, %ebx + subl $ rva(_end), %ebx addq %rbp, %rbx /* Set up the stack */ - leaq boot_stack_end(%rbx), %rsp - - /* - * paging_prepare() and cleanup_trampoline() below can have GOT - * references. Adjust the table with address we are running at. - * - * Zero RAX for adjust_got: the GOT was not adjusted before; - * there's no adjustment to undo. - */ - xorq %rax, %rax - - /* - * Calculate the address the binary is loaded at and use it as - * a GOT adjustment. - */ - call 1f -1: popq %rdi - subq $1b, %rdi - - call .Ladjust_got + leaq rva(boot_stack_end)(%rbx), %rsp /* * At this point we are in long mode with 4-level paging enabled, @@ -410,6 +416,10 @@ SYM_CODE_START(startup_64) .Lon_kernel_cs: + pushq %rsi + call load_stage1_idt + popq %rsi + /* * paging_prepare() sets up the trampoline and checks if we need to * enable 5-level paging. @@ -444,7 +454,7 @@ SYM_CODE_START(startup_64) lretq trampoline_return: /* Restore the stack, the 32-bit trampoline uses its own stack */ - leaq boot_stack_end(%rbx), %rsp + leaq rva(boot_stack_end)(%rbx), %rsp /* * cleanup_trampoline() would restore trampoline memory. @@ -456,7 +466,7 @@ trampoline_return: * this function call. */ pushq %rsi - leaq top_pgtable(%rbx), %rdi + leaq rva(top_pgtable)(%rbx), %rdi call cleanup_trampoline popq %rsi @@ -464,30 +474,15 @@ trampoline_return: pushq $0 popfq - /* - * Previously we've adjusted the GOT with address the binary was - * loaded at. Now we need to re-adjust for relocation address. - * - * Calculate the address the binary is loaded at, so that we can - * undo the previous GOT adjustment. - */ - call 1f -1: popq %rax - subq $1b, %rax - - /* The new adjustment is the relocation address */ - movq %rbx, %rdi - call .Ladjust_got - /* * Copy the compressed kernel to the end of our buffer * where decompression in place becomes safe. */ pushq %rsi leaq (_bss-8)(%rip), %rsi - leaq (_bss-8)(%rbx), %rdi - movq $_bss /* - $startup_32 */, %rcx - shrq $3, %rcx + leaq rva(_bss-8)(%rbx), %rdi + movl $(_bss - startup_32), %ecx + shrl $3, %ecx std rep movsq cld @@ -498,15 +493,15 @@ trampoline_return: * during extract_kernel below. To avoid any issues, repoint the GDTR * to the new copy of the GDT. */ - leaq gdt64(%rbx), %rax - leaq gdt(%rbx), %rdx + leaq rva(gdt64)(%rbx), %rax + leaq rva(gdt)(%rbx), %rdx movq %rdx, 2(%rax) lgdt (%rax) /* * Jump to the relocated address. */ - leaq .Lrelocated(%rbx), %rax + leaq rva(.Lrelocated)(%rbx), %rax jmp *%rax SYM_CODE_END(startup_64) @@ -518,7 +513,7 @@ SYM_FUNC_START_ALIAS(efi_stub_entry) movq %rdx, %rbx /* save boot_params pointer */ call efi_main movq %rbx,%rsi - leaq startup_64(%rax), %rax + leaq rva(startup_64)(%rax), %rax jmp *%rax SYM_FUNC_END(efi64_stub_entry) SYM_FUNC_END_ALIAS(efi_stub_entry) @@ -538,15 +533,33 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) rep stosq /* + * If running as an SEV guest, the encryption mask is required in the + * page-table setup code below. When the guest also has SEV-ES enabled + * set_sev_encryption_mask() will cause #VC exceptions, but the stage2 + * handler can't map its GHCB because the page-table is not set up yet. + * So set up the encryption mask here while still on the stage1 #VC + * handler. Then load stage2 IDT and switch to the kernel's own + * page-table. + */ + pushq %rsi + call set_sev_encryption_mask + call load_stage2_idt + + /* Pass boot_params to initialize_identity_maps() */ + movq (%rsp), %rdi + call initialize_identity_maps + popq %rsi + +/* * Do the extraction, and jump to the new kernel.. */ pushq %rsi /* Save the real mode argument */ movq %rsi, %rdi /* real mode address */ leaq boot_heap(%rip), %rsi /* malloc area for uncompression */ leaq input_data(%rip), %rdx /* input_data */ - movl $z_input_len, %ecx /* input_len */ + movl input_len(%rip), %ecx /* input_len */ movq %rbp, %r8 /* output target address */ - movl $z_output_len, %r9d /* decompressed length, end of relocs */ + movl output_len(%rip), %r9d /* decompressed length, end of relocs */ call extract_kernel /* returns kernel location in %rax */ popq %rsi @@ -556,27 +569,6 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) jmp *%rax SYM_FUNC_END(.Lrelocated) -/* - * Adjust the global offset table - * - * RAX is the previous adjustment of the table to undo (use 0 if it's the - * first time we touch GOT). - * RDI is the new adjustment to apply. - */ -.Ladjust_got: - /* Walk through the GOT adding the address to the entries */ - leaq _got(%rip), %rdx - leaq _egot(%rip), %rcx -1: - cmpq %rcx, %rdx - jae 2f - subq %rax, (%rdx) /* Undo previous adjustment */ - addq %rdi, (%rdx) /* Apply the new adjustment */ - addq $8, %rdx - jmp 1b -2: - ret - .code32 /* * This is the 32-bit trampoline that will be copied over to low memory. @@ -690,10 +682,21 @@ SYM_DATA_START_LOCAL(gdt) .quad 0x0000000000000000 /* TS continued */ SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end) +SYM_DATA_START(boot_idt_desc) + .word boot_idt_end - boot_idt - 1 + .quad 0 +SYM_DATA_END(boot_idt_desc) + .balign 8 +SYM_DATA_START(boot_idt) + .rept BOOT_IDT_ENTRIES + .quad 0 + .quad 0 + .endr +SYM_DATA_END_LABEL(boot_idt, SYM_L_GLOBAL, boot_idt_end) + #ifdef CONFIG_EFI_STUB SYM_DATA(image_offset, .long 0) #endif - #ifdef CONFIG_EFI_MIXED SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0, 0) SYM_DATA(efi_is64, .byte 1) @@ -702,7 +705,7 @@ SYM_DATA(efi_is64, .byte 1) #define BS32_handle_protocol 88 // offsetof(efi_boot_services_32_t, handle_protocol) #define LI32_image_base 32 // offsetof(efi_loaded_image_32_t, image_base) - .text + __HEAD .code32 SYM_FUNC_START(efi32_pe_entry) /* @@ -724,12 +727,12 @@ SYM_FUNC_START(efi32_pe_entry) call 1f 1: pop %ebx - subl $1b, %ebx + subl $ rva(1b), %ebx /* Get the loaded image protocol pointer from the image handle */ leal -4(%ebp), %eax pushl %eax // &loaded_image - leal loaded_image_proto(%ebx), %eax + leal rva(loaded_image_proto)(%ebx), %eax pushl %eax // pass the GUID address pushl 8(%ebp) // pass the image handle @@ -764,7 +767,7 @@ SYM_FUNC_START(efi32_pe_entry) * use it before we get to the 64-bit efi_pe_entry() in C code. */ subl %esi, %ebx - movl %ebx, image_offset(%ebp) // save image_offset + movl %ebx, rva(image_offset)(%ebp) // save image_offset jmp efi32_pe_stub_entry 2: popl %edi // restore callee-save registers diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c new file mode 100644 index 000000000000..a5e5db6ada3c --- /dev/null +++ b/arch/x86/boot/compressed/ident_map_64.c @@ -0,0 +1,360 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * This code is used on x86_64 to create page table identity mappings on + * demand by building up a new set of page tables (or appending to the + * existing ones), and then switching over to them when ready. + * + * Copyright (C) 2015-2016 Yinghai Lu + * Copyright (C) 2016 Kees Cook + */ + +/* + * Since we're dealing with identity mappings, physical and virtual + * addresses are the same, so override these defines which are ultimately + * used by the headers in misc.h. + */ +#define __pa(x) ((unsigned long)(x)) +#define __va(x) ((void *)((unsigned long)(x))) + +/* No PAGE_TABLE_ISOLATION support needed either: */ +#undef CONFIG_PAGE_TABLE_ISOLATION + +#include "error.h" +#include "misc.h" + +/* These actually do the work of building the kernel identity maps. */ +#include <linux/pgtable.h> +#include <asm/cmpxchg.h> +#include <asm/trap_pf.h> +#include <asm/trapnr.h> +#include <asm/init.h> +/* Use the static base for this part of the boot process */ +#undef __PAGE_OFFSET +#define __PAGE_OFFSET __PAGE_OFFSET_BASE +#include "../../mm/ident_map.c" + +#define _SETUP +#include <asm/setup.h> /* For COMMAND_LINE_SIZE */ +#undef _SETUP + +extern unsigned long get_cmd_line_ptr(void); + +/* Used by PAGE_KERN* macros: */ +pteval_t __default_kernel_pte_mask __read_mostly = ~0; + +/* Used to track our page table allocation area. */ +struct alloc_pgt_data { + unsigned char *pgt_buf; + unsigned long pgt_buf_size; + unsigned long pgt_buf_offset; +}; + +/* + * Allocates space for a page table entry, using struct alloc_pgt_data + * above. Besides the local callers, this is used as the allocation + * callback in mapping_info below. + */ +static void *alloc_pgt_page(void *context) +{ + struct alloc_pgt_data *pages = (struct alloc_pgt_data *)context; + unsigned char *entry; + + /* Validate there is space available for a new page. */ + if (pages->pgt_buf_offset >= pages->pgt_buf_size) { + debug_putstr("out of pgt_buf in " __FILE__ "!?\n"); + debug_putaddr(pages->pgt_buf_offset); + debug_putaddr(pages->pgt_buf_size); + return NULL; + } + + entry = pages->pgt_buf + pages->pgt_buf_offset; + pages->pgt_buf_offset += PAGE_SIZE; + + return entry; +} + +/* Used to track our allocated page tables. */ +static struct alloc_pgt_data pgt_data; + +/* The top level page table entry pointer. */ +static unsigned long top_level_pgt; + +phys_addr_t physical_mask = (1ULL << __PHYSICAL_MASK_SHIFT) - 1; + +/* + * Mapping information structure passed to kernel_ident_mapping_init(). + * Due to relocation, pointers must be assigned at run time not build time. + */ +static struct x86_mapping_info mapping_info; + +/* + * Adds the specified range to the identity mappings. + */ +static void add_identity_map(unsigned long start, unsigned long end) +{ + int ret; + + /* Align boundary to 2M. */ + start = round_down(start, PMD_SIZE); + end = round_up(end, PMD_SIZE); + if (start >= end) + return; + + /* Build the mapping. */ + ret = kernel_ident_mapping_init(&mapping_info, (pgd_t *)top_level_pgt, start, end); + if (ret) + error("Error: kernel_ident_mapping_init() failed\n"); +} + +/* Locates and clears a region for a new top level page table. */ +void initialize_identity_maps(void *rmode) +{ + unsigned long cmdline; + + /* Exclude the encryption mask from __PHYSICAL_MASK */ + physical_mask &= ~sme_me_mask; + + /* Init mapping_info with run-time function/buffer pointers. */ + mapping_info.alloc_pgt_page = alloc_pgt_page; + mapping_info.context = &pgt_data; + mapping_info.page_flag = __PAGE_KERNEL_LARGE_EXEC | sme_me_mask; + mapping_info.kernpg_flag = _KERNPG_TABLE; + + /* + * It should be impossible for this not to already be true, + * but since calling this a second time would rewind the other + * counters, let's just make sure this is reset too. + */ + pgt_data.pgt_buf_offset = 0; + + /* + * If we came here via startup_32(), cr3 will be _pgtable already + * and we must append to the existing area instead of entirely + * overwriting it. + * + * With 5-level paging, we use '_pgtable' to allocate the p4d page table, + * the top-level page table is allocated separately. + * + * p4d_offset(top_level_pgt, 0) would cover both the 4- and 5-level + * cases. On 4-level paging it's equal to 'top_level_pgt'. + */ + top_level_pgt = read_cr3_pa(); + if (p4d_offset((pgd_t *)top_level_pgt, 0) == (p4d_t *)_pgtable) { + pgt_data.pgt_buf = _pgtable + BOOT_INIT_PGT_SIZE; + pgt_data.pgt_buf_size = BOOT_PGT_SIZE - BOOT_INIT_PGT_SIZE; + memset(pgt_data.pgt_buf, 0, pgt_data.pgt_buf_size); + } else { + pgt_data.pgt_buf = _pgtable; + pgt_data.pgt_buf_size = BOOT_PGT_SIZE; + memset(pgt_data.pgt_buf, 0, pgt_data.pgt_buf_size); + top_level_pgt = (unsigned long)alloc_pgt_page(&pgt_data); + } + + /* + * New page-table is set up - map the kernel image, boot_params and the + * command line. The uncompressed kernel requires boot_params and the + * command line to be mapped in the identity mapping. Map them + * explicitly here in case the compressed kernel does not touch them, + * or does not touch all the pages covering them. + */ + add_identity_map((unsigned long)_head, (unsigned long)_end); + boot_params = rmode; + add_identity_map((unsigned long)boot_params, (unsigned long)(boot_params + 1)); + cmdline = get_cmd_line_ptr(); + add_identity_map(cmdline, cmdline + COMMAND_LINE_SIZE); + + /* Load the new page-table. */ + write_cr3(top_level_pgt); +} + +/* + * This switches the page tables to the new level4 that has been built + * via calls to add_identity_map() above. If booted via startup_32(), + * this is effectively a no-op. + */ +void finalize_identity_maps(void) +{ + write_cr3(top_level_pgt); +} + +static pte_t *split_large_pmd(struct x86_mapping_info *info, + pmd_t *pmdp, unsigned long __address) +{ + unsigned long page_flags; + unsigned long address; + pte_t *pte; + pmd_t pmd; + int i; + + pte = (pte_t *)info->alloc_pgt_page(info->context); + if (!pte) + return NULL; + + address = __address & PMD_MASK; + /* No large page - clear PSE flag */ + page_flags = info->page_flag & ~_PAGE_PSE; + + /* Populate the PTEs */ + for (i = 0; i < PTRS_PER_PMD; i++) { + set_pte(&pte[i], __pte(address | page_flags)); + address += PAGE_SIZE; + } + + /* + * Ideally we need to clear the large PMD first and do a TLB + * flush before we write the new PMD. But the 2M range of the + * PMD might contain the code we execute and/or the stack + * we are on, so we can't do that. But that should be safe here + * because we are going from large to small mappings and we are + * also the only user of the page-table, so there is no chance + * of a TLB multihit. + */ + pmd = __pmd((unsigned long)pte | info->kernpg_flag); + set_pmd(pmdp, pmd); + /* Flush TLB to establish the new PMD */ + write_cr3(top_level_pgt); + + return pte + pte_index(__address); +} + +static void clflush_page(unsigned long address) +{ + unsigned int flush_size; + char *cl, *start, *end; + + /* + * Hardcode cl-size to 64 - CPUID can't be used here because that might + * cause another #VC exception and the GHCB is not ready to use yet. + */ + flush_size = 64; + start = (char *)(address & PAGE_MASK); + end = start + PAGE_SIZE; + + /* + * First make sure there are no pending writes on the cache-lines to + * flush. + */ + asm volatile("mfence" : : : "memory"); + + for (cl = start; cl != end; cl += flush_size) + clflush(cl); +} + +static int set_clr_page_flags(struct x86_mapping_info *info, + unsigned long address, + pteval_t set, pteval_t clr) +{ + pgd_t *pgdp = (pgd_t *)top_level_pgt; + p4d_t *p4dp; + pud_t *pudp; + pmd_t *pmdp; + pte_t *ptep, pte; + + /* + * First make sure there is a PMD mapping for 'address'. + * It should already exist, but keep things generic. + * + * To map the page just read from it and fault it in if there is no + * mapping yet. add_identity_map() can't be called here because that + * would unconditionally map the address on PMD level, destroying any + * PTE-level mappings that might already exist. Use assembly here so + * the access won't be optimized away. + */ + asm volatile("mov %[address], %%r9" + :: [address] "g" (*(unsigned long *)address) + : "r9", "memory"); + + /* + * The page is mapped at least with PMD size - so skip checks and walk + * directly to the PMD. + */ + p4dp = p4d_offset(pgdp, address); + pudp = pud_offset(p4dp, address); + pmdp = pmd_offset(pudp, address); + + if (pmd_large(*pmdp)) + ptep = split_large_pmd(info, pmdp, address); + else + ptep = pte_offset_kernel(pmdp, address); + + if (!ptep) + return -ENOMEM; + + /* + * Changing encryption attributes of a page requires to flush it from + * the caches. + */ + if ((set | clr) & _PAGE_ENC) + clflush_page(address); + + /* Update PTE */ + pte = *ptep; + pte = pte_set_flags(pte, set); + pte = pte_clear_flags(pte, clr); + set_pte(ptep, pte); + + /* Flush TLB after changing encryption attribute */ + write_cr3(top_level_pgt); + + return 0; +} + +int set_page_decrypted(unsigned long address) +{ + return set_clr_page_flags(&mapping_info, address, 0, _PAGE_ENC); +} + +int set_page_encrypted(unsigned long address) +{ + return set_clr_page_flags(&mapping_info, address, _PAGE_ENC, 0); +} + +int set_page_non_present(unsigned long address) +{ + return set_clr_page_flags(&mapping_info, address, 0, _PAGE_PRESENT); +} + +static void do_pf_error(const char *msg, unsigned long error_code, + unsigned long address, unsigned long ip) +{ + error_putstr(msg); + + error_putstr("\nError Code: "); + error_puthex(error_code); + error_putstr("\nCR2: 0x"); + error_puthex(address); + error_putstr("\nRIP relative to _head: 0x"); + error_puthex(ip - (unsigned long)_head); + error_putstr("\n"); + + error("Stopping.\n"); +} + +void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code) +{ + unsigned long address = native_read_cr2(); + unsigned long end; + bool ghcb_fault; + + ghcb_fault = sev_es_check_ghcb_fault(address); + + address &= PMD_MASK; + end = address + PMD_SIZE; + + /* + * Check for unexpected error codes. Unexpected are: + * - Faults on present pages + * - User faults + * - Reserved bits set + */ + if (error_code & (X86_PF_PROT | X86_PF_USER | X86_PF_RSVD)) + do_pf_error("Unexpected page-fault:", error_code, address, regs->ip); + else if (ghcb_fault) + do_pf_error("Page-fault on GHCB page:", error_code, address, regs->ip); + + /* + * Error code is sane - now identity map the 2M region around + * the faulting address. + */ + add_identity_map(address, end); +} diff --git a/arch/x86/boot/compressed/idt_64.c b/arch/x86/boot/compressed/idt_64.c new file mode 100644 index 000000000000..804a502ee0d2 --- /dev/null +++ b/arch/x86/boot/compressed/idt_64.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include <asm/trap_pf.h> +#include <asm/segment.h> +#include <asm/trapnr.h> +#include "misc.h" + +static void set_idt_entry(int vector, void (*handler)(void)) +{ + unsigned long address = (unsigned long)handler; + gate_desc entry; + + memset(&entry, 0, sizeof(entry)); + + entry.offset_low = (u16)(address & 0xffff); + entry.segment = __KERNEL_CS; + entry.bits.type = GATE_TRAP; + entry.bits.p = 1; + entry.offset_middle = (u16)((address >> 16) & 0xffff); + entry.offset_high = (u32)(address >> 32); + + memcpy(&boot_idt[vector], &entry, sizeof(entry)); +} + +/* Have this here so we don't need to include <asm/desc.h> */ +static void load_boot_idt(const struct desc_ptr *dtr) +{ + asm volatile("lidt %0"::"m" (*dtr)); +} + +/* Setup IDT before kernel jumping to .Lrelocated */ +void load_stage1_idt(void) +{ + boot_idt_desc.address = (unsigned long)boot_idt; + + + if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) + set_idt_entry(X86_TRAP_VC, boot_stage1_vc); + + load_boot_idt(&boot_idt_desc); +} + +/* Setup IDT after kernel jumping to .Lrelocated */ +void load_stage2_idt(void) +{ + boot_idt_desc.address = (unsigned long)boot_idt; + + set_idt_entry(X86_TRAP_PF, boot_page_fault); + +#ifdef CONFIG_AMD_MEM_ENCRYPT + set_idt_entry(X86_TRAP_VC, boot_stage2_vc); +#endif + + load_boot_idt(&boot_idt_desc); +} diff --git a/arch/x86/boot/compressed/idt_handlers_64.S b/arch/x86/boot/compressed/idt_handlers_64.S new file mode 100644 index 000000000000..22890e199f5b --- /dev/null +++ b/arch/x86/boot/compressed/idt_handlers_64.S @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Early IDT handler entry points + * + * Copyright (C) 2019 SUSE + * + * Author: Joerg Roedel <jroedel@suse.de> + */ + +#include <asm/segment.h> + +/* For ORIG_RAX */ +#include "../../entry/calling.h" + +.macro EXCEPTION_HANDLER name function error_code=0 +SYM_FUNC_START(\name) + + /* Build pt_regs */ + .if \error_code == 0 + pushq $0 + .endif + + pushq %rdi + pushq %rsi + pushq %rdx + pushq %rcx + pushq %rax + pushq %r8 + pushq %r9 + pushq %r10 + pushq %r11 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + + /* Call handler with pt_regs */ + movq %rsp, %rdi + /* Error code is second parameter */ + movq ORIG_RAX(%rsp), %rsi + call \function + + /* Restore regs */ + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %rbp + popq %rbx + popq %r11 + popq %r10 + popq %r9 + popq %r8 + popq %rax + popq %rcx + popq %rdx + popq %rsi + popq %rdi + + /* Remove error code and return */ + addq $8, %rsp + + iretq +SYM_FUNC_END(\name) + .endm + + .text + .code64 + +EXCEPTION_HANDLER boot_page_fault do_boot_page_fault error_code=1 + +#ifdef CONFIG_AMD_MEM_ENCRYPT +EXCEPTION_HANDLER boot_stage1_vc do_vc_no_ghcb error_code=1 +EXCEPTION_HANDLER boot_stage2_vc do_boot_stage2_vc error_code=1 +#endif diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index dde7cb3724df..b92fffbe761f 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -36,17 +36,12 @@ #define STATIC #include <linux/decompress/mm.h> -#ifdef CONFIG_X86_5LEVEL -unsigned int __pgtable_l5_enabled; -unsigned int pgdir_shift __ro_after_init = 39; -unsigned int ptrs_per_p4d __ro_after_init = 1; -#endif +#define _SETUP +#include <asm/setup.h> /* For COMMAND_LINE_SIZE */ +#undef _SETUP extern unsigned long get_cmd_line_ptr(void); -/* Used by PAGE_KERN* macros: */ -pteval_t __default_kernel_pte_mask __read_mostly = ~0; - /* Simplified build-specific string for starting entropy. */ static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION; @@ -87,8 +82,11 @@ static unsigned long get_boot_seed(void) static bool memmap_too_large; -/* Store memory limit specified by "mem=nn[KMG]" or "memmap=nn[KMG]" */ -static unsigned long long mem_limit = ULLONG_MAX; +/* + * Store memory limit: MAXMEM on 64-bit and KERNEL_IMAGE_SIZE on 32-bit. + * It may be reduced by "mem=nn[KMG]" or "memmap=nn[KMG]" command line options. + */ +static u64 mem_limit; /* Number of immovable memory regions */ static int num_immovable_mem; @@ -131,8 +129,7 @@ enum parse_mode { }; static int -parse_memmap(char *p, unsigned long long *start, unsigned long long *size, - enum parse_mode mode) +parse_memmap(char *p, u64 *start, u64 *size, enum parse_mode mode) { char *oldp; @@ -162,7 +159,7 @@ parse_memmap(char *p, unsigned long long *start, unsigned long long *size, */ *size = 0; } else { - unsigned long long flags; + u64 flags; /* * efi_fake_mem=nn@ss:attr the attr specifies @@ -201,7 +198,7 @@ static void mem_avoid_memmap(enum parse_mode mode, char *str) while (str && (i < MAX_MEMMAP_REGIONS)) { int rc; - unsigned long long start, size; + u64 start, size; char *k = strchr(str, ','); if (k) @@ -214,7 +211,7 @@ static void mem_avoid_memmap(enum parse_mode mode, char *str) if (start == 0) { /* Store the specified memory limit if size > 0 */ - if (size > 0) + if (size > 0 && size < mem_limit) mem_limit = size; continue; @@ -261,15 +258,15 @@ static void parse_gb_huge_pages(char *param, char *val) static void handle_mem_options(void) { char *args = (char *)get_cmd_line_ptr(); - size_t len = strlen((char *)args); + size_t len; char *tmp_cmdline; char *param, *val; u64 mem_size; - if (!strstr(args, "memmap=") && !strstr(args, "mem=") && - !strstr(args, "hugepages")) + if (!args) return; + len = strnlen(args, COMMAND_LINE_SIZE-1); tmp_cmdline = malloc(len + 1); if (!tmp_cmdline) error("Failed to allocate space for tmp_cmdline"); @@ -284,14 +281,12 @@ static void handle_mem_options(void) while (*args) { args = next_arg(args, ¶m, &val); /* Stop at -- */ - if (!val && strcmp(param, "--") == 0) { - warn("Only '--' specified in cmdline"); - goto out; - } + if (!val && strcmp(param, "--") == 0) + break; if (!strcmp(param, "memmap")) { mem_avoid_memmap(PARSE_MEMMAP, val); - } else if (strstr(param, "hugepages")) { + } else if (IS_ENABLED(CONFIG_X86_64) && strstr(param, "hugepages")) { parse_gb_huge_pages(param, val); } else if (!strcmp(param, "mem")) { char *p = val; @@ -300,21 +295,23 @@ static void handle_mem_options(void) continue; mem_size = memparse(p, &p); if (mem_size == 0) - goto out; + break; - mem_limit = mem_size; + if (mem_size < mem_limit) + mem_limit = mem_size; } else if (!strcmp(param, "efi_fake_mem")) { mem_avoid_memmap(PARSE_EFI, val); } } -out: free(tmp_cmdline); return; } /* - * In theory, KASLR can put the kernel anywhere in the range of [16M, 64T). + * In theory, KASLR can put the kernel anywhere in the range of [16M, MAXMEM) + * on 64-bit, and [16M, KERNEL_IMAGE_SIZE) on 32-bit. + * * The mem_avoid array is used to store the ranges that need to be avoided * when KASLR searches for an appropriate random address. We must avoid any * regions that are unsafe to overlap with during decompression, and other @@ -392,8 +389,7 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size, { unsigned long init_size = boot_params->hdr.init_size; u64 initrd_start, initrd_size; - u64 cmd_line, cmd_line_size; - char *ptr; + unsigned long cmd_line, cmd_line_size; /* * Avoid the region that is unsafe to overlap during @@ -401,8 +397,6 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size, */ mem_avoid[MEM_AVOID_ZO_RANGE].start = input; mem_avoid[MEM_AVOID_ZO_RANGE].size = (output + init_size) - input; - add_identity_map(mem_avoid[MEM_AVOID_ZO_RANGE].start, - mem_avoid[MEM_AVOID_ZO_RANGE].size); /* Avoid initrd. */ initrd_start = (u64)boot_params->ext_ramdisk_image << 32; @@ -414,22 +408,17 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size, /* No need to set mapping for initrd, it will be handled in VO. */ /* Avoid kernel command line. */ - cmd_line = (u64)boot_params->ext_cmd_line_ptr << 32; - cmd_line |= boot_params->hdr.cmd_line_ptr; + cmd_line = get_cmd_line_ptr(); /* Calculate size of cmd_line. */ - ptr = (char *)(unsigned long)cmd_line; - for (cmd_line_size = 0; ptr[cmd_line_size++];) - ; - mem_avoid[MEM_AVOID_CMDLINE].start = cmd_line; - mem_avoid[MEM_AVOID_CMDLINE].size = cmd_line_size; - add_identity_map(mem_avoid[MEM_AVOID_CMDLINE].start, - mem_avoid[MEM_AVOID_CMDLINE].size); + if (cmd_line) { + cmd_line_size = strnlen((char *)cmd_line, COMMAND_LINE_SIZE-1) + 1; + mem_avoid[MEM_AVOID_CMDLINE].start = cmd_line; + mem_avoid[MEM_AVOID_CMDLINE].size = cmd_line_size; + } /* Avoid boot parameters. */ mem_avoid[MEM_AVOID_BOOTPARAMS].start = (unsigned long)boot_params; mem_avoid[MEM_AVOID_BOOTPARAMS].size = sizeof(*boot_params); - add_identity_map(mem_avoid[MEM_AVOID_BOOTPARAMS].start, - mem_avoid[MEM_AVOID_BOOTPARAMS].size); /* We don't need to set a mapping for setup_data. */ @@ -438,11 +427,6 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size, /* Enumerate the immovable memory regions */ num_immovable_mem = count_immovable_mem_regions(); - -#ifdef CONFIG_X86_VERBOSE_BOOTUP - /* Make sure video RAM can be used. */ - add_identity_map(0, PMD_SIZE); -#endif } /* @@ -454,7 +438,7 @@ static bool mem_avoid_overlap(struct mem_vector *img, { int i; struct setup_data *ptr; - unsigned long earliest = img->start + img->size; + u64 earliest = img->start + img->size; bool is_overlapping = false; for (i = 0; i < MEM_AVOID_MAX; i++) { @@ -499,18 +483,16 @@ static bool mem_avoid_overlap(struct mem_vector *img, } struct slot_area { - unsigned long addr; - int num; + u64 addr; + unsigned long num; }; #define MAX_SLOT_AREA 100 static struct slot_area slot_areas[MAX_SLOT_AREA]; - +static unsigned int slot_area_index; static unsigned long slot_max; -static unsigned long slot_area_index; - static void store_slot_info(struct mem_vector *region, unsigned long image_size) { struct slot_area slot_area; @@ -519,13 +501,10 @@ static void store_slot_info(struct mem_vector *region, unsigned long image_size) return; slot_area.addr = region->start; - slot_area.num = (region->size - image_size) / - CONFIG_PHYSICAL_ALIGN + 1; + slot_area.num = 1 + (region->size - image_size) / CONFIG_PHYSICAL_ALIGN; - if (slot_area.num > 0) { - slot_areas[slot_area_index++] = slot_area; - slot_max += slot_area.num; - } + slot_areas[slot_area_index++] = slot_area; + slot_max += slot_area.num; } /* @@ -535,57 +514,53 @@ static void store_slot_info(struct mem_vector *region, unsigned long image_size) static void process_gb_huge_pages(struct mem_vector *region, unsigned long image_size) { - unsigned long addr, size = 0; + u64 pud_start, pud_end; + unsigned long gb_huge_pages; struct mem_vector tmp; - int i = 0; - if (!max_gb_huge_pages) { + if (!IS_ENABLED(CONFIG_X86_64) || !max_gb_huge_pages) { store_slot_info(region, image_size); return; } - addr = ALIGN(region->start, PUD_SIZE); - /* Did we raise the address above the passed in memory entry? */ - if (addr < region->start + region->size) - size = region->size - (addr - region->start); - - /* Check how many 1GB huge pages can be filtered out: */ - while (size > PUD_SIZE && max_gb_huge_pages) { - size -= PUD_SIZE; - max_gb_huge_pages--; - i++; - } + /* Are there any 1GB pages in the region? */ + pud_start = ALIGN(region->start, PUD_SIZE); + pud_end = ALIGN_DOWN(region->start + region->size, PUD_SIZE); /* No good 1GB huge pages found: */ - if (!i) { + if (pud_start >= pud_end) { store_slot_info(region, image_size); return; } - /* - * Skip those 'i'*1GB good huge pages, and continue checking and - * processing the remaining head or tail part of the passed region - * if available. - */ - - if (addr >= region->start + image_size) { + /* Check if the head part of the region is usable. */ + if (pud_start >= region->start + image_size) { tmp.start = region->start; - tmp.size = addr - region->start; + tmp.size = pud_start - region->start; store_slot_info(&tmp, image_size); } - size = region->size - (addr - region->start) - i * PUD_SIZE; - if (size >= image_size) { - tmp.start = addr + i * PUD_SIZE; - tmp.size = size; + /* Skip the good 1GB pages. */ + gb_huge_pages = (pud_end - pud_start) >> PUD_SHIFT; + if (gb_huge_pages > max_gb_huge_pages) { + pud_end = pud_start + (max_gb_huge_pages << PUD_SHIFT); + max_gb_huge_pages = 0; + } else { + max_gb_huge_pages -= gb_huge_pages; + } + + /* Check if the tail part of the region is usable. */ + if (region->start + region->size >= pud_end + image_size) { + tmp.start = pud_end; + tmp.size = region->start + region->size - pud_end; store_slot_info(&tmp, image_size); } } -static unsigned long slots_fetch_random(void) +static u64 slots_fetch_random(void) { unsigned long slot; - int i; + unsigned int i; /* Handle case of no slots stored. */ if (slot_max == 0) @@ -598,7 +573,7 @@ static unsigned long slots_fetch_random(void) slot -= slot_areas[i].num; continue; } - return slot_areas[i].addr + slot * CONFIG_PHYSICAL_ALIGN; + return slot_areas[i].addr + ((u64)slot * CONFIG_PHYSICAL_ALIGN); } if (i == slot_area_index) @@ -611,49 +586,23 @@ static void __process_mem_region(struct mem_vector *entry, unsigned long image_size) { struct mem_vector region, overlap; - unsigned long start_orig, end; - struct mem_vector cur_entry; - - /* On 32-bit, ignore entries entirely above our maximum. */ - if (IS_ENABLED(CONFIG_X86_32) && entry->start >= KERNEL_IMAGE_SIZE) - return; + u64 region_end; - /* Ignore entries entirely below our minimum. */ - if (entry->start + entry->size < minimum) - return; - - /* Ignore entries above memory limit */ - end = min(entry->size + entry->start, mem_limit); - if (entry->start >= end) - return; - cur_entry.start = entry->start; - cur_entry.size = end - entry->start; - - region.start = cur_entry.start; - region.size = cur_entry.size; + /* Enforce minimum and memory limit. */ + region.start = max_t(u64, entry->start, minimum); + region_end = min(entry->start + entry->size, mem_limit); /* Give up if slot area array is full. */ while (slot_area_index < MAX_SLOT_AREA) { - start_orig = region.start; - - /* Potentially raise address to minimum location. */ - if (region.start < minimum) - region.start = minimum; - /* Potentially raise address to meet alignment needs. */ region.start = ALIGN(region.start, CONFIG_PHYSICAL_ALIGN); /* Did we raise the address above the passed in memory entry? */ - if (region.start > cur_entry.start + cur_entry.size) + if (region.start > region_end) return; /* Reduce size by any delta from the original address. */ - region.size -= region.start - start_orig; - - /* On 32-bit, reduce region size to fit within max size. */ - if (IS_ENABLED(CONFIG_X86_32) && - region.start + region.size > KERNEL_IMAGE_SIZE) - region.size = KERNEL_IMAGE_SIZE - region.start; + region.size = region_end - region.start; /* Return if region can't contain decompressed kernel */ if (region.size < image_size) @@ -666,27 +615,19 @@ static void __process_mem_region(struct mem_vector *entry, } /* Store beginning of region if holds at least image_size. */ - if (overlap.start > region.start + image_size) { - struct mem_vector beginning; - - beginning.start = region.start; - beginning.size = overlap.start - region.start; - process_gb_huge_pages(&beginning, image_size); + if (overlap.start >= region.start + image_size) { + region.size = overlap.start - region.start; + process_gb_huge_pages(®ion, image_size); } - /* Return if overlap extends to or past end of region. */ - if (overlap.start + overlap.size >= region.start + region.size) - return; - /* Clip off the overlapping region and start over. */ - region.size -= overlap.start - region.start + overlap.size; region.start = overlap.start + overlap.size; } } static bool process_mem_region(struct mem_vector *region, - unsigned long long minimum, - unsigned long long image_size) + unsigned long minimum, + unsigned long image_size) { int i; /* @@ -709,7 +650,7 @@ static bool process_mem_region(struct mem_vector *region, * immovable memory and @region. */ for (i = 0; i < num_immovable_mem; i++) { - unsigned long long start, end, entry_end, region_end; + u64 start, end, entry_end, region_end; struct mem_vector entry; if (!mem_overlaps(region, &immovable_mem[i])) @@ -736,8 +677,8 @@ static bool process_mem_region(struct mem_vector *region, #ifdef CONFIG_EFI /* - * Returns true if mirror region found (and must have been processed - * for slots adding) + * Returns true if we processed the EFI memmap, which we prefer over the E820 + * table if it is available. */ static bool process_efi_entries(unsigned long minimum, unsigned long image_size) @@ -839,20 +780,30 @@ static void process_e820_entries(unsigned long minimum, static unsigned long find_random_phys_addr(unsigned long minimum, unsigned long image_size) { + u64 phys_addr; + + /* Bail out early if it's impossible to succeed. */ + if (minimum + image_size > mem_limit) + return 0; + /* Check if we had too many memmaps. */ if (memmap_too_large) { debug_putstr("Aborted memory entries scan (more than 4 memmap= args)!\n"); return 0; } - /* Make sure minimum is aligned. */ - minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN); + if (!process_efi_entries(minimum, image_size)) + process_e820_entries(minimum, image_size); - if (process_efi_entries(minimum, image_size)) - return slots_fetch_random(); + phys_addr = slots_fetch_random(); - process_e820_entries(minimum, image_size); - return slots_fetch_random(); + /* Perform a final check to make sure the address is in range. */ + if (phys_addr < minimum || phys_addr + image_size > mem_limit) { + warn("Invalid physical address chosen!\n"); + return 0; + } + + return (unsigned long)phys_addr; } static unsigned long find_random_virt_addr(unsigned long minimum, @@ -860,18 +811,12 @@ static unsigned long find_random_virt_addr(unsigned long minimum, { unsigned long slots, random_addr; - /* Make sure minimum is aligned. */ - minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN); - /* Align image_size for easy slot calculations. */ - image_size = ALIGN(image_size, CONFIG_PHYSICAL_ALIGN); - /* * There are how many CONFIG_PHYSICAL_ALIGN-sized slots * that can hold image_size within the range of minimum to * KERNEL_IMAGE_SIZE? */ - slots = (KERNEL_IMAGE_SIZE - minimum - image_size) / - CONFIG_PHYSICAL_ALIGN + 1; + slots = 1 + (KERNEL_IMAGE_SIZE - minimum - image_size) / CONFIG_PHYSICAL_ALIGN; random_addr = kaslr_get_random_long("Virtual") % slots; @@ -895,18 +840,12 @@ void choose_random_location(unsigned long input, return; } -#ifdef CONFIG_X86_5LEVEL - if (__read_cr4() & X86_CR4_LA57) { - __pgtable_l5_enabled = 1; - pgdir_shift = 48; - ptrs_per_p4d = 512; - } -#endif - boot_params->hdr.loadflags |= KASLR_FLAG; - /* Prepare to add new identity pagetables on demand. */ - initialize_identity_maps(); + if (IS_ENABLED(CONFIG_X86_32)) + mem_limit = KERNEL_IMAGE_SIZE; + else + mem_limit = MAXMEM; /* Record the various known unsafe memory ranges. */ mem_avoid_init(input, input_size, *output); @@ -917,6 +856,8 @@ void choose_random_location(unsigned long input, * location: */ min_addr = min(*output, 512UL << 20); + /* Make sure minimum is aligned. */ + min_addr = ALIGN(min_addr, CONFIG_PHYSICAL_ALIGN); /* Walk available memory entries to find a random address. */ random_addr = find_random_phys_addr(min_addr, output_size); @@ -924,19 +865,8 @@ void choose_random_location(unsigned long input, warn("Physical KASLR disabled: no suitable memory region!"); } else { /* Update the new physical address location. */ - if (*output != random_addr) { - add_identity_map(random_addr, output_size); + if (*output != random_addr) *output = random_addr; - } - - /* - * This loads the identity mapping page table. - * This should only be done if a new physical address - * is found for the kernel, otherwise we should keep - * the old page table to make it be like the "nokaslr" - * case. - */ - finalize_identity_maps(); } diff --git a/arch/x86/boot/compressed/kaslr_64.c b/arch/x86/boot/compressed/kaslr_64.c deleted file mode 100644 index f9c5c13d979b..000000000000 --- a/arch/x86/boot/compressed/kaslr_64.c +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * This code is used on x86_64 to create page table identity mappings on - * demand by building up a new set of page tables (or appending to the - * existing ones), and then switching over to them when ready. - * - * Copyright (C) 2015-2016 Yinghai Lu - * Copyright (C) 2016 Kees Cook - */ - -/* - * Since we're dealing with identity mappings, physical and virtual - * addresses are the same, so override these defines which are ultimately - * used by the headers in misc.h. - */ -#define __pa(x) ((unsigned long)(x)) -#define __va(x) ((void *)((unsigned long)(x))) - -/* No PAGE_TABLE_ISOLATION support needed either: */ -#undef CONFIG_PAGE_TABLE_ISOLATION - -#include "misc.h" - -/* These actually do the work of building the kernel identity maps. */ -#include <linux/pgtable.h> -#include <asm/init.h> -/* Use the static base for this part of the boot process */ -#undef __PAGE_OFFSET -#define __PAGE_OFFSET __PAGE_OFFSET_BASE -#include "../../mm/ident_map.c" - -/* Used to track our page table allocation area. */ -struct alloc_pgt_data { - unsigned char *pgt_buf; - unsigned long pgt_buf_size; - unsigned long pgt_buf_offset; -}; - -/* - * Allocates space for a page table entry, using struct alloc_pgt_data - * above. Besides the local callers, this is used as the allocation - * callback in mapping_info below. - */ -static void *alloc_pgt_page(void *context) -{ - struct alloc_pgt_data *pages = (struct alloc_pgt_data *)context; - unsigned char *entry; - - /* Validate there is space available for a new page. */ - if (pages->pgt_buf_offset >= pages->pgt_buf_size) { - debug_putstr("out of pgt_buf in " __FILE__ "!?\n"); - debug_putaddr(pages->pgt_buf_offset); - debug_putaddr(pages->pgt_buf_size); - return NULL; - } - - entry = pages->pgt_buf + pages->pgt_buf_offset; - pages->pgt_buf_offset += PAGE_SIZE; - - return entry; -} - -/* Used to track our allocated page tables. */ -static struct alloc_pgt_data pgt_data; - -/* The top level page table entry pointer. */ -static unsigned long top_level_pgt; - -phys_addr_t physical_mask = (1ULL << __PHYSICAL_MASK_SHIFT) - 1; - -/* - * Mapping information structure passed to kernel_ident_mapping_init(). - * Due to relocation, pointers must be assigned at run time not build time. - */ -static struct x86_mapping_info mapping_info; - -/* Locates and clears a region for a new top level page table. */ -void initialize_identity_maps(void) -{ - /* If running as an SEV guest, the encryption mask is required. */ - set_sev_encryption_mask(); - - /* Exclude the encryption mask from __PHYSICAL_MASK */ - physical_mask &= ~sme_me_mask; - - /* Init mapping_info with run-time function/buffer pointers. */ - mapping_info.alloc_pgt_page = alloc_pgt_page; - mapping_info.context = &pgt_data; - mapping_info.page_flag = __PAGE_KERNEL_LARGE_EXEC | sme_me_mask; - mapping_info.kernpg_flag = _KERNPG_TABLE; - - /* - * It should be impossible for this not to already be true, - * but since calling this a second time would rewind the other - * counters, let's just make sure this is reset too. - */ - pgt_data.pgt_buf_offset = 0; - - /* - * If we came here via startup_32(), cr3 will be _pgtable already - * and we must append to the existing area instead of entirely - * overwriting it. - * - * With 5-level paging, we use '_pgtable' to allocate the p4d page table, - * the top-level page table is allocated separately. - * - * p4d_offset(top_level_pgt, 0) would cover both the 4- and 5-level - * cases. On 4-level paging it's equal to 'top_level_pgt'. - */ - top_level_pgt = read_cr3_pa(); - if (p4d_offset((pgd_t *)top_level_pgt, 0) == (p4d_t *)_pgtable) { - debug_putstr("booted via startup_32()\n"); - pgt_data.pgt_buf = _pgtable + BOOT_INIT_PGT_SIZE; - pgt_data.pgt_buf_size = BOOT_PGT_SIZE - BOOT_INIT_PGT_SIZE; - memset(pgt_data.pgt_buf, 0, pgt_data.pgt_buf_size); - } else { - debug_putstr("booted via startup_64()\n"); - pgt_data.pgt_buf = _pgtable; - pgt_data.pgt_buf_size = BOOT_PGT_SIZE; - memset(pgt_data.pgt_buf, 0, pgt_data.pgt_buf_size); - top_level_pgt = (unsigned long)alloc_pgt_page(&pgt_data); - } -} - -/* - * Adds the specified range to what will become the new identity mappings. - * Once all ranges have been added, the new mapping is activated by calling - * finalize_identity_maps() below. - */ -void add_identity_map(unsigned long start, unsigned long size) -{ - unsigned long end = start + size; - - /* Align boundary to 2M. */ - start = round_down(start, PMD_SIZE); - end = round_up(end, PMD_SIZE); - if (start >= end) - return; - - /* Build the mapping. */ - kernel_ident_mapping_init(&mapping_info, (pgd_t *)top_level_pgt, - start, end); -} - -/* - * This switches the page tables to the new level4 that has been built - * via calls to add_identity_map() above. If booted via startup_32(), - * this is effectively a no-op. - */ -void finalize_identity_maps(void) -{ - write_cr3(top_level_pgt); -} diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index e478e40fbe5a..267e7f93050e 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -442,6 +442,13 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, parse_elf(output); handle_relocations(output, output_len, virt_addr); debug_putstr("done.\nBooting the kernel.\n"); + + /* + * Flush GHCB from cache and map it encrypted again when running as + * SEV-ES guest. + */ + sev_es_shutdown_ghcb(); + return output; } diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index 726e264410ff..6d31f1b4c4d1 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -23,6 +23,7 @@ #include <asm/page.h> #include <asm/boot.h> #include <asm/bootparam.h> +#include <asm/desc_defs.h> #define BOOT_CTYPE_H #include <linux/acpi.h> @@ -36,6 +37,9 @@ #define memptr unsigned #endif +/* boot/compressed/vmlinux start and end markers */ +extern char _head[], _end[]; + /* misc.c */ extern memptr free_mem_ptr; extern memptr free_mem_end_ptr; @@ -70,8 +74,8 @@ int cmdline_find_option(const char *option, char *buffer, int bufsize); int cmdline_find_option_bool(const char *option); struct mem_vector { - unsigned long long start; - unsigned long long size; + u64 start; + u64 size; }; #if CONFIG_RANDOMIZE_BASE @@ -81,8 +85,6 @@ void choose_random_location(unsigned long input, unsigned long *output, unsigned long output_size, unsigned long *virt_addr); -/* cpuflags.c */ -bool has_cpuflag(int flag); #else static inline void choose_random_location(unsigned long input, unsigned long input_size, @@ -93,18 +95,14 @@ static inline void choose_random_location(unsigned long input, } #endif +/* cpuflags.c */ +bool has_cpuflag(int flag); + #ifdef CONFIG_X86_64 -void initialize_identity_maps(void); -void add_identity_map(unsigned long start, unsigned long size); -void finalize_identity_maps(void); +extern int set_page_decrypted(unsigned long address); +extern int set_page_encrypted(unsigned long address); +extern int set_page_non_present(unsigned long address); extern unsigned char _pgtable[]; -#else -static inline void initialize_identity_maps(void) -{ } -static inline void add_identity_map(unsigned long start, unsigned long size) -{ } -static inline void finalize_identity_maps(void) -{ } #endif #ifdef CONFIG_EARLY_PRINTK @@ -119,6 +117,17 @@ static inline void console_init(void) void set_sev_encryption_mask(void); +#ifdef CONFIG_AMD_MEM_ENCRYPT +void sev_es_shutdown_ghcb(void); +extern bool sev_es_check_ghcb_fault(unsigned long address); +#else +static inline void sev_es_shutdown_ghcb(void) { } +static inline bool sev_es_check_ghcb_fault(unsigned long address) +{ + return false; +} +#endif + /* acpi.c */ #ifdef CONFIG_ACPI acpi_physical_address get_rsdp_addr(void); @@ -133,4 +142,21 @@ int count_immovable_mem_regions(void); static inline int count_immovable_mem_regions(void) { return 0; } #endif +/* ident_map_64.c */ +#ifdef CONFIG_X86_5LEVEL +extern unsigned int __pgtable_l5_enabled, pgdir_shift, ptrs_per_p4d; +#endif + +/* Used by PAGE_KERN* macros: */ +extern pteval_t __default_kernel_pte_mask; + +/* idt_64.c */ +extern gate_desc boot_idt[BOOT_IDT_ENTRIES]; +extern struct desc_ptr boot_idt_desc; + +/* IDT Entry Points */ +void boot_page_fault(void); +void boot_stage1_vc(void); +void boot_stage2_vc(void); + #endif /* BOOT_COMPRESSED_MISC_H */ diff --git a/arch/x86/boot/compressed/mkpiggy.c b/arch/x86/boot/compressed/mkpiggy.c index 7e01248765b2..52aa56cdbacc 100644 --- a/arch/x86/boot/compressed/mkpiggy.c +++ b/arch/x86/boot/compressed/mkpiggy.c @@ -60,6 +60,12 @@ int main(int argc, char *argv[]) printf(".incbin \"%s\"\n", argv[1]); printf("input_data_end:\n"); + printf(".section \".rodata\",\"a\",@progbits\n"); + printf(".globl input_len\n"); + printf("input_len:\n\t.long %lu\n", ilen); + printf(".globl output_len\n"); + printf("output_len:\n\t.long %lu\n", (unsigned long)olen); + retval = 0; bail: if (f) diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c index c8862696a47b..2a78746f5a4c 100644 --- a/arch/x86/boot/compressed/pgtable_64.c +++ b/arch/x86/boot/compressed/pgtable_64.c @@ -5,18 +5,16 @@ #include "pgtable.h" #include "../string.h" -/* - * __force_order is used by special_insns.h asm code to force instruction - * serialization. - * - * It is not referenced from the code, but GCC < 5 with -fPIE would fail - * due to an undefined symbol. Define it to make these ancient GCCs work. - */ -unsigned long __force_order; - #define BIOS_START_MIN 0x20000U /* 128K, less than this is insane */ #define BIOS_START_MAX 0x9f000U /* 640K, absolute maximum */ +#ifdef CONFIG_X86_5LEVEL +/* __pgtable_l5_enabled needs to be in .data to avoid being cleared along with .bss */ +unsigned int __section(".data") __pgtable_l5_enabled; +unsigned int __section(".data") pgdir_shift = 39; +unsigned int __section(".data") ptrs_per_p4d = 1; +#endif + struct paging_config { unsigned long trampoline_start; unsigned long l5_required; @@ -32,7 +30,7 @@ static char trampoline_save[TRAMPOLINE_32BIT_SIZE]; * Avoid putting the pointer into .bss as it will be cleared between * paging_prepare() and extract_kernel(). */ -unsigned long *trampoline_32bit __section(.data); +unsigned long *trampoline_32bit __section(".data"); extern struct boot_params *boot_params; int cmdline_find_option_bool(const char *option); @@ -207,4 +205,13 @@ void cleanup_trampoline(void *pgtable) /* Restore trampoline memory */ memcpy(trampoline_32bit, trampoline_save, TRAMPOLINE_32BIT_SIZE); + + /* Initialize variables for 5-level paging */ +#ifdef CONFIG_X86_5LEVEL + if (__read_cr4() & X86_CR4_LA57) { + __pgtable_l5_enabled = 1; + pgdir_shift = 48; + ptrs_per_p4d = 512; + } +#endif } diff --git a/arch/x86/boot/compressed/sev-es.c b/arch/x86/boot/compressed/sev-es.c new file mode 100644 index 000000000000..954cb2702e23 --- /dev/null +++ b/arch/x86/boot/compressed/sev-es.c @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD Encrypted Register State Support + * + * Author: Joerg Roedel <jroedel@suse.de> + */ + +/* + * misc.h needs to be first because it knows how to include the other kernel + * headers in the pre-decompression code in a way that does not break + * compilation. + */ +#include "misc.h" + +#include <asm/pgtable_types.h> +#include <asm/sev-es.h> +#include <asm/trapnr.h> +#include <asm/trap_pf.h> +#include <asm/msr-index.h> +#include <asm/fpu/xcr.h> +#include <asm/ptrace.h> +#include <asm/svm.h> + +#include "error.h" + +struct ghcb boot_ghcb_page __aligned(PAGE_SIZE); +struct ghcb *boot_ghcb; + +/* + * Copy a version of this function here - insn-eval.c can't be used in + * pre-decompression code. + */ +static bool insn_has_rep_prefix(struct insn *insn) +{ + int i; + + insn_get_prefixes(insn); + + for (i = 0; i < insn->prefixes.nbytes; i++) { + insn_byte_t p = insn->prefixes.bytes[i]; + + if (p == 0xf2 || p == 0xf3) + return true; + } + + return false; +} + +/* + * Only a dummy for insn_get_seg_base() - Early boot-code is 64bit only and + * doesn't use segments. + */ +static unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx) +{ + return 0UL; +} + +static inline u64 sev_es_rd_ghcb_msr(void) +{ + unsigned long low, high; + + asm volatile("rdmsr" : "=a" (low), "=d" (high) : + "c" (MSR_AMD64_SEV_ES_GHCB)); + + return ((high << 32) | low); +} + +static inline void sev_es_wr_ghcb_msr(u64 val) +{ + u32 low, high; + + low = val & 0xffffffffUL; + high = val >> 32; + + asm volatile("wrmsr" : : "c" (MSR_AMD64_SEV_ES_GHCB), + "a"(low), "d" (high) : "memory"); +} + +static enum es_result vc_decode_insn(struct es_em_ctxt *ctxt) +{ + char buffer[MAX_INSN_SIZE]; + enum es_result ret; + + memcpy(buffer, (unsigned char *)ctxt->regs->ip, MAX_INSN_SIZE); + + insn_init(&ctxt->insn, buffer, MAX_INSN_SIZE, 1); + insn_get_length(&ctxt->insn); + + ret = ctxt->insn.immediate.got ? ES_OK : ES_DECODE_FAILED; + + return ret; +} + +static enum es_result vc_write_mem(struct es_em_ctxt *ctxt, + void *dst, char *buf, size_t size) +{ + memcpy(dst, buf, size); + + return ES_OK; +} + +static enum es_result vc_read_mem(struct es_em_ctxt *ctxt, + void *src, char *buf, size_t size) +{ + memcpy(buf, src, size); + + return ES_OK; +} + +#undef __init +#undef __pa +#define __init +#define __pa(x) ((unsigned long)(x)) + +#define __BOOT_COMPRESSED + +/* Basic instruction decoding support needed */ +#include "../../lib/inat.c" +#include "../../lib/insn.c" + +/* Include code for early handlers */ +#include "../../kernel/sev-es-shared.c" + +static bool early_setup_sev_es(void) +{ + if (!sev_es_negotiate_protocol()) + sev_es_terminate(GHCB_SEV_ES_REASON_PROTOCOL_UNSUPPORTED); + + if (set_page_decrypted((unsigned long)&boot_ghcb_page)) + return false; + + /* Page is now mapped decrypted, clear it */ + memset(&boot_ghcb_page, 0, sizeof(boot_ghcb_page)); + + boot_ghcb = &boot_ghcb_page; + + /* Initialize lookup tables for the instruction decoder */ + inat_init_tables(); + + return true; +} + +void sev_es_shutdown_ghcb(void) +{ + if (!boot_ghcb) + return; + + if (!sev_es_check_cpu_features()) + error("SEV-ES CPU Features missing."); + + /* + * GHCB Page must be flushed from the cache and mapped encrypted again. + * Otherwise the running kernel will see strange cache effects when + * trying to use that page. + */ + if (set_page_encrypted((unsigned long)&boot_ghcb_page)) + error("Can't map GHCB page encrypted"); + + /* + * GHCB page is mapped encrypted again and flushed from the cache. + * Mark it non-present now to catch bugs when #VC exceptions trigger + * after this point. + */ + if (set_page_non_present((unsigned long)&boot_ghcb_page)) + error("Can't unmap GHCB page"); +} + +bool sev_es_check_ghcb_fault(unsigned long address) +{ + /* Check whether the fault was on the GHCB page */ + return ((address & PAGE_MASK) == (unsigned long)&boot_ghcb_page); +} + +void do_boot_stage2_vc(struct pt_regs *regs, unsigned long exit_code) +{ + struct es_em_ctxt ctxt; + enum es_result result; + + if (!boot_ghcb && !early_setup_sev_es()) + sev_es_terminate(GHCB_SEV_ES_REASON_GENERAL_REQUEST); + + vc_ghcb_invalidate(boot_ghcb); + result = vc_init_em_ctxt(&ctxt, regs, exit_code); + if (result != ES_OK) + goto finish; + + switch (exit_code) { + case SVM_EXIT_RDTSC: + case SVM_EXIT_RDTSCP: + result = vc_handle_rdtsc(boot_ghcb, &ctxt, exit_code); + break; + case SVM_EXIT_IOIO: + result = vc_handle_ioio(boot_ghcb, &ctxt); + break; + case SVM_EXIT_CPUID: + result = vc_handle_cpuid(boot_ghcb, &ctxt); + break; + default: + result = ES_UNSUPPORTED; + break; + } + +finish: + if (result == ES_OK) { + vc_finish_insn(&ctxt); + } else if (result != ES_RETRY) { + /* + * For now, just halt the machine. That makes debugging easier, + * later we just call sev_es_terminate() here. + */ + while (true) + asm volatile("hlt\n"); + } +} diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S index 8f1025d1f681..112b2375d021 100644 --- a/arch/x86/boot/compressed/vmlinux.lds.S +++ b/arch/x86/boot/compressed/vmlinux.lds.S @@ -42,12 +42,6 @@ SECTIONS *(.rodata.*) _erodata = . ; } - .got : { - _got = .; - KEEP(*(.got.plt)) - KEEP(*(.got)) - _egot = .; - } .data : { _data = . ; *(.data) @@ -75,5 +69,49 @@ SECTIONS . = ALIGN(PAGE_SIZE); /* keep ZO size page aligned */ _end = .; + STABS_DEBUG + DWARF_DEBUG + ELF_DETAILS + DISCARDS + /DISCARD/ : { + *(.dynamic) *(.dynsym) *(.dynstr) *(.dynbss) + *(.hash) *(.gnu.hash) + *(.note.*) + } + + .got.plt (INFO) : { + *(.got.plt) + } + ASSERT(SIZEOF(.got.plt) == 0 || +#ifdef CONFIG_X86_64 + SIZEOF(.got.plt) == 0x18, +#else + SIZEOF(.got.plt) == 0xc, +#endif + "Unexpected GOT/PLT entries detected!") + + /* + * Sections that should stay zero sized, which is safer to + * explicitly check instead of blindly discarding. + */ + .got : { + *(.got) + } + ASSERT(SIZEOF(.got) == 0, "Unexpected GOT entries detected!") + + .plt : { + *(.plt) *(.plt.*) + } + ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!") + + .rel.dyn : { + *(.rel.*) *(.rel_*) + } + ASSERT(SIZEOF(.rel.dyn) == 0, "Unexpected run-time relocations (.rel) detected!") + + .rela.dyn : { + *(.rela.*) *(.rela_*) + } + ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!") } diff --git a/arch/x86/boot/setup.ld b/arch/x86/boot/setup.ld index 24c95522f231..49546c247ae2 100644 --- a/arch/x86/boot/setup.ld +++ b/arch/x86/boot/setup.ld @@ -20,7 +20,7 @@ SECTIONS .initdata : { *(.initdata) } __end_init = .; - .text : { *(.text) } + .text : { *(.text .text.*) } .text32 : { *(.text32) } . = ALIGN(16); diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c index c8b8c1a8d1fc..a3725ad46c5a 100644 --- a/arch/x86/boot/tools/build.c +++ b/arch/x86/boot/tools/build.c @@ -416,8 +416,6 @@ int main(int argc, char ** argv) /* Set the default root device */ put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]); - printf("Setup is %d bytes (padded to %d bytes).\n", c, i); - /* Open and stat the kernel file */ fd = open(argv[2], O_RDONLY); if (fd < 0) @@ -425,7 +423,6 @@ int main(int argc, char ** argv) if (fstat(fd, &sb)) die("Unable to stat `%s': %m", argv[2]); sz = sb.st_size; - printf("System is %d kB\n", (sz+1023)/1024); kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0); if (kernel == MAP_FAILED) die("Unable to mmap '%s': %m", argv[2]); @@ -488,7 +485,6 @@ int main(int argc, char ** argv) } /* Write the CRC */ - printf("CRC %x\n", crc); put_unaligned_le32(crc, buf); if (fwrite(buf, 1, 4, dest) != 4) die("Writing CRC failed"); diff --git a/arch/x86/boot/tty.c b/arch/x86/boot/tty.c index 1fedabdb95ad..f7eb976b0a4b 100644 --- a/arch/x86/boot/tty.c +++ b/arch/x86/boot/tty.c @@ -25,7 +25,7 @@ int early_serial_base; * error during initialization. */ -static void __attribute__((section(".inittext"))) serial_putchar(int ch) +static void __section(".inittext") serial_putchar(int ch) { unsigned timeout = 0xffff; @@ -35,7 +35,7 @@ static void __attribute__((section(".inittext"))) serial_putchar(int ch) outb(ch, early_serial_base + TXR); } -static void __attribute__((section(".inittext"))) bios_putchar(int ch) +static void __section(".inittext") bios_putchar(int ch) { struct biosregs ireg; @@ -47,7 +47,7 @@ static void __attribute__((section(".inittext"))) bios_putchar(int ch) intcall(0x10, &ireg, NULL); } -void __attribute__((section(".inittext"))) putchar(int ch) +void __section(".inittext") putchar(int ch) { if (ch == '\n') putchar('\r'); /* \n -> \r\n */ @@ -58,7 +58,7 @@ void __attribute__((section(".inittext"))) putchar(int ch) serial_putchar(ch); } -void __attribute__((section(".inittext"))) puts(const char *str) +void __section(".inittext") puts(const char *str) { while (*str) putchar(*str++); diff --git a/arch/x86/boot/video.h b/arch/x86/boot/video.h index cbf7fed22441..04bde0bb2003 100644 --- a/arch/x86/boot/video.h +++ b/arch/x86/boot/video.h @@ -78,7 +78,7 @@ struct card_info { u16 xmode_n; /* Size of unprobed mode range */ }; -#define __videocard struct card_info __attribute__((used,section(".videocards"))) +#define __videocard struct card_info __section(".videocards") __attribute__((used)) extern struct card_info video_cards[], video_cards_end[]; int mode_defined(u16 mode); /* video.c */ diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index d7577fece9eb..78210793d357 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -19,6 +19,7 @@ CONFIG_CGROUP_CPUACCT=y CONFIG_BLK_DEV_INITRD=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y +# CONFIG_64BIT is not set CONFIG_SMP=y CONFIG_X86_GENERIC=y CONFIG_HPET_TIMER=y @@ -186,7 +187,6 @@ CONFIG_DRM_I915=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y CONFIG_FB_EFI=y -CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index f85600143747..9936528e1939 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -181,7 +181,6 @@ CONFIG_DRM_I915=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y CONFIG_FB_EFI=y -CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set diff --git a/arch/x86/crypto/blake2s-glue.c b/arch/x86/crypto/blake2s-glue.c index 6737bcea1fa1..c025a01cf708 100644 --- a/arch/x86/crypto/blake2s-glue.c +++ b/arch/x86/crypto/blake2s-glue.c @@ -11,6 +11,7 @@ #include <linux/jump_label.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/sizes.h> #include <asm/cpufeature.h> #include <asm/fpu/api.h> diff --git a/arch/x86/crypto/chacha_glue.c b/arch/x86/crypto/chacha_glue.c index e67a59130025..7b3a1cf0984b 100644 --- a/arch/x86/crypto/chacha_glue.c +++ b/arch/x86/crypto/chacha_glue.c @@ -12,6 +12,7 @@ #include <crypto/internal/skcipher.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/sizes.h> #include <asm/simd.h> asmlinkage void chacha_block_xor_ssse3(u32 *state, u8 *dst, const u8 *src, diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c index d2d069bd459b..feccb5254c7e 100644 --- a/arch/x86/crypto/crc32c-intel_glue.c +++ b/arch/x86/crypto/crc32c-intel_glue.c @@ -28,9 +28,9 @@ #define SCALE_F sizeof(unsigned long) #ifdef CONFIG_X86_64 -#define REX_PRE "0x48, " +#define CRC32_INST "crc32q %1, %q0" #else -#define REX_PRE +#define CRC32_INST "crc32l %1, %0" #endif #ifdef CONFIG_X86_64 @@ -48,11 +48,8 @@ asmlinkage unsigned int crc_pcl(const u8 *buffer, int len, static u32 crc32c_intel_le_hw_byte(u32 crc, unsigned char const *data, size_t length) { while (length--) { - __asm__ __volatile__( - ".byte 0xf2, 0xf, 0x38, 0xf0, 0xf1" - :"=S"(crc) - :"0"(crc), "c"(*data) - ); + asm("crc32b %1, %0" + : "+r" (crc) : "rm" (*data)); data++; } @@ -66,11 +63,8 @@ static u32 __pure crc32c_intel_le_hw(u32 crc, unsigned char const *p, size_t len unsigned long *ptmp = (unsigned long *)p; while (iquotient--) { - __asm__ __volatile__( - ".byte 0xf2, " REX_PRE "0xf, 0x38, 0xf1, 0xf1;" - :"=S"(crc) - :"0"(crc), "c"(*ptmp) - ); + asm(CRC32_INST + : "+r" (crc) : "rm" (*ptmp)); ptmp++; } diff --git a/arch/x86/crypto/curve25519-x86_64.c b/arch/x86/crypto/curve25519-x86_64.c index 8acbb6584a37..5af8021b98ce 100644 --- a/arch/x86/crypto/curve25519-x86_64.c +++ b/arch/x86/crypto/curve25519-x86_64.c @@ -11,6 +11,7 @@ #include <linux/jump_label.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/scatterlist.h> #include <asm/cpufeature.h> #include <asm/processor.h> @@ -45,11 +46,11 @@ static inline u64 add_scalar(u64 *out, const u64 *f1, u64 f2) asm volatile( /* Clear registers to propagate the carry bit */ - " xor %%r8, %%r8;" - " xor %%r9, %%r9;" - " xor %%r10, %%r10;" - " xor %%r11, %%r11;" - " xor %1, %1;" + " xor %%r8d, %%r8d;" + " xor %%r9d, %%r9d;" + " xor %%r10d, %%r10d;" + " xor %%r11d, %%r11d;" + " xor %k1, %k1;" /* Begin addition chain */ " addq 0(%3), %0;" @@ -93,7 +94,7 @@ static inline void fadd(u64 *out, const u64 *f1, const u64 *f2) " cmovc %0, %%rax;" /* Step 2: Add carry*38 to the original sum */ - " xor %%rcx, %%rcx;" + " xor %%ecx, %%ecx;" " add %%rax, %%r8;" " adcx %%rcx, %%r9;" " movq %%r9, 8(%1);" @@ -165,28 +166,28 @@ static inline void fmul(u64 *out, const u64 *f1, const u64 *f2, u64 *tmp) /* Compute src1[0] * src2 */ " movq 0(%1), %%rdx;" - " mulxq 0(%3), %%r8, %%r9;" " xor %%r10, %%r10;" " movq %%r8, 0(%0);" + " mulxq 0(%3), %%r8, %%r9;" " xor %%r10d, %%r10d;" " movq %%r8, 0(%0);" " mulxq 8(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " movq %%r10, 8(%0);" " mulxq 16(%3), %%rbx, %%r13;" " adox %%r11, %%rbx;" " mulxq 24(%3), %%r14, %%rdx;" " adox %%r13, %%r14;" " mov $0, %%rax;" " adox %%rdx, %%rax;" /* Compute src1[1] * src2 */ " movq 8(%1), %%rdx;" - " mulxq 0(%3), %%r8, %%r9;" " xor %%r10, %%r10;" " adcxq 8(%0), %%r8;" " movq %%r8, 8(%0);" + " mulxq 0(%3), %%r8, %%r9;" " xor %%r10d, %%r10d;" " adcxq 8(%0), %%r8;" " movq %%r8, 8(%0);" " mulxq 8(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " adcx %%rbx, %%r10;" " movq %%r10, 16(%0);" " mulxq 16(%3), %%rbx, %%r13;" " adox %%r11, %%rbx;" " adcx %%r14, %%rbx;" " mov $0, %%r8;" " mulxq 24(%3), %%r14, %%rdx;" " adox %%r13, %%r14;" " adcx %%rax, %%r14;" " mov $0, %%rax;" " adox %%rdx, %%rax;" " adcx %%r8, %%rax;" /* Compute src1[2] * src2 */ " movq 16(%1), %%rdx;" - " mulxq 0(%3), %%r8, %%r9;" " xor %%r10, %%r10;" " adcxq 16(%0), %%r8;" " movq %%r8, 16(%0);" + " mulxq 0(%3), %%r8, %%r9;" " xor %%r10d, %%r10d;" " adcxq 16(%0), %%r8;" " movq %%r8, 16(%0);" " mulxq 8(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " adcx %%rbx, %%r10;" " movq %%r10, 24(%0);" " mulxq 16(%3), %%rbx, %%r13;" " adox %%r11, %%rbx;" " adcx %%r14, %%rbx;" " mov $0, %%r8;" " mulxq 24(%3), %%r14, %%rdx;" " adox %%r13, %%r14;" " adcx %%rax, %%r14;" " mov $0, %%rax;" " adox %%rdx, %%rax;" " adcx %%r8, %%rax;" /* Compute src1[3] * src2 */ " movq 24(%1), %%rdx;" - " mulxq 0(%3), %%r8, %%r9;" " xor %%r10, %%r10;" " adcxq 24(%0), %%r8;" " movq %%r8, 24(%0);" + " mulxq 0(%3), %%r8, %%r9;" " xor %%r10d, %%r10d;" " adcxq 24(%0), %%r8;" " movq %%r8, 24(%0);" " mulxq 8(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " adcx %%rbx, %%r10;" " movq %%r10, 32(%0);" " mulxq 16(%3), %%rbx, %%r13;" " adox %%r11, %%rbx;" " adcx %%r14, %%rbx;" " movq %%rbx, 40(%0);" " mov $0, %%r8;" " mulxq 24(%3), %%r14, %%rdx;" " adox %%r13, %%r14;" " adcx %%rax, %%r14;" " movq %%r14, 48(%0);" " mov $0, %%rax;" @@ -200,7 +201,7 @@ static inline void fmul(u64 *out, const u64 *f1, const u64 *f2, u64 *tmp) /* Step 1: Compute dst + carry == tmp_hi * 38 + tmp_lo */ " mov $38, %%rdx;" " mulxq 32(%1), %%r8, %%r13;" - " xor %3, %3;" + " xor %k3, %k3;" " adoxq 0(%1), %%r8;" " mulxq 40(%1), %%r9, %%rbx;" " adcx %%r13, %%r9;" @@ -246,28 +247,28 @@ static inline void fmul2(u64 *out, const u64 *f1, const u64 *f2, u64 *tmp) /* Compute src1[0] * src2 */ " movq 0(%1), %%rdx;" - " mulxq 0(%3), %%r8, %%r9;" " xor %%r10, %%r10;" " movq %%r8, 0(%0);" + " mulxq 0(%3), %%r8, %%r9;" " xor %%r10d, %%r10d;" " movq %%r8, 0(%0);" " mulxq 8(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " movq %%r10, 8(%0);" " mulxq 16(%3), %%rbx, %%r13;" " adox %%r11, %%rbx;" " mulxq 24(%3), %%r14, %%rdx;" " adox %%r13, %%r14;" " mov $0, %%rax;" " adox %%rdx, %%rax;" /* Compute src1[1] * src2 */ " movq 8(%1), %%rdx;" - " mulxq 0(%3), %%r8, %%r9;" " xor %%r10, %%r10;" " adcxq 8(%0), %%r8;" " movq %%r8, 8(%0);" + " mulxq 0(%3), %%r8, %%r9;" " xor %%r10d, %%r10d;" " adcxq 8(%0), %%r8;" " movq %%r8, 8(%0);" " mulxq 8(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " adcx %%rbx, %%r10;" " movq %%r10, 16(%0);" " mulxq 16(%3), %%rbx, %%r13;" " adox %%r11, %%rbx;" " adcx %%r14, %%rbx;" " mov $0, %%r8;" " mulxq 24(%3), %%r14, %%rdx;" " adox %%r13, %%r14;" " adcx %%rax, %%r14;" " mov $0, %%rax;" " adox %%rdx, %%rax;" " adcx %%r8, %%rax;" /* Compute src1[2] * src2 */ " movq 16(%1), %%rdx;" - " mulxq 0(%3), %%r8, %%r9;" " xor %%r10, %%r10;" " adcxq 16(%0), %%r8;" " movq %%r8, 16(%0);" + " mulxq 0(%3), %%r8, %%r9;" " xor %%r10d, %%r10d;" " adcxq 16(%0), %%r8;" " movq %%r8, 16(%0);" " mulxq 8(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " adcx %%rbx, %%r10;" " movq %%r10, 24(%0);" " mulxq 16(%3), %%rbx, %%r13;" " adox %%r11, %%rbx;" " adcx %%r14, %%rbx;" " mov $0, %%r8;" " mulxq 24(%3), %%r14, %%rdx;" " adox %%r13, %%r14;" " adcx %%rax, %%r14;" " mov $0, %%rax;" " adox %%rdx, %%rax;" " adcx %%r8, %%rax;" /* Compute src1[3] * src2 */ " movq 24(%1), %%rdx;" - " mulxq 0(%3), %%r8, %%r9;" " xor %%r10, %%r10;" " adcxq 24(%0), %%r8;" " movq %%r8, 24(%0);" + " mulxq 0(%3), %%r8, %%r9;" " xor %%r10d, %%r10d;" " adcxq 24(%0), %%r8;" " movq %%r8, 24(%0);" " mulxq 8(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " adcx %%rbx, %%r10;" " movq %%r10, 32(%0);" " mulxq 16(%3), %%rbx, %%r13;" " adox %%r11, %%rbx;" " adcx %%r14, %%rbx;" " movq %%rbx, 40(%0);" " mov $0, %%r8;" " mulxq 24(%3), %%r14, %%rdx;" " adox %%r13, %%r14;" " adcx %%rax, %%r14;" " movq %%r14, 48(%0);" " mov $0, %%rax;" @@ -277,29 +278,29 @@ static inline void fmul2(u64 *out, const u64 *f1, const u64 *f2, u64 *tmp) /* Compute src1[0] * src2 */ " movq 32(%1), %%rdx;" - " mulxq 32(%3), %%r8, %%r9;" " xor %%r10, %%r10;" " movq %%r8, 64(%0);" - " mulxq 40(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " movq %%r10, 72(%0);" + " mulxq 32(%3), %%r8, %%r9;" " xor %%r10d, %%r10d;" " movq %%r8, 64(%0);" + " mulxq 40(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " movq %%r10, 72(%0);" " mulxq 48(%3), %%rbx, %%r13;" " adox %%r11, %%rbx;" " mulxq 56(%3), %%r14, %%rdx;" " adox %%r13, %%r14;" " mov $0, %%rax;" " adox %%rdx, %%rax;" /* Compute src1[1] * src2 */ " movq 40(%1), %%rdx;" - " mulxq 32(%3), %%r8, %%r9;" " xor %%r10, %%r10;" " adcxq 72(%0), %%r8;" " movq %%r8, 72(%0);" - " mulxq 40(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " adcx %%rbx, %%r10;" " movq %%r10, 80(%0);" + " mulxq 32(%3), %%r8, %%r9;" " xor %%r10d, %%r10d;" " adcxq 72(%0), %%r8;" " movq %%r8, 72(%0);" + " mulxq 40(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " adcx %%rbx, %%r10;" " movq %%r10, 80(%0);" " mulxq 48(%3), %%rbx, %%r13;" " adox %%r11, %%rbx;" " adcx %%r14, %%rbx;" " mov $0, %%r8;" " mulxq 56(%3), %%r14, %%rdx;" " adox %%r13, %%r14;" " adcx %%rax, %%r14;" " mov $0, %%rax;" " adox %%rdx, %%rax;" " adcx %%r8, %%rax;" /* Compute src1[2] * src2 */ " movq 48(%1), %%rdx;" - " mulxq 32(%3), %%r8, %%r9;" " xor %%r10, %%r10;" " adcxq 80(%0), %%r8;" " movq %%r8, 80(%0);" - " mulxq 40(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " adcx %%rbx, %%r10;" " movq %%r10, 88(%0);" + " mulxq 32(%3), %%r8, %%r9;" " xor %%r10d, %%r10d;" " adcxq 80(%0), %%r8;" " movq %%r8, 80(%0);" + " mulxq 40(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " adcx %%rbx, %%r10;" " movq %%r10, 88(%0);" " mulxq 48(%3), %%rbx, %%r13;" " adox %%r11, %%rbx;" " adcx %%r14, %%rbx;" " mov $0, %%r8;" " mulxq 56(%3), %%r14, %%rdx;" " adox %%r13, %%r14;" " adcx %%rax, %%r14;" " mov $0, %%rax;" " adox %%rdx, %%rax;" " adcx %%r8, %%rax;" /* Compute src1[3] * src2 */ " movq 56(%1), %%rdx;" - " mulxq 32(%3), %%r8, %%r9;" " xor %%r10, %%r10;" " adcxq 88(%0), %%r8;" " movq %%r8, 88(%0);" - " mulxq 40(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " adcx %%rbx, %%r10;" " movq %%r10, 96(%0);" + " mulxq 32(%3), %%r8, %%r9;" " xor %%r10d, %%r10d;" " adcxq 88(%0), %%r8;" " movq %%r8, 88(%0);" + " mulxq 40(%3), %%r10, %%r11;" " adox %%r9, %%r10;" " adcx %%rbx, %%r10;" " movq %%r10, 96(%0);" " mulxq 48(%3), %%rbx, %%r13;" " adox %%r11, %%rbx;" " adcx %%r14, %%rbx;" " movq %%rbx, 104(%0);" " mov $0, %%r8;" " mulxq 56(%3), %%r14, %%rdx;" " adox %%r13, %%r14;" " adcx %%rax, %%r14;" " movq %%r14, 112(%0);" " mov $0, %%rax;" " adox %%rdx, %%rax;" " adcx %%r8, %%rax;" " movq %%rax, 120(%0);" @@ -312,7 +313,7 @@ static inline void fmul2(u64 *out, const u64 *f1, const u64 *f2, u64 *tmp) /* Step 1: Compute dst + carry == tmp_hi * 38 + tmp_lo */ " mov $38, %%rdx;" " mulxq 32(%1), %%r8, %%r13;" - " xor %3, %3;" + " xor %k3, %k3;" " adoxq 0(%1), %%r8;" " mulxq 40(%1), %%r9, %%rbx;" " adcx %%r13, %%r9;" @@ -345,7 +346,7 @@ static inline void fmul2(u64 *out, const u64 *f1, const u64 *f2, u64 *tmp) /* Step 1: Compute dst + carry == tmp_hi * 38 + tmp_lo */ " mov $38, %%rdx;" " mulxq 96(%1), %%r8, %%r13;" - " xor %3, %3;" + " xor %k3, %k3;" " adoxq 64(%1), %%r8;" " mulxq 104(%1), %%r9, %%rbx;" " adcx %%r13, %%r9;" @@ -516,7 +517,7 @@ static inline void fsqr(u64 *out, const u64 *f, u64 *tmp) /* Step 1: Compute all partial products */ " movq 0(%1), %%rdx;" /* f[0] */ - " mulxq 8(%1), %%r8, %%r14;" " xor %%r15, %%r15;" /* f[1]*f[0] */ + " mulxq 8(%1), %%r8, %%r14;" " xor %%r15d, %%r15d;" /* f[1]*f[0] */ " mulxq 16(%1), %%r9, %%r10;" " adcx %%r14, %%r9;" /* f[2]*f[0] */ " mulxq 24(%1), %%rax, %%rcx;" " adcx %%rax, %%r10;" /* f[3]*f[0] */ " movq 24(%1), %%rdx;" /* f[3] */ @@ -526,7 +527,7 @@ static inline void fsqr(u64 *out, const u64 *f, u64 *tmp) " mulxq 16(%1), %%rax, %%rcx;" " mov $0, %%r14;" /* f[2]*f[1] */ /* Step 2: Compute two parallel carry chains */ - " xor %%r15, %%r15;" + " xor %%r15d, %%r15d;" " adox %%rax, %%r10;" " adcx %%r8, %%r8;" " adox %%rcx, %%r11;" @@ -563,7 +564,7 @@ static inline void fsqr(u64 *out, const u64 *f, u64 *tmp) /* Step 1: Compute dst + carry == tmp_hi * 38 + tmp_lo */ " mov $38, %%rdx;" " mulxq 32(%1), %%r8, %%r13;" - " xor %%rcx, %%rcx;" + " xor %%ecx, %%ecx;" " adoxq 0(%1), %%r8;" " mulxq 40(%1), %%r9, %%rbx;" " adcx %%r13, %%r9;" @@ -607,7 +608,7 @@ static inline void fsqr2(u64 *out, const u64 *f, u64 *tmp) asm volatile( /* Step 1: Compute all partial products */ " movq 0(%1), %%rdx;" /* f[0] */ - " mulxq 8(%1), %%r8, %%r14;" " xor %%r15, %%r15;" /* f[1]*f[0] */ + " mulxq 8(%1), %%r8, %%r14;" " xor %%r15d, %%r15d;" /* f[1]*f[0] */ " mulxq 16(%1), %%r9, %%r10;" " adcx %%r14, %%r9;" /* f[2]*f[0] */ " mulxq 24(%1), %%rax, %%rcx;" " adcx %%rax, %%r10;" /* f[3]*f[0] */ " movq 24(%1), %%rdx;" /* f[3] */ @@ -617,7 +618,7 @@ static inline void fsqr2(u64 *out, const u64 *f, u64 *tmp) " mulxq 16(%1), %%rax, %%rcx;" " mov $0, %%r14;" /* f[2]*f[1] */ /* Step 2: Compute two parallel carry chains */ - " xor %%r15, %%r15;" + " xor %%r15d, %%r15d;" " adox %%rax, %%r10;" " adcx %%r8, %%r8;" " adox %%rcx, %%r11;" @@ -647,7 +648,7 @@ static inline void fsqr2(u64 *out, const u64 *f, u64 *tmp) /* Step 1: Compute all partial products */ " movq 32(%1), %%rdx;" /* f[0] */ - " mulxq 40(%1), %%r8, %%r14;" " xor %%r15, %%r15;" /* f[1]*f[0] */ + " mulxq 40(%1), %%r8, %%r14;" " xor %%r15d, %%r15d;" /* f[1]*f[0] */ " mulxq 48(%1), %%r9, %%r10;" " adcx %%r14, %%r9;" /* f[2]*f[0] */ " mulxq 56(%1), %%rax, %%rcx;" " adcx %%rax, %%r10;" /* f[3]*f[0] */ " movq 56(%1), %%rdx;" /* f[3] */ @@ -657,7 +658,7 @@ static inline void fsqr2(u64 *out, const u64 *f, u64 *tmp) " mulxq 48(%1), %%rax, %%rcx;" " mov $0, %%r14;" /* f[2]*f[1] */ /* Step 2: Compute two parallel carry chains */ - " xor %%r15, %%r15;" + " xor %%r15d, %%r15d;" " adox %%rax, %%r10;" " adcx %%r8, %%r8;" " adox %%rcx, %%r11;" @@ -692,7 +693,7 @@ static inline void fsqr2(u64 *out, const u64 *f, u64 *tmp) /* Step 1: Compute dst + carry == tmp_hi * 38 + tmp_lo */ " mov $38, %%rdx;" " mulxq 32(%1), %%r8, %%r13;" - " xor %%rcx, %%rcx;" + " xor %%ecx, %%ecx;" " adoxq 0(%1), %%r8;" " mulxq 40(%1), %%r9, %%rbx;" " adcx %%r13, %%r9;" @@ -725,7 +726,7 @@ static inline void fsqr2(u64 *out, const u64 *f, u64 *tmp) /* Step 1: Compute dst + carry == tmp_hi * 38 + tmp_lo */ " mov $38, %%rdx;" " mulxq 96(%1), %%r8, %%r13;" - " xor %%rcx, %%rcx;" + " xor %%ecx, %%ecx;" " adoxq 64(%1), %%r8;" " mulxq 104(%1), %%r9, %%rbx;" " adcx %%r13, %%r9;" diff --git a/arch/x86/crypto/nhpoly1305-avx2-glue.c b/arch/x86/crypto/nhpoly1305-avx2-glue.c index 80fcb85736e1..8ea5ab0f1ca7 100644 --- a/arch/x86/crypto/nhpoly1305-avx2-glue.c +++ b/arch/x86/crypto/nhpoly1305-avx2-glue.c @@ -10,6 +10,7 @@ #include <crypto/internal/simd.h> #include <crypto/nhpoly1305.h> #include <linux/module.h> +#include <linux/sizes.h> #include <asm/simd.h> asmlinkage void nh_avx2(const u32 *key, const u8 *message, size_t message_len, diff --git a/arch/x86/crypto/nhpoly1305-sse2-glue.c b/arch/x86/crypto/nhpoly1305-sse2-glue.c index cc6b7c1a2705..2b353d42ed13 100644 --- a/arch/x86/crypto/nhpoly1305-sse2-glue.c +++ b/arch/x86/crypto/nhpoly1305-sse2-glue.c @@ -10,6 +10,7 @@ #include <crypto/internal/simd.h> #include <crypto/nhpoly1305.h> #include <linux/module.h> +#include <linux/sizes.h> #include <asm/simd.h> asmlinkage void nh_sse2(const u32 *key, const u8 *message, size_t message_len, diff --git a/arch/x86/crypto/poly1305-x86_64-cryptogams.pl b/arch/x86/crypto/poly1305-x86_64-cryptogams.pl index 137edcf038cb..7d568012cc15 100644 --- a/arch/x86/crypto/poly1305-x86_64-cryptogams.pl +++ b/arch/x86/crypto/poly1305-x86_64-cryptogams.pl @@ -246,7 +246,7 @@ $code.=<<___ if (!$kernel); ___ &declare_function("poly1305_init_x86_64", 32, 3); $code.=<<___; - xor %rax,%rax + xor %eax,%eax mov %rax,0($ctx) # initialize hash value mov %rax,8($ctx) mov %rax,16($ctx) @@ -2853,7 +2853,7 @@ $code.=<<___; .type poly1305_init_base2_44,\@function,3 .align 32 poly1305_init_base2_44: - xor %rax,%rax + xor %eax,%eax mov %rax,0($ctx) # initialize hash value mov %rax,8($ctx) mov %rax,16($ctx) @@ -3947,7 +3947,7 @@ xor128_decrypt_n_pad: mov \$16,$len sub %r10,$len xor %eax,%eax - xor %r11,%r11 + xor %r11d,%r11d .Loop_dec_byte: mov ($inp,$otp),%r11b mov ($otp),%al @@ -4085,7 +4085,7 @@ avx_handler: .long 0xa548f3fc # cld; rep movsq mov $disp,%rsi - xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + xor %ecx,%ecx # arg1, UNW_FLAG_NHANDLER mov 8(%rsi),%rdx # arg2, disp->ImageBase mov 0(%rsi),%r8 # arg3, disp->ControlPc mov 16(%rsi),%r9 # arg4, disp->FunctionEntry diff --git a/arch/x86/crypto/poly1305_glue.c b/arch/x86/crypto/poly1305_glue.c index dfe921efa9b2..e508dbd91813 100644 --- a/arch/x86/crypto/poly1305_glue.c +++ b/arch/x86/crypto/poly1305_glue.c @@ -11,6 +11,7 @@ #include <linux/jump_label.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/sizes.h> #include <asm/intel-family.h> #include <asm/simd.h> @@ -157,9 +158,6 @@ static unsigned int crypto_poly1305_setdctxkey(struct poly1305_desc_ctx *dctx, dctx->s[1] = get_unaligned_le32(&inp[4]); dctx->s[2] = get_unaligned_le32(&inp[8]); dctx->s[3] = get_unaligned_le32(&inp[12]); - inp += POLY1305_BLOCK_SIZE; - len -= POLY1305_BLOCK_SIZE; - acc += POLY1305_BLOCK_SIZE; dctx->sset = true; } } diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h index ae9b0d4615b3..07a9331d55e7 100644 --- a/arch/x86/entry/calling.h +++ b/arch/x86/entry/calling.h @@ -6,7 +6,6 @@ #include <asm/percpu.h> #include <asm/asm-offsets.h> #include <asm/processor-flags.h> -#include <asm/inst.h> /* diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 2f84c7ca74ea..870efeec8bda 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -299,7 +299,7 @@ __visible noinstr void xen_pv_evtchn_do_upcall(struct pt_regs *regs) old_regs = set_irq_regs(regs); instrumentation_begin(); - run_on_irqstack_cond(__xen_pv_evtchn_do_upcall, NULL, regs); + run_on_irqstack_cond(__xen_pv_evtchn_do_upcall, regs); instrumentation_begin(); set_irq_regs(old_regs); diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 70dea9337816..cad08703c4ad 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -46,13 +46,13 @@ .code64 .section .entry.text, "ax" -#ifdef CONFIG_PARAVIRT +#ifdef CONFIG_PARAVIRT_XXL SYM_CODE_START(native_usergs_sysret64) UNWIND_HINT_EMPTY swapgs sysretq SYM_CODE_END(native_usergs_sysret64) -#endif /* CONFIG_PARAVIRT */ +#endif /* CONFIG_PARAVIRT_XXL */ /* * 64-bit SYSCALL instruction entry. Up to 6 arguments in registers. @@ -101,6 +101,8 @@ SYM_CODE_START(entry_SYSCALL_64) SWITCH_TO_KERNEL_CR3 scratch_reg=%rsp movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp +SYM_INNER_LABEL(entry_SYSCALL_64_safe_stack, SYM_L_GLOBAL) + /* Construct struct pt_regs on stack */ pushq $__USER_DS /* pt_regs->ss */ pushq PER_CPU_VAR(cpu_tss_rw + TSS_sp2) /* pt_regs->sp */ @@ -446,6 +448,84 @@ _ASM_NOKPROBE(\asmsym) SYM_CODE_END(\asmsym) .endm +#ifdef CONFIG_AMD_MEM_ENCRYPT +/** + * idtentry_vc - Macro to generate entry stub for #VC + * @vector: Vector number + * @asmsym: ASM symbol for the entry point + * @cfunc: C function to be called + * + * The macro emits code to set up the kernel context for #VC. The #VC handler + * runs on an IST stack and needs to be able to cause nested #VC exceptions. + * + * To make this work the #VC entry code tries its best to pretend it doesn't use + * an IST stack by switching to the task stack if coming from user-space (which + * includes early SYSCALL entry path) or back to the stack in the IRET frame if + * entered from kernel-mode. + * + * If entered from kernel-mode the return stack is validated first, and if it is + * not safe to use (e.g. because it points to the entry stack) the #VC handler + * will switch to a fall-back stack (VC2) and call a special handler function. + * + * The macro is only used for one vector, but it is planned to be extended in + * the future for the #HV exception. + */ +.macro idtentry_vc vector asmsym cfunc +SYM_CODE_START(\asmsym) + UNWIND_HINT_IRET_REGS + ASM_CLAC + + /* + * If the entry is from userspace, switch stacks and treat it as + * a normal entry. + */ + testb $3, CS-ORIG_RAX(%rsp) + jnz .Lfrom_usermode_switch_stack_\@ + + /* + * paranoid_entry returns SWAPGS flag for paranoid_exit in EBX. + * EBX == 0 -> SWAPGS, EBX == 1 -> no SWAPGS + */ + call paranoid_entry + + UNWIND_HINT_REGS + + /* + * Switch off the IST stack to make it free for nested exceptions. The + * vc_switch_off_ist() function will switch back to the interrupted + * stack if it is safe to do so. If not it switches to the VC fall-back + * stack. + */ + movq %rsp, %rdi /* pt_regs pointer */ + call vc_switch_off_ist + movq %rax, %rsp /* Switch to new stack */ + + UNWIND_HINT_REGS + + /* Update pt_regs */ + movq ORIG_RAX(%rsp), %rsi /* get error code into 2nd argument*/ + movq $-1, ORIG_RAX(%rsp) /* no syscall to restart */ + + movq %rsp, %rdi /* pt_regs pointer */ + + call \cfunc + + /* + * No need to switch back to the IST stack. The current stack is either + * identical to the stack in the IRET frame or the VC fall-back stack, + * so it is definitly mapped even with PTI enabled. + */ + jmp paranoid_exit + + /* Switch to the regular task stack */ +.Lfrom_usermode_switch_stack_\@: + idtentry_body safe_stack_\cfunc, has_error_code=1 + +_ASM_NOKPROBE(\asmsym) +SYM_CODE_END(\asmsym) +.endm +#endif + /* * Double fault entry. Straight paranoid. No checks from which context * this comes because for the espfix induced #DF this would do the wrong @@ -682,6 +762,8 @@ SYM_CODE_END(.Lbad_gs) * rdx: Function argument (can be NULL if none) */ SYM_FUNC_START(asm_call_on_stack) +SYM_INNER_LABEL(asm_call_sysvec_on_stack, SYM_L_GLOBAL) +SYM_INNER_LABEL(asm_call_irq_on_stack, SYM_L_GLOBAL) /* * Save the frame pointer unconditionally. This allows the ORC * unwinder to handle the stack switch. @@ -840,8 +922,9 @@ SYM_CODE_START_LOCAL(paranoid_entry) * retrieve and set the current CPUs kernel GSBASE. The stored value * has to be restored in paranoid_exit unconditionally. * - * The MSR write ensures that no subsequent load is based on a - * mispredicted GSBASE. No extra FENCE required. + * The unconditional write to GS base below ensures that no subsequent + * loads based on a mispredicted GS base can happen, therefore no LFENCE + * is needed here. */ SAVE_AND_SET_GSBASE scratch_reg=%rax save_reg=%rbx ret diff --git a/arch/x86/entry/syscall_x32.c b/arch/x86/entry/syscall_x32.c index 1583831f61a9..f2fe0a33bcfd 100644 --- a/arch/x86/entry/syscall_x32.c +++ b/arch/x86/entry/syscall_x32.c @@ -12,8 +12,13 @@ * Reuse the 64-bit entry points for the x32 versions that occupy different * slots in the syscall table. */ +#define __x32_sys_readv __x64_sys_readv +#define __x32_sys_writev __x64_sys_writev #define __x32_sys_getsockopt __x64_sys_getsockopt #define __x32_sys_setsockopt __x64_sys_setsockopt +#define __x32_sys_vmsplice __x64_sys_vmsplice +#define __x32_sys_process_vm_readv __x64_sys_process_vm_readv +#define __x32_sys_process_vm_writev __x64_sys_process_vm_writev #define __SYSCALL_64(nr, sym) diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl index 9d1102873666..0d0667a9fbd7 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl @@ -32,7 +32,7 @@ 18 i386 oldstat sys_stat 19 i386 lseek sys_lseek compat_sys_lseek 20 i386 getpid sys_getpid -21 i386 mount sys_mount compat_sys_mount +21 i386 mount sys_mount 22 i386 umount sys_oldumount 23 i386 setuid sys_setuid16 24 i386 getuid sys_getuid16 @@ -142,7 +142,7 @@ 128 i386 init_module sys_init_module 129 i386 delete_module sys_delete_module 130 i386 get_kernel_syms -131 i386 quotactl sys_quotactl compat_sys_quotactl32 +131 i386 quotactl sys_quotactl 132 i386 getpgid sys_getpgid 133 i386 fchdir sys_fchdir 134 i386 bdflush sys_bdflush @@ -156,8 +156,8 @@ 142 i386 _newselect sys_select compat_sys_select 143 i386 flock sys_flock 144 i386 msync sys_msync -145 i386 readv sys_readv compat_sys_readv -146 i386 writev sys_writev compat_sys_writev +145 i386 readv sys_readv +146 i386 writev sys_writev 147 i386 getsid sys_getsid 148 i386 fdatasync sys_fdatasync 149 i386 _sysctl sys_ni_syscall @@ -327,7 +327,7 @@ 313 i386 splice sys_splice 314 i386 sync_file_range sys_ia32_sync_file_range 315 i386 tee sys_tee -316 i386 vmsplice sys_vmsplice compat_sys_vmsplice +316 i386 vmsplice sys_vmsplice 317 i386 move_pages sys_move_pages compat_sys_move_pages 318 i386 getcpu sys_getcpu 319 i386 epoll_pwait sys_epoll_pwait @@ -358,8 +358,8 @@ 344 i386 syncfs sys_syncfs 345 i386 sendmmsg sys_sendmmsg compat_sys_sendmmsg 346 i386 setns sys_setns -347 i386 process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv -348 i386 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev +347 i386 process_vm_readv sys_process_vm_readv +348 i386 process_vm_writev sys_process_vm_writev 349 i386 kcmp sys_kcmp 350 i386 finit_module sys_finit_module 351 i386 sched_setattr sys_sched_setattr @@ -444,3 +444,4 @@ 437 i386 openat2 sys_openat2 438 i386 pidfd_getfd sys_pidfd_getfd 439 i386 faccessat2 sys_faccessat2 +440 i386 process_madvise sys_process_madvise diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl index f30d6ae9a688..1f47e24fb65c 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl @@ -361,6 +361,7 @@ 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 +440 common process_madvise sys_process_madvise # # x32-specific system call numbers start at 512 to avoid cache impact @@ -371,8 +372,8 @@ 512 x32 rt_sigaction compat_sys_rt_sigaction 513 x32 rt_sigreturn compat_sys_x32_rt_sigreturn 514 x32 ioctl compat_sys_ioctl -515 x32 readv compat_sys_readv -516 x32 writev compat_sys_writev +515 x32 readv sys_readv +516 x32 writev sys_writev 517 x32 recvfrom compat_sys_recvfrom 518 x32 sendmsg compat_sys_sendmsg 519 x32 recvmsg compat_sys_recvmsg @@ -388,15 +389,15 @@ 529 x32 waitid compat_sys_waitid 530 x32 set_robust_list compat_sys_set_robust_list 531 x32 get_robust_list compat_sys_get_robust_list -532 x32 vmsplice compat_sys_vmsplice +532 x32 vmsplice sys_vmsplice 533 x32 move_pages compat_sys_move_pages 534 x32 preadv compat_sys_preadv64 535 x32 pwritev compat_sys_pwritev64 536 x32 rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo 537 x32 recvmmsg compat_sys_recvmmsg_time64 538 x32 sendmmsg compat_sys_sendmmsg -539 x32 process_vm_readv compat_sys_process_vm_readv -540 x32 process_vm_writev compat_sys_process_vm_writev +539 x32 process_vm_readv sys_process_vm_readv +540 x32 process_vm_writev sys_process_vm_writev 541 x32 setsockopt sys_setsockopt 542 x32 getsockopt sys_getsockopt 543 x32 io_setup compat_sys_io_setup diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index 215376d975a2..21243747965d 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -9,8 +9,6 @@ ARCH_REL_TYPE_ABS := R_X86_64_JUMP_SLOT|R_X86_64_GLOB_DAT|R_X86_64_RELATIVE| ARCH_REL_TYPE_ABS += R_386_GLOB_DAT|R_386_JMP_SLOT|R_386_RELATIVE include $(srctree)/lib/vdso/Makefile -KBUILD_CFLAGS += $(DISABLE_LTO) - # Sanitizer runtimes are unavailable and cannot be linked here. KASAN_SANITIZE := n UBSAN_SANITIZE := n @@ -176,7 +174,7 @@ quiet_cmd_vdso = VDSO $@ -T $(filter %.lds,$^) $(filter %.o,$^) && \ sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' -VDSO_LDFLAGS = -shared --hash-style=both --build-id \ +VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 \ $(call ld-option, --eh-frame-hdr) -Bsymbolic GCOV_PROFILE := n diff --git a/arch/x86/entry/vdso/vdso32/vclock_gettime.c b/arch/x86/entry/vdso/vdso32/vclock_gettime.c index 84a4a73f77f7..283ed9d00426 100644 --- a/arch/x86/entry/vdso/vdso32/vclock_gettime.c +++ b/arch/x86/entry/vdso/vdso32/vclock_gettime.c @@ -14,6 +14,7 @@ #undef CONFIG_ILLEGAL_POINTER_VALUE #undef CONFIG_SPARSEMEM_VMEMMAP #undef CONFIG_NR_CPUS +#undef CONFIG_PARAVIRT_XXL #define CONFIG_X86_32 1 #define CONFIG_PGTABLE_LEVELS 2 diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c index 26c36357c4c9..40669eac9d6d 100644 --- a/arch/x86/events/amd/ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -89,6 +89,7 @@ struct perf_ibs { u64 max_period; unsigned long offset_mask[1]; int offset_max; + unsigned int fetch_count_reset_broken : 1; struct cpu_perf_ibs __percpu *pcpu; struct attribute **format_attrs; @@ -334,11 +335,18 @@ static u64 get_ibs_op_count(u64 config) { u64 count = 0; - if (config & IBS_OP_VAL) - count += (config & IBS_OP_MAX_CNT) << 4; /* cnt rolled over */ - - if (ibs_caps & IBS_CAPS_RDWROPCNT) - count += (config & IBS_OP_CUR_CNT) >> 32; + /* + * If the internal 27-bit counter rolled over, the count is MaxCnt + * and the lower 7 bits of CurCnt are randomized. + * Otherwise CurCnt has the full 27-bit current counter value. + */ + if (config & IBS_OP_VAL) { + count = (config & IBS_OP_MAX_CNT) << 4; + if (ibs_caps & IBS_CAPS_OPCNTEXT) + count += config & IBS_OP_MAX_CNT_EXT_MASK; + } else if (ibs_caps & IBS_CAPS_RDWROPCNT) { + count = (config & IBS_OP_CUR_CNT) >> 32; + } return count; } @@ -363,7 +371,12 @@ perf_ibs_event_update(struct perf_ibs *perf_ibs, struct perf_event *event, static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs, struct hw_perf_event *hwc, u64 config) { - wrmsrl(hwc->config_base, hwc->config | config | perf_ibs->enable_mask); + u64 tmp = hwc->config | config; + + if (perf_ibs->fetch_count_reset_broken) + wrmsrl(hwc->config_base, tmp & ~perf_ibs->enable_mask); + + wrmsrl(hwc->config_base, tmp | perf_ibs->enable_mask); } /* @@ -394,7 +407,7 @@ static void perf_ibs_start(struct perf_event *event, int flags) struct hw_perf_event *hwc = &event->hw; struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu); struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu); - u64 period; + u64 period, config = 0; if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED))) return; @@ -403,13 +416,19 @@ static void perf_ibs_start(struct perf_event *event, int flags) hwc->state = 0; perf_ibs_set_period(perf_ibs, hwc, &period); + if (perf_ibs == &perf_ibs_op && (ibs_caps & IBS_CAPS_OPCNTEXT)) { + config |= period & IBS_OP_MAX_CNT_EXT_MASK; + period &= ~IBS_OP_MAX_CNT_EXT_MASK; + } + config |= period >> 4; + /* * Set STARTED before enabling the hardware, such that a subsequent NMI * must observe it. */ set_bit(IBS_STARTED, pcpu->state); clear_bit(IBS_STOPPING, pcpu->state); - perf_ibs_enable_event(perf_ibs, hwc, period >> 4); + perf_ibs_enable_event(perf_ibs, hwc, config); perf_event_update_userpage(event); } @@ -577,7 +596,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) struct perf_ibs_data ibs_data; int offset, size, check_rip, offset_max, throttle = 0; unsigned int msr; - u64 *buf, *config, period; + u64 *buf, *config, period, new_config = 0; if (!test_bit(IBS_STARTED, pcpu->state)) { fail: @@ -626,18 +645,24 @@ fail: perf_ibs->offset_max, offset + 1); } while (offset < offset_max); + /* + * Read IbsBrTarget, IbsOpData4, and IbsExtdCtl separately + * depending on their availability. + * Can't add to offset_max as they are staggered + */ if (event->attr.sample_type & PERF_SAMPLE_RAW) { - /* - * Read IbsBrTarget and IbsOpData4 separately - * depending on their availability. - * Can't add to offset_max as they are staggered - */ - if (ibs_caps & IBS_CAPS_BRNTRGT) { - rdmsrl(MSR_AMD64_IBSBRTARGET, *buf++); - size++; + if (perf_ibs == &perf_ibs_op) { + if (ibs_caps & IBS_CAPS_BRNTRGT) { + rdmsrl(MSR_AMD64_IBSBRTARGET, *buf++); + size++; + } + if (ibs_caps & IBS_CAPS_OPDATA4) { + rdmsrl(MSR_AMD64_IBSOPDATA4, *buf++); + size++; + } } - if (ibs_caps & IBS_CAPS_OPDATA4) { - rdmsrl(MSR_AMD64_IBSOPDATA4, *buf++); + if (perf_ibs == &perf_ibs_fetch && (ibs_caps & IBS_CAPS_FETCHCTLEXTD)) { + rdmsrl(MSR_AMD64_ICIBSEXTDCTL, *buf++); size++; } } @@ -666,13 +691,17 @@ out: if (throttle) { perf_ibs_stop(event, 0); } else { - period >>= 4; - - if ((ibs_caps & IBS_CAPS_RDWROPCNT) && - (*config & IBS_OP_CNT_CTL)) - period |= *config & IBS_OP_CUR_CNT_RAND; + if (perf_ibs == &perf_ibs_op) { + if (ibs_caps & IBS_CAPS_OPCNTEXT) { + new_config = period & IBS_OP_MAX_CNT_EXT_MASK; + period &= ~IBS_OP_MAX_CNT_EXT_MASK; + } + if ((ibs_caps & IBS_CAPS_RDWROPCNT) && (*config & IBS_OP_CNT_CTL)) + new_config |= *config & IBS_OP_CUR_CNT_RAND; + } + new_config |= period >> 4; - perf_ibs_enable_event(perf_ibs, hwc, period); + perf_ibs_enable_event(perf_ibs, hwc, new_config); } perf_event_update_userpage(event); @@ -733,12 +762,26 @@ static __init void perf_event_ibs_init(void) { struct attribute **attr = ibs_op_format_attrs; + /* + * Some chips fail to reset the fetch count when it is written; instead + * they need a 0-1 transition of IbsFetchEn. + */ + if (boot_cpu_data.x86 >= 0x16 && boot_cpu_data.x86 <= 0x18) + perf_ibs_fetch.fetch_count_reset_broken = 1; + perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch"); if (ibs_caps & IBS_CAPS_OPCNT) { perf_ibs_op.config_mask |= IBS_OP_CNT_CTL; *attr++ = &format_attr_cnt_ctl.attr; } + + if (ibs_caps & IBS_CAPS_OPCNTEXT) { + perf_ibs_op.max_period |= IBS_OP_MAX_CNT_EXT_MASK; + perf_ibs_op.config_mask |= IBS_OP_MAX_CNT_EXT_MASK; + perf_ibs_op.cnt_mask |= IBS_OP_MAX_CNT_EXT_MASK; + } + perf_ibs_pmu_init(&perf_ibs_op, "ibs_op"); register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs"); diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c index fb616203ce42..be50ef8572cc 100644 --- a/arch/x86/events/amd/iommu.c +++ b/arch/x86/events/amd/iommu.c @@ -379,7 +379,7 @@ static __init int _init_events_attrs(void) while (amd_iommu_v2_event_descs[i].attr.attr.name) i++; - attrs = kcalloc(i + 1, sizeof(struct attribute **), GFP_KERNEL); + attrs = kcalloc(i + 1, sizeof(*attrs), GFP_KERNEL); if (!attrs) return -ENOMEM; diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c index 76400c052b0e..7f014d450bc2 100644 --- a/arch/x86/events/amd/uncore.c +++ b/arch/x86/events/amd/uncore.c @@ -181,28 +181,28 @@ static void amd_uncore_del(struct perf_event *event, int flags) } /* - * Convert logical CPU number to L3 PMC Config ThreadMask format + * Return a full thread and slice mask unless user + * has provided them */ -static u64 l3_thread_slice_mask(int cpu) +static u64 l3_thread_slice_mask(u64 config) { - u64 thread_mask, core = topology_core_id(cpu); - unsigned int shift, thread = 0; + if (boot_cpu_data.x86 <= 0x18) + return ((config & AMD64_L3_SLICE_MASK) ? : AMD64_L3_SLICE_MASK) | + ((config & AMD64_L3_THREAD_MASK) ? : AMD64_L3_THREAD_MASK); - if (topology_smt_supported() && !topology_is_primary_thread(cpu)) - thread = 1; - - if (boot_cpu_data.x86 <= 0x18) { - shift = AMD64_L3_THREAD_SHIFT + 2 * (core % 4) + thread; - thread_mask = BIT_ULL(shift); - - return AMD64_L3_SLICE_MASK | thread_mask; - } - - core = (core << AMD64_L3_COREID_SHIFT) & AMD64_L3_COREID_MASK; - shift = AMD64_L3_THREAD_SHIFT + thread; - thread_mask = BIT_ULL(shift); + /* + * If the user doesn't specify a threadmask, they're not trying to + * count core 0, so we enable all cores & threads. + * We'll also assume that they want to count slice 0 if they specify + * a threadmask and leave sliceid and enallslices unpopulated. + */ + if (!(config & AMD64_L3_F19H_THREAD_MASK)) + return AMD64_L3_F19H_THREAD_MASK | AMD64_L3_EN_ALL_SLICES | + AMD64_L3_EN_ALL_CORES; - return AMD64_L3_EN_ALL_SLICES | core | thread_mask; + return config & (AMD64_L3_F19H_THREAD_MASK | AMD64_L3_SLICEID_MASK | + AMD64_L3_EN_ALL_CORES | AMD64_L3_EN_ALL_SLICES | + AMD64_L3_COREID_MASK); } static int amd_uncore_event_init(struct perf_event *event) @@ -232,7 +232,7 @@ static int amd_uncore_event_init(struct perf_event *event) * For other events, the two fields do not affect the count. */ if (l3_mask && is_llc_event(event)) - hwc->config |= l3_thread_slice_mask(event->cpu); + hwc->config |= l3_thread_slice_mask(event->attr.config); uncore = event_to_amd_uncore(event); if (!uncore) @@ -274,47 +274,72 @@ static struct attribute_group amd_uncore_attr_group = { .attrs = amd_uncore_attrs, }; -/* - * Similar to PMU_FORMAT_ATTR but allowing for format_attr to be assigned based - * on family - */ -#define AMD_FORMAT_ATTR(_dev, _name, _format) \ -static ssize_t \ -_dev##_show##_name(struct device *dev, \ - struct device_attribute *attr, \ - char *page) \ -{ \ - BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ - return sprintf(page, _format "\n"); \ -} \ -static struct device_attribute format_attr_##_dev##_name = __ATTR_RO(_dev); - -/* Used for each uncore counter type */ -#define AMD_ATTRIBUTE(_name) \ -static struct attribute *amd_uncore_format_attr_##_name[] = { \ - &format_attr_event_##_name.attr, \ - &format_attr_umask.attr, \ - NULL, \ -}; \ -static struct attribute_group amd_uncore_format_group_##_name = { \ - .name = "format", \ - .attrs = amd_uncore_format_attr_##_name, \ -}; \ -static const struct attribute_group *amd_uncore_attr_groups_##_name[] = { \ - &amd_uncore_attr_group, \ - &amd_uncore_format_group_##_name, \ - NULL, \ +#define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \ +static ssize_t __uncore_##_var##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, \ + char *page) \ +{ \ + BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ + return sprintf(page, _format "\n"); \ +} \ +static struct kobj_attribute format_attr_##_var = \ + __ATTR(_name, 0444, __uncore_##_var##_show, NULL) + +DEFINE_UNCORE_FORMAT_ATTR(event12, event, "config:0-7,32-35"); +DEFINE_UNCORE_FORMAT_ATTR(event14, event, "config:0-7,32-35,59-60"); /* F17h+ DF */ +DEFINE_UNCORE_FORMAT_ATTR(event8, event, "config:0-7"); /* F17h+ L3 */ +DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); +DEFINE_UNCORE_FORMAT_ATTR(coreid, coreid, "config:42-44"); /* F19h L3 */ +DEFINE_UNCORE_FORMAT_ATTR(slicemask, slicemask, "config:48-51"); /* F17h L3 */ +DEFINE_UNCORE_FORMAT_ATTR(threadmask8, threadmask, "config:56-63"); /* F17h L3 */ +DEFINE_UNCORE_FORMAT_ATTR(threadmask2, threadmask, "config:56-57"); /* F19h L3 */ +DEFINE_UNCORE_FORMAT_ATTR(enallslices, enallslices, "config:46"); /* F19h L3 */ +DEFINE_UNCORE_FORMAT_ATTR(enallcores, enallcores, "config:47"); /* F19h L3 */ +DEFINE_UNCORE_FORMAT_ATTR(sliceid, sliceid, "config:48-50"); /* F19h L3 */ + +static struct attribute *amd_uncore_df_format_attr[] = { + &format_attr_event12.attr, /* event14 if F17h+ */ + &format_attr_umask.attr, + NULL, +}; + +static struct attribute *amd_uncore_l3_format_attr[] = { + &format_attr_event12.attr, /* event8 if F17h+ */ + &format_attr_umask.attr, + NULL, /* slicemask if F17h, coreid if F19h */ + NULL, /* threadmask8 if F17h, enallslices if F19h */ + NULL, /* enallcores if F19h */ + NULL, /* sliceid if F19h */ + NULL, /* threadmask2 if F19h */ + NULL, +}; + +static struct attribute_group amd_uncore_df_format_group = { + .name = "format", + .attrs = amd_uncore_df_format_attr, }; -AMD_FORMAT_ATTR(event, , "config:0-7,32-35"); -AMD_FORMAT_ATTR(umask, , "config:8-15"); -AMD_FORMAT_ATTR(event, _df, "config:0-7,32-35,59-60"); -AMD_FORMAT_ATTR(event, _l3, "config:0-7"); -AMD_ATTRIBUTE(df); -AMD_ATTRIBUTE(l3); +static struct attribute_group amd_uncore_l3_format_group = { + .name = "format", + .attrs = amd_uncore_l3_format_attr, +}; + +static const struct attribute_group *amd_uncore_df_attr_groups[] = { + &amd_uncore_attr_group, + &amd_uncore_df_format_group, + NULL, +}; + +static const struct attribute_group *amd_uncore_l3_attr_groups[] = { + &amd_uncore_attr_group, + &amd_uncore_l3_format_group, + NULL, +}; static struct pmu amd_nb_pmu = { .task_ctx_nr = perf_invalid_context, + .attr_groups = amd_uncore_df_attr_groups, + .name = "amd_nb", .event_init = amd_uncore_event_init, .add = amd_uncore_add, .del = amd_uncore_del, @@ -326,6 +351,8 @@ static struct pmu amd_nb_pmu = { static struct pmu amd_llc_pmu = { .task_ctx_nr = perf_invalid_context, + .attr_groups = amd_uncore_l3_attr_groups, + .name = "amd_l2", .event_init = amd_uncore_event_init, .add = amd_uncore_add, .del = amd_uncore_del, @@ -529,6 +556,8 @@ static int amd_uncore_cpu_dead(unsigned int cpu) static int __init amd_uncore_init(void) { + struct attribute **df_attr = amd_uncore_df_format_attr; + struct attribute **l3_attr = amd_uncore_l3_format_attr; int ret = -ENODEV; if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD && @@ -538,6 +567,8 @@ static int __init amd_uncore_init(void) if (!boot_cpu_has(X86_FEATURE_TOPOEXT)) return -ENODEV; + num_counters_nb = NUM_COUNTERS_NB; + num_counters_llc = NUM_COUNTERS_L2; if (boot_cpu_data.x86 >= 0x17) { /* * For F17h and above, the Northbridge counters are @@ -545,27 +576,16 @@ static int __init amd_uncore_init(void) * counters are supported too. The PMUs are exported * based on family as either L2 or L3 and NB or DF. */ - num_counters_nb = NUM_COUNTERS_NB; num_counters_llc = NUM_COUNTERS_L3; amd_nb_pmu.name = "amd_df"; amd_llc_pmu.name = "amd_l3"; - format_attr_event_df.show = &event_show_df; - format_attr_event_l3.show = &event_show_l3; l3_mask = true; - } else { - num_counters_nb = NUM_COUNTERS_NB; - num_counters_llc = NUM_COUNTERS_L2; - amd_nb_pmu.name = "amd_nb"; - amd_llc_pmu.name = "amd_l2"; - format_attr_event_df = format_attr_event; - format_attr_event_l3 = format_attr_event; - l3_mask = false; } - amd_nb_pmu.attr_groups = amd_uncore_attr_groups_df; - amd_llc_pmu.attr_groups = amd_uncore_attr_groups_l3; - if (boot_cpu_has(X86_FEATURE_PERFCTR_NB)) { + if (boot_cpu_data.x86 >= 0x17) + *df_attr = &format_attr_event14.attr; + amd_uncore_nb = alloc_percpu(struct amd_uncore *); if (!amd_uncore_nb) { ret = -ENOMEM; @@ -575,13 +595,29 @@ static int __init amd_uncore_init(void) if (ret) goto fail_nb; - pr_info("%s NB counters detected\n", - boot_cpu_data.x86_vendor == X86_VENDOR_HYGON ? - "HYGON" : "AMD"); + pr_info("%d %s %s counters detected\n", num_counters_nb, + boot_cpu_data.x86_vendor == X86_VENDOR_HYGON ? "HYGON" : "", + amd_nb_pmu.name); + ret = 0; } if (boot_cpu_has(X86_FEATURE_PERFCTR_LLC)) { + if (boot_cpu_data.x86 >= 0x19) { + *l3_attr++ = &format_attr_event8.attr; + *l3_attr++ = &format_attr_umask.attr; + *l3_attr++ = &format_attr_coreid.attr; + *l3_attr++ = &format_attr_enallslices.attr; + *l3_attr++ = &format_attr_enallcores.attr; + *l3_attr++ = &format_attr_sliceid.attr; + *l3_attr++ = &format_attr_threadmask2.attr; + } else if (boot_cpu_data.x86 >= 0x17) { + *l3_attr++ = &format_attr_event8.attr; + *l3_attr++ = &format_attr_umask.attr; + *l3_attr++ = &format_attr_slicemask.attr; + *l3_attr++ = &format_attr_threadmask8.attr; + } + amd_uncore_llc = alloc_percpu(struct amd_uncore *); if (!amd_uncore_llc) { ret = -ENOMEM; @@ -591,9 +627,9 @@ static int __init amd_uncore_init(void) if (ret) goto fail_llc; - pr_info("%s LLC counters detected\n", - boot_cpu_data.x86_vendor == X86_VENDOR_HYGON ? - "HYGON" : "AMD"); + pr_info("%d %s %s counters detected\n", num_counters_llc, + boot_cpu_data.x86_vendor == X86_VENDOR_HYGON ? "HYGON" : "", + amd_llc_pmu.name); ret = 0; } diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 1cbf57dc2ac8..a88c94d65693 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -28,6 +28,7 @@ #include <linux/bitops.h> #include <linux/device.h> #include <linux/nospec.h> +#include <linux/static_call.h> #include <asm/apic.h> #include <asm/stacktrace.h> @@ -52,6 +53,34 @@ DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { DEFINE_STATIC_KEY_FALSE(rdpmc_never_available_key); DEFINE_STATIC_KEY_FALSE(rdpmc_always_available_key); +/* + * This here uses DEFINE_STATIC_CALL_NULL() to get a static_call defined + * from just a typename, as opposed to an actual function. + */ +DEFINE_STATIC_CALL_NULL(x86_pmu_handle_irq, *x86_pmu.handle_irq); +DEFINE_STATIC_CALL_NULL(x86_pmu_disable_all, *x86_pmu.disable_all); +DEFINE_STATIC_CALL_NULL(x86_pmu_enable_all, *x86_pmu.enable_all); +DEFINE_STATIC_CALL_NULL(x86_pmu_enable, *x86_pmu.enable); +DEFINE_STATIC_CALL_NULL(x86_pmu_disable, *x86_pmu.disable); + +DEFINE_STATIC_CALL_NULL(x86_pmu_add, *x86_pmu.add); +DEFINE_STATIC_CALL_NULL(x86_pmu_del, *x86_pmu.del); +DEFINE_STATIC_CALL_NULL(x86_pmu_read, *x86_pmu.read); + +DEFINE_STATIC_CALL_NULL(x86_pmu_schedule_events, *x86_pmu.schedule_events); +DEFINE_STATIC_CALL_NULL(x86_pmu_get_event_constraints, *x86_pmu.get_event_constraints); +DEFINE_STATIC_CALL_NULL(x86_pmu_put_event_constraints, *x86_pmu.put_event_constraints); + +DEFINE_STATIC_CALL_NULL(x86_pmu_start_scheduling, *x86_pmu.start_scheduling); +DEFINE_STATIC_CALL_NULL(x86_pmu_commit_scheduling, *x86_pmu.commit_scheduling); +DEFINE_STATIC_CALL_NULL(x86_pmu_stop_scheduling, *x86_pmu.stop_scheduling); + +DEFINE_STATIC_CALL_NULL(x86_pmu_sched_task, *x86_pmu.sched_task); +DEFINE_STATIC_CALL_NULL(x86_pmu_swap_task_ctx, *x86_pmu.swap_task_ctx); + +DEFINE_STATIC_CALL_NULL(x86_pmu_drain_pebs, *x86_pmu.drain_pebs); +DEFINE_STATIC_CALL_NULL(x86_pmu_pebs_aliases, *x86_pmu.pebs_aliases); + u64 __read_mostly hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] @@ -76,6 +105,9 @@ u64 x86_perf_event_update(struct perf_event *event) if (unlikely(!hwc->event_base)) return 0; + if (unlikely(is_topdown_count(event)) && x86_pmu.update_topdown_event) + return x86_pmu.update_topdown_event(event); + /* * Careful: an NMI might modify the previous event value. * @@ -660,7 +692,7 @@ static void x86_pmu_disable(struct pmu *pmu) cpuc->enabled = 0; barrier(); - x86_pmu.disable_all(); + static_call(x86_pmu_disable_all)(); } void x86_pmu_enable_all(int added) @@ -907,8 +939,7 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) if (cpuc->txn_flags & PERF_PMU_TXN_ADD) n0 -= cpuc->n_txn; - if (x86_pmu.start_scheduling) - x86_pmu.start_scheduling(cpuc); + static_call_cond(x86_pmu_start_scheduling)(cpuc); for (i = 0, wmin = X86_PMC_IDX_MAX, wmax = 0; i < n; i++) { c = cpuc->event_constraint[i]; @@ -925,7 +956,7 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) * change due to external factors (sibling state, allow_tfa). */ if (!c || (c->flags & PERF_X86_EVENT_DYNAMIC)) { - c = x86_pmu.get_event_constraints(cpuc, i, cpuc->event_list[i]); + c = static_call(x86_pmu_get_event_constraints)(cpuc, i, cpuc->event_list[i]); cpuc->event_constraint[i] = c; } @@ -1008,8 +1039,7 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) if (!unsched && assign) { for (i = 0; i < n; i++) { e = cpuc->event_list[i]; - if (x86_pmu.commit_scheduling) - x86_pmu.commit_scheduling(cpuc, i, assign[i]); + static_call_cond(x86_pmu_commit_scheduling)(cpuc, i, assign[i]); } } else { for (i = n0; i < n; i++) { @@ -1018,19 +1048,56 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) /* * release events that failed scheduling */ - if (x86_pmu.put_event_constraints) - x86_pmu.put_event_constraints(cpuc, e); + static_call_cond(x86_pmu_put_event_constraints)(cpuc, e); cpuc->event_constraint[i] = NULL; } } - if (x86_pmu.stop_scheduling) - x86_pmu.stop_scheduling(cpuc); + static_call_cond(x86_pmu_stop_scheduling)(cpuc); return unsched ? -EINVAL : 0; } +static int add_nr_metric_event(struct cpu_hw_events *cpuc, + struct perf_event *event) +{ + if (is_metric_event(event)) { + if (cpuc->n_metric == INTEL_TD_METRIC_NUM) + return -EINVAL; + cpuc->n_metric++; + cpuc->n_txn_metric++; + } + + return 0; +} + +static void del_nr_metric_event(struct cpu_hw_events *cpuc, + struct perf_event *event) +{ + if (is_metric_event(event)) + cpuc->n_metric--; +} + +static int collect_event(struct cpu_hw_events *cpuc, struct perf_event *event, + int max_count, int n) +{ + + if (x86_pmu.intel_cap.perf_metrics && add_nr_metric_event(cpuc, event)) + return -EINVAL; + + if (n >= max_count + cpuc->n_metric) + return -EINVAL; + + cpuc->event_list[n] = event; + if (is_counter_pair(&event->hw)) { + cpuc->n_pair++; + cpuc->n_txn_pair++; + } + + return 0; +} + /* * dogrp: true if must collect siblings events (group) * returns total number of events and error code @@ -1067,28 +1134,22 @@ static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, } if (is_x86_event(leader)) { - if (n >= max_count) + if (collect_event(cpuc, leader, max_count, n)) return -EINVAL; - cpuc->event_list[n] = leader; n++; - if (is_counter_pair(&leader->hw)) - cpuc->n_pair++; } + if (!dogrp) return n; for_each_sibling_event(event, leader) { - if (!is_x86_event(event) || - event->state <= PERF_EVENT_STATE_OFF) + if (!is_x86_event(event) || event->state <= PERF_EVENT_STATE_OFF) continue; - if (n >= max_count) + if (collect_event(cpuc, event, max_count, n)) return -EINVAL; - cpuc->event_list[n] = event; n++; - if (is_counter_pair(&event->hw)) - cpuc->n_pair++; } return n; } @@ -1110,11 +1171,16 @@ static inline void x86_assign_hw_event(struct perf_event *event, hwc->event_base = 0; break; + case INTEL_PMC_IDX_METRIC_BASE ... INTEL_PMC_IDX_METRIC_END: + /* All the metric events are mapped onto the fixed counter 3. */ + idx = INTEL_PMC_IDX_FIXED_SLOTS; + /* fall through */ case INTEL_PMC_IDX_FIXED ... INTEL_PMC_IDX_FIXED_BTS-1: hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (idx - INTEL_PMC_IDX_FIXED); - hwc->event_base_rdpmc = (idx - INTEL_PMC_IDX_FIXED) | 1<<30; + hwc->event_base_rdpmc = (idx - INTEL_PMC_IDX_FIXED) | + INTEL_PMC_FIXED_RDPMC_BASE; break; default: @@ -1226,7 +1292,7 @@ static void x86_pmu_enable(struct pmu *pmu) cpuc->enabled = 1; barrier(); - x86_pmu.enable_all(added); + static_call(x86_pmu_enable_all)(added); } static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left); @@ -1245,6 +1311,10 @@ int x86_perf_event_set_period(struct perf_event *event) if (unlikely(!hwc->event_base)) return 0; + if (unlikely(is_topdown_count(event)) && + x86_pmu.set_topdown_event_period) + return x86_pmu.set_topdown_event_period(event); + /* * If we are way outside a reasonable range then just skip forward: */ @@ -1284,11 +1354,11 @@ int x86_perf_event_set_period(struct perf_event *event) wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask); /* - * Clear the Merge event counter's upper 16 bits since + * Sign extend the Merge event counter's upper 16 bits since * we currently declare a 48-bit counter width */ if (is_counter_pair(hwc)) - wrmsrl(x86_pmu_event_addr(idx + 1), 0); + wrmsrl(x86_pmu_event_addr(idx + 1), 0xffff); /* * Due to erratum on certan cpu we need @@ -1347,7 +1417,7 @@ static int x86_pmu_add(struct perf_event *event, int flags) if (cpuc->txn_flags & PERF_PMU_TXN_ADD) goto done_collect; - ret = x86_pmu.schedule_events(cpuc, n, assign); + ret = static_call(x86_pmu_schedule_events)(cpuc, n, assign); if (ret) goto out; /* @@ -1365,13 +1435,11 @@ done_collect: cpuc->n_added += n - n0; cpuc->n_txn += n - n0; - if (x86_pmu.add) { - /* - * This is before x86_pmu_enable() will call x86_pmu_start(), - * so we enable LBRs before an event needs them etc.. - */ - x86_pmu.add(event); - } + /* + * This is before x86_pmu_enable() will call x86_pmu_start(), + * so we enable LBRs before an event needs them etc.. + */ + static_call_cond(x86_pmu_add)(event); ret = 0; out: @@ -1399,7 +1467,7 @@ static void x86_pmu_start(struct perf_event *event, int flags) cpuc->events[idx] = event; __set_bit(idx, cpuc->active_mask); __set_bit(idx, cpuc->running); - x86_pmu.enable(event); + static_call(x86_pmu_enable)(event); perf_event_update_userpage(event); } @@ -1469,7 +1537,7 @@ void x86_pmu_stop(struct perf_event *event, int flags) struct hw_perf_event *hwc = &event->hw; if (test_bit(hwc->idx, cpuc->active_mask)) { - x86_pmu.disable(event); + static_call(x86_pmu_disable)(event); __clear_bit(hwc->idx, cpuc->active_mask); cpuc->events[hwc->idx] = NULL; WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); @@ -1519,8 +1587,7 @@ static void x86_pmu_del(struct perf_event *event, int flags) if (i >= cpuc->n_events - cpuc->n_added) --cpuc->n_added; - if (x86_pmu.put_event_constraints) - x86_pmu.put_event_constraints(cpuc, event); + static_call_cond(x86_pmu_put_event_constraints)(cpuc, event); /* Delete the array entry. */ while (++i < cpuc->n_events) { @@ -1529,17 +1596,18 @@ static void x86_pmu_del(struct perf_event *event, int flags) } cpuc->event_constraint[i-1] = NULL; --cpuc->n_events; + if (x86_pmu.intel_cap.perf_metrics) + del_nr_metric_event(cpuc, event); perf_event_update_userpage(event); do_del: - if (x86_pmu.del) { - /* - * This is after x86_pmu_stop(); so we disable LBRs after any - * event can need them etc.. - */ - x86_pmu.del(event); - } + + /* + * This is after x86_pmu_stop(); so we disable LBRs after any + * event can need them etc.. + */ + static_call_cond(x86_pmu_del)(event); } int x86_pmu_handle_irq(struct pt_regs *regs) @@ -1617,7 +1685,7 @@ perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs) return NMI_DONE; start_clock = sched_clock(); - ret = x86_pmu.handle_irq(regs); + ret = static_call(x86_pmu_handle_irq)(regs); finish_clock = sched_clock(); perf_sample_event_took(finish_clock - start_clock); @@ -1830,6 +1898,38 @@ ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event) static struct attribute_group x86_pmu_attr_group; static struct attribute_group x86_pmu_caps_group; +static void x86_pmu_static_call_update(void) +{ + static_call_update(x86_pmu_handle_irq, x86_pmu.handle_irq); + static_call_update(x86_pmu_disable_all, x86_pmu.disable_all); + static_call_update(x86_pmu_enable_all, x86_pmu.enable_all); + static_call_update(x86_pmu_enable, x86_pmu.enable); + static_call_update(x86_pmu_disable, x86_pmu.disable); + + static_call_update(x86_pmu_add, x86_pmu.add); + static_call_update(x86_pmu_del, x86_pmu.del); + static_call_update(x86_pmu_read, x86_pmu.read); + + static_call_update(x86_pmu_schedule_events, x86_pmu.schedule_events); + static_call_update(x86_pmu_get_event_constraints, x86_pmu.get_event_constraints); + static_call_update(x86_pmu_put_event_constraints, x86_pmu.put_event_constraints); + + static_call_update(x86_pmu_start_scheduling, x86_pmu.start_scheduling); + static_call_update(x86_pmu_commit_scheduling, x86_pmu.commit_scheduling); + static_call_update(x86_pmu_stop_scheduling, x86_pmu.stop_scheduling); + + static_call_update(x86_pmu_sched_task, x86_pmu.sched_task); + static_call_update(x86_pmu_swap_task_ctx, x86_pmu.swap_task_ctx); + + static_call_update(x86_pmu_drain_pebs, x86_pmu.drain_pebs); + static_call_update(x86_pmu_pebs_aliases, x86_pmu.pebs_aliases); +} + +static void _x86_pmu_read(struct perf_event *event) +{ + x86_perf_event_update(event); +} + static int __init init_hw_perf_events(void) { struct x86_pmu_quirk *quirk; @@ -1898,6 +1998,11 @@ static int __init init_hw_perf_events(void) pr_info("... fixed-purpose events: %d\n", x86_pmu.num_counters_fixed); pr_info("... event mask: %016Lx\n", x86_pmu.intel_ctrl); + if (!x86_pmu.read) + x86_pmu.read = _x86_pmu_read; + + x86_pmu_static_call_update(); + /* * Install callbacks. Core will call them for each online * cpu. @@ -1934,11 +2039,9 @@ out: } early_initcall(init_hw_perf_events); -static inline void x86_pmu_read(struct perf_event *event) +static void x86_pmu_read(struct perf_event *event) { - if (x86_pmu.read) - return x86_pmu.read(event); - x86_perf_event_update(event); + static_call(x86_pmu_read)(event); } /* @@ -1962,6 +2065,8 @@ static void x86_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags) perf_pmu_disable(pmu); __this_cpu_write(cpu_hw_events.n_txn, 0); + __this_cpu_write(cpu_hw_events.n_txn_pair, 0); + __this_cpu_write(cpu_hw_events.n_txn_metric, 0); } /* @@ -1987,6 +2092,8 @@ static void x86_pmu_cancel_txn(struct pmu *pmu) */ __this_cpu_sub(cpu_hw_events.n_added, __this_cpu_read(cpu_hw_events.n_txn)); __this_cpu_sub(cpu_hw_events.n_events, __this_cpu_read(cpu_hw_events.n_txn)); + __this_cpu_sub(cpu_hw_events.n_pair, __this_cpu_read(cpu_hw_events.n_txn_pair)); + __this_cpu_sub(cpu_hw_events.n_metric, __this_cpu_read(cpu_hw_events.n_txn_metric)); perf_pmu_enable(pmu); } @@ -2015,7 +2122,7 @@ static int x86_pmu_commit_txn(struct pmu *pmu) if (!x86_pmu_initialized()) return -EAGAIN; - ret = x86_pmu.schedule_events(cpuc, n, assign); + ret = static_call(x86_pmu_schedule_events)(cpuc, n, assign); if (ret) return ret; @@ -2208,17 +2315,15 @@ static void x86_pmu_event_unmapped(struct perf_event *event, struct mm_struct *m static int x86_pmu_event_idx(struct perf_event *event) { - int idx = event->hw.idx; + struct hw_perf_event *hwc = &event->hw; - if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED)) + if (!(hwc->flags & PERF_X86_EVENT_RDPMC_ALLOWED)) return 0; - if (x86_pmu.num_counters_fixed && idx >= INTEL_PMC_IDX_FIXED) { - idx -= INTEL_PMC_IDX_FIXED; - idx |= 1 << 30; - } - - return idx + 1; + if (is_metric_idx(hwc->idx)) + return INTEL_PMC_FIXED_RDPMC_METRICS + 1; + else + return hwc->event_base_rdpmc + 1; } static ssize_t get_attr_rdpmc(struct device *cdev, @@ -2308,15 +2413,13 @@ static const struct attribute_group *x86_pmu_attr_groups[] = { static void x86_pmu_sched_task(struct perf_event_context *ctx, bool sched_in) { - if (x86_pmu.sched_task) - x86_pmu.sched_task(ctx, sched_in); + static_call_cond(x86_pmu_sched_task)(ctx, sched_in); } static void x86_pmu_swap_task_ctx(struct perf_event_context *prev, struct perf_event_context *next) { - if (x86_pmu.swap_task_ctx) - x86_pmu.swap_task_ctx(prev, next); + static_call_cond(x86_pmu_swap_task_ctx)(prev, next); } void perf_check_microcode(void) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 31e6887d24f1..f1926e9f2143 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -243,10 +243,14 @@ static struct extra_reg intel_skl_extra_regs[] __read_mostly = { static struct event_constraint intel_icl_event_constraints[] = { FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ - INTEL_UEVENT_CONSTRAINT(0x1c0, 0), /* INST_RETIRED.PREC_DIST */ + FIXED_EVENT_CONSTRAINT(0x01c0, 0), /* INST_RETIRED.PREC_DIST */ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */ FIXED_EVENT_CONSTRAINT(0x0400, 3), /* SLOTS */ + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_RETIRING, 0), + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_BAD_SPEC, 1), + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_FE_BOUND, 2), + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_BE_BOUND, 3), INTEL_EVENT_CONSTRAINT_RANGE(0x03, 0x0a, 0xf), INTEL_EVENT_CONSTRAINT_RANGE(0x1f, 0x28, 0xf), INTEL_EVENT_CONSTRAINT(0x32, 0xf), /* SW_PREFETCH_ACCESS.* */ @@ -309,6 +313,12 @@ EVENT_ATTR_STR_HT(topdown-recovery-bubbles, td_recovery_bubbles, EVENT_ATTR_STR_HT(topdown-recovery-bubbles.scale, td_recovery_bubbles_scale, "4", "2"); +EVENT_ATTR_STR(slots, slots, "event=0x00,umask=0x4"); +EVENT_ATTR_STR(topdown-retiring, td_retiring, "event=0x00,umask=0x80"); +EVENT_ATTR_STR(topdown-bad-spec, td_bad_spec, "event=0x00,umask=0x81"); +EVENT_ATTR_STR(topdown-fe-bound, td_fe_bound, "event=0x00,umask=0x82"); +EVENT_ATTR_STR(topdown-be-bound, td_be_bound, "event=0x00,umask=0x83"); + static struct attribute *snb_events_attrs[] = { EVENT_PTR(td_slots_issued), EVENT_PTR(td_slots_retired), @@ -2165,11 +2175,24 @@ static inline void intel_clear_masks(struct perf_event *event, int idx) static void intel_pmu_disable_fixed(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; - int idx = hwc->idx - INTEL_PMC_IDX_FIXED; u64 ctrl_val, mask; + int idx = hwc->idx; - mask = 0xfULL << (idx * 4); + if (is_topdown_idx(idx)) { + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); + + /* + * When there are other active TopDown events, + * don't disable the fixed counter 3. + */ + if (*(u64 *)cpuc->active_mask & INTEL_PMC_OTHER_TOPDOWN_BITS(idx)) + return; + idx = INTEL_PMC_IDX_FIXED_SLOTS; + } + intel_clear_masks(event, idx); + + mask = 0xfULL << ((idx - INTEL_PMC_IDX_FIXED) * 4); rdmsrl(hwc->config_base, ctrl_val); ctrl_val &= ~mask; wrmsrl(hwc->config_base, ctrl_val); @@ -2180,17 +2203,28 @@ static void intel_pmu_disable_event(struct perf_event *event) struct hw_perf_event *hwc = &event->hw; int idx = hwc->idx; - if (idx < INTEL_PMC_IDX_FIXED) { + switch (idx) { + case 0 ... INTEL_PMC_IDX_FIXED - 1: intel_clear_masks(event, idx); x86_pmu_disable_event(event); - } else if (idx < INTEL_PMC_IDX_FIXED_BTS) { - intel_clear_masks(event, idx); + break; + case INTEL_PMC_IDX_FIXED ... INTEL_PMC_IDX_FIXED_BTS - 1: + case INTEL_PMC_IDX_METRIC_BASE ... INTEL_PMC_IDX_METRIC_END: intel_pmu_disable_fixed(event); - } else if (idx == INTEL_PMC_IDX_FIXED_BTS) { + break; + case INTEL_PMC_IDX_FIXED_BTS: intel_pmu_disable_bts(); intel_pmu_drain_bts_buffer(); - } else if (idx == INTEL_PMC_IDX_FIXED_VLBR) + return; + case INTEL_PMC_IDX_FIXED_VLBR: intel_clear_masks(event, idx); + break; + default: + intel_clear_masks(event, idx); + pr_warn("Failed to disable the event with invalid index %d\n", + idx); + return; + } /* * Needs to be called after x86_pmu_disable_event, @@ -2208,10 +2242,189 @@ static void intel_pmu_del_event(struct perf_event *event) intel_pmu_pebs_del(event); } +static int icl_set_topdown_event_period(struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + s64 left = local64_read(&hwc->period_left); + + /* + * The values in PERF_METRICS MSR are derived from fixed counter 3. + * Software should start both registers, PERF_METRICS and fixed + * counter 3, from zero. + * Clear PERF_METRICS and Fixed counter 3 in initialization. + * After that, both MSRs will be cleared for each read. + * Don't need to clear them again. + */ + if (left == x86_pmu.max_period) { + wrmsrl(MSR_CORE_PERF_FIXED_CTR3, 0); + wrmsrl(MSR_PERF_METRICS, 0); + hwc->saved_slots = 0; + hwc->saved_metric = 0; + } + + if ((hwc->saved_slots) && is_slots_event(event)) { + wrmsrl(MSR_CORE_PERF_FIXED_CTR3, hwc->saved_slots); + wrmsrl(MSR_PERF_METRICS, hwc->saved_metric); + } + + perf_event_update_userpage(event); + + return 0; +} + +static inline u64 icl_get_metrics_event_value(u64 metric, u64 slots, int idx) +{ + u32 val; + + /* + * The metric is reported as an 8bit integer fraction + * suming up to 0xff. + * slots-in-metric = (Metric / 0xff) * slots + */ + val = (metric >> ((idx - INTEL_PMC_IDX_METRIC_BASE) * 8)) & 0xff; + return mul_u64_u32_div(slots, val, 0xff); +} + +static u64 icl_get_topdown_value(struct perf_event *event, + u64 slots, u64 metrics) +{ + int idx = event->hw.idx; + u64 delta; + + if (is_metric_idx(idx)) + delta = icl_get_metrics_event_value(metrics, slots, idx); + else + delta = slots; + + return delta; +} + +static void __icl_update_topdown_event(struct perf_event *event, + u64 slots, u64 metrics, + u64 last_slots, u64 last_metrics) +{ + u64 delta, last = 0; + + delta = icl_get_topdown_value(event, slots, metrics); + if (last_slots) + last = icl_get_topdown_value(event, last_slots, last_metrics); + + /* + * The 8bit integer fraction of metric may be not accurate, + * especially when the changes is very small. + * For example, if only a few bad_spec happens, the fraction + * may be reduced from 1 to 0. If so, the bad_spec event value + * will be 0 which is definitely less than the last value. + * Avoid update event->count for this case. + */ + if (delta > last) { + delta -= last; + local64_add(delta, &event->count); + } +} + +static void update_saved_topdown_regs(struct perf_event *event, + u64 slots, u64 metrics) +{ + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); + struct perf_event *other; + int idx; + + event->hw.saved_slots = slots; + event->hw.saved_metric = metrics; + + for_each_set_bit(idx, cpuc->active_mask, INTEL_PMC_IDX_TD_BE_BOUND + 1) { + if (!is_topdown_idx(idx)) + continue; + other = cpuc->events[idx]; + other->hw.saved_slots = slots; + other->hw.saved_metric = metrics; + } +} + +/* + * Update all active Topdown events. + * + * The PERF_METRICS and Fixed counter 3 are read separately. The values may be + * modify by a NMI. PMU has to be disabled before calling this function. + */ +static u64 icl_update_topdown_event(struct perf_event *event) +{ + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); + struct perf_event *other; + u64 slots, metrics; + bool reset = true; + int idx; + + /* read Fixed counter 3 */ + rdpmcl((3 | INTEL_PMC_FIXED_RDPMC_BASE), slots); + if (!slots) + return 0; + + /* read PERF_METRICS */ + rdpmcl(INTEL_PMC_FIXED_RDPMC_METRICS, metrics); + + for_each_set_bit(idx, cpuc->active_mask, INTEL_PMC_IDX_TD_BE_BOUND + 1) { + if (!is_topdown_idx(idx)) + continue; + other = cpuc->events[idx]; + __icl_update_topdown_event(other, slots, metrics, + event ? event->hw.saved_slots : 0, + event ? event->hw.saved_metric : 0); + } + + /* + * Check and update this event, which may have been cleared + * in active_mask e.g. x86_pmu_stop() + */ + if (event && !test_bit(event->hw.idx, cpuc->active_mask)) { + __icl_update_topdown_event(event, slots, metrics, + event->hw.saved_slots, + event->hw.saved_metric); + + /* + * In x86_pmu_stop(), the event is cleared in active_mask first, + * then drain the delta, which indicates context switch for + * counting. + * Save metric and slots for context switch. + * Don't need to reset the PERF_METRICS and Fixed counter 3. + * Because the values will be restored in next schedule in. + */ + update_saved_topdown_regs(event, slots, metrics); + reset = false; + } + + if (reset) { + /* The fixed counter 3 has to be written before the PERF_METRICS. */ + wrmsrl(MSR_CORE_PERF_FIXED_CTR3, 0); + wrmsrl(MSR_PERF_METRICS, 0); + if (event) + update_saved_topdown_regs(event, 0, 0); + } + + return slots; +} + +static void intel_pmu_read_topdown_event(struct perf_event *event) +{ + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); + + /* Only need to call update_topdown_event() once for group read. */ + if ((cpuc->txn_flags & PERF_PMU_TXN_READ) && + !is_slots_event(event)) + return; + + perf_pmu_disable(event->pmu); + x86_pmu.update_topdown_event(event); + perf_pmu_enable(event->pmu); +} + static void intel_pmu_read_event(struct perf_event *event) { if (event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD) intel_pmu_auto_reload_read(event); + else if (is_topdown_count(event) && x86_pmu.update_topdown_event) + intel_pmu_read_topdown_event(event); else x86_perf_event_update(event); } @@ -2219,8 +2432,22 @@ static void intel_pmu_read_event(struct perf_event *event) static void intel_pmu_enable_fixed(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; - int idx = hwc->idx - INTEL_PMC_IDX_FIXED; u64 ctrl_val, mask, bits = 0; + int idx = hwc->idx; + + if (is_topdown_idx(idx)) { + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); + /* + * When there are other active TopDown events, + * don't enable the fixed counter 3 again. + */ + if (*(u64 *)cpuc->active_mask & INTEL_PMC_OTHER_TOPDOWN_BITS(idx)) + return; + + idx = INTEL_PMC_IDX_FIXED_SLOTS; + } + + intel_set_masks(event, idx); /* * Enable IRQ generation (0x8), if not PEBS, @@ -2240,6 +2467,7 @@ static void intel_pmu_enable_fixed(struct perf_event *event) if (x86_pmu.version > 2 && hwc->config & ARCH_PERFMON_EVENTSEL_ANY) bits |= 0x4; + idx -= INTEL_PMC_IDX_FIXED; bits <<= (idx * 4); mask = 0xfULL << (idx * 4); @@ -2262,18 +2490,27 @@ static void intel_pmu_enable_event(struct perf_event *event) if (unlikely(event->attr.precise_ip)) intel_pmu_pebs_enable(event); - if (idx < INTEL_PMC_IDX_FIXED) { + switch (idx) { + case 0 ... INTEL_PMC_IDX_FIXED - 1: intel_set_masks(event, idx); __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE); - } else if (idx < INTEL_PMC_IDX_FIXED_BTS) { - intel_set_masks(event, idx); + break; + case INTEL_PMC_IDX_FIXED ... INTEL_PMC_IDX_FIXED_BTS - 1: + case INTEL_PMC_IDX_METRIC_BASE ... INTEL_PMC_IDX_METRIC_END: intel_pmu_enable_fixed(event); - } else if (idx == INTEL_PMC_IDX_FIXED_BTS) { + break; + case INTEL_PMC_IDX_FIXED_BTS: if (!__this_cpu_read(cpu_hw_events.enabled)) return; intel_pmu_enable_bts(hwc->config); - } else if (idx == INTEL_PMC_IDX_FIXED_VLBR) + break; + case INTEL_PMC_IDX_FIXED_VLBR: intel_set_masks(event, idx); + break; + default: + pr_warn("Failed to enable the event with invalid index %d\n", + idx); + } } static void intel_pmu_add_event(struct perf_event *event) @@ -2389,7 +2626,7 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) /* * PEBS overflow sets bit 62 in the global status register */ - if (__test_and_clear_bit(62, (unsigned long *)&status)) { + if (__test_and_clear_bit(GLOBAL_STATUS_BUFFER_OVF_BIT, (unsigned long *)&status)) { u64 pebs_enabled = cpuc->pebs_enabled; handled++; @@ -2410,7 +2647,7 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) /* * Intel PT */ - if (__test_and_clear_bit(55, (unsigned long *)&status)) { + if (__test_and_clear_bit(GLOBAL_STATUS_TRACE_TOPAPMI_BIT, (unsigned long *)&status)) { handled++; if (unlikely(perf_guest_cbs && perf_guest_cbs->is_in_guest() && perf_guest_cbs->handle_intel_pt_intr)) @@ -2420,6 +2657,15 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) } /* + * Intel Perf mertrics + */ + if (__test_and_clear_bit(GLOBAL_STATUS_PERF_METRICS_OVF_BIT, (unsigned long *)&status)) { + handled++; + if (x86_pmu.update_topdown_event) + x86_pmu.update_topdown_event(NULL); + } + + /* * Checkpointed counters can lead to 'spurious' PMIs because the * rollback caused by the PMI will have cleared the overflow status * bit. Therefore always force probe these counters. @@ -3355,6 +3601,56 @@ static int intel_pmu_hw_config(struct perf_event *event) if (event->attr.type != PERF_TYPE_RAW) return 0; + /* + * Config Topdown slots and metric events + * + * The slots event on Fixed Counter 3 can support sampling, + * which will be handled normally in x86_perf_event_update(). + * + * Metric events don't support sampling and require being paired + * with a slots event as group leader. When the slots event + * is used in a metrics group, it too cannot support sampling. + */ + if (x86_pmu.intel_cap.perf_metrics && is_topdown_event(event)) { + if (event->attr.config1 || event->attr.config2) + return -EINVAL; + + /* + * The TopDown metrics events and slots event don't + * support any filters. + */ + if (event->attr.config & X86_ALL_EVENT_FLAGS) + return -EINVAL; + + if (is_metric_event(event)) { + struct perf_event *leader = event->group_leader; + + /* The metric events don't support sampling. */ + if (is_sampling_event(event)) + return -EINVAL; + + /* The metric events require a slots group leader. */ + if (!is_slots_event(leader)) + return -EINVAL; + + /* + * The leader/SLOTS must not be a sampling event for + * metric use; hardware requires it starts at 0 when used + * in conjunction with MSR_PERF_METRICS. + */ + if (is_sampling_event(leader)) + return -EINVAL; + + event->event_caps |= PERF_EV_CAP_SIBLING; + /* + * Only once we have a METRICs sibling do we + * need TopDown magic. + */ + leader->hw.flags |= PERF_X86_EVENT_TOPDOWN; + event->hw.flags |= PERF_X86_EVENT_TOPDOWN; + } + } + if (!(event->attr.config & ARCH_PERFMON_EVENTSEL_ANY)) return 0; @@ -3787,6 +4083,17 @@ static void intel_pmu_cpu_starting(int cpu) if (x86_pmu.counter_freezing) enable_counter_freeze(); + /* Disable perf metrics if any added CPU doesn't support it. */ + if (x86_pmu.intel_cap.perf_metrics) { + union perf_capabilities perf_cap; + + rdmsrl(MSR_IA32_PERF_CAPABILITIES, perf_cap.capabilities); + if (!perf_cap.perf_metrics) { + x86_pmu.intel_cap.perf_metrics = 0; + x86_pmu.intel_ctrl &= ~(1ULL << GLOBAL_CTRL_EN_PERF_METRICS); + } + } + if (!cpuc->shared_regs) return; @@ -4355,6 +4662,15 @@ static struct attribute *icl_events_attrs[] = { NULL, }; +static struct attribute *icl_td_events_attrs[] = { + EVENT_PTR(slots), + EVENT_PTR(td_retiring), + EVENT_PTR(td_bad_spec), + EVENT_PTR(td_fe_bound), + EVENT_PTR(td_be_bound), + NULL, +}; + static struct attribute *icl_tsx_events_attrs[] = { EVENT_PTR(tx_start), EVENT_PTR(tx_abort), @@ -4830,6 +5146,7 @@ __init int intel_pmu_init(void) case INTEL_FAM6_ATOM_TREMONT_D: case INTEL_FAM6_ATOM_TREMONT: + case INTEL_FAM6_ATOM_TREMONT_L: x86_pmu.late_ack = true; memcpy(hw_cache_event_ids, glp_hw_cache_event_ids, sizeof(hw_cache_event_ids)); @@ -5139,10 +5456,13 @@ __init int intel_pmu_init(void) hsw_format_attr : nhm_format_attr; extra_skl_attr = skl_format_attr; mem_attr = icl_events_attrs; + td_attr = icl_td_events_attrs; tsx_attr = icl_tsx_events_attrs; x86_pmu.rtm_abort_event = X86_CONFIG(.event=0xca, .umask=0x02); x86_pmu.lbr_pt_coexist = true; intel_pmu_pebs_data_source_skl(pmem); + x86_pmu.update_topdown_event = icl_update_topdown_event; + x86_pmu.set_topdown_event_period = icl_set_topdown_event_period; pr_cont("Icelake events, "); name = "icelake"; break; @@ -5198,6 +5518,15 @@ __init int intel_pmu_init(void) * counter, so do not extend mask to generic counters */ for_each_event_constraint(c, x86_pmu.event_constraints) { + /* + * Don't extend the topdown slots and metrics + * events to the generic counters. + */ + if (c->idxmsk64 & INTEL_PMC_MSK_TOPDOWN) { + c->weight = hweight64(c->idxmsk64); + continue; + } + if (c->cmask == FIXED_EVENT_FLAGS && c->idxmsk64 != INTEL_PMC_MSK_FIXED_REF_CYCLES) { c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1; @@ -5253,6 +5582,9 @@ __init int intel_pmu_init(void) if (x86_pmu.counter_freezing) x86_pmu.handle_irq = intel_pmu_handle_irq_v4; + if (x86_pmu.intel_cap.perf_metrics) + x86_pmu.intel_ctrl |= 1ULL << GLOBAL_CTRL_EN_PERF_METRICS; + return 0; } diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index 86848c57b55e..404315df1e16 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c @@ -670,9 +670,7 @@ unlock: static inline void intel_pmu_drain_pebs_buffer(void) { - struct pt_regs regs; - - x86_pmu.drain_pebs(®s); + x86_pmu.drain_pebs(NULL); } /* @@ -1737,6 +1735,7 @@ static void __intel_pmu_pebs_event(struct perf_event *event, struct x86_perf_regs perf_regs; struct pt_regs *regs = &perf_regs.regs; void *at = get_next_pebs_record_by_bit(base, top, bit); + struct pt_regs dummy_iregs; if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) { /* @@ -1749,6 +1748,9 @@ static void __intel_pmu_pebs_event(struct perf_event *event, } else if (!intel_pmu_save_and_restart(event)) return; + if (!iregs) + iregs = &dummy_iregs; + while (count > 1) { setup_sample(event, iregs, at, &data, regs); perf_event_output(event, &data, regs); @@ -1758,16 +1760,22 @@ static void __intel_pmu_pebs_event(struct perf_event *event, } setup_sample(event, iregs, at, &data, regs); - - /* - * All but the last records are processed. - * The last one is left to be able to call the overflow handler. - */ - if (perf_event_overflow(event, &data, regs)) { - x86_pmu_stop(event, 0); - return; + if (iregs == &dummy_iregs) { + /* + * The PEBS records may be drained in the non-overflow context, + * e.g., large PEBS + context switch. Perf should treat the + * last record the same as other PEBS records, and doesn't + * invoke the generic overflow handler. + */ + perf_event_output(event, &data, regs); + } else { + /* + * All but the last records are processed. + * The last one is left to be able to call the overflow handler. + */ + if (perf_event_overflow(event, &data, regs)) + x86_pmu_stop(event, 0); } - } static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index d5c6d3b340c5..86d012b3e0b4 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -12,6 +12,8 @@ struct intel_uncore_type **uncore_mmio_uncores = empty_uncore; static bool pcidrv_registered; struct pci_driver *uncore_pci_driver; +/* The PCI driver for the device which the uncore doesn't own. */ +struct pci_driver *uncore_pci_sub_driver; /* pci bus to socket mapping */ DEFINE_RAW_SPINLOCK(pci2phy_map_lock); struct list_head pci2phy_map_head = LIST_HEAD_INIT(pci2phy_map_head); @@ -989,65 +991,71 @@ uncore_types_init(struct intel_uncore_type **types, bool setid) } /* - * add a pci uncore device + * Get the die information of a PCI device. + * @pdev: The PCI device. + * @phys_id: The physical socket id which the device maps to. + * @die: The die id which the device maps to. */ -static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +static int uncore_pci_get_dev_die_info(struct pci_dev *pdev, + int *phys_id, int *die) { - struct intel_uncore_type *type; - struct intel_uncore_pmu *pmu = NULL; - struct intel_uncore_box *box; - int phys_id, die, ret; - - phys_id = uncore_pcibus_to_physid(pdev->bus); - if (phys_id < 0) + *phys_id = uncore_pcibus_to_physid(pdev->bus); + if (*phys_id < 0) return -ENODEV; - die = (topology_max_die_per_package() > 1) ? phys_id : - topology_phys_to_logical_pkg(phys_id); - if (die < 0) + *die = (topology_max_die_per_package() > 1) ? *phys_id : + topology_phys_to_logical_pkg(*phys_id); + if (*die < 0) return -EINVAL; - if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) { - int idx = UNCORE_PCI_DEV_IDX(id->driver_data); - - uncore_extra_pci_dev[die].dev[idx] = pdev; - pci_set_drvdata(pdev, NULL); - return 0; - } - - type = uncore_pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)]; + return 0; +} - /* - * Some platforms, e.g. Knights Landing, use a common PCI device ID - * for multiple instances of an uncore PMU device type. We should check - * PCI slot and func to indicate the uncore box. - */ - if (id->driver_data & ~0xffff) { - struct pci_driver *pci_drv = pdev->driver; - const struct pci_device_id *ids = pci_drv->id_table; - unsigned int devfn; - - while (ids && ids->vendor) { - if ((ids->vendor == pdev->vendor) && - (ids->device == pdev->device)) { - devfn = PCI_DEVFN(UNCORE_PCI_DEV_DEV(ids->driver_data), - UNCORE_PCI_DEV_FUNC(ids->driver_data)); - if (devfn == pdev->devfn) { - pmu = &type->pmus[UNCORE_PCI_DEV_IDX(ids->driver_data)]; - break; - } +/* + * Find the PMU of a PCI device. + * @pdev: The PCI device. + * @ids: The ID table of the available PCI devices with a PMU. + */ +static struct intel_uncore_pmu * +uncore_pci_find_dev_pmu(struct pci_dev *pdev, const struct pci_device_id *ids) +{ + struct intel_uncore_pmu *pmu = NULL; + struct intel_uncore_type *type; + kernel_ulong_t data; + unsigned int devfn; + + while (ids && ids->vendor) { + if ((ids->vendor == pdev->vendor) && + (ids->device == pdev->device)) { + data = ids->driver_data; + devfn = PCI_DEVFN(UNCORE_PCI_DEV_DEV(data), + UNCORE_PCI_DEV_FUNC(data)); + if (devfn == pdev->devfn) { + type = uncore_pci_uncores[UNCORE_PCI_DEV_TYPE(data)]; + pmu = &type->pmus[UNCORE_PCI_DEV_IDX(data)]; + break; } - ids++; } - if (pmu == NULL) - return -ENODEV; - } else { - /* - * for performance monitoring unit with multiple boxes, - * each box has a different function id. - */ - pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)]; + ids++; } + return pmu; +} + +/* + * Register the PMU for a PCI device + * @pdev: The PCI device. + * @type: The corresponding PMU type of the device. + * @pmu: The corresponding PMU of the device. + * @phys_id: The physical socket id which the device maps to. + * @die: The die id which the device maps to. + */ +static int uncore_pci_pmu_register(struct pci_dev *pdev, + struct intel_uncore_type *type, + struct intel_uncore_pmu *pmu, + int phys_id, int die) +{ + struct intel_uncore_box *box; + int ret; if (WARN_ON_ONCE(pmu->boxes[die] != NULL)) return -EINVAL; @@ -1067,7 +1075,6 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id box->pci_dev = pdev; box->pmu = pmu; uncore_box_init(box); - pci_set_drvdata(pdev, box); pmu->boxes[die] = box; if (atomic_inc_return(&pmu->activeboxes) > 1) @@ -1076,7 +1083,6 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id /* First active box registers the pmu */ ret = uncore_pmu_register(pmu); if (ret) { - pci_set_drvdata(pdev, NULL); pmu->boxes[die] = NULL; uncore_box_exit(box); kfree(box); @@ -1084,18 +1090,87 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id return ret; } +/* + * add a pci uncore device + */ +static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct intel_uncore_type *type; + struct intel_uncore_pmu *pmu = NULL; + int phys_id, die, ret; + + ret = uncore_pci_get_dev_die_info(pdev, &phys_id, &die); + if (ret) + return ret; + + if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) { + int idx = UNCORE_PCI_DEV_IDX(id->driver_data); + + uncore_extra_pci_dev[die].dev[idx] = pdev; + pci_set_drvdata(pdev, NULL); + return 0; + } + + type = uncore_pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)]; + + /* + * Some platforms, e.g. Knights Landing, use a common PCI device ID + * for multiple instances of an uncore PMU device type. We should check + * PCI slot and func to indicate the uncore box. + */ + if (id->driver_data & ~0xffff) { + struct pci_driver *pci_drv = pdev->driver; + + pmu = uncore_pci_find_dev_pmu(pdev, pci_drv->id_table); + if (pmu == NULL) + return -ENODEV; + } else { + /* + * for performance monitoring unit with multiple boxes, + * each box has a different function id. + */ + pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)]; + } + + ret = uncore_pci_pmu_register(pdev, type, pmu, phys_id, die); + + pci_set_drvdata(pdev, pmu->boxes[die]); + + return ret; +} + +/* + * Unregister the PMU of a PCI device + * @pmu: The corresponding PMU is unregistered. + * @phys_id: The physical socket id which the device maps to. + * @die: The die id which the device maps to. + */ +static void uncore_pci_pmu_unregister(struct intel_uncore_pmu *pmu, + int phys_id, int die) +{ + struct intel_uncore_box *box = pmu->boxes[die]; + + if (WARN_ON_ONCE(phys_id != box->pci_phys_id)) + return; + + pmu->boxes[die] = NULL; + if (atomic_dec_return(&pmu->activeboxes) == 0) + uncore_pmu_unregister(pmu); + uncore_box_exit(box); + kfree(box); +} + static void uncore_pci_remove(struct pci_dev *pdev) { struct intel_uncore_box *box; struct intel_uncore_pmu *pmu; int i, phys_id, die; - phys_id = uncore_pcibus_to_physid(pdev->bus); + if (uncore_pci_get_dev_die_info(pdev, &phys_id, &die)) + return; box = pci_get_drvdata(pdev); if (!box) { - die = (topology_max_die_per_package() > 1) ? phys_id : - topology_phys_to_logical_pkg(phys_id); for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) { if (uncore_extra_pci_dev[die].dev[i] == pdev) { uncore_extra_pci_dev[die].dev[i] = NULL; @@ -1107,15 +1182,84 @@ static void uncore_pci_remove(struct pci_dev *pdev) } pmu = box->pmu; - if (WARN_ON_ONCE(phys_id != box->pci_phys_id)) - return; pci_set_drvdata(pdev, NULL); - pmu->boxes[box->dieid] = NULL; - if (atomic_dec_return(&pmu->activeboxes) == 0) - uncore_pmu_unregister(pmu); - uncore_box_exit(box); - kfree(box); + + uncore_pci_pmu_unregister(pmu, phys_id, die); +} + +static int uncore_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev = data; + struct pci_dev *pdev = to_pci_dev(dev); + struct intel_uncore_pmu *pmu; + int phys_id, die; + + /* Unregister the PMU when the device is going to be deleted. */ + if (action != BUS_NOTIFY_DEL_DEVICE) + return NOTIFY_DONE; + + pmu = uncore_pci_find_dev_pmu(pdev, uncore_pci_sub_driver->id_table); + if (!pmu) + return NOTIFY_DONE; + + if (uncore_pci_get_dev_die_info(pdev, &phys_id, &die)) + return NOTIFY_DONE; + + uncore_pci_pmu_unregister(pmu, phys_id, die); + + return NOTIFY_OK; +} + +static struct notifier_block uncore_notifier = { + .notifier_call = uncore_bus_notify, +}; + +static void uncore_pci_sub_driver_init(void) +{ + const struct pci_device_id *ids = uncore_pci_sub_driver->id_table; + struct intel_uncore_type *type; + struct intel_uncore_pmu *pmu; + struct pci_dev *pci_sub_dev; + bool notify = false; + unsigned int devfn; + int phys_id, die; + + while (ids && ids->vendor) { + pci_sub_dev = NULL; + type = uncore_pci_uncores[UNCORE_PCI_DEV_TYPE(ids->driver_data)]; + /* + * Search the available device, and register the + * corresponding PMU. + */ + while ((pci_sub_dev = pci_get_device(PCI_VENDOR_ID_INTEL, + ids->device, pci_sub_dev))) { + devfn = PCI_DEVFN(UNCORE_PCI_DEV_DEV(ids->driver_data), + UNCORE_PCI_DEV_FUNC(ids->driver_data)); + if (devfn != pci_sub_dev->devfn) + continue; + + pmu = &type->pmus[UNCORE_PCI_DEV_IDX(ids->driver_data)]; + if (!pmu) + continue; + + if (uncore_pci_get_dev_die_info(pci_sub_dev, + &phys_id, &die)) + continue; + + if (!uncore_pci_pmu_register(pci_sub_dev, type, pmu, + phys_id, die)) + notify = true; + } + ids++; + } + + if (notify && bus_register_notifier(&pci_bus_type, &uncore_notifier)) + notify = false; + + if (!notify) + uncore_pci_sub_driver = NULL; } static int __init uncore_pci_init(void) @@ -1141,6 +1285,9 @@ static int __init uncore_pci_init(void) if (ret) goto errtype; + if (uncore_pci_sub_driver) + uncore_pci_sub_driver_init(); + pcidrv_registered = true; return 0; @@ -1158,6 +1305,8 @@ static void uncore_pci_exit(void) { if (pcidrv_registered) { pcidrv_registered = false; + if (uncore_pci_sub_driver) + bus_unregister_notifier(&pci_bus_type, &uncore_notifier); pci_unregister_driver(uncore_pci_driver); uncore_types_exit(uncore_pci_uncores); kfree(uncore_extra_pci_dev); @@ -1478,12 +1627,12 @@ static const struct intel_uncore_init_fun icl_uncore_init __initconst = { }; static const struct intel_uncore_init_fun tgl_uncore_init __initconst = { - .cpu_init = icl_uncore_cpu_init, + .cpu_init = tgl_uncore_cpu_init, .mmio_init = tgl_uncore_mmio_init, }; static const struct intel_uncore_init_fun tgl_l_uncore_init __initconst = { - .cpu_init = icl_uncore_cpu_init, + .cpu_init = tgl_uncore_cpu_init, .mmio_init = tgl_l_uncore_mmio_init, }; diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h index 105fdc69825e..83d2a7d490e0 100644 --- a/arch/x86/events/intel/uncore.h +++ b/arch/x86/events/intel/uncore.h @@ -552,6 +552,7 @@ extern struct intel_uncore_type **uncore_msr_uncores; extern struct intel_uncore_type **uncore_pci_uncores; extern struct intel_uncore_type **uncore_mmio_uncores; extern struct pci_driver *uncore_pci_driver; +extern struct pci_driver *uncore_pci_sub_driver; extern raw_spinlock_t pci2phy_map_lock; extern struct list_head pci2phy_map_head; extern struct pci_extra_dev *uncore_extra_pci_dev; @@ -567,6 +568,7 @@ void snb_uncore_cpu_init(void); void nhm_uncore_cpu_init(void); void skl_uncore_cpu_init(void); void icl_uncore_cpu_init(void); +void tgl_uncore_cpu_init(void); void tgl_uncore_mmio_init(void); void tgl_l_uncore_mmio_init(void); int snb_pci2phy_map_init(int devid); diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c index 6a4ca27b2c9e..39e632ed6ca9 100644 --- a/arch/x86/events/intel/uncore_snb.c +++ b/arch/x86/events/intel/uncore_snb.c @@ -126,6 +126,10 @@ #define ICL_UNC_CBO_0_PER_CTR0 0x702 #define ICL_UNC_CBO_MSR_OFFSET 0x8 +/* ICL ARB register */ +#define ICL_UNC_ARB_PER_CTR 0x3b1 +#define ICL_UNC_ARB_PERFEVTSEL 0x3b3 + DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); @@ -313,15 +317,21 @@ void skl_uncore_cpu_init(void) snb_uncore_arb.ops = &skl_uncore_msr_ops; } +static struct intel_uncore_ops icl_uncore_msr_ops = { + .disable_event = snb_uncore_msr_disable_event, + .enable_event = snb_uncore_msr_enable_event, + .read_counter = uncore_msr_read_counter, +}; + static struct intel_uncore_type icl_uncore_cbox = { .name = "cbox", - .num_counters = 4, + .num_counters = 2, .perf_ctr_bits = 44, .perf_ctr = ICL_UNC_CBO_0_PER_CTR0, .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0, .event_mask = SNB_UNC_RAW_EVENT_MASK, .msr_offset = ICL_UNC_CBO_MSR_OFFSET, - .ops = &skl_uncore_msr_ops, + .ops = &icl_uncore_msr_ops, .format_group = &snb_uncore_format_group, }; @@ -350,13 +360,25 @@ static struct intel_uncore_type icl_uncore_clockbox = { .single_fixed = 1, .event_mask = SNB_UNC_CTL_EV_SEL_MASK, .format_group = &icl_uncore_clock_format_group, - .ops = &skl_uncore_msr_ops, + .ops = &icl_uncore_msr_ops, .event_descs = icl_uncore_events, }; +static struct intel_uncore_type icl_uncore_arb = { + .name = "arb", + .num_counters = 1, + .num_boxes = 1, + .perf_ctr_bits = 44, + .perf_ctr = ICL_UNC_ARB_PER_CTR, + .event_ctl = ICL_UNC_ARB_PERFEVTSEL, + .event_mask = SNB_UNC_RAW_EVENT_MASK, + .ops = &icl_uncore_msr_ops, + .format_group = &snb_uncore_format_group, +}; + static struct intel_uncore_type *icl_msr_uncores[] = { &icl_uncore_cbox, - &snb_uncore_arb, + &icl_uncore_arb, &icl_uncore_clockbox, NULL, }; @@ -374,6 +396,21 @@ void icl_uncore_cpu_init(void) { uncore_msr_uncores = icl_msr_uncores; icl_uncore_cbox.num_boxes = icl_get_cbox_num(); +} + +static struct intel_uncore_type *tgl_msr_uncores[] = { + &icl_uncore_cbox, + &snb_uncore_arb, + &icl_uncore_clockbox, + NULL, +}; + +void tgl_uncore_cpu_init(void) +{ + uncore_msr_uncores = tgl_msr_uncores; + icl_uncore_cbox.num_boxes = icl_get_cbox_num(); + icl_uncore_cbox.ops = &skl_uncore_msr_ops; + icl_uncore_clockbox.ops = &skl_uncore_msr_ops; snb_uncore_arb.ops = &skl_uncore_msr_ops; } diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index 62e88ad919ff..7bdb1821215d 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -393,6 +393,11 @@ #define SNR_M2M_PCI_PMON_BOX_CTL 0x438 #define SNR_M2M_PCI_PMON_UMASK_EXT 0xff +/* SNR PCIE3 */ +#define SNR_PCIE3_PCI_PMON_CTL0 0x508 +#define SNR_PCIE3_PCI_PMON_CTR0 0x4e8 +#define SNR_PCIE3_PCI_PMON_BOX_CTL 0x4e0 + /* SNR IMC */ #define SNR_IMC_MMIO_PMON_FIXED_CTL 0x54 #define SNR_IMC_MMIO_PMON_FIXED_CTR 0x38 @@ -3749,7 +3754,9 @@ static int skx_iio_set_mapping(struct intel_uncore_type *type) ret = skx_iio_get_topology(type); if (ret) - return ret; + goto clear_attr_update; + + ret = -ENOMEM; /* One more for NULL. */ attrs = kcalloc((uncore_max_dies() + 1), sizeof(*attrs), GFP_KERNEL); @@ -3781,8 +3788,9 @@ err: kfree(eas); kfree(attrs); kfree(type->topology); +clear_attr_update: type->attr_update = NULL; - return -ENOMEM; + return ret; } static void skx_iio_cleanup_mapping(struct intel_uncore_type *type) @@ -4551,12 +4559,46 @@ static struct intel_uncore_type snr_uncore_m2m = { .format_group = &snr_m2m_uncore_format_group, }; +static void snr_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + + pci_write_config_dword(pdev, hwc->config_base, (u32)(hwc->config | SNBEP_PMON_CTL_EN)); + pci_write_config_dword(pdev, hwc->config_base + 4, (u32)(hwc->config >> 32)); +} + +static struct intel_uncore_ops snr_pcie3_uncore_pci_ops = { + .init_box = snr_m2m_uncore_pci_init_box, + .disable_box = snbep_uncore_pci_disable_box, + .enable_box = snbep_uncore_pci_enable_box, + .disable_event = snbep_uncore_pci_disable_event, + .enable_event = snr_uncore_pci_enable_event, + .read_counter = snbep_uncore_pci_read_counter, +}; + +static struct intel_uncore_type snr_uncore_pcie3 = { + .name = "pcie3", + .num_counters = 4, + .num_boxes = 1, + .perf_ctr_bits = 48, + .perf_ctr = SNR_PCIE3_PCI_PMON_CTR0, + .event_ctl = SNR_PCIE3_PCI_PMON_CTL0, + .event_mask = SKX_IIO_PMON_RAW_EVENT_MASK, + .event_mask_ext = SKX_IIO_PMON_RAW_EVENT_MASK_EXT, + .box_ctl = SNR_PCIE3_PCI_PMON_BOX_CTL, + .ops = &snr_pcie3_uncore_pci_ops, + .format_group = &skx_uncore_iio_format_group, +}; + enum { SNR_PCI_UNCORE_M2M, + SNR_PCI_UNCORE_PCIE3, }; static struct intel_uncore_type *snr_pci_uncores[] = { [SNR_PCI_UNCORE_M2M] = &snr_uncore_m2m, + [SNR_PCI_UNCORE_PCIE3] = &snr_uncore_pcie3, NULL, }; @@ -4573,6 +4615,19 @@ static struct pci_driver snr_uncore_pci_driver = { .id_table = snr_uncore_pci_ids, }; +static const struct pci_device_id snr_uncore_pci_sub_ids[] = { + { /* PCIe3 RP */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x334a), + .driver_data = UNCORE_PCI_DEV_FULL_DATA(4, 0, SNR_PCI_UNCORE_PCIE3, 0), + }, + { /* end: all zeroes */ } +}; + +static struct pci_driver snr_uncore_pci_sub_driver = { + .name = "snr_uncore_sub", + .id_table = snr_uncore_pci_sub_ids, +}; + int snr_uncore_pci_init(void) { /* SNR UBOX DID */ @@ -4584,6 +4639,7 @@ int snr_uncore_pci_init(void) uncore_pci_uncores = snr_pci_uncores; uncore_pci_driver = &snr_uncore_pci_driver; + uncore_pci_sub_driver = &snr_uncore_pci_sub_driver; return 0; } @@ -4751,10 +4807,10 @@ static struct uncore_event_desc snr_uncore_imc_freerunning_events[] = { INTEL_UNCORE_EVENT_DESC(dclk, "event=0xff,umask=0x10"), INTEL_UNCORE_EVENT_DESC(read, "event=0xff,umask=0x20"), - INTEL_UNCORE_EVENT_DESC(read.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(read.scale, "6.103515625e-5"), INTEL_UNCORE_EVENT_DESC(read.unit, "MiB"), INTEL_UNCORE_EVENT_DESC(write, "event=0xff,umask=0x21"), - INTEL_UNCORE_EVENT_DESC(write.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(write.scale, "6.103515625e-5"), INTEL_UNCORE_EVENT_DESC(write.unit, "MiB"), { /* end: all zeroes */ }, }; @@ -5212,17 +5268,17 @@ static struct uncore_event_desc icx_uncore_imc_freerunning_events[] = { INTEL_UNCORE_EVENT_DESC(dclk, "event=0xff,umask=0x10"), INTEL_UNCORE_EVENT_DESC(read, "event=0xff,umask=0x20"), - INTEL_UNCORE_EVENT_DESC(read.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(read.scale, "6.103515625e-5"), INTEL_UNCORE_EVENT_DESC(read.unit, "MiB"), INTEL_UNCORE_EVENT_DESC(write, "event=0xff,umask=0x21"), - INTEL_UNCORE_EVENT_DESC(write.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(write.scale, "6.103515625e-5"), INTEL_UNCORE_EVENT_DESC(write.unit, "MiB"), INTEL_UNCORE_EVENT_DESC(ddrt_read, "event=0xff,umask=0x30"), - INTEL_UNCORE_EVENT_DESC(ddrt_read.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(ddrt_read.scale, "6.103515625e-5"), INTEL_UNCORE_EVENT_DESC(ddrt_read.unit, "MiB"), INTEL_UNCORE_EVENT_DESC(ddrt_write, "event=0xff,umask=0x31"), - INTEL_UNCORE_EVENT_DESC(ddrt_write.scale, "3.814697266e-6"), + INTEL_UNCORE_EVENT_DESC(ddrt_write.scale, "6.103515625e-5"), INTEL_UNCORE_EVENT_DESC(ddrt_write.unit, "MiB"), { /* end: all zeroes */ }, }; diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c index a949f6f55991..4be8f9cabd07 100644 --- a/arch/x86/events/msr.c +++ b/arch/x86/events/msr.c @@ -78,6 +78,7 @@ static bool test_intel(int idx, void *data) case INTEL_FAM6_ATOM_GOLDMONT_PLUS: case INTEL_FAM6_ATOM_TREMONT_D: case INTEL_FAM6_ATOM_TREMONT: + case INTEL_FAM6_ATOM_TREMONT_L: case INTEL_FAM6_XEON_PHI_KNL: case INTEL_FAM6_XEON_PHI_KNM: diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 7b68ab5f19e7..ee2b9b9fc2a5 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -79,6 +79,31 @@ static inline bool constraint_match(struct event_constraint *c, u64 ecode) #define PERF_X86_EVENT_PEBS_VIA_PT 0x0800 /* use PT buffer for PEBS */ #define PERF_X86_EVENT_PAIR 0x1000 /* Large Increment per Cycle */ #define PERF_X86_EVENT_LBR_SELECT 0x2000 /* Save/Restore MSR_LBR_SELECT */ +#define PERF_X86_EVENT_TOPDOWN 0x4000 /* Count Topdown slots/metrics events */ + +static inline bool is_topdown_count(struct perf_event *event) +{ + return event->hw.flags & PERF_X86_EVENT_TOPDOWN; +} + +static inline bool is_metric_event(struct perf_event *event) +{ + u64 config = event->attr.config; + + return ((config & ARCH_PERFMON_EVENTSEL_EVENT) == 0) && + ((config & INTEL_ARCH_EVENT_MASK) >= INTEL_TD_METRIC_RETIRING) && + ((config & INTEL_ARCH_EVENT_MASK) <= INTEL_TD_METRIC_MAX); +} + +static inline bool is_slots_event(struct perf_event *event) +{ + return (event->attr.config & INTEL_ARCH_EVENT_MASK) == INTEL_TD_SLOTS; +} + +static inline bool is_topdown_event(struct perf_event *event) +{ + return is_metric_event(event) || is_slots_event(event); +} struct amd_nb { int nb_id; /* NorthBridge id */ @@ -210,6 +235,8 @@ struct cpu_hw_events { they've never been enabled yet */ int n_txn; /* the # last events in the below arrays; added in the current transaction */ + int n_txn_pair; + int n_txn_metric; int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */ u64 tags[X86_PMC_IDX_MAX]; @@ -285,6 +312,12 @@ struct cpu_hw_events { u64 tfa_shadow; /* + * Perf Metrics + */ + /* number of accepted metrics events */ + int n_metric; + + /* * AMD specific bits */ struct amd_nb *amd_nb; @@ -376,6 +409,19 @@ struct cpu_hw_events { EVENT_CONSTRAINT(c, (1ULL << (32+n)), FIXED_EVENT_FLAGS) /* + * The special metric counters do not actually exist. They are calculated from + * the combination of the FxCtr3 + MSR_PERF_METRICS. + * + * The special metric counters are mapped to a dummy offset for the scheduler. + * The sharing between multiple users of the same metric without multiplexing + * is not allowed, even though the hardware supports that in principle. + */ + +#define METRIC_EVENT_CONSTRAINT(c, n) \ + EVENT_CONSTRAINT(c, (1ULL << (INTEL_PMC_IDX_METRIC_BASE + n)), \ + INTEL_ARCH_EVENT_MASK) + +/* * Constraint on the Event code + UMask */ #define INTEL_UEVENT_CONSTRAINT(c, n) \ @@ -537,7 +583,7 @@ union perf_capabilities { */ u64 full_width_write:1; u64 pebs_baseline:1; - u64 pebs_metrics_available:1; + u64 perf_metrics:1; u64 pebs_output_pt_available:1; }; u64 capabilities; @@ -727,6 +773,12 @@ struct x86_pmu { atomic_t lbr_exclusive[x86_lbr_exclusive_max]; /* + * Intel perf metrics + */ + u64 (*update_topdown_event)(struct perf_event *event); + int (*set_topdown_event_period)(struct perf_event *event); + + /* * perf task context (i.e. struct perf_event_context::task_ctx_data) * switch helper to bridge calls from perf/core to perf/x86. * See struct pmu::swap_task_ctx() usage for examples; diff --git a/arch/x86/events/rapl.c b/arch/x86/events/rapl.c index 67b411f7e8c4..7c0120e2e957 100644 --- a/arch/x86/events/rapl.c +++ b/arch/x86/events/rapl.c @@ -815,6 +815,7 @@ static const struct x86_cpu_id rapl_model_match[] __initconst = { X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &model_spr), X86_MATCH_VENDOR_FAM(AMD, 0x17, &model_amd_fam17h), X86_MATCH_VENDOR_FAM(HYGON, 0x18, &model_amd_fam17h), + X86_MATCH_VENDOR_FAM(AMD, 0x19, &model_amd_fam17h), {}, }; MODULE_DEVICE_TABLE(x86cpu, rapl_model_match); diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index 6035df1b49e1..e04d90af4c27 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -148,9 +148,9 @@ static inline bool hv_reenlightenment_available(void) * Check for required features and priviliges to make TSC frequency * change notifications work. */ - return ms_hyperv.features & HV_X64_ACCESS_FREQUENCY_MSRS && + return ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS && ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE && - ms_hyperv.features & HV_X64_ACCESS_REENLIGHTENMENT; + ms_hyperv.features & HV_ACCESS_REENLIGHTENMENT; } DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_reenlightenment) @@ -330,8 +330,8 @@ void __init hyperv_init(void) return; /* Absolutely required MSRs */ - required_msrs = HV_X64_MSR_HYPERCALL_AVAILABLE | - HV_X64_MSR_VP_INDEX_AVAILABLE; + required_msrs = HV_MSR_HYPERCALL_AVAILABLE | + HV_MSR_VP_INDEX_AVAILABLE; if ((ms_hyperv.features & required_msrs) != required_msrs) return; diff --git a/arch/x86/hyperv/hv_spinlock.c b/arch/x86/hyperv/hv_spinlock.c index 07f21a06392f..f3270c1fc48c 100644 --- a/arch/x86/hyperv/hv_spinlock.c +++ b/arch/x86/hyperv/hv_spinlock.c @@ -66,7 +66,7 @@ void __init hv_init_spinlocks(void) { if (!hv_pvspin || !apic || !(ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) || - !(ms_hyperv.features & HV_X64_MSR_GUEST_IDLE_AVAILABLE)) { + !(ms_hyperv.features & HV_MSR_GUEST_IDLE_AVAILABLE)) { pr_info("PV spinlocks disabled\n"); return; } diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index ca8a657edf59..a09fc37ead9d 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -239,7 +239,6 @@ beyond_if: (regs)->ss = __USER32_DS; regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0; - set_fs(USER_DS); return 0; } diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index ca0976456a6b..6d2df1ee427b 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -159,8 +159,6 @@ static inline u64 x86_default_get_root_pointer(void) extern int x86_acpi_numa_init(void); #endif /* CONFIG_ACPI_NUMA */ -#define acpi_unlazy_tlb(x) leave_mm(x) - #ifdef CONFIG_ACPI_APEI static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr) { diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 2cc44e957c31..4e3099d9ae62 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -374,12 +374,12 @@ extern struct apic *apic; #define apic_driver(sym) \ static const struct apic *__apicdrivers_##sym __used \ __aligned(sizeof(struct apic *)) \ - __section(.apicdrivers) = { &sym } + __section(".apicdrivers") = { &sym } #define apic_drivers(sym1, sym2) \ static struct apic *__apicdrivers_##sym1##sym2[2] __used \ __aligned(sizeof(struct apic *)) \ - __section(.apicdrivers) = { &sym1, &sym2 } + __section(".apicdrivers") = { &sym1, &sym2 } extern struct apic *__apicdrivers[], *__apicdrivers_end[]; @@ -519,6 +519,14 @@ static inline bool apic_id_is_primary_thread(unsigned int id) { return false; } static inline void apic_smt_update(void) { } #endif +struct msi_msg; + +#ifdef CONFIG_PCI_MSI +void x86_vector_msi_compose_msg(struct irq_data *data, struct msi_msg *msg); +#else +# define x86_vector_msi_compose_msg NULL +#endif + extern void ioapic_zap_locks(void); #endif /* _ASM_X86_APIC_H */ diff --git a/arch/x86/include/asm/asm-prototypes.h b/arch/x86/include/asm/asm-prototypes.h index 5a42f9206138..51e2bf27cc9b 100644 --- a/arch/x86/include/asm/asm-prototypes.h +++ b/arch/x86/include/asm/asm-prototypes.h @@ -5,6 +5,7 @@ #include <asm/string.h> #include <asm/page.h> #include <asm/checksum.h> +#include <asm/mce.h> #include <asm-generic/asm-prototypes.h> diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h index 5c15f95b1ba7..0603c7423aca 100644 --- a/arch/x86/include/asm/asm.h +++ b/arch/x86/include/asm/asm.h @@ -135,14 +135,21 @@ # define _ASM_EXTABLE_UA(from, to) \ _ASM_EXTABLE_HANDLE(from, to, ex_handler_uaccess) +# define _ASM_EXTABLE_CPY(from, to) \ + _ASM_EXTABLE_HANDLE(from, to, ex_handler_copy) + # define _ASM_EXTABLE_FAULT(from, to) \ _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault) -# define _ASM_NOKPROBE(entry) \ +# ifdef CONFIG_KPROBES +# define _ASM_NOKPROBE(entry) \ .pushsection "_kprobe_blacklist","aw" ; \ _ASM_ALIGN ; \ _ASM_PTR (entry); \ .popsection +# else +# define _ASM_NOKPROBE(entry) +# endif #else /* ! __ASSEMBLY__ */ # define _EXPAND_EXTABLE_HANDLE(x) #x @@ -160,6 +167,9 @@ # define _ASM_EXTABLE_UA(from, to) \ _ASM_EXTABLE_HANDLE(from, to, ex_handler_uaccess) +# define _ASM_EXTABLE_CPY(from, to) \ + _ASM_EXTABLE_HANDLE(from, to, ex_handler_copy) + # define _ASM_EXTABLE_FAULT(from, to) \ _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault) diff --git a/arch/x86/include/asm/cache.h b/arch/x86/include/asm/cache.h index abe08690a887..69404eae9983 100644 --- a/arch/x86/include/asm/cache.h +++ b/arch/x86/include/asm/cache.h @@ -8,7 +8,7 @@ #define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) -#define __read_mostly __attribute__((__section__(".data..read_mostly"))) +#define __read_mostly __section(".data..read_mostly") #define INTERNODE_CACHE_SHIFT CONFIG_X86_INTERNODE_CACHE_SHIFT #define INTERNODE_CACHE_BYTES (1 << INTERNODE_CACHE_SHIFT) diff --git a/arch/x86/include/asm/checksum.h b/arch/x86/include/asm/checksum.h index 0ada98d5d09f..bca625a60186 100644 --- a/arch/x86/include/asm/checksum.h +++ b/arch/x86/include/asm/checksum.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 1 #define HAVE_CSUM_COPY_USER +#define _HAVE_ARCH_CSUM_AND_COPY #ifdef CONFIG_X86_32 # include <asm/checksum_32.h> #else diff --git a/arch/x86/include/asm/checksum_32.h b/arch/x86/include/asm/checksum_32.h index 11624c8a9d8d..17da95387997 100644 --- a/arch/x86/include/asm/checksum_32.h +++ b/arch/x86/include/asm/checksum_32.h @@ -27,9 +27,7 @@ asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum); * better 64-bit) boundary */ -asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, - int len, __wsum sum, - int *src_err_ptr, int *dst_err_ptr); +asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, int len); /* * Note: when you get a NULL pointer exception here this means someone @@ -38,26 +36,20 @@ asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, * If you use these functions directly please don't forget the * access_ok(). */ -static inline __wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) +static inline __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len) { - return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL); + return csum_partial_copy_generic(src, dst, len); } static inline __wsum csum_and_copy_from_user(const void __user *src, - void *dst, int len, - __wsum sum, int *err_ptr) + void *dst, int len) { __wsum ret; might_sleep(); - if (!user_access_begin(src, len)) { - if (len) - *err_ptr = -EFAULT; - return sum; - } - ret = csum_partial_copy_generic((__force void *)src, dst, - len, sum, err_ptr, NULL); + if (!user_access_begin(src, len)) + return 0; + ret = csum_partial_copy_generic((__force void *)src, dst, len); user_access_end(); return ret; @@ -178,23 +170,17 @@ static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, */ static inline __wsum csum_and_copy_to_user(const void *src, void __user *dst, - int len, __wsum sum, - int *err_ptr) + int len) { __wsum ret; might_sleep(); - if (user_access_begin(dst, len)) { - ret = csum_partial_copy_generic(src, (__force void *)dst, - len, sum, NULL, err_ptr); - user_access_end(); - return ret; - } + if (!user_access_begin(dst, len)) + return 0; - if (len) - *err_ptr = -EFAULT; - - return (__force __wsum)-1; /* invalid checksum */ + ret = csum_partial_copy_generic(src, (__force void *)dst, len); + user_access_end(); + return ret; } #endif /* _ASM_X86_CHECKSUM_32_H */ diff --git a/arch/x86/include/asm/checksum_64.h b/arch/x86/include/asm/checksum_64.h index 0a289b87e872..407beebadaf4 100644 --- a/arch/x86/include/asm/checksum_64.h +++ b/arch/x86/include/asm/checksum_64.h @@ -130,17 +130,11 @@ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, extern __wsum csum_partial(const void *buff, int len, __wsum sum); /* Do not call this directly. Use the wrappers below */ -extern __visible __wsum csum_partial_copy_generic(const void *src, const void *dst, - int len, __wsum sum, - int *src_err_ptr, int *dst_err_ptr); +extern __visible __wsum csum_partial_copy_generic(const void *src, void *dst, int len); - -extern __wsum csum_and_copy_from_user(const void __user *src, void *dst, - int len, __wsum isum, int *errp); -extern __wsum csum_and_copy_to_user(const void *src, void __user *dst, - int len, __wsum isum, int *errp); -extern __wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum); +extern __wsum csum_and_copy_from_user(const void __user *src, void *dst, int len); +extern __wsum csum_and_copy_to_user(const void *src, void __user *dst, int len); +extern __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len); /** * ip_compute_csum - Compute an 16bit IP checksum. diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h index d4edf281fff4..0e327a01f50f 100644 --- a/arch/x86/include/asm/compat.h +++ b/arch/x86/include/asm/compat.h @@ -27,8 +27,6 @@ typedef u16 compat_nlink_t; typedef u16 compat_ipc_pid_t; typedef u32 compat_caddr_t; typedef __kernel_fsid_t compat_fsid_t; -typedef s64 __attribute__((aligned(4))) compat_s64; -typedef u64 __attribute__((aligned(4))) compat_u64; struct compat_stat { compat_dev_t st_dev; @@ -211,6 +209,7 @@ static inline bool in_compat_syscall(void) return in_32bit_syscall(); } #define in_compat_syscall in_compat_syscall /* override the generic impl */ +#define compat_need_64bit_alignment_fixup in_ia32_syscall #endif struct compat_siginfo; diff --git a/arch/x86/include/asm/copy_mc_test.h b/arch/x86/include/asm/copy_mc_test.h new file mode 100644 index 000000000000..e4991ba96726 --- /dev/null +++ b/arch/x86/include/asm/copy_mc_test.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _COPY_MC_TEST_H_ +#define _COPY_MC_TEST_H_ + +#ifndef __ASSEMBLY__ +#ifdef CONFIG_COPY_MC_TEST +extern unsigned long copy_mc_test_src; +extern unsigned long copy_mc_test_dst; + +static inline void copy_mc_inject_src(void *addr) +{ + if (addr) + copy_mc_test_src = (unsigned long) addr; + else + copy_mc_test_src = ~0UL; +} + +static inline void copy_mc_inject_dst(void *addr) +{ + if (addr) + copy_mc_test_dst = (unsigned long) addr; + else + copy_mc_test_dst = ~0UL; +} +#else /* CONFIG_COPY_MC_TEST */ +static inline void copy_mc_inject_src(void *addr) +{ +} + +static inline void copy_mc_inject_dst(void *addr) +{ +} +#endif /* CONFIG_COPY_MC_TEST */ + +#else /* __ASSEMBLY__ */ +#include <asm/export.h> + +#ifdef CONFIG_COPY_MC_TEST +.macro COPY_MC_TEST_CTL + .pushsection .data + .align 8 + .globl copy_mc_test_src + copy_mc_test_src: + .quad 0 + EXPORT_SYMBOL_GPL(copy_mc_test_src) + .globl copy_mc_test_dst + copy_mc_test_dst: + .quad 0 + EXPORT_SYMBOL_GPL(copy_mc_test_dst) + .popsection +.endm + +.macro COPY_MC_TEST_SRC reg count target + leaq \count(\reg), %r9 + cmp copy_mc_test_src, %r9 + ja \target +.endm + +.macro COPY_MC_TEST_DST reg count target + leaq \count(\reg), %r9 + cmp copy_mc_test_dst, %r9 + ja \target +.endm +#else +.macro COPY_MC_TEST_CTL +.endm + +.macro COPY_MC_TEST_SRC reg count target +.endm + +.macro COPY_MC_TEST_DST reg count target +.endm +#endif /* CONFIG_COPY_MC_TEST */ +#endif /* __ASSEMBLY__ */ +#endif /* _COPY_MC_TEST_H_ */ diff --git a/arch/x86/include/asm/cpu_entry_area.h b/arch/x86/include/asm/cpu_entry_area.h index 8902fdb7de13..3d52b094850a 100644 --- a/arch/x86/include/asm/cpu_entry_area.h +++ b/arch/x86/include/asm/cpu_entry_area.h @@ -11,25 +11,29 @@ #ifdef CONFIG_X86_64 /* Macro to enforce the same ordering and stack sizes */ -#define ESTACKS_MEMBERS(guardsize) \ - char DF_stack_guard[guardsize]; \ - char DF_stack[EXCEPTION_STKSZ]; \ - char NMI_stack_guard[guardsize]; \ - char NMI_stack[EXCEPTION_STKSZ]; \ - char DB_stack_guard[guardsize]; \ - char DB_stack[EXCEPTION_STKSZ]; \ - char MCE_stack_guard[guardsize]; \ - char MCE_stack[EXCEPTION_STKSZ]; \ - char IST_top_guard[guardsize]; \ +#define ESTACKS_MEMBERS(guardsize, optional_stack_size) \ + char DF_stack_guard[guardsize]; \ + char DF_stack[EXCEPTION_STKSZ]; \ + char NMI_stack_guard[guardsize]; \ + char NMI_stack[EXCEPTION_STKSZ]; \ + char DB_stack_guard[guardsize]; \ + char DB_stack[EXCEPTION_STKSZ]; \ + char MCE_stack_guard[guardsize]; \ + char MCE_stack[EXCEPTION_STKSZ]; \ + char VC_stack_guard[guardsize]; \ + char VC_stack[optional_stack_size]; \ + char VC2_stack_guard[guardsize]; \ + char VC2_stack[optional_stack_size]; \ + char IST_top_guard[guardsize]; \ /* The exception stacks' physical storage. No guard pages required */ struct exception_stacks { - ESTACKS_MEMBERS(0) + ESTACKS_MEMBERS(0, 0) }; /* The effective cpu entry area mapping with guard pages. */ struct cea_exception_stacks { - ESTACKS_MEMBERS(PAGE_SIZE) + ESTACKS_MEMBERS(PAGE_SIZE, EXCEPTION_STKSZ) }; /* @@ -40,6 +44,8 @@ enum exception_stack_ordering { ESTACK_NMI, ESTACK_DB, ESTACK_MCE, + ESTACK_VC, + ESTACK_VC2, N_EXCEPTION_STACKS }; @@ -139,4 +145,7 @@ static inline struct entry_stack *cpu_entry_stack(int cpu) #define __this_cpu_ist_top_va(name) \ CEA_ESTACK_TOP(__this_cpu_read(cea_exception_stacks), name) +#define __this_cpu_ist_bottom_va(name) \ + CEA_ESTACK_BOT(__this_cpu_read(cea_exception_stacks), name) + #endif diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 2901d5df4366..dad350d42ecf 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -96,7 +96,7 @@ #define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in IA32 userspace */ #define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in IA32 userspace */ #define X86_FEATURE_REP_GOOD ( 3*32+16) /* REP microcode works well */ -/* free ( 3*32+17) */ +#define X86_FEATURE_SME_COHERENT ( 3*32+17) /* "" AMD hardware-enforced cache coherency */ #define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" LFENCE synchronizes RDTSC */ #define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */ #define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */ @@ -236,6 +236,7 @@ #define X86_FEATURE_EPT_AD ( 8*32+17) /* Intel Extended Page Table access-dirty bit */ #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 */ /* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */ #define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/ @@ -288,6 +289,7 @@ #define X86_FEATURE_FENCE_SWAPGS_USER (11*32+ 4) /* "" LFENCE in user entry SWAPGS path */ #define X86_FEATURE_FENCE_SWAPGS_KERNEL (11*32+ 5) /* "" LFENCE in kernel entry SWAPGS path */ #define X86_FEATURE_SPLIT_LOCK_DETECT (11*32+ 6) /* #AC for split lock */ +#define X86_FEATURE_PER_THREAD_MBA (11*32+ 7) /* "" Per-thread Memory Bandwidth Allocation */ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ @@ -353,6 +355,7 @@ #define X86_FEATURE_CLDEMOTE (16*32+25) /* CLDEMOTE instruction */ #define X86_FEATURE_MOVDIRI (16*32+27) /* MOVDIRI instruction */ #define X86_FEATURE_MOVDIR64B (16*32+28) /* MOVDIR64B instruction */ +#define X86_FEATURE_ENQCMD (16*32+29) /* ENQCMD and ENQCMDS instructions */ /* AMD-defined CPU features, CPUID level 0x80000007 (EBX), word 17 */ #define X86_FEATURE_OVERFLOW_RECOV (17*32+ 0) /* MCA overflow recovery support */ @@ -368,6 +371,7 @@ #define X86_FEATURE_MD_CLEAR (18*32+10) /* VERW clears CPU buffers */ #define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */ #define X86_FEATURE_SERIALIZE (18*32+14) /* SERIALIZE instruction */ +#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_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */ diff --git a/arch/x86/include/asm/debugreg.h b/arch/x86/include/asm/debugreg.h index e89558a3fe4a..cfdf307ddc01 100644 --- a/arch/x86/include/asm/debugreg.h +++ b/arch/x86/include/asm/debugreg.h @@ -90,8 +90,6 @@ static __always_inline bool hw_breakpoint_active(void) return __this_cpu_read(cpu_dr7) & DR_GLOBAL_ENABLE_MASK; } -extern void aout_dump_debugregs(struct user *dump); - extern void hw_breakpoint_restore(void); static __always_inline unsigned long local_db_save(void) diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index 1ced11d31932..476082a83d1c 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h @@ -383,6 +383,33 @@ static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit) void alloc_intr_gate(unsigned int n, const void *addr); +static inline void init_idt_data(struct idt_data *data, unsigned int n, + const void *addr) +{ + BUG_ON(n > 0xFF); + + memset(data, 0, sizeof(*data)); + data->vector = n; + data->addr = addr; + data->segment = __KERNEL_CS; + data->bits.type = GATE_INTERRUPT; + data->bits.p = 1; +} + +static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d) +{ + unsigned long addr = (unsigned long) d->addr; + + gate->offset_low = (u16) addr; + gate->segment = (u16) d->segment; + gate->bits = d->bits; + gate->offset_middle = (u16) (addr >> 16); +#ifdef CONFIG_X86_64 + gate->offset_high = (u32) (addr >> 32); + gate->reserved = 0; +#endif +} + extern unsigned long system_vectors[]; extern void load_current_idt(void); diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h index a91f3b6e4f2a..f7e7099af595 100644 --- a/arch/x86/include/asm/desc_defs.h +++ b/arch/x86/include/asm/desc_defs.h @@ -74,6 +74,13 @@ struct idt_bits { p : 1; } __attribute__((packed)); +struct idt_data { + unsigned int vector; + unsigned int segment; + struct idt_bits bits; + const void *addr; +}; + struct gate_struct { u16 offset_low; u16 segment; @@ -109,6 +116,9 @@ struct desc_ptr { #endif /* !__ASSEMBLY__ */ +/* Boot IDT definitions */ +#define BOOT_IDT_ENTRIES 32 + /* Access rights as returned by LAR */ #define AR_TYPE_RODATA (0 * (1 << 9)) #define AR_TYPE_RWDATA (1 * (1 << 9)) diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h index 4ea8584682f9..5861d34f9771 100644 --- a/arch/x86/include/asm/disabled-features.h +++ b/arch/x86/include/asm/disabled-features.h @@ -56,6 +56,12 @@ # define DISABLE_PTI (1 << (X86_FEATURE_PTI & 31)) #endif +#ifdef CONFIG_IOMMU_SUPPORT +# define DISABLE_ENQCMD 0 +#else +# define DISABLE_ENQCMD (1 << (X86_FEATURE_ENQCMD & 31)) +#endif + /* * Make sure to add features to the correct mask */ @@ -75,7 +81,8 @@ #define DISABLED_MASK13 0 #define DISABLED_MASK14 0 #define DISABLED_MASK15 0 -#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57|DISABLE_UMIP) +#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57|DISABLE_UMIP| \ + DISABLE_ENQCMD) #define DISABLED_MASK17 0 #define DISABLED_MASK18 0 #define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19) diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index fed67eafcacc..bb1654fe0ce7 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -8,10 +8,8 @@ */ #include <linux/scatterlist.h> -#include <linux/dma-debug.h> #include <asm/io.h> #include <asm/swiotlb.h> -#include <linux/dma-contiguous.h> extern int iommu_merge; extern int panic_on_overflow; diff --git a/arch/x86/include/asm/extable.h b/arch/x86/include/asm/extable.h index d8c2198d543b..1f0cbc52937c 100644 --- a/arch/x86/include/asm/extable.h +++ b/arch/x86/include/asm/extable.h @@ -29,10 +29,17 @@ struct pt_regs; (b)->handler = (tmp).handler - (delta); \ } while (0) +enum handler_type { + EX_HANDLER_NONE, + EX_HANDLER_FAULT, + EX_HANDLER_UACCESS, + EX_HANDLER_OTHER +}; + extern int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code, unsigned long fault_addr); extern int fixup_bug(struct pt_regs *regs, int trapnr); -extern bool ex_has_fault_handler(unsigned long ip); +extern enum handler_type ex_get_fault_handler_type(unsigned long ip); extern void early_fixup_exception(struct pt_regs *regs, int trapnr); #endif diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index 0f0dd645b594..77217bd292bd 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h @@ -99,7 +99,7 @@ enum fixed_addresses { FIX_PCIE_MCFG, #endif #endif -#ifdef CONFIG_PARAVIRT +#ifdef CONFIG_PARAVIRT_XXL FIX_PARAVIRT_BOOTMAP, #endif #ifdef CONFIG_X86_INTEL_MID diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h index b774c52e5411..dcd9503b1098 100644 --- a/arch/x86/include/asm/fpu/api.h +++ b/arch/x86/include/asm/fpu/api.h @@ -62,4 +62,16 @@ extern void switch_fpu_return(void); */ extern int cpu_has_xfeatures(u64 xfeatures_mask, const char **feature_name); +/* + * Tasks that are not using SVA have mm->pasid set to zero to note that they + * will not have the valid bit set in MSR_IA32_PASID while they are running. + */ +#define PASID_DISABLED 0 + +#ifdef CONFIG_IOMMU_SUPPORT +/* Update current's PASID MSR/state by mm's PASID. */ +void update_pasid(void); +#else +static inline void update_pasid(void) { } +#endif #endif /* _ASM_X86_FPU_API_H */ diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index 0a460f2a3f90..8d33ad80704f 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -19,6 +19,7 @@ #include <asm/user.h> #include <asm/fpu/api.h> #include <asm/fpu/xstate.h> +#include <asm/fpu/xcr.h> #include <asm/cpufeature.h> #include <asm/trace/fpu.h> @@ -583,38 +584,13 @@ static inline void switch_fpu_finish(struct fpu *new_fpu) pkru_val = pk->pkru; } __write_pkru(pkru_val); -} - -/* - * MXCSR and XCR definitions: - */ - -static inline void ldmxcsr(u32 mxcsr) -{ - asm volatile("ldmxcsr %0" :: "m" (mxcsr)); -} - -extern unsigned int mxcsr_feature_mask; - -#define XCR_XFEATURE_ENABLED_MASK 0x00000000 -static inline u64 xgetbv(u32 index) -{ - u32 eax, edx; - - asm volatile(".byte 0x0f,0x01,0xd0" /* xgetbv */ - : "=a" (eax), "=d" (edx) - : "c" (index)); - return eax + ((u64)edx << 32); -} - -static inline void xsetbv(u32 index, u64 value) -{ - u32 eax = value; - u32 edx = value >> 32; - - asm volatile(".byte 0x0f,0x01,0xd1" /* xsetbv */ - : : "a" (eax), "d" (edx), "c" (index)); + /* + * Expensive PASID MSR write will be avoided in update_pasid() because + * TIF_NEED_FPU_LOAD was set. And the PASID state won't be updated + * unless it's different from mm->pasid to reduce overhead. + */ + update_pasid(); } #endif /* _ASM_X86_FPU_INTERNAL_H */ diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h index c87364ea6446..f5a38a5f3ae1 100644 --- a/arch/x86/include/asm/fpu/types.h +++ b/arch/x86/include/asm/fpu/types.h @@ -114,7 +114,7 @@ enum xfeature { XFEATURE_Hi16_ZMM, XFEATURE_PT_UNIMPLEMENTED_SO_FAR, XFEATURE_PKRU, - XFEATURE_RSRVD_COMP_10, + XFEATURE_PASID, XFEATURE_RSRVD_COMP_11, XFEATURE_RSRVD_COMP_12, XFEATURE_RSRVD_COMP_13, @@ -134,6 +134,7 @@ enum xfeature { #define XFEATURE_MASK_Hi16_ZMM (1 << XFEATURE_Hi16_ZMM) #define XFEATURE_MASK_PT (1 << XFEATURE_PT_UNIMPLEMENTED_SO_FAR) #define XFEATURE_MASK_PKRU (1 << XFEATURE_PKRU) +#define XFEATURE_MASK_PASID (1 << XFEATURE_PASID) #define XFEATURE_MASK_LBR (1 << XFEATURE_LBR) #define XFEATURE_MASK_FPSSE (XFEATURE_MASK_FP | XFEATURE_MASK_SSE) @@ -256,6 +257,14 @@ struct arch_lbr_state { struct lbr_entry entries[]; } __packed; +/* + * State component 10 is supervisor state used for context-switching the + * PASID state. + */ +struct ia32_pasid_state { + u64 pasid; +} __packed; + struct xstate_header { u64 xfeatures; u64 xcomp_bv; diff --git a/arch/x86/include/asm/fpu/xcr.h b/arch/x86/include/asm/fpu/xcr.h new file mode 100644 index 000000000000..1c7ab8d95da5 --- /dev/null +++ b/arch/x86/include/asm/fpu/xcr.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_X86_FPU_XCR_H +#define _ASM_X86_FPU_XCR_H + +/* + * MXCSR and XCR definitions: + */ + +static inline void ldmxcsr(u32 mxcsr) +{ + asm volatile("ldmxcsr %0" :: "m" (mxcsr)); +} + +extern unsigned int mxcsr_feature_mask; + +#define XCR_XFEATURE_ENABLED_MASK 0x00000000 + +static inline u64 xgetbv(u32 index) +{ + u32 eax, edx; + + asm volatile("xgetbv" : "=a" (eax), "=d" (edx) : "c" (index)); + return eax + ((u64)edx << 32); +} + +static inline void xsetbv(u32 index, u64 value) +{ + u32 eax = value; + u32 edx = value >> 32; + + asm volatile("xsetbv" :: "a" (eax), "d" (edx), "c" (index)); +} + +#endif /* _ASM_X86_FPU_XCR_H */ diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h index 14ab815132d4..47a92232d595 100644 --- a/arch/x86/include/asm/fpu/xstate.h +++ b/arch/x86/include/asm/fpu/xstate.h @@ -35,7 +35,7 @@ XFEATURE_MASK_BNDCSR) /* All currently supported supervisor features */ -#define XFEATURE_MASK_SUPERVISOR_SUPPORTED (0) +#define XFEATURE_MASK_SUPERVISOR_SUPPORTED (XFEATURE_MASK_PASID) /* * A supervisor state component may not always contain valuable information, diff --git a/arch/x86/include/asm/frame.h b/arch/x86/include/asm/frame.h index 296b346184b2..fb42659f6e98 100644 --- a/arch/x86/include/asm/frame.h +++ b/arch/x86/include/asm/frame.h @@ -60,12 +60,26 @@ #define FRAME_END "pop %" _ASM_BP "\n" #ifdef CONFIG_X86_64 + #define ENCODE_FRAME_POINTER \ "lea 1(%rsp), %rbp\n\t" + +static inline unsigned long encode_frame_pointer(struct pt_regs *regs) +{ + return (unsigned long)regs + 1; +} + #else /* !CONFIG_X86_64 */ + #define ENCODE_FRAME_POINTER \ "movl %esp, %ebp\n\t" \ "andl $0x7fffffff, %ebp\n\t" + +static inline unsigned long encode_frame_pointer(struct pt_regs *regs) +{ + return (unsigned long)regs & 0x7fffffff; +} + #endif /* CONFIG_X86_64 */ #endif /* __ASSEMBLY__ */ @@ -83,6 +97,11 @@ #define ENCODE_FRAME_POINTER +static inline unsigned long encode_frame_pointer(struct pt_regs *regs) +{ + return 0; +} + #endif #define FRAME_BEGIN diff --git a/arch/x86/include/asm/fsgsbase.h b/arch/x86/include/asm/fsgsbase.h index d552646411a9..35cff5f2becf 100644 --- a/arch/x86/include/asm/fsgsbase.h +++ b/arch/x86/include/asm/fsgsbase.h @@ -57,7 +57,7 @@ static inline unsigned long x86_fsbase_read_cpu(void) { unsigned long fsbase; - if (static_cpu_has(X86_FEATURE_FSGSBASE)) + if (boot_cpu_has(X86_FEATURE_FSGSBASE)) fsbase = rdfsbase(); else rdmsrl(MSR_FS_BASE, fsbase); @@ -67,7 +67,7 @@ static inline unsigned long x86_fsbase_read_cpu(void) static inline void x86_fsbase_write_cpu(unsigned long fsbase) { - if (static_cpu_has(X86_FEATURE_FSGSBASE)) + if (boot_cpu_has(X86_FEATURE_FSGSBASE)) wrfsbase(fsbase); else wrmsrl(MSR_FS_BASE, fsbase); diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index 74c12437401e..a4aeeaace040 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h @@ -36,61 +36,56 @@ struct msi_desc; enum irq_alloc_type { X86_IRQ_ALLOC_TYPE_IOAPIC = 1, X86_IRQ_ALLOC_TYPE_HPET, - X86_IRQ_ALLOC_TYPE_MSI, - X86_IRQ_ALLOC_TYPE_MSIX, + X86_IRQ_ALLOC_TYPE_PCI_MSI, + X86_IRQ_ALLOC_TYPE_PCI_MSIX, X86_IRQ_ALLOC_TYPE_DMAR, X86_IRQ_ALLOC_TYPE_UV, + X86_IRQ_ALLOC_TYPE_IOAPIC_GET_PARENT, + X86_IRQ_ALLOC_TYPE_HPET_GET_PARENT, }; +struct ioapic_alloc_info { + int pin; + int node; + u32 trigger : 1; + u32 polarity : 1; + u32 valid : 1; + struct IO_APIC_route_entry *entry; +}; + +struct uv_alloc_info { + int limit; + int blade; + unsigned long offset; + char *name; + +}; + +/** + * irq_alloc_info - X86 specific interrupt allocation info + * @type: X86 specific allocation type + * @flags: Flags for allocation tweaks + * @devid: Device ID for allocations + * @hwirq: Associated hw interrupt number in the domain + * @mask: CPU mask for vector allocation + * @desc: Pointer to msi descriptor + * @data: Allocation specific data + * + * @ioapic: IOAPIC specific allocation data + * @uv: UV specific allocation data +*/ struct irq_alloc_info { enum irq_alloc_type type; u32 flags; - const struct cpumask *mask; /* CPU mask for vector allocation */ + u32 devid; + irq_hw_number_t hwirq; + const struct cpumask *mask; + struct msi_desc *desc; + void *data; + union { - int unused; -#ifdef CONFIG_HPET_TIMER - struct { - int hpet_id; - int hpet_index; - void *hpet_data; - }; -#endif -#ifdef CONFIG_PCI_MSI - struct { - struct pci_dev *msi_dev; - irq_hw_number_t msi_hwirq; - }; -#endif -#ifdef CONFIG_X86_IO_APIC - struct { - int ioapic_id; - int ioapic_pin; - int ioapic_node; - u32 ioapic_trigger : 1; - u32 ioapic_polarity : 1; - u32 ioapic_valid : 1; - struct IO_APIC_route_entry *ioapic_entry; - }; -#endif -#ifdef CONFIG_DMAR_TABLE - struct { - int dmar_id; - void *dmar_data; - }; -#endif -#ifdef CONFIG_X86_UV - struct { - int uv_limit; - int uv_blade; - unsigned long uv_offset; - char *uv_name; - }; -#endif -#if IS_ENABLED(CONFIG_VMD) - struct { - struct msi_desc *desc; - }; -#endif + struct ioapic_alloc_info ioapic; + struct uv_alloc_info uv; }; }; diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h index 7a4d2062385c..0ed20e8bba9e 100644 --- a/arch/x86/include/asm/hyperv-tlfs.h +++ b/arch/x86/include/asm/hyperv-tlfs.h @@ -28,39 +28,6 @@ #define HYPERV_CPUID_MAX 0x4000ffff /* - * Aliases for Group A features that have X64 in the name. - * On x86/x64 these are HYPERV_CPUID_FEATURES.EAX bits. - */ - -#define HV_X64_MSR_VP_RUNTIME_AVAILABLE \ - HV_MSR_VP_RUNTIME_AVAILABLE -#define HV_X64_MSR_SYNIC_AVAILABLE \ - HV_MSR_SYNIC_AVAILABLE -#define HV_X64_MSR_APIC_ACCESS_AVAILABLE \ - HV_MSR_APIC_ACCESS_AVAILABLE -#define HV_X64_MSR_HYPERCALL_AVAILABLE \ - HV_MSR_HYPERCALL_AVAILABLE -#define HV_X64_MSR_VP_INDEX_AVAILABLE \ - HV_MSR_VP_INDEX_AVAILABLE -#define HV_X64_MSR_RESET_AVAILABLE \ - HV_MSR_RESET_AVAILABLE -#define HV_X64_MSR_GUEST_IDLE_AVAILABLE \ - HV_MSR_GUEST_IDLE_AVAILABLE -#define HV_X64_ACCESS_FREQUENCY_MSRS \ - HV_ACCESS_FREQUENCY_MSRS -#define HV_X64_ACCESS_REENLIGHTENMENT \ - HV_ACCESS_REENLIGHTENMENT -#define HV_X64_ACCESS_TSC_INVARIANT \ - HV_ACCESS_TSC_INVARIANT - -/* - * Aliases for Group B features that have X64 in the name. - * On x86/x64 these are HYPERV_CPUID_FEATURES.EBX bits. - */ -#define HV_X64_POST_MESSAGES HV_POST_MESSAGES -#define HV_X64_SIGNAL_EVENTS HV_SIGNAL_EVENTS - -/* * Group D Features. The bit assignments are custom to each architecture. * On x86/x64 these are HYPERV_CPUID_FEATURES.EDX bits. */ diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h index a43366191212..b2442eb0ac2f 100644 --- a/arch/x86/include/asm/idtentry.h +++ b/arch/x86/include/asm/idtentry.h @@ -242,7 +242,7 @@ __visible noinstr void func(struct pt_regs *regs) \ instrumentation_begin(); \ irq_enter_rcu(); \ kvm_set_cpu_l1tf_flush_l1d(); \ - run_on_irqstack_cond(__##func, regs, regs); \ + run_sysvec_on_irqstack_cond(__##func, regs); \ irq_exit_rcu(); \ instrumentation_end(); \ irqentry_exit(regs, state); \ @@ -309,6 +309,19 @@ static __always_inline void __##func(struct pt_regs *regs) __visible void noist_##func(struct pt_regs *regs) /** + * DECLARE_IDTENTRY_VC - Declare functions for the VC entry point + * @vector: Vector number (ignored for C) + * @func: Function name of the entry point + * + * Maps to DECLARE_IDTENTRY_RAW_ERRORCODE, but declares also the + * safe_stack C handler. + */ +#define DECLARE_IDTENTRY_VC(vector, func) \ + DECLARE_IDTENTRY_RAW_ERRORCODE(vector, func); \ + __visible noinstr void ist_##func(struct pt_regs *regs, unsigned long error_code); \ + __visible noinstr void safe_stack_##func(struct pt_regs *regs, unsigned long error_code) + +/** * DEFINE_IDTENTRY_IST - Emit code for IST entry points * @func: Function name of the entry point * @@ -347,6 +360,35 @@ static __always_inline void __##func(struct pt_regs *regs) #define DEFINE_IDTENTRY_DF(func) \ DEFINE_IDTENTRY_RAW_ERRORCODE(func) +/** + * DEFINE_IDTENTRY_VC_SAFE_STACK - Emit code for VMM communication handler + which runs on a safe stack. + * @func: Function name of the entry point + * + * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE + */ +#define DEFINE_IDTENTRY_VC_SAFE_STACK(func) \ + DEFINE_IDTENTRY_RAW_ERRORCODE(safe_stack_##func) + +/** + * DEFINE_IDTENTRY_VC_IST - Emit code for VMM communication handler + which runs on the VC fall-back stack + * @func: Function name of the entry point + * + * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE + */ +#define DEFINE_IDTENTRY_VC_IST(func) \ + DEFINE_IDTENTRY_RAW_ERRORCODE(ist_##func) + +/** + * DEFINE_IDTENTRY_VC - Emit code for VMM communication handler + * @func: Function name of the entry point + * + * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE + */ +#define DEFINE_IDTENTRY_VC(func) \ + DEFINE_IDTENTRY_RAW_ERRORCODE(func) + #else /* CONFIG_X86_64 */ /** @@ -433,6 +475,9 @@ __visible noinstr void func(struct pt_regs *regs, \ # define DECLARE_IDTENTRY_XENCB(vector, func) \ DECLARE_IDTENTRY(vector, func) +# define DECLARE_IDTENTRY_VC(vector, func) \ + idtentry_vc vector asm_##func func + #else # define DECLARE_IDTENTRY_MCE(vector, func) \ DECLARE_IDTENTRY(vector, func) @@ -547,7 +592,7 @@ DECLARE_IDTENTRY_RAW(X86_TRAP_MC, exc_machine_check); /* NMI */ DECLARE_IDTENTRY_NMI(X86_TRAP_NMI, exc_nmi); -#if defined(CONFIG_XEN_PV) && defined(CONFIG_X86_64) +#ifdef CONFIG_XEN_PV DECLARE_IDTENTRY_RAW(X86_TRAP_NMI, xenpv_exc_nmi); #endif @@ -557,13 +602,18 @@ DECLARE_IDTENTRY_DEBUG(X86_TRAP_DB, exc_debug); #else DECLARE_IDTENTRY_RAW(X86_TRAP_DB, exc_debug); #endif -#if defined(CONFIG_XEN_PV) && defined(CONFIG_X86_64) +#ifdef CONFIG_XEN_PV DECLARE_IDTENTRY_RAW(X86_TRAP_DB, xenpv_exc_debug); #endif /* #DF */ DECLARE_IDTENTRY_DF(X86_TRAP_DF, exc_double_fault); +/* #VC */ +#ifdef CONFIG_AMD_MEM_ENCRYPT +DECLARE_IDTENTRY_VC(X86_TRAP_VC, exc_vmm_communication); +#endif + #ifdef CONFIG_XEN_PV DECLARE_IDTENTRY_XENCB(X86_TRAP_OTHER, exc_xen_hypervisor_callback); #endif @@ -591,10 +641,6 @@ DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_VECTOR, sysvec_call_function); #endif #ifdef CONFIG_X86_LOCAL_APIC -# ifdef CONFIG_X86_UV -DECLARE_IDTENTRY_SYSVEC(UV_BAU_MESSAGE, sysvec_uv_bau_message); -# endif - # ifdef CONFIG_X86_MCE_THRESHOLD DECLARE_IDTENTRY_SYSVEC(THRESHOLD_APIC_VECTOR, sysvec_threshold); # endif diff --git a/arch/x86/include/asm/insn-eval.h b/arch/x86/include/asm/insn-eval.h index 2b6ccf2c49f1..a0f839aa144d 100644 --- a/arch/x86/include/asm/insn-eval.h +++ b/arch/x86/include/asm/insn-eval.h @@ -15,9 +15,15 @@ #define INSN_CODE_SEG_OPND_SZ(params) (params & 0xf) #define INSN_CODE_SEG_PARAMS(oper_sz, addr_sz) (oper_sz | (addr_sz << 4)) +bool insn_has_rep_prefix(struct insn *insn); void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs); int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs); +int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs); unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx); int insn_get_code_seg_params(struct pt_regs *regs); +int insn_fetch_from_user(struct pt_regs *regs, + unsigned char buf[MAX_INSN_SIZE]); +bool insn_decode(struct insn *insn, struct pt_regs *regs, + unsigned char buf[MAX_INSN_SIZE], int buf_size); #endif /* _ASM_X86_INSN_EVAL_H */ diff --git a/arch/x86/include/asm/intel-mid.h b/arch/x86/include/asm/intel-mid.h index de58391bdee0..cf0e25f45422 100644 --- a/arch/x86/include/asm/intel-mid.h +++ b/arch/x86/include/asm/intel-mid.h @@ -43,7 +43,7 @@ struct devs_id { #define sfi_device(i) \ static const struct devs_id *const __intel_mid_sfi_##i##_dev __used \ - __attribute__((__section__(".x86_intel_mid_dev.init"))) = &i + __section(".x86_intel_mid_dev.init") = &i /** * struct mid_sd_board_info - template for SD device creation diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index e1aa17a468a8..d726459d08e5 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -401,7 +401,7 @@ extern bool phys_mem_access_encrypted(unsigned long phys_addr, /** * iosubmit_cmds512 - copy data to single MMIO location, in 512-bit units - * @__dst: destination, in MMIO space (must be 512-bit aligned) + * @dst: destination, in MMIO space (must be 512-bit aligned) * @src: source * @count: number of 512 bits quantities to submit * @@ -412,25 +412,14 @@ extern bool phys_mem_access_encrypted(unsigned long phys_addr, * Warning: Do not use this helper unless your driver has checked that the CPU * instruction is supported on the platform. */ -static inline void iosubmit_cmds512(void __iomem *__dst, const void *src, +static inline void iosubmit_cmds512(void __iomem *dst, const void *src, size_t count) { - /* - * Note that this isn't an "on-stack copy", just definition of "dst" - * as a pointer to 64-bytes of stuff that is going to be overwritten. - * In the MOVDIR64B case that may be needed as you can use the - * MOVDIR64B instruction to copy arbitrary memory around. This trick - * lets the compiler know how much gets clobbered. - */ - volatile struct { char _[64]; } *dst = __dst; const u8 *from = src; const u8 *end = from + count * 64; while (from < end) { - /* MOVDIR64B [rdx], rax */ - asm volatile(".byte 0x66, 0x0f, 0x38, 0xf8, 0x02" - : "=m" (dst) - : "d" (from), "a" (dst)); + movdir64b(dst, from); from += 64; } } diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h index 4bc985f1e2e4..af4a151d70b3 100644 --- a/arch/x86/include/asm/irq_remapping.h +++ b/arch/x86/include/asm/irq_remapping.h @@ -45,8 +45,6 @@ extern int irq_remap_enable_fault_handling(void); extern void panic_if_irq_remap(const char *msg); extern struct irq_domain * -irq_remapping_get_ir_irq_domain(struct irq_alloc_info *info); -extern struct irq_domain * irq_remapping_get_irq_domain(struct irq_alloc_info *info); /* Create PCI MSI/MSIx irqdomain, use @parent as the parent irqdomain. */ @@ -74,12 +72,6 @@ static inline void panic_if_irq_remap(const char *msg) } static inline struct irq_domain * -irq_remapping_get_ir_irq_domain(struct irq_alloc_info *info) -{ - return NULL; -} - -static inline struct irq_domain * irq_remapping_get_irq_domain(struct irq_alloc_info *info) { return NULL; diff --git a/arch/x86/include/asm/irq_stack.h b/arch/x86/include/asm/irq_stack.h index 4ae66f097101..775816965c6a 100644 --- a/arch/x86/include/asm/irq_stack.h +++ b/arch/x86/include/asm/irq_stack.h @@ -12,20 +12,50 @@ static __always_inline bool irqstack_active(void) return __this_cpu_read(irq_count) != -1; } -void asm_call_on_stack(void *sp, void *func, void *arg); +void asm_call_on_stack(void *sp, void (*func)(void), void *arg); +void asm_call_sysvec_on_stack(void *sp, void (*func)(struct pt_regs *regs), + struct pt_regs *regs); +void asm_call_irq_on_stack(void *sp, void (*func)(struct irq_desc *desc), + struct irq_desc *desc); -static __always_inline void __run_on_irqstack(void *func, void *arg) +static __always_inline void __run_on_irqstack(void (*func)(void)) { void *tos = __this_cpu_read(hardirq_stack_ptr); __this_cpu_add(irq_count, 1); - asm_call_on_stack(tos - 8, func, arg); + asm_call_on_stack(tos - 8, func, NULL); + __this_cpu_sub(irq_count, 1); +} + +static __always_inline void +__run_sysvec_on_irqstack(void (*func)(struct pt_regs *regs), + struct pt_regs *regs) +{ + void *tos = __this_cpu_read(hardirq_stack_ptr); + + __this_cpu_add(irq_count, 1); + asm_call_sysvec_on_stack(tos - 8, func, regs); + __this_cpu_sub(irq_count, 1); +} + +static __always_inline void +__run_irq_on_irqstack(void (*func)(struct irq_desc *desc), + struct irq_desc *desc) +{ + void *tos = __this_cpu_read(hardirq_stack_ptr); + + __this_cpu_add(irq_count, 1); + asm_call_irq_on_stack(tos - 8, func, desc); __this_cpu_sub(irq_count, 1); } #else /* CONFIG_X86_64 */ static inline bool irqstack_active(void) { return false; } -static inline void __run_on_irqstack(void *func, void *arg) { } +static inline void __run_on_irqstack(void (*func)(void)) { } +static inline void __run_sysvec_on_irqstack(void (*func)(struct pt_regs *regs), + struct pt_regs *regs) { } +static inline void __run_irq_on_irqstack(void (*func)(struct irq_desc *desc), + struct irq_desc *desc) { } #endif /* !CONFIG_X86_64 */ static __always_inline bool irq_needs_irq_stack(struct pt_regs *regs) @@ -37,17 +67,40 @@ static __always_inline bool irq_needs_irq_stack(struct pt_regs *regs) return !user_mode(regs) && !irqstack_active(); } -static __always_inline void run_on_irqstack_cond(void *func, void *arg, + +static __always_inline void run_on_irqstack_cond(void (*func)(void), struct pt_regs *regs) { - void (*__func)(void *arg) = func; + lockdep_assert_irqs_disabled(); + + if (irq_needs_irq_stack(regs)) + __run_on_irqstack(func); + else + func(); +} + +static __always_inline void +run_sysvec_on_irqstack_cond(void (*func)(struct pt_regs *regs), + struct pt_regs *regs) +{ + lockdep_assert_irqs_disabled(); + if (irq_needs_irq_stack(regs)) + __run_sysvec_on_irqstack(func, regs); + else + func(regs); +} + +static __always_inline void +run_irq_on_irqstack_cond(void (*func)(struct irq_desc *desc), struct irq_desc *desc, + struct pt_regs *regs) +{ lockdep_assert_irqs_disabled(); if (irq_needs_irq_stack(regs)) - __run_on_irqstack(__func, arg); + __run_irq_on_irqstack(func, desc); else - __func(arg); + func(desc); } #endif diff --git a/arch/x86/include/asm/irqdomain.h b/arch/x86/include/asm/irqdomain.h index c066ffae222b..cd684d45cb5f 100644 --- a/arch/x86/include/asm/irqdomain.h +++ b/arch/x86/include/asm/irqdomain.h @@ -51,9 +51,13 @@ extern int mp_irqdomain_ioapic_idx(struct irq_domain *domain); #endif /* CONFIG_X86_IO_APIC */ #ifdef CONFIG_PCI_MSI -extern void arch_init_msi_domain(struct irq_domain *domain); +void x86_create_pci_msi_domain(void); +struct irq_domain *native_create_pci_msi_domain(void); +extern struct irq_domain *x86_pci_msi_default_domain; #else -static inline void arch_init_msi_domain(struct irq_domain *domain) { } +static inline void x86_create_pci_msi_domain(void) { } +#define native_create_pci_msi_domain NULL +#define x86_pci_msi_default_domain NULL #endif #endif diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h index 02a0cf547d7b..2dfc8d380dab 100644 --- a/arch/x86/include/asm/irqflags.h +++ b/arch/x86/include/asm/irqflags.h @@ -9,7 +9,7 @@ #include <asm/nospec-branch.h> /* Provide __cpuidle; we can't safely include <linux/cpu.h> */ -#define __cpuidle __attribute__((__section__(".cpuidle.text"))) +#define __cpuidle __section(".cpuidle.text") /* * Interrupt control: diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h index 143bc9abe99c..991a7ad540c7 100644 --- a/arch/x86/include/asm/kprobes.h +++ b/arch/x86/include/asm/kprobes.h @@ -106,5 +106,9 @@ extern int kprobe_exceptions_notify(struct notifier_block *self, extern int kprobe_int3_handler(struct pt_regs *regs); extern int kprobe_debug_handler(struct pt_regs *regs); +#else + +static inline int kprobe_debug_handler(struct pt_regs *regs) { return 0; } + #endif /* CONFIG_KPROBES */ #endif /* _ASM_X86_KPROBES_H */ diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 5303dbc5c9bc..d44858b69353 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -80,13 +80,14 @@ #define KVM_REQ_HV_EXIT KVM_ARCH_REQ(21) #define KVM_REQ_HV_STIMER KVM_ARCH_REQ(22) #define KVM_REQ_LOAD_EOI_EXITMAP KVM_ARCH_REQ(23) -#define KVM_REQ_GET_VMCS12_PAGES KVM_ARCH_REQ(24) +#define KVM_REQ_GET_NESTED_STATE_PAGES KVM_ARCH_REQ(24) #define KVM_REQ_APICV_UPDATE \ KVM_ARCH_REQ_FLAGS(25, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) #define KVM_REQ_TLB_FLUSH_CURRENT KVM_ARCH_REQ(26) #define KVM_REQ_HV_TLB_FLUSH \ KVM_ARCH_REQ_FLAGS(27, KVM_REQUEST_NO_WAKEUP) #define KVM_REQ_APF_READY KVM_ARCH_REQ(28) +#define KVM_REQ_MSR_FILTER_CHANGED KVM_ARCH_REQ(29) #define CR0_RESERVED_BITS \ (~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \ @@ -132,7 +133,7 @@ static inline gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level) #define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT) #define KVM_MIN_FREE_MMU_PAGES 5 #define KVM_REFILL_PAGES 25 -#define KVM_MAX_CPUID_ENTRIES 80 +#define KVM_MAX_CPUID_ENTRIES 256 #define KVM_NR_FIXED_MTRR_REGION 88 #define KVM_NR_VAR_MTRR 8 @@ -636,7 +637,7 @@ struct kvm_vcpu_arch { int halt_request; /* real mode on Intel only */ int cpuid_nent; - struct kvm_cpuid_entry2 cpuid_entries[KVM_MAX_CPUID_ENTRIES]; + struct kvm_cpuid_entry2 *cpuid_entries; int maxphyaddr; int max_tdp_level; @@ -788,6 +789,21 @@ struct kvm_vcpu_arch { /* AMD MSRC001_0015 Hardware Configuration */ u64 msr_hwcr; + + /* pv related cpuid info */ + struct { + /* + * value of the eax register in the KVM_CPUID_FEATURES CPUID + * leaf. + */ + u32 features; + + /* + * indicates whether pv emulation should be disabled if features + * are not present in the guest's cpuid + */ + bool enforce; + } pv_cpuid; }; struct kvm_lpage_info { @@ -860,6 +876,13 @@ struct kvm_hv { struct kvm_hv_syndbg hv_syndbg; }; +struct msr_bitmap_range { + u32 flags; + u32 nmsrs; + u32 base; + unsigned long *bitmap; +}; + enum kvm_irqchip_mode { KVM_IRQCHIP_NONE, KVM_IRQCHIP_KERNEL, /* created with KVM_CREATE_IRQCHIP */ @@ -961,8 +984,31 @@ struct kvm_arch { bool guest_can_read_msr_platform_info; bool exception_payload_enabled; + /* Deflect RDMSR and WRMSR to user space when they trigger a #GP */ + u32 user_space_msr_mask; + + struct { + u8 count; + bool default_allow:1; + struct msr_bitmap_range ranges[16]; + } msr_filter; + struct kvm_pmu_event_filter *pmu_event_filter; struct task_struct *nx_lpage_recovery_thread; + + /* + * Whether the TDP MMU is enabled for this VM. This contains a + * snapshot of the TDP MMU module parameter from when the VM was + * created and remains unchanged for the life of the VM. If this is + * true, TDP MMU handler functions will run for various MMU + * operations. + */ + bool tdp_mmu_enabled; + + /* List of struct tdp_mmu_pages being used as roots */ + struct list_head tdp_mmu_roots; + /* List of struct tdp_mmu_pages not being used as roots */ + struct list_head tdp_mmu_pages; }; struct kvm_vm_stat { @@ -1069,7 +1115,7 @@ struct kvm_x86_ops { 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); - void (*set_efer)(struct kvm_vcpu *vcpu, u64 efer); + 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); void (*get_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); @@ -1143,7 +1189,12 @@ struct kvm_x86_ops { /* Returns actual tsc_offset set in active VMCS */ u64 (*write_l1_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset); - void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2); + /* + * Retrieve somewhat arbitrary exit information. Intended to be used + * only from within tracepoints to avoid VMREADs when tracing is off. + */ + void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2, + u32 *exit_int_info, u32 *exit_int_info_err_code); int (*check_intercept)(struct kvm_vcpu *vcpu, struct x86_instruction_info *info, @@ -1221,12 +1272,13 @@ struct kvm_x86_ops { int (*get_msr_feature)(struct kvm_msr_entry *entry); - bool (*need_emulation_on_page_fault)(struct kvm_vcpu *vcpu); + bool (*can_emulate_instruction)(struct kvm_vcpu *vcpu, void *insn, int insn_len); bool (*apic_init_signal_blocked)(struct kvm_vcpu *vcpu); int (*enable_direct_tlbflush)(struct kvm_vcpu *vcpu); void (*migrate_timers)(struct kvm_vcpu *vcpu); + void (*msr_filter_changed)(struct kvm_vcpu *vcpu); }; struct kvm_x86_nested_ops { @@ -1238,7 +1290,7 @@ struct kvm_x86_nested_ops { int (*set_state)(struct kvm_vcpu *vcpu, struct kvm_nested_state __user *user_kvm_nested_state, struct kvm_nested_state *kvm_state); - bool (*get_vmcs12_pages)(struct kvm_vcpu *vcpu); + bool (*get_nested_state_pages)(struct kvm_vcpu *vcpu); int (*write_log_dirty)(struct kvm_vcpu *vcpu, gpa_t l2_gpa); int (*enable_evmcs)(struct kvm_vcpu *vcpu, @@ -1612,8 +1664,8 @@ int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low, unsigned long ipi_bitmap_high, u32 min, unsigned long icr, int op_64_bit); -void kvm_define_shared_msr(unsigned index, u32 msr); -int kvm_set_shared_msr(unsigned index, u64 val, u64 mask); +void kvm_define_user_return_msr(unsigned index, u32 msr); +int kvm_set_user_return_msr(unsigned index, u64 val, u64 mask); u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc); u64 kvm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc); diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index cf503824529c..a0f147893a04 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -136,9 +136,24 @@ #define MCE_HANDLED_NFIT BIT_ULL(3) #define MCE_HANDLED_EDAC BIT_ULL(4) #define MCE_HANDLED_MCELOG BIT_ULL(5) + +/* + * Indicates an MCE which has happened in kernel space but from + * which the kernel can recover simply by executing fixup_exception() + * so that an error is returned to the caller of the function that + * hit the machine check. + */ #define MCE_IN_KERNEL_RECOV BIT_ULL(6) /* + * Indicates an MCE that happened in kernel space while copying data + * from user. In this case fixup_exception() gets the kernel to the + * error exit for the copy function. Machine check handler can then + * treat it like a fault taken in user mode. + */ +#define MCE_IN_KERNEL_COPYIN BIT_ULL(7) + +/* * This structure contains all data related to the MCE log. Also * carries a signature to make it easier to find from external * debugging tools. Each entry is only valid when its finished flag @@ -174,6 +189,15 @@ extern void mce_unregister_decode_chain(struct notifier_block *nb); extern int mce_p5_enabled; +#ifdef CONFIG_ARCH_HAS_COPY_MC +extern void enable_copy_mc_fragile(void); +unsigned long __must_check copy_mc_fragile(void *dst, const void *src, unsigned cnt); +#else +static inline void enable_copy_mc_fragile(void) +{ +} +#endif + #ifdef CONFIG_X86_MCE int mcheck_init(void); void mcheck_cpu_init(struct cpuinfo_x86 *c); @@ -200,12 +224,8 @@ void mce_setup(struct mce *m); void mce_log(struct mce *m); DECLARE_PER_CPU(struct device *, mce_device); -/* - * Maximum banks number. - * This is the limit of the current register layout on - * Intel CPUs. - */ -#define MAX_NR_BANKS 32 +/* Maximum number of MCA banks per CPU. */ +#define MAX_NR_BANKS 64 #ifdef CONFIG_X86_MCE_INTEL void mce_intel_feature_init(struct cpuinfo_x86 *c); @@ -328,7 +348,6 @@ enum smca_bank_types { struct smca_hwid { unsigned int bank_type; /* Use with smca_bank_types for easy indexing. */ u32 hwid_mcatype; /* (hwid,mcatype) tuple */ - u32 xec_bitmap; /* Bitmap of valid ExtErrorCodes; current max is 21. */ u8 count; /* Number of instances. */ }; diff --git a/arch/x86/include/asm/mcsafe_test.h b/arch/x86/include/asm/mcsafe_test.h deleted file mode 100644 index eb59804b6201..000000000000 --- a/arch/x86/include/asm/mcsafe_test.h +++ /dev/null @@ -1,75 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _MCSAFE_TEST_H_ -#define _MCSAFE_TEST_H_ - -#ifndef __ASSEMBLY__ -#ifdef CONFIG_MCSAFE_TEST -extern unsigned long mcsafe_test_src; -extern unsigned long mcsafe_test_dst; - -static inline void mcsafe_inject_src(void *addr) -{ - if (addr) - mcsafe_test_src = (unsigned long) addr; - else - mcsafe_test_src = ~0UL; -} - -static inline void mcsafe_inject_dst(void *addr) -{ - if (addr) - mcsafe_test_dst = (unsigned long) addr; - else - mcsafe_test_dst = ~0UL; -} -#else /* CONFIG_MCSAFE_TEST */ -static inline void mcsafe_inject_src(void *addr) -{ -} - -static inline void mcsafe_inject_dst(void *addr) -{ -} -#endif /* CONFIG_MCSAFE_TEST */ - -#else /* __ASSEMBLY__ */ -#include <asm/export.h> - -#ifdef CONFIG_MCSAFE_TEST -.macro MCSAFE_TEST_CTL - .pushsection .data - .align 8 - .globl mcsafe_test_src - mcsafe_test_src: - .quad 0 - EXPORT_SYMBOL_GPL(mcsafe_test_src) - .globl mcsafe_test_dst - mcsafe_test_dst: - .quad 0 - EXPORT_SYMBOL_GPL(mcsafe_test_dst) - .popsection -.endm - -.macro MCSAFE_TEST_SRC reg count target - leaq \count(\reg), %r9 - cmp mcsafe_test_src, %r9 - ja \target -.endm - -.macro MCSAFE_TEST_DST reg count target - leaq \count(\reg), %r9 - cmp mcsafe_test_dst, %r9 - ja \target -.endm -#else -.macro MCSAFE_TEST_CTL -.endm - -.macro MCSAFE_TEST_SRC reg count target -.endm - -.macro MCSAFE_TEST_DST reg count target -.endm -#endif /* CONFIG_MCSAFE_TEST */ -#endif /* __ASSEMBLY__ */ -#endif /* _MCSAFE_TEST_H_ */ diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h index 5049f6c22683..2f62bbdd9d12 100644 --- a/arch/x86/include/asm/mem_encrypt.h +++ b/arch/x86/include/asm/mem_encrypt.h @@ -19,6 +19,7 @@ #ifdef CONFIG_AMD_MEM_ENCRYPT extern u64 sme_me_mask; +extern u64 sev_status; extern bool sev_enabled; void sme_encrypt_execute(unsigned long encrypted_kernel_vaddr, @@ -48,10 +49,12 @@ void __init mem_encrypt_free_decrypted_mem(void); /* Architecture __weak replacement functions */ void __init mem_encrypt_init(void); +void __init sev_es_init_vc_handling(void); bool sme_active(void); bool sev_active(void); +bool sev_es_active(void); -#define __bss_decrypted __attribute__((__section__(".bss..decrypted"))) +#define __bss_decrypted __section(".bss..decrypted") #else /* !CONFIG_AMD_MEM_ENCRYPT */ @@ -70,8 +73,10 @@ static inline void __init sme_early_init(void) { } static inline void __init sme_encrypt_kernel(struct boot_params *bp) { } static inline void __init sme_enable(struct boot_params *bp) { } +static inline void sev_es_init_vc_handling(void) { } static inline bool sme_active(void) { return false; } static inline bool sev_active(void) { return false; } +static inline bool sev_es_active(void) { return false; } static inline int __init early_set_memory_decrypted(unsigned long vaddr, unsigned long size) { return 0; } diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h index 606cbaebd336..e90ac7e9ae2c 100644 --- a/arch/x86/include/asm/mpspec.h +++ b/arch/x86/include/asm/mpspec.h @@ -67,21 +67,11 @@ static inline void find_smp_config(void) #ifdef CONFIG_X86_MPPARSE extern void e820__memblock_alloc_reserved_mpc_new(void); extern int enable_update_mptable; -extern int default_mpc_apic_id(struct mpc_cpu *m); -extern void default_smp_read_mpc_oem(struct mpc_table *mpc); -# ifdef CONFIG_X86_IO_APIC -extern void default_mpc_oem_bus_info(struct mpc_bus *m, char *str); -# else -# define default_mpc_oem_bus_info NULL -# endif extern void default_find_smp_config(void); extern void default_get_smp_config(unsigned int early); #else static inline void e820__memblock_alloc_reserved_mpc_new(void) { } #define enable_update_mptable 0 -#define default_mpc_apic_id NULL -#define default_smp_read_mpc_oem NULL -#define default_mpc_oem_bus_info NULL #define default_find_smp_config x86_init_noop #define default_get_smp_config x86_init_uint_noop #endif diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 4f77b8f22e54..ffc289992d1b 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -54,6 +54,7 @@ typedef int (*hyperv_fill_flush_list_func)( #define hv_enable_vdso_clocksource() \ vclocks_set_used(VDSO_CLOCKMODE_HVCLOCK); #define hv_get_raw_timer() rdtsc_ordered() +#define hv_get_vector() HYPERVISOR_CALLBACK_VECTOR /* * Reference to pv_ops must be inline so objtool diff --git a/arch/x86/include/asm/msi.h b/arch/x86/include/asm/msi.h index 25ddd0916bb2..cd30013d15d3 100644 --- a/arch/x86/include/asm/msi.h +++ b/arch/x86/include/asm/msi.h @@ -9,6 +9,4 @@ typedef struct irq_alloc_info msi_alloc_info_t; int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec, msi_alloc_info_t *arg); -void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc); - #endif /* _ASM_X86_MSI_H */ diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 2859ee4f39a8..972a34d93505 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -257,6 +257,9 @@ #define MSR_IA32_LASTINTFROMIP 0x000001dd #define MSR_IA32_LASTINTTOIP 0x000001de +#define MSR_IA32_PASID 0x00000d93 +#define MSR_IA32_PASID_VALID BIT_ULL(31) + /* DEBUGCTLMSR bits (others vary by model): */ #define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */ #define DEBUGCTLMSR_BTF_SHIFT 1 @@ -464,11 +467,15 @@ #define MSR_AMD64_IBSOP_REG_MASK ((1UL<<MSR_AMD64_IBSOP_REG_COUNT)-1) #define MSR_AMD64_IBSCTL 0xc001103a #define MSR_AMD64_IBSBRTARGET 0xc001103b +#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_SEV_ES_GHCB 0xc0010130 #define MSR_AMD64_SEV 0xc0010131 #define MSR_AMD64_SEV_ENABLED_BIT 0 +#define MSR_AMD64_SEV_ES_ENABLED_BIT 1 #define MSR_AMD64_SEV_ENABLED BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT) +#define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT) #define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f @@ -857,11 +864,14 @@ #define MSR_CORE_PERF_FIXED_CTR0 0x00000309 #define MSR_CORE_PERF_FIXED_CTR1 0x0000030a #define MSR_CORE_PERF_FIXED_CTR2 0x0000030b +#define MSR_CORE_PERF_FIXED_CTR3 0x0000030c #define MSR_CORE_PERF_FIXED_CTR_CTRL 0x0000038d #define MSR_CORE_PERF_GLOBAL_STATUS 0x0000038e #define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f #define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390 +#define MSR_PERF_METRICS 0x00000329 + /* PERF_GLOBAL_OVF_CTL bits */ #define MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT 55 #define MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI (1ULL << MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT) diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 86f20d520a07..0b4920a7238e 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -60,22 +60,20 @@ struct saved_msrs { #define EAX_EDX_RET(val, low, high) "=A" (val) #endif -#ifdef CONFIG_TRACEPOINTS /* * Be very careful with includes. This header is prone to include loops. */ #include <asm/atomic.h> #include <linux/tracepoint-defs.h> -extern struct tracepoint __tracepoint_read_msr; -extern struct tracepoint __tracepoint_write_msr; -extern struct tracepoint __tracepoint_rdpmc; -#define msr_tracepoint_active(t) static_key_false(&(t).key) +#ifdef CONFIG_TRACEPOINTS +DECLARE_TRACEPOINT(read_msr); +DECLARE_TRACEPOINT(write_msr); +DECLARE_TRACEPOINT(rdpmc); extern void do_trace_write_msr(unsigned int msr, u64 val, int failed); extern void do_trace_read_msr(unsigned int msr, u64 val, int failed); extern void do_trace_rdpmc(unsigned int msr, u64 val, int failed); #else -#define msr_tracepoint_active(t) false static inline void do_trace_write_msr(unsigned int msr, u64 val, int failed) {} static inline void do_trace_read_msr(unsigned int msr, u64 val, int failed) {} static inline void do_trace_rdpmc(unsigned int msr, u64 val, int failed) {} @@ -128,7 +126,7 @@ static inline unsigned long long native_read_msr(unsigned int msr) val = __rdmsr(msr); - if (msr_tracepoint_active(__tracepoint_read_msr)) + if (tracepoint_enabled(read_msr)) do_trace_read_msr(msr, val, 0); return val; @@ -150,7 +148,7 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr, _ASM_EXTABLE(2b, 3b) : [err] "=r" (*err), EAX_EDX_RET(val, low, high) : "c" (msr), [fault] "i" (-EIO)); - if (msr_tracepoint_active(__tracepoint_read_msr)) + if (tracepoint_enabled(read_msr)) do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), *err); return EAX_EDX_VAL(val, low, high); } @@ -161,7 +159,7 @@ native_write_msr(unsigned int msr, u32 low, u32 high) { __wrmsr(msr, low, high); - if (msr_tracepoint_active(__tracepoint_write_msr)) + if (tracepoint_enabled(write_msr)) do_trace_write_msr(msr, ((u64)high << 32 | low), 0); } @@ -181,7 +179,7 @@ native_write_msr_safe(unsigned int msr, u32 low, u32 high) : "c" (msr), "0" (low), "d" (high), [fault] "i" (-EIO) : "memory"); - if (msr_tracepoint_active(__tracepoint_write_msr)) + if (tracepoint_enabled(write_msr)) do_trace_write_msr(msr, ((u64)high << 32 | low), err); return err; } @@ -248,7 +246,7 @@ static inline unsigned long long native_read_pmc(int counter) DECLARE_ARGS(val, low, high); asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter)); - if (msr_tracepoint_active(__tracepoint_rdpmc)) + if (tracepoint_enabled(rdpmc)) do_trace_rdpmc(counter, EAX_EDX_VAL(val, low, high), 0); return EAX_EDX_VAL(val, low, high); } diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index e7752b4038ff..cb9ad6b73973 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -4,7 +4,7 @@ #define _ASM_X86_NOSPEC_BRANCH_H_ #include <linux/static_key.h> -#include <linux/frame.h> +#include <linux/objtool.h> #include <asm/alternative.h> #include <asm/alternative-asm.h> @@ -314,19 +314,19 @@ static inline void mds_idle_clear_cpu_buffers(void) * lfence * jmp spec_trap * do_rop: - * mov %rax,(%rsp) for x86_64 + * mov %rcx,(%rsp) for x86_64 * mov %edx,(%esp) for x86_32 * retq * * Without retpolines configured: * - * jmp *%rax for x86_64 + * jmp *%rcx for x86_64 * jmp *%edx for x86_32 */ #ifdef CONFIG_RETPOLINE # ifdef CONFIG_X86_64 -# define RETPOLINE_RAX_BPF_JIT_SIZE 17 -# define RETPOLINE_RAX_BPF_JIT() \ +# define RETPOLINE_RCX_BPF_JIT_SIZE 17 +# define RETPOLINE_RCX_BPF_JIT() \ do { \ EMIT1_off32(0xE8, 7); /* callq do_rop */ \ /* spec_trap: */ \ @@ -334,7 +334,7 @@ do { \ EMIT3(0x0F, 0xAE, 0xE8); /* lfence */ \ EMIT2(0xEB, 0xF9); /* jmp spec_trap */ \ /* do_rop: */ \ - EMIT4(0x48, 0x89, 0x04, 0x24); /* mov %rax,(%rsp) */ \ + EMIT4(0x48, 0x89, 0x0C, 0x24); /* mov %rcx,(%rsp) */ \ EMIT1(0xC3); /* retq */ \ } while (0) # else /* !CONFIG_X86_64 */ @@ -352,9 +352,9 @@ do { \ # endif #else /* !CONFIG_RETPOLINE */ # ifdef CONFIG_X86_64 -# define RETPOLINE_RAX_BPF_JIT_SIZE 2 -# define RETPOLINE_RAX_BPF_JIT() \ - EMIT2(0xFF, 0xE0); /* jmp *%rax */ +# define RETPOLINE_RCX_BPF_JIT_SIZE 2 +# define RETPOLINE_RCX_BPF_JIT() \ + EMIT2(0xFF, 0xE1); /* jmp *%rcx */ # else /* !CONFIG_X86_64 */ # define RETPOLINE_EDX_BPF_JIT() \ EMIT2(0xFF, 0xE2) /* jmp *%edx */ diff --git a/arch/x86/include/asm/numa.h b/arch/x86/include/asm/numa.h index bbfde3d2662f..e3bae2b60a0d 100644 --- a/arch/x86/include/asm/numa.h +++ b/arch/x86/include/asm/numa.h @@ -3,6 +3,7 @@ #define _ASM_X86_NUMA_H #include <linux/nodemask.h> +#include <linux/errno.h> #include <asm/topology.h> #include <asm/apicdef.h> @@ -62,12 +63,14 @@ extern void numa_clear_node(int cpu); extern void __init init_cpu_to_node(void); extern void numa_add_cpu(int cpu); extern void numa_remove_cpu(int cpu); +extern void init_gi_nodes(void); #else /* CONFIG_NUMA */ static inline void numa_set_node(int cpu, int node) { } static inline void numa_clear_node(int cpu) { } static inline void init_cpu_to_node(void) { } static inline void numa_add_cpu(int cpu) { } static inline void numa_remove_cpu(int cpu) { } +static inline void init_gi_nodes(void) { } #endif /* CONFIG_NUMA */ #ifdef CONFIG_DEBUG_PER_CPU_MAPS @@ -77,7 +80,12 @@ void debug_cpumask_set_cpu(int cpu, int node, bool enable); #ifdef CONFIG_NUMA_EMU #define FAKE_NODE_MIN_SIZE ((u64)32 << 20) #define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1UL)) -void numa_emu_cmdline(char *); +int numa_emu_cmdline(char *str); +#else /* CONFIG_NUMA_EMU */ +static inline int numa_emu_cmdline(char *str) +{ + return -EINVAL; +} #endif /* CONFIG_NUMA_EMU */ #endif /* _ASM_X86_NUMA_H */ diff --git a/arch/x86/include/asm/orc_types.h b/arch/x86/include/asm/orc_types.h index d25534940bde..fdbffec4cfde 100644 --- a/arch/x86/include/asm/orc_types.h +++ b/arch/x86/include/asm/orc_types.h @@ -39,27 +39,6 @@ #define ORC_REG_SP_INDIRECT 9 #define ORC_REG_MAX 15 -/* - * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the - * caller's SP right before it made the call). Used for all callable - * functions, i.e. all C code and all callable asm functions. - * - * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points - * to a fully populated pt_regs from a syscall, interrupt, or exception. - * - * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset - * points to the iret return frame. - * - * The UNWIND_HINT macros are used only for the unwind_hint struct. They - * aren't used in struct orc_entry due to size and complexity constraints. - * Objtool converts them to real types when it converts the hints to orc - * entries. - */ -#define ORC_TYPE_CALL 0 -#define ORC_TYPE_REGS 1 -#define ORC_TYPE_REGS_IRET 2 -#define UNWIND_HINT_TYPE_RET_OFFSET 3 - #ifndef __ASSEMBLY__ /* * This struct is more or less a vastly simplified version of the DWARF Call @@ -78,19 +57,6 @@ struct orc_entry { unsigned end:1; } __packed; -/* - * This struct is used by asm and inline asm code to manually annotate the - * location of registers on the stack for the ORC unwinder. - * - * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*. - */ -struct unwind_hint { - u32 ip; - s16 sp_offset; - u8 sp_reg; - u8 type; - u8 end; -}; #endif /* __ASSEMBLY__ */ #endif /* _ORC_TYPES_H */ diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h index 565ad755c785..f462895a33e4 100644 --- a/arch/x86/include/asm/page_32_types.h +++ b/arch/x86/include/asm/page_32_types.h @@ -42,6 +42,17 @@ #endif /* CONFIG_X86_PAE */ /* + * User space process size: 3GB (default). + */ +#define IA32_PAGE_OFFSET __PAGE_OFFSET +#define TASK_SIZE __PAGE_OFFSET +#define TASK_SIZE_LOW TASK_SIZE +#define TASK_SIZE_MAX TASK_SIZE +#define DEFAULT_MAP_WINDOW TASK_SIZE +#define STACK_TOP TASK_SIZE +#define STACK_TOP_MAX STACK_TOP + +/* * Kernel image size is limited to 512 MB (see in arch/x86/kernel/head_32.S) */ #define KERNEL_IMAGE_SIZE (512 * 1024 * 1024) diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h index 288b065955b7..3f49dac03617 100644 --- a/arch/x86/include/asm/page_64_types.h +++ b/arch/x86/include/asm/page_64_types.h @@ -28,6 +28,7 @@ #define IST_INDEX_NMI 1 #define IST_INDEX_DB 2 #define IST_INDEX_MCE 3 +#define IST_INDEX_VC 4 /* * Set __PAGE_OFFSET to the most negative possible address + @@ -59,6 +60,44 @@ #endif /* + * User space process size. This is the first address outside the user range. + * There are a few constraints that determine this: + * + * On Intel CPUs, if a SYSCALL instruction is at the highest canonical + * address, then that syscall will enter the kernel with a + * non-canonical return address, and SYSRET will explode dangerously. + * We avoid this particular problem by preventing anything executable + * from being mapped at the maximum canonical address. + * + * On AMD CPUs in the Ryzen family, there's a nasty bug in which the + * CPUs malfunction if they execute code from the highest canonical page. + * They'll speculate right off the end of the canonical space, and + * bad things happen. This is worked around in the same way as the + * Intel problem. + * + * With page table isolation enabled, we map the LDT in ... [stay tuned] + */ +#define TASK_SIZE_MAX ((_AC(1,UL) << __VIRTUAL_MASK_SHIFT) - PAGE_SIZE) + +#define DEFAULT_MAP_WINDOW ((1UL << 47) - PAGE_SIZE) + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \ + 0xc0000000 : 0xFFFFe000) + +#define TASK_SIZE_LOW (test_thread_flag(TIF_ADDR32) ? \ + IA32_PAGE_OFFSET : DEFAULT_MAP_WINDOW) +#define TASK_SIZE (test_thread_flag(TIF_ADDR32) ? \ + IA32_PAGE_OFFSET : TASK_SIZE_MAX) +#define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_ADDR32)) ? \ + IA32_PAGE_OFFSET : TASK_SIZE_MAX) + +#define STACK_TOP TASK_SIZE_LOW +#define STACK_TOP_MAX TASK_SIZE_MAX + +/* * Maximum kernel image size is limited to 1 GiB, due to the fixmap living * in the next 1 GiB (see level2_kernel_pgt in arch/x86/kernel/head_64.S). * diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 3d2afecde50c..d25cc6830e89 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -160,8 +160,6 @@ static inline void wbinvd(void) PVOP_VCALL0(cpu.wbinvd); } -#define get_kernel_rpl() (pv_info.kernel_rpl) - static inline u64 paravirt_read_msr(unsigned msr) { return PVOP_CALL1(u64, cpu.read_msr, msr); @@ -277,12 +275,10 @@ static inline void load_TLS(struct thread_struct *t, unsigned cpu) PVOP_VCALL2(cpu.load_tls, t, cpu); } -#ifdef CONFIG_X86_64 static inline void load_gs_index(unsigned int gs) { PVOP_VCALL1(cpu.load_gs_index, gs); } -#endif static inline void write_ldt_entry(struct desc_struct *dt, int entry, const void *desc) @@ -375,52 +371,22 @@ static inline void paravirt_release_p4d(unsigned long pfn) static inline pte_t __pte(pteval_t val) { - pteval_t ret; - - if (sizeof(pteval_t) > sizeof(long)) - ret = PVOP_CALLEE2(pteval_t, mmu.make_pte, val, (u64)val >> 32); - else - ret = PVOP_CALLEE1(pteval_t, mmu.make_pte, val); - - return (pte_t) { .pte = ret }; + return (pte_t) { PVOP_CALLEE1(pteval_t, mmu.make_pte, val) }; } static inline pteval_t pte_val(pte_t pte) { - pteval_t ret; - - if (sizeof(pteval_t) > sizeof(long)) - ret = PVOP_CALLEE2(pteval_t, mmu.pte_val, - pte.pte, (u64)pte.pte >> 32); - else - ret = PVOP_CALLEE1(pteval_t, mmu.pte_val, pte.pte); - - return ret; + return PVOP_CALLEE1(pteval_t, mmu.pte_val, pte.pte); } static inline pgd_t __pgd(pgdval_t val) { - pgdval_t ret; - - if (sizeof(pgdval_t) > sizeof(long)) - ret = PVOP_CALLEE2(pgdval_t, mmu.make_pgd, val, (u64)val >> 32); - else - ret = PVOP_CALLEE1(pgdval_t, mmu.make_pgd, val); - - return (pgd_t) { ret }; + return (pgd_t) { PVOP_CALLEE1(pgdval_t, mmu.make_pgd, val) }; } static inline pgdval_t pgd_val(pgd_t pgd) { - pgdval_t ret; - - if (sizeof(pgdval_t) > sizeof(long)) - ret = PVOP_CALLEE2(pgdval_t, mmu.pgd_val, - pgd.pgd, (u64)pgd.pgd >> 32); - else - ret = PVOP_CALLEE1(pgdval_t, mmu.pgd_val, pgd.pgd); - - return ret; + return PVOP_CALLEE1(pgdval_t, mmu.pgd_val, pgd.pgd); } #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION @@ -438,78 +404,34 @@ static inline void ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned pte_t *ptep, pte_t old_pte, pte_t pte) { - if (sizeof(pteval_t) > sizeof(long)) - /* 5 arg words */ - pv_ops.mmu.ptep_modify_prot_commit(vma, addr, ptep, pte); - else - PVOP_VCALL4(mmu.ptep_modify_prot_commit, - vma, addr, ptep, pte.pte); + PVOP_VCALL4(mmu.ptep_modify_prot_commit, vma, addr, ptep, pte.pte); } static inline void set_pte(pte_t *ptep, pte_t pte) { - if (sizeof(pteval_t) > sizeof(long)) - PVOP_VCALL3(mmu.set_pte, ptep, pte.pte, (u64)pte.pte >> 32); - else - PVOP_VCALL2(mmu.set_pte, ptep, pte.pte); -} - -static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pte) -{ - if (sizeof(pteval_t) > sizeof(long)) - /* 5 arg words */ - pv_ops.mmu.set_pte_at(mm, addr, ptep, pte); - else - PVOP_VCALL4(mmu.set_pte_at, mm, addr, ptep, pte.pte); + PVOP_VCALL2(mmu.set_pte, ptep, pte.pte); } static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) { - pmdval_t val = native_pmd_val(pmd); - - if (sizeof(pmdval_t) > sizeof(long)) - PVOP_VCALL3(mmu.set_pmd, pmdp, val, (u64)val >> 32); - else - PVOP_VCALL2(mmu.set_pmd, pmdp, val); + PVOP_VCALL2(mmu.set_pmd, pmdp, native_pmd_val(pmd)); } -#if CONFIG_PGTABLE_LEVELS >= 3 static inline pmd_t __pmd(pmdval_t val) { - pmdval_t ret; - - if (sizeof(pmdval_t) > sizeof(long)) - ret = PVOP_CALLEE2(pmdval_t, mmu.make_pmd, val, (u64)val >> 32); - else - ret = PVOP_CALLEE1(pmdval_t, mmu.make_pmd, val); - - return (pmd_t) { ret }; + return (pmd_t) { PVOP_CALLEE1(pmdval_t, mmu.make_pmd, val) }; } static inline pmdval_t pmd_val(pmd_t pmd) { - pmdval_t ret; - - if (sizeof(pmdval_t) > sizeof(long)) - ret = PVOP_CALLEE2(pmdval_t, mmu.pmd_val, - pmd.pmd, (u64)pmd.pmd >> 32); - else - ret = PVOP_CALLEE1(pmdval_t, mmu.pmd_val, pmd.pmd); - - return ret; + return PVOP_CALLEE1(pmdval_t, mmu.pmd_val, pmd.pmd); } static inline void set_pud(pud_t *pudp, pud_t pud) { - pudval_t val = native_pud_val(pud); - - if (sizeof(pudval_t) > sizeof(long)) - PVOP_VCALL3(mmu.set_pud, pudp, val, (u64)val >> 32); - else - PVOP_VCALL2(mmu.set_pud, pudp, val); + PVOP_VCALL2(mmu.set_pud, pudp, native_pud_val(pud)); } -#if CONFIG_PGTABLE_LEVELS >= 4 + static inline pud_t __pud(pudval_t val) { pudval_t ret; @@ -526,7 +448,7 @@ static inline pudval_t pud_val(pud_t pud) static inline void pud_clear(pud_t *pudp) { - set_pud(pudp, __pud(0)); + set_pud(pudp, native_make_pud(0)); } static inline void set_p4d(p4d_t *p4dp, p4d_t p4d) @@ -563,40 +485,17 @@ static inline void __set_pgd(pgd_t *pgdp, pgd_t pgd) } while (0) #define pgd_clear(pgdp) do { \ - if (pgtable_l5_enabled()) \ - set_pgd(pgdp, __pgd(0)); \ + if (pgtable_l5_enabled()) \ + set_pgd(pgdp, native_make_pgd(0)); \ } while (0) #endif /* CONFIG_PGTABLE_LEVELS == 5 */ static inline void p4d_clear(p4d_t *p4dp) { - set_p4d(p4dp, __p4d(0)); + set_p4d(p4dp, native_make_p4d(0)); } -#endif /* CONFIG_PGTABLE_LEVELS == 4 */ - -#endif /* CONFIG_PGTABLE_LEVELS >= 3 */ - -#ifdef CONFIG_X86_PAE -/* Special-case pte-setting operations for PAE, which can't update a - 64-bit pte atomically */ -static inline void set_pte_atomic(pte_t *ptep, pte_t pte) -{ - PVOP_VCALL3(mmu.set_pte_atomic, ptep, pte.pte, pte.pte >> 32); -} - -static inline void pte_clear(struct mm_struct *mm, unsigned long addr, - pte_t *ptep) -{ - PVOP_VCALL3(mmu.pte_clear, mm, addr, ptep); -} - -static inline void pmd_clear(pmd_t *pmdp) -{ - PVOP_VCALL1(mmu.pmd_clear, pmdp); -} -#else /* !CONFIG_X86_PAE */ static inline void set_pte_atomic(pte_t *ptep, pte_t pte) { set_pte(ptep, pte); @@ -605,14 +504,13 @@ static inline void set_pte_atomic(pte_t *ptep, pte_t pte) static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - set_pte_at(mm, addr, ptep, __pte(0)); + set_pte(ptep, native_make_pte(0)); } static inline void pmd_clear(pmd_t *pmdp) { - set_pmd(pmdp, __pmd(0)); + set_pmd(pmdp, native_make_pmd(0)); } -#endif /* CONFIG_X86_PAE */ #define __HAVE_ARCH_START_CONTEXT_SWITCH static inline void arch_start_context_switch(struct task_struct *prev) @@ -682,16 +580,9 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu); #endif /* SMP && PARAVIRT_SPINLOCKS */ #ifdef CONFIG_X86_32 -#define PV_SAVE_REGS "pushl %ecx; pushl %edx;" -#define PV_RESTORE_REGS "popl %edx; popl %ecx;" - /* save and restore all caller-save registers, except return value */ #define PV_SAVE_ALL_CALLER_REGS "pushl %ecx;" #define PV_RESTORE_ALL_CALLER_REGS "popl %ecx;" - -#define PV_FLAGS_ARG "0" -#define PV_EXTRA_CLOBBERS -#define PV_VEXTRA_CLOBBERS #else /* save and restore all caller-save registers, except return value */ #define PV_SAVE_ALL_CALLER_REGS \ @@ -712,14 +603,6 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu); "pop %rsi;" \ "pop %rdx;" \ "pop %rcx;" - -/* We save some registers, but all of them, that's too much. We clobber all - * caller saved registers but the argument parameter */ -#define PV_SAVE_REGS "pushq %%rdi;" -#define PV_RESTORE_REGS "popq %%rdi;" -#define PV_EXTRA_CLOBBERS EXTRA_CLOBBERS, "rcx" , "rdx", "rsi" -#define PV_VEXTRA_CLOBBERS EXTRA_CLOBBERS, "rdi", "rcx" , "rdx", "rsi" -#define PV_FLAGS_ARG "D" #endif /* diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 8dfcb2508e6d..0fad9f61c76a 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -68,13 +68,8 @@ struct paravirt_callee_save { /* general info */ struct pv_info { #ifdef CONFIG_PARAVIRT_XXL - unsigned int kernel_rpl; - int shared_kernel_pmd; - -#ifdef CONFIG_X86_64 u16 extra_user_64bit_cs; /* __USER_CS if none */ #endif -#endif const char *name; }; @@ -126,9 +121,7 @@ struct pv_cpu_ops { void (*set_ldt)(const void *desc, unsigned entries); unsigned long (*store_tr)(void); void (*load_tls)(struct thread_struct *t, unsigned int cpu); -#ifdef CONFIG_X86_64 void (*load_gs_index)(unsigned int idx); -#endif void (*write_ldt_entry)(struct desc_struct *ldt, int entrynum, const void *desc); void (*write_gdt_entry)(struct desc_struct *, @@ -249,8 +242,6 @@ struct pv_mmu_ops { /* Pagetable manipulation functions */ void (*set_pte)(pte_t *ptep, pte_t pteval); - void (*set_pte_at)(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pteval); void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval); pte_t (*ptep_modify_prot_start)(struct vm_area_struct *vma, unsigned long addr, @@ -264,21 +255,11 @@ struct pv_mmu_ops { struct paravirt_callee_save pgd_val; struct paravirt_callee_save make_pgd; -#if CONFIG_PGTABLE_LEVELS >= 3 -#ifdef CONFIG_X86_PAE - void (*set_pte_atomic)(pte_t *ptep, pte_t pteval); - void (*pte_clear)(struct mm_struct *mm, unsigned long addr, - pte_t *ptep); - void (*pmd_clear)(pmd_t *pmdp); - -#endif /* CONFIG_X86_PAE */ - void (*set_pud)(pud_t *pudp, pud_t pudval); struct paravirt_callee_save pmd_val; struct paravirt_callee_save make_pmd; -#if CONFIG_PGTABLE_LEVELS >= 4 struct paravirt_callee_save pud_val; struct paravirt_callee_save make_pud; @@ -291,10 +272,6 @@ struct pv_mmu_ops { void (*set_pgd)(pgd_t *pgdp, pgd_t pgdval); #endif /* CONFIG_PGTABLE_LEVELS >= 5 */ -#endif /* CONFIG_PGTABLE_LEVELS >= 4 */ - -#endif /* CONFIG_PGTABLE_LEVELS >= 3 */ - struct pv_lazy_ops lazy_mode; /* dom0 ops */ diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 7ccb338507e3..d2c76c8d8cfd 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -105,17 +105,6 @@ static inline void early_quirks(void) { } extern void pci_iommu_alloc(void); -#ifdef CONFIG_PCI_MSI -/* implemented in arch/x86/kernel/apic/io_apic. */ -struct msi_desc; -int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); -void native_teardown_msi_irq(unsigned int irq); -void native_restore_msi_irqs(struct pci_dev *dev); -#else -#define native_setup_msi_irqs NULL -#define native_teardown_msi_irq NULL -#endif - /* generic pci stuff */ #include <asm-generic/pci.h> diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index 73bb404f4d2a..490411dba438 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h @@ -114,9 +114,20 @@ extern const struct pci_raw_ops pci_direct_conf1; extern bool port_cf9_safe; /* arch_initcall level */ +#ifdef CONFIG_PCI_DIRECT extern int pci_direct_probe(void); extern void pci_direct_init(int type); +#else +static inline int pci_direct_probe(void) { return -1; } +static inline void pci_direct_init(int type) { } +#endif + +#ifdef CONFIG_PCI_BIOS extern void pci_pcbios_init(void); +#else +static inline void pci_pcbios_init(void) { } +#endif + extern void __init dmi_check_pciprobe(void); extern void __init dmi_check_skip_isa_align(void); diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 0c1b13720525..6960cd6d1f23 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -196,13 +196,29 @@ struct x86_pmu_capability { * Fixed-purpose performance events: */ +/* RDPMC offset for Fixed PMCs */ +#define INTEL_PMC_FIXED_RDPMC_BASE (1 << 30) +#define INTEL_PMC_FIXED_RDPMC_METRICS (1 << 29) + /* - * All 3 fixed-mode PMCs are configured via this single MSR: + * All the fixed-mode PMCs are configured via this single MSR: */ #define MSR_ARCH_PERFMON_FIXED_CTR_CTRL 0x38d /* - * The counts are available in three separate MSRs: + * There is no event-code assigned to the fixed-mode PMCs. + * + * For a fixed-mode PMC, which has an equivalent event on a general-purpose + * PMC, the event-code of the equivalent event is used for the fixed-mode PMC, + * e.g., Instr_Retired.Any and CPU_CLK_Unhalted.Core. + * + * For a fixed-mode PMC, which doesn't have an equivalent event, a + * pseudo-encoding is used, e.g., CPU_CLK_Unhalted.Ref and TOPDOWN.SLOTS. + * The pseudo event-code for a fixed-mode PMC must be 0x00. + * The pseudo umask-code is 0xX. The X equals the index of the fixed + * counter + 1, e.g., the fixed counter 2 has the pseudo-encoding 0x0300. + * + * The counts are available in separate MSRs: */ /* Instr_Retired.Any: */ @@ -213,29 +229,84 @@ struct x86_pmu_capability { #define MSR_ARCH_PERFMON_FIXED_CTR1 0x30a #define INTEL_PMC_IDX_FIXED_CPU_CYCLES (INTEL_PMC_IDX_FIXED + 1) -/* CPU_CLK_Unhalted.Ref: */ +/* CPU_CLK_Unhalted.Ref: event=0x00,umask=0x3 (pseudo-encoding) */ #define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b #define INTEL_PMC_IDX_FIXED_REF_CYCLES (INTEL_PMC_IDX_FIXED + 2) #define INTEL_PMC_MSK_FIXED_REF_CYCLES (1ULL << INTEL_PMC_IDX_FIXED_REF_CYCLES) +/* TOPDOWN.SLOTS: event=0x00,umask=0x4 (pseudo-encoding) */ +#define MSR_ARCH_PERFMON_FIXED_CTR3 0x30c +#define INTEL_PMC_IDX_FIXED_SLOTS (INTEL_PMC_IDX_FIXED + 3) +#define INTEL_PMC_MSK_FIXED_SLOTS (1ULL << INTEL_PMC_IDX_FIXED_SLOTS) + /* * We model BTS tracing as another fixed-mode PMC. * - * We choose a value in the middle of the fixed event range, since lower + * We choose the value 47 for the fixed index of BTS, since lower * values are used by actual fixed events and higher values are used * to indicate other overflow conditions in the PERF_GLOBAL_STATUS msr. */ -#define INTEL_PMC_IDX_FIXED_BTS (INTEL_PMC_IDX_FIXED + 16) +#define INTEL_PMC_IDX_FIXED_BTS (INTEL_PMC_IDX_FIXED + 15) + +/* + * The PERF_METRICS MSR is modeled as several magic fixed-mode PMCs, one for + * each TopDown metric event. + * + * Internally the TopDown metric events are mapped to the FxCtr 3 (SLOTS). + */ +#define INTEL_PMC_IDX_METRIC_BASE (INTEL_PMC_IDX_FIXED + 16) +#define INTEL_PMC_IDX_TD_RETIRING (INTEL_PMC_IDX_METRIC_BASE + 0) +#define INTEL_PMC_IDX_TD_BAD_SPEC (INTEL_PMC_IDX_METRIC_BASE + 1) +#define INTEL_PMC_IDX_TD_FE_BOUND (INTEL_PMC_IDX_METRIC_BASE + 2) +#define INTEL_PMC_IDX_TD_BE_BOUND (INTEL_PMC_IDX_METRIC_BASE + 3) +#define INTEL_PMC_IDX_METRIC_END INTEL_PMC_IDX_TD_BE_BOUND +#define INTEL_PMC_MSK_TOPDOWN ((0xfull << INTEL_PMC_IDX_METRIC_BASE) | \ + INTEL_PMC_MSK_FIXED_SLOTS) -#define GLOBAL_STATUS_COND_CHG BIT_ULL(63) -#define GLOBAL_STATUS_BUFFER_OVF BIT_ULL(62) -#define GLOBAL_STATUS_UNC_OVF BIT_ULL(61) -#define GLOBAL_STATUS_ASIF BIT_ULL(60) -#define GLOBAL_STATUS_COUNTERS_FROZEN BIT_ULL(59) -#define GLOBAL_STATUS_LBRS_FROZEN_BIT 58 -#define GLOBAL_STATUS_LBRS_FROZEN BIT_ULL(GLOBAL_STATUS_LBRS_FROZEN_BIT) -#define GLOBAL_STATUS_TRACE_TOPAPMI BIT_ULL(55) +/* + * There is no event-code assigned to the TopDown events. + * + * For the slots event, use the pseudo code of the fixed counter 3. + * + * For the metric events, the pseudo event-code is 0x00. + * The pseudo umask-code starts from the middle of the pseudo event + * space, 0x80. + */ +#define INTEL_TD_SLOTS 0x0400 /* TOPDOWN.SLOTS */ +/* Level 1 metrics */ +#define INTEL_TD_METRIC_RETIRING 0x8000 /* Retiring metric */ +#define INTEL_TD_METRIC_BAD_SPEC 0x8100 /* Bad speculation metric */ +#define INTEL_TD_METRIC_FE_BOUND 0x8200 /* FE bound metric */ +#define INTEL_TD_METRIC_BE_BOUND 0x8300 /* BE bound metric */ +#define INTEL_TD_METRIC_MAX INTEL_TD_METRIC_BE_BOUND +#define INTEL_TD_METRIC_NUM 4 + +static inline bool is_metric_idx(int idx) +{ + return (unsigned)(idx - INTEL_PMC_IDX_METRIC_BASE) < INTEL_TD_METRIC_NUM; +} + +static inline bool is_topdown_idx(int idx) +{ + return is_metric_idx(idx) || idx == INTEL_PMC_IDX_FIXED_SLOTS; +} +#define INTEL_PMC_OTHER_TOPDOWN_BITS(bit) \ + (~(0x1ull << bit) & INTEL_PMC_MSK_TOPDOWN) + +#define GLOBAL_STATUS_COND_CHG BIT_ULL(63) +#define GLOBAL_STATUS_BUFFER_OVF_BIT 62 +#define GLOBAL_STATUS_BUFFER_OVF BIT_ULL(GLOBAL_STATUS_BUFFER_OVF_BIT) +#define GLOBAL_STATUS_UNC_OVF BIT_ULL(61) +#define GLOBAL_STATUS_ASIF BIT_ULL(60) +#define GLOBAL_STATUS_COUNTERS_FROZEN BIT_ULL(59) +#define GLOBAL_STATUS_LBRS_FROZEN_BIT 58 +#define GLOBAL_STATUS_LBRS_FROZEN BIT_ULL(GLOBAL_STATUS_LBRS_FROZEN_BIT) +#define GLOBAL_STATUS_TRACE_TOPAPMI_BIT 55 +#define GLOBAL_STATUS_TRACE_TOPAPMI BIT_ULL(GLOBAL_STATUS_TRACE_TOPAPMI_BIT) +#define GLOBAL_STATUS_PERF_METRICS_OVF_BIT 48 + +#define GLOBAL_CTRL_EN_PERF_METRICS 48 /* * We model guest LBR event tracing as another fixed-mode PMC like BTS. * @@ -334,6 +405,7 @@ struct pebs_xmm { #define IBS_OP_ENABLE (1ULL<<17) #define IBS_OP_MAX_CNT 0x0000FFFFULL #define IBS_OP_MAX_CNT_EXT 0x007FFFFFULL /* not a register bit mask */ +#define IBS_OP_MAX_CNT_EXT_MASK (0x7FULL<<20) /* separate upper 7 bits */ #define IBS_RIP_INVALID (1ULL<<38) #ifdef CONFIG_X86_LOCAL_APIC diff --git a/arch/x86/include/asm/pgtable-3level_types.h b/arch/x86/include/asm/pgtable-3level_types.h index 80fbb4a9ed87..56baf43befb4 100644 --- a/arch/x86/include/asm/pgtable-3level_types.h +++ b/arch/x86/include/asm/pgtable-3level_types.h @@ -20,12 +20,7 @@ typedef union { } pte_t; #endif /* !__ASSEMBLY__ */ -#ifdef CONFIG_PARAVIRT_XXL -#define SHARED_KERNEL_PMD ((!static_cpu_has(X86_FEATURE_PTI) && \ - (pv_info.shared_kernel_pmd))) -#else #define SHARED_KERNEL_PMD (!static_cpu_has(X86_FEATURE_PTI)) -#endif #define ARCH_PAGE_TABLE_SYNC_MASK (SHARED_KERNEL_PMD ? 0 : PGTBL_PMD_MODIFIED) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index b836138ce852..a02c67291cfc 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -28,7 +28,7 @@ #include <asm-generic/pgtable_uffd.h> extern pgd_t early_top_pgt[PTRS_PER_PGD]; -int __init __early_make_pgtable(unsigned long address, pmdval_t pmd); +bool __init __early_make_pgtable(unsigned long address, pmdval_t pmd); void ptdump_walk_pgd_level(struct seq_file *m, struct mm_struct *mm); void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm, @@ -63,7 +63,6 @@ extern pmdval_t early_pmd_flags; #include <asm/paravirt.h> #else /* !CONFIG_PARAVIRT_XXL */ #define set_pte(ptep, pte) native_set_pte(ptep, pte) -#define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) #define set_pte_atomic(ptep, pte) \ native_set_pte_atomic(ptep, pte) @@ -1033,10 +1032,10 @@ static inline pud_t native_local_pudp_get_and_clear(pud_t *pudp) return res; } -static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep , pte_t pte) +static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) { - native_set_pte(ptep, pte); + set_pte(ptep, pte); } static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h index 8f63efb2a2cc..52e5f5f2240d 100644 --- a/arch/x86/include/asm/pgtable_64_types.h +++ b/arch/x86/include/asm/pgtable_64_types.h @@ -159,6 +159,4 @@ extern unsigned int ptrs_per_p4d; #define PGD_KERNEL_START ((PAGE_SIZE / 2) / sizeof(pgd_t)) -#define ARCH_PAGE_TABLE_SYNC_MASK (pgtable_l5_enabled() ? PGTBL_PGD_MODIFIED : PGTBL_P4D_MODIFIED) - #endif /* _ASM_X86_PGTABLE_64_DEFS_H */ diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 97143d87994c..82a08b585818 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -482,10 +482,6 @@ extern unsigned int fpu_user_xstate_size; struct perf_event; -typedef struct { - unsigned long seg; -} mm_segment_t; - struct thread_struct { /* Cached TLS descriptors: */ struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; @@ -517,7 +513,7 @@ struct thread_struct { /* Save middle states of ptrace breakpoints */ struct perf_event *ptrace_bps[HBP_NUM]; /* Debug status used for traps, single steps, etc... */ - unsigned long debugreg6; + unsigned long virtual_dr6; /* Keep track of the exact dr7 value set by the user */ unsigned long ptrace_dr7; /* Fault info: */ @@ -538,8 +534,6 @@ struct thread_struct { */ unsigned long iopl_emul; - mm_segment_t addr_limit; - unsigned int sig_on_uaccess_err:1; /* Floating point and extended processor state */ @@ -696,6 +690,7 @@ extern void load_direct_gdt(int); extern void load_fixmap_gdt(int); extern void load_percpu_segment(int); extern void cpu_init(void); +extern void cpu_init_exception_handling(void); extern void cr4_init(void); static inline unsigned long get_debugctlmsr(void) @@ -782,67 +777,15 @@ static inline void spin_lock_prefetch(const void *x) }) #ifdef CONFIG_X86_32 -/* - * User space process size: 3GB (default). - */ -#define IA32_PAGE_OFFSET PAGE_OFFSET -#define TASK_SIZE PAGE_OFFSET -#define TASK_SIZE_LOW TASK_SIZE -#define TASK_SIZE_MAX TASK_SIZE -#define DEFAULT_MAP_WINDOW TASK_SIZE -#define STACK_TOP TASK_SIZE -#define STACK_TOP_MAX STACK_TOP - #define INIT_THREAD { \ .sp0 = TOP_OF_INIT_STACK, \ .sysenter_cs = __KERNEL_CS, \ - .addr_limit = KERNEL_DS, \ } #define KSTK_ESP(task) (task_pt_regs(task)->sp) #else -/* - * User space process size. This is the first address outside the user range. - * There are a few constraints that determine this: - * - * On Intel CPUs, if a SYSCALL instruction is at the highest canonical - * address, then that syscall will enter the kernel with a - * non-canonical return address, and SYSRET will explode dangerously. - * We avoid this particular problem by preventing anything executable - * from being mapped at the maximum canonical address. - * - * On AMD CPUs in the Ryzen family, there's a nasty bug in which the - * CPUs malfunction if they execute code from the highest canonical page. - * They'll speculate right off the end of the canonical space, and - * bad things happen. This is worked around in the same way as the - * Intel problem. - * - * With page table isolation enabled, we map the LDT in ... [stay tuned] - */ -#define TASK_SIZE_MAX ((1UL << __VIRTUAL_MASK_SHIFT) - PAGE_SIZE) - -#define DEFAULT_MAP_WINDOW ((1UL << 47) - PAGE_SIZE) - -/* This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \ - 0xc0000000 : 0xFFFFe000) - -#define TASK_SIZE_LOW (test_thread_flag(TIF_ADDR32) ? \ - IA32_PAGE_OFFSET : DEFAULT_MAP_WINDOW) -#define TASK_SIZE (test_thread_flag(TIF_ADDR32) ? \ - IA32_PAGE_OFFSET : TASK_SIZE_MAX) -#define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_ADDR32)) ? \ - IA32_PAGE_OFFSET : TASK_SIZE_MAX) - -#define STACK_TOP TASK_SIZE_LOW -#define STACK_TOP_MAX TASK_SIZE_MAX - -#define INIT_THREAD { \ - .addr_limit = KERNEL_DS, \ -} +#define INIT_THREAD { } extern unsigned long KSTK_ESP(struct task_struct *task); diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h index 28996fe19301..2c35f1c01a2d 100644 --- a/arch/x86/include/asm/proto.h +++ b/arch/x86/include/asm/proto.h @@ -10,6 +10,7 @@ void syscall_init(void); #ifdef CONFIG_X86_64 void entry_SYSCALL_64(void); +void entry_SYSCALL_64_safe_stack(void); long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2); #endif diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h index b35030eeec36..5db5d083c873 100644 --- a/arch/x86/include/asm/realmode.h +++ b/arch/x86/include/asm/realmode.h @@ -21,6 +21,9 @@ struct real_mode_header { /* SMP trampoline */ u32 trampoline_start; u32 trampoline_header; +#ifdef CONFIG_AMD_MEM_ENCRYPT + u32 sev_es_trampoline_start; +#endif #ifdef CONFIG_X86_64 u32 trampoline_pgd; #endif @@ -57,6 +60,9 @@ extern unsigned char real_mode_blob_end[]; extern unsigned long initial_code; extern unsigned long initial_gs; extern unsigned long initial_stack; +#ifdef CONFIG_AMD_MEM_ENCRYPT +extern unsigned long initial_vc_handler; +#endif extern unsigned char real_mode_blob[]; extern unsigned char real_mode_relocs[]; @@ -66,6 +72,7 @@ extern unsigned char startup_32_smp[]; extern unsigned char boot_gdt[]; #else extern unsigned char secondary_startup_64[]; +extern unsigned char secondary_startup_64_no_verify[]; #endif static inline size_t real_mode_size_needed(void) diff --git a/arch/x86/include/asm/required-features.h b/arch/x86/include/asm/required-features.h index 6847d85400a8..3ff0d48469f2 100644 --- a/arch/x86/include/asm/required-features.h +++ b/arch/x86/include/asm/required-features.h @@ -54,7 +54,7 @@ #endif #ifdef CONFIG_X86_64 -#ifdef CONFIG_PARAVIRT +#ifdef CONFIG_PARAVIRT_XXL /* Paravirtualized systems may not have PSE or PGE available */ #define NEED_PSE 0 #define NEED_PGE 0 diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index 9646c300f128..7fdd4facfce7 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h @@ -222,15 +222,11 @@ #endif -#ifndef CONFIG_PARAVIRT_XXL -# define get_kernel_rpl() 0 -#endif - #define IDT_ENTRIES 256 #define NUM_EXCEPTION_VECTORS 32 /* Bitmask of exception vectors which push an error code on the stack: */ -#define EXCEPTION_ERRCODE_MASK 0x00027d00 +#define EXCEPTION_ERRCODE_MASK 0x20027d00 #define GDT_SIZE (GDT_ENTRIES*8) #define GDT_ENTRY_TLS_ENTRIES 3 diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index 84b645cc8bc9..389d851a02c4 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h @@ -39,6 +39,8 @@ void vsmp_init(void); static inline void vsmp_init(void) { } #endif +struct pt_regs; + void setup_bios_corruption_check(void); void early_platform_quirks(void); @@ -48,7 +50,9 @@ extern void reserve_standard_io_resources(void); extern void i386_reserve_resources(void); extern unsigned long __startup_64(unsigned long physaddr, struct boot_params *bp); extern unsigned long __startup_secondary_64(void); -extern int early_make_pgtable(unsigned long address); +extern void startup_64_setup_env(unsigned long physbase); +extern void early_setup_idt(void); +extern void __init do_early_exception(struct pt_regs *regs, int trapnr); #ifdef CONFIG_X86_INTEL_MID extern void x86_intel_mid_early_setup(void); @@ -115,7 +119,7 @@ void *extend_brk(size_t size, size_t align); * executable.) */ #define RESERVE_BRK(name,sz) \ - static void __section(.discard.text) __used notrace \ + static void __section(".discard.text") __used notrace \ __brk_reservation_fn_##name##__(void) { \ asm volatile ( \ ".pushsection .brk_reservation,\"aw\",@nobits;" \ diff --git a/arch/x86/include/asm/sev-es.h b/arch/x86/include/asm/sev-es.h new file mode 100644 index 000000000000..cf1d957c7091 --- /dev/null +++ b/arch/x86/include/asm/sev-es.h @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * AMD Encrypted Register State Support + * + * Author: Joerg Roedel <jroedel@suse.de> + */ + +#ifndef __ASM_ENCRYPTED_STATE_H +#define __ASM_ENCRYPTED_STATE_H + +#include <linux/types.h> +#include <asm/insn.h> + +#define GHCB_SEV_INFO 0x001UL +#define GHCB_SEV_INFO_REQ 0x002UL +#define GHCB_INFO(v) ((v) & 0xfffUL) +#define GHCB_PROTO_MAX(v) (((v) >> 48) & 0xffffUL) +#define GHCB_PROTO_MIN(v) (((v) >> 32) & 0xffffUL) +#define GHCB_PROTO_OUR 0x0001UL +#define GHCB_SEV_CPUID_REQ 0x004UL +#define GHCB_CPUID_REQ_EAX 0 +#define GHCB_CPUID_REQ_EBX 1 +#define GHCB_CPUID_REQ_ECX 2 +#define GHCB_CPUID_REQ_EDX 3 +#define GHCB_CPUID_REQ(fn, reg) (GHCB_SEV_CPUID_REQ | \ + (((unsigned long)reg & 3) << 30) | \ + (((unsigned long)fn) << 32)) + +#define GHCB_PROTOCOL_MAX 0x0001UL +#define GHCB_DEFAULT_USAGE 0x0000UL + +#define GHCB_SEV_CPUID_RESP 0x005UL +#define GHCB_SEV_TERMINATE 0x100UL +#define GHCB_SEV_TERMINATE_REASON(reason_set, reason_val) \ + (((((u64)reason_set) & 0x7) << 12) | \ + ((((u64)reason_val) & 0xff) << 16)) +#define GHCB_SEV_ES_REASON_GENERAL_REQUEST 0 +#define GHCB_SEV_ES_REASON_PROTOCOL_UNSUPPORTED 1 + +#define GHCB_SEV_GHCB_RESP_CODE(v) ((v) & 0xfff) +#define VMGEXIT() { asm volatile("rep; vmmcall\n\r"); } + +enum es_result { + ES_OK, /* All good */ + ES_UNSUPPORTED, /* Requested operation not supported */ + ES_VMM_ERROR, /* Unexpected state from the VMM */ + ES_DECODE_FAILED, /* Instruction decoding failed */ + ES_EXCEPTION, /* Instruction caused exception */ + ES_RETRY, /* Retry instruction emulation */ +}; + +struct es_fault_info { + unsigned long vector; + unsigned long error_code; + unsigned long cr2; +}; + +struct pt_regs; + +/* ES instruction emulation context */ +struct es_em_ctxt { + struct pt_regs *regs; + struct insn insn; + struct es_fault_info fi; +}; + +void do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code); + +static inline u64 lower_bits(u64 val, unsigned int bits) +{ + u64 mask = (1ULL << bits) - 1; + + return (val & mask); +} + +struct real_mode_header; +enum stack_type; + +/* Early IDT entry points for #VC handler */ +extern void vc_no_ghcb(void); +extern void vc_boot_ghcb(void); +extern bool handle_vc_boot_ghcb(struct pt_regs *regs); + +#ifdef CONFIG_AMD_MEM_ENCRYPT +extern struct static_key_false sev_es_enable_key; +extern void __sev_es_ist_enter(struct pt_regs *regs); +extern void __sev_es_ist_exit(void); +static __always_inline void sev_es_ist_enter(struct pt_regs *regs) +{ + if (static_branch_unlikely(&sev_es_enable_key)) + __sev_es_ist_enter(regs); +} +static __always_inline void sev_es_ist_exit(void) +{ + if (static_branch_unlikely(&sev_es_enable_key)) + __sev_es_ist_exit(); +} +extern int sev_es_setup_ap_jump_table(struct real_mode_header *rmh); +extern void __sev_es_nmi_complete(void); +static __always_inline void sev_es_nmi_complete(void) +{ + if (static_branch_unlikely(&sev_es_enable_key)) + __sev_es_nmi_complete(); +} +extern int __init sev_es_efi_map_ghcbs(pgd_t *pgd); +#else +static inline void sev_es_ist_enter(struct pt_regs *regs) { } +static inline void sev_es_ist_exit(void) { } +static inline int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) { return 0; } +static inline void sev_es_nmi_complete(void) { } +static inline int sev_es_efi_map_ghcbs(pgd_t *pgd) { return 0; } +#endif + +#endif diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h index 59a3e13204c3..cc177b4431ae 100644 --- a/arch/x86/include/asm/special_insns.h +++ b/arch/x86/include/asm/special_insns.h @@ -11,45 +11,47 @@ #include <linux/jump_label.h> /* - * Volatile isn't enough to prevent the compiler from reordering the - * read/write functions for the control registers and messing everything up. - * A memory clobber would solve the problem, but would prevent reordering of - * all loads stores around it, which can hurt performance. Solution is to - * use a variable and mimic reads and writes to it to enforce serialization + * The compiler should not reorder volatile asm statements with respect to each + * other: they should execute in program order. However GCC 4.9.x and 5.x have + * a bug (which was fixed in 8.1, 7.3 and 6.5) where they might reorder + * volatile asm. The write functions are not affected since they have memory + * clobbers preventing reordering. To prevent reads from being reordered with + * respect to writes, use a dummy memory operand. */ -extern unsigned long __force_order; + +#define __FORCE_ORDER "m"(*(unsigned int *)0x1000UL) void native_write_cr0(unsigned long val); static inline unsigned long native_read_cr0(void) { unsigned long val; - asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order)); + asm volatile("mov %%cr0,%0\n\t" : "=r" (val) : __FORCE_ORDER); return val; } static __always_inline unsigned long native_read_cr2(void) { unsigned long val; - asm volatile("mov %%cr2,%0\n\t" : "=r" (val), "=m" (__force_order)); + asm volatile("mov %%cr2,%0\n\t" : "=r" (val) : __FORCE_ORDER); return val; } static __always_inline void native_write_cr2(unsigned long val) { - asm volatile("mov %0,%%cr2": : "r" (val), "m" (__force_order)); + asm volatile("mov %0,%%cr2": : "r" (val) : "memory"); } static inline unsigned long __native_read_cr3(void) { unsigned long val; - asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order)); + asm volatile("mov %%cr3,%0\n\t" : "=r" (val) : __FORCE_ORDER); return val; } static inline void native_write_cr3(unsigned long val) { - asm volatile("mov %0,%%cr3": : "r" (val), "m" (__force_order)); + asm volatile("mov %0,%%cr3": : "r" (val) : "memory"); } static inline unsigned long native_read_cr4(void) @@ -64,10 +66,10 @@ static inline unsigned long native_read_cr4(void) asm volatile("1: mov %%cr4, %0\n" "2:\n" _ASM_EXTABLE(1b, 2b) - : "=r" (val), "=m" (__force_order) : "0" (0)); + : "=r" (val) : "0" (0), __FORCE_ORDER); #else /* CR4 always exists on x86_64. */ - asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order)); + asm volatile("mov %%cr4,%0\n\t" : "=r" (val) : __FORCE_ORDER); #endif return val; } @@ -234,6 +236,76 @@ static inline void clwb(volatile void *__p) #define nop() asm volatile ("nop") +static inline void serialize(void) +{ + /* Instruction opcode for SERIALIZE; supported in binutils >= 2.35. */ + asm volatile(".byte 0xf, 0x1, 0xe8" ::: "memory"); +} + +/* The dst parameter must be 64-bytes aligned */ +static inline void movdir64b(void *dst, const void *src) +{ + const struct { char _[64]; } *__src = src; + struct { char _[64]; } *__dst = dst; + + /* + * MOVDIR64B %(rdx), rax. + * + * Both __src and __dst must be memory constraints in order to tell the + * compiler that no other memory accesses should be reordered around + * this one. + * + * Also, both must be supplied as lvalues because this tells + * the compiler what the object is (its size) the instruction accesses. + * I.e., not the pointers but what they point to, thus the deref'ing '*'. + */ + asm volatile(".byte 0x66, 0x0f, 0x38, 0xf8, 0x02" + : "+m" (*__dst) + : "m" (*__src), "a" (__dst), "d" (__src)); +} + +/** + * enqcmds - Enqueue a command in supervisor (CPL0) mode + * @dst: destination, in MMIO space (must be 512-bit aligned) + * @src: 512 bits memory operand + * + * The ENQCMDS instruction allows software to write a 512-bit command to + * a 512-bit-aligned special MMIO region that supports the instruction. + * A return status is loaded into the ZF flag in the RFLAGS register. + * ZF = 0 equates to success, and ZF = 1 indicates retry or error. + * + * This function issues the ENQCMDS instruction to submit data from + * kernel space to MMIO space, in a unit of 512 bits. Order of data access + * is not guaranteed, nor is a memory barrier performed afterwards. It + * returns 0 on success and -EAGAIN on failure. + * + * Warning: Do not use this helper unless your driver has checked that the + * ENQCMDS instruction is supported on the platform and the device accepts + * ENQCMDS. + */ +static inline int enqcmds(void __iomem *dst, const void *src) +{ + const struct { char _[64]; } *__src = src; + struct { char _[64]; } *__dst = dst; + int zf; + + /* + * ENQCMDS %(rdx), rax + * + * See movdir64b()'s comment on operand specification. + */ + asm volatile(".byte 0xf3, 0x0f, 0x38, 0xf8, 0x02, 0x66, 0x90" + CC_SET(z) + : CC_OUT(z) (zf), "+m" (*__dst) + : "m" (*__src), "a" (__dst), "d" (__src)); + + /* Submission failure is indicated via EFLAGS.ZF=1 */ + if (zf) + return -EAGAIN; + + return 0; +} + #endif /* __KERNEL__ */ #endif /* _ASM_X86_SPECIAL_INSNS_H */ diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h index 5ae5a68e469d..49600643faba 100644 --- a/arch/x86/include/asm/stacktrace.h +++ b/arch/x86/include/asm/stacktrace.h @@ -35,6 +35,8 @@ bool in_entry_stack(unsigned long *stack, struct stack_info *info); int get_stack_info(unsigned long *stack, struct task_struct *task, struct stack_info *info, unsigned long *visit_mask); +bool get_stack_info_noinstr(unsigned long *stack, struct task_struct *task, + struct stack_info *info); const char *stack_type_name(enum stack_type type); diff --git a/arch/x86/include/asm/static_call.h b/arch/x86/include/asm/static_call.h new file mode 100644 index 000000000000..c37f11999d0c --- /dev/null +++ b/arch/x86/include/asm/static_call.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_STATIC_CALL_H +#define _ASM_STATIC_CALL_H + +#include <asm/text-patching.h> + +/* + * For CONFIG_HAVE_STATIC_CALL_INLINE, this is a temporary trampoline which + * uses the current value of the key->func pointer to do an indirect jump to + * the function. This trampoline is only used during boot, before the call + * sites get patched by static_call_update(). The name of this trampoline has + * a magical aspect: objtool uses it to find static call sites so it can create + * the .static_call_sites section. + * + * For CONFIG_HAVE_STATIC_CALL, this is a permanent trampoline which + * does a direct jump to the function. The direct jump gets patched by + * static_call_update(). + * + * Having the trampoline in a special section forces GCC to emit a JMP.d32 when + * it does tail-call optimization on the call; since you cannot compute the + * relative displacement across sections. + */ + +#define __ARCH_DEFINE_STATIC_CALL_TRAMP(name, insns) \ + asm(".pushsection .static_call.text, \"ax\" \n" \ + ".align 4 \n" \ + ".globl " STATIC_CALL_TRAMP_STR(name) " \n" \ + STATIC_CALL_TRAMP_STR(name) ": \n" \ + insns " \n" \ + ".type " STATIC_CALL_TRAMP_STR(name) ", @function \n" \ + ".size " STATIC_CALL_TRAMP_STR(name) ", . - " STATIC_CALL_TRAMP_STR(name) " \n" \ + ".popsection \n") + +#define ARCH_DEFINE_STATIC_CALL_TRAMP(name, func) \ + __ARCH_DEFINE_STATIC_CALL_TRAMP(name, ".byte 0xe9; .long " #func " - (. + 4)") + +#define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) \ + __ARCH_DEFINE_STATIC_CALL_TRAMP(name, "ret; nop; nop; nop; nop") + +#endif /* _ASM_STATIC_CALL_H */ diff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h index 75314c3dbe47..6e450827f677 100644 --- a/arch/x86/include/asm/string_64.h +++ b/arch/x86/include/asm/string_64.h @@ -82,38 +82,6 @@ int strcmp(const char *cs, const char *ct); #endif -#define __HAVE_ARCH_MEMCPY_MCSAFE 1 -__must_check unsigned long __memcpy_mcsafe(void *dst, const void *src, - size_t cnt); -DECLARE_STATIC_KEY_FALSE(mcsafe_key); - -/** - * memcpy_mcsafe - copy memory with indication if a machine check happened - * - * @dst: destination address - * @src: source address - * @cnt: number of bytes to copy - * - * Low level memory copy function that catches machine checks - * We only call into the "safe" function on systems that can - * actually do machine check recovery. Everyone else can just - * use memcpy(). - * - * Return 0 for success, or number of bytes not copied if there was an - * exception. - */ -static __always_inline __must_check unsigned long -memcpy_mcsafe(void *dst, const void *src, size_t cnt) -{ -#ifdef CONFIG_X86_MCE - if (static_branch_unlikely(&mcsafe_key)) - return __memcpy_mcsafe(dst, src, cnt); - else -#endif - memcpy(dst, src, cnt); - return 0; -} - #ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE #define __HAVE_ARCH_MEMCPY_FLUSHCACHE 1 void __memcpy_flushcache(void *dst, const void *src, size_t cnt); diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 8a1f5382a4ea..71d630bb5e08 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -3,10 +3,54 @@ #define __SVM_H #include <uapi/asm/svm.h> - +#include <uapi/asm/kvm.h> + +/* + * 32-bit intercept words in the VMCB Control Area, starting + * at Byte offset 000h. + */ + +enum intercept_words { + INTERCEPT_CR = 0, + INTERCEPT_DR, + INTERCEPT_EXCEPTION, + INTERCEPT_WORD3, + INTERCEPT_WORD4, + INTERCEPT_WORD5, + MAX_INTERCEPT, +}; enum { - INTERCEPT_INTR, + /* Byte offset 000h (word 0) */ + INTERCEPT_CR0_READ = 0, + INTERCEPT_CR3_READ = 3, + INTERCEPT_CR4_READ = 4, + INTERCEPT_CR8_READ = 8, + INTERCEPT_CR0_WRITE = 16, + INTERCEPT_CR3_WRITE = 16 + 3, + INTERCEPT_CR4_WRITE = 16 + 4, + INTERCEPT_CR8_WRITE = 16 + 8, + /* Byte offset 004h (word 1) */ + INTERCEPT_DR0_READ = 32, + INTERCEPT_DR1_READ, + INTERCEPT_DR2_READ, + INTERCEPT_DR3_READ, + INTERCEPT_DR4_READ, + INTERCEPT_DR5_READ, + INTERCEPT_DR6_READ, + INTERCEPT_DR7_READ, + INTERCEPT_DR0_WRITE = 48, + INTERCEPT_DR1_WRITE, + INTERCEPT_DR2_WRITE, + INTERCEPT_DR3_WRITE, + INTERCEPT_DR4_WRITE, + INTERCEPT_DR5_WRITE, + INTERCEPT_DR6_WRITE, + INTERCEPT_DR7_WRITE, + /* Byte offset 008h (word 2) */ + INTERCEPT_EXCEPTION_OFFSET = 64, + /* Byte offset 00Ch (word 3) */ + INTERCEPT_INTR = 96, INTERCEPT_NMI, INTERCEPT_SMI, INTERCEPT_INIT, @@ -38,7 +82,8 @@ enum { INTERCEPT_TASK_SWITCH, INTERCEPT_FERR_FREEZE, INTERCEPT_SHUTDOWN, - INTERCEPT_VMRUN, + /* Byte offset 010h (word 4) */ + INTERCEPT_VMRUN = 128, INTERCEPT_VMMCALL, INTERCEPT_VMLOAD, INTERCEPT_VMSAVE, @@ -53,15 +98,18 @@ enum { INTERCEPT_MWAIT_COND, INTERCEPT_XSETBV, INTERCEPT_RDPRU, + /* Byte offset 014h (word 5) */ + INTERCEPT_INVLPGB = 160, + INTERCEPT_INVLPGB_ILLEGAL, + INTERCEPT_INVPCID, + INTERCEPT_MCOMMIT, + INTERCEPT_TLBSYNC, }; struct __attribute__ ((__packed__)) vmcb_control_area { - u32 intercept_cr; - u32 intercept_dr; - u32 intercept_exceptions; - u64 intercept; - u8 reserved_1[40]; + u32 intercepts[MAX_INTERCEPT]; + u32 reserved_1[15 - MAX_INTERCEPT]; u16 pause_filter_thresh; u16 pause_filter_count; u64 iopm_base_pa; @@ -150,14 +198,14 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define SVM_NESTED_CTL_NP_ENABLE BIT(0) #define SVM_NESTED_CTL_SEV_ENABLE BIT(1) -struct __attribute__ ((__packed__)) vmcb_seg { +struct vmcb_seg { u16 selector; u16 attrib; u32 limit; u64 base; -}; +} __packed; -struct __attribute__ ((__packed__)) vmcb_save_area { +struct vmcb_save_area { struct vmcb_seg es; struct vmcb_seg cs; struct vmcb_seg ss; @@ -200,20 +248,67 @@ struct __attribute__ ((__packed__)) vmcb_save_area { u64 br_to; u64 last_excp_from; u64 last_excp_to; -}; + /* + * The following part of the save area is valid only for + * SEV-ES guests when referenced through the GHCB. + */ + u8 reserved_7[104]; + u64 reserved_8; /* rax already available at 0x01f8 */ + u64 rcx; + u64 rdx; + u64 rbx; + u64 reserved_9; /* rsp already available at 0x01d8 */ + u64 rbp; + u64 rsi; + u64 rdi; + u64 r8; + u64 r9; + u64 r10; + u64 r11; + u64 r12; + u64 r13; + u64 r14; + u64 r15; + u8 reserved_10[16]; + u64 sw_exit_code; + u64 sw_exit_info_1; + u64 sw_exit_info_2; + u64 sw_scratch; + u8 reserved_11[56]; + u64 xcr0; + u8 valid_bitmap[16]; + u64 x87_state_gpa; +} __packed; + +struct ghcb { + struct vmcb_save_area save; + u8 reserved_save[2048 - sizeof(struct vmcb_save_area)]; + + u8 shared_buffer[2032]; + + u8 reserved_1[10]; + u16 protocol_version; /* negotiated SEV-ES/GHCB protocol version */ + u32 ghcb_usage; +} __packed; + + +#define EXPECTED_VMCB_SAVE_AREA_SIZE 1032 +#define EXPECTED_VMCB_CONTROL_AREA_SIZE 256 +#define EXPECTED_GHCB_SIZE PAGE_SIZE static inline void __unused_size_checks(void) { - BUILD_BUG_ON(sizeof(struct vmcb_save_area) != 0x298); - BUILD_BUG_ON(sizeof(struct vmcb_control_area) != 256); + BUILD_BUG_ON(sizeof(struct vmcb_save_area) != EXPECTED_VMCB_SAVE_AREA_SIZE); + BUILD_BUG_ON(sizeof(struct vmcb_control_area) != EXPECTED_VMCB_CONTROL_AREA_SIZE); + BUILD_BUG_ON(sizeof(struct ghcb) != EXPECTED_GHCB_SIZE); } -struct __attribute__ ((__packed__)) vmcb { +struct vmcb { struct vmcb_control_area control; u8 reserved_control[1024 - sizeof(struct vmcb_control_area)]; struct vmcb_save_area save; -}; +} __packed; #define SVM_CPUID_FUNC 0x8000000a @@ -240,32 +335,6 @@ struct __attribute__ ((__packed__)) vmcb { #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK #define SVM_SELECTOR_CODE_MASK (1 << 3) -#define INTERCEPT_CR0_READ 0 -#define INTERCEPT_CR3_READ 3 -#define INTERCEPT_CR4_READ 4 -#define INTERCEPT_CR8_READ 8 -#define INTERCEPT_CR0_WRITE (16 + 0) -#define INTERCEPT_CR3_WRITE (16 + 3) -#define INTERCEPT_CR4_WRITE (16 + 4) -#define INTERCEPT_CR8_WRITE (16 + 8) - -#define INTERCEPT_DR0_READ 0 -#define INTERCEPT_DR1_READ 1 -#define INTERCEPT_DR2_READ 2 -#define INTERCEPT_DR3_READ 3 -#define INTERCEPT_DR4_READ 4 -#define INTERCEPT_DR5_READ 5 -#define INTERCEPT_DR6_READ 6 -#define INTERCEPT_DR7_READ 7 -#define INTERCEPT_DR0_WRITE (16 + 0) -#define INTERCEPT_DR1_WRITE (16 + 1) -#define INTERCEPT_DR2_WRITE (16 + 2) -#define INTERCEPT_DR3_WRITE (16 + 3) -#define INTERCEPT_DR4_WRITE (16 + 4) -#define INTERCEPT_DR5_WRITE (16 + 5) -#define INTERCEPT_DR6_WRITE (16 + 6) -#define INTERCEPT_DR7_WRITE (16 + 7) - #define SVM_EVTINJ_VEC_MASK 0xff #define SVM_EVTINJ_TYPE_SHIFT 8 @@ -298,4 +367,47 @@ struct __attribute__ ((__packed__)) vmcb { #define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP) +/* GHCB Accessor functions */ + +#define GHCB_BITMAP_IDX(field) \ + (offsetof(struct vmcb_save_area, field) / sizeof(u64)) + +#define DEFINE_GHCB_ACCESSORS(field) \ + static inline bool ghcb_##field##_is_valid(const struct ghcb *ghcb) \ + { \ + return test_bit(GHCB_BITMAP_IDX(field), \ + (unsigned long *)&ghcb->save.valid_bitmap); \ + } \ + \ + static inline void ghcb_set_##field(struct ghcb *ghcb, u64 value) \ + { \ + __set_bit(GHCB_BITMAP_IDX(field), \ + (unsigned long *)&ghcb->save.valid_bitmap); \ + ghcb->save.field = value; \ + } + +DEFINE_GHCB_ACCESSORS(cpl) +DEFINE_GHCB_ACCESSORS(rip) +DEFINE_GHCB_ACCESSORS(rsp) +DEFINE_GHCB_ACCESSORS(rax) +DEFINE_GHCB_ACCESSORS(rcx) +DEFINE_GHCB_ACCESSORS(rdx) +DEFINE_GHCB_ACCESSORS(rbx) +DEFINE_GHCB_ACCESSORS(rbp) +DEFINE_GHCB_ACCESSORS(rsi) +DEFINE_GHCB_ACCESSORS(rdi) +DEFINE_GHCB_ACCESSORS(r8) +DEFINE_GHCB_ACCESSORS(r9) +DEFINE_GHCB_ACCESSORS(r10) +DEFINE_GHCB_ACCESSORS(r11) +DEFINE_GHCB_ACCESSORS(r12) +DEFINE_GHCB_ACCESSORS(r13) +DEFINE_GHCB_ACCESSORS(r14) +DEFINE_GHCB_ACCESSORS(r15) +DEFINE_GHCB_ACCESSORS(sw_exit_code) +DEFINE_GHCB_ACCESSORS(sw_exit_info_1) +DEFINE_GHCB_ACCESSORS(sw_exit_info_2) +DEFINE_GHCB_ACCESSORS(sw_scratch) +DEFINE_GHCB_ACCESSORS(xcr0) + #endif diff --git a/arch/x86/include/asm/sync_core.h b/arch/x86/include/asm/sync_core.h index fdb5b356e59b..0fd4a9dfb29c 100644 --- a/arch/x86/include/asm/sync_core.h +++ b/arch/x86/include/asm/sync_core.h @@ -5,6 +5,7 @@ #include <linux/preempt.h> #include <asm/processor.h> #include <asm/cpufeature.h> +#include <asm/special_insns.h> #ifdef CONFIG_X86_32 static inline void iret_to_self(void) @@ -46,22 +47,34 @@ static inline void iret_to_self(void) * * b) Text was modified on a different CPU, may subsequently be * executed on this CPU, and you want to make sure the new version - * gets executed. This generally means you're calling this in a IPI. + * gets executed. This generally means you're calling this in an IPI. * * If you're calling this for a different reason, you're probably doing * it wrong. + * + * Like all of Linux's memory ordering operations, this is a + * compiler barrier as well. */ static inline void sync_core(void) { /* - * There are quite a few ways to do this. IRET-to-self is nice - * because it works on every CPU, at any CPL (so it's compatible - * with paravirtualization), and it never exits to a hypervisor. - * The only down sides are that it's a bit slow (it seems to be - * a bit more than 2x slower than the fastest options) and that - * it unmasks NMIs. The "push %cs" is needed because, in - * paravirtual environments, __KERNEL_CS may not be a valid CS - * value when we do IRET directly. + * The SERIALIZE instruction is the most straightforward way to + * do this, but it is not universally available. + */ + if (static_cpu_has(X86_FEATURE_SERIALIZE)) { + serialize(); + return; + } + + /* + * For all other processors, there are quite a few ways to do this. + * IRET-to-self is nice because it works on every CPU, at any CPL + * (so it's compatible with paravirtualization), and it never exits + * to a hypervisor. The only downsides are that it's a bit slow + * (it seems to be a bit more than 2x slower than the fastest + * options) and that it unmasks NMIs. The "push %cs" is needed, + * because in paravirtual environments __KERNEL_CS may not be a + * valid CS value when we do IRET directly. * * In case NMI unmasking or performance ever becomes a problem, * the next best option appears to be MOV-to-CR2 and an @@ -71,9 +84,6 @@ static inline void sync_core(void) * CPUID is the conventional way, but it's nasty: it doesn't * exist on some 486-like CPUs, and it usually exits to a * hypervisor. - * - * Like all of Linux's memory ordering operations, this is a - * compiler barrier as well. */ iret_to_self(); } diff --git a/arch/x86/include/asm/text-patching.h b/arch/x86/include/asm/text-patching.h index 6593b42cb379..b7421780e4e9 100644 --- a/arch/x86/include/asm/text-patching.h +++ b/arch/x86/include/asm/text-patching.h @@ -53,6 +53,9 @@ extern void text_poke_finish(void); #define INT3_INSN_SIZE 1 #define INT3_INSN_OPCODE 0xCC +#define RET_INSN_SIZE 1 +#define RET_INSN_OPCODE 0xC3 + #define CALL_INSN_SIZE 5 #define CALL_INSN_OPCODE 0xE8 @@ -73,6 +76,7 @@ static __always_inline int text_opcode_size(u8 opcode) switch(opcode) { __CASE(INT3); + __CASE(RET); __CASE(CALL); __CASE(JMP32); __CASE(JMP8); @@ -141,11 +145,26 @@ void int3_emulate_push(struct pt_regs *regs, unsigned long val) } static __always_inline +unsigned long int3_emulate_pop(struct pt_regs *regs) +{ + unsigned long val = *(unsigned long *)regs->sp; + regs->sp += sizeof(unsigned long); + return val; +} + +static __always_inline void int3_emulate_call(struct pt_regs *regs, unsigned long func) { int3_emulate_push(regs, regs->ip - INT3_INSN_SIZE + CALL_INSN_SIZE); int3_emulate_jmp(regs, func); } + +static __always_inline +void int3_emulate_ret(struct pt_regs *regs) +{ + unsigned long ip = int3_emulate_pop(regs); + int3_emulate_jmp(regs, ip); +} #endif /* !CONFIG_UML_X86 */ #endif /* _ASM_X86_TEXT_PATCHING_H */ diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 267701ae3d86..44733a4bfc42 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -102,7 +102,6 @@ struct thread_info { #define TIF_SYSCALL_TRACEPOINT 28 /* syscall tracepoint instrumentation */ #define TIF_ADDR32 29 /* 32-bit address space on 64 bits */ #define TIF_X32 30 /* 32-bit native x86-64 binary */ -#define TIF_FSCHECK 31 /* Check FS is USER_DS on return */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) @@ -131,7 +130,6 @@ struct thread_info { #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_ADDR32 (1 << TIF_ADDR32) #define _TIF_X32 (1 << TIF_X32) -#define _TIF_FSCHECK (1 << TIF_FSCHECK) /* flags to check in __switch_to() */ #define _TIF_WORK_CTXSW_BASE \ diff --git a/arch/x86/include/asm/trap_pf.h b/arch/x86/include/asm/trap_pf.h new file mode 100644 index 000000000000..305bc1214aef --- /dev/null +++ b/arch/x86/include/asm/trap_pf.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_X86_TRAP_PF_H +#define _ASM_X86_TRAP_PF_H + +/* + * Page fault error code bits: + * + * bit 0 == 0: no page found 1: protection fault + * bit 1 == 0: read access 1: write access + * bit 2 == 0: kernel-mode access 1: user-mode access + * bit 3 == 1: use of reserved bit detected + * bit 4 == 1: fault was an instruction fetch + * bit 5 == 1: protection keys block access + */ +enum x86_pf_error_code { + X86_PF_PROT = 1 << 0, + X86_PF_WRITE = 1 << 1, + X86_PF_USER = 1 << 2, + X86_PF_RSVD = 1 << 3, + X86_PF_INSTR = 1 << 4, + X86_PF_PK = 1 << 5, +}; + +#endif /* _ASM_X86_TRAP_PF_H */ diff --git a/arch/x86/include/asm/trapnr.h b/arch/x86/include/asm/trapnr.h index 082f45631fa9..f5d2325aa0b7 100644 --- a/arch/x86/include/asm/trapnr.h +++ b/arch/x86/include/asm/trapnr.h @@ -26,6 +26,7 @@ #define X86_TRAP_XF 19 /* SIMD Floating-Point Exception */ #define X86_TRAP_VE 20 /* Virtualization Exception */ #define X86_TRAP_CP 21 /* Control Protection Exception */ +#define X86_TRAP_VC 29 /* VMM Communication Exception */ #define X86_TRAP_IRET 32 /* IRET Exception */ #endif diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index 714b1a30e7b0..7f7200021bd1 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h @@ -8,12 +8,14 @@ #include <asm/debugreg.h> #include <asm/idtentry.h> #include <asm/siginfo.h> /* TRAP_TRACE, ... */ +#include <asm/trap_pf.h> #ifdef CONFIG_X86_64 asmlinkage __visible notrace struct pt_regs *sync_regs(struct pt_regs *eregs); asmlinkage __visible notrace struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s); void __init trap_init(void); +asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *eregs); #endif #ifdef CONFIG_X86_F00F_BUG @@ -35,28 +37,12 @@ extern int panic_on_unrecovered_nmi; void math_emulate(struct math_emu_info *); +bool fault_in_kernel_space(unsigned long address); + #ifdef CONFIG_VMAP_STACK void __noreturn handle_stack_overflow(const char *message, struct pt_regs *regs, unsigned long fault_address); #endif -/* - * Page fault error code bits: - * - * bit 0 == 0: no page found 1: protection fault - * bit 1 == 0: read access 1: write access - * bit 2 == 0: kernel-mode access 1: user-mode access - * bit 3 == 1: use of reserved bit detected - * bit 4 == 1: fault was an instruction fetch - * bit 5 == 1: protection keys block access - */ -enum x86_pf_error_code { - X86_PF_PROT = 1 << 0, - X86_PF_WRITE = 1 << 1, - X86_PF_USER = 1 << 2, - X86_PF_RSVD = 1 << 3, - X86_PF_INSTR = 1 << 4, - X86_PF_PK = 1 << 5, -}; #endif /* _ASM_X86_TRAPS_H */ diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index ecefaffd15d4..c9fa7be3df82 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -13,30 +13,6 @@ #include <asm/extable.h> /* - * The fs value determines whether argument validity checking should be - * performed or not. If get_fs() == USER_DS, checking is performed, with - * get_fs() == KERNEL_DS, checking is bypassed. - * - * For historical reasons, these macros are grossly misnamed. - */ - -#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) - -#define KERNEL_DS MAKE_MM_SEG(-1UL) -#define USER_DS MAKE_MM_SEG(TASK_SIZE_MAX) - -#define get_fs() (current->thread.addr_limit) -static inline void set_fs(mm_segment_t fs) -{ - current->thread.addr_limit = fs; - /* On user-mode return, check fs is correct */ - set_thread_flag(TIF_FSCHECK); -} - -#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg) -#define user_addr_max() (current->thread.addr_limit.seg) - -/* * Test whether a block of memory is a valid user space address. * Returns 0 if the range is valid, nonzero otherwise. */ @@ -93,28 +69,17 @@ static inline bool pagefault_disabled(void); #define access_ok(addr, size) \ ({ \ WARN_ON_IN_IRQ(); \ - likely(!__range_not_ok(addr, size, user_addr_max())); \ + likely(!__range_not_ok(addr, size, TASK_SIZE_MAX)); \ }) -/* - * These are the main single-value transfer routines. They automatically - * use the right size if we just have the right pointer type. - * - * This gets kind of ugly. We want to return _two_ values in "get_user()" - * and yet we don't want to do any pointers, because that is too much - * of a performance impact. Thus we have a few rather ugly macros here, - * and hide all the ugliness from the user. - * - * The "__xxx" versions of the user access functions are versions that - * do not verify the address space, that must have been done previously - * with a separate "access_ok()" call (this is used when we do multiple - * accesses to the same area of user memory). - */ - extern int __get_user_1(void); extern int __get_user_2(void); extern int __get_user_4(void); extern int __get_user_8(void); +extern int __get_user_nocheck_1(void); +extern int __get_user_nocheck_2(void); +extern int __get_user_nocheck_4(void); +extern int __get_user_nocheck_8(void); extern int __get_user_bad(void); #define __uaccess_begin() stac() @@ -138,25 +103,12 @@ extern int __get_user_bad(void); #define __typefits(x,type,not) \ __builtin_choose_expr(sizeof(x)<=sizeof(type),(unsigned type)0,not) -/** - * get_user - Get a simple variable from user space. - * @x: Variable to store result. - * @ptr: Source address, in user space. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * This macro copies a single simple variable from user space to kernel - * space. It supports simple types like char and int, but not larger - * data types like structures or arrays. - * - * @ptr must have pointer-to-simple-variable type, and the result of - * dereferencing @ptr must be assignable to @x without a cast. - * - * Return: zero on success, or -EFAULT on error. - * On error, the variable @x is set to zero. - */ /* + * This is used for both get_user() and __get_user() to expand to + * the proper special function call that has odd calling conventions + * due to returning both a value and an error, and that depends on + * the size of the pointer passed in. + * * Careful: we have to cast the result to the type of the pointer * for sign reasons. * @@ -169,13 +121,12 @@ extern int __get_user_bad(void); * Clang/LLVM cares about the size of the register, but still wants * the base register for something that ends up being a pair. */ -#define get_user(x, ptr) \ +#define do_get_user_call(fn,x,ptr) \ ({ \ int __ret_gu; \ register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \ __chk_user_ptr(ptr); \ - might_fault(); \ - asm volatile("call __get_user_%P4" \ + asm volatile("call __" #fn "_%P4" \ : "=a" (__ret_gu), "=r" (__val_gu), \ ASM_CALL_CONSTRAINT \ : "0" (ptr), "i" (sizeof(*(ptr)))); \ @@ -183,10 +134,48 @@ extern int __get_user_bad(void); __builtin_expect(__ret_gu, 0); \ }) -#define __put_user_x(size, x, ptr, __ret_pu) \ - asm volatile("call __put_user_" #size : "=a" (__ret_pu) \ - : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") +/** + * get_user - Get a simple variable from user space. + * @x: Variable to store result. + * @ptr: Source address, in user space. + * + * Context: User context only. This function may sleep if pagefaults are + * enabled. + * + * This macro copies a single simple variable from user space to kernel + * space. It supports simple types like char and int, but not larger + * data types like structures or arrays. + * + * @ptr must have pointer-to-simple-variable type, and the result of + * dereferencing @ptr must be assignable to @x without a cast. + * + * Return: zero on success, or -EFAULT on error. + * On error, the variable @x is set to zero. + */ +#define get_user(x,ptr) ({ might_fault(); do_get_user_call(get_user,x,ptr); }) +/** + * __get_user - Get a simple variable from user space, with less checking. + * @x: Variable to store result. + * @ptr: Source address, in user space. + * + * Context: User context only. This function may sleep if pagefaults are + * enabled. + * + * This macro copies a single simple variable from user space to kernel + * space. It supports simple types like char and int, but not larger + * data types like structures or arrays. + * + * @ptr must have pointer-to-simple-variable type, and the result of + * dereferencing @ptr must be assignable to @x without a cast. + * + * Caller must check the pointer with access_ok() before calling this + * function. + * + * Return: zero on success, or -EFAULT on error. + * On error, the variable @x is set to zero. + */ +#define __get_user(x,ptr) do_get_user_call(get_user_nocheck,x,ptr) #ifdef CONFIG_X86_32 @@ -199,25 +188,49 @@ extern int __get_user_bad(void); : : "A" (x), "r" (addr) \ : : label) -#define __put_user_x8(x, ptr, __ret_pu) \ - asm volatile("call __put_user_8" : "=a" (__ret_pu) \ - : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") #else #define __put_user_goto_u64(x, ptr, label) \ __put_user_goto(x, ptr, "q", "er", label) -#define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu) #endif extern void __put_user_bad(void); /* * Strange magic calling convention: pointer in %ecx, - * value in %eax(:%edx), return value in %eax. clobbers %rbx + * value in %eax(:%edx), return value in %ecx. clobbers %rbx */ extern void __put_user_1(void); extern void __put_user_2(void); extern void __put_user_4(void); extern void __put_user_8(void); +extern void __put_user_nocheck_1(void); +extern void __put_user_nocheck_2(void); +extern void __put_user_nocheck_4(void); +extern void __put_user_nocheck_8(void); + +/* + * ptr must be evaluated and assigned to the temporary __ptr_pu before + * the assignment of x to __val_pu, to avoid any function calls + * involved in the ptr expression (possibly implicitly generated due + * to KASAN) from clobbering %ax. + */ +#define do_put_user_call(fn,x,ptr) \ +({ \ + int __ret_pu; \ + void __user *__ptr_pu; \ + register __typeof__(*(ptr)) __val_pu asm("%"_ASM_AX); \ + __chk_user_ptr(ptr); \ + __ptr_pu = (ptr); \ + __val_pu = (x); \ + asm volatile("call __" #fn "_%P[size]" \ + : "=c" (__ret_pu), \ + ASM_CALL_CONSTRAINT \ + : "0" (__ptr_pu), \ + "r" (__val_pu), \ + [size] "i" (sizeof(*(ptr))) \ + :"ebx"); \ + __builtin_expect(__ret_pu, 0); \ +}) /** * put_user - Write a simple value into user space. @@ -236,32 +249,29 @@ extern void __put_user_8(void); * * Return: zero on success, or -EFAULT on error. */ -#define put_user(x, ptr) \ -({ \ - int __ret_pu; \ - __typeof__(*(ptr)) __pu_val; \ - __chk_user_ptr(ptr); \ - might_fault(); \ - __pu_val = x; \ - switch (sizeof(*(ptr))) { \ - case 1: \ - __put_user_x(1, __pu_val, ptr, __ret_pu); \ - break; \ - case 2: \ - __put_user_x(2, __pu_val, ptr, __ret_pu); \ - break; \ - case 4: \ - __put_user_x(4, __pu_val, ptr, __ret_pu); \ - break; \ - case 8: \ - __put_user_x8(__pu_val, ptr, __ret_pu); \ - break; \ - default: \ - __put_user_x(X, __pu_val, ptr, __ret_pu); \ - break; \ - } \ - __builtin_expect(__ret_pu, 0); \ -}) +#define put_user(x, ptr) ({ might_fault(); do_put_user_call(put_user,x,ptr); }) + +/** + * __put_user - Write a simple value into user space, with less checking. + * @x: Value to copy to user space. + * @ptr: Destination address, in user space. + * + * Context: User context only. This function may sleep if pagefaults are + * enabled. + * + * This macro copies a single simple value from kernel space to user + * space. It supports simple types like char and int, but not larger + * data types like structures or arrays. + * + * @ptr must have pointer-to-simple-variable type, and @x must be assignable + * to the result of dereferencing @ptr. + * + * Caller must check the pointer with access_ok() before calling this + * function. + * + * Return: zero on success, or -EFAULT on error. + */ +#define __put_user(x, ptr) do_put_user_call(put_user_nocheck,x,ptr) #define __put_user_size(x, ptr, size, label) \ do { \ @@ -284,6 +294,55 @@ do { \ } \ } while (0) +#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT + +#ifdef CONFIG_X86_32 +#define __get_user_asm_u64(x, ptr, label) do { \ + unsigned int __gu_low, __gu_high; \ + const unsigned int __user *__gu_ptr; \ + __gu_ptr = (const void __user *)(ptr); \ + __get_user_asm(__gu_low, ptr, "l", "=r", label); \ + __get_user_asm(__gu_high, ptr+1, "l", "=r", label); \ + (x) = ((unsigned long long)__gu_high << 32) | __gu_low; \ +} while (0) +#else +#define __get_user_asm_u64(x, ptr, label) \ + __get_user_asm(x, ptr, "q", "=r", label) +#endif + +#define __get_user_size(x, ptr, size, label) \ +do { \ + __chk_user_ptr(ptr); \ + switch (size) { \ + unsigned char x_u8__; \ + case 1: \ + __get_user_asm(x_u8__, ptr, "b", "=q", label); \ + (x) = x_u8__; \ + break; \ + case 2: \ + __get_user_asm(x, ptr, "w", "=r", label); \ + break; \ + case 4: \ + __get_user_asm(x, ptr, "l", "=r", label); \ + break; \ + case 8: \ + __get_user_asm_u64(x, ptr, label); \ + break; \ + default: \ + (x) = __get_user_bad(); \ + } \ +} while (0) + +#define __get_user_asm(x, addr, itype, ltype, label) \ + asm_volatile_goto("\n" \ + "1: mov"itype" %[umem],%[output]\n" \ + _ASM_EXTABLE_UA(1b, %l2) \ + : [output] ltype(x) \ + : [umem] "m" (__m(addr)) \ + : : label) + +#else // !CONFIG_CC_HAS_ASM_GOTO_OUTPUT + #ifdef CONFIG_X86_32 #define __get_user_asm_u64(x, ptr, retval) \ ({ \ @@ -343,7 +402,7 @@ do { \ "2:\n" \ ".section .fixup,\"ax\"\n" \ "3: mov %[efault],%[errout]\n" \ - " xor"itype" %[output],%[output]\n" \ + " xorl %k[output],%k[output]\n" \ " jmp 2b\n" \ ".previous\n" \ _ASM_EXTABLE_UA(1b, 3b) \ @@ -352,33 +411,7 @@ do { \ : [umem] "m" (__m(addr)), \ [efault] "i" (-EFAULT), "0" (err)) -#define __put_user_nocheck(x, ptr, size) \ -({ \ - __label__ __pu_label; \ - int __pu_err = -EFAULT; \ - __typeof__(*(ptr)) __pu_val = (x); \ - __typeof__(ptr) __pu_ptr = (ptr); \ - __typeof__(size) __pu_size = (size); \ - __uaccess_begin(); \ - __put_user_size(__pu_val, __pu_ptr, __pu_size, __pu_label); \ - __pu_err = 0; \ -__pu_label: \ - __uaccess_end(); \ - __builtin_expect(__pu_err, 0); \ -}) - -#define __get_user_nocheck(x, ptr, size) \ -({ \ - int __gu_err; \ - __inttype(*(ptr)) __gu_val; \ - __typeof__(ptr) __gu_ptr = (ptr); \ - __typeof__(size) __gu_size = (size); \ - __uaccess_begin_nospec(); \ - __get_user_size(__gu_val, __gu_ptr, __gu_size, __gu_err); \ - __uaccess_end(); \ - (x) = (__force __typeof__(*(ptr)))__gu_val; \ - __builtin_expect(__gu_err, 0); \ -}) +#endif // CONFIG_CC_ASM_GOTO_OUTPUT /* FIXME: this hack is definitely wrong -AK */ struct __large_struct { unsigned long buf[100]; }; @@ -396,55 +429,6 @@ struct __large_struct { unsigned long buf[100]; }; : : ltype(x), "m" (__m(addr)) \ : : label) -/** - * __get_user - Get a simple variable from user space, with less checking. - * @x: Variable to store result. - * @ptr: Source address, in user space. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * This macro copies a single simple variable from user space to kernel - * space. It supports simple types like char and int, but not larger - * data types like structures or arrays. - * - * @ptr must have pointer-to-simple-variable type, and the result of - * dereferencing @ptr must be assignable to @x without a cast. - * - * Caller must check the pointer with access_ok() before calling this - * function. - * - * Return: zero on success, or -EFAULT on error. - * On error, the variable @x is set to zero. - */ - -#define __get_user(x, ptr) \ - __get_user_nocheck((x), (ptr), sizeof(*(ptr))) - -/** - * __put_user - Write a simple value into user space, with less checking. - * @x: Value to copy to user space. - * @ptr: Destination address, in user space. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * This macro copies a single simple value from kernel space to user - * space. It supports simple types like char and int, but not larger - * data types like structures or arrays. - * - * @ptr must have pointer-to-simple-variable type, and @x must be assignable - * to the result of dereferencing @ptr. - * - * Caller must check the pointer with access_ok() before calling this - * function. - * - * Return: zero on success, or -EFAULT on error. - */ - -#define __put_user(x, ptr) \ - __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) - extern unsigned long copy_from_user_nmi(void *to, const void __user *from, unsigned long n); extern __must_check long @@ -455,6 +439,15 @@ extern __must_check long strnlen_user(const char __user *str, long n); unsigned long __must_check clear_user(void __user *mem, unsigned long len); unsigned long __must_check __clear_user(void __user *mem, unsigned long len); +#ifdef CONFIG_ARCH_HAS_COPY_MC +unsigned long __must_check +copy_mc_to_kernel(void *to, const void *from, unsigned len); +#define copy_mc_to_kernel copy_mc_to_kernel + +unsigned long __must_check +copy_mc_to_user(void *to, const void *from, unsigned len); +#endif + /* * movsl can be slow when source and dest are not both 8-byte aligned */ @@ -494,6 +487,14 @@ static __must_check __always_inline bool user_access_begin(const void __user *pt #define unsafe_put_user(x, ptr, label) \ __put_user_size((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) +#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT +#define unsafe_get_user(x, ptr, err_label) \ +do { \ + __inttype(*(ptr)) __gu_val; \ + __get_user_size(__gu_val, (ptr), sizeof(*(ptr)), err_label); \ + (x) = (__force __typeof__(*(ptr)))__gu_val; \ +} while (0) +#else // !CONFIG_CC_HAS_ASM_GOTO_OUTPUT #define unsafe_get_user(x, ptr, err_label) \ do { \ int __gu_err; \ @@ -502,6 +503,7 @@ do { \ (x) = (__force __typeof__(*(ptr)))__gu_val; \ if (unlikely(__gu_err)) goto err_label; \ } while (0) +#endif // CONFIG_CC_HAS_ASM_GOTO_OUTPUT /* * We want the unsafe accessors to always be inlined and use @@ -528,6 +530,11 @@ do { \ #define HAVE_GET_KERNEL_NOFAULT +#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT +#define __get_kernel_nofault(dst, src, type, err_label) \ + __get_user_size(*((type *)(dst)), (__force type __user *)(src), \ + sizeof(type), err_label) +#else // !CONFIG_CC_HAS_ASM_GOTO_OUTPUT #define __get_kernel_nofault(dst, src, type, err_label) \ do { \ int __kr_err; \ @@ -537,6 +544,7 @@ do { \ if (unlikely(__kr_err)) \ goto err_label; \ } while (0) +#endif // CONFIG_CC_HAS_ASM_GOTO_OUTPUT #define __put_kernel_nofault(dst, src, type, err_label) \ __put_user_size(*((type *)(src)), (__force type __user *)(dst), \ diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index bc10e3dc64fe..e7265a552f4f 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -47,22 +47,6 @@ copy_user_generic(void *to, const void *from, unsigned len) } static __always_inline __must_check unsigned long -copy_to_user_mcsafe(void *to, const void *from, unsigned len) -{ - unsigned long ret; - - __uaccess_begin(); - /* - * Note, __memcpy_mcsafe() is explicitly used since it can - * handle exceptions / faults. memcpy_mcsafe() may fall back to - * memcpy() which lacks this handling. - */ - ret = __memcpy_mcsafe(to, from, len); - __uaccess_end(); - return ret; -} - -static __always_inline __must_check unsigned long raw_copy_from_user(void *dst, const void __user *src, unsigned long size) { return copy_user_generic(dst, (__force void *)src, size); @@ -102,8 +86,4 @@ __copy_from_user_flushcache(void *dst, const void __user *src, unsigned size) kasan_check_write(dst, size); return __copy_user_flushcache(dst, src, size); } - -unsigned long -mcsafe_handle_tail(char *to, char *from, unsigned len); - #endif /* _ASM_X86_UACCESS_64_H */ diff --git a/arch/x86/include/asm/unwind_hints.h b/arch/x86/include/asm/unwind_hints.h index 7d903fdb3f43..664d4610d700 100644 --- a/arch/x86/include/asm/unwind_hints.h +++ b/arch/x86/include/asm/unwind_hints.h @@ -1,51 +1,17 @@ #ifndef _ASM_X86_UNWIND_HINTS_H #define _ASM_X86_UNWIND_HINTS_H +#include <linux/objtool.h> + #include "orc_types.h" #ifdef __ASSEMBLY__ -/* - * In asm, there are two kinds of code: normal C-type callable functions and - * the rest. The normal callable functions can be called by other code, and - * don't do anything unusual with the stack. Such normal callable functions - * are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this - * category. In this case, no special debugging annotations are needed because - * objtool can automatically generate the ORC data for the ORC unwinder to read - * at runtime. - * - * Anything which doesn't fall into the above category, such as syscall and - * interrupt handlers, tends to not be called directly by other functions, and - * often does unusual non-C-function-type things with the stack pointer. Such - * code needs to be annotated such that objtool can understand it. The - * following CFI hint macros are for this type of code. - * - * These macros provide hints to objtool about the state of the stack at each - * instruction. Objtool starts from the hints and follows the code flow, - * making automatic CFI adjustments when it sees pushes and pops, filling out - * the debuginfo as necessary. It will also warn if it sees any - * inconsistencies. - */ -.macro UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=0 type=ORC_TYPE_CALL end=0 -#ifdef CONFIG_STACK_VALIDATION -.Lunwind_hint_ip_\@: - .pushsection .discard.unwind_hints - /* struct unwind_hint */ - .long .Lunwind_hint_ip_\@ - . - .short \sp_offset - .byte \sp_reg - .byte \type - .byte \end - .balign 4 - .popsection -#endif -.endm - .macro UNWIND_HINT_EMPTY - UNWIND_HINT sp_reg=ORC_REG_UNDEFINED end=1 + UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_CALL end=1 .endm -.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 iret=0 +.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0 .if \base == %rsp .if \indirect .set sp_reg, ORC_REG_SP_INDIRECT @@ -66,24 +32,24 @@ .set sp_offset, \offset - .if \iret - .set type, ORC_TYPE_REGS_IRET + .if \partial + .set type, UNWIND_HINT_TYPE_REGS_PARTIAL .elseif \extra == 0 - .set type, ORC_TYPE_REGS_IRET + .set type, UNWIND_HINT_TYPE_REGS_PARTIAL .set sp_offset, \offset + (16*8) .else - .set type, ORC_TYPE_REGS + .set type, UNWIND_HINT_TYPE_REGS .endif UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type .endm .macro UNWIND_HINT_IRET_REGS base=%rsp offset=0 - UNWIND_HINT_REGS base=\base offset=\offset iret=1 + UNWIND_HINT_REGS base=\base offset=\offset partial=1 .endm .macro UNWIND_HINT_FUNC sp_offset=8 - UNWIND_HINT sp_offset=\sp_offset + UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=\sp_offset type=UNWIND_HINT_TYPE_CALL .endm /* @@ -92,7 +58,7 @@ * initial_func_cfi. */ .macro UNWIND_HINT_RET_OFFSET sp_offset=8 - UNWIND_HINT type=UNWIND_HINT_TYPE_RET_OFFSET sp_offset=\sp_offset + UNWIND_HINT sp_reg=ORC_REG_SP type=UNWIND_HINT_TYPE_RET_OFFSET sp_offset=\sp_offset .endm #endif /* __ASSEMBLY__ */ diff --git a/arch/x86/include/asm/uv/bios.h b/arch/x86/include/asm/uv/bios.h index 70050d0136c3..08b3d810dfba 100644 --- a/arch/x86/include/asm/uv/bios.h +++ b/arch/x86/include/asm/uv/bios.h @@ -5,8 +5,9 @@ /* * UV BIOS layer definitions. * - * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved. - * Copyright (c) Russ Anderson <rja@sgi.com> + * (C) Copyright 2020 Hewlett Packard Enterprise Development LP + * Copyright (C) 2007-2017 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) Russ Anderson <rja@sgi.com> */ #include <linux/rtc.h> @@ -71,6 +72,11 @@ struct uv_gam_range_entry { u32 limit; /* PA bits 56:26 (UV_GAM_RANGE_SHFT) */ }; +#define UV_AT_SIZE 8 /* 7 character arch type + NULL char */ +struct uv_arch_type_entry { + char archtype[UV_AT_SIZE]; +}; + #define UV_SYSTAB_SIG "UVST" #define UV_SYSTAB_VERSION_1 1 /* UV2/3 BIOS version */ #define UV_SYSTAB_VERSION_UV4 0x400 /* UV4 BIOS base version */ @@ -79,10 +85,14 @@ struct uv_gam_range_entry { #define UV_SYSTAB_VERSION_UV4_3 0x403 /* - GAM Range PXM Value */ #define UV_SYSTAB_VERSION_UV4_LATEST UV_SYSTAB_VERSION_UV4_3 +#define UV_SYSTAB_VERSION_UV5 0x500 /* UV5 GAM base version */ +#define UV_SYSTAB_VERSION_UV5_LATEST UV_SYSTAB_VERSION_UV5 + #define UV_SYSTAB_TYPE_UNUSED 0 /* End of table (offset == 0) */ #define UV_SYSTAB_TYPE_GAM_PARAMS 1 /* GAM PARAM conversions */ #define UV_SYSTAB_TYPE_GAM_RNG_TBL 2 /* GAM entry table */ -#define UV_SYSTAB_TYPE_MAX 3 +#define UV_SYSTAB_TYPE_ARCH_TYPE 3 /* UV arch type */ +#define UV_SYSTAB_TYPE_MAX 4 /* * The UV system table describes specific firmware @@ -133,6 +143,7 @@ extern s64 uv_bios_reserved_page_pa(u64, u64 *, u64 *, u64 *); extern int uv_bios_set_legacy_vga_target(bool decode, int domain, int bus); extern int uv_bios_init(void); +extern unsigned long get_uv_systab_phys(bool msg); extern unsigned long sn_rtc_cycles_per_second; extern int uv_type; diff --git a/arch/x86/include/asm/uv/uv.h b/arch/x86/include/asm/uv/uv.h index e48aea9ba47d..172d3e4a9e4b 100644 --- a/arch/x86/include/asm/uv/uv.h +++ b/arch/x86/include/asm/uv/uv.h @@ -35,10 +35,8 @@ extern int is_uv_hubbed(int uvtype); extern void uv_cpu_init(void); extern void uv_nmi_init(void); extern void uv_system_init(void); -extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, - const struct flush_tlb_info *info); -#else /* X86_UV */ +#else /* !X86_UV */ static inline enum uv_system_type get_uv_system_type(void) { return UV_NONE; } static inline bool is_early_uv_system(void) { return 0; } diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h deleted file mode 100644 index cd24804955d7..000000000000 --- a/arch/x86/include/asm/uv/uv_bau.h +++ /dev/null @@ -1,755 +0,0 @@ -/* - * 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. - * - * SGI UV Broadcast Assist Unit definitions - * - * Copyright (C) 2008-2011 Silicon Graphics, Inc. All rights reserved. - */ - -#ifndef _ASM_X86_UV_UV_BAU_H -#define _ASM_X86_UV_UV_BAU_H - -#include <linux/bitmap.h> -#include <asm/idtentry.h> - -#define BITSPERBYTE 8 - -/* - * Broadcast Assist Unit messaging structures - * - * Selective Broadcast activations are induced by software action - * specifying a particular 8-descriptor "set" via a 6-bit index written - * to an MMR. - * Thus there are 64 unique 512-byte sets of SB descriptors - one set for - * each 6-bit index value. These descriptor sets are mapped in sequence - * starting with set 0 located at the address specified in the - * BAU_SB_DESCRIPTOR_BASE register, set 1 is located at BASE + 512, - * set 2 is at BASE + 2*512, set 3 at BASE + 3*512, and so on. - * - * We will use one set for sending BAU messages from each of the - * cpu's on the uvhub. - * - * TLB shootdown will use the first of the 8 descriptors of each set. - * Each of the descriptors is 64 bytes in size (8*64 = 512 bytes in a set). - */ - -#define MAX_CPUS_PER_UVHUB 128 -#define MAX_CPUS_PER_SOCKET 64 -#define ADP_SZ 64 /* hardware-provided max. */ -#define UV_CPUS_PER_AS 32 /* hardware-provided max. */ -#define ITEMS_PER_DESC 8 -/* the 'throttle' to prevent the hardware stay-busy bug */ -#define MAX_BAU_CONCURRENT 3 -#define UV_ACT_STATUS_MASK 0x3 -#define UV_ACT_STATUS_SIZE 2 -#define UV_DISTRIBUTION_SIZE 256 -#define UV_SW_ACK_NPENDING 8 -#define UV_NET_ENDPOINT_INTD 0x28 -#define UV_PAYLOADQ_GNODE_SHIFT 49 -#define UV_PTC_BASENAME "sgi_uv/ptc_statistics" -#define UV_BAU_BASENAME "sgi_uv/bau_tunables" -#define UV_BAU_TUNABLES_DIR "sgi_uv" -#define UV_BAU_TUNABLES_FILE "bau_tunables" -#define WHITESPACE " \t\n" -#define cpubit_isset(cpu, bau_local_cpumask) \ - test_bit((cpu), (bau_local_cpumask).bits) - -/* [19:16] SOFT_ACK timeout period 19: 1 is urgency 7 17:16 1 is multiplier */ -/* - * UV2: Bit 19 selects between - * (0): 10 microsecond timebase and - * (1): 80 microseconds - * we're using 560us - */ -#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD (15UL) -/* assuming UV3 is the same */ - -#define BAU_MISC_CONTROL_MULT_MASK 3 - -#define UVH_AGING_PRESCALE_SEL 0x000000b000UL -/* [30:28] URGENCY_7 an index into a table of times */ -#define BAU_URGENCY_7_SHIFT 28 -#define BAU_URGENCY_7_MASK 7 - -#define UVH_TRANSACTION_TIMEOUT 0x000000b200UL -/* [45:40] BAU - BAU transaction timeout select - a multiplier */ -#define BAU_TRANS_SHIFT 40 -#define BAU_TRANS_MASK 0x3f - -/* - * shorten some awkward names - */ -#define AS_PUSH_SHIFT UVH_LB_BAU_SB_ACTIVATION_CONTROL_PUSH_SHFT -#define SOFTACK_MSHIFT UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT -#define SOFTACK_PSHIFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT -#define SOFTACK_TIMEOUT_PERIOD UV_INTD_SOFT_ACK_TIMEOUT_PERIOD -#define PREFETCH_HINT_SHFT UV3H_LB_BAU_MISC_CONTROL_ENABLE_INTD_PREFETCH_HINT_SHFT -#define SB_STATUS_SHFT UV3H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT -#define write_gmmr uv_write_global_mmr64 -#define write_lmmr uv_write_local_mmr -#define read_lmmr uv_read_local_mmr -#define read_gmmr uv_read_global_mmr64 - -/* - * bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1 - */ -#define DS_IDLE 0 -#define DS_ACTIVE 1 -#define DS_DESTINATION_TIMEOUT 2 -#define DS_SOURCE_TIMEOUT 3 -/* - * bits put together from HRP_LB_BAU_SB_ACTIVATION_STATUS_0/1/2 - * values 1 and 3 will not occur - * Decoded meaning ERROR BUSY AUX ERR - * ------------------------------- ---- ----- ------- - * IDLE 0 0 0 - * BUSY (active) 0 1 0 - * SW Ack Timeout (destination) 1 0 0 - * SW Ack INTD rejected (strong NACK) 1 0 1 - * Source Side Time Out Detected 1 1 0 - * Destination Side PUT Failed 1 1 1 - */ -#define UV2H_DESC_IDLE 0 -#define UV2H_DESC_BUSY 2 -#define UV2H_DESC_DEST_TIMEOUT 4 -#define UV2H_DESC_DEST_STRONG_NACK 5 -#define UV2H_DESC_SOURCE_TIMEOUT 6 -#define UV2H_DESC_DEST_PUT_ERR 7 - -/* - * delay for 'plugged' timeout retries, in microseconds - */ -#define PLUGGED_DELAY 10 - -/* - * threshholds at which to use IPI to free resources - */ -/* after this # consecutive 'plugged' timeouts, use IPI to release resources */ -#define PLUGSB4RESET 100 -/* after this many consecutive timeouts, use IPI to release resources */ -#define TIMEOUTSB4RESET 1 -/* at this number uses of IPI to release resources, giveup the request */ -#define IPI_RESET_LIMIT 1 -/* after this # consecutive successes, bump up the throttle if it was lowered */ -#define COMPLETE_THRESHOLD 5 -/* after this # of giveups (fall back to kernel IPI's) disable the use of - the BAU for a period of time */ -#define GIVEUP_LIMIT 100 - -#define UV_LB_SUBNODEID 0x10 - -#define UV_SA_SHFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT -#define UV_SA_MASK UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK -/* 4 bits of software ack period */ -#define UV2_ACK_MASK 0x7UL -#define UV2_ACK_UNITS_SHFT 3 -#define UV2_EXT_SHFT UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT - -/* - * number of entries in the destination side payload queue - */ -#define DEST_Q_SIZE 20 -/* - * number of destination side software ack resources - */ -#define DEST_NUM_RESOURCES 8 -/* - * completion statuses for sending a TLB flush message - */ -#define FLUSH_RETRY_PLUGGED 1 -#define FLUSH_RETRY_TIMEOUT 2 -#define FLUSH_GIVEUP 3 -#define FLUSH_COMPLETE 4 - -/* - * tuning the action when the numalink network is extremely delayed - */ -#define CONGESTED_RESPONSE_US 1000 /* 'long' response time, in - microseconds */ -#define CONGESTED_REPS 10 /* long delays averaged over - this many broadcasts */ -#define DISABLED_PERIOD 10 /* time for the bau to be - disabled, in seconds */ -/* see msg_type: */ -#define MSG_NOOP 0 -#define MSG_REGULAR 1 -#define MSG_RETRY 2 - -#define BAU_DESC_QUALIFIER 0x534749 - -enum uv_bau_version { - UV_BAU_V2 = 2, - UV_BAU_V3, - UV_BAU_V4, -}; - -/* - * Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor) - * If the 'multilevel' flag in the header portion of the descriptor - * has been set to 0, then endpoint multi-unicast mode is selected. - * The distribution specification (32 bytes) is interpreted as a 256-bit - * distribution vector. Adjacent bits correspond to consecutive even numbered - * nodeIDs. The result of adding the index of a given bit to the 15-bit - * 'base_dest_nasid' field of the header corresponds to the - * destination nodeID associated with that specified bit. - */ -struct pnmask { - unsigned long bits[BITS_TO_LONGS(UV_DISTRIBUTION_SIZE)]; -}; - -/* - * mask of cpu's on a uvhub - * (during initialization we need to check that unsigned long has - * enough bits for max. cpu's per uvhub) - */ -struct bau_local_cpumask { - unsigned long bits; -}; - -/* - * Payload: 16 bytes (128 bits) (bytes 0x20-0x2f of descriptor) - * only 12 bytes (96 bits) of the payload area are usable. - * An additional 3 bytes (bits 27:4) of the header address are carried - * to the next bytes of the destination payload queue. - * And an additional 2 bytes of the header Suppl_A field are also - * carried to the destination payload queue. - * But the first byte of the Suppl_A becomes bits 127:120 (the 16th byte) - * of the destination payload queue, which is written by the hardware - * with the s/w ack resource bit vector. - * [ effective message contents (16 bytes (128 bits) maximum), not counting - * the s/w ack bit vector ] - */ - -/** - * struct uv2_3_bau_msg_payload - defines payload for INTD transactions - * @address: Signifies a page or all TLB's of the cpu - * @sending_cpu: CPU from which the message originates - * @acknowledge_count: CPUs on the destination Hub that received the interrupt - */ -struct uv2_3_bau_msg_payload { - u64 address; - u16 sending_cpu; - u16 acknowledge_count; -}; - -/** - * struct uv4_bau_msg_payload - defines payload for INTD transactions - * @address: Signifies a page or all TLB's of the cpu - * @sending_cpu: CPU from which the message originates - * @acknowledge_count: CPUs on the destination Hub that received the interrupt - * @qualifier: Set by source to verify origin of INTD broadcast - */ -struct uv4_bau_msg_payload { - u64 address; - u16 sending_cpu; - u16 acknowledge_count; - u32 reserved:8; - u32 qualifier:24; -}; - -/* - * UV2 Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor) - * see figure 9-2 of harp_sys.pdf - * assuming UV3 is the same - */ -struct uv2_3_bau_msg_header { - unsigned int base_dest_nasid:15; /* nasid of the first bit */ - /* bits 14:0 */ /* in uvhub map */ - unsigned int dest_subnodeid:5; /* must be 0x10, for the LB */ - /* bits 19:15 */ - unsigned int rsvd_1:1; /* must be zero */ - /* bit 20 */ - /* Address bits 59:21 */ - /* bits 25:2 of address (44:21) are payload */ - /* these next 24 bits become bytes 12-14 of msg */ - /* bits 28:21 land in byte 12 */ - unsigned int replied_to:1; /* sent as 0 by the source to - byte 12 */ - /* bit 21 */ - unsigned int msg_type:3; /* software type of the - message */ - /* bits 24:22 */ - unsigned int canceled:1; /* message canceled, resource - is to be freed*/ - /* bit 25 */ - unsigned int payload_1:3; /* not currently used */ - /* bits 28:26 */ - - /* bits 36:29 land in byte 13 */ - unsigned int payload_2a:3; /* not currently used */ - unsigned int payload_2b:5; /* not currently used */ - /* bits 36:29 */ - - /* bits 44:37 land in byte 14 */ - unsigned int payload_3:8; /* not currently used */ - /* bits 44:37 */ - - unsigned int rsvd_2:7; /* reserved */ - /* bits 51:45 */ - unsigned int swack_flag:1; /* software acknowledge flag */ - /* bit 52 */ - unsigned int rsvd_3a:3; /* must be zero */ - unsigned int rsvd_3b:8; /* must be zero */ - unsigned int rsvd_3c:8; /* must be zero */ - unsigned int rsvd_3d:3; /* must be zero */ - /* bits 74:53 */ - unsigned int fairness:3; /* usually zero */ - /* bits 77:75 */ - - unsigned int sequence:16; /* message sequence number */ - /* bits 93:78 Suppl_A */ - unsigned int chaining:1; /* next descriptor is part of - this activation*/ - /* bit 94 */ - unsigned int multilevel:1; /* multi-level multicast - format */ - /* bit 95 */ - unsigned int rsvd_4:24; /* ordered / source node / - source subnode / aging - must be zero */ - /* bits 119:96 */ - unsigned int command:8; /* message type */ - /* bits 127:120 */ -}; - -/* - * The activation descriptor: - * The format of the message to send, plus all accompanying control - * Should be 64 bytes - */ -struct bau_desc { - struct pnmask distribution; - /* - * message template, consisting of header and payload: - */ - union bau_msg_header { - struct uv2_3_bau_msg_header uv2_3_hdr; - } header; - - union bau_payload_header { - struct uv2_3_bau_msg_payload uv2_3; - struct uv4_bau_msg_payload uv4; - } payload; -}; -/* UV2: - * -payload-- ---------header------ - * bytes 0-11 bits 70-78 bits 21-44 - * A B (2) C (3) - * - * A/B/C are moved to: - * A C B - * bytes 0-11 bytes 12-14 bytes 16-17 (byte 15 filled in by hw as vector) - * ------------payload queue----------- - */ - -/* - * The payload queue on the destination side is an array of these. - * With BAU_MISC_CONTROL set for software acknowledge mode, the messages - * are 32 bytes (2 micropackets) (256 bits) in length, but contain only 17 - * bytes of usable data, including the sw ack vector in byte 15 (bits 127:120) - * (12 bytes come from bau_msg_payload, 3 from payload_1, 2 from - * swack_vec and payload_2) - * "Enabling Software Acknowledgment mode (see Section 4.3.3 Software - * Acknowledge Processing) also selects 32 byte (17 bytes usable) payload - * operation." - */ -struct bau_pq_entry { - unsigned long address; /* signifies a page or all TLB's - of the cpu */ - /* 64 bits, bytes 0-7 */ - unsigned short sending_cpu; /* cpu that sent the message */ - /* 16 bits, bytes 8-9 */ - unsigned short acknowledge_count; /* filled in by destination */ - /* 16 bits, bytes 10-11 */ - /* these next 3 bytes come from bits 58-81 of the message header */ - unsigned short replied_to:1; /* sent as 0 by the source */ - unsigned short msg_type:3; /* software message type */ - unsigned short canceled:1; /* sent as 0 by the source */ - unsigned short unused1:3; /* not currently using */ - /* byte 12 */ - unsigned char unused2a; /* not currently using */ - /* byte 13 */ - unsigned char unused2; /* not currently using */ - /* byte 14 */ - unsigned char swack_vec; /* filled in by the hardware */ - /* byte 15 (bits 127:120) */ - unsigned short sequence; /* message sequence number */ - /* bytes 16-17 */ - unsigned char unused4[2]; /* not currently using bytes 18-19 */ - /* bytes 18-19 */ - int number_of_cpus; /* filled in at destination */ - /* 32 bits, bytes 20-23 (aligned) */ - unsigned char unused5[8]; /* not using */ - /* bytes 24-31 */ -}; - -struct msg_desc { - struct bau_pq_entry *msg; - int msg_slot; - struct bau_pq_entry *queue_first; - struct bau_pq_entry *queue_last; -}; - -struct reset_args { - int sender; -}; - -/* - * This structure is allocated per_cpu for UV TLB shootdown statistics. - */ -struct ptc_stats { - /* sender statistics */ - unsigned long s_giveup; /* number of fall backs to - IPI-style flushes */ - unsigned long s_requestor; /* number of shootdown - requests */ - unsigned long s_stimeout; /* source side timeouts */ - unsigned long s_dtimeout; /* destination side timeouts */ - unsigned long s_strongnacks; /* number of strong nack's */ - unsigned long s_time; /* time spent in sending side */ - unsigned long s_retriesok; /* successful retries */ - unsigned long s_ntargcpu; /* total number of cpu's - targeted */ - unsigned long s_ntargself; /* times the sending cpu was - targeted */ - unsigned long s_ntarglocals; /* targets of cpus on the local - blade */ - unsigned long s_ntargremotes; /* targets of cpus on remote - blades */ - unsigned long s_ntarglocaluvhub; /* targets of the local hub */ - unsigned long s_ntargremoteuvhub; /* remotes hubs targeted */ - unsigned long s_ntarguvhub; /* total number of uvhubs - targeted */ - unsigned long s_ntarguvhub16; /* number of times target - hubs >= 16*/ - unsigned long s_ntarguvhub8; /* number of times target - hubs >= 8 */ - unsigned long s_ntarguvhub4; /* number of times target - hubs >= 4 */ - unsigned long s_ntarguvhub2; /* number of times target - hubs >= 2 */ - unsigned long s_ntarguvhub1; /* number of times target - hubs == 1 */ - unsigned long s_resets_plug; /* ipi-style resets from plug - state */ - unsigned long s_resets_timeout; /* ipi-style resets from - timeouts */ - unsigned long s_busy; /* status stayed busy past - s/w timer */ - unsigned long s_throttles; /* waits in throttle */ - unsigned long s_retry_messages; /* retry broadcasts */ - unsigned long s_bau_reenabled; /* for bau enable/disable */ - unsigned long s_bau_disabled; /* for bau enable/disable */ - unsigned long s_uv2_wars; /* uv2 workaround, perm. busy */ - unsigned long s_uv2_wars_hw; /* uv2 workaround, hiwater */ - unsigned long s_uv2_war_waits; /* uv2 workaround, long waits */ - unsigned long s_overipilimit; /* over the ipi reset limit */ - unsigned long s_giveuplimit; /* disables, over giveup limit*/ - unsigned long s_enters; /* entries to the driver */ - unsigned long s_ipifordisabled; /* fall back to IPI; disabled */ - unsigned long s_plugged; /* plugged by h/w bug*/ - unsigned long s_congested; /* giveup on long wait */ - /* destination statistics */ - unsigned long d_alltlb; /* times all tlb's on this - cpu were flushed */ - unsigned long d_onetlb; /* times just one tlb on this - cpu was flushed */ - unsigned long d_multmsg; /* interrupts with multiple - messages */ - unsigned long d_nomsg; /* interrupts with no message */ - unsigned long d_time; /* time spent on destination - side */ - unsigned long d_requestee; /* number of messages - processed */ - unsigned long d_retries; /* number of retry messages - processed */ - unsigned long d_canceled; /* number of messages canceled - by retries */ - unsigned long d_nocanceled; /* retries that found nothing - to cancel */ - unsigned long d_resets; /* number of ipi-style requests - processed */ - unsigned long d_rcanceled; /* number of messages canceled - by resets */ -}; - -struct tunables { - int *tunp; - int deflt; -}; - -struct hub_and_pnode { - short uvhub; - short pnode; -}; - -struct socket_desc { - short num_cpus; - short cpu_number[MAX_CPUS_PER_SOCKET]; -}; - -struct uvhub_desc { - unsigned short socket_mask; - short num_cpus; - short uvhub; - short pnode; - struct socket_desc socket[2]; -}; - -/** - * struct bau_control - * @status_mmr: location of status mmr, determined by uvhub_cpu - * @status_index: index of ERR|BUSY bits in status mmr, determined by uvhub_cpu - * - * Per-cpu control struct containing CPU topology information and BAU tuneables. - */ -struct bau_control { - struct bau_desc *descriptor_base; - struct bau_pq_entry *queue_first; - struct bau_pq_entry *queue_last; - struct bau_pq_entry *bau_msg_head; - struct bau_control *uvhub_master; - struct bau_control *socket_master; - struct ptc_stats *statp; - cpumask_t *cpumask; - unsigned long timeout_interval; - unsigned long set_bau_on_time; - atomic_t active_descriptor_count; - int plugged_tries; - int timeout_tries; - int ipi_attempts; - int conseccompletes; - u64 status_mmr; - int status_index; - bool nobau; - short baudisabled; - short cpu; - short osnode; - short uvhub_cpu; - short uvhub; - short uvhub_version; - short cpus_in_socket; - short cpus_in_uvhub; - short partition_base_pnode; - short busy; /* all were busy (war) */ - unsigned short message_number; - unsigned short uvhub_quiesce; - short socket_acknowledge_count[DEST_Q_SIZE]; - cycles_t send_message; - cycles_t period_end; - cycles_t period_time; - spinlock_t uvhub_lock; - spinlock_t queue_lock; - spinlock_t disable_lock; - /* tunables */ - int max_concurr; - int max_concurr_const; - int plugged_delay; - int plugsb4reset; - int timeoutsb4reset; - int ipi_reset_limit; - int complete_threshold; - int cong_response_us; - int cong_reps; - cycles_t disabled_period; - int period_giveups; - int giveup_limit; - long period_requests; - struct hub_and_pnode *thp; -}; - -/* Abstracted BAU functions */ -struct bau_operations { - unsigned long (*read_l_sw_ack)(void); - unsigned long (*read_g_sw_ack)(int pnode); - unsigned long (*bau_gpa_to_offset)(unsigned long vaddr); - void (*write_l_sw_ack)(unsigned long mmr); - void (*write_g_sw_ack)(int pnode, unsigned long mmr); - void (*write_payload_first)(int pnode, unsigned long mmr); - void (*write_payload_last)(int pnode, unsigned long mmr); - int (*wait_completion)(struct bau_desc*, - struct bau_control*, long try); -}; - -static inline void write_mmr_data_broadcast(int pnode, unsigned long mmr_image) -{ - write_gmmr(pnode, UVH_BAU_DATA_BROADCAST, mmr_image); -} - -static inline void write_mmr_descriptor_base(int pnode, unsigned long mmr_image) -{ - write_gmmr(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, mmr_image); -} - -static inline void write_mmr_activation(unsigned long index) -{ - write_lmmr(UVH_LB_BAU_SB_ACTIVATION_CONTROL, index); -} - -static inline void write_gmmr_activation(int pnode, unsigned long mmr_image) -{ - write_gmmr(pnode, UVH_LB_BAU_SB_ACTIVATION_CONTROL, mmr_image); -} - -static inline void write_mmr_proc_payload_first(int pnode, unsigned long mmr_image) -{ - write_gmmr(pnode, UV4H_LB_PROC_INTD_QUEUE_FIRST, mmr_image); -} - -static inline void write_mmr_proc_payload_last(int pnode, unsigned long mmr_image) -{ - write_gmmr(pnode, UV4H_LB_PROC_INTD_QUEUE_LAST, mmr_image); -} - -static inline void write_mmr_payload_first(int pnode, unsigned long mmr_image) -{ - write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST, mmr_image); -} - -static inline void write_mmr_payload_tail(int pnode, unsigned long mmr_image) -{ - write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL, mmr_image); -} - -static inline void write_mmr_payload_last(int pnode, unsigned long mmr_image) -{ - write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST, mmr_image); -} - -static inline void write_mmr_misc_control(int pnode, unsigned long mmr_image) -{ - write_gmmr(pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); -} - -static inline unsigned long read_mmr_misc_control(int pnode) -{ - return read_gmmr(pnode, UVH_LB_BAU_MISC_CONTROL); -} - -static inline void write_mmr_sw_ack(unsigned long mr) -{ - uv_write_local_mmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, mr); -} - -static inline void write_gmmr_sw_ack(int pnode, unsigned long mr) -{ - write_gmmr(pnode, UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, mr); -} - -static inline unsigned long read_mmr_sw_ack(void) -{ - return read_lmmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); -} - -static inline unsigned long read_gmmr_sw_ack(int pnode) -{ - return read_gmmr(pnode, UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); -} - -static inline void write_mmr_proc_sw_ack(unsigned long mr) -{ - uv_write_local_mmr(UV4H_LB_PROC_INTD_SOFT_ACK_CLEAR, mr); -} - -static inline void write_gmmr_proc_sw_ack(int pnode, unsigned long mr) -{ - write_gmmr(pnode, UV4H_LB_PROC_INTD_SOFT_ACK_CLEAR, mr); -} - -static inline unsigned long read_mmr_proc_sw_ack(void) -{ - return read_lmmr(UV4H_LB_PROC_INTD_SOFT_ACK_PENDING); -} - -static inline unsigned long read_gmmr_proc_sw_ack(int pnode) -{ - return read_gmmr(pnode, UV4H_LB_PROC_INTD_SOFT_ACK_PENDING); -} - -static inline void write_mmr_data_config(int pnode, unsigned long mr) -{ - uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, mr); -} - -static inline int bau_uvhub_isset(int uvhub, struct pnmask *dstp) -{ - return constant_test_bit(uvhub, &dstp->bits[0]); -} -static inline void bau_uvhub_set(int pnode, struct pnmask *dstp) -{ - __set_bit(pnode, &dstp->bits[0]); -} -static inline void bau_uvhubs_clear(struct pnmask *dstp, - int nbits) -{ - bitmap_zero(&dstp->bits[0], nbits); -} -static inline int bau_uvhub_weight(struct pnmask *dstp) -{ - return bitmap_weight((unsigned long *)&dstp->bits[0], - UV_DISTRIBUTION_SIZE); -} - -static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits) -{ - bitmap_zero(&dstp->bits, nbits); -} - -struct atomic_short { - short counter; -}; - -/* - * atomic_read_short - read a short atomic variable - * @v: pointer of type atomic_short - * - * Atomically reads the value of @v. - */ -static inline int atomic_read_short(const struct atomic_short *v) -{ - return v->counter; -} - -/* - * atom_asr - add and return a short int - * @i: short value to add - * @v: pointer of type atomic_short - * - * Atomically adds @i to @v and returns @i + @v - */ -static inline int atom_asr(short i, struct atomic_short *v) -{ - short __i = i; - asm volatile(LOCK_PREFIX "xaddw %0, %1" - : "+r" (i), "+m" (v->counter) - : : "memory"); - return i + __i; -} - -/* - * conditionally add 1 to *v, unless *v is >= u - * return 0 if we cannot add 1 to *v because it is >= u - * return 1 if we can add 1 to *v because it is < u - * the add is atomic - * - * This is close to atomic_add_unless(), but this allows the 'u' value - * to be lowered below the current 'v'. atomic_add_unless can only stop - * on equal. - */ -static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u) -{ - spin_lock(lock); - if (atomic_read(v) >= u) { - spin_unlock(lock); - return 0; - } - atomic_inc(v); - spin_unlock(lock); - return 1; -} - -void uv_bau_message_interrupt(struct pt_regs *regs); - -#endif /* _ASM_X86_UV_UV_BAU_H */ diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h index 100d66806503..5002f52be332 100644 --- a/arch/x86/include/asm/uv/uv_hub.h +++ b/arch/x86/include/asm/uv/uv_hub.h @@ -5,6 +5,7 @@ * * SGI UV architectural definitions * + * (C) Copyright 2020 Hewlett Packard Enterprise Development LP * Copyright (C) 2007-2014 Silicon Graphics, Inc. All rights reserved. */ @@ -129,17 +130,6 @@ */ #define UV_MAX_NASID_VALUE (UV_MAX_NUMALINK_BLADES * 2) -/* System Controller Interface Reg info */ -struct uv_scir_s { - struct timer_list timer; - unsigned long offset; - unsigned long last; - unsigned long idle_on; - unsigned long idle_off; - unsigned char state; - unsigned char enabled; -}; - /* GAM (globally addressed memory) range table */ struct uv_gam_range_s { u32 limit; /* PA bits 56:26 (GAM_RANGE_SHFT) */ @@ -155,6 +145,8 @@ struct uv_gam_range_s { * available in the L3 cache on the cpu socket for the node. */ struct uv_hub_info_s { + unsigned int hub_type; + unsigned char hub_revision; unsigned long global_mmr_base; unsigned long global_mmr_shift; unsigned long gpa_mask; @@ -167,9 +159,9 @@ struct uv_hub_info_s { unsigned char m_val; unsigned char n_val; unsigned char gr_table_len; - unsigned char hub_revision; unsigned char apic_pnode_shift; unsigned char gpa_shift; + unsigned char nasid_shift; unsigned char m_shift; unsigned char n_lshift; unsigned int gnode_extra; @@ -191,16 +183,13 @@ struct uv_hub_info_s { struct uv_cpu_info_s { void *p_uv_hub_info; unsigned char blade_cpu_id; - struct uv_scir_s scir; + void *reserved; }; DECLARE_PER_CPU(struct uv_cpu_info_s, __uv_cpu_info); #define uv_cpu_info this_cpu_ptr(&__uv_cpu_info) #define uv_cpu_info_per(cpu) (&per_cpu(__uv_cpu_info, cpu)) -#define uv_scir_info (&uv_cpu_info->scir) -#define uv_cpu_scir_info(cpu) (&uv_cpu_info_per(cpu)->scir) - /* Node specific hub common info struct */ extern void **__uv_hub_info_list; static inline struct uv_hub_info_s *uv_hub_info_list(int node) @@ -219,6 +208,17 @@ static inline struct uv_hub_info_s *uv_cpu_hub_info(int cpu) return (struct uv_hub_info_s *)uv_cpu_info_per(cpu)->p_uv_hub_info; } +static inline int uv_hub_type(void) +{ + return uv_hub_info->hub_type; +} + +static inline __init void uv_hub_type_set(int uvmask) +{ + uv_hub_info->hub_type = uvmask; +} + + /* * HUB revision ranges for each UV HUB architecture. * This is a software convention - NOT the hardware revision numbers in @@ -228,39 +228,31 @@ static inline struct uv_hub_info_s *uv_cpu_hub_info(int cpu) #define UV3_HUB_REVISION_BASE 5 #define UV4_HUB_REVISION_BASE 7 #define UV4A_HUB_REVISION_BASE 8 /* UV4 (fixed) rev 2 */ +#define UV5_HUB_REVISION_BASE 9 -static inline int is_uv2_hub(void) -{ - return is_uv_hubbed(uv(2)); -} - -static inline int is_uv3_hub(void) -{ - return is_uv_hubbed(uv(3)); -} +static inline int is_uv(int uvmask) { return uv_hub_type() & uvmask; } +static inline int is_uv1_hub(void) { return 0; } +static inline int is_uv2_hub(void) { return is_uv(UV2); } +static inline int is_uv3_hub(void) { return is_uv(UV3); } +static inline int is_uv4a_hub(void) { return is_uv(UV4A); } +static inline int is_uv4_hub(void) { return is_uv(UV4); } +static inline int is_uv5_hub(void) { return is_uv(UV5); } -/* First test "is UV4A", then "is UV4" */ -static inline int is_uv4a_hub(void) -{ - if (is_uv_hubbed(uv(4))) - return (uv_hub_info->hub_revision == UV4A_HUB_REVISION_BASE); - return 0; -} +/* + * UV4A is a revision of UV4. So on UV4A, both is_uv4_hub() and + * is_uv4a_hub() return true, While on UV4, only is_uv4_hub() + * returns true. So to get true results, first test if is UV4A, + * then test if is UV4. + */ -static inline int is_uv4_hub(void) -{ - return is_uv_hubbed(uv(4)); -} +/* UVX class: UV2,3,4 */ +static inline int is_uvx_hub(void) { return is_uv(UVX); } -static inline int is_uvx_hub(void) -{ - return (is_uv_hubbed(-2) >= uv(2)); -} +/* UVY class: UV5,..? */ +static inline int is_uvy_hub(void) { return is_uv(UVY); } -static inline int is_uv_hub(void) -{ - return is_uvx_hub(); -} +/* Any UV Hubbed System */ +static inline int is_uv_hub(void) { return is_uv(UV_ANY); } union uvh_apicid { unsigned long v; @@ -282,9 +274,11 @@ union uvh_apicid { * g - GNODE (full 15-bit global nasid, right shifted 1) * p - PNODE (local part of nsids, right shifted 1) */ -#define UV_NASID_TO_PNODE(n) (((n) >> 1) & uv_hub_info->pnode_mask) +#define UV_NASID_TO_PNODE(n) \ + (((n) >> uv_hub_info->nasid_shift) & uv_hub_info->pnode_mask) #define UV_PNODE_TO_GNODE(p) ((p) |uv_hub_info->gnode_extra) -#define UV_PNODE_TO_NASID(p) (UV_PNODE_TO_GNODE(p) << 1) +#define UV_PNODE_TO_NASID(p) \ + (UV_PNODE_TO_GNODE(p) << uv_hub_info->nasid_shift) #define UV2_LOCAL_MMR_BASE 0xfa000000UL #define UV2_GLOBAL_MMR32_BASE 0xfc000000UL @@ -297,29 +291,42 @@ union uvh_apicid { #define UV3_GLOBAL_MMR32_SIZE (32UL * 1024 * 1024) #define UV4_LOCAL_MMR_BASE 0xfa000000UL -#define UV4_GLOBAL_MMR32_BASE 0xfc000000UL +#define UV4_GLOBAL_MMR32_BASE 0 #define UV4_LOCAL_MMR_SIZE (32UL * 1024 * 1024) -#define UV4_GLOBAL_MMR32_SIZE (16UL * 1024 * 1024) +#define UV4_GLOBAL_MMR32_SIZE 0 + +#define UV5_LOCAL_MMR_BASE 0xfa000000UL +#define UV5_GLOBAL_MMR32_BASE 0 +#define UV5_LOCAL_MMR_SIZE (32UL * 1024 * 1024) +#define UV5_GLOBAL_MMR32_SIZE 0 #define UV_LOCAL_MMR_BASE ( \ - is_uv2_hub() ? UV2_LOCAL_MMR_BASE : \ - is_uv3_hub() ? UV3_LOCAL_MMR_BASE : \ - /*is_uv4_hub*/ UV4_LOCAL_MMR_BASE) + is_uv(UV2) ? UV2_LOCAL_MMR_BASE : \ + is_uv(UV3) ? UV3_LOCAL_MMR_BASE : \ + is_uv(UV4) ? UV4_LOCAL_MMR_BASE : \ + is_uv(UV5) ? UV5_LOCAL_MMR_BASE : \ + 0) #define UV_GLOBAL_MMR32_BASE ( \ - is_uv2_hub() ? UV2_GLOBAL_MMR32_BASE : \ - is_uv3_hub() ? UV3_GLOBAL_MMR32_BASE : \ - /*is_uv4_hub*/ UV4_GLOBAL_MMR32_BASE) + is_uv(UV2) ? UV2_GLOBAL_MMR32_BASE : \ + is_uv(UV3) ? UV3_GLOBAL_MMR32_BASE : \ + is_uv(UV4) ? UV4_GLOBAL_MMR32_BASE : \ + is_uv(UV5) ? UV5_GLOBAL_MMR32_BASE : \ + 0) #define UV_LOCAL_MMR_SIZE ( \ - is_uv2_hub() ? UV2_LOCAL_MMR_SIZE : \ - is_uv3_hub() ? UV3_LOCAL_MMR_SIZE : \ - /*is_uv4_hub*/ UV4_LOCAL_MMR_SIZE) + is_uv(UV2) ? UV2_LOCAL_MMR_SIZE : \ + is_uv(UV3) ? UV3_LOCAL_MMR_SIZE : \ + is_uv(UV4) ? UV4_LOCAL_MMR_SIZE : \ + is_uv(UV5) ? UV5_LOCAL_MMR_SIZE : \ + 0) #define UV_GLOBAL_MMR32_SIZE ( \ - is_uv2_hub() ? UV2_GLOBAL_MMR32_SIZE : \ - is_uv3_hub() ? UV3_GLOBAL_MMR32_SIZE : \ - /*is_uv4_hub*/ UV4_GLOBAL_MMR32_SIZE) + is_uv(UV2) ? UV2_GLOBAL_MMR32_SIZE : \ + is_uv(UV3) ? UV3_GLOBAL_MMR32_SIZE : \ + is_uv(UV4) ? UV4_GLOBAL_MMR32_SIZE : \ + is_uv(UV5) ? UV5_GLOBAL_MMR32_SIZE : \ + 0) #define UV_GLOBAL_MMR64_BASE (uv_hub_info->global_mmr_base) @@ -720,7 +727,7 @@ extern void uv_nmi_setup_hubless(void); #define UVH_TSC_SYNC_SHIFT_UV2K 16 /* UV2/3k have different bits */ #define UVH_TSC_SYNC_MASK 3 /* 0011 */ #define UVH_TSC_SYNC_VALID 3 /* 0011 */ -#define UVH_TSC_SYNC_INVALID 2 /* 0010 */ +#define UVH_TSC_SYNC_UNKNOWN 0 /* 0000 */ /* BMC sets a bit this MMR non-zero before sending an NMI */ #define UVH_NMI_MMR UVH_BIOS_KERNEL_MMR @@ -728,19 +735,6 @@ extern void uv_nmi_setup_hubless(void); #define UVH_NMI_MMR_SHIFT 63 #define UVH_NMI_MMR_TYPE "SCRATCH5" -/* Newer SMM NMI handler, not present in all systems */ -#define UVH_NMI_MMRX UVH_EVENT_OCCURRED0 -#define UVH_NMI_MMRX_CLEAR UVH_EVENT_OCCURRED0_ALIAS -#define UVH_NMI_MMRX_SHIFT UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT -#define UVH_NMI_MMRX_TYPE "EXTIO_INT0" - -/* Non-zero indicates newer SMM NMI handler present */ -#define UVH_NMI_MMRX_SUPPORTED UVH_EXTIO_INT0_BROADCAST - -/* Indicates to BIOS that we want to use the newer SMM NMI handler */ -#define UVH_NMI_MMRX_REQ UVH_BIOS_KERNEL_MMR_ALIAS_2 -#define UVH_NMI_MMRX_REQ_SHIFT 62 - struct uv_hub_nmi_s { raw_spinlock_t nmi_lock; atomic_t in_nmi; /* flag this node in UV NMI IRQ */ @@ -772,29 +766,6 @@ DECLARE_PER_CPU(struct uv_cpu_nmi_s, uv_cpu_nmi); #define UV_NMI_STATE_DUMP 2 #define UV_NMI_STATE_DUMP_DONE 3 -/* Update SCIR state */ -static inline void uv_set_scir_bits(unsigned char value) -{ - if (uv_scir_info->state != value) { - uv_scir_info->state = value; - uv_write_local_mmr8(uv_scir_info->offset, value); - } -} - -static inline unsigned long uv_scir_offset(int apicid) -{ - return SCIR_LOCAL_MMR_BASE | (apicid & 0x3f); -} - -static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value) -{ - if (uv_cpu_scir_info(cpu)->state != value) { - uv_write_global_mmr8(uv_cpu_to_pnode(cpu), - uv_cpu_scir_info(cpu)->offset, value); - uv_cpu_scir_info(cpu)->state = value; - } -} - /* * Get the minimum revision number of the hub chips within the partition. * (See UVx_HUB_REVISION_BASE above for specific values.) diff --git a/arch/x86/include/asm/uv/uv_mmrs.h b/arch/x86/include/asm/uv/uv_mmrs.h index 775bf143a072..57fa67373262 100644 --- a/arch/x86/include/asm/uv/uv_mmrs.h +++ b/arch/x86/include/asm/uv/uv_mmrs.h @@ -3,8 +3,9 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * SGI UV MMR definitions + * HPE UV MMR definitions * + * (C) Copyright 2020 Hewlett Packard Enterprise Development LP * Copyright (C) 2007-2016 Silicon Graphics, Inc. All rights reserved. */ @@ -18,42 +19,43 @@ * grouped by architecture types. * * UVH - definitions common to all UV hub types. - * UVXH - definitions common to all UV eXtended hub types (currently 2, 3, 4). - * UV2H - definitions specific to UV type 2 hub. - * UV3H - definitions specific to UV type 3 hub. + * UVXH - definitions common to UVX class (2, 3, 4). + * UVYH - definitions common to UVY class (5). + * UV5H - definitions specific to UV type 5 hub. + * UV4AH - definitions specific to UV type 4A hub. * UV4H - definitions specific to UV type 4 hub. - * - * So in general, MMR addresses and structures are identical on all hubs types. - * These MMRs are identified as: - * #define UVH_xxx <address> - * union uvh_xxx { - * unsigned long v; - * struct uvh_int_cmpd_s { - * } s; - * }; + * UV3H - definitions specific to UV type 3 hub. + * UV2H - definitions specific to UV type 2 hub. * * If the MMR exists on all hub types but have different addresses, - * use a conditional operator to define the value at runtime. - * #define UV2Hxxx b - * #define UV3Hxxx c - * #define UV4Hxxx d - * #define UV4AHxxx e - * #define UVHxxx (is_uv2_hub() ? UV2Hxxx : - * (is_uv3_hub() ? UV3Hxxx : - * (is_uv4a_hub() ? UV4AHxxx : - * UV4Hxxx)) + * use a conditional operator to define the value at runtime. Any + * that are not defined are blank. + * (UV4A variations only generated if different from uv4) + * #define UVHxxx ( + * is_uv(UV5) ? UV5Hxxx value : + * is_uv(UV4A) ? UV4AHxxx value : + * is_uv(UV4) ? UV4Hxxx value : + * is_uv(UV3) ? UV3Hxxx value : + * is_uv(UV2) ? UV2Hxxx value : + * <ucv> or <undef value>) + * + * Class UVX has UVs (2|3|4|4A). + * Class UVY has UVs (5). * * union uvh_xxx { * unsigned long v; * struct uvh_xxx_s { # Common fields only * } s; - * struct uv2h_xxx_s { # Full UV2 definition (*) - * } s2; - * struct uv3h_xxx_s { # Full UV3 definition (*) - * } s3; - * (NOTE: No struct uv4ah_xxx_s members exist) + * struct uv5h_xxx_s { # Full UV5 definition (*) + * } s5; + * struct uv4ah_xxx_s { # Full UV4A definition (*) + * } s4a; * struct uv4h_xxx_s { # Full UV4 definition (*) * } s4; + * struct uv3h_xxx_s { # Full UV3 definition (*) + * } s3; + * struct uv2h_xxx_s { # Full UV2 definition (*) + * } s2; * }; * (* - if present and different than the common struct) * @@ -62,429 +64,499 @@ * if the contents is the same for all hubs, only the "s" structure is * generated. * - * If the MMR exists on ONLY 1 type of hub, no generic definition is - * generated: - * #define UVnH_xxx <uvn address> - * union uvnh_xxx { - * unsigned long v; - * struct uvh_int_cmpd_s { - * } sn; - * }; - * - * (GEN Flags: mflags_opt= undefs=function UV234=UVXH) + * (GEN Flags: undefs=function) */ + /* UV bit masks */ +#define UV2 (1 << 0) +#define UV3 (1 << 1) +#define UV4 (1 << 2) +#define UV4A (1 << 3) +#define UV5 (1 << 4) +#define UVX (UV2|UV3|UV4) +#define UVY (UV5) +#define UV_ANY (~0) + + + + #define UV_MMR_ENABLE (1UL << 63) +#define UV1_HUB_PART_NUMBER 0x88a5 #define UV2_HUB_PART_NUMBER 0x8eb8 #define UV2_HUB_PART_NUMBER_X 0x1111 #define UV3_HUB_PART_NUMBER 0x9578 #define UV3_HUB_PART_NUMBER_X 0x4321 #define UV4_HUB_PART_NUMBER 0x99a1 +#define UV5_HUB_PART_NUMBER 0xa171 /* Error function to catch undefined references */ extern unsigned long uv_undefined(char *str); /* ========================================================================= */ -/* UVH_BAU_DATA_BROADCAST */ -/* ========================================================================= */ -#define UVH_BAU_DATA_BROADCAST 0x61688UL - -#define UV2H_BAU_DATA_BROADCAST_32 0x440 -#define UV3H_BAU_DATA_BROADCAST_32 0x440 -#define UV4H_BAU_DATA_BROADCAST_32 0x360 -#define UVH_BAU_DATA_BROADCAST_32 ( \ - is_uv2_hub() ? UV2H_BAU_DATA_BROADCAST_32 : \ - is_uv3_hub() ? UV3H_BAU_DATA_BROADCAST_32 : \ - /*is_uv4_hub*/ UV4H_BAU_DATA_BROADCAST_32) - -#define UVH_BAU_DATA_BROADCAST_ENABLE_SHFT 0 -#define UVH_BAU_DATA_BROADCAST_ENABLE_MASK 0x0000000000000001UL - - -union uvh_bau_data_broadcast_u { - unsigned long v; - struct uvh_bau_data_broadcast_s { - unsigned long enable:1; /* RW */ - unsigned long rsvd_1_63:63; - } s; -}; - -/* ========================================================================= */ -/* UVH_BAU_DATA_CONFIG */ -/* ========================================================================= */ -#define UVH_BAU_DATA_CONFIG 0x61680UL - -#define UV2H_BAU_DATA_CONFIG_32 0x438 -#define UV3H_BAU_DATA_CONFIG_32 0x438 -#define UV4H_BAU_DATA_CONFIG_32 0x358 -#define UVH_BAU_DATA_CONFIG_32 ( \ - is_uv2_hub() ? UV2H_BAU_DATA_CONFIG_32 : \ - is_uv3_hub() ? UV3H_BAU_DATA_CONFIG_32 : \ - /*is_uv4_hub*/ UV4H_BAU_DATA_CONFIG_32) - -#define UVH_BAU_DATA_CONFIG_VECTOR_SHFT 0 -#define UVH_BAU_DATA_CONFIG_DM_SHFT 8 -#define UVH_BAU_DATA_CONFIG_DESTMODE_SHFT 11 -#define UVH_BAU_DATA_CONFIG_STATUS_SHFT 12 -#define UVH_BAU_DATA_CONFIG_P_SHFT 13 -#define UVH_BAU_DATA_CONFIG_T_SHFT 15 -#define UVH_BAU_DATA_CONFIG_M_SHFT 16 -#define UVH_BAU_DATA_CONFIG_APIC_ID_SHFT 32 -#define UVH_BAU_DATA_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_BAU_DATA_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_BAU_DATA_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_BAU_DATA_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_BAU_DATA_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_BAU_DATA_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_BAU_DATA_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_BAU_DATA_CONFIG_APIC_ID_MASK 0xffffffff00000000UL - - -union uvh_bau_data_config_u { - unsigned long v; - struct uvh_bau_data_config_s { - unsigned long vector_:8; /* RW */ - unsigned long dm:3; /* RW */ - unsigned long destmode:1; /* RW */ - unsigned long status:1; /* RO */ - unsigned long p:1; /* RO */ - unsigned long rsvd_14:1; - unsigned long t:1; /* RO */ - unsigned long m:1; /* RW */ - unsigned long rsvd_17_31:15; - unsigned long apic_id:32; /* RW */ - } s; -}; - -/* ========================================================================= */ /* UVH_EVENT_OCCURRED0 */ /* ========================================================================= */ #define UVH_EVENT_OCCURRED0 0x70000UL -#define UVH_EVENT_OCCURRED0_32 0x5e8 +/* UVH common defines*/ #define UVH_EVENT_OCCURRED0_LB_HCERR_SHFT 0 -#define UVH_EVENT_OCCURRED0_RH_AOERR0_SHFT 11 #define UVH_EVENT_OCCURRED0_LB_HCERR_MASK 0x0000000000000001UL -#define UVH_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL +/* UVXH common defines */ #define UVXH_EVENT_OCCURRED0_RH_HCERR_SHFT 2 -#define UVXH_EVENT_OCCURRED0_LH0_HCERR_SHFT 3 -#define UVXH_EVENT_OCCURRED0_LH1_HCERR_SHFT 4 -#define UVXH_EVENT_OCCURRED0_GR0_HCERR_SHFT 5 -#define UVXH_EVENT_OCCURRED0_GR1_HCERR_SHFT 6 -#define UVXH_EVENT_OCCURRED0_NI0_HCERR_SHFT 7 -#define UVXH_EVENT_OCCURRED0_NI1_HCERR_SHFT 8 -#define UVXH_EVENT_OCCURRED0_LB_AOERR0_SHFT 9 -#define UVXH_EVENT_OCCURRED0_LH0_AOERR0_SHFT 12 -#define UVXH_EVENT_OCCURRED0_LH1_AOERR0_SHFT 13 -#define UVXH_EVENT_OCCURRED0_GR0_AOERR0_SHFT 14 -#define UVXH_EVENT_OCCURRED0_GR1_AOERR0_SHFT 15 -#define UVXH_EVENT_OCCURRED0_XB_AOERR0_SHFT 16 #define UVXH_EVENT_OCCURRED0_RH_HCERR_MASK 0x0000000000000004UL +#define UVXH_EVENT_OCCURRED0_LH0_HCERR_SHFT 3 #define UVXH_EVENT_OCCURRED0_LH0_HCERR_MASK 0x0000000000000008UL +#define UVXH_EVENT_OCCURRED0_LH1_HCERR_SHFT 4 #define UVXH_EVENT_OCCURRED0_LH1_HCERR_MASK 0x0000000000000010UL +#define UVXH_EVENT_OCCURRED0_GR0_HCERR_SHFT 5 #define UVXH_EVENT_OCCURRED0_GR0_HCERR_MASK 0x0000000000000020UL +#define UVXH_EVENT_OCCURRED0_GR1_HCERR_SHFT 6 #define UVXH_EVENT_OCCURRED0_GR1_HCERR_MASK 0x0000000000000040UL +#define UVXH_EVENT_OCCURRED0_NI0_HCERR_SHFT 7 #define UVXH_EVENT_OCCURRED0_NI0_HCERR_MASK 0x0000000000000080UL +#define UVXH_EVENT_OCCURRED0_NI1_HCERR_SHFT 8 #define UVXH_EVENT_OCCURRED0_NI1_HCERR_MASK 0x0000000000000100UL +#define UVXH_EVENT_OCCURRED0_LB_AOERR0_SHFT 9 #define UVXH_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000000200UL +#define UVXH_EVENT_OCCURRED0_RH_AOERR0_SHFT 11 +#define UVXH_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL +#define UVXH_EVENT_OCCURRED0_LH0_AOERR0_SHFT 12 #define UVXH_EVENT_OCCURRED0_LH0_AOERR0_MASK 0x0000000000001000UL +#define UVXH_EVENT_OCCURRED0_LH1_AOERR0_SHFT 13 #define UVXH_EVENT_OCCURRED0_LH1_AOERR0_MASK 0x0000000000002000UL +#define UVXH_EVENT_OCCURRED0_GR0_AOERR0_SHFT 14 #define UVXH_EVENT_OCCURRED0_GR0_AOERR0_MASK 0x0000000000004000UL +#define UVXH_EVENT_OCCURRED0_GR1_AOERR0_SHFT 15 #define UVXH_EVENT_OCCURRED0_GR1_AOERR0_MASK 0x0000000000008000UL +#define UVXH_EVENT_OCCURRED0_XB_AOERR0_SHFT 16 #define UVXH_EVENT_OCCURRED0_XB_AOERR0_MASK 0x0000000000010000UL -#define UV2H_EVENT_OCCURRED0_QP_HCERR_SHFT 1 -#define UV2H_EVENT_OCCURRED0_QP_AOERR0_SHFT 10 -#define UV2H_EVENT_OCCURRED0_RT_AOERR0_SHFT 17 -#define UV2H_EVENT_OCCURRED0_NI0_AOERR0_SHFT 18 -#define UV2H_EVENT_OCCURRED0_NI1_AOERR0_SHFT 19 -#define UV2H_EVENT_OCCURRED0_LB_AOERR1_SHFT 20 -#define UV2H_EVENT_OCCURRED0_QP_AOERR1_SHFT 21 -#define UV2H_EVENT_OCCURRED0_RH_AOERR1_SHFT 22 -#define UV2H_EVENT_OCCURRED0_LH0_AOERR1_SHFT 23 -#define UV2H_EVENT_OCCURRED0_LH1_AOERR1_SHFT 24 -#define UV2H_EVENT_OCCURRED0_GR0_AOERR1_SHFT 25 -#define UV2H_EVENT_OCCURRED0_GR1_AOERR1_SHFT 26 -#define UV2H_EVENT_OCCURRED0_XB_AOERR1_SHFT 27 -#define UV2H_EVENT_OCCURRED0_RT_AOERR1_SHFT 28 -#define UV2H_EVENT_OCCURRED0_NI0_AOERR1_SHFT 29 -#define UV2H_EVENT_OCCURRED0_NI1_AOERR1_SHFT 30 -#define UV2H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 31 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 32 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 33 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 34 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 35 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 36 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 37 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 38 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 39 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 40 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 41 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 42 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 43 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 44 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 45 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 46 -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 47 -#define UV2H_EVENT_OCCURRED0_L1_NMI_INT_SHFT 48 -#define UV2H_EVENT_OCCURRED0_STOP_CLOCK_SHFT 49 -#define UV2H_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 50 -#define UV2H_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 51 -#define UV2H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 52 -#define UV2H_EVENT_OCCURRED0_IPI_INT_SHFT 53 -#define UV2H_EVENT_OCCURRED0_EXTIO_INT0_SHFT 54 -#define UV2H_EVENT_OCCURRED0_EXTIO_INT1_SHFT 55 -#define UV2H_EVENT_OCCURRED0_EXTIO_INT2_SHFT 56 -#define UV2H_EVENT_OCCURRED0_EXTIO_INT3_SHFT 57 -#define UV2H_EVENT_OCCURRED0_PROFILE_INT_SHFT 58 -#define UV2H_EVENT_OCCURRED0_QP_HCERR_MASK 0x0000000000000002UL -#define UV2H_EVENT_OCCURRED0_QP_AOERR0_MASK 0x0000000000000400UL -#define UV2H_EVENT_OCCURRED0_RT_AOERR0_MASK 0x0000000000020000UL -#define UV2H_EVENT_OCCURRED0_NI0_AOERR0_MASK 0x0000000000040000UL -#define UV2H_EVENT_OCCURRED0_NI1_AOERR0_MASK 0x0000000000080000UL -#define UV2H_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000100000UL -#define UV2H_EVENT_OCCURRED0_QP_AOERR1_MASK 0x0000000000200000UL -#define UV2H_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000400000UL -#define UV2H_EVENT_OCCURRED0_LH0_AOERR1_MASK 0x0000000000800000UL -#define UV2H_EVENT_OCCURRED0_LH1_AOERR1_MASK 0x0000000001000000UL -#define UV2H_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000002000000UL -#define UV2H_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000004000000UL -#define UV2H_EVENT_OCCURRED0_XB_AOERR1_MASK 0x0000000008000000UL -#define UV2H_EVENT_OCCURRED0_RT_AOERR1_MASK 0x0000000010000000UL -#define UV2H_EVENT_OCCURRED0_NI0_AOERR1_MASK 0x0000000020000000UL -#define UV2H_EVENT_OCCURRED0_NI1_AOERR1_MASK 0x0000000040000000UL -#define UV2H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000080000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000100000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000200000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000400000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000800000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000001000000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000002000000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000004000000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000008000000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000010000000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000020000000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000040000000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000080000000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000100000000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000200000000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000400000000000UL -#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000800000000000UL -#define UV2H_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0001000000000000UL -#define UV2H_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0002000000000000UL -#define UV2H_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0004000000000000UL -#define UV2H_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0008000000000000UL -#define UV2H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0010000000000000UL -#define UV2H_EVENT_OCCURRED0_IPI_INT_MASK 0x0020000000000000UL -#define UV2H_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0040000000000000UL -#define UV2H_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0080000000000000UL -#define UV2H_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0100000000000000UL -#define UV2H_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0200000000000000UL -#define UV2H_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0400000000000000UL - -#define UV3H_EVENT_OCCURRED0_QP_HCERR_SHFT 1 -#define UV3H_EVENT_OCCURRED0_QP_AOERR0_SHFT 10 -#define UV3H_EVENT_OCCURRED0_RT_AOERR0_SHFT 17 -#define UV3H_EVENT_OCCURRED0_NI0_AOERR0_SHFT 18 -#define UV3H_EVENT_OCCURRED0_NI1_AOERR0_SHFT 19 -#define UV3H_EVENT_OCCURRED0_LB_AOERR1_SHFT 20 -#define UV3H_EVENT_OCCURRED0_QP_AOERR1_SHFT 21 -#define UV3H_EVENT_OCCURRED0_RH_AOERR1_SHFT 22 -#define UV3H_EVENT_OCCURRED0_LH0_AOERR1_SHFT 23 -#define UV3H_EVENT_OCCURRED0_LH1_AOERR1_SHFT 24 -#define UV3H_EVENT_OCCURRED0_GR0_AOERR1_SHFT 25 -#define UV3H_EVENT_OCCURRED0_GR1_AOERR1_SHFT 26 -#define UV3H_EVENT_OCCURRED0_XB_AOERR1_SHFT 27 -#define UV3H_EVENT_OCCURRED0_RT_AOERR1_SHFT 28 -#define UV3H_EVENT_OCCURRED0_NI0_AOERR1_SHFT 29 -#define UV3H_EVENT_OCCURRED0_NI1_AOERR1_SHFT 30 -#define UV3H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 31 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 32 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 33 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 34 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 35 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 36 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 37 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 38 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 39 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 40 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 41 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 42 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 43 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 44 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 45 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 46 -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 47 -#define UV3H_EVENT_OCCURRED0_L1_NMI_INT_SHFT 48 -#define UV3H_EVENT_OCCURRED0_STOP_CLOCK_SHFT 49 -#define UV3H_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 50 -#define UV3H_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 51 -#define UV3H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 52 -#define UV3H_EVENT_OCCURRED0_IPI_INT_SHFT 53 -#define UV3H_EVENT_OCCURRED0_EXTIO_INT0_SHFT 54 -#define UV3H_EVENT_OCCURRED0_EXTIO_INT1_SHFT 55 -#define UV3H_EVENT_OCCURRED0_EXTIO_INT2_SHFT 56 -#define UV3H_EVENT_OCCURRED0_EXTIO_INT3_SHFT 57 -#define UV3H_EVENT_OCCURRED0_PROFILE_INT_SHFT 58 -#define UV3H_EVENT_OCCURRED0_QP_HCERR_MASK 0x0000000000000002UL -#define UV3H_EVENT_OCCURRED0_QP_AOERR0_MASK 0x0000000000000400UL -#define UV3H_EVENT_OCCURRED0_RT_AOERR0_MASK 0x0000000000020000UL -#define UV3H_EVENT_OCCURRED0_NI0_AOERR0_MASK 0x0000000000040000UL -#define UV3H_EVENT_OCCURRED0_NI1_AOERR0_MASK 0x0000000000080000UL -#define UV3H_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000100000UL -#define UV3H_EVENT_OCCURRED0_QP_AOERR1_MASK 0x0000000000200000UL -#define UV3H_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000400000UL -#define UV3H_EVENT_OCCURRED0_LH0_AOERR1_MASK 0x0000000000800000UL -#define UV3H_EVENT_OCCURRED0_LH1_AOERR1_MASK 0x0000000001000000UL -#define UV3H_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000002000000UL -#define UV3H_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000004000000UL -#define UV3H_EVENT_OCCURRED0_XB_AOERR1_MASK 0x0000000008000000UL -#define UV3H_EVENT_OCCURRED0_RT_AOERR1_MASK 0x0000000010000000UL -#define UV3H_EVENT_OCCURRED0_NI0_AOERR1_MASK 0x0000000020000000UL -#define UV3H_EVENT_OCCURRED0_NI1_AOERR1_MASK 0x0000000040000000UL -#define UV3H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000080000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000100000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000200000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000400000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000800000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000001000000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000002000000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000004000000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000008000000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000010000000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000020000000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000040000000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000080000000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000100000000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000200000000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000400000000000UL -#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000800000000000UL -#define UV3H_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0001000000000000UL -#define UV3H_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0002000000000000UL -#define UV3H_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0004000000000000UL -#define UV3H_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0008000000000000UL -#define UV3H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0010000000000000UL -#define UV3H_EVENT_OCCURRED0_IPI_INT_MASK 0x0020000000000000UL -#define UV3H_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0040000000000000UL -#define UV3H_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0080000000000000UL -#define UV3H_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0100000000000000UL -#define UV3H_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0200000000000000UL -#define UV3H_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0400000000000000UL - +/* UVYH common defines */ +#define UVYH_EVENT_OCCURRED0_KT_HCERR_SHFT 1 +#define UVYH_EVENT_OCCURRED0_KT_HCERR_MASK 0x0000000000000002UL +#define UVYH_EVENT_OCCURRED0_RH0_HCERR_SHFT 2 +#define UVYH_EVENT_OCCURRED0_RH0_HCERR_MASK 0x0000000000000004UL +#define UVYH_EVENT_OCCURRED0_RH1_HCERR_SHFT 3 +#define UVYH_EVENT_OCCURRED0_RH1_HCERR_MASK 0x0000000000000008UL +#define UVYH_EVENT_OCCURRED0_LH0_HCERR_SHFT 4 +#define UVYH_EVENT_OCCURRED0_LH0_HCERR_MASK 0x0000000000000010UL +#define UVYH_EVENT_OCCURRED0_LH1_HCERR_SHFT 5 +#define UVYH_EVENT_OCCURRED0_LH1_HCERR_MASK 0x0000000000000020UL +#define UVYH_EVENT_OCCURRED0_LH2_HCERR_SHFT 6 +#define UVYH_EVENT_OCCURRED0_LH2_HCERR_MASK 0x0000000000000040UL +#define UVYH_EVENT_OCCURRED0_LH3_HCERR_SHFT 7 +#define UVYH_EVENT_OCCURRED0_LH3_HCERR_MASK 0x0000000000000080UL +#define UVYH_EVENT_OCCURRED0_XB_HCERR_SHFT 8 +#define UVYH_EVENT_OCCURRED0_XB_HCERR_MASK 0x0000000000000100UL +#define UVYH_EVENT_OCCURRED0_RDM_HCERR_SHFT 9 +#define UVYH_EVENT_OCCURRED0_RDM_HCERR_MASK 0x0000000000000200UL +#define UVYH_EVENT_OCCURRED0_NI0_HCERR_SHFT 10 +#define UVYH_EVENT_OCCURRED0_NI0_HCERR_MASK 0x0000000000000400UL +#define UVYH_EVENT_OCCURRED0_NI1_HCERR_SHFT 11 +#define UVYH_EVENT_OCCURRED0_NI1_HCERR_MASK 0x0000000000000800UL +#define UVYH_EVENT_OCCURRED0_LB_AOERR0_SHFT 12 +#define UVYH_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000001000UL +#define UVYH_EVENT_OCCURRED0_KT_AOERR0_SHFT 13 +#define UVYH_EVENT_OCCURRED0_KT_AOERR0_MASK 0x0000000000002000UL +#define UVYH_EVENT_OCCURRED0_RH0_AOERR0_SHFT 14 +#define UVYH_EVENT_OCCURRED0_RH0_AOERR0_MASK 0x0000000000004000UL +#define UVYH_EVENT_OCCURRED0_RH1_AOERR0_SHFT 15 +#define UVYH_EVENT_OCCURRED0_RH1_AOERR0_MASK 0x0000000000008000UL +#define UVYH_EVENT_OCCURRED0_LH0_AOERR0_SHFT 16 +#define UVYH_EVENT_OCCURRED0_LH0_AOERR0_MASK 0x0000000000010000UL +#define UVYH_EVENT_OCCURRED0_LH1_AOERR0_SHFT 17 +#define UVYH_EVENT_OCCURRED0_LH1_AOERR0_MASK 0x0000000000020000UL +#define UVYH_EVENT_OCCURRED0_LH2_AOERR0_SHFT 18 +#define UVYH_EVENT_OCCURRED0_LH2_AOERR0_MASK 0x0000000000040000UL +#define UVYH_EVENT_OCCURRED0_LH3_AOERR0_SHFT 19 +#define UVYH_EVENT_OCCURRED0_LH3_AOERR0_MASK 0x0000000000080000UL +#define UVYH_EVENT_OCCURRED0_XB_AOERR0_SHFT 20 +#define UVYH_EVENT_OCCURRED0_XB_AOERR0_MASK 0x0000000000100000UL +#define UVYH_EVENT_OCCURRED0_RDM_AOERR0_SHFT 21 +#define UVYH_EVENT_OCCURRED0_RDM_AOERR0_MASK 0x0000000000200000UL +#define UVYH_EVENT_OCCURRED0_RT0_AOERR0_SHFT 22 +#define UVYH_EVENT_OCCURRED0_RT0_AOERR0_MASK 0x0000000000400000UL +#define UVYH_EVENT_OCCURRED0_RT1_AOERR0_SHFT 23 +#define UVYH_EVENT_OCCURRED0_RT1_AOERR0_MASK 0x0000000000800000UL +#define UVYH_EVENT_OCCURRED0_NI0_AOERR0_SHFT 24 +#define UVYH_EVENT_OCCURRED0_NI0_AOERR0_MASK 0x0000000001000000UL +#define UVYH_EVENT_OCCURRED0_NI1_AOERR0_SHFT 25 +#define UVYH_EVENT_OCCURRED0_NI1_AOERR0_MASK 0x0000000002000000UL +#define UVYH_EVENT_OCCURRED0_LB_AOERR1_SHFT 26 +#define UVYH_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000004000000UL +#define UVYH_EVENT_OCCURRED0_KT_AOERR1_SHFT 27 +#define UVYH_EVENT_OCCURRED0_KT_AOERR1_MASK 0x0000000008000000UL +#define UVYH_EVENT_OCCURRED0_RH0_AOERR1_SHFT 28 +#define UVYH_EVENT_OCCURRED0_RH0_AOERR1_MASK 0x0000000010000000UL +#define UVYH_EVENT_OCCURRED0_RH1_AOERR1_SHFT 29 +#define UVYH_EVENT_OCCURRED0_RH1_AOERR1_MASK 0x0000000020000000UL +#define UVYH_EVENT_OCCURRED0_LH0_AOERR1_SHFT 30 +#define UVYH_EVENT_OCCURRED0_LH0_AOERR1_MASK 0x0000000040000000UL +#define UVYH_EVENT_OCCURRED0_LH1_AOERR1_SHFT 31 +#define UVYH_EVENT_OCCURRED0_LH1_AOERR1_MASK 0x0000000080000000UL +#define UVYH_EVENT_OCCURRED0_LH2_AOERR1_SHFT 32 +#define UVYH_EVENT_OCCURRED0_LH2_AOERR1_MASK 0x0000000100000000UL +#define UVYH_EVENT_OCCURRED0_LH3_AOERR1_SHFT 33 +#define UVYH_EVENT_OCCURRED0_LH3_AOERR1_MASK 0x0000000200000000UL +#define UVYH_EVENT_OCCURRED0_XB_AOERR1_SHFT 34 +#define UVYH_EVENT_OCCURRED0_XB_AOERR1_MASK 0x0000000400000000UL +#define UVYH_EVENT_OCCURRED0_RDM_AOERR1_SHFT 35 +#define UVYH_EVENT_OCCURRED0_RDM_AOERR1_MASK 0x0000000800000000UL +#define UVYH_EVENT_OCCURRED0_RT0_AOERR1_SHFT 36 +#define UVYH_EVENT_OCCURRED0_RT0_AOERR1_MASK 0x0000001000000000UL +#define UVYH_EVENT_OCCURRED0_RT1_AOERR1_SHFT 37 +#define UVYH_EVENT_OCCURRED0_RT1_AOERR1_MASK 0x0000002000000000UL +#define UVYH_EVENT_OCCURRED0_NI0_AOERR1_SHFT 38 +#define UVYH_EVENT_OCCURRED0_NI0_AOERR1_MASK 0x0000004000000000UL +#define UVYH_EVENT_OCCURRED0_NI1_AOERR1_SHFT 39 +#define UVYH_EVENT_OCCURRED0_NI1_AOERR1_MASK 0x0000008000000000UL +#define UVYH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 40 +#define UVYH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000010000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 41 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000020000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 42 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000040000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 43 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000080000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 44 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000100000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 45 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000200000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 46 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000400000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 47 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000800000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 48 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0001000000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 49 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0002000000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 50 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0004000000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 51 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0008000000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 52 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0010000000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 53 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0020000000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 54 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0040000000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 55 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0080000000000000UL +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 56 +#define UVYH_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0100000000000000UL +#define UVYH_EVENT_OCCURRED0_L1_NMI_INT_SHFT 57 +#define UVYH_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0200000000000000UL +#define UVYH_EVENT_OCCURRED0_STOP_CLOCK_SHFT 58 +#define UVYH_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0400000000000000UL +#define UVYH_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 59 +#define UVYH_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0800000000000000UL +#define UVYH_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 60 +#define UVYH_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x1000000000000000UL +#define UVYH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 61 +#define UVYH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x2000000000000000UL + +/* UV4 unique defines */ #define UV4H_EVENT_OCCURRED0_KT_HCERR_SHFT 1 -#define UV4H_EVENT_OCCURRED0_KT_AOERR0_SHFT 10 -#define UV4H_EVENT_OCCURRED0_RTQ0_AOERR0_SHFT 17 -#define UV4H_EVENT_OCCURRED0_RTQ1_AOERR0_SHFT 18 -#define UV4H_EVENT_OCCURRED0_RTQ2_AOERR0_SHFT 19 -#define UV4H_EVENT_OCCURRED0_RTQ3_AOERR0_SHFT 20 -#define UV4H_EVENT_OCCURRED0_NI0_AOERR0_SHFT 21 -#define UV4H_EVENT_OCCURRED0_NI1_AOERR0_SHFT 22 -#define UV4H_EVENT_OCCURRED0_LB_AOERR1_SHFT 23 -#define UV4H_EVENT_OCCURRED0_KT_AOERR1_SHFT 24 -#define UV4H_EVENT_OCCURRED0_RH_AOERR1_SHFT 25 -#define UV4H_EVENT_OCCURRED0_LH0_AOERR1_SHFT 26 -#define UV4H_EVENT_OCCURRED0_LH1_AOERR1_SHFT 27 -#define UV4H_EVENT_OCCURRED0_GR0_AOERR1_SHFT 28 -#define UV4H_EVENT_OCCURRED0_GR1_AOERR1_SHFT 29 -#define UV4H_EVENT_OCCURRED0_XB_AOERR1_SHFT 30 -#define UV4H_EVENT_OCCURRED0_RTQ0_AOERR1_SHFT 31 -#define UV4H_EVENT_OCCURRED0_RTQ1_AOERR1_SHFT 32 -#define UV4H_EVENT_OCCURRED0_RTQ2_AOERR1_SHFT 33 -#define UV4H_EVENT_OCCURRED0_RTQ3_AOERR1_SHFT 34 -#define UV4H_EVENT_OCCURRED0_NI0_AOERR1_SHFT 35 -#define UV4H_EVENT_OCCURRED0_NI1_AOERR1_SHFT 36 -#define UV4H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 37 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 38 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 39 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 40 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 41 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 42 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 43 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 44 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 45 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 46 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 47 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 48 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 49 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 50 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 51 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 52 -#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 53 -#define UV4H_EVENT_OCCURRED0_L1_NMI_INT_SHFT 54 -#define UV4H_EVENT_OCCURRED0_STOP_CLOCK_SHFT 55 -#define UV4H_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 56 -#define UV4H_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 57 -#define UV4H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 58 -#define UV4H_EVENT_OCCURRED0_IPI_INT_SHFT 59 -#define UV4H_EVENT_OCCURRED0_EXTIO_INT0_SHFT 60 -#define UV4H_EVENT_OCCURRED0_EXTIO_INT1_SHFT 61 -#define UV4H_EVENT_OCCURRED0_EXTIO_INT2_SHFT 62 -#define UV4H_EVENT_OCCURRED0_EXTIO_INT3_SHFT 63 #define UV4H_EVENT_OCCURRED0_KT_HCERR_MASK 0x0000000000000002UL +#define UV4H_EVENT_OCCURRED0_KT_AOERR0_SHFT 10 #define UV4H_EVENT_OCCURRED0_KT_AOERR0_MASK 0x0000000000000400UL +#define UV4H_EVENT_OCCURRED0_RTQ0_AOERR0_SHFT 17 #define UV4H_EVENT_OCCURRED0_RTQ0_AOERR0_MASK 0x0000000000020000UL +#define UV4H_EVENT_OCCURRED0_RTQ1_AOERR0_SHFT 18 #define UV4H_EVENT_OCCURRED0_RTQ1_AOERR0_MASK 0x0000000000040000UL +#define UV4H_EVENT_OCCURRED0_RTQ2_AOERR0_SHFT 19 #define UV4H_EVENT_OCCURRED0_RTQ2_AOERR0_MASK 0x0000000000080000UL +#define UV4H_EVENT_OCCURRED0_RTQ3_AOERR0_SHFT 20 #define UV4H_EVENT_OCCURRED0_RTQ3_AOERR0_MASK 0x0000000000100000UL +#define UV4H_EVENT_OCCURRED0_NI0_AOERR0_SHFT 21 #define UV4H_EVENT_OCCURRED0_NI0_AOERR0_MASK 0x0000000000200000UL +#define UV4H_EVENT_OCCURRED0_NI1_AOERR0_SHFT 22 #define UV4H_EVENT_OCCURRED0_NI1_AOERR0_MASK 0x0000000000400000UL +#define UV4H_EVENT_OCCURRED0_LB_AOERR1_SHFT 23 #define UV4H_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000800000UL +#define UV4H_EVENT_OCCURRED0_KT_AOERR1_SHFT 24 #define UV4H_EVENT_OCCURRED0_KT_AOERR1_MASK 0x0000000001000000UL +#define UV4H_EVENT_OCCURRED0_RH_AOERR1_SHFT 25 #define UV4H_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000002000000UL +#define UV4H_EVENT_OCCURRED0_LH0_AOERR1_SHFT 26 #define UV4H_EVENT_OCCURRED0_LH0_AOERR1_MASK 0x0000000004000000UL +#define UV4H_EVENT_OCCURRED0_LH1_AOERR1_SHFT 27 #define UV4H_EVENT_OCCURRED0_LH1_AOERR1_MASK 0x0000000008000000UL +#define UV4H_EVENT_OCCURRED0_GR0_AOERR1_SHFT 28 #define UV4H_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000010000000UL +#define UV4H_EVENT_OCCURRED0_GR1_AOERR1_SHFT 29 #define UV4H_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000020000000UL +#define UV4H_EVENT_OCCURRED0_XB_AOERR1_SHFT 30 #define UV4H_EVENT_OCCURRED0_XB_AOERR1_MASK 0x0000000040000000UL +#define UV4H_EVENT_OCCURRED0_RTQ0_AOERR1_SHFT 31 #define UV4H_EVENT_OCCURRED0_RTQ0_AOERR1_MASK 0x0000000080000000UL +#define UV4H_EVENT_OCCURRED0_RTQ1_AOERR1_SHFT 32 #define UV4H_EVENT_OCCURRED0_RTQ1_AOERR1_MASK 0x0000000100000000UL +#define UV4H_EVENT_OCCURRED0_RTQ2_AOERR1_SHFT 33 #define UV4H_EVENT_OCCURRED0_RTQ2_AOERR1_MASK 0x0000000200000000UL +#define UV4H_EVENT_OCCURRED0_RTQ3_AOERR1_SHFT 34 #define UV4H_EVENT_OCCURRED0_RTQ3_AOERR1_MASK 0x0000000400000000UL +#define UV4H_EVENT_OCCURRED0_NI0_AOERR1_SHFT 35 #define UV4H_EVENT_OCCURRED0_NI0_AOERR1_MASK 0x0000000800000000UL +#define UV4H_EVENT_OCCURRED0_NI1_AOERR1_SHFT 36 #define UV4H_EVENT_OCCURRED0_NI1_AOERR1_MASK 0x0000001000000000UL +#define UV4H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 37 #define UV4H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000002000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 38 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000004000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 39 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000008000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 40 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000010000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 41 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000020000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 42 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000040000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 43 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000080000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 44 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000100000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 45 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000200000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 46 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000400000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 47 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000800000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 48 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0001000000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 49 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0002000000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 50 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0004000000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 51 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0008000000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 52 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0010000000000000UL +#define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 53 #define UV4H_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0020000000000000UL +#define UV4H_EVENT_OCCURRED0_L1_NMI_INT_SHFT 54 #define UV4H_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0040000000000000UL +#define UV4H_EVENT_OCCURRED0_STOP_CLOCK_SHFT 55 #define UV4H_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0080000000000000UL +#define UV4H_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 56 #define UV4H_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0100000000000000UL +#define UV4H_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 57 #define UV4H_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0200000000000000UL +#define UV4H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 58 #define UV4H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0400000000000000UL +#define UV4H_EVENT_OCCURRED0_IPI_INT_SHFT 59 #define UV4H_EVENT_OCCURRED0_IPI_INT_MASK 0x0800000000000000UL +#define UV4H_EVENT_OCCURRED0_EXTIO_INT0_SHFT 60 #define UV4H_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x1000000000000000UL +#define UV4H_EVENT_OCCURRED0_EXTIO_INT1_SHFT 61 #define UV4H_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x2000000000000000UL +#define UV4H_EVENT_OCCURRED0_EXTIO_INT2_SHFT 62 #define UV4H_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x4000000000000000UL +#define UV4H_EVENT_OCCURRED0_EXTIO_INT3_SHFT 63 #define UV4H_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x8000000000000000UL +/* UV3 unique defines */ +#define UV3H_EVENT_OCCURRED0_QP_HCERR_SHFT 1 +#define UV3H_EVENT_OCCURRED0_QP_HCERR_MASK 0x0000000000000002UL +#define UV3H_EVENT_OCCURRED0_QP_AOERR0_SHFT 10 +#define UV3H_EVENT_OCCURRED0_QP_AOERR0_MASK 0x0000000000000400UL +#define UV3H_EVENT_OCCURRED0_RT_AOERR0_SHFT 17 +#define UV3H_EVENT_OCCURRED0_RT_AOERR0_MASK 0x0000000000020000UL +#define UV3H_EVENT_OCCURRED0_NI0_AOERR0_SHFT 18 +#define UV3H_EVENT_OCCURRED0_NI0_AOERR0_MASK 0x0000000000040000UL +#define UV3H_EVENT_OCCURRED0_NI1_AOERR0_SHFT 19 +#define UV3H_EVENT_OCCURRED0_NI1_AOERR0_MASK 0x0000000000080000UL +#define UV3H_EVENT_OCCURRED0_LB_AOERR1_SHFT 20 +#define UV3H_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000100000UL +#define UV3H_EVENT_OCCURRED0_QP_AOERR1_SHFT 21 +#define UV3H_EVENT_OCCURRED0_QP_AOERR1_MASK 0x0000000000200000UL +#define UV3H_EVENT_OCCURRED0_RH_AOERR1_SHFT 22 +#define UV3H_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000400000UL +#define UV3H_EVENT_OCCURRED0_LH0_AOERR1_SHFT 23 +#define UV3H_EVENT_OCCURRED0_LH0_AOERR1_MASK 0x0000000000800000UL +#define UV3H_EVENT_OCCURRED0_LH1_AOERR1_SHFT 24 +#define UV3H_EVENT_OCCURRED0_LH1_AOERR1_MASK 0x0000000001000000UL +#define UV3H_EVENT_OCCURRED0_GR0_AOERR1_SHFT 25 +#define UV3H_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000002000000UL +#define UV3H_EVENT_OCCURRED0_GR1_AOERR1_SHFT 26 +#define UV3H_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000004000000UL +#define UV3H_EVENT_OCCURRED0_XB_AOERR1_SHFT 27 +#define UV3H_EVENT_OCCURRED0_XB_AOERR1_MASK 0x0000000008000000UL +#define UV3H_EVENT_OCCURRED0_RT_AOERR1_SHFT 28 +#define UV3H_EVENT_OCCURRED0_RT_AOERR1_MASK 0x0000000010000000UL +#define UV3H_EVENT_OCCURRED0_NI0_AOERR1_SHFT 29 +#define UV3H_EVENT_OCCURRED0_NI0_AOERR1_MASK 0x0000000020000000UL +#define UV3H_EVENT_OCCURRED0_NI1_AOERR1_SHFT 30 +#define UV3H_EVENT_OCCURRED0_NI1_AOERR1_MASK 0x0000000040000000UL +#define UV3H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 31 +#define UV3H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000080000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 32 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000100000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 33 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000200000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 34 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000400000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 35 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000800000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 36 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000001000000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 37 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000002000000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 38 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000004000000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 39 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000008000000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 40 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000010000000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 41 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000020000000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 42 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000040000000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 43 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000080000000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 44 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000100000000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 45 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000200000000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 46 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000400000000000UL +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 47 +#define UV3H_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000800000000000UL +#define UV3H_EVENT_OCCURRED0_L1_NMI_INT_SHFT 48 +#define UV3H_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0001000000000000UL +#define UV3H_EVENT_OCCURRED0_STOP_CLOCK_SHFT 49 +#define UV3H_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0002000000000000UL +#define UV3H_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 50 +#define UV3H_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0004000000000000UL +#define UV3H_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 51 +#define UV3H_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0008000000000000UL +#define UV3H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 52 +#define UV3H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0010000000000000UL +#define UV3H_EVENT_OCCURRED0_IPI_INT_SHFT 53 +#define UV3H_EVENT_OCCURRED0_IPI_INT_MASK 0x0020000000000000UL +#define UV3H_EVENT_OCCURRED0_EXTIO_INT0_SHFT 54 +#define UV3H_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0040000000000000UL +#define UV3H_EVENT_OCCURRED0_EXTIO_INT1_SHFT 55 +#define UV3H_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0080000000000000UL +#define UV3H_EVENT_OCCURRED0_EXTIO_INT2_SHFT 56 +#define UV3H_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0100000000000000UL +#define UV3H_EVENT_OCCURRED0_EXTIO_INT3_SHFT 57 +#define UV3H_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0200000000000000UL +#define UV3H_EVENT_OCCURRED0_PROFILE_INT_SHFT 58 +#define UV3H_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0400000000000000UL + +/* UV2 unique defines */ +#define UV2H_EVENT_OCCURRED0_QP_HCERR_SHFT 1 +#define UV2H_EVENT_OCCURRED0_QP_HCERR_MASK 0x0000000000000002UL +#define UV2H_EVENT_OCCURRED0_QP_AOERR0_SHFT 10 +#define UV2H_EVENT_OCCURRED0_QP_AOERR0_MASK 0x0000000000000400UL +#define UV2H_EVENT_OCCURRED0_RT_AOERR0_SHFT 17 +#define UV2H_EVENT_OCCURRED0_RT_AOERR0_MASK 0x0000000000020000UL +#define UV2H_EVENT_OCCURRED0_NI0_AOERR0_SHFT 18 +#define UV2H_EVENT_OCCURRED0_NI0_AOERR0_MASK 0x0000000000040000UL +#define UV2H_EVENT_OCCURRED0_NI1_AOERR0_SHFT 19 +#define UV2H_EVENT_OCCURRED0_NI1_AOERR0_MASK 0x0000000000080000UL +#define UV2H_EVENT_OCCURRED0_LB_AOERR1_SHFT 20 +#define UV2H_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000100000UL +#define UV2H_EVENT_OCCURRED0_QP_AOERR1_SHFT 21 +#define UV2H_EVENT_OCCURRED0_QP_AOERR1_MASK 0x0000000000200000UL +#define UV2H_EVENT_OCCURRED0_RH_AOERR1_SHFT 22 +#define UV2H_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000400000UL +#define UV2H_EVENT_OCCURRED0_LH0_AOERR1_SHFT 23 +#define UV2H_EVENT_OCCURRED0_LH0_AOERR1_MASK 0x0000000000800000UL +#define UV2H_EVENT_OCCURRED0_LH1_AOERR1_SHFT 24 +#define UV2H_EVENT_OCCURRED0_LH1_AOERR1_MASK 0x0000000001000000UL +#define UV2H_EVENT_OCCURRED0_GR0_AOERR1_SHFT 25 +#define UV2H_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000002000000UL +#define UV2H_EVENT_OCCURRED0_GR1_AOERR1_SHFT 26 +#define UV2H_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000004000000UL +#define UV2H_EVENT_OCCURRED0_XB_AOERR1_SHFT 27 +#define UV2H_EVENT_OCCURRED0_XB_AOERR1_MASK 0x0000000008000000UL +#define UV2H_EVENT_OCCURRED0_RT_AOERR1_SHFT 28 +#define UV2H_EVENT_OCCURRED0_RT_AOERR1_MASK 0x0000000010000000UL +#define UV2H_EVENT_OCCURRED0_NI0_AOERR1_SHFT 29 +#define UV2H_EVENT_OCCURRED0_NI0_AOERR1_MASK 0x0000000020000000UL +#define UV2H_EVENT_OCCURRED0_NI1_AOERR1_SHFT 30 +#define UV2H_EVENT_OCCURRED0_NI1_AOERR1_MASK 0x0000000040000000UL +#define UV2H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 31 +#define UV2H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000080000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 32 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000100000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 33 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000200000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 34 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000400000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 35 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000800000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 36 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000001000000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 37 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000002000000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 38 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000004000000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 39 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000008000000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 40 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000010000000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 41 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000020000000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 42 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000040000000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 43 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000080000000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 44 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000100000000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 45 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000200000000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 46 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000400000000000UL +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 47 +#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000800000000000UL +#define UV2H_EVENT_OCCURRED0_L1_NMI_INT_SHFT 48 +#define UV2H_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0001000000000000UL +#define UV2H_EVENT_OCCURRED0_STOP_CLOCK_SHFT 49 +#define UV2H_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0002000000000000UL +#define UV2H_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 50 +#define UV2H_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0004000000000000UL +#define UV2H_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 51 +#define UV2H_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0008000000000000UL +#define UV2H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 52 +#define UV2H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0010000000000000UL +#define UV2H_EVENT_OCCURRED0_IPI_INT_SHFT 53 +#define UV2H_EVENT_OCCURRED0_IPI_INT_MASK 0x0020000000000000UL +#define UV2H_EVENT_OCCURRED0_EXTIO_INT0_SHFT 54 +#define UV2H_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0040000000000000UL +#define UV2H_EVENT_OCCURRED0_EXTIO_INT1_SHFT 55 +#define UV2H_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0080000000000000UL +#define UV2H_EVENT_OCCURRED0_EXTIO_INT2_SHFT 56 +#define UV2H_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0100000000000000UL +#define UV2H_EVENT_OCCURRED0_EXTIO_INT3_SHFT 57 +#define UV2H_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0200000000000000UL +#define UV2H_EVENT_OCCURRED0_PROFILE_INT_SHFT 58 +#define UV2H_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0400000000000000UL + +#define UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK ( \ + is_uv(UV4) ? 0x1000000000000000UL : \ + is_uv(UV3) ? 0x0040000000000000UL : \ + is_uv(UV2) ? 0x0040000000000000UL : \ + 0) #define UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT ( \ - is_uv2_hub() ? UV2H_EVENT_OCCURRED0_EXTIO_INT0_SHFT : \ - is_uv3_hub() ? UV3H_EVENT_OCCURRED0_EXTIO_INT0_SHFT : \ - /*is_uv4_hub*/ UV4H_EVENT_OCCURRED0_EXTIO_INT0_SHFT) + is_uv(UV4) ? 60 : \ + is_uv(UV3) ? 54 : \ + is_uv(UV2) ? 54 : \ + -1) union uvh_event_occurred0_u { unsigned long v; + + /* UVH common struct */ struct uvh_event_occurred0_s { - unsigned long lb_hcerr:1; /* RW, W1C */ - unsigned long rsvd_1_10:10; - unsigned long rh_aoerr0:1; /* RW, W1C */ - unsigned long rsvd_12_63:52; + unsigned long lb_hcerr:1; /* RW */ + unsigned long rsvd_1_63:63; } s; + + /* UVXH common struct */ struct uvxh_event_occurred0_s { unsigned long lb_hcerr:1; /* RW */ unsigned long rsvd_1:1; @@ -505,6 +577,142 @@ union uvh_event_occurred0_u { unsigned long xb_aoerr0:1; /* RW */ unsigned long rsvd_17_63:47; } sx; + + /* UVYH common struct */ + struct uvyh_event_occurred0_s { + unsigned long lb_hcerr:1; /* RW */ + unsigned long kt_hcerr:1; /* RW */ + unsigned long rh0_hcerr:1; /* RW */ + unsigned long rh1_hcerr:1; /* RW */ + unsigned long lh0_hcerr:1; /* RW */ + unsigned long lh1_hcerr:1; /* RW */ + unsigned long lh2_hcerr:1; /* RW */ + unsigned long lh3_hcerr:1; /* RW */ + unsigned long xb_hcerr:1; /* RW */ + unsigned long rdm_hcerr:1; /* RW */ + unsigned long ni0_hcerr:1; /* RW */ + unsigned long ni1_hcerr:1; /* RW */ + unsigned long lb_aoerr0:1; /* RW */ + unsigned long kt_aoerr0:1; /* RW */ + unsigned long rh0_aoerr0:1; /* RW */ + unsigned long rh1_aoerr0:1; /* RW */ + unsigned long lh0_aoerr0:1; /* RW */ + unsigned long lh1_aoerr0:1; /* RW */ + unsigned long lh2_aoerr0:1; /* RW */ + unsigned long lh3_aoerr0:1; /* RW */ + unsigned long xb_aoerr0:1; /* RW */ + unsigned long rdm_aoerr0:1; /* RW */ + unsigned long rt0_aoerr0:1; /* RW */ + unsigned long rt1_aoerr0:1; /* RW */ + unsigned long ni0_aoerr0:1; /* RW */ + unsigned long ni1_aoerr0:1; /* RW */ + unsigned long lb_aoerr1:1; /* RW */ + unsigned long kt_aoerr1:1; /* RW */ + unsigned long rh0_aoerr1:1; /* RW */ + unsigned long rh1_aoerr1:1; /* RW */ + unsigned long lh0_aoerr1:1; /* RW */ + unsigned long lh1_aoerr1:1; /* RW */ + unsigned long lh2_aoerr1:1; /* RW */ + unsigned long lh3_aoerr1:1; /* RW */ + unsigned long xb_aoerr1:1; /* RW */ + unsigned long rdm_aoerr1:1; /* RW */ + unsigned long rt0_aoerr1:1; /* RW */ + unsigned long rt1_aoerr1:1; /* RW */ + unsigned long ni0_aoerr1:1; /* RW */ + unsigned long ni1_aoerr1:1; /* RW */ + unsigned long system_shutdown_int:1; /* RW */ + unsigned long lb_irq_int_0:1; /* RW */ + unsigned long lb_irq_int_1:1; /* RW */ + unsigned long lb_irq_int_2:1; /* RW */ + unsigned long lb_irq_int_3:1; /* RW */ + unsigned long lb_irq_int_4:1; /* RW */ + unsigned long lb_irq_int_5:1; /* RW */ + unsigned long lb_irq_int_6:1; /* RW */ + unsigned long lb_irq_int_7:1; /* RW */ + unsigned long lb_irq_int_8:1; /* RW */ + unsigned long lb_irq_int_9:1; /* RW */ + unsigned long lb_irq_int_10:1; /* RW */ + unsigned long lb_irq_int_11:1; /* RW */ + unsigned long lb_irq_int_12:1; /* RW */ + unsigned long lb_irq_int_13:1; /* RW */ + unsigned long lb_irq_int_14:1; /* RW */ + unsigned long lb_irq_int_15:1; /* RW */ + unsigned long l1_nmi_int:1; /* RW */ + unsigned long stop_clock:1; /* RW */ + unsigned long asic_to_l1:1; /* RW */ + unsigned long l1_to_asic:1; /* RW */ + unsigned long la_seq_trigger:1; /* RW */ + unsigned long rsvd_62_63:2; + } sy; + + /* UV5 unique struct */ + struct uv5h_event_occurred0_s { + unsigned long lb_hcerr:1; /* RW */ + unsigned long kt_hcerr:1; /* RW */ + unsigned long rh0_hcerr:1; /* RW */ + unsigned long rh1_hcerr:1; /* RW */ + unsigned long lh0_hcerr:1; /* RW */ + unsigned long lh1_hcerr:1; /* RW */ + unsigned long lh2_hcerr:1; /* RW */ + unsigned long lh3_hcerr:1; /* RW */ + unsigned long xb_hcerr:1; /* RW */ + unsigned long rdm_hcerr:1; /* RW */ + unsigned long ni0_hcerr:1; /* RW */ + unsigned long ni1_hcerr:1; /* RW */ + unsigned long lb_aoerr0:1; /* RW */ + unsigned long kt_aoerr0:1; /* RW */ + unsigned long rh0_aoerr0:1; /* RW */ + unsigned long rh1_aoerr0:1; /* RW */ + unsigned long lh0_aoerr0:1; /* RW */ + unsigned long lh1_aoerr0:1; /* RW */ + unsigned long lh2_aoerr0:1; /* RW */ + unsigned long lh3_aoerr0:1; /* RW */ + unsigned long xb_aoerr0:1; /* RW */ + unsigned long rdm_aoerr0:1; /* RW */ + unsigned long rt0_aoerr0:1; /* RW */ + unsigned long rt1_aoerr0:1; /* RW */ + unsigned long ni0_aoerr0:1; /* RW */ + unsigned long ni1_aoerr0:1; /* RW */ + unsigned long lb_aoerr1:1; /* RW */ + unsigned long kt_aoerr1:1; /* RW */ + unsigned long rh0_aoerr1:1; /* RW */ + unsigned long rh1_aoerr1:1; /* RW */ + unsigned long lh0_aoerr1:1; /* RW */ + unsigned long lh1_aoerr1:1; /* RW */ + unsigned long lh2_aoerr1:1; /* RW */ + unsigned long lh3_aoerr1:1; /* RW */ + unsigned long xb_aoerr1:1; /* RW */ + unsigned long rdm_aoerr1:1; /* RW */ + unsigned long rt0_aoerr1:1; /* RW */ + unsigned long rt1_aoerr1:1; /* RW */ + unsigned long ni0_aoerr1:1; /* RW */ + unsigned long ni1_aoerr1:1; /* RW */ + unsigned long system_shutdown_int:1; /* RW */ + unsigned long lb_irq_int_0:1; /* RW */ + unsigned long lb_irq_int_1:1; /* RW */ + unsigned long lb_irq_int_2:1; /* RW */ + unsigned long lb_irq_int_3:1; /* RW */ + unsigned long lb_irq_int_4:1; /* RW */ + unsigned long lb_irq_int_5:1; /* RW */ + unsigned long lb_irq_int_6:1; /* RW */ + unsigned long lb_irq_int_7:1; /* RW */ + unsigned long lb_irq_int_8:1; /* RW */ + unsigned long lb_irq_int_9:1; /* RW */ + unsigned long lb_irq_int_10:1; /* RW */ + unsigned long lb_irq_int_11:1; /* RW */ + unsigned long lb_irq_int_12:1; /* RW */ + unsigned long lb_irq_int_13:1; /* RW */ + unsigned long lb_irq_int_14:1; /* RW */ + unsigned long lb_irq_int_15:1; /* RW */ + unsigned long l1_nmi_int:1; /* RW */ + unsigned long stop_clock:1; /* RW */ + unsigned long asic_to_l1:1; /* RW */ + unsigned long l1_to_asic:1; /* RW */ + unsigned long la_seq_trigger:1; /* RW */ + unsigned long rsvd_62_63:2; + } s5; + + /* UV4 unique struct */ struct uv4h_event_occurred0_s { unsigned long lb_hcerr:1; /* RW */ unsigned long kt_hcerr:1; /* RW */ @@ -571,13 +779,1355 @@ union uvh_event_occurred0_u { unsigned long extio_int2:1; /* RW */ unsigned long extio_int3:1; /* RW */ } s4; + + /* UV3 unique struct */ + struct uv3h_event_occurred0_s { + unsigned long lb_hcerr:1; /* RW */ + unsigned long qp_hcerr:1; /* RW */ + unsigned long rh_hcerr:1; /* RW */ + unsigned long lh0_hcerr:1; /* RW */ + unsigned long lh1_hcerr:1; /* RW */ + unsigned long gr0_hcerr:1; /* RW */ + unsigned long gr1_hcerr:1; /* RW */ + unsigned long ni0_hcerr:1; /* RW */ + unsigned long ni1_hcerr:1; /* RW */ + unsigned long lb_aoerr0:1; /* RW */ + unsigned long qp_aoerr0:1; /* RW */ + unsigned long rh_aoerr0:1; /* RW */ + unsigned long lh0_aoerr0:1; /* RW */ + unsigned long lh1_aoerr0:1; /* RW */ + unsigned long gr0_aoerr0:1; /* RW */ + unsigned long gr1_aoerr0:1; /* RW */ + unsigned long xb_aoerr0:1; /* RW */ + unsigned long rt_aoerr0:1; /* RW */ + unsigned long ni0_aoerr0:1; /* RW */ + unsigned long ni1_aoerr0:1; /* RW */ + unsigned long lb_aoerr1:1; /* RW */ + unsigned long qp_aoerr1:1; /* RW */ + unsigned long rh_aoerr1:1; /* RW */ + unsigned long lh0_aoerr1:1; /* RW */ + unsigned long lh1_aoerr1:1; /* RW */ + unsigned long gr0_aoerr1:1; /* RW */ + unsigned long gr1_aoerr1:1; /* RW */ + unsigned long xb_aoerr1:1; /* RW */ + unsigned long rt_aoerr1:1; /* RW */ + unsigned long ni0_aoerr1:1; /* RW */ + unsigned long ni1_aoerr1:1; /* RW */ + unsigned long system_shutdown_int:1; /* RW */ + unsigned long lb_irq_int_0:1; /* RW */ + unsigned long lb_irq_int_1:1; /* RW */ + unsigned long lb_irq_int_2:1; /* RW */ + unsigned long lb_irq_int_3:1; /* RW */ + unsigned long lb_irq_int_4:1; /* RW */ + unsigned long lb_irq_int_5:1; /* RW */ + unsigned long lb_irq_int_6:1; /* RW */ + unsigned long lb_irq_int_7:1; /* RW */ + unsigned long lb_irq_int_8:1; /* RW */ + unsigned long lb_irq_int_9:1; /* RW */ + unsigned long lb_irq_int_10:1; /* RW */ + unsigned long lb_irq_int_11:1; /* RW */ + unsigned long lb_irq_int_12:1; /* RW */ + unsigned long lb_irq_int_13:1; /* RW */ + unsigned long lb_irq_int_14:1; /* RW */ + unsigned long lb_irq_int_15:1; /* RW */ + unsigned long l1_nmi_int:1; /* RW */ + unsigned long stop_clock:1; /* RW */ + unsigned long asic_to_l1:1; /* RW */ + unsigned long l1_to_asic:1; /* RW */ + unsigned long la_seq_trigger:1; /* RW */ + unsigned long ipi_int:1; /* RW */ + unsigned long extio_int0:1; /* RW */ + unsigned long extio_int1:1; /* RW */ + unsigned long extio_int2:1; /* RW */ + unsigned long extio_int3:1; /* RW */ + unsigned long profile_int:1; /* RW */ + unsigned long rsvd_59_63:5; + } s3; + + /* UV2 unique struct */ + struct uv2h_event_occurred0_s { + unsigned long lb_hcerr:1; /* RW */ + unsigned long qp_hcerr:1; /* RW */ + unsigned long rh_hcerr:1; /* RW */ + unsigned long lh0_hcerr:1; /* RW */ + unsigned long lh1_hcerr:1; /* RW */ + unsigned long gr0_hcerr:1; /* RW */ + unsigned long gr1_hcerr:1; /* RW */ + unsigned long ni0_hcerr:1; /* RW */ + unsigned long ni1_hcerr:1; /* RW */ + unsigned long lb_aoerr0:1; /* RW */ + unsigned long qp_aoerr0:1; /* RW */ + unsigned long rh_aoerr0:1; /* RW */ + unsigned long lh0_aoerr0:1; /* RW */ + unsigned long lh1_aoerr0:1; /* RW */ + unsigned long gr0_aoerr0:1; /* RW */ + unsigned long gr1_aoerr0:1; /* RW */ + unsigned long xb_aoerr0:1; /* RW */ + unsigned long rt_aoerr0:1; /* RW */ + unsigned long ni0_aoerr0:1; /* RW */ + unsigned long ni1_aoerr0:1; /* RW */ + unsigned long lb_aoerr1:1; /* RW */ + unsigned long qp_aoerr1:1; /* RW */ + unsigned long rh_aoerr1:1; /* RW */ + unsigned long lh0_aoerr1:1; /* RW */ + unsigned long lh1_aoerr1:1; /* RW */ + unsigned long gr0_aoerr1:1; /* RW */ + unsigned long gr1_aoerr1:1; /* RW */ + unsigned long xb_aoerr1:1; /* RW */ + unsigned long rt_aoerr1:1; /* RW */ + unsigned long ni0_aoerr1:1; /* RW */ + unsigned long ni1_aoerr1:1; /* RW */ + unsigned long system_shutdown_int:1; /* RW */ + unsigned long lb_irq_int_0:1; /* RW */ + unsigned long lb_irq_int_1:1; /* RW */ + unsigned long lb_irq_int_2:1; /* RW */ + unsigned long lb_irq_int_3:1; /* RW */ + unsigned long lb_irq_int_4:1; /* RW */ + unsigned long lb_irq_int_5:1; /* RW */ + unsigned long lb_irq_int_6:1; /* RW */ + unsigned long lb_irq_int_7:1; /* RW */ + unsigned long lb_irq_int_8:1; /* RW */ + unsigned long lb_irq_int_9:1; /* RW */ + unsigned long lb_irq_int_10:1; /* RW */ + unsigned long lb_irq_int_11:1; /* RW */ + unsigned long lb_irq_int_12:1; /* RW */ + unsigned long lb_irq_int_13:1; /* RW */ + unsigned long lb_irq_int_14:1; /* RW */ + unsigned long lb_irq_int_15:1; /* RW */ + unsigned long l1_nmi_int:1; /* RW */ + unsigned long stop_clock:1; /* RW */ + unsigned long asic_to_l1:1; /* RW */ + unsigned long l1_to_asic:1; /* RW */ + unsigned long la_seq_trigger:1; /* RW */ + unsigned long ipi_int:1; /* RW */ + unsigned long extio_int0:1; /* RW */ + unsigned long extio_int1:1; /* RW */ + unsigned long extio_int2:1; /* RW */ + unsigned long extio_int3:1; /* RW */ + unsigned long profile_int:1; /* RW */ + unsigned long rsvd_59_63:5; + } s2; }; /* ========================================================================= */ /* UVH_EVENT_OCCURRED0_ALIAS */ /* ========================================================================= */ #define UVH_EVENT_OCCURRED0_ALIAS 0x70008UL -#define UVH_EVENT_OCCURRED0_ALIAS_32 0x5f0 + + +/* ========================================================================= */ +/* UVH_EVENT_OCCURRED1 */ +/* ========================================================================= */ +#define UVH_EVENT_OCCURRED1 0x70080UL + + + +/* UVYH common defines */ +#define UVYH_EVENT_OCCURRED1_IPI_INT_SHFT 0 +#define UVYH_EVENT_OCCURRED1_IPI_INT_MASK 0x0000000000000001UL +#define UVYH_EVENT_OCCURRED1_EXTIO_INT0_SHFT 1 +#define UVYH_EVENT_OCCURRED1_EXTIO_INT0_MASK 0x0000000000000002UL +#define UVYH_EVENT_OCCURRED1_EXTIO_INT1_SHFT 2 +#define UVYH_EVENT_OCCURRED1_EXTIO_INT1_MASK 0x0000000000000004UL +#define UVYH_EVENT_OCCURRED1_EXTIO_INT2_SHFT 3 +#define UVYH_EVENT_OCCURRED1_EXTIO_INT2_MASK 0x0000000000000008UL +#define UVYH_EVENT_OCCURRED1_EXTIO_INT3_SHFT 4 +#define UVYH_EVENT_OCCURRED1_EXTIO_INT3_MASK 0x0000000000000010UL +#define UVYH_EVENT_OCCURRED1_PROFILE_INT_SHFT 5 +#define UVYH_EVENT_OCCURRED1_PROFILE_INT_MASK 0x0000000000000020UL +#define UVYH_EVENT_OCCURRED1_BAU_DATA_SHFT 6 +#define UVYH_EVENT_OCCURRED1_BAU_DATA_MASK 0x0000000000000040UL +#define UVYH_EVENT_OCCURRED1_PROC_GENERAL_SHFT 7 +#define UVYH_EVENT_OCCURRED1_PROC_GENERAL_MASK 0x0000000000000080UL +#define UVYH_EVENT_OCCURRED1_XH_TLB_INT0_SHFT 8 +#define UVYH_EVENT_OCCURRED1_XH_TLB_INT0_MASK 0x0000000000000100UL +#define UVYH_EVENT_OCCURRED1_XH_TLB_INT1_SHFT 9 +#define UVYH_EVENT_OCCURRED1_XH_TLB_INT1_MASK 0x0000000000000200UL +#define UVYH_EVENT_OCCURRED1_XH_TLB_INT2_SHFT 10 +#define UVYH_EVENT_OCCURRED1_XH_TLB_INT2_MASK 0x0000000000000400UL +#define UVYH_EVENT_OCCURRED1_XH_TLB_INT3_SHFT 11 +#define UVYH_EVENT_OCCURRED1_XH_TLB_INT3_MASK 0x0000000000000800UL +#define UVYH_EVENT_OCCURRED1_XH_TLB_INT4_SHFT 12 +#define UVYH_EVENT_OCCURRED1_XH_TLB_INT4_MASK 0x0000000000001000UL +#define UVYH_EVENT_OCCURRED1_XH_TLB_INT5_SHFT 13 +#define UVYH_EVENT_OCCURRED1_XH_TLB_INT5_MASK 0x0000000000002000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT0_SHFT 14 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT0_MASK 0x0000000000004000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT1_SHFT 15 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT1_MASK 0x0000000000008000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT2_SHFT 16 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT2_MASK 0x0000000000010000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT3_SHFT 17 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT3_MASK 0x0000000000020000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT4_SHFT 18 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT4_MASK 0x0000000000040000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT5_SHFT 19 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT5_MASK 0x0000000000080000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT6_SHFT 20 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT6_MASK 0x0000000000100000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT7_SHFT 21 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT7_MASK 0x0000000000200000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT8_SHFT 22 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT8_MASK 0x0000000000400000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT9_SHFT 23 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT9_MASK 0x0000000000800000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT10_SHFT 24 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT10_MASK 0x0000000001000000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT11_SHFT 25 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT11_MASK 0x0000000002000000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT12_SHFT 26 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT12_MASK 0x0000000004000000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT13_SHFT 27 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT13_MASK 0x0000000008000000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT14_SHFT 28 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT14_MASK 0x0000000010000000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT15_SHFT 29 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT15_MASK 0x0000000020000000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT16_SHFT 30 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT16_MASK 0x0000000040000000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT17_SHFT 31 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT17_MASK 0x0000000080000000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT18_SHFT 32 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT18_MASK 0x0000000100000000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT19_SHFT 33 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT19_MASK 0x0000000200000000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT20_SHFT 34 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT20_MASK 0x0000000400000000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT21_SHFT 35 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT21_MASK 0x0000000800000000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT22_SHFT 36 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT22_MASK 0x0000001000000000UL +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT23_SHFT 37 +#define UVYH_EVENT_OCCURRED1_RDM_TLB_INT23_MASK 0x0000002000000000UL + +/* UV4 unique defines */ +#define UV4H_EVENT_OCCURRED1_PROFILE_INT_SHFT 0 +#define UV4H_EVENT_OCCURRED1_PROFILE_INT_MASK 0x0000000000000001UL +#define UV4H_EVENT_OCCURRED1_BAU_DATA_SHFT 1 +#define UV4H_EVENT_OCCURRED1_BAU_DATA_MASK 0x0000000000000002UL +#define UV4H_EVENT_OCCURRED1_PROC_GENERAL_SHFT 2 +#define UV4H_EVENT_OCCURRED1_PROC_GENERAL_MASK 0x0000000000000004UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT0_SHFT 3 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT0_MASK 0x0000000000000008UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT1_SHFT 4 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT1_MASK 0x0000000000000010UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT2_SHFT 5 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT2_MASK 0x0000000000000020UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT3_SHFT 6 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT3_MASK 0x0000000000000040UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT4_SHFT 7 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT4_MASK 0x0000000000000080UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT5_SHFT 8 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT5_MASK 0x0000000000000100UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT6_SHFT 9 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT6_MASK 0x0000000000000200UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT7_SHFT 10 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT7_MASK 0x0000000000000400UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT8_SHFT 11 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT8_MASK 0x0000000000000800UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT9_SHFT 12 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT9_MASK 0x0000000000001000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT10_SHFT 13 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT10_MASK 0x0000000000002000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT11_SHFT 14 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT11_MASK 0x0000000000004000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT12_SHFT 15 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT12_MASK 0x0000000000008000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT13_SHFT 16 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT13_MASK 0x0000000000010000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT14_SHFT 17 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT14_MASK 0x0000000000020000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT15_SHFT 18 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT15_MASK 0x0000000000040000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT16_SHFT 19 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT16_MASK 0x0000000000080000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT17_SHFT 20 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT17_MASK 0x0000000000100000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT18_SHFT 21 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT18_MASK 0x0000000000200000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT19_SHFT 22 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT19_MASK 0x0000000000400000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT20_SHFT 23 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT20_MASK 0x0000000000800000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT21_SHFT 24 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT21_MASK 0x0000000001000000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT22_SHFT 25 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT22_MASK 0x0000000002000000UL +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT23_SHFT 26 +#define UV4H_EVENT_OCCURRED1_GR0_TLB_INT23_MASK 0x0000000004000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT0_SHFT 27 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT0_MASK 0x0000000008000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT1_SHFT 28 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT1_MASK 0x0000000010000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT2_SHFT 29 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT2_MASK 0x0000000020000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT3_SHFT 30 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT3_MASK 0x0000000040000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT4_SHFT 31 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT4_MASK 0x0000000080000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT5_SHFT 32 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT5_MASK 0x0000000100000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT6_SHFT 33 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT6_MASK 0x0000000200000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT7_SHFT 34 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT7_MASK 0x0000000400000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT8_SHFT 35 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT8_MASK 0x0000000800000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT9_SHFT 36 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT9_MASK 0x0000001000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT10_SHFT 37 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT10_MASK 0x0000002000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT11_SHFT 38 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT11_MASK 0x0000004000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT12_SHFT 39 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT12_MASK 0x0000008000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT13_SHFT 40 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT13_MASK 0x0000010000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT14_SHFT 41 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT14_MASK 0x0000020000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT15_SHFT 42 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT15_MASK 0x0000040000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT16_SHFT 43 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT16_MASK 0x0000080000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT17_SHFT 44 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT17_MASK 0x0000100000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT18_SHFT 45 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT18_MASK 0x0000200000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT19_SHFT 46 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT19_MASK 0x0000400000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT20_SHFT 47 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT20_MASK 0x0000800000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT21_SHFT 48 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT21_MASK 0x0001000000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT22_SHFT 49 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT22_MASK 0x0002000000000000UL +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT23_SHFT 50 +#define UV4H_EVENT_OCCURRED1_GR1_TLB_INT23_MASK 0x0004000000000000UL + +/* UV3 unique defines */ +#define UV3H_EVENT_OCCURRED1_BAU_DATA_SHFT 0 +#define UV3H_EVENT_OCCURRED1_BAU_DATA_MASK 0x0000000000000001UL +#define UV3H_EVENT_OCCURRED1_POWER_MANAGEMENT_REQ_SHFT 1 +#define UV3H_EVENT_OCCURRED1_POWER_MANAGEMENT_REQ_MASK 0x0000000000000002UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT0_SHFT 2 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT0_MASK 0x0000000000000004UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT1_SHFT 3 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT1_MASK 0x0000000000000008UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT2_SHFT 4 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT2_MASK 0x0000000000000010UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT3_SHFT 5 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT3_MASK 0x0000000000000020UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT4_SHFT 6 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT4_MASK 0x0000000000000040UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT5_SHFT 7 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT5_MASK 0x0000000000000080UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT6_SHFT 8 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT6_MASK 0x0000000000000100UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT7_SHFT 9 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT7_MASK 0x0000000000000200UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT8_SHFT 10 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT8_MASK 0x0000000000000400UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT9_SHFT 11 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT9_MASK 0x0000000000000800UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT10_SHFT 12 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT10_MASK 0x0000000000001000UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT11_SHFT 13 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT11_MASK 0x0000000000002000UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT12_SHFT 14 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT12_MASK 0x0000000000004000UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT13_SHFT 15 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT13_MASK 0x0000000000008000UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT14_SHFT 16 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT14_MASK 0x0000000000010000UL +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT15_SHFT 17 +#define UV3H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT15_MASK 0x0000000000020000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT0_SHFT 18 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT0_MASK 0x0000000000040000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT1_SHFT 19 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT1_MASK 0x0000000000080000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT2_SHFT 20 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT2_MASK 0x0000000000100000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT3_SHFT 21 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT3_MASK 0x0000000000200000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT4_SHFT 22 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT4_MASK 0x0000000000400000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT5_SHFT 23 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT5_MASK 0x0000000000800000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT6_SHFT 24 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT6_MASK 0x0000000001000000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT7_SHFT 25 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT7_MASK 0x0000000002000000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT8_SHFT 26 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT8_MASK 0x0000000004000000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT9_SHFT 27 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT9_MASK 0x0000000008000000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT10_SHFT 28 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT10_MASK 0x0000000010000000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT11_SHFT 29 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT11_MASK 0x0000000020000000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT12_SHFT 30 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT12_MASK 0x0000000040000000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT13_SHFT 31 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT13_MASK 0x0000000080000000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT14_SHFT 32 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT14_MASK 0x0000000100000000UL +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT15_SHFT 33 +#define UV3H_EVENT_OCCURRED1_GR0_TLB_INT15_MASK 0x0000000200000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT0_SHFT 34 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT0_MASK 0x0000000400000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT1_SHFT 35 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT1_MASK 0x0000000800000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT2_SHFT 36 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT2_MASK 0x0000001000000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT3_SHFT 37 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT3_MASK 0x0000002000000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT4_SHFT 38 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT4_MASK 0x0000004000000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT5_SHFT 39 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT5_MASK 0x0000008000000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT6_SHFT 40 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT6_MASK 0x0000010000000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT7_SHFT 41 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT7_MASK 0x0000020000000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT8_SHFT 42 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT8_MASK 0x0000040000000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT9_SHFT 43 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT9_MASK 0x0000080000000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT10_SHFT 44 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT10_MASK 0x0000100000000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT11_SHFT 45 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT11_MASK 0x0000200000000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT12_SHFT 46 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT12_MASK 0x0000400000000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT13_SHFT 47 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT13_MASK 0x0000800000000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT14_SHFT 48 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT14_MASK 0x0001000000000000UL +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT15_SHFT 49 +#define UV3H_EVENT_OCCURRED1_GR1_TLB_INT15_MASK 0x0002000000000000UL +#define UV3H_EVENT_OCCURRED1_RTC_INTERVAL_INT_SHFT 50 +#define UV3H_EVENT_OCCURRED1_RTC_INTERVAL_INT_MASK 0x0004000000000000UL +#define UV3H_EVENT_OCCURRED1_BAU_DASHBOARD_INT_SHFT 51 +#define UV3H_EVENT_OCCURRED1_BAU_DASHBOARD_INT_MASK 0x0008000000000000UL + +/* UV2 unique defines */ +#define UV2H_EVENT_OCCURRED1_BAU_DATA_SHFT 0 +#define UV2H_EVENT_OCCURRED1_BAU_DATA_MASK 0x0000000000000001UL +#define UV2H_EVENT_OCCURRED1_POWER_MANAGEMENT_REQ_SHFT 1 +#define UV2H_EVENT_OCCURRED1_POWER_MANAGEMENT_REQ_MASK 0x0000000000000002UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT0_SHFT 2 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT0_MASK 0x0000000000000004UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT1_SHFT 3 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT1_MASK 0x0000000000000008UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT2_SHFT 4 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT2_MASK 0x0000000000000010UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT3_SHFT 5 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT3_MASK 0x0000000000000020UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT4_SHFT 6 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT4_MASK 0x0000000000000040UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT5_SHFT 7 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT5_MASK 0x0000000000000080UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT6_SHFT 8 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT6_MASK 0x0000000000000100UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT7_SHFT 9 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT7_MASK 0x0000000000000200UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT8_SHFT 10 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT8_MASK 0x0000000000000400UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT9_SHFT 11 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT9_MASK 0x0000000000000800UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT10_SHFT 12 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT10_MASK 0x0000000000001000UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT11_SHFT 13 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT11_MASK 0x0000000000002000UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT12_SHFT 14 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT12_MASK 0x0000000000004000UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT13_SHFT 15 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT13_MASK 0x0000000000008000UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT14_SHFT 16 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT14_MASK 0x0000000000010000UL +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT15_SHFT 17 +#define UV2H_EVENT_OCCURRED1_MESSAGE_ACCELERATOR_INT15_MASK 0x0000000000020000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT0_SHFT 18 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT0_MASK 0x0000000000040000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT1_SHFT 19 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT1_MASK 0x0000000000080000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT2_SHFT 20 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT2_MASK 0x0000000000100000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT3_SHFT 21 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT3_MASK 0x0000000000200000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT4_SHFT 22 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT4_MASK 0x0000000000400000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT5_SHFT 23 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT5_MASK 0x0000000000800000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT6_SHFT 24 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT6_MASK 0x0000000001000000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT7_SHFT 25 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT7_MASK 0x0000000002000000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT8_SHFT 26 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT8_MASK 0x0000000004000000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT9_SHFT 27 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT9_MASK 0x0000000008000000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT10_SHFT 28 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT10_MASK 0x0000000010000000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT11_SHFT 29 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT11_MASK 0x0000000020000000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT12_SHFT 30 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT12_MASK 0x0000000040000000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT13_SHFT 31 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT13_MASK 0x0000000080000000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT14_SHFT 32 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT14_MASK 0x0000000100000000UL +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT15_SHFT 33 +#define UV2H_EVENT_OCCURRED1_GR0_TLB_INT15_MASK 0x0000000200000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT0_SHFT 34 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT0_MASK 0x0000000400000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT1_SHFT 35 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT1_MASK 0x0000000800000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT2_SHFT 36 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT2_MASK 0x0000001000000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT3_SHFT 37 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT3_MASK 0x0000002000000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT4_SHFT 38 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT4_MASK 0x0000004000000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT5_SHFT 39 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT5_MASK 0x0000008000000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT6_SHFT 40 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT6_MASK 0x0000010000000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT7_SHFT 41 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT7_MASK 0x0000020000000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT8_SHFT 42 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT8_MASK 0x0000040000000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT9_SHFT 43 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT9_MASK 0x0000080000000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT10_SHFT 44 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT10_MASK 0x0000100000000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT11_SHFT 45 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT11_MASK 0x0000200000000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT12_SHFT 46 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT12_MASK 0x0000400000000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT13_SHFT 47 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT13_MASK 0x0000800000000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT14_SHFT 48 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT14_MASK 0x0001000000000000UL +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT15_SHFT 49 +#define UV2H_EVENT_OCCURRED1_GR1_TLB_INT15_MASK 0x0002000000000000UL +#define UV2H_EVENT_OCCURRED1_RTC_INTERVAL_INT_SHFT 50 +#define UV2H_EVENT_OCCURRED1_RTC_INTERVAL_INT_MASK 0x0004000000000000UL +#define UV2H_EVENT_OCCURRED1_BAU_DASHBOARD_INT_SHFT 51 +#define UV2H_EVENT_OCCURRED1_BAU_DASHBOARD_INT_MASK 0x0008000000000000UL + +#define UVH_EVENT_OCCURRED1_EXTIO_INT0_MASK ( \ + is_uv(UV5) ? 0x0000000000000002UL : \ + 0) +#define UVH_EVENT_OCCURRED1_EXTIO_INT0_SHFT ( \ + is_uv(UV5) ? 1 : \ + -1) + +union uvyh_event_occurred1_u { + unsigned long v; + + /* UVYH common struct */ + struct uvyh_event_occurred1_s { + unsigned long ipi_int:1; /* RW */ + unsigned long extio_int0:1; /* RW */ + unsigned long extio_int1:1; /* RW */ + unsigned long extio_int2:1; /* RW */ + unsigned long extio_int3:1; /* RW */ + unsigned long profile_int:1; /* RW */ + unsigned long bau_data:1; /* RW */ + unsigned long proc_general:1; /* RW */ + unsigned long xh_tlb_int0:1; /* RW */ + unsigned long xh_tlb_int1:1; /* RW */ + unsigned long xh_tlb_int2:1; /* RW */ + unsigned long xh_tlb_int3:1; /* RW */ + unsigned long xh_tlb_int4:1; /* RW */ + unsigned long xh_tlb_int5:1; /* RW */ + unsigned long rdm_tlb_int0:1; /* RW */ + unsigned long rdm_tlb_int1:1; /* RW */ + unsigned long rdm_tlb_int2:1; /* RW */ + unsigned long rdm_tlb_int3:1; /* RW */ + unsigned long rdm_tlb_int4:1; /* RW */ + unsigned long rdm_tlb_int5:1; /* RW */ + unsigned long rdm_tlb_int6:1; /* RW */ + unsigned long rdm_tlb_int7:1; /* RW */ + unsigned long rdm_tlb_int8:1; /* RW */ + unsigned long rdm_tlb_int9:1; /* RW */ + unsigned long rdm_tlb_int10:1; /* RW */ + unsigned long rdm_tlb_int11:1; /* RW */ + unsigned long rdm_tlb_int12:1; /* RW */ + unsigned long rdm_tlb_int13:1; /* RW */ + unsigned long rdm_tlb_int14:1; /* RW */ + unsigned long rdm_tlb_int15:1; /* RW */ + unsigned long rdm_tlb_int16:1; /* RW */ + unsigned long rdm_tlb_int17:1; /* RW */ + unsigned long rdm_tlb_int18:1; /* RW */ + unsigned long rdm_tlb_int19:1; /* RW */ + unsigned long rdm_tlb_int20:1; /* RW */ + unsigned long rdm_tlb_int21:1; /* RW */ + unsigned long rdm_tlb_int22:1; /* RW */ + unsigned long rdm_tlb_int23:1; /* RW */ + unsigned long rsvd_38_63:26; + } sy; + + /* UV5 unique struct */ + struct uv5h_event_occurred1_s { + unsigned long ipi_int:1; /* RW */ + unsigned long extio_int0:1; /* RW */ + unsigned long extio_int1:1; /* RW */ + unsigned long extio_int2:1; /* RW */ + unsigned long extio_int3:1; /* RW */ + unsigned long profile_int:1; /* RW */ + unsigned long bau_data:1; /* RW */ + unsigned long proc_general:1; /* RW */ + unsigned long xh_tlb_int0:1; /* RW */ + unsigned long xh_tlb_int1:1; /* RW */ + unsigned long xh_tlb_int2:1; /* RW */ + unsigned long xh_tlb_int3:1; /* RW */ + unsigned long xh_tlb_int4:1; /* RW */ + unsigned long xh_tlb_int5:1; /* RW */ + unsigned long rdm_tlb_int0:1; /* RW */ + unsigned long rdm_tlb_int1:1; /* RW */ + unsigned long rdm_tlb_int2:1; /* RW */ + unsigned long rdm_tlb_int3:1; /* RW */ + unsigned long rdm_tlb_int4:1; /* RW */ + unsigned long rdm_tlb_int5:1; /* RW */ + unsigned long rdm_tlb_int6:1; /* RW */ + unsigned long rdm_tlb_int7:1; /* RW */ + unsigned long rdm_tlb_int8:1; /* RW */ + unsigned long rdm_tlb_int9:1; /* RW */ + unsigned long rdm_tlb_int10:1; /* RW */ + unsigned long rdm_tlb_int11:1; /* RW */ + unsigned long rdm_tlb_int12:1; /* RW */ + unsigned long rdm_tlb_int13:1; /* RW */ + unsigned long rdm_tlb_int14:1; /* RW */ + unsigned long rdm_tlb_int15:1; /* RW */ + unsigned long rdm_tlb_int16:1; /* RW */ + unsigned long rdm_tlb_int17:1; /* RW */ + unsigned long rdm_tlb_int18:1; /* RW */ + unsigned long rdm_tlb_int19:1; /* RW */ + unsigned long rdm_tlb_int20:1; /* RW */ + unsigned long rdm_tlb_int21:1; /* RW */ + unsigned long rdm_tlb_int22:1; /* RW */ + unsigned long rdm_tlb_int23:1; /* RW */ + unsigned long rsvd_38_63:26; + } s5; + + /* UV4 unique struct */ + struct uv4h_event_occurred1_s { + unsigned long profile_int:1; /* RW */ + unsigned long bau_data:1; /* RW */ + unsigned long proc_general:1; /* RW */ + unsigned long gr0_tlb_int0:1; /* RW */ + unsigned long gr0_tlb_int1:1; /* RW */ + unsigned long gr0_tlb_int2:1; /* RW */ + unsigned long gr0_tlb_int3:1; /* RW */ + unsigned long gr0_tlb_int4:1; /* RW */ + unsigned long gr0_tlb_int5:1; /* RW */ + unsigned long gr0_tlb_int6:1; /* RW */ + unsigned long gr0_tlb_int7:1; /* RW */ + unsigned long gr0_tlb_int8:1; /* RW */ + unsigned long gr0_tlb_int9:1; /* RW */ + unsigned long gr0_tlb_int10:1; /* RW */ + unsigned long gr0_tlb_int11:1; /* RW */ + unsigned long gr0_tlb_int12:1; /* RW */ + unsigned long gr0_tlb_int13:1; /* RW */ + unsigned long gr0_tlb_int14:1; /* RW */ + unsigned long gr0_tlb_int15:1; /* RW */ + unsigned long gr0_tlb_int16:1; /* RW */ + unsigned long gr0_tlb_int17:1; /* RW */ + unsigned long gr0_tlb_int18:1; /* RW */ + unsigned long gr0_tlb_int19:1; /* RW */ + unsigned long gr0_tlb_int20:1; /* RW */ + unsigned long gr0_tlb_int21:1; /* RW */ + unsigned long gr0_tlb_int22:1; /* RW */ + unsigned long gr0_tlb_int23:1; /* RW */ + unsigned long gr1_tlb_int0:1; /* RW */ + unsigned long gr1_tlb_int1:1; /* RW */ + unsigned long gr1_tlb_int2:1; /* RW */ + unsigned long gr1_tlb_int3:1; /* RW */ + unsigned long gr1_tlb_int4:1; /* RW */ + unsigned long gr1_tlb_int5:1; /* RW */ + unsigned long gr1_tlb_int6:1; /* RW */ + unsigned long gr1_tlb_int7:1; /* RW */ + unsigned long gr1_tlb_int8:1; /* RW */ + unsigned long gr1_tlb_int9:1; /* RW */ + unsigned long gr1_tlb_int10:1; /* RW */ + unsigned long gr1_tlb_int11:1; /* RW */ + unsigned long gr1_tlb_int12:1; /* RW */ + unsigned long gr1_tlb_int13:1; /* RW */ + unsigned long gr1_tlb_int14:1; /* RW */ + unsigned long gr1_tlb_int15:1; /* RW */ + unsigned long gr1_tlb_int16:1; /* RW */ + unsigned long gr1_tlb_int17:1; /* RW */ + unsigned long gr1_tlb_int18:1; /* RW */ + unsigned long gr1_tlb_int19:1; /* RW */ + unsigned long gr1_tlb_int20:1; /* RW */ + unsigned long gr1_tlb_int21:1; /* RW */ + unsigned long gr1_tlb_int22:1; /* RW */ + unsigned long gr1_tlb_int23:1; /* RW */ + unsigned long rsvd_51_63:13; + } s4; + + /* UV3 unique struct */ + struct uv3h_event_occurred1_s { + unsigned long bau_data:1; /* RW */ + unsigned long power_management_req:1; /* RW */ + unsigned long message_accelerator_int0:1; /* RW */ + unsigned long message_accelerator_int1:1; /* RW */ + unsigned long message_accelerator_int2:1; /* RW */ + unsigned long message_accelerator_int3:1; /* RW */ + unsigned long message_accelerator_int4:1; /* RW */ + unsigned long message_accelerator_int5:1; /* RW */ + unsigned long message_accelerator_int6:1; /* RW */ + unsigned long message_accelerator_int7:1; /* RW */ + unsigned long message_accelerator_int8:1; /* RW */ + unsigned long message_accelerator_int9:1; /* RW */ + unsigned long message_accelerator_int10:1; /* RW */ + unsigned long message_accelerator_int11:1; /* RW */ + unsigned long message_accelerator_int12:1; /* RW */ + unsigned long message_accelerator_int13:1; /* RW */ + unsigned long message_accelerator_int14:1; /* RW */ + unsigned long message_accelerator_int15:1; /* RW */ + unsigned long gr0_tlb_int0:1; /* RW */ + unsigned long gr0_tlb_int1:1; /* RW */ + unsigned long gr0_tlb_int2:1; /* RW */ + unsigned long gr0_tlb_int3:1; /* RW */ + unsigned long gr0_tlb_int4:1; /* RW */ + unsigned long gr0_tlb_int5:1; /* RW */ + unsigned long gr0_tlb_int6:1; /* RW */ + unsigned long gr0_tlb_int7:1; /* RW */ + unsigned long gr0_tlb_int8:1; /* RW */ + unsigned long gr0_tlb_int9:1; /* RW */ + unsigned long gr0_tlb_int10:1; /* RW */ + unsigned long gr0_tlb_int11:1; /* RW */ + unsigned long gr0_tlb_int12:1; /* RW */ + unsigned long gr0_tlb_int13:1; /* RW */ + unsigned long gr0_tlb_int14:1; /* RW */ + unsigned long gr0_tlb_int15:1; /* RW */ + unsigned long gr1_tlb_int0:1; /* RW */ + unsigned long gr1_tlb_int1:1; /* RW */ + unsigned long gr1_tlb_int2:1; /* RW */ + unsigned long gr1_tlb_int3:1; /* RW */ + unsigned long gr1_tlb_int4:1; /* RW */ + unsigned long gr1_tlb_int5:1; /* RW */ + unsigned long gr1_tlb_int6:1; /* RW */ + unsigned long gr1_tlb_int7:1; /* RW */ + unsigned long gr1_tlb_int8:1; /* RW */ + unsigned long gr1_tlb_int9:1; /* RW */ + unsigned long gr1_tlb_int10:1; /* RW */ + unsigned long gr1_tlb_int11:1; /* RW */ + unsigned long gr1_tlb_int12:1; /* RW */ + unsigned long gr1_tlb_int13:1; /* RW */ + unsigned long gr1_tlb_int14:1; /* RW */ + unsigned long gr1_tlb_int15:1; /* RW */ + unsigned long rtc_interval_int:1; /* RW */ + unsigned long bau_dashboard_int:1; /* RW */ + unsigned long rsvd_52_63:12; + } s3; + + /* UV2 unique struct */ + struct uv2h_event_occurred1_s { + unsigned long bau_data:1; /* RW */ + unsigned long power_management_req:1; /* RW */ + unsigned long message_accelerator_int0:1; /* RW */ + unsigned long message_accelerator_int1:1; /* RW */ + unsigned long message_accelerator_int2:1; /* RW */ + unsigned long message_accelerator_int3:1; /* RW */ + unsigned long message_accelerator_int4:1; /* RW */ + unsigned long message_accelerator_int5:1; /* RW */ + unsigned long message_accelerator_int6:1; /* RW */ + unsigned long message_accelerator_int7:1; /* RW */ + unsigned long message_accelerator_int8:1; /* RW */ + unsigned long message_accelerator_int9:1; /* RW */ + unsigned long message_accelerator_int10:1; /* RW */ + unsigned long message_accelerator_int11:1; /* RW */ + unsigned long message_accelerator_int12:1; /* RW */ + unsigned long message_accelerator_int13:1; /* RW */ + unsigned long message_accelerator_int14:1; /* RW */ + unsigned long message_accelerator_int15:1; /* RW */ + unsigned long gr0_tlb_int0:1; /* RW */ + unsigned long gr0_tlb_int1:1; /* RW */ + unsigned long gr0_tlb_int2:1; /* RW */ + unsigned long gr0_tlb_int3:1; /* RW */ + unsigned long gr0_tlb_int4:1; /* RW */ + unsigned long gr0_tlb_int5:1; /* RW */ + unsigned long gr0_tlb_int6:1; /* RW */ + unsigned long gr0_tlb_int7:1; /* RW */ + unsigned long gr0_tlb_int8:1; /* RW */ + unsigned long gr0_tlb_int9:1; /* RW */ + unsigned long gr0_tlb_int10:1; /* RW */ + unsigned long gr0_tlb_int11:1; /* RW */ + unsigned long gr0_tlb_int12:1; /* RW */ + unsigned long gr0_tlb_int13:1; /* RW */ + unsigned long gr0_tlb_int14:1; /* RW */ + unsigned long gr0_tlb_int15:1; /* RW */ + unsigned long gr1_tlb_int0:1; /* RW */ + unsigned long gr1_tlb_int1:1; /* RW */ + unsigned long gr1_tlb_int2:1; /* RW */ + unsigned long gr1_tlb_int3:1; /* RW */ + unsigned long gr1_tlb_int4:1; /* RW */ + unsigned long gr1_tlb_int5:1; /* RW */ + unsigned long gr1_tlb_int6:1; /* RW */ + unsigned long gr1_tlb_int7:1; /* RW */ + unsigned long gr1_tlb_int8:1; /* RW */ + unsigned long gr1_tlb_int9:1; /* RW */ + unsigned long gr1_tlb_int10:1; /* RW */ + unsigned long gr1_tlb_int11:1; /* RW */ + unsigned long gr1_tlb_int12:1; /* RW */ + unsigned long gr1_tlb_int13:1; /* RW */ + unsigned long gr1_tlb_int14:1; /* RW */ + unsigned long gr1_tlb_int15:1; /* RW */ + unsigned long rtc_interval_int:1; /* RW */ + unsigned long bau_dashboard_int:1; /* RW */ + unsigned long rsvd_52_63:12; + } s2; +}; + +/* ========================================================================= */ +/* UVH_EVENT_OCCURRED1_ALIAS */ +/* ========================================================================= */ +#define UVH_EVENT_OCCURRED1_ALIAS 0x70088UL + + +/* ========================================================================= */ +/* UVH_EVENT_OCCURRED2 */ +/* ========================================================================= */ +#define UVH_EVENT_OCCURRED2 0x70100UL + + + +/* UVYH common defines */ +#define UVYH_EVENT_OCCURRED2_RTC_INTERVAL_INT_SHFT 0 +#define UVYH_EVENT_OCCURRED2_RTC_INTERVAL_INT_MASK 0x0000000000000001UL +#define UVYH_EVENT_OCCURRED2_BAU_DASHBOARD_INT_SHFT 1 +#define UVYH_EVENT_OCCURRED2_BAU_DASHBOARD_INT_MASK 0x0000000000000002UL +#define UVYH_EVENT_OCCURRED2_RTC_0_SHFT 2 +#define UVYH_EVENT_OCCURRED2_RTC_0_MASK 0x0000000000000004UL +#define UVYH_EVENT_OCCURRED2_RTC_1_SHFT 3 +#define UVYH_EVENT_OCCURRED2_RTC_1_MASK 0x0000000000000008UL +#define UVYH_EVENT_OCCURRED2_RTC_2_SHFT 4 +#define UVYH_EVENT_OCCURRED2_RTC_2_MASK 0x0000000000000010UL +#define UVYH_EVENT_OCCURRED2_RTC_3_SHFT 5 +#define UVYH_EVENT_OCCURRED2_RTC_3_MASK 0x0000000000000020UL +#define UVYH_EVENT_OCCURRED2_RTC_4_SHFT 6 +#define UVYH_EVENT_OCCURRED2_RTC_4_MASK 0x0000000000000040UL +#define UVYH_EVENT_OCCURRED2_RTC_5_SHFT 7 +#define UVYH_EVENT_OCCURRED2_RTC_5_MASK 0x0000000000000080UL +#define UVYH_EVENT_OCCURRED2_RTC_6_SHFT 8 +#define UVYH_EVENT_OCCURRED2_RTC_6_MASK 0x0000000000000100UL +#define UVYH_EVENT_OCCURRED2_RTC_7_SHFT 9 +#define UVYH_EVENT_OCCURRED2_RTC_7_MASK 0x0000000000000200UL +#define UVYH_EVENT_OCCURRED2_RTC_8_SHFT 10 +#define UVYH_EVENT_OCCURRED2_RTC_8_MASK 0x0000000000000400UL +#define UVYH_EVENT_OCCURRED2_RTC_9_SHFT 11 +#define UVYH_EVENT_OCCURRED2_RTC_9_MASK 0x0000000000000800UL +#define UVYH_EVENT_OCCURRED2_RTC_10_SHFT 12 +#define UVYH_EVENT_OCCURRED2_RTC_10_MASK 0x0000000000001000UL +#define UVYH_EVENT_OCCURRED2_RTC_11_SHFT 13 +#define UVYH_EVENT_OCCURRED2_RTC_11_MASK 0x0000000000002000UL +#define UVYH_EVENT_OCCURRED2_RTC_12_SHFT 14 +#define UVYH_EVENT_OCCURRED2_RTC_12_MASK 0x0000000000004000UL +#define UVYH_EVENT_OCCURRED2_RTC_13_SHFT 15 +#define UVYH_EVENT_OCCURRED2_RTC_13_MASK 0x0000000000008000UL +#define UVYH_EVENT_OCCURRED2_RTC_14_SHFT 16 +#define UVYH_EVENT_OCCURRED2_RTC_14_MASK 0x0000000000010000UL +#define UVYH_EVENT_OCCURRED2_RTC_15_SHFT 17 +#define UVYH_EVENT_OCCURRED2_RTC_15_MASK 0x0000000000020000UL +#define UVYH_EVENT_OCCURRED2_RTC_16_SHFT 18 +#define UVYH_EVENT_OCCURRED2_RTC_16_MASK 0x0000000000040000UL +#define UVYH_EVENT_OCCURRED2_RTC_17_SHFT 19 +#define UVYH_EVENT_OCCURRED2_RTC_17_MASK 0x0000000000080000UL +#define UVYH_EVENT_OCCURRED2_RTC_18_SHFT 20 +#define UVYH_EVENT_OCCURRED2_RTC_18_MASK 0x0000000000100000UL +#define UVYH_EVENT_OCCURRED2_RTC_19_SHFT 21 +#define UVYH_EVENT_OCCURRED2_RTC_19_MASK 0x0000000000200000UL +#define UVYH_EVENT_OCCURRED2_RTC_20_SHFT 22 +#define UVYH_EVENT_OCCURRED2_RTC_20_MASK 0x0000000000400000UL +#define UVYH_EVENT_OCCURRED2_RTC_21_SHFT 23 +#define UVYH_EVENT_OCCURRED2_RTC_21_MASK 0x0000000000800000UL +#define UVYH_EVENT_OCCURRED2_RTC_22_SHFT 24 +#define UVYH_EVENT_OCCURRED2_RTC_22_MASK 0x0000000001000000UL +#define UVYH_EVENT_OCCURRED2_RTC_23_SHFT 25 +#define UVYH_EVENT_OCCURRED2_RTC_23_MASK 0x0000000002000000UL +#define UVYH_EVENT_OCCURRED2_RTC_24_SHFT 26 +#define UVYH_EVENT_OCCURRED2_RTC_24_MASK 0x0000000004000000UL +#define UVYH_EVENT_OCCURRED2_RTC_25_SHFT 27 +#define UVYH_EVENT_OCCURRED2_RTC_25_MASK 0x0000000008000000UL +#define UVYH_EVENT_OCCURRED2_RTC_26_SHFT 28 +#define UVYH_EVENT_OCCURRED2_RTC_26_MASK 0x0000000010000000UL +#define UVYH_EVENT_OCCURRED2_RTC_27_SHFT 29 +#define UVYH_EVENT_OCCURRED2_RTC_27_MASK 0x0000000020000000UL +#define UVYH_EVENT_OCCURRED2_RTC_28_SHFT 30 +#define UVYH_EVENT_OCCURRED2_RTC_28_MASK 0x0000000040000000UL +#define UVYH_EVENT_OCCURRED2_RTC_29_SHFT 31 +#define UVYH_EVENT_OCCURRED2_RTC_29_MASK 0x0000000080000000UL +#define UVYH_EVENT_OCCURRED2_RTC_30_SHFT 32 +#define UVYH_EVENT_OCCURRED2_RTC_30_MASK 0x0000000100000000UL +#define UVYH_EVENT_OCCURRED2_RTC_31_SHFT 33 +#define UVYH_EVENT_OCCURRED2_RTC_31_MASK 0x0000000200000000UL + +/* UV4 unique defines */ +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT0_SHFT 0 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT0_MASK 0x0000000000000001UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT1_SHFT 1 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT1_MASK 0x0000000000000002UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT2_SHFT 2 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT2_MASK 0x0000000000000004UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT3_SHFT 3 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT3_MASK 0x0000000000000008UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT4_SHFT 4 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT4_MASK 0x0000000000000010UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT5_SHFT 5 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT5_MASK 0x0000000000000020UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT6_SHFT 6 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT6_MASK 0x0000000000000040UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT7_SHFT 7 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT7_MASK 0x0000000000000080UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT8_SHFT 8 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT8_MASK 0x0000000000000100UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT9_SHFT 9 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT9_MASK 0x0000000000000200UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT10_SHFT 10 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT10_MASK 0x0000000000000400UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT11_SHFT 11 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT11_MASK 0x0000000000000800UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT12_SHFT 12 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT12_MASK 0x0000000000001000UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT13_SHFT 13 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT13_MASK 0x0000000000002000UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT14_SHFT 14 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT14_MASK 0x0000000000004000UL +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT15_SHFT 15 +#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT15_MASK 0x0000000000008000UL +#define UV4H_EVENT_OCCURRED2_RTC_INTERVAL_INT_SHFT 16 +#define UV4H_EVENT_OCCURRED2_RTC_INTERVAL_INT_MASK 0x0000000000010000UL +#define UV4H_EVENT_OCCURRED2_BAU_DASHBOARD_INT_SHFT 17 +#define UV4H_EVENT_OCCURRED2_BAU_DASHBOARD_INT_MASK 0x0000000000020000UL +#define UV4H_EVENT_OCCURRED2_RTC_0_SHFT 18 +#define UV4H_EVENT_OCCURRED2_RTC_0_MASK 0x0000000000040000UL +#define UV4H_EVENT_OCCURRED2_RTC_1_SHFT 19 +#define UV4H_EVENT_OCCURRED2_RTC_1_MASK 0x0000000000080000UL +#define UV4H_EVENT_OCCURRED2_RTC_2_SHFT 20 +#define UV4H_EVENT_OCCURRED2_RTC_2_MASK 0x0000000000100000UL +#define UV4H_EVENT_OCCURRED2_RTC_3_SHFT 21 +#define UV4H_EVENT_OCCURRED2_RTC_3_MASK 0x0000000000200000UL +#define UV4H_EVENT_OCCURRED2_RTC_4_SHFT 22 +#define UV4H_EVENT_OCCURRED2_RTC_4_MASK 0x0000000000400000UL +#define UV4H_EVENT_OCCURRED2_RTC_5_SHFT 23 +#define UV4H_EVENT_OCCURRED2_RTC_5_MASK 0x0000000000800000UL +#define UV4H_EVENT_OCCURRED2_RTC_6_SHFT 24 +#define UV4H_EVENT_OCCURRED2_RTC_6_MASK 0x0000000001000000UL +#define UV4H_EVENT_OCCURRED2_RTC_7_SHFT 25 +#define UV4H_EVENT_OCCURRED2_RTC_7_MASK 0x0000000002000000UL +#define UV4H_EVENT_OCCURRED2_RTC_8_SHFT 26 +#define UV4H_EVENT_OCCURRED2_RTC_8_MASK 0x0000000004000000UL +#define UV4H_EVENT_OCCURRED2_RTC_9_SHFT 27 +#define UV4H_EVENT_OCCURRED2_RTC_9_MASK 0x0000000008000000UL +#define UV4H_EVENT_OCCURRED2_RTC_10_SHFT 28 +#define UV4H_EVENT_OCCURRED2_RTC_10_MASK 0x0000000010000000UL +#define UV4H_EVENT_OCCURRED2_RTC_11_SHFT 29 +#define UV4H_EVENT_OCCURRED2_RTC_11_MASK 0x0000000020000000UL +#define UV4H_EVENT_OCCURRED2_RTC_12_SHFT 30 +#define UV4H_EVENT_OCCURRED2_RTC_12_MASK 0x0000000040000000UL +#define UV4H_EVENT_OCCURRED2_RTC_13_SHFT 31 +#define UV4H_EVENT_OCCURRED2_RTC_13_MASK 0x0000000080000000UL +#define UV4H_EVENT_OCCURRED2_RTC_14_SHFT 32 +#define UV4H_EVENT_OCCURRED2_RTC_14_MASK 0x0000000100000000UL +#define UV4H_EVENT_OCCURRED2_RTC_15_SHFT 33 +#define UV4H_EVENT_OCCURRED2_RTC_15_MASK 0x0000000200000000UL +#define UV4H_EVENT_OCCURRED2_RTC_16_SHFT 34 +#define UV4H_EVENT_OCCURRED2_RTC_16_MASK 0x0000000400000000UL +#define UV4H_EVENT_OCCURRED2_RTC_17_SHFT 35 +#define UV4H_EVENT_OCCURRED2_RTC_17_MASK 0x0000000800000000UL +#define UV4H_EVENT_OCCURRED2_RTC_18_SHFT 36 +#define UV4H_EVENT_OCCURRED2_RTC_18_MASK 0x0000001000000000UL +#define UV4H_EVENT_OCCURRED2_RTC_19_SHFT 37 +#define UV4H_EVENT_OCCURRED2_RTC_19_MASK 0x0000002000000000UL +#define UV4H_EVENT_OCCURRED2_RTC_20_SHFT 38 +#define UV4H_EVENT_OCCURRED2_RTC_20_MASK 0x0000004000000000UL +#define UV4H_EVENT_OCCURRED2_RTC_21_SHFT 39 +#define UV4H_EVENT_OCCURRED2_RTC_21_MASK 0x0000008000000000UL +#define UV4H_EVENT_OCCURRED2_RTC_22_SHFT 40 +#define UV4H_EVENT_OCCURRED2_RTC_22_MASK 0x0000010000000000UL +#define UV4H_EVENT_OCCURRED2_RTC_23_SHFT 41 +#define UV4H_EVENT_OCCURRED2_RTC_23_MASK 0x0000020000000000UL +#define UV4H_EVENT_OCCURRED2_RTC_24_SHFT 42 +#define UV4H_EVENT_OCCURRED2_RTC_24_MASK 0x0000040000000000UL +#define UV4H_EVENT_OCCURRED2_RTC_25_SHFT 43 +#define UV4H_EVENT_OCCURRED2_RTC_25_MASK 0x0000080000000000UL +#define UV4H_EVENT_OCCURRED2_RTC_26_SHFT 44 +#define UV4H_EVENT_OCCURRED2_RTC_26_MASK 0x0000100000000000UL +#define UV4H_EVENT_OCCURRED2_RTC_27_SHFT 45 +#define UV4H_EVENT_OCCURRED2_RTC_27_MASK 0x0000200000000000UL +#define UV4H_EVENT_OCCURRED2_RTC_28_SHFT 46 +#define UV4H_EVENT_OCCURRED2_RTC_28_MASK 0x0000400000000000UL +#define UV4H_EVENT_OCCURRED2_RTC_29_SHFT 47 +#define UV4H_EVENT_OCCURRED2_RTC_29_MASK 0x0000800000000000UL +#define UV4H_EVENT_OCCURRED2_RTC_30_SHFT 48 +#define UV4H_EVENT_OCCURRED2_RTC_30_MASK 0x0001000000000000UL +#define UV4H_EVENT_OCCURRED2_RTC_31_SHFT 49 +#define UV4H_EVENT_OCCURRED2_RTC_31_MASK 0x0002000000000000UL + +/* UV3 unique defines */ +#define UV3H_EVENT_OCCURRED2_RTC_0_SHFT 0 +#define UV3H_EVENT_OCCURRED2_RTC_0_MASK 0x0000000000000001UL +#define UV3H_EVENT_OCCURRED2_RTC_1_SHFT 1 +#define UV3H_EVENT_OCCURRED2_RTC_1_MASK 0x0000000000000002UL +#define UV3H_EVENT_OCCURRED2_RTC_2_SHFT 2 +#define UV3H_EVENT_OCCURRED2_RTC_2_MASK 0x0000000000000004UL +#define UV3H_EVENT_OCCURRED2_RTC_3_SHFT 3 +#define UV3H_EVENT_OCCURRED2_RTC_3_MASK 0x0000000000000008UL +#define UV3H_EVENT_OCCURRED2_RTC_4_SHFT 4 +#define UV3H_EVENT_OCCURRED2_RTC_4_MASK 0x0000000000000010UL +#define UV3H_EVENT_OCCURRED2_RTC_5_SHFT 5 +#define UV3H_EVENT_OCCURRED2_RTC_5_MASK 0x0000000000000020UL +#define UV3H_EVENT_OCCURRED2_RTC_6_SHFT 6 +#define UV3H_EVENT_OCCURRED2_RTC_6_MASK 0x0000000000000040UL +#define UV3H_EVENT_OCCURRED2_RTC_7_SHFT 7 +#define UV3H_EVENT_OCCURRED2_RTC_7_MASK 0x0000000000000080UL +#define UV3H_EVENT_OCCURRED2_RTC_8_SHFT 8 +#define UV3H_EVENT_OCCURRED2_RTC_8_MASK 0x0000000000000100UL +#define UV3H_EVENT_OCCURRED2_RTC_9_SHFT 9 +#define UV3H_EVENT_OCCURRED2_RTC_9_MASK 0x0000000000000200UL +#define UV3H_EVENT_OCCURRED2_RTC_10_SHFT 10 +#define UV3H_EVENT_OCCURRED2_RTC_10_MASK 0x0000000000000400UL +#define UV3H_EVENT_OCCURRED2_RTC_11_SHFT 11 +#define UV3H_EVENT_OCCURRED2_RTC_11_MASK 0x0000000000000800UL +#define UV3H_EVENT_OCCURRED2_RTC_12_SHFT 12 +#define UV3H_EVENT_OCCURRED2_RTC_12_MASK 0x0000000000001000UL +#define UV3H_EVENT_OCCURRED2_RTC_13_SHFT 13 +#define UV3H_EVENT_OCCURRED2_RTC_13_MASK 0x0000000000002000UL +#define UV3H_EVENT_OCCURRED2_RTC_14_SHFT 14 +#define UV3H_EVENT_OCCURRED2_RTC_14_MASK 0x0000000000004000UL +#define UV3H_EVENT_OCCURRED2_RTC_15_SHFT 15 +#define UV3H_EVENT_OCCURRED2_RTC_15_MASK 0x0000000000008000UL +#define UV3H_EVENT_OCCURRED2_RTC_16_SHFT 16 +#define UV3H_EVENT_OCCURRED2_RTC_16_MASK 0x0000000000010000UL +#define UV3H_EVENT_OCCURRED2_RTC_17_SHFT 17 +#define UV3H_EVENT_OCCURRED2_RTC_17_MASK 0x0000000000020000UL +#define UV3H_EVENT_OCCURRED2_RTC_18_SHFT 18 +#define UV3H_EVENT_OCCURRED2_RTC_18_MASK 0x0000000000040000UL +#define UV3H_EVENT_OCCURRED2_RTC_19_SHFT 19 +#define UV3H_EVENT_OCCURRED2_RTC_19_MASK 0x0000000000080000UL +#define UV3H_EVENT_OCCURRED2_RTC_20_SHFT 20 +#define UV3H_EVENT_OCCURRED2_RTC_20_MASK 0x0000000000100000UL +#define UV3H_EVENT_OCCURRED2_RTC_21_SHFT 21 +#define UV3H_EVENT_OCCURRED2_RTC_21_MASK 0x0000000000200000UL +#define UV3H_EVENT_OCCURRED2_RTC_22_SHFT 22 +#define UV3H_EVENT_OCCURRED2_RTC_22_MASK 0x0000000000400000UL +#define UV3H_EVENT_OCCURRED2_RTC_23_SHFT 23 +#define UV3H_EVENT_OCCURRED2_RTC_23_MASK 0x0000000000800000UL +#define UV3H_EVENT_OCCURRED2_RTC_24_SHFT 24 +#define UV3H_EVENT_OCCURRED2_RTC_24_MASK 0x0000000001000000UL +#define UV3H_EVENT_OCCURRED2_RTC_25_SHFT 25 +#define UV3H_EVENT_OCCURRED2_RTC_25_MASK 0x0000000002000000UL +#define UV3H_EVENT_OCCURRED2_RTC_26_SHFT 26 +#define UV3H_EVENT_OCCURRED2_RTC_26_MASK 0x0000000004000000UL +#define UV3H_EVENT_OCCURRED2_RTC_27_SHFT 27 +#define UV3H_EVENT_OCCURRED2_RTC_27_MASK 0x0000000008000000UL +#define UV3H_EVENT_OCCURRED2_RTC_28_SHFT 28 +#define UV3H_EVENT_OCCURRED2_RTC_28_MASK 0x0000000010000000UL +#define UV3H_EVENT_OCCURRED2_RTC_29_SHFT 29 +#define UV3H_EVENT_OCCURRED2_RTC_29_MASK 0x0000000020000000UL +#define UV3H_EVENT_OCCURRED2_RTC_30_SHFT 30 +#define UV3H_EVENT_OCCURRED2_RTC_30_MASK 0x0000000040000000UL +#define UV3H_EVENT_OCCURRED2_RTC_31_SHFT 31 +#define UV3H_EVENT_OCCURRED2_RTC_31_MASK 0x0000000080000000UL + +/* UV2 unique defines */ +#define UV2H_EVENT_OCCURRED2_RTC_0_SHFT 0 +#define UV2H_EVENT_OCCURRED2_RTC_0_MASK 0x0000000000000001UL +#define UV2H_EVENT_OCCURRED2_RTC_1_SHFT 1 +#define UV2H_EVENT_OCCURRED2_RTC_1_MASK 0x0000000000000002UL +#define UV2H_EVENT_OCCURRED2_RTC_2_SHFT 2 +#define UV2H_EVENT_OCCURRED2_RTC_2_MASK 0x0000000000000004UL +#define UV2H_EVENT_OCCURRED2_RTC_3_SHFT 3 +#define UV2H_EVENT_OCCURRED2_RTC_3_MASK 0x0000000000000008UL +#define UV2H_EVENT_OCCURRED2_RTC_4_SHFT 4 +#define UV2H_EVENT_OCCURRED2_RTC_4_MASK 0x0000000000000010UL +#define UV2H_EVENT_OCCURRED2_RTC_5_SHFT 5 +#define UV2H_EVENT_OCCURRED2_RTC_5_MASK 0x0000000000000020UL +#define UV2H_EVENT_OCCURRED2_RTC_6_SHFT 6 +#define UV2H_EVENT_OCCURRED2_RTC_6_MASK 0x0000000000000040UL +#define UV2H_EVENT_OCCURRED2_RTC_7_SHFT 7 +#define UV2H_EVENT_OCCURRED2_RTC_7_MASK 0x0000000000000080UL +#define UV2H_EVENT_OCCURRED2_RTC_8_SHFT 8 +#define UV2H_EVENT_OCCURRED2_RTC_8_MASK 0x0000000000000100UL +#define UV2H_EVENT_OCCURRED2_RTC_9_SHFT 9 +#define UV2H_EVENT_OCCURRED2_RTC_9_MASK 0x0000000000000200UL +#define UV2H_EVENT_OCCURRED2_RTC_10_SHFT 10 +#define UV2H_EVENT_OCCURRED2_RTC_10_MASK 0x0000000000000400UL +#define UV2H_EVENT_OCCURRED2_RTC_11_SHFT 11 +#define UV2H_EVENT_OCCURRED2_RTC_11_MASK 0x0000000000000800UL +#define UV2H_EVENT_OCCURRED2_RTC_12_SHFT 12 +#define UV2H_EVENT_OCCURRED2_RTC_12_MASK 0x0000000000001000UL +#define UV2H_EVENT_OCCURRED2_RTC_13_SHFT 13 +#define UV2H_EVENT_OCCURRED2_RTC_13_MASK 0x0000000000002000UL +#define UV2H_EVENT_OCCURRED2_RTC_14_SHFT 14 +#define UV2H_EVENT_OCCURRED2_RTC_14_MASK 0x0000000000004000UL +#define UV2H_EVENT_OCCURRED2_RTC_15_SHFT 15 +#define UV2H_EVENT_OCCURRED2_RTC_15_MASK 0x0000000000008000UL +#define UV2H_EVENT_OCCURRED2_RTC_16_SHFT 16 +#define UV2H_EVENT_OCCURRED2_RTC_16_MASK 0x0000000000010000UL +#define UV2H_EVENT_OCCURRED2_RTC_17_SHFT 17 +#define UV2H_EVENT_OCCURRED2_RTC_17_MASK 0x0000000000020000UL +#define UV2H_EVENT_OCCURRED2_RTC_18_SHFT 18 +#define UV2H_EVENT_OCCURRED2_RTC_18_MASK 0x0000000000040000UL +#define UV2H_EVENT_OCCURRED2_RTC_19_SHFT 19 +#define UV2H_EVENT_OCCURRED2_RTC_19_MASK 0x0000000000080000UL +#define UV2H_EVENT_OCCURRED2_RTC_20_SHFT 20 +#define UV2H_EVENT_OCCURRED2_RTC_20_MASK 0x0000000000100000UL +#define UV2H_EVENT_OCCURRED2_RTC_21_SHFT 21 +#define UV2H_EVENT_OCCURRED2_RTC_21_MASK 0x0000000000200000UL +#define UV2H_EVENT_OCCURRED2_RTC_22_SHFT 22 +#define UV2H_EVENT_OCCURRED2_RTC_22_MASK 0x0000000000400000UL +#define UV2H_EVENT_OCCURRED2_RTC_23_SHFT 23 +#define UV2H_EVENT_OCCURRED2_RTC_23_MASK 0x0000000000800000UL +#define UV2H_EVENT_OCCURRED2_RTC_24_SHFT 24 +#define UV2H_EVENT_OCCURRED2_RTC_24_MASK 0x0000000001000000UL +#define UV2H_EVENT_OCCURRED2_RTC_25_SHFT 25 +#define UV2H_EVENT_OCCURRED2_RTC_25_MASK 0x0000000002000000UL +#define UV2H_EVENT_OCCURRED2_RTC_26_SHFT 26 +#define UV2H_EVENT_OCCURRED2_RTC_26_MASK 0x0000000004000000UL +#define UV2H_EVENT_OCCURRED2_RTC_27_SHFT 27 +#define UV2H_EVENT_OCCURRED2_RTC_27_MASK 0x0000000008000000UL +#define UV2H_EVENT_OCCURRED2_RTC_28_SHFT 28 +#define UV2H_EVENT_OCCURRED2_RTC_28_MASK 0x0000000010000000UL +#define UV2H_EVENT_OCCURRED2_RTC_29_SHFT 29 +#define UV2H_EVENT_OCCURRED2_RTC_29_MASK 0x0000000020000000UL +#define UV2H_EVENT_OCCURRED2_RTC_30_SHFT 30 +#define UV2H_EVENT_OCCURRED2_RTC_30_MASK 0x0000000040000000UL +#define UV2H_EVENT_OCCURRED2_RTC_31_SHFT 31 +#define UV2H_EVENT_OCCURRED2_RTC_31_MASK 0x0000000080000000UL + +#define UVH_EVENT_OCCURRED2_RTC_1_MASK ( \ + is_uv(UV5) ? 0x0000000000000008UL : \ + is_uv(UV4) ? 0x0000000000080000UL : \ + is_uv(UV3) ? 0x0000000000000002UL : \ + is_uv(UV2) ? 0x0000000000000002UL : \ + 0) +#define UVH_EVENT_OCCURRED2_RTC_1_SHFT ( \ + is_uv(UV5) ? 3 : \ + is_uv(UV4) ? 19 : \ + is_uv(UV3) ? 1 : \ + is_uv(UV2) ? 1 : \ + -1) + +union uvyh_event_occurred2_u { + unsigned long v; + + /* UVYH common struct */ + struct uvyh_event_occurred2_s { + unsigned long rtc_interval_int:1; /* RW */ + unsigned long bau_dashboard_int:1; /* RW */ + unsigned long rtc_0:1; /* RW */ + unsigned long rtc_1:1; /* RW */ + unsigned long rtc_2:1; /* RW */ + unsigned long rtc_3:1; /* RW */ + unsigned long rtc_4:1; /* RW */ + unsigned long rtc_5:1; /* RW */ + unsigned long rtc_6:1; /* RW */ + unsigned long rtc_7:1; /* RW */ + unsigned long rtc_8:1; /* RW */ + unsigned long rtc_9:1; /* RW */ + unsigned long rtc_10:1; /* RW */ + unsigned long rtc_11:1; /* RW */ + unsigned long rtc_12:1; /* RW */ + unsigned long rtc_13:1; /* RW */ + unsigned long rtc_14:1; /* RW */ + unsigned long rtc_15:1; /* RW */ + unsigned long rtc_16:1; /* RW */ + unsigned long rtc_17:1; /* RW */ + unsigned long rtc_18:1; /* RW */ + unsigned long rtc_19:1; /* RW */ + unsigned long rtc_20:1; /* RW */ + unsigned long rtc_21:1; /* RW */ + unsigned long rtc_22:1; /* RW */ + unsigned long rtc_23:1; /* RW */ + unsigned long rtc_24:1; /* RW */ + unsigned long rtc_25:1; /* RW */ + unsigned long rtc_26:1; /* RW */ + unsigned long rtc_27:1; /* RW */ + unsigned long rtc_28:1; /* RW */ + unsigned long rtc_29:1; /* RW */ + unsigned long rtc_30:1; /* RW */ + unsigned long rtc_31:1; /* RW */ + unsigned long rsvd_34_63:30; + } sy; + + /* UV5 unique struct */ + struct uv5h_event_occurred2_s { + unsigned long rtc_interval_int:1; /* RW */ + unsigned long bau_dashboard_int:1; /* RW */ + unsigned long rtc_0:1; /* RW */ + unsigned long rtc_1:1; /* RW */ + unsigned long rtc_2:1; /* RW */ + unsigned long rtc_3:1; /* RW */ + unsigned long rtc_4:1; /* RW */ + unsigned long rtc_5:1; /* RW */ + unsigned long rtc_6:1; /* RW */ + unsigned long rtc_7:1; /* RW */ + unsigned long rtc_8:1; /* RW */ + unsigned long rtc_9:1; /* RW */ + unsigned long rtc_10:1; /* RW */ + unsigned long rtc_11:1; /* RW */ + unsigned long rtc_12:1; /* RW */ + unsigned long rtc_13:1; /* RW */ + unsigned long rtc_14:1; /* RW */ + unsigned long rtc_15:1; /* RW */ + unsigned long rtc_16:1; /* RW */ + unsigned long rtc_17:1; /* RW */ + unsigned long rtc_18:1; /* RW */ + unsigned long rtc_19:1; /* RW */ + unsigned long rtc_20:1; /* RW */ + unsigned long rtc_21:1; /* RW */ + unsigned long rtc_22:1; /* RW */ + unsigned long rtc_23:1; /* RW */ + unsigned long rtc_24:1; /* RW */ + unsigned long rtc_25:1; /* RW */ + unsigned long rtc_26:1; /* RW */ + unsigned long rtc_27:1; /* RW */ + unsigned long rtc_28:1; /* RW */ + unsigned long rtc_29:1; /* RW */ + unsigned long rtc_30:1; /* RW */ + unsigned long rtc_31:1; /* RW */ + unsigned long rsvd_34_63:30; + } s5; + + /* UV4 unique struct */ + struct uv4h_event_occurred2_s { + unsigned long message_accelerator_int0:1; /* RW */ + unsigned long message_accelerator_int1:1; /* RW */ + unsigned long message_accelerator_int2:1; /* RW */ + unsigned long message_accelerator_int3:1; /* RW */ + unsigned long message_accelerator_int4:1; /* RW */ + unsigned long message_accelerator_int5:1; /* RW */ + unsigned long message_accelerator_int6:1; /* RW */ + unsigned long message_accelerator_int7:1; /* RW */ + unsigned long message_accelerator_int8:1; /* RW */ + unsigned long message_accelerator_int9:1; /* RW */ + unsigned long message_accelerator_int10:1; /* RW */ + unsigned long message_accelerator_int11:1; /* RW */ + unsigned long message_accelerator_int12:1; /* RW */ + unsigned long message_accelerator_int13:1; /* RW */ + unsigned long message_accelerator_int14:1; /* RW */ + unsigned long message_accelerator_int15:1; /* RW */ + unsigned long rtc_interval_int:1; /* RW */ + unsigned long bau_dashboard_int:1; /* RW */ + unsigned long rtc_0:1; /* RW */ + unsigned long rtc_1:1; /* RW */ + unsigned long rtc_2:1; /* RW */ + unsigned long rtc_3:1; /* RW */ + unsigned long rtc_4:1; /* RW */ + unsigned long rtc_5:1; /* RW */ + unsigned long rtc_6:1; /* RW */ + unsigned long rtc_7:1; /* RW */ + unsigned long rtc_8:1; /* RW */ + unsigned long rtc_9:1; /* RW */ + unsigned long rtc_10:1; /* RW */ + unsigned long rtc_11:1; /* RW */ + unsigned long rtc_12:1; /* RW */ + unsigned long rtc_13:1; /* RW */ + unsigned long rtc_14:1; /* RW */ + unsigned long rtc_15:1; /* RW */ + unsigned long rtc_16:1; /* RW */ + unsigned long rtc_17:1; /* RW */ + unsigned long rtc_18:1; /* RW */ + unsigned long rtc_19:1; /* RW */ + unsigned long rtc_20:1; /* RW */ + unsigned long rtc_21:1; /* RW */ + unsigned long rtc_22:1; /* RW */ + unsigned long rtc_23:1; /* RW */ + unsigned long rtc_24:1; /* RW */ + unsigned long rtc_25:1; /* RW */ + unsigned long rtc_26:1; /* RW */ + unsigned long rtc_27:1; /* RW */ + unsigned long rtc_28:1; /* RW */ + unsigned long rtc_29:1; /* RW */ + unsigned long rtc_30:1; /* RW */ + unsigned long rtc_31:1; /* RW */ + unsigned long rsvd_50_63:14; + } s4; + + /* UV3 unique struct */ + struct uv3h_event_occurred2_s { + unsigned long rtc_0:1; /* RW */ + unsigned long rtc_1:1; /* RW */ + unsigned long rtc_2:1; /* RW */ + unsigned long rtc_3:1; /* RW */ + unsigned long rtc_4:1; /* RW */ + unsigned long rtc_5:1; /* RW */ + unsigned long rtc_6:1; /* RW */ + unsigned long rtc_7:1; /* RW */ + unsigned long rtc_8:1; /* RW */ + unsigned long rtc_9:1; /* RW */ + unsigned long rtc_10:1; /* RW */ + unsigned long rtc_11:1; /* RW */ + unsigned long rtc_12:1; /* RW */ + unsigned long rtc_13:1; /* RW */ + unsigned long rtc_14:1; /* RW */ + unsigned long rtc_15:1; /* RW */ + unsigned long rtc_16:1; /* RW */ + unsigned long rtc_17:1; /* RW */ + unsigned long rtc_18:1; /* RW */ + unsigned long rtc_19:1; /* RW */ + unsigned long rtc_20:1; /* RW */ + unsigned long rtc_21:1; /* RW */ + unsigned long rtc_22:1; /* RW */ + unsigned long rtc_23:1; /* RW */ + unsigned long rtc_24:1; /* RW */ + unsigned long rtc_25:1; /* RW */ + unsigned long rtc_26:1; /* RW */ + unsigned long rtc_27:1; /* RW */ + unsigned long rtc_28:1; /* RW */ + unsigned long rtc_29:1; /* RW */ + unsigned long rtc_30:1; /* RW */ + unsigned long rtc_31:1; /* RW */ + unsigned long rsvd_32_63:32; + } s3; + + /* UV2 unique struct */ + struct uv2h_event_occurred2_s { + unsigned long rtc_0:1; /* RW */ + unsigned long rtc_1:1; /* RW */ + unsigned long rtc_2:1; /* RW */ + unsigned long rtc_3:1; /* RW */ + unsigned long rtc_4:1; /* RW */ + unsigned long rtc_5:1; /* RW */ + unsigned long rtc_6:1; /* RW */ + unsigned long rtc_7:1; /* RW */ + unsigned long rtc_8:1; /* RW */ + unsigned long rtc_9:1; /* RW */ + unsigned long rtc_10:1; /* RW */ + unsigned long rtc_11:1; /* RW */ + unsigned long rtc_12:1; /* RW */ + unsigned long rtc_13:1; /* RW */ + unsigned long rtc_14:1; /* RW */ + unsigned long rtc_15:1; /* RW */ + unsigned long rtc_16:1; /* RW */ + unsigned long rtc_17:1; /* RW */ + unsigned long rtc_18:1; /* RW */ + unsigned long rtc_19:1; /* RW */ + unsigned long rtc_20:1; /* RW */ + unsigned long rtc_21:1; /* RW */ + unsigned long rtc_22:1; /* RW */ + unsigned long rtc_23:1; /* RW */ + unsigned long rtc_24:1; /* RW */ + unsigned long rtc_25:1; /* RW */ + unsigned long rtc_26:1; /* RW */ + unsigned long rtc_27:1; /* RW */ + unsigned long rtc_28:1; /* RW */ + unsigned long rtc_29:1; /* RW */ + unsigned long rtc_30:1; /* RW */ + unsigned long rtc_31:1; /* RW */ + unsigned long rsvd_32_63:32; + } s2; +}; + +/* ========================================================================= */ +/* UVH_EVENT_OCCURRED2_ALIAS */ +/* ========================================================================= */ +#define UVH_EVENT_OCCURRED2_ALIAS 0x70108UL /* ========================================================================= */ @@ -585,51 +2135,148 @@ union uvh_event_occurred0_u { /* ========================================================================= */ #define UVH_EXTIO_INT0_BROADCAST 0x61448UL -#define UV2H_EXTIO_INT0_BROADCAST_32 0x3f0 -#define UV3H_EXTIO_INT0_BROADCAST_32 0x3f0 -#define UV4H_EXTIO_INT0_BROADCAST_32 0x310 -#define UVH_EXTIO_INT0_BROADCAST_32 ( \ - is_uv2_hub() ? UV2H_EXTIO_INT0_BROADCAST_32 : \ - is_uv3_hub() ? UV3H_EXTIO_INT0_BROADCAST_32 : \ - /*is_uv4_hub*/ UV4H_EXTIO_INT0_BROADCAST_32) - +/* UVH common defines*/ #define UVH_EXTIO_INT0_BROADCAST_ENABLE_SHFT 0 #define UVH_EXTIO_INT0_BROADCAST_ENABLE_MASK 0x0000000000000001UL union uvh_extio_int0_broadcast_u { unsigned long v; + + /* UVH common struct */ struct uvh_extio_int0_broadcast_s { unsigned long enable:1; /* RW */ unsigned long rsvd_1_63:63; } s; + + /* UV5 unique struct */ + struct uv5h_extio_int0_broadcast_s { + unsigned long enable:1; /* RW */ + unsigned long rsvd_1_63:63; + } s5; + + /* UV4 unique struct */ + struct uv4h_extio_int0_broadcast_s { + unsigned long enable:1; /* RW */ + unsigned long rsvd_1_63:63; + } s4; + + /* UV3 unique struct */ + struct uv3h_extio_int0_broadcast_s { + unsigned long enable:1; /* RW */ + unsigned long rsvd_1_63:63; + } s3; + + /* UV2 unique struct */ + struct uv2h_extio_int0_broadcast_s { + unsigned long enable:1; /* RW */ + unsigned long rsvd_1_63:63; + } s2; +}; + +/* ========================================================================= */ +/* UVH_GR0_GAM_GR_CONFIG */ +/* ========================================================================= */ +#define UVH_GR0_GAM_GR_CONFIG ( \ + is_uv(UV5) ? 0x600028UL : \ + is_uv(UV4) ? 0x600028UL : \ + is_uv(UV3) ? 0xc00028UL : \ + is_uv(UV2) ? 0xc00028UL : \ + 0) + + + +/* UVYH common defines */ +#define UVYH_GR0_GAM_GR_CONFIG_SUBSPACE_SHFT 10 +#define UVYH_GR0_GAM_GR_CONFIG_SUBSPACE_MASK 0x0000000000000400UL + +/* UV4 unique defines */ +#define UV4H_GR0_GAM_GR_CONFIG_SUBSPACE_SHFT 10 +#define UV4H_GR0_GAM_GR_CONFIG_SUBSPACE_MASK 0x0000000000000400UL + +/* UV3 unique defines */ +#define UV3H_GR0_GAM_GR_CONFIG_M_SKT_SHFT 0 +#define UV3H_GR0_GAM_GR_CONFIG_M_SKT_MASK 0x000000000000003fUL +#define UV3H_GR0_GAM_GR_CONFIG_SUBSPACE_SHFT 10 +#define UV3H_GR0_GAM_GR_CONFIG_SUBSPACE_MASK 0x0000000000000400UL + +/* UV2 unique defines */ +#define UV2H_GR0_GAM_GR_CONFIG_N_GR_SHFT 0 +#define UV2H_GR0_GAM_GR_CONFIG_N_GR_MASK 0x000000000000000fUL + + +union uvyh_gr0_gam_gr_config_u { + unsigned long v; + + /* UVYH common struct */ + struct uvyh_gr0_gam_gr_config_s { + unsigned long rsvd_0_9:10; + unsigned long subspace:1; /* RW */ + unsigned long rsvd_11_63:53; + } sy; + + /* UV5 unique struct */ + struct uv5h_gr0_gam_gr_config_s { + unsigned long rsvd_0_9:10; + unsigned long subspace:1; /* RW */ + unsigned long rsvd_11_63:53; + } s5; + + /* UV4 unique struct */ + struct uv4h_gr0_gam_gr_config_s { + unsigned long rsvd_0_9:10; + unsigned long subspace:1; /* RW */ + unsigned long rsvd_11_63:53; + } s4; + + /* UV3 unique struct */ + struct uv3h_gr0_gam_gr_config_s { + unsigned long m_skt:6; /* RW */ + unsigned long undef_6_9:4; /* Undefined */ + unsigned long subspace:1; /* RW */ + unsigned long reserved:53; + } s3; + + /* UV2 unique struct */ + struct uv2h_gr0_gam_gr_config_s { + unsigned long n_gr:4; /* RW */ + unsigned long reserved:60; + } s2; }; /* ========================================================================= */ /* UVH_GR0_TLB_INT0_CONFIG */ /* ========================================================================= */ -#define UVH_GR0_TLB_INT0_CONFIG 0x61b00UL - -#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_SHFT 0 -#define UVH_GR0_TLB_INT0_CONFIG_DM_SHFT 8 -#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_SHFT 11 -#define UVH_GR0_TLB_INT0_CONFIG_STATUS_SHFT 12 -#define UVH_GR0_TLB_INT0_CONFIG_P_SHFT 13 -#define UVH_GR0_TLB_INT0_CONFIG_T_SHFT 15 -#define UVH_GR0_TLB_INT0_CONFIG_M_SHFT 16 -#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_SHFT 32 -#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_GR0_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_GR0_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_GR0_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_GR0_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_GR0_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL +#define UVH_GR0_TLB_INT0_CONFIG ( \ + is_uv(UV4) ? 0x61b00UL : \ + is_uv(UV3) ? 0x61b00UL : \ + is_uv(UV2) ? 0x61b00UL : \ + uv_undefined("UVH_GR0_TLB_INT0_CONFIG")) + + +/* UVXH common defines */ +#define UVXH_GR0_TLB_INT0_CONFIG_VECTOR_SHFT 0 +#define UVXH_GR0_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL +#define UVXH_GR0_TLB_INT0_CONFIG_DM_SHFT 8 +#define UVXH_GR0_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL +#define UVXH_GR0_TLB_INT0_CONFIG_DESTMODE_SHFT 11 +#define UVXH_GR0_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL +#define UVXH_GR0_TLB_INT0_CONFIG_STATUS_SHFT 12 +#define UVXH_GR0_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL +#define UVXH_GR0_TLB_INT0_CONFIG_P_SHFT 13 +#define UVXH_GR0_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL +#define UVXH_GR0_TLB_INT0_CONFIG_T_SHFT 15 +#define UVXH_GR0_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL +#define UVXH_GR0_TLB_INT0_CONFIG_M_SHFT 16 +#define UVXH_GR0_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL +#define UVXH_GR0_TLB_INT0_CONFIG_APIC_ID_SHFT 32 +#define UVXH_GR0_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL union uvh_gr0_tlb_int0_config_u { unsigned long v; + + /* UVH common struct */ struct uvh_gr0_tlb_int0_config_s { unsigned long vector_:8; /* RW */ unsigned long dm:3; /* RW */ @@ -642,33 +2289,97 @@ union uvh_gr0_tlb_int0_config_u { unsigned long rsvd_17_31:15; unsigned long apic_id:32; /* RW */ } s; + + /* UVXH common struct */ + struct uvxh_gr0_tlb_int0_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ + } sx; + + /* UV4 unique struct */ + struct uv4h_gr0_tlb_int0_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ + } s4; + + /* UV3 unique struct */ + struct uv3h_gr0_tlb_int0_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ + } s3; + + /* UV2 unique struct */ + struct uv2h_gr0_tlb_int0_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ + } s2; }; /* ========================================================================= */ /* UVH_GR0_TLB_INT1_CONFIG */ /* ========================================================================= */ -#define UVH_GR0_TLB_INT1_CONFIG 0x61b40UL - -#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_SHFT 0 -#define UVH_GR0_TLB_INT1_CONFIG_DM_SHFT 8 -#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_SHFT 11 -#define UVH_GR0_TLB_INT1_CONFIG_STATUS_SHFT 12 -#define UVH_GR0_TLB_INT1_CONFIG_P_SHFT 13 -#define UVH_GR0_TLB_INT1_CONFIG_T_SHFT 15 -#define UVH_GR0_TLB_INT1_CONFIG_M_SHFT 16 -#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_SHFT 32 -#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_GR0_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_GR0_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_GR0_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_GR0_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_GR0_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL +#define UVH_GR0_TLB_INT1_CONFIG ( \ + is_uv(UV4) ? 0x61b40UL : \ + is_uv(UV3) ? 0x61b40UL : \ + is_uv(UV2) ? 0x61b40UL : \ + uv_undefined("UVH_GR0_TLB_INT1_CONFIG")) + + +/* UVXH common defines */ +#define UVXH_GR0_TLB_INT1_CONFIG_VECTOR_SHFT 0 +#define UVXH_GR0_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL +#define UVXH_GR0_TLB_INT1_CONFIG_DM_SHFT 8 +#define UVXH_GR0_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL +#define UVXH_GR0_TLB_INT1_CONFIG_DESTMODE_SHFT 11 +#define UVXH_GR0_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL +#define UVXH_GR0_TLB_INT1_CONFIG_STATUS_SHFT 12 +#define UVXH_GR0_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL +#define UVXH_GR0_TLB_INT1_CONFIG_P_SHFT 13 +#define UVXH_GR0_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL +#define UVXH_GR0_TLB_INT1_CONFIG_T_SHFT 15 +#define UVXH_GR0_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL +#define UVXH_GR0_TLB_INT1_CONFIG_M_SHFT 16 +#define UVXH_GR0_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL +#define UVXH_GR0_TLB_INT1_CONFIG_APIC_ID_SHFT 32 +#define UVXH_GR0_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL union uvh_gr0_tlb_int1_config_u { unsigned long v; + + /* UVH common struct */ struct uvh_gr0_tlb_int1_config_s { unsigned long vector_:8; /* RW */ unsigned long dm:3; /* RW */ @@ -681,382 +2392,97 @@ union uvh_gr0_tlb_int1_config_u { unsigned long rsvd_17_31:15; unsigned long apic_id:32; /* RW */ } s; -}; -/* ========================================================================= */ -/* UVH_GR0_TLB_MMR_CONTROL */ -/* ========================================================================= */ -#define UV2H_GR0_TLB_MMR_CONTROL 0xc01080UL -#define UV3H_GR0_TLB_MMR_CONTROL 0xc01080UL -#define UV4H_GR0_TLB_MMR_CONTROL 0x601080UL -#define UVH_GR0_TLB_MMR_CONTROL ( \ - is_uv2_hub() ? UV2H_GR0_TLB_MMR_CONTROL : \ - is_uv3_hub() ? UV3H_GR0_TLB_MMR_CONTROL : \ - /*is_uv4_hub*/ UV4H_GR0_TLB_MMR_CONTROL) - -#define UVH_GR0_TLB_MMR_CONTROL_INDEX_SHFT 0 -#define UVH_GR0_TLB_MMR_CONTROL_AUTO_VALID_EN_SHFT 16 -#define UVH_GR0_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_SHFT 20 -#define UVH_GR0_TLB_MMR_CONTROL_MMR_WRITE_SHFT 30 -#define UVH_GR0_TLB_MMR_CONTROL_MMR_READ_SHFT 31 -#define UVH_GR0_TLB_MMR_CONTROL_AUTO_VALID_EN_MASK 0x0000000000010000UL -#define UVH_GR0_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_MASK 0x0000000000100000UL -#define UVH_GR0_TLB_MMR_CONTROL_MMR_WRITE_MASK 0x0000000040000000UL -#define UVH_GR0_TLB_MMR_CONTROL_MMR_READ_MASK 0x0000000080000000UL - -#define UVXH_GR0_TLB_MMR_CONTROL_INDEX_SHFT 0 -#define UVXH_GR0_TLB_MMR_CONTROL_AUTO_VALID_EN_SHFT 16 -#define UVXH_GR0_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_SHFT 20 -#define UVXH_GR0_TLB_MMR_CONTROL_MMR_WRITE_SHFT 30 -#define UVXH_GR0_TLB_MMR_CONTROL_MMR_READ_SHFT 31 -#define UVXH_GR0_TLB_MMR_CONTROL_MMR_OP_DONE_SHFT 32 -#define UVXH_GR0_TLB_MMR_CONTROL_AUTO_VALID_EN_MASK 0x0000000000010000UL -#define UVXH_GR0_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_MASK 0x0000000000100000UL -#define UVXH_GR0_TLB_MMR_CONTROL_MMR_WRITE_MASK 0x0000000040000000UL -#define UVXH_GR0_TLB_MMR_CONTROL_MMR_READ_MASK 0x0000000080000000UL -#define UVXH_GR0_TLB_MMR_CONTROL_MMR_OP_DONE_MASK 0x0000000100000000UL - -#define UV2H_GR0_TLB_MMR_CONTROL_INDEX_SHFT 0 -#define UV2H_GR0_TLB_MMR_CONTROL_MEM_SEL_SHFT 12 -#define UV2H_GR0_TLB_MMR_CONTROL_AUTO_VALID_EN_SHFT 16 -#define UV2H_GR0_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_SHFT 20 -#define UV2H_GR0_TLB_MMR_CONTROL_MMR_WRITE_SHFT 30 -#define UV2H_GR0_TLB_MMR_CONTROL_MMR_READ_SHFT 31 -#define UV2H_GR0_TLB_MMR_CONTROL_MMR_OP_DONE_SHFT 32 -#define UV2H_GR0_TLB_MMR_CONTROL_MMR_INJ_CON_SHFT 48 -#define UV2H_GR0_TLB_MMR_CONTROL_MMR_INJ_TLBRAM_SHFT 52 -#define UV2H_GR0_TLB_MMR_CONTROL_INDEX_MASK 0x0000000000000fffUL -#define UV2H_GR0_TLB_MMR_CONTROL_MEM_SEL_MASK 0x0000000000003000UL -#define UV2H_GR0_TLB_MMR_CONTROL_AUTO_VALID_EN_MASK 0x0000000000010000UL -#define UV2H_GR0_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_MASK 0x0000000000100000UL -#define UV2H_GR0_TLB_MMR_CONTROL_MMR_WRITE_MASK 0x0000000040000000UL -#define UV2H_GR0_TLB_MMR_CONTROL_MMR_READ_MASK 0x0000000080000000UL -#define UV2H_GR0_TLB_MMR_CONTROL_MMR_OP_DONE_MASK 0x0000000100000000UL -#define UV2H_GR0_TLB_MMR_CONTROL_MMR_INJ_CON_MASK 0x0001000000000000UL -#define UV2H_GR0_TLB_MMR_CONTROL_MMR_INJ_TLBRAM_MASK 0x0010000000000000UL - -#define UV3H_GR0_TLB_MMR_CONTROL_INDEX_SHFT 0 -#define UV3H_GR0_TLB_MMR_CONTROL_MEM_SEL_SHFT 12 -#define UV3H_GR0_TLB_MMR_CONTROL_AUTO_VALID_EN_SHFT 16 -#define UV3H_GR0_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_SHFT 20 -#define UV3H_GR0_TLB_MMR_CONTROL_ECC_SEL_SHFT 21 -#define UV3H_GR0_TLB_MMR_CONTROL_MMR_WRITE_SHFT 30 -#define UV3H_GR0_TLB_MMR_CONTROL_MMR_READ_SHFT 31 -#define UV3H_GR0_TLB_MMR_CONTROL_MMR_OP_DONE_SHFT 32 -#define UV3H_GR0_TLB_MMR_CONTROL_INDEX_MASK 0x0000000000000fffUL -#define UV3H_GR0_TLB_MMR_CONTROL_MEM_SEL_MASK 0x0000000000003000UL -#define UV3H_GR0_TLB_MMR_CONTROL_AUTO_VALID_EN_MASK 0x0000000000010000UL -#define UV3H_GR0_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_MASK 0x0000000000100000UL -#define UV3H_GR0_TLB_MMR_CONTROL_ECC_SEL_MASK 0x0000000000200000UL -#define UV3H_GR0_TLB_MMR_CONTROL_MMR_WRITE_MASK 0x0000000040000000UL -#define UV3H_GR0_TLB_MMR_CONTROL_MMR_READ_MASK 0x0000000080000000UL -#define UV3H_GR0_TLB_MMR_CONTROL_MMR_OP_DONE_MASK 0x0000000100000000UL - -#define UV4H_GR0_TLB_MMR_CONTROL_INDEX_SHFT 0 -#define UV4H_GR0_TLB_MMR_CONTROL_MEM_SEL_SHFT 13 -#define UV4H_GR0_TLB_MMR_CONTROL_AUTO_VALID_EN_SHFT 16 -#define UV4H_GR0_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_SHFT 20 -#define UV4H_GR0_TLB_MMR_CONTROL_ECC_SEL_SHFT 21 -#define UV4H_GR0_TLB_MMR_CONTROL_MMR_WRITE_SHFT 30 -#define UV4H_GR0_TLB_MMR_CONTROL_MMR_READ_SHFT 31 -#define UV4H_GR0_TLB_MMR_CONTROL_MMR_OP_DONE_SHFT 32 -#define UV4H_GR0_TLB_MMR_CONTROL_PAGE_SIZE_SHFT 59 -#define UV4H_GR0_TLB_MMR_CONTROL_INDEX_MASK 0x0000000000001fffUL -#define UV4H_GR0_TLB_MMR_CONTROL_MEM_SEL_MASK 0x0000000000006000UL -#define UV4H_GR0_TLB_MMR_CONTROL_AUTO_VALID_EN_MASK 0x0000000000010000UL -#define UV4H_GR0_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_MASK 0x0000000000100000UL -#define UV4H_GR0_TLB_MMR_CONTROL_ECC_SEL_MASK 0x0000000000200000UL -#define UV4H_GR0_TLB_MMR_CONTROL_MMR_WRITE_MASK 0x0000000040000000UL -#define UV4H_GR0_TLB_MMR_CONTROL_MMR_READ_MASK 0x0000000080000000UL -#define UV4H_GR0_TLB_MMR_CONTROL_MMR_OP_DONE_MASK 0x0000000100000000UL -#define UV4H_GR0_TLB_MMR_CONTROL_PAGE_SIZE_MASK 0xf800000000000000UL - -#define UVH_GR0_TLB_MMR_CONTROL_INDEX_MASK ( \ - is_uv2_hub() ? UV2H_GR0_TLB_MMR_CONTROL_INDEX_MASK : \ - is_uv3_hub() ? UV3H_GR0_TLB_MMR_CONTROL_INDEX_MASK : \ - /*is_uv4_hub*/ UV4H_GR0_TLB_MMR_CONTROL_INDEX_MASK) -#define UVH_GR0_TLB_MMR_CONTROL_MEM_SEL_MASK ( \ - is_uv2_hub() ? UV2H_GR0_TLB_MMR_CONTROL_MEM_SEL_MASK : \ - is_uv3_hub() ? UV3H_GR0_TLB_MMR_CONTROL_MEM_SEL_MASK : \ - /*is_uv4_hub*/ UV4H_GR0_TLB_MMR_CONTROL_MEM_SEL_MASK) -#define UVH_GR0_TLB_MMR_CONTROL_MEM_SEL_SHFT ( \ - is_uv2_hub() ? UV2H_GR0_TLB_MMR_CONTROL_MEM_SEL_SHFT : \ - is_uv3_hub() ? UV3H_GR0_TLB_MMR_CONTROL_MEM_SEL_SHFT : \ - /*is_uv4_hub*/ UV4H_GR0_TLB_MMR_CONTROL_MEM_SEL_SHFT) - -union uvh_gr0_tlb_mmr_control_u { - unsigned long v; - struct uvh_gr0_tlb_mmr_control_s { - unsigned long rsvd_0_15:16; - unsigned long auto_valid_en:1; /* RW */ - unsigned long rsvd_17_19:3; - unsigned long mmr_hash_index_en:1; /* RW */ - unsigned long rsvd_21_29:9; - unsigned long mmr_write:1; /* WP */ - unsigned long mmr_read:1; /* WP */ - unsigned long rsvd_32_48:17; - unsigned long rsvd_49_51:3; - unsigned long rsvd_52_63:12; - } s; - struct uvxh_gr0_tlb_mmr_control_s { - unsigned long rsvd_0_15:16; - unsigned long auto_valid_en:1; /* RW */ - unsigned long rsvd_17_19:3; - unsigned long mmr_hash_index_en:1; /* RW */ - unsigned long rsvd_21_29:9; - unsigned long mmr_write:1; /* WP */ - unsigned long mmr_read:1; /* WP */ - unsigned long mmr_op_done:1; /* RW */ - unsigned long rsvd_33_47:15; - unsigned long rsvd_48:1; - unsigned long rsvd_49_51:3; - unsigned long rsvd_52_63:12; + /* UVXH common struct */ + struct uvxh_gr0_tlb_int1_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ } sx; - struct uv2h_gr0_tlb_mmr_control_s { - unsigned long index:12; /* RW */ - unsigned long mem_sel:2; /* RW */ - unsigned long rsvd_14_15:2; - unsigned long auto_valid_en:1; /* RW */ - unsigned long rsvd_17_19:3; - unsigned long mmr_hash_index_en:1; /* RW */ - unsigned long rsvd_21_29:9; - unsigned long mmr_write:1; /* WP */ - unsigned long mmr_read:1; /* WP */ - unsigned long mmr_op_done:1; /* RW */ - unsigned long rsvd_33_47:15; - unsigned long mmr_inj_con:1; /* RW */ - unsigned long rsvd_49_51:3; - unsigned long mmr_inj_tlbram:1; /* RW */ - unsigned long rsvd_53_63:11; - } s2; - struct uv3h_gr0_tlb_mmr_control_s { - unsigned long index:12; /* RW */ - unsigned long mem_sel:2; /* RW */ - unsigned long rsvd_14_15:2; - unsigned long auto_valid_en:1; /* RW */ - unsigned long rsvd_17_19:3; - unsigned long mmr_hash_index_en:1; /* RW */ - unsigned long ecc_sel:1; /* RW */ - unsigned long rsvd_22_29:8; - unsigned long mmr_write:1; /* WP */ - unsigned long mmr_read:1; /* WP */ - unsigned long mmr_op_done:1; /* RW */ - unsigned long rsvd_33_47:15; - unsigned long undef_48:1; /* Undefined */ - unsigned long rsvd_49_51:3; - unsigned long undef_52:1; /* Undefined */ - unsigned long rsvd_53_63:11; - } s3; - struct uv4h_gr0_tlb_mmr_control_s { - unsigned long index:13; /* RW */ - unsigned long mem_sel:2; /* RW */ - unsigned long rsvd_15:1; - unsigned long auto_valid_en:1; /* RW */ - unsigned long rsvd_17_19:3; - unsigned long mmr_hash_index_en:1; /* RW */ - unsigned long ecc_sel:1; /* RW */ - unsigned long rsvd_22_29:8; - unsigned long mmr_write:1; /* WP */ - unsigned long mmr_read:1; /* WP */ - unsigned long mmr_op_done:1; /* RW */ - unsigned long rsvd_33_47:15; - unsigned long undef_48:1; /* Undefined */ - unsigned long rsvd_49_51:3; - unsigned long rsvd_52_58:7; - unsigned long page_size:5; /* RW */ + + /* UV4 unique struct */ + struct uv4h_gr0_tlb_int1_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ } s4; -}; -/* ========================================================================= */ -/* UVH_GR0_TLB_MMR_READ_DATA_HI */ -/* ========================================================================= */ -#define UV2H_GR0_TLB_MMR_READ_DATA_HI 0xc010a0UL -#define UV3H_GR0_TLB_MMR_READ_DATA_HI 0xc010a0UL -#define UV4H_GR0_TLB_MMR_READ_DATA_HI 0x6010a0UL -#define UVH_GR0_TLB_MMR_READ_DATA_HI ( \ - is_uv2_hub() ? UV2H_GR0_TLB_MMR_READ_DATA_HI : \ - is_uv3_hub() ? UV3H_GR0_TLB_MMR_READ_DATA_HI : \ - /*is_uv4_hub*/ UV4H_GR0_TLB_MMR_READ_DATA_HI) - -#define UVH_GR0_TLB_MMR_READ_DATA_HI_PFN_SHFT 0 - -#define UVXH_GR0_TLB_MMR_READ_DATA_HI_PFN_SHFT 0 - -#define UV2H_GR0_TLB_MMR_READ_DATA_HI_PFN_SHFT 0 -#define UV2H_GR0_TLB_MMR_READ_DATA_HI_GAA_SHFT 41 -#define UV2H_GR0_TLB_MMR_READ_DATA_HI_DIRTY_SHFT 43 -#define UV2H_GR0_TLB_MMR_READ_DATA_HI_LARGER_SHFT 44 -#define UV2H_GR0_TLB_MMR_READ_DATA_HI_PFN_MASK 0x000001ffffffffffUL -#define UV2H_GR0_TLB_MMR_READ_DATA_HI_GAA_MASK 0x0000060000000000UL -#define UV2H_GR0_TLB_MMR_READ_DATA_HI_DIRTY_MASK 0x0000080000000000UL -#define UV2H_GR0_TLB_MMR_READ_DATA_HI_LARGER_MASK 0x0000100000000000UL - -#define UV3H_GR0_TLB_MMR_READ_DATA_HI_PFN_SHFT 0 -#define UV3H_GR0_TLB_MMR_READ_DATA_HI_GAA_SHFT 41 -#define UV3H_GR0_TLB_MMR_READ_DATA_HI_DIRTY_SHFT 43 -#define UV3H_GR0_TLB_MMR_READ_DATA_HI_LARGER_SHFT 44 -#define UV3H_GR0_TLB_MMR_READ_DATA_HI_AA_EXT_SHFT 45 -#define UV3H_GR0_TLB_MMR_READ_DATA_HI_WAY_ECC_SHFT 55 -#define UV3H_GR0_TLB_MMR_READ_DATA_HI_PFN_MASK 0x000001ffffffffffUL -#define UV3H_GR0_TLB_MMR_READ_DATA_HI_GAA_MASK 0x0000060000000000UL -#define UV3H_GR0_TLB_MMR_READ_DATA_HI_DIRTY_MASK 0x0000080000000000UL -#define UV3H_GR0_TLB_MMR_READ_DATA_HI_LARGER_MASK 0x0000100000000000UL -#define UV3H_GR0_TLB_MMR_READ_DATA_HI_AA_EXT_MASK 0x0000200000000000UL -#define UV3H_GR0_TLB_MMR_READ_DATA_HI_WAY_ECC_MASK 0xff80000000000000UL - -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_PFN_SHFT 0 -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_PNID_SHFT 34 -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_GAA_SHFT 49 -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_DIRTY_SHFT 51 -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_LARGER_SHFT 52 -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_AA_EXT_SHFT 53 -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_WAY_ECC_SHFT 55 -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_PFN_MASK 0x00000003ffffffffUL -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_PNID_MASK 0x0001fffc00000000UL -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_GAA_MASK 0x0006000000000000UL -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_DIRTY_MASK 0x0008000000000000UL -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_LARGER_MASK 0x0010000000000000UL -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_AA_EXT_MASK 0x0020000000000000UL -#define UV4H_GR0_TLB_MMR_READ_DATA_HI_WAY_ECC_MASK 0xff80000000000000UL - - -union uvh_gr0_tlb_mmr_read_data_hi_u { - unsigned long v; - struct uv2h_gr0_tlb_mmr_read_data_hi_s { - unsigned long pfn:41; /* RO */ - unsigned long gaa:2; /* RO */ - unsigned long dirty:1; /* RO */ - unsigned long larger:1; /* RO */ - unsigned long rsvd_45_63:19; - } s2; - struct uv3h_gr0_tlb_mmr_read_data_hi_s { - unsigned long pfn:41; /* RO */ - unsigned long gaa:2; /* RO */ - unsigned long dirty:1; /* RO */ - unsigned long larger:1; /* RO */ - unsigned long aa_ext:1; /* RO */ - unsigned long undef_46_54:9; /* Undefined */ - unsigned long way_ecc:9; /* RO */ + /* UV3 unique struct */ + struct uv3h_gr0_tlb_int1_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ } s3; - struct uv4h_gr0_tlb_mmr_read_data_hi_s { - unsigned long pfn:34; /* RO */ - unsigned long pnid:15; /* RO */ - unsigned long gaa:2; /* RO */ - unsigned long dirty:1; /* RO */ - unsigned long larger:1; /* RO */ - unsigned long aa_ext:1; /* RO */ - unsigned long undef_54:1; /* Undefined */ - unsigned long way_ecc:9; /* RO */ - } s4; -}; -/* ========================================================================= */ -/* UVH_GR0_TLB_MMR_READ_DATA_LO */ -/* ========================================================================= */ -#define UV2H_GR0_TLB_MMR_READ_DATA_LO 0xc010a8UL -#define UV3H_GR0_TLB_MMR_READ_DATA_LO 0xc010a8UL -#define UV4H_GR0_TLB_MMR_READ_DATA_LO 0x6010a8UL -#define UVH_GR0_TLB_MMR_READ_DATA_LO ( \ - is_uv2_hub() ? UV2H_GR0_TLB_MMR_READ_DATA_LO : \ - is_uv3_hub() ? UV3H_GR0_TLB_MMR_READ_DATA_LO : \ - /*is_uv4_hub*/ UV4H_GR0_TLB_MMR_READ_DATA_LO) - -#define UVH_GR0_TLB_MMR_READ_DATA_LO_VPN_SHFT 0 -#define UVH_GR0_TLB_MMR_READ_DATA_LO_ASID_SHFT 39 -#define UVH_GR0_TLB_MMR_READ_DATA_LO_VALID_SHFT 63 -#define UVH_GR0_TLB_MMR_READ_DATA_LO_VPN_MASK 0x0000007fffffffffUL -#define UVH_GR0_TLB_MMR_READ_DATA_LO_ASID_MASK 0x7fffff8000000000UL -#define UVH_GR0_TLB_MMR_READ_DATA_LO_VALID_MASK 0x8000000000000000UL - -#define UVXH_GR0_TLB_MMR_READ_DATA_LO_VPN_SHFT 0 -#define UVXH_GR0_TLB_MMR_READ_DATA_LO_ASID_SHFT 39 -#define UVXH_GR0_TLB_MMR_READ_DATA_LO_VALID_SHFT 63 -#define UVXH_GR0_TLB_MMR_READ_DATA_LO_VPN_MASK 0x0000007fffffffffUL -#define UVXH_GR0_TLB_MMR_READ_DATA_LO_ASID_MASK 0x7fffff8000000000UL -#define UVXH_GR0_TLB_MMR_READ_DATA_LO_VALID_MASK 0x8000000000000000UL - -#define UV2H_GR0_TLB_MMR_READ_DATA_LO_VPN_SHFT 0 -#define UV2H_GR0_TLB_MMR_READ_DATA_LO_ASID_SHFT 39 -#define UV2H_GR0_TLB_MMR_READ_DATA_LO_VALID_SHFT 63 -#define UV2H_GR0_TLB_MMR_READ_DATA_LO_VPN_MASK 0x0000007fffffffffUL -#define UV2H_GR0_TLB_MMR_READ_DATA_LO_ASID_MASK 0x7fffff8000000000UL -#define UV2H_GR0_TLB_MMR_READ_DATA_LO_VALID_MASK 0x8000000000000000UL - -#define UV3H_GR0_TLB_MMR_READ_DATA_LO_VPN_SHFT 0 -#define UV3H_GR0_TLB_MMR_READ_DATA_LO_ASID_SHFT 39 -#define UV3H_GR0_TLB_MMR_READ_DATA_LO_VALID_SHFT 63 -#define UV3H_GR0_TLB_MMR_READ_DATA_LO_VPN_MASK 0x0000007fffffffffUL -#define UV3H_GR0_TLB_MMR_READ_DATA_LO_ASID_MASK 0x7fffff8000000000UL -#define UV3H_GR0_TLB_MMR_READ_DATA_LO_VALID_MASK 0x8000000000000000UL - -#define UV4H_GR0_TLB_MMR_READ_DATA_LO_VPN_SHFT 0 -#define UV4H_GR0_TLB_MMR_READ_DATA_LO_ASID_SHFT 39 -#define UV4H_GR0_TLB_MMR_READ_DATA_LO_VALID_SHFT 63 -#define UV4H_GR0_TLB_MMR_READ_DATA_LO_VPN_MASK 0x0000007fffffffffUL -#define UV4H_GR0_TLB_MMR_READ_DATA_LO_ASID_MASK 0x7fffff8000000000UL -#define UV4H_GR0_TLB_MMR_READ_DATA_LO_VALID_MASK 0x8000000000000000UL - - -union uvh_gr0_tlb_mmr_read_data_lo_u { - unsigned long v; - struct uvh_gr0_tlb_mmr_read_data_lo_s { - unsigned long vpn:39; /* RO */ - unsigned long asid:24; /* RO */ - unsigned long valid:1; /* RO */ - } s; - struct uvxh_gr0_tlb_mmr_read_data_lo_s { - unsigned long vpn:39; /* RO */ - unsigned long asid:24; /* RO */ - unsigned long valid:1; /* RO */ - } sx; - struct uv2h_gr0_tlb_mmr_read_data_lo_s { - unsigned long vpn:39; /* RO */ - unsigned long asid:24; /* RO */ - unsigned long valid:1; /* RO */ + /* UV2 unique struct */ + struct uv2h_gr0_tlb_int1_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ } s2; - struct uv3h_gr0_tlb_mmr_read_data_lo_s { - unsigned long vpn:39; /* RO */ - unsigned long asid:24; /* RO */ - unsigned long valid:1; /* RO */ - } s3; - struct uv4h_gr0_tlb_mmr_read_data_lo_s { - unsigned long vpn:39; /* RO */ - unsigned long asid:24; /* RO */ - unsigned long valid:1; /* RO */ - } s4; }; /* ========================================================================= */ /* UVH_GR1_TLB_INT0_CONFIG */ /* ========================================================================= */ -#define UV2H_GR1_TLB_INT0_CONFIG 0x61f00UL -#define UV3H_GR1_TLB_INT0_CONFIG 0x61f00UL -#define UV4H_GR1_TLB_INT0_CONFIG 0x62100UL #define UVH_GR1_TLB_INT0_CONFIG ( \ - is_uv2_hub() ? UV2H_GR1_TLB_INT0_CONFIG : \ - is_uv3_hub() ? UV3H_GR1_TLB_INT0_CONFIG : \ - /*is_uv4_hub*/ UV4H_GR1_TLB_INT0_CONFIG) - -#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_SHFT 0 -#define UVH_GR1_TLB_INT0_CONFIG_DM_SHFT 8 -#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_SHFT 11 -#define UVH_GR1_TLB_INT0_CONFIG_STATUS_SHFT 12 -#define UVH_GR1_TLB_INT0_CONFIG_P_SHFT 13 -#define UVH_GR1_TLB_INT0_CONFIG_T_SHFT 15 -#define UVH_GR1_TLB_INT0_CONFIG_M_SHFT 16 -#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_SHFT 32 -#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_GR1_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_GR1_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_GR1_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_GR1_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_GR1_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL + is_uv(UV4) ? 0x62100UL : \ + is_uv(UV3) ? 0x61f00UL : \ + is_uv(UV2) ? 0x61f00UL : \ + uv_undefined("UVH_GR1_TLB_INT0_CONFIG")) + + +/* UVXH common defines */ +#define UVXH_GR1_TLB_INT0_CONFIG_VECTOR_SHFT 0 +#define UVXH_GR1_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL +#define UVXH_GR1_TLB_INT0_CONFIG_DM_SHFT 8 +#define UVXH_GR1_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL +#define UVXH_GR1_TLB_INT0_CONFIG_DESTMODE_SHFT 11 +#define UVXH_GR1_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL +#define UVXH_GR1_TLB_INT0_CONFIG_STATUS_SHFT 12 +#define UVXH_GR1_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL +#define UVXH_GR1_TLB_INT0_CONFIG_P_SHFT 13 +#define UVXH_GR1_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL +#define UVXH_GR1_TLB_INT0_CONFIG_T_SHFT 15 +#define UVXH_GR1_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL +#define UVXH_GR1_TLB_INT0_CONFIG_M_SHFT 16 +#define UVXH_GR1_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL +#define UVXH_GR1_TLB_INT0_CONFIG_APIC_ID_SHFT 32 +#define UVXH_GR1_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL union uvh_gr1_tlb_int0_config_u { unsigned long v; + + /* UVH common struct */ struct uvh_gr1_tlb_int0_config_s { unsigned long vector_:8; /* RW */ unsigned long dm:3; /* RW */ @@ -1069,39 +2495,97 @@ union uvh_gr1_tlb_int0_config_u { unsigned long rsvd_17_31:15; unsigned long apic_id:32; /* RW */ } s; + + /* UVXH common struct */ + struct uvxh_gr1_tlb_int0_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ + } sx; + + /* UV4 unique struct */ + struct uv4h_gr1_tlb_int0_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ + } s4; + + /* UV3 unique struct */ + struct uv3h_gr1_tlb_int0_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ + } s3; + + /* UV2 unique struct */ + struct uv2h_gr1_tlb_int0_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ + } s2; }; /* ========================================================================= */ /* UVH_GR1_TLB_INT1_CONFIG */ /* ========================================================================= */ -#define UV2H_GR1_TLB_INT1_CONFIG 0x61f40UL -#define UV3H_GR1_TLB_INT1_CONFIG 0x61f40UL -#define UV4H_GR1_TLB_INT1_CONFIG 0x62140UL #define UVH_GR1_TLB_INT1_CONFIG ( \ - is_uv2_hub() ? UV2H_GR1_TLB_INT1_CONFIG : \ - is_uv3_hub() ? UV3H_GR1_TLB_INT1_CONFIG : \ - /*is_uv4_hub*/ UV4H_GR1_TLB_INT1_CONFIG) - -#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_SHFT 0 -#define UVH_GR1_TLB_INT1_CONFIG_DM_SHFT 8 -#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_SHFT 11 -#define UVH_GR1_TLB_INT1_CONFIG_STATUS_SHFT 12 -#define UVH_GR1_TLB_INT1_CONFIG_P_SHFT 13 -#define UVH_GR1_TLB_INT1_CONFIG_T_SHFT 15 -#define UVH_GR1_TLB_INT1_CONFIG_M_SHFT 16 -#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_SHFT 32 -#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_GR1_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_GR1_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_GR1_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_GR1_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_GR1_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL + is_uv(UV4) ? 0x62140UL : \ + is_uv(UV3) ? 0x61f40UL : \ + is_uv(UV2) ? 0x61f40UL : \ + uv_undefined("UVH_GR1_TLB_INT1_CONFIG")) + + +/* UVXH common defines */ +#define UVXH_GR1_TLB_INT1_CONFIG_VECTOR_SHFT 0 +#define UVXH_GR1_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL +#define UVXH_GR1_TLB_INT1_CONFIG_DM_SHFT 8 +#define UVXH_GR1_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL +#define UVXH_GR1_TLB_INT1_CONFIG_DESTMODE_SHFT 11 +#define UVXH_GR1_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL +#define UVXH_GR1_TLB_INT1_CONFIG_STATUS_SHFT 12 +#define UVXH_GR1_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL +#define UVXH_GR1_TLB_INT1_CONFIG_P_SHFT 13 +#define UVXH_GR1_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL +#define UVXH_GR1_TLB_INT1_CONFIG_T_SHFT 15 +#define UVXH_GR1_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL +#define UVXH_GR1_TLB_INT1_CONFIG_M_SHFT 16 +#define UVXH_GR1_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL +#define UVXH_GR1_TLB_INT1_CONFIG_APIC_ID_SHFT 32 +#define UVXH_GR1_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL union uvh_gr1_tlb_int1_config_u { unsigned long v; + + /* UVH common struct */ struct uvh_gr1_tlb_int1_config_s { unsigned long vector_:8; /* RW */ unsigned long dm:3; /* RW */ @@ -1114,337 +2598,62 @@ union uvh_gr1_tlb_int1_config_u { unsigned long rsvd_17_31:15; unsigned long apic_id:32; /* RW */ } s; -}; -/* ========================================================================= */ -/* UVH_GR1_TLB_MMR_CONTROL */ -/* ========================================================================= */ -#define UV2H_GR1_TLB_MMR_CONTROL 0x1001080UL -#define UV3H_GR1_TLB_MMR_CONTROL 0x1001080UL -#define UV4H_GR1_TLB_MMR_CONTROL 0x701080UL -#define UVH_GR1_TLB_MMR_CONTROL ( \ - is_uv2_hub() ? UV2H_GR1_TLB_MMR_CONTROL : \ - is_uv3_hub() ? UV3H_GR1_TLB_MMR_CONTROL : \ - /*is_uv4_hub*/ UV4H_GR1_TLB_MMR_CONTROL) - -#define UVH_GR1_TLB_MMR_CONTROL_INDEX_SHFT 0 -#define UVH_GR1_TLB_MMR_CONTROL_AUTO_VALID_EN_SHFT 16 -#define UVH_GR1_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_SHFT 20 -#define UVH_GR1_TLB_MMR_CONTROL_MMR_WRITE_SHFT 30 -#define UVH_GR1_TLB_MMR_CONTROL_MMR_READ_SHFT 31 -#define UVH_GR1_TLB_MMR_CONTROL_AUTO_VALID_EN_MASK 0x0000000000010000UL -#define UVH_GR1_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_MASK 0x0000000000100000UL -#define UVH_GR1_TLB_MMR_CONTROL_MMR_WRITE_MASK 0x0000000040000000UL -#define UVH_GR1_TLB_MMR_CONTROL_MMR_READ_MASK 0x0000000080000000UL - -#define UVXH_GR1_TLB_MMR_CONTROL_INDEX_SHFT 0 -#define UVXH_GR1_TLB_MMR_CONTROL_AUTO_VALID_EN_SHFT 16 -#define UVXH_GR1_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_SHFT 20 -#define UVXH_GR1_TLB_MMR_CONTROL_MMR_WRITE_SHFT 30 -#define UVXH_GR1_TLB_MMR_CONTROL_MMR_READ_SHFT 31 -#define UVXH_GR1_TLB_MMR_CONTROL_MMR_OP_DONE_SHFT 32 -#define UVXH_GR1_TLB_MMR_CONTROL_AUTO_VALID_EN_MASK 0x0000000000010000UL -#define UVXH_GR1_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_MASK 0x0000000000100000UL -#define UVXH_GR1_TLB_MMR_CONTROL_MMR_WRITE_MASK 0x0000000040000000UL -#define UVXH_GR1_TLB_MMR_CONTROL_MMR_READ_MASK 0x0000000080000000UL -#define UVXH_GR1_TLB_MMR_CONTROL_MMR_OP_DONE_MASK 0x0000000100000000UL - -#define UV2H_GR1_TLB_MMR_CONTROL_INDEX_SHFT 0 -#define UV2H_GR1_TLB_MMR_CONTROL_MEM_SEL_SHFT 12 -#define UV2H_GR1_TLB_MMR_CONTROL_AUTO_VALID_EN_SHFT 16 -#define UV2H_GR1_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_SHFT 20 -#define UV2H_GR1_TLB_MMR_CONTROL_MMR_WRITE_SHFT 30 -#define UV2H_GR1_TLB_MMR_CONTROL_MMR_READ_SHFT 31 -#define UV2H_GR1_TLB_MMR_CONTROL_MMR_OP_DONE_SHFT 32 -#define UV2H_GR1_TLB_MMR_CONTROL_MMR_INJ_CON_SHFT 48 -#define UV2H_GR1_TLB_MMR_CONTROL_MMR_INJ_TLBRAM_SHFT 52 -#define UV2H_GR1_TLB_MMR_CONTROL_INDEX_MASK 0x0000000000000fffUL -#define UV2H_GR1_TLB_MMR_CONTROL_MEM_SEL_MASK 0x0000000000003000UL -#define UV2H_GR1_TLB_MMR_CONTROL_AUTO_VALID_EN_MASK 0x0000000000010000UL -#define UV2H_GR1_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_MASK 0x0000000000100000UL -#define UV2H_GR1_TLB_MMR_CONTROL_MMR_WRITE_MASK 0x0000000040000000UL -#define UV2H_GR1_TLB_MMR_CONTROL_MMR_READ_MASK 0x0000000080000000UL -#define UV2H_GR1_TLB_MMR_CONTROL_MMR_OP_DONE_MASK 0x0000000100000000UL -#define UV2H_GR1_TLB_MMR_CONTROL_MMR_INJ_CON_MASK 0x0001000000000000UL -#define UV2H_GR1_TLB_MMR_CONTROL_MMR_INJ_TLBRAM_MASK 0x0010000000000000UL - -#define UV3H_GR1_TLB_MMR_CONTROL_INDEX_SHFT 0 -#define UV3H_GR1_TLB_MMR_CONTROL_MEM_SEL_SHFT 12 -#define UV3H_GR1_TLB_MMR_CONTROL_AUTO_VALID_EN_SHFT 16 -#define UV3H_GR1_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_SHFT 20 -#define UV3H_GR1_TLB_MMR_CONTROL_ECC_SEL_SHFT 21 -#define UV3H_GR1_TLB_MMR_CONTROL_MMR_WRITE_SHFT 30 -#define UV3H_GR1_TLB_MMR_CONTROL_MMR_READ_SHFT 31 -#define UV3H_GR1_TLB_MMR_CONTROL_MMR_OP_DONE_SHFT 32 -#define UV3H_GR1_TLB_MMR_CONTROL_INDEX_MASK 0x0000000000000fffUL -#define UV3H_GR1_TLB_MMR_CONTROL_MEM_SEL_MASK 0x0000000000003000UL -#define UV3H_GR1_TLB_MMR_CONTROL_AUTO_VALID_EN_MASK 0x0000000000010000UL -#define UV3H_GR1_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_MASK 0x0000000000100000UL -#define UV3H_GR1_TLB_MMR_CONTROL_ECC_SEL_MASK 0x0000000000200000UL -#define UV3H_GR1_TLB_MMR_CONTROL_MMR_WRITE_MASK 0x0000000040000000UL -#define UV3H_GR1_TLB_MMR_CONTROL_MMR_READ_MASK 0x0000000080000000UL -#define UV3H_GR1_TLB_MMR_CONTROL_MMR_OP_DONE_MASK 0x0000000100000000UL - -#define UV4H_GR1_TLB_MMR_CONTROL_INDEX_SHFT 0 -#define UV4H_GR1_TLB_MMR_CONTROL_MEM_SEL_SHFT 13 -#define UV4H_GR1_TLB_MMR_CONTROL_AUTO_VALID_EN_SHFT 16 -#define UV4H_GR1_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_SHFT 20 -#define UV4H_GR1_TLB_MMR_CONTROL_ECC_SEL_SHFT 21 -#define UV4H_GR1_TLB_MMR_CONTROL_MMR_WRITE_SHFT 30 -#define UV4H_GR1_TLB_MMR_CONTROL_MMR_READ_SHFT 31 -#define UV4H_GR1_TLB_MMR_CONTROL_MMR_OP_DONE_SHFT 32 -#define UV4H_GR1_TLB_MMR_CONTROL_PAGE_SIZE_SHFT 59 -#define UV4H_GR1_TLB_MMR_CONTROL_INDEX_MASK 0x0000000000001fffUL -#define UV4H_GR1_TLB_MMR_CONTROL_MEM_SEL_MASK 0x0000000000006000UL -#define UV4H_GR1_TLB_MMR_CONTROL_AUTO_VALID_EN_MASK 0x0000000000010000UL -#define UV4H_GR1_TLB_MMR_CONTROL_MMR_HASH_INDEX_EN_MASK 0x0000000000100000UL -#define UV4H_GR1_TLB_MMR_CONTROL_ECC_SEL_MASK 0x0000000000200000UL -#define UV4H_GR1_TLB_MMR_CONTROL_MMR_WRITE_MASK 0x0000000040000000UL -#define UV4H_GR1_TLB_MMR_CONTROL_MMR_READ_MASK 0x0000000080000000UL -#define UV4H_GR1_TLB_MMR_CONTROL_MMR_OP_DONE_MASK 0x0000000100000000UL -#define UV4H_GR1_TLB_MMR_CONTROL_PAGE_SIZE_MASK 0xf800000000000000UL - - -union uvh_gr1_tlb_mmr_control_u { - unsigned long v; - struct uvh_gr1_tlb_mmr_control_s { - unsigned long rsvd_0_15:16; - unsigned long auto_valid_en:1; /* RW */ - unsigned long rsvd_17_19:3; - unsigned long mmr_hash_index_en:1; /* RW */ - unsigned long rsvd_21_29:9; - unsigned long mmr_write:1; /* WP */ - unsigned long mmr_read:1; /* WP */ - unsigned long rsvd_32_48:17; - unsigned long rsvd_49_51:3; - unsigned long rsvd_52_63:12; - } s; - struct uvxh_gr1_tlb_mmr_control_s { - unsigned long rsvd_0_15:16; - unsigned long auto_valid_en:1; /* RW */ - unsigned long rsvd_17_19:3; - unsigned long mmr_hash_index_en:1; /* RW */ - unsigned long rsvd_21_29:9; - unsigned long mmr_write:1; /* WP */ - unsigned long mmr_read:1; /* WP */ - unsigned long mmr_op_done:1; /* RW */ - unsigned long rsvd_33_47:15; - unsigned long rsvd_48:1; - unsigned long rsvd_49_51:3; - unsigned long rsvd_52_63:12; + /* UVXH common struct */ + struct uvxh_gr1_tlb_int1_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ } sx; - struct uv2h_gr1_tlb_mmr_control_s { - unsigned long index:12; /* RW */ - unsigned long mem_sel:2; /* RW */ - unsigned long rsvd_14_15:2; - unsigned long auto_valid_en:1; /* RW */ - unsigned long rsvd_17_19:3; - unsigned long mmr_hash_index_en:1; /* RW */ - unsigned long rsvd_21_29:9; - unsigned long mmr_write:1; /* WP */ - unsigned long mmr_read:1; /* WP */ - unsigned long mmr_op_done:1; /* RW */ - unsigned long rsvd_33_47:15; - unsigned long mmr_inj_con:1; /* RW */ - unsigned long rsvd_49_51:3; - unsigned long mmr_inj_tlbram:1; /* RW */ - unsigned long rsvd_53_63:11; - } s2; - struct uv3h_gr1_tlb_mmr_control_s { - unsigned long index:12; /* RW */ - unsigned long mem_sel:2; /* RW */ - unsigned long rsvd_14_15:2; - unsigned long auto_valid_en:1; /* RW */ - unsigned long rsvd_17_19:3; - unsigned long mmr_hash_index_en:1; /* RW */ - unsigned long ecc_sel:1; /* RW */ - unsigned long rsvd_22_29:8; - unsigned long mmr_write:1; /* WP */ - unsigned long mmr_read:1; /* WP */ - unsigned long mmr_op_done:1; /* RW */ - unsigned long rsvd_33_47:15; - unsigned long undef_48:1; /* Undefined */ - unsigned long rsvd_49_51:3; - unsigned long undef_52:1; /* Undefined */ - unsigned long rsvd_53_63:11; - } s3; - struct uv4h_gr1_tlb_mmr_control_s { - unsigned long index:13; /* RW */ - unsigned long mem_sel:2; /* RW */ - unsigned long rsvd_15:1; - unsigned long auto_valid_en:1; /* RW */ - unsigned long rsvd_17_19:3; - unsigned long mmr_hash_index_en:1; /* RW */ - unsigned long ecc_sel:1; /* RW */ - unsigned long rsvd_22_29:8; - unsigned long mmr_write:1; /* WP */ - unsigned long mmr_read:1; /* WP */ - unsigned long mmr_op_done:1; /* RW */ - unsigned long rsvd_33_47:15; - unsigned long undef_48:1; /* Undefined */ - unsigned long rsvd_49_51:3; - unsigned long rsvd_52_58:7; - unsigned long page_size:5; /* RW */ + + /* UV4 unique struct */ + struct uv4h_gr1_tlb_int1_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ } s4; -}; -/* ========================================================================= */ -/* UVH_GR1_TLB_MMR_READ_DATA_HI */ -/* ========================================================================= */ -#define UV2H_GR1_TLB_MMR_READ_DATA_HI 0x10010a0UL -#define UV3H_GR1_TLB_MMR_READ_DATA_HI 0x10010a0UL -#define UV4H_GR1_TLB_MMR_READ_DATA_HI 0x7010a0UL -#define UVH_GR1_TLB_MMR_READ_DATA_HI ( \ - is_uv2_hub() ? UV2H_GR1_TLB_MMR_READ_DATA_HI : \ - is_uv3_hub() ? UV3H_GR1_TLB_MMR_READ_DATA_HI : \ - /*is_uv4_hub*/ UV4H_GR1_TLB_MMR_READ_DATA_HI) - -#define UVH_GR1_TLB_MMR_READ_DATA_HI_PFN_SHFT 0 - -#define UVXH_GR1_TLB_MMR_READ_DATA_HI_PFN_SHFT 0 - -#define UV2H_GR1_TLB_MMR_READ_DATA_HI_PFN_SHFT 0 -#define UV2H_GR1_TLB_MMR_READ_DATA_HI_GAA_SHFT 41 -#define UV2H_GR1_TLB_MMR_READ_DATA_HI_DIRTY_SHFT 43 -#define UV2H_GR1_TLB_MMR_READ_DATA_HI_LARGER_SHFT 44 -#define UV2H_GR1_TLB_MMR_READ_DATA_HI_PFN_MASK 0x000001ffffffffffUL -#define UV2H_GR1_TLB_MMR_READ_DATA_HI_GAA_MASK 0x0000060000000000UL -#define UV2H_GR1_TLB_MMR_READ_DATA_HI_DIRTY_MASK 0x0000080000000000UL -#define UV2H_GR1_TLB_MMR_READ_DATA_HI_LARGER_MASK 0x0000100000000000UL - -#define UV3H_GR1_TLB_MMR_READ_DATA_HI_PFN_SHFT 0 -#define UV3H_GR1_TLB_MMR_READ_DATA_HI_GAA_SHFT 41 -#define UV3H_GR1_TLB_MMR_READ_DATA_HI_DIRTY_SHFT 43 -#define UV3H_GR1_TLB_MMR_READ_DATA_HI_LARGER_SHFT 44 -#define UV3H_GR1_TLB_MMR_READ_DATA_HI_AA_EXT_SHFT 45 -#define UV3H_GR1_TLB_MMR_READ_DATA_HI_WAY_ECC_SHFT 55 -#define UV3H_GR1_TLB_MMR_READ_DATA_HI_PFN_MASK 0x000001ffffffffffUL -#define UV3H_GR1_TLB_MMR_READ_DATA_HI_GAA_MASK 0x0000060000000000UL -#define UV3H_GR1_TLB_MMR_READ_DATA_HI_DIRTY_MASK 0x0000080000000000UL -#define UV3H_GR1_TLB_MMR_READ_DATA_HI_LARGER_MASK 0x0000100000000000UL -#define UV3H_GR1_TLB_MMR_READ_DATA_HI_AA_EXT_MASK 0x0000200000000000UL -#define UV3H_GR1_TLB_MMR_READ_DATA_HI_WAY_ECC_MASK 0xff80000000000000UL - -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_PFN_SHFT 0 -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_PNID_SHFT 34 -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_GAA_SHFT 49 -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_DIRTY_SHFT 51 -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_LARGER_SHFT 52 -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_AA_EXT_SHFT 53 -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_WAY_ECC_SHFT 55 -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_PFN_MASK 0x00000003ffffffffUL -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_PNID_MASK 0x0001fffc00000000UL -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_GAA_MASK 0x0006000000000000UL -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_DIRTY_MASK 0x0008000000000000UL -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_LARGER_MASK 0x0010000000000000UL -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_AA_EXT_MASK 0x0020000000000000UL -#define UV4H_GR1_TLB_MMR_READ_DATA_HI_WAY_ECC_MASK 0xff80000000000000UL - - -union uvh_gr1_tlb_mmr_read_data_hi_u { - unsigned long v; - struct uv2h_gr1_tlb_mmr_read_data_hi_s { - unsigned long pfn:41; /* RO */ - unsigned long gaa:2; /* RO */ - unsigned long dirty:1; /* RO */ - unsigned long larger:1; /* RO */ - unsigned long rsvd_45_63:19; - } s2; - struct uv3h_gr1_tlb_mmr_read_data_hi_s { - unsigned long pfn:41; /* RO */ - unsigned long gaa:2; /* RO */ - unsigned long dirty:1; /* RO */ - unsigned long larger:1; /* RO */ - unsigned long aa_ext:1; /* RO */ - unsigned long undef_46_54:9; /* Undefined */ - unsigned long way_ecc:9; /* RO */ + /* UV3 unique struct */ + struct uv3h_gr1_tlb_int1_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ } s3; - struct uv4h_gr1_tlb_mmr_read_data_hi_s { - unsigned long pfn:34; /* RO */ - unsigned long pnid:15; /* RO */ - unsigned long gaa:2; /* RO */ - unsigned long dirty:1; /* RO */ - unsigned long larger:1; /* RO */ - unsigned long aa_ext:1; /* RO */ - unsigned long undef_54:1; /* Undefined */ - unsigned long way_ecc:9; /* RO */ - } s4; -}; -/* ========================================================================= */ -/* UVH_GR1_TLB_MMR_READ_DATA_LO */ -/* ========================================================================= */ -#define UV2H_GR1_TLB_MMR_READ_DATA_LO 0x10010a8UL -#define UV3H_GR1_TLB_MMR_READ_DATA_LO 0x10010a8UL -#define UV4H_GR1_TLB_MMR_READ_DATA_LO 0x7010a8UL -#define UVH_GR1_TLB_MMR_READ_DATA_LO ( \ - is_uv2_hub() ? UV2H_GR1_TLB_MMR_READ_DATA_LO : \ - is_uv3_hub() ? UV3H_GR1_TLB_MMR_READ_DATA_LO : \ - /*is_uv4_hub*/ UV4H_GR1_TLB_MMR_READ_DATA_LO) - -#define UVH_GR1_TLB_MMR_READ_DATA_LO_VPN_SHFT 0 -#define UVH_GR1_TLB_MMR_READ_DATA_LO_ASID_SHFT 39 -#define UVH_GR1_TLB_MMR_READ_DATA_LO_VALID_SHFT 63 -#define UVH_GR1_TLB_MMR_READ_DATA_LO_VPN_MASK 0x0000007fffffffffUL -#define UVH_GR1_TLB_MMR_READ_DATA_LO_ASID_MASK 0x7fffff8000000000UL -#define UVH_GR1_TLB_MMR_READ_DATA_LO_VALID_MASK 0x8000000000000000UL - -#define UVXH_GR1_TLB_MMR_READ_DATA_LO_VPN_SHFT 0 -#define UVXH_GR1_TLB_MMR_READ_DATA_LO_ASID_SHFT 39 -#define UVXH_GR1_TLB_MMR_READ_DATA_LO_VALID_SHFT 63 -#define UVXH_GR1_TLB_MMR_READ_DATA_LO_VPN_MASK 0x0000007fffffffffUL -#define UVXH_GR1_TLB_MMR_READ_DATA_LO_ASID_MASK 0x7fffff8000000000UL -#define UVXH_GR1_TLB_MMR_READ_DATA_LO_VALID_MASK 0x8000000000000000UL - -#define UV2H_GR1_TLB_MMR_READ_DATA_LO_VPN_SHFT 0 -#define UV2H_GR1_TLB_MMR_READ_DATA_LO_ASID_SHFT 39 -#define UV2H_GR1_TLB_MMR_READ_DATA_LO_VALID_SHFT 63 -#define UV2H_GR1_TLB_MMR_READ_DATA_LO_VPN_MASK 0x0000007fffffffffUL -#define UV2H_GR1_TLB_MMR_READ_DATA_LO_ASID_MASK 0x7fffff8000000000UL -#define UV2H_GR1_TLB_MMR_READ_DATA_LO_VALID_MASK 0x8000000000000000UL - -#define UV3H_GR1_TLB_MMR_READ_DATA_LO_VPN_SHFT 0 -#define UV3H_GR1_TLB_MMR_READ_DATA_LO_ASID_SHFT 39 -#define UV3H_GR1_TLB_MMR_READ_DATA_LO_VALID_SHFT 63 -#define UV3H_GR1_TLB_MMR_READ_DATA_LO_VPN_MASK 0x0000007fffffffffUL -#define UV3H_GR1_TLB_MMR_READ_DATA_LO_ASID_MASK 0x7fffff8000000000UL -#define UV3H_GR1_TLB_MMR_READ_DATA_LO_VALID_MASK 0x8000000000000000UL - -#define UV4H_GR1_TLB_MMR_READ_DATA_LO_VPN_SHFT 0 -#define UV4H_GR1_TLB_MMR_READ_DATA_LO_ASID_SHFT 39 -#define UV4H_GR1_TLB_MMR_READ_DATA_LO_VALID_SHFT 63 -#define UV4H_GR1_TLB_MMR_READ_DATA_LO_VPN_MASK 0x0000007fffffffffUL -#define UV4H_GR1_TLB_MMR_READ_DATA_LO_ASID_MASK 0x7fffff8000000000UL -#define UV4H_GR1_TLB_MMR_READ_DATA_LO_VALID_MASK 0x8000000000000000UL - - -union uvh_gr1_tlb_mmr_read_data_lo_u { - unsigned long v; - struct uvh_gr1_tlb_mmr_read_data_lo_s { - unsigned long vpn:39; /* RO */ - unsigned long asid:24; /* RO */ - unsigned long valid:1; /* RO */ - } s; - struct uvxh_gr1_tlb_mmr_read_data_lo_s { - unsigned long vpn:39; /* RO */ - unsigned long asid:24; /* RO */ - unsigned long valid:1; /* RO */ - } sx; - struct uv2h_gr1_tlb_mmr_read_data_lo_s { - unsigned long vpn:39; /* RO */ - unsigned long asid:24; /* RO */ - unsigned long valid:1; /* RO */ + /* UV2 unique struct */ + struct uv2h_gr1_tlb_int1_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ } s2; - struct uv3h_gr1_tlb_mmr_read_data_lo_s { - unsigned long vpn:39; /* RO */ - unsigned long asid:24; /* RO */ - unsigned long valid:1; /* RO */ - } s3; - struct uv4h_gr1_tlb_mmr_read_data_lo_s { - unsigned long vpn:39; /* RO */ - unsigned long asid:24; /* RO */ - unsigned long valid:1; /* RO */ - } s4; }; /* ========================================================================= */ @@ -1452,52 +2661,43 @@ union uvh_gr1_tlb_mmr_read_data_lo_u { /* ========================================================================= */ #define UVH_INT_CMPB 0x22080UL +/* UVH common defines*/ #define UVH_INT_CMPB_REAL_TIME_CMPB_SHFT 0 #define UVH_INT_CMPB_REAL_TIME_CMPB_MASK 0x00ffffffffffffffUL union uvh_int_cmpb_u { unsigned long v; + + /* UVH common struct */ struct uvh_int_cmpb_s { unsigned long real_time_cmpb:56; /* RW */ unsigned long rsvd_56_63:8; } s; -}; - -/* ========================================================================= */ -/* UVH_INT_CMPC */ -/* ========================================================================= */ -#define UVH_INT_CMPC 0x22100UL - - -#define UVXH_INT_CMPC_REAL_TIME_CMP_2_SHFT 0 -#define UVXH_INT_CMPC_REAL_TIME_CMP_2_MASK 0x00ffffffffffffffUL - -union uvh_int_cmpc_u { - unsigned long v; - struct uvh_int_cmpc_s { - unsigned long real_time_cmpc:56; /* RW */ + /* UV5 unique struct */ + struct uv5h_int_cmpb_s { + unsigned long real_time_cmpb:56; /* RW */ unsigned long rsvd_56_63:8; - } s; -}; + } s5; -/* ========================================================================= */ -/* UVH_INT_CMPD */ -/* ========================================================================= */ -#define UVH_INT_CMPD 0x22180UL - - -#define UVXH_INT_CMPD_REAL_TIME_CMP_3_SHFT 0 -#define UVXH_INT_CMPD_REAL_TIME_CMP_3_MASK 0x00ffffffffffffffUL + /* UV4 unique struct */ + struct uv4h_int_cmpb_s { + unsigned long real_time_cmpb:56; /* RW */ + unsigned long rsvd_56_63:8; + } s4; + /* UV3 unique struct */ + struct uv3h_int_cmpb_s { + unsigned long real_time_cmpb:56; /* RW */ + unsigned long rsvd_56_63:8; + } s3; -union uvh_int_cmpd_u { - unsigned long v; - struct uvh_int_cmpd_s { - unsigned long real_time_cmpd:56; /* RW */ + /* UV2 unique struct */ + struct uv2h_int_cmpb_s { + unsigned long real_time_cmpb:56; /* RW */ unsigned long rsvd_56_63:8; - } s; + } s2; }; /* ========================================================================= */ @@ -1505,28 +2705,23 @@ union uvh_int_cmpd_u { /* ========================================================================= */ #define UVH_IPI_INT 0x60500UL -#define UV2H_IPI_INT_32 0x348 -#define UV3H_IPI_INT_32 0x348 -#define UV4H_IPI_INT_32 0x268 -#define UVH_IPI_INT_32 ( \ - is_uv2_hub() ? UV2H_IPI_INT_32 : \ - is_uv3_hub() ? UV3H_IPI_INT_32 : \ - /*is_uv4_hub*/ UV4H_IPI_INT_32) - +/* UVH common defines*/ #define UVH_IPI_INT_VECTOR_SHFT 0 -#define UVH_IPI_INT_DELIVERY_MODE_SHFT 8 -#define UVH_IPI_INT_DESTMODE_SHFT 11 -#define UVH_IPI_INT_APIC_ID_SHFT 16 -#define UVH_IPI_INT_SEND_SHFT 63 #define UVH_IPI_INT_VECTOR_MASK 0x00000000000000ffUL +#define UVH_IPI_INT_DELIVERY_MODE_SHFT 8 #define UVH_IPI_INT_DELIVERY_MODE_MASK 0x0000000000000700UL +#define UVH_IPI_INT_DESTMODE_SHFT 11 #define UVH_IPI_INT_DESTMODE_MASK 0x0000000000000800UL +#define UVH_IPI_INT_APIC_ID_SHFT 16 #define UVH_IPI_INT_APIC_ID_MASK 0x0000ffffffff0000UL +#define UVH_IPI_INT_SEND_SHFT 63 #define UVH_IPI_INT_SEND_MASK 0x8000000000000000UL union uvh_ipi_int_u { unsigned long v; + + /* UVH common struct */ struct uvh_ipi_int_s { unsigned long vector_:8; /* RW */ unsigned long delivery_mode:3; /* RW */ @@ -1536,903 +2731,105 @@ union uvh_ipi_int_u { unsigned long rsvd_48_62:15; unsigned long send:1; /* WP */ } s; -}; - -/* ========================================================================= */ -/* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST */ -/* ========================================================================= */ -#define UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST 0x320050UL -#define UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST 0x320050UL -#define UV4H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST uv_undefined("UV4H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST") -#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST ( \ - is_uv2_hub() ? UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST : \ - is_uv3_hub() ? UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST : \ - /*is_uv4_hub*/ UV4H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST) -#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_32 0x9c0 - - -#define UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_SHFT 4 -#define UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_NODE_ID_SHFT 49 -#define UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_MASK 0x000007fffffffff0UL -#define UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_NODE_ID_MASK 0x7ffe000000000000UL - -#define UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_SHFT 4 -#define UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_NODE_ID_SHFT 49 -#define UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_MASK 0x000007fffffffff0UL -#define UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_NODE_ID_MASK 0x7ffe000000000000UL - - -union uvh_lb_bau_intd_payload_queue_first_u { - unsigned long v; - struct uv2h_lb_bau_intd_payload_queue_first_s { - unsigned long rsvd_0_3:4; - unsigned long address:39; /* RW */ - unsigned long rsvd_43_48:6; - unsigned long node_id:14; /* RW */ - unsigned long rsvd_63:1; - } s2; - struct uv3h_lb_bau_intd_payload_queue_first_s { - unsigned long rsvd_0_3:4; - unsigned long address:39; /* RW */ - unsigned long rsvd_43_48:6; - unsigned long node_id:14; /* RW */ - unsigned long rsvd_63:1; - } s3; -}; - -/* ========================================================================= */ -/* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST */ -/* ========================================================================= */ -#define UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_LAST 0x320060UL -#define UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_LAST 0x320060UL -#define UV4H_LB_BAU_INTD_PAYLOAD_QUEUE_LAST uv_undefined("UV4H_LB_BAU_INTD_PAYLOAD_QUEUE_LAST") -#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST ( \ - is_uv2_hub() ? UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_LAST : \ - is_uv3_hub() ? UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_LAST : \ - /*is_uv4_hub*/ UV4H_LB_BAU_INTD_PAYLOAD_QUEUE_LAST) -#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_32 0x9c8 - - -#define UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_SHFT 4 -#define UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_MASK 0x000007fffffffff0UL - -#define UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_SHFT 4 -#define UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_MASK 0x000007fffffffff0UL - - -union uvh_lb_bau_intd_payload_queue_last_u { - unsigned long v; - struct uv2h_lb_bau_intd_payload_queue_last_s { - unsigned long rsvd_0_3:4; - unsigned long address:39; /* RW */ - unsigned long rsvd_43_63:21; - } s2; - struct uv3h_lb_bau_intd_payload_queue_last_s { - unsigned long rsvd_0_3:4; - unsigned long address:39; /* RW */ - unsigned long rsvd_43_63:21; - } s3; -}; - -/* ========================================================================= */ -/* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL */ -/* ========================================================================= */ -#define UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL 0x320070UL -#define UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL 0x320070UL -#define UV4H_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL uv_undefined("UV4H_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL") -#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL ( \ - is_uv2_hub() ? UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL : \ - is_uv3_hub() ? UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL : \ - /*is_uv4_hub*/ UV4H_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL) -#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_32 0x9d0 - - -#define UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_SHFT 4 -#define UV2H_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_MASK 0x000007fffffffff0UL - -#define UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_SHFT 4 -#define UV3H_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_MASK 0x000007fffffffff0UL + /* UV5 unique struct */ + struct uv5h_ipi_int_s { + unsigned long vector_:8; /* RW */ + unsigned long delivery_mode:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long rsvd_12_15:4; + unsigned long apic_id:32; /* RW */ + unsigned long rsvd_48_62:15; + unsigned long send:1; /* WP */ + } s5; -union uvh_lb_bau_intd_payload_queue_tail_u { - unsigned long v; - struct uv2h_lb_bau_intd_payload_queue_tail_s { - unsigned long rsvd_0_3:4; - unsigned long address:39; /* RW */ - unsigned long rsvd_43_63:21; - } s2; - struct uv3h_lb_bau_intd_payload_queue_tail_s { - unsigned long rsvd_0_3:4; - unsigned long address:39; /* RW */ - unsigned long rsvd_43_63:21; - } s3; -}; + /* UV4 unique struct */ + struct uv4h_ipi_int_s { + unsigned long vector_:8; /* RW */ + unsigned long delivery_mode:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long rsvd_12_15:4; + unsigned long apic_id:32; /* RW */ + unsigned long rsvd_48_62:15; + unsigned long send:1; /* WP */ + } s4; -/* ========================================================================= */ -/* UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE */ -/* ========================================================================= */ -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE 0x320080UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE 0x320080UL -#define UV4H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE uv_undefined("UV4H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE") -#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE ( \ - is_uv2_hub() ? UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE : \ - is_uv3_hub() ? UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE : \ - /*is_uv4_hub*/ UV4H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE) -#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_32 0xa68 - - -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_SHFT 0 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_1_SHFT 1 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_2_SHFT 2 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_3_SHFT 3 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_4_SHFT 4 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_5_SHFT 5 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_6_SHFT 6 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_7_SHFT 7 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_0_SHFT 8 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_1_SHFT 9 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_2_SHFT 10 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_3_SHFT 11 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_4_SHFT 12 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_5_SHFT 13 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_6_SHFT 14 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_SHFT 15 -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_MASK 0x0000000000000001UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_1_MASK 0x0000000000000002UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_2_MASK 0x0000000000000004UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_3_MASK 0x0000000000000008UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_4_MASK 0x0000000000000010UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_5_MASK 0x0000000000000020UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_6_MASK 0x0000000000000040UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_7_MASK 0x0000000000000080UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_0_MASK 0x0000000000000100UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_1_MASK 0x0000000000000200UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_2_MASK 0x0000000000000400UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_3_MASK 0x0000000000000800UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_4_MASK 0x0000000000001000UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_5_MASK 0x0000000000002000UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_6_MASK 0x0000000000004000UL -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_MASK 0x0000000000008000UL - -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_SHFT 0 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_1_SHFT 1 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_2_SHFT 2 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_3_SHFT 3 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_4_SHFT 4 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_5_SHFT 5 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_6_SHFT 6 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_7_SHFT 7 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_0_SHFT 8 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_1_SHFT 9 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_2_SHFT 10 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_3_SHFT 11 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_4_SHFT 12 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_5_SHFT 13 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_6_SHFT 14 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_SHFT 15 -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_MASK 0x0000000000000001UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_1_MASK 0x0000000000000002UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_2_MASK 0x0000000000000004UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_3_MASK 0x0000000000000008UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_4_MASK 0x0000000000000010UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_5_MASK 0x0000000000000020UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_6_MASK 0x0000000000000040UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_7_MASK 0x0000000000000080UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_0_MASK 0x0000000000000100UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_1_MASK 0x0000000000000200UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_2_MASK 0x0000000000000400UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_3_MASK 0x0000000000000800UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_4_MASK 0x0000000000001000UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_5_MASK 0x0000000000002000UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_6_MASK 0x0000000000004000UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_MASK 0x0000000000008000UL - - -union uvh_lb_bau_intd_software_acknowledge_u { - unsigned long v; - struct uv2h_lb_bau_intd_software_acknowledge_s { - unsigned long pending_0:1; /* RW */ - unsigned long pending_1:1; /* RW */ - unsigned long pending_2:1; /* RW */ - unsigned long pending_3:1; /* RW */ - unsigned long pending_4:1; /* RW */ - unsigned long pending_5:1; /* RW */ - unsigned long pending_6:1; /* RW */ - unsigned long pending_7:1; /* RW */ - unsigned long timeout_0:1; /* RW */ - unsigned long timeout_1:1; /* RW */ - unsigned long timeout_2:1; /* RW */ - unsigned long timeout_3:1; /* RW */ - unsigned long timeout_4:1; /* RW */ - unsigned long timeout_5:1; /* RW */ - unsigned long timeout_6:1; /* RW */ - unsigned long timeout_7:1; /* RW */ - unsigned long rsvd_16_63:48; - } s2; - struct uv3h_lb_bau_intd_software_acknowledge_s { - unsigned long pending_0:1; /* RW */ - unsigned long pending_1:1; /* RW */ - unsigned long pending_2:1; /* RW */ - unsigned long pending_3:1; /* RW */ - unsigned long pending_4:1; /* RW */ - unsigned long pending_5:1; /* RW */ - unsigned long pending_6:1; /* RW */ - unsigned long pending_7:1; /* RW */ - unsigned long timeout_0:1; /* RW */ - unsigned long timeout_1:1; /* RW */ - unsigned long timeout_2:1; /* RW */ - unsigned long timeout_3:1; /* RW */ - unsigned long timeout_4:1; /* RW */ - unsigned long timeout_5:1; /* RW */ - unsigned long timeout_6:1; /* RW */ - unsigned long timeout_7:1; /* RW */ - unsigned long rsvd_16_63:48; + /* UV3 unique struct */ + struct uv3h_ipi_int_s { + unsigned long vector_:8; /* RW */ + unsigned long delivery_mode:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long rsvd_12_15:4; + unsigned long apic_id:32; /* RW */ + unsigned long rsvd_48_62:15; + unsigned long send:1; /* WP */ } s3; -}; -/* ========================================================================= */ -/* UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS */ -/* ========================================================================= */ -#define UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS 0x320088UL -#define UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS 0x320088UL -#define UV4H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS uv_undefined("UV4H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS") -#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS ( \ - is_uv2_hub() ? UV2H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS : \ - is_uv3_hub() ? UV3H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS : \ - /*is_uv4_hub*/ UV4H_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS) -#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS_32 0xa70 - - -/* ========================================================================= */ -/* UVH_LB_BAU_MISC_CONTROL */ -/* ========================================================================= */ -#define UV2H_LB_BAU_MISC_CONTROL 0x320170UL -#define UV3H_LB_BAU_MISC_CONTROL 0x320170UL -#define UV4H_LB_BAU_MISC_CONTROL 0xc8170UL -#define UVH_LB_BAU_MISC_CONTROL ( \ - is_uv2_hub() ? UV2H_LB_BAU_MISC_CONTROL : \ - is_uv3_hub() ? UV3H_LB_BAU_MISC_CONTROL : \ - /*is_uv4_hub*/ UV4H_LB_BAU_MISC_CONTROL) - -#define UV2H_LB_BAU_MISC_CONTROL_32 0xa10 -#define UV3H_LB_BAU_MISC_CONTROL_32 0xa10 -#define UV4H_LB_BAU_MISC_CONTROL_32 0xa18 -#define UVH_LB_BAU_MISC_CONTROL_32 ( \ - is_uv2_hub() ? UV2H_LB_BAU_MISC_CONTROL_32 : \ - is_uv3_hub() ? UV3H_LB_BAU_MISC_CONTROL_32 : \ - /*is_uv4_hub*/ UV4H_LB_BAU_MISC_CONTROL_32) - -#define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 -#define UVH_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8 -#define UVH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9 -#define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 -#define UVH_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11 -#define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 -#define UVH_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20 -#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21 -#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22 -#define UVH_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23 -#define UVH_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24 -#define UVH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27 -#define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 -#define UVH_LB_BAU_MISC_CONTROL_FUN_SHFT 48 -#define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL -#define UVH_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL -#define UVH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL -#define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL -#define UVH_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL -#define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL -#define UVH_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL -#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL -#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL -#define UVH_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL -#define UVH_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL -#define UVH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL -#define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL -#define UVH_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL - -#define UVXH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 -#define UVXH_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8 -#define UVXH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9 -#define UVXH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 -#define UVXH_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11 -#define UVXH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 -#define UVXH_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20 -#define UVXH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21 -#define UVXH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22 -#define UVXH_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23 -#define UVXH_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24 -#define UVXH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27 -#define UVXH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 -#define UVXH_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_SHFT 29 -#define UVXH_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_SHFT 30 -#define UVXH_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_SHFT 31 -#define UVXH_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_SHFT 32 -#define UVXH_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT 33 -#define UVXH_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_SHFT 34 -#define UVXH_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT 35 -#define UVXH_LB_BAU_MISC_CONTROL_FUN_SHFT 48 -#define UVXH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL -#define UVXH_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL -#define UVXH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL -#define UVXH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL -#define UVXH_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL -#define UVXH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL -#define UVXH_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL -#define UVXH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL -#define UVXH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL -#define UVXH_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL -#define UVXH_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL -#define UVXH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL -#define UVXH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL -#define UVXH_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_MASK 0x0000000020000000UL -#define UVXH_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_MASK 0x0000000040000000UL -#define UVXH_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_MASK 0x0000000080000000UL -#define UVXH_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_MASK 0x0000000100000000UL -#define UVXH_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_MASK 0x0000000200000000UL -#define UVXH_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_MASK 0x0000000400000000UL -#define UVXH_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_MASK 0x0000000800000000UL -#define UVXH_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL - -#define UV2H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 -#define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8 -#define UV2H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9 -#define UV2H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 -#define UV2H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11 -#define UV2H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 -#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15 -#define UV2H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT 16 -#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20 -#define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21 -#define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22 -#define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23 -#define UV2H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24 -#define UV2H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27 -#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 -#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_SHFT 29 -#define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_SHFT 30 -#define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_SHFT 31 -#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_SHFT 32 -#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT 33 -#define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_SHFT 34 -#define UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT 35 -#define UV2H_LB_BAU_MISC_CONTROL_FUN_SHFT 48 -#define UV2H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL -#define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL -#define UV2H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL -#define UV2H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL -#define UV2H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL -#define UV2H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL -#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK 0x0000000000008000UL -#define UV2H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK 0x00000000000f0000UL -#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL -#define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL -#define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL -#define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL -#define UV2H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL -#define UV2H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL -#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL -#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_MASK 0x0000000020000000UL -#define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_MASK 0x0000000040000000UL -#define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_MASK 0x0000000080000000UL -#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_MASK 0x0000000100000000UL -#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_MASK 0x0000000200000000UL -#define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_MASK 0x0000000400000000UL -#define UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_MASK 0x0000000800000000UL -#define UV2H_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL - -#define UV3H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 -#define UV3H_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8 -#define UV3H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9 -#define UV3H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 -#define UV3H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11 -#define UV3H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15 -#define UV3H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT 16 -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20 -#define UV3H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21 -#define UV3H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22 -#define UV3H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23 -#define UV3H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24 -#define UV3H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27 -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_SHFT 29 -#define UV3H_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_SHFT 30 -#define UV3H_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_SHFT 31 -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_SHFT 32 -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT 33 -#define UV3H_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_SHFT 34 -#define UV3H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT 35 -#define UV3H_LB_BAU_MISC_CONTROL_SUPPRESS_QUIESCE_MSGS_TO_QPI_SHFT 36 -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_INTD_PREFETCH_HINT_SHFT 37 -#define UV3H_LB_BAU_MISC_CONTROL_THREAD_KILL_TIMEBASE_SHFT 38 -#define UV3H_LB_BAU_MISC_CONTROL_FUN_SHFT 48 -#define UV3H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL -#define UV3H_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL -#define UV3H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL -#define UV3H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL -#define UV3H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL -#define UV3H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK 0x0000000000008000UL -#define UV3H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK 0x00000000000f0000UL -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL -#define UV3H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL -#define UV3H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL -#define UV3H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL -#define UV3H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL -#define UV3H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_MASK 0x0000000020000000UL -#define UV3H_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_MASK 0x0000000040000000UL -#define UV3H_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_MASK 0x0000000080000000UL -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_MASK 0x0000000100000000UL -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_MASK 0x0000000200000000UL -#define UV3H_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_MASK 0x0000000400000000UL -#define UV3H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_MASK 0x0000000800000000UL -#define UV3H_LB_BAU_MISC_CONTROL_SUPPRESS_QUIESCE_MSGS_TO_QPI_MASK 0x0000001000000000UL -#define UV3H_LB_BAU_MISC_CONTROL_ENABLE_INTD_PREFETCH_HINT_MASK 0x0000002000000000UL -#define UV3H_LB_BAU_MISC_CONTROL_THREAD_KILL_TIMEBASE_MASK 0x00003fc000000000UL -#define UV3H_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL - -#define UV4H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 -#define UV4H_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8 -#define UV4H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9 -#define UV4H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 -#define UV4H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11 -#define UV4H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 -#define UV4H_LB_BAU_MISC_CONTROL_RESERVED_15_19_SHFT 15 -#define UV4H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20 -#define UV4H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21 -#define UV4H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22 -#define UV4H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23 -#define UV4H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24 -#define UV4H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27 -#define UV4H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 -#define UV4H_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_SHFT 29 -#define UV4H_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_SHFT 30 -#define UV4H_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_SHFT 31 -#define UV4H_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_SHFT 32 -#define UV4H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT 33 -#define UV4H_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_SHFT 34 -#define UV4H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT 35 -#define UV4H_LB_BAU_MISC_CONTROL_SUPPRESS_QUIESCE_MSGS_TO_QPI_SHFT 36 -#define UV4H_LB_BAU_MISC_CONTROL_RESERVED_37_SHFT 37 -#define UV4H_LB_BAU_MISC_CONTROL_THREAD_KILL_TIMEBASE_SHFT 38 -#define UV4H_LB_BAU_MISC_CONTROL_ADDRESS_INTERLEAVE_SELECT_SHFT 46 -#define UV4H_LB_BAU_MISC_CONTROL_FUN_SHFT 48 -#define UV4H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL -#define UV4H_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL -#define UV4H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL -#define UV4H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL -#define UV4H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL -#define UV4H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL -#define UV4H_LB_BAU_MISC_CONTROL_RESERVED_15_19_MASK 0x00000000000f8000UL -#define UV4H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL -#define UV4H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL -#define UV4H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL -#define UV4H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL -#define UV4H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL -#define UV4H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL -#define UV4H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL -#define UV4H_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_MASK 0x0000000020000000UL -#define UV4H_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_MASK 0x0000000040000000UL -#define UV4H_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_MASK 0x0000000080000000UL -#define UV4H_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_MASK 0x0000000100000000UL -#define UV4H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_MASK 0x0000000200000000UL -#define UV4H_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_MASK 0x0000000400000000UL -#define UV4H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_MASK 0x0000000800000000UL -#define UV4H_LB_BAU_MISC_CONTROL_SUPPRESS_QUIESCE_MSGS_TO_QPI_MASK 0x0000001000000000UL -#define UV4H_LB_BAU_MISC_CONTROL_RESERVED_37_MASK 0x0000002000000000UL -#define UV4H_LB_BAU_MISC_CONTROL_THREAD_KILL_TIMEBASE_MASK 0x00003fc000000000UL -#define UV4H_LB_BAU_MISC_CONTROL_ADDRESS_INTERLEAVE_SELECT_MASK 0x0000400000000000UL -#define UV4H_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL - -#define UV4H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK \ - uv_undefined("UV4H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK") -#define UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK ( \ - is_uv2_hub() ? UV2H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK : \ - is_uv3_hub() ? UV3H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK : \ - /*is_uv4_hub*/ UV4H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK) -#define UV4H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT \ - uv_undefined("UV4H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT") -#define UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT ( \ - is_uv2_hub() ? UV2H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT : \ - is_uv3_hub() ? UV3H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT : \ - /*is_uv4_hub*/ UV4H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT) -#define UV4H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK \ - uv_undefined("UV4H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK") -#define UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK ( \ - is_uv2_hub() ? UV2H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK : \ - is_uv3_hub() ? UV3H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK : \ - /*is_uv4_hub*/ UV4H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK) -#define UV4H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT \ - uv_undefined("UV4H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT") -#define UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT ( \ - is_uv2_hub() ? UV2H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT : \ - is_uv3_hub() ? UV3H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT : \ - /*is_uv4_hub*/ UV4H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT) - -union uvh_lb_bau_misc_control_u { - unsigned long v; - struct uvh_lb_bau_misc_control_s { - unsigned long rejection_delay:8; /* RW */ - unsigned long apic_mode:1; /* RW */ - unsigned long force_broadcast:1; /* RW */ - unsigned long force_lock_nop:1; /* RW */ - unsigned long qpi_agent_presence_vector:3; /* RW */ - unsigned long descriptor_fetch_mode:1; /* RW */ - unsigned long rsvd_15_19:5; - unsigned long enable_dual_mapping_mode:1; /* RW */ - unsigned long vga_io_port_decode_enable:1; /* RW */ - unsigned long vga_io_port_16_bit_decode:1; /* RW */ - unsigned long suppress_dest_registration:1; /* RW */ - unsigned long programmed_initial_priority:3; /* RW */ - unsigned long use_incoming_priority:1; /* RW */ - unsigned long enable_programmed_initial_priority:1;/* RW */ - unsigned long rsvd_29_47:19; - unsigned long fun:16; /* RW */ - } s; - struct uvxh_lb_bau_misc_control_s { - unsigned long rejection_delay:8; /* RW */ - unsigned long apic_mode:1; /* RW */ - unsigned long force_broadcast:1; /* RW */ - unsigned long force_lock_nop:1; /* RW */ - unsigned long qpi_agent_presence_vector:3; /* RW */ - unsigned long descriptor_fetch_mode:1; /* RW */ - unsigned long rsvd_15_19:5; - unsigned long enable_dual_mapping_mode:1; /* RW */ - unsigned long vga_io_port_decode_enable:1; /* RW */ - unsigned long vga_io_port_16_bit_decode:1; /* RW */ - unsigned long suppress_dest_registration:1; /* RW */ - unsigned long programmed_initial_priority:3; /* RW */ - unsigned long use_incoming_priority:1; /* RW */ - unsigned long enable_programmed_initial_priority:1;/* RW */ - unsigned long enable_automatic_apic_mode_selection:1;/* RW */ - unsigned long apic_mode_status:1; /* RO */ - unsigned long suppress_interrupts_to_self:1; /* RW */ - unsigned long enable_lock_based_system_flush:1;/* RW */ - unsigned long enable_extended_sb_status:1; /* RW */ - unsigned long suppress_int_prio_udt_to_self:1;/* RW */ - unsigned long use_legacy_descriptor_formats:1;/* RW */ - unsigned long rsvd_36_47:12; - unsigned long fun:16; /* RW */ - } sx; - struct uv2h_lb_bau_misc_control_s { - unsigned long rejection_delay:8; /* RW */ - unsigned long apic_mode:1; /* RW */ - unsigned long force_broadcast:1; /* RW */ - unsigned long force_lock_nop:1; /* RW */ - unsigned long qpi_agent_presence_vector:3; /* RW */ - unsigned long descriptor_fetch_mode:1; /* RW */ - unsigned long enable_intd_soft_ack_mode:1; /* RW */ - unsigned long intd_soft_ack_timeout_period:4; /* RW */ - unsigned long enable_dual_mapping_mode:1; /* RW */ - unsigned long vga_io_port_decode_enable:1; /* RW */ - unsigned long vga_io_port_16_bit_decode:1; /* RW */ - unsigned long suppress_dest_registration:1; /* RW */ - unsigned long programmed_initial_priority:3; /* RW */ - unsigned long use_incoming_priority:1; /* RW */ - unsigned long enable_programmed_initial_priority:1;/* RW */ - unsigned long enable_automatic_apic_mode_selection:1;/* RW */ - unsigned long apic_mode_status:1; /* RO */ - unsigned long suppress_interrupts_to_self:1; /* RW */ - unsigned long enable_lock_based_system_flush:1;/* RW */ - unsigned long enable_extended_sb_status:1; /* RW */ - unsigned long suppress_int_prio_udt_to_self:1;/* RW */ - unsigned long use_legacy_descriptor_formats:1;/* RW */ - unsigned long rsvd_36_47:12; - unsigned long fun:16; /* RW */ + /* UV2 unique struct */ + struct uv2h_ipi_int_s { + unsigned long vector_:8; /* RW */ + unsigned long delivery_mode:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long rsvd_12_15:4; + unsigned long apic_id:32; /* RW */ + unsigned long rsvd_48_62:15; + unsigned long send:1; /* WP */ } s2; - struct uv3h_lb_bau_misc_control_s { - unsigned long rejection_delay:8; /* RW */ - unsigned long apic_mode:1; /* RW */ - unsigned long force_broadcast:1; /* RW */ - unsigned long force_lock_nop:1; /* RW */ - unsigned long qpi_agent_presence_vector:3; /* RW */ - unsigned long descriptor_fetch_mode:1; /* RW */ - unsigned long enable_intd_soft_ack_mode:1; /* RW */ - unsigned long intd_soft_ack_timeout_period:4; /* RW */ - unsigned long enable_dual_mapping_mode:1; /* RW */ - unsigned long vga_io_port_decode_enable:1; /* RW */ - unsigned long vga_io_port_16_bit_decode:1; /* RW */ - unsigned long suppress_dest_registration:1; /* RW */ - unsigned long programmed_initial_priority:3; /* RW */ - unsigned long use_incoming_priority:1; /* RW */ - unsigned long enable_programmed_initial_priority:1;/* RW */ - unsigned long enable_automatic_apic_mode_selection:1;/* RW */ - unsigned long apic_mode_status:1; /* RO */ - unsigned long suppress_interrupts_to_self:1; /* RW */ - unsigned long enable_lock_based_system_flush:1;/* RW */ - unsigned long enable_extended_sb_status:1; /* RW */ - unsigned long suppress_int_prio_udt_to_self:1;/* RW */ - unsigned long use_legacy_descriptor_formats:1;/* RW */ - unsigned long suppress_quiesce_msgs_to_qpi:1; /* RW */ - unsigned long enable_intd_prefetch_hint:1; /* RW */ - unsigned long thread_kill_timebase:8; /* RW */ - unsigned long rsvd_46_47:2; - unsigned long fun:16; /* RW */ - } s3; - struct uv4h_lb_bau_misc_control_s { - unsigned long rejection_delay:8; /* RW */ - unsigned long apic_mode:1; /* RW */ - unsigned long force_broadcast:1; /* RW */ - unsigned long force_lock_nop:1; /* RW */ - unsigned long qpi_agent_presence_vector:3; /* RW */ - unsigned long descriptor_fetch_mode:1; /* RW */ - unsigned long rsvd_15_19:5; - unsigned long enable_dual_mapping_mode:1; /* RW */ - unsigned long vga_io_port_decode_enable:1; /* RW */ - unsigned long vga_io_port_16_bit_decode:1; /* RW */ - unsigned long suppress_dest_registration:1; /* RW */ - unsigned long programmed_initial_priority:3; /* RW */ - unsigned long use_incoming_priority:1; /* RW */ - unsigned long enable_programmed_initial_priority:1;/* RW */ - unsigned long enable_automatic_apic_mode_selection:1;/* RW */ - unsigned long apic_mode_status:1; /* RO */ - unsigned long suppress_interrupts_to_self:1; /* RW */ - unsigned long enable_lock_based_system_flush:1;/* RW */ - unsigned long enable_extended_sb_status:1; /* RW */ - unsigned long suppress_int_prio_udt_to_self:1;/* RW */ - unsigned long use_legacy_descriptor_formats:1;/* RW */ - unsigned long suppress_quiesce_msgs_to_qpi:1; /* RW */ - unsigned long rsvd_37:1; - unsigned long thread_kill_timebase:8; /* RW */ - unsigned long address_interleave_select:1; /* RW */ - unsigned long rsvd_47:1; - unsigned long fun:16; /* RW */ - } s4; -}; - -/* ========================================================================= */ -/* UVH_LB_BAU_SB_ACTIVATION_CONTROL */ -/* ========================================================================= */ -#define UV2H_LB_BAU_SB_ACTIVATION_CONTROL 0x320020UL -#define UV3H_LB_BAU_SB_ACTIVATION_CONTROL 0x320020UL -#define UV4H_LB_BAU_SB_ACTIVATION_CONTROL 0xc8020UL -#define UVH_LB_BAU_SB_ACTIVATION_CONTROL ( \ - is_uv2_hub() ? UV2H_LB_BAU_SB_ACTIVATION_CONTROL : \ - is_uv3_hub() ? UV3H_LB_BAU_SB_ACTIVATION_CONTROL : \ - /*is_uv4_hub*/ UV4H_LB_BAU_SB_ACTIVATION_CONTROL) - -#define UV2H_LB_BAU_SB_ACTIVATION_CONTROL_32 0x9a8 -#define UV3H_LB_BAU_SB_ACTIVATION_CONTROL_32 0x9a8 -#define UV4H_LB_BAU_SB_ACTIVATION_CONTROL_32 0x9c8 -#define UVH_LB_BAU_SB_ACTIVATION_CONTROL_32 ( \ - is_uv2_hub() ? UV2H_LB_BAU_SB_ACTIVATION_CONTROL_32 : \ - is_uv3_hub() ? UV3H_LB_BAU_SB_ACTIVATION_CONTROL_32 : \ - /*is_uv4_hub*/ UV4H_LB_BAU_SB_ACTIVATION_CONTROL_32) - -#define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_SHFT 0 -#define UVH_LB_BAU_SB_ACTIVATION_CONTROL_PUSH_SHFT 62 -#define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INIT_SHFT 63 -#define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_MASK 0x000000000000003fUL -#define UVH_LB_BAU_SB_ACTIVATION_CONTROL_PUSH_MASK 0x4000000000000000UL -#define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INIT_MASK 0x8000000000000000UL - - -union uvh_lb_bau_sb_activation_control_u { - unsigned long v; - struct uvh_lb_bau_sb_activation_control_s { - unsigned long index:6; /* RW */ - unsigned long rsvd_6_61:56; - unsigned long push:1; /* WP */ - unsigned long init:1; /* WP */ - } s; -}; - -/* ========================================================================= */ -/* UVH_LB_BAU_SB_ACTIVATION_STATUS_0 */ -/* ========================================================================= */ -#define UV2H_LB_BAU_SB_ACTIVATION_STATUS_0 0x320030UL -#define UV3H_LB_BAU_SB_ACTIVATION_STATUS_0 0x320030UL -#define UV4H_LB_BAU_SB_ACTIVATION_STATUS_0 0xc8030UL -#define UVH_LB_BAU_SB_ACTIVATION_STATUS_0 ( \ - is_uv2_hub() ? UV2H_LB_BAU_SB_ACTIVATION_STATUS_0 : \ - is_uv3_hub() ? UV3H_LB_BAU_SB_ACTIVATION_STATUS_0 : \ - /*is_uv4_hub*/ UV4H_LB_BAU_SB_ACTIVATION_STATUS_0) - -#define UV2H_LB_BAU_SB_ACTIVATION_STATUS_0_32 0x9b0 -#define UV3H_LB_BAU_SB_ACTIVATION_STATUS_0_32 0x9b0 -#define UV4H_LB_BAU_SB_ACTIVATION_STATUS_0_32 0x9d0 -#define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_32 ( \ - is_uv2_hub() ? UV2H_LB_BAU_SB_ACTIVATION_STATUS_0_32 : \ - is_uv3_hub() ? UV3H_LB_BAU_SB_ACTIVATION_STATUS_0_32 : \ - /*is_uv4_hub*/ UV4H_LB_BAU_SB_ACTIVATION_STATUS_0_32) - -#define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_SHFT 0 -#define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_MASK 0xffffffffffffffffUL - - -union uvh_lb_bau_sb_activation_status_0_u { - unsigned long v; - struct uvh_lb_bau_sb_activation_status_0_s { - unsigned long status:64; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_LB_BAU_SB_ACTIVATION_STATUS_1 */ -/* ========================================================================= */ -#define UV2H_LB_BAU_SB_ACTIVATION_STATUS_1 0x320040UL -#define UV3H_LB_BAU_SB_ACTIVATION_STATUS_1 0x320040UL -#define UV4H_LB_BAU_SB_ACTIVATION_STATUS_1 0xc8040UL -#define UVH_LB_BAU_SB_ACTIVATION_STATUS_1 ( \ - is_uv2_hub() ? UV2H_LB_BAU_SB_ACTIVATION_STATUS_1 : \ - is_uv3_hub() ? UV3H_LB_BAU_SB_ACTIVATION_STATUS_1 : \ - /*is_uv4_hub*/ UV4H_LB_BAU_SB_ACTIVATION_STATUS_1) - -#define UV2H_LB_BAU_SB_ACTIVATION_STATUS_1_32 0x9b8 -#define UV3H_LB_BAU_SB_ACTIVATION_STATUS_1_32 0x9b8 -#define UV4H_LB_BAU_SB_ACTIVATION_STATUS_1_32 0x9d8 -#define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_32 ( \ - is_uv2_hub() ? UV2H_LB_BAU_SB_ACTIVATION_STATUS_1_32 : \ - is_uv3_hub() ? UV3H_LB_BAU_SB_ACTIVATION_STATUS_1_32 : \ - /*is_uv4_hub*/ UV4H_LB_BAU_SB_ACTIVATION_STATUS_1_32) - -#define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_SHFT 0 -#define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_MASK 0xffffffffffffffffUL - - -union uvh_lb_bau_sb_activation_status_1_u { - unsigned long v; - struct uvh_lb_bau_sb_activation_status_1_s { - unsigned long status:64; /* RW */ - } s; }; /* ========================================================================= */ -/* UVH_LB_BAU_SB_DESCRIPTOR_BASE */ -/* ========================================================================= */ -#define UV2H_LB_BAU_SB_DESCRIPTOR_BASE 0x320010UL -#define UV3H_LB_BAU_SB_DESCRIPTOR_BASE 0x320010UL -#define UV4H_LB_BAU_SB_DESCRIPTOR_BASE 0xc8010UL -#define UVH_LB_BAU_SB_DESCRIPTOR_BASE ( \ - is_uv2_hub() ? UV2H_LB_BAU_SB_DESCRIPTOR_BASE : \ - is_uv3_hub() ? UV3H_LB_BAU_SB_DESCRIPTOR_BASE : \ - /*is_uv4_hub*/ UV4H_LB_BAU_SB_DESCRIPTOR_BASE) - -#define UV2H_LB_BAU_SB_DESCRIPTOR_BASE_32 0x9a0 -#define UV3H_LB_BAU_SB_DESCRIPTOR_BASE_32 0x9a0 -#define UV4H_LB_BAU_SB_DESCRIPTOR_BASE_32 0x9c0 -#define UVH_LB_BAU_SB_DESCRIPTOR_BASE_32 ( \ - is_uv2_hub() ? UV2H_LB_BAU_SB_DESCRIPTOR_BASE_32 : \ - is_uv3_hub() ? UV3H_LB_BAU_SB_DESCRIPTOR_BASE_32 : \ - /*is_uv4_hub*/ UV4H_LB_BAU_SB_DESCRIPTOR_BASE_32) - -#define UVH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_SHFT 12 - -#define UV2H_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_SHFT 49 -#define UV2H_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_MASK 0x000007fffffff000UL -#define UV2H_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_MASK 0x7ffe000000000000UL - -#define UV3H_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_SHFT 49 -#define UV3H_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_MASK 0x000007fffffff000UL -#define UV3H_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_MASK 0x7ffe000000000000UL - -#define UV4H_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_SHFT 49 -#define UV4H_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_MASK 0x00003ffffffff000UL -#define UV4H_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_MASK 0x7ffe000000000000UL - -#define UV4AH_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_SHFT 53 -#define UV4AH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_MASK 0x000ffffffffff000UL -#define UV4AH_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_MASK 0xffe0000000000000UL - -#define UVH_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_SHFT ( \ - is_uv2_hub() ? UV2H_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_SHFT : \ - is_uv3_hub() ? UV3H_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_SHFT : \ - is_uv4a_hub() ? UV4AH_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_SHFT : \ - /*is_uv4_hub*/ UV4H_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_SHFT) - -#define UVH_LB_BAU_SB_DESCRIPTOR_PAGE_ADDRESS_MASK ( \ - is_uv2_hub() ? UV2H_LB_BAU_SB_DESCRIPTOR_PAGE_ADDRESS_MASK : \ - is_uv3_hub() ? UV3H_LB_BAU_SB_DESCRIPTOR_PAGE_ADDRESS_MASK : \ - is_uv4a_hub() ? UV4AH_LB_BAU_SB_DESCRIPTOR_PAGE_ADDRESS_MASK : \ - /*is_uv4_hub*/ UV4H_LB_BAU_SB_DESCRIPTOR_PAGE_ADDRESS_MASK) - -#define UVH_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_MASK ( \ - is_uv2_hub() ? UV2H_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_MASK : \ - is_uv3_hub() ? UV3H_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_MASK : \ - is_uv4a_hub() ? UV4AH_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_MASK : \ - /*is_uv4_hub*/ UV4H_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_MASK) - -/* ========================================================================= */ /* UVH_NODE_ID */ /* ========================================================================= */ #define UVH_NODE_ID 0x0UL -#define UV2H_NODE_ID 0x0UL -#define UV3H_NODE_ID 0x0UL -#define UV4H_NODE_ID 0x0UL +/* UVH common defines*/ #define UVH_NODE_ID_FORCE1_SHFT 0 -#define UVH_NODE_ID_MANUFACTURER_SHFT 1 -#define UVH_NODE_ID_PART_NUMBER_SHFT 12 -#define UVH_NODE_ID_REVISION_SHFT 28 -#define UVH_NODE_ID_NODE_ID_SHFT 32 #define UVH_NODE_ID_FORCE1_MASK 0x0000000000000001UL +#define UVH_NODE_ID_MANUFACTURER_SHFT 1 #define UVH_NODE_ID_MANUFACTURER_MASK 0x0000000000000ffeUL +#define UVH_NODE_ID_PART_NUMBER_SHFT 12 #define UVH_NODE_ID_PART_NUMBER_MASK 0x000000000ffff000UL +#define UVH_NODE_ID_REVISION_SHFT 28 #define UVH_NODE_ID_REVISION_MASK 0x00000000f0000000UL -#define UVH_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL +#define UVH_NODE_ID_NODE_ID_SHFT 32 +#define UVH_NODE_ID_NI_PORT_SHFT 57 -#define UVXH_NODE_ID_FORCE1_SHFT 0 -#define UVXH_NODE_ID_MANUFACTURER_SHFT 1 -#define UVXH_NODE_ID_PART_NUMBER_SHFT 12 -#define UVXH_NODE_ID_REVISION_SHFT 28 -#define UVXH_NODE_ID_NODE_ID_SHFT 32 -#define UVXH_NODE_ID_NODES_PER_BIT_SHFT 50 -#define UVXH_NODE_ID_NI_PORT_SHFT 57 -#define UVXH_NODE_ID_FORCE1_MASK 0x0000000000000001UL -#define UVXH_NODE_ID_MANUFACTURER_MASK 0x0000000000000ffeUL -#define UVXH_NODE_ID_PART_NUMBER_MASK 0x000000000ffff000UL -#define UVXH_NODE_ID_REVISION_MASK 0x00000000f0000000UL +/* UVXH common defines */ #define UVXH_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL +#define UVXH_NODE_ID_NODES_PER_BIT_SHFT 50 #define UVXH_NODE_ID_NODES_PER_BIT_MASK 0x01fc000000000000UL #define UVXH_NODE_ID_NI_PORT_MASK 0x3e00000000000000UL -#define UV2H_NODE_ID_FORCE1_SHFT 0 -#define UV2H_NODE_ID_MANUFACTURER_SHFT 1 -#define UV2H_NODE_ID_PART_NUMBER_SHFT 12 -#define UV2H_NODE_ID_REVISION_SHFT 28 -#define UV2H_NODE_ID_NODE_ID_SHFT 32 -#define UV2H_NODE_ID_NODES_PER_BIT_SHFT 50 -#define UV2H_NODE_ID_NI_PORT_SHFT 57 -#define UV2H_NODE_ID_FORCE1_MASK 0x0000000000000001UL -#define UV2H_NODE_ID_MANUFACTURER_MASK 0x0000000000000ffeUL -#define UV2H_NODE_ID_PART_NUMBER_MASK 0x000000000ffff000UL -#define UV2H_NODE_ID_REVISION_MASK 0x00000000f0000000UL -#define UV2H_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL -#define UV2H_NODE_ID_NODES_PER_BIT_MASK 0x01fc000000000000UL -#define UV2H_NODE_ID_NI_PORT_MASK 0x3e00000000000000UL - -#define UV3H_NODE_ID_FORCE1_SHFT 0 -#define UV3H_NODE_ID_MANUFACTURER_SHFT 1 -#define UV3H_NODE_ID_PART_NUMBER_SHFT 12 -#define UV3H_NODE_ID_REVISION_SHFT 28 -#define UV3H_NODE_ID_NODE_ID_SHFT 32 -#define UV3H_NODE_ID_ROUTER_SELECT_SHFT 48 -#define UV3H_NODE_ID_RESERVED_2_SHFT 49 -#define UV3H_NODE_ID_NODES_PER_BIT_SHFT 50 -#define UV3H_NODE_ID_NI_PORT_SHFT 57 -#define UV3H_NODE_ID_FORCE1_MASK 0x0000000000000001UL -#define UV3H_NODE_ID_MANUFACTURER_MASK 0x0000000000000ffeUL -#define UV3H_NODE_ID_PART_NUMBER_MASK 0x000000000ffff000UL -#define UV3H_NODE_ID_REVISION_MASK 0x00000000f0000000UL -#define UV3H_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL -#define UV3H_NODE_ID_ROUTER_SELECT_MASK 0x0001000000000000UL -#define UV3H_NODE_ID_RESERVED_2_MASK 0x0002000000000000UL -#define UV3H_NODE_ID_NODES_PER_BIT_MASK 0x01fc000000000000UL -#define UV3H_NODE_ID_NI_PORT_MASK 0x3e00000000000000UL - -#define UV4H_NODE_ID_FORCE1_SHFT 0 -#define UV4H_NODE_ID_MANUFACTURER_SHFT 1 -#define UV4H_NODE_ID_PART_NUMBER_SHFT 12 -#define UV4H_NODE_ID_REVISION_SHFT 28 -#define UV4H_NODE_ID_NODE_ID_SHFT 32 +/* UVYH common defines */ +#define UVYH_NODE_ID_NODE_ID_MASK 0x0000007f00000000UL +#define UVYH_NODE_ID_NI_PORT_MASK 0x7e00000000000000UL + +/* UV4 unique defines */ #define UV4H_NODE_ID_ROUTER_SELECT_SHFT 48 -#define UV4H_NODE_ID_RESERVED_2_SHFT 49 -#define UV4H_NODE_ID_NODES_PER_BIT_SHFT 50 -#define UV4H_NODE_ID_NI_PORT_SHFT 57 -#define UV4H_NODE_ID_FORCE1_MASK 0x0000000000000001UL -#define UV4H_NODE_ID_MANUFACTURER_MASK 0x0000000000000ffeUL -#define UV4H_NODE_ID_PART_NUMBER_MASK 0x000000000ffff000UL -#define UV4H_NODE_ID_REVISION_MASK 0x00000000f0000000UL -#define UV4H_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL #define UV4H_NODE_ID_ROUTER_SELECT_MASK 0x0001000000000000UL +#define UV4H_NODE_ID_RESERVED_2_SHFT 49 #define UV4H_NODE_ID_RESERVED_2_MASK 0x0002000000000000UL -#define UV4H_NODE_ID_NODES_PER_BIT_MASK 0x01fc000000000000UL -#define UV4H_NODE_ID_NI_PORT_MASK 0x3e00000000000000UL + +/* UV3 unique defines */ +#define UV3H_NODE_ID_ROUTER_SELECT_SHFT 48 +#define UV3H_NODE_ID_ROUTER_SELECT_MASK 0x0001000000000000UL +#define UV3H_NODE_ID_RESERVED_2_SHFT 49 +#define UV3H_NODE_ID_RESERVED_2_MASK 0x0002000000000000UL union uvh_node_id_u { unsigned long v; + + /* UVH common struct */ struct uvh_node_id_s { unsigned long force1:1; /* RO */ unsigned long manufacturer:11; /* RO */ unsigned long part_number:16; /* RO */ unsigned long revision:4; /* RO */ - unsigned long node_id:15; /* RW */ - unsigned long rsvd_47_63:17; + unsigned long rsvd_32_63:32; } s; + + /* UVXH common struct */ struct uvxh_node_id_s { unsigned long force1:1; /* RO */ unsigned long manufacturer:11; /* RO */ @@ -2444,17 +2841,47 @@ union uvh_node_id_u { unsigned long ni_port:5; /* RO */ unsigned long rsvd_62_63:2; } sx; - struct uv2h_node_id_s { + + /* UVYH common struct */ + struct uvyh_node_id_s { + unsigned long force1:1; /* RO */ + unsigned long manufacturer:11; /* RO */ + unsigned long part_number:16; /* RO */ + unsigned long revision:4; /* RO */ + unsigned long node_id:7; /* RW */ + unsigned long rsvd_39_56:18; + unsigned long ni_port:6; /* RO */ + unsigned long rsvd_63:1; + } sy; + + /* UV5 unique struct */ + struct uv5h_node_id_s { + unsigned long force1:1; /* RO */ + unsigned long manufacturer:11; /* RO */ + unsigned long part_number:16; /* RO */ + unsigned long revision:4; /* RO */ + unsigned long node_id:7; /* RW */ + unsigned long rsvd_39_56:18; + unsigned long ni_port:6; /* RO */ + unsigned long rsvd_63:1; + } s5; + + /* UV4 unique struct */ + struct uv4h_node_id_s { unsigned long force1:1; /* RO */ unsigned long manufacturer:11; /* RO */ unsigned long part_number:16; /* RO */ unsigned long revision:4; /* RO */ unsigned long node_id:15; /* RW */ - unsigned long rsvd_47_49:3; + unsigned long rsvd_47:1; + unsigned long router_select:1; /* RO */ + unsigned long rsvd_49:1; unsigned long nodes_per_bit:7; /* RO */ unsigned long ni_port:5; /* RO */ unsigned long rsvd_62_63:2; - } s2; + } s4; + + /* UV3 unique struct */ struct uv3h_node_id_s { unsigned long force1:1; /* RO */ unsigned long manufacturer:11; /* RO */ @@ -2468,186 +2895,569 @@ union uvh_node_id_u { unsigned long ni_port:5; /* RO */ unsigned long rsvd_62_63:2; } s3; - struct uv4h_node_id_s { + + /* UV2 unique struct */ + struct uv2h_node_id_s { unsigned long force1:1; /* RO */ unsigned long manufacturer:11; /* RO */ unsigned long part_number:16; /* RO */ unsigned long revision:4; /* RO */ unsigned long node_id:15; /* RW */ - unsigned long rsvd_47:1; - unsigned long router_select:1; /* RO */ - unsigned long rsvd_49:1; + unsigned long rsvd_47_49:3; unsigned long nodes_per_bit:7; /* RO */ unsigned long ni_port:5; /* RO */ unsigned long rsvd_62_63:2; - } s4; + } s2; +}; + +/* ========================================================================= */ +/* UVH_NODE_PRESENT_0 */ +/* ========================================================================= */ +#define UVH_NODE_PRESENT_0 ( \ + is_uv(UV5) ? 0x1400UL : \ + 0) + + +/* UVYH common defines */ +#define UVYH_NODE_PRESENT_0_NODES_SHFT 0 +#define UVYH_NODE_PRESENT_0_NODES_MASK 0xffffffffffffffffUL + + +union uvh_node_present_0_u { + unsigned long v; + + /* UVH common struct */ + struct uvh_node_present_0_s { + unsigned long nodes:64; /* RW */ + } s; + + /* UVYH common struct */ + struct uvyh_node_present_0_s { + unsigned long nodes:64; /* RW */ + } sy; + + /* UV5 unique struct */ + struct uv5h_node_present_0_s { + unsigned long nodes:64; /* RW */ + } s5; +}; + +/* ========================================================================= */ +/* UVH_NODE_PRESENT_1 */ +/* ========================================================================= */ +#define UVH_NODE_PRESENT_1 ( \ + is_uv(UV5) ? 0x1408UL : \ + 0) + + +/* UVYH common defines */ +#define UVYH_NODE_PRESENT_1_NODES_SHFT 0 +#define UVYH_NODE_PRESENT_1_NODES_MASK 0xffffffffffffffffUL + + +union uvh_node_present_1_u { + unsigned long v; + + /* UVH common struct */ + struct uvh_node_present_1_s { + unsigned long nodes:64; /* RW */ + } s; + + /* UVYH common struct */ + struct uvyh_node_present_1_s { + unsigned long nodes:64; /* RW */ + } sy; + + /* UV5 unique struct */ + struct uv5h_node_present_1_s { + unsigned long nodes:64; /* RW */ + } s5; }; /* ========================================================================= */ /* UVH_NODE_PRESENT_TABLE */ /* ========================================================================= */ -#define UVH_NODE_PRESENT_TABLE 0x1400UL +#define UVH_NODE_PRESENT_TABLE ( \ + is_uv(UV4) ? 0x1400UL : \ + is_uv(UV3) ? 0x1400UL : \ + is_uv(UV2) ? 0x1400UL : \ + 0) -#define UV2H_NODE_PRESENT_TABLE_DEPTH 16 -#define UV3H_NODE_PRESENT_TABLE_DEPTH 16 -#define UV4H_NODE_PRESENT_TABLE_DEPTH 4 #define UVH_NODE_PRESENT_TABLE_DEPTH ( \ - is_uv2_hub() ? UV2H_NODE_PRESENT_TABLE_DEPTH : \ - is_uv3_hub() ? UV3H_NODE_PRESENT_TABLE_DEPTH : \ - /*is_uv4_hub*/ UV4H_NODE_PRESENT_TABLE_DEPTH) + is_uv(UV4) ? 4 : \ + is_uv(UV3) ? 16 : \ + is_uv(UV2) ? 16 : \ + 0) -#define UVH_NODE_PRESENT_TABLE_NODES_SHFT 0 -#define UVH_NODE_PRESENT_TABLE_NODES_MASK 0xffffffffffffffffUL + +/* UVXH common defines */ +#define UVXH_NODE_PRESENT_TABLE_NODES_SHFT 0 +#define UVXH_NODE_PRESENT_TABLE_NODES_MASK 0xffffffffffffffffUL union uvh_node_present_table_u { unsigned long v; + + /* UVH common struct */ struct uvh_node_present_table_s { unsigned long nodes:64; /* RW */ } s; + + /* UVXH common struct */ + struct uvxh_node_present_table_s { + unsigned long nodes:64; /* RW */ + } sx; + + /* UV4 unique struct */ + struct uv4h_node_present_table_s { + unsigned long nodes:64; /* RW */ + } s4; + + /* UV3 unique struct */ + struct uv3h_node_present_table_s { + unsigned long nodes:64; /* RW */ + } s3; + + /* UV2 unique struct */ + struct uv2h_node_present_table_s { + unsigned long nodes:64; /* RW */ + } s2; +}; + +/* ========================================================================= */ +/* UVH_RH10_GAM_ADDR_MAP_CONFIG */ +/* ========================================================================= */ +#define UVH_RH10_GAM_ADDR_MAP_CONFIG ( \ + is_uv(UV5) ? 0x470000UL : \ + 0) + + +/* UVYH common defines */ +#define UVYH_RH10_GAM_ADDR_MAP_CONFIG_N_SKT_SHFT 6 +#define UVYH_RH10_GAM_ADDR_MAP_CONFIG_N_SKT_MASK 0x00000000000001c0UL +#define UVYH_RH10_GAM_ADDR_MAP_CONFIG_LS_ENABLE_SHFT 12 +#define UVYH_RH10_GAM_ADDR_MAP_CONFIG_LS_ENABLE_MASK 0x0000000000001000UL +#define UVYH_RH10_GAM_ADDR_MAP_CONFIG_MK_TME_KEYID_BITS_SHFT 16 +#define UVYH_RH10_GAM_ADDR_MAP_CONFIG_MK_TME_KEYID_BITS_MASK 0x00000000000f0000UL + + +union uvh_rh10_gam_addr_map_config_u { + unsigned long v; + + /* UVH common struct */ + struct uvh_rh10_gam_addr_map_config_s { + unsigned long undef_0_5:6; /* Undefined */ + unsigned long n_skt:3; /* RW */ + unsigned long undef_9_11:3; /* Undefined */ + unsigned long ls_enable:1; /* RW */ + unsigned long undef_13_15:3; /* Undefined */ + unsigned long mk_tme_keyid_bits:4; /* RW */ + unsigned long rsvd_20_63:44; + } s; + + /* UVYH common struct */ + struct uvyh_rh10_gam_addr_map_config_s { + unsigned long undef_0_5:6; /* Undefined */ + unsigned long n_skt:3; /* RW */ + unsigned long undef_9_11:3; /* Undefined */ + unsigned long ls_enable:1; /* RW */ + unsigned long undef_13_15:3; /* Undefined */ + unsigned long mk_tme_keyid_bits:4; /* RW */ + unsigned long rsvd_20_63:44; + } sy; + + /* UV5 unique struct */ + struct uv5h_rh10_gam_addr_map_config_s { + unsigned long undef_0_5:6; /* Undefined */ + unsigned long n_skt:3; /* RW */ + unsigned long undef_9_11:3; /* Undefined */ + unsigned long ls_enable:1; /* RW */ + unsigned long undef_13_15:3; /* Undefined */ + unsigned long mk_tme_keyid_bits:4; /* RW */ + } s5; }; /* ========================================================================= */ -/* UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR */ +/* UVH_RH10_GAM_GRU_OVERLAY_CONFIG */ /* ========================================================================= */ -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR 0x16000c8UL -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR 0x16000c8UL -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR 0x4800c8UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR) - -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_SHFT 24 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_SHFT 48 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_MASK 0x00000000ff000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_SHFT 24 -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_SHFT 48 -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_SHFT 63 -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_MASK 0x00000000ff000000UL -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_SHFT 24 -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_SHFT 48 -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_SHFT 63 -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_MASK 0x00000000ff000000UL -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_SHFT 24 -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_SHFT 48 -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_SHFT 63 -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_MASK 0x00000000ff000000UL -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_SHFT 24 -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_SHFT 48 -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_SHFT 63 -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_MASK 0x00000000ff000000UL -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_MASK 0x8000000000000000UL - - -union uvh_rh_gam_alias210_overlay_config_0_mmr_u { +#define UVH_RH10_GAM_GRU_OVERLAY_CONFIG ( \ + is_uv(UV5) ? 0x4700b0UL : \ + 0) + + +/* UVYH common defines */ +#define UVYH_RH10_GAM_GRU_OVERLAY_CONFIG_BASE_SHFT 25 +#define UVYH_RH10_GAM_GRU_OVERLAY_CONFIG_BASE_MASK 0x000ffffffe000000UL +#define UVYH_RH10_GAM_GRU_OVERLAY_CONFIG_N_GRU_SHFT 52 +#define UVYH_RH10_GAM_GRU_OVERLAY_CONFIG_N_GRU_MASK 0x0070000000000000UL +#define UVYH_RH10_GAM_GRU_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVYH_RH10_GAM_GRU_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +#define UVH_RH10_GAM_GRU_OVERLAY_CONFIG_BASE_MASK ( \ + is_uv(UV5) ? 0x000ffffffe000000UL : \ + 0) +#define UVH_RH10_GAM_GRU_OVERLAY_CONFIG_BASE_SHFT ( \ + is_uv(UV5) ? 25 : \ + -1) + +union uvh_rh10_gam_gru_overlay_config_u { unsigned long v; - struct uvh_rh_gam_alias210_overlay_config_0_mmr_s { - unsigned long rsvd_0_23:24; - unsigned long base:8; /* RW */ - unsigned long rsvd_32_47:16; - unsigned long m_alias:5; /* RW */ - unsigned long rsvd_53_62:10; + + /* UVH common struct */ + struct uvh_rh10_gam_gru_overlay_config_s { + unsigned long undef_0_24:25; /* Undefined */ + unsigned long base:27; /* RW */ + unsigned long n_gru:3; /* RW */ + unsigned long undef_55_62:8; /* Undefined */ unsigned long enable:1; /* RW */ } s; - struct uvxh_rh_gam_alias210_overlay_config_0_mmr_s { - unsigned long rsvd_0_23:24; - unsigned long base:8; /* RW */ - unsigned long rsvd_32_47:16; - unsigned long m_alias:5; /* RW */ - unsigned long rsvd_53_62:10; + + /* UVYH common struct */ + struct uvyh_rh10_gam_gru_overlay_config_s { + unsigned long undef_0_24:25; /* Undefined */ + unsigned long base:27; /* RW */ + unsigned long n_gru:3; /* RW */ + unsigned long undef_55_62:8; /* Undefined */ unsigned long enable:1; /* RW */ - } sx; - struct uv2h_rh_gam_alias210_overlay_config_0_mmr_s { - unsigned long rsvd_0_23:24; - unsigned long base:8; /* RW */ - unsigned long rsvd_32_47:16; - unsigned long m_alias:5; /* RW */ - unsigned long rsvd_53_62:10; + } sy; + + /* UV5 unique struct */ + struct uv5h_rh10_gam_gru_overlay_config_s { + unsigned long undef_0_24:25; /* Undefined */ + unsigned long base:27; /* RW */ + unsigned long n_gru:3; /* RW */ + unsigned long undef_55_62:8; /* Undefined */ unsigned long enable:1; /* RW */ - } s2; - struct uv3h_rh_gam_alias210_overlay_config_0_mmr_s { - unsigned long rsvd_0_23:24; - unsigned long base:8; /* RW */ - unsigned long rsvd_32_47:16; - unsigned long m_alias:5; /* RW */ - unsigned long rsvd_53_62:10; + } s5; +}; + +/* ========================================================================= */ +/* UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG0 */ +/* ========================================================================= */ +#define UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG0 ( \ + is_uv(UV5) ? 0x473000UL : \ + 0) + + +/* UVYH common defines */ +#define UVYH_RH10_GAM_MMIOH_OVERLAY_CONFIG0_BASE_SHFT 26 +#define UVYH_RH10_GAM_MMIOH_OVERLAY_CONFIG0_BASE_MASK 0x000ffffffc000000UL +#define UVYH_RH10_GAM_MMIOH_OVERLAY_CONFIG0_M_IO_SHFT 52 +#define UVYH_RH10_GAM_MMIOH_OVERLAY_CONFIG0_M_IO_MASK 0x03f0000000000000UL +#define UVYH_RH10_GAM_MMIOH_OVERLAY_CONFIG0_ENABLE_SHFT 63 +#define UVYH_RH10_GAM_MMIOH_OVERLAY_CONFIG0_ENABLE_MASK 0x8000000000000000UL + +#define UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG0_BASE_MASK ( \ + is_uv(UV5) ? 0x000ffffffc000000UL : \ + 0) +#define UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG0_BASE_SHFT ( \ + is_uv(UV5) ? 26 : \ + -1) + +union uvh_rh10_gam_mmioh_overlay_config0_u { + unsigned long v; + + /* UVH common struct */ + struct uvh_rh10_gam_mmioh_overlay_config0_s { + unsigned long rsvd_0_25:26; + unsigned long base:26; /* RW */ + unsigned long m_io:6; /* RW */ + unsigned long n_io:4; + unsigned long undef_62:1; /* Undefined */ unsigned long enable:1; /* RW */ - } s3; - struct uv4h_rh_gam_alias210_overlay_config_0_mmr_s { - unsigned long rsvd_0_23:24; - unsigned long base:8; /* RW */ - unsigned long rsvd_32_47:16; - unsigned long m_alias:5; /* RW */ - unsigned long rsvd_53_62:10; + } s; + + /* UVYH common struct */ + struct uvyh_rh10_gam_mmioh_overlay_config0_s { + unsigned long rsvd_0_25:26; + unsigned long base:26; /* RW */ + unsigned long m_io:6; /* RW */ + unsigned long n_io:4; + unsigned long undef_62:1; /* Undefined */ unsigned long enable:1; /* RW */ + } sy; + + /* UV5 unique struct */ + struct uv5h_rh10_gam_mmioh_overlay_config0_s { + unsigned long rsvd_0_25:26; + unsigned long base:26; /* RW */ + unsigned long m_io:6; /* RW */ + unsigned long n_io:4; + unsigned long undef_62:1; /* Undefined */ + unsigned long enable:1; /* RW */ + } s5; +}; + +/* ========================================================================= */ +/* UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG1 */ +/* ========================================================================= */ +#define UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG1 ( \ + is_uv(UV5) ? 0x474000UL : \ + 0) + + +/* UVYH common defines */ +#define UVYH_RH10_GAM_MMIOH_OVERLAY_CONFIG1_BASE_SHFT 26 +#define UVYH_RH10_GAM_MMIOH_OVERLAY_CONFIG1_BASE_MASK 0x000ffffffc000000UL +#define UVYH_RH10_GAM_MMIOH_OVERLAY_CONFIG1_M_IO_SHFT 52 +#define UVYH_RH10_GAM_MMIOH_OVERLAY_CONFIG1_M_IO_MASK 0x03f0000000000000UL +#define UVYH_RH10_GAM_MMIOH_OVERLAY_CONFIG1_ENABLE_SHFT 63 +#define UVYH_RH10_GAM_MMIOH_OVERLAY_CONFIG1_ENABLE_MASK 0x8000000000000000UL + +#define UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG1_BASE_MASK ( \ + is_uv(UV5) ? 0x000ffffffc000000UL : \ + 0) +#define UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG1_BASE_SHFT ( \ + is_uv(UV5) ? 26 : \ + -1) + +union uvh_rh10_gam_mmioh_overlay_config1_u { + unsigned long v; + + /* UVH common struct */ + struct uvh_rh10_gam_mmioh_overlay_config1_s { + unsigned long rsvd_0_25:26; + unsigned long base:26; /* RW */ + unsigned long m_io:6; /* RW */ + unsigned long n_io:4; + unsigned long undef_62:1; /* Undefined */ + unsigned long enable:1; /* RW */ + } s; + + /* UVYH common struct */ + struct uvyh_rh10_gam_mmioh_overlay_config1_s { + unsigned long rsvd_0_25:26; + unsigned long base:26; /* RW */ + unsigned long m_io:6; /* RW */ + unsigned long n_io:4; + unsigned long undef_62:1; /* Undefined */ + unsigned long enable:1; /* RW */ + } sy; + + /* UV5 unique struct */ + struct uv5h_rh10_gam_mmioh_overlay_config1_s { + unsigned long rsvd_0_25:26; + unsigned long base:26; /* RW */ + unsigned long m_io:6; /* RW */ + unsigned long n_io:4; + unsigned long undef_62:1; /* Undefined */ + unsigned long enable:1; /* RW */ + } s5; +}; + +/* ========================================================================= */ +/* UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG0 */ +/* ========================================================================= */ +#define UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG0 ( \ + is_uv(UV5) ? 0x473800UL : \ + 0) + +#define UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG0_DEPTH ( \ + is_uv(UV5) ? 128 : \ + 0) + + +/* UVYH common defines */ +#define UVYH_RH10_GAM_MMIOH_REDIRECT_CONFIG0_NASID_SHFT 0 +#define UVYH_RH10_GAM_MMIOH_REDIRECT_CONFIG0_NASID_MASK 0x000000000000007fUL + + +union uvh_rh10_gam_mmioh_redirect_config0_u { + unsigned long v; + + /* UVH common struct */ + struct uvh_rh10_gam_mmioh_redirect_config0_s { + unsigned long nasid:7; /* RW */ + unsigned long rsvd_7_63:57; + } s; + + /* UVYH common struct */ + struct uvyh_rh10_gam_mmioh_redirect_config0_s { + unsigned long nasid:7; /* RW */ + unsigned long rsvd_7_63:57; + } sy; + + /* UV5 unique struct */ + struct uv5h_rh10_gam_mmioh_redirect_config0_s { + unsigned long nasid:7; /* RW */ + unsigned long rsvd_7_63:57; + } s5; +}; + +/* ========================================================================= */ +/* UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG1 */ +/* ========================================================================= */ +#define UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG1 ( \ + is_uv(UV5) ? 0x474800UL : \ + 0) + +#define UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG1_DEPTH ( \ + is_uv(UV5) ? 128 : \ + 0) + + +/* UVYH common defines */ +#define UVYH_RH10_GAM_MMIOH_REDIRECT_CONFIG1_NASID_SHFT 0 +#define UVYH_RH10_GAM_MMIOH_REDIRECT_CONFIG1_NASID_MASK 0x000000000000007fUL + + +union uvh_rh10_gam_mmioh_redirect_config1_u { + unsigned long v; + + /* UVH common struct */ + struct uvh_rh10_gam_mmioh_redirect_config1_s { + unsigned long nasid:7; /* RW */ + unsigned long rsvd_7_63:57; + } s; + + /* UVYH common struct */ + struct uvyh_rh10_gam_mmioh_redirect_config1_s { + unsigned long nasid:7; /* RW */ + unsigned long rsvd_7_63:57; + } sy; + + /* UV5 unique struct */ + struct uv5h_rh10_gam_mmioh_redirect_config1_s { + unsigned long nasid:7; /* RW */ + unsigned long rsvd_7_63:57; + } s5; +}; + +/* ========================================================================= */ +/* UVH_RH10_GAM_MMR_OVERLAY_CONFIG */ +/* ========================================================================= */ +#define UVH_RH10_GAM_MMR_OVERLAY_CONFIG ( \ + is_uv(UV5) ? 0x470090UL : \ + 0) + + +/* UVYH common defines */ +#define UVYH_RH10_GAM_MMR_OVERLAY_CONFIG_BASE_SHFT 25 +#define UVYH_RH10_GAM_MMR_OVERLAY_CONFIG_BASE_MASK 0x000ffffffe000000UL +#define UVYH_RH10_GAM_MMR_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVYH_RH10_GAM_MMR_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +#define UVH_RH10_GAM_MMR_OVERLAY_CONFIG_BASE_MASK ( \ + is_uv(UV5) ? 0x000ffffffe000000UL : \ + 0) +#define UVH_RH10_GAM_MMR_OVERLAY_CONFIG_BASE_SHFT ( \ + is_uv(UV5) ? 25 : \ + -1) + +union uvh_rh10_gam_mmr_overlay_config_u { + unsigned long v; + + /* UVH common struct */ + struct uvh_rh10_gam_mmr_overlay_config_s { + unsigned long undef_0_24:25; /* Undefined */ + unsigned long base:27; /* RW */ + unsigned long undef_52_62:11; /* Undefined */ + unsigned long enable:1; /* RW */ + } s; + + /* UVYH common struct */ + struct uvyh_rh10_gam_mmr_overlay_config_s { + unsigned long undef_0_24:25; /* Undefined */ + unsigned long base:27; /* RW */ + unsigned long undef_52_62:11; /* Undefined */ + unsigned long enable:1; /* RW */ + } sy; + + /* UV5 unique struct */ + struct uv5h_rh10_gam_mmr_overlay_config_s { + unsigned long undef_0_24:25; /* Undefined */ + unsigned long base:27; /* RW */ + unsigned long undef_52_62:11; /* Undefined */ + unsigned long enable:1; /* RW */ + } s5; +}; + +/* ========================================================================= */ +/* UVH_RH_GAM_ADDR_MAP_CONFIG */ +/* ========================================================================= */ +#define UVH_RH_GAM_ADDR_MAP_CONFIG ( \ + is_uv(UV4) ? 0x480000UL : \ + is_uv(UV3) ? 0x1600000UL : \ + is_uv(UV2) ? 0x1600000UL : \ + 0) + + +/* UVXH common defines */ +#define UVXH_RH_GAM_ADDR_MAP_CONFIG_N_SKT_SHFT 6 +#define UVXH_RH_GAM_ADDR_MAP_CONFIG_N_SKT_MASK 0x00000000000003c0UL + +/* UV3 unique defines */ +#define UV3H_RH_GAM_ADDR_MAP_CONFIG_M_SKT_SHFT 0 +#define UV3H_RH_GAM_ADDR_MAP_CONFIG_M_SKT_MASK 0x000000000000003fUL + +/* UV2 unique defines */ +#define UV2H_RH_GAM_ADDR_MAP_CONFIG_M_SKT_SHFT 0 +#define UV2H_RH_GAM_ADDR_MAP_CONFIG_M_SKT_MASK 0x000000000000003fUL + + +union uvh_rh_gam_addr_map_config_u { + unsigned long v; + + /* UVH common struct */ + struct uvh_rh_gam_addr_map_config_s { + unsigned long rsvd_0_5:6; + unsigned long n_skt:4; /* RW */ + unsigned long rsvd_10_63:54; + } s; + + /* UVXH common struct */ + struct uvxh_rh_gam_addr_map_config_s { + unsigned long rsvd_0_5:6; + unsigned long n_skt:4; /* RW */ + unsigned long rsvd_10_63:54; + } sx; + + /* UV4 unique struct */ + struct uv4h_rh_gam_addr_map_config_s { + unsigned long rsvd_0_5:6; + unsigned long n_skt:4; /* RW */ + unsigned long rsvd_10_63:54; } s4; + + /* UV3 unique struct */ + struct uv3h_rh_gam_addr_map_config_s { + unsigned long m_skt:6; /* RW */ + unsigned long n_skt:4; /* RW */ + unsigned long rsvd_10_63:54; + } s3; + + /* UV2 unique struct */ + struct uv2h_rh_gam_addr_map_config_s { + unsigned long m_skt:6; /* RW */ + unsigned long n_skt:4; /* RW */ + unsigned long rsvd_10_63:54; + } s2; }; /* ========================================================================= */ -/* UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR */ +/* UVH_RH_GAM_ALIAS_0_OVERLAY_CONFIG */ /* ========================================================================= */ -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR 0x16000d8UL -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR 0x16000d8UL -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR 0x4800d8UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR) - -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_SHFT 24 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_SHFT 48 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_MASK 0x00000000ff000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_SHFT 24 -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_SHFT 48 -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_SHFT 63 -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_MASK 0x00000000ff000000UL -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_SHFT 24 -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_SHFT 48 -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_SHFT 63 -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_MASK 0x00000000ff000000UL -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_SHFT 24 -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_SHFT 48 -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_SHFT 63 -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_MASK 0x00000000ff000000UL -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_SHFT 24 -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_SHFT 48 -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_SHFT 63 -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_MASK 0x00000000ff000000UL -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_MASK 0x8000000000000000UL - - -union uvh_rh_gam_alias210_overlay_config_1_mmr_u { +#define UVH_RH_GAM_ALIAS_0_OVERLAY_CONFIG ( \ + is_uv(UV4) ? 0x4800c8UL : \ + is_uv(UV3) ? 0x16000c8UL : \ + is_uv(UV2) ? 0x16000c8UL : \ + 0) + + +/* UVXH common defines */ +#define UVXH_RH_GAM_ALIAS_0_OVERLAY_CONFIG_BASE_SHFT 24 +#define UVXH_RH_GAM_ALIAS_0_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL +#define UVXH_RH_GAM_ALIAS_0_OVERLAY_CONFIG_M_ALIAS_SHFT 48 +#define UVXH_RH_GAM_ALIAS_0_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL +#define UVXH_RH_GAM_ALIAS_0_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVXH_RH_GAM_ALIAS_0_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + + +union uvh_rh_gam_alias_0_overlay_config_u { unsigned long v; - struct uvh_rh_gam_alias210_overlay_config_1_mmr_s { + + /* UVH common struct */ + struct uvh_rh_gam_alias_0_overlay_config_s { unsigned long rsvd_0_23:24; unsigned long base:8; /* RW */ unsigned long rsvd_32_47:16; @@ -2655,7 +3465,9 @@ union uvh_rh_gam_alias210_overlay_config_1_mmr_u { unsigned long rsvd_53_62:10; unsigned long enable:1; /* RW */ } s; - struct uvxh_rh_gam_alias210_overlay_config_1_mmr_s { + + /* UVXH common struct */ + struct uvxh_rh_gam_alias_0_overlay_config_s { unsigned long rsvd_0_23:24; unsigned long base:8; /* RW */ unsigned long rsvd_32_47:16; @@ -2663,15 +3475,19 @@ union uvh_rh_gam_alias210_overlay_config_1_mmr_u { unsigned long rsvd_53_62:10; unsigned long enable:1; /* RW */ } sx; - struct uv2h_rh_gam_alias210_overlay_config_1_mmr_s { + + /* UV4 unique struct */ + struct uv4h_rh_gam_alias_0_overlay_config_s { unsigned long rsvd_0_23:24; unsigned long base:8; /* RW */ unsigned long rsvd_32_47:16; unsigned long m_alias:5; /* RW */ unsigned long rsvd_53_62:10; unsigned long enable:1; /* RW */ - } s2; - struct uv3h_rh_gam_alias210_overlay_config_1_mmr_s { + } s4; + + /* UV3 unique struct */ + struct uv3h_rh_gam_alias_0_overlay_config_s { unsigned long rsvd_0_23:24; unsigned long base:8; /* RW */ unsigned long rsvd_32_47:16; @@ -2679,66 +3495,96 @@ union uvh_rh_gam_alias210_overlay_config_1_mmr_u { unsigned long rsvd_53_62:10; unsigned long enable:1; /* RW */ } s3; - struct uv4h_rh_gam_alias210_overlay_config_1_mmr_s { + + /* UV2 unique struct */ + struct uv2h_rh_gam_alias_0_overlay_config_s { unsigned long rsvd_0_23:24; unsigned long base:8; /* RW */ unsigned long rsvd_32_47:16; unsigned long m_alias:5; /* RW */ unsigned long rsvd_53_62:10; unsigned long enable:1; /* RW */ + } s2; +}; + +/* ========================================================================= */ +/* UVH_RH_GAM_ALIAS_0_REDIRECT_CONFIG */ +/* ========================================================================= */ +#define UVH_RH_GAM_ALIAS_0_REDIRECT_CONFIG ( \ + is_uv(UV4) ? 0x4800d0UL : \ + is_uv(UV3) ? 0x16000d0UL : \ + is_uv(UV2) ? 0x16000d0UL : \ + 0) + + +/* UVXH common defines */ +#define UVXH_RH_GAM_ALIAS_0_REDIRECT_CONFIG_DEST_BASE_SHFT 24 +#define UVXH_RH_GAM_ALIAS_0_REDIRECT_CONFIG_DEST_BASE_MASK 0x00003fffff000000UL + + +union uvh_rh_gam_alias_0_redirect_config_u { + unsigned long v; + + /* UVH common struct */ + struct uvh_rh_gam_alias_0_redirect_config_s { + unsigned long rsvd_0_23:24; + unsigned long dest_base:22; /* RW */ + unsigned long rsvd_46_63:18; + } s; + + /* UVXH common struct */ + struct uvxh_rh_gam_alias_0_redirect_config_s { + unsigned long rsvd_0_23:24; + unsigned long dest_base:22; /* RW */ + unsigned long rsvd_46_63:18; + } sx; + + /* UV4 unique struct */ + struct uv4h_rh_gam_alias_0_redirect_config_s { + unsigned long rsvd_0_23:24; + unsigned long dest_base:22; /* RW */ + unsigned long rsvd_46_63:18; } s4; + + /* UV3 unique struct */ + struct uv3h_rh_gam_alias_0_redirect_config_s { + unsigned long rsvd_0_23:24; + unsigned long dest_base:22; /* RW */ + unsigned long rsvd_46_63:18; + } s3; + + /* UV2 unique struct */ + struct uv2h_rh_gam_alias_0_redirect_config_s { + unsigned long rsvd_0_23:24; + unsigned long dest_base:22; /* RW */ + unsigned long rsvd_46_63:18; + } s2; }; /* ========================================================================= */ -/* UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR */ +/* UVH_RH_GAM_ALIAS_1_OVERLAY_CONFIG */ /* ========================================================================= */ -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR 0x16000e8UL -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR 0x16000e8UL -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR 0x4800e8UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR) - -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_SHFT 24 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_SHFT 48 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_MASK 0x00000000ff000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_SHFT 24 -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_SHFT 48 -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_SHFT 63 -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_MASK 0x00000000ff000000UL -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UVXH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_SHFT 24 -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_SHFT 48 -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_SHFT 63 -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_MASK 0x00000000ff000000UL -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UV2H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_SHFT 24 -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_SHFT 48 -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_SHFT 63 -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_MASK 0x00000000ff000000UL -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UV3H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_SHFT 24 -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_SHFT 48 -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_SHFT 63 -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_MASK 0x00000000ff000000UL -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UV4H_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_MASK 0x8000000000000000UL - - -union uvh_rh_gam_alias210_overlay_config_2_mmr_u { +#define UVH_RH_GAM_ALIAS_1_OVERLAY_CONFIG ( \ + is_uv(UV4) ? 0x4800d8UL : \ + is_uv(UV3) ? 0x16000d8UL : \ + is_uv(UV2) ? 0x16000d8UL : \ + 0) + + +/* UVXH common defines */ +#define UVXH_RH_GAM_ALIAS_1_OVERLAY_CONFIG_BASE_SHFT 24 +#define UVXH_RH_GAM_ALIAS_1_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL +#define UVXH_RH_GAM_ALIAS_1_OVERLAY_CONFIG_M_ALIAS_SHFT 48 +#define UVXH_RH_GAM_ALIAS_1_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL +#define UVXH_RH_GAM_ALIAS_1_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVXH_RH_GAM_ALIAS_1_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + + +union uvh_rh_gam_alias_1_overlay_config_u { unsigned long v; - struct uvh_rh_gam_alias210_overlay_config_2_mmr_s { + + /* UVH common struct */ + struct uvh_rh_gam_alias_1_overlay_config_s { unsigned long rsvd_0_23:24; unsigned long base:8; /* RW */ unsigned long rsvd_32_47:16; @@ -2746,7 +3592,9 @@ union uvh_rh_gam_alias210_overlay_config_2_mmr_u { unsigned long rsvd_53_62:10; unsigned long enable:1; /* RW */ } s; - struct uvxh_rh_gam_alias210_overlay_config_2_mmr_s { + + /* UVXH common struct */ + struct uvxh_rh_gam_alias_1_overlay_config_s { unsigned long rsvd_0_23:24; unsigned long base:8; /* RW */ unsigned long rsvd_32_47:16; @@ -2754,15 +3602,19 @@ union uvh_rh_gam_alias210_overlay_config_2_mmr_u { unsigned long rsvd_53_62:10; unsigned long enable:1; /* RW */ } sx; - struct uv2h_rh_gam_alias210_overlay_config_2_mmr_s { + + /* UV4 unique struct */ + struct uv4h_rh_gam_alias_1_overlay_config_s { unsigned long rsvd_0_23:24; unsigned long base:8; /* RW */ unsigned long rsvd_32_47:16; unsigned long m_alias:5; /* RW */ unsigned long rsvd_53_62:10; unsigned long enable:1; /* RW */ - } s2; - struct uv3h_rh_gam_alias210_overlay_config_2_mmr_s { + } s4; + + /* UV3 unique struct */ + struct uv3h_rh_gam_alias_1_overlay_config_s { unsigned long rsvd_0_23:24; unsigned long base:8; /* RW */ unsigned long rsvd_32_47:16; @@ -2770,321 +3622,289 @@ union uvh_rh_gam_alias210_overlay_config_2_mmr_u { unsigned long rsvd_53_62:10; unsigned long enable:1; /* RW */ } s3; - struct uv4h_rh_gam_alias210_overlay_config_2_mmr_s { + + /* UV2 unique struct */ + struct uv2h_rh_gam_alias_1_overlay_config_s { unsigned long rsvd_0_23:24; unsigned long base:8; /* RW */ unsigned long rsvd_32_47:16; unsigned long m_alias:5; /* RW */ unsigned long rsvd_53_62:10; unsigned long enable:1; /* RW */ - } s4; + } s2; }; /* ========================================================================= */ -/* UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR */ +/* UVH_RH_GAM_ALIAS_1_REDIRECT_CONFIG */ /* ========================================================================= */ -#define UV2H_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR 0x16000d0UL -#define UV3H_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR 0x16000d0UL -#define UV4H_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR 0x4800d0UL -#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR) - -#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT 24 -#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_MASK 0x00003fffff000000UL - -#define UVXH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT 24 -#define UVXH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_MASK 0x00003fffff000000UL - -#define UV2H_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT 24 -#define UV2H_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_MASK 0x00003fffff000000UL +#define UVH_RH_GAM_ALIAS_1_REDIRECT_CONFIG ( \ + is_uv(UV4) ? 0x4800e0UL : \ + is_uv(UV3) ? 0x16000e0UL : \ + is_uv(UV2) ? 0x16000e0UL : \ + 0) -#define UV3H_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT 24 -#define UV3H_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_MASK 0x00003fffff000000UL -#define UV4H_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT 24 -#define UV4H_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_MASK 0x00003fffff000000UL +/* UVXH common defines */ +#define UVXH_RH_GAM_ALIAS_1_REDIRECT_CONFIG_DEST_BASE_SHFT 24 +#define UVXH_RH_GAM_ALIAS_1_REDIRECT_CONFIG_DEST_BASE_MASK 0x00003fffff000000UL -union uvh_rh_gam_alias210_redirect_config_0_mmr_u { +union uvh_rh_gam_alias_1_redirect_config_u { unsigned long v; - struct uvh_rh_gam_alias210_redirect_config_0_mmr_s { + + /* UVH common struct */ + struct uvh_rh_gam_alias_1_redirect_config_s { unsigned long rsvd_0_23:24; unsigned long dest_base:22; /* RW */ unsigned long rsvd_46_63:18; } s; - struct uvxh_rh_gam_alias210_redirect_config_0_mmr_s { + + /* UVXH common struct */ + struct uvxh_rh_gam_alias_1_redirect_config_s { unsigned long rsvd_0_23:24; unsigned long dest_base:22; /* RW */ unsigned long rsvd_46_63:18; } sx; - struct uv2h_rh_gam_alias210_redirect_config_0_mmr_s { + + /* UV4 unique struct */ + struct uv4h_rh_gam_alias_1_redirect_config_s { unsigned long rsvd_0_23:24; unsigned long dest_base:22; /* RW */ unsigned long rsvd_46_63:18; - } s2; - struct uv3h_rh_gam_alias210_redirect_config_0_mmr_s { + } s4; + + /* UV3 unique struct */ + struct uv3h_rh_gam_alias_1_redirect_config_s { unsigned long rsvd_0_23:24; unsigned long dest_base:22; /* RW */ unsigned long rsvd_46_63:18; } s3; - struct uv4h_rh_gam_alias210_redirect_config_0_mmr_s { + + /* UV2 unique struct */ + struct uv2h_rh_gam_alias_1_redirect_config_s { unsigned long rsvd_0_23:24; unsigned long dest_base:22; /* RW */ unsigned long rsvd_46_63:18; - } s4; + } s2; }; /* ========================================================================= */ -/* UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR */ +/* UVH_RH_GAM_ALIAS_2_OVERLAY_CONFIG */ /* ========================================================================= */ -#define UV2H_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR 0x16000e0UL -#define UV3H_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR 0x16000e0UL -#define UV4H_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR 0x4800e0UL -#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR) - -#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_SHFT 24 -#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_MASK 0x00003fffff000000UL - -#define UVXH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_SHFT 24 -#define UVXH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_MASK 0x00003fffff000000UL +#define UVH_RH_GAM_ALIAS_2_OVERLAY_CONFIG ( \ + is_uv(UV4) ? 0x4800e8UL : \ + is_uv(UV3) ? 0x16000e8UL : \ + is_uv(UV2) ? 0x16000e8UL : \ + 0) -#define UV2H_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_SHFT 24 -#define UV2H_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_MASK 0x00003fffff000000UL -#define UV3H_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_SHFT 24 -#define UV3H_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_MASK 0x00003fffff000000UL +/* UVXH common defines */ +#define UVXH_RH_GAM_ALIAS_2_OVERLAY_CONFIG_BASE_SHFT 24 +#define UVXH_RH_GAM_ALIAS_2_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL +#define UVXH_RH_GAM_ALIAS_2_OVERLAY_CONFIG_M_ALIAS_SHFT 48 +#define UVXH_RH_GAM_ALIAS_2_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL +#define UVXH_RH_GAM_ALIAS_2_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVXH_RH_GAM_ALIAS_2_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL -#define UV4H_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_SHFT 24 -#define UV4H_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR_DEST_BASE_MASK 0x00003fffff000000UL - -union uvh_rh_gam_alias210_redirect_config_1_mmr_u { +union uvh_rh_gam_alias_2_overlay_config_u { unsigned long v; - struct uvh_rh_gam_alias210_redirect_config_1_mmr_s { + + /* UVH common struct */ + struct uvh_rh_gam_alias_2_overlay_config_s { unsigned long rsvd_0_23:24; - unsigned long dest_base:22; /* RW */ - unsigned long rsvd_46_63:18; + unsigned long base:8; /* RW */ + unsigned long rsvd_32_47:16; + unsigned long m_alias:5; /* RW */ + unsigned long rsvd_53_62:10; + unsigned long enable:1; /* RW */ } s; - struct uvxh_rh_gam_alias210_redirect_config_1_mmr_s { + + /* UVXH common struct */ + struct uvxh_rh_gam_alias_2_overlay_config_s { unsigned long rsvd_0_23:24; - unsigned long dest_base:22; /* RW */ - unsigned long rsvd_46_63:18; + unsigned long base:8; /* RW */ + unsigned long rsvd_32_47:16; + unsigned long m_alias:5; /* RW */ + unsigned long rsvd_53_62:10; + unsigned long enable:1; /* RW */ } sx; - struct uv2h_rh_gam_alias210_redirect_config_1_mmr_s { + + /* UV4 unique struct */ + struct uv4h_rh_gam_alias_2_overlay_config_s { unsigned long rsvd_0_23:24; - unsigned long dest_base:22; /* RW */ - unsigned long rsvd_46_63:18; - } s2; - struct uv3h_rh_gam_alias210_redirect_config_1_mmr_s { + unsigned long base:8; /* RW */ + unsigned long rsvd_32_47:16; + unsigned long m_alias:5; /* RW */ + unsigned long rsvd_53_62:10; + unsigned long enable:1; /* RW */ + } s4; + + /* UV3 unique struct */ + struct uv3h_rh_gam_alias_2_overlay_config_s { unsigned long rsvd_0_23:24; - unsigned long dest_base:22; /* RW */ - unsigned long rsvd_46_63:18; + unsigned long base:8; /* RW */ + unsigned long rsvd_32_47:16; + unsigned long m_alias:5; /* RW */ + unsigned long rsvd_53_62:10; + unsigned long enable:1; /* RW */ } s3; - struct uv4h_rh_gam_alias210_redirect_config_1_mmr_s { + + /* UV2 unique struct */ + struct uv2h_rh_gam_alias_2_overlay_config_s { unsigned long rsvd_0_23:24; - unsigned long dest_base:22; /* RW */ - unsigned long rsvd_46_63:18; - } s4; + unsigned long base:8; /* RW */ + unsigned long rsvd_32_47:16; + unsigned long m_alias:5; /* RW */ + unsigned long rsvd_53_62:10; + unsigned long enable:1; /* RW */ + } s2; }; /* ========================================================================= */ -/* UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR */ +/* UVH_RH_GAM_ALIAS_2_REDIRECT_CONFIG */ /* ========================================================================= */ -#define UV2H_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR 0x16000f0UL -#define UV3H_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR 0x16000f0UL -#define UV4H_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR 0x4800f0UL -#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR) - -#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_SHFT 24 -#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_MASK 0x00003fffff000000UL - -#define UVXH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_SHFT 24 -#define UVXH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_MASK 0x00003fffff000000UL - -#define UV2H_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_SHFT 24 -#define UV2H_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_MASK 0x00003fffff000000UL +#define UVH_RH_GAM_ALIAS_2_REDIRECT_CONFIG ( \ + is_uv(UV4) ? 0x4800f0UL : \ + is_uv(UV3) ? 0x16000f0UL : \ + is_uv(UV2) ? 0x16000f0UL : \ + 0) -#define UV3H_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_SHFT 24 -#define UV3H_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_MASK 0x00003fffff000000UL -#define UV4H_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_SHFT 24 -#define UV4H_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR_DEST_BASE_MASK 0x00003fffff000000UL +/* UVXH common defines */ +#define UVXH_RH_GAM_ALIAS_2_REDIRECT_CONFIG_DEST_BASE_SHFT 24 +#define UVXH_RH_GAM_ALIAS_2_REDIRECT_CONFIG_DEST_BASE_MASK 0x00003fffff000000UL -union uvh_rh_gam_alias210_redirect_config_2_mmr_u { +union uvh_rh_gam_alias_2_redirect_config_u { unsigned long v; - struct uvh_rh_gam_alias210_redirect_config_2_mmr_s { + + /* UVH common struct */ + struct uvh_rh_gam_alias_2_redirect_config_s { unsigned long rsvd_0_23:24; unsigned long dest_base:22; /* RW */ unsigned long rsvd_46_63:18; } s; - struct uvxh_rh_gam_alias210_redirect_config_2_mmr_s { + + /* UVXH common struct */ + struct uvxh_rh_gam_alias_2_redirect_config_s { unsigned long rsvd_0_23:24; unsigned long dest_base:22; /* RW */ unsigned long rsvd_46_63:18; } sx; - struct uv2h_rh_gam_alias210_redirect_config_2_mmr_s { + + /* UV4 unique struct */ + struct uv4h_rh_gam_alias_2_redirect_config_s { unsigned long rsvd_0_23:24; unsigned long dest_base:22; /* RW */ unsigned long rsvd_46_63:18; - } s2; - struct uv3h_rh_gam_alias210_redirect_config_2_mmr_s { + } s4; + + /* UV3 unique struct */ + struct uv3h_rh_gam_alias_2_redirect_config_s { unsigned long rsvd_0_23:24; unsigned long dest_base:22; /* RW */ unsigned long rsvd_46_63:18; } s3; - struct uv4h_rh_gam_alias210_redirect_config_2_mmr_s { + + /* UV2 unique struct */ + struct uv2h_rh_gam_alias_2_redirect_config_s { unsigned long rsvd_0_23:24; unsigned long dest_base:22; /* RW */ unsigned long rsvd_46_63:18; - } s4; -}; - -/* ========================================================================= */ -/* UVH_RH_GAM_CONFIG_MMR */ -/* ========================================================================= */ -#define UV2H_RH_GAM_CONFIG_MMR 0x1600000UL -#define UV3H_RH_GAM_CONFIG_MMR 0x1600000UL -#define UV4H_RH_GAM_CONFIG_MMR 0x480000UL -#define UVH_RH_GAM_CONFIG_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_CONFIG_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_CONFIG_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_CONFIG_MMR) - -#define UVH_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 -#define UVH_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL - -#define UVXH_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 -#define UVXH_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL - -#define UV2H_RH_GAM_CONFIG_MMR_M_SKT_SHFT 0 -#define UV2H_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 -#define UV2H_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL -#define UV2H_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL - -#define UV3H_RH_GAM_CONFIG_MMR_M_SKT_SHFT 0 -#define UV3H_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 -#define UV3H_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL -#define UV3H_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL - -#define UV4H_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 -#define UV4H_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL - - -union uvh_rh_gam_config_mmr_u { - unsigned long v; - struct uvh_rh_gam_config_mmr_s { - unsigned long rsvd_0_5:6; - unsigned long n_skt:4; /* RW */ - unsigned long rsvd_10_63:54; - } s; - struct uvxh_rh_gam_config_mmr_s { - unsigned long rsvd_0_5:6; - unsigned long n_skt:4; /* RW */ - unsigned long rsvd_10_63:54; - } sx; - struct uv2h_rh_gam_config_mmr_s { - unsigned long m_skt:6; /* RW */ - unsigned long n_skt:4; /* RW */ - unsigned long rsvd_10_63:54; } s2; - struct uv3h_rh_gam_config_mmr_s { - unsigned long m_skt:6; /* RW */ - unsigned long n_skt:4; /* RW */ - unsigned long rsvd_10_63:54; - } s3; - struct uv4h_rh_gam_config_mmr_s { - unsigned long rsvd_0_5:6; - unsigned long n_skt:4; /* RW */ - unsigned long rsvd_10_63:54; - } s4; }; /* ========================================================================= */ -/* UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR */ +/* UVH_RH_GAM_GRU_OVERLAY_CONFIG */ /* ========================================================================= */ -#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR 0x1600010UL -#define UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MMR 0x1600010UL -#define UV4H_RH_GAM_GRU_OVERLAY_CONFIG_MMR 0x480010UL -#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_GRU_OVERLAY_CONFIG_MMR) - -#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52 -#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL -#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UVXH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52 -#define UVXH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UVXH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL -#define UVXH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28 -#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52 -#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL -#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL -#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28 -#define UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52 -#define UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_MODE_SHFT 62 -#define UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL -#define UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL -#define UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_MODE_MASK 0x4000000000000000UL -#define UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV4H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 26 -#define UV4H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52 -#define UV4H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UV4H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL -#define UV4H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL -#define UV4H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK ( \ - is_uv2_hub() ? UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK : \ - is_uv3_hub() ? UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK : \ - /*is_uv4_hub*/ UV4H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK) -#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT ( \ - is_uv2_hub() ? UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT : \ - is_uv3_hub() ? UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT : \ - /*is_uv4_hub*/ UV4H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT) - -union uvh_rh_gam_gru_overlay_config_mmr_u { +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG ( \ + is_uv(UV4) ? 0x480010UL : \ + is_uv(UV3) ? 0x1600010UL : \ + is_uv(UV2) ? 0x1600010UL : \ + 0) + + +/* UVXH common defines */ +#define UVXH_RH_GAM_GRU_OVERLAY_CONFIG_N_GRU_SHFT 52 +#define UVXH_RH_GAM_GRU_OVERLAY_CONFIG_N_GRU_MASK 0x00f0000000000000UL +#define UVXH_RH_GAM_GRU_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVXH_RH_GAM_GRU_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +/* UV4A unique defines */ +#define UV4AH_RH_GAM_GRU_OVERLAY_CONFIG_BASE_SHFT 26 +#define UV4AH_RH_GAM_GRU_OVERLAY_CONFIG_BASE_MASK 0x000ffffffc000000UL + +/* UV4 unique defines */ +#define UV4H_RH_GAM_GRU_OVERLAY_CONFIG_BASE_SHFT 26 +#define UV4H_RH_GAM_GRU_OVERLAY_CONFIG_BASE_MASK 0x00003ffffc000000UL + +/* UV3 unique defines */ +#define UV3H_RH_GAM_GRU_OVERLAY_CONFIG_BASE_SHFT 28 +#define UV3H_RH_GAM_GRU_OVERLAY_CONFIG_BASE_MASK 0x00003ffff0000000UL +#define UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MODE_SHFT 62 +#define UV3H_RH_GAM_GRU_OVERLAY_CONFIG_MODE_MASK 0x4000000000000000UL + +/* UV2 unique defines */ +#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_BASE_SHFT 28 +#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_BASE_MASK 0x00003ffff0000000UL + +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_BASE_MASK ( \ + is_uv(UV4A) ? 0x000ffffffc000000UL : \ + is_uv(UV4) ? 0x00003ffffc000000UL : \ + is_uv(UV3) ? 0x00003ffff0000000UL : \ + is_uv(UV2) ? 0x00003ffff0000000UL : \ + 0) +#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_BASE_SHFT ( \ + is_uv(UV4) ? 26 : \ + is_uv(UV3) ? 28 : \ + is_uv(UV2) ? 28 : \ + -1) + +union uvh_rh_gam_gru_overlay_config_u { unsigned long v; - struct uvh_rh_gam_gru_overlay_config_mmr_s { - unsigned long rsvd_0_51:52; + + /* UVH common struct */ + struct uvh_rh_gam_gru_overlay_config_s { + unsigned long rsvd_0_45:46; + unsigned long rsvd_46_51:6; unsigned long n_gru:4; /* RW */ unsigned long rsvd_56_62:7; unsigned long enable:1; /* RW */ } s; - struct uvxh_rh_gam_gru_overlay_config_mmr_s { + + /* UVXH common struct */ + struct uvxh_rh_gam_gru_overlay_config_s { unsigned long rsvd_0_45:46; unsigned long rsvd_46_51:6; unsigned long n_gru:4; /* RW */ unsigned long rsvd_56_62:7; unsigned long enable:1; /* RW */ } sx; - struct uv2h_rh_gam_gru_overlay_config_mmr_s { - unsigned long rsvd_0_27:28; - unsigned long base:18; /* RW */ + + /* UV4A unique struct */ + struct uv4ah_rh_gam_gru_overlay_config_s { + unsigned long rsvd_0_24:25; + unsigned long undef_25:1; /* Undefined */ + unsigned long base:26; /* RW */ + unsigned long n_gru:4; /* RW */ + unsigned long rsvd_56_62:7; + unsigned long enable:1; /* RW */ + } s4a; + + /* UV4 unique struct */ + struct uv4h_rh_gam_gru_overlay_config_s { + unsigned long rsvd_0_24:25; + unsigned long undef_25:1; /* Undefined */ + unsigned long base:20; /* RW */ unsigned long rsvd_46_51:6; unsigned long n_gru:4; /* RW */ unsigned long rsvd_56_62:7; unsigned long enable:1; /* RW */ - } s2; - struct uv3h_rh_gam_gru_overlay_config_mmr_s { + } s4; + + /* UV3 unique struct */ + struct uv3h_rh_gam_gru_overlay_config_s { unsigned long rsvd_0_27:28; unsigned long base:18; /* RW */ unsigned long rsvd_46_51:6; @@ -3093,86 +3913,141 @@ union uvh_rh_gam_gru_overlay_config_mmr_u { unsigned long mode:1; /* RW */ unsigned long enable:1; /* RW */ } s3; - struct uv4h_rh_gam_gru_overlay_config_mmr_s { - unsigned long rsvd_0_24:25; - unsigned long undef_25:1; /* Undefined */ - unsigned long base:20; /* RW */ + + /* UV2 unique struct */ + struct uv2h_rh_gam_gru_overlay_config_s { + unsigned long rsvd_0_27:28; + unsigned long base:18; /* RW */ unsigned long rsvd_46_51:6; unsigned long n_gru:4; /* RW */ unsigned long rsvd_56_62:7; unsigned long enable:1; /* RW */ - } s4; + } s2; }; /* ========================================================================= */ -/* UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR */ +/* UVH_RH_GAM_MMIOH_OVERLAY_CONFIG */ /* ========================================================================= */ -#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR uv_undefined("UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR") -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR 0x1603000UL -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR 0x483000UL -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR) - - -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_BASE_SHFT 26 -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_SHFT 46 -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_ENABLE_SHFT 63 -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_BASE_MASK 0x00003ffffc000000UL -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_MASK 0x000fc00000000000UL -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_BASE_SHFT 26 -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_SHFT 46 -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_ENABLE_SHFT 63 -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_BASE_MASK 0x00003ffffc000000UL -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_MASK 0x000fc00000000000UL -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_SHFT 52 -#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_BASE_MASK 0x000ffffffc000000UL -#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_MASK 0x03f0000000000000UL -#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_SHFT ( \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_SHFT : \ - is_uv4a_hub() ? UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_SHFT : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_SHFT) - -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_BASE_MASK ( \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_BASE_MASK : \ - is_uv4a_hub() ? UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_BASE_MASK : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_BASE_MASK) - -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_MASK ( \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_MASK : \ - is_uv4a_hub() ? UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_MASK : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_MASK) - -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_ENABLE_MASK ( \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_ENABLE_MASK : \ - is_uv4a_hub() ? UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_ENABLE_MASK : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_ENABLE_MASK) - -union uvh_rh_gam_mmioh_overlay_config0_mmr_u { +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG ( \ + is_uv(UV2) ? 0x1600030UL : \ + 0) + + + +/* UV2 unique defines */ +#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_BASE_SHFT 27 +#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_BASE_MASK 0x00003ffff8000000UL +#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_M_IO_SHFT 46 +#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_M_IO_MASK 0x000fc00000000000UL +#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_N_IO_SHFT 52 +#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_N_IO_MASK 0x00f0000000000000UL +#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_BASE_SHFT ( \ + is_uv(UV2) ? 27 : \ + uv_undefined("UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_BASE_SHFT")) + +union uvh_rh_gam_mmioh_overlay_config_u { unsigned long v; - struct uv3h_rh_gam_mmioh_overlay_config0_mmr_s { + + /* UVH common struct */ + struct uvh_rh_gam_mmioh_overlay_config_s { + unsigned long rsvd_0_26:27; + unsigned long base:19; /* RW */ + unsigned long m_io:6; /* RW */ + unsigned long n_io:4; /* RW */ + unsigned long rsvd_56_62:7; + unsigned long enable:1; /* RW */ + } s; + + /* UVXH common struct */ + struct uvxh_rh_gam_mmioh_overlay_config_s { + unsigned long rsvd_0_26:27; + unsigned long base:19; /* RW */ + unsigned long m_io:6; /* RW */ + unsigned long n_io:4; /* RW */ + unsigned long rsvd_56_62:7; + unsigned long enable:1; /* RW */ + } sx; + + /* UV2 unique struct */ + struct uv2h_rh_gam_mmioh_overlay_config_s { + unsigned long rsvd_0_26:27; + unsigned long base:19; /* RW */ + unsigned long m_io:6; /* RW */ + unsigned long n_io:4; /* RW */ + unsigned long rsvd_56_62:7; + unsigned long enable:1; /* RW */ + } s2; +}; + +/* ========================================================================= */ +/* UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0 */ +/* ========================================================================= */ +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0 ( \ + is_uv(UV4) ? 0x483000UL : \ + is_uv(UV3) ? 0x1603000UL : \ + 0) + +/* UV4A unique defines */ +#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_BASE_SHFT 26 +#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_BASE_MASK 0x000ffffffc000000UL +#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_M_IO_SHFT 52 +#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_M_IO_MASK 0x03f0000000000000UL +#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_ENABLE_SHFT 63 +#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG0_ENABLE_MASK 0x8000000000000000UL + +/* UV4 unique defines */ +#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_BASE_SHFT 26 +#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_BASE_MASK 0x00003ffffc000000UL +#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_M_IO_SHFT 46 +#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_M_IO_MASK 0x000fc00000000000UL +#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_ENABLE_SHFT 63 +#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG0_ENABLE_MASK 0x8000000000000000UL + +/* UV3 unique defines */ +#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_BASE_SHFT 26 +#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_BASE_MASK 0x00003ffffc000000UL +#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_M_IO_SHFT 46 +#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_M_IO_MASK 0x000fc00000000000UL +#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_ENABLE_SHFT 63 +#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_ENABLE_MASK 0x8000000000000000UL + +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_BASE_MASK ( \ + is_uv(UV4A) ? 0x000ffffffc000000UL : \ + is_uv(UV4) ? 0x00003ffffc000000UL : \ + is_uv(UV3) ? 0x00003ffffc000000UL : \ + 0) +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_BASE_SHFT ( \ + is_uv(UV4) ? 26 : \ + is_uv(UV3) ? 26 : \ + -1) + +union uvh_rh_gam_mmioh_overlay_config0_u { + unsigned long v; + + /* UVH common struct */ + struct uvh_rh_gam_mmioh_overlay_config0_s { unsigned long rsvd_0_25:26; unsigned long base:20; /* RW */ unsigned long m_io:6; /* RW */ unsigned long n_io:4; unsigned long rsvd_56_62:7; unsigned long enable:1; /* RW */ - } s3; - struct uv4h_rh_gam_mmioh_overlay_config0_mmr_s { + } s; + + /* UVXH common struct */ + struct uvxh_rh_gam_mmioh_overlay_config0_s { unsigned long rsvd_0_25:26; unsigned long base:20; /* RW */ unsigned long m_io:6; /* RW */ unsigned long n_io:4; unsigned long rsvd_56_62:7; unsigned long enable:1; /* RW */ - } s4; + } sx; + + /* UV4A unique struct */ struct uv4ah_rh_gam_mmioh_overlay_config0_mmr_s { unsigned long rsvd_0_25:26; unsigned long base:26; /* RW */ @@ -3181,71 +4056,94 @@ union uvh_rh_gam_mmioh_overlay_config0_mmr_u { unsigned long undef_62:1; /* Undefined */ unsigned long enable:1; /* RW */ } s4a; + + /* UV4 unique struct */ + struct uv4h_rh_gam_mmioh_overlay_config0_s { + unsigned long rsvd_0_25:26; + unsigned long base:20; /* RW */ + unsigned long m_io:6; /* RW */ + unsigned long n_io:4; + unsigned long rsvd_56_62:7; + unsigned long enable:1; /* RW */ + } s4; + + /* UV3 unique struct */ + struct uv3h_rh_gam_mmioh_overlay_config0_s { + unsigned long rsvd_0_25:26; + unsigned long base:20; /* RW */ + unsigned long m_io:6; /* RW */ + unsigned long n_io:4; + unsigned long rsvd_56_62:7; + unsigned long enable:1; /* RW */ + } s3; }; /* ========================================================================= */ -/* UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR */ +/* UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1 */ /* ========================================================================= */ -#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR uv_undefined("UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR") -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR 0x1603000UL -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR 0x484000UL -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR) - - -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_BASE_SHFT 26 -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_SHFT 46 -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_ENABLE_SHFT 63 -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_BASE_MASK 0x00003ffffc000000UL -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_MASK 0x000fc00000000000UL -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_BASE_SHFT 26 -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_SHFT 46 -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_ENABLE_SHFT 63 -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_BASE_MASK 0x00003ffffc000000UL -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_MASK 0x000fc00000000000UL -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_SHFT 52 -#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_BASE_MASK 0x000ffffffc000000UL -#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_MASK 0x03f0000000000000UL - -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_SHFT ( \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_SHFT : \ - is_uv4a_hub() ? UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_SHFT : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_SHFT) - -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_BASE_MASK ( \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_BASE_MASK : \ - is_uv4a_hub() ? UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_BASE_MASK : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_BASE_MASK) - -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_MASK ( \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_MASK : \ - is_uv4a_hub() ? UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_MASK : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_MASK) - -union uvh_rh_gam_mmioh_overlay_config1_mmr_u { +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1 ( \ + is_uv(UV4) ? 0x484000UL : \ + is_uv(UV3) ? 0x1604000UL : \ + 0) + +/* UV4A unique defines */ +#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG1_BASE_SHFT 26 +#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG1_BASE_MASK 0x000ffffffc000000UL +#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG1_M_IO_SHFT 52 +#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG1_M_IO_MASK 0x03f0000000000000UL +#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG1_ENABLE_SHFT 63 +#define UV4AH_RH_GAM_MMIOH_OVERLAY_CONFIG1_ENABLE_MASK 0x8000000000000000UL + +/* UV4 unique defines */ +#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_BASE_SHFT 26 +#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_BASE_MASK 0x00003ffffc000000UL +#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_M_IO_SHFT 46 +#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_M_IO_MASK 0x000fc00000000000UL +#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_ENABLE_SHFT 63 +#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_ENABLE_MASK 0x8000000000000000UL + +/* UV3 unique defines */ +#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_BASE_SHFT 26 +#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_BASE_MASK 0x00003ffffc000000UL +#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_M_IO_SHFT 46 +#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_M_IO_MASK 0x000fc00000000000UL +#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_ENABLE_SHFT 63 +#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_ENABLE_MASK 0x8000000000000000UL + +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_BASE_MASK ( \ + is_uv(UV4A) ? 0x000ffffffc000000UL : \ + is_uv(UV4) ? 0x00003ffffc000000UL : \ + is_uv(UV3) ? 0x00003ffffc000000UL : \ + 0) +#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_BASE_SHFT ( \ + is_uv(UV4) ? 26 : \ + is_uv(UV3) ? 26 : \ + -1) + +union uvh_rh_gam_mmioh_overlay_config1_u { unsigned long v; - struct uv3h_rh_gam_mmioh_overlay_config1_mmr_s { + + /* UVH common struct */ + struct uvh_rh_gam_mmioh_overlay_config1_s { unsigned long rsvd_0_25:26; unsigned long base:20; /* RW */ unsigned long m_io:6; /* RW */ unsigned long n_io:4; unsigned long rsvd_56_62:7; unsigned long enable:1; /* RW */ - } s3; - struct uv4h_rh_gam_mmioh_overlay_config1_mmr_s { + } s; + + /* UVXH common struct */ + struct uvxh_rh_gam_mmioh_overlay_config1_s { unsigned long rsvd_0_25:26; unsigned long base:20; /* RW */ unsigned long m_io:6; /* RW */ unsigned long n_io:4; unsigned long rsvd_56_62:7; unsigned long enable:1; /* RW */ - } s4; + } sx; + + /* UV4A unique struct */ struct uv4ah_rh_gam_mmioh_overlay_config1_mmr_s { unsigned long rsvd_0_25:26; unsigned long base:26; /* RW */ @@ -3254,232 +4152,275 @@ union uvh_rh_gam_mmioh_overlay_config1_mmr_u { unsigned long undef_62:1; /* Undefined */ unsigned long enable:1; /* RW */ } s4a; -}; -/* ========================================================================= */ -/* UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR */ -/* ========================================================================= */ -#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR 0x1600030UL -#define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR uv_undefined("UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR") -#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR uv_undefined("UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR") -#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR) - - -#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT 27 -#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_SHFT 46 -#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_SHFT 52 -#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff8000000UL -#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_MASK 0x000fc00000000000UL -#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_MASK 0x00f0000000000000UL -#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - - -union uvh_rh_gam_mmioh_overlay_config_mmr_u { - unsigned long v; - struct uv2h_rh_gam_mmioh_overlay_config_mmr_s { - unsigned long rsvd_0_26:27; - unsigned long base:19; /* RW */ + /* UV4 unique struct */ + struct uv4h_rh_gam_mmioh_overlay_config1_s { + unsigned long rsvd_0_25:26; + unsigned long base:20; /* RW */ unsigned long m_io:6; /* RW */ - unsigned long n_io:4; /* RW */ + unsigned long n_io:4; unsigned long rsvd_56_62:7; unsigned long enable:1; /* RW */ - } s2; + } s4; + + /* UV3 unique struct */ + struct uv3h_rh_gam_mmioh_overlay_config1_s { + unsigned long rsvd_0_25:26; + unsigned long base:20; /* RW */ + unsigned long m_io:6; /* RW */ + unsigned long n_io:4; + unsigned long rsvd_56_62:7; + unsigned long enable:1; /* RW */ + } s3; }; /* ========================================================================= */ -/* UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR */ +/* UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0 */ /* ========================================================================= */ -#define UV2H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR uv_undefined("UV2H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR") -#define UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR 0x1603800UL -#define UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR 0x483800UL -#define UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR) +#define UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0 ( \ + is_uv(UV4) ? 0x483800UL : \ + is_uv(UV3) ? 0x1603800UL : \ + 0) -#define UV2H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_DEPTH uv_undefined("UV2H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_DEPTH") -#define UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_DEPTH 128 -#define UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_DEPTH 128 -#define UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_DEPTH ( \ - is_uv2_hub() ? UV2H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_DEPTH : \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_DEPTH : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_DEPTH) +#define UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0_DEPTH ( \ + is_uv(UV4) ? 128 : \ + is_uv(UV3) ? 128 : \ + 0) +/* UV4A unique defines */ +#define UV4AH_RH_GAM_MMIOH_REDIRECT_CONFIG0_NASID_SHFT 0 +#define UV4AH_RH_GAM_MMIOH_REDIRECT_CONFIG0_NASID_MASK 0x0000000000000fffUL -#define UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_NASID_SHFT 0 -#define UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_NASID_MASK 0x0000000000007fffUL +/* UV4 unique defines */ +#define UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG0_NASID_SHFT 0 +#define UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG0_NASID_MASK 0x0000000000007fffUL -#define UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_NASID_SHFT 0 -#define UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_NASID_MASK 0x0000000000007fffUL +/* UV3 unique defines */ +#define UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG0_NASID_SHFT 0 +#define UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG0_NASID_MASK 0x0000000000007fffUL -#define UV4AH_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_NASID_MASK 0x0000000000000fffUL -#define UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_NASID_MASK ( \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_NASID_MASK : \ - is_uv4a_hub() ? UV4AH_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_NASID_MASK : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_NASID_MASK) - -union uvh_rh_gam_mmioh_redirect_config0_mmr_u { +union uvh_rh_gam_mmioh_redirect_config0_u { unsigned long v; - struct uv3h_rh_gam_mmioh_redirect_config0_mmr_s { + + /* UVH common struct */ + struct uvh_rh_gam_mmioh_redirect_config0_s { unsigned long nasid:15; /* RW */ unsigned long rsvd_15_63:49; - } s3; - struct uv4h_rh_gam_mmioh_redirect_config0_mmr_s { + } s; + + /* UVXH common struct */ + struct uvxh_rh_gam_mmioh_redirect_config0_s { unsigned long nasid:15; /* RW */ unsigned long rsvd_15_63:49; - } s4; - struct uv4ah_rh_gam_mmioh_redirect_config0_mmr_s { + } sx; + + struct uv4ah_rh_gam_mmioh_redirect_config0_s { unsigned long nasid:12; /* RW */ unsigned long rsvd_12_63:52; } s4a; + + /* UV4 unique struct */ + struct uv4h_rh_gam_mmioh_redirect_config0_s { + unsigned long nasid:15; /* RW */ + unsigned long rsvd_15_63:49; + } s4; + + /* UV3 unique struct */ + struct uv3h_rh_gam_mmioh_redirect_config0_s { + unsigned long nasid:15; /* RW */ + unsigned long rsvd_15_63:49; + } s3; }; /* ========================================================================= */ -/* UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR */ +/* UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1 */ /* ========================================================================= */ -#define UV2H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR uv_undefined("UV2H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR") -#define UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR 0x1604800UL -#define UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR 0x484800UL -#define UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR) - -#define UV2H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_DEPTH uv_undefined("UV2H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_DEPTH") -#define UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_DEPTH 128 -#define UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_DEPTH 128 -#define UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_DEPTH ( \ - is_uv2_hub() ? UV2H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_DEPTH : \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_DEPTH : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_DEPTH) +#define UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1 ( \ + is_uv(UV4) ? 0x484800UL : \ + is_uv(UV3) ? 0x1604800UL : \ + 0) +#define UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1_DEPTH ( \ + is_uv(UV4) ? 128 : \ + is_uv(UV3) ? 128 : \ + 0) -#define UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_NASID_SHFT 0 -#define UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_NASID_MASK 0x0000000000007fffUL +/* UV4A unique defines */ +#define UV4AH_RH_GAM_MMIOH_REDIRECT_CONFIG0_NASID_SHFT 0 +#define UV4AH_RH_GAM_MMIOH_REDIRECT_CONFIG0_NASID_MASK 0x0000000000000fffUL -#define UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_NASID_SHFT 0 -#define UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_NASID_MASK 0x0000000000007fffUL +/* UV4 unique defines */ +#define UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG1_NASID_SHFT 0 +#define UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG1_NASID_MASK 0x0000000000007fffUL -#define UV4AH_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_NASID_MASK 0x0000000000000fffUL +/* UV3 unique defines */ +#define UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG1_NASID_SHFT 0 +#define UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG1_NASID_MASK 0x0000000000007fffUL -#define UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_NASID_MASK ( \ - is_uv3_hub() ? UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_NASID_MASK : \ - is_uv4a_hub() ? UV4AH_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_NASID_MASK : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_NASID_MASK) -union uvh_rh_gam_mmioh_redirect_config1_mmr_u { +union uvh_rh_gam_mmioh_redirect_config1_u { unsigned long v; - struct uv3h_rh_gam_mmioh_redirect_config1_mmr_s { + + /* UVH common struct */ + struct uvh_rh_gam_mmioh_redirect_config1_s { unsigned long nasid:15; /* RW */ unsigned long rsvd_15_63:49; - } s3; - struct uv4h_rh_gam_mmioh_redirect_config1_mmr_s { + } s; + + /* UVXH common struct */ + struct uvxh_rh_gam_mmioh_redirect_config1_s { unsigned long nasid:15; /* RW */ unsigned long rsvd_15_63:49; - } s4; - struct uv4ah_rh_gam_mmioh_redirect_config1_mmr_s { + } sx; + + struct uv4ah_rh_gam_mmioh_redirect_config1_s { unsigned long nasid:12; /* RW */ unsigned long rsvd_12_63:52; } s4a; + + /* UV4 unique struct */ + struct uv4h_rh_gam_mmioh_redirect_config1_s { + unsigned long nasid:15; /* RW */ + unsigned long rsvd_15_63:49; + } s4; + + /* UV3 unique struct */ + struct uv3h_rh_gam_mmioh_redirect_config1_s { + unsigned long nasid:15; /* RW */ + unsigned long rsvd_15_63:49; + } s3; }; /* ========================================================================= */ -/* UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR */ +/* UVH_RH_GAM_MMR_OVERLAY_CONFIG */ /* ========================================================================= */ -#define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR 0x1600028UL -#define UV3H_RH_GAM_MMR_OVERLAY_CONFIG_MMR 0x1600028UL -#define UV4H_RH_GAM_MMR_OVERLAY_CONFIG_MMR 0x480028UL -#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR ( \ - is_uv2_hub() ? UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR : \ - is_uv3_hub() ? UV3H_RH_GAM_MMR_OVERLAY_CONFIG_MMR : \ - /*is_uv4_hub*/ UV4H_RH_GAM_MMR_OVERLAY_CONFIG_MMR) - -#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 -#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL -#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UVXH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 -#define UVXH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UVXH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL -#define UVXH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 -#define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL -#define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV3H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 -#define UV3H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UV3H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL -#define UV3H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - -#define UV4H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 -#define UV4H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 -#define UV4H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL -#define UV4H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL - - -union uvh_rh_gam_mmr_overlay_config_mmr_u { +#define UVH_RH_GAM_MMR_OVERLAY_CONFIG ( \ + is_uv(UV4) ? 0x480028UL : \ + is_uv(UV3) ? 0x1600028UL : \ + is_uv(UV2) ? 0x1600028UL : \ + 0) + + +/* UVXH common defines */ +#define UVXH_RH_GAM_MMR_OVERLAY_CONFIG_BASE_SHFT 26 +#define UVXH_RH_GAM_MMR_OVERLAY_CONFIG_BASE_MASK ( \ + is_uv(UV4A) ? 0x000ffffffc000000UL : \ + is_uv(UV4) ? 0x00003ffffc000000UL : \ + is_uv(UV3) ? 0x00003ffffc000000UL : \ + is_uv(UV2) ? 0x00003ffffc000000UL : \ + 0) +#define UVXH_RH_GAM_MMR_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVXH_RH_GAM_MMR_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +/* UV4A unique defines */ +#define UV4AH_RH_GAM_GRU_OVERLAY_CONFIG_BASE_SHFT 26 +#define UV4AH_RH_GAM_GRU_OVERLAY_CONFIG_BASE_MASK 0x000ffffffc000000UL + +#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_BASE_MASK ( \ + is_uv(UV4A) ? 0x000ffffffc000000UL : \ + is_uv(UV4) ? 0x00003ffffc000000UL : \ + is_uv(UV3) ? 0x00003ffffc000000UL : \ + is_uv(UV2) ? 0x00003ffffc000000UL : \ + 0) + +#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_BASE_SHFT ( \ + is_uv(UV4) ? 26 : \ + is_uv(UV3) ? 26 : \ + is_uv(UV2) ? 26 : \ + -1) + +union uvh_rh_gam_mmr_overlay_config_u { unsigned long v; - struct uvh_rh_gam_mmr_overlay_config_mmr_s { + + /* UVH common struct */ + struct uvh_rh_gam_mmr_overlay_config_s { unsigned long rsvd_0_25:26; unsigned long base:20; /* RW */ unsigned long rsvd_46_62:17; unsigned long enable:1; /* RW */ } s; - struct uvxh_rh_gam_mmr_overlay_config_mmr_s { + + /* UVXH common struct */ + struct uvxh_rh_gam_mmr_overlay_config_s { unsigned long rsvd_0_25:26; unsigned long base:20; /* RW */ unsigned long rsvd_46_62:17; unsigned long enable:1; /* RW */ } sx; - struct uv2h_rh_gam_mmr_overlay_config_mmr_s { + + /* UV4 unique struct */ + struct uv4h_rh_gam_mmr_overlay_config_s { unsigned long rsvd_0_25:26; unsigned long base:20; /* RW */ unsigned long rsvd_46_62:17; unsigned long enable:1; /* RW */ - } s2; - struct uv3h_rh_gam_mmr_overlay_config_mmr_s { + } s4; + + /* UV3 unique struct */ + struct uv3h_rh_gam_mmr_overlay_config_s { unsigned long rsvd_0_25:26; unsigned long base:20; /* RW */ unsigned long rsvd_46_62:17; unsigned long enable:1; /* RW */ } s3; - struct uv4h_rh_gam_mmr_overlay_config_mmr_s { + + /* UV2 unique struct */ + struct uv2h_rh_gam_mmr_overlay_config_s { unsigned long rsvd_0_25:26; unsigned long base:20; /* RW */ unsigned long rsvd_46_62:17; unsigned long enable:1; /* RW */ - } s4; + } s2; }; /* ========================================================================= */ /* UVH_RTC */ /* ========================================================================= */ -#define UV2H_RTC 0x340000UL -#define UV3H_RTC 0x340000UL -#define UV4H_RTC 0xe0000UL #define UVH_RTC ( \ - is_uv2_hub() ? UV2H_RTC : \ - is_uv3_hub() ? UV3H_RTC : \ - /*is_uv4_hub*/ UV4H_RTC) + is_uv(UV5) ? 0xe0000UL : \ + is_uv(UV4) ? 0xe0000UL : \ + is_uv(UV3) ? 0x340000UL : \ + is_uv(UV2) ? 0x340000UL : \ + 0) +/* UVH common defines*/ #define UVH_RTC_REAL_TIME_CLOCK_SHFT 0 #define UVH_RTC_REAL_TIME_CLOCK_MASK 0x00ffffffffffffffUL union uvh_rtc_u { unsigned long v; + + /* UVH common struct */ struct uvh_rtc_s { unsigned long real_time_clock:56; /* RW */ unsigned long rsvd_56_63:8; } s; + + /* UV5 unique struct */ + struct uv5h_rtc_s { + unsigned long real_time_clock:56; /* RW */ + unsigned long rsvd_56_63:8; + } s5; + + /* UV4 unique struct */ + struct uv4h_rtc_s { + unsigned long real_time_clock:56; /* RW */ + unsigned long rsvd_56_63:8; + } s4; + + /* UV3 unique struct */ + struct uv3h_rtc_s { + unsigned long real_time_clock:56; /* RW */ + unsigned long rsvd_56_63:8; + } s3; + + /* UV2 unique struct */ + struct uv2h_rtc_s { + unsigned long real_time_clock:56; /* RW */ + unsigned long rsvd_56_63:8; + } s2; }; /* ========================================================================= */ @@ -3487,26 +4428,29 @@ union uvh_rtc_u { /* ========================================================================= */ #define UVH_RTC1_INT_CONFIG 0x615c0UL +/* UVH common defines*/ #define UVH_RTC1_INT_CONFIG_VECTOR_SHFT 0 -#define UVH_RTC1_INT_CONFIG_DM_SHFT 8 -#define UVH_RTC1_INT_CONFIG_DESTMODE_SHFT 11 -#define UVH_RTC1_INT_CONFIG_STATUS_SHFT 12 -#define UVH_RTC1_INT_CONFIG_P_SHFT 13 -#define UVH_RTC1_INT_CONFIG_T_SHFT 15 -#define UVH_RTC1_INT_CONFIG_M_SHFT 16 -#define UVH_RTC1_INT_CONFIG_APIC_ID_SHFT 32 #define UVH_RTC1_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL +#define UVH_RTC1_INT_CONFIG_DM_SHFT 8 #define UVH_RTC1_INT_CONFIG_DM_MASK 0x0000000000000700UL +#define UVH_RTC1_INT_CONFIG_DESTMODE_SHFT 11 #define UVH_RTC1_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL +#define UVH_RTC1_INT_CONFIG_STATUS_SHFT 12 #define UVH_RTC1_INT_CONFIG_STATUS_MASK 0x0000000000001000UL +#define UVH_RTC1_INT_CONFIG_P_SHFT 13 #define UVH_RTC1_INT_CONFIG_P_MASK 0x0000000000002000UL +#define UVH_RTC1_INT_CONFIG_T_SHFT 15 #define UVH_RTC1_INT_CONFIG_T_MASK 0x0000000000008000UL +#define UVH_RTC1_INT_CONFIG_M_SHFT 16 #define UVH_RTC1_INT_CONFIG_M_MASK 0x0000000000010000UL +#define UVH_RTC1_INT_CONFIG_APIC_ID_SHFT 32 #define UVH_RTC1_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL union uvh_rtc1_int_config_u { unsigned long v; + + /* UVH common struct */ struct uvh_rtc1_int_config_s { unsigned long vector_:8; /* RW */ unsigned long dm:3; /* RW */ @@ -3519,591 +4463,175 @@ union uvh_rtc1_int_config_u { unsigned long rsvd_17_31:15; unsigned long apic_id:32; /* RW */ } s; -}; - -/* ========================================================================= */ -/* UVH_SCRATCH5 */ -/* ========================================================================= */ -#define UV2H_SCRATCH5 0x2d0200UL -#define UV3H_SCRATCH5 0x2d0200UL -#define UV4H_SCRATCH5 0xb0200UL -#define UVH_SCRATCH5 ( \ - is_uv2_hub() ? UV2H_SCRATCH5 : \ - is_uv3_hub() ? UV3H_SCRATCH5 : \ - /*is_uv4_hub*/ UV4H_SCRATCH5) - -#define UV2H_SCRATCH5_32 0x778 -#define UV3H_SCRATCH5_32 0x778 -#define UV4H_SCRATCH5_32 0x798 -#define UVH_SCRATCH5_32 ( \ - is_uv2_hub() ? UV2H_SCRATCH5_32 : \ - is_uv3_hub() ? UV3H_SCRATCH5_32 : \ - /*is_uv4_hub*/ UV4H_SCRATCH5_32) - -#define UVH_SCRATCH5_SCRATCH5_SHFT 0 -#define UVH_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL - - -union uvh_scratch5_u { - unsigned long v; - struct uvh_scratch5_s { - unsigned long scratch5:64; /* RW, W1CS */ - } s; -}; -/* ========================================================================= */ -/* UVH_SCRATCH5_ALIAS */ -/* ========================================================================= */ -#define UV2H_SCRATCH5_ALIAS 0x2d0208UL -#define UV3H_SCRATCH5_ALIAS 0x2d0208UL -#define UV4H_SCRATCH5_ALIAS 0xb0208UL -#define UVH_SCRATCH5_ALIAS ( \ - is_uv2_hub() ? UV2H_SCRATCH5_ALIAS : \ - is_uv3_hub() ? UV3H_SCRATCH5_ALIAS : \ - /*is_uv4_hub*/ UV4H_SCRATCH5_ALIAS) - -#define UV2H_SCRATCH5_ALIAS_32 0x780 -#define UV3H_SCRATCH5_ALIAS_32 0x780 -#define UV4H_SCRATCH5_ALIAS_32 0x7a0 -#define UVH_SCRATCH5_ALIAS_32 ( \ - is_uv2_hub() ? UV2H_SCRATCH5_ALIAS_32 : \ - is_uv3_hub() ? UV3H_SCRATCH5_ALIAS_32 : \ - /*is_uv4_hub*/ UV4H_SCRATCH5_ALIAS_32) - - -/* ========================================================================= */ -/* UVH_SCRATCH5_ALIAS_2 */ -/* ========================================================================= */ -#define UV2H_SCRATCH5_ALIAS_2 0x2d0210UL -#define UV3H_SCRATCH5_ALIAS_2 0x2d0210UL -#define UV4H_SCRATCH5_ALIAS_2 0xb0210UL -#define UVH_SCRATCH5_ALIAS_2 ( \ - is_uv2_hub() ? UV2H_SCRATCH5_ALIAS_2 : \ - is_uv3_hub() ? UV3H_SCRATCH5_ALIAS_2 : \ - /*is_uv4_hub*/ UV4H_SCRATCH5_ALIAS_2) -#define UVH_SCRATCH5_ALIAS_2_32 0x788 - - -/* ========================================================================= */ -/* UVXH_EVENT_OCCURRED2 */ -/* ========================================================================= */ -#define UVXH_EVENT_OCCURRED2 0x70100UL - -#define UV2H_EVENT_OCCURRED2_32 0xb68 -#define UV3H_EVENT_OCCURRED2_32 0xb68 -#define UV4H_EVENT_OCCURRED2_32 0x608 -#define UVH_EVENT_OCCURRED2_32 ( \ - is_uv2_hub() ? UV2H_EVENT_OCCURRED2_32 : \ - is_uv3_hub() ? UV3H_EVENT_OCCURRED2_32 : \ - /*is_uv4_hub*/ UV4H_EVENT_OCCURRED2_32) - - -#define UV2H_EVENT_OCCURRED2_RTC_0_SHFT 0 -#define UV2H_EVENT_OCCURRED2_RTC_1_SHFT 1 -#define UV2H_EVENT_OCCURRED2_RTC_2_SHFT 2 -#define UV2H_EVENT_OCCURRED2_RTC_3_SHFT 3 -#define UV2H_EVENT_OCCURRED2_RTC_4_SHFT 4 -#define UV2H_EVENT_OCCURRED2_RTC_5_SHFT 5 -#define UV2H_EVENT_OCCURRED2_RTC_6_SHFT 6 -#define UV2H_EVENT_OCCURRED2_RTC_7_SHFT 7 -#define UV2H_EVENT_OCCURRED2_RTC_8_SHFT 8 -#define UV2H_EVENT_OCCURRED2_RTC_9_SHFT 9 -#define UV2H_EVENT_OCCURRED2_RTC_10_SHFT 10 -#define UV2H_EVENT_OCCURRED2_RTC_11_SHFT 11 -#define UV2H_EVENT_OCCURRED2_RTC_12_SHFT 12 -#define UV2H_EVENT_OCCURRED2_RTC_13_SHFT 13 -#define UV2H_EVENT_OCCURRED2_RTC_14_SHFT 14 -#define UV2H_EVENT_OCCURRED2_RTC_15_SHFT 15 -#define UV2H_EVENT_OCCURRED2_RTC_16_SHFT 16 -#define UV2H_EVENT_OCCURRED2_RTC_17_SHFT 17 -#define UV2H_EVENT_OCCURRED2_RTC_18_SHFT 18 -#define UV2H_EVENT_OCCURRED2_RTC_19_SHFT 19 -#define UV2H_EVENT_OCCURRED2_RTC_20_SHFT 20 -#define UV2H_EVENT_OCCURRED2_RTC_21_SHFT 21 -#define UV2H_EVENT_OCCURRED2_RTC_22_SHFT 22 -#define UV2H_EVENT_OCCURRED2_RTC_23_SHFT 23 -#define UV2H_EVENT_OCCURRED2_RTC_24_SHFT 24 -#define UV2H_EVENT_OCCURRED2_RTC_25_SHFT 25 -#define UV2H_EVENT_OCCURRED2_RTC_26_SHFT 26 -#define UV2H_EVENT_OCCURRED2_RTC_27_SHFT 27 -#define UV2H_EVENT_OCCURRED2_RTC_28_SHFT 28 -#define UV2H_EVENT_OCCURRED2_RTC_29_SHFT 29 -#define UV2H_EVENT_OCCURRED2_RTC_30_SHFT 30 -#define UV2H_EVENT_OCCURRED2_RTC_31_SHFT 31 -#define UV2H_EVENT_OCCURRED2_RTC_0_MASK 0x0000000000000001UL -#define UV2H_EVENT_OCCURRED2_RTC_1_MASK 0x0000000000000002UL -#define UV2H_EVENT_OCCURRED2_RTC_2_MASK 0x0000000000000004UL -#define UV2H_EVENT_OCCURRED2_RTC_3_MASK 0x0000000000000008UL -#define UV2H_EVENT_OCCURRED2_RTC_4_MASK 0x0000000000000010UL -#define UV2H_EVENT_OCCURRED2_RTC_5_MASK 0x0000000000000020UL -#define UV2H_EVENT_OCCURRED2_RTC_6_MASK 0x0000000000000040UL -#define UV2H_EVENT_OCCURRED2_RTC_7_MASK 0x0000000000000080UL -#define UV2H_EVENT_OCCURRED2_RTC_8_MASK 0x0000000000000100UL -#define UV2H_EVENT_OCCURRED2_RTC_9_MASK 0x0000000000000200UL -#define UV2H_EVENT_OCCURRED2_RTC_10_MASK 0x0000000000000400UL -#define UV2H_EVENT_OCCURRED2_RTC_11_MASK 0x0000000000000800UL -#define UV2H_EVENT_OCCURRED2_RTC_12_MASK 0x0000000000001000UL -#define UV2H_EVENT_OCCURRED2_RTC_13_MASK 0x0000000000002000UL -#define UV2H_EVENT_OCCURRED2_RTC_14_MASK 0x0000000000004000UL -#define UV2H_EVENT_OCCURRED2_RTC_15_MASK 0x0000000000008000UL -#define UV2H_EVENT_OCCURRED2_RTC_16_MASK 0x0000000000010000UL -#define UV2H_EVENT_OCCURRED2_RTC_17_MASK 0x0000000000020000UL -#define UV2H_EVENT_OCCURRED2_RTC_18_MASK 0x0000000000040000UL -#define UV2H_EVENT_OCCURRED2_RTC_19_MASK 0x0000000000080000UL -#define UV2H_EVENT_OCCURRED2_RTC_20_MASK 0x0000000000100000UL -#define UV2H_EVENT_OCCURRED2_RTC_21_MASK 0x0000000000200000UL -#define UV2H_EVENT_OCCURRED2_RTC_22_MASK 0x0000000000400000UL -#define UV2H_EVENT_OCCURRED2_RTC_23_MASK 0x0000000000800000UL -#define UV2H_EVENT_OCCURRED2_RTC_24_MASK 0x0000000001000000UL -#define UV2H_EVENT_OCCURRED2_RTC_25_MASK 0x0000000002000000UL -#define UV2H_EVENT_OCCURRED2_RTC_26_MASK 0x0000000004000000UL -#define UV2H_EVENT_OCCURRED2_RTC_27_MASK 0x0000000008000000UL -#define UV2H_EVENT_OCCURRED2_RTC_28_MASK 0x0000000010000000UL -#define UV2H_EVENT_OCCURRED2_RTC_29_MASK 0x0000000020000000UL -#define UV2H_EVENT_OCCURRED2_RTC_30_MASK 0x0000000040000000UL -#define UV2H_EVENT_OCCURRED2_RTC_31_MASK 0x0000000080000000UL - -#define UV3H_EVENT_OCCURRED2_RTC_0_SHFT 0 -#define UV3H_EVENT_OCCURRED2_RTC_1_SHFT 1 -#define UV3H_EVENT_OCCURRED2_RTC_2_SHFT 2 -#define UV3H_EVENT_OCCURRED2_RTC_3_SHFT 3 -#define UV3H_EVENT_OCCURRED2_RTC_4_SHFT 4 -#define UV3H_EVENT_OCCURRED2_RTC_5_SHFT 5 -#define UV3H_EVENT_OCCURRED2_RTC_6_SHFT 6 -#define UV3H_EVENT_OCCURRED2_RTC_7_SHFT 7 -#define UV3H_EVENT_OCCURRED2_RTC_8_SHFT 8 -#define UV3H_EVENT_OCCURRED2_RTC_9_SHFT 9 -#define UV3H_EVENT_OCCURRED2_RTC_10_SHFT 10 -#define UV3H_EVENT_OCCURRED2_RTC_11_SHFT 11 -#define UV3H_EVENT_OCCURRED2_RTC_12_SHFT 12 -#define UV3H_EVENT_OCCURRED2_RTC_13_SHFT 13 -#define UV3H_EVENT_OCCURRED2_RTC_14_SHFT 14 -#define UV3H_EVENT_OCCURRED2_RTC_15_SHFT 15 -#define UV3H_EVENT_OCCURRED2_RTC_16_SHFT 16 -#define UV3H_EVENT_OCCURRED2_RTC_17_SHFT 17 -#define UV3H_EVENT_OCCURRED2_RTC_18_SHFT 18 -#define UV3H_EVENT_OCCURRED2_RTC_19_SHFT 19 -#define UV3H_EVENT_OCCURRED2_RTC_20_SHFT 20 -#define UV3H_EVENT_OCCURRED2_RTC_21_SHFT 21 -#define UV3H_EVENT_OCCURRED2_RTC_22_SHFT 22 -#define UV3H_EVENT_OCCURRED2_RTC_23_SHFT 23 -#define UV3H_EVENT_OCCURRED2_RTC_24_SHFT 24 -#define UV3H_EVENT_OCCURRED2_RTC_25_SHFT 25 -#define UV3H_EVENT_OCCURRED2_RTC_26_SHFT 26 -#define UV3H_EVENT_OCCURRED2_RTC_27_SHFT 27 -#define UV3H_EVENT_OCCURRED2_RTC_28_SHFT 28 -#define UV3H_EVENT_OCCURRED2_RTC_29_SHFT 29 -#define UV3H_EVENT_OCCURRED2_RTC_30_SHFT 30 -#define UV3H_EVENT_OCCURRED2_RTC_31_SHFT 31 -#define UV3H_EVENT_OCCURRED2_RTC_0_MASK 0x0000000000000001UL -#define UV3H_EVENT_OCCURRED2_RTC_1_MASK 0x0000000000000002UL -#define UV3H_EVENT_OCCURRED2_RTC_2_MASK 0x0000000000000004UL -#define UV3H_EVENT_OCCURRED2_RTC_3_MASK 0x0000000000000008UL -#define UV3H_EVENT_OCCURRED2_RTC_4_MASK 0x0000000000000010UL -#define UV3H_EVENT_OCCURRED2_RTC_5_MASK 0x0000000000000020UL -#define UV3H_EVENT_OCCURRED2_RTC_6_MASK 0x0000000000000040UL -#define UV3H_EVENT_OCCURRED2_RTC_7_MASK 0x0000000000000080UL -#define UV3H_EVENT_OCCURRED2_RTC_8_MASK 0x0000000000000100UL -#define UV3H_EVENT_OCCURRED2_RTC_9_MASK 0x0000000000000200UL -#define UV3H_EVENT_OCCURRED2_RTC_10_MASK 0x0000000000000400UL -#define UV3H_EVENT_OCCURRED2_RTC_11_MASK 0x0000000000000800UL -#define UV3H_EVENT_OCCURRED2_RTC_12_MASK 0x0000000000001000UL -#define UV3H_EVENT_OCCURRED2_RTC_13_MASK 0x0000000000002000UL -#define UV3H_EVENT_OCCURRED2_RTC_14_MASK 0x0000000000004000UL -#define UV3H_EVENT_OCCURRED2_RTC_15_MASK 0x0000000000008000UL -#define UV3H_EVENT_OCCURRED2_RTC_16_MASK 0x0000000000010000UL -#define UV3H_EVENT_OCCURRED2_RTC_17_MASK 0x0000000000020000UL -#define UV3H_EVENT_OCCURRED2_RTC_18_MASK 0x0000000000040000UL -#define UV3H_EVENT_OCCURRED2_RTC_19_MASK 0x0000000000080000UL -#define UV3H_EVENT_OCCURRED2_RTC_20_MASK 0x0000000000100000UL -#define UV3H_EVENT_OCCURRED2_RTC_21_MASK 0x0000000000200000UL -#define UV3H_EVENT_OCCURRED2_RTC_22_MASK 0x0000000000400000UL -#define UV3H_EVENT_OCCURRED2_RTC_23_MASK 0x0000000000800000UL -#define UV3H_EVENT_OCCURRED2_RTC_24_MASK 0x0000000001000000UL -#define UV3H_EVENT_OCCURRED2_RTC_25_MASK 0x0000000002000000UL -#define UV3H_EVENT_OCCURRED2_RTC_26_MASK 0x0000000004000000UL -#define UV3H_EVENT_OCCURRED2_RTC_27_MASK 0x0000000008000000UL -#define UV3H_EVENT_OCCURRED2_RTC_28_MASK 0x0000000010000000UL -#define UV3H_EVENT_OCCURRED2_RTC_29_MASK 0x0000000020000000UL -#define UV3H_EVENT_OCCURRED2_RTC_30_MASK 0x0000000040000000UL -#define UV3H_EVENT_OCCURRED2_RTC_31_MASK 0x0000000080000000UL + /* UV5 unique struct */ + struct uv5h_rtc1_int_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ + } s5; -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT0_SHFT 0 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT1_SHFT 1 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT2_SHFT 2 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT3_SHFT 3 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT4_SHFT 4 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT5_SHFT 5 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT6_SHFT 6 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT7_SHFT 7 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT8_SHFT 8 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT9_SHFT 9 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT10_SHFT 10 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT11_SHFT 11 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT12_SHFT 12 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT13_SHFT 13 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT14_SHFT 14 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT15_SHFT 15 -#define UV4H_EVENT_OCCURRED2_RTC_INTERVAL_INT_SHFT 16 -#define UV4H_EVENT_OCCURRED2_BAU_DASHBOARD_INT_SHFT 17 -#define UV4H_EVENT_OCCURRED2_RTC_0_SHFT 18 -#define UV4H_EVENT_OCCURRED2_RTC_1_SHFT 19 -#define UV4H_EVENT_OCCURRED2_RTC_2_SHFT 20 -#define UV4H_EVENT_OCCURRED2_RTC_3_SHFT 21 -#define UV4H_EVENT_OCCURRED2_RTC_4_SHFT 22 -#define UV4H_EVENT_OCCURRED2_RTC_5_SHFT 23 -#define UV4H_EVENT_OCCURRED2_RTC_6_SHFT 24 -#define UV4H_EVENT_OCCURRED2_RTC_7_SHFT 25 -#define UV4H_EVENT_OCCURRED2_RTC_8_SHFT 26 -#define UV4H_EVENT_OCCURRED2_RTC_9_SHFT 27 -#define UV4H_EVENT_OCCURRED2_RTC_10_SHFT 28 -#define UV4H_EVENT_OCCURRED2_RTC_11_SHFT 29 -#define UV4H_EVENT_OCCURRED2_RTC_12_SHFT 30 -#define UV4H_EVENT_OCCURRED2_RTC_13_SHFT 31 -#define UV4H_EVENT_OCCURRED2_RTC_14_SHFT 32 -#define UV4H_EVENT_OCCURRED2_RTC_15_SHFT 33 -#define UV4H_EVENT_OCCURRED2_RTC_16_SHFT 34 -#define UV4H_EVENT_OCCURRED2_RTC_17_SHFT 35 -#define UV4H_EVENT_OCCURRED2_RTC_18_SHFT 36 -#define UV4H_EVENT_OCCURRED2_RTC_19_SHFT 37 -#define UV4H_EVENT_OCCURRED2_RTC_20_SHFT 38 -#define UV4H_EVENT_OCCURRED2_RTC_21_SHFT 39 -#define UV4H_EVENT_OCCURRED2_RTC_22_SHFT 40 -#define UV4H_EVENT_OCCURRED2_RTC_23_SHFT 41 -#define UV4H_EVENT_OCCURRED2_RTC_24_SHFT 42 -#define UV4H_EVENT_OCCURRED2_RTC_25_SHFT 43 -#define UV4H_EVENT_OCCURRED2_RTC_26_SHFT 44 -#define UV4H_EVENT_OCCURRED2_RTC_27_SHFT 45 -#define UV4H_EVENT_OCCURRED2_RTC_28_SHFT 46 -#define UV4H_EVENT_OCCURRED2_RTC_29_SHFT 47 -#define UV4H_EVENT_OCCURRED2_RTC_30_SHFT 48 -#define UV4H_EVENT_OCCURRED2_RTC_31_SHFT 49 -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT0_MASK 0x0000000000000001UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT1_MASK 0x0000000000000002UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT2_MASK 0x0000000000000004UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT3_MASK 0x0000000000000008UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT4_MASK 0x0000000000000010UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT5_MASK 0x0000000000000020UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT6_MASK 0x0000000000000040UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT7_MASK 0x0000000000000080UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT8_MASK 0x0000000000000100UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT9_MASK 0x0000000000000200UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT10_MASK 0x0000000000000400UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT11_MASK 0x0000000000000800UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT12_MASK 0x0000000000001000UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT13_MASK 0x0000000000002000UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT14_MASK 0x0000000000004000UL -#define UV4H_EVENT_OCCURRED2_MESSAGE_ACCELERATOR_INT15_MASK 0x0000000000008000UL -#define UV4H_EVENT_OCCURRED2_RTC_INTERVAL_INT_MASK 0x0000000000010000UL -#define UV4H_EVENT_OCCURRED2_BAU_DASHBOARD_INT_MASK 0x0000000000020000UL -#define UV4H_EVENT_OCCURRED2_RTC_0_MASK 0x0000000000040000UL -#define UV4H_EVENT_OCCURRED2_RTC_1_MASK 0x0000000000080000UL -#define UV4H_EVENT_OCCURRED2_RTC_2_MASK 0x0000000000100000UL -#define UV4H_EVENT_OCCURRED2_RTC_3_MASK 0x0000000000200000UL -#define UV4H_EVENT_OCCURRED2_RTC_4_MASK 0x0000000000400000UL -#define UV4H_EVENT_OCCURRED2_RTC_5_MASK 0x0000000000800000UL -#define UV4H_EVENT_OCCURRED2_RTC_6_MASK 0x0000000001000000UL -#define UV4H_EVENT_OCCURRED2_RTC_7_MASK 0x0000000002000000UL -#define UV4H_EVENT_OCCURRED2_RTC_8_MASK 0x0000000004000000UL -#define UV4H_EVENT_OCCURRED2_RTC_9_MASK 0x0000000008000000UL -#define UV4H_EVENT_OCCURRED2_RTC_10_MASK 0x0000000010000000UL -#define UV4H_EVENT_OCCURRED2_RTC_11_MASK 0x0000000020000000UL -#define UV4H_EVENT_OCCURRED2_RTC_12_MASK 0x0000000040000000UL -#define UV4H_EVENT_OCCURRED2_RTC_13_MASK 0x0000000080000000UL -#define UV4H_EVENT_OCCURRED2_RTC_14_MASK 0x0000000100000000UL -#define UV4H_EVENT_OCCURRED2_RTC_15_MASK 0x0000000200000000UL -#define UV4H_EVENT_OCCURRED2_RTC_16_MASK 0x0000000400000000UL -#define UV4H_EVENT_OCCURRED2_RTC_17_MASK 0x0000000800000000UL -#define UV4H_EVENT_OCCURRED2_RTC_18_MASK 0x0000001000000000UL -#define UV4H_EVENT_OCCURRED2_RTC_19_MASK 0x0000002000000000UL -#define UV4H_EVENT_OCCURRED2_RTC_20_MASK 0x0000004000000000UL -#define UV4H_EVENT_OCCURRED2_RTC_21_MASK 0x0000008000000000UL -#define UV4H_EVENT_OCCURRED2_RTC_22_MASK 0x0000010000000000UL -#define UV4H_EVENT_OCCURRED2_RTC_23_MASK 0x0000020000000000UL -#define UV4H_EVENT_OCCURRED2_RTC_24_MASK 0x0000040000000000UL -#define UV4H_EVENT_OCCURRED2_RTC_25_MASK 0x0000080000000000UL -#define UV4H_EVENT_OCCURRED2_RTC_26_MASK 0x0000100000000000UL -#define UV4H_EVENT_OCCURRED2_RTC_27_MASK 0x0000200000000000UL -#define UV4H_EVENT_OCCURRED2_RTC_28_MASK 0x0000400000000000UL -#define UV4H_EVENT_OCCURRED2_RTC_29_MASK 0x0000800000000000UL -#define UV4H_EVENT_OCCURRED2_RTC_30_MASK 0x0001000000000000UL -#define UV4H_EVENT_OCCURRED2_RTC_31_MASK 0x0002000000000000UL + /* UV4 unique struct */ + struct uv4h_rtc1_int_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ + } s4; -#define UVXH_EVENT_OCCURRED2_RTC_1_MASK ( \ - is_uv2_hub() ? UV2H_EVENT_OCCURRED2_RTC_1_MASK : \ - is_uv3_hub() ? UV3H_EVENT_OCCURRED2_RTC_1_MASK : \ - /*is_uv4_hub*/ UV4H_EVENT_OCCURRED2_RTC_1_MASK) + /* UV3 unique struct */ + struct uv3h_rtc1_int_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ + } s3; -union uvh_event_occurred2_u { - unsigned long v; - struct uv2h_event_occurred2_s { - unsigned long rtc_0:1; /* RW */ - unsigned long rtc_1:1; /* RW */ - unsigned long rtc_2:1; /* RW */ - unsigned long rtc_3:1; /* RW */ - unsigned long rtc_4:1; /* RW */ - unsigned long rtc_5:1; /* RW */ - unsigned long rtc_6:1; /* RW */ - unsigned long rtc_7:1; /* RW */ - unsigned long rtc_8:1; /* RW */ - unsigned long rtc_9:1; /* RW */ - unsigned long rtc_10:1; /* RW */ - unsigned long rtc_11:1; /* RW */ - unsigned long rtc_12:1; /* RW */ - unsigned long rtc_13:1; /* RW */ - unsigned long rtc_14:1; /* RW */ - unsigned long rtc_15:1; /* RW */ - unsigned long rtc_16:1; /* RW */ - unsigned long rtc_17:1; /* RW */ - unsigned long rtc_18:1; /* RW */ - unsigned long rtc_19:1; /* RW */ - unsigned long rtc_20:1; /* RW */ - unsigned long rtc_21:1; /* RW */ - unsigned long rtc_22:1; /* RW */ - unsigned long rtc_23:1; /* RW */ - unsigned long rtc_24:1; /* RW */ - unsigned long rtc_25:1; /* RW */ - unsigned long rtc_26:1; /* RW */ - unsigned long rtc_27:1; /* RW */ - unsigned long rtc_28:1; /* RW */ - unsigned long rtc_29:1; /* RW */ - unsigned long rtc_30:1; /* RW */ - unsigned long rtc_31:1; /* RW */ - unsigned long rsvd_32_63:32; + /* UV2 unique struct */ + struct uv2h_rtc1_int_config_s { + unsigned long vector_:8; /* RW */ + unsigned long dm:3; /* RW */ + unsigned long destmode:1; /* RW */ + unsigned long status:1; /* RO */ + unsigned long p:1; /* RO */ + unsigned long rsvd_14:1; + unsigned long t:1; /* RO */ + unsigned long m:1; /* RW */ + unsigned long rsvd_17_31:15; + unsigned long apic_id:32; /* RW */ } s2; - struct uv3h_event_occurred2_s { - unsigned long rtc_0:1; /* RW */ - unsigned long rtc_1:1; /* RW */ - unsigned long rtc_2:1; /* RW */ - unsigned long rtc_3:1; /* RW */ - unsigned long rtc_4:1; /* RW */ - unsigned long rtc_5:1; /* RW */ - unsigned long rtc_6:1; /* RW */ - unsigned long rtc_7:1; /* RW */ - unsigned long rtc_8:1; /* RW */ - unsigned long rtc_9:1; /* RW */ - unsigned long rtc_10:1; /* RW */ - unsigned long rtc_11:1; /* RW */ - unsigned long rtc_12:1; /* RW */ - unsigned long rtc_13:1; /* RW */ - unsigned long rtc_14:1; /* RW */ - unsigned long rtc_15:1; /* RW */ - unsigned long rtc_16:1; /* RW */ - unsigned long rtc_17:1; /* RW */ - unsigned long rtc_18:1; /* RW */ - unsigned long rtc_19:1; /* RW */ - unsigned long rtc_20:1; /* RW */ - unsigned long rtc_21:1; /* RW */ - unsigned long rtc_22:1; /* RW */ - unsigned long rtc_23:1; /* RW */ - unsigned long rtc_24:1; /* RW */ - unsigned long rtc_25:1; /* RW */ - unsigned long rtc_26:1; /* RW */ - unsigned long rtc_27:1; /* RW */ - unsigned long rtc_28:1; /* RW */ - unsigned long rtc_29:1; /* RW */ - unsigned long rtc_30:1; /* RW */ - unsigned long rtc_31:1; /* RW */ - unsigned long rsvd_32_63:32; - } s3; - struct uv4h_event_occurred2_s { - unsigned long message_accelerator_int0:1; /* RW */ - unsigned long message_accelerator_int1:1; /* RW */ - unsigned long message_accelerator_int2:1; /* RW */ - unsigned long message_accelerator_int3:1; /* RW */ - unsigned long message_accelerator_int4:1; /* RW */ - unsigned long message_accelerator_int5:1; /* RW */ - unsigned long message_accelerator_int6:1; /* RW */ - unsigned long message_accelerator_int7:1; /* RW */ - unsigned long message_accelerator_int8:1; /* RW */ - unsigned long message_accelerator_int9:1; /* RW */ - unsigned long message_accelerator_int10:1; /* RW */ - unsigned long message_accelerator_int11:1; /* RW */ - unsigned long message_accelerator_int12:1; /* RW */ - unsigned long message_accelerator_int13:1; /* RW */ - unsigned long message_accelerator_int14:1; /* RW */ - unsigned long message_accelerator_int15:1; /* RW */ - unsigned long rtc_interval_int:1; /* RW */ - unsigned long bau_dashboard_int:1; /* RW */ - unsigned long rtc_0:1; /* RW */ - unsigned long rtc_1:1; /* RW */ - unsigned long rtc_2:1; /* RW */ - unsigned long rtc_3:1; /* RW */ - unsigned long rtc_4:1; /* RW */ - unsigned long rtc_5:1; /* RW */ - unsigned long rtc_6:1; /* RW */ - unsigned long rtc_7:1; /* RW */ - unsigned long rtc_8:1; /* RW */ - unsigned long rtc_9:1; /* RW */ - unsigned long rtc_10:1; /* RW */ - unsigned long rtc_11:1; /* RW */ - unsigned long rtc_12:1; /* RW */ - unsigned long rtc_13:1; /* RW */ - unsigned long rtc_14:1; /* RW */ - unsigned long rtc_15:1; /* RW */ - unsigned long rtc_16:1; /* RW */ - unsigned long rtc_17:1; /* RW */ - unsigned long rtc_18:1; /* RW */ - unsigned long rtc_19:1; /* RW */ - unsigned long rtc_20:1; /* RW */ - unsigned long rtc_21:1; /* RW */ - unsigned long rtc_22:1; /* RW */ - unsigned long rtc_23:1; /* RW */ - unsigned long rtc_24:1; /* RW */ - unsigned long rtc_25:1; /* RW */ - unsigned long rtc_26:1; /* RW */ - unsigned long rtc_27:1; /* RW */ - unsigned long rtc_28:1; /* RW */ - unsigned long rtc_29:1; /* RW */ - unsigned long rtc_30:1; /* RW */ - unsigned long rtc_31:1; /* RW */ - unsigned long rsvd_50_63:14; - } s4; }; /* ========================================================================= */ -/* UVXH_EVENT_OCCURRED2_ALIAS */ +/* UVH_SCRATCH5 */ /* ========================================================================= */ -#define UVXH_EVENT_OCCURRED2_ALIAS 0x70108UL - -#define UV2H_EVENT_OCCURRED2_ALIAS_32 0xb70 -#define UV3H_EVENT_OCCURRED2_ALIAS_32 0xb70 -#define UV4H_EVENT_OCCURRED2_ALIAS_32 0x610 -#define UVH_EVENT_OCCURRED2_ALIAS_32 ( \ - is_uv2_hub() ? UV2H_EVENT_OCCURRED2_ALIAS_32 : \ - is_uv3_hub() ? UV3H_EVENT_OCCURRED2_ALIAS_32 : \ - /*is_uv4_hub*/ UV4H_EVENT_OCCURRED2_ALIAS_32) +#define UVH_SCRATCH5 ( \ + is_uv(UV5) ? 0xb0200UL : \ + is_uv(UV4) ? 0xb0200UL : \ + is_uv(UV3) ? 0x2d0200UL : \ + is_uv(UV2) ? 0x2d0200UL : \ + 0) +#define UV5H_SCRATCH5 0xb0200UL +#define UV4H_SCRATCH5 0xb0200UL +#define UV3H_SCRATCH5 0x2d0200UL +#define UV2H_SCRATCH5 0x2d0200UL +/* UVH common defines*/ +#define UVH_SCRATCH5_SCRATCH5_SHFT 0 +#define UVH_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL -/* ========================================================================= */ -/* UVXH_LB_BAU_SB_ACTIVATION_STATUS_2 */ -/* ========================================================================= */ -#define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2 0x320130UL -#define UV3H_LB_BAU_SB_ACTIVATION_STATUS_2 0x320130UL -#define UV4H_LB_BAU_SB_ACTIVATION_STATUS_2 0xc8130UL -#define UVH_LB_BAU_SB_ACTIVATION_STATUS_2 ( \ - is_uv2_hub() ? UV2H_LB_BAU_SB_ACTIVATION_STATUS_2 : \ - is_uv3_hub() ? UV3H_LB_BAU_SB_ACTIVATION_STATUS_2 : \ - /*is_uv4_hub*/ UV4H_LB_BAU_SB_ACTIVATION_STATUS_2) +/* UVXH common defines */ +#define UVXH_SCRATCH5_SCRATCH5_SHFT 0 +#define UVXH_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL -#define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2_32 0x9f0 -#define UV3H_LB_BAU_SB_ACTIVATION_STATUS_2_32 0x9f0 -#define UV4H_LB_BAU_SB_ACTIVATION_STATUS_2_32 0xa10 -#define UVH_LB_BAU_SB_ACTIVATION_STATUS_2_32 ( \ - is_uv2_hub() ? UV2H_LB_BAU_SB_ACTIVATION_STATUS_2_32 : \ - is_uv3_hub() ? UV3H_LB_BAU_SB_ACTIVATION_STATUS_2_32 : \ - /*is_uv4_hub*/ UV4H_LB_BAU_SB_ACTIVATION_STATUS_2_32) +/* UVYH common defines */ +#define UVYH_SCRATCH5_SCRATCH5_SHFT 0 +#define UVYH_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL -#define UVXH_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_SHFT 0 -#define UVXH_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_MASK 0xffffffffffffffffUL +/* UV5 unique defines */ +#define UV5H_SCRATCH5_SCRATCH5_SHFT 0 +#define UV5H_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL -#define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_SHFT 0 -#define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_MASK 0xffffffffffffffffUL +/* UV4 unique defines */ +#define UV4H_SCRATCH5_SCRATCH5_SHFT 0 +#define UV4H_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL -#define UV3H_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_SHFT 0 -#define UV3H_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_MASK 0xffffffffffffffffUL +/* UV3 unique defines */ +#define UV3H_SCRATCH5_SCRATCH5_SHFT 0 +#define UV3H_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL -#define UV4H_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_SHFT 0 -#define UV4H_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_MASK 0xffffffffffffffffUL +/* UV2 unique defines */ +#define UV2H_SCRATCH5_SCRATCH5_SHFT 0 +#define UV2H_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL -union uvxh_lb_bau_sb_activation_status_2_u { +union uvh_scratch5_u { unsigned long v; - struct uvxh_lb_bau_sb_activation_status_2_s { - unsigned long aux_error:64; /* RW */ - } sx; - struct uv2h_lb_bau_sb_activation_status_2_s { - unsigned long aux_error:64; /* RW */ - } s2; - struct uv3h_lb_bau_sb_activation_status_2_s { - unsigned long aux_error:64; /* RW */ - } s3; - struct uv4h_lb_bau_sb_activation_status_2_s { - unsigned long aux_error:64; /* RW */ - } s4; -}; -/* ========================================================================= */ -/* UV3H_GR0_GAM_GR_CONFIG */ -/* ========================================================================= */ -#define UV3H_GR0_GAM_GR_CONFIG 0xc00028UL - -#define UV3H_GR0_GAM_GR_CONFIG_M_SKT_SHFT 0 -#define UV3H_GR0_GAM_GR_CONFIG_SUBSPACE_SHFT 10 -#define UV3H_GR0_GAM_GR_CONFIG_M_SKT_MASK 0x000000000000003fUL -#define UV3H_GR0_GAM_GR_CONFIG_SUBSPACE_MASK 0x0000000000000400UL + /* UVH common struct */ + struct uvh_scratch5_s { + unsigned long scratch5:64; /* RW */ + } s; -union uv3h_gr0_gam_gr_config_u { - unsigned long v; - struct uv3h_gr0_gam_gr_config_s { - unsigned long m_skt:6; /* RW */ - unsigned long undef_6_9:4; /* Undefined */ - unsigned long subspace:1; /* RW */ - unsigned long reserved:53; - } s3; -}; + /* UVXH common struct */ + struct uvxh_scratch5_s { + unsigned long scratch5:64; /* RW */ + } sx; -/* ========================================================================= */ -/* UV4H_LB_PROC_INTD_QUEUE_FIRST */ -/* ========================================================================= */ -#define UV4H_LB_PROC_INTD_QUEUE_FIRST 0xa4100UL + /* UVYH common struct */ + struct uvyh_scratch5_s { + unsigned long scratch5:64; /* RW */ + } sy; -#define UV4H_LB_PROC_INTD_QUEUE_FIRST_FIRST_PAYLOAD_ADDRESS_SHFT 6 -#define UV4H_LB_PROC_INTD_QUEUE_FIRST_FIRST_PAYLOAD_ADDRESS_MASK 0x00003fffffffffc0UL + /* UV5 unique struct */ + struct uv5h_scratch5_s { + unsigned long scratch5:64; /* RW */ + } s5; -union uv4h_lb_proc_intd_queue_first_u { - unsigned long v; - struct uv4h_lb_proc_intd_queue_first_s { - unsigned long undef_0_5:6; /* Undefined */ - unsigned long first_payload_address:40; /* RW */ + /* UV4 unique struct */ + struct uv4h_scratch5_s { + unsigned long scratch5:64; /* RW */ } s4; -}; -/* ========================================================================= */ -/* UV4H_LB_PROC_INTD_QUEUE_LAST */ -/* ========================================================================= */ -#define UV4H_LB_PROC_INTD_QUEUE_LAST 0xa4108UL - -#define UV4H_LB_PROC_INTD_QUEUE_LAST_LAST_PAYLOAD_ADDRESS_SHFT 5 -#define UV4H_LB_PROC_INTD_QUEUE_LAST_LAST_PAYLOAD_ADDRESS_MASK 0x00003fffffffffe0UL + /* UV3 unique struct */ + struct uv3h_scratch5_s { + unsigned long scratch5:64; /* RW */ + } s3; -union uv4h_lb_proc_intd_queue_last_u { - unsigned long v; - struct uv4h_lb_proc_intd_queue_last_s { - unsigned long undef_0_4:5; /* Undefined */ - unsigned long last_payload_address:41; /* RW */ - } s4; + /* UV2 unique struct */ + struct uv2h_scratch5_s { + unsigned long scratch5:64; /* RW */ + } s2; }; /* ========================================================================= */ -/* UV4H_LB_PROC_INTD_SOFT_ACK_CLEAR */ +/* UVH_SCRATCH5_ALIAS */ /* ========================================================================= */ -#define UV4H_LB_PROC_INTD_SOFT_ACK_CLEAR 0xa4118UL +#define UVH_SCRATCH5_ALIAS ( \ + is_uv(UV5) ? 0xb0208UL : \ + is_uv(UV4) ? 0xb0208UL : \ + is_uv(UV3) ? 0x2d0208UL : \ + is_uv(UV2) ? 0x2d0208UL : \ + 0) +#define UV5H_SCRATCH5_ALIAS 0xb0208UL +#define UV4H_SCRATCH5_ALIAS 0xb0208UL +#define UV3H_SCRATCH5_ALIAS 0x2d0208UL +#define UV2H_SCRATCH5_ALIAS 0x2d0208UL -#define UV4H_LB_PROC_INTD_SOFT_ACK_CLEAR_SOFT_ACK_PENDING_FLAGS_SHFT 0 -#define UV4H_LB_PROC_INTD_SOFT_ACK_CLEAR_SOFT_ACK_PENDING_FLAGS_MASK 0x00000000000000ffUL - -union uv4h_lb_proc_intd_soft_ack_clear_u { - unsigned long v; - struct uv4h_lb_proc_intd_soft_ack_clear_s { - unsigned long soft_ack_pending_flags:8; /* WP */ - } s4; -}; /* ========================================================================= */ -/* UV4H_LB_PROC_INTD_SOFT_ACK_PENDING */ +/* UVH_SCRATCH5_ALIAS_2 */ /* ========================================================================= */ -#define UV4H_LB_PROC_INTD_SOFT_ACK_PENDING 0xa4110UL - -#define UV4H_LB_PROC_INTD_SOFT_ACK_PENDING_SOFT_ACK_FLAGS_SHFT 0 -#define UV4H_LB_PROC_INTD_SOFT_ACK_PENDING_SOFT_ACK_FLAGS_MASK 0x00000000000000ffUL +#define UVH_SCRATCH5_ALIAS_2 ( \ + is_uv(UV5) ? 0xb0210UL : \ + is_uv(UV4) ? 0xb0210UL : \ + is_uv(UV3) ? 0x2d0210UL : \ + is_uv(UV2) ? 0x2d0210UL : \ + 0) +#define UV5H_SCRATCH5_ALIAS_2 0xb0210UL +#define UV4H_SCRATCH5_ALIAS_2 0xb0210UL +#define UV3H_SCRATCH5_ALIAS_2 0x2d0210UL +#define UV2H_SCRATCH5_ALIAS_2 0x2d0210UL -union uv4h_lb_proc_intd_soft_ack_pending_u { - unsigned long v; - struct uv4h_lb_proc_intd_soft_ack_pending_s { - unsigned long soft_ack_flags:8; /* RW */ - } s4; -}; #endif /* _ASM_X86_UV_UV_MMRS_H */ diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index cd7de4b401fe..f8ba5289ecb0 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -52,7 +52,7 @@ #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES VMCS_CONTROL_BIT(VIRT_APIC_ACCESSES) #define SECONDARY_EXEC_ENABLE_EPT VMCS_CONTROL_BIT(EPT) #define SECONDARY_EXEC_DESC VMCS_CONTROL_BIT(DESC_EXITING) -#define SECONDARY_EXEC_RDTSCP VMCS_CONTROL_BIT(RDTSCP) +#define SECONDARY_EXEC_ENABLE_RDTSCP VMCS_CONTROL_BIT(RDTSCP) #define SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE VMCS_CONTROL_BIT(VIRTUAL_X2APIC) #define SECONDARY_EXEC_ENABLE_VPID VMCS_CONTROL_BIT(VPID) #define SECONDARY_EXEC_WBINVD_EXITING VMCS_CONTROL_BIT(WBINVD_EXITING) diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index 6807153c0410..dde5b3f1e7cd 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h @@ -4,29 +4,22 @@ #include <asm/bootparam.h> +struct ghcb; struct mpc_bus; struct mpc_cpu; +struct pt_regs; struct mpc_table; struct cpuinfo_x86; +struct irq_domain; /** * struct x86_init_mpparse - platform specific mpparse ops - * @mpc_record: platform specific mpc record accounting * @setup_ioapic_ids: platform specific ioapic id override - * @mpc_apic_id: platform specific mpc apic id assignment - * @smp_read_mpc_oem: platform specific oem mpc table setup - * @mpc_oem_pci_bus: platform specific pci bus setup (default NULL) - * @mpc_oem_bus_info: platform specific mpc bus info * @find_smp_config: find the smp configuration * @get_smp_config: get the smp configuration */ struct x86_init_mpparse { - void (*mpc_record)(unsigned int mode); void (*setup_ioapic_ids)(void); - int (*mpc_apic_id)(struct mpc_cpu *m); - void (*smp_read_mpc_oem)(struct mpc_table *mpc); - void (*mpc_oem_pci_bus)(struct mpc_bus *m); - void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name); void (*find_smp_config)(void); void (*get_smp_config)(unsigned int early); }; @@ -52,12 +45,14 @@ struct x86_init_resources { * @intr_init: interrupt init code * @intr_mode_select: interrupt delivery mode selection * @intr_mode_init: interrupt delivery mode setup + * @create_pci_msi_domain: Create the PCI/MSI interrupt domain */ struct x86_init_irqs { void (*pre_vector_init)(void); void (*intr_init)(void); void (*intr_mode_select)(void); void (*intr_mode_init)(void); + struct irq_domain *(*create_pci_msi_domain)(void); }; /** @@ -236,10 +231,22 @@ struct x86_legacy_features { /** * struct x86_hyper_runtime - x86 hypervisor specific runtime callbacks * - * @pin_vcpu: pin current vcpu to specified physical cpu (run rarely) + * @pin_vcpu: pin current vcpu to specified physical + * cpu (run rarely) + * @sev_es_hcall_prepare: Load additional hypervisor-specific + * state into the GHCB when doing a VMMCALL under + * SEV-ES. Called from the #VC exception handler. + * @sev_es_hcall_finish: Copies state from the GHCB back into the + * processor (or pt_regs). Also runs checks on the + * state returned from the hypervisor after a + * VMMCALL under SEV-ES. Needs to return 'false' + * if the checks fail. Called from the #VC + * exception handler. */ struct x86_hyper_runtime { void (*pin_vcpu)(int cpu); + void (*sev_es_hcall_prepare)(struct ghcb *ghcb, struct pt_regs *regs); + bool (*sev_es_hcall_finish)(struct ghcb *ghcb, struct pt_regs *regs); }; /** @@ -283,9 +290,6 @@ struct x86_platform_ops { struct pci_dev; struct x86_msi_ops { - int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type); - void (*teardown_msi_irq)(unsigned int irq); - void (*teardown_msi_irqs)(struct pci_dev *dev); void (*restore_msi_irqs)(struct pci_dev *dev); }; diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h index 0780f97c1850..89e5f3d1bba8 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -192,6 +192,26 @@ struct kvm_msr_list { __u32 indices[0]; }; +/* Maximum size of any access bitmap in bytes */ +#define KVM_MSR_FILTER_MAX_BITMAP_SIZE 0x600 + +/* for KVM_X86_SET_MSR_FILTER */ +struct kvm_msr_filter_range { +#define KVM_MSR_FILTER_READ (1 << 0) +#define KVM_MSR_FILTER_WRITE (1 << 1) + __u32 flags; + __u32 nmsrs; /* number of msrs in bitmap */ + __u32 base; /* MSR index the bitmap starts at */ + __u8 *bitmap; /* a 1 bit allows the operations in flags, 0 denies */ +}; + +#define KVM_MSR_FILTER_MAX_RANGES 16 +struct kvm_msr_filter { +#define KVM_MSR_FILTER_DEFAULT_ALLOW (0 << 0) +#define KVM_MSR_FILTER_DEFAULT_DENY (1 << 0) + __u32 flags; + struct kvm_msr_filter_range ranges[KVM_MSR_FILTER_MAX_RANGES]; +}; struct kvm_cpuid_entry { __u32 function; diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h index 2e8a30f06c74..f1d8307454e0 100644 --- a/arch/x86/include/uapi/asm/svm.h +++ b/arch/x86/include/uapi/asm/svm.h @@ -29,6 +29,7 @@ #define SVM_EXIT_WRITE_DR6 0x036 #define SVM_EXIT_WRITE_DR7 0x037 #define SVM_EXIT_EXCP_BASE 0x040 +#define SVM_EXIT_LAST_EXCP 0x05f #define SVM_EXIT_INTR 0x060 #define SVM_EXIT_NMI 0x061 #define SVM_EXIT_SMI 0x062 @@ -76,10 +77,21 @@ #define SVM_EXIT_MWAIT_COND 0x08c #define SVM_EXIT_XSETBV 0x08d #define SVM_EXIT_RDPRU 0x08e +#define SVM_EXIT_INVPCID 0x0a2 #define SVM_EXIT_NPF 0x400 #define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401 #define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402 +/* SEV-ES software-defined VMGEXIT events */ +#define SVM_VMGEXIT_MMIO_READ 0x80000001 +#define SVM_VMGEXIT_MMIO_WRITE 0x80000002 +#define SVM_VMGEXIT_NMI_COMPLETE 0x80000003 +#define SVM_VMGEXIT_AP_HLT_LOOP 0x80000004 +#define SVM_VMGEXIT_AP_JUMP_TABLE 0x80000005 +#define SVM_VMGEXIT_SET_AP_JUMP_TABLE 0 +#define SVM_VMGEXIT_GET_AP_JUMP_TABLE 1 +#define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff + #define SVM_EXIT_ERR -1 #define SVM_EXIT_REASONS \ @@ -171,6 +183,7 @@ { SVM_EXIT_MONITOR, "monitor" }, \ { SVM_EXIT_MWAIT, "mwait" }, \ { SVM_EXIT_XSETBV, "xsetbv" }, \ + { SVM_EXIT_INVPCID, "invpcid" }, \ { SVM_EXIT_NPF, "npf" }, \ { SVM_EXIT_AVIC_INCOMPLETE_IPI, "avic_incomplete_ipi" }, \ { SVM_EXIT_AVIC_UNACCELERATED_ACCESS, "avic_unaccelerated_access" }, \ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index e77261db2391..68608bd892c0 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -20,6 +20,7 @@ CFLAGS_REMOVE_kvmclock.o = -pg CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_early_printk.o = -pg CFLAGS_REMOVE_head64.o = -pg +CFLAGS_REMOVE_sev-es.o = -pg endif KASAN_SANITIZE_head$(BITS).o := n @@ -27,6 +28,7 @@ KASAN_SANITIZE_dumpstack.o := n KASAN_SANITIZE_dumpstack_$(BITS).o := n KASAN_SANITIZE_stacktrace.o := n KASAN_SANITIZE_paravirt.o := n +KASAN_SANITIZE_sev-es.o := n # With some compiler versions the generated code results in boot hangs, caused # by several compilation units. To be safe, disable all instrumentation. @@ -45,6 +47,8 @@ endif # non-deterministic coverage. KCOV_INSTRUMENT := n +CFLAGS_head$(BITS).o += -fno-stack-protector + CFLAGS_irq.o := -I $(srctree)/$(src)/../include/asm/trace obj-y := process_$(BITS).o signal.o @@ -68,6 +72,7 @@ obj-y += tsc.o tsc_msr.o io_delay.o rtc.o obj-y += pci-iommu_table.o obj-y += resource.o obj-y += irqflags.o +obj-y += static_call.o obj-y += process.o obj-y += fpu/ @@ -145,6 +150,7 @@ obj-$(CONFIG_UNWINDER_ORC) += unwind_orc.o obj-$(CONFIG_UNWINDER_FRAME_POINTER) += unwind_frame.o obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o +obj-$(CONFIG_AMD_MEM_ENCRYPT) += sev-es.o ### # 64 bit specific files ifeq ($(CONFIG_X86_64),y) diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index cdaab30880b9..4adbe65afe23 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -1103,6 +1103,10 @@ noinstr int poke_int3_handler(struct pt_regs *regs) */ goto out_put; + case RET_INSN_OPCODE: + int3_emulate_ret(regs); + break; + case CALL_INSN_OPCODE: int3_emulate_call(regs, (long)ip + tp->rel32); break; @@ -1277,6 +1281,7 @@ static void text_poke_loc_init(struct text_poke_loc *tp, void *addr, switch (tp->opcode) { case INT3_INSN_OPCODE: + case RET_INSN_OPCODE: break; case CALL_INSN_OPCODE: diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c index e89031e9c847..9ac696487b13 100644 --- a/arch/x86/kernel/amd_gart_64.c +++ b/arch/x86/kernel/amd_gart_64.c @@ -32,6 +32,7 @@ #include <linux/gfp.h> #include <linux/atomic.h> #include <linux/dma-direct.h> +#include <linux/dma-map-ops.h> #include <asm/mtrr.h> #include <asm/proto.h> #include <asm/iommu.h> @@ -96,8 +97,7 @@ static unsigned long alloc_iommu(struct device *dev, int size, base_index = ALIGN(iommu_bus_base & dma_get_seg_boundary(dev), PAGE_SIZE) >> PAGE_SHIFT; - boundary_size = ALIGN((u64)dma_get_seg_boundary(dev) + 1, - PAGE_SIZE) >> PAGE_SHIFT; + boundary_size = dma_get_seg_boundary_nr_pages(dev, PAGE_SHIFT); spin_lock_irqsave(&iommu_bitmap_lock, flags); offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, next_bit, @@ -468,7 +468,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, { void *vaddr; - vaddr = dma_direct_alloc_pages(dev, size, dma_addr, flag, attrs); + vaddr = dma_direct_alloc(dev, size, dma_addr, flag, attrs); if (!vaddr || !force_iommu || dev->coherent_dma_mask <= DMA_BIT_MASK(24)) return vaddr; @@ -480,7 +480,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, goto out_free; return vaddr; out_free: - dma_direct_free_pages(dev, size, vaddr, *dma_addr, attrs); + dma_direct_free(dev, size, vaddr, *dma_addr, attrs); return NULL; } @@ -490,7 +490,7 @@ gart_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_addr, unsigned long attrs) { gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, 0); - dma_direct_free_pages(dev, size, vaddr, dma_addr, attrs); + dma_direct_free(dev, size, vaddr, dma_addr, attrs); } static int no_agp; @@ -678,6 +678,8 @@ static const struct dma_map_ops gart_dma_ops = { .get_sgtable = dma_common_get_sgtable, .dma_supported = dma_direct_supported, .get_required_mask = dma_direct_get_required_mask, + .alloc_pages = dma_direct_alloc_pages, + .free_pages = dma_direct_free_pages, }; static void gart_iommu_shutdown(void) diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 5f943b938167..b3eef1d5c903 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1429,6 +1429,9 @@ void __init apic_intr_mode_init(void) break; } + if (x86_platform.apic_post_init) + x86_platform.apic_post_init(); + apic_bsp_setup(upmode); } diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 779a89e31c4c..7b3c7e0d4a09 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -860,10 +860,10 @@ void ioapic_set_alloc_attr(struct irq_alloc_info *info, int node, { init_irq_alloc_info(info, NULL); info->type = X86_IRQ_ALLOC_TYPE_IOAPIC; - info->ioapic_node = node; - info->ioapic_trigger = trigger; - info->ioapic_polarity = polarity; - info->ioapic_valid = 1; + info->ioapic.node = node; + info->ioapic.trigger = trigger; + info->ioapic.polarity = polarity; + info->ioapic.valid = 1; } #ifndef CONFIG_ACPI @@ -878,32 +878,32 @@ static void ioapic_copy_alloc_attr(struct irq_alloc_info *dst, copy_irq_alloc_info(dst, src); dst->type = X86_IRQ_ALLOC_TYPE_IOAPIC; - dst->ioapic_id = mpc_ioapic_id(ioapic_idx); - dst->ioapic_pin = pin; - dst->ioapic_valid = 1; - if (src && src->ioapic_valid) { - dst->ioapic_node = src->ioapic_node; - dst->ioapic_trigger = src->ioapic_trigger; - dst->ioapic_polarity = src->ioapic_polarity; + dst->devid = mpc_ioapic_id(ioapic_idx); + dst->ioapic.pin = pin; + dst->ioapic.valid = 1; + if (src && src->ioapic.valid) { + dst->ioapic.node = src->ioapic.node; + dst->ioapic.trigger = src->ioapic.trigger; + dst->ioapic.polarity = src->ioapic.polarity; } else { - dst->ioapic_node = NUMA_NO_NODE; + dst->ioapic.node = NUMA_NO_NODE; if (acpi_get_override_irq(gsi, &trigger, &polarity) >= 0) { - dst->ioapic_trigger = trigger; - dst->ioapic_polarity = polarity; + dst->ioapic.trigger = trigger; + dst->ioapic.polarity = polarity; } else { /* * PCI interrupts are always active low level * triggered. */ - dst->ioapic_trigger = IOAPIC_LEVEL; - dst->ioapic_polarity = IOAPIC_POL_LOW; + dst->ioapic.trigger = IOAPIC_LEVEL; + dst->ioapic.polarity = IOAPIC_POL_LOW; } } } static int ioapic_alloc_attr_node(struct irq_alloc_info *info) { - return (info && info->ioapic_valid) ? info->ioapic_node : NUMA_NO_NODE; + return (info && info->ioapic.valid) ? info->ioapic.node : NUMA_NO_NODE; } static void mp_register_handler(unsigned int irq, unsigned long trigger) @@ -933,14 +933,14 @@ static bool mp_check_pin_attr(int irq, struct irq_alloc_info *info) * pin with real trigger and polarity attributes. */ if (irq < nr_legacy_irqs() && data->count == 1) { - if (info->ioapic_trigger != data->trigger) - mp_register_handler(irq, info->ioapic_trigger); - data->entry.trigger = data->trigger = info->ioapic_trigger; - data->entry.polarity = data->polarity = info->ioapic_polarity; + if (info->ioapic.trigger != data->trigger) + mp_register_handler(irq, info->ioapic.trigger); + data->entry.trigger = data->trigger = info->ioapic.trigger; + data->entry.polarity = data->polarity = info->ioapic.polarity; } - return data->trigger == info->ioapic_trigger && - data->polarity == info->ioapic_polarity; + return data->trigger == info->ioapic.trigger && + data->polarity == info->ioapic.polarity; } static int alloc_irq_from_domain(struct irq_domain *domain, int ioapic, u32 gsi, @@ -1002,7 +1002,7 @@ static int alloc_isa_irq_from_domain(struct irq_domain *domain, if (!mp_check_pin_attr(irq, info)) return -EBUSY; if (__add_pin_to_irq_node(irq_data->chip_data, node, ioapic, - info->ioapic_pin)) + info->ioapic.pin)) return -ENOMEM; } else { info->flags |= X86_IRQ_ALLOC_LEGACY; @@ -2092,8 +2092,8 @@ static int mp_alloc_timer_irq(int ioapic, int pin) struct irq_alloc_info info; ioapic_set_alloc_attr(&info, NUMA_NO_NODE, 0, 0); - info.ioapic_id = mpc_ioapic_id(ioapic); - info.ioapic_pin = pin; + info.devid = mpc_ioapic_id(ioapic); + info.ioapic.pin = pin; mutex_lock(&ioapic_mutex); irq = alloc_isa_irq_from_domain(domain, 0, ioapic, pin, &info); mutex_unlock(&ioapic_mutex); @@ -2243,6 +2243,7 @@ static inline void __init check_timer(void) legacy_pic->init(0); legacy_pic->make_irq(0); apic_write(APIC_LVT0, APIC_DM_EXTINT); + legacy_pic->unmask(0); unlock_ExtINT_logic(); @@ -2296,9 +2297,9 @@ static int mp_irqdomain_create(int ioapic) return 0; init_irq_alloc_info(&info, NULL); - info.type = X86_IRQ_ALLOC_TYPE_IOAPIC; - info.ioapic_id = mpc_ioapic_id(ioapic); - parent = irq_remapping_get_ir_irq_domain(&info); + info.type = X86_IRQ_ALLOC_TYPE_IOAPIC_GET_PARENT; + info.devid = mpc_ioapic_id(ioapic); + parent = irq_remapping_get_irq_domain(&info); if (!parent) parent = x86_vector_domain; else @@ -2932,9 +2933,9 @@ int mp_ioapic_registered(u32 gsi_base) static void mp_irqdomain_get_attr(u32 gsi, struct mp_chip_data *data, struct irq_alloc_info *info) { - if (info && info->ioapic_valid) { - data->trigger = info->ioapic_trigger; - data->polarity = info->ioapic_polarity; + if (info && info->ioapic.valid) { + data->trigger = info->ioapic.trigger; + data->polarity = info->ioapic.polarity; } else if (acpi_get_override_irq(gsi, &data->trigger, &data->polarity) < 0) { /* PCI interrupts are always active low level triggered. */ @@ -2980,7 +2981,7 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, return -EINVAL; ioapic = mp_irqdomain_ioapic_idx(domain); - pin = info->ioapic_pin; + pin = info->ioapic.pin; if (irq_find_mapping(domain, (irq_hw_number_t)pin) > 0) return -EEXIST; @@ -2988,7 +2989,7 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, if (!data) return -ENOMEM; - info->ioapic_entry = &data->entry; + info->ioapic.entry = &data->entry; ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, info); if (ret < 0) { kfree(data); @@ -2996,7 +2997,7 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, } INIT_LIST_HEAD(&data->irq_2_pin); - irq_data->hwirq = info->ioapic_pin; + irq_data->hwirq = info->ioapic.pin; irq_data->chip = (domain->parent == x86_vector_domain) ? &ioapic_chip : &ioapic_ir_chip; irq_data->chip_data = data; @@ -3006,8 +3007,8 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin); local_irq_save(flags); - if (info->ioapic_entry) - mp_setup_entry(cfg, data, info->ioapic_entry); + if (info->ioapic.entry) + mp_setup_entry(cfg, data, info->ioapic.entry); mp_register_handler(virq, data->trigger); if (virq < nr_legacy_irqs()) legacy_pic->mask(virq); diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c index c2b2911feeef..6313f0a05db7 100644 --- a/arch/x86/kernel/apic/msi.c +++ b/arch/x86/kernel/apic/msi.c @@ -21,7 +21,7 @@ #include <asm/apic.h> #include <asm/irq_remapping.h> -static struct irq_domain *msi_default_domain; +struct irq_domain *x86_pci_msi_default_domain __ro_after_init; static void __irq_msi_compose_msg(struct irq_cfg *cfg, struct msi_msg *msg) { @@ -45,7 +45,7 @@ static void __irq_msi_compose_msg(struct irq_cfg *cfg, struct msi_msg *msg) MSI_DATA_VECTOR(cfg->vector); } -static void irq_msi_compose_msg(struct irq_data *data, struct msi_msg *msg) +void x86_vector_msi_compose_msg(struct irq_data *data, struct msi_msg *msg) { __irq_msi_compose_msg(irqd_cfg(data), msg); } @@ -177,40 +177,10 @@ static struct irq_chip pci_msi_controller = { .irq_mask = pci_msi_mask_irq, .irq_ack = irq_chip_ack_parent, .irq_retrigger = irq_chip_retrigger_hierarchy, - .irq_compose_msi_msg = irq_msi_compose_msg, .irq_set_affinity = msi_set_affinity, .flags = IRQCHIP_SKIP_SET_WAKE, }; -int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) -{ - struct irq_domain *domain; - struct irq_alloc_info info; - - init_irq_alloc_info(&info, NULL); - info.type = X86_IRQ_ALLOC_TYPE_MSI; - info.msi_dev = dev; - - domain = irq_remapping_get_irq_domain(&info); - if (domain == NULL) - domain = msi_default_domain; - if (domain == NULL) - return -ENOSYS; - - return msi_domain_alloc_irqs(domain, &dev->dev, nvec); -} - -void native_teardown_msi_irq(unsigned int irq) -{ - irq_domain_free_irqs(irq, 1); -} - -static irq_hw_number_t pci_msi_get_hwirq(struct msi_domain_info *info, - msi_alloc_info_t *arg) -{ - return arg->msi_hwirq; -} - int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec, msi_alloc_info_t *arg) { @@ -218,11 +188,10 @@ int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec, struct msi_desc *desc = first_pci_msi_entry(pdev); init_irq_alloc_info(arg, NULL); - arg->msi_dev = pdev; if (desc->msi_attrib.is_msix) { - arg->type = X86_IRQ_ALLOC_TYPE_MSIX; + arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSIX; } else { - arg->type = X86_IRQ_ALLOC_TYPE_MSI; + arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSI; arg->flags |= X86_IRQ_ALLOC_CONTIGUOUS_VECTORS; } @@ -230,16 +199,8 @@ int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec, } EXPORT_SYMBOL_GPL(pci_msi_prepare); -void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc) -{ - arg->msi_hwirq = pci_msi_domain_calc_hwirq(arg->msi_dev, desc); -} -EXPORT_SYMBOL_GPL(pci_msi_set_desc); - static struct msi_domain_ops pci_msi_domain_ops = { - .get_hwirq = pci_msi_get_hwirq, .msi_prepare = pci_msi_prepare, - .set_desc = pci_msi_set_desc, }; static struct msi_domain_info pci_msi_domain_info = { @@ -251,25 +212,32 @@ static struct msi_domain_info pci_msi_domain_info = { .handler_name = "edge", }; -void __init arch_init_msi_domain(struct irq_domain *parent) +struct irq_domain * __init native_create_pci_msi_domain(void) { struct fwnode_handle *fn; + struct irq_domain *d; if (disable_apic) - return; + return NULL; fn = irq_domain_alloc_named_fwnode("PCI-MSI"); - if (fn) { - msi_default_domain = - pci_msi_create_irq_domain(fn, &pci_msi_domain_info, - parent); - } - if (!msi_default_domain) { + if (!fn) + return NULL; + + d = pci_msi_create_irq_domain(fn, &pci_msi_domain_info, + x86_vector_domain); + if (!d) { irq_domain_free_fwnode(fn); - pr_warn("failed to initialize irqdomain for MSI/MSI-x.\n"); + pr_warn("Failed to initialize PCI-MSI irqdomain.\n"); } else { - msi_default_domain->flags |= IRQ_DOMAIN_MSI_NOMASK_QUIRK; + d->flags |= IRQ_DOMAIN_MSI_NOMASK_QUIRK; } + return d; +} + +void __init x86_create_pci_msi_domain(void) +{ + x86_pci_msi_default_domain = x86_init.irqs.create_pci_msi_domain(); } #ifdef CONFIG_IRQ_REMAP @@ -279,7 +247,6 @@ static struct irq_chip pci_msi_ir_controller = { .irq_mask = pci_msi_mask_irq, .irq_ack = irq_chip_ack_parent, .irq_retrigger = irq_chip_retrigger_hierarchy, - .irq_set_vcpu_affinity = irq_chip_set_vcpu_affinity_parent, .flags = IRQCHIP_SKIP_SET_WAKE, }; @@ -321,35 +288,28 @@ static struct irq_chip dmar_msi_controller = { .irq_ack = irq_chip_ack_parent, .irq_set_affinity = msi_domain_set_affinity, .irq_retrigger = irq_chip_retrigger_hierarchy, - .irq_compose_msi_msg = irq_msi_compose_msg, .irq_write_msi_msg = dmar_msi_write_msg, .flags = IRQCHIP_SKIP_SET_WAKE, }; -static irq_hw_number_t dmar_msi_get_hwirq(struct msi_domain_info *info, - msi_alloc_info_t *arg) -{ - return arg->dmar_id; -} - static int dmar_msi_init(struct irq_domain *domain, struct msi_domain_info *info, unsigned int virq, irq_hw_number_t hwirq, msi_alloc_info_t *arg) { - irq_domain_set_info(domain, virq, arg->dmar_id, info->chip, NULL, - handle_edge_irq, arg->dmar_data, "edge"); + irq_domain_set_info(domain, virq, arg->devid, info->chip, NULL, + handle_edge_irq, arg->data, "edge"); return 0; } static struct msi_domain_ops dmar_msi_domain_ops = { - .get_hwirq = dmar_msi_get_hwirq, .msi_init = dmar_msi_init, }; static struct msi_domain_info dmar_msi_domain_info = { .ops = &dmar_msi_domain_ops, .chip = &dmar_msi_controller, + .flags = MSI_FLAG_USE_DEF_DOM_OPS, }; static struct irq_domain *dmar_get_irq_domain(void) @@ -384,8 +344,9 @@ int dmar_alloc_hwirq(int id, int node, void *arg) init_irq_alloc_info(&info, NULL); info.type = X86_IRQ_ALLOC_TYPE_DMAR; - info.dmar_id = id; - info.dmar_data = arg; + info.devid = id; + info.hwirq = id; + info.data = arg; return irq_domain_alloc_irqs(domain, 1, node, &info); } @@ -419,24 +380,17 @@ static struct irq_chip hpet_msi_controller __ro_after_init = { .irq_ack = irq_chip_ack_parent, .irq_set_affinity = msi_domain_set_affinity, .irq_retrigger = irq_chip_retrigger_hierarchy, - .irq_compose_msi_msg = irq_msi_compose_msg, .irq_write_msi_msg = hpet_msi_write_msg, .flags = IRQCHIP_SKIP_SET_WAKE, }; -static irq_hw_number_t hpet_msi_get_hwirq(struct msi_domain_info *info, - msi_alloc_info_t *arg) -{ - return arg->hpet_index; -} - static int hpet_msi_init(struct irq_domain *domain, struct msi_domain_info *info, unsigned int virq, irq_hw_number_t hwirq, msi_alloc_info_t *arg) { irq_set_status_flags(virq, IRQ_MOVE_PCNTXT); - irq_domain_set_info(domain, virq, arg->hpet_index, info->chip, NULL, - handle_edge_irq, arg->hpet_data, "edge"); + irq_domain_set_info(domain, virq, arg->hwirq, info->chip, NULL, + handle_edge_irq, arg->data, "edge"); return 0; } @@ -448,7 +402,6 @@ static void hpet_msi_free(struct irq_domain *domain, } static struct msi_domain_ops hpet_msi_domain_ops = { - .get_hwirq = hpet_msi_get_hwirq, .msi_init = hpet_msi_init, .msi_free = hpet_msi_free, }; @@ -456,6 +409,7 @@ static struct msi_domain_ops hpet_msi_domain_ops = { static struct msi_domain_info hpet_msi_domain_info = { .ops = &hpet_msi_domain_ops, .chip = &hpet_msi_controller, + .flags = MSI_FLAG_USE_DEF_DOM_OPS, }; struct irq_domain *hpet_create_irq_domain(int hpet_id) @@ -476,9 +430,9 @@ struct irq_domain *hpet_create_irq_domain(int hpet_id) domain_info->data = (void *)(long)hpet_id; init_irq_alloc_info(&info, NULL); - info.type = X86_IRQ_ALLOC_TYPE_HPET; - info.hpet_id = hpet_id; - parent = irq_remapping_get_ir_irq_domain(&info); + info.type = X86_IRQ_ALLOC_TYPE_HPET_GET_PARENT; + info.devid = hpet_id; + parent = irq_remapping_get_irq_domain(&info); if (parent == NULL) parent = x86_vector_domain; else @@ -506,9 +460,9 @@ int hpet_assign_irq(struct irq_domain *domain, struct hpet_channel *hc, init_irq_alloc_info(&info, NULL); info.type = X86_IRQ_ALLOC_TYPE_HPET; - info.hpet_data = hc; - info.hpet_id = hpet_dev_id(domain); - info.hpet_index = dev_num; + info.data = hc; + info.devid = hpet_dev_id(domain); + info.hwirq = dev_num; return irq_domain_alloc_irqs(domain, 1, NUMA_NO_NODE, &info); } diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 99ee61c9ba54..67b6f7c049ec 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -170,9 +170,6 @@ void __init default_setup_apic_routing(void) if (apic->setup_apic_routing) apic->setup_apic_routing(); - - if (x86_platform.apic_post_init) - x86_platform.apic_post_init(); } void __init generic_apic_probe(void) diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index bd3835d6b535..c46720f185c0 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c @@ -32,9 +32,6 @@ void __init default_setup_apic_routing(void) break; } } - - if (x86_platform.apic_post_init) - x86_platform.apic_post_init(); } int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id) diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index f8a56b5dc29f..1eac53632786 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c @@ -714,8 +714,6 @@ int __init arch_early_irq_init(void) BUG_ON(x86_vector_domain == NULL); irq_set_default_host(x86_vector_domain); - arch_init_msi_domain(x86_vector_domain); - BUG_ON(!alloc_cpumask_var(&vector_searchmask, GFP_KERNEL)); /* @@ -824,6 +822,7 @@ static struct irq_chip lapic_controller = { .name = "APIC", .irq_ack = apic_ack_edge, .irq_set_affinity = apic_set_affinity, + .irq_compose_msi_msg = x86_vector_msi_compose_msg, .irq_retrigger = apic_retrigger_irq, }; diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 0b6eea3f54e6..714233cee0b5 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -5,6 +5,7 @@ * * SGI UV APIC functions (note: not an Intel compatible APIC) * + * (C) Copyright 2020 Hewlett Packard Enterprise Development LP * Copyright (C) 2007-2014 Silicon Graphics, Inc. All rights reserved. */ #include <linux/crash_dump.h> @@ -29,19 +30,24 @@ static int uv_hubbed_system; static int uv_hubless_system; static u64 gru_start_paddr, gru_end_paddr; static union uvh_apicid uvh_apicid; +static int uv_node_id; -/* Unpack OEM/TABLE ID's to be NULL terminated strings */ +/* Unpack AT/OEM/TABLE ID's to be NULL terminated strings */ +static u8 uv_archtype[UV_AT_SIZE]; static u8 oem_id[ACPI_OEM_ID_SIZE + 1]; static u8 oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; -/* Information derived from CPUID: */ +/* Information derived from CPUID and some UV MMRs */ static struct { unsigned int apicid_shift; unsigned int apicid_mask; unsigned int socketid_shift; /* aka pnode_shift for UV2/3 */ unsigned int pnode_mask; + unsigned int nasid_shift; unsigned int gpa_shift; unsigned int gnode_shift; + unsigned int m_skt; + unsigned int n_skt; } uv_cpuid; static int uv_min_hub_revision_id; @@ -77,6 +83,9 @@ static unsigned long __init uv_early_read_mmr(unsigned long addr) static inline bool is_GRU_range(u64 start, u64 end) { + if (!gru_start_paddr) + return false; + return start >= gru_start_paddr && end <= gru_end_paddr; } @@ -85,43 +94,102 @@ static bool uv_is_untracked_pat_range(u64 start, u64 end) return is_ISA_range(start, end) || is_GRU_range(start, end); } -static int __init early_get_pnodeid(void) +static void __init early_get_pnodeid(void) { - union uvh_node_id_u node_id; - union uvh_rh_gam_config_mmr_u m_n_config; int pnode; - /* Currently, all blades have same revision number */ + uv_cpuid.m_skt = 0; + if (UVH_RH10_GAM_ADDR_MAP_CONFIG) { + union uvh_rh10_gam_addr_map_config_u m_n_config; + + m_n_config.v = uv_early_read_mmr(UVH_RH10_GAM_ADDR_MAP_CONFIG); + uv_cpuid.n_skt = m_n_config.s.n_skt; + uv_cpuid.nasid_shift = 0; + } else if (UVH_RH_GAM_ADDR_MAP_CONFIG) { + union uvh_rh_gam_addr_map_config_u m_n_config; + + m_n_config.v = uv_early_read_mmr(UVH_RH_GAM_ADDR_MAP_CONFIG); + uv_cpuid.n_skt = m_n_config.s.n_skt; + if (is_uv(UV3)) + uv_cpuid.m_skt = m_n_config.s3.m_skt; + if (is_uv(UV2)) + uv_cpuid.m_skt = m_n_config.s2.m_skt; + uv_cpuid.nasid_shift = 1; + } else { + unsigned long GAM_ADDR_MAP_CONFIG = 0; + + WARN(GAM_ADDR_MAP_CONFIG == 0, + "UV: WARN: GAM_ADDR_MAP_CONFIG is not available\n"); + uv_cpuid.n_skt = 0; + uv_cpuid.nasid_shift = 0; + } + + if (is_uv(UV4|UVY)) + uv_cpuid.gnode_shift = 2; /* min partition is 4 sockets */ + + uv_cpuid.pnode_mask = (1 << uv_cpuid.n_skt) - 1; + pnode = (uv_node_id >> uv_cpuid.nasid_shift) & uv_cpuid.pnode_mask; + uv_cpuid.gpa_shift = 46; /* Default unless changed */ + + pr_info("UV: n_skt:%d pnmsk:%x pn:%x\n", + uv_cpuid.n_skt, uv_cpuid.pnode_mask, pnode); +} + +/* Running on a UV Hubbed system, determine which UV Hub Type it is */ +static int __init early_set_hub_type(void) +{ + union uvh_node_id_u node_id; + + /* + * The NODE_ID MMR is always at offset 0. + * Contains the chip part # + revision. + * Node_id field started with 15 bits, + * ... now 7 but upper 8 are masked to 0. + * All blades/nodes have the same part # and hub revision. + */ node_id.v = uv_early_read_mmr(UVH_NODE_ID); - m_n_config.v = uv_early_read_mmr(UVH_RH_GAM_CONFIG_MMR); - uv_min_hub_revision_id = node_id.s.revision; + uv_node_id = node_id.sx.node_id; switch (node_id.s.part_number) { - case UV2_HUB_PART_NUMBER: - case UV2_HUB_PART_NUMBER_X: - uv_min_hub_revision_id += UV2_HUB_REVISION_BASE - 1; + + case UV5_HUB_PART_NUMBER: + uv_min_hub_revision_id = node_id.s.revision + + UV5_HUB_REVISION_BASE; + uv_hub_type_set(UV5); break; + + /* UV4/4A only have a revision difference */ + case UV4_HUB_PART_NUMBER: + uv_min_hub_revision_id = node_id.s.revision + + UV4_HUB_REVISION_BASE; + uv_hub_type_set(UV4); + if (uv_min_hub_revision_id == UV4A_HUB_REVISION_BASE) + uv_hub_type_set(UV4|UV4A); + break; + case UV3_HUB_PART_NUMBER: case UV3_HUB_PART_NUMBER_X: - uv_min_hub_revision_id += UV3_HUB_REVISION_BASE; + uv_min_hub_revision_id = node_id.s.revision + + UV3_HUB_REVISION_BASE; + uv_hub_type_set(UV3); break; - /* Update: UV4A has only a modified revision to indicate HUB fixes */ - case UV4_HUB_PART_NUMBER: - uv_min_hub_revision_id += UV4_HUB_REVISION_BASE - 1; - uv_cpuid.gnode_shift = 2; /* min partition is 4 sockets */ + case UV2_HUB_PART_NUMBER: + case UV2_HUB_PART_NUMBER_X: + uv_min_hub_revision_id = node_id.s.revision + + UV2_HUB_REVISION_BASE - 1; + uv_hub_type_set(UV2); break; + + default: + return 0; } - uv_hub_info->hub_revision = uv_min_hub_revision_id; - uv_cpuid.pnode_mask = (1 << m_n_config.s.n_skt) - 1; - pnode = (node_id.s.node_id >> 1) & uv_cpuid.pnode_mask; - uv_cpuid.gpa_shift = 46; /* Default unless changed */ + pr_info("UV: part#:%x rev:%d rev_id:%d UVtype:0x%x\n", + node_id.s.part_number, node_id.s.revision, + uv_min_hub_revision_id, is_uv(~0)); - pr_info("UV: rev:%d part#:%x nodeid:%04x n_skt:%d pnmsk:%x pn:%x\n", - node_id.s.revision, node_id.s.part_number, node_id.s.node_id, - m_n_config.s.n_skt, uv_cpuid.pnode_mask, pnode); - return pnode; + return 1; } static void __init uv_tsc_check_sync(void) @@ -130,38 +198,41 @@ static void __init uv_tsc_check_sync(void) int sync_state; int mmr_shift; char *state; - bool valid; - /* Accommodate different UV arch BIOSes */ + /* Different returns from different UV BIOS versions */ mmr = uv_early_read_mmr(UVH_TSC_SYNC_MMR); mmr_shift = is_uv2_hub() ? UVH_TSC_SYNC_SHIFT_UV2K : UVH_TSC_SYNC_SHIFT; sync_state = (mmr >> mmr_shift) & UVH_TSC_SYNC_MASK; + /* Check if TSC is valid for all sockets */ switch (sync_state) { case UVH_TSC_SYNC_VALID: state = "in sync"; - valid = true; + mark_tsc_async_resets("UV BIOS"); break; - case UVH_TSC_SYNC_INVALID: - state = "unstable"; - valid = false; + /* If BIOS state unknown, don't do anything */ + case UVH_TSC_SYNC_UNKNOWN: + state = "unknown"; break; + + /* Otherwise, BIOS indicates problem with TSC */ default: - state = "unknown: assuming valid"; - valid = true; + state = "unstable"; + mark_tsc_unstable("UV BIOS"); break; } pr_info("UV: TSC sync state from BIOS:0%d(%s)\n", sync_state, state); - - /* Mark flag that says TSC != 0 is valid for socket 0 */ - if (valid) - mark_tsc_async_resets("UV BIOS"); - else - mark_tsc_unstable("UV BIOS"); } +/* Selector for (4|4A|5) structs */ +#define uvxy_field(sname, field, undef) ( \ + is_uv(UV4A) ? sname.s4a.field : \ + is_uv(UV4) ? sname.s4.field : \ + is_uv(UV3) ? sname.s3.field : \ + undef) + /* [Copied from arch/x86/kernel/cpu/topology.c:detect_extended_topology()] */ #define SMT_LEVEL 0 /* Leaf 0xb SMT level */ @@ -221,29 +292,110 @@ static void __init uv_stringify(int len, char *to, char *from) strncpy(to, from, len-1); } -static int __init uv_acpi_madt_oem_check(char *_oem_id, char *_oem_table_id) +/* Find UV arch type entry in UVsystab */ +static unsigned long __init early_find_archtype(struct uv_systab *st) +{ + int i; + + for (i = 0; st->entry[i].type != UV_SYSTAB_TYPE_UNUSED; i++) { + unsigned long ptr = st->entry[i].offset; + + if (!ptr) + continue; + ptr += (unsigned long)st; + if (st->entry[i].type == UV_SYSTAB_TYPE_ARCH_TYPE) + return ptr; + } + return 0; +} + +/* Validate UV arch type field in UVsystab */ +static int __init decode_arch_type(unsigned long ptr) +{ + struct uv_arch_type_entry *uv_ate = (struct uv_arch_type_entry *)ptr; + int n = strlen(uv_ate->archtype); + + if (n > 0 && n < sizeof(uv_ate->archtype)) { + pr_info("UV: UVarchtype received from BIOS\n"); + uv_stringify(UV_AT_SIZE, uv_archtype, uv_ate->archtype); + return 1; + } + return 0; +} + +/* Determine if UV arch type entry might exist in UVsystab */ +static int __init early_get_arch_type(void) { - int pnodeid; - int uv_apic; + unsigned long uvst_physaddr, uvst_size, ptr; + struct uv_systab *st; + u32 rev; + int ret; + + uvst_physaddr = get_uv_systab_phys(0); + if (!uvst_physaddr) + return 0; + + st = early_memremap_ro(uvst_physaddr, sizeof(struct uv_systab)); + if (!st) { + pr_err("UV: Cannot access UVsystab, remap failed\n"); + return 0; + } + rev = st->revision; + if (rev < UV_SYSTAB_VERSION_UV5) { + early_memunmap(st, sizeof(struct uv_systab)); + return 0; + } + + uvst_size = st->size; + early_memunmap(st, sizeof(struct uv_systab)); + st = early_memremap_ro(uvst_physaddr, uvst_size); + if (!st) { + pr_err("UV: Cannot access UVarchtype, remap failed\n"); + return 0; + } + + ptr = early_find_archtype(st); + if (!ptr) { + early_memunmap(st, uvst_size); + return 0; + } + + ret = decode_arch_type(ptr); + early_memunmap(st, uvst_size); + return ret; +} + +static int __init uv_set_system_type(char *_oem_id) +{ + /* Save OEM_ID passed from ACPI MADT */ uv_stringify(sizeof(oem_id), oem_id, _oem_id); - uv_stringify(sizeof(oem_table_id), oem_table_id, _oem_table_id); - if (strncmp(oem_id, "SGI", 3) != 0) { - if (strncmp(oem_id, "NSGI", 4) != 0) + /* Check if BIOS sent us a UVarchtype */ + if (!early_get_arch_type()) + + /* If not use OEM ID for UVarchtype */ + uv_stringify(UV_AT_SIZE, uv_archtype, _oem_id); + + /* Check if not hubbed */ + if (strncmp(uv_archtype, "SGI", 3) != 0) { + + /* (Not hubbed), check if not hubless */ + if (strncmp(uv_archtype, "NSGI", 4) != 0) + + /* (Not hubless), not a UV */ return 0; - /* UV4 Hubless, CH, (0x11:UV4+Any) */ - if (strncmp(oem_id, "NSGI4", 5) == 0) + /* UV4 Hubless: CH */ + if (strncmp(uv_archtype, "NSGI4", 5) == 0) uv_hubless_system = 0x11; - /* UV3 Hubless, UV300/MC990X w/o hub (0x9:UV3+Any) */ + /* UV3 Hubless: UV300/MC990X w/o hub */ else uv_hubless_system = 0x9; - pr_info("UV: OEM IDs %s/%s, HUBLESS(0x%x)\n", - oem_id, oem_table_id, uv_hubless_system); - + pr_info("UV: OEM IDs %s/%s, SystemType %d, HUBLESS ID %x\n", + oem_id, oem_table_id, uv_system_type, uv_hubless_system); return 0; } @@ -252,60 +404,83 @@ static int __init uv_acpi_madt_oem_check(char *_oem_id, char *_oem_table_id) return 0; } - /* Set up early hub type field in uv_hub_info for Node 0 */ - uv_cpu_info->p_uv_hub_info = &uv_hub_info_node0; + /* Set hubbed type if true */ + uv_hub_info->hub_revision = + !strncmp(uv_archtype, "SGI5", 4) ? UV5_HUB_REVISION_BASE : + !strncmp(uv_archtype, "SGI4", 4) ? UV4_HUB_REVISION_BASE : + !strncmp(uv_archtype, "SGI3", 4) ? UV3_HUB_REVISION_BASE : + !strcmp(uv_archtype, "SGI2") ? UV2_HUB_REVISION_BASE : 0; + + switch (uv_hub_info->hub_revision) { + case UV5_HUB_REVISION_BASE: + uv_hubbed_system = 0x21; + uv_hub_type_set(UV5); + break; - /* - * Determine UV arch type. - * SGI2: UV2000/3000 - * SGI3: UV300 (truncated to 4 chars because of different varieties) - * SGI4: UV400 (truncated to 4 chars because of different varieties) - */ - if (!strncmp(oem_id, "SGI4", 4)) { - uv_hub_info->hub_revision = UV4_HUB_REVISION_BASE; + case UV4_HUB_REVISION_BASE: uv_hubbed_system = 0x11; + uv_hub_type_set(UV4); + break; - } else if (!strncmp(oem_id, "SGI3", 4)) { - uv_hub_info->hub_revision = UV3_HUB_REVISION_BASE; + case UV3_HUB_REVISION_BASE: uv_hubbed_system = 0x9; + uv_hub_type_set(UV3); + break; - } else if (!strcmp(oem_id, "SGI2")) { - uv_hub_info->hub_revision = UV2_HUB_REVISION_BASE; + case UV2_HUB_REVISION_BASE: uv_hubbed_system = 0x5; + uv_hub_type_set(UV2); + break; - } else { - uv_hub_info->hub_revision = 0; - goto badbios; + default: + return 0; } - pnodeid = early_get_pnodeid(); - early_get_apic_socketid_shift(); + /* Get UV hub chip part number & revision */ + early_set_hub_type(); + /* Other UV setup functions */ + early_get_pnodeid(); + early_get_apic_socketid_shift(); x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range; x86_platform.nmi_init = uv_nmi_init; + uv_tsc_check_sync(); + + return 1; +} + +/* Called early to probe for the correct APIC driver */ +static int __init uv_acpi_madt_oem_check(char *_oem_id, char *_oem_table_id) +{ + /* Set up early hub info fields for Node 0 */ + uv_cpu_info->p_uv_hub_info = &uv_hub_info_node0; + + /* If not UV, return. */ + if (likely(uv_set_system_type(_oem_id) == 0)) + return 0; + + /* Save and Decode OEM Table ID */ + uv_stringify(sizeof(oem_table_id), oem_table_id, _oem_table_id); - if (!strcmp(oem_table_id, "UVX")) { - /* This is the most common hardware variant: */ + /* This is the most common hardware variant, x2apic mode */ + if (!strcmp(oem_table_id, "UVX")) uv_system_type = UV_X2APIC; - uv_apic = 0; - } else if (!strcmp(oem_table_id, "UVL")) { - /* Only used for very small systems: */ + /* Only used for very small systems, usually 1 chassis, legacy mode */ + else if (!strcmp(oem_table_id, "UVL")) uv_system_type = UV_LEGACY_APIC; - uv_apic = 0; - } else { + else goto badbios; - } - pr_info("UV: OEM IDs %s/%s, System/HUB Types %d/%d, uv_apic %d\n", oem_id, oem_table_id, uv_system_type, uv_min_hub_revision_id, uv_apic); - uv_tsc_check_sync(); + pr_info("UV: OEM IDs %s/%s, System/UVType %d/0x%x, HUB RevID %d\n", + oem_id, oem_table_id, uv_system_type, is_uv(UV_ANY), + uv_min_hub_revision_id); - return uv_apic; + return 0; badbios: - pr_err("UV: OEM_ID:%s OEM_TABLE_ID:%s\n", oem_id, oem_table_id); - pr_err("Current UV Type or BIOS not supported\n"); + pr_err("UV: UVarchtype:%s not supported\n", uv_archtype); BUG(); } @@ -673,12 +848,12 @@ static struct apic apic_x2apic_uv_x __ro_after_init = { }; #define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_LENGTH 3 -#define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT +#define DEST_SHIFT UVXH_RH_GAM_ALIAS_0_REDIRECT_CONFIG_DEST_BASE_SHFT static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) { - union uvh_rh_gam_alias210_overlay_config_2_mmr_u alias; - union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect; + union uvh_rh_gam_alias_2_overlay_config_u alias; + union uvh_rh_gam_alias_2_redirect_config_u redirect; unsigned long m_redirect; unsigned long m_overlay; int i; @@ -686,16 +861,16 @@ static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) for (i = 0; i < UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_LENGTH; i++) { switch (i) { case 0: - m_redirect = UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR; - m_overlay = UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR; + m_redirect = UVH_RH_GAM_ALIAS_0_REDIRECT_CONFIG; + m_overlay = UVH_RH_GAM_ALIAS_0_OVERLAY_CONFIG; break; case 1: - m_redirect = UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR; - m_overlay = UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR; + m_redirect = UVH_RH_GAM_ALIAS_1_REDIRECT_CONFIG; + m_overlay = UVH_RH_GAM_ALIAS_1_OVERLAY_CONFIG; break; case 2: - m_redirect = UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR; - m_overlay = UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR; + m_redirect = UVH_RH_GAM_ALIAS_2_REDIRECT_CONFIG; + m_overlay = UVH_RH_GAM_ALIAS_2_OVERLAY_CONFIG; break; } alias.v = uv_read_local_mmr(m_overlay); @@ -710,6 +885,7 @@ static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) } enum map_type {map_wb, map_uc}; +static const char * const mt[] = { "WB", "UC" }; static __init void map_high(char *id, unsigned long base, int pshift, int bshift, int max_pnode, enum map_type map_type) { @@ -721,23 +897,36 @@ static __init void map_high(char *id, unsigned long base, int pshift, int bshift pr_info("UV: Map %s_HI base address NULL\n", id); return; } - pr_debug("UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, paddr + bytes); if (map_type == map_uc) init_extra_mapping_uc(paddr, bytes); else init_extra_mapping_wb(paddr, bytes); + + pr_info("UV: Map %s_HI 0x%lx - 0x%lx %s (%d segments)\n", + id, paddr, paddr + bytes, mt[map_type], max_pnode + 1); } static __init void map_gru_high(int max_pnode) { - union uvh_rh_gam_gru_overlay_config_mmr_u gru; - int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT; - unsigned long mask = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK; - unsigned long base; + union uvh_rh_gam_gru_overlay_config_u gru; + unsigned long mask, base; + int shift; + + if (UVH_RH_GAM_GRU_OVERLAY_CONFIG) { + gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG); + shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_BASE_SHFT; + mask = UVH_RH_GAM_GRU_OVERLAY_CONFIG_BASE_MASK; + } else if (UVH_RH10_GAM_GRU_OVERLAY_CONFIG) { + gru.v = uv_read_local_mmr(UVH_RH10_GAM_GRU_OVERLAY_CONFIG); + shift = UVH_RH10_GAM_GRU_OVERLAY_CONFIG_BASE_SHFT; + mask = UVH_RH10_GAM_GRU_OVERLAY_CONFIG_BASE_MASK; + } else { + pr_err("UV: GRU unavailable (no MMR)\n"); + return; + } - gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR); if (!gru.s.enable) { - pr_info("UV: GRU disabled\n"); + pr_info("UV: GRU disabled (by BIOS)\n"); return; } @@ -749,62 +938,104 @@ static __init void map_gru_high(int max_pnode) static __init void map_mmr_high(int max_pnode) { - union uvh_rh_gam_mmr_overlay_config_mmr_u mmr; - int shift = UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT; + unsigned long base; + int shift; + bool enable; + + if (UVH_RH10_GAM_MMR_OVERLAY_CONFIG) { + union uvh_rh10_gam_mmr_overlay_config_u mmr; + + mmr.v = uv_read_local_mmr(UVH_RH10_GAM_MMR_OVERLAY_CONFIG); + enable = mmr.s.enable; + base = mmr.s.base; + shift = UVH_RH10_GAM_MMR_OVERLAY_CONFIG_BASE_SHFT; + } else if (UVH_RH_GAM_MMR_OVERLAY_CONFIG) { + union uvh_rh_gam_mmr_overlay_config_u mmr; + + mmr.v = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG); + enable = mmr.s.enable; + base = mmr.s.base; + shift = UVH_RH_GAM_MMR_OVERLAY_CONFIG_BASE_SHFT; + } else { + pr_err("UV:%s:RH_GAM_MMR_OVERLAY_CONFIG MMR undefined?\n", + __func__); + return; + } - mmr.v = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR); - if (mmr.s.enable) - map_high("MMR", mmr.s.base, shift, shift, max_pnode, map_uc); + if (enable) + map_high("MMR", base, shift, shift, max_pnode, map_uc); else pr_info("UV: MMR disabled\n"); } -/* UV3/4 have identical MMIOH overlay configs, UV4A is slightly different */ -static __init void map_mmioh_high_uv34(int index, int min_pnode, int max_pnode) -{ - unsigned long overlay; - unsigned long mmr; - unsigned long base; - unsigned long nasid_mask; - unsigned long m_overlay; - int i, n, shift, m_io, max_io; - int nasid, lnasid, fi, li; - char *id; - - if (index == 0) { - id = "MMIOH0"; - m_overlay = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR; - overlay = uv_read_local_mmr(m_overlay); - base = overlay & UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_BASE_MASK; - mmr = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR; - m_io = (overlay & UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_MASK) - >> UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_SHFT; - shift = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_M_IO_SHFT; - n = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_DEPTH; - nasid_mask = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0_MMR_NASID_MASK; - } else { - id = "MMIOH1"; - m_overlay = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR; - overlay = uv_read_local_mmr(m_overlay); - base = overlay & UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_BASE_MASK; - mmr = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR; - m_io = (overlay & UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_MASK) - >> UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_SHFT; - shift = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR_M_IO_SHFT; - n = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_DEPTH; - nasid_mask = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1_MMR_NASID_MASK; +/* Arch specific ENUM cases */ +enum mmioh_arch { + UV2_MMIOH = -1, + UVY_MMIOH0, UVY_MMIOH1, + UVX_MMIOH0, UVX_MMIOH1, +}; + +/* Calculate and Map MMIOH Regions */ +static void __init calc_mmioh_map(enum mmioh_arch index, + int min_pnode, int max_pnode, + int shift, unsigned long base, int m_io, int n_io) +{ + unsigned long mmr, nasid_mask; + int nasid, min_nasid, max_nasid, lnasid, mapped; + int i, fi, li, n, max_io; + char id[8]; + + /* One (UV2) mapping */ + if (index == UV2_MMIOH) { + strncpy(id, "MMIOH", sizeof(id)); + max_io = max_pnode; + mapped = 0; + goto map_exit; } - pr_info("UV: %s overlay 0x%lx base:0x%lx m_io:%d\n", id, overlay, base, m_io); - if (!(overlay & UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_MMR_ENABLE_MASK)) { - pr_info("UV: %s disabled\n", id); + + /* small and large MMIOH mappings */ + switch (index) { + case UVY_MMIOH0: + mmr = UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG0; + nasid_mask = UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG0_BASE_MASK; + n = UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG0_DEPTH; + min_nasid = min_pnode; + max_nasid = max_pnode; + mapped = 1; + break; + case UVY_MMIOH1: + mmr = UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG1; + nasid_mask = UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG1_BASE_MASK; + n = UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG1_DEPTH; + min_nasid = min_pnode; + max_nasid = max_pnode; + mapped = 1; + break; + case UVX_MMIOH0: + mmr = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0; + nasid_mask = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_BASE_MASK; + n = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0_DEPTH; + min_nasid = min_pnode * 2; + max_nasid = max_pnode * 2; + mapped = 1; + break; + case UVX_MMIOH1: + mmr = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1; + nasid_mask = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_BASE_MASK; + n = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1_DEPTH; + min_nasid = min_pnode * 2; + max_nasid = max_pnode * 2; + mapped = 1; + break; + default: + pr_err("UV:%s:Invalid mapping type:%d\n", __func__, index); return; } - /* Convert to NASID: */ - min_pnode *= 2; - max_pnode *= 2; - max_io = lnasid = fi = li = -1; + /* enum values chosen so (index mod 2) is MMIOH 0/1 (low/high) */ + snprintf(id, sizeof(id), "MMIOH%d", index%2); + max_io = lnasid = fi = li = -1; for (i = 0; i < n; i++) { unsigned long m_redirect = mmr + i * 8; unsigned long redirect = uv_read_local_mmr(m_redirect); @@ -814,9 +1045,12 @@ static __init void map_mmioh_high_uv34(int index, int min_pnode, int max_pnode) pr_info("UV: %s redirect base 0x%lx(@0x%lx) 0x%04x\n", id, redirect, m_redirect, nasid); - /* Invalid NASID: */ - if (nasid < min_pnode || max_pnode < nasid) + /* Invalid NASID check */ + if (nasid < min_nasid || max_nasid < nasid) { + pr_err("UV:%s:Invalid NASID:%x (range:%x..%x)\n", + __func__, index, min_nasid, max_nasid); nasid = -1; + } if (nasid == lnasid) { li = i; @@ -839,7 +1073,8 @@ static __init void map_mmioh_high_uv34(int index, int min_pnode, int max_pnode) } addr1 = (base << shift) + f * (1ULL << m_io); addr2 = (base << shift) + (l + 1) * (1ULL << m_io); - pr_info("UV: %s[%03d..%03d] NASID 0x%04x ADDR 0x%016lx - 0x%016lx\n", id, fi, li, lnasid, addr1, addr2); + pr_info("UV: %s[%03d..%03d] NASID 0x%04x ADDR 0x%016lx - 0x%016lx\n", + id, fi, li, lnasid, addr1, addr2); if (max_io < l) max_io = l; } @@ -847,49 +1082,93 @@ static __init void map_mmioh_high_uv34(int index, int min_pnode, int max_pnode) lnasid = nasid; } - pr_info("UV: %s base:0x%lx shift:%d M_IO:%d MAX_IO:%d\n", id, base, shift, m_io, max_io); +map_exit: + pr_info("UV: %s base:0x%lx shift:%d m_io:%d max_io:%d max_pnode:0x%x\n", + id, base, shift, m_io, max_io, max_pnode); - if (max_io >= 0) + if (max_io >= 0 && !mapped) map_high(id, base, shift, m_io, max_io, map_uc); } static __init void map_mmioh_high(int min_pnode, int max_pnode) { - union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh; - unsigned long mmr, base; - int shift, enable, m_io, n_io; + /* UVY flavor */ + if (UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG0) { + union uvh_rh10_gam_mmioh_overlay_config0_u mmioh0; + union uvh_rh10_gam_mmioh_overlay_config1_u mmioh1; + + mmioh0.v = uv_read_local_mmr(UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG0); + if (unlikely(mmioh0.s.enable == 0)) + pr_info("UV: MMIOH0 disabled\n"); + else + calc_mmioh_map(UVY_MMIOH0, min_pnode, max_pnode, + UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG0_BASE_SHFT, + mmioh0.s.base, mmioh0.s.m_io, mmioh0.s.n_io); - if (is_uv3_hub() || is_uv4_hub()) { - /* Map both MMIOH regions: */ - map_mmioh_high_uv34(0, min_pnode, max_pnode); - map_mmioh_high_uv34(1, min_pnode, max_pnode); + mmioh1.v = uv_read_local_mmr(UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG1); + if (unlikely(mmioh1.s.enable == 0)) + pr_info("UV: MMIOH1 disabled\n"); + else + calc_mmioh_map(UVY_MMIOH1, min_pnode, max_pnode, + UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG1_BASE_SHFT, + mmioh1.s.base, mmioh1.s.m_io, mmioh1.s.n_io); return; } + /* UVX flavor */ + if (UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0) { + union uvh_rh_gam_mmioh_overlay_config0_u mmioh0; + union uvh_rh_gam_mmioh_overlay_config1_u mmioh1; + + mmioh0.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0); + if (unlikely(mmioh0.s.enable == 0)) + pr_info("UV: MMIOH0 disabled\n"); + else { + unsigned long base = uvxy_field(mmioh0, base, 0); + int m_io = uvxy_field(mmioh0, m_io, 0); + int n_io = uvxy_field(mmioh0, n_io, 0); + + calc_mmioh_map(UVX_MMIOH0, min_pnode, max_pnode, + UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_BASE_SHFT, + base, m_io, n_io); + } - if (is_uv2_hub()) { - mmr = UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR; - shift = UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT; - mmioh.v = uv_read_local_mmr(mmr); - enable = !!mmioh.s2.enable; - base = mmioh.s2.base; - m_io = mmioh.s2.m_io; - n_io = mmioh.s2.n_io; - - if (enable) { - max_pnode &= (1 << n_io) - 1; - pr_info("UV: base:0x%lx shift:%d N_IO:%d M_IO:%d max_pnode:0x%x\n", - base, shift, m_io, n_io, max_pnode); - map_high("MMIOH", base, shift, m_io, max_pnode, map_uc); - } else { - pr_info("UV: MMIOH disabled\n"); + mmioh1.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1); + if (unlikely(mmioh1.s.enable == 0)) + pr_info("UV: MMIOH1 disabled\n"); + else { + unsigned long base = uvxy_field(mmioh1, base, 0); + int m_io = uvxy_field(mmioh1, m_io, 0); + int n_io = uvxy_field(mmioh1, n_io, 0); + + calc_mmioh_map(UVX_MMIOH1, min_pnode, max_pnode, + UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_BASE_SHFT, + base, m_io, n_io); } + return; + } + + /* UV2 flavor */ + if (UVH_RH_GAM_MMIOH_OVERLAY_CONFIG) { + union uvh_rh_gam_mmioh_overlay_config_u mmioh; + + mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG); + if (unlikely(mmioh.s2.enable == 0)) + pr_info("UV: MMIOH disabled\n"); + else + calc_mmioh_map(UV2_MMIOH, min_pnode, max_pnode, + UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_BASE_SHFT, + mmioh.s2.base, mmioh.s2.m_io, mmioh.s2.n_io); + return; } } static __init void map_low_mmrs(void) { - init_extra_mapping_uc(UV_GLOBAL_MMR32_BASE, UV_GLOBAL_MMR32_SIZE); - init_extra_mapping_uc(UV_LOCAL_MMR_BASE, UV_LOCAL_MMR_SIZE); + if (UV_GLOBAL_MMR32_BASE) + init_extra_mapping_uc(UV_GLOBAL_MMR32_BASE, UV_GLOBAL_MMR32_SIZE); + + if (UV_LOCAL_MMR_BASE) + init_extra_mapping_uc(UV_LOCAL_MMR_BASE, UV_LOCAL_MMR_SIZE); } static __init void uv_rtc_init(void) @@ -909,85 +1188,6 @@ static __init void uv_rtc_init(void) } } -/* - * percpu heartbeat timer - */ -static void uv_heartbeat(struct timer_list *timer) -{ - unsigned char bits = uv_scir_info->state; - - /* Flip heartbeat bit: */ - bits ^= SCIR_CPU_HEARTBEAT; - - /* Is this CPU idle? */ - if (idle_cpu(raw_smp_processor_id())) - bits &= ~SCIR_CPU_ACTIVITY; - else - bits |= SCIR_CPU_ACTIVITY; - - /* Update system controller interface reg: */ - uv_set_scir_bits(bits); - - /* Enable next timer period: */ - mod_timer(timer, jiffies + SCIR_CPU_HB_INTERVAL); -} - -static int uv_heartbeat_enable(unsigned int cpu) -{ - while (!uv_cpu_scir_info(cpu)->enabled) { - struct timer_list *timer = &uv_cpu_scir_info(cpu)->timer; - - uv_set_cpu_scir_bits(cpu, SCIR_CPU_HEARTBEAT|SCIR_CPU_ACTIVITY); - timer_setup(timer, uv_heartbeat, TIMER_PINNED); - timer->expires = jiffies + SCIR_CPU_HB_INTERVAL; - add_timer_on(timer, cpu); - uv_cpu_scir_info(cpu)->enabled = 1; - - /* Also ensure that boot CPU is enabled: */ - cpu = 0; - } - return 0; -} - -#ifdef CONFIG_HOTPLUG_CPU -static int uv_heartbeat_disable(unsigned int cpu) -{ - if (uv_cpu_scir_info(cpu)->enabled) { - uv_cpu_scir_info(cpu)->enabled = 0; - del_timer(&uv_cpu_scir_info(cpu)->timer); - } - uv_set_cpu_scir_bits(cpu, 0xff); - return 0; -} - -static __init void uv_scir_register_cpu_notifier(void) -{ - cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "x86/x2apic-uvx:online", - uv_heartbeat_enable, uv_heartbeat_disable); -} - -#else /* !CONFIG_HOTPLUG_CPU */ - -static __init void uv_scir_register_cpu_notifier(void) -{ -} - -static __init int uv_init_heartbeat(void) -{ - int cpu; - - if (is_uv_system()) { - for_each_online_cpu(cpu) - uv_heartbeat_enable(cpu); - } - - return 0; -} - -late_initcall(uv_init_heartbeat); - -#endif /* !CONFIG_HOTPLUG_CPU */ - /* Direct Legacy VGA I/O traffic to designated IOH */ static int uv_set_vga_state(struct pci_dev *pdev, bool decode, unsigned int command_bits, u32 flags) { @@ -1027,26 +1227,22 @@ struct mn { unsigned char n_lshift; }; +/* Initialize caller's MN struct and fill in values */ static void get_mn(struct mn *mnp) { - union uvh_rh_gam_config_mmr_u m_n_config; - union uv3h_gr0_gam_gr_config_u m_gr_config; - - /* Make sure the whole structure is well initialized: */ memset(mnp, 0, sizeof(*mnp)); - - m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR); - mnp->n_val = m_n_config.s.n_skt; - - if (is_uv4_hub()) { + mnp->n_val = uv_cpuid.n_skt; + if (is_uv(UV4|UVY)) { mnp->m_val = 0; mnp->n_lshift = 0; } else if (is_uv3_hub()) { - mnp->m_val = m_n_config.s3.m_skt; - m_gr_config.v = uv_read_local_mmr(UV3H_GR0_GAM_GR_CONFIG); + union uvyh_gr0_gam_gr_config_u m_gr_config; + + mnp->m_val = uv_cpuid.m_skt; + m_gr_config.v = uv_read_local_mmr(UVH_GR0_GAM_GR_CONFIG); mnp->n_lshift = m_gr_config.s3.m_skt; } else if (is_uv2_hub()) { - mnp->m_val = m_n_config.s2.m_skt; + mnp->m_val = uv_cpuid.m_skt; mnp->n_lshift = mnp->m_val == 40 ? 40 : 39; } mnp->m_shift = mnp->m_val ? 64 - mnp->m_val : 0; @@ -1054,7 +1250,6 @@ static void get_mn(struct mn *mnp) static void __init uv_init_hub_info(struct uv_hub_info_s *hi) { - union uvh_node_id_u node_id; struct mn mn; get_mn(&mn); @@ -1067,7 +1262,9 @@ static void __init uv_init_hub_info(struct uv_hub_info_s *hi) hi->m_shift = mn.m_shift; hi->n_lshift = mn.n_lshift ? mn.n_lshift : 0; hi->hub_revision = uv_hub_info->hub_revision; + hi->hub_type = uv_hub_info->hub_type; hi->pnode_mask = uv_cpuid.pnode_mask; + hi->nasid_shift = uv_cpuid.nasid_shift; hi->min_pnode = _min_pnode; hi->min_socket = _min_socket; hi->pnode_to_socket = _pnode_to_socket; @@ -1076,9 +1273,8 @@ static void __init uv_init_hub_info(struct uv_hub_info_s *hi) hi->gr_table_len = _gr_table_len; hi->gr_table = _gr_table; - node_id.v = uv_read_local_mmr(UVH_NODE_ID); uv_cpuid.gnode_shift = max_t(unsigned int, uv_cpuid.gnode_shift, mn.n_val); - hi->gnode_extra = (node_id.s.node_id & ~((1 << uv_cpuid.gnode_shift) - 1)) >> 1; + hi->gnode_extra = (uv_node_id & ~((1 << uv_cpuid.gnode_shift) - 1)) >> 1; if (mn.m_val) hi->gnode_upper = (u64)hi->gnode_extra << mn.m_val; @@ -1090,7 +1286,9 @@ static void __init uv_init_hub_info(struct uv_hub_info_s *hi) hi->gpa_shift = uv_gp_table->gpa_shift; hi->gpa_mask = (1UL << hi->gpa_shift) - 1; } else { - hi->global_mmr_base = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) & ~UV_MMR_ENABLE; + hi->global_mmr_base = + uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG) & + ~UV_MMR_ENABLE; hi->global_mmr_shift = _UV_GLOBAL_MMR64_PNODE_SHIFT; } @@ -1101,7 +1299,11 @@ static void __init uv_init_hub_info(struct uv_hub_info_s *hi) /* Show system specific info: */ pr_info("UV: N:%d M:%d m_shift:%d n_lshift:%d\n", hi->n_val, hi->m_val, hi->m_shift, hi->n_lshift); pr_info("UV: gpa_mask/shift:0x%lx/%d pnode_mask:0x%x apic_pns:%d\n", hi->gpa_mask, hi->gpa_shift, hi->pnode_mask, hi->apic_pnode_shift); - pr_info("UV: mmr_base/shift:0x%lx/%ld gru_base/shift:0x%lx/%ld\n", hi->global_mmr_base, hi->global_mmr_shift, hi->global_gru_base, hi->global_gru_shift); + pr_info("UV: mmr_base/shift:0x%lx/%ld\n", hi->global_mmr_base, hi->global_mmr_shift); + if (hi->global_gru_base) + pr_info("UV: gru_base/shift:0x%lx/%ld\n", + hi->global_gru_base, hi->global_gru_shift); + pr_info("UV: gnode_upper:0x%lx gnode_extra:0x%x\n", hi->gnode_upper, hi->gnode_extra); } @@ -1173,21 +1375,25 @@ static void __init decode_gam_rng_tbl(unsigned long ptr) pr_info("UV: GRT: %d entries, sockets(min:%x,max:%x) pnodes(min:%x,max:%x)\n", index, _min_socket, _max_socket, _min_pnode, _max_pnode); } +/* Walk through UVsystab decoding the fields */ static int __init decode_uv_systab(void) { struct uv_systab *st; int i; - /* If system is uv3 or lower, there is no extended UVsystab */ - if (is_uv_hubbed(0xfffffe) < uv(4) && is_uv_hubless(0xfffffe) < uv(4)) - return 0; /* No extended UVsystab required */ - + /* Get mapped UVsystab pointer */ st = uv_systab; + + /* If UVsystab is version 1, there is no extended UVsystab */ + if (st && st->revision == UV_SYSTAB_VERSION_1) + return 0; + if ((!st) || (st->revision < UV_SYSTAB_VERSION_UV4_LATEST)) { int rev = st ? st->revision : 0; - pr_err("UV: BIOS UVsystab version(%x) mismatch, expecting(%x)\n", rev, UV_SYSTAB_VERSION_UV4_LATEST); - pr_err("UV: Cannot support UV operations, switching to generic PC\n"); + pr_err("UV: BIOS UVsystab mismatch, (%x < %x)\n", + rev, UV_SYSTAB_VERSION_UV4_LATEST); + pr_err("UV: Does not support UV, switch to non-UV x86_64\n"); uv_system_type = UV_NONE; return -EINVAL; @@ -1199,7 +1405,8 @@ static int __init decode_uv_systab(void) if (!ptr) continue; - ptr = ptr + (unsigned long)st; + /* point to payload */ + ptr += (unsigned long)st; switch (st->entry[i].type) { case UV_SYSTAB_TYPE_GAM_PARAMS: @@ -1209,32 +1416,49 @@ static int __init decode_uv_systab(void) case UV_SYSTAB_TYPE_GAM_RNG_TBL: decode_gam_rng_tbl(ptr); break; + + case UV_SYSTAB_TYPE_ARCH_TYPE: + /* already processed in early startup */ + break; + + default: + pr_err("UV:%s:Unrecognized UV_SYSTAB_TYPE:%d, skipped\n", + __func__, st->entry[i].type); + break; } } return 0; } -/* - * Set up physical blade translations from UVH_NODE_PRESENT_TABLE - * .. NB: UVH_NODE_PRESENT_TABLE is going away, - * .. being replaced by GAM Range Table - */ +/* Set up physical blade translations from UVH_NODE_PRESENT_TABLE */ static __init void boot_init_possible_blades(struct uv_hub_info_s *hub_info) { + unsigned long np; int i, uv_pb = 0; - pr_info("UV: NODE_PRESENT_DEPTH = %d\n", UVH_NODE_PRESENT_TABLE_DEPTH); - for (i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) { - unsigned long np; - - np = uv_read_local_mmr(UVH_NODE_PRESENT_TABLE + i * 8); - if (np) + if (UVH_NODE_PRESENT_TABLE) { + pr_info("UV: NODE_PRESENT_DEPTH = %d\n", + UVH_NODE_PRESENT_TABLE_DEPTH); + for (i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) { + np = uv_read_local_mmr(UVH_NODE_PRESENT_TABLE + i * 8); pr_info("UV: NODE_PRESENT(%d) = 0x%016lx\n", i, np); - + uv_pb += hweight64(np); + } + } + if (UVH_NODE_PRESENT_0) { + np = uv_read_local_mmr(UVH_NODE_PRESENT_0); + pr_info("UV: NODE_PRESENT_0 = 0x%016lx\n", np); + uv_pb += hweight64(np); + } + if (UVH_NODE_PRESENT_1) { + np = uv_read_local_mmr(UVH_NODE_PRESENT_1); + pr_info("UV: NODE_PRESENT_1 = 0x%016lx\n", np); uv_pb += hweight64(np); } if (uv_possible_blades != uv_pb) uv_possible_blades = uv_pb; + + pr_info("UV: number nodes/possible blades %d\n", uv_pb); } static void __init build_socket_tables(void) @@ -1253,7 +1477,7 @@ static void __init build_socket_tables(void) pr_info("UV: No UVsystab socket table, ignoring\n"); return; } - pr_crit("UV: Error: UVsystab address translations not available!\n"); + pr_err("UV: Error: UVsystab address translations not available!\n"); BUG(); } @@ -1379,9 +1603,9 @@ static int __maybe_unused proc_hubless_show(struct seq_file *file, void *data) return 0; } -static int __maybe_unused proc_oemid_show(struct seq_file *file, void *data) +static int __maybe_unused proc_archtype_show(struct seq_file *file, void *data) { - seq_printf(file, "%s/%s\n", oem_id, oem_table_id); + seq_printf(file, "%s/%s\n", uv_archtype, oem_table_id); return 0; } @@ -1390,7 +1614,7 @@ static __init void uv_setup_proc_files(int hubless) struct proc_dir_entry *pde; pde = proc_mkdir(UV_PROC_NODE, NULL); - proc_create_single("oemid", 0, pde, proc_oemid_show); + proc_create_single("archtype", 0, pde, proc_archtype_show); if (hubless) proc_create_single("hubless", 0, pde, proc_hubless_show); else @@ -1429,7 +1653,8 @@ static void __init uv_system_init_hub(void) struct uv_hub_info_s hub_info = {0}; int bytes, cpu, nodeid; unsigned short min_pnode = 9999, max_pnode = 0; - char *hub = is_uv4_hub() ? "UV400" : + char *hub = is_uv5_hub() ? "UV500" : + is_uv4_hub() ? "UV400" : is_uv3_hub() ? "UV300" : is_uv2_hub() ? "UV2000/3000" : NULL; @@ -1441,12 +1666,14 @@ static void __init uv_system_init_hub(void) map_low_mmrs(); - /* Get uv_systab for decoding: */ + /* Get uv_systab for decoding, setup UV BIOS calls */ uv_bios_init(); /* If there's an UVsystab problem then abort UV init: */ - if (decode_uv_systab() < 0) + if (decode_uv_systab() < 0) { + pr_err("UV: Mangled UVsystab format\n"); return; + } build_socket_tables(); build_uv_gr_table(); @@ -1517,8 +1744,6 @@ static void __init uv_system_init_hub(void) uv_hub_info_list(numa_node_id)->pnode = pnode; else if (uv_cpu_hub_info(cpu)->pnode == 0xffff) uv_cpu_hub_info(cpu)->pnode = pnode; - - uv_cpu_scir_info(cpu)->offset = uv_scir_offset(apicid); } for_each_node(nodeid) { @@ -1547,7 +1772,6 @@ static void __init uv_system_init_hub(void) uv_nmi_setup(); uv_cpu_init(); - uv_scir_register_cpu_notifier(); uv_setup_proc_files(0); /* Register Legacy VGA I/O redirection handler: */ diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c index 3ca07ad552ae..70b7154f4bdd 100644 --- a/arch/x86/kernel/asm-offsets.c +++ b/arch/x86/kernel/asm-offsets.c @@ -38,9 +38,6 @@ static void __used common(void) #endif BLANK(); - OFFSET(TASK_addr_limit, task_struct, thread.addr_limit); - - BLANK(); OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); BLANK(); diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index dcc3d943c68f..6062ce586b95 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -614,7 +614,7 @@ static void early_detect_mem_encrypt(struct cpuinfo_x86 *c) * If BIOS has not enabled SME then don't advertise the * SME feature (set in scattered.c). * For SEV: If BIOS has not enabled SEV then don't advertise the - * SEV feature (set in scattered.c). + * SEV and SEV_ES feature (set in scattered.c). * * In all cases, since support for SME and SEV requires long mode, * don't advertise the feature under CONFIG_X86_32. @@ -645,6 +645,7 @@ clear_all: setup_clear_cpu_cap(X86_FEATURE_SME); clear_sev: setup_clear_cpu_cap(X86_FEATURE_SEV); + setup_clear_cpu_cap(X86_FEATURE_SEV_ES); } } diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index c5cf336e5077..345f7d905db6 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c @@ -65,6 +65,9 @@ static void init_c3(struct cpuinfo_x86 *c) c->x86_cache_alignment = c->x86_clflush_size * 2; set_cpu_cap(c, X86_FEATURE_REP_GOOD); } + + if (c->x86 >= 7) + set_cpu_cap(c, X86_FEATURE_REP_GOOD); } enum { @@ -90,18 +93,15 @@ enum { static void early_init_centaur(struct cpuinfo_x86 *c) { - switch (c->x86) { #ifdef CONFIG_X86_32 - case 5: - /* Emulate MTRRs using Centaur's MCR. */ + /* Emulate MTRRs using Centaur's MCR. */ + if (c->x86 == 5) set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR); - break; #endif - case 6: - if (c->x86_model >= 0xf) - set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); - break; - } + if ((c->x86 == 6 && c->x86_model >= 0xf) || + (c->x86 >= 7)) + set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); + #ifdef CONFIG_X86_64 set_cpu_cap(c, X86_FEATURE_SYSENTER32); #endif @@ -145,9 +145,8 @@ static void init_centaur(struct cpuinfo_x86 *c) set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON); } - switch (c->x86) { #ifdef CONFIG_X86_32 - case 5: + if (c->x86 == 5) { switch (c->x86_model) { case 4: name = "C6"; @@ -207,12 +206,10 @@ static void init_centaur(struct cpuinfo_x86 *c) c->x86_cache_size = (cc>>24)+(dd>>24); } sprintf(c->x86_model_id, "WinChip %s", name); - break; + } #endif - case 6: + if (c->x86 == 6 || c->x86 >= 7) init_c3(c); - break; - } #ifdef CONFIG_X86_64 set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); #endif diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c5d6f17d9b9d..35ad8480c464 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -23,6 +23,7 @@ #include <linux/syscore_ops.h> #include <linux/pgtable.h> +#include <asm/cmdline.h> #include <asm/stackprotector.h> #include <asm/perf_event.h> #include <asm/mmu_context.h> @@ -359,7 +360,7 @@ void native_write_cr0(unsigned long val) unsigned long bits_missing = 0; set_register: - asm volatile("mov %0,%%cr0": "+r" (val), "+m" (__force_order)); + asm volatile("mov %0,%%cr0": "+r" (val) : : "memory"); if (static_branch_likely(&cr_pinning)) { if (unlikely((val & X86_CR0_WP) != X86_CR0_WP)) { @@ -378,7 +379,7 @@ void native_write_cr4(unsigned long val) unsigned long bits_changed = 0; set_register: - asm volatile("mov %0,%%cr4": "+r" (val), "+m" (cr4_pinned_bits)); + asm volatile("mov %0,%%cr4": "+r" (val) : : "memory"); if (static_branch_likely(&cr_pinning)) { if (unlikely((val & cr4_pinned_mask) != cr4_pinned_bits)) { @@ -1221,6 +1222,59 @@ static void detect_nopl(void) } /* + * We parse cpu parameters early because fpu__init_system() is executed + * before parse_early_param(). + */ +static void __init cpu_parse_early_param(void) +{ + char arg[128]; + char *argptr = arg; + int arglen, res, bit; + +#ifdef CONFIG_X86_32 + if (cmdline_find_option_bool(boot_command_line, "no387")) +#ifdef CONFIG_MATH_EMULATION + setup_clear_cpu_cap(X86_FEATURE_FPU); +#else + pr_err("Option 'no387' required CONFIG_MATH_EMULATION enabled.\n"); +#endif + + if (cmdline_find_option_bool(boot_command_line, "nofxsr")) + setup_clear_cpu_cap(X86_FEATURE_FXSR); +#endif + + if (cmdline_find_option_bool(boot_command_line, "noxsave")) + setup_clear_cpu_cap(X86_FEATURE_XSAVE); + + if (cmdline_find_option_bool(boot_command_line, "noxsaveopt")) + setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); + + if (cmdline_find_option_bool(boot_command_line, "noxsaves")) + setup_clear_cpu_cap(X86_FEATURE_XSAVES); + + arglen = cmdline_find_option(boot_command_line, "clearcpuid", arg, sizeof(arg)); + if (arglen <= 0) + return; + + pr_info("Clearing CPUID bits:"); + do { + res = get_option(&argptr, &bit); + if (res == 0 || res == 3) + break; + + /* If the argument was too long, the last bit may be cut off */ + if (res == 1 && arglen >= sizeof(arg)) + break; + + if (bit >= 0 && bit < NCAPINTS * 32) { + pr_cont(" " X86_CAP_FMT, x86_cap_flag(bit)); + setup_clear_cpu_cap(bit); + } + } while (res == 2); + pr_cont("\n"); +} + +/* * Do minimum CPU detection early. * Fields really needed: vendor, cpuid_level, family, model, mask, * cache alignment. @@ -1255,6 +1309,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) get_cpu_cap(c); get_cpu_address_sizes(c); setup_force_cpu_cap(X86_FEATURE_CPUID); + cpu_parse_early_param(); if (this_cpu->c_early_init) this_cpu->c_early_init(c); @@ -1413,15 +1468,7 @@ static void generic_identify(struct cpuinfo_x86 *c) * ESPFIX issue, we can change this. */ #ifdef CONFIG_X86_32 -# ifdef CONFIG_PARAVIRT_XXL - do { - extern void native_iret(void); - if (pv_ops.cpu.iret == native_iret) - set_cpu_bug(c, X86_BUG_ESPFIX); - } while (0); -# else set_cpu_bug(c, X86_BUG_ESPFIX); -# endif #endif } @@ -1829,6 +1876,8 @@ static inline void tss_setup_ist(struct tss_struct *tss) tss->x86_tss.ist[IST_INDEX_NMI] = __this_cpu_ist_top_va(NMI); tss->x86_tss.ist[IST_INDEX_DB] = __this_cpu_ist_top_va(DB); tss->x86_tss.ist[IST_INDEX_MCE] = __this_cpu_ist_top_va(MCE); + /* Only mapped when SEV-ES is active */ + tss->x86_tss.ist[IST_INDEX_VC] = __this_cpu_ist_top_va(VC); } #else /* CONFIG_X86_64 */ @@ -1861,6 +1910,29 @@ static inline void tss_setup_io_bitmap(struct tss_struct *tss) } /* + * Setup everything needed to handle exceptions from the IDT, including the IST + * exceptions which use paranoid_entry(). + */ +void cpu_init_exception_handling(void) +{ + struct tss_struct *tss = this_cpu_ptr(&cpu_tss_rw); + int cpu = raw_smp_processor_id(); + + /* paranoid_entry() gets the CPU number from the GDT */ + setup_getcpu(cpu); + + /* IST vectors need TSS to be set up. */ + tss_setup_ist(tss); + tss_setup_io_bitmap(tss); + set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss); + + load_TR_desc(); + + /* Finally load the IDT */ + load_current_idt(); +} + +/* * cpu_init() initializes state that is per-CPU. Some data is already * initialized (naturally) in the bootstrap process, such as the GDT * and IDT. We reload them nevertheless, this function acts as a diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 9d033693519a..67944128876d 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h @@ -38,7 +38,7 @@ struct _tlb_table { #define cpu_dev_register(cpu_devX) \ static const struct cpu_dev *const __cpu_dev_##cpu_devX __used \ - __attribute__((__section__(".x86_cpu_dev.init"))) = \ + __section(".x86_cpu_dev.init") = \ &cpu_devX; extern const struct cpu_dev *const __x86_cpu_dev_start[], diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-deps.c index 3cbe24ca80ab..d502241995a3 100644 --- a/arch/x86/kernel/cpu/cpuid-deps.c +++ b/arch/x86/kernel/cpu/cpuid-deps.c @@ -69,6 +69,8 @@ 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_ENQCMD, X86_FEATURE_XSAVES }, + { X86_FEATURE_PER_THREAD_MBA, X86_FEATURE_MBA }, {} }; diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c index 99be063fcb1b..0c6b02dd744c 100644 --- a/arch/x86/kernel/cpu/mce/amd.c +++ b/arch/x86/kernel/cpu/mce/amd.c @@ -132,49 +132,49 @@ static enum smca_bank_types smca_get_bank_type(unsigned int bank) } static struct smca_hwid smca_hwid_mcatypes[] = { - /* { bank_type, hwid_mcatype, xec_bitmap } */ + /* { bank_type, hwid_mcatype } */ /* Reserved type */ - { SMCA_RESERVED, HWID_MCATYPE(0x00, 0x0), 0x0 }, + { SMCA_RESERVED, HWID_MCATYPE(0x00, 0x0) }, /* ZN Core (HWID=0xB0) MCA types */ - { SMCA_LS, HWID_MCATYPE(0xB0, 0x0), 0x1FFFFF }, - { SMCA_LS_V2, HWID_MCATYPE(0xB0, 0x10), 0xFFFFFF }, - { SMCA_IF, HWID_MCATYPE(0xB0, 0x1), 0x3FFF }, - { SMCA_L2_CACHE, HWID_MCATYPE(0xB0, 0x2), 0xF }, - { SMCA_DE, HWID_MCATYPE(0xB0, 0x3), 0x1FF }, + { SMCA_LS, HWID_MCATYPE(0xB0, 0x0) }, + { SMCA_LS_V2, HWID_MCATYPE(0xB0, 0x10) }, + { SMCA_IF, HWID_MCATYPE(0xB0, 0x1) }, + { SMCA_L2_CACHE, HWID_MCATYPE(0xB0, 0x2) }, + { SMCA_DE, HWID_MCATYPE(0xB0, 0x3) }, /* HWID 0xB0 MCATYPE 0x4 is Reserved */ - { SMCA_EX, HWID_MCATYPE(0xB0, 0x5), 0xFFF }, - { SMCA_FP, HWID_MCATYPE(0xB0, 0x6), 0x7F }, - { SMCA_L3_CACHE, HWID_MCATYPE(0xB0, 0x7), 0xFF }, + { SMCA_EX, HWID_MCATYPE(0xB0, 0x5) }, + { SMCA_FP, HWID_MCATYPE(0xB0, 0x6) }, + { SMCA_L3_CACHE, HWID_MCATYPE(0xB0, 0x7) }, /* Data Fabric MCA types */ - { SMCA_CS, HWID_MCATYPE(0x2E, 0x0), 0x1FF }, - { SMCA_PIE, HWID_MCATYPE(0x2E, 0x1), 0x1F }, - { SMCA_CS_V2, HWID_MCATYPE(0x2E, 0x2), 0x3FFF }, + { SMCA_CS, HWID_MCATYPE(0x2E, 0x0) }, + { SMCA_PIE, HWID_MCATYPE(0x2E, 0x1) }, + { SMCA_CS_V2, HWID_MCATYPE(0x2E, 0x2) }, /* Unified Memory Controller MCA type */ - { SMCA_UMC, HWID_MCATYPE(0x96, 0x0), 0xFF }, + { SMCA_UMC, HWID_MCATYPE(0x96, 0x0) }, /* Parameter Block MCA type */ - { SMCA_PB, HWID_MCATYPE(0x05, 0x0), 0x1 }, + { SMCA_PB, HWID_MCATYPE(0x05, 0x0) }, /* Platform Security Processor MCA type */ - { SMCA_PSP, HWID_MCATYPE(0xFF, 0x0), 0x1 }, - { SMCA_PSP_V2, HWID_MCATYPE(0xFF, 0x1), 0x3FFFF }, + { SMCA_PSP, HWID_MCATYPE(0xFF, 0x0) }, + { SMCA_PSP_V2, HWID_MCATYPE(0xFF, 0x1) }, /* System Management Unit MCA type */ - { SMCA_SMU, HWID_MCATYPE(0x01, 0x0), 0x1 }, - { SMCA_SMU_V2, HWID_MCATYPE(0x01, 0x1), 0x7FF }, + { SMCA_SMU, HWID_MCATYPE(0x01, 0x0) }, + { SMCA_SMU_V2, HWID_MCATYPE(0x01, 0x1) }, /* Microprocessor 5 Unit MCA type */ - { SMCA_MP5, HWID_MCATYPE(0x01, 0x2), 0x3FF }, + { SMCA_MP5, HWID_MCATYPE(0x01, 0x2) }, /* Northbridge IO Unit MCA type */ - { SMCA_NBIO, HWID_MCATYPE(0x18, 0x0), 0x1F }, + { SMCA_NBIO, HWID_MCATYPE(0x18, 0x0) }, /* PCI Express Unit MCA type */ - { SMCA_PCIE, HWID_MCATYPE(0x46, 0x0), 0x1F }, + { SMCA_PCIE, HWID_MCATYPE(0x46, 0x0) }, }; struct smca_bank smca_banks[MAX_NR_BANKS]; diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index f43a78bde670..4102b866e7c0 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -40,7 +40,6 @@ #include <linux/debugfs.h> #include <linux/irq_work.h> #include <linux/export.h> -#include <linux/jump_label.h> #include <linux/set_memory.h> #include <linux/sync_core.h> #include <linux/task_work.h> @@ -373,42 +372,105 @@ static int msr_to_offset(u32 msr) return -1; } +__visible bool ex_handler_rdmsr_fault(const struct exception_table_entry *fixup, + struct pt_regs *regs, int trapnr, + unsigned long error_code, + unsigned long fault_addr) +{ + pr_emerg("MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n", + (unsigned int)regs->cx, regs->ip, (void *)regs->ip); + + show_stack_regs(regs); + + panic("MCA architectural violation!\n"); + + while (true) + cpu_relax(); + + return true; +} + /* MSR access wrappers used for error injection */ -static u64 mce_rdmsrl(u32 msr) +static noinstr u64 mce_rdmsrl(u32 msr) { - u64 v; + DECLARE_ARGS(val, low, high); if (__this_cpu_read(injectm.finished)) { - int offset = msr_to_offset(msr); + int offset; + u64 ret; + + instrumentation_begin(); + offset = msr_to_offset(msr); if (offset < 0) - return 0; - return *(u64 *)((char *)this_cpu_ptr(&injectm) + offset); - } + ret = 0; + else + ret = *(u64 *)((char *)this_cpu_ptr(&injectm) + offset); - if (rdmsrl_safe(msr, &v)) { - WARN_ONCE(1, "mce: Unable to read MSR 0x%x!\n", msr); - /* - * Return zero in case the access faulted. This should - * not happen normally but can happen if the CPU does - * something weird, or if the code is buggy. - */ - v = 0; + instrumentation_end(); + + return ret; } - return v; + /* + * RDMSR on MCA MSRs should not fault. If they do, this is very much an + * architectural violation and needs to be reported to hw vendor. Panic + * the box to not allow any further progress. + */ + asm volatile("1: rdmsr\n" + "2:\n" + _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_rdmsr_fault) + : EAX_EDX_RET(val, low, high) : "c" (msr)); + + + return EAX_EDX_VAL(val, low, high); +} + +__visible bool ex_handler_wrmsr_fault(const struct exception_table_entry *fixup, + struct pt_regs *regs, int trapnr, + unsigned long error_code, + unsigned long fault_addr) +{ + pr_emerg("MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n", + (unsigned int)regs->cx, (unsigned int)regs->dx, (unsigned int)regs->ax, + regs->ip, (void *)regs->ip); + + show_stack_regs(regs); + + panic("MCA architectural violation!\n"); + + while (true) + cpu_relax(); + + return true; } -static void mce_wrmsrl(u32 msr, u64 v) +static noinstr void mce_wrmsrl(u32 msr, u64 v) { + u32 low, high; + if (__this_cpu_read(injectm.finished)) { - int offset = msr_to_offset(msr); + int offset; + + instrumentation_begin(); + offset = msr_to_offset(msr); if (offset >= 0) *(u64 *)((char *)this_cpu_ptr(&injectm) + offset) = v; + + instrumentation_end(); + return; } - wrmsrl(msr, v); + + low = (u32)v; + high = (u32)(v >> 32); + + /* See comment in mce_rdmsrl() */ + asm volatile("1: wrmsr\n" + "2:\n" + _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_wrmsr_fault) + : : "c" (msr), "a"(low), "d" (high) : "memory"); } /* @@ -745,7 +807,7 @@ log_it: goto clear_it; mce_read_aux(&m, i); - m.severity = mce_severity(&m, mca_cfg.tolerant, NULL, false); + m.severity = mce_severity(&m, NULL, mca_cfg.tolerant, NULL, false); /* * Don't get the IP here because it's unlikely to * have anything to do with the actual error location. @@ -794,7 +856,7 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp, quirk_no_way_out(i, m, regs); m->bank = i; - if (mce_severity(m, mca_cfg.tolerant, &tmp, true) >= MCE_PANIC_SEVERITY) { + if (mce_severity(m, regs, mca_cfg.tolerant, &tmp, true) >= MCE_PANIC_SEVERITY) { mce_read_aux(m, i); *msg = tmp; return 1; @@ -872,7 +934,6 @@ static void mce_reign(void) struct mce *m = NULL; int global_worst = 0; char *msg = NULL; - char *nmsg = NULL; /* * This CPU is the Monarch and the other CPUs have run @@ -880,12 +941,10 @@ static void mce_reign(void) * Grade the severity of the errors of all the CPUs. */ for_each_possible_cpu(cpu) { - int severity = mce_severity(&per_cpu(mces_seen, cpu), - mca_cfg.tolerant, - &nmsg, true); - if (severity > global_worst) { - msg = nmsg; - global_worst = severity; + struct mce *mtmp = &per_cpu(mces_seen, cpu); + + if (mtmp->severity > global_worst) { + global_worst = mtmp->severity; m = &per_cpu(mces_seen, cpu); } } @@ -895,8 +954,11 @@ static void mce_reign(void) * This dumps all the mces in the log buffer and stops the * other CPUs. */ - if (m && global_worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) + if (m && global_worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) { + /* call mce_severity() to get "msg" for panic */ + mce_severity(m, NULL, mca_cfg.tolerant, &msg, true); mce_panic("Fatal machine check", m, msg); + } /* * For UC somewhere we let the CPU who detects it handle it. @@ -1105,7 +1167,7 @@ static noinstr bool mce_check_crashing_cpu(void) return false; } -static void __mc_scan_banks(struct mce *m, struct mce *final, +static void __mc_scan_banks(struct mce *m, struct pt_regs *regs, struct mce *final, unsigned long *toclear, unsigned long *valid_banks, int no_way_out, int *worst) { @@ -1140,7 +1202,7 @@ static void __mc_scan_banks(struct mce *m, struct mce *final, /* Set taint even when machine check was not enabled. */ add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE); - severity = mce_severity(m, cfg->tolerant, NULL, true); + severity = mce_severity(m, regs, cfg->tolerant, NULL, true); /* * When machine check was for corrected/deferred handler don't @@ -1188,13 +1250,34 @@ static void kill_me_maybe(struct callback_head *cb) if (!p->mce_ripv) flags |= MF_MUST_KILL; - if (!memory_failure(p->mce_addr >> PAGE_SHIFT, flags)) { + if (!memory_failure(p->mce_addr >> PAGE_SHIFT, flags) && + !(p->mce_kflags & MCE_IN_KERNEL_COPYIN)) { set_mce_nospec(p->mce_addr >> PAGE_SHIFT, p->mce_whole_page); + sync_core(); return; } - pr_err("Memory error not recovered"); - kill_me_now(cb); + if (p->mce_vaddr != (void __user *)-1l) { + force_sig_mceerr(BUS_MCEERR_AR, p->mce_vaddr, PAGE_SHIFT); + } else { + pr_err("Memory error not recovered"); + kill_me_now(cb); + } +} + +static void queue_task_work(struct mce *m, int kill_it) +{ + current->mce_addr = m->addr; + current->mce_kflags = m->kflags; + current->mce_ripv = !!(m->mcgstatus & MCG_STATUS_RIPV); + current->mce_whole_page = whole_page(m); + + if (kill_it) + current->mce_kill_me.func = kill_me_now; + else + current->mce_kill_me.func = kill_me_maybe; + + task_work_add(current, ¤t->mce_kill_me, TWA_RESUME); } /* @@ -1291,7 +1374,7 @@ noinstr void do_machine_check(struct pt_regs *regs) order = mce_start(&no_way_out); } - __mc_scan_banks(&m, final, toclear, valid_banks, no_way_out, &worst); + __mc_scan_banks(&m, regs, final, toclear, valid_banks, no_way_out, &worst); if (!no_way_out) mce_clear_state(toclear); @@ -1313,7 +1396,7 @@ noinstr void do_machine_check(struct pt_regs *regs) * make sure we have the right "msg". */ if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) { - mce_severity(&m, cfg->tolerant, &msg, true); + mce_severity(&m, regs, cfg->tolerant, &msg, true); mce_panic("Local fatal machine check!", &m, msg); } } @@ -1330,25 +1413,16 @@ noinstr void do_machine_check(struct pt_regs *regs) if (worst > 0) irq_work_queue(&mce_irq_work); - mce_wrmsrl(MSR_IA32_MCG_STATUS, 0); - - sync_core(); - if (worst != MCE_AR_SEVERITY && !kill_it) - return; + goto out; /* Fault was in user mode and we need to take some action */ if ((m.cs & 3) == 3) { /* If this triggers there is no way to recover. Die hard. */ BUG_ON(!on_thread_stack() || !user_mode(regs)); - current->mce_addr = m.addr; - current->mce_ripv = !!(m.mcgstatus & MCG_STATUS_RIPV); - current->mce_whole_page = whole_page(&m); - current->mce_kill_me.func = kill_me_maybe; - if (kill_it) - current->mce_kill_me.func = kill_me_now; - task_work_add(current, ¤t->mce_kill_me, true); + queue_task_work(&m, kill_it); + } else { /* * Handle an MCE which has happened in kernel space but from @@ -1363,7 +1437,12 @@ noinstr void do_machine_check(struct pt_regs *regs) if (!fixup_exception(regs, X86_TRAP_MC, 0, 0)) mce_panic("Failed kernel mode recovery", &m, msg); } + + if (m.kflags & MCE_IN_KERNEL_COPYIN) + queue_task_work(&m, kill_it); } +out: + mce_wrmsrl(MSR_IA32_MCG_STATUS, 0); } EXPORT_SYMBOL_GPL(do_machine_check); @@ -1904,6 +1983,8 @@ void (*machine_check_vector)(struct pt_regs *) = unexpected_machine_check; static __always_inline void exc_machine_check_kernel(struct pt_regs *regs) { + bool irq_state; + WARN_ON_ONCE(user_mode(regs)); /* @@ -1914,7 +1995,7 @@ static __always_inline void exc_machine_check_kernel(struct pt_regs *regs) mce_check_crashing_cpu()) return; - nmi_enter(); + irq_state = idtentry_enter_nmi(regs); /* * The call targets are marked noinstr, but objtool can't figure * that out because it's an indirect call. Annotate it. @@ -1925,7 +2006,7 @@ static __always_inline void exc_machine_check_kernel(struct pt_regs *regs) if (regs->flags & X86_EFLAGS_IF) trace_hardirqs_on_prepare(); instrumentation_end(); - nmi_exit(); + idtentry_exit_nmi(regs, irq_state); } static __always_inline void exc_machine_check_user(struct pt_regs *regs) @@ -2062,7 +2143,7 @@ void mce_disable_bank(int bank) and older. * mce=nobootlog Don't log MCEs from before booting. * mce=bios_cmci_threshold Don't program the CMCI threshold - * mce=recovery force enable memcpy_mcsafe() + * mce=recovery force enable copy_mc_fragile() */ static int __init mcheck_enable(char *str) { @@ -2670,13 +2751,10 @@ static void __init mcheck_debugfs_init(void) static void __init mcheck_debugfs_init(void) { } #endif -DEFINE_STATIC_KEY_FALSE(mcsafe_key); -EXPORT_SYMBOL_GPL(mcsafe_key); - static int __init mcheck_late_init(void) { if (mca_cfg.recovery) - static_branch_inc(&mcsafe_key); + enable_copy_mc_fragile(); mcheck_debugfs_init(); diff --git a/arch/x86/kernel/cpu/mce/dev-mcelog.c b/arch/x86/kernel/cpu/mce/dev-mcelog.c index 03e51053592a..100fbeebdc72 100644 --- a/arch/x86/kernel/cpu/mce/dev-mcelog.c +++ b/arch/x86/kernel/cpu/mce/dev-mcelog.c @@ -67,7 +67,9 @@ static int dev_mce_log(struct notifier_block *nb, unsigned long val, unlock: mutex_unlock(&mce_chrdev_read_mutex); - mce->kflags |= MCE_HANDLED_MCELOG; + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) + mce->kflags |= MCE_HANDLED_MCELOG; + return NOTIFY_OK; } diff --git a/arch/x86/kernel/cpu/mce/internal.h b/arch/x86/kernel/cpu/mce/internal.h index 6473070b5da4..88dcc79cfb07 100644 --- a/arch/x86/kernel/cpu/mce/internal.h +++ b/arch/x86/kernel/cpu/mce/internal.h @@ -38,7 +38,8 @@ int mce_gen_pool_add(struct mce *mce); int mce_gen_pool_init(void); struct llist_node *mce_gen_pool_prepare_records(void); -extern int (*mce_severity)(struct mce *a, int tolerant, char **msg, bool is_excp); +extern int (*mce_severity)(struct mce *a, struct pt_regs *regs, + int tolerant, char **msg, bool is_excp); struct dentry *mce_get_debugfs_dir(void); extern mce_banks_t mce_banks_ce_disabled; @@ -185,4 +186,14 @@ extern bool amd_filter_mce(struct mce *m); static inline bool amd_filter_mce(struct mce *m) { return false; }; #endif +__visible bool ex_handler_rdmsr_fault(const struct exception_table_entry *fixup, + struct pt_regs *regs, int trapnr, + unsigned long error_code, + unsigned long fault_addr); + +__visible bool ex_handler_wrmsr_fault(const struct exception_table_entry *fixup, + struct pt_regs *regs, int trapnr, + unsigned long error_code, + unsigned long fault_addr); + #endif /* __X86_MCE_INTERNAL_H__ */ diff --git a/arch/x86/kernel/cpu/mce/severity.c b/arch/x86/kernel/cpu/mce/severity.c index e1da619add19..83df991314c5 100644 --- a/arch/x86/kernel/cpu/mce/severity.c +++ b/arch/x86/kernel/cpu/mce/severity.c @@ -9,9 +9,14 @@ #include <linux/seq_file.h> #include <linux/init.h> #include <linux/debugfs.h> -#include <asm/mce.h> #include <linux/uaccess.h> +#include <asm/mce.h> +#include <asm/intel-family.h> +#include <asm/traps.h> +#include <asm/insn.h> +#include <asm/insn-eval.h> + #include "internal.h" /* @@ -40,9 +45,14 @@ static struct severity { unsigned char context; unsigned char excp; unsigned char covered; + unsigned char cpu_model; + unsigned char cpu_minstepping; + unsigned char bank_lo, bank_hi; char *msg; } severities[] = { #define MCESEV(s, m, c...) { .sev = MCE_ ## s ## _SEVERITY, .msg = m, ## c } +#define BANK_RANGE(l, h) .bank_lo = l, .bank_hi = h +#define MODEL_STEPPING(m, s) .cpu_model = m, .cpu_minstepping = s #define KERNEL .context = IN_KERNEL #define USER .context = IN_USER #define KERNEL_RECOV .context = IN_KERNEL_RECOV @@ -90,14 +100,9 @@ static struct severity { EXCP, KERNEL_RECOV, MCGMASK(MCG_STATUS_RIPV, 0) ), MCESEV( - DEFERRED, "Deferred error", - NOSER, MASK(MCI_STATUS_UC|MCI_STATUS_DEFERRED|MCI_STATUS_POISON, MCI_STATUS_DEFERRED) - ), - MCESEV( KEEP, "Corrected error", NOSER, BITCLR(MCI_STATUS_UC) ), - /* * known AO MCACODs reported via MCE or CMC: * @@ -113,6 +118,18 @@ static struct severity { AO, "Action optional: last level cache writeback error", SER, MASK(MCI_UC_AR|MCACOD, MCI_STATUS_UC|MCACOD_L3WB) ), + /* + * Quirk for Skylake/Cascade Lake. Patrol scrubber may be configured + * to report uncorrected errors using CMCI with a special signature. + * UC=0, MSCOD=0x0010, MCACOD=binary(000X 0000 1100 XXXX) reported + * in one of the memory controller banks. + * Set severity to "AO" for same action as normal patrol scrub error. + */ + MCESEV( + AO, "Uncorrected Patrol Scrub Error", + SER, MASK(MCI_STATUS_UC|MCI_ADDR|0xffffeff0, MCI_ADDR|0x001000c0), + MODEL_STEPPING(INTEL_FAM6_SKYLAKE_X, 4), BANK_RANGE(13, 18) + ), /* ignore OVER for UCNA */ MCESEV( @@ -198,6 +215,47 @@ static struct severity { #define mc_recoverable(mcg) (((mcg) & (MCG_STATUS_RIPV|MCG_STATUS_EIPV)) == \ (MCG_STATUS_RIPV|MCG_STATUS_EIPV)) +static bool is_copy_from_user(struct pt_regs *regs) +{ + u8 insn_buf[MAX_INSN_SIZE]; + struct insn insn; + unsigned long addr; + + if (copy_from_kernel_nofault(insn_buf, (void *)regs->ip, MAX_INSN_SIZE)) + return false; + + kernel_insn_init(&insn, insn_buf, MAX_INSN_SIZE); + insn_get_opcode(&insn); + if (!insn.opcode.got) + return false; + + switch (insn.opcode.value) { + /* MOV mem,reg */ + case 0x8A: case 0x8B: + /* MOVZ mem,reg */ + case 0xB60F: case 0xB70F: + insn_get_modrm(&insn); + insn_get_sib(&insn); + if (!insn.modrm.got || !insn.sib.got) + return false; + addr = (unsigned long)insn_get_addr_ref(&insn, regs); + break; + /* REP MOVS */ + case 0xA4: case 0xA5: + addr = regs->si; + break; + default: + return false; + } + + if (fault_in_kernel_space(addr)) + return false; + + current->mce_vaddr = (void __user *)addr; + + return true; +} + /* * If mcgstatus indicated that ip/cs on the stack were * no good, then "m->cs" will be zero and we will have @@ -209,15 +267,25 @@ static struct severity { * distinguish an exception taken in user from from one * taken in the kernel. */ -static int error_context(struct mce *m) +static int error_context(struct mce *m, struct pt_regs *regs) { + enum handler_type t; + if ((m->cs & 3) == 3) return IN_USER; + if (!mc_recoverable(m->mcgstatus)) + return IN_KERNEL; - if (mc_recoverable(m->mcgstatus) && ex_has_fault_handler(m->ip)) { + t = ex_get_fault_handler_type(m->ip); + if (t == EX_HANDLER_FAULT) { m->kflags |= MCE_IN_KERNEL_RECOV; return IN_KERNEL_RECOV; } + if (t == EX_HANDLER_UACCESS && regs && is_copy_from_user(regs)) { + m->kflags |= MCE_IN_KERNEL_RECOV; + m->kflags |= MCE_IN_KERNEL_COPYIN; + return IN_KERNEL_RECOV; + } return IN_KERNEL; } @@ -253,9 +321,10 @@ static int mce_severity_amd_smca(struct mce *m, enum context err_ctx) * See AMD Error Scope Hierarchy table in a newer BKDG. For example * 49125_15h_Models_30h-3Fh_BKDG.pdf, section "RAS Features" */ -static int mce_severity_amd(struct mce *m, int tolerant, char **msg, bool is_excp) +static int mce_severity_amd(struct mce *m, struct pt_regs *regs, int tolerant, + char **msg, bool is_excp) { - enum context ctx = error_context(m); + enum context ctx = error_context(m, regs); /* Processor Context Corrupt, no need to fumble too much, die! */ if (m->status & MCI_STATUS_PCC) @@ -305,10 +374,11 @@ static int mce_severity_amd(struct mce *m, int tolerant, char **msg, bool is_exc return MCE_KEEP_SEVERITY; } -static int mce_severity_intel(struct mce *m, int tolerant, char **msg, bool is_excp) +static int mce_severity_intel(struct mce *m, struct pt_regs *regs, + int tolerant, char **msg, bool is_excp) { enum exception excp = (is_excp ? EXCP_CONTEXT : NO_EXCP); - enum context ctx = error_context(m); + enum context ctx = error_context(m, regs); struct severity *s; for (s = severities;; s++) { @@ -324,6 +394,12 @@ static int mce_severity_intel(struct mce *m, int tolerant, char **msg, bool is_e continue; if (s->excp && excp != s->excp) continue; + if (s->cpu_model && boot_cpu_data.x86_model != s->cpu_model) + continue; + if (s->cpu_minstepping && boot_cpu_data.x86_stepping < s->cpu_minstepping) + continue; + if (s->bank_lo && (m->bank < s->bank_lo || m->bank > s->bank_hi)) + continue; if (msg) *msg = s->msg; s->covered = 1; @@ -336,7 +412,7 @@ static int mce_severity_intel(struct mce *m, int tolerant, char **msg, bool is_e } /* Default to mce_severity_intel */ -int (*mce_severity)(struct mce *m, int tolerant, char **msg, bool is_excp) = +int (*mce_severity)(struct mce *m, struct pt_regs *regs, int tolerant, char **msg, bool is_excp) = mce_severity_intel; void __init mcheck_vendor_init_severity(void) diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 31125448b174..05ef1f4550cb 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -55,9 +55,14 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_callback) set_irq_regs(old_regs); } -void hv_setup_vmbus_irq(void (*handler)(void)) +int hv_setup_vmbus_irq(int irq, void (*handler)(void)) { + /* + * The 'irq' argument is ignored on x86/x64 because a hard-coded + * interrupt vector is used for Hyper-V interrupts. + */ vmbus_handler = handler; + return 0; } void hv_remove_vmbus_irq(void) @@ -248,7 +253,7 @@ static void __init ms_hyperv_init_platform(void) hv_host_info_edx >> 24, hv_host_info_edx & 0xFFFFFF); } - if (ms_hyperv.features & HV_X64_ACCESS_FREQUENCY_MSRS && + if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS && ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) { x86_platform.calibrate_tsc = hv_get_tsc_khz; x86_platform.calibrate_cpu = hv_get_tsc_khz; @@ -270,7 +275,7 @@ static void __init ms_hyperv_init_platform(void) crash_kexec_post_notifiers = true; #ifdef CONFIG_X86_LOCAL_APIC - if (ms_hyperv.features & HV_X64_ACCESS_FREQUENCY_MSRS && + if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS && ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) { /* * Get the APIC frequency. @@ -296,7 +301,7 @@ static void __init ms_hyperv_init_platform(void) machine_ops.shutdown = hv_machine_shutdown; machine_ops.crash_shutdown = hv_machine_crash_shutdown; #endif - if (ms_hyperv.features & HV_X64_ACCESS_TSC_INVARIANT) { + if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) { wrmsrl(HV_X64_MSR_TSC_INVARIANT_CONTROL, 0x1); setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE); } else { @@ -330,7 +335,7 @@ static void __init ms_hyperv_init_platform(void) alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_hyperv_callback); /* Setup the IDT for reenlightenment notifications */ - if (ms_hyperv.features & HV_X64_ACCESS_REENLIGHTENMENT) { + if (ms_hyperv.features & HV_ACCESS_REENLIGHTENMENT) { alloc_intr_gate(HYPERV_REENLIGHTENMENT_VECTOR, asm_sysvec_hyperv_reenlightenment); } diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c index 6a9df71c1b9e..e5f4ee8f4c3b 100644 --- a/arch/x86/kernel/cpu/resctrl/core.c +++ b/arch/x86/kernel/cpu/resctrl/core.c @@ -168,6 +168,7 @@ struct rdt_resource rdt_resources_all[] = { .name = "MB", .domains = domain_init(RDT_RESOURCE_MBA), .cache_level = 3, + .parse_ctrlval = parse_bw, .format_str = "%d=%*u", .fflags = RFTYPE_RES_MB, }, @@ -254,22 +255,30 @@ static bool __get_mem_config_intel(struct rdt_resource *r) { union cpuid_0x10_3_eax eax; union cpuid_0x10_x_edx edx; - u32 ebx, ecx; + u32 ebx, ecx, max_delay; cpuid_count(0x00000010, 3, &eax.full, &ebx, &ecx, &edx.full); r->num_closid = edx.split.cos_max + 1; - r->membw.max_delay = eax.split.max_delay + 1; + max_delay = eax.split.max_delay + 1; r->default_ctrl = MAX_MBA_BW; + r->membw.arch_needs_linear = true; if (ecx & MBA_IS_LINEAR) { r->membw.delay_linear = true; - r->membw.min_bw = MAX_MBA_BW - r->membw.max_delay; - r->membw.bw_gran = MAX_MBA_BW - r->membw.max_delay; + r->membw.min_bw = MAX_MBA_BW - max_delay; + r->membw.bw_gran = MAX_MBA_BW - max_delay; } else { if (!rdt_get_mb_table(r)) return false; + r->membw.arch_needs_linear = false; } r->data_width = 3; + if (boot_cpu_has(X86_FEATURE_PER_THREAD_MBA)) + r->membw.throttle_mode = THREAD_THROTTLE_PER_THREAD; + else + r->membw.throttle_mode = THREAD_THROTTLE_MAX; + thread_throttle_mode_init(); + r->alloc_capable = true; r->alloc_enabled = true; @@ -288,7 +297,13 @@ static bool __rdt_get_mem_config_amd(struct rdt_resource *r) /* AMD does not use delay */ r->membw.delay_linear = false; + r->membw.arch_needs_linear = false; + /* + * AMD does not use memory delay throttle model to control + * the allocation like Intel does. + */ + r->membw.throttle_mode = THREAD_THROTTLE_UNDEFINED; r->membw.min_bw = 0; r->membw.bw_gran = 1; /* Max value is 2048, Data width should be 4 in decimal */ @@ -346,19 +361,6 @@ static void rdt_get_cdp_l2_config(void) rdt_get_cdp_config(RDT_RESOURCE_L2, RDT_RESOURCE_L2CODE); } -static int get_cache_id(int cpu, int level) -{ - struct cpu_cacheinfo *ci = get_cpu_cacheinfo(cpu); - int i; - - for (i = 0; i < ci->num_leaves; i++) { - if (ci->info_list[i].level == level) - return ci->info_list[i].id; - } - - return -1; -} - static void mba_wrmsr_amd(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r) { @@ -556,13 +558,13 @@ static int domain_setup_mon_state(struct rdt_resource *r, struct rdt_domain *d) */ static void domain_add_cpu(int cpu, struct rdt_resource *r) { - int id = get_cache_id(cpu, r->cache_level); + int id = get_cpu_cacheinfo_id(cpu, r->cache_level); struct list_head *add_pos = NULL; struct rdt_domain *d; d = rdt_find_domain(r, id, &add_pos); if (IS_ERR(d)) { - pr_warn("Could't find cache id for cpu %d\n", cpu); + pr_warn("Couldn't find cache id for CPU %d\n", cpu); return; } @@ -602,12 +604,12 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r) static void domain_remove_cpu(int cpu, struct rdt_resource *r) { - int id = get_cache_id(cpu, r->cache_level); + int id = get_cpu_cacheinfo_id(cpu, r->cache_level); struct rdt_domain *d; d = rdt_find_domain(r, id, NULL); if (IS_ERR_OR_NULL(d)) { - pr_warn("Could't find cache id for cpu %d\n", cpu); + pr_warn("Couldn't find cache id for CPU %d\n", cpu); return; } @@ -918,12 +920,12 @@ static __init void rdt_init_res_defs_intel(void) r->rid == RDT_RESOURCE_L3CODE || r->rid == RDT_RESOURCE_L2 || r->rid == RDT_RESOURCE_L2DATA || - r->rid == RDT_RESOURCE_L2CODE) - r->cbm_validate = cbm_validate_intel; - else if (r->rid == RDT_RESOURCE_MBA) { + r->rid == RDT_RESOURCE_L2CODE) { + r->cache.arch_has_sparse_bitmaps = false; + r->cache.arch_has_empty_bitmaps = false; + } else if (r->rid == RDT_RESOURCE_MBA) { r->msr_base = MSR_IA32_MBA_THRTL_BASE; r->msr_update = mba_wrmsr_intel; - r->parse_ctrlval = parse_bw_intel; } } } @@ -938,12 +940,12 @@ static __init void rdt_init_res_defs_amd(void) r->rid == RDT_RESOURCE_L3CODE || r->rid == RDT_RESOURCE_L2 || r->rid == RDT_RESOURCE_L2DATA || - r->rid == RDT_RESOURCE_L2CODE) - r->cbm_validate = cbm_validate_amd; - else if (r->rid == RDT_RESOURCE_MBA) { + r->rid == RDT_RESOURCE_L2CODE) { + r->cache.arch_has_sparse_bitmaps = true; + r->cache.arch_has_empty_bitmaps = true; + } else if (r->rid == RDT_RESOURCE_MBA) { r->msr_base = MSR_IA32_MBA_BW_BASE; r->msr_update = mba_wrmsr_amd; - r->parse_ctrlval = parse_bw_amd; } } } diff --git a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c index 934c8fb8a64a..c877642e8a14 100644 --- a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c +++ b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c @@ -23,53 +23,6 @@ /* * Check whether MBA bandwidth percentage value is correct. The value is - * checked against the minimum and maximum bandwidth values specified by - * the hardware. The allocated bandwidth percentage is rounded to the next - * control step available on the hardware. - */ -static bool bw_validate_amd(char *buf, unsigned long *data, - struct rdt_resource *r) -{ - unsigned long bw; - int ret; - - ret = kstrtoul(buf, 10, &bw); - if (ret) { - rdt_last_cmd_printf("Non-decimal digit in MB value %s\n", buf); - return false; - } - - if (bw < r->membw.min_bw || bw > r->default_ctrl) { - rdt_last_cmd_printf("MB value %ld out of range [%d,%d]\n", bw, - r->membw.min_bw, r->default_ctrl); - return false; - } - - *data = roundup(bw, (unsigned long)r->membw.bw_gran); - return true; -} - -int parse_bw_amd(struct rdt_parse_data *data, struct rdt_resource *r, - struct rdt_domain *d) -{ - unsigned long bw_val; - - if (d->have_new_ctrl) { - rdt_last_cmd_printf("Duplicate domain %d\n", d->id); - return -EINVAL; - } - - if (!bw_validate_amd(data->buf, &bw_val, r)) - return -EINVAL; - - d->new_ctrl = bw_val; - d->have_new_ctrl = true; - - return 0; -} - -/* - * Check whether MBA bandwidth percentage value is correct. The value is * checked against the minimum and max bandwidth values specified by the * hardware. The allocated bandwidth percentage is rounded to the next * control step available on the hardware. @@ -82,7 +35,7 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r) /* * Only linear delay values is supported for current Intel SKUs. */ - if (!r->membw.delay_linear) { + if (!r->membw.delay_linear && r->membw.arch_needs_linear) { rdt_last_cmd_puts("No support for non-linear MB domains\n"); return false; } @@ -104,8 +57,8 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r) return true; } -int parse_bw_intel(struct rdt_parse_data *data, struct rdt_resource *r, - struct rdt_domain *d) +int parse_bw(struct rdt_parse_data *data, struct rdt_resource *r, + struct rdt_domain *d) { unsigned long bw_val; @@ -123,12 +76,14 @@ int parse_bw_intel(struct rdt_parse_data *data, struct rdt_resource *r, } /* - * Check whether a cache bit mask is valid. The SDM says: + * Check whether a cache bit mask is valid. + * For Intel the SDM says: * Please note that all (and only) contiguous '1' combinations * are allowed (e.g. FFFFH, 0FF0H, 003CH, etc.). * Additionally Haswell requires at least two bits set. + * AMD allows non-contiguous bitmasks. */ -bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r) +static bool cbm_validate(char *buf, u32 *data, struct rdt_resource *r) { unsigned long first_bit, zero_bit, val; unsigned int cbm_len = r->cache.cbm_len; @@ -140,7 +95,8 @@ bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r) return false; } - if (val == 0 || val > r->default_ctrl) { + if ((!r->cache.arch_has_empty_bitmaps && val == 0) || + val > r->default_ctrl) { rdt_last_cmd_puts("Mask out of range\n"); return false; } @@ -148,7 +104,9 @@ bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r) first_bit = find_first_bit(&val, cbm_len); zero_bit = find_next_zero_bit(&val, cbm_len, first_bit); - if (find_next_bit(&val, cbm_len, zero_bit) < cbm_len) { + /* Are non-contiguous bitmaps allowed? */ + if (!r->cache.arch_has_sparse_bitmaps && + (find_next_bit(&val, cbm_len, zero_bit) < cbm_len)) { rdt_last_cmd_printf("The mask %lx has non-consecutive 1-bits\n", val); return false; } @@ -164,30 +122,6 @@ bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r) } /* - * Check whether a cache bit mask is valid. AMD allows non-contiguous - * bitmasks - */ -bool cbm_validate_amd(char *buf, u32 *data, struct rdt_resource *r) -{ - unsigned long val; - int ret; - - ret = kstrtoul(buf, 16, &val); - if (ret) { - rdt_last_cmd_printf("Non-hex character in the mask %s\n", buf); - return false; - } - - if (val > r->default_ctrl) { - rdt_last_cmd_puts("Mask out of range\n"); - return false; - } - - *data = val; - return true; -} - -/* * Read one cache bit mask (hex). Check that it is valid for the current * resource type. */ @@ -212,7 +146,7 @@ int parse_cbm(struct rdt_parse_data *data, struct rdt_resource *r, return -EINVAL; } - if (!r->cbm_validate(data->buf, &cbm_val, r)) + if (!cbm_validate(data->buf, &cbm_val, r)) return -EINVAL; if ((rdtgrp->mode == RDT_MODE_EXCLUSIVE || diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h index 5ffa32256b3b..80fa997fae60 100644 --- a/arch/x86/kernel/cpu/resctrl/internal.h +++ b/arch/x86/kernel/cpu/resctrl/internal.h @@ -283,7 +283,6 @@ struct rftype { * struct mbm_state - status for each MBM counter in each domain * @chunks: Total data moved (multiply by rdt_group.mon_scale to get bytes) * @prev_msr Value of IA32_QM_CTR for this RMID last time we read it - * @chunks_bw Total local data moved. Used for bandwidth calculation * @prev_bw_msr:Value of previous IA32_QM_CTR for bandwidth counting * @prev_bw The most recent bandwidth in MBps * @delta_bw Difference between the current and previous bandwidth @@ -292,7 +291,6 @@ struct rftype { struct mbm_state { u64 chunks; u64 prev_msr; - u64 chunks_bw; u64 prev_bw_msr; u32 prev_bw; u32 delta_bw; @@ -360,6 +358,8 @@ struct msr_param { * in a cache bit mask * @shareable_bits: Bitmask of shareable resource with other * executing entities + * @arch_has_sparse_bitmaps: True if a bitmap like f00f is valid. + * @arch_has_empty_bitmaps: True if the '0' bitmap is valid. */ struct rdt_cache { unsigned int cbm_len; @@ -367,25 +367,43 @@ struct rdt_cache { unsigned int cbm_idx_mult; unsigned int cbm_idx_offset; unsigned int shareable_bits; + bool arch_has_sparse_bitmaps; + bool arch_has_empty_bitmaps; +}; + +/** + * enum membw_throttle_mode - System's memory bandwidth throttling mode + * @THREAD_THROTTLE_UNDEFINED: Not relevant to the system + * @THREAD_THROTTLE_MAX: Memory bandwidth is throttled at the core + * always using smallest bandwidth percentage + * assigned to threads, aka "max throttling" + * @THREAD_THROTTLE_PER_THREAD: Memory bandwidth is throttled at the thread + */ +enum membw_throttle_mode { + THREAD_THROTTLE_UNDEFINED = 0, + THREAD_THROTTLE_MAX, + THREAD_THROTTLE_PER_THREAD, }; /** * struct rdt_membw - Memory bandwidth allocation related data - * @max_delay: Max throttle delay. Delay is the hardware - * representation for memory bandwidth. * @min_bw: Minimum memory bandwidth percentage user can request * @bw_gran: Granularity at which the memory bandwidth is allocated * @delay_linear: True if memory B/W delay is in linear scale + * @arch_needs_linear: True if we can't configure non-linear resources + * @throttle_mode: Bandwidth throttling mode when threads request + * different memory bandwidths * @mba_sc: True if MBA software controller(mba_sc) is enabled * @mb_map: Mapping of memory B/W percentage to memory B/W delay */ struct rdt_membw { - u32 max_delay; - u32 min_bw; - u32 bw_gran; - u32 delay_linear; - bool mba_sc; - u32 *mb_map; + u32 min_bw; + u32 bw_gran; + u32 delay_linear; + bool arch_needs_linear; + enum membw_throttle_mode throttle_mode; + bool mba_sc; + u32 *mb_map; }; static inline bool is_llc_occupancy_enabled(void) @@ -437,7 +455,6 @@ struct rdt_parse_data { * @cache: Cache allocation related data * @format_str: Per resource format string to show domain value * @parse_ctrlval: Per resource function pointer to parse control values - * @cbm_validate Cache bitmask validate function * @evt_list: List of monitoring events * @num_rmid: Number of RMIDs available * @mon_scale: cqm counter * mon_scale = occupancy in bytes @@ -464,7 +481,6 @@ struct rdt_resource { int (*parse_ctrlval)(struct rdt_parse_data *data, struct rdt_resource *r, struct rdt_domain *d); - bool (*cbm_validate)(char *buf, u32 *data, struct rdt_resource *r); struct list_head evt_list; int num_rmid; unsigned int mon_scale; @@ -474,10 +490,8 @@ struct rdt_resource { int parse_cbm(struct rdt_parse_data *data, struct rdt_resource *r, struct rdt_domain *d); -int parse_bw_intel(struct rdt_parse_data *data, struct rdt_resource *r, - struct rdt_domain *d); -int parse_bw_amd(struct rdt_parse_data *data, struct rdt_resource *r, - struct rdt_domain *d); +int parse_bw(struct rdt_parse_data *data, struct rdt_resource *r, + struct rdt_domain *d); extern struct mutex rdtgroup_mutex; @@ -609,8 +623,7 @@ void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms); void cqm_handle_limbo(struct work_struct *work); bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d); void __check_limbo(struct rdt_domain *d, bool force_free); -bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r); -bool cbm_validate_amd(char *buf, u32 *data, struct rdt_resource *r); void rdt_domain_reconfigure_cdp(struct rdt_resource *r); +void __init thread_throttle_mode_init(void); #endif /* _ASM_X86_RESCTRL_INTERNAL_H */ diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c index 837d7d012b7b..54dffe574e67 100644 --- a/arch/x86/kernel/cpu/resctrl/monitor.c +++ b/arch/x86/kernel/cpu/resctrl/monitor.c @@ -279,8 +279,7 @@ static void mbm_bw_count(u32 rmid, struct rmid_read *rr) return; chunks = mbm_overflow_count(m->prev_bw_msr, tval, rr->r->mbm_width); - m->chunks_bw += chunks; - m->chunks = m->chunks_bw; + m->chunks += chunks; cur_bw = (chunks * r->mon_scale) >> 20; if (m->delta_comp) @@ -478,19 +477,13 @@ void cqm_handle_limbo(struct work_struct *work) mutex_lock(&rdtgroup_mutex); r = &rdt_resources_all[RDT_RESOURCE_L3]; - d = get_domain_from_cpu(cpu, r); - - if (!d) { - pr_warn_once("Failure to get domain for limbo worker\n"); - goto out_unlock; - } + d = container_of(work, struct rdt_domain, cqm_limbo.work); __check_limbo(d, false); if (has_busy_rmid(r, d)) schedule_delayed_work_on(cpu, &d->cqm_limbo, delay); -out_unlock: mutex_unlock(&rdtgroup_mutex); } @@ -520,10 +513,7 @@ void mbm_handle_overflow(struct work_struct *work) goto out_unlock; r = &rdt_resources_all[RDT_RESOURCE_L3]; - - d = get_domain_from_cpu(cpu, r); - if (!d) - goto out_unlock; + d = container_of(work, struct rdt_domain, mbm_over.work); list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) { mbm_update(r, d, prgrp->mon.rmid); diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index 3f844f14fc0a..af323e2e3100 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -561,7 +561,7 @@ static int __rdtgroup_move_task(struct task_struct *tsk, * callback has been invoked. */ atomic_inc(&rdtgrp->waitcount); - ret = task_work_add(tsk, &callback->work, true); + ret = task_work_add(tsk, &callback->work, TWA_RESUME); if (ret) { /* * Task is exiting. Drop the refcount and free the callback. @@ -592,6 +592,18 @@ static int __rdtgroup_move_task(struct task_struct *tsk, return ret; } +static bool is_closid_match(struct task_struct *t, struct rdtgroup *r) +{ + return (rdt_alloc_capable && + (r->type == RDTCTRL_GROUP) && (t->closid == r->closid)); +} + +static bool is_rmid_match(struct task_struct *t, struct rdtgroup *r) +{ + return (rdt_mon_capable && + (r->type == RDTMON_GROUP) && (t->rmid == r->mon.rmid)); +} + /** * rdtgroup_tasks_assigned - Test if tasks have been assigned to resource group * @r: Resource group @@ -607,8 +619,7 @@ int rdtgroup_tasks_assigned(struct rdtgroup *r) rcu_read_lock(); for_each_process_thread(p, t) { - if ((r->type == RDTCTRL_GROUP && t->closid == r->closid) || - (r->type == RDTMON_GROUP && t->rmid == r->mon.rmid)) { + if (is_closid_match(t, r) || is_rmid_match(t, r)) { ret = 1; break; } @@ -706,8 +717,7 @@ static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s) rcu_read_lock(); for_each_process_thread(p, t) { - if ((r->type == RDTCTRL_GROUP && t->closid == r->closid) || - (r->type == RDTMON_GROUP && t->rmid == r->mon.rmid)) + if (is_closid_match(t, r) || is_rmid_match(t, r)) seq_printf(s, "%d\n", t->pid); } rcu_read_unlock(); @@ -1017,6 +1027,19 @@ static int max_threshold_occ_show(struct kernfs_open_file *of, return 0; } +static int rdt_thread_throttle_mode_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct rdt_resource *r = of->kn->parent->priv; + + if (r->membw.throttle_mode == THREAD_THROTTLE_PER_THREAD) + seq_puts(seq, "per-thread\n"); + else + seq_puts(seq, "max\n"); + + return 0; +} + static ssize_t max_threshold_occ_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { @@ -1513,6 +1536,17 @@ static struct rftype res_common_files[] = { .seq_show = rdt_delay_linear_show, .fflags = RF_CTRL_INFO | RFTYPE_RES_MB, }, + /* + * Platform specific which (if any) capabilities are provided by + * thread_throttle_mode. Defer "fflags" initialization to platform + * discovery. + */ + { + .name = "thread_throttle_mode", + .mode = 0444, + .kf_ops = &rdtgroup_kf_single_ops, + .seq_show = rdt_thread_throttle_mode_show, + }, { .name = "max_threshold_occupancy", .mode = 0644, @@ -1583,7 +1617,7 @@ static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags) lockdep_assert_held(&rdtgroup_mutex); for (rft = rfts; rft < rfts + len; rft++) { - if ((fflags & rft->fflags) == rft->fflags) { + if (rft->fflags && ((fflags & rft->fflags) == rft->fflags)) { ret = rdtgroup_add_file(kn, rft); if (ret) goto error; @@ -1600,6 +1634,33 @@ error: return ret; } +static struct rftype *rdtgroup_get_rftype_by_name(const char *name) +{ + struct rftype *rfts, *rft; + int len; + + rfts = res_common_files; + len = ARRAY_SIZE(res_common_files); + + for (rft = rfts; rft < rfts + len; rft++) { + if (!strcmp(rft->name, name)) + return rft; + } + + return NULL; +} + +void __init thread_throttle_mode_init(void) +{ + struct rftype *rft; + + rft = rdtgroup_get_rftype_by_name("thread_throttle_mode"); + if (!rft) + return; + + rft->fflags = RF_CTRL_INFO | RFTYPE_RES_MB; +} + /** * rdtgroup_kn_mode_restrict - Restrict user access to named resctrl file * @r: The resource group with which the file is associated. @@ -2245,18 +2306,6 @@ static int reset_all_ctrls(struct rdt_resource *r) return 0; } -static bool is_closid_match(struct task_struct *t, struct rdtgroup *r) -{ - return (rdt_alloc_capable && - (r->type == RDTCTRL_GROUP) && (t->closid == r->closid)); -} - -static bool is_rmid_match(struct task_struct *t, struct rdtgroup *r) -{ - return (rdt_mon_capable && - (r->type == RDTMON_GROUP) && (t->rmid == r->mon.rmid)); -} - /* * Move tasks from one to the other group. If @from is NULL, then all tasks * in the systems are moved unconditionally (used for teardown). @@ -3196,7 +3245,7 @@ int __init rdtgroup_init(void) * It may also be ok since that would enable debugging of RDT before * resctrl is mounted. * The reason why the debugfs directory is created here and not in - * rdt_mount() is because rdt_mount() takes rdtgroup_mutex and + * rdt_get_tree() is because rdt_get_tree() takes rdtgroup_mutex and * during the debugfs directory creation also &sb->s_type->i_mutex_key * (the lockdep class of inode->i_rwsem). Other filesystem * interactions (eg. SyS_getdents) have the lock ordering: diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index 62b137c3c97a..866c9a9bcdee 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c @@ -35,12 +35,15 @@ static const struct cpuid_bit cpuid_bits[] = { { X86_FEATURE_CDP_L3, CPUID_ECX, 2, 0x00000010, 1 }, { X86_FEATURE_CDP_L2, CPUID_ECX, 2, 0x00000010, 2 }, { X86_FEATURE_MBA, CPUID_EBX, 3, 0x00000010, 0 }, + { X86_FEATURE_PER_THREAD_MBA, CPUID_ECX, 0, 0x00000010, 3 }, { X86_FEATURE_HW_PSTATE, CPUID_EDX, 7, 0x80000007, 0 }, { X86_FEATURE_CPB, CPUID_EDX, 9, 0x80000007, 0 }, { X86_FEATURE_PROC_FEEDBACK, CPUID_EDX, 11, 0x80000007, 0 }, { X86_FEATURE_MBA, CPUID_EBX, 6, 0x80000008, 0 }, { X86_FEATURE_SME, CPUID_EAX, 0, 0x8000001f, 0 }, { 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 }, { 0, 0, 0, 0, 0 } }; diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 9b6fafa69be9..924571fe5864 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c @@ -33,6 +33,7 @@ #include <asm/timer.h> #include <asm/apic.h> #include <asm/vmware.h> +#include <asm/svm.h> #undef pr_fmt #define pr_fmt(fmt) "vmware: " fmt @@ -476,10 +477,49 @@ static bool __init vmware_legacy_x2apic_available(void) (eax & (1 << VMWARE_CMD_LEGACY_X2APIC)) != 0; } +#ifdef CONFIG_AMD_MEM_ENCRYPT +static void vmware_sev_es_hcall_prepare(struct ghcb *ghcb, + struct pt_regs *regs) +{ + /* Copy VMWARE specific Hypercall parameters to the GHCB */ + ghcb_set_rip(ghcb, regs->ip); + ghcb_set_rbx(ghcb, regs->bx); + ghcb_set_rcx(ghcb, regs->cx); + ghcb_set_rdx(ghcb, regs->dx); + ghcb_set_rsi(ghcb, regs->si); + ghcb_set_rdi(ghcb, regs->di); + ghcb_set_rbp(ghcb, regs->bp); +} + +static bool vmware_sev_es_hcall_finish(struct ghcb *ghcb, struct pt_regs *regs) +{ + if (!(ghcb_rbx_is_valid(ghcb) && + ghcb_rcx_is_valid(ghcb) && + ghcb_rdx_is_valid(ghcb) && + ghcb_rsi_is_valid(ghcb) && + ghcb_rdi_is_valid(ghcb) && + 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; + + return true; +} +#endif + const __initconst struct hypervisor_x86 x86_hyper_vmware = { - .name = "VMware", - .detect = vmware_platform, - .type = X86_HYPER_VMWARE, - .init.init_platform = vmware_platform_setup, - .init.x2apic_available = vmware_legacy_x2apic_available, + .name = "VMware", + .detect = vmware_platform, + .type = X86_HYPER_VMWARE, + .init.init_platform = vmware_platform_setup, + .init.x2apic_available = vmware_legacy_x2apic_available, +#ifdef CONFIG_AMD_MEM_ENCRYPT + .runtime.sev_es_hcall_prepare = vmware_sev_es_hcall_prepare, + .runtime.sev_es_hcall_finish = vmware_sev_es_hcall_finish, +#endif }; diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index a0e8fc7d85f1..ddffd80f5c52 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -229,8 +229,8 @@ static int dt_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, it = &of_ioapic_type[type_index]; ioapic_set_alloc_attr(&tmp, NUMA_NO_NODE, it->trigger, it->polarity); - tmp.ioapic_id = mpc_ioapic_id(mp_irqdomain_ioapic_idx(domain)); - tmp.ioapic_pin = fwspec->param[0]; + tmp.devid = mpc_ioapic_id(mp_irqdomain_ioapic_idx(domain)); + tmp.ioapic.pin = fwspec->param[0]; return mp_irqdomain_alloc(domain, virq, nr_irqs, &tmp); } diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 48ce44576947..25c06b67e7e0 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -29,8 +29,8 @@ static int die_counter; static struct pt_regs exec_summary_regs; -bool in_task_stack(unsigned long *stack, struct task_struct *task, - struct stack_info *info) +bool noinstr in_task_stack(unsigned long *stack, struct task_struct *task, + struct stack_info *info) { unsigned long *begin = task_stack_page(task); unsigned long *end = task_stack_page(task) + THREAD_SIZE; @@ -46,7 +46,8 @@ bool in_task_stack(unsigned long *stack, struct task_struct *task, return true; } -bool in_entry_stack(unsigned long *stack, struct stack_info *info) +/* Called from get_stack_info_noinstr - so must be noinstr too */ +bool noinstr in_entry_stack(unsigned long *stack, struct stack_info *info) { struct entry_stack *ss = cpu_entry_stack(smp_processor_id()); @@ -115,7 +116,8 @@ void show_opcodes(struct pt_regs *regs, const char *loglvl) unsigned long prologue = regs->ip - PROLOGUE_SIZE; if (copy_code(regs, opcodes, prologue, sizeof(opcodes))) { - printk("%sCode: Bad RIP value.\n", loglvl); + printk("%sCode: Unable to access opcode bytes at RIP 0x%lx.\n", + loglvl, prologue); } else { printk("%sCode: %" __stringify(PROLOGUE_SIZE) "ph <%02x> %" __stringify(EPILOGUE_SIZE) "ph\n", loglvl, opcodes, diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 4a94d38cd141..1dd851397bd9 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -24,11 +24,13 @@ static const char * const exception_stack_names[] = { [ ESTACK_NMI ] = "NMI", [ ESTACK_DB ] = "#DB", [ ESTACK_MCE ] = "#MC", + [ ESTACK_VC ] = "#VC", + [ ESTACK_VC2 ] = "#VC2", }; const char *stack_type_name(enum stack_type type) { - BUILD_BUG_ON(N_EXCEPTION_STACKS != 4); + BUILD_BUG_ON(N_EXCEPTION_STACKS != 6); if (type == STACK_TYPE_IRQ) return "IRQ"; @@ -79,16 +81,18 @@ struct estack_pages estack_pages[CEA_ESTACK_PAGES] ____cacheline_aligned = { EPAGERANGE(NMI), EPAGERANGE(DB), EPAGERANGE(MCE), + EPAGERANGE(VC), + EPAGERANGE(VC2), }; -static bool in_exception_stack(unsigned long *stack, struct stack_info *info) +static __always_inline bool in_exception_stack(unsigned long *stack, struct stack_info *info) { unsigned long begin, end, stk = (unsigned long)stack; const struct estack_pages *ep; struct pt_regs *regs; unsigned int k; - BUILD_BUG_ON(N_EXCEPTION_STACKS != 4); + BUILD_BUG_ON(N_EXCEPTION_STACKS != 6); begin = (unsigned long)__this_cpu_read(cea_exception_stacks); /* @@ -122,7 +126,7 @@ static bool in_exception_stack(unsigned long *stack, struct stack_info *info) return true; } -static bool in_irq_stack(unsigned long *stack, struct stack_info *info) +static __always_inline bool in_irq_stack(unsigned long *stack, struct stack_info *info) { unsigned long *end = (unsigned long *)this_cpu_read(hardirq_stack_ptr); unsigned long *begin = end - (IRQ_STACK_SIZE / sizeof(long)); @@ -147,32 +151,38 @@ static bool in_irq_stack(unsigned long *stack, struct stack_info *info) return true; } -int get_stack_info(unsigned long *stack, struct task_struct *task, - struct stack_info *info, unsigned long *visit_mask) +bool noinstr get_stack_info_noinstr(unsigned long *stack, struct task_struct *task, + struct stack_info *info) { - if (!stack) - goto unknown; - - task = task ? : current; - if (in_task_stack(stack, task, info)) - goto recursion_check; + return true; if (task != current) - goto unknown; + return false; if (in_exception_stack(stack, info)) - goto recursion_check; + return true; if (in_irq_stack(stack, info)) - goto recursion_check; + return true; if (in_entry_stack(stack, info)) - goto recursion_check; + return true; + + return false; +} + +int get_stack_info(unsigned long *stack, struct task_struct *task, + struct stack_info *info, unsigned long *visit_mask) +{ + task = task ? : current; - goto unknown; + if (!stack) + goto unknown; + + if (!get_stack_info_noinstr(stack, task, info)) + goto unknown; -recursion_check: /* * Make sure we don't iterate through any given stack more than once. * If it comes up a second time then there's something wrong going on: diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 983cd53ed4c9..22aad412f965 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -305,6 +305,20 @@ static int __init cpcompare(const void *a, const void *b) return (ap->addr != ap->entry->addr) - (bp->addr != bp->entry->addr); } +static bool e820_nomerge(enum e820_type type) +{ + /* + * These types may indicate distinct platform ranges aligned to + * numa node, protection domain, performance domain, or other + * boundaries. Do not merge them. + */ + if (type == E820_TYPE_PRAM) + return true; + if (type == E820_TYPE_SOFT_RESERVED) + return true; + return false; +} + int __init e820__update_table(struct e820_table *table) { struct e820_entry *entries = table->entries; @@ -380,7 +394,7 @@ int __init e820__update_table(struct e820_table *table) } /* Continue building up new map based on this information: */ - if (current_type != last_type || current_type == E820_TYPE_PRAM) { + if (current_type != last_type || e820_nomerge(current_type)) { if (last_type != 0) { new_entries[new_nr_entries].size = change_point[chg_idx]->addr - last_addr; /* Move forward only if the new size was non-zero: */ diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c index 61ddc3a5e5c2..701f196d7c68 100644 --- a/arch/x86/kernel/fpu/init.c +++ b/arch/x86/kernel/fpu/init.c @@ -5,7 +5,6 @@ #include <asm/fpu/internal.h> #include <asm/tlbflush.h> #include <asm/setup.h> -#include <asm/cmdline.h> #include <linux/sched.h> #include <linux/sched/task.h> @@ -238,51 +237,11 @@ static void __init fpu__init_system_ctx_switch(void) } /* - * We parse fpu parameters early because fpu__init_system() is executed - * before parse_early_param(). - */ -static void __init fpu__init_parse_early_param(void) -{ - char arg[32]; - char *argptr = arg; - int bit; - -#ifdef CONFIG_X86_32 - if (cmdline_find_option_bool(boot_command_line, "no387")) -#ifdef CONFIG_MATH_EMULATION - setup_clear_cpu_cap(X86_FEATURE_FPU); -#else - pr_err("Option 'no387' required CONFIG_MATH_EMULATION enabled.\n"); -#endif - - if (cmdline_find_option_bool(boot_command_line, "nofxsr")) - setup_clear_cpu_cap(X86_FEATURE_FXSR); -#endif - - if (cmdline_find_option_bool(boot_command_line, "noxsave")) - setup_clear_cpu_cap(X86_FEATURE_XSAVE); - - if (cmdline_find_option_bool(boot_command_line, "noxsaveopt")) - setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); - - if (cmdline_find_option_bool(boot_command_line, "noxsaves")) - setup_clear_cpu_cap(X86_FEATURE_XSAVES); - - if (cmdline_find_option(boot_command_line, "clearcpuid", arg, - sizeof(arg)) && - get_option(&argptr, &bit) && - bit >= 0 && - bit < NCAPINTS * 32) - setup_clear_cpu_cap(bit); -} - -/* * Called on the boot CPU once per system bootup, to set up the initial * FPU state that is later cloned into all processes: */ void __init fpu__init_system(struct cpuinfo_x86 *c) { - fpu__init_parse_early_param(); fpu__init_system_early_generic(c); /* diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index 038e19c0019e..5d8047441a0a 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -37,6 +37,7 @@ static const char *xfeature_names[] = "AVX-512 ZMM_Hi256" , "Processor Trace (unused)" , "Protection Keys User registers", + "PASID state", "unknown xstate feature" , }; @@ -51,6 +52,7 @@ static short xsave_cpuid_features[] __initdata = { X86_FEATURE_AVX512F, X86_FEATURE_INTEL_PT, X86_FEATURE_PKU, + X86_FEATURE_ENQCMD, }; /* @@ -318,6 +320,7 @@ static void __init print_xstate_features(void) print_xstate_feature(XFEATURE_MASK_ZMM_Hi256); print_xstate_feature(XFEATURE_MASK_Hi16_ZMM); print_xstate_feature(XFEATURE_MASK_PKRU); + print_xstate_feature(XFEATURE_MASK_PASID); } /* @@ -592,6 +595,7 @@ static void check_xstate_against_struct(int nr) XCHECK_SZ(sz, nr, XFEATURE_ZMM_Hi256, struct avx_512_zmm_uppers_state); XCHECK_SZ(sz, nr, XFEATURE_Hi16_ZMM, struct avx_512_hi16_state); XCHECK_SZ(sz, nr, XFEATURE_PKRU, struct pkru_state); + XCHECK_SZ(sz, nr, XFEATURE_PASID, struct ia32_pasid_state); /* * Make *SURE* to add any feature numbers in below if @@ -601,7 +605,7 @@ static void check_xstate_against_struct(int nr) if ((nr < XFEATURE_YMM) || (nr >= XFEATURE_MAX) || (nr == XFEATURE_PT_UNIMPLEMENTED_SO_FAR) || - ((nr >= XFEATURE_RSRVD_COMP_10) && (nr <= XFEATURE_LBR))) { + ((nr >= XFEATURE_RSRVD_COMP_11) && (nr <= XFEATURE_LBR))) { WARN_ONCE(1, "no structure for xstate: %d\n", nr); XSTATE_WARN_ON(1); } @@ -1398,3 +1402,60 @@ int proc_pid_arch_status(struct seq_file *m, struct pid_namespace *ns, return 0; } #endif /* CONFIG_PROC_PID_ARCH_STATUS */ + +#ifdef CONFIG_IOMMU_SUPPORT +void update_pasid(void) +{ + u64 pasid_state; + u32 pasid; + + if (!cpu_feature_enabled(X86_FEATURE_ENQCMD)) + return; + + if (!current->mm) + return; + + pasid = READ_ONCE(current->mm->pasid); + /* Set the valid bit in the PASID MSR/state only for valid pasid. */ + pasid_state = pasid == PASID_DISABLED ? + pasid : pasid | MSR_IA32_PASID_VALID; + + /* + * No need to hold fregs_lock() since the task's fpstate won't + * be changed by others (e.g. ptrace) while the task is being + * switched to or is in IPI. + */ + if (!test_thread_flag(TIF_NEED_FPU_LOAD)) { + /* The MSR is active and can be directly updated. */ + wrmsrl(MSR_IA32_PASID, pasid_state); + } else { + struct fpu *fpu = ¤t->thread.fpu; + struct ia32_pasid_state *ppasid_state; + struct xregs_state *xsave; + + /* + * The CPU's xstate registers are not currently active. Just + * update the PASID state in the memory buffer here. The + * PASID MSR will be loaded when returning to user mode. + */ + xsave = &fpu->state.xsave; + xsave->header.xfeatures |= XFEATURE_MASK_PASID; + ppasid_state = get_xsave_addr(xsave, XFEATURE_PASID); + /* + * Since XFEATURE_MASK_PASID is set in xfeatures, ppasid_state + * won't be NULL and no need to check its value. + * + * Only update the task's PASID state when it's different + * from the mm's pasid. + */ + if (ppasid_state->pasid != pasid_state) { + /* + * Invalid fpregs so that state restoring will pick up + * the PASID state. + */ + __fpu_invalidate_fpregs_state(fpu); + ppasid_state->pasid = pasid_state; + } + } +} +#endif /* CONFIG_IOMMU_SUPPORT */ diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index cbb71c1b574f..05e117137b45 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -36,6 +36,11 @@ #include <asm/microcode.h> #include <asm/kasan.h> #include <asm/fixmap.h> +#include <asm/realmode.h> +#include <asm/desc.h> +#include <asm/extable.h> +#include <asm/trapnr.h> +#include <asm/sev-es.h> /* * Manage page tables very early on. @@ -61,7 +66,25 @@ unsigned long vmemmap_base __ro_after_init = __VMEMMAP_BASE_L4; EXPORT_SYMBOL(vmemmap_base); #endif -#define __head __section(.head.text) +/* + * GDT used on the boot CPU before switching to virtual addresses. + */ +static struct desc_struct startup_gdt[GDT_ENTRIES] = { + [GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff), + [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff), + [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff), +}; + +/* + * Address needs to be set at runtime because it references the startup_gdt + * while the kernel still uses a direct mapping. + */ +static struct desc_ptr startup_gdt_descr = { + .size = sizeof(startup_gdt), + .address = 0, +}; + +#define __head __section(".head.text") static void __head *fixup_pointer(void *ptr, unsigned long physaddr) { @@ -297,7 +320,7 @@ static void __init reset_early_page_tables(void) } /* Create a new PMD entry */ -int __init __early_make_pgtable(unsigned long address, pmdval_t pmd) +bool __init __early_make_pgtable(unsigned long address, pmdval_t pmd) { unsigned long physaddr = address - __PAGE_OFFSET; pgdval_t pgd, *pgd_p; @@ -307,7 +330,7 @@ int __init __early_make_pgtable(unsigned long address, pmdval_t pmd) /* Invalid address or early pgt is done ? */ if (physaddr >= MAXMEM || read_cr3_pa() != __pa_nodebug(early_top_pgt)) - return -1; + return false; again: pgd_p = &early_top_pgt[pgd_index(address)].pgd; @@ -364,10 +387,10 @@ again: } pmd_p[pmd_index(address)] = pmd; - return 0; + return true; } -int __init early_make_pgtable(unsigned long address) +static bool __init early_make_pgtable(unsigned long address) { unsigned long physaddr = address - __PAGE_OFFSET; pmdval_t pmd; @@ -377,6 +400,19 @@ int __init early_make_pgtable(unsigned long address) return __early_make_pgtable(address, pmd); } +void __init do_early_exception(struct pt_regs *regs, int trapnr) +{ + if (trapnr == X86_TRAP_PF && + early_make_pgtable(native_read_cr2())) + return; + + if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT) && + trapnr == X86_TRAP_VC && handle_vc_boot_ghcb(regs)) + return; + + early_fixup_exception(regs, trapnr); +} + /* Don't add a printk in there. printk relies on the PDA which is not initialized yet. */ static void __init clear_bss(void) @@ -489,3 +525,81 @@ void __init x86_64_start_reservations(char *real_mode_data) start_kernel(); } + +/* + * Data structures and code used for IDT setup in head_64.S. The bringup-IDT is + * used until the idt_table takes over. On the boot CPU this happens in + * x86_64_start_kernel(), on secondary CPUs in start_secondary(). In both cases + * this happens in the functions called from head_64.S. + * + * The idt_table can't be used that early because all the code modifying it is + * in idt.c and can be instrumented by tracing or KASAN, which both don't work + * during early CPU bringup. Also the idt_table has the runtime vectors + * configured which require certain CPU state to be setup already (like TSS), + * which also hasn't happened yet in early CPU bringup. + */ +static gate_desc bringup_idt_table[NUM_EXCEPTION_VECTORS] __page_aligned_data; + +static struct desc_ptr bringup_idt_descr = { + .size = (NUM_EXCEPTION_VECTORS * sizeof(gate_desc)) - 1, + .address = 0, /* Set at runtime */ +}; + +static void set_bringup_idt_handler(gate_desc *idt, int n, void *handler) +{ +#ifdef CONFIG_AMD_MEM_ENCRYPT + struct idt_data data; + gate_desc desc; + + init_idt_data(&data, n, handler); + idt_init_desc(&desc, &data); + native_write_idt_entry(idt, n, &desc); +#endif +} + +/* This runs while still in the direct mapping */ +static void startup_64_load_idt(unsigned long physbase) +{ + struct desc_ptr *desc = fixup_pointer(&bringup_idt_descr, physbase); + gate_desc *idt = fixup_pointer(bringup_idt_table, physbase); + + + if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) { + void *handler; + + /* VMM Communication Exception */ + handler = fixup_pointer(vc_no_ghcb, physbase); + set_bringup_idt_handler(idt, X86_TRAP_VC, handler); + } + + desc->address = (unsigned long)idt; + native_load_idt(desc); +} + +/* This is used when running on kernel addresses */ +void early_setup_idt(void) +{ + /* VMM Communication Exception */ + if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) + set_bringup_idt_handler(bringup_idt_table, X86_TRAP_VC, vc_boot_ghcb); + + bringup_idt_descr.address = (unsigned long)bringup_idt_table; + native_load_idt(&bringup_idt_descr); +} + +/* + * Setup boot CPU state needed before kernel switches to virtual addresses. + */ +void __head startup_64_setup_env(unsigned long physbase) +{ + /* Load GDT */ + startup_gdt_descr.address = (unsigned long)fixup_pointer(startup_gdt, physbase); + native_load_gdt(&startup_gdt_descr); + + /* New GDT is live - reload data segment registers */ + asm volatile("movl %%eax, %%ds\n" + "movl %%eax, %%ss\n" + "movl %%eax, %%es\n" : : "a"(__KERNEL_DS) : "memory"); + + startup_64_load_idt(physbase); +} diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 16da4ac01597..7eb2a1c87969 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -73,6 +73,20 @@ SYM_CODE_START_NOALIGN(startup_64) /* Set up the stack for verify_cpu(), similar to initial_stack below */ leaq (__end_init_task - SIZEOF_PTREGS)(%rip), %rsp + leaq _text(%rip), %rdi + pushq %rsi + call startup_64_setup_env + popq %rsi + + /* Now switch to __KERNEL_CS so IRET works reliably */ + pushq $__KERNEL_CS + leaq .Lon_kernel_cs(%rip), %rax + pushq %rax + lretq + +.Lon_kernel_cs: + UNWIND_HINT_EMPTY + /* Sanitize CPU configuration */ call verify_cpu @@ -112,6 +126,18 @@ SYM_CODE_START(secondary_startup_64) call verify_cpu /* + * The secondary_startup_64_no_verify entry point is only used by + * SEV-ES guests. In those guests the call to verify_cpu() would cause + * #VC exceptions which can not be handled at this stage of secondary + * CPU bringup. + * + * All non SEV-ES systems, especially Intel systems, need to execute + * verify_cpu() above to make sure NX is enabled. + */ +SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL) + UNWIND_HINT_EMPTY + + /* * Retrieve the modifier (SME encryption mask if SME is active) to be * added to the initial pgdir entry that will be programmed into CR3. */ @@ -144,33 +170,6 @@ SYM_CODE_START(secondary_startup_64) 1: UNWIND_HINT_EMPTY - /* Check if nx is implemented */ - movl $0x80000001, %eax - cpuid - movl %edx,%edi - - /* Setup EFER (Extended Feature Enable Register) */ - movl $MSR_EFER, %ecx - rdmsr - btsl $_EFER_SCE, %eax /* Enable System Call */ - btl $20,%edi /* No Execute supported? */ - jnc 1f - btsl $_EFER_NX, %eax - btsq $_PAGE_BIT_NX,early_pmd_flags(%rip) -1: wrmsr /* Make changes effective */ - - /* Setup cr0 */ - movl $CR0_STATE, %eax - /* Make changes effective */ - movq %rax, %cr0 - - /* Setup a boot time stack */ - movq initial_stack(%rip), %rsp - - /* zero EFLAGS after setting rsp */ - pushq $0 - popfq - /* * We must switch to a new descriptor in kernel space for the GDT * because soon the kernel won't have access anymore to the userspace @@ -205,6 +204,41 @@ SYM_CODE_START(secondary_startup_64) movl initial_gs+4(%rip),%edx wrmsr + /* + * Setup a boot time stack - Any secondary CPU will have lost its stack + * by now because the cr3-switch above unmaps the real-mode stack + */ + movq initial_stack(%rip), %rsp + + /* Setup and Load IDT */ + pushq %rsi + call early_setup_idt + popq %rsi + + /* Check if nx is implemented */ + movl $0x80000001, %eax + cpuid + movl %edx,%edi + + /* Setup EFER (Extended Feature Enable Register) */ + movl $MSR_EFER, %ecx + rdmsr + btsl $_EFER_SCE, %eax /* Enable System Call */ + btl $20,%edi /* No Execute supported? */ + jnc 1f + btsl $_EFER_NX, %eax + btsq $_PAGE_BIT_NX,early_pmd_flags(%rip) +1: wrmsr /* Make changes effective */ + + /* Setup cr0 */ + movl $CR0_STATE, %eax + /* Make changes effective */ + movq %rax, %cr0 + + /* zero EFLAGS after setting rsp */ + pushq $0 + popfq + /* rsi is pointer to real mode structure with interesting info. pass it to C */ movq %rsi, %rdi @@ -259,11 +293,47 @@ SYM_CODE_START(start_cpu0) SYM_CODE_END(start_cpu0) #endif +#ifdef CONFIG_AMD_MEM_ENCRYPT +/* + * VC Exception handler used during early boot when running on kernel + * addresses, but before the switch to the idt_table can be made. + * The early_idt_handler_array can't be used here because it calls into a lot + * of __init code and this handler is also used during CPU offlining/onlining. + * Therefore this handler ends up in the .text section so that it stays around + * when .init.text is freed. + */ +SYM_CODE_START_NOALIGN(vc_boot_ghcb) + UNWIND_HINT_IRET_REGS offset=8 + + /* Build pt_regs */ + PUSH_AND_CLEAR_REGS + + /* Call C handler */ + movq %rsp, %rdi + movq ORIG_RAX(%rsp), %rsi + movq initial_vc_handler(%rip), %rax + ANNOTATE_RETPOLINE_SAFE + call *%rax + + /* Unwind pt_regs */ + POP_REGS + + /* Remove Error Code */ + addq $8, %rsp + + /* Pure iret required here - don't use INTERRUPT_RETURN */ + iretq +SYM_CODE_END(vc_boot_ghcb) +#endif + /* Both SMP bootup and ACPI suspend change these variables */ __REFDATA .balign 8 SYM_DATA(initial_code, .quad x86_64_start_kernel) SYM_DATA(initial_gs, .quad INIT_PER_CPU_VAR(fixed_percpu_data)) +#ifdef CONFIG_AMD_MEM_ENCRYPT +SYM_DATA(initial_vc_handler, .quad handle_vc_boot_ghcb) +#endif /* * The SIZEOF_PTREGS gap is a convention which helps the in-kernel unwinder @@ -319,22 +389,43 @@ SYM_CODE_START_LOCAL(early_idt_handler_common) pushq %r15 /* pt_regs->r15 */ UNWIND_HINT_REGS - cmpq $14,%rsi /* Page fault? */ - jnz 10f - GET_CR2_INTO(%rdi) /* can clobber %rax if pv */ - call early_make_pgtable - andl %eax,%eax - jz 20f /* All good */ - -10: movq %rsp,%rdi /* RDI = pt_regs; RSI is already trapnr */ - call early_fixup_exception + call do_early_exception -20: decl early_recursion_flag(%rip) jmp restore_regs_and_return_to_kernel SYM_CODE_END(early_idt_handler_common) +#ifdef CONFIG_AMD_MEM_ENCRYPT +/* + * VC Exception handler used during very early boot. The + * early_idt_handler_array can't be used because it returns via the + * paravirtualized INTERRUPT_RETURN and pv-ops don't work that early. + * + * This handler will end up in the .init.text section and not be + * available to boot secondary CPUs. + */ +SYM_CODE_START_NOALIGN(vc_no_ghcb) + UNWIND_HINT_IRET_REGS offset=8 + + /* Build pt_regs */ + PUSH_AND_CLEAR_REGS + + /* Call C handler */ + movq %rsp, %rdi + movq ORIG_RAX(%rsp), %rsi + call do_vc_no_ghcb + + /* Unwind pt_regs */ + POP_REGS + + /* Remove Error Code */ + addq $8, %rsp + + /* Pure iret required here - don't use INTERRUPT_RETURN */ + iretq +SYM_CODE_END(vc_no_ghcb) +#endif #define SYM_DATA_START_PAGE_ALIGNED(name) \ SYM_START(name, SYM_L_GLOBAL, .balign PAGE_SIZE) diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index b98ff620ba77..03aa33b58165 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -442,42 +442,6 @@ int hw_breakpoint_arch_parse(struct perf_event *bp, } /* - * Dump the debug register contents to the user. - * We can't dump our per cpu values because it - * may contain cpu wide breakpoint, something that - * doesn't belong to the current task. - * - * TODO: include non-ptrace user breakpoints (perf) - */ -void aout_dump_debugregs(struct user *dump) -{ - int i; - int dr7 = 0; - struct perf_event *bp; - struct arch_hw_breakpoint *info; - struct thread_struct *thread = ¤t->thread; - - for (i = 0; i < HBP_NUM; i++) { - bp = thread->ptrace_bps[i]; - - if (bp && !bp->attr.disabled) { - dump->u_debugreg[i] = bp->attr.bp_addr; - info = counter_arch_bp(bp); - dr7 |= encode_dr7(i, info->len, info->type); - } else { - dump->u_debugreg[i] = 0; - } - } - - dump->u_debugreg[4] = 0; - dump->u_debugreg[5] = 0; - dump->u_debugreg[6] = current->thread.debugreg6; - - dump->u_debugreg[7] = dr7; -} -EXPORT_SYMBOL_GPL(aout_dump_debugregs); - -/* * Release the user breakpoints used by ptrace */ void flush_ptrace_hw_breakpoint(struct task_struct *tsk) @@ -490,7 +454,7 @@ void flush_ptrace_hw_breakpoint(struct task_struct *tsk) t->ptrace_bps[i] = NULL; } - t->debugreg6 = 0; + t->virtual_dr6 = 0; t->ptrace_dr7 = 0; } @@ -500,7 +464,7 @@ void hw_breakpoint_restore(void) set_debugreg(__this_cpu_read(cpu_debugreg[1]), 1); set_debugreg(__this_cpu_read(cpu_debugreg[2]), 2); set_debugreg(__this_cpu_read(cpu_debugreg[3]), 3); - set_debugreg(current->thread.debugreg6, 6); + set_debugreg(DR6_RESERVED, 6); set_debugreg(__this_cpu_read(cpu_dr7), 7); } EXPORT_SYMBOL_GPL(hw_breakpoint_restore); @@ -523,10 +487,10 @@ EXPORT_SYMBOL_GPL(hw_breakpoint_restore); */ static int hw_breakpoint_handler(struct die_args *args) { - int i, cpu, rc = NOTIFY_STOP; + int i, rc = NOTIFY_STOP; struct perf_event *bp; - unsigned long dr6; unsigned long *dr6_p; + unsigned long dr6; /* The DR6 value is pointed by args->err */ dr6_p = (unsigned long *)ERR_PTR(args->err); @@ -540,14 +504,6 @@ static int hw_breakpoint_handler(struct die_args *args) if ((dr6 & DR_TRAP_BITS) == 0) return NOTIFY_DONE; - /* - * Assert that local interrupts are disabled - * Reset the DRn bits in the virtualized register value. - * The ptrace trigger routine will add in whatever is needed. - */ - current->thread.debugreg6 &= ~DR_TRAP_BITS; - cpu = get_cpu(); - /* Handle all the breakpoints that were triggered */ for (i = 0; i < HBP_NUM; ++i) { if (likely(!(dr6 & (DR_TRAP0 << i)))) @@ -561,7 +517,7 @@ static int hw_breakpoint_handler(struct die_args *args) */ rcu_read_lock(); - bp = per_cpu(bp_per_reg[i], cpu); + bp = this_cpu_read(bp_per_reg[i]); /* * Reset the 'i'th TRAP bit in dr6 to denote completion of * exception handling @@ -592,12 +548,10 @@ static int hw_breakpoint_handler(struct die_args *args) * breakpoints (to generate signals) and b) when the system has * taken exception due to multiple causes */ - if ((current->thread.debugreg6 & DR_TRAP_BITS) || + if ((current->thread.virtual_dr6 & DR_TRAP_BITS) || (dr6 & (~DR_TRAP_BITS))) rc = NOTIFY_DONE; - put_cpu(); - return rc; } diff --git a/arch/x86/kernel/idt.c b/arch/x86/kernel/idt.c index 7ecf9babf0cb..ee1a283f8e96 100644 --- a/arch/x86/kernel/idt.c +++ b/arch/x86/kernel/idt.c @@ -11,13 +11,6 @@ #include <asm/desc.h> #include <asm/hw_irq.h> -struct idt_data { - unsigned int vector; - unsigned int segment; - struct idt_bits bits; - const void *addr; -}; - #define DPL0 0x0 #define DPL3 0x3 @@ -149,9 +142,6 @@ static const __initconst struct idt_data apic_idts[] = { # ifdef CONFIG_IRQ_WORK INTG(IRQ_WORK_VECTOR, asm_sysvec_irq_work), # endif -# ifdef CONFIG_X86_UV - INTG(UV_BAU_MESSAGE, asm_sysvec_uv_bau_message), -# endif INTG(SPURIOUS_APIC_VECTOR, asm_sysvec_spurious_apic_interrupt), INTG(ERROR_APIC_VECTOR, asm_sysvec_error_interrupt), #endif @@ -178,20 +168,6 @@ bool idt_is_f00f_address(unsigned long address) } #endif -static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d) -{ - unsigned long addr = (unsigned long) d->addr; - - gate->offset_low = (u16) addr; - gate->segment = (u16) d->segment; - gate->bits = d->bits; - gate->offset_middle = (u16) (addr >> 16); -#ifdef CONFIG_X86_64 - gate->offset_high = (u32) (addr >> 32); - gate->reserved = 0; -#endif -} - static __init void idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size, bool sys) { @@ -209,14 +185,7 @@ static __init void set_intr_gate(unsigned int n, const void *addr) { struct idt_data data; - BUG_ON(n > 0xFF); - - memset(&data, 0, sizeof(data)); - data.vector = n; - data.addr = addr; - data.segment = __KERNEL_CS; - data.bits.type = GATE_INTERRUPT; - data.bits.p = 1; + init_idt_data(&data, n, addr); idt_setup_from_table(idt_table, &data, 1, false); } @@ -257,11 +226,14 @@ static const __initconst struct idt_data early_pf_idts[] = { * cpu_init() when the TSS has been initialized. */ static const __initconst struct idt_data ist_idts[] = { - ISTG(X86_TRAP_DB, asm_exc_debug, IST_INDEX_DB), - ISTG(X86_TRAP_NMI, asm_exc_nmi, IST_INDEX_NMI), - ISTG(X86_TRAP_DF, asm_exc_double_fault, IST_INDEX_DF), + ISTG(X86_TRAP_DB, asm_exc_debug, IST_INDEX_DB), + ISTG(X86_TRAP_NMI, asm_exc_nmi, IST_INDEX_NMI), + ISTG(X86_TRAP_DF, asm_exc_double_fault, IST_INDEX_DF), #ifdef CONFIG_X86_MCE - ISTG(X86_TRAP_MC, asm_exc_machine_check, IST_INDEX_MCE), + ISTG(X86_TRAP_MC, asm_exc_machine_check, IST_INDEX_MCE), +#endif +#ifdef CONFIG_AMD_MEM_ENCRYPT + ISTG(X86_TRAP_VC, asm_exc_vmm_communication, IST_INDEX_VC), #endif }; diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 181060247e3c..c5dd50369e2f 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -227,7 +227,7 @@ static __always_inline void handle_irq(struct irq_desc *desc, struct pt_regs *regs) { if (IS_ENABLED(CONFIG_X86_64)) - run_on_irqstack_cond(desc->handle_irq, desc, regs); + run_irq_on_irqstack_cond(desc->handle_irq, desc, regs); else __handle_irq(desc, regs); } diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c index 1b4fe93a86c5..440eed558558 100644 --- a/arch/x86/kernel/irq_64.c +++ b/arch/x86/kernel/irq_64.c @@ -74,5 +74,5 @@ int irq_init_percpu_irqstack(unsigned int cpu) void do_softirq_own_stack(void) { - run_on_irqstack_cond(__do_softirq, NULL, NULL); + run_on_irqstack_cond(__do_softirq, NULL); } diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index c2f02f308ecf..ff7878df96b4 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -629,9 +629,10 @@ static void kgdb_hw_overflow_handler(struct perf_event *event, struct task_struct *tsk = current; int i; - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { if (breakinfo[i].enabled) - tsk->thread.debugreg6 |= (DR_TRAP0 << i); + tsk->thread.virtual_dr6 |= (DR_TRAP0 << i); + } } void kgdb_arch_late(void) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index fdadc37d72af..547c7abb39f5 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -38,9 +38,9 @@ #include <linux/kdebug.h> #include <linux/kallsyms.h> #include <linux/ftrace.h> -#include <linux/frame.h> #include <linux/kasan.h> #include <linux/moduleloader.h> +#include <linux/objtool.h> #include <linux/vmalloc.h> #include <linux/pgtable.h> @@ -767,124 +767,21 @@ asm( NOKPROBE_SYMBOL(kretprobe_trampoline); STACK_FRAME_NON_STANDARD(kretprobe_trampoline); + /* * Called from kretprobe_trampoline */ __used __visible void *trampoline_handler(struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *tmp; - unsigned long flags, orig_ret_address = 0; - unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; - kprobe_opcode_t *correct_ret_addr = NULL; - void *frame_pointer; - bool skipped = false; - - /* - * Set a dummy kprobe for avoiding kretprobe recursion. - * Since kretprobe never run in kprobe handler, kprobe must not - * be running at this point. - */ - kprobe_busy_begin(); - - INIT_HLIST_HEAD(&empty_rp); - kretprobe_hash_lock(current, &head, &flags); /* fixup registers */ regs->cs = __KERNEL_CS; #ifdef CONFIG_X86_32 - regs->cs |= get_kernel_rpl(); regs->gs = 0; #endif - /* We use pt_regs->sp for return address holder. */ - frame_pointer = ®s->sp; - regs->ip = trampoline_address; + regs->ip = (unsigned long)&kretprobe_trampoline; regs->orig_ax = ~0UL; - /* - * It is possible to have multiple instances associated with a given - * task either because multiple functions in the call path have - * return probes installed on them, and/or more than one - * return probe was registered for a target function. - * - * We can handle this because: - * - instances are always pushed into the head of the list - * - when multiple return probes are registered for the same - * function, the (chronologically) first instance's ret_addr - * will be the real return address, and all the rest will - * point to kretprobe_trampoline. - */ - hlist_for_each_entry(ri, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - /* - * Return probes must be pushed on this hash list correct - * order (same as return order) so that it can be popped - * correctly. However, if we find it is pushed it incorrect - * order, this means we find a function which should not be - * probed, because the wrong order entry is pushed on the - * path of processing other kretprobe itself. - */ - if (ri->fp != frame_pointer) { - if (!skipped) - pr_warn("kretprobe is stacked incorrectly. Trying to fixup.\n"); - skipped = true; - continue; - } - - orig_ret_address = (unsigned long)ri->ret_addr; - if (skipped) - pr_warn("%ps must be blacklisted because of incorrect kretprobe order\n", - ri->rp->kp.addr); - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_assert(ri, orig_ret_address, trampoline_address); - - correct_ret_addr = ri->ret_addr; - hlist_for_each_entry_safe(ri, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - if (ri->fp != frame_pointer) - continue; - - orig_ret_address = (unsigned long)ri->ret_addr; - if (ri->rp && ri->rp->handler) { - __this_cpu_write(current_kprobe, &ri->rp->kp); - ri->ret_addr = correct_ret_addr; - ri->rp->handler(ri, regs); - __this_cpu_write(current_kprobe, &kprobe_busy); - } - - recycle_rp_inst(ri, &empty_rp); - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_hash_unlock(current, &flags); - - kprobe_busy_end(); - - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } - return (void *)orig_ret_address; + return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, ®s->sp); } NOKPROBE_SYMBOL(trampoline_handler); diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c index 40f380461e6d..041f0b50bc27 100644 --- a/arch/x86/kernel/kprobes/opt.c +++ b/arch/x86/kernel/kprobes/opt.c @@ -16,8 +16,9 @@ #include <linux/kdebug.h> #include <linux/kallsyms.h> #include <linux/ftrace.h> -#include <linux/frame.h> +#include <linux/objtool.h> #include <linux/pgtable.h> +#include <linux/static_call.h> #include <asm/text-patching.h> #include <asm/cacheflush.h> @@ -181,7 +182,6 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs) /* Save skipped registers */ regs->cs = __KERNEL_CS; #ifdef CONFIG_X86_32 - regs->cs |= get_kernel_rpl(); regs->gs = 0; #endif regs->ip = (unsigned long)op->kp.addr + INT3_INSN_SIZE; @@ -210,7 +210,8 @@ static int copy_optimized_instructions(u8 *dest, u8 *src, u8 *real) /* Check whether the address range is reserved */ if (ftrace_text_reserved(src, src + len - 1) || alternatives_text_reserved(src, src + len - 1) || - jump_label_text_reserved(src, src + len - 1)) + jump_label_text_reserved(src, src + len - 1) || + static_call_text_reserved(src, src + len - 1)) return -EBUSY; return len; diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 08320b0b2b27..7f57ede3cb8e 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -36,6 +36,8 @@ #include <asm/hypervisor.h> #include <asm/tlb.h> #include <asm/cpuidle_haltpoll.h> +#include <asm/ptrace.h> +#include <asm/svm.h> DEFINE_STATIC_KEY_FALSE(kvm_async_pf_enabled); @@ -270,9 +272,8 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_kvm_asyncpf_interrupt) { struct pt_regs *old_regs = set_irq_regs(regs); u32 token; - irqentry_state_t state; - state = irqentry_enter(regs); + ack_APIC_irq(); inc_irq_stat(irq_hv_callback_count); @@ -283,7 +284,6 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_kvm_asyncpf_interrupt) wrmsrl(MSR_KVM_ASYNC_PF_ACK, 1); } - irqentry_exit(regs, state); set_irq_regs(old_regs); } @@ -746,13 +746,34 @@ static void __init kvm_init_platform(void) x86_platform.apic_post_init = kvm_apic_init; } +#if defined(CONFIG_AMD_MEM_ENCRYPT) +static void kvm_sev_es_hcall_prepare(struct ghcb *ghcb, struct pt_regs *regs) +{ + /* RAX and CPL are already in the GHCB */ + ghcb_set_rbx(ghcb, regs->bx); + ghcb_set_rcx(ghcb, regs->cx); + ghcb_set_rdx(ghcb, regs->dx); + ghcb_set_rsi(ghcb, regs->si); +} + +static bool kvm_sev_es_hcall_finish(struct ghcb *ghcb, struct pt_regs *regs) +{ + /* No checking of the return state needed */ + return true; +} +#endif + const __initconst struct hypervisor_x86 x86_hyper_kvm = { - .name = "KVM", - .detect = kvm_detect, - .type = X86_HYPER_KVM, - .init.guest_late_init = kvm_guest_init, - .init.x2apic_available = kvm_para_available, - .init.init_platform = kvm_init_platform, + .name = "KVM", + .detect = kvm_detect, + .type = X86_HYPER_KVM, + .init.guest_late_init = kvm_guest_init, + .init.x2apic_available = kvm_para_available, + .init.init_platform = kvm_init_platform, +#if defined(CONFIG_AMD_MEM_ENCRYPT) + .runtime.sev_es_hcall_prepare = kvm_sev_es_hcall_prepare, + .runtime.sev_es_hcall_finish = kvm_sev_es_hcall_finish, +#endif }; static __init int activate_jump_labels(void) @@ -954,7 +975,7 @@ void arch_haltpoll_disable(unsigned int cpu) if (!kvm_para_has_feature(KVM_FEATURE_POLL_CONTROL)) return; - /* Enable guest halt poll disables host halt poll */ + /* Disable guest halt poll enables host halt poll */ smp_call_function_single(cpu, kvm_enable_host_haltpoll, NULL, 1); } EXPORT_SYMBOL_GPL(arch_haltpoll_disable); diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index baa21090c9be..8f06449aab27 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -24,7 +24,6 @@ #include <asm/irqdomain.h> #include <asm/mtrr.h> #include <asm/mpspec.h> -#include <asm/io_apic.h> #include <asm/proto.h> #include <asm/bios_ebda.h> #include <asm/e820/api.h> @@ -46,11 +45,6 @@ static int __init mpf_checksum(unsigned char *mp, int len) return sum & 0xFF; } -int __init default_mpc_apic_id(struct mpc_cpu *m) -{ - return m->apicid; -} - static void __init MP_processor_info(struct mpc_cpu *m) { int apicid; @@ -61,7 +55,7 @@ static void __init MP_processor_info(struct mpc_cpu *m) return; } - apicid = x86_init.mpparse.mpc_apic_id(m); + apicid = m->apicid; if (m->cpuflag & CPU_BOOTPROCESSOR) { bootup_cpu = " (Bootup-CPU)"; @@ -73,7 +67,7 @@ static void __init MP_processor_info(struct mpc_cpu *m) } #ifdef CONFIG_X86_IO_APIC -void __init default_mpc_oem_bus_info(struct mpc_bus *m, char *str) +static void __init mpc_oem_bus_info(struct mpc_bus *m, char *str) { memcpy(str, m->bustype, 6); str[6] = 0; @@ -84,7 +78,7 @@ static void __init MP_bus_info(struct mpc_bus *m) { char str[7]; - x86_init.mpparse.mpc_oem_bus_info(m, str); + mpc_oem_bus_info(m, str); #if MAX_MP_BUSSES < 256 if (m->busid >= MAX_MP_BUSSES) { @@ -100,9 +94,6 @@ static void __init MP_bus_info(struct mpc_bus *m) mp_bus_id_to_type[m->busid] = MP_BUS_ISA; #endif } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) { - if (x86_init.mpparse.mpc_oem_pci_bus) - x86_init.mpparse.mpc_oem_pci_bus(m); - clear_bit(m->busid, mp_bus_not_pci); #ifdef CONFIG_EISA mp_bus_id_to_type[m->busid] = MP_BUS_PCI; @@ -198,8 +189,6 @@ static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt) 1, mpc, mpc->length, 1); } -void __init default_smp_read_mpc_oem(struct mpc_table *mpc) { } - static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) { char str[16]; @@ -218,14 +207,7 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) if (early) return 1; - if (mpc->oemptr) - x86_init.mpparse.smp_read_mpc_oem(mpc); - - /* - * Now process the configuration blocks. - */ - x86_init.mpparse.mpc_record(0); - + /* Now process the configuration blocks. */ while (count < mpc->length) { switch (*mpt) { case MP_PROCESSOR: @@ -256,7 +238,6 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) count = mpc->length; break; } - x86_init.mpparse.mpc_record(1); } if (!num_processors) diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 49dcfb85e773..c0d409810658 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -80,18 +80,30 @@ static ssize_t msr_read(struct file *file, char __user *buf, static int filter_write(u32 reg) { + /* + * MSRs writes usually happen all at once, and can easily saturate kmsg. + * Only allow one message every 30 seconds. + * + * It's possible to be smarter here and do it (for example) per-MSR, but + * it would certainly be more complex, and this is enough at least to + * avoid saturating the ring buffer. + */ + static DEFINE_RATELIMIT_STATE(fw_rs, 30 * HZ, 1); + switch (allow_writes) { case MSR_WRITES_ON: return 0; case MSR_WRITES_OFF: return -EPERM; default: break; } + if (!__ratelimit(&fw_rs)) + return 0; + if (reg == MSR_IA32_ENERGY_PERF_BIAS) return 0; - pr_err_ratelimited("Write to unrecognized MSR 0x%x by %s\n" - "Please report to x86@kernel.org\n", - reg, current->comm); + pr_err("Write to unrecognized MSR 0x%x by %s (pid: %d). Please report to x86@kernel.org.\n", + reg, current->comm, current->pid); return 0; } diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index 4fc9954a9560..4bc77aaf1303 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -33,6 +33,7 @@ #include <asm/reboot.h> #include <asm/cache.h> #include <asm/nospec-branch.h> +#include <asm/sev-es.h> #define CREATE_TRACE_POINTS #include <trace/events/nmi.h> @@ -102,7 +103,6 @@ fs_initcall(nmi_warning_debugfs); static void nmi_check_duration(struct nmiaction *action, u64 duration) { - u64 whole_msecs = READ_ONCE(action->max_duration); int remainder_ns, decimal_msecs; if (duration < nmi_longest_ns || duration < action->max_duration) @@ -110,12 +110,12 @@ static void nmi_check_duration(struct nmiaction *action, u64 duration) action->max_duration = duration; - remainder_ns = do_div(whole_msecs, (1000 * 1000)); + remainder_ns = do_div(duration, (1000 * 1000)); decimal_msecs = remainder_ns / 1000; printk_ratelimited(KERN_INFO "INFO: NMI handler (%ps) took too long to run: %lld.%03d msecs\n", - action->handler, whole_msecs, decimal_msecs); + action->handler, duration, decimal_msecs); } static int nmi_handle(unsigned int type, struct pt_regs *regs) @@ -477,6 +477,12 @@ DEFINE_IDTENTRY_RAW(exc_nmi) { bool irq_state; + /* + * Re-enable NMIs right here when running as an SEV-ES guest. This might + * cause nested NMIs, but those can be handled safely. + */ + sev_es_nmi_complete(); + if (IS_ENABLED(CONFIG_SMP) && arch_cpu_is_offline(smp_processor_id())) return; @@ -488,6 +494,12 @@ DEFINE_IDTENTRY_RAW(exc_nmi) this_cpu_write(nmi_cr2, read_cr2()); nmi_restart: + /* + * Needs to happen before DR7 is accessed, because the hypervisor can + * intercept DR7 reads/writes, turning those into #VC exceptions. + */ + sev_es_ist_enter(regs); + this_cpu_write(nmi_dr7, local_db_save()); irq_state = idtentry_enter_nmi(regs); @@ -501,6 +513,8 @@ nmi_restart: local_db_restore(this_cpu_read(nmi_dr7)); + sev_es_ist_exit(); + if (unlikely(this_cpu_read(nmi_cr2) != read_cr2())) write_cr2(this_cpu_read(nmi_cr2)); if (this_cpu_dec_return(nmi_state)) diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index de2138ba38e5..6c3407ba6ee9 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -263,13 +263,8 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void) struct pv_info pv_info = { .name = "bare hardware", #ifdef CONFIG_PARAVIRT_XXL - .kernel_rpl = 0, - .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */ - -#ifdef CONFIG_X86_64 .extra_user_64bit_cs = __USER_CS, #endif -#endif }; /* 64-bit pagetable entries */ @@ -305,9 +300,7 @@ struct paravirt_patch_template pv_ops = { .cpu.load_idt = native_load_idt, .cpu.store_tr = native_store_tr, .cpu.load_tls = native_load_tls, -#ifdef CONFIG_X86_64 .cpu.load_gs_index = native_load_gs_index, -#endif .cpu.write_ldt_entry = native_write_ldt_entry, .cpu.write_gdt_entry = native_write_gdt_entry, .cpu.write_idt_entry = native_write_idt_entry, @@ -317,9 +310,7 @@ struct paravirt_patch_template pv_ops = { .cpu.load_sp0 = native_load_sp0, -#ifdef CONFIG_X86_64 .cpu.usergs_sysret64 = native_usergs_sysret64, -#endif .cpu.iret = native_iret, .cpu.swapgs = native_swapgs, @@ -369,24 +360,16 @@ struct paravirt_patch_template pv_ops = { .mmu.release_p4d = paravirt_nop, .mmu.set_pte = native_set_pte, - .mmu.set_pte_at = native_set_pte_at, .mmu.set_pmd = native_set_pmd, .mmu.ptep_modify_prot_start = __ptep_modify_prot_start, .mmu.ptep_modify_prot_commit = __ptep_modify_prot_commit, -#if CONFIG_PGTABLE_LEVELS >= 3 -#ifdef CONFIG_X86_PAE - .mmu.set_pte_atomic = native_set_pte_atomic, - .mmu.pte_clear = native_pte_clear, - .mmu.pmd_clear = native_pmd_clear, -#endif .mmu.set_pud = native_set_pud, .mmu.pmd_val = PTE_IDENT, .mmu.make_pmd = PTE_IDENT, -#if CONFIG_PGTABLE_LEVELS >= 4 .mmu.pud_val = PTE_IDENT, .mmu.make_pud = PTE_IDENT, @@ -398,8 +381,6 @@ struct paravirt_patch_template pv_ops = { .mmu.set_pgd = native_set_pgd, #endif /* CONFIG_PGTABLE_LEVELS >= 5 */ -#endif /* CONFIG_PGTABLE_LEVELS >= 4 */ -#endif /* CONFIG_PGTABLE_LEVELS >= 3 */ .mmu.pte_val = PTE_IDENT, .mmu.pgd_val = PTE_IDENT, diff --git a/arch/x86/kernel/paravirt_patch.c b/arch/x86/kernel/paravirt_patch.c index 3eff63c090d2..ace6e334cb39 100644 --- a/arch/x86/kernel/paravirt_patch.c +++ b/arch/x86/kernel/paravirt_patch.c @@ -26,14 +26,10 @@ struct patch_xxl { const unsigned char mmu_read_cr3[3]; const unsigned char mmu_write_cr3[3]; const unsigned char irq_restore_fl[2]; -# ifdef CONFIG_X86_64 const unsigned char cpu_wbinvd[2]; const unsigned char cpu_usergs_sysret64[6]; const unsigned char cpu_swapgs[3]; const unsigned char mov64[3]; -# else - const unsigned char cpu_iret[1]; -# endif }; static const struct patch_xxl patch_data_xxl = { @@ -42,7 +38,6 @@ static const struct patch_xxl patch_data_xxl = { .irq_save_fl = { 0x9c, 0x58 }, // pushf; pop %[re]ax .mmu_read_cr2 = { 0x0f, 0x20, 0xd0 }, // mov %cr2, %[re]ax .mmu_read_cr3 = { 0x0f, 0x20, 0xd8 }, // mov %cr3, %[re]ax -# ifdef CONFIG_X86_64 .mmu_write_cr3 = { 0x0f, 0x22, 0xdf }, // mov %rdi, %cr3 .irq_restore_fl = { 0x57, 0x9d }, // push %rdi; popfq .cpu_wbinvd = { 0x0f, 0x09 }, // wbinvd @@ -50,19 +45,11 @@ static const struct patch_xxl patch_data_xxl = { 0x48, 0x0f, 0x07 }, // swapgs; sysretq .cpu_swapgs = { 0x0f, 0x01, 0xf8 }, // swapgs .mov64 = { 0x48, 0x89, 0xf8 }, // mov %rdi, %rax -# else - .mmu_write_cr3 = { 0x0f, 0x22, 0xd8 }, // mov %eax, %cr3 - .irq_restore_fl = { 0x50, 0x9d }, // push %eax; popf - .cpu_iret = { 0xcf }, // iret -# endif }; unsigned int paravirt_patch_ident_64(void *insn_buff, unsigned int len) { -#ifdef CONFIG_X86_64 return PATCH(xxl, mov64, insn_buff, len); -#endif - return 0; } # endif /* CONFIG_PARAVIRT_XXL */ @@ -98,13 +85,9 @@ unsigned int native_patch(u8 type, void *insn_buff, unsigned long addr, PATCH_CASE(mmu, read_cr3, xxl, insn_buff, len); PATCH_CASE(mmu, write_cr3, xxl, insn_buff, len); -# ifdef CONFIG_X86_64 PATCH_CASE(cpu, usergs_sysret64, xxl, insn_buff, len); PATCH_CASE(cpu, swapgs, xxl, insn_buff, len); PATCH_CASE(cpu, wbinvd, xxl, insn_buff, len); -# else - PATCH_CASE(cpu, iret, xxl, insn_buff, len); -# endif #endif #ifdef CONFIG_PARAVIRT_SPINLOCKS diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 5dcedad21dff..de234e7a8962 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 +#include <linux/dma-map-ops.h> #include <linux/dma-direct.h> -#include <linux/dma-debug.h> #include <linux/iommu.h> #include <linux/dmar.h> #include <linux/export.h> diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 13ce616cc7af..ba4593a913fa 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -42,6 +42,7 @@ #include <asm/spec-ctrl.h> #include <asm/io_bitmap.h> #include <asm/proto.h> +#include <asm/frame.h> #include "process.h" @@ -133,7 +134,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg, fork_frame = container_of(childregs, struct fork_frame, regs); frame = &fork_frame->frame; - frame->bp = 0; + frame->bp = encode_frame_pointer(childregs); frame->ret_addr = (unsigned long) ret_from_fork; p->thread.sp = (unsigned long) fork_frame; p->thread.io_bitmap = NULL; diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 9afefe325acb..df342bedea88 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -407,7 +407,7 @@ unsigned long x86_gsbase_read_cpu_inactive(void) { unsigned long gsbase; - if (static_cpu_has(X86_FEATURE_FSGSBASE)) { + if (boot_cpu_has(X86_FEATURE_FSGSBASE)) { unsigned long flags; local_irq_save(flags); @@ -422,7 +422,7 @@ unsigned long x86_gsbase_read_cpu_inactive(void) void x86_gsbase_write_cpu_inactive(unsigned long gsbase) { - if (static_cpu_has(X86_FEATURE_FSGSBASE)) { + if (boot_cpu_has(X86_FEATURE_FSGSBASE)) { unsigned long flags; local_irq_save(flags); @@ -439,7 +439,7 @@ unsigned long x86_fsbase_read_task(struct task_struct *task) if (task == current) fsbase = x86_fsbase_read_cpu(); - else if (static_cpu_has(X86_FEATURE_FSGSBASE) || + else if (boot_cpu_has(X86_FEATURE_FSGSBASE) || (task->thread.fsindex == 0)) fsbase = task->thread.fsbase; else @@ -454,7 +454,7 @@ unsigned long x86_gsbase_read_task(struct task_struct *task) if (task == current) gsbase = x86_gsbase_read_cpu_inactive(); - else if (static_cpu_has(X86_FEATURE_FSGSBASE) || + else if (boot_cpu_has(X86_FEATURE_FSGSBASE) || (task->thread.gsindex == 0)) gsbase = task->thread.gsbase; else diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index e7537c5440bb..bedca011459c 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -465,7 +465,7 @@ static void ptrace_triggered(struct perf_event *bp, break; } - thread->debugreg6 |= (DR_TRAP0 << i); + thread->virtual_dr6 |= (DR_TRAP0 << i); } /* @@ -601,7 +601,7 @@ static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n) if (bp) val = bp->hw.info.address; } else if (n == 6) { - val = thread->debugreg6; + val = thread->virtual_dr6 ^ DR6_RESERVED; /* Flip back to arch polarity */ } else if (n == 7) { val = thread->ptrace_dr7; } @@ -657,7 +657,7 @@ static int ptrace_set_debugreg(struct task_struct *tsk, int n, if (n < HBP_NUM) { rc = ptrace_set_breakpoint_addr(tsk, n, val); } else if (n == 6) { - thread->debugreg6 = val; + thread->virtual_dr6 = val ^ DR6_RESERVED; /* Flip to positive polarity */ rc = 0; } else if (n == 7) { rc = ptrace_write_dr7(tsk, val); diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 1b10717c9321..6d0df6a58873 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c @@ -8,6 +8,7 @@ #include <asm/hpet.h> #include <asm/setup.h> +#include <asm/mce.h> #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI) @@ -624,10 +625,6 @@ static void amd_disable_seq_and_redirect_scrub(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3, amd_disable_seq_and_redirect_scrub); -#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE) -#include <linux/jump_label.h> -#include <asm/string_64.h> - /* Ivy Bridge, Haswell, Broadwell */ static void quirk_intel_brickland_xeon_ras_cap(struct pci_dev *pdev) { @@ -636,7 +633,7 @@ static void quirk_intel_brickland_xeon_ras_cap(struct pci_dev *pdev) pci_read_config_dword(pdev, 0x84, &capid0); if (capid0 & 0x10) - static_branch_inc(&mcsafe_key); + enable_copy_mc_fragile(); } /* Skylake */ @@ -653,7 +650,7 @@ static void quirk_intel_purley_xeon_ras_cap(struct pci_dev *pdev) * enabled, so memory machine check recovery is also enabled. */ if ((capid0 & 0xc0) == 0xc0 || (capid5 & 0x1e0)) - static_branch_inc(&mcsafe_key); + enable_copy_mc_fragile(); } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0ec3, quirk_intel_brickland_xeon_ras_cap); @@ -661,7 +658,6 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2fc0, quirk_intel_brickland_xeon_ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, quirk_intel_brickland_xeon_ras_cap); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2083, quirk_intel_purley_xeon_ras_cap); #endif -#endif bool x86_apple_machine; EXPORT_SYMBOL(x86_apple_machine); diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index a515e2d230b7..db115943e8bd 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -10,7 +10,7 @@ #include <linux/sched.h> #include <linux/tboot.h> #include <linux/delay.h> -#include <linux/frame.h> +#include <linux/objtool.h> #include <linux/pgtable.h> #include <acpi/reboot.h> #include <asm/io.h> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 3511736fbc74..84f581c91db4 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -7,6 +7,7 @@ */ #include <linux/console.h> #include <linux/crash_dump.h> +#include <linux/dma-map-ops.h> #include <linux/dmi.h> #include <linux/efi.h> #include <linux/init_ohci1394_dma.h> @@ -19,6 +20,8 @@ #include <linux/hugetlb.h> #include <linux/tboot.h> #include <linux/usb/xhci-dbgp.h> +#include <linux/static_call.h> +#include <linux/swiotlb.h> #include <uapi/linux/mount.h> @@ -263,16 +266,12 @@ static void __init relocate_initrd(void) u64 area_size = PAGE_ALIGN(ramdisk_size); /* We need to move the initrd down into directly mapped mem */ - relocated_ramdisk = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped), - area_size, PAGE_SIZE); - + relocated_ramdisk = memblock_phys_alloc_range(area_size, PAGE_SIZE, 0, + PFN_PHYS(max_pfn_mapped)); if (!relocated_ramdisk) panic("Cannot find place for new RAMDISK of size %lld\n", ramdisk_size); - /* Note: this includes all the mem currently occupied by - the initrd, we rely on that fact to keep the data intact. */ - memblock_reserve(relocated_ramdisk, area_size); initrd_start = relocated_ramdisk + PAGE_OFFSET; initrd_end = initrd_start + ramdisk_size; printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n", @@ -299,13 +298,13 @@ static void __init early_reserve_initrd(void) memblock_reserve(ramdisk_image, ramdisk_end - ramdisk_image); } + static void __init reserve_initrd(void) { /* Assume only end is not page aligned */ u64 ramdisk_image = get_ramdisk_image(); u64 ramdisk_size = get_ramdisk_size(); u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); - u64 mapped_size; if (!boot_params.hdr.type_of_loader || !ramdisk_image || !ramdisk_size) @@ -313,12 +312,6 @@ static void __init reserve_initrd(void) initrd_start = 0; - mapped_size = memblock_mem_size(max_pfn_mapped); - if (ramdisk_size >= (mapped_size>>1)) - panic("initrd too large to handle, " - "disabling initrd (%lld needed, %lld available)\n", - ramdisk_size, mapped_size>>1); - printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n", ramdisk_image, ramdisk_end - 1); @@ -430,13 +423,13 @@ static int __init reserve_crashkernel_low(void) { #ifdef CONFIG_X86_64 unsigned long long base, low_base = 0, low_size = 0; - unsigned long total_low_mem; + unsigned long low_mem_limit; int ret; - total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT)); + low_mem_limit = min(memblock_phys_mem_size(), CRASH_ADDR_LOW_MAX); /* crashkernel=Y,low */ - ret = parse_crashkernel_low(boot_command_line, total_low_mem, &low_size, &base); + ret = parse_crashkernel_low(boot_command_line, low_mem_limit, &low_size, &base); if (ret) { /* * two parts from kernel/dma/swiotlb.c: @@ -454,23 +447,17 @@ static int __init reserve_crashkernel_low(void) return 0; } - low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN); + low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 0, CRASH_ADDR_LOW_MAX); if (!low_base) { pr_err("Cannot reserve %ldMB crashkernel low memory, please try smaller size.\n", (unsigned long)(low_size >> 20)); return -ENOMEM; } - ret = memblock_reserve(low_base, low_size); - if (ret) { - pr_err("%s: Error reserving crashkernel low memblock.\n", __func__); - return ret; - } - - pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System low RAM: %ldMB)\n", + pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (low RAM limit: %ldMB)\n", (unsigned long)(low_size >> 20), (unsigned long)(low_base >> 20), - (unsigned long)(total_low_mem >> 20)); + (unsigned long)(low_mem_limit >> 20)); crashk_low_res.start = low_base; crashk_low_res.end = low_base + low_size - 1; @@ -514,13 +501,13 @@ static void __init reserve_crashkernel(void) * unless "crashkernel=size[KMG],high" is specified. */ if (!high) - crash_base = memblock_find_in_range(CRASH_ALIGN, - CRASH_ADDR_LOW_MAX, - crash_size, CRASH_ALIGN); + crash_base = memblock_phys_alloc_range(crash_size, + CRASH_ALIGN, CRASH_ALIGN, + CRASH_ADDR_LOW_MAX); if (!crash_base) - crash_base = memblock_find_in_range(CRASH_ALIGN, - CRASH_ADDR_HIGH_MAX, - crash_size, CRASH_ALIGN); + crash_base = memblock_phys_alloc_range(crash_size, + CRASH_ALIGN, CRASH_ALIGN, + CRASH_ADDR_HIGH_MAX); if (!crash_base) { pr_info("crashkernel reservation failed - No suitable area found.\n"); return; @@ -528,19 +515,13 @@ static void __init reserve_crashkernel(void) } else { unsigned long long start; - start = memblock_find_in_range(crash_base, - crash_base + crash_size, - crash_size, 1 << 20); + start = memblock_phys_alloc_range(crash_size, SZ_1M, crash_base, + crash_base + crash_size); if (start != crash_base) { pr_info("crashkernel reservation failed - memory is in use.\n"); return; } } - ret = memblock_reserve(crash_base, crash_size); - if (ret) { - pr_err("%s: Error reserving crashkernel memblock.\n", __func__); - return; - } if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) { memblock_free(crash_base, crash_size); @@ -849,6 +830,7 @@ void __init setup_arch(char **cmdline_p) early_cpu_init(); arch_init_ideal_nops(); jump_label_init(); + static_call_init(); early_ioremap_init(); setup_olpc_ofw_pgd(); @@ -1077,6 +1059,7 @@ void __init setup_arch(char **cmdline_p) efi_fake_memmap(); efi_find_mirror(); efi_esrt_init(); + efi_mokvar_table_init(); /* * The EFI specification says that boot service code won't be @@ -1218,6 +1201,7 @@ void __init setup_arch(char **cmdline_p) prefill_possible_map(); init_cpu_to_node(); + init_gi_nodes(); io_apic_init_mappings(); diff --git a/arch/x86/kernel/sev-es-shared.c b/arch/x86/kernel/sev-es-shared.c new file mode 100644 index 000000000000..5f83ccaab877 --- /dev/null +++ b/arch/x86/kernel/sev-es-shared.c @@ -0,0 +1,507 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD Encrypted Register State Support + * + * Author: Joerg Roedel <jroedel@suse.de> + * + * This file is not compiled stand-alone. It contains code shared + * between the pre-decompression boot code and the running Linux kernel + * and is included directly into both code-bases. + */ + +#ifndef __BOOT_COMPRESSED +#define error(v) pr_err(v) +#define has_cpuflag(f) boot_cpu_has(f) +#endif + +static bool __init sev_es_check_cpu_features(void) +{ + if (!has_cpuflag(X86_FEATURE_RDRAND)) { + error("RDRAND instruction not supported - no trusted source of randomness available\n"); + return false; + } + + return true; +} + +static void sev_es_terminate(unsigned int reason) +{ + u64 val = GHCB_SEV_TERMINATE; + + /* + * Tell the hypervisor what went wrong - only reason-set 0 is + * currently supported. + */ + val |= GHCB_SEV_TERMINATE_REASON(0, reason); + + /* Request Guest Termination from Hypvervisor */ + sev_es_wr_ghcb_msr(val); + VMGEXIT(); + + while (true) + asm volatile("hlt\n" : : : "memory"); +} + +static bool sev_es_negotiate_protocol(void) +{ + u64 val; + + /* Do the GHCB protocol version negotiation */ + sev_es_wr_ghcb_msr(GHCB_SEV_INFO_REQ); + VMGEXIT(); + val = sev_es_rd_ghcb_msr(); + + if (GHCB_INFO(val) != GHCB_SEV_INFO) + return false; + + if (GHCB_PROTO_MAX(val) < GHCB_PROTO_OUR || + GHCB_PROTO_MIN(val) > GHCB_PROTO_OUR) + return false; + + return true; +} + +static __always_inline void vc_ghcb_invalidate(struct ghcb *ghcb) +{ + memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap)); +} + +static bool vc_decoding_needed(unsigned long exit_code) +{ + /* Exceptions don't require to decode the instruction */ + return !(exit_code >= SVM_EXIT_EXCP_BASE && + exit_code <= SVM_EXIT_LAST_EXCP); +} + +static enum es_result vc_init_em_ctxt(struct es_em_ctxt *ctxt, + struct pt_regs *regs, + unsigned long exit_code) +{ + enum es_result ret = ES_OK; + + memset(ctxt, 0, sizeof(*ctxt)); + ctxt->regs = regs; + + if (vc_decoding_needed(exit_code)) + ret = vc_decode_insn(ctxt); + + return ret; +} + +static void vc_finish_insn(struct es_em_ctxt *ctxt) +{ + ctxt->regs->ip += ctxt->insn.length; +} + +static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb, + struct es_em_ctxt *ctxt, + u64 exit_code, u64 exit_info_1, + u64 exit_info_2) +{ + enum es_result ret; + + /* Fill in protocol and format specifiers */ + ghcb->protocol_version = GHCB_PROTOCOL_MAX; + ghcb->ghcb_usage = GHCB_DEFAULT_USAGE; + + ghcb_set_sw_exit_code(ghcb, exit_code); + ghcb_set_sw_exit_info_1(ghcb, exit_info_1); + ghcb_set_sw_exit_info_2(ghcb, exit_info_2); + + sev_es_wr_ghcb_msr(__pa(ghcb)); + VMGEXIT(); + + if ((ghcb->save.sw_exit_info_1 & 0xffffffff) == 1) { + u64 info = ghcb->save.sw_exit_info_2; + unsigned long v; + + info = ghcb->save.sw_exit_info_2; + v = info & SVM_EVTINJ_VEC_MASK; + + /* Check if exception information from hypervisor is sane. */ + if ((info & SVM_EVTINJ_VALID) && + ((v == X86_TRAP_GP) || (v == X86_TRAP_UD)) && + ((info & SVM_EVTINJ_TYPE_MASK) == SVM_EVTINJ_TYPE_EXEPT)) { + ctxt->fi.vector = v; + if (info & SVM_EVTINJ_VALID_ERR) + ctxt->fi.error_code = info >> 32; + ret = ES_EXCEPTION; + } else { + ret = ES_VMM_ERROR; + } + } else { + ret = ES_OK; + } + + return ret; +} + +/* + * Boot VC Handler - This is the first VC handler during boot, there is no GHCB + * page yet, so it only supports the MSR based communication with the + * hypervisor and only the CPUID exit-code. + */ +void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code) +{ + unsigned int fn = lower_bits(regs->ax, 32); + unsigned long val; + + /* Only CPUID is supported via MSR protocol */ + if (exit_code != SVM_EXIT_CPUID) + goto fail; + + sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_EAX)); + VMGEXIT(); + val = sev_es_rd_ghcb_msr(); + if (GHCB_SEV_GHCB_RESP_CODE(val) != GHCB_SEV_CPUID_RESP) + goto fail; + regs->ax = val >> 32; + + sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_EBX)); + VMGEXIT(); + val = sev_es_rd_ghcb_msr(); + if (GHCB_SEV_GHCB_RESP_CODE(val) != GHCB_SEV_CPUID_RESP) + goto fail; + regs->bx = val >> 32; + + sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_ECX)); + VMGEXIT(); + val = sev_es_rd_ghcb_msr(); + if (GHCB_SEV_GHCB_RESP_CODE(val) != GHCB_SEV_CPUID_RESP) + goto fail; + regs->cx = val >> 32; + + sev_es_wr_ghcb_msr(GHCB_CPUID_REQ(fn, GHCB_CPUID_REQ_EDX)); + VMGEXIT(); + val = sev_es_rd_ghcb_msr(); + if (GHCB_SEV_GHCB_RESP_CODE(val) != GHCB_SEV_CPUID_RESP) + goto fail; + regs->dx = val >> 32; + + /* Skip over the CPUID two-byte opcode */ + regs->ip += 2; + + return; + +fail: + sev_es_wr_ghcb_msr(GHCB_SEV_TERMINATE); + VMGEXIT(); + + /* Shouldn't get here - if we do halt the machine */ + while (true) + asm volatile("hlt\n"); +} + +static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt, + void *src, char *buf, + unsigned int data_size, + unsigned int count, + bool backwards) +{ + int i, b = backwards ? -1 : 1; + enum es_result ret = ES_OK; + + for (i = 0; i < count; i++) { + void *s = src + (i * data_size * b); + char *d = buf + (i * data_size); + + ret = vc_read_mem(ctxt, s, d, data_size); + if (ret != ES_OK) + break; + } + + return ret; +} + +static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt, + void *dst, char *buf, + unsigned int data_size, + unsigned int count, + bool backwards) +{ + int i, s = backwards ? -1 : 1; + enum es_result ret = ES_OK; + + for (i = 0; i < count; i++) { + void *d = dst + (i * data_size * s); + char *b = buf + (i * data_size); + + ret = vc_write_mem(ctxt, d, b, data_size); + if (ret != ES_OK) + break; + } + + return ret; +} + +#define IOIO_TYPE_STR BIT(2) +#define IOIO_TYPE_IN 1 +#define IOIO_TYPE_INS (IOIO_TYPE_IN | IOIO_TYPE_STR) +#define IOIO_TYPE_OUT 0 +#define IOIO_TYPE_OUTS (IOIO_TYPE_OUT | IOIO_TYPE_STR) + +#define IOIO_REP BIT(3) + +#define IOIO_ADDR_64 BIT(9) +#define IOIO_ADDR_32 BIT(8) +#define IOIO_ADDR_16 BIT(7) + +#define IOIO_DATA_32 BIT(6) +#define IOIO_DATA_16 BIT(5) +#define IOIO_DATA_8 BIT(4) + +#define IOIO_SEG_ES (0 << 10) +#define IOIO_SEG_DS (3 << 10) + +static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) +{ + struct insn *insn = &ctxt->insn; + *exitinfo = 0; + + switch (insn->opcode.bytes[0]) { + /* INS opcodes */ + case 0x6c: + case 0x6d: + *exitinfo |= IOIO_TYPE_INS; + *exitinfo |= IOIO_SEG_ES; + *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; + break; + + /* OUTS opcodes */ + case 0x6e: + case 0x6f: + *exitinfo |= IOIO_TYPE_OUTS; + *exitinfo |= IOIO_SEG_DS; + *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; + break; + + /* IN immediate opcodes */ + case 0xe4: + case 0xe5: + *exitinfo |= IOIO_TYPE_IN; + *exitinfo |= (u64)insn->immediate.value << 16; + break; + + /* OUT immediate opcodes */ + case 0xe6: + case 0xe7: + *exitinfo |= IOIO_TYPE_OUT; + *exitinfo |= (u64)insn->immediate.value << 16; + break; + + /* IN register opcodes */ + case 0xec: + case 0xed: + *exitinfo |= IOIO_TYPE_IN; + *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; + break; + + /* OUT register opcodes */ + case 0xee: + case 0xef: + *exitinfo |= IOIO_TYPE_OUT; + *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; + break; + + default: + return ES_DECODE_FAILED; + } + + switch (insn->opcode.bytes[0]) { + case 0x6c: + case 0x6e: + case 0xe4: + case 0xe6: + case 0xec: + case 0xee: + /* Single byte opcodes */ + *exitinfo |= IOIO_DATA_8; + break; + default: + /* Length determined by instruction parsing */ + *exitinfo |= (insn->opnd_bytes == 2) ? IOIO_DATA_16 + : IOIO_DATA_32; + } + switch (insn->addr_bytes) { + case 2: + *exitinfo |= IOIO_ADDR_16; + break; + case 4: + *exitinfo |= IOIO_ADDR_32; + break; + case 8: + *exitinfo |= IOIO_ADDR_64; + break; + } + + if (insn_has_rep_prefix(insn)) + *exitinfo |= IOIO_REP; + + return ES_OK; +} + +static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt) +{ + struct pt_regs *regs = ctxt->regs; + u64 exit_info_1, exit_info_2; + enum es_result ret; + + ret = vc_ioio_exitinfo(ctxt, &exit_info_1); + if (ret != ES_OK) + return ret; + + if (exit_info_1 & IOIO_TYPE_STR) { + + /* (REP) INS/OUTS */ + + bool df = ((regs->flags & X86_EFLAGS_DF) == X86_EFLAGS_DF); + unsigned int io_bytes, exit_bytes; + unsigned int ghcb_count, op_count; + unsigned long es_base; + u64 sw_scratch; + + /* + * For the string variants with rep prefix the amount of in/out + * operations per #VC exception is limited so that the kernel + * has a chance to take interrupts and re-schedule while the + * instruction is emulated. + */ + io_bytes = (exit_info_1 >> 4) & 0x7; + ghcb_count = sizeof(ghcb->shared_buffer) / io_bytes; + + op_count = (exit_info_1 & IOIO_REP) ? regs->cx : 1; + exit_info_2 = min(op_count, ghcb_count); + exit_bytes = exit_info_2 * io_bytes; + + es_base = insn_get_seg_base(ctxt->regs, INAT_SEG_REG_ES); + + /* Read bytes of OUTS into the shared buffer */ + if (!(exit_info_1 & IOIO_TYPE_IN)) { + ret = vc_insn_string_read(ctxt, + (void *)(es_base + regs->si), + ghcb->shared_buffer, io_bytes, + exit_info_2, df); + if (ret) + return ret; + } + + /* + * Issue an VMGEXIT to the HV to consume the bytes from the + * shared buffer or to have it write them into the shared buffer + * depending on the instruction: OUTS or INS. + */ + sw_scratch = __pa(ghcb) + offsetof(struct ghcb, shared_buffer); + ghcb_set_sw_scratch(ghcb, sw_scratch); + ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_IOIO, + exit_info_1, exit_info_2); + if (ret != ES_OK) + return ret; + + /* Read bytes from shared buffer into the guest's destination. */ + if (exit_info_1 & IOIO_TYPE_IN) { + ret = vc_insn_string_write(ctxt, + (void *)(es_base + regs->di), + ghcb->shared_buffer, io_bytes, + exit_info_2, df); + if (ret) + return ret; + + if (df) + regs->di -= exit_bytes; + else + regs->di += exit_bytes; + } else { + if (df) + regs->si -= exit_bytes; + else + regs->si += exit_bytes; + } + + if (exit_info_1 & IOIO_REP) + regs->cx -= exit_info_2; + + ret = regs->cx ? ES_RETRY : ES_OK; + + } else { + + /* IN/OUT into/from rAX */ + + int bits = (exit_info_1 & 0x70) >> 1; + u64 rax = 0; + + if (!(exit_info_1 & IOIO_TYPE_IN)) + rax = lower_bits(regs->ax, bits); + + ghcb_set_rax(ghcb, rax); + + ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_IOIO, exit_info_1, 0); + if (ret != ES_OK) + return ret; + + if (exit_info_1 & IOIO_TYPE_IN) { + if (!ghcb_rax_is_valid(ghcb)) + return ES_VMM_ERROR; + regs->ax = lower_bits(ghcb->save.rax, bits); + } + } + + return ret; +} + +static enum es_result vc_handle_cpuid(struct ghcb *ghcb, + struct es_em_ctxt *ctxt) +{ + struct pt_regs *regs = ctxt->regs; + u32 cr4 = native_read_cr4(); + enum es_result ret; + + ghcb_set_rax(ghcb, regs->ax); + ghcb_set_rcx(ghcb, regs->cx); + + if (cr4 & X86_CR4_OSXSAVE) + /* Safe to read xcr0 */ + ghcb_set_xcr0(ghcb, xgetbv(XCR_XFEATURE_ENABLED_MASK)); + else + /* xgetbv will cause #GP - use reset value for xcr0 */ + ghcb_set_xcr0(ghcb, 1); + + ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_CPUID, 0, 0); + if (ret != ES_OK) + return ret; + + if (!(ghcb_rax_is_valid(ghcb) && + ghcb_rbx_is_valid(ghcb) && + ghcb_rcx_is_valid(ghcb) && + ghcb_rdx_is_valid(ghcb))) + return ES_VMM_ERROR; + + regs->ax = ghcb->save.rax; + regs->bx = ghcb->save.rbx; + regs->cx = ghcb->save.rcx; + regs->dx = ghcb->save.rdx; + + return ES_OK; +} + +static enum es_result vc_handle_rdtsc(struct ghcb *ghcb, + struct es_em_ctxt *ctxt, + unsigned long exit_code) +{ + bool rdtscp = (exit_code == SVM_EXIT_RDTSCP); + enum es_result ret; + + ret = sev_es_ghcb_hv_call(ghcb, ctxt, exit_code, 0, 0); + if (ret != ES_OK) + return ret; + + if (!(ghcb_rax_is_valid(ghcb) && ghcb_rdx_is_valid(ghcb) && + (!rdtscp || ghcb_rcx_is_valid(ghcb)))) + return ES_VMM_ERROR; + + ctxt->regs->ax = ghcb->save.rax; + ctxt->regs->dx = ghcb->save.rdx; + if (rdtscp) + ctxt->regs->cx = ghcb->save.rcx; + + return ES_OK; +} diff --git a/arch/x86/kernel/sev-es.c b/arch/x86/kernel/sev-es.c new file mode 100644 index 000000000000..4a96726fbaf8 --- /dev/null +++ b/arch/x86/kernel/sev-es.c @@ -0,0 +1,1404 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * AMD Memory Encryption Support + * + * Copyright (C) 2019 SUSE + * + * Author: Joerg Roedel <jroedel@suse.de> + */ + +#define pr_fmt(fmt) "SEV-ES: " fmt + +#include <linux/sched/debug.h> /* For show_regs() */ +#include <linux/percpu-defs.h> +#include <linux/mem_encrypt.h> +#include <linux/lockdep.h> +#include <linux/printk.h> +#include <linux/mm_types.h> +#include <linux/set_memory.h> +#include <linux/memblock.h> +#include <linux/kernel.h> +#include <linux/mm.h> + +#include <asm/cpu_entry_area.h> +#include <asm/stacktrace.h> +#include <asm/sev-es.h> +#include <asm/insn-eval.h> +#include <asm/fpu/internal.h> +#include <asm/processor.h> +#include <asm/realmode.h> +#include <asm/traps.h> +#include <asm/svm.h> +#include <asm/smp.h> +#include <asm/cpu.h> + +#define DR7_RESET_VALUE 0x400 + +/* For early boot hypervisor communication in SEV-ES enabled guests */ +static struct ghcb boot_ghcb_page __bss_decrypted __aligned(PAGE_SIZE); + +/* + * Needs to be in the .data section because we need it NULL before bss is + * cleared + */ +static struct ghcb __initdata *boot_ghcb; + +/* #VC handler runtime per-CPU data */ +struct sev_es_runtime_data { + struct ghcb ghcb_page; + + /* Physical storage for the per-CPU IST stack of the #VC handler */ + char ist_stack[EXCEPTION_STKSZ] __aligned(PAGE_SIZE); + + /* + * Physical storage for the per-CPU fall-back stack of the #VC handler. + * The fall-back stack is used when it is not safe to switch back to the + * interrupted stack in the #VC entry code. + */ + char fallback_stack[EXCEPTION_STKSZ] __aligned(PAGE_SIZE); + + /* + * Reserve one page per CPU as backup storage for the unencrypted GHCB. + * It is needed when an NMI happens while the #VC handler uses the real + * GHCB, and the NMI handler itself is causing another #VC exception. In + * that case the GHCB content of the first handler needs to be backed up + * and restored. + */ + struct ghcb backup_ghcb; + + /* + * Mark the per-cpu GHCBs as in-use to detect nested #VC exceptions. + * There is no need for it to be atomic, because nothing is written to + * the GHCB between the read and the write of ghcb_active. So it is safe + * to use it when a nested #VC exception happens before the write. + * + * This is necessary for example in the #VC->NMI->#VC case when the NMI + * happens while the first #VC handler uses the GHCB. When the NMI code + * raises a second #VC handler it might overwrite the contents of the + * GHCB written by the first handler. To avoid this the content of the + * GHCB is saved and restored when the GHCB is detected to be in use + * already. + */ + bool ghcb_active; + bool backup_ghcb_active; + + /* + * Cached DR7 value - write it on DR7 writes and return it on reads. + * That value will never make it to the real hardware DR7 as debugging + * is currently unsupported in SEV-ES guests. + */ + unsigned long dr7; +}; + +struct ghcb_state { + struct ghcb *ghcb; +}; + +static DEFINE_PER_CPU(struct sev_es_runtime_data*, runtime_data); +DEFINE_STATIC_KEY_FALSE(sev_es_enable_key); + +/* Needed in vc_early_forward_exception */ +void do_early_exception(struct pt_regs *regs, int trapnr); + +static void __init setup_vc_stacks(int cpu) +{ + struct sev_es_runtime_data *data; + struct cpu_entry_area *cea; + unsigned long vaddr; + phys_addr_t pa; + + data = per_cpu(runtime_data, cpu); + cea = get_cpu_entry_area(cpu); + + /* Map #VC IST stack */ + vaddr = CEA_ESTACK_BOT(&cea->estacks, VC); + pa = __pa(data->ist_stack); + cea_set_pte((void *)vaddr, pa, PAGE_KERNEL); + + /* Map VC fall-back stack */ + vaddr = CEA_ESTACK_BOT(&cea->estacks, VC2); + pa = __pa(data->fallback_stack); + cea_set_pte((void *)vaddr, pa, PAGE_KERNEL); +} + +static __always_inline bool on_vc_stack(unsigned long sp) +{ + return ((sp >= __this_cpu_ist_bottom_va(VC)) && (sp < __this_cpu_ist_top_va(VC))); +} + +/* + * This function handles the case when an NMI is raised in the #VC exception + * handler entry code. In this case, the IST entry for #VC must be adjusted, so + * that any subsequent #VC exception will not overwrite the stack contents of the + * interrupted #VC handler. + * + * The IST entry is adjusted unconditionally so that it can be also be + * unconditionally adjusted back in sev_es_ist_exit(). Otherwise a nested + * sev_es_ist_exit() call may adjust back the IST entry too early. + */ +void noinstr __sev_es_ist_enter(struct pt_regs *regs) +{ + unsigned long old_ist, new_ist; + + /* Read old IST entry */ + old_ist = __this_cpu_read(cpu_tss_rw.x86_tss.ist[IST_INDEX_VC]); + + /* Make room on the IST stack */ + if (on_vc_stack(regs->sp)) + new_ist = ALIGN_DOWN(regs->sp, 8) - sizeof(old_ist); + else + new_ist = old_ist - sizeof(old_ist); + + /* Store old IST entry */ + *(unsigned long *)new_ist = old_ist; + + /* Set new IST entry */ + this_cpu_write(cpu_tss_rw.x86_tss.ist[IST_INDEX_VC], new_ist); +} + +void noinstr __sev_es_ist_exit(void) +{ + unsigned long ist; + + /* Read IST entry */ + ist = __this_cpu_read(cpu_tss_rw.x86_tss.ist[IST_INDEX_VC]); + + if (WARN_ON(ist == __this_cpu_ist_top_va(VC))) + return; + + /* Read back old IST entry and write it to the TSS */ + this_cpu_write(cpu_tss_rw.x86_tss.ist[IST_INDEX_VC], *(unsigned long *)ist); +} + +static __always_inline struct ghcb *sev_es_get_ghcb(struct ghcb_state *state) +{ + struct sev_es_runtime_data *data; + struct ghcb *ghcb; + + data = this_cpu_read(runtime_data); + ghcb = &data->ghcb_page; + + if (unlikely(data->ghcb_active)) { + /* GHCB is already in use - save its contents */ + + if (unlikely(data->backup_ghcb_active)) + return NULL; + + /* Mark backup_ghcb active before writing to it */ + data->backup_ghcb_active = true; + + state->ghcb = &data->backup_ghcb; + + /* Backup GHCB content */ + *state->ghcb = *ghcb; + } else { + state->ghcb = NULL; + data->ghcb_active = true; + } + + return ghcb; +} + +static __always_inline void sev_es_put_ghcb(struct ghcb_state *state) +{ + struct sev_es_runtime_data *data; + struct ghcb *ghcb; + + data = this_cpu_read(runtime_data); + ghcb = &data->ghcb_page; + + if (state->ghcb) { + /* Restore GHCB from Backup */ + *ghcb = *state->ghcb; + data->backup_ghcb_active = false; + state->ghcb = NULL; + } else { + data->ghcb_active = false; + } +} + +/* Needed in vc_early_forward_exception */ +void do_early_exception(struct pt_regs *regs, int trapnr); + +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) +{ + u32 low, high; + + low = (u32)(val); + high = (u32)(val >> 32); + + native_wrmsr(MSR_AMD64_SEV_ES_GHCB, low, high); +} + +static int vc_fetch_insn_kernel(struct es_em_ctxt *ctxt, + unsigned char *buffer) +{ + return copy_from_kernel_nofault(buffer, (unsigned char *)ctxt->regs->ip, MAX_INSN_SIZE); +} + +static enum es_result vc_decode_insn(struct es_em_ctxt *ctxt) +{ + char buffer[MAX_INSN_SIZE]; + enum es_result ret; + int res; + + if (user_mode(ctxt->regs)) { + res = insn_fetch_from_user(ctxt->regs, buffer); + if (!res) { + ctxt->fi.vector = X86_TRAP_PF; + ctxt->fi.error_code = X86_PF_INSTR | X86_PF_USER; + ctxt->fi.cr2 = ctxt->regs->ip; + return ES_EXCEPTION; + } + + if (!insn_decode(&ctxt->insn, ctxt->regs, buffer, res)) + return ES_DECODE_FAILED; + } else { + res = vc_fetch_insn_kernel(ctxt, buffer); + if (res) { + ctxt->fi.vector = X86_TRAP_PF; + ctxt->fi.error_code = X86_PF_INSTR; + ctxt->fi.cr2 = ctxt->regs->ip; + return ES_EXCEPTION; + } + + insn_init(&ctxt->insn, buffer, MAX_INSN_SIZE - res, 1); + insn_get_length(&ctxt->insn); + } + + ret = ctxt->insn.immediate.got ? ES_OK : ES_DECODE_FAILED; + + return ret; +} + +static enum es_result vc_write_mem(struct es_em_ctxt *ctxt, + char *dst, char *buf, size_t size) +{ + unsigned long error_code = X86_PF_PROT | X86_PF_WRITE; + char __user *target = (char __user *)dst; + u64 d8; + u32 d4; + u16 d2; + u8 d1; + + switch (size) { + case 1: + memcpy(&d1, buf, 1); + if (put_user(d1, target)) + goto fault; + break; + case 2: + memcpy(&d2, buf, 2); + if (put_user(d2, target)) + goto fault; + break; + case 4: + memcpy(&d4, buf, 4); + if (put_user(d4, target)) + goto fault; + break; + case 8: + memcpy(&d8, buf, 8); + if (put_user(d8, target)) + goto fault; + break; + default: + WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size); + return ES_UNSUPPORTED; + } + + return ES_OK; + +fault: + if (user_mode(ctxt->regs)) + error_code |= X86_PF_USER; + + ctxt->fi.vector = X86_TRAP_PF; + ctxt->fi.error_code = error_code; + ctxt->fi.cr2 = (unsigned long)dst; + + return ES_EXCEPTION; +} + +static enum es_result vc_read_mem(struct es_em_ctxt *ctxt, + char *src, char *buf, size_t size) +{ + unsigned long error_code = X86_PF_PROT; + char __user *s = (char __user *)src; + u64 d8; + u32 d4; + u16 d2; + u8 d1; + + switch (size) { + case 1: + if (get_user(d1, s)) + goto fault; + memcpy(buf, &d1, 1); + break; + case 2: + if (get_user(d2, s)) + goto fault; + memcpy(buf, &d2, 2); + break; + case 4: + if (get_user(d4, s)) + goto fault; + memcpy(buf, &d4, 4); + break; + case 8: + if (get_user(d8, s)) + goto fault; + memcpy(buf, &d8, 8); + break; + default: + WARN_ONCE(1, "%s: Invalid size: %zu\n", __func__, size); + return ES_UNSUPPORTED; + } + + return ES_OK; + +fault: + if (user_mode(ctxt->regs)) + error_code |= X86_PF_USER; + + ctxt->fi.vector = X86_TRAP_PF; + ctxt->fi.error_code = error_code; + ctxt->fi.cr2 = (unsigned long)src; + + return ES_EXCEPTION; +} + +static bool vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt *ctxt, + unsigned long vaddr, phys_addr_t *paddr) +{ + unsigned long va = (unsigned long)vaddr; + unsigned int level; + phys_addr_t pa; + pgd_t *pgd; + pte_t *pte; + + pgd = __va(read_cr3_pa()); + pgd = &pgd[pgd_index(va)]; + pte = lookup_address_in_pgd(pgd, va, &level); + if (!pte) { + ctxt->fi.vector = X86_TRAP_PF; + ctxt->fi.cr2 = vaddr; + ctxt->fi.error_code = 0; + + if (user_mode(ctxt->regs)) + ctxt->fi.error_code |= X86_PF_USER; + + return false; + } + + pa = (phys_addr_t)pte_pfn(*pte) << PAGE_SHIFT; + pa |= va & ~page_level_mask(level); + + *paddr = pa; + + return true; +} + +/* Include code shared with pre-decompression boot stage */ +#include "sev-es-shared.c" + +void noinstr __sev_es_nmi_complete(void) +{ + struct ghcb_state state; + struct ghcb *ghcb; + + ghcb = sev_es_get_ghcb(&state); + + vc_ghcb_invalidate(ghcb); + ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_NMI_COMPLETE); + ghcb_set_sw_exit_info_1(ghcb, 0); + ghcb_set_sw_exit_info_2(ghcb, 0); + + sev_es_wr_ghcb_msr(__pa_nodebug(ghcb)); + VMGEXIT(); + + sev_es_put_ghcb(&state); +} + +static u64 get_jump_table_addr(void) +{ + struct ghcb_state state; + unsigned long flags; + struct ghcb *ghcb; + u64 ret = 0; + + local_irq_save(flags); + + ghcb = sev_es_get_ghcb(&state); + + vc_ghcb_invalidate(ghcb); + ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_AP_JUMP_TABLE); + ghcb_set_sw_exit_info_1(ghcb, SVM_VMGEXIT_GET_AP_JUMP_TABLE); + ghcb_set_sw_exit_info_2(ghcb, 0); + + sev_es_wr_ghcb_msr(__pa(ghcb)); + VMGEXIT(); + + if (ghcb_sw_exit_info_1_is_valid(ghcb) && + ghcb_sw_exit_info_2_is_valid(ghcb)) + ret = ghcb->save.sw_exit_info_2; + + sev_es_put_ghcb(&state); + + local_irq_restore(flags); + + return ret; +} + +int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) +{ + u16 startup_cs, startup_ip; + phys_addr_t jump_table_pa; + u64 jump_table_addr; + u16 __iomem *jump_table; + + jump_table_addr = get_jump_table_addr(); + + /* On UP guests there is no jump table so this is not a failure */ + if (!jump_table_addr) + return 0; + + /* Check if AP Jump Table is page-aligned */ + if (jump_table_addr & ~PAGE_MASK) + return -EINVAL; + + jump_table_pa = jump_table_addr & PAGE_MASK; + + startup_cs = (u16)(rmh->trampoline_start >> 4); + startup_ip = (u16)(rmh->sev_es_trampoline_start - + rmh->trampoline_start); + + jump_table = ioremap_encrypted(jump_table_pa, PAGE_SIZE); + if (!jump_table) + return -EIO; + + writew(startup_ip, &jump_table[0]); + writew(startup_cs, &jump_table[1]); + + iounmap(jump_table); + + return 0; +} + +/* + * This is needed by the OVMF UEFI firmware which will use whatever it finds in + * the GHCB MSR as its GHCB to talk to the hypervisor. So make sure the per-cpu + * runtime GHCBs used by the kernel are also mapped in the EFI page-table. + */ +int __init sev_es_efi_map_ghcbs(pgd_t *pgd) +{ + struct sev_es_runtime_data *data; + unsigned long address, pflags; + int cpu; + u64 pfn; + + if (!sev_es_active()) + return 0; + + pflags = _PAGE_NX | _PAGE_RW; + + for_each_possible_cpu(cpu) { + data = per_cpu(runtime_data, cpu); + + address = __pa(&data->ghcb_page); + pfn = address >> PAGE_SHIFT; + + if (kernel_map_pages_in_pgd(pgd, pfn, address, 1, pflags)) + return 1; + } + + return 0; +} + +static enum es_result vc_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt) +{ + struct pt_regs *regs = ctxt->regs; + enum es_result ret; + u64 exit_info_1; + + /* Is it a WRMSR? */ + exit_info_1 = (ctxt->insn.opcode.bytes[1] == 0x30) ? 1 : 0; + + ghcb_set_rcx(ghcb, regs->cx); + if (exit_info_1) { + ghcb_set_rax(ghcb, regs->ax); + ghcb_set_rdx(ghcb, regs->dx); + } + + ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_MSR, exit_info_1, 0); + + if ((ret == ES_OK) && (!exit_info_1)) { + regs->ax = ghcb->save.rax; + regs->dx = ghcb->save.rdx; + } + + return ret; +} + +/* + * This function runs on the first #VC exception after the kernel + * switched to virtual addresses. + */ +static bool __init sev_es_setup_ghcb(void) +{ + /* First make sure the hypervisor talks a supported protocol. */ + if (!sev_es_negotiate_protocol()) + return false; + + /* + * Clear the boot_ghcb. The first exception comes in before the bss + * section is cleared. + */ + memset(&boot_ghcb_page, 0, PAGE_SIZE); + + /* Alright - Make the boot-ghcb public */ + boot_ghcb = &boot_ghcb_page; + + return true; +} + +#ifdef CONFIG_HOTPLUG_CPU +static void sev_es_ap_hlt_loop(void) +{ + struct ghcb_state state; + struct ghcb *ghcb; + + ghcb = sev_es_get_ghcb(&state); + + while (true) { + vc_ghcb_invalidate(ghcb); + ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_AP_HLT_LOOP); + ghcb_set_sw_exit_info_1(ghcb, 0); + ghcb_set_sw_exit_info_2(ghcb, 0); + + sev_es_wr_ghcb_msr(__pa(ghcb)); + VMGEXIT(); + + /* Wakeup signal? */ + if (ghcb_sw_exit_info_2_is_valid(ghcb) && + ghcb->save.sw_exit_info_2) + break; + } + + sev_es_put_ghcb(&state); +} + +/* + * Play_dead handler when running under SEV-ES. This is needed because + * the hypervisor can't deliver an SIPI request to restart the AP. + * Instead the kernel has to issue a VMGEXIT to halt the VCPU until the + * hypervisor wakes it up again. + */ +static void sev_es_play_dead(void) +{ + play_dead_common(); + + /* IRQs now disabled */ + + sev_es_ap_hlt_loop(); + + /* + * If we get here, the VCPU was woken up again. Jump to CPU + * startup code to get it back online. + */ + start_cpu0(); +} +#else /* CONFIG_HOTPLUG_CPU */ +#define sev_es_play_dead native_play_dead +#endif /* CONFIG_HOTPLUG_CPU */ + +#ifdef CONFIG_SMP +static void __init sev_es_setup_play_dead(void) +{ + smp_ops.play_dead = sev_es_play_dead; +} +#else +static inline void sev_es_setup_play_dead(void) { } +#endif + +static void __init alloc_runtime_data(int cpu) +{ + struct sev_es_runtime_data *data; + + data = memblock_alloc(sizeof(*data), PAGE_SIZE); + if (!data) + panic("Can't allocate SEV-ES runtime data"); + + per_cpu(runtime_data, cpu) = data; +} + +static void __init init_ghcb(int cpu) +{ + struct sev_es_runtime_data *data; + int err; + + data = per_cpu(runtime_data, cpu); + + err = early_set_memory_decrypted((unsigned long)&data->ghcb_page, + sizeof(data->ghcb_page)); + if (err) + panic("Can't map GHCBs unencrypted"); + + memset(&data->ghcb_page, 0, sizeof(data->ghcb_page)); + + data->ghcb_active = false; + data->backup_ghcb_active = false; +} + +void __init sev_es_init_vc_handling(void) +{ + int cpu; + + BUILD_BUG_ON(offsetof(struct sev_es_runtime_data, ghcb_page) % PAGE_SIZE); + + if (!sev_es_active()) + return; + + if (!sev_es_check_cpu_features()) + panic("SEV-ES CPU Features missing"); + + /* Enable SEV-ES special handling */ + static_branch_enable(&sev_es_enable_key); + + /* Initialize per-cpu GHCB pages */ + for_each_possible_cpu(cpu) { + alloc_runtime_data(cpu); + init_ghcb(cpu); + setup_vc_stacks(cpu); + } + + sev_es_setup_play_dead(); + + /* Secondary CPUs use the runtime #VC handler */ + initial_vc_handler = (unsigned long)safe_stack_exc_vmm_communication; +} + +static void __init vc_early_forward_exception(struct es_em_ctxt *ctxt) +{ + int trapnr = ctxt->fi.vector; + + if (trapnr == X86_TRAP_PF) + native_write_cr2(ctxt->fi.cr2); + + ctxt->regs->orig_ax = ctxt->fi.error_code; + do_early_exception(ctxt->regs, trapnr); +} + +static long *vc_insn_get_reg(struct es_em_ctxt *ctxt) +{ + long *reg_array; + int offset; + + reg_array = (long *)ctxt->regs; + offset = insn_get_modrm_reg_off(&ctxt->insn, ctxt->regs); + + if (offset < 0) + return NULL; + + offset /= sizeof(long); + + return reg_array + offset; +} + +static long *vc_insn_get_rm(struct es_em_ctxt *ctxt) +{ + long *reg_array; + int offset; + + reg_array = (long *)ctxt->regs; + offset = insn_get_modrm_rm_off(&ctxt->insn, ctxt->regs); + + if (offset < 0) + return NULL; + + offset /= sizeof(long); + + return reg_array + offset; +} +static enum es_result vc_do_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt, + unsigned int bytes, bool read) +{ + u64 exit_code, exit_info_1, exit_info_2; + unsigned long ghcb_pa = __pa(ghcb); + phys_addr_t paddr; + void __user *ref; + + ref = insn_get_addr_ref(&ctxt->insn, ctxt->regs); + if (ref == (void __user *)-1L) + return ES_UNSUPPORTED; + + exit_code = read ? SVM_VMGEXIT_MMIO_READ : SVM_VMGEXIT_MMIO_WRITE; + + if (!vc_slow_virt_to_phys(ghcb, ctxt, (unsigned long)ref, &paddr)) { + if (!read) + ctxt->fi.error_code |= X86_PF_WRITE; + + return ES_EXCEPTION; + } + + exit_info_1 = paddr; + /* Can never be greater than 8 */ + exit_info_2 = bytes; + + ghcb_set_sw_scratch(ghcb, ghcb_pa + offsetof(struct ghcb, shared_buffer)); + + return sev_es_ghcb_hv_call(ghcb, ctxt, exit_code, exit_info_1, exit_info_2); +} + +static enum es_result vc_handle_mmio_twobyte_ops(struct ghcb *ghcb, + struct es_em_ctxt *ctxt) +{ + struct insn *insn = &ctxt->insn; + unsigned int bytes = 0; + enum es_result ret; + int sign_byte; + long *reg_data; + + switch (insn->opcode.bytes[1]) { + /* MMIO Read w/ zero-extension */ + case 0xb6: + bytes = 1; + fallthrough; + case 0xb7: + if (!bytes) + bytes = 2; + + ret = vc_do_mmio(ghcb, ctxt, bytes, true); + if (ret) + break; + + /* Zero extend based on operand size */ + reg_data = vc_insn_get_reg(ctxt); + if (!reg_data) + return ES_DECODE_FAILED; + + memset(reg_data, 0, insn->opnd_bytes); + + memcpy(reg_data, ghcb->shared_buffer, bytes); + break; + + /* MMIO Read w/ sign-extension */ + case 0xbe: + bytes = 1; + fallthrough; + case 0xbf: + if (!bytes) + bytes = 2; + + ret = vc_do_mmio(ghcb, ctxt, bytes, true); + if (ret) + break; + + /* Sign extend based on operand size */ + reg_data = vc_insn_get_reg(ctxt); + if (!reg_data) + return ES_DECODE_FAILED; + + if (bytes == 1) { + u8 *val = (u8 *)ghcb->shared_buffer; + + sign_byte = (*val & 0x80) ? 0xff : 0x00; + } else { + u16 *val = (u16 *)ghcb->shared_buffer; + + sign_byte = (*val & 0x8000) ? 0xff : 0x00; + } + memset(reg_data, sign_byte, insn->opnd_bytes); + + memcpy(reg_data, ghcb->shared_buffer, bytes); + break; + + default: + ret = ES_UNSUPPORTED; + } + + return ret; +} + +/* + * The MOVS instruction has two memory operands, which raises the + * problem that it is not known whether the access to the source or the + * destination caused the #VC exception (and hence whether an MMIO read + * or write operation needs to be emulated). + * + * Instead of playing games with walking page-tables and trying to guess + * whether the source or destination is an MMIO range, split the move + * into two operations, a read and a write with only one memory operand. + * This will cause a nested #VC exception on the MMIO address which can + * then be handled. + * + * This implementation has the benefit that it also supports MOVS where + * source _and_ destination are MMIO regions. + * + * It will slow MOVS on MMIO down a lot, but in SEV-ES guests it is a + * rare operation. If it turns out to be a performance problem the split + * operations can be moved to memcpy_fromio() and memcpy_toio(). + */ +static enum es_result vc_handle_mmio_movs(struct es_em_ctxt *ctxt, + unsigned int bytes) +{ + unsigned long ds_base, es_base; + unsigned char *src, *dst; + unsigned char buffer[8]; + enum es_result ret; + bool rep; + int off; + + ds_base = insn_get_seg_base(ctxt->regs, INAT_SEG_REG_DS); + es_base = insn_get_seg_base(ctxt->regs, INAT_SEG_REG_ES); + + if (ds_base == -1L || es_base == -1L) { + ctxt->fi.vector = X86_TRAP_GP; + ctxt->fi.error_code = 0; + return ES_EXCEPTION; + } + + src = ds_base + (unsigned char *)ctxt->regs->si; + dst = es_base + (unsigned char *)ctxt->regs->di; + + ret = vc_read_mem(ctxt, src, buffer, bytes); + if (ret != ES_OK) + return ret; + + ret = vc_write_mem(ctxt, dst, buffer, bytes); + if (ret != ES_OK) + return ret; + + if (ctxt->regs->flags & X86_EFLAGS_DF) + off = -bytes; + else + off = bytes; + + ctxt->regs->si += off; + ctxt->regs->di += off; + + rep = insn_has_rep_prefix(&ctxt->insn); + if (rep) + ctxt->regs->cx -= 1; + + if (!rep || ctxt->regs->cx == 0) + return ES_OK; + else + return ES_RETRY; +} + +static enum es_result vc_handle_mmio(struct ghcb *ghcb, + struct es_em_ctxt *ctxt) +{ + struct insn *insn = &ctxt->insn; + unsigned int bytes = 0; + enum es_result ret; + long *reg_data; + + switch (insn->opcode.bytes[0]) { + /* MMIO Write */ + case 0x88: + bytes = 1; + fallthrough; + case 0x89: + if (!bytes) + bytes = insn->opnd_bytes; + + reg_data = vc_insn_get_reg(ctxt); + if (!reg_data) + return ES_DECODE_FAILED; + + memcpy(ghcb->shared_buffer, reg_data, bytes); + + ret = vc_do_mmio(ghcb, ctxt, bytes, false); + break; + + case 0xc6: + bytes = 1; + fallthrough; + case 0xc7: + if (!bytes) + bytes = insn->opnd_bytes; + + memcpy(ghcb->shared_buffer, insn->immediate1.bytes, bytes); + + ret = vc_do_mmio(ghcb, ctxt, bytes, false); + break; + + /* MMIO Read */ + case 0x8a: + bytes = 1; + fallthrough; + case 0x8b: + if (!bytes) + bytes = insn->opnd_bytes; + + ret = vc_do_mmio(ghcb, ctxt, bytes, true); + if (ret) + break; + + reg_data = vc_insn_get_reg(ctxt); + if (!reg_data) + return ES_DECODE_FAILED; + + /* Zero-extend for 32-bit operation */ + if (bytes == 4) + *reg_data = 0; + + memcpy(reg_data, ghcb->shared_buffer, bytes); + break; + + /* MOVS instruction */ + case 0xa4: + bytes = 1; + fallthrough; + case 0xa5: + if (!bytes) + bytes = insn->opnd_bytes; + + ret = vc_handle_mmio_movs(ctxt, bytes); + break; + /* Two-Byte Opcodes */ + case 0x0f: + ret = vc_handle_mmio_twobyte_ops(ghcb, ctxt); + break; + default: + ret = ES_UNSUPPORTED; + } + + return ret; +} + +static enum es_result vc_handle_dr7_write(struct ghcb *ghcb, + struct es_em_ctxt *ctxt) +{ + struct sev_es_runtime_data *data = this_cpu_read(runtime_data); + long val, *reg = vc_insn_get_rm(ctxt); + enum es_result ret; + + if (!reg) + return ES_DECODE_FAILED; + + val = *reg; + + /* Upper 32 bits must be written as zeroes */ + if (val >> 32) { + ctxt->fi.vector = X86_TRAP_GP; + ctxt->fi.error_code = 0; + return ES_EXCEPTION; + } + + /* Clear out other reserved bits and set bit 10 */ + val = (val & 0xffff23ffL) | BIT(10); + + /* Early non-zero writes to DR7 are not supported */ + if (!data && (val & ~DR7_RESET_VALUE)) + return ES_UNSUPPORTED; + + /* Using a value of 0 for ExitInfo1 means RAX holds the value */ + ghcb_set_rax(ghcb, val); + ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_WRITE_DR7, 0, 0); + if (ret != ES_OK) + return ret; + + if (data) + data->dr7 = val; + + return ES_OK; +} + +static enum es_result vc_handle_dr7_read(struct ghcb *ghcb, + struct es_em_ctxt *ctxt) +{ + struct sev_es_runtime_data *data = this_cpu_read(runtime_data); + long *reg = vc_insn_get_rm(ctxt); + + if (!reg) + return ES_DECODE_FAILED; + + if (data) + *reg = data->dr7; + else + *reg = DR7_RESET_VALUE; + + return ES_OK; +} + +static enum es_result vc_handle_wbinvd(struct ghcb *ghcb, + struct es_em_ctxt *ctxt) +{ + return sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_WBINVD, 0, 0); +} + +static enum es_result vc_handle_rdpmc(struct ghcb *ghcb, struct es_em_ctxt *ctxt) +{ + enum es_result ret; + + ghcb_set_rcx(ghcb, ctxt->regs->cx); + + ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_RDPMC, 0, 0); + if (ret != ES_OK) + return ret; + + if (!(ghcb_rax_is_valid(ghcb) && ghcb_rdx_is_valid(ghcb))) + return ES_VMM_ERROR; + + ctxt->regs->ax = ghcb->save.rax; + ctxt->regs->dx = ghcb->save.rdx; + + return ES_OK; +} + +static enum es_result vc_handle_monitor(struct ghcb *ghcb, + struct es_em_ctxt *ctxt) +{ + /* + * Treat it as a NOP and do not leak a physical address to the + * hypervisor. + */ + return ES_OK; +} + +static enum es_result vc_handle_mwait(struct ghcb *ghcb, + struct es_em_ctxt *ctxt) +{ + /* Treat the same as MONITOR/MONITORX */ + return ES_OK; +} + +static enum es_result vc_handle_vmmcall(struct ghcb *ghcb, + struct es_em_ctxt *ctxt) +{ + enum es_result ret; + + ghcb_set_rax(ghcb, ctxt->regs->ax); + ghcb_set_cpl(ghcb, user_mode(ctxt->regs) ? 3 : 0); + + if (x86_platform.hyper.sev_es_hcall_prepare) + x86_platform.hyper.sev_es_hcall_prepare(ghcb, ctxt->regs); + + ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_VMMCALL, 0, 0); + if (ret != ES_OK) + return ret; + + if (!ghcb_rax_is_valid(ghcb)) + return ES_VMM_ERROR; + + ctxt->regs->ax = ghcb->save.rax; + + /* + * Call sev_es_hcall_finish() after regs->ax is already set. + * This allows the hypervisor handler to overwrite it again if + * necessary. + */ + if (x86_platform.hyper.sev_es_hcall_finish && + !x86_platform.hyper.sev_es_hcall_finish(ghcb, ctxt->regs)) + return ES_VMM_ERROR; + + return ES_OK; +} + +static enum es_result vc_handle_trap_ac(struct ghcb *ghcb, + struct es_em_ctxt *ctxt) +{ + /* + * Calling ecx_alignment_check() directly does not work, because it + * enables IRQs and the GHCB is active. Forward the exception and call + * it later from vc_forward_exception(). + */ + ctxt->fi.vector = X86_TRAP_AC; + ctxt->fi.error_code = 0; + return ES_EXCEPTION; +} + +static __always_inline void vc_handle_trap_db(struct pt_regs *regs) +{ + if (user_mode(regs)) + noist_exc_debug(regs); + else + exc_debug(regs); +} + +static enum es_result vc_handle_exitcode(struct es_em_ctxt *ctxt, + struct ghcb *ghcb, + unsigned long exit_code) +{ + enum es_result result; + + switch (exit_code) { + case SVM_EXIT_READ_DR7: + result = vc_handle_dr7_read(ghcb, ctxt); + break; + case SVM_EXIT_WRITE_DR7: + result = vc_handle_dr7_write(ghcb, ctxt); + break; + case SVM_EXIT_EXCP_BASE + X86_TRAP_AC: + result = vc_handle_trap_ac(ghcb, ctxt); + break; + case SVM_EXIT_RDTSC: + case SVM_EXIT_RDTSCP: + result = vc_handle_rdtsc(ghcb, ctxt, exit_code); + break; + case SVM_EXIT_RDPMC: + result = vc_handle_rdpmc(ghcb, ctxt); + break; + case SVM_EXIT_INVD: + pr_err_ratelimited("#VC exception for INVD??? Seriously???\n"); + result = ES_UNSUPPORTED; + break; + case SVM_EXIT_CPUID: + result = vc_handle_cpuid(ghcb, ctxt); + break; + case SVM_EXIT_IOIO: + result = vc_handle_ioio(ghcb, ctxt); + break; + case SVM_EXIT_MSR: + result = vc_handle_msr(ghcb, ctxt); + break; + case SVM_EXIT_VMMCALL: + result = vc_handle_vmmcall(ghcb, ctxt); + break; + case SVM_EXIT_WBINVD: + result = vc_handle_wbinvd(ghcb, ctxt); + break; + case SVM_EXIT_MONITOR: + result = vc_handle_monitor(ghcb, ctxt); + break; + case SVM_EXIT_MWAIT: + result = vc_handle_mwait(ghcb, ctxt); + break; + case SVM_EXIT_NPF: + result = vc_handle_mmio(ghcb, ctxt); + break; + default: + /* + * Unexpected #VC exception + */ + result = ES_UNSUPPORTED; + } + + return result; +} + +static __always_inline void vc_forward_exception(struct es_em_ctxt *ctxt) +{ + long error_code = ctxt->fi.error_code; + int trapnr = ctxt->fi.vector; + + ctxt->regs->orig_ax = ctxt->fi.error_code; + + switch (trapnr) { + case X86_TRAP_GP: + exc_general_protection(ctxt->regs, error_code); + break; + case X86_TRAP_UD: + exc_invalid_op(ctxt->regs); + break; + case X86_TRAP_AC: + exc_alignment_check(ctxt->regs, error_code); + break; + default: + pr_emerg("Unsupported exception in #VC instruction emulation - can't continue\n"); + BUG(); + } +} + +static __always_inline bool on_vc_fallback_stack(struct pt_regs *regs) +{ + unsigned long sp = (unsigned long)regs; + + return (sp >= __this_cpu_ist_bottom_va(VC2) && sp < __this_cpu_ist_top_va(VC2)); +} + +/* + * Main #VC exception handler. It is called when the entry code was able to + * switch off the IST to a safe kernel stack. + * + * With the current implementation it is always possible to switch to a safe + * stack because #VC exceptions only happen at known places, like intercepted + * instructions or accesses to MMIO areas/IO ports. They can also happen with + * code instrumentation when the hypervisor intercepts #DB, but the critical + * paths are forbidden to be instrumented, so #DB exceptions currently also + * only happen in safe places. + */ +DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) +{ + struct sev_es_runtime_data *data = this_cpu_read(runtime_data); + struct ghcb_state state; + struct es_em_ctxt ctxt; + enum es_result result; + struct ghcb *ghcb; + + lockdep_assert_irqs_disabled(); + + /* + * Handle #DB before calling into !noinstr code to avoid recursive #DB. + */ + if (error_code == SVM_EXIT_EXCP_BASE + X86_TRAP_DB) { + vc_handle_trap_db(regs); + return; + } + + instrumentation_begin(); + + /* + * This is invoked through an interrupt gate, so IRQs are disabled. The + * code below might walk page-tables for user or kernel addresses, so + * keep the IRQs disabled to protect us against concurrent TLB flushes. + */ + + ghcb = sev_es_get_ghcb(&state); + if (!ghcb) { + /* + * Mark GHCBs inactive so that panic() is able to print the + * message. + */ + data->ghcb_active = false; + data->backup_ghcb_active = false; + + panic("Unable to handle #VC exception! GHCB and Backup GHCB are already in use"); + } + + vc_ghcb_invalidate(ghcb); + result = vc_init_em_ctxt(&ctxt, regs, error_code); + + if (result == ES_OK) + result = vc_handle_exitcode(&ctxt, ghcb, error_code); + + sev_es_put_ghcb(&state); + + /* Done - now check the result */ + switch (result) { + case ES_OK: + vc_finish_insn(&ctxt); + break; + case ES_UNSUPPORTED: + pr_err_ratelimited("Unsupported exit-code 0x%02lx in early #VC exception (IP: 0x%lx)\n", + error_code, regs->ip); + goto fail; + case ES_VMM_ERROR: + pr_err_ratelimited("Failure in communication with VMM (exit-code 0x%02lx IP: 0x%lx)\n", + error_code, regs->ip); + goto fail; + case ES_DECODE_FAILED: + pr_err_ratelimited("Failed to decode instruction (exit-code 0x%02lx IP: 0x%lx)\n", + error_code, regs->ip); + goto fail; + case ES_EXCEPTION: + vc_forward_exception(&ctxt); + break; + case ES_RETRY: + /* Nothing to do */ + break; + default: + pr_emerg("Unknown result in %s():%d\n", __func__, result); + /* + * Emulating the instruction which caused the #VC exception + * failed - can't continue so print debug information + */ + BUG(); + } + +out: + instrumentation_end(); + + return; + +fail: + if (user_mode(regs)) { + /* + * Do not kill the machine if user-space triggered the + * exception. Send SIGBUS instead and let user-space deal with + * it. + */ + force_sig_fault(SIGBUS, BUS_OBJERR, (void __user *)0); + } else { + pr_emerg("PANIC: Unhandled #VC exception in kernel space (result=%d)\n", + result); + + /* Show some debug info */ + show_regs(regs); + + /* Ask hypervisor to sev_es_terminate */ + sev_es_terminate(GHCB_SEV_ES_REASON_GENERAL_REQUEST); + + /* If that fails and we get here - just panic */ + panic("Returned from Terminate-Request to Hypervisor\n"); + } + + goto out; +} + +/* This handler runs on the #VC fall-back stack. It can cause further #VC exceptions */ +DEFINE_IDTENTRY_VC_IST(exc_vmm_communication) +{ + instrumentation_begin(); + panic("Can't handle #VC exception from unsupported context\n"); + instrumentation_end(); +} + +DEFINE_IDTENTRY_VC(exc_vmm_communication) +{ + if (likely(!on_vc_fallback_stack(regs))) + safe_stack_exc_vmm_communication(regs, error_code); + else + ist_exc_vmm_communication(regs, error_code); +} + +bool __init handle_vc_boot_ghcb(struct pt_regs *regs) +{ + unsigned long exit_code = regs->orig_ax; + struct es_em_ctxt ctxt; + enum es_result result; + + /* Do initial setup or terminate the guest */ + if (unlikely(boot_ghcb == NULL && !sev_es_setup_ghcb())) + sev_es_terminate(GHCB_SEV_ES_REASON_GENERAL_REQUEST); + + vc_ghcb_invalidate(boot_ghcb); + + result = vc_init_em_ctxt(&ctxt, regs, exit_code); + if (result == ES_OK) + result = vc_handle_exitcode(&ctxt, boot_ghcb, exit_code); + + /* Done - now check the result */ + switch (result) { + case ES_OK: + vc_finish_insn(&ctxt); + break; + case ES_UNSUPPORTED: + early_printk("PANIC: Unsupported exit-code 0x%02lx in early #VC exception (IP: 0x%lx)\n", + exit_code, regs->ip); + goto fail; + case ES_VMM_ERROR: + early_printk("PANIC: Failure in communication with VMM (exit-code 0x%02lx IP: 0x%lx)\n", + exit_code, regs->ip); + goto fail; + case ES_DECODE_FAILED: + early_printk("PANIC: Failed to decode instruction (exit-code 0x%02lx IP: 0x%lx)\n", + exit_code, regs->ip); + goto fail; + case ES_EXCEPTION: + vc_early_forward_exception(&ctxt); + break; + case ES_RETRY: + /* Nothing to do */ + break; + default: + BUG(); + } + + return true; + +fail: + show_regs(regs); + + while (true) + halt(); +} diff --git a/arch/x86/kernel/signal_compat.c b/arch/x86/kernel/signal_compat.c index 9ccbf0576cd0..a7f3e12cfbdb 100644 --- a/arch/x86/kernel/signal_compat.c +++ b/arch/x86/kernel/signal_compat.c @@ -27,7 +27,7 @@ static inline void signal_compat_build_tests(void) */ BUILD_BUG_ON(NSIGILL != 11); BUILD_BUG_ON(NSIGFPE != 15); - BUILD_BUG_ON(NSIGSEGV != 7); + BUILD_BUG_ON(NSIGSEGV != 9); BUILD_BUG_ON(NSIGBUS != 5); BUILD_BUG_ON(NSIGTRAP != 5); BUILD_BUG_ON(NSIGCHLD != 6); diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index f5ef689dd62a..de776b2e6046 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -227,7 +227,7 @@ static void notrace start_secondary(void *unused) load_cr3(swapper_pg_dir); __flush_tlb_all(); #endif - load_current_idt(); + cpu_init_exception_handling(); cpu_init(); x86_cpuinit.early_percpu_clock_init(); preempt_disable(); diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c index 2fd698e28e4d..8627fda8d993 100644 --- a/arch/x86/kernel/stacktrace.c +++ b/arch/x86/kernel/stacktrace.c @@ -18,13 +18,13 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, struct unwind_state state; unsigned long addr; - if (regs && !consume_entry(cookie, regs->ip, false)) + if (regs && !consume_entry(cookie, regs->ip)) return; for (unwind_start(&state, task, regs, NULL); !unwind_done(&state); unwind_next_frame(&state)) { addr = unwind_get_return_address(&state); - if (!addr || !consume_entry(cookie, addr, false)) + if (!addr || !consume_entry(cookie, addr)) break; } } @@ -72,7 +72,7 @@ int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, if (!addr) return -EINVAL; - if (!consume_entry(cookie, addr, false)) + if (!consume_entry(cookie, addr)) return -EINVAL; } @@ -114,7 +114,7 @@ void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie, { const void __user *fp = (const void __user *)regs->bp; - if (!consume_entry(cookie, regs->ip, false)) + if (!consume_entry(cookie, regs->ip)) return; while (1) { @@ -128,7 +128,7 @@ void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie, break; if (!frame.ret_addr) break; - if (!consume_entry(cookie, frame.ret_addr, false)) + if (!consume_entry(cookie, frame.ret_addr)) break; fp = frame.next_fp; } diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c new file mode 100644 index 000000000000..ca9a380d9c0b --- /dev/null +++ b/arch/x86/kernel/static_call.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/static_call.h> +#include <linux/memory.h> +#include <linux/bug.h> +#include <asm/text-patching.h> + +enum insn_type { + CALL = 0, /* site call */ + NOP = 1, /* site cond-call */ + JMP = 2, /* tramp / site tail-call */ + RET = 3, /* tramp / site cond-tail-call */ +}; + +static void __ref __static_call_transform(void *insn, enum insn_type type, void *func) +{ + int size = CALL_INSN_SIZE; + const void *code; + + switch (type) { + case CALL: + code = text_gen_insn(CALL_INSN_OPCODE, insn, func); + break; + + case NOP: + code = ideal_nops[NOP_ATOMIC5]; + break; + + case JMP: + code = text_gen_insn(JMP32_INSN_OPCODE, insn, func); + break; + + case RET: + code = text_gen_insn(RET_INSN_OPCODE, insn, func); + size = RET_INSN_SIZE; + break; + } + + if (memcmp(insn, code, size) == 0) + return; + + if (unlikely(system_state == SYSTEM_BOOTING)) + return text_poke_early(insn, code, size); + + text_poke_bp(insn, code, size, NULL); +} + +static void __static_call_validate(void *insn, bool tail) +{ + u8 opcode = *(u8 *)insn; + + if (tail) { + if (opcode == JMP32_INSN_OPCODE || + opcode == RET_INSN_OPCODE) + return; + } else { + if (opcode == CALL_INSN_OPCODE || + !memcmp(insn, ideal_nops[NOP_ATOMIC5], 5)) + return; + } + + /* + * If we ever trigger this, our text is corrupt, we'll probably not live long. + */ + WARN_ONCE(1, "unexpected static_call insn opcode 0x%x at %pS\n", opcode, insn); +} + +static inline enum insn_type __sc_insn(bool null, bool tail) +{ + /* + * Encode the following table without branches: + * + * tail null insn + * -----+-------+------ + * 0 | 0 | CALL + * 0 | 1 | NOP + * 1 | 0 | JMP + * 1 | 1 | RET + */ + return 2*tail + null; +} + +void arch_static_call_transform(void *site, void *tramp, void *func, bool tail) +{ + mutex_lock(&text_mutex); + + if (tramp) { + __static_call_validate(tramp, true); + __static_call_transform(tramp, __sc_insn(!func, true), func); + } + + if (IS_ENABLED(CONFIG_HAVE_STATIC_CALL_INLINE) && site) { + __static_call_validate(site, tail); + __static_call_transform(site, __sc_insn(!func, tail), func); + } + + mutex_unlock(&text_mutex); +} +EXPORT_SYMBOL_GPL(arch_static_call_transform); diff --git a/arch/x86/kernel/sys_ia32.c b/arch/x86/kernel/sys_ia32.c index 720cde885042..6cf65397d225 100644 --- a/arch/x86/kernel/sys_ia32.c +++ b/arch/x86/kernel/sys_ia32.c @@ -251,6 +251,6 @@ COMPAT_SYSCALL_DEFINE5(ia32_clone, unsigned long, clone_flags, .tls = tls_val, }; - return _do_fork(&args); + return kernel_clone(&args); } #endif /* CONFIG_IA32_EMULATION */ diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 81a2fb711091..3c70fb34028b 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -43,6 +43,7 @@ #include <asm/stacktrace.h> #include <asm/processor.h> #include <asm/debugreg.h> +#include <asm/realmode.h> #include <asm/text-patching.h> #include <asm/ftrace.h> #include <asm/traps.h> @@ -195,7 +196,7 @@ static __always_inline void __user *error_get_trap_addr(struct pt_regs *regs) DEFINE_IDTENTRY(exc_divide_error) { - do_error_trap(regs, 0, "divide_error", X86_TRAP_DE, SIGFPE, + do_error_trap(regs, 0, "divide error", X86_TRAP_DE, SIGFPE, FPE_INTDIV, error_get_trap_addr(regs)); } @@ -673,6 +674,50 @@ asmlinkage __visible noinstr struct pt_regs *sync_regs(struct pt_regs *eregs) return regs; } +#ifdef CONFIG_AMD_MEM_ENCRYPT +asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *regs) +{ + unsigned long sp, *stack; + struct stack_info info; + struct pt_regs *regs_ret; + + /* + * In the SYSCALL entry path the RSP value comes from user-space - don't + * trust it and switch to the current kernel stack + */ + if (regs->ip >= (unsigned long)entry_SYSCALL_64 && + regs->ip < (unsigned long)entry_SYSCALL_64_safe_stack) { + sp = this_cpu_read(cpu_current_top_of_stack); + goto sync; + } + + /* + * From here on the RSP value is trusted. Now check whether entry + * happened from a safe stack. Not safe are the entry or unknown stacks, + * use the fall-back stack instead in this case. + */ + sp = regs->sp; + stack = (unsigned long *)sp; + + if (!get_stack_info_noinstr(stack, current, &info) || info.type == STACK_TYPE_ENTRY || + info.type >= STACK_TYPE_EXCEPTION_LAST) + sp = __this_cpu_ist_top_va(VC2); + +sync: + /* + * Found a safe stack - switch to it as if the entry didn't happen via + * IST stack. The code below only copies pt_regs, the real switch happens + * in assembly code. + */ + sp = ALIGN_DOWN(sp, 8) - sizeof(*regs_ret); + + regs_ret = (struct pt_regs *)sp; + *regs_ret = *regs; + + return regs_ret; +} +#endif + struct bad_iret_stack { void *error_entry_ret; struct pt_regs regs; @@ -745,9 +790,21 @@ static __always_inline unsigned long debug_read_clear_dr6(void) * Keep it simple: clear DR6 immediately. */ get_debugreg(dr6, 6); - set_debugreg(0, 6); - /* Filter out all the reserved bits which are preset to 1 */ - dr6 &= ~DR6_RESERVED; + set_debugreg(DR6_RESERVED, 6); + dr6 ^= DR6_RESERVED; /* Flip to positive polarity */ + + /* + * Clear the virtual DR6 value, ptrace routines will set bits here for + * things we want signals for. + */ + current->thread.virtual_dr6 = 0; + + /* + * The SDM says "The processor clears the BTF flag when it + * generates a debug exception." Clear TIF_BLOCKSTEP to keep + * TIF_BLOCKSTEP in sync with the hardware BTF flag. + */ + clear_thread_flag(TIF_BLOCKSTEP); return dr6; } @@ -776,74 +833,20 @@ static __always_inline unsigned long debug_read_clear_dr6(void) * * May run on IST stack. */ -static void handle_debug(struct pt_regs *regs, unsigned long dr6, bool user) -{ - struct task_struct *tsk = current; - bool user_icebp; - int si_code; - - /* - * The SDM says "The processor clears the BTF flag when it - * generates a debug exception." Clear TIF_BLOCKSTEP to keep - * TIF_BLOCKSTEP in sync with the hardware BTF flag. - */ - clear_thread_flag(TIF_BLOCKSTEP); - - /* - * If DR6 is zero, no point in trying to handle it. The kernel is - * not using INT1. - */ - if (!user && !dr6) - return; +static bool notify_debug(struct pt_regs *regs, unsigned long *dr6) +{ /* - * If dr6 has no reason to give us about the origin of this trap, - * then it's very likely the result of an icebp/int01 trap. - * User wants a sigtrap for that. + * Notifiers will clear bits in @dr6 to indicate the event has been + * consumed - hw_breakpoint_handler(), single_stop_cont(). + * + * Notifiers will set bits in @virtual_dr6 to indicate the desire + * for signals - ptrace_triggered(), kgdb_hw_overflow_handler(). */ - user_icebp = user && !dr6; - - /* Store the virtualized DR6 value */ - tsk->thread.debugreg6 = dr6; - -#ifdef CONFIG_KPROBES - if (kprobe_debug_handler(regs)) { - return; - } -#endif - - if (notify_die(DIE_DEBUG, "debug", regs, (long)&dr6, 0, - SIGTRAP) == NOTIFY_STOP) { - return; - } - - /* It's safe to allow irq's after DR6 has been saved */ - cond_local_irq_enable(regs); - - if (v8086_mode(regs)) { - handle_vm86_trap((struct kernel_vm86_regs *) regs, 0, - X86_TRAP_DB); - goto out; - } - - if (WARN_ON_ONCE((dr6 & DR_STEP) && !user_mode(regs))) { - /* - * Historical junk that used to handle SYSENTER single-stepping. - * This should be unreachable now. If we survive for a while - * without anyone hitting this warning, we'll turn this into - * an oops. - */ - tsk->thread.debugreg6 &= ~DR_STEP; - set_tsk_thread_flag(tsk, TIF_SINGLESTEP); - regs->flags &= ~X86_EFLAGS_TF; - } - - si_code = get_si_code(tsk->thread.debugreg6); - if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp) - send_sigtrap(regs, 0, si_code); + if (notify_die(DIE_DEBUG, "debug", regs, (long)dr6, 0, SIGTRAP) == NOTIFY_STOP) + return true; -out: - cond_local_irq_disable(regs); + return false; } static __always_inline void exc_debug_kernel(struct pt_regs *regs, @@ -877,8 +880,32 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs, if ((dr6 & DR_STEP) && is_sysenter_singlestep(regs)) dr6 &= ~DR_STEP; - handle_debug(regs, dr6, false); + if (kprobe_debug_handler(regs)) + goto out; + + /* + * The kernel doesn't use INT1 + */ + if (!dr6) + goto out; + + if (notify_debug(regs, &dr6)) + goto out; + /* + * The kernel doesn't use TF single-step outside of: + * + * - Kprobes, consumed through kprobe_debug_handler() + * - KGDB, consumed through notify_debug() + * + * So if we get here with DR_STEP set, something is wonky. + * + * A known way to trigger this is through QEMU's GDB stub, + * which leaks #DB into the guest and causes IST recursion. + */ + if (WARN_ON_ONCE(dr6 & DR_STEP)) + regs->flags &= ~X86_EFLAGS_TF; +out: instrumentation_end(); idtentry_exit_nmi(regs, irq_state); @@ -888,6 +915,8 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs, static __always_inline void exc_debug_user(struct pt_regs *regs, unsigned long dr6) { + bool icebp; + /* * If something gets miswired and we end up here for a kernel mode * #DB, we will malfunction. @@ -906,8 +935,32 @@ static __always_inline void exc_debug_user(struct pt_regs *regs, irqentry_enter_from_user_mode(regs); instrumentation_begin(); - handle_debug(regs, dr6, true); + /* + * If dr6 has no reason to give us about the origin of this trap, + * then it's very likely the result of an icebp/int01 trap. + * User wants a sigtrap for that. + */ + icebp = !dr6; + + if (notify_debug(regs, &dr6)) + goto out; + /* It's safe to allow irq's after DR6 has been saved */ + local_irq_enable(); + + if (v8086_mode(regs)) { + handle_vm86_trap((struct kernel_vm86_regs *)regs, 0, X86_TRAP_DB); + goto out_irq; + } + + /* Add the virtual_dr6 bits for signals. */ + dr6 |= current->thread.virtual_dr6; + if (dr6 & (DR_STEP | DR_TRAP_BITS) || icebp) + send_sigtrap(regs, 0, get_si_code(dr6)); + +out_irq: + local_irq_disable(); +out: instrumentation_end(); irqentry_exit_to_user_mode(regs); } @@ -1074,6 +1127,9 @@ void __init trap_init(void) /* Init cpu_entry_area before IST entries are set up */ setup_cpu_entry_areas(); + /* Init GHCB memory pages when running as an SEV-ES guest */ + sev_es_init_vc_handling(); + idt_setup_traps(); /* diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 49d925043171..f70dffc2771f 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -54,7 +54,7 @@ struct clocksource *art_related_clocksource; struct cyc2ns { struct cyc2ns_data data[2]; /* 0 + 2*16 = 32 */ - seqcount_t seq; /* 32 + 4 = 36 */ + seqcount_latch_t seq; /* 32 + 4 = 36 */ }; /* fits one cacheline */ @@ -73,14 +73,14 @@ __always_inline void cyc2ns_read_begin(struct cyc2ns_data *data) preempt_disable_notrace(); do { - seq = this_cpu_read(cyc2ns.seq.sequence); + seq = this_cpu_read(cyc2ns.seq.seqcount.sequence); idx = seq & 1; data->cyc2ns_offset = this_cpu_read(cyc2ns.data[idx].cyc2ns_offset); data->cyc2ns_mul = this_cpu_read(cyc2ns.data[idx].cyc2ns_mul); data->cyc2ns_shift = this_cpu_read(cyc2ns.data[idx].cyc2ns_shift); - } while (unlikely(seq != this_cpu_read(cyc2ns.seq.sequence))); + } while (unlikely(seq != this_cpu_read(cyc2ns.seq.seqcount.sequence))); } __always_inline void cyc2ns_read_end(void) @@ -186,7 +186,7 @@ static void __init cyc2ns_init_boot_cpu(void) { struct cyc2ns *c2n = this_cpu_ptr(&cyc2ns); - seqcount_init(&c2n->seq); + seqcount_latch_init(&c2n->seq); __set_cyc2ns_scale(tsc_khz, smp_processor_id(), rdtsc()); } @@ -203,7 +203,7 @@ static void __init cyc2ns_init_secondary_cpus(void) for_each_possible_cpu(cpu) { if (cpu != this_cpu) { - seqcount_init(&c2n->seq); + seqcount_latch_init(&c2n->seq); c2n = per_cpu_ptr(&cyc2ns, cpu); c2n->data[0] = data[0]; c2n->data[1] = data[1]; diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c index 8d5cbe1bbb3b..f6225bf22c02 100644 --- a/arch/x86/kernel/umip.c +++ b/arch/x86/kernel/umip.c @@ -45,11 +45,12 @@ * value that, lies close to the top of the kernel memory. The limit for the GDT * and the IDT are set to zero. * - * Given that SLDT and STR are not commonly used in programs that run on WineHQ - * or DOSEMU2, they are not emulated. - * - * The instruction smsw is emulated to return the value that the register CR0 + * The instruction SMSW is emulated to return the value that the register CR0 * has at boot time as set in the head_32. + * SLDT and STR are emulated to return the values that the kernel programmatically + * assigns: + * - SLDT returns (GDT_ENTRY_LDT * 8) if an LDT has been set, 0 if not. + * - STR returns (GDT_ENTRY_TSS * 8). * * Emulation is provided for both 32-bit and 64-bit processes. * @@ -244,16 +245,34 @@ static int emulate_umip_insn(struct insn *insn, int umip_inst, *data_size += UMIP_GDT_IDT_LIMIT_SIZE; memcpy(data, &dummy_limit, UMIP_GDT_IDT_LIMIT_SIZE); - } else if (umip_inst == UMIP_INST_SMSW) { - unsigned long dummy_value = CR0_STATE; + } else if (umip_inst == UMIP_INST_SMSW || umip_inst == UMIP_INST_SLDT || + umip_inst == UMIP_INST_STR) { + unsigned long dummy_value; + + if (umip_inst == UMIP_INST_SMSW) { + dummy_value = CR0_STATE; + } else if (umip_inst == UMIP_INST_STR) { + dummy_value = GDT_ENTRY_TSS * 8; + } else if (umip_inst == UMIP_INST_SLDT) { +#ifdef CONFIG_MODIFY_LDT_SYSCALL + down_read(¤t->mm->context.ldt_usr_sem); + if (current->mm->context.ldt) + dummy_value = GDT_ENTRY_LDT * 8; + else + dummy_value = 0; + up_read(¤t->mm->context.ldt_usr_sem); +#else + dummy_value = 0; +#endif + } /* - * Even though the CR0 register has 4 bytes, the number + * For these 3 instructions, the number * of bytes to be copied in the result buffer is determined * by whether the operand is a register or a memory location. * If operand is a register, return as many bytes as the operand * size. If operand is memory, return only the two least - * siginificant bytes of CR0. + * siginificant bytes. */ if (X86_MODRM_MOD(insn->modrm.value) == 3) *data_size = insn->opnd_bytes; @@ -261,7 +280,6 @@ static int emulate_umip_insn(struct insn *insn, int umip_inst, *data_size = 2; memcpy(data, &dummy_value, *data_size); - /* STR and SLDT are not emulated */ } else { return -EINVAL; } @@ -317,63 +335,28 @@ static void force_sig_info_umip_fault(void __user *addr, struct pt_regs *regs) */ bool fixup_umip_exception(struct pt_regs *regs) { - int not_copied, nr_copied, reg_offset, dummy_data_size, umip_inst; - unsigned long seg_base = 0, *reg_addr; + int nr_copied, reg_offset, dummy_data_size, umip_inst; /* 10 bytes is the maximum size of the result of UMIP instructions */ unsigned char dummy_data[10] = { 0 }; unsigned char buf[MAX_INSN_SIZE]; + unsigned long *reg_addr; void __user *uaddr; struct insn insn; - int seg_defs; if (!regs) return false; - /* - * If not in user-space long mode, a custom code segment could be in - * use. This is true in protected mode (if the process defined a local - * descriptor table), or virtual-8086 mode. In most of the cases - * seg_base will be zero as in USER_CS. - */ - if (!user_64bit_mode(regs)) - seg_base = insn_get_seg_base(regs, INAT_SEG_REG_CS); - - if (seg_base == -1L) - return false; - - not_copied = copy_from_user(buf, (void __user *)(seg_base + regs->ip), - sizeof(buf)); - nr_copied = sizeof(buf) - not_copied; + nr_copied = insn_fetch_from_user(regs, buf); /* - * The copy_from_user above could have failed if user code is protected - * by a memory protection key. Give up on emulation in such a case. - * Should we issue a page fault? + * The insn_fetch_from_user above could have failed if user code + * is protected by a memory protection key. Give up on emulation + * in such a case. Should we issue a page fault? */ if (!nr_copied) return false; - insn_init(&insn, buf, nr_copied, user_64bit_mode(regs)); - - /* - * Override the default operand and address sizes with what is specified - * in the code segment descriptor. The instruction decoder only sets - * the address size it to either 4 or 8 address bytes and does nothing - * for the operand bytes. This OK for most of the cases, but we could - * have special cases where, for instance, a 16-bit code segment - * descriptor is used. - * If there is an address override prefix, the instruction decoder - * correctly updates these values, even for 16-bit defaults. - */ - seg_defs = insn_get_code_seg_params(regs); - if (seg_defs == -EINVAL) - return false; - - insn.addr_bytes = INSN_CODE_SEG_ADDR_SZ(seg_defs); - insn.opnd_bytes = INSN_CODE_SEG_OPND_SZ(seg_defs); - - insn_get_length(&insn); - if (nr_copied < insn.length) + if (!insn_decode(&insn, regs, buf, nr_copied)) return false; umip_inst = identify_insn(&insn); @@ -383,10 +366,6 @@ bool fixup_umip_exception(struct pt_regs *regs) umip_pr_warn(regs, "%s instruction cannot be used by applications.\n", umip_insns[umip_inst]); - /* Do not emulate (spoof) SLDT or STR. */ - if (umip_inst == UMIP_INST_STR || umip_inst == UMIP_INST_SLDT) - return false; - umip_pr_warn(regs, "For now, expensive software emulation returns the result.\n"); if (emulate_umip_insn(&insn, umip_inst, dummy_data, &dummy_data_size, diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c index ec88bbe08a32..6a339ce328e0 100644 --- a/arch/x86/kernel/unwind_orc.c +++ b/arch/x86/kernel/unwind_orc.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only +#include <linux/objtool.h> #include <linux/module.h> #include <linux/sort.h> #include <asm/ptrace.h> @@ -127,12 +128,12 @@ static struct orc_entry null_orc_entry = { .sp_offset = sizeof(long), .sp_reg = ORC_REG_SP, .bp_reg = ORC_REG_UNDEFINED, - .type = ORC_TYPE_CALL + .type = UNWIND_HINT_TYPE_CALL }; /* Fake frame pointer entry -- used as a fallback for generated code */ static struct orc_entry orc_fp_entry = { - .type = ORC_TYPE_CALL, + .type = UNWIND_HINT_TYPE_CALL, .sp_reg = ORC_REG_BP, .sp_offset = 16, .bp_reg = ORC_REG_PREV_SP, @@ -531,7 +532,7 @@ bool unwind_next_frame(struct unwind_state *state) /* Find IP, SP and possibly regs: */ switch (orc->type) { - case ORC_TYPE_CALL: + case UNWIND_HINT_TYPE_CALL: ip_p = sp - sizeof(long); if (!deref_stack_reg(state, ip_p, &state->ip)) @@ -546,7 +547,7 @@ bool unwind_next_frame(struct unwind_state *state) state->signal = false; break; - case ORC_TYPE_REGS: + case UNWIND_HINT_TYPE_REGS: if (!deref_stack_regs(state, sp, &state->ip, &state->sp)) { orc_warn_current("can't access registers at %pB\n", (void *)orig_ip); @@ -559,7 +560,7 @@ bool unwind_next_frame(struct unwind_state *state) state->signal = true; break; - case ORC_TYPE_REGS_IRET: + case UNWIND_HINT_TYPE_REGS_PARTIAL: if (!deref_stack_iret_regs(state, sp, &state->ip, &state->sp)) { orc_warn_current("can't access iret registers at %pB\n", (void *)orig_ip); diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 9a03e5b23135..bf9e0adb5b7e 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -136,6 +136,7 @@ SECTIONS ENTRY_TEXT ALIGN_ENTRY_TEXT_END SOFTIRQENTRY_TEXT + STATIC_CALL_TEXT *(.fixup) *(.gnu.warning) @@ -411,10 +412,47 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + ELF_DETAILS DISCARDS -} + /* + * Make sure that the .got.plt is either completely empty or it + * contains only the lazy dispatch entries. + */ + .got.plt (INFO) : { *(.got.plt) } + ASSERT(SIZEOF(.got.plt) == 0 || +#ifdef CONFIG_X86_64 + SIZEOF(.got.plt) == 0x18, +#else + SIZEOF(.got.plt) == 0xc, +#endif + "Unexpected GOT/PLT entries detected!") + + /* + * Sections that should stay zero sized, which is safer to + * explicitly check instead of blindly discarding. + */ + .got : { + *(.got) *(.igot.*) + } + ASSERT(SIZEOF(.got) == 0, "Unexpected GOT entries detected!") + + .plt : { + *(.plt) *(.plt.*) *(.iplt) + } + ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!") + + .rel.dyn : { + *(.rel.*) *(.rel_*) + } + ASSERT(SIZEOF(.rel.dyn) == 0, "Unexpected run-time relocations (.rel) detected!") + + .rela.dyn : { + *(.rela.*) *(.rela_*) + } + ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!") +} #ifdef CONFIG_X86_32 /* diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index 123f1c1f1788..a3038d8deb6a 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c @@ -24,6 +24,7 @@ #include <asm/tsc.h> #include <asm/iommu.h> #include <asm/mach_traps.h> +#include <asm/irqdomain.h> void x86_init_noop(void) { } void __init x86_init_uint_noop(unsigned int unused) { } @@ -67,11 +68,7 @@ struct x86_init_ops x86_init __initdata = { }, .mpparse = { - .mpc_record = x86_init_uint_noop, .setup_ioapic_ids = x86_init_noop, - .mpc_apic_id = default_mpc_apic_id, - .smp_read_mpc_oem = default_smp_read_mpc_oem, - .mpc_oem_bus_info = default_mpc_oem_bus_info, .find_smp_config = default_find_smp_config, .get_smp_config = default_get_smp_config, }, @@ -80,7 +77,8 @@ struct x86_init_ops x86_init __initdata = { .pre_vector_init = init_ISA_irqs, .intr_init = native_init_IRQ, .intr_mode_select = apic_intr_mode_select, - .intr_mode_init = apic_intr_mode_init + .intr_mode_init = apic_intr_mode_init, + .create_pci_msi_domain = native_create_pci_msi_domain, }, .oem = { @@ -148,28 +146,10 @@ EXPORT_SYMBOL_GPL(x86_platform); #if defined(CONFIG_PCI_MSI) struct x86_msi_ops x86_msi __ro_after_init = { - .setup_msi_irqs = native_setup_msi_irqs, - .teardown_msi_irq = native_teardown_msi_irq, - .teardown_msi_irqs = default_teardown_msi_irqs, .restore_msi_irqs = default_restore_msi_irqs, }; /* MSI arch specific hooks */ -int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) -{ - return x86_msi.setup_msi_irqs(dev, nvec, type); -} - -void arch_teardown_msi_irqs(struct pci_dev *dev) -{ - x86_msi.teardown_msi_irqs(dev); -} - -void arch_teardown_msi_irq(unsigned int irq) -{ - x86_msi.teardown_msi_irq(irq); -} - void arch_restore_msi_irqs(struct pci_dev *dev) { x86_msi.restore_msi_irqs(dev); diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index fbd5bd7a945a..f92dfd8ef10d 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -66,6 +66,7 @@ config KVM_WERROR default y if X86_64 && !KASAN # We use the dependency on !COMPILE_TEST to not be enabled # blindly in allmodconfig or allyesconfig configurations + depends on KVM depends on (X86_64 && !KASAN) || !COMPILE_TEST depends on EXPERT help diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 4a3081e9f4b5..b804444e16d4 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -15,9 +15,11 @@ kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o kvm-y += x86.o emulate.o i8259.o irq.o lapic.o \ i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \ - hyperv.o debugfs.o mmu/mmu.o mmu/page_track.o + hyperv.o debugfs.o mmu/mmu.o mmu/page_track.o \ + mmu/spte.o mmu/tdp_iter.o mmu/tdp_mmu.o -kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o vmx/evmcs.o vmx/nested.o +kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o \ + vmx/evmcs.o vmx/nested.o vmx/posted_intr.o kvm-amd-y += svm/svm.o svm/vmenter.o svm/pmu.o svm/nested.o svm/avic.o svm/sev.o obj-$(CONFIG_KVM) += kvm.o diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 3fd6eec202d7..06a278b3701d 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -54,7 +54,24 @@ static u32 xstate_required_size(u64 xstate_bv, bool compacted) #define F feature_bit -static int kvm_check_cpuid(struct kvm_vcpu *vcpu) +static inline struct kvm_cpuid_entry2 *cpuid_entry2_find( + struct kvm_cpuid_entry2 *entries, int nent, u32 function, u32 index) +{ + struct kvm_cpuid_entry2 *e; + int i; + + for (i = 0; i < nent; i++) { + e = &entries[i]; + + if (e->function == function && (e->index == index || + !(e->flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX))) + return e; + } + + return NULL; +} + +static int kvm_check_cpuid(struct kvm_cpuid_entry2 *entries, int nent) { struct kvm_cpuid_entry2 *best; @@ -62,7 +79,7 @@ static int kvm_check_cpuid(struct kvm_vcpu *vcpu) * The existing code assumes virtual address is 48-bit or 57-bit in the * canonical address checks; exit if it is ever changed. */ - best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0); + best = cpuid_entry2_find(entries, nent, 0x80000008, 0); if (best) { int vaddr_bits = (best->eax & 0xff00) >> 8; @@ -107,6 +124,13 @@ void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu) (best->eax & (1 << KVM_FEATURE_PV_UNHALT))) best->eax &= ~(1 << KVM_FEATURE_PV_UNHALT); + /* + * save the feature bitmap to avoid cpuid lookup for every PV + * operation + */ + if (best) + vcpu->arch.pv_cpuid.features = best->eax; + if (!kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT)) { best = kvm_find_cpuid_entry(vcpu, 0x1, 0); if (best) @@ -121,8 +145,6 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) struct kvm_lapic *apic = vcpu->arch.apic; struct kvm_cpuid_entry2 *best; - kvm_x86_ops.vcpu_after_set_cpuid(vcpu); - best = kvm_find_cpuid_entry(vcpu, 1, 0); if (best && apic) { if (cpuid_entry_has(best, X86_FEATURE_TSC_DEADLINE_TIMER)) @@ -146,7 +168,9 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) kvm_pmu_refresh(vcpu); vcpu->arch.cr4_guest_rsvd_bits = __cr4_reserved_bits(guest_cpuid_has, vcpu); - kvm_x86_ops.update_exception_bitmap(vcpu); + + /* Invoke the vendor callback only after the above state is updated. */ + kvm_x86_ops.vcpu_after_set_cpuid(vcpu); } static int is_efer_nx(void) @@ -186,7 +210,6 @@ int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu) not_found: return 36; } -EXPORT_SYMBOL_GPL(cpuid_query_maxphyaddr); /* when an old userspace process fills a new kernel module */ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, @@ -194,46 +217,53 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry __user *entries) { int r, i; - struct kvm_cpuid_entry *cpuid_entries = NULL; + struct kvm_cpuid_entry *e = NULL; + struct kvm_cpuid_entry2 *e2 = NULL; - r = -E2BIG; if (cpuid->nent > KVM_MAX_CPUID_ENTRIES) - goto out; + return -E2BIG; + if (cpuid->nent) { - cpuid_entries = vmemdup_user(entries, - array_size(sizeof(struct kvm_cpuid_entry), - cpuid->nent)); - if (IS_ERR(cpuid_entries)) { - r = PTR_ERR(cpuid_entries); - goto out; + e = vmemdup_user(entries, array_size(sizeof(*e), cpuid->nent)); + if (IS_ERR(e)) + return PTR_ERR(e); + + e2 = kvmalloc_array(cpuid->nent, sizeof(*e2), GFP_KERNEL_ACCOUNT); + if (!e2) { + r = -ENOMEM; + goto out_free_cpuid; } } for (i = 0; i < cpuid->nent; i++) { - vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function; - vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax; - vcpu->arch.cpuid_entries[i].ebx = cpuid_entries[i].ebx; - vcpu->arch.cpuid_entries[i].ecx = cpuid_entries[i].ecx; - vcpu->arch.cpuid_entries[i].edx = cpuid_entries[i].edx; - vcpu->arch.cpuid_entries[i].index = 0; - vcpu->arch.cpuid_entries[i].flags = 0; - vcpu->arch.cpuid_entries[i].padding[0] = 0; - vcpu->arch.cpuid_entries[i].padding[1] = 0; - vcpu->arch.cpuid_entries[i].padding[2] = 0; + e2[i].function = e[i].function; + e2[i].eax = e[i].eax; + e2[i].ebx = e[i].ebx; + e2[i].ecx = e[i].ecx; + e2[i].edx = e[i].edx; + e2[i].index = 0; + e2[i].flags = 0; + e2[i].padding[0] = 0; + e2[i].padding[1] = 0; + e2[i].padding[2] = 0; } - vcpu->arch.cpuid_nent = cpuid->nent; - r = kvm_check_cpuid(vcpu); + + r = kvm_check_cpuid(e2, cpuid->nent); if (r) { - vcpu->arch.cpuid_nent = 0; - kvfree(cpuid_entries); - goto out; + kvfree(e2); + goto out_free_cpuid; } + kvfree(vcpu->arch.cpuid_entries); + vcpu->arch.cpuid_entries = e2; + vcpu->arch.cpuid_nent = cpuid->nent; + cpuid_fix_nx_cap(vcpu); kvm_update_cpuid_runtime(vcpu); kvm_vcpu_after_set_cpuid(vcpu); - kvfree(cpuid_entries); -out: +out_free_cpuid: + kvfree(e); + return r; } @@ -241,26 +271,32 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, struct kvm_cpuid_entry2 __user *entries) { + struct kvm_cpuid_entry2 *e2 = NULL; int r; - r = -E2BIG; if (cpuid->nent > KVM_MAX_CPUID_ENTRIES) - goto out; - r = -EFAULT; - if (copy_from_user(&vcpu->arch.cpuid_entries, entries, - cpuid->nent * sizeof(struct kvm_cpuid_entry2))) - goto out; - vcpu->arch.cpuid_nent = cpuid->nent; - r = kvm_check_cpuid(vcpu); + return -E2BIG; + + if (cpuid->nent) { + e2 = vmemdup_user(entries, array_size(sizeof(*e2), cpuid->nent)); + if (IS_ERR(e2)) + return PTR_ERR(e2); + } + + r = kvm_check_cpuid(e2, cpuid->nent); if (r) { - vcpu->arch.cpuid_nent = 0; - goto out; + kvfree(e2); + return r; } + kvfree(vcpu->arch.cpuid_entries); + vcpu->arch.cpuid_entries = e2; + vcpu->arch.cpuid_nent = cpuid->nent; + kvm_update_cpuid_runtime(vcpu); kvm_vcpu_after_set_cpuid(vcpu); -out: - return r; + + return 0; } int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, @@ -371,7 +407,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(SERIALIZE) | F(TSXLDTRK) ); /* TSC_ADJUST and ARCH_CAPABILITIES are emulated in software. */ @@ -941,17 +977,8 @@ out_free: struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, u32 function, u32 index) { - struct kvm_cpuid_entry2 *e; - int i; - - for (i = 0; i < vcpu->arch.cpuid_nent; ++i) { - e = &vcpu->arch.cpuid_entries[i]; - - if (e->function == function && (e->index == index || - !(e->flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX))) - return e; - } - return NULL; + return cpuid_entry2_find(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent, + function, index); } EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry); diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index 3a923ae15f2f..bf8577947ed2 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -5,6 +5,7 @@ #include "x86.h" #include <asm/cpu.h> #include <asm/processor.h> +#include <uapi/asm/kvm_para.h> extern u32 kvm_cpu_caps[NCAPINTS] __read_mostly; void kvm_set_cpu_caps(void); @@ -34,6 +35,11 @@ static inline int cpuid_maxphyaddr(struct kvm_vcpu *vcpu) return vcpu->arch.maxphyaddr; } +static inline bool kvm_vcpu_is_illegal_gpa(struct kvm_vcpu *vcpu, gpa_t gpa) +{ + return (gpa >= BIT_ULL(cpuid_maxphyaddr(vcpu))); +} + struct cpuid_reg { u32 function; u32 index; @@ -308,4 +314,13 @@ static inline bool page_address_valid(struct kvm_vcpu *vcpu, gpa_t gpa) return PAGE_ALIGNED(gpa) && !(gpa >> cpuid_maxphyaddr(vcpu)); } +static __always_inline bool guest_pv_has(struct kvm_vcpu *vcpu, + unsigned int kvm_feature) +{ + if (!vcpu->arch.pv_cpuid.enforce) + return true; + + return vcpu->arch.pv_cpuid.features & (1u << kvm_feature); +} + #endif diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 5299ef5ff18d..0d917eb70319 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2505,9 +2505,14 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt, *reg_write(ctxt, i) = GET_SMSTATE(u32, smstate, 0x7fd0 + i * 4); val = GET_SMSTATE(u32, smstate, 0x7fcc); - ctxt->ops->set_dr(ctxt, 6, (val & DR6_VOLATILE) | DR6_FIXED_1); + + if (ctxt->ops->set_dr(ctxt, 6, (val & DR6_VOLATILE) | DR6_FIXED_1)) + return X86EMUL_UNHANDLEABLE; + val = GET_SMSTATE(u32, smstate, 0x7fc8); - ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1); + + if (ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1)) + return X86EMUL_UNHANDLEABLE; selector = GET_SMSTATE(u32, smstate, 0x7fc4); set_desc_base(&desc, GET_SMSTATE(u32, smstate, 0x7f64)); @@ -2560,16 +2565,23 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, ctxt->eflags = GET_SMSTATE(u32, smstate, 0x7f70) | X86_EFLAGS_FIXED; val = GET_SMSTATE(u32, smstate, 0x7f68); - ctxt->ops->set_dr(ctxt, 6, (val & DR6_VOLATILE) | DR6_FIXED_1); + + if (ctxt->ops->set_dr(ctxt, 6, (val & DR6_VOLATILE) | DR6_FIXED_1)) + return X86EMUL_UNHANDLEABLE; + val = GET_SMSTATE(u32, smstate, 0x7f60); - ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1); + + if (ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1)) + return X86EMUL_UNHANDLEABLE; cr0 = GET_SMSTATE(u64, smstate, 0x7f58); cr3 = GET_SMSTATE(u64, smstate, 0x7f50); cr4 = GET_SMSTATE(u64, smstate, 0x7f48); ctxt->ops->set_smbase(ctxt, GET_SMSTATE(u32, smstate, 0x7f00)); val = GET_SMSTATE(u64, smstate, 0x7ed0); - ctxt->ops->set_msr(ctxt, MSR_EFER, val & ~EFER_LMA); + + if (ctxt->ops->set_msr(ctxt, MSR_EFER, val & ~EFER_LMA)) + return X86EMUL_UNHANDLEABLE; selector = GET_SMSTATE(u32, smstate, 0x7e90); rsm_set_desc_flags(&desc, GET_SMSTATE(u32, smstate, 0x7e92) << 8); @@ -3594,7 +3606,7 @@ static int em_rdpid(struct x86_emulate_ctxt *ctxt) u64 tsc_aux = 0; if (ctxt->ops->get_msr(ctxt, MSR_TSC_AUX, &tsc_aux)) - return emulate_gp(ctxt, 0); + return emulate_ud(ctxt); ctxt->dst.val = tsc_aux; return X86EMUL_CONTINUE; } @@ -3689,21 +3701,35 @@ static int em_dr_write(struct x86_emulate_ctxt *ctxt) static int em_wrmsr(struct x86_emulate_ctxt *ctxt) { + u64 msr_index = reg_read(ctxt, VCPU_REGS_RCX); u64 msr_data; + int r; msr_data = (u32)reg_read(ctxt, VCPU_REGS_RAX) | ((u64)reg_read(ctxt, VCPU_REGS_RDX) << 32); - if (ctxt->ops->set_msr(ctxt, reg_read(ctxt, VCPU_REGS_RCX), msr_data)) + r = ctxt->ops->set_msr(ctxt, msr_index, msr_data); + + if (r == X86EMUL_IO_NEEDED) + return r; + + if (r > 0) return emulate_gp(ctxt, 0); - return X86EMUL_CONTINUE; + return r < 0 ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE; } static int em_rdmsr(struct x86_emulate_ctxt *ctxt) { + u64 msr_index = reg_read(ctxt, VCPU_REGS_RCX); u64 msr_data; + int r; + + r = ctxt->ops->get_msr(ctxt, msr_index, &msr_data); + + if (r == X86EMUL_IO_NEEDED) + return r; - if (ctxt->ops->get_msr(ctxt, reg_read(ctxt, VCPU_REGS_RCX), &msr_data)) + if (r) return emulate_gp(ctxt, 0); *reg_write(ctxt, VCPU_REGS_RAX) = (u32)msr_data; diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 1d330564eed8..5c7c4060b45c 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -633,6 +633,11 @@ static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config, { union hv_stimer_config new_config = {.as_uint64 = config}, old_config = {.as_uint64 = stimer->config.as_uint64}; + struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer); + struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu); + + if (!synic->active && !host) + return 1; trace_kvm_hv_stimer_set_config(stimer_to_vcpu(stimer)->vcpu_id, stimer->index, config, host); @@ -652,6 +657,12 @@ static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config, static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count, bool host) { + struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer); + struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu); + + if (!synic->active && !host) + return 1; + trace_kvm_hv_stimer_set_count(stimer_to_vcpu(stimer)->vcpu_id, stimer->index, count, host); @@ -2000,20 +2011,20 @@ int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, break; case HYPERV_CPUID_FEATURES: - ent->eax |= HV_X64_MSR_VP_RUNTIME_AVAILABLE; + ent->eax |= HV_MSR_VP_RUNTIME_AVAILABLE; ent->eax |= HV_MSR_TIME_REF_COUNT_AVAILABLE; - ent->eax |= HV_X64_MSR_SYNIC_AVAILABLE; + ent->eax |= HV_MSR_SYNIC_AVAILABLE; ent->eax |= HV_MSR_SYNTIMER_AVAILABLE; - ent->eax |= HV_X64_MSR_APIC_ACCESS_AVAILABLE; - ent->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE; - ent->eax |= HV_X64_MSR_VP_INDEX_AVAILABLE; - ent->eax |= HV_X64_MSR_RESET_AVAILABLE; + ent->eax |= HV_MSR_APIC_ACCESS_AVAILABLE; + ent->eax |= HV_MSR_HYPERCALL_AVAILABLE; + ent->eax |= HV_MSR_VP_INDEX_AVAILABLE; + ent->eax |= HV_MSR_RESET_AVAILABLE; ent->eax |= HV_MSR_REFERENCE_TSC_AVAILABLE; - ent->eax |= HV_X64_ACCESS_FREQUENCY_MSRS; - ent->eax |= HV_X64_ACCESS_REENLIGHTENMENT; + ent->eax |= HV_ACCESS_FREQUENCY_MSRS; + ent->eax |= HV_ACCESS_REENLIGHTENMENT; - ent->ebx |= HV_X64_POST_MESSAGES; - ent->ebx |= HV_X64_SIGNAL_EVENTS; + ent->ebx |= HV_POST_MESSAGES; + ent->ebx |= HV_SIGNAL_EVENTS; ent->edx |= HV_FEATURE_FREQUENCY_MSRS_AVAILABLE; ent->edx |= HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE; diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index d057376bd3d3..698969e18fe3 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c @@ -197,12 +197,9 @@ static void ioapic_lazy_update_eoi(struct kvm_ioapic *ioapic, int irq) /* * If no longer has pending EOI in LAPICs, update - * EOI for this vetor. + * EOI for this vector. */ rtc_irq_eoi(ioapic, vcpu, entry->fields.vector); - kvm_ioapic_update_eoi_one(vcpu, ioapic, - entry->fields.trig_mode, - irq); break; } } diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h index cfe83d4ae625..a889563ad02d 100644 --- a/arch/x86/kvm/kvm_cache_regs.h +++ b/arch/x86/kvm/kvm_cache_regs.h @@ -7,7 +7,7 @@ #define KVM_POSSIBLE_CR0_GUEST_BITS X86_CR0_TS #define KVM_POSSIBLE_CR4_GUEST_BITS \ (X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR \ - | X86_CR4_OSXMMEXCPT | X86_CR4_LA57 | X86_CR4_PGE | X86_CR4_TSD) + | X86_CR4_OSXMMEXCPT | X86_CR4_PGE | X86_CR4_TSD | X86_CR4_FSGSBASE) #define BUILD_KVM_GPR_ACCESSORS(lname, uname) \ static __always_inline unsigned long kvm_##lname##_read(struct kvm_vcpu *vcpu)\ diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 35cca2e0c802..105e7859d1f2 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -310,6 +310,12 @@ static inline void kvm_apic_set_ldr(struct kvm_lapic *apic, u32 id) atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); } +static inline void kvm_apic_set_dfr(struct kvm_lapic *apic, u32 val) +{ + kvm_lapic_set_reg(apic, APIC_DFR, val); + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); +} + static inline u32 kvm_apic_calc_x2apic_ldr(u32 id) { return ((id >> 4) << 16) | (1 << (id & 0xf)); @@ -488,6 +494,12 @@ static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) } } +void kvm_apic_clear_irr(struct kvm_vcpu *vcpu, int vec) +{ + apic_clear_irr(vec, vcpu->arch.apic); +} +EXPORT_SYMBOL_GPL(kvm_apic_clear_irr); + static inline void apic_set_isr(int vec, struct kvm_lapic *apic) { struct kvm_vcpu *vcpu; @@ -1576,9 +1588,6 @@ static void __kvm_wait_lapic_expire(struct kvm_vcpu *vcpu) struct kvm_lapic *apic = vcpu->arch.apic; u64 guest_tsc, tsc_deadline; - if (apic->lapic_timer.expired_tscdeadline == 0) - return; - tsc_deadline = apic->lapic_timer.expired_tscdeadline; apic->lapic_timer.expired_tscdeadline = 0; guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc()); @@ -1593,7 +1602,10 @@ static void __kvm_wait_lapic_expire(struct kvm_vcpu *vcpu) void kvm_wait_lapic_expire(struct kvm_vcpu *vcpu) { - if (lapic_timer_int_injected(vcpu)) + if (lapic_in_kernel(vcpu) && + vcpu->arch.apic->lapic_timer.expired_tscdeadline && + vcpu->arch.apic->lapic_timer.timer_advance_ns && + lapic_timer_int_injected(vcpu)) __kvm_wait_lapic_expire(vcpu); } EXPORT_SYMBOL_GPL(kvm_wait_lapic_expire); @@ -1629,14 +1641,15 @@ static void apic_timer_expired(struct kvm_lapic *apic, bool from_timer_fn) } if (kvm_use_posted_timer_interrupt(apic->vcpu)) { - if (apic->lapic_timer.timer_advance_ns) - __kvm_wait_lapic_expire(vcpu); + kvm_wait_lapic_expire(vcpu); kvm_apic_inject_pending_timer_irqs(apic); return; } atomic_inc(&apic->lapic_timer.pending); - kvm_set_pending_timer(vcpu); + kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu); + if (from_timer_fn) + kvm_vcpu_kick(vcpu); } static void start_sw_tscdeadline(struct kvm_lapic *apic) @@ -1984,10 +1997,9 @@ int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) break; case APIC_DFR: - if (!apic_x2apic_mode(apic)) { - kvm_lapic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF); - atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); - } else + if (!apic_x2apic_mode(apic)) + kvm_apic_set_dfr(apic, val | 0x0FFFFFFF); + else ret = 1; break; @@ -2183,8 +2195,7 @@ u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu) { struct kvm_lapic *apic = vcpu->arch.apic; - if (!lapic_in_kernel(vcpu) || - !apic_lvtt_tscdeadline(apic)) + if (!kvm_apic_present(vcpu) || !apic_lvtt_tscdeadline(apic)) return 0; return apic->lapic_timer.tscdeadline; @@ -2194,8 +2205,7 @@ void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data) { struct kvm_lapic *apic = vcpu->arch.apic; - if (!kvm_apic_present(vcpu) || apic_lvtt_oneshot(apic) || - apic_lvtt_period(apic)) + if (!kvm_apic_present(vcpu) || !apic_lvtt_tscdeadline(apic)) return; hrtimer_cancel(&apic->lapic_timer.timer); @@ -2303,7 +2313,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT)); apic_manage_nmi_watchdog(apic, kvm_lapic_get_reg(apic, APIC_LVT0)); - kvm_lapic_set_reg(apic, APIC_DFR, 0xffffffffU); + kvm_apic_set_dfr(apic, 0xffffffffU); apic_set_spiv(apic, 0xff); kvm_lapic_set_reg(apic, APIC_TASKPRI, 0); if (!apic_x2apic_mode(apic)) @@ -2461,6 +2471,7 @@ int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu) __apic_update_ppr(apic, &ppr); return apic_has_interrupt_for_ppr(apic, ppr); } +EXPORT_SYMBOL_GPL(kvm_apic_has_interrupt); int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu) { diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 754f29beb83e..4fb86e3a9dd3 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -89,6 +89,7 @@ int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len, bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, int shorthand, unsigned int dest, int dest_mode); int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2); +void kvm_apic_clear_irr(struct kvm_vcpu *vcpu, int vec); bool __kvm_apic_update_irr(u32 *pir, void *regs, int *max_irr); bool kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir, int *max_irr); void kvm_apic_update_ppr(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 5efc6081ca13..9c4a9c8e43d9 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -155,11 +155,6 @@ static inline bool is_write_protection(struct kvm_vcpu *vcpu) return kvm_read_cr0_bits(vcpu, X86_CR0_WP); } -static inline bool kvm_mmu_is_illegal_gpa(struct kvm_vcpu *vcpu, gpa_t gpa) -{ - return (gpa >= BIT_ULL(cpuid_maxphyaddr(vcpu))); -} - /* * Check if a given access (described through the I/D, W/R and U/S bits of a * page fault error code pfec) causes a permission fault with the given PTE diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 43fdb0c12a5d..17587f496ec7 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -19,10 +19,12 @@ #include "ioapic.h" #include "mmu.h" #include "mmu_internal.h" +#include "tdp_mmu.h" #include "x86.h" #include "kvm_cache_regs.h" #include "kvm_emulate.h" #include "cpuid.h" +#include "spte.h" #include <linux/kvm_host.h> #include <linux/types.h> @@ -45,7 +47,6 @@ #include <asm/page.h> #include <asm/memtype.h> #include <asm/cmpxchg.h> -#include <asm/e820/api.h> #include <asm/io.h> #include <asm/vmx.h> #include <asm/kvm_page_track.h> @@ -64,12 +65,12 @@ static uint __read_mostly nx_huge_pages_recovery_ratio = 60; static int set_nx_huge_pages(const char *val, const struct kernel_param *kp); static int set_nx_huge_pages_recovery_ratio(const char *val, const struct kernel_param *kp); -static struct kernel_param_ops nx_huge_pages_ops = { +static const struct kernel_param_ops nx_huge_pages_ops = { .set = set_nx_huge_pages, .get = param_get_bool, }; -static struct kernel_param_ops nx_huge_pages_recovery_ratio_ops = { +static const struct kernel_param_ops nx_huge_pages_recovery_ratio_ops = { .set = set_nx_huge_pages_recovery_ratio, .get = param_get_uint, }; @@ -104,45 +105,13 @@ enum { AUDIT_POST_SYNC }; -#undef MMU_DEBUG - #ifdef MMU_DEBUG -static bool dbg = 0; +bool dbg = 0; module_param(dbg, bool, 0644); - -#define pgprintk(x...) do { if (dbg) printk(x); } while (0) -#define rmap_printk(x...) do { if (dbg) printk(x); } while (0) -#define MMU_WARN_ON(x) WARN_ON(x) -#else -#define pgprintk(x...) do { } while (0) -#define rmap_printk(x...) do { } while (0) -#define MMU_WARN_ON(x) do { } while (0) #endif #define PTE_PREFETCH_NUM 8 -#define PT_FIRST_AVAIL_BITS_SHIFT 10 -#define PT64_SECOND_AVAIL_BITS_SHIFT 54 - -/* - * The mask used to denote special SPTEs, which can be either MMIO SPTEs or - * Access Tracking SPTEs. - */ -#define SPTE_SPECIAL_MASK (3ULL << 52) -#define SPTE_AD_ENABLED_MASK (0ULL << 52) -#define SPTE_AD_DISABLED_MASK (1ULL << 52) -#define SPTE_AD_WRPROT_ONLY_MASK (2ULL << 52) -#define SPTE_MMIO_MASK (3ULL << 52) - -#define PT64_LEVEL_BITS 9 - -#define PT64_LEVEL_SHIFT(level) \ - (PAGE_SHIFT + (level - 1) * PT64_LEVEL_BITS) - -#define PT64_INDEX(address, level)\ - (((address) >> PT64_LEVEL_SHIFT(level)) & ((1 << PT64_LEVEL_BITS) - 1)) - - #define PT32_LEVEL_BITS 10 #define PT32_LEVEL_SHIFT(level) \ @@ -156,18 +125,6 @@ module_param(dbg, bool, 0644); (((address) >> PT32_LEVEL_SHIFT(level)) & ((1 << PT32_LEVEL_BITS) - 1)) -#ifdef CONFIG_DYNAMIC_PHYSICAL_MASK -#define PT64_BASE_ADDR_MASK (physical_mask & ~(u64)(PAGE_SIZE-1)) -#else -#define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1)) -#endif -#define PT64_LVL_ADDR_MASK(level) \ - (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \ - * PT64_LEVEL_BITS))) - 1)) -#define PT64_LVL_OFFSET_MASK(level) \ - (PT64_BASE_ADDR_MASK & ((1ULL << (PAGE_SHIFT + (((level) - 1) \ - * PT64_LEVEL_BITS))) - 1)) - #define PT32_BASE_ADDR_MASK PAGE_MASK #define PT32_DIR_BASE_ADDR_MASK \ (PAGE_MASK & ~((1ULL << (PAGE_SHIFT + PT32_LEVEL_BITS)) - 1)) @@ -175,42 +132,11 @@ module_param(dbg, bool, 0644); (PAGE_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \ * PT32_LEVEL_BITS))) - 1)) -#define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | shadow_user_mask \ - | shadow_x_mask | shadow_nx_mask | shadow_me_mask) - -#define ACC_EXEC_MASK 1 -#define ACC_WRITE_MASK PT_WRITABLE_MASK -#define ACC_USER_MASK PT_USER_MASK -#define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK) - -/* The mask for the R/X bits in EPT PTEs */ -#define PT64_EPT_READABLE_MASK 0x1ull -#define PT64_EPT_EXECUTABLE_MASK 0x4ull - #include <trace/events/kvm.h> -#define SPTE_HOST_WRITEABLE (1ULL << PT_FIRST_AVAIL_BITS_SHIFT) -#define SPTE_MMU_WRITEABLE (1ULL << (PT_FIRST_AVAIL_BITS_SHIFT + 1)) - -#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level) - /* make pte_list_desc fit well in cache line */ #define PTE_LIST_EXT 3 -/* - * Return values of handle_mmio_page_fault and mmu.page_fault: - * RET_PF_RETRY: let CPU fault again on the address. - * RET_PF_EMULATE: mmio page fault, emulate the instruction directly. - * - * For handle_mmio_page_fault only: - * RET_PF_INVALID: the spte is invalid, let the real page fault path update it. - */ -enum { - RET_PF_RETRY = 0, - RET_PF_EMULATE = 1, - RET_PF_INVALID = 2, -}; - struct pte_list_desc { u64 *sptes[PTE_LIST_EXT]; struct pte_list_desc *more; @@ -242,65 +168,10 @@ struct kvm_shadow_walk_iterator { __shadow_walk_next(&(_walker), spte)) static struct kmem_cache *pte_list_desc_cache; -static struct kmem_cache *mmu_page_header_cache; +struct kmem_cache *mmu_page_header_cache; static struct percpu_counter kvm_total_used_mmu_pages; -static u64 __read_mostly shadow_nx_mask; -static u64 __read_mostly shadow_x_mask; /* mutual exclusive with nx_mask */ -static u64 __read_mostly shadow_user_mask; -static u64 __read_mostly shadow_accessed_mask; -static u64 __read_mostly shadow_dirty_mask; -static u64 __read_mostly shadow_mmio_value; -static u64 __read_mostly shadow_mmio_access_mask; -static u64 __read_mostly shadow_present_mask; -static u64 __read_mostly shadow_me_mask; - -/* - * SPTEs used by MMUs without A/D bits are marked with SPTE_AD_DISABLED_MASK; - * shadow_acc_track_mask is the set of bits to be cleared in non-accessed - * pages. - */ -static u64 __read_mostly shadow_acc_track_mask; - -/* - * The mask/shift to use for saving the original R/X bits when marking the PTE - * as not-present for access tracking purposes. We do not save the W bit as the - * PTEs being access tracked also need to be dirty tracked, so the W bit will be - * restored only when a write is attempted to the page. - */ -static const u64 shadow_acc_track_saved_bits_mask = PT64_EPT_READABLE_MASK | - PT64_EPT_EXECUTABLE_MASK; -static const u64 shadow_acc_track_saved_bits_shift = PT64_SECOND_AVAIL_BITS_SHIFT; - -/* - * This mask must be set on all non-zero Non-Present or Reserved SPTEs in order - * to guard against L1TF attacks. - */ -static u64 __read_mostly shadow_nonpresent_or_rsvd_mask; - -/* - * The number of high-order 1 bits to use in the mask above. - */ -static const u64 shadow_nonpresent_or_rsvd_mask_len = 5; - -/* - * In some cases, we need to preserve the GFN of a non-present or reserved - * SPTE when we usurp the upper five bits of the physical address space to - * defend against L1TF, e.g. for MMIO SPTEs. To preserve the GFN, we'll - * shift bits of the GFN that overlap with shadow_nonpresent_or_rsvd_mask - * left into the reserved bits, i.e. the GFN in the SPTE will be split into - * high and low parts. This mask covers the lower bits of the GFN. - */ -static u64 __read_mostly shadow_nonpresent_or_rsvd_lower_gfn_mask; - -/* - * The number of non-reserved physical address bits irrespective of features - * that repurpose legal bits, e.g. MKTME. - */ -static u8 __read_mostly shadow_phys_bits; - static void mmu_spte_set(u64 *sptep, u64 spte); -static bool is_executable_pte(u64 spte); static union kvm_mmu_page_role kvm_mmu_calc_root_page_role(struct kvm_vcpu *vcpu); @@ -325,7 +196,7 @@ static void kvm_flush_remote_tlbs_with_range(struct kvm *kvm, kvm_flush_remote_tlbs(kvm); } -static void kvm_flush_remote_tlbs_with_address(struct kvm *kvm, +void kvm_flush_remote_tlbs_with_address(struct kvm *kvm, u64 start_gfn, u64 pages) { struct kvm_tlb_range range; @@ -336,143 +207,17 @@ static void kvm_flush_remote_tlbs_with_address(struct kvm *kvm, kvm_flush_remote_tlbs_with_range(kvm, &range); } -void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 access_mask) -{ - BUG_ON((u64)(unsigned)access_mask != access_mask); - WARN_ON(mmio_value & (shadow_nonpresent_or_rsvd_mask << shadow_nonpresent_or_rsvd_mask_len)); - WARN_ON(mmio_value & shadow_nonpresent_or_rsvd_lower_gfn_mask); - shadow_mmio_value = mmio_value | SPTE_MMIO_MASK; - shadow_mmio_access_mask = access_mask; -} -EXPORT_SYMBOL_GPL(kvm_mmu_set_mmio_spte_mask); - -static bool is_mmio_spte(u64 spte) -{ - return (spte & SPTE_SPECIAL_MASK) == SPTE_MMIO_MASK; -} - -static inline bool sp_ad_disabled(struct kvm_mmu_page *sp) -{ - return sp->role.ad_disabled; -} - -static inline bool kvm_vcpu_ad_need_write_protect(struct kvm_vcpu *vcpu) -{ - /* - * When using the EPT page-modification log, the GPAs in the log - * would come from L2 rather than L1. Therefore, we need to rely - * on write protection to record dirty pages. This also bypasses - * PML, since writes now result in a vmexit. - */ - return vcpu->arch.mmu == &vcpu->arch.guest_mmu; -} - -static inline bool spte_ad_enabled(u64 spte) -{ - MMU_WARN_ON(is_mmio_spte(spte)); - return (spte & SPTE_SPECIAL_MASK) != SPTE_AD_DISABLED_MASK; -} - -static inline bool spte_ad_need_write_protect(u64 spte) -{ - MMU_WARN_ON(is_mmio_spte(spte)); - return (spte & SPTE_SPECIAL_MASK) != SPTE_AD_ENABLED_MASK; -} - -static bool is_nx_huge_page_enabled(void) +bool is_nx_huge_page_enabled(void) { return READ_ONCE(nx_huge_pages); } -static inline u64 spte_shadow_accessed_mask(u64 spte) -{ - MMU_WARN_ON(is_mmio_spte(spte)); - return spte_ad_enabled(spte) ? shadow_accessed_mask : 0; -} - -static inline u64 spte_shadow_dirty_mask(u64 spte) -{ - MMU_WARN_ON(is_mmio_spte(spte)); - return spte_ad_enabled(spte) ? shadow_dirty_mask : 0; -} - -static inline bool is_access_track_spte(u64 spte) -{ - return !spte_ad_enabled(spte) && (spte & shadow_acc_track_mask) == 0; -} - -/* - * Due to limited space in PTEs, the MMIO generation is a 19 bit subset of - * the memslots generation and is derived as follows: - * - * Bits 0-8 of the MMIO generation are propagated to spte bits 3-11 - * Bits 9-18 of the MMIO generation are propagated to spte bits 52-61 - * - * The KVM_MEMSLOT_GEN_UPDATE_IN_PROGRESS flag is intentionally not included in - * the MMIO generation number, as doing so would require stealing a bit from - * the "real" generation number and thus effectively halve the maximum number - * of MMIO generations that can be handled before encountering a wrap (which - * requires a full MMU zap). The flag is instead explicitly queried when - * checking for MMIO spte cache hits. - */ -#define MMIO_SPTE_GEN_MASK GENMASK_ULL(17, 0) - -#define MMIO_SPTE_GEN_LOW_START 3 -#define MMIO_SPTE_GEN_LOW_END 11 -#define MMIO_SPTE_GEN_LOW_MASK GENMASK_ULL(MMIO_SPTE_GEN_LOW_END, \ - MMIO_SPTE_GEN_LOW_START) - -#define MMIO_SPTE_GEN_HIGH_START PT64_SECOND_AVAIL_BITS_SHIFT -#define MMIO_SPTE_GEN_HIGH_END 62 -#define MMIO_SPTE_GEN_HIGH_MASK GENMASK_ULL(MMIO_SPTE_GEN_HIGH_END, \ - MMIO_SPTE_GEN_HIGH_START) - -static u64 generation_mmio_spte_mask(u64 gen) -{ - u64 mask; - - WARN_ON(gen & ~MMIO_SPTE_GEN_MASK); - BUILD_BUG_ON((MMIO_SPTE_GEN_HIGH_MASK | MMIO_SPTE_GEN_LOW_MASK) & SPTE_SPECIAL_MASK); - - mask = (gen << MMIO_SPTE_GEN_LOW_START) & MMIO_SPTE_GEN_LOW_MASK; - mask |= (gen << MMIO_SPTE_GEN_HIGH_START) & MMIO_SPTE_GEN_HIGH_MASK; - return mask; -} - -static u64 get_mmio_spte_generation(u64 spte) -{ - u64 gen; - - gen = (spte & MMIO_SPTE_GEN_LOW_MASK) >> MMIO_SPTE_GEN_LOW_START; - gen |= (spte & MMIO_SPTE_GEN_HIGH_MASK) >> MMIO_SPTE_GEN_HIGH_START; - return gen; -} - -static u64 make_mmio_spte(struct kvm_vcpu *vcpu, u64 gfn, unsigned int access) -{ - - u64 gen = kvm_vcpu_memslots(vcpu)->generation & MMIO_SPTE_GEN_MASK; - u64 mask = generation_mmio_spte_mask(gen); - u64 gpa = gfn << PAGE_SHIFT; - - access &= shadow_mmio_access_mask; - mask |= shadow_mmio_value | access; - mask |= gpa | shadow_nonpresent_or_rsvd_mask; - mask |= (gpa & shadow_nonpresent_or_rsvd_mask) - << shadow_nonpresent_or_rsvd_mask_len; - - return mask; -} - static void mark_mmio_spte(struct kvm_vcpu *vcpu, u64 *sptep, u64 gfn, unsigned int access) { u64 mask = make_mmio_spte(vcpu, gfn, access); - unsigned int gen = get_mmio_spte_generation(mask); - - access = mask & ACC_ALL; - trace_mark_mmio_spte(sptep, gfn, access, gen); + trace_mark_mmio_spte(sptep, gfn, mask); mmu_spte_set(sptep, mask); } @@ -521,7 +266,7 @@ static gpa_t translate_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access, struct x86_exception *exception) { /* Check if guest physical address doesn't exceed guest maximum */ - if (kvm_mmu_is_illegal_gpa(vcpu, gpa)) { + if (kvm_vcpu_is_illegal_gpa(vcpu, gpa)) { exception->error_code |= PFERR_RSVD_MASK; return UNMAPPED_GVA; } @@ -529,90 +274,6 @@ static gpa_t translate_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access, return gpa; } -/* - * Sets the shadow PTE masks used by the MMU. - * - * Assumptions: - * - Setting either @accessed_mask or @dirty_mask requires setting both - * - At least one of @accessed_mask or @acc_track_mask must be set - */ -void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, - u64 dirty_mask, u64 nx_mask, u64 x_mask, u64 p_mask, - u64 acc_track_mask, u64 me_mask) -{ - BUG_ON(!dirty_mask != !accessed_mask); - BUG_ON(!accessed_mask && !acc_track_mask); - BUG_ON(acc_track_mask & SPTE_SPECIAL_MASK); - - shadow_user_mask = user_mask; - shadow_accessed_mask = accessed_mask; - shadow_dirty_mask = dirty_mask; - shadow_nx_mask = nx_mask; - shadow_x_mask = x_mask; - shadow_present_mask = p_mask; - shadow_acc_track_mask = acc_track_mask; - shadow_me_mask = me_mask; -} -EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes); - -static u8 kvm_get_shadow_phys_bits(void) -{ - /* - * boot_cpu_data.x86_phys_bits is reduced when MKTME or SME are detected - * in CPU detection code, but the processor treats those reduced bits as - * 'keyID' thus they are not reserved bits. Therefore KVM needs to look at - * the physical address bits reported by CPUID. - */ - if (likely(boot_cpu_data.extended_cpuid_level >= 0x80000008)) - return cpuid_eax(0x80000008) & 0xff; - - /* - * Quite weird to have VMX or SVM but not MAXPHYADDR; probably a VM with - * custom CPUID. Proceed with whatever the kernel found since these features - * aren't virtualizable (SME/SEV also require CPUIDs higher than 0x80000008). - */ - return boot_cpu_data.x86_phys_bits; -} - -static void kvm_mmu_reset_all_pte_masks(void) -{ - u8 low_phys_bits; - - shadow_user_mask = 0; - shadow_accessed_mask = 0; - shadow_dirty_mask = 0; - shadow_nx_mask = 0; - shadow_x_mask = 0; - shadow_present_mask = 0; - shadow_acc_track_mask = 0; - - shadow_phys_bits = kvm_get_shadow_phys_bits(); - - /* - * If the CPU has 46 or less physical address bits, then set an - * appropriate mask to guard against L1TF attacks. Otherwise, it is - * assumed that the CPU is not vulnerable to L1TF. - * - * Some Intel CPUs address the L1 cache using more PA bits than are - * reported by CPUID. Use the PA width of the L1 cache when possible - * to achieve more effective mitigation, e.g. if system RAM overlaps - * the most significant bits of legal physical address space. - */ - shadow_nonpresent_or_rsvd_mask = 0; - low_phys_bits = boot_cpu_data.x86_phys_bits; - if (boot_cpu_has_bug(X86_BUG_L1TF) && - !WARN_ON_ONCE(boot_cpu_data.x86_cache_bits >= - 52 - shadow_nonpresent_or_rsvd_mask_len)) { - low_phys_bits = boot_cpu_data.x86_cache_bits - - shadow_nonpresent_or_rsvd_mask_len; - shadow_nonpresent_or_rsvd_mask = - rsvd_bits(low_phys_bits, boot_cpu_data.x86_cache_bits - 1); - } - - shadow_nonpresent_or_rsvd_lower_gfn_mask = - GENMASK_ULL(low_phys_bits - 1, PAGE_SHIFT); -} - static int is_cpuid_PSE36(void) { return 1; @@ -623,35 +284,6 @@ static int is_nx(struct kvm_vcpu *vcpu) return vcpu->arch.efer & EFER_NX; } -static int is_shadow_present_pte(u64 pte) -{ - return (pte != 0) && !is_mmio_spte(pte); -} - -static int is_large_pte(u64 pte) -{ - return pte & PT_PAGE_SIZE_MASK; -} - -static int is_last_spte(u64 pte, int level) -{ - if (level == PG_LEVEL_4K) - return 1; - if (is_large_pte(pte)) - return 1; - return 0; -} - -static bool is_executable_pte(u64 spte) -{ - return (spte & (shadow_x_mask | shadow_nx_mask)) == shadow_x_mask; -} - -static kvm_pfn_t spte_to_pfn(u64 pte) -{ - return (pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; -} - static gfn_t pse36_gfn_delta(u32 gpte) { int shift = 32 - PT32_DIR_PSE36_SHIFT - PAGE_SHIFT; @@ -796,12 +428,6 @@ retry: } #endif -static bool spte_can_locklessly_be_made_writable(u64 spte) -{ - return (spte & (SPTE_HOST_WRITEABLE | SPTE_MMU_WRITEABLE)) == - (SPTE_HOST_WRITEABLE | SPTE_MMU_WRITEABLE); -} - static bool spte_has_volatile_bits(u64 spte) { if (!is_shadow_present_pte(spte)) @@ -826,21 +452,6 @@ static bool spte_has_volatile_bits(u64 spte) return false; } -static bool is_accessed_spte(u64 spte) -{ - u64 accessed_mask = spte_shadow_accessed_mask(spte); - - return accessed_mask ? spte & accessed_mask - : !is_access_track_spte(spte); -} - -static bool is_dirty_spte(u64 spte) -{ - u64 dirty_mask = spte_shadow_dirty_mask(spte); - - return dirty_mask ? spte & dirty_mask : spte & PT_WRITABLE_MASK; -} - /* Rules for using mmu_spte_set: * Set the sptep from nonpresent to present. * Note: the sptep being assigned *must* be either not present @@ -976,34 +587,6 @@ static u64 mmu_spte_get_lockless(u64 *sptep) return __get_spte_lockless(sptep); } -static u64 mark_spte_for_access_track(u64 spte) -{ - if (spte_ad_enabled(spte)) - return spte & ~shadow_accessed_mask; - - if (is_access_track_spte(spte)) - return spte; - - /* - * Making an Access Tracking PTE will result in removal of write access - * from the PTE. So, verify that we will be able to restore the write - * access in the fast page fault path later on. - */ - WARN_ONCE((spte & PT_WRITABLE_MASK) && - !spte_can_locklessly_be_made_writable(spte), - "kvm: Writable SPTE is not locklessly dirty-trackable\n"); - - WARN_ONCE(spte & (shadow_acc_track_saved_bits_mask << - shadow_acc_track_saved_bits_shift), - "kvm: Access Tracking saved bit locations are not zero\n"); - - spte |= (spte & shadow_acc_track_saved_bits_mask) << - shadow_acc_track_saved_bits_shift; - spte &= ~shadow_acc_track_mask; - - return spte; -} - /* Restore an acc-track PTE back to a regular PTE */ static u64 restore_acc_track_spte(u64 spte) { @@ -1193,7 +776,7 @@ static void account_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp) kvm_mmu_gfn_disallow_lpage(slot, gfn); } -static void account_huge_nx_page(struct kvm *kvm, struct kvm_mmu_page *sp) +void account_huge_nx_page(struct kvm *kvm, struct kvm_mmu_page *sp) { if (sp->lpage_disallowed) return; @@ -1221,7 +804,7 @@ static void unaccount_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp) kvm_mmu_gfn_allow_lpage(slot, gfn); } -static void unaccount_huge_nx_page(struct kvm *kvm, struct kvm_mmu_page *sp) +void unaccount_huge_nx_page(struct kvm *kvm, struct kvm_mmu_page *sp) { --kvm->stat.nx_lpage_splits; sp->lpage_disallowed = false; @@ -1640,6 +1223,9 @@ static void kvm_mmu_write_protect_pt_masked(struct kvm *kvm, { struct kvm_rmap_head *rmap_head; + if (kvm->arch.tdp_mmu_enabled) + kvm_tdp_mmu_clear_dirty_pt_masked(kvm, slot, + slot->base_gfn + gfn_offset, mask, true); while (mask) { rmap_head = __gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask), PG_LEVEL_4K, slot); @@ -1666,6 +1252,9 @@ void kvm_mmu_clear_dirty_pt_masked(struct kvm *kvm, { struct kvm_rmap_head *rmap_head; + if (kvm->arch.tdp_mmu_enabled) + kvm_tdp_mmu_clear_dirty_pt_masked(kvm, slot, + slot->base_gfn + gfn_offset, mask, false); while (mask) { rmap_head = __gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask), PG_LEVEL_4K, slot); @@ -1710,6 +1299,10 @@ bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm, write_protected |= __rmap_write_protect(kvm, rmap_head, true); } + if (kvm->arch.tdp_mmu_enabled) + write_protected |= + kvm_tdp_mmu_write_protect_gfn(kvm, slot, gfn); + return write_protected; } @@ -1769,13 +1362,8 @@ restart: pte_list_remove(rmap_head, sptep); goto restart; } else { - new_spte = *sptep & ~PT64_BASE_ADDR_MASK; - new_spte |= (u64)new_pfn << PAGE_SHIFT; - - new_spte &= ~PT_WRITABLE_MASK; - new_spte &= ~SPTE_HOST_WRITEABLE; - - new_spte = mark_spte_for_access_track(new_spte); + new_spte = kvm_mmu_changed_pte_notifier_make_spte( + *sptep, new_pfn); mmu_spte_clear_track_bits(sptep); mmu_spte_set(sptep, new_spte); @@ -1919,12 +1507,26 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end, unsigned flags) { - return kvm_handle_hva_range(kvm, start, end, 0, kvm_unmap_rmapp); + int r; + + r = kvm_handle_hva_range(kvm, start, end, 0, kvm_unmap_rmapp); + + if (kvm->arch.tdp_mmu_enabled) + r |= kvm_tdp_mmu_zap_hva_range(kvm, start, end); + + return r; } int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) { - return kvm_handle_hva(kvm, hva, (unsigned long)&pte, kvm_set_pte_rmapp); + int r; + + r = kvm_handle_hva(kvm, hva, (unsigned long)&pte, kvm_set_pte_rmapp); + + if (kvm->arch.tdp_mmu_enabled) + r |= kvm_tdp_mmu_set_spte_hva(kvm, hva, &pte); + + return r; } static int kvm_age_rmapp(struct kvm *kvm, struct kvm_rmap_head *rmap_head, @@ -1973,12 +1575,24 @@ static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn) int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end) { - return kvm_handle_hva_range(kvm, start, end, 0, kvm_age_rmapp); + int young = false; + + young = kvm_handle_hva_range(kvm, start, end, 0, kvm_age_rmapp); + if (kvm->arch.tdp_mmu_enabled) + young |= kvm_tdp_mmu_age_hva_range(kvm, start, end); + + return young; } int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) { - return kvm_handle_hva(kvm, hva, 0, kvm_test_age_rmapp); + int young = false; + + young = kvm_handle_hva(kvm, hva, 0, kvm_test_age_rmapp); + if (kvm->arch.tdp_mmu_enabled) + young |= kvm_tdp_mmu_test_age_hva(kvm, hva); + + return young; } #ifdef MMU_DEBUG @@ -2469,7 +2083,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, } if (sp->unsync_children) - kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); + kvm_make_request(KVM_REQ_MMU_SYNC, vcpu); __clear_sp_write_flooding_count(sp); @@ -2577,13 +2191,7 @@ static void link_shadow_page(struct kvm_vcpu *vcpu, u64 *sptep, BUILD_BUG_ON(VMX_EPT_WRITABLE_MASK != PT_WRITABLE_MASK); - spte = __pa(sp->spt) | shadow_present_mask | PT_WRITABLE_MASK | - shadow_user_mask | shadow_x_mask | shadow_me_mask; - - if (sp_ad_disabled(sp)) - spte |= SPTE_AD_DISABLED_MASK; - else - spte |= shadow_accessed_mask; + spte = make_nonleaf_spte(sp->spt, sp_ad_disabled(sp)); mmu_spte_set(sptep, spte); @@ -2615,8 +2223,9 @@ static void validate_direct_spte(struct kvm_vcpu *vcpu, u64 *sptep, } } -static bool mmu_page_zap_pte(struct kvm *kvm, struct kvm_mmu_page *sp, - u64 *spte) +/* Returns the number of zapped non-leaf child shadow pages. */ +static int mmu_page_zap_pte(struct kvm *kvm, struct kvm_mmu_page *sp, + u64 *spte, struct list_head *invalid_list) { u64 pte; struct kvm_mmu_page *child; @@ -2630,23 +2239,34 @@ static bool mmu_page_zap_pte(struct kvm *kvm, struct kvm_mmu_page *sp, } else { child = to_shadow_page(pte & PT64_BASE_ADDR_MASK); drop_parent_pte(child, spte); - } - return true; - } - if (is_mmio_spte(pte)) + /* + * Recursively zap nested TDP SPs, parentless SPs are + * unlikely to be used again in the near future. This + * avoids retaining a large number of stale nested SPs. + */ + if (tdp_enabled && invalid_list && + child->role.guest_mode && !child->parent_ptes.val) + return kvm_mmu_prepare_zap_page(kvm, child, + invalid_list); + } + } else if (is_mmio_spte(pte)) { mmu_spte_clear_no_track(spte); - - return false; + } + return 0; } -static void kvm_mmu_page_unlink_children(struct kvm *kvm, - struct kvm_mmu_page *sp) +static int kvm_mmu_page_unlink_children(struct kvm *kvm, + struct kvm_mmu_page *sp, + struct list_head *invalid_list) { + int zapped = 0; unsigned i; for (i = 0; i < PT64_ENT_PER_PAGE; ++i) - mmu_page_zap_pte(kvm, sp, sp->spt + i); + zapped += mmu_page_zap_pte(kvm, sp, sp->spt + i, invalid_list); + + return zapped; } static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp) @@ -2692,7 +2312,7 @@ static bool __kvm_mmu_prepare_zap_page(struct kvm *kvm, trace_kvm_mmu_prepare_zap_page(sp); ++kvm->stat.mmu_shadow_zapped; *nr_zapped = mmu_zap_unsync_children(kvm, sp, invalid_list); - kvm_mmu_page_unlink_children(kvm, sp); + *nr_zapped += kvm_mmu_page_unlink_children(kvm, sp, invalid_list); kvm_mmu_unlink_parents(kvm, sp); /* Zapping children means active_mmu_pages has become unstable. */ @@ -2885,8 +2505,8 @@ static void kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) kvm_mmu_mark_parents_unsync(sp); } -static bool mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn, - bool can_unsync) +bool mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn, + bool can_unsync) { struct kvm_mmu_page *sp; @@ -2946,132 +2566,42 @@ static bool mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn, return false; } -static bool kvm_is_mmio_pfn(kvm_pfn_t pfn) -{ - if (pfn_valid(pfn)) - return !is_zero_pfn(pfn) && PageReserved(pfn_to_page(pfn)) && - /* - * Some reserved pages, such as those from NVDIMM - * DAX devices, are not for MMIO, and can be mapped - * with cached memory type for better performance. - * However, the above check misconceives those pages - * as MMIO, and results in KVM mapping them with UC - * memory type, which would hurt the performance. - * Therefore, we check the host memory type in addition - * and only treat UC/UC-/WC pages as MMIO. - */ - (!pat_enabled() || pat_pfn_immune_to_uc_mtrr(pfn)); - - return !e820__mapped_raw_any(pfn_to_hpa(pfn), - pfn_to_hpa(pfn + 1) - 1, - E820_TYPE_RAM); -} - -/* Bits which may be returned by set_spte() */ -#define SET_SPTE_WRITE_PROTECTED_PT BIT(0) -#define SET_SPTE_NEED_REMOTE_TLB_FLUSH BIT(1) - static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, unsigned int pte_access, int level, gfn_t gfn, kvm_pfn_t pfn, bool speculative, bool can_unsync, bool host_writable) { - u64 spte = 0; - int ret = 0; + u64 spte; struct kvm_mmu_page *sp; + int ret; if (set_mmio_spte(vcpu, sptep, gfn, pfn, pte_access)) return 0; sp = sptep_to_sp(sptep); - if (sp_ad_disabled(sp)) - spte |= SPTE_AD_DISABLED_MASK; - else if (kvm_vcpu_ad_need_write_protect(vcpu)) - spte |= SPTE_AD_WRPROT_ONLY_MASK; - - /* - * For the EPT case, shadow_present_mask is 0 if hardware - * supports exec-only page table entries. In that case, - * ACC_USER_MASK and shadow_user_mask are used to represent - * read access. See FNAME(gpte_access) in paging_tmpl.h. - */ - spte |= shadow_present_mask; - if (!speculative) - spte |= spte_shadow_accessed_mask(spte); - if (level > PG_LEVEL_4K && (pte_access & ACC_EXEC_MASK) && - is_nx_huge_page_enabled()) { - pte_access &= ~ACC_EXEC_MASK; - } + ret = make_spte(vcpu, pte_access, level, gfn, pfn, *sptep, speculative, + can_unsync, host_writable, sp_ad_disabled(sp), &spte); - if (pte_access & ACC_EXEC_MASK) - spte |= shadow_x_mask; - else - spte |= shadow_nx_mask; - - if (pte_access & ACC_USER_MASK) - spte |= shadow_user_mask; - - if (level > PG_LEVEL_4K) - spte |= PT_PAGE_SIZE_MASK; - if (tdp_enabled) - spte |= kvm_x86_ops.get_mt_mask(vcpu, gfn, - kvm_is_mmio_pfn(pfn)); - - if (host_writable) - spte |= SPTE_HOST_WRITEABLE; - else - pte_access &= ~ACC_WRITE_MASK; - - if (!kvm_is_mmio_pfn(pfn)) - spte |= shadow_me_mask; - - spte |= (u64)pfn << PAGE_SHIFT; - - if (pte_access & ACC_WRITE_MASK) { - spte |= PT_WRITABLE_MASK | SPTE_MMU_WRITEABLE; - - /* - * Optimization: for pte sync, if spte was writable the hash - * lookup is unnecessary (and expensive). Write protection - * is responsibility of mmu_get_page / kvm_sync_page. - * Same reasoning can be applied to dirty page accounting. - */ - if (!can_unsync && is_writable_pte(*sptep)) - goto set_pte; - - if (mmu_need_write_protect(vcpu, gfn, can_unsync)) { - pgprintk("%s: found shadow page for %llx, marking ro\n", - __func__, gfn); - ret |= SET_SPTE_WRITE_PROTECTED_PT; - pte_access &= ~ACC_WRITE_MASK; - spte &= ~(PT_WRITABLE_MASK | SPTE_MMU_WRITEABLE); - } - } - - if (pte_access & ACC_WRITE_MASK) { + if (spte & PT_WRITABLE_MASK) kvm_vcpu_mark_page_dirty(vcpu, gfn); - spte |= spte_shadow_dirty_mask(spte); - } - if (speculative) - spte = mark_spte_for_access_track(spte); - -set_pte: - if (mmu_spte_update(sptep, spte)) + if (*sptep == spte) + ret |= SET_SPTE_SPURIOUS; + else if (mmu_spte_update(sptep, spte)) ret |= SET_SPTE_NEED_REMOTE_TLB_FLUSH; return ret; } static int mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep, - unsigned int pte_access, int write_fault, int level, + unsigned int pte_access, bool write_fault, int level, gfn_t gfn, kvm_pfn_t pfn, bool speculative, bool host_writable) { int was_rmapped = 0; int rmap_count; int set_spte_ret; - int ret = RET_PF_RETRY; + int ret = RET_PF_FIXED; bool flush = false; pgprintk("%s: spte %llx write_fault %d gfn %llx\n", __func__, @@ -3113,6 +2643,15 @@ static int mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep, if (unlikely(is_mmio_spte(*sptep))) ret = RET_PF_EMULATE; + /* + * The fault is fully spurious if and only if the new SPTE and old SPTE + * are identical, and emulation is not required. + */ + if ((set_spte_ret & SET_SPTE_SPURIOUS) && ret == RET_PF_FIXED) { + WARN_ON_ONCE(!was_rmapped); + return RET_PF_SPURIOUS; + } + pgprintk("%s: setting spte %llx\n", __func__, *sptep); trace_kvm_mmu_set_spte(level, gfn, sptep); if (!was_rmapped && is_large_pte(*sptep)) @@ -3161,7 +2700,7 @@ static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu, return -1; for (i = 0; i < ret; i++, gfn++, start++) { - mmu_set_spte(vcpu, start, access, 0, sp->role.level, gfn, + mmu_set_spte(vcpu, start, access, false, sp->role.level, gfn, page_to_pfn(pages[i]), true, true); put_page(pages[i]); } @@ -3239,8 +2778,9 @@ static int host_pfn_mapping_level(struct kvm_vcpu *vcpu, gfn_t gfn, return level; } -static int kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, gfn_t gfn, - int max_level, kvm_pfn_t *pfnp) +int kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, gfn_t gfn, + int max_level, kvm_pfn_t *pfnp, + bool huge_page_disallowed, int *req_level) { struct kvm_memory_slot *slot; struct kvm_lpage_info *linfo; @@ -3248,6 +2788,8 @@ static int kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, gfn_t gfn, kvm_pfn_t mask; int level; + *req_level = PG_LEVEL_4K; + if (unlikely(max_level == PG_LEVEL_4K)) return PG_LEVEL_4K; @@ -3272,7 +2814,14 @@ static int kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, gfn_t gfn, if (level == PG_LEVEL_4K) return level; - level = min(level, max_level); + *req_level = level = min(level, max_level); + + /* + * Enforce the iTLB multihit workaround after capturing the requested + * level, which will be used to do precise, accurate accounting. + */ + if (huge_page_disallowed) + return PG_LEVEL_4K; /* * mmu_notifier_retry() was successful and mmu_lock is held, so @@ -3285,14 +2834,12 @@ static int kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, gfn_t gfn, return level; } -static void disallowed_hugepage_adjust(struct kvm_shadow_walk_iterator it, - gfn_t gfn, kvm_pfn_t *pfnp, int *levelp) +void disallowed_hugepage_adjust(u64 spte, gfn_t gfn, int cur_level, + kvm_pfn_t *pfnp, int *goal_levelp) { - int level = *levelp; - u64 spte = *it.sptep; + int level = *goal_levelp; - if (it.level == level && level > PG_LEVEL_4K && - is_nx_huge_page_enabled() && + if (cur_level == level && level > PG_LEVEL_4K && is_shadow_present_pte(spte) && !is_large_pte(spte)) { /* @@ -3302,26 +2849,32 @@ static void disallowed_hugepage_adjust(struct kvm_shadow_walk_iterator it, * patching back for them into pfn the next 9 bits of * the address. */ - u64 page_mask = KVM_PAGES_PER_HPAGE(level) - KVM_PAGES_PER_HPAGE(level - 1); + u64 page_mask = KVM_PAGES_PER_HPAGE(level) - + KVM_PAGES_PER_HPAGE(level - 1); *pfnp |= gfn & page_mask; - (*levelp)--; + (*goal_levelp)--; } } -static int __direct_map(struct kvm_vcpu *vcpu, gpa_t gpa, int write, +static int __direct_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code, int map_writable, int max_level, kvm_pfn_t pfn, - bool prefault, bool account_disallowed_nx_lpage) + bool prefault, bool is_tdp) { + bool nx_huge_page_workaround_enabled = is_nx_huge_page_enabled(); + bool write = error_code & PFERR_WRITE_MASK; + bool exec = error_code & PFERR_FETCH_MASK; + bool huge_page_disallowed = exec && nx_huge_page_workaround_enabled; struct kvm_shadow_walk_iterator it; struct kvm_mmu_page *sp; - int level, ret; + int level, req_level, ret; gfn_t gfn = gpa >> PAGE_SHIFT; gfn_t base_gfn = gfn; if (WARN_ON(!VALID_PAGE(vcpu->arch.mmu->root_hpa))) return RET_PF_RETRY; - level = kvm_mmu_hugepage_adjust(vcpu, gfn, max_level, &pfn); + level = kvm_mmu_hugepage_adjust(vcpu, gfn, max_level, &pfn, + huge_page_disallowed, &req_level); trace_kvm_mmu_spte_requested(gpa, level, pfn); for_each_shadow_entry(vcpu, gpa, it) { @@ -3329,7 +2882,9 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t gpa, int write, * We cannot overwrite existing page tables with an NX * large page, as the leaf could be executable. */ - disallowed_hugepage_adjust(it, gfn, &pfn, &level); + if (nx_huge_page_workaround_enabled) + disallowed_hugepage_adjust(*it.sptep, gfn, it.level, + &pfn, &level); base_gfn = gfn & ~(KVM_PAGES_PER_HPAGE(it.level) - 1); if (it.level == level) @@ -3341,7 +2896,8 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t gpa, int write, it.level - 1, true, ACC_ALL); link_shadow_page(vcpu, it.sptep, sp); - if (account_disallowed_nx_lpage) + if (is_tdp && huge_page_disallowed && + req_level >= it.level) account_huge_nx_page(vcpu->kvm, sp); } } @@ -3349,6 +2905,9 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t gpa, int write, ret = mmu_set_spte(vcpu, it.sptep, ACC_ALL, write, level, base_gfn, pfn, prefault, map_writable); + if (ret == RET_PF_SPURIOUS) + return ret; + direct_pte_prefetch(vcpu, it.sptep); ++vcpu->stat.pf_fixed; return ret; @@ -3479,21 +3038,19 @@ static bool is_access_allowed(u32 fault_err_code, u64 spte) } /* - * Return value: - * - true: let the vcpu to access on the same address again. - * - false: let the real page fault path to fix it. + * Returns one of RET_PF_INVALID, RET_PF_FIXED or RET_PF_SPURIOUS. */ -static bool fast_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, - u32 error_code) +static int fast_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, + u32 error_code) { struct kvm_shadow_walk_iterator iterator; struct kvm_mmu_page *sp; - bool fault_handled = false; + int ret = RET_PF_INVALID; u64 spte = 0ull; uint retry_count = 0; if (!page_fault_can_be_fast(error_code)) - return false; + return ret; walk_shadow_page_lockless_begin(vcpu); @@ -3519,7 +3076,7 @@ static bool fast_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, * they are always ACC_ALL. */ if (is_access_allowed(error_code, spte)) { - fault_handled = true; + ret = RET_PF_SPURIOUS; break; } @@ -3562,11 +3119,11 @@ static bool fast_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, * since the gfn is not stable for indirect shadow page. See * Documentation/virt/kvm/locking.rst to get more detail. */ - fault_handled = fast_pf_fix_direct_spte(vcpu, sp, - iterator.sptep, spte, - new_spte); - if (fault_handled) + if (fast_pf_fix_direct_spte(vcpu, sp, iterator.sptep, spte, + new_spte)) { + ret = RET_PF_FIXED; break; + } if (++retry_count > 4) { printk_once(KERN_WARNING @@ -3577,10 +3134,10 @@ static bool fast_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, } while (true); trace_fast_page_fault(vcpu, cr2_or_gpa, error_code, iterator.sptep, - spte, fault_handled); + spte, ret); walk_shadow_page_lockless_end(vcpu); - return fault_handled; + return ret; } static void mmu_free_root_page(struct kvm *kvm, hpa_t *root_hpa, @@ -3592,9 +3149,13 @@ static void mmu_free_root_page(struct kvm *kvm, hpa_t *root_hpa, return; sp = to_shadow_page(*root_hpa & PT64_BASE_ADDR_MASK); - --sp->root_count; - if (!sp->root_count && sp->role.invalid) - kvm_mmu_prepare_zap_page(kvm, sp, invalid_list); + + if (kvm_mmu_put_root(kvm, sp)) { + if (sp->tdp_mmu_page) + kvm_tdp_mmu_free_root(kvm, sp); + else if (sp->role.invalid) + kvm_mmu_prepare_zap_page(kvm, sp, invalid_list); + } *root_hpa = INVALID_PAGE; } @@ -3603,6 +3164,7 @@ static void mmu_free_root_page(struct kvm *kvm, hpa_t *root_hpa, void kvm_mmu_free_roots(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, ulong roots_to_free) { + struct kvm *kvm = vcpu->kvm; int i; LIST_HEAD(invalid_list); bool free_active_root = roots_to_free & KVM_MMU_ROOT_CURRENT; @@ -3620,22 +3182,21 @@ void kvm_mmu_free_roots(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, return; } - spin_lock(&vcpu->kvm->mmu_lock); + spin_lock(&kvm->mmu_lock); for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++) if (roots_to_free & KVM_MMU_ROOT_PREVIOUS(i)) - mmu_free_root_page(vcpu->kvm, &mmu->prev_roots[i].hpa, + mmu_free_root_page(kvm, &mmu->prev_roots[i].hpa, &invalid_list); if (free_active_root) { if (mmu->shadow_root_level >= PT64_ROOT_4LEVEL && (mmu->root_level >= PT64_ROOT_4LEVEL || mmu->direct_map)) { - mmu_free_root_page(vcpu->kvm, &mmu->root_hpa, - &invalid_list); + mmu_free_root_page(kvm, &mmu->root_hpa, &invalid_list); } else { for (i = 0; i < 4; ++i) if (mmu->pae_root[i] != 0) - mmu_free_root_page(vcpu->kvm, + mmu_free_root_page(kvm, &mmu->pae_root[i], &invalid_list); mmu->root_hpa = INVALID_PAGE; @@ -3643,8 +3204,8 @@ void kvm_mmu_free_roots(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, mmu->root_pgd = 0; } - kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list); - spin_unlock(&vcpu->kvm->mmu_lock); + kvm_mmu_commit_zap_page(kvm, &invalid_list); + spin_unlock(&kvm->mmu_lock); } EXPORT_SYMBOL_GPL(kvm_mmu_free_roots); @@ -3684,8 +3245,16 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu) hpa_t root; unsigned i; - if (shadow_root_level >= PT64_ROOT_4LEVEL) { - root = mmu_alloc_root(vcpu, 0, 0, shadow_root_level, true); + if (vcpu->kvm->arch.tdp_mmu_enabled) { + root = kvm_tdp_mmu_get_vcpu_root_hpa(vcpu); + + if (!VALID_PAGE(root)) + return -ENOSPC; + vcpu->arch.mmu->root_hpa = root; + } else if (shadow_root_level >= PT64_ROOT_4LEVEL) { + root = mmu_alloc_root(vcpu, 0, 0, shadow_root_level, + true); + if (!VALID_PAGE(root)) return -ENOSPC; vcpu->arch.mmu->root_hpa = root; @@ -3910,54 +3479,82 @@ static bool mmio_info_in_cache(struct kvm_vcpu *vcpu, u64 addr, bool direct) return vcpu_match_mmio_gva(vcpu, addr); } -/* return true if reserved bit is detected on spte. */ -static bool -walk_shadow_page_get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep) +/* + * 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) { struct kvm_shadow_walk_iterator iterator; - u64 sptes[PT64_ROOT_MAX_LEVEL], spte = 0ull; - struct rsvd_bits_validate *rsvd_check; - int root, leaf; - bool reserved = false; + int leaf = vcpu->arch.mmu->root_level; + u64 spte; - rsvd_check = &vcpu->arch.mmu->shadow_zero_check; walk_shadow_page_lockless_begin(vcpu); - for (shadow_walk_init(&iterator, vcpu, addr), - leaf = root = iterator.level; + for (shadow_walk_init(&iterator, vcpu, addr); shadow_walk_okay(&iterator); __shadow_walk_next(&iterator, spte)) { + leaf = iterator.level; spte = mmu_spte_get_lockless(iterator.sptep); sptes[leaf - 1] = spte; - leaf--; if (!is_shadow_present_pte(spte)) break; + } + + walk_shadow_page_lockless_end(vcpu); + + return leaf; +} + +/* return true if reserved bit is detected on spte. */ +static bool get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep) +{ + u64 sptes[PT64_ROOT_MAX_LEVEL]; + struct rsvd_bits_validate *rsvd_check; + int root = vcpu->arch.mmu->root_level; + int leaf; + int level; + bool reserved = false; + + if (!VALID_PAGE(vcpu->arch.mmu->root_hpa)) { + *sptep = 0ull; + return reserved; + } + + if (is_tdp_mmu_root(vcpu->kvm, vcpu->arch.mmu->root_hpa)) + leaf = kvm_tdp_mmu_get_walk(vcpu, addr, sptes); + else + leaf = get_walk(vcpu, addr, sptes); + + rsvd_check = &vcpu->arch.mmu->shadow_zero_check; + + for (level = root; level >= leaf; level--) { + if (!is_shadow_present_pte(sptes[level - 1])) + break; /* * 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, spte) | - __is_rsvd_bits_set(rsvd_check, spte, iterator.level); + reserved |= __is_bad_mt_xwr(rsvd_check, sptes[level - 1]) | + __is_rsvd_bits_set(rsvd_check, sptes[level - 1], + level); } - walk_shadow_page_lockless_end(vcpu); - if (reserved) { pr_err("%s: detect reserved bits on spte, addr 0x%llx, dump hierarchy:\n", __func__, addr); - while (root > leaf) { + for (level = root; level >= leaf; level--) pr_err("------ spte 0x%llx level %d.\n", - sptes[root - 1], root); - root--; - } + sptes[level - 1], level); } - *sptep = spte; + *sptep = sptes[leaf - 1]; + return reserved; } @@ -3969,7 +3566,7 @@ static int handle_mmio_page_fault(struct kvm_vcpu *vcpu, u64 addr, bool direct) if (mmio_info_in_cache(vcpu, addr, direct)) return RET_PF_EMULATE; - reserved = walk_shadow_page_get_mmio_spte(vcpu, addr, &spte); + reserved = get_mmio_spte(vcpu, addr, &spte); if (WARN_ON(reserved)) return -EINVAL; @@ -4080,8 +3677,6 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code, bool prefault, int max_level, bool is_tdp) { bool write = error_code & PFERR_WRITE_MASK; - bool exec = error_code & PFERR_FETCH_MASK; - bool lpage_disallowed = exec && is_nx_huge_page_enabled(); bool map_writable; gfn_t gfn = gpa >> PAGE_SHIFT; @@ -4092,16 +3687,16 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code, if (page_fault_handle_page_track(vcpu, error_code, gfn)) return RET_PF_EMULATE; - if (fast_page_fault(vcpu, gpa, error_code)) - return RET_PF_RETRY; + if (!is_tdp_mmu_root(vcpu->kvm, vcpu->arch.mmu->root_hpa)) { + r = fast_page_fault(vcpu, gpa, error_code); + if (r != RET_PF_INVALID) + return r; + } r = mmu_topup_memory_caches(vcpu, false); if (r) return r; - if (lpage_disallowed) - max_level = PG_LEVEL_4K; - mmu_seq = vcpu->kvm->mmu_notifier_seq; smp_rmb(); @@ -4118,8 +3713,13 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code, r = make_mmu_pages_available(vcpu); if (r) goto out_unlock; - r = __direct_map(vcpu, gpa, write, map_writable, max_level, pfn, - prefault, is_tdp && lpage_disallowed); + + if (is_tdp_mmu_root(vcpu->kvm, vcpu->arch.mmu->root_hpa)) + r = kvm_tdp_mmu_map(vcpu, gpa, error_code, map_writable, max_level, + pfn, prefault); + else + r = __direct_map(vcpu, gpa, error_code, map_writable, max_level, pfn, + prefault, is_tdp); out_unlock: spin_unlock(&vcpu->kvm->mmu_lock); @@ -4292,7 +3892,13 @@ static void __kvm_mmu_new_pgd(struct kvm_vcpu *vcpu, gpa_t new_pgd, */ vcpu_clear_mmio_info(vcpu, MMIO_GVA_ANY); - __clear_sp_write_flooding_count(to_shadow_page(vcpu->arch.mmu->root_hpa)); + /* + * If this is a direct root page, it doesn't have a write flooding + * count. Otherwise, clear the write flooding count. + */ + if (!new_role.direct) + __clear_sp_write_flooding_count( + to_shadow_page(vcpu->arch.mmu->root_hpa)); } void kvm_mmu_new_pgd(struct kvm_vcpu *vcpu, gpa_t new_pgd, bool skip_tlb_flush, @@ -5400,7 +5006,7 @@ static void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, u32 base_role = vcpu->arch.mmu->mmu_role.base.word; entry = *spte; - mmu_page_zap_pte(vcpu->kvm, sp, spte); + mmu_page_zap_pte(vcpu->kvm, sp, spte, NULL); if (gentry && !((sp->role.word ^ base_role) & ~role_ign.word) && rmap_can_add(vcpu)) @@ -5450,13 +5056,14 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u64 error_code, if (r == RET_PF_INVALID) { r = kvm_mmu_do_page_fault(vcpu, cr2_or_gpa, lower_32_bits(error_code), false); - WARN_ON(r == RET_PF_INVALID); + if (WARN_ON_ONCE(r == RET_PF_INVALID)) + return -EIO; } - if (r == RET_PF_RETRY) - return 1; if (r < 0) return r; + if (r != RET_PF_EMULATE) + return 1; /* * Before emulating the instruction, check if the error code @@ -5485,18 +5092,6 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u64 error_code, if (!mmio_info_in_cache(vcpu, cr2_or_gpa, direct) && !is_guest_mode(vcpu)) emulation_type |= EMULTYPE_ALLOW_RETRY_PF; emulate: - /* - * On AMD platforms, under certain conditions insn_len may be zero on #NPF. - * This can happen if a guest gets a page-fault on data access but the HW - * table walker is not able to read the instruction page (e.g instruction - * page is not present in memory). In those cases we simply restart the - * guest, with the exception of AMD Erratum 1096 which is unrecoverable. - */ - if (unlikely(insn && !insn_len)) { - if (!kvm_x86_ops.need_emulation_on_page_fault(vcpu)) - return 1; - } - return x86_emulate_instruction(vcpu, cr2_or_gpa, emulation_type, insn, insn_len); } @@ -5682,11 +5277,17 @@ static void free_mmu_pages(struct kvm_mmu *mmu) free_page((unsigned long)mmu->lm_root); } -static int alloc_mmu_pages(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu) +static int __kvm_mmu_create(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu) { struct page *page; int i; + mmu->root_hpa = INVALID_PAGE; + mmu->root_pgd = 0; + mmu->translate_gpa = translate_gpa; + for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++) + mmu->prev_roots[i] = KVM_MMU_ROOT_INFO_INVALID; + /* * When using PAE paging, the four PDPTEs are treated as 'root' pages, * while the PDP table is a per-vCPU construct that's allocated at MMU @@ -5712,7 +5313,6 @@ static int alloc_mmu_pages(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu) int kvm_mmu_create(struct kvm_vcpu *vcpu) { - uint i; int ret; vcpu->arch.mmu_pte_list_desc_cache.kmem_cache = pte_list_desc_cache; @@ -5726,25 +5326,13 @@ int kvm_mmu_create(struct kvm_vcpu *vcpu) vcpu->arch.mmu = &vcpu->arch.root_mmu; vcpu->arch.walk_mmu = &vcpu->arch.root_mmu; - vcpu->arch.root_mmu.root_hpa = INVALID_PAGE; - vcpu->arch.root_mmu.root_pgd = 0; - vcpu->arch.root_mmu.translate_gpa = translate_gpa; - for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++) - vcpu->arch.root_mmu.prev_roots[i] = KVM_MMU_ROOT_INFO_INVALID; - - vcpu->arch.guest_mmu.root_hpa = INVALID_PAGE; - vcpu->arch.guest_mmu.root_pgd = 0; - vcpu->arch.guest_mmu.translate_gpa = translate_gpa; - for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++) - vcpu->arch.guest_mmu.prev_roots[i] = KVM_MMU_ROOT_INFO_INVALID; - vcpu->arch.nested_mmu.translate_gpa = translate_nested_gpa; - ret = alloc_mmu_pages(vcpu, &vcpu->arch.guest_mmu); + ret = __kvm_mmu_create(vcpu, &vcpu->arch.guest_mmu); if (ret) return ret; - ret = alloc_mmu_pages(vcpu, &vcpu->arch.root_mmu); + ret = __kvm_mmu_create(vcpu, &vcpu->arch.root_mmu); if (ret) goto fail_allocate_root; @@ -5841,6 +5429,10 @@ static void kvm_mmu_zap_all_fast(struct kvm *kvm) kvm_reload_remote_mmus(kvm); kvm_zap_obsolete_pages(kvm); + + if (kvm->arch.tdp_mmu_enabled) + kvm_tdp_mmu_zap_all(kvm); + spin_unlock(&kvm->mmu_lock); } @@ -5860,6 +5452,8 @@ void kvm_mmu_init_vm(struct kvm *kvm) { struct kvm_page_track_notifier_node *node = &kvm->arch.mmu_sp_tracker; + kvm_mmu_init_tdp_mmu(kvm); + node->track_write = kvm_mmu_pte_write; node->track_flush_slot = kvm_mmu_invalidate_zap_pages_in_memslot; kvm_page_track_register_notifier(kvm, node); @@ -5870,6 +5464,8 @@ void kvm_mmu_uninit_vm(struct kvm *kvm) struct kvm_page_track_notifier_node *node = &kvm->arch.mmu_sp_tracker; kvm_page_track_unregister_notifier(kvm, node); + + kvm_mmu_uninit_tdp_mmu(kvm); } void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) @@ -5877,6 +5473,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) struct kvm_memslots *slots; struct kvm_memory_slot *memslot; int i; + bool flush; spin_lock(&kvm->mmu_lock); for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { @@ -5896,6 +5493,12 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) } } + if (kvm->arch.tdp_mmu_enabled) { + flush = kvm_tdp_mmu_zap_gfn_range(kvm, gfn_start, gfn_end); + if (flush) + kvm_flush_remote_tlbs(kvm); + } + spin_unlock(&kvm->mmu_lock); } @@ -5914,6 +5517,8 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, spin_lock(&kvm->mmu_lock); flush = slot_handle_level(kvm, memslot, slot_rmap_write_protect, start_level, KVM_MAX_HUGEPAGE_LEVEL, false); + if (kvm->arch.tdp_mmu_enabled) + flush |= kvm_tdp_mmu_wrprot_slot(kvm, memslot, PG_LEVEL_4K); spin_unlock(&kvm->mmu_lock); /* @@ -5977,6 +5582,9 @@ void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm, spin_lock(&kvm->mmu_lock); slot_handle_leaf(kvm, (struct kvm_memory_slot *)memslot, kvm_mmu_zap_collapsible_spte, true); + + if (kvm->arch.tdp_mmu_enabled) + kvm_tdp_mmu_zap_collapsible_sptes(kvm, memslot); spin_unlock(&kvm->mmu_lock); } @@ -6002,6 +5610,8 @@ void kvm_mmu_slot_leaf_clear_dirty(struct kvm *kvm, spin_lock(&kvm->mmu_lock); flush = slot_handle_leaf(kvm, memslot, __rmap_clear_dirty, false); + if (kvm->arch.tdp_mmu_enabled) + flush |= kvm_tdp_mmu_clear_dirty_slot(kvm, memslot); spin_unlock(&kvm->mmu_lock); /* @@ -6023,6 +5633,8 @@ void kvm_mmu_slot_largepage_remove_write_access(struct kvm *kvm, spin_lock(&kvm->mmu_lock); flush = slot_handle_large_level(kvm, memslot, slot_rmap_write_protect, false); + if (kvm->arch.tdp_mmu_enabled) + flush |= kvm_tdp_mmu_wrprot_slot(kvm, memslot, PG_LEVEL_2M); spin_unlock(&kvm->mmu_lock); if (flush) @@ -6037,6 +5649,8 @@ void kvm_mmu_slot_set_dirty(struct kvm *kvm, spin_lock(&kvm->mmu_lock); flush = slot_handle_all_level(kvm, memslot, __rmap_set_dirty, false); + if (kvm->arch.tdp_mmu_enabled) + flush |= kvm_tdp_mmu_slot_set_dirty(kvm, memslot); spin_unlock(&kvm->mmu_lock); if (flush) @@ -6062,6 +5676,10 @@ restart: } kvm_mmu_commit_zap_page(kvm, &invalid_list); + + if (kvm->arch.tdp_mmu_enabled) + kvm_tdp_mmu_zap_all(kvm); + spin_unlock(&kvm->mmu_lock); } @@ -6357,7 +5975,10 @@ static void kvm_recover_nx_lpages(struct kvm *kvm) ratio = READ_ONCE(nx_huge_pages_recovery_ratio); to_zap = ratio ? DIV_ROUND_UP(kvm->stat.nx_lpage_splits, ratio) : 0; - while (to_zap && !list_empty(&kvm->arch.lpage_disallowed_mmu_pages)) { + for ( ; to_zap; --to_zap) { + if (list_empty(&kvm->arch.lpage_disallowed_mmu_pages)) + break; + /* * We use a separate list instead of just using active_mmu_pages * because the number of lpage_disallowed pages is expected to @@ -6367,15 +5988,20 @@ static void kvm_recover_nx_lpages(struct kvm *kvm) struct kvm_mmu_page, lpage_disallowed_link); WARN_ON_ONCE(!sp->lpage_disallowed); - kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list); - WARN_ON_ONCE(sp->lpage_disallowed); + if (sp->tdp_mmu_page) + kvm_tdp_mmu_zap_gfn_range(kvm, sp->gfn, + sp->gfn + KVM_PAGES_PER_HPAGE(sp->role.level)); + else { + kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list); + WARN_ON_ONCE(sp->lpage_disallowed); + } - if (!--to_zap || need_resched() || spin_needbreak(&kvm->mmu_lock)) { + if (need_resched() || spin_needbreak(&kvm->mmu_lock)) { kvm_mmu_commit_zap_page(kvm, &invalid_list); - if (to_zap) - cond_resched_lock(&kvm->mmu_lock); + cond_resched_lock(&kvm->mmu_lock); } } + kvm_mmu_commit_zap_page(kvm, &invalid_list); spin_unlock(&kvm->mmu_lock); srcu_read_unlock(&kvm->srcu, rcu_idx); diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h index 3acf3b8eb469..bfc6389edc28 100644 --- a/arch/x86/kvm/mmu/mmu_internal.h +++ b/arch/x86/kvm/mmu/mmu_internal.h @@ -3,9 +3,23 @@ #define __KVM_X86_MMU_INTERNAL_H #include <linux/types.h> - +#include <linux/kvm_host.h> #include <asm/kvm_host.h> +#undef MMU_DEBUG + +#ifdef MMU_DEBUG +extern bool dbg; + +#define pgprintk(x...) do { if (dbg) printk(x); } while (0) +#define rmap_printk(x...) do { if (dbg) printk(x); } while (0) +#define MMU_WARN_ON(x) WARN_ON(x) +#else +#define pgprintk(x...) do { } while (0) +#define rmap_printk(x...) do { } while (0) +#define MMU_WARN_ON(x) do { } while (0) +#endif + struct kvm_mmu_page { struct list_head link; struct hlist_node hash_link; @@ -41,8 +55,12 @@ struct kvm_mmu_page { /* Number of writes since the last time traversal visited this page. */ atomic_t write_flooding_count; + + bool tdp_mmu_page; }; +extern struct kmem_cache *mmu_page_header_cache; + static inline struct kvm_mmu_page *to_shadow_page(hpa_t shadow_page) { struct page *page = pfn_to_page(shadow_page >> PAGE_SHIFT); @@ -55,9 +73,77 @@ static inline struct kvm_mmu_page *sptep_to_sp(u64 *sptep) return to_shadow_page(__pa(sptep)); } +static inline bool kvm_vcpu_ad_need_write_protect(struct kvm_vcpu *vcpu) +{ + /* + * When using the EPT page-modification log, the GPAs in the log + * would come from L2 rather than L1. Therefore, we need to rely + * on write protection to record dirty pages. This also bypasses + * PML, since writes now result in a vmexit. + */ + return vcpu->arch.mmu == &vcpu->arch.guest_mmu; +} + +bool is_nx_huge_page_enabled(void); +bool mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn, + bool can_unsync); + void kvm_mmu_gfn_disallow_lpage(struct kvm_memory_slot *slot, gfn_t gfn); void kvm_mmu_gfn_allow_lpage(struct kvm_memory_slot *slot, gfn_t gfn); bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm, struct kvm_memory_slot *slot, u64 gfn); +void kvm_flush_remote_tlbs_with_address(struct kvm *kvm, + u64 start_gfn, u64 pages); + +static inline void kvm_mmu_get_root(struct kvm *kvm, struct kvm_mmu_page *sp) +{ + BUG_ON(!sp->root_count); + lockdep_assert_held(&kvm->mmu_lock); + + ++sp->root_count; +} + +static inline bool kvm_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *sp) +{ + lockdep_assert_held(&kvm->mmu_lock); + --sp->root_count; + + return !sp->root_count; +} + +/* + * Return values of handle_mmio_page_fault, mmu.page_fault, and fast_page_fault(). + * + * RET_PF_RETRY: let CPU fault again on the address. + * RET_PF_EMULATE: mmio page fault, emulate the instruction directly. + * RET_PF_INVALID: the spte is invalid, let the real page fault path update it. + * RET_PF_FIXED: The faulting entry has been fixed. + * RET_PF_SPURIOUS: The faulting entry was already fixed, e.g. by another vCPU. + */ +enum { + RET_PF_RETRY = 0, + RET_PF_EMULATE, + RET_PF_INVALID, + RET_PF_FIXED, + RET_PF_SPURIOUS, +}; + +/* Bits which may be returned by set_spte() */ +#define SET_SPTE_WRITE_PROTECTED_PT BIT(0) +#define SET_SPTE_NEED_REMOTE_TLB_FLUSH BIT(1) +#define SET_SPTE_SPURIOUS BIT(2) + +int kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, gfn_t gfn, + int max_level, kvm_pfn_t *pfnp, + bool huge_page_disallowed, int *req_level); +void disallowed_hugepage_adjust(u64 spte, gfn_t gfn, int cur_level, + kvm_pfn_t *pfnp, int *goal_levelp); + +bool is_nx_huge_page_enabled(void); + +void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc); + +void account_huge_nx_page(struct kvm *kvm, struct kvm_mmu_page *sp); +void unaccount_huge_nx_page(struct kvm *kvm, struct kvm_mmu_page *sp); #endif /* __KVM_X86_MMU_INTERNAL_H */ diff --git a/arch/x86/kvm/mmu/mmutrace.h b/arch/x86/kvm/mmu/mmutrace.h index 9d15bc0c535b..213699b27b44 100644 --- a/arch/x86/kvm/mmu/mmutrace.h +++ b/arch/x86/kvm/mmu/mmutrace.h @@ -202,8 +202,8 @@ DEFINE_EVENT(kvm_mmu_page_class, kvm_mmu_prepare_zap_page, TRACE_EVENT( mark_mmio_spte, - TP_PROTO(u64 *sptep, gfn_t gfn, unsigned access, unsigned int gen), - TP_ARGS(sptep, gfn, access, gen), + TP_PROTO(u64 *sptep, gfn_t gfn, u64 spte), + TP_ARGS(sptep, gfn, spte), TP_STRUCT__entry( __field(void *, sptep) @@ -215,8 +215,8 @@ TRACE_EVENT( TP_fast_assign( __entry->sptep = sptep; __entry->gfn = gfn; - __entry->access = access; - __entry->gen = gen; + __entry->access = spte & ACC_ALL; + __entry->gen = get_mmio_spte_generation(spte); ), TP_printk("sptep:%p gfn %llx access %x gen %x", __entry->sptep, @@ -244,14 +244,11 @@ TRACE_EVENT( __entry->access) ); -#define __spte_satisfied(__spte) \ - (__entry->retry && is_writable_pte(__entry->__spte)) - TRACE_EVENT( fast_page_fault, TP_PROTO(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u32 error_code, - u64 *sptep, u64 old_spte, bool retry), - TP_ARGS(vcpu, cr2_or_gpa, error_code, sptep, old_spte, retry), + u64 *sptep, u64 old_spte, int ret), + TP_ARGS(vcpu, cr2_or_gpa, error_code, sptep, old_spte, ret), TP_STRUCT__entry( __field(int, vcpu_id) @@ -260,7 +257,7 @@ TRACE_EVENT( __field(u64 *, sptep) __field(u64, old_spte) __field(u64, new_spte) - __field(bool, retry) + __field(int, ret) ), TP_fast_assign( @@ -270,7 +267,7 @@ TRACE_EVENT( __entry->sptep = sptep; __entry->old_spte = old_spte; __entry->new_spte = *sptep; - __entry->retry = retry; + __entry->ret = ret; ), TP_printk("vcpu %d gva %llx error_code %s sptep %p old %#llx" @@ -278,7 +275,7 @@ TRACE_EVENT( __entry->cr2_or_gpa, __print_flags(__entry->error_code, "|", kvm_mmu_trace_pferr_flags), __entry->sptep, __entry->old_spte, __entry->new_spte, - __spte_satisfied(old_spte), __spte_satisfied(new_spte) + __entry->ret == RET_PF_SPURIOUS, __entry->ret == RET_PF_FIXED ) ); diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c index a84a141a2ad2..8443a675715b 100644 --- a/arch/x86/kvm/mmu/page_track.c +++ b/arch/x86/kvm/mmu/page_track.c @@ -229,7 +229,8 @@ void kvm_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new, return; idx = srcu_read_lock(&head->track_srcu); - hlist_for_each_entry_rcu(n, &head->track_notifier_list, node) + hlist_for_each_entry_srcu(n, &head->track_notifier_list, node, + srcu_read_lock_held(&head->track_srcu)) if (n->track_write) n->track_write(vcpu, gpa, new, bytes, n); srcu_read_unlock(&head->track_srcu, idx); @@ -254,7 +255,8 @@ void kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot) return; idx = srcu_read_lock(&head->track_srcu); - hlist_for_each_entry_rcu(n, &head->track_notifier_list, node) + hlist_for_each_entry_srcu(n, &head->track_notifier_list, node, + srcu_read_lock_held(&head->track_srcu)) if (n->track_flush_slot) n->track_flush_slot(kvm, slot, n); srcu_read_unlock(&head->track_srcu, idx); diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index 4dd6b1e5b8cf..50e268eb8e1a 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -550,7 +550,7 @@ FNAME(prefetch_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, * we call mmu_set_spte() with host_writable = true because * pte_prefetch_gfn_to_pfn always gets a writable pfn. */ - mmu_set_spte(vcpu, spte, pte_access, 0, PG_LEVEL_4K, gfn, pfn, + mmu_set_spte(vcpu, spte, pte_access, false, PG_LEVEL_4K, gfn, pfn, true, true); kvm_release_pfn_clean(pfn); @@ -625,15 +625,18 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw, * emulate this operation, return 1 to indicate this case. */ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr, - struct guest_walker *gw, - int write_fault, int max_level, - kvm_pfn_t pfn, bool map_writable, bool prefault, - bool lpage_disallowed) + struct guest_walker *gw, u32 error_code, + int max_level, kvm_pfn_t pfn, bool map_writable, + bool prefault) { + bool nx_huge_page_workaround_enabled = is_nx_huge_page_enabled(); + bool write_fault = error_code & PFERR_WRITE_MASK; + bool exec = error_code & PFERR_FETCH_MASK; + bool huge_page_disallowed = exec && nx_huge_page_workaround_enabled; struct kvm_mmu_page *sp = NULL; struct kvm_shadow_walk_iterator it; unsigned direct_access, access = gw->pt_access; - int top_level, hlevel, ret; + int top_level, level, req_level, ret; gfn_t base_gfn = gw->gfn; direct_access = gw->pte_access; @@ -679,7 +682,8 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr, link_shadow_page(vcpu, it.sptep, sp); } - hlevel = kvm_mmu_hugepage_adjust(vcpu, gw->gfn, max_level, &pfn); + level = kvm_mmu_hugepage_adjust(vcpu, gw->gfn, max_level, &pfn, + huge_page_disallowed, &req_level); trace_kvm_mmu_spte_requested(addr, gw->level, pfn); @@ -690,10 +694,12 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr, * We cannot overwrite existing page tables with an NX * large page, as the leaf could be executable. */ - disallowed_hugepage_adjust(it, gw->gfn, &pfn, &hlevel); + if (nx_huge_page_workaround_enabled) + disallowed_hugepage_adjust(*it.sptep, gw->gfn, it.level, + &pfn, &level); base_gfn = gw->gfn & ~(KVM_PAGES_PER_HPAGE(it.level) - 1); - if (it.level == hlevel) + if (it.level == level) break; validate_direct_spte(vcpu, it.sptep, direct_access); @@ -704,13 +710,16 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr, sp = kvm_mmu_get_page(vcpu, base_gfn, addr, it.level - 1, true, direct_access); link_shadow_page(vcpu, it.sptep, sp); - if (lpage_disallowed) + if (huge_page_disallowed && req_level >= it.level) account_huge_nx_page(vcpu->kvm, sp); } } ret = mmu_set_spte(vcpu, it.sptep, gw->pte_access, write_fault, it.level, base_gfn, pfn, prefault, map_writable); + if (ret == RET_PF_SPURIOUS) + return ret; + FNAME(pte_prefetch)(vcpu, gw, it.sptep); ++vcpu->stat.pf_fixed; return ret; @@ -738,7 +747,7 @@ out_gpte_changed: */ static bool FNAME(is_self_change_mapping)(struct kvm_vcpu *vcpu, - struct guest_walker *walker, int user_fault, + struct guest_walker *walker, bool user_fault, bool *write_fault_to_shadow_pgtable) { int level; @@ -776,15 +785,13 @@ FNAME(is_self_change_mapping)(struct kvm_vcpu *vcpu, static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gpa_t addr, u32 error_code, bool prefault) { - int write_fault = error_code & PFERR_WRITE_MASK; - int user_fault = error_code & PFERR_USER_MASK; + bool write_fault = error_code & PFERR_WRITE_MASK; + bool user_fault = error_code & PFERR_USER_MASK; struct guest_walker walker; int r; kvm_pfn_t pfn; unsigned long mmu_seq; bool map_writable, is_self_change_mapping; - bool lpage_disallowed = (error_code & PFERR_FETCH_MASK) && - is_nx_huge_page_enabled(); int max_level; pgprintk("%s: addr %lx err %x\n", __func__, addr, error_code); @@ -825,7 +832,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gpa_t addr, u32 error_code, is_self_change_mapping = FNAME(is_self_change_mapping)(vcpu, &walker, user_fault, &vcpu->arch.write_fault_to_shadow_pgtable); - if (lpage_disallowed || is_self_change_mapping) + if (is_self_change_mapping) max_level = PG_LEVEL_4K; else max_level = walker.level; @@ -869,8 +876,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gpa_t addr, u32 error_code, r = make_mmu_pages_available(vcpu); if (r) goto out_unlock; - r = FNAME(fetch)(vcpu, addr, &walker, write_fault, max_level, pfn, - map_writable, prefault, lpage_disallowed); + r = FNAME(fetch)(vcpu, addr, &walker, error_code, max_level, pfn, + map_writable, prefault); kvm_mmu_audit(vcpu, AUDIT_POST_PAGE_FAULT); out_unlock: @@ -895,6 +902,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva, hpa_t root_hpa) { struct kvm_shadow_walk_iterator iterator; struct kvm_mmu_page *sp; + u64 old_spte; int level; u64 *sptep; @@ -917,7 +925,8 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva, hpa_t root_hpa) sptep = iterator.sptep; sp = sptep_to_sp(sptep); - if (is_last_spte(*sptep, level)) { + old_spte = *sptep; + if (is_last_spte(old_spte, level)) { pt_element_t gpte; gpa_t pte_gpa; @@ -927,7 +936,8 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva, hpa_t root_hpa) pte_gpa = FNAME(get_level1_sp_gpa)(sp); pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t); - if (mmu_page_zap_pte(vcpu->kvm, sp, sptep)) + mmu_page_zap_pte(vcpu->kvm, sp, sptep, NULL); + if (is_shadow_present_pte(old_spte)) kvm_flush_remote_tlbs_with_address(vcpu->kvm, sp->gfn, KVM_PAGES_PER_HPAGE(sp->role.level)); diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c new file mode 100644 index 000000000000..d9c5665a55e9 --- /dev/null +++ b/arch/x86/kvm/mmu/spte.c @@ -0,0 +1,318 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Kernel-based Virtual Machine driver for Linux + * + * Macros and functions to access KVM PTEs (also known as SPTEs) + * + * Copyright (C) 2006 Qumranet, Inc. + * Copyright 2020 Red Hat, Inc. and/or its affiliates. + */ + + +#include <linux/kvm_host.h> +#include "mmu.h" +#include "mmu_internal.h" +#include "x86.h" +#include "spte.h" + +#include <asm/e820/api.h> + +u64 __read_mostly shadow_nx_mask; +u64 __read_mostly shadow_x_mask; /* mutual exclusive with nx_mask */ +u64 __read_mostly shadow_user_mask; +u64 __read_mostly shadow_accessed_mask; +u64 __read_mostly shadow_dirty_mask; +u64 __read_mostly shadow_mmio_value; +u64 __read_mostly shadow_mmio_access_mask; +u64 __read_mostly shadow_present_mask; +u64 __read_mostly shadow_me_mask; +u64 __read_mostly shadow_acc_track_mask; + +u64 __read_mostly shadow_nonpresent_or_rsvd_mask; +u64 __read_mostly shadow_nonpresent_or_rsvd_lower_gfn_mask; + +u8 __read_mostly shadow_phys_bits; + +static u64 generation_mmio_spte_mask(u64 gen) +{ + u64 mask; + + WARN_ON(gen & ~MMIO_SPTE_GEN_MASK); + BUILD_BUG_ON((MMIO_SPTE_GEN_HIGH_MASK | MMIO_SPTE_GEN_LOW_MASK) & SPTE_SPECIAL_MASK); + + mask = (gen << MMIO_SPTE_GEN_LOW_START) & MMIO_SPTE_GEN_LOW_MASK; + mask |= (gen << MMIO_SPTE_GEN_HIGH_START) & MMIO_SPTE_GEN_HIGH_MASK; + return mask; +} + +u64 make_mmio_spte(struct kvm_vcpu *vcpu, u64 gfn, unsigned int access) +{ + u64 gen = kvm_vcpu_memslots(vcpu)->generation & MMIO_SPTE_GEN_MASK; + u64 mask = generation_mmio_spte_mask(gen); + u64 gpa = gfn << PAGE_SHIFT; + + access &= shadow_mmio_access_mask; + mask |= shadow_mmio_value | access; + mask |= gpa | shadow_nonpresent_or_rsvd_mask; + mask |= (gpa & shadow_nonpresent_or_rsvd_mask) + << shadow_nonpresent_or_rsvd_mask_len; + + return mask; +} + +static bool kvm_is_mmio_pfn(kvm_pfn_t pfn) +{ + if (pfn_valid(pfn)) + return !is_zero_pfn(pfn) && PageReserved(pfn_to_page(pfn)) && + /* + * Some reserved pages, such as those from NVDIMM + * DAX devices, are not for MMIO, and can be mapped + * with cached memory type for better performance. + * However, the above check misconceives those pages + * as MMIO, and results in KVM mapping them with UC + * memory type, which would hurt the performance. + * Therefore, we check the host memory type in addition + * and only treat UC/UC-/WC pages as MMIO. + */ + (!pat_enabled() || pat_pfn_immune_to_uc_mtrr(pfn)); + + return !e820__mapped_raw_any(pfn_to_hpa(pfn), + pfn_to_hpa(pfn + 1) - 1, + E820_TYPE_RAM); +} + +int make_spte(struct kvm_vcpu *vcpu, unsigned int pte_access, int level, + gfn_t gfn, kvm_pfn_t pfn, u64 old_spte, bool speculative, + bool can_unsync, bool host_writable, bool ad_disabled, + u64 *new_spte) +{ + u64 spte = 0; + int ret = 0; + + if (ad_disabled) + spte |= SPTE_AD_DISABLED_MASK; + else if (kvm_vcpu_ad_need_write_protect(vcpu)) + spte |= SPTE_AD_WRPROT_ONLY_MASK; + + /* + * For the EPT case, shadow_present_mask is 0 if hardware + * supports exec-only page table entries. In that case, + * ACC_USER_MASK and shadow_user_mask are used to represent + * read access. See FNAME(gpte_access) in paging_tmpl.h. + */ + spte |= shadow_present_mask; + if (!speculative) + spte |= spte_shadow_accessed_mask(spte); + + if (level > PG_LEVEL_4K && (pte_access & ACC_EXEC_MASK) && + is_nx_huge_page_enabled()) { + pte_access &= ~ACC_EXEC_MASK; + } + + if (pte_access & ACC_EXEC_MASK) + spte |= shadow_x_mask; + else + spte |= shadow_nx_mask; + + if (pte_access & ACC_USER_MASK) + spte |= shadow_user_mask; + + if (level > PG_LEVEL_4K) + spte |= PT_PAGE_SIZE_MASK; + if (tdp_enabled) + spte |= kvm_x86_ops.get_mt_mask(vcpu, gfn, + kvm_is_mmio_pfn(pfn)); + + if (host_writable) + spte |= SPTE_HOST_WRITEABLE; + else + pte_access &= ~ACC_WRITE_MASK; + + if (!kvm_is_mmio_pfn(pfn)) + spte |= shadow_me_mask; + + spte |= (u64)pfn << PAGE_SHIFT; + + if (pte_access & ACC_WRITE_MASK) { + spte |= PT_WRITABLE_MASK | SPTE_MMU_WRITEABLE; + + /* + * Optimization: for pte sync, if spte was writable the hash + * lookup is unnecessary (and expensive). Write protection + * is responsibility of mmu_get_page / kvm_sync_page. + * Same reasoning can be applied to dirty page accounting. + */ + if (!can_unsync && is_writable_pte(old_spte)) + goto out; + + if (mmu_need_write_protect(vcpu, gfn, can_unsync)) { + pgprintk("%s: found shadow page for %llx, marking ro\n", + __func__, gfn); + ret |= SET_SPTE_WRITE_PROTECTED_PT; + pte_access &= ~ACC_WRITE_MASK; + spte &= ~(PT_WRITABLE_MASK | SPTE_MMU_WRITEABLE); + } + } + + if (pte_access & ACC_WRITE_MASK) + spte |= spte_shadow_dirty_mask(spte); + + if (speculative) + spte = mark_spte_for_access_track(spte); + +out: + *new_spte = spte; + return ret; +} + +u64 make_nonleaf_spte(u64 *child_pt, bool ad_disabled) +{ + u64 spte; + + spte = __pa(child_pt) | shadow_present_mask | PT_WRITABLE_MASK | + shadow_user_mask | shadow_x_mask | shadow_me_mask; + + if (ad_disabled) + spte |= SPTE_AD_DISABLED_MASK; + else + spte |= shadow_accessed_mask; + + return spte; +} + +u64 kvm_mmu_changed_pte_notifier_make_spte(u64 old_spte, kvm_pfn_t new_pfn) +{ + u64 new_spte; + + new_spte = old_spte & ~PT64_BASE_ADDR_MASK; + new_spte |= (u64)new_pfn << PAGE_SHIFT; + + new_spte &= ~PT_WRITABLE_MASK; + new_spte &= ~SPTE_HOST_WRITEABLE; + + new_spte = mark_spte_for_access_track(new_spte); + + return new_spte; +} + +static u8 kvm_get_shadow_phys_bits(void) +{ + /* + * boot_cpu_data.x86_phys_bits is reduced when MKTME or SME are detected + * in CPU detection code, but the processor treats those reduced bits as + * 'keyID' thus they are not reserved bits. Therefore KVM needs to look at + * the physical address bits reported by CPUID. + */ + if (likely(boot_cpu_data.extended_cpuid_level >= 0x80000008)) + return cpuid_eax(0x80000008) & 0xff; + + /* + * Quite weird to have VMX or SVM but not MAXPHYADDR; probably a VM with + * custom CPUID. Proceed with whatever the kernel found since these features + * aren't virtualizable (SME/SEV also require CPUIDs higher than 0x80000008). + */ + return boot_cpu_data.x86_phys_bits; +} + +u64 mark_spte_for_access_track(u64 spte) +{ + if (spte_ad_enabled(spte)) + return spte & ~shadow_accessed_mask; + + if (is_access_track_spte(spte)) + return spte; + + /* + * Making an Access Tracking PTE will result in removal of write access + * from the PTE. So, verify that we will be able to restore the write + * access in the fast page fault path later on. + */ + WARN_ONCE((spte & PT_WRITABLE_MASK) && + !spte_can_locklessly_be_made_writable(spte), + "kvm: Writable SPTE is not locklessly dirty-trackable\n"); + + WARN_ONCE(spte & (shadow_acc_track_saved_bits_mask << + shadow_acc_track_saved_bits_shift), + "kvm: Access Tracking saved bit locations are not zero\n"); + + spte |= (spte & shadow_acc_track_saved_bits_mask) << + shadow_acc_track_saved_bits_shift; + spte &= ~shadow_acc_track_mask; + + return spte; +} + +void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 access_mask) +{ + BUG_ON((u64)(unsigned)access_mask != access_mask); + WARN_ON(mmio_value & (shadow_nonpresent_or_rsvd_mask << shadow_nonpresent_or_rsvd_mask_len)); + WARN_ON(mmio_value & shadow_nonpresent_or_rsvd_lower_gfn_mask); + shadow_mmio_value = mmio_value | SPTE_MMIO_MASK; + shadow_mmio_access_mask = access_mask; +} +EXPORT_SYMBOL_GPL(kvm_mmu_set_mmio_spte_mask); + +/* + * Sets the shadow PTE masks used by the MMU. + * + * Assumptions: + * - Setting either @accessed_mask or @dirty_mask requires setting both + * - At least one of @accessed_mask or @acc_track_mask must be set + */ +void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, + u64 dirty_mask, u64 nx_mask, u64 x_mask, u64 p_mask, + u64 acc_track_mask, u64 me_mask) +{ + BUG_ON(!dirty_mask != !accessed_mask); + BUG_ON(!accessed_mask && !acc_track_mask); + BUG_ON(acc_track_mask & SPTE_SPECIAL_MASK); + + shadow_user_mask = user_mask; + shadow_accessed_mask = accessed_mask; + shadow_dirty_mask = dirty_mask; + shadow_nx_mask = nx_mask; + shadow_x_mask = x_mask; + shadow_present_mask = p_mask; + shadow_acc_track_mask = acc_track_mask; + shadow_me_mask = me_mask; +} +EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes); + +void kvm_mmu_reset_all_pte_masks(void) +{ + u8 low_phys_bits; + + shadow_user_mask = 0; + shadow_accessed_mask = 0; + shadow_dirty_mask = 0; + shadow_nx_mask = 0; + shadow_x_mask = 0; + shadow_present_mask = 0; + shadow_acc_track_mask = 0; + + shadow_phys_bits = kvm_get_shadow_phys_bits(); + + /* + * If the CPU has 46 or less physical address bits, then set an + * appropriate mask to guard against L1TF attacks. Otherwise, it is + * assumed that the CPU is not vulnerable to L1TF. + * + * Some Intel CPUs address the L1 cache using more PA bits than are + * reported by CPUID. Use the PA width of the L1 cache when possible + * to achieve more effective mitigation, e.g. if system RAM overlaps + * the most significant bits of legal physical address space. + */ + shadow_nonpresent_or_rsvd_mask = 0; + low_phys_bits = boot_cpu_data.x86_phys_bits; + if (boot_cpu_has_bug(X86_BUG_L1TF) && + !WARN_ON_ONCE(boot_cpu_data.x86_cache_bits >= + 52 - shadow_nonpresent_or_rsvd_mask_len)) { + low_phys_bits = boot_cpu_data.x86_cache_bits + - shadow_nonpresent_or_rsvd_mask_len; + shadow_nonpresent_or_rsvd_mask = + rsvd_bits(low_phys_bits, boot_cpu_data.x86_cache_bits - 1); + } + + shadow_nonpresent_or_rsvd_lower_gfn_mask = + GENMASK_ULL(low_phys_bits - 1, PAGE_SHIFT); +} diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h new file mode 100644 index 000000000000..4ecf40e0b8fe --- /dev/null +++ b/arch/x86/kvm/mmu/spte.h @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#ifndef KVM_X86_MMU_SPTE_H +#define KVM_X86_MMU_SPTE_H + +#include "mmu_internal.h" + +#define PT_FIRST_AVAIL_BITS_SHIFT 10 +#define PT64_SECOND_AVAIL_BITS_SHIFT 54 + +/* + * The mask used to denote special SPTEs, which can be either MMIO SPTEs or + * Access Tracking SPTEs. + */ +#define SPTE_SPECIAL_MASK (3ULL << 52) +#define SPTE_AD_ENABLED_MASK (0ULL << 52) +#define SPTE_AD_DISABLED_MASK (1ULL << 52) +#define SPTE_AD_WRPROT_ONLY_MASK (2ULL << 52) +#define SPTE_MMIO_MASK (3ULL << 52) + +#ifdef CONFIG_DYNAMIC_PHYSICAL_MASK +#define PT64_BASE_ADDR_MASK (physical_mask & ~(u64)(PAGE_SIZE-1)) +#else +#define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1)) +#endif +#define PT64_LVL_ADDR_MASK(level) \ + (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \ + * PT64_LEVEL_BITS))) - 1)) +#define PT64_LVL_OFFSET_MASK(level) \ + (PT64_BASE_ADDR_MASK & ((1ULL << (PAGE_SHIFT + (((level) - 1) \ + * PT64_LEVEL_BITS))) - 1)) + +#define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | shadow_user_mask \ + | shadow_x_mask | shadow_nx_mask | shadow_me_mask) + +#define ACC_EXEC_MASK 1 +#define ACC_WRITE_MASK PT_WRITABLE_MASK +#define ACC_USER_MASK PT_USER_MASK +#define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK) + +/* The mask for the R/X bits in EPT PTEs */ +#define PT64_EPT_READABLE_MASK 0x1ull +#define PT64_EPT_EXECUTABLE_MASK 0x4ull + +#define PT64_LEVEL_BITS 9 + +#define PT64_LEVEL_SHIFT(level) \ + (PAGE_SHIFT + (level - 1) * PT64_LEVEL_BITS) + +#define PT64_INDEX(address, level)\ + (((address) >> PT64_LEVEL_SHIFT(level)) & ((1 << PT64_LEVEL_BITS) - 1)) +#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level) + + +#define SPTE_HOST_WRITEABLE (1ULL << PT_FIRST_AVAIL_BITS_SHIFT) +#define SPTE_MMU_WRITEABLE (1ULL << (PT_FIRST_AVAIL_BITS_SHIFT + 1)) + +/* + * Due to limited space in PTEs, the MMIO generation is a 19 bit subset of + * the memslots generation and is derived as follows: + * + * Bits 0-8 of the MMIO generation are propagated to spte bits 3-11 + * Bits 9-18 of the MMIO generation are propagated to spte bits 52-61 + * + * The KVM_MEMSLOT_GEN_UPDATE_IN_PROGRESS flag is intentionally not included in + * the MMIO generation number, as doing so would require stealing a bit from + * the "real" generation number and thus effectively halve the maximum number + * of MMIO generations that can be handled before encountering a wrap (which + * requires a full MMU zap). The flag is instead explicitly queried when + * checking for MMIO spte cache hits. + */ +#define MMIO_SPTE_GEN_MASK GENMASK_ULL(17, 0) + +#define MMIO_SPTE_GEN_LOW_START 3 +#define MMIO_SPTE_GEN_LOW_END 11 +#define MMIO_SPTE_GEN_LOW_MASK GENMASK_ULL(MMIO_SPTE_GEN_LOW_END, \ + MMIO_SPTE_GEN_LOW_START) + +#define MMIO_SPTE_GEN_HIGH_START PT64_SECOND_AVAIL_BITS_SHIFT +#define MMIO_SPTE_GEN_HIGH_END 62 +#define MMIO_SPTE_GEN_HIGH_MASK GENMASK_ULL(MMIO_SPTE_GEN_HIGH_END, \ + MMIO_SPTE_GEN_HIGH_START) + +extern u64 __read_mostly shadow_nx_mask; +extern u64 __read_mostly shadow_x_mask; /* mutual exclusive with nx_mask */ +extern u64 __read_mostly shadow_user_mask; +extern u64 __read_mostly shadow_accessed_mask; +extern u64 __read_mostly shadow_dirty_mask; +extern u64 __read_mostly shadow_mmio_value; +extern u64 __read_mostly shadow_mmio_access_mask; +extern u64 __read_mostly shadow_present_mask; +extern u64 __read_mostly shadow_me_mask; + +/* + * SPTEs used by MMUs without A/D bits are marked with SPTE_AD_DISABLED_MASK; + * shadow_acc_track_mask is the set of bits to be cleared in non-accessed + * pages. + */ +extern u64 __read_mostly shadow_acc_track_mask; + +/* + * This mask must be set on all non-zero Non-Present or Reserved SPTEs in order + * to guard against L1TF attacks. + */ +extern u64 __read_mostly shadow_nonpresent_or_rsvd_mask; + +/* + * The mask/shift to use for saving the original R/X bits when marking the PTE + * as not-present for access tracking purposes. We do not save the W bit as the + * PTEs being access tracked also need to be dirty tracked, so the W bit will be + * restored only when a write is attempted to the page. + */ +static const u64 shadow_acc_track_saved_bits_mask = PT64_EPT_READABLE_MASK | + PT64_EPT_EXECUTABLE_MASK; +static const u64 shadow_acc_track_saved_bits_shift = PT64_SECOND_AVAIL_BITS_SHIFT; + +/* + * The number of high-order 1 bits to use in the mask above. + */ +static const u64 shadow_nonpresent_or_rsvd_mask_len = 5; + +/* + * In some cases, we need to preserve the GFN of a non-present or reserved + * SPTE when we usurp the upper five bits of the physical address space to + * defend against L1TF, e.g. for MMIO SPTEs. To preserve the GFN, we'll + * shift bits of the GFN that overlap with shadow_nonpresent_or_rsvd_mask + * left into the reserved bits, i.e. the GFN in the SPTE will be split into + * high and low parts. This mask covers the lower bits of the GFN. + */ +extern u64 __read_mostly shadow_nonpresent_or_rsvd_lower_gfn_mask; + +/* + * The number of non-reserved physical address bits irrespective of features + * that repurpose legal bits, e.g. MKTME. + */ +extern u8 __read_mostly shadow_phys_bits; + +static inline bool is_mmio_spte(u64 spte) +{ + return (spte & SPTE_SPECIAL_MASK) == SPTE_MMIO_MASK; +} + +static inline bool sp_ad_disabled(struct kvm_mmu_page *sp) +{ + return sp->role.ad_disabled; +} + +static inline bool spte_ad_enabled(u64 spte) +{ + MMU_WARN_ON(is_mmio_spte(spte)); + return (spte & SPTE_SPECIAL_MASK) != SPTE_AD_DISABLED_MASK; +} + +static inline bool spte_ad_need_write_protect(u64 spte) +{ + MMU_WARN_ON(is_mmio_spte(spte)); + return (spte & SPTE_SPECIAL_MASK) != SPTE_AD_ENABLED_MASK; +} + +static inline u64 spte_shadow_accessed_mask(u64 spte) +{ + MMU_WARN_ON(is_mmio_spte(spte)); + return spte_ad_enabled(spte) ? shadow_accessed_mask : 0; +} + +static inline u64 spte_shadow_dirty_mask(u64 spte) +{ + MMU_WARN_ON(is_mmio_spte(spte)); + return spte_ad_enabled(spte) ? shadow_dirty_mask : 0; +} + +static inline bool is_access_track_spte(u64 spte) +{ + return !spte_ad_enabled(spte) && (spte & shadow_acc_track_mask) == 0; +} + +static inline int is_shadow_present_pte(u64 pte) +{ + return (pte != 0) && !is_mmio_spte(pte); +} + +static inline int is_large_pte(u64 pte) +{ + return pte & PT_PAGE_SIZE_MASK; +} + +static inline int is_last_spte(u64 pte, int level) +{ + if (level == PG_LEVEL_4K) + return 1; + if (is_large_pte(pte)) + return 1; + return 0; +} + +static inline bool is_executable_pte(u64 spte) +{ + return (spte & (shadow_x_mask | shadow_nx_mask)) == shadow_x_mask; +} + +static inline kvm_pfn_t spte_to_pfn(u64 pte) +{ + return (pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; +} + +static inline bool is_accessed_spte(u64 spte) +{ + u64 accessed_mask = spte_shadow_accessed_mask(spte); + + return accessed_mask ? spte & accessed_mask + : !is_access_track_spte(spte); +} + +static inline bool is_dirty_spte(u64 spte) +{ + u64 dirty_mask = spte_shadow_dirty_mask(spte); + + return dirty_mask ? spte & dirty_mask : spte & PT_WRITABLE_MASK; +} + +static inline bool spte_can_locklessly_be_made_writable(u64 spte) +{ + return (spte & (SPTE_HOST_WRITEABLE | SPTE_MMU_WRITEABLE)) == + (SPTE_HOST_WRITEABLE | SPTE_MMU_WRITEABLE); +} + +static inline u64 get_mmio_spte_generation(u64 spte) +{ + u64 gen; + + gen = (spte & MMIO_SPTE_GEN_LOW_MASK) >> MMIO_SPTE_GEN_LOW_START; + gen |= (spte & MMIO_SPTE_GEN_HIGH_MASK) >> MMIO_SPTE_GEN_HIGH_START; + return gen; +} + +/* Bits which may be returned by set_spte() */ +#define SET_SPTE_WRITE_PROTECTED_PT BIT(0) +#define SET_SPTE_NEED_REMOTE_TLB_FLUSH BIT(1) +#define SET_SPTE_SPURIOUS BIT(2) + +int make_spte(struct kvm_vcpu *vcpu, unsigned int pte_access, int level, + gfn_t gfn, kvm_pfn_t pfn, u64 old_spte, bool speculative, + bool can_unsync, bool host_writable, bool ad_disabled, + u64 *new_spte); +u64 make_nonleaf_spte(u64 *child_pt, bool ad_disabled); +u64 make_mmio_spte(struct kvm_vcpu *vcpu, u64 gfn, unsigned int access); +u64 mark_spte_for_access_track(u64 spte); +u64 kvm_mmu_changed_pte_notifier_make_spte(u64 old_spte, kvm_pfn_t new_pfn); + +void kvm_mmu_reset_all_pte_masks(void); + +#endif diff --git a/arch/x86/kvm/mmu/tdp_iter.c b/arch/x86/kvm/mmu/tdp_iter.c new file mode 100644 index 000000000000..87b7e16911db --- /dev/null +++ b/arch/x86/kvm/mmu/tdp_iter.c @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "mmu_internal.h" +#include "tdp_iter.h" +#include "spte.h" + +/* + * Recalculates the pointer to the SPTE for the current GFN and level and + * reread the SPTE. + */ +static void tdp_iter_refresh_sptep(struct tdp_iter *iter) +{ + iter->sptep = iter->pt_path[iter->level - 1] + + SHADOW_PT_INDEX(iter->gfn << PAGE_SHIFT, iter->level); + iter->old_spte = READ_ONCE(*iter->sptep); +} + +static gfn_t round_gfn_for_level(gfn_t gfn, int level) +{ + return gfn & -KVM_PAGES_PER_HPAGE(level); +} + +/* + * Sets a TDP iterator to walk a pre-order traversal of the paging structure + * rooted at root_pt, starting with the walk to translate goal_gfn. + */ +void tdp_iter_start(struct tdp_iter *iter, u64 *root_pt, int root_level, + int min_level, gfn_t goal_gfn) +{ + WARN_ON(root_level < 1); + WARN_ON(root_level > PT64_ROOT_MAX_LEVEL); + + iter->goal_gfn = goal_gfn; + iter->root_level = root_level; + iter->min_level = min_level; + iter->level = root_level; + iter->pt_path[iter->level - 1] = root_pt; + + iter->gfn = round_gfn_for_level(iter->goal_gfn, iter->level); + tdp_iter_refresh_sptep(iter); + + iter->valid = true; +} + +/* + * Given an SPTE and its level, returns a pointer containing the host virtual + * address of the child page table referenced by the SPTE. Returns null if + * there is no such entry. + */ +u64 *spte_to_child_pt(u64 spte, int level) +{ + /* + * There's no child entry if this entry isn't present or is a + * last-level entry. + */ + if (!is_shadow_present_pte(spte) || is_last_spte(spte, level)) + return NULL; + + return __va(spte_to_pfn(spte) << PAGE_SHIFT); +} + +/* + * Steps down one level in the paging structure towards the goal GFN. Returns + * true if the iterator was able to step down a level, false otherwise. + */ +static bool try_step_down(struct tdp_iter *iter) +{ + u64 *child_pt; + + if (iter->level == iter->min_level) + return false; + + /* + * Reread the SPTE before stepping down to avoid traversing into page + * tables that are no longer linked from this entry. + */ + iter->old_spte = READ_ONCE(*iter->sptep); + + child_pt = spte_to_child_pt(iter->old_spte, iter->level); + if (!child_pt) + return false; + + iter->level--; + iter->pt_path[iter->level - 1] = child_pt; + iter->gfn = round_gfn_for_level(iter->goal_gfn, iter->level); + tdp_iter_refresh_sptep(iter); + + return true; +} + +/* + * Steps to the next entry in the current page table, at the current page table + * level. The next entry could point to a page backing guest memory or another + * page table, or it could be non-present. Returns true if the iterator was + * able to step to the next entry in the page table, false if the iterator was + * already at the end of the current page table. + */ +static bool try_step_side(struct tdp_iter *iter) +{ + /* + * Check if the iterator is already at the end of the current page + * table. + */ + if (SHADOW_PT_INDEX(iter->gfn << PAGE_SHIFT, iter->level) == + (PT64_ENT_PER_PAGE - 1)) + return false; + + iter->gfn += KVM_PAGES_PER_HPAGE(iter->level); + iter->goal_gfn = iter->gfn; + iter->sptep++; + iter->old_spte = READ_ONCE(*iter->sptep); + + return true; +} + +/* + * Tries to traverse back up a level in the paging structure so that the walk + * can continue from the next entry in the parent page table. Returns true on a + * successful step up, false if already in the root page. + */ +static bool try_step_up(struct tdp_iter *iter) +{ + if (iter->level == iter->root_level) + return false; + + iter->level++; + iter->gfn = round_gfn_for_level(iter->gfn, iter->level); + tdp_iter_refresh_sptep(iter); + + return true; +} + +/* + * Step to the next SPTE in a pre-order traversal of the paging structure. + * To get to the next SPTE, the iterator either steps down towards the goal + * GFN, if at a present, non-last-level SPTE, or over to a SPTE mapping a + * highter GFN. + * + * The basic algorithm is as follows: + * 1. If the current SPTE is a non-last-level SPTE, step down into the page + * table it points to. + * 2. If the iterator cannot step down, it will try to step to the next SPTE + * in the current page of the paging structure. + * 3. If the iterator cannot step to the next entry in the current page, it will + * try to step up to the parent paging structure page. In this case, that + * SPTE will have already been visited, and so the iterator must also step + * to the side again. + */ +void tdp_iter_next(struct tdp_iter *iter) +{ + if (try_step_down(iter)) + return; + + do { + if (try_step_side(iter)) + return; + } while (try_step_up(iter)); + iter->valid = false; +} + +/* + * Restart the walk over the paging structure from the root, starting from the + * highest gfn the iterator had previously reached. Assumes that the entire + * paging structure, except the root page, may have been completely torn down + * and rebuilt. + */ +void tdp_iter_refresh_walk(struct tdp_iter *iter) +{ + gfn_t goal_gfn = iter->goal_gfn; + + if (iter->gfn > goal_gfn) + goal_gfn = iter->gfn; + + tdp_iter_start(iter, iter->pt_path[iter->root_level - 1], + iter->root_level, iter->min_level, goal_gfn); +} + +u64 *tdp_iter_root_pt(struct tdp_iter *iter) +{ + return iter->pt_path[iter->root_level - 1]; +} + diff --git a/arch/x86/kvm/mmu/tdp_iter.h b/arch/x86/kvm/mmu/tdp_iter.h new file mode 100644 index 000000000000..47170d0dc98e --- /dev/null +++ b/arch/x86/kvm/mmu/tdp_iter.h @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0 + +#ifndef __KVM_X86_MMU_TDP_ITER_H +#define __KVM_X86_MMU_TDP_ITER_H + +#include <linux/kvm_host.h> + +#include "mmu.h" + +/* + * A TDP iterator performs a pre-order walk over a TDP paging structure. + */ +struct tdp_iter { + /* + * The iterator will traverse the paging structure towards the mapping + * for this GFN. + */ + gfn_t goal_gfn; + /* Pointers to the page tables traversed to reach the current SPTE */ + u64 *pt_path[PT64_ROOT_MAX_LEVEL]; + /* A pointer to the current SPTE */ + u64 *sptep; + /* The lowest GFN mapped by the current SPTE */ + gfn_t gfn; + /* The level of the root page given to the iterator */ + int root_level; + /* The lowest level the iterator should traverse to */ + int min_level; + /* The iterator's current level within the paging structure */ + int level; + /* A snapshot of the value at sptep */ + u64 old_spte; + /* + * Whether the iterator has a valid state. This will be false if the + * iterator walks off the end of the paging structure. + */ + bool valid; +}; + +/* + * Iterates over every SPTE mapping the GFN range [start, end) in a + * preorder traversal. + */ +#define for_each_tdp_pte_min_level(iter, root, root_level, min_level, start, end) \ + for (tdp_iter_start(&iter, root, root_level, min_level, start); \ + iter.valid && iter.gfn < end; \ + tdp_iter_next(&iter)) + +#define for_each_tdp_pte(iter, root, root_level, start, end) \ + for_each_tdp_pte_min_level(iter, root, root_level, PG_LEVEL_4K, start, end) + +u64 *spte_to_child_pt(u64 pte, int level); + +void tdp_iter_start(struct tdp_iter *iter, u64 *root_pt, int root_level, + int min_level, gfn_t goal_gfn); +void tdp_iter_next(struct tdp_iter *iter); +void tdp_iter_refresh_walk(struct tdp_iter *iter); +u64 *tdp_iter_root_pt(struct tdp_iter *iter); + +#endif /* __KVM_X86_MMU_TDP_ITER_H */ diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c new file mode 100644 index 000000000000..27e381c9da6c --- /dev/null +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -0,0 +1,1157 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "mmu.h" +#include "mmu_internal.h" +#include "mmutrace.h" +#include "tdp_iter.h" +#include "tdp_mmu.h" +#include "spte.h" + +#ifdef CONFIG_X86_64 +static bool __read_mostly tdp_mmu_enabled = false; +module_param_named(tdp_mmu, tdp_mmu_enabled, bool, 0644); +#endif + +static bool is_tdp_mmu_enabled(void) +{ +#ifdef CONFIG_X86_64 + return tdp_enabled && READ_ONCE(tdp_mmu_enabled); +#else + return false; +#endif /* CONFIG_X86_64 */ +} + +/* Initializes the TDP MMU for the VM, if enabled. */ +void kvm_mmu_init_tdp_mmu(struct kvm *kvm) +{ + if (!is_tdp_mmu_enabled()) + return; + + /* This should not be changed for the lifetime of the VM. */ + kvm->arch.tdp_mmu_enabled = true; + + INIT_LIST_HEAD(&kvm->arch.tdp_mmu_roots); + INIT_LIST_HEAD(&kvm->arch.tdp_mmu_pages); +} + +void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm) +{ + if (!kvm->arch.tdp_mmu_enabled) + return; + + WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); +} + +#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) +{ + struct kvm_mmu_page *sp; + + sp = to_shadow_page(hpa); + + return sp->tdp_mmu_page && sp->root_count; +} + +static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root, + gfn_t start, gfn_t end, bool can_yield); + +void kvm_tdp_mmu_free_root(struct kvm *kvm, struct kvm_mmu_page *root) +{ + gfn_t max_gfn = 1ULL << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT); + + lockdep_assert_held(&kvm->mmu_lock); + + WARN_ON(root->root_count); + WARN_ON(!root->tdp_mmu_page); + + list_del(&root->link); + + zap_gfn_range(kvm, root, 0, max_gfn, false); + + free_page((unsigned long)root->spt); + kmem_cache_free(mmu_page_header_cache, root); +} + +static union kvm_mmu_page_role page_role_for_level(struct kvm_vcpu *vcpu, + int level) +{ + union kvm_mmu_page_role role; + + role = vcpu->arch.mmu->mmu_role.base; + role.level = level; + role.direct = true; + role.gpte_is_8_bytes = true; + role.access = ACC_ALL; + + return role; +} + +static struct kvm_mmu_page *alloc_tdp_mmu_page(struct kvm_vcpu *vcpu, gfn_t gfn, + int level) +{ + struct kvm_mmu_page *sp; + + sp = kvm_mmu_memory_cache_alloc(&vcpu->arch.mmu_page_header_cache); + sp->spt = kvm_mmu_memory_cache_alloc(&vcpu->arch.mmu_shadow_page_cache); + set_page_private(virt_to_page(sp->spt), (unsigned long)sp); + + sp->role.word = page_role_for_level(vcpu, level).word; + sp->gfn = gfn; + sp->tdp_mmu_page = true; + + return sp; +} + +static struct kvm_mmu_page *get_tdp_mmu_vcpu_root(struct kvm_vcpu *vcpu) +{ + union kvm_mmu_page_role role; + struct kvm *kvm = vcpu->kvm; + struct kvm_mmu_page *root; + + role = page_role_for_level(vcpu, vcpu->arch.mmu->shadow_root_level); + + spin_lock(&kvm->mmu_lock); + + /* Check for an existing root before allocating a new one. */ + for_each_tdp_mmu_root(kvm, root) { + if (root->role.word == role.word) { + kvm_mmu_get_root(kvm, root); + spin_unlock(&kvm->mmu_lock); + return root; + } + } + + root = alloc_tdp_mmu_page(vcpu, 0, vcpu->arch.mmu->shadow_root_level); + root->root_count = 1; + + list_add(&root->link, &kvm->arch.tdp_mmu_roots); + + spin_unlock(&kvm->mmu_lock); + + return root; +} + +hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu) +{ + struct kvm_mmu_page *root; + + root = get_tdp_mmu_vcpu_root(vcpu); + if (!root) + return INVALID_PAGE; + + return __pa(root->spt); +} + +static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn, + u64 old_spte, u64 new_spte, int level); + +static int kvm_mmu_page_as_id(struct kvm_mmu_page *sp) +{ + return sp->role.smm ? 1 : 0; +} + +static void handle_changed_spte_acc_track(u64 old_spte, u64 new_spte, int level) +{ + bool pfn_changed = spte_to_pfn(old_spte) != spte_to_pfn(new_spte); + + if (!is_shadow_present_pte(old_spte) || !is_last_spte(old_spte, level)) + return; + + if (is_accessed_spte(old_spte) && + (!is_accessed_spte(new_spte) || pfn_changed)) + kvm_set_pfn_accessed(spte_to_pfn(old_spte)); +} + +static void handle_changed_spte_dirty_log(struct kvm *kvm, int as_id, gfn_t gfn, + u64 old_spte, u64 new_spte, int level) +{ + bool pfn_changed; + struct kvm_memory_slot *slot; + + if (level > PG_LEVEL_4K) + return; + + pfn_changed = spte_to_pfn(old_spte) != spte_to_pfn(new_spte); + + 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); + } +} + +/** + * handle_changed_spte - handle bookkeeping associated with an SPTE change + * @kvm: kvm instance + * @as_id: the address space of the paging structure the SPTE was a part of + * @gfn: the base GFN that was mapped by the SPTE + * @old_spte: The value of the SPTE before the change + * @new_spte: The value of the SPTE after the change + * @level: the level of the PT the SPTE is part of in the paging structure + * + * Handle bookkeeping that might result from the modification of a SPTE. + * This function must be called for all TDP SPTE modifications. + */ +static void __handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn, + u64 old_spte, u64 new_spte, int level) +{ + bool was_present = is_shadow_present_pte(old_spte); + bool is_present = is_shadow_present_pte(new_spte); + bool was_leaf = was_present && is_last_spte(old_spte, level); + bool is_leaf = is_present && is_last_spte(new_spte, level); + bool pfn_changed = spte_to_pfn(old_spte) != spte_to_pfn(new_spte); + u64 *pt; + struct kvm_mmu_page *sp; + u64 old_child_spte; + int i; + + WARN_ON(level > PT64_ROOT_MAX_LEVEL); + WARN_ON(level < PG_LEVEL_4K); + WARN_ON(gfn & (KVM_PAGES_PER_HPAGE(level) - 1)); + + /* + * If this warning were to trigger it would indicate that there was a + * missing MMU notifier or a race with some notifier handler. + * A present, leaf SPTE should never be directly replaced with another + * present leaf SPTE pointing to a differnt PFN. A notifier handler + * should be zapping the SPTE before the main MM's page table is + * changed, or the SPTE should be zeroed, and the TLBs flushed by the + * thread before replacement. + */ + if (was_leaf && is_leaf && pfn_changed) { + pr_err("Invalid SPTE change: cannot replace a present leaf\n" + "SPTE with another present leaf SPTE mapping a\n" + "different PFN!\n" + "as_id: %d gfn: %llx old_spte: %llx new_spte: %llx level: %d", + as_id, gfn, old_spte, new_spte, level); + + /* + * Crash the host to prevent error propagation and guest data + * courruption. + */ + BUG(); + } + + if (old_spte == new_spte) + return; + + /* + * The only times a SPTE should be changed from a non-present to + * non-present state is when an MMIO entry is installed/modified/ + * removed. In that case, there is nothing to do here. + */ + if (!was_present && !is_present) { + /* + * If this change does not involve a MMIO SPTE, it is + * unexpected. Log the change, though it should not impact the + * guest since both the former and current SPTEs are nonpresent. + */ + if (WARN_ON(!is_mmio_spte(old_spte) && !is_mmio_spte(new_spte))) + pr_err("Unexpected SPTE change! Nonpresent SPTEs\n" + "should not be replaced with another,\n" + "different nonpresent SPTE, unless one or both\n" + "are MMIO SPTEs.\n" + "as_id: %d gfn: %llx old_spte: %llx new_spte: %llx level: %d", + as_id, gfn, old_spte, new_spte, level); + return; + } + + + if (was_leaf && is_dirty_spte(old_spte) && + (!is_dirty_spte(new_spte) || pfn_changed)) + kvm_set_pfn_dirty(spte_to_pfn(old_spte)); + + /* + * Recursively handle child PTs if the change removed a subtree from + * the paging structure. + */ + if (was_present && !was_leaf && (pfn_changed || !is_present)) { + pt = spte_to_child_pt(old_spte, level); + sp = sptep_to_sp(pt); + + list_del(&sp->link); + + if (sp->lpage_disallowed) + unaccount_huge_nx_page(kvm, sp); + + for (i = 0; i < PT64_ENT_PER_PAGE; i++) { + old_child_spte = READ_ONCE(*(pt + i)); + WRITE_ONCE(*(pt + i), 0); + handle_changed_spte(kvm, as_id, + gfn + (i * KVM_PAGES_PER_HPAGE(level - 1)), + old_child_spte, 0, level - 1); + } + + kvm_flush_remote_tlbs_with_address(kvm, gfn, + KVM_PAGES_PER_HPAGE(level)); + + free_page((unsigned long)pt); + kmem_cache_free(mmu_page_header_cache, sp); + } +} + +static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn, + u64 old_spte, u64 new_spte, int level) +{ + __handle_changed_spte(kvm, as_id, gfn, old_spte, new_spte, level); + handle_changed_spte_acc_track(old_spte, new_spte, level); + handle_changed_spte_dirty_log(kvm, as_id, gfn, old_spte, + new_spte, level); +} + +static inline void __tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter, + u64 new_spte, bool record_acc_track, + bool record_dirty_log) +{ + u64 *root_pt = tdp_iter_root_pt(iter); + struct kvm_mmu_page *root = sptep_to_sp(root_pt); + int as_id = kvm_mmu_page_as_id(root); + + WRITE_ONCE(*iter->sptep, new_spte); + + __handle_changed_spte(kvm, as_id, iter->gfn, iter->old_spte, new_spte, + iter->level); + if (record_acc_track) + handle_changed_spte_acc_track(iter->old_spte, new_spte, + iter->level); + if (record_dirty_log) + handle_changed_spte_dirty_log(kvm, as_id, iter->gfn, + iter->old_spte, new_spte, + iter->level); +} + +static inline void tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter, + u64 new_spte) +{ + __tdp_mmu_set_spte(kvm, iter, new_spte, true, true); +} + +static inline void tdp_mmu_set_spte_no_acc_track(struct kvm *kvm, + struct tdp_iter *iter, + u64 new_spte) +{ + __tdp_mmu_set_spte(kvm, iter, new_spte, false, true); +} + +static inline void tdp_mmu_set_spte_no_dirty_log(struct kvm *kvm, + struct tdp_iter *iter, + u64 new_spte) +{ + __tdp_mmu_set_spte(kvm, iter, new_spte, true, false); +} + +#define tdp_root_for_each_pte(_iter, _root, _start, _end) \ + for_each_tdp_pte(_iter, _root->spt, _root->role.level, _start, _end) + +#define tdp_root_for_each_leaf_pte(_iter, _root, _start, _end) \ + tdp_root_for_each_pte(_iter, _root, _start, _end) \ + if (!is_shadow_present_pte(_iter.old_spte) || \ + !is_last_spte(_iter.old_spte, _iter.level)) \ + continue; \ + else + +#define tdp_mmu_for_each_pte(_iter, _mmu, _start, _end) \ + for_each_tdp_pte(_iter, __va(_mmu->root_hpa), \ + _mmu->shadow_root_level, _start, _end) + +/* + * Flush the TLB if the process should drop kvm->mmu_lock. + * Return whether the caller still needs to flush the tlb. + */ +static bool tdp_mmu_iter_flush_cond_resched(struct kvm *kvm, struct tdp_iter *iter) +{ + if (need_resched() || spin_needbreak(&kvm->mmu_lock)) { + kvm_flush_remote_tlbs(kvm); + cond_resched_lock(&kvm->mmu_lock); + tdp_iter_refresh_walk(iter); + return false; + } else { + return true; + } +} + +static void tdp_mmu_iter_cond_resched(struct kvm *kvm, struct tdp_iter *iter) +{ + if (need_resched() || spin_needbreak(&kvm->mmu_lock)) { + cond_resched_lock(&kvm->mmu_lock); + tdp_iter_refresh_walk(iter); + } +} + +/* + * Tears down the mappings for the range of gfns, [start, end), and frees the + * non-root pages mapping GFNs strictly within that range. Returns true if + * SPTEs have been cleared and a TLB flush is needed before releasing the + * MMU lock. + * If can_yield is true, will release the MMU lock and reschedule if the + * scheduler needs the CPU or there is contention on the MMU lock. If this + * function cannot yield, it will not release the MMU lock or reschedule and + * the caller must ensure it does not supply too large a GFN range, or the + * operation can cause a soft lockup. + */ +static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root, + gfn_t start, gfn_t end, bool can_yield) +{ + struct tdp_iter iter; + bool flush_needed = false; + + tdp_root_for_each_pte(iter, root, start, end) { + if (!is_shadow_present_pte(iter.old_spte)) + continue; + + /* + * If this is a non-last-level SPTE that covers a larger range + * than should be zapped, continue, and zap the mappings at a + * lower level. + */ + if ((iter.gfn < start || + iter.gfn + KVM_PAGES_PER_HPAGE(iter.level) > end) && + !is_last_spte(iter.old_spte, iter.level)) + continue; + + tdp_mmu_set_spte(kvm, &iter, 0); + + if (can_yield) + flush_needed = tdp_mmu_iter_flush_cond_resched(kvm, &iter); + else + flush_needed = true; + } + return flush_needed; +} + +/* + * Tears down the mappings for the range of gfns, [start, end), and frees the + * non-root pages mapping GFNs strictly within that range. Returns true if + * SPTEs have been cleared and a TLB flush is needed before releasing the + * MMU lock. + */ +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); + + flush |= zap_gfn_range(kvm, root, start, end, true); + + kvm_mmu_put_root(kvm, root); + } + + return flush; +} + +void kvm_tdp_mmu_zap_all(struct kvm *kvm) +{ + gfn_t max_gfn = 1ULL << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT); + bool flush; + + flush = kvm_tdp_mmu_zap_gfn_range(kvm, 0, max_gfn); + if (flush) + kvm_flush_remote_tlbs(kvm); +} + +/* + * Installs a last-level SPTE to handle a TDP page fault. + * (NPT/EPT violation/misconfiguration) + */ +static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu, int write, + int map_writable, + struct tdp_iter *iter, + kvm_pfn_t pfn, bool prefault) +{ + u64 new_spte; + int ret = 0; + int make_spte_ret = 0; + + 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 + 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); + + if (new_spte == iter->old_spte) + ret = RET_PF_SPURIOUS; + else + tdp_mmu_set_spte(vcpu->kvm, iter, new_spte); + + /* + * If the page fault was caused by a write but the page is write + * protected, emulation is needed. If the emulation was skipped, + * the vCPU would have the same fault again. + */ + if (make_spte_ret & SET_SPTE_WRITE_PROTECTED_PT) { + if (write) + ret = RET_PF_EMULATE; + kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); + } + + /* If a MMIO SPTE is installed, the MMIO will need to be emulated. */ + if (unlikely(is_mmio_spte(new_spte))) + ret = RET_PF_EMULATE; + + trace_kvm_mmu_set_spte(iter->level, iter->gfn, iter->sptep); + if (!prefault) + vcpu->stat.pf_fixed++; + + return ret; +} + +/* + * Handle a TDP page fault (NPT/EPT violation/misconfiguration) by installing + * page tables and SPTEs to translate the faulting guest physical address. + */ +int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code, + int map_writable, int max_level, kvm_pfn_t pfn, + bool prefault) +{ + bool nx_huge_page_workaround_enabled = is_nx_huge_page_enabled(); + bool write = error_code & PFERR_WRITE_MASK; + bool exec = error_code & PFERR_FETCH_MASK; + bool huge_page_disallowed = exec && nx_huge_page_workaround_enabled; + struct kvm_mmu *mmu = vcpu->arch.mmu; + struct tdp_iter iter; + struct kvm_mmu_page *sp; + u64 *child_pt; + u64 new_spte; + int ret; + gfn_t gfn = gpa >> PAGE_SHIFT; + int level; + int req_level; + + if (WARN_ON(!VALID_PAGE(vcpu->arch.mmu->root_hpa))) + return RET_PF_RETRY; + if (WARN_ON(!is_tdp_mmu_root(vcpu->kvm, vcpu->arch.mmu->root_hpa))) + return RET_PF_RETRY; + + level = kvm_mmu_hugepage_adjust(vcpu, gfn, max_level, &pfn, + huge_page_disallowed, &req_level); + + trace_kvm_mmu_spte_requested(gpa, level, pfn); + tdp_mmu_for_each_pte(iter, mmu, gfn, gfn + 1) { + if (nx_huge_page_workaround_enabled) + disallowed_hugepage_adjust(iter.old_spte, gfn, + iter.level, &pfn, &level); + + if (iter.level == level) + break; + + /* + * If there is an SPTE mapping a large page at a higher level + * than the target, that SPTE must be cleared and replaced + * with a non-leaf SPTE. + */ + if (is_shadow_present_pte(iter.old_spte) && + is_large_pte(iter.old_spte)) { + tdp_mmu_set_spte(vcpu->kvm, &iter, 0); + + kvm_flush_remote_tlbs_with_address(vcpu->kvm, iter.gfn, + KVM_PAGES_PER_HPAGE(iter.level)); + + /* + * The iter must explicitly re-read the spte here + * because the new value informs the !present + * path below. + */ + iter.old_spte = READ_ONCE(*iter.sptep); + } + + if (!is_shadow_present_pte(iter.old_spte)) { + sp = alloc_tdp_mmu_page(vcpu, iter.gfn, iter.level); + list_add(&sp->link, &vcpu->kvm->arch.tdp_mmu_pages); + child_pt = sp->spt; + clear_page(child_pt); + new_spte = make_nonleaf_spte(child_pt, + !shadow_accessed_mask); + + trace_kvm_mmu_get_page(sp, true); + if (huge_page_disallowed && req_level >= iter.level) + account_huge_nx_page(vcpu->kvm, sp); + + tdp_mmu_set_spte(vcpu->kvm, &iter, new_spte); + } + } + + if (WARN_ON(iter.level != level)) + return RET_PF_RETRY; + + ret = tdp_mmu_map_handle_target_level(vcpu, write, map_writable, &iter, + pfn, prefault); + + return ret; +} + +static int kvm_tdp_mmu_handle_hva_range(struct kvm *kvm, unsigned long start, + unsigned long end, unsigned long data, + int (*handler)(struct kvm *kvm, struct kvm_memory_slot *slot, + struct kvm_mmu_page *root, gfn_t start, + gfn_t end, unsigned long data)) +{ + struct kvm_memslots *slots; + struct kvm_memory_slot *memslot; + struct kvm_mmu_page *root; + 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); + + as_id = kvm_mmu_page_as_id(root); + slots = __kvm_memslots(kvm, as_id); + kvm_for_each_memslot(memslot, slots) { + unsigned long hva_start, hva_end; + gfn_t gfn_start, gfn_end; + + hva_start = max(start, memslot->userspace_addr); + hva_end = min(end, memslot->userspace_addr + + (memslot->npages << PAGE_SHIFT)); + if (hva_start >= hva_end) + continue; + /* + * {gfn(page) | page intersects with [hva_start, hva_end)} = + * {gfn_start, gfn_start+1, ..., gfn_end-1}. + */ + gfn_start = hva_to_gfn_memslot(hva_start, memslot); + gfn_end = hva_to_gfn_memslot(hva_end + PAGE_SIZE - 1, memslot); + + ret |= handler(kvm, memslot, root, gfn_start, + gfn_end, data); + } + + kvm_mmu_put_root(kvm, root); + } + + return ret; +} + +static int zap_gfn_range_hva_wrapper(struct kvm *kvm, + struct kvm_memory_slot *slot, + struct kvm_mmu_page *root, gfn_t start, + gfn_t end, unsigned long unused) +{ + return zap_gfn_range(kvm, root, start, end, false); +} + +int kvm_tdp_mmu_zap_hva_range(struct kvm *kvm, unsigned long start, + unsigned long end) +{ + return kvm_tdp_mmu_handle_hva_range(kvm, start, end, 0, + zap_gfn_range_hva_wrapper); +} + +/* + * Mark the SPTEs range of GFNs [start, end) unaccessed and return non-zero + * if any of the GFNs in the range have been accessed. + */ +static int age_gfn_range(struct kvm *kvm, struct kvm_memory_slot *slot, + struct kvm_mmu_page *root, gfn_t start, gfn_t end, + unsigned long unused) +{ + struct tdp_iter iter; + int young = 0; + u64 new_spte = 0; + + tdp_root_for_each_leaf_pte(iter, root, start, end) { + /* + * If we have a non-accessed entry we don't need to change the + * pte. + */ + if (!is_accessed_spte(iter.old_spte)) + continue; + + new_spte = iter.old_spte; + + if (spte_ad_enabled(new_spte)) { + clear_bit((ffs(shadow_accessed_mask) - 1), + (unsigned long *)&new_spte); + } else { + /* + * Capture the dirty status of the page, so that it doesn't get + * lost when the SPTE is marked for access tracking. + */ + if (is_writable_pte(new_spte)) + kvm_set_pfn_dirty(spte_to_pfn(new_spte)); + + new_spte = mark_spte_for_access_track(new_spte); + } + new_spte &= ~shadow_dirty_mask; + + tdp_mmu_set_spte_no_acc_track(kvm, &iter, new_spte); + young = 1; + } + + return young; +} + +int kvm_tdp_mmu_age_hva_range(struct kvm *kvm, unsigned long start, + unsigned long end) +{ + return kvm_tdp_mmu_handle_hva_range(kvm, start, end, 0, + age_gfn_range); +} + +static int test_age_gfn(struct kvm *kvm, struct kvm_memory_slot *slot, + struct kvm_mmu_page *root, gfn_t gfn, gfn_t unused, + unsigned long unused2) +{ + struct tdp_iter iter; + + tdp_root_for_each_leaf_pte(iter, root, gfn, gfn + 1) + if (is_accessed_spte(iter.old_spte)) + return 1; + + return 0; +} + +int kvm_tdp_mmu_test_age_hva(struct kvm *kvm, unsigned long hva) +{ + return kvm_tdp_mmu_handle_hva_range(kvm, hva, hva + 1, 0, + test_age_gfn); +} + +/* + * Handle the changed_pte MMU notifier for the TDP MMU. + * data is a pointer to the new pte_t mapping the HVA specified by the MMU + * notifier. + * Returns non-zero if a flush is needed before releasing the MMU lock. + */ +static int set_tdp_spte(struct kvm *kvm, struct kvm_memory_slot *slot, + struct kvm_mmu_page *root, gfn_t gfn, gfn_t unused, + unsigned long data) +{ + struct tdp_iter iter; + pte_t *ptep = (pte_t *)data; + kvm_pfn_t new_pfn; + u64 new_spte; + int need_flush = 0; + + WARN_ON(pte_huge(*ptep)); + + new_pfn = pte_pfn(*ptep); + + tdp_root_for_each_pte(iter, root, gfn, gfn + 1) { + if (iter.level != PG_LEVEL_4K) + continue; + + if (!is_shadow_present_pte(iter.old_spte)) + break; + + tdp_mmu_set_spte(kvm, &iter, 0); + + kvm_flush_remote_tlbs_with_address(kvm, iter.gfn, 1); + + if (!pte_write(*ptep)) { + new_spte = kvm_mmu_changed_pte_notifier_make_spte( + iter.old_spte, new_pfn); + + tdp_mmu_set_spte(kvm, &iter, new_spte); + } + + need_flush = 1; + } + + if (need_flush) + kvm_flush_remote_tlbs_with_address(kvm, gfn, 1); + + return 0; +} + +int kvm_tdp_mmu_set_spte_hva(struct kvm *kvm, unsigned long address, + pte_t *host_ptep) +{ + return kvm_tdp_mmu_handle_hva_range(kvm, address, address + 1, + (unsigned long)host_ptep, + set_tdp_spte); +} + +/* + * Remove write access from all the SPTEs mapping GFNs [start, end). If + * skip_4k is set, SPTEs that map 4k pages, will not be write-protected. + * Returns true if an SPTE has been changed and the TLBs need to be flushed. + */ +static bool wrprot_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root, + gfn_t start, gfn_t end, int min_level) +{ + struct tdp_iter iter; + u64 new_spte; + bool spte_set = false; + + BUG_ON(min_level > KVM_MAX_HUGEPAGE_LEVEL); + + for_each_tdp_pte_min_level(iter, root->spt, root->role.level, + min_level, start, end) { + if (!is_shadow_present_pte(iter.old_spte) || + !is_last_spte(iter.old_spte, iter.level)) + continue; + + new_spte = iter.old_spte & ~PT_WRITABLE_MASK; + + tdp_mmu_set_spte_no_dirty_log(kvm, &iter, new_spte); + spte_set = true; + + tdp_mmu_iter_cond_resched(kvm, &iter); + } + return spte_set; +} + +/* + * Remove write access from all the SPTEs mapping GFNs in the memslot. Will + * only affect leaf SPTEs down to min_level. + * Returns true if an SPTE has been changed and the TLBs need to be flushed. + */ +bool kvm_tdp_mmu_wrprot_slot(struct kvm *kvm, struct kvm_memory_slot *slot, + int min_level) +{ + struct kvm_mmu_page *root; + int root_as_id; + bool spte_set = false; + + for_each_tdp_mmu_root(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; +} + +/* + * Clear the dirty status of all the SPTEs mapping GFNs in the memslot. If + * AD bits are enabled, this will involve clearing the dirty bit on each SPTE. + * If AD bits are not enabled, this will require clearing the writable bit on + * each SPTE. Returns true if an SPTE has been changed and the TLBs need to + * be flushed. + */ +static bool clear_dirty_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root, + gfn_t start, gfn_t end) +{ + struct tdp_iter iter; + u64 new_spte; + bool spte_set = false; + + tdp_root_for_each_leaf_pte(iter, root, start, end) { + if (spte_ad_need_write_protect(iter.old_spte)) { + if (is_writable_pte(iter.old_spte)) + new_spte = iter.old_spte & ~PT_WRITABLE_MASK; + else + continue; + } else { + if (iter.old_spte & shadow_dirty_mask) + new_spte = iter.old_spte & ~shadow_dirty_mask; + else + continue; + } + + tdp_mmu_set_spte_no_dirty_log(kvm, &iter, new_spte); + spte_set = true; + + tdp_mmu_iter_cond_resched(kvm, &iter); + } + return spte_set; +} + +/* + * Clear the dirty status of all the SPTEs mapping GFNs in the memslot. If + * AD bits are enabled, this will involve clearing the dirty bit on each SPTE. + * If AD bits are not enabled, this will require clearing the writable bit on + * each SPTE. Returns true if an SPTE has been changed and the TLBs need to + * be flushed. + */ +bool kvm_tdp_mmu_clear_dirty_slot(struct kvm *kvm, struct kvm_memory_slot *slot) +{ + struct kvm_mmu_page *root; + int root_as_id; + bool spte_set = false; + + for_each_tdp_mmu_root(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; +} + +/* + * Clears the dirty status of all the 4k SPTEs mapping GFNs for which a bit is + * set in mask, starting at gfn. The given memslot is expected to contain all + * the GFNs represented by set bits in the mask. If AD bits are enabled, + * clearing the dirty status will involve clearing the dirty bit on each SPTE + * or, if AD bits are not enabled, clearing the writable bit on each SPTE. + */ +static void clear_dirty_pt_masked(struct kvm *kvm, struct kvm_mmu_page *root, + gfn_t gfn, unsigned long mask, bool wrprot) +{ + struct tdp_iter iter; + u64 new_spte; + + tdp_root_for_each_leaf_pte(iter, root, gfn + __ffs(mask), + gfn + BITS_PER_LONG) { + if (!mask) + break; + + if (iter.level > PG_LEVEL_4K || + !(mask & (1UL << (iter.gfn - gfn)))) + continue; + + if (wrprot || spte_ad_need_write_protect(iter.old_spte)) { + if (is_writable_pte(iter.old_spte)) + new_spte = iter.old_spte & ~PT_WRITABLE_MASK; + else + continue; + } else { + if (iter.old_spte & shadow_dirty_mask) + new_spte = iter.old_spte & ~shadow_dirty_mask; + else + continue; + } + + tdp_mmu_set_spte_no_dirty_log(kvm, &iter, new_spte); + + mask &= ~(1UL << (iter.gfn - gfn)); + } +} + +/* + * Clears the dirty status of all the 4k SPTEs mapping GFNs for which a bit is + * set in mask, starting at gfn. The given memslot is expected to contain all + * the GFNs represented by set bits in the mask. If AD bits are enabled, + * clearing the dirty status will involve clearing the dirty bit on each SPTE + * or, if AD bits are not enabled, clearing the writable bit on each SPTE. + */ +void kvm_tdp_mmu_clear_dirty_pt_masked(struct kvm *kvm, + struct kvm_memory_slot *slot, + gfn_t gfn, unsigned long mask, + bool wrprot) +{ + struct kvm_mmu_page *root; + int root_as_id; + + lockdep_assert_held(&kvm->mmu_lock); + for_each_tdp_mmu_root(kvm, root) { + root_as_id = kvm_mmu_page_as_id(root); + if (root_as_id != slot->as_id) + continue; + + clear_dirty_pt_masked(kvm, root, gfn, mask, wrprot); + } +} + +/* + * Set the dirty status of all the SPTEs mapping GFNs in the memslot. This is + * only used for PML, and so will involve setting the dirty bit on each SPTE. + * Returns true if an SPTE has been changed and the TLBs need to be flushed. + */ +static bool set_dirty_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root, + gfn_t start, gfn_t end) +{ + struct tdp_iter iter; + u64 new_spte; + bool spte_set = false; + + tdp_root_for_each_pte(iter, root, start, end) { + if (!is_shadow_present_pte(iter.old_spte)) + continue; + + new_spte = iter.old_spte | shadow_dirty_mask; + + tdp_mmu_set_spte(kvm, &iter, new_spte); + spte_set = true; + + tdp_mmu_iter_cond_resched(kvm, &iter); + } + + return spte_set; +} + +/* + * Set the dirty status of all the SPTEs mapping GFNs in the memslot. This is + * only used for PML, and so will involve setting the dirty bit on each SPTE. + * Returns true if an SPTE has been changed and the TLBs need to be flushed. + */ +bool kvm_tdp_mmu_slot_set_dirty(struct kvm *kvm, struct kvm_memory_slot *slot) +{ + struct kvm_mmu_page *root; + int root_as_id; + bool spte_set = false; + + for_each_tdp_mmu_root(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; +} + +/* + * Clear non-leaf entries (and free associated page tables) which could + * be replaced by large mappings, for GFNs within the slot. + */ +static void zap_collapsible_spte_range(struct kvm *kvm, + struct kvm_mmu_page *root, + gfn_t start, gfn_t end) +{ + struct tdp_iter iter; + kvm_pfn_t pfn; + bool spte_set = false; + + tdp_root_for_each_pte(iter, root, start, end) { + if (!is_shadow_present_pte(iter.old_spte) || + is_last_spte(iter.old_spte, iter.level)) + continue; + + pfn = spte_to_pfn(iter.old_spte); + if (kvm_is_reserved_pfn(pfn) || + !PageTransCompoundMap(pfn_to_page(pfn))) + continue; + + tdp_mmu_set_spte(kvm, &iter, 0); + + spte_set = tdp_mmu_iter_flush_cond_resched(kvm, &iter); + } + + if (spte_set) + kvm_flush_remote_tlbs(kvm); +} + +/* + * Clear non-leaf entries (and free associated page tables) which could + * be replaced by large mappings, for GFNs within the slot. + */ +void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, + const struct kvm_memory_slot *slot) +{ + struct kvm_mmu_page *root; + int root_as_id; + + for_each_tdp_mmu_root(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); + } +} + +/* + * Removes write access on the last level SPTE mapping this GFN and unsets the + * SPTE_MMU_WRITABLE bit to ensure future writes continue to be intercepted. + * Returns true if an SPTE was set and a TLB flush is needed. + */ +static bool write_protect_gfn(struct kvm *kvm, struct kvm_mmu_page *root, + gfn_t gfn) +{ + struct tdp_iter iter; + u64 new_spte; + bool spte_set = false; + + tdp_root_for_each_leaf_pte(iter, root, gfn, gfn + 1) { + if (!is_writable_pte(iter.old_spte)) + break; + + new_spte = iter.old_spte & + ~(PT_WRITABLE_MASK | SPTE_MMU_WRITEABLE); + + tdp_mmu_set_spte(kvm, &iter, new_spte); + spte_set = true; + } + + return spte_set; +} + +/* + * Removes write access on the last level SPTE mapping this GFN and unsets the + * SPTE_MMU_WRITABLE bit to ensure future writes continue to be intercepted. + * Returns true if an SPTE was set and a TLB flush is needed. + */ +bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, + struct kvm_memory_slot *slot, gfn_t gfn) +{ + struct kvm_mmu_page *root; + int root_as_id; + bool spte_set = false; + + lockdep_assert_held(&kvm->mmu_lock); + for_each_tdp_mmu_root(kvm, root) { + root_as_id = kvm_mmu_page_as_id(root); + if (root_as_id != slot->as_id) + continue; + + spte_set |= write_protect_gfn(kvm, root, gfn); + } + return spte_set; +} + +/* + * 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) +{ + 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; + + tdp_mmu_for_each_pte(iter, mmu, gfn, gfn + 1) { + leaf = iter.level; + sptes[leaf - 1] = iter.old_spte; + } + + return leaf; +} diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h new file mode 100644 index 000000000000..556e065503f6 --- /dev/null +++ b/arch/x86/kvm/mmu/tdp_mmu.h @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0 + +#ifndef __KVM_X86_MMU_TDP_MMU_H +#define __KVM_X86_MMU_TDP_MMU_H + +#include <linux/kvm_host.h> + +void kvm_mmu_init_tdp_mmu(struct kvm *kvm); +void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm); + +bool is_tdp_mmu_root(struct kvm *kvm, hpa_t root); +hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu); +void kvm_tdp_mmu_free_root(struct kvm *kvm, struct kvm_mmu_page *root); + +bool kvm_tdp_mmu_zap_gfn_range(struct kvm *kvm, gfn_t start, gfn_t end); +void kvm_tdp_mmu_zap_all(struct kvm *kvm); + +int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code, + int map_writable, int max_level, kvm_pfn_t pfn, + bool prefault); + +int kvm_tdp_mmu_zap_hva_range(struct kvm *kvm, unsigned long start, + unsigned long end); + +int kvm_tdp_mmu_age_hva_range(struct kvm *kvm, unsigned long start, + unsigned long end); +int kvm_tdp_mmu_test_age_hva(struct kvm *kvm, unsigned long hva); + +int kvm_tdp_mmu_set_spte_hva(struct kvm *kvm, unsigned long address, + pte_t *host_ptep); + +bool kvm_tdp_mmu_wrprot_slot(struct kvm *kvm, struct kvm_memory_slot *slot, + int min_level); +bool kvm_tdp_mmu_clear_dirty_slot(struct kvm *kvm, + struct kvm_memory_slot *slot); +void kvm_tdp_mmu_clear_dirty_pt_masked(struct kvm *kvm, + struct kvm_memory_slot *slot, + gfn_t gfn, unsigned long mask, + bool wrprot); +bool kvm_tdp_mmu_slot_set_dirty(struct kvm *kvm, struct kvm_memory_slot *slot); +void kvm_tdp_mmu_zap_collapsible_sptes(struct kvm *kvm, + const struct kvm_memory_slot *slot); + +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); +#endif /* __KVM_X86_MMU_TDP_MMU_H */ diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c index ac830cd50830..8c550999ace0 100644 --- a/arch/x86/kvm/svm/avic.c +++ b/arch/x86/kvm/svm/avic.c @@ -153,20 +153,18 @@ int avic_vm_init(struct kvm *kvm) return 0; /* Allocating physical APIC ID table (4KB) */ - p_page = alloc_page(GFP_KERNEL_ACCOUNT); + p_page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); if (!p_page) goto free_avic; kvm_svm->avic_physical_id_table_page = p_page; - clear_page(page_address(p_page)); /* Allocating logical APIC ID table (4KB) */ - l_page = alloc_page(GFP_KERNEL_ACCOUNT); + l_page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); if (!l_page) goto free_avic; kvm_svm->avic_logical_id_table_page = l_page; - clear_page(page_address(l_page)); spin_lock_irqsave(&svm_vm_data_hash_lock, flags); again: @@ -868,6 +866,7 @@ int svm_update_pi_irte(struct kvm *kvm, unsigned int host_irq, * - Tell IOMMU to use legacy mode for this interrupt. * - Retrieve ga_tag of prior interrupt remapping data. */ + pi.prev_ga_tag = 0; pi.is_guest_mode = false; ret = irq_set_vcpu_affinity(host_irq, &pi); diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index fb68467e6049..9e4c226dbf7d 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -98,6 +98,7 @@ static void nested_svm_uninit_mmu_context(struct kvm_vcpu *vcpu) void recalc_intercepts(struct vcpu_svm *svm) { struct vmcb_control_area *c, *h, *g; + unsigned int i; vmcb_mark_dirty(svm->vmcb, VMCB_INTERCEPTS); @@ -108,42 +109,37 @@ void recalc_intercepts(struct vcpu_svm *svm) h = &svm->nested.hsave->control; g = &svm->nested.ctl; - svm->nested.host_intercept_exceptions = h->intercept_exceptions; - - c->intercept_cr = h->intercept_cr; - c->intercept_dr = h->intercept_dr; - c->intercept_exceptions = h->intercept_exceptions; - c->intercept = h->intercept; + for (i = 0; i < MAX_INTERCEPT; i++) + c->intercepts[i] = h->intercepts[i]; if (g->int_ctl & V_INTR_MASKING_MASK) { /* We only want the cr8 intercept bits of L1 */ - c->intercept_cr &= ~(1U << INTERCEPT_CR8_READ); - c->intercept_cr &= ~(1U << INTERCEPT_CR8_WRITE); + vmcb_clr_intercept(c, INTERCEPT_CR8_READ); + vmcb_clr_intercept(c, INTERCEPT_CR8_WRITE); /* * Once running L2 with HF_VINTR_MASK, EFLAGS.IF does not * affect any interrupt we may want to inject; therefore, * interrupt window vmexits are irrelevant to L0. */ - c->intercept &= ~(1ULL << INTERCEPT_VINTR); + vmcb_clr_intercept(c, INTERCEPT_VINTR); } /* We don't want to see VMMCALLs from a nested guest */ - c->intercept &= ~(1ULL << INTERCEPT_VMMCALL); + vmcb_clr_intercept(c, INTERCEPT_VMMCALL); - c->intercept_cr |= g->intercept_cr; - c->intercept_dr |= g->intercept_dr; - c->intercept_exceptions |= g->intercept_exceptions; - c->intercept |= g->intercept; + for (i = 0; i < MAX_INTERCEPT; i++) + c->intercepts[i] |= g->intercepts[i]; } static void copy_vmcb_control_area(struct vmcb_control_area *dst, struct vmcb_control_area *from) { - dst->intercept_cr = from->intercept_cr; - dst->intercept_dr = from->intercept_dr; - dst->intercept_exceptions = from->intercept_exceptions; - dst->intercept = from->intercept; + unsigned int i; + + for (i = 0; i < MAX_INTERCEPT; i++) + dst->intercepts[i] = from->intercepts[i]; + dst->iopm_base_pa = from->iopm_base_pa; dst->msrpm_base_pa = from->msrpm_base_pa; dst->tsc_offset = from->tsc_offset; @@ -176,7 +172,7 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) */ int i; - if (!(svm->nested.ctl.intercept & (1ULL << INTERCEPT_MSR_PROT))) + if (!(vmcb_is_intercept(&svm->nested.ctl, INTERCEPT_MSR_PROT))) return true; for (i = 0; i < MSRPM_OFFSETS; i++) { @@ -200,9 +196,23 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) return true; } +static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + if (!nested_svm_vmrun_msrpm(svm)) { + vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; + vcpu->run->internal.suberror = + KVM_INTERNAL_ERROR_EMULATION; + vcpu->run->internal.ndata = 0; + return false; + } + + return true; +} + static bool nested_vmcb_check_controls(struct vmcb_control_area *control) { - if ((control->intercept & (1ULL << INTERCEPT_VMRUN)) == 0) + if ((vmcb_is_intercept(control, INTERCEPT_VMRUN)) == 0) return false; if (control->asid == 0) @@ -215,41 +225,39 @@ static bool nested_vmcb_check_controls(struct vmcb_control_area *control) return true; } -static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb) +static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12) { - bool nested_vmcb_lma; - if ((vmcb->save.efer & EFER_SVME) == 0) + bool vmcb12_lma; + + if ((vmcb12->save.efer & EFER_SVME) == 0) return false; - if (((vmcb->save.cr0 & X86_CR0_CD) == 0) && - (vmcb->save.cr0 & X86_CR0_NW)) + if (((vmcb12->save.cr0 & X86_CR0_CD) == 0) && (vmcb12->save.cr0 & X86_CR0_NW)) return false; - if (!kvm_dr6_valid(vmcb->save.dr6) || !kvm_dr7_valid(vmcb->save.dr7)) + if (!kvm_dr6_valid(vmcb12->save.dr6) || !kvm_dr7_valid(vmcb12->save.dr7)) return false; - nested_vmcb_lma = - (vmcb->save.efer & EFER_LME) && - (vmcb->save.cr0 & X86_CR0_PG); + vmcb12_lma = (vmcb12->save.efer & EFER_LME) && (vmcb12->save.cr0 & X86_CR0_PG); - if (!nested_vmcb_lma) { - if (vmcb->save.cr4 & X86_CR4_PAE) { - if (vmcb->save.cr3 & MSR_CR3_LEGACY_PAE_RESERVED_MASK) + if (!vmcb12_lma) { + if (vmcb12->save.cr4 & X86_CR4_PAE) { + if (vmcb12->save.cr3 & MSR_CR3_LEGACY_PAE_RESERVED_MASK) return false; } else { - if (vmcb->save.cr3 & MSR_CR3_LEGACY_RESERVED_MASK) + if (vmcb12->save.cr3 & MSR_CR3_LEGACY_RESERVED_MASK) return false; } } else { - if (!(vmcb->save.cr4 & X86_CR4_PAE) || - !(vmcb->save.cr0 & X86_CR0_PE) || - (vmcb->save.cr3 & MSR_CR3_LONG_RESERVED_MASK)) + if (!(vmcb12->save.cr4 & X86_CR4_PAE) || + !(vmcb12->save.cr0 & X86_CR0_PE) || + (vmcb12->save.cr3 & MSR_CR3_LONG_MBZ_MASK)) return false; } - if (kvm_valid_cr4(&svm->vcpu, vmcb->save.cr4)) + if (kvm_valid_cr4(&svm->vcpu, vmcb12->save.cr4)) return false; - return nested_vmcb_check_controls(&vmcb->control); + return nested_vmcb_check_controls(&vmcb12->control); } static void load_nested_vmcb_control(struct vcpu_svm *svm, @@ -296,7 +304,7 @@ void sync_nested_vmcb_control(struct vcpu_svm *svm) * EXIT_INT_INFO. */ static void nested_vmcb_save_pending_event(struct vcpu_svm *svm, - struct vmcb *nested_vmcb) + struct vmcb *vmcb12) { struct kvm_vcpu *vcpu = &svm->vcpu; u32 exit_int_info = 0; @@ -308,7 +316,7 @@ static void nested_vmcb_save_pending_event(struct vcpu_svm *svm, if (vcpu->arch.exception.has_error_code) { exit_int_info |= SVM_EVTINJ_VALID_ERR; - nested_vmcb->control.exit_int_info_err = + vmcb12->control.exit_int_info_err = vcpu->arch.exception.error_code; } @@ -325,7 +333,7 @@ static void nested_vmcb_save_pending_event(struct vcpu_svm *svm, exit_int_info |= SVM_EVTINJ_TYPE_INTR; } - nested_vmcb->control.exit_int_info = exit_int_info; + vmcb12->control.exit_int_info = exit_int_info; } static inline bool nested_npt_enabled(struct vcpu_svm *svm) @@ -364,31 +372,31 @@ static int nested_svm_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3, return 0; } -static void nested_prepare_vmcb_save(struct vcpu_svm *svm, struct vmcb *nested_vmcb) +static void nested_prepare_vmcb_save(struct vcpu_svm *svm, struct vmcb *vmcb12) { /* Load the nested guest state */ - svm->vmcb->save.es = nested_vmcb->save.es; - svm->vmcb->save.cs = nested_vmcb->save.cs; - svm->vmcb->save.ss = nested_vmcb->save.ss; - svm->vmcb->save.ds = nested_vmcb->save.ds; - svm->vmcb->save.gdtr = nested_vmcb->save.gdtr; - svm->vmcb->save.idtr = nested_vmcb->save.idtr; - kvm_set_rflags(&svm->vcpu, nested_vmcb->save.rflags); - svm_set_efer(&svm->vcpu, nested_vmcb->save.efer); - svm_set_cr0(&svm->vcpu, nested_vmcb->save.cr0); - svm_set_cr4(&svm->vcpu, nested_vmcb->save.cr4); - svm->vmcb->save.cr2 = svm->vcpu.arch.cr2 = nested_vmcb->save.cr2; - kvm_rax_write(&svm->vcpu, nested_vmcb->save.rax); - kvm_rsp_write(&svm->vcpu, nested_vmcb->save.rsp); - kvm_rip_write(&svm->vcpu, nested_vmcb->save.rip); + svm->vmcb->save.es = vmcb12->save.es; + svm->vmcb->save.cs = vmcb12->save.cs; + svm->vmcb->save.ss = vmcb12->save.ss; + 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); + svm_set_efer(&svm->vcpu, vmcb12->save.efer); + svm_set_cr0(&svm->vcpu, vmcb12->save.cr0); + svm_set_cr4(&svm->vcpu, vmcb12->save.cr4); + svm->vmcb->save.cr2 = svm->vcpu.arch.cr2 = vmcb12->save.cr2; + kvm_rax_write(&svm->vcpu, vmcb12->save.rax); + kvm_rsp_write(&svm->vcpu, vmcb12->save.rsp); + kvm_rip_write(&svm->vcpu, vmcb12->save.rip); /* In case we don't even reach vcpu_run, the fields are not updated */ - svm->vmcb->save.rax = nested_vmcb->save.rax; - svm->vmcb->save.rsp = nested_vmcb->save.rsp; - svm->vmcb->save.rip = nested_vmcb->save.rip; - svm->vmcb->save.dr7 = nested_vmcb->save.dr7; - svm->vcpu.arch.dr6 = nested_vmcb->save.dr6; - svm->vmcb->save.cpl = nested_vmcb->save.cpl; + 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.cpl = vmcb12->save.cpl; } static void nested_prepare_vmcb_control(struct vcpu_svm *svm) @@ -426,17 +434,17 @@ static void nested_prepare_vmcb_control(struct vcpu_svm *svm) vmcb_mark_all_dirty(svm->vmcb); } -int enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb_gpa, - struct vmcb *nested_vmcb) +int enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb12_gpa, + struct vmcb *vmcb12) { int ret; - svm->nested.vmcb = vmcb_gpa; - load_nested_vmcb_control(svm, &nested_vmcb->control); - nested_prepare_vmcb_save(svm, nested_vmcb); + svm->nested.vmcb12_gpa = vmcb12_gpa; + load_nested_vmcb_control(svm, &vmcb12->control); + nested_prepare_vmcb_save(svm, vmcb12); nested_prepare_vmcb_control(svm); - ret = nested_svm_load_cr3(&svm->vcpu, nested_vmcb->save.cr3, + ret = nested_svm_load_cr3(&svm->vcpu, vmcb12->save.cr3, nested_npt_enabled(svm)); if (ret) return ret; @@ -449,19 +457,19 @@ int enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb_gpa, int nested_svm_vmrun(struct vcpu_svm *svm) { int ret; - struct vmcb *nested_vmcb; + struct vmcb *vmcb12; struct vmcb *hsave = svm->nested.hsave; struct vmcb *vmcb = svm->vmcb; struct kvm_host_map map; - u64 vmcb_gpa; + u64 vmcb12_gpa; if (is_smm(&svm->vcpu)) { kvm_queue_exception(&svm->vcpu, UD_VECTOR); return 1; } - vmcb_gpa = svm->vmcb->save.rax; - ret = kvm_vcpu_map(&svm->vcpu, gpa_to_gfn(vmcb_gpa), &map); + vmcb12_gpa = svm->vmcb->save.rax; + ret = kvm_vcpu_map(&svm->vcpu, gpa_to_gfn(vmcb12_gpa), &map); if (ret == -EINVAL) { kvm_inject_gp(&svm->vcpu, 0); return 1; @@ -471,26 +479,31 @@ int nested_svm_vmrun(struct vcpu_svm *svm) ret = kvm_skip_emulated_instruction(&svm->vcpu); - nested_vmcb = map.hva; + vmcb12 = map.hva; - if (!nested_vmcb_checks(svm, nested_vmcb)) { - nested_vmcb->control.exit_code = SVM_EXIT_ERR; - nested_vmcb->control.exit_code_hi = 0; - nested_vmcb->control.exit_info_1 = 0; - nested_vmcb->control.exit_info_2 = 0; + if (WARN_ON_ONCE(!svm->nested.initialized)) + return -EINVAL; + + if (!nested_vmcb_checks(svm, vmcb12)) { + vmcb12->control.exit_code = SVM_EXIT_ERR; + vmcb12->control.exit_code_hi = 0; + vmcb12->control.exit_info_1 = 0; + vmcb12->control.exit_info_2 = 0; goto out; } - trace_kvm_nested_vmrun(svm->vmcb->save.rip, vmcb_gpa, - nested_vmcb->save.rip, - nested_vmcb->control.int_ctl, - nested_vmcb->control.event_inj, - nested_vmcb->control.nested_ctl); + trace_kvm_nested_vmrun(svm->vmcb->save.rip, vmcb12_gpa, + vmcb12->save.rip, + vmcb12->control.int_ctl, + vmcb12->control.event_inj, + vmcb12->control.nested_ctl); - trace_kvm_nested_intercepts(nested_vmcb->control.intercept_cr & 0xffff, - nested_vmcb->control.intercept_cr >> 16, - nested_vmcb->control.intercept_exceptions, - nested_vmcb->control.intercept); + trace_kvm_nested_intercepts(vmcb12->control.intercepts[INTERCEPT_CR] & 0xffff, + vmcb12->control.intercepts[INTERCEPT_CR] >> 16, + vmcb12->control.intercepts[INTERCEPT_EXCEPTION], + vmcb12->control.intercepts[INTERCEPT_WORD3], + vmcb12->control.intercepts[INTERCEPT_WORD4], + vmcb12->control.intercepts[INTERCEPT_WORD5]); /* Clear internal status */ kvm_clear_exception_queue(&svm->vcpu); @@ -522,7 +535,7 @@ int nested_svm_vmrun(struct vcpu_svm *svm) svm->nested.nested_run_pending = 1; - if (enter_svm_guest_mode(svm, vmcb_gpa, nested_vmcb)) + if (enter_svm_guest_mode(svm, vmcb12_gpa, vmcb12)) goto out_exit_err; if (nested_svm_vmrun_msrpm(svm)) @@ -563,75 +576,77 @@ void nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb) int nested_svm_vmexit(struct vcpu_svm *svm) { int rc; - struct vmcb *nested_vmcb; + struct vmcb *vmcb12; struct vmcb *hsave = svm->nested.hsave; struct vmcb *vmcb = svm->vmcb; struct kvm_host_map map; - rc = kvm_vcpu_map(&svm->vcpu, gpa_to_gfn(svm->nested.vmcb), &map); + rc = kvm_vcpu_map(&svm->vcpu, gpa_to_gfn(svm->nested.vmcb12_gpa), &map); if (rc) { if (rc == -EINVAL) kvm_inject_gp(&svm->vcpu, 0); return 1; } - nested_vmcb = map.hva; + vmcb12 = map.hva; /* Exit Guest-Mode */ leave_guest_mode(&svm->vcpu); - svm->nested.vmcb = 0; + svm->nested.vmcb12_gpa = 0; WARN_ON_ONCE(svm->nested.nested_run_pending); /* in case we halted in L2 */ svm->vcpu.arch.mp_state = KVM_MP_STATE_RUNNABLE; /* Give the current vmcb to the guest */ - svm_set_gif(svm, false); - nested_vmcb->save.es = vmcb->save.es; - nested_vmcb->save.cs = vmcb->save.cs; - nested_vmcb->save.ss = vmcb->save.ss; - nested_vmcb->save.ds = vmcb->save.ds; - nested_vmcb->save.gdtr = vmcb->save.gdtr; - nested_vmcb->save.idtr = vmcb->save.idtr; - nested_vmcb->save.efer = svm->vcpu.arch.efer; - nested_vmcb->save.cr0 = kvm_read_cr0(&svm->vcpu); - nested_vmcb->save.cr3 = kvm_read_cr3(&svm->vcpu); - nested_vmcb->save.cr2 = vmcb->save.cr2; - nested_vmcb->save.cr4 = svm->vcpu.arch.cr4; - nested_vmcb->save.rflags = kvm_get_rflags(&svm->vcpu); - nested_vmcb->save.rip = kvm_rip_read(&svm->vcpu); - nested_vmcb->save.rsp = kvm_rsp_read(&svm->vcpu); - nested_vmcb->save.rax = kvm_rax_read(&svm->vcpu); - nested_vmcb->save.dr7 = vmcb->save.dr7; - nested_vmcb->save.dr6 = svm->vcpu.arch.dr6; - nested_vmcb->save.cpl = vmcb->save.cpl; - - nested_vmcb->control.int_state = vmcb->control.int_state; - nested_vmcb->control.exit_code = vmcb->control.exit_code; - nested_vmcb->control.exit_code_hi = vmcb->control.exit_code_hi; - nested_vmcb->control.exit_info_1 = vmcb->control.exit_info_1; - nested_vmcb->control.exit_info_2 = vmcb->control.exit_info_2; - - if (nested_vmcb->control.exit_code != SVM_EXIT_ERR) - nested_vmcb_save_pending_event(svm, nested_vmcb); + vmcb12->save.es = vmcb->save.es; + vmcb12->save.cs = vmcb->save.cs; + vmcb12->save.ss = vmcb->save.ss; + vmcb12->save.ds = vmcb->save.ds; + vmcb12->save.gdtr = vmcb->save.gdtr; + vmcb12->save.idtr = vmcb->save.idtr; + vmcb12->save.efer = svm->vcpu.arch.efer; + vmcb12->save.cr0 = kvm_read_cr0(&svm->vcpu); + vmcb12->save.cr3 = kvm_read_cr3(&svm->vcpu); + vmcb12->save.cr2 = vmcb->save.cr2; + vmcb12->save.cr4 = svm->vcpu.arch.cr4; + vmcb12->save.rflags = kvm_get_rflags(&svm->vcpu); + vmcb12->save.rip = kvm_rip_read(&svm->vcpu); + vmcb12->save.rsp = kvm_rsp_read(&svm->vcpu); + vmcb12->save.rax = kvm_rax_read(&svm->vcpu); + vmcb12->save.dr7 = vmcb->save.dr7; + vmcb12->save.dr6 = svm->vcpu.arch.dr6; + vmcb12->save.cpl = vmcb->save.cpl; + + vmcb12->control.int_state = vmcb->control.int_state; + vmcb12->control.exit_code = vmcb->control.exit_code; + vmcb12->control.exit_code_hi = vmcb->control.exit_code_hi; + vmcb12->control.exit_info_1 = vmcb->control.exit_info_1; + vmcb12->control.exit_info_2 = vmcb->control.exit_info_2; + + if (vmcb12->control.exit_code != SVM_EXIT_ERR) + nested_vmcb_save_pending_event(svm, vmcb12); if (svm->nrips_enabled) - nested_vmcb->control.next_rip = vmcb->control.next_rip; + vmcb12->control.next_rip = vmcb->control.next_rip; - nested_vmcb->control.int_ctl = svm->nested.ctl.int_ctl; - nested_vmcb->control.tlb_ctl = svm->nested.ctl.tlb_ctl; - nested_vmcb->control.event_inj = svm->nested.ctl.event_inj; - nested_vmcb->control.event_inj_err = svm->nested.ctl.event_inj_err; + vmcb12->control.int_ctl = svm->nested.ctl.int_ctl; + vmcb12->control.tlb_ctl = svm->nested.ctl.tlb_ctl; + vmcb12->control.event_inj = svm->nested.ctl.event_inj; + vmcb12->control.event_inj_err = svm->nested.ctl.event_inj_err; - nested_vmcb->control.pause_filter_count = + vmcb12->control.pause_filter_count = svm->vmcb->control.pause_filter_count; - nested_vmcb->control.pause_filter_thresh = + vmcb12->control.pause_filter_thresh = svm->vmcb->control.pause_filter_thresh; /* Restore the original control entries */ copy_vmcb_control_area(&vmcb->control, &hsave->control); + /* On vmexit the GIF is set to false */ + svm_set_gif(svm, false); + svm->vmcb->control.tsc_offset = svm->vcpu.arch.tsc_offset = svm->vcpu.arch.l1_tsc_offset; @@ -657,11 +672,11 @@ int nested_svm_vmexit(struct vcpu_svm *svm) vmcb_mark_all_dirty(svm->vmcb); - trace_kvm_nested_vmexit_inject(nested_vmcb->control.exit_code, - nested_vmcb->control.exit_info_1, - nested_vmcb->control.exit_info_2, - nested_vmcb->control.exit_int_info, - nested_vmcb->control.exit_int_info_err, + trace_kvm_nested_vmexit_inject(vmcb12->control.exit_code, + vmcb12->control.exit_info_1, + vmcb12->control.exit_info_2, + vmcb12->control.exit_int_info, + vmcb12->control.exit_int_info_err, KVM_ISA_SVM); kvm_vcpu_unmap(&svm->vcpu, &map, true); @@ -686,6 +701,45 @@ int nested_svm_vmexit(struct vcpu_svm *svm) return 0; } +int svm_allocate_nested(struct vcpu_svm *svm) +{ + struct page *hsave_page; + + if (svm->nested.initialized) + return 0; + + hsave_page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); + if (!hsave_page) + return -ENOMEM; + svm->nested.hsave = page_address(hsave_page); + + svm->nested.msrpm = svm_vcpu_alloc_msrpm(); + if (!svm->nested.msrpm) + goto err_free_hsave; + svm_vcpu_init_msrpm(&svm->vcpu, svm->nested.msrpm); + + svm->nested.initialized = true; + return 0; + +err_free_hsave: + __free_page(hsave_page); + return -ENOMEM; +} + +void svm_free_nested(struct vcpu_svm *svm) +{ + if (!svm->nested.initialized) + return; + + svm_vcpu_free_msrpm(svm->nested.msrpm); + svm->nested.msrpm = NULL; + + __free_page(virt_to_page(svm->nested.hsave)); + svm->nested.hsave = NULL; + + svm->nested.initialized = false; +} + /* * Forcibly leave nested mode in order to be able to reset the VCPU later on. */ @@ -700,6 +754,8 @@ void svm_leave_nested(struct vcpu_svm *svm) copy_vmcb_control_area(&vmcb->control, &hsave->control); nested_svm_uninit_mmu_context(&svm->vcpu); } + + kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, &svm->vcpu); } static int nested_svm_exit_handled_msr(struct vcpu_svm *svm) @@ -707,7 +763,7 @@ static int nested_svm_exit_handled_msr(struct vcpu_svm *svm) u32 offset, msr, value; int write, mask; - if (!(svm->nested.ctl.intercept & (1ULL << INTERCEPT_MSR_PROT))) + if (!(vmcb_is_intercept(&svm->nested.ctl, INTERCEPT_MSR_PROT))) return NESTED_EXIT_HOST; msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; @@ -734,7 +790,7 @@ static int nested_svm_intercept_ioio(struct vcpu_svm *svm) u8 start_bit; u64 gpa; - if (!(svm->nested.ctl.intercept & (1ULL << INTERCEPT_IOIO_PROT))) + if (!(vmcb_is_intercept(&svm->nested.ctl, INTERCEPT_IOIO_PROT))) return NESTED_EXIT_HOST; port = svm->vmcb->control.exit_info_1 >> 16; @@ -765,14 +821,12 @@ static int nested_svm_intercept(struct vcpu_svm *svm) vmexit = nested_svm_intercept_ioio(svm); break; case SVM_EXIT_READ_CR0 ... SVM_EXIT_WRITE_CR8: { - u32 bit = 1U << (exit_code - SVM_EXIT_READ_CR0); - if (svm->nested.ctl.intercept_cr & bit) + if (vmcb_is_intercept(&svm->nested.ctl, exit_code)) vmexit = NESTED_EXIT_DONE; break; } case SVM_EXIT_READ_DR0 ... SVM_EXIT_WRITE_DR7: { - u32 bit = 1U << (exit_code - SVM_EXIT_READ_DR0); - if (svm->nested.ctl.intercept_dr & bit) + if (vmcb_is_intercept(&svm->nested.ctl, exit_code)) vmexit = NESTED_EXIT_DONE; break; } @@ -790,8 +844,7 @@ static int nested_svm_intercept(struct vcpu_svm *svm) break; } default: { - u64 exit_bits = 1ULL << (exit_code - SVM_EXIT_INTR); - if (svm->nested.ctl.intercept & exit_bits) + if (vmcb_is_intercept(&svm->nested.ctl, exit_code)) vmexit = NESTED_EXIT_DONE; } } @@ -831,7 +884,7 @@ static bool nested_exit_on_exception(struct vcpu_svm *svm) { unsigned int nr = svm->vcpu.arch.exception.nr; - return (svm->nested.ctl.intercept_exceptions & (1 << nr)); + return (svm->nested.ctl.intercepts[INTERCEPT_EXCEPTION] & BIT(nr)); } static void nested_svm_inject_exception_vmexit(struct vcpu_svm *svm) @@ -899,7 +952,7 @@ static void nested_svm_intr(struct vcpu_svm *svm) static inline bool nested_exit_on_init(struct vcpu_svm *svm) { - return (svm->nested.ctl.intercept & (1ULL << INTERCEPT_INIT)); + return vmcb_is_intercept(&svm->nested.ctl, INTERCEPT_INIT); } static void nested_svm_init(struct vcpu_svm *svm) @@ -980,7 +1033,8 @@ int nested_svm_exit_special(struct vcpu_svm *svm) case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 0x1f: { u32 excp_bits = 1 << (exit_code - SVM_EXIT_EXCP_BASE); - if (get_host_vmcb(svm)->control.intercept_exceptions & excp_bits) + if (get_host_vmcb(svm)->control.intercepts[INTERCEPT_EXCEPTION] & + excp_bits) return NESTED_EXIT_HOST; else if (exit_code == SVM_EXIT_EXCP_BASE + PF_VECTOR && svm->vcpu.arch.apf.host_apf_flags) @@ -1018,7 +1072,7 @@ static int svm_get_nested_state(struct kvm_vcpu *vcpu, /* First fill in the header and copy it out. */ if (is_guest_mode(vcpu)) { - kvm_state.hdr.svm.vmcb_pa = svm->nested.vmcb; + kvm_state.hdr.svm.vmcb_pa = svm->nested.vmcb12_gpa; kvm_state.size += KVM_STATE_NESTED_SVM_VMCB_SIZE; kvm_state.flags |= KVM_STATE_NESTED_GUEST_MODE; @@ -1060,10 +1114,14 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, struct vmcb *hsave = svm->nested.hsave; struct vmcb __user *user_vmcb = (struct vmcb __user *) &user_kvm_nested_state->data.svm[0]; - struct vmcb_control_area ctl; - struct vmcb_save_area save; + struct vmcb_control_area *ctl; + struct vmcb_save_area *save; + int ret; u32 cr0; + BUILD_BUG_ON(sizeof(struct vmcb_control_area) + sizeof(struct vmcb_save_area) > + KVM_STATE_NESTED_SVM_VMCB_SIZE); + if (kvm_state->format != KVM_STATE_NESTED_FORMAT_SVM) return -EINVAL; @@ -1088,20 +1146,30 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, if (!(kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE)) { svm_leave_nested(svm); - goto out_set_gif; + svm_set_gif(svm, !!(kvm_state->flags & KVM_STATE_NESTED_GIF_SET)); + return 0; } if (!page_address_valid(vcpu, kvm_state->hdr.svm.vmcb_pa)) return -EINVAL; if (kvm_state->size < sizeof(*kvm_state) + KVM_STATE_NESTED_SVM_VMCB_SIZE) return -EINVAL; - if (copy_from_user(&ctl, &user_vmcb->control, sizeof(ctl))) - return -EFAULT; - if (copy_from_user(&save, &user_vmcb->save, sizeof(save))) - return -EFAULT; - if (!nested_vmcb_check_controls(&ctl)) - return -EINVAL; + ret = -ENOMEM; + ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + save = kzalloc(sizeof(*save), GFP_KERNEL); + if (!ctl || !save) + goto out_free; + + ret = -EFAULT; + if (copy_from_user(ctl, &user_vmcb->control, sizeof(*ctl))) + goto out_free; + if (copy_from_user(save, &user_vmcb->save, sizeof(*save))) + goto out_free; + + ret = -EINVAL; + if (!nested_vmcb_check_controls(ctl)) + goto out_free; /* * Processor state contains L2 state. Check that it is @@ -1109,15 +1177,15 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, */ cr0 = kvm_read_cr0(vcpu); if (((cr0 & X86_CR0_CD) == 0) && (cr0 & X86_CR0_NW)) - return -EINVAL; + goto out_free; /* * Validate host state saved from before VMRUN (see * nested_svm_check_permissions). * TODO: validate reserved bits for all saved state. */ - if (!(save.cr0 & X86_CR0_PG)) - return -EINVAL; + if (!(save->cr0 & X86_CR0_PG)) + goto out_free; /* * All checks done, we can enter guest mode. L1 control fields @@ -1126,19 +1194,24 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, * contains saved L1 state. */ copy_vmcb_control_area(&hsave->control, &svm->vmcb->control); - hsave->save = save; + hsave->save = *save; - svm->nested.vmcb = kvm_state->hdr.svm.vmcb_pa; - load_nested_vmcb_control(svm, &ctl); + svm->nested.vmcb12_gpa = kvm_state->hdr.svm.vmcb_pa; + load_nested_vmcb_control(svm, ctl); nested_prepare_vmcb_control(svm); -out_set_gif: - svm_set_gif(svm, !!(kvm_state->flags & KVM_STATE_NESTED_GIF_SET)); - return 0; + kvm_make_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); + ret = 0; +out_free: + kfree(save); + kfree(ctl); + + return ret; } struct kvm_x86_nested_ops svm_nested_ops = { .check_events = svm_check_nested_events, + .get_nested_state_pages = svm_get_nested_state_pages, .get_state = svm_get_nested_state, .set_state = svm_set_nested_state, }; diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 402dc4234e39..c0b14106258a 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -384,7 +384,8 @@ static void sev_clflush_pages(struct page *pages[], unsigned long npages) uint8_t *page_virtual; unsigned long i; - if (npages == 0 || pages == NULL) + if (this_cpu_has(X86_FEATURE_SME_COHERENT) || npages == 0 || + pages == NULL) return; for (i = 0; i < npages; i++) { @@ -446,10 +447,8 @@ static int sev_launch_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp) } /* - * The LAUNCH_UPDATE command will perform in-place encryption of the - * memory content (i.e it will write the same memory region with C=1). - * It's possible that the cache may contain the data with C=0, i.e., - * unencrypted so invalidate it first. + * Flush (on non-coherent CPUs) before LAUNCH_UPDATE encrypts pages in + * place; the cache may contain the data that was written unencrypted. */ sev_clflush_pages(inpages, npages); @@ -805,10 +804,9 @@ static int sev_dbg_crypt(struct kvm *kvm, struct kvm_sev_cmd *argp, bool dec) } /* - * The DBG_{DE,EN}CRYPT commands will perform {dec,en}cryption of the - * memory content (i.e it will write the same memory region with C=1). - * It's possible that the cache may contain the data with C=0, i.e., - * unencrypted so invalidate it first. + * Flush (on non-coherent CPUs) before DBG_{DE,EN}CRYPT read or modify + * the pages; flush the destination too so that future accesses do not + * see stale data. */ sev_clflush_pages(src_p, 1); sev_clflush_pages(dst_p, 1); @@ -856,7 +854,7 @@ static int sev_launch_secret(struct kvm *kvm, struct kvm_sev_cmd *argp) struct kvm_sev_launch_secret params; struct page **pages; void *blob, *hdr; - unsigned long n; + unsigned long n, i; int ret, offset; if (!sev_guest(kvm)) @@ -870,6 +868,12 @@ static int sev_launch_secret(struct kvm *kvm, struct kvm_sev_cmd *argp) return PTR_ERR(pages); /* + * Flush (on non-coherent CPUs) before LAUNCH_SECRET encrypts pages in + * place; the cache may contain the data that was written unencrypted. + */ + sev_clflush_pages(pages, n); + + /* * The secret must be copied into contiguous memory region, lets verify * that userspace memory pages are contiguous before we issue command. */ @@ -914,6 +918,11 @@ e_free_blob: e_free: kfree(data); e_unpin_memory: + /* content of memory is updated, mark pages dirty */ + for (i = 0; i < n; i++) { + set_page_dirty_lock(pages[i]); + mark_page_accessed(pages[i]); + } sev_unpin_memory(kvm, pages, n); return ret; } @@ -1106,6 +1115,7 @@ void sev_vm_destroy(struct kvm *kvm) list_for_each_safe(pos, q, head) { __unregister_enc_region_locked(kvm, list_entry(pos, struct enc_region, list)); + cond_resched(); } } diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 0194336b64a4..2f32fd09e259 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -19,7 +19,7 @@ #include <linux/trace_events.h> #include <linux/slab.h> #include <linux/hashtable.h> -#include <linux/frame.h> +#include <linux/objtool.h> #include <linux/psp-sev.h> #include <linux/file.h> #include <linux/pagemap.h> @@ -91,7 +91,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 */ -} direct_access_msrs[] = { +} direct_access_msrs[MAX_DIRECT_ACCESS_MSRS] = { { .index = MSR_STAR, .always = true }, { .index = MSR_IA32_SYSENTER_CS, .always = true }, #ifdef CONFIG_X86_64 @@ -263,9 +263,10 @@ static int get_max_npt_level(void) #endif } -void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) +int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) { struct vcpu_svm *svm = to_svm(vcpu); + u64 old_efer = vcpu->arch.efer; vcpu->arch.efer = efer; if (!npt_enabled) { @@ -276,13 +277,32 @@ void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) efer &= ~EFER_LME; } - if (!(efer & EFER_SVME)) { - svm_leave_nested(svm); - svm_set_gif(svm, true); + if ((old_efer & EFER_SVME) != (efer & EFER_SVME)) { + if (!(efer & EFER_SVME)) { + svm_leave_nested(svm); + svm_set_gif(svm, true); + + /* + * Free the nested guest state, unless we are in SMM. + * In this case we will return to the nested guest + * as soon as we leave SMM. + */ + if (!is_smm(&svm->vcpu)) + svm_free_nested(svm); + + } else { + int ret = svm_allocate_nested(svm); + + if (ret) { + vcpu->arch.efer = old_efer; + return ret; + } + } } svm->vmcb->save.efer = efer | EFER_SVME; vmcb_mark_dirty(svm->vmcb, VMCB_CR); + return 0; } static int is_external_interrupt(u32 info) @@ -553,18 +573,44 @@ free_cpu_data: } -static bool valid_msr_intercept(u32 index) +static int direct_access_msr_slot(u32 msr) { - int i; + u32 i; for (i = 0; direct_access_msrs[i].index != MSR_INVALID; i++) - if (direct_access_msrs[i].index == index) - return true; + if (direct_access_msrs[i].index == msr) + return i; - return false; + return -ENOENT; +} + +static void set_shadow_msr_intercept(struct kvm_vcpu *vcpu, u32 msr, int read, + int write) +{ + struct vcpu_svm *svm = to_svm(vcpu); + int slot = direct_access_msr_slot(msr); + + if (slot == -ENOENT) + return; + + /* Set the shadow bitmaps to the desired intercept states */ + if (read) + set_bit(slot, svm->shadow_msr_intercept.read); + else + clear_bit(slot, svm->shadow_msr_intercept.read); + + if (write) + set_bit(slot, svm->shadow_msr_intercept.write); + else + clear_bit(slot, svm->shadow_msr_intercept.write); +} + +static bool valid_msr_intercept(u32 index) +{ + return direct_access_msr_slot(index) != -ENOENT; } -static bool msr_write_intercepted(struct kvm_vcpu *vcpu, unsigned msr) +static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr) { u8 bit_write; unsigned long tmp; @@ -583,8 +629,8 @@ static bool msr_write_intercepted(struct kvm_vcpu *vcpu, unsigned msr) return !!test_bit(bit_write, &tmp); } -static void set_msr_interception(u32 *msrpm, unsigned msr, - int read, int write) +static void set_msr_interception_bitmap(struct kvm_vcpu *vcpu, u32 *msrpm, + u32 msr, int read, int write) { u8 bit_read, bit_write; unsigned long tmp; @@ -596,6 +642,13 @@ static void set_msr_interception(u32 *msrpm, unsigned msr, */ WARN_ON(!valid_msr_intercept(msr)); + /* Enforce non allowed MSRs to trap */ + if (read && !kvm_msr_allowed(vcpu, msr, KVM_MSR_FILTER_READ)) + read = 0; + + if (write && !kvm_msr_allowed(vcpu, msr, KVM_MSR_FILTER_WRITE)) + write = 0; + offset = svm_msrpm_offset(msr); bit_read = 2 * (msr & 0x0f); bit_write = 2 * (msr & 0x0f) + 1; @@ -609,17 +662,60 @@ static void set_msr_interception(u32 *msrpm, unsigned msr, msrpm[offset] = tmp; } -static void svm_vcpu_init_msrpm(u32 *msrpm) +static void set_msr_interception(struct kvm_vcpu *vcpu, u32 *msrpm, u32 msr, + int read, int write) { - int i; + set_shadow_msr_intercept(vcpu, msr, read, write); + set_msr_interception_bitmap(vcpu, msrpm, msr, read, write); +} + +u32 *svm_vcpu_alloc_msrpm(void) +{ + struct page *pages = alloc_pages(GFP_KERNEL_ACCOUNT, MSRPM_ALLOC_ORDER); + u32 *msrpm; + if (!pages) + return NULL; + + msrpm = page_address(pages); memset(msrpm, 0xff, PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER)); + return msrpm; +} + +void svm_vcpu_init_msrpm(struct kvm_vcpu *vcpu, u32 *msrpm) +{ + int i; + for (i = 0; direct_access_msrs[i].index != MSR_INVALID; i++) { if (!direct_access_msrs[i].always) continue; + set_msr_interception(vcpu, msrpm, direct_access_msrs[i].index, 1, 1); + } +} + + +void svm_vcpu_free_msrpm(u32 *msrpm) +{ + __free_pages(virt_to_page(msrpm), MSRPM_ALLOC_ORDER); +} + +static void svm_msr_filter_changed(struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + u32 i; + + /* + * Set intercept permissions for all direct access MSRs again. They + * will automatically get filtered through the MSR filter, so we are + * back in sync after this. + */ + for (i = 0; direct_access_msrs[i].index != MSR_INVALID; i++) { + u32 msr = direct_access_msrs[i].index; + u32 read = test_bit(i, svm->shadow_msr_intercept.read); + u32 write = test_bit(i, svm->shadow_msr_intercept.write); - set_msr_interception(msrpm, direct_access_msrs[i].index, 1, 1); + set_msr_interception_bitmap(vcpu, svm->msrpm, msr, read, write); } } @@ -666,26 +762,26 @@ static void init_msrpm_offsets(void) } } -static void svm_enable_lbrv(struct vcpu_svm *svm) +static void svm_enable_lbrv(struct kvm_vcpu *vcpu) { - u32 *msrpm = svm->msrpm; + struct vcpu_svm *svm = to_svm(vcpu); svm->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK; - set_msr_interception(msrpm, MSR_IA32_LASTBRANCHFROMIP, 1, 1); - set_msr_interception(msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1); - set_msr_interception(msrpm, MSR_IA32_LASTINTFROMIP, 1, 1); - set_msr_interception(msrpm, MSR_IA32_LASTINTTOIP, 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); } -static void svm_disable_lbrv(struct vcpu_svm *svm) +static void svm_disable_lbrv(struct kvm_vcpu *vcpu) { - u32 *msrpm = svm->msrpm; + struct vcpu_svm *svm = to_svm(vcpu); svm->vmcb->control.virt_ext &= ~LBR_CTL_ENABLE_MASK; - set_msr_interception(msrpm, MSR_IA32_LASTBRANCHFROMIP, 0, 0); - set_msr_interception(msrpm, MSR_IA32_LASTBRANCHTOIP, 0, 0); - set_msr_interception(msrpm, MSR_IA32_LASTINTFROMIP, 0, 0); - set_msr_interception(msrpm, MSR_IA32_LASTINTTOIP, 0, 0); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, 0, 0); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 0, 0); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 0, 0); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 0, 0); } void disable_nmi_singlestep(struct vcpu_svm *svm) @@ -813,6 +909,9 @@ static __init void svm_set_cpu_caps(void) if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD) || boot_cpu_has(X86_FEATURE_AMD_SSBD)) kvm_cpu_cap_set(X86_FEATURE_VIRT_SSBD); + + /* Enable INVPCID feature */ + kvm_cpu_cap_check_and_set(X86_FEATURE_INVPCID); } static __init int svm_hardware_setup(void) @@ -985,6 +1084,21 @@ static u64 svm_write_l1_tsc_offset(struct kvm_vcpu *vcpu, u64 offset) return svm->vmcb->control.tsc_offset; } +static void svm_check_invpcid(struct vcpu_svm *svm) +{ + /* + * Intercept INVPCID instruction only if shadow page table is + * enabled. Interception is not required with nested page table + * enabled. + */ + if (kvm_cpu_cap_has(X86_FEATURE_INVPCID)) { + if (!npt_enabled) + svm_set_intercept(svm, INTERCEPT_INVPCID); + else + svm_clr_intercept(svm, INTERCEPT_INVPCID); + } +} + static void init_vmcb(struct vcpu_svm *svm) { struct vmcb_control_area *control = &svm->vmcb->control; @@ -992,14 +1106,14 @@ static void init_vmcb(struct vcpu_svm *svm) svm->vcpu.arch.hflags = 0; - set_cr_intercept(svm, INTERCEPT_CR0_READ); - set_cr_intercept(svm, INTERCEPT_CR3_READ); - set_cr_intercept(svm, INTERCEPT_CR4_READ); - set_cr_intercept(svm, INTERCEPT_CR0_WRITE); - set_cr_intercept(svm, INTERCEPT_CR3_WRITE); - set_cr_intercept(svm, INTERCEPT_CR4_WRITE); + svm_set_intercept(svm, INTERCEPT_CR0_READ); + svm_set_intercept(svm, INTERCEPT_CR3_READ); + svm_set_intercept(svm, INTERCEPT_CR4_READ); + svm_set_intercept(svm, INTERCEPT_CR0_WRITE); + svm_set_intercept(svm, INTERCEPT_CR3_WRITE); + svm_set_intercept(svm, INTERCEPT_CR4_WRITE); if (!kvm_vcpu_apicv_active(&svm->vcpu)) - set_cr_intercept(svm, INTERCEPT_CR8_WRITE); + svm_set_intercept(svm, INTERCEPT_CR8_WRITE); set_dr_intercepts(svm); @@ -1094,15 +1208,15 @@ static void init_vmcb(struct vcpu_svm *svm) control->nested_ctl |= SVM_NESTED_CTL_NP_ENABLE; svm_clr_intercept(svm, INTERCEPT_INVLPG); clr_exception_intercept(svm, PF_VECTOR); - clr_cr_intercept(svm, INTERCEPT_CR3_READ); - clr_cr_intercept(svm, INTERCEPT_CR3_WRITE); + svm_clr_intercept(svm, INTERCEPT_CR3_READ); + svm_clr_intercept(svm, INTERCEPT_CR3_WRITE); save->g_pat = svm->vcpu.arch.pat; save->cr3 = 0; save->cr4 = 0; } svm->asid_generation = 0; - svm->nested.vmcb = 0; + svm->nested.vmcb12_gpa = 0; svm->vcpu.arch.hflags = 0; if (!kvm_pause_in_guest(svm->vcpu.kvm)) { @@ -1114,6 +1228,8 @@ static void init_vmcb(struct vcpu_svm *svm) svm_clr_intercept(svm, INTERCEPT_PAUSE); } + svm_check_invpcid(svm); + if (kvm_vcpu_apicv_active(&svm->vcpu)) avic_init_vmcb(svm); @@ -1171,35 +1287,20 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) static int svm_create_vcpu(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm; - struct page *page; - struct page *msrpm_pages; - struct page *hsave_page; - struct page *nested_msrpm_pages; + struct page *vmcb_page; int err; BUILD_BUG_ON(offsetof(struct vcpu_svm, vcpu) != 0); svm = to_svm(vcpu); err = -ENOMEM; - page = alloc_page(GFP_KERNEL_ACCOUNT); - if (!page) + vmcb_page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); + if (!vmcb_page) goto out; - msrpm_pages = alloc_pages(GFP_KERNEL_ACCOUNT, MSRPM_ALLOC_ORDER); - if (!msrpm_pages) - goto free_page1; - - nested_msrpm_pages = alloc_pages(GFP_KERNEL_ACCOUNT, MSRPM_ALLOC_ORDER); - if (!nested_msrpm_pages) - goto free_page2; - - hsave_page = alloc_page(GFP_KERNEL_ACCOUNT); - if (!hsave_page) - goto free_page3; - err = avic_init_vcpu(svm); if (err) - goto free_page4; + goto error_free_vmcb_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. @@ -1207,18 +1308,14 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu) if (irqchip_in_kernel(vcpu->kvm) && kvm_apicv_activated(vcpu->kvm)) svm->avic_is_running = true; - svm->nested.hsave = page_address(hsave_page); - clear_page(svm->nested.hsave); - - svm->msrpm = page_address(msrpm_pages); - svm_vcpu_init_msrpm(svm->msrpm); + svm->msrpm = svm_vcpu_alloc_msrpm(); + if (!svm->msrpm) + goto error_free_vmcb_page; - svm->nested.msrpm = page_address(nested_msrpm_pages); - svm_vcpu_init_msrpm(svm->nested.msrpm); + svm_vcpu_init_msrpm(vcpu, svm->msrpm); - svm->vmcb = page_address(page); - clear_page(svm->vmcb); - svm->vmcb_pa = __sme_set(page_to_pfn(page) << PAGE_SHIFT); + svm->vmcb = page_address(vmcb_page); + svm->vmcb_pa = __sme_set(page_to_pfn(vmcb_page) << PAGE_SHIFT); svm->asid_generation = 0; init_vmcb(svm); @@ -1227,14 +1324,8 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu) return 0; -free_page4: - __free_page(hsave_page); -free_page3: - __free_pages(nested_msrpm_pages, MSRPM_ALLOC_ORDER); -free_page2: - __free_pages(msrpm_pages, MSRPM_ALLOC_ORDER); -free_page1: - __free_page(page); +error_free_vmcb_page: + __free_page(vmcb_page); out: return err; } @@ -1258,10 +1349,10 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu) */ svm_clear_current_vmcb(svm->vmcb); + svm_free_nested(svm); + __free_page(pfn_to_page(__sme_clr(svm->vmcb_pa) >> PAGE_SHIFT)); __free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER); - __free_page(virt_to_page(svm->nested.hsave)); - __free_pages(virt_to_page(svm->nested.msrpm), MSRPM_ALLOC_ORDER); } static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) @@ -1549,11 +1640,11 @@ static void update_cr0_intercept(struct vcpu_svm *svm) vmcb_mark_dirty(svm->vmcb, VMCB_CR); if (gcr0 == *hcr0) { - clr_cr_intercept(svm, INTERCEPT_CR0_READ); - clr_cr_intercept(svm, INTERCEPT_CR0_WRITE); + svm_clr_intercept(svm, INTERCEPT_CR0_READ); + svm_clr_intercept(svm, INTERCEPT_CR0_WRITE); } else { - set_cr_intercept(svm, INTERCEPT_CR0_READ); - set_cr_intercept(svm, INTERCEPT_CR0_WRITE); + svm_set_intercept(svm, INTERCEPT_CR0_READ); + svm_set_intercept(svm, INTERCEPT_CR0_WRITE); } } @@ -2183,6 +2274,12 @@ static int iret_interception(struct vcpu_svm *svm) return 1; } +static int invd_interception(struct vcpu_svm *svm) +{ + /* Treat an INVD instruction as a NOP and just skip it. */ + return kvm_skip_emulated_instruction(&svm->vcpu); +} + static int invlpg_interception(struct vcpu_svm *svm) { if (!static_cpu_has(X86_FEATURE_DECODEASSISTS)) @@ -2218,12 +2315,9 @@ static bool check_selective_cr0_intercepted(struct vcpu_svm *svm, { unsigned long cr0 = svm->vcpu.arch.cr0; bool ret = false; - u64 intercept; - - intercept = svm->nested.ctl.intercept; if (!is_guest_mode(&svm->vcpu) || - (!(intercept & (1ULL << INTERCEPT_SELECTIVE_CR0)))) + (!(vmcb_is_intercept(&svm->nested.ctl, INTERCEPT_SELECTIVE_CR0)))) return false; cr0 &= ~SVM_CR0_SELECTIVE_MASK; @@ -2261,6 +2355,7 @@ static int cr_interception(struct vcpu_svm *svm) if (cr >= 16) { /* mov to cr */ cr -= 16; val = kvm_register_read(&svm->vcpu, reg); + trace_kvm_cr_write(cr, val); switch (cr) { case 0: if (!check_selective_cr0_intercepted(svm, val)) @@ -2306,6 +2401,7 @@ static int cr_interception(struct vcpu_svm *svm) return 1; } kvm_register_write(&svm->vcpu, reg, val); + trace_kvm_cr_read(cr, val); } return kvm_complete_insn_gp(&svm->vcpu, err); } @@ -2556,7 +2652,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) * We update the L1 MSR bit as well since it will end up * touching the MSR anyway now. */ - set_msr_interception(svm->msrpm, MSR_IA32_SPEC_CTRL, 1, 1); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_SPEC_CTRL, 1, 1); break; case MSR_IA32_PRED_CMD: if (!msr->host_initiated && @@ -2571,7 +2667,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) break; wrmsrl(MSR_IA32_PRED_CMD, PRED_CMD_IBPB); - set_msr_interception(svm->msrpm, MSR_IA32_PRED_CMD, 0, 1); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_PRED_CMD, 0, 1); break; case MSR_AMD64_VIRT_SPEC_CTRL: if (!msr->host_initiated && @@ -2635,9 +2731,9 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) svm->vmcb->save.dbgctl = data; vmcb_mark_dirty(svm->vmcb, VMCB_LBR); if (data & (1ULL<<0)) - svm_enable_lbrv(svm); + svm_enable_lbrv(vcpu); else - svm_disable_lbrv(svm); + svm_disable_lbrv(vcpu); break; case MSR_VM_HSAVE_PA: svm->nested.hsave_msr = data; @@ -2733,6 +2829,33 @@ static int mwait_interception(struct vcpu_svm *svm) return nop_interception(svm); } +static int invpcid_interception(struct vcpu_svm *svm) +{ + struct kvm_vcpu *vcpu = &svm->vcpu; + unsigned long type; + gva_t gva; + + if (!guest_cpuid_has(vcpu, X86_FEATURE_INVPCID)) { + kvm_queue_exception(vcpu, UD_VECTOR); + return 1; + } + + /* + * For an INVPCID intercept: + * EXITINFO1 provides the linear address of the memory operand. + * EXITINFO2 provides the contents of the register operand. + */ + type = svm->vmcb->control.exit_info_2; + gva = svm->vmcb->control.exit_info_1; + + if (type > 3) { + kvm_inject_gp(vcpu, 0); + return 1; + } + + return kvm_handle_invpcid(vcpu, type, gva); +} + static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { [SVM_EXIT_READ_CR0] = cr_interception, [SVM_EXIT_READ_CR3] = cr_interception, @@ -2774,7 +2897,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { [SVM_EXIT_RDPMC] = rdpmc_interception, [SVM_EXIT_CPUID] = cpuid_interception, [SVM_EXIT_IRET] = iret_interception, - [SVM_EXIT_INVD] = emulate_on_interception, + [SVM_EXIT_INVD] = invd_interception, [SVM_EXIT_PAUSE] = pause_interception, [SVM_EXIT_HLT] = halt_interception, [SVM_EXIT_INVLPG] = invlpg_interception, @@ -2795,6 +2918,7 @@ 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_INVPCID] = invpcid_interception, [SVM_EXIT_NPF] = npf_interception, [SVM_EXIT_RSM] = rsm_interception, [SVM_EXIT_AVIC_INCOMPLETE_IPI] = avic_incomplete_ipi_interception, @@ -2813,12 +2937,14 @@ static void dump_vmcb(struct kvm_vcpu *vcpu) } pr_err("VMCB Control Area:\n"); - pr_err("%-20s%04x\n", "cr_read:", control->intercept_cr & 0xffff); - pr_err("%-20s%04x\n", "cr_write:", control->intercept_cr >> 16); - pr_err("%-20s%04x\n", "dr_read:", control->intercept_dr & 0xffff); - pr_err("%-20s%04x\n", "dr_write:", control->intercept_dr >> 16); - pr_err("%-20s%08x\n", "exceptions:", control->intercept_exceptions); - pr_err("%-20s%016llx\n", "intercepts:", control->intercept); + pr_err("%-20s%04x\n", "cr_read:", control->intercepts[INTERCEPT_CR] & 0xffff); + pr_err("%-20s%04x\n", "cr_write:", control->intercepts[INTERCEPT_CR] >> 16); + pr_err("%-20s%04x\n", "dr_read:", control->intercepts[INTERCEPT_DR] & 0xffff); + pr_err("%-20s%04x\n", "dr_write:", control->intercepts[INTERCEPT_DR] >> 16); + pr_err("%-20s%08x\n", "exceptions:", control->intercepts[INTERCEPT_EXCEPTION]); + pr_err("%-20s%08x %08x\n", "intercepts:", + control->intercepts[INTERCEPT_WORD3], + control->intercepts[INTERCEPT_WORD4]); pr_err("%-20s%d\n", "pause filter count:", control->pause_filter_count); pr_err("%-20s%d\n", "pause filter threshold:", control->pause_filter_thresh); @@ -2917,12 +3043,19 @@ static void dump_vmcb(struct kvm_vcpu *vcpu) "excp_to:", save->last_excp_to); } -static void svm_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2) +static void svm_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2, + u32 *intr_info, u32 *error_code) { struct vmcb_control_area *control = &to_svm(vcpu)->vmcb->control; *info1 = control->exit_info_1; *info2 = control->exit_info_2; + *intr_info = control->exit_int_info; + if ((*intr_info & SVM_EXITINTINFO_VALID) && + (*intr_info & SVM_EXITINTINFO_VALID_ERR)) + *error_code = control->exit_int_info_err; + else + *error_code = 0; } static int handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) @@ -2933,22 +3066,15 @@ static int handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) trace_kvm_exit(exit_code, vcpu, KVM_ISA_SVM); - if (!is_cr_intercept(svm, INTERCEPT_CR0_WRITE)) + 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; - svm_complete_interrupts(svm); - if (is_guest_mode(vcpu)) { int vmexit; - trace_kvm_nested_vmexit(svm->vmcb->save.rip, exit_code, - svm->vmcb->control.exit_info_1, - svm->vmcb->control.exit_info_2, - svm->vmcb->control.exit_int_info, - svm->vmcb->control.exit_int_info_err, - KVM_ISA_SVM); + trace_kvm_nested_vmexit(exit_code, vcpu, KVM_ISA_SVM); vmexit = nested_svm_exit_special(svm); @@ -3058,13 +3184,13 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) if (nested_svm_virtualize_tpr(vcpu)) return; - clr_cr_intercept(svm, INTERCEPT_CR8_WRITE); + svm_clr_intercept(svm, INTERCEPT_CR8_WRITE); if (irr == -1) return; if (tpr >= irr) - set_cr_intercept(svm, INTERCEPT_CR8_WRITE); + svm_set_intercept(svm, INTERCEPT_CR8_WRITE); } bool svm_nmi_blocked(struct kvm_vcpu *vcpu) @@ -3252,7 +3378,7 @@ static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu) if (nested_svm_virtualize_tpr(vcpu)) return; - if (!is_cr_intercept(svm, INTERCEPT_CR8_WRITE)) { + if (!svm_is_intercept(svm, INTERCEPT_CR8_WRITE)) { int cr8 = svm->vmcb->control.int_ctl & V_TPR_MASK; kvm_set_cr8(vcpu, cr8); } @@ -3349,8 +3475,7 @@ static void svm_cancel_injection(struct kvm_vcpu *vcpu) static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu) { - if (!is_guest_mode(vcpu) && - to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_MSR && + if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_MSR && to_svm(vcpu)->vmcb->control.exit_info_1) return handle_fastpath_set_msr_irqoff(vcpu); @@ -3415,7 +3540,6 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) { - fastpath_t exit_fastpath; struct vcpu_svm *svm = to_svm(vcpu); svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX]; @@ -3456,9 +3580,7 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) clgi(); kvm_load_guest_xsave_state(vcpu); - if (lapic_in_kernel(vcpu) && - vcpu->arch.apic->lapic_timer.timer_advance_ns) - kvm_wait_lapic_expire(vcpu); + kvm_wait_lapic_expire(vcpu); /* * If this vCPU has touched SPEC_CTRL, restore the guest's value if @@ -3504,7 +3626,6 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) stgi(); /* Any pending NMI will happen here */ - exit_fastpath = svm_exit_handlers_fastpath(vcpu); if (unlikely(svm->vmcb->control.exit_code == SVM_EXIT_NMI)) kvm_after_interrupt(&svm->vcpu); @@ -3518,6 +3639,7 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) } svm->vmcb->control.tlb_ctl = TLB_CONTROL_DO_NOTHING; + vmcb_mark_all_clean(svm->vmcb); /* if exit due to PF check for async PF */ if (svm->vmcb->control.exit_code == SVM_EXIT_EXCP_BASE + PF_VECTOR) @@ -3537,8 +3659,12 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) SVM_EXIT_EXCP_BASE + MC_VECTOR)) svm_handle_mce(svm); - vmcb_mark_all_clean(svm->vmcb); - return exit_fastpath; + svm_complete_interrupts(svm); + + if (is_guest_mode(vcpu)) + return EXIT_FASTPATH_NONE; + + return svm_exit_handlers_fastpath(vcpu); } static void svm_load_mmu_pgd(struct kvm_vcpu *vcpu, unsigned long root, @@ -3624,6 +3750,9 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) svm->nrips_enabled = kvm_cpu_cap_has(X86_FEATURE_NRIPS) && guest_cpuid_has(&svm->vcpu, X86_FEATURE_NRIPS); + /* Check again if INVPCID interception if required */ + svm_check_invpcid(svm); + if (!kvm_vcpu_apicv_active(vcpu)) return; @@ -3738,7 +3867,6 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, break; case SVM_EXIT_WRITE_CR0: { unsigned long cr0, val; - u64 intercept; if (info->intercept == x86_intercept_cr_write) icpt_info.exit_code += info->modrm_reg; @@ -3747,9 +3875,8 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, info->intercept == x86_intercept_clts) break; - intercept = svm->nested.ctl.intercept; - - if (!(intercept & (1ULL << INTERCEPT_SELECTIVE_CR0))) + if (!(vmcb_is_intercept(&svm->nested.ctl, + INTERCEPT_SELECTIVE_CR0))) break; cr0 = vcpu->arch.cr0 & ~SVM_CR0_SELECTIVE_MASK; @@ -3884,7 +4011,7 @@ static int svm_pre_enter_smm(struct kvm_vcpu *vcpu, char *smstate) /* FED8h - SVM Guest */ put_smstate(u64, smstate, 0x7ed8, 1); /* FEE0h - SVM Guest VMCB Physical Address */ - put_smstate(u64, smstate, 0x7ee0, svm->nested.vmcb); + put_smstate(u64, smstate, 0x7ee0, svm->nested.vmcb12_gpa); svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX]; svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP]; @@ -3900,21 +4027,31 @@ static int svm_pre_enter_smm(struct kvm_vcpu *vcpu, char *smstate) static int svm_pre_leave_smm(struct kvm_vcpu *vcpu, const char *smstate) { struct vcpu_svm *svm = to_svm(vcpu); - struct vmcb *nested_vmcb; struct kvm_host_map map; - u64 guest; - u64 vmcb; int ret = 0; - guest = GET_SMSTATE(u64, smstate, 0x7ed8); - vmcb = GET_SMSTATE(u64, smstate, 0x7ee0); + if (guest_cpuid_has(vcpu, X86_FEATURE_LM)) { + u64 saved_efer = GET_SMSTATE(u64, smstate, 0x7ed0); + u64 guest = GET_SMSTATE(u64, smstate, 0x7ed8); + u64 vmcb12_gpa = GET_SMSTATE(u64, smstate, 0x7ee0); - if (guest) { - if (kvm_vcpu_map(&svm->vcpu, gpa_to_gfn(vmcb), &map) == -EINVAL) - return 1; - nested_vmcb = map.hva; - ret = enter_svm_guest_mode(svm, vmcb, nested_vmcb); - kvm_vcpu_unmap(&svm->vcpu, &map, true); + if (guest) { + if (!guest_cpuid_has(vcpu, X86_FEATURE_SVM)) + return 1; + + if (!(saved_efer & EFER_SVME)) + return 1; + + if (kvm_vcpu_map(&svm->vcpu, + gpa_to_gfn(vmcb12_gpa), &map) == -EINVAL) + return 1; + + if (svm_allocate_nested(svm)) + return 1; + + ret = enter_svm_guest_mode(svm, vmcb12_gpa, map.hva); + kvm_vcpu_unmap(&svm->vcpu, &map, true); + } } return ret; @@ -3933,19 +4070,10 @@ static void enable_smi_window(struct kvm_vcpu *vcpu) } } -static bool svm_need_emulation_on_page_fault(struct kvm_vcpu *vcpu) +static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, void *insn, int insn_len) { - unsigned long cr4 = kvm_read_cr4(vcpu); - bool smep = cr4 & X86_CR4_SMEP; - bool smap = cr4 & X86_CR4_SMAP; - bool is_user = svm_get_cpl(vcpu) == 3; - - /* - * If RIP is invalid, go ahead with emulation which will cause an - * internal error exit. - */ - if (!kvm_vcpu_gfn_to_memslot(vcpu, kvm_rip_read(vcpu) >> PAGE_SHIFT)) - return true; + bool smep, smap, is_user; + unsigned long cr4; /* * Detect and workaround Errata 1096 Fam_17h_00_0Fh. @@ -3987,6 +4115,20 @@ static bool svm_need_emulation_on_page_fault(struct kvm_vcpu *vcpu) * instruction pointer so we will not able to workaround it. Lets * print the error and request to kill the guest. */ + if (likely(!insn || insn_len)) + return true; + + /* + * If RIP is invalid, go ahead with emulation which will cause an + * internal error exit. + */ + if (!kvm_vcpu_gfn_to_memslot(vcpu, kvm_rip_read(vcpu) >> PAGE_SHIFT)) + return true; + + cr4 = kvm_read_cr4(vcpu); + smep = cr4 & X86_CR4_SMEP; + smap = cr4 & X86_CR4_SMAP; + is_user = svm_get_cpl(vcpu) == 3; if (smap && (!smep || is_user)) { if (!sev_guest(vcpu->kvm)) return true; @@ -4010,7 +4152,7 @@ static bool svm_apic_init_signal_blocked(struct kvm_vcpu *vcpu) * if an INIT signal is pending. */ return !gif_set(svm) || - (svm->vmcb->control.intercept & (1ULL << INTERCEPT_INIT)); + (vmcb_is_intercept(&svm->vmcb->control, INTERCEPT_INIT)); } static void svm_vm_destroy(struct kvm *kvm) @@ -4148,9 +4290,11 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { .mem_enc_reg_region = svm_register_enc_region, .mem_enc_unreg_region = svm_unregister_enc_region, - .need_emulation_on_page_fault = svm_need_emulation_on_page_fault, + .can_emulate_instruction = svm_can_emulate_instruction, .apic_init_signal_blocked = svm_apic_init_signal_blocked, + + .msr_filter_changed = svm_msr_filter_changed, }; static struct kvm_x86_init_ops svm_init_ops __initdata = { @@ -4164,6 +4308,8 @@ static struct kvm_x86_init_ops svm_init_ops __initdata = { static int __init svm_init(void) { + __unused_size_checks(); + return kvm_init(&svm_init_ops, sizeof(struct vcpu_svm), __alignof__(struct vcpu_svm), THIS_MODULE); } diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index a798e1731709..1d853fe4c778 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -31,6 +31,7 @@ static const u32 host_save_user_msrs[] = { #define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs) +#define MAX_DIRECT_ACCESS_MSRS 15 #define MSRPM_OFFSETS 16 extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly; extern bool npt_enabled; @@ -85,8 +86,7 @@ struct svm_nested_state { struct vmcb *hsave; u64 hsave_msr; u64 vm_cr_msr; - u64 vmcb; - u32 host_intercept_exceptions; + u64 vmcb12_gpa; /* These are the merged vectors */ u32 *msrpm; @@ -97,6 +97,8 @@ struct svm_nested_state { /* cache for control fields of the guest */ struct vmcb_control_area ctl; + + bool initialized; }; struct vcpu_svm { @@ -158,6 +160,12 @@ struct vcpu_svm { */ struct list_head ir_list; spinlock_t ir_list_lock; + + /* Save desired MSR intercept (read: pass-through) state */ + struct { + DECLARE_BITMAP(read, MAX_DIRECT_ACCESS_MSRS); + DECLARE_BITMAP(write, MAX_DIRECT_ACCESS_MSRS); + } shadow_msr_intercept; }; struct svm_cpu_data { @@ -214,51 +222,44 @@ static inline struct vmcb *get_host_vmcb(struct vcpu_svm *svm) return svm->vmcb; } -static inline void set_cr_intercept(struct vcpu_svm *svm, int bit) +static inline void vmcb_set_intercept(struct vmcb_control_area *control, u32 bit) { - struct vmcb *vmcb = get_host_vmcb(svm); - - vmcb->control.intercept_cr |= (1U << bit); - - recalc_intercepts(svm); + WARN_ON_ONCE(bit >= 32 * MAX_INTERCEPT); + __set_bit(bit, (unsigned long *)&control->intercepts); } -static inline void clr_cr_intercept(struct vcpu_svm *svm, int bit) +static inline void vmcb_clr_intercept(struct vmcb_control_area *control, u32 bit) { - struct vmcb *vmcb = get_host_vmcb(svm); - - vmcb->control.intercept_cr &= ~(1U << bit); - - recalc_intercepts(svm); + WARN_ON_ONCE(bit >= 32 * MAX_INTERCEPT); + __clear_bit(bit, (unsigned long *)&control->intercepts); } -static inline bool is_cr_intercept(struct vcpu_svm *svm, int bit) +static inline bool vmcb_is_intercept(struct vmcb_control_area *control, u32 bit) { - struct vmcb *vmcb = get_host_vmcb(svm); - - return vmcb->control.intercept_cr & (1U << bit); + WARN_ON_ONCE(bit >= 32 * MAX_INTERCEPT); + return test_bit(bit, (unsigned long *)&control->intercepts); } static inline void set_dr_intercepts(struct vcpu_svm *svm) { struct vmcb *vmcb = get_host_vmcb(svm); - vmcb->control.intercept_dr = (1 << INTERCEPT_DR0_READ) - | (1 << INTERCEPT_DR1_READ) - | (1 << INTERCEPT_DR2_READ) - | (1 << INTERCEPT_DR3_READ) - | (1 << INTERCEPT_DR4_READ) - | (1 << INTERCEPT_DR5_READ) - | (1 << INTERCEPT_DR6_READ) - | (1 << INTERCEPT_DR7_READ) - | (1 << INTERCEPT_DR0_WRITE) - | (1 << INTERCEPT_DR1_WRITE) - | (1 << INTERCEPT_DR2_WRITE) - | (1 << INTERCEPT_DR3_WRITE) - | (1 << INTERCEPT_DR4_WRITE) - | (1 << INTERCEPT_DR5_WRITE) - | (1 << INTERCEPT_DR6_WRITE) - | (1 << INTERCEPT_DR7_WRITE); + 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_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); } @@ -267,25 +268,27 @@ static inline void clr_dr_intercepts(struct vcpu_svm *svm) { struct vmcb *vmcb = get_host_vmcb(svm); - vmcb->control.intercept_dr = 0; + vmcb->control.intercepts[INTERCEPT_DR] = 0; recalc_intercepts(svm); } -static inline void set_exception_intercept(struct vcpu_svm *svm, int bit) +static inline void set_exception_intercept(struct vcpu_svm *svm, u32 bit) { struct vmcb *vmcb = get_host_vmcb(svm); - vmcb->control.intercept_exceptions |= (1U << bit); + WARN_ON_ONCE(bit >= 32); + vmcb_set_intercept(&vmcb->control, INTERCEPT_EXCEPTION_OFFSET + bit); recalc_intercepts(svm); } -static inline void clr_exception_intercept(struct vcpu_svm *svm, int bit) +static inline void clr_exception_intercept(struct vcpu_svm *svm, u32 bit) { struct vmcb *vmcb = get_host_vmcb(svm); - vmcb->control.intercept_exceptions &= ~(1U << bit); + WARN_ON_ONCE(bit >= 32); + vmcb_clr_intercept(&vmcb->control, INTERCEPT_EXCEPTION_OFFSET + bit); recalc_intercepts(svm); } @@ -294,7 +297,7 @@ static inline void svm_set_intercept(struct vcpu_svm *svm, int bit) { struct vmcb *vmcb = get_host_vmcb(svm); - vmcb->control.intercept |= (1ULL << bit); + vmcb_set_intercept(&vmcb->control, bit); recalc_intercepts(svm); } @@ -303,14 +306,14 @@ static inline void svm_clr_intercept(struct vcpu_svm *svm, int bit) { struct vmcb *vmcb = get_host_vmcb(svm); - vmcb->control.intercept &= ~(1ULL << bit); + vmcb_clr_intercept(&vmcb->control, bit); recalc_intercepts(svm); } static inline bool svm_is_intercept(struct vcpu_svm *svm, int bit) { - return (svm->vmcb->control.intercept & (1ULL << bit)) != 0; + return vmcb_is_intercept(&svm->vmcb->control, bit); } static inline bool vgif_enabled(struct vcpu_svm *svm) @@ -345,11 +348,15 @@ static inline bool gif_set(struct vcpu_svm *svm) /* svm.c */ #define MSR_CR3_LEGACY_RESERVED_MASK 0xfe7U #define MSR_CR3_LEGACY_PAE_RESERVED_MASK 0x7U -#define MSR_CR3_LONG_RESERVED_MASK 0xfff0000000000fe7U +#define MSR_CR3_LONG_MBZ_MASK 0xfff0000000000000U #define MSR_INVALID 0xffffffffU u32 svm_msrpm_offset(u32 msr); -void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer); +u32 *svm_vcpu_alloc_msrpm(void); +void svm_vcpu_init_msrpm(struct kvm_vcpu *vcpu, u32 *msrpm); +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_flush_tlb(struct kvm_vcpu *vcpu); @@ -374,22 +381,24 @@ static inline bool nested_svm_virtualize_tpr(struct kvm_vcpu *vcpu) static inline bool nested_exit_on_smi(struct vcpu_svm *svm) { - return (svm->nested.ctl.intercept & (1ULL << INTERCEPT_SMI)); + return vmcb_is_intercept(&svm->nested.ctl, INTERCEPT_SMI); } static inline bool nested_exit_on_intr(struct vcpu_svm *svm) { - return (svm->nested.ctl.intercept & (1ULL << INTERCEPT_INTR)); + return vmcb_is_intercept(&svm->nested.ctl, INTERCEPT_INTR); } static inline bool nested_exit_on_nmi(struct vcpu_svm *svm) { - return (svm->nested.ctl.intercept & (1ULL << INTERCEPT_NMI)); + return vmcb_is_intercept(&svm->nested.ctl, INTERCEPT_NMI); } int enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb_gpa, struct vmcb *nested_vmcb); void svm_leave_nested(struct vcpu_svm *svm); +void svm_free_nested(struct vcpu_svm *svm); +int svm_allocate_nested(struct vcpu_svm *svm); int nested_svm_vmrun(struct vcpu_svm *svm); void nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb); int nested_svm_vmexit(struct vcpu_svm *svm); diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index b66432b015d2..aef960f90f26 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -15,18 +15,20 @@ * Tracepoint for guest mode entry. */ TRACE_EVENT(kvm_entry, - TP_PROTO(unsigned int vcpu_id), - TP_ARGS(vcpu_id), + TP_PROTO(struct kvm_vcpu *vcpu), + TP_ARGS(vcpu), TP_STRUCT__entry( __field( unsigned int, vcpu_id ) + __field( unsigned long, rip ) ), TP_fast_assign( - __entry->vcpu_id = vcpu_id; + __entry->vcpu_id = vcpu->vcpu_id; + __entry->rip = kvm_rip_read(vcpu); ), - TP_printk("vcpu %u", __entry->vcpu_id) + TP_printk("vcpu %u, rip 0x%lx", __entry->vcpu_id, __entry->rip) ); /* @@ -233,36 +235,45 @@ TRACE_EVENT(kvm_apic, (isa == KVM_ISA_VMX) ? \ __print_flags(exit_reason & ~0xffff, " ", VMX_EXIT_REASON_FLAGS) : "" +#define TRACE_EVENT_KVM_EXIT(name) \ +TRACE_EVENT(name, \ + TP_PROTO(unsigned int exit_reason, struct kvm_vcpu *vcpu, u32 isa), \ + TP_ARGS(exit_reason, vcpu, isa), \ + \ + TP_STRUCT__entry( \ + __field( unsigned int, exit_reason ) \ + __field( unsigned long, guest_rip ) \ + __field( u32, isa ) \ + __field( u64, info1 ) \ + __field( u64, info2 ) \ + __field( u32, intr_info ) \ + __field( u32, error_code ) \ + __field( unsigned int, vcpu_id ) \ + ), \ + \ + TP_fast_assign( \ + __entry->exit_reason = exit_reason; \ + __entry->guest_rip = kvm_rip_read(vcpu); \ + __entry->isa = isa; \ + __entry->vcpu_id = vcpu->vcpu_id; \ + kvm_x86_ops.get_exit_info(vcpu, &__entry->info1, \ + &__entry->info2, \ + &__entry->intr_info, \ + &__entry->error_code); \ + ), \ + \ + TP_printk("vcpu %u reason %s%s%s rip 0x%lx info1 0x%016llx " \ + "info2 0x%016llx intr_info 0x%08x error_code 0x%08x", \ + __entry->vcpu_id, \ + kvm_print_exit_reason(__entry->exit_reason, __entry->isa), \ + __entry->guest_rip, __entry->info1, __entry->info2, \ + __entry->intr_info, __entry->error_code) \ +) + /* * Tracepoint for kvm guest exit: */ -TRACE_EVENT(kvm_exit, - TP_PROTO(unsigned int exit_reason, struct kvm_vcpu *vcpu, u32 isa), - TP_ARGS(exit_reason, vcpu, isa), - - TP_STRUCT__entry( - __field( unsigned int, exit_reason ) - __field( unsigned long, guest_rip ) - __field( u32, isa ) - __field( u64, info1 ) - __field( u64, info2 ) - __field( unsigned int, vcpu_id ) - ), - - TP_fast_assign( - __entry->exit_reason = exit_reason; - __entry->guest_rip = kvm_rip_read(vcpu); - __entry->isa = isa; - __entry->vcpu_id = vcpu->vcpu_id; - kvm_x86_ops.get_exit_info(vcpu, &__entry->info1, - &__entry->info2); - ), - - TP_printk("vcpu %u reason %s%s%s rip 0x%lx info %llx %llx", - __entry->vcpu_id, - kvm_print_exit_reason(__entry->exit_reason, __entry->isa), - __entry->guest_rip, __entry->info1, __entry->info2) -); +TRACE_EVENT_KVM_EXIT(kvm_exit); /* * Tracepoint for kvm interrupt injection: @@ -544,63 +555,38 @@ TRACE_EVENT(kvm_nested_vmrun, ); TRACE_EVENT(kvm_nested_intercepts, - TP_PROTO(__u16 cr_read, __u16 cr_write, __u32 exceptions, __u64 intercept), - TP_ARGS(cr_read, cr_write, exceptions, intercept), + TP_PROTO(__u16 cr_read, __u16 cr_write, __u32 exceptions, + __u32 intercept1, __u32 intercept2, __u32 intercept3), + TP_ARGS(cr_read, cr_write, exceptions, intercept1, + intercept2, intercept3), TP_STRUCT__entry( __field( __u16, cr_read ) __field( __u16, cr_write ) __field( __u32, exceptions ) - __field( __u64, intercept ) + __field( __u32, intercept1 ) + __field( __u32, intercept2 ) + __field( __u32, intercept3 ) ), TP_fast_assign( __entry->cr_read = cr_read; __entry->cr_write = cr_write; __entry->exceptions = exceptions; - __entry->intercept = intercept; + __entry->intercept1 = intercept1; + __entry->intercept2 = intercept2; + __entry->intercept3 = intercept3; ), - TP_printk("cr_read: %04x cr_write: %04x excp: %08x intercept: %016llx", - __entry->cr_read, __entry->cr_write, __entry->exceptions, - __entry->intercept) + TP_printk("cr_read: %04x cr_write: %04x excp: %08x " + "intercepts: %08x %08x %08x", + __entry->cr_read, __entry->cr_write, __entry->exceptions, + __entry->intercept1, __entry->intercept2, __entry->intercept3) ); /* * Tracepoint for #VMEXIT while nested */ -TRACE_EVENT(kvm_nested_vmexit, - TP_PROTO(__u64 rip, __u32 exit_code, - __u64 exit_info1, __u64 exit_info2, - __u32 exit_int_info, __u32 exit_int_info_err, __u32 isa), - TP_ARGS(rip, exit_code, exit_info1, exit_info2, - exit_int_info, exit_int_info_err, isa), - - TP_STRUCT__entry( - __field( __u64, rip ) - __field( __u32, exit_code ) - __field( __u64, exit_info1 ) - __field( __u64, exit_info2 ) - __field( __u32, exit_int_info ) - __field( __u32, exit_int_info_err ) - __field( __u32, isa ) - ), - - TP_fast_assign( - __entry->rip = rip; - __entry->exit_code = exit_code; - __entry->exit_info1 = exit_info1; - __entry->exit_info2 = exit_info2; - __entry->exit_int_info = exit_int_info; - __entry->exit_int_info_err = exit_int_info_err; - __entry->isa = isa; - ), - TP_printk("rip: 0x%016llx reason: %s%s%s ext_inf1: 0x%016llx " - "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x", - __entry->rip, - kvm_print_exit_reason(__entry->exit_code, __entry->isa), - __entry->exit_info1, __entry->exit_info2, - __entry->exit_int_info, __entry->exit_int_info_err) -); +TRACE_EVENT_KVM_EXIT(kvm_nested_vmexit); /* * Tracepoint for #VMEXIT reinjected to the guest diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h index 4bbd8b448d22..3a1861403d73 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -151,7 +151,7 @@ static inline bool vmx_umip_emulated(void) static inline bool cpu_has_vmx_rdtscp(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & - SECONDARY_EXEC_RDTSCP; + SECONDARY_EXEC_ENABLE_RDTSCP; } static inline bool cpu_has_vmx_virtualize_x2apic_mode(void) @@ -196,7 +196,7 @@ static inline bool cpu_has_vmx_ple(void) SECONDARY_EXEC_PAUSE_LOOP_EXITING; } -static inline bool vmx_rdrand_supported(void) +static inline bool cpu_has_vmx_rdrand(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_RDRAND_EXITING; @@ -233,7 +233,7 @@ static inline bool cpu_has_vmx_encls_vmexit(void) SECONDARY_EXEC_ENCLS_EXITING; } -static inline bool vmx_rdseed_supported(void) +static inline bool cpu_has_vmx_rdseed(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_RDSEED_EXITING; @@ -244,13 +244,13 @@ static inline bool cpu_has_vmx_pml(void) return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_ENABLE_PML; } -static inline bool vmx_xsaves_supported(void) +static inline bool cpu_has_vmx_xsaves(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_XSAVES; } -static inline bool vmx_waitpkg_supported(void) +static inline bool cpu_has_vmx_waitpkg(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE; diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 23b58c28a1c9..89af692deb7e 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 -#include <linux/frame.h> +#include <linux/objtool.h> #include <linux/percpu.h> #include <asm/debugreg.h> @@ -233,6 +233,44 @@ static inline void nested_release_evmcs(struct kvm_vcpu *vcpu) vmx->nested.hv_evmcs = NULL; } +static void vmx_sync_vmcs_host_state(struct vcpu_vmx *vmx, + struct loaded_vmcs *prev) +{ + struct vmcs_host_state *dest, *src; + + if (unlikely(!vmx->guest_state_loaded)) + return; + + src = &prev->host_state; + dest = &vmx->loaded_vmcs->host_state; + + vmx_set_host_fs_gs(dest, src->fs_sel, src->gs_sel, src->fs_base, src->gs_base); + dest->ldt_sel = src->ldt_sel; +#ifdef CONFIG_X86_64 + dest->ds_sel = src->ds_sel; + dest->es_sel = src->es_sel; +#endif +} + +static void vmx_switch_vmcs(struct kvm_vcpu *vcpu, struct loaded_vmcs *vmcs) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + struct loaded_vmcs *prev; + int cpu; + + if (WARN_ON_ONCE(vmx->loaded_vmcs == vmcs)) + return; + + cpu = get_cpu(); + prev = vmx->loaded_vmcs; + vmx->loaded_vmcs = vmcs; + vmx_vcpu_load_vmcs(vcpu, cpu, prev); + vmx_sync_vmcs_host_state(vmx, prev); + put_cpu(); + + vmx_register_cache_reset(vcpu); +} + /* * Free whatever needs to be freed from vmx->nested when L1 goes down, or * just stops using VMX. @@ -241,10 +279,13 @@ static void free_nested(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); + if (WARN_ON_ONCE(vmx->loaded_vmcs != &vmx->vmcs01)) + vmx_switch_vmcs(vcpu, &vmx->vmcs01); + if (!vmx->nested.vmxon && !vmx->nested.smm.vmxon) return; - kvm_clear_request(KVM_REQ_GET_VMCS12_PAGES, vcpu); + kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); vmx->nested.vmxon = false; vmx->nested.smm.vmxon = false; @@ -277,44 +318,6 @@ static void free_nested(struct kvm_vcpu *vcpu) free_loaded_vmcs(&vmx->nested.vmcs02); } -static void vmx_sync_vmcs_host_state(struct vcpu_vmx *vmx, - struct loaded_vmcs *prev) -{ - struct vmcs_host_state *dest, *src; - - if (unlikely(!vmx->guest_state_loaded)) - return; - - src = &prev->host_state; - dest = &vmx->loaded_vmcs->host_state; - - vmx_set_host_fs_gs(dest, src->fs_sel, src->gs_sel, src->fs_base, src->gs_base); - dest->ldt_sel = src->ldt_sel; -#ifdef CONFIG_X86_64 - dest->ds_sel = src->ds_sel; - dest->es_sel = src->es_sel; -#endif -} - -static void vmx_switch_vmcs(struct kvm_vcpu *vcpu, struct loaded_vmcs *vmcs) -{ - struct vcpu_vmx *vmx = to_vmx(vcpu); - struct loaded_vmcs *prev; - int cpu; - - if (vmx->loaded_vmcs == vmcs) - return; - - cpu = get_cpu(); - prev = vmx->loaded_vmcs; - vmx->loaded_vmcs = vmcs; - vmx_vcpu_load_vmcs(vcpu, cpu, prev); - vmx_sync_vmcs_host_state(vmx, prev); - put_cpu(); - - vmx_register_cache_reset(vcpu); -} - /* * Ensure that the current vmcs of the logical processor is the * vmcs01 of the vcpu before calling free_nested(). @@ -323,8 +326,6 @@ void nested_vmx_free_vcpu(struct kvm_vcpu *vcpu) { vcpu_load(vcpu); vmx_leave_nested(vcpu); - vmx_switch_vmcs(vcpu, &to_vmx(vcpu)->vmcs01); - free_nested(vcpu); vcpu_put(vcpu); } @@ -938,11 +939,11 @@ static bool nested_vmx_get_vmexit_msr_value(struct kvm_vcpu *vcpu, * VM-exit in L0, use the more accurate value. */ if (msr_index == MSR_IA32_TSC) { - int index = vmx_find_msr_index(&vmx->msr_autostore.guest, - MSR_IA32_TSC); + int i = vmx_find_loadstore_msr_slot(&vmx->msr_autostore.guest, + MSR_IA32_TSC); - if (index >= 0) { - u64 val = vmx->msr_autostore.guest.val[index].value; + if (i >= 0) { + u64 val = vmx->msr_autostore.guest.val[i].value; *data = kvm_read_l1_tsc(vcpu, val); return true; @@ -1031,16 +1032,16 @@ static void prepare_vmx_msr_autostore_list(struct kvm_vcpu *vcpu, struct vcpu_vmx *vmx = to_vmx(vcpu); struct vmx_msrs *autostore = &vmx->msr_autostore.guest; bool in_vmcs12_store_list; - int msr_autostore_index; + int msr_autostore_slot; bool in_autostore_list; int last; - msr_autostore_index = vmx_find_msr_index(autostore, msr_index); - in_autostore_list = msr_autostore_index >= 0; + msr_autostore_slot = vmx_find_loadstore_msr_slot(autostore, msr_index); + in_autostore_list = msr_autostore_slot >= 0; in_vmcs12_store_list = nested_msr_store_list_has_msr(vcpu, msr_index); if (in_vmcs12_store_list && !in_autostore_list) { - if (autostore->nr == NR_LOADSTORE_MSRS) { + if (autostore->nr == MAX_NR_LOADSTORE_MSRS) { /* * Emulated VMEntry does not fail here. Instead a less * accurate value will be returned by @@ -1057,7 +1058,7 @@ static void prepare_vmx_msr_autostore_list(struct kvm_vcpu *vcpu, autostore->val[last].index = msr_index; } else if (!in_vmcs12_store_list && in_autostore_list) { last = --autostore->nr; - autostore->val[msr_autostore_index] = autostore->val[last]; + autostore->val[msr_autostore_slot] = autostore->val[last]; } } @@ -2286,7 +2287,7 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) /* Take the following fields only from vmcs12 */ exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | SECONDARY_EXEC_ENABLE_INVPCID | - SECONDARY_EXEC_RDTSCP | + SECONDARY_EXEC_ENABLE_RDTSCP | SECONDARY_EXEC_XSAVES | SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | @@ -2314,6 +2315,9 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) vmcs_write16(GUEST_INTR_STATUS, vmcs12->guest_intr_status); + if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_UNRESTRICTED_GUEST)) + exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST; + secondary_exec_controls_set(vmx, exec_control); } @@ -2408,6 +2412,8 @@ static void prepare_vmcs02_rare(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) vmcs_writel(GUEST_TR_BASE, vmcs12->guest_tr_base); vmcs_writel(GUEST_GDTR_BASE, vmcs12->guest_gdtr_base); vmcs_writel(GUEST_IDTR_BASE, vmcs12->guest_idtr_base); + + vmx->segment_cache.bitmask = 0; } if (!hv_evmcs || !(hv_evmcs->hv_clean_fields & @@ -2571,7 +2577,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, * which means L1 attempted VMEntry to L2 with invalid state. * Fail the VMEntry. */ - if (vmx->emulation_required) { + if (CC(!vmx_guest_state_valid(vcpu))) { *entry_failure_code = ENTRY_FAIL_DEFAULT; return -EINVAL; } @@ -3344,8 +3350,10 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, prepare_vmcs02_early(vmx, vmcs12); if (from_vmentry) { - if (unlikely(!nested_get_vmcs12_pages(vcpu))) + if (unlikely(!nested_get_vmcs12_pages(vcpu))) { + vmx_switch_vmcs(vcpu, &vmx->vmcs01); return NVMX_VMENTRY_KVM_INTERNAL_ERROR; + } if (nested_vmx_check_vmentry_hw(vcpu)) { vmx_switch_vmcs(vcpu, &vmx->vmcs01); @@ -3387,7 +3395,7 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, * to nested_get_vmcs12_pages before the next VM-entry. The MSRs * have already been set at vmentry time and should not be reset. */ - kvm_make_request(KVM_REQ_GET_VMCS12_PAGES, vcpu); + kvm_make_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); } /* @@ -3468,11 +3476,11 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) if (evmptrld_status == EVMPTRLD_ERROR) { kvm_queue_exception(vcpu, UD_VECTOR); return 1; - } else if (evmptrld_status == EVMPTRLD_VMFAIL) { + } else if (CC(evmptrld_status == EVMPTRLD_VMFAIL)) { return nested_vmx_failInvalid(vcpu); } - if (!vmx->nested.hv_evmcs && vmx->nested.current_vmptr == -1ull) + if (CC(!vmx->nested.hv_evmcs && vmx->nested.current_vmptr == -1ull)) return nested_vmx_failInvalid(vcpu); vmcs12 = get_vmcs12(vcpu); @@ -3483,7 +3491,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) * rather than RFLAGS.ZF, and no error number is stored to the * VM-instruction error field. */ - if (vmcs12->hdr.shadow_vmcs) + if (CC(vmcs12->hdr.shadow_vmcs)) return nested_vmx_failInvalid(vcpu); if (vmx->nested.hv_evmcs) { @@ -3504,10 +3512,10 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) * for misconfigurations which will anyway be caught by the processor * when using the merged vmcs02. */ - if (interrupt_shadow & KVM_X86_SHADOW_INT_MOV_SS) + if (CC(interrupt_shadow & KVM_X86_SHADOW_INT_MOV_SS)) return nested_vmx_fail(vcpu, VMXERR_ENTRY_EVENTS_BLOCKED_BY_MOV_SS); - if (vmcs12->launch_state == launch) + if (CC(vmcs12->launch_state == launch)) return nested_vmx_fail(vcpu, launch ? VMXERR_VMLAUNCH_NONCLEAR_VMCS : VMXERR_VMRESUME_NONLAUNCHED_VMCS); @@ -3528,6 +3536,14 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) if (unlikely(status != NVMX_VMENTRY_SUCCESS)) goto vmentry_failed; + /* Emulate processing of posted interrupts on VM-Enter. */ + if (nested_cpu_has_posted_intr(vmcs12) && + kvm_apic_has_interrupt(vcpu) == vmx->nested.posted_intr_nv) { + vmx->nested.pi_pending = true; + kvm_make_request(KVM_REQ_EVENT, vcpu); + kvm_apic_clear_irr(vcpu, vmx->nested.posted_intr_nv); + } + /* Hide L1D cache contents from the nested guest. */ vmx->vcpu.arch.l1tf_flush_l1d = true; @@ -4257,7 +4273,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, static inline u64 nested_vmx_get_vmcs01_guest_efer(struct vcpu_vmx *vmx) { - struct shared_msr_entry *efer_msr; + struct vmx_uret_msr *efer_msr; unsigned int i; if (vm_entry_controls_get(vmx) & VM_ENTRY_LOAD_IA32_EFER) @@ -4271,7 +4287,7 @@ static inline u64 nested_vmx_get_vmcs01_guest_efer(struct vcpu_vmx *vmx) return vmx->msr_autoload.guest.val[i].value; } - efer_msr = find_msr_entry(vmx, MSR_EFER); + efer_msr = vmx_find_uret_msr(vmx, MSR_EFER); if (efer_msr) return efer_msr->data; @@ -4404,6 +4420,14 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) kvm_vcpu_flush_tlb_current(vcpu); + /* + * VCPU_EXREG_PDPTR will be clobbered in arch/x86/kvm/vmx/vmx.h between + * now and the new vmentry. Ensure that the VMCS02 PDPTR fields are + * up-to-date before switching to L1. + */ + if (enable_ept && is_pae_paging(vcpu)) + vmx_ept_load_pdptrs(vcpu); + leave_guest_mode(vcpu); if (nested_cpu_has_preemption_timer(vmcs12)) @@ -4668,7 +4692,7 @@ void nested_vmx_pmu_entry_exit_ctls_update(struct kvm_vcpu *vcpu) vmx->nested.msrs.entry_ctls_high &= ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL; vmx->nested.msrs.exit_ctls_high &= - ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL; + ~VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL; } } @@ -4688,7 +4712,7 @@ static int nested_vmx_get_vmptr(struct kvm_vcpu *vcpu, gpa_t *vmpointer, r = kvm_read_guest_virt(vcpu, gva, vmpointer, sizeof(*vmpointer), &e); if (r != X86EMUL_CONTINUE) { - *ret = vmx_handle_memory_failure(vcpu, r, &e); + *ret = kvm_handle_memory_failure(vcpu, r, &e); return -EINVAL; } @@ -4752,7 +4776,7 @@ static int enter_vmx_operation(struct kvm_vcpu *vcpu) if (vmx_pt_mode_is_host_guest()) { vmx->pt_desc.guest.ctl = 0; - pt_update_intercept_for_msr(vmx); + pt_update_intercept_for_msr(vcpu); } return 0; @@ -4995,7 +5019,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu) /* _system ok, nested_vmx_check_permission has verified cpl=0 */ r = kvm_write_guest_virt_system(vcpu, gva, &value, len, &e); if (r != X86EMUL_CONTINUE) - return vmx_handle_memory_failure(vcpu, r, &e); + return kvm_handle_memory_failure(vcpu, r, &e); } return nested_vmx_succeed(vcpu); @@ -5068,7 +5092,7 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) return 1; r = kvm_read_guest_virt(vcpu, gva, &value, len, &e); if (r != X86EMUL_CONTINUE) - return vmx_handle_memory_failure(vcpu, r, &e); + return kvm_handle_memory_failure(vcpu, r, &e); } field = kvm_register_readl(vcpu, (((instr_info) >> 28) & 0xf)); @@ -5230,7 +5254,7 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu) r = kvm_write_guest_virt_system(vcpu, gva, (void *)¤t_vmptr, sizeof(gpa_t), &e); if (r != X86EMUL_CONTINUE) - return vmx_handle_memory_failure(vcpu, r, &e); + return kvm_handle_memory_failure(vcpu, r, &e); return nested_vmx_succeed(vcpu); } @@ -5283,7 +5307,7 @@ static int handle_invept(struct kvm_vcpu *vcpu) return 1; r = kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e); if (r != X86EMUL_CONTINUE) - return vmx_handle_memory_failure(vcpu, r, &e); + return kvm_handle_memory_failure(vcpu, r, &e); /* * Nested EPT roots are always held through guest_mmu, @@ -5365,7 +5389,7 @@ static int handle_invvpid(struct kvm_vcpu *vcpu) return 1; r = kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e); if (r != X86EMUL_CONTINUE) - return vmx_handle_memory_failure(vcpu, r, &e); + return kvm_handle_memory_failure(vcpu, r, &e); if (operand.vpid >> 16) return nested_vmx_fail(vcpu, @@ -5910,13 +5934,7 @@ bool nested_vmx_reflect_vmexit(struct kvm_vcpu *vcpu) goto reflect_vmexit; } - exit_intr_info = vmx_get_intr_info(vcpu); - exit_qual = vmx_get_exit_qual(vcpu); - - trace_kvm_nested_vmexit(kvm_rip_read(vcpu), exit_reason, exit_qual, - vmx->idt_vectoring_info, exit_intr_info, - vmcs_read32(VM_EXIT_INTR_ERROR_CODE), - KVM_ISA_VMX); + trace_kvm_nested_vmexit(exit_reason, vcpu, KVM_ISA_VMX); /* If L0 (KVM) wants the exit, it trumps L1's desires. */ if (nested_vmx_l0_wants_exit(vcpu, exit_reason)) @@ -5932,14 +5950,14 @@ bool nested_vmx_reflect_vmexit(struct kvm_vcpu *vcpu) * need to be synthesized by querying the in-kernel LAPIC, but external * interrupts are never reflected to L1 so it's a non-issue. */ - if ((exit_intr_info & - (INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK)) == - (INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK)) { + exit_intr_info = vmx_get_intr_info(vcpu); + if (is_exception_with_error_code(exit_intr_info)) { struct vmcs12 *vmcs12 = get_vmcs12(vcpu); vmcs12->vm_exit_intr_error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE); } + exit_qual = vmx_get_exit_qual(vcpu); reflect_vmexit: nested_vmx_vmexit(vcpu, exit_reason, exit_intr_info, exit_qual); @@ -6174,7 +6192,7 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, * restored yet. EVMCS will be mapped from * nested_get_vmcs12_pages(). */ - kvm_make_request(KVM_REQ_GET_VMCS12_PAGES, vcpu); + kvm_make_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); } else { return -EINVAL; } @@ -6310,7 +6328,8 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps) #ifdef CONFIG_X86_64 VM_EXIT_HOST_ADDR_SPACE_SIZE | #endif - VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT; + VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT | + VM_EXIT_CLEAR_BNDCFGS | VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL; msrs->exit_ctls_high |= VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER | @@ -6329,7 +6348,8 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps) #ifdef CONFIG_X86_64 VM_ENTRY_IA32E_MODE | #endif - VM_ENTRY_LOAD_IA32_PAT; + VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_LOAD_BNDCFGS | + VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL; msrs->entry_ctls_high |= (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | VM_ENTRY_LOAD_IA32_EFER); @@ -6383,7 +6403,7 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps) msrs->secondary_ctls_low = 0; msrs->secondary_ctls_high &= SECONDARY_EXEC_DESC | - SECONDARY_EXEC_RDTSCP | + SECONDARY_EXEC_ENABLE_RDTSCP | SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | SECONDARY_EXEC_WBINVD_EXITING | SECONDARY_EXEC_APIC_REGISTER_VIRT | @@ -6553,7 +6573,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_vmcs12_pages = nested_get_vmcs12_pages, + .get_nested_state_pages = nested_get_vmcs12_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/posted_intr.c b/arch/x86/kvm/vmx/posted_intr.c new file mode 100644 index 000000000000..f02962dcc72c --- /dev/null +++ b/arch/x86/kvm/vmx/posted_intr.c @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include <linux/kvm_host.h> + +#include <asm/irq_remapping.h> +#include <asm/cpu.h> + +#include "lapic.h" +#include "posted_intr.h" +#include "trace.h" +#include "vmx.h" + +/* + * We maintian a per-CPU linked-list of vCPU, so in wakeup_handler() we + * can find which vCPU should be waken up. + */ +static DEFINE_PER_CPU(struct list_head, blocked_vcpu_on_cpu); +static DEFINE_PER_CPU(spinlock_t, blocked_vcpu_on_cpu_lock); + +static inline struct pi_desc *vcpu_to_pi_desc(struct kvm_vcpu *vcpu) +{ + return &(to_vmx(vcpu)->pi_desc); +} + +void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu) +{ + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); + struct pi_desc old, new; + unsigned int dest; + + /* + * In case of hot-plug or hot-unplug, we may have to undo + * vmx_vcpu_pi_put even if there is no assigned device. And we + * always keep PI.NDST up to date for simplicity: it makes the + * code easier, and CPU migration is not a fast path. + */ + if (!pi_test_sn(pi_desc) && vcpu->cpu == cpu) + return; + + /* + * If the 'nv' field is POSTED_INTR_WAKEUP_VECTOR, do not change + * PI.NDST: pi_post_block is the one expected to change PID.NDST and the + * wakeup handler expects the vCPU to be on the blocked_vcpu_list that + * matches PI.NDST. Otherwise, a vcpu may not be able to be woken up + * correctly. + */ + if (pi_desc->nv == POSTED_INTR_WAKEUP_VECTOR || vcpu->cpu == cpu) { + pi_clear_sn(pi_desc); + goto after_clear_sn; + } + + /* The full case. */ + do { + old.control = new.control = pi_desc->control; + + dest = cpu_physical_id(cpu); + + if (x2apic_enabled()) + new.ndst = dest; + else + new.ndst = (dest << 8) & 0xFF00; + + new.sn = 0; + } while (cmpxchg64(&pi_desc->control, old.control, + new.control) != old.control); + +after_clear_sn: + + /* + * Clear SN before reading the bitmap. The VT-d firmware + * writes the bitmap and reads SN atomically (5.2.3 in the + * spec), so it doesn't really have a memory barrier that + * pairs with this, but we cannot do that and we need one. + */ + smp_mb__after_atomic(); + + if (!pi_is_pir_empty(pi_desc)) + pi_set_on(pi_desc); +} + +void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu) +{ + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); + + if (!kvm_arch_has_assigned_device(vcpu->kvm) || + !irq_remapping_cap(IRQ_POSTING_CAP) || + !kvm_vcpu_apicv_active(vcpu)) + return; + + /* Set SN when the vCPU is preempted */ + if (vcpu->preempted) + pi_set_sn(pi_desc); +} + +static void __pi_post_block(struct kvm_vcpu *vcpu) +{ + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); + struct pi_desc old, new; + unsigned int dest; + + do { + old.control = new.control = pi_desc->control; + WARN(old.nv != POSTED_INTR_WAKEUP_VECTOR, + "Wakeup handler not enabled while the VCPU is blocked\n"); + + dest = cpu_physical_id(vcpu->cpu); + + if (x2apic_enabled()) + new.ndst = dest; + else + new.ndst = (dest << 8) & 0xFF00; + + /* set 'NV' to 'notification vector' */ + new.nv = POSTED_INTR_VECTOR; + } while (cmpxchg64(&pi_desc->control, old.control, + new.control) != old.control); + + if (!WARN_ON_ONCE(vcpu->pre_pcpu == -1)) { + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); + list_del(&vcpu->blocked_vcpu_list); + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); + vcpu->pre_pcpu = -1; + } +} + +/* + * This routine does the following things for vCPU which is going + * to be blocked if VT-d PI is enabled. + * - Store the vCPU to the wakeup list, so when interrupts happen + * we can find the right vCPU to wake up. + * - Change the Posted-interrupt descriptor as below: + * 'NDST' <-- vcpu->pre_pcpu + * 'NV' <-- POSTED_INTR_WAKEUP_VECTOR + * - If 'ON' is set during this process, which means at least one + * interrupt is posted for this vCPU, we cannot block it, in + * this case, return 1, otherwise, return 0. + * + */ +int pi_pre_block(struct kvm_vcpu *vcpu) +{ + unsigned int dest; + struct pi_desc old, new; + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); + + if (!kvm_arch_has_assigned_device(vcpu->kvm) || + !irq_remapping_cap(IRQ_POSTING_CAP) || + !kvm_vcpu_apicv_active(vcpu)) + return 0; + + WARN_ON(irqs_disabled()); + local_irq_disable(); + if (!WARN_ON_ONCE(vcpu->pre_pcpu != -1)) { + vcpu->pre_pcpu = vcpu->cpu; + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); + list_add_tail(&vcpu->blocked_vcpu_list, + &per_cpu(blocked_vcpu_on_cpu, + vcpu->pre_pcpu)); + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); + } + + do { + old.control = new.control = pi_desc->control; + + WARN((pi_desc->sn == 1), + "Warning: SN field of posted-interrupts " + "is set before blocking\n"); + + /* + * Since vCPU can be preempted during this process, + * vcpu->cpu could be different with pre_pcpu, we + * need to set pre_pcpu as the destination of wakeup + * notification event, then we can find the right vCPU + * to wakeup in wakeup handler if interrupts happen + * when the vCPU is in blocked state. + */ + dest = cpu_physical_id(vcpu->pre_pcpu); + + if (x2apic_enabled()) + new.ndst = dest; + else + new.ndst = (dest << 8) & 0xFF00; + + /* set 'NV' to 'wakeup vector' */ + new.nv = POSTED_INTR_WAKEUP_VECTOR; + } while (cmpxchg64(&pi_desc->control, old.control, + new.control) != old.control); + + /* We should not block the vCPU if an interrupt is posted for it. */ + if (pi_test_on(pi_desc) == 1) + __pi_post_block(vcpu); + + local_irq_enable(); + return (vcpu->pre_pcpu == -1); +} + +void pi_post_block(struct kvm_vcpu *vcpu) +{ + if (vcpu->pre_pcpu == -1) + return; + + WARN_ON(irqs_disabled()); + local_irq_disable(); + __pi_post_block(vcpu); + local_irq_enable(); +} + +/* + * Handler for POSTED_INTERRUPT_WAKEUP_VECTOR. + */ +void pi_wakeup_handler(void) +{ + struct kvm_vcpu *vcpu; + int cpu = smp_processor_id(); + + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); + list_for_each_entry(vcpu, &per_cpu(blocked_vcpu_on_cpu, cpu), + blocked_vcpu_list) { + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); + + if (pi_test_on(pi_desc) == 1) + kvm_vcpu_kick(vcpu); + } + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); +} + +void __init pi_init_cpu(int cpu) +{ + INIT_LIST_HEAD(&per_cpu(blocked_vcpu_on_cpu, cpu)); + spin_lock_init(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); +} + +bool pi_has_pending_interrupt(struct kvm_vcpu *vcpu) +{ + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); + + return pi_test_on(pi_desc) || + (pi_test_sn(pi_desc) && !pi_is_pir_empty(pi_desc)); +} + + +/* + * pi_update_irte - set IRTE for Posted-Interrupts + * + * @kvm: kvm + * @host_irq: host irq of the interrupt + * @guest_irq: gsi of the interrupt + * @set: set or unset PI + * returns 0 on success, < 0 on failure + */ +int pi_update_irte(struct kvm *kvm, unsigned int host_irq, uint32_t guest_irq, + bool set) +{ + struct kvm_kernel_irq_routing_entry *e; + struct kvm_irq_routing_table *irq_rt; + struct kvm_lapic_irq irq; + struct kvm_vcpu *vcpu; + struct vcpu_data vcpu_info; + int idx, ret = 0; + + if (!kvm_arch_has_assigned_device(kvm) || + !irq_remapping_cap(IRQ_POSTING_CAP) || + !kvm_vcpu_apicv_active(kvm->vcpus[0])) + return 0; + + idx = srcu_read_lock(&kvm->irq_srcu); + irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu); + if (guest_irq >= irq_rt->nr_rt_entries || + hlist_empty(&irq_rt->map[guest_irq])) { + pr_warn_once("no route for guest_irq %u/%u (broken user space?)\n", + guest_irq, irq_rt->nr_rt_entries); + goto out; + } + + hlist_for_each_entry(e, &irq_rt->map[guest_irq], link) { + if (e->type != KVM_IRQ_ROUTING_MSI) + continue; + /* + * VT-d PI cannot support posting multicast/broadcast + * interrupts to a vCPU, we still use interrupt remapping + * for these kind of interrupts. + * + * For lowest-priority interrupts, we only support + * those with single CPU as the destination, e.g. user + * configures the interrupts via /proc/irq or uses + * irqbalance to make the interrupts single-CPU. + * + * We will support full lowest-priority interrupt later. + * + * In addition, we can only inject generic interrupts using + * the PI mechanism, refuse to route others through it. + */ + + kvm_set_msi_irq(kvm, e, &irq); + if (!kvm_intr_is_single_vcpu(kvm, &irq, &vcpu) || + !kvm_irq_is_postable(&irq)) { + /* + * Make sure the IRTE is in remapped mode if + * we don't handle it in posted mode. + */ + ret = irq_set_vcpu_affinity(host_irq, NULL); + if (ret < 0) { + printk(KERN_INFO + "failed to back to remapped mode, irq: %u\n", + host_irq); + goto out; + } + + continue; + } + + vcpu_info.pi_desc_addr = __pa(&to_vmx(vcpu)->pi_desc); + vcpu_info.vector = irq.vector; + + trace_kvm_pi_irte_update(host_irq, vcpu->vcpu_id, e->gsi, + vcpu_info.vector, vcpu_info.pi_desc_addr, set); + + if (set) + ret = irq_set_vcpu_affinity(host_irq, &vcpu_info); + else + ret = irq_set_vcpu_affinity(host_irq, NULL); + + if (ret < 0) { + printk(KERN_INFO "%s: failed to update PI IRTE\n", + __func__); + goto out; + } + } + + ret = 0; +out: + srcu_read_unlock(&kvm->irq_srcu, idx); + return ret; +} diff --git a/arch/x86/kvm/vmx/posted_intr.h b/arch/x86/kvm/vmx/posted_intr.h new file mode 100644 index 000000000000..0bdc41391c5b --- /dev/null +++ b/arch/x86/kvm/vmx/posted_intr.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __KVM_X86_VMX_POSTED_INTR_H +#define __KVM_X86_VMX_POSTED_INTR_H + +#define POSTED_INTR_ON 0 +#define POSTED_INTR_SN 1 + +/* Posted-Interrupt Descriptor */ +struct pi_desc { + u32 pir[8]; /* Posted interrupt requested */ + union { + struct { + /* bit 256 - Outstanding Notification */ + u16 on : 1, + /* bit 257 - Suppress Notification */ + sn : 1, + /* bit 271:258 - Reserved */ + rsvd_1 : 14; + /* bit 279:272 - Notification Vector */ + u8 nv; + /* bit 287:280 - Reserved */ + u8 rsvd_2; + /* bit 319:288 - Notification Destination */ + u32 ndst; + }; + u64 control; + }; + u32 rsvd[6]; +} __aligned(64); + +static inline bool pi_test_and_set_on(struct pi_desc *pi_desc) +{ + return test_and_set_bit(POSTED_INTR_ON, + (unsigned long *)&pi_desc->control); +} + +static inline bool pi_test_and_clear_on(struct pi_desc *pi_desc) +{ + return test_and_clear_bit(POSTED_INTR_ON, + (unsigned long *)&pi_desc->control); +} + +static inline int pi_test_and_set_pir(int vector, struct pi_desc *pi_desc) +{ + return test_and_set_bit(vector, (unsigned long *)pi_desc->pir); +} + +static inline bool pi_is_pir_empty(struct pi_desc *pi_desc) +{ + return bitmap_empty((unsigned long *)pi_desc->pir, NR_VECTORS); +} + +static inline void pi_set_sn(struct pi_desc *pi_desc) +{ + set_bit(POSTED_INTR_SN, + (unsigned long *)&pi_desc->control); +} + +static inline void pi_set_on(struct pi_desc *pi_desc) +{ + set_bit(POSTED_INTR_ON, + (unsigned long *)&pi_desc->control); +} + +static inline void pi_clear_on(struct pi_desc *pi_desc) +{ + clear_bit(POSTED_INTR_ON, + (unsigned long *)&pi_desc->control); +} + +static inline void pi_clear_sn(struct pi_desc *pi_desc) +{ + clear_bit(POSTED_INTR_SN, + (unsigned long *)&pi_desc->control); +} + +static inline int pi_test_on(struct pi_desc *pi_desc) +{ + return test_bit(POSTED_INTR_ON, + (unsigned long *)&pi_desc->control); +} + +static inline int pi_test_sn(struct pi_desc *pi_desc) +{ + return test_bit(POSTED_INTR_SN, + (unsigned long *)&pi_desc->control); +} + +void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu); +void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu); +int pi_pre_block(struct kvm_vcpu *vcpu); +void pi_post_block(struct kvm_vcpu *vcpu); +void pi_wakeup_handler(void); +void __init pi_init_cpu(int cpu); +bool pi_has_pending_interrupt(struct kvm_vcpu *vcpu); +int pi_update_irte(struct kvm *kvm, unsigned int host_irq, uint32_t guest_irq, + bool set); + +#endif /* __KVM_X86_VMX_POSTED_INTR_H */ diff --git a/arch/x86/kvm/vmx/vmcs.h b/arch/x86/kvm/vmx/vmcs.h index 7a3675fddec2..1472c6c376f7 100644 --- a/arch/x86/kvm/vmx/vmcs.h +++ b/arch/x86/kvm/vmx/vmcs.h @@ -138,6 +138,13 @@ static inline bool is_external_intr(u32 intr_info) return is_intr_type(intr_info, INTR_TYPE_EXT_INTR); } +static inline bool is_exception_with_error_code(u32 intr_info) +{ + const u32 mask = INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK; + + return (intr_info & mask) == mask; +} + enum vmcs_field_width { VMCS_FIELD_WIDTH_U16 = 0, VMCS_FIELD_WIDTH_U64 = 1, diff --git a/arch/x86/kvm/vmx/vmenter.S b/arch/x86/kvm/vmx/vmenter.S index 799db084a336..90ad7a6246e3 100644 --- a/arch/x86/kvm/vmx/vmenter.S +++ b/arch/x86/kvm/vmx/vmenter.S @@ -4,6 +4,7 @@ #include <asm/bitsperlong.h> #include <asm/kvm_vcpu_regs.h> #include <asm/nospec-branch.h> +#include <asm/segment.h> #define WORD_SIZE (BITS_PER_LONG / 8) @@ -294,3 +295,36 @@ SYM_FUNC_START(vmread_error_trampoline) ret SYM_FUNC_END(vmread_error_trampoline) + +SYM_FUNC_START(vmx_do_interrupt_nmi_irqoff) + /* + * Unconditionally create a stack frame, getting the correct RSP on the + * stack (for x86-64) would take two instructions anyways, and RBP can + * be used to restore RSP to make objtool happy (see below). + */ + push %_ASM_BP + mov %_ASM_SP, %_ASM_BP + +#ifdef CONFIG_X86_64 + /* + * Align RSP to a 16-byte boundary (to emulate CPU behavior) before + * creating the synthetic interrupt stack frame for the IRQ/NMI. + */ + and $-16, %rsp + push $__KERNEL_DS + push %rbp +#endif + pushf + push $__KERNEL_CS + CALL_NOSPEC _ASM_ARG1 + + /* + * "Restore" RSP from RBP, even though IRET has already unwound RSP to + * the correct value. objtool doesn't know the callee will IRET and, + * without the explicit restore, thinks the stack is getting walloped. + * Using an unwind hint is problematic due to x86-64's dynamic alignment. + */ + mov %_ASM_BP, %_ASM_SP + pop %_ASM_BP + ret +SYM_FUNC_END(vmx_do_interrupt_nmi_irqoff) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 819c185adf09..d14c94d0aff1 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -13,7 +13,6 @@ * Yaniv Kamay <yaniv@qumranet.com> */ -#include <linux/frame.h> #include <linux/highmem.h> #include <linux/hrtimer.h> #include <linux/kernel.h> @@ -22,6 +21,7 @@ #include <linux/moduleparam.h> #include <linux/mod_devicetable.h> #include <linux/mm.h> +#include <linux/objtool.h> #include <linux/sched.h> #include <linux/sched/smt.h> #include <linux/slab.h> @@ -56,7 +56,6 @@ #include "lapic.h" #include "mmu.h" #include "nested.h" -#include "ops.h" #include "pmu.h" #include "trace.h" #include "vmcs.h" @@ -129,6 +128,9 @@ static bool __read_mostly enable_preemption_timer = 1; module_param_named(preemption_timer, enable_preemption_timer, bool, S_IRUGO); #endif +extern bool __read_mostly allow_smaller_maxphyaddr; +module_param(allow_smaller_maxphyaddr, bool, S_IRUGO); + #define KVM_VM_CR0_ALWAYS_OFF (X86_CR0_NW | X86_CR0_CD) #define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST X86_CR0_NE #define KVM_VM_CR0_ALWAYS_ON \ @@ -146,8 +148,25 @@ module_param_named(preemption_timer, enable_preemption_timer, bool, S_IRUGO); RTIT_STATUS_ERROR | RTIT_STATUS_STOPPED | \ RTIT_STATUS_BYTECNT)) -#define MSR_IA32_RTIT_OUTPUT_BASE_MASK \ - (~((1UL << cpuid_query_maxphyaddr(vcpu)) - 1) | 0x7f) +/* + * List of MSRs that can be directly passed to the guest. + * In addition to these x2apic and PT MSRs are handled specially. + */ +static u32 vmx_possible_passthrough_msrs[MAX_POSSIBLE_PASSTHROUGH_MSRS] = { + MSR_IA32_SPEC_CTRL, + MSR_IA32_PRED_CMD, + MSR_IA32_TSC, + MSR_FS_BASE, + MSR_GS_BASE, + MSR_KERNEL_GS_BASE, + MSR_IA32_SYSENTER_CS, + MSR_IA32_SYSENTER_ESP, + MSR_IA32_SYSENTER_EIP, + MSR_CORE_C1_RES, + MSR_CORE_C3_RESIDENCY, + MSR_CORE_C6_RESIDENCY, + MSR_CORE_C7_RESIDENCY, +}; /* * These 2 parameters are used to config the controls for Pause-Loop Exiting: @@ -341,9 +360,8 @@ static const struct kernel_param_ops vmentry_l1d_flush_ops = { }; module_param_cb(vmentry_l1d_flush, &vmentry_l1d_flush_ops, NULL, 0644); -static bool guest_state_valid(struct kvm_vcpu *vcpu); static u32 vmx_segment_access_rights(struct kvm_segment *var); -static __always_inline void vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, +static __always_inline void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type); void vmx_vmexit(void); @@ -398,13 +416,6 @@ DEFINE_PER_CPU(struct vmcs *, current_vmcs); */ static DEFINE_PER_CPU(struct list_head, loaded_vmcss_on_cpu); -/* - * We maintian a per-CPU linked-list of vCPU, so in wakeup_handler() we - * can find which vCPU should be waken up. - */ -static DEFINE_PER_CPU(struct list_head, blocked_vcpu_on_cpu); -static DEFINE_PER_CPU(spinlock_t, blocked_vcpu_on_cpu_lock); - static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS); static DEFINE_SPINLOCK(vmx_vpid_lock); @@ -447,9 +458,9 @@ static unsigned long host_idt_base; * will emulate SYSCALL in legacy mode if the vendor string in guest * CPUID.0:{EBX,ECX,EDX} is "AuthenticAMD" or "AMDisbetter!" To * support this emulation, IA32_STAR must always be included in - * vmx_msr_index[], even in i386 builds. + * vmx_uret_msrs_list[], even in i386 builds. */ -const u32 vmx_msr_index[] = { +static const u32 vmx_uret_msrs_list[] = { #ifdef CONFIG_X86_64 MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR, #endif @@ -623,36 +634,71 @@ static inline bool report_flexpriority(void) return flexpriority_enabled; } -static inline int __find_msr_index(struct vcpu_vmx *vmx, u32 msr) +static int possible_passthrough_msr_slot(u32 msr) +{ + u32 i; + + for (i = 0; i < ARRAY_SIZE(vmx_possible_passthrough_msrs); i++) + if (vmx_possible_passthrough_msrs[i] == msr) + return i; + + return -ENOENT; +} + +static bool is_valid_passthrough_msr(u32 msr) +{ + bool r; + + switch (msr) { + case 0x800 ... 0x8ff: + /* x2APIC MSRs. These are handled in vmx_update_msr_bitmap_x2apic() */ + return true; + case MSR_IA32_RTIT_STATUS: + case MSR_IA32_RTIT_OUTPUT_BASE: + case MSR_IA32_RTIT_OUTPUT_MASK: + case MSR_IA32_RTIT_CR3_MATCH: + case MSR_IA32_RTIT_ADDR0_A ... MSR_IA32_RTIT_ADDR3_B: + /* PT MSRs. These are handled in pt_update_intercept_for_msr() */ + return true; + } + + r = possible_passthrough_msr_slot(msr) != -ENOENT; + + WARN(!r, "Invalid MSR %x, please adapt vmx_possible_passthrough_msrs[]", msr); + + return r; +} + +static inline int __vmx_find_uret_msr(struct vcpu_vmx *vmx, u32 msr) { int i; - for (i = 0; i < vmx->nmsrs; ++i) - if (vmx_msr_index[vmx->guest_msrs[i].index] == msr) + for (i = 0; i < vmx->nr_uret_msrs; ++i) + if (vmx_uret_msrs_list[vmx->guest_uret_msrs[i].slot] == msr) return i; return -1; } -struct shared_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr) +struct vmx_uret_msr *vmx_find_uret_msr(struct vcpu_vmx *vmx, u32 msr) { int i; - i = __find_msr_index(vmx, msr); + i = __vmx_find_uret_msr(vmx, msr); if (i >= 0) - return &vmx->guest_msrs[i]; + return &vmx->guest_uret_msrs[i]; return NULL; } -static int vmx_set_guest_msr(struct vcpu_vmx *vmx, struct shared_msr_entry *msr, u64 data) +static int vmx_set_guest_uret_msr(struct vcpu_vmx *vmx, + struct vmx_uret_msr *msr, u64 data) { int ret = 0; u64 old_msr_data = msr->data; msr->data = data; - if (msr - vmx->guest_msrs < vmx->save_nmsrs) { + if (msr - vmx->guest_uret_msrs < vmx->nr_active_uret_msrs) { preempt_disable(); - ret = kvm_set_shared_msr(msr->index, msr->data, - msr->mask); + ret = kvm_set_user_return_msr(msr->slot, msr->data, msr->mask); preempt_enable(); if (ret) msr->data = old_msr_data; @@ -791,6 +837,18 @@ void update_exception_bitmap(struct kvm_vcpu *vcpu) */ if (is_guest_mode(vcpu)) eb |= get_vmcs12(vcpu)->exception_bitmap; + else { + /* + * If EPT is enabled, #PF is only trapped if MAXPHYADDR is mismatched + * between guest and host. In that case we only care about present + * faults. For vmcs02, however, PFEC_MASK and PFEC_MATCH are set in + * prepare_vmcs02_rare. + */ + bool selective_pf_trap = enable_ept && (eb & (1u << PF_VECTOR)); + int mask = selective_pf_trap ? PFERR_PRESENT_MASK : 0; + vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, mask); + vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, mask); + } vmcs_write32(EXCEPTION_BITMAP, eb); } @@ -825,7 +883,7 @@ static void clear_atomic_switch_msr_special(struct vcpu_vmx *vmx, vm_exit_controls_clearbit(vmx, exit); } -int vmx_find_msr_index(struct vmx_msrs *m, u32 msr) +int vmx_find_loadstore_msr_slot(struct vmx_msrs *m, u32 msr) { unsigned int i; @@ -859,7 +917,7 @@ static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr) } break; } - i = vmx_find_msr_index(&m->guest, msr); + i = vmx_find_loadstore_msr_slot(&m->guest, msr); if (i < 0) goto skip_guest; --m->guest.nr; @@ -867,7 +925,7 @@ static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr) vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, m->guest.nr); skip_guest: - i = vmx_find_msr_index(&m->host, msr); + i = vmx_find_loadstore_msr_slot(&m->host, msr); if (i < 0) return; @@ -926,12 +984,12 @@ static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr, wrmsrl(MSR_IA32_PEBS_ENABLE, 0); } - i = vmx_find_msr_index(&m->guest, msr); + i = vmx_find_loadstore_msr_slot(&m->guest, msr); if (!entry_only) - j = vmx_find_msr_index(&m->host, msr); + j = vmx_find_loadstore_msr_slot(&m->host, msr); - if ((i < 0 && m->guest.nr == NR_LOADSTORE_MSRS) || - (j < 0 && m->host.nr == NR_LOADSTORE_MSRS)) { + if ((i < 0 && m->guest.nr == MAX_NR_LOADSTORE_MSRS) || + (j < 0 && m->host.nr == MAX_NR_LOADSTORE_MSRS)) { printk_once(KERN_WARNING "Not enough msr switch entries. " "Can't add msr %x\n", msr); return; @@ -954,10 +1012,11 @@ static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr, m->host.val[j].value = host_val; } -static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset) +static bool update_transition_efer(struct vcpu_vmx *vmx) { u64 guest_efer = vmx->vcpu.arch.efer; u64 ignore_bits = 0; + int i; /* Shadow paging assumes NX to be available. */ if (!enable_ept) @@ -989,17 +1048,21 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset) else clear_atomic_switch_msr(vmx, MSR_EFER); return false; - } else { - clear_atomic_switch_msr(vmx, MSR_EFER); + } + + i = __vmx_find_uret_msr(vmx, MSR_EFER); + if (i < 0) + return false; - guest_efer &= ~ignore_bits; - guest_efer |= host_efer & ignore_bits; + clear_atomic_switch_msr(vmx, MSR_EFER); - vmx->guest_msrs[efer_offset].data = guest_efer; - vmx->guest_msrs[efer_offset].mask = ~ignore_bits; + guest_efer &= ~ignore_bits; + guest_efer |= host_efer & ignore_bits; - return true; - } + vmx->guest_uret_msrs[i].data = guest_efer; + vmx->guest_uret_msrs[i].mask = ~ignore_bits; + + return true; } #ifdef CONFIG_X86_32 @@ -1037,6 +1100,12 @@ static inline bool pt_can_write_msr(struct vcpu_vmx *vmx) !(vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN); } +static inline bool pt_output_base_valid(struct kvm_vcpu *vcpu, u64 base) +{ + /* The base must be 128-byte aligned and a legal physical address. */ + return !kvm_vcpu_is_illegal_gpa(vcpu, base) && !(base & 0x7f); +} + static inline void pt_load_msr(struct pt_ctx *ctx, u32 addr_range) { u32 i; @@ -1141,12 +1210,12 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) * when guest state is loaded. This happens when guest transitions * to/from long-mode by setting MSR_EFER.LMA. */ - if (!vmx->guest_msrs_ready) { - vmx->guest_msrs_ready = true; - for (i = 0; i < vmx->save_nmsrs; ++i) - kvm_set_shared_msr(vmx->guest_msrs[i].index, - vmx->guest_msrs[i].data, - vmx->guest_msrs[i].mask); + if (!vmx->guest_uret_msrs_loaded) { + vmx->guest_uret_msrs_loaded = true; + for (i = 0; i < vmx->nr_active_uret_msrs; ++i) + kvm_set_user_return_msr(vmx->guest_uret_msrs[i].slot, + vmx->guest_uret_msrs[i].data, + vmx->guest_uret_msrs[i].mask); } @@ -1230,7 +1299,7 @@ static void vmx_prepare_switch_to_host(struct vcpu_vmx *vmx) #endif load_fixmap_gdt(raw_smp_processor_id()); vmx->guest_state_loaded = false; - vmx->guest_msrs_ready = false; + vmx->guest_uret_msrs_loaded = false; } #ifdef CONFIG_X86_64 @@ -1253,62 +1322,6 @@ static void vmx_write_guest_kernel_gs_base(struct vcpu_vmx *vmx, u64 data) } #endif -static void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu) -{ - struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); - struct pi_desc old, new; - unsigned int dest; - - /* - * In case of hot-plug or hot-unplug, we may have to undo - * vmx_vcpu_pi_put even if there is no assigned device. And we - * always keep PI.NDST up to date for simplicity: it makes the - * code easier, and CPU migration is not a fast path. - */ - if (!pi_test_sn(pi_desc) && vcpu->cpu == cpu) - return; - - /* - * If the 'nv' field is POSTED_INTR_WAKEUP_VECTOR, do not change - * PI.NDST: pi_post_block is the one expected to change PID.NDST and the - * wakeup handler expects the vCPU to be on the blocked_vcpu_list that - * matches PI.NDST. Otherwise, a vcpu may not be able to be woken up - * correctly. - */ - if (pi_desc->nv == POSTED_INTR_WAKEUP_VECTOR || vcpu->cpu == cpu) { - pi_clear_sn(pi_desc); - goto after_clear_sn; - } - - /* The full case. */ - do { - old.control = new.control = pi_desc->control; - - dest = cpu_physical_id(cpu); - - if (x2apic_enabled()) - new.ndst = dest; - else - new.ndst = (dest << 8) & 0xFF00; - - new.sn = 0; - } while (cmpxchg64(&pi_desc->control, old.control, - new.control) != old.control); - -after_clear_sn: - - /* - * Clear SN before reading the bitmap. The VT-d firmware - * writes the bitmap and reads SN atomically (5.2.3 in the - * spec), so it doesn't really have a memory barrier that - * pairs with this, but we cannot do that and we need one. - */ - smp_mb__after_atomic(); - - if (!pi_is_pir_empty(pi_desc)) - pi_set_on(pi_desc); -} - void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu, struct loaded_vmcs *buddy) { @@ -1392,20 +1405,6 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) vmx->host_debugctlmsr = get_debugctlmsr(); } -static void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu) -{ - struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); - - if (!kvm_arch_has_assigned_device(vcpu->kvm) || - !irq_remapping_cap(IRQ_POSTING_CAP) || - !kvm_vcpu_apicv_active(vcpu)) - return; - - /* Set SN when the vCPU is preempted */ - if (vcpu->preempted) - pi_set_sn(pi_desc); -} - static void vmx_vcpu_put(struct kvm_vcpu *vcpu) { vmx_vcpu_pi_put(vcpu); @@ -1415,7 +1414,7 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu) static bool emulation_required(struct kvm_vcpu *vcpu) { - return emulate_invalid_guest_state && !guest_state_valid(vcpu); + return emulate_invalid_guest_state && !vmx_guest_state_valid(vcpu); } unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) @@ -1441,7 +1440,7 @@ void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) struct vcpu_vmx *vmx = to_vmx(vcpu); unsigned long old_rflags; - if (enable_unrestricted_guest) { + if (is_unrestricted_guest(vcpu)) { kvm_register_mark_available(vcpu, VCPU_EXREG_RFLAGS); vmx->rflags = rflags; vmcs_writel(GUEST_RFLAGS, rflags); @@ -1561,6 +1560,11 @@ static int vmx_rtit_ctl_check(struct kvm_vcpu *vcpu, u64 data) return 0; } +static bool vmx_can_emulate_instruction(struct kvm_vcpu *vcpu, void *insn, int insn_len) +{ + return true; +} + static int skip_emulated_instruction(struct kvm_vcpu *vcpu) { unsigned long rip, orig_rip; @@ -1599,33 +1603,6 @@ static int skip_emulated_instruction(struct kvm_vcpu *vcpu) } /* - * Handles kvm_read/write_guest_virt*() result and either injects #PF or returns - * KVM_EXIT_INTERNAL_ERROR for cases not currently handled by KVM. Return value - * indicates whether exit to userspace is needed. - */ -int vmx_handle_memory_failure(struct kvm_vcpu *vcpu, int r, - struct x86_exception *e) -{ - if (r == X86EMUL_PROPAGATE_FAULT) { - kvm_inject_emulated_page_fault(vcpu, e); - return 1; - } - - /* - * In case kvm_read/write_guest_virt*() failed with X86EMUL_IO_NEEDED - * while handling a VMX instruction KVM could've handled the request - * correctly by exiting to userspace and performing I/O but there - * doesn't seem to be a real use-case behind such requests, just return - * KVM_EXIT_INTERNAL_ERROR for now. - */ - vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; - vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; - vcpu->run->internal.ndata = 0; - - return 0; -} - -/* * Recognizes a pending MTF VM-exit and records the nested state for later * delivery. */ @@ -1708,16 +1685,19 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu) vmx_clear_hlt(vcpu); } -/* - * Swap MSR entry in host/guest MSR entry array. - */ -static void move_msr_up(struct vcpu_vmx *vmx, int from, int to) +static void vmx_setup_uret_msr(struct vcpu_vmx *vmx, unsigned int msr) { - struct shared_msr_entry tmp; + struct vmx_uret_msr tmp; + int from, to; + + from = __vmx_find_uret_msr(vmx, msr); + if (from < 0) + return; + to = vmx->nr_active_uret_msrs++; - tmp = vmx->guest_msrs[to]; - vmx->guest_msrs[to] = vmx->guest_msrs[from]; - vmx->guest_msrs[from] = tmp; + tmp = vmx->guest_uret_msrs[to]; + vmx->guest_uret_msrs[to] = vmx->guest_uret_msrs[from]; + vmx->guest_uret_msrs[from] = tmp; } /* @@ -1727,38 +1707,26 @@ static void move_msr_up(struct vcpu_vmx *vmx, int from, int to) */ static void setup_msrs(struct vcpu_vmx *vmx) { - int save_nmsrs, index; - - save_nmsrs = 0; + vmx->guest_uret_msrs_loaded = false; + vmx->nr_active_uret_msrs = 0; #ifdef CONFIG_X86_64 /* * The SYSCALL MSRs are only needed on long mode guests, and only * when EFER.SCE is set. */ if (is_long_mode(&vmx->vcpu) && (vmx->vcpu.arch.efer & EFER_SCE)) { - index = __find_msr_index(vmx, MSR_STAR); - if (index >= 0) - move_msr_up(vmx, index, save_nmsrs++); - index = __find_msr_index(vmx, MSR_LSTAR); - if (index >= 0) - move_msr_up(vmx, index, save_nmsrs++); - index = __find_msr_index(vmx, MSR_SYSCALL_MASK); - if (index >= 0) - move_msr_up(vmx, index, save_nmsrs++); + vmx_setup_uret_msr(vmx, MSR_STAR); + vmx_setup_uret_msr(vmx, MSR_LSTAR); + vmx_setup_uret_msr(vmx, MSR_SYSCALL_MASK); } #endif - index = __find_msr_index(vmx, MSR_EFER); - if (index >= 0 && update_transition_efer(vmx, index)) - move_msr_up(vmx, index, save_nmsrs++); - index = __find_msr_index(vmx, MSR_TSC_AUX); - if (index >= 0 && guest_cpuid_has(&vmx->vcpu, X86_FEATURE_RDTSCP)) - move_msr_up(vmx, index, save_nmsrs++); - index = __find_msr_index(vmx, MSR_IA32_TSX_CTRL); - if (index >= 0) - move_msr_up(vmx, index, save_nmsrs++); - - vmx->save_nmsrs = save_nmsrs; - vmx->guest_msrs_ready = false; + if (update_transition_efer(vmx)) + vmx_setup_uret_msr(vmx, MSR_EFER); + + if (guest_cpuid_has(&vmx->vcpu, X86_FEATURE_RDTSCP)) + vmx_setup_uret_msr(vmx, MSR_TSC_AUX); + + vmx_setup_uret_msr(vmx, MSR_IA32_TSX_CTRL); if (cpu_has_vmx_msr_bitmap()) vmx_update_msr_bitmap(&vmx->vcpu); @@ -1828,7 +1796,7 @@ static int vmx_get_msr_feature(struct kvm_msr_entry *msr) static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) { struct vcpu_vmx *vmx = to_vmx(vcpu); - struct shared_msr_entry *msr; + struct vmx_uret_msr *msr; u32 index; switch (msr_info->index) { @@ -1849,7 +1817,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) if (!msr_info->host_initiated && !(vcpu->arch.arch_capabilities & ARCH_CAP_TSX_CTRL_MSR)) return 1; - goto find_shared_msr; + goto find_uret_msr; case MSR_IA32_UMWAIT_CONTROL: if (!msr_info->host_initiated && !vmx_has_waitpkg(vmx)) return 1; @@ -1956,10 +1924,10 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) if (!msr_info->host_initiated && !guest_cpuid_has(vcpu, X86_FEATURE_RDTSCP)) return 1; - goto find_shared_msr; + goto find_uret_msr; default: - find_shared_msr: - msr = find_msr_entry(vmx, msr_info->index); + find_uret_msr: + msr = vmx_find_uret_msr(vmx, msr_info->index); if (msr) { msr_info->data = msr->data; break; @@ -1988,7 +1956,7 @@ static u64 nested_vmx_truncate_sysenter_addr(struct kvm_vcpu *vcpu, static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) { struct vcpu_vmx *vmx = to_vmx(vcpu); - struct shared_msr_entry *msr; + struct vmx_uret_msr *msr; int ret = 0; u32 msr_index = msr_info->index; u64 data = msr_info->data; @@ -2082,7 +2050,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) * in the merging. We update the vmcs01 here for L1 as well * since it will end up touching the MSR anyway now. */ - vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap, + vmx_disable_intercept_for_msr(vcpu, MSR_IA32_SPEC_CTRL, MSR_TYPE_RW); break; @@ -2092,7 +2060,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return 1; if (data & ~(TSX_CTRL_RTM_DISABLE | TSX_CTRL_CPUID_CLEAR)) return 1; - goto find_shared_msr; + goto find_uret_msr; case MSR_IA32_PRED_CMD: if (!msr_info->host_initiated && !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL)) @@ -2118,8 +2086,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) * vmcs02.msr_bitmap here since it gets completely overwritten * in the merging. */ - vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap, MSR_IA32_PRED_CMD, - MSR_TYPE_W); + vmx_disable_intercept_for_msr(vcpu, MSR_IA32_PRED_CMD, MSR_TYPE_W); break; case MSR_IA32_CR_PAT: if (!kvm_pat_valid(data)) @@ -2169,7 +2136,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return 1; vmcs_write64(GUEST_IA32_RTIT_CTL, data); vmx->pt_desc.guest.ctl = data; - pt_update_intercept_for_msr(vmx); + pt_update_intercept_for_msr(vcpu); break; case MSR_IA32_RTIT_STATUS: if (!pt_can_write_msr(vmx)) @@ -2194,7 +2161,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) !intel_pt_validate_cap(vmx->pt_desc.caps, PT_CAP_single_range_output)) return 1; - if (data & MSR_IA32_RTIT_OUTPUT_BASE_MASK) + if (!pt_output_base_valid(vcpu, data)) return 1; vmx->pt_desc.guest.output_base = data; break; @@ -2229,13 +2196,13 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) /* Check reserved bit, higher 32 bits should be zero */ if ((data >> 32) != 0) return 1; - goto find_shared_msr; + goto find_uret_msr; default: - find_shared_msr: - msr = find_msr_entry(vmx, msr_index); + find_uret_msr: + msr = vmx_find_uret_msr(vmx, msr_index); if (msr) - ret = vmx_set_guest_msr(vmx, msr, data); + ret = vmx_set_guest_uret_msr(vmx, msr, data); else ret = kvm_set_msr_common(vcpu, msr_info); } @@ -2267,7 +2234,8 @@ static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) vcpu->arch.cr0 |= vmcs_readl(GUEST_CR0) & guest_owned_bits; break; case VCPU_EXREG_CR3: - if (enable_unrestricted_guest || (enable_ept && is_paging(vcpu))) + if (is_unrestricted_guest(vcpu) || + (enable_ept && is_paging(vcpu))) vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); break; case VCPU_EXREG_CR4: @@ -2448,7 +2416,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, SECONDARY_EXEC_UNRESTRICTED_GUEST | SECONDARY_EXEC_PAUSE_LOOP_EXITING | SECONDARY_EXEC_DESC | - SECONDARY_EXEC_RDTSCP | + SECONDARY_EXEC_ENABLE_RDTSCP | SECONDARY_EXEC_ENABLE_INVPCID | SECONDARY_EXEC_APIC_REGISTER_VIRT | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | @@ -2862,13 +2830,14 @@ static void enter_rmode(struct kvm_vcpu *vcpu) kvm_mmu_reset_context(vcpu); } -void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer) +int vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer) { struct vcpu_vmx *vmx = to_vmx(vcpu); - struct shared_msr_entry *msr = find_msr_entry(vmx, MSR_EFER); + struct vmx_uret_msr *msr = vmx_find_uret_msr(vmx, MSR_EFER); + /* Nothing to do if hardware doesn't support EFER. */ if (!msr) - return; + return 0; vcpu->arch.efer = efer; if (efer & EFER_LMA) { @@ -2880,6 +2849,7 @@ void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer) msr->data = efer & ~EFER_LME; } setup_msrs(vmx); + return 0; } #ifdef CONFIG_X86_64 @@ -2971,7 +2941,7 @@ static void vmx_flush_tlb_guest(struct kvm_vcpu *vcpu) vpid_sync_context(to_vmx(vcpu)->vpid); } -static void ept_load_pdptrs(struct kvm_vcpu *vcpu) +void vmx_ept_load_pdptrs(struct kvm_vcpu *vcpu) { struct kvm_mmu *mmu = vcpu->arch.walk_mmu; @@ -3033,7 +3003,7 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) unsigned long hw_cr0; hw_cr0 = (cr0 & ~KVM_VM_CR0_ALWAYS_OFF); - if (enable_unrestricted_guest) + if (is_unrestricted_guest(vcpu)) hw_cr0 |= KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST; else { hw_cr0 |= KVM_VM_CR0_ALWAYS_ON; @@ -3054,7 +3024,7 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) } #endif - if (enable_ept && !enable_unrestricted_guest) + if (enable_ept && !is_unrestricted_guest(vcpu)) ept_update_paging_mode_cr0(&hw_cr0, cr0, vcpu); vmcs_writel(CR0_READ_SHADOW, cr0); @@ -3114,7 +3084,7 @@ static void vmx_load_mmu_pgd(struct kvm_vcpu *vcpu, unsigned long pgd, guest_cr3 = vcpu->arch.cr3; else /* vmcs01.GUEST_CR3 is already up-to-date. */ update_guest_cr3 = false; - ept_load_pdptrs(vcpu); + vmx_ept_load_pdptrs(vcpu); } else { guest_cr3 = pgd; } @@ -3134,7 +3104,7 @@ int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) unsigned long hw_cr4; hw_cr4 = (cr4_read_shadow() & X86_CR4_MCE) | (cr4 & ~X86_CR4_MCE); - if (enable_unrestricted_guest) + if (is_unrestricted_guest(vcpu)) hw_cr4 |= KVM_VM_CR4_ALWAYS_ON_UNRESTRICTED_GUEST; else if (vmx->rmode.vm86_active) hw_cr4 |= KVM_RMODE_VM_CR4_ALWAYS_ON; @@ -3169,7 +3139,7 @@ int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) vcpu->arch.cr4 = cr4; kvm_register_mark_available(vcpu, VCPU_EXREG_CR4); - if (!enable_unrestricted_guest) { + if (!is_unrestricted_guest(vcpu)) { if (enable_ept) { if (!is_paging(vcpu)) { hw_cr4 &= ~X86_CR4_PAE; @@ -3309,7 +3279,7 @@ void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) * tree. Newer qemu binaries with that qemu fix would not need this * kvm hack. */ - if (enable_unrestricted_guest && (seg != VCPU_SREG_LDTR)) + if (is_unrestricted_guest(vcpu) && (seg != VCPU_SREG_LDTR)) var->type |= 0x1; /* Accessed */ vmcs_write32(sf->ar_bytes, vmx_segment_access_rights(var)); @@ -3498,11 +3468,8 @@ static bool cs_ss_rpl_check(struct kvm_vcpu *vcpu) * not. * We assume that registers are always usable */ -static bool guest_state_valid(struct kvm_vcpu *vcpu) +bool __vmx_guest_state_valid(struct kvm_vcpu *vcpu) { - if (enable_unrestricted_guest) - return true; - /* real mode guest state checks */ if (!is_protmode(vcpu) || (vmx_get_rflags(vcpu) & X86_EFLAGS_VM)) { if (!rmode_segment_valid(vcpu, VCPU_SREG_CS)) @@ -3688,11 +3655,52 @@ void free_vpid(int vpid) spin_unlock(&vmx_vpid_lock); } -static __always_inline void vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, - u32 msr, int type) +static void vmx_clear_msr_bitmap_read(ulong *msr_bitmap, u32 msr) +{ + int f = sizeof(unsigned long); + + if (msr <= 0x1fff) + __clear_bit(msr, msr_bitmap + 0x000 / f); + else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) + __clear_bit(msr & 0x1fff, msr_bitmap + 0x400 / f); +} + +static void vmx_clear_msr_bitmap_write(ulong *msr_bitmap, u32 msr) +{ + int f = sizeof(unsigned long); + + if (msr <= 0x1fff) + __clear_bit(msr, msr_bitmap + 0x800 / f); + else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) + __clear_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f); +} + +static void vmx_set_msr_bitmap_read(ulong *msr_bitmap, u32 msr) +{ + int f = sizeof(unsigned long); + + if (msr <= 0x1fff) + __set_bit(msr, msr_bitmap + 0x000 / f); + else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) + __set_bit(msr & 0x1fff, msr_bitmap + 0x400 / f); +} + +static void vmx_set_msr_bitmap_write(ulong *msr_bitmap, u32 msr) { int f = sizeof(unsigned long); + if (msr <= 0x1fff) + __set_bit(msr, msr_bitmap + 0x800 / f); + else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) + __set_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f); +} + +static __always_inline void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, + u32 msr, int type) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + unsigned long *msr_bitmap = vmx->vmcs01.msr_bitmap; + if (!cpu_has_vmx_msr_bitmap()) return; @@ -3700,36 +3708,44 @@ static __always_inline void vmx_disable_intercept_for_msr(unsigned long *msr_bit evmcs_touch_msr_bitmap(); /* - * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals - * have the write-low and read-high bitmap offsets the wrong way round. - * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff. - */ - if (msr <= 0x1fff) { - if (type & MSR_TYPE_R) - /* read-low */ - __clear_bit(msr, msr_bitmap + 0x000 / f); + * Mark the desired intercept state in shadow bitmap, this is needed + * for resync when the MSR filters change. + */ + if (is_valid_passthrough_msr(msr)) { + int idx = possible_passthrough_msr_slot(msr); + + if (idx != -ENOENT) { + if (type & MSR_TYPE_R) + clear_bit(idx, vmx->shadow_msr_intercept.read); + if (type & MSR_TYPE_W) + clear_bit(idx, vmx->shadow_msr_intercept.write); + } + } - if (type & MSR_TYPE_W) - /* write-low */ - __clear_bit(msr, msr_bitmap + 0x800 / f); + if ((type & MSR_TYPE_R) && + !kvm_msr_allowed(vcpu, msr, KVM_MSR_FILTER_READ)) { + vmx_set_msr_bitmap_read(msr_bitmap, msr); + type &= ~MSR_TYPE_R; + } - } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { - msr &= 0x1fff; - if (type & MSR_TYPE_R) - /* read-high */ - __clear_bit(msr, msr_bitmap + 0x400 / f); + if ((type & MSR_TYPE_W) && + !kvm_msr_allowed(vcpu, msr, KVM_MSR_FILTER_WRITE)) { + vmx_set_msr_bitmap_write(msr_bitmap, msr); + type &= ~MSR_TYPE_W; + } - if (type & MSR_TYPE_W) - /* write-high */ - __clear_bit(msr, msr_bitmap + 0xc00 / f); + if (type & MSR_TYPE_R) + vmx_clear_msr_bitmap_read(msr_bitmap, msr); - } + if (type & MSR_TYPE_W) + vmx_clear_msr_bitmap_write(msr_bitmap, msr); } -static __always_inline void vmx_enable_intercept_for_msr(unsigned long *msr_bitmap, +static __always_inline void vmx_enable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type) { - int f = sizeof(unsigned long); + struct vcpu_vmx *vmx = to_vmx(vcpu); + unsigned long *msr_bitmap = vmx->vmcs01.msr_bitmap; if (!cpu_has_vmx_msr_bitmap()) return; @@ -3738,39 +3754,34 @@ static __always_inline void vmx_enable_intercept_for_msr(unsigned long *msr_bitm evmcs_touch_msr_bitmap(); /* - * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals - * have the write-low and read-high bitmap offsets the wrong way round. - * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff. - */ - if (msr <= 0x1fff) { - if (type & MSR_TYPE_R) - /* read-low */ - __set_bit(msr, msr_bitmap + 0x000 / f); - - if (type & MSR_TYPE_W) - /* write-low */ - __set_bit(msr, msr_bitmap + 0x800 / f); - - } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { - msr &= 0x1fff; - if (type & MSR_TYPE_R) - /* read-high */ - __set_bit(msr, msr_bitmap + 0x400 / f); + * Mark the desired intercept state in shadow bitmap, this is needed + * for resync when the MSR filter changes. + */ + if (is_valid_passthrough_msr(msr)) { + int idx = possible_passthrough_msr_slot(msr); + + if (idx != -ENOENT) { + if (type & MSR_TYPE_R) + set_bit(idx, vmx->shadow_msr_intercept.read); + if (type & MSR_TYPE_W) + set_bit(idx, vmx->shadow_msr_intercept.write); + } + } - if (type & MSR_TYPE_W) - /* write-high */ - __set_bit(msr, msr_bitmap + 0xc00 / f); + if (type & MSR_TYPE_R) + vmx_set_msr_bitmap_read(msr_bitmap, msr); - } + if (type & MSR_TYPE_W) + vmx_set_msr_bitmap_write(msr_bitmap, msr); } -static __always_inline void vmx_set_intercept_for_msr(unsigned long *msr_bitmap, - u32 msr, int type, bool value) +static __always_inline void vmx_set_intercept_for_msr(struct kvm_vcpu *vcpu, + u32 msr, int type, bool value) { if (value) - vmx_enable_intercept_for_msr(msr_bitmap, msr, type); + vmx_enable_intercept_for_msr(vcpu, msr, type); else - vmx_disable_intercept_for_msr(msr_bitmap, msr, type); + vmx_disable_intercept_for_msr(vcpu, msr, type); } static u8 vmx_msr_bitmap_mode(struct kvm_vcpu *vcpu) @@ -3788,35 +3799,47 @@ static u8 vmx_msr_bitmap_mode(struct kvm_vcpu *vcpu) return mode; } -static void vmx_update_msr_bitmap_x2apic(unsigned long *msr_bitmap, - u8 mode) +static void vmx_reset_x2apic_msrs(struct kvm_vcpu *vcpu, u8 mode) { + unsigned long *msr_bitmap = to_vmx(vcpu)->vmcs01.msr_bitmap; + unsigned long read_intercept; int msr; + read_intercept = (mode & MSR_BITMAP_MODE_X2APIC_APICV) ? 0 : ~0; + for (msr = 0x800; msr <= 0x8ff; msr += BITS_PER_LONG) { - unsigned word = msr / BITS_PER_LONG; - msr_bitmap[word] = (mode & MSR_BITMAP_MODE_X2APIC_APICV) ? 0 : ~0; - msr_bitmap[word + (0x800 / sizeof(long))] = ~0; + unsigned int read_idx = msr / BITS_PER_LONG; + unsigned int write_idx = read_idx + (0x800 / sizeof(long)); + + msr_bitmap[read_idx] = read_intercept; + msr_bitmap[write_idx] = ~0ul; } +} - if (mode & MSR_BITMAP_MODE_X2APIC) { - /* - * TPR reads and writes can be virtualized even if virtual interrupt - * delivery is not in use. - */ - vmx_disable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_TASKPRI), MSR_TYPE_RW); - if (mode & MSR_BITMAP_MODE_X2APIC_APICV) { - vmx_enable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_TMCCT), MSR_TYPE_R); - vmx_disable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_EOI), MSR_TYPE_W); - vmx_disable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_SELF_IPI), MSR_TYPE_W); - } +static void vmx_update_msr_bitmap_x2apic(struct kvm_vcpu *vcpu, u8 mode) +{ + if (!cpu_has_vmx_msr_bitmap()) + return; + + vmx_reset_x2apic_msrs(vcpu, mode); + + /* + * TPR reads and writes can be virtualized even if virtual interrupt + * delivery is not in use. + */ + vmx_set_intercept_for_msr(vcpu, X2APIC_MSR(APIC_TASKPRI), MSR_TYPE_RW, + !(mode & MSR_BITMAP_MODE_X2APIC)); + + if (mode & MSR_BITMAP_MODE_X2APIC_APICV) { + vmx_enable_intercept_for_msr(vcpu, X2APIC_MSR(APIC_TMCCT), MSR_TYPE_RW); + vmx_disable_intercept_for_msr(vcpu, X2APIC_MSR(APIC_EOI), MSR_TYPE_W); + vmx_disable_intercept_for_msr(vcpu, X2APIC_MSR(APIC_SELF_IPI), MSR_TYPE_W); } } void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); - unsigned long *msr_bitmap = vmx->vmcs01.msr_bitmap; u8 mode = vmx_msr_bitmap_mode(vcpu); u8 changed = mode ^ vmx->msr_bitmap_mode; @@ -3824,30 +3847,24 @@ void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu) return; if (changed & (MSR_BITMAP_MODE_X2APIC | MSR_BITMAP_MODE_X2APIC_APICV)) - vmx_update_msr_bitmap_x2apic(msr_bitmap, mode); + vmx_update_msr_bitmap_x2apic(vcpu, mode); vmx->msr_bitmap_mode = mode; } -void pt_update_intercept_for_msr(struct vcpu_vmx *vmx) +void pt_update_intercept_for_msr(struct kvm_vcpu *vcpu) { - unsigned long *msr_bitmap = vmx->vmcs01.msr_bitmap; + struct vcpu_vmx *vmx = to_vmx(vcpu); bool flag = !(vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN); u32 i; - vmx_set_intercept_for_msr(msr_bitmap, MSR_IA32_RTIT_STATUS, - MSR_TYPE_RW, flag); - vmx_set_intercept_for_msr(msr_bitmap, MSR_IA32_RTIT_OUTPUT_BASE, - MSR_TYPE_RW, flag); - vmx_set_intercept_for_msr(msr_bitmap, MSR_IA32_RTIT_OUTPUT_MASK, - MSR_TYPE_RW, flag); - vmx_set_intercept_for_msr(msr_bitmap, MSR_IA32_RTIT_CR3_MATCH, - MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_RTIT_STATUS, MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_RTIT_OUTPUT_BASE, MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_RTIT_OUTPUT_MASK, MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_RTIT_CR3_MATCH, MSR_TYPE_RW, flag); for (i = 0; i < vmx->pt_desc.addr_range; i++) { - vmx_set_intercept_for_msr(msr_bitmap, - MSR_IA32_RTIT_ADDR0_A + i * 2, MSR_TYPE_RW, flag); - vmx_set_intercept_for_msr(msr_bitmap, - MSR_IA32_RTIT_ADDR0_B + i * 2, MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_RTIT_ADDR0_A + i * 2, MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_RTIT_ADDR0_B + i * 2, MSR_TYPE_RW, flag); } } @@ -3871,6 +3888,29 @@ static bool vmx_guest_apic_has_interrupt(struct kvm_vcpu *vcpu) return ((rvi & 0xf0) > (vppr & 0xf0)); } +static void vmx_msr_filter_changed(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + u32 i; + + /* + * Set intercept permissions for all potentially passed through MSRs + * again. They will automatically get filtered through the MSR filter, + * so we are back in sync after this. + */ + for (i = 0; i < ARRAY_SIZE(vmx_possible_passthrough_msrs); i++) { + u32 msr = vmx_possible_passthrough_msrs[i]; + bool read = test_bit(i, vmx->shadow_msr_intercept.read); + bool write = test_bit(i, vmx->shadow_msr_intercept.write); + + vmx_set_intercept_for_msr(vcpu, msr, MSR_TYPE_R, read); + vmx_set_intercept_for_msr(vcpu, msr, MSR_TYPE_W, write); + } + + pt_update_intercept_for_msr(vcpu); + vmx_update_msr_bitmap_x2apic(vcpu, vmx_msr_bitmap_mode(vcpu)); +} + static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu, bool nested) { @@ -4028,13 +4068,16 @@ void vmx_set_constant_host_state(struct vcpu_vmx *vmx) void set_cr4_guest_host_mask(struct vcpu_vmx *vmx) { - vmx->vcpu.arch.cr4_guest_owned_bits = KVM_POSSIBLE_CR4_GUEST_BITS; + struct kvm_vcpu *vcpu = &vmx->vcpu; + + vcpu->arch.cr4_guest_owned_bits = KVM_POSSIBLE_CR4_GUEST_BITS & + ~vcpu->arch.cr4_guest_rsvd_bits; if (!enable_ept) - vmx->vcpu.arch.cr4_guest_owned_bits &= ~X86_CR4_PGE; + vcpu->arch.cr4_guest_owned_bits &= ~X86_CR4_PGE; if (is_guest_mode(&vmx->vcpu)) - vmx->vcpu.arch.cr4_guest_owned_bits &= - ~get_vmcs12(&vmx->vcpu)->cr4_guest_host_mask; - vmcs_writel(CR4_GUEST_HOST_MASK, ~vmx->vcpu.arch.cr4_guest_owned_bits); + vcpu->arch.cr4_guest_owned_bits &= + ~get_vmcs12(vcpu)->cr4_guest_host_mask; + vmcs_writel(CR4_GUEST_HOST_MASK, ~vcpu->arch.cr4_guest_owned_bits); } u32 vmx_pin_based_exec_ctrl(struct vcpu_vmx *vmx) @@ -4099,6 +4142,61 @@ u32 vmx_exec_control(struct vcpu_vmx *vmx) return exec_control; } +/* + * Adjust a single secondary execution control bit to intercept/allow an + * instruction in the guest. This is usually done based on whether or not a + * feature has been exposed to the guest in order to correctly emulate faults. + */ +static inline void +vmx_adjust_secondary_exec_control(struct vcpu_vmx *vmx, u32 *exec_control, + u32 control, bool enabled, bool exiting) +{ + /* + * If the control is for an opt-in feature, clear the control if the + * feature is not exposed to the guest, i.e. not enabled. If the + * control is opt-out, i.e. an exiting control, clear the control if + * the feature _is_ exposed to the guest, i.e. exiting/interception is + * disabled for the associated instruction. Note, the caller is + * responsible presetting exec_control to set all supported bits. + */ + if (enabled == exiting) + *exec_control &= ~control; + + /* + * Update the nested MSR settings so that a nested VMM can/can't set + * controls for features that are/aren't exposed to the guest. + */ + if (nested) { + if (enabled) + vmx->nested.msrs.secondary_ctls_high |= control; + else + vmx->nested.msrs.secondary_ctls_high &= ~control; + } +} + +/* + * Wrapper macro for the common case of adjusting a secondary execution control + * based on a single guest CPUID bit, with a dedicated feature bit. This also + * verifies that the control is actually supported by KVM and hardware. + */ +#define vmx_adjust_sec_exec_control(vmx, exec_control, name, feat_name, ctrl_name, exiting) \ +({ \ + bool __enabled; \ + \ + if (cpu_has_vmx_##name()) { \ + __enabled = guest_cpuid_has(&(vmx)->vcpu, \ + X86_FEATURE_##feat_name); \ + vmx_adjust_secondary_exec_control(vmx, exec_control, \ + SECONDARY_EXEC_##ctrl_name, __enabled, exiting); \ + } \ +}) + +/* More macro magic for ENABLE_/opt-in versus _EXITING/opt-out controls. */ +#define vmx_adjust_sec_exec_feature(vmx, exec_control, lname, uname) \ + vmx_adjust_sec_exec_control(vmx, exec_control, lname, uname, ENABLE_##uname, false) + +#define vmx_adjust_sec_exec_exiting(vmx, exec_control, lname, uname) \ + vmx_adjust_sec_exec_control(vmx, exec_control, lname, uname, uname##_EXITING, true) static void vmx_compute_secondary_exec_control(struct vcpu_vmx *vmx) { @@ -4139,7 +4237,7 @@ static void vmx_compute_secondary_exec_control(struct vcpu_vmx *vmx) if (!enable_pml) exec_control &= ~SECONDARY_EXEC_ENABLE_PML; - if (vmx_xsaves_supported()) { + if (cpu_has_vmx_xsaves()) { /* Exposing XSAVES only when XSAVE is exposed */ bool xsaves_enabled = boot_cpu_has(X86_FEATURE_XSAVE) && @@ -4148,101 +4246,29 @@ static void vmx_compute_secondary_exec_control(struct vcpu_vmx *vmx) vcpu->arch.xsaves_enabled = xsaves_enabled; - if (!xsaves_enabled) - exec_control &= ~SECONDARY_EXEC_XSAVES; - - if (nested) { - if (xsaves_enabled) - vmx->nested.msrs.secondary_ctls_high |= - SECONDARY_EXEC_XSAVES; - else - vmx->nested.msrs.secondary_ctls_high &= - ~SECONDARY_EXEC_XSAVES; - } + vmx_adjust_secondary_exec_control(vmx, &exec_control, + SECONDARY_EXEC_XSAVES, + xsaves_enabled, false); } - if (cpu_has_vmx_rdtscp()) { - bool rdtscp_enabled = guest_cpuid_has(vcpu, X86_FEATURE_RDTSCP); - if (!rdtscp_enabled) - exec_control &= ~SECONDARY_EXEC_RDTSCP; + vmx_adjust_sec_exec_feature(vmx, &exec_control, rdtscp, RDTSCP); - if (nested) { - if (rdtscp_enabled) - vmx->nested.msrs.secondary_ctls_high |= - SECONDARY_EXEC_RDTSCP; - else - vmx->nested.msrs.secondary_ctls_high &= - ~SECONDARY_EXEC_RDTSCP; - } - } - - if (cpu_has_vmx_invpcid()) { - /* Exposing INVPCID only when PCID is exposed */ - bool invpcid_enabled = - guest_cpuid_has(vcpu, X86_FEATURE_INVPCID) && - guest_cpuid_has(vcpu, X86_FEATURE_PCID); - - if (!invpcid_enabled) { - exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; - guest_cpuid_clear(vcpu, X86_FEATURE_INVPCID); - } - - if (nested) { - if (invpcid_enabled) - vmx->nested.msrs.secondary_ctls_high |= - SECONDARY_EXEC_ENABLE_INVPCID; - else - vmx->nested.msrs.secondary_ctls_high &= - ~SECONDARY_EXEC_ENABLE_INVPCID; - } - } - - if (vmx_rdrand_supported()) { - bool rdrand_enabled = guest_cpuid_has(vcpu, X86_FEATURE_RDRAND); - if (rdrand_enabled) - exec_control &= ~SECONDARY_EXEC_RDRAND_EXITING; - - if (nested) { - if (rdrand_enabled) - vmx->nested.msrs.secondary_ctls_high |= - SECONDARY_EXEC_RDRAND_EXITING; - else - vmx->nested.msrs.secondary_ctls_high &= - ~SECONDARY_EXEC_RDRAND_EXITING; - } - } - - if (vmx_rdseed_supported()) { - bool rdseed_enabled = guest_cpuid_has(vcpu, X86_FEATURE_RDSEED); - if (rdseed_enabled) - exec_control &= ~SECONDARY_EXEC_RDSEED_EXITING; - - if (nested) { - if (rdseed_enabled) - vmx->nested.msrs.secondary_ctls_high |= - SECONDARY_EXEC_RDSEED_EXITING; - else - vmx->nested.msrs.secondary_ctls_high &= - ~SECONDARY_EXEC_RDSEED_EXITING; - } - } + /* + * Expose INVPCID if and only if PCID is also exposed to the guest. + * INVPCID takes a #UD when it's disabled in the VMCS, but a #GP or #PF + * if CR4.PCIDE=0. Enumerating CPUID.INVPCID=1 would lead to incorrect + * behavior from the guest perspective (it would expect #GP or #PF). + */ + if (!guest_cpuid_has(vcpu, X86_FEATURE_PCID)) + guest_cpuid_clear(vcpu, X86_FEATURE_INVPCID); + vmx_adjust_sec_exec_feature(vmx, &exec_control, invpcid, INVPCID); - if (vmx_waitpkg_supported()) { - bool waitpkg_enabled = - guest_cpuid_has(vcpu, X86_FEATURE_WAITPKG); - if (!waitpkg_enabled) - exec_control &= ~SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE; + vmx_adjust_sec_exec_exiting(vmx, &exec_control, rdrand, RDRAND); + vmx_adjust_sec_exec_exiting(vmx, &exec_control, rdseed, RDSEED); - if (nested) { - if (waitpkg_enabled) - vmx->nested.msrs.secondary_ctls_high |= - SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE; - else - vmx->nested.msrs.secondary_ctls_high &= - ~SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE; - } - } + vmx_adjust_sec_exec_control(vmx, &exec_control, waitpkg, WAITPKG, + ENABLE_USR_WAIT_PAUSE, false); vmx->secondary_exec_control = exec_control; } @@ -4335,7 +4361,7 @@ static void init_vmcs(struct vcpu_vmx *vmx) if (vmx->vpid != 0) vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid); - if (vmx_xsaves_supported()) + if (cpu_has_vmx_xsaves()) vmcs_write64(XSS_EXIT_BITMAP, VMX_XSS_EXIT_BITMAP); if (enable_pml) { @@ -4352,16 +4378,6 @@ static void init_vmcs(struct vcpu_vmx *vmx) vmx->pt_desc.guest.output_mask = 0x7F; vmcs_write64(GUEST_IA32_RTIT_CTL, 0); } - - /* - * If EPT is enabled, #PF is only trapped if MAXPHYADDR is mismatched - * between guest and host. In that case we only care about present - * faults. - */ - if (enable_ept) { - vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, PFERR_PRESENT_MASK); - vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, PFERR_PRESENT_MASK); - } } static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) @@ -4803,6 +4819,7 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu) * EPT will cause page fault only if we need to * detect illegal GPAs. */ + WARN_ON_ONCE(!allow_smaller_maxphyaddr); kvm_fixup_and_inject_pf_error(vcpu, cr2, error_code); return 1; } else @@ -5148,7 +5165,8 @@ static int handle_vmcall(struct kvm_vcpu *vcpu) static int handle_invd(struct kvm_vcpu *vcpu) { - return kvm_emulate_instruction(vcpu, 0); + /* Treat an INVD instruction as a NOP and just skip it. */ + return kvm_skip_emulated_instruction(vcpu); } static int handle_invlpg(struct kvm_vcpu *vcpu) @@ -5331,7 +5349,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu) * would also use advanced VM-exit information for EPT violations to * reconstruct the page fault error code. */ - if (unlikely(kvm_mmu_is_illegal_gpa(vcpu, gpa))) + if (unlikely(allow_smaller_maxphyaddr && kvm_vcpu_is_illegal_gpa(vcpu, gpa))) return kvm_emulate_instruction(vcpu, 0); return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0); @@ -5442,25 +5460,6 @@ static void shrink_ple_window(struct kvm_vcpu *vcpu) } } -/* - * Handler for POSTED_INTERRUPT_WAKEUP_VECTOR. - */ -static void wakeup_handler(void) -{ - struct kvm_vcpu *vcpu; - int cpu = smp_processor_id(); - - spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); - list_for_each_entry(vcpu, &per_cpu(blocked_vcpu_on_cpu, cpu), - blocked_vcpu_list) { - struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); - - if (pi_test_on(pi_desc) == 1) - kvm_vcpu_kick(vcpu); - } - spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); -} - static void vmx_enable_tdp(void) { kvm_mmu_set_mask_ptes(VMX_EPT_READABLE_MASK, @@ -5524,16 +5523,11 @@ static int handle_invpcid(struct kvm_vcpu *vcpu) { u32 vmx_instruction_info; unsigned long type; - bool pcid_enabled; gva_t gva; - struct x86_exception e; - unsigned i; - unsigned long roots_to_free = 0; struct { u64 pcid; u64 gla; } operand; - int r; if (!guest_cpuid_has(vcpu, X86_FEATURE_INVPCID)) { kvm_queue_exception(vcpu, UD_VECTOR); @@ -5556,68 +5550,7 @@ static int handle_invpcid(struct kvm_vcpu *vcpu) sizeof(operand), &gva)) return 1; - r = kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e); - if (r != X86EMUL_CONTINUE) - return vmx_handle_memory_failure(vcpu, r, &e); - - if (operand.pcid >> 12 != 0) { - kvm_inject_gp(vcpu, 0); - return 1; - } - - pcid_enabled = kvm_read_cr4_bits(vcpu, X86_CR4_PCIDE); - - switch (type) { - case INVPCID_TYPE_INDIV_ADDR: - if ((!pcid_enabled && (operand.pcid != 0)) || - is_noncanonical_address(operand.gla, vcpu)) { - kvm_inject_gp(vcpu, 0); - return 1; - } - kvm_mmu_invpcid_gva(vcpu, operand.gla, operand.pcid); - return kvm_skip_emulated_instruction(vcpu); - - case INVPCID_TYPE_SINGLE_CTXT: - if (!pcid_enabled && (operand.pcid != 0)) { - kvm_inject_gp(vcpu, 0); - return 1; - } - - if (kvm_get_active_pcid(vcpu) == operand.pcid) { - kvm_mmu_sync_roots(vcpu); - kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); - } - - for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++) - if (kvm_get_pcid(vcpu, vcpu->arch.mmu->prev_roots[i].pgd) - == operand.pcid) - roots_to_free |= KVM_MMU_ROOT_PREVIOUS(i); - - kvm_mmu_free_roots(vcpu, vcpu->arch.mmu, roots_to_free); - /* - * If neither the current cr3 nor any of the prev_roots use the - * given PCID, then nothing needs to be done here because a - * resync will happen anyway before switching to any other CR3. - */ - - return kvm_skip_emulated_instruction(vcpu); - - case INVPCID_TYPE_ALL_NON_GLOBAL: - /* - * Currently, KVM doesn't mark global entries in the shadow - * page tables, so a non-global flush just degenerates to a - * global flush. If needed, we could optimize this later by - * keeping track of global entries in shadow page tables. - */ - - fallthrough; - case INVPCID_TYPE_ALL_INCL_GLOBAL: - kvm_mmu_unload(vcpu); - return kvm_skip_emulated_instruction(vcpu); - - default: - BUG(); /* We have already checked above that type <= 3 */ - } + return kvm_handle_invpcid(vcpu, type, gva); } static int handle_pml_full(struct kvm_vcpu *vcpu) @@ -5746,10 +5679,24 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { static const int kvm_vmx_max_exit_handlers = ARRAY_SIZE(kvm_vmx_exit_handlers); -static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2) +static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2, + u32 *intr_info, u32 *error_code) { + struct vcpu_vmx *vmx = to_vmx(vcpu); + *info1 = vmx_get_exit_qual(vcpu); - *info2 = vmx_get_intr_info(vcpu); + if (!(vmx->exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY)) { + *info2 = vmx->idt_vectoring_info; + *intr_info = vmx_get_intr_info(vcpu); + if (is_exception_with_error_code(*intr_info)) + *error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE); + else + *error_code = 0; + } else { + *info2 = 0; + *intr_info = 0; + *error_code = 0; + } } static void vmx_destroy_pml_buffer(struct vcpu_vmx *vmx) @@ -6054,6 +6001,7 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) (exit_reason != EXIT_REASON_EXCEPTION_NMI && exit_reason != EXIT_REASON_EPT_VIOLATION && exit_reason != EXIT_REASON_PML_FULL && + exit_reason != EXIT_REASON_APIC_ACCESS && exit_reason != EXIT_REASON_TASK_SWITCH)) { vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_DELIVERY_EV; @@ -6382,14 +6330,6 @@ static int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu) return max_irr; } -static bool vmx_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu) -{ - struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); - - return pi_test_on(pi_desc) || - (pi_test_sn(pi_desc) && !pi_is_pir_empty(pi_desc)); -} - static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) { if (!kvm_vcpu_apicv_active(vcpu)) @@ -6409,70 +6349,43 @@ static void vmx_apicv_post_state_restore(struct kvm_vcpu *vcpu) memset(vmx->pi_desc.pir, 0, sizeof(vmx->pi_desc.pir)); } +void vmx_do_interrupt_nmi_irqoff(unsigned long entry); + +static void handle_interrupt_nmi_irqoff(struct kvm_vcpu *vcpu, u32 intr_info) +{ + unsigned int vector = intr_info & INTR_INFO_VECTOR_MASK; + gate_desc *desc = (gate_desc *)host_idt_base + vector; + + kvm_before_interrupt(vcpu); + vmx_do_interrupt_nmi_irqoff(gate_offset(desc)); + kvm_after_interrupt(vcpu); +} + static void handle_exception_nmi_irqoff(struct vcpu_vmx *vmx) { u32 intr_info = vmx_get_intr_info(&vmx->vcpu); /* if exit due to PF check for async PF */ - if (is_page_fault(intr_info)) { + if (is_page_fault(intr_info)) vmx->vcpu.arch.apf.host_apf_flags = kvm_read_and_reset_apf_flags(); /* Handle machine checks before interrupts are enabled */ - } else if (is_machine_check(intr_info)) { + else if (is_machine_check(intr_info)) kvm_machine_check(); /* We need to handle NMIs before interrupts are enabled */ - } else if (is_nmi(intr_info)) { - kvm_before_interrupt(&vmx->vcpu); - asm("int $2"); - kvm_after_interrupt(&vmx->vcpu); - } + else if (is_nmi(intr_info)) + handle_interrupt_nmi_irqoff(&vmx->vcpu, intr_info); } static void handle_external_interrupt_irqoff(struct kvm_vcpu *vcpu) { - unsigned int vector; - unsigned long entry; -#ifdef CONFIG_X86_64 - unsigned long tmp; -#endif - gate_desc *desc; u32 intr_info = vmx_get_intr_info(vcpu); if (WARN_ONCE(!is_external_intr(intr_info), "KVM: unexpected VM-Exit interrupt info: 0x%x", intr_info)) return; - vector = intr_info & INTR_INFO_VECTOR_MASK; - desc = (gate_desc *)host_idt_base + vector; - entry = gate_offset(desc); - - kvm_before_interrupt(vcpu); - - asm volatile( -#ifdef CONFIG_X86_64 - "mov %%rsp, %[sp]\n\t" - "and $-16, %%rsp\n\t" - "push %[ss]\n\t" - "push %[sp]\n\t" -#endif - "pushf\n\t" - "push %[cs]\n\t" - CALL_NOSPEC - : -#ifdef CONFIG_X86_64 - [sp]"=&r"(tmp), -#endif - ASM_CALL_CONSTRAINT - : - [thunk_target]"r"(entry), -#ifdef CONFIG_X86_64 - [ss]"i"(__KERNEL_DS), -#endif - [cs]"i"(__KERNEL_CS) - ); - - kvm_after_interrupt(vcpu); + handle_interrupt_nmi_irqoff(vcpu, intr_info); } -STACK_FRAME_NON_STANDARD(handle_external_interrupt_irqoff); static void vmx_handle_exit_irqoff(struct kvm_vcpu *vcpu) { @@ -6799,9 +6712,7 @@ reenter_guest: if (enable_preemption_timer) vmx_update_hv_timer(vcpu); - if (lapic_in_kernel(vcpu) && - vcpu->arch.apic->lapic_timer.timer_advance_ns) - kvm_wait_lapic_expire(vcpu); + kvm_wait_lapic_expire(vcpu); /* * If this vCPU has touched SPEC_CTRL, restore the guest's value if @@ -6945,20 +6856,20 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) goto free_vpid; } - BUILD_BUG_ON(ARRAY_SIZE(vmx_msr_index) != NR_SHARED_MSRS); + BUILD_BUG_ON(ARRAY_SIZE(vmx_uret_msrs_list) != MAX_NR_USER_RETURN_MSRS); - for (i = 0; i < ARRAY_SIZE(vmx_msr_index); ++i) { - u32 index = vmx_msr_index[i]; + for (i = 0; i < ARRAY_SIZE(vmx_uret_msrs_list); ++i) { + u32 index = vmx_uret_msrs_list[i]; u32 data_low, data_high; - int j = vmx->nmsrs; + int j = vmx->nr_uret_msrs; if (rdmsr_safe(index, &data_low, &data_high) < 0) continue; if (wrmsr_safe(index, data_low, data_high) < 0) continue; - vmx->guest_msrs[j].index = i; - vmx->guest_msrs[j].data = 0; + vmx->guest_uret_msrs[j].slot = i; + vmx->guest_uret_msrs[j].data = 0; switch (index) { case MSR_IA32_TSX_CTRL: /* @@ -6966,32 +6877,36 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) * let's avoid changing CPUID bits under the host * kernel's feet. */ - vmx->guest_msrs[j].mask = ~(u64)TSX_CTRL_CPUID_CLEAR; + vmx->guest_uret_msrs[j].mask = ~(u64)TSX_CTRL_CPUID_CLEAR; break; default: - vmx->guest_msrs[j].mask = -1ull; + vmx->guest_uret_msrs[j].mask = -1ull; break; } - ++vmx->nmsrs; + ++vmx->nr_uret_msrs; } err = alloc_loaded_vmcs(&vmx->vmcs01); if (err < 0) goto free_pml; + /* The MSR bitmap starts with all ones */ + bitmap_fill(vmx->shadow_msr_intercept.read, MAX_POSSIBLE_PASSTHROUGH_MSRS); + bitmap_fill(vmx->shadow_msr_intercept.write, MAX_POSSIBLE_PASSTHROUGH_MSRS); + msr_bitmap = vmx->vmcs01.msr_bitmap; - vmx_disable_intercept_for_msr(msr_bitmap, MSR_IA32_TSC, MSR_TYPE_R); - vmx_disable_intercept_for_msr(msr_bitmap, MSR_FS_BASE, MSR_TYPE_RW); - vmx_disable_intercept_for_msr(msr_bitmap, MSR_GS_BASE, MSR_TYPE_RW); - vmx_disable_intercept_for_msr(msr_bitmap, MSR_KERNEL_GS_BASE, MSR_TYPE_RW); - vmx_disable_intercept_for_msr(msr_bitmap, MSR_IA32_SYSENTER_CS, MSR_TYPE_RW); - vmx_disable_intercept_for_msr(msr_bitmap, MSR_IA32_SYSENTER_ESP, MSR_TYPE_RW); - vmx_disable_intercept_for_msr(msr_bitmap, MSR_IA32_SYSENTER_EIP, MSR_TYPE_RW); + vmx_disable_intercept_for_msr(vcpu, MSR_IA32_TSC, MSR_TYPE_R); + vmx_disable_intercept_for_msr(vcpu, MSR_FS_BASE, MSR_TYPE_RW); + vmx_disable_intercept_for_msr(vcpu, MSR_GS_BASE, MSR_TYPE_RW); + vmx_disable_intercept_for_msr(vcpu, MSR_KERNEL_GS_BASE, MSR_TYPE_RW); + vmx_disable_intercept_for_msr(vcpu, MSR_IA32_SYSENTER_CS, MSR_TYPE_RW); + vmx_disable_intercept_for_msr(vcpu, MSR_IA32_SYSENTER_ESP, MSR_TYPE_RW); + vmx_disable_intercept_for_msr(vcpu, MSR_IA32_SYSENTER_EIP, MSR_TYPE_RW); if (kvm_cstate_in_guest(vcpu->kvm)) { - vmx_disable_intercept_for_msr(msr_bitmap, MSR_CORE_C1_RES, MSR_TYPE_R); - vmx_disable_intercept_for_msr(msr_bitmap, MSR_CORE_C3_RESIDENCY, MSR_TYPE_R); - vmx_disable_intercept_for_msr(msr_bitmap, MSR_CORE_C6_RESIDENCY, MSR_TYPE_R); - vmx_disable_intercept_for_msr(msr_bitmap, MSR_CORE_C7_RESIDENCY, MSR_TYPE_R); + vmx_disable_intercept_for_msr(vcpu, MSR_CORE_C1_RES, MSR_TYPE_R); + vmx_disable_intercept_for_msr(vcpu, MSR_CORE_C3_RESIDENCY, MSR_TYPE_R); + vmx_disable_intercept_for_msr(vcpu, MSR_CORE_C6_RESIDENCY, MSR_TYPE_R); + vmx_disable_intercept_for_msr(vcpu, MSR_CORE_C7_RESIDENCY, MSR_TYPE_R); } vmx->msr_bitmap_mode = 0; @@ -7015,8 +6930,7 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) } if (nested) - nested_vmx_setup_ctls_msrs(&vmx->nested.msrs, - vmx_capability.ept); + memcpy(&vmx->nested.msrs, &vmcs_config.nested, sizeof(vmx->nested.msrs)); else memset(&vmx->nested.msrs, 0, sizeof(vmx->nested.msrs)); @@ -7336,13 +7250,18 @@ static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) update_intel_pt_cfg(vcpu); if (boot_cpu_has(X86_FEATURE_RTM)) { - struct shared_msr_entry *msr; - msr = find_msr_entry(vmx, MSR_IA32_TSX_CTRL); + struct vmx_uret_msr *msr; + msr = vmx_find_uret_msr(vmx, MSR_IA32_TSX_CTRL); if (msr) { bool enabled = guest_cpuid_has(vcpu, X86_FEATURE_RTM); - vmx_set_guest_msr(vmx, msr, enabled ? 0 : TSX_CTRL_RTM_DISABLE); + vmx_set_guest_uret_msr(vmx, msr, enabled ? 0 : TSX_CTRL_RTM_DISABLE); } } + + set_cr4_guest_host_mask(vmx); + + /* Refresh #PF interception to account for MAXPHYADDR changes. */ + update_exception_bitmap(vcpu); } static __init void vmx_set_cpu_caps(void) @@ -7366,14 +7285,14 @@ static __init void vmx_set_cpu_caps(void) /* CPUID 0xD.1 */ supported_xss = 0; - if (!vmx_xsaves_supported()) + if (!cpu_has_vmx_xsaves()) kvm_cpu_cap_clear(X86_FEATURE_XSAVES); /* CPUID 0x80000001 */ if (!cpu_has_vmx_rdtscp()) kvm_cpu_cap_clear(X86_FEATURE_RDTSCP); - if (vmx_waitpkg_supported()) + if (cpu_has_vmx_waitpkg()) kvm_cpu_cap_check_and_set(X86_FEATURE_WAITPKG); } @@ -7429,7 +7348,7 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu, * Because it is marked as EmulateOnUD, we need to intercept it here. */ case x86_intercept_rdtscp: - if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) { + if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENABLE_RDTSCP)) { exception->vector = UD_VECTOR; exception->error_code_valid = false; return X86EMUL_PROPAGATE_FAULT; @@ -7561,107 +7480,6 @@ static void vmx_enable_log_dirty_pt_masked(struct kvm *kvm, kvm_mmu_clear_dirty_pt_masked(kvm, memslot, offset, mask); } -static void __pi_post_block(struct kvm_vcpu *vcpu) -{ - struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); - struct pi_desc old, new; - unsigned int dest; - - do { - old.control = new.control = pi_desc->control; - WARN(old.nv != POSTED_INTR_WAKEUP_VECTOR, - "Wakeup handler not enabled while the VCPU is blocked\n"); - - dest = cpu_physical_id(vcpu->cpu); - - if (x2apic_enabled()) - new.ndst = dest; - else - new.ndst = (dest << 8) & 0xFF00; - - /* set 'NV' to 'notification vector' */ - new.nv = POSTED_INTR_VECTOR; - } while (cmpxchg64(&pi_desc->control, old.control, - new.control) != old.control); - - if (!WARN_ON_ONCE(vcpu->pre_pcpu == -1)) { - spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); - list_del(&vcpu->blocked_vcpu_list); - spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); - vcpu->pre_pcpu = -1; - } -} - -/* - * This routine does the following things for vCPU which is going - * to be blocked if VT-d PI is enabled. - * - Store the vCPU to the wakeup list, so when interrupts happen - * we can find the right vCPU to wake up. - * - Change the Posted-interrupt descriptor as below: - * 'NDST' <-- vcpu->pre_pcpu - * 'NV' <-- POSTED_INTR_WAKEUP_VECTOR - * - If 'ON' is set during this process, which means at least one - * interrupt is posted for this vCPU, we cannot block it, in - * this case, return 1, otherwise, return 0. - * - */ -static int pi_pre_block(struct kvm_vcpu *vcpu) -{ - unsigned int dest; - struct pi_desc old, new; - struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); - - if (!kvm_arch_has_assigned_device(vcpu->kvm) || - !irq_remapping_cap(IRQ_POSTING_CAP) || - !kvm_vcpu_apicv_active(vcpu)) - return 0; - - WARN_ON(irqs_disabled()); - local_irq_disable(); - if (!WARN_ON_ONCE(vcpu->pre_pcpu != -1)) { - vcpu->pre_pcpu = vcpu->cpu; - spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); - list_add_tail(&vcpu->blocked_vcpu_list, - &per_cpu(blocked_vcpu_on_cpu, - vcpu->pre_pcpu)); - spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); - } - - do { - old.control = new.control = pi_desc->control; - - WARN((pi_desc->sn == 1), - "Warning: SN field of posted-interrupts " - "is set before blocking\n"); - - /* - * Since vCPU can be preempted during this process, - * vcpu->cpu could be different with pre_pcpu, we - * need to set pre_pcpu as the destination of wakeup - * notification event, then we can find the right vCPU - * to wakeup in wakeup handler if interrupts happen - * when the vCPU is in blocked state. - */ - dest = cpu_physical_id(vcpu->pre_pcpu); - - if (x2apic_enabled()) - new.ndst = dest; - else - new.ndst = (dest << 8) & 0xFF00; - - /* set 'NV' to 'wakeup vector' */ - new.nv = POSTED_INTR_WAKEUP_VECTOR; - } while (cmpxchg64(&pi_desc->control, old.control, - new.control) != old.control); - - /* We should not block the vCPU if an interrupt is posted for it. */ - if (pi_test_on(pi_desc) == 1) - __pi_post_block(vcpu); - - local_irq_enable(); - return (vcpu->pre_pcpu == -1); -} - static int vmx_pre_block(struct kvm_vcpu *vcpu) { if (pi_pre_block(vcpu)) @@ -7673,17 +7491,6 @@ static int vmx_pre_block(struct kvm_vcpu *vcpu) return 0; } -static void pi_post_block(struct kvm_vcpu *vcpu) -{ - if (vcpu->pre_pcpu == -1) - return; - - WARN_ON(irqs_disabled()); - local_irq_disable(); - __pi_post_block(vcpu); - local_irq_enable(); -} - static void vmx_post_block(struct kvm_vcpu *vcpu) { if (kvm_x86_ops.set_hv_timer) @@ -7692,100 +7499,6 @@ static void vmx_post_block(struct kvm_vcpu *vcpu) pi_post_block(vcpu); } -/* - * vmx_update_pi_irte - set IRTE for Posted-Interrupts - * - * @kvm: kvm - * @host_irq: host irq of the interrupt - * @guest_irq: gsi of the interrupt - * @set: set or unset PI - * returns 0 on success, < 0 on failure - */ -static int vmx_update_pi_irte(struct kvm *kvm, unsigned int host_irq, - uint32_t guest_irq, bool set) -{ - struct kvm_kernel_irq_routing_entry *e; - struct kvm_irq_routing_table *irq_rt; - struct kvm_lapic_irq irq; - struct kvm_vcpu *vcpu; - struct vcpu_data vcpu_info; - int idx, ret = 0; - - if (!kvm_arch_has_assigned_device(kvm) || - !irq_remapping_cap(IRQ_POSTING_CAP) || - !kvm_vcpu_apicv_active(kvm->vcpus[0])) - return 0; - - idx = srcu_read_lock(&kvm->irq_srcu); - irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu); - if (guest_irq >= irq_rt->nr_rt_entries || - hlist_empty(&irq_rt->map[guest_irq])) { - pr_warn_once("no route for guest_irq %u/%u (broken user space?)\n", - guest_irq, irq_rt->nr_rt_entries); - goto out; - } - - hlist_for_each_entry(e, &irq_rt->map[guest_irq], link) { - if (e->type != KVM_IRQ_ROUTING_MSI) - continue; - /* - * VT-d PI cannot support posting multicast/broadcast - * interrupts to a vCPU, we still use interrupt remapping - * for these kind of interrupts. - * - * For lowest-priority interrupts, we only support - * those with single CPU as the destination, e.g. user - * configures the interrupts via /proc/irq or uses - * irqbalance to make the interrupts single-CPU. - * - * We will support full lowest-priority interrupt later. - * - * In addition, we can only inject generic interrupts using - * the PI mechanism, refuse to route others through it. - */ - - kvm_set_msi_irq(kvm, e, &irq); - if (!kvm_intr_is_single_vcpu(kvm, &irq, &vcpu) || - !kvm_irq_is_postable(&irq)) { - /* - * Make sure the IRTE is in remapped mode if - * we don't handle it in posted mode. - */ - ret = irq_set_vcpu_affinity(host_irq, NULL); - if (ret < 0) { - printk(KERN_INFO - "failed to back to remapped mode, irq: %u\n", - host_irq); - goto out; - } - - continue; - } - - vcpu_info.pi_desc_addr = __pa(vcpu_to_pi_desc(vcpu)); - vcpu_info.vector = irq.vector; - - trace_kvm_pi_irte_update(host_irq, vcpu->vcpu_id, e->gsi, - vcpu_info.vector, vcpu_info.pi_desc_addr, set); - - if (set) - ret = irq_set_vcpu_affinity(host_irq, &vcpu_info); - else - ret = irq_set_vcpu_affinity(host_irq, NULL); - - if (ret < 0) { - printk(KERN_INFO "%s: failed to update PI IRTE\n", - __func__); - goto out; - } - } - - ret = 0; -out: - srcu_read_unlock(&kvm->irq_srcu, idx); - return ret; -} - static void vmx_setup_mce(struct kvm_vcpu *vcpu) { if (vcpu->arch.mcg_cap & MCG_LMCE_P) @@ -7843,11 +7556,6 @@ static void enable_smi_window(struct kvm_vcpu *vcpu) /* RSM will cause a vmexit anyway. */ } -static bool vmx_need_emulation_on_page_fault(struct kvm_vcpu *vcpu) -{ - return false; -} - static bool vmx_apic_init_signal_blocked(struct kvm_vcpu *vcpu) { return to_vmx(vcpu)->nested.vmxon; @@ -7954,7 +7662,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { .guest_apic_has_interrupt = vmx_guest_apic_has_interrupt, .sync_pir_to_irr = vmx_sync_pir_to_irr, .deliver_posted_interrupt = vmx_deliver_posted_interrupt, - .dy_apicv_has_pending_interrupt = vmx_dy_apicv_has_pending_interrupt, + .dy_apicv_has_pending_interrupt = pi_has_pending_interrupt, .set_tss_addr = vmx_set_tss_addr, .set_identity_map_addr = vmx_set_identity_map_addr, @@ -7988,7 +7696,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { .pmu_ops = &intel_pmu_ops, .nested_ops = &vmx_nested_ops, - .update_pi_irte = vmx_update_pi_irte, + .update_pi_irte = pi_update_irte, #ifdef CONFIG_X86_64 .set_hv_timer = vmx_set_hv_timer, @@ -8002,9 +7710,11 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { .pre_leave_smm = vmx_pre_leave_smm, .enable_smi_window = enable_smi_window, - .need_emulation_on_page_fault = vmx_need_emulation_on_page_fault, + .can_emulate_instruction = vmx_can_emulate_instruction, .apic_init_signal_blocked = vmx_apic_init_signal_blocked, .migrate_timers = vmx_migrate_timers, + + .msr_filter_changed = vmx_msr_filter_changed, }; static __init int hardware_setup(void) @@ -8016,8 +7726,8 @@ static __init int hardware_setup(void) store_idt(&dt); host_idt_base = dt.address; - for (i = 0; i < ARRAY_SIZE(vmx_msr_index); ++i) - kvm_define_shared_msr(i, vmx_msr_index[i]); + for (i = 0; i < ARRAY_SIZE(vmx_uret_msrs_list); ++i) + kvm_define_user_return_msr(i, vmx_uret_msrs_list[i]); if (setup_vmcs_config(&vmcs_config, &vmx_capability) < 0) return -EIO; @@ -8154,7 +7864,7 @@ static __init int hardware_setup(void) vmx_x86_ops.request_immediate_exit = __kvm_request_immediate_exit; } - kvm_set_posted_intr_wakeup_handler(wakeup_handler); + kvm_set_posted_intr_wakeup_handler(pi_wakeup_handler); kvm_mce_cap_supported |= MCG_LMCE_P; @@ -8293,8 +8003,8 @@ static int __init vmx_init(void) for_each_possible_cpu(cpu) { INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu)); - INIT_LIST_HEAD(&per_cpu(blocked_vcpu_on_cpu, cpu)); - spin_lock_init(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); + + pi_init_cpu(cpu); } #ifdef CONFIG_KEXEC_CORE @@ -8304,11 +8014,12 @@ static int __init vmx_init(void) vmx_check_vmcs12_offsets(); /* - * Intel processors don't have problems with - * GUEST_MAXPHYADDR < HOST_MAXPHYADDR so enable - * it for VMX by default + * Shadow paging doesn't have a (further) performance penalty + * from GUEST_MAXPHYADDR < HOST_MAXPHYADDR so enable it + * by default */ - allow_smaller_maxphyaddr = true; + if (!enable_ept) + allow_smaller_maxphyaddr = true; return 0; } diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 26175a4759fa..f6f66e5c6510 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -9,8 +9,9 @@ #include "capabilities.h" #include "kvm_cache_regs.h" -#include "ops.h" +#include "posted_intr.h" #include "vmcs.h" +#include "vmx_ops.h" #include "cpuid.h" extern const u32 vmx_msr_index[]; @@ -22,20 +23,20 @@ extern const u32 vmx_msr_index[]; #define X2APIC_MSR(r) (APIC_BASE_MSR + ((r) >> 4)) #ifdef CONFIG_X86_64 -#define NR_SHARED_MSRS 7 +#define MAX_NR_USER_RETURN_MSRS 7 #else -#define NR_SHARED_MSRS 4 +#define MAX_NR_USER_RETURN_MSRS 4 #endif -#define NR_LOADSTORE_MSRS 8 +#define MAX_NR_LOADSTORE_MSRS 8 struct vmx_msrs { unsigned int nr; - struct vmx_msr_entry val[NR_LOADSTORE_MSRS]; + struct vmx_msr_entry val[MAX_NR_LOADSTORE_MSRS]; }; -struct shared_msr_entry { - unsigned index; +struct vmx_uret_msr { + unsigned int slot; /* The MSR's slot in kvm_user_return_msrs. */ u64 data; u64 mask; }; @@ -49,29 +50,6 @@ enum segment_cache_field { SEG_FIELD_NR = 4 }; -/* Posted-Interrupt Descriptor */ -struct pi_desc { - u32 pir[8]; /* Posted interrupt requested */ - union { - struct { - /* bit 256 - Outstanding Notification */ - u16 on : 1, - /* bit 257 - Suppress Notification */ - sn : 1, - /* bit 271:258 - Reserved */ - rsvd_1 : 14; - /* bit 279:272 - Notification Vector */ - u8 nv; - /* bit 287:280 - Reserved */ - u8 rsvd_2; - /* bit 319:288 - Notification Destination */ - u32 ndst; - }; - u64 control; - }; - u32 rsvd[6]; -} __aligned(64); - #define RTIT_ADDR_RANGE 4 struct pt_ctx { @@ -218,10 +196,10 @@ struct vcpu_vmx { u32 idt_vectoring_info; ulong rflags; - struct shared_msr_entry guest_msrs[NR_SHARED_MSRS]; - int nmsrs; - int save_nmsrs; - bool guest_msrs_ready; + struct vmx_uret_msr guest_uret_msrs[MAX_NR_USER_RETURN_MSRS]; + int nr_uret_msrs; + int nr_active_uret_msrs; + bool guest_uret_msrs_loaded; #ifdef CONFIG_X86_64 u64 msr_host_kernel_gs_base; u64 msr_guest_kernel_gs_base; @@ -301,6 +279,13 @@ struct vcpu_vmx { u64 ept_pointer; struct pt_desc pt_desc; + + /* Save desired MSR intercept (read: pass-through) state */ +#define MAX_POSSIBLE_PASSTHROUGH_MSRS 13 + struct { + DECLARE_BITMAP(read, MAX_POSSIBLE_PASSTHROUGH_MSRS); + DECLARE_BITMAP(write, MAX_POSSIBLE_PASSTHROUGH_MSRS); + } shadow_msr_intercept; }; enum ept_pointers_status { @@ -334,7 +319,7 @@ unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu); void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags); u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu); void vmx_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask); -void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer); +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 set_cr4_guest_host_mask(struct vcpu_vmx *vmx); @@ -343,6 +328,7 @@ void vmx_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); u64 construct_eptp(struct kvm_vcpu *vcpu, unsigned long root_hpa, int root_level); + void update_exception_bitmap(struct kvm_vcpu *vcpu); void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu); bool vmx_nmi_blocked(struct kvm_vcpu *vcpu); @@ -350,73 +336,11 @@ bool vmx_interrupt_blocked(struct kvm_vcpu *vcpu); bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu); void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked); void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu); -struct shared_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr); -void pt_update_intercept_for_msr(struct vcpu_vmx *vmx); +struct vmx_uret_msr *vmx_find_uret_msr(struct vcpu_vmx *vmx, u32 msr); +void pt_update_intercept_for_msr(struct kvm_vcpu *vcpu); void vmx_update_host_rsp(struct vcpu_vmx *vmx, unsigned long host_rsp); -int vmx_find_msr_index(struct vmx_msrs *m, u32 msr); -int vmx_handle_memory_failure(struct kvm_vcpu *vcpu, int r, - struct x86_exception *e); - -#define POSTED_INTR_ON 0 -#define POSTED_INTR_SN 1 - -static inline bool pi_test_and_set_on(struct pi_desc *pi_desc) -{ - return test_and_set_bit(POSTED_INTR_ON, - (unsigned long *)&pi_desc->control); -} - -static inline bool pi_test_and_clear_on(struct pi_desc *pi_desc) -{ - return test_and_clear_bit(POSTED_INTR_ON, - (unsigned long *)&pi_desc->control); -} - -static inline int pi_test_and_set_pir(int vector, struct pi_desc *pi_desc) -{ - return test_and_set_bit(vector, (unsigned long *)pi_desc->pir); -} - -static inline bool pi_is_pir_empty(struct pi_desc *pi_desc) -{ - return bitmap_empty((unsigned long *)pi_desc->pir, NR_VECTORS); -} - -static inline void pi_set_sn(struct pi_desc *pi_desc) -{ - set_bit(POSTED_INTR_SN, - (unsigned long *)&pi_desc->control); -} - -static inline void pi_set_on(struct pi_desc *pi_desc) -{ - set_bit(POSTED_INTR_ON, - (unsigned long *)&pi_desc->control); -} - -static inline void pi_clear_on(struct pi_desc *pi_desc) -{ - clear_bit(POSTED_INTR_ON, - (unsigned long *)&pi_desc->control); -} - -static inline void pi_clear_sn(struct pi_desc *pi_desc) -{ - clear_bit(POSTED_INTR_SN, - (unsigned long *)&pi_desc->control); -} - -static inline int pi_test_on(struct pi_desc *pi_desc) -{ - return test_bit(POSTED_INTR_ON, - (unsigned long *)&pi_desc->control); -} - -static inline int pi_test_sn(struct pi_desc *pi_desc) -{ - return test_bit(POSTED_INTR_SN, - (unsigned long *)&pi_desc->control); -} +int vmx_find_loadstore_msr_slot(struct vmx_msrs *m, u32 msr); +void vmx_ept_load_pdptrs(struct kvm_vcpu *vcpu); static inline u8 vmx_get_rvi(void) { @@ -498,11 +422,6 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) return container_of(vcpu, struct vcpu_vmx, vcpu); } -static inline struct pi_desc *vcpu_to_pi_desc(struct kvm_vcpu *vcpu) -{ - return &(to_vmx(vcpu)->pi_desc); -} - static inline unsigned long vmx_get_exit_qual(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); @@ -551,7 +470,23 @@ static inline bool vmx_has_waitpkg(struct vcpu_vmx *vmx) static inline bool vmx_need_pf_intercept(struct kvm_vcpu *vcpu) { - return !enable_ept || cpuid_maxphyaddr(vcpu) < boot_cpu_data.x86_phys_bits; + if (!enable_ept) + return true; + + return allow_smaller_maxphyaddr && cpuid_maxphyaddr(vcpu) < boot_cpu_data.x86_phys_bits; +} + +static inline bool is_unrestricted_guest(struct kvm_vcpu *vcpu) +{ + return enable_unrestricted_guest && (!is_guest_mode(vcpu) || + (secondary_exec_controls_get(to_vmx(vcpu)) & + SECONDARY_EXEC_UNRESTRICTED_GUEST)); +} + +bool __vmx_guest_state_valid(struct kvm_vcpu *vcpu); +static inline bool vmx_guest_state_valid(struct kvm_vcpu *vcpu) +{ + return is_unrestricted_guest(vcpu) || __vmx_guest_state_valid(vcpu); } void dump_vmcs(void); diff --git a/arch/x86/kvm/vmx/ops.h b/arch/x86/kvm/vmx/vmx_ops.h index 692b0c31c9c8..692b0c31c9c8 100644 --- a/arch/x86/kvm/vmx/ops.h +++ b/arch/x86/kvm/vmx/vmx_ops.h diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 75270229a8bf..397f599b20e5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -71,6 +71,7 @@ #include <asm/irq_remapping.h> #include <asm/mshyperv.h> #include <asm/hypervisor.h> +#include <asm/tlbflush.h> #include <asm/intel_pt.h> #include <asm/emulate_prefix.h> #include <clocksource/hyperv_timer.h> @@ -161,24 +162,29 @@ module_param(force_emulation_prefix, bool, S_IRUGO); int __read_mostly pi_inject_timer = -1; module_param(pi_inject_timer, bint, S_IRUGO | S_IWUSR); -#define KVM_NR_SHARED_MSRS 16 +/* + * Restoring the host value for MSRs that are only consumed when running in + * usermode, e.g. SYSCALL MSRs and TSC_AUX, can be deferred until the CPU + * returns to userspace, i.e. the kernel can run with the guest's value. + */ +#define KVM_MAX_NR_USER_RETURN_MSRS 16 -struct kvm_shared_msrs_global { +struct kvm_user_return_msrs_global { int nr; - u32 msrs[KVM_NR_SHARED_MSRS]; + u32 msrs[KVM_MAX_NR_USER_RETURN_MSRS]; }; -struct kvm_shared_msrs { +struct kvm_user_return_msrs { struct user_return_notifier urn; bool registered; - struct kvm_shared_msr_values { + struct kvm_user_return_msr_values { u64 host; u64 curr; - } values[KVM_NR_SHARED_MSRS]; + } values[KVM_MAX_NR_USER_RETURN_MSRS]; }; -static struct kvm_shared_msrs_global __read_mostly shared_msrs_global; -static struct kvm_shared_msrs __percpu *shared_msrs; +static struct kvm_user_return_msrs_global __read_mostly user_return_msrs_global; +static struct kvm_user_return_msrs __percpu *user_return_msrs; #define KVM_SUPPORTED_XCR0 (XFEATURE_MASK_FP | XFEATURE_MASK_SSE \ | XFEATURE_MASK_YMM | XFEATURE_MASK_BNDREGS \ @@ -188,7 +194,7 @@ static struct kvm_shared_msrs __percpu *shared_msrs; u64 __read_mostly host_efer; EXPORT_SYMBOL_GPL(host_efer); -bool __read_mostly allow_smaller_maxphyaddr; +bool __read_mostly allow_smaller_maxphyaddr = 0; EXPORT_SYMBOL_GPL(allow_smaller_maxphyaddr); static u64 __read_mostly host_xss; @@ -266,7 +272,7 @@ static int kvm_msr_ignored_check(struct kvm_vcpu *vcpu, u32 msr, } else { vcpu_debug_ratelimited(vcpu, "unhandled %s: 0x%x data 0x%llx\n", op, msr, data); - return 1; + return -ENOENT; } } @@ -293,9 +299,9 @@ static inline void kvm_async_pf_hash_reset(struct kvm_vcpu *vcpu) static void kvm_on_user_return(struct user_return_notifier *urn) { unsigned slot; - struct kvm_shared_msrs *locals - = container_of(urn, struct kvm_shared_msrs, urn); - struct kvm_shared_msr_values *values; + struct kvm_user_return_msrs *msrs + = container_of(urn, struct kvm_user_return_msrs, urn); + struct kvm_user_return_msr_values *values; unsigned long flags; /* @@ -303,73 +309,73 @@ static void kvm_on_user_return(struct user_return_notifier *urn) * interrupted and executed through kvm_arch_hardware_disable() */ local_irq_save(flags); - if (locals->registered) { - locals->registered = false; + if (msrs->registered) { + msrs->registered = false; user_return_notifier_unregister(urn); } local_irq_restore(flags); - for (slot = 0; slot < shared_msrs_global.nr; ++slot) { - values = &locals->values[slot]; + for (slot = 0; slot < user_return_msrs_global.nr; ++slot) { + values = &msrs->values[slot]; if (values->host != values->curr) { - wrmsrl(shared_msrs_global.msrs[slot], values->host); + wrmsrl(user_return_msrs_global.msrs[slot], values->host); values->curr = values->host; } } } -void kvm_define_shared_msr(unsigned slot, u32 msr) +void kvm_define_user_return_msr(unsigned slot, u32 msr) { - BUG_ON(slot >= KVM_NR_SHARED_MSRS); - shared_msrs_global.msrs[slot] = msr; - if (slot >= shared_msrs_global.nr) - shared_msrs_global.nr = slot + 1; + BUG_ON(slot >= KVM_MAX_NR_USER_RETURN_MSRS); + user_return_msrs_global.msrs[slot] = msr; + if (slot >= user_return_msrs_global.nr) + user_return_msrs_global.nr = slot + 1; } -EXPORT_SYMBOL_GPL(kvm_define_shared_msr); +EXPORT_SYMBOL_GPL(kvm_define_user_return_msr); -static void kvm_shared_msr_cpu_online(void) +static void kvm_user_return_msr_cpu_online(void) { unsigned int cpu = smp_processor_id(); - struct kvm_shared_msrs *smsr = per_cpu_ptr(shared_msrs, cpu); + struct kvm_user_return_msrs *msrs = per_cpu_ptr(user_return_msrs, cpu); u64 value; int i; - for (i = 0; i < shared_msrs_global.nr; ++i) { - rdmsrl_safe(shared_msrs_global.msrs[i], &value); - smsr->values[i].host = value; - smsr->values[i].curr = value; + for (i = 0; i < user_return_msrs_global.nr; ++i) { + rdmsrl_safe(user_return_msrs_global.msrs[i], &value); + msrs->values[i].host = value; + msrs->values[i].curr = value; } } -int kvm_set_shared_msr(unsigned slot, u64 value, u64 mask) +int kvm_set_user_return_msr(unsigned slot, u64 value, u64 mask) { unsigned int cpu = smp_processor_id(); - struct kvm_shared_msrs *smsr = per_cpu_ptr(shared_msrs, cpu); + struct kvm_user_return_msrs *msrs = per_cpu_ptr(user_return_msrs, cpu); int err; - value = (value & mask) | (smsr->values[slot].host & ~mask); - if (value == smsr->values[slot].curr) + value = (value & mask) | (msrs->values[slot].host & ~mask); + if (value == msrs->values[slot].curr) return 0; - err = wrmsrl_safe(shared_msrs_global.msrs[slot], value); + err = wrmsrl_safe(user_return_msrs_global.msrs[slot], value); if (err) return 1; - smsr->values[slot].curr = value; - if (!smsr->registered) { - smsr->urn.on_user_return = kvm_on_user_return; - user_return_notifier_register(&smsr->urn); - smsr->registered = true; + msrs->values[slot].curr = value; + if (!msrs->registered) { + msrs->urn.on_user_return = kvm_on_user_return; + user_return_notifier_register(&msrs->urn); + msrs->registered = true; } return 0; } -EXPORT_SYMBOL_GPL(kvm_set_shared_msr); +EXPORT_SYMBOL_GPL(kvm_set_user_return_msr); static void drop_user_return_notifiers(void) { unsigned int cpu = smp_processor_id(); - struct kvm_shared_msrs *smsr = per_cpu_ptr(shared_msrs, cpu); + struct kvm_user_return_msrs *msrs = per_cpu_ptr(user_return_msrs, cpu); - if (smsr->registered) - kvm_on_user_return(&smsr->urn); + if (msrs->registered) + kvm_on_user_return(&msrs->urn); } u64 kvm_get_apic_base(struct kvm_vcpu *vcpu) @@ -976,6 +982,7 @@ 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)) return 1; @@ -1003,7 +1010,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) if (kvm_x86_ops.set_cr4(vcpu, cr4)) return 1; - if (((cr4 ^ old_cr4) & pdptr_bits) || + if (((cr4 ^ old_cr4) & mmu_role_bits) || (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE))) kvm_mmu_reset_context(vcpu); @@ -1451,6 +1458,7 @@ static int set_efer(struct kvm_vcpu *vcpu, struct msr_data *msr_info) { u64 old_efer = vcpu->arch.efer; u64 efer = msr_info->data; + int r; if (efer & efer_reserved_bits) return 1; @@ -1467,7 +1475,11 @@ static int set_efer(struct kvm_vcpu *vcpu, struct msr_data *msr_info) efer &= ~EFER_LMA; efer |= vcpu->arch.efer & EFER_LMA; - kvm_x86_ops.set_efer(vcpu, efer); + r = kvm_x86_ops.set_efer(vcpu, efer); + if (r) { + WARN_ON(r > 0); + return r; + } /* Update reserved bits */ if ((efer ^ old_efer) & EFER_NX) @@ -1482,6 +1494,40 @@ void kvm_enable_efer_bits(u64 mask) } EXPORT_SYMBOL_GPL(kvm_enable_efer_bits); +bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type) +{ + struct kvm *kvm = vcpu->kvm; + struct msr_bitmap_range *ranges = kvm->arch.msr_filter.ranges; + u32 count = kvm->arch.msr_filter.count; + u32 i; + bool r = kvm->arch.msr_filter.default_allow; + int idx; + + /* MSR filtering not set up or x2APIC enabled, allow everything */ + if (!count || (index >= 0x800 && index <= 0x8ff)) + return true; + + /* Prevent collision with set_msr_filter */ + idx = srcu_read_lock(&kvm->srcu); + + for (i = 0; i < count; i++) { + u32 start = ranges[i].base; + u32 end = start + ranges[i].nmsrs; + u32 flags = ranges[i].flags; + unsigned long *bitmap = ranges[i].bitmap; + + if ((index >= start) && (index < end) && (flags & type)) { + r = !!test_bit(index - start, bitmap); + break; + } + } + + srcu_read_unlock(&kvm->srcu, idx); + + return r; +} +EXPORT_SYMBOL_GPL(kvm_msr_allowed); + /* * Write @data into the MSR specified by @index. Select MSR specific fault * checks are bypassed if @host_initiated is %true. @@ -1493,6 +1539,9 @@ static int __kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data, { struct msr_data msr; + if (!host_initiated && !kvm_msr_allowed(vcpu, index, KVM_MSR_FILTER_WRITE)) + return -EPERM; + switch (index) { case MSR_FS_BASE: case MSR_GS_BASE: @@ -1549,6 +1598,9 @@ int __kvm_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data, struct msr_data msr; int ret; + if (!host_initiated && !kvm_msr_allowed(vcpu, index, KVM_MSR_FILTER_READ)) + return -EPERM; + msr.index = index; msr.host_initiated = host_initiated; @@ -1584,12 +1636,91 @@ 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) +{ + if (vcpu->run->msr.error) { + kvm_inject_gp(vcpu, 0); + return 1; + } else if (is_read) { + 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); +} + +static int complete_emulated_wrmsr(struct kvm_vcpu *vcpu) +{ + return complete_emulated_msr(vcpu, false); +} + +static u64 kvm_msr_reason(int r) +{ + switch (r) { + case -ENOENT: + return KVM_MSR_EXIT_REASON_UNKNOWN; + case -EPERM: + return KVM_MSR_EXIT_REASON_FILTER; + default: + return KVM_MSR_EXIT_REASON_INVAL; + } +} + +static int kvm_msr_user_space(struct kvm_vcpu *vcpu, u32 index, + u32 exit_reason, u64 data, + int (*completion)(struct kvm_vcpu *vcpu), + int r) +{ + u64 msr_reason = kvm_msr_reason(r); + + /* Check if the user wanted to know about this MSR fault */ + if (!(vcpu->kvm->arch.user_space_msr_mask & msr_reason)) + return 0; + + vcpu->run->exit_reason = exit_reason; + vcpu->run->msr.error = 0; + memset(vcpu->run->msr.pad, 0, sizeof(vcpu->run->msr.pad)); + vcpu->run->msr.reason = msr_reason; + vcpu->run->msr.index = index; + vcpu->run->msr.data = data; + vcpu->arch.complete_userspace_io = completion; + + return 1; +} + +static int kvm_get_msr_user_space(struct kvm_vcpu *vcpu, u32 index, int r) +{ + return kvm_msr_user_space(vcpu, index, KVM_EXIT_X86_RDMSR, 0, + complete_emulated_rdmsr, r); +} + +static int kvm_set_msr_user_space(struct kvm_vcpu *vcpu, u32 index, u64 data, int r) +{ + return kvm_msr_user_space(vcpu, index, KVM_EXIT_X86_WRMSR, data, + complete_emulated_wrmsr, r); +} + int kvm_emulate_rdmsr(struct kvm_vcpu *vcpu) { u32 ecx = kvm_rcx_read(vcpu); u64 data; + int r; + + r = kvm_get_msr(vcpu, ecx, &data); - if (kvm_get_msr(vcpu, ecx, &data)) { + /* MSR read failed? See if we should ask user space */ + if (r && kvm_get_msr_user_space(vcpu, ecx, r)) { + /* Bounce to user space */ + return 0; + } + + /* MSR read failed? Inject a #GP */ + if (r) { trace_kvm_msr_read_ex(ecx); kvm_inject_gp(vcpu, 0); return 1; @@ -1607,8 +1738,21 @@ int kvm_emulate_wrmsr(struct kvm_vcpu *vcpu) { u32 ecx = kvm_rcx_read(vcpu); u64 data = kvm_read_edx_eax(vcpu); + int r; - if (kvm_set_msr(vcpu, ecx, data)) { + r = kvm_set_msr(vcpu, ecx, data); + + /* MSR write failed? See if we should ask user space */ + if (r && kvm_set_msr_user_space(vcpu, ecx, data, r)) + /* Bounce to user space */ + return 0; + + /* Signal all other negative errors to userspace */ + if (r < 0) + return r; + + /* MSR write failed? Inject a #GP */ + if (r > 0) { trace_kvm_msr_write_ex(ecx, data); kvm_inject_gp(vcpu, 0); return 1; @@ -1774,12 +1918,6 @@ static s64 get_kvmclock_base_ns(void) } #endif -void kvm_set_pending_timer(struct kvm_vcpu *vcpu) -{ - kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu); - kvm_vcpu_kick(vcpu); -} - static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) { int version; @@ -1787,6 +1925,8 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) struct pvclock_wall_clock wc; u64 wall_nsec; + kvm->arch.wall_clock = wall_clock; + if (!wall_clock) return; @@ -1819,6 +1959,34 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); } +static void kvm_write_system_time(struct kvm_vcpu *vcpu, gpa_t system_time, + bool old_msr, bool host_initiated) +{ + struct kvm_arch *ka = &vcpu->kvm->arch; + + if (vcpu->vcpu_id == 0 && !host_initiated) { + if (ka->boot_vcpu_runs_old_kvmclock && old_msr) + kvm_make_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu); + + ka->boot_vcpu_runs_old_kvmclock = old_msr; + } + + vcpu->arch.time = system_time; + kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu); + + /* we verify if the enable bit is set... */ + vcpu->arch.pv_time_enabled = false; + if (!(system_time & 1)) + return; + + if (!kvm_gfn_to_hva_cache_init(vcpu->kvm, + &vcpu->arch.pv_time, system_time & ~1ULL, + sizeof(struct pvclock_vcpu_time_info))) + vcpu->arch.pv_time_enabled = true; + + return; +} + static uint32_t div_frac(uint32_t dividend, uint32_t divisor) { do_shl32_div32(dividend, divisor); @@ -1978,12 +2146,6 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu) #endif } -static void update_ia32_tsc_adjust_msr(struct kvm_vcpu *vcpu, s64 offset) -{ - u64 curr_offset = vcpu->arch.l1_tsc_offset; - vcpu->arch.ia32_tsc_adjust_msr += offset - curr_offset; -} - /* * Multiply tsc by a fixed point number represented by ratio. * @@ -2045,14 +2207,13 @@ static inline bool kvm_check_tsc_unstable(void) return check_tsc_unstable(); } -void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr) +static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data) { struct kvm *kvm = vcpu->kvm; u64 offset, ns, elapsed; unsigned long flags; bool matched; bool already_matched; - u64 data = msr->data; bool synchronizing = false; raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags); @@ -2061,7 +2222,7 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr) elapsed = ns - kvm->arch.last_tsc_nsec; if (vcpu->arch.virtual_tsc_khz) { - if (data == 0 && msr->host_initiated) { + if (data == 0) { /* * detection of vcpu initialization -- need to sync * with other vCPUs. This particularly helps to keep @@ -2131,9 +2292,6 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr) vcpu->arch.this_tsc_nsec = kvm->arch.cur_tsc_nsec; vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write; - if (!msr->host_initiated && guest_cpuid_has(vcpu, X86_FEATURE_TSC_ADJUST)) - update_ia32_tsc_adjust_msr(vcpu, offset); - kvm_vcpu_write_tsc_offset(vcpu, offset); raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags); @@ -2148,8 +2306,6 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr) spin_unlock(&kvm->arch.pvclock_gtod_sync_lock); } -EXPORT_SYMBOL_GPL(kvm_write_tsc); - static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu, s64 adjustment) { @@ -2695,24 +2851,19 @@ static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data) u32 page_num = data & ~PAGE_MASK; u64 page_addr = data & PAGE_MASK; u8 *page; - int r; - r = -E2BIG; if (page_num >= blob_size) - goto out; - r = -ENOMEM; + return 1; + page = memdup_user(blob_addr + (page_num * PAGE_SIZE), PAGE_SIZE); - if (IS_ERR(page)) { - r = PTR_ERR(page); - goto out; + if (IS_ERR(page)) + return PTR_ERR(page); + + if (kvm_vcpu_write_guest(vcpu, page_addr, page, PAGE_SIZE)) { + kfree(page); + return 1; } - if (kvm_vcpu_write_guest(vcpu, page_addr, page, PAGE_SIZE)) - goto out_free; - r = 0; -out_free: - kfree(page); -out: - return r; + return 0; } static inline bool kvm_pv_async_pf_enabled(struct kvm_vcpu *vcpu) @@ -2730,9 +2881,17 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) if (data & 0x30) return 1; - if (!lapic_in_kernel(vcpu)) + if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF_VMEXIT) && + (data & KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT)) + return 1; + + if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF_INT) && + (data & KVM_ASYNC_PF_DELIVERY_AS_INT)) return 1; + if (!lapic_in_kernel(vcpu)) + return data ? 1 : 0; + vcpu->arch.apf.msr_en_val = data; if (!kvm_pv_async_pf_enabled(vcpu)) { @@ -2807,10 +2966,12 @@ static void record_steal_time(struct kvm_vcpu *vcpu) * Doing a TLB flush here, on the guest's behalf, can avoid * expensive IPIs. */ - trace_kvm_pv_tlb_flush(vcpu->vcpu_id, - st->preempted & KVM_VCPU_FLUSH_TLB); - if (xchg(&st->preempted, 0) & KVM_VCPU_FLUSH_TLB) - kvm_vcpu_flush_tlb_guest(vcpu); + if (guest_pv_has(vcpu, KVM_FEATURE_PV_TLB_FLUSH)) { + trace_kvm_pv_tlb_flush(vcpu->vcpu_id, + st->preempted & KVM_VCPU_FLUSH_TLB); + if (xchg(&st->preempted, 0) & KVM_VCPU_FLUSH_TLB) + kvm_vcpu_flush_tlb_guest(vcpu); + } vcpu->arch.st.preempted = 0; @@ -2944,7 +3105,13 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) vcpu->arch.msr_ia32_power_ctl = data; break; case MSR_IA32_TSC: - kvm_write_tsc(vcpu, msr_info); + if (msr_info->host_initiated) { + kvm_synchronize_tsc(vcpu, data); + } else { + u64 adj = kvm_compute_tsc_offset(vcpu, data) - vcpu->arch.l1_tsc_offset; + adjust_tsc_offset_guest(vcpu, adj); + vcpu->arch.ia32_tsc_adjust_msr += adj; + } break; case MSR_IA32_XSS: if (!msr_info->host_initiated && @@ -2965,53 +3132,54 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) vcpu->arch.smi_count = data; break; case MSR_KVM_WALL_CLOCK_NEW: + if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE2)) + return 1; + + kvm_write_wall_clock(vcpu->kvm, data); + break; case MSR_KVM_WALL_CLOCK: - vcpu->kvm->arch.wall_clock = data; + if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE)) + return 1; + kvm_write_wall_clock(vcpu->kvm, data); break; case MSR_KVM_SYSTEM_TIME_NEW: - case MSR_KVM_SYSTEM_TIME: { - struct kvm_arch *ka = &vcpu->kvm->arch; - - if (vcpu->vcpu_id == 0 && !msr_info->host_initiated) { - bool tmp = (msr == MSR_KVM_SYSTEM_TIME); - - if (ka->boot_vcpu_runs_old_kvmclock != tmp) - kvm_make_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu); - - ka->boot_vcpu_runs_old_kvmclock = tmp; - } - - vcpu->arch.time = data; - kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu); - - /* we verify if the enable bit is set... */ - vcpu->arch.pv_time_enabled = false; - if (!(data & 1)) - break; + if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE2)) + return 1; - if (!kvm_gfn_to_hva_cache_init(vcpu->kvm, - &vcpu->arch.pv_time, data & ~1ULL, - sizeof(struct pvclock_vcpu_time_info))) - vcpu->arch.pv_time_enabled = true; + kvm_write_system_time(vcpu, data, false, msr_info->host_initiated); + break; + case MSR_KVM_SYSTEM_TIME: + if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE)) + return 1; + kvm_write_system_time(vcpu, data, true, msr_info->host_initiated); break; - } case MSR_KVM_ASYNC_PF_EN: + if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF)) + return 1; + if (kvm_pv_enable_async_pf(vcpu, data)) return 1; break; case MSR_KVM_ASYNC_PF_INT: + if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF_INT)) + return 1; + if (kvm_pv_enable_async_pf_int(vcpu, data)) return 1; break; case MSR_KVM_ASYNC_PF_ACK: + if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF)) + return 1; if (data & 0x1) { vcpu->arch.apf.pageready_pending = false; kvm_check_async_pf_completion(vcpu); } break; case MSR_KVM_STEAL_TIME: + if (!guest_pv_has(vcpu, KVM_FEATURE_STEAL_TIME)) + return 1; if (unlikely(!sched_info_on())) return 1; @@ -3028,11 +3196,17 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) break; case MSR_KVM_PV_EOI_EN: + if (!guest_pv_has(vcpu, KVM_FEATURE_PV_EOI)) + return 1; + if (kvm_lapic_enable_pv_eoi(vcpu, data, sizeof(u8))) return 1; break; case MSR_KVM_POLL_CONTROL: + if (!guest_pv_has(vcpu, KVM_FEATURE_POLL_CONTROL)) + return 1; + /* only enable bit supported */ if (data & (-1ULL << 1)) return 1; @@ -3221,9 +3395,22 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_IA32_POWER_CTL: msr_info->data = vcpu->arch.msr_ia32_power_ctl; break; - case MSR_IA32_TSC: - msr_info->data = kvm_scale_tsc(vcpu, rdtsc()) + vcpu->arch.tsc_offset; + case MSR_IA32_TSC: { + /* + * Intel SDM states that MSR_IA32_TSC read adds the TSC offset + * even when not intercepted. AMD manual doesn't explicitly + * state this but appears to behave the same. + * + * On userspace reads and writes, however, we unconditionally + * return L1's TSC value to ensure backwards-compatible + * behavior for migration. + */ + u64 tsc_offset = msr_info->host_initiated ? vcpu->arch.l1_tsc_offset : + vcpu->arch.tsc_offset; + + msr_info->data = kvm_scale_tsc(vcpu, rdtsc()) + tsc_offset; break; + } case MSR_MTRRcap: case 0x200 ... 0x2ff: return kvm_mtrr_get_msr(vcpu, msr_info->index, &msr_info->data); @@ -3513,6 +3700,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_EXCEPTION_PAYLOAD: case KVM_CAP_SET_GUEST_DEBUG: case KVM_CAP_LAST_CPU: + case KVM_CAP_X86_USER_SPACE_MSR: + case KVM_CAP_X86_MSR_FILTER: + case KVM_CAP_ENFORCE_PV_FEATURE_CPUID: r = 1; break; case KVM_CAP_SYNC_REGS: @@ -4383,6 +4573,11 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, return kvm_x86_ops.enable_direct_tlbflush(vcpu); + case KVM_CAP_ENFORCE_PV_FEATURE_CPUID: + vcpu->arch.pv_cpuid.enforce = cap->args[0]; + + return 0; + default: return -EINVAL; } @@ -5033,6 +5228,10 @@ split_irqchip_unlock: kvm->arch.exception_payload_enabled = cap->args[0]; r = 0; break; + case KVM_CAP_X86_USER_SPACE_MSR: + kvm->arch.user_space_msr_mask = cap->args[0]; + r = 0; + break; default: r = -EINVAL; break; @@ -5040,6 +5239,110 @@ split_irqchip_unlock: return r; } +static void kvm_clear_msr_filter(struct kvm *kvm) +{ + u32 i; + u32 count = kvm->arch.msr_filter.count; + struct msr_bitmap_range ranges[16]; + + mutex_lock(&kvm->lock); + kvm->arch.msr_filter.count = 0; + memcpy(ranges, kvm->arch.msr_filter.ranges, count * sizeof(ranges[0])); + mutex_unlock(&kvm->lock); + synchronize_srcu(&kvm->srcu); + + for (i = 0; i < count; i++) + kfree(ranges[i].bitmap); +} + +static int kvm_add_msr_filter(struct kvm *kvm, struct kvm_msr_filter_range *user_range) +{ + struct msr_bitmap_range *ranges = kvm->arch.msr_filter.ranges; + struct msr_bitmap_range range; + unsigned long *bitmap = NULL; + size_t bitmap_size; + int r; + + if (!user_range->nmsrs) + return 0; + + bitmap_size = BITS_TO_LONGS(user_range->nmsrs) * sizeof(long); + if (!bitmap_size || bitmap_size > KVM_MSR_FILTER_MAX_BITMAP_SIZE) + return -EINVAL; + + bitmap = memdup_user((__user u8*)user_range->bitmap, bitmap_size); + if (IS_ERR(bitmap)) + return PTR_ERR(bitmap); + + range = (struct msr_bitmap_range) { + .flags = user_range->flags, + .base = user_range->base, + .nmsrs = user_range->nmsrs, + .bitmap = bitmap, + }; + + if (range.flags & ~(KVM_MSR_FILTER_READ | KVM_MSR_FILTER_WRITE)) { + r = -EINVAL; + goto err; + } + + if (!range.flags) { + r = -EINVAL; + goto err; + } + + /* Everything ok, add this range identifier to our global pool */ + ranges[kvm->arch.msr_filter.count] = range; + /* Make sure we filled the array before we tell anyone to walk it */ + smp_wmb(); + kvm->arch.msr_filter.count++; + + return 0; +err: + kfree(bitmap); + return r; +} + +static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, void __user *argp) +{ + struct kvm_msr_filter __user *user_msr_filter = argp; + struct kvm_msr_filter filter; + bool default_allow; + int r = 0; + bool empty = true; + u32 i; + + if (copy_from_user(&filter, user_msr_filter, sizeof(filter))) + return -EFAULT; + + for (i = 0; i < ARRAY_SIZE(filter.ranges); i++) + empty &= !filter.ranges[i].nmsrs; + + default_allow = !(filter.flags & KVM_MSR_FILTER_DEFAULT_DENY); + if (empty && !default_allow) + return -EINVAL; + + kvm_clear_msr_filter(kvm); + + kvm->arch.msr_filter.default_allow = default_allow; + + /* + * Protect from concurrent calls to this function that could trigger + * a TOCTOU violation on kvm->arch.msr_filter.count. + */ + mutex_lock(&kvm->lock); + for (i = 0; i < ARRAY_SIZE(filter.ranges); i++) { + r = kvm_add_msr_filter(kvm, &filter.ranges[i]); + if (r) + break; + } + + kvm_make_all_cpus_request(kvm, KVM_REQ_MSR_FILTER_CHANGED); + mutex_unlock(&kvm->lock); + + return r; +} + long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -5346,6 +5649,9 @@ set_pit2_out: case KVM_SET_PMU_EVENT_FILTER: r = kvm_vm_ioctl_set_pmu_event_filter(kvm, argp); break; + case KVM_X86_SET_MSR_FILTER: + r = kvm_vm_ioctl_set_msr_filter(kvm, argp); + break; default: r = -ENOTTY; } @@ -5707,6 +6013,9 @@ int handle_ud(struct kvm_vcpu *vcpu) char sig[5]; /* ud2; .ascii "kvm" */ struct x86_exception e; + if (unlikely(!kvm_x86_ops.can_emulate_instruction(vcpu, NULL, 0))) + return 1; + if (force_emulation_prefix && kvm_read_guest_virt(vcpu, kvm_get_linear_rip(vcpu), sig, sizeof(sig), &e) == 0 && @@ -6362,13 +6671,33 @@ static void emulator_set_segment(struct x86_emulate_ctxt *ctxt, u16 selector, static int emulator_get_msr(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata) { - return kvm_get_msr(emul_to_vcpu(ctxt), msr_index, pdata); + struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); + int r; + + r = kvm_get_msr(vcpu, msr_index, pdata); + + if (r && kvm_get_msr_user_space(vcpu, msr_index, r)) { + /* Bounce to user space */ + return X86EMUL_IO_NEEDED; + } + + return r; } static int emulator_set_msr(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 data) { - return kvm_set_msr(emul_to_vcpu(ctxt), msr_index, data); + struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); + int r; + + r = kvm_set_msr(vcpu, msr_index, data); + + if (r && kvm_set_msr_user_space(vcpu, msr_index, data, r)) { + /* Bounce to user space */ + return X86EMUL_IO_NEEDED; + } + + return r; } static u64 emulator_get_smbase(struct x86_emulate_ctxt *ctxt) @@ -6912,7 +7241,10 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, int r; struct x86_emulate_ctxt *ctxt = vcpu->arch.emulate_ctxt; bool writeback = true; - bool write_fault_to_spt = vcpu->arch.write_fault_to_shadow_pgtable; + bool write_fault_to_spt; + + if (unlikely(!kvm_x86_ops.can_emulate_instruction(vcpu, insn, insn_len))) + return 1; vcpu->arch.l1tf_flush_l1d = true; @@ -6920,6 +7252,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, * Clear write_fault_to_shadow_pgtable here to ensure it is * never reused. */ + write_fault_to_spt = vcpu->arch.write_fault_to_shadow_pgtable; vcpu->arch.write_fault_to_shadow_pgtable = false; kvm_clear_exception_queue(vcpu); @@ -7514,9 +7847,9 @@ int kvm_arch_init(void *opaque) goto out_free_x86_fpu_cache; } - shared_msrs = alloc_percpu(struct kvm_shared_msrs); - if (!shared_msrs) { - printk(KERN_ERR "kvm: failed to allocate percpu kvm_shared_msrs\n"); + user_return_msrs = alloc_percpu(struct kvm_user_return_msrs); + if (!user_return_msrs) { + printk(KERN_ERR "kvm: failed to allocate percpu kvm_user_return_msrs\n"); goto out_free_x86_emulator_cache; } @@ -7549,7 +7882,7 @@ int kvm_arch_init(void *opaque) return 0; out_free_percpu: - free_percpu(shared_msrs); + free_percpu(user_return_msrs); out_free_x86_emulator_cache: kmem_cache_destroy(x86_emulator_cache); out_free_x86_fpu_cache: @@ -7576,7 +7909,7 @@ void kvm_arch_exit(void) #endif kvm_x86_ops.hardware_enable = NULL; kvm_mmu_module_exit(); - free_percpu(shared_msrs); + free_percpu(user_return_msrs); kmem_cache_destroy(x86_fpu_cache); } @@ -7717,11 +8050,16 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) goto out; } + ret = -KVM_ENOSYS; + switch (nr) { case KVM_HC_VAPIC_POLL_IRQ: ret = 0; break; case KVM_HC_KICK_CPU: + if (!guest_pv_has(vcpu, KVM_FEATURE_PV_UNHALT)) + break; + kvm_pv_kick_cpu_op(vcpu->kvm, a0, a1); kvm_sched_yield(vcpu->kvm, a1); ret = 0; @@ -7732,9 +8070,15 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) break; #endif case KVM_HC_SEND_IPI: + if (!guest_pv_has(vcpu, KVM_FEATURE_PV_SEND_IPI)) + break; + ret = kvm_pv_send_ipi(vcpu->kvm, a0, a1, a2, a3, op_64_bit); break; case KVM_HC_SCHED_YIELD: + if (!guest_pv_has(vcpu, KVM_FEATURE_PV_SCHED_YIELD)) + break; + kvm_sched_yield(vcpu->kvm, a0); ret = 0; break; @@ -8365,8 +8709,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) bool req_immediate_exit = false; if (kvm_request_pending(vcpu)) { - if (kvm_check_request(KVM_REQ_GET_VMCS12_PAGES, vcpu)) { - if (unlikely(!kvm_x86_ops.nested_ops->get_vmcs12_pages(vcpu))) { + if (kvm_check_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu)) { + if (unlikely(!kvm_x86_ops.nested_ops->get_nested_state_pages(vcpu))) { r = 0; goto out; } @@ -8473,6 +8817,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) kvm_vcpu_update_apicv(vcpu); if (kvm_check_request(KVM_REQ_APF_READY, vcpu)) kvm_check_async_pf_completion(vcpu); + if (kvm_check_request(KVM_REQ_MSR_FILTER_CHANGED, vcpu)) + kvm_x86_ops.msr_filter_changed(vcpu); } if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) { @@ -8548,7 +8894,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) kvm_x86_ops.request_immediate_exit(vcpu); } - trace_kvm_entry(vcpu->vcpu_id); + trace_kvm_entry(vcpu); fpregs_assert_state_consistent(); if (test_thread_flag(TIF_NEED_FPU_LOAD)) @@ -9562,7 +9908,6 @@ fail_mmu_destroy: void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) { - struct msr_data msr; struct kvm *kvm = vcpu->kvm; kvm_hv_vcpu_postcreate(vcpu); @@ -9570,10 +9915,7 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) if (mutex_lock_killable(&vcpu->mutex)) return; vcpu_load(vcpu); - msr.data = 0x0; - msr.index = MSR_IA32_TSC; - msr.host_initiated = true; - kvm_write_tsc(vcpu, &msr); + kvm_synchronize_tsc(vcpu, 0); vcpu_put(vcpu); /* poll control enabled by default */ @@ -9610,6 +9952,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) kvm_mmu_destroy(vcpu); srcu_read_unlock(&vcpu->kvm->srcu, idx); free_page((unsigned long)vcpu->arch.pio_data); + kvfree(vcpu->arch.cpuid_entries); if (!lapic_in_kernel(vcpu)) static_key_slow_dec(&kvm_no_apic_vcpu); } @@ -9707,7 +10050,7 @@ int kvm_arch_hardware_enable(void) u64 max_tsc = 0; bool stable, backwards_tsc = false; - kvm_shared_msr_cpu_online(); + kvm_user_return_msr_cpu_online(); ret = kvm_x86_ops.hardware_enable(); if (ret != 0) return ret; @@ -10025,6 +10368,8 @@ void kvm_arch_pre_destroy_vm(struct kvm *kvm) void kvm_arch_destroy_vm(struct kvm *kvm) { + u32 i; + if (current->mm == kvm->mm) { /* * Free memory regions allocated on behalf of userspace, @@ -10041,6 +10386,8 @@ void kvm_arch_destroy_vm(struct kvm *kvm) } if (kvm_x86_ops.vm_destroy) kvm_x86_ops.vm_destroy(kvm); + for (i = 0; i < kvm->arch.msr_filter.count; i++) + kfree(kvm->arch.msr_filter.ranges[i].bitmap); kvm_pic_destroy(kvm); kvm_ioapic_destroy(kvm); kvm_free_vcpus(kvm); @@ -10771,6 +11118,111 @@ void kvm_fixup_and_inject_pf_error(struct kvm_vcpu *vcpu, gva_t gva, u16 error_c } EXPORT_SYMBOL_GPL(kvm_fixup_and_inject_pf_error); +/* + * Handles kvm_read/write_guest_virt*() result and either injects #PF or returns + * KVM_EXIT_INTERNAL_ERROR for cases not currently handled by KVM. Return value + * indicates whether exit to userspace is needed. + */ +int kvm_handle_memory_failure(struct kvm_vcpu *vcpu, int r, + struct x86_exception *e) +{ + if (r == X86EMUL_PROPAGATE_FAULT) { + kvm_inject_emulated_page_fault(vcpu, e); + return 1; + } + + /* + * In case kvm_read/write_guest_virt*() failed with X86EMUL_IO_NEEDED + * while handling a VMX instruction KVM could've handled the request + * correctly by exiting to userspace and performing I/O but there + * doesn't seem to be a real use-case behind such requests, just return + * KVM_EXIT_INTERNAL_ERROR for now. + */ + vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; + vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; + vcpu->run->internal.ndata = 0; + + return 0; +} +EXPORT_SYMBOL_GPL(kvm_handle_memory_failure); + +int kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsigned long type, gva_t gva) +{ + bool pcid_enabled; + struct x86_exception e; + unsigned i; + unsigned long roots_to_free = 0; + struct { + u64 pcid; + u64 gla; + } operand; + int r; + + r = kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e); + if (r != X86EMUL_CONTINUE) + return kvm_handle_memory_failure(vcpu, r, &e); + + if (operand.pcid >> 12 != 0) { + kvm_inject_gp(vcpu, 0); + return 1; + } + + pcid_enabled = kvm_read_cr4_bits(vcpu, X86_CR4_PCIDE); + + switch (type) { + case INVPCID_TYPE_INDIV_ADDR: + if ((!pcid_enabled && (operand.pcid != 0)) || + is_noncanonical_address(operand.gla, vcpu)) { + kvm_inject_gp(vcpu, 0); + return 1; + } + kvm_mmu_invpcid_gva(vcpu, operand.gla, operand.pcid); + return kvm_skip_emulated_instruction(vcpu); + + case INVPCID_TYPE_SINGLE_CTXT: + if (!pcid_enabled && (operand.pcid != 0)) { + kvm_inject_gp(vcpu, 0); + return 1; + } + + if (kvm_get_active_pcid(vcpu) == operand.pcid) { + kvm_mmu_sync_roots(vcpu); + kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); + } + + for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++) + if (kvm_get_pcid(vcpu, vcpu->arch.mmu->prev_roots[i].pgd) + == operand.pcid) + roots_to_free |= KVM_MMU_ROOT_PREVIOUS(i); + + kvm_mmu_free_roots(vcpu, vcpu->arch.mmu, roots_to_free); + /* + * If neither the current cr3 nor any of the prev_roots use the + * given PCID, then nothing needs to be done here because a + * resync will happen anyway before switching to any other CR3. + */ + + return kvm_skip_emulated_instruction(vcpu); + + case INVPCID_TYPE_ALL_NON_GLOBAL: + /* + * Currently, KVM doesn't mark global entries in the shadow + * page tables, so a non-global flush just degenerates to a + * global flush. If needed, we could optimize this later by + * keeping track of global entries in shadow page tables. + */ + + fallthrough; + case INVPCID_TYPE_ALL_INCL_GLOBAL: + kvm_mmu_unload(vcpu); + return kvm_skip_emulated_instruction(vcpu); + + default: + BUG(); /* We have already checked above that type <= 3 */ + } +} +EXPORT_SYMBOL_GPL(kvm_handle_invpcid); + EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_fast_mmio); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq); diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 995ab696dcf0..3900ab0c6004 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -246,7 +246,6 @@ static inline bool kvm_vcpu_latch_init(struct kvm_vcpu *vcpu) return is_smm(vcpu) || kvm_x86_ops.apic_init_signal_blocked(vcpu); } -void kvm_set_pending_timer(struct kvm_vcpu *vcpu); void kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip); void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr); @@ -372,6 +371,10 @@ 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_vcpu_exit_request(struct kvm_vcpu *vcpu); +int kvm_handle_memory_failure(struct kvm_vcpu *vcpu, int r, + struct x86_exception *e); +int kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsigned long type, gva_t gva); +bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type); #define KVM_MSR_RET_INVALID 2 diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index aa067859a70b..bad4dee4f0e4 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_SMP) += msr-smp.o cache-smp.o lib-y := delay.o misc.o cmdline.o cpu.o lib-y += usercopy_$(BITS).o usercopy.o getuser.o putuser.o lib-y += memcpy_$(BITS).o +lib-$(CONFIG_ARCH_HAS_COPY_MC) += copy_mc.o copy_mc_64.o lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o insn-eval.o lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o lib-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o diff --git a/arch/x86/lib/checksum_32.S b/arch/x86/lib/checksum_32.S index d1d768912368..4304320e51f4 100644 --- a/arch/x86/lib/checksum_32.S +++ b/arch/x86/lib/checksum_32.S @@ -253,28 +253,17 @@ EXPORT_SYMBOL(csum_partial) /* unsigned int csum_partial_copy_generic (const char *src, char *dst, - int len, int sum, int *src_err_ptr, int *dst_err_ptr) + int len) */ /* * Copy from ds while checksumming, otherwise like csum_partial - * - * The macros SRC and DST specify the type of access for the instruction. - * thus we can call a custom exception handler for all access types. - * - * FIXME: could someone double-check whether I haven't mixed up some SRC and - * DST definitions? It's damn hard to trigger all cases. I hope I got - * them all but there's no guarantee. */ -#define SRC(y...) \ +#define EXC(y...) \ 9999: y; \ _ASM_EXTABLE_UA(9999b, 6001f) -#define DST(y...) \ - 9999: y; \ - _ASM_EXTABLE_UA(9999b, 6002f) - #ifndef CONFIG_X86_USE_PPRO_CHECKSUM #define ARGBASE 16 @@ -285,20 +274,20 @@ SYM_FUNC_START(csum_partial_copy_generic) pushl %edi pushl %esi pushl %ebx - movl ARGBASE+16(%esp),%eax # sum movl ARGBASE+12(%esp),%ecx # len movl ARGBASE+4(%esp),%esi # src movl ARGBASE+8(%esp),%edi # dst + movl $-1, %eax # sum testl $2, %edi # Check alignment. jz 2f # Jump if alignment is ok. subl $2, %ecx # Alignment uses up two bytes. jae 1f # Jump if we had at least two bytes. addl $2, %ecx # ecx was < 2. Deal with it. jmp 4f -SRC(1: movw (%esi), %bx ) +EXC(1: movw (%esi), %bx ) addl $2, %esi -DST( movw %bx, (%edi) ) +EXC( movw %bx, (%edi) ) addl $2, %edi addw %bx, %ax adcl $0, %eax @@ -306,34 +295,34 @@ DST( movw %bx, (%edi) ) movl %ecx, FP(%esp) shrl $5, %ecx jz 2f - testl %esi, %esi -SRC(1: movl (%esi), %ebx ) -SRC( movl 4(%esi), %edx ) + testl %esi, %esi # what's wrong with clc? +EXC(1: movl (%esi), %ebx ) +EXC( movl 4(%esi), %edx ) adcl %ebx, %eax -DST( movl %ebx, (%edi) ) +EXC( movl %ebx, (%edi) ) adcl %edx, %eax -DST( movl %edx, 4(%edi) ) +EXC( movl %edx, 4(%edi) ) -SRC( movl 8(%esi), %ebx ) -SRC( movl 12(%esi), %edx ) +EXC( movl 8(%esi), %ebx ) +EXC( movl 12(%esi), %edx ) adcl %ebx, %eax -DST( movl %ebx, 8(%edi) ) +EXC( movl %ebx, 8(%edi) ) adcl %edx, %eax -DST( movl %edx, 12(%edi) ) +EXC( movl %edx, 12(%edi) ) -SRC( movl 16(%esi), %ebx ) -SRC( movl 20(%esi), %edx ) +EXC( movl 16(%esi), %ebx ) +EXC( movl 20(%esi), %edx ) adcl %ebx, %eax -DST( movl %ebx, 16(%edi) ) +EXC( movl %ebx, 16(%edi) ) adcl %edx, %eax -DST( movl %edx, 20(%edi) ) +EXC( movl %edx, 20(%edi) ) -SRC( movl 24(%esi), %ebx ) -SRC( movl 28(%esi), %edx ) +EXC( movl 24(%esi), %ebx ) +EXC( movl 28(%esi), %edx ) adcl %ebx, %eax -DST( movl %ebx, 24(%edi) ) +EXC( movl %ebx, 24(%edi) ) adcl %edx, %eax -DST( movl %edx, 28(%edi) ) +EXC( movl %edx, 28(%edi) ) lea 32(%esi), %esi lea 32(%edi), %edi @@ -345,9 +334,9 @@ DST( movl %edx, 28(%edi) ) andl $0x1c, %edx je 4f shrl $2, %edx # This clears CF -SRC(3: movl (%esi), %ebx ) +EXC(3: movl (%esi), %ebx ) adcl %ebx, %eax -DST( movl %ebx, (%edi) ) +EXC( movl %ebx, (%edi) ) lea 4(%esi), %esi lea 4(%edi), %edi dec %edx @@ -357,39 +346,24 @@ DST( movl %ebx, (%edi) ) jz 7f cmpl $2, %ecx jb 5f -SRC( movw (%esi), %cx ) +EXC( movw (%esi), %cx ) leal 2(%esi), %esi -DST( movw %cx, (%edi) ) +EXC( movw %cx, (%edi) ) leal 2(%edi), %edi je 6f shll $16,%ecx -SRC(5: movb (%esi), %cl ) -DST( movb %cl, (%edi) ) +EXC(5: movb (%esi), %cl ) +EXC( movb %cl, (%edi) ) 6: addl %ecx, %eax adcl $0, %eax 7: -5000: # Exception handler: .section .fixup, "ax" 6001: - movl ARGBASE+20(%esp), %ebx # src_err_ptr - movl $-EFAULT, (%ebx) - - # zero the complete destination - computing the rest - # is too much work - movl ARGBASE+8(%esp), %edi # dst - movl ARGBASE+12(%esp), %ecx # len - xorl %eax,%eax - rep ; stosb - - jmp 5000b - -6002: - movl ARGBASE+24(%esp), %ebx # dst_err_ptr - movl $-EFAULT,(%ebx) - jmp 5000b + xorl %eax, %eax + jmp 7b .previous @@ -405,14 +379,14 @@ SYM_FUNC_END(csum_partial_copy_generic) /* Version for PentiumII/PPro */ #define ROUND1(x) \ - SRC(movl x(%esi), %ebx ) ; \ + EXC(movl x(%esi), %ebx ) ; \ addl %ebx, %eax ; \ - DST(movl %ebx, x(%edi) ) ; + EXC(movl %ebx, x(%edi) ) ; #define ROUND(x) \ - SRC(movl x(%esi), %ebx ) ; \ + EXC(movl x(%esi), %ebx ) ; \ adcl %ebx, %eax ; \ - DST(movl %ebx, x(%edi) ) ; + EXC(movl %ebx, x(%edi) ) ; #define ARGBASE 12 @@ -423,7 +397,7 @@ SYM_FUNC_START(csum_partial_copy_generic) movl ARGBASE+4(%esp),%esi #src movl ARGBASE+8(%esp),%edi #dst movl ARGBASE+12(%esp),%ecx #len - movl ARGBASE+16(%esp),%eax #sum + movl $-1, %eax #sum # movl %ecx, %edx movl %ecx, %ebx movl %esi, %edx @@ -439,7 +413,7 @@ SYM_FUNC_START(csum_partial_copy_generic) JMP_NOSPEC ebx 1: addl $64,%esi addl $64,%edi - SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl) + EXC(movb -32(%edx),%bl) ; EXC(movb (%edx),%bl) ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52) ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36) ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20) @@ -453,29 +427,20 @@ SYM_FUNC_START(csum_partial_copy_generic) jz 7f cmpl $2, %edx jb 5f -SRC( movw (%esi), %dx ) +EXC( movw (%esi), %dx ) leal 2(%esi), %esi -DST( movw %dx, (%edi) ) +EXC( movw %dx, (%edi) ) leal 2(%edi), %edi je 6f shll $16,%edx 5: -SRC( movb (%esi), %dl ) -DST( movb %dl, (%edi) ) +EXC( movb (%esi), %dl ) +EXC( movb %dl, (%edi) ) 6: addl %edx, %eax adcl $0, %eax 7: .section .fixup, "ax" -6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr - movl $-EFAULT, (%ebx) - # zero the complete destination (computing the rest is too much work) - movl ARGBASE+8(%esp),%edi # dst - movl ARGBASE+12(%esp),%ecx # len - xorl %eax,%eax - rep; stosb - jmp 7b -6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr - movl $-EFAULT, (%ebx) +6001: xorl %eax, %eax jmp 7b .previous diff --git a/arch/x86/lib/copy_mc.c b/arch/x86/lib/copy_mc.c new file mode 100644 index 000000000000..c13e8c9ee926 --- /dev/null +++ b/arch/x86/lib/copy_mc.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2016-2020 Intel Corporation. All rights reserved. */ + +#include <linux/jump_label.h> +#include <linux/uaccess.h> +#include <linux/export.h> +#include <linux/string.h> +#include <linux/types.h> + +#include <asm/mce.h> + +#ifdef CONFIG_X86_MCE +/* + * See COPY_MC_TEST for self-test of the copy_mc_fragile() + * implementation. + */ +static DEFINE_STATIC_KEY_FALSE(copy_mc_fragile_key); + +void enable_copy_mc_fragile(void) +{ + static_branch_inc(©_mc_fragile_key); +} +#define copy_mc_fragile_enabled (static_branch_unlikely(©_mc_fragile_key)) + +/* + * Similar to copy_user_handle_tail, probe for the write fault point, or + * source exception point. + */ +__visible notrace unsigned long +copy_mc_fragile_handle_tail(char *to, char *from, unsigned len) +{ + for (; len; --len, to++, from++) + if (copy_mc_fragile(to, from, 1)) + break; + return len; +} +#else +/* + * No point in doing careful copying, or consulting a static key when + * there is no #MC handler in the CONFIG_X86_MCE=n case. + */ +void enable_copy_mc_fragile(void) +{ +} +#define copy_mc_fragile_enabled (0) +#endif + +unsigned long copy_mc_enhanced_fast_string(void *dst, const void *src, unsigned len); + +/** + * copy_mc_to_kernel - memory copy that handles source exceptions + * + * @dst: destination address + * @src: source address + * @len: number of bytes to copy + * + * Call into the 'fragile' version on systems that benefit from avoiding + * corner case poison consumption scenarios, For example, accessing + * poison across 2 cachelines with a single instruction. Almost all + * other uses case can use copy_mc_enhanced_fast_string() for a fast + * recoverable copy, or fallback to plain memcpy. + * + * Return 0 for success, or number of bytes not copied if there was an + * exception. + */ +unsigned long __must_check copy_mc_to_kernel(void *dst, const void *src, unsigned len) +{ + if (copy_mc_fragile_enabled) + return copy_mc_fragile(dst, src, len); + if (static_cpu_has(X86_FEATURE_ERMS)) + return copy_mc_enhanced_fast_string(dst, src, len); + memcpy(dst, src, len); + return 0; +} +EXPORT_SYMBOL_GPL(copy_mc_to_kernel); + +unsigned long __must_check copy_mc_to_user(void *dst, const void *src, unsigned len) +{ + unsigned long ret; + + if (copy_mc_fragile_enabled) { + __uaccess_begin(); + ret = copy_mc_fragile(dst, src, len); + __uaccess_end(); + return ret; + } + + if (static_cpu_has(X86_FEATURE_ERMS)) { + __uaccess_begin(); + ret = copy_mc_enhanced_fast_string(dst, src, len); + __uaccess_end(); + return ret; + } + + return copy_user_generic(dst, src, len); +} diff --git a/arch/x86/lib/copy_mc_64.S b/arch/x86/lib/copy_mc_64.S new file mode 100644 index 000000000000..892d8915f609 --- /dev/null +++ b/arch/x86/lib/copy_mc_64.S @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright(c) 2016-2020 Intel Corporation. All rights reserved. */ + +#include <linux/linkage.h> +#include <asm/copy_mc_test.h> +#include <asm/export.h> +#include <asm/asm.h> + +#ifndef CONFIG_UML + +#ifdef CONFIG_X86_MCE +COPY_MC_TEST_CTL + +/* + * copy_mc_fragile - copy memory with indication if an exception / fault happened + * + * The 'fragile' version is opted into by platform quirks and takes + * pains to avoid unrecoverable corner cases like 'fast-string' + * instruction sequences, and consuming poison across a cacheline + * boundary. The non-fragile version is equivalent to memcpy() + * regardless of CPU machine-check-recovery capability. + */ +SYM_FUNC_START(copy_mc_fragile) + cmpl $8, %edx + /* Less than 8 bytes? Go to byte copy loop */ + jb .L_no_whole_words + + /* Check for bad alignment of source */ + testl $7, %esi + /* Already aligned */ + jz .L_8byte_aligned + + /* Copy one byte at a time until source is 8-byte aligned */ + movl %esi, %ecx + andl $7, %ecx + subl $8, %ecx + negl %ecx + subl %ecx, %edx +.L_read_leading_bytes: + movb (%rsi), %al + COPY_MC_TEST_SRC %rsi 1 .E_leading_bytes + COPY_MC_TEST_DST %rdi 1 .E_leading_bytes +.L_write_leading_bytes: + movb %al, (%rdi) + incq %rsi + incq %rdi + decl %ecx + jnz .L_read_leading_bytes + +.L_8byte_aligned: + movl %edx, %ecx + andl $7, %edx + shrl $3, %ecx + jz .L_no_whole_words + +.L_read_words: + movq (%rsi), %r8 + COPY_MC_TEST_SRC %rsi 8 .E_read_words + COPY_MC_TEST_DST %rdi 8 .E_write_words +.L_write_words: + movq %r8, (%rdi) + addq $8, %rsi + addq $8, %rdi + decl %ecx + jnz .L_read_words + + /* Any trailing bytes? */ +.L_no_whole_words: + andl %edx, %edx + jz .L_done_memcpy_trap + + /* Copy trailing bytes */ + movl %edx, %ecx +.L_read_trailing_bytes: + movb (%rsi), %al + COPY_MC_TEST_SRC %rsi 1 .E_trailing_bytes + COPY_MC_TEST_DST %rdi 1 .E_trailing_bytes +.L_write_trailing_bytes: + movb %al, (%rdi) + incq %rsi + incq %rdi + decl %ecx + jnz .L_read_trailing_bytes + + /* Copy successful. Return zero */ +.L_done_memcpy_trap: + xorl %eax, %eax +.L_done: + ret +SYM_FUNC_END(copy_mc_fragile) +EXPORT_SYMBOL_GPL(copy_mc_fragile) + + .section .fixup, "ax" + /* + * Return number of bytes not copied for any failure. Note that + * there is no "tail" handling since the source buffer is 8-byte + * aligned and poison is cacheline aligned. + */ +.E_read_words: + shll $3, %ecx +.E_leading_bytes: + addl %edx, %ecx +.E_trailing_bytes: + mov %ecx, %eax + jmp .L_done + + /* + * For write fault handling, given the destination is unaligned, + * we handle faults on multi-byte writes with a byte-by-byte + * copy up to the write-protected page. + */ +.E_write_words: + shll $3, %ecx + addl %edx, %ecx + movl %ecx, %edx + jmp copy_mc_fragile_handle_tail + + .previous + + _ASM_EXTABLE_FAULT(.L_read_leading_bytes, .E_leading_bytes) + _ASM_EXTABLE_FAULT(.L_read_words, .E_read_words) + _ASM_EXTABLE_FAULT(.L_read_trailing_bytes, .E_trailing_bytes) + _ASM_EXTABLE(.L_write_leading_bytes, .E_leading_bytes) + _ASM_EXTABLE(.L_write_words, .E_write_words) + _ASM_EXTABLE(.L_write_trailing_bytes, .E_trailing_bytes) +#endif /* CONFIG_X86_MCE */ + +/* + * copy_mc_enhanced_fast_string - memory copy with exception handling + * + * Fast string copy + fault / exception handling. If the CPU does + * support machine check exception recovery, but does not support + * recovering from fast-string exceptions then this CPU needs to be + * added to the copy_mc_fragile_key set of quirks. Otherwise, absent any + * machine check recovery support this version should be no slower than + * standard memcpy. + */ +SYM_FUNC_START(copy_mc_enhanced_fast_string) + movq %rdi, %rax + movq %rdx, %rcx +.L_copy: + rep movsb + /* Copy successful. Return zero */ + xorl %eax, %eax + ret +SYM_FUNC_END(copy_mc_enhanced_fast_string) + + .section .fixup, "ax" +.E_copy: + /* + * On fault %rcx is updated such that the copy instruction could + * optionally be restarted at the fault position, i.e. it + * contains 'bytes remaining'. A non-zero return indicates error + * to copy_mc_generic() users, or indicate short transfers to + * user-copy routines. + */ + movq %rcx, %rax + ret + + .previous + + _ASM_EXTABLE_FAULT(.L_copy, .E_copy) +#endif /* !CONFIG_UML */ diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index 816f128a6d52..77b9b2a3b5c8 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S @@ -15,6 +15,7 @@ #include <asm/asm.h> #include <asm/smap.h> #include <asm/export.h> +#include <asm/trapnr.h> .macro ALIGN_DESTINATION /* check for bad alignment of destination */ @@ -36,8 +37,8 @@ jmp .Lcopy_user_handle_tail .previous - _ASM_EXTABLE_UA(100b, 103b) - _ASM_EXTABLE_UA(101b, 103b) + _ASM_EXTABLE_CPY(100b, 103b) + _ASM_EXTABLE_CPY(101b, 103b) .endm /* @@ -116,26 +117,26 @@ SYM_FUNC_START(copy_user_generic_unrolled) 60: jmp .Lcopy_user_handle_tail /* ecx is zerorest also */ .previous - _ASM_EXTABLE_UA(1b, 30b) - _ASM_EXTABLE_UA(2b, 30b) - _ASM_EXTABLE_UA(3b, 30b) - _ASM_EXTABLE_UA(4b, 30b) - _ASM_EXTABLE_UA(5b, 30b) - _ASM_EXTABLE_UA(6b, 30b) - _ASM_EXTABLE_UA(7b, 30b) - _ASM_EXTABLE_UA(8b, 30b) - _ASM_EXTABLE_UA(9b, 30b) - _ASM_EXTABLE_UA(10b, 30b) - _ASM_EXTABLE_UA(11b, 30b) - _ASM_EXTABLE_UA(12b, 30b) - _ASM_EXTABLE_UA(13b, 30b) - _ASM_EXTABLE_UA(14b, 30b) - _ASM_EXTABLE_UA(15b, 30b) - _ASM_EXTABLE_UA(16b, 30b) - _ASM_EXTABLE_UA(18b, 40b) - _ASM_EXTABLE_UA(19b, 40b) - _ASM_EXTABLE_UA(21b, 50b) - _ASM_EXTABLE_UA(22b, 50b) + _ASM_EXTABLE_CPY(1b, 30b) + _ASM_EXTABLE_CPY(2b, 30b) + _ASM_EXTABLE_CPY(3b, 30b) + _ASM_EXTABLE_CPY(4b, 30b) + _ASM_EXTABLE_CPY(5b, 30b) + _ASM_EXTABLE_CPY(6b, 30b) + _ASM_EXTABLE_CPY(7b, 30b) + _ASM_EXTABLE_CPY(8b, 30b) + _ASM_EXTABLE_CPY(9b, 30b) + _ASM_EXTABLE_CPY(10b, 30b) + _ASM_EXTABLE_CPY(11b, 30b) + _ASM_EXTABLE_CPY(12b, 30b) + _ASM_EXTABLE_CPY(13b, 30b) + _ASM_EXTABLE_CPY(14b, 30b) + _ASM_EXTABLE_CPY(15b, 30b) + _ASM_EXTABLE_CPY(16b, 30b) + _ASM_EXTABLE_CPY(18b, 40b) + _ASM_EXTABLE_CPY(19b, 40b) + _ASM_EXTABLE_CPY(21b, 50b) + _ASM_EXTABLE_CPY(22b, 50b) SYM_FUNC_END(copy_user_generic_unrolled) EXPORT_SYMBOL(copy_user_generic_unrolled) @@ -180,8 +181,8 @@ SYM_FUNC_START(copy_user_generic_string) jmp .Lcopy_user_handle_tail .previous - _ASM_EXTABLE_UA(1b, 11b) - _ASM_EXTABLE_UA(3b, 12b) + _ASM_EXTABLE_CPY(1b, 11b) + _ASM_EXTABLE_CPY(3b, 12b) SYM_FUNC_END(copy_user_generic_string) EXPORT_SYMBOL(copy_user_generic_string) @@ -213,7 +214,7 @@ SYM_FUNC_START(copy_user_enhanced_fast_string) jmp .Lcopy_user_handle_tail .previous - _ASM_EXTABLE_UA(1b, 12b) + _ASM_EXTABLE_CPY(1b, 12b) SYM_FUNC_END(copy_user_enhanced_fast_string) EXPORT_SYMBOL(copy_user_enhanced_fast_string) @@ -221,6 +222,7 @@ EXPORT_SYMBOL(copy_user_enhanced_fast_string) * Try to copy last bytes and clear the rest if needed. * Since protection fault in copy_from/to_user is not a normal situation, * it is not necessary to optimize tail handling. + * Don't try to copy the tail if machine check happened * * Input: * rdi destination @@ -232,12 +234,25 @@ EXPORT_SYMBOL(copy_user_enhanced_fast_string) */ SYM_CODE_START_LOCAL(.Lcopy_user_handle_tail) movl %edx,%ecx + cmp $X86_TRAP_MC,%eax /* check if X86_TRAP_MC */ + je 3f 1: rep movsb 2: mov %ecx,%eax ASM_CLAC ret - _ASM_EXTABLE_UA(1b, 2b) + /* + * Return zero to pretend that this copy succeeded. This + * is counter-intuitive, but needed to prevent the code + * in lib/iov_iter.c from retrying and running back into + * the poison cache line again. The machine check handler + * will ensure that a SIGBUS is sent to the task. + */ +3: xorl %eax,%eax + ASM_CLAC + ret + + _ASM_EXTABLE_CPY(1b, 2b) SYM_CODE_END(.Lcopy_user_handle_tail) /* @@ -366,27 +381,27 @@ SYM_FUNC_START(__copy_user_nocache) jmp .Lcopy_user_handle_tail .previous - _ASM_EXTABLE_UA(1b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(2b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(3b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(4b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(5b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(6b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(7b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(8b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(9b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(10b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(11b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(12b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(13b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(14b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(15b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(16b, .L_fixup_4x8b_copy) - _ASM_EXTABLE_UA(20b, .L_fixup_8b_copy) - _ASM_EXTABLE_UA(21b, .L_fixup_8b_copy) - _ASM_EXTABLE_UA(30b, .L_fixup_4b_copy) - _ASM_EXTABLE_UA(31b, .L_fixup_4b_copy) - _ASM_EXTABLE_UA(40b, .L_fixup_1b_copy) - _ASM_EXTABLE_UA(41b, .L_fixup_1b_copy) + _ASM_EXTABLE_CPY(1b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(2b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(3b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(4b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(5b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(6b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(7b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(8b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(9b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(10b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(11b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(12b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(13b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(14b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(15b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(16b, .L_fixup_4x8b_copy) + _ASM_EXTABLE_CPY(20b, .L_fixup_8b_copy) + _ASM_EXTABLE_CPY(21b, .L_fixup_8b_copy) + _ASM_EXTABLE_CPY(30b, .L_fixup_4b_copy) + _ASM_EXTABLE_CPY(31b, .L_fixup_4b_copy) + _ASM_EXTABLE_CPY(40b, .L_fixup_1b_copy) + _ASM_EXTABLE_CPY(41b, .L_fixup_1b_copy) SYM_FUNC_END(__copy_user_nocache) EXPORT_SYMBOL(__copy_user_nocache) diff --git a/arch/x86/lib/csum-copy_64.S b/arch/x86/lib/csum-copy_64.S index 3394a8ff7fd0..1fbd8ee9642d 100644 --- a/arch/x86/lib/csum-copy_64.S +++ b/arch/x86/lib/csum-copy_64.S @@ -18,9 +18,6 @@ * rdi source * rsi destination * edx len (32bit) - * ecx sum (32bit) - * r8 src_err_ptr (int) - * r9 dst_err_ptr (int) * * Output * eax 64bit sum. undefined in case of exception. @@ -31,44 +28,32 @@ .macro source 10: - _ASM_EXTABLE_UA(10b, .Lbad_source) + _ASM_EXTABLE_UA(10b, .Lfault) .endm .macro dest 20: - _ASM_EXTABLE_UA(20b, .Lbad_dest) + _ASM_EXTABLE_UA(20b, .Lfault) .endm - /* - * No _ASM_EXTABLE_UA; this is used for intentional prefetch on a - * potentially unmapped kernel address. - */ - .macro ignore L=.Lignore -30: - _ASM_EXTABLE(30b, \L) - .endm - - SYM_FUNC_START(csum_partial_copy_generic) - cmpl $3*64, %edx - jle .Lignore - -.Lignore: - subq $7*8, %rsp - movq %rbx, 2*8(%rsp) - movq %r12, 3*8(%rsp) - movq %r14, 4*8(%rsp) - movq %r13, 5*8(%rsp) - movq %r15, 6*8(%rsp) + subq $5*8, %rsp + movq %rbx, 0*8(%rsp) + movq %r12, 1*8(%rsp) + movq %r14, 2*8(%rsp) + movq %r13, 3*8(%rsp) + movq %r15, 4*8(%rsp) - movq %r8, (%rsp) - movq %r9, 1*8(%rsp) - - movl %ecx, %eax + movl $-1, %eax + xorl %r9d, %r9d movl %edx, %ecx + cmpl $8, %ecx + jb .Lshort - xorl %r9d, %r9d - movq %rcx, %r12 + testb $7, %sil + jne .Lunaligned +.Laligned: + movl %ecx, %r12d shrq $6, %r12 jz .Lhandle_tail /* < 64 */ @@ -99,7 +84,12 @@ SYM_FUNC_START(csum_partial_copy_generic) source movq 56(%rdi), %r13 - ignore 2f +30: + /* + * No _ASM_EXTABLE_UA; this is used for intentional prefetch on a + * potentially unmapped kernel address. + */ + _ASM_EXTABLE(30b, 2f) prefetcht0 5*64(%rdi) 2: adcq %rbx, %rax @@ -131,8 +121,6 @@ SYM_FUNC_START(csum_partial_copy_generic) dest movq %r13, 56(%rsi) -3: - leaq 64(%rdi), %rdi leaq 64(%rsi), %rsi @@ -142,8 +130,8 @@ SYM_FUNC_START(csum_partial_copy_generic) /* do last up to 56 bytes */ .Lhandle_tail: - /* ecx: count */ - movl %ecx, %r10d + /* ecx: count, rcx.63: the end result needs to be rol8 */ + movq %rcx, %r10 andl $63, %ecx shrl $3, %ecx jz .Lfold @@ -172,6 +160,7 @@ SYM_FUNC_START(csum_partial_copy_generic) .Lhandle_7: movl %r10d, %ecx andl $7, %ecx +.L1: /* .Lshort rejoins the common path here */ shrl $1, %ecx jz .Lhandle_1 movl $2, %edx @@ -203,26 +192,65 @@ SYM_FUNC_START(csum_partial_copy_generic) adcl %r9d, %eax /* carry */ .Lende: - movq 2*8(%rsp), %rbx - movq 3*8(%rsp), %r12 - movq 4*8(%rsp), %r14 - movq 5*8(%rsp), %r13 - movq 6*8(%rsp), %r15 - addq $7*8, %rsp + testq %r10, %r10 + js .Lwas_odd +.Lout: + movq 0*8(%rsp), %rbx + movq 1*8(%rsp), %r12 + movq 2*8(%rsp), %r14 + movq 3*8(%rsp), %r13 + movq 4*8(%rsp), %r15 + addq $5*8, %rsp ret +.Lshort: + movl %ecx, %r10d + jmp .L1 +.Lunaligned: + xorl %ebx, %ebx + testb $1, %sil + jne .Lodd +1: testb $2, %sil + je 2f + source + movw (%rdi), %bx + dest + movw %bx, (%rsi) + leaq 2(%rdi), %rdi + subq $2, %rcx + leaq 2(%rsi), %rsi + addq %rbx, %rax +2: testb $4, %sil + je .Laligned + source + movl (%rdi), %ebx + dest + movl %ebx, (%rsi) + leaq 4(%rdi), %rdi + subq $4, %rcx + leaq 4(%rsi), %rsi + addq %rbx, %rax + jmp .Laligned + +.Lodd: + source + movb (%rdi), %bl + dest + movb %bl, (%rsi) + leaq 1(%rdi), %rdi + leaq 1(%rsi), %rsi + /* decrement, set MSB */ + leaq -1(%rcx, %rcx), %rcx + rorq $1, %rcx + shll $8, %ebx + addq %rbx, %rax + jmp 1b + +.Lwas_odd: + roll $8, %eax + jmp .Lout - /* Exception handlers. Very simple, zeroing is done in the wrappers */ -.Lbad_source: - movq (%rsp), %rax - testq %rax, %rax - jz .Lende - movl $-EFAULT, (%rax) - jmp .Lende - -.Lbad_dest: - movq 8(%rsp), %rax - testq %rax, %rax - jz .Lende - movl $-EFAULT, (%rax) - jmp .Lende + /* Exception: just return 0 */ +.Lfault: + xorl %eax, %eax + jmp .Lout SYM_FUNC_END(csum_partial_copy_generic) diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c index ee63d7576fd2..189344924a2b 100644 --- a/arch/x86/lib/csum-wrappers_64.c +++ b/arch/x86/lib/csum-wrappers_64.c @@ -21,52 +21,16 @@ * src and dst are best aligned to 64bits. */ __wsum -csum_and_copy_from_user(const void __user *src, void *dst, - int len, __wsum isum, int *errp) +csum_and_copy_from_user(const void __user *src, void *dst, int len) { - might_sleep(); - *errp = 0; + __wsum sum; + might_sleep(); if (!user_access_begin(src, len)) - goto out_err; - - /* - * Why 6, not 7? To handle odd addresses aligned we - * would need to do considerable complications to fix the - * checksum which is defined as an 16bit accumulator. The - * fix alignment code is primarily for performance - * compatibility with 32bit and that will handle odd - * addresses slowly too. - */ - if (unlikely((unsigned long)src & 6)) { - while (((unsigned long)src & 6) && len >= 2) { - __u16 val16; - - unsafe_get_user(val16, (const __u16 __user *)src, out); - - *(__u16 *)dst = val16; - isum = (__force __wsum)add32_with_carry( - (__force unsigned)isum, val16); - src += 2; - dst += 2; - len -= 2; - } - } - isum = csum_partial_copy_generic((__force const void *)src, - dst, len, isum, errp, NULL); - user_access_end(); - if (unlikely(*errp)) - goto out_err; - - return isum; - -out: + return 0; + sum = csum_partial_copy_generic((__force const void *)src, dst, len); user_access_end(); -out_err: - *errp = -EFAULT; - memset(dst, 0, len); - - return isum; + return sum; } EXPORT_SYMBOL(csum_and_copy_from_user); @@ -82,40 +46,16 @@ EXPORT_SYMBOL(csum_and_copy_from_user); * src and dst are best aligned to 64bits. */ __wsum -csum_and_copy_to_user(const void *src, void __user *dst, - int len, __wsum isum, int *errp) +csum_and_copy_to_user(const void *src, void __user *dst, int len) { - __wsum ret; + __wsum sum; might_sleep(); - - if (!user_access_begin(dst, len)) { - *errp = -EFAULT; + if (!user_access_begin(dst, len)) return 0; - } - - if (unlikely((unsigned long)dst & 6)) { - while (((unsigned long)dst & 6) && len >= 2) { - __u16 val16 = *(__u16 *)src; - - isum = (__force __wsum)add32_with_carry( - (__force unsigned)isum, val16); - unsafe_put_user(val16, (__u16 __user *)dst, out); - src += 2; - dst += 2; - len -= 2; - } - } - - *errp = 0; - ret = csum_partial_copy_generic(src, (void __force *)dst, - len, isum, NULL, errp); - user_access_end(); - return ret; -out: + sum = csum_partial_copy_generic(src, (void __force *)dst, len); user_access_end(); - *errp = -EFAULT; - return isum; + return sum; } EXPORT_SYMBOL(csum_and_copy_to_user); @@ -129,9 +69,9 @@ EXPORT_SYMBOL(csum_and_copy_to_user); * Returns an 32bit unfolded checksum of the buffer. */ __wsum -csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) +csum_partial_copy_nocheck(const void *src, void *dst, int len) { - return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL); + return csum_partial_copy_generic(src, dst, len); } EXPORT_SYMBOL(csum_partial_copy_nocheck); diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S index c8a85b512796..fa1bc2104b32 100644 --- a/arch/x86/lib/getuser.S +++ b/arch/x86/lib/getuser.S @@ -35,10 +35,21 @@ #include <asm/smap.h> #include <asm/export.h> +#define ASM_BARRIER_NOSPEC ALTERNATIVE "", "lfence", X86_FEATURE_LFENCE_RDTSC + +#ifdef CONFIG_X86_5LEVEL +#define LOAD_TASK_SIZE_MINUS_N(n) \ + ALTERNATIVE __stringify(mov $((1 << 47) - 4096 - (n)),%rdx), \ + __stringify(mov $((1 << 56) - 4096 - (n)),%rdx), X86_FEATURE_LA57 +#else +#define LOAD_TASK_SIZE_MINUS_N(n) \ + mov $(TASK_SIZE_MAX - (n)),%_ASM_DX +#endif + .text SYM_FUNC_START(__get_user_1) - mov PER_CPU_VAR(current_task), %_ASM_DX - cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX + LOAD_TASK_SIZE_MINUS_N(0) + cmp %_ASM_DX,%_ASM_AX jae bad_get_user sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */ and %_ASM_DX, %_ASM_AX @@ -51,15 +62,13 @@ SYM_FUNC_END(__get_user_1) EXPORT_SYMBOL(__get_user_1) SYM_FUNC_START(__get_user_2) - add $1,%_ASM_AX - jc bad_get_user - mov PER_CPU_VAR(current_task), %_ASM_DX - cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX + LOAD_TASK_SIZE_MINUS_N(1) + cmp %_ASM_DX,%_ASM_AX jae bad_get_user sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */ and %_ASM_DX, %_ASM_AX ASM_STAC -2: movzwl -1(%_ASM_AX),%edx +2: movzwl (%_ASM_AX),%edx xor %eax,%eax ASM_CLAC ret @@ -67,15 +76,13 @@ SYM_FUNC_END(__get_user_2) EXPORT_SYMBOL(__get_user_2) SYM_FUNC_START(__get_user_4) - add $3,%_ASM_AX - jc bad_get_user - mov PER_CPU_VAR(current_task), %_ASM_DX - cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX + LOAD_TASK_SIZE_MINUS_N(3) + cmp %_ASM_DX,%_ASM_AX jae bad_get_user sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */ and %_ASM_DX, %_ASM_AX ASM_STAC -3: movl -3(%_ASM_AX),%edx +3: movl (%_ASM_AX),%edx xor %eax,%eax ASM_CLAC ret @@ -84,29 +91,25 @@ EXPORT_SYMBOL(__get_user_4) SYM_FUNC_START(__get_user_8) #ifdef CONFIG_X86_64 - add $7,%_ASM_AX - jc bad_get_user - mov PER_CPU_VAR(current_task), %_ASM_DX - cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX + LOAD_TASK_SIZE_MINUS_N(7) + cmp %_ASM_DX,%_ASM_AX jae bad_get_user sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */ and %_ASM_DX, %_ASM_AX ASM_STAC -4: movq -7(%_ASM_AX),%rdx +4: movq (%_ASM_AX),%rdx xor %eax,%eax ASM_CLAC ret #else - add $7,%_ASM_AX - jc bad_get_user_8 - mov PER_CPU_VAR(current_task), %_ASM_DX - cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX + LOAD_TASK_SIZE_MINUS_N(7) + cmp %_ASM_DX,%_ASM_AX jae bad_get_user_8 sbb %_ASM_DX, %_ASM_DX /* array_index_mask_nospec() */ and %_ASM_DX, %_ASM_AX ASM_STAC -4: movl -7(%_ASM_AX),%edx -5: movl -3(%_ASM_AX),%ecx +4: movl (%_ASM_AX),%edx +5: movl 4(%_ASM_AX),%ecx xor %eax,%eax ASM_CLAC ret @@ -114,6 +117,52 @@ SYM_FUNC_START(__get_user_8) SYM_FUNC_END(__get_user_8) EXPORT_SYMBOL(__get_user_8) +/* .. and the same for __get_user, just without the range checks */ +SYM_FUNC_START(__get_user_nocheck_1) + ASM_STAC + ASM_BARRIER_NOSPEC +6: movzbl (%_ASM_AX),%edx + xor %eax,%eax + ASM_CLAC + ret +SYM_FUNC_END(__get_user_nocheck_1) +EXPORT_SYMBOL(__get_user_nocheck_1) + +SYM_FUNC_START(__get_user_nocheck_2) + ASM_STAC + ASM_BARRIER_NOSPEC +7: movzwl (%_ASM_AX),%edx + xor %eax,%eax + ASM_CLAC + ret +SYM_FUNC_END(__get_user_nocheck_2) +EXPORT_SYMBOL(__get_user_nocheck_2) + +SYM_FUNC_START(__get_user_nocheck_4) + ASM_STAC + ASM_BARRIER_NOSPEC +8: movl (%_ASM_AX),%edx + xor %eax,%eax + ASM_CLAC + ret +SYM_FUNC_END(__get_user_nocheck_4) +EXPORT_SYMBOL(__get_user_nocheck_4) + +SYM_FUNC_START(__get_user_nocheck_8) + ASM_STAC + ASM_BARRIER_NOSPEC +#ifdef CONFIG_X86_64 +9: movq (%_ASM_AX),%rdx +#else +9: movl (%_ASM_AX),%edx +10: movl 4(%_ASM_AX),%ecx +#endif + xor %eax,%eax + ASM_CLAC + ret +SYM_FUNC_END(__get_user_nocheck_8) +EXPORT_SYMBOL(__get_user_nocheck_8) + SYM_CODE_START_LOCAL(.Lbad_get_user_clac) ASM_CLAC @@ -134,6 +183,7 @@ bad_get_user_8: SYM_CODE_END(.Lbad_get_user_8_clac) #endif +/* get_user */ _ASM_EXTABLE_UA(1b, .Lbad_get_user_clac) _ASM_EXTABLE_UA(2b, .Lbad_get_user_clac) _ASM_EXTABLE_UA(3b, .Lbad_get_user_clac) @@ -143,3 +193,14 @@ SYM_CODE_END(.Lbad_get_user_8_clac) _ASM_EXTABLE_UA(4b, .Lbad_get_user_8_clac) _ASM_EXTABLE_UA(5b, .Lbad_get_user_8_clac) #endif + +/* __get_user */ + _ASM_EXTABLE_UA(6b, .Lbad_get_user_clac) + _ASM_EXTABLE_UA(7b, .Lbad_get_user_clac) + _ASM_EXTABLE_UA(8b, .Lbad_get_user_clac) +#ifdef CONFIG_X86_64 + _ASM_EXTABLE_UA(9b, .Lbad_get_user_clac) +#else + _ASM_EXTABLE_UA(9b, .Lbad_get_user_8_clac) + _ASM_EXTABLE_UA(10b, .Lbad_get_user_8_clac) +#endif diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c index 5e69603ff63f..58f7fb95c7f4 100644 --- a/arch/x86/lib/insn-eval.c +++ b/arch/x86/lib/insn-eval.c @@ -20,6 +20,7 @@ enum reg_type { REG_TYPE_RM = 0, + REG_TYPE_REG, REG_TYPE_INDEX, REG_TYPE_BASE, }; @@ -53,6 +54,30 @@ static bool is_string_insn(struct insn *insn) } /** + * insn_has_rep_prefix() - Determine if instruction has a REP prefix + * @insn: Instruction containing the prefix to inspect + * + * Returns: + * + * true if the instruction has a REP prefix, false if not. + */ +bool insn_has_rep_prefix(struct insn *insn) +{ + int i; + + insn_get_prefixes(insn); + + for (i = 0; i < insn->prefixes.nbytes; i++) { + insn_byte_t p = insn->prefixes.bytes[i]; + + if (p == 0xf2 || p == 0xf3) + return true; + } + + return false; +} + +/** * get_seg_reg_override_idx() - obtain segment register override index * @insn: Valid instruction with segment override prefixes * @@ -439,6 +464,13 @@ static int get_reg_offset(struct insn *insn, struct pt_regs *regs, regno += 8; break; + case REG_TYPE_REG: + regno = X86_MODRM_REG(insn->modrm.value); + + if (X86_REX_R(insn->rex_prefix.value)) + regno += 8; + break; + case REG_TYPE_INDEX: regno = X86_SIB_INDEX(insn->sib.value); if (X86_REX_X(insn->rex_prefix.value)) @@ -808,6 +840,21 @@ int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs) } /** + * insn_get_modrm_reg_off() - Obtain register in reg part of the ModRM byte + * @insn: Instruction containing the ModRM byte + * @regs: Register values as seen when entering kernel mode + * + * Returns: + * + * The register indicated by the reg part of the ModRM byte. The + * register is obtained as an offset from the base of pt_regs. + */ +int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs) +{ + return get_reg_offset(insn, regs, REG_TYPE_REG); +} + +/** * get_seg_base_limit() - obtain base address and limit of a segment * @insn: Instruction. Must be valid. * @regs: Register values as seen when entering kernel mode @@ -1367,3 +1414,86 @@ void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs) return (void __user *)-1L; } } + +/** + * insn_fetch_from_user() - Copy instruction bytes from user-space memory + * @regs: Structure with register values as seen when entering kernel mode + * @buf: Array to store the fetched instruction + * + * Gets the linear address of the instruction and copies the instruction bytes + * to the buf. + * + * Returns: + * + * Number of instruction bytes copied. + * + * 0 if nothing was copied. + */ +int insn_fetch_from_user(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE]) +{ + unsigned long seg_base = 0; + int not_copied; + + /* + * If not in user-space long mode, a custom code segment could be in + * use. This is true in protected mode (if the process defined a local + * descriptor table), or virtual-8086 mode. In most of the cases + * seg_base will be zero as in USER_CS. + */ + if (!user_64bit_mode(regs)) { + seg_base = insn_get_seg_base(regs, INAT_SEG_REG_CS); + if (seg_base == -1L) + return 0; + } + + + not_copied = copy_from_user(buf, (void __user *)(seg_base + regs->ip), + MAX_INSN_SIZE); + + return MAX_INSN_SIZE - not_copied; +} + +/** + * insn_decode() - Decode an instruction + * @insn: Structure to store decoded instruction + * @regs: Structure with register values as seen when entering kernel mode + * @buf: Buffer containing the instruction bytes + * @buf_size: Number of instruction bytes available in buf + * + * Decodes the instruction provided in buf and stores the decoding results in + * insn. Also determines the correct address and operand sizes. + * + * Returns: + * + * True if instruction was decoded, False otherwise. + */ +bool insn_decode(struct insn *insn, struct pt_regs *regs, + unsigned char buf[MAX_INSN_SIZE], int buf_size) +{ + int seg_defs; + + insn_init(insn, buf, buf_size, user_64bit_mode(regs)); + + /* + * Override the default operand and address sizes with what is specified + * in the code segment descriptor. The instruction decoder only sets + * the address size it to either 4 or 8 address bytes and does nothing + * for the operand bytes. This OK for most of the cases, but we could + * have special cases where, for instance, a 16-bit code segment + * descriptor is used. + * If there is an address override prefix, the instruction decoder + * correctly updates these values, even for 16-bit defaults. + */ + seg_defs = insn_get_code_seg_params(regs); + if (seg_defs == -EINVAL) + return false; + + insn->addr_bytes = INSN_CODE_SEG_ADDR_SZ(seg_defs); + insn->opnd_bytes = INSN_CODE_SEG_OPND_SZ(seg_defs); + + insn_get_length(insn); + if (buf_size < insn->length) + return false; + + return true; +} diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S index bbcc05bcefad..037faac46b0c 100644 --- a/arch/x86/lib/memcpy_64.S +++ b/arch/x86/lib/memcpy_64.S @@ -4,7 +4,6 @@ #include <linux/linkage.h> #include <asm/errno.h> #include <asm/cpufeatures.h> -#include <asm/mcsafe_test.h> #include <asm/alternative-asm.h> #include <asm/export.h> @@ -187,117 +186,3 @@ SYM_FUNC_START_LOCAL(memcpy_orig) SYM_FUNC_END(memcpy_orig) .popsection - -#ifndef CONFIG_UML - -MCSAFE_TEST_CTL - -/* - * __memcpy_mcsafe - memory copy with machine check exception handling - * Note that we only catch machine checks when reading the source addresses. - * Writes to target are posted and don't generate machine checks. - */ -SYM_FUNC_START(__memcpy_mcsafe) - cmpl $8, %edx - /* Less than 8 bytes? Go to byte copy loop */ - jb .L_no_whole_words - - /* Check for bad alignment of source */ - testl $7, %esi - /* Already aligned */ - jz .L_8byte_aligned - - /* Copy one byte at a time until source is 8-byte aligned */ - movl %esi, %ecx - andl $7, %ecx - subl $8, %ecx - negl %ecx - subl %ecx, %edx -.L_read_leading_bytes: - movb (%rsi), %al - MCSAFE_TEST_SRC %rsi 1 .E_leading_bytes - MCSAFE_TEST_DST %rdi 1 .E_leading_bytes -.L_write_leading_bytes: - movb %al, (%rdi) - incq %rsi - incq %rdi - decl %ecx - jnz .L_read_leading_bytes - -.L_8byte_aligned: - movl %edx, %ecx - andl $7, %edx - shrl $3, %ecx - jz .L_no_whole_words - -.L_read_words: - movq (%rsi), %r8 - MCSAFE_TEST_SRC %rsi 8 .E_read_words - MCSAFE_TEST_DST %rdi 8 .E_write_words -.L_write_words: - movq %r8, (%rdi) - addq $8, %rsi - addq $8, %rdi - decl %ecx - jnz .L_read_words - - /* Any trailing bytes? */ -.L_no_whole_words: - andl %edx, %edx - jz .L_done_memcpy_trap - - /* Copy trailing bytes */ - movl %edx, %ecx -.L_read_trailing_bytes: - movb (%rsi), %al - MCSAFE_TEST_SRC %rsi 1 .E_trailing_bytes - MCSAFE_TEST_DST %rdi 1 .E_trailing_bytes -.L_write_trailing_bytes: - movb %al, (%rdi) - incq %rsi - incq %rdi - decl %ecx - jnz .L_read_trailing_bytes - - /* Copy successful. Return zero */ -.L_done_memcpy_trap: - xorl %eax, %eax -.L_done: - ret -SYM_FUNC_END(__memcpy_mcsafe) -EXPORT_SYMBOL_GPL(__memcpy_mcsafe) - - .section .fixup, "ax" - /* - * Return number of bytes not copied for any failure. Note that - * there is no "tail" handling since the source buffer is 8-byte - * aligned and poison is cacheline aligned. - */ -.E_read_words: - shll $3, %ecx -.E_leading_bytes: - addl %edx, %ecx -.E_trailing_bytes: - mov %ecx, %eax - jmp .L_done - - /* - * For write fault handling, given the destination is unaligned, - * we handle faults on multi-byte writes with a byte-by-byte - * copy up to the write-protected page. - */ -.E_write_words: - shll $3, %ecx - addl %edx, %ecx - movl %ecx, %edx - jmp mcsafe_handle_tail - - .previous - - _ASM_EXTABLE_FAULT(.L_read_leading_bytes, .E_leading_bytes) - _ASM_EXTABLE_FAULT(.L_read_words, .E_read_words) - _ASM_EXTABLE_FAULT(.L_read_trailing_bytes, .E_trailing_bytes) - _ASM_EXTABLE(.L_write_leading_bytes, .E_leading_bytes) - _ASM_EXTABLE(.L_write_words, .E_write_words) - _ASM_EXTABLE(.L_write_trailing_bytes, .E_trailing_bytes) -#endif diff --git a/arch/x86/lib/putuser.S b/arch/x86/lib/putuser.S index 7c7c92db8497..0ea344c5ea43 100644 --- a/arch/x86/lib/putuser.S +++ b/arch/x86/lib/putuser.S @@ -25,76 +25,87 @@ * Inputs: %eax[:%edx] contains the data * %ecx contains the address * - * Outputs: %eax is error code (0 or -EFAULT) + * Outputs: %ecx is error code (0 or -EFAULT) + * + * Clobbers: %ebx needed for task pointer * * These functions should not modify any other registers, * as they get called from within inline assembly. */ -#define ENTER mov PER_CPU_VAR(current_task), %_ASM_BX +#ifdef CONFIG_X86_5LEVEL +#define LOAD_TASK_SIZE_MINUS_N(n) \ + ALTERNATIVE __stringify(mov $((1 << 47) - 4096 - (n)),%rbx), \ + __stringify(mov $((1 << 56) - 4096 - (n)),%rbx), X86_FEATURE_LA57 +#else +#define LOAD_TASK_SIZE_MINUS_N(n) \ + mov $(TASK_SIZE_MAX - (n)),%_ASM_BX +#endif .text SYM_FUNC_START(__put_user_1) - ENTER - cmp TASK_addr_limit(%_ASM_BX),%_ASM_CX + LOAD_TASK_SIZE_MINUS_N(0) + cmp %_ASM_BX,%_ASM_CX jae .Lbad_put_user +SYM_INNER_LABEL(__put_user_nocheck_1, SYM_L_GLOBAL) ASM_STAC 1: movb %al,(%_ASM_CX) - xor %eax,%eax + xor %ecx,%ecx ASM_CLAC ret SYM_FUNC_END(__put_user_1) EXPORT_SYMBOL(__put_user_1) +EXPORT_SYMBOL(__put_user_nocheck_1) SYM_FUNC_START(__put_user_2) - ENTER - mov TASK_addr_limit(%_ASM_BX),%_ASM_BX - sub $1,%_ASM_BX + LOAD_TASK_SIZE_MINUS_N(1) cmp %_ASM_BX,%_ASM_CX jae .Lbad_put_user +SYM_INNER_LABEL(__put_user_nocheck_2, SYM_L_GLOBAL) ASM_STAC 2: movw %ax,(%_ASM_CX) - xor %eax,%eax + xor %ecx,%ecx ASM_CLAC ret SYM_FUNC_END(__put_user_2) EXPORT_SYMBOL(__put_user_2) +EXPORT_SYMBOL(__put_user_nocheck_2) SYM_FUNC_START(__put_user_4) - ENTER - mov TASK_addr_limit(%_ASM_BX),%_ASM_BX - sub $3,%_ASM_BX + LOAD_TASK_SIZE_MINUS_N(3) cmp %_ASM_BX,%_ASM_CX jae .Lbad_put_user +SYM_INNER_LABEL(__put_user_nocheck_4, SYM_L_GLOBAL) ASM_STAC 3: movl %eax,(%_ASM_CX) - xor %eax,%eax + xor %ecx,%ecx ASM_CLAC ret SYM_FUNC_END(__put_user_4) EXPORT_SYMBOL(__put_user_4) +EXPORT_SYMBOL(__put_user_nocheck_4) SYM_FUNC_START(__put_user_8) - ENTER - mov TASK_addr_limit(%_ASM_BX),%_ASM_BX - sub $7,%_ASM_BX + LOAD_TASK_SIZE_MINUS_N(7) cmp %_ASM_BX,%_ASM_CX jae .Lbad_put_user +SYM_INNER_LABEL(__put_user_nocheck_8, SYM_L_GLOBAL) ASM_STAC 4: mov %_ASM_AX,(%_ASM_CX) #ifdef CONFIG_X86_32 5: movl %edx,4(%_ASM_CX) #endif - xor %eax,%eax + xor %ecx,%ecx ASM_CLAC RET SYM_FUNC_END(__put_user_8) EXPORT_SYMBOL(__put_user_8) +EXPORT_SYMBOL(__put_user_nocheck_8) SYM_CODE_START_LOCAL(.Lbad_put_user_clac) ASM_CLAC .Lbad_put_user: - movl $-EFAULT,%eax + movl $-EFAULT,%ecx RET SYM_CODE_END(.Lbad_put_user_clac) diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c index b0dfac3d3df7..508c81e97ab1 100644 --- a/arch/x86/lib/usercopy_64.c +++ b/arch/x86/lib/usercopy_64.c @@ -56,27 +56,6 @@ unsigned long clear_user(void __user *to, unsigned long n) } EXPORT_SYMBOL(clear_user); -/* - * Similar to copy_user_handle_tail, probe for the write fault point, - * but reuse __memcpy_mcsafe in case a new read error is encountered. - * clac() is handled in _copy_to_iter_mcsafe(). - */ -__visible notrace unsigned long -mcsafe_handle_tail(char *to, char *from, unsigned len) -{ - for (; len; --len, to++, from++) { - /* - * Call the assembly routine back directly since - * memcpy_mcsafe() may silently fallback to memcpy. - */ - unsigned long rem = __memcpy_mcsafe(to, from, 1); - - if (rem) - break; - } - return len; -} - #ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE /** * clean_cache_range - write back a cache range with CLWB @@ -120,7 +99,7 @@ long __copy_user_flushcache(void *dst, const void __user *src, unsigned size) */ if (size < 8) { if (!IS_ALIGNED(dest, 4) || size != 4) - clean_cache_range(dst, 1); + clean_cache_range(dst, size); } else { if (!IS_ALIGNED(dest, 8)) { dest = ALIGN(dest, boot_cpu_data.x86_clflush_size); diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c index 770b613790b3..f5e1e60c9095 100644 --- a/arch/x86/mm/cpu_entry_area.c +++ b/arch/x86/mm/cpu_entry_area.c @@ -21,7 +21,8 @@ DEFINE_PER_CPU(struct cea_exception_stacks*, cea_exception_stacks); DECLARE_PER_CPU_PAGE_ALIGNED(struct doublefault_stack, doublefault_stack); #endif -struct cpu_entry_area *get_cpu_entry_area(int cpu) +/* Is called from entry code, so must be noinstr */ +noinstr struct cpu_entry_area *get_cpu_entry_area(int cpu) { unsigned long va = CPU_ENTRY_AREA_PER_CPU + cpu * CPU_ENTRY_AREA_SIZE; BUILD_BUG_ON(sizeof(struct cpu_entry_area) % PAGE_SIZE != 0); diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c index 1d6cb07f4f86..b93d6cd08a7f 100644 --- a/arch/x86/mm/extable.c +++ b/arch/x86/mm/extable.c @@ -5,6 +5,7 @@ #include <xen/xen.h> #include <asm/fpu/internal.h> +#include <asm/sev-es.h> #include <asm/traps.h> #include <asm/kdebug.h> @@ -80,6 +81,18 @@ __visible bool ex_handler_uaccess(const struct exception_table_entry *fixup, } EXPORT_SYMBOL(ex_handler_uaccess); +__visible bool ex_handler_copy(const struct exception_table_entry *fixup, + struct pt_regs *regs, int trapnr, + unsigned long error_code, + unsigned long fault_addr) +{ + WARN_ONCE(trapnr == X86_TRAP_GP, "General protection fault in user access. Non-canonical address?"); + regs->ip = ex_fixup_addr(fixup); + regs->ax = trapnr; + return true; +} +EXPORT_SYMBOL(ex_handler_copy); + __visible bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup, struct pt_regs *regs, int trapnr, unsigned long error_code, @@ -125,17 +138,21 @@ __visible bool ex_handler_clear_fs(const struct exception_table_entry *fixup, } EXPORT_SYMBOL(ex_handler_clear_fs); -__visible bool ex_has_fault_handler(unsigned long ip) +enum handler_type ex_get_fault_handler_type(unsigned long ip) { const struct exception_table_entry *e; ex_handler_t handler; e = search_exception_tables(ip); if (!e) - return false; + return EX_HANDLER_NONE; handler = ex_fixup_handler(e); - - return handler == ex_handler_fault; + if (handler == ex_handler_fault) + return EX_HANDLER_FAULT; + else if (handler == ex_handler_uaccess || handler == ex_handler_copy) + return EX_HANDLER_UACCESS; + else + return EX_HANDLER_OTHER; } int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code, diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 6e3e8a124903..82bf37a5c9ec 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1128,7 +1128,7 @@ access_error(unsigned long error_code, struct vm_area_struct *vma) return 0; } -static int fault_in_kernel_space(unsigned long address) +bool fault_in_kernel_space(unsigned long address) { /* * On 64-bit systems, the vsyscall page is at an address above @@ -1446,11 +1446,14 @@ DEFINE_IDTENTRY_RAW_ERRORCODE(exc_page_fault) prefetchw(¤t->mm->mmap_lock); /* - * KVM has two types of events that are, logically, interrupts, but - * are unfortunately delivered using the #PF vector. These events are - * "you just accessed valid memory, but the host doesn't have it right - * now, so I'll put you to sleep if you continue" and "that memory - * you tried to access earlier is available now." + * KVM uses #PF vector to deliver 'page not present' events to guests + * (asynchronous page fault mechanism). The event happens when a + * userspace task is trying to access some valid (from guest's point of + * view) memory which is not currently mapped by the host (e.g. the + * memory is swapped out). Note, the corresponding "page ready" event + * which is injected when the memory becomes available, is delived via + * an interrupt mechanism and not a #PF exception + * (see arch/x86/kernel/kvm.c: sysvec_kvm_asyncpf_interrupt()). * * We are relying on the interrupted context being sane (valid RSP, * relevant locks not held, etc.), which is fine as long as the diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index a4ac13cc3fdc..b5a3fa4033d3 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -217,11 +217,6 @@ static void sync_global_pgds(unsigned long start, unsigned long end) sync_global_pgds_l4(start, end); } -void arch_sync_kernel_mappings(unsigned long start, unsigned long end) -{ - sync_global_pgds(start, end); -} - /* * NOTE: This function is marked __ref because it calls __init function * (alloc_bootmem_pages). It's safe to do it ONLY when after_bootmem == 0. @@ -1257,14 +1252,19 @@ static void __init preallocate_vmalloc_pages(void) if (!p4d) goto failed; - /* - * With 5-level paging the P4D level is not folded. So the PGDs - * are now populated and there is no need to walk down to the - * PUD level. - */ if (pgtable_l5_enabled()) continue; + /* + * The goal here is to allocate all possibly required + * hardware page tables pointed to by the top hardware + * level. + * + * On 4-level systems, the P4D layer is folded away and + * the above code does no preallocation. Below, go down + * to the pud _software_ level to ensure the second + * hardware level is allocated on 4-level systems too. + */ lvl = "pud"; pud = pud_alloc(&init_mm, p4d, addr); if (!pud) diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c index 9f1177edc2e7..efbb3de472df 100644 --- a/arch/x86/mm/mem_encrypt.c +++ b/arch/x86/mm/mem_encrypt.c @@ -37,12 +37,13 @@ * reside in the .data section so as not to be zeroed out when the .bss * section is later cleared. */ -u64 sme_me_mask __section(.data) = 0; +u64 sme_me_mask __section(".data") = 0; +u64 sev_status __section(".data") = 0; EXPORT_SYMBOL(sme_me_mask); DEFINE_STATIC_KEY_FALSE(sev_enable_key); EXPORT_SYMBOL_GPL(sev_enable_key); -bool sev_enabled __section(.data); +bool sev_enabled __section(".data"); /* Buffer used for early in-place encryption by BSP, no locking needed */ static char sme_early_buffer[PAGE_SIZE] __initdata __aligned(PAGE_SIZE); @@ -347,7 +348,13 @@ bool sme_active(void) bool sev_active(void) { - return sme_me_mask && sev_enabled; + return sev_status & MSR_AMD64_SEV_ENABLED; +} + +/* Needs to be called from non-instrumentable code */ +bool noinstr sev_es_active(void) +{ + return sev_status & MSR_AMD64_SEV_ES_ENABLED; } /* Override for DMA direct allocation check - ARCH_HAS_FORCE_DMA_UNENCRYPTED */ @@ -400,6 +407,31 @@ void __init mem_encrypt_free_decrypted_mem(void) free_init_pages("unused decrypted", vaddr, vaddr_end); } +static void print_mem_encrypt_feature_info(void) +{ + pr_info("AMD Memory Encryption Features active:"); + + /* Secure Memory Encryption */ + if (sme_active()) { + /* + * SME is mutually exclusive with any of the SEV + * features below. + */ + pr_cont(" SME\n"); + return; + } + + /* Secure Encrypted Virtualization */ + if (sev_active()) + pr_cont(" SEV"); + + /* Encrypted Register State */ + if (sev_es_active()) + pr_cont(" SEV-ES"); + + pr_cont("\n"); +} + /* Architecture __weak replacement functions */ void __init mem_encrypt_init(void) { @@ -415,8 +447,6 @@ void __init mem_encrypt_init(void) if (sev_active()) static_branch_enable(&sev_enable_key); - pr_info("AMD %s active\n", - sev_active() ? "Secure Encrypted Virtualization (SEV)" - : "Secure Memory Encryption (SME)"); + print_mem_encrypt_feature_info(); } diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c index e2b0e2ac07bb..733b983f3a89 100644 --- a/arch/x86/mm/mem_encrypt_identity.c +++ b/arch/x86/mm/mem_encrypt_identity.c @@ -81,7 +81,7 @@ struct sme_populate_pgd_data { * section is 2MB aligned to allow for simple pagetable setup using only * PMD entries (see vmlinux.lds.S). */ -static char sme_workarea[2 * PMD_PAGE_SIZE] __section(.init.scratch); +static char sme_workarea[2 * PMD_PAGE_SIZE] __section(".init.scratch"); static char sme_cmdline_arg[] __initdata = "mem_encrypt"; static char sme_cmdline_on[] __initdata = "on"; @@ -540,6 +540,9 @@ void __init sme_enable(struct boot_params *bp) if (!(msr & MSR_AMD64_SEV_ENABLED)) return; + /* Save SEV_STATUS to avoid reading MSR again */ + sev_status = msr; + /* SEV state cannot be controlled by a command line option */ sme_me_mask = me_mask; sev_enabled = true; diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index aa76ec2d359b..44148691d78b 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c @@ -37,14 +37,12 @@ static __init int numa_setup(char *opt) return -EINVAL; if (!strncmp(opt, "off", 3)) numa_off = 1; -#ifdef CONFIG_NUMA_EMU if (!strncmp(opt, "fake=", 5)) - numa_emu_cmdline(opt + 5); -#endif -#ifdef CONFIG_ACPI_NUMA + return numa_emu_cmdline(opt + 5); if (!strncmp(opt, "noacpi", 6)) - acpi_numa = -1; -#endif + disable_srat(); + if (!strncmp(opt, "nohmat", 6)) + disable_hmat(); return 0; } early_param("numa", numa_setup); @@ -516,7 +514,7 @@ static void __init numa_clear_kernel_node_hotplug(void) * memory ranges, because quirks such as trim_snb_memory() * reserve specific pages for Sandy Bridge graphics. ] */ - for_each_memblock(reserved, mb_region) { + for_each_reserved_mem_region(mb_region) { int nid = memblock_get_region_node(mb_region); if (nid != MAX_NUMNODES) @@ -748,6 +746,27 @@ static void __init init_memory_less_node(int nid) } /* + * A node may exist which has one or more Generic Initiators but no CPUs and no + * memory. + * + * This function must be called after init_cpu_to_node(), to ensure that any + * memoryless CPU nodes have already been brought online, and before the + * node_data[nid] is needed for zone list setup in build_all_zonelists(). + * + * When this function is called, any nodes containing either memory and/or CPUs + * will already be online and there is no need to do anything extra, even if + * they also contain one or more Generic Initiators. + */ +void __init init_gi_nodes(void) +{ + int nid; + + for_each_node_state(nid, N_GENERIC_INITIATOR) + if (!node_online(nid)) + init_memory_less_node(nid); +} + +/* * Setup early cpu_to_node. * * Populate cpu_to_node[] only if x86_cpu_to_apicid[], @@ -919,7 +938,6 @@ int phys_to_target_node(phys_addr_t start) return meminfo_to_nid(&numa_reserved_meminfo, start); } -EXPORT_SYMBOL_GPL(phys_to_target_node); int memory_add_physaddr_to_nid(u64 start) { diff --git a/arch/x86/mm/numa_emulation.c b/arch/x86/mm/numa_emulation.c index 683cd12f4793..87d77cc52f86 100644 --- a/arch/x86/mm/numa_emulation.c +++ b/arch/x86/mm/numa_emulation.c @@ -13,9 +13,10 @@ static int emu_nid_to_phys[MAX_NUMNODES]; static char *emu_cmdline __initdata; -void __init numa_emu_cmdline(char *str) +int __init numa_emu_cmdline(char *str) { emu_cmdline = str; + return 0; } static int __init emu_find_memblk_by_nid(int nid, const struct numa_meminfo *mi) diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index d1b2a889f035..40baa90e74f4 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -1999,7 +1999,7 @@ static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc) /* * Before changing the encryption attribute, we need to flush caches. */ - cpa_flush(&cpa, 1); + cpa_flush(&cpa, !this_cpu_has(X86_FEATURE_SME_COHERENT)); ret = __change_page_attr_set_clr(&cpa, 1); diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 0951b47e64c1..11666ba19b62 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -14,7 +14,6 @@ #include <asm/nospec-branch.h> #include <asm/cache.h> #include <asm/apic.h> -#include <asm/uv/uv.h> #include "mm_internal.h" @@ -800,29 +799,6 @@ STATIC_NOPV void native_flush_tlb_others(const struct cpumask *cpumask, trace_tlb_flush(TLB_REMOTE_SEND_IPI, (info->end - info->start) >> PAGE_SHIFT); - if (is_uv_system()) { - /* - * This whole special case is confused. UV has a "Broadcast - * Assist Unit", which seems to be a fancy way to send IPIs. - * Back when x86 used an explicit TLB flush IPI, UV was - * optimized to use its own mechanism. These days, x86 uses - * smp_call_function_many(), but UV still uses a manual IPI, - * and that IPI's action is out of date -- it does a manual - * flush instead of calling flush_tlb_func_remote(). This - * means that the percpu tlb_gen variables won't be updated - * and we'll do pointless flushes on future context switches. - * - * Rather than hooking native_flush_tlb_others() here, I think - * that UV should be updated so that smp_call_function_many(), - * etc, are optimal on UV. - */ - cpumask = uv_flush_tlb_others(cpumask, info); - if (cpumask) - smp_call_function_many(cpumask, flush_tlb_func_remote, - (void *)info, 1); - return; - } - /* * If no page tables were freed, we can skip sending IPIs to * CPUs in lazy TLB mode. They will flush the CPU themselves diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 42b6709e6dc7..796506dcfc42 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -221,14 +221,48 @@ struct jit_context { /* Number of bytes emit_patch() needs to generate instructions */ #define X86_PATCH_SIZE 5 +/* Number of bytes that will be skipped on tailcall */ +#define X86_TAIL_CALL_OFFSET 11 -#define PROLOGUE_SIZE 25 +static void push_callee_regs(u8 **pprog, bool *callee_regs_used) +{ + u8 *prog = *pprog; + int cnt = 0; + + if (callee_regs_used[0]) + EMIT1(0x53); /* push rbx */ + if (callee_regs_used[1]) + EMIT2(0x41, 0x55); /* push r13 */ + if (callee_regs_used[2]) + EMIT2(0x41, 0x56); /* push r14 */ + if (callee_regs_used[3]) + EMIT2(0x41, 0x57); /* push r15 */ + *pprog = prog; +} + +static void pop_callee_regs(u8 **pprog, bool *callee_regs_used) +{ + u8 *prog = *pprog; + int cnt = 0; + + if (callee_regs_used[3]) + EMIT2(0x41, 0x5F); /* pop r15 */ + if (callee_regs_used[2]) + EMIT2(0x41, 0x5E); /* pop r14 */ + if (callee_regs_used[1]) + EMIT2(0x41, 0x5D); /* pop r13 */ + if (callee_regs_used[0]) + EMIT1(0x5B); /* pop rbx */ + *pprog = prog; +} /* - * Emit x86-64 prologue code for BPF program and check its size. - * bpf_tail_call helper will skip it while jumping into another program + * Emit x86-64 prologue code for BPF program. + * bpf_tail_call helper will skip the first X86_TAIL_CALL_OFFSET bytes + * while jumping to another program */ -static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf) +static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf, + bool tail_call_reachable, bool is_subprog) { u8 *prog = *pprog; int cnt = X86_PATCH_SIZE; @@ -238,19 +272,19 @@ static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf) */ memcpy(prog, ideal_nops[NOP_ATOMIC5], cnt); prog += cnt; + if (!ebpf_from_cbpf) { + if (tail_call_reachable && !is_subprog) + EMIT2(0x31, 0xC0); /* xor eax, eax */ + else + EMIT2(0x66, 0x90); /* nop2 */ + } EMIT1(0x55); /* push rbp */ EMIT3(0x48, 0x89, 0xE5); /* mov rbp, rsp */ /* sub rsp, rounded_stack_depth */ - EMIT3_off32(0x48, 0x81, 0xEC, round_up(stack_depth, 8)); - EMIT1(0x53); /* push rbx */ - EMIT2(0x41, 0x55); /* push r13 */ - EMIT2(0x41, 0x56); /* push r14 */ - EMIT2(0x41, 0x57); /* push r15 */ - if (!ebpf_from_cbpf) { - /* zero init tail_call_cnt */ - EMIT2(0x6a, 0x00); - BUILD_BUG_ON(cnt != PROLOGUE_SIZE); - } + if (stack_depth) + EMIT3_off32(0x48, 0x81, 0xEC, round_up(stack_depth, 8)); + if (tail_call_reachable) + EMIT1(0x50); /* push rax */ *pprog = prog; } @@ -314,13 +348,14 @@ static int __bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, mutex_lock(&text_mutex); if (memcmp(ip, old_insn, X86_PATCH_SIZE)) goto out; + ret = 1; if (memcmp(ip, new_insn, X86_PATCH_SIZE)) { if (text_live) text_poke_bp(ip, new_insn, X86_PATCH_SIZE, NULL); else memcpy(ip, new_insn, X86_PATCH_SIZE); + ret = 0; } - ret = 0; out: mutex_unlock(&text_mutex); return ret; @@ -337,6 +372,22 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, return __bpf_arch_text_poke(ip, t, old_addr, new_addr, true); } +static int get_pop_bytes(bool *callee_regs_used) +{ + int bytes = 0; + + if (callee_regs_used[3]) + bytes += 2; + if (callee_regs_used[2]) + bytes += 2; + if (callee_regs_used[1]) + bytes += 2; + if (callee_regs_used[0]) + bytes += 1; + + return bytes; +} + /* * Generate the following code: * @@ -351,12 +402,32 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, * goto *(prog->bpf_func + prologue_size); * out: */ -static void emit_bpf_tail_call_indirect(u8 **pprog) +static void emit_bpf_tail_call_indirect(u8 **pprog, bool *callee_regs_used, + u32 stack_depth) { + int tcc_off = -4 - round_up(stack_depth, 8); u8 *prog = *pprog; - int label1, label2, label3; + int pop_bytes = 0; + int off1 = 42; + int off2 = 31; + int off3 = 9; int cnt = 0; + /* count the additional bytes used for popping callee regs from stack + * that need to be taken into account for each of the offsets that + * are used for bailing out of the tail call + */ + pop_bytes = get_pop_bytes(callee_regs_used); + off1 += pop_bytes; + off2 += pop_bytes; + off3 += pop_bytes; + + if (stack_depth) { + off1 += 7; + off2 += 7; + off3 += 7; + } + /* * rdi - pointer to ctx * rsi - pointer to bpf_array @@ -370,72 +441,112 @@ static void emit_bpf_tail_call_indirect(u8 **pprog) EMIT2(0x89, 0xD2); /* mov edx, edx */ EMIT3(0x39, 0x56, /* cmp dword ptr [rsi + 16], edx */ offsetof(struct bpf_array, map.max_entries)); -#define OFFSET1 (41 + RETPOLINE_RAX_BPF_JIT_SIZE) /* Number of bytes to jump */ +#define OFFSET1 (off1 + RETPOLINE_RCX_BPF_JIT_SIZE) /* Number of bytes to jump */ EMIT2(X86_JBE, OFFSET1); /* jbe out */ - label1 = cnt; /* * if (tail_call_cnt > MAX_TAIL_CALL_CNT) * goto out; */ - EMIT2_off32(0x8B, 0x85, -36 - MAX_BPF_STACK); /* mov eax, dword ptr [rbp - 548] */ + EMIT2_off32(0x8B, 0x85, tcc_off); /* mov eax, dword ptr [rbp - tcc_off] */ EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */ -#define OFFSET2 (30 + RETPOLINE_RAX_BPF_JIT_SIZE) +#define OFFSET2 (off2 + RETPOLINE_RCX_BPF_JIT_SIZE) EMIT2(X86_JA, OFFSET2); /* ja out */ - label2 = cnt; EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */ - EMIT2_off32(0x89, 0x85, -36 - MAX_BPF_STACK); /* mov dword ptr [rbp -548], eax */ + EMIT2_off32(0x89, 0x85, tcc_off); /* mov dword ptr [rbp - tcc_off], eax */ /* prog = array->ptrs[index]; */ - EMIT4_off32(0x48, 0x8B, 0x84, 0xD6, /* mov rax, [rsi + rdx * 8 + offsetof(...)] */ + EMIT4_off32(0x48, 0x8B, 0x8C, 0xD6, /* mov rcx, [rsi + rdx * 8 + offsetof(...)] */ offsetof(struct bpf_array, ptrs)); /* * if (prog == NULL) * goto out; */ - EMIT3(0x48, 0x85, 0xC0); /* test rax,rax */ -#define OFFSET3 (8 + RETPOLINE_RAX_BPF_JIT_SIZE) + EMIT3(0x48, 0x85, 0xC9); /* test rcx,rcx */ +#define OFFSET3 (off3 + RETPOLINE_RCX_BPF_JIT_SIZE) EMIT2(X86_JE, OFFSET3); /* je out */ - label3 = cnt; - /* goto *(prog->bpf_func + prologue_size); */ - EMIT4(0x48, 0x8B, 0x40, /* mov rax, qword ptr [rax + 32] */ - offsetof(struct bpf_prog, bpf_func)); - EMIT4(0x48, 0x83, 0xC0, PROLOGUE_SIZE); /* add rax, prologue_size */ + *pprog = prog; + pop_callee_regs(pprog, callee_regs_used); + prog = *pprog; + + EMIT1(0x58); /* pop rax */ + if (stack_depth) + EMIT3_off32(0x48, 0x81, 0xC4, /* add rsp, sd */ + round_up(stack_depth, 8)); + /* goto *(prog->bpf_func + X86_TAIL_CALL_OFFSET); */ + EMIT4(0x48, 0x8B, 0x49, /* mov rcx, qword ptr [rcx + 32] */ + offsetof(struct bpf_prog, bpf_func)); + EMIT4(0x48, 0x83, 0xC1, /* add rcx, X86_TAIL_CALL_OFFSET */ + X86_TAIL_CALL_OFFSET); /* - * Wow we're ready to jump into next BPF program + * Now we're ready to jump into next BPF program * rdi == ctx (1st arg) - * rax == prog->bpf_func + prologue_size + * rcx == prog->bpf_func + X86_TAIL_CALL_OFFSET */ - RETPOLINE_RAX_BPF_JIT(); + RETPOLINE_RCX_BPF_JIT(); /* out: */ - BUILD_BUG_ON(cnt - label1 != OFFSET1); - BUILD_BUG_ON(cnt - label2 != OFFSET2); - BUILD_BUG_ON(cnt - label3 != OFFSET3); *pprog = prog; } static void emit_bpf_tail_call_direct(struct bpf_jit_poke_descriptor *poke, - u8 **pprog, int addr, u8 *image) + u8 **pprog, int addr, u8 *image, + bool *callee_regs_used, u32 stack_depth) { + int tcc_off = -4 - round_up(stack_depth, 8); u8 *prog = *pprog; + int pop_bytes = 0; + int off1 = 20; + int poke_off; int cnt = 0; + /* count the additional bytes used for popping callee regs to stack + * that need to be taken into account for jump offset that is used for + * bailing out from of the tail call when limit is reached + */ + pop_bytes = get_pop_bytes(callee_regs_used); + off1 += pop_bytes; + + /* + * total bytes for: + * - nop5/ jmpq $off + * - pop callee regs + * - sub rsp, $val if depth > 0 + * - pop rax + */ + poke_off = X86_PATCH_SIZE + pop_bytes + 1; + if (stack_depth) { + poke_off += 7; + off1 += 7; + } + /* * if (tail_call_cnt > MAX_TAIL_CALL_CNT) * goto out; */ - EMIT2_off32(0x8B, 0x85, -36 - MAX_BPF_STACK); /* mov eax, dword ptr [rbp - 548] */ + EMIT2_off32(0x8B, 0x85, tcc_off); /* mov eax, dword ptr [rbp - tcc_off] */ EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */ - EMIT2(X86_JA, 14); /* ja out */ + EMIT2(X86_JA, off1); /* ja out */ EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */ - EMIT2_off32(0x89, 0x85, -36 - MAX_BPF_STACK); /* mov dword ptr [rbp -548], eax */ + EMIT2_off32(0x89, 0x85, tcc_off); /* mov dword ptr [rbp - tcc_off], eax */ - poke->ip = image + (addr - X86_PATCH_SIZE); - poke->adj_off = PROLOGUE_SIZE; + poke->tailcall_bypass = image + (addr - poke_off - X86_PATCH_SIZE); + poke->adj_off = X86_TAIL_CALL_OFFSET; + poke->tailcall_target = image + (addr - X86_PATCH_SIZE); + poke->bypass_addr = (u8 *)poke->tailcall_target + X86_PATCH_SIZE; + + emit_jump(&prog, (u8 *)poke->tailcall_target + X86_PATCH_SIZE, + poke->tailcall_bypass); + + *pprog = prog; + pop_callee_regs(pprog, callee_regs_used); + prog = *pprog; + EMIT1(0x58); /* pop rax */ + if (stack_depth) + EMIT3_off32(0x48, 0x81, 0xC4, round_up(stack_depth, 8)); memcpy(prog, ideal_nops[NOP_ATOMIC5], X86_PATCH_SIZE); prog += X86_PATCH_SIZE; @@ -453,7 +564,7 @@ static void bpf_tail_call_direct_fixup(struct bpf_prog *prog) for (i = 0; i < prog->aux->size_poke_tab; i++) { poke = &prog->aux->poke_tab[i]; - WARN_ON_ONCE(READ_ONCE(poke->ip_stable)); + WARN_ON_ONCE(READ_ONCE(poke->tailcall_target_stable)); if (poke->reason != BPF_POKE_REASON_TAIL_CALL) continue; @@ -464,18 +575,25 @@ static void bpf_tail_call_direct_fixup(struct bpf_prog *prog) if (target) { /* Plain memcpy is used when image is not live yet * and still not locked as read-only. Once poke - * location is active (poke->ip_stable), any parallel - * bpf_arch_text_poke() might occur still on the - * read-write image until we finally locked it as - * read-only. Both modifications on the given image - * are under text_mutex to avoid interference. + * location is active (poke->tailcall_target_stable), + * any parallel bpf_arch_text_poke() might occur + * still on the read-write image until we finally + * locked it as read-only. Both modifications on + * the given image are under text_mutex to avoid + * interference. */ - ret = __bpf_arch_text_poke(poke->ip, BPF_MOD_JUMP, NULL, + ret = __bpf_arch_text_poke(poke->tailcall_target, + BPF_MOD_JUMP, NULL, (u8 *)target->bpf_func + poke->adj_off, false); BUG_ON(ret < 0); + ret = __bpf_arch_text_poke(poke->tailcall_bypass, + BPF_MOD_JUMP, + (u8 *)poke->tailcall_target + + X86_PATCH_SIZE, NULL, false); + BUG_ON(ret < 0); } - WRITE_ONCE(poke->ip_stable, true); + WRITE_ONCE(poke->tailcall_target_stable, true); mutex_unlock(&array->aux->poke_mutex); } } @@ -652,19 +770,49 @@ static bool ex_handler_bpf(const struct exception_table_entry *x, return true; } +static void detect_reg_usage(struct bpf_insn *insn, int insn_cnt, + bool *regs_used, bool *tail_call_seen) +{ + int i; + + for (i = 1; i <= insn_cnt; i++, insn++) { + if (insn->code == (BPF_JMP | BPF_TAIL_CALL)) + *tail_call_seen = true; + if (insn->dst_reg == BPF_REG_6 || insn->src_reg == BPF_REG_6) + regs_used[0] = true; + if (insn->dst_reg == BPF_REG_7 || insn->src_reg == BPF_REG_7) + regs_used[1] = true; + if (insn->dst_reg == BPF_REG_8 || insn->src_reg == BPF_REG_8) + regs_used[2] = true; + if (insn->dst_reg == BPF_REG_9 || insn->src_reg == BPF_REG_9) + regs_used[3] = true; + } +} + static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, int oldproglen, struct jit_context *ctx) { + bool tail_call_reachable = bpf_prog->aux->tail_call_reachable; struct bpf_insn *insn = bpf_prog->insnsi; + bool callee_regs_used[4] = {}; int insn_cnt = bpf_prog->len; + bool tail_call_seen = false; bool seen_exit = false; u8 temp[BPF_MAX_INSN_SIZE + BPF_INSN_SAFETY]; int i, cnt = 0, excnt = 0; int proglen = 0; u8 *prog = temp; + detect_reg_usage(insn, insn_cnt, callee_regs_used, + &tail_call_seen); + + /* tail call's presence in current prog implies it is reachable */ + tail_call_reachable |= tail_call_seen; + emit_prologue(&prog, bpf_prog->aux->stack_depth, - bpf_prog_was_classic(bpf_prog)); + bpf_prog_was_classic(bpf_prog), tail_call_reachable, + bpf_prog->aux->func_idx != 0); + push_callee_regs(&prog, callee_regs_used); addrs[0] = prog - temp; for (i = 1; i <= insn_cnt; i++, insn++) { @@ -1102,16 +1250,27 @@ xadd: if (is_imm8(insn->off)) /* call */ case BPF_JMP | BPF_CALL: func = (u8 *) __bpf_call_base + imm32; - if (!imm32 || emit_call(&prog, func, image + addrs[i - 1])) - return -EINVAL; + if (tail_call_reachable) { + EMIT3_off32(0x48, 0x8B, 0x85, + -(bpf_prog->aux->stack_depth + 8)); + if (!imm32 || emit_call(&prog, func, image + addrs[i - 1] + 7)) + return -EINVAL; + } else { + if (!imm32 || emit_call(&prog, func, image + addrs[i - 1])) + return -EINVAL; + } break; case BPF_JMP | BPF_TAIL_CALL: if (imm32) emit_bpf_tail_call_direct(&bpf_prog->aux->poke_tab[imm32 - 1], - &prog, addrs[i], image); + &prog, addrs[i], image, + callee_regs_used, + bpf_prog->aux->stack_depth); else - emit_bpf_tail_call_indirect(&prog); + emit_bpf_tail_call_indirect(&prog, + callee_regs_used, + bpf_prog->aux->stack_depth); break; /* cond jump */ @@ -1294,12 +1453,7 @@ emit_jmp: seen_exit = true; /* Update cleanup_addr */ ctx->cleanup_addr = proglen; - if (!bpf_prog_was_classic(bpf_prog)) - EMIT1(0x5B); /* get rid of tail_call_cnt */ - EMIT2(0x41, 0x5F); /* pop r15 */ - EMIT2(0x41, 0x5E); /* pop r14 */ - EMIT2(0x41, 0x5D); /* pop r13 */ - EMIT1(0x5B); /* pop rbx */ + pop_callee_regs(&prog, callee_regs_used); EMIT1(0xC9); /* leave */ EMIT1(0xC3); /* ret */ break; @@ -1379,10 +1533,15 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog, u8 *prog = *pprog; int cnt = 0; - if (emit_call(&prog, __bpf_prog_enter, prog)) - return -EINVAL; - /* remember prog start time returned by __bpf_prog_enter */ - emit_mov_reg(&prog, true, BPF_REG_6, BPF_REG_0); + if (p->aux->sleepable) { + if (emit_call(&prog, __bpf_prog_enter_sleepable, prog)) + return -EINVAL; + } else { + if (emit_call(&prog, __bpf_prog_enter, prog)) + return -EINVAL; + /* remember prog start time returned by __bpf_prog_enter */ + emit_mov_reg(&prog, true, BPF_REG_6, BPF_REG_0); + } /* arg1: lea rdi, [rbp - stack_size] */ EMIT4(0x48, 0x8D, 0x7D, -stack_size); @@ -1402,13 +1561,18 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog, if (mod_ret) emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -8); - /* arg1: mov rdi, progs[i] */ - emit_mov_imm64(&prog, BPF_REG_1, (long) p >> 32, - (u32) (long) p); - /* arg2: mov rsi, rbx <- start time in nsec */ - emit_mov_reg(&prog, true, BPF_REG_2, BPF_REG_6); - if (emit_call(&prog, __bpf_prog_exit, prog)) - return -EINVAL; + if (p->aux->sleepable) { + if (emit_call(&prog, __bpf_prog_exit_sleepable, prog)) + return -EINVAL; + } else { + /* arg1: mov rdi, progs[i] */ + emit_mov_imm64(&prog, BPF_REG_1, (long) p >> 32, + (u32) (long) p); + /* arg2: mov rsi, rbx <- start time in nsec */ + emit_mov_reg(&prog, true, BPF_REG_2, BPF_REG_6); + if (emit_call(&prog, __bpf_prog_exit, prog)) + return -EINVAL; + } *pprog = prog; return 0; diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index df1d95913d4e..3507f456fcd0 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -19,6 +19,7 @@ #include <asm/smp.h> #include <asm/pci_x86.h> #include <asm/setup.h> +#include <asm/irqdomain.h> unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | PCI_PROBE_MMCONF; @@ -633,8 +634,9 @@ static void set_dev_domain_options(struct pci_dev *pdev) int pcibios_add_device(struct pci_dev *dev) { - struct setup_data *data; struct pci_setup_rom *rom; + struct irq_domain *msidom; + struct setup_data *data; u64 pa_data; pa_data = boot_params.hdr.setup_data; @@ -661,6 +663,20 @@ int pcibios_add_device(struct pci_dev *dev) memunmap(data); } set_dev_domain_options(dev); + + /* + * Setup the initial MSI domain of the device. If the underlying + * bus has a PCI/MSI irqdomain associated use the bus domain, + * otherwise set the default domain. This ensures that special irq + * domains e.g. VMD are preserved. The default ensures initial + * operation if irq remapping is not active. If irq remapping is + * active it will overwrite the domain pointer when the device is + * associated to a remapping domain. + */ + msidom = dev_get_msi_domain(&dev->bus->dev); + if (!msidom) + msidom = x86_pci_msi_default_domain; + dev_set_msi_domain(&dev->dev, msidom); return 0; } diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index b8c9a5b87f37..0a0e168be1cb 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -587,7 +587,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0xa26d, pci_invalid_bar); static void pci_fixup_amd_ehci_pme(struct pci_dev *dev) { dev_info(&dev->dev, "PME# does not work under D3, disabling it\n"); - dev->pme_support &= ~((PCI_PM_CAP_PME_D3 | PCI_PM_CAP_PME_D3cold) + dev->pme_support &= ~((PCI_PM_CAP_PME_D3hot | PCI_PM_CAP_PME_D3cold) >> PCI_PM_CAP_PME_SHIFT); } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x7808, pci_fixup_amd_ehci_pme); diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c index 5fc617edf108..00bfa1ebad6c 100644 --- a/arch/x86/pci/init.c +++ b/arch/x86/pci/init.c @@ -3,16 +3,17 @@ #include <linux/init.h> #include <asm/pci_x86.h> #include <asm/x86_init.h> +#include <asm/irqdomain.h> /* arch_initcall has too random ordering, so call the initializers in the right sequence from here. */ static __init int pci_arch_init(void) { -#ifdef CONFIG_PCI_DIRECT - int type = 0; + int type; + + x86_create_pci_msi_domain(); type = pci_direct_probe(); -#endif if (!(pci_probe & PCI_PROBE_NOEARLY)) pci_mmcfg_early_init(); @@ -20,18 +21,16 @@ static __init int pci_arch_init(void) if (x86_init.pci.arch_init && !x86_init.pci.arch_init()) return 0; -#ifdef CONFIG_PCI_BIOS pci_pcbios_init(); -#endif + /* * don't check for raw_pci_ops here because we want pcbios as last * fallback, yet it's needed to run first to set pcibios_last_bus * in case legacy PCI probing is used. otherwise detecting peer busses * fails. */ -#ifdef CONFIG_PCI_DIRECT pci_direct_init(type); -#endif + if (!raw_pci_ops && !raw_pci_ext_ops) printk(KERN_ERR "PCI: Fatal: No config space access function found\n"); diff --git a/arch/x86/pci/intel_mid_pci.c b/arch/x86/pci/intel_mid_pci.c index 00c62115f39c..24ca4ee2802f 100644 --- a/arch/x86/pci/intel_mid_pci.c +++ b/arch/x86/pci/intel_mid_pci.c @@ -33,6 +33,7 @@ #include <asm/hw_irq.h> #include <asm/io_apic.h> #include <asm/intel-mid.h> +#include <asm/acpi.h> #define PCIE_CAP_OFFSET 0x100 @@ -322,7 +323,7 @@ static void pci_d3delay_fixup(struct pci_dev *dev) */ if (type1_access_ok(dev->bus->number, dev->devfn, PCI_DEVICE_ID)) return; - dev->d3_delay = 0; + dev->d3hot_delay = 0; } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_d3delay_fixup); diff --git a/arch/x86/pci/sta2x11-fixup.c b/arch/x86/pci/sta2x11-fixup.c index c313d784efab..5701d5ba3df4 100644 --- a/arch/x86/pci/sta2x11-fixup.c +++ b/arch/x86/pci/sta2x11-fixup.c @@ -15,7 +15,6 @@ #include <asm/iommu.h> #define STA2X11_SWIOTLB_SIZE (4*1024*1024) -extern int swiotlb_late_init_with_default_size(size_t default_size); /* * We build a list of bus numbers that are under the ConneXt. The @@ -133,7 +132,7 @@ static void sta2x11_map_ep(struct pci_dev *pdev) struct sta2x11_instance *instance = sta2x11_pdev_to_instance(pdev); struct device *dev = &pdev->dev; u32 amba_base, max_amba_addr; - int i; + int i, ret; if (!instance) return; @@ -141,7 +140,9 @@ static void sta2x11_map_ep(struct pci_dev *pdev) pci_read_config_dword(pdev, AHB_BASE(0), &amba_base); max_amba_addr = amba_base + STA2X11_AMBA_SIZE - 1; - dev->dma_pfn_offset = PFN_DOWN(-amba_base); + ret = dma_direct_set_offset(dev, 0, amba_base, STA2X11_AMBA_SIZE); + if (ret) + dev_err(dev, "sta2x11: could not set DMA offset\n"); dev->bus_dma_limit = max_amba_addr; pci_set_consistent_dma_mask(pdev, max_amba_addr); diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 89395a5049bb..c552cd2d0632 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -157,6 +157,13 @@ static int acpi_register_gsi_xen(struct device *dev, u32 gsi, struct xen_pci_frontend_ops *xen_pci_frontend; EXPORT_SYMBOL_GPL(xen_pci_frontend); +struct xen_msi_ops { + int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type); + void (*teardown_msi_irqs)(struct pci_dev *dev); +}; + +static struct xen_msi_ops xen_msi_ops __ro_after_init; + static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { int irq, ret, i; @@ -372,28 +379,122 @@ static void xen_initdom_restore_msi_irqs(struct pci_dev *dev) WARN(ret && ret != -ENOSYS, "restore_msi -> %d\n", ret); } } -#endif +#else /* CONFIG_XEN_DOM0 */ +#define xen_initdom_setup_msi_irqs NULL +#define xen_initdom_restore_msi_irqs NULL +#endif /* !CONFIG_XEN_DOM0 */ static void xen_teardown_msi_irqs(struct pci_dev *dev) { struct msi_desc *msidesc; + int i; + + for_each_pci_msi_entry(msidesc, dev) { + if (msidesc->irq) { + for (i = 0; i < msidesc->nvec_used; i++) + xen_destroy_irq(msidesc->irq + i); + } + } +} + +static void xen_pv_teardown_msi_irqs(struct pci_dev *dev) +{ + struct msi_desc *msidesc = first_pci_msi_entry(dev); - msidesc = first_pci_msi_entry(dev); if (msidesc->msi_attrib.is_msix) xen_pci_frontend_disable_msix(dev); else xen_pci_frontend_disable_msi(dev); - /* Free the IRQ's and the msidesc using the generic code. */ - default_teardown_msi_irqs(dev); + xen_teardown_msi_irqs(dev); } -static void xen_teardown_msi_irq(unsigned int irq) +static int xen_msi_domain_alloc_irqs(struct irq_domain *domain, + struct device *dev, int nvec) { - xen_destroy_irq(irq); + int type; + + if (WARN_ON_ONCE(!dev_is_pci(dev))) + return -EINVAL; + + if (first_msi_entry(dev)->msi_attrib.is_msix) + type = PCI_CAP_ID_MSIX; + else + type = PCI_CAP_ID_MSI; + + return xen_msi_ops.setup_msi_irqs(to_pci_dev(dev), nvec, type); } -#endif +static void xen_msi_domain_free_irqs(struct irq_domain *domain, + struct device *dev) +{ + if (WARN_ON_ONCE(!dev_is_pci(dev))) + return; + + xen_msi_ops.teardown_msi_irqs(to_pci_dev(dev)); +} + +static struct msi_domain_ops xen_pci_msi_domain_ops = { + .domain_alloc_irqs = xen_msi_domain_alloc_irqs, + .domain_free_irqs = xen_msi_domain_free_irqs, +}; + +static struct msi_domain_info xen_pci_msi_domain_info = { + .ops = &xen_pci_msi_domain_ops, +}; + +/* + * This irq domain is a blatant violation of the irq domain design, but + * distangling XEN into real irq domains is not a job for mere mortals with + * limited XENology. But it's the least dangerous way for a mere mortal to + * get rid of the arch_*_msi_irqs() hackery in order to store the irq + * domain pointer in struct device. This irq domain wrappery allows to do + * that without breaking XEN terminally. + */ +static __init struct irq_domain *xen_create_pci_msi_domain(void) +{ + struct irq_domain *d = NULL; + struct fwnode_handle *fn; + + fn = irq_domain_alloc_named_fwnode("XEN-MSI"); + if (fn) + d = msi_create_irq_domain(fn, &xen_pci_msi_domain_info, NULL); + + /* FIXME: No idea how to survive if this fails */ + BUG_ON(!d); + + return d; +} + +static __init void xen_setup_pci_msi(void) +{ + if (xen_pv_domain()) { + if (xen_initial_domain()) { + xen_msi_ops.setup_msi_irqs = xen_initdom_setup_msi_irqs; + x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs; + } else { + xen_msi_ops.setup_msi_irqs = xen_setup_msi_irqs; + } + xen_msi_ops.teardown_msi_irqs = xen_pv_teardown_msi_irqs; + pci_msi_ignore_mask = 1; + } else if (xen_hvm_domain()) { + xen_msi_ops.setup_msi_irqs = xen_hvm_setup_msi_irqs; + xen_msi_ops.teardown_msi_irqs = xen_teardown_msi_irqs; + } else { + WARN_ON_ONCE(1); + return; + } + + /* + * Override the PCI/MSI irq domain init function. No point + * in allocating the native domain and never use it. + */ + x86_init.irqs.create_pci_msi_domain = xen_create_pci_msi_domain; +} + +#else /* CONFIG_PCI_MSI */ +static inline void xen_setup_pci_msi(void) { } +#endif /* CONFIG_PCI_MSI */ int __init pci_xen_init(void) { @@ -410,17 +511,12 @@ int __init pci_xen_init(void) /* Keep ACPI out of the picture */ acpi_noirq_set(); -#ifdef CONFIG_PCI_MSI - x86_msi.setup_msi_irqs = xen_setup_msi_irqs; - x86_msi.teardown_msi_irq = xen_teardown_msi_irq; - x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs; - pci_msi_ignore_mask = 1; -#endif + xen_setup_pci_msi(); return 0; } #ifdef CONFIG_PCI_MSI -void __init xen_msi_init(void) +static void __init xen_hvm_msi_init(void) { if (!disable_apic) { /* @@ -435,9 +531,7 @@ void __init xen_msi_init(void) ((eax & XEN_HVM_CPUID_APIC_ACCESS_VIRT) && boot_cpu_has(X86_FEATURE_APIC))) return; } - - x86_msi.setup_msi_irqs = xen_hvm_setup_msi_irqs; - x86_msi.teardown_msi_irq = xen_teardown_msi_irq; + xen_setup_pci_msi(); } #endif @@ -460,7 +554,7 @@ int __init pci_xen_hvm_init(void) * We need to wait until after x2apic is initialized * before we can set MSI IRQ ops. */ - x86_platform.apic_post_init = xen_msi_init; + x86_platform.apic_post_init = xen_hvm_msi_init; #endif return 0; } @@ -470,12 +564,7 @@ int __init pci_xen_initial_domain(void) { int irq; -#ifdef CONFIG_PCI_MSI - x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs; - x86_msi.teardown_msi_irq = xen_teardown_msi_irq; - x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs; - pci_msi_ignore_mask = 1; -#endif + xen_setup_pci_msi(); __acpi_register_gsi = acpi_register_gsi_xen; __acpi_unregister_gsi = NULL; /* diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index d37ebe6e70d7..8a26e705cb06 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -90,6 +90,9 @@ static const unsigned long * const efi_tables[] = { &efi.tpm_log, &efi.tpm_final_log, &efi_rng_seed, +#ifdef CONFIG_LOAD_UEFI_KEYS + &efi.mokvar_table, +#endif }; u64 efi_setup; /* efi setup_data physical address */ diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 6af4da1149ba..8f5759df7776 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -47,6 +47,7 @@ #include <asm/realmode.h> #include <asm/time.h> #include <asm/pgalloc.h> +#include <asm/sev-es.h> /* * We allocate runtime services regions top-down, starting from -4G, i.e. @@ -230,6 +231,15 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) } /* + * When SEV-ES is active, the GHCB as set by the kernel will be used + * by firmware. Create a 1:1 unencrypted mapping for each GHCB. + */ + if (sev_es_efi_map_ghcbs(pgd)) { + pr_err("Failed to create 1:1 mapping for the GHCBs!\n"); + return 1; + } + + /* * When making calls to the firmware everything needs to be 1:1 * mapped and addressable with 32-bit pointers. Map the kernel * text and allocate a new stack because we can't rely on the diff --git a/arch/x86/platform/pvh/enlighten.c b/arch/x86/platform/pvh/enlighten.c index c0a502f7e3a7..9ac7457f52a3 100644 --- a/arch/x86/platform/pvh/enlighten.c +++ b/arch/x86/platform/pvh/enlighten.c @@ -19,8 +19,8 @@ * pvh_bootparams and pvh_start_info need to live in the data segment since * they are used after startup_{32|64}, which clear .bss, are invoked. */ -struct boot_params pvh_bootparams __attribute__((section(".data"))); -struct hvm_start_info pvh_start_info __attribute__((section(".data"))); +struct boot_params pvh_bootparams __section(".data"); +struct hvm_start_info pvh_start_info __section(".data"); unsigned int pvh_start_info_sz = sizeof(pvh_start_info); diff --git a/arch/x86/platform/uv/Makefile b/arch/x86/platform/uv/Makefile index a3693c829e2e..224ff0504890 100644 --- a/arch/x86/platform/uv/Makefile +++ b/arch/x86/platform/uv/Makefile @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_X86_UV) += tlb_uv.o bios_uv.o uv_irq.o uv_sysfs.o uv_time.o uv_nmi.o +obj-$(CONFIG_X86_UV) += bios_uv.o uv_irq.o uv_sysfs.o uv_time.o uv_nmi.o diff --git a/arch/x86/platform/uv/bios_uv.c b/arch/x86/platform/uv/bios_uv.c index a2f447dffea6..54511eaccf4d 100644 --- a/arch/x86/platform/uv/bios_uv.c +++ b/arch/x86/platform/uv/bios_uv.c @@ -2,8 +2,9 @@ /* * BIOS run time interface routines. * - * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved. - * Copyright (c) Russ Anderson <rja@sgi.com> + * (C) Copyright 2020 Hewlett Packard Enterprise Development LP + * Copyright (C) 2007-2017 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) Russ Anderson <rja@sgi.com> */ #include <linux/efi.h> @@ -170,16 +171,27 @@ int uv_bios_set_legacy_vga_target(bool decode, int domain, int bus) (u64)decode, (u64)domain, (u64)bus, 0, 0); } -int uv_bios_init(void) +unsigned long get_uv_systab_phys(bool msg) { - uv_systab = NULL; if ((uv_systab_phys == EFI_INVALID_TABLE_ADDR) || !uv_systab_phys || efi_runtime_disabled()) { - pr_crit("UV: UVsystab: missing\n"); - return -EEXIST; + if (msg) + pr_crit("UV: UVsystab: missing\n"); + return 0; } + return uv_systab_phys; +} + +int uv_bios_init(void) +{ + unsigned long uv_systab_phys_addr; + + uv_systab = NULL; + uv_systab_phys_addr = get_uv_systab_phys(1); + if (!uv_systab_phys_addr) + return -EEXIST; - uv_systab = ioremap(uv_systab_phys, sizeof(struct uv_systab)); + uv_systab = ioremap(uv_systab_phys_addr, sizeof(struct uv_systab)); if (!uv_systab || strncmp(uv_systab->signature, UV_SYSTAB_SIG, 4)) { pr_err("UV: UVsystab: bad signature!\n"); iounmap(uv_systab); @@ -191,7 +203,7 @@ int uv_bios_init(void) int size = uv_systab->size; iounmap(uv_systab); - uv_systab = ioremap(uv_systab_phys, size); + uv_systab = ioremap(uv_systab_phys_addr, size); if (!uv_systab) { pr_err("UV: UVsystab: ioremap(%d) failed!\n", size); return -EFAULT; diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c deleted file mode 100644 index 62ea907668f8..000000000000 --- a/arch/x86/platform/uv/tlb_uv.c +++ /dev/null @@ -1,2097 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SGI UltraViolet TLB flush routines. - * - * (c) 2008-2014 Cliff Wickman <cpw@sgi.com>, SGI. - */ -#include <linux/seq_file.h> -#include <linux/proc_fs.h> -#include <linux/debugfs.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/delay.h> - -#include <asm/mmu_context.h> -#include <asm/uv/uv.h> -#include <asm/uv/uv_mmrs.h> -#include <asm/uv/uv_hub.h> -#include <asm/uv/uv_bau.h> -#include <asm/apic.h> -#include <asm/tsc.h> -#include <asm/irq_vectors.h> -#include <asm/timer.h> - -static struct bau_operations ops __ro_after_init; - -static int timeout_us; -static bool nobau = true; -static int nobau_perm; - -/* tunables: */ -static int max_concurr = MAX_BAU_CONCURRENT; -static int max_concurr_const = MAX_BAU_CONCURRENT; -static int plugged_delay = PLUGGED_DELAY; -static int plugsb4reset = PLUGSB4RESET; -static int giveup_limit = GIVEUP_LIMIT; -static int timeoutsb4reset = TIMEOUTSB4RESET; -static int ipi_reset_limit = IPI_RESET_LIMIT; -static int complete_threshold = COMPLETE_THRESHOLD; -static int congested_respns_us = CONGESTED_RESPONSE_US; -static int congested_reps = CONGESTED_REPS; -static int disabled_period = DISABLED_PERIOD; - -static struct tunables tunables[] = { - {&max_concurr, MAX_BAU_CONCURRENT}, /* must be [0] */ - {&plugged_delay, PLUGGED_DELAY}, - {&plugsb4reset, PLUGSB4RESET}, - {&timeoutsb4reset, TIMEOUTSB4RESET}, - {&ipi_reset_limit, IPI_RESET_LIMIT}, - {&complete_threshold, COMPLETE_THRESHOLD}, - {&congested_respns_us, CONGESTED_RESPONSE_US}, - {&congested_reps, CONGESTED_REPS}, - {&disabled_period, DISABLED_PERIOD}, - {&giveup_limit, GIVEUP_LIMIT} -}; - -static struct dentry *tunables_dir; - -/* these correspond to the statistics printed by ptc_seq_show() */ -static char *stat_description[] = { - "sent: number of shootdown messages sent", - "stime: time spent sending messages", - "numuvhubs: number of hubs targeted with shootdown", - "numuvhubs16: number times 16 or more hubs targeted", - "numuvhubs8: number times 8 or more hubs targeted", - "numuvhubs4: number times 4 or more hubs targeted", - "numuvhubs2: number times 2 or more hubs targeted", - "numuvhubs1: number times 1 hub targeted", - "numcpus: number of cpus targeted with shootdown", - "dto: number of destination timeouts", - "retries: destination timeout retries sent", - "rok: : destination timeouts successfully retried", - "resetp: ipi-style resource resets for plugs", - "resett: ipi-style resource resets for timeouts", - "giveup: fall-backs to ipi-style shootdowns", - "sto: number of source timeouts", - "bz: number of stay-busy's", - "throt: number times spun in throttle", - "swack: image of UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE", - "recv: shootdown messages received", - "rtime: time spent processing messages", - "all: shootdown all-tlb messages", - "one: shootdown one-tlb messages", - "mult: interrupts that found multiple messages", - "none: interrupts that found no messages", - "retry: number of retry messages processed", - "canc: number messages canceled by retries", - "nocan: number retries that found nothing to cancel", - "reset: number of ipi-style reset requests processed", - "rcan: number messages canceled by reset requests", - "disable: number times use of the BAU was disabled", - "enable: number times use of the BAU was re-enabled" -}; - -static int __init setup_bau(char *arg) -{ - int result; - - if (!arg) - return -EINVAL; - - result = strtobool(arg, &nobau); - if (result) - return result; - - /* we need to flip the logic here, so that bau=y sets nobau to false */ - nobau = !nobau; - - if (!nobau) - pr_info("UV BAU Enabled\n"); - else - pr_info("UV BAU Disabled\n"); - - return 0; -} -early_param("bau", setup_bau); - -/* base pnode in this partition */ -static int uv_base_pnode __read_mostly; - -static DEFINE_PER_CPU(struct ptc_stats, ptcstats); -static DEFINE_PER_CPU(struct bau_control, bau_control); -static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask); - -static void -set_bau_on(void) -{ - int cpu; - struct bau_control *bcp; - - if (nobau_perm) { - pr_info("BAU not initialized; cannot be turned on\n"); - return; - } - nobau = false; - for_each_present_cpu(cpu) { - bcp = &per_cpu(bau_control, cpu); - bcp->nobau = false; - } - pr_info("BAU turned on\n"); - return; -} - -static void -set_bau_off(void) -{ - int cpu; - struct bau_control *bcp; - - nobau = true; - for_each_present_cpu(cpu) { - bcp = &per_cpu(bau_control, cpu); - bcp->nobau = true; - } - pr_info("BAU turned off\n"); - return; -} - -/* - * Determine the first node on a uvhub. 'Nodes' are used for kernel - * memory allocation. - */ -static int __init uvhub_to_first_node(int uvhub) -{ - int node, b; - - for_each_online_node(node) { - b = uv_node_to_blade_id(node); - if (uvhub == b) - return node; - } - return -1; -} - -/* - * Determine the apicid of the first cpu on a uvhub. - */ -static int __init uvhub_to_first_apicid(int uvhub) -{ - int cpu; - - for_each_present_cpu(cpu) - if (uvhub == uv_cpu_to_blade_id(cpu)) - return per_cpu(x86_cpu_to_apicid, cpu); - return -1; -} - -/* - * Free a software acknowledge hardware resource by clearing its Pending - * bit. This will return a reply to the sender. - * If the message has timed out, a reply has already been sent by the - * hardware but the resource has not been released. In that case our - * clear of the Timeout bit (as well) will free the resource. No reply will - * be sent (the hardware will only do one reply per message). - */ -static void reply_to_message(struct msg_desc *mdp, struct bau_control *bcp, - int do_acknowledge) -{ - unsigned long dw; - struct bau_pq_entry *msg; - - msg = mdp->msg; - if (!msg->canceled && do_acknowledge) { - dw = (msg->swack_vec << UV_SW_ACK_NPENDING) | msg->swack_vec; - ops.write_l_sw_ack(dw); - } - msg->replied_to = 1; - msg->swack_vec = 0; -} - -/* - * Process the receipt of a RETRY message - */ -static void bau_process_retry_msg(struct msg_desc *mdp, - struct bau_control *bcp) -{ - int i; - int cancel_count = 0; - unsigned long msg_res; - unsigned long mmr = 0; - struct bau_pq_entry *msg = mdp->msg; - struct bau_pq_entry *msg2; - struct ptc_stats *stat = bcp->statp; - - stat->d_retries++; - /* - * cancel any message from msg+1 to the retry itself - */ - for (msg2 = msg+1, i = 0; i < DEST_Q_SIZE; msg2++, i++) { - if (msg2 > mdp->queue_last) - msg2 = mdp->queue_first; - if (msg2 == msg) - break; - - /* same conditions for cancellation as do_reset */ - if ((msg2->replied_to == 0) && (msg2->canceled == 0) && - (msg2->swack_vec) && ((msg2->swack_vec & - msg->swack_vec) == 0) && - (msg2->sending_cpu == msg->sending_cpu) && - (msg2->msg_type != MSG_NOOP)) { - mmr = ops.read_l_sw_ack(); - msg_res = msg2->swack_vec; - /* - * This is a message retry; clear the resources held - * by the previous message only if they timed out. - * If it has not timed out we have an unexpected - * situation to report. - */ - if (mmr & (msg_res << UV_SW_ACK_NPENDING)) { - unsigned long mr; - /* - * Is the resource timed out? - * Make everyone ignore the cancelled message. - */ - msg2->canceled = 1; - stat->d_canceled++; - cancel_count++; - mr = (msg_res << UV_SW_ACK_NPENDING) | msg_res; - ops.write_l_sw_ack(mr); - } - } - } - if (!cancel_count) - stat->d_nocanceled++; -} - -/* - * Do all the things a cpu should do for a TLB shootdown message. - * Other cpu's may come here at the same time for this message. - */ -static void bau_process_message(struct msg_desc *mdp, struct bau_control *bcp, - int do_acknowledge) -{ - short socket_ack_count = 0; - short *sp; - struct atomic_short *asp; - struct ptc_stats *stat = bcp->statp; - struct bau_pq_entry *msg = mdp->msg; - struct bau_control *smaster = bcp->socket_master; - - /* - * This must be a normal message, or retry of a normal message - */ - if (msg->address == TLB_FLUSH_ALL) { - flush_tlb_local(); - stat->d_alltlb++; - } else { - flush_tlb_one_user(msg->address); - stat->d_onetlb++; - } - stat->d_requestee++; - - /* - * One cpu on each uvhub has the additional job on a RETRY - * of releasing the resource held by the message that is - * being retried. That message is identified by sending - * cpu number. - */ - if (msg->msg_type == MSG_RETRY && bcp == bcp->uvhub_master) - bau_process_retry_msg(mdp, bcp); - - /* - * This is a swack message, so we have to reply to it. - * Count each responding cpu on the socket. This avoids - * pinging the count's cache line back and forth between - * the sockets. - */ - sp = &smaster->socket_acknowledge_count[mdp->msg_slot]; - asp = (struct atomic_short *)sp; - socket_ack_count = atom_asr(1, asp); - if (socket_ack_count == bcp->cpus_in_socket) { - int msg_ack_count; - /* - * Both sockets dump their completed count total into - * the message's count. - */ - *sp = 0; - asp = (struct atomic_short *)&msg->acknowledge_count; - msg_ack_count = atom_asr(socket_ack_count, asp); - - if (msg_ack_count == bcp->cpus_in_uvhub) { - /* - * All cpus in uvhub saw it; reply - * (unless we are in the UV2 workaround) - */ - reply_to_message(mdp, bcp, do_acknowledge); - } - } - - return; -} - -/* - * Determine the first cpu on a pnode. - */ -static int pnode_to_first_cpu(int pnode, struct bau_control *smaster) -{ - int cpu; - struct hub_and_pnode *hpp; - - for_each_present_cpu(cpu) { - hpp = &smaster->thp[cpu]; - if (pnode == hpp->pnode) - return cpu; - } - return -1; -} - -/* - * Last resort when we get a large number of destination timeouts is - * to clear resources held by a given cpu. - * Do this with IPI so that all messages in the BAU message queue - * can be identified by their nonzero swack_vec field. - * - * This is entered for a single cpu on the uvhub. - * The sender want's this uvhub to free a specific message's - * swack resources. - */ -static void do_reset(void *ptr) -{ - int i; - struct bau_control *bcp = &per_cpu(bau_control, smp_processor_id()); - struct reset_args *rap = (struct reset_args *)ptr; - struct bau_pq_entry *msg; - struct ptc_stats *stat = bcp->statp; - - stat->d_resets++; - /* - * We're looking for the given sender, and - * will free its swack resource. - * If all cpu's finally responded after the timeout, its - * message 'replied_to' was set. - */ - for (msg = bcp->queue_first, i = 0; i < DEST_Q_SIZE; msg++, i++) { - unsigned long msg_res; - /* do_reset: same conditions for cancellation as - bau_process_retry_msg() */ - if ((msg->replied_to == 0) && - (msg->canceled == 0) && - (msg->sending_cpu == rap->sender) && - (msg->swack_vec) && - (msg->msg_type != MSG_NOOP)) { - unsigned long mmr; - unsigned long mr; - /* - * make everyone else ignore this message - */ - msg->canceled = 1; - /* - * only reset the resource if it is still pending - */ - mmr = ops.read_l_sw_ack(); - msg_res = msg->swack_vec; - mr = (msg_res << UV_SW_ACK_NPENDING) | msg_res; - if (mmr & msg_res) { - stat->d_rcanceled++; - ops.write_l_sw_ack(mr); - } - } - } - return; -} - -/* - * Use IPI to get all target uvhubs to release resources held by - * a given sending cpu number. - */ -static void reset_with_ipi(struct pnmask *distribution, struct bau_control *bcp) -{ - int pnode; - int apnode; - int maskbits; - int sender = bcp->cpu; - cpumask_t *mask = bcp->uvhub_master->cpumask; - struct bau_control *smaster = bcp->socket_master; - struct reset_args reset_args; - - reset_args.sender = sender; - cpumask_clear(mask); - /* find a single cpu for each uvhub in this distribution mask */ - maskbits = sizeof(struct pnmask) * BITSPERBYTE; - /* each bit is a pnode relative to the partition base pnode */ - for (pnode = 0; pnode < maskbits; pnode++) { - int cpu; - if (!bau_uvhub_isset(pnode, distribution)) - continue; - apnode = pnode + bcp->partition_base_pnode; - cpu = pnode_to_first_cpu(apnode, smaster); - cpumask_set_cpu(cpu, mask); - } - - /* IPI all cpus; preemption is already disabled */ - smp_call_function_many(mask, do_reset, (void *)&reset_args, 1); - return; -} - -/* - * Not to be confused with cycles_2_ns() from tsc.c; this gives a relative - * number, not an absolute. It converts a duration in cycles to a duration in - * ns. - */ -static inline unsigned long long cycles_2_ns(unsigned long long cyc) -{ - struct cyc2ns_data data; - unsigned long long ns; - - cyc2ns_read_begin(&data); - ns = mul_u64_u32_shr(cyc, data.cyc2ns_mul, data.cyc2ns_shift); - cyc2ns_read_end(); - - return ns; -} - -/* - * The reverse of the above; converts a duration in ns to a duration in cycles. - */ -static inline unsigned long long ns_2_cycles(unsigned long long ns) -{ - struct cyc2ns_data data; - unsigned long long cyc; - - cyc2ns_read_begin(&data); - cyc = (ns << data.cyc2ns_shift) / data.cyc2ns_mul; - cyc2ns_read_end(); - - return cyc; -} - -static inline unsigned long cycles_2_us(unsigned long long cyc) -{ - return cycles_2_ns(cyc) / NSEC_PER_USEC; -} - -static inline cycles_t sec_2_cycles(unsigned long sec) -{ - return ns_2_cycles(sec * NSEC_PER_SEC); -} - -static inline unsigned long long usec_2_cycles(unsigned long usec) -{ - return ns_2_cycles(usec * NSEC_PER_USEC); -} - -/* - * wait for all cpus on this hub to finish their sends and go quiet - * leaves uvhub_quiesce set so that no new broadcasts are started by - * bau_flush_send_and_wait() - */ -static inline void quiesce_local_uvhub(struct bau_control *hmaster) -{ - atom_asr(1, (struct atomic_short *)&hmaster->uvhub_quiesce); -} - -/* - * mark this quiet-requestor as done - */ -static inline void end_uvhub_quiesce(struct bau_control *hmaster) -{ - atom_asr(-1, (struct atomic_short *)&hmaster->uvhub_quiesce); -} - -/* - * UV2 could have an extra bit of status in the ACTIVATION_STATUS_2 register. - * But not currently used. - */ -static unsigned long uv2_3_read_status(unsigned long offset, int rshft, int desc) -{ - return ((read_lmmr(offset) >> rshft) & UV_ACT_STATUS_MASK) << 1; -} - -/* - * Entered when a bau descriptor has gone into a permanent busy wait because - * of a hardware bug. - * Workaround the bug. - */ -static int handle_uv2_busy(struct bau_control *bcp) -{ - struct ptc_stats *stat = bcp->statp; - - stat->s_uv2_wars++; - bcp->busy = 1; - return FLUSH_GIVEUP; -} - -static int uv2_3_wait_completion(struct bau_desc *bau_desc, - struct bau_control *bcp, long try) -{ - unsigned long descriptor_stat; - cycles_t ttm; - u64 mmr_offset = bcp->status_mmr; - int right_shift = bcp->status_index; - int desc = bcp->uvhub_cpu; - long busy_reps = 0; - struct ptc_stats *stat = bcp->statp; - - descriptor_stat = uv2_3_read_status(mmr_offset, right_shift, desc); - - /* spin on the status MMR, waiting for it to go idle */ - while (descriptor_stat != UV2H_DESC_IDLE) { - if (descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT) { - /* - * A h/w bug on the destination side may - * have prevented the message being marked - * pending, thus it doesn't get replied to - * and gets continually nacked until it times - * out with a SOURCE_TIMEOUT. - */ - stat->s_stimeout++; - return FLUSH_GIVEUP; - } else if (descriptor_stat == UV2H_DESC_DEST_TIMEOUT) { - ttm = get_cycles(); - - /* - * Our retries may be blocked by all destination - * swack resources being consumed, and a timeout - * pending. In that case hardware returns the - * ERROR that looks like a destination timeout. - * Without using the extended status we have to - * deduce from the short time that this was a - * strong nack. - */ - if (cycles_2_us(ttm - bcp->send_message) < timeout_us) { - bcp->conseccompletes = 0; - stat->s_plugged++; - /* FLUSH_RETRY_PLUGGED causes hang on boot */ - return FLUSH_GIVEUP; - } - stat->s_dtimeout++; - bcp->conseccompletes = 0; - /* FLUSH_RETRY_TIMEOUT causes hang on boot */ - return FLUSH_GIVEUP; - } else { - busy_reps++; - if (busy_reps > 1000000) { - /* not to hammer on the clock */ - busy_reps = 0; - ttm = get_cycles(); - if ((ttm - bcp->send_message) > bcp->timeout_interval) - return handle_uv2_busy(bcp); - } - /* - * descriptor_stat is still BUSY - */ - cpu_relax(); - } - descriptor_stat = uv2_3_read_status(mmr_offset, right_shift, desc); - } - bcp->conseccompletes++; - return FLUSH_COMPLETE; -} - -/* - * Returns the status of current BAU message for cpu desc as a bit field - * [Error][Busy][Aux] - */ -static u64 read_status(u64 status_mmr, int index, int desc) -{ - u64 stat; - - stat = ((read_lmmr(status_mmr) >> index) & UV_ACT_STATUS_MASK) << 1; - stat |= (read_lmmr(UVH_LB_BAU_SB_ACTIVATION_STATUS_2) >> desc) & 0x1; - - return stat; -} - -static int uv4_wait_completion(struct bau_desc *bau_desc, - struct bau_control *bcp, long try) -{ - struct ptc_stats *stat = bcp->statp; - u64 descriptor_stat; - u64 mmr = bcp->status_mmr; - int index = bcp->status_index; - int desc = bcp->uvhub_cpu; - - descriptor_stat = read_status(mmr, index, desc); - - /* spin on the status MMR, waiting for it to go idle */ - while (descriptor_stat != UV2H_DESC_IDLE) { - switch (descriptor_stat) { - case UV2H_DESC_SOURCE_TIMEOUT: - stat->s_stimeout++; - return FLUSH_GIVEUP; - - case UV2H_DESC_DEST_TIMEOUT: - stat->s_dtimeout++; - bcp->conseccompletes = 0; - return FLUSH_RETRY_TIMEOUT; - - case UV2H_DESC_DEST_STRONG_NACK: - stat->s_plugged++; - bcp->conseccompletes = 0; - return FLUSH_RETRY_PLUGGED; - - case UV2H_DESC_DEST_PUT_ERR: - bcp->conseccompletes = 0; - return FLUSH_GIVEUP; - - default: - /* descriptor_stat is still BUSY */ - cpu_relax(); - } - descriptor_stat = read_status(mmr, index, desc); - } - bcp->conseccompletes++; - return FLUSH_COMPLETE; -} - -/* - * Our retries are blocked by all destination sw ack resources being - * in use, and a timeout is pending. In that case hardware immediately - * returns the ERROR that looks like a destination timeout. - */ -static void destination_plugged(struct bau_desc *bau_desc, - struct bau_control *bcp, - struct bau_control *hmaster, struct ptc_stats *stat) -{ - udelay(bcp->plugged_delay); - bcp->plugged_tries++; - - if (bcp->plugged_tries >= bcp->plugsb4reset) { - bcp->plugged_tries = 0; - - quiesce_local_uvhub(hmaster); - - spin_lock(&hmaster->queue_lock); - reset_with_ipi(&bau_desc->distribution, bcp); - spin_unlock(&hmaster->queue_lock); - - end_uvhub_quiesce(hmaster); - - bcp->ipi_attempts++; - stat->s_resets_plug++; - } -} - -static void destination_timeout(struct bau_desc *bau_desc, - struct bau_control *bcp, struct bau_control *hmaster, - struct ptc_stats *stat) -{ - hmaster->max_concurr = 1; - bcp->timeout_tries++; - if (bcp->timeout_tries >= bcp->timeoutsb4reset) { - bcp->timeout_tries = 0; - - quiesce_local_uvhub(hmaster); - - spin_lock(&hmaster->queue_lock); - reset_with_ipi(&bau_desc->distribution, bcp); - spin_unlock(&hmaster->queue_lock); - - end_uvhub_quiesce(hmaster); - - bcp->ipi_attempts++; - stat->s_resets_timeout++; - } -} - -/* - * Stop all cpus on a uvhub from using the BAU for a period of time. - * This is reversed by check_enable. - */ -static void disable_for_period(struct bau_control *bcp, struct ptc_stats *stat) -{ - int tcpu; - struct bau_control *tbcp; - struct bau_control *hmaster; - cycles_t tm1; - - hmaster = bcp->uvhub_master; - spin_lock(&hmaster->disable_lock); - if (!bcp->baudisabled) { - stat->s_bau_disabled++; - tm1 = get_cycles(); - for_each_present_cpu(tcpu) { - tbcp = &per_cpu(bau_control, tcpu); - if (tbcp->uvhub_master == hmaster) { - tbcp->baudisabled = 1; - tbcp->set_bau_on_time = - tm1 + bcp->disabled_period; - } - } - } - spin_unlock(&hmaster->disable_lock); -} - -static void count_max_concurr(int stat, struct bau_control *bcp, - struct bau_control *hmaster) -{ - bcp->plugged_tries = 0; - bcp->timeout_tries = 0; - if (stat != FLUSH_COMPLETE) - return; - if (bcp->conseccompletes <= bcp->complete_threshold) - return; - if (hmaster->max_concurr >= hmaster->max_concurr_const) - return; - hmaster->max_concurr++; -} - -static void record_send_stats(cycles_t time1, cycles_t time2, - struct bau_control *bcp, struct ptc_stats *stat, - int completion_status, int try) -{ - cycles_t elapsed; - - if (time2 > time1) { - elapsed = time2 - time1; - stat->s_time += elapsed; - - if ((completion_status == FLUSH_COMPLETE) && (try == 1)) { - bcp->period_requests++; - bcp->period_time += elapsed; - if ((elapsed > usec_2_cycles(bcp->cong_response_us)) && - (bcp->period_requests > bcp->cong_reps) && - ((bcp->period_time / bcp->period_requests) > - usec_2_cycles(bcp->cong_response_us))) { - stat->s_congested++; - disable_for_period(bcp, stat); - } - } - } else - stat->s_requestor--; - - if (completion_status == FLUSH_COMPLETE && try > 1) - stat->s_retriesok++; - else if (completion_status == FLUSH_GIVEUP) { - stat->s_giveup++; - if (get_cycles() > bcp->period_end) - bcp->period_giveups = 0; - bcp->period_giveups++; - if (bcp->period_giveups == 1) - bcp->period_end = get_cycles() + bcp->disabled_period; - if (bcp->period_giveups > bcp->giveup_limit) { - disable_for_period(bcp, stat); - stat->s_giveuplimit++; - } - } -} - -/* - * Handle the completion status of a message send. - */ -static void handle_cmplt(int completion_status, struct bau_desc *bau_desc, - struct bau_control *bcp, struct bau_control *hmaster, - struct ptc_stats *stat) -{ - if (completion_status == FLUSH_RETRY_PLUGGED) - destination_plugged(bau_desc, bcp, hmaster, stat); - else if (completion_status == FLUSH_RETRY_TIMEOUT) - destination_timeout(bau_desc, bcp, hmaster, stat); -} - -/* - * Send a broadcast and wait for it to complete. - * - * The flush_mask contains the cpus the broadcast is to be sent to including - * cpus that are on the local uvhub. - * - * Returns 0 if all flushing represented in the mask was done. - * Returns 1 if it gives up entirely and the original cpu mask is to be - * returned to the kernel. - */ -static int uv_flush_send_and_wait(struct cpumask *flush_mask, - struct bau_control *bcp, - struct bau_desc *bau_desc) -{ - int seq_number = 0; - int completion_stat = 0; - long try = 0; - unsigned long index; - cycles_t time1; - cycles_t time2; - struct ptc_stats *stat = bcp->statp; - struct bau_control *hmaster = bcp->uvhub_master; - struct uv2_3_bau_msg_header *uv2_3_hdr = NULL; - - while (hmaster->uvhub_quiesce) - cpu_relax(); - - time1 = get_cycles(); - uv2_3_hdr = &bau_desc->header.uv2_3_hdr; - - do { - if (try == 0) { - uv2_3_hdr->msg_type = MSG_REGULAR; - seq_number = bcp->message_number++; - } else { - uv2_3_hdr->msg_type = MSG_RETRY; - stat->s_retry_messages++; - } - - uv2_3_hdr->sequence = seq_number; - index = (1UL << AS_PUSH_SHIFT) | bcp->uvhub_cpu; - bcp->send_message = get_cycles(); - - write_mmr_activation(index); - - try++; - completion_stat = ops.wait_completion(bau_desc, bcp, try); - - handle_cmplt(completion_stat, bau_desc, bcp, hmaster, stat); - - if (bcp->ipi_attempts >= bcp->ipi_reset_limit) { - bcp->ipi_attempts = 0; - stat->s_overipilimit++; - completion_stat = FLUSH_GIVEUP; - break; - } - cpu_relax(); - } while ((completion_stat == FLUSH_RETRY_PLUGGED) || - (completion_stat == FLUSH_RETRY_TIMEOUT)); - - time2 = get_cycles(); - - count_max_concurr(completion_stat, bcp, hmaster); - - while (hmaster->uvhub_quiesce) - cpu_relax(); - - atomic_dec(&hmaster->active_descriptor_count); - - record_send_stats(time1, time2, bcp, stat, completion_stat, try); - - if (completion_stat == FLUSH_GIVEUP) - /* FLUSH_GIVEUP will fall back to using IPI's for tlb flush */ - return 1; - return 0; -} - -/* - * The BAU is disabled for this uvhub. When the disabled time period has - * expired re-enable it. - * Return 0 if it is re-enabled for all cpus on this uvhub. - */ -static int check_enable(struct bau_control *bcp, struct ptc_stats *stat) -{ - int tcpu; - struct bau_control *tbcp; - struct bau_control *hmaster; - - hmaster = bcp->uvhub_master; - spin_lock(&hmaster->disable_lock); - if (bcp->baudisabled && (get_cycles() >= bcp->set_bau_on_time)) { - stat->s_bau_reenabled++; - for_each_present_cpu(tcpu) { - tbcp = &per_cpu(bau_control, tcpu); - if (tbcp->uvhub_master == hmaster) { - tbcp->baudisabled = 0; - tbcp->period_requests = 0; - tbcp->period_time = 0; - tbcp->period_giveups = 0; - } - } - spin_unlock(&hmaster->disable_lock); - return 0; - } - spin_unlock(&hmaster->disable_lock); - return -1; -} - -static void record_send_statistics(struct ptc_stats *stat, int locals, int hubs, - int remotes, struct bau_desc *bau_desc) -{ - stat->s_requestor++; - stat->s_ntargcpu += remotes + locals; - stat->s_ntargremotes += remotes; - stat->s_ntarglocals += locals; - - /* uvhub statistics */ - hubs = bau_uvhub_weight(&bau_desc->distribution); - if (locals) { - stat->s_ntarglocaluvhub++; - stat->s_ntargremoteuvhub += (hubs - 1); - } else - stat->s_ntargremoteuvhub += hubs; - - stat->s_ntarguvhub += hubs; - - if (hubs >= 16) - stat->s_ntarguvhub16++; - else if (hubs >= 8) - stat->s_ntarguvhub8++; - else if (hubs >= 4) - stat->s_ntarguvhub4++; - else if (hubs >= 2) - stat->s_ntarguvhub2++; - else - stat->s_ntarguvhub1++; -} - -/* - * Translate a cpu mask to the uvhub distribution mask in the BAU - * activation descriptor. - */ -static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp, - struct bau_desc *bau_desc, int *localsp, int *remotesp) -{ - int cpu; - int pnode; - int cnt = 0; - struct hub_and_pnode *hpp; - - for_each_cpu(cpu, flush_mask) { - /* - * The distribution vector is a bit map of pnodes, relative - * to the partition base pnode (and the partition base nasid - * in the header). - * Translate cpu to pnode and hub using a local memory array. - */ - hpp = &bcp->socket_master->thp[cpu]; - pnode = hpp->pnode - bcp->partition_base_pnode; - bau_uvhub_set(pnode, &bau_desc->distribution); - cnt++; - if (hpp->uvhub == bcp->uvhub) - (*localsp)++; - else - (*remotesp)++; - } - if (!cnt) - return 1; - return 0; -} - -/* - * globally purge translation cache of a virtual address or all TLB's - * @cpumask: mask of all cpu's in which the address is to be removed - * @mm: mm_struct containing virtual address range - * @start: start virtual address to be removed from TLB - * @end: end virtual address to be remove from TLB - * @cpu: the current cpu - * - * This is the entry point for initiating any UV global TLB shootdown. - * - * Purges the translation caches of all specified processors of the given - * virtual address, or purges all TLB's on specified processors. - * - * The caller has derived the cpumask from the mm_struct. This function - * is called only if there are bits set in the mask. (e.g. flush_tlb_page()) - * - * The cpumask is converted into a uvhubmask of the uvhubs containing - * those cpus. - * - * Note that this function should be called with preemption disabled. - * - * Returns NULL if all remote flushing was done. - * Returns pointer to cpumask if some remote flushing remains to be - * done. The returned pointer is valid till preemption is re-enabled. - */ -const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, - const struct flush_tlb_info *info) -{ - unsigned int cpu = smp_processor_id(); - int locals = 0, remotes = 0, hubs = 0; - struct bau_desc *bau_desc; - struct cpumask *flush_mask; - struct ptc_stats *stat; - struct bau_control *bcp; - unsigned long descriptor_status, status, address; - - bcp = &per_cpu(bau_control, cpu); - - if (bcp->nobau) - return cpumask; - - stat = bcp->statp; - stat->s_enters++; - - if (bcp->busy) { - descriptor_status = - read_lmmr(UVH_LB_BAU_SB_ACTIVATION_STATUS_0); - status = ((descriptor_status >> (bcp->uvhub_cpu * - UV_ACT_STATUS_SIZE)) & UV_ACT_STATUS_MASK) << 1; - if (status == UV2H_DESC_BUSY) - return cpumask; - bcp->busy = 0; - } - - /* bau was disabled due to slow response */ - if (bcp->baudisabled) { - if (check_enable(bcp, stat)) { - stat->s_ipifordisabled++; - return cpumask; - } - } - - /* - * Each sending cpu has a per-cpu mask which it fills from the caller's - * cpu mask. All cpus are converted to uvhubs and copied to the - * activation descriptor. - */ - flush_mask = (struct cpumask *)per_cpu(uv_flush_tlb_mask, cpu); - /* don't actually do a shootdown of the local cpu */ - cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu)); - - if (cpumask_test_cpu(cpu, cpumask)) - stat->s_ntargself++; - - bau_desc = bcp->descriptor_base; - bau_desc += (ITEMS_PER_DESC * bcp->uvhub_cpu); - bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); - if (set_distrib_bits(flush_mask, bcp, bau_desc, &locals, &remotes)) - return NULL; - - record_send_statistics(stat, locals, hubs, remotes, bau_desc); - - if (!info->end || (info->end - info->start) <= PAGE_SIZE) - address = info->start; - else - address = TLB_FLUSH_ALL; - - switch (bcp->uvhub_version) { - case UV_BAU_V2: - case UV_BAU_V3: - bau_desc->payload.uv2_3.address = address; - bau_desc->payload.uv2_3.sending_cpu = cpu; - break; - case UV_BAU_V4: - bau_desc->payload.uv4.address = address; - bau_desc->payload.uv4.sending_cpu = cpu; - bau_desc->payload.uv4.qualifier = BAU_DESC_QUALIFIER; - break; - } - - /* - * uv_flush_send_and_wait returns 0 if all cpu's were messaged, - * or 1 if it gave up and the original cpumask should be returned. - */ - if (!uv_flush_send_and_wait(flush_mask, bcp, bau_desc)) - return NULL; - else - return cpumask; -} - -/* - * Search the message queue for any 'other' unprocessed message with the - * same software acknowledge resource bit vector as the 'msg' message. - */ -static struct bau_pq_entry *find_another_by_swack(struct bau_pq_entry *msg, - struct bau_control *bcp) -{ - struct bau_pq_entry *msg_next = msg + 1; - unsigned char swack_vec = msg->swack_vec; - - if (msg_next > bcp->queue_last) - msg_next = bcp->queue_first; - while (msg_next != msg) { - if ((msg_next->canceled == 0) && (msg_next->replied_to == 0) && - (msg_next->swack_vec == swack_vec)) - return msg_next; - msg_next++; - if (msg_next > bcp->queue_last) - msg_next = bcp->queue_first; - } - return NULL; -} - -/* - * UV2 needs to work around a bug in which an arriving message has not - * set a bit in the UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE register. - * Such a message must be ignored. - */ -static void process_uv2_message(struct msg_desc *mdp, struct bau_control *bcp) -{ - unsigned long mmr_image; - unsigned char swack_vec; - struct bau_pq_entry *msg = mdp->msg; - struct bau_pq_entry *other_msg; - - mmr_image = ops.read_l_sw_ack(); - swack_vec = msg->swack_vec; - - if ((swack_vec & mmr_image) == 0) { - /* - * This message was assigned a swack resource, but no - * reserved acknowlegment is pending. - * The bug has prevented this message from setting the MMR. - */ - /* - * Some message has set the MMR 'pending' bit; it might have - * been another message. Look for that message. - */ - other_msg = find_another_by_swack(msg, bcp); - if (other_msg) { - /* - * There is another. Process this one but do not - * ack it. - */ - bau_process_message(mdp, bcp, 0); - /* - * Let the natural processing of that other message - * acknowledge it. Don't get the processing of sw_ack's - * out of order. - */ - return; - } - } - - /* - * Either the MMR shows this one pending a reply or there is no - * other message using this sw_ack, so it is safe to acknowledge it. - */ - bau_process_message(mdp, bcp, 1); - - return; -} - -/* - * The BAU message interrupt comes here. (registered by set_intr_gate) - * See entry_64.S - * - * We received a broadcast assist message. - * - * Interrupts are disabled; this interrupt could represent - * the receipt of several messages. - * - * All cores/threads on this hub get this interrupt. - * The last one to see it does the software ack. - * (the resource will not be freed until noninterruptable cpus see this - * interrupt; hardware may timeout the s/w ack and reply ERROR) - */ -DEFINE_IDTENTRY_SYSVEC(sysvec_uv_bau_message) -{ - int count = 0; - cycles_t time_start; - struct bau_pq_entry *msg; - struct bau_control *bcp; - struct ptc_stats *stat; - struct msg_desc msgdesc; - - ack_APIC_irq(); - kvm_set_cpu_l1tf_flush_l1d(); - time_start = get_cycles(); - - bcp = &per_cpu(bau_control, smp_processor_id()); - stat = bcp->statp; - - msgdesc.queue_first = bcp->queue_first; - msgdesc.queue_last = bcp->queue_last; - - msg = bcp->bau_msg_head; - while (msg->swack_vec) { - count++; - - msgdesc.msg_slot = msg - msgdesc.queue_first; - msgdesc.msg = msg; - if (bcp->uvhub_version == UV_BAU_V2) - process_uv2_message(&msgdesc, bcp); - else - /* no error workaround for uv3 */ - bau_process_message(&msgdesc, bcp, 1); - - msg++; - if (msg > msgdesc.queue_last) - msg = msgdesc.queue_first; - bcp->bau_msg_head = msg; - } - stat->d_time += (get_cycles() - time_start); - if (!count) - stat->d_nomsg++; - else if (count > 1) - stat->d_multmsg++; -} - -/* - * Each target uvhub (i.e. a uvhub that has cpu's) needs to have - * shootdown message timeouts enabled. The timeout does not cause - * an interrupt, but causes an error message to be returned to - * the sender. - */ -static void __init enable_timeouts(void) -{ - int uvhub; - int nuvhubs; - int pnode; - unsigned long mmr_image; - - nuvhubs = uv_num_possible_blades(); - - for (uvhub = 0; uvhub < nuvhubs; uvhub++) { - if (!uv_blade_nr_possible_cpus(uvhub)) - continue; - - pnode = uv_blade_to_pnode(uvhub); - mmr_image = read_mmr_misc_control(pnode); - /* - * Set the timeout period and then lock it in, in three - * steps; captures and locks in the period. - * - * To program the period, the SOFT_ACK_MODE must be off. - */ - mmr_image &= ~(1L << SOFTACK_MSHIFT); - write_mmr_misc_control(pnode, mmr_image); - /* - * Set the 4-bit period. - */ - mmr_image &= ~((unsigned long)0xf << SOFTACK_PSHIFT); - mmr_image |= (SOFTACK_TIMEOUT_PERIOD << SOFTACK_PSHIFT); - write_mmr_misc_control(pnode, mmr_image); - - mmr_image |= (1L << SOFTACK_MSHIFT); - if (is_uv2_hub()) { - /* do not touch the legacy mode bit */ - /* hw bug workaround; do not use extended status */ - mmr_image &= ~(1L << UV2_EXT_SHFT); - } else if (is_uv3_hub()) { - mmr_image &= ~(1L << PREFETCH_HINT_SHFT); - mmr_image |= (1L << SB_STATUS_SHFT); - } - write_mmr_misc_control(pnode, mmr_image); - } -} - -static void *ptc_seq_start(struct seq_file *file, loff_t *offset) -{ - if (*offset < num_possible_cpus()) - return offset; - return NULL; -} - -static void *ptc_seq_next(struct seq_file *file, void *data, loff_t *offset) -{ - (*offset)++; - if (*offset < num_possible_cpus()) - return offset; - return NULL; -} - -static void ptc_seq_stop(struct seq_file *file, void *data) -{ -} - -/* - * Display the statistics thru /proc/sgi_uv/ptc_statistics - * 'data' points to the cpu number - * Note: see the descriptions in stat_description[]. - */ -static int ptc_seq_show(struct seq_file *file, void *data) -{ - struct ptc_stats *stat; - struct bau_control *bcp; - int cpu; - - cpu = *(loff_t *)data; - if (!cpu) { - seq_puts(file, - "# cpu bauoff sent stime self locals remotes ncpus localhub "); - seq_puts(file, "remotehub numuvhubs numuvhubs16 numuvhubs8 "); - seq_puts(file, - "numuvhubs4 numuvhubs2 numuvhubs1 dto snacks retries "); - seq_puts(file, - "rok resetp resett giveup sto bz throt disable "); - seq_puts(file, - "enable wars warshw warwaits enters ipidis plugged "); - seq_puts(file, - "ipiover glim cong swack recv rtime all one mult "); - seq_puts(file, "none retry canc nocan reset rcan\n"); - } - if (cpu < num_possible_cpus() && cpu_online(cpu)) { - bcp = &per_cpu(bau_control, cpu); - if (bcp->nobau) { - seq_printf(file, "cpu %d bau disabled\n", cpu); - return 0; - } - stat = bcp->statp; - /* source side statistics */ - seq_printf(file, - "cpu %d %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", - cpu, bcp->nobau, stat->s_requestor, - cycles_2_us(stat->s_time), - stat->s_ntargself, stat->s_ntarglocals, - stat->s_ntargremotes, stat->s_ntargcpu, - stat->s_ntarglocaluvhub, stat->s_ntargremoteuvhub, - stat->s_ntarguvhub, stat->s_ntarguvhub16); - seq_printf(file, "%ld %ld %ld %ld %ld %ld ", - stat->s_ntarguvhub8, stat->s_ntarguvhub4, - stat->s_ntarguvhub2, stat->s_ntarguvhub1, - stat->s_dtimeout, stat->s_strongnacks); - seq_printf(file, "%ld %ld %ld %ld %ld %ld %ld %ld ", - stat->s_retry_messages, stat->s_retriesok, - stat->s_resets_plug, stat->s_resets_timeout, - stat->s_giveup, stat->s_stimeout, - stat->s_busy, stat->s_throttles); - seq_printf(file, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", - stat->s_bau_disabled, stat->s_bau_reenabled, - stat->s_uv2_wars, stat->s_uv2_wars_hw, - stat->s_uv2_war_waits, stat->s_enters, - stat->s_ipifordisabled, stat->s_plugged, - stat->s_overipilimit, stat->s_giveuplimit, - stat->s_congested); - - /* destination side statistics */ - seq_printf(file, - "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", - ops.read_g_sw_ack(uv_cpu_to_pnode(cpu)), - stat->d_requestee, cycles_2_us(stat->d_time), - stat->d_alltlb, stat->d_onetlb, stat->d_multmsg, - stat->d_nomsg, stat->d_retries, stat->d_canceled, - stat->d_nocanceled, stat->d_resets, - stat->d_rcanceled); - } - return 0; -} - -/* - * Display the tunables thru debugfs - */ -static ssize_t tunables_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - char *buf; - int ret; - - buf = kasprintf(GFP_KERNEL, "%s %s %s\n%d %d %d %d %d %d %d %d %d %d\n", - "max_concur plugged_delay plugsb4reset timeoutsb4reset", - "ipi_reset_limit complete_threshold congested_response_us", - "congested_reps disabled_period giveup_limit", - max_concurr, plugged_delay, plugsb4reset, - timeoutsb4reset, ipi_reset_limit, complete_threshold, - congested_respns_us, congested_reps, disabled_period, - giveup_limit); - - if (!buf) - return -ENOMEM; - - ret = simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf)); - kfree(buf); - return ret; -} - -/* - * handle a write to /proc/sgi_uv/ptc_statistics - * -1: reset the statistics - * 0: display meaning of the statistics - */ -static ssize_t ptc_proc_write(struct file *file, const char __user *user, - size_t count, loff_t *data) -{ - int cpu; - int i; - int elements; - long input_arg; - char optstr[64]; - struct ptc_stats *stat; - - if (count == 0 || count > sizeof(optstr)) - return -EINVAL; - if (copy_from_user(optstr, user, count)) - return -EFAULT; - optstr[count - 1] = '\0'; - - if (!strcmp(optstr, "on")) { - set_bau_on(); - return count; - } else if (!strcmp(optstr, "off")) { - set_bau_off(); - return count; - } - - if (kstrtol(optstr, 10, &input_arg) < 0) { - pr_debug("%s is invalid\n", optstr); - return -EINVAL; - } - - if (input_arg == 0) { - elements = ARRAY_SIZE(stat_description); - pr_debug("# cpu: cpu number\n"); - pr_debug("Sender statistics:\n"); - for (i = 0; i < elements; i++) - pr_debug("%s\n", stat_description[i]); - } else if (input_arg == -1) { - for_each_present_cpu(cpu) { - stat = &per_cpu(ptcstats, cpu); - memset(stat, 0, sizeof(struct ptc_stats)); - } - } - - return count; -} - -static int local_atoi(const char *name) -{ - int val = 0; - - for (;; name++) { - switch (*name) { - case '0' ... '9': - val = 10*val+(*name-'0'); - break; - default: - return val; - } - } -} - -/* - * Parse the values written to /sys/kernel/debug/sgi_uv/bau_tunables. - * Zero values reset them to defaults. - */ -static int parse_tunables_write(struct bau_control *bcp, char *instr, - int count) -{ - char *p; - char *q; - int cnt = 0; - int val; - int e = ARRAY_SIZE(tunables); - - p = instr + strspn(instr, WHITESPACE); - q = p; - for (; *p; p = q + strspn(q, WHITESPACE)) { - q = p + strcspn(p, WHITESPACE); - cnt++; - if (q == p) - break; - } - if (cnt != e) { - pr_info("bau tunable error: should be %d values\n", e); - return -EINVAL; - } - - p = instr + strspn(instr, WHITESPACE); - q = p; - for (cnt = 0; *p; p = q + strspn(q, WHITESPACE), cnt++) { - q = p + strcspn(p, WHITESPACE); - val = local_atoi(p); - switch (cnt) { - case 0: - if (val == 0) { - max_concurr = MAX_BAU_CONCURRENT; - max_concurr_const = MAX_BAU_CONCURRENT; - continue; - } - if (val < 1 || val > bcp->cpus_in_uvhub) { - pr_debug( - "Error: BAU max concurrent %d is invalid\n", - val); - return -EINVAL; - } - max_concurr = val; - max_concurr_const = val; - continue; - default: - if (val == 0) - *tunables[cnt].tunp = tunables[cnt].deflt; - else - *tunables[cnt].tunp = val; - continue; - } - } - return 0; -} - -/* - * Handle a write to debugfs. (/sys/kernel/debug/sgi_uv/bau_tunables) - */ -static ssize_t tunables_write(struct file *file, const char __user *user, - size_t count, loff_t *data) -{ - int cpu; - int ret; - char instr[100]; - struct bau_control *bcp; - - if (count == 0 || count > sizeof(instr)-1) - return -EINVAL; - if (copy_from_user(instr, user, count)) - return -EFAULT; - - instr[count] = '\0'; - - cpu = get_cpu(); - bcp = &per_cpu(bau_control, cpu); - ret = parse_tunables_write(bcp, instr, count); - put_cpu(); - if (ret) - return ret; - - for_each_present_cpu(cpu) { - bcp = &per_cpu(bau_control, cpu); - bcp->max_concurr = max_concurr; - bcp->max_concurr_const = max_concurr; - bcp->plugged_delay = plugged_delay; - bcp->plugsb4reset = plugsb4reset; - bcp->timeoutsb4reset = timeoutsb4reset; - bcp->ipi_reset_limit = ipi_reset_limit; - bcp->complete_threshold = complete_threshold; - bcp->cong_response_us = congested_respns_us; - bcp->cong_reps = congested_reps; - bcp->disabled_period = sec_2_cycles(disabled_period); - bcp->giveup_limit = giveup_limit; - } - return count; -} - -static const struct seq_operations uv_ptc_seq_ops = { - .start = ptc_seq_start, - .next = ptc_seq_next, - .stop = ptc_seq_stop, - .show = ptc_seq_show -}; - -static int ptc_proc_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &uv_ptc_seq_ops); -} - -static int tunables_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static const struct proc_ops uv_ptc_proc_ops = { - .proc_open = ptc_proc_open, - .proc_read = seq_read, - .proc_write = ptc_proc_write, - .proc_lseek = seq_lseek, - .proc_release = seq_release, -}; - -static const struct file_operations tunables_fops = { - .open = tunables_open, - .read = tunables_read, - .write = tunables_write, - .llseek = default_llseek, -}; - -static int __init uv_ptc_init(void) -{ - struct proc_dir_entry *proc_uv_ptc; - - if (!is_uv_system()) - return 0; - - proc_uv_ptc = proc_create(UV_PTC_BASENAME, 0444, NULL, - &uv_ptc_proc_ops); - if (!proc_uv_ptc) { - pr_err("unable to create %s proc entry\n", - UV_PTC_BASENAME); - return -EINVAL; - } - - tunables_dir = debugfs_create_dir(UV_BAU_TUNABLES_DIR, NULL); - debugfs_create_file(UV_BAU_TUNABLES_FILE, 0600, tunables_dir, NULL, - &tunables_fops); - return 0; -} - -/* - * Initialize the sending side's sending buffers. - */ -static void activation_descriptor_init(int node, int pnode, int base_pnode) -{ - int i; - int cpu; - unsigned long gpa; - unsigned long m; - unsigned long n; - size_t dsize; - struct bau_desc *bau_desc; - struct bau_desc *bd2; - struct uv2_3_bau_msg_header *uv2_3_hdr; - struct bau_control *bcp; - - /* - * each bau_desc is 64 bytes; there are 8 (ITEMS_PER_DESC) - * per cpu; and one per cpu on the uvhub (ADP_SZ) - */ - dsize = sizeof(struct bau_desc) * ADP_SZ * ITEMS_PER_DESC; - bau_desc = kmalloc_node(dsize, GFP_KERNEL, node); - BUG_ON(!bau_desc); - - gpa = uv_gpa(bau_desc); - n = uv_gpa_to_gnode(gpa); - m = ops.bau_gpa_to_offset(gpa); - - /* the 14-bit pnode */ - write_mmr_descriptor_base(pnode, - (n << UVH_LB_BAU_SB_DESCRIPTOR_BASE_NODE_ID_SHFT | m)); - /* - * Initializing all 8 (ITEMS_PER_DESC) descriptors for each - * cpu even though we only use the first one; one descriptor can - * describe a broadcast to 256 uv hubs. - */ - for (i = 0, bd2 = bau_desc; i < (ADP_SZ * ITEMS_PER_DESC); i++, bd2++) { - memset(bd2, 0, sizeof(struct bau_desc)); - /* - * BIOS uses legacy mode, but uv2 and uv3 hardware always - * uses native mode for selective broadcasts. - */ - uv2_3_hdr = &bd2->header.uv2_3_hdr; - uv2_3_hdr->swack_flag = 1; - uv2_3_hdr->base_dest_nasid = UV_PNODE_TO_NASID(base_pnode); - uv2_3_hdr->dest_subnodeid = UV_LB_SUBNODEID; - uv2_3_hdr->command = UV_NET_ENDPOINT_INTD; - } - for_each_present_cpu(cpu) { - if (pnode != uv_blade_to_pnode(uv_cpu_to_blade_id(cpu))) - continue; - bcp = &per_cpu(bau_control, cpu); - bcp->descriptor_base = bau_desc; - } -} - -/* - * initialize the destination side's receiving buffers - * entered for each uvhub in the partition - * - node is first node (kernel memory notion) on the uvhub - * - pnode is the uvhub's physical identifier - */ -static void pq_init(int node, int pnode) -{ - int cpu; - size_t plsize; - char *cp; - void *vp; - unsigned long gnode, first, last, tail; - struct bau_pq_entry *pqp; - struct bau_control *bcp; - - plsize = (DEST_Q_SIZE + 1) * sizeof(struct bau_pq_entry); - vp = kmalloc_node(plsize, GFP_KERNEL, node); - BUG_ON(!vp); - - pqp = (struct bau_pq_entry *)vp; - cp = (char *)pqp + 31; - pqp = (struct bau_pq_entry *)(((unsigned long)cp >> 5) << 5); - - for_each_present_cpu(cpu) { - if (pnode != uv_cpu_to_pnode(cpu)) - continue; - /* for every cpu on this pnode: */ - bcp = &per_cpu(bau_control, cpu); - bcp->queue_first = pqp; - bcp->bau_msg_head = pqp; - bcp->queue_last = pqp + (DEST_Q_SIZE - 1); - } - - first = ops.bau_gpa_to_offset(uv_gpa(pqp)); - last = ops.bau_gpa_to_offset(uv_gpa(pqp + (DEST_Q_SIZE - 1))); - - /* - * Pre UV4, the gnode is required to locate the payload queue - * and the payload queue tail must be maintained by the kernel. - */ - bcp = &per_cpu(bau_control, smp_processor_id()); - if (bcp->uvhub_version <= UV_BAU_V3) { - tail = first; - gnode = uv_gpa_to_gnode(uv_gpa(pqp)); - first = (gnode << UV_PAYLOADQ_GNODE_SHIFT) | tail; - write_mmr_payload_tail(pnode, tail); - } - - ops.write_payload_first(pnode, first); - ops.write_payload_last(pnode, last); - - /* in effect, all msg_type's are set to MSG_NOOP */ - memset(pqp, 0, sizeof(struct bau_pq_entry) * DEST_Q_SIZE); -} - -/* - * Initialization of each UV hub's structures - */ -static void __init init_uvhub(int uvhub, int vector, int base_pnode) -{ - int node; - int pnode; - unsigned long apicid; - - node = uvhub_to_first_node(uvhub); - pnode = uv_blade_to_pnode(uvhub); - - activation_descriptor_init(node, pnode, base_pnode); - - pq_init(node, pnode); - /* - * The below initialization can't be in firmware because the - * messaging IRQ will be determined by the OS. - */ - apicid = uvhub_to_first_apicid(uvhub); - write_mmr_data_config(pnode, ((apicid << 32) | vector)); -} - -/* - * We will set BAU_MISC_CONTROL with a timeout period. - * But the BIOS has set UVH_AGING_PRESCALE_SEL and UVH_TRANSACTION_TIMEOUT. - * So the destination timeout period has to be calculated from them. - */ -static int calculate_destination_timeout(void) -{ - unsigned long mmr_image; - int mult1; - int base; - int ret; - - /* same destination timeout for uv2 and uv3 */ - /* 4 bits 0/1 for 10/80us base, 3 bits of multiplier */ - mmr_image = uv_read_local_mmr(UVH_LB_BAU_MISC_CONTROL); - mmr_image = (mmr_image & UV_SA_MASK) >> UV_SA_SHFT; - if (mmr_image & (1L << UV2_ACK_UNITS_SHFT)) - base = 80; - else - base = 10; - mult1 = mmr_image & UV2_ACK_MASK; - ret = mult1 * base; - - return ret; -} - -static void __init init_per_cpu_tunables(void) -{ - int cpu; - struct bau_control *bcp; - - for_each_present_cpu(cpu) { - bcp = &per_cpu(bau_control, cpu); - bcp->baudisabled = 0; - if (nobau) - bcp->nobau = true; - bcp->statp = &per_cpu(ptcstats, cpu); - /* time interval to catch a hardware stay-busy bug */ - bcp->timeout_interval = usec_2_cycles(2*timeout_us); - bcp->max_concurr = max_concurr; - bcp->max_concurr_const = max_concurr; - bcp->plugged_delay = plugged_delay; - bcp->plugsb4reset = plugsb4reset; - bcp->timeoutsb4reset = timeoutsb4reset; - bcp->ipi_reset_limit = ipi_reset_limit; - bcp->complete_threshold = complete_threshold; - bcp->cong_response_us = congested_respns_us; - bcp->cong_reps = congested_reps; - bcp->disabled_period = sec_2_cycles(disabled_period); - bcp->giveup_limit = giveup_limit; - spin_lock_init(&bcp->queue_lock); - spin_lock_init(&bcp->uvhub_lock); - spin_lock_init(&bcp->disable_lock); - } -} - -/* - * Scan all cpus to collect blade and socket summaries. - */ -static int __init get_cpu_topology(int base_pnode, - struct uvhub_desc *uvhub_descs, - unsigned char *uvhub_mask) -{ - int cpu; - int pnode; - int uvhub; - int socket; - struct bau_control *bcp; - struct uvhub_desc *bdp; - struct socket_desc *sdp; - - for_each_present_cpu(cpu) { - bcp = &per_cpu(bau_control, cpu); - - memset(bcp, 0, sizeof(struct bau_control)); - - pnode = uv_cpu_hub_info(cpu)->pnode; - if ((pnode - base_pnode) >= UV_DISTRIBUTION_SIZE) { - pr_emerg( - "cpu %d pnode %d-%d beyond %d; BAU disabled\n", - cpu, pnode, base_pnode, UV_DISTRIBUTION_SIZE); - return 1; - } - - bcp->osnode = cpu_to_node(cpu); - bcp->partition_base_pnode = base_pnode; - - uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; - *(uvhub_mask + (uvhub/8)) |= (1 << (uvhub%8)); - bdp = &uvhub_descs[uvhub]; - - bdp->num_cpus++; - bdp->uvhub = uvhub; - bdp->pnode = pnode; - - /* kludge: 'assuming' one node per socket, and assuming that - disabling a socket just leaves a gap in node numbers */ - socket = bcp->osnode & 1; - bdp->socket_mask |= (1 << socket); - sdp = &bdp->socket[socket]; - sdp->cpu_number[sdp->num_cpus] = cpu; - sdp->num_cpus++; - if (sdp->num_cpus > MAX_CPUS_PER_SOCKET) { - pr_emerg("%d cpus per socket invalid\n", - sdp->num_cpus); - return 1; - } - } - return 0; -} - -/* - * Each socket is to get a local array of pnodes/hubs. - */ -static void make_per_cpu_thp(struct bau_control *smaster) -{ - int cpu; - size_t hpsz = sizeof(struct hub_and_pnode) * num_possible_cpus(); - - smaster->thp = kzalloc_node(hpsz, GFP_KERNEL, smaster->osnode); - for_each_present_cpu(cpu) { - smaster->thp[cpu].pnode = uv_cpu_hub_info(cpu)->pnode; - smaster->thp[cpu].uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; - } -} - -/* - * Each uvhub is to get a local cpumask. - */ -static void make_per_hub_cpumask(struct bau_control *hmaster) -{ - int sz = sizeof(cpumask_t); - - hmaster->cpumask = kzalloc_node(sz, GFP_KERNEL, hmaster->osnode); -} - -/* - * Initialize all the per_cpu information for the cpu's on a given socket, - * given what has been gathered into the socket_desc struct. - * And reports the chosen hub and socket masters back to the caller. - */ -static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp, - struct bau_control **smasterp, - struct bau_control **hmasterp) -{ - int i, cpu, uvhub_cpu; - struct bau_control *bcp; - - for (i = 0; i < sdp->num_cpus; i++) { - cpu = sdp->cpu_number[i]; - bcp = &per_cpu(bau_control, cpu); - bcp->cpu = cpu; - if (i == 0) { - *smasterp = bcp; - if (!(*hmasterp)) - *hmasterp = bcp; - } - bcp->cpus_in_uvhub = bdp->num_cpus; - bcp->cpus_in_socket = sdp->num_cpus; - bcp->socket_master = *smasterp; - bcp->uvhub = bdp->uvhub; - if (is_uv2_hub()) - bcp->uvhub_version = UV_BAU_V2; - else if (is_uv3_hub()) - bcp->uvhub_version = UV_BAU_V3; - else if (is_uv4_hub()) - bcp->uvhub_version = UV_BAU_V4; - else { - pr_emerg("uvhub version not 1, 2, 3, or 4\n"); - return 1; - } - bcp->uvhub_master = *hmasterp; - uvhub_cpu = uv_cpu_blade_processor_id(cpu); - bcp->uvhub_cpu = uvhub_cpu; - - /* - * The ERROR and BUSY status registers are located pairwise over - * the STATUS_0 and STATUS_1 mmrs; each an array[32] of 2 bits. - */ - if (uvhub_cpu < UV_CPUS_PER_AS) { - bcp->status_mmr = UVH_LB_BAU_SB_ACTIVATION_STATUS_0; - bcp->status_index = uvhub_cpu * UV_ACT_STATUS_SIZE; - } else { - bcp->status_mmr = UVH_LB_BAU_SB_ACTIVATION_STATUS_1; - bcp->status_index = (uvhub_cpu - UV_CPUS_PER_AS) - * UV_ACT_STATUS_SIZE; - } - - if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) { - pr_emerg("%d cpus per uvhub invalid\n", - bcp->uvhub_cpu); - return 1; - } - } - return 0; -} - -/* - * Summarize the blade and socket topology into the per_cpu structures. - */ -static int __init summarize_uvhub_sockets(int nuvhubs, - struct uvhub_desc *uvhub_descs, - unsigned char *uvhub_mask) -{ - int socket; - int uvhub; - unsigned short socket_mask; - - for (uvhub = 0; uvhub < nuvhubs; uvhub++) { - struct uvhub_desc *bdp; - struct bau_control *smaster = NULL; - struct bau_control *hmaster = NULL; - - if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8)))) - continue; - - bdp = &uvhub_descs[uvhub]; - socket_mask = bdp->socket_mask; - socket = 0; - while (socket_mask) { - struct socket_desc *sdp; - if ((socket_mask & 1)) { - sdp = &bdp->socket[socket]; - if (scan_sock(sdp, bdp, &smaster, &hmaster)) - return 1; - make_per_cpu_thp(smaster); - } - socket++; - socket_mask = (socket_mask >> 1); - } - make_per_hub_cpumask(hmaster); - } - return 0; -} - -/* - * initialize the bau_control structure for each cpu - */ -static int __init init_per_cpu(int nuvhubs, int base_part_pnode) -{ - struct uvhub_desc *uvhub_descs; - unsigned char *uvhub_mask = NULL; - - if (is_uv3_hub() || is_uv2_hub()) - timeout_us = calculate_destination_timeout(); - - uvhub_descs = kcalloc(nuvhubs, sizeof(struct uvhub_desc), GFP_KERNEL); - if (!uvhub_descs) - goto fail; - - uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL); - if (!uvhub_mask) - goto fail; - - if (get_cpu_topology(base_part_pnode, uvhub_descs, uvhub_mask)) - goto fail; - - if (summarize_uvhub_sockets(nuvhubs, uvhub_descs, uvhub_mask)) - goto fail; - - kfree(uvhub_descs); - kfree(uvhub_mask); - init_per_cpu_tunables(); - return 0; - -fail: - kfree(uvhub_descs); - kfree(uvhub_mask); - return 1; -} - -static const struct bau_operations uv2_3_bau_ops __initconst = { - .bau_gpa_to_offset = uv_gpa_to_offset, - .read_l_sw_ack = read_mmr_sw_ack, - .read_g_sw_ack = read_gmmr_sw_ack, - .write_l_sw_ack = write_mmr_sw_ack, - .write_g_sw_ack = write_gmmr_sw_ack, - .write_payload_first = write_mmr_payload_first, - .write_payload_last = write_mmr_payload_last, - .wait_completion = uv2_3_wait_completion, -}; - -static const struct bau_operations uv4_bau_ops __initconst = { - .bau_gpa_to_offset = uv_gpa_to_soc_phys_ram, - .read_l_sw_ack = read_mmr_proc_sw_ack, - .read_g_sw_ack = read_gmmr_proc_sw_ack, - .write_l_sw_ack = write_mmr_proc_sw_ack, - .write_g_sw_ack = write_gmmr_proc_sw_ack, - .write_payload_first = write_mmr_proc_payload_first, - .write_payload_last = write_mmr_proc_payload_last, - .wait_completion = uv4_wait_completion, -}; - -/* - * Initialization of BAU-related structures - */ -static int __init uv_bau_init(void) -{ - int uvhub; - int pnode; - int nuvhubs; - int cur_cpu; - int cpus; - int vector; - cpumask_var_t *mask; - - if (!is_uv_system()) - return 0; - - if (is_uv4_hub()) - ops = uv4_bau_ops; - else if (is_uv3_hub()) - ops = uv2_3_bau_ops; - else if (is_uv2_hub()) - ops = uv2_3_bau_ops; - - nuvhubs = uv_num_possible_blades(); - if (nuvhubs < 2) { - pr_crit("UV: BAU disabled - insufficient hub count\n"); - goto err_bau_disable; - } - - for_each_possible_cpu(cur_cpu) { - mask = &per_cpu(uv_flush_tlb_mask, cur_cpu); - zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cur_cpu)); - } - - uv_base_pnode = 0x7fffffff; - for (uvhub = 0; uvhub < nuvhubs; uvhub++) { - cpus = uv_blade_nr_possible_cpus(uvhub); - if (cpus && (uv_blade_to_pnode(uvhub) < uv_base_pnode)) - uv_base_pnode = uv_blade_to_pnode(uvhub); - } - - /* software timeouts are not supported on UV4 */ - if (is_uv3_hub() || is_uv2_hub()) - enable_timeouts(); - - if (init_per_cpu(nuvhubs, uv_base_pnode)) { - pr_crit("UV: BAU disabled - per CPU init failed\n"); - goto err_bau_disable; - } - - vector = UV_BAU_MESSAGE; - for_each_possible_blade(uvhub) { - if (uv_blade_nr_possible_cpus(uvhub)) - init_uvhub(uvhub, vector, uv_base_pnode); - } - - for_each_possible_blade(uvhub) { - if (uv_blade_nr_possible_cpus(uvhub)) { - unsigned long val; - unsigned long mmr; - pnode = uv_blade_to_pnode(uvhub); - /* INIT the bau */ - val = 1L << 63; - write_gmmr_activation(pnode, val); - mmr = 1; /* should be 1 to broadcast to both sockets */ - write_mmr_data_broadcast(pnode, mmr); - } - } - - return 0; - -err_bau_disable: - - for_each_possible_cpu(cur_cpu) - free_cpumask_var(per_cpu(uv_flush_tlb_mask, cur_cpu)); - - set_bau_off(); - nobau_perm = 1; - - return -EINVAL; -} -core_initcall(uv_bau_init); -fs_initcall(uv_ptc_init); diff --git a/arch/x86/platform/uv/uv_irq.c b/arch/x86/platform/uv/uv_irq.c index abb6075397f0..18ca2261cc9a 100644 --- a/arch/x86/platform/uv/uv_irq.c +++ b/arch/x86/platform/uv/uv_irq.c @@ -90,15 +90,15 @@ static int uv_domain_alloc(struct irq_domain *domain, unsigned int virq, ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, arg); if (ret >= 0) { - if (info->uv_limit == UV_AFFINITY_CPU) + if (info->uv.limit == UV_AFFINITY_CPU) irq_set_status_flags(virq, IRQ_NO_BALANCING); else irq_set_status_flags(virq, IRQ_MOVE_PCNTXT); - chip_data->pnode = uv_blade_to_pnode(info->uv_blade); - chip_data->offset = info->uv_offset; + chip_data->pnode = uv_blade_to_pnode(info->uv.blade); + chip_data->offset = info->uv.offset; irq_domain_set_info(domain, virq, virq, &uv_irq_chip, chip_data, - handle_percpu_irq, NULL, info->uv_name); + handle_percpu_irq, NULL, info->uv.name); } else { kfree(chip_data); } @@ -193,10 +193,10 @@ int uv_setup_irq(char *irq_name, int cpu, int mmr_blade, init_irq_alloc_info(&info, cpumask_of(cpu)); info.type = X86_IRQ_ALLOC_TYPE_UV; - info.uv_limit = limit; - info.uv_blade = mmr_blade; - info.uv_offset = mmr_offset; - info.uv_name = irq_name; + info.uv.limit = limit; + info.uv.blade = mmr_blade; + info.uv.offset = mmr_offset; + info.uv.name = irq_name; return irq_domain_alloc_irqs(domain, 1, uv_blade_to_memory_nid(mmr_blade), &info); diff --git a/arch/x86/platform/uv/uv_nmi.c b/arch/x86/platform/uv/uv_nmi.c index 9d08ff5a755e..eafc530c8767 100644 --- a/arch/x86/platform/uv/uv_nmi.c +++ b/arch/x86/platform/uv/uv_nmi.c @@ -2,8 +2,9 @@ /* * SGI NMI support routines * - * Copyright (c) 2009-2013 Silicon Graphics, Inc. All Rights Reserved. - * Copyright (c) Mike Travis + * (C) Copyright 2020 Hewlett Packard Enterprise Development LP + * Copyright (C) 2007-2017 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) Mike Travis */ #include <linux/cpu.h> @@ -54,6 +55,19 @@ static struct uv_hub_nmi_s **uv_hub_nmi_list; DEFINE_PER_CPU(struct uv_cpu_nmi_s, uv_cpu_nmi); +/* Newer SMM NMI handler, not present in all systems */ +static unsigned long uvh_nmi_mmrx; /* UVH_EVENT_OCCURRED0/1 */ +static unsigned long uvh_nmi_mmrx_clear; /* UVH_EVENT_OCCURRED0/1_ALIAS */ +static int uvh_nmi_mmrx_shift; /* UVH_EVENT_OCCURRED0/1_EXTIO_INT0_SHFT */ +static char *uvh_nmi_mmrx_type; /* "EXTIO_INT0" */ + +/* Non-zero indicates newer SMM NMI handler present */ +static unsigned long uvh_nmi_mmrx_supported; /* UVH_EXTIO_INT0_BROADCAST */ + +/* Indicates to BIOS that we want to use the newer SMM NMI handler */ +static unsigned long uvh_nmi_mmrx_req; /* UVH_BIOS_KERNEL_MMR_ALIAS_2 */ +static int uvh_nmi_mmrx_req_shift; /* 62 */ + /* UV hubless values */ #define NMI_CONTROL_PORT 0x70 #define NMI_DUMMY_PORT 0x71 @@ -227,13 +241,41 @@ static inline bool uv_nmi_action_is(const char *action) /* Setup which NMI support is present in system */ static void uv_nmi_setup_mmrs(void) { - if (uv_read_local_mmr(UVH_NMI_MMRX_SUPPORTED)) { - uv_write_local_mmr(UVH_NMI_MMRX_REQ, - 1UL << UVH_NMI_MMRX_REQ_SHIFT); - nmi_mmr = UVH_NMI_MMRX; - nmi_mmr_clear = UVH_NMI_MMRX_CLEAR; - nmi_mmr_pending = 1UL << UVH_NMI_MMRX_SHIFT; - pr_info("UV: SMI NMI support: %s\n", UVH_NMI_MMRX_TYPE); + /* First determine arch specific MMRs to handshake with BIOS */ + if (UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK) { + uvh_nmi_mmrx = UVH_EVENT_OCCURRED0; + uvh_nmi_mmrx_clear = UVH_EVENT_OCCURRED0_ALIAS; + uvh_nmi_mmrx_shift = UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT; + uvh_nmi_mmrx_type = "OCRD0-EXTIO_INT0"; + + uvh_nmi_mmrx_supported = UVH_EXTIO_INT0_BROADCAST; + uvh_nmi_mmrx_req = UVH_BIOS_KERNEL_MMR_ALIAS_2; + uvh_nmi_mmrx_req_shift = 62; + + } else if (UVH_EVENT_OCCURRED1_EXTIO_INT0_MASK) { + uvh_nmi_mmrx = UVH_EVENT_OCCURRED1; + uvh_nmi_mmrx_clear = UVH_EVENT_OCCURRED1_ALIAS; + uvh_nmi_mmrx_shift = UVH_EVENT_OCCURRED1_EXTIO_INT0_SHFT; + uvh_nmi_mmrx_type = "OCRD1-EXTIO_INT0"; + + uvh_nmi_mmrx_supported = UVH_EXTIO_INT0_BROADCAST; + uvh_nmi_mmrx_req = UVH_BIOS_KERNEL_MMR_ALIAS_2; + uvh_nmi_mmrx_req_shift = 62; + + } else { + pr_err("UV:%s:cannot find EVENT_OCCURRED*_EXTIO_INT0\n", + __func__); + return; + } + + /* Then find out if new NMI is supported */ + if (likely(uv_read_local_mmr(uvh_nmi_mmrx_supported))) { + uv_write_local_mmr(uvh_nmi_mmrx_req, + 1UL << uvh_nmi_mmrx_req_shift); + nmi_mmr = uvh_nmi_mmrx; + nmi_mmr_clear = uvh_nmi_mmrx_clear; + nmi_mmr_pending = 1UL << uvh_nmi_mmrx_shift; + pr_info("UV: SMI NMI support: %s\n", uvh_nmi_mmrx_type); } else { nmi_mmr = UVH_NMI_MMR; nmi_mmr_clear = UVH_NMI_MMR_CLEAR; @@ -1049,5 +1091,5 @@ void __init uv_nmi_setup_hubless(void) /* Ensure NMI enabled in Processor Interface Reg: */ uv_reassert_nmi(); uv_register_nmi_notifier(); - pr_info("UV: Hubless NMI enabled\n"); + pr_info("UV: PCH NMI enabled\n"); } diff --git a/arch/x86/platform/uv/uv_time.c b/arch/x86/platform/uv/uv_time.c index f82a1337a608..54663f3e00cb 100644 --- a/arch/x86/platform/uv/uv_time.c +++ b/arch/x86/platform/uv/uv_time.c @@ -2,6 +2,7 @@ /* * SGI RTC clock/timer routines. * + * (C) Copyright 2020 Hewlett Packard Enterprise Development LP * Copyright (c) 2009-2013 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) Dimitri Sivanich */ @@ -52,7 +53,7 @@ struct uv_rtc_timer_head { struct { int lcpu; /* systemwide logical cpu number */ u64 expires; /* next timer expiration for this cpu */ - } cpu[1]; + } cpu[]; }; /* @@ -84,10 +85,8 @@ static void uv_rtc_send_IPI(int cpu) /* Check for an RTC interrupt pending */ static int uv_intr_pending(int pnode) { - if (is_uvx_hub()) - return uv_read_global_mmr64(pnode, UVXH_EVENT_OCCURRED2) & - UVXH_EVENT_OCCURRED2_RTC_1_MASK; - return 0; + return uv_read_global_mmr64(pnode, UVH_EVENT_OCCURRED2) & + UVH_EVENT_OCCURRED2_RTC_1_MASK; } /* Setup interrupt and return non-zero if early expiration occurred. */ @@ -101,8 +100,8 @@ static int uv_setup_intr(int cpu, u64 expires) UVH_RTC1_INT_CONFIG_M_MASK); uv_write_global_mmr64(pnode, UVH_INT_CMPB, -1L); - uv_write_global_mmr64(pnode, UVXH_EVENT_OCCURRED2_ALIAS, - UVXH_EVENT_OCCURRED2_RTC_1_MASK); + uv_write_global_mmr64(pnode, UVH_EVENT_OCCURRED2_ALIAS, + UVH_EVENT_OCCURRED2_RTC_1_MASK); val = (X86_PLATFORM_IPI_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) | ((u64)apicid << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT); @@ -148,9 +147,8 @@ static __init int uv_rtc_allocate_timers(void) struct uv_rtc_timer_head *head = blade_info[bid]; if (!head) { - head = kmalloc_node(sizeof(struct uv_rtc_timer_head) + - (uv_blade_nr_possible_cpus(bid) * - 2 * sizeof(u64)), + head = kmalloc_node(struct_size(head, cpu, + uv_blade_nr_possible_cpus(bid)), GFP_KERNEL, nid); if (!head) { uv_rtc_deallocate_timers(); diff --git a/arch/x86/purgatory/purgatory.c b/arch/x86/purgatory/purgatory.c index 2961234d0795..7b37a412f829 100644 --- a/arch/x86/purgatory/purgatory.c +++ b/arch/x86/purgatory/purgatory.c @@ -14,9 +14,9 @@ #include "../boot/string.h" -u8 purgatory_sha256_digest[SHA256_DIGEST_SIZE] __section(.kexec-purgatory); +u8 purgatory_sha256_digest[SHA256_DIGEST_SIZE] __section(".kexec-purgatory"); -struct kexec_sha_region purgatory_sha_regions[KEXEC_SEGMENT_MAX] __section(.kexec-purgatory); +struct kexec_sha_region purgatory_sha_regions[KEXEC_SEGMENT_MAX] __section(".kexec-purgatory"); static int verify_sha256_digest(void) { diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c index 1ed1208931e0..22fda7d99159 100644 --- a/arch/x86/realmode/init.c +++ b/arch/x86/realmode/init.c @@ -9,6 +9,7 @@ #include <asm/realmode.h> #include <asm/tlbflush.h> #include <asm/crash.h> +#include <asm/sev-es.h> struct real_mode_header *real_mode_header; u32 *trampoline_cr4_features; @@ -38,6 +39,25 @@ void __init reserve_real_mode(void) crash_reserve_low_1M(); } +static void sme_sev_setup_real_mode(struct trampoline_header *th) +{ +#ifdef CONFIG_AMD_MEM_ENCRYPT + if (sme_active()) + th->flags |= TH_FLAGS_SME_ACTIVE; + + if (sev_es_active()) { + /* + * Skip the call to verify_cpu() in secondary_startup_64 as it + * will cause #VC exceptions when the AP can't handle them yet. + */ + th->start = (u64) secondary_startup_64_no_verify; + + if (sev_es_setup_ap_jump_table(real_mode_header)) + panic("Failed to get/update SEV-ES AP Jump Table"); + } +#endif +} + static void __init setup_real_mode(void) { u16 real_mode_seg; @@ -104,13 +124,13 @@ static void __init setup_real_mode(void) *trampoline_cr4_features = mmu_cr4_features; trampoline_header->flags = 0; - if (sme_active()) - trampoline_header->flags |= TH_FLAGS_SME_ACTIVE; trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd); trampoline_pgd[0] = trampoline_pgd_entry.pgd; trampoline_pgd[511] = init_top_pgt[511].pgd; #endif + + sme_sev_setup_real_mode(trampoline_header); } /* diff --git a/arch/x86/realmode/rm/header.S b/arch/x86/realmode/rm/header.S index af04512c02d9..8c1db5bf5d78 100644 --- a/arch/x86/realmode/rm/header.S +++ b/arch/x86/realmode/rm/header.S @@ -20,6 +20,9 @@ SYM_DATA_START(real_mode_header) /* SMP trampoline */ .long pa_trampoline_start .long pa_trampoline_header +#ifdef CONFIG_AMD_MEM_ENCRYPT + .long pa_sev_es_trampoline_start +#endif #ifdef CONFIG_X86_64 .long pa_trampoline_pgd; #endif diff --git a/arch/x86/realmode/rm/trampoline_64.S b/arch/x86/realmode/rm/trampoline_64.S index 251758ed7443..84c5d1b33d10 100644 --- a/arch/x86/realmode/rm/trampoline_64.S +++ b/arch/x86/realmode/rm/trampoline_64.S @@ -56,6 +56,7 @@ SYM_CODE_START(trampoline_start) testl %eax, %eax # Check for return code jnz no_longmode +.Lswitch_to_protected: /* * GDT tables in non default location kernel can be beyond 16MB and * lgdt will not be able to load the address as in real mode default @@ -80,6 +81,25 @@ no_longmode: jmp no_longmode SYM_CODE_END(trampoline_start) +#ifdef CONFIG_AMD_MEM_ENCRYPT +/* SEV-ES supports non-zero IP for entry points - no alignment needed */ +SYM_CODE_START(sev_es_trampoline_start) + cli # We should be safe anyway + + LJMPW_RM(1f) +1: + mov %cs, %ax # Code and data in the same place + mov %ax, %ds + mov %ax, %es + mov %ax, %ss + + # Setup stack + movl $rm_stack_end, %esp + + jmp .Lswitch_to_protected +SYM_CODE_END(sev_es_trampoline_start) +#endif /* CONFIG_AMD_MEM_ENCRYPT */ + #include "../kernel/verify_cpu.S" .section ".text32","ax" diff --git a/arch/x86/tools/gen-insn-attr-x86.awk b/arch/x86/tools/gen-insn-attr-x86.awk index a42015b305f4..af38469afd14 100644 --- a/arch/x86/tools/gen-insn-attr-x86.awk +++ b/arch/x86/tools/gen-insn-attr-x86.awk @@ -362,6 +362,9 @@ function convert_operands(count,opnd, i,j,imm,mod) END { if (awkchecked != "") exit 1 + + print "#ifndef __BOOT_COMPRESSED\n" + # print escape opcode map's array print "/* Escape opcode map array */" print "const insn_attr_t * const inat_escape_tables[INAT_ESC_MAX + 1]" \ @@ -388,6 +391,51 @@ END { for (j = 0; j < max_lprefix; j++) if (atable[i,j]) print " ["i"]["j"] = "atable[i,j]"," - print "};" + print "};\n" + + print "#else /* !__BOOT_COMPRESSED */\n" + + print "/* Escape opcode map array */" + print "static const insn_attr_t *inat_escape_tables[INAT_ESC_MAX + 1]" \ + "[INAT_LSTPFX_MAX + 1];" + print "" + + print "/* Group opcode map array */" + print "static const insn_attr_t *inat_group_tables[INAT_GRP_MAX + 1]"\ + "[INAT_LSTPFX_MAX + 1];" + print "" + + print "/* AVX opcode map array */" + print "static const insn_attr_t *inat_avx_tables[X86_VEX_M_MAX + 1]"\ + "[INAT_LSTPFX_MAX + 1];" + print "" + + print "static void inat_init_tables(void)" + print "{" + + # print escape opcode map's array + print "\t/* Print Escape opcode map array */" + for (i = 0; i < geid; i++) + for (j = 0; j < max_lprefix; j++) + if (etable[i,j]) + print "\tinat_escape_tables["i"]["j"] = "etable[i,j]";" + print "" + + # print group opcode map's array + print "\t/* Print Group opcode map array */" + for (i = 0; i < ggid; i++) + for (j = 0; j < max_lprefix; j++) + if (gtable[i,j]) + print "\tinat_group_tables["i"]["j"] = "gtable[i,j]";" + print "" + # print AVX opcode map's array + print "\t/* Print AVX opcode map array */" + for (i = 0; i < gaid; i++) + for (j = 0; j < max_lprefix; j++) + if (atable[i,j]) + print "\tinat_avx_tables["i"]["j"] = "atable[i,j]";" + + print "}" + print "#endif" } diff --git a/arch/x86/um/asm/checksum.h b/arch/x86/um/asm/checksum.h index ff6bba2c8ab6..b07824500363 100644 --- a/arch/x86/um/asm/checksum.h +++ b/arch/x86/um/asm/checksum.h @@ -20,22 +20,6 @@ */ extern __wsum csum_partial(const void *buff, int len, __wsum sum); -/* - * Note: when you get a NULL pointer exception here this means someone - * passed in an incorrect kernel address to one of these functions. - * - * If you use these functions directly please don't forget the - * access_ok(). - */ - -static __inline__ -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) -{ - memcpy(dst, src, len); - return csum_partial(dst, len, sum); -} - /** * csum_fold - Fold and invert a 32bit checksum. * sum: 32bit unfolded sum diff --git a/arch/x86/um/asm/checksum_32.h b/arch/x86/um/asm/checksum_32.h index b9ac7c9eb72c..0b13c2947ad1 100644 --- a/arch/x86/um/asm/checksum_32.h +++ b/arch/x86/um/asm/checksum_32.h @@ -35,27 +35,4 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, return csum_fold(sum); } -/* - * Copy and checksum to user - */ -#define HAVE_CSUM_COPY_USER -static __inline__ __wsum csum_and_copy_to_user(const void *src, - void __user *dst, - int len, __wsum sum, int *err_ptr) -{ - if (access_ok(dst, len)) { - if (copy_to_user(dst, src, len)) { - *err_ptr = -EFAULT; - return (__force __wsum)-1; - } - - return csum_partial(src, len, sum); - } - - if (len) - *err_ptr = -EFAULT; - - return (__force __wsum)-1; /* invalid checksum */ -} - #endif diff --git a/arch/x86/um/ptrace_64.c b/arch/x86/um/ptrace_64.c index 09a085bde0d4..1401899dee9b 100644 --- a/arch/x86/um/ptrace_64.c +++ b/arch/x86/um/ptrace_64.c @@ -52,14 +52,6 @@ static const int reg_offsets[] = int putreg(struct task_struct *child, int regno, unsigned long value) { -#ifdef TIF_IA32 - /* - * Some code in the 64bit emulation may not be 64bit clean. - * Don't take any chances. - */ - if (test_tsk_thread_flag(child, TIF_IA32)) - value &= 0xffffffff; -#endif switch (regno) { case R8: case R9: @@ -137,10 +129,7 @@ int poke_user(struct task_struct *child, long addr, long data) unsigned long getreg(struct task_struct *child, int regno) { unsigned long mask = ~0UL; -#ifdef TIF_IA32 - if (test_tsk_thread_flag(child, TIF_IA32)) - mask = 0xffffffff; -#endif + switch (regno) { case R8: case R9: diff --git a/arch/x86/um/stub_segv.c b/arch/x86/um/stub_segv.c index 27361cbb7ca9..fdcd58af707a 100644 --- a/arch/x86/um/stub_segv.c +++ b/arch/x86/um/stub_segv.c @@ -8,7 +8,7 @@ #include <sysdep/mcontext.h> #include <sys/ucontext.h> -void __attribute__ ((__section__ (".__syscall_stub"))) +void __section(".__syscall_stub") stub_segv_handler(int sig, siginfo_t *info, void *p) { ucontext_t *uc = p; diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c index c51dd8363d25..bae61554abcc 100644 --- a/arch/x86/um/user-offsets.c +++ b/arch/x86/um/user-offsets.c @@ -2,7 +2,7 @@ #include <stdio.h> #include <stddef.h> #include <signal.h> -#include <sys/poll.h> +#include <poll.h> #include <sys/mman.h> #include <sys/user.h> #define __FRAME_OFFSETS diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 205b1176084f..aa9f50fccc5d 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -71,7 +71,7 @@ EXPORT_SYMBOL_GPL(xen_have_vector_callback); * NB: needs to live in .data because it's used by xen_prepare_pvh which runs * before clearing the bss. */ -uint32_t xen_start_flags __attribute__((section(".data"))) = 0; +uint32_t xen_start_flags __section(".data") = 0; EXPORT_SYMBOL(xen_start_flags); /* diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 22e741e0b10c..4409306364dc 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -32,7 +32,7 @@ #include <linux/pci.h> #include <linux/gfp.h> #include <linux/edd.h> -#include <linux/frame.h> +#include <linux/objtool.h> #include <xen/xen.h> #include <xen/events.h> @@ -1014,8 +1014,6 @@ void __init xen_setup_vcpu_info_placement(void) } static const struct pv_info xen_info __initconst = { - .shared_kernel_pmd = 0, - .extra_user_64bit_cs = FLAT_USER_CS64, .name = "Xen", }; @@ -1302,7 +1300,7 @@ asmlinkage __visible void __init xen_start_kernel(void) * any NUMA information the kernel tries to get from ACPI will * be meaningless. Prevent it from trying. */ - acpi_numa = -1; + disable_srat(); #endif WARN_ON(xen_cpuhp_setup(xen_cpu_up_prepare_pv, xen_cpu_dead_pv)); @@ -1314,10 +1312,6 @@ asmlinkage __visible void __init xen_start_kernel(void) xen_start_info->nr_pages); xen_reserve_special_pages(); - /* keep using Xen gdt for now; no urgent need to change it */ - - pv_info.kernel_rpl = 0; - /* * We used to do this in xen_arch_setup, but that is too late * on AMD were early_cpu_init (run before ->arch_setup()) calls @@ -1376,6 +1370,15 @@ asmlinkage __visible void __init xen_start_kernel(void) x86_init.mpparse.get_smp_config = x86_init_uint_noop; xen_boot_params_init_edd(); + +#ifdef CONFIG_ACPI + /* + * Disable selecting "Firmware First mode" for correctable + * memory errors, as this is the duty of the hypervisor to + * decide. + */ + acpi_disable_cmcff = 1; +#endif } if (!boot_params.screen_info.orig_video_isVGA) diff --git a/arch/x86/xen/enlighten_pvh.c b/arch/x86/xen/enlighten_pvh.c index 80a79db72fcf..0d5e34b9e6f9 100644 --- a/arch/x86/xen/enlighten_pvh.c +++ b/arch/x86/xen/enlighten_pvh.c @@ -21,7 +21,7 @@ * The variable xen_pvh needs to live in the data segment since it is used * after startup_{32|64} is invoked, which will clear the .bss segment. */ -bool xen_pvh __attribute__((section(".data"))) = 0; +bool xen_pvh __section(".data") = 0; void __init xen_pvh_init(struct boot_params *boot_params) { diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c index 4988e19598c8..1e681bf62561 100644 --- a/arch/x86/xen/grant-table.c +++ b/arch/x86/xen/grant-table.c @@ -25,6 +25,7 @@ static struct gnttab_vm_area { struct vm_struct *area; pte_t **ptes; + int idx; } gnttab_shared_vm_area, gnttab_status_vm_area; int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes, @@ -90,19 +91,31 @@ void arch_gnttab_unmap(void *shared, unsigned long nr_gframes) } } +static int gnttab_apply(pte_t *pte, unsigned long addr, void *data) +{ + struct gnttab_vm_area *area = data; + + area->ptes[area->idx++] = pte; + return 0; +} + static int arch_gnttab_valloc(struct gnttab_vm_area *area, unsigned nr_frames) { area->ptes = kmalloc_array(nr_frames, sizeof(*area->ptes), GFP_KERNEL); if (area->ptes == NULL) return -ENOMEM; - - area->area = alloc_vm_area(PAGE_SIZE * nr_frames, area->ptes); - if (area->area == NULL) { - kfree(area->ptes); - return -ENOMEM; - } - + area->area = get_vm_area(PAGE_SIZE * nr_frames, VM_IOREMAP); + if (!area->area) + goto out_free_ptes; + if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr, + PAGE_SIZE * nr_frames, gnttab_apply, area)) + goto out_free_vm_area; return 0; +out_free_vm_area: + free_vm_area(area->area); +out_free_ptes: + kfree(area->ptes); + return -ENOMEM; } static void arch_gnttab_vfree(struct gnttab_vm_area *area) diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c index 3273c985d3dd..cf2ade864c30 100644 --- a/arch/x86/xen/mmu_pv.c +++ b/arch/x86/xen/mmu_pv.c @@ -285,13 +285,6 @@ static void xen_set_pte(pte_t *ptep, pte_t pteval) __xen_set_pte(ptep, pteval); } -static void xen_set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pteval) -{ - trace_xen_mmu_set_pte_at(mm, addr, ptep, pteval); - __xen_set_pte(ptep, pteval); -} - pte_t xen_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { @@ -1149,7 +1142,7 @@ static void __init xen_pagetable_p2m_free(void) * We could be in __ka space. * We roundup to the PMD, which means that if anybody at this stage is * using the __ka address of xen_start_info or - * xen_start_info->shared_info they are in going to crash. Fortunatly + * xen_start_info->shared_info they are in going to crash. Fortunately * we have already revectored in xen_setup_kernel_pagetable. */ size = roundup(size, PMD_SIZE); @@ -2105,7 +2098,6 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { .release_pmd = xen_release_pmd_init, .set_pte = xen_set_pte_init, - .set_pte_at = xen_set_pte_at, .set_pmd = xen_set_pmd_hyper, .ptep_modify_prot_start = __ptep_modify_prot_start, diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c index 33293ce01d8d..19ae3e4fe4e9 100644 --- a/arch/x86/xen/pci-swiotlb-xen.c +++ b/arch/x86/xen/pci-swiotlb-xen.c @@ -2,7 +2,7 @@ /* Glue code to lib/swiotlb-xen.c */ -#include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/pci.h> #include <xen/swiotlb-xen.h> diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 2097fa0ebdb5..c1b2f764b29a 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -88,14 +88,17 @@ int xen_smp_intr_init(unsigned int cpu) per_cpu(xen_callfunc_irq, cpu).irq = rc; per_cpu(xen_callfunc_irq, cpu).name = callfunc_name; - debug_name = kasprintf(GFP_KERNEL, "debug%d", cpu); - rc = bind_virq_to_irqhandler(VIRQ_DEBUG, cpu, xen_debug_interrupt, - IRQF_PERCPU | IRQF_NOBALANCING, - debug_name, NULL); - if (rc < 0) - goto fail; - per_cpu(xen_debug_irq, cpu).irq = rc; - per_cpu(xen_debug_irq, cpu).name = debug_name; + if (!xen_fifo_events) { + debug_name = kasprintf(GFP_KERNEL, "debug%d", cpu); + rc = bind_virq_to_irqhandler(VIRQ_DEBUG, cpu, + xen_debug_interrupt, + IRQF_PERCPU | IRQF_NOBALANCING, + debug_name, NULL); + if (rc < 0) + goto fail; + per_cpu(xen_debug_irq, cpu).irq = rc; + per_cpu(xen_debug_irq, cpu).name = debug_name; + } callfunc_name = kasprintf(GFP_KERNEL, "callfuncsingle%d", cpu); rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_SINGLE_VECTOR, diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 45d556f71858..9546c3384c75 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h @@ -29,6 +29,8 @@ extern struct start_info *xen_start_info; extern struct shared_info xen_dummy_shared_info; extern struct shared_info *HYPERVISOR_shared_info; +extern bool xen_fifo_events; + void xen_setup_mfn_list_list(void); void xen_build_mfn_list_list(void); void xen_setup_machphys_mapping(void); diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index e997e0119c02..d0dfa50bd0bb 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -41,6 +41,7 @@ config XTENSA select IRQ_DOMAIN select MODULES_USE_ELF_RELA select PERF_USE_VMALLOC + select SET_FS select VIRT_TO_BUS help Xtensa processors are 32-bit RISC machines designed by Tensilica @@ -217,20 +218,6 @@ config HOTPLUG_CPU Say N if you want to disable CPU hotplug. -config SECCOMP - bool - prompt "Enable seccomp to safely compute untrusted bytecode" - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via prctl(PR_SET_SECCOMP), it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - config FAST_SYSCALL_XTENSA bool "Enable fast atomic syscalls" default n @@ -537,7 +524,7 @@ config MEMMAP_CACHEATTR 2: cache bypass, 4: WB cached, f: illegal. - For ful MMU: + For full MMU: bit 0: executable, bit 1: writable, bits 2..3: diff --git a/arch/xtensa/include/asm/checksum.h b/arch/xtensa/include/asm/checksum.h index 243a5fe79d3c..44ec1d0b2a35 100644 --- a/arch/xtensa/include/asm/checksum.h +++ b/arch/xtensa/include/asm/checksum.h @@ -37,32 +37,27 @@ asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum); * better 64-bit) boundary */ -asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, - int len, __wsum sum, - int *src_err_ptr, int *dst_err_ptr); +asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, int len); +#define _HAVE_ARCH_CSUM_AND_COPY /* * Note: when you get a NULL pointer exception here this means someone * passed in an incorrect kernel address to one of these functions. */ static inline -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) +__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len) { - return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL); + return csum_partial_copy_generic(src, dst, len); } #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER static inline __wsum csum_and_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) + int len) { - if (access_ok(src, len)) - return csum_partial_copy_generic((__force const void *)src, dst, - len, sum, err_ptr, NULL); - if (len) - *err_ptr = -EFAULT; - return sum; + if (!access_ok(src, len)) + return 0; + return csum_partial_copy_generic((__force const void *)src, dst, len); } /* @@ -243,15 +238,10 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, */ #define HAVE_CSUM_COPY_USER static __inline__ __wsum csum_and_copy_to_user(const void *src, - void __user *dst, int len, - __wsum sum, int *err_ptr) + void __user *dst, int len) { - if (access_ok(dst, len)) - return csum_partial_copy_generic(src,dst,len,sum,NULL,err_ptr); - - if (len) - *err_ptr = -EFAULT; - - return (__force __wsum)-1; /* invalid checksum */ + if (!access_ok(dst, len)) + return 0; + return csum_partial_copy_generic(src, (__force void *)dst, len); } #endif diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index 17c4384f8495..94955caa4488 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c @@ -11,8 +11,7 @@ * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> */ -#include <linux/dma-contiguous.h> -#include <linux/dma-noncoherent.h> +#include <linux/dma-map-ops.h> #include <linux/dma-direct.h> #include <linux/gfp.h> #include <linux/highmem.h> diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index be2c78f71695..ed184106e4cf 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -93,7 +93,7 @@ typedef struct tagtable { } tagtable_t; #define __tagtable(tag, fn) static tagtable_t __tagtable_##fn \ - __attribute__((used, section(".taglist"))) = { tag, fn } + __section(".taglist") __attribute__((used)) = { tag, fn } /* parse current tag */ diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index b3b17d6c50f0..1fb1047f905c 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -501,6 +501,6 @@ void do_notify_resume(struct pt_regs *regs) if (test_thread_flag(TIF_SIGPENDING)) do_signal(regs); - if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) + if (test_thread_flag(TIF_NOTIFY_RESUME)) tracehook_notify_resume(regs); } diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl index 6276e3c2d3fc..b070f272995d 100644 --- a/arch/xtensa/kernel/syscalls/syscall.tbl +++ b/arch/xtensa/kernel/syscalls/syscall.tbl @@ -410,3 +410,4 @@ 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd 439 common faccessat2 sys_faccessat2 +440 common process_madvise sys_process_madvise diff --git a/arch/xtensa/lib/checksum.S b/arch/xtensa/lib/checksum.S index 4cb9ca58d9ad..cf1bed1a5bd6 100644 --- a/arch/xtensa/lib/checksum.S +++ b/arch/xtensa/lib/checksum.S @@ -175,19 +175,14 @@ ENDPROC(csum_partial) */ /* -unsigned int csum_partial_copy_generic (const char *src, char *dst, int len, - int sum, int *src_err_ptr, int *dst_err_ptr) +unsigned int csum_partial_copy_generic (const char *src, char *dst, int len) a2 = src a3 = dst a4 = len a5 = sum - a6 = src_err_ptr - a7 = dst_err_ptr a8 = temp a9 = temp a10 = temp - a11 = original len for exception handling - a12 = original dst for exception handling This function is optimized for 4-byte aligned addresses. Other alignments work, but not nearly as efficiently. @@ -196,8 +191,7 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst, int len, ENTRY(csum_partial_copy_generic) abi_entry_default - mov a12, a3 - mov a11, a4 + movi a5, -1 or a10, a2, a3 /* We optimize the following alignment tests for the 4-byte @@ -228,26 +222,26 @@ ENTRY(csum_partial_copy_generic) #endif EX(10f) l32i a9, a2, 0 EX(10f) l32i a8, a2, 4 -EX(11f) s32i a9, a3, 0 -EX(11f) s32i a8, a3, 4 +EX(10f) s32i a9, a3, 0 +EX(10f) s32i a8, a3, 4 ONES_ADD(a5, a9) ONES_ADD(a5, a8) EX(10f) l32i a9, a2, 8 EX(10f) l32i a8, a2, 12 -EX(11f) s32i a9, a3, 8 -EX(11f) s32i a8, a3, 12 +EX(10f) s32i a9, a3, 8 +EX(10f) s32i a8, a3, 12 ONES_ADD(a5, a9) ONES_ADD(a5, a8) EX(10f) l32i a9, a2, 16 EX(10f) l32i a8, a2, 20 -EX(11f) s32i a9, a3, 16 -EX(11f) s32i a8, a3, 20 +EX(10f) s32i a9, a3, 16 +EX(10f) s32i a8, a3, 20 ONES_ADD(a5, a9) ONES_ADD(a5, a8) EX(10f) l32i a9, a2, 24 EX(10f) l32i a8, a2, 28 -EX(11f) s32i a9, a3, 24 -EX(11f) s32i a8, a3, 28 +EX(10f) s32i a9, a3, 24 +EX(10f) s32i a8, a3, 28 ONES_ADD(a5, a9) ONES_ADD(a5, a8) addi a2, a2, 32 @@ -267,7 +261,7 @@ EX(11f) s32i a8, a3, 28 .Loop6: #endif EX(10f) l32i a9, a2, 0 -EX(11f) s32i a9, a3, 0 +EX(10f) s32i a9, a3, 0 ONES_ADD(a5, a9) addi a2, a2, 4 addi a3, a3, 4 @@ -298,7 +292,7 @@ EX(11f) s32i a9, a3, 0 .Loop7: #endif EX(10f) l16ui a9, a2, 0 -EX(11f) s16i a9, a3, 0 +EX(10f) s16i a9, a3, 0 ONES_ADD(a5, a9) addi a2, a2, 2 addi a3, a3, 2 @@ -309,7 +303,7 @@ EX(11f) s16i a9, a3, 0 /* This section processes a possible trailing odd byte. */ _bbci.l a4, 0, 8f /* 1-byte chunk */ EX(10f) l8ui a9, a2, 0 -EX(11f) s8i a9, a3, 0 +EX(10f) s8i a9, a3, 0 #ifdef __XTENSA_EB__ slli a9, a9, 8 /* shift byte to bits 8..15 */ #endif @@ -334,8 +328,8 @@ EX(11f) s8i a9, a3, 0 #endif EX(10f) l8ui a9, a2, 0 EX(10f) l8ui a8, a2, 1 -EX(11f) s8i a9, a3, 0 -EX(11f) s8i a8, a3, 1 +EX(10f) s8i a9, a3, 0 +EX(10f) s8i a8, a3, 1 #ifdef __XTENSA_EB__ slli a9, a9, 8 /* combine into a single 16-bit value */ #else /* for checksum computation */ @@ -356,38 +350,7 @@ ENDPROC(csum_partial_copy_generic) # Exception handler: .section .fixup, "ax" -/* - a6 = src_err_ptr - a7 = dst_err_ptr - a11 = original len for exception handling - a12 = original dst for exception handling -*/ - 10: - _movi a2, -EFAULT - s32i a2, a6, 0 /* src_err_ptr */ - - # clear the complete destination - computing the rest - # is too much work - movi a2, 0 -#if XCHAL_HAVE_LOOPS - loopgtz a11, 2f -#else - beqz a11, 2f - add a11, a11, a12 /* a11 = ending address */ -.Leloop: -#endif - s8i a2, a12, 0 - addi a12, a12, 1 -#if !XCHAL_HAVE_LOOPS - blt a12, a11, .Leloop -#endif -2: - abi_ret_default - -11: - movi a2, -EFAULT - s32i a2, a7, 0 /* dst_err_ptr */ movi a2, 0 abi_ret_default diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index a05b306cf371..c6fc83efee0c 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -26,7 +26,7 @@ #include <linux/nodemask.h> #include <linux/mm.h> #include <linux/of_fdt.h> -#include <linux/dma-contiguous.h> +#include <linux/dma-map-ops.h> #include <asm/bootparam.h> #include <asm/page.h> @@ -79,67 +79,32 @@ void __init zones_init(void) free_area_init(max_zone_pfn); } -#ifdef CONFIG_HIGHMEM -static void __init free_area_high(unsigned long pfn, unsigned long end) -{ - for (; pfn < end; pfn++) - free_highmem_page(pfn_to_page(pfn)); -} - static void __init free_highpages(void) { +#ifdef CONFIG_HIGHMEM unsigned long max_low = max_low_pfn; - struct memblock_region *mem, *res; + phys_addr_t range_start, range_end; + u64 i; - reset_all_zones_managed_pages(); /* set highmem page free */ - for_each_memblock(memory, mem) { - unsigned long start = memblock_region_memory_base_pfn(mem); - unsigned long end = memblock_region_memory_end_pfn(mem); + for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, + &range_start, &range_end, NULL) { + unsigned long start = PHYS_PFN(range_start); + unsigned long end = PHYS_PFN(range_end); /* Ignore complete lowmem entries */ if (end <= max_low) continue; - if (memblock_is_nomap(mem)) - continue; - /* Truncate partial highmem entries */ if (start < max_low) start = max_low; - /* Find and exclude any reserved regions */ - for_each_memblock(reserved, res) { - unsigned long res_start, res_end; - - res_start = memblock_region_reserved_base_pfn(res); - res_end = memblock_region_reserved_end_pfn(res); - - if (res_end < start) - continue; - if (res_start < start) - res_start = start; - if (res_start > end) - res_start = end; - if (res_end > end) - res_end = end; - if (res_start != start) - free_area_high(start, res_start); - start = res_end; - if (start == end) - break; - } - - /* And now free anything which remains */ - if (start < end) - free_area_high(start, end); + for (; start < end; start++) + free_highmem_page(pfn_to_page(start)); } -} -#else -static void __init free_highpages(void) -{ -} #endif +} /* * Initialize memory pages. |